[gnome-calendar/gnome-3-24] view: rework active-date



commit 40993b13ac9407fd6ca9a0f95f242f405b4c3a12
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              |   52 +++++----------
 src/gcal-view.h              |    7 +-
 src/gcal-window.c            |  148 +++++++++++++++++++----------------------
 src/views/gcal-month-view.c  |   94 ++++++++++-----------------
 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   |   99 ++++++++++------------------
 src/views/gcal-year-view.c   |   94 +++++++++++++++++----------
 11 files changed, 270 insertions(+), 381 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 7ad4005..037bc05 100644
--- a/src/gcal-view.c
+++ b/src/gcal-view.c
@@ -75,58 +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);
-}
-
-icaltimetype*
-gcal_view_get_date (GcalView *view)
-{
-  icaltimetype *date;
-
-  g_return_val_if_fail (GCAL_IS_VIEW (view), NULL);
-
-  g_object_get (view, "active-date", &date, NULL);
-  return date;
-}
-
-/**
- * gcal_view_get_initial_date:
- * @view: a #GcalView
- *
- * Return the initial date represented by the view.
- *
- * Returns: (transfer full): An #icaltimetype object
- **/
-icaltimetype*
-gcal_view_get_initial_date (GcalView *view)
-{
-  g_return_val_if_fail (GCAL_IS_VIEW (view), NULL);
-  g_return_val_if_fail (GCAL_VIEW_GET_IFACE (view)->get_initial_date, NULL);
-
-  return GCAL_VIEW_GET_IFACE (view)->get_initial_date (view);
+  GCAL_VIEW_GET_IFACE (view)->set_date (view, date);
 }
 
 /**
- * gcal_view_get_final_date:
+ * gcal_view_get_date:
  * @view: a #GcalView
  *
- * Return the final date represented by the view.
+ * Retrieves the date of @view.
  *
- * Returns: (transfer full): An #icaltimetype object
- **/
+ * Returns: (transfer none): an #icaltimetype.
+ */
 icaltimetype*
-gcal_view_get_final_date (GcalView *view)
+gcal_view_get_date (GcalView *view)
 {
   g_return_val_if_fail (GCAL_IS_VIEW (view), NULL);
-  g_return_val_if_fail (GCAL_VIEW_GET_IFACE (view)->get_final_date, NULL);
+  g_return_val_if_fail (GCAL_VIEW_GET_IFACE (view)->get_date, NULL);
 
-  return GCAL_VIEW_GET_IFACE (view)->get_final_date (view);
+  return GCAL_VIEW_GET_IFACE (view)->get_date (view);
 }
 
 /**
diff --git a/src/gcal-view.h b/src/gcal-view.h
index 3c4ec90..042bce4 100644
--- a/src/gcal-view.h
+++ b/src/gcal-view.h
@@ -42,9 +42,10 @@ struct _GcalViewInterface
                                                         icaltimetype *start_span,
                                                         icaltimetype *end_span);
 
-  /* Time handling related API */
-  icaltimetype*  (*get_initial_date)                   (GcalView    *view);
-  icaltimetype*  (*get_final_date)                     (GcalView    *view);
+  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 066f742..963367a 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -226,7 +226,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)
@@ -1193,82 +1196,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);
@@ -1338,6 +1265,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);
@@ -1445,7 +1385,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;
@@ -1481,7 +1420,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 (
@@ -1555,6 +1493,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,
@@ -1567,6 +1511,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 b524fc0..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"
@@ -915,52 +916,39 @@ add_new_event_button_cb (GtkWidget *button,
 
 /* GcalView Interface API */
 static icaltimetype*
-gcal_month_view_get_initial_date (GcalView *view)
+gcal_month_view_get_date (GcalView *view)
 {
-  //FIXME to retrieve the 35 days range
-  GcalMonthView *self;
-  icaltimetype *new_date;
-
-  g_return_val_if_fail (GCAL_IS_MONTH_VIEW (view), NULL);
-
-  self = GCAL_MONTH_VIEW (view);
+  GcalMonthView *self = GCAL_MONTH_VIEW (view);
 
-  new_date = gcal_dup_icaltime (self->date);
-  new_date->day = 1;
-  new_date->is_date = 0;
-  new_date->hour = 0;
-  new_date->minute = 0;
-  new_date->second = 0;
-
-  return new_date;
+  return self->date;
 }
 
-/**
- * gcal_month_view_get_final_date:
- *
- * Since: 0.1
- * Return value: the last day of the month
- * Returns: (transfer full): Release with g_free()
- **/
-static icaltimetype*
-gcal_month_view_get_final_date (GcalView *view)
+static void
+gcal_month_view_set_date (GcalView     *view,
+                          icaltimetype *date)
 {
-  //FIXME to retrieve the 35 days range
+  GcalSubscriberViewPrivate *ppriv;
   GcalMonthView *self;
-  icaltimetype *new_date;
 
-  g_return_val_if_fail (GCAL_IS_MONTH_VIEW (view), NULL);
+  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);
 
-  new_date = gcal_dup_icaltime (self->date);
-  new_date->day = icaltime_days_in_month (self->date->month, self->date->year);
-  new_date->is_date = 0;
-  new_date->hour = 23;
-  new_date->minute = 59;
-  new_date->second = 59;
+  GCAL_TRACE_MSG ("new date: %s", icaltime_as_ical_string (*date));
+
+  cancel_selection (self);
 
-  return new_date;
+  ppriv->children_changed = TRUE;
+  gtk_widget_queue_resize (GTK_WIDGET (view));
+
+  GCAL_EXIT;
 }
 
 static void
@@ -988,11 +976,9 @@ gcal_month_view_get_children_by_uuid (GcalView    *view,
 static void
 gcal_view_interface_init (GcalViewInterface *iface)
 {
-  iface->get_initial_date = gcal_month_view_get_initial_date;
-  iface->get_final_date = gcal_month_view_get_final_date;
-
+  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;
 }
 
@@ -1002,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;
@@ -2116,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 c22a65f..f5f2480 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 92abc47..8d7fcb4 100644
--- a/src/views/gcal-week-view.c
+++ b/src/views/gcal-week-view.c
@@ -162,58 +162,33 @@ schedule_position_scroll (GcalWeekView *self)
                                                 self);
 }
 
-/**
- * gcal_week_view_get_initial_date:
- *
- * Since: 0.1
- * Return value: the first day of the week
- * Returns: (transfer full): Release with g_free()
- **/
+/* GcalView implementation */
 static icaltimetype*
-gcal_week_view_get_initial_date (GcalView *view)
+gcal_week_view_get_date (GcalView *view)
 {
-  GcalWeekView *self;
-  icaltimetype *new_date;
-
-  g_return_val_if_fail (GCAL_IS_WEEK_VIEW (view), NULL);
-  self = GCAL_WEEK_VIEW(view);
-  new_date = g_new0 (icaltimetype, 1);
-  *new_date = icaltime_from_day_of_year (icaltime_start_doy_week (*(self->date),
-                                                                  self->first_weekday + 1),
-                                         self->date->year);
-  new_date->is_date = 0;
-  new_date->hour = 0;
-  new_date->minute = 0;
-  new_date->second = 0;
-  *new_date = icaltime_set_timezone (new_date, self->date->zone);
-  return new_date;
+  GcalWeekView *self = GCAL_WEEK_VIEW (view);
+
+  return self->date;
 }
 
-/**
- * gcal_week_view_get_final_date:
- *
- * Since: 0.1
- * Return value: the last day of the week
- * Returns: (transfer full): Release with g_free()
- **/
-static icaltimetype*
-gcal_week_view_get_final_date (GcalView *view)
+static void
+gcal_week_view_set_date (GcalView     *view,
+                         icaltimetype *date)
 {
-  GcalWeekView *self;
-  icaltimetype *new_date;
-
-  g_return_val_if_fail (GCAL_IS_WEEK_VIEW (view), NULL);
-  self = GCAL_WEEK_VIEW(view);
-  new_date = g_new0 (icaltimetype, 1);
-  *new_date = icaltime_from_day_of_year (icaltime_start_doy_week (*(self->date),
-                                                                  self->first_weekday + 1) + 6,
-                                         self->date->year);
-  new_date->is_date = 0;
-  new_date->hour = 23;
-  new_date->minute = 59;
-  new_date->second = 0;
-  *new_date = icaltime_set_timezone (new_date, self->date->zone);
-  return new_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*
@@ -240,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;
@@ -293,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,
@@ -484,15 +470,6 @@ gcal_week_view_draw_hours (GcalWeekView *self,
 }
 
 static void
-gcal_view_interface_init (GcalViewInterface *iface)
-{
-  iface->get_initial_date = gcal_week_view_get_initial_date;
-  iface->get_final_date = gcal_week_view_get_final_date;
-  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;
@@ -521,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]