[gnome-calendar] view: rework active-date



commit aa5b963412d52fd3b983a84885e63ad3bdf10578
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Apr 12 20:47:37 2017 -0300

    view: rework active-date
    
    The current implementation is deficient in many ways, the
    worst one being the it relying on GObject semi-synchronous
    property emission.
    
    This issue was exposed by the Week view code, where the active
    date was updated, but delayed to reach the Week header and some
    events were being added ~before~ the active date changed.
    
    With this work, I was also able to figure out a bunch of code
    that relied on this (i.e. luck) to work.

 data/ui/week-view.ui         |    2 -
 src/gcal-view.c              |   24 ++++++--
 src/gcal-view.h              |    5 ++
 src/gcal-window.c            |  148 +++++++++++++++++++----------------------
 src/views/gcal-month-view.c  |   69 ++++++++++++++------
 src/views/gcal-week-grid.c   |   55 ++++------------
 src/views/gcal-week-grid.h   |    3 +
 src/views/gcal-week-header.c |   94 ++++++++++-----------------
 src/views/gcal-week-header.h |    3 +
 src/views/gcal-week-view.c   |   57 ++++++++++++-----
 src/views/gcal-year-view.c   |   94 +++++++++++++++++----------
 11 files changed, 295 insertions(+), 259 deletions(-)
---
diff --git a/data/ui/week-view.ui b/data/ui/week-view.ui
index 62d8754..7540bcb 100644
--- a/data/ui/week-view.ui
+++ b/data/ui/week-view.ui
@@ -9,7 +9,6 @@
     <child>
       <object class="GcalWeekHeader" id="header">
         <property name="visible">True</property>
-        <property name="active-date" bind-source="GcalWeekView" bind-property="active-date" 
bind-flags="default" />
         <signal name="event-activated" handler="on_event_activated" object="GcalWeekView" swapped="yes" />
       </object>
     </child>
@@ -37,7 +36,6 @@
                     <property name="visible">True</property>
                     <property name="hexpand">True</property>
                     <property name="vexpand">True</property>
-                    <property name="active-date" bind-source="GcalWeekView" bind-property="active-date" 
bind-flags="default" />
                     <signal name="event-activated" handler="on_event_activated" object="GcalWeekView" 
swapped="yes" />
                   </object>
                 </child>
diff --git a/src/gcal-view.c b/src/gcal-view.c
index fae8a76..037bc05 100644
--- a/src/gcal-view.c
+++ b/src/gcal-view.c
@@ -75,24 +75,38 @@ gcal_view_default_init (GcalViewInterface *iface)
                 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
 }
 
+/**
+ * gcal_view_set_date:
+ * @view: a #GcalView
+ * @date: an #icaltimetype
+ *
+ * Sets the date of @view.
+ */
 void
 gcal_view_set_date (GcalView     *view,
                     icaltimetype *date)
 {
   g_return_if_fail (GCAL_IS_VIEW (view));
+  g_return_if_fail (GCAL_VIEW_GET_IFACE (view)->set_date);
 
-  g_object_set (view, "active-date", date, NULL);
+  GCAL_VIEW_GET_IFACE (view)->set_date (view, date);
 }
 
+/**
+ * gcal_view_get_date:
+ * @view: a #GcalView
+ *
+ * Retrieves the date of @view.
+ *
+ * Returns: (transfer none): an #icaltimetype.
+ */
 icaltimetype*
 gcal_view_get_date (GcalView *view)
 {
-  icaltimetype *date;
-
   g_return_val_if_fail (GCAL_IS_VIEW (view), NULL);
+  g_return_val_if_fail (GCAL_VIEW_GET_IFACE (view)->get_date, NULL);
 
-  g_object_get (view, "active-date", &date, NULL);
-  return date;
+  return GCAL_VIEW_GET_IFACE (view)->get_date (view);
 }
 
 /**
diff --git a/src/gcal-view.h b/src/gcal-view.h
index 8ec6e6c..a1df2d2 100644
--- a/src/gcal-view.h
+++ b/src/gcal-view.h
@@ -42,6 +42,11 @@ struct _GcalViewInterface
                                                         icaltimetype *start_span,
                                                         icaltimetype *end_span);
 
+  icaltimetype*  (*get_date)                           (GcalView     *view);
+
+  void           (*set_date)                           (GcalView     *view,
+                                                        icaltimetype *date);
+
   /* Marks related API */
   void           (*clear_marks)                        (GcalView    *view);
 
diff --git a/src/gcal-window.c b/src/gcal-window.c
index 662d3d8..89750c9 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -268,7 +268,10 @@ update_active_date (GcalWindow   *window,
 
   previous_date = window->active_date;
   window->active_date = new_date;
-  g_object_notify (G_OBJECT (window), "active-date");
+
+  gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_WEEK]), new_date);
+  gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_MONTH]), new_date);
+  gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_YEAR]), new_date);
 
   /* year_view */
   if (previous_date->year != new_date->year)
@@ -1235,82 +1238,6 @@ schedule_open_edit_dialog_by_uuid (OpenEditDialogData *edit_dialog_data)
 }
 
 static void
-gcal_window_constructed (GObject *object)
-{
-  GcalWindow *window = GCAL_WINDOW (object);
-
-  GtkBuilder *builder;
-  GMenuModel *winmenu;
-
-  GSettings *helper_settings;
-  gchar *clock_format;
-  gboolean use_24h_format;
-
-  GCAL_ENTRY;
-
-  if (G_OBJECT_CLASS (gcal_window_parent_class)->constructed != NULL)
-    G_OBJECT_CLASS (gcal_window_parent_class)->constructed (object);
-
-  helper_settings = g_settings_new ("org.gnome.desktop.interface");
-  clock_format = g_settings_get_string (helper_settings, "clock-format");
-  use_24h_format = (g_strcmp0 (clock_format, "24h") == 0);
-  g_free (clock_format);
-  g_object_unref (helper_settings);
-
-  /* header_bar: menu */
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_resource (builder,
-                                 "/org/gnome/calendar/gtk/menus.ui",
-                                 NULL);
-
-  winmenu = (GMenuModel *)gtk_builder_get_object (builder, "win-menu");
-  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (window->menu_button),
-                                  winmenu);
-
-  g_object_unref (builder);
-
-  window->views[GCAL_WINDOW_VIEW_WEEK] = window->week_view;
-  window->views[GCAL_WINDOW_VIEW_MONTH] = window->month_view;
-  window->views[GCAL_WINDOW_VIEW_YEAR] = window->year_view;
-
-  gcal_edit_dialog_set_time_format (GCAL_EDIT_DIALOG (window->edit_dialog), use_24h_format);
-
-  gcal_week_view_set_first_weekday (GCAL_WEEK_VIEW (window->views[GCAL_WINDOW_VIEW_WEEK]), get_first_weekday 
());
-  gcal_week_view_set_use_24h_format (GCAL_WEEK_VIEW (window->views[GCAL_WINDOW_VIEW_WEEK]), use_24h_format);
-
-  gcal_month_view_set_first_weekday (GCAL_MONTH_VIEW (window->views[GCAL_WINDOW_VIEW_MONTH]), 
get_first_weekday ());
-  gcal_month_view_set_use_24h_format (GCAL_MONTH_VIEW (window->views[GCAL_WINDOW_VIEW_MONTH]), 
use_24h_format);
-
-  gcal_year_view_set_first_weekday (GCAL_YEAR_VIEW (window->views[GCAL_WINDOW_VIEW_YEAR]), get_first_weekday 
());
-  gcal_year_view_set_use_24h_format (GCAL_YEAR_VIEW (window->views[GCAL_WINDOW_VIEW_YEAR]), use_24h_format);
-
-  /* search view */
-  gcal_search_view_connect (GCAL_SEARCH_VIEW (window->search_view), window->manager);
-  gcal_search_view_set_time_format (GCAL_SEARCH_VIEW (window->search_view), use_24h_format);
-
-  /* refresh timeout, first is fast */
-  window->refresh_timeout_id = g_timeout_add (FAST_REFRESH_TIMEOUT, (GSourceFunc) refresh_sources, object);
-
-  /* calendars popover */
-  gtk_list_box_set_sort_func (GTK_LIST_BOX (window->calendar_listbox), (GtkListBoxSortFunc) 
calendar_listbox_sort_func,
-                              object, NULL);
-
-  if (!gcal_manager_get_loading (window->manager))
-    {
-      GList *sources, *l;
-
-      sources = gcal_manager_get_sources_connected (window->manager);
-
-      for (l = sources; l != NULL; l = g_list_next (l))
-        add_source (window->manager, l->data, is_source_enabled (l->data), object);
-
-      g_list_free (sources);
-    }
-
-  GCAL_EXIT;
-}
-
-static void
 gcal_window_finalize (GObject *object)
 {
   GcalWindow *window = GCAL_WINDOW (object);
@@ -1380,6 +1307,19 @@ gcal_window_set_property (GObject      *object,
     case PROP_MANAGER:
       if (g_set_object (&self->manager, g_value_get_object (value)))
         {
+
+          if (!gcal_manager_get_loading (self->manager))
+            {
+              GList *sources, *l;
+
+              sources = gcal_manager_get_sources_connected (self->manager);
+
+              for (l = sources; l != NULL; l = g_list_next (l))
+                add_source (self->manager, l->data, is_source_enabled (l->data), self);
+
+              g_list_free (sources);
+            }
+
           g_signal_connect (self->manager, "source-added", G_CALLBACK (add_source), object);
           g_signal_connect (self->manager, "source-removed", G_CALLBACK (remove_source), object);
           g_signal_connect_swapped (self->manager, "source-enabled", G_CALLBACK (source_enabled), object);
@@ -1487,7 +1427,6 @@ gcal_window_class_init(GcalWindowClass *klass)
   GtkWidgetClass *widget_class;
 
   object_class = G_OBJECT_CLASS (klass);
-  object_class->constructed = gcal_window_constructed;
   object_class->finalize = gcal_window_finalize;
   object_class->set_property = gcal_window_set_property;
   object_class->get_property = gcal_window_get_property;
@@ -1523,7 +1462,6 @@ gcal_window_class_init(GcalWindowClass *klass)
                           "Date",
                           "The active/selected date",
                           ICAL_TIME_TYPE,
-                          G_PARAM_CONSTRUCT |
                           G_PARAM_READWRITE));
 
   g_object_class_install_property (
@@ -1597,6 +1535,12 @@ gcal_window_class_init(GcalWindowClass *klass)
 static void
 gcal_window_init (GcalWindow *self)
 {
+  GtkBuilder *builder;
+  GMenuModel *winmenu;
+  GSettings *helper_settings;
+  gchar *clock_format;
+  gboolean use_24h_format;
+
   /* Setup actions */
   g_action_map_add_action_entries (G_ACTION_MAP (self),
                                    actions,
@@ -1609,6 +1553,52 @@ gcal_window_init (GcalWindow *self)
   g_object_bind_property (self, "application", self->source_dialog, "application",
                           G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
 
+  helper_settings = g_settings_new ("org.gnome.desktop.interface");
+  clock_format = g_settings_get_string (helper_settings, "clock-format");
+  use_24h_format = (g_strcmp0 (clock_format, "24h") == 0);
+  g_free (clock_format);
+  g_object_unref (helper_settings);
+
+  /* header_bar: menu */
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_resource (builder,
+                                 "/org/gnome/calendar/gtk/menus.ui",
+                                 NULL);
+
+  winmenu = (GMenuModel *)gtk_builder_get_object (builder, "win-menu");
+  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (self->menu_button),
+                                  winmenu);
+
+  g_object_unref (builder);
+
+  self->views[GCAL_WINDOW_VIEW_WEEK] = self->week_view;
+  self->views[GCAL_WINDOW_VIEW_MONTH] = self->month_view;
+  self->views[GCAL_WINDOW_VIEW_YEAR] = self->year_view;
+
+  gcal_edit_dialog_set_time_format (GCAL_EDIT_DIALOG (self->edit_dialog), use_24h_format);
+
+  gcal_week_view_set_first_weekday (GCAL_WEEK_VIEW (self->views[GCAL_WINDOW_VIEW_WEEK]), get_first_weekday 
());
+  gcal_week_view_set_use_24h_format (GCAL_WEEK_VIEW (self->views[GCAL_WINDOW_VIEW_WEEK]), use_24h_format);
+
+  gcal_month_view_set_first_weekday (GCAL_MONTH_VIEW (self->views[GCAL_WINDOW_VIEW_MONTH]), 
get_first_weekday ());
+  gcal_month_view_set_use_24h_format (GCAL_MONTH_VIEW (self->views[GCAL_WINDOW_VIEW_MONTH]), use_24h_format);
+
+  gcal_year_view_set_first_weekday (GCAL_YEAR_VIEW (self->views[GCAL_WINDOW_VIEW_YEAR]), get_first_weekday 
());
+  gcal_year_view_set_use_24h_format (GCAL_YEAR_VIEW (self->views[GCAL_WINDOW_VIEW_YEAR]), use_24h_format);
+
+  /* search view */
+  gcal_search_view_connect (GCAL_SEARCH_VIEW (self->search_view), self->manager);
+  gcal_search_view_set_time_format (GCAL_SEARCH_VIEW (self->search_view), use_24h_format);
+
+  /* refresh timeout, first is fast */
+  self->refresh_timeout_id = g_timeout_add (FAST_REFRESH_TIMEOUT, (GSourceFunc) refresh_sources, self);
+
+  /* calendars popover */
+  gtk_list_box_set_sort_func (GTK_LIST_BOX (self->calendar_listbox),
+                              (GtkListBoxSortFunc) calendar_listbox_sort_func,
+                              self,
+                              NULL);
+
   self->active_date = g_new0 (icaltimetype, 1);
   self->rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
 }
diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c
index 82841a0..5758ad5 100644
--- a/src/views/gcal-month-view.c
+++ b/src/views/gcal-month-view.c
@@ -24,6 +24,7 @@
 
 #define G_LOG_DOMAIN "GcalMonthView"
 
+#include "gcal-debug.h"
 #include "gcal-month-view.h"
 #include "gcal-subscriber-view-private.h"
 #include "gcal-utils.h"
@@ -914,6 +915,42 @@ add_new_event_button_cb (GtkWidget *button,
 }
 
 /* GcalView Interface API */
+static icaltimetype*
+gcal_month_view_get_date (GcalView *view)
+{
+  GcalMonthView *self = GCAL_MONTH_VIEW (view);
+
+  return self->date;
+}
+
+static void
+gcal_month_view_set_date (GcalView     *view,
+                          icaltimetype *date)
+{
+  GcalSubscriberViewPrivate *ppriv;
+  GcalMonthView *self;
+
+  GCAL_ENTRY;
+
+  self = GCAL_MONTH_VIEW (view);
+  ppriv = GCAL_SUBSCRIBER_VIEW (view)->priv;
+
+  g_clear_pointer (&self->date, g_free);
+
+  self->date = gcal_dup_icaltime (date);
+  self->days_delay = (time_day_of_week (1, self->date->month - 1, self->date->year) - self->first_weekday + 
7) % 7;
+  self->keyboard_cell = self->days_delay + (self->date->day - 1);
+
+  GCAL_TRACE_MSG ("new date: %s", icaltime_as_ical_string (*date));
+
+  cancel_selection (self);
+
+  ppriv->children_changed = TRUE;
+  gtk_widget_queue_resize (GTK_WIDGET (view));
+
+  GCAL_EXIT;
+}
+
 static void
 gcal_month_view_clear_marks (GcalView *view)
 {
@@ -939,6 +976,8 @@ gcal_month_view_get_children_by_uuid (GcalView    *view,
 static void
 gcal_view_interface_init (GcalViewInterface *iface)
 {
+  iface->get_date = gcal_month_view_get_date;
+  iface->set_date = gcal_month_view_set_date;
   iface->clear_marks = gcal_month_view_clear_marks;
   iface->get_children_by_uuid = gcal_month_view_get_children_by_uuid;
 }
@@ -949,29 +988,12 @@ gcal_month_view_set_property (GObject       *object,
                               const GValue  *value,
                               GParamSpec    *pspec)
 {
-  GcalSubscriberViewPrivate *ppriv;
-  GcalMonthView *self;
-
-  ppriv = GCAL_SUBSCRIBER_VIEW (object)->priv;
-  self = GCAL_MONTH_VIEW (object);
-
   switch (property_id)
     {
     case PROP_DATE:
-      {
-        if (self->date != NULL)
-          g_free (self->date);
-
-        self->date = g_value_dup_boxed (value);
-        self->days_delay = (time_day_of_week (1, self->date->month - 1, self->date->year) - 
self->first_weekday + 7) % 7;
-        self->keyboard_cell = self->days_delay + (self->date->day - 1);
-
-        cancel_selection (GCAL_MONTH_VIEW (object));
+      gcal_view_set_date (GCAL_VIEW (object), g_value_get_boxed (value));
+      break;
 
-        ppriv->children_changed = TRUE;
-        gtk_widget_queue_resize (GTK_WIDGET (object));
-        break;
-      }
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -2063,15 +2085,22 @@ gcal_month_view_button_release (GtkWidget      *widget,
 
   if (current_day >= self->days_delay && current_day < days)
     {
+      gboolean valid;
+
       g_clear_pointer (&self->end_mark_cell, g_date_time_unref);
 
       self->keyboard_cell = current_day;
       self->end_mark_cell = g_date_time_new_local (self->date->year, self->date->month, current_day - 
self->days_delay + 1, 0, 0, 0);
 
       self->date->day = g_date_time_get_day_of_month (self->end_mark_cell);
+
+      /* First, make sure to show the popover */
+      valid = show_popover_for_position (GCAL_MONTH_VIEW (widget), x, y, released_indicator);
+
+      /* Then update the active date */
       g_object_notify (G_OBJECT (self), "active-date");
 
-      return show_popover_for_position (GCAL_MONTH_VIEW (widget), x, y, released_indicator);
+      return valid;
     }
   else
     {
diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c
index 59ec049..004ad1f 100644
--- a/src/views/gcal-week-grid.c
+++ b/src/views/gcal-week-grid.c
@@ -74,12 +74,6 @@ struct _GcalWeekGrid
 
 G_DEFINE_TYPE (GcalWeekGrid, gcal_week_grid, GTK_TYPE_CONTAINER);
 
-enum
-{
-  PROP_0,
-  PROP_ACTIVE_DATE,
-  LAST_PROP
-};
 
 enum
 {
@@ -88,7 +82,6 @@ enum
 };
 
 static guint signals[LAST_SIGNAL] = { 0, };
-static GParamSpec* properties[LAST_PROP] = { NULL, };
 
 /* ChildData methods */
 static ChildData*
@@ -311,17 +304,7 @@ gcal_week_grid_get_property (GObject    *object,
                              GValue     *value,
                              GParamSpec *pspec)
 {
-  GcalWeekGrid *self = GCAL_WEEK_GRID (object);
-
-  switch (prop_id)
-    {
-    case PROP_ACTIVE_DATE:
-      g_value_set_boxed (value, self->active_date);
-      return;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 }
 
 static void
@@ -330,21 +313,7 @@ gcal_week_grid_set_property (GObject      *object,
                              const GValue *value,
                              GParamSpec   *pspec)
 {
-  GcalWeekGrid *self = GCAL_WEEK_GRID (object);
-
-  switch (prop_id)
-    {
-    case PROP_ACTIVE_DATE:
-      g_clear_pointer (&self->active_date, g_free);
-      self->active_date = g_value_dup_boxed (value);
-
-      gtk_widget_queue_resize (GTK_WIDGET (self));
-      gtk_widget_queue_draw (GTK_WIDGET (self));
-      return;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 }
 
 static void
@@ -1115,13 +1084,6 @@ gcal_week_grid_class_init (GcalWeekGridClass *klass)
   widget_class->drag_leave = gcal_week_grid_drag_leave;
   widget_class->drag_drop = gcal_week_grid_drag_drop;
 
-  properties[PROP_ACTIVE_DATE] = g_param_spec_boxed ("active-date",
-                                                     "Date",
-                                                     "The active selected date",
-                                                     ICAL_TIME_TYPE,
-                                                     G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
-
-
   signals[EVENT_ACTIVATED] = g_signal_new ("event-activated",
                                            GCAL_TYPE_WEEK_GRID,
                                            G_SIGNAL_RUN_FIRST,
@@ -1130,8 +1092,6 @@ gcal_week_grid_class_init (GcalWeekGridClass *klass)
                                            1,
                                            GCAL_TYPE_EVENT_WIDGET);
 
-  g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
-
   gtk_widget_class_set_css_name (widget_class, "weekgrid");
 }
 
@@ -1290,3 +1250,14 @@ gcal_week_grid_clear_marks (GcalWeekGrid *self)
 
   gtk_widget_queue_draw (GTK_WIDGET (self));
 }
+
+void
+gcal_week_grid_set_date (GcalWeekGrid *self,
+                         icaltimetype *date)
+{
+  g_clear_pointer (&self->active_date, g_free);
+  self->active_date = gcal_dup_icaltime (date);
+
+  gtk_widget_queue_resize (GTK_WIDGET (self));
+  gtk_widget_queue_draw (GTK_WIDGET (self));
+}
diff --git a/src/views/gcal-week-grid.h b/src/views/gcal-week-grid.h
index 9992508..2d519b3 100644
--- a/src/views/gcal-week-grid.h
+++ b/src/views/gcal-week-grid.h
@@ -51,6 +51,9 @@ GList*               gcal_week_grid_get_children_by_uuid         (GcalWeekGrid
 
 void                 gcal_week_grid_clear_marks                  (GcalWeekGrid       *self);
 
+void                 gcal_week_grid_set_date                     (GcalWeekGrid       *self,
+                                                                  icaltimetype       *date);
+
 G_END_DECLS
 
 #endif /* GCAL_WEEK_GRID_H */
diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c
index 23e0a4f..6cbcc73 100644
--- a/src/views/gcal-week-header.c
+++ b/src/views/gcal-week-header.c
@@ -86,12 +86,6 @@ typedef enum
 
 enum
 {
-  PROP_0,
-  PROP_ACTIVE_DATE
-};
-
-enum
-{
   EVENT_ACTIVATED,
   LAST_SIGNAL
 };
@@ -1060,17 +1054,7 @@ gcal_week_header_get_property (GObject    *object,
                                GValue     *value,
                                GParamSpec *pspec)
 {
-  GcalWeekHeader *self = GCAL_WEEK_HEADER (object);
-
-  switch (prop_id)
-    {
-    case PROP_ACTIVE_DATE:
-      g_value_set_boxed (value, self->active_date);
-      return;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 }
 
 static void
@@ -1079,41 +1063,7 @@ gcal_week_header_set_property (GObject      *object,
                                const GValue *value,
                                GParamSpec   *pspec)
 {
-  GcalWeekHeader *self = GCAL_WEEK_HEADER (object);
-  icaltimetype *old_date, *new_date;
-
-  switch (prop_id)
-    {
-    case PROP_ACTIVE_DATE:
-      old_date = self->active_date;
-      new_date = g_value_dup_boxed (value);
-
-      /*
-       * If the active date changed, but we're still in the same week,
-       * there's no need to recalculate visible events.
-       */
-      if (old_date && new_date &&
-          old_date->year == new_date->year &&
-          icaltime_week_number (*old_date) == icaltime_week_number (*new_date))
-        {
-          g_free (new_date);
-          break;
-        }
-
-      self->active_date = new_date;
-
-      update_title (self);
-      gtk_widget_queue_draw (GTK_WIDGET (self));
-
-      if (old_date)
-        update_unchanged_events (self, self->active_date);
-
-      g_clear_pointer (&old_date, g_free);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 }
 
 static void
@@ -1514,14 +1464,6 @@ gcal_week_header_class_init (GcalWeekHeaderClass *kclass)
   widget_class->drag_leave = gcal_week_header_drag_leave;
   widget_class->drag_drop = gcal_week_header_drag_drop;
 
-  g_object_class_install_property (object_class,
-                                   PROP_ACTIVE_DATE,
-                                   g_param_spec_boxed ("active-date",
-                                                       "Date",
-                                                       "The active selected date",
-                                                       ICAL_TIME_TYPE,
-                                                       G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
-
   signals[EVENT_ACTIVATED] = g_signal_new ("event-activated",
                                            GCAL_TYPE_WEEK_HEADER,
                                            G_SIGNAL_RUN_FIRST,
@@ -1787,3 +1729,35 @@ gcal_week_header_clear_marks (GcalWeekHeader *self)
 
   gtk_widget_queue_draw (GTK_WIDGET (self));
 }
+
+void
+gcal_week_header_set_date (GcalWeekHeader *self,
+                           icaltimetype   *date)
+{
+  icaltimetype *old_date, *new_date;
+
+  old_date = self->active_date;
+  new_date = gcal_dup_icaltime (date);
+
+  /*
+   * If the active date changed, but we're still in the same week,
+   * there's no need to recalculate visible events.
+   */
+  if (old_date && new_date &&
+      old_date->year == new_date->year &&
+      icaltime_week_number (*old_date) == icaltime_week_number (*new_date))
+    {
+      g_free (new_date);
+      return;
+    }
+
+  self->active_date = new_date;
+
+  update_title (self);
+  gtk_widget_queue_draw (GTK_WIDGET (self));
+
+  if (old_date)
+    update_unchanged_events (self, self->active_date);
+
+  g_clear_pointer (&old_date, g_free);
+}
diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h
index fa866dc..8c9d904 100644
--- a/src/views/gcal-week-header.h
+++ b/src/views/gcal-week-header.h
@@ -53,6 +53,9 @@ GtkSizeGroup*        gcal_week_header_get_sidebar_size_group     (GcalWeekHeader
 
 void                 gcal_week_header_clear_marks                (GcalWeekHeader     *self);
 
+void                 gcal_week_header_set_date                   (GcalWeekHeader     *self,
+                                                                  icaltimetype       *date);
+
 G_END_DECLS
 
 #endif /* GCAL_WEEK_HEADER_H */
diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c
index b115919..8d7fcb4 100644
--- a/src/views/gcal-week-view.c
+++ b/src/views/gcal-week-view.c
@@ -162,6 +162,35 @@ schedule_position_scroll (GcalWeekView *self)
                                                 self);
 }
 
+/* GcalView implementation */
+static icaltimetype*
+gcal_week_view_get_date (GcalView *view)
+{
+  GcalWeekView *self = GCAL_WEEK_VIEW (view);
+
+  return self->date;
+}
+
+static void
+gcal_week_view_set_date (GcalView     *view,
+                         icaltimetype *date)
+{
+  GcalWeekView *self = GCAL_WEEK_VIEW (view);
+
+  GCAL_ENTRY;
+
+  g_clear_pointer (&self->date, g_free);
+  self->date = gcal_dup_icaltime (date);
+
+  /* Propagate the new date */
+  gcal_week_grid_set_date (GCAL_WEEK_GRID (self->week_grid), date);
+  gcal_week_header_set_date (GCAL_WEEK_HEADER (self->header), date);
+
+  schedule_position_scroll (self);
+
+  GCAL_EXIT;
+}
+
 static GList*
 gcal_week_view_get_children_by_uuid (GcalView    *view,
                                      const gchar *uuid)
@@ -186,6 +215,15 @@ gcal_week_view_clear_marks (GcalView *view)
 }
 
 static void
+gcal_view_interface_init (GcalViewInterface *iface)
+{
+  iface->get_date = gcal_week_view_get_date;
+  iface->set_date = gcal_week_view_set_date;
+  iface->get_children_by_uuid = gcal_week_view_get_children_by_uuid;
+  iface->clear_marks = gcal_week_view_clear_marks;
+}
+
+static void
 update_hours_sidebar_size (GcalWeekView *self)
 {
   GtkStyleContext *context;
@@ -239,6 +277,8 @@ update_hours_sidebar_size (GcalWeekView *self)
   g_object_unref (layout);
 }
 
+
+/* ECalDataModelSubscriber implementation */
 static void
 gcal_week_view_component_added (ECalDataModelSubscriber *subscriber,
                                 ECalClient              *client,
@@ -430,13 +470,6 @@ gcal_week_view_draw_hours (GcalWeekView *self,
 }
 
 static void
-gcal_view_interface_init (GcalViewInterface *iface)
-{
-  iface->get_children_by_uuid = gcal_week_view_get_children_by_uuid;
-  iface->clear_marks = gcal_week_view_clear_marks;
-}
-
-static void
 gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface)
 {
   iface->component_added = gcal_week_view_component_added;
@@ -465,18 +498,10 @@ gcal_week_view_set_property (GObject       *object,
                              const GValue  *value,
                              GParamSpec    *pspec)
 {
-  GcalWeekView *self;
-
-  self = GCAL_WEEK_VIEW (object);
-
   switch (property_id)
     {
     case PROP_DATE:
-      g_clear_pointer (&self->date, g_free);
-      self->date = g_value_dup_boxed (value);
-
-      schedule_position_scroll (self);
-
+      gcal_view_set_date (GCAL_VIEW (object), g_value_get_boxed (value));
       break;
 
     default:
diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c
index de5a2f3..68c6db3 100644
--- a/src/views/gcal-year-view.c
+++ b/src/views/gcal-year-view.c
@@ -19,6 +19,7 @@
 
 #define G_LOG_DOMAIN "GcalYearView"
 
+#include "gcal-debug.h"
 #include "gcal-year-view.h"
 #include "gcal-view.h"
 #include "gcal-utils.h"
@@ -553,7 +554,7 @@ update_date (GcalYearView *year_view,
     needs_reset = TRUE;
 
   g_clear_pointer (&year_view->date, g_free);
-  year_view->date = new_date;
+  year_view->date = gcal_dup_icaltime (new_date);
 
   year_view->first_week_of_year = get_last_week_of_year_dmy (year_view->first_weekday,
                                                              1, G_DATE_JANUARY,  year_view->date->year);;
@@ -1541,6 +1542,62 @@ navigator_drag_leave_cb (GcalYearView   *self,
   gtk_widget_queue_draw (navigator);
 }
 
+/* GcalView implementation */
+static icaltimetype*
+gcal_year_view_get_date (GcalView *view)
+{
+  GcalYearView *self = GCAL_YEAR_VIEW (view);
+
+  return self->date;
+}
+
+static void
+gcal_year_view_set_date (GcalView     *view,
+                         icaltimetype *date)
+{
+  GCAL_ENTRY;
+
+  update_date (GCAL_YEAR_VIEW (view), date);
+
+  GCAL_EXIT;
+}
+
+static GList*
+gcal_year_view_get_children_by_uuid (GcalView    *view,
+                                     const gchar *uuid)
+{
+  GcalYearView *year_view = GCAL_YEAR_VIEW (view);
+  GList *children, *l, *result = NULL;
+
+  children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar));
+
+  for (l = children; l != NULL; l = g_list_next (l))
+    {
+      GcalEventWidget *child_widget;
+      GcalEvent *event;
+
+      child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
+      event = gcal_event_widget_get_event (child_widget);
+
+
+      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
+        result = g_list_append (result, child_widget);
+    }
+
+  g_list_free (children);
+
+  return result;
+}
+
+static void
+gcal_view_interface_init (GcalViewInterface *iface)
+{
+  /* FIXME: implement what's needed */
+  iface->get_date = gcal_year_view_get_date;
+  iface->set_date = gcal_year_view_set_date;
+  iface->get_children_by_uuid = gcal_year_view_get_children_by_uuid;
+}
+
 static void
 gcal_year_view_finalize (GObject *object)
 {
@@ -1597,7 +1654,7 @@ gcal_year_view_set_property (GObject      *object,
   switch (prop_id)
     {
     case PROP_DATE:
-      update_date (self, g_value_dup_boxed (value));
+      gcal_view_set_date (GCAL_VIEW (self), g_value_get_boxed (value));
       break;
 
     case PROP_SHOW_WEEK_NUMBERS:
@@ -1716,31 +1773,6 @@ gcal_year_view_direction_changed (GtkWidget        *widget,
     year_view->k = 1;
 }
 
-static GList*
-gcal_year_view_get_children_by_uuid (GcalView    *view,
-                                     const gchar *uuid)
-{
-  GcalYearView *year_view = GCAL_YEAR_VIEW (view);
-  GList *children, *l, *result = NULL;
-
-  children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar));
-  for (l = children; l != NULL; l = g_list_next (l))
-    {
-      GcalEventWidget *child_widget;
-      GcalEvent *event;
-
-      child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
-      event = gcal_event_widget_get_event (child_widget);
-
-
-      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
-        result = g_list_append (result, child_widget);
-    }
-  g_list_free (children);
-
-  return result;
-}
-
 static void
 gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
                                 ECalClient              *client,
@@ -1780,7 +1812,6 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
   for (i = start_month; i <= end_month; i++)
     g_ptr_array_add (self->events[i], event);
 
-  update_selected_dates_from_button_data (self);
   update_sidebar (self);
 
   gtk_widget_queue_draw (GTK_WIDGET (self->navigator));
@@ -1986,13 +2017,6 @@ gcal_year_view_init (GcalYearView *self)
 }
 
 static void
-gcal_view_interface_init (GcalViewInterface *iface)
-{
-  /* FIXME: implement what's needed */
-  iface->get_children_by_uuid = gcal_year_view_get_children_by_uuid;
-}
-
-static void
 gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface)
 {
   iface->component_added = gcal_year_view_component_added;


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