[gnome-calendar/wip/gbsneto/gcal-event: 3/13] event-widget: use GcalEvent internally



commit 0ec0ea81217402c1d40ba968fd945b14cf390643
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sun Feb 7 12:52:18 2016 -0200

    event-widget: use GcalEvent internally
    
    This saves a lot of code, and is much saner to maintain.

 data/ui/window.ui          |    2 +-
 src/gcal-edit-dialog.c     |   15 +-
 src/gcal-edit-dialog.h     |    5 +-
 src/gcal-event-widget.c    |  871 +++++++++++++++++---------------------------
 src/gcal-event-widget.h    |   50 +--
 src/gcal-manager.c         |   22 +-
 src/gcal-month-view.c      |  123 ++++---
 src/gcal-subscriber-view.c |   46 ++--
 src/gcal-utils.c           |   37 ++-
 src/gcal-utils.h           |    3 +
 src/gcal-week-view.c       |   27 +-
 src/gcal-window.c          |   49 +--
 src/gcal-year-view.c       |  142 +++++---
 13 files changed, 625 insertions(+), 767 deletions(-)
---
diff --git a/data/ui/window.ui b/data/ui/window.ui
index 27f0bf7..86705f8 100644
--- a/data/ui/window.ui
+++ b/data/ui/window.ui
@@ -392,7 +392,7 @@
                 <property name="can_focus">True</property>
                 <property name="hexpand">True</property>
                 <signal name="activate" handler="create_event" object="GcalWindow" swapped="yes"/>
-                <signal name="notify::text" handler="new_event_entry_text_changed" object="GcalWindow" 
swapped="yes"/>
+                <signal name="notify::text" handler="new_event_entry_text_changed" object="GcalWindow" 
swapped="no"/>
               </object>
               <packing>
                 <property name="left_attach">0</property>
diff --git a/src/gcal-edit-dialog.c b/src/gcal-edit-dialog.c
index 6a9a880..f711bec 100644
--- a/src/gcal-edit-dialog.c
+++ b/src/gcal-edit-dialog.c
@@ -793,12 +793,12 @@ gcal_edit_dialog_set_event_is_new (GcalEditDialog *dialog,
 }
 
 void
-gcal_edit_dialog_set_event_data (GcalEditDialog *dialog,
-                                 GcalEventData  *data)
+gcal_edit_dialog_set_event (GcalEditDialog *dialog,
+                            GcalEvent      *event)
 {
-
   GdkRGBA color;
   GdkPixbuf *pix;
+  ESource *source;
 
   const gchar *const_text = NULL;
   gboolean all_day;
@@ -810,13 +810,14 @@ gcal_edit_dialog_set_event_data (GcalEditDialog *dialog,
   ECalComponentDateTime dtend;
 
   all_day = FALSE;
+  source = gcal_event_get_source (event);
 
   dialog->setting_event = TRUE;
 
-  g_set_object (&dialog->source, data->source);
+  g_set_object (&dialog->source, source);
 
   g_clear_object (&dialog->component);
-  dialog->component = e_cal_component_clone (data->event_component);
+  dialog->component = e_cal_component_clone (gcal_event_get_component (event));
 
   g_clear_pointer (&dialog->source_uid, g_free);
   dialog->source_uid = e_source_dup_uid (dialog->source);
@@ -850,14 +851,14 @@ gcal_edit_dialog_set_event_data (GcalEditDialog *dialog,
     gtk_entry_set_text (GTK_ENTRY (dialog->summary_entry), e_summary.value);
 
   /* dialog titlebar's title & subtitle */
-  get_color_name_from_source (data->source, &color);
+  get_color_name_from_source (source, &color);
 
   pix = gcal_get_pixbuf_from_color (&color, 16);
   gtk_image_set_from_pixbuf (GTK_IMAGE (dialog->source_image), pix);
   g_object_unref (pix);
 
   gtk_header_bar_set_subtitle (GTK_HEADER_BAR (dialog->titlebar),
-                               e_source_get_display_name (data->source));
+                               e_source_get_display_name (source));
 
   /* retrieve start and end dates */
   e_cal_component_get_dtstart (dialog->component, &dtstart);
diff --git a/src/gcal-edit-dialog.h b/src/gcal-edit-dialog.h
index fe7abf5..60d9249 100644
--- a/src/gcal-edit-dialog.h
+++ b/src/gcal-edit-dialog.h
@@ -20,6 +20,7 @@
 #ifndef __GCAL_EDIT_DIALOG_H__
 #define __GCAL_EDIT_DIALOG_H__
 
+#include "gcal-event.h"
 #include "gcal-manager.h"
 
 #include <gtk/gtk.h>
@@ -39,8 +40,8 @@ GtkWidget*           gcal_edit_dialog_new                     (gboolean format_2
 void                 gcal_edit_dialog_set_event_is_new        (GcalEditDialog *dialog,
                                                                gboolean       event_is_new);
 
-void                 gcal_edit_dialog_set_event_data          (GcalEditDialog *dialog,
-                                                               GcalEventData  *data);
+void                 gcal_edit_dialog_set_event               (GcalEditDialog *dialog,
+                                                               GcalEvent      *event);
 
 void                 gcal_edit_dialog_set_manager             (GcalEditDialog *dialog,
                                                                GcalManager    *manager);
diff --git a/src/gcal-event-widget.c b/src/gcal-event-widget.c
index bce9fef..251046f 100644
--- a/src/gcal-event-widget.c
+++ b/src/gcal-event-widget.c
@@ -20,28 +20,21 @@
 #include "gcal-event-widget.h"
 #include "gcal-utils.h"
 
-#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
+#define INTENSITY(c) ((c->red) * 0.30 + (c->green) * 0.59 + (c->blue) * 0.11)
 
 struct _GcalEventWidget
 {
   GtkWidget      parent;
 
   /* properties */
-  gchar         *uuid;
-  gchar         *summary;
-  GdkRGBA       *color;
-  icaltimetype  *dt_start;
-  icaltimetype  *dt_end; /* could be NULL, meaning dt_end is the same as start_date */
-  gboolean       all_day;
+  GDateTime     *dt_start;
+  GDateTime     *dt_end;
   gboolean       has_reminders;
 
   /* internal data */
   gboolean       read_only;
 
-  /* weak ESource reference */
-  ESource       *source;
-  /* ECalComponent data */
-  ECalComponent *component;
+  GcalEvent     *event;
 
   GdkWindow     *event_window;
   gboolean       button_pressed;
@@ -50,12 +43,9 @@ struct _GcalEventWidget
 enum
 {
   PROP_0,
-  PROP_UUID,
-  PROP_SUMMARY,
-  PROP_COLOR,
-  PROP_DTSTART,
-  PROP_DTEND,
-  PROP_ALL_DAY,
+  PROP_DATE_END,
+  PROP_DATE_START,
+  PROP_EVENT,
   PROP_HAS_REMINDERS
 };
 
@@ -67,144 +57,110 @@ enum
 
 static guint signals[NUM_SIGNALS] = { 0, };
 
-static void     gcal_event_widget_set_property         (GObject        *object,
-                                                        guint           property_id,
-                                                        const GValue   *value,
-                                                        GParamSpec     *pspec);
-
-static void     gcal_event_widget_get_property         (GObject        *object,
-                                                        guint           property_id,
-                                                        GValue         *value,
-                                                        GParamSpec     *pspec);
-
-static void     gcal_event_widget_finalize             (GObject        *object);
-
-static void     gcal_event_widget_get_preferred_width  (GtkWidget      *widget,
-                                                        gint           *minimum,
-                                                        gint           *natural);
-
-static void     gcal_event_widget_get_preferred_height (GtkWidget      *widget,
-                                                        gint           *minimum,
-                                                        gint           *natural);
-
-static void     gcal_event_widget_realize              (GtkWidget      *widget);
-
-static void     gcal_event_widget_unrealize            (GtkWidget      *widget);
+G_DEFINE_TYPE (GcalEventWidget, gcal_event_widget, GTK_TYPE_WIDGET)
 
-static void     gcal_event_widget_map                  (GtkWidget      *widget);
+static void
+gcal_event_widget_update_style (GcalEventWidget *self)
+{
+  GtkStyleContext *context;
+  gboolean slanted_start, slanted_end;
 
-static void     gcal_event_widget_unmap                (GtkWidget      *widget);
+  context = gtk_widget_get_style_context (GTK_WIDGET (self));
+  slanted_start = FALSE;
+  slanted_end = FALSE;
 
-static void     gcal_event_widget_size_allocate        (GtkWidget      *widget,
-                                                        GtkAllocation  *allocation);
+  /* Clear previous style classes */
+  gtk_style_context_remove_class (context, "slanted");
+  gtk_style_context_remove_class (context, "slanted-start");
+  gtk_style_context_remove_class (context, "slanted-end");
 
-static gboolean gcal_event_widget_draw                 (GtkWidget      *widget,
-                                                        cairo_t        *cr);
+  /*
+   * If the event's dates differs from the widget's dates,
+   * add a slanted edge class at the widget.
+   */
 
-static gboolean gcal_event_widget_button_press_event   (GtkWidget      *widget,
-                                                        GdkEventButton *event);
+  if (self->dt_start)
+    slanted_start = g_date_time_compare (gcal_event_get_date_start (self->event), self->dt_start) != 0;
 
-static gboolean gcal_event_widget_button_release_event (GtkWidget      *widget,
-                                                        GdkEventButton *event);
+  if (self->dt_end)
+    slanted_end = g_date_time_compare (gcal_event_get_date_end (self->event), self->dt_end) != 0;
 
-G_DEFINE_TYPE (GcalEventWidget, gcal_event_widget, GTK_TYPE_WIDGET)
+  if (slanted_start && slanted_end)
+    gtk_style_context_add_class (context, "slanted");
+  else if (slanted_start)
+    gtk_style_context_add_class (context, "slanted-start");
+  else if (slanted_end)
+    gtk_style_context_add_class (context, "slanted-end");
+}
 
 static void
-gcal_event_widget_class_init(GcalEventWidgetClass *klass)
+update_color (GcalEventWidget *self)
 {
-  GObjectClass *object_class;
-  GtkWidgetClass *widget_class;
-
-  object_class = G_OBJECT_CLASS (klass);
-  object_class->set_property = gcal_event_widget_set_property;
-  object_class->get_property = gcal_event_widget_get_property;
-  object_class->finalize = gcal_event_widget_finalize;
-
-  widget_class = GTK_WIDGET_CLASS (klass);
-  widget_class->get_preferred_width = gcal_event_widget_get_preferred_width;
-  widget_class->get_preferred_height = gcal_event_widget_get_preferred_height;
-  widget_class->realize = gcal_event_widget_realize;
-  widget_class->unrealize = gcal_event_widget_unrealize;
-  widget_class->map = gcal_event_widget_map;
-  widget_class->unmap = gcal_event_widget_unmap;
-  widget_class->size_allocate = gcal_event_widget_size_allocate;
-  widget_class->draw = gcal_event_widget_draw;
-  widget_class->button_press_event = gcal_event_widget_button_press_event;
-  widget_class->button_release_event = gcal_event_widget_button_release_event;
-
-  g_object_class_install_property (object_class,
-                                   PROP_UUID,
-                                   g_param_spec_string ("uuid",
-                                                        "Unique uid",
-                                                        "The unique-unique id composed of 
source_uid:event_uid",
-                                                        NULL,
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_READWRITE));
-
-  g_object_class_install_property (object_class,
-                                   PROP_SUMMARY,
-                                   g_param_spec_string ("summary",
-                                                        "Summary",
-                                                        "The event summary",
-                                                        NULL,
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_READWRITE));
-
-  g_object_class_install_property (object_class,
-                                   PROP_COLOR,
-                                   g_param_spec_boxed ("color",
-                                                       "Color",
-                                                       "The color to render",
-                                                       GDK_TYPE_RGBA,
-                                                       G_PARAM_CONSTRUCT |
-                                                       G_PARAM_READWRITE));
+  GtkStyleContext *context;
+  GdkRGBA *color;
+  GQuark color_id;
+  gchar *color_str;
+  gchar *css_class;
 
-  g_object_class_install_property (object_class,
-                                   PROP_DTSTART,
-                                   g_param_spec_boxed ("date-start",
-                                                       "Date Start",
-                                                       "The starting date of the event",
-                                                       ICAL_TIME_TYPE,
-                                                       G_PARAM_CONSTRUCT |
-                                                       G_PARAM_READWRITE));
+  context = gtk_widget_get_style_context (GTK_WIDGET (self));
+  color = gcal_event_get_color (self->event);
 
-  g_object_class_install_property (object_class,
-                                   PROP_DTEND,
-                                   g_param_spec_boxed ("date-end",
-                                                       "Date End",
-                                                       "The end date of the event",
-                                                       ICAL_TIME_TYPE,
-                                                       G_PARAM_CONSTRUCT |
-                                                       G_PARAM_READWRITE));
+  color_str = gdk_rgba_to_string (color);
+  color_id = g_quark_from_string (color_str);
+  css_class = g_strdup_printf ("color-%d", color_id);
 
-  g_object_class_install_property (object_class,
-                                   PROP_ALL_DAY,
-                                   g_param_spec_boolean ("all-day",
-                                                         "All day",
-                                                         "Wheter the event is all-day or not",
-                                                         FALSE,
-                                                         G_PARAM_CONSTRUCT |
-                                                         G_PARAM_READWRITE));
+  gtk_style_context_add_class (context, css_class);
 
-  g_object_class_install_property (object_class,
-                                   PROP_HAS_REMINDERS,
-                                   g_param_spec_boolean ("has-reminders",
-                                                         "Event has reminders",
-                                                         "Wheter the event has reminders set or not",
-                                                         FALSE,
-                                                         G_PARAM_CONSTRUCT |
-                                                         G_PARAM_READWRITE));
+  if (INTENSITY (color) > 0.5)
+    {
+      gtk_style_context_remove_class (context, "color-dark");
+      gtk_style_context_add_class (context, "color-light");
+    }
+  else
+    {
+      gtk_style_context_remove_class (context, "color-light");
+      gtk_style_context_add_class (context, "color-dark");
+    }
 
-  signals[ACTIVATE] = g_signal_new ("activate",
-                                     GCAL_TYPE_EVENT_WIDGET,
-                                     G_SIGNAL_RUN_LAST,
-                                     0,
-                                     NULL, NULL,
-                                     g_cclosure_marshal_VOID__VOID,
-                                     G_TYPE_NONE,
-                                     0);
+  g_free (color_str);
+  g_free (css_class);
+}
 
-  gtk_widget_class_set_css_name (widget_class, "event-widget");
+static void
+gcal_event_widget_set_event_internal (GcalEventWidget *self,
+                                      GcalEvent       *event)
+{
+  /*
+   * This function is called only once, since the property is
+   * set as CONSTRUCT_ONLY. Any other attempt to set an event
+   * will be ignored.
+   *
+   * Because of that condition, we don't really have to care about
+   * disconnecting functions or cleaning up the previous event.
+   */
+
+  /* The event spawns with a floating reference, and we take it's ownership */
+  g_set_object (&self->event, event);
+
+  /*
+   * Initially, the widget's start and end dates are the same
+   * of the event's ones. We may change it afterwards.
+   */
+  gcal_event_widget_set_date_start (self, gcal_event_get_date_start (event));
+  gcal_event_widget_set_date_end (self, gcal_event_get_date_end (event));
+
+  /* Update color */
+  update_color (self);
+
+  g_signal_connect_swapped (event,
+                            "notify::color",
+                            G_CALLBACK (update_color),
+                            self);
+
+  g_signal_connect_swapped (event,
+                            "notify::summary",
+                            G_CALLBACK (gtk_widget_queue_draw),
+                            self);
 }
 
 static void
@@ -224,71 +180,29 @@ gcal_event_widget_set_property (GObject      *object,
 
   switch (property_id)
     {
-    case PROP_UUID:
-      g_clear_pointer (&self->uuid, g_free);
-      self->uuid = g_value_dup_string (value);
-      g_object_notify (object, "uuid");
-      return;
-    case PROP_SUMMARY:
-      g_clear_pointer (&self->summary, g_free);
-      self->summary = g_value_dup_string (value);
-      g_object_notify (object, "summary");
-      return;
-    case PROP_COLOR:
-      {
-        GtkStyleContext *context;
-
-        context = gtk_widget_get_style_context (GTK_WIDGET (object));
-
-        g_clear_pointer (&self->color, gdk_rgba_free);
-        self->color = g_value_dup_boxed (value);
-
-        if (self->color == NULL)
-          return;
-
-        if (INTENSITY (self->color->red,
-                       self->color->green,
-                       self->color->blue) > 0.5)
-          {
-            gtk_style_context_remove_class (context, "color-dark");
-            gtk_style_context_add_class (context, "color-light");
-          }
-        else
-          {
-            gtk_style_context_remove_class (context, "color-light");
-            gtk_style_context_add_class (context, "color-dark");
-          }
-
-        g_object_notify (object, "color");
-        return;
-      }
-    case PROP_DTSTART:
-      g_clear_pointer (&self->dt_start, g_free);
-      self->dt_start = g_value_dup_boxed (value);
-      g_object_notify (object, "date-start");
-      return;
-    case PROP_DTEND:
-      g_clear_pointer (&self->dt_end, g_free);
-      self->dt_end = g_value_dup_boxed (value);
-      g_object_notify (object, "date-end");
-      return;
-    case PROP_ALL_DAY:
-      if (self->all_day != g_value_get_boolean (value))
-        {
-          self->all_day = g_value_get_boolean (value);
-          g_object_notify (object, "all-day");
-        }
-      return;
+    case PROP_DATE_END:
+      gcal_event_widget_set_date_end (self, g_value_get_boxed (value));
+      break;
+
+    case PROP_DATE_START:
+      gcal_event_widget_set_date_start (self, g_value_get_boxed (value));
+      break;
+
+    case PROP_EVENT:
+      gcal_event_widget_set_event_internal (self, g_value_get_object (value));
+      break;
+
     case PROP_HAS_REMINDERS:
       if (self->has_reminders != g_value_get_boolean (value))
         {
           self->has_reminders = g_value_get_boolean (value);
-          g_object_notify (object, "all-day");
+          g_object_notify (object, "has-reminders");
         }
-      return;
-    }
+      break;
 
-  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
 }
 
 static void
@@ -301,30 +215,25 @@ gcal_event_widget_get_property (GObject      *object,
 
   switch (property_id)
     {
-    case PROP_UUID:
-      g_value_set_string (value, self->uuid);
-      return;
-    case PROP_SUMMARY:
-      g_value_set_string (value, self->summary);
-      return;
-    case PROP_COLOR:
-      g_value_set_boxed (value, self->color);
-      return;
-    case PROP_DTSTART:
-      g_value_set_boxed (value, self->dt_start);
-      return;
-    case PROP_DTEND:
+    case PROP_DATE_END:
       g_value_set_boxed (value, self->dt_end);
-      return;
-    case PROP_ALL_DAY:
-      g_value_set_boolean (value, self->all_day);
-      return;
+      break;
+
+    case PROP_DATE_START:
+      g_value_set_boxed (value, self->dt_start);
+      break;
+
+    case PROP_EVENT:
+      g_value_set_object (value, self->event);
+      break;
+
     case PROP_HAS_REMINDERS:
       g_value_set_boolean (value, self->has_reminders);
-      return;
-    }
+      break;
 
-  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
 }
 
 static void
@@ -334,14 +243,8 @@ gcal_event_widget_finalize (GObject *object)
 
   self = GCAL_EVENT_WIDGET (object);
 
-  g_clear_object (&self->component);
-
   /* releasing properties */
-  g_clear_pointer (&self->uuid, g_free);
-  g_clear_pointer (&self->summary, g_free);
-  g_clear_pointer (&self->color, gdk_rgba_free);
-  g_clear_pointer (&self->dt_start, g_free);
-  g_clear_pointer (&self->dt_end, g_free);
+  g_clear_object (&self->event);
 
   G_OBJECT_CLASS (gcal_event_widget_parent_class)->finalize (object);
 }
@@ -533,7 +436,7 @@ gcal_event_widget_draw (GtkWidget *widget,
 
   /* FIXME for RTL alignment and icons positions */
   gtk_style_context_get (context, state, "font", &font_desc, NULL);
-  layout = gtk_widget_create_pango_layout (widget, self->summary);
+  layout = gtk_widget_create_pango_layout (widget, gcal_event_get_summary (self->event));
   pango_layout_set_font_description (layout, font_desc);
   pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
   pango_layout_set_width (layout, (width - (padding.left + padding.right) ) * PANGO_SCALE);
@@ -649,141 +552,107 @@ gcal_event_widget_button_release_event (GtkWidget      *widget,
   return FALSE;
 }
 
-GtkWidget*
-gcal_event_widget_new (gchar *uuid)
-{
-  return g_object_new (GCAL_TYPE_EVENT_WIDGET, "uuid", uuid, NULL);
-}
 
-/**
- * gcal_event_widget_new_from_data:
- * @data: a #GcalEventData instance
- *
- * Create an event widget by passing its #ECalComponent and #ESource
- *
- * Returns: a #GcalEventWidget as #GtkWidget
- **/
-GtkWidget*
-gcal_event_widget_new_from_data (GcalEventData *data)
+static void
+gcal_event_widget_class_init(GcalEventWidgetClass *klass)
 {
-  GtkWidget *widget;
-  GcalEventWidget *event;
-
-  gchar *uuid;
-  ECalComponentId *id;
-  ECalComponentText e_summary;
-
-  GQuark color_id;
-  GdkRGBA color;
-  gchar *color_str, *custom_css_class;
-
-  ECalComponentDateTime dt;
-  icaltimetype *date;
-  gboolean start_is_date, end_is_date;
-
-  id = e_cal_component_get_id (data->event_component);
-  if (id->rid != NULL)
-    {
-      uuid = g_strdup_printf ("%s:%s:%s",
-                              e_source_get_uid (data->source),
-                              id->uid,
-                              id->rid);
-    }
-  else
-    {
-      uuid = g_strdup_printf ("%s:%s",
-                              e_source_get_uid (data->source),
-                              id->uid);
-    }
-  widget = g_object_new (GCAL_TYPE_EVENT_WIDGET, "uuid", uuid, NULL);
-  e_cal_component_free_id (id);
-  g_free (uuid);
-
-  event = GCAL_EVENT_WIDGET (widget);
-  event->component = data->event_component;
-  event->source = data->source;
-
-  /* summary */
-  e_cal_component_get_summary (event->component, &e_summary);
-  gcal_event_widget_set_summary (event, (gchar*) e_summary.value);
-
-  /* color */
-  get_color_name_from_source (event->source, &color);
-  gcal_event_widget_set_color (event, &color);
-
-  color_str = gdk_rgba_to_string (&color);
-  color_id = g_quark_from_string (color_str);
-  custom_css_class = g_strdup_printf ("color-%d", color_id);
-  gtk_style_context_add_class (gtk_widget_get_style_context (widget), custom_css_class);
-  g_free (custom_css_class);
-  g_free (color_str);
-
-  /* start date */
-  e_cal_component_get_dtstart (event->component, &dt);
-  date = gcal_dup_icaltime (dt.value);
-
-  start_is_date = date->is_date == 1;
-  if (!start_is_date)
-    {
-      if (dt.tzid != NULL)
-        dt.value->zone = icaltimezone_get_builtin_timezone_from_tzid (dt.tzid);
-      *date = icaltime_convert_to_zone (*(dt.value),
-                                        e_cal_util_get_system_timezone ());
-    }
+  GObjectClass *object_class;
+  GtkWidgetClass *widget_class;
 
-  gcal_event_widget_set_date (event, date);
-  e_cal_component_free_datetime (&dt);
-  g_free (date);
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->set_property = gcal_event_widget_set_property;
+  object_class->get_property = gcal_event_widget_get_property;
+  object_class->finalize = gcal_event_widget_finalize;
 
-  /* end date */
-  e_cal_component_get_dtend (event->component, &dt);
-  if (dt.value != NULL)
-    {
-      date = gcal_dup_icaltime (dt.value);
+  widget_class = GTK_WIDGET_CLASS (klass);
+  widget_class->get_preferred_width = gcal_event_widget_get_preferred_width;
+  widget_class->get_preferred_height = gcal_event_widget_get_preferred_height;
+  widget_class->realize = gcal_event_widget_realize;
+  widget_class->unrealize = gcal_event_widget_unrealize;
+  widget_class->map = gcal_event_widget_map;
+  widget_class->unmap = gcal_event_widget_unmap;
+  widget_class->size_allocate = gcal_event_widget_size_allocate;
+  widget_class->draw = gcal_event_widget_draw;
+  widget_class->button_press_event = gcal_event_widget_button_press_event;
+  widget_class->button_release_event = gcal_event_widget_button_release_event;
 
-      end_is_date = date->is_date == 1;
-      if (!end_is_date)
-        {
-          if (dt.tzid != NULL)
-            dt.value->zone = icaltimezone_get_builtin_timezone_from_tzid (dt.tzid);
-          *date = icaltime_convert_to_zone (*(dt.value),
-                                            e_cal_util_get_system_timezone ());
-        }
+  /**
+   * GcalEventWidget::date-end:
+   *
+   * The end date this widget represents. Notice that this may
+   * differ from the event's end date. For example, if the event
+   * spans more than one month and we're in Month View, the end
+   * date marks the last day this event is visible.
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_DATE_END,
+                                   g_param_spec_boxed ("date-end",
+                                                       "End date",
+                                                       "The end date of the widget",
+                                                       G_TYPE_DATE_TIME,
+                                                       G_PARAM_READWRITE));
 
-      gcal_event_widget_set_end_date (event, date);
-      e_cal_component_free_datetime (&dt);
-      g_free (date);
+  /**
+   * GcalEventWidget::date-start:
+   *
+   * The start date this widget represents. Notice that this may
+   * differ from the event's start date. For example, if the event
+   * spans more than one month and we're in Month View, the start
+   * date marks the first day this event is visible.
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_DATE_START,
+                                   g_param_spec_boxed ("date-start",
+                                                       "Start date",
+                                                       "The start date of the widget",
+                                                       G_TYPE_DATE_TIME,
+                                                       G_PARAM_READWRITE));
 
-      /* set_all_day */
-      gcal_event_widget_set_all_day (event, start_is_date && end_is_date);
-    }
+  /**
+   * GcalEventWidget::event:
+   *
+   * The event this widget represents.
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_EVENT,
+                                   g_param_spec_object ("event",
+                                                        "Event",
+                                                        "The event this widget represents",
+                                                        GCAL_TYPE_EVENT,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  /**
+   * GcalEventWidget::has-reminders:
+   *
+   * Whether the event has reminders or not.
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_HAS_REMINDERS,
+                                   g_param_spec_boolean ("has-reminders",
+                                                         "Event has reminders",
+                                                         "Wheter the event has reminders set or not",
+                                                         FALSE,
+                                                         G_PARAM_READWRITE));
 
-  /* set_has_reminders */
-  gcal_event_widget_set_has_reminders (event, e_cal_component_has_alarms (event->component));
+  signals[ACTIVATE] = g_signal_new ("activate",
+                                     GCAL_TYPE_EVENT_WIDGET,
+                                     G_SIGNAL_RUN_LAST,
+                                     0,
+                                     NULL, NULL,
+                                     g_cclosure_marshal_VOID__VOID,
+                                     G_TYPE_NONE,
+                                     0);
 
-  return widget;
+  gtk_widget_class_set_css_name (widget_class, "event-widget");
 }
 
-GtkWidget*
-gcal_event_widget_clone (GcalEventWidget *widget)
-{
-  GtkWidget *new_widget;
-  GcalEventData *data;
-
-  data = gcal_event_widget_get_data (widget);
-  g_object_ref (data->event_component);
-
-  new_widget = gcal_event_widget_new_from_data (data);
-  g_free (data);
-
-  gcal_event_widget_set_read_only(GCAL_EVENT_WIDGET (new_widget), gcal_event_widget_get_read_only (widget));
-  return new_widget;
-}
 
-const gchar*
-gcal_event_widget_peek_uuid (GcalEventWidget *event)
+GtkWidget*
+gcal_event_widget_new (GcalEvent *event)
 {
-  return event->uuid;
+  return g_object_new (GCAL_TYPE_EVENT_WIDGET,
+                       "event", event,
+                       NULL);
 }
 
 void
@@ -801,212 +670,146 @@ gcal_event_widget_get_read_only (GcalEventWidget *event)
   return event->read_only;
 }
 
-/**
- * gcal_event_widget_set_date:
- * @event: a #GcalEventWidget
- * @date: a #icaltimetype object with the date
- *
- * Set the start-date of the event
- **/
 void
-gcal_event_widget_set_date (GcalEventWidget    *event,
-                            const icaltimetype *date)
-{
-  g_object_set (event, "date-start", date, NULL);
-}
-
-/**
- * gcal_event_widget_get_date:
- * @event: a #GcalEventWidget
- *
- * Return the starting date of the event
- *
- * Returns: (transfer full): Release with g_free()
- **/
-icaltimetype*
-gcal_event_widget_get_date (GcalEventWidget *event)
+gcal_event_widget_set_has_reminders (GcalEventWidget *event,
+                                     gboolean         has_reminders)
 {
-  icaltimetype *dt;
+  g_return_if_fail (GCAL_IS_EVENT_WIDGET (event));
 
-  g_object_get (event, "date-start", &dt, NULL);
-  return dt;
+  g_object_set (event, "has-reminders", has_reminders, NULL);
 }
 
-/**
- * gcal_event_widget_peek_start_date:
- * @event:
- *
- * Return the starting date of the event.
- *
- * Returns: (Transfer none): An { link icaltimetype} instance
- **/
-const icaltimetype*
-gcal_event_widget_peek_start_date (GcalEventWidget *event)
+gboolean
+gcal_event_widget_get_has_reminders (GcalEventWidget *event)
 {
-  return event->dt_start;
-}
+  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (event), FALSE);
 
-/**
- * gcal_event_widget_set_end_date:
- * @event: a #GcalEventWidget
- * @date: a #icaltimetype object with the date
- *
- * Set the end date of the event
- **/
-void
-gcal_event_widget_set_end_date (GcalEventWidget    *event,
-                                const icaltimetype *date)
-{
-  g_object_set (event, "date-end", date, NULL);
+  return event->has_reminders;
 }
 
 /**
- * gcal_event_widget_get_end_date:
- * @event: a #GcalEventWidget
+ * gcal_event_widget_get_date_end:
+ * @self: a #GcalEventWidget
  *
- * Return the end date of the event. If the event has no end_date
- * (as Google does on 0 sec events) %NULL will be returned
+ * Retrieves the visible end date of this widget. This
+ * may differ from the event's end date.
  *
- * Returns: (transfer full): Release with g_free()
- **/
-icaltimetype*
-gcal_event_widget_get_end_date (GcalEventWidget *event)
+ * Returns: (transfer none): a #GDateTime
+ */
+GDateTime*
+gcal_event_widget_get_date_end (GcalEventWidget *self)
 {
-  icaltimetype *dt;
+  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (self), NULL);
 
-  g_object_get (event, "date-end", &dt, NULL);
-  return dt;
+  return self->dt_end ? self->dt_end : self->dt_start;
 }
 
 /**
- * gcal_event_widget_peek_end_date:
- * @event:
+ * gcal_event_widget_set_date_end:
+ * @self: a #GcalEventWidget
+ * @date_end: the end date of this widget
  *
- * Return the end date of the event.
- *
- * Returns: (Transfer none): An { link icaltimetype} instance
- **/
-const icaltimetype*
-gcal_event_widget_peek_end_date (GcalEventWidget *event)
-{
-  return event->dt_end != NULL ? event->dt_end : event->dt_start;
-}
-
+ * Sets the visible end date of this widget. This
+ * may differ from the event's end date, but cannot
+ * be after it.
+ */
 void
-gcal_event_widget_set_summary (GcalEventWidget *event,
-                               gchar           *summary)
+gcal_event_widget_set_date_end (GcalEventWidget *self,
+                                GDateTime       *date_end)
 {
-  g_return_if_fail (GCAL_IS_EVENT_WIDGET (event));
+  g_return_if_fail (GCAL_IS_EVENT_WIDGET (self));
 
-  g_object_set (event, "summary", summary, NULL);
-}
+  if (self->dt_end != date_end &&
+      (!self->dt_end || !date_end ||
+       (self->dt_end && date_end && !g_date_time_equal (self->dt_end, date_end))))
+    {
+      /* The end date should never be after the event's end date */
+      if (date_end && g_date_time_compare (date_end, gcal_event_get_date_end (self->event)) > 0)
+        return;
 
-gchar*
-gcal_event_widget_get_summary (GcalEventWidget *event)
-{
-  return g_strdup (event->summary);
-}
+      g_clear_pointer (&self->dt_end, g_date_time_unref);
+      self->dt_end = g_date_time_ref (date_end);
 
-void
-gcal_event_widget_set_color (GcalEventWidget *event,
-                             GdkRGBA         *color)
-{
-  g_return_if_fail (GCAL_IS_EVENT_WIDGET (event));
+      gcal_event_widget_update_style (self);
 
-  g_object_set (event, "color", color, NULL);
+      g_object_notify (G_OBJECT (self), "date-end");
+    }
 }
 
-GdkRGBA*
-gcal_event_widget_get_color (GcalEventWidget *event)
+/**
+ * gcal_event_widget_get_date_start:
+ * @self: a #GcalEventWidget
+ *
+ * Retrieves the visible start date of this widget. This
+ * may differ from the event's start date.
+ *
+ * Returns: (transfer none): a #GDateTime
+ */
+GDateTime*
+gcal_event_widget_get_date_start (GcalEventWidget *self)
 {
-  GdkRGBA *color;
-  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (event), NULL);
+  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (self), NULL);
 
-  color = NULL;
-  g_object_get (event, "color", color, NULL);
-  return color;
+  return self->dt_start;
 }
 
+/**
+ * gcal_event_widget_set_date_start:
+ * @self: a #GcalEventWidget
+ * @date_end: the start date of this widget
+ *
+ * Sets the visible start date of this widget. This
+ * may differ from the event's start date, but cannot
+ * be before it.
+ */
 void
-gcal_event_widget_set_all_day (GcalEventWidget *event,
-                               gboolean         all_day)
+gcal_event_widget_set_date_start (GcalEventWidget *self,
+                                  GDateTime       *date_start)
 {
-  g_return_if_fail (GCAL_IS_EVENT_WIDGET (event));
-
-  g_object_set (event, "all-day", all_day, NULL);
-}
-
-gboolean
-gcal_event_widget_get_all_day (GcalEventWidget *event)
-{
-  gboolean all_day;
-  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (event), FALSE);
-
-  g_object_get (event, "all-day", &all_day, NULL);
-  return all_day;
-}
-
-gboolean
-gcal_event_widget_is_multiday (GcalEventWidget *event)
-{
-  gint start_day_of_year, end_day_of_year;
-
-  if (event->dt_end == NULL)
-    return FALSE;
-
-  start_day_of_year = icaltime_day_of_year (*(event->dt_start));
-  end_day_of_year = icaltime_day_of_year (*(event->dt_end));
+  g_return_if_fail (GCAL_IS_EVENT_WIDGET (self));
 
-  if (event->all_day && start_day_of_year + 1 == end_day_of_year)
-    return FALSE;
-
-  if (event->all_day && start_day_of_year == icaltime_days_in_year (event->dt_start->year) && 
end_day_of_year == 1 &&
-      event->dt_start->year + 1 == event->dt_end->year)
-    return FALSE;
-
-  return start_day_of_year != end_day_of_year;
-}
-
-void
-gcal_event_widget_set_has_reminders (GcalEventWidget *event,
-                                     gboolean         has_reminders)
-{
-  g_return_if_fail (GCAL_IS_EVENT_WIDGET (event));
+  if (self->dt_start != date_start &&
+      (!self->dt_start || !date_start ||
+       (self->dt_start && date_start && !g_date_time_equal (self->dt_start, date_start))))
+    {
+      /* The start date should never be before the event's start date */
+      if (date_start && g_date_time_compare (date_start, gcal_event_get_date_start (self->event)) < 0)
+        return;
 
-  g_object_set (event, "has-reminders", has_reminders, NULL);
-}
+      g_clear_pointer (&self->dt_start, g_date_time_unref);
+      self->dt_start = g_date_time_ref (date_start);
 
-gboolean
-gcal_event_widget_get_has_reminders (GcalEventWidget *event)
-{
-  gboolean has_reminders;
-  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (event), FALSE);
+      gcal_event_widget_update_style (self);
 
-  g_object_get (event, "has-reminders", &has_reminders, NULL);
-  return has_reminders;
+      g_object_notify (G_OBJECT (self), "date-start");
+    }
 }
 
 /**
- * gcal_event_widget_get_data:
- * @event: a #GcalEventWidget instance
+ * gcal_event_widget_get_event:
+ * @self: a #GcalEventWidget
  *
- * Returns a #GcalEventData with shallows members, meaning the members
- * are owned but the struct should be freed.
+ * Retrieves the @GcalEvent this widget represents.
  *
- * Returns: (transfer full): a #GcalEventData
- **/
-GcalEventData*
-gcal_event_widget_get_data (GcalEventWidget *event)
+ * Returns: (transfer none): a #GcalEvent
+ */
+GcalEvent*
+gcal_event_widget_get_event (GcalEventWidget *self)
 {
-  GcalEventData *data;
+  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (self), NULL);
 
-  g_return_val_if_fail (GCAL_IS_EVENT_WIDGET (event), NULL);
+  return self->event;
+}
 
-  data = g_new0 (GcalEventData, 1);
-  data->source = event->source;
-  data->event_component = event->component;
+GtkWidget*
+gcal_event_widget_clone (GcalEventWidget *widget)
+{
+  GtkWidget *new_widget;
+
+  new_widget = gcal_event_widget_new (widget->event);
+  gcal_event_widget_set_read_only(GCAL_EVENT_WIDGET (new_widget), gcal_event_widget_get_read_only (widget));
 
-  return data;
+  return new_widget;
 }
 
 /**
@@ -1023,22 +826,10 @@ gboolean
 gcal_event_widget_equal (GcalEventWidget *widget1,
                          GcalEventWidget *widget2)
 {
-  ECalComponentId *id1;
-  ECalComponentId *id2;
-
-  gboolean same_id = FALSE;
-
-  if (!e_source_equal (widget1->source, widget2->source))
+  if (!e_source_equal (gcal_event_get_source (widget1->event), gcal_event_get_source (widget2->event)))
     return FALSE;
 
-  id1 = e_cal_component_get_id (widget1->component);
-  id2 = e_cal_component_get_id (widget2->component);
-  same_id = e_cal_component_id_equal (id1, id2);
-
-  e_cal_component_free_id (id1);
-  e_cal_component_free_id (id2);
-
-  return same_id;
+  return g_strcmp0 (gcal_event_get_uid (widget1->event), gcal_event_get_uid (widget2->event)) == 0;
 }
 
 /**
@@ -1057,13 +848,13 @@ gcal_event_widget_compare_by_length (GcalEventWidget *widget1,
   time_t time_s1, time_s2;
   time_t time_e1, time_e2;
 
-  time_e1 = time_s1 = icaltime_as_timet (*(widget1->dt_start));
-  time_e2 = time_s2 = icaltime_as_timet (*(widget2->dt_start));
+  time_e1 = time_s1 = g_date_time_to_unix (widget1->dt_start);
+  time_e2 = time_s2 = g_date_time_to_unix (widget2->dt_start);
 
   if (widget1->dt_end != NULL)
-    time_e1 = icaltime_as_timet (*(widget1->dt_end));
+    time_e1 = g_date_time_to_unix (widget1->dt_end);
   if (widget2->dt_end)
-    time_e2 = icaltime_as_timet (*(widget2->dt_end));
+    time_e2 = g_date_time_to_unix (widget2->dt_end);
 
   return (time_e2 - time_s2) - (time_e1 - time_s1);
 }
@@ -1072,7 +863,7 @@ gint
 gcal_event_widget_compare_by_start_date (GcalEventWidget *widget1,
                                          GcalEventWidget *widget2)
 {
-  return icaltime_compare (*(widget1->dt_start), *(widget2->dt_start));
+  return g_date_time_compare (widget1->dt_start, widget2->dt_start);
 }
 
 /**
@@ -1089,39 +880,39 @@ gint
 gcal_event_widget_compare_for_single_day (GcalEventWidget *widget1,
                                           GcalEventWidget *widget2)
 {
-  if (gcal_event_widget_is_multiday (widget1) && gcal_event_widget_is_multiday (widget2))
+  if (gcal_event_is_multiday (widget1->event) && gcal_event_is_multiday (widget2->event))
     {
       time_t time_s1, time_s2;
       time_t time_e1, time_e2;
       time_t result;
 
-      time_s1 = icaltime_as_timet (*(widget1->dt_start));
-      time_s2 = icaltime_as_timet (*(widget2->dt_start));
-      time_e1 = icaltime_as_timet (*(widget1->dt_end));
-      time_e2 = icaltime_as_timet (*(widget2->dt_end));
+      time_s1 = g_date_time_to_unix (widget1->dt_start);
+      time_s2 = g_date_time_to_unix (widget2->dt_start);
+      time_e1 = g_date_time_to_unix (widget1->dt_end);
+      time_e2 = g_date_time_to_unix (widget2->dt_end);
 
       result = (time_e2 - time_s2) - (time_e1 - time_s1);
       if (result != 0)
         return result;
       else
-        return icaltime_compare (*(widget1->dt_start), *(widget2->dt_start));
+        return g_date_time_compare (widget1->dt_start, widget2->dt_start);
     }
   else
     {
-      if (gcal_event_widget_is_multiday (widget1))
+      if (gcal_event_is_multiday (widget1->event))
         return -1;
-      else if (gcal_event_widget_is_multiday (widget2))
+      else if (gcal_event_is_multiday (widget2->event))
         return 1;
       else
         {
-          if (widget1->all_day && widget2->all_day)
+          if (gcal_event_get_all_day (widget1->event) && gcal_event_get_all_day (widget2->event))
             return 0;
-          else if (widget1->all_day)
+          else if (gcal_event_get_all_day (widget1->event))
             return -1;
-          else if (widget2->all_day)
+          else if (gcal_event_get_all_day (widget2->event))
             return 1;
           else
-            return icaltime_compare (*(widget1->dt_start), *(widget2->dt_start));
+            return g_date_time_compare (widget1->dt_start, widget2->dt_start);
         }
     }
 }
diff --git a/src/gcal-event-widget.h b/src/gcal-event-widget.h
index 4feca51..d07b79f 100644
--- a/src/gcal-event-widget.h
+++ b/src/gcal-event-widget.h
@@ -20,6 +20,7 @@
 #ifndef __GCAL_EVENT_WIDGET_H__
 #define __GCAL_EVENT_WIDGET_H__
 
+#include "gcal-event.h"
 #include "gcal-manager.h"
 
 #include <gtk/gtk.h>
@@ -32,56 +33,33 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (GcalEventWidget, gcal_event_widget, GCAL, EVENT_WIDGET, GtkWidget)
 
-GtkWidget*    gcal_event_widget_new                        (gchar              *uuid);
+GtkWidget*    gcal_event_widget_new                        (GcalEvent          *event);
 
-GtkWidget*    gcal_event_widget_new_from_data              (GcalEventData      *data);
+GcalEvent*    gcal_event_widget_get_event                  (GcalEventWidget    *self);
 
-GtkWidget*    gcal_event_widget_clone                      (GcalEventWidget    *widget);
+GDateTime*    gcal_event_widget_get_date_start             (GcalEventWidget    *self);
+
+void          gcal_event_widget_set_date_start             (GcalEventWidget    *self,
+                                                            GDateTime          *date_start);
+
+GDateTime*    gcal_event_widget_get_date_end               (GcalEventWidget    *self);
 
-const gchar*  gcal_event_widget_peek_uuid                  (GcalEventWidget    *event);
+void          gcal_event_widget_set_date_end               (GcalEventWidget    *self,
+                                                            GDateTime          *date_end);
 
 void          gcal_event_widget_set_read_only              (GcalEventWidget    *event,
                                                             gboolean            read_only);
 
 gboolean      gcal_event_widget_get_read_only              (GcalEventWidget    *event);
 
-void          gcal_event_widget_set_date                   (GcalEventWidget    *event,
-                                                            const icaltimetype *date);
-
-icaltimetype* gcal_event_widget_get_date                   (GcalEventWidget    *event);
-
-const icaltimetype* gcal_event_widget_peek_start_date            (GcalEventWidget    *event);
-
-void          gcal_event_widget_set_end_date               (GcalEventWidget    *event,
-                                                            const icaltimetype *date);
-
-icaltimetype* gcal_event_widget_get_end_date               (GcalEventWidget    *event);
-
-const icaltimetype* gcal_event_widget_peek_end_date              (GcalEventWidget    *event);
-
-void          gcal_event_widget_set_summary                (GcalEventWidget    *event,
-                                                            gchar              *summary);
-
-gchar*        gcal_event_widget_get_summary                (GcalEventWidget    *event);
-
-void          gcal_event_widget_set_color                  (GcalEventWidget    *event,
-                                                            GdkRGBA            *color);
-
-GdkRGBA*      gcal_event_widget_get_color                  (GcalEventWidget    *event);
-
-void          gcal_event_widget_set_all_day                (GcalEventWidget    *event,
-                                                            gboolean            all_day);
-
-gboolean     gcal_event_widget_get_all_day                 (GcalEventWidget    *event);
-
-gboolean     gcal_event_widget_is_multiday                 (GcalEventWidget    *event);
-
 void         gcal_event_widget_set_has_reminders           (GcalEventWidget    *event,
                                                             gboolean            has_reminders);
 
 gboolean     gcal_event_widget_get_has_reminders           (GcalEventWidget    *event);
 
-GcalEventData* gcal_event_widget_get_data                  (GcalEventWidget    *event);
+/* Utilities */
+
+GtkWidget*    gcal_event_widget_clone                      (GcalEventWidget    *widget);
 
 gboolean     gcal_event_widget_equal                       (GcalEventWidget    *widget1,
                                                             GcalEventWidget    *widget2);
diff --git a/src/gcal-manager.c b/src/gcal-manager.c
index 30790e3..8b60625 100644
--- a/src/gcal-manager.c
+++ b/src/gcal-manager.c
@@ -17,6 +17,7 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "gcal-event.h"
 #include "gcal-manager.h"
 #include "gcal-utils.h"
 
@@ -281,6 +282,25 @@ gather_components (ECalDataModel         *data_model,
   return TRUE;
 }
 
+static gboolean
+gather_events (ECalDataModel         *data_model,
+               ECalClient            *client,
+               const ECalComponentId *id,
+               ECalComponent         *comp,
+               time_t                 instance_start,
+               time_t                 instance_end,
+               gpointer               user_data)
+{
+  GList **result = user_data;
+  GcalEvent *event;
+
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp);
+
+  *result = g_list_append (*result, event);/* FIXME: add me sorted */
+
+  return TRUE;
+}
+
 /**
  * load_source:
  * @manager: Manager instance
@@ -1522,7 +1542,7 @@ gcal_manager_get_events (GcalManager  *manager,
   range_start = icaltime_as_timet_with_zone (*start_date, manager->system_timezone);
   range_end = icaltime_as_timet_with_zone (*end_date, manager->system_timezone);
 
-  e_cal_data_model_foreach_component (manager->e_data_model, range_start, range_end, gather_components, 
&list);
+  e_cal_data_model_foreach_component (manager->e_data_model, range_start, range_end, gather_events, &list);
   return list;
 }
 
diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c
index 7ec5896..1055ed8 100644
--- a/src/gcal-month-view.c
+++ b/src/gcal-month-view.c
@@ -475,11 +475,6 @@ rebuild_popover_for_day (GcalMonthView *view,
   GdkRectangle rect;
 
   gchar *label_title;
-
-  icaltimetype date, second_date;
-  const icaltimetype *dt_start, *dt_end;
-  gint start_comparison, end_comparison;
-
   /* placement helpers */
   gdouble start_grid_y, cell_width, cell_height;
 
@@ -504,36 +499,44 @@ rebuild_popover_for_day (GcalMonthView *view,
   gtk_container_foreach (GTK_CONTAINER (priv->events_list_box), (GtkCallback) gtk_widget_destroy, NULL);
 
   l = g_hash_table_lookup (ppriv->overflow_cells, GINT_TO_POINTER (priv->pressed_overflow_indicator));
+
+  /* Setup the start & end dates of the events as the begin & end of day */
   if (l != NULL)
     {
-      date = *(priv->date);
-      date.day = day;
+      GDateTime *current_date;
+      GDateTime *dt_start;
+      GDateTime *dt_end;
+      GTimeZone *tz;
+
+      current_date = icaltime_to_datetime (priv->date, &tz);
+      dt_start = g_date_time_new (tz,
+                                  g_date_time_get_year (current_date),
+                                  g_date_time_get_month (current_date),
+                                  day,
+                                  0, 0, 0);
+
+      dt_end = g_date_time_new (tz,
+                                g_date_time_get_year (current_date),
+                                g_date_time_get_month (current_date),
+                                day + 1,
+                                0, 0, 0);
+
+      for (; l != NULL; l = g_list_next (l))
+        {
+          GtkWidget *cloned_event;
 
-      second_date = date;
+          cloned_event = gcal_event_widget_clone (l->data);
+          gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (cloned_event), dt_start);
+          gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (cloned_event), dt_end);
 
-      date.hour = 0;
-      date.minute = 0;
-      second_date.hour = 23;
-      second_date.minute =59;
-    }
-  for (; l != NULL; l = g_list_next (l))
-    {
-      child_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (l->data));
-      gtk_container_add (GTK_CONTAINER (priv->events_list_box), child_widget);
-      _gcal_subscriber_view_setup_child (GCAL_SUBSCRIBER_VIEW (view), child_widget);
-
-      dt_start = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (child_widget));
-      dt_end = gcal_event_widget_peek_end_date (GCAL_EVENT_WIDGET (child_widget));
-
-      date.is_date = dt_start->is_date;
-      start_comparison = icaltime_compare (*dt_start, date);
-      end_comparison = icaltime_compare (second_date, *dt_end);
-      if (start_comparison == -1 && end_comparison == -1)
-        gtk_style_context_add_class (gtk_widget_get_style_context (child_widget), "slanted");
-      else if (start_comparison == -1)
-        gtk_style_context_add_class (gtk_widget_get_style_context (child_widget), "slanted-start");
-      else if (end_comparison == -1)
-        gtk_style_context_add_class (gtk_widget_get_style_context (child_widget), "slanted-end");
+          gtk_container_add (GTK_CONTAINER (priv->events_list_box), cloned_event);
+          _gcal_subscriber_view_setup_child (GCAL_SUBSCRIBER_VIEW (view), cloned_event);
+        }
+
+      g_clear_pointer (&current_date, g_date_time_unref);
+      g_clear_pointer (&dt_start, g_date_time_unref);
+      g_clear_pointer (&dt_end, g_date_time_unref);
+      g_clear_pointer (&tz, g_time_zone_unref);
     }
 
   /* placement calculation */
@@ -605,28 +608,33 @@ update_list_box_headers (GtkListBoxRow *row,
 {
   GcalMonthViewPrivate *priv;
   GtkWidget *row_child, *before_child = NULL;
-  const icaltimetype *row_date, *before_date = NULL;
+  GDateTime *row_date, *before_date = NULL;
+  GcalEvent *row_event;
 
   priv = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (user_data));
   row_child = gtk_bin_get_child (GTK_BIN (row));
-  row_date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (row_child));
+  row_event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (row_child));
+  row_date = gcal_event_widget_get_date_start (GCAL_EVENT_WIDGET (row_child));
   if (before != NULL)
     {
       before_child = gtk_bin_get_child (GTK_BIN (before));
-      before_date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (before_child));
+      before_date = gcal_event_widget_get_date_start (GCAL_EVENT_WIDGET (before_child));
     }
 
-  if (!gcal_event_widget_is_multiday (GCAL_EVENT_WIDGET (row_child)) &&
-      !gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (row_child)) &&
-      (before_date == NULL || before_date->hour != row_date->hour))
+  if (!gcal_event_is_multiday (row_event) &&
+      !gcal_event_get_all_day (row_event) &&
+      (before_date == NULL || g_date_time_get_hour (before_date) != g_date_time_get_hour (row_date)))
     {
       gchar *time;
       GtkWidget *label, *vbox;
+      gint hour;
+
+      hour = g_date_time_get_hour (row_date);
 
       if (priv->use_24h_format)
-        time = g_strdup_printf ("%.2d:00", row_date->hour);
+        time = g_strdup_printf ("%.2d:00", hour);
       else
-        time = g_strdup_printf ("%.2d:00 %s", row_date->hour % 12, row_date->hour < 12 ? "AM" : "PM");
+        time = g_strdup_printf ("%.2d:00 %s", hour % 12, hour < 12 ? "AM" : "PM");
 
       label = gtk_label_new (time);
       gtk_style_context_add_class (gtk_widget_get_style_context (label), GTK_STYLE_CLASS_DIM_LABEL);
@@ -1066,11 +1074,14 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
       gint first_cell, last_cell, first_row, last_row, start, end;
       gboolean visible, start_before = TRUE, end_after = TRUE;
 
-      const icaltimetype *date;
+      GDateTime *date;
+      GcalEvent *event;
       GArray *cells, *lengths;
 
       child_widget = (GtkWidget*) l->data;
-      uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child_widget));
+      event = gcal_event_widget_get_event (l->data);
+      uuid = gcal_event_get_uid (event);
+
       if (!gtk_widget_is_visible (child_widget) && !g_hash_table_contains (ppriv->hidden_as_overflow, uuid))
         continue;
 
@@ -1078,30 +1089,30 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
       gtk_widget_get_preferred_height (child_widget, NULL, &natural_height);
 
       j = 1;
-      date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (child_widget));
-      if (date->month == priv->date->month)
+      date = gcal_event_widget_get_date_start (GCAL_EVENT_WIDGET (child_widget));
+      if (g_date_time_get_month (date) == priv->date->month)
         {
-          j = date->day;
+          j = g_date_time_get_day_of_month (date);
           start_before = FALSE;
         }
       j += priv->days_delay;
       first_cell = 7 * ((j - 1) / 7)+ 6 * priv->k + sw * ((j - 1) % 7);
 
       j = icaltime_days_in_month (priv->date->month, priv->date->year);
-      date = gcal_event_widget_peek_end_date (GCAL_EVENT_WIDGET (child_widget));
-      if (gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (child_widget)))
+      date = gcal_event_widget_get_date_end (GCAL_EVENT_WIDGET (child_widget));
+      if (gcal_event_get_all_day (event))
         {
-          if (date->month == priv->date->month)
+          if (g_date_time_get_month (date) == priv->date->month)
             {
-              j = date->day - 1;
+              j = g_date_time_get_day_of_month (date) - 1;
               end_after = FALSE;
             }
         }
       else
         {
-          if (date->month == priv->date->month)
+          if (g_date_time_get_month (date) == priv->date->month)
             {
-              j = date->day;
+              j = g_date_time_get_day_of_month (date);
               end_after = FALSE;
             }
         }
@@ -1221,7 +1232,8 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
         {
           child_widget = (GtkWidget*) aux->data;
 
-          uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child_widget));
+          uuid = gcal_event_get_uid (gcal_event_widget_get_event (GCAL_EVENT_WIDGET (child_widget)));
+
           if (!gtk_widget_is_visible (child_widget) && !g_hash_table_contains (ppriv->hidden_as_overflow, 
uuid))
             continue;
 
@@ -1797,15 +1809,18 @@ static gboolean
 gcal_month_view_is_child_multiday (GcalSubscriberView *subscriber,
                                      GcalEventWidget    *child)
 {
-  return gcal_event_widget_is_multiday (child);
+  return gcal_event_is_multiday (gcal_event_widget_get_event (child));
 }
 
 static guint
 gcal_month_view_get_child_cell (GcalSubscriberView *subscriber,
                                 GcalEventWidget    *child)
 {
-  const icaltimetype *dt_start = gcal_event_widget_peek_start_date (child);
-  return dt_start->day;
+  GDateTime *dt;
+
+  dt = gcal_event_widget_get_date_start (child);
+
+  return g_date_time_get_day_of_month (dt);
 }
 
 static void
diff --git a/src/gcal-subscriber-view.c b/src/gcal-subscriber-view.c
index 937c763..43ae97f 100644
--- a/src/gcal-subscriber-view.c
+++ b/src/gcal-subscriber-view.c
@@ -21,8 +21,9 @@
 #include "gcal-subscriber-view.h"
 #include "gcal-subscriber-view-private.h"
 
-#include "gcal-view.h"
+#include "gcal-event.h"
 #include "gcal-event-widget.h"
+#include "gcal-view.h"
 
 enum
 {
@@ -169,13 +170,15 @@ gcal_subscriber_view_add (GtkContainer *container,
                           GtkWidget    *widget)
 {
   GcalSubscriberViewPrivate *priv;
+  GcalEvent *event;
   const gchar *uuid;
   GList *l = NULL;
 
   g_return_if_fail (GCAL_IS_EVENT_WIDGET (widget));
   g_return_if_fail (gtk_widget_get_parent (widget) == NULL);
   priv = gcal_subscriber_view_get_instance_private (GCAL_SUBSCRIBER_VIEW (container));
-  uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (widget));
+  event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (widget));
+  uuid = gcal_event_get_uid (event);
 
   /* inserting in all children hash */
   if (g_hash_table_lookup (priv->children, uuid) != NULL)
@@ -215,6 +218,7 @@ gcal_subscriber_view_remove (GtkContainer *container,
                              GtkWidget    *widget)
 {
   GcalSubscriberViewPrivate *priv;
+  GcalEvent *event;
   const gchar *uuid;
 
   GList *l, *aux;
@@ -222,8 +226,8 @@ gcal_subscriber_view_remove (GtkContainer *container,
 
   g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container));
   priv = gcal_subscriber_view_get_instance_private (GCAL_SUBSCRIBER_VIEW (container));
-
-  uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (widget));
+  event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (widget));
+  uuid = gcal_event_get_uid (event);
 
   l = g_hash_table_lookup (priv->children, uuid);
   if (l != NULL)
@@ -352,20 +356,17 @@ gcal_subscriber_view_component_added (ECalDataModelSubscriber *subscriber,
                                       ECalClient              *client,
                                       ECalComponent           *comp)
 {
-  GtkWidget *event;
-  GcalEventData *data;
+  GtkWidget *event_widget;
+  GcalEvent *event;
 
-  data = g_new0 (GcalEventData, 1);
-  data->source = e_client_get_source (E_CLIENT (client));
-  data->event_component = e_cal_component_clone (comp);
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp);
+  event_widget = gcal_event_widget_new (event);
+  gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (event_widget), e_client_is_readonly (E_CLIENT 
(client)));
 
-  event = gcal_event_widget_new_from_data (data);
-  gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (event), e_client_is_readonly (E_CLIENT (client)));
+  gtk_widget_show (event_widget);
+  gtk_container_add (GTK_CONTAINER (subscriber), event_widget);
 
-  gtk_widget_show (event);
-  gtk_container_add (GTK_CONTAINER (subscriber), event);
-
-  g_free (data);
+  g_clear_object (&event);
 }
 
 static void
@@ -376,17 +377,14 @@ gcal_subscriber_view_component_modified (ECalDataModelSubscriber *subscriber,
   GcalSubscriberViewPrivate *priv;
   GList *l;
   GtkWidget *new_widget;
-  GcalEventData *data;
+  GcalEvent *event;
 
   priv = gcal_subscriber_view_get_instance_private (GCAL_SUBSCRIBER_VIEW (subscriber));
-  data = g_new0 (GcalEventData, 1);
-  data->source = e_client_get_source (E_CLIENT (client));
-  data->event_component = e_cal_component_clone (comp);
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp);
+  new_widget = gcal_event_widget_new (event);
 
-  new_widget = gcal_event_widget_new_from_data (data);
-  g_free (data);
+  l = g_hash_table_lookup (priv->children, gcal_event_get_uid (event));
 
-  l = g_hash_table_lookup (priv->children, gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (new_widget)));
   if (l != NULL)
     {
       gtk_widget_destroy (l->data);
@@ -397,10 +395,12 @@ gcal_subscriber_view_component_modified (ECalDataModelSubscriber *subscriber,
   else
     {
       g_warning ("%s: Widget with uuid: %s not found in view: %s",
-                 G_STRFUNC, gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (new_widget)),
+                 G_STRFUNC, gcal_event_get_uid (event),
                  gtk_widget_get_name (GTK_WIDGET (subscriber)));
       gtk_widget_destroy (new_widget);
     }
+
+  g_clear_object (&event);
 }
 
 static void
diff --git a/src/gcal-utils.c b/src/gcal-utils.c
index cba1099..552de36 100644
--- a/src/gcal-utils.c
+++ b/src/gcal-utils.c
@@ -63,6 +63,29 @@ month_item[12] =
 
 G_DEFINE_BOXED_TYPE (icaltimetype, icaltime, gcal_dup_icaltime, g_free)
 
+gint
+datetime_compare_date (GDateTime *dt1,
+                       GDateTime *dt2)
+{
+  if (!dt1 && !dt2)
+    return 0;
+  else if (!dt1)
+    return -1;
+  else if (!dt2)
+    return 1;
+
+  if (g_date_time_get_year (dt1) != g_date_time_get_year (dt2))
+    return g_date_time_get_year (dt1) - g_date_time_get_year (dt2);
+
+  if (g_date_time_get_month (dt1) != g_date_time_get_month (dt2))
+    return g_date_time_get_month (dt1) - g_date_time_get_month (dt2);
+
+  if (g_date_time_get_day_of_month (dt1) != g_date_time_get_day_of_month (dt2))
+    return g_date_time_get_day_of_month (dt1) - g_date_time_get_day_of_month (dt2);
+
+  return 0;
+}
+
 icaltimetype*
 datetime_to_icaltime (GDateTime *dt)
 {
@@ -233,22 +256,18 @@ gcal_compare_event_widget_by_date (gconstpointer a,
   /* negative value if a < b; zero if a = b; positive value if a > b. */
   GcalViewChild *a_child;
   GcalViewChild *b_child;
-  icaltimetype *a_date;
-  icaltimetype *b_date;
+  GDateTime *a_date;
+  GDateTime *b_date;
 
   gint comparison;
 
   a_child = (GcalViewChild*) a;
   b_child = (GcalViewChild*) b;
 
-  a_date =
-    gcal_event_widget_get_date (GCAL_EVENT_WIDGET (a_child->widget));
-  b_date =
-    gcal_event_widget_get_date (GCAL_EVENT_WIDGET (b_child->widget));
+  a_date = gcal_event_get_date_start (gcal_event_widget_get_event (GCAL_EVENT_WIDGET (a_child->widget)));
+  b_date = gcal_event_get_date_start (gcal_event_widget_get_event (GCAL_EVENT_WIDGET (b_child->widget)));
 
-  comparison = icaltime_compare (*a_date, *b_date);
-  g_free (a_date);
-  g_free (b_date);
+  comparison = g_date_time_compare (a_date, b_date);
 
   return comparison;
 }
diff --git a/src/gcal-utils.h b/src/gcal-utils.h
index 9397b05..303e1a0 100644
--- a/src/gcal-utils.h
+++ b/src/gcal-utils.h
@@ -52,6 +52,9 @@ const gchar*  (*GcalTranslateFunc)                              (GtkWidget
 
 GType           icaltime_get_type                               (void)            G_GNUC_CONST;
 
+gint            datetime_compare_date                           (GDateTime             *dt1,
+                                                                 GDateTime             *dt2);
+
 icaltimetype*   datetime_to_icaltime                            (GDateTime             *dt);
 
 gboolean        datetime_is_date                                (GDateTime             *dt);
diff --git a/src/gcal-week-view.c b/src/gcal-week-view.c
index b97891b..8854a79 100644
--- a/src/gcal-week-view.c
+++ b/src/gcal-week-view.c
@@ -1131,9 +1131,10 @@ gcal_week_view_add (GtkContainer *container,
   GList *l;
 
   gint day;
-  icaltimetype *date;
 
   GcalWeekViewChild *new_child;
+  GDateTime *date;
+  GcalEvent *event;
 
   g_return_if_fail (GCAL_IS_WEEK_VIEW (container));
   g_return_if_fail (GCAL_IS_EVENT_WIDGET (widget));
@@ -1141,8 +1142,9 @@ gcal_week_view_add (GtkContainer *container,
   priv = gcal_week_view_get_instance_private (GCAL_WEEK_VIEW (container));
 
   /* Check if it's already added for date */
-  date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
-  day = (icaltime_day_of_week (*date) - priv->first_weekday + 6) % 7;
+  event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (widget));
+  date = gcal_event_get_date_start (event);
+  day = (g_date_time_get_day_of_week (date) - priv->first_weekday + 6) % 7;
 
   for (l = priv->days[day]; l != NULL; l = l->next)
     {
@@ -1164,7 +1166,7 @@ gcal_week_view_add (GtkContainer *container,
   new_child->widget = widget;
   new_child->hidden_by_me = FALSE;
 
-  if (gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (widget)))
+  if (gcal_event_get_all_day (event))
     {
       new_child->index = -1;
       if (gtk_widget_get_window (widget) != NULL)
@@ -1173,7 +1175,7 @@ gcal_week_view_add (GtkContainer *container,
     }
   else
     {
-      new_child->index = date->hour;
+      new_child->index = g_date_time_get_hour (date);
       if (priv->grid_window != NULL)
         gtk_widget_set_parent_window (widget, priv->grid_window);
     }
@@ -1185,7 +1187,6 @@ gcal_week_view_add (GtkContainer *container,
                     "activate",
                     G_CALLBACK (event_opened),
                     container);
-  g_free (date);
 }
 
 static void
@@ -1193,17 +1194,18 @@ gcal_week_view_remove (GtkContainer *container,
                         GtkWidget    *widget)
 {
   GcalWeekViewPrivate *priv;
+  GcalEvent *event;
+  GDateTime *date;
   GList *l;
-  icaltimetype *date;
   gint day;
   gboolean was_visible;
 
   g_return_if_fail (GCAL_IS_WEEK_VIEW (container));
   g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container));
   priv = gcal_week_view_get_instance_private (GCAL_WEEK_VIEW (container));
-
-  date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
-  day = (icaltime_day_of_week (*date) - priv->first_weekday + 6) % 7;
+  event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (widget));
+  date = gcal_event_get_date_start (event);
+  day = (g_date_time_get_day_of_week (date) - priv->first_weekday + 6) % 7;
 
   for (l = priv->days[day]; l != NULL; l = l->next)
     {
@@ -1347,10 +1349,13 @@ gcal_week_view_get_by_uuid (GcalSubscriberView *subscriber_view,
       for (l = priv->days[i]; l != NULL; l = l->next)
         {
           GcalWeekViewChild *child;
+          GcalEvent *event;
           const gchar* widget_uuid;
 
           child = (GcalWeekViewChild*) l->data;
-          widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child->widget));
+          event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (child->widget));
+          widget_uuid = gcal_event_get_uid (event);
+
           if (g_strcmp0 (uuid, widget_uuid) == 0)
             return child->widget;
         }
diff --git a/src/gcal-window.c b/src/gcal-window.c
index 093212c..a75e60a 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -773,7 +773,7 @@ new_event_entry_text_changed (GObject    *object,
   static gboolean blocked = TRUE;
   gint length;
 
-  length = g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (user_data)), -1);
+  length = g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (object)), -1);
 
   gtk_widget_set_sensitive (window->new_event_create_button, length > 0);
 
@@ -1083,18 +1083,13 @@ create_event (gpointer   user_data,
                                        window->event_creation_data->end_date);
   if (widget == window->new_event_details_button)
     {
-      GcalEventData *edata;
+      GcalEvent *event;
 
-      edata = g_new0 (GcalEventData, 1);
-      edata->source = source;
-      edata->event_component = comp;
+      event = gcal_event_new (source, comp);
 
-      gcal_edit_dialog_set_event_is_new (GCAL_EDIT_DIALOG (window->edit_dialog),
-                                         TRUE);
-      gcal_edit_dialog_set_event_data (GCAL_EDIT_DIALOG (window->edit_dialog),
-                                       edata);
+      gcal_edit_dialog_set_event_is_new (GCAL_EDIT_DIALOG (window->edit_dialog), TRUE);
+      gcal_edit_dialog_set_event (GCAL_EDIT_DIALOG (window->edit_dialog), event);
       g_object_unref (comp);
-      g_free (edata);
 
       gtk_dialog_run (GTK_DIALOG (window->edit_dialog));
     }
@@ -1104,7 +1099,9 @@ create_event (gpointer   user_data,
       gcal_manager_create_event (window->manager, source, comp);
     }
 
-  g_object_unref (source);
+  g_clear_object (&source);
+  g_clear_object (&event);
+  g_clear_object (&comp);
 }
 
 static void
@@ -1114,19 +1111,18 @@ create_event_detailed_cb (GcalView *view,
                           gpointer  user_data)
 {
   GcalWindow *window = GCAL_WINDOW (user_data);
-  GcalEventData *edata;
+  ECalComponent *comp;
+  GcalEvent *event;
 
-  edata = g_new0 (GcalEventData, 1);
-  edata->source = gcal_manager_get_default_source (window->manager);
-  edata->event_component = build_component_from_details ("", (icaltimetype*) start_span, (icaltimetype*) 
end_span);
+  comp = build_component_from_details ("", (icaltimetype*) start_span, (icaltimetype*) end_span);
+  event = gcal_event_new (gcal_manager_get_default_source (window->manager), comp);
 
   gcal_edit_dialog_set_event_is_new (GCAL_EDIT_DIALOG (window->edit_dialog), TRUE);
-  gcal_edit_dialog_set_event_data (GCAL_EDIT_DIALOG (window->edit_dialog), edata);
-
-  g_object_unref (edata->event_component);
-  g_free (edata);
+  gcal_edit_dialog_set_event (GCAL_EDIT_DIALOG (window->edit_dialog), event);
 
   gtk_dialog_run (GTK_DIALOG (window->edit_dialog));
+
+  g_clear_object (&comp);
 }
 
 static void
@@ -1135,16 +1131,11 @@ event_activated (GcalView        *view,
                  gpointer         user_data)
 {
   GcalWindow *window = GCAL_WINDOW (user_data);
-  GcalEventData *data;
-
-  data = gcal_event_widget_get_data (event_widget);
-  gcal_edit_dialog_set_event_is_new (
-      GCAL_EDIT_DIALOG (window->edit_dialog),
-      FALSE);
-  gcal_edit_dialog_set_event_data (
-      GCAL_EDIT_DIALOG (window->edit_dialog),
-      data);
-  g_free (data);
+  GcalEvent *event;
+
+  event = gcal_event_widget_get_event (event_widget);
+  gcal_edit_dialog_set_event_is_new (GCAL_EDIT_DIALOG (window->edit_dialog), FALSE);
+  gcal_edit_dialog_set_event (GCAL_EDIT_DIALOG (window->edit_dialog), event);
 
   gtk_dialog_run (GTK_DIALOG (window->edit_dialog));
 }
diff --git a/src/gcal-year-view.c b/src/gcal-year-view.c
index abd0ea8..8488654 100644
--- a/src/gcal-year-view.c
+++ b/src/gcal-year-view.c
@@ -199,12 +199,14 @@ update_selected_dates_from_button_data (GcalYearView *year_view)
       year_view->start_selected_date->day = selected_data.start_day;
       year_view->start_selected_date->month = selected_data.start_month + 1;
       year_view->start_selected_date->year = year_view->date->year;
+      year_view->end_selected_date->is_date = TRUE;
 
       year_view->end_selected_date->day = selected_data.end_day;
       year_view->end_selected_date->month = selected_data.end_month + 1;
       year_view->end_selected_date->year = year_view->date->year;
       year_view->end_selected_date->hour = 23;
       year_view->end_selected_date->minute = 59;
+      year_view->end_selected_date->is_date = TRUE;
       *(year_view->end_selected_date) = icaltime_normalize (*(year_view->end_selected_date));
     }
   else
@@ -212,6 +214,7 @@ update_selected_dates_from_button_data (GcalYearView *year_view)
       *(year_view->start_selected_date) = *(year_view->current_date);
       year_view->start_selected_date->hour = 0;
       year_view->start_selected_date->minute = 0;
+      year_view->start_selected_date->second = 0;
 
       *(year_view->end_selected_date) = *(year_view->current_date);
       year_view->end_selected_date->hour = 23;
@@ -254,50 +257,59 @@ update_no_events_page (GcalYearView *year_view)
 
 static void
 add_event_to_day_array (GcalYearView  *year_view,
-                        GcalEventData *event_data,
+                        GcalEvent     *event,
                         GList        **days_widgets_array,
                         gint           days_span)
 {
   GtkWidget *child_widget;
 
-  const icaltimetype *dt_start, *dt_end;
-  icaltimetype date, second_date;
+  GDateTime *dt_start, *dt_end;
+  GDateTime *date, *second_date;
+  GTimeZone *tz;
 
   gint i;
   gboolean child_widget_used = FALSE;
 
-  child_widget = gcal_event_widget_new_from_data (event_data);
+  child_widget = gcal_event_widget_new (event);
   gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (child_widget),
-                                   !gcal_manager_is_client_writable (year_view->manager, 
event_data->source));
+                                   !gcal_manager_is_client_writable (year_view->manager, 
gcal_event_get_source (event)));
 
-  dt_start = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (child_widget));
-  dt_end = gcal_event_widget_peek_end_date (GCAL_EVENT_WIDGET (child_widget));
+  dt_start = gcal_event_get_date_start (event);
+  dt_end = gcal_event_get_date_end (event);
 
   /* normalize date on each new event */
-  date = *(year_view->start_selected_date);
-  second_date = *(year_view->start_selected_date);
-  second_date.hour = 23;
-  second_date.minute = 59;
+  date = icaltime_to_datetime (year_view->start_selected_date, &tz);
+  second_date = g_date_time_new (tz,
+                                 g_date_time_get_year (date),
+                                 g_date_time_get_month (date),
+                                 g_date_time_get_day_of_month (date) + 1,
+                                 0, 0, 0);
+
+  gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (child_widget), date);
+  gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (child_widget), second_date);
 
   /* marking and cloning */
   for (i = 0; i < days_span; i++)
     {
-      GtkWidget *cloned_child = child_widget;
+      GDateTime *aux;
+      GtkWidget *cloned_child;
       gint start_comparison, end_comparison;
 
-      if (i != 0)
-        {
-          icaltime_adjust (&date, 1, 0, 0, 0);
-          icaltime_adjust (&second_date, 1, 0, 0, 0);
-        }
+      cloned_child = child_widget;
+      start_comparison = datetime_compare_date (dt_start, date);
 
-      start_comparison = icaltime_compare_date (dt_start, &date);
       if (start_comparison <= 0)
         {
           if (child_widget_used)
-            cloned_child = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
+            {
+              cloned_child = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
+              gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (cloned_child), date);
+              gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (cloned_child), second_date);
+            }
           else
-            child_widget_used = TRUE;
+            {
+              child_widget_used = TRUE;
+            }
         }
       else
         {
@@ -310,21 +322,20 @@ add_event_to_day_array (GcalYearView  *year_view,
                                                         cloned_child,
                                                         (GCompareFunc) 
gcal_event_widget_compare_for_single_day);
 
-          end_comparison = icaltime_compare_date (&second_date, dt_end);
-          /* XXX: hack ensuring allday events with end_date a day after */
-          if (end_comparison == -1 && second_date.year == dt_end->year && dt_end->is_date == 1)
-            end_comparison = 0;
-
-          if (start_comparison < 0 && end_comparison < 0)
-            gtk_style_context_add_class (gtk_widget_get_style_context (cloned_child), "slanted");
-          else if (start_comparison < 0)
-            gtk_style_context_add_class (gtk_widget_get_style_context (cloned_child), "slanted-start");
-          else if (end_comparison < 0)
-            gtk_style_context_add_class (gtk_widget_get_style_context (cloned_child), "slanted-end");
+          end_comparison = g_date_time_compare (second_date, dt_end);
 
           if (end_comparison == 0)
             break;
         }
+
+      /* Move the compared dates to the next day */
+      aux = date;
+      date = g_date_time_add_days (date, 1);
+      g_clear_pointer (&aux, g_date_time_unref);
+
+      aux = second_date;
+      second_date = g_date_time_add_days (second_date, 1);
+      g_clear_pointer (&aux, g_date_time_unref);
     }
 }
 
@@ -373,8 +384,8 @@ update_sidebar (GcalYearView *year_view)
       g_list_free (current_day);
     }
 
+  g_list_free_full (events, g_object_unref);
   g_free (days_widgets_array);
-  g_list_free_full (events, g_free);
 }
 
 static void
@@ -393,20 +404,26 @@ update_sidebar_headers (GtkListBoxRow *row,
 {
   GcalYearView *year_view;
   GtkWidget *row_child, *before_child = NULL, *row_header = NULL;
-  const icaltimetype *row_date, *before_date = NULL;
+  GcalEvent *row_event, *before_event;
+  GDateTime *row_date, *before_date = NULL;
   icaltimetype date;
   gint row_shift, before_shift =-1;
 
   year_view = GCAL_YEAR_VIEW (user_data);
   row_child = gtk_bin_get_child (GTK_BIN (row));
+
   if (row_child == NULL)
     return;
-  row_date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (row_child));
+
+  row_event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (row_child));
+  row_date = gcal_event_get_date_start (row_event);
   row_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row_child), "shift"));
+
   if (before != NULL)
     {
       before_child = gtk_bin_get_child (GTK_BIN (before));
-      before_date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (before_child));
+      before_event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (before_child));
+      before_date = gcal_event_get_date_start (before_event);
       before_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (before_child), "shift"));
     }
 
@@ -432,17 +449,20 @@ update_sidebar_headers (GtkListBoxRow *row,
       gtk_container_add (GTK_CONTAINER (row_header), label);
     }
 
-  if (!gcal_event_widget_is_multiday (GCAL_EVENT_WIDGET (row_child)) &&
-      !gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (row_child)) &&
-      (before_date == NULL || before_date->hour != row_date->hour))
+  if (!gcal_event_is_multiday (row_event) &&
+      !gcal_event_get_all_day (row_event) &&
+      (before_date == NULL || g_date_time_get_hour (before_date) != g_date_time_get_hour (row_date)))
     {
       gchar *time;
       GtkWidget *label;
+      gint hour;
+
+      hour = g_date_time_get_hour (row_date);
 
       if (year_view->use_24h_format)
-        time = g_strdup_printf ("%.2d:00", row_date->hour);
+        time = g_strdup_printf ("%.2d:00", hour);
       else
-        time = g_strdup_printf ("%.2d:00 %s", row_date->hour % 12, row_date->hour < 12 ? "AM" : "PM");
+        time = g_strdup_printf ("%.2d:00 %s", hour % 12, hour < 12 ? "AM" : "PM");
 
       label = gtk_label_new (time);
       gtk_style_context_add_class (gtk_widget_get_style_context (label), GTK_STYLE_CLASS_DIM_LABEL);
@@ -752,7 +772,7 @@ draw_month_grid (GcalYearView *year_view,
                                  box_side * (row + 1) + y + box_padding_top + layout_height + 2.0,
                                  VISUAL_CLUES_SIDE, VISUAL_CLUES_SIDE);
           gtk_style_context_restore (context);
-          g_list_free_full (events, g_free);
+          g_list_free_full (events, g_object_unref);
         }
 
       g_free (nr_day);
@@ -1174,8 +1194,14 @@ gcal_year_view_get_children_by_uuid (GcalView    *view,
   children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar));
   for (l = children; l != NULL; l = g_list_next (l))
     {
-      GcalEventWidget *child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
-      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_widget_peek_uuid (child_widget)) == 0)
+      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);
@@ -1190,7 +1216,7 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
 {
   GcalYearView *year_view = GCAL_YEAR_VIEW (subscriber);
 
-  GcalEventData *data;
+  GcalEvent *event;
   GList **days_widgets_array;
   GList *l;
   gint i, days_span;
@@ -1203,9 +1229,7 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
   days_span = icaltime_day_of_year(*(year_view->end_selected_date)) - 
icaltime_day_of_year(*(year_view->start_selected_date)) + 1;
   days_widgets_array = g_new0 (GList*, days_span);
 
-  data = g_new0 (GcalEventData, 1);
-  data->source = e_client_get_source (E_CLIENT (client));
-  data->event_component = e_cal_component_clone (comp);
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp);
 
   /* check if event belongs to range */
   zone = gcal_manager_get_system_timezone (year_view->manager);
@@ -1228,11 +1252,10 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
         (event_start >= range_start && event_start <= range_end) ||
         (event_end >= range_start && event_end <= range_end)))
     {
-      g_object_unref (data->event_component);
       goto out;
     }
 
-  add_event_to_day_array (year_view, data, days_widgets_array, days_span);
+  add_event_to_day_array (year_view, event, days_widgets_array, days_span);
   gtk_stack_set_visible_child_name (GTK_STACK (year_view->navigator_stack), "events-list");
 
   for (i = 0; i < days_span; i++)
@@ -1251,7 +1274,7 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
     }
 
 out:
-  g_free (data);
+  g_clear_object (&event);
   g_free (days_widgets_array);
 }
 
@@ -1268,8 +1291,13 @@ gcal_year_view_component_changed (ECalDataModelSubscriber *subscriber,
   children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar));
   for (l = children; l != NULL; l = g_list_next (l))
     {
-      GcalEventWidget *child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
-      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_widget_peek_uuid (child_widget)) == 0)
+      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)
         gtk_widget_destroy (GTK_WIDGET (l->data));
     }
   g_list_free (children);
@@ -1299,8 +1327,14 @@ gcal_year_view_component_removed (ECalDataModelSubscriber *subscriber,
   children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar));
   for (l = children; l != NULL; l = g_list_next (l))
     {
-      GcalEventWidget *child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
-      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_widget_peek_uuid (child_widget)) == 0)
+      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)
         {
           if (g_list_length (children) == 1)
             update_sidebar_needed = TRUE;


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