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-tasks.c | 151 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 123 insertions(+), 28 deletions(-) (limited to 'calendar/gui/e-tasks.c') diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c index 9f83428228..a935f09863 100644 --- a/calendar/gui/e-tasks.c +++ b/calendar/gui/e-tasks.c @@ -61,6 +61,7 @@ struct _ETasksPrivate { /* The task lists for display */ GHashTable *clients; GList *clients_list; + ECal *default_client; ECalView *query; @@ -88,7 +89,6 @@ struct _ETasksPrivate { GList *notifications; }; - static void e_tasks_class_init (ETasksClass *class); static void e_tasks_init (ETasks *tasks); static void setup_widgets (ETasks *tasks); @@ -178,6 +178,21 @@ table_selection_change_cb (ETable *etable, gpointer data) n_selected); } +static void +user_created_cb (GtkWidget *view, ETasks *tasks) +{ + ETasksPrivate *priv; + ECal *ecal; + ECalModel *model; + + priv = tasks->priv; + + model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); + ecal = e_cal_model_get_default_client (model); + + e_tasks_add_todo_source (tasks, e_cal_get_source (ecal)); +} + /* Callback used when the sexp in the search bar changes */ static void search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data) @@ -237,6 +252,10 @@ set_timezone (ETasks *tasks) e_cal_set_default_timezone (client, zone, NULL); } + if (priv->default_client && e_cal_get_load_state (priv->default_client) == E_CAL_LOAD_LOADED) + /* FIXME Error checking */ + e_cal_set_default_timezone (priv->default_client, zone, NULL); + if (priv->preview) e_cal_component_preview_set_default_timezone (E_CAL_COMPONENT_PREVIEW (priv->preview), zone); } @@ -477,6 +496,8 @@ setup_widgets (ETasks *tasks) priv->tasks_view = e_calendar_table_new (); priv->tasks_view_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->tasks_view)); + g_signal_connect (priv->tasks_view, "user_created", G_CALLBACK (user_created_cb), tasks); + etable = e_table_scrolled_get_table ( E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable)); e_table_set_state (etable, E_TASKS_TABLE_DEFAULT_STATE); @@ -492,6 +513,7 @@ setup_widgets (ETasks *tasks) G_CALLBACK(table_drag_data_get), tasks); g_signal_connect (etable, "table_drag_data_delete", G_CALLBACK(table_drag_data_delete), tasks); + /* e_table_drag_dest_set (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)), 0, list_drag_types, num_list_drag_types, GDK_ACTION_LINK); @@ -651,6 +673,10 @@ e_tasks_destroy (GtkObject *object) g_hash_table_destroy (priv->clients); g_list_free (priv->clients_list); + if (priv->default_client) + g_object_unref (priv->default_client); + priv->default_client = NULL; + if (priv->current_uid) { g_free (priv->current_uid); priv->current_uid = NULL; @@ -761,6 +787,8 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, ETasks *tasks) switch (status) { case E_CALENDAR_STATUS_OK : + g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL); + set_status_message (tasks, _("Loading tasks")); model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); e_cal_model_add_client (model, ecal); @@ -789,6 +817,63 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, ETasks *tasks) } } +static void +default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, ETasks *tasks) +{ + ECalModel *model; + ESource *source; + ETasksPrivate *priv; + + priv = tasks->priv; + + source = e_cal_get_source (ecal); + + switch (status) { + case E_CALENDAR_STATUS_OK : + g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL); + model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); + + set_timezone (tasks); + e_cal_model_set_default_client (model, ecal); + break; + default : + /* Make sure the source doesn't disappear on us */ + g_object_ref (source); + + priv->clients_list = g_list_remove (priv->clients_list, ecal); + g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, tasks); + + /* Do this last because it unrefs the client */ + g_hash_table_remove (priv->clients, e_cal_get_uri (ecal)); + + gtk_signal_emit (GTK_OBJECT (tasks), e_tasks_signals[SOURCE_REMOVED], source); + + set_status_message (tasks, NULL); + g_object_unref (ecal); + g_object_unref (source); + + break; + } +} + +typedef void (*open_func) (ECal *, ECalendarStatus, ETasks *); + +static gboolean +open_ecal (ETasks *tasks, ECal *cal, gboolean only_if_exists, open_func of) +{ + ETasksPrivate *priv; + + priv = tasks->priv; + + set_status_message (tasks, _("Opening tasks at %s"), e_cal_get_uri (cal)); + + g_signal_connect (G_OBJECT (cal), "cal_opened", G_CALLBACK (of), tasks); + e_cal_open_async (cal, only_if_exists); + + return TRUE; +} + void e_tasks_open_task (ETasks *tasks) { @@ -833,8 +918,6 @@ e_tasks_add_todo_source (ETasks *tasks, ESource *source) { ETasksPrivate *priv; ECal *client; - char *str_uri; - GError *error = NULL; const char *uid; g_return_val_if_fail (tasks != NULL, FALSE); @@ -845,32 +928,40 @@ e_tasks_add_todo_source (ETasks *tasks, ESource *source) uid = e_source_peek_uid (source); client = g_hash_table_lookup (priv->clients, uid); - if (client) - return TRUE; - + if (client) { + /* We already have it */ - /* FIXME Loading should be async */ - /* FIXME With no event handling here the status message never actually changes */ - str_uri = e_source_get_uri (source); - set_status_message (tasks, _("Opening tasks at %s"), str_uri); + return TRUE; + } else { + ESource *default_source; + + if (priv->default_client) { + default_source = e_cal_get_source (priv->default_client); + + /* We don't have it but the default client is it */ + if (!strcmp (e_source_peek_uid (default_source), uid)) + client = g_object_ref (priv->default_client); + } - client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO); - if (!client) { - g_free (str_uri); - return FALSE; + /* Create a new one */ + if (!client) { + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO); + if (!client) + return FALSE; + } } - g_hash_table_insert (priv->clients, g_strdup (uid) , client); - priv->clients_list = g_list_prepend (priv->clients_list, client); - g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), tasks); g_signal_connect (G_OBJECT (client), "categories_changed", G_CALLBACK (client_categories_changed_cb), tasks); g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), tasks); - g_signal_connect (G_OBJECT (client), "cal_opened", G_CALLBACK (client_cal_opened_cb), tasks); + + /* add the client to internal structure */ + g_hash_table_insert (priv->clients, g_strdup (uid) , client); + priv->clients_list = g_list_prepend (priv->clients_list, client); gtk_signal_emit (GTK_OBJECT (tasks), e_tasks_signals[SOURCE_ADDED], source); - e_cal_open_async (client, FALSE); + open_ecal (tasks, client, FALSE, client_cal_opened_cb); return TRUE; } @@ -915,8 +1006,6 @@ e_tasks_set_default_source (ETasks *tasks, ESource *source) { ETasksPrivate *priv; ECal *ecal; - ECalModel *model; - char *str_uri; g_return_val_if_fail (tasks != NULL, FALSE); g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); @@ -924,14 +1013,20 @@ e_tasks_set_default_source (ETasks *tasks, ESource *source) priv = tasks->priv; - str_uri = e_source_get_uri (source); - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - ecal = e_cal_model_get_client_for_uri (model, str_uri); - g_free (str_uri); - if (!ecal) - return FALSE; + ecal = g_hash_table_lookup (priv->clients, e_source_peek_uid (source)); + + if (priv->default_client) + g_object_unref (priv->default_client); + + if (ecal) { + priv->default_client = g_object_ref (ecal); + } else { + priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO); + if (!priv->default_client) + return FALSE; + } - e_cal_model_set_default_client (model, ecal); + open_ecal (tasks, priv->default_client, FALSE, default_client_cal_opened_cb); return TRUE; } -- cgit v1.2.3