[gnome-calendar] Added GcalWeekView. Not integrated yet.



commit 1021c7e781fe883440b6e63e16008bcb72524331
Author: Erick PÃrez Castellanos <erick red gmail com>
Date:   Thu Jul 5 21:40:02 2012 -0400

    Added GcalWeekView. Not integrated yet.
    
    Refactoring the code inside GcalMonthView for drawing and for showing child
    widgets.
    Fixed ref_sink in GcalEditableRemainder. (Don't need it)
    Added translation for weekdays abbreviation. (Thxs to ebassi & mclasen)
    Passed make distcheck.

 po/POTFILES.in               |    3 +
 src/Makefile.am              |    2 +
 src/gcal-editable-reminder.c |    1 -
 src/gcal-event-widget.c      |   38 ++-
 src/gcal-event-widget.h      |    5 +
 src/gcal-month-view.c        |  249 +++++++++----
 src/gcal-utils.c             |   18 +
 src/gcal-utils.h             |    2 +
 src/gcal-week-view.c         |  892 ++++++++++++++++++++++++++++++++++++++++++
 src/gcal-week-view.h         |   63 +++
 src/gcal-window.c            |    2 +-
 11 files changed, 1201 insertions(+), 74 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5b736cc..4178203 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,12 +2,15 @@
 
 src/main.c
 src/gcal-application.c
+src/gcal-window.c
 src/gcal-toolbar.c
 src/gcal-month-view.c
+src/gcal-week-view.c
 src/gcal-event-view.c
 src/gcal-editable-date.c
 src/gcal-editable-reminder.c
 src/gcal-manager.c
+src/gcal-utils.c
 
 data/gnome-calendar.desktop.in.in
 data/org.gnome.calendar.gschema.xml.in
diff --git a/src/Makefile.am b/src/Makefile.am
index d00a56f..691c5ec 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,8 @@ gnome_calendar_SOURCES =                                \
 	gcal-view.h                                           \
 	gcal-month-view.c                                     \
 	gcal-month-view.h                                     \
+	gcal-week-view.c                                      \
+	gcal-week-view.h                                     \
 	gcal-event-widget.c                                   \
 	gcal-event-widget.h                                   \
 	gcal-event-view.c                                     \
diff --git a/src/gcal-editable-reminder.c b/src/gcal-editable-reminder.c
index d64940d..9c11f57 100644
--- a/src/gcal-editable-reminder.c
+++ b/src/gcal-editable-reminder.c
@@ -129,7 +129,6 @@ gcal_editable_reminder_constructed (GObject *object)
                                           NULL);
 
   priv->add_button = gtk_button_new_with_label (_("Add reminder"));
-  g_object_ref_sink (priv->add_button);
   g_object_set (priv->add_button,
                 "halign", GTK_ALIGN_START,
                 "valign", GTK_ALIGN_START,
diff --git a/src/gcal-event-widget.c b/src/gcal-event-widget.c
index 411ad8c..34e49ea 100644
--- a/src/gcal-event-widget.c
+++ b/src/gcal-event-widget.c
@@ -32,6 +32,7 @@ struct _GcalEventWidgetPrivate
   gchar        *summary;
   GdkRGBA      *color;
   icaltimetype *dt_start;
+  gboolean      all_day;
 };
 
 enum
@@ -40,7 +41,8 @@ enum
   PROP_UUID,
   PROP_SUMMARY,
   PROP_COLOR,
-  PROP_DTSTART
+  PROP_DTSTART,
+  PROP_ALLDAY
 };
 
 enum
@@ -148,6 +150,15 @@ gcal_event_widget_class_init(GcalEventWidgetClass *klass)
                                                        G_PARAM_CONSTRUCT |
                                                        G_PARAM_READWRITE));
 
+  g_object_class_install_property (object_class,
+                                   PROP_ALLDAY,
+                                   g_param_spec_boolean ("all-day",
+                                                         "All day",
+                                                         "Wheter the event is all-day or not",
+                                                         FALSE,
+                                                         G_PARAM_CONSTRUCT |
+                                                         G_PARAM_READWRITE));
+
   signals[ACTIVATED] = g_signal_new ("activated",
                                      GCAL_TYPE_EVENT_WIDGET,
                                      G_SIGNAL_RUN_LAST,
@@ -219,6 +230,9 @@ gcal_event_widget_set_property (GObject      *object,
 
       priv->dt_start = g_value_dup_boxed (value);
       return;
+    case PROP_ALLDAY:
+      priv->all_day = g_value_get_boolean (value);
+      return;
     }
 
   G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -248,6 +262,9 @@ gcal_event_widget_get_property (GObject      *object,
     case PROP_DTSTART:
       g_value_set_boxed (value, priv->dt_start);
       return;
+    case PROP_ALLDAY:
+      g_value_set_boolean (value, priv->all_day);
+      return;
     }
 
   G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -579,3 +596,22 @@ gcal_event_widget_get_color (GcalEventWidget *event)
   g_object_get (event, "color", color, NULL);
   return color;
 }
+
+void
+gcal_event_widget_set_all_day (GcalEventWidget *event,
+                               gboolean         all_day)
+{
+  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;
+}
diff --git a/src/gcal-event-widget.h b/src/gcal-event-widget.h
index 4e3f1bc..7412274 100644
--- a/src/gcal-event-widget.h
+++ b/src/gcal-event-widget.h
@@ -77,6 +77,11 @@ void          gcal_event_widget_set_color                  (GcalEventWidget *eve
 
 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);
+
 G_END_DECLS
 
 #endif /* __GCAL_EVENT_WIDGET_H__ */
diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c
index 525ce5d..83bf382 100644
--- a/src/gcal-month-view.c
+++ b/src/gcal-month-view.c
@@ -25,12 +25,22 @@
 
 #include <glib/gi18n.h>
 
+#include <libecal/e-cal-time-util.h>
+
 enum
 {
   PROP_0,
   PROP_DATE
 };
 
+struct _GcalViewChild
+{
+  GtkWidget *widget;
+  gboolean   hidden_by_me;
+};
+
+typedef struct _GcalViewChild GcalViewChild;
+
 struct _GcalMonthViewPrivate
 {
   /**
@@ -49,23 +59,12 @@ struct _GcalMonthViewPrivate
   icaltimetype   *date;
 
   gint            days_delay;
+  gint            header_size;
   gint            grid_header_size;
   gdouble         vertical_step;
   gdouble         horizontal_step;
 };
 
-/* this will need translation */
-const char* weekdays [] =
- {
-   "Sun",
-   "Mon",
-   "Tue",
-   "Wed",
-   "Thu",
-   "Fri",
-   "Sat"
-  };
-
 static void         gcal_view_interface_init                (GcalViewIface  *iface);
 
 static void         gcal_month_view_constructed             (GObject        *object);
@@ -113,10 +112,15 @@ static void         gcal_month_view_forall                  (GtkContainer   *con
                                                              GtkCallback     callback,
                                                              gpointer        callback_data);
 
-static void         gcal_month_view_draw_month_grid         (GcalMonthView  *view,
+static void         gcal_month_view_draw_header             (GcalMonthView  *view,
                                                              cairo_t        *cr,
-                                                             gint            x,
-                                                             gint            y);
+                                                             GtkAllocation  *alloc,
+                                                             GtkBorder      *padding);
+
+static void         gcal_month_view_draw_grid               (GcalMonthView  *view,
+                                                             cairo_t        *cr,
+                                                             GtkAllocation  *alloc,
+                                                             GtkBorder      *padding);
 
 static gboolean     gcal_month_view_is_in_range             (GcalView       *view,
                                                              icaltimetype   *date);
@@ -134,7 +138,8 @@ G_DEFINE_TYPE_WITH_CODE (GcalMonthView,
                                                 gcal_view_interface_init));
 
 
-static void gcal_month_view_class_init (GcalMonthViewClass *klass)
+static void
+gcal_month_view_class_init (GcalMonthViewClass *klass)
 {
   GtkContainerClass *container_class;
   GtkWidgetClass *widget_class;
@@ -175,7 +180,8 @@ static void gcal_month_view_class_init (GcalMonthViewClass *klass)
 
 
 
-static void gcal_month_view_init (GcalMonthView *self)
+static void
+gcal_month_view_init (GcalMonthView *self)
 {
   GcalMonthViewPrivate *priv;
   gint i;
@@ -390,48 +396,53 @@ gcal_month_view_size_allocate (GtkWidget     *widget,
   pango_layout_get_pixel_size (layout, NULL, &font_height);
 
   /* init values */
-  priv->grid_header_size = 12;
+  priv->header_size = font_height + 4;
+  priv->grid_header_size = font_height + 4;
   priv->horizontal_step =
     (allocation->width - (allocation->x + padding.left + padding.right)) / 7;
   priv->vertical_step =
-    (allocation->height - (allocation->y + padding.top + padding.bottom + priv->grid_header_size)) / 5;
+    (allocation->height - (allocation->y + padding.top + padding.bottom + priv->header_size + priv->grid_header_size)) / 5;
 
   for (i = 0; i < 35; i++)
     {
-      if (priv->days[i] == NULL)
-        continue;
       added_height = 0;
       for (l = priv->days[i]; l != NULL; l = l->next)
         {
+          GcalViewChild *child;
           gint pos_x;
           gint pos_y;
           gint min_height;
           gint natural_height;
           GtkAllocation child_allocation;
 
+          child = (GcalViewChild*) l->data;
+
           pos_x = ( i % 7 ) * priv->horizontal_step;
           pos_y = ( i / 7 ) * priv->vertical_step;
 
-          if (! gtk_widget_get_visible (GTK_WIDGET (l->data)))
+          if ((! gtk_widget_get_visible (child->widget)) && (! child->hidden_by_me))
             continue;
-          gtk_widget_get_preferred_height (GTK_WIDGET (l->data),
+
+          gtk_widget_get_preferred_height (child->widget,
                                            &min_height,
                                            &natural_height);
-          child_allocation.x = pos_x + allocation->x + padding.top;
+          child_allocation.x = pos_x + allocation->x + padding.left;
           child_allocation.y = pos_y + font_height + allocation->y
-            + priv->grid_header_size + padding.left;
+            + priv->header_size + priv->grid_header_size + padding.top;
           child_allocation.width = priv->horizontal_step;
           child_allocation.height = MIN (natural_height, priv->vertical_step);
           if (added_height + font_height + child_allocation.height
               > priv->vertical_step)
             {
-              gtk_widget_hide (GTK_WIDGET (l->data));
+              gtk_widget_hide (child->widget);
+              child->hidden_by_me = TRUE;
             }
           else
             {
-              gtk_widget_show (GTK_WIDGET (l->data));
+              gtk_widget_show (child->widget);
+              child->hidden_by_me = FALSE;
               child_allocation.y = child_allocation.y + added_height;
-              gtk_widget_size_allocate (GTK_WIDGET (l->data), &child_allocation);
+              gtk_widget_size_allocate (child->widget, &child_allocation);
               added_height += child_allocation.height;
             }
         }
@@ -442,32 +453,19 @@ static gboolean
 gcal_month_view_draw (GtkWidget *widget,
                       cairo_t   *cr)
 {
-  GcalMonthViewPrivate *priv;
   GtkStyleContext *context;
   GtkStateFlags state;
   GtkBorder padding;
-  GdkRGBA color;
   GtkAllocation alloc;
 
-  priv = GCAL_MONTH_VIEW (widget)->priv;
-
   context = gtk_widget_get_style_context (widget);
   state = gtk_widget_get_state_flags (widget);
 
   gtk_style_context_get_padding (context, state, &padding);
-  gtk_style_context_get_color (context, state, &color);
-
-  /* grid_header_size is found through pango_get_size_in_pixels */
-  priv->grid_header_size = 12;
-
-  /* getting allocation, and so on */
   gtk_widget_get_allocation (widget, &alloc);
 
-  gcal_month_view_draw_month_grid (
-      GCAL_MONTH_VIEW (widget),
-      cr,
-      alloc.x + padding.left,
-      alloc.y + padding.top + priv->grid_header_size);
+  gcal_month_view_draw_header (GCAL_MONTH_VIEW (widget), cr, &alloc, &padding);
+  gcal_month_view_draw_grid (GCAL_MONTH_VIEW (widget), cr, &alloc, &padding);
 
   if (GTK_WIDGET_CLASS (gcal_month_view_parent_class)->draw != NULL)
     GTK_WIDGET_CLASS (gcal_month_view_parent_class)->draw (widget, cr);
@@ -512,8 +510,9 @@ gcal_month_view_button_press (GtkWidget      *widget,
   return TRUE;
 }
 
-static gboolean gcal_month_view_button_release (GtkWidget      *widget,
-                                                GdkEventButton *event)
+static gboolean
+gcal_month_view_button_release (GtkWidget      *widget,
+                                GdkEventButton *event)
 {
   GcalMonthViewPrivate *priv;
   GtkStyleContext *context;
@@ -564,6 +563,8 @@ gcal_month_view_add (GtkContainer *container,
   gint day;
   icaltimetype *date;
 
+  GcalViewChild *new_child;
+
   g_return_if_fail (GCAL_IS_MONTH_VIEW (container));
   g_return_if_fail (GCAL_IS_EVENT_WIDGET (widget));
   g_return_if_fail (gtk_widget_get_parent (widget) == NULL);
@@ -576,15 +577,23 @@ gcal_month_view_add (GtkContainer *container,
 
   for (l = priv->days[day]; l != NULL; l = l->next)
     {
+      GcalViewChild *child;
+
+      child = (GcalViewChild*) l->data;
       if (g_strcmp0 (
             gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (widget)),
-            gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (l->data))) == 0)
+            gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child->widget))) == 0)
         {
           g_warning ("Trying to add an event with the same uuid to the view");
           return;
         }
     }
-  priv->days[day] = g_list_append (priv->days[day], widget);
+
+  new_child = g_new0 (GcalViewChild, 1);
+  new_child->widget = widget;
+  new_child->hidden_by_me = FALSE;
+
+  priv->days[day] = g_list_append (priv->days[day], new_child);
   gtk_widget_set_parent (widget, GTK_WIDGET (container));
 }
 
@@ -595,6 +604,7 @@ gcal_month_view_remove (GtkContainer *container,
   GcalMonthViewPrivate *priv;
   icaltimetype *date;
   gint day;
+  GList *l;
 
   g_return_if_fail (GCAL_IS_MONTH_VIEW (container));
   g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container));
@@ -604,7 +614,18 @@ gcal_month_view_remove (GtkContainer *container,
   day = date->day + ( - priv->days_delay);
   g_free (date);
 
-  priv->days[day] = g_list_remove (priv->days[day], widget);
+  for (l = priv->days[day]; l != NULL; l = l->next)
+    {
+      GcalViewChild *child;
+
+      child = (GcalViewChild*) l->data;
+      if (child->widget == widget)
+        {
+          priv->days[day] = g_list_remove (priv->days[day], child);
+          g_free (child);
+          break;
+        }
+    }
   gtk_widget_unparent (widget);
 }
 
@@ -624,16 +645,83 @@ gcal_month_view_forall (GtkContainer *container,
     {
       for (l = priv->days[i]; l != NULL; l = l->next)
         {
-          (* callback) (l->data, callback_data);
+          GcalViewChild *child;
+
+          child = (GcalViewChild*) l->data;
+          (* callback) (child->widget, callback_data);
         }
     }
 }
 
 static void
-gcal_month_view_draw_month_grid (GcalMonthView *view,
-                                 cairo_t       *cr,
-                                 gint           x,
-                                 gint           y)
+gcal_month_view_draw_header (GcalMonthView  *view,
+                             cairo_t       *cr,
+                             GtkAllocation *alloc,
+                             GtkBorder     *padding)
+{
+  GcalMonthViewPrivate *priv;
+  GtkStyleContext *context;
+  GtkStateFlags state;
+  GdkRGBA color;
+
+  PangoLayout *layout;
+  gint layout_width;
+
+  gchar *left_header;
+  gchar *right_header;
+  gchar str_date[64];
+
+  struct tm tm_date;
+
+  g_return_if_fail (GCAL_IS_MONTH_VIEW (view));
+  priv = view->priv;
+
+  context = gtk_widget_get_style_context (GTK_WIDGET (view));
+  state = gtk_widget_get_state_flags (GTK_WIDGET (view));
+
+  gtk_style_context_get_color (context, state, &color);
+  cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
+
+  layout = pango_cairo_create_layout (cr);
+  pango_layout_set_font_description (layout,
+                                     gtk_style_context_get_font (context,
+                                                                 state));
+
+  tm_date = icaltimetype_to_tm (priv->date);
+  e_utf8_strftime_fix_am_pm (str_date, 64, "%B", &tm_date);
+
+  left_header = g_strdup_printf ("%s", str_date);
+  right_header = g_strdup_printf ("%d", priv->date->year);
+
+  pango_layout_set_text (layout, left_header, -1);
+  pango_cairo_update_layout (cr, layout);
+
+  cairo_move_to (cr, alloc->x + padding->left, alloc->y + padding->top);
+  pango_cairo_show_layout (cr, layout);
+
+  state |= GTK_STATE_FLAG_INSENSITIVE;
+  gtk_style_context_get_color (context, state, &color);
+  cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
+
+  pango_layout_set_text (layout, right_header, -1);
+  pango_cairo_update_layout (cr, layout);
+  pango_layout_get_pixel_size (layout, &layout_width, NULL);
+
+  cairo_move_to (cr,
+                 alloc->width - padding->right - layout_width,
+                 alloc->y + padding->top);
+  pango_cairo_show_layout (cr, layout);
+
+  g_free (left_header);
+  g_free (right_header);
+  g_object_unref (layout);
+}
+
+static void
+gcal_month_view_draw_grid (GcalMonthView *view,
+                           cairo_t       *cr,
+                           GtkAllocation *alloc,
+                           GtkBorder     *padding)
 {
   GcalMonthViewPrivate *priv;
   GtkWidget *widget;
@@ -646,6 +734,9 @@ gcal_month_view_draw_month_grid (GcalMonthView *view,
   gint font_width;
   gint font_height;
 
+  gdouble start_grid_x;
+  gdouble start_grid_y;
+
   guint8 n_days_in_month;
 
   PangoLayout *layout;
@@ -653,6 +744,10 @@ gcal_month_view_draw_month_grid (GcalMonthView *view,
 
   priv = view->priv;
   widget = GTK_WIDGET (view);
+
+  start_grid_x = alloc->x + padding->left;
+  start_grid_y = alloc->y + padding->top + priv->header_size + priv->grid_header_size;
+
   context = gtk_widget_get_style_context (widget);
   state = gtk_widget_get_state_flags (widget);
 
@@ -660,8 +755,8 @@ gcal_month_view_draw_month_grid (GcalMonthView *view,
   gtk_style_context_get_background_color (context, state, &color);
   cairo_set_source_rgba (cr, color.red, color.green, color.blue, 0.8);
   cairo_rectangle (cr,
-                   x + priv->horizontal_step * ( priv->selected_cell % 7),
-                   y + priv->vertical_step * ( priv->selected_cell / 7),
+                   start_grid_x + priv->horizontal_step * ( priv->selected_cell % 7),
+                   start_grid_y + priv->vertical_step * ( priv->selected_cell / 7),
                    priv->horizontal_step,
                    priv->vertical_step);
   cairo_fill (cr);
@@ -680,12 +775,12 @@ gcal_month_view_draw_month_grid (GcalMonthView *view,
 
   for (i = 0; i < 7; i++)
     {
-      pango_layout_set_text (layout, weekdays[i], -1);
+      pango_layout_set_text (layout, gcal_get_weekday (i), -1);
       pango_cairo_update_layout (cr, layout);
       pango_layout_get_pixel_size (layout, &font_width, &font_height);
       cairo_move_to (cr,
-                     x + priv->horizontal_step * i + 1,
-                     y - font_height - 1);
+                     start_grid_x + priv->horizontal_step * i + 1,
+                     start_grid_y - font_height - 1);
       pango_cairo_show_layout (cr, layout);
 
       for (j = 0; j < 5; j++)
@@ -698,9 +793,10 @@ gcal_month_view_draw_month_grid (GcalMonthView *view,
           pango_layout_set_text (layout, day, -1);
           pango_cairo_update_layout (cr, layout);
           pango_layout_get_pixel_size (layout, &font_width, &font_height);
+          /* 2: is margin-left and 1: is margin_top for numbers */
           cairo_move_to (cr,
-                         x + priv->horizontal_step * i + 2,
-                         y + priv->vertical_step * j + 1);
+                         start_grid_x + priv->horizontal_step * i + 2,
+                         start_grid_y + priv->vertical_step * j + 1);
           pango_cairo_show_layout (cr, layout);
           g_free (day);
         }
@@ -710,22 +806,21 @@ gcal_month_view_draw_month_grid (GcalMonthView *view,
 
   for (i = 0; i < 6; i++)
     {
-      cairo_move_to (cr, x, y + priv->vertical_step * i);
+      cairo_move_to (cr, start_grid_x, start_grid_y + priv->vertical_step * i);
       cairo_line_to (cr,
-                     x + priv->horizontal_step * 7,
-                     y + priv->vertical_step * i);
+                     start_grid_x + priv->horizontal_step * 7,
+                     start_grid_y + priv->vertical_step * i);
     }
 
   for (i = 0; i < 8; i++)
     {
-      cairo_move_to (cr, x + priv->horizontal_step * i, y);
+      cairo_move_to (cr, start_grid_x + priv->horizontal_step * i, start_grid_y);
       cairo_line_to (cr,
-                     x + priv->horizontal_step * i,
-                     y + priv->vertical_step * 5);
+                     start_grid_x + priv->horizontal_step * i,
+                     start_grid_y + priv->vertical_step * 5);
     }
 
   cairo_stroke (cr);
-
 }
 
 static gboolean
@@ -752,9 +847,17 @@ gcal_month_view_remove_by_uuid (GcalView    *view,
     {
       for (l = priv->days[i]; l != NULL; l = l->next)
         {
-          const gchar* widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (l->data));
+          GcalViewChild *child;
+          const gchar* widget_uuid;
+
+          child = (GcalViewChild*) l->data;
+          widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child->widget));
           if (g_strcmp0 (uuid, widget_uuid) == 0)
-            gtk_widget_destroy (GTK_WIDGET (l->data));
+            {
+              gtk_widget_destroy (child->widget);
+              i = 36;
+              break;
+            }
         }
     }
 }
@@ -774,9 +877,13 @@ gcal_month_view_get_by_uuid (GcalView    *view,
     {
       for (l = priv->days[i]; l != NULL; l = l->next)
         {
-          const gchar* widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (l->data));
+          GcalViewChild *child;
+          const gchar* widget_uuid;
+
+          child = (GcalViewChild*) l->data;
+          widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child->widget));
           if (g_strcmp0 (uuid, widget_uuid) == 0)
-            return GTK_WIDGET (l->data);
+            return child->widget;
         }
     }
   return NULL;
diff --git a/src/gcal-utils.c b/src/gcal-utils.c
index 17391cd..e897ffb 100644
--- a/src/gcal-utils.c
+++ b/src/gcal-utils.c
@@ -22,6 +22,8 @@
 
 #include <string.h>
 
+#include <glib/gi18n.h>
+
 #include <libedataserver/e-data-server-util.h>
 #include <libedataserverui/e-cell-renderer-color.h>
 
@@ -186,6 +188,22 @@ gcal_get_source_uid (GtkTreeModel *model,
   return uid;
 }
 
+const gchar*
+gcal_get_weekday (gint i)
+{
+  static const char* weekdays [] =
+    {
+      N_("Sun"),
+      N_("Mon"),
+      N_("Tue"),
+      N_("Wed"),
+      N_("Thu"),
+      N_("Fri"),
+      N_("Sat")
+   };
+  return _(weekdays[i]);
+}
+
 /* Function to do a last minute fixup of the AM/PM stuff if the locale
  * and gettext haven't done it right. Most English speaking countries
  * except the USA use the 24 hour clock (UK, Australia etc). However
diff --git a/src/gcal-utils.h b/src/gcal-utils.h
index 877a49c..75fa006 100644
--- a/src/gcal-utils.h
+++ b/src/gcal-utils.h
@@ -65,6 +65,8 @@ gchar*          gcal_get_source_name                            (GtkTreeModel
 gchar*          gcal_get_source_uid                             (GtkTreeModel    *model,
                                                                  const gchar     *name);
 
+const gchar*    gcal_get_weekday                                (gint             i);
+
 /* code brought from evolution */
 gsize           e_strftime_fix_am_pm                            (gchar           *str,
                                                                  gsize            max,
diff --git a/src/gcal-week-view.c b/src/gcal-week-view.c
new file mode 100644
index 0000000..5ffe1c5
--- /dev/null
+++ b/src/gcal-week-view.c
@@ -0,0 +1,892 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
+/*
+ * gcal-week-view.c
+ *
+ * Copyright (C) 2012 - Erick PÃrez Castellanos
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gcal-week-view.h"
+#include "gcal-utils.h"
+#include "gcal-view.h"
+#include "gcal-event-widget.h"
+
+#include <glib/gi18n.h>
+
+#include <libecal/e-cal-time-util.h>
+
+enum
+{
+  PROP_0,
+  PROP_DATE
+};
+
+struct _GcalViewChild
+{
+  GtkWidget *widget;
+  gboolean   hidden_by_me;
+
+  /* vertical index */
+  gint       index;
+};
+
+typedef struct _GcalViewChild GcalViewChild;
+
+struct _GcalWeekViewPrivate
+{
+  /**
+   * This is where we keep the refs of the child widgets.
+   * Every child added to the list placed in the position
+   * of it corresponding cell number.
+   * The cell number is calculated in _add method.
+   */
+  GList          *days [7];
+
+  GdkWindow      *event_window;
+
+  icaltimetype   *date;
+
+  gint            days_delay;
+  gint            header_size;
+  gint            grid_header_size;
+  gint            grid_sidebar_size;
+
+  /* hours_steps is the number of cell I will show vertically */
+  gint            hours_steps;
+  gdouble         vertical_step;
+  gdouble         horizontal_step;
+};
+
+static void         gcal_view_interface_init               (GcalViewIface  *iface);
+
+static void         gcal_week_view_set_property            (GObject        *object,
+                                                            guint           property_id,
+                                                            const GValue   *value,
+                                                            GParamSpec     *pspec);
+
+static void         gcal_week_view_get_property            (GObject        *object,
+                                                            guint           property_id,
+                                                            GValue         *value,
+                                                            GParamSpec     *pspec);
+
+static void         gcal_week_view_finalize                (GObject        *object);
+
+static void         gcal_week_view_realize                 (GtkWidget      *widget);
+
+static void         gcal_week_view_unrealize               (GtkWidget      *widget);
+
+static void         gcal_week_view_map                     (GtkWidget      *widget);
+
+static void         gcal_week_view_unmap                   (GtkWidget      *widget);
+
+static void         gcal_week_view_size_allocate           (GtkWidget      *widget,
+                                                            GtkAllocation  *allocation);
+
+static gboolean     gcal_week_view_draw                    (GtkWidget      *widget,
+                                                            cairo_t        *cr);
+
+static void         gcal_week_view_add                     (GtkContainer   *constainer,
+                                                            GtkWidget      *widget);
+
+static void         gcal_week_view_remove                  (GtkContainer   *constainer,
+                                                            GtkWidget      *widget);
+
+static void         gcal_week_view_forall                  (GtkContainer   *container,
+                                                            gboolean        include_internals,
+                                                            GtkCallback     callback,
+                                                            gpointer        callback_data);
+
+static void         gcal_week_view_draw_header             (GcalWeekView   *view,
+                                                            cairo_t        *cr,
+                                                            GtkAllocation  *alloc,
+                                                            GtkBorder      *padding);
+
+static void         gcal_week_view_draw_grid               (GcalWeekView   *view,
+                                                            cairo_t        *cr,
+                                                            GtkAllocation  *alloc,
+                                                            GtkBorder      *padding);
+
+static gboolean     gcal_week_view_is_in_range             (GcalView       *view,
+                                                            icaltimetype   *date);
+
+static void         gcal_week_view_remove_by_uuid          (GcalView       *view,
+                                                            const gchar    *uuid);
+
+static GtkWidget*   gcal_week_view_get_by_uuid             (GcalView       *view,
+                                                            const gchar    *uuid);
+
+G_DEFINE_TYPE_WITH_CODE (GcalWeekView,
+                         gcal_week_view,
+                         GTK_TYPE_CONTAINER,
+                         G_IMPLEMENT_INTERFACE (GCAL_TYPE_VIEW,
+                                                gcal_view_interface_init));
+
+
+static void
+gcal_week_view_class_init (GcalWeekViewClass *klass)
+{
+  GtkContainerClass *container_class;
+  GtkWidgetClass *widget_class;
+  GObjectClass *object_class;
+
+  container_class = GTK_CONTAINER_CLASS (klass);
+  container_class->add   = gcal_week_view_add;
+  container_class->remove = gcal_week_view_remove;
+  container_class->forall = gcal_week_view_forall;
+
+  widget_class = GTK_WIDGET_CLASS (klass);
+  widget_class->realize = gcal_week_view_realize;
+  widget_class->unrealize = gcal_week_view_unrealize;
+  widget_class->map = gcal_week_view_map;
+  widget_class->unmap = gcal_week_view_unmap;
+  widget_class->size_allocate = gcal_week_view_size_allocate;
+  widget_class->draw = gcal_week_view_draw;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->set_property = gcal_week_view_set_property;
+  object_class->get_property = gcal_week_view_get_property;
+  object_class->finalize = gcal_week_view_finalize;
+
+  g_object_class_install_property (object_class,
+                                   PROP_DATE,
+                                   g_param_spec_boxed ("date",
+                                                       "Date",
+                                                       _("Date"),
+                                                       ICAL_TIME_TYPE,
+                                                       G_PARAM_CONSTRUCT |
+                                                       G_PARAM_READWRITE));
+
+  g_type_class_add_private ((gpointer)klass, sizeof (GcalWeekViewPrivate));
+}
+
+
+
+static void
+gcal_week_view_init (GcalWeekView *self)
+{
+  GcalWeekViewPrivate *priv;
+  gint i;
+
+  gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+                                            GCAL_TYPE_WEEK_VIEW,
+                                            GcalWeekViewPrivate);
+  priv = self->priv;
+
+  for (i = 0; i < 7; i++)
+    {
+      priv->days[i] = NULL;
+    }
+}
+
+static void
+gcal_view_interface_init (GcalViewIface *iface)
+{
+  iface->is_in_range = gcal_week_view_is_in_range;
+  iface->remove_by_uuid = gcal_week_view_remove_by_uuid;
+  iface->get_by_uuid = gcal_week_view_get_by_uuid;
+}
+
+static void
+gcal_week_view_set_property (GObject       *object,
+                              guint          property_id,
+                              const GValue  *value,
+                              GParamSpec    *pspec)
+{
+  GcalWeekViewPrivate *priv = GCAL_WEEK_VIEW (object)->priv;
+
+  switch (property_id)
+    {
+    case PROP_DATE:
+      {
+        icaltimetype *first_of_month;
+
+        if (priv->date != NULL)
+          g_free (priv->date);
+
+        priv->date = g_value_dup_boxed (value);
+
+        first_of_month = gcal_dup_icaltime (priv->date);
+        first_of_month->day = 1;
+        priv->days_delay =  - icaltime_day_of_week (*first_of_month) + 2;
+        g_free (first_of_month);
+        break;
+      }
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gcal_week_view_get_property (GObject       *object,
+                              guint          property_id,
+                              GValue        *value,
+                              GParamSpec    *pspec)
+{
+  GcalWeekViewPrivate *priv = GCAL_WEEK_VIEW (object)->priv;
+
+  switch (property_id)
+    {
+    case PROP_DATE:
+      g_value_set_boxed (value, priv->date);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gcal_week_view_finalize (GObject       *object)
+{
+  GcalWeekViewPrivate *priv = GCAL_WEEK_VIEW (object)->priv;
+
+  if (priv->date != NULL)
+    g_free (priv->date);
+
+  /* Chain up to parent's finalize() method. */
+  G_OBJECT_CLASS (gcal_week_view_parent_class)->finalize (object);
+}
+
+static void
+gcal_week_view_realize (GtkWidget *widget)
+{
+  GcalWeekViewPrivate *priv;
+  GdkWindow *parent_window;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+  GtkAllocation allocation;
+
+  priv = GCAL_WEEK_VIEW (widget)->priv;
+  gtk_widget_set_realized (widget, TRUE);
+
+  parent_window = gtk_widget_get_parent_window (widget);
+  gtk_widget_set_window (widget, parent_window);
+  g_object_ref (parent_window);
+
+  gtk_widget_get_allocation (widget, &allocation);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_ONLY;
+  attributes.x = allocation.x;
+  attributes.y = allocation.y;
+  attributes.width = allocation.width;
+  attributes.height = allocation.height;
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
+                            GDK_BUTTON_RELEASE_MASK |
+                            GDK_BUTTON1_MOTION_MASK |
+                            GDK_POINTER_MOTION_HINT_MASK |
+                            GDK_POINTER_MOTION_MASK |
+                            GDK_ENTER_NOTIFY_MASK |
+                            GDK_LEAVE_NOTIFY_MASK);
+  attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+  priv->event_window = gdk_window_new (parent_window,
+                                       &attributes,
+                                       attributes_mask);
+  gdk_window_set_user_data (priv->event_window, widget);
+}
+
+static void
+gcal_week_view_unrealize (GtkWidget *widget)
+{
+  GcalWeekViewPrivate *priv;
+
+  priv = GCAL_WEEK_VIEW (widget)->priv;
+  if (priv->event_window != NULL)
+    {
+      gdk_window_set_user_data (priv->event_window, NULL);
+      gdk_window_destroy (priv->event_window);
+      priv->event_window = NULL;
+    }
+
+  GTK_WIDGET_CLASS (gcal_week_view_parent_class)->unrealize (widget);
+}
+
+static void
+gcal_week_view_map (GtkWidget *widget)
+{
+  GcalWeekViewPrivate *priv;
+
+  priv = GCAL_WEEK_VIEW (widget)->priv;
+  if (priv->event_window)
+    gdk_window_show (priv->event_window);
+
+  GTK_WIDGET_CLASS (gcal_week_view_parent_class)->map (widget);
+}
+
+static void
+gcal_week_view_unmap (GtkWidget *widget)
+{
+  GcalWeekViewPrivate *priv;
+
+  priv = GCAL_WEEK_VIEW (widget)->priv;
+  if (priv->event_window)
+    gdk_window_hide (priv->event_window);
+
+  GTK_WIDGET_CLASS (gcal_week_view_parent_class)->unmap (widget);
+}
+
+static void
+gcal_week_view_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+  GcalWeekViewPrivate *priv;
+  gint i;
+  GList *l;
+
+  GtkStyleContext *context;
+  GtkStateFlags state;
+  GtkBorder padding;
+
+  PangoLayout *layout;
+  gint font_width;
+  gint font_height;
+
+  priv = GCAL_WEEK_VIEW (widget)->priv;
+
+  gtk_widget_set_allocation (widget, allocation);
+  if (gtk_widget_get_realized (widget))
+    {
+      gdk_window_move_resize (priv->event_window,
+                              allocation->x,
+                              allocation->y,
+                              allocation->width,
+                              allocation->height);
+    }
+
+  context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
+  gtk_style_context_get_padding (context, state, &padding);
+
+  layout = pango_layout_new (gtk_widget_get_pango_context (widget));
+  pango_layout_set_font_description (layout,
+                                     gtk_style_context_get_font (context,
+                                                                 state));
+  pango_layout_set_text (layout, _("All day"), -1);
+  pango_layout_get_pixel_size (layout, &font_width, &font_height);
+
+  /* init values */
+  /* FIXME: these values should be extracted from the theme font size */
+  priv->header_size = font_height + 4;
+  priv->grid_header_size = font_height + 4;
+  priv->grid_sidebar_size = font_width + 8;
+
+  priv->horizontal_step = (allocation->width - (allocation->x + padding.left + padding.right + priv->grid_sidebar_size)) / 7;
+  priv->vertical_step =
+    (allocation->height - (allocation->y + padding.top + padding.bottom + priv->header_size + priv->grid_header_size)) / 11;
+  priv->hours_steps = 1;
+  if (priv->vertical_step < 2 * font_height)
+    {
+      priv->hours_steps = 2;
+      priv->vertical_step =
+        (allocation->height - (allocation->y + padding.top + padding.bottom + priv->header_size + priv->grid_header_size)) / 6;
+    }
+
+  for (i = 0; i < 7; i++)
+    {
+      for (l = priv->days[i]; l != NULL; l = l->next)
+        {
+          GcalViewChild *child;
+          gdouble added_height [11];
+
+          gint pos_x;
+          gint pos_y;
+          gint min_height;
+          gint natural_height;
+          GtkAllocation child_allocation;
+
+          child = (GcalViewChild*) l->data;
+          pos_x = i * priv->horizontal_step;
+          pos_y = ((child->index + (priv->hours_steps - 1)) / (priv->hours_steps)) * priv->vertical_step;
+
+          if ((! gtk_widget_get_visible (child->widget)) && (! child->hidden_by_me))
+            continue;
+
+          gtk_widget_get_preferred_height (child->widget,
+                                           &min_height,
+                                           &natural_height);
+
+          child_allocation.x = pos_x + allocation->x + padding.left
+            + priv->grid_sidebar_size;
+          child_allocation.y = pos_y + allocation->y + padding.top
+            + priv->header_size + priv->grid_header_size;
+          child_allocation.width = priv->horizontal_step;
+          child_allocation.height = MIN (natural_height, priv->vertical_step);
+          if (added_height[child->index] + child_allocation.height
+              > priv->vertical_step)
+            {
+              gtk_widget_hide (child->widget);
+              child->hidden_by_me = TRUE;
+            }
+          else
+            {
+              gtk_widget_show (child->widget);
+              child->hidden_by_me = FALSE;
+              child_allocation.y = child_allocation.y + added_height[child->index];
+              gtk_widget_size_allocate (child->widget, &child_allocation);
+              added_height[child->index] += child_allocation.height;
+            }
+        }
+    }
+}
+
+static gboolean
+gcal_week_view_draw (GtkWidget *widget,
+                      cairo_t   *cr)
+{
+  GtkStyleContext *context;
+  GtkStateFlags state;
+  GtkBorder padding;
+  GtkAllocation alloc;
+
+  context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
+
+  /* getting padding and allocation */
+  gtk_style_context_get_padding (context, state, &padding);
+  gtk_widget_get_allocation (widget, &alloc);
+
+  gcal_week_view_draw_header (GCAL_WEEK_VIEW (widget), cr, &alloc, &padding);
+  gcal_week_view_draw_grid (GCAL_WEEK_VIEW (widget), cr, &alloc, &padding);
+
+  if (GTK_WIDGET_CLASS (gcal_week_view_parent_class)->draw != NULL)
+    GTK_WIDGET_CLASS (gcal_week_view_parent_class)->draw (widget, cr);
+
+  return FALSE;
+}
+
+static void
+gcal_week_view_add (GtkContainer *container,
+                     GtkWidget    *widget)
+{
+  GcalWeekViewPrivate *priv;
+  GList *l;
+
+  gint day;
+  icaltimetype *date;
+
+  GcalViewChild *new_child;
+
+  g_return_if_fail (GCAL_IS_WEEK_VIEW (container));
+  g_return_if_fail (GCAL_IS_EVENT_WIDGET (widget));
+  g_return_if_fail (gtk_widget_get_parent (widget) == NULL);
+  priv = GCAL_WEEK_VIEW (container)->priv;
+
+  /* Check if it's already added for date */
+  date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
+  day = icaltime_day_of_week (*date);
+
+  for (l = priv->days[day - 1]; l != NULL; l = l->next)
+    {
+      GcalViewChild *child;
+
+      child = (GcalViewChild*) l->data;
+
+      if (g_strcmp0 (
+            gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (widget)),
+            gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child->widget))) == 0)
+        {
+          g_warning ("Trying to add an event with the same uuid to the view");
+          return;
+        }
+    }
+
+  new_child = g_new0 (GcalViewChild, 1);
+  new_child->widget = widget;
+  new_child->hidden_by_me = FALSE;
+
+  if (gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (widget)))
+    new_child->index = 0;
+  else
+    new_child->index = date->hour + 1 - 8;
+
+  priv->days[day - 1] = g_list_append (priv->days[day - 1], new_child);
+  gtk_widget_set_parent (widget, GTK_WIDGET (container));
+
+  g_free (date);
+}
+
+static void
+gcal_week_view_remove (GtkContainer *container,
+                        GtkWidget    *widget)
+{
+  GcalWeekViewPrivate *priv;
+  GList *l;
+  icaltimetype *date;
+  gint day;
+
+  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 (container)->priv;
+
+  date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
+  day = icaltime_day_of_week (*date);
+
+  for (l = priv->days[day - 1]; l != NULL; l = l->next)
+    {
+      GcalViewChild *child;
+
+      child = (GcalViewChild*) l->data;
+      if (child->widget == widget)
+        {
+          priv->days[day - 1] = g_list_remove (priv->days[day - 1], child);
+          g_free (child);
+          break;
+        }
+    }
+
+  gtk_widget_unparent (widget);
+
+  g_free (date);
+}
+
+static void
+gcal_week_view_forall (GtkContainer *container,
+                        gboolean      include_internals,
+                        GtkCallback   callback,
+                        gpointer      callback_data)
+{
+  GcalWeekViewPrivate *priv;
+  gint i;
+  GList *l;
+
+  priv = GCAL_WEEK_VIEW (container)->priv;
+
+  for (i = 0; i < 7; i++)
+    {
+      for (l = priv->days[i]; l != NULL; l = l->next)
+        {
+          GcalViewChild *child;
+
+          child = (GcalViewChild*) l->data;
+          (* callback) (child->widget, callback_data);
+        }
+    }
+}
+
+static void
+gcal_week_view_draw_header (GcalWeekView  *view,
+                            cairo_t       *cr,
+                            GtkAllocation *alloc,
+                            GtkBorder     *padding)
+{
+  GtkStyleContext *context;
+  GtkStateFlags state;
+  GdkRGBA color;
+
+  PangoLayout *layout;
+  gint layout_width;
+
+  gchar *left_header;
+  gchar *right_header;
+  gchar str_date[64];
+
+  icaltimetype *start_of_week;
+  struct tm tm_date;
+
+  g_return_if_fail (GCAL_IS_WEEK_VIEW (view));
+
+  context = gtk_widget_get_style_context (GTK_WIDGET (view));
+  state = gtk_widget_get_state_flags (GTK_WIDGET (view));
+
+  gtk_style_context_get_color (context, state, &color);
+  cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
+
+  layout = pango_cairo_create_layout (cr);
+  pango_layout_set_font_description (layout,
+                                     gtk_style_context_get_font (context,
+                                                                 state));
+
+  start_of_week = gcal_week_view_get_initial_date (view);
+  tm_date = icaltimetype_to_tm (start_of_week);
+  e_utf8_strftime_fix_am_pm (str_date, 64, "%B %d", &tm_date);
+
+  left_header = g_strdup_printf ("%s %s", _("Week of"), str_date);
+  right_header = g_strdup_printf ("%s %d",
+                                  _("Week"),
+                                  icaltime_week_number (*start_of_week));
+
+  pango_layout_set_text (layout, left_header, -1);
+  pango_cairo_update_layout (cr, layout);
+
+  cairo_move_to (cr, alloc->x + padding->left, alloc->y + padding->top);
+  pango_cairo_show_layout (cr, layout);
+
+  state |= GTK_STATE_FLAG_INSENSITIVE;
+  gtk_style_context_get_color (context, state, &color);
+  cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
+
+  pango_layout_set_text (layout, right_header, -1);
+  pango_cairo_update_layout (cr, layout);
+  pango_layout_get_pixel_size (layout, &layout_width, NULL);
+
+  cairo_move_to (cr,
+                 alloc->width - padding->right - layout_width,
+                 alloc->y + padding->top);
+  pango_cairo_show_layout (cr, layout);
+
+  g_free (start_of_week);
+  g_free (left_header);
+  g_free (right_header);
+  g_object_unref (layout);
+}
+
+static void
+gcal_week_view_draw_grid (GcalWeekView  *view,
+                          cairo_t       *cr,
+                          GtkAllocation *alloc,
+                          GtkBorder     *padding)
+{
+  GcalWeekViewPrivate *priv;
+  GtkWidget *widget;
+
+  GtkStyleContext *context;
+  GtkStateFlags state;
+  GdkRGBA color;
+
+  gint i;
+  gint font_width;
+  gint font_height;
+
+  PangoLayout *layout;
+
+  icaltimetype *start_of_week;
+
+  priv = view->priv;
+  widget = GTK_WIDGET (view);
+  context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
+
+  /* drawing grid header */
+  state = gtk_widget_get_state_flags (widget);
+  gtk_style_context_get_color (context, state, &color);
+  cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
+
+  layout = pango_cairo_create_layout (cr);
+  pango_layout_set_font_description (layout,
+                                     gtk_style_context_get_font (context,
+                                                                 state));
+
+  start_of_week = gcal_week_view_get_initial_date (view);
+  for (i = 0; i < 7; i++)
+    {
+      gchar *weekday_header;
+      gint n_day;
+
+      n_day = start_of_week->day + i;
+      if (n_day > icaltime_days_in_month (start_of_week->month, start_of_week->year))
+        n_day = n_day - icaltime_days_in_month (start_of_week->month, start_of_week->year);
+
+      weekday_header = g_strdup_printf ("%s %d",gcal_get_weekday (i), n_day);
+      pango_layout_set_text (layout, weekday_header, -1);
+      pango_cairo_update_layout (cr, layout);
+      pango_layout_get_pixel_size (layout, &font_width, &font_height);
+      cairo_move_to (cr,
+                     alloc->x + padding->left + priv->grid_sidebar_size + priv->horizontal_step * i + 1 + ((priv->horizontal_step - font_width) / 2),
+                     alloc->y + padding->top + priv->header_size);
+      pango_cairo_show_layout (cr, layout);
+
+      g_free (weekday_header);
+    }
+  g_free (start_of_week);
+
+  /* draw grid_sidebar */
+  pango_layout_set_text (layout, _("All day"), -1);
+  pango_cairo_update_layout (cr, layout);
+  pango_layout_get_pixel_size (layout, &font_width, &font_height);
+  cairo_move_to (cr,
+                 alloc->x + padding->left + (( priv->grid_sidebar_size  - font_width) / 2),
+                 alloc->y + padding->top + priv->header_size + priv->grid_header_size + ((priv->vertical_step - font_height) / 2));
+  pango_cairo_show_layout (cr, layout);
+
+  for (i = 0; i < 10 / priv->hours_steps; i++)
+    {
+      gchar *hours;
+      gint n_hour;
+
+      n_hour = 8 + i * priv->hours_steps;
+      if (n_hour < 12)
+        hours = g_strdup_printf ("%d %s", n_hour, _("AM"));
+      else if (n_hour == 12)
+        hours = g_strdup_printf (_("Noon"));
+      else
+        hours = g_strdup_printf ("%d %s", n_hour - 12, _("PM"));
+
+      pango_layout_set_text (layout, hours, -1);
+      pango_cairo_update_layout (cr, layout);
+      pango_layout_get_pixel_size (layout, &font_width, &font_height);
+      cairo_move_to (cr,
+                     alloc->x + padding->left + (( priv->grid_sidebar_size  - font_width) / 2),
+                     alloc->y + padding->top + priv->header_size + priv->grid_header_size + priv->vertical_step * (i + 1) + ((priv->vertical_step - font_height) / 2));
+      pango_cairo_show_layout (cr, layout);
+
+      g_free (hours);
+    }
+
+  /* grid, vertical lines first */
+  for (i = 0; i < 8; i++)
+    {
+      cairo_move_to (cr,
+                     alloc->x + padding->left + priv->grid_sidebar_size + priv->horizontal_step * i,
+                     alloc->y + padding->top + priv->header_size + priv->grid_header_size);
+      cairo_line_to (cr,
+                     alloc->x + padding->left + priv->grid_sidebar_size + priv->horizontal_step * i,
+                     alloc->y + padding->top + priv->header_size + priv->grid_header_size + priv->vertical_step *  ((10 / priv->hours_steps) + 1));
+    }
+
+  /* rest of the lines */
+  for (i = 0; i <= 10 / priv->hours_steps + 1; i++)
+    {
+      cairo_move_to (cr,
+                     alloc->x + padding->left + priv->grid_sidebar_size,
+                     alloc->y + padding->top + priv->header_size + priv->grid_header_size + priv->vertical_step * i);
+      cairo_line_to (cr,
+                     alloc->x + padding->left + priv->grid_sidebar_size + priv->horizontal_step * 7,
+                     alloc->y + padding->top + priv->header_size + priv->grid_header_size + priv->vertical_step * i);
+    }
+
+  cairo_stroke (cr);
+
+  g_object_unref (layout);
+}
+
+static gboolean
+gcal_week_view_is_in_range (GcalView     *view,
+                             icaltimetype *date)
+{
+  //FIXME: Add implementation here.
+  // as it should return TRUE all the time.
+  return TRUE;
+}
+
+static void
+gcal_week_view_remove_by_uuid (GcalView    *view,
+                                const gchar *uuid)
+{
+  GcalWeekViewPrivate *priv;
+  gint i;
+  GList *l;
+
+  g_return_if_fail (GCAL_IS_WEEK_VIEW (view));
+  priv = GCAL_WEEK_VIEW (view)->priv;
+
+  for (i = 0; i < 7; i++)
+    {
+      for (l = priv->days[i]; l != NULL; l = l->next)
+        {
+          GcalViewChild *child;
+          const gchar* widget_uuid;
+
+          child = (GcalViewChild*) l->data;
+          widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child->widget));
+          if (g_strcmp0 (uuid, widget_uuid) == 0)
+            {
+              gtk_widget_destroy (child->widget);
+              i = 8;
+              break;
+            }
+        }
+    }
+}
+
+static GtkWidget*
+gcal_week_view_get_by_uuid (GcalView    *view,
+                            const gchar *uuid)
+{
+  GcalWeekViewPrivate *priv;
+  gint i;
+  GList *l;
+
+  g_return_val_if_fail (GCAL_IS_WEEK_VIEW (view), NULL);
+  priv = GCAL_WEEK_VIEW (view)->priv;
+
+  for (i = 0; i < 7; i++)
+    {
+      for (l = priv->days[i]; l != NULL; l = l->next)
+        {
+          GcalViewChild *child;
+          const gchar* widget_uuid;
+
+          child = (GcalViewChild*) l->data;
+          widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child->widget));
+          if (g_strcmp0 (uuid, widget_uuid) == 0)
+            return child->widget;
+        }
+    }
+  return NULL;
+}
+
+/* Public API */
+/**
+ * gcal_week_view_new:
+ * @date:
+ *
+ * Since: 0.1
+ * Return value: the new month view widget
+ * Returns: (transfer full):
+ **/
+GtkWidget*
+gcal_week_view_new (icaltimetype *date)
+{
+  return g_object_new (GCAL_TYPE_WEEK_VIEW, "date", date, NULL);
+}
+
+/**
+ * gcal_week_view_get_initial_date:
+ *
+ * Since: 0.1
+ * Return value: the first day of the month
+ * Returns: (transfer full): Release with g_free
+ **/
+icaltimetype*
+gcal_week_view_get_initial_date (GcalWeekView *view)
+{
+  GcalWeekViewPrivate *priv;
+  icaltimetype *new_date;
+
+  priv = view->priv;
+  new_date = g_new0 (icaltimetype, 1);
+  *new_date = icaltime_from_day_of_year (
+      icaltime_day_of_year (*(priv->date)) - icaltime_day_of_week (*(priv->date)) + 1,
+      priv->date->year);
+
+  return new_date;
+}
+
+/**
+ * gcal_week_view_get_final_date:
+ *
+ * Since: 0.1
+ * Return value: the last day of the month
+ * Returns: (transfer full): Release with g_free
+ **/
+icaltimetype*
+gcal_week_view_get_final_date (GcalWeekView *view)
+{
+  GcalWeekViewPrivate *priv;
+  icaltimetype *new_date;
+
+  priv = view->priv;
+  new_date = g_new0 (icaltimetype, 1);
+  *new_date = icaltime_from_day_of_year (
+      icaltime_day_of_year (*(priv->date)) + 7 - icaltime_day_of_week (*(priv->date)),
+      priv->date->year);
+
+  return new_date;
+}
diff --git a/src/gcal-week-view.h b/src/gcal-week-view.h
new file mode 100644
index 0000000..5b173d1
--- /dev/null
+++ b/src/gcal-week-view.h
@@ -0,0 +1,63 @@
+/*
+ * gcal-week-view.h
+ *
+ * Copyright (C) 2012 - Erick PÃrez Castellanos
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GCAL_WEEK_VIEW_H__
+#define __GCAL_WEEK_VIEW_H__
+
+#include <gtk/gtk.h>
+
+#include <libical/icaltime.h>
+
+G_BEGIN_DECLS
+
+#define GCAL_TYPE_WEEK_VIEW                       (gcal_week_view_get_type ())
+#define GCAL_WEEK_VIEW(obj)                       (G_TYPE_CHECK_INSTANCE_CAST((obj), GCAL_TYPE_WEEK_VIEW, GcalWeekView))
+#define GCAL_WEEK_VIEW_CLASS(klass)               (G_TYPE_CHECK_CLASS_CAST((klass), GCAL_TYPE_WEEK_VIEW, GcalWeekViewClass))
+#define GCAL_IS_WEEK_VIEW(obj)                    (G_TYPE_CHECK_INSTANCE_TYPE((obj), GCAL_TYPE_WEEK_VIEW))
+#define GCAL_IS_WEEK_VIEW_CLASS(klass)            (G_TYPE_CHECK_CLASS_TYPE((klass), GCAL_TYPE_WEEK_VIEW))
+#define GCAL_WEEK_VIEW_GET_CLASS(obj)             (G_TYPE_INSTANCE_GET_CLASS((obj), GCAL_TYPE_WEEK_VIEW, GcalWeekViewClass))
+
+typedef struct _GcalWeekView                       GcalWeekView;
+typedef struct _GcalWeekViewClass                  GcalWeekViewClass;
+typedef struct _GcalWeekViewPrivate                GcalWeekViewPrivate;
+
+struct _GcalWeekView
+{
+  GtkContainer parent;
+
+  /* add your public declarations here */
+  GcalWeekViewPrivate *priv;
+};
+
+struct _GcalWeekViewClass
+{
+  GtkContainerClass parent_class;
+};
+
+GType          gcal_week_view_get_type         (void);
+
+GtkWidget*     gcal_week_view_new              (icaltimetype  *date);
+
+icaltimetype*  gcal_week_view_get_initial_date (GcalWeekView *view);
+
+icaltimetype*  gcal_week_view_get_final_date   (GcalWeekView *view);
+
+G_END_DECLS
+
+#endif /* __GCAL_WEEK_VIEW_H__ */
diff --git a/src/gcal-window.c b/src/gcal-window.c
index 46b095b..2877e0c 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -615,7 +615,7 @@ gcal_window_events_added (GcalManager *manager,
                                       starting_date);
           gtk_widget_show (event);
           gtk_container_add (
-              GTK_CONTAINER (priv->views[GCAL_VIEW_TYPE_MONTHLY]),
+              GTK_CONTAINER (priv->views[priv->active_view]),
               event);
           gtk_style_context_add_class (gtk_widget_get_style_context (event),
                                        "event");



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