From 8b1e261b3e451e1a28176cc1b835634a1a30d0d8 Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Sun, 16 Nov 2003 22:37:13 +0000 Subject: add it via e-tasks (remove_uri_for_source): remove it via e-tasks 2003-11-16 JP Rosevear * gui/tasks-component.c (add_uri_for_source): add it via e-tasks (remove_uri_for_source): remove it via e-tasks (get_default_task): provide a default for editing (impl_createControls): create the control directly (impl_requestCreateItem): implement * gui/gnome-cal.c (gnome_calendar_purge): don't let the two list iterators clobber each other * gui/e-tasks.h: add protos * gui/e-tasks.c (e_tasks_destroy): free the client list and the hash, disconnect signals (e_tasks_new_task): use the default client (e_tasks_add_todo_uri): add a uri (e_tasks_remove_todo_uri): remove a uri (e_tasks_set_default_uri): set default uri (e_tasks_get_default_client): get default client (e_tasks_delete_completed): expunge from all clients (e_tasks_setup_view_menus): use default client uri * gui/e-tasks.c (set_timezone): set the timezone for all clients (e_tasks_init): set up the clients has table * gui/e-calendar-table.etspec: yank some useless display columns * gui/e-cal-model.c (remove_client): remove objects in reverse order so we don't clobber ourselves * gui/calendar-component.c: add FIXME svn path=/trunk/; revision=23373 --- calendar/ChangeLog | 33 ++++++ calendar/gui/calendar-component.c | 1 + calendar/gui/e-cal-model.c | 4 +- calendar/gui/e-calendar-table.etspec | 2 - calendar/gui/e-tasks.c | 198 +++++++++++++++++++++++++++++------ calendar/gui/e-tasks.h | 4 + calendar/gui/gnome-cal.c | 31 +++--- calendar/gui/tasks-component.c | 96 ++++++++++++----- 8 files changed, 284 insertions(+), 85 deletions(-) (limited to 'calendar') diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 535d877c09..c7c7cae7e5 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,36 @@ +2003-11-16 JP Rosevear + + * gui/tasks-component.c (add_uri_for_source): add it via e-tasks + (remove_uri_for_source): remove it via e-tasks + (get_default_task): provide a default for editing + (impl_createControls): create the control directly + (impl_requestCreateItem): implement + + * gui/gnome-cal.c (gnome_calendar_purge): don't let the two list + iterators clobber each other + + * gui/e-tasks.h: add protos + + * gui/e-tasks.c (e_tasks_destroy): free the client list and the + hash, disconnect signals + (e_tasks_new_task): use the default client + (e_tasks_add_todo_uri): add a uri + (e_tasks_remove_todo_uri): remove a uri + (e_tasks_set_default_uri): set default uri + (e_tasks_get_default_client): get default client + (e_tasks_delete_completed): expunge from all clients + (e_tasks_setup_view_menus): use default client uri + + * gui/e-tasks.c (set_timezone): set the timezone for all clients + (e_tasks_init): set up the clients has table + + * gui/e-calendar-table.etspec: yank some useless display columns + + * gui/e-cal-model.c (remove_client): remove objects in reverse + order so we don't clobber ourselves + + * gui/calendar-component.c: add FIXME + 2003-11-16 JP Rosevear * gui/calendar-component.c (get_default_event): set up a event to diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index 7e89f6f0fa..74d87ec3fe 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -64,6 +64,7 @@ struct _CalendarComponentPrivate { guint selected_not; }; +/* FIXME This should be gnome cal likely */ extern ECompEditorRegistry *comp_editor_registry; /* Utility functions. */ diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index 5211515c9a..bd5a6ec324 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -1355,8 +1355,8 @@ remove_client (ECalModel *model, ECalModelClient *client_data) /* remove all objects belonging to this client */ e_table_model_pre_change (E_TABLE_MODEL (model)); - for (i = 0; i < model->priv->objects->len; i++) { - ECalModelComponent *comp_data = (ECalModelComponent *) g_ptr_array_index (model->priv->objects, i); + for (i = model->priv->objects->len; i > 0; i--) { + ECalModelComponent *comp_data = (ECalModelComponent *) g_ptr_array_index (model->priv->objects, i - 1); g_assert (comp_data != NULL); diff --git a/calendar/gui/e-calendar-table.etspec b/calendar/gui/e-calendar-table.etspec index 2021ab0037..2d87771d53 100644 --- a/calendar/gui/e-calendar-table.etspec +++ b/calendar/gui/e-calendar-table.etspec @@ -1,8 +1,6 @@ - - diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c index 3e4a47e17a..ae915e49e2 100644 --- a/calendar/gui/e-tasks.c +++ b/calendar/gui/e-tasks.c @@ -52,9 +52,11 @@ /* Private part of the GnomeCalendar structure */ struct _ETasksPrivate { - /* The calendar client object we monitor */ - ECal *client; - ECalView *query; + /* The task lists for display */ + GHashTable *clients; + GList *clients_list; + + ECalView *query; /* The ECalendarTable showing the tasks. */ GtkWidget *tasks_view; @@ -425,7 +427,8 @@ set_timezone (ETasks *tasks) ETasksPrivate *priv; char *location; icaltimezone *zone; - + GList *l; + priv = tasks->priv; location = calendar_config_get_timezone (); @@ -435,9 +438,13 @@ set_timezone (ETasks *tasks) if (!zone) zone = icaltimezone_get_utc_timezone (); - if (e_cal_get_load_state (priv->client) == E_CAL_LOAD_LOADED) - /* FIXME Error checking */ - e_cal_set_default_timezone (priv->client, zone, NULL); + for (l = priv->clients_list; l != NULL; l = l->next) { + ECal *client = l->data; + + if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) + /* FIXME Error checking */ + e_cal_set_default_timezone (client, zone, NULL); + } } static void @@ -572,7 +579,7 @@ e_tasks_init (ETasks *tasks) setup_config (tasks); setup_widgets (tasks); - priv->client = NULL; + priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); priv->query = NULL; priv->view_instance = NULL; priv->view_menus = NULL; @@ -649,12 +656,16 @@ e_tasks_destroy (GtkObject *object) if (priv) { GList *l; - - if (priv->client) { - g_object_unref (priv->client); - priv->client = NULL; + + /* disconnect from signals on all the clients */ + for (l = priv->clients_list; l != NULL; l = l->next) { + g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, tasks); } - + + g_hash_table_destroy (priv->clients); + g_list_free (priv->clients_list); + if (priv->current_uid) { g_free (priv->current_uid); priv->current_uid = NULL; @@ -691,6 +702,7 @@ gboolean e_tasks_open (ETasks *tasks, char *file) { +#if 0 ETasksPrivate *priv; char *message; EUri *uri; @@ -747,7 +759,7 @@ e_tasks_open (ETasks *tasks, g_free (real_uri); e_uri_free (uri); - +#endif return TRUE; } @@ -864,24 +876,133 @@ e_tasks_new_task (ETasks *tasks) TaskEditor *tedit; ECalComponent *comp; const char *category; - + ECal *ecal; + g_return_if_fail (E_IS_TASKS (tasks)); priv = tasks->priv; - tedit = task_editor_new (priv->client); - - comp = cal_comp_task_new_with_defaults (priv->client); + /* FIXME What to do about no default client */ + ecal = e_tasks_get_default_client (tasks); + if (!ecal) + return; + + comp = cal_comp_task_new_with_defaults (ecal); category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); e_cal_component_set_categories (comp, category); + tedit = task_editor_new (ecal); comp_editor_edit_comp (COMP_EDITOR (tedit), comp); g_object_unref (comp); comp_editor_focus (COMP_EDITOR (tedit)); } +gboolean +e_tasks_add_todo_uri (ETasks *tasks, const char *str_uri) +{ + ETasksPrivate *priv; + ECal *client; + ECalModel *model; + + g_return_val_if_fail (tasks != NULL, FALSE); + g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); + g_return_val_if_fail (str_uri != NULL, FALSE); + + priv = tasks->priv; + + client = g_hash_table_lookup (priv->clients, str_uri); + if (client) + return TRUE; + + client = e_cal_new (str_uri, CALOBJ_TYPE_TODO); + g_hash_table_insert (priv->clients, g_strdup (str_uri), 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); + + if (!e_cal_open (client, FALSE, NULL)) { + g_hash_table_remove (priv->clients, str_uri); + priv->clients_list = g_list_prepend (priv->clients_list, client); + g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, tasks); + + return FALSE; + } + + model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); + e_cal_model_add_client (model, client); + + return TRUE; +} + +gboolean +e_tasks_remove_todo_uri (ETasks *tasks, const char *str_uri) +{ + ETasksPrivate *priv; + ECal *client; + ECalModel *model; + + g_return_val_if_fail (tasks != NULL, FALSE); + g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); + g_return_val_if_fail (str_uri != NULL, FALSE); + + priv = tasks->priv; + + client = g_hash_table_lookup (priv->clients, str_uri); + if (!client) + return TRUE; + + g_hash_table_remove (priv->clients, str_uri); + priv->clients_list = g_list_remove (priv->clients_list, client); + g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, tasks); + + model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); + e_cal_model_remove_client (model, client); + + return TRUE; +} + +gboolean +e_tasks_set_default_uri (ETasks *tasks, const char *str_uri) +{ + ETasksPrivate *priv; + ECal *ecal; + ECalModel *model; + + g_return_val_if_fail (tasks != NULL, FALSE); + g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); + g_return_val_if_fail (str_uri != NULL, FALSE); + + priv = tasks->priv; + + ecal = g_hash_table_lookup (priv->clients, str_uri); + if (!ecal) + return FALSE; + + model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); + e_cal_model_set_default_client (model, ecal); + + return TRUE; +} + +ECal * +e_tasks_get_default_client (ETasks *tasks) +{ + ETasksPrivate *priv; + + g_return_val_if_fail (tasks != NULL, NULL); + g_return_val_if_fail (E_IS_TASKS (tasks), NULL); + + priv = tasks->priv; + + return e_cal_model_get_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view))); +} + /** * e_tasks_complete_selected: * @tasks: A tasks control widget @@ -940,33 +1061,42 @@ e_tasks_delete_completed (ETasks *tasks) { ETasksPrivate *priv; char *sexp; - GList *objects, *l; + GList *l; g_return_if_fail (tasks != NULL); g_return_if_fail (E_IS_TASKS (tasks)); priv = tasks->priv; - /* FIXME Confirm expunge */ - - set_status_message (tasks, _("Expunging")); - sexp = g_strdup ("(is-completed?)"); - if (!e_cal_get_object_list (priv->client, sexp, &objects, NULL)) { - set_status_message (tasks, NULL); - g_free (sexp); - g_warning (G_STRLOC ": Could not get the objects"); - return; - } - g_free (sexp); + set_status_message (tasks, _("Expunging")); - for (l = objects; l; l = l->next) { - /* FIXME Better error handling */ - e_cal_remove_object (priv->client, icalcomponent_get_uid (l->data), NULL); + /* FIXME Confirm expunge */ + for (l = priv->clients_list; l != NULL; l = l->next) { + ECal *client = l->data; + GList *objects, *m; + gboolean read_only = TRUE; + + e_cal_is_read_only (client, &read_only, NULL); + if (!read_only) + continue; + + if (!e_cal_get_object_list (client, sexp, &objects, NULL)) { + g_warning (G_STRLOC ": Could not get the objects"); + + continue; + } + + for (m = objects; m; m = m->next) { + /* FIXME Better error handling */ + e_cal_remove_object (client, icalcomponent_get_uid (m->data), NULL); + } } set_status_message (tasks, NULL); + + g_free (sexp); } /* Callback used from the view collection when we need to display a new view */ @@ -1041,7 +1171,7 @@ e_tasks_setup_view_menus (ETasks *tasks, BonoboUIComponent *uic) gal_view_collection_load (collection); } - priv->view_instance = gal_view_instance_new (collection, e_cal_get_uri (priv->client)); + priv->view_instance = gal_view_instance_new (collection, e_cal_get_uri (e_tasks_get_default_client (tasks))); priv->view_menus = gal_view_menus_new (priv->view_instance); gal_view_menus_apply (priv->view_menus, uic, NULL); diff --git a/calendar/gui/e-tasks.h b/calendar/gui/e-tasks.h index a1cfc0612b..276149107f 100644 --- a/calendar/gui/e-tasks.h +++ b/calendar/gui/e-tasks.h @@ -66,6 +66,10 @@ void e_tasks_set_ui_component (ETasks *tasks, gboolean e_tasks_open (ETasks *tasks, char *file); +gboolean e_tasks_add_todo_uri (ETasks *tasks, const char *str_uri); +gboolean e_tasks_remove_todo_uri (ETasks *tasks, const char *str_uri); +gboolean e_tasks_set_default_uri (ETasks *tasks, const char *str_uri); +ECal *e_tasks_get_default_client (ETasks *tasks); void e_tasks_new_task (ETasks *tasks); void e_tasks_complete_selected (ETasks *tasks); diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index a034c4d4fb..3cc8e4e0cc 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -70,14 +70,12 @@ /* Private part of the GnomeCalendar structure */ struct _GnomeCalendarPrivate { - /* - * The Calendar Folder. - */ - + /* The calendars for display */ GHashTable *clients; GList *clients_list; /* Set of categories from the calendar client */ + /* FIXME are we getting all the categories? */ GPtrArray *cal_categories; /* @@ -2217,6 +2215,7 @@ gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri) g_signal_connect (G_OBJECT (client), "categories_changed", G_CALLBACK (client_categories_changed_cb), gcal); g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal); + /* FIXME Do this async? */ if (!e_cal_open (client, FALSE, NULL)) { g_hash_table_remove (priv->clients, str_uri); priv->clients_list = g_list_prepend (priv->clients_list, client); @@ -2256,6 +2255,7 @@ gnome_calendar_remove_event_uri (GnomeCalendar *gcal, const char *str_uri) ECal *client; int i; + g_return_val_if_fail (gcal != NULL, FALSE); g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); g_return_val_if_fail (str_uri != NULL, FALSE); @@ -2283,15 +2283,6 @@ gnome_calendar_remove_event_uri (GnomeCalendar *gcal, const char *str_uri) return TRUE; } -/** - * gnome_calendar_set_default_uri - * @gcal: A calendar view. - * @client: The client to use as default. - * - * Set the default client on the given calendar view. The default calendar will - * be used as the default when creating events in the view. - */ - /** * gnome_calendar_set_default_uri: * @gcal: A calendar view @@ -2305,17 +2296,19 @@ gnome_calendar_remove_event_uri (GnomeCalendar *gcal, const char *str_uri) * otherwise **/ gboolean -gnome_calendar_set_default_uri (GnomeCalendar *gcal, const char *uri) +gnome_calendar_set_default_uri (GnomeCalendar *gcal, const char *str_uri) { GnomeCalendarPrivate *priv; ECal *client; int i; + g_return_val_if_fail (gcal != NULL, FALSE); g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); + g_return_val_if_fail (str_uri != NULL, FALSE); priv = gcal->priv; - client = g_hash_table_lookup (priv->clients, uri); + client = g_hash_table_lookup (priv->clients, str_uri); if (!client) return FALSE; @@ -2902,7 +2895,7 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) /* FIXME Confirm expunge */ for (l = priv->clients_list; l != NULL; l = l->next) { ECal *client = l->data; - GList *objects, *l; + GList *objects, *m; gboolean read_only = TRUE; e_cal_is_read_only (client, &read_only, NULL); @@ -2915,12 +2908,12 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) continue; } - for (l = objects; l; l = l->next) { + for (m = objects; m; m = m->next) { ECalComponent *comp; gboolean remove = TRUE; comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data)); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (m->data)); e_cal_recur_generate_instances (comp, older_than, -1, (ECalRecurInstanceFn) check_instance_cb, @@ -2930,7 +2923,7 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) /* FIXME Better error handling */ if (remove) - e_cal_remove_object (client, icalcomponent_get_uid (l->data), NULL); + e_cal_remove_object (client, icalcomponent_get_uid (m->data), NULL); g_object_unref (comp); } diff --git a/calendar/gui/tasks-component.c b/calendar/gui/tasks-component.c index 28e55ddf8e..ebb671dff8 100644 --- a/calendar/gui/tasks-component.c +++ b/calendar/gui/tasks-component.c @@ -28,12 +28,18 @@ #include #include #include +#include #include #include #include "e-cal-model.h" #include "e-tasks.h" #include "tasks-component.h" #include "tasks-control.h" +#include "e-comp-editor-registry.h" +#include "migration.h" +#include "comp-util.h" +#include "dialogs/comp-editor.h" +#include "dialogs/task-editor.h" #include "widgets/misc/e-source-selector.h" @@ -44,12 +50,17 @@ static BonoboObjectClass *parent_class = NULL; +/* Tasks should have their own registry */ +extern ECompEditorRegistry *comp_editor_registry; + struct _TasksComponentPrivate { char *config_directory; GConfClient *gconf_client; + ESourceList *source_list; GSList *source_selection; - GtkWidget *tasks; + + ETasks *tasks; }; /* Utility functions. */ @@ -57,39 +68,18 @@ struct _TasksComponentPrivate { static void add_uri_for_source (ESource *source, ETasks *tasks) { - ECal *client; - ECalModel *model; - GError *error = NULL; char *uri = e_source_get_uri (source); - model = e_calendar_table_get_model (e_tasks_get_calendar_table (tasks)); - client = e_cal_model_get_client_for_uri (model, uri); - if (!client) { - client = e_cal_new (uri, CALOBJ_TYPE_TODO); - if (e_cal_open (client, FALSE, &error)) { - e_cal_model_add_client (model, client); - } else { - g_warning (G_STRLOC ": Could not open tasks at %s: %s", uri, error->message); - g_error_free (error); - g_object_unref (client); - } - } - + e_tasks_add_todo_uri (tasks, uri); g_free (uri); } static void remove_uri_for_source (ESource *source, ETasks *tasks) { - ECal *client; - ECalModel *model; char *uri = e_source_get_uri (source); - model = e_calendar_table_get_model (e_tasks_get_calendar_table (tasks)); - client = e_cal_model_get_client_for_uri (model, uri); - if (client) - e_cal_model_remove_client (model, client); - + e_tasks_remove_todo_uri (tasks, uri); g_free (uri); } @@ -135,6 +125,17 @@ update_uris_for_selection (ESourceSelector *selector, TasksComponent *component) priv->source_selection = selection; } +/* FIXME This is duplicated from comp-editor-factory.c, should it go in comp-util? */ +static ECalComponent * +get_default_task (ECal *ecal) +{ + ECalComponent *comp; + + comp = cal_comp_task_new_with_defaults (ecal); + + return comp; +} + /* Callbacks. */ static void source_selection_changed_cb (ESourceSelector *selector, TasksComponent *component) @@ -246,8 +247,22 @@ impl_createControls (PortableServer_Servant servant, sidebar_control = bonobo_control_new (selector_scrolled_window); /* create the tasks view */ - view_control = tasks_control_new (); - priv->tasks = bonobo_control_get_widget (view_control); + priv->tasks = E_TASKS (e_tasks_new ()); + if (!priv->tasks) { + g_warning (G_STRLOC ": could not create the control!"); + bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); + return; + } + + gtk_widget_show (GTK_WIDGET (priv->tasks)); + + view_control = bonobo_control_new (GTK_WIDGET (priv->tasks)); + if (!view_control) { + g_warning (G_STRLOC ": could not create the control!"); + bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); + return; + } + g_signal_connect (view_control, "activate", G_CALLBACK (control_activate_cb), priv->tasks); g_signal_connect_object (selector, "selection_changed", @@ -290,9 +305,34 @@ impl_requestCreateItem (PortableServer_Servant servant, const CORBA_char *item_type_name, CORBA_Environment *ev) { - /* FIXME: fill me in */ + TasksComponent *tasks_component = TASKS_COMPONENT (bonobo_object_from_servant (servant)); + TasksComponentPrivate *priv; + ECal *ecal; + ECalComponent *comp; + TaskEditor *editor; + + priv = tasks_component->priv; + + ecal = e_tasks_get_default_client (E_TASKS (priv->tasks)); + if (!ecal) { + /* FIXME We should display a gui dialog or something */ + bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType); + g_warning (G_STRLOC ": No default client"); + } + + editor = task_editor_new (ecal); + + if (strcmp (item_type_name, CREATE_TASK_ID) == 0) { + comp = get_default_task (ecal); + } else { + bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType); + return; + } + + comp_editor_edit_comp (COMP_EDITOR (editor), comp); + comp_editor_focus (COMP_EDITOR (editor)); - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UnknownType, NULL); + e_comp_editor_registry_add (comp_editor_registry, COMP_EDITOR (editor), TRUE); } /* Initialization */ -- cgit