aboutsummaryrefslogtreecommitdiff
path: root/libmessaging-menu
diff options
context:
space:
mode:
authorŁukasz 'sil2100' Zemczak <lukasz.zemczak@canonical.com>2013-08-20 10:53:01 +0200
committerŁukasz 'sil2100' Zemczak <lukasz.zemczak@canonical.com>2013-08-20 10:53:01 +0200
commit88b2fd89ff0bc4be81acd8f6d5751dba96e295f8 (patch)
tree2f231acd79d96f697709586effbabb4928477c89 /libmessaging-menu
parentb25532c6a307381f523a78b4b5fbdeb73896bb3d (diff)
downloadayatana-indicator-messages-88b2fd89ff0bc4be81acd8f6d5751dba96e295f8.tar.gz
ayatana-indicator-messages-88b2fd89ff0bc4be81acd8f6d5751dba96e295f8.tar.bz2
ayatana-indicator-messages-88b2fd89ff0bc4be81acd8f6d5751dba96e295f8.zip
Revert rev 352 as it is causing a SIGTRAP on start
Diffstat (limited to 'libmessaging-menu')
-rw-r--r--libmessaging-menu/Makefile.am55
-rw-r--r--libmessaging-menu/gtupleaction.c354
-rw-r--r--libmessaging-menu/gtupleaction.h40
-rw-r--r--libmessaging-menu/messaging-menu-app.h163
-rw-r--r--libmessaging-menu/messaging-menu-message.c547
-rw-r--r--libmessaging-menu/messaging-menu-message.h70
-rw-r--r--libmessaging-menu/messaging-menu.c (renamed from libmessaging-menu/messaging-menu-app.c)745
-rw-r--r--libmessaging-menu/messaging-menu.h125
8 files changed, 796 insertions, 1303 deletions
diff --git a/libmessaging-menu/Makefile.am b/libmessaging-menu/Makefile.am
index 1042d9f..7a6ee31 100644
--- a/libmessaging-menu/Makefile.am
+++ b/libmessaging-menu/Makefile.am
@@ -4,25 +4,36 @@ lib_LTLIBRARIES = libmessaging-menu.la
libmessaging_menu_ladir = $(includedir)/messaging-menu
libmessaging_menu_la_SOURCES = \
- messaging-menu-app.c \
- messaging-menu-message.c
+ messaging-menu.c \
+ gtupleaction.c \
+ gtupleaction.h \
+ $(BUILT_SOURCES)
libmessaging_menu_la_HEADERS = \
- messaging-menu-app.h \
- messaging-menu.h \
- messaging-menu-message.h
+ messaging-menu.h
-libmessaging_menu_la_LIBADD = \
- $(GIO_LIBS) \
- $(top_builddir)/common/libmessaging-common.la
+libmessaging_menu_la_LIBADD = $(GIO_LIBS)
libmessaging_menu_la_CFLAGS = \
- -I$(top_builddir)/common \
$(GIO_CFLAGS) \
-Wall
libmessaging_menu_la_LDFLAGS = -export-symbols-regex "^messaging_menu_.*"
+BUILT_SOURCES = \
+ indicator-messages-service.c \
+ indicator-messages-service.h
+
+CLEANFILES = $(BUILT_SOURCES)
+
+indicator-messages-service.c: $(top_srcdir)/src/messages-service.xml
+ $(AM_V_GEN) gdbus-codegen \
+ --interface-prefix com.canonical.indicator.messages. \
+ --generate-c-code indicator-messages-service \
+ --c-namespace IndicatorMessages \
+ $^
+indicator-messages-service.h: indicator-messages-service.c
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = messaging-menu.pc
@@ -41,11 +52,7 @@ MessagingMenu_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0
MessagingMenu_1_0_gir_CFLAGS = $(INCLUDES) $(GIO_CFLAGS)
MessagingMenu_1_0_gir_SCANNERFLAGS = --c-include="messaging-menu.h"
MessagingMenu_1_0_gir_LIBS = libmessaging-menu.la
-MessagingMenu_1_0_gir_FILES = \
- messaging-menu-app.c \
- messaging-menu-app.h \
- messaging-menu-message.c \
- messaging-menu-message.h
+MessagingMenu_1_0_gir_FILES = messaging-menu.c messaging-menu.h
MessagingMenu_1_0_gir_EXPORT_PACKAGES = messaging-menu
INTROSPECTION_GIRS += MessagingMenu-1.0.gir
@@ -55,23 +62,5 @@ gir_DATA = $(INTROSPECTION_GIRS)
typelibdir = $(libdir)/girepository-1.0
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
-CLEANFILES = $(gir_DATA) $(typelib_DATA)
-
-
-#########################
-# VAPI Files
-#########################
-
-if HAVE_VALA
-
-vapidir = $(datadir)/vala/vapi
-vapi_DATA = MessagingMenu-1.0.vapi
-
-MessagingMenu-1.0.vapi: MessagingMenu-1.0.gir
- $(VALA_API_GEN) --pkg gio-2.0 --library=MessagingMenu-1.0 $<
-
-CLEANFILES += $(vapi_DATA)
-
-endif
-
+CLEANFILES +=$(gir_DATA) $(typelib_DATA)
endif
diff --git a/libmessaging-menu/gtupleaction.c b/libmessaging-menu/gtupleaction.c
new file mode 100644
index 0000000..21bc003
--- /dev/null
+++ b/libmessaging-menu/gtupleaction.c
@@ -0,0 +1,354 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Lars Uebernickel <lars.uebernickel@canonical.com>
+ */
+
+#include "gtupleaction.h"
+
+typedef GObjectClass GTupleActionClass;
+
+struct _GTupleAction
+{
+ GObject parent;
+
+ gchar *name;
+ GVariantType *type;
+ gboolean enabled;
+
+ gsize n_children;
+ GVariant **children;
+};
+
+static void action_interface_init (GActionInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GTupleAction, g_tuple_action, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, action_interface_init));
+
+enum
+{
+ PROP_0,
+ PROP_NAME,
+ PROP_PARAMETER_TYPE,
+ PROP_ENABLED,
+ PROP_STATE_TYPE,
+ PROP_STATE,
+ N_PROPERTIES
+};
+
+enum
+{
+ SIGNAL_ACTIVATE,
+ N_SIGNALS
+};
+
+static GParamSpec *properties[N_PROPERTIES];
+static guint signal_ids[N_SIGNALS];
+
+static const gchar *
+g_tuple_action_get_name (GAction *action)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (action);
+
+ return tuple->name;
+}
+
+static const GVariantType *
+g_tuple_action_get_parameter_type (GAction *action)
+{
+ return NULL;
+}
+
+static const GVariantType *
+g_tuple_action_get_state_type (GAction *action)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (action);
+
+ return tuple->type;
+}
+
+static GVariant *
+g_tuple_action_get_state_hint (GAction *action)
+{
+ return NULL;
+}
+
+static gboolean
+g_tuple_action_get_enabled (GAction *action)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (action);
+
+ return tuple->enabled;
+}
+
+static GVariant *
+g_tuple_action_get_state (GAction *action)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (action);
+ GVariant *result;
+
+ result = g_variant_new_tuple (tuple->children, tuple->n_children);
+ return g_variant_ref_sink (result);
+}
+
+static void
+g_tuple_action_set_state (GTupleAction *tuple,
+ GVariant *state)
+{
+ int i;
+
+ g_return_if_fail (g_variant_type_is_tuple (g_variant_get_type (state)));
+
+ if (tuple->type == NULL)
+ {
+ tuple->type = g_variant_type_copy (g_variant_get_type (state));
+ tuple->n_children = g_variant_n_children (state);
+ tuple->children = g_new0 (GVariant *, tuple->n_children);
+ }
+
+ for (i = 0; i < tuple->n_children; i++)
+ {
+ if (tuple->children[i])
+ g_variant_unref (tuple->children[i]);
+ tuple->children[i] = g_variant_get_child_value (state, i);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (tuple), properties[PROP_STATE]);
+}
+
+static void
+g_tuple_action_change_state (GAction *action,
+ GVariant *value)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (action);
+
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (g_variant_is_of_type (value, tuple->type));
+
+ g_variant_ref_sink (value);
+
+ /* TODO add a change-state signal similar to GSimpleAction */
+ g_tuple_action_set_state (tuple, value);
+
+ g_variant_unref (value);
+}
+
+static void
+g_tuple_action_activate (GAction *action,
+ GVariant *parameter)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (action);
+
+ g_return_if_fail (parameter == NULL);
+
+ if (tuple->enabled)
+ g_signal_emit (tuple, signal_ids[SIGNAL_ACTIVATE], 0, NULL);
+}
+
+static void
+g_tuple_action_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GAction *action = G_ACTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, g_tuple_action_get_name (action));
+ break;
+
+ case PROP_PARAMETER_TYPE:
+ g_value_set_boxed (value, g_tuple_action_get_parameter_type (action));
+ break;
+
+ case PROP_ENABLED:
+ g_value_set_boolean (value, g_tuple_action_get_enabled (action));
+ break;
+
+ case PROP_STATE_TYPE:
+ g_value_set_boxed (value, g_tuple_action_get_state_type (action));
+ break;
+
+ case PROP_STATE:
+ g_value_take_variant (value, g_tuple_action_get_state (action));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_tuple_action_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ tuple->name = g_value_dup_string (value);
+ g_object_notify_by_pspec (object, properties[PROP_NAME]);
+ break;
+
+ case PROP_ENABLED:
+ tuple->enabled = g_value_get_boolean (value);
+ g_object_notify_by_pspec (object, properties[PROP_ENABLED]);
+ break;
+
+ case PROP_STATE:
+ g_tuple_action_set_state (tuple, g_value_get_variant (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_tuple_action_finalize (GObject *object)
+{
+ GTupleAction *tuple = G_TUPLE_ACTION (object);
+ int i;
+
+ g_free (tuple->name);
+ g_variant_type_free (tuple->type);
+
+ for (i = 0; i < tuple->n_children; i++)
+ g_variant_unref (tuple->children[i]);
+
+ g_free (tuple->children);
+
+ G_OBJECT_CLASS (g_tuple_action_parent_class)->finalize (object);
+}
+
+static void
+action_interface_init (GActionInterface *iface)
+{
+ iface->get_name = g_tuple_action_get_name;
+ iface->get_parameter_type = g_tuple_action_get_parameter_type;
+ iface->get_state_type = g_tuple_action_get_state_type;
+ iface->get_state_hint = g_tuple_action_get_state_hint;
+ iface->get_enabled = g_tuple_action_get_enabled;
+ iface->get_state = g_tuple_action_get_state;
+ iface->change_state = g_tuple_action_change_state;
+ iface->activate = g_tuple_action_activate;
+}
+
+static void
+g_tuple_action_class_init (GTupleActionClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->get_property = g_tuple_action_get_property;
+ object_class->set_property = g_tuple_action_set_property;
+ object_class->finalize = g_tuple_action_finalize;
+
+ properties[PROP_NAME] = g_param_spec_string ("name",
+ "Name",
+ "The name of the action",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_PARAMETER_TYPE] = g_param_spec_boxed ("parameter-type",
+ "Parameter Type",
+ "The variant type passed to activate",
+ G_TYPE_VARIANT_TYPE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_ENABLED] = g_param_spec_boolean ("enabled",
+ "Enabled",
+ "Whether the action can be activated",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_STATE_TYPE] = g_param_spec_boxed ("state-type",
+ "State Type",
+ "The variant type of the state, must be a tuple",
+ G_TYPE_VARIANT_TYPE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_STATE] = g_param_spec_variant ("state",
+ "State",
+ "The state of the action",
+ G_VARIANT_TYPE_TUPLE,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+
+ signal_ids[SIGNAL_ACTIVATE] = g_signal_new ("activate",
+ G_TYPE_TUPLE_ACTION,
+ G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VARIANT,
+ G_TYPE_NONE, 1,
+ G_TYPE_VARIANT);
+}
+
+static void
+g_tuple_action_init (GTupleAction *action)
+{
+ action->enabled = TRUE;
+}
+
+GTupleAction *
+g_tuple_action_new (const gchar *name,
+ GVariant *initial_state)
+{
+ const GVariantType *type;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (initial_state != NULL, NULL);
+
+ type = g_variant_get_type (initial_state);
+ g_return_val_if_fail (g_variant_type_is_tuple (type), NULL);
+
+ return g_object_new (G_TYPE_TUPLE_ACTION,
+ "name", name,
+ "state", initial_state,
+ NULL);
+}
+
+void
+g_tuple_action_set_child (GTupleAction *action,
+ gsize index,
+ GVariant *value)
+{
+ const GVariantType *type;
+
+ g_return_if_fail (G_IS_TUPLE_ACTION (action));
+ g_return_if_fail (index < action->n_children);
+ g_return_if_fail (value != NULL);
+
+ type = g_variant_get_type (value);
+ g_return_if_fail (g_variant_is_of_type (value, type));
+
+ g_variant_unref (action->children[index]);
+ action->children[index] = g_variant_ref_sink (value);
+
+ g_object_notify_by_pspec (G_OBJECT (action), properties[PROP_STATE]);
+}
diff --git a/libmessaging-menu/gtupleaction.h b/libmessaging-menu/gtupleaction.h
new file mode 100644
index 0000000..c447d71
--- /dev/null
+++ b/libmessaging-menu/gtupleaction.h
@@ -0,0 +1,40 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Lars Uebernickel <lars.uebernickel@canonical.com>
+ */
+
+#ifndef __g_tuple_action_h__
+#define __g_tuple_action_h__
+
+#include <gio/gio.h>
+
+#define G_TYPE_TUPLE_ACTION (g_tuple_action_get_type ())
+#define G_TUPLE_ACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TUPLE_ACTION, GTupleAction))
+#define G_IS_TUPLE_ACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TUPLE_ACTION))
+
+typedef struct _GTupleAction GTupleAction;
+
+GType g_tuple_action_get_type (void) G_GNUC_CONST;
+
+GTupleAction * g_tuple_action_new (const gchar *name,
+ GVariant *initial_state);
+
+void g_tuple_action_set_child (GTupleAction *action,
+ gsize index,
+ GVariant *value);
+
+#endif
diff --git a/libmessaging-menu/messaging-menu-app.h b/libmessaging-menu/messaging-menu-app.h
deleted file mode 100644
index c8097e1..0000000
--- a/libmessaging-menu/messaging-menu-app.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Lars Uebernickel <lars.uebernickel@canonical.com>
- */
-
-#ifndef __messaging_menu_app_h__
-#define __messaging_menu_app_h__
-
-#include <gio/gio.h>
-#include "messaging-menu-message.h"
-
-G_BEGIN_DECLS
-
-#define MESSAGING_MENU_TYPE_APP messaging_menu_app_get_type()
-#define MESSAGING_MENU_APP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MESSAGING_MENU_TYPE_APP, MessagingMenuApp))
-#define MESSAGING_MENU_APP_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), MESSAGING_MENU_TYPE_APP, MessagingMenuAppClass))
-#define MESSAGING_MENU_IS_APP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MESSAGING_MENU_TYPE_APP))
-
-/**
- * MessagingMenuStatus:
- * @MESSAGING_MENU_STATUS_AVAILABLE: available
- * @MESSAGING_MENU_STATUS_AWAY: away
- * @MESSAGING_MENU_STATUS_BUSY: busy
- * @MESSAGING_MENU_STATUS_INVISIBLE: invisible
- * @MESSAGING_MENU_STATUS_OFFLINE: offline
- *
- * An enumeration for the possible chat statuses the messaging menu can be in.
- */
-typedef enum {
- MESSAGING_MENU_STATUS_AVAILABLE,
- MESSAGING_MENU_STATUS_AWAY,
- MESSAGING_MENU_STATUS_BUSY,
- MESSAGING_MENU_STATUS_INVISIBLE,
- MESSAGING_MENU_STATUS_OFFLINE
-} MessagingMenuStatus;
-
-
-typedef GObjectClass MessagingMenuAppClass;
-typedef struct _MessagingMenuApp MessagingMenuApp;
-
-GType messaging_menu_app_get_type (void) G_GNUC_CONST;
-
-MessagingMenuApp * messaging_menu_app_new (const gchar *desktop_id);
-
-void messaging_menu_app_register (MessagingMenuApp *app);
-void messaging_menu_app_unregister (MessagingMenuApp *app);
-
-void messaging_menu_app_set_status (MessagingMenuApp *app,
- MessagingMenuStatus status);
-
-void messaging_menu_app_insert_source (MessagingMenuApp *app,
- gint position,
- const gchar *id,
- GIcon *icon,
- const gchar *label);
-
-void messaging_menu_app_append_source (MessagingMenuApp *app,
- const gchar *id,
- GIcon *icon,
- const gchar *label);
-
-void messaging_menu_app_insert_source_with_count (MessagingMenuApp *app,
- gint position,
- const gchar *id,
- GIcon *icon,
- const gchar *label,
- guint count);
-
-void messaging_menu_app_append_source_with_count (MessagingMenuApp *app,
- const gchar *id,
- GIcon *icon,
- const gchar *label,
- guint count);
-
-void messaging_menu_app_insert_source_with_time (MessagingMenuApp *app,
- gint position,
- const gchar *id,
- GIcon *icon,
- const gchar *label,
- gint64 time);
-
-void messaging_menu_app_append_source_with_time (MessagingMenuApp *app,
- const gchar *id,
- GIcon *icon,
- const gchar *label,
- gint64 time);
-
-void messaging_menu_app_append_source_with_string (MessagingMenuApp *app,
- const gchar *id,
- GIcon *icon,
- const gchar *label,
- const gchar *str);
-
-void messaging_menu_app_insert_source_with_string (MessagingMenuApp *app,
- gint position,
- const gchar *id,
- GIcon *icon,
- const gchar *label,
- const gchar *str);
-
-void messaging_menu_app_remove_source (MessagingMenuApp *app,
- const gchar *source_id);
-
-gboolean messaging_menu_app_has_source (MessagingMenuApp *app,
- const gchar *source_id);
-
-void messaging_menu_app_set_source_label (MessagingMenuApp *app,
- const gchar *source_id,
- const gchar *label);
-
-void messaging_menu_app_set_source_icon (MessagingMenuApp *app,
- const gchar *source_id,
- GIcon *icon);
-
-void messaging_menu_app_set_source_count (MessagingMenuApp *app,
- const gchar *source_id,
- guint count);
-
-void messaging_menu_app_set_source_time (MessagingMenuApp *app,
- const gchar *source_id,
- gint64 time);
-
-void messaging_menu_app_set_source_string (MessagingMenuApp *app,
- const gchar *source_id,
- const gchar *str);
-
-void messaging_menu_app_draw_attention (MessagingMenuApp *app,
- const gchar *source_id);
-
-void messaging_menu_app_remove_attention (MessagingMenuApp *app,
- const gchar *source_id);
-
-void messaging_menu_app_append_message (MessagingMenuApp *app,
- MessagingMenuMessage *msg,
- const gchar *source_id,
- gboolean notify);
-
-MessagingMenuMessage * messaging_menu_app_get_message (MessagingMenuApp *app,
- const gchar *id);
-
-void messaging_menu_app_remove_message (MessagingMenuApp *app,
- MessagingMenuMessage *msg);
-
-void messaging_menu_app_remove_message_by_id (MessagingMenuApp *app,
- const gchar *id);
-
-G_END_DECLS
-
-#endif
diff --git a/libmessaging-menu/messaging-menu-message.c b/libmessaging-menu/messaging-menu-message.c
deleted file mode 100644
index b81cbea..0000000
--- a/libmessaging-menu/messaging-menu-message.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Lars Uebernickel <lars.uebernickel@canonical.com>
- */
-
-#include "messaging-menu-message.h"
-
-typedef GObjectClass MessagingMenuMessageClass;
-
-struct _MessagingMenuMessage
-{
- GObject parent;
-
- gchar *id;
- GIcon *icon;
- gchar *title;
- gchar *subtitle;
- gchar *body;
- gint64 time;
- gboolean draws_attention;
-
- GSList *actions;
-};
-
-G_DEFINE_TYPE (MessagingMenuMessage, messaging_menu_message, G_TYPE_OBJECT);
-
-enum
-{
- PROP_0,
- PROP_ID,
- PROP_ICON,
- PROP_TITLE,
- PROP_SUBTITLE,
- PROP_BODY,
- PROP_TIME,
- PROP_DRAWS_ATTENTION,
- NUM_PROPERTIES
-};
-
-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)
-{
- MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object);
-
- g_clear_object (&msg->icon);
-
- G_OBJECT_CLASS (messaging_menu_message_parent_class)->dispose (object);
-}
-
-static void
-messaging_menu_message_finalize (GObject *object)
-{
- MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object);
-
- g_free (msg->id);
- g_free (msg->title);
- 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);
-}
-
-static void
-messaging_menu_message_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object);
-
- switch (property_id)
- {
- case PROP_ID:
- g_value_set_string (value, msg->id);
- break;
-
- case PROP_ICON:
- g_value_set_object (value, msg->icon);
- break;
-
- case PROP_TITLE:
- g_value_set_string (value, msg->title);
- break;
-
- case PROP_SUBTITLE:
- g_value_set_string (value, msg->subtitle);
- break;
-
- case PROP_BODY:
- g_value_set_string (value, msg->body);
-
- case PROP_TIME:
- g_value_set_int64 (value, msg->time);
- break;
-
- case PROP_DRAWS_ATTENTION:
- g_value_set_boolean (value, msg->draws_attention);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-messaging_menu_message_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object);
-
- switch (property_id)
- {
- case PROP_ID:
- msg->id = g_value_dup_string (value);
- break;
-
- case PROP_ICON:
- msg->icon = g_value_dup_object (value);
- break;
-
- case PROP_TITLE:
- msg->title = g_value_dup_string (value);
- break;
-
- case PROP_SUBTITLE:
- msg->subtitle = g_value_dup_string (value);
- break;
-
- case PROP_BODY:
- msg->body = g_value_dup_string (value);
-
- case PROP_TIME:
- msg->time = g_value_get_int64 (value);
- break;
-
- case PROP_DRAWS_ATTENTION:
- messaging_menu_message_set_draws_attention (msg, g_value_get_boolean (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-messaging_menu_message_class_init (MessagingMenuMessageClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = messaging_menu_message_dispose;
- object_class->finalize = messaging_menu_message_finalize;
- object_class->get_property = messaging_menu_message_get_property;
- object_class->set_property = messaging_menu_message_set_property;
-
- properties[PROP_ID] = g_param_spec_string ("id", "Id",
- "Unique id of the message",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- properties[PROP_ICON] = g_param_spec_object ("icon", "Icon",
- "Icon of the message",
- G_TYPE_ICON,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- properties[PROP_TITLE] = g_param_spec_string ("title", "Title",
- "Title of the message",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- properties[PROP_SUBTITLE] = g_param_spec_string ("subtitle", "Subtitle",
- "Subtitle of the message",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- properties[PROP_BODY] = g_param_spec_string ("body", "Body",
- "First lines of the body of the message",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- properties[PROP_TIME] = g_param_spec_int64 ("time", "Time",
- "Time the message was sent, in microseconds", 0, G_MAXINT64, 0,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- properties[PROP_DRAWS_ATTENTION] = g_param_spec_boolean ("draws-attention", "Draws attention",
- "Whether the message should draw attention",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (klass, NUM_PROPERTIES, properties);
-
- /**
- * MessagingMenuMessage::activate:
- * @msg: the #MessagingMenuMessage
- * @action: (allow-none): the id of activated action, or %NULL
- * @parameter: (allow-none): activation parameter, or %NULL
- *
- * Emitted when the user has activated the 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().
- */
- g_signal_new ("activate",
- MESSAGING_MENU_TYPE_MESSAGE,
- G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_VARIANT);
-}
-
-static void
-messaging_menu_message_init (MessagingMenuMessage *self)
-{
-}
-
-/**
- * messaging_menu_message_new:
- * @id: unique id of 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
- * @time: the time the message was received
- *
- * Creates a new #MessagingMenuMessage.
- *
- * Returns: (transfer full): a new #MessagingMenuMessage
- */
-MessagingMenuMessage *
-messaging_menu_message_new (const gchar *id,
- GIcon *icon,
- const gchar *title,
- const gchar *subtitle,
- const gchar *body,
- gint64 time)
-{
- g_return_val_if_fail (id != NULL, NULL);
- g_return_val_if_fail (title != NULL, NULL);
-
- return g_object_new (MESSAGING_MENU_TYPE_MESSAGE,
- "id", id,
- "icon", icon,
- "title", title,
- "subtitle", subtitle,
- "body", body,
- "time", time,
- NULL);
-}
-
-/**
- * messaging_menu_message_get_id:
- * @msg: a #MessagingMenuMessage
- *
- * Returns: the unique id of @msg
- */
-const gchar *
-messaging_menu_message_get_id (MessagingMenuMessage *msg)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL);
-
- return msg->id;
-}
-
-/**
- * messaging_menu_message_get_icon:
- * @msg: a #MessagingMenuMessage
- *
- * Returns: (transfer none): the icon of @msg
- */
-GIcon *
-messaging_menu_message_get_icon (MessagingMenuMessage *msg)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL);
-
- return msg->icon;
-}
-
-/**
- * messaging_menu_message_get_title:
- * @msg: a #MessagingMenuMessage
- *
- * Returns: the title of @msg
- */
-const gchar *
-messaging_menu_message_get_title (MessagingMenuMessage *msg)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL);
-
- return msg->title;
-}
-
-/**
- * messaging_menu_message_get_subtitle:
- * @msg: a #MessagingMenuMessage
- *
- * Returns: the subtitle of @msg
- */
-const gchar *
-messaging_menu_message_get_subtitle (MessagingMenuMessage *msg)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL);
-
- return msg->subtitle;
-}
-
-/**
- * messaging_menu_message_get_body:
- * @msg: a #MessagingMenuMessage
- *
- * Returns: the body of @msg
- */
-const gchar *
-messaging_menu_message_get_body (MessagingMenuMessage *msg)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL);
-
- return msg->body;
-}
-
-/**
- * messaging_menu_message_get_time:
- * @msg: a #MessagingMenuMessage
- *
- * Returns: the time at which @msg was received
- */
-gint64
-messaging_menu_message_get_time (MessagingMenuMessage *msg)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), 0);
-
- return msg->time;
-}
-
-/**
- * messaging_menu_message_get_draws_attention:
- * @msg: a #MessagingMenuMessage
- *
- * Returns: whether @msg is drawing attention
- */
-gboolean
-messaging_menu_message_get_draws_attention (MessagingMenuMessage *msg)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), FALSE);
-
- return msg->draws_attention;
-}
-
-/**
- * messaging_menu_message_set_draws_attention:
- * @msg: a #MessagingMenuMessage
- * @draws_attention: whether @msg should draw attention
- *
- * Sets whether @msg is drawing attention.
- */
-void
-messaging_menu_message_set_draws_attention (MessagingMenuMessage *msg,
- gboolean draws_attention)
-{
- g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (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 ("a{sv}"));
-
- g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string (action->id));
-
- if (action->label)
- g_variant_builder_add (&builder, "{sv}", "label", g_variant_new_string (action->label));
-
- if (action->parameter_type)
- {
- gchar *type = g_variant_type_dup_string (action->parameter_type);
- g_variant_builder_add (&builder, "{sv}", "parameter-type", g_variant_new_signature (type));
- g_free (type);
- }
-
- if (action->parameter_hint)
- g_variant_builder_add (&builder, "{sv}", "parameter-hint", action->parameter_hint);
-
- return g_variant_builder_end (&builder);
-}
-
-/*<internal>
- * _messaging_menu_message_to_variant:
- * @msg: a #MessagingMenuMessage
- *
- * Serializes @msg to a #GVariant of the form (sssssxaa{sv}b):
- *
- * id
- * icon
- * title
- * subtitle
- * body
- * time
- * array of action dictionaries
- * 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 ("(sssssxaa{sv}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 ("aa{sv}"));
- 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
deleted file mode 100644
index 4708246..0000000
--- a/libmessaging-menu/messaging-menu-message.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Lars Uebernickel <lars.uebernickel@canonical.com>
- */
-
-#ifndef __messaging_menu_message_h__
-#define __messaging_menu_message_h__
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define MESSAGING_MENU_TYPE_MESSAGE (messaging_menu_message_get_type ())
-#define MESSAGING_MENU_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MESSAGING_MENU_TYPE_MESSAGE, MessagingMenuMessage))
-#define MESSAGING_MENU_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MESSAGING_MENU_TYPE_MESSAGE, MessagingMenuMessageClass))
-#define MESSAGING_MENU_IS_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MESSAGING_MENU_TYPE_MESSAGE))
-#define MESSAGING_MENU_IS_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MESSAGING_MENU_TYPE_MESSAGE))
-#define MESSAGING_MENU_MESSAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MESSAGING_MENU_TYPE_MESSAGE, MessagingMenuMessageClass))
-
-typedef struct _MessagingMenuMessage MessagingMenuMessage;
-
-GType messaging_menu_message_get_type (void) G_GNUC_CONST;
-
-MessagingMenuMessage * messaging_menu_message_new (const gchar *id,
- GIcon *icon,
- const gchar *title,
- const gchar *subtitle,
- const gchar *body,
- gint64 time);
-
-const gchar * messaging_menu_message_get_id (MessagingMenuMessage *msg);
-
-GIcon * messaging_menu_message_get_icon (MessagingMenuMessage *msg);
-
-const gchar * messaging_menu_message_get_title (MessagingMenuMessage *msg);
-
-const gchar * messaging_menu_message_get_subtitle (MessagingMenuMessage *msg);
-
-const gchar * messaging_menu_message_get_body (MessagingMenuMessage *msg);
-
-gint64 messaging_menu_message_get_time (MessagingMenuMessage *msg);
-
-gboolean messaging_menu_message_get_draws_attention (MessagingMenuMessage *msg);
-
-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/libmessaging-menu/messaging-menu-app.c b/libmessaging-menu/messaging-menu.c
index 421a09f..467a67a 100644
--- a/libmessaging-menu/messaging-menu-app.c
+++ b/libmessaging-menu/messaging-menu.c
@@ -17,12 +17,10 @@
* Lars Uebernickel <lars.uebernickel@canonical.com>
*/
-#include "messaging-menu-app.h"
+#include "messaging-menu.h"
#include "indicator-messages-service.h"
-#include "indicator-messages-application.h"
#include <gio/gdesktopappinfo.h>
-#include <string.h>
/**
* SECTION:messaging-menu
@@ -104,14 +102,14 @@ struct _MessagingMenuApp
int registered; /* -1 for unknown */
MessagingMenuStatus status;
gboolean status_set;
+ GSimpleActionGroup *source_actions;
+ GMenu *menu;
GDBusConnection *bus;
- GHashTable *messages;
- GList *sources;
- IndicatorMessagesApplication *app_interface;
-
IndicatorMessagesService *messages_service;
guint watch_id;
+ guint action_export_id;
+ guint menu_export_id;
GCancellable *cancellable;
};
@@ -135,61 +133,10 @@ static guint signals[N_SIGNALS];
static const gchar *status_ids[] = { "available", "away", "busy", "invisible", "offline" };
-typedef struct
-{
- gchar *id;
- GIcon *icon;
- gchar *label;
-
- guint32 count;
- gint64 time;
- gchar *string;
- gboolean draws_attention;
-} Source;
-
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)
-{
- Source *source = data;
-
- if (source)
- {
- g_free (source->id);
- g_clear_object (&source->icon);
- g_free (source->label);
- g_free (source->string);
- g_slice_free (Source, source);
- }
-}
-
-static GVariant *
-source_to_variant (Source *source)
-{
- GVariant *v;
- gchar *iconstr;
-
- iconstr = source->icon ? g_icon_to_string (source->icon) : NULL;
-
- v = g_variant_new ("(sssuxsb)", source->id,
- source->label,
- iconstr ? iconstr : "",
- source->count,
- source->time,
- source->string ? source->string : "",
- source->draws_attention);
-
- g_free (iconstr);
-
- return v;
-}
-
static gchar *
messaging_menu_app_get_dbus_object_path (MessagingMenuApp *app)
{
@@ -208,14 +155,18 @@ messaging_menu_app_get_dbus_object_path (MessagingMenuApp *app)
}
static void
-messaging_menu_app_got_bus (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
+export_menus_and_actions (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
{
MessagingMenuApp *app = user_data;
GError *error = NULL;
gchar *object_path;
+ object_path = messaging_menu_app_get_dbus_object_path (app);
+ if (!object_path)
+ return;
+
app->bus = g_bus_get_finish (res, &error);
if (app->bus == NULL)
{
@@ -224,13 +175,23 @@ messaging_menu_app_got_bus (GObject *source,
return;
}
- object_path = messaging_menu_app_get_dbus_object_path (app);
+ app->action_export_id = g_dbus_connection_export_action_group (app->bus,
+ object_path,
+ G_ACTION_GROUP (app->source_actions),
+ &error);
+ if (!app->action_export_id)
+ {
+ g_warning ("unable to export action group: %s", error->message);
+ g_clear_error (&error);
+ }
- if (object_path &&
- !g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (app->app_interface),
- app->bus, object_path, &error))
+ app->menu_export_id = g_dbus_connection_export_menu_model (app->bus,
+ object_path,
+ G_MENU_MODEL (app->menu),
+ &error);
+ if (!app->menu_export_id)
{
- g_warning ("unable to export application interface: %s", error->message);
+ g_warning ("unable to export menu: %s", error->message);
g_clear_error (&error);
}
@@ -253,7 +214,7 @@ messaging_menu_app_set_desktop_id (MessagingMenuApp *app,
g_bus_get (G_BUS_TYPE_SESSION,
app->cancellable,
- messaging_menu_app_got_bus,
+ export_menus_and_actions,
app);
}
@@ -287,6 +248,20 @@ messaging_menu_app_dispose (GObject *object)
{
MessagingMenuApp *app = MESSAGING_MENU_APP (object);
+ if (app->bus)
+ {
+ if (app->action_export_id > 0)
+ g_dbus_connection_unexport_action_group (app->bus, app->action_export_id);
+
+ if (app->menu_export_id > 0)
+ g_dbus_connection_unexport_menu_model (app->bus, app->menu_export_id);
+
+ app->action_export_id = 0;
+ app->menu_export_id = 0;
+ g_object_unref (app->bus);
+ app->bus = NULL;
+ }
+
if (app->watch_id > 0)
{
g_bus_unwatch_name (app->watch_id);
@@ -312,14 +287,9 @@ 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);
- g_clear_object (&app->bus);
+ g_clear_object (&app->source_actions);
+ g_clear_object (&app->menu);
G_OBJECT_CLASS (messaging_menu_app_parent_class)->dispose (object);
}
@@ -450,168 +420,6 @@ indicator_messages_vanished (GDBusConnection *bus,
}
}
-static gboolean
-messaging_menu_app_list_sources (IndicatorMessagesApplication *app_interface,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- MessagingMenuApp *app = user_data;
- GVariantBuilder builder;
- GList *it;
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssuxsb)"));
-
- for (it = app->sources; it; it = it->next)
- g_variant_builder_add_value (&builder, source_to_variant (it->data));
-
- indicator_messages_application_complete_list_sources (app_interface,
- invocation,
- g_variant_builder_end (&builder));
-
- return TRUE;
-}
-
-static gint
-compare_source_id (gconstpointer a,
- gconstpointer b)
-{
- const Source *source = a;
- const gchar *id = b;
-
- return strcmp (source->id, id);
-}
-
-static gboolean
-messaging_menu_app_remove_source_internal (MessagingMenuApp *app,
- const gchar *source_id)
-{
- GList *node;
-
- node = g_list_find_custom (app->sources, source_id, compare_source_id);
- if (node)
- {
- source_free (node->data);
- app->sources = g_list_delete_link (app->sources, node);
- return TRUE;
- }
-
- return FALSE;
-}
-
-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,
- gpointer user_data)
-{
- MessagingMenuApp *app = user_data;
- GQuark q = g_quark_from_string (source_id);
-
- /* 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);
-
- indicator_messages_application_complete_activate_source (app_interface, invocation);
-
- 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(sssssxaa{sv}b)"));
-
- 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,
- const gchar *action_id,
- GVariant *params,
- gpointer user_data)
-{
- MessagingMenuApp *app = user_data;
- MessagingMenuMessage *msg;
-
- msg = g_hash_table_lookup (app->messages, message_id);
- if (msg)
- {
- if (*action_id)
- {
- gchar *signal;
-
- signal = g_strconcat ("activate::", action_id, NULL);
-
- if (g_variant_n_children (params))
- {
- GVariant *param;
-
- g_variant_get_child (params, 0, "v", &param);
- g_signal_emit_by_name (msg, signal, action_id, param);
-
- g_variant_unref (param);
- }
- else
- g_signal_emit_by_name (msg, signal, action_id, NULL);
-
- g_free (signal);
- }
- else
- g_signal_emit_by_name (msg, "activate", NULL, NULL);
-
-
- /* 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 gboolean
-messaging_menu_app_dismiss (IndicatorMessagesApplication *app_interface,
- GDBusMethodInvocation *invocation,
- const gchar * const *sources,
- const gchar * const *messages,
- gpointer user_data)
-{
- MessagingMenuApp *app = user_data;
- const gchar * const *it;
-
- for (it = sources; *it; it++)
- messaging_menu_app_remove_source_internal (app, *it);
-
- for (it = messages; *it; it++)
- messaging_menu_app_remove_message_internal (app, *it);
-
- return TRUE;
-}
-
static void
messaging_menu_app_init (MessagingMenuApp *app)
{
@@ -619,21 +427,15 @@ messaging_menu_app_init (MessagingMenuApp *app)
app->status_set = FALSE;
app->bus = NULL;
+ app->action_export_id = 0;
+ app->menu_export_id = 0;
+
app->cancellable = g_cancellable_new ();
- app->app_interface = indicator_messages_application_skeleton_new ();
- g_signal_connect (app->app_interface, "handle-list-sources",
- 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);
- g_signal_connect (app->app_interface, "handle-dismiss",
- G_CALLBACK (messaging_menu_app_dismiss), app);
+ app->source_actions = g_simple_action_group_new ();
+ app->menu = g_menu_new ();
- app->messages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ app->cancellable = g_cancellable_new ();
app->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
"com.canonical.indicator.messages",
@@ -806,73 +608,124 @@ global_status_changed (IndicatorMessagesService *service,
g_signal_emit (app, signals[STATUS_CHANGED], 0, status);
}
-static Source *
-messaging_menu_app_lookup_source (MessagingMenuApp *app,
- const gchar *id)
+static void
+source_action_activated (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ MessagingMenuApp *app = user_data;
+ const gchar *name = g_action_get_name (G_ACTION (action));
+ GQuark q = g_quark_from_string (name);
+
+ messaging_menu_app_remove_source (app, name);
+
+ g_signal_emit (app, signals[ACTIVATE_SOURCE], q, name);
+}
+
+static void
+messaging_menu_app_insert_source_action (MessagingMenuApp *app,
+ gint position,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label,
+ GVariant *state)
{
- GList *node;
+ GSimpleAction *action;
+ GMenuItem *menuitem;
+
+ g_return_if_fail (MESSAGING_MENU_IS_APP (app));
+ g_return_if_fail (id != NULL);
+
+ if (g_simple_action_group_lookup (app->source_actions, id))
+ {
+ g_warning ("a source with id '%s' already exists", id);
+ return;
+ }
- node = g_list_find_custom (app->sources, id, compare_source_id);
+ action = g_simple_action_new_stateful (id, NULL, state);
+ g_signal_connect (action, "activate",
+ G_CALLBACK (source_action_activated), app);
+ g_simple_action_group_insert (app->source_actions, G_ACTION (action));
+ g_object_unref (action);
- return node ? node->data : NULL;
+ menuitem = g_menu_item_new (label, NULL);
+ g_menu_item_set_action_and_target_value (menuitem, id, NULL);
+ g_menu_item_set_attribute (menuitem, "x-canonical-type", "s", "ImSourceMenuItem");
+ if (icon)
+ {
+ gchar *iconstr = g_icon_to_string (icon);
+ g_menu_item_set_attribute (menuitem, "x-canonical-icon", "s", iconstr);
+ g_free (iconstr);
+ }
+ g_menu_insert_item (app->menu, position, menuitem);
+ g_object_unref (menuitem);
}
-static Source *
-messaging_menu_app_get_source (MessagingMenuApp *app,
- const gchar *id)
+static GSimpleAction *
+messaging_menu_app_get_source_action (MessagingMenuApp *app,
+ const gchar *source_id)
+
{
- Source *source;
+ GAction *action;
- source = messaging_menu_app_lookup_source (app, id);
- if (!source)
- g_warning ("a source with id '%s' doesn't exist", id);
+ g_return_val_if_fail (MESSAGING_MENU_IS_APP (app), NULL);
+ g_return_val_if_fail (source_id != NULL, NULL);
- return source;
+ action = g_simple_action_group_lookup (app->source_actions, source_id);
+ if (action == NULL)
+ g_warning ("a source with id '%s' doesn't exist", source_id);
+
+ return G_SIMPLE_ACTION (action);
}
static void
-messaging_menu_app_notify_source_changed (MessagingMenuApp *app,
- Source *source)
+messaging_menu_app_set_source_action (MessagingMenuApp *app,
+ const gchar *source_id,
+ guint count,
+ gint64 time,
+ const gchar *string)
{
- indicator_messages_application_emit_source_changed (app->app_interface,
- source_to_variant (source));
+ GSimpleAction *action;
+ GVariant *state;
+ gboolean draws_attention;
+ GVariant *new_state;
+
+ action = messaging_menu_app_get_source_action (app, source_id);
+ if (!action)
+ return;
+
+ state = g_action_get_state (G_ACTION (action));
+ g_variant_get_child (state, 3, "b", &draws_attention);
+
+ new_state = g_variant_new ("(uxsb)", count, time, string, draws_attention);
+ g_simple_action_set_state (action, new_state);
+
+ g_variant_unref (state);
}
static void
-messaging_menu_app_insert_source_internal (MessagingMenuApp *app,
- gint position,
- const gchar *id,
- GIcon *icon,
- const gchar *label,
- guint count,
- gint64 time,
- const gchar *string)
+messaging_menu_app_set_draws_attention (MessagingMenuApp *app,
+ const gchar *source_id,
+ gboolean draws_attention)
{
- Source *source;
+ GSimpleAction *action;
+ GVariant *state;
+ guint count;
+ gint64 time;
+ const gchar *string;
+ GVariant *new_state;
- g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (id != NULL);
- g_return_if_fail (label != NULL);
+ action = messaging_menu_app_get_source_action (app, source_id);
+ if (!action)
+ return;
- if (messaging_menu_app_lookup_source (app, id))
- {
- g_warning ("a source with id '%s' already exists", id);
- return;
- }
+ state = g_action_get_state (G_ACTION (action));
+ g_variant_get (state, "(ux&sb)", &count, &time, &string, NULL);
- source = g_slice_new0 (Source);
- source->id = g_strdup (id);
- source->label = g_strdup (label);
- if (icon)
- source->icon = g_object_ref (icon);
- source->count = count;
- source->time = time;
- source->string = g_strdup (string);
- app->sources = g_list_insert (app->sources, source, position);
-
- indicator_messages_application_emit_source_added (app->app_interface,
- position,
- source_to_variant (source));
+ new_state = g_variant_new ("(uxsb)", count, time, string, draws_attention);
+ g_simple_action_set_state (action, new_state);
+
+ g_variant_unref (state);
}
/**
@@ -949,7 +802,8 @@ messaging_menu_app_insert_source_with_count (MessagingMenuApp *app,
const gchar *label,
guint count)
{
- messaging_menu_app_insert_source_internal (app, position, id, icon, label, count, 0, "");
+ messaging_menu_app_insert_source_action (app, position, id, icon, label,
+ g_variant_new ("(uxsb)", count, 0, "", FALSE));
}
/**
@@ -1003,7 +857,8 @@ messaging_menu_app_insert_source_with_time (MessagingMenuApp *app,
const gchar *label,
gint64 time)
{
- messaging_menu_app_insert_source_internal (app, position, id, icon, label, 0, time, "");
+ messaging_menu_app_insert_source_action (app, position, id, icon, label,
+ g_variant_new ("(uxsb)", 0, time, "", FALSE));
}
/**
@@ -1059,7 +914,8 @@ messaging_menu_app_insert_source_with_string (MessagingMenuApp *app,
const gchar *label,
const gchar *str)
{
- messaging_menu_app_insert_source_internal (app, position, id, icon, label, 0, 0, str);
+ messaging_menu_app_insert_source_action (app, position, id, icon, label,
+ g_variant_new ("(uxsb)", 0, 0, str, FALSE));
}
/**
@@ -1099,11 +955,34 @@ void
messaging_menu_app_remove_source (MessagingMenuApp *app,
const gchar *source_id)
{
+ int n_items;
+ int i;
+
g_return_if_fail (MESSAGING_MENU_IS_APP (app));
g_return_if_fail (source_id != NULL);
- if (messaging_menu_app_remove_source_internal (app, source_id))
- indicator_messages_application_emit_source_removed (app->app_interface, source_id);
+ if (g_simple_action_group_lookup (app->source_actions, source_id) == NULL)
+ return;
+
+ n_items = g_menu_model_get_n_items (G_MENU_MODEL (app->menu));
+ for (i = 0; i < n_items; i++)
+ {
+ gchar *action;
+
+ if (g_menu_model_get_item_attribute (G_MENU_MODEL (app->menu), i,
+ "action", "s", &action))
+ {
+ if (!g_strcmp0 (action, source_id))
+ {
+ g_menu_remove (app->menu, i);
+ break;
+ }
+
+ g_free (action);
+ }
+ }
+
+ g_simple_action_group_remove (app->source_actions, source_id);
}
/**
@@ -1120,7 +999,46 @@ messaging_menu_app_has_source (MessagingMenuApp *app,
g_return_val_if_fail (MESSAGING_MENU_IS_APP (app), FALSE);
g_return_val_if_fail (source_id != NULL, FALSE);
- return messaging_menu_app_lookup_source (app, source_id) != NULL;
+ return g_simple_action_group_lookup (app->source_actions, source_id) != NULL;
+}
+
+static GMenuItem *
+g_menu_find_item_with_action (GMenu *menu,
+ const gchar *action,
+ gint *out_pos)
+{
+ gint i;
+ gint n_elements;
+ GMenuItem *item = NULL;
+
+ n_elements = g_menu_model_get_n_items (G_MENU_MODEL (menu));
+
+ for (i = 0; i < n_elements && item == NULL; i++)
+ {
+ GVariant *attr;
+
+ item = g_menu_item_new_from_model (G_MENU_MODEL (menu), i);
+ attr = g_menu_item_get_attribute_value (item, G_MENU_ATTRIBUTE_ACTION, G_VARIANT_TYPE_STRING);
+
+ if (!g_str_equal (action, g_variant_get_string (attr, NULL)))
+ g_clear_object (&item);
+
+ g_variant_unref (attr);
+ }
+
+ if (item && out_pos)
+ *out_pos = i - 1;
+
+ return item;
+}
+
+static void
+g_menu_replace_item (GMenu *menu,
+ gint pos,
+ GMenuItem *item)
+{
+ g_menu_remove (menu, pos);
+ g_menu_insert_item (menu, pos, item);
}
/**
@@ -1136,19 +1054,21 @@ messaging_menu_app_set_source_label (MessagingMenuApp *app,
const gchar *source_id,
const gchar *label)
{
- Source *source;
+ gint pos;
+ GMenuItem *item;
g_return_if_fail (MESSAGING_MENU_IS_APP (app));
g_return_if_fail (source_id != NULL);
g_return_if_fail (label != NULL);
- source = messaging_menu_app_get_source (app, source_id);
- if (source)
- {
- g_free (source->label);
- source->label = g_strdup (label);
- messaging_menu_app_notify_source_changed (app, source);
- }
+ item = g_menu_find_item_with_action (app->menu, source_id, &pos);
+ if (item == NULL)
+ return;
+
+ g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_LABEL, "s", label);
+ g_menu_replace_item (app->menu, pos, item);
+
+ g_object_unref (item);
}
/**
@@ -1164,19 +1084,33 @@ messaging_menu_app_set_source_icon (MessagingMenuApp *app,
const gchar *source_id,
GIcon *icon)
{
- Source *source;
+ gint pos;
+ GMenuItem *item;
g_return_if_fail (MESSAGING_MENU_IS_APP (app));
g_return_if_fail (source_id != NULL);
- source = messaging_menu_app_get_source (app, source_id);
- if (source)
+ item = g_menu_find_item_with_action (app->menu, source_id, &pos);
+ if (item == NULL)
+ return;
+
+ if (icon)
+ {
+ gchar *iconstr;
+
+ iconstr = g_icon_to_string (icon);
+ g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr);
+
+ g_free (iconstr);
+ }
+ else
{
- g_clear_object (&source->icon);
- if (icon)
- source->icon = g_object_ref (icon);
- messaging_menu_app_notify_source_changed (app, source);
+ g_menu_item_set_attribute_value (item, "x-canonical-icon", NULL);
}
+
+ g_menu_replace_item (app->menu, pos, item);
+
+ g_object_unref (item);
}
/**
@@ -1191,17 +1125,7 @@ void messaging_menu_app_set_source_count (MessagingMenuApp *app,
const gchar *source_id,
guint count)
{
- Source *source;
-
- g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (source_id != NULL);
-
- source = messaging_menu_app_get_source (app, source_id);
- if (source)
- {
- source->count = count;
- messaging_menu_app_notify_source_changed (app, source);
- }
+ messaging_menu_app_set_source_action (app, source_id, count, 0, "");
}
/**
@@ -1217,17 +1141,7 @@ messaging_menu_app_set_source_time (MessagingMenuApp *app,
const gchar *source_id,
gint64 time)
{
- Source *source;
-
- g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (source_id != NULL);
-
- source = messaging_menu_app_get_source (app, source_id);
- if (source)
- {
- source->time = time;
- messaging_menu_app_notify_source_changed (app, source);
- }
+ messaging_menu_app_set_source_action (app, source_id, 0, time, "");
}
/**
@@ -1243,18 +1157,7 @@ messaging_menu_app_set_source_string (MessagingMenuApp *app,
const gchar *source_id,
const gchar *str)
{
- Source *source;
-
- g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (source_id != NULL);
-
- source = messaging_menu_app_get_source (app, source_id);
- if (source)
- {
- g_free (source->string);
- source->string = g_strdup (str);
- messaging_menu_app_notify_source_changed (app, source);
- }
+ messaging_menu_app_set_source_action (app, source_id, 0, 0, str);
}
/**
@@ -1272,17 +1175,7 @@ void
messaging_menu_app_draw_attention (MessagingMenuApp *app,
const gchar *source_id)
{
- Source *source;
-
- g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (source_id != NULL);
-
- source = messaging_menu_app_get_source (app, source_id);
- if (source)
- {
- source->draws_attention = TRUE;
- messaging_menu_app_notify_source_changed (app, source);
- }
+ messaging_menu_app_set_draws_attention (app, source_id, TRUE);
}
/**
@@ -1303,131 +1196,5 @@ void
messaging_menu_app_remove_attention (MessagingMenuApp *app,
const gchar *source_id)
{
- Source *source;
-
- g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (source_id != NULL);
-
- source = messaging_menu_app_get_source (app, source_id);
- if (source)
- {
- source->draws_attention = FALSE;
- messaging_menu_app_notify_source_changed (app, source);
- }
-}
-
-/**
- * messaging_menu_app_append_message:
- * @app: a #MessagingMenuApp
- * @msg: the #MessagingMenuMessage to append
- * @source_id: (allow-none): the source id to which @msg is added, or NULL
- * @notify: whether a notification bubble should be shown for this
- * message
- *
- * Appends @msg to the source with id @source_id of @app. The messaging
- * menu might not display this message immediately if other messages are
- * queued before this one.
- *
- * If @source_id has a count associated with it, that count will be
- * increased by one.
- *
- * If @source_id is %NULL, @msg won't be associated with a source.
- */
-void
-messaging_menu_app_append_message (MessagingMenuApp *app,
- MessagingMenuMessage *msg,
- 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 (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);
- }
- }
-}
-
-/**
- * messaging_menu_app_get_message:
- * @app: a #MessagingMenuApp
- * @id: id of the message to retrieve
- *
- * Retrieves the message with @id, that was added with
- * messaging_menu_app_append_message().
- *
- * Returns: (transfer none) (allow-none): the #MessagingMenuApp with
- * @id, or %NULL
- */
-MessagingMenuMessage *
-messaging_menu_app_get_message (MessagingMenuApp *app,
- const gchar *id)
-{
- g_return_val_if_fail (MESSAGING_MENU_IS_APP (app), NULL);
- g_return_val_if_fail (id != NULL, NULL);
-
- return g_hash_table_lookup (app->messages, id);
-}
-
-/**
- * messaging_menu_app_remove_message:
- * @app: a #MessagingMenuApp
- * @msg: the #MessagingMenuMessage to remove
- *
- * Removes @msg from @app.
- *
- * If @source_id has a count associated with it, that count will be
- * decreased by one.
- */
-void
-messaging_menu_app_remove_message (MessagingMenuApp *app,
- MessagingMenuMessage *msg)
-{
- /* take a ref of @msg here to make sure the pointer returned by
- * _get_id() is valid for the duration of remove_message_by_id. */
- g_object_ref (msg);
- messaging_menu_app_remove_message_by_id (app, messaging_menu_message_get_id (msg));
- g_object_unref (msg);
-}
-
-/**
- * messaging_menu_app_remove_message_by_id:
- * @app: a #MessagingMenuApp
- * @id: the unique id of @msg
- *
- * Removes the message with the id @id from @app.
- *
- * If @source_id has a count associated with it, that count will be
- * decreased by one.
- */
-void
-messaging_menu_app_remove_message_by_id (MessagingMenuApp *app,
- const gchar *id)
-{
- 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_message_removed (app->app_interface, id);
+ messaging_menu_app_set_draws_attention (app, source_id, FALSE);
}
diff --git a/libmessaging-menu/messaging-menu.h b/libmessaging-menu/messaging-menu.h
index 929b229..6c405c7 100644
--- a/libmessaging-menu/messaging-menu.h
+++ b/libmessaging-menu/messaging-menu.h
@@ -20,6 +20,129 @@
#ifndef __messaging_menu_h__
#define __messaging_menu_h__
-#include "messaging-menu-app.h"
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define MESSAGING_MENU_TYPE_APP messaging_menu_app_get_type()
+#define MESSAGING_MENU_APP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MESSAGING_MENU_TYPE_APP, MessagingMenuApp))
+#define MESSAGING_MENU_APP_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), MESSAGING_MENU_TYPE_APP, MessagingMenuAppClass))
+#define MESSAGING_MENU_IS_APP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MESSAGING_MENU_TYPE_APP))
+
+/**
+ * MessagingMenuStatus:
+ * @MESSAGING_MENU_STATUS_AVAILABLE: available
+ * @MESSAGING_MENU_STATUS_AWAY: away
+ * @MESSAGING_MENU_STATUS_BUSY: busy
+ * @MESSAGING_MENU_STATUS_INVISIBLE: invisible
+ * @MESSAGING_MENU_STATUS_OFFLINE: offline
+ *
+ * An enumeration for the possible chat statuses the messaging menu can be in.
+ */
+typedef enum {
+ MESSAGING_MENU_STATUS_AVAILABLE,
+ MESSAGING_MENU_STATUS_AWAY,
+ MESSAGING_MENU_STATUS_BUSY,
+ MESSAGING_MENU_STATUS_INVISIBLE,
+ MESSAGING_MENU_STATUS_OFFLINE
+} MessagingMenuStatus;
+
+
+typedef GObjectClass MessagingMenuAppClass;
+typedef struct _MessagingMenuApp MessagingMenuApp;
+
+GType messaging_menu_app_get_type (void) G_GNUC_CONST;
+
+MessagingMenuApp * messaging_menu_app_new (const gchar *desktop_id);
+
+void messaging_menu_app_register (MessagingMenuApp *app);
+void messaging_menu_app_unregister (MessagingMenuApp *app);
+
+void messaging_menu_app_set_status (MessagingMenuApp *app,
+ MessagingMenuStatus status);
+
+void messaging_menu_app_insert_source (MessagingMenuApp *app,
+ gint position,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label);
+
+void messaging_menu_app_append_source (MessagingMenuApp *app,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label);
+
+void messaging_menu_app_insert_source_with_count (MessagingMenuApp *app,
+ gint position,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label,
+ guint count);
+
+void messaging_menu_app_append_source_with_count (MessagingMenuApp *app,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label,
+ guint count);
+
+void messaging_menu_app_insert_source_with_time (MessagingMenuApp *app,
+ gint position,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label,
+ gint64 time);
+
+void messaging_menu_app_append_source_with_time (MessagingMenuApp *app,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label,
+ gint64 time);
+
+void messaging_menu_app_append_source_with_string (MessagingMenuApp *app,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label,
+ const gchar *str);
+
+void messaging_menu_app_insert_source_with_string (MessagingMenuApp *app,
+ gint position,
+ const gchar *id,
+ GIcon *icon,
+ const gchar *label,
+ const gchar *str);
+
+void messaging_menu_app_remove_source (MessagingMenuApp *app,
+ const gchar *source_id);
+
+gboolean messaging_menu_app_has_source (MessagingMenuApp *app,
+ const gchar *source_id);
+
+void messaging_menu_app_set_source_label (MessagingMenuApp *app,
+ const gchar *source_id,
+ const gchar *label);
+
+void messaging_menu_app_set_source_icon (MessagingMenuApp *app,
+ const gchar *source_id,
+ GIcon *icon);
+
+void messaging_menu_app_set_source_count (MessagingMenuApp *app,
+ const gchar *source_id,
+ guint count);
+
+void messaging_menu_app_set_source_time (MessagingMenuApp *app,
+ const gchar *source_id,
+ gint64 time);
+
+void messaging_menu_app_set_source_string (MessagingMenuApp *app,
+ const gchar *source_id,
+ const gchar *str);
+
+void messaging_menu_app_draw_attention (MessagingMenuApp *app,
+ const gchar *source_id);
+
+void messaging_menu_app_remove_attention (MessagingMenuApp *app,
+ const gchar *source_id);
+
+G_END_DECLS
#endif