From feb60b1977c1fe3fa45452bc40f6635f56b0e39f Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Tue, 11 Jan 2011 12:21:36 +0000 Subject: Added initial support for ecal (untested) --- src/indicator-datetime.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'src/indicator-datetime.c') diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index acdc340..4c3b315 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -923,6 +923,83 @@ generate_format_string (IndicatorDatetime * self) return g_strdup_printf(_("%s, %s"), date_string, time_string); } +/* We have a small little menuitem type that handles all + of the fun stuff for indicators. Mostly this is the + shifting over and putting the icon in with some right + side text that'll be determined by the service. + Copied verbatim from an old revision (including comments) of indicator-messages +*/ +static gboolean +new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + 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, INDICATOR_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, INDICATOR_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, INDICATOR_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(G_OBJECT(newitem), "destroyed", G_CALLBACK(g_free), mi_data); + + return TRUE; +} + static gboolean new_calendar_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, @@ -986,6 +1063,7 @@ 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_indicator_item); return GTK_MENU(self->priv->menu); } -- cgit v1.2.3 From b54626d404eccdc07b2bac09301d5e28dcc838f2 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Wed, 12 Jan 2011 11:25:04 +0000 Subject: Added missing stuff, getting it ready to be buildable --- configure.ac | 8 +++--- src/datetime-service.c | 1 + src/indicator-datetime.c | 63 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 8 deletions(-) (limited to 'src/indicator-datetime.c') diff --git a/configure.ac b/configure.ac index c248853..10ea46b 100644 --- a/configure.ac +++ b/configure.ac @@ -66,16 +66,16 @@ AS_IF([test "x$with_gtk" = x3], [PKG_CHECK_MODULES(INDICATOR, indicator3 >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk3 >= $DBUSMENUGTK_REQUIRED_VERSION - libido3-0.1 >= $INDICATOR_DISPLAY_OBJECTS, - libecal >= $ECAL_REQUIRED_VERSION, + libido3-0.1 >= $INDICATOR_DISPLAY_OBJECTS + libecal >= $ECAL_REQUIRED_VERSION libical >= $ICAL_REQUIRED_VERSION) ], [test "x$with_gtk" = x2], [PKG_CHECK_MODULES(INDICATOR, indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION - libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS, - libecal >= $ECAL_REQUIRED_VERSION, + libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS + libecal >= $ECAL_REQUIRED_VERSION libical >= $ICAL_REQUIRED_VERSION) ], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] diff --git a/src/datetime-service.c b/src/datetime-service.c index 814c9c6..33c8f30 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -307,6 +307,7 @@ update_appointment_menu_items (gpointer user_data) { // TODO: now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution // not sure if the ical URL property is actually an evolution compatible URI and no real way to tell other than testing + // We may need to change this to ecalcomponenets to get something closer to the evolution URI p = icalcomponent_get_first_property(icalcomp, ICAL_URL_PROPERTY); v = icalproperty_get_value(p); uri = icalvalue_get_string(v); diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 4c3b315..364c7b4 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -40,6 +40,7 @@ with this program. If not, see . /* DBusMenu */ #include #include +#include #include "dbus-shared.h" @@ -99,6 +100,13 @@ enum { PROP_CUSTOM_TIME_FORMAT }; +typedef struct _indicator_item_t indicator_item_t; +struct _indicator_item_t { + GtkWidget * icon; + GtkWidget * label; + GtkWidget * right; +}; + #define PROP_TIME_FORMAT_S "time-format" #define PROP_SHOW_SECONDS_S "show-seconds" #define PROP_SHOW_DAY_S "show-day" @@ -150,6 +158,8 @@ INDICATOR_SET_TYPE(INDICATOR_DATETIME_TYPE) G_DEFINE_TYPE (IndicatorDatetime, indicator_datetime, INDICATOR_OBJECT_TYPE); +static GtkSizeGroup * indicator_right_group = NULL; + static void indicator_datetime_class_init (IndicatorDatetimeClass *klass) { @@ -923,6 +933,51 @@ generate_format_string (IndicatorDatetime * self) return g_strdup_printf(_("%s, %s"), date_string, time_string); } +/* Whenever we have a property change on a DbusmenuMenuitem + we need to be responsive to that. */ +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 shifting over and putting the icon in with some right @@ -944,7 +999,7 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu /* Icon, probably someone's face or avatar on an IM */ mi_data->icon = gtk_image_new(); - GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(newitem, INDICATOR_MENUITEM_PROP_ICON); + 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 @@ -976,14 +1031,14 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu 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, INDICATOR_MENUITEM_PROP_LABEL)); + 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, INDICATOR_MENUITEM_PROP_RIGHT)); + 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); @@ -1063,7 +1118,7 @@ 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_indicator_item); + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), APPOINTMENT_MENUITEM_TYPE, new_appointment_item); return GTK_MENU(self->priv->menu); } -- cgit v1.2.3 From add30ba3ce73f5b10f592cc1cd23132a9c04d980 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Wed, 19 Jan 2011 15:21:14 +0000 Subject: Updated the eds code to use ecalcomponents rather than ical so we get colours etc... --- src/datetime-service.c | 168 ++++++++++++++++++++++++++++++++++++----------- src/indicator-datetime.c | 10 +++ 2 files changed, 141 insertions(+), 37 deletions(-) (limited to 'src/indicator-datetime.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index 33c8f30..e06b76d 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -36,10 +36,14 @@ with this program. If not, see . #include #include #include +#include +#include +#include // Other users of ecal seem to also include these, not sure why they should be included by the above #include #include + #include #include "datetime-interface.h" @@ -235,21 +239,37 @@ check_for_calendar (gpointer user_data) return FALSE; } -/* Populate the menu with todays, next 5 appointments. We probably want to shift this off to an idle-add - * the problem is the inserting order of items and updating them might be difficult. - * we should hook into the ABOUT TO SHOW signal and use that to update the appointments. +static gboolean +timezone_clicked_cb() { + + return FALSE; +} + +static gboolean +update_timezone_menu_items(gpointer user_data) { + + return FALSE; +} + +/* Populate the menu with todays, next 5 appointments. + * we should hook into the ABOUT TO SHOW signal and use that to update the appointments. + * Experience has shown that caldav's and webcals can be slow to load from eds + * this is a problem mainly on the EDS side of things, not ours. */ static gboolean update_appointment_menu_items (gpointer user_data) { - + // FFR: we should take into account short term timers, for instance + // tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec. time_t t1, t2; gchar *query, *is, *ie; GList *objects = NULL, *l; GError *gerror = NULL; DbusmenuMenuitem * item = NULL; gint i; + gint width, height; ecal = e_cal_new_system_calendar(); + if (!ecal) { g_debug("e_cal_new_system_calendar failed"); ecal = NULL; @@ -269,50 +289,119 @@ update_appointment_menu_items (gpointer user_data) { return FALSE; } + /* This timezone represents the timezone of the calendar, this might be different to the current UTC offset. + * this means we'll have some geoclue interaction going on, and possibly the user will be involved in setting + * their location manually, case in point: trains have satellite links which often geoclue to sweden, + * this shouldn't automatically set the location and mess up all the appointments for the user. + */ ecal_timezone = icaltimezone_get_tzid(tzone); - // TODO: Remove all the existing menu items which are appointments. - time(&t1); time(&t2); - t2 += (time_t) (24 * 60 * 60); /* 1 day ahead of now */ + t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now */ is = isodate_from_time_t(t1); ie = isodate_from_time_t(t2); - // FIXME can we put a limit on the number of results? + // FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie); - if (!e_cal_get_object_list(ecal, query, &objects, &gerror);) { + if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror);) { g_debug("Failed to get objects\n"); g_free(ecal); ecal = NULL; return FALSE; } - i = 0; - gint width, height; gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + if (appointments != NULL) { + for (l = appointments; l; l = l->next) { + item = l->data; + // TODO: Remove all the existing menu items which are in appointments. + + // pop it out of the dbus menu + // remove it from the appointments glist + // free it + } + appointments = NULL; + } + + i = 0; for (l = objects; l; l = l->next) { - icalcomponent *icalcomp = l->data; - icalproperty* p; - icalvalue *v; - gchar *name, *due, *uri, *cmd; - p = icalcomponent_get_first_property(icalcomp, ICAL_NAME_PROPERTY); - v = icalproperty_get_value(p); - name = icalvalue_get_string(v); + ECalComponent *ecalcomp = l->data; + ECalComponentText valuetext; + ECalComponentDateTime datetime; + icaltimezone *appointment_zone; + time_t appointment_time, ti; + icalproperty_status status; + gchar *summary, right[20], *cmd; + const gchar *uri; + struct tm *tmp_tm, *tm_today; + + vtype = e_cal_component_get_vtype (comp); + + // See above FIXME regarding query result + // If it's not an event or todo, continue no-increment + if (vtype != E_CAL_COMPONENT_EVENT || vtype != E_CAL_COMPONENT_TODO) + continue; + + // See above FIXME regarding query result + // if the status is completed, continue no-increment + e_cal_component_get_status (ecalcomp, &status); + if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) + 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", INDICATOR_MENUITEM_TYPE); + dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); + dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - p = icalcomponent_get_first_property(icalcomp, ICAL_DUE_PROPERTY); - v = icalproperty_get_value(p); - due = icalvalue_get_string(v); + // Label text + e_cal_component_get_summary (ecalcomp, &valuetext); + summary = g_strdup (valuetext.value); + e_cal_component_free_text (&valuetext); + dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_LABEL, summary); + g_free (summary); + + // Due text + if (vtype == E_CAL_COMPONENT_EVENT) + e_cal_component_get_dtstart (ecalcomp, &datetime); + else + e_cal_component_get_due (ecalcomp, &datetime); + + if (datetime.value) { + appointment_zone = get_zone_from_tzid (client, datetime.tzid); + if (!appointment_zone || datetime.value->is_date) + appointment_zone = ecal_timezone; + appointment_time = icaltime_as_timet_with_zone (*datetime.value, appointment_zone); + } + e_cal_component_free_datetime (&datetime); + tmp_tm = convert_timet_to_struct_tm (appointment_time, appointment_zone); - // TODO: now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution - // not sure if the ical URL property is actually an evolution compatible URI and no real way to tell other than testing - // We may need to change this to ecalcomponenets to get something closer to the evolution URI - p = icalcomponent_get_first_property(icalcomp, ICAL_URL_PROPERTY); - v = icalproperty_get_value(p); - uri = icalvalue_get_string(v); + // Get today + time(&ti); + tm_today = convert_timet_to_struct_tm (ti, appointment_zone); + if (tm_today->mday == tmp_tm->mday && tm_today->mon == tmp_tm->mon && tm_today->year == tmp_tm->year) + strftime(&right, sizeof(right), "%X", tmp_tm); + else + strftime(&right, sizeof(right), "%a %X", tmp_tm); + dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, &right); + + // 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); + g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (activate_cb), cmd); + // Get the colour E_CAL_COMPONENT_FIELD_COLOR + // Get the icon, either EVENT or MEMO or TODO? + gdouble red, blue, green; + ECalSource *source = e_cal_get_source (ecalcomp->client); + if (!ecalcomp->color && e_source_get_color (source, &source_color)) { + g_free (comp_data->color); + ecalcomp->color = g_strdup_printf ("#%06x", source_color & 0xffffff); + } + //cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); //cairo_t *cr = cairo_create(cs); @@ -320,17 +409,10 @@ update_appointment_menu_items (gpointer user_data) { //GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)cs, 0,0,0,0, width, height); - // TODO: 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", INDICATOR_MENUITEM_TYPE); - dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_LABEL, name); //dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); - dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, due); - dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); - dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + dbusmenu_menuitem_child_append (root, item); - g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_cb), cmd); + 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++; @@ -395,7 +477,19 @@ build_menus (DbusmenuMenuitem * root) // This just populates the items on startup later we want to be able to update the appointments before // presenting the menu. update_appointment_menu_items(NULL); - + if (calendar != NULL) { + // TODO Create "Add appointment" menu item + } + // TODO Create FFR? "Add timer" menu item + + separator = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append(root, separator); + + update_timezone_menu_items(NULL); + // TODO Create "detected location" menu item? (defaults to the geoclue location) + // TODO Create "Add location" menu item + separator = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); dbusmenu_menuitem_child_append(root, separator); diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 364c7b4..c6dc2c1 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -1081,6 +1081,16 @@ new_calendar_item (DbusmenuMenuitem * newitem, return TRUE; } +static gboolean +new_timezone_item(DbusmenuMenuitem * newitem, + DbusmenuMenuitem * parent, + DbusmenuClient * client) +{ + // Menu item with a radio button and a right aligned time + + return TRUE; +} + /* Grabs the label. Creates it if it doesn't exist already */ static GtkLabel * -- cgit v1.2.3 From 665f9ece45a30a255c85aab6b9a855dda8a56b1d Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Mon, 24 Jan 2011 17:22:35 +0000 Subject: Final few fixes making it buildable --- configure.ac | 12 +++----- src/datetime-service.c | 80 +++++++++++++++++++++++------------------------- src/dbus-shared.h | 13 +++++--- src/indicator-datetime.c | 1 + 4 files changed, 53 insertions(+), 53 deletions(-) (limited to 'src/indicator-datetime.c') diff --git a/configure.ac b/configure.ac index 2feb744..09ea542 100644 --- a/configure.ac +++ b/configure.ac @@ -66,17 +66,13 @@ AS_IF([test "x$with_gtk" = x3], [PKG_CHECK_MODULES(INDICATOR, indicator3 >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION - libido3-0.1 >= $INDICATOR_DISPLAY_OBJECTS - libecal >= $ECAL_REQUIRED_VERSION - libical >= $ICAL_REQUIRED_VERSION) + libido3-0.1 >= $INDICATOR_DISPLAY_OBJECTS) ], [test "x$with_gtk" = x2], [PKG_CHECK_MODULES(INDICATOR, indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION - libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - libecal >= $ECAL_REQUIRED_VERSION - libical >= $ICAL_REQUIRED_VERSION) + libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS) ], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) @@ -86,7 +82,9 @@ PKG_CHECK_MODULES(SERVICE, indicator >= $INDICATOR_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS gio-2.0 >= $GIO_REQUIRED_VERSION geoclue >= $GEOCLUE_REQUIRED_VERSION - liboobs-1 >= $OOBS_REQUIRED_VERSION) + liboobs-1 >= $OOBS_REQUIRED_VERSION + libecal-1.2 >= $ECAL_REQUIRED_VERSION + libical >= $ICAL_REQUIRED_VERSION) AC_SUBST(INDICATOR_CFLAGS) AC_SUBST(INDICATOR_LIBS) diff --git a/src/datetime-service.c b/src/datetime-service.c index e06b76d..020371f 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -23,6 +23,7 @@ with this program. If not, see . #include #include +#include #include #include @@ -36,11 +37,9 @@ with this program. If not, see . #include #include #include -#include #include #include // Other users of ecal seem to also include these, not sure why they should be included by the above -#include #include @@ -66,7 +65,7 @@ static DbusmenuMenuitem * settings = NULL; static DbusmenuMenuitem * tzchange = NULL; static GList * appointments = NULL; static ECal * ecal = NULL; -static gchar * ecal_timezone = NULL; +static const gchar * ecal_timezone = NULL; /* Geoclue trackers */ static GeoclueMasterClient * geo_master = NULL; @@ -239,15 +238,9 @@ check_for_calendar (gpointer user_data) return FALSE; } -static gboolean -timezone_clicked_cb() { - - return FALSE; -} - static gboolean update_timezone_menu_items(gpointer user_data) { - + // Get the location preferences and the current location, highlight the current location somehow return FALSE; } @@ -261,6 +254,7 @@ update_appointment_menu_items (gpointer user_data) { // FFR: we should take into account short term timers, for instance // tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec. time_t t1, t2; + icaltimezone *tzone; gchar *query, *is, *ie; GList *objects = NULL, *l; GError *gerror = NULL; @@ -268,7 +262,8 @@ update_appointment_menu_items (gpointer user_data) { gint i; gint width, height; - ecal = e_cal_new_system_calendar(); + if (!ecal) + ecal = e_cal_new_system_calendar(); if (!ecal) { g_debug("e_cal_new_system_calendar failed"); @@ -282,7 +277,7 @@ update_appointment_menu_items (gpointer user_data) { return FALSE; } - if (!e_cal_get_timezone(ecal, "UTC", &tzone, &gerror) { + if (!e_cal_get_timezone(ecal, "UTC", &tzone, &gerror)) { g_debug("failed to get time zone\n"); g_free(ecal); ecal = NULL; @@ -305,22 +300,20 @@ update_appointment_menu_items (gpointer user_data) { // FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie); - if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror);) { + if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror)) { g_debug("Failed to get objects\n"); g_free(ecal); ecal = NULL; return FALSE; } gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - if (appointments != NULL) { for (l = appointments; l; l = l->next) { item = l->data; - // TODO: Remove all the existing menu items which are in appointments. - - // pop it out of the dbus menu - // remove it from the appointments glist - // free it + // Remove all the existing menu items which are in appointments. + dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(item)); + appointments = g_list_remove(appointments, item); + g_free(item); } appointments = NULL; } @@ -330,14 +323,13 @@ update_appointment_menu_items (gpointer user_data) { ECalComponent *ecalcomp = l->data; ECalComponentText valuetext; ECalComponentDateTime datetime; - icaltimezone *appointment_zone; - time_t appointment_time, ti; + icaltimezone *appointment_zone = NULL; icalproperty_status status; gchar *summary, right[20], *cmd; const gchar *uri; - struct tm *tmp_tm, *tm_today; - - vtype = e_cal_component_get_vtype (comp); + struct tm tmp_tm; + + ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp); // See above FIXME regarding query result // If it's not an event or todo, continue no-increment @@ -352,15 +344,16 @@ update_appointment_menu_items (gpointer user_data) { // 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", INDICATOR_MENUITEM_TYPE); + dbusmenu_menuitem_property_set (item, "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); // Label text e_cal_component_get_summary (ecalcomp, &valuetext); summary = g_strdup (valuetext.value); - e_cal_component_free_text (&valuetext); + dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_LABEL, summary); + g_free (summary); // Due text @@ -369,23 +362,26 @@ update_appointment_menu_items (gpointer user_data) { else e_cal_component_get_due (ecalcomp, &datetime); - if (datetime.value) { - appointment_zone = get_zone_from_tzid (client, datetime.tzid); - if (!appointment_zone || datetime.value->is_date) - appointment_zone = ecal_timezone; - appointment_time = icaltime_as_timet_with_zone (*datetime.value, appointment_zone); + // FIXME need to get the timezone of the above datetime, + // and get the icaltimezone of the geoclue timezone/selected timezone (whichever is preferred) + if (!datetime.value) { + g_free(item); + continue; } + + 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); + e_cal_component_free_datetime (&datetime); - tmp_tm = convert_timet_to_struct_tm (appointment_time, appointment_zone); // Get today - time(&ti); - tm_today = convert_timet_to_struct_tm (ti, appointment_zone); - if (tm_today->mday == tmp_tm->mday && tm_today->mon == tmp_tm->mon && tm_today->year == tmp_tm->year) - strftime(&right, sizeof(right), "%X", tmp_tm); + if (datetime.value->is_date) + strftime(right, sizeof(right), "%X", &tmp_tm); else - strftime(&right, sizeof(right), "%a %X", tmp_tm); - dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, &right); + strftime(right, sizeof(right), "%a %X", &tmp_tm); + dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right); // 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); @@ -395,12 +391,13 @@ update_appointment_menu_items (gpointer user_data) { // Get the colour E_CAL_COMPONENT_FIELD_COLOR // Get the icon, either EVENT or MEMO or TODO? - gdouble red, blue, green; + /*gdouble red, blue, green; ECalSource *source = e_cal_get_source (ecalcomp->client); if (!ecalcomp->color && e_source_get_color (source, &source_color)) { g_free (comp_data->color); ecalcomp->color = g_strdup_printf ("#%06x", source_color & 0xffffff); - } + }*/ + //cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); //cairo_t *cr = cairo_create(cs); @@ -412,7 +409,7 @@ update_appointment_menu_items (gpointer user_data) { //dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); dbusmenu_menuitem_child_append (root, item); - appointments = g_list_append(appointments, item); // Keep track of the items here to make them east to remove + 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++; @@ -487,7 +484,6 @@ build_menus (DbusmenuMenuitem * root) dbusmenu_menuitem_child_append(root, separator); update_timezone_menu_items(NULL); - // TODO Create "detected location" menu item? (defaults to the geoclue location) // TODO Create "Add location" menu item separator = dbusmenu_menuitem_new(); diff --git a/src/dbus-shared.h b/src/dbus-shared.h index 4ecd64b..1f90ca7 100644 --- a/src/dbus-shared.h +++ b/src/dbus-shared.h @@ -29,7 +29,12 @@ with this program. If not, see . #define DBUSMENU_CALENDAR_MENUITEM_TYPE "x-canonical-calendar-item" -#define APPOINTMENT_MENUITEM_TYPE "indicator-item" -#define APPOINTMENT_MENUITEM_PROP_LABEL "indicator-label" -#define APPOINTMENT_MENUITEM_PROP_ICON "indicator-icon" -#define APPOINTMENT_MENUITEM_PROP_RIGHT "right-side-text" +#define APPOINTMENT_MENUITEM_TYPE "appointment-item" +#define APPOINTMENT_MENUITEM_PROP_LABEL "appointment-label" +#define APPOINTMENT_MENUITEM_PROP_ICON "appointment-icon" +#define APPOINTMENT_MENUITEM_PROP_RIGHT "appointment-time" + +#define TIMEZONE_MENUITEM_TYPE "timezone-item" +#define TIMEZONE_MENUITEM_PROP_LABEL "timezone-label" +#define TIMEZONE_MENUITEM_PROP_RADIO "timezone-radio" +#define TIMEZONE_MENUITEM_PROP_RIGHT "timezone-time" diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 5d92296..a07e667 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -1263,6 +1263,7 @@ get_menu (IndicatorObject * 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); return GTK_MENU(self->priv->menu); } -- cgit v1.2.3 From c023a16ebdef8c0bdbd10cdfe9cf753afad1191b Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Wed, 26 Jan 2011 11:12:48 -0500 Subject: fix some crashes --- src/datetime-service.c | 1 + src/indicator-datetime.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/indicator-datetime.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index 020371f..d80fc18 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -415,6 +415,7 @@ update_appointment_menu_items (gpointer user_data) { i++; } 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. + ecal = NULL; return TRUE; } diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index a07e667..288ab26 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -340,7 +340,7 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) } if (error != NULL) { - g_error("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message); + g_warning("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message); g_error_free(error); return; } @@ -1182,7 +1182,7 @@ new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu 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(G_OBJECT(newitem), "destroyed", G_CALLBACK(g_free), mi_data); + g_signal_connect_swapped(G_OBJECT(newitem), "destroyed", G_CALLBACK(g_free), mi_data); return TRUE; } -- cgit v1.2.3 From e0718f3613ae3a39a58e87cf1f4b2c4c00b76117 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Mon, 31 Jan 2011 17:30:19 +0000 Subject: Removed all buggy code from the datetime-service to push for A2 --- src/datetime-service.c | 178 +++++++++++++++++++++++++++++++++++++++++++++-- src/indicator-datetime.c | 122 ++------------------------------ 2 files changed, 180 insertions(+), 120 deletions(-) (limited to 'src/indicator-datetime.c') diff --git a/src/datetime-service.c b/src/datetime-service.c index 3fe6ebb..5961df8 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -63,6 +63,9 @@ static DbusmenuMenuitem * date = NULL; static DbusmenuMenuitem * calendar = NULL; static DbusmenuMenuitem * settings = NULL; static DbusmenuMenuitem * tzchange = NULL; +static GList * appointments = NULL; +static ECal * ecal = NULL; +static const gchar * ecal_timezone = NULL; /* Geoclue trackers */ static GeoclueMasterClient * geo_master = NULL; @@ -248,15 +251,180 @@ update_timezone_menu_items(gpointer user_data) { */ static gboolean update_appointment_menu_items (gpointer user_data) { + // FFR: we should take into account short term timers, for instance + // tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec. + time_t t1, t2; + icaltimezone *tzone; + gchar *query, *is, *ie; + GList *objects = NULL, *l; + GError *gerror = NULL; DbusmenuMenuitem * item = NULL; - gint i; - for (i = 0; i < 5; i++) { + gint width, height; + g_debug("Setting up ecal."); + if (!ecal) + ecal = e_cal_new_system_calendar(); + + if (!ecal) { + g_debug("e_cal_new_system_calendar failed"); + ecal = NULL; + return FALSE; + } + g_debug("Open calendar."); + if (!e_cal_open(ecal, FALSE, &gerror) ) { + g_debug("e_cal_open: %s\n", gerror->message); + g_free(ecal); + ecal = NULL; + return FALSE; + } + g_debug("Get calendar timezone."); + if (!e_cal_get_timezone(ecal, "UTC", &tzone, &gerror)) { + g_debug("failed to get time zone\n"); + g_free(ecal); + ecal = NULL; + return FALSE; + } + + /* This timezone represents the timezone of the calendar, this might be different to the current UTC offset. + * this means we'll have some geoclue interaction going on, and possibly the user will be involved in setting + * their location manually, case in point: trains have satellite links which often geoclue to sweden, + * this shouldn't automatically set the location and mess up all the appointments for the user. + */ + ecal_timezone = icaltimezone_get_tzid(tzone); + + time(&t1); + time(&t2); + t2 += (time_t) (7 * 24 * 60 * 60); /* 7 days ahead of now */ + + is = isodate_from_time_t(t1); + ie = isodate_from_time_t(t2); + // FIXME can we put a limit on the number of results? Or if not complete, or is event/todo? + query = g_strdup_printf("(occur-in-time-range? (make-time\"%s\") (make-time\"%s\"))", is, ie); + g_debug("Getting objects with query: %s", query); + if (!e_cal_get_object_list_as_comp(ecal, query, &objects, &gerror)) { + g_debug("Failed to get objects\n"); + g_free(ecal); + ecal = NULL; + return FALSE; + } + g_debug("Number of objects returned: %d", g_list_length(objects)); + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + /*if (appointments != NULL) { + for (l = appointments; l; l = l->next) { + item = l->data; + // Remove all the existing menu items which are in appointments. + dbusmenu_menuitem_child_delete(root, DBUSMENU_MENUITEM(item)); + appointments = g_list_remove(appointments, item); + g_free(item); + } + appointments = NULL; + }*/ + + i = 0; + for (l = objects; l; l = l->next) { + ECalComponent *ecalcomp = l->data; + ECalComponentText valuetext; + ECalComponentDateTime datetime; + icaltimezone *appointment_zone = NULL; + icalproperty_status status; + gchar *summary, *cmd; + const gchar *uri; + struct tm tmp_tm; + + ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp); + + // See above FIXME regarding query result + // If it's not an event or todo, continue no-increment + if (vtype != E_CAL_COMPONENT_EVENT && vtype != E_CAL_COMPONENT_TODO) + continue; + + // See above FIXME regarding query result + // if the status is completed, continue no-increment + e_cal_component_get_status (ecalcomp, &status); + if (status == ICAL_STATUS_COMPLETED || status == ICAL_STATUS_CANCELLED) + 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, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE); - dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_LABEL, "fake summary"); - dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, "9:00pm"); + //dbusmenu_menuitem_property_set (item, "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); + + // 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); + g_free (summary); + + // Due text + if (vtype == E_CAL_COMPONENT_EVENT) + e_cal_component_get_dtstart (ecalcomp, &datetime); + else + e_cal_component_get_due (ecalcomp, &datetime); + + // 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 + if (!datetime.value) { + g_free(item); + continue; + } + + 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); + else + strftime(right, sizeof(right), "%a %X", &tmp_tm);*/ + //dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right); + + 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); + g_signal_connect (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (activate_cb), cmd); + + // Get the colour E_CAL_COMPONENT_FIELD_COLOR + // Get the icon, either EVENT or MEMO or TODO? + /*gdouble red, blue, green; + ECalSource *source = e_cal_get_source (ecalcomp->client); + if (!ecalcomp->color && e_source_get_color (source, &source_color)) { + g_free (comp_data->color); + ecalcomp->color = g_strdup_printf ("#%06x", source_color & 0xffffff); + }*/ + + + //cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + //cairo_t *cr = cairo_create(cs); + + // TODO: Draw the correct icon for the appointment type and then tint it using mask fill. + + //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."); + 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. } return TRUE; } diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index e7a448e..44740a6 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,48 +1067,7 @@ generate_format_string (IndicatorDatetime * self) /* Whenever we have a property change on a DbusmenuMenuitem we need to be responsive to that. */ -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; -} +// indicator prop changed removed /* We have a small little menuitem type that handles all of the fun stuff for indicators. Mostly this is the @@ -1116,76 +1075,8 @@ indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, in side text that'll be determined by the service. Copied verbatim from an old revision (including comments) of indicator-messages */ -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 */ +// new appointment item removed - 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 new_calendar_item (DbusmenuMenuitem * newitem, @@ -1213,7 +1104,7 @@ new_calendar_item (DbusmenuMenuitem * newitem, return TRUE; } - +/* static gboolean new_timezone_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, @@ -1224,6 +1115,7 @@ new_timezone_item(DbusmenuMenuitem * newitem, return TRUE; } +*/ /* Grabs the label. Creates it if it doesn't exist already */ @@ -1264,8 +1156,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); } -- cgit v1.2.3 From 5734c96d1e10bbc78532b07cb3fe127c609a7e16 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Wed, 2 Feb 2011 11:14:26 +0000 Subject: Getting the menu working almost correctly --- src/datetime-service.c | 50 +++++++++++-------- src/indicator-datetime.c | 123 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 145 insertions(+), 28 deletions(-) (limited to 'src/indicator-datetime.c') 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); } -- cgit v1.2.3 From 85ace9f8b921ba8ffde95510953f008f92d8ac61 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Fri, 4 Feb 2011 14:57:29 +0000 Subject: Added the timezone/location menu item code. --- src/indicator-datetime.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'src/indicator-datetime.c') diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 7748a8c..20485e5 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -105,6 +105,7 @@ enum { typedef struct _indicator_item_t indicator_item_t; struct _indicator_item_t { + GtkWidget * radio; GtkWidget * icon; GtkWidget * label; GtkWidget * right; @@ -175,6 +176,7 @@ static void update_time (IndicatorDatetime * self); static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); static gint generate_strftime_bitmask (const char *time_str); +static GSList *location_group = NULL; /* Indicator Module Config */ INDICATOR_SET_VERSION @@ -1221,9 +1223,50 @@ new_timezone_item(DbusmenuMenuitem * newitem, 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 */ + // Menu item with a radio button and a right aligned time + 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); + + mi_data->radio = gtk_radio_button_new(location_group); + if (location_group == NULL) + location_group = gtk_radio_button_get_group(mi_data->radio); + + gtk_toggle_button_set_active(mi_data->radio, + dbusmenu_menuitem_property_get_bool(newitem, TIMEZONE_MENUITEM_PROP_RADIO)); - return TRUE; + gtk_box_pack_start(GTK_BOX(hbox), mi_data->radio, FALSE, FALSE, 0); + gtk_widget_show(mi_data->radio); + + /* 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; } /* Grabs the label. Creates it if it doesn't -- cgit v1.2.3 From 2b9d7908ec2117de20887ebda1baca1049a54e87 Mon Sep 17 00:00:00 2001 From: karl-qdh Date: Mon, 7 Feb 2011 10:35:58 +0000 Subject: Updated datetime service slightly to draw coloured dots for evolution colours, evolution is still slightly broken at doing it's part here and returns null colours. Updated configure.ac (hope this doesn't break merge), and added the radio menu item with a right aligned time to the indicator so we can have location/timezone entries. --- configure.ac | 42 ++++++++++++++----- src/datetime-service.c | 102 ++++++++++++++++++++++++++--------------------- src/indicator-datetime.c | 4 +- 3 files changed, 91 insertions(+), 57 deletions(-) (limited to 'src/indicator-datetime.c') diff --git a/configure.ac b/configure.ac index cc96999..4f35d38 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,10 @@ INDICATOR_DISPLAY_OBJECTS=0.1.10 GEOCLUE_REQUIRED_VERSION=0.12.0 OOBS_REQUIRED_VERSION=2.31.0 ECAL_REQUIRED_VERSION=2.30 +EDS_REQUIRED_VERSION=2.30 ICAL_REQUIRED_VERSION=0.44 +CAIRO_REQUIRED_VERSION=1.10 +GDK_REQUIRED_VERSION=2.22 AS_IF([test "x$with_gtk" = x3], [PKG_CHECK_MODULES(INDICATOR, indicator3 >= $INDICATOR_REQUIRED_VERSION @@ -77,15 +80,36 @@ AS_IF([test "x$with_gtk" = x3], [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] ) -PKG_CHECK_MODULES(SERVICE, indicator >= $INDICATOR_REQUIRED_VERSION - dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION - libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION - geoclue >= $GEOCLUE_REQUIRED_VERSION - liboobs-1 >= $OOBS_REQUIRED_VERSION - libecal-1.2 >= $ECAL_REQUIRED_VERSION - libical >= $ICAL_REQUIRED_VERSION) - +AS_IF([test "x$with_gtk" = x3], + [PKG_CHECK_MODULES(SERVICE, indicator >= $INDICATOR_REQUIRED_VERSION + dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION + dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION + libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION + libecal-1.2 >= $ECAL_REQUIRED_VERSION + libical >= $ICAL_REQUIRED_VERSION + libedataserver-1.2 >= EDS_REQUIRED_VERSION + cairo >= CAIRO_REQUIRED_VERSION + gdk-2.0 >= GDK_REQUIRED_VERSION) + ], + [test "x$with_gtk" = x2], + [PKG_CHECK_MODULES(SERVICE, indicator >= $INDICATOR_REQUIRED_VERSION + dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION + dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION + libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION + libecal-1.2 >= $ECAL_REQUIRED_VERSION + libical >= $ICAL_REQUIRED_VERSION + libedataserver-1.2 >= EDS_REQUIRED_VERSION + cairo >= CAIRO_REQUIRED_VERSION + gdk-2.0 >= GDK_REQUIRED_VERSION) + ], + [AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])] +) AC_SUBST(INDICATOR_CFLAGS) AC_SUBST(INDICATOR_LIBS) diff --git a/src/datetime-service.c b/src/datetime-service.c index 3f5aa80..3aa6acf 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -53,6 +53,7 @@ with this program. If not, see . #include "dbus-shared.h" static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data); +static gboolean update_appointment_menu_items (gpointer user_data); static void setup_timer (void); static IndicatorService * service = NULL; @@ -67,6 +68,8 @@ static DbusmenuMenuitem * date = NULL; static DbusmenuMenuitem * calendar = NULL; static DbusmenuMenuitem * settings = NULL; static DbusmenuMenuitem * tzchange = NULL; +static DbusmenuMenuitem * add_appointment = NULL; +static DbusmenuMenuitem * add_location = NULL; static GList * appointments = NULL; static ECal * ecal = NULL; static const gchar * ecal_timezone = NULL; @@ -234,10 +237,47 @@ check_for_calendar (gpointer user_data) g_debug("Found the calendar application: %s", evo); dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + + GError *gerror = NULL; + // TODO: In reality we should iterate sources of calendar, but getting the local one doens't lag for > a minute + g_debug("Setting up ecal."); + if (!ecal) + ecal = e_cal_new_system_calendar(); + + if (!ecal) { + g_debug("e_cal_new_system_calendar failed"); + ecal = NULL; + } + g_debug("Open calendar."); + if (!e_cal_open(ecal, FALSE, &gerror) ) { + g_debug("e_cal_open: %s\n", gerror->message); + g_free(ecal); + ecal = NULL; + } + g_debug("Get calendar timezone."); + if (!e_cal_get_timezone(ecal, "UTC", &tzone, &gerror)) { + g_debug("failed to get time zone\n"); + g_free(ecal); + ecal = NULL; + } + + /* This timezone represents the timezone of the calendar, this might be different to the current UTC offset. + * this means we'll have some geoclue interaction going on, and possibly the user will be involved in setting + * their location manually, case in point: trains have satellite links which often geoclue to sweden, + * this shouldn't automatically set the location and mess up all the appointments for the user. + */ + if (ecal) ecal_timezone = icaltimezone_get_tzid(tzone); + + update_appointment_menu_items(NULL); + g_signal_connect(root, DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW, G_CALLBACK(update_appointment_menu_items), NULL); + g_free(evo); } else { g_debug("Unable to find calendar app."); dbusmenu_menuitem_property_set_bool(calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); } return FALSE; @@ -245,7 +285,12 @@ check_for_calendar (gpointer user_data) static gboolean update_timezone_menu_items(gpointer user_data) { - // Get the location preferences and the current location, highlight the current location somehow + // Get the current location as specified by the user as a place name and time and add it, + // Get the location from geoclue as a place and time and add it, + // Get the evolution calendar timezone as a place and time and add it, + // Get the current timezone that the clock uses and select that + // Iterate over configured places and add any which aren't already listed + // Hook up each of these to setting the time/current timezone return FALSE; } @@ -508,51 +553,12 @@ build_menus (DbusmenuMenuitem * root) dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); dbusmenu_menuitem_child_append(root, separator); - // This just populates the items on startup later we want to be able to update the appointments before - // presenting the menu. - if (calendar != NULL) { - GError *gerror = NULL; - // TODO: In reality we should iterate sources of calendar, but getting the local one doens't lag for > a minute - g_debug("Setting up ecal."); - if (!ecal) - ecal = e_cal_new_system_calendar(); - - if (!ecal) { - g_debug("e_cal_new_system_calendar failed"); - ecal = NULL; - } - g_debug("Open calendar."); - if (!e_cal_open(ecal, FALSE, &gerror) ) { - g_debug("e_cal_open: %s\n", gerror->message); - g_free(ecal); - ecal = NULL; - } - g_debug("Get calendar timezone."); - if (!e_cal_get_timezone(ecal, "UTC", &tzone, &gerror)) { - g_debug("failed to get time zone\n"); - g_free(ecal); - ecal = NULL; - } - - /* This timezone represents the timezone of the calendar, this might be different to the current UTC offset. - * this means we'll have some geoclue interaction going on, and possibly the user will be involved in setting - * their location manually, case in point: trains have satellite links which often geoclue to sweden, - * this shouldn't automatically set the location and mess up all the appointments for the user. - */ - if (ecal) ecal_timezone = icaltimezone_get_tzid(tzone); - - g_signal_connect(root, DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW, G_CALLBACK(update_appointment_menu_items), NULL); - update_appointment_menu_items(NULL); - // TODO Create "Add appointment" menu item - } - // TODO Create FFR? "Add timer" menu item - - separator = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append(root, separator); - - update_timezone_menu_items(NULL); - // TODO Create "Add location" menu item + add_appointment = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Appointment")); + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); + dbusmenu_menuitem_property_set_bool(add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + g_signal_connect(G_OBJECT(add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar"); + dbusmenu_menuitem_child_add_position (root, add_appointment, 4); separator = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); @@ -565,6 +571,10 @@ build_menus (DbusmenuMenuitem * root) dbusmenu_menuitem_child_append(root, tzchange); check_timezone_sync(); + separator = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append(root, separator); + settings = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set (settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings...")); /* insensitive until we check for available apps */ diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 20485e5..1f61864 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -1236,9 +1236,9 @@ new_timezone_item(DbusmenuMenuitem * newitem, mi_data->radio = gtk_radio_button_new(location_group); if (location_group == NULL) - location_group = gtk_radio_button_get_group(mi_data->radio); + location_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(mi_data->radio)); - gtk_toggle_button_set_active(mi_data->radio, + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mi_data->radio), dbusmenu_menuitem_property_get_bool(newitem, TIMEZONE_MENUITEM_PROP_RADIO)); gtk_box_pack_start(GTK_BOX(hbox), mi_data->radio, FALSE, FALSE, 0); -- cgit v1.2.3