diff --git a/src/core/gcal-calendar-monitor.c b/src/core/gcal-calendar-monitor.c index c058b87f..53c893da 100644 --- a/src/core/gcal-calendar-monitor.c +++ b/src/core/gcal-calendar-monitor.c @@ -25,6 +25,7 @@ #include "gcal-date-time-utils.h" #include "gcal-debug.h" #include "gcal-event.h" +#include "gcal-event-list.h" #include #include @@ -59,6 +60,7 @@ struct _GcalCalendarMonitor GAsyncQueue *messages; GcalCalendar *calendar; gboolean complete; + GcalEventList *event_list; const GcalCalendarMonitorListener *listener; gpointer listener_user_data; @@ -89,8 +91,10 @@ static gboolean add_events_to_timeline_in_idle_cb (gpointer static gboolean update_events_in_idle_cb (gpointer user_data); static gboolean remove_events_from_timeline_in_idle_cb (gpointer user_data); static gboolean complete_in_idle_cb (gpointer user_data); +static void g_list_model_interface_init (GListModelInterface *iface); -G_DEFINE_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_CODE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, g_list_model_interface_init)) enum { @@ -102,6 +106,48 @@ enum static GParamSpec *properties [N_PROPS] = { NULL, }; + +/* + * GListModel interface + */ + +static GType +gcal_calendar_monitor_get_item_type (GListModel *model G_GNUC_UNUSED) +{ + return GCAL_TYPE_EVENT; +} + +static guint +gcal_calendar_monitor_get_n_items (GListModel *model) +{ + GcalCalendarMonitor *self = (GcalCalendarMonitor *) model; + + g_assert (GCAL_IS_CALENDAR_MONITOR (self)); + + return g_list_model_get_n_items (G_LIST_MODEL (self->event_list)); +} + +static gpointer +gcal_calendar_monitor_get_item (GListModel *model, + guint position) +{ + GcalCalendarMonitor *self = (GcalCalendarMonitor *) model; + + g_assert (GCAL_IS_CALENDAR_MONITOR (self)); + + return g_list_model_get_item (G_LIST_MODEL (self->event_list), position); +} + + +static void +g_list_model_interface_init (GListModelInterface *iface) +{ + iface->get_item_type = gcal_calendar_monitor_get_item_type; + iface->get_n_items = gcal_calendar_monitor_get_n_items; + iface->get_item = gcal_calendar_monitor_get_item; +} + + /* * Threads * @@ -995,8 +1041,9 @@ remove_events_outside_range (GcalCalendarMonitor *self, G_RW_LOCK_WRITER_AUTO_LOCK (&self->shared.lock, writer_locker); - events_to_remove = g_ptr_array_new_full (g_hash_table_size (self->shared.events), - g_object_unref); + events_to_remove = g_ptr_array_new_null_terminated (g_hash_table_size (self->shared.events), + g_object_unref, + TRUE); g_hash_table_iter_init (&iter, self->shared.events); while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &event)) @@ -1011,7 +1058,10 @@ remove_events_outside_range (GcalCalendarMonitor *self, } if (events_to_remove->len > 0) - self->listener->remove_events (self, events_to_remove, self->listener_user_data); + { + self->listener->remove_events (self, events_to_remove, self->listener_user_data); + gcal_event_list_remove_events (self->event_list, (GcalEvent **) events_to_remove->pdata); + } } static void @@ -1028,7 +1078,10 @@ remove_all_events (GcalCalendarMonitor *self) events_to_remove = g_hash_table_steal_all_values (self->shared.events); if (events_to_remove->len > 0) - self->listener->remove_events (self, events_to_remove, self->listener_user_data); + { + self->listener->remove_events (self, events_to_remove, self->listener_user_data); + gcal_event_list_remove_all_events (self->event_list); + } } static void @@ -1087,7 +1140,10 @@ add_events_to_timeline_in_idle_cb (gpointer user_data) } if (events_to_add->len > 0) - self->listener->add_events (self, events_to_add, self->listener_user_data); + { + self->listener->add_events (self, events_to_add, self->listener_user_data); + gcal_event_list_add_events (self->event_list, (GcalEvent **) events_to_add->pdata); + } GCAL_RETURN (G_SOURCE_REMOVE); } @@ -1138,7 +1194,11 @@ update_events_in_idle_cb (gpointer user_data) g_assert (old_events->len == new_events->len); if (new_events->len > 0) - self->listener->update_events (self, old_events, new_events, self->listener_user_data); + { + self->listener->update_events (self, old_events, new_events, self->listener_user_data); + gcal_event_list_remove_events (self->event_list, (GcalEvent **) old_events->pdata); + gcal_event_list_add_events (self->event_list, (GcalEvent **) new_events->pdata); + } GCAL_RETURN (G_SOURCE_REMOVE); } @@ -1181,7 +1241,10 @@ remove_events_from_timeline_in_idle_cb (gpointer user_data) } if (events_to_remove->len > 0) - self->listener->remove_events (self, events_to_remove, self->listener_user_data); + { + self->listener->remove_events (self, events_to_remove, self->listener_user_data); + gcal_event_list_remove_events (self->event_list, (GcalEvent **) events_to_remove->pdata); + } GCAL_RETURN (G_SOURCE_REMOVE); } @@ -1253,6 +1316,7 @@ gcal_calendar_monitor_finalize (GObject *object) { GcalCalendarMonitor *self = (GcalCalendarMonitor *)object; + g_clear_object (&self->event_list); g_clear_object (&self->calendar); g_clear_pointer (&self->thread_context, g_main_context_unref); g_clear_pointer (&self->main_context, g_main_context_unref); @@ -1341,8 +1405,11 @@ gcal_calendar_monitor_init (GcalCalendarMonitor *self) self->main_context = g_main_context_ref_thread_default (); self->messages = g_async_queue_new (); self->complete = FALSE; + self->event_list = gcal_event_list_new (); g_rw_lock_init (&self->shared.lock); + + g_signal_connect_swapped (self->event_list, "items-changed", G_CALLBACK (g_list_model_items_changed), self); } GcalCalendarMonitor*