aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Uebernickel <lars.uebernickel@canonical.com>2013-08-12 21:19:42 +0200
committerLars Uebernickel <lars.uebernickel@canonical.com>2013-08-12 21:19:42 +0200
commitff4aefe6c8d9c36881f26c2cf8514c2ce1f3edca (patch)
tree853b2ae06615f5beed76334efe97bbc94f2f2fb7 /src
parent769affeef08a04881a5a84aa5c2db2caedf70646 (diff)
downloadayatana-indicator-messages-ff4aefe6c8d9c36881f26c2cf8514c2ce1f3edca.tar.gz
ayatana-indicator-messages-ff4aefe6c8d9c36881f26c2cf8514c2ce1f3edca.tar.bz2
ayatana-indicator-messages-ff4aefe6c8d9c36881f26c2cf8514c2ce1f3edca.zip
Add ImMenu
A base class for all messaging menus. ImPhoneMenu already subclasses from it, with a desktop version coming up.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/im-menu.c148
-rw-r--r--src/im-menu.h56
-rw-r--r--src/im-phone-menu.c38
-rw-r--r--src/im-phone-menu.h6
-rw-r--r--src/messages-service.c45
6 files changed, 252 insertions, 43 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c011d5d..74a1142 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,6 +14,8 @@ indicator_messages_service_SOURCES = \
gsettingsstrv.h \
gmenuutils.c \
gmenuutils.h \
+ im-menu.c \
+ im-menu.h \
im-phone-menu.c \
im-phone-menu.h \
im-application-list.c \
diff --git a/src/im-menu.c b/src/im-menu.c
new file mode 100644
index 0000000..9f4d3e0
--- /dev/null
+++ b/src/im-menu.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2013 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Lars Uebernickel <lars.uebernickel@canonical.com>
+ */
+
+#include "im-menu.h"
+
+struct _ImMenuPrivate
+{
+ GMenu *toplevel_menu;
+ GMenu *menu;
+ ImApplicationList *applist;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (ImMenu, im_menu, G_TYPE_OBJECT)
+
+enum
+{
+ PROP_0,
+ PROP_APPLICATION_LIST,
+ NUM_PROPERTIES
+};
+
+static void
+im_menu_finalize (GObject *object)
+{
+ ImMenuPrivate *priv = im_menu_get_instance_private (IM_MENU (object));
+
+ g_object_unref (priv->toplevel_menu);
+ g_object_unref (priv->menu);
+ g_object_unref (priv->applist);
+
+ G_OBJECT_CLASS (im_menu_parent_class)->finalize (object);
+}
+
+static void
+im_menu_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ImMenuPrivate *priv = im_menu_get_instance_private (IM_MENU (object));
+
+ switch (property_id)
+ {
+ case PROP_APPLICATION_LIST:
+ g_value_set_object (value, priv->applist);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+im_menu_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ImMenuPrivate *priv = im_menu_get_instance_private (IM_MENU (object));
+
+ switch (property_id)
+ {
+ case PROP_APPLICATION_LIST: /* construct only */
+ priv->applist = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+im_menu_class_init (ImMenuClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = im_menu_finalize;
+ object_class->get_property = im_menu_get_property;
+ object_class->set_property = im_menu_set_property;
+
+ g_object_class_install_property (object_class, PROP_APPLICATION_LIST,
+ g_param_spec_object ("application-list", "", "",
+ IM_TYPE_APPLICATION_LIST,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+im_menu_init (ImMenu *menu)
+{
+ ImMenuPrivate *priv = im_menu_get_instance_private (menu);
+ GMenuItem *root;
+
+ priv->toplevel_menu = g_menu_new ();
+ priv->menu = g_menu_new ();
+
+ root = g_menu_item_new (NULL, "indicator.messages");
+ g_menu_item_set_attribute (root, "x-canonical-type", "s", "com.canonical.indicator.root");
+ g_menu_item_set_submenu (root, G_MENU_MODEL (priv->menu));
+ g_menu_append_item (priv->toplevel_menu, root);
+
+ g_object_unref (root);
+}
+
+ImApplicationList *
+im_menu_get_application_list (ImMenu *menu)
+{
+ ImMenuPrivate *priv;
+
+ g_return_val_if_fail (IM_IS_MENU (menu), FALSE);
+
+ priv = im_menu_get_instance_private (menu);
+ return priv->applist;
+}
+
+gboolean
+im_menu_export (ImMenu *menu,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error)
+{
+ ImMenuPrivate *priv;
+
+ g_return_val_if_fail (IM_IS_MENU (menu), FALSE);
+
+ priv = im_menu_get_instance_private (menu);
+ return g_dbus_connection_export_menu_model (connection,
+ object_path,
+ G_MENU_MODEL (priv->toplevel_menu),
+ error) > 0;
+}
diff --git a/src/im-menu.h b/src/im-menu.h
new file mode 100644
index 0000000..7276020
--- /dev/null
+++ b/src/im-menu.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2013 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Lars Uebernickel <lars.uebernickel@canonical.com>
+ */
+
+#ifndef __IM_MENU_H__
+#define __IM_MENU_H__
+
+#include <gio/gio.h>
+#include "im-application-list.h"
+
+#define IM_TYPE_MENU (im_menu_get_type ())
+#define IM_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IM_TYPE_MENU, ImMenu))
+#define IM_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IM_TYPE_MENU, ImMenuClass))
+#define IM_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IM_TYPE_MENU))
+#define IM_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IM_TYPE_MENU))
+#define IM_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IM_TYPE_MENU, ImMenuClass))
+
+typedef struct _ImMenuClass ImMenuClass;
+typedef struct _ImMenu ImMenu;
+typedef struct _ImMenuPrivate ImMenuPrivate;
+
+struct _ImMenuClass
+{
+ GObjectClass parent_class;
+};
+
+struct _ImMenu
+{
+ GObject parent_instance;
+};
+
+GType im_menu_get_type (void) G_GNUC_CONST;
+
+ImApplicationList * im_menu_get_application_list (ImMenu *menu);
+
+gboolean im_menu_export (ImMenu *menu,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error);
+
+#endif
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 <string.h>
-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);
@@ -87,6 +86,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)
{
ImPhoneMenu *menu = IM_PHONE_MENU (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
diff --git a/src/im-phone-menu.h b/src/im-phone-menu.h
index 258ce73..9742f61 100644
--- a/src/im-phone-menu.h
+++ b/src/im-phone-menu.h
@@ -20,7 +20,7 @@
#ifndef __IM_PHONE_MENU_H__
#define __IM_PHONE_MENU_H__
-#include <gio/gio.h>
+#include "im-menu.h"
#define IM_TYPE_PHONE_MENU (im_phone_menu_get_type ())
#define IM_PHONE_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IM_TYPE_PHONE_MENU, ImPhoneMenu))
@@ -33,9 +33,7 @@ typedef struct _ImPhoneMenu ImPhoneMenu;
GType im_phone_menu_get_type (void);
-ImPhoneMenu * im_phone_menu_new (void);
-
-GMenuModel * im_phone_menu_get_model (ImPhoneMenu *menu);
+ImPhoneMenu * im_phone_menu_new (ImApplicationList *applist);
void im_phone_menu_add_message (ImPhoneMenu *menu,
const gchar *app_id,
diff --git a/src/messages-service.c b/src/messages-service.c
index 94d6d29..781e261 100644
--- a/src/messages-service.c
+++ b/src/messages-service.c
@@ -39,8 +39,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
static ImApplicationList *applications;
static IndicatorMessagesService *messages_service;
-static GMenu *toplevel_menu;
-static ImPhoneMenu *menu;
+static GHashTable *menus;
static GSettings *settings;
static void
@@ -82,6 +81,9 @@ on_bus_acquired (GDBusConnection *bus,
gpointer user_data)
{
GError *error = NULL;
+ GHashTableIter it;
+ const gchar *profile;
+ ImMenu *menu;
g_dbus_connection_export_action_group (bus, INDICATOR_MESSAGES_DBUS_OBJECT,
im_application_list_get_action_group (applications),
@@ -92,12 +94,17 @@ on_bus_acquired (GDBusConnection *bus,
return;
}
- g_dbus_connection_export_menu_model (bus, INDICATOR_MESSAGES_DBUS_OBJECT "/phone",
- G_MENU_MODEL (toplevel_menu), &error);
- if (error) {
- g_warning ("unable to export menu on dbus: %s", error->message);
- g_error_free (error);
- return;
+ g_hash_table_iter_init (&it, menus);
+ while (g_hash_table_iter_next (&it, (gpointer *) &profile, (gpointer *) &menu)) {
+ gchar *object_path;
+
+ object_path = g_strconcat (INDICATOR_MESSAGES_DBUS_OBJECT, "/", profile, NULL);
+ if (!im_menu_export (menu, bus, object_path, &error)) {
+ g_warning ("unable to export menu for profile '%s': %s", profile, error->message);
+ g_clear_error (&error);
+ }
+
+ g_free (object_path);
}
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (messages_service),
@@ -126,7 +133,6 @@ int
main (int argc, char ** argv)
{
GMainLoop * mainloop = NULL;
- GMenuItem *root;
GBusNameOwnerFlags flags;
/* Glib init */
@@ -157,30 +163,17 @@ main (int argc, char ** argv)
g_signal_connect (messages_service, "handle-unregister-application",
G_CALLBACK (unregister_application), NULL);
- menu = im_phone_menu_new ();
-
- toplevel_menu = g_menu_new ();
- root = g_menu_item_new (NULL, "indicator.messages");
- g_menu_item_set_attribute (root, "x-canonical-type", "s", "com.canonical.indicator.root");
- g_menu_item_set_submenu (root, im_phone_menu_get_model (menu));
- g_menu_append_item (toplevel_menu, root);
-
settings = g_settings_new ("com.canonical.indicator.messages");
applications = im_application_list_new ();
- g_signal_connect_swapped (applications, "message-added",
- G_CALLBACK (im_phone_menu_add_message), menu);
- g_signal_connect_swapped (applications, "message-removed",
- G_CALLBACK (im_phone_menu_remove_message), menu);
- g_signal_connect_swapped (applications, "app-stopped",
- G_CALLBACK (im_phone_menu_remove_application), menu);
- g_signal_connect_swapped (applications, "remove-all",
- G_CALLBACK (im_phone_menu_remove_all), menu);
+
+ menus = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+ g_hash_table_insert (menus, "phone", im_phone_menu_new (applications));
g_main_loop_run(mainloop);
/* Clean up */
- g_object_unref (root);
+ g_hash_table_unref (menus);
g_object_unref (messages_service);
g_object_unref (settings);
g_object_unref (applications);