diff options
Diffstat (limited to 'widgets/e-timezone-dialog')
-rw-r--r-- | widgets/e-timezone-dialog/e-timezone-dialog.c | 226 | ||||
-rw-r--r-- | widgets/e-timezone-dialog/e-timezone-dialog.h | 45 |
2 files changed, 112 insertions, 159 deletions
diff --git a/widgets/e-timezone-dialog/e-timezone-dialog.c b/widgets/e-timezone-dialog/e-timezone-dialog.c index 9821717c29..1e01edcd1c 100644 --- a/widgets/e-timezone-dialog/e-timezone-dialog.c +++ b/widgets/e-timezone-dialog/e-timezone-dialog.c @@ -39,10 +39,9 @@ #define E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_2_RGBA 0x000000ff struct _ETimezoneDialogPrivate { - /* The TZID of the timezone. May be NULL for a 'local time' (i.e. when - the displayed name is "") or for builtin timezones which we haven't - loaded yet. */ - char *tzid; + /* The selected timezone. May be NULL for a 'local time' (i.e. when + the displayed name is ""). */ + icaltimezone *zone; /* Glade XML data */ GladeXML *xml; @@ -84,9 +83,10 @@ static gboolean on_map_button_pressed (GtkWidget *w, GdkEventButton *event, gpointer data); -static char* get_zone_from_point (ETimezoneDialog *etd, +static icaltimezone* get_zone_from_point (ETimezoneDialog *etd, EMapPoint *point); -static void find_selected_point (ETimezoneDialog *etd); +static void set_map_timezone (ETimezoneDialog *etd, + icaltimezone *zone); static void on_combo_changed (GtkEditable *entry, ETimezoneDialog *etd); @@ -116,7 +116,6 @@ e_timezone_dialog_init (ETimezoneDialog *etd) priv = g_new0 (ETimezoneDialogPrivate, 1); etd->priv = priv; - priv->tzid = NULL; priv->point_selected = NULL; priv->point_hover = NULL; priv->timeout_id = 0; @@ -168,7 +167,6 @@ e_timezone_dialog_finalize (GObject *object) etd = E_TIMEZONE_DIALOG (object); priv = etd->priv; - g_free (priv->tzid); g_free (priv); (* G_OBJECT_CLASS (parent_class)->finalize) (object); @@ -230,6 +228,7 @@ e_timezone_dialog_construct (ETimezoneDialog *etd) { ETimezoneDialogPrivate *priv; GtkWidget *map; + GtkRequisition req; g_return_val_if_fail (etd != NULL, NULL); g_return_val_if_fail (E_IS_TIMEZONE_DIALOG (etd), NULL); @@ -249,8 +248,8 @@ e_timezone_dialog_construct (ETimezoneDialog *etd) goto error; } - map = GTK_WIDGET (e_map_new ()); - priv->map = E_MAP (map); + priv->map = e_map_new (); + map = GTK_WIDGET (priv->map); gtk_widget_set_events (map, gtk_widget_get_events (map) | GDK_LEAVE_NOTIFY_MASK | GDK_VISIBILITY_NOTIFY_MASK); @@ -262,6 +261,9 @@ e_timezone_dialog_construct (ETimezoneDialog *etd) gtk_container_add (GTK_CONTAINER (priv->map_window), map); gtk_widget_show (map); + /* Ensure a reasonable minimum amount of map is visible */ + gtk_widget_set_size_request (priv->map_window, 200, 200); + g_signal_connect (map, "motion-notify-event", G_CALLBACK (on_map_motion), etd); g_signal_connect (map, "leave-notify-event", G_CALLBACK (on_map_leave), etd); g_signal_connect (map, "visibility-notify-event", G_CALLBACK (on_map_visibility_changed), etd); @@ -322,6 +324,18 @@ e_timezone_dialog_new (void) } +static const char * +zone_display_name (icaltimezone *zone) +{ + const char *display_name; + + display_name = icaltimezone_get_display_name (zone); + if (icaltimezone_get_builtin_timezone (display_name)) + display_name = _(display_name); + + return display_name; +} + /* This flashes the currently selected timezone in the map. */ static gboolean @@ -354,7 +368,9 @@ on_map_motion (GtkWidget *widget, GdkEventMotion *event, gpointer data) ETimezoneDialog *etd; ETimezoneDialogPrivate *priv; double longitude, latitude; - char *old_zone, *new_zone; + char *old_zone_name; + const char *new_zone_name; + icaltimezone *new_zone; etd = E_TIMEZONE_DIALOG (data); priv = etd->priv; @@ -373,11 +389,13 @@ on_map_motion (GtkWidget *widget, GdkEventMotion *event, gpointer data) e_map_point_set_color_rgba (priv->map, priv->point_hover, E_TIMEZONE_DIALOG_MAP_POINT_HOVER_RGBA); - gtk_label_get (GTK_LABEL (priv->timezone_preview), &old_zone); + gtk_label_get (GTK_LABEL (priv->timezone_preview), &old_zone_name); new_zone = get_zone_from_point (etd, priv->point_hover); - if (strcmp (old_zone, new_zone)) + new_zone_name = zone_display_name (new_zone); + if (strcmp (old_zone_name, new_zone_name)) { gtk_label_set_text (GTK_LABEL (priv->timezone_preview), - new_zone); + new_zone_name); + } return TRUE; } @@ -447,7 +465,6 @@ on_map_button_pressed (GtkWidget *w, GdkEventButton *event, gpointer data) ETimezoneDialog *etd; ETimezoneDialogPrivate *priv; double longitude, latitude; - char *location; etd = E_TIMEZONE_DIALOG (data); priv = etd->priv; @@ -468,21 +485,18 @@ on_map_button_pressed (GtkWidget *w, GdkEventButton *event, gpointer data) E_TIMEZONE_DIALOG_MAP_POINT_NORMAL_RGBA); priv->point_selected = priv->point_hover; - location = get_zone_from_point (etd, priv->point_selected); + priv->zone = get_zone_from_point (etd, priv->point_selected); gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry), - location); - - g_free (priv->tzid); - priv->tzid = NULL; + zone_display_name (priv->zone)); } return TRUE; } -/* Returns the translated timezone location of the fiven EMapPoint, - e.g. "Europe/London", in the current locale's encoding (not UTF-8). */ -static char* +/* Returns the translated timezone location of the given EMapPoint, + e.g. "Europe/London". */ +static icaltimezone * get_zone_from_point (ETimezoneDialog *etd, EMapPoint *point) { @@ -494,7 +508,7 @@ get_zone_from_point (ETimezoneDialog *etd, priv = etd->priv; if (point == NULL) - return ""; + return NULL; e_map_point_get_location (point, &longitude, &latitude); @@ -514,7 +528,7 @@ get_zone_from_point (ETimezoneDialog *etd, zone_latitude - 0.005 <= latitude && zone_latitude + 0.005 >= latitude) { - return _(icaltimezone_get_location (zone)); + return zone; } } @@ -524,56 +538,50 @@ get_zone_from_point (ETimezoneDialog *etd, } -/* Returns the TZID of the timezone set, and optionally its displayed name. - The TZID may be NULL, in which case the builtin timezone with the city name - of display_name should be used. If display_name is also NULL or "", then it - is assumed to be a 'local time'. Note that display_name may be translated, - so you need to convert it back to English before trying to load it. - It will be in the GTK+ encoding, i.e. not UTF-8. */ -char* -e_timezone_dialog_get_timezone (ETimezoneDialog *etd, - const char **display_name) +/** + * e_timezone_dialog_get_timezone: + * @etd: the timezone dialog + * + * Return value: the currently-selected timezone, or %NULL if no timezone + * is selected. + **/ +icaltimezone * +e_timezone_dialog_get_timezone (ETimezoneDialog *etd) { ETimezoneDialogPrivate *priv; - g_return_val_if_fail (etd != NULL, NULL); g_return_val_if_fail (E_IS_TIMEZONE_DIALOG (etd), NULL); priv = etd->priv; - if (display_name) - *display_name = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry)); - - return priv->tzid; + return priv->zone; } - -/* Sets the TZID and displayed name of the timezone. The TZID may be NULL for - a 'local time' (i.e. display_name is NULL or "") or if it is a builtin - timezone which hasn't been loaded yet. (This is done so we don't load - timezones until we really need them.) The display_name should be the - translated name in the GTK+ - it will be displayed exactly as it is. */ +/** + * e_timezone_dialog_set_timezone: + * @etd: the timezone dialog + * @zone: the timezone + * + * Sets the timezone of @etd to @zone. Updates the display name and + * selected location. The caller must ensure that @zone is not freed + * before @etd is destroyed. + **/ void -e_timezone_dialog_set_timezone (ETimezoneDialog *etd, - char *tzid, - char *display_name) +e_timezone_dialog_set_timezone (ETimezoneDialog *etd, + icaltimezone *zone) { ETimezoneDialogPrivate *priv; - g_return_if_fail (etd != NULL); g_return_if_fail (E_IS_TIMEZONE_DIALOG (etd)); priv = etd->priv; - if (priv->tzid) - g_free (priv->tzid); - - priv->tzid = g_strdup (tzid); + priv->zone = zone; gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry), - display_name ? display_name : ""); + zone ? zone_display_name (zone) : ""); - find_selected_point (etd); + set_map_timezone (etd, zone); } @@ -591,45 +599,24 @@ e_timezone_dialog_get_toplevel (ETimezoneDialog *etd) } -/* This tries to find the timezone corresponding to the text in the combo, - and selects the point so that it flashes. */ static void -find_selected_point (ETimezoneDialog *etd) +set_map_timezone (ETimezoneDialog *etd, icaltimezone *zone) { ETimezoneDialogPrivate *priv; - icalarray *zones; - const char *current_zone; - EMapPoint *point = NULL; - int i; + EMapPoint *point; + double zone_longitude, zone_latitude; priv = etd->priv; - current_zone = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry)); - - /* Get the array of builtin timezones. */ - zones = icaltimezone_get_builtin_timezones (); - - for (i = 0; i < zones->num_elements; i++) { - icaltimezone *zone; - char *location; - - zone = icalarray_element_at (zones, i); - - location = _(icaltimezone_get_location (zone)); - - if (!strcmp (current_zone, location)) { - double zone_longitude, zone_latitude; - - zone_longitude = icaltimezone_get_longitude (zone); - zone_latitude = icaltimezone_get_latitude (zone); - - point = e_map_get_closest_point (priv->map, - zone_longitude, - zone_latitude, - FALSE); - break; - } - } + if (zone) { + zone_longitude = icaltimezone_get_longitude (zone); + zone_latitude = icaltimezone_get_latitude (zone); + point = e_map_get_closest_point (priv->map, + zone_longitude, + zone_latitude, + FALSE); + } else + point = NULL; if (priv->point_selected) e_map_point_set_color_rgba (priv->map, priv->point_selected, @@ -643,13 +630,35 @@ static void on_combo_changed (GtkEditable *entry, ETimezoneDialog *etd) { ETimezoneDialogPrivate *priv; + const char *new_zone_name; + icalarray *zones; + icaltimezone *map_zone = NULL; + char *location; + int i; priv = etd->priv; - find_selected_point (etd); + new_zone_name = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry)); + + if (!*new_zone_name) + priv->zone = NULL; + else if (!strcmp (new_zone_name, _("UTC"))) + priv->zone = icaltimezone_get_utc_timezone (); + else { + priv->zone = NULL; + + zones = icaltimezone_get_builtin_timezones (); + for (i = 0; i < zones->num_elements; i++) { + map_zone = icalarray_element_at (zones, i); + location = _(icaltimezone_get_location (map_zone)); + if (!strcmp (new_zone_name, location)) { + priv->zone = map_zone; + break; + } + } + } - g_free (priv->tzid); - priv->tzid = NULL; + set_map_timezone (etd, map_zone); } /** @@ -670,40 +679,5 @@ e_timezone_dialog_reparent (ETimezoneDialog *etd, gtk_widget_reparent (priv->table, new_parent); } - -/* Returns the builtin timezone corresponding to display_name, which is - the translated location, e.g. 'Europe/London', in the locale's encoding. - If display_name is NULL or "" it returns NULL. */ -icaltimezone* -e_timezone_dialog_get_builtin_timezone (const char *display_name) -{ - icalarray *zones; - int i; - - /* If the field is empty, return NULL (i.e. a floating time). */ - if (!display_name || !display_name[0]) - return NULL; - - /* Check for UTC. */ - if (!strcmp (display_name, _("UTC"))) - return icaltimezone_get_utc_timezone (); - - /* Get the array of builtin timezones. */ - zones = icaltimezone_get_builtin_timezones (); - - for (i = 0; i < zones->num_elements; i++) { - icaltimezone *zone; - char *location; - - zone = icalarray_element_at (zones, i); - location = icaltimezone_get_location (zone); - if (!strcmp (display_name, _(location))) - return zone; - } - - return NULL; -} - - E_MAKE_TYPE (e_timezone_dialog, "ETimezoneDialog", ETimezoneDialog, e_timezone_dialog_class_init, e_timezone_dialog_init, G_TYPE_OBJECT) diff --git a/widgets/e-timezone-dialog/e-timezone-dialog.h b/widgets/e-timezone-dialog/e-timezone-dialog.h index cdcfc91ef4..35617844f1 100644 --- a/widgets/e-timezone-dialog/e-timezone-dialog.h +++ b/widgets/e-timezone-dialog/e-timezone-dialog.h @@ -51,39 +51,18 @@ struct _ETimezoneDialogClass { }; -GtkType e_timezone_dialog_get_type (void); -ETimezoneDialog* e_timezone_dialog_construct (ETimezoneDialog *etd); - -ETimezoneDialog* e_timezone_dialog_new (void); - -/* Returns the TZID of the timezone set, and optionally its displayed name. - The TZID may be NULL, in which case the builtin timezone with the city name - of display_name should be used. If display_name is also NULL or "", then it - is assumed to be a 'local time'. Note that display_name may be translated, - so you need to convert it back to English before trying to load it. - It will be in the GTK+ encoding, i.e. not UTF-8. */ -char* e_timezone_dialog_get_timezone (ETimezoneDialog *etd, - const char **display_name); - -/* Sets the TZID and displayed name of the timezone. The TZID may be NULL for - a 'local time' (i.e. display_name is NULL or "") or if it is a builtin - timezone which hasn't been loaded yet. (This is done so we don't load - timezones until we really need them.) The display_name should be the - translated name in the GTK+ - it will be displayed exactly as it is. */ -void e_timezone_dialog_set_timezone (ETimezoneDialog *etd, - char *tzid, - char *display_name); - -GtkWidget* e_timezone_dialog_get_toplevel (ETimezoneDialog *etd); - -void e_timezone_dialog_reparent (ETimezoneDialog *etd, - GtkWidget *new_parent); - -/* Returns the builtin timezone corresponding to display_name, which is - the translated location, e.g. 'Europe/London', in the GTK+ encoding. - If display_name is NULL or "" it returns NULL. */ -icaltimezone *e_timezone_dialog_get_builtin_timezone (const char *display_name); +GType e_timezone_dialog_get_type (void); +ETimezoneDialog *e_timezone_dialog_construct (ETimezoneDialog *etd); - +ETimezoneDialog *e_timezone_dialog_new (void); + +icaltimezone *e_timezone_dialog_get_timezone (ETimezoneDialog *etd); +void e_timezone_dialog_set_timezone (ETimezoneDialog *etd, + icaltimezone *zone); + +GtkWidget *e_timezone_dialog_get_toplevel (ETimezoneDialog *etd); + +void e_timezone_dialog_reparent (ETimezoneDialog *etd, + GtkWidget *new_parent); #endif /* __E_TIMEZONE_DIALOG_H__ */ |