From 6f990698f610eb444845f36a70cad04bca2415f3 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 20 Nov 2012 15:45:03 +0100 Subject: messages-serivce: move menu creation into separate class --- src/im-phone-menu.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 src/im-phone-menu.c (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c new file mode 100644 index 0000000..abb3a11 --- /dev/null +++ b/src/im-phone-menu.c @@ -0,0 +1,216 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Lars Uebernickel + */ + +#include "im-phone-menu.h" + +#include + +typedef GObjectClass ImPhoneMenuClass; + +struct _ImPhoneMenu +{ + GObject parent; + + GMenu *toplevel_menu; + GMenu *message_section; + GMenu *source_section; + +}; + +G_DEFINE_TYPE (ImPhoneMenu, im_phone_menu, G_TYPE_OBJECT); + +typedef void (*ImMenuForeachFunc) (GMenuModel *menu, gint pos); + +static void +im_phone_menu_foreach_item_with_action (GMenuModel *menu, + const gchar *action, + ImMenuForeachFunc func) +{ + gint n_items; + gint i; + + n_items = g_menu_model_get_n_items (menu); + for (i = 0; i < n_items; i++) + { + gchar *item_action; + + g_menu_model_get_item_attribute (menu, i, G_MENU_ATTRIBUTE_ACTION, "s", &item_action); + + if (g_str_equal (action, item_action)) + func (menu, i); + + g_free (item_action); + } +} + +static void +im_phone_menu_dispose (GObject *object) +{ + ImPhoneMenu *menu = IM_PHONE_MENU (object); + + g_clear_object (&menu->toplevel_menu); + g_clear_object (&menu->message_section); + g_clear_object (&menu->source_section); + + G_OBJECT_CLASS (im_phone_menu_parent_class)->dispose (object); +} + +static void +im_phone_menu_finalize (GObject *object) +{ + G_OBJECT_CLASS (im_phone_menu_parent_class)->finalize (object); +} + +static void +im_phone_menu_class_init (ImPhoneMenuClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = im_phone_menu_dispose; + object_class->finalize = im_phone_menu_finalize; +} + +static void +im_phone_menu_init (ImPhoneMenu *menu) +{ + menu->message_section = g_menu_new (); + menu->source_section = g_menu_new (); + + menu->toplevel_menu = g_menu_new (); + g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->message_section)); + g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->source_section)); +} + +ImPhoneMenu * +im_phone_menu_new (void) +{ + return g_object_new (IM_TYPE_PHONE_MENU, NULL); +} + +GMenuModel * +im_phone_menu_get_model (ImPhoneMenu *menu) +{ + g_return_val_if_fail (IM_IS_PHONE_MENU (menu), NULL); + + return G_MENU_MODEL (menu->toplevel_menu); +} + +void +im_phone_menu_add_message (ImPhoneMenu *menu, + GDesktopAppInfo *app, + const gchar *id, + const gchar *iconstr, + const gchar *title, + const gchar *subtitle, + const gchar *body, + gint64 time) +{ + const gchar *app_id; + GMenuItem *item; + gchar *action_name; + + g_return_if_fail (IM_IS_PHONE_MENU (menu)); + g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + + app_id = g_app_info_get_id (G_APP_INFO (app)); + g_return_if_fail (app_id); + + action_name = g_strconcat (app_id, ".", id, NULL); + + item = g_menu_item_new (title, action_name); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.messageitem"); + g_menu_item_set_attribute (item, "x-canonical-message-id", "s", id); + g_menu_item_set_attribute (item, "x-canonical-subtitle", "s", subtitle); + g_menu_item_set_attribute (item, "x-canonical-text", "s", body); + g_menu_item_set_attribute (item, "x-canonical-time", "x", time); + + if (iconstr) + g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); + + g_menu_append_item (menu->message_section, item); + + g_free (action_name); + g_object_unref (item); +} + +void +im_phone_menu_remove_message (ImPhoneMenu *menu, + GDesktopAppInfo *app, + const gchar *id) +{ + gchar *action_name; + + g_return_if_fail (IM_IS_PHONE_MENU (menu)); + g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + + action_name = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", id, NULL); + im_phone_menu_foreach_item_with_action (G_MENU_MODEL (menu->message_section), + action_name, + (ImMenuForeachFunc) g_menu_remove); + + g_free (action_name); +} + +void +im_phone_menu_add_source (ImPhoneMenu *menu, + GDesktopAppInfo *app, + const gchar *id, + const gchar *label, + const gchar *iconstr, + guint32 count, + gint64 time, + const gchar *string) +{ + GMenuItem *item; + gchar *action_name; + + g_return_if_fail (IM_IS_PHONE_MENU (menu)); + g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + + action_name = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", id, NULL); + + item = g_menu_item_new (label, action_name); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.sourceitem"); + + if (iconstr) + g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); + + g_menu_append_item (menu->source_section, item); + + g_free (action_name); + g_object_unref (item); +} + +void +im_phone_menu_remove_source (ImPhoneMenu *menu, + GDesktopAppInfo *app, + const gchar *id) +{ + gchar *action_name; + + g_return_if_fail (IM_IS_PHONE_MENU (menu)); + g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + + action_name = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", id, NULL); + im_phone_menu_foreach_item_with_action (G_MENU_MODEL (menu->source_section), + action_name, + (ImMenuForeachFunc) g_menu_remove); + + g_free (action_name); +} -- cgit v1.2.3 From d22b49e5fee5ae352ec6050e63181850a857fb3a Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 21 Nov 2012 00:02:12 +0100 Subject: Remove applications from the menu when the disappear from the bus --- src/im-phone-menu.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index abb3a11..43b7a6c 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -214,3 +214,46 @@ im_phone_menu_remove_source (ImPhoneMenu *menu, g_free (action_name); } + +static void +im_phone_menu_remove_all_for_app (GMenu *menu, + GDesktopAppInfo *app) +{ + gchar *prefix; + gint n_items; + gint i = 0; + + prefix = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", NULL); + + n_items = g_menu_model_get_n_items (G_MENU_MODEL (menu)); + while (i < n_items) + { + gchar *action; + + g_menu_model_get_item_attribute (G_MENU_MODEL (menu), i, G_MENU_ATTRIBUTE_ACTION, "s", &action); + if (g_str_has_prefix (action, prefix)) + { + g_menu_remove (menu, i); + n_items--; + } + else + { + i++; + } + + g_free (action); + } + + g_free (prefix); +} + +void +im_phone_menu_remove_application (ImPhoneMenu *menu, + GDesktopAppInfo *app) +{ + g_return_if_fail (IM_IS_PHONE_MENU (menu)); + g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + + im_phone_menu_remove_all_for_app (menu->source_section, app); + im_phone_menu_remove_all_for_app (menu->message_section, app); +} -- cgit v1.2.3 From 7d78b08907c94be166da15adc9b7dad3c282d0f2 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 21 Nov 2012 11:25:20 +0100 Subject: ImApplicationList: no need to include the dynamic data in the signals This data can (and should) always be retrieved via actions. --- src/im-phone-menu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 43b7a6c..0ba41c4 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -172,10 +172,7 @@ im_phone_menu_add_source (ImPhoneMenu *menu, GDesktopAppInfo *app, const gchar *id, const gchar *label, - const gchar *iconstr, - guint32 count, - gint64 time, - const gchar *string) + const gchar *iconstr) { GMenuItem *item; gchar *action_name; -- cgit v1.2.3 From e5985f89f62fdac65d4f80037835691630cc3d2c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 22 Nov 2012 12:03:01 +0100 Subject: ImPhoneMenu: expose application icon on message items --- src/im-phone-menu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 0ba41c4..9fd52df 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -124,6 +124,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, const gchar *app_id; GMenuItem *item; gchar *action_name; + GIcon *app_icon; g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); @@ -143,6 +144,17 @@ im_phone_menu_add_message (ImPhoneMenu *menu, if (iconstr) g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); + app_icon = g_app_info_get_icon (G_APP_INFO (app)); + if (app_icon) + { + gchar *app_iconstr; + + app_iconstr = g_icon_to_string (app_icon); + g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_iconstr); + + g_free (app_iconstr); + } + g_menu_append_item (menu->message_section, item); g_free (action_name); -- cgit v1.2.3 From 979a9b32a625adb29af3b5bd6bfe324268a51b2c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 26 Nov 2012 11:34:50 +0100 Subject: Canonicalize application ids Remove trailing '.desktop' and replace all dots by underscores to make GActionMuxer work (which uses the dot as a separator). In order to contain the canonicalization to ImApplicationList, its signals now contain string parameters to id and icon name instead of GDesktopAppInfo pointers. --- src/im-phone-menu.c | 48 ++++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 30 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 9fd52df..65718be 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -113,7 +113,8 @@ im_phone_menu_get_model (ImPhoneMenu *menu) void im_phone_menu_add_message (ImPhoneMenu *menu, - GDesktopAppInfo *app, + const gchar *app_id, + const gchar *app_icon, const gchar *id, const gchar *iconstr, const gchar *title, @@ -121,15 +122,10 @@ im_phone_menu_add_message (ImPhoneMenu *menu, const gchar *body, gint64 time) { - const gchar *app_id; GMenuItem *item; gchar *action_name; - GIcon *app_icon; g_return_if_fail (IM_IS_PHONE_MENU (menu)); - g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); - - app_id = g_app_info_get_id (G_APP_INFO (app)); g_return_if_fail (app_id); action_name = g_strconcat (app_id, ".", id, NULL); @@ -144,16 +140,8 @@ im_phone_menu_add_message (ImPhoneMenu *menu, if (iconstr) g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); - app_icon = g_app_info_get_icon (G_APP_INFO (app)); if (app_icon) - { - gchar *app_iconstr; - - app_iconstr = g_icon_to_string (app_icon); - g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_iconstr); - - g_free (app_iconstr); - } + g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_icon); g_menu_append_item (menu->message_section, item); @@ -163,15 +151,15 @@ im_phone_menu_add_message (ImPhoneMenu *menu, void im_phone_menu_remove_message (ImPhoneMenu *menu, - GDesktopAppInfo *app, + const gchar *app_id, const gchar *id) { gchar *action_name; g_return_if_fail (IM_IS_PHONE_MENU (menu)); - g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + g_return_if_fail (app_id != NULL); - action_name = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", id, NULL); + action_name = g_strconcat (app_id, ".", id, NULL); im_phone_menu_foreach_item_with_action (G_MENU_MODEL (menu->message_section), action_name, (ImMenuForeachFunc) g_menu_remove); @@ -181,7 +169,7 @@ im_phone_menu_remove_message (ImPhoneMenu *menu, void im_phone_menu_add_source (ImPhoneMenu *menu, - GDesktopAppInfo *app, + const gchar *app_id, const gchar *id, const gchar *label, const gchar *iconstr) @@ -190,9 +178,9 @@ im_phone_menu_add_source (ImPhoneMenu *menu, gchar *action_name; g_return_if_fail (IM_IS_PHONE_MENU (menu)); - g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + g_return_if_fail (app_id != NULL); - action_name = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", id, NULL); + action_name = g_strconcat (app_id, ".", id, NULL); item = g_menu_item_new (label, action_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.sourceitem"); @@ -208,15 +196,15 @@ im_phone_menu_add_source (ImPhoneMenu *menu, void im_phone_menu_remove_source (ImPhoneMenu *menu, - GDesktopAppInfo *app, + const gchar *app_id, const gchar *id) { gchar *action_name; g_return_if_fail (IM_IS_PHONE_MENU (menu)); - g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + g_return_if_fail (app_id != NULL); - action_name = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", id, NULL); + action_name = g_strconcat (app_id, ".", id, NULL); im_phone_menu_foreach_item_with_action (G_MENU_MODEL (menu->source_section), action_name, (ImMenuForeachFunc) g_menu_remove); @@ -226,13 +214,13 @@ im_phone_menu_remove_source (ImPhoneMenu *menu, static void im_phone_menu_remove_all_for_app (GMenu *menu, - GDesktopAppInfo *app) + const gchar *app_id) { gchar *prefix; gint n_items; gint i = 0; - prefix = g_strconcat (g_app_info_get_id (G_APP_INFO (app)), ".", NULL); + prefix = g_strconcat (app_id, ".", NULL); n_items = g_menu_model_get_n_items (G_MENU_MODEL (menu)); while (i < n_items) @@ -258,11 +246,11 @@ im_phone_menu_remove_all_for_app (GMenu *menu, void im_phone_menu_remove_application (ImPhoneMenu *menu, - GDesktopAppInfo *app) + const gchar *app_id) { g_return_if_fail (IM_IS_PHONE_MENU (menu)); - g_return_if_fail (G_IS_DESKTOP_APP_INFO (app)); + g_return_if_fail (app_id != NULL); - im_phone_menu_remove_all_for_app (menu->source_section, app); - im_phone_menu_remove_all_for_app (menu->message_section, app); + im_phone_menu_remove_all_for_app (menu->source_section, app_id); + im_phone_menu_remove_all_for_app (menu->message_section, app_id); } -- cgit v1.2.3 From f758143a4c818e23b2e410d5bf63305c84a07590 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 26 Nov 2012 16:26:25 +0100 Subject: Add "Clear All" --- src/im-phone-menu.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 65718be..f1a5074 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -89,12 +89,20 @@ im_phone_menu_class_init (ImPhoneMenuClass *klass) static void im_phone_menu_init (ImPhoneMenu *menu) { + GMenuItem *item; + menu->message_section = g_menu_new (); menu->source_section = g_menu_new (); menu->toplevel_menu = g_menu_new (); g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->message_section)); g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->source_section)); + + item = g_menu_item_new ("Clear All", "remove-all"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.button"); + g_menu_append_item (menu->toplevel_menu, item); + + g_object_unref (item); } ImPhoneMenu * -- cgit v1.2.3 From abdb9c6e7bd033e8a9aa29a467e9f2e69cb6af2b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 26 Nov 2012 17:10:04 +0100 Subject: Remove sections and "Clear All" when no sources or messages are available --- src/im-phone-menu.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index f1a5074..7842920 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -59,6 +59,33 @@ im_phone_menu_foreach_item_with_action (GMenuModel *menu, } } +static void +im_phone_menu_update_toplevel (ImPhoneMenu *menu) +{ + if (g_menu_model_get_n_items (G_MENU_MODEL (menu->message_section)) || + g_menu_model_get_n_items (G_MENU_MODEL (menu->source_section))) + { + if (g_menu_model_get_n_items (G_MENU_MODEL (menu->toplevel_menu)) == 0) + { + GMenuItem *item; + + g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->message_section)); + g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->source_section)); + + item = g_menu_item_new ("Clear All", "remove-all"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.button"); + g_menu_append_item (menu->toplevel_menu, item); + + g_object_unref (item); + } + } + else + { + while (g_menu_model_get_n_items (G_MENU_MODEL (menu->toplevel_menu))) + g_menu_remove (menu->toplevel_menu, 0); + } +} + static void im_phone_menu_dispose (GObject *object) { @@ -89,20 +116,16 @@ im_phone_menu_class_init (ImPhoneMenuClass *klass) static void im_phone_menu_init (ImPhoneMenu *menu) { - GMenuItem *item; - + menu->toplevel_menu = g_menu_new (); menu->message_section = g_menu_new (); menu->source_section = g_menu_new (); - menu->toplevel_menu = g_menu_new (); - g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->message_section)); - g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->source_section)); - - item = g_menu_item_new ("Clear All", "remove-all"); - g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.button"); - g_menu_append_item (menu->toplevel_menu, item); + g_signal_connect_swapped (menu->message_section, "items-changed", + G_CALLBACK (im_phone_menu_update_toplevel), menu); + g_signal_connect_swapped (menu->source_section, "items-changed", + G_CALLBACK (im_phone_menu_update_toplevel), menu); - g_object_unref (item); + im_phone_menu_update_toplevel (menu); } ImPhoneMenu * -- cgit v1.2.3 From b2c6b50cdfc1cc9a288516cef102ad2943b0e950 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 26 Nov 2012 20:06:47 +0100 Subject: Use namespaced action names (src. and msg.) in phone menu --- src/im-phone-menu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 7842920..728c08b 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -159,7 +159,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id); - action_name = g_strconcat (app_id, ".", id, NULL); + action_name = g_strconcat (app_id, ".msg.", id, NULL); item = g_menu_item_new (title, action_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.messageitem"); @@ -190,7 +190,7 @@ im_phone_menu_remove_message (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id != NULL); - action_name = g_strconcat (app_id, ".", id, NULL); + action_name = g_strconcat (app_id, ".msg.", id, NULL); im_phone_menu_foreach_item_with_action (G_MENU_MODEL (menu->message_section), action_name, (ImMenuForeachFunc) g_menu_remove); @@ -211,7 +211,7 @@ im_phone_menu_add_source (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id != NULL); - action_name = g_strconcat (app_id, ".", id, NULL); + action_name = g_strconcat (app_id, ".src.", id, NULL); item = g_menu_item_new (label, action_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.sourceitem"); @@ -235,7 +235,7 @@ im_phone_menu_remove_source (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id != NULL); - action_name = g_strconcat (app_id, ".", id, NULL); + action_name = g_strconcat (app_id, ".src.", id, NULL); im_phone_menu_foreach_item_with_action (G_MENU_MODEL (menu->source_section), action_name, (ImMenuForeachFunc) g_menu_remove); -- cgit v1.2.3 From e6930c0df67ab53fcb2f7183741dee1bc0d599d4 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 28 Nov 2012 17:39:14 +0100 Subject: Expose message actions in the phone menu And use com.canonical.indicator.messages.snapdecision as widget type if the message has actions. --- src/im-phone-menu.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 728c08b..6e511ac 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -151,6 +151,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, const gchar *title, const gchar *subtitle, const gchar *body, + GVariant *actions, gint64 time) { GMenuItem *item; @@ -162,7 +163,15 @@ im_phone_menu_add_message (ImPhoneMenu *menu, action_name = g_strconcat (app_id, ".msg.", id, NULL); item = g_menu_item_new (title, action_name); - g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.messageitem"); + + if (g_variant_n_children (actions)) + { + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.snapdecision"); + g_menu_item_set_attribute (item, "x-canonical-message-actions", "v", actions); + } + else + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.messageitem"); + g_menu_item_set_attribute (item, "x-canonical-message-id", "s", id); g_menu_item_set_attribute (item, "x-canonical-subtitle", "s", subtitle); g_menu_item_set_attribute (item, "x-canonical-text", "s", body); -- cgit v1.2.3 From 0e126bb708f9381819e01debdcbdfd508aa47d2d Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 4 Dec 2012 10:35:04 +0000 Subject: Reverse order of messages Newest messages should show up on top. The menu is still sorted by the time messages were added, not by the time property of MessagingMenuMessage. --- src/im-phone-menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 6e511ac..ed28023 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -183,7 +183,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, if (app_icon) g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_icon); - g_menu_append_item (menu->message_section, item); + g_menu_prepend_item (menu->message_section, item); g_free (action_name); g_object_unref (item); @@ -228,7 +228,7 @@ im_phone_menu_add_source (ImPhoneMenu *menu, if (iconstr) g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); - g_menu_append_item (menu->source_section, item); + g_menu_prepend_item (menu->source_section, item); g_free (action_name); g_object_unref (item); -- cgit v1.2.3 From af58f8e28e5ab5ed29de518bd921f8ae699ac972 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 4 Dec 2012 12:31:33 +0000 Subject: Export symbolic application icons on messages This is implemented by appending '-symbolic' to the first icon name. The old icon name is kept as a fallback in case there's no symbolic icon installed. This doesn't work yet for applications that specify their icon as a filename. --- src/im-phone-menu.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index ed28023..51467ba 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -146,6 +146,7 @@ void im_phone_menu_add_message (ImPhoneMenu *menu, const gchar *app_id, const gchar *app_icon, + const gchar *symbolic_app_icon, const gchar *id, const gchar *iconstr, const gchar *title, @@ -183,6 +184,9 @@ im_phone_menu_add_message (ImPhoneMenu *menu, if (app_icon) g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_icon); + if (symbolic_app_icon) + g_menu_item_set_attribute (item, "x-canonical-app-icon-symbolic", "s", symbolic_app_icon); + g_menu_prepend_item (menu->message_section, item); g_free (action_name); -- cgit v1.2.3 From 40b99f3e6fc6170da525c88cf79186cd9cb565de Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 4 Dec 2012 18:33:55 +0000 Subject: Only expose one application icon (the -symbolic one) --- src/im-phone-menu.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 51467ba..ed28023 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -146,7 +146,6 @@ void im_phone_menu_add_message (ImPhoneMenu *menu, const gchar *app_id, const gchar *app_icon, - const gchar *symbolic_app_icon, const gchar *id, const gchar *iconstr, const gchar *title, @@ -184,9 +183,6 @@ im_phone_menu_add_message (ImPhoneMenu *menu, if (app_icon) g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_icon); - if (symbolic_app_icon) - g_menu_item_set_attribute (item, "x-canonical-app-icon-symbolic", "s", symbolic_app_icon); - g_menu_prepend_item (menu->message_section, item); g_free (action_name); -- cgit v1.2.3 From e1988a3d3857b4a3c51e9e4b5132e91c188ec28c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 10 Dec 2012 13:42:29 +0100 Subject: Remove the snapdecision widget type Always use messageitem instead. --- src/im-phone-menu.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index ed28023..83363d1 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -164,14 +164,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, item = g_menu_item_new (title, action_name); - if (g_variant_n_children (actions)) - { - g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.snapdecision"); - g_menu_item_set_attribute (item, "x-canonical-message-actions", "v", actions); - } - else - g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.messageitem"); - + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.messageitem"); g_menu_item_set_attribute (item, "x-canonical-message-id", "s", id); g_menu_item_set_attribute (item, "x-canonical-subtitle", "s", subtitle); g_menu_item_set_attribute (item, "x-canonical-text", "s", body); @@ -183,6 +176,9 @@ im_phone_menu_add_message (ImPhoneMenu *menu, if (app_icon) g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_icon); + if (actions) + g_menu_item_set_attribute (item, "x-canonical-message-actions", "v", actions); + g_menu_prepend_item (menu->message_section, item); g_free (action_name); -- cgit v1.2.3 From 1b61967566bdb16bd6fea882bb6f3c73c625cb35 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 14 Dec 2012 12:05:30 +0100 Subject: ImPhoneMenu: sort messages by time --- src/im-phone-menu.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 83363d1..922dc82 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -142,6 +142,17 @@ im_phone_menu_get_model (ImPhoneMenu *menu) return G_MENU_MODEL (menu->toplevel_menu); } +static gint64 +im_phone_menu_get_message_time (GMenuModel *model, + gint i) +{ + gint64 time; + + g_menu_model_get_item_attribute (model, i, "x-canonical-time", "x", &time); + + return time; +} + void im_phone_menu_add_message (ImPhoneMenu *menu, const gchar *app_id, @@ -156,6 +167,8 @@ im_phone_menu_add_message (ImPhoneMenu *menu, { GMenuItem *item; gchar *action_name; + gint n_messages; + gint pos; g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id); @@ -179,7 +192,13 @@ im_phone_menu_add_message (ImPhoneMenu *menu, if (actions) g_menu_item_set_attribute (item, "x-canonical-message-actions", "v", actions); - g_menu_prepend_item (menu->message_section, item); + n_messages = g_menu_model_get_n_items (G_MENU_MODEL (menu->message_section)); + pos = 0; + while (pos < n_messages && + time < im_phone_menu_get_message_time (G_MENU_MODEL (menu->message_section), pos)) + pos++; + + g_menu_insert_item (menu->message_section, pos, item); g_free (action_name); g_object_unref (item); -- cgit v1.2.3 From dd756106c02cabc79c7429e42ff6658bd37bba6c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 20 Dec 2012 17:46:15 +0100 Subject: ImApplicationList: add "remove-all" signal This is a temporary hack to work around a crash in QMenuModel. --- src/im-phone-menu.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 922dc82..3d5f94d 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -309,3 +309,23 @@ im_phone_menu_remove_application (ImPhoneMenu *menu, im_phone_menu_remove_all_for_app (menu->source_section, app_id); im_phone_menu_remove_all_for_app (menu->message_section, app_id); } + +void +im_phone_menu_remove_all (ImPhoneMenu *menu) +{ + g_return_if_fail (IM_IS_PHONE_MENU (menu)); + + while (g_menu_model_get_n_items (G_MENU_MODEL (menu->toplevel_menu))) + g_menu_remove (menu->toplevel_menu, 0); + + g_object_unref (menu->message_section); + g_object_unref (menu->source_section); + + menu->message_section = g_menu_new (); + menu->source_section = g_menu_new (); + + g_signal_connect_swapped (menu->message_section, "items-changed", + G_CALLBACK (im_phone_menu_update_toplevel), menu); + g_signal_connect_swapped (menu->source_section, "items-changed", + G_CALLBACK (im_phone_menu_update_toplevel), menu); +} -- cgit v1.2.3 From 769affeef08a04881a5a84aa5c2db2caedf70646 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 31 Jul 2013 09:55:32 +0200 Subject: Prefix action names with "indicator." --- src/im-phone-menu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 3d5f94d..907749f 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -72,7 +72,7 @@ im_phone_menu_update_toplevel (ImPhoneMenu *menu) g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->message_section)); g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->source_section)); - item = g_menu_item_new ("Clear All", "remove-all"); + item = g_menu_item_new ("Clear All", "indicator.remove-all"); g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.button"); g_menu_append_item (menu->toplevel_menu, item); @@ -173,7 +173,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id); - action_name = g_strconcat (app_id, ".msg.", id, NULL); + action_name = g_strconcat ("indicator.", app_id, ".msg.", id, NULL); item = g_menu_item_new (title, action_name); @@ -235,7 +235,7 @@ im_phone_menu_add_source (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id != NULL); - action_name = g_strconcat (app_id, ".src.", id, NULL); + action_name = g_strconcat ("indicator.", app_id, ".src.", id, NULL); item = g_menu_item_new (label, action_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.sourceitem"); -- cgit v1.2.3 From ff4aefe6c8d9c36881f26c2cf8514c2ce1f3edca Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 12 Aug 2013 21:19:42 +0200 Subject: Add ImMenu A base class for all messaging menus. ImPhoneMenu already subclasses from it, with a desktop version coming up. --- src/im-phone-menu.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 907749f..b24e235 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -21,19 +21,18 @@ #include -typedef GObjectClass ImPhoneMenuClass; +typedef ImMenuClass ImPhoneMenuClass; struct _ImPhoneMenu { - GObject parent; + ImMenu parent; GMenu *toplevel_menu; GMenu *message_section; GMenu *source_section; - }; -G_DEFINE_TYPE (ImPhoneMenu, im_phone_menu, G_TYPE_OBJECT); +G_DEFINE_TYPE (ImPhoneMenu, im_phone_menu, IM_TYPE_MENU); typedef void (*ImMenuForeachFunc) (GMenuModel *menu, gint pos); @@ -86,6 +85,22 @@ im_phone_menu_update_toplevel (ImPhoneMenu *menu) } } +static void +im_phone_menu_constructed (GObject *object) +{ + ImPhoneMenu *menu = IM_PHONE_MENU (object); + ImApplicationList *applist; + + applist = im_menu_get_application_list (IM_MENU (menu)); + + g_signal_connect_swapped (applist, "message-added", G_CALLBACK (im_phone_menu_add_message), menu); + g_signal_connect_swapped (applist, "message-removed", G_CALLBACK (im_phone_menu_remove_message), menu); + g_signal_connect_swapped (applist, "app-stopped", G_CALLBACK (im_phone_menu_remove_application), menu); + g_signal_connect_swapped (applist, "remove-all", G_CALLBACK (im_phone_menu_remove_all), menu); + + G_OBJECT_CLASS (im_phone_menu_parent_class)->constructed (object); +} + static void im_phone_menu_dispose (GObject *object) { @@ -109,6 +124,7 @@ im_phone_menu_class_init (ImPhoneMenuClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->constructed = im_phone_menu_constructed; object_class->dispose = im_phone_menu_dispose; object_class->finalize = im_phone_menu_finalize; } @@ -129,17 +145,13 @@ im_phone_menu_init (ImPhoneMenu *menu) } ImPhoneMenu * -im_phone_menu_new (void) -{ - return g_object_new (IM_TYPE_PHONE_MENU, NULL); -} - -GMenuModel * -im_phone_menu_get_model (ImPhoneMenu *menu) +im_phone_menu_new (ImApplicationList *applist) { - g_return_val_if_fail (IM_IS_PHONE_MENU (menu), NULL); + g_return_val_if_fail (IM_IS_APPLICATION_LIST (applist), NULL); - return G_MENU_MODEL (menu->toplevel_menu); + return g_object_new (IM_TYPE_PHONE_MENU, + "application-list", applist, + NULL); } static gint64 -- cgit v1.2.3 From 0b24c6a91ff91400568cab9b4d192a0a85db918e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 12 Aug 2013 21:33:39 +0200 Subject: Move toplevel menu logic into ImMenu Also, get rid of only exporting sections if they were non-empty. That was a hack for non-conformant GMenuModel renderers. --- src/im-phone-menu.c | 70 +++++++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 48 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index b24e235..7b5132b 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -27,7 +27,6 @@ struct _ImPhoneMenu { ImMenu parent; - GMenu *toplevel_menu; GMenu *message_section; GMenu *source_section; }; @@ -59,37 +58,29 @@ im_phone_menu_foreach_item_with_action (GMenuModel *menu, } static void -im_phone_menu_update_toplevel (ImPhoneMenu *menu) +im_phone_menu_constructed (GObject *object) { - if (g_menu_model_get_n_items (G_MENU_MODEL (menu->message_section)) || - g_menu_model_get_n_items (G_MENU_MODEL (menu->source_section))) - { - if (g_menu_model_get_n_items (G_MENU_MODEL (menu->toplevel_menu)) == 0) - { - GMenuItem *item; + ImPhoneMenu *menu = IM_PHONE_MENU (object); + ImApplicationList *applist; - g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->message_section)); - g_menu_append_section (menu->toplevel_menu, NULL, G_MENU_MODEL (menu->source_section)); + im_menu_append_section (IM_MENU (menu), G_MENU_MODEL (menu->message_section)); + im_menu_append_section (IM_MENU (menu), G_MENU_MODEL (menu->source_section)); - item = g_menu_item_new ("Clear All", "indicator.remove-all"); - g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.button"); - g_menu_append_item (menu->toplevel_menu, item); + { + GMenu *clear_section; + GMenuItem *item; - g_object_unref (item); - } - } - else - { - while (g_menu_model_get_n_items (G_MENU_MODEL (menu->toplevel_menu))) - g_menu_remove (menu->toplevel_menu, 0); - } -} + clear_section = g_menu_new (); -static void -im_phone_menu_constructed (GObject *object) -{ - ImPhoneMenu *menu = IM_PHONE_MENU (object); - ImApplicationList *applist; + item = g_menu_item_new ("Clear All", "indicator.remove-all"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.button"); + g_menu_append_item (clear_section, item); + + im_menu_append_section (IM_MENU (menu), G_MENU_MODEL (clear_section)); + + g_object_unref (item); + g_object_unref (clear_section); + } applist = im_menu_get_application_list (IM_MENU (menu)); @@ -106,7 +97,6 @@ im_phone_menu_dispose (GObject *object) { ImPhoneMenu *menu = IM_PHONE_MENU (object); - g_clear_object (&menu->toplevel_menu); g_clear_object (&menu->message_section); g_clear_object (&menu->source_section); @@ -132,16 +122,8 @@ im_phone_menu_class_init (ImPhoneMenuClass *klass) static void im_phone_menu_init (ImPhoneMenu *menu) { - menu->toplevel_menu = g_menu_new (); menu->message_section = g_menu_new (); menu->source_section = g_menu_new (); - - g_signal_connect_swapped (menu->message_section, "items-changed", - G_CALLBACK (im_phone_menu_update_toplevel), menu); - g_signal_connect_swapped (menu->source_section, "items-changed", - G_CALLBACK (im_phone_menu_update_toplevel), menu); - - im_phone_menu_update_toplevel (menu); } ImPhoneMenu * @@ -327,17 +309,9 @@ im_phone_menu_remove_all (ImPhoneMenu *menu) { g_return_if_fail (IM_IS_PHONE_MENU (menu)); - while (g_menu_model_get_n_items (G_MENU_MODEL (menu->toplevel_menu))) - g_menu_remove (menu->toplevel_menu, 0); - - g_object_unref (menu->message_section); - g_object_unref (menu->source_section); - - menu->message_section = g_menu_new (); - menu->source_section = g_menu_new (); + while (g_menu_model_get_n_items (G_MENU_MODEL (menu->message_section))) + g_menu_remove (menu->message_section, 0); - g_signal_connect_swapped (menu->message_section, "items-changed", - G_CALLBACK (im_phone_menu_update_toplevel), menu); - g_signal_connect_swapped (menu->source_section, "items-changed", - G_CALLBACK (im_phone_menu_update_toplevel), menu); + while (g_menu_model_get_n_items (G_MENU_MODEL (menu->source_section))) + g_menu_remove (menu->source_section, 0); } -- cgit v1.2.3 From 4fcb03be88fcd4ce0358db56f311f8c59dc85d44 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 13 Aug 2013 15:16:42 +0200 Subject: Use "icon" instead of "x-canonical-icon" --- src/im-phone-menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 7b5132b..96bae42 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -178,7 +178,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, g_menu_item_set_attribute (item, "x-canonical-time", "x", time); if (iconstr) - g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); + g_menu_item_set_attribute (item, "icon", "s", iconstr); if (app_icon) g_menu_item_set_attribute (item, "x-canonical-app-icon", "s", app_icon); -- cgit v1.2.3 From 08739c5fe918d9aef5b3f2f8b0e86a2fbed08a7f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 16 Aug 2013 14:01:36 -0500 Subject: Dropping indicator prefixes as they're set up with the base namespace of the section --- src/im-phone-menu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/im-phone-menu.c') diff --git a/src/im-phone-menu.c b/src/im-phone-menu.c index 96bae42..7381097 100644 --- a/src/im-phone-menu.c +++ b/src/im-phone-menu.c @@ -72,7 +72,7 @@ im_phone_menu_constructed (GObject *object) clear_section = g_menu_new (); - item = g_menu_item_new ("Clear All", "indicator.remove-all"); + item = g_menu_item_new ("Clear All", "remove-all"); g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.button"); g_menu_append_item (clear_section, item); @@ -167,7 +167,7 @@ im_phone_menu_add_message (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id); - action_name = g_strconcat ("indicator.", app_id, ".msg.", id, NULL); + action_name = g_strconcat (app_id, ".msg.", id, NULL); item = g_menu_item_new (title, action_name); @@ -229,7 +229,7 @@ im_phone_menu_add_source (ImPhoneMenu *menu, g_return_if_fail (IM_IS_PHONE_MENU (menu)); g_return_if_fail (app_id != NULL); - action_name = g_strconcat ("indicator.", app_id, ".src.", id, NULL); + action_name = g_strconcat (app_id, ".src.", id, NULL); item = g_menu_item_new (label, action_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.messages.sourceitem"); -- cgit v1.2.3