aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkarl-qdh <karl@qdh.org.uk>2011-02-02 11:14:26 +0000
committerkarl-qdh <karl@qdh.org.uk>2011-02-02 11:14:26 +0000
commit5734c96d1e10bbc78532b07cb3fe127c609a7e16 (patch)
tree6d02f78d24f2063e0bb2ee1258932e96a0679091
parente0718f3613ae3a39a58e87cf1f4b2c4c00b76117 (diff)
downloadayatana-indicator-datetime-5734c96d1e10bbc78532b07cb3fe127c609a7e16.tar.gz
ayatana-indicator-datetime-5734c96d1e10bbc78532b07cb3fe127c609a7e16.tar.bz2
ayatana-indicator-datetime-5734c96d1e10bbc78532b07cb3fe127c609a7e16.zip
Getting the menu working almost correctly
-rw-r--r--src/datetime-service.c50
-rw-r--r--src/indicator-datetime.c123
2 files changed, 145 insertions, 28 deletions
diff --git a/src/datetime-service.c b/src/datetime-service.c
index 5961df8..85fcc2d 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -261,6 +261,7 @@ update_appointment_menu_items (gpointer user_data) {
DbusmenuMenuitem * item = NULL;
gint i;
gint width, height;
+
g_debug("Setting up ecal.");
if (!ecal)
ecal = e_cal_new_system_calendar();
@@ -309,7 +310,7 @@ update_appointment_menu_items (gpointer user_data) {
}
g_debug("Number of objects returned: %d", g_list_length(objects));
gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
- /*if (appointments != NULL) {
+ if (appointments != NULL) {
for (l = appointments; l; l = l->next) {
item = l->data;
// Remove all the existing menu items which are in appointments.
@@ -318,8 +319,8 @@ update_appointment_menu_items (gpointer user_data) {
g_free(item);
}
appointments = NULL;
- }*/
-
+ }
+
i = 0;
for (l = objects; l; l = l->next) {
ECalComponent *ecalcomp = l->data;
@@ -328,6 +329,7 @@ update_appointment_menu_items (gpointer user_data) {
icaltimezone *appointment_zone = NULL;
icalproperty_status status;
gchar *summary, *cmd;
+ char right[20];
const gchar *uri;
struct tm tmp_tm;
@@ -345,17 +347,19 @@ update_appointment_menu_items (gpointer user_data) {
continue;
// INPROGRESS: Create a menu item for each of them, try to include helpful metadata e.g. colours, due time
+
item = dbusmenu_menuitem_new();
- //dbusmenu_menuitem_property_set (item, "type", APPOINTMENT_MENUITEM_TYPE);
+ dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE);
dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
-
+
+ g_debug("Start Object");
// Label text
- g_debug("Label Summary.");
e_cal_component_get_summary (ecalcomp, &valuetext);
summary = g_strdup (valuetext.value);
- dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, summary);
+ dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_LABEL, summary);
+ g_debug("Summary: %s", summary);
g_free (summary);
// Due text
@@ -367,36 +371,40 @@ update_appointment_menu_items (gpointer user_data) {
// FIXME need to get the timezone of the above datetime,
// and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred)
- g_debug("Check for a datetime."); // Should always have one
+ //g_debug("Check for a datetime."); // Should always have one
if (!datetime.value) {
g_free(item);
continue;
}
- g_debug("Set appointment zone.");
+ //g_debug("Set appointment zone.");
if (!appointment_zone || datetime.value->is_date) { // If it's today put in the current timezone?
appointment_zone = tzone;
}
tmp_tm = icaltimetype_to_tm_with_zone (datetime.value, appointment_zone, tzone);
- g_debug("Free datetime.");
- e_cal_component_free_datetime (&datetime);
// Get today
- /*g_debug("Generate strings");
- if (datetime.value->is_date)
- strftime(right, sizeof(right), "%X", &tmp_tm);
+ g_debug("Generate strings");
+ if (datetime.value->is_date) // Is today - not working :/
+ strftime(right, 20, "%l:%M %P", &tmp_tm);
else
- strftime(right, sizeof(right), "%a %X", &tmp_tm);*/
- //dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right);
+ strftime(right, 20, "%a %l:%M %P", &tmp_tm);
+
+ g_debug("Appointment time: %s", right);
+ dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right);
+
+ //g_debug("Free datetime.");
+ e_cal_component_free_datetime (&datetime);
- g_debug("Set callback");
// Now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution
- e_cal_component_get_url(ecalcomp, &uri);
- cmd = g_strconcat("evolution ", uri, NULL);
+ e_cal_component_get_uid(ecalcomp, &uri);
+ cmd = g_strconcat("evolution calendar://", uri, NULL);
g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
G_CALLBACK (activate_cb), cmd);
+ g_debug("Command to Execute: %s", cmd);
+
// Get the colour E_CAL_COMPONENT_FIELD_COLOR
// Get the icon, either EVENT or MEMO or TODO?
/*gdouble red, blue, green;
@@ -415,14 +423,14 @@ update_appointment_menu_items (gpointer user_data) {
//GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)cs, 0,0,0,0, width, height);
//dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
- g_debug("Add to menu.");
+
dbusmenu_menuitem_child_append (root, item);
appointments = g_list_append (appointments, item); // Keep track of the items here to make them east to remove
if (i == 4) break; // See above FIXME regarding query result limit
i++;
}
- g_debug("Free-ing ecal.");
+ g_debug("End of objects");
if (ecal) {
//g_free(ecal); // Really we should do the setup somewhere where we know it'll only run once, right now, we'll do it every time and free it.
}
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index 44740a6..7748a8c 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -182,7 +182,7 @@ INDICATOR_SET_TYPE(INDICATOR_DATETIME_TYPE)
G_DEFINE_TYPE (IndicatorDatetime, indicator_datetime, INDICATOR_OBJECT_TYPE);
-//static GtkSizeGroup * indicator_right_group = NULL;
+static GtkSizeGroup * indicator_right_group = NULL;
static void
indicator_datetime_class_init (IndicatorDatetimeClass *klass)
@@ -1067,7 +1067,48 @@ generate_format_string (IndicatorDatetime * self)
/* Whenever we have a property change on a DbusmenuMenuitem
we need to be responsive to that. */
-// indicator prop changed removed
+static void
+indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, indicator_item_t * mi_data)
+{
+ if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_LABEL)) {
+ /* Set the main label */
+ gtk_label_set_text(GTK_LABEL(mi_data->label), value);
+ } else if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_RIGHT)) {
+ /* Set the right label */
+ gtk_label_set_text(GTK_LABEL(mi_data->right), value);
+ } else if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_ICON)) {
+ /* We don't use the value here, which is probably less efficient,
+ but it's easier to use the easy function. And since th value
+ is already cached, shouldn't be a big deal really. */
+ GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(mi, APPOINTMENT_MENUITEM_PROP_ICON);
+ if (pixbuf != NULL) {
+ /* If we've got a pixbuf we need to make sure it's of a reasonable
+ size to fit in the menu. If not, rescale it. */
+ GdkPixbuf * resized_pixbuf;
+ gint width, height;
+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+ if (gdk_pixbuf_get_width(pixbuf) > width ||
+ gdk_pixbuf_get_height(pixbuf) > height) {
+ g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height);
+ resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf,
+ width,
+ height,
+ GDK_INTERP_BILINEAR);
+ } else {
+ g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
+ resized_pixbuf = pixbuf;
+ }
+ gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf);
+ /* The other pixbuf should be free'd by the dbusmenu. */
+ if (resized_pixbuf != pixbuf) {
+ g_object_unref(resized_pixbuf);
+ }
+ }
+ } else {
+ g_warning("Indicator Item property '%s' unknown", prop);
+ }
+ return;
+}
/* We have a small little menuitem type that handles all
of the fun stuff for indicators. Mostly this is the
@@ -1075,7 +1116,76 @@ generate_format_string (IndicatorDatetime * self)
side text that'll be determined by the service.
Copied verbatim from an old revision (including comments) of indicator-messages
*/
-// new appointment item removed
+static gboolean
+new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+ /* Note: not checking parent, it's reasonable for it to be NULL */
+
+ indicator_item_t * mi_data = g_new0(indicator_item_t, 1);
+
+ GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
+
+ GtkWidget * hbox = gtk_hbox_new(FALSE, 4);
+
+ /* Icon, probably someone's face or avatar on an IM */
+ mi_data->icon = gtk_image_new();
+ GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(newitem, APPOINTMENT_MENUITEM_PROP_ICON);
+
+ if (pixbuf != NULL) {
+ /* If we've got a pixbuf we need to make sure it's of a reasonable
+ size to fit in the menu. If not, rescale it. */
+ GdkPixbuf * resized_pixbuf;
+ gint width, height;
+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+ if (gdk_pixbuf_get_width(pixbuf) > width ||
+ gdk_pixbuf_get_height(pixbuf) > height) {
+ g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height);
+ resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf,
+ width,
+ height,
+ GDK_INTERP_BILINEAR);
+ } else {
+ g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
+ resized_pixbuf = pixbuf;
+ }
+
+ gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf);
+
+ /* The other pixbuf should be free'd by the dbusmenu. */
+ if (resized_pixbuf != pixbuf) {
+ g_object_unref(resized_pixbuf);
+ }
+ }
+ gtk_misc_set_alignment(GTK_MISC(mi_data->icon), 0.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), mi_data->icon, FALSE, FALSE, 0);
+ gtk_widget_show(mi_data->icon);
+
+ /* Label, probably a username, chat room or mailbox name */
+ mi_data->label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPOINTMENT_MENUITEM_PROP_LABEL));
+ gtk_misc_set_alignment(GTK_MISC(mi_data->label), 0.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), mi_data->label, TRUE, TRUE, 0);
+ gtk_widget_show(mi_data->label);
+
+ /* Usually either the time or the count on the individual
+ item. */
+ mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPOINTMENT_MENUITEM_PROP_RIGHT));
+ gtk_size_group_add_widget(indicator_right_group, mi_data->right);
+ gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, 0);
+ gtk_widget_show(mi_data->right);
+
+ gtk_container_add(GTK_CONTAINER(gmi), hbox);
+ gtk_widget_show(hbox);
+
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
+
+ g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data);
+ g_signal_connect_swapped(G_OBJECT(newitem), "destroyed", G_CALLBACK(g_free), mi_data);
+
+ return TRUE;
+}
static gboolean
@@ -1104,7 +1214,7 @@ new_calendar_item (DbusmenuMenuitem * newitem,
return TRUE;
}
-/*
+
static gboolean
new_timezone_item(DbusmenuMenuitem * newitem,
DbusmenuMenuitem * parent,
@@ -1115,7 +1225,6 @@ new_timezone_item(DbusmenuMenuitem * newitem,
return TRUE;
}
-*/
/* Grabs the label. Creates it if it doesn't
exist already */
@@ -1156,8 +1265,8 @@ get_menu (IndicatorObject * io)
g_object_set_data (G_OBJECT (client), "indicator", io);
dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_CALENDAR_MENUITEM_TYPE, new_calendar_item);
- //dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), APPOINTMENT_MENUITEM_TYPE, new_appointment_item);
- //dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), TIMEZONE_MENUITEM_TYPE, new_timezone_item);
+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), APPOINTMENT_MENUITEM_TYPE, new_appointment_item);
+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), TIMEZONE_MENUITEM_TYPE, new_timezone_item);
return GTK_MENU(self->priv->menu);
}