[gnome-calendar] event: implement GInitable



commit f1069c96d6e63f5f3f643080bb92bf29c20de4f6
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Sep 28 00:07:28 2016 -0300

    event: implement GInitable
    
    Since the event creation can fail, lets make it a GInitable
    so that we can fail during initialization.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763166

 src/gcal-event.c             |   95 ++++++++++++++++++++++++++++++++++++++----
 src/gcal-event.h             |   12 +++++-
 src/gcal-manager.c           |   14 +++++-
 src/gcal-quick-add-popover.c |    2 +-
 src/gcal-search-view.c       |   17 ++++---
 src/gcal-subscriber-view.c   |   24 ++++++++++-
 src/gcal-window.c            |    2 +-
 src/gcal-year-view.c         |   13 +++++-
 8 files changed, 155 insertions(+), 24 deletions(-)
---
diff --git a/src/gcal-event.c b/src/gcal-event.c
index 408604b..3f920e3 100644
--- a/src/gcal-event.c
+++ b/src/gcal-event.c
@@ -48,9 +48,16 @@ struct _GcalEvent
 
   ECalComponent      *component;
   ESource            *source;
+
+  gboolean            is_valid : 1;
+  gboolean            is_initialized : 1;
+  GError             *initialization_error;
 };
 
-G_DEFINE_TYPE (GcalEvent, gcal_event, G_TYPE_OBJECT)
+static void          gcal_event_initable_iface_init              (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcalEvent, gcal_event, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gcal_event_initable_iface_init))
 
 enum {
   PROP_0,
@@ -237,6 +244,23 @@ gcal_event_set_component_internal (GcalEvent     *self,
 
       /* Setup start date */
       e_cal_component_get_dtstart (component, &start);
+
+      /*
+       * A NULL start date is invalid. We set something bogus to procceed, and make
+       * it set a GError and return NULL.
+       */
+      if (!start.value)
+        {
+          self->is_valid = FALSE;
+          g_set_error (&self->initialization_error,
+                       GCAL_EVENT_ERROR,
+                       GCAL_EVENT_ERROR_INVALID_START_DATE,
+                       "Event '%s' has an invalid start date", gcal_event_get_uid (self));
+
+          start.value = g_new0 (icaltimetype, 1);
+          *start.value = icaltime_today ();
+        }
+
       date = icaltime_normalize (*start.value);
       zone_start = get_timezone_from_ical (&start);
       date_start = g_date_time_new (zone_start,
@@ -300,6 +324,44 @@ gcal_event_set_component_internal (GcalEvent     *self,
     }
 }
 
+/*
+ * GInitable iface implementation
+ */
+
+G_LOCK_DEFINE_STATIC (init_lock);
+
+static gboolean
+gcal_event_initable_init (GInitable     *initable,
+                          GCancellable  *cancellable,
+                          GError       **error)
+{
+  GcalEvent *self;
+
+  self = GCAL_EVENT (initable);
+
+  G_LOCK (init_lock);
+
+  if (self->is_initialized)
+    goto out;
+
+
+out:
+  self->is_initialized = TRUE;
+
+  if (!self->is_valid)
+    g_propagate_error (error, g_error_copy (self->initialization_error));
+
+  G_UNLOCK (init_lock);
+
+  return self->is_valid;
+}
+
+static void
+gcal_event_initable_iface_init (GInitableIface *iface)
+{
+  iface->init = gcal_event_initable_init;
+}
+
 static void
 gcal_event_finalize (GObject *object)
 {
@@ -593,27 +655,44 @@ gcal_event_init (GcalEvent *self)
 
   /* Alarms */
   self->alarms = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+
+  self->is_valid = TRUE;
+}
+
+/**
+ * gcal_event_error_quark:
+ *
+ * Error quark for event creating.
+ */
+GQuark
+gcal_event_error_quark (void)
+{
+  return g_quark_from_static_string ("Invalid start date");
 }
 
 /**
  * gcal_event_new:
  * @source: (nullable): an #ESource
  * @component: a #ECalComponent
+ * @error: (nullable): return location for a #GError
  *
  * Creates a new event which belongs to @source and
  * is represented by @component. New events will have
  * a %NULL @source.
  *
- * Returns: (transfer full): a #GcalEvent
+ * Returns: (transfer full)(nullable): a #GcalEvent
  */
 GcalEvent*
-gcal_event_new (ESource       *source,
-                ECalComponent *component)
+gcal_event_new (ESource        *source,
+                ECalComponent  *component,
+                GError        **error)
 {
-  return g_object_new (GCAL_TYPE_EVENT,
-                       "source", source,
-                       "component", component,
-                       NULL);
+  return g_initable_new (GCAL_TYPE_EVENT,
+                         NULL,
+                         error,
+                         "source", source,
+                         "component", component,
+                         NULL);
 }
 
 /**
diff --git a/src/gcal-event.h b/src/gcal-event.h
index 16dc19a..ce21b22 100644
--- a/src/gcal-event.h
+++ b/src/gcal-event.h
@@ -26,12 +26,22 @@
 
 G_BEGIN_DECLS
 
+typedef enum
+{
+  GCAL_EVENT_ERROR_INVALID_START_DATE
+} GcalEventError;
+
+#define GCAL_EVENT_ERROR gcal_event_error_quark ()
+
 #define GCAL_TYPE_EVENT (gcal_event_get_type())
 
 G_DECLARE_FINAL_TYPE (GcalEvent, gcal_event, GCAL, EVENT, GObject)
 
+GQuark               gcal_event_error_quark                      (void);
+
 GcalEvent*           gcal_event_new                              (ESource            *source,
-                                                                  ECalComponent      *component);
+                                                                  ECalComponent      *component,
+                                                                  GError            **error);
 
 gboolean             gcal_event_get_all_day                      (GcalEvent          *self);
 
diff --git a/src/gcal-manager.c b/src/gcal-manager.c
index 4f96634..fd25f21 100644
--- a/src/gcal-manager.c
+++ b/src/gcal-manager.c
@@ -274,10 +274,20 @@ gather_events (ECalDataModel         *data_model,
                time_t                 instance_end,
                gpointer               user_data)
 {
-  GList **result = user_data;
   GcalEvent *event;
+  GError *error;
+  GList **result;
+
+  error = NULL;
+  result = user_data;
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
 
-  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp);
+  if (error)
+    {
+      g_warning ("Error: %s", error->message);
+      g_clear_error (&error);
+      return TRUE;
+    }
 
   *result = g_list_append (*result, event);/* FIXME: add me sorted */
 
diff --git a/src/gcal-quick-add-popover.c b/src/gcal-quick-add-popover.c
index e129876..d3f61e9 100644
--- a/src/gcal-quick-add-popover.c
+++ b/src/gcal-quick-add-popover.c
@@ -465,7 +465,7 @@ edit_or_create_event (GcalQuickAddPopover *self,
   /* Create an ECalComponent from the data above */
   component = build_component_from_details (summary, date_start, date_end);
 
-  event = gcal_event_new (source, component);
+  event = gcal_event_new (source, component, NULL);
   gcal_event_set_all_day (event, all_day);
   gcal_event_set_timezone (event, tz);
 
diff --git a/src/gcal-search-view.c b/src/gcal-search-view.c
index b8a13e3..2c3a3c8 100644
--- a/src/gcal-search-view.c
+++ b/src/gcal-search-view.c
@@ -574,18 +574,21 @@ gcal_search_view_component_added (ECalDataModelSubscriber *subscriber,
 
   RowEventData *row_data;
   GcalEvent *event;
+  GError *error;
   gchar *uid;
 
   view = GCAL_SEARCH_VIEW (subscriber);
-
-  e_cal_component_get_dtstart (comp, &dt);
-
-  /* Protect against NULL start date */
-  if (dt.value == NULL)
-    return;
+  error = NULL;
 
   /* event */
-  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp);
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
+
+  if (error)
+    {
+      g_warning ("Error creating event: %s", error->message);
+      g_clear_error (&error);
+      return;
+    }
 
   /* insert row_data at the hash of events */
   row_data = g_new0 (RowEventData, 1);
diff --git a/src/gcal-subscriber-view.c b/src/gcal-subscriber-view.c
index 550ad41..79bb8d0 100644
--- a/src/gcal-subscriber-view.c
+++ b/src/gcal-subscriber-view.c
@@ -370,8 +370,18 @@ gcal_subscriber_view_component_added (ECalDataModelSubscriber *subscriber,
 {
   GtkWidget *event_widget;
   GcalEvent *event;
+  GError *error;
+
+  error = NULL;
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
+
+  if (error)
+    {
+      g_message ("Error creating event: %s", error->message);
+      g_clear_error (&error);
+      return;
+    }
 
-  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)));
 
@@ -390,9 +400,19 @@ gcal_subscriber_view_component_modified (ECalDataModelSubscriber *subscriber,
   GList *l;
   GtkWidget *new_widget;
   GcalEvent *event;
+  GError *error;
 
+  error = NULL;
   priv = gcal_subscriber_view_get_instance_private (GCAL_SUBSCRIBER_VIEW (subscriber));
-  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp);
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
+
+  if (error)
+    {
+      g_message ("Error creating event: %s", error->message);
+      g_clear_error (&error);
+      return;
+    }
+
   new_widget = gcal_event_widget_new (event);
 
   l = g_hash_table_lookup (priv->children, gcal_event_get_uid (event));
diff --git a/src/gcal-window.c b/src/gcal-window.c
index 3864ce3..57ad392 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -1061,7 +1061,7 @@ create_event_detailed_cb (GcalView *view,
   GcalEvent *event;
 
   comp = build_component_from_details ("", start_span, end_span);
-  event = gcal_event_new (gcal_manager_get_default_source (window->manager), comp);
+  event = gcal_event_new (gcal_manager_get_default_source (window->manager), comp, NULL);
 
   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);
diff --git a/src/gcal-year-view.c b/src/gcal-year-view.c
index 83289bb..7bf2979 100644
--- a/src/gcal-year-view.c
+++ b/src/gcal-year-view.c
@@ -1619,6 +1619,7 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
   GcalYearView *year_view = GCAL_YEAR_VIEW (subscriber);
 
   GcalEvent *event;
+  GError *error;
   GList **days_widgets_array;
   GList *l;
   gint i, days_span;
@@ -1627,12 +1628,20 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
   time_t event_start, event_end, range_start, range_end;
   icaltimezone *zone;
 
+  error = NULL;
+  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, &error);
+
+  if (error)
+    {
+      g_warning ("Error creating event: %s", error->message);
+      g_clear_error (&error);
+      return;
+    }
+
   update_selected_dates_from_button_data (year_view);
   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);
 
-  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);
   range_start = icaltime_as_timet_with_zone (*(year_view->start_selected_date), zone);


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