/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Authors: Alexandre Rocha Lima e Marcondes (alexandre@p4tecnologia.com) * * Code based on mark-all-read plugin by Chenthill Palanisamy (pchenthill@novell.com) * * Copyright 2005 P4 Tecnologia e Desenvolvimento Humano Ltda.Novell, Inc. (www.p4tecnologia.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "e-util/e-error.h" #define GLADE_HOOKUP_OBJECT(component,widget,name) \ g_object_set_data_full (G_OBJECT (component), name, \ gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) #define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ g_object_set_data (G_OBJECT (component), name, widget) #define GCONF_KEY_ROOT "/apps/evolution/purge_mail/" #define GCONF_KEY_ENABLE "/enable_purge_mail" #define GCONF_KEY_INTERVAL "/delete_older_than" #define VALID_CHARS "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM" GtkWidget *common = NULL; struct purge_mail_stuff { gulong vbox_hid; gulong check_hid; gulong spin_hid; GtkWidget *vbox; GtkWidget *check; GtkWidget *spin; gchar *folderuri; }; GtkWidget* purge_mail_construct (EConfigHookItemFactoryData *hook_data, EMConfigTargetFolder *target, gchar *folderuri); GtkWidget* org_gnome_purge_mail_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data); void org_gnome_purge_mail (EPlugin *ep, EMPopupTargetFolder *target); static void purge_got_folder (char *uri, CamelFolder *folder, void *data); static void purge_all_sub_folders (CamelStore *store, CamelFolderInfo *fi, CamelException *ex); static void purge_mail (CamelFolder *folder, CamelFolderInfo *folder_info); static void cleanup_cb (GObject *o, gpointer data); static void enable_purge_mail (GtkWidget *widget, gpointer data); static void set_purge_mail_interval (GtkWidget *widget, gpointer data); void org_gnome_purge_mail (EPlugin *ep, EMPopupTargetFolder *t) { if (t->uri == NULL) { return; } mail_get_folder(t->uri, 0, purge_got_folder, NULL, mail_thread_new); } static void purge_mail (CamelFolder *folder, CamelFolderInfo *folder_info) { GConfClient *gconf; gint value; GPtrArray *uids; gboolean active; CamelMessageInfo *info; time_t curtime, msgtime; struct tm *timediff; int i, diff; uids = camel_folder_get_uids (folder); camel_folder_freeze(folder); gconf = gconf_client_get_default (); value = gconf_client_get_int (gconf, g_strconcat(GCONF_KEY_ROOT, g_strcanon(folder_info->uri,VALID_CHARS,'_'), GCONF_KEY_INTERVAL, NULL), NULL); active = gconf_client_get_bool (gconf, g_strconcat(GCONF_KEY_ROOT, g_strcanon(folder_info->uri,VALID_CHARS,'_'), GCONF_KEY_ENABLE, NULL), NULL); if (!active) { camel_folder_thaw(folder); camel_folder_free_uids (folder, uids); g_object_unref (G_OBJECT (gconf)); return; } for (i=0;ilen;i++) { info = camel_folder_get_message_info (folder, uids->pdata[i]); msgtime = camel_message_info_date_received (info); curtime = time (NULL); timediff = localtime (&curtime); diff = timediff->tm_sec + timediff->tm_min * 60 + timediff->tm_hour * 3600; if (difftime(curtime, msgtime) >= (86400 * value)) camel_folder_delete_message (folder, uids->pdata[i]); } camel_folder_thaw(folder); camel_folder_free_uids (folder, uids); g_object_unref (G_OBJECT (gconf)); } static void purge_got_folder (char *uri, CamelFolder *folder, void *data) { CamelFolderInfo *info; CamelStore *store; CamelException ex; gint response; guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_FAST; camel_exception_init (&ex); store = folder->parent_store; info = camel_store_get_folder_info (store, folder->full_name, flags, &ex); /* FIXME we have to disable the menu item */ if (!folder) return; if (camel_exception_is_set (&ex)) { camel_exception_clear (&ex); return; } if (info && (info->child || info->next)) { response = e_error_run (NULL, "mail:ask-mark-read", NULL); } else { purge_mail (folder, info); return; } if (response == GTK_RESPONSE_NO) { purge_mail (folder, info); } else if (response == GTK_RESPONSE_YES){ purge_all_sub_folders (store, info, &ex); } } static void purge_all_sub_folders (CamelStore *store, CamelFolderInfo *fi, CamelException *ex) { while (fi) { CamelFolder *folder; if (fi->child) { purge_all_sub_folders (store, fi->child, ex); if (camel_exception_is_set (ex)) return; } if (!(folder = camel_store_get_folder (store, fi->full_name, 0, ex))) return; if (!CAMEL_IS_VEE_FOLDER (folder)) { purge_mail (folder, fi); } fi = fi->next; } } static void enable_purge_mail (GtkWidget *widget, gpointer data) { struct purge_mail_stuff *stuff = (struct purge_mail_stuff *) data; GConfClient *gconf; gboolean active; gconf = gconf_client_get_default (); active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); gtk_widget_set_sensitive (GTK_WIDGET(stuff->spin), active); gconf_client_set_bool (gconf, g_strconcat(GCONF_KEY_ROOT, g_strcanon(stuff->folderuri,VALID_CHARS,'_'), GCONF_KEY_ENABLE, NULL), active, NULL); g_object_unref (G_OBJECT (gconf)); } static void set_purge_mail_interval (GtkWidget *widget, gpointer data) { struct purge_mail_stuff *stuff = (struct purge_mail_stuff *) data; GConfClient *gconf; gint value; gconf = gconf_client_get_default (); value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget)); gconf_client_set_int (gconf, g_strconcat(GCONF_KEY_ROOT, g_strcanon(stuff->folderuri,VALID_CHARS,'_'), GCONF_KEY_INTERVAL, NULL), value, NULL); g_object_unref (G_OBJECT (gconf)); } GtkWidget * org_gnome_purge_mail_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data) { gchar *folderuri = NULL; gchar *folder_name = NULL; EMConfigTargetFolder *target= (EMConfigTargetFolder *)hook_data->config->target; CamelFolder *folder = target->folder; folder_name = g_strdup (folder->full_name); folderuri = g_strdup(target->uri); /* This is kind of bad..but we don't have types for all these folders.*/ if ( !( strcmp (folder_name, "Mailbox") && strcmp (folder_name, "Calendar") && strcmp (folder_name, "Contacts") && strcmp (folder_name, "Documents") && strcmp (folder_name, "Authored") && strcmp (folder_name, "Default Library") && strcmp (folder_name, "Work In Progress") && strcmp (folder_name, "Cabinet") && strcmp (folder_name, "Sent Items") && strcmp (folder_name, "Trash") && strcmp (folder_name, "Checklist"))) { g_free (folderuri); return NULL; } common = NULL; common = purge_mail_construct(hook_data, target, folderuri); gtk_notebook_append_page((GtkNotebook *) hook_data->parent, (GtkWidget *) common, gtk_label_new_with_mnemonic N_("Purge")); return GTK_WIDGET (common); } GtkWidget* purge_mail_construct (EConfigHookItemFactoryData *hook_data, EMConfigTargetFolder *target, gchar *folderuri) { GConfClient *gconf; gconf = gconf_client_get_default (); GtkWidget *vboxPurged2 = NULL; GtkWidget *check_enabled = NULL; GtkWidget *vbox194 = NULL; GtkWidget *hbox227 = NULL; GtkWidget *lbl = NULL; GtkWidget *lblDaysOld1 = NULL; GtkWidget *lblDaysOld2 = NULL; GtkObject *spbDays_adj = NULL; GtkWidget *spbDays = NULL; struct purge_mail_stuff *stuff; stuff = g_new0 (struct purge_mail_stuff, 1); stuff->folderuri = folderuri; vboxPurged2 = gtk_vbox_new (FALSE, 6); gtk_widget_show (vboxPurged2); lbl = gtk_label_new (_(" ")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (vboxPurged2), lbl, FALSE, FALSE, 0); check_enabled = gtk_check_button_new_with_mnemonic (_("Purge _old mail")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_enabled), gconf_client_get_bool (gconf, g_strconcat(GCONF_KEY_ROOT, g_strcanon(folderuri,VALID_CHARS,'_'), GCONF_KEY_ENABLE, NULL), NULL)); stuff->check_hid = g_signal_connect (GTK_TOGGLE_BUTTON (check_enabled), "toggled", G_CALLBACK (enable_purge_mail), stuff); gtk_box_pack_start (GTK_BOX (vboxPurged2), check_enabled, FALSE, FALSE, 0); stuff->check = check_enabled; vbox194 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox194); gtk_box_pack_start (GTK_BOX (vboxPurged2), vbox194, FALSE, FALSE, 0); hbox227 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox227); gtk_box_pack_start (GTK_BOX (vbox194), hbox227, TRUE, TRUE, 0); lblDaysOld1 = gtk_label_new (_("Delete messages older than ")); gtk_widget_show (lblDaysOld1); gtk_box_pack_start (GTK_BOX (hbox227), lblDaysOld1, FALSE, FALSE, 0); spbDays_adj = gtk_adjustment_new (30, 0, 9999, 1, 10, 10); spbDays = gtk_spin_button_new (GTK_ADJUSTMENT (spbDays_adj), 1, 0); gtk_spin_button_set_value (GTK_SPIN_BUTTON (spbDays), gconf_client_get_int (gconf, g_strconcat(GCONF_KEY_ROOT,g_strcanon(folderuri,VALID_CHARS,'_'), GCONF_KEY_INTERVAL, NULL), NULL)); gtk_widget_set_sensitive (GTK_WIDGET(spbDays), gconf_client_get_bool (gconf, g_strconcat(GCONF_KEY_ROOT, g_strcanon(folderuri,VALID_CHARS,'_'), GCONF_KEY_ENABLE, NULL), NULL)); stuff->spin_hid = g_signal_connect (GTK_SPIN_BUTTON (spbDays), "value-changed", G_CALLBACK (set_purge_mail_interval), stuff); gtk_widget_show (spbDays); gtk_box_pack_start (GTK_BOX (hbox227), spbDays, TRUE, TRUE, 0); stuff->spin = spbDays; lblDaysOld2 = gtk_label_new (_(" days")); gtk_widget_show (lblDaysOld2); gtk_box_pack_start (GTK_BOX (hbox227), lblDaysOld2, FALSE, FALSE, 0); stuff->vbox_hid = g_signal_connect (vboxPurged2, "destroy", G_CALLBACK (cleanup_cb), stuff); g_object_unref (G_OBJECT (gconf)); gtk_widget_show_all (vboxPurged2); return GTK_WIDGET (vboxPurged2); } static void cleanup_cb (GObject *o, gpointer data) { struct purge_mail_stuff *stuff = data; if (g_signal_handler_is_connected (stuff->vbox, stuff->vbox_hid)) g_signal_handler_disconnect (stuff->vbox, stuff->vbox_hid); if (g_signal_handler_is_connected (stuff->spin, stuff->spin_hid)) g_signal_handler_disconnect (stuff->spin, stuff->spin_hid); if (g_signal_handler_is_connected (stuff->check, stuff->check_hid)) g_signal_handler_disconnect (stuff->check, stuff->check_hid); g_free (stuff->folderuri); g_free (stuff); }