aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac9
-rw-r--r--libmessaging-menu/messaging-menu.c6
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/app-section.c8
-rw-r--r--src/dbus-data.h3
-rw-r--r--src/gmenuutils.c2
-rw-r--r--src/im-app-menu-item.c47
-rw-r--r--src/im-source-menu-item.c142
-rw-r--r--src/indicator-messages.c28
-rw-r--r--src/messages-service.c14
-rw-r--r--test/Makefile.am5
11 files changed, 230 insertions, 35 deletions
diff --git a/configure.ac b/configure.ac
index dc56181..d9270dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
-AC_INIT(indicator-messages, 0.6.0)
+AC_INIT(indicator-messages, 12.10.0)
AC_PREREQ(2.62)
@@ -38,11 +38,10 @@ AC_PROG_CXX
# Dependencies
###########################
-GTK_REQUIRED_VERSION=3.0
-GIO_UNIX_REQUIRED_VERSION=2.18
-PANEL_REQUIRED_VERSION=2.0.0
+GTK_REQUIRED_VERSION=3.5.12
+GIO_UNIX_REQUIRED_VERSION=2.33.10
INDICATOR_REQUIRED_VERSION=0.3.19
-GLIB_REQUIRED_VERSION=2.31.20
+GLIB_REQUIRED_VERSION=2.33.10
INTROSPECTION_REQUIRED_VERSION=1.32.0
PKG_CHECK_MODULES(APPLET, gtk+-3.0 >= $GTK_REQUIRED_VERSION
diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c
index ea33cd6..336e89c 100644
--- a/libmessaging-menu/messaging-menu.c
+++ b/libmessaging-menu/messaging-menu.c
@@ -442,9 +442,9 @@ messaging_menu_app_insert_source_action (MessagingMenuApp *app,
g_menu_item_set_attribute (menuitem, "x-canonical-type", "s", "ImSourceMenuItem");
if (icon)
{
- gchar *icon_name = g_icon_to_string (icon);
- g_menu_item_set_attribute (menuitem, "indicator-icon-name", icon_name);
- g_free (icon_name);
+ 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);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 21cd0b1..edb0388 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,4 +1,3 @@
[encoding: UTF-8]
-src/messages-service-dbus.c
src/indicator-messages.c
src/messages-service.c
diff --git a/src/app-section.c b/src/app-section.c
index f922dca..1574892 100644
--- a/src/app-section.c
+++ b/src/app-section.c
@@ -314,7 +314,7 @@ app_section_set_app_info (AppSection *self,
GSimpleAction *launch;
GFile *keyfile;
GMenuItem *item;
- gchar *iconname;
+ gchar *iconstr;
g_return_if_fail (priv->appinfo == NULL);
@@ -332,9 +332,9 @@ app_section_set_app_info (AppSection *self,
item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch");
g_menu_item_set_attribute (item, "x-canonical-type", "s", "ImAppMenuItem");
- iconname = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo)));
- g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconname);
- g_free (iconname);
+ iconstr = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo)));
+ g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr);
+ g_free (iconstr);
g_menu_append_item (priv->menu, item);
g_object_unref (item);
diff --git a/src/dbus-data.h b/src/dbus-data.h
index 3c72b81..64747a9 100644
--- a/src/dbus-data.h
+++ b/src/dbus-data.h
@@ -8,7 +8,4 @@
#define INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT "/com/canonical/indicator/messages/service"
#define INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE "com.canonical.indicator.messages.service"
-#define INDICATOR_MENU_ATTRIBUTE_ICON_NAME "indicator-icon-name"
-#define INDICATOR_MENU_ATTRIBUTE_ACCESSIBLE_DESCRIPTION "indicator-accessible-description"
-
#endif /* __DBUS_DATA_H__ */
diff --git a/src/gmenuutils.c b/src/gmenuutils.c
index 056e75f..f3ceba7 100644
--- a/src/gmenuutils.c
+++ b/src/gmenuutils.c
@@ -71,7 +71,7 @@ g_menu_append_with_icon_name (GMenu *menu,
GMenuItem *item;
item = g_menu_item_new (label, detailed_action);
- g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", icon_name);
+ g_menu_item_set_attribute (item, "x-canonical-icon", "s", icon_name);
g_menu_append_item (menu, item);
diff --git a/src/im-app-menu-item.c b/src/im-app-menu-item.c
index f4430be..eddf562 100644
--- a/src/im-app-menu-item.c
+++ b/src/im-app-menu-item.c
@@ -24,6 +24,9 @@ struct _ImAppMenuItemPrivate
GActionGroup *action_group;
gchar *action;
gboolean is_running;
+
+ GtkWidget *icon;
+ GtkWidget *label;
};
enum
@@ -39,6 +42,26 @@ static GParamSpec *properties[NUM_PROPERTIES];
G_DEFINE_TYPE (ImAppMenuItem, im_app_menu_item, GTK_TYPE_MENU_ITEM);
static void
+im_app_menu_item_constructed (GObject *object)
+{
+ ImAppMenuItemPrivate *priv = IM_APP_MENU_ITEM (object)->priv;
+ GtkWidget *grid;
+
+ priv->icon = g_object_ref (gtk_image_new ());
+
+ priv->label = g_object_ref (gtk_label_new (""));
+
+ grid = gtk_grid_new ();
+ gtk_grid_attach (GTK_GRID (grid), priv->icon, 0, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), priv->label, 1, 0, 1, 1);
+
+ gtk_container_add (GTK_CONTAINER (object), grid);
+ gtk_widget_show_all (grid);
+
+ G_OBJECT_CLASS (im_app_menu_item_parent_class)->constructed (object);
+}
+
+static void
im_app_menu_item_set_action_name (ImAppMenuItem *self,
const gchar *action_name)
{
@@ -156,6 +179,9 @@ im_app_menu_item_dispose (GObject *object)
if (self->priv->action_group)
im_app_menu_item_set_action_group (self, NULL);
+ g_clear_object (&self->priv->icon);
+ g_clear_object (&self->priv->label);
+
G_OBJECT_CLASS (im_app_menu_item_parent_class)->dispose (object);
}
@@ -223,6 +249,7 @@ im_app_menu_item_class_init (ImAppMenuItemClass *klass)
g_type_class_add_private (klass, sizeof (ImAppMenuItemPrivate));
+ object_class->constructed = im_app_menu_item_constructed;
object_class->set_property = im_app_menu_set_property;
object_class->dispose = im_app_menu_item_dispose;
object_class->finalize = im_app_menu_item_finalize;
@@ -260,15 +287,33 @@ void
im_app_menu_item_set_menu_item (ImAppMenuItem *self,
GMenuItem *menuitem)
{
+ gchar *iconstr = NULL;
+ GIcon *icon = NULL;
gchar *label;
gchar *action = NULL;
+ if (g_menu_item_get_attribute (menuitem, "x-canonical-icon", "s", &iconstr))
+ {
+ GError *error;
+
+ icon = g_icon_new_for_string (iconstr, &error);
+ if (icon == NULL)
+ {
+ g_warning ("unable to set icon: %s", error->message);
+ g_error_free (error);
+ }
+ g_free (iconstr);
+ }
+ gtk_image_set_from_gicon (GTK_IMAGE (self->priv->icon), icon, GTK_ICON_SIZE_MENU);
+
g_menu_item_get_attribute (menuitem, "label", "s", &label);
- gtk_menu_item_set_label (GTK_MENU_ITEM (self), label ? label : "");
+ gtk_label_set_label (GTK_LABEL (self->priv->label), label ? label : "");
g_menu_item_get_attribute (menuitem, "action", "s", &action);
im_app_menu_item_set_action_name (self, action);
+ if (icon)
+ g_object_unref (icon);
g_free (label);
g_free (action);
}
diff --git a/src/im-source-menu-item.c b/src/im-source-menu-item.c
index 82d553f..269c75d 100644
--- a/src/im-source-menu-item.c
+++ b/src/im-source-menu-item.c
@@ -19,12 +19,16 @@
#include "im-source-menu-item.h"
+#include <libintl.h>
+
struct _ImSourceMenuItemPrivate
{
GActionGroup *action_group;
gchar *action;
+ GtkWidget *icon;
GtkWidget *label;
+ GtkWidget *detail;
};
enum
@@ -48,11 +52,21 @@ im_source_menu_item_constructed (GObject *object)
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL);
+ priv->icon = g_object_ref (gtk_image_new ());
+ gtk_widget_set_margin_left (priv->icon, icon_width + 2);
+
priv->label = g_object_ref (gtk_label_new (""));
- gtk_widget_set_margin_left (priv->label, icon_width + 2);
+
+ priv->detail = g_object_ref (gtk_label_new (""));
+ gtk_widget_set_halign (priv->detail, GTK_ALIGN_END);
+ gtk_widget_set_hexpand (priv->detail, TRUE);
+ gtk_misc_set_alignment (GTK_MISC (priv->label), 1.0, 0.5);
+ gtk_style_context_add_class (gtk_widget_get_style_context (priv->detail), "accelerator");
grid = gtk_grid_new ();
- gtk_grid_attach (GTK_GRID (grid), priv->label, 0, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), priv->icon, 0, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), priv->label, 1, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), priv->detail, 2, 0, 1, 1);
gtk_container_add (GTK_CONTAINER (object), grid);
gtk_widget_show_all (grid);
@@ -60,6 +74,104 @@ im_source_menu_item_constructed (GObject *object)
G_OBJECT_CLASS (im_source_menu_item_parent_class)->constructed (object);
}
+/* collapse_whitespace:
+ * @str: the source string
+ *
+ * Collapses all occurences of consecutive whitespace charactes in @str
+ * into a single space.
+ *
+ * Returns: (transfer full): a newly-allocated string
+ */
+static gchar *
+collapse_whitespace (const gchar *str)
+{
+ GString *result;
+ gboolean in_space = FALSE;
+
+ if (str == NULL)
+ return NULL;
+
+ result = g_string_new ("");
+
+ while (*str)
+ {
+ gunichar c = g_utf8_get_char_validated (str, -1);
+
+ if (c < 0)
+ break;
+
+ if (!g_unichar_isspace (c))
+ {
+ g_string_append_unichar (result, c);
+ in_space = FALSE;
+ }
+ else if (!in_space)
+ {
+ g_string_append_c (result, ' ');
+ in_space = TRUE;
+ }
+
+ str = g_utf8_next_char (str);
+ }
+
+ return g_string_free (result, FALSE);
+}
+
+static gchar *
+im_source_menu_item_time_span_string (gint64 timestamp)
+{
+ gchar *str;
+ gint64 span;
+ gint hours;
+ gint minutes;
+
+ span = MAX (g_get_real_time () - timestamp, 0) / G_USEC_PER_SEC;
+ hours = span / 3600;
+ minutes = (span / 60) % 60;
+
+ if (hours == 0)
+ {
+ /* TRANSLATORS: number of minutes that have passed */
+ str = g_strdup_printf (ngettext ("%d m", "%d m", minutes), minutes);
+ }
+ else
+ {
+ /* TRANSLATORS: number of hours that have passed */
+ str = g_strdup_printf (ngettext ("%d h", "%d h", hours), hours);
+ }
+
+ return str;
+}
+
+static gboolean
+im_source_menu_item_set_state (ImSourceMenuItem *self,
+ GVariant *state)
+{
+ ImSourceMenuItemPrivate *priv = self->priv;
+ guint32 count;
+ gint64 time;
+ const gchar *str;
+ gchar *detail;
+
+ g_return_val_if_fail (g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)")), FALSE);
+
+ g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL);
+
+ if (count != 0)
+ detail = g_strdup_printf ("%d", count);
+ else if (time != 0)
+ detail = im_source_menu_item_time_span_string (time);
+ else if (str != NULL && *str)
+ detail = collapse_whitespace (str);
+ else
+ detail = NULL;
+
+ gtk_label_set_text (GTK_LABEL (priv->detail), detail ? detail : "");
+
+ g_free (detail);
+ return TRUE;
+}
+
static void
im_source_menu_item_set_action_name (ImSourceMenuItem *self,
const gchar *action_name)
@@ -77,7 +189,7 @@ im_source_menu_item_set_action_name (ImSourceMenuItem *self,
g_action_group_query_action (priv->action_group, priv->action,
&enabled, NULL, NULL, NULL, &state))
{
- if (!state || !g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)")))
+ if (!state || !im_source_menu_item_set_state (self, state))
enabled = FALSE;
if (state)
@@ -132,7 +244,7 @@ im_source_menu_item_action_state_changed (GActionGroup *action_group,
ImSourceMenuItem *self = user_data;
if (g_strcmp0 (self->priv->action, action_name) == 0)
- g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("(uxsb)")));
+ im_source_menu_item_set_state (self, value);
}
static void
@@ -166,6 +278,10 @@ im_source_menu_item_dispose (GObject *object)
if (self->priv->action_group)
im_source_menu_item_set_action_group (self, NULL);
+ g_clear_object (&self->priv->icon);
+ g_clear_object (&self->priv->label);
+ g_clear_object (&self->priv->detail);
+
G_OBJECT_CLASS (im_source_menu_item_parent_class)->dispose (object);
}
@@ -226,22 +342,38 @@ im_source_menu_item_init (ImSourceMenuItem *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
IM_TYPE_SOURCE_MENU_ITEM,
ImSourceMenuItemPrivate);
- g_message (G_STRFUNC);
}
void
im_source_menu_item_set_menu_item (ImSourceMenuItem *self,
GMenuItem *menuitem)
{
+ gchar *iconstr = NULL;
+ GIcon *icon = NULL;
gchar *label;
gchar *action = NULL;
+ if (g_menu_item_get_attribute (menuitem, "x-canonical-icon", "s", &iconstr))
+ {
+ GError *error;
+ icon = g_icon_new_for_string (iconstr, &error);
+ if (icon == NULL)
+ {
+ g_warning ("unable to set icon: %s", error->message);
+ g_error_free (error);
+ }
+ g_free (iconstr);
+ }
+ gtk_image_set_from_gicon (GTK_IMAGE (self->priv->icon), icon, GTK_ICON_SIZE_MENU);
+
g_menu_item_get_attribute (menuitem, "label", "s", &label);
gtk_label_set_label (GTK_LABEL (self->priv->label), label ? label : "");
g_menu_item_get_attribute (menuitem, "action", "s", &action);
im_source_menu_item_set_action_name (self, action);
+ if (icon)
+ g_object_unref (icon);
g_free (label);
g_free (action);
}
diff --git a/src/indicator-messages.c b/src/indicator-messages.c
index d898ad6..946da55 100644
--- a/src/indicator-messages.c
+++ b/src/indicator-messages.c
@@ -2,10 +2,11 @@
An indicator to show information that is in messaging applications
that the user is using.
-Copyright 2009 Canonical Ltd.
+Copyright 2012 Canonical Ltd.
Authors:
Ted Gould <ted@canonical.com>
+ Lars Uebernickel <lars.uebernickel@canonical.com>
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
@@ -232,21 +233,34 @@ indicator_messages_accessible_desc_updated (IndicatorMessages *self)
static void
update_root_item (IndicatorMessages * self)
{
- const gchar *icon_name;
+ gchar *iconstr;
if (g_menu_model_get_n_items (self->menu) == 0)
return;
- g_menu_model_get_item_attribute (self->menu, 0, INDICATOR_MENU_ATTRIBUTE_ICON_NAME,
- "&s", &icon_name);
+ if (g_menu_model_get_item_attribute (self->menu, 0, "x-canonical-icon", "s", &iconstr)) {
+ GIcon *icon;
+ GError *error;
+
+ icon = g_icon_new_for_string (iconstr, &error);
+ if (icon) {
+ gtk_image_set_from_gicon (GTK_IMAGE (self->image), icon, GTK_ICON_SIZE_MENU);
+ g_object_unref (icon);
+ }
+ else {
+ g_warning ("unable to load icon: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (iconstr);
+ }
g_free (self->accessible_desc);
+ self->accessible_desc = NULL;
- g_menu_model_get_item_attribute (self->menu, 0, INDICATOR_MENU_ATTRIBUTE_ACCESSIBLE_DESCRIPTION,
+ g_menu_model_get_item_attribute (self->menu, 0, "x-canonical-accessible-description",
"s", &self->accessible_desc);
indicator_messages_accessible_desc_updated (self);
-
- gtk_image_set_from_icon_name (GTK_IMAGE (self->image), icon_name, GTK_ICON_SIZE_MENU);
}
static void
diff --git a/src/messages-service.c b/src/messages-service.c
index aade829..407b8ba 100644
--- a/src/messages-service.c
+++ b/src/messages-service.c
@@ -2,10 +2,11 @@
An indicator to show information that is in messaging applications
that the user is using.
-Copyright 2009 Canonical Ltd.
+Copyright 2012 Canonical Ltd.
Authors:
Ted Gould <ted@canonical.com>
+ Lars Uebernickel <lars.uebernickel@canonical.com>
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
@@ -464,6 +465,8 @@ main (int argc, char ** argv)
GMainLoop * mainloop = NULL;
IndicatorService * service = NULL;
GMenuItem *header;
+ GIcon *icon;
+ gchar *iconstr;
/* Glib init */
g_type_init();
@@ -501,11 +504,14 @@ main (int argc, char ** argv)
chat_section = create_status_section ();
g_menu_append (menu, _("Clear"), "clear");
+ icon = g_themed_icon_new ("indicator-messages");
+ iconstr = g_icon_to_string (icon);
+
toplevel_menu = g_menu_new ();
header = g_menu_item_new (NULL, "messages");
g_menu_item_set_submenu (header, G_MENU_MODEL (menu));
- g_menu_item_set_attribute (header, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", "indicator-messages");
- g_menu_item_set_attribute (header, INDICATOR_MENU_ATTRIBUTE_ACCESSIBLE_DESCRIPTION, "s", _("Messages"));
+ g_menu_item_set_attribute (header, "x-canonical-icon", "s", iconstr);
+ g_menu_item_set_attribute (header, "x-canonical-accessible-description", "s", _("Messages"));
g_menu_append_item (toplevel_menu, header);
g_object_unref (header);
@@ -518,6 +524,8 @@ main (int argc, char ** argv)
g_main_loop_run(mainloop);
/* Clean up */
+ g_free (iconstr);
+ g_object_unref (icon);
g_object_unref (messages_service);
g_object_unref (chat_section);
g_object_unref (settings);
diff --git a/test/Makefile.am b/test/Makefile.am
index ebf2da2..4671446 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -38,8 +38,8 @@ noinst_LTLIBRARIES = \
libindicator-messages-service.la
libindicator_messages_service_la_SOURCES = \
- $(top_srcdir)/src/indicator-messages-service.c \
- $(top_srcdir)/src/indicator-messages-service.h \
+ $(top_builddir)/src/indicator-messages-service.c \
+ $(top_builddir)/src/indicator-messages-service.h \
$(top_srcdir)/src/app-section.c \
$(top_srcdir)/src/app-section.h \
$(top_srcdir)/src/gactionmuxer.c \
@@ -52,6 +52,7 @@ libindicator_messages_service_ladir = \
libindicator_messages_service_la_CFLAGS = \
$(APPLET_CFLAGS) \
$(COVERAGE_CFLAGS) \
+ -I$(top_builddir)/src \
-Wall \
-Wl,-Bsymbolic-functions \
-Wl,-z,defs \