aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog14
-rw-r--r--calendar/gui/calendar-commands.c52
-rw-r--r--calendar/gui/gnome-cal.c152
-rw-r--r--calendar/gui/gnome-cal.h2
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);