[gnome-calendar/wip/pandusonu/week-view: 49/60] week-header: start moving to use another event storage



commit 6e318f346338cb2009d5e79b8b41da83b872a4fb
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Nov 3 14:05:18 2016 -0200

    week-header: start moving to use another event storage
    
    Instead of using a single, giant GList to store all the available
    events, use an array of sorted GLists.
    
    This commit adds temporary debug messages, beware the huge output.

 src/views/gcal-week-header.c |  604 +++++++++++++++++++++++++++---------------
 src/views/gcal-week-header.h |    2 +-
 2 files changed, 386 insertions(+), 220 deletions(-)
---
diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c
index 31998e0..990b369 100644
--- a/src/views/gcal-week-header.c
+++ b/src/views/gcal-week-header.c
@@ -54,7 +54,7 @@ struct _GcalWeekHeader
    * The list will later be iterated after the active date is changed
    * and the events will be placed
    */
-  GList            *events;
+  GList            *events[7];
 
   gint              first_weekday;
 
@@ -72,17 +72,8 @@ struct _GcalWeekHeader
   GtkSizeGroup     *sizegroup;
 };
 
-static GDateTime*     get_start_of_week                     (GcalWeekHeader *self);
-
-static gint           events_compare_func                   (GcalEvent *first,
-                                                             GcalEvent *second);
-
 static void           update_headers                        (GcalWeekHeader *self);
 
-static void           place_events                          (GcalWeekHeader *self);
-
-static void           clear_current_events                  (GcalWeekHeader *self);
-
 static void           header_collapse                       (GcalWeekHeader *self);
 
 static void           header_expand                         (GcalWeekHeader *self);
@@ -118,239 +109,371 @@ enum
 G_DEFINE_TYPE (GcalWeekHeader, gcal_week_header, GTK_TYPE_GRID);
 
 static GDateTime*
-get_start_of_week (GcalWeekHeader *self)
+get_start_of_week (icaltimetype *date)
 {
   icaltimetype *new_date;
 
-  g_return_val_if_fail (GCAL_IS_WEEK_HEADER (self), NULL);
   new_date = g_new0 (icaltimetype, 1);
-  *new_date = icaltime_from_day_of_year (icaltime_start_doy_week (*(self->active_date),
-                                                                  self->first_weekday + 1),
-                                                                  self->active_date->year);
+  *new_date = icaltime_from_day_of_year (icaltime_start_doy_week (*(date), get_first_weekday () + 1),
+                                         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->active_date->zone);
+  *new_date = icaltime_set_timezone (new_date, date->zone);
 
   return icaltime_to_datetime (new_date);
 }
 
+static GDateTime*
+get_end_of_week (icaltimetype *date)
+{
+  GDateTime *week_start, *week_end;
+
+  week_start = get_start_of_week (date);
+  week_end = g_date_time_add_days (week_start, 7);
+
+  g_clear_pointer (&week_start, g_date_time_unref);
+
+  return week_end;
+}
+
 static gint
-events_compare_func (GcalEvent *first,
-                     GcalEvent *second)
+get_event_start_weekday (GcalWeekHeader *self,
+                         GcalEvent      *event)
 {
-  gint retval;
+  GDateTime *week_start, *event_start;
+  gint start_weekday;
+
+  week_start = get_start_of_week (self->current_date);
+  event_start = gcal_event_get_date_start (event);
 
+  g_message ("current week start: %s", g_date_time_format (week_start, "%x %X"));
+
+  /* Only calculate the start day if it starts in the current week */
+  if (g_date_time_compare (event_start, week_start) >= 0)
+    start_weekday = (g_date_time_get_day_of_week (event_start) - get_first_weekday ()) % 7;
+  else
+    start_weekday = 0;
+
+  g_clear_pointer (&week_start, g_date_time_unref);
+
+  return start_weekday;
+}
+
+static gint
+compare_events_by_length (GcalEvent *event1,
+                          GcalEvent *event2)
+{
   /* Multiday events should come before single day events */
-  if (gcal_event_is_multiday (first) != gcal_event_is_multiday (second))
-    return gcal_event_is_multiday (second) - gcal_event_is_multiday (first);
+  if (gcal_event_is_multiday (event1) != gcal_event_is_multiday (event2))
+    return gcal_event_is_multiday (event2) - gcal_event_is_multiday (event1);
 
   /* Compare with respect to start day */
-  retval = g_date_time_compare (gcal_event_get_date_start (first),
-                                gcal_event_get_date_start (second));
+  return gcal_event_compare (event1, event2);
+}
 
-  if (retval != 0)
-    return retval;
+static void
+add_event_to_weekday (GcalWeekHeader *self,
+                      GcalEvent      *event,
+                      gint            weekday)
+{
+  GList *l;
 
-  /* Compare with respect to end day effectively comparing with respect to duration */
-  return g_date_time_compare (gcal_event_get_date_end (second), gcal_event_get_date_end (first));
+  l = self->events[weekday];
+  l = g_list_insert_sorted (l, event, (GCompareFunc) compare_events_by_length);
+
+  self->events[weekday] = l;
 }
 
 static void
-update_headers (GcalWeekHeader *self)
+move_events_at_column (GcalWeekHeader *self,
+                       gint            column,
+                       gint            start_at,
+                       gint            n_events)
 {
-  GDateTime *week_start, *week_end;
-  gchar *year_label, *month_label, *week_label;
+  GList *found_widgets, *l;
+  gint counter;
+  gint i;
 
-  if(!self->active_date)
+  if (n_events == 0)
     return;
 
-  week_start = get_start_of_week (self);
-  week_end = g_date_time_add_days (week_start, 6);
+  found_widgets = NULL;
+  counter = 0;
+  i = start_at;
 
-  if (g_date_time_get_month (week_start) == g_date_time_get_month (week_end))
-    {
-      month_label = g_strdup_printf ("%s ", gcal_get_month_name (g_date_time_get_month (week_start) - 1));
-    }
-  else
-    {
-      month_label = g_strdup_printf("%s - %s ",
-                                    gcal_get_month_name (g_date_time_get_month (week_start) -1),
-                                    gcal_get_month_name (g_date_time_get_month (week_end) - 1));
-    }
+  g_message ("  -  -  moving %d events below %d from column %d",
+             n_events, column, n_events);
 
-  if (g_date_time_get_year (week_start) == g_date_time_get_year (week_end))
+  /* First, lets find the widgets at this column */
+  do
     {
-      week_label = g_strdup_printf ("week %d", g_date_time_get_week_of_year (week_start));
-      year_label = g_strdup_printf ("%d", g_date_time_get_year (week_start));
+      GtkWidget *widget_at_y;
+
+      /*
+       * The first element is the column is always a placeholder GtkBox,
+       * which we disconsider by starting the counter at 1.
+       */
+      widget_at_y = gtk_grid_get_child_at (GTK_GRID (self->grid), column, i);
+
+      /* Move the events to below */
+      if (widget_at_y)
+        {
+          found_widgets = g_list_prepend (found_widgets, widget_at_y);
+          counter++;
+          g_message ("  -  -  -  found an event widget (%d)", counter);
+        }
+
+      i++;
     }
-  else
+  while (counter < n_events);
+
+  /*
+   * Now the we discovered all the widgets at that column,
+   * move them below, one by one.
+   */
+  for (l = found_widgets; l != NULL; l = l->next)
     {
-      week_label = g_strdup_printf ("week %d/%d",
-                                    g_date_time_get_week_of_year (week_start),
-                                    g_date_time_get_week_of_year (week_end));
-      year_label = g_strdup_printf ("%d-%d",
-                                    g_date_time_get_year (week_start),
-                                    g_date_time_get_year (week_end));
-    }
+      gint top_attach;
 
-  gtk_label_set_label (GTK_LABEL (self->month_label), month_label);
-  gtk_label_set_label (GTK_LABEL (self->week_label), week_label);
-  gtk_label_set_label (GTK_LABEL (self->year_label), year_label);
+      /* Get the widget's current position... */
+      gtk_container_child_get (GTK_CONTAINER (self->grid),
+                               l->data,
+                               "top_attach", &top_attach,
+                               NULL);
 
-  g_clear_pointer (&week_start, g_date_time_unref);
-  g_clear_pointer (&week_end, g_date_time_unref);
-  g_clear_pointer (&month_label, g_free);
-  g_clear_pointer (&week_label, g_free);
-  g_clear_pointer (&year_label, g_free);
+      g_message ("  -  -  -  setting top_attach to %d", top_attach + 1);
+
+      /* And move it to position + 1 */
+      gtk_container_child_set (GTK_CONTAINER (self->grid),
+                               l->data,
+                               "top_attach", top_attach + 1,
+                               NULL);
+    }
+
+  g_clear_pointer (&found_widgets, g_list_free);
 }
 
 static void
-place_events (GcalWeekHeader *self)
+add_event_to_grid (GcalWeekHeader *self,
+                   GcalEvent      *event,
+                   gint            start,
+                   gint            end)
 {
-  GList *l, *iter;
-  GDateTime *week_start, *week_end;
+  GDateTime *widget_start_dt, *widget_end_dt;
+  GtkWidget *widget;
+  gint events_at_weekday;
+  gint position;
   gint i;
-  gint hidden_events[7];
 
-  if (!self->active_date)
-    return;
+  g_message ("  -  adding %s event", gcal_event_is_multiday (event) ? "multiday" : "single day");
 
-  week_start = get_start_of_week (self);
-  week_end = g_date_time_add_days (week_start, 6);
-  iter = g_list_copy (self->events);
+  events_at_weekday = g_list_length (self->events[start]);
 
-  for (i = 0; i < 7; i++)
-    hidden_events[i] = 0;
+  /* Add at least at the first weekday */
+  add_event_to_weekday (self, event, start);
 
-  iter = g_list_sort (iter, (GCompareFunc) events_compare_func);
+  position = g_list_index (self->events[start], event) + 1;
 
-  for (l = iter; l != NULL; l = l->next)
+  /*
+   * This event is not visible until the header is expanded, so it
+   * only goes to the overlow list.
+   */
+  if (position > 3 && !self->expanded)
     {
-      GcalEvent *event;
-      GtkWidget *widget;
-      GDateTime *event_start, *event_end;
-      gint start, end;
-      gboolean placed;
+      /* TODO: hide the last event, and show the "Other Events" label */
+      return;
+    }
 
-      start = -1;
-      end = -1;
-      placed = FALSE;
-      event = GCAL_EVENT (l->data);
-      widget = gcal_event_widget_new (event);
-      event_start = gcal_event_get_date_start (event);
-      event_end = gcal_event_get_date_end (event);
+  g_message ("  -  -  adding event to column %d", start);
+  g_message ("  -  -  -  there are %d events in this column", events_at_weekday);
 
-      gtk_widget_set_visible (widget, TRUE);
+  move_events_at_column (self, start, position, events_at_weekday - position + 1);
 
-      for (i = 0; i < 7; i++)
-        {
-          GDateTime *day_start, *day_end;
+  /* Add the event to the grid */
+  widget = gcal_event_widget_new (event);
+  gtk_widget_set_margin_end (widget, end == 6 ? 0 : 6);
 
-          day_start = g_date_time_add_days (week_start, i);
-          day_end = g_date_time_add_days (day_start, 1);
+  gtk_grid_attach (GTK_GRID (self->grid),
+                   widget,
+                   start,
+                   position,
+                   1,
+                   1);
 
-          /* Checks if the event is present on the i-th day of the week */
-          if ((g_date_time_compare (event_start, day_start) < 0 && g_date_time_compare (event_end, day_end) 
= 0) ||
-              (g_date_time_compare (event_start, day_start) >= 0 && g_date_time_compare (event_end, day_end) 
< 0) ||
-              (g_date_time_compare (event_start, day_start) >= 0 && g_date_time_compare (event_start, 
day_end) < 0) ||
-              (g_date_time_compare (event_end, day_start) > 0 && g_date_time_compare (event_end, day_end) < 
0))
-            {
-              if (start == -1)
-                start = i;
+  gtk_widget_show (widget);
 
-              end = i;
-            }
-        }
+  /* Single-day events are the simplest case, and the code above is enough to deal with them */
+  if (!gcal_event_is_multiday (event))
+    return;
 
-      self->events = g_list_remove_all (self->events, l->data);
+  /* Setup the event's start date */
+  widget_start_dt = get_start_of_week (self->active_date);
+  widget_end_dt = g_date_time_add_days (widget_start_dt, 1);
 
-      if (start == -1)
-        continue;
+  gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (widget), widget_start_dt);
+  gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget), widget_end_dt);
 
-      for (i = 1 ; ; i++)
-        {
-          gint j;
-          gboolean present;
+  g_clear_pointer (&widget_start_dt, g_date_time_unref);
 
-          if (!(self->expanded) && i >=4)
-            break;
+  /*
+   * In addition to moving the current column's events below, multiday
+   * events must also move the events from ~all~ the columns it spans
+   * below
+   */
+  for (i = start + 1; i <= end; i++)
+    {
+      gint new_position;
 
-          present = FALSE;
+      events_at_weekday = g_list_length (self->events[i]);
 
-          /*
-           * Checks if the columns required for the event
-           * are free in the i-th row
-           */
-          for (j = start; j < end + 1; j++)
-            present = present || gtk_grid_get_child_at (GTK_GRID (self->grid), j, i);
+      /* Add the event to that day */
+      add_event_to_weekday (self, event, i);
 
-          if (!present)
-            {
-              gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (widget),
-                                                MAX (week_start, event_start));
-              gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget),
-                                              MIN(week_end, event_end));
-
-              gtk_grid_attach (GTK_GRID (self->grid), widget, start, i, end - start + 1, 1);
-              placed = TRUE;
-              break;
-            }
-        }
+      g_message ("  -  -  adding event to column %d", i);
+      g_message ("  -  -  -  there are %d events in this column", events_at_weekday);
+
+
+      /* Check the event position at this weekday */
+      new_position = g_list_index (self->events[i], event) + 1;
+
+      g_message ("  -  -  -  adding event to position %d", new_position);
 
-      if (!placed)
+      move_events_at_column (self, i, new_position, events_at_weekday - new_position + 1);
+
+      /* Add the event to the grid */
+      if (new_position == position)
         {
-          for (i = start; i <= end; i++)
-            hidden_events[i]++;
+          GDateTime *new_widget_end_dt;
+
+          new_widget_end_dt = g_date_time_add_days (widget_end_dt, 1);
+
+          /* Update the widget's end date */
+          gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget), new_widget_end_dt);
+
+          gtk_container_child_set (GTK_CONTAINER (self->grid),
+                                   widget,
+                                   "width", i - start + 1,
+                                   NULL);
 
-          self->events = g_list_append (self->events, event);
+          g_clear_pointer (&widget_end_dt, g_date_time_unref);
+          widget_end_dt = new_widget_end_dt;
+        }
+      else
+        {
+          /* TODO: clone the widget */
         }
     }
 
-    if (!(self->expanded))
-      {
-        gtk_grid_remove_row (GTK_GRID (self->grid), 4);
+  gtk_widget_show (widget);
+}
 
-        for (i = 0; i < 7; i++)
-          {
-            if (hidden_events[i])
-              {
-                GtkWidget *widget;
+static void
+update_events_for_date (GcalWeekHeader *self,
+                        icaltimetype   *old_icaldt,
+                        icaltimetype   *new_icaldt)
+{
+  GDateTime *old_week_start, *old_week_end;
+  GDateTime *new_week_start, *new_week_end;
+  GList *events_to_update, *l;
+  gint weekday;
 
-                widget = gtk_label_new (g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "Other event", "Other 
%d events", hidden_events[i]),
-                                                         hidden_events[i]));
+  events_to_update = NULL;
 
-                gtk_widget_set_visible (widget, TRUE);
-                gtk_grid_attach (GTK_GRID (self->grid), widget, i, 4, 1, 1);
-              }
-          }
-      }
+  old_week_start = get_start_of_week (old_icaldt);
+  old_week_end = get_end_of_week (old_icaldt);
+
+  new_week_start = get_start_of_week (new_icaldt);
+  new_week_end = get_end_of_week (new_icaldt);
+
+  for (weekday = 0; weekday < 7; weekday++)
+    {
+      GList *events;
+
+      events = self->events[weekday];
+
+      for (l = events; l != NULL; l = l->next)
+        {
+          GDateTime *event_start, *event_end;
+
+          event_start = gcal_event_get_date_start (l->data);
+          event_end = gcal_event_get_date_end (l->data);
 
-    g_list_free (iter);
+          /*
+           * Check if the event must be updated. Updatable events are events that
+           * started somewhere in the past, and are still present.
+           */
+          if (g_date_time_compare (event_start, old_week_end) < 0 &&
+              g_date_time_compare (event_end, new_week_start) > 0 &&
+              !g_list_find (events_to_update, l->data))
+            {
+              events_to_update = g_list_append (events_to_update, l->data);
+            }
+        }
+    }
+
+  for (l = events_to_update; l != NULL; l = l->next)
+    {
+      gcal_week_header_remove_event (self, gcal_event_get_uid (l->data));
+      gcal_week_header_add_event (self, l->data);
+    }
+
+  g_clear_pointer (&events_to_update, g_list_free);
+  g_clear_pointer (&new_week_start, g_date_time_unref);
+  g_clear_pointer (&old_week_start, g_date_time_unref);
+  g_clear_pointer (&new_week_end, g_date_time_unref);
+  g_clear_pointer (&old_week_end, g_date_time_unref);
 }
 
 static void
-clear_current_events (GcalWeekHeader *self)
+update_headers (GcalWeekHeader *self)
 {
-  GList *children, *l;
+  GDateTime *week_start, *week_end;
+  gchar *year_label, *month_label, *week_label;
 
-  children = g_list_copy (gtk_container_get_children (GTK_CONTAINER (self->grid)));
+  if(!self->active_date)
+    return;
 
-  for (l = children; l != NULL; l = l->next)
-    {
-      if (!GCAL_IS_EVENT_WIDGET (l->data))
-        continue;
+  week_start = get_start_of_week (self->active_date);
+  week_end = g_date_time_add_days (week_start, 6);
 
-      /* Add current events to events list to add later if necessary */
-      self->events = g_list_append (self->events,
-                                    gcal_event_widget_get_event (l->data));
+  if (g_date_time_get_month (week_start) == g_date_time_get_month (week_end))
+    {
+      month_label = g_strdup_printf ("%s ", gcal_get_month_name (g_date_time_get_month (week_start) - 1));
+    }
+  else
+    {
+      month_label = g_strdup_printf("%s - %s ",
+                                    gcal_get_month_name (g_date_time_get_month (week_start) -1),
+                                    gcal_get_month_name (g_date_time_get_month (week_end) - 1));
+    }
 
-      gtk_widget_destroy (l->data);
+  if (g_date_time_get_year (week_start) == g_date_time_get_year (week_end))
+    {
+      week_label = g_strdup_printf ("week %d", g_date_time_get_week_of_year (week_start));
+      year_label = g_strdup_printf ("%d", g_date_time_get_year (week_start));
     }
+  else
+    {
+      week_label = g_strdup_printf ("week %d/%d",
+                                    g_date_time_get_week_of_year (week_start),
+                                    g_date_time_get_week_of_year (week_end));
+      year_label = g_strdup_printf ("%d-%d",
+                                    g_date_time_get_year (week_start),
+                                    g_date_time_get_year (week_end));
+    }
+
+  gtk_label_set_label (GTK_LABEL (self->month_label), month_label);
+  gtk_label_set_label (GTK_LABEL (self->week_label), week_label);
+  gtk_label_set_label (GTK_LABEL (self->year_label), year_label);
 
-  g_list_free (children);
+  g_clear_pointer (&week_start, g_date_time_unref);
+  g_clear_pointer (&week_end, g_date_time_unref);
+  g_clear_pointer (&month_label, g_free);
+  g_clear_pointer (&week_label, g_free);
+  g_clear_pointer (&year_label, g_free);
 }
 
 static void
@@ -400,8 +523,6 @@ header_collapse (GcalWeekHeader *self)
 
             widget = GCAL_EVENT_WIDGET (gtk_grid_get_child_at (GTK_GRID (self->grid), i, row));
 
-            self->events = g_list_append (self->events, gcal_event_widget_get_event (widget));
-
             gtk_widget_destroy (GTK_WIDGET (widget));
           }
       }
@@ -440,7 +561,6 @@ header_expand (GcalWeekHeader *self)
   gtk_image_set_from_icon_name (GTK_IMAGE (self->expand_button_image), "go-up-symbolic", 4);
 
   gtk_grid_remove_row (GTK_GRID (self->grid), 4);
-  place_events (self);
 }
 
 static void
@@ -457,54 +577,12 @@ static void
 gcal_week_header_finalize (GObject *object)
 {
   GcalWeekHeader *self = GCAL_WEEK_HEADER (object);
+  gint i;
 
   g_clear_pointer (&self->current_date, g_free);
-  g_list_free (self->events);
-}
-
-void
-gcal_week_header_add_event (GcalWeekHeader *self,
-                            GcalEvent      *event)
-{
-  self->events = g_list_append (self->events, event);
-}
-
-void
-gcal_week_header_remove_event (GcalWeekHeader *self,
-                               gchar          *uuid)
-{
-  GList *children, *l, *iter;
-
-  children = gtk_container_get_children (GTK_CONTAINER (self->grid));
-
-  for (l = children; l != NULL; l = g_list_next (l))
-    {
-      GcalEventWidget *child_widget;
-      GcalEvent *event;
-
-      if (!GCAL_IS_EVENT_WIDGET(l->data))
-        continue;
 
-      child_widget = GCAL_EVENT_WIDGET (l->data);
-      event = gcal_event_widget_get_event (child_widget);
-
-      if(child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
-        gtk_widget_destroy (GTK_WIDGET (l->data));
-    }
-
-  iter = g_list_copy (self->events);
-
-  for (l = iter; l != NULL; l = g_list_next (l))
-    {
-      if (!GCAL_IS_EVENT (l->data))
-        continue;
-
-      if (l->data != NULL && g_strcmp0 (uuid, gcal_event_get_uid (l->data)) == 0)
-        self->events = g_list_remove_all (self->events, l->data);
-    }
-
-  g_list_free (children);
-  g_list_free (iter);
+  for (i = 0; i < 7; i++)
+    g_list_free (self->events[i]);
 }
 
 static void
@@ -533,19 +611,21 @@ gcal_week_header_set_property (GObject      *object,
                                GParamSpec   *pspec)
 {
   GcalWeekHeader *self = GCAL_WEEK_HEADER (object);
+  icaltimetype *old_date;
 
   switch (prop_id)
     {
     case PROP_ACTIVE_DATE:
-      g_clear_pointer (&self->active_date, g_free);
+      old_date = self->active_date;
       self->active_date = g_value_dup_boxed (value);
 
       update_headers (self);
-      clear_current_events (self);
-      place_events (self);
-
       gtk_widget_queue_draw (self->draw_area);
 
+      if (old_date)
+        update_events_for_date (self, old_date, self->active_date);
+
+      g_clear_pointer (&old_date, g_free);
       return;
 
     default:
@@ -613,7 +693,7 @@ gcal_week_header_draw (GcalWeekHeader *self,
   pango_font_description_set_weight (bold_font, PANGO_WEIGHT_MEDIUM);
   pango_layout_set_font_description (layout, bold_font);
 
-  week_start = get_start_of_week (self);
+  week_start = get_start_of_week (self->active_date);
   week_end = g_date_time_add_days (week_start, 6);
   current_cell = icaltime_day_of_week (*(self->active_date)) - 1;
   current_cell = (7 + current_cell - self->first_weekday) % 7;
@@ -775,6 +855,92 @@ gcal_week_header_set_use_24h_format (GcalWeekHeader *self,
 }
 
 void
+gcal_week_header_add_event (GcalWeekHeader *self,
+                            GcalEvent      *event)
+{
+  GDateTime *start_date, *end_date, *week_start, *week_end;
+  gint weekday;
+  gint width;
+
+  g_return_if_fail (GCAL_IS_WEEK_HEADER (self));
+
+  week_start = get_start_of_week (self->active_date);
+  week_end = get_end_of_week (self->active_date);
+  start_date = gcal_event_get_date_start (event);
+  end_date = gcal_event_get_date_end (event);
+  weekday = get_event_start_weekday (self, event);
+
+  /* Calculate the real width of this event */
+  width = ceil (g_date_time_difference (end_date, start_date) / G_TIME_SPAN_DAY);
+
+  if (g_date_time_compare (start_date, week_start) < 0)
+    width -= ceil (g_date_time_difference (week_start, start_date) / G_TIME_SPAN_DAY);
+
+  if (g_date_time_compare (week_end, end_date) < 0)
+    width -= ceil (g_date_time_difference (end_date, week_end) / G_TIME_SPAN_DAY);
+
+  g_message ("ADD: '%s' (pos: %d, width: %d)", gcal_event_get_summary (event), weekday, width);
+
+  add_event_to_grid (self, event, weekday, weekday + width - 1);
+
+  g_clear_pointer (&week_end, g_date_time_unref);
+  g_clear_pointer (&week_start, g_date_time_unref);
+}
+
+void
+gcal_week_header_remove_event (GcalWeekHeader *self,
+                               const gchar    *uuid)
+{
+  GcalEvent *removed_event;
+  GList *children, *l;
+  gint weekday;
+
+  g_return_if_fail (GCAL_IS_WEEK_HEADER (self));
+
+  children = gtk_container_get_children (GTK_CONTAINER (self->grid));
+  removed_event = NULL;
+
+  for (l = children; l != NULL; l = l->next)
+    {
+      GcalEventWidget *child_widget;
+      GcalEvent *event;
+
+      if (!GCAL_IS_EVENT_WIDGET (l->data))
+        continue;
+
+      child_widget = GCAL_EVENT_WIDGET (l->data);
+      event = gcal_event_widget_get_event (child_widget);
+
+      if (g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
+        {
+          removed_event = g_object_ref (event);
+          gtk_widget_destroy (l->data);
+        }
+    }
+
+  if (!removed_event)
+    goto out;
+
+  /* Remove from the weekday's GList */
+  for (weekday = 0; weekday < 7; weekday++)
+    {
+      l = self->events[weekday];
+      l = g_list_remove (l, removed_event);
+
+      self->events[weekday] = l;
+    }
+
+  g_message ("DEL: '%s' (length of %d: %d)",
+             gcal_event_get_summary (removed_event),
+             weekday,
+             g_list_length (l));
+
+out:
+  g_clear_pointer (&children, g_list_free);
+  g_clear_object (&removed_event);
+}
+
+void
 gcal_week_header_set_current_date (GcalWeekHeader *self,
                                    icaltimetype   *current_date)
 {
@@ -783,9 +949,9 @@ gcal_week_header_set_current_date (GcalWeekHeader *self,
   g_clear_pointer (&self->current_date, g_free);
   self->current_date = gcal_dup_icaltime (current_date);
 
+  g_message ("-----");
+
   update_headers (self);
-  clear_current_events (self);
-  place_events (self);
 
   gtk_widget_queue_draw (self->draw_area);
 }
diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h
index 00d16ed..732d112 100644
--- a/src/views/gcal-week-header.h
+++ b/src/views/gcal-week-header.h
@@ -47,7 +47,7 @@ void                 gcal_week_header_add_event                  (GcalWeekHeader
                                                                   GcalEvent          *event);
 
 void                 gcal_week_header_remove_event               (GcalWeekHeader     *self,
-                                                                  gchar              *uuid);
+                                                                  const gchar        *uuid);
 
 GtkSizeGroup*        gcal_week_header_get_sidebar_size_group     (GcalWeekHeader     *self);
 


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