diff options
author | Ted Gould <ted@gould.cx> | 2011-02-08 14:18:31 -0600 |
---|---|---|
committer | Ted Gould <ted@gould.cx> | 2011-02-08 14:18:31 -0600 |
commit | 5716237564374b3e1f1d698f2d659d4052f23dd5 (patch) | |
tree | e9a46f80eba7c61963d08e05fdda0006d1b039de /src | |
parent | bde608a3bf5cd96f61ca6a62dbfbdd7c28070c86 (diff) | |
parent | d59aaf9c31b2db87b517095caff818a9ff50343a (diff) | |
download | ayatana-indicator-datetime-5716237564374b3e1f1d698f2d659d4052f23dd5.tar.gz ayatana-indicator-datetime-5716237564374b3e1f1d698f2d659d4052f23dd5.tar.bz2 ayatana-indicator-datetime-5716237564374b3e1f1d698f2d659d4052f23dd5.zip |
* Upstream Merge
* Adding some color support along with times
Diffstat (limited to 'src')
-rw-r--r-- | src/datetime-service.c | 147 | ||||
-rw-r--r-- | src/indicator-datetime.c | 45 |
2 files changed, 125 insertions, 67 deletions
diff --git a/src/datetime-service.c b/src/datetime-service.c index f2efcfe..9e3e938 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -24,9 +24,12 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <locale.h> #include <gtk/gtk.h> +#include <gdk/gdk.h> #include <glib/gi18n.h> #include <gio/gio.h> +#include <math.h> +#include <libdbusmenu-gtk/menuitem.h> #include <libdbusmenu-glib/server.h> #include <libdbusmenu-glib/client.h> #include <libdbusmenu-glib/menuitem.h> @@ -41,6 +44,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <libedataserver/e-source.h> // Other users of ecal seem to also include these, not sure why they should be included by the above #include <libical/icaltime.h> +#include <cairo/cairo.h> #include <oobs/oobs-timeconfig.h> @@ -49,6 +53,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #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 void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data); static void geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * c, gchar * d, gpointer user_data); @@ -65,6 +70,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; @@ -232,10 +239,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; @@ -243,7 +287,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; } @@ -419,28 +468,29 @@ update_appointment_menu_items (gpointer user_data) { g_debug("Command to Execute: %s", cmd); - // Get the colour E_CAL_COMPONENT_FIELD_COLOR - // Get the icon, either EVENT or MEMO or TODO? - // needs EDS, ecal component colours are broken... - //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); - //} - //g_debug("Colour to use: %s", ecalcomp->color); - - //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. + ESource *source = e_cal_get_source (ecal); + //e_source_get_color (source, &source_color); api has been changed + const gchar *color_spec = e_source_peek_color_spec(source); + GdkColor color; + g_debug("Colour to use: %s", color_spec); + + // Draw the correct icon for the appointment type and then tint it using mask fill. // For now we'll create a circle + if (color_spec != NULL) { + gdk_color_parse (color_spec, &color); + + cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + cairo_t *cr = cairo_create(cs); + cairo_arc (cr, width/2, height/2, width/2, 0, 2 * M_PI); + gdk_cairo_set_source_color(cr, &color); + cairo_fill(cr); - - //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); - + GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, (GdkDrawable*)cs, + gdk_colormap_new(gdk_drawable_get_visual((GdkDrawable*)cs), TRUE), 0,0,0,0, width, height); + cairo_destroy(cr); + + dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf); + } dbusmenu_menuitem_child_add_position (root, item, 4+i); appointments = g_list_append (appointments, item); // Keep track of the items here to make them east to remove g_debug("Adding appointment: %p", item); @@ -506,51 +556,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); @@ -563,6 +574,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 7748a8c..1f61864 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(GTK_RADIO_BUTTON(mi_data->radio)); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(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 |