diff options
-rw-r--r-- | mail/ChangeLog | 18 | ||||
-rw-r--r-- | mail/Makefile.am | 1 | ||||
-rw-r--r-- | mail/component-factory.c | 77 | ||||
-rw-r--r-- | mail/folder-browser-factory.c | 10 | ||||
-rw-r--r-- | mail/mail-ops.c | 177 | ||||
-rw-r--r-- | mail/mail-vfolder.c | 176 | ||||
-rw-r--r-- | mail/mail.h | 2 |
7 files changed, 272 insertions, 189 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index 945af50fff..637f43efc2 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,21 @@ +2000-07-29 Not Zed <NotZed@HelixCode.com> + + * component-factory.c (create_view): Remove hack to pass the + storage around. + + * folder-browser-factory.c (control_activate): Changed to call + renamed vfolder editor. + + * mail-ops.c (vfolder_edit_vfolders): renamed from vfolder_edit, + call new edit function. + (vfolder_editor_clicked): Removed. + (filter_druid_clicked): + (filter_edit): Updated for api change. + (real_fetch_mail): Fixed up for api change and fucked up indent. + (filter_get_folder): callback for filter driver. + + * mail-vfolder.c: New file to manage virtual folders. + 2000-07-29 JP Rosevear <jpr@helixcode.com> * mail-format.c (mail_generate_reply): Use new mail config stuff diff --git a/mail/Makefile.am b/mail/Makefile.am index ab08d1315f..c5752ac822 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -49,6 +49,7 @@ evolution_mail_SOURCES = \ mail-threads.c \ mail-threads.h \ mail-types.h \ + mail-vfolder.c \ main.c \ message-list.c \ message-list.h \ diff --git a/mail/component-factory.c b/mail/component-factory.c index 2ebd9c6961..77f61508f2 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -39,7 +39,6 @@ #include "e-util/e-gui-utils.h" #include "e-util/e-setup.h" -#include "filter/filter-driver.h" #include "component-factory.h" static void create_vfolder_storage (EvolutionShellComponent *shell_component); @@ -58,7 +57,7 @@ static const EvolutionShellComponentFolderType folder_types[] = { }; /* GROSS HACK: for passing to other parts of the program */ -EvolutionShellClient *global_shell_client = NULL; +/*EvolutionShellClient *global_shell_client = NULL;*/ /* EvolutionShellComponent methods and signals. */ @@ -84,10 +83,6 @@ create_view (EvolutionShellComponent *shell_component, g_assert (folder_browser_widget != NULL); g_assert (IS_FOLDER_BROWSER (folder_browser_widget)); - /* dum de dum, hack to let the folder browser know the storage its in */ - gtk_object_set_data (GTK_OBJECT (folder_browser_widget), "e-storage", - gtk_object_get_data(GTK_OBJECT (shell_component), "e-storage")); - *control_return = control; return EVOLUTION_SHELL_COMPONENT_OK; @@ -145,7 +140,7 @@ owner_set_cb (EvolutionShellComponent *shell_component, g_print ("evolution-mail: Yeeeh! We have an owner!\n"); /* FIXME */ /* GROSS HACK */ - global_shell_client = shell_client; + /*global_shell_client = shell_client;*/ create_vfolder_storage (shell_component); create_imap_storage (shell_component); @@ -195,75 +190,13 @@ component_factory_init (void) } } +/* FIXME: remove */ static void create_vfolder_storage (EvolutionShellComponent *shell_component) { - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - EvolutionStorage *storage; - - shell_client = evolution_shell_component_get_owner (shell_component); - if (shell_client == NULL) { - g_warning ("We have no shell!?"); - return; - } + void vfolder_create_storage(EvolutionShellComponent *shell_component); - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - storage = evolution_storage_new ("VFolders"); - if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) { - g_warning ("Cannot register storage"); - return; - } - - /* save the storage for later */ - gtk_object_set_data(GTK_OBJECT (shell_component), "e-storage", storage); - - /* this is totally not the way we want to do this - but the - filter stuff needs work before we can remove it */ - { - FilterDriver *fe; - int i, count; - char *user, *system; - - user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); - system = g_strdup_printf("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR); - fe = filter_driver_new(system, user, mail_uri_to_folder); - g_free(user); - g_free(system); - count = filter_driver_rule_count(fe); - - for (i = 0; i < count; i++) { - struct filter_option *fo; - GString *query; - struct filter_desc *desc = NULL; - char *desctext, descunknown[64]; - char *name; - - fo = filter_driver_rule_get(fe, i); - if (fo == NULL) - continue; - query = g_string_new(""); - if (fo->description) - desc = fo->description->data; - if (desc) - desctext = desc->data; - else { - sprintf(descunknown, "vfolder-%p", fo); - desctext = descunknown; - } - g_string_sprintf(query, "vfolder:%s/vfolder/%s?", evolution_dir, desctext); - filter_driver_expand_option(fe, query, NULL, fo); - name = g_strdup_printf("/%s", desctext); - evolution_storage_new_folder (storage, name, - "mail", - query->str, - desctext); - g_string_free(query, TRUE); - g_free(name); - } - gtk_object_unref(GTK_OBJECT (fe)); - } + vfolder_create_storage(shell_component); } struct create_info_s { diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c index 43820e96b7..f6ea1d3bd7 100644 --- a/mail/folder-browser-factory.c +++ b/mail/folder-browser-factory.c @@ -81,17 +81,17 @@ control_activate (BonoboControl *control, BonoboUIHandler *uih, GNOME_STOCK_PIXMAP_TRASH, 0, 0, expunge_folder, folder_browser); - bonobo_ui_handler_menu_new_item (uih, "/Tools/Filter Druid ...", _("_Filter Druid ..."), + bonobo_ui_handler_menu_new_item (uih, "/Tools/Mail Filters ...", _("Mail _Filters ..."), NULL, -1, BONOBO_UI_HANDLER_PIXMAP_NONE, 0, 0, 0, filter_edit, folder_browser); - bonobo_ui_handler_menu_new_item (uih, "/Tools/Virtual Folder Druid ...", _("_Virtual Folder Druid ..."), + bonobo_ui_handler_menu_new_item (uih, "/Tools/vFolder Editor ...", _("_vFolder Editor ..."), NULL, -1, BONOBO_UI_HANDLER_PIXMAP_NONE, 0, - 0, 0, vfolder_edit, folder_browser); + 0, 0, vfolder_edit_vfolders, folder_browser); bonobo_ui_handler_menu_new_item (uih, "/Tools/Mail Configuration ...", _("_Mail Configuration ..."), NULL, -1, @@ -139,8 +139,8 @@ control_deactivate (BonoboControl *control, BonoboUIHandler *uih, bonobo_ui_handler_menu_remove (uih, "/View/Threaded"); bonobo_ui_handler_menu_remove (uih, "/Actions/Mark all seen"); bonobo_ui_handler_menu_remove (uih, "/Actions/Expunge"); - bonobo_ui_handler_menu_remove (uih, "/Tools/Filter Druid ..."); - bonobo_ui_handler_menu_remove (uih, "/Tools/Virtual Folder Druid ..."); + bonobo_ui_handler_menu_remove (uih, "/Tools/Mail Filters ..."); + bonobo_ui_handler_menu_remove (uih, "/Tools/vFolder Editor ..."); bonobo_ui_handler_menu_remove (uih, "/Tools/Mail Configuration ..."); bonobo_ui_handler_menu_remove (uih, "/Tools/Forget Passwords"); bonobo_ui_handler_dock_remove (uih, toolbar_name); diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 281d024786..682753df9d 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -125,6 +125,12 @@ select_first_unread (CamelFolder *folder, int type, gpointer data) 0, CAMEL_MESSAGE_SEEN); } +static CamelFolder * +filter_get_folder(FilterDriver *fd, const char *uri, void *data) +{ + return mail_uri_to_folder(uri); +} + void real_fetch_mail (gpointer user_data) { @@ -134,7 +140,8 @@ real_fetch_mail (gpointer user_data) CamelStore *store = NULL, *dest_store = NULL; CamelFolder *folder = NULL, *dest_folder = NULL; char *url = NULL, *dest_url; - FilterDriver *filter = NULL; + FilterContext *fc = NULL; + FilterDriver *driver = NULL; char *userrules, *systemrules; char *tmp_mbox = NULL, *source; guint handler_id = 0; @@ -147,7 +154,7 @@ real_fetch_mail (gpointer user_data) /* If using IMAP, don't do anything... */ if (!strncmp (url, "imap:", 5)) return; - + ex = camel_exception_new (); dest_url = g_strdup_printf ("mbox://%s/local/Inbox", evolution_dir); @@ -170,6 +177,19 @@ real_fetch_mail (gpointer user_data) * temporary store first. */ if (!strncmp (url, "mbox:", 5)) { + int tmpfd; + + tmpfd = open (tmp_mbox, O_RDWR | O_CREAT | O_APPEND, 0660); + + if (tmpfd == -1) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Couldn't create temporary " + "mbox: %s", g_strerror (errno)); + async_mail_exception_dialog ("Unable to move mail", ex, fb ); + goto cleanup; + } + close (tmpfd); + /* Skip over "mbox:" plus host part (if any) of url. */ source = url + 5; if (!strncmp (source, "//", 2)) @@ -196,22 +216,22 @@ real_fetch_mail (gpointer user_data) } else { CamelFolder *sourcefolder; - store = camel_session_get_store (session, url, ex); + store = camel_session_get_store(session, url, ex); if (!store) { - async_mail_exception_dialog ("Unable to get new mail", ex, fb); + async_mail_exception_dialog("Unable to get new mail", ex, fb); goto cleanup; } - camel_service_connect (CAMEL_SERVICE (store), ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_USER_CANCEL) - async_mail_exception_dialog ("Unable to get new mail", ex, fb); + camel_service_connect(CAMEL_SERVICE (store), ex); + if (camel_exception_get_id(ex) != CAMEL_EXCEPTION_NONE) { + if (camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) + async_mail_exception_dialog("Unable to get new mail", ex, fb); goto cleanup; } - sourcefolder = camel_store_get_folder (store, "inbox", FALSE, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to get new mail", ex, fb); + sourcefolder = camel_store_get_folder(store, "inbox", FALSE, ex); + if (camel_exception_get_id(ex) != CAMEL_EXCEPTION_NONE) { + async_mail_exception_dialog("Unable to get new mail", ex, fb); goto cleanup; } @@ -277,12 +297,15 @@ real_fetch_mail (gpointer user_data) folder_browser_clear_search (fb); /* apply filtering rules to this inbox */ - userrules = g_strdup_printf ("%s/filters.xml", evolution_dir); - systemrules = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); - filter = filter_driver_new (systemrules, userrules, mail_uri_to_folder); + fc = filter_context_new(); + userrules = g_strdup_printf("%s/filters.xml", evolution_dir); + systemrules = g_strdup_printf("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); + rule_context_load((RuleContext *)fc, systemrules, userrules); g_free (userrules); g_free (systemrules); + driver = filter_driver_new(fc, filter_get_folder, 0); + /* Attach a handler to the destination folder to select the first unread * message iff it changes and iff it's the folder being viewed. */ @@ -290,7 +313,7 @@ real_fetch_mail (gpointer user_data) handler_id = gtk_signal_connect (GTK_OBJECT (dest_folder), "folder_changed", GTK_SIGNAL_FUNC (select_first_unread), fb); - if (filter_driver_run (filter, folder, dest_folder) == -1) { + if (filter_driver_run(driver, folder, dest_folder) == -1) { async_mail_exception_dialog ("Unable to get new mail", ex, fb); goto cleanup; } @@ -303,8 +326,10 @@ real_fetch_mail (gpointer user_data) unlink (tmp_mbox); /* FIXME: should use camel to do this */ g_free (tmp_mbox); - if (filter) - gtk_object_unref (GTK_OBJECT (filter)); + if (driver) + gtk_object_unref((GtkObject *)driver); + if (fc) + gtk_object_unref((GtkObject *)fc); if (url) g_free (url); @@ -877,18 +902,21 @@ expunge_folder (BonoboUIHandler *uih, void *user_data, const char *path) } static void -filter_druid_clicked (FilterEditor *fe, int button, FolderBrowser *fb) +filter_druid_clicked(GtkWidget *w, int button, FolderBrowser *fb) { + FilterContext *fc; + if (button == 0) { char *user; - user = g_strdup_printf ("%s/filters.xml", evolution_dir); - filter_editor_save_rules (fe, user); - g_free (user); + fc = gtk_object_get_data((GtkObject *)w, "context"); + user = g_strdup_printf("%s/filters.xml", evolution_dir); + rule_context_save((RuleContext *)fc, user); + g_free(user); } if (button != -1) { - gnome_dialog_close (GNOME_DIALOG (fe)); + gnome_dialog_close((GnomeDialog *)w); } } @@ -896,107 +924,34 @@ void filter_edit (BonoboUIHandler *uih, void *user_data, const char *path) { FolderBrowser *fb = FOLDER_BROWSER (user_data); - FilterEditor *fe; + FilterContext *fc; char *user, *system; + GtkWidget *w; - fe = filter_editor_new (); - - user = g_strdup_printf ("%s/filters.xml", evolution_dir); - system = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); - filter_editor_set_rule_files (fe, system, user); - g_free (user); - g_free (system); - gnome_dialog_append_buttons (GNOME_DIALOG (fe), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, 0); - gtk_signal_connect (GTK_OBJECT (fe), "clicked", filter_druid_clicked, fb); - gtk_widget_show (GTK_WIDGET (fe)); -} - -static void -vfolder_editor_clicked(FilterEditor *fe, int button, FolderBrowser *fb) -{ - if (button == 0) { - char *user; - - user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); - filter_editor_save_rules (fe, user); - g_free (user); - - /* FIXME: this is also not the way to do this, see also - component-factory.c */ - { - EvolutionStorage *storage; - FilterDriver *fe; - int i, count; - char *user, *system; - extern char *evolution_dir; - - storage = gtk_object_get_data (GTK_OBJECT (fb), "e-storage"); - - user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); - system = g_strdup_printf ("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR); - fe = filter_driver_new (system, user, mail_uri_to_folder); - g_free (user); - g_free (system); - count = filter_driver_rule_count (fe); - for (i = 0; i < count; i++) { - struct filter_option *fo; - GString *query; - struct filter_desc *desc = NULL; - char *desctext, descunknown[64]; - char *name; - - fo = filter_driver_rule_get (fe, i); - if (fo == NULL) - continue; - query = g_string_new (""); - if (fo->description) - desc = fo->description->data; - if (desc) - desctext = desc->data; - else { - sprintf (descunknown, "volder-%p", fo); - desctext = descunknown; - } - g_string_sprintf (query, "vfolder:/%s/vfolder/%s?", evolution_dir, desctext); - filter_driver_expand_option (fe, query, NULL, fo); - name = g_strdup_printf ("/%s", desctext); - evolution_storage_new_folder (storage, name, "mail", - query->str, name + 1); - g_string_free (query, TRUE); - g_free (name); - } - gtk_object_unref (GTK_OBJECT (fe)); - } - - } - if (button != -1) { - gnome_dialog_close (GNOME_DIALOG (fe)); - } + fc = filter_context_new(); + user = g_strdup_printf("%s/filters.xml", evolution_dir); + system = g_strdup_printf("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); + rule_context_load((RuleContext *)fc, system, user); + g_free(user); + g_free(system); + w = filter_editor_construct(fc); + gtk_object_set_data_full((GtkObject *)w, "context", fc, (GtkDestroyNotify)gtk_object_unref); + gtk_signal_connect((GtkObject *)w, "clicked", filter_druid_clicked, fb); + gtk_widget_show(w); } void -vfolder_edit (BonoboUIHandler *uih, void *user_data, const char *path) +vfolder_edit_vfolders (BonoboUIHandler *uih, void *user_data, const char *path) { - FolderBrowser *fb = FOLDER_BROWSER (user_data); - FilterEditor *fe; - char *user, *system; - - fe = filter_editor_new (); + void vfolder_edit(void); - user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); - system = g_strdup_printf ("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR); - filter_editor_set_rule_files (fe, system, user); - g_free (user); - g_free (system); - gnome_dialog_append_buttons (GNOME_DIALOG (fe), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, 0); - gtk_signal_connect (GTK_OBJECT (fe), "clicked", vfolder_editor_clicked, fb); - gtk_widget_show (GTK_WIDGET (fe)); + vfolder_edit(); } void providers_config (BonoboUIHandler *uih, void *user_data, const char *path) { - mail_config (); + mail_config(); } void diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c new file mode 100644 index 0000000000..cef814082a --- /dev/null +++ b/mail/mail-vfolder.c @@ -0,0 +1,176 @@ +/* + Copyright 2000 Helix Code Inc. + + Author: Michael Zucchi <notzed@helixcode.com> + + code for managing vfolders + + NOTE: dont run this through fucking indent. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <bonobo.h> + +#include "Evolution.h" +#include "evolution-storage.h" + +#include "evolution-shell-component.h" +#include "folder-browser.h" + +#include "filter/vfolder-context.h" +#include "filter/filter-rule.h" +#include "filter/vfolder-editor.h" + +struct _vfolder_info { + char *name; + char *query; +}; + +/* list of vfolders available */ +static GList *available_vfolders = NULL; +static VfolderContext *context; +static EvolutionStorage *vfolder_storage; + +/* GROSS HACK: for passing to other parts of the program */ +EvolutionShellClient *global_shell_client = NULL; +extern char *evolution_dir; + +static struct _vfolder_info * +vfolder_find(char *name) +{ + GList *l = available_vfolders; + struct _vfolder_info *info; + + while (l) { + info = l->data; + if (!strcmp(info->name, name)) + return info; + l = g_list_next(l); + } + return NULL; +} + +/* go through the list of what we have, what we want, and make + them match, deleting/reconfiguring as required */ +static void +vfolder_refresh(void) +{ + GList *l; + GList *head = NULL; /* processed list */ + struct _vfolder_info *info; + FilterRule *rule; + GString *expr = g_string_new(""); + char *uri, *path; + + rule = NULL; + while ( (rule = rule_context_next_rule((RuleContext *)context, rule)) ) { + info = vfolder_find(rule->name); + g_string_truncate(expr, 0); + filter_rule_build_code(rule, expr); + if (info) { + available_vfolders = g_list_remove(available_vfolders, info); + + /* check if the rule has changed ... otherwise, leave it */ + if (strcmp(expr->str, info->query)) { + printf("Must reconfigure vfolder with new rule?\n"); + g_free(info->query); + info->query = g_strdup(expr->str); + + uri = g_strdup_printf("vfolder:%s/vfolder/%s?%s", evolution_dir, info->name, info->query); + path = g_strdup_printf("/%s", info->name); + evolution_storage_removed_folder(vfolder_storage, path); + evolution_storage_new_folder (vfolder_storage, path, + "mail", + uri, + info->name); + g_free(uri); + g_free(path); + } + } else { + info = g_malloc(sizeof(*info)); + info->name = g_strdup(rule->name); + info->query = g_strdup(expr->str); + printf("Adding new vfolder: %s %s\n", rule->name, expr->str); + + uri = g_strdup_printf("vfolder:%s/vfolder/%s?%s", evolution_dir, info->name, info->query); + path = g_strdup_printf("/%s", info->name); + evolution_storage_new_folder (vfolder_storage, path, + "mail", + uri, + info->name); + g_free(uri); + g_free(path); + } + head = g_list_append(head, info); + } + /* everything in available_vfolders are to be removed ... */ + l = available_vfolders; + while (l) { + info = l->data; + printf("removing vfolders %s %s\n", info->name, info->query); + path = g_strdup_printf("/%s", info->name); + evolution_storage_removed_folder(vfolder_storage, path); + g_free(path); + g_free(info->name); + g_free(info->query); + l = g_list_next(l); + } + g_list_free(available_vfolders); + available_vfolders = head; + g_string_free(expr, TRUE); +} + +void +vfolder_create_storage(EvolutionShellComponent *shell_component) +{ + EvolutionShellClient *shell_client; + Evolution_Shell corba_shell; + EvolutionStorage *storage; + char *user, *system; + + shell_client = evolution_shell_component_get_owner (shell_component); + if (shell_client == NULL) { + g_warning ("We have no shell!?"); + return; + } + global_shell_client = shell_client; + + corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); + + storage = evolution_storage_new ("VFolders"); + if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) { + g_warning ("Cannot register storage"); + return; + } + + vfolder_storage = storage; + + user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); + system = g_strdup_printf("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR); + + context = vfolder_context_new(); + printf("loading rules %s %s\n", system, user); + if (rule_context_load((RuleContext *)context, system, user) != 0) { + g_warning("cannot load vfolders: %s\n", ((RuleContext *)context)->error); + } + g_free(user); + g_free(system); + vfolder_refresh(); +} + +void +vfolder_edit(void) +{ + GtkWidget *w; + char *user; + + w = vfolder_editor_construct(context); + if (gnome_dialog_run_and_close((GnomeDialog *)w) == 0) { + user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); + rule_context_save(context, user); + g_free(user); + vfolder_refresh(); + } +} diff --git a/mail/mail.h b/mail/mail.h index 7376114886..9cf857cd7f 100644 --- a/mail/mail.h +++ b/mail/mail.h @@ -58,7 +58,7 @@ void print_msg (GtkWidget *button, gpointer user_data); void mark_all_seen (BonoboUIHandler *uih, void *user_data, const char *path); void expunge_folder (BonoboUIHandler *uih, void *user_data, const char *path); void filter_edit (BonoboUIHandler *uih, void *user_data, const char *path); -void vfolder_edit (BonoboUIHandler *uih, void *user_data, const char *path); +void vfolder_edit_vfolders (BonoboUIHandler *uih, void *user_data, const char *path); void providers_config (BonoboUIHandler *uih, void *user_data, const char *path); /* session */ |