[evolution] I#385 - Add "floating time" timezone option for events



commit fb39c5ad57388a0a0a594a828ad39d5533430450
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jun 20 15:44:21 2019 +0200

    I#385 - Add "floating time" timezone option for events
    
    Closes https://gitlab.gnome.org/GNOME/evolution/issues/385

 src/calendar/gui/e-comp-editor-property-part.c  | 17 +++--
 src/calendar/gui/e-comp-editor-property-parts.c | 12 ++--
 src/calendar/gui/e-timezone-entry.c             | 25 +++++++
 src/calendar/gui/e-timezone-entry.h             |  3 +
 src/e-util/e-timezone-dialog.c                  | 92 +++++++++++++++++++++++--
 src/e-util/e-timezone-dialog.h                  |  3 +
 6 files changed, 138 insertions(+), 14 deletions(-)
---
diff --git a/src/calendar/gui/e-comp-editor-property-part.c b/src/calendar/gui/e-comp-editor-property-part.c
index 7e2da74a84..34bbc52412 100644
--- a/src/calendar/gui/e-comp-editor-property-part.c
+++ b/src/calendar/gui/e-comp-editor-property-part.c
@@ -993,10 +993,19 @@ e_comp_editor_property_part_datetime_get_value (ECompEditorPropertyPartDatetime
                        i_cal_time_set_time (value, hour, minute, 0);
 
                        timezone_entry = g_weak_ref_get (&part_datetime->priv->timezone_entry);
-                       if (timezone_entry)
-                               i_cal_time_set_timezone (value, e_timezone_entry_get_timezone 
(timezone_entry));
-                       if (!i_cal_time_get_timezone (value))
-                               i_cal_time_set_timezone (value, i_cal_timezone_get_utc_timezone ());
+                       if (timezone_entry) {
+                               ICalTimezone *zone, *utc_zone;
+
+                               utc_zone = i_cal_timezone_get_utc_timezone ();
+                               zone = e_timezone_entry_get_timezone (timezone_entry);
+
+                               /* It's required to have set the built-in UTC zone, not its copy,
+                                  thus libical knows that it's a UTC time, not a time with UTC TZID. */
+                               if (zone && g_strcmp0 (i_cal_timezone_get_location (utc_zone), 
i_cal_timezone_get_location (zone)) == 0)
+                                       zone = utc_zone;
+
+                               i_cal_time_set_timezone (value, zone);
+                       }
                }
        }
 
diff --git a/src/calendar/gui/e-comp-editor-property-parts.c b/src/calendar/gui/e-comp-editor-property-parts.c
index fc35f35bc9..27f498518a 100644
--- a/src/calendar/gui/e-comp-editor-property-parts.c
+++ b/src/calendar/gui/e-comp-editor-property-parts.c
@@ -1436,6 +1436,7 @@ ecepp_timezone_create_widgets (ECompEditorPropertyPart *property_part,
        gtk_widget_show (*out_label_widget);
 
        *out_edit_widget = e_timezone_entry_new ();
+       e_timezone_entry_set_allow_none (E_TIMEZONE_ENTRY (*out_edit_widget), TRUE);
        e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (*out_edit_widget), calendar_config_get_icaltimezone 
());
 
        gtk_widget_show (*out_edit_widget);
@@ -1470,15 +1471,16 @@ ecepp_timezone_fill_widget (ECompEditorPropertyPart *property_part,
 
        if (prop) {
                ICalTime *itt;
+               GtkWidget *edit_widget;
+
+               edit_widget = e_comp_editor_property_part_get_edit_widget (property_part);
+               g_return_if_fail (E_IS_TIMEZONE_ENTRY (edit_widget));
 
                itt = get_func (prop);
                if (itt && i_cal_time_get_timezone (itt)) {
-                       GtkWidget *edit_widget;
-
-                       edit_widget = e_comp_editor_property_part_get_edit_widget (property_part);
-                       g_return_if_fail (E_IS_TIMEZONE_ENTRY (edit_widget));
-
                        e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (edit_widget), 
i_cal_time_get_timezone (itt));
+               } else {
+                       e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (edit_widget), NULL);
                }
 
                g_clear_object (&itt);
diff --git a/src/calendar/gui/e-timezone-entry.c b/src/calendar/gui/e-timezone-entry.c
index 6acdaea126..576e3eb87c 100644
--- a/src/calendar/gui/e-timezone-entry.c
+++ b/src/calendar/gui/e-timezone-entry.c
@@ -45,6 +45,7 @@ struct _ETimezoneEntryPrivate {
         * use a ref count - we assume it is never destroyed for the
         * lifetime of this widget. */
        ICalTimezone *timezone;
+       gboolean allow_none;
 
        GtkWidget *entry;
        GtkWidget *button;
@@ -87,6 +88,8 @@ timezone_entry_update_entry (ETimezoneEntry *timezone_entry)
                 * it. If it isn't a builtin timezone name, we don't. */
                if (i_cal_timezone_get_builtin_timezone (display_name))
                        display_name = _(display_name);
+       } else if (timezone_entry->priv->allow_none) {
+               display_name = C_("timezone", "None");
        } else
                display_name = "";
 
@@ -164,6 +167,7 @@ timezone_entry_button_clicked_cb (ETimezoneEntry *timezone_entry)
        ICalTimezone *timezone;
 
        timezone_dialog = e_timezone_dialog_new ();
+       e_timezone_dialog_set_allow_none (timezone_dialog, e_timezone_entry_get_allow_none (timezone_entry));
 
        timezone = e_timezone_entry_get_timezone (timezone_entry);
        e_timezone_dialog_set_timezone (timezone_dialog, timezone);
@@ -324,6 +328,7 @@ e_timezone_entry_init (ETimezoneEntry *timezone_entry)
        GtkWidget *widget;
 
        timezone_entry->priv = E_TIMEZONE_ENTRY_GET_PRIVATE (timezone_entry);
+       timezone_entry->priv->allow_none = FALSE;
 
        gtk_widget_set_can_focus (GTK_WIDGET (timezone_entry), TRUE);
        gtk_orientable_set_orientation (GTK_ORIENTABLE (timezone_entry), GTK_ORIENTATION_HORIZONTAL);
@@ -384,3 +389,23 @@ e_timezone_entry_set_timezone (ETimezoneEntry *timezone_entry,
 
        g_object_notify (G_OBJECT (timezone_entry), "timezone");
 }
+
+gboolean
+e_timezone_entry_get_allow_none (ETimezoneEntry *timezone_entry)
+{
+       g_return_val_if_fail (E_IS_TIMEZONE_ENTRY (timezone_entry), FALSE);
+
+       return timezone_entry->priv->allow_none;
+}
+
+void
+e_timezone_entry_set_allow_none (ETimezoneEntry *timezone_entry,
+                                gboolean allow_none)
+{
+       g_return_if_fail (E_IS_TIMEZONE_ENTRY (timezone_entry));
+
+       if ((timezone_entry->priv->allow_none ? 1 : 0) == (allow_none ? 1 : 0))
+               return;
+
+       timezone_entry->priv->allow_none = allow_none;
+}
diff --git a/src/calendar/gui/e-timezone-entry.h b/src/calendar/gui/e-timezone-entry.h
index be59c6f590..d931e62210 100644
--- a/src/calendar/gui/e-timezone-entry.h
+++ b/src/calendar/gui/e-timezone-entry.h
@@ -75,6 +75,9 @@ GtkWidget *   e_timezone_entry_new            (void);
 ICalTimezone * e_timezone_entry_get_timezone   (ETimezoneEntry *timezone_entry);
 void           e_timezone_entry_set_timezone   (ETimezoneEntry *timezone_entry,
                                                 const ICalTimezone *timezone);
+gboolean       e_timezone_entry_get_allow_none (ETimezoneEntry *timezone_entry);
+void           e_timezone_entry_set_allow_none (ETimezoneEntry *timezone_entry,
+                                                gboolean allow_none);
 
 G_END_DECLS
 
diff --git a/src/e-util/e-timezone-dialog.c b/src/e-util/e-timezone-dialog.c
index a429faa795..18d61f1afc 100644
--- a/src/e-util/e-timezone-dialog.c
+++ b/src/e-util/e-timezone-dialog.c
@@ -51,6 +51,9 @@
 #define E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_1_RGBA 0xff60e0ff
 #define E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_2_RGBA 0x000000ff
 
+/* Translators: 'None' for a time zone, like 'No time zone being set' */
+#define NONE_TZ_TEXT C_("timezone", "None")
+
 #define E_TIMEZONE_DIALOG_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_TIMEZONE_DIALOG, ETimezoneDialogPrivate))
@@ -59,6 +62,7 @@ struct _ETimezoneDialogPrivate {
        /* The selected timezone. May be NULL for a 'local time' (i.e. when
         * the displayed name is ""). */
        ICalTimezone *zone;
+       gboolean allow_none;
 
        /* In case a non-builtin timezone is used. */
        GSList *custom_zones; /* ICalTimezone * */
@@ -134,6 +138,7 @@ e_timezone_dialog_init (ETimezoneDialog *etd)
 {
        etd->priv = E_TIMEZONE_DIALOG_GET_PRIVATE (etd);
        etd->priv->index = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+       etd->priv->allow_none = FALSE;
 }
 
 /* Dispose handler for the event editor */
@@ -808,10 +813,11 @@ e_timezone_dialog_set_timezone (ETimezoneDialog *etd,
 {
        ETimezoneDialogPrivate *priv;
        gchar *display = NULL;
+       const gchar *no_tz_text;
 
        g_return_if_fail (E_IS_TIMEZONE_DIALOG (etd));
 
-       if (!zone)
+       if (!zone && !etd->priv->allow_none)
                zone = get_local_timezone ();
 
        if (zone)
@@ -844,15 +850,87 @@ e_timezone_dialog_set_timezone (ETimezoneDialog *etd,
 
        priv->zone = zone ? e_cal_util_copy_timezone (zone) : NULL;
 
+       if (priv->allow_none)
+               no_tz_text = NONE_TZ_TEXT;
+       else
+               no_tz_text = "";
+
        gtk_label_set_text (
-               GTK_LABEL (priv->preview_label),
-               zone ? display : "");
-       timezone_combo_set_active_text (etd, zone ? zone_display_name (zone) : "");
+               GTK_LABEL (priv->preview_label), zone ? display : no_tz_text);
+       timezone_combo_set_active_text (etd, zone ? zone_display_name (zone) : no_tz_text);
 
        set_map_timezone (etd, zone);
        g_free (display);
 }
 
+gboolean
+e_timezone_dialog_get_allow_none (ETimezoneDialog *etd)
+{
+       g_return_val_if_fail (E_IS_TIMEZONE_DIALOG (etd), FALSE);
+
+       return etd->priv->allow_none;
+}
+
+void
+e_timezone_dialog_set_allow_none (ETimezoneDialog *etd,
+                                 gboolean allow_none)
+{
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       g_return_if_fail (E_IS_TIMEZONE_DIALOG (etd));
+
+       if ((etd->priv->allow_none ? 1 : 0) == (allow_none ? 1 : 0))
+               return;
+
+       model = gtk_combo_box_get_model (GTK_COMBO_BOX (etd->priv->timezone_combo));
+
+       /* Remove the 'None' item. Custom time zones can be in there, thus search for it */
+       if (etd->priv->allow_none &&
+           gtk_tree_model_get_iter_first (model, &iter)) {
+               const gchar *none_tz_text = NONE_TZ_TEXT;
+
+               do {
+                       gchar *name = NULL, *location = NULL;
+                       gboolean found;
+
+                       gtk_tree_model_get (model, &iter, 0, &name, 1, &location, -1);
+
+                       found = g_strcmp0 (name, none_tz_text) == 0 &&
+                               g_strcmp0 (location, none_tz_text) == 0;
+
+                       g_free (name);
+                       g_free (location);
+
+                       if (found) {
+                               g_hash_table_remove (etd->priv->index, "");
+
+                               gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+                               break;
+                       }
+               } while (gtk_tree_model_iter_next (model, &iter));
+       }
+
+       etd->priv->allow_none = allow_none;
+
+       /* Add the 'None' item */
+       if (etd->priv->allow_none) {
+               GtkTreeStore *tree_store = GTK_TREE_STORE (model);
+               GtkTreeIter *piter;
+
+               gtk_tree_store_prepend (tree_store, &iter, NULL);
+               gtk_tree_store_set (tree_store, &iter,
+                       0, NONE_TZ_TEXT,
+                       1, NONE_TZ_TEXT,
+                       -1);
+
+               piter = g_new (GtkTreeIter, 1);
+               *piter = iter;
+
+               g_hash_table_insert (etd->priv->index, (gchar *) "", piter);
+       }
+}
+
 GtkWidget *
 e_timezone_dialog_get_toplevel (ETimezoneDialog *etd)
 {
@@ -979,8 +1057,12 @@ timezone_combo_set_active_text (ETimezoneDialog *etd,
 
        combo = GTK_COMBO_BOX (etd->priv->timezone_combo);
 
-       if (zone_name && *zone_name)
+       if ((zone_name && *zone_name) || etd->priv->allow_none) {
+               if (!zone_name)
+                       zone_name = "";
+
                piter = g_hash_table_lookup (etd->priv->index, zone_name);
+       }
 
        if (piter)
                gtk_combo_box_set_active_iter (combo, piter);
diff --git a/src/e-util/e-timezone-dialog.h b/src/e-util/e-timezone-dialog.h
index 43f6bb81e6..cb541f8aff 100644
--- a/src/e-util/e-timezone-dialog.h
+++ b/src/e-util/e-timezone-dialog.h
@@ -74,6 +74,9 @@ ETimezoneDialog *
 ICalTimezone * e_timezone_dialog_get_timezone  (ETimezoneDialog *etd);
 void           e_timezone_dialog_set_timezone  (ETimezoneDialog *etd,
                                                 const ICalTimezone *zone);
+gboolean       e_timezone_dialog_get_allow_none(ETimezoneDialog *etd);
+void           e_timezone_dialog_set_allow_none(ETimezoneDialog *etd,
+                                                gboolean allow_none);
 GtkWidget *    e_timezone_dialog_get_toplevel  (ETimezoneDialog *etd);
 
 #endif /* E_TIMEZONE_DIALOG_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]