[evolution] GnomeCalendar: Get rid of the async message dispatcher.



commit 1047848935ff20342a1ced37553ba89d710378d5
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Jun 1 00:44:44 2013 -0400

    GnomeCalendar: Get rid of the async message dispatcher.
    
    Obtain calendar views asynchronously and concurrently, and update the
    task and memo pads synchronously (they don't block as best I can tell).
    
    Get rid of the whole thread-pool message dispatching thing, which I
    think I myself wrote years ago (calendar had no async API back then).
    
    Consequently I'm seeing calendar events show up noticably quicker.

 calendar/gui/gnome-cal.c                    |  581 ++++++++++++++-------------
 modules/calendar/e-cal-shell-view-private.c |    6 +-
 2 files changed, 302 insertions(+), 285 deletions(-)
---
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 8716f5f..616a26b 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -66,6 +66,8 @@
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), GNOME_TYPE_CALENDAR, GnomeCalendarPrivate))
 
+typedef struct _ViewData ViewData;
+
 /* Private part of the GnomeCalendar structure */
 struct _GnomeCalendarPrivate {
        ESourceRegistry *registry;
@@ -86,12 +88,10 @@ struct _GnomeCalendarPrivate {
        GtkWidget   *memo_table; /* EMemoTable, but can be NULL */
        GtkWidget   *task_table; /* ETaskTable, but can be NULL */
 
-       /* Calendar query for the date navigator */
-       GMutex       dn_query_lock;
-       GList       *dn_queries; /* list of CalQueries */
+       GHashTable *date_nav_view_data;  /* set of ViewData */
+       GMutex date_nav_view_data_lock;
+
        gchar        *sexp;
-       gchar        *todo_sexp;
-       gchar        *memo_sexp;
        guint        update_timeout;
        guint        update_marcus_bains_line_timeout;
 
@@ -124,11 +124,18 @@ struct _GnomeCalendarPrivate {
         * else it uses the date range set in search bar. */
        gboolean lview_select_daten_range;
 
-       /* Used in update_todo_view, to prevent interleaving when
-        * called in separate thread. */
-       GMutex todo_update_lock;
+       GCancellable *cancellable;
+};
 
+struct _ViewData {
+       volatile gint ref_count;
+       GWeakRef gcal_weak_ref;
        GCancellable *cancellable;
+       ECalClientView *client_view;
+       gulong objects_added_handler_id;
+       gulong objects_modified_handler_id;
+       gulong objects_removed_handler_id;
+       gulong complete_handler_id;
 };
 
 enum {
@@ -159,46 +166,98 @@ static void gnome_calendar_goto_date (GnomeCalendar *gcal,
 
 static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal);
 
-static void update_todo_view (GnomeCalendar *gcal);
-static void update_memo_view (GnomeCalendar *gcal);
+static void update_task_and_memo_views (GnomeCalendar *gcal);
+
+G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, G_TYPE_OBJECT)
 
-/* Simple asynchronous message dispatcher */
-typedef struct _Message Message;
-typedef void (*MessageFunc) (Message *msg);
+static ViewData *
+view_data_new (GnomeCalendar *gcal)
+{
+       ViewData *view_data;
 
-struct _Message {
-       MessageFunc func;
-       GSourceFunc done;
-};
+       view_data = g_slice_new0 (ViewData);
+       view_data->ref_count = 1;
+       view_data->cancellable = g_cancellable_new ();
 
-static void
-message_proxy (Message *msg)
+       g_weak_ref_set (&view_data->gcal_weak_ref, gcal);
+
+       return view_data;
+}
+
+static ViewData *
+view_data_ref (ViewData *view_data)
 {
-       g_return_if_fail (msg->func != NULL);
+       g_return_val_if_fail (view_data != NULL, NULL);
+       g_return_val_if_fail (view_data->ref_count > 0, NULL);
+
+       g_atomic_int_inc (&view_data->ref_count);
 
-       msg->func (msg);
-       if (msg->done)
-               g_idle_add (msg->done, msg);
+       return view_data;
 }
 
-static gpointer
-create_thread_pool (void)
+static void
+view_data_unref (ViewData *view_data)
 {
-       /* once created, run forever */
-       return g_thread_pool_new ((GFunc) message_proxy, NULL, 1, FALSE, NULL);
+       g_return_if_fail (view_data != NULL);
+       g_return_if_fail (view_data->ref_count > 0);
+
+       if (g_atomic_int_dec_and_test (&view_data->ref_count)) {
+
+               if (view_data->objects_added_handler_id > 0)
+                       g_signal_handler_disconnect (
+                               view_data->client_view,
+                               view_data->objects_added_handler_id);
+
+               if (view_data->objects_modified_handler_id > 0)
+                       g_signal_handler_disconnect (
+                               view_data->client_view,
+                               view_data->objects_modified_handler_id);
+
+               if (view_data->objects_removed_handler_id > 0)
+                       g_signal_handler_disconnect (
+                               view_data->client_view,
+                               view_data->objects_removed_handler_id);
+
+               if (view_data->complete_handler_id > 0)
+                       g_signal_handler_disconnect (
+                               view_data->client_view,
+                               view_data->complete_handler_id);
+
+               g_weak_ref_set (&view_data->gcal_weak_ref, NULL);
+
+               g_cancellable_cancel (view_data->cancellable);
+
+               g_clear_object (&view_data->cancellable);
+               g_clear_object (&view_data->client_view);
+
+               g_slice_free (ViewData, view_data);
+       }
 }
 
 static void
-message_push (Message *msg)
+date_nav_view_data_insert (GnomeCalendar *gcal,
+                           ViewData *view_data)
 {
-       static GOnce once = G_ONCE_INIT;
+       g_return_if_fail (view_data != NULL);
 
-       g_once (&once, (GThreadFunc) create_thread_pool, NULL);
+       g_mutex_lock (&gcal->priv->date_nav_view_data_lock);
 
-       g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL);
+       g_hash_table_add (
+               gcal->priv->date_nav_view_data,
+               view_data_ref (view_data));
+
+       g_mutex_unlock (&gcal->priv->date_nav_view_data_lock);
 }
 
-G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, G_TYPE_OBJECT)
+static void
+date_nav_view_data_remove_all (GnomeCalendar *gcal)
+{
+       g_mutex_lock (&gcal->priv->date_nav_view_data_lock);
+
+       g_hash_table_remove_all (gcal->priv->date_nav_view_data);
+
+       g_mutex_unlock (&gcal->priv->date_nav_view_data_lock);
+}
 
 static void
 gcal_update_status_message (GnomeCalendar *gcal,
@@ -834,70 +893,81 @@ ensure_dates_are_in_default_zone (GnomeCalendar *gcal,
 
 /* Callback used when the calendar query reports of an updated object */
 static void
-dn_client_view_objects_added_cb (ECalClientView *view,
-                                 const GSList *objects,
-                                 gpointer data)
+gnome_cal_objects_added_cb (ECalClientView *view,
+                            const GSList *list,
+                            GWeakRef *weak_ref)
 {
        GnomeCalendar *gcal;
-       GnomeCalendarPrivate *priv;
-       const GSList *l;
 
-       gcal = GNOME_CALENDAR (data);
-       priv = gcal->priv;
+       gcal = g_weak_ref_get (weak_ref);
 
-       for (l = objects; l; l = l->next) {
-               ECalComponent *comp = NULL;
+       if (gcal != NULL) {
+               const GSList *link;
 
-               ensure_dates_are_in_default_zone (gcal, l->data);
-               comp = e_cal_component_new ();
-               if (!e_cal_component_set_icalcomponent (
-                       comp, icalcomponent_new_clone (l->data))) {
+               for (link = list; link != NULL; link = g_slist_next (link)) {
+                       ECalComponent *comp = NULL;
+                       icalcomponent *icalcomp = link->data;
+
+                       ensure_dates_are_in_default_zone (gcal, icalcomp);
+                       comp = e_cal_component_new ();
+                       if (!e_cal_component_set_icalcomponent (
+                               comp, icalcomponent_new_clone (icalcomp))) {
+                               g_object_unref (comp);
+                               continue;
+                       }
+
+                       tag_calendar_by_comp (
+                               gcal->priv->date_navigator, comp,
+                               e_cal_client_view_get_client (view),
+                               NULL, FALSE, TRUE, TRUE,
+                               gcal->priv->cancellable);
                        g_object_unref (comp);
-                       continue;
                }
 
-               tag_calendar_by_comp (
-                       priv->date_navigator, comp,
-                       e_cal_client_view_get_client (view),
-                       NULL, FALSE, TRUE, TRUE, priv->cancellable);
-               g_object_unref (comp);
+               g_object_unref (gcal);
        }
 }
 
 static void
-dn_client_view_objects_modified_cb (ECalClientView *view,
-                                    const GSList *objects,
-                                    gpointer data)
+gnome_cal_objects_modified_cb (ECalClientView *view,
+                               const GSList *objects,
+                               GWeakRef *weak_ref)
 {
        GnomeCalendar *gcal;
 
-       gcal = GNOME_CALENDAR (data);
+       gcal = g_weak_ref_get (weak_ref);
 
-       /* We have to retag the whole thing: an event may change dates
-        * and the tag_calendar_by_comp() below would not know how to
-        * untag the old dates. */
-       gnome_calendar_update_query (gcal);
+       if (gcal != NULL) {
+               /* We have to retag the whole thing: an event may change dates
+                * and the tag_calendar_by_comp() below would not know how to
+                * untag the old dates. */
+               gnome_calendar_update_query (gcal);
+               g_object_unref (gcal);
+       }
 }
 
 /* Callback used when the calendar query reports of a removed object */
 static void
-dn_client_view_objects_removed_cb (ECalClientView *view,
-                                   const GSList *ids,
-                                   gpointer data)
+gnome_cal_objects_removed_cb (ECalClientView *view,
+                              const GSList *ids,
+                              GWeakRef *weak_ref)
 {
        GnomeCalendar *gcal;
 
-       gcal = GNOME_CALENDAR (data);
+       gcal = g_weak_ref_get (weak_ref);
 
-       /* Just retag the whole thing */
-       gnome_calendar_update_query (gcal);
+       if (gcal != NULL) {
+               /* Just retag the whole thing */
+               gnome_calendar_update_query (gcal);
+               g_object_unref (gcal);
+       }
 }
 
 /* Callback used when the calendar query is done */
 static void
-dn_client_view_complete_cb (ECalClientView *query,
+gnome_cal_view_complete_cb (ECalClientView *query,
                             const GError *error,
-                            gpointer data)
+                            GWeakRef *weak_ref)
 {
        /* FIXME Better error reporting */
        if (error != NULL)
@@ -1141,128 +1211,137 @@ adjust_client_view_sexp (GnomeCalendar *gcal,
        return new_sexp;
 }
 
-struct _date_query_msg {
-       Message header;
-       GnomeCalendar *gcal;
-};
-
 static void
-free_dn_queries (GnomeCalendar *gcal)
+gnome_cal_get_client_view_cb (GObject *source_object,
+                              GAsyncResult *result,
+                              gpointer user_data)
 {
-       GList *l;
-       GnomeCalendarPrivate *priv;
-
-       priv = gcal->priv;
-
-       g_mutex_lock (&priv->dn_query_lock);
+       ECalClient *client;
+       ECalClientView *client_view = NULL;
+       GnomeCalendar *gcal;
+       ViewData *view_data;
+       GError *local_error = NULL;
+
+       client = E_CAL_CLIENT (source_object);
+       view_data = (ViewData *) user_data;
+
+       e_cal_client_get_view_finish (
+               client, result, &client_view, &local_error);
+
+       /* Sanity check. */
+       g_return_if_fail (
+               ((client_view != NULL) && (local_error == NULL)) ||
+               ((client_view == NULL) && (local_error != NULL)));
+
+       gcal = g_weak_ref_get (&view_data->gcal_weak_ref);
+
+       if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+               g_error_free (local_error);
+
+       } else if (local_error != NULL) {
+               /* FIXME This should be displayed as an EAlert. */
+               g_warning ("%s: %s", G_STRFUNC, local_error->message);
+               g_error_free (local_error);
+
+       } else if (gcal != NULL) {
+               gulong handler_id;
+
+               /* The ViewData struct is only modified from a single
+                * thread, so no locking is necessary when populating
+                * the struct members. */
+
+               view_data->client_view = g_object_ref (client_view);
+
+               handler_id = g_signal_connect_data (
+                       client_view, "objects-added",
+                       G_CALLBACK (gnome_cal_objects_added_cb),
+                       e_weak_ref_new (gcal),
+                       (GClosureNotify) e_weak_ref_free, 0);
+               view_data->objects_added_handler_id = handler_id;
+
+               handler_id = g_signal_connect_data (
+                       client_view, "objects-modified",
+                       G_CALLBACK (gnome_cal_objects_modified_cb),
+                       e_weak_ref_new (gcal),
+                       (GClosureNotify) e_weak_ref_free, 0);
+               view_data->objects_modified_handler_id = handler_id;
+
+               handler_id = g_signal_connect_data (
+                       client_view, "objects-removed",
+                       G_CALLBACK (gnome_cal_objects_removed_cb),
+                       e_weak_ref_new (gcal),
+                       (GClosureNotify) e_weak_ref_free, 0);
+               view_data->objects_removed_handler_id = handler_id;
+
+               handler_id = g_signal_connect_data (
+                       client_view, "complete",
+                       G_CALLBACK (gnome_cal_view_complete_cb),
+                       e_weak_ref_new (gcal),
+                       (GClosureNotify) e_weak_ref_free, 0);
+               view_data->complete_handler_id = handler_id;
+
+               /* XXX This call blocks with no way to cancel.  But the
+                *     ECalClientView API does not provide a proper way. */
+               e_cal_client_view_start (client_view, &local_error);
+
+               if (local_error != NULL) {
+                       g_warning ("%s: %s", G_STRFUNC, local_error->message);
+                       g_error_free (local_error);
+               }
 
-       for (l = priv->dn_queries; l != NULL; l = l->next) {
-               if (!l->data)
-                       continue;
-               g_signal_handlers_disconnect_matched (
-                       l->data, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
-               g_object_unref (l->data);
+               g_object_unref (gcal);
        }
 
-       g_list_free (priv->dn_queries);
-       priv->dn_queries = NULL;
+       g_clear_object (&client_view);
 
-       g_mutex_unlock (&priv->dn_query_lock);
+       view_data_unref (view_data);
 }
 
-static void
-update_query_async (struct _date_query_msg *msg)
+/* Restarts a query for the date navigator in the calendar */
+void
+gnome_calendar_update_query (GnomeCalendar *gcal)
 {
-       GnomeCalendar *gcal = msg->gcal;
-       GnomeCalendarPrivate *priv;
-       ECalClientView *new_view;
-       gchar *real_sexp;
        GList *list, *link;
+       gchar *real_sexp;
 
-       priv = gcal->priv;
+       g_return_if_fail (GNOME_IS_CALENDAR (gcal));
 
-       /* free the previous queries */
-       free_dn_queries (gcal);
+       e_calendar_item_clear_marks (gcal->priv->date_navigator->calitem);
 
-       g_return_if_fail (priv->sexp != NULL);
+       /* This cancels any previous view requests still in progress. */
+       date_nav_view_data_remove_all (gcal);
 
-       real_sexp = adjust_client_view_sexp (gcal, priv->sexp);
-       if (!real_sexp) {
-               return; /* No time range is set, so don't start a query */
-       }
+       g_return_if_fail (gcal->priv->sexp != NULL);
+
+       /* Don't start a query unless a time range is set. */
+       real_sexp = adjust_client_view_sexp (gcal, gcal->priv->sexp);
+       if (real_sexp == NULL)
+               return;
 
-       list = e_cal_model_list_clients (priv->model);
+       list = e_cal_model_list_clients (gcal->priv->model);
 
        /* create queries for each loaded client */
        for (link = list; link != NULL; link = g_list_next (link)) {
                ECalClient *client = E_CAL_CLIENT (link->data);
-               GError *error = NULL;
+               ViewData *view_data;
 
-               new_view = NULL;
-               if (!e_cal_client_get_view_sync (client, real_sexp, &new_view, NULL, &error)) {
-                       g_warning (G_STRLOC ": Could not create the view: %s ", error->message);
-                       g_clear_error (&error);
+               view_data = view_data_new (gcal);
+               date_nav_view_data_insert (gcal, view_data);
 
-                       continue;
-               }
+               e_cal_client_get_view (
+                       client, real_sexp,
+                       view_data->cancellable,
+                       gnome_cal_get_client_view_cb,
+                       view_data_ref (view_data));
 
-               g_signal_connect (
-                       new_view, "objects-added",
-                       G_CALLBACK (dn_client_view_objects_added_cb), gcal);
-               g_signal_connect (
-                       new_view, "objects-modified",
-                       G_CALLBACK (dn_client_view_objects_modified_cb), gcal);
-               g_signal_connect (
-                       new_view, "objects-removed",
-                       G_CALLBACK (dn_client_view_objects_removed_cb), gcal);
-               g_signal_connect (
-                       new_view, "complete",
-                       G_CALLBACK (dn_client_view_complete_cb), gcal);
-
-               g_mutex_lock (&priv->dn_query_lock);
-               priv->dn_queries = g_list_append (priv->dn_queries, new_view);
-               e_cal_client_view_start (new_view, &error);
-               if (error != NULL) {
-                       g_warning (
-                               "%s: Failed to start view: %s",
-                               G_STRFUNC, error->message);
-                       g_clear_error (&error);
-               }
-               g_mutex_unlock (&priv->dn_query_lock);
+               view_data_unref (view_data);
        }
 
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
-       /* free memory */
        g_free (real_sexp);
-       update_todo_view (gcal);
-}
-
-static gboolean
-update_query_done (struct _date_query_msg *msg)
-{
-       g_object_unref (msg->gcal);
-       g_slice_free (struct _date_query_msg, msg);
 
-       return FALSE;
-}
-
-/* Restarts a query for the date navigator in the calendar */
-void
-gnome_calendar_update_query (GnomeCalendar *gcal)
-{
-       struct _date_query_msg *msg;
-
-       g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
-       e_calendar_item_clear_marks (gcal->priv->date_navigator->calitem);
-
-       msg = g_slice_new0 (struct _date_query_msg);
-       msg->header.func = (MessageFunc) update_query_async;
-       msg->header.done = (GSourceFunc) update_query_done;
-       msg->gcal = g_object_ref (gcal);
-
-       message_push ((Message *) msg);
+       update_task_and_memo_views (gcal);
 }
 
 void
@@ -1313,141 +1392,74 @@ gnome_calendar_set_search_query (GnomeCalendar *gcal,
                e_cal_model_set_search_query (model, sexp);
 }
 
-struct _mupdate_todo_msg {
-       Message header;
-       GnomeCalendar *gcal;
-};
-
 static void
-update_todo_view_async (struct _mupdate_todo_msg *msg)
-{
-       GnomeCalendar *gcal;
-       GnomeCalendarPrivate *priv;
-       ECalModel *model;
-       gchar *sexp = NULL;
-
-       g_return_if_fail (msg != NULL);
-
-       gcal = msg->gcal;
-       priv = gcal->priv;
-
-       g_return_if_fail (priv->task_table != NULL);
-
-       g_mutex_lock (&priv->todo_update_lock);
-
-       /* Set the query on the task pad */
-       if (priv->todo_sexp) {
-               g_free (priv->todo_sexp);
-               priv->todo_sexp = NULL;
-       }
-
-       model = e_task_table_get_model (E_TASK_TABLE (priv->task_table));
-
-       if ((sexp = calendar_config_get_hide_completed_tasks_sexp (FALSE)) != NULL) {
-               priv->todo_sexp = g_strdup_printf (
-                       "(and %s %s)", sexp,
-                       priv->sexp ? priv->sexp : "");
-               e_cal_model_set_search_query (model, priv->todo_sexp);
-               g_free (sexp);
-       } else {
-               priv->todo_sexp = g_strdup (priv->sexp);
-               e_cal_model_set_search_query (model, priv->todo_sexp);
-       }
-
-       update_memo_view (msg->gcal);
-
-       g_mutex_unlock (&priv->todo_update_lock);
-}
-
-static gboolean
-update_todo_view_done (struct _mupdate_todo_msg *msg)
+update_task_and_memo_views (GnomeCalendar *gcal)
 {
+       ECalModel *memo_model;
+       ECalModel *task_model;
+       ECalModel *view_model;
        EMemoTable *memo_table;
        ETaskTable *task_table;
-       EShellView *shell_view;
-       GnomeCalendar *gcal;
-
-       g_return_val_if_fail (msg != NULL, FALSE);
-
-       gcal = msg->gcal;
+       time_t start = -1, end = -1;
+       gchar *hide_completed_tasks_sexp;
 
-       g_return_val_if_fail (gcal->priv->task_table != NULL, FALSE);
-       g_return_val_if_fail (gcal->priv->memo_table != NULL, FALSE);
+       /* Set the query on the task pad. */
 
        task_table = E_TASK_TABLE (gcal->priv->task_table);
-       shell_view = e_task_table_get_shell_view (task_table);
-       e_shell_view_unblock_update_actions (shell_view);
+       task_model = e_task_table_get_model (task_table);
 
-       memo_table = E_MEMO_TABLE (gcal->priv->memo_table);
-       shell_view = e_memo_table_get_shell_view (memo_table);
-       e_shell_view_unblock_update_actions (shell_view);
-
-       g_object_unref (msg->gcal);
-       g_slice_free (struct _mupdate_todo_msg, msg);
-
-       return FALSE;
-}
+       hide_completed_tasks_sexp =
+               calendar_config_get_hide_completed_tasks_sexp (FALSE);
 
-static void
-update_todo_view (GnomeCalendar *gcal)
-{
-       EMemoTable *memo_table;
-       ETaskTable *task_table;
-       EShellView *shell_view;
-       struct _mupdate_todo_msg *msg;
+       if (hide_completed_tasks_sexp != NULL) {
+               if (gcal->priv->sexp != NULL) {
+                       gchar *sexp;
 
-       /* they are both or none anyway */
-       if (!gcal->priv->task_table || !gcal->priv->memo_table)
-               return;
+                       sexp = g_strdup_printf (
+                               "(and %s %s)",
+                               hide_completed_tasks_sexp,
+                               gcal->priv->sexp);
+                       e_cal_model_set_search_query (task_model, sexp);
+                       g_free (sexp);
+               } else {
+                       e_cal_model_set_search_query (
+                               task_model, hide_completed_tasks_sexp);
+               }
+       } else {
+               e_cal_model_set_search_query (task_model, gcal->priv->sexp);
+       }
 
-       msg = g_slice_new0 (struct _mupdate_todo_msg);
-       msg->header.func = (MessageFunc) update_todo_view_async;
-       msg->header.done = (GSourceFunc) update_todo_view_done;
-       msg->gcal = g_object_ref (gcal);
+       g_free (hide_completed_tasks_sexp);
 
-       task_table = E_TASK_TABLE (gcal->priv->task_table);
-       shell_view = e_task_table_get_shell_view (task_table);
-       e_shell_view_block_update_actions (shell_view);
+       /* Set the query on the memo pad. */
 
        memo_table = E_MEMO_TABLE (gcal->priv->memo_table);
-       shell_view = e_memo_table_get_shell_view (memo_table);
-       e_shell_view_block_update_actions (shell_view);
-
-       message_push ((Message *) msg);
-}
-
-static void
-update_memo_view (GnomeCalendar *gcal)
-{
-       GnomeCalendarPrivate *priv;
-       ECalModel *model, *view_model;
-       time_t start = -1, end = -1;
-       gchar *iso_start, *iso_end;
-
-       priv = gcal->priv;
-       if (!priv->memo_table)
-               return;
+       memo_model = e_memo_table_get_model (memo_table);
 
-       /* Set the query on the memo pad*/
-       model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo_table));
        view_model = gnome_calendar_get_model (gcal);
        e_cal_model_get_time_range (view_model, &start, &end);
 
        if (start != -1 && end != -1) {
+               gchar *iso_start;
+               gchar *iso_end;
+               gchar *sexp;
+
                iso_start = isodate_from_time_t (start);
                iso_end = isodate_from_time_t (end);
 
-               g_free (priv->memo_sexp);
+               sexp = g_strdup_printf (
+                       "(and (or (not (has-start?)) "
+                       "(occur-in-time-range? (make-time \"%s\") "
+                       "(make-time \"%s\") \"%s\")) %s)",
+                       iso_start, iso_end,
+                       gcal_get_default_tzloc (gcal),
+                       gcal->priv->sexp ? gcal->priv->sexp : "");
 
-               priv->memo_sexp = g_strdup_printf (
-                       "(and (or (not (has-start?)) (occur-in-time-range? (make-time \"%s\") (make-time 
\"%s\") \"%s\")) %s)",
-                       iso_start, iso_end, gcal_get_default_tzloc (gcal),
-                       priv->sexp ? priv->sexp : "");
-
-               e_cal_model_set_search_query (model, priv->memo_sexp);
+               e_cal_model_set_search_query (memo_model, sexp);
 
                g_free (iso_start);
                g_free (iso_end);
+               g_free (sexp);
        }
 }
 
@@ -1490,13 +1502,13 @@ setup_widgets (GnomeCalendar *gcal)
 
        priv = gcal->priv;
 
-       /* update_todo_view (gcal); */
+       /* update_task_and_memo_views (gcal); */
 
        /* Timeout check to hide completed items */
 #if 0 /* KILL-BONOBO */
        priv->update_timeout = g_timeout_add_full (
                G_PRIORITY_LOW, 60000, (GSourceFunc)
-               update_todo_view_cb, gcal, NULL);
+               update_task_and_memo_views_cb, gcal, NULL);
 #endif
 
        /* The Marcus Bains line */
@@ -1511,10 +1523,17 @@ setup_widgets (GnomeCalendar *gcal)
 static void
 gnome_calendar_init (GnomeCalendar *gcal)
 {
+       GHashTable *date_nav_view_data;
+
+       date_nav_view_data = g_hash_table_new_full (
+               (GHashFunc) g_direct_hash,
+               (GEqualFunc) g_direct_equal,
+               (GDestroyNotify) view_data_unref,
+               (GDestroyNotify) NULL);
+
        gcal->priv = GNOME_CALENDAR_GET_PRIVATE (gcal);
 
-       g_mutex_init (&gcal->priv->todo_update_lock);
-       g_mutex_init (&gcal->priv->dn_query_lock);
+       g_mutex_init (&gcal->priv->date_nav_view_data_lock);
 
        gcal->priv->current_view_type = GNOME_CAL_WORK_WEEK_VIEW;
        gcal->priv->range_selected = FALSE;
@@ -1522,10 +1541,9 @@ gnome_calendar_init (GnomeCalendar *gcal)
 
        setup_widgets (gcal);
 
-       gcal->priv->dn_queries = NULL;
+       gcal->priv->date_nav_view_data = date_nav_view_data;
+
        gcal->priv->sexp = g_strdup ("#t"); /* Match all */
-       gcal->priv->todo_sexp = g_strdup ("#t");
-       gcal->priv->memo_sexp = g_strdup ("#t");
 
        gcal->priv->visible_start = -1;
        gcal->priv->visible_end = -1;
@@ -1563,7 +1581,7 @@ gnome_calendar_do_dispose (GObject *object)
                }
        }
 
-       free_dn_queries (GNOME_CALENDAR (object));
+       g_hash_table_remove_all (priv->date_nav_view_data);
 
        if (priv->sexp) {
                g_free (priv->sexp);
@@ -1597,8 +1615,9 @@ gnome_calendar_finalize (GObject *object)
 
        priv = GNOME_CALENDAR_GET_PRIVATE (object);
 
-       g_mutex_clear (&priv->todo_update_lock);
-       g_mutex_clear (&priv->dn_query_lock);
+       g_mutex_clear (&priv->date_nav_view_data_lock);
+
+       g_hash_table_destroy (priv->date_nav_view_data);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (gnome_calendar_parent_class)->finalize (object);
@@ -2283,7 +2302,7 @@ gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal)
                gtk_widget_queue_draw (GTK_WIDGET (calendar_view));
                g_signal_emit (gcal, signals[DATES_SHOWN_CHANGED], 0);
        }
-       update_todo_view (gcal);
+       update_task_and_memo_views (gcal);
 }
 
 /* Returns the number of selected events (0 or 1 at present). */
diff --git a/modules/calendar/e-cal-shell-view-private.c b/modules/calendar/e-cal-shell-view-private.c
index f8d455e..a03da04 100644
--- a/modules/calendar/e-cal-shell-view-private.c
+++ b/modules/calendar/e-cal-shell-view-private.c
@@ -586,10 +586,8 @@ e_cal_shell_view_private_constructed (ECalShellView *cal_shell_view)
 
        /* Give GnomeCalendar a handle to the date navigator, memo and task table. */
        gnome_calendar_set_date_navigator (calendar, date_navigator);
-       gnome_calendar_set_memo_table (
-               calendar, memo_table ? GTK_WIDGET (memo_table) : NULL);
-       gnome_calendar_set_task_table (
-               calendar, task_table ? GTK_WIDGET (task_table) : NULL);
+       gnome_calendar_set_memo_table (calendar, GTK_WIDGET (memo_table));
+       gnome_calendar_set_task_table (calendar, GTK_WIDGET (task_table));
 
        e_calendar_item_set_get_time_callback (
                date_navigator->calitem, (ECalendarItemGetTimeCallback)


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