[evolution-patches] Expunge events



These 2 patches implement the Expunge menu item in the calendar, which
allows to remove events older than a given date, thus having a way to
clean up the calendar.

It works pretty well, although on highly loaded calendars, it is damn
slow, due to the notifications being sent to all views after every
cal_client_remove_object.

So, I guess we need to have a cal_client_remove_objects call, or a way
to disable notifications temporarily (much more difficult, since we have
the query cache in the backend library).

The dialog needs of course some love from Anna :-)

cheers
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/ui/ChangeLog,v
retrieving revision 1.343
diff -u -p -r1.343 ChangeLog
--- ChangeLog	1 Jan 1997 08:15:55 -0000	1.343
+++ ChangeLog	15 Jul 2003 22:14:40 -0000
@@ -1,3 +1,9 @@
+2003-07-15  Rodrigo Moya <rodrigo ximian com>
+
+	* evolution-calendar.xml: added 'Expunge' menu item.
+
+	* evolution-tasks.xml: added separator after 'Send/Receive'.
+
 2003-07-10  Yuedong Du  <yuedong du sun com>
 
 	* evolution-mail-message.xml: add a menu entry corresponding to new
Index: evolution-calendar.xml
===================================================================
RCS file: /cvs/gnome/evolution/ui/evolution-calendar.xml,v
retrieving revision 1.58
diff -u -p -r1.58 evolution-calendar.xml
--- evolution-calendar.xml	1 Jul 2003 21:46:34 -0000	1.58
+++ evolution-calendar.xml	15 Jul 2003 22:14:40 -0000
@@ -23,6 +23,7 @@
     <cmd name="DeleteAllOccurrences" _tip="Delete All Occurrences" pixtype="stock" pixname="gtk-delete"/>
 
     <cmd name="PublishFreeBusy" _tip="Publish Free/Busy information for this calendar"/>
+    <cmd name="CalendarExpunge" _label="_Expunge" _tip="Delete old appointments and meetings" accel="*Control*e"/>
   </commands>
 
   <menu>
@@ -64,7 +65,9 @@
 
     <submenu name="Actions" _label="_Actions">
       <placeholder name="ComponentActionsPlaceholder">
+        <separator/>
 	<menuitem name="PublishFreeBusy" verb="" _label="_Publish Free/Busy Information"/>
+	<menuitem name="CalendarExpunge" verb=""/>
       </placeholder>
     </submenu>
   </menu>
Index: evolution-tasks.xml
===================================================================
RCS file: /cvs/gnome/evolution/ui/evolution-tasks.xml,v
retrieving revision 1.30
diff -u -p -r1.30 evolution-tasks.xml
--- evolution-tasks.xml	1 Jul 2003 21:46:34 -0000	1.30
+++ evolution-tasks.xml	15 Jul 2003 22:14:40 -0000
@@ -42,6 +42,7 @@
 
     <submenu name="Actions" _label="_Actions">
       <placeholder name="ComponentActionsPlaceholder">
+        <separator/>
 	<menuitem name="TasksExpunge" verb=""/>
       </placeholder>
     </submenu>
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.1819
diff -u -p -r1.1819 ChangeLog
--- ChangeLog	14 Jul 2003 18:46:04 -0000	1.1819
+++ ChangeLog	15 Jul 2003 22:12:49 -0000
@@ -1,3 +1,13 @@
+2003-07-15  Rodrigo Moya <rodrigo ximian com>
+
+	* gui/gnome-cal.[ch] (gnome_calendar_expunge): new function.
+	(gnome_calendar_destroy): free new members.
+
+	* gui/calendar-commands.c (expunge_cmd): added implementation for the
+	'Expunge' menu item.
+	(confirm_expunge): new function for prompting the user about the
+	events to be expunged.
+
 2003-07-14  Rodrigo Moya <rodrigo ximian com>
 
 	Fixes #41676
Index: gui/calendar-commands.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-commands.c,v
retrieving revision 1.121
diff -u -p -r1.121 calendar-commands.c
--- gui/calendar-commands.c	1 Jul 2003 21:47:10 -0000	1.121
+++ gui/calendar-commands.c	15 Jul 2003 22:12:49 -0000
@@ -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 
 	}
 }
 
+static void
+expunge_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_expunge (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 ("CalendarExpunge", expunge_cmd),
 
 	BONOBO_UI_VERB_END
 };
Index: gui/gnome-cal.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/gnome-cal.c,v
retrieving revision 1.244
diff -u -p -r1.244 gnome-cal.c
--- gui/gnome-cal.c	2 Jul 2003 01:33:35 -0000	1.244
+++ gui/gnome-cal.c	15 Jul 2003 22:12:51 -0000
@@ -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 expunging old events */
+	CalQuery *exp_query;
+	time_t exp_older_than;
 };
 
 /* Signal IDs */
@@ -957,6 +962,8 @@ gnome_calendar_init (GnomeCalendar *gcal
 
 	priv->visible_start = -1;
 	priv->visible_end = -1;
+
+	priv->exp_query = NULL;
 }
 
 /* Frees a set of categories */
@@ -1040,6 +1047,13 @@ gnome_calendar_destroy (GtkObject *objec
 			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;
 	}
@@ -3061,6 +3075,144 @@ gnome_calendar_delete_selected_occurrenc
 		else
 			e_week_view_delete_occurrence (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
+expunging_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 (_("Expunging 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
+expunging_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
+expunging_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_expunge (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 expunging */
+	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), _("Expunging"));
+	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_expunge(): Could not create the query");
+		return;
+	}
+	
+	g_signal_connect (priv->exp_query, "obj_updated", G_CALLBACK (expunging_obj_updated_cb), gcal);
+	g_signal_connect (priv->exp_query, "query_done", G_CALLBACK (expunging_query_done_cb), gcal);
+	g_signal_connect (priv->exp_query, "eval_error", G_CALLBACK (expunging_eval_error_cb), gcal);
 }
 
 ECalendarTable*
Index: gui/gnome-cal.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/gnome-cal.h,v
retrieving revision 1.82
diff -u -p -r1.82 gnome-cal.h
--- gui/gnome-cal.h	2 Jul 2003 01:33:35 -0000	1.82
+++ gui/gnome-cal.h	15 Jul 2003 22:12:51 -0000
@@ -182,6 +182,8 @@ void       gnome_calendar_paste_clipboar
 
 void       gnome_calendar_delete_selection	(GnomeCalendar  *gcal);
 void       gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal);
+void       gnome_calendar_expunge               (GnomeCalendar  *gcal,
+						 time_t older_than);
 
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]