diff options
Diffstat (limited to 'calendar/gui/gnome-cal.c')
-rw-r--r-- | calendar/gui/gnome-cal.c | 617 |
1 files changed, 187 insertions, 430 deletions
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index c2a0c2c61e..bcefd8eeee 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -61,8 +61,6 @@ #include "misc.h" #include "ea-calendar.h" -extern ECompEditorRegistry *comp_editor_registry; - /* Private part of the GnomeCalendar structure */ @@ -71,6 +69,8 @@ struct _GnomeCalendarPrivate { * The Calendar Folder. */ + GHashTable *clients; + /* Set of categories from the calendar client */ GPtrArray *cal_categories; @@ -119,6 +119,7 @@ struct _GnomeCalendarPrivate { /* This is the view currently shown. We use it to keep track of the positions of the panes. range_selected is TRUE if a range of dates was selected in the date navigator to show the view. */ + ECalView *views[GNOME_CAL_LAST_VIEW]; GnomeCalendarViewType current_view_type; gboolean range_selected; @@ -145,10 +146,6 @@ struct _GnomeCalendarPrivate { 'dates-shown-changed' signal.*/ time_t visible_start; time_t visible_end; - - /* Calendar query for purging old events */ - GList *exp_queries; - time_t exp_older_than; }; /* Signal IDs */ @@ -361,97 +358,70 @@ gnome_calendar_class_init (GnomeCalendarClass *class) /* Callback used when the calendar query reports of an updated object */ static void -dn_query_obj_updated_cb (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data) +dn_query_objects_added_cb (CalQuery *query, GList *objects, gpointer data) { GnomeCalendar *gcal; GnomeCalendarPrivate *priv; - CalComponent *comp = NULL; - icalcomponent *icalcomp; - CalClientGetStatus status; - + GList *l; + gcal = GNOME_CALENDAR (data); priv = gcal->priv; - /* If this is an update that is not part of an ongoing query, 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. - */ - if (!query_in_progress) { - update_query (gcal); - return; - } + for (l = objects; l; l = l->next) { + CalComponent *comp = NULL; - status = cal_client_get_object (cal_query_get_client (query), uid, &icalcomp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { + if (!cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) { g_object_unref (comp); - icalcomponent_free (icalcomp); - return; + + continue; } - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("dn_query_obj_updated_cb(): Syntax error while getting object `%s'", uid); - return; - - case CAL_CLIENT_GET_NOT_FOUND: - /* The object is no longer in the server, so do nothing */ - return; - default: - g_assert_not_reached (); - return; + tag_calendar_by_comp (priv->date_navigator, comp, cal_query_get_client (query), NULL, + FALSE, TRUE); + g_object_unref (comp); } - - tag_calendar_by_comp (priv->date_navigator, comp, cal_query_get_client (query), NULL, - FALSE, TRUE); - g_object_unref (comp); } -/* Callback used when the calendar query reports of a removed object */ static void -dn_query_obj_removed_cb (CalQuery *query, const char *uid, gpointer data) +dn_query_objects_modified_cb (CalQuery *query, GList *objects, gpointer data) { GnomeCalendar *gcal; + GnomeCalendarPrivate *priv; gcal = GNOME_CALENDAR (data); + priv = gcal->priv; - /* Just retag the whole thing */ + /* 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. + */ update_query (gcal); } -/* Callback used when the calendar query is done */ +/* Callback used when the calendar query reports of a removed object */ static void -dn_query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, - gpointer data) +dn_query_objects_removed_cb (CalQuery *query, GList *uids, gpointer data) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); - /* FIXME */ - - if (status != CAL_QUERY_DONE_SUCCESS) - fprintf (stderr, "query done: %s\n", error_str); + /* Just retag the whole thing */ + update_query (gcal); } -/* Callback used when the calendar query reports an evaluation error */ +/* Callback used when the calendar query is done */ static void -dn_query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) +dn_query_done_cb (CalQuery *query, ECalendarStatus status, gpointer data) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); - /* FIXME */ - - fprintf (stderr, "eval error: %s\n", error_str); + /* FIXME Better error reporting */ + if (status != E_CALENDAR_STATUS_OK) + g_warning (G_STRLOC ": Query did not successfully complete"); } /* Returns the current view widget, an EDayView, EWeekView or ECalListView. */ @@ -603,6 +573,7 @@ adjust_query_sexp (GnomeCalendar *gcal, const char *sexp) start, end, sexp); + g_free (start); g_free (end); @@ -649,22 +620,24 @@ update_query (GnomeCalendar *gcal) /* create queries for each loaded client */ client_list = e_cal_model_get_client_list (e_cal_view_get_model (E_CAL_VIEW (priv->day_view))); for (l = client_list; l != NULL; l = l->next) { - old_query = cal_client_get_query ((CalClient *) l->data, real_sexp); - if (!old_query) { - g_message ("update_query(): Could not create the query"); + if (!cal_client_get_query ((CalClient *) l->data, real_sexp, &old_query, NULL)) { + g_warning (G_STRLOC ": Could not create the query"); + continue; } - g_signal_connect (old_query, "obj_updated", - G_CALLBACK (dn_query_obj_updated_cb), gcal); - g_signal_connect (old_query, "obj_removed", - G_CALLBACK (dn_query_obj_removed_cb), gcal); + g_signal_connect (old_query, "objects_added", + G_CALLBACK (dn_query_objects_added_cb), gcal); + g_signal_connect (old_query, "objects_modified", + G_CALLBACK (dn_query_objects_modified_cb), gcal); + g_signal_connect (old_query, "objects_removed", + G_CALLBACK (dn_query_objects_removed_cb), gcal); g_signal_connect (old_query, "query_done", - G_CALLBACK (dn_query_query_done_cb), gcal); - g_signal_connect (old_query, "eval_error", - G_CALLBACK (dn_query_eval_error_cb), gcal); + G_CALLBACK (dn_query_done_cb), gcal); priv->dn_queries = g_list_append (priv->dn_queries, old_query); + + cal_query_start (old_query); } g_list_free (client_list); @@ -673,6 +646,30 @@ update_query (GnomeCalendar *gcal) e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL); } +static void +adjust_query_for_view (ECalView *cal_view, const char *sexp) +{ + char *real_sexp, *start, *end; + time_t ttstart, ttend; + + e_cal_view_get_visible_time_range (cal_view, &ttstart, &ttend); + + start = isodate_from_time_t (ttstart); + end = isodate_from_time_t (ttend); + + real_sexp = g_strdup_printf ( + "(and (occur-in-time-range? (make-time \"%s\")" + " (make-time \"%s\"))" + " %s)", + start, end, sexp); + + e_cal_model_set_query (e_cal_view_get_model (cal_view), real_sexp); + + g_free (start); + g_free (end); + g_free (real_sexp); +} + /** * gnome_calendar_set_query: * @gcal: A calendar. @@ -685,6 +682,7 @@ gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp) { GnomeCalendarPrivate *priv; ECalModel *model; + int i; g_return_if_fail (gcal != NULL); g_return_if_fail (GNOME_IS_CALENDAR (gcal)); @@ -701,9 +699,9 @@ gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp) update_query (gcal); - /* Set the query on the main view */ - model = e_cal_view_get_model (E_CAL_VIEW (gnome_calendar_get_current_view_widget (gcal))); - e_cal_model_set_query (model, sexp); + /* Set the query on the views */ + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) + adjust_query_for_view (E_CAL_VIEW (priv->views[i]), sexp); /* Set the query on the task pad */ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); @@ -747,14 +745,15 @@ search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, GnomeCalendar *gcal; GnomeCalendarPrivate *priv; ECalModel *model; + int i; gcal = GNOME_CALENDAR (data); priv = gcal->priv; - e_day_view_set_default_category (E_DAY_VIEW (priv->day_view), category); - e_day_view_set_default_category (E_DAY_VIEW (priv->work_week_view), category); - e_week_view_set_default_category (E_WEEK_VIEW (priv->week_view), category); - e_week_view_set_default_category (E_WEEK_VIEW (priv->month_view), category); + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { + e_cal_view_set_default_category (E_CAL_VIEW (priv->views[i]), + category); + } model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); e_cal_model_set_default_category (model, category); @@ -853,7 +852,6 @@ setup_widgets (GnomeCalendar *gcal) GtkWidget *w; gchar *filename; ETable *etable; - ECalModel *model; priv = gcal->priv; @@ -915,7 +913,8 @@ setup_widgets (GnomeCalendar *gcal) gtk_paned_pack2 (GTK_PANED (priv->vpane), priv->todo, TRUE, TRUE); gtk_widget_show (priv->todo); - filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir); + filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()), + "TaskPad", NULL); e_calendar_table_load_state (E_CALENDAR_TABLE (priv->todo), filename); g_free (filename); @@ -977,7 +976,7 @@ setup_widgets (GnomeCalendar *gcal) connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view)); /* The List View. */ - filename = g_strdup_printf ("%s/config/CalListView", evolution_dir); + filename = g_strdup_printf (".evolution/config/CalListView"); priv->list_view = e_cal_list_view_new (filename); g_free (filename); @@ -988,14 +987,12 @@ setup_widgets (GnomeCalendar *gcal) connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view)); - model = (ECalModel *) e_cal_model_calendar_new (); - e_cal_view_set_model (E_CAL_VIEW (priv->day_view), model); - e_cal_view_set_model (E_CAL_VIEW (priv->work_week_view), model); - e_cal_view_set_model (E_CAL_VIEW (priv->week_view), model); - e_cal_view_set_model (E_CAL_VIEW (priv->month_view), model); - e_cal_view_set_model (E_CAL_VIEW (priv->list_view), model); + priv->views[GNOME_CAL_DAY_VIEW] = E_CAL_VIEW (priv->day_view); + priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CAL_VIEW (priv->work_week_view); + priv->views[GNOME_CAL_WEEK_VIEW] = E_CAL_VIEW (priv->week_view); + priv->views[GNOME_CAL_MONTH_VIEW] = E_CAL_VIEW (priv->month_view); + priv->views[GNOME_CAL_LIST_VIEW] = E_CAL_VIEW (priv->list_view); - g_object_unref (model); gnome_calendar_update_config_settings (gcal, TRUE); } @@ -1008,6 +1005,8 @@ gnome_calendar_init (GnomeCalendar *gcal) priv = g_new0 (GnomeCalendarPrivate, 1); gcal->priv = priv; + priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->cal_categories = NULL; priv->tasks_categories = NULL; @@ -1027,8 +1026,6 @@ gnome_calendar_init (GnomeCalendar *gcal) priv->visible_start = -1; priv->visible_end = -1; - - priv->exp_queries = NULL; } /* Frees a set of categories */ @@ -1062,6 +1059,8 @@ gnome_calendar_destroy (GtkObject *object) if (priv) { GList *l, *client_list; + g_hash_table_destroy (priv->clients); + free_categories (priv->cal_categories); priv->cal_categories = NULL; @@ -1078,7 +1077,8 @@ gnome_calendar_destroy (GtkObject *object) g_list_free (client_list); /* Save the TaskPad layout. */ - filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir); + filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()), + "TaskPad", NULL); e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename); g_free (filename); @@ -1120,19 +1120,6 @@ gnome_calendar_destroy (GtkObject *object) priv->view_menus = NULL; } - if (priv->exp_queries) { - GList *l; - - for (l = priv->exp_queries; l != NULL; l = l->next) { - g_signal_handlers_disconnect_matched ((CalQuery *) l->data, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - g_object_unref (l->data); - } - - g_list_free (priv->exp_queries); - priv->exp_queries = NULL; - } - g_free (priv); gcal->priv = NULL; } @@ -1764,7 +1751,8 @@ client_cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer da case CAL_CLIENT_OPEN_SUCCESS: /* Set the client's default timezone, if we have one. */ if (priv->zone) { - cal_client_set_default_timezone (client, priv->zone); + /* FIXME Error checking */ + cal_client_set_default_timezone (client, priv->zone, NULL); } /* add the alarms for this client */ @@ -1996,7 +1984,7 @@ gnome_calendar_construct (GnomeCalendar *gcal) /* * TaskPad Folder Client. */ - priv->task_pad_client = cal_client_new (); + priv->task_pad_client = cal_client_new ("", CALOBJ_TYPE_TODO); /* FIXME: use default tasks */ if (!priv->task_pad_client) return NULL; @@ -2063,7 +2051,8 @@ gnome_calendar_get_calendar_model (GnomeCalendar *gcal) priv = gcal->priv; - return e_cal_view_get_model (E_CAL_VIEW (priv->week_view)); + return e_cal_view_get_model ( + gnome_calendar_get_current_view_widget (gcal)); } /** @@ -2078,6 +2067,28 @@ gnome_calendar_get_default_client (GnomeCalendar *gcal) } /** + * gnome_calendar_set_default_client + * @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. + */ +void +gnome_calendar_set_default_client (GnomeCalendar *gcal, CalClient *client) +{ + int i; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { + e_cal_model_set_default_client ( + e_cal_view_get_model (E_CAL_VIEW (gcal->priv->views[i])), + client); + } +} + +/** * gnome_calendar_get_task_pad_cal_client: * @gcal: A calendar view. * @@ -2145,67 +2156,56 @@ add_alarms (const char *uri) CORBA_exception_free (&ev); } +/** + * gnome_calendar_add_event_uri: + * @gcal: A GnomeCalendar. + * @str_uri: URI to add to the calendar views. + * + * Adds the given calendar URI to the calendar views. + * + * Returns: TRUE if successful, FALSE if error. + */ gboolean -gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri) +gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri) { GnomeCalendarPrivate *priv; - gboolean success; - EUri *uri; - char *message; - char *real_uri; - char *urinopwd; CalClient *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; - g_return_val_if_fail ( - cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_NOT_LOADED, - FALSE); - - uri = e_uri_new (str_uri); - if (!uri || !g_strncasecmp (uri->protocol, "file", 4)) - real_uri = g_concat_dir_and_file (str_uri, "calendar.ics"); - else - real_uri = g_strdup (str_uri); - - urinopwd = get_uri_without_password (str_uri); - message = g_strdup_printf (_("Opening calendar at %s"), urinopwd); - g_free (urinopwd); - e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), message); - g_free (message); - - client = cal_client_new (); - g_signal_connect (G_OBJECT (client), "cal_opened", G_CALLBACK (client_cal_opened_cb), gcal); + client = g_hash_table_lookup (priv->clients, str_uri); + if (client) + return TRUE; + + client = cal_client_new (str_uri, CALOBJ_TYPE_EVENT); + g_hash_table_insert (priv->clients, g_strdup (str_uri), g_object_ref (client)); + g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), gcal); 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); - if (!cal_client_open_calendar (client, real_uri, FALSE)) { - g_warning (G_STRLOC ": Could not issue the request to open the calendar folder"); + if (!cal_client_open (client, FALSE, NULL)) { + g_hash_table_remove (priv->clients, str_uri); g_object_unref (client); - e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL); return FALSE; } - /* Open the appropriate Tasks folder to show in the TaskPad */ - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), - _("Opening default tasks folder")); - success = cal_client_open_default_tasks (priv->task_pad_client, FALSE); - - g_free (real_uri); - e_uri_free (uri); - - if (!success) { - g_message ("gnome_calendar_open(): Could not issue the request to open the tasks folder"); - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL); - return FALSE; + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { + ECalModel *model; + + model = e_cal_view_get_model (priv->views[i]); + e_cal_model_add_client (model, client); } + /* update date navigator query */ + update_query (gcal); + return TRUE; } @@ -2308,7 +2308,8 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal, CalClient *client = l->data; if (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED) - cal_client_set_default_timezone (client, priv->zone); + /* FIXME Error checking */ + cal_client_set_default_timezone (client, priv->zone, NULL); } g_list_free (client_list); @@ -2316,8 +2317,9 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal, if (priv->task_pad_client && cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_LOADED) { + /* FIXME Error Checking */ cal_client_set_default_timezone (priv->task_pad_client, - priv->zone); + priv->zone, NULL); } e_cal_view_set_timezone (E_CAL_VIEW (priv->day_view), priv->zone); @@ -2383,147 +2385,6 @@ gnome_calendar_get_selected_time_range (GnomeCalendar *gcal, *end_time = priv->selection_end_time; } -void -gnome_calendar_edit_object (GnomeCalendar *gcal, CalClient *client, icalcomponent *icalcomp, gboolean meeting) -{ - GnomeCalendarPrivate *priv; - CompEditor *ce; - const char *uid; - CalComponent *comp; - - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (icalcomp != NULL); - - priv = gcal->priv; - - uid = icalcomponent_get_uid (icalcomp); - - ce = e_comp_editor_registry_find (comp_editor_registry, uid); - if (!ce) { - EventEditor *ee; - - ee = event_editor_new (client); - if (!ee) { - g_message ("gnome_calendar_edit_object(): Could not create the event editor"); - return; - } - ce = COMP_EDITOR (ee); - - comp = cal_component_new (); - cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); - - comp_editor_edit_comp (ce, comp); - if (meeting) - event_editor_show_meeting (ee); - - e_comp_editor_registry_add (comp_editor_registry, ce, FALSE); - - g_object_unref (comp); - } - - comp_editor_focus (ce); -} - -/** - * gnome_calendar_new_appointment_for: - * @gcal: An Evolution calendar. - * @dtstart: a Unix time_t that marks the beginning of the appointment. - * @dtend: a Unix time_t that marks the end of the appointment. - * @all_day: if true, the dtstart and dtend are expanded to cover the entire - * day, and the event is set to TRANSPARENT. - * - * Opens an event editor dialog for a new appointment. - * - **/ -void -gnome_calendar_new_appointment_for (GnomeCalendar *cal, - time_t dtstart, time_t dtend, - gboolean all_day, - gboolean meeting) -{ - GnomeCalendarPrivate *priv; - struct icaltimetype itt; - CalComponentDateTime dt; - CalComponent *comp; - icalcomponent *icalcomp; - CalComponentTransparency transparency; - const char *category; - - g_return_if_fail (cal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (cal)); - - priv = cal->priv; - - dt.value = &itt; - if (all_day) - dt.tzid = NULL; - else - dt.tzid = icaltimezone_get_tzid (priv->zone); - - icalcomp = e_cal_model_create_component_with_defaults (e_cal_view_get_model (E_CAL_VIEW (priv->week_view))); - comp = cal_component_new (); - cal_component_set_icalcomponent (comp, icalcomp); - - /* DTSTART, DTEND */ - - itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone); - if (all_day) { - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - cal_component_set_dtstart (comp, &dt); - - itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone); - if (all_day) { - /* We round it up to the end of the day, unless it is already - set to midnight. */ - if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) { - icaltime_adjust (&itt, 1, 0, 0, 0); - } - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - cal_component_set_dtend (comp, &dt); - - transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT - : CAL_COMPONENT_TRANSP_OPAQUE; - cal_component_set_transparency (comp, transparency); - - - /* Category */ - - category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); - cal_component_set_categories (comp, category); - - /* Edit! */ - - cal_component_commit_sequence (comp); - - gnome_calendar_edit_object (cal, gnome_calendar_get_default_client (cal), icalcomp, meeting); - g_object_unref (comp); -} - -/** - * gnome_calendar_new_appointment: - * @gcal: An Evolution calendar. - * - * Opens an event editor dialog for a new appointment. The appointment's start - * and end times are set to the currently selected time range in the calendar - * views. - **/ -void -gnome_calendar_new_appointment (GnomeCalendar *gcal) -{ - time_t dtstart, dtend; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - gnome_calendar_get_current_time_range (gcal, &dtstart, &dtend); - gnome_calendar_new_appointment_for (gcal, dtstart, dtend, FALSE, FALSE); -} - /** * gnome_calendar_new_task: * @gcal: An Evolution calendar. @@ -3020,136 +2881,17 @@ gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal) } } -void -gnome_calendar_unrecur_selection (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - FocusLocation location; - GtkWidget *view; - - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - - view = gnome_calendar_get_current_view_widget (gcal); - - if (E_IS_DAY_VIEW (view)) - e_day_view_unrecur_appointment (E_DAY_VIEW (view)); - else - e_week_view_unrecur_appointment (E_WEEK_VIEW (view)); - } -} - -typedef struct { - gboolean remove; - GnomeCalendar *gcal; -} obj_updated_closure; - static gboolean check_instance_cb (CalComponent *comp, time_t instance_start, time_t instance_end, gpointer data) { - obj_updated_closure *closure = data; - - if (instance_start >= closure->gcal->priv->exp_older_than || - instance_end >= closure->gcal->priv->exp_older_than) { - closure->remove = FALSE; - return FALSE; - } - - closure->remove = TRUE; - return TRUE; -} - -static void -purging_obj_updated_cb (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data) -{ - GnomeCalendarPrivate *priv; - GnomeCalendar *gcal = data; - CalComponent *comp; - icalcomponent *icalcomp; - obj_updated_closure closure; - gchar *msg; - - priv = gcal->priv; - - if (cal_client_get_object (cal_query_get_client (query), uid, &icalcomp) != CAL_CLIENT_GET_SUCCESS) - return; - - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - icalcomponent_free (icalcomp); - return; - } - - msg = g_strdup_printf (_("Purging event %s"), uid); - - /* further filter the event, to check the last recurrence end date */ - if (cal_component_has_recurrences (comp)) { - closure.remove = TRUE; - closure.gcal = gcal; - - cal_recur_generate_instances (comp, priv->exp_older_than, -1, - (CalRecurInstanceFn) check_instance_cb, - &closure, - (CalRecurResolveTimezoneFn) cal_client_resolve_tzid_cb, - cal_query_get_client (query), priv->zone); - - if (closure.remove) { - e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), msg); - delete_error_dialog (cal_client_remove_object (cal_query_get_client (query), uid), - CAL_COMPONENT_EVENT); - } - } else { - e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), msg); - delete_error_dialog (cal_client_remove_object (cal_query_get_client (query), uid), CAL_COMPONENT_EVENT); - } - - g_object_unref (comp); - g_free (msg); -} - -static void -purging_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) -{ - GnomeCalendarPrivate *priv; - GnomeCalendar *gcal = data; - - priv = gcal->priv; - - e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL); - - g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - - priv->exp_queries = g_list_remove (priv->exp_queries, query); - g_object_unref (query); -} + gboolean *remove = data; -static void -purging_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data) -{ - GnomeCalendarPrivate *priv; - GnomeCalendar *gcal = data; - - priv = gcal->priv; - - e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL); + *remove = FALSE; - g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - - priv->exp_queries = g_list_remove (priv->exp_queries, query); - g_object_unref (query); + return FALSE; } void @@ -3163,11 +2905,6 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) priv = gcal->priv; - /* if we have a query, we are already purging */ - if (priv->exp_queries) - return; - - priv->exp_older_than = older_than; start = isodate_from_time_t (0); end = isodate_from_time_t (older_than); sexp = g_strdup_printf ("(and (= (get-vtype) \"VEVENT\")" @@ -3177,27 +2914,47 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), _("Purging")); + /* FIXME Confirm expunge */ + client_list = e_cal_model_get_client_list (e_cal_view_get_model (E_CAL_VIEW (priv->week_view))); for (l = client_list; l != NULL; l = l->next) { - CalQuery *exp_query; - - if (cal_client_is_read_only ((CalClient *) l->data)) + CalClient *client = l->data; + GList *objects, *l; + gboolean read_only = TRUE; + + cal_client_is_read_only (client, &read_only, NULL); + if (!read_only) continue; - - exp_query = cal_client_get_query ((CalClient *) l->data, sexp); - if (!exp_query) { - e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL); - g_message ("gnome_calendar_purge(): Could not create the query"); + + if (!cal_client_get_object_list (client, sexp, &objects, NULL)) { + g_warning (G_STRLOC ": Could not get the objects"); + continue; } - - g_signal_connect (exp_query, "obj_updated", G_CALLBACK (purging_obj_updated_cb), gcal); - g_signal_connect (exp_query, "query_done", G_CALLBACK (purging_query_done_cb), gcal); - g_signal_connect (exp_query, "eval_error", G_CALLBACK (purging_eval_error_cb), gcal); - - priv->exp_queries = g_list_append (priv->exp_queries, exp_query); + + for (l = objects; l; l = l->next) { + CalComponent *comp; + gboolean remove = TRUE; + + comp = cal_component_new (); + cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data)); + + cal_recur_generate_instances (comp, older_than, -1, + (CalRecurInstanceFn) check_instance_cb, + &remove, + (CalRecurResolveTimezoneFn) cal_client_resolve_tzid_cb, + client, priv->zone); + + /* FIXME Better error handling */ + if (remove) + cal_client_remove_object (client, icalcomponent_get_uid (l->data), NULL); + + g_object_unref (comp); + } } + e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL); + g_list_free (client_list); g_free (sexp); g_free (start); |