[gnome-calendar] edit-dialog: keep start and end dates synchronized



commit 56ae69d6c4f1dab5700076cd022e1e4d312d868b
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Aug 30 00:29:50 2016 -0300

    edit-dialog: keep start and end dates synchronized
    
    Never let them enter in an invalid state, where the end
    date is ahead of the start date.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=770263

 data/ui/edit-dialog.ui |    4 +++
 src/gcal-edit-dialog.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 0 deletions(-)
---
diff --git a/data/ui/edit-dialog.ui b/data/ui/edit-dialog.ui
index 975c09e..37ec055 100644
--- a/data/ui/edit-dialog.ui
+++ b/data/ui/edit-dialog.ui
@@ -219,6 +219,7 @@
                   <object class="GcalDateSelector" id="start_date_selector">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <signal name="notify::date" handler="sync_datetimes" object="GcalEditDialog" 
swapped="yes" />
                   </object>
                 </child>
                 <child>
@@ -232,6 +233,7 @@
                   <object class="GcalDateSelector" id="end_date_selector">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <signal name="notify::date" handler="sync_datetimes" object="GcalEditDialog" 
swapped="yes" />
                   </object>
                 </child>
               </object>
@@ -281,6 +283,7 @@
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="hexpand">True</property>
+                            <signal name="notify::time" handler="sync_datetimes" object="GcalEditDialog" 
swapped="yes" />
                           </object>
                         </child>
                         <child>
@@ -295,6 +298,7 @@
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="hexpand">True</property>
+                            <signal name="notify::time" handler="sync_datetimes" object="GcalEditDialog" 
swapped="yes" />
                           </object>
                         </child>
                       </object>
diff --git a/src/gcal-edit-dialog.c b/src/gcal-edit-dialog.c
index ff54dd1..4cf1a69 100644
--- a/src/gcal-edit-dialog.c
+++ b/src/gcal-edit-dialog.c
@@ -295,6 +295,61 @@ update_revealer_visibility_cb (GtkRevealer *revealer)
 }
 
 static void
+sync_datetimes (GcalEditDialog *self,
+                GParamSpec     *pspec,
+                GtkWidget      *widget)
+{
+  GDateTime *start, *end, *new_date;
+  GtkWidget *date_widget, *time_widget;
+  gboolean is_start;
+  gint hour_to_add;
+
+  is_start = (widget == self->start_time_selector || widget == self->start_date_selector);
+  start = gcal_edit_dialog_get_date_start (self);
+  end = gcal_edit_dialog_get_date_end (self);
+
+  /* The date is valid, no need to update the fields */
+  if (g_date_time_compare (end, start) >= 0)
+    goto out;
+
+  /*
+   * If the user is changing the start date or time, we change the end
+   * date or time (and vice versa).
+   */
+  hour_to_add = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->all_day_check)) ? 0 : 1;
+
+  if (is_start)
+    {
+      new_date = g_date_time_add_hours (start, hour_to_add);
+
+      date_widget = self->end_date_selector;
+      time_widget = self->end_time_selector;
+    }
+  else
+    {
+      new_date = g_date_time_add_hours (end, hour_to_add);
+
+      date_widget = self->start_date_selector;
+      time_widget = self->start_time_selector;
+    }
+
+  g_signal_handlers_block_by_func (date_widget, sync_datetimes, self);
+  g_signal_handlers_block_by_func (time_widget, sync_datetimes, self);
+
+  gcal_date_selector_set_date (GCAL_DATE_SELECTOR (date_widget), new_date);
+  gcal_time_selector_set_time (GCAL_TIME_SELECTOR (time_widget), new_date);
+
+  g_signal_handlers_unblock_by_func (date_widget, sync_datetimes, self);
+  g_signal_handlers_unblock_by_func (time_widget, sync_datetimes, self);
+
+  g_clear_pointer (&new_date, g_date_time_unref);
+
+out:
+  g_clear_pointer (&start, g_date_time_unref);
+  g_clear_pointer (&end, g_date_time_unref);
+}
+
+static void
 gcal_edit_dialog_get_property (GObject    *object,
                                guint       prop_id,
                                GValue     *value,
@@ -442,6 +497,7 @@ gcal_edit_dialog_class_init (GcalEditDialogClass *klass)
   gtk_widget_class_bind_template_callback (widget_class, update_summary);
   gtk_widget_class_bind_template_callback (widget_class, update_location);
   gtk_widget_class_bind_template_callback (widget_class, update_revealer_visibility_cb);
+  gtk_widget_class_bind_template_callback (widget_class, sync_datetimes);
 }
 
 static void
@@ -1044,13 +1100,25 @@ gcal_edit_dialog_set_event (GcalEditDialog *dialog,
       date_end = all_day ? g_date_time_add_days (date_end, -1) : g_date_time_to_local (date_end);
 
       /* date */
+      g_signal_handlers_block_by_func (dialog->end_date_selector, sync_datetimes, dialog);
+      g_signal_handlers_block_by_func (dialog->start_date_selector, sync_datetimes, dialog);
+
       gcal_date_selector_set_date (GCAL_DATE_SELECTOR (dialog->start_date_selector), date_start);
       gcal_date_selector_set_date (GCAL_DATE_SELECTOR (dialog->end_date_selector), date_end);
 
+      g_signal_handlers_unblock_by_func (dialog->start_date_selector, sync_datetimes, dialog);
+      g_signal_handlers_unblock_by_func (dialog->end_date_selector, sync_datetimes, dialog);
+
       /* time */
+      g_signal_handlers_block_by_func (dialog->end_time_selector, sync_datetimes, dialog);
+      g_signal_handlers_block_by_func (dialog->start_time_selector, sync_datetimes, dialog);
+
       gcal_time_selector_set_time (GCAL_TIME_SELECTOR (dialog->start_time_selector), date_start);
       gcal_time_selector_set_time (GCAL_TIME_SELECTOR (dialog->end_time_selector), date_end);
 
+      g_signal_handlers_unblock_by_func (dialog->start_time_selector, sync_datetimes, dialog);
+      g_signal_handlers_unblock_by_func (dialog->end_time_selector, sync_datetimes, dialog);
+
       /* all_day  */
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->all_day_check), all_day);
 


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