[evolution] I#1715 - Calendar: Ensure value type matches for start/end, start/due



commit e2b64680eff7cddd4a53bdffffe2397f2832e90c
Author: Milan Crha <mcrha redhat com>
Date:   Thu Nov 25 18:55:09 2021 +0100

    I#1715 - Calendar: Ensure value type matches for start/end, start/due
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1715

 src/calendar/gui/e-comp-editor-event.c         | 10 ++++
 src/calendar/gui/e-comp-editor-property-part.c |  8 ++-
 src/calendar/gui/e-comp-editor-task.c          | 71 ++++++++++++++++++++++++++
 src/calendar/gui/e-comp-editor.c               | 47 +++++++++++++++++
 src/calendar/gui/e-comp-editor.h               |  4 ++
 5 files changed, 135 insertions(+), 5 deletions(-)
---
diff --git a/src/calendar/gui/e-comp-editor-event.c b/src/calendar/gui/e-comp-editor-event.c
index 33ecb9df83..1a8a96fc19 100644
--- a/src/calendar/gui/e-comp-editor-event.c
+++ b/src/calendar/gui/e-comp-editor-event.c
@@ -82,6 +82,9 @@ ece_event_update_times (ECompEditorEvent *event_editor,
                        event_editor->priv->dtstart,
                        event_editor->priv->dtend,
                        change_end_datetime);
+               e_comp_editor_ensure_same_value_type (E_COMP_EDITOR (event_editor),
+                       change_end_datetime ? event_editor->priv->dtstart : event_editor->priv->dtend,
+                       change_end_datetime ? event_editor->priv->dtend : event_editor->priv->dtstart);
        }
 
        flags = e_comp_editor_get_flags (E_COMP_EDITOR (event_editor));
@@ -145,6 +148,13 @@ ece_event_all_day_toggled_cb (ECompEditorEvent *event_editor)
 
        edit_widget = e_comp_editor_property_part_get_edit_widget (event_editor->priv->dtstart);
 
+       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (event_editor->priv->all_day_check))) {
+               gint hour, minute;
+
+               if (!e_date_edit_get_time_of_day (E_DATE_EDIT (edit_widget), &hour, &minute))
+                       e_date_edit_set_time_of_day (E_DATE_EDIT (edit_widget), 0, 0);
+       }
+
        ece_event_update_times (event_editor, E_DATE_EDIT (edit_widget), TRUE);
 
        e_comp_editor_ensure_changed (E_COMP_EDITOR (event_editor));
diff --git a/src/calendar/gui/e-comp-editor-property-part.c b/src/calendar/gui/e-comp-editor-property-part.c
index 393f0f4aa3..14bb9b408d 100644
--- a/src/calendar/gui/e-comp-editor-property-part.c
+++ b/src/calendar/gui/e-comp-editor-property-part.c
@@ -1119,12 +1119,10 @@ e_comp_editor_property_part_datetime_set_value (ECompEditorPropertyPartDatetime
 
                if (!i_cal_time_is_date (value))
                        e_date_edit_set_time_of_day (date_edit, i_cal_time_get_hour (value), 
i_cal_time_get_minute (value));
-               else if (e_date_edit_get_show_time (date_edit))
-                       e_date_edit_set_time_of_day (date_edit, 0, 0);
-               else if (e_date_edit_get_allow_no_date_set (date_edit))
+               else if (e_date_edit_get_show_time (date_edit) && e_date_edit_get_allow_no_date_set 
(date_edit))
                        e_date_edit_set_time_of_day (date_edit, -1, -1);
-
-               e_comp_editor_property_part_datetime_set_date_only (part_datetime, i_cal_time_is_date 
(value));
+               else
+                       e_comp_editor_property_part_datetime_set_date_only (part_datetime, TRUE);
        }
 
        g_clear_object (&tmp_value);
diff --git a/src/calendar/gui/e-comp-editor-task.c b/src/calendar/gui/e-comp-editor-task.c
index 96c575961d..262529e8c7 100644
--- a/src/calendar/gui/e-comp-editor-task.c
+++ b/src/calendar/gui/e-comp-editor-task.c
@@ -50,6 +50,8 @@ struct _ECompEditorTaskPrivate {
 
        gpointer in_the_past_alert;
        gpointer insensitive_info_alert;
+       gboolean dtstart_is_unset;
+       gboolean due_is_unset;
 };
 
 G_DEFINE_TYPE (ECompEditorTask, e_comp_editor_task, E_TYPE_COMP_EDITOR)
@@ -313,10 +315,14 @@ ece_task_dtstart_changed_cb (EDateEdit *date_edit,
                             ECompEditorTask *task_editor)
 {
        ECompEditor *comp_editor;
+       gboolean was_unset;
 
        g_return_if_fail (E_IS_DATE_EDIT (date_edit));
        g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor));
 
+       was_unset = task_editor->priv->dtstart_is_unset;
+       task_editor->priv->dtstart_is_unset = e_date_edit_get_time (date_edit) == (time_t) -1;
+
        comp_editor = E_COMP_EDITOR (task_editor);
 
        if (e_comp_editor_get_updating (comp_editor))
@@ -328,6 +334,16 @@ ece_task_dtstart_changed_cb (EDateEdit *date_edit,
                task_editor->priv->dtstart, task_editor->priv->due_date,
                TRUE);
 
+       /* When setting DTSTART for the first time, derive the type from the DUE,
+          otherwise the DUE has changed the type to the DATE only. */
+       if (was_unset) {
+               e_comp_editor_ensure_same_value_type (E_COMP_EDITOR (task_editor),
+                       task_editor->priv->due_date, task_editor->priv->dtstart);
+       } else {
+               e_comp_editor_ensure_same_value_type (E_COMP_EDITOR (task_editor),
+                       task_editor->priv->dtstart, task_editor->priv->due_date);
+       }
+
        e_comp_editor_set_updating (comp_editor, FALSE);
 
        ece_task_check_dates_in_the_past (task_editor);
@@ -338,10 +354,14 @@ ece_task_due_date_changed_cb (EDateEdit *date_edit,
                              ECompEditorTask *task_editor)
 {
        ECompEditor *comp_editor;
+       gboolean was_unset;
 
        g_return_if_fail (E_IS_DATE_EDIT (date_edit));
        g_return_if_fail (E_IS_COMP_EDITOR_TASK (task_editor));
 
+       was_unset = task_editor->priv->due_is_unset;
+       task_editor->priv->due_is_unset = e_date_edit_get_time (date_edit) == (time_t) -1;
+
        comp_editor = E_COMP_EDITOR (task_editor);
 
        if (e_comp_editor_get_updating (comp_editor))
@@ -353,6 +373,16 @@ ece_task_due_date_changed_cb (EDateEdit *date_edit,
                task_editor->priv->dtstart, task_editor->priv->due_date,
                FALSE);
 
+       /* When setting DUE for the first time, derive the type from the DTSTART,
+          otherwise the DTSTART has changed the type to the DATE only. */
+       if (was_unset) {
+               e_comp_editor_ensure_same_value_type (E_COMP_EDITOR (task_editor),
+                       task_editor->priv->dtstart, task_editor->priv->due_date);
+       } else {
+               e_comp_editor_ensure_same_value_type (E_COMP_EDITOR (task_editor),
+                       task_editor->priv->due_date, task_editor->priv->dtstart);
+       }
+
        e_comp_editor_set_updating (comp_editor, FALSE);
 
        ece_task_check_dates_in_the_past (task_editor);
@@ -666,6 +696,44 @@ ece_task_fill_component (ECompEditor *comp_editor,
        return TRUE;
 }
 
+static void
+ece_task_all_day_notify_active_cb (GObject *object,
+                                  GParamSpec *param,
+                                  gpointer user_data)
+{
+       ECompEditorTask *task_editor = user_data;
+       gboolean active = FALSE, visible = FALSE;
+
+       g_object_get (object,
+               "active", &active,
+               "visible", &visible,
+               NULL);
+
+       if (!active && visible) {
+               EDateEdit *dtstart_date_edit;
+
+               dtstart_date_edit = E_DATE_EDIT (e_comp_editor_property_part_get_edit_widget 
(task_editor->priv->dtstart));
+
+               if (e_date_edit_get_time (dtstart_date_edit) != (time_t) -1) {
+                       EDateEdit *due_date_edit;
+
+                       due_date_edit = E_DATE_EDIT (e_comp_editor_property_part_get_edit_widget 
(task_editor->priv->due_date));
+
+                       if (e_date_edit_get_time (due_date_edit) != (time_t) -1) {
+                               gint hour, minute;
+
+                               if (e_date_edit_get_time_of_day (dtstart_date_edit, &hour, &minute) !=
+                                   e_date_edit_get_time_of_day (due_date_edit, &hour, &minute)) {
+                                       if (e_date_edit_get_time_of_day (dtstart_date_edit, &hour, &minute))
+                                               e_date_edit_set_time_of_day (due_date_edit, hour, minute);
+                                       else
+                                               e_date_edit_set_time_of_day (due_date_edit, -1, -1);
+                               }
+                       }
+               }
+       }
+}
+
 static void
 ece_task_setup_ui (ECompEditorTask *task_editor)
 {
@@ -784,6 +852,9 @@ ece_task_setup_ui (ECompEditorTask *task_editor)
                action, "active",
                edit_widget, "show-time",
                G_BINDING_INVERT_BOOLEAN);
+
+       e_signal_connect_notify (action, "notify::active",
+               G_CALLBACK (ece_task_all_day_notify_active_cb), task_editor);
 }
 
 static void
diff --git a/src/calendar/gui/e-comp-editor.c b/src/calendar/gui/e-comp-editor.c
index a4b8dae976..16b3e15204 100644
--- a/src/calendar/gui/e-comp-editor.c
+++ b/src/calendar/gui/e-comp-editor.c
@@ -3543,6 +3543,53 @@ e_comp_editor_ensure_start_before_end (ECompEditor *comp_editor,
        g_clear_object (&end_tt);
 }
 
+void
+e_comp_editor_ensure_same_value_type (ECompEditor *comp_editor,
+                                     ECompEditorPropertyPart *src_datetime,
+                                     ECompEditorPropertyPart *des_datetime)
+{
+       ECompEditorPropertyPartDatetime *src_dtm, *des_dtm;
+       ICalTime *src_tt, *des_tt;
+
+       g_return_if_fail (E_IS_COMP_EDITOR (comp_editor));
+       g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (src_datetime));
+       g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DATETIME (des_datetime));
+
+       src_dtm = E_COMP_EDITOR_PROPERTY_PART_DATETIME (src_datetime);
+       des_dtm = E_COMP_EDITOR_PROPERTY_PART_DATETIME (des_datetime);
+
+       src_tt = e_comp_editor_property_part_datetime_get_value (src_dtm);
+       des_tt = e_comp_editor_property_part_datetime_get_value (des_dtm);
+
+       if (!src_tt || !des_tt ||
+           i_cal_time_is_null_time (src_tt) ||
+           i_cal_time_is_null_time (des_tt) ||
+           !i_cal_time_is_valid_time (src_tt) ||
+           !i_cal_time_is_valid_time (des_tt)) {
+               g_clear_object (&src_tt);
+               g_clear_object (&des_tt);
+               return;
+       }
+
+       if (i_cal_time_is_date (src_tt) != i_cal_time_is_date (des_tt)) {
+               gint hour = 0, minute = 0, second = 0;
+
+               i_cal_time_set_is_date (des_tt, i_cal_time_is_date (src_tt));
+
+               if (!i_cal_time_is_date (des_tt)) {
+                       i_cal_time_get_time (src_tt, &hour, &minute, &second);
+                       i_cal_time_set_time (des_tt, hour, minute, second);
+               }
+
+               e_comp_editor_set_updating (comp_editor, TRUE);
+               e_comp_editor_property_part_datetime_set_value (des_dtm, des_tt);
+               e_comp_editor_set_updating (comp_editor, FALSE);
+       }
+
+       g_clear_object (&src_tt);
+       g_clear_object (&des_tt);
+}
+
 static gboolean
 e_comp_editor_holds_component (ECompEditor *comp_editor,
                               ESource *origin_source,
diff --git a/src/calendar/gui/e-comp-editor.h b/src/calendar/gui/e-comp-editor.h
index 8973040bcb..1f262d0591 100644
--- a/src/calendar/gui/e-comp-editor.h
+++ b/src/calendar/gui/e-comp-editor.h
@@ -172,6 +172,10 @@ void               e_comp_editor_ensure_start_before_end
                                                 ECompEditorPropertyPart *start_datetime,
                                                 ECompEditorPropertyPart *end_datetime,
                                                 gboolean change_end_datetime);
+void           e_comp_editor_ensure_same_value_type
+                                               (ECompEditor *comp_editor,
+                                                ECompEditorPropertyPart *src_datetime,
+                                                ECompEditorPropertyPart *des_datetime);
 ECompEditor *  e_comp_editor_open_for_component
                                                (GtkWindow *parent,
                                                 EShell *shell,


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