diff options
-rw-r--r-- | calendar/ChangeLog | 14 | ||||
-rw-r--r-- | calendar/gui/calendar-commands.c | 52 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 152 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.h | 2 |
4 files changed, 219 insertions, 1 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 01cd31d988..aa4a22411f 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,17 @@ +2003-07-16 Rodrigo Moya <rodrigo@ximian.com> + + * gui/gnome-cal.[ch] (gnome_calendar_purge): new function, + which uses a CalQuery to retrieve the objects older than a given date. + (check_instance_cb): callback for cal_recur_generate_instances. + (purging_obj_updated_cb): call check_instance_cb on each recurrence + to double-check the event can be deleted. + (purging_query_done_cb, purging_eval_error_cb): needed callbacks to + finish the query. + (gnome_calendar_destroy): free new members. + + * gui/calendar-commands.c (purge_cmd): added implementation for the + 'Purge' menu item. + 2003-07-16 Andrew Wu <Yang.Wu@sun.com> Fixes #45774 diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c index ce921bbc44..82cf5e1976 100644 --- a/calendar/gui/calendar-commands.c +++ b/calendar/gui/calendar-commands.c @@ -36,7 +36,8 @@ #include <gtk/gtkfilesel.h> #include <gtk/gtkmain.h> #include <gtk/gtksignal.h> - +#include <gtk/gtkspinbutton.h> +#include <gtk/gtkmessagedialog.h> #include <libgnome/gnome-util.h> #include <libgnomeui/gnome-dialog-util.h> #include <libgnomeui/gnome-messagebox.h> @@ -338,6 +339,54 @@ publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) } } +static void +purge_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) +{ + GnomeCalendar *gcal; + GtkWidget *dialog, *parent, *box, *label, *spin, *unit; + int response; + + gcal = GNOME_CALENDAR (data); + + /* create the dialog */ + parent = gtk_widget_get_toplevel (GTK_WIDGET (gcal)); + dialog = gtk_message_dialog_new ( + parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK_CANCEL, + _("This operation will permanently erase all events older than the selected amount of time. If you continue, you will not be able to recover these events.")); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); + + box = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, TRUE, FALSE, 6); + + label = gtk_label_new (_("Purge events older than")); + gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 6); + spin = gtk_spin_button_new_with_range (0.0, 1000.0, 1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 60.0); + gtk_box_pack_start (GTK_BOX (box), spin, FALSE, FALSE, 6); + label = gtk_label_new (_("days")); + gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 6); + + gtk_widget_show_all (box); + + /* run the dialog */ + response = gtk_dialog_run (GTK_DIALOG (dialog)); + if (response == GTK_RESPONSE_OK) { + gint days; + time_t tt; + + days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin)); + tt = time (NULL); + tt -= (days * (24 * 3600)); + + gnome_calendar_purge (gcal, tt); + } + + gtk_widget_destroy (dialog); +} + /* Does a queryInterface on the control's parent control frame for the ShellView interface */ static GNOME_Evolution_ShellView get_shell_view_interface (BonoboControl *control) @@ -719,6 +768,7 @@ static BonoboUIVerb verbs [] = { BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked), BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd), + BONOBO_UI_VERB ("CalendarPurge", purge_cmd), BONOBO_UI_VERB_END }; diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 66d1c38d0f..f9c612ccd9 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -40,6 +40,7 @@ #include <cal-util/timeutil.h> #include "widgets/menus/gal-view-menus.h" #include "e-comp-editor-registry.h" +#include "dialogs/delete-error.h" #include "dialogs/event-editor.h" #include "dialogs/task-editor.h" #include "comp-util.h" @@ -143,6 +144,10 @@ struct _GnomeCalendarPrivate { 'dates-shown-changed' signal.*/ time_t visible_start; time_t visible_end; + + /* Calendar query for purging old events */ + CalQuery *exp_query; + time_t exp_older_than; }; /* Signal IDs */ @@ -979,6 +984,8 @@ gnome_calendar_init (GnomeCalendar *gcal) priv->visible_start = -1; priv->visible_end = -1; + + priv->exp_query = NULL; } /* Frees a set of categories */ @@ -1062,6 +1069,13 @@ gnome_calendar_destroy (GtkObject *object) priv->view_menus = NULL; } + if (priv->exp_query) { + g_signal_handlers_disconnect_matched (priv->exp_query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + g_object_unref (priv->exp_query); + priv->exp_query = NULL; + } + g_free (priv); gcal->priv = NULL; } @@ -3100,6 +3114,144 @@ gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal) } } +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; + obj_updated_closure closure; + gchar *msg; + + priv = gcal->priv; + + if (cal_client_get_object (priv->client, uid, &comp) != CAL_CLIENT_GET_SUCCESS) + 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, + priv->client, priv->zone); + + if (closure.remove) { + e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), msg); + delete_error_dialog (cal_client_remove_object (priv->client, uid), + CAL_COMPONENT_EVENT); + } + } else { + e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), msg); + delete_error_dialog (cal_client_remove_object (priv->client, 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_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), NULL); + + g_signal_handlers_disconnect_matched (priv->exp_query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + g_object_unref (priv->exp_query); + priv->exp_query = NULL; +} + +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_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), NULL); + + g_signal_handlers_disconnect_matched (priv->exp_query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + g_object_unref (priv->exp_query); + priv->exp_query = NULL; +} + +void +gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) +{ + GnomeCalendarPrivate *priv; + char *sexp, *start, *end; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + priv = gcal->priv; + + /* if we have a query, we are already purging */ + if (priv->exp_query) + 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\")" + " (occur-in-time-range? (make-time \"%s\")" + " (make-time \"%s\")))", + start, end); + + e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), _("Purging")); + priv->exp_query = cal_client_get_query (priv->client, sexp); + + g_free (sexp); + g_free (start); + g_free (end); + + if (!priv->exp_query) { + e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), NULL); + g_message ("gnome_calendar_purge(): Could not create the query"); + return; + } + + g_signal_connect (priv->exp_query, "obj_updated", G_CALLBACK (purging_obj_updated_cb), gcal); + g_signal_connect (priv->exp_query, "query_done", G_CALLBACK (purging_query_done_cb), gcal); + g_signal_connect (priv->exp_query, "eval_error", G_CALLBACK (purging_eval_error_cb), gcal); +} + ECalendarTable* gnome_calendar_get_task_pad (GnomeCalendar *gcal) { diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h index 22bae4f735..e573a55fbb 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -184,6 +184,8 @@ void gnome_calendar_paste_clipboard (GnomeCalendar *gcal); void gnome_calendar_delete_selection (GnomeCalendar *gcal); void gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal); +void gnome_calendar_purge (GnomeCalendar *gcal, + time_t older_than); |