From 1dcf7c2a308edb953759b4abd5e0f8e1f94050dd Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Wed, 14 Jul 2004 02:20:55 +0000 Subject: Fixes #57287, 58748 2004-07-12 JP Rosevear Fixes #57287, 58748 * gui/tasks-component.c (source_added_cb): if the source was added in the main calendar, select it because the user caused this to happen by creating a task (create_component_view): listen for source_added signal on the tasks * gui/gnome-cal.c (view_selection_changed_cb): if the user created a task, make sure we are displaying the relevant event list (set_timezone): set the default zone of the default client (setup_widgets): listen for the user_created signal (gnome_calendar_destroy): clean up default client (client_cal_opened_cb): disconnect from the open signal (default_client_cal_opened_cb): set the default client on the models (open_ecal): make the callback function a param (gnome_calendar_add_source): include the default client when searching for an existing client (gnome_calendar_set_default_source): make the default client independent of the rest of the clients * gui/e-week-view.c (e_week_view_on_editing_stopped): emit user_created signal * gui/e-tasks.c (user_created_cb): if the user created a task, make sure we are displaying the relevant task list (set_timezone): set the timezone on the client (setup_widgets): listen for user_created signal (e_tasks_destroy): unref default client (default_client_cal_opened_cb): set the default on the model when it opens (open_ecal): open a task list (e_tasks_add_todo_source): include the default client when searching for an existing client (e_tasks_set_default_source): make the default client independent of the rest of the clients * gui/e-day-view.c (e_day_view_on_editing_stopped): emit user_created signal * gui/e-calendar-view.h: add signal proto * gui/e-calendar-view.c (e_calendar_view_class_init): add user_created signal * gui/e-calendar-table.h: add signal proto * gui/e-calendar-table.c (e_calendar_table_class_init): add user_created signal (row_appended_cb): if row is appended, emit user_created signal (e_calendar_table_init): listen for row_appended signal * gui/e-cal-model.h: add signal proto * gui/e-cal-model.c (e_cal_model_class_init): add row_appended signal (ecm_append_row): don't leak, emit row appended signal (e_cal_model_set_default_client): remove the existing default if it was only used as the default (update_e_cal_view_for_client): short circuit query create (add_new_client): look for an existing client and update its record if found, handle opening things here (e_cal_model_add_client): just call add_new_client (remove_client_objects): just remove a client's objects (remove_client): use above, handle removal of client if its default * gui/calendar-component.c (source_added_cb): if the source was added in the main calendar, select it because the user caused this to happen by creating an appointment (create_component_view): listen for source_added signal on the calendar svn path=/trunk/; revision=26644 --- calendar/gui/e-cal-model.c | 121 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 29 deletions(-) (limited to 'calendar/gui/e-cal-model.c') diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index c2d4fc57ad..ebba86d864 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -34,6 +34,8 @@ typedef struct { ECal *client; ECalView *query; + + gboolean do_query; } ECalModelClient; struct _ECalModelPrivate { @@ -88,9 +90,15 @@ static char *ecm_value_to_string (ETableModel *etm, int col, const void *value); static const char *ecm_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data); +static ECalModelClient *add_new_client (ECalModel *model, ECal *client, gboolean do_query); +static ECalModelClient *find_client_data (ECalModel *model, ECal *client); +static void remove_client_objects (ECalModel *model, ECalModelClient *client_data); +static void remove_client (ECalModel *model, ECalModelClient *client_data); + /* Signal IDs */ enum { TIME_RANGE_CHANGED, + ROW_APPENDED, LAST_SIGNAL }; @@ -135,6 +143,15 @@ e_cal_model_class_init (ECalModelClass *klass) NULL, NULL, e_calendar_marshal_VOID__LONG_LONG, G_TYPE_NONE, 2, G_TYPE_LONG, G_TYPE_LONG); + + signals[ROW_APPENDED] = + g_signal_new ("row_appended", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ECalModelClass, row_appended), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -758,9 +775,13 @@ ecm_append_row (ETableModel *etm, ETableModel *source, int row) g_warning (G_STRLOC ": Could not create the object!"); /* FIXME: show error dialog */ + icalcomponent_free (comp_data.icalcomp); + return; } icalcomponent_free (comp_data.icalcomp); + + g_signal_emit (G_OBJECT (model), signals[ROW_APPENDED], 0); } static void * @@ -1097,6 +1118,8 @@ e_cal_model_get_default_client (ECalModel *model) priv = model->priv; + /* FIXME Should we force the client to be open? */ + /* we always return a valid ECal, since we rely on it in many places */ if (priv->default_client) return priv->default_client; @@ -1113,6 +1136,7 @@ void e_cal_model_set_default_client (ECalModel *model, ECal *client) { ECalModelPrivate *priv; + ECalModelClient *client_data; g_return_if_fail (model != NULL); g_return_if_fail (E_IS_CAL_MODEL (model)); @@ -1121,11 +1145,21 @@ e_cal_model_set_default_client (ECalModel *model, ECal *client) priv = model->priv; + if (priv->default_client) { + ECalModelClient *client_data; + + client_data = find_client_data (model, priv->default_client); + g_assert (client_data); + + if (!client_data->do_query) + remove_client (model, client_data); + } + /* Make sure its in the model */ - e_cal_model_add_client (model, client); + client_data = add_new_client (model, client, FALSE); /* Store the default client */ - priv->default_client = e_cal_model_get_client_for_uri (model, e_cal_get_uri (client)); + priv->default_client = client_data->client; } /** @@ -1366,6 +1400,10 @@ update_e_cal_view_for_client (ECalModel *model, ECalModelClient *client_data) /* prepare the query */ g_assert (priv->full_sexp != NULL); + /* Don't create the new query if we won't use it */ + if (!client_data->do_query) + return; + if (!e_cal_get_query (client_data->client, priv->full_sexp, &client_data->query, NULL)) { g_warning (G_STRLOC ": Unable to get query"); @@ -1412,24 +1450,46 @@ cal_opened_cb (ECal *client, ECalendarStatus status, gpointer user_data) update_e_cal_view_for_client (model, client_data); } + static ECalModelClient * -add_new_client (ECalModel *model, ECal *client) +add_new_client (ECalModel *model, ECal *client, gboolean do_query) { ECalModelPrivate *priv; ECalModelClient *client_data; - + ECal *existing_client; + priv = model->priv; + /* Look for an existing client with the same URI */ + existing_client = e_cal_model_get_client_for_uri (model, e_cal_get_uri (client)); + if (existing_client) { + client_data = find_client_data (model, client); + g_assert (client_data); + + if (!client_data->do_query) + client_data->do_query = do_query; + + goto load; + } + client_data = g_new0 (ECalModelClient, 1); - client_data->client = client; + client_data->client = g_object_ref (client); client_data->query = NULL; - g_object_ref (client_data->client); + client_data->do_query = do_query; priv->clients = g_list_append (priv->clients, client_data); g_signal_connect (G_OBJECT (client_data->client), "backend_died", G_CALLBACK (backend_died_cb), model); + load: + if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) { + update_e_cal_view_for_client (model, client_data); + } else { + g_signal_connect (client, "cal_opened", G_CALLBACK (cal_opened_cb), model); + e_cal_open_async (client, TRUE); + } + return client_data; } @@ -1447,29 +1507,14 @@ e_cal_model_add_client (ECalModel *model, ECal *client) priv = model->priv; - if (e_cal_model_get_client_for_uri (model, e_cal_get_uri (client))) - return; - - client_data = add_new_client (model, client); - if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) { - update_e_cal_view_for_client (model, client_data); - } else { - g_signal_connect (client, "cal_opened", G_CALLBACK (cal_opened_cb), model); - e_cal_open_async (client, TRUE); - } + client_data = add_new_client (model, client, TRUE); } static void -remove_client (ECalModel *model, ECalModelClient *client_data) +remove_client_objects (ECalModel *model, ECalModelClient *client_data) { - gint i; - - g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - if (client_data->query) - g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - - model->priv->clients = g_list_remove (model->priv->clients, client_data); - + int i; + /* remove all objects belonging to this client */ for (i = model->priv->objects->len; i > 0; i--) { ECalModelComponent *comp_data = (ECalModelComponent *) g_ptr_array_index (model->priv->objects, i - 1); @@ -1485,11 +1530,29 @@ remove_client (ECalModel *model, ECalModelClient *client_data) e_table_model_row_deleted (E_TABLE_MODEL (model), i - 1); } } +} + +static void +remove_client (ECalModel *model, ECalModelClient *client_data) +{ + /* FIXME We might not want to disconnect the open signal for the default client */ + g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); + if (client_data->query) + g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); + + remove_client_objects (model, client_data); + + /* If this is the default client and we were querying (so it + * was also a source), keep it around but don't query it */ + if (model->priv->default_client == client_data->client && client_data->do_query) { + client_data->do_query = FALSE; + + return; + } + + /* Remove the client from the list */ + model->priv->clients = g_list_remove (model->priv->clients, client_data); - /* If this was the default client, unset it */ - if (model->priv->default_client == client_data->client) - model->priv->default_client = NULL; - /* free all remaining memory */ g_object_unref (client_data->client); if (client_data->query) -- cgit v1.2.3