diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2012-01-18 00:07:19 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2012-01-19 12:48:47 +0800 |
commit | 61ae36351b24cc676f60483d576706bf827f2987 (patch) | |
tree | c55d9e000efd47fa14865fad2defa79b5ed61ffd /mail | |
parent | 37644b9d257369c5c158121ca4807cafbe844595 (diff) | |
download | gsoc2013-evolution-61ae36351b24cc676f60483d576706bf827f2987.tar.gz gsoc2013-evolution-61ae36351b24cc676f60483d576706bf827f2987.tar.zst gsoc2013-evolution-61ae36351b24cc676f60483d576706bf827f2987.zip |
Introduce libemail-engine and libemail-utils.
These libraries are bound for E-D-S so they live at the lowest layer of
Evolution for now -- even libeutil can link to them (but please don't).
This is the first step toward moving mail handing to a D-Bus service.
Diffstat (limited to 'mail')
81 files changed, 1465 insertions, 12564 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am index 8310cff129..b80d56cb8e 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -4,14 +4,6 @@ privsolib_LTLIBRARIES = libevolution-mail.la mailincludedir = $(privincludedir)/mail -include $(top_srcdir)/glib-gen.mak -glib_enum_headers=e-mail-enums.h -glib_enum_output=e-mail-enumtypes -glib_enum_define=E_MAIL -glib_enum_prefix=e_mail - -ENUM_GENERATED = e-mail-enumtypes.h e-mail-enumtypes.c - libevolution_mail_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ -I$(top_srcdir)/widgets \ @@ -53,11 +45,7 @@ mailinclude_HEADERS = \ e-mail-backend.h \ e-mail-browser.h \ e-mail-display.h \ - e-mail-enums.h \ - e-mail-enumtypes.h \ e-mail-folder-pane.h \ - e-mail-folder-utils.h \ - e-mail-junk-filter.h \ e-mail-junk-options.h \ e-mail-label-action.h \ e-mail-label-dialog.h \ @@ -70,10 +58,8 @@ mailinclude_HEADERS = \ e-mail-paned-view.h \ e-mail-reader-utils.h \ e-mail-reader.h \ - e-mail-session-utils.h \ - e-mail-session.h \ + e-mail-ui-session.h \ e-mail-sidebar.h \ - e-mail-store-utils.h \ e-mail-tag-editor.h \ e-mail-view.h \ em-account-editor.h \ @@ -104,13 +90,8 @@ mailinclude_HEADERS = \ em-vfolder-editor.h \ em-vfolder-rule.h \ mail-autofilter.h \ - mail-config.h \ - mail-folder-cache.h \ mail-guess-servers.h \ - mail-mt.h \ - mail-ops.h \ mail-send-recv.h \ - mail-tools.h \ mail-vfolder.h \ message-list.h @@ -129,10 +110,7 @@ libevolution_mail_la_SOURCES = \ e-mail-backend.c \ e-mail-browser.c \ e-mail-display.c \ - e-mail-enumtypes.c \ e-mail-folder-pane.c \ - e-mail-folder-utils.c \ - e-mail-junk-filter.c \ e-mail-junk-options.c \ e-mail-label-action.c \ e-mail-label-dialog.c \ @@ -145,10 +123,8 @@ libevolution_mail_la_SOURCES = \ e-mail-paned-view.c \ e-mail-reader-utils.c \ e-mail-reader.c \ - e-mail-session-utils.c \ - e-mail-session.c \ + e-mail-ui-session.c \ e-mail-sidebar.c \ - e-mail-store-utils.c \ e-mail-tag-editor.c \ e-mail-view.c \ em-account-editor.c \ @@ -179,13 +155,8 @@ libevolution_mail_la_SOURCES = \ em-vfolder-editor.c \ em-vfolder-rule.c \ mail-autofilter.c \ - mail-config.c \ - mail-folder-cache.c \ mail-guess-servers.c \ - mail-mt.c \ - mail-ops.c \ mail-send-recv.c \ - mail-tools.c \ mail-vfolder.c \ message-list.c @@ -202,6 +173,8 @@ SMIME_LIBS = \ endif libevolution_mail_la_LIBADD = \ + $(top_builddir)/libemail-utils/libemail-utils.la \ + $(top_builddir)/libemail-engine/libemail-engine.la \ $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/composer/libcomposer.la \ @@ -307,7 +280,7 @@ endif dist-hook: cd $(distdir); rm -f $(BUILT_SOURCES) -BUILT_SOURCES = $(error_DATA) $(ENUM_GENERATED) +BUILT_SOURCES = $(error_DATA) CLEANFILES = $(BUILT_SOURCES) diff --git a/mail/e-mail-account-manager.c b/mail/e-mail-account-manager.c index 522e26e94c..86a0bf5e4b 100644 --- a/mail/e-mail-account-manager.c +++ b/mail/e-mail-account-manager.c @@ -22,7 +22,7 @@ #include <glib/gi18n-lib.h> #include <gdk/gdkkeysyms.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> #include <mail/e-mail-account-tree-view.h> #define E_MAIL_ACCOUNT_MANAGER_GET_PRIVATE(obj) \ diff --git a/mail/e-mail-account-manager.h b/mail/e-mail-account-manager.h index 23f7890500..63e52b463c 100644 --- a/mail/e-mail-account-manager.h +++ b/mail/e-mail-account-manager.h @@ -20,8 +20,8 @@ #define E_MAIL_ACCOUNT_MANAGER_H #include <gtk/gtk.h> -#include <e-util/e-account-utils.h> #include <mail/e-mail-account-store.h> +#include <libemail-utils/e-account-utils.h> /* Standard GObject macros */ #define E_TYPE_MAIL_ACCOUNT_MANAGER \ diff --git a/mail/e-mail-account-store.c b/mail/e-mail-account-store.c index e5a630850c..c14f75e4e5 100644 --- a/mail/e-mail-account-store.c +++ b/mail/e-mail-account-store.c @@ -25,9 +25,11 @@ #include <libebackend/e-extensible.h> #include <e-util/e-marshal.h> -#include <e-util/e-account-utils.h> #include <e-util/e-alert-dialog.h> -#include <mail/mail-ops.h> + +#include <libemail-utils/e-account-utils.h> +#include <libemail-engine/mail-ops.h> + #include <mail/mail-vfolder.h> #define E_MAIL_ACCOUNT_STORE_GET_PRIVATE(obj) \ @@ -462,9 +464,16 @@ mail_account_store_service_removed (EMailAccountStore *store, EAccountList *account_list; EAccount *account; + EMailSession *session; + MailFolderCache *cache; CamelProvider *provider; const gchar *uid; + session = e_mail_account_store_get_session (store); + cache = e_mail_session_get_folder_cache (session); + + mail_folder_cache_service_removed (cache, service); + account_list = e_get_account_list (); uid = camel_service_get_uid (service); account = e_get_account_by_uid (uid); @@ -497,9 +506,16 @@ mail_account_store_service_enabled (EMailAccountStore *store, * The 'busy_count' is bumped until changes are written back * to the D-Bus service. For now I guess we'll just block. */ + EMailSession *session; + MailFolderCache *cache; GSettings *settings; const gchar *uid; + session = e_mail_account_store_get_session (store); + cache = e_mail_session_get_folder_cache (session); + + mail_folder_cache_service_enabled (cache, service); + uid = camel_service_get_uid (service); /* Handle built-in services that don't have an EAccount. */ @@ -541,9 +557,16 @@ mail_account_store_service_disabled (EMailAccountStore *store, * The 'busy_count' is bumped until changes are written back * to the D-Bus service. For now I guess we'll just block. */ + EMailSession *session; + MailFolderCache *cache; GSettings *settings; const gchar *uid; + session = e_mail_account_store_get_session (store); + cache = e_mail_session_get_folder_cache (session); + + mail_folder_cache_service_disabled (cache, service); + uid = camel_service_get_uid (service); /* Handle built-in services that don't have an EAccount. */ @@ -1096,6 +1119,10 @@ e_mail_account_store_add_service (EMailAccountStore *store, /* This populates the rest of the columns. */ mail_account_store_update_row (store, service, &iter); + /* No need to connect to "service-added" emissions since it's + * always immediately followed by either "service-enabled" or + * "service-disabled" in MailFolderCache */ + g_signal_emit (store, signals[SERVICE_ADDED], 0, service); if (enabled) @@ -1115,7 +1142,7 @@ e_mail_account_store_remove_service (EMailAccountStore *store, CamelService *service) { GtkTreeIter iter; - gboolean proceed = TRUE; + gboolean proceed; g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store)); g_return_if_fail (CAMEL_IS_SERVICE (service)); @@ -1148,7 +1175,7 @@ e_mail_account_store_enable_service (EMailAccountStore *store, CamelService *service) { GtkTreeIter iter; - gboolean proceed = TRUE; + gboolean proceed; g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store)); g_return_if_fail (CAMEL_IS_SERVICE (service)); @@ -1166,7 +1193,6 @@ e_mail_account_store_enable_service (EMailAccountStore *store, gtk_list_store_set ( GTK_LIST_STORE (store), &iter, E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED, TRUE, -1); - g_signal_emit (store, signals[SERVICE_ENABLED], 0, service); } } @@ -1177,7 +1203,7 @@ e_mail_account_store_disable_service (EMailAccountStore *store, CamelService *service) { GtkTreeIter iter; - gboolean proceed = TRUE; + gboolean proceed; g_return_if_fail (E_IS_MAIL_ACCOUNT_STORE (store)); g_return_if_fail (CAMEL_IS_SERVICE (service)); @@ -1195,7 +1221,6 @@ e_mail_account_store_disable_service (EMailAccountStore *store, gtk_list_store_set ( GTK_LIST_STORE (store), &iter, E_MAIL_ACCOUNT_STORE_COLUMN_ENABLED, FALSE, -1); - g_signal_emit (store, signals[SERVICE_DISABLED], 0, service); } } diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c index 2f769e9c42..921b2d0efc 100644 --- a/mail/e-mail-backend.c +++ b/mail/e-mail-backend.c @@ -32,26 +32,29 @@ #include <glib/gstdio.h> #include <libedataserver/e-data-server-util.h> -#include "e-util/e-account-utils.h" -#include "e-util/e-alert-dialog.h" -#include "e-util/e-alert-sink.h" - -#include "misc/e-account-combo-box.h" - -#include "shell/e-shell.h" - -#include "mail/e-mail-folder-utils.h" -#include "mail/e-mail-migrate.h" -#include "mail/e-mail-session.h" -#include "mail/e-mail-store-utils.h" -#include "mail/em-event.h" -#include "mail/em-folder-tree-model.h" -#include "mail/em-utils.h" -#include "mail/mail-autofilter.h" -#include "mail/mail-config.h" -#include "mail/mail-folder-cache.h" -#include "mail/mail-ops.h" -#include "mail/mail-vfolder.h" +#include <shell/e-shell.h> + +#include <e-util/e-alert-dialog.h> +#include <e-util/e-alert-sink.h> + +#include <misc/e-account-combo-box.h> + +#include <libemail-utils/e-account-utils.h> +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/e-mail-session.h> +#include <libemail-engine/e-mail-store-utils.h> +#include <libemail-engine/mail-config.h> +#include <libemail-engine/mail-folder-cache.h> +#include <libemail-engine/mail-ops.h> + +#include <mail/e-mail-migrate.h> +#include <mail/e-mail-ui-session.h> +#include <mail/em-event.h> +#include <mail/em-folder-tree-model.h> +#include <mail/em-utils.h> +#include <mail/mail-autofilter.h> +#include <mail/mail-send-recv.h> +#include <mail/mail-vfolder.h> #define E_MAIL_BACKEND_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -760,6 +763,132 @@ mail_backend_finalize (GObject *object) } static void +mail_backend_add_store (EMailSession *session, + CamelStore *store, + EMailBackend *backend) +{ + EMFolderTreeModel *model; + + model = em_folder_tree_model_get_default (); + em_folder_tree_model_add_store (model, store); +} + +static void +mail_backend_remove_store (EMailSession *session, + CamelStore *store, + EMailBackend *backend) +{ + EMFolderTreeModel *model; + + model = em_folder_tree_model_get_default (); + em_folder_tree_model_remove_store (model, store); +} + +#define SET_ACITIVITY(cancellable, activity) \ + g_object_set_data (G_OBJECT (cancellable), "e-activity", activity) +#define GET_ACITIVITY(cancellable) \ + g_object_get_data (G_OBJECT (cancellable), "e-activity") + +static void +mail_mt_create_activity (GCancellable *cancellable) +{ + EActivity *activity; + + activity = e_activity_new (); + e_activity_set_percent (activity, 0.0); + e_activity_set_cancellable (activity, cancellable); + SET_ACITIVITY (cancellable, activity); +} + +static void +mail_mt_submit_activity (GCancellable *cancellable) +{ + EShell *shell; + EShellBackend *shell_backend; + EActivity *activity; + + shell = e_shell_get_default (); + shell_backend = e_shell_get_backend_by_name ( + shell, "mail"); + + activity = GET_ACITIVITY (cancellable); + if (activity) + e_shell_backend_add_activity (shell_backend, activity); + +} + +static void +mail_mt_free_activity (GCancellable *cancellable) +{ + EActivity *activity = GET_ACITIVITY (cancellable); + + if (activity) + g_object_unref (activity); +} + +static void +mail_mt_complete_acitivity (GCancellable *cancellable) +{ + EActivity *activity = GET_ACITIVITY (cancellable); + + if (activity) + e_activity_set_state (activity, E_ACTIVITY_COMPLETED); +} + +static void +mail_mt_cancel_activity (GCancellable *cancellable) +{ + EActivity *activity = GET_ACITIVITY (cancellable); + + if (activity) + e_activity_set_state (activity, E_ACTIVITY_CANCELLED); +} + +static void +mail_mt_alert_error (GCancellable *cancellable, + const char *what, + const char *message) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window = NULL; + EShellContent *shell_content; + GList *list, *iter; + GtkApplication *application; + + shell = e_shell_get_default (); + application = GTK_APPLICATION (shell); + list = gtk_application_get_windows (application); + + /* Find the most recently used EShellWindow. */ + for (iter = list; iter != NULL; iter = g_list_next (iter)) { + if (E_IS_SHELL_WINDOW (iter->data)) { + shell_window = E_SHELL_WINDOW (iter->data); + break; + } + } + + /* If we can't find an EShellWindow then... well, screw it. */ + if (shell_window == NULL) + return; + + shell_view = e_shell_window_get_shell_view ( + shell_window, "mail"); + shell_content = e_shell_view_get_shell_content (shell_view); + + if (what) { + e_alert_submit ( + E_ALERT_SINK (shell_content), + "mail:async-error", what, + message, NULL); + } else + e_alert_submit ( + E_ALERT_SINK (shell_content), + "mail:async-error-nodescribe", + message, NULL); +} + +static void mail_backend_constructed (GObject *object) { EMailBackendPrivate *priv; @@ -777,7 +906,11 @@ mail_backend_constructed (GObject *object) camel_provider_init (); - priv->session = e_mail_session_new (); + priv->session = e_mail_ui_session_new (); + + g_signal_connect ( + priv->session, "flush-outbox", + G_CALLBACK (mail_send), priv->session); g_object_bind_property ( shell, "online", @@ -806,6 +939,16 @@ mail_backend_constructed (GObject *object) e_account_combo_box_set_session (CAMEL_SESSION (priv->session)); g_signal_connect ( + priv->session, "store-added", + G_CALLBACK (mail_backend_add_store), + shell_backend); + + g_signal_connect ( + priv->session, "store-removed", + G_CALLBACK (mail_backend_remove_store), + shell_backend); + + g_signal_connect ( shell, "prepare-for-offline", G_CALLBACK (mail_backend_prepare_for_offline_cb), shell_backend); @@ -844,6 +987,14 @@ mail_backend_constructed (GObject *object) mail_config_init (priv->session); mail_msg_init (); + mail_msg_register_activities ( + mail_mt_create_activity, + mail_mt_submit_activity, + mail_mt_free_activity, + mail_mt_complete_acitivity, + mail_mt_cancel_activity, + mail_mt_alert_error); + /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (e_mail_backend_parent_class)->constructed (object); } diff --git a/mail/e-mail-backend.h b/mail/e-mail-backend.h index 6279d3fb5e..b44b330a9f 100644 --- a/mail/e-mail-backend.h +++ b/mail/e-mail-backend.h @@ -26,8 +26,8 @@ #ifndef E_MAIL_BACKEND_H #define E_MAIL_BACKEND_H -#include <mail/e-mail-session.h> #include <shell/e-shell-backend.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define E_TYPE_MAIL_BACKEND \ diff --git a/mail/e-mail-enums.h b/mail/e-mail-enums.h deleted file mode 100644 index e0ad3ad86f..0000000000 --- a/mail/e-mail-enums.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * e-mail-enums.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_ENUMS_H -#define E_MAIL_ENUMS_H - -#include <glib.h> - -G_BEGIN_DECLS - -typedef enum { - E_MAIL_DISPLAY_STYLE_NORMAL, - E_MAIL_DISPLAY_STYLE_FULL_HEADERS, - E_MAIL_DISPLAY_STYLE_SOURCE -} EMailDisplayStyle; - -typedef enum { - E_MAIL_FORWARD_STYLE_ATTACHED, - E_MAIL_FORWARD_STYLE_INLINE, - E_MAIL_FORWARD_STYLE_QUOTED -} EMailForwardStyle; - -typedef enum { - E_MAIL_IMAGE_LOADING_POLICY_NEVER, - E_MAIL_IMAGE_LOADING_POLICY_SOMETIMES, - E_MAIL_IMAGE_LOADING_POLICY_ALWAYS -} EMailImageLoadingPolicy; - -/* XXX E_MAIL_FOLDER_TEMPLATES is a prime example of why templates - * should be a core feature: the mailer now has to know about - * this specific plugin, which defeats the purpose of plugins. */ -typedef enum { - E_MAIL_LOCAL_FOLDER_INBOX, - E_MAIL_LOCAL_FOLDER_DRAFTS, - E_MAIL_LOCAL_FOLDER_OUTBOX, - E_MAIL_LOCAL_FOLDER_SENT, - E_MAIL_LOCAL_FOLDER_TEMPLATES, - E_MAIL_LOCAL_FOLDER_LOCAL_INBOX, - E_MAIL_NUM_LOCAL_FOLDERS -} EMailLocalFolder; - -typedef enum { - E_MAIL_REPLY_STYLE_QUOTED, - E_MAIL_REPLY_STYLE_DO_NOT_QUOTE, - E_MAIL_REPLY_STYLE_ATTACH, - E_MAIL_REPLY_STYLE_OUTLOOK -} EMailReplyStyle; - -typedef enum { - E_MAIL_REPLY_TO_SENDER, - E_MAIL_REPLY_TO_RECIPIENT, - E_MAIL_REPLY_TO_FROM, - E_MAIL_REPLY_TO_ALL, - E_MAIL_REPLY_TO_LIST -} EMailReplyType; - -G_END_DECLS - -#endif /* E_MAIL_ENUMS_H */ diff --git a/mail/e-mail-folder-pane.c b/mail/e-mail-folder-pane.c index 277228071e..7e0457e3bd 100644 --- a/mail/e-mail-folder-pane.c +++ b/mail/e-mail-folder-pane.c @@ -30,18 +30,22 @@ #include "e-util/e-util.h" #include "e-util/e-plugin-ui.h" + #include "shell/e-shell.h" #include "shell/e-shell-utils.h" + #include "widgets/misc/e-popup-action.h" #include "widgets/misc/e-preview-pane.h" +#include "libemail-engine/e-mail-utils.h" +#include "libemail-engine/mail-tools.h" + #include "mail/e-mail-reader.h" #include "mail/e-mail-reader-utils.h" #include "mail/em-folder-tree-model.h" #include "mail/em-format-html-display.h" #include "mail/em-composer-utils.h" #include "mail/em-utils.h" -#include "mail/mail-tools.h" #include "mail/message-list.h" #define E_MAIL_FOLDER_PANE_GET_PRIVATE(obj) \ diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c deleted file mode 100644 index fe093adb21..0000000000 --- a/mail/e-mail-folder-utils.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* - * e-mail-folder-utils.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-mail-folder-utils.h" - -#include <glib/gi18n-lib.h> - -#include "mail/mail-tools.h" - -/* X-Mailer header value */ -#define X_MAILER ("Evolution " VERSION SUB_VERSION " " VERSION_COMMENT) - -typedef struct _AsyncContext AsyncContext; - -struct _AsyncContext { - CamelMimeMessage *message; - CamelMessageInfo *info; - CamelMimePart *part; - GHashTable *hash_table; - GPtrArray *ptr_array; - GFile *destination; - gchar *fwd_subject; - gchar *message_uid; -}; - -static void -async_context_free (AsyncContext *context) -{ - if (context->message != NULL) - g_object_unref (context->message); - - if (context->info != NULL) - camel_message_info_free (context->info); - - if (context->part != NULL) - g_object_unref (context->part); - - if (context->hash_table != NULL) - g_hash_table_unref (context->hash_table); - - if (context->ptr_array != NULL) - g_ptr_array_unref (context->ptr_array); - - if (context->destination != NULL) - g_object_unref (context->destination); - - g_free (context->fwd_subject); - g_free (context->message_uid); - - g_slice_free (AsyncContext, context); -} - -static void -mail_folder_append_message_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_mail_folder_append_message_sync ( - CAMEL_FOLDER (object), context->message, - context->info, &context->message_uid, - cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -gboolean -e_mail_folder_append_message_sync (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info, - gchar **appended_uid, - GCancellable *cancellable, - GError **error) -{ - CamelMedium *medium; - gboolean success; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE); - - medium = CAMEL_MEDIUM (message); - - camel_operation_push_message ( - cancellable, - _("Saving message to folder '%s'"), - camel_folder_get_full_name (folder)); - - if (camel_medium_get_header (medium, "X-Mailer") == NULL) - camel_medium_set_header (medium, "X-Mailer", X_MAILER); - - camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); - - success = camel_folder_append_message_sync ( - folder, message, info, appended_uid, cancellable, error); - - camel_operation_pop_message (cancellable); - - return success; -} - -void -e_mail_folder_append_message (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - - context = g_slice_new0 (AsyncContext); - context->message = g_object_ref (message); - - if (info != NULL) - context->info = camel_message_info_ref (info); - - simple = g_simple_async_result_new ( - G_OBJECT (folder), callback, user_data, - e_mail_folder_append_message); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, mail_folder_append_message_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_folder_append_message_finish (CamelFolder *folder, - GAsyncResult *result, - gchar **appended_uid, - GError **error) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (folder), - e_mail_folder_append_message), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (appended_uid != NULL) { - *appended_uid = context->message_uid; - context->message_uid = NULL; - } - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_folder_build_attachment_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - context->part = e_mail_folder_build_attachment_sync ( - CAMEL_FOLDER (object), context->ptr_array, - &context->fwd_subject, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -CamelMimePart * -e_mail_folder_build_attachment_sync (CamelFolder *folder, - GPtrArray *message_uids, - gchar **fwd_subject, - GCancellable *cancellable, - GError **error) -{ - GHashTable *hash_table; - CamelMimeMessage *message; - CamelMimePart *part; - const gchar *uid; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - g_return_val_if_fail (message_uids != NULL, NULL); - - /* Need at least one message UID to make an attachment. */ - g_return_val_if_fail (message_uids->len > 0, NULL); - - hash_table = e_mail_folder_get_multiple_messages_sync ( - folder, message_uids, cancellable, error); - - if (hash_table == NULL) - return NULL; - - /* Create the forward subject from the first message. */ - - uid = g_ptr_array_index (message_uids, 0); - g_return_val_if_fail (uid != NULL, NULL); - - message = g_hash_table_lookup (hash_table, uid); - g_return_val_if_fail (message != NULL, NULL); - - if (fwd_subject != NULL) - *fwd_subject = mail_tool_generate_forward_subject (message); - - if (message_uids->len == 1) { - part = mail_tool_make_message_attachment (message); - - } else { - CamelMultipart *multipart; - guint ii; - - multipart = camel_multipart_new (); - camel_data_wrapper_set_mime_type ( - CAMEL_DATA_WRAPPER (multipart), "multipart/digest"); - camel_multipart_set_boundary (multipart, NULL); - - for (ii = 0; ii < message_uids->len; ii++) { - uid = g_ptr_array_index (message_uids, ii); - g_return_val_if_fail (uid != NULL, NULL); - - message = g_hash_table_lookup (hash_table, uid); - g_return_val_if_fail (message != NULL, NULL); - - part = mail_tool_make_message_attachment (message); - camel_multipart_add_part (multipart, part); - g_object_unref (part); - } - - part = camel_mime_part_new (); - - camel_medium_set_content ( - CAMEL_MEDIUM (part), - CAMEL_DATA_WRAPPER (multipart)); - - camel_mime_part_set_description ( - part, _("Forwarded messages")); - - g_object_unref (multipart); - } - - g_hash_table_unref (hash_table); - - return part; -} - -void -e_mail_folder_build_attachment (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (message_uids != NULL); - - /* Need at least one message UID to make an attachment. */ - g_return_if_fail (message_uids->len > 0); - - context = g_slice_new0 (AsyncContext); - context->ptr_array = g_ptr_array_ref (message_uids); - - simple = g_simple_async_result_new ( - G_OBJECT (folder), callback, user_data, - e_mail_folder_build_attachment); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, mail_folder_build_attachment_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -CamelMimePart * -e_mail_folder_build_attachment_finish (CamelFolder *folder, - GAsyncResult *result, - gchar **fwd_subject, - GError **error) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (folder), - e_mail_folder_build_attachment), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - if (fwd_subject != NULL) { - *fwd_subject = context->fwd_subject; - context->fwd_subject = NULL; - } - - g_return_val_if_fail (CAMEL_IS_MIME_PART (context->part), NULL); - - return g_object_ref (context->part); -} - -static void -mail_folder_find_duplicate_messages_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - context->hash_table = e_mail_folder_find_duplicate_messages_sync ( - CAMEL_FOLDER (object), context->ptr_array, - cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -GHashTable * -e_mail_folder_find_duplicate_messages_sync (CamelFolder *folder, - GPtrArray *message_uids, - GCancellable *cancellable, - GError **error) -{ - GQueue trash = G_QUEUE_INIT; - GHashTable *hash_table; - GHashTable *unique_ids; - GHashTableIter iter; - gpointer key, value; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - g_return_val_if_fail (message_uids != NULL, NULL); - - /* hash_table = { MessageUID : CamelMessage } */ - hash_table = e_mail_folder_get_multiple_messages_sync ( - folder, message_uids, cancellable, error); - - if (hash_table == NULL) - return NULL; - - camel_operation_push_message ( - cancellable, _("Scanning messages for duplicates")); - - unique_ids = g_hash_table_new_full ( - (GHashFunc) g_int64_hash, - (GEqualFunc) g_int64_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - - g_hash_table_iter_init (&iter, hash_table); - - while (g_hash_table_iter_next (&iter, &key, &value)) { - const CamelSummaryMessageID *message_id; - CamelDataWrapper *content; - CamelMessageFlags flags; - CamelMessageInfo *info; - CamelStream *stream; - GByteArray *buffer; - gboolean duplicate; - gssize n_bytes; - gchar *digest; - - info = camel_folder_get_message_info (folder, key); - message_id = camel_message_info_message_id (info); - flags = camel_message_info_flags (info); - - /* Skip messages marked for deletion. */ - if (flags & CAMEL_MESSAGE_DELETED) { - g_queue_push_tail (&trash, key); - camel_message_info_free (info); - continue; - } - - /* Generate a digest string from the message's content. */ - - content = camel_medium_get_content (CAMEL_MEDIUM (value)); - - if (content == NULL) { - g_queue_push_tail (&trash, key); - camel_message_info_free (info); - continue; - } - - stream = camel_stream_mem_new (); - - n_bytes = camel_data_wrapper_decode_to_stream_sync ( - content, stream, cancellable, error); - - if (n_bytes < 0) { - camel_message_info_free (info); - g_object_unref (stream); - goto fail; - } - - /* The CamelStreamMem owns the buffer. */ - buffer = camel_stream_mem_get_byte_array ( - CAMEL_STREAM_MEM (stream)); - g_return_val_if_fail (buffer != NULL, NULL); - - digest = g_compute_checksum_for_data ( - G_CHECKSUM_SHA256, buffer->data, buffer->len); - - g_object_unref (stream); - - /* Determine if the message a duplicate. */ - - value = g_hash_table_lookup (unique_ids, &message_id->id.id); - duplicate = (value != NULL) && g_str_equal (digest, value); - - if (duplicate) - g_free (digest); - else { - gint64 *v_int64; - - /* XXX Might be better to create a GArray - * of 64-bit integers and have the hash - * table keys point to array elements. */ - v_int64 = g_new0 (gint64, 1); - *v_int64 = (gint64) message_id->id.id; - - g_hash_table_insert (unique_ids, v_int64, digest); - g_queue_push_tail (&trash, key); - } - - camel_message_info_free (info); - } - - /* Delete all non-duplicate messages from the hash table. */ - while ((key = g_queue_pop_head (&trash)) != NULL) - g_hash_table_remove (hash_table, key); - - goto exit; - -fail: - g_hash_table_destroy (hash_table); - hash_table = NULL; - -exit: - camel_operation_pop_message (cancellable); - - g_hash_table_destroy (unique_ids); - - return hash_table; -} - -void -e_mail_folder_find_duplicate_messages (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (message_uids != NULL); - - context = g_slice_new0 (AsyncContext); - context->ptr_array = g_ptr_array_ref (message_uids); - - simple = g_simple_async_result_new ( - G_OBJECT (folder), callback, user_data, - e_mail_folder_find_duplicate_messages); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, mail_folder_find_duplicate_messages_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -GHashTable * -e_mail_folder_find_duplicate_messages_finish (CamelFolder *folder, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (folder), - e_mail_folder_find_duplicate_messages), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - return g_hash_table_ref (context->hash_table); -} - -static void -mail_folder_get_multiple_messages_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - context->hash_table = e_mail_folder_get_multiple_messages_sync ( - CAMEL_FOLDER (object), context->ptr_array, - cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -GHashTable * -e_mail_folder_get_multiple_messages_sync (CamelFolder *folder, - GPtrArray *message_uids, - GCancellable *cancellable, - GError **error) -{ - GHashTable *hash_table; - CamelMimeMessage *message; - guint ii; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - g_return_val_if_fail (message_uids != NULL, NULL); - - camel_operation_push_message ( - cancellable, - ngettext ( - "Retrieving %d message", - "Retrieving %d messages", - message_uids->len), - message_uids->len); - - hash_table = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); - - /* This is an all or nothing operation. Destroy the - * hash table if we fail to retrieve any message. */ - - for (ii = 0; ii < message_uids->len; ii++) { - const gchar *uid; - gint percent; - - uid = g_ptr_array_index (message_uids, ii); - percent = ((ii + 1) * 100) / message_uids->len; - - message = camel_folder_get_message_sync ( - folder, uid, cancellable, error); - - camel_operation_progress (cancellable, percent); - - if (CAMEL_IS_MIME_MESSAGE (message)) { - g_hash_table_insert ( - hash_table, g_strdup (uid), message); - } else { - g_hash_table_destroy (hash_table); - hash_table = NULL; - break; - } - } - - camel_operation_pop_message (cancellable); - - return hash_table; -} - -void -e_mail_folder_get_multiple_messages (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (message_uids != NULL); - - context = g_slice_new0 (AsyncContext); - context->ptr_array = g_ptr_array_ref (message_uids); - - simple = g_simple_async_result_new ( - G_OBJECT (folder), callback, user_data, - e_mail_folder_get_multiple_messages); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, mail_folder_get_multiple_messages_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -GHashTable * -e_mail_folder_get_multiple_messages_finish (CamelFolder *folder, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (folder), - e_mail_folder_get_multiple_messages), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - return g_hash_table_ref (context->hash_table); -} - -static void -mail_folder_remove_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - GError *error = NULL; - - e_mail_folder_remove_sync ( - CAMEL_FOLDER (object), cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -static gboolean -mail_folder_remove_recursive (CamelStore *store, - CamelFolderInfo *folder_info, - GCancellable *cancellable, - GError **error) -{ - gboolean success = TRUE; - - while (folder_info != NULL) { - CamelFolder *folder; - - if (folder_info->child != NULL) { - success = mail_folder_remove_recursive ( - store, folder_info->child, cancellable, error); - if (!success) - break; - } - - folder = camel_store_get_folder_sync ( - store, folder_info->full_name, 0, cancellable, error); - if (folder == NULL) { - success = FALSE; - break; - } - - if (!CAMEL_IS_VEE_FOLDER (folder)) { - GPtrArray *uids; - guint ii; - - /* Delete every message in this folder, - * then expunge it. */ - - camel_folder_freeze (folder); - - uids = camel_folder_get_uids (folder); - - for (ii = 0; ii < uids->len; ii++) - camel_folder_delete_message ( - folder, uids->pdata[ii]); - - camel_folder_free_uids (folder, uids); - - success = camel_folder_synchronize_sync ( - folder, TRUE, cancellable, error); - - camel_folder_thaw (folder); - } - - g_object_unref (folder); - - if (!success) - break; - - /* If the store supports subscriptions, - * then unsubscribe from this folder. */ - if (CAMEL_IS_SUBSCRIBABLE (store)) { - success = camel_subscribable_unsubscribe_folder_sync ( - CAMEL_SUBSCRIBABLE (store), - folder_info->full_name, - cancellable, error); - if (!success) - break; - } - - success = camel_store_delete_folder_sync ( - store, folder_info->full_name, cancellable, error); - if (!success) - break; - - folder_info = folder_info->next; - } - - return success; -} - -static void -follow_cancel_cb (GCancellable *cancellable, - GCancellable *transparent_cancellable) -{ - g_cancellable_cancel (transparent_cancellable); -} - -gboolean -e_mail_folder_remove_sync (CamelFolder *folder, - GCancellable *cancellable, - GError **error) -{ - CamelFolderInfo *folder_info; - CamelFolderInfo *to_remove; - CamelFolderInfo *next = NULL; - CamelStore *parent_store; - const gchar *full_name; - gboolean success = TRUE; - GCancellable *transparent_cancellable = NULL; - gulong cbid = 0; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - - full_name = camel_folder_get_full_name (folder); - parent_store = camel_folder_get_parent_store (folder); - - folder_info = camel_store_get_folder_info_sync ( - parent_store, full_name, - CAMEL_STORE_FOLDER_INFO_FAST | - CAMEL_STORE_FOLDER_INFO_RECURSIVE | - CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, - cancellable, error); - - if (folder_info == NULL) - return FALSE; - - to_remove = folder_info; - - /* For cases when the top-level folder_info contains siblings, - * such as when full_name contains a wildcard letter, compare - * the folder name against folder_info->full_name to avoid - * removing more folders than requested. */ - if (folder_info->next != NULL) { - while (to_remove != NULL) { - if (g_strcmp0 (to_remove->full_name, full_name) == 0) - break; - to_remove = to_remove->next; - } - - /* XXX Should we set a GError and return FALSE here? */ - if (to_remove == NULL) { - g_warning ( - "%s: Failed to find folder '%s'", - G_STRFUNC, full_name); - camel_store_free_folder_info ( - parent_store, folder_info); - return TRUE; - } - - /* Prevent iterating over siblings. */ - next = to_remove->next; - to_remove->next = NULL; - } - - camel_operation_push_message ( - cancellable, _("Removing folder '%s'"), - camel_folder_get_full_name (folder)); - - if (cancellable) { - transparent_cancellable = g_cancellable_new (); - cbid = g_cancellable_connect (cancellable, G_CALLBACK (follow_cancel_cb), transparent_cancellable, NULL); - } - - success = mail_folder_remove_recursive ( - parent_store, to_remove, transparent_cancellable, error); - - if (transparent_cancellable) { - g_cancellable_disconnect (cancellable, cbid); - g_object_unref (transparent_cancellable); - } - - camel_operation_pop_message (cancellable); - - /* Restore the folder_info tree to its original - * state so we don't leak folder_info nodes. */ - to_remove->next = next; - - camel_store_free_folder_info (parent_store, folder_info); - - return success; -} - -void -e_mail_folder_remove (CamelFolder *folder, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - simple = g_simple_async_result_new ( - G_OBJECT (folder), callback, - user_data, e_mail_folder_remove); - - g_simple_async_result_run_in_thread ( - simple, mail_folder_remove_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_folder_remove_finish (CamelFolder *folder, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (folder), - e_mail_folder_remove), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_folder_remove_attachments_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_mail_folder_remove_attachments_sync ( - CAMEL_FOLDER (object), context->ptr_array, - cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -/* Helper for e_mail_folder_remove_attachments_sync() */ -static gboolean -mail_folder_strip_message (CamelFolder *folder, - CamelMimeMessage *message, - const gchar *message_uid, - GCancellable *cancellable, - GError **error) -{ - CamelDataWrapper *content; - CamelMultipart *multipart; - gboolean modified = FALSE; - gboolean success = TRUE; - guint ii, n_parts; - - content = camel_medium_get_content (CAMEL_MEDIUM (message)); - - if (!CAMEL_IS_MULTIPART (content)) - return TRUE; - - multipart = CAMEL_MULTIPART (content); - n_parts = camel_multipart_get_number (multipart); - - /* Replace MIME parts with "attachment" or "inline" dispositions - * with a small "text/plain" part saying the file was removed. */ - for (ii = 0; ii < n_parts; ii++) { - CamelMimePart *mime_part; - const gchar *disposition; - gboolean is_attachment; - - mime_part = camel_multipart_get_part (multipart, ii); - disposition = camel_mime_part_get_disposition (mime_part); - - is_attachment = - (g_strcmp0 (disposition, "attachment") == 0) || - (g_strcmp0 (disposition, "inline") == 0); - - if (is_attachment) { - const gchar *filename; - const gchar *content_type; - gchar *content; - - disposition = "inline"; - content_type = "text/plain"; - filename = camel_mime_part_get_filename (mime_part); - - if (filename != NULL && *filename != '\0') - content = g_strdup_printf ( - _("File \"%s\" has been removed."), - filename); - else - content = g_strdup ( - _("File has been removed.")); - - camel_mime_part_set_content ( - mime_part, content, - strlen (content), content_type); - camel_mime_part_set_content_type ( - mime_part, content_type); - camel_mime_part_set_disposition ( - mime_part, disposition); - - modified = TRUE; - } - } - - /* Append the modified message with removed attachments to - * the folder and mark the original message for deletion. */ - if (modified) { - CamelMessageInfo *orig_info; - CamelMessageInfo *copy_info; - CamelMessageFlags flags; - - orig_info = - camel_folder_get_message_info (folder, message_uid); - copy_info = - camel_message_info_new_from_header ( - NULL, CAMEL_MIME_PART (message)->headers); - - flags = camel_folder_get_message_flags (folder, message_uid); - camel_message_info_set_flags (copy_info, flags, flags); - - success = camel_folder_append_message_sync ( - folder, message, copy_info, NULL, cancellable, error); - if (success) - camel_message_info_set_flags ( - orig_info, - CAMEL_MESSAGE_DELETED, - CAMEL_MESSAGE_DELETED); - - camel_folder_free_message_info (folder, orig_info); - camel_message_info_free (copy_info); - } - - return success; -} - -gboolean -e_mail_folder_remove_attachments_sync (CamelFolder *folder, - GPtrArray *message_uids, - GCancellable *cancellable, - GError **error) -{ - gboolean success = TRUE; - guint ii; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - g_return_val_if_fail (message_uids != NULL, FALSE); - - camel_folder_freeze (folder); - - camel_operation_push_message (cancellable, _("Removing attachments")); - - for (ii = 0; success && ii < message_uids->len; ii++) { - CamelMimeMessage *message; - const gchar *uid; - gint percent; - - uid = g_ptr_array_index (message_uids, ii); - - message = camel_folder_get_message_sync ( - folder, uid, cancellable, error); - - if (message == NULL) { - success = FALSE; - break; - } - - success = mail_folder_strip_message ( - folder, message, uid, cancellable, error); - - percent = ((ii + 1) * 100) / message_uids->len; - camel_operation_progress (cancellable, percent); - - g_object_unref (message); - } - - camel_operation_pop_message (cancellable); - - if (success) - camel_folder_synchronize_sync ( - folder, FALSE, cancellable, error); - - camel_folder_thaw (folder); - - return success; -} - -void -e_mail_folder_remove_attachments (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (message_uids != NULL); - - context = g_slice_new0 (AsyncContext); - context->ptr_array = g_ptr_array_ref (message_uids); - - simple = g_simple_async_result_new ( - G_OBJECT (folder), callback, user_data, - e_mail_folder_remove_attachments); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, mail_folder_remove_attachments_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_folder_remove_attachments_finish (CamelFolder *folder, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (folder), - e_mail_folder_remove_attachments), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_folder_save_messages_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_mail_folder_save_messages_sync ( - CAMEL_FOLDER (object), context->ptr_array, - context->destination, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -/* Helper for e_mail_folder_save_messages_sync() */ -static void -mail_folder_save_prepare_part (CamelMimePart *mime_part) -{ - CamelDataWrapper *content; - - content = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); - - if (content == NULL) - return; - - if (CAMEL_IS_MULTIPART (content)) { - guint n_parts, ii; - - n_parts = camel_multipart_get_number ( - CAMEL_MULTIPART (content)); - for (ii = 0; ii < n_parts; ii++) { - mime_part = camel_multipart_get_part ( - CAMEL_MULTIPART (content), ii); - mail_folder_save_prepare_part (mime_part); - } - - } else if (CAMEL_IS_MIME_MESSAGE (content)) { - mail_folder_save_prepare_part (CAMEL_MIME_PART (content)); - - } else { - CamelContentType *type; - - /* Save textual parts as 8-bit, not encoded. */ - type = camel_data_wrapper_get_mime_type_field (content); - if (camel_content_type_is (type, "text", "*")) - camel_mime_part_set_encoding ( - mime_part, CAMEL_TRANSFER_ENCODING_8BIT); - } -} - -gboolean -e_mail_folder_save_messages_sync (CamelFolder *folder, - GPtrArray *message_uids, - GFile *destination, - GCancellable *cancellable, - GError **error) -{ - GFileOutputStream *file_output_stream; - GByteArray *byte_array; - CamelStream *base_stream; - gboolean success = TRUE; - guint ii; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - g_return_val_if_fail (message_uids != NULL, FALSE); - g_return_val_if_fail (G_IS_FILE (destination), FALSE); - - /* Need at least one message UID to save. */ - g_return_val_if_fail (message_uids->len > 0, FALSE); - - camel_operation_push_message ( - cancellable, ngettext ( - "Saving %d message", - "Saving %d messages", - message_uids->len), - message_uids->len); - - file_output_stream = g_file_replace ( - destination, NULL, FALSE, - G_FILE_CREATE_PRIVATE | - G_FILE_CREATE_REPLACE_DESTINATION, - cancellable, error); - - if (file_output_stream == NULL) { - camel_operation_pop_message (cancellable); - return FALSE; - } - - /* CamelStreamMem takes ownership of the GByteArray. */ - byte_array = g_byte_array_new (); - base_stream = camel_stream_mem_new_with_byte_array (byte_array); - - for (ii = 0; ii < message_uids->len; ii++) { - CamelMimeMessage *message; - CamelMimeFilter *filter; - CamelStream *stream; - const gchar *uid; - gchar *from_line; - gint percent; - gint retval; - - uid = g_ptr_array_index (message_uids, ii); - - message = camel_folder_get_message_sync ( - folder, uid, cancellable, error); - if (message == NULL) { - success = FALSE; - goto exit; - } - - mail_folder_save_prepare_part (CAMEL_MIME_PART (message)); - - from_line = camel_mime_message_build_mbox_from (message); - g_return_val_if_fail (from_line != NULL, FALSE); - - success = g_output_stream_write_all ( - G_OUTPUT_STREAM (file_output_stream), - from_line, strlen (from_line), NULL, - cancellable, error); - - g_free (from_line); - - if (!success) { - g_object_unref (message); - goto exit; - } - - filter = camel_mime_filter_from_new (); - stream = camel_stream_filter_new (base_stream); - camel_stream_filter_add (CAMEL_STREAM_FILTER (stream), filter); - - retval = camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (message), - stream, cancellable, error); - - g_object_unref (filter); - g_object_unref (stream); - - if (retval == -1) { - g_object_unref (message); - goto exit; - } - - g_byte_array_append (byte_array, (guint8 *) "\n", 1); - - success = g_output_stream_write_all ( - G_OUTPUT_STREAM (file_output_stream), - byte_array->data, byte_array->len, - NULL, cancellable, error); - - if (!success) { - g_object_unref (message); - goto exit; - } - - percent = ((ii + 1) * 100) / message_uids->len; - camel_operation_progress (cancellable, percent); - - /* Flush the buffer for the next message. - * For memory streams this never fails. */ - g_seekable_seek ( - G_SEEKABLE (base_stream), - 0, G_SEEK_SET, NULL, NULL); - - g_object_unref (message); - } - -exit: - g_object_unref (file_output_stream); - g_object_unref (base_stream); - - camel_operation_pop_message (cancellable); - - if (!success) { - /* Try deleting the destination file. */ - g_file_delete (destination, NULL, NULL); - } - - return success; -} - -void -e_mail_folder_save_messages (CamelFolder *folder, - GPtrArray *message_uids, - GFile *destination, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (message_uids != NULL); - g_return_if_fail (G_IS_FILE (destination)); - - /* Need at least one message UID to save. */ - g_return_if_fail (message_uids->len > 0); - - context = g_slice_new0 (AsyncContext); - context->ptr_array = g_ptr_array_ref (message_uids); - context->destination = g_object_ref (destination); - - simple = g_simple_async_result_new ( - G_OBJECT (folder), callback, user_data, - e_mail_folder_save_messages); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, mail_folder_save_messages_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_folder_save_messages_finish (CamelFolder *folder, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (folder), - e_mail_folder_save_messages), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -/** - * e_mail_folder_uri_build: - * @store: a #CamelStore - * @folder_name: a folder name - * - * Builds a folder URI string from @store and @folder_name. - * - * Returns: a newly-allocated folder URI string - **/ -gchar * -e_mail_folder_uri_build (CamelStore *store, - const gchar *folder_name) -{ - const gchar *uid; - gchar *encoded_name; - gchar *encoded_uid; - gchar *uri; - - g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); - g_return_val_if_fail (folder_name != NULL, NULL); - - /* Skip the leading slash, if present. */ - if (*folder_name == '/') - folder_name++; - - uid = camel_service_get_uid (CAMEL_SERVICE (store)); - - encoded_uid = camel_url_encode (uid, ":;@/"); - encoded_name = camel_url_encode (folder_name, "#"); - - uri = g_strdup_printf ("folder://%s/%s", encoded_uid, encoded_name); - - g_free (encoded_uid); - g_free (encoded_name); - - return uri; -} - -/** - * e_mail_folder_uri_parse: - * @session: a #CamelSession - * @folder_uri: a folder URI - * @out_store: return location for a #CamelStore, or %NULL - * @out_folder_name: return location for a folder name, or %NULL - * @error: return location for a #GError, or %NULL - * - * Parses a folder URI generated by e_mail_folder_uri_build() and - * returns the corresponding #CamelStore instance in @out_store and - * folder name string in @out_folder_name. If the URI is malformed - * or no corresponding store exists, the function sets @error and - * returns %FALSE. - * - * If the function is able to parse the URI, the #CamelStore instance - * set in @out_store should be unreferenced with g_object_unref() when - * done with it, and the folder name string set in @out_folder_name - * should be freed with g_free(). - * - * The function also handles older style URIs, such as ones where the - * #CamelStore's #CamelStore::uri string was embedded directly in the - * folder URI, and account-based URIs that used an "email://" prefix. - * - * Returns: %TRUE if @folder_uri could be parsed, %FALSE otherwise - **/ -gboolean -e_mail_folder_uri_parse (CamelSession *session, - const gchar *folder_uri, - CamelStore **out_store, - gchar **out_folder_name, - GError **error) -{ - CamelURL *url; - CamelService *service = NULL; - gchar *folder_name = NULL; - gboolean success = FALSE; - - g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); - g_return_val_if_fail (folder_uri != NULL, FALSE); - - url = camel_url_new (folder_uri, error); - if (url == NULL) - return FALSE; - - /* Current URI Format: 'folder://' STORE_UID '/' FOLDER_PATH */ - if (g_strcmp0 (url->protocol, "folder") == 0) { - - if (url->host != NULL) { - gchar *uid; - - if (url->user == NULL || *url->user == '\0') - uid = g_strdup (url->host); - else - uid = g_strconcat ( - url->user, "@", url->host, NULL); - - service = camel_session_get_service (session, uid); - g_free (uid); - } - - if (url->path != NULL && *url->path == '/') - folder_name = camel_url_decode_path (url->path + 1); - - /* This style was used to reference accounts by UID before - * CamelServices themselves had UIDs. Some examples are: - * - * Special cases: - * - * 'email://local@local/' FOLDER_PATH - * 'email://vfolder@local/' FOLDER_PATH - * - * General case: - * - * 'email://' ACCOUNT_UID '/' FOLDER_PATH - * - * Note: ACCOUNT_UID is now equivalent to STORE_UID, and - * the STORE_UIDs for the special cases are 'local' - * and 'vfolder'. - */ - } else if (g_strcmp0 (url->protocol, "email") == 0) { - gchar *uid = NULL; - - /* Handle the special cases. */ - if (g_strcmp0 (url->host, "local") == 0) { - if (g_strcmp0 (url->user, "local") == 0) - uid = g_strdup ("local"); - if (g_strcmp0 (url->user, "vfolder") == 0) - uid = g_strdup ("vfolder"); - } - - /* Handle the general case. */ - if (uid == NULL && url->host != NULL) { - if (url->user == NULL) - uid = g_strdup (url->host); - else - uid = g_strdup_printf ( - "%s@%s", url->user, url->host); - } - - if (uid != NULL) { - service = camel_session_get_service (session, uid); - g_free (uid); - } - - if (url->path != NULL && *url->path == '/') - folder_name = camel_url_decode_path (url->path + 1); - - /* CamelFolderInfo URIs used to embed the store's URI, so the - * folder name is appended as either a path part or a fragment - * part, depending whether the store's URI used the path part. - * To determine which it is, you have to check the provider - * flags for CAMEL_URL_FRAGMENT_IS_PATH. */ - } else { - service = camel_session_get_service_by_url ( - session, url, CAMEL_PROVIDER_STORE); - - if (CAMEL_IS_STORE (service)) { - CamelProvider *provider; - - provider = camel_service_get_provider (service); - - if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) - folder_name = g_strdup (url->fragment); - else if (url->path != NULL && *url->path == '/') - folder_name = g_strdup (url->path + 1); - } - } - - if (CAMEL_IS_STORE (service) && folder_name != NULL) { - if (out_store != NULL) - *out_store = g_object_ref (service); - - if (out_folder_name != NULL) { - *out_folder_name = folder_name; - folder_name = NULL; - } - - success = TRUE; - } else { - g_set_error ( - error, CAMEL_FOLDER_ERROR, - CAMEL_FOLDER_ERROR_INVALID, - _("Invalid folder URI '%s'"), - folder_uri); - } - - g_free (folder_name); - - camel_url_free (url); - - return success; -} - -/** - * e_mail_folder_uri_equal: - * @session: a #CamelSession - * @folder_uri_a: a folder URI - * @folder_uri_b: another folder URI - * - * Compares two folder URIs for equality. If either URI is invalid, - * the function returns %FALSE. - * - * Returns: %TRUE if the URIs are equal, %FALSE if not - **/ -gboolean -e_mail_folder_uri_equal (CamelSession *session, - const gchar *folder_uri_a, - const gchar *folder_uri_b) -{ - CamelStore *store_a; - CamelStore *store_b; - CamelStoreClass *class; - gchar *folder_name_a; - gchar *folder_name_b; - gboolean success_a; - gboolean success_b; - gboolean equal = FALSE; - - g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); - g_return_val_if_fail (folder_uri_a != NULL, FALSE); - g_return_val_if_fail (folder_uri_b != NULL, FALSE); - - success_a = e_mail_folder_uri_parse ( - session, folder_uri_a, &store_a, &folder_name_a, NULL); - - success_b = e_mail_folder_uri_parse ( - session, folder_uri_b, &store_b, &folder_name_b, NULL); - - if (!success_a || !success_b) - goto exit; - - if (store_a != store_b) - goto exit; - - /* Doesn't matter which store we use since they're the same. */ - class = CAMEL_STORE_GET_CLASS (store_a); - g_return_val_if_fail (class->compare_folder_name != NULL, FALSE); - - equal = class->compare_folder_name (folder_name_a, folder_name_b); - -exit: - if (success_a) { - g_object_unref (store_a); - g_free (folder_name_a); - } - - if (success_b) { - g_object_unref (store_b); - g_free (folder_name_b); - } - - return equal; -} - -/** - * e_mail_folder_uri_from_folder: - * @folder: a #CamelFolder - * - * Convenience function for building a folder URI from a #CamelFolder. - * Free the returned URI string with g_free(). - * - * Returns: a newly-allocated folder URI string - **/ -gchar * -e_mail_folder_uri_from_folder (CamelFolder *folder) -{ - CamelStore *store; - const gchar *folder_name; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - - store = camel_folder_get_parent_store (folder); - folder_name = camel_folder_get_full_name (folder); - - return e_mail_folder_uri_build (store, folder_name); -} - -/** - * e_mail_folder_uri_to_markup: - * @session: a #CamelSession - * @folder_uri: a folder URI - * @error: return location for a #GError, or %NULL - * - * Converts @folder_uri to a markup string suitable for displaying to users. - * The string consists of the #CamelStore display name (in bold), followed - * by the folder path. If the URI is malformed or no corresponding store - * exists, the function sets @error and returns %NULL. Free the returned - * string with g_free(). - * - * Returns: a newly-allocated markup string, or %NULL - **/ -gchar * -e_mail_folder_uri_to_markup (CamelSession *session, - const gchar *folder_uri, - GError **error) -{ - CamelStore *store = NULL; - const gchar *display_name; - gchar *folder_name = NULL; - gchar *markup; - gboolean success; - - g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); - g_return_val_if_fail (folder_uri != NULL, NULL); - - success = e_mail_folder_uri_parse ( - session, folder_uri, &store, &folder_name, error); - - if (!success) - return NULL; - - g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); - g_return_val_if_fail (folder_name != NULL, NULL); - - display_name = camel_service_get_display_name (CAMEL_SERVICE (store)); - - markup = g_markup_printf_escaped ( - "<b>%s</b> : %s", display_name, folder_name); - - g_object_unref (store); - g_free (folder_name); - - return markup; -} diff --git a/mail/e-mail-folder-utils.h b/mail/e-mail-folder-utils.h deleted file mode 100644 index 9e8dd0f050..0000000000 --- a/mail/e-mail-folder-utils.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * e-mail-folder-utils.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_FOLDER_UTILS_H -#define E_MAIL_FOLDER_UTILS_H - -/* CamelFolder wrappers with Evolution-specific policies. */ - -#include <camel/camel.h> - -G_BEGIN_DECLS - -gboolean e_mail_folder_append_message_sync - (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info, - gchar **appended_uid, - GCancellable *cancellable, - GError **error); -void e_mail_folder_append_message (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_folder_append_message_finish - (CamelFolder *folder, - GAsyncResult *result, - gchar **appended_uid, - GError **error); - -CamelMimePart * e_mail_folder_build_attachment_sync - (CamelFolder *folder, - GPtrArray *message_uids, - gchar **fwd_subject, - GCancellable *cancellable, - GError **error); -void e_mail_folder_build_attachment (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -CamelMimePart * e_mail_folder_build_attachment_finish - (CamelFolder *folder, - GAsyncResult *result, - gchar **fwd_subject, - GError **error); - -GHashTable * e_mail_folder_find_duplicate_messages_sync - (CamelFolder *folder, - GPtrArray *message_uids, - GCancellable *cancellable, - GError **error); -void e_mail_folder_find_duplicate_messages - (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -GHashTable * e_mail_folder_find_duplicate_messages_finish - (CamelFolder *folder, - GAsyncResult *result, - GError **error); - -GHashTable * e_mail_folder_get_multiple_messages_sync - (CamelFolder *folder, - GPtrArray *message_uids, - GCancellable *cancellable, - GError **error); -void e_mail_folder_get_multiple_messages - (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -GHashTable * e_mail_folder_get_multiple_messages_finish - (CamelFolder *folder, - GAsyncResult *result, - GError **error); - -gboolean e_mail_folder_remove_sync (CamelFolder *folder, - GCancellable *cancellable, - GError **error); -void e_mail_folder_remove (CamelFolder *folder, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_folder_remove_finish (CamelFolder *folder, - GAsyncResult *result, - GError **error); - -gboolean e_mail_folder_remove_attachments_sync - (CamelFolder *folder, - GPtrArray *message_uids, - GCancellable *cancellable, - GError **error); -void e_mail_folder_remove_attachments - (CamelFolder *folder, - GPtrArray *message_uids, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_folder_remove_attachments_finish - (CamelFolder *folder, - GAsyncResult *result, - GError **error); - -gboolean e_mail_folder_save_messages_sync - (CamelFolder *folder, - GPtrArray *message_uids, - GFile *destination, - GCancellable *cancellable, - GError **error); -void e_mail_folder_save_messages (CamelFolder *folder, - GPtrArray *message_uids, - GFile *destination, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_folder_save_messages_finish - (CamelFolder *folder, - GAsyncResult *result, - GError **error); - -gchar * e_mail_folder_uri_build (CamelStore *store, - const gchar *folder_name); -gboolean e_mail_folder_uri_parse (CamelSession *session, - const gchar *folder_uri, - CamelStore **out_store, - gchar **out_folder_name, - GError **error); -gboolean e_mail_folder_uri_equal (CamelSession *session, - const gchar *folder_uri_a, - const gchar *folder_uri_b); -gchar * e_mail_folder_uri_from_folder (CamelFolder *folder); -gchar * e_mail_folder_uri_to_markup (CamelSession *session, - const gchar *folder_uri, - GError **error); - -G_END_DECLS - -#endif /* E_MAIL_FOLDER_UTILS_H */ diff --git a/mail/e-mail-junk-filter.c b/mail/e-mail-junk-filter.c deleted file mode 100644 index 71128013ad..0000000000 --- a/mail/e-mail-junk-filter.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * e-mail-junk-filter.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#include "e-mail-junk-filter.h" - -#include <mail/e-mail-session.h> - -G_DEFINE_ABSTRACT_TYPE ( - EMailJunkFilter, - e_mail_junk_filter, - E_TYPE_EXTENSION) - -static void -e_mail_junk_filter_class_init (EMailJunkFilterClass *class) -{ - EExtensionClass *extension_class; - - extension_class = E_EXTENSION_CLASS (class); - extension_class->extensible_type = E_TYPE_MAIL_SESSION; -} - -static void -e_mail_junk_filter_init (EMailJunkFilter *junk_filter) -{ -} - -gboolean -e_mail_junk_filter_available (EMailJunkFilter *junk_filter) -{ - EMailJunkFilterClass *class; - - g_return_val_if_fail (E_IS_MAIL_JUNK_FILTER (junk_filter), FALSE); - - class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter); - g_return_val_if_fail (class->available != NULL, FALSE); - - return class->available (junk_filter); -} - -GtkWidget * -e_mail_junk_filter_new_config_widget (EMailJunkFilter *junk_filter) -{ - EMailJunkFilterClass *class; - GtkWidget *widget = NULL; - - g_return_val_if_fail (E_IS_MAIL_JUNK_FILTER (junk_filter), NULL); - - class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter); - - if (class->new_config_widget != NULL) - widget = class->new_config_widget (junk_filter); - - return widget; -} - -gint -e_mail_junk_filter_compare (EMailJunkFilter *junk_filter_a, - EMailJunkFilter *junk_filter_b) -{ - EMailJunkFilterClass *class_a; - EMailJunkFilterClass *class_b; - - class_a = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter_a); - class_b = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter_b); - - return g_utf8_collate (class_a->display_name, class_b->display_name); -} diff --git a/mail/e-mail-junk-filter.h b/mail/e-mail-junk-filter.h deleted file mode 100644 index 74a7840c2d..0000000000 --- a/mail/e-mail-junk-filter.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * e-mail-junk-filter.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_JUNK_FILTER_H -#define E_MAIL_JUNK_FILTER_H - -#include <gtk/gtk.h> -#include <libebackend/e-extension.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_JUNK_FILTER \ - (e_mail_junk_filter_get_type ()) -#define E_MAIL_JUNK_FILTER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_JUNK_FILTER, EMailJunkFilter)) -#define E_MAIL_JUNK_FILTER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_JUNK_FILTER, EMailJunkFilterClass)) -#define E_IS_MAIL_JUNK_FILTER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_JUNK_FILTER)) -#define E_IS_MAIL_JUNK_FILTER_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_JUNK_FILTER)) -#define E_MAIL_JUNK_FILTER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_JUNK_FILTER, EMailJunkFilterClass)) - -G_BEGIN_DECLS - -typedef struct _EMailJunkFilter EMailJunkFilter; -typedef struct _EMailJunkFilterClass EMailJunkFilterClass; -typedef struct _EMailJunkFilterPrivate EMailJunkFilterPrivate; - -struct _EMailJunkFilter { - EExtension parent; - EMailJunkFilterPrivate *priv; -}; - -struct _EMailJunkFilterClass { - EExtensionClass parent_class; - - const gchar *filter_name; - const gchar *display_name; - - gboolean (*available) (EMailJunkFilter *junk_filter); - GtkWidget * (*new_config_widget) (EMailJunkFilter *junk_filter); -}; - -GType e_mail_junk_filter_get_type (void) G_GNUC_CONST; -gboolean e_mail_junk_filter_available (EMailJunkFilter *junk_filter); -GtkWidget * e_mail_junk_filter_new_config_widget - (EMailJunkFilter *junk_filter); -gint e_mail_junk_filter_compare (EMailJunkFilter *junk_filter_a, - EMailJunkFilter *junk_filter_b); - -G_END_DECLS - -#endif /* E_MAIL_JUNK_FILTER_H */ diff --git a/mail/e-mail-junk-options.c b/mail/e-mail-junk-options.c index d57e1d6dc6..e2c670c688 100644 --- a/mail/e-mail-junk-options.c +++ b/mail/e-mail-junk-options.c @@ -21,7 +21,7 @@ #include <config.h> #include <glib/gi18n-lib.h> -#include <mail/e-mail-junk-filter.h> +#include <libemail-engine/e-mail-junk-filter.h> #define E_MAIL_JUNK_OPTIONS_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ diff --git a/mail/e-mail-junk-options.h b/mail/e-mail-junk-options.h index 5e2c99faf7..7e9108e7b7 100644 --- a/mail/e-mail-junk-options.h +++ b/mail/e-mail-junk-options.h @@ -20,7 +20,7 @@ #define E_MAIL_JUNK_OPTIONS_H #include <gtk/gtk.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define E_TYPE_MAIL_JUNK_OPTIONS \ diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c index fdf5684e0a..3b7de4c387 100644 --- a/mail/e-mail-migrate.c +++ b/mail/e-mail-migrate.c @@ -48,22 +48,25 @@ #include <libxml/parser.h> #include <libxml/xmlmemory.h> -#include <e-util/e-util.h> #include <libedataserver/e-xml-utils.h> #include <libedataserver/e-data-server-util.h> + +#include <shell/e-shell.h> +#include <shell/e-shell-migrate.h> + +#include <e-util/e-util.h> #include <e-util/e-xml-utils.h> -#include "e-util/e-account-utils.h" -#include "e-util/e-alert-dialog.h" -#include "e-util/e-util-private.h" -#include "e-util/e-plugin.h" -#include "e-util/e-signature-utils.h" +#include <e-util/e-alert-dialog.h> +#include <e-util/e-util-private.h> +#include <e-util/e-plugin.h> + +#include <libemail-utils/e-account-utils.h> +#include <libemail-utils/e-signature-utils.h> -#include "shell/e-shell.h" -#include "shell/e-shell-migrate.h" +#include <libemail-engine/e-mail-folder-utils.h> #include "e-mail-backend.h" -#include "e-mail-folder-utils.h" #include "em-utils.h" #define d(x) x diff --git a/mail/e-mail-notebook-view.c b/mail/e-mail-notebook-view.c index 0232b92423..5d100cfc21 100644 --- a/mail/e-mail-notebook-view.c +++ b/mail/e-mail-notebook-view.c @@ -31,7 +31,7 @@ #include "mail/em-folder-tree.h" #include "e-mail-notebook-view.h" #include "e-mail-folder-pane.h" -#include "e-mail-folder-utils.h" +#include "libemail-engine/e-mail-folder-utils.h" #include "e-mail-message-pane.h" #include <shell/e-shell-window-actions.h> diff --git a/mail/e-mail-paned-view.c b/mail/e-mail-paned-view.c index 0098462de1..7a510e3ebd 100644 --- a/mail/e-mail-paned-view.c +++ b/mail/e-mail-paned-view.c @@ -38,11 +38,13 @@ #include <shell/e-shell-window-actions.h> +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/e-mail-utils.h> +#include <libemail-engine/mail-config.h> +#include <libemail-engine/mail-ops.h> + #include "em-utils.h" -#include "mail-config.h" -#include "mail-ops.h" #include "message-list.h" -#include "e-mail-folder-utils.h" #include "e-mail-reader-utils.h" #define E_MAIL_PANED_VIEW_GET_PRIVATE(obj) \ diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c index bd51c97e1f..c814435119 100644 --- a/mail/e-mail-reader-utils.c +++ b/mail/e-mail-reader-utils.c @@ -37,15 +37,17 @@ #include "misc/e-web-view.h" #include "shell/e-shell-utils.h" +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/e-mail-utils.h> +#include <libemail-engine/mail-ops.h> +#include <libemail-engine/mail-tools.h> + #include "mail/e-mail-backend.h" #include "mail/e-mail-browser.h" -#include "mail/e-mail-folder-utils.h" #include "mail/em-composer-utils.h" #include "mail/em-format-html-print.h" #include "mail/em-utils.h" #include "mail/mail-autofilter.h" -#include "mail/mail-ops.h" -#include "mail/mail-tools.h" #include "mail/mail-vfolder.h" #include "mail/message-list.h" diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c index 5c67c62d02..37c92fbf78 100644 --- a/mail/e-mail-reader.c +++ b/mail/e-mail-reader.c @@ -32,7 +32,6 @@ #include <X11/XF86keysym.h> #endif -#include "e-util/e-account-utils.h" #include "e-util/e-charset.h" #include "e-util/e-util.h" #include "e-util/e-alert-dialog.h" @@ -40,10 +39,16 @@ #include "widgets/misc/e-popup-action.h" #include "widgets/misc/e-menu-tool-action.h" +#include "libemail-utils/e-account-utils.h" +#include "libemail-utils/mail-mt.h" + +#include "libemail-engine/mail-ops.h" +#include "libemail-engine/e-mail-utils.h" +#include "libemail-engine/e-mail-enumtypes.h" + #include "mail/e-mail-backend.h" #include "mail/e-mail-browser.h" #include "mail/e-mail-display.h" -#include "mail/e-mail-enumtypes.h" #include "mail/e-mail-reader-utils.h" #include "mail/e-mail-view.h" #include "mail/em-composer-utils.h" @@ -52,8 +57,6 @@ #include "mail/em-folder-tree.h" #include "mail/em-utils.h" #include "mail/mail-autofilter.h" -#include "mail/mail-ops.h" -#include "mail/mail-mt.h" #include "mail/mail-vfolder.h" #include "mail/message-list.h" diff --git a/mail/e-mail-session-utils.c b/mail/e-mail-session-utils.c deleted file mode 100644 index f1c27a3425..0000000000 --- a/mail/e-mail-session-utils.c +++ /dev/null @@ -1,930 +0,0 @@ -/* - * e-mail-session-utils.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-mail-session-utils.h" - -#include "em-utils.h" - -#include <glib/gi18n-lib.h> - -#include <mail/mail-tools.h> -#include <mail/e-mail-folder-utils.h> -#include <e-util/e-account-utils.h> -#include <filter/e-filter-rule.h> - -/* X-Mailer header value */ -#define X_MAILER ("Evolution " VERSION SUB_VERSION " " VERSION_COMMENT) - -typedef struct _AsyncContext AsyncContext; - -struct _AsyncContext { - CamelFolder *sent_folder; - - CamelMimeMessage *message; - CamelMessageInfo *info; - - CamelAddress *from; - CamelAddress *recipients; - - CamelFilterDriver *driver; - - GCancellable *cancellable; - gint io_priority; - - /* X-Evolution headers */ - struct _camel_header_raw *xev; - - GPtrArray *post_to_uris; - - gchar *folder_uri; - gchar *message_uid; - gchar *transport_uid; - gchar *sent_folder_uri; -}; - -static void -async_context_free (AsyncContext *context) -{ - if (context->sent_folder != NULL) - g_object_unref (context->sent_folder); - - if (context->message != NULL) - g_object_unref (context->message); - - if (context->info != NULL) - camel_message_info_free (context->info); - - if (context->from != NULL) - g_object_unref (context->from); - - if (context->recipients != NULL) - g_object_unref (context->recipients); - - if (context->driver != NULL) - g_object_unref (context->driver); - - if (context->cancellable != NULL) { - camel_operation_pop_message (context->cancellable); - g_object_unref (context->cancellable); - } - - if (context->xev != NULL) - camel_header_raw_clear (&context->xev); - - if (context->post_to_uris != NULL) { - g_ptr_array_foreach ( - context->post_to_uris, (GFunc) g_free, NULL); - g_ptr_array_free (context->post_to_uris, TRUE); - } - - g_free (context->folder_uri); - g_free (context->message_uid); - g_free (context->transport_uid); - g_free (context->sent_folder_uri); - - g_slice_free (AsyncContext, context); -} - -GQuark -e_mail_error_quark (void) -{ - static GQuark quark = 0; - - if (G_UNLIKELY (quark == 0)) { - const gchar *string = "e-mail-error-quark"; - quark = g_quark_from_static_string (string); - } - - return quark; -} - -static void -mail_session_handle_draft_headers_thread (GSimpleAsyncResult *simple, - EMailSession *session, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_mail_session_handle_draft_headers_sync ( - session, context->message, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -gboolean -e_mail_session_handle_draft_headers_sync (EMailSession *session, - CamelMimeMessage *message, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *folder; - CamelMedium *medium; - const gchar *folder_uri; - const gchar *message_uid; - const gchar *header_name; - gboolean success; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE); - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE); - - medium = CAMEL_MEDIUM (message); - - header_name = "X-Evolution-Draft-Folder"; - folder_uri = camel_medium_get_header (medium, header_name); - - header_name = "X-Evolution-Draft-Message"; - message_uid = camel_medium_get_header (medium, header_name); - - /* Don't report errors about missing X-Evolution-Draft - * headers. These headers are optional, so their absence - * is handled by doing nothing. */ - if (folder_uri == NULL || message_uid == NULL) - return TRUE; - - folder = e_mail_session_uri_to_folder_sync ( - session, folder_uri, 0, cancellable, error); - - if (folder == NULL) - return FALSE; - - camel_folder_set_message_flags ( - folder, message_uid, - CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, - CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN); - - success = camel_folder_synchronize_message_sync ( - folder, message_uid, cancellable, error); - - g_object_unref (folder); - - return success; -} - -void -e_mail_session_handle_draft_headers (EMailSession *session, - CamelMimeMessage *message, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - - context = g_slice_new0 (AsyncContext); - context->message = g_object_ref (message); - - simple = g_simple_async_result_new ( - G_OBJECT (session), callback, user_data, - e_mail_session_handle_draft_headers); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_session_handle_draft_headers_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_session_handle_draft_headers_finish (EMailSession *session, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (session), - e_mail_session_handle_draft_headers), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_session_handle_source_headers_thread (GSimpleAsyncResult *simple, - EMailSession *session, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_mail_session_handle_source_headers_sync ( - session, context->message, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -gboolean -e_mail_session_handle_source_headers_sync (EMailSession *session, - CamelMimeMessage *message, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *folder; - CamelMedium *medium; - CamelMessageFlags flags = 0; - const gchar *folder_uri; - const gchar *message_uid; - const gchar *flag_string; - const gchar *header_name; - gboolean success; - guint length, ii; - gchar **tokens; - gchar *string; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE); - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE); - - medium = CAMEL_MEDIUM (message); - - header_name = "X-Evolution-Source-Folder"; - folder_uri = camel_medium_get_header (medium, header_name); - - header_name = "X-Evolution-Source-Message"; - message_uid = camel_medium_get_header (medium, header_name); - - header_name = "X-Evolution-Source-Flags"; - flag_string = camel_medium_get_header (medium, header_name); - - /* Don't report errors about missing X-Evolution-Source - * headers. These headers are optional, so their absence - * is handled by doing nothing. */ - if (folder_uri == NULL || message_uid == NULL || flag_string == NULL) - return TRUE; - - /* Convert the flag string to CamelMessageFlags. */ - - string = g_strstrip (g_strdup (flag_string)); - tokens = g_strsplit (string, " ", 0); - g_free (string); - - /* If tokens is NULL, a length of 0 will skip the loop. */ - length = (tokens != NULL) ? g_strv_length (tokens) : 0; - - for (ii = 0; ii < length; ii++) { - /* Note: We're only checking for flags known to - * be used in X-Evolution-Source-Flags headers. - * Add more as needed. */ - if (g_strcmp0 (tokens[ii], "ANSWERED") == 0) - flags |= CAMEL_MESSAGE_ANSWERED; - else if (g_strcmp0 (tokens[ii], "ANSWERED_ALL") == 0) - flags |= CAMEL_MESSAGE_ANSWERED_ALL; - else if (g_strcmp0 (tokens[ii], "FORWARDED") == 0) - flags |= CAMEL_MESSAGE_FORWARDED; - else if (g_strcmp0 (tokens[ii], "SEEN") == 0) - flags |= CAMEL_MESSAGE_SEEN; - else - g_warning ( - "Unknown flag '%s' in %s", - tokens[ii], header_name); - } - - g_strfreev (tokens); - - folder = e_mail_session_uri_to_folder_sync ( - session, folder_uri, 0, cancellable, error); - - if (folder == NULL) - return FALSE; - - camel_folder_set_message_flags ( - folder, message_uid, flags, flags); - - success = camel_folder_synchronize_message_sync ( - folder, message_uid, cancellable, error); - - g_object_unref (folder); - - return success; -} - -void -e_mail_session_handle_source_headers (EMailSession *session, - CamelMimeMessage *message, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - - context = g_slice_new0 (AsyncContext); - context->message = g_object_ref (message); - - simple = g_simple_async_result_new ( - G_OBJECT (session), callback, user_data, - e_mail_session_handle_source_headers); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_session_handle_source_headers_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_session_handle_source_headers_finish (EMailSession *session, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (session), - e_mail_session_handle_draft_headers), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_session_send_to_thread (GSimpleAsyncResult *simple, - EMailSession *session, - GCancellable *cancellable) -{ - AsyncContext *context; - CamelFolder *local_sent_folder; - GString *error_messages; - gboolean copy_to_sent = TRUE; - guint ii; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - /* Send the message to all recipients. */ - if (camel_address_length (context->recipients) > 0) { - CamelProvider *provider; - CamelService *service; - gboolean did_connect = FALSE; - - service = camel_session_get_service ( - CAMEL_SESSION (session), context->transport_uid); - - if (!CAMEL_IS_TRANSPORT (service)) { - g_simple_async_result_set_error (simple, - CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_URL_INVALID, - _("Cannot get transport for account '%s'"), - context->transport_uid); - return; - } - - if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED) { - did_connect = TRUE; - - /* XXX This API does not allow for cancellation. */ - if (!em_utils_connect_service_sync (service, cancellable, &error)) { - g_simple_async_result_take_error (simple, error); - return; - } - } - - provider = camel_service_get_provider (service); - - if (provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER) - copy_to_sent = FALSE; - - camel_transport_send_to_sync ( - CAMEL_TRANSPORT (service), - context->message, context->from, - context->recipients, cancellable, &error); - - if (did_connect) - em_utils_disconnect_service_sync ( - service, error == NULL, - cancellable, error ? NULL : &error); - - if (error != NULL) { - g_simple_async_result_take_error (simple, error); - return; - } - } - - /* Post the message to requested folders. */ - for (ii = 0; ii < context->post_to_uris->len; ii++) { - CamelFolder *folder; - const gchar *folder_uri; - - folder_uri = g_ptr_array_index (context->post_to_uris, ii); - - folder = e_mail_session_uri_to_folder_sync ( - session, folder_uri, 0, cancellable, &error); - - if (error != NULL) { - g_warn_if_fail (folder == NULL); - g_simple_async_result_take_error (simple, error); - return; - } - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - camel_folder_append_message_sync ( - folder, context->message, context->info, - NULL, cancellable, &error); - - g_object_unref (folder); - - if (error != NULL) { - g_simple_async_result_take_error (simple, error); - return; - } - } - - /*** Post Processing ***/ - - /* This accumulates error messages during post-processing. */ - error_messages = g_string_sized_new (256); - - mail_tool_restore_xevolution_headers (context->message, context->xev); - - /* Run filters on the outgoing message. */ - if (context->driver != NULL) { - camel_filter_driver_filter_message ( - context->driver, context->message, context->info, - NULL, NULL, NULL, "", cancellable, &error); - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto exit; - - if (error != NULL) { - g_string_append_printf ( - error_messages, - _("Failed to apply outgoing filters: %s"), - error->message); - g_clear_error (&error); - } - } - - if (!copy_to_sent) - goto cleanup; - - /* Append the sent message to a Sent folder. */ - - local_sent_folder = - e_mail_session_get_local_folder ( - session, E_MAIL_LOCAL_FOLDER_SENT); - - /* Try to extract a CamelFolder from the Sent folder URI. */ - if (context->sent_folder_uri != NULL) { - context->sent_folder = e_mail_session_uri_to_folder_sync ( - session, context->sent_folder_uri, 0, - cancellable, &error); - if (error != NULL) { - g_warn_if_fail (context->sent_folder == NULL); - if (error_messages->len > 0) - g_string_append (error_messages, "\n\n"); - g_string_append_printf ( - error_messages, - _("Failed to append to %s: %s\n" - "Appending to local 'Sent' folder instead."), - context->sent_folder_uri, error->message); - g_clear_error (&error); - } - } - - /* Fall back to the local Sent folder. */ - if (context->sent_folder == NULL) - context->sent_folder = g_object_ref (local_sent_folder); - - /* Append the message. */ - camel_folder_append_message_sync ( - context->sent_folder, context->message, - context->info, NULL, cancellable, &error); - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto exit; - - if (error == NULL) - goto cleanup; - - /* If appending to a remote Sent folder failed, - * try appending to the local Sent folder. */ - if (context->sent_folder != local_sent_folder) { - const gchar *description; - - description = camel_folder_get_description ( - context->sent_folder); - - if (error_messages->len > 0) - g_string_append (error_messages, "\n\n"); - g_string_append_printf ( - error_messages, - _("Failed to append to %s: %s\n" - "Appending to local 'Sent' folder instead."), - description, error->message); - g_clear_error (&error); - - camel_folder_append_message_sync ( - local_sent_folder, context->message, - context->info, NULL, cancellable, &error); - } - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto exit; - - /* We can't even append to the local Sent folder? - * In that case just leave the message in Outbox. */ - if (error != NULL) { - if (error_messages->len > 0) - g_string_append (error_messages, "\n\n"); - g_string_append_printf ( - error_messages, - _("Failed to append to local 'Sent' folder: %s"), - error->message); - g_clear_error (&error); - goto exit; - } - -cleanup: - - /* The send operation was successful; ignore cleanup errors. */ - - /* Mark the draft message for deletion, if present. */ - e_mail_session_handle_draft_headers_sync ( - session, context->message, cancellable, &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } - - /* Set flags on the original source message, if present. - * Source message refers to the message being forwarded - * or replied to. */ - e_mail_session_handle_source_headers_sync ( - session, context->message, cancellable, &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } - -exit: - - /* If we were cancelled, disregard any other errors. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_simple_async_result_take_error (simple, error); - - /* Stuff the accumulated error messages in a GError. */ - } else if (error_messages->len > 0) { - g_simple_async_result_set_error ( - simple, E_MAIL_ERROR, - E_MAIL_ERROR_POST_PROCESSING, - "%s", error_messages->str); - } - - /* Synchronize the Sent folder. */ - if (context->sent_folder != NULL) - camel_folder_synchronize_sync ( - context->sent_folder, FALSE, cancellable, NULL); - - g_string_free (error_messages, TRUE); -} - -void -e_mail_session_send_to (EMailSession *session, - CamelMimeMessage *message, - gint io_priority, - GCancellable *cancellable, - CamelFilterGetFolderFunc get_folder_func, - gpointer get_folder_data, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - CamelAddress *from; - CamelAddress *recipients; - CamelMedium *medium; - CamelMessageInfo *info; - EAccount *account = NULL; - GPtrArray *post_to_uris; - struct _camel_header_raw *xev; - struct _camel_header_raw *header; - const gchar *string; - const gchar *resent_from; - gchar *transport_uid = NULL; - gchar *sent_folder_uri = NULL; - GError *error = NULL; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - - medium = CAMEL_MEDIUM (message); - - camel_medium_set_header (medium, "X-Mailer", X_MAILER); - - xev = mail_tool_remove_xevolution_headers (message); - - /* Extract directives from X-Evolution headers. */ - - string = camel_header_raw_find (&xev, "X-Evolution-Account", NULL); - if (string != NULL) { - gchar *account_uid; - - account_uid = g_strstrip (g_strdup (string)); - account = e_get_account_by_uid (account_uid); - g_free (account_uid); - } - - if (account != NULL) { - if (account->transport != NULL) { - - /* XXX Transport UIDs are kludgy right now. We - * use the EAccount's regular UID and tack on - * "-transport". Will be better soon. */ - transport_uid = g_strconcat ( - account->uid, "-transport", NULL); - - /* to reprompt password on sending if needed */ - account->transport->get_password_canceled = FALSE; - } - sent_folder_uri = g_strdup (account->sent_folder_uri); - } - - string = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL); - if (sent_folder_uri == NULL && string != NULL) - sent_folder_uri = g_strstrip (g_strdup (string)); - - string = camel_header_raw_find (&xev, "X-Evolution-Transport", NULL); - if (transport_uid == NULL && string != NULL) - transport_uid = g_strstrip (g_strdup (string)); - - post_to_uris = g_ptr_array_new (); - for (header = xev; header != NULL; header = header->next) { - gchar *folder_uri; - - if (g_strcmp0 (header->name, "X-Evolution-PostTo") != 0) - continue; - - folder_uri = g_strstrip (g_strdup (header->value)); - g_ptr_array_add (post_to_uris, folder_uri); - } - - /* Collect sender and recipients from headers. */ - - from = (CamelAddress *) camel_internet_address_new (); - recipients = (CamelAddress *) camel_internet_address_new (); - resent_from = camel_medium_get_header (medium, "Resent-From"); - - if (resent_from != NULL) { - const CamelInternetAddress *addr; - const gchar *type; - - camel_address_decode (from, resent_from); - - type = CAMEL_RECIPIENT_TYPE_RESENT_TO; - addr = camel_mime_message_get_recipients (message, type); - camel_address_cat (recipients, CAMEL_ADDRESS (addr)); - - type = CAMEL_RECIPIENT_TYPE_RESENT_CC; - addr = camel_mime_message_get_recipients (message, type); - camel_address_cat (recipients, CAMEL_ADDRESS (addr)); - - type = CAMEL_RECIPIENT_TYPE_RESENT_BCC; - addr = camel_mime_message_get_recipients (message, type); - camel_address_cat (recipients, CAMEL_ADDRESS (addr)); - - } else { - const CamelInternetAddress *addr; - const gchar *type; - - addr = camel_mime_message_get_from (message); - camel_address_copy (from, CAMEL_ADDRESS (addr)); - - type = CAMEL_RECIPIENT_TYPE_TO; - addr = camel_mime_message_get_recipients (message, type); - camel_address_cat (recipients, CAMEL_ADDRESS (addr)); - - type = CAMEL_RECIPIENT_TYPE_CC; - addr = camel_mime_message_get_recipients (message, type); - camel_address_cat (recipients, CAMEL_ADDRESS (addr)); - - type = CAMEL_RECIPIENT_TYPE_BCC; - addr = camel_mime_message_get_recipients (message, type); - camel_address_cat (recipients, CAMEL_ADDRESS (addr)); - } - - /* Miscellaneous preparations. */ - - info = camel_message_info_new (NULL); - camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0); - - /* The rest of the processing happens in a thread. */ - - context = g_slice_new0 (AsyncContext); - context->message = g_object_ref (message); - context->io_priority = io_priority; - context->from = from; - context->recipients = recipients; - context->message = g_object_ref (message); - context->info = info; - context->xev = xev; - context->post_to_uris = post_to_uris; - context->transport_uid = transport_uid; - context->sent_folder_uri = sent_folder_uri; - - if (G_IS_CANCELLABLE (cancellable)) - context->cancellable = g_object_ref (cancellable); - - /* Failure here emits a runtime warning but is non-fatal. */ - context->driver = camel_session_get_filter_driver ( - CAMEL_SESSION (session), E_FILTER_SOURCE_OUTGOING, &error); - if (context->driver != NULL && get_folder_func) - camel_filter_driver_set_folder_func ( - context->driver, get_folder_func, get_folder_data); - if (error != NULL) { - g_warn_if_fail (context->driver == NULL); - g_warning ("%s", error->message); - g_error_free (error); - } - - /* This gets popped in async_context_free(). */ - camel_operation_push_message ( - context->cancellable, _("Sending message")); - - simple = g_simple_async_result_new ( - G_OBJECT (session), callback, - user_data, e_mail_session_send_to); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_session_send_to_thread, - context->io_priority, - context->cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_session_send_to_finish (EMailSession *session, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (session), - e_mail_session_send_to), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_session_unsubscribe_folder_thread (GSimpleAsyncResult *simple, - EMailSession *session, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_mail_session_unsubscribe_folder_sync ( - session, context->folder_uri, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -gboolean -e_mail_session_unsubscribe_folder_sync (EMailSession *session, - const gchar *folder_uri, - GCancellable *cancellable, - GError **error) -{ - CamelStore *store = NULL; - gchar *folder_name = NULL; - const gchar *message; - gboolean success = FALSE; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE); - g_return_val_if_fail (folder_uri != NULL, FALSE); - - success = e_mail_folder_uri_parse ( - CAMEL_SESSION (session), folder_uri, - &store, &folder_name, error); - - if (!success) - return FALSE; - - message = _("Unsubscribing from folder '%s'"); - camel_operation_push_message (cancellable, message, folder_name); - - /* FIXME This should take our GCancellable. */ - success = - em_utils_connect_service_sync ( - CAMEL_SERVICE (store), cancellable, error) && - camel_subscribable_unsubscribe_folder_sync ( - CAMEL_SUBSCRIBABLE (store), - folder_name, cancellable, error); - - camel_operation_pop_message (cancellable); - - g_object_unref (store); - g_free (folder_name); - - return success; -} - -void -e_mail_session_unsubscribe_folder (EMailSession *session, - const gchar *folder_uri, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (folder_uri != NULL); - - context = g_slice_new0 (AsyncContext); - context->folder_uri = g_strdup (folder_uri); - - simple = g_simple_async_result_new ( - G_OBJECT (session), callback, user_data, - e_mail_session_unsubscribe_folder); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_session_unsubscribe_folder_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_session_unsubscribe_folder_finish (EMailSession *session, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (session), - e_mail_session_unsubscribe_folder), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} diff --git a/mail/e-mail-session-utils.h b/mail/e-mail-session-utils.h deleted file mode 100644 index b398be5f84..0000000000 --- a/mail/e-mail-session-utils.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * e-mail-session-utils.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_SESSION_UTILS_H -#define E_MAIL_SESSION_UTILS_H - -/* High-level operations with Evolution-specific policies. */ - -#include <mail/e-mail-session.h> - -#define E_MAIL_ERROR (e_mail_error_quark ()) - -G_BEGIN_DECLS - -typedef enum { - E_MAIL_ERROR_POST_PROCESSING -} EMailError; - -GQuark e_mail_error_quark (void) G_GNUC_CONST; -gboolean e_mail_session_handle_draft_headers_sync - (EMailSession *session, - CamelMimeMessage *message, - GCancellable *cancellable, - GError **error); -void e_mail_session_handle_draft_headers - (EMailSession *session, - CamelMimeMessage *message, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_session_handle_draft_headers_finish - (EMailSession *session, - GAsyncResult *result, - GError **error); -gboolean e_mail_session_handle_source_headers_sync - (EMailSession *session, - CamelMimeMessage *message, - GCancellable *cancellable, - GError **error); -void e_mail_session_handle_source_headers - (EMailSession *session, - CamelMimeMessage *message, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_session_handle_source_headers_finish - (EMailSession *session, - GAsyncResult *result, - GError **error); -void e_mail_session_send_to (EMailSession *session, - CamelMimeMessage *message, - gint io_priority, - GCancellable *cancellable, - CamelFilterGetFolderFunc get_folder_func, - gpointer get_folder_data, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_session_send_to_finish (EMailSession *session, - GAsyncResult *result, - GError **error); -gboolean e_mail_session_unsubscribe_folder_sync - (EMailSession *session, - const gchar *folder_uri, - GCancellable *cancellable, - GError **error); -void e_mail_session_unsubscribe_folder - (EMailSession *session, - const gchar *folder_uri, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_session_unsubscribe_folder_finish - (EMailSession *session, - GAsyncResult *result, - GError **error); - -G_END_DECLS - -#endif /* E_MAIL_SESSION_UTILS_H */ diff --git a/mail/e-mail-session.c b/mail/e-mail-session.c deleted file mode 100644 index 57c800cb91..0000000000 --- a/mail/e-mail-session.c +++ /dev/null @@ -1,2413 +0,0 @@ -/* - * e-mail-session.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2009 Intel Corporation - * - */ - -/* mail-session.c: handles the session information and resource manipulation */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <glib/gi18n.h> -#include <glib/gstdio.h> - -#include <gtk/gtk.h> - -#ifdef HAVE_CANBERRA -#include <canberra-gtk.h> -#endif - -#include <libedataserver/e-flag.h> -#include <libedataserver/e-proxy.h> -#include <libebackend/e-extensible.h> -#include <libedataserverui/e-passwords.h> - -#include "e-util/e-util.h" -#include "e-util/e-account-utils.h" -#include "e-util/e-alert-dialog.h" -#include "e-util/e-util-private.h" - -#include "shell/e-shell.h" -#include "shell/e-shell-view.h" -#include "shell/e-shell-content.h" -#include "shell/e-shell-window.h" - -#include "e-mail-account-store.h" -#include "e-mail-folder-utils.h" -#include "e-mail-junk-filter.h" -#include "e-mail-session.h" -#include "em-composer-utils.h" -#include "em-filter-context.h" -#include "em-filter-rule.h" -#include "em-utils.h" -#include "mail-config.h" -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-send-recv.h" -#include "mail-tools.h" - -#define E_MAIL_SESSION_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MAIL_SESSION, EMailSessionPrivate)) - -typedef struct _AsyncContext AsyncContext; -typedef struct _SourceContext SourceContext; - -struct _EMailSessionPrivate { - EMailAccountStore *account_store; - MailFolderCache *folder_cache; - EMailLabelListStore *label_store; - - EAccountList *account_list; - gulong account_added_handler_id; - gulong account_changed_handler_id; - - CamelStore *local_store; - CamelStore *vfolder_store; - - FILE *filter_logfile; - GHashTable *junk_filters; - EProxy *proxy; - - /* Local folder cache. */ - GPtrArray *local_folders; - GPtrArray *local_folder_uris; -}; - -struct _AsyncContext { - /* arguments */ - CamelStoreGetFolderFlags flags; - gchar *uid; - gchar *uri; - - /* results */ - CamelFolder *folder; -}; - -struct _SourceContext { - EMailSession *session; - CamelService *service; -}; - -enum { - PROP_0, - PROP_ACCOUNT_STORE, - PROP_FOLDER_CACHE, - PROP_JUNK_FILTER_NAME, - PROP_LABEL_STORE, - PROP_LOCAL_STORE, - PROP_VFOLDER_STORE -}; - -enum { - ACTIVITY_ADDED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -static const gchar *local_folder_names[E_MAIL_NUM_LOCAL_FOLDERS] = { - N_("Inbox"), /* E_MAIL_LOCAL_FOLDER_INBOX */ - N_("Drafts"), /* E_MAIL_LOCAL_FOLDER_DRAFTS */ - N_("Outbox"), /* E_MAIL_LOCAL_FOLDER_OUTBOX */ - N_("Sent"), /* E_MAIL_LOCAL_FOLDER_SENT */ - N_("Templates"), /* E_MAIL_LOCAL_FOLDER_TEMPLATES */ - "Inbox" /* E_MAIL_LOCAL_FOLDER_LOCAL_INBOX */ -}; - -static gchar *mail_data_dir; -static gchar *mail_cache_dir; -static gchar *mail_config_dir; - -#if 0 -static MailMsgInfo ms_thread_info_dummy = { sizeof (MailMsg) }; -#endif - -G_DEFINE_TYPE_WITH_CODE ( - EMailSession, - e_mail_session, - CAMEL_TYPE_SESSION, - G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL)) - -/* Support for CamelSession.alert_user() *************************************/ - -static gpointer user_message_dialog; -static GQueue user_message_queue = { NULL, NULL, 0 }; - -struct _user_message_msg { - MailMsg base; - - CamelSessionAlertType type; - gchar *prompt; - GSList *button_captions; - EFlag *done; - - gint result; - guint ismain : 1; -}; - -static void user_message_exec (struct _user_message_msg *m, - GCancellable *cancellable, - GError **error); - -static void -user_message_response_free (GtkDialog *dialog, - gint button) -{ - struct _user_message_msg *m = NULL; - - gtk_widget_destroy ((GtkWidget *) dialog); - - user_message_dialog = NULL; - - /* check for pendings */ - if (!g_queue_is_empty (&user_message_queue)) { - GCancellable *cancellable; - - m = g_queue_pop_head (&user_message_queue); - cancellable = e_activity_get_cancellable (m->base.activity); - user_message_exec (m, cancellable, &m->base.error); - mail_msg_unref (m); - } -} - -/* clicked, send back the reply */ -static void -user_message_response (GtkDialog *dialog, - gint button, - struct _user_message_msg *m) -{ - /* if !m or !button_captions, then we've already replied */ - if (m && m->button_captions) { - m->result = button; - e_flag_set (m->done); - } - - user_message_response_free (dialog, button); -} - -static void -user_message_exec (struct _user_message_msg *m, - GCancellable *cancellable, - GError **error) -{ - gboolean info_only; - GtkWindow *parent; - EShell *shell; - const gchar *error_type; - gint index; - GSList *iter; - - info_only = g_slist_length (m->button_captions) <= 1; - - if (!m->ismain && user_message_dialog != NULL && !info_only) { - g_queue_push_tail (&user_message_queue, mail_msg_ref (m)); - return; - } - - switch (m->type) { - case CAMEL_SESSION_ALERT_INFO: - error_type = "mail:session-message-info"; - break; - case CAMEL_SESSION_ALERT_WARNING: - error_type = "mail:session-message-warning"; - break; - case CAMEL_SESSION_ALERT_ERROR: - error_type = "mail:session-message-error"; - break; - default: - error_type = NULL; - g_return_if_reached (); - } - - shell = e_shell_get_default (); - - /* try to find "mail" view to place the informational alert to */ - if (info_only) { - GtkWindow *active_window; - EShellWindow *shell_window; - EShellView *shell_view; - EShellContent *shell_content = NULL; - - /* check currently active window first, ... */ - active_window = e_shell_get_active_window (shell); - if (active_window && E_IS_SHELL_WINDOW (active_window)) { - if (E_IS_SHELL_WINDOW (active_window)) { - shell_window = E_SHELL_WINDOW (active_window); - shell_view = e_shell_window_peek_shell_view (shell_window, "mail"); - if (shell_view) - shell_content = e_shell_view_get_shell_content (shell_view); - } - } - - if (!shell_content) { - GList *list, *iter; - - list = gtk_application_get_windows (GTK_APPLICATION (shell)); - - /* ...then iterate through all opened windows and pick one which has it */ - for (iter = list; iter != NULL && !shell_content; iter = g_list_next (iter)) { - if (E_IS_SHELL_WINDOW (iter->data)) { - shell_window = iter->data; - shell_view = e_shell_window_peek_shell_view (shell_window, "mail"); - if (shell_view) - shell_content = e_shell_view_get_shell_content (shell_view); - } - } - } - - /* when no shell-content found, which might not happen, but just in case, - process the information alert like usual, through an EAlertDialog machinery - */ - if (shell_content) { - e_alert_submit (E_ALERT_SINK (shell_content), error_type, m->prompt, NULL); - return; - } else if (!m->ismain && user_message_dialog != NULL) { - g_queue_push_tail (&user_message_queue, mail_msg_ref (m)); - return; - } - } - - /* Pull in the active window from the shell to get a parent window */ - parent = e_shell_get_active_window (shell); - user_message_dialog = e_alert_dialog_new_for_args ( - parent, error_type, m->prompt, NULL); - g_object_set (user_message_dialog, "resizable", TRUE, NULL); - - if (m->button_captions) { - GtkWidget *action_area; - GList *children, *child; - - /* remove all default buttons and keep only those requested */ - action_area = gtk_dialog_get_action_area (GTK_DIALOG (user_message_dialog)); - - children = gtk_container_get_children (GTK_CONTAINER (action_area)); - for (child = children; child != NULL; child = child->next) { - gtk_container_remove (GTK_CONTAINER (action_area), child->data); - } - - g_list_free (children); - } - - for (index = 0, iter = m->button_captions; iter; index++, iter = iter->next) { - gtk_dialog_add_button (GTK_DIALOG (user_message_dialog), iter->data, index); - } - - /* XXX This is a case where we need to be able to construct - * custom EAlerts without a predefined XML definition. */ - if (m->ismain) { - gint response; - - response = gtk_dialog_run (user_message_dialog); - user_message_response ( - user_message_dialog, response, m); - } else { - gpointer user_data = m; - - if (g_slist_length (m->button_captions) <= 1) - user_data = NULL; - - g_signal_connect ( - user_message_dialog, "response", - G_CALLBACK (user_message_response), user_data); - gtk_widget_show (user_message_dialog); - } -} - -static void -user_message_free (struct _user_message_msg *m) -{ - g_free (m->prompt); - g_slist_free_full (m->button_captions, g_free); - e_flag_free (m->done); -} - -static MailMsgInfo user_message_info = { - sizeof (struct _user_message_msg), - (MailMsgDescFunc) NULL, - (MailMsgExecFunc) user_message_exec, - (MailMsgDoneFunc) NULL, - (MailMsgFreeFunc) user_message_free -}; - -/* Support for CamelSession.get_filter_driver () *****************************/ - -static CamelFolder * -get_folder (CamelFilterDriver *d, - const gchar *uri, - gpointer user_data, - GError **error) -{ - EMailSession *session = E_MAIL_SESSION (user_data); - - /* FIXME Not passing a GCancellable here. */ - /* FIXME Need a camel_filter_driver_get_session(). */ - return e_mail_session_uri_to_folder_sync ( - session, uri, 0, NULL, error); -} - -static gboolean -session_play_sound_cb (const gchar *filename) -{ -#ifdef HAVE_CANBERRA - if (filename != NULL && *filename != '\0') - ca_context_play ( - ca_gtk_context_get (), 0, - CA_PROP_MEDIA_FILENAME, filename, - NULL); - else -#endif - gdk_beep (); - - return FALSE; -} - -static void -session_play_sound (CamelFilterDriver *driver, - const gchar *filename, - gpointer user_data) -{ - g_idle_add_full ( - G_PRIORITY_DEFAULT_IDLE, - (GSourceFunc) session_play_sound_cb, - g_strdup (filename), (GDestroyNotify) g_free); -} - -static void -session_system_beep (CamelFilterDriver *driver, - gpointer user_data) -{ - g_idle_add ((GSourceFunc) session_play_sound_cb, NULL); -} - -static CamelFilterDriver * -main_get_filter_driver (CamelSession *session, - const gchar *type, - GError **error) -{ - EMailSession *ms = E_MAIL_SESSION (session); - CamelFilterDriver *driver; - EFilterRule *rule = NULL; - const gchar *config_dir; - gchar *user, *system; - GSettings *settings; - ERuleContext *fc; - - settings = g_settings_new ("org.gnome.evolution.mail"); - - config_dir = mail_session_get_config_dir (); - user = g_build_filename (config_dir, "filters.xml", NULL); - system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL); - fc = (ERuleContext *) em_filter_context_new (ms); - e_rule_context_load (fc, system, user); - g_free (system); - g_free (user); - - driver = camel_filter_driver_new (session); - camel_filter_driver_set_folder_func (driver, get_folder, session); - - if (g_settings_get_boolean (settings, "filters-log-actions")) { - if (ms->priv->filter_logfile == NULL) { - gchar *filename; - - filename = g_settings_get_string (settings, "filters-log-file"); - if (filename) { - ms->priv->filter_logfile = g_fopen (filename, "a+"); - g_free (filename); - } - } - - if (ms->priv->filter_logfile) - camel_filter_driver_set_logfile (driver, ms->priv->filter_logfile); - } - - camel_filter_driver_set_shell_func (driver, mail_execute_shell_command, NULL); - camel_filter_driver_set_play_sound_func (driver, session_play_sound, NULL); - camel_filter_driver_set_system_beep_func (driver, session_system_beep, NULL); - - if ((!strcmp (type, E_FILTER_SOURCE_INCOMING) || - !strcmp (type, E_FILTER_SOURCE_JUNKTEST)) - && camel_session_get_check_junk (session)) { - - /* implicit junk check as 1st rule */ - camel_filter_driver_add_rule ( - driver, "Junk check", "(junk-test)", - "(begin (set-system-flag \"junk\"))"); - } - - if (strcmp (type, E_FILTER_SOURCE_JUNKTEST) != 0) { - GString *fsearch, *faction; - - fsearch = g_string_new (""); - faction = g_string_new (""); - - if (!strcmp (type, E_FILTER_SOURCE_DEMAND)) - type = E_FILTER_SOURCE_INCOMING; - - /* add the user-defined rules next */ - while ((rule = e_rule_context_next_rule (fc, rule, type))) { - g_string_truncate (fsearch, 0); - g_string_truncate (faction, 0); - - /* skip disabled rules */ - if (!rule->enabled) - continue; - - e_filter_rule_build_code (rule, fsearch); - em_filter_rule_build_action ( - EM_FILTER_RULE (rule), faction); - camel_filter_driver_add_rule ( - driver, rule->name, - fsearch->str, faction->str); - } - - g_string_free (fsearch, TRUE); - g_string_free (faction, TRUE); - } - - g_object_unref (fc); - - g_object_unref (settings); - - return driver; -} - -/* Support for CamelSession.forward_to () ************************************/ - -static guint preparing_flush = 0; - -static gboolean -forward_to_flush_outbox_cb (EMailSession *session) -{ - g_return_val_if_fail (preparing_flush != 0, FALSE); - - preparing_flush = 0; - mail_send (session); - - return FALSE; -} - -static void -ms_forward_to_cb (CamelFolder *folder, - GAsyncResult *result, - EMailSession *session) -{ - GSettings *settings; - - /* FIXME Poor error handling. */ - if (!e_mail_folder_append_message_finish (folder, result, NULL, NULL)) - return; - - settings = g_settings_new ("org.gnome.evolution.mail"); - - /* do not call mail send immediately, just pile them all in the outbox */ - if (preparing_flush || g_settings_get_boolean ( - settings, "flush-outbox")) { - if (preparing_flush) - g_source_remove (preparing_flush); - - preparing_flush = g_timeout_add_seconds ( - 60, (GSourceFunc) - forward_to_flush_outbox_cb, session); - } - - g_object_unref (settings); -} - -static void -async_context_free (AsyncContext *context) -{ - if (context->folder != NULL) - g_object_unref (context->folder); - - g_free (context->uid); - g_free (context->uri); - - g_slice_free (AsyncContext, context); -} - -static void -source_context_free (SourceContext *context) -{ - if (context->session != NULL) - g_object_unref (context->session); - - if (context->service != NULL) - g_object_unref (context->service); - - g_slice_free (SourceContext, context); -} - -static gchar * -mail_session_make_key (CamelService *service, - const gchar *item) -{ - gchar *key; - - if (service != NULL) { - CamelURL *url; - - url = camel_service_new_camel_url (service); - key = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); - camel_url_free (url); - } else - key = g_strdup (item); - - return key; -} - -static void -mail_session_check_junk_notify (GSettings *settings, - const gchar *key, - CamelSession *session) -{ - if (strcmp (key, "junk-check-incoming") == 0) - camel_session_set_check_junk ( - session, g_settings_get_boolean (settings, key)); -} - -static const gchar * -mail_session_get_junk_filter_name (EMailSession *session) -{ - CamelJunkFilter *junk_filter; - GHashTableIter iter; - gpointer key, value; - - /* XXX This property can be removed once Evolution moves to - * GSettings and can use transform functions when binding - * properties to settings. That's why this is private. */ - - g_hash_table_iter_init (&iter, session->priv->junk_filters); - junk_filter = camel_session_get_junk_filter (CAMEL_SESSION (session)); - - while (g_hash_table_iter_next (&iter, &key, &value)) { - if (junk_filter == CAMEL_JUNK_FILTER (value)) - return (const gchar *) key; - } - - if (junk_filter != NULL) - g_warning ( - "Camel is using a junk filter " - "unknown to Evolution of type %s", - G_OBJECT_TYPE_NAME (junk_filter)); - - return ""; -} - -static void -mail_session_set_junk_filter_name (EMailSession *session, - const gchar *junk_filter_name) -{ - CamelJunkFilter *junk_filter = NULL; - - /* XXX This property can be removed once Evolution moves to - * GSettings and can use transform functions when binding - * properties to settings. That's why this is private. */ - - /* An empty string is equivalent to a NULL string. */ - if (junk_filter_name != NULL && *junk_filter_name == '\0') - junk_filter_name = NULL; - - if (junk_filter_name != NULL) { - junk_filter = g_hash_table_lookup ( - session->priv->junk_filters, junk_filter_name); - if (junk_filter != NULL) { - if (!e_mail_junk_filter_available ( - E_MAIL_JUNK_FILTER (junk_filter))) - junk_filter = NULL; - } else { - g_warning ( - "Unrecognized junk filter name " - "'%s' in GSettings", junk_filter_name); - } - } - - camel_session_set_junk_filter (CAMEL_SESSION (session), junk_filter); - - /* XXX We emit the "notify" signal in mail_session_notify(). */ -} - -static void -mail_session_add_by_account (EMailSession *session, - EAccount *account) -{ - CamelService *service = NULL; - CamelProvider *provider; - CamelURL *url; - gboolean transport_only; - GError *error = NULL; - - /* check whether it's transport-only accounts */ - transport_only = - (account->source == NULL) || - (account->source->url == NULL) || - (*account->source->url == '\0'); - if (transport_only) - goto handle_transport; - - /* Load the service, but don't connect. Check its provider, - * and if this belongs in the folder tree model, add it. */ - - url = camel_url_new (account->source->url, NULL); - if (url != NULL) { - provider = camel_provider_get (url->protocol, NULL); - camel_url_free (url); - } else { - provider = NULL; - } - - if (provider == NULL) { - /* In case we do not have a provider here, we handle - * the special case of having multiple mail identities - * eg. a dummy account having just SMTP server defined */ - goto handle_transport; - } - - service = camel_session_add_service ( - CAMEL_SESSION (session), - account->uid, provider->protocol, - CAMEL_PROVIDER_STORE, &error); - - if (error != NULL) { - g_warning ( - "Failed to add service: %s: %s", - account->name, error->message); - g_error_free (error); - return; - } - - camel_service_set_display_name (service, account->name); - -handle_transport: - - /* While we're at it, add the account's transport (if it has one) - * to the CamelSession. The transport's UID is a kludge for now. - * We take the EAccount's UID and tack on "-transport". */ - - if (account->transport) { - GError *transport_error = NULL; - - url = camel_url_new ( - account->transport->url, - &transport_error); - - if (url != NULL) { - provider = camel_provider_get ( - url->protocol, &transport_error); - camel_url_free (url); - } else - provider = NULL; - - if (provider != NULL) { - gchar *transport_uid; - - transport_uid = g_strconcat ( - account->uid, "-transport", NULL); - - camel_session_add_service ( - CAMEL_SESSION (session), - transport_uid, provider->protocol, - CAMEL_PROVIDER_TRANSPORT, &transport_error); - - g_free (transport_uid); - } - - if (transport_error) { - g_warning ( - "%s: Failed to add transport service: %s", - G_STRFUNC, transport_error->message); - g_error_free (transport_error); - } - } -} - -static void -mail_session_account_added_cb (EAccountList *account_list, - EAccount *account, - EMailSession *session) -{ - mail_session_add_by_account (session, account); -} - -static void -mail_session_account_changed_cb (EAccountList *account_list, - EAccount *account, - EMailSession *session) -{ - EMFolderTreeModel *folder_tree_model; - CamelService *service; - - service = camel_session_get_service ( - CAMEL_SESSION (session), account->uid); - - if (!CAMEL_IS_STORE (service)) - return; - - /* Update the display name of the corresponding CamelStore. - * EMailAccountStore listens for "notify" signals from each - * service so it will detect this and update the model. - * - * XXX If EAccount defined GObject properties we could just - * bind EAccount:name to CamelService:display-name and - * be done with it. Oh well. - */ - - camel_service_set_display_name (service, account->name); - - /* Remove the store from the folder tree model and, if the - * account is still enabled, re-add it. Easier than trying - * to update the model with the store in place. - * - * em_folder_tree_model_add_store() already knows which types - * of stores to disregard, so we don't have to deal with that - * here. */ - - folder_tree_model = em_folder_tree_model_get_default (); - - em_folder_tree_model_remove_store ( - folder_tree_model, CAMEL_STORE (service)); - - if (account->enabled) - em_folder_tree_model_add_store ( - folder_tree_model, CAMEL_STORE (service)); -} - -static gboolean -mail_session_add_service_cb (SourceContext *context) -{ - EMailAccountStore *store; - - store = e_mail_session_get_account_store (context->session); - e_mail_account_store_add_service (store, context->service); - - return FALSE; -} - -static void -mail_session_add_local_store (EMailSession *session) -{ - CamelLocalSettings *local_settings; - CamelSession *camel_session; - CamelSettings *settings; - CamelService *service; - const gchar *data_dir; - gchar *path; - gint ii; - GError *error = NULL; - - camel_session = CAMEL_SESSION (session); - - service = camel_session_add_service ( - camel_session, E_MAIL_SESSION_LOCAL_UID, - "maildir", CAMEL_PROVIDER_STORE, &error); - - /* XXX One could argue this is a fatal error - * since we depend on it in so many places. */ - if (error != NULL) { - g_critical ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - return; - } - - g_return_if_fail (CAMEL_IS_SERVICE (service)); - - camel_service_set_display_name (service, _("On This Computer")); - - settings = camel_service_get_settings (service); - local_settings = CAMEL_LOCAL_SETTINGS (settings); - data_dir = camel_session_get_user_data_dir (camel_session); - - path = g_build_filename (data_dir, E_MAIL_SESSION_LOCAL_UID, NULL); - camel_local_settings_set_path (local_settings, path); - g_free (path); - - /* Shouldn't need to worry about other mail applications - * altering files in our local mail store. */ - g_object_set (service, "need-summary-check", FALSE, NULL); - - /* Populate the local folder cache. */ - for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) { - CamelFolder *folder; - gchar *folder_uri; - const gchar *display_name; - GError *error = NULL; - - display_name = local_folder_names[ii]; - - /* XXX This blocks but should be fast. */ - if (ii == E_MAIL_LOCAL_FOLDER_LOCAL_INBOX) - folder = camel_store_get_inbox_folder_sync ( - CAMEL_STORE (service), NULL, &error); - else - folder = camel_store_get_folder_sync ( - CAMEL_STORE (service), display_name, - CAMEL_STORE_FOLDER_CREATE, NULL, &error); - - folder_uri = e_mail_folder_uri_build ( - CAMEL_STORE (service), display_name); - - /* The arrays take ownership of the items added. */ - g_ptr_array_add (session->priv->local_folders, folder); - g_ptr_array_add (session->priv->local_folder_uris, folder_uri); - - if (error != NULL) { - g_critical ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - } - - session->priv->local_store = g_object_ref (service); -} - -static void -mail_session_add_vfolder_store (EMailSession *session) -{ - CamelSession *camel_session; - CamelService *service; - GError *error = NULL; - - camel_session = CAMEL_SESSION (session); - - service = camel_session_add_service ( - camel_session, E_MAIL_SESSION_VFOLDER_UID, - "vfolder", CAMEL_PROVIDER_STORE, &error); - - if (error != NULL) { - g_critical ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - return; - } - - g_return_if_fail (CAMEL_IS_SERVICE (service)); - - camel_service_set_display_name (service, _("Search Folders")); - em_utils_connect_service_sync (service, NULL, NULL); - - /* XXX There's more configuration to do in vfolder_load_storage() - * but it requires an EMailBackend, which we don't have access - * to from here, so it has to be called from elsewhere. Kinda - * thinking about reworking that... */ - - session->priv->vfolder_store = g_object_ref (service); -} - -static void -mail_session_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_JUNK_FILTER_NAME: - mail_session_set_junk_filter_name ( - E_MAIL_SESSION (object), - g_value_get_string (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_session_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ACCOUNT_STORE: - g_value_set_object ( - value, - e_mail_session_get_account_store ( - E_MAIL_SESSION (object))); - return; - - case PROP_FOLDER_CACHE: - g_value_set_object ( - value, - e_mail_session_get_folder_cache ( - E_MAIL_SESSION (object))); - return; - - case PROP_JUNK_FILTER_NAME: - g_value_set_string ( - value, - mail_session_get_junk_filter_name ( - E_MAIL_SESSION (object))); - return; - - case PROP_LABEL_STORE: - g_value_set_object ( - value, - e_mail_session_get_label_store ( - E_MAIL_SESSION (object))); - return; - - case PROP_LOCAL_STORE: - g_value_set_object ( - value, - e_mail_session_get_local_store ( - E_MAIL_SESSION (object))); - return; - - case PROP_VFOLDER_STORE: - g_value_set_object ( - value, - e_mail_session_get_vfolder_store ( - E_MAIL_SESSION (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_session_dispose (GObject *object) -{ - EMailSessionPrivate *priv; - - priv = E_MAIL_SESSION_GET_PRIVATE (object); - - if (priv->account_store != NULL) { - e_mail_account_store_clear (priv->account_store); - g_object_unref (priv->account_store); - priv->account_store = NULL; - } - - if (priv->folder_cache != NULL) { - g_object_unref (priv->folder_cache); - priv->folder_cache = NULL; - } - - if (priv->label_store != NULL) { - g_object_unref (priv->label_store); - priv->label_store = NULL; - } - - if (priv->account_list != NULL) { - g_signal_handler_disconnect ( - priv->account_list, - priv->account_added_handler_id); - g_signal_handler_disconnect ( - priv->account_list, - priv->account_changed_handler_id); - g_object_unref (priv->account_list); - priv->account_list = NULL; - } - - if (priv->local_store != NULL) { - g_object_unref (priv->local_store); - priv->local_store = NULL; - } - - if (priv->vfolder_store != NULL) { - g_object_unref (priv->vfolder_store); - priv->vfolder_store = NULL; - } - - g_ptr_array_set_size (priv->local_folders, 0); - g_ptr_array_set_size (priv->local_folder_uris, 0); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_mail_session_parent_class)->dispose (object); -} - -static void -mail_session_finalize (GObject *object) -{ - EMailSessionPrivate *priv; - - priv = E_MAIL_SESSION_GET_PRIVATE (object); - - g_hash_table_destroy (priv->junk_filters); - g_object_unref (priv->proxy); - - g_ptr_array_free (priv->local_folders, TRUE); - g_ptr_array_free (priv->local_folder_uris, TRUE); - - g_free (mail_data_dir); - g_free (mail_config_dir); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_mail_session_parent_class)->finalize (object); -} - -static void -mail_session_notify (GObject *object, - GParamSpec *pspec) -{ - /* GObject does not implement this method; do not chain up. */ - - /* XXX Delete this once Evolution moves to GSettings and - * we're able to get rid of PROP_JUNK_FILTER_NAME. */ - if (g_strcmp0 (pspec->name, "junk-filter") == 0) - g_object_notify (object, "junk-filter-name"); -} - -static gboolean -mail_session_initialize_stores_idle (gpointer user_data) -{ - EMailSession *session = user_data; - EAccountList *account_list; - EAccount *account; - EIterator *iter; - - g_return_val_if_fail (session != NULL, FALSE); - - /* Load user-defined mail accounts. */ - account_list = session->priv->account_list; - iter = e_list_get_iterator (E_LIST (account_list)); - - while (e_iterator_is_valid (iter)) { - /* XXX EIterator misuses const. */ - account = (EAccount *) e_iterator_get (iter); - - mail_session_add_by_account (session, account); - - e_iterator_next (iter); - } - - g_object_unref (iter); - - /* Initialize which account is default. */ - - account = e_get_default_account (); - if (account != NULL) { - CamelService *service; - - service = camel_session_get_service ( - CAMEL_SESSION (session), account->uid); - e_mail_account_store_set_default_service ( - session->priv->account_store, service); - } - - return FALSE; -} - -static void -mail_session_constructed (GObject *object) -{ - EMFolderTreeModel *folder_tree_model; - EMailSession *session; - EExtensible *extensible; - GType extension_type; - GList *list, *link; - GSettings *settings; - EAccountList *account_list; - gulong handler_id; - - session = E_MAIL_SESSION (object); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_session_parent_class)->constructed (object); - - account_list = e_get_account_list (); - session->priv->account_list = g_object_ref (account_list); - - session->priv->account_store = e_mail_account_store_new (session); - - /* This must be created after the account store. */ - session->priv->folder_cache = mail_folder_cache_new (session); - - /* XXX Make sure the folder tree model is created before we - * add built-in CamelStores so it gets signals from the - * EMailAccountStore. - * - * XXX This is creating a circular reference. Perhaps the - * model should only hold a weak pointer to EMailSession? - * - * FIXME EMailSession should just own the default instance. - */ - folder_tree_model = em_folder_tree_model_get_default (); - em_folder_tree_model_set_session (folder_tree_model, session); - - /* Add built-in CamelStores. */ - - mail_session_add_local_store (session); - mail_session_add_vfolder_store (session); - - /* Give it a chance to load user settings, they are not loaded yet. - * - * XXX Is this the case where hiding such natural things like loading - * user setting into an EExtension strikes back and proves itself - * being suboptimal? - */ - g_idle_add (mail_session_initialize_stores_idle, object); - - /* Listen for account list updates. */ - - handler_id = g_signal_connect ( - account_list, "account-added", - G_CALLBACK (mail_session_account_added_cb), session); - session->priv->account_added_handler_id = handler_id; - - handler_id = g_signal_connect ( - account_list, "account-changed", - G_CALLBACK (mail_session_account_changed_cb), session); - session->priv->account_changed_handler_id = handler_id; - - extensible = E_EXTENSIBLE (object); - e_extensible_load_extensions (extensible); - - /* Add junk filter extensions to an internal hash table. */ - - extension_type = E_TYPE_MAIL_JUNK_FILTER; - list = e_extensible_list_extensions (extensible, extension_type); - - for (link = list; link != NULL; link = g_list_next (link)) { - EMailJunkFilter *junk_filter; - EMailJunkFilterClass *class; - - junk_filter = E_MAIL_JUNK_FILTER (link->data); - class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter); - - if (!CAMEL_IS_JUNK_FILTER (junk_filter)) { - g_warning ( - "Skipping %s: Does not implement " - "CamelJunkFilterInterface", - G_OBJECT_TYPE_NAME (junk_filter)); - continue; - } - - if (class->filter_name == NULL) { - g_warning ( - "Skipping %s: filter_name unset", - G_OBJECT_TYPE_NAME (junk_filter)); - continue; - } - - if (class->display_name == NULL) { - g_warning ( - "Skipping %s: display_name unset", - G_OBJECT_TYPE_NAME (junk_filter)); - continue; - } - - /* No need to reference the EMailJunkFilter since - * EMailSession owns the reference to it already. */ - g_hash_table_insert ( - session->priv->junk_filters, - (gpointer) class->filter_name, - junk_filter); - } - - g_list_free (list); - - /* Bind the "junk-default-plugin" GSettings - * key to our "junk-filter-name" property. */ - - settings = g_settings_new ("org.gnome.evolution.mail"); - g_settings_bind ( - settings, "junk-default-plugin", - object, "junk-filter-name", - G_SETTINGS_BIND_DEFAULT); - g_object_unref (settings); -} - -static CamelService * -mail_session_add_service (CamelSession *session, - const gchar *uid, - const gchar *protocol, - CamelProviderType type, - GError **error) -{ - CamelService *service; - - /* Chain up to parents add_service() method. */ - service = CAMEL_SESSION_CLASS (e_mail_session_parent_class)-> - add_service (session, uid, protocol, type, error); - - /* Initialize the CamelSettings object from CamelURL parameters. - * This is temporary; soon we'll read settings from key files. */ - - if (CAMEL_IS_SERVICE (service)) { - EAccount *account; - CamelURL *url = NULL; - - account = e_get_account_by_uid (uid); - if (account != NULL) { - const gchar *url_string = NULL; - - switch (type) { - case CAMEL_PROVIDER_STORE: - url_string = account->source->url; - break; - case CAMEL_PROVIDER_TRANSPORT: - url_string = account->transport->url; - break; - default: - break; - } - - if (url_string != NULL) { - url = camel_url_new (url_string, error); - if (url == NULL) { - g_object_unref (service); - service = NULL; - } - } - } - - if (url != NULL) { - CamelSettings *settings; - - settings = camel_service_get_settings (service); - camel_settings_load_from_url (settings, url); - camel_url_free (url); - - g_object_notify (G_OBJECT (service), "settings"); - - /* Migrate files for this service from its old - * URL-based directory to a UID-based directory - * if necessary. */ - camel_service_migrate_files (service); - } - } - - /* Inform the EMailAccountStore of the new CamelService - * from an idle callback so the service has a chance to - * fully initialize first. */ - if (CAMEL_IS_STORE (service)) { - SourceContext *context; - - context = g_slice_new0 (SourceContext); - context->session = g_object_ref (session); - context->service = g_object_ref (service); - - g_idle_add_full ( - G_PRIORITY_DEFAULT_IDLE, - (GSourceFunc) mail_session_add_service_cb, - context, (GDestroyNotify) source_context_free); - } - - return service; -} - -static gchar * -mail_session_get_password (CamelSession *session, - CamelService *service, - const gchar *prompt, - const gchar *item, - guint32 flags, - GError **error) -{ - EAccount *account = NULL; - const gchar *display_name = NULL; - const gchar *uid = NULL; - gchar *ret = NULL; - - if (CAMEL_IS_SERVICE (service)) { - display_name = camel_service_get_display_name (service); - uid = camel_service_get_uid (service); - account = e_get_account_by_uid (uid); - } - - if (!strcmp(item, "popb4smtp_uid")) { - /* not 100% mt safe, but should be ok */ - ret = g_strdup ((account != NULL) ? account->uid : uid); - } else { - gchar *key = mail_session_make_key (service, item); - EAccountService *config_service = NULL; - - ret = e_passwords_get_password (NULL, key); - if (ret == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) { - gboolean remember; - - g_free (ret); - ret = NULL; - - if (account != NULL) { - if (CAMEL_IS_STORE (service)) - config_service = account->source; - if (CAMEL_IS_TRANSPORT (service)) - config_service = account->transport; - } - - remember = config_service ? config_service->save_passwd : FALSE; - - if (!config_service || (config_service && - !config_service->get_password_canceled)) { - guint32 eflags; - gchar *title; - - if (flags & CAMEL_SESSION_PASSPHRASE) { - if (display_name != NULL) - title = g_strdup_printf ( - _("Enter Passphrase for %s"), - display_name); - else - title = g_strdup ( - _("Enter Passphrase")); - } else { - if (display_name != NULL) - title = g_strdup_printf ( - _("Enter Password for %s"), - display_name); - else - title = g_strdup ( - _("Enter Password")); - } - if ((flags & CAMEL_SESSION_PASSWORD_STATIC) != 0) - eflags = E_PASSWORDS_REMEMBER_NEVER; - else if (config_service == NULL) - eflags = E_PASSWORDS_REMEMBER_SESSION; - else - eflags = E_PASSWORDS_REMEMBER_FOREVER; - - if (flags & CAMEL_SESSION_PASSWORD_REPROMPT) - eflags |= E_PASSWORDS_REPROMPT; - - if (flags & CAMEL_SESSION_PASSWORD_SECRET) - eflags |= E_PASSWORDS_SECRET; - - if (flags & CAMEL_SESSION_PASSPHRASE) - eflags |= E_PASSWORDS_PASSPHRASE; - - /* HACK: breaks abstraction ... - * e_account_writable() doesn't use the - * EAccount, it also uses the same writable - * key for source and transport. */ - if (!e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD)) - eflags |= E_PASSWORDS_DISABLE_REMEMBER; - - ret = e_passwords_ask_password ( - title, NULL, key, prompt, - eflags, &remember, NULL); - - if (!ret) - e_passwords_forget_password (NULL, key); - - g_free (title); - - if (ret && config_service) { - config_service->save_passwd = remember; - e_account_list_save (e_get_account_list ()); - } - - if (config_service) - config_service->get_password_canceled = ret == NULL; - } - } - - g_free (key); - } - - if (ret == NULL) - g_set_error ( - error, G_IO_ERROR, - G_IO_ERROR_CANCELLED, - _("User canceled operation.")); - - return ret; -} - -static gboolean -mail_session_forget_password (CamelSession *session, - CamelService *service, - const gchar *item, - GError **error) -{ - gchar *key; - - key = mail_session_make_key (service, item); - - e_passwords_forget_password (NULL, key); - - g_free (key); - - return TRUE; -} - -static gint -mail_session_alert_user (CamelSession *session, - CamelSessionAlertType type, - const gchar *prompt, - GSList *button_captions) -{ - struct _user_message_msg *m; - GCancellable *cancellable; - gint result = -1; - GSList *iter; - - m = mail_msg_new (&user_message_info); - m->ismain = mail_in_main_thread (); - m->type = type; - m->prompt = g_strdup (prompt); - m->done = e_flag_new (); - m->button_captions = g_slist_copy (button_captions); - - for (iter = m->button_captions; iter; iter = iter->next) - iter->data = g_strdup (iter->data); - - if (g_slist_length (button_captions) > 1) - mail_msg_ref (m); - - cancellable = e_activity_get_cancellable (m->base.activity); - - if (m->ismain) - user_message_exec (m, cancellable, &m->base.error); - else - mail_msg_main_loop_push (m); - - if (g_slist_length (button_captions) > 1) { - e_flag_wait (m->done); - result = m->result; - mail_msg_unref (m); - } else if (m->ismain) - mail_msg_unref (m); - - return result; -} - -static CamelFilterDriver * -mail_session_get_filter_driver (CamelSession *session, - const gchar *type, - GError **error) -{ - return (CamelFilterDriver *) mail_call_main ( - MAIL_CALL_p_ppp, (MailMainFunc) main_get_filter_driver, - session, type, error); -} - -static gboolean -mail_session_lookup_addressbook (CamelSession *session, - const gchar *name) -{ - CamelInternetAddress *addr; - gboolean ret; - - if (!mail_config_get_lookup_book ()) - return FALSE; - - addr = camel_internet_address_new (); - camel_address_decode ((CamelAddress *) addr, name); - ret = em_utils_in_addressbook ( - addr, mail_config_get_lookup_book_local_only ()); - g_object_unref (addr); - - return ret; -} - -static gboolean -mail_session_forward_to (CamelSession *session, - CamelFolder *folder, - CamelMimeMessage *message, - const gchar *address, - GError **error) -{ - EAccount *account; - CamelMimeMessage *forward; - CamelStream *mem; - CamelInternetAddress *addr; - CamelFolder *out_folder; - CamelMessageInfo *info; - CamelMedium *medium; - const gchar *from_address; - const gchar *from_name; - const gchar *header_name; - struct _camel_header_raw *xev; - gchar *subject; - - g_return_val_if_fail (folder != NULL, FALSE); - g_return_val_if_fail (message != NULL, FALSE); - g_return_val_if_fail (address != NULL, FALSE); - - if (!*address) { - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("No destination address provided, forward " - "of the message has been cancelled.")); - return FALSE; - } - - account = em_utils_guess_account_with_recipients (message, folder); - if (!account) { - g_set_error ( - error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, - _("No account found to use, forward of the " - "message has been cancelled.")); - return FALSE; - } - - from_address = account->id->address; - from_name = account->id->name; - - forward = camel_mime_message_new (); - - /* make copy of the message, because we are going to modify it */ - mem = camel_stream_mem_new (); - camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (message), mem, NULL, NULL); - g_seekable_seek (G_SEEKABLE (mem), 0, G_SEEK_SET, NULL, NULL); - camel_data_wrapper_construct_from_stream_sync ( - CAMEL_DATA_WRAPPER (forward), mem, NULL, NULL); - g_object_unref (mem); - - /* clear previous recipients */ - camel_mime_message_set_recipients ( - forward, CAMEL_RECIPIENT_TYPE_TO, NULL); - camel_mime_message_set_recipients ( - forward, CAMEL_RECIPIENT_TYPE_CC, NULL); - camel_mime_message_set_recipients ( - forward, CAMEL_RECIPIENT_TYPE_BCC, NULL); - camel_mime_message_set_recipients ( - forward, CAMEL_RECIPIENT_TYPE_RESENT_TO, NULL); - camel_mime_message_set_recipients ( - forward, CAMEL_RECIPIENT_TYPE_RESENT_CC, NULL); - camel_mime_message_set_recipients ( - forward, CAMEL_RECIPIENT_TYPE_RESENT_BCC, NULL); - - medium = CAMEL_MEDIUM (forward); - - /* remove all delivery and notification headers */ - header_name = "Disposition-Notification-To"; - while (camel_medium_get_header (medium, header_name)) - camel_medium_remove_header (medium, header_name); - - header_name = "Delivered-To"; - while (camel_medium_get_header (medium, header_name)) - camel_medium_remove_header (medium, header_name); - - /* remove any X-Evolution-* headers that may have been set */ - xev = mail_tool_remove_xevolution_headers (forward); - camel_header_raw_clear (&xev); - - /* from */ - addr = camel_internet_address_new (); - camel_internet_address_add (addr, from_name, from_address); - camel_mime_message_set_from (forward, addr); - g_object_unref (addr); - - /* to */ - addr = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (addr), address); - camel_mime_message_set_recipients ( - forward, CAMEL_RECIPIENT_TYPE_TO, addr); - g_object_unref (addr); - - /* subject */ - subject = mail_tool_generate_forward_subject (message); - camel_mime_message_set_subject (forward, subject); - g_free (subject); - - /* and send it */ - info = camel_message_info_new (NULL); - out_folder = e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX); - camel_message_info_set_flags ( - info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); - - /* FIXME Pass a GCancellable. */ - e_mail_folder_append_message ( - out_folder, forward, info, G_PRIORITY_DEFAULT, NULL, - (GAsyncReadyCallback) ms_forward_to_cb, session); - - camel_message_info_free (info); - - return TRUE; -} - -static void -mail_session_get_socks_proxy (CamelSession *session, - const gchar *for_host, - gchar **host_ret, - gint *port_ret) -{ - EMailSession *mail_session; - gchar *uri; - - g_return_if_fail (session != NULL); - g_return_if_fail (for_host != NULL); - g_return_if_fail (host_ret != NULL); - g_return_if_fail (port_ret != NULL); - - mail_session = E_MAIL_SESSION (session); - g_return_if_fail (mail_session != NULL); - g_return_if_fail (mail_session->priv != NULL); - - *host_ret = NULL; - *port_ret = 0; - - uri = g_strconcat ("socks://", for_host, NULL); - - if (e_proxy_require_proxy_for_uri (mail_session->priv->proxy, uri)) { - SoupURI *suri; - - suri = e_proxy_peek_uri_for (mail_session->priv->proxy, uri); - if (suri) { - *host_ret = g_strdup (suri->host); - *port_ret = suri->port; - } - } - - g_free (uri); -} - -static gboolean -mail_session_authenticate_sync (CamelSession *session, - CamelService *service, - const gchar *mechanism, - GCancellable *cancellable, - GError **error) -{ - CamelServiceAuthType *authtype = NULL; - CamelAuthenticationResult result; - CamelProvider *provider; - CamelSettings *settings; - const gchar *password; - guint32 password_flags; - GError *local_error = NULL; - - /* Do not chain up. Camel's default method is only an example for - * subclasses to follow. Instead we mimic most of its logic here. */ - - provider = camel_service_get_provider (service); - settings = camel_service_get_settings (service); - - /* APOP is one case where a non-SASL mechanism name is passed, so - * don't bail if the CamelServiceAuthType struct comes back NULL. */ - if (mechanism != NULL) - authtype = camel_sasl_authtype (mechanism); - - /* If the SASL mechanism does not involve a user - * password, then it gets one shot to authenticate. */ - if (authtype != NULL && !authtype->need_password) { - result = camel_service_authenticate_sync ( - service, mechanism, cancellable, error); - if (result == CAMEL_AUTHENTICATION_REJECTED) - g_set_error ( - error, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE, - _("%s authentication failed"), mechanism); - return (result == CAMEL_AUTHENTICATION_ACCEPTED); - } - - /* Some SASL mechanisms can attempt to authenticate without a - * user password being provided (e.g. single-sign-on credentials), - * but can fall back to a user password. Handle that case next. */ - if (mechanism != NULL) { - CamelProvider *provider; - CamelSasl *sasl; - const gchar *service_name; - gboolean success = FALSE; - - provider = camel_service_get_provider (service); - service_name = provider->protocol; - - /* XXX Would be nice if camel_sasl_try_empty_password_sync() - * returned CamelAuthenticationResult so it's easier to - * detect errors. */ - sasl = camel_sasl_new (service_name, mechanism, service); - if (sasl != NULL) { - success = camel_sasl_try_empty_password_sync ( - sasl, cancellable, &local_error); - g_object_unref (sasl); - } - - if (success) - return TRUE; - } - - /* Abort authentication if we got cancelled. - * Otherwise clear any errors and press on. */ - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return FALSE; - - g_clear_error (&local_error); - - password_flags = CAMEL_SESSION_PASSWORD_SECRET; - -retry: - password = camel_service_get_password (service); - - if (password == NULL) { - CamelNetworkSettings *network_settings; - const gchar *host; - const gchar *user; - gchar *prompt; - gchar *new_passwd; - - network_settings = CAMEL_NETWORK_SETTINGS (settings); - host = camel_network_settings_get_host (network_settings); - user = camel_network_settings_get_user (network_settings); - - prompt = camel_session_build_password_prompt ( - provider->name, user, host); - - new_passwd = camel_session_get_password ( - session, service, prompt, "password", - password_flags, &local_error); - camel_service_set_password (service, new_passwd); - password = camel_service_get_password (service); - g_free (new_passwd); - - g_free (prompt); - - if (local_error != NULL) { - g_propagate_error (error, local_error); - return FALSE; - } - - if (password == NULL) { - g_set_error ( - error, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE, - _("No password was provided")); - return FALSE; - } - } - - result = camel_service_authenticate_sync ( - service, mechanism, cancellable, error); - - if (result == CAMEL_AUTHENTICATION_REJECTED) { - password_flags |= CAMEL_SESSION_PASSWORD_REPROMPT; - camel_service_set_password (service, NULL); - goto retry; - } - - return (result == CAMEL_AUTHENTICATION_ACCEPTED); -} - -static void -e_mail_session_class_init (EMailSessionClass *class) -{ - GObjectClass *object_class; - CamelSessionClass *session_class; - - g_type_class_add_private (class, sizeof (EMailSessionPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_session_set_property; - object_class->get_property = mail_session_get_property; - object_class->dispose = mail_session_dispose; - object_class->finalize = mail_session_finalize; - object_class->notify = mail_session_notify; - object_class->constructed = mail_session_constructed; - - session_class = CAMEL_SESSION_CLASS (class); - session_class->add_service = mail_session_add_service; - session_class->get_password = mail_session_get_password; - session_class->forget_password = mail_session_forget_password; - session_class->alert_user = mail_session_alert_user; - session_class->get_filter_driver = mail_session_get_filter_driver; - session_class->lookup_addressbook = mail_session_lookup_addressbook; - session_class->forward_to = mail_session_forward_to; - session_class->get_socks_proxy = mail_session_get_socks_proxy; - session_class->authenticate_sync = mail_session_authenticate_sync; - - g_object_class_install_property ( - object_class, - PROP_FOLDER_CACHE, - g_param_spec_object ( - "folder-cache", - NULL, - NULL, - MAIL_TYPE_FOLDER_CACHE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /* XXX This property can be removed once Evolution moves to - * GSettings and can use transform functions when binding - * properties to settings. */ - g_object_class_install_property ( - object_class, - PROP_JUNK_FILTER_NAME, - g_param_spec_string ( - "junk-filter-name", - NULL, - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_LABEL_STORE, - g_param_spec_object ( - "label-store", - "Label Store", - "Mail label store", - E_TYPE_MAIL_LABEL_LIST_STORE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_LOCAL_STORE, - g_param_spec_object ( - "local-store", - "Local Store", - "Built-in local store", - CAMEL_TYPE_STORE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, - PROP_VFOLDER_STORE, - g_param_spec_object ( - "vfolder-store", - "Search Folder Store", - "Built-in search folder store", - CAMEL_TYPE_STORE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - signals[ACTIVITY_ADDED] = g_signal_new ( - "activity-added", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EMailSessionClass, activity_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - E_TYPE_ACTIVITY); -} - -static void -e_mail_session_init (EMailSession *session) -{ - GSettings *settings; - GHashTable *junk_filters; - - junk_filters = g_hash_table_new ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal); - - session->priv = E_MAIL_SESSION_GET_PRIVATE (session); - session->priv->label_store = e_mail_label_list_store_new (); - session->priv->junk_filters = junk_filters; - session->priv->proxy = e_proxy_new (); - - session->priv->local_folders = - g_ptr_array_new_with_free_func ( - (GDestroyNotify) g_object_unref); - session->priv->local_folder_uris = - g_ptr_array_new_with_free_func ( - (GDestroyNotify) g_free); - - /* Initialize the EAccount setup. */ - e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD); - - settings = g_settings_new ("org.gnome.evolution.mail"); - - camel_session_set_check_junk ( - CAMEL_SESSION (session), g_settings_get_boolean ( - settings, "junk-check-incoming")); - g_signal_connect ( - settings, "changed", - G_CALLBACK (mail_session_check_junk_notify), session); - - mail_config_reload_junk_headers (session); - - e_proxy_setup_proxy (session->priv->proxy); - - g_object_unref (settings); -} - -EMailSession * -e_mail_session_new (void) -{ - const gchar *user_data_dir; - const gchar *user_cache_dir; - - user_data_dir = mail_session_get_data_dir (); - user_cache_dir = mail_session_get_cache_dir (); - - return g_object_new ( - E_TYPE_MAIL_SESSION, - "user-data-dir", user_data_dir, - "user-cache-dir", user_cache_dir, - NULL); -} - -void -e_mail_session_add_activity (EMailSession *session, - EActivity *activity) -{ - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (E_IS_ACTIVITY (activity)); - - g_signal_emit (session, signals[ACTIVITY_ADDED], 0, activity); -} - -EMailAccountStore * -e_mail_session_get_account_store (EMailSession *session) -{ - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - return session->priv->account_store; -} - -MailFolderCache * -e_mail_session_get_folder_cache (EMailSession *session) -{ - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - return session->priv->folder_cache; -} - -EMailLabelListStore * -e_mail_session_get_label_store (EMailSession *session) -{ - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - return session->priv->label_store; -} - -CamelStore * -e_mail_session_get_local_store (EMailSession *session) -{ - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - return session->priv->local_store; -} - -CamelStore * -e_mail_session_get_vfolder_store (EMailSession *session) -{ - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - return session->priv->vfolder_store; -} - -CamelFolder * -e_mail_session_get_local_folder (EMailSession *session, - EMailLocalFolder type) -{ - GPtrArray *local_folders; - CamelFolder *folder; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - local_folders = session->priv->local_folders; - g_return_val_if_fail (type < local_folders->len, NULL); - - folder = g_ptr_array_index (local_folders, type); - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - - return folder; -} - -const gchar * -e_mail_session_get_local_folder_uri (EMailSession *session, - EMailLocalFolder type) -{ - GPtrArray *local_folder_uris; - const gchar *folder_uri; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - local_folder_uris = session->priv->local_folder_uris; - g_return_val_if_fail (type < local_folder_uris->len, NULL); - - folder_uri = g_ptr_array_index (local_folder_uris, type); - g_return_val_if_fail (folder_uri != NULL, NULL); - - return folder_uri; -} - -GList * -e_mail_session_get_available_junk_filters (EMailSession *session) -{ - GList *list, *link; - GQueue trash = G_QUEUE_INIT; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - list = g_hash_table_get_values (session->priv->junk_filters); - - /* Discard unavailable junk filters. (e.g. Junk filter - * requires Bogofilter but Bogofilter is not installed, - * hence the junk filter is unavailable.) */ - - for (link = list; link != NULL; link = g_list_next (link)) { - EMailJunkFilter *junk_filter; - - junk_filter = E_MAIL_JUNK_FILTER (link->data); - if (!e_mail_junk_filter_available (junk_filter)) - g_queue_push_tail (&trash, link); - } - - while ((link = g_queue_pop_head (&trash)) != NULL) - list = g_list_delete_link (list, link); - - /* Sort the remaining junk filters by display name. */ - - return g_list_sort (list, (GCompareFunc) e_mail_junk_filter_compare); -} - -static void -mail_session_get_inbox_thread (GSimpleAsyncResult *simple, - EMailSession *session, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - context->folder = e_mail_session_get_inbox_sync ( - session, context->uid, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -CamelFolder * -e_mail_session_get_inbox_sync (EMailSession *session, - const gchar *service_uid, - GCancellable *cancellable, - GError **error) -{ - CamelService *service; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - g_return_val_if_fail (service_uid != NULL, NULL); - - service = camel_session_get_service ( - CAMEL_SESSION (session), service_uid); - - if (!CAMEL_IS_STORE (service)) - return NULL; - - if (!em_utils_connect_service_sync (service, cancellable, error)) - return NULL; - - return camel_store_get_inbox_folder_sync ( - CAMEL_STORE (service), cancellable, error); -} - -void -e_mail_session_get_inbox (EMailSession *session, - const gchar *service_uid, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (service_uid != NULL); - - context = g_slice_new0 (AsyncContext); - context->uid = g_strdup (service_uid); - - simple = g_simple_async_result_new ( - G_OBJECT (session), callback, - user_data, e_mail_session_get_inbox); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_session_get_inbox_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -CamelFolder * -e_mail_session_get_inbox_finish (EMailSession *session, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (session), - e_mail_session_get_inbox), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - g_return_val_if_fail (CAMEL_IS_FOLDER (context->folder), NULL); - - return g_object_ref (context->folder); -} - -static void -mail_session_get_trash_thread (GSimpleAsyncResult *simple, - EMailSession *session, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - context->folder = e_mail_session_get_trash_sync ( - session, context->uid, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -CamelFolder * -e_mail_session_get_trash_sync (EMailSession *session, - const gchar *service_uid, - GCancellable *cancellable, - GError **error) -{ - CamelService *service; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - g_return_val_if_fail (service_uid != NULL, NULL); - - service = camel_session_get_service ( - CAMEL_SESSION (session), service_uid); - - if (!CAMEL_IS_STORE (service)) - return NULL; - - if (!em_utils_connect_service_sync (service, cancellable, error)) - return NULL; - - return camel_store_get_trash_folder_sync ( - CAMEL_STORE (service), cancellable, error); -} - -void -e_mail_session_get_trash (EMailSession *session, - const gchar *service_uid, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (service_uid != NULL); - - context = g_slice_new0 (AsyncContext); - context->uid = g_strdup (service_uid); - - simple = g_simple_async_result_new ( - G_OBJECT (session), callback, - user_data, e_mail_session_get_trash); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_session_get_trash_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -CamelFolder * -e_mail_session_get_trash_finish (EMailSession *session, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (session), - e_mail_session_get_trash), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - g_return_val_if_fail (CAMEL_IS_FOLDER (context->folder), NULL); - - return g_object_ref (context->folder); -} - -static void -mail_session_uri_to_folder_thread (GSimpleAsyncResult *simple, - EMailSession *session, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - context->folder = e_mail_session_uri_to_folder_sync ( - session, context->uri, context->flags, - cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -CamelFolder * -e_mail_session_uri_to_folder_sync (EMailSession *session, - const gchar *folder_uri, - CamelStoreGetFolderFlags flags, - GCancellable *cancellable, - GError **error) -{ - CamelStore *store; - CamelFolder *folder; - gchar *folder_name; - gboolean success; - - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - g_return_val_if_fail (folder_uri != NULL, NULL); - - success = e_mail_folder_uri_parse ( - CAMEL_SESSION (session), folder_uri, - &store, &folder_name, error); - - if (!success) - return NULL; - - folder = camel_store_get_folder_sync ( - store, folder_name, flags, cancellable, error); - - if (folder != NULL) { - MailFolderCache *folder_cache; - folder_cache = e_mail_session_get_folder_cache (session); - mail_folder_cache_note_folder (folder_cache, folder); - } - - g_free (folder_name); - g_object_unref (store); - - return folder; -} - -void -e_mail_session_uri_to_folder (EMailSession *session, - const gchar *folder_uri, - CamelStoreGetFolderFlags flags, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (folder_uri != NULL); - - context = g_slice_new0 (AsyncContext); - context->uri = g_strdup (folder_uri); - context->flags = flags; - - simple = g_simple_async_result_new ( - G_OBJECT (session), callback, - user_data, e_mail_session_uri_to_folder); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_session_uri_to_folder_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -CamelFolder * -e_mail_session_uri_to_folder_finish (EMailSession *session, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (session), - e_mail_session_uri_to_folder), NULL); - - simple = G_SIMPLE_ASYNC_RESULT (result); - context = g_simple_async_result_get_op_res_gpointer (simple); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - g_return_val_if_fail (CAMEL_IS_FOLDER (context->folder), NULL); - - return g_object_ref (context->folder); -} - -/******************************** Legacy API *********************************/ - -void -mail_session_flush_filter_log (EMailSession *session) -{ - g_return_if_fail (E_IS_MAIL_SESSION (session)); - - if (session->priv->filter_logfile) - fflush (session->priv->filter_logfile); -} - -const gchar * -mail_session_get_data_dir (void) -{ - if (G_UNLIKELY (mail_data_dir == NULL)) - mail_data_dir = g_build_filename ( - e_get_user_data_dir (), "mail", NULL); - - return mail_data_dir; -} - -const gchar * -mail_session_get_cache_dir (void) -{ - if (G_UNLIKELY (mail_cache_dir == NULL)) - mail_cache_dir = g_build_filename ( - e_get_user_cache_dir (), "mail", NULL); - - return mail_cache_dir; -} - -const gchar * -mail_session_get_config_dir (void) -{ - if (G_UNLIKELY (mail_config_dir == NULL)) - mail_config_dir = g_build_filename ( - e_get_user_config_dir (), "mail", NULL); - - return mail_config_dir; -} - diff --git a/mail/e-mail-session.h b/mail/e-mail-session.h deleted file mode 100644 index 7f5f22de27..0000000000 --- a/mail/e-mail-session.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * e-mail-session.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_MAIL_SESSION_H -#define E_MAIL_SESSION_H - -#include <camel/camel.h> -#include <e-util/e-activity.h> -#include <mail/e-mail-enums.h> -#include <mail/e-mail-account-store.h> -#include <mail/e-mail-label-list-store.h> -#include <mail/mail-folder-cache.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_SESSION \ - (e_mail_session_get_type ()) -#define E_MAIL_SESSION(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_SESSION, EMailSession)) -#define E_MAIL_SESSION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_SESSION, EMailSessionClass)) -#define E_IS_MAIL_SESSION(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_SESSION)) -#define E_IS_MAIL_SESSION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_SESSION)) -#define E_MAIL_SESSION_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_SESSION, EMailSessionClass)) - -/* Built-in CamelServices */ -#define E_MAIL_SESSION_LOCAL_UID "local" /* "On This Computer" */ -#define E_MAIL_SESSION_VFOLDER_UID "vfolder" /* "Search Folders" */ - -G_BEGIN_DECLS - -typedef struct _EMailSession EMailSession; -typedef struct _EMailSessionClass EMailSessionClass; -typedef struct _EMailSessionPrivate EMailSessionPrivate; - -struct _EMailSession { - CamelSession parent; - EMailSessionPrivate *priv; -}; - -struct _EMailSessionClass { - CamelSessionClass parent_class; - - void (*activity_added) (EMailSession *session, - EActivity *activity); -}; - -GType e_mail_session_get_type (void); -EMailSession * e_mail_session_new (void); -void e_mail_session_add_activity (EMailSession *session, - EActivity *activity); -EMailAccountStore * - e_mail_session_get_account_store - (EMailSession *session); -MailFolderCache * - e_mail_session_get_folder_cache (EMailSession *session); -EMailLabelListStore * - e_mail_session_get_label_store (EMailSession *session); -CamelStore * e_mail_session_get_local_store (EMailSession *session); -CamelStore * e_mail_session_get_vfolder_store - (EMailSession *session); -CamelFolder * e_mail_session_get_local_folder (EMailSession *session, - EMailLocalFolder type); -const gchar * e_mail_session_get_local_folder_uri - (EMailSession *session, - EMailLocalFolder type); -GList * e_mail_session_get_available_junk_filters - (EMailSession *session); -CamelFolder * e_mail_session_get_inbox_sync (EMailSession *session, - const gchar *service_uid, - GCancellable *cancellable, - GError **error); -void e_mail_session_get_inbox (EMailSession *session, - const gchar *service_uid, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -CamelFolder * e_mail_session_get_inbox_finish (EMailSession *session, - GAsyncResult *result, - GError **error); -CamelFolder * e_mail_session_get_trash_sync (EMailSession *session, - const gchar *service_uid, - GCancellable *cancellable, - GError **error); -void e_mail_session_get_trash (EMailSession *session, - const gchar *service_uid, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -CamelFolder * e_mail_session_get_trash_finish (EMailSession *session, - GAsyncResult *result, - GError **error); -CamelFolder * e_mail_session_uri_to_folder_sync - (EMailSession *session, - const gchar *folder_uri, - CamelStoreGetFolderFlags flags, - GCancellable *cancellable, - GError **error); -void e_mail_session_uri_to_folder (EMailSession *session, - const gchar *folder_uri, - CamelStoreGetFolderFlags flags, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -CamelFolder * e_mail_session_uri_to_folder_finish - (EMailSession *session, - GAsyncResult *result, - GError **error); - -/*** Legacy API ***/ - -void mail_session_flush_filter_log (EMailSession *session); -const gchar * mail_session_get_data_dir (void); -const gchar * mail_session_get_cache_dir (void); -const gchar * mail_session_get_config_dir (void); - -G_END_DECLS - -#endif /* E_MAIL_SESSION_H */ diff --git a/mail/e-mail-sidebar.h b/mail/e-mail-sidebar.h index a88c3ccc15..bdde4c1090 100644 --- a/mail/e-mail-sidebar.h +++ b/mail/e-mail-sidebar.h @@ -22,8 +22,8 @@ #ifndef E_MAIL_SIDEBAR_H #define E_MAIL_SIDEBAR_H -#include <mail/e-mail-session.h> #include <mail/em-folder-tree.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define E_TYPE_MAIL_SIDEBAR \ diff --git a/mail/e-mail-store-utils.c b/mail/e-mail-store-utils.c deleted file mode 100644 index 7f978c8b7f..0000000000 --- a/mail/e-mail-store-utils.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * e-mail-store-utils.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "em-utils.h" - -#include "e-mail-store-utils.h" - -#include <glib/gi18n-lib.h> - -typedef struct _AsyncContext AsyncContext; - -struct _AsyncContext { - gchar *full_name; -}; - -static void -async_context_free (AsyncContext *context) -{ - g_free (context->full_name); - - g_slice_free (AsyncContext, context); -} - -static void -mail_store_create_folder_thread (GSimpleAsyncResult *simple, - GObject *object, - GCancellable *cancellable) -{ - AsyncContext *context; - GError *error = NULL; - - context = g_simple_async_result_get_op_res_gpointer (simple); - - e_mail_store_create_folder_sync ( - CAMEL_STORE (object), context->full_name, - cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); -} - -gboolean -e_mail_store_create_folder_sync (CamelStore *store, - const gchar *full_name, - GCancellable *cancellable, - GError **error) -{ - CamelFolderInfo *folder_info; - gchar *copied_full_name; - gchar *display_name; - const gchar *parent; - gboolean success = TRUE; - - g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE); - g_return_val_if_fail (full_name != NULL, FALSE); - - copied_full_name = g_strdup (full_name); - display_name = strrchr (copied_full_name, '/'); - if (display_name == NULL) { - display_name = copied_full_name; - parent = ""; - } else { - *display_name++ = '\0'; - parent = copied_full_name; - } - - folder_info = camel_store_create_folder_sync ( - store, parent, display_name, cancellable, error); - - g_free (copied_full_name); - - if (folder_info == NULL) - return FALSE; - - if (CAMEL_IS_SUBSCRIBABLE (store)) - success = camel_subscribable_subscribe_folder_sync ( - CAMEL_SUBSCRIBABLE (store), - full_name, cancellable, error); - - camel_store_free_folder_info (store, folder_info); - - return success; -} - -void -e_mail_store_create_folder (CamelStore *store, - const gchar *full_name, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AsyncContext *context; - - g_return_if_fail (CAMEL_IS_STORE (store)); - g_return_if_fail (full_name != NULL); - - context = g_slice_new0 (AsyncContext); - context->full_name = g_strdup (full_name); - - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, user_data, - e_mail_store_create_folder); - - g_simple_async_result_set_op_res_gpointer ( - simple, context, (GDestroyNotify) async_context_free); - - g_simple_async_result_run_in_thread ( - simple, mail_store_create_folder_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_store_create_folder_finish (CamelStore *store, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (store), - e_mail_store_create_folder), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_store_go_offline_thread (GSimpleAsyncResult *simple, - CamelStore *store, - GCancellable *cancellable) -{ - CamelService *service; - gchar *service_name; - GError *error = NULL; - - service = CAMEL_SERVICE (store); - - service_name = camel_service_get_name (service, TRUE); - camel_operation_push_message ( - cancellable, _("Disconnecting from '%s'"), service_name); - g_free (service_name); - - if (CAMEL_IS_DISCO_STORE (store)) { - CamelDiscoStore *disco_store; - - disco_store = CAMEL_DISCO_STORE (store); - - if (camel_disco_store_can_work_offline (disco_store)) - camel_disco_store_set_status ( - disco_store, CAMEL_DISCO_STORE_OFFLINE, - cancellable, &error); - else - em_utils_disconnect_service_sync (service, TRUE, cancellable, &error); - - } else if (CAMEL_IS_OFFLINE_STORE (store)) { - CamelOfflineStore *offline_store; - - offline_store = CAMEL_OFFLINE_STORE (store); - - camel_offline_store_set_online_sync ( - offline_store, FALSE, cancellable, &error); - - } else - em_utils_disconnect_service_sync (service, TRUE, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); - - camel_operation_pop_message (cancellable); -} - -void -e_mail_store_go_offline (CamelStore *store, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - - g_return_if_fail (CAMEL_IS_STORE (store)); - - /* Cancel any pending connect first so the set_offline_op - * thread won't get queued behind a hung connect op. */ - camel_service_cancel_connect (CAMEL_SERVICE (store)); - - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, - user_data, e_mail_store_go_offline); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_store_go_offline_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_store_go_offline_finish (CamelStore *store, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (store), e_mail_store_go_offline), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_store_go_online_thread (GSimpleAsyncResult *simple, - CamelStore *store, - GCancellable *cancellable) -{ - CamelService *service; - gchar *service_name; - GError *error = NULL; - - service = CAMEL_SERVICE (store); - - service_name = camel_service_get_name (service, TRUE); - camel_operation_push_message ( - cancellable, _("Reconnecting to '%s'"), service_name); - g_free (service_name); - - if (CAMEL_IS_DISCO_STORE (store)) - camel_disco_store_set_status ( - CAMEL_DISCO_STORE (store), - CAMEL_DISCO_STORE_ONLINE, - cancellable, &error); - - else if (CAMEL_IS_OFFLINE_STORE (store)) - camel_offline_store_set_online_sync ( - CAMEL_OFFLINE_STORE (store), - TRUE, cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); - - camel_operation_pop_message (cancellable); -} - -void -e_mail_store_go_online (CamelStore *store, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - - g_return_if_fail (CAMEL_IS_STORE (store)); - - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, - user_data, e_mail_store_go_online); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_store_go_online_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_store_go_online_finish (CamelStore *store, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (store), e_mail_store_go_online), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} - -static void -mail_store_prepare_for_offline_thread (GSimpleAsyncResult *simple, - CamelStore *store, - GCancellable *cancellable) -{ - CamelService *service; - gchar *service_name; - GError *error = NULL; - - service = CAMEL_SERVICE (store); - - service_name = camel_service_get_name (service, TRUE); - camel_operation_push_message ( - cancellable, _("Preparing account '%s' for offline"), - service_name); - g_free (service_name); - - if (CAMEL_IS_DISCO_STORE (store)) - camel_disco_store_prepare_for_offline ( - CAMEL_DISCO_STORE (store), cancellable, &error); - - else if (CAMEL_IS_OFFLINE_STORE (store)) - camel_offline_store_prepare_for_offline_sync ( - CAMEL_OFFLINE_STORE (store), cancellable, &error); - - if (error != NULL) - g_simple_async_result_take_error (simple, error); - - camel_operation_pop_message (cancellable); -} - -void -e_mail_store_prepare_for_offline (CamelStore *store, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - - g_return_if_fail (CAMEL_IS_STORE (store)); - - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, user_data, - e_mail_store_prepare_for_offline); - - g_simple_async_result_run_in_thread ( - simple, (GSimpleAsyncThreadFunc) - mail_store_prepare_for_offline_thread, - io_priority, cancellable); - - g_object_unref (simple); -} - -gboolean -e_mail_store_prepare_for_offline_finish (CamelStore *store, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (store), - e_mail_store_prepare_for_offline), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} diff --git a/mail/e-mail-store-utils.h b/mail/e-mail-store-utils.h deleted file mode 100644 index de4484c020..0000000000 --- a/mail/e-mail-store-utils.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * e-mail-store-utils.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef E_MAIL_STORE_UTILS_H -#define E_MAIL_STORE_UTILS_H - -/* CamelStore wrappers with Evolution-specific policies. */ - -#include <camel/camel.h> - -G_BEGIN_DECLS - -gboolean e_mail_store_create_folder_sync (CamelStore *store, - const gchar *full_name, - GCancellable *cancellable, - GError **error); -void e_mail_store_create_folder (CamelStore *store, - const gchar *full_name, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_store_create_folder_finish - (CamelStore *store, - GAsyncResult *result, - GError **error); - -void e_mail_store_go_offline (CamelStore *store, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_store_go_offline_finish (CamelStore *store, - GAsyncResult *result, - GError **error); - -void e_mail_store_go_online (CamelStore *store, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_store_go_online_finish (CamelStore *store, - GAsyncResult *result, - GError **error); - -void e_mail_store_prepare_for_offline - (CamelStore *store, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean e_mail_store_prepare_for_offline_finish - (CamelStore *store, - GAsyncResult *result, - GError **error); - -G_END_DECLS - -#endif /* E_MAIL_STORE_UTILS_H */ diff --git a/mail/e-mail-ui-session.c b/mail/e-mail-ui-session.c new file mode 100644 index 0000000000..dcb2e25573 --- /dev/null +++ b/mail/e-mail-ui-session.c @@ -0,0 +1,904 @@ +/* + * e-mail-ui-session.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2009 Intel Corporation + * + */ + +/* mail-session.c: handles the session information and resource manipulation */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <glib/gi18n.h> +#include <glib/gstdio.h> + +#include <gtk/gtk.h> + + +#ifdef HAVE_CANBERRA +#include <canberra-gtk.h> +#endif + +#include <libedataserver/e-flag.h> +#include <libedataserver/e-proxy.h> +#include <libebackend/e-extensible.h> +#include <libedataserverui/e-passwords.h> + +#include "e-mail-account-store.h" + +#include "e-util/e-util.h" +#include "libemail-utils/e-account-utils.h" +#include "e-util/e-alert-dialog.h" +#include "e-util/e-util-private.h" + +#include "shell/e-shell.h" +#include "shell/e-shell-view.h" +#include "shell/e-shell-content.h" +#include "shell/e-shell-window.h" + +#include "libemail-engine/e-mail-folder-utils.h" +#include "libemail-engine/e-mail-junk-filter.h" +#include "libemail-engine/e-mail-session.h" +#include "e-mail-ui-session.h" +#include "em-composer-utils.h" +#include "em-filter-context.h" +#include "em-filter-rule.h" +#include "em-utils.h" +#include "libemail-engine/mail-config.h" +#include "libemail-utils/mail-mt.h" +#include "libemail-engine/mail-ops.h" +#include "mail-send-recv.h" +#include "libemail-engine/mail-tools.h" + +#define E_MAIL_UI_SESSION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MAIL_UI_SESSION, EMailUISessionPrivate)) + +typedef struct _SourceContext SourceContext; + +struct _EMailUISessionPrivate { + FILE *filter_logfile; + CamelStore *vfolder_store; + EMailAccountStore *account_store; + EMailLabelListStore *label_store; + + EAccountList *account_list; + gulong account_changed_handler_id; +}; + +enum { + PROP_0, + PROP_ACCOUNT_STORE, + PROP_LABEL_STORE, + PROP_VFOLDER_STORE +}; + +enum { + ACTIVITY_ADDED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +G_DEFINE_TYPE_WITH_CODE ( + EMailUISession, + e_mail_ui_session, + E_TYPE_MAIL_SESSION, + G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL)) + +struct _SourceContext { + EMailUISession *session; + CamelService *service; +}; + +/* Support for CamelSession.alert_user() *************************************/ + +static gpointer user_message_dialog; +static GQueue user_message_queue = { NULL, NULL, 0 }; + +struct _user_message_msg { + MailMsg base; + + CamelSessionAlertType type; + gchar *prompt; + GSList *button_captions; + EFlag *done; + + gint result; + guint ismain : 1; +}; + +static void user_message_exec (struct _user_message_msg *m, + GCancellable *cancellable, + GError **error); + +static void +user_message_response_free (GtkDialog *dialog, + gint button) +{ + struct _user_message_msg *m = NULL; + + gtk_widget_destroy ((GtkWidget *) dialog); + + user_message_dialog = NULL; + + /* check for pendings */ + if (!g_queue_is_empty (&user_message_queue)) { + GCancellable *cancellable; + + m = g_queue_pop_head (&user_message_queue); + cancellable = m->base.cancellable; + user_message_exec (m, cancellable, &m->base.error); + mail_msg_unref (m); + } +} + +/* clicked, send back the reply */ +static void +user_message_response (GtkDialog *dialog, + gint button, + struct _user_message_msg *m) +{ + /* if !m or !button_captions, then we've already replied */ + if (m && m->button_captions) { + m->result = button; + e_flag_set (m->done); + } + + user_message_response_free (dialog, button); +} + +static void +user_message_exec (struct _user_message_msg *m, + GCancellable *cancellable, + GError **error) +{ + gboolean info_only; + GtkWindow *parent; + EShell *shell; + const gchar *error_type; + gint index; + GSList *iter; + + info_only = g_slist_length (m->button_captions) <= 1; + + if (!m->ismain && user_message_dialog != NULL && !info_only) { + g_queue_push_tail (&user_message_queue, mail_msg_ref (m)); + return; + } + + switch (m->type) { + case CAMEL_SESSION_ALERT_INFO: + error_type = "mail:session-message-info"; + break; + case CAMEL_SESSION_ALERT_WARNING: + error_type = "mail:session-message-warning"; + break; + case CAMEL_SESSION_ALERT_ERROR: + error_type = "mail:session-message-error"; + break; + default: + error_type = NULL; + g_return_if_reached (); + } + + shell = e_shell_get_default (); + + /* try to find "mail" view to place the informational alert to */ + if (info_only) { + GtkWindow *active_window; + EShellWindow *shell_window; + EShellView *shell_view; + EShellContent *shell_content = NULL; + + /* check currently active window first, ... */ + active_window = e_shell_get_active_window (shell); + if (active_window && E_IS_SHELL_WINDOW (active_window)) { + if (E_IS_SHELL_WINDOW (active_window)) { + shell_window = E_SHELL_WINDOW (active_window); + shell_view = e_shell_window_peek_shell_view (shell_window, "mail"); + if (shell_view) + shell_content = e_shell_view_get_shell_content (shell_view); + } + } + + if (!shell_content) { + GList *list, *iter; + + list = gtk_application_get_windows (GTK_APPLICATION (shell)); + + /* ...then iterate through all opened windows and pick one which has it */ + for (iter = list; iter != NULL && !shell_content; iter = g_list_next (iter)) { + if (E_IS_SHELL_WINDOW (iter->data)) { + shell_window = iter->data; + shell_view = e_shell_window_peek_shell_view (shell_window, "mail"); + if (shell_view) + shell_content = e_shell_view_get_shell_content (shell_view); + } + } + } + + /* when no shell-content found, which might not happen, but just in case, + process the information alert like usual, through an EAlertDialog machinery + */ + if (shell_content) { + e_alert_submit (E_ALERT_SINK (shell_content), error_type, m->prompt, NULL); + return; + } else if (!m->ismain && user_message_dialog != NULL) { + g_queue_push_tail (&user_message_queue, mail_msg_ref (m)); + return; + } + } + + /* Pull in the active window from the shell to get a parent window */ + parent = e_shell_get_active_window (shell); + user_message_dialog = e_alert_dialog_new_for_args ( + parent, error_type, m->prompt, NULL); + g_object_set (user_message_dialog, "resizable", TRUE, NULL); + + if (m->button_captions) { + GtkWidget *action_area; + GList *children, *child; + + /* remove all default buttons and keep only those requested */ + action_area = gtk_dialog_get_action_area (GTK_DIALOG (user_message_dialog)); + + children = gtk_container_get_children (GTK_CONTAINER (action_area)); + for (child = children; child != NULL; child = child->next) { + gtk_container_remove (GTK_CONTAINER (action_area), child->data); + } + + g_list_free (children); + } + + for (index = 0, iter = m->button_captions; iter; index++, iter = iter->next) { + gtk_dialog_add_button (GTK_DIALOG (user_message_dialog), iter->data, index); + } + + + /* XXX This is a case where we need to be able to construct + * custom EAlerts without a predefined XML definition. */ + if (m->ismain) { + gint response; + + response = gtk_dialog_run (user_message_dialog); + user_message_response ( + user_message_dialog, response, m); + } else { + gpointer user_data = m; + + if (g_slist_length (m->button_captions) <= 1) + user_data = NULL; + + g_signal_connect ( + user_message_dialog, "response", + G_CALLBACK (user_message_response), user_data); + gtk_widget_show (user_message_dialog); + } +} + +static void +user_message_free (struct _user_message_msg *m) +{ + g_free (m->prompt); + g_slist_free_full (m->button_captions, g_free); + e_flag_free (m->done); +} + +static MailMsgInfo user_message_info = { + sizeof (struct _user_message_msg), + (MailMsgDescFunc) NULL, + (MailMsgExecFunc) user_message_exec, + (MailMsgDoneFunc) NULL, + (MailMsgFreeFunc) user_message_free +}; + +/* Support for CamelSession.get_filter_driver () *****************************/ + +static CamelFolder * +get_folder (CamelFilterDriver *d, + const gchar *uri, + gpointer user_data, + GError **error) +{ + EMailSession *session = E_MAIL_SESSION (user_data); + + /* FIXME Not passing a GCancellable here. */ + /* FIXME Need a camel_filter_driver_get_session(). */ + return e_mail_session_uri_to_folder_sync ( + session, uri, 0, NULL, error); +} + +static gboolean +session_play_sound_cb (const gchar *filename) +{ +#ifdef HAVE_CANBERRA + if (filename != NULL && *filename != '\0') + ca_context_play ( + ca_gtk_context_get (), 0, + CA_PROP_MEDIA_FILENAME, filename, + NULL); + else +#endif + gdk_beep (); + + return FALSE; +} + +static void +session_play_sound (CamelFilterDriver *driver, + const gchar *filename, + gpointer user_data) +{ + g_idle_add_full ( + G_PRIORITY_DEFAULT_IDLE, + (GSourceFunc) session_play_sound_cb, + g_strdup (filename), (GDestroyNotify) g_free); +} + +static void +session_system_beep (CamelFilterDriver *driver, + gpointer user_data) +{ + g_idle_add ((GSourceFunc) session_play_sound_cb, NULL); +} + +static CamelFilterDriver * +main_get_filter_driver (CamelSession *session, + const gchar *type, + GError **error) +{ + EMailSession *ms = E_MAIL_SESSION (session); + CamelFilterDriver *driver; + EFilterRule *rule = NULL; + const gchar *config_dir; + gchar *user, *system; + GSettings *settings; + ERuleContext *fc; + EMailUISessionPrivate *priv; + + priv = E_MAIL_UI_SESSION_GET_PRIVATE (session); + + settings = g_settings_new ("org.gnome.evolution.mail"); + + config_dir = mail_session_get_config_dir (); + user = g_build_filename (config_dir, "filters.xml", NULL); + system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL); + fc = (ERuleContext *) em_filter_context_new (ms); + e_rule_context_load (fc, system, user); + g_free (system); + g_free (user); + + driver = camel_filter_driver_new (session); + camel_filter_driver_set_folder_func (driver, get_folder, session); + + if (g_settings_get_boolean (settings, "filters-log-actions")) { + if (priv->filter_logfile == NULL) { + gchar *filename; + + filename = g_settings_get_string (settings, "filters-log-file"); + if (filename) { + priv->filter_logfile = g_fopen (filename, "a+"); + g_free (filename); + } + } + + if (priv->filter_logfile) + camel_filter_driver_set_logfile (driver, priv->filter_logfile); + } + + camel_filter_driver_set_shell_func (driver, mail_execute_shell_command, NULL); + camel_filter_driver_set_play_sound_func (driver, session_play_sound, NULL); + camel_filter_driver_set_system_beep_func (driver, session_system_beep, NULL); + + if ((!strcmp (type, E_FILTER_SOURCE_INCOMING) || + !strcmp (type, E_FILTER_SOURCE_JUNKTEST)) + && camel_session_get_check_junk (session)) { + + /* implicit junk check as 1st rule */ + camel_filter_driver_add_rule ( + driver, "Junk check", "(junk-test)", + "(begin (set-system-flag \"junk\"))"); + } + + if (strcmp (type, E_FILTER_SOURCE_JUNKTEST) != 0) { + GString *fsearch, *faction; + + fsearch = g_string_new (""); + faction = g_string_new (""); + + if (!strcmp (type, E_FILTER_SOURCE_DEMAND)) + type = E_FILTER_SOURCE_INCOMING; + + /* add the user-defined rules next */ + while ((rule = e_rule_context_next_rule (fc, rule, type))) { + g_string_truncate (fsearch, 0); + g_string_truncate (faction, 0); + + /* skip disabled rules */ + if (!rule->enabled) + continue; + + e_filter_rule_build_code (rule, fsearch); + em_filter_rule_build_action ( + EM_FILTER_RULE (rule), faction); + camel_filter_driver_add_rule ( + driver, rule->name, + fsearch->str, faction->str); + } + + g_string_free (fsearch, TRUE); + g_string_free (faction, TRUE); + } + + g_object_unref (fc); + + g_object_unref (settings); + + return driver; +} + +static void +source_context_free (SourceContext *context) +{ + if (context->session != NULL) + g_object_unref (context->session); + + if (context->service != NULL) + g_object_unref (context->service); + + g_slice_free (SourceContext, context); +} + +static void +mail_ui_session_dispose (GObject *object) +{ + EMailUISessionPrivate *priv; + + priv = E_MAIL_UI_SESSION_GET_PRIVATE (object); + + if (priv->account_store != NULL) { + e_mail_account_store_clear (priv->account_store); + g_object_unref (priv->account_store); + priv->account_store = NULL; + } + + if (priv->label_store != NULL) { + g_object_unref (priv->label_store); + priv->label_store = NULL; + } + + + if (priv->vfolder_store != NULL) { + g_object_unref (priv->vfolder_store); + priv->vfolder_store = NULL; + } + + if (priv->account_list != NULL) { + g_signal_handler_disconnect ( + priv->account_list, + priv->account_changed_handler_id); + g_object_unref (priv->account_list); + priv->account_list = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_mail_ui_session_parent_class)->dispose (object); +} + +static void +mail_ui_session_add_vfolder_store (EMailUISession *uisession) +{ + CamelSession *camel_session; + CamelService *service; + GError *error = NULL; + + camel_session = CAMEL_SESSION (uisession); + + service = camel_session_add_service ( + camel_session, E_MAIL_SESSION_VFOLDER_UID, + "vfolder", CAMEL_PROVIDER_STORE, &error); + + if (error != NULL) { + g_critical ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + return; + } + + g_return_if_fail (CAMEL_IS_SERVICE (service)); + + camel_service_set_display_name (service, _("Search Folders")); + em_utils_connect_service_sync (service, NULL, NULL); + + /* XXX There's more configuration to do in vfolder_load_storage() + * but it requires an EMailBackend, which we don't have access + * to from here, so it has to be called from elsewhere. Kinda + * thinking about reworking that... */ + + uisession->priv->vfolder_store = g_object_ref (service); +} + +static void +mail_ui_session_account_changed_cb (EAccountList *account_list, + EAccount *account, + EMailSession *session) +{ + EMFolderTreeModel *folder_tree_model; + CamelService *service; + + service = camel_session_get_service ( + CAMEL_SESSION (session), account->uid); + + if (!CAMEL_IS_STORE (service)) + return; + + /* Update the display name of the corresponding CamelStore. + * EMailAccountStore listens for "notify" signals from each + * service so it will detect this and update the model. + * + * XXX If EAccount defined GObject properties we could just + * bind EAccount:name to CamelService:display-name and + * be done with it. Oh well. + */ + + camel_service_set_display_name (service, account->name); + + /* Remove the store from the folder tree model and, if the + * account is still enabled, re-add it. Easier than trying + * to update the model with the store in place. + * + * em_folder_tree_model_add_store() already knows which types + * of stores to disregard, so we don't have to deal with that + * here. */ + + folder_tree_model = em_folder_tree_model_get_default (); + + em_folder_tree_model_remove_store ( + folder_tree_model, CAMEL_STORE (service)); + + if (account->enabled) + em_folder_tree_model_add_store ( + folder_tree_model, CAMEL_STORE (service)); +} + +static gboolean +mail_ui_session_initialize_stores_idle (gpointer user_data) +{ + EMailUISession *session = user_data; + EMailAccountStore *account_store; + EAccount *account; + + g_return_val_if_fail (session != NULL, FALSE); + + account_store = e_mail_ui_session_get_account_store (session); + + /* Initialize which account is default. */ + account = e_get_default_account (); + if (account != NULL) { + CamelService *service; + + service = camel_session_get_service ( + CAMEL_SESSION (session), account->uid); + e_mail_account_store_set_default_service ( + account_store, service); + } + + return FALSE; +} + +static void +mail_ui_session_constructed (GObject *object) +{ + EMailUISessionPrivate *priv; + EMFolderTreeModel *folder_tree_model; + EMailSession *session; + EMailUISession *uisession; + EAccountList *account_list; + gulong handler_id; + + session = E_MAIL_SESSION (object); + uisession = E_MAIL_UI_SESSION(object); + uisession->priv = priv = E_MAIL_UI_SESSION_GET_PRIVATE (object); + + priv->account_store = e_mail_account_store_new (session); + + account_list = e_get_account_list (); + uisession->priv->account_list = g_object_ref (account_list); + + /* XXX Make sure the folder tree model is created before we + * add built-in CamelStores so it gets signals from the + * EMailAccountStore. + * + * XXX This is creating a circular reference. Perhaps the + * model should only hold a weak pointer to EMailSession? + * + * FIXME EMailSession should just own the default instance. + */ + folder_tree_model = em_folder_tree_model_get_default (); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_mail_ui_session_parent_class)->constructed (object); + + em_folder_tree_model_set_session (folder_tree_model, session); + + mail_ui_session_add_vfolder_store (uisession); + + g_idle_add (mail_ui_session_initialize_stores_idle, object); + + handler_id = g_signal_connect ( + account_list, "account-changed", + G_CALLBACK (mail_ui_session_account_changed_cb), session); + priv->account_changed_handler_id = handler_id; + +} + +static gint +mail_ui_session_alert_user (CamelSession *session, + CamelSessionAlertType type, + const gchar *prompt, + GSList *button_captions) +{ + struct _user_message_msg *m; + GCancellable *cancellable; + gint result = -1; + GSList *iter; + + m = mail_msg_new (&user_message_info); + m->ismain = mail_in_main_thread (); + m->type = type; + m->prompt = g_strdup (prompt); + m->done = e_flag_new (); + m->button_captions = g_slist_copy (button_captions); + + for (iter = m->button_captions; iter; iter = iter->next) + iter->data = g_strdup (iter->data); + + if (g_slist_length (button_captions) > 1) + mail_msg_ref (m); + + cancellable = m->base.cancellable; + + if (m->ismain) + user_message_exec (m, cancellable, &m->base.error); + else + mail_msg_main_loop_push (m); + + if (g_slist_length (button_captions) > 1) { + e_flag_wait (m->done); + result = m->result; + mail_msg_unref (m); + } else if (m->ismain) + mail_msg_unref (m); + + return result; +} + +static CamelFilterDriver * +mail_ui_session_get_filter_driver (CamelSession *session, + const gchar *type, + GError **error) +{ + return (CamelFilterDriver *) mail_call_main ( + MAIL_CALL_p_ppp, (MailMainFunc) main_get_filter_driver, + session, type, error); +} + +static void +mail_ui_session_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_ui_session_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACCOUNT_STORE: + g_value_set_object ( + value, + e_mail_ui_session_get_account_store ( + E_MAIL_UI_SESSION (object))); + return; + + case PROP_LABEL_STORE: + g_value_set_object ( + value, + e_mail_ui_session_get_label_store ( + E_MAIL_UI_SESSION (object))); + return; + + + case PROP_VFOLDER_STORE: + g_value_set_object ( + value, + e_mail_ui_session_get_vfolder_store ( + E_MAIL_UI_SESSION (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static gboolean +mail_ui_session_add_service_cb (SourceContext *context) +{ + EMailAccountStore *store; + + store = e_mail_ui_session_get_account_store (context->session); + e_mail_account_store_add_service (store, context->service); + + return FALSE; +} + +static CamelService * +mail_ui_session_add_service (CamelSession *session, + const gchar *uid, + const gchar *protocol, + CamelProviderType type, + GError **error) +{ + CamelService *service; + + /* Chain up to parent's constructed() method. */ + service = CAMEL_SESSION_CLASS (e_mail_ui_session_parent_class)-> + add_service (session, uid, protocol, type, error); + + /* Inform the EMailAccountStore of the new CamelService + * from an idle callback so the service has a chance to + * fully initialize first. */ + if (CAMEL_IS_STORE (service)) { + SourceContext *context; + + context = g_slice_new0 (SourceContext); + context->session = g_object_ref (session); + context->service = g_object_ref (service); + + g_idle_add_full ( + G_PRIORITY_DEFAULT_IDLE, + (GSourceFunc) mail_ui_session_add_service_cb, + context, (GDestroyNotify) source_context_free); + } + + return service; +} + +static void +e_mail_ui_session_class_init (EMailUISessionClass *class) +{ + GObjectClass *object_class; + CamelSessionClass *session_class; + + g_type_class_add_private (class, sizeof (EMailUISessionPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = mail_ui_session_set_property; + object_class->get_property = mail_ui_session_get_property; + object_class->dispose = mail_ui_session_dispose; + object_class->constructed = mail_ui_session_constructed; + + session_class = CAMEL_SESSION_CLASS (class); + session_class->alert_user = mail_ui_session_alert_user; + session_class->get_filter_driver = mail_ui_session_get_filter_driver; + session_class->add_service = mail_ui_session_add_service; + + g_object_class_install_property ( + object_class, + PROP_VFOLDER_STORE, + g_param_spec_object ( + "vfolder-store", + "Search Folder Store", + "Built-in search folder store", + CAMEL_TYPE_STORE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_LABEL_STORE, + g_param_spec_object ( + "label-store", + "Label Store", + "Mail label store", + E_TYPE_MAIL_LABEL_LIST_STORE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + signals[ACTIVITY_ADDED] = g_signal_new ( + "activity-added", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMailUISessionClass, activity_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_ACTIVITY); +} + +static void +e_mail_ui_session_init (EMailUISession *session) +{ + session->priv = E_MAIL_UI_SESSION_GET_PRIVATE (session); + session->priv->label_store = e_mail_label_list_store_new (); +} + +EMailSession * +e_mail_ui_session_new (void) +{ + const gchar *user_data_dir; + const gchar *user_cache_dir; + + user_data_dir = mail_session_get_data_dir (); + user_cache_dir = mail_session_get_cache_dir (); + + return g_object_new ( + E_TYPE_MAIL_UI_SESSION, + "user-data-dir", user_data_dir, + "user-cache-dir", user_cache_dir, + NULL); +} + + +EMailAccountStore * +e_mail_ui_session_get_account_store (EMailUISession *session) +{ + g_return_val_if_fail (E_IS_MAIL_UI_SESSION (session), NULL); + + return session->priv->account_store; +} + +CamelStore * +e_mail_ui_session_get_vfolder_store (EMailUISession *session) +{ + g_return_val_if_fail (E_IS_MAIL_UI_SESSION (session), NULL); + + return session->priv->vfolder_store; +} + +void +e_mail_ui_session_add_activity (EMailUISession *session, + EActivity *activity) +{ + g_return_if_fail (E_IS_MAIL_UI_SESSION (session)); + g_return_if_fail (E_IS_ACTIVITY (activity)); + + g_signal_emit (session, signals[ACTIVITY_ADDED], 0, activity); +} + +EMailLabelListStore * +e_mail_ui_session_get_label_store (EMailUISession *session) +{ + g_return_val_if_fail (E_IS_MAIL_UI_SESSION (session), NULL); + + return session->priv->label_store; +} + diff --git a/mail/e-mail-ui-session.h b/mail/e-mail-ui-session.h new file mode 100644 index 0000000000..1a36487757 --- /dev/null +++ b/mail/e-mail-ui-session.h @@ -0,0 +1,93 @@ +/* + * e-mail-session.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Jeffrey Stedfast <fejj@ximian.com> + * Srinivasa Ragavan <sragavan@gnome.org> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MAIL_UI_SESSION_H +#define E_MAIL_UI_SESSION_H + +#include <camel/camel.h> +#include <libemail-engine/e-mail-enums.h> +#include <libemail-engine/e-mail-session.h> +#include <libemail-engine/mail-folder-cache.h> +#include <mail/e-mail-account-store.h> +#include <e-util/e-activity.h> + +#include <mail/e-mail-account-store.h> +#include <mail/e-mail-label-list-store.h> + +/* Standard GObject macros */ +#define E_TYPE_MAIL_UI_SESSION \ + (e_mail_ui_session_get_type ()) +#define E_MAIL_UI_SESSION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MAIL_UI_SESSION, EMailUISession)) +#define E_MAIL_UI_SESSION_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MAIL_UI_SESSION, EMailUISessionClass)) +#define E_IS_MAIL_UI_SESSION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MAIL_UI_SESSION)) +#define E_IS_MAIL_UI_SESSION_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MAIL_UI_SESSION)) +#define E_MAIL_UI_SESSION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MAIL_UI_SESSION, EMailUISessionClass)) + +G_BEGIN_DECLS + +typedef struct _EMailUISession EMailUISession; +typedef struct _EMailUISessionClass EMailUISessionClass; +typedef struct _EMailUISessionPrivate EMailUISessionPrivate; + +struct _EMailUISession { + EMailSession parent; + EMailUISessionPrivate *priv; +}; + +struct _EMailUISessionClass { + EMailSessionClass parent_class; + + void (*activity_added) (EMailUISession *session, + EActivity *activity); + +}; + +GType e_mail_ui_session_get_type (void); +EMailSession * e_mail_ui_session_new (void); +CamelStore * e_mail_ui_session_get_vfolder_store + (EMailUISession *session); +EMailAccountStore * + e_mail_ui_session_get_account_store + (EMailUISession *session); +void e_mail_ui_session_add_activity (EMailUISession *session, + EActivity *activity); +EMailLabelListStore * + e_mail_ui_session_get_label_store + (EMailUISession *session); + +G_END_DECLS + +#endif /* E_MAIL_UI_SESSION_H */ diff --git a/mail/e-mail.h b/mail/e-mail.h index 02c169cd10..3b34765784 100644 --- a/mail/e-mail.h +++ b/mail/e-mail.h @@ -26,7 +26,6 @@ #include <mail/e-mail-enums.h> #include <mail/e-mail-enumtypes.h> #include <mail/e-mail-folder-pane.h> -#include <mail/e-mail-folder-utils.h> #include <mail/e-mail-label-action.h> #include <mail/e-mail-label-dialog.h> #include <mail/e-mail-label-list-store.h> @@ -38,10 +37,7 @@ #include <mail/e-mail-paned-view.h> #include <mail/e-mail-reader.h> #include <mail/e-mail-reader-utils.h> -#include <mail/e-mail-session.h> -#include <mail/e-mail-session-utils.h> #include <mail/e-mail-sidebar.h> -#include <mail/e-mail-store-utils.h> #include <mail/e-mail-tag-editor.h> #include <mail/e-mail-view.h> diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c index 1fc17abc5e..8b7f1600d6 100644 --- a/mail/em-account-editor.c +++ b/mail/em-account-editor.c @@ -45,32 +45,38 @@ #include <libedataserverui/e-passwords.h> -#include "shell/e-shell.h" -#include "e-util/e-util.h" -#include "e-util/e-alert-dialog.h" -#include "e-util/e-account-utils.h" -#include "e-util/e-dialog-utils.h" -#include "e-util/e-signature-list.h" -#include "e-util/e-signature-utils.h" -#include "e-util/e-util-private.h" -#include "widgets/misc/e-auth-combo-box.h" -#include "widgets/misc/e-signature-editor.h" -#include "widgets/misc/e-port-entry.h" +#include <shell/e-shell.h> +#include <e-util/e-util.h> +#include <e-util/e-alert-dialog.h> +#include <e-util/e-dialog-utils.h> +#include <e-util/e-util-private.h> + +#include <libemail-utils/e-account-utils.h> +#include <libemail-utils/e-signature-list.h> +#include <libemail-utils/e-signature-utils.h> +#include <libemail-utils/mail-mt.h> + +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/mail-ops.h> + +#include <widgets/misc/e-auth-combo-box.h> +#include <widgets/misc/e-signature-editor.h> +#include <widgets/misc/e-port-entry.h> + +#include "e-mail-account-store.h" #include "e-mail-backend.h" -#include "e-mail-folder-utils.h" #include "e-mail-junk-options.h" +#include "e-mail-ui-session.h" +#include "em-account-editor.h" #include "em-config.h" #include "em-folder-selection-button.h" -#include "em-account-editor.h" -#include "mail-send-recv.h" #include "em-utils.h" -#include "mail-ops.h" -#include "mail-mt.h" #include "mail-guess-servers.h" +#include "mail-send-recv.h" #if defined (HAVE_NSS) && defined (ENABLE_SMIME) -#include "smime/gui/e-cert-selector.h" +#include <smime/gui/e-cert-selector.h> #endif #define EM_ACCOUNT_EDITOR_GET_PRIVATE(obj) \ @@ -5501,7 +5507,7 @@ emae_commit (EConfig *ec, service = camel_session_get_service ( CAMEL_SESSION (session), account->uid); - store = e_mail_session_get_account_store (session); + store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION(session)); e_mail_account_store_set_default_service (store, service); } diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c index dc8d89725a..4d8e37d9a4 100644 --- a/mail/em-composer-utils.c +++ b/mail/em-composer-utils.c @@ -32,32 +32,35 @@ #include <libedataserver/e-data-server-util.h> -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-tools.h" -#include "mail-send-recv.h" +#include <e-util/e-alert-dialog.h> +#include <e-util/e-alert-sink.h> +#include <e-util/e-util.h> + +#include <libemail-utils/e-account-utils.h> +#include <libemail-utils/mail-mt.h> + +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/e-mail-session.h> +#include <libemail-engine/e-mail-session-utils.h> +#include <libemail-engine/mail-ops.h> +#include <libemail-engine/mail-tools.h> -#include "e-util/e-account-utils.h" -#include "e-util/e-alert-dialog.h" -#include "e-util/e-alert-sink.h" -#include "e-util/e-util.h" +#include <shell/e-shell.h> -#include "shell/e-shell.h" +#include <composer/e-msg-composer.h> +#include <composer/e-composer-actions.h> +#include <composer/e-composer-post-header.h> -#include "e-mail-folder-utils.h" -#include "e-mail-session.h" -#include "e-mail-session-utils.h" #include "em-utils.h" #include "em-composer-utils.h" -#include "composer/e-msg-composer.h" -#include "composer/e-composer-actions.h" -#include "composer/e-composer-post-header.h" #include "em-folder-selector.h" #include "em-folder-tree.h" #include "em-format-html.h" #include "em-format-html-print.h" #include "em-format-quote.h" #include "em-event.h" +#include "mail-send-recv.h" + #ifdef G_OS_WIN32 #ifdef gmtime_r diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h index 093001dfd0..5b3d3a469a 100644 --- a/mail/em-composer-utils.h +++ b/mail/em-composer-utils.h @@ -26,9 +26,9 @@ #include <em-format/em-format.h> #include <mail/e-mail-backend.h> -#include <mail/e-mail-enums.h> #include <mail/e-mail-reader.h> #include <composer/e-msg-composer.h> +#include <libemail-engine/e-mail-enums.h> G_BEGIN_DECLS diff --git a/mail/em-filter-context.h b/mail/em-filter-context.h index 3545bf16eb..1f8889d94c 100644 --- a/mail/em-filter-context.h +++ b/mail/em-filter-context.h @@ -25,8 +25,8 @@ #ifndef EM_FILTER_CONTEXT_H #define EM_FILTER_CONTEXT_H -#include <mail/e-mail-session.h> #include <filter/e-rule-context.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_FILTER_CONTEXT \ diff --git a/mail/em-filter-folder-element.h b/mail/em-filter-folder-element.h index f71b4c128b..f5a1741795 100644 --- a/mail/em-filter-folder-element.h +++ b/mail/em-filter-folder-element.h @@ -25,8 +25,8 @@ #ifndef EM_FILTER_FOLDER_ELEMENT_H #define EM_FILTER_FOLDER_ELEMENT_H -#include <mail/e-mail-session.h> #include <filter/e-filter-element.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_FILTER_FOLDER_ELEMENT \ diff --git a/mail/em-filter-source-element.c b/mail/em-filter-source-element.c index a8e51e2827..5848f938db 100644 --- a/mail/em-filter-source-element.c +++ b/mail/em-filter-source-element.c @@ -32,8 +32,8 @@ #include <gtk/gtk.h> #include <camel/camel.h> -#include <e-util/e-account-utils.h> #include <filter/e-filter-part.h> +#include <libemail-utils/e-account-utils.h> #define EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ diff --git a/mail/em-filter-source-element.h b/mail/em-filter-source-element.h index 41c3f3f8fc..061a487fc8 100644 --- a/mail/em-filter-source-element.h +++ b/mail/em-filter-source-element.h @@ -24,8 +24,8 @@ #ifndef EM_FILTER_SOURCE_ELEMENT_H #define EM_FILTER_SOURCE_ELEMENT_H -#include <mail/e-mail-session.h> #include <filter/e-filter-element.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_FILTER_SOURCE_ELEMENT \ diff --git a/mail/em-folder-properties.c b/mail/em-folder-properties.c index 75ccf5304b..2abb1f366d 100644 --- a/mail/em-folder-properties.c +++ b/mail/em-folder-properties.c @@ -24,18 +24,20 @@ #include <config.h> #endif +#include "em-folder-properties.h" + #include <string.h> #include <gtk/gtk.h> #include <glib/gi18n.h> -#include "em-folder-properties.h" -#include "em-config.h" +#include <libemail-utils/mail-mt.h> +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/mail-ops.h> #include "e-mail-backend.h" -#include "e-mail-folder-utils.h" -#include "mail-ops.h" -#include "mail-mt.h" +#include "e-mail-ui-session.h" +#include "em-config.h" #include "mail-vfolder.h" typedef struct _AsyncContext AsyncContext; @@ -498,8 +500,8 @@ em_folder_properties_show (CamelStore *store, cancellable = camel_operation_new (); e_activity_set_cancellable (context->activity, cancellable); - e_mail_session_add_activity ( - E_MAIL_SESSION (session), context->activity); + e_mail_ui_session_add_activity ( + E_MAIL_UI_SESSION (session), context->activity); camel_store_get_folder ( store, folder_name, 0, G_PRIORITY_DEFAULT, cancellable, diff --git a/mail/em-folder-properties.h b/mail/em-folder-properties.h index 704e43b6d3..2d829af17f 100644 --- a/mail/em-folder-properties.h +++ b/mail/em-folder-properties.h @@ -25,7 +25,8 @@ #define __EM_FOLDER_PROPERTIES_H__ #include <camel/camel.h> -#include <mail/e-mail-session.h> +#include <e-util/e-alert-sink.h> +#include <libemail-engine/e-mail-session.h> G_BEGIN_DECLS diff --git a/mail/em-folder-selection-button.c b/mail/em-folder-selection-button.c index 6e40234444..fb4e27d83b 100644 --- a/mail/em-folder-selection-button.c +++ b/mail/em-folder-selection-button.c @@ -28,7 +28,8 @@ #include <glib/gi18n.h> #include <e-util/e-util.h> -#include "e-mail-folder-utils.h" +#include <libemail-engine/e-mail-folder-utils.h> + #include "em-folder-tree.h" #include "em-folder-selector.h" #include "em-utils.h" diff --git a/mail/em-folder-selection-button.h b/mail/em-folder-selection-button.h index 6e646e3af0..945f1dab0b 100644 --- a/mail/em-folder-selection-button.h +++ b/mail/em-folder-selection-button.h @@ -25,7 +25,7 @@ #define EM_FOLDER_SELECTION_BUTTON_H #include <gtk/gtk.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_FOLDER_SELECTION_BUTTON \ diff --git a/mail/em-folder-selector.c b/mail/em-folder-selector.c index 2f5b58274f..18172cb7a5 100644 --- a/mail/em-folder-selector.c +++ b/mail/em-folder-selector.c @@ -29,7 +29,8 @@ #include <glib/gi18n.h> #include <e-util/e-util.h> -#include "e-mail-session.h" +#include <libemail-engine/e-mail-session.h> + #include "em-folder-tree.h" #include "em-folder-selector.h" #include "em-folder-utils.h" diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c index c346435f80..7ee385c892 100644 --- a/mail/em-folder-tree-model.c +++ b/mail/em-folder-tree-model.c @@ -36,22 +36,22 @@ #include <glib/gi18n.h> -#include "e-util/e-util.h" -#include "e-util/e-account-utils.h" +#include <e-util/e-util.h> +#include <shell/e-shell.h> -#include "mail-tools.h" -#include "mail-mt.h" -#include "mail-ops.h" +#include <libemail-utils/e-account-utils.h> +#include <libemail-utils/mail-mt.h> -/* sigh, these 2 only needed for outbox total count checking - a mess */ -#include "mail-folder-cache.h" +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/mail-folder-cache.h> +#include <libemail-engine/mail-tools.h> +#include <libemail-engine/mail-ops.h> -#include "em-utils.h" -#include "em-folder-utils.h" -#include "em-event.h" - -#include "e-mail-folder-utils.h" -#include "shell/e-shell.h" +#include <e-mail-account-store.h> +#include <e-mail-ui-session.h> +#include <em-utils.h> +#include <em-folder-utils.h> +#include <em-event.h> #define EM_FOLDER_TREE_MODEL_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -573,7 +573,7 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model, MailFolderCache *folder_cache; folder_cache = e_mail_session_get_folder_cache (session); - account_store = e_mail_session_get_account_store (session); + account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session)); /* Keep our own reference since we connect to its signals. */ g_warn_if_fail (model->priv->account_store == NULL); diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h index 1bf5483367..b4acb3dce6 100644 --- a/mail/em-folder-tree-model.h +++ b/mail/em-folder-tree-model.h @@ -26,7 +26,7 @@ #include <gtk/gtk.h> #include <camel/camel.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_FOLDER_TREE_MODEL \ diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c index a1e4142cf6..46a8c108e8 100644 --- a/mail/em-folder-tree.c +++ b/mail/em-folder-tree.c @@ -48,11 +48,11 @@ #include "em-vfolder-rule.h" -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-tools.h" -#include "mail-send-recv.h" -#include "mail-vfolder.h" +#include "libemail-utils/mail-mt.h" +#include "libemail-engine/e-mail-folder-utils.h" +#include "libemail-engine/e-mail-session.h" +#include "libemail-engine/mail-ops.h" +#include "libemail-engine/mail-tools.h" #include "em-utils.h" #include "em-folder-tree.h" @@ -60,9 +60,10 @@ #include "em-folder-selector.h" #include "em-folder-properties.h" #include "em-event.h" +#include "mail-send-recv.h" +#include "mail-vfolder.h" -#include "e-mail-folder-utils.h" -#include "e-mail-session.h" +#include "e-mail-ui-session.h" #define d(x) @@ -1822,7 +1823,8 @@ em_folder_tree_new_activity (EMFolderTree *folder_tree) g_object_unref (cancellable); session = em_folder_tree_get_session (folder_tree); - e_mail_session_add_activity (session, activity); + e_mail_ui_session_add_activity ( + E_MAIL_UI_SESSION (session), activity); return activity; } @@ -2036,7 +2038,7 @@ folder_tree_drop_folder (struct _DragDataReceivedAsync *m) d(printf(" * Drop folder '%s' onto '%s'\n", data, m->full_name)); - cancellable = e_activity_get_cancellable (m->base.activity); + cancellable = m->base.cancellable; folder = e_mail_session_uri_to_folder_sync ( m->session, (gchar *) data, 0, diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h index 6a60f2bc31..1e39ebab18 100644 --- a/mail/em-folder-tree.h +++ b/mail/em-folder-tree.h @@ -25,9 +25,10 @@ #define EM_FOLDER_TREE_H #include <gtk/gtk.h> +#include <e-util/e-activity.h> #include <e-util/e-alert-sink.h> -#include <mail/e-mail-session.h> #include <mail/em-folder-tree-model.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_FOLDER_TREE \ diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c index 825e6af7ca..1350df7c7b 100644 --- a/mail/em-folder-utils.c +++ b/mail/em-folder-utils.c @@ -45,22 +45,23 @@ #include "em-vfolder-rule.h" -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-tools.h" -#include "mail-vfolder.h" -#include "mail-folder-cache.h" - +#include "libemail-utils/mail-mt.h" +#include "libemail-engine/e-mail-folder-utils.h" +#include "libemail-engine/e-mail-session.h" +#include "libemail-engine/e-mail-store-utils.h" +#include "libemail-engine/e-mail-utils.h" +#include "libemail-engine/mail-ops.h" +#include "libemail-engine/mail-tools.h" +#include "libemail-engine/mail-folder-cache.h" + +#include "e-mail-ui-session.h" #include "em-utils.h" #include "em-folder-tree.h" #include "em-folder-tree-model.h" #include "em-folder-utils.h" #include "em-folder-selector.h" #include "em-folder-properties.h" - -#include "e-mail-folder-utils.h" -#include "e-mail-session.h" -#include "e-mail-store-utils.h" +#include "mail-vfolder.h" #define d(x) @@ -567,7 +568,7 @@ em_folder_utils_create_folder (GtkWindow *parent, model = em_folder_tree_model_new (); em_folder_tree_model_set_session (model, session); - account_store = e_mail_session_get_account_store (session); + account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session)); e_mail_account_store_queue_enabled_services (account_store, &queue); while (!g_queue_is_empty (&queue)) { diff --git a/mail/em-folder-utils.h b/mail/em-folder-utils.h index 9211cacd90..db3853042c 100644 --- a/mail/em-folder-utils.h +++ b/mail/em-folder-utils.h @@ -26,7 +26,7 @@ #include <gtk/gtk.h> #include <camel/camel.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> #include <mail/em-folder-tree.h> G_BEGIN_DECLS diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c index a600c5a48a..04216900bc 100644 --- a/mail/em-format-html-print.c +++ b/mail/em-format-html-print.c @@ -30,11 +30,13 @@ #include <gtk/gtk.h> #include <gtkhtml/gtkhtml.h> -#include "mail-ops.h" -#include "mail-mt.h" -#include "em-format-html-print.h" #include <e-util/e-print.h> +#include <libemail-utils/mail-mt.h> +#include <libemail-engine/mail-ops.h> + +#include "em-format-html-print.h" + G_DEFINE_TYPE ( EMFormatHTMLPrint, em_format_html_print, diff --git a/mail/em-format-html.c b/mail/em-format-html.c index 706de09248..a720d2cc9f 100644 --- a/mail/em-format-html.c +++ b/mail/em-format-html.c @@ -57,12 +57,15 @@ #include <glib/gi18n.h> -#include "e-mail-enumtypes.h" +#include <libemail-utils/mail-mt.h> + +#include <libemail-engine/e-mail-enumtypes.h> +#include <libemail-engine/e-mail-utils.h> +#include <libemail-engine/mail-config.h> + #include "em-format-html.h" #include "em-html-stream.h" #include "em-utils.h" -#include "mail-config.h" -#include "mail-mt.h" #define EM_FORMAT_HTML_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ diff --git a/mail/em-format-html.h b/mail/em-format-html.h index 7ded2e82f9..954a54ea0c 100644 --- a/mail/em-format-html.h +++ b/mail/em-format-html.h @@ -29,9 +29,9 @@ #define EM_FORMAT_HTML_H #include <em-format/em-format.h> -#include <mail/e-mail-enums.h> #include <misc/e-web-view.h> #include <gtkhtml/gtkhtml-embedded.h> +#include <libemail-engine/e-mail-enums.h> /* Standard GObject macros */ #define EM_TYPE_FORMAT_HTML \ diff --git a/mail/em-subscription-editor.c b/mail/em-subscription-editor.c index 15f7a3be32..ceefe7ca49 100644 --- a/mail/em-subscription-editor.c +++ b/mail/em-subscription-editor.c @@ -25,12 +25,12 @@ #include <string.h> #include <glib/gi18n-lib.h> -#include "mail-tools.h" -#include "mail-ops.h" -#include "mail-mt.h" +#include <libemail-utils/e-account-utils.h> +#include <libemail-utils/mail-mt.h> +#include <libemail-engine/mail-tools.h> +#include <libemail-engine/mail-ops.h> #include <e-util/e-util.h> -#include <e-util/e-account-utils.h> #include <e-util/e-util-private.h> #include "em-folder-utils.h" diff --git a/mail/em-subscription-editor.h b/mail/em-subscription-editor.h index c6f6c258f0..b9abedb166 100644 --- a/mail/em-subscription-editor.h +++ b/mail/em-subscription-editor.h @@ -21,7 +21,7 @@ #include <gtk/gtk.h> #include <camel/camel.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_SUBSCRIPTION_EDITOR \ diff --git a/mail/em-sync-stream.c b/mail/em-sync-stream.c index 06f96ecd83..841d890e41 100644 --- a/mail/em-sync-stream.c +++ b/mail/em-sync-stream.c @@ -32,7 +32,7 @@ #include <glib/gi18n-lib.h> #include <libedataserver/e-flag.h> -#include "mail-mt.h" +#include <libemail-utils/mail-mt.h> enum _write_msg_t { EMSS_WRITE, diff --git a/mail/em-utils.c b/mail/em-utils.c index 416588cfbb..247b47d967 100644 --- a/mail/em-utils.c +++ b/mail/em-utils.c @@ -41,38 +41,40 @@ #undef interface #endif -#include <libebook/e-book-client.h> -#include <libebook/e-book-query.h> - #include "em-filter-editor.h" #include <glib/gi18n.h> #include <gio/gio.h> -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-tools.h" -#include "e-mail-tag-editor.h" - +#include <libebook/e-book-client.h> +#include <libebook/e-book-query.h> #include <libedataserver/e-data-server-util.h> #include <libedataserver/e-flag.h> #include <libedataserver/e-proxy.h> -#include "e-util/e-util.h" -#include "e-util/e-util-private.h" -#include "e-util/e-mktemp.h" -#include "e-util/e-account-utils.h" -#include "e-util/e-dialog-utils.h" -#include "e-util/e-alert-dialog.h" -#include "shell/e-shell.h" -#include "widgets/misc/e-attachment.h" -#include "em-utils.h" +#include <e-util/e-util.h> +#include <e-util/e-util-private.h> +#include <e-util/e-mktemp.h> +#include <e-util/e-dialog-utils.h> +#include <e-util/e-alert-dialog.h> + +#include <shell/e-shell.h> +#include <widgets/misc/e-attachment.h> + +#include <libemail-utils/e-account-utils.h> +#include <libemail-utils/mail-mt.h> + +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/e-mail-session.h> +#include <libemail-engine/mail-ops.h> +#include <libemail-engine/mail-tools.h> + +#include "e-mail-tag-editor.h" #include "em-composer-utils.h" #include "em-format-quote.h" #include "em-format-html-print.h" -#include "e-mail-folder-utils.h" -#include "e-mail-session.h" +#include "em-utils.h" /* XXX This is a dirty hack on a dirty hack. We really need * to rework or get rid of the functions that use this. */ @@ -1107,202 +1109,6 @@ em_utils_selection_get_urilist (GtkSelectionData *selection_data, g_strfreev (uris); } -/** - * em_utils_folder_is_templates: - * @folder: a #CamelFolder - * - * Decides if @folder is a Templates folder. - * - * Returns %TRUE if this is a Templates folder or %FALSE otherwise. - **/ - -gboolean -em_utils_folder_is_templates (CamelFolder *folder) -{ - CamelFolder *local_templates_folder; - CamelSession *session; - CamelStore *store; - EAccountList *account_list; - EIterator *iterator; - gchar *folder_uri; - gboolean is_templates = FALSE; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - - store = camel_folder_get_parent_store (folder); - session = camel_service_get_session (CAMEL_SERVICE (store)); - - local_templates_folder = - e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_TEMPLATES); - - if (folder == local_templates_folder) - return TRUE; - - folder_uri = e_mail_folder_uri_from_folder (folder); - - account_list = e_get_account_list (); - iterator = e_list_get_iterator (E_LIST (account_list)); - - while (!is_templates && e_iterator_is_valid (iterator)) { - EAccount *account; - - /* XXX EIterator misuses const. */ - account = (EAccount *) e_iterator_get (iterator); - - if (account->templates_folder_uri != NULL) - is_templates = e_mail_folder_uri_equal ( - session, folder_uri, - account->templates_folder_uri); - - e_iterator_next (iterator); - } - - g_object_unref (iterator); - g_free (folder_uri); - - return is_templates; -} - -/** - * em_utils_folder_is_drafts: - * @folder: a #CamelFolder - * - * Decides if @folder is a Drafts folder. - * - * Returns %TRUE if this is a Drafts folder or %FALSE otherwise. - **/ -gboolean -em_utils_folder_is_drafts (CamelFolder *folder) -{ - CamelFolder *local_drafts_folder; - CamelSession *session; - CamelStore *store; - EAccountList *account_list; - EIterator *iterator; - gchar *folder_uri; - gboolean is_drafts = FALSE; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - - store = camel_folder_get_parent_store (folder); - session = camel_service_get_session (CAMEL_SERVICE (store)); - - local_drafts_folder = - e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS); - - if (folder == local_drafts_folder) - return TRUE; - - folder_uri = e_mail_folder_uri_from_folder (folder); - - account_list = e_get_account_list (); - iterator = e_list_get_iterator (E_LIST (account_list)); - - while (!is_drafts && e_iterator_is_valid (iterator)) { - EAccount *account; - - /* XXX EIterator misuses const. */ - account = (EAccount *) e_iterator_get (iterator); - - if (account->drafts_folder_uri != NULL) - is_drafts = e_mail_folder_uri_equal ( - session, folder_uri, - account->drafts_folder_uri); - - e_iterator_next (iterator); - } - - g_object_unref (iterator); - g_free (folder_uri); - - return is_drafts; -} - -/** - * em_utils_folder_is_sent: - * @folder: a #CamelFolder - * - * Decides if @folder is a Sent folder. - * - * Returns %TRUE if this is a Sent folder or %FALSE otherwise. - **/ -gboolean -em_utils_folder_is_sent (CamelFolder *folder) -{ - CamelFolder *local_sent_folder; - CamelSession *session; - CamelStore *store; - EAccountList *account_list; - EIterator *iterator; - gchar *folder_uri; - gboolean is_sent = FALSE; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - - store = camel_folder_get_parent_store (folder); - session = camel_service_get_session (CAMEL_SERVICE (store)); - - local_sent_folder = - e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_SENT); - - if (folder == local_sent_folder) - return TRUE; - - folder_uri = e_mail_folder_uri_from_folder (folder); - - account_list = e_get_account_list (); - iterator = e_list_get_iterator (E_LIST (account_list)); - - while (!is_sent && e_iterator_is_valid (iterator)) { - EAccount *account; - - /* XXX EIterator misuses const. */ - account = (EAccount *) e_iterator_get (iterator); - - if (account->sent_folder_uri != NULL) - is_sent = e_mail_folder_uri_equal ( - session, folder_uri, - account->sent_folder_uri); - - e_iterator_next (iterator); - } - - g_object_unref (iterator); - g_free (folder_uri); - - return is_sent; -} - -/** - * em_utils_folder_is_outbox: - * @folder: a #CamelFolder - * - * Decides if @folder is an Outbox folder. - * - * Returns %TRUE if this is an Outbox folder or %FALSE otherwise. - **/ -gboolean -em_utils_folder_is_outbox (CamelFolder *folder) -{ - CamelStore *store; - CamelSession *session; - CamelFolder *local_outbox_folder; - - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); - - store = camel_folder_get_parent_store (folder); - session = camel_service_get_session (CAMEL_SERVICE (store)); - - local_outbox_folder = - e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX); - - return (folder == local_outbox_folder); -} - /* ********************************************************************** */ static EProxy *emu_proxy = NULL; static GStaticMutex emu_proxy_lock = G_STATIC_MUTEX_INIT; @@ -1454,578 +1260,6 @@ em_utils_empty_trash (GtkWidget *parent, /* ********************************************************************** */ -/* runs sync, in main thread */ -static gpointer -emu_addr_setup (gpointer user_data) -{ - GError *err = NULL; - ESourceList **psource_list = user_data; - - if (!e_book_client_get_sources (psource_list, &err)) - g_error_free (err); - - return NULL; -} - -static void -emu_addr_cancel_stop (gpointer data) -{ - gboolean *stop = data; - - g_return_if_fail (stop != NULL); - - *stop = TRUE; -} - -static void -emu_addr_cancel_cancellable (gpointer data) -{ - GCancellable *cancellable = data; - - g_return_if_fail (cancellable != NULL); - - g_cancellable_cancel (cancellable); -} - -struct TryOpenEBookStruct { - GError **error; - EFlag *flag; - gboolean result; -}; - -static void -try_open_book_client_cb (GObject *source_object, - GAsyncResult *result, - gpointer closure) -{ - EBookClient *book_client = E_BOOK_CLIENT (source_object); - struct TryOpenEBookStruct *data = (struct TryOpenEBookStruct *) closure; - GError *error = NULL; - - if (!data) - return; - - e_client_open_finish (E_CLIENT (book_client), result, &error); - - data->result = error == NULL; - - if (!data->result) { - g_clear_error (data->error); - g_propagate_error (data->error, error); - } - - e_flag_set (data->flag); -} - -/* - * try_open_book_client: - * Tries to open address book asynchronously, but acts as synchronous. - * The advantage is it checks periodically whether the camel_operation - * has been canceled or not, and if so, then stops immediately, with - * result FALSE. Otherwise returns same as e_client_open() - */ -static gboolean -try_open_book_client (EBookClient *book_client, - gboolean only_if_exists, - GCancellable *cancellable, - GError **error) -{ - struct TryOpenEBookStruct data; - gboolean canceled = FALSE; - EFlag *flag = e_flag_new (); - - data.error = error; - data.flag = flag; - data.result = FALSE; - - e_client_open ( - E_CLIENT (book_client), only_if_exists, - cancellable, try_open_book_client_cb, &data); - - while (canceled = g_cancellable_is_cancelled (cancellable), - !canceled && !e_flag_is_set (flag)) { - GTimeVal wait; - - g_get_current_time (&wait); - g_time_val_add (&wait, 250000); /* waits 250ms */ - - e_flag_timed_wait (flag, &wait); - } - - if (canceled) { - g_cancellable_cancel (cancellable); - - g_clear_error (error); - g_propagate_error ( - error, e_client_error_create ( - E_CLIENT_ERROR_CANCELLED, NULL)); - } - - e_flag_wait (flag); - e_flag_free (flag); - - return data.result && (!error || !*error); -} - -#define NOT_FOUND_BOOK (GINT_TO_POINTER (1)) - -G_LOCK_DEFINE_STATIC (contact_cache); - -/* key is lowercased contact email; value is EBook pointer - * (just for comparison) where it comes from */ -static GHashTable *contact_cache = NULL; - -/* key is source ID; value is pointer to EBook */ -static GHashTable *emu_books_hash = NULL; - -/* key is source ID; value is same pointer as key; this is hash of - * broken books, which failed to open for some reason */ -static GHashTable *emu_broken_books_hash = NULL; - -static ESourceList *emu_books_source_list = NULL; - -static gboolean -search_address_in_addressbooks (const gchar *address, - gboolean local_only, - gboolean (*check_contact) (EContact *contact, - gpointer user_data), - gpointer user_data) -{ - gboolean found = FALSE, stop = FALSE, found_any = FALSE; - gchar *lowercase_addr; - gpointer ptr; - EBookQuery *book_query; - gchar *query; - GSList *s, *g, *addr_sources = NULL; - GHook *hook_cancellable; - GCancellable *cancellable; - - if (!address || !*address) - return FALSE; - - G_LOCK (contact_cache); - - if (!emu_books_source_list) { - mail_call_main ( - MAIL_CALL_p_p, (MailMainFunc) - emu_addr_setup, &emu_books_source_list); - emu_books_hash = g_hash_table_new_full ( - g_str_hash, g_str_equal, g_free, g_object_unref); - emu_broken_books_hash = g_hash_table_new_full ( - g_str_hash, g_str_equal, g_free, NULL); - contact_cache = g_hash_table_new_full ( - g_str_hash, g_str_equal, g_free, NULL); - } - - if (!emu_books_source_list) { - G_UNLOCK (contact_cache); - return FALSE; - } - - lowercase_addr = g_utf8_strdown (address, -1); - ptr = g_hash_table_lookup (contact_cache, lowercase_addr); - if (ptr != NULL && (check_contact == NULL || ptr == NOT_FOUND_BOOK)) { - g_free (lowercase_addr); - G_UNLOCK (contact_cache); - return ptr != NOT_FOUND_BOOK; - } - - book_query = e_book_query_field_test (E_CONTACT_EMAIL, E_BOOK_QUERY_IS, address); - query = e_book_query_to_string (book_query); - e_book_query_unref (book_query); - - for (g = e_source_list_peek_groups (emu_books_source_list); - g; g = g_slist_next (g)) { - ESourceGroup *group = g->data; - - if (!group) - continue; - - if (local_only && !(e_source_group_peek_base_uri (group) && - g_str_has_prefix ( - e_source_group_peek_base_uri (group), "local:"))) - continue; - - for (s = e_source_group_peek_sources (group); s; s = g_slist_next (s)) { - ESource *source = s->data; - const gchar *completion = e_source_get_property (source, "completion"); - - if (completion && g_ascii_strcasecmp (completion, "true") == 0) { - addr_sources = g_slist_prepend (addr_sources, g_object_ref (source)); - } - } - } - - cancellable = g_cancellable_new (); - hook_cancellable = mail_cancel_hook_add (emu_addr_cancel_cancellable, cancellable); - - for (s = addr_sources; !stop && !found && s; s = g_slist_next (s)) { - ESource *source = s->data; - GSList *contacts; - EBookClient *book_client = NULL; - GHook *hook_stop; - gboolean cached_book = FALSE; - const gchar *display_name; - const gchar *uid; - GError *err = NULL; - - uid = e_source_peek_uid (source); - display_name = e_source_peek_name (source); - - /* failed to load this book last time, skip it now */ - if (g_hash_table_lookup (emu_broken_books_hash, uid) != NULL) { - d(printf ("%s: skipping broken book '%s'\n", - G_STRFUNC, display_name)); - continue; - } - - d(printf(" checking '%s'\n", e_source_get_uri(source))); - - hook_stop = mail_cancel_hook_add (emu_addr_cancel_stop, &stop); - - book_client = g_hash_table_lookup (emu_books_hash, uid); - if (!book_client) { - book_client = e_book_client_new (source, &err); - - if (book_client == NULL) { - if (err && (g_error_matches (err, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))) { - stop = TRUE; - } else if (err) { - gchar *source_uid; - - source_uid = g_strdup (uid); - - g_hash_table_insert ( - emu_broken_books_hash, - source_uid, source_uid); - - g_warning ( - "%s: Unable to create addressbook '%s': %s", - G_STRFUNC, - display_name, - err->message); - } - g_clear_error (&err); - } else if (!stop && !try_open_book_client (book_client, TRUE, cancellable, &err)) { - g_object_unref (book_client); - book_client = NULL; - - if (err && (g_error_matches (err, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))) { - stop = TRUE; - } else if (err) { - gchar *source_uid; - - source_uid = g_strdup (uid); - - g_hash_table_insert ( - emu_broken_books_hash, - source_uid, source_uid); - - g_warning ( - "%s: Unable to open addressbook '%s': %s", - G_STRFUNC, - display_name, - err->message); - } - g_clear_error (&err); - } - } else { - cached_book = TRUE; - } - - if (book_client && !stop && e_book_client_get_contacts_sync (book_client, query, &contacts, cancellable, &err)) { - if (contacts != NULL) { - if (!found_any) { - g_hash_table_insert (contact_cache, g_strdup (lowercase_addr), book_client); - } - found_any = TRUE; - - if (check_contact) { - GSList *l; - - for (l = contacts; l && !found; l = l->next) { - EContact *contact = l->data; - - found = check_contact (contact, user_data); - } - } else { - found = TRUE; - } - - g_slist_foreach (contacts, (GFunc) g_object_unref, NULL); - g_slist_free (contacts); - } - } else if (book_client) { - stop = stop || (err && - (g_error_matches (err, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))); - if (err && !stop) { - gchar *source_uid = g_strdup (uid); - - g_hash_table_insert (emu_broken_books_hash, source_uid, source_uid); - - g_warning ( - "%s: Can't get contacts from '%s': %s", - G_STRFUNC, - display_name, - err->message); - } - g_clear_error (&err); - } - - mail_cancel_hook_remove (hook_stop); - - if (stop && !cached_book && book_client) { - g_object_unref (book_client); - } else if (!stop && book_client && !cached_book) { - g_hash_table_insert ( - emu_books_hash, g_strdup (uid), book_client); - } - } - - mail_cancel_hook_remove (hook_cancellable); - g_object_unref (cancellable); - - g_slist_free_full (addr_sources, (GDestroyNotify) g_object_unref); - - g_free (query); - - if (!found_any) { - g_hash_table_insert (contact_cache, lowercase_addr, NOT_FOUND_BOOK); - lowercase_addr = NULL; - } - - G_UNLOCK (contact_cache); - - g_free (lowercase_addr); - - return found_any; -} - -gboolean -em_utils_in_addressbook (CamelInternetAddress *iaddr, - gboolean local_only) -{ - const gchar *addr; - - /* TODO: check all addresses? */ - if (iaddr == NULL || !camel_internet_address_get (iaddr, 0, NULL, &addr)) - return FALSE; - - return search_address_in_addressbooks (addr, local_only, NULL, NULL); -} - -static gboolean -extract_photo_data (EContact *contact, - gpointer user_data) -{ - EContactPhoto **photo = user_data; - - g_return_val_if_fail (contact != NULL, FALSE); - g_return_val_if_fail (user_data != NULL, FALSE); - - *photo = e_contact_get (contact, E_CONTACT_PHOTO); - if (!*photo) - *photo = e_contact_get (contact, E_CONTACT_LOGO); - - return *photo != NULL; -} - -typedef struct _PhotoInfo { - gchar *address; - EContactPhoto *photo; -} PhotoInfo; - -static void -emu_free_photo_info (PhotoInfo *pi) -{ - if (!pi) - return; - - if (pi->address) - g_free (pi->address); - if (pi->photo) - e_contact_photo_free (pi->photo); - g_free (pi); -} - -G_LOCK_DEFINE_STATIC (photos_cache); -static GSList *photos_cache = NULL; /* list of PhotoInfo-s */ - -CamelMimePart * -em_utils_contact_photo (CamelInternetAddress *cia, - gboolean local_only) -{ - const gchar *addr = NULL; - CamelMimePart *part = NULL; - EContactPhoto *photo = NULL; - GSList *p, *first_not_null = NULL; - gint count_not_null = 0; - - if (cia == NULL || !camel_internet_address_get (cia, 0, NULL, &addr) || !addr) { - return NULL; - } - - G_LOCK (photos_cache); - - /* search a cache first */ - for (p = photos_cache; p; p = p->next) { - PhotoInfo *pi = p->data; - - if (!pi) - continue; - - if (pi->photo) { - if (!first_not_null) - first_not_null = p; - count_not_null++; - } - - if (g_ascii_strcasecmp (addr, pi->address) == 0) { - photo = pi->photo; - break; - } - } - - /* !p means the address had not been found in the cache */ - if (!p && search_address_in_addressbooks ( - addr, local_only, extract_photo_data, &photo)) { - PhotoInfo *pi; - - if (photo && photo->type != E_CONTACT_PHOTO_TYPE_INLINED) { - e_contact_photo_free (photo); - photo = NULL; - } - - /* keep only up to 10 photos in memory */ - if (photo && count_not_null >= 10 && first_not_null) { - pi = first_not_null->data; - - photos_cache = g_slist_remove (photos_cache, pi); - - emu_free_photo_info (pi); - } - - pi = g_new0 (PhotoInfo, 1); - pi->address = g_strdup (addr); - pi->photo = photo; - - photos_cache = g_slist_append (photos_cache, pi); - } - - /* some photo found, use it */ - if (photo) { - /* Form a mime part out of the photo */ - part = camel_mime_part_new (); - camel_mime_part_set_content (part, - (const gchar *) photo->data.inlined.data, - photo->data.inlined.length, "image/jpeg"); - } - - G_UNLOCK (photos_cache); - - return part; -} - -/* list of email addresses (strings) to remove from local cache of photos and - * contacts, but only if the photo doesn't exist or is an not-found contact */ -void -emu_remove_from_mail_cache (const GSList *addresses) -{ - const GSList *a; - GSList *p; - CamelInternetAddress *cia; - - cia = camel_internet_address_new (); - - for (a = addresses; a; a = a->next) { - const gchar *addr = NULL; - - if (!a->data) - continue; - - if (camel_address_decode ((CamelAddress *) cia, a->data) != -1 && - camel_internet_address_get (cia, 0, NULL, &addr) && addr) { - gchar *lowercase_addr = g_utf8_strdown (addr, -1); - - G_LOCK (contact_cache); - if (g_hash_table_lookup (contact_cache, lowercase_addr) == NOT_FOUND_BOOK) - g_hash_table_remove (contact_cache, lowercase_addr); - G_UNLOCK (contact_cache); - - g_free (lowercase_addr); - - G_LOCK (photos_cache); - for (p = photos_cache; p; p = p->next) { - PhotoInfo *pi = p->data; - - if (pi && !pi->photo && g_ascii_strcasecmp (pi->address, addr) == 0) { - photos_cache = g_slist_remove (photos_cache, pi); - emu_free_photo_info (pi); - break; - } - } - G_UNLOCK (photos_cache); - } - } - - g_object_unref (cia); -} - -void -emu_remove_from_mail_cache_1 (const gchar *address) -{ - GSList *l; - - g_return_if_fail (address != NULL); - - l = g_slist_append (NULL, (gpointer) address); - - emu_remove_from_mail_cache (l); - - g_slist_free (l); -} - -/* frees all data created by call of em_utils_in_addressbook() or - * em_utils_contact_photo() */ -void -emu_free_mail_cache (void) -{ - G_LOCK (contact_cache); - - if (emu_books_hash) { - g_hash_table_destroy (emu_books_hash); - emu_books_hash = NULL; - } - - if (emu_broken_books_hash) { - g_hash_table_destroy (emu_broken_books_hash); - emu_broken_books_hash = NULL; - } - - if (emu_books_source_list) { - g_object_unref (emu_books_source_list); - emu_books_source_list = NULL; - } - - if (contact_cache) { - g_hash_table_destroy (contact_cache); - contact_cache = NULL; - } - - G_UNLOCK (contact_cache); - - G_LOCK (photos_cache); - - g_slist_foreach (photos_cache, (GFunc) emu_free_photo_info, NULL); - g_slist_free (photos_cache); - photos_cache = NULL; - - G_UNLOCK (photos_cache); -} - void em_utils_clear_get_password_canceled_accounts_flag (void) { @@ -2080,148 +1314,6 @@ em_utils_url_unescape_amp (const gchar *url) return buff; } -static EAccount * -guess_account_from_folder (CamelFolder *folder) -{ - CamelStore *store; - const gchar *uid; - - store = camel_folder_get_parent_store (folder); - uid = camel_service_get_uid (CAMEL_SERVICE (store)); - - return e_get_account_by_uid (uid); -} - -static EAccount * -guess_account_from_message (CamelMimeMessage *message) -{ - const gchar *uid; - - uid = camel_mime_message_get_source (message); - - return (uid != NULL) ? e_get_account_by_uid (uid) : NULL; -} - -EAccount * -em_utils_guess_account (CamelMimeMessage *message, - CamelFolder *folder) -{ - EAccount *account = NULL; - - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); - - if (folder != NULL) - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - - /* check for newsgroup header */ - if (folder != NULL - && camel_medium_get_header (CAMEL_MEDIUM (message), "Newsgroups")) - account = guess_account_from_folder (folder); - - /* check for source folder */ - if (account == NULL && folder != NULL) - account = guess_account_from_folder (folder); - - /* then message source */ - if (account == NULL) - account = guess_account_from_message (message); - - return account; -} - -EAccount * -em_utils_guess_account_with_recipients (CamelMimeMessage *message, - CamelFolder *folder) -{ - EAccount *account = NULL; - EAccountList *account_list; - GHashTable *recipients; - EIterator *iterator; - CamelInternetAddress *addr; - const gchar *type; - const gchar *key; - - /* This policy is subject to debate and tweaking, - * but please also document the rational here. */ - - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); - - /* Build a set of email addresses in which to test for membership. - * Only the keys matter here; the values just need to be non-NULL. */ - recipients = g_hash_table_new (g_str_hash, g_str_equal); - - type = CAMEL_RECIPIENT_TYPE_TO; - addr = camel_mime_message_get_recipients (message, type); - if (addr != NULL) { - gint index = 0; - - while (camel_internet_address_get (addr, index++, NULL, &key)) - g_hash_table_insert ( - recipients, (gpointer) key, - GINT_TO_POINTER (1)); - } - - type = CAMEL_RECIPIENT_TYPE_CC; - addr = camel_mime_message_get_recipients (message, type); - if (addr != NULL) { - gint index = 0; - - while (camel_internet_address_get (addr, index++, NULL, &key)) - g_hash_table_insert ( - recipients, (gpointer) key, - GINT_TO_POINTER (1)); - } - - /* First Preference: We were given a folder that maps to an - * enabled account, and that account's email address appears - * in the list of To: or Cc: recipients. */ - - if (folder != NULL) - account = guess_account_from_folder (folder); - - if (account == NULL || !account->enabled) - goto second_preference; - - if ((key = account->id->address) == NULL) - goto second_preference; - - if (g_hash_table_lookup (recipients, key) != NULL) - goto exit; - -second_preference: - - /* Second Preference: Choose any enabled account whose email - * address appears in the list to To: or Cc: recipients. */ - - account_list = e_get_account_list (); - iterator = e_list_get_iterator (E_LIST (account_list)); - - while (e_iterator_is_valid (iterator)) { - account = (EAccount *) e_iterator_get (iterator); - e_iterator_next (iterator); - - if (account == NULL || !account->enabled) - continue; - - if ((key = account->id->address) == NULL) - continue; - - if (g_hash_table_lookup (recipients, key) != NULL) { - g_object_unref (iterator); - goto exit; - } - } - g_object_unref (iterator); - - /* Last Preference: Defer to em_utils_guess_account(). */ - account = em_utils_guess_account (message, folder); - -exit: - g_hash_table_destroy (recipients); - - return account; -} - void emu_restore_folder_tree_state (EMFolderTree *folder_tree) { @@ -2252,76 +1344,6 @@ emu_restore_folder_tree_state (EMFolderTree *folder_tree) g_key_file_free (key_file); } -/* Returns TRUE if CamelURL points to a local mbox file. */ -gboolean -em_utils_is_local_delivery_mbox_file (CamelURL *url) -{ - g_return_val_if_fail (url != NULL, FALSE); - - return g_str_equal (url->protocol, "mbox") && - (url->path != NULL) && - g_file_test (url->path, G_FILE_TEST_EXISTS) && - !g_file_test (url->path, G_FILE_TEST_IS_DIR); -} - -static void -cancel_service_connect_cb (GCancellable *cancellable, - CamelService *service) -{ - g_return_if_fail (CAMEL_IS_SERVICE (service)); - - camel_service_cancel_connect (service); -} - -gboolean -em_utils_connect_service_sync (CamelService *service, - GCancellable *cancellable, - GError **error) -{ - gboolean res; - gulong handler_id = 0; - - g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE); - - if (cancellable != NULL) - handler_id = g_cancellable_connect ( - cancellable, - G_CALLBACK (cancel_service_connect_cb), - service, NULL); - - res = camel_service_connect_sync (service, error); - - if (handler_id) - g_cancellable_disconnect (cancellable, handler_id); - - return res; -} - -gboolean -em_utils_disconnect_service_sync (CamelService *service, - gboolean clean, - GCancellable *cancellable, - GError **error) -{ - gboolean res; - gulong handler_id = 0; - - g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE); - - if (cancellable != NULL) - handler_id = g_cancellable_connect ( - cancellable, - G_CALLBACK (cancel_service_connect_cb), - service, NULL); - - res = camel_service_disconnect_sync (service, clean, error); - - if (handler_id) - g_cancellable_disconnect (cancellable, handler_id); - - return res; -} - static gboolean check_prefix (const gchar *subject, const gchar *prefix, diff --git a/mail/em-utils.h b/mail/em-utils.h index bf02419526..09ae4a56eb 100644 --- a/mail/em-utils.h +++ b/mail/em-utils.h @@ -29,8 +29,10 @@ #include <libedataserver/e-proxy.h> #include <libedataserver/e-account.h> +#include <libemail-engine/e-mail-session.h> +#include <libemail-engine/e-mail-utils.h> + #include <mail/e-mail-reader.h> -#include <mail/e-mail-session.h> #include <mail/em-folder-tree.h> G_BEGIN_DECLS @@ -42,7 +44,6 @@ gboolean em_utils_ask_open_many (GtkWindow *parent, gint how_many); gboolean em_utils_prompt_user (GtkWindow *parent, const gchar *promptkey, const gchar *tag, ...); GPtrArray *em_utils_uids_copy (GPtrArray *uids); -void em_utils_uids_free (GPtrArray *uids); void em_utils_edit_filters (EMailSession *session, EAlertSink *alert_sink, @@ -64,11 +65,6 @@ void em_utils_selection_get_uidlist (GtkSelectionData *data, EMailSession *sessi void em_utils_selection_set_urilist (GtkSelectionData *data, CamelFolder *folder, GPtrArray *uids); void em_utils_selection_get_urilist (GtkSelectionData *data, CamelFolder *folder); -gboolean em_utils_folder_is_drafts (CamelFolder *folder); -gboolean em_utils_folder_is_templates (CamelFolder *folder); -gboolean em_utils_folder_is_sent (CamelFolder *folder); -gboolean em_utils_folder_is_outbox (CamelFolder *folder); - EProxy * em_utils_get_proxy (void); /* FIXME: should this have an override charset? */ @@ -77,33 +73,16 @@ gchar *em_utils_message_to_html (CamelMimeMessage *msg, const gchar *credits, gu void em_utils_empty_trash (GtkWidget *parent, EMailSession *session); -/* is this address in the addressbook? caches results */ -gboolean em_utils_in_addressbook (CamelInternetAddress *addr, gboolean local_only); -CamelMimePart *em_utils_contact_photo (CamelInternetAddress *addr, gboolean local); - /* clears flag 'get_password_canceled' at every known accounts, so if needed, get_password will show dialog */ void em_utils_clear_get_password_canceled_accounts_flag (void); /* Unescapes & back to a real & in URIs */ gchar *em_utils_url_unescape_amp (const gchar *url); -EAccount * em_utils_guess_account (CamelMimeMessage *message, - CamelFolder *folder); -EAccount * em_utils_guess_account_with_recipients - (CamelMimeMessage *message, - CamelFolder *folder); - -void emu_remove_from_mail_cache (const GSList *addresses); -void emu_remove_from_mail_cache_1 (const gchar *address); -void emu_free_mail_cache (void); +void emu_free_mail_account_sort_order_cache (void); void emu_restore_folder_tree_state (EMFolderTree *folder_tree); -gboolean em_utils_is_local_delivery_mbox_file (CamelURL *url); - -gboolean em_utils_connect_service_sync (CamelService *service, GCancellable *cancellable, GError **error); -gboolean em_utils_disconnect_service_sync (CamelService *service, gboolean clean, GCancellable *cancellable, GError **error); - gboolean em_utils_is_re_in_subject (struct _EShell *shell, const gchar *subject, gint *skip_len); diff --git a/mail/em-vfolder-context.h b/mail/em-vfolder-context.h index c0fd041abc..2d1c6ef0fc 100644 --- a/mail/em-vfolder-context.h +++ b/mail/em-vfolder-context.h @@ -25,8 +25,8 @@ #ifndef EM_VFOLDER_CONTEXT_H #define EM_VFOLDER_CONTEXT_H -#include <mail/e-mail-session.h> #include <filter/e-rule-context.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_VFOLDER_CONTEXT \ diff --git a/mail/em-vfolder-rule.c b/mail/em-vfolder-rule.c index a22816070a..91bf46128e 100644 --- a/mail/em-vfolder-rule.c +++ b/mail/em-vfolder-rule.c @@ -30,17 +30,19 @@ #include <gtk/gtk.h> #include <glib/gi18n.h> +#include <shell/e-shell.h> + +#include <e-util/e-util.h> +#include <e-util/e-alert.h> +#include <e-util/e-util-private.h> + +#include <libemail-engine/e-mail-folder-utils.h> + +#include "em-folder-selector.h" +#include "em-folder-tree.h" +#include "em-utils.h" #include "em-vfolder-context.h" #include "em-vfolder-rule.h" -#include "mail/e-mail-folder-utils.h" -#include "mail/em-utils.h" -#include "mail/em-folder-tree.h" -#include "mail/em-folder-selector.h" -#include "shell/e-shell.h" - -#include "e-util/e-util.h" -#include "e-util/e-alert.h" -#include "e-util/e-util-private.h" #define EM_VFOLDER_RULE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ diff --git a/mail/em-vfolder-rule.h b/mail/em-vfolder-rule.h index 7fc8daaee9..1b3a4432ca 100644 --- a/mail/em-vfolder-rule.h +++ b/mail/em-vfolder-rule.h @@ -24,8 +24,8 @@ #ifndef EM_VFOLDER_RULE_H #define EM_VFOLDER_RULE_H -#include <mail/e-mail-session.h> #include <filter/e-filter-rule.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define EM_TYPE_VFOLDER_RULE \ diff --git a/mail/importers/Makefile.am b/mail/importers/Makefile.am index fa1a400f03..6a7e9a8b6e 100644 --- a/mail/importers/Makefile.am +++ b/mail/importers/Makefile.am @@ -28,6 +28,8 @@ libevolution_mail_importers_la_LIBADD = \ $(top_builddir)/mail/libevolution-mail.la \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/libemail-engine/libemail-engine.la \ + $(top_builddir)/libemail-utils/libemail-utils.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ $(GTKHTML_LIBS) diff --git a/mail/importers/elm-importer.c b/mail/importers/elm-importer.c index 832bf749ea..288d9fb736 100644 --- a/mail/importers/elm-importer.c +++ b/mail/importers/elm-importer.c @@ -40,7 +40,7 @@ #include "mail-importer.h" -#include "mail/mail-mt.h" +#include "libemail-utils/mail-mt.h" #include "mail/e-mail-backend.h" #include "e-util/e-import.h" #include "shell/e-shell.h" diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c index c3d5f2f1b7..f6e5c63613 100644 --- a/mail/importers/evolution-mbox-importer.c +++ b/mail/importers/evolution-mbox-importer.c @@ -48,7 +48,7 @@ #include "mail/em-folder-selection-button.h" #include "mail/em-folder-tree-model.h" #include "mail/em-folder-tree.h" -#include "mail/mail-mt.h" +#include "libemail-utils/mail-mt.h" #include "mail-importer.h" diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c index 558359c636..716d99c991 100644 --- a/mail/importers/mail-importer.c +++ b/mail/importers/mail-importer.c @@ -39,9 +39,9 @@ #include "e-util/e-util-private.h" #include "shell/e-shell-backend.h" -#include "mail-mt.h" -#include "mail-tools.h" -#include "e-mail-session.h" +#include "libemail-utils/mail-mt.h" +#include "libemail-engine/mail-tools.h" +#include "libemail-engine/e-mail-session.h" #include "mail-importer.h" @@ -277,9 +277,9 @@ mail_importer_import_mbox_sync (EMailSession *session, m->path = g_strdup (path); m->uri = g_strdup (folderuri); if (cancellable) - e_activity_set_cancellable (m->base.activity, cancellable); + m->base.cancellable = cancellable; - cancellable = e_activity_get_cancellable (m->base.activity); + cancellable = m->base.cancellable; import_mbox_exec (m, cancellable, &m->base.error); import_mbox_done (m); diff --git a/mail/importers/mail-importer.h b/mail/importers/mail-importer.h index d66ed464ec..bd0335c299 100644 --- a/mail/importers/mail-importer.h +++ b/mail/importers/mail-importer.h @@ -26,7 +26,7 @@ #include <e-util/e-import.h> #include <camel/camel.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> EImportImporter *mbox_importer_peek (void); diff --git a/mail/importers/pine-importer.c b/mail/importers/pine-importer.c index 1ba44583ab..3ecfbbc5df 100644 --- a/mail/importers/pine-importer.c +++ b/mail/importers/pine-importer.c @@ -43,7 +43,7 @@ #include "mail-importer.h" -#include "mail/mail-mt.h" +#include "libemail-utils/mail-mt.h" #include "mail/e-mail-backend.h" #include "e-util/e-import.h" #include "shell/e-shell.h" diff --git a/mail/mail-autofilter.c b/mail/mail-autofilter.c index 6d08c78a40..08e3a3d937 100644 --- a/mail/mail-autofilter.c +++ b/mail/mail-autofilter.c @@ -29,8 +29,9 @@ #include <glib/gi18n.h> -#include "e-mail-folder-utils.h" -#include "e-mail-session.h" +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/e-mail-session.h> + #include "mail-vfolder.h" #include "mail-autofilter.h" #include "em-utils.h" diff --git a/mail/mail-autofilter.h b/mail/mail-autofilter.h index 47f68c3be5..34593b0f95 100644 --- a/mail/mail-autofilter.h +++ b/mail/mail-autofilter.h @@ -27,9 +27,9 @@ #include <camel/camel.h> #include <filter/e-filter-rule.h> -#include <mail/e-mail-session.h> #include <mail/em-filter-context.h> #include <mail/em-vfolder-context.h> +#include <libemail-engine/e-mail-session.h> enum { AUTO_SUBJECT = 1, diff --git a/mail/mail-config.c b/mail/mail-config.c deleted file mode 100644 index fc003acbde..0000000000 --- a/mail/mail-config.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * Radek Doulik <rodo@ximian.com> - * Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2009 Intel Corporation - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include <libedataserver/e-data-server-util.h> - -#include <e-util/e-util.h> -#include "e-util/e-account-utils.h" -#include "e-util/e-signature-utils.h" - -#include "e-mail-folder-utils.h" -#include "mail-config.h" -#include "mail-tools.h" - -typedef struct { - GSList *labels; - - gboolean address_compress; - gint address_count; - - GSList *jh_header; - gboolean jh_check; - gboolean book_lookup; - gboolean book_lookup_local_only; -} MailConfig; - -extern gint camel_header_param_encode_filenames_in_rfc_2047; - -static MailConfig *config = NULL; -static GSettings *mail_settings = NULL; - -static void -settings_outlook_filenames_changed (GSettings *settings, - const gchar *key, - gpointer user_data) -{ - /* pass option to the camel */ - if (g_settings_get_boolean (settings, key)) - camel_header_param_encode_filenames_in_rfc_2047 = 1; - else - camel_header_param_encode_filenames_in_rfc_2047 = 0; -} - -static void -settings_jh_headers_changed (GSettings *settings, - const gchar *key, - EMailSession *session) -{ - GSList *node; - GPtrArray *name, *value; - gchar **strv; - gint i; - - g_slist_foreach (config->jh_header, (GFunc) g_free, NULL); - g_slist_free (config->jh_header); - config->jh_header = NULL; - - strv = g_settings_get_strv (settings, "junk-custom-header"); - for (i = 0; strv[i] != NULL; i++) - config->jh_header = g_slist_append (config->jh_header, g_strdup (strv[i])); - g_strfreev (strv); - - node = config->jh_header; - name = g_ptr_array_new (); - value = g_ptr_array_new (); - while (node && node->data) { - gchar **tok = g_strsplit (node->data, "=", 2); - g_ptr_array_add (name, g_strdup (tok[0])); - g_ptr_array_add (value, g_strdup (tok[1])); - node = node->next; - g_strfreev (tok); - } - camel_session_set_junk_headers ( - CAMEL_SESSION (session), - (const gchar **) name->pdata, - (const gchar **) value->pdata, name->len); - - g_ptr_array_foreach (name, (GFunc) g_free, NULL); - g_ptr_array_foreach (value, (GFunc) g_free, NULL); - g_ptr_array_free (name, TRUE); - g_ptr_array_free (value, TRUE); -} - -static void -settings_jh_check_changed (GSettings *settings, - const gchar *key, - EMailSession *session) -{ - config->jh_check = g_settings_get_boolean (settings, "junk-check-custom-header"); - if (!config->jh_check) { - camel_session_set_junk_headers ( - CAMEL_SESSION (session), NULL, NULL, 0); - } else { - settings_jh_headers_changed (settings, NULL, session); - } -} - -static void -settings_bool_value_changed (GSettings *settings, - const gchar *key, - gboolean *save_location) -{ - *save_location = g_settings_get_boolean (settings, key); -} - -static void -settings_int_value_changed (GSettings *settings, - const gchar *key, - gint *save_location) -{ - *save_location = g_settings_get_int (settings, key); -} - -void -mail_config_write (void) -{ - EAccountList *account_list; - ESignatureList *signature_list; - - if (!config) - return; - - account_list = e_get_account_list (); - signature_list = e_get_signature_list (); - - e_account_list_save (account_list); - e_signature_list_save (signature_list); - - g_settings_sync (); -} - -gint -mail_config_get_address_count (void) -{ - if (!config->address_compress) - return -1; - - return config->address_count; -} - -/* timeout interval, in seconds, when to call server update */ -gint -mail_config_get_sync_timeout (void) -{ - gint res = 60; - - res = g_settings_get_int (mail_settings, "sync-interval"); - - /* do not allow recheck sooner than every 30 seconds */ - if (res == 0) - res = 60; - else if (res < 30) - res = 30; - - return res; -} - -gchar * -mail_config_folder_to_cachename (CamelFolder *folder, - const gchar *prefix) -{ - gchar *folder_uri, *basename, *filename; - const gchar *config_dir; - - config_dir = mail_session_get_config_dir (); - - basename = g_build_filename (config_dir, "folders", NULL); - if (!g_file_test (basename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - /* create the folder if does not exist */ - g_mkdir_with_parents (basename, 0700); - } - g_free (basename); - - folder_uri = e_mail_folder_uri_from_folder (folder); - e_filename_make_safe (folder_uri); - basename = g_strdup_printf ("%s%s", prefix, folder_uri); - filename = g_build_filename (config_dir, "folders", basename, NULL); - g_free (basename); - g_free (folder_uri); - - return filename; -} - -void -mail_config_reload_junk_headers (EMailSession *session) -{ - g_return_if_fail (E_IS_MAIL_SESSION (session)); - - /* It automatically sets in the session */ - if (config == NULL) - mail_config_init (session); - else { - settings_jh_check_changed (mail_settings, NULL, session); - } -} - -gboolean -mail_config_get_lookup_book (void) -{ - g_return_val_if_fail (config != NULL, FALSE); - - return config->book_lookup; -} - -gboolean -mail_config_get_lookup_book_local_only (void) -{ - g_return_val_if_fail (config != NULL, FALSE); - - return config->book_lookup_local_only; -} - -/* Config struct routines */ -void -mail_config_init (EMailSession *session) -{ - g_return_if_fail (E_IS_MAIL_SESSION (session)); - - if (config) - return; - - config = g_new0 (MailConfig, 1); - - mail_settings = g_settings_new ("org.gnome.evolution.mail"); - - /* Composer Configuration */ - - settings_outlook_filenames_changed ( - mail_settings, "composer-outlook-filenames", NULL); - g_signal_connect ( - mail_settings, "changed::composer-outlook-filenames", - G_CALLBACK (settings_outlook_filenames_changed), NULL); - - /* Display Configuration */ - - g_signal_connect ( - mail_settings, "changed::address-compress", - G_CALLBACK (settings_bool_value_changed), &config->address_compress); - config->address_compress = g_settings_get_boolean (mail_settings, "address-compress"); - - g_signal_connect ( - mail_settings, "changed::address-count", - G_CALLBACK (settings_int_value_changed), &config->address_count); - config->address_count = g_settings_get_int (mail_settings, "address-count"); - - /* Junk Configuration */ - - g_signal_connect ( - mail_settings, "changed::junk-check-custom-header", - G_CALLBACK (settings_jh_check_changed), session); - config->jh_check = g_settings_get_boolean (mail_settings, "junk-check-custom-header"); - - g_signal_connect ( - mail_settings, "changed::junk-custom-header", - G_CALLBACK (settings_jh_headers_changed), session); - - g_signal_connect ( - mail_settings, "changed::junk-lookup-addressbook", - G_CALLBACK (settings_bool_value_changed), &config->book_lookup); - config->book_lookup = g_settings_get_boolean (mail_settings, "junk-lookup-addressbook"); - - g_signal_connect ( - mail_settings, "changed::junk-lookup-addressbook-local-only", - G_CALLBACK (settings_bool_value_changed), &config->book_lookup_local_only); - config->book_lookup_local_only = g_settings_get_boolean (mail_settings, "junk-lookup-addressbook-local-only"); - - settings_jh_check_changed (mail_settings, NULL, session); -} diff --git a/mail/mail-config.h b/mail/mail-config.h deleted file mode 100644 index 29038093cb..0000000000 --- a/mail/mail-config.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef MAIL_CONFIG_H -#define MAIL_CONFIG_H - -#include <mail/e-mail-session.h> - -G_BEGIN_DECLS - -/* Configuration */ -void mail_config_init (EMailSession *session); -void mail_config_write (void); - -/* General Accessor functions */ - -gint mail_config_get_address_count (void); - -/* static utility functions */ -gchar * mail_config_folder_to_cachename (CamelFolder *folder, - const gchar *prefix); -gint mail_config_get_sync_timeout (void); - -void mail_config_reload_junk_headers (EMailSession *session); -gboolean mail_config_get_lookup_book (void); -gboolean mail_config_get_lookup_book_local_only (void); - -G_END_DECLS - -#endif /* MAIL_CONFIG_H */ diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c deleted file mode 100644 index 4092ee6861..0000000000 --- a/mail/mail-folder-cache.c +++ /dev/null @@ -1,1875 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Peter Williams <peterw@ximian.com> - * Michael Zucchi <notzed@ximian.com> - * Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2009 Intel Corporation - * - */ - -/** - * SECTION: mail-folder-cache - * @short_description: Stores information about open folders - **/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <time.h> - -#include <glib/gi18n.h> -#include <glib/gstdio.h> - -#include <libedataserver/e-data-server-util.h> -#include <e-util/e-marshal.h> -#include <e-util/e-util.h> - -#include "mail-mt.h" -#include "mail-folder-cache.h" -#include "mail-ops.h" -#include "mail-tools.h" - -#include "em-utils.h" -#include "e-mail-folder-utils.h" -#include "e-mail-session.h" -#include "e-mail-store-utils.h" - -#define w(x) -#define d(x) - -#define MAIL_FOLDER_CACHE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), MAIL_TYPE_FOLDER_CACHE, MailFolderCachePrivate)) - -/* This code is a mess, there is no reason it should be so complicated. */ - -typedef struct _StoreInfo StoreInfo; - -struct _MailFolderCachePrivate { - gpointer session; /* weak pointer */ - EMailAccountStore *account_store; - - /* source id for the ping timeout callback */ - guint ping_id; - /* Store to storeinfo table, active stores */ - GHashTable *stores; - /* mutex to protect access to the stores hash */ - GMutex *stores_mutex; - /* List of folder changes to be executed in gui thread */ - GQueue updates; - /* idle source id for flushing all pending updates */ - guint update_id; - /* hack for people who LIKE to have unsent count */ - gint count_sent; - gint count_trash; - - GQueue local_folder_uris; - GQueue remote_folder_uris; -}; - -enum { - PROP_0, - PROP_SESSION -}; - -enum { - FOLDER_AVAILABLE, - FOLDER_UNAVAILABLE, - FOLDER_DELETED, - FOLDER_RENAMED, - FOLDER_UNREAD_UPDATED, - FOLDER_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -struct _folder_info { - StoreInfo *store_info; /* 'parent' link */ - - gchar *full_name; /* full name of folder/folderinfo */ - - guint32 flags; - gboolean has_children; - - gpointer folder; /* if known (weak pointer) */ -}; - -/* pending list of updates */ -struct _folder_update { - guint remove:1; /* removing from vfolders */ - guint delete:1; /* deleting as well? */ - guint add:1; /* add to vfolder */ - guint unsub:1; /* unsubcribing? */ - guint new; /* new mail arrived? */ - - gchar *full_name; - gchar *oldfull; - - gint unread; - CamelStore *store; - - /* for only one new message... */ - gchar *msg_uid; /* ... its uid ... */ - gchar *msg_sender; /* ... its sender ... */ - gchar *msg_subject; /* ... and its subject. */ -}; - -struct _StoreInfo { - GHashTable *folders; /* by full_name */ - CamelStore *store; /* the store for these folders */ - gboolean first_update; /* TRUE initially, then FALSE forever */ - - /* Hold a reference to keep them alive. */ - CamelFolder *vjunk; - CamelFolder *vtrash; - - /* Outstanding folderinfo requests */ - GQueue folderinfo_updates; -}; - -struct _update_data { - NoteDoneFunc done; - gpointer data; - MailFolderCache *cache; - GCancellable *cancellable; -}; - -G_DEFINE_TYPE (MailFolderCache, mail_folder_cache, G_TYPE_OBJECT) - -static void -free_update (struct _folder_update *up) -{ - g_free (up->full_name); - if (up->store) - g_object_unref (up->store); - g_free (up->oldfull); - g_free (up->msg_uid); - g_free (up->msg_sender); - g_free (up->msg_subject); - g_free (up); -} - -static void -free_folder_info (struct _folder_info *mfi) -{ - g_free (mfi->full_name); - g_free (mfi); -} - -static StoreInfo * -store_info_new (CamelStore *store) -{ - StoreInfo *info; - GHashTable *folders; - - folders = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) free_folder_info); - - info = g_slice_new0 (StoreInfo); - info->folders = folders; - info->store = g_object_ref (store); - info->first_update = TRUE; - - /* If these are vfolders then they need to be opened - * now, otherwise they won't keep track of all folders. */ - if (store->flags & CAMEL_STORE_VJUNK) - info->vjunk = camel_store_get_junk_folder_sync ( - store, NULL, NULL); - if (store->flags & CAMEL_STORE_VTRASH) - info->vtrash = camel_store_get_trash_folder_sync ( - store, NULL, NULL); - - g_queue_init (&info->folderinfo_updates); - - return info; -} - -static void -store_info_free (StoreInfo *info) -{ - struct _update_data *ud; - - while (!g_queue_is_empty (&info->folderinfo_updates)) { - ud = g_queue_pop_head (&info->folderinfo_updates); - g_cancellable_cancel (ud->cancellable); - } - - g_hash_table_destroy (info->folders); - g_object_unref (info->store); - - if (info->vjunk != NULL) - g_object_unref (info->vjunk); - - if (info->vtrash != NULL) - g_object_unref (info->vtrash); - - g_slice_free (StoreInfo, info); -} - -static gboolean -flush_updates_idle_cb (MailFolderCache *cache) -{ - struct _folder_update *up; - - g_mutex_lock (cache->priv->stores_mutex); - while ((up = g_queue_pop_head (&cache->priv->updates)) != NULL) { - g_mutex_unlock (cache->priv->stores_mutex); - - if (up->remove) { - if (up->delete) { - g_signal_emit ( - cache, signals[FOLDER_DELETED], 0, - up->store, up->full_name); - } else - g_signal_emit ( - cache, signals[FOLDER_UNAVAILABLE], 0, - up->store, up->full_name); - } else { - if (up->oldfull && up->add) { - g_signal_emit ( - cache, signals[FOLDER_RENAMED], 0, - up->store, up->oldfull, up->full_name); - } - - if (!up->oldfull && up->add) - g_signal_emit ( - cache, signals[FOLDER_AVAILABLE], 0, - up->store, up->full_name); - } - - /* update unread counts */ - g_signal_emit (cache, signals[FOLDER_UNREAD_UPDATED], 0, - up->store, up->full_name, up->unread); - - /* indicate that the folder has changed (new mail received, etc) */ - if (up->store != NULL && up->full_name != NULL) { - g_signal_emit ( - cache, signals[FOLDER_CHANGED], 0, up->store, - up->full_name, up->new, up->msg_uid, - up->msg_sender, up->msg_subject); - } - - if (CAMEL_IS_VEE_STORE (up->store) && !up->remove) { - /* Normally the vfolder store takes care of the - * folder_opened event itcache, but we add folder to - * the noting system later, thus we do not know about - * search folders to update them in a tree, thus - * ensure their changes will be tracked correctly. */ - CamelFolder *folder; - - /* FIXME camel_store_get_folder_sync() may block. */ - folder = camel_store_get_folder_sync ( - up->store, up->full_name, 0, NULL, NULL); - - if (folder) { - mail_folder_cache_note_folder (cache, folder); - g_object_unref (folder); - } - } - - free_update (up); - - g_mutex_lock (cache->priv->stores_mutex); - } - cache->priv->update_id = 0; - g_mutex_unlock (cache->priv->stores_mutex); - - return FALSE; -} - -static void -flush_updates (MailFolderCache *cache) -{ - if (cache->priv->update_id > 0) - return; - - if (g_queue_is_empty (&cache->priv->updates)) - return; - - cache->priv->update_id = g_idle_add ( - (GSourceFunc) flush_updates_idle_cb, cache); -} - -/* This is how unread counts work (and don't work): - * - * camel_folder_unread_message_count() only gives a correct answer if - * the store is paying attention to the folder. (Some stores always - * pay attention to all folders, but IMAP can only pay attention to - * one folder at a time.) But it doesn't have any way to know when - * it's lying, so it's only safe to call it when you know for sure - * that the store is paying attention to the folder, such as when it's - * just been created, or you get a folder_changed signal on it. - * - * camel_store_get_folder_info() always gives correct answers for the - * folders it checks, but it can also return -1 for a folder, meaning - * it didn't check, and so you should stick with your previous answer. - * - * update_1folder is called from three places: with info != NULL when - * the folder is created (or get_folder_info), with info == NULL when - * a folder changed event is emitted. - * - * So if info is NULL, camel_folder_unread_message_count is correct, - * and if it's not NULL and its unread_message_count isn't -1, then - * it's correct. */ - -static void -update_1folder (MailFolderCache *cache, - struct _folder_info *mfi, - gint new, - const gchar *msg_uid, - const gchar *msg_sender, - const gchar *msg_subject, - CamelFolderInfo *info) -{ - struct _folder_update *up; - CamelFolder *folder; - gint unread = -1; - gint deleted; - - folder = mfi->folder; - if (folder) { - gboolean folder_is_sent; - gboolean folder_is_drafts; - gboolean folder_is_outbox; - gboolean folder_is_vtrash; - gboolean special_case; - - folder_is_sent = em_utils_folder_is_sent (folder); - folder_is_drafts = em_utils_folder_is_drafts (folder); - folder_is_outbox = em_utils_folder_is_outbox (folder); - folder_is_vtrash = CAMEL_IS_VTRASH_FOLDER (folder); - - special_case = - (cache->priv->count_trash && folder_is_vtrash) || - (cache->priv->count_sent && folder_is_sent) || - folder_is_drafts || folder_is_outbox; - - if (special_case) { - d(printf(" total count\n")); - unread = camel_folder_get_message_count (folder); - if (folder_is_drafts || folder_is_outbox) { - guint32 junked = 0; - - if ((deleted = camel_folder_get_deleted_message_count (folder)) > 0) - unread -= deleted; - - junked = camel_folder_summary_get_junk_count (folder->summary); - if (junked > 0) - unread -= junked; - } - } else { - d(printf(" unread count\n")); - if (info) - unread = info->unread; - else - unread = camel_folder_get_unread_message_count (folder); - } - } - - d(printf("folder updated: unread %d: '%s'\n", unread, mfi->full_name)); - - if (unread == -1) - return; - - up = g_malloc0 (sizeof (*up)); - up->full_name = g_strdup (mfi->full_name); - up->unread = unread; - up->new = new; - up->store = g_object_ref (mfi->store_info->store); - up->msg_uid = g_strdup (msg_uid); - up->msg_sender = g_strdup (msg_sender); - up->msg_subject = g_strdup (msg_subject); - g_queue_push_tail (&cache->priv->updates, up); - flush_updates (cache); -} - -static void -folder_changed_cb (CamelFolder *folder, - CamelFolderChangeInfo *changes, - MailFolderCache *cache) -{ - static GHashTable *last_newmail_per_folder = NULL; - time_t latest_received, new_latest_received; - CamelFolder *local_drafts; - CamelFolder *local_outbox; - CamelFolder *local_sent; - CamelSession *session; - CamelStore *parent_store; - CamelMessageInfo *info; - StoreInfo *si; - struct _folder_info *mfi; - const gchar *full_name; - gint new = 0; - gint i; - guint32 flags; - gchar *uid = NULL, *sender = NULL, *subject = NULL; - - full_name = camel_folder_get_full_name (folder); - parent_store = camel_folder_get_parent_store (folder); - session = camel_service_get_session (CAMEL_SERVICE (parent_store)); - - if (!last_newmail_per_folder) - last_newmail_per_folder = g_hash_table_new (g_direct_hash, g_direct_equal); - - /* it's fine to hash them by folder pointer here */ - latest_received = GPOINTER_TO_INT ( - g_hash_table_lookup (last_newmail_per_folder, folder)); - new_latest_received = latest_received; - - local_drafts = e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS); - local_outbox = e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX); - local_sent = e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_SENT); - - if (!CAMEL_IS_VEE_FOLDER (folder) - && folder != local_drafts - && folder != local_outbox - && folder != local_sent - && changes && (changes->uid_added->len > 0)) { - /* for each added message, check to see that it is - * brand new, not junk and not already deleted */ - for (i = 0; i < changes->uid_added->len; i++) { - info = camel_folder_get_message_info ( - folder, changes->uid_added->pdata[i]); - if (info) { - flags = camel_message_info_flags (info); - if (((flags & CAMEL_MESSAGE_SEEN) == 0) && - ((flags & CAMEL_MESSAGE_JUNK) == 0) && - ((flags & CAMEL_MESSAGE_DELETED) == 0) && - (camel_message_info_date_received (info) > latest_received)) { - if (camel_message_info_date_received (info) > new_latest_received) - new_latest_received = camel_message_info_date_received (info); - new++; - if (new == 1) { - uid = g_strdup (camel_message_info_uid (info)); - sender = g_strdup (camel_message_info_from (info)); - subject = g_strdup (camel_message_info_subject (info)); - } else { - g_free (uid); - g_free (sender); - g_free (subject); - - uid = NULL; - sender = NULL; - subject = NULL; - } - } - camel_folder_free_message_info (folder, info); - } - } - } - - if (new > 0) - g_hash_table_insert ( - last_newmail_per_folder, folder, - GINT_TO_POINTER (new_latest_received)); - - g_mutex_lock (cache->priv->stores_mutex); - if (cache->priv->stores != NULL - && (si = g_hash_table_lookup (cache->priv->stores, parent_store)) != NULL - && (mfi = g_hash_table_lookup (si->folders, full_name)) != NULL - && mfi->folder == folder) { - update_1folder (cache, mfi, new, uid, sender, subject, NULL); - } - g_mutex_unlock (cache->priv->stores_mutex); - - g_free (uid); - g_free (sender); - g_free (subject); -} - -static void -unset_folder_info (MailFolderCache *cache, - struct _folder_info *mfi, - gint delete, - gint unsub) -{ - struct _folder_update *up; - - d(printf("unset folderinfo '%s'\n", mfi->uri)); - - if (mfi->folder) { - CamelFolder *folder = mfi->folder; - - g_signal_handlers_disconnect_by_func ( - folder, folder_changed_cb, cache); - - g_object_remove_weak_pointer ( - G_OBJECT (mfi->folder), &mfi->folder); - } - - if ((mfi->flags & CAMEL_FOLDER_NOSELECT) == 0) { - up = g_malloc0 (sizeof (*up)); - - up->remove = TRUE; - up->delete = delete; - up->unsub = unsub; - up->store = g_object_ref (mfi->store_info->store); - up->full_name = g_strdup (mfi->full_name); - - g_queue_push_tail (&cache->priv->updates, up); - flush_updates (cache); - } -} - -static void -setup_folder (MailFolderCache *cache, - CamelFolderInfo *fi, - StoreInfo *si) -{ - struct _folder_info *mfi; - struct _folder_update *up; - - mfi = g_hash_table_lookup (si->folders, fi->full_name); - if (mfi) { - update_1folder (cache, mfi, 0, NULL, NULL, NULL, fi); - } else { - mfi = g_malloc0 (sizeof (*mfi)); - mfi->full_name = g_strdup (fi->full_name); - mfi->store_info = si; - mfi->flags = fi->flags; - mfi->has_children = fi->child != NULL; - - g_hash_table_insert (si->folders, mfi->full_name, mfi); - - up = g_malloc0 (sizeof (*up)); - up->full_name = g_strdup (mfi->full_name); - up->unread = fi->unread; - up->store = g_object_ref (si->store); - - if ((fi->flags & CAMEL_FOLDER_NOSELECT) == 0) - up->add = TRUE; - - g_queue_push_tail (&cache->priv->updates, up); - flush_updates (cache); - } -} - -static void -create_folders (MailFolderCache *cache, - CamelFolderInfo *fi, - StoreInfo *si) -{ - while (fi) { - setup_folder (cache, fi, si); - - if (fi->child) - create_folders (cache, fi->child, si); - - fi = fi->next; - } -} - -static void -store_folder_subscribed_cb (CamelStore *store, - CamelFolderInfo *info, - MailFolderCache *cache) -{ - StoreInfo *si; - - g_mutex_lock (cache->priv->stores_mutex); - si = g_hash_table_lookup (cache->priv->stores, store); - if (si) - setup_folder (cache, info, si); - g_mutex_unlock (cache->priv->stores_mutex); -} - -static void -store_folder_created_cb (CamelStore *store, - CamelFolderInfo *info, - MailFolderCache *cache) -{ - /* We only want created events to do more work - * if we dont support subscriptions. */ - if (!CAMEL_IS_SUBSCRIBABLE (store)) - store_folder_subscribed_cb (store, info, cache); -} - -static void -store_folder_opened_cb (CamelStore *store, - CamelFolder *folder, - MailFolderCache *cache) -{ - mail_folder_cache_note_folder (cache, folder); -} - -static void -store_folder_unsubscribed_cb (CamelStore *store, - CamelFolderInfo *info, - MailFolderCache *cache) -{ - StoreInfo *si; - struct _folder_info *mfi; - - g_mutex_lock (cache->priv->stores_mutex); - si = g_hash_table_lookup (cache->priv->stores, store); - if (si) { - mfi = g_hash_table_lookup (si->folders, info->full_name); - if (mfi) { - unset_folder_info (cache, mfi, TRUE, TRUE); - g_hash_table_remove (si->folders, mfi->full_name); - } - } - g_mutex_unlock (cache->priv->stores_mutex); -} - -static void -store_folder_deleted_cb (CamelStore *store, - CamelFolderInfo *info, - MailFolderCache *cache) -{ - /* We only want deleted events to do more work - * if we dont support subscriptions. */ - if (!CAMEL_IS_SUBSCRIBABLE (store)) - store_folder_unsubscribed_cb (store, info, cache); -} - -static void -rename_folders (MailFolderCache *cache, - StoreInfo *si, - const gchar *oldbase, - const gchar *newbase, - CamelFolderInfo *fi) -{ - gchar *old, *olduri, *oldfile, *newuri, *newfile; - struct _folder_info *mfi; - struct _folder_update *up; - const gchar *config_dir; - - up = g_malloc0 (sizeof (*up)); - - d(printf("oldbase '%s' newbase '%s' new '%s'\n", oldbase, newbase, fi->full_name)); - - /* Form what was the old name, and try and look it up */ - old = g_strdup_printf("%s%s", oldbase, fi->full_name + strlen(newbase)); - mfi = g_hash_table_lookup (si->folders, old); - if (mfi) { - up->oldfull = mfi->full_name; - - /* Be careful not to invoke the destroy function. */ - g_hash_table_steal (si->folders, mfi->full_name); - - /* Its a rename op */ - mfi->full_name = g_strdup (fi->full_name); - mfi->flags = fi->flags; - mfi->has_children = fi->child != NULL; - - g_hash_table_insert (si->folders, mfi->full_name, mfi); - } else { - /* Its a new op */ - mfi = g_malloc0 (sizeof (*mfi)); - mfi->full_name = g_strdup (fi->full_name); - mfi->store_info = si; - mfi->flags = fi->flags; - mfi->has_children = fi->child != NULL; - - g_hash_table_insert (si->folders, mfi->full_name, mfi); - } - - up->full_name = g_strdup (mfi->full_name); - up->unread = fi->unread==-1 ? 0 : fi->unread; - up->store = g_object_ref (si->store); - - if ((fi->flags & CAMEL_FOLDER_NOSELECT) == 0) - up->add = TRUE; - - g_queue_push_tail (&cache->priv->updates, up); - flush_updates (cache); -#if 0 - if (fi->sibling) - rename_folders (cache, si, oldbase, newbase, fi->sibling, folders); - if (fi->child) - rename_folders (cache, si, oldbase, newbase, fi->child, folders); -#endif - - /* rename the meta-data we maintain ourselves */ - config_dir = mail_session_get_config_dir (); - olduri = e_mail_folder_uri_build (si->store, old); - e_filename_make_safe (olduri); - newuri = e_mail_folder_uri_build (si->store, fi->full_name); - e_filename_make_safe (newuri); - oldfile = g_strdup_printf("%s/custom_view-%s.xml", config_dir, olduri); - newfile = g_strdup_printf("%s/custom_view-%s.xml", config_dir, newuri); - g_rename (oldfile, newfile); - g_free (oldfile); - g_free (newfile); - oldfile = g_strdup_printf("%s/current_view-%s.xml", config_dir, olduri); - newfile = g_strdup_printf("%s/current_view-%s.xml", config_dir, newuri); - g_rename (oldfile, newfile); - g_free (oldfile); - g_free (newfile); - g_free (olduri); - g_free (newuri); - - g_free (old); -} - -static void -get_folders (CamelFolderInfo *fi, - GPtrArray *folders) -{ - while (fi) { - g_ptr_array_add (folders, fi); - - if (fi->child) - get_folders (fi->child, folders); - - fi = fi->next; - } -} - -static gint -folder_cmp (gconstpointer ap, - gconstpointer bp) -{ - const CamelFolderInfo *a = ((CamelFolderInfo **) ap)[0]; - const CamelFolderInfo *b = ((CamelFolderInfo **) bp)[0]; - - return strcmp (a->full_name, b->full_name); -} - -static void -store_folder_renamed_cb (CamelStore *store, - const gchar *old_name, - CamelFolderInfo *info, - MailFolderCache *cache) -{ - StoreInfo *si; - - g_mutex_lock (cache->priv->stores_mutex); - si = g_hash_table_lookup (cache->priv->stores, store); - if (si) { - GPtrArray *folders = g_ptr_array_new (); - CamelFolderInfo *top; - gint i; - - /* Ok, so for some reason the folderinfo we have comes in all messed up from - * imap, should find out why ... this makes it workable */ - get_folders (info, folders); - qsort (folders->pdata, folders->len, sizeof (folders->pdata[0]), folder_cmp); - - top = folders->pdata[0]; - for (i = 0; i < folders->len; i++) { - rename_folders (cache, si, old_name, top->full_name, folders->pdata[i]); - } - - g_ptr_array_free (folders, TRUE); - - } - g_mutex_unlock (cache->priv->stores_mutex); -} - -static void -unset_folder_info_hash (gchar *path, - struct _folder_info *mfi, - gpointer data) -{ - MailFolderCache *cache = (MailFolderCache *) data; - unset_folder_info (cache, mfi, FALSE, FALSE); -} - -static void -mail_folder_cache_first_update (MailFolderCache *cache, - StoreInfo *info) -{ - EMailSession *session; - const gchar *uid; - - session = mail_folder_cache_get_session (cache); - uid = camel_service_get_uid (CAMEL_SERVICE (info->store)); - - if (info->vjunk != NULL) - mail_folder_cache_note_folder (cache, info->vjunk); - - if (info->vtrash != NULL) - mail_folder_cache_note_folder (cache, info->vtrash); - - /* Some extra work for the "On This Computer" store. */ - if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) { - CamelFolder *folder; - gint ii; - - for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) { - folder = e_mail_session_get_local_folder (session, ii); - mail_folder_cache_note_folder (cache, folder); - } - } -} - -static void -update_folders (CamelStore *store, - GAsyncResult *result, - struct _update_data *ud) -{ - CamelFolderInfo *fi; - StoreInfo *si; - GError *error = NULL; - - fi = camel_store_get_folder_info_finish (store, result, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - g_mutex_lock (ud->cache->priv->stores_mutex); - si = g_hash_table_lookup (ud->cache->priv->stores, store); - if (si && !g_cancellable_is_cancelled (ud->cancellable)) { - /* The 'si' is still there, so we can remove ourselves from - * its list. Or else its not, and we're on our own and free - * anyway. */ - g_queue_remove (&si->folderinfo_updates, ud); - - if (fi != NULL) - create_folders (ud->cache, fi, si); - } - g_mutex_unlock (ud->cache->priv->stores_mutex); - - /* Do some extra work for the first update. */ - if (si != NULL && si->first_update) { - mail_folder_cache_first_update (ud->cache, si); - si->first_update = FALSE; - } - - if (fi != NULL) { - gboolean free_fi = TRUE; - - if (ud->done != NULL) - free_fi = ud->done (ud->cache, store, fi, ud->data); - if (free_fi) - camel_store_free_folder_info (store, fi); - } - - if (ud->cancellable != NULL) - g_object_unref (ud->cancellable); - - g_free (ud); -} - -struct _ping_store_msg { - MailMsg base; - CamelStore *store; -}; - -static gchar * -ping_store_desc (struct _ping_store_msg *m) -{ - gchar *service_name; - gchar *msg; - - service_name = camel_service_get_name (CAMEL_SERVICE (m->store), TRUE); - msg = g_strdup_printf (_("Pinging %s"), service_name); - g_free (service_name); - - return msg; -} - -static void -ping_store_exec (struct _ping_store_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelServiceConnectionStatus status; - CamelService *service; - gboolean online = FALSE; - - service = CAMEL_SERVICE (m->store); - status = camel_service_get_connection_status (service); - - if (status == CAMEL_SERVICE_CONNECTED) { - if (CAMEL_IS_DISCO_STORE (m->store) && - camel_disco_store_status ( - CAMEL_DISCO_STORE (m->store)) !=CAMEL_DISCO_STORE_OFFLINE) - online = TRUE; - else if (CAMEL_IS_OFFLINE_STORE (m->store) && - camel_offline_store_get_online ( - CAMEL_OFFLINE_STORE (m->store))) - online = TRUE; - } - if (online) - camel_store_noop_sync (m->store, cancellable, error); -} - -static void -ping_store_free (struct _ping_store_msg *m) -{ - g_object_unref (m->store); -} - -static MailMsgInfo ping_store_info = { - sizeof (struct _ping_store_msg), - (MailMsgDescFunc) ping_store_desc, - (MailMsgExecFunc) ping_store_exec, - (MailMsgDoneFunc) NULL, - (MailMsgFreeFunc) ping_store_free -}; - -static void -ping_store (CamelStore *store) -{ - CamelServiceConnectionStatus status; - CamelService *service; - struct _ping_store_msg *m; - - service = CAMEL_SERVICE (store); - status = camel_service_get_connection_status (service); - - if (status != CAMEL_SERVICE_CONNECTED) - return; - - m = mail_msg_new (&ping_store_info); - m->store = g_object_ref (store); - - mail_msg_slow_ordered_push (m); -} - -static gboolean -ping_cb (MailFolderCache *cache) -{ - g_mutex_lock (cache->priv->stores_mutex); - - g_hash_table_foreach (cache->priv->stores, (GHFunc) ping_store, NULL); - - g_mutex_unlock (cache->priv->stores_mutex); - - return TRUE; -} - -static gboolean -store_has_folder_hierarchy (CamelStore *store) -{ - CamelProvider *provider; - - g_return_val_if_fail (store != NULL, FALSE); - - provider = camel_service_get_provider (CAMEL_SERVICE (store)); - g_return_val_if_fail (provider != NULL, FALSE); - - return (provider->flags & (CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_EXTERNAL)) != 0; -} - -static void -store_go_online_cb (CamelStore *store, - GAsyncResult *result, - struct _update_data *ud) -{ - /* FIXME Not checking result for error. */ - - g_mutex_lock (ud->cache->priv->stores_mutex); - - if (g_hash_table_lookup (ud->cache->priv->stores, store) != NULL && - !g_cancellable_is_cancelled (ud->cancellable)) { - /* We're already in the store update list. */ - if (store_has_folder_hierarchy (store)) - camel_store_get_folder_info ( - store, NULL, - CAMEL_STORE_FOLDER_INFO_FAST | - CAMEL_STORE_FOLDER_INFO_RECURSIVE | - CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, - G_PRIORITY_DEFAULT, ud->cancellable, - (GAsyncReadyCallback) update_folders, ud); - } else { - /* The store vanished, that means we were probably cancelled, - * or at any rate, need to clean ourselves up. */ - if (ud->cancellable != NULL) - g_object_unref (ud->cancellable); - g_free (ud); - } - - g_mutex_unlock (ud->cache->priv->stores_mutex); -} - -static GList * -find_folder_uri (GQueue *queue, - CamelSession *session, - const gchar *folder_uri) -{ - GList *head, *link; - - head = g_queue_peek_head_link (queue); - - for (link = head; link != NULL; link = g_list_next (link)) - if (e_mail_folder_uri_equal (session, link->data, folder_uri)) - break; - - return link; -} - -struct _find_info { - const gchar *folder_uri; - struct _folder_info *fi; -}; - -static void -storeinfo_find_folder_info (CamelStore *store, - StoreInfo *si, - struct _find_info *fi) -{ - gchar *folder_name; - gboolean success; - - if (fi->fi != NULL) - return; - - success = e_mail_folder_uri_parse ( - camel_service_get_session (CAMEL_SERVICE (store)), - fi->folder_uri, NULL, &folder_name, NULL); - - if (success) { - fi->fi = g_hash_table_lookup (si->folders, folder_name); - g_free (folder_name); - } -} - -static void -mail_folder_cache_service_removed (EMailAccountStore *account_store, - CamelService *service, - MailFolderCache *cache) -{ - StoreInfo *si; - - if (cache->priv->stores == NULL) - return; - - g_mutex_lock (cache->priv->stores_mutex); - - si = g_hash_table_lookup (cache->priv->stores, service); - if (si != NULL) { - g_hash_table_remove (cache->priv->stores, service); - - g_signal_handlers_disconnect_matched ( - service, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, cache); - - g_hash_table_foreach ( - si->folders, (GHFunc) - unset_folder_info_hash, cache); - - store_info_free (si); - } - - g_mutex_unlock (cache->priv->stores_mutex); -} - -static void -mail_folder_cache_service_enabled (EMailAccountStore *account_store, - CamelService *service, - MailFolderCache *cache) -{ - mail_folder_cache_note_store ( - cache, CAMEL_STORE (service), NULL, NULL, NULL); -} - -static void -mail_folder_cache_service_disabled (EMailAccountStore *account_store, - CamelService *service, - MailFolderCache *cache) -{ - /* To the folder cache, disabling a service is the same as - * removing it. We keep a separate callback function only - * to use as a breakpoint target in a debugger. */ - mail_folder_cache_service_removed (account_store, service, cache); -} - -static void -mail_folder_cache_set_session (MailFolderCache *cache, - EMailSession *session) -{ - g_return_if_fail (E_IS_MAIL_SESSION (session)); - g_return_if_fail (cache->priv->session == NULL); - - cache->priv->session = session; - - g_object_add_weak_pointer ( - G_OBJECT (cache->priv->session), - &cache->priv->session); -} - -static void -mail_folder_cache_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SESSION: - mail_folder_cache_set_session ( - MAIL_FOLDER_CACHE (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_folder_cache_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_SESSION: - g_value_set_object ( - value, - mail_folder_cache_get_session ( - MAIL_FOLDER_CACHE (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -mail_folder_cache_dispose (GObject *object) -{ - MailFolderCachePrivate *priv; - - priv = MAIL_FOLDER_CACHE_GET_PRIVATE (object); - - if (priv->session != NULL) { - g_object_remove_weak_pointer ( - G_OBJECT (priv->session), &priv->session); - priv->session = NULL; - } - - if (priv->account_store != NULL) { - g_signal_handlers_disconnect_matched ( - priv->account_store, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, object); - g_object_unref (priv->account_store); - priv->account_store = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (mail_folder_cache_parent_class)->dispose (object); -} - -static void -mail_folder_cache_finalize (GObject *object) -{ - MailFolderCachePrivate *priv; - - priv = MAIL_FOLDER_CACHE_GET_PRIVATE (object); - - g_hash_table_destroy (priv->stores); - g_mutex_free (priv->stores_mutex); - - if (priv->ping_id > 0) { - g_source_remove (priv->ping_id); - priv->ping_id = 0; - } - - if (priv->update_id > 0) { - g_source_remove (priv->update_id); - priv->update_id = 0; - } - - while (!g_queue_is_empty (&priv->local_folder_uris)) - g_free (g_queue_pop_head (&priv->local_folder_uris)); - - while (!g_queue_is_empty (&priv->remote_folder_uris)) - g_free (g_queue_pop_head (&priv->remote_folder_uris)); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (mail_folder_cache_parent_class)->finalize (object); -} - -static void -mail_folder_cache_constructed (GObject *object) -{ - MailFolderCache *cache; - EMailSession *session; - EMailAccountStore *account_store; - - cache = MAIL_FOLDER_CACHE (object); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (mail_folder_cache_parent_class)->constructed (object); - - session = mail_folder_cache_get_session (cache); - account_store = e_mail_session_get_account_store (session); - - cache->priv->account_store = g_object_ref (account_store); - - /* No need to connect to "service-added" emissions since it's - * always immediately followed by either "service-enabled" or - * "service-disabled". */ - - g_signal_connect ( - account_store, "service-removed", - G_CALLBACK (mail_folder_cache_service_removed), cache); - - g_signal_connect ( - account_store, "service-enabled", - G_CALLBACK (mail_folder_cache_service_enabled), cache); - - g_signal_connect ( - account_store, "service-disabled", - G_CALLBACK (mail_folder_cache_service_disabled), cache); - -} - -static void -mail_folder_cache_folder_available (MailFolderCache *cache, - CamelStore *store, - const gchar *folder_name) -{ - CamelService *service; - CamelSession *session; - CamelProvider *provider; - GQueue *queue; - gchar *folder_uri; - - /* Disregard virtual stores. */ - if (CAMEL_IS_VEE_STORE (store)) - return; - - /* Disregard virtual Junk folders. */ - if (store->flags & CAMEL_STORE_VJUNK) - if (g_strcmp0 (folder_name, CAMEL_VJUNK_NAME) == 0) - return; - - /* Disregard virtual Trash folders. */ - if (store->flags & CAMEL_STORE_VTRASH) - if (g_strcmp0 (folder_name, CAMEL_VTRASH_NAME) == 0) - return; - - service = CAMEL_SERVICE (store); - session = camel_service_get_session (service); - provider = camel_service_get_provider (service); - - /* Reuse the stores mutex just because it's handy. */ - g_mutex_lock (cache->priv->stores_mutex); - - folder_uri = e_mail_folder_uri_build (store, folder_name); - - if (provider->flags & CAMEL_PROVIDER_IS_REMOTE) - queue = &cache->priv->remote_folder_uris; - else - queue = &cache->priv->local_folder_uris; - - if (find_folder_uri (queue, session, folder_uri) == NULL) - g_queue_push_tail (queue, folder_uri); - else - g_free (folder_uri); - - g_mutex_unlock (cache->priv->stores_mutex); -} - -static void -mail_folder_cache_folder_unavailable (MailFolderCache *cache, - CamelStore *store, - const gchar *folder_name) -{ - CamelService *service; - CamelSession *session; - CamelProvider *provider; - GQueue *queue; - GList *link; - gchar *folder_uri; - - /* Disregard virtual stores. */ - if (CAMEL_IS_VEE_STORE (store)) - return; - - /* Disregard virtual Junk folders. */ - if (store->flags & CAMEL_STORE_VJUNK) - if (g_strcmp0 (folder_name, CAMEL_VJUNK_NAME) == 0) - return; - - /* Disregard virtual Trash folders. */ - if (store->flags & CAMEL_STORE_VTRASH) - if (g_strcmp0 (folder_name, CAMEL_VTRASH_NAME) == 0) - return; - - service = CAMEL_SERVICE (store); - session = camel_service_get_session (service); - provider = camel_service_get_provider (service); - - /* Reuse the stores mutex just because it's handy. */ - g_mutex_lock (cache->priv->stores_mutex); - - folder_uri = e_mail_folder_uri_build (store, folder_name); - - if (provider->flags & CAMEL_PROVIDER_IS_REMOTE) - queue = &cache->priv->remote_folder_uris; - else - queue = &cache->priv->local_folder_uris; - - link = find_folder_uri (queue, session, folder_uri); - if (link != NULL) { - g_free (link->data); - g_queue_delete_link (queue, link); - } - - g_free (folder_uri); - - g_mutex_unlock (cache->priv->stores_mutex); -} - -static void -mail_folder_cache_folder_deleted (MailFolderCache *cache, - CamelStore *store, - const gchar *folder_name) -{ - CamelService *service; - CamelSession *session; - GQueue *queue; - GList *link; - gchar *folder_uri; - - /* Disregard virtual stores. */ - if (CAMEL_IS_VEE_STORE (store)) - return; - - /* Disregard virtual Junk folders. */ - if (store->flags & CAMEL_STORE_VJUNK) - if (g_strcmp0 (folder_name, CAMEL_VJUNK_NAME) == 0) - return; - - /* Disregard virtual Trash folders. */ - if (store->flags & CAMEL_STORE_VTRASH) - if (g_strcmp0 (folder_name, CAMEL_VTRASH_NAME) == 0) - return; - - service = CAMEL_SERVICE (store); - session = camel_service_get_session (service); - - /* Reuse the stores mutex just because it's handy. */ - g_mutex_lock (cache->priv->stores_mutex); - - folder_uri = e_mail_folder_uri_build (store, folder_name); - - queue = &cache->priv->local_folder_uris; - link = find_folder_uri (queue, session, folder_uri); - if (link != NULL) { - g_free (link->data); - g_queue_delete_link (queue, link); - } - - queue = &cache->priv->remote_folder_uris; - link = find_folder_uri (queue, session, folder_uri); - if (link != NULL) { - g_free (link->data); - g_queue_delete_link (queue, link); - } - - g_free (folder_uri); - - g_mutex_unlock (cache->priv->stores_mutex); -} - -static void -mail_folder_cache_class_init (MailFolderCacheClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (MailFolderCachePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = mail_folder_cache_set_property; - object_class->get_property = mail_folder_cache_get_property; - object_class->dispose = mail_folder_cache_dispose; - object_class->finalize = mail_folder_cache_finalize; - object_class->constructed = mail_folder_cache_constructed; - - class->folder_available = mail_folder_cache_folder_available; - class->folder_unavailable = mail_folder_cache_folder_unavailable; - class->folder_deleted = mail_folder_cache_folder_deleted; - - g_object_class_install_property ( - object_class, - PROP_SESSION, - g_param_spec_object ( - "session", - "Session", - "Mail session", - E_TYPE_MAIL_SESSION, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - /** - * MailFolderCache::folder-available - * @store: the #CamelStore containing the folder - * @folder_name: the name of the folder - * - * Emitted when a folder becomes available - **/ - signals[FOLDER_AVAILABLE] = g_signal_new ( - "folder-available", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MailFolderCacheClass, folder_available), - NULL, NULL, /* accumulator */ - e_marshal_VOID__OBJECT_STRING, - G_TYPE_NONE, 2, - CAMEL_TYPE_STORE, - G_TYPE_STRING); - - /** - * MailFolderCache::folder-unavailable - * @store: the #CamelStore containing the folder - * @folder_name: the name of the folder - * - * Emitted when a folder becomes unavailable. This represents a - * transient condition. See MailFolderCache::folder-deleted to be - * notified when a folder is permanently removed. - **/ - signals[FOLDER_UNAVAILABLE] = g_signal_new ( - "folder-unavailable", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MailFolderCacheClass, folder_unavailable), - NULL, NULL, /* accumulator */ - e_marshal_VOID__OBJECT_STRING, - G_TYPE_NONE, 2, - CAMEL_TYPE_STORE, - G_TYPE_STRING); - - /** - * MailFolderCache::folder-deleted - * @store: the #CamelStore containing the folder - * @folder_name: the name of the folder - * - * Emitted when a folder is deleted - **/ - signals[FOLDER_DELETED] = g_signal_new ( - "folder-deleted", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MailFolderCacheClass, folder_deleted), - NULL, NULL, /* accumulator */ - e_marshal_VOID__OBJECT_STRING, - G_TYPE_NONE, 2, - CAMEL_TYPE_STORE, - G_TYPE_STRING); - - /** - * MailFolderCache::folder-renamed - * @store: the #CamelStore containing the folder - * @old_folder_name: the old name of the folder - * @new_folder_name: the new name of the folder - * - * Emitted when a folder is renamed - **/ - signals[FOLDER_RENAMED] = g_signal_new ( - "folder-renamed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MailFolderCacheClass, folder_renamed), - NULL, NULL, /* accumulator */ - e_marshal_VOID__OBJECT_STRING_STRING, - G_TYPE_NONE, 3, - CAMEL_TYPE_STORE, - G_TYPE_STRING, - G_TYPE_STRING); - - /** - * MailFolderCache::folder-unread-updated - * @store: the #CamelStore containing the folder - * @folder_name: the name of the folder - * @unread: the number of unread mails in the folder - * - * Emitted when a we receive an update to the unread count for a folder - **/ - signals[FOLDER_UNREAD_UPDATED] = g_signal_new ( - "folder-unread-updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MailFolderCacheClass, folder_unread_updated), - NULL, NULL, /* accumulator */ - e_marshal_VOID__OBJECT_STRING_INT, - G_TYPE_NONE, 3, - CAMEL_TYPE_STORE, - G_TYPE_STRING, - G_TYPE_INT); - - /** - * MailFolderCache::folder-changed - * @store: the #CamelStore containing the folder - * @folder_name: the name of the folder - * @new_messages: the number of new messages for the folder - * @msg_uid: uid of the new message, or NULL - * @msg_sender: sender of the new message, or NULL - * @msg_subject: subject of the new message, or NULL - * - * Emitted when a folder has changed. If @new_messages is not - * exactly 1, @msg_uid, @msg_sender, and @msg_subject will be NULL. - **/ - signals[FOLDER_CHANGED] = g_signal_new ( - "folder-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MailFolderCacheClass, folder_changed), - NULL, NULL, /* accumulator */ - e_marshal_VOID__OBJECT_STRING_INT_STRING_STRING_STRING, - G_TYPE_NONE, 6, - CAMEL_TYPE_STORE, - G_TYPE_STRING, - G_TYPE_INT, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); -} - -static void -mail_folder_cache_init (MailFolderCache *cache) -{ - const gchar *buf; - guint timeout; - - cache->priv = MAIL_FOLDER_CACHE_GET_PRIVATE (cache); - - /* initialize values */ - cache->priv->stores = g_hash_table_new (NULL, NULL); - cache->priv->stores_mutex = g_mutex_new (); - - g_queue_init (&cache->priv->updates); - cache->priv->count_sent = getenv("EVOLUTION_COUNT_SENT") != NULL; - cache->priv->count_trash = getenv("EVOLUTION_COUNT_TRASH") != NULL; - - buf = getenv ("EVOLUTION_PING_TIMEOUT"); - timeout = buf ? strtoul (buf, NULL, 10) : 600; - cache->priv->ping_id = g_timeout_add_seconds ( - timeout, (GSourceFunc) ping_cb, cache); - - g_queue_init (&cache->priv->local_folder_uris); - g_queue_init (&cache->priv->remote_folder_uris); -} - -MailFolderCache * -mail_folder_cache_new (EMailSession *session) -{ - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - return g_object_new ( - MAIL_TYPE_FOLDER_CACHE, - "session", session, NULL); -} - -EMailSession * -mail_folder_cache_get_session (MailFolderCache *cache) -{ - g_return_val_if_fail (MAIL_IS_FOLDER_CACHE (cache), NULL); - - return E_MAIL_SESSION (cache->priv->session); -} - -/** - * mail_folder_cache_note_store: - * - * Add a store whose folders should appear in the shell The folders are scanned - * from the store, and/or added at runtime via the folder_created event. The - * @done function returns if we can free folder info. - */ -void -mail_folder_cache_note_store (MailFolderCache *cache, - CamelStore *store, - GCancellable *cancellable, - NoteDoneFunc done, - gpointer data) -{ - CamelSession *session; - StoreInfo *si; - struct _update_data *ud; - gint hook = 0; - - g_return_if_fail (MAIL_IS_FOLDER_CACHE (cache)); - g_return_if_fail (CAMEL_IS_STORE (store)); - - session = camel_service_get_session (CAMEL_SERVICE (store)); - - g_mutex_lock (cache->priv->stores_mutex); - - si = g_hash_table_lookup (cache->priv->stores, store); - if (si == NULL) { - si = store_info_new (store); - g_hash_table_insert (cache->priv->stores, store, si); - hook = TRUE; - } - - ud = g_malloc0 (sizeof (*ud)); - ud->done = done; - ud->data = data; - ud->cache = cache; - - if (G_IS_CANCELLABLE (cancellable)) - ud->cancellable = g_object_ref (cancellable); - - /* We might get a race when setting up a store, such that it is - * still left in offline mode, after we've gone online. This - * catches and fixes it up when the shell opens us. */ - if (CAMEL_IS_DISCO_STORE (store)) { - if (camel_session_get_online (session) && - camel_disco_store_status (CAMEL_DISCO_STORE (store)) == - CAMEL_DISCO_STORE_OFFLINE) { - e_mail_store_go_online ( - store, G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) store_go_online_cb, ud); - } else { - goto normal_setup; - } - } else if (CAMEL_IS_OFFLINE_STORE (store)) { - if (camel_session_get_online (session) && - !camel_offline_store_get_online ( - CAMEL_OFFLINE_STORE (store))) { - e_mail_store_go_online ( - store, G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) store_go_online_cb, ud); - } else { - goto normal_setup; - } - } else { - normal_setup: - if (store_has_folder_hierarchy (store)) - camel_store_get_folder_info ( - store, NULL, - CAMEL_STORE_FOLDER_INFO_FAST | - CAMEL_STORE_FOLDER_INFO_RECURSIVE | - CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) update_folders, ud); - } - - g_queue_push_tail (&si->folderinfo_updates, ud); - - g_mutex_unlock (cache->priv->stores_mutex); - - /* there is potential for race here, but it is safe as we check - * for the store anyway */ - if (hook) { - g_signal_connect ( - store, "folder-opened", - G_CALLBACK (store_folder_opened_cb), cache); - g_signal_connect ( - store, "folder-created", - G_CALLBACK (store_folder_created_cb), cache); - g_signal_connect ( - store, "folder-deleted", - G_CALLBACK (store_folder_deleted_cb), cache); - g_signal_connect ( - store, "folder-renamed", - G_CALLBACK (store_folder_renamed_cb), cache); - } - - if (hook && CAMEL_IS_SUBSCRIBABLE (store)) { - g_signal_connect ( - store, "folder-subscribed", - G_CALLBACK (store_folder_subscribed_cb), cache); - g_signal_connect ( - store, "folder-unsubscribed", - G_CALLBACK (store_folder_unsubscribed_cb), cache); - } -} - -/** - * mail_folder_cache_note_folder: - * - * When a folder has been opened, notify it for watching. The folder must have - * already been created on the store (which has already been noted) before the - * folder can be opened - */ -void -mail_folder_cache_note_folder (MailFolderCache *cache, - CamelFolder *folder) -{ - CamelStore *parent_store; - StoreInfo *si; - struct _folder_info *mfi; - const gchar *full_name; - - g_return_if_fail (MAIL_IS_FOLDER_CACHE (cache)); - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - full_name = camel_folder_get_full_name (folder); - parent_store = camel_folder_get_parent_store (folder); - - g_mutex_lock (cache->priv->stores_mutex); - if (cache->priv->stores == NULL - || (si = g_hash_table_lookup (cache->priv->stores, parent_store)) == NULL - || (mfi = g_hash_table_lookup (si->folders, full_name)) == NULL) { - w(g_warning("Noting folder before store initialised")); - g_mutex_unlock (cache->priv->stores_mutex); - return; - } - - /* dont do anything if we already have this */ - if (mfi->folder == folder) { - g_mutex_unlock (cache->priv->stores_mutex); - return; - } - - mfi->folder = folder; - - g_object_add_weak_pointer (G_OBJECT (folder), &mfi->folder); - - update_1folder (cache, mfi, 0, NULL, NULL, NULL, NULL); - - g_mutex_unlock (cache->priv->stores_mutex); - - g_signal_connect ( - folder, "changed", - G_CALLBACK (folder_changed_cb), cache); -} - -/** - * mail_folder_cache_get_folder_from_uri: - * - * Gets the #CamelFolder for the supplied @uri. - * - * Returns: %TRUE if the URI is available, folderp is set to a reffed - * folder if the folder has also already been opened - */ -gboolean -mail_folder_cache_get_folder_from_uri (MailFolderCache *cache, - const gchar *uri, - CamelFolder **folderp) -{ - struct _find_info fi = { uri, NULL }; - - if (cache->priv->stores == NULL) - return FALSE; - - g_mutex_lock (cache->priv->stores_mutex); - g_hash_table_foreach ( - cache->priv->stores, (GHFunc) - storeinfo_find_folder_info, &fi); - if (folderp) { - if (fi.fi && fi.fi->folder) - *folderp = g_object_ref (fi.fi->folder); - else - *folderp = NULL; - } - g_mutex_unlock (cache->priv->stores_mutex); - - return fi.fi != NULL; -} - -gboolean -mail_folder_cache_get_folder_info_flags (MailFolderCache *cache, - CamelFolder *folder, - CamelFolderInfoFlags *flags) -{ - struct _find_info fi = { NULL, NULL }; - gchar *folder_uri; - - if (cache->priv->stores == NULL) - return FALSE; - - folder_uri = e_mail_folder_uri_from_folder (folder); - fi.folder_uri = folder_uri; - - g_mutex_lock (cache->priv->stores_mutex); - g_hash_table_foreach ( - cache->priv->stores, (GHFunc) - storeinfo_find_folder_info, &fi); - if (flags) { - if (fi.fi) - *flags = fi.fi->flags; - else - *flags = 0; - } - g_mutex_unlock (cache->priv->stores_mutex); - - g_free (folder_uri); - - return fi.fi != NULL; -} - -/* Returns whether folder 'folder' has children based on folder_info->child property. - * If not found returns FALSE and sets 'found' to FALSE, if not NULL. */ -gboolean -mail_folder_cache_get_folder_has_children (MailFolderCache *cache, - CamelFolder *folder, - gboolean *found) -{ - struct _find_info fi = { NULL, NULL }; - gchar *folder_uri; - - g_return_val_if_fail (cache != NULL, FALSE); - g_return_val_if_fail (folder != NULL, FALSE); - - if (cache->priv->stores == NULL) - return FALSE; - - folder_uri = e_mail_folder_uri_from_folder (folder); - fi.folder_uri = folder_uri; - - g_mutex_lock (cache->priv->stores_mutex); - g_hash_table_foreach ( - cache->priv->stores, (GHFunc) - storeinfo_find_folder_info, &fi); - if (found) - *found = fi.fi != NULL; - g_mutex_unlock (cache->priv->stores_mutex); - - g_free (folder_uri); - - return fi.fi != NULL && fi.fi->has_children; -} - -void -mail_folder_cache_get_local_folder_uris (MailFolderCache *self, - GQueue *out_queue) -{ - GList *head, *link; - - g_return_if_fail (MAIL_IS_FOLDER_CACHE (self)); - g_return_if_fail (out_queue != NULL); - - /* Reuse the stores mutex just because it's handy. */ - g_mutex_lock (self->priv->stores_mutex); - - head = g_queue_peek_head_link (&self->priv->local_folder_uris); - - for (link = head; link != NULL; link = g_list_next (link)) - g_queue_push_tail (out_queue, g_strdup (link->data)); - - g_mutex_unlock (self->priv->stores_mutex); -} - -void -mail_folder_cache_get_remote_folder_uris (MailFolderCache *self, - GQueue *out_queue) -{ - GList *head, *link; - - g_return_if_fail (MAIL_IS_FOLDER_CACHE (self)); - g_return_if_fail (out_queue != NULL); - - /* Reuse the stores mutex just because it's handy. */ - g_mutex_lock (self->priv->stores_mutex); - - head = g_queue_peek_head_link (&self->priv->remote_folder_uris); - - for (link = head; link != NULL; link = g_list_next (link)) - g_queue_push_tail (out_queue, g_strdup (link->data)); - - g_mutex_unlock (self->priv->stores_mutex); -} diff --git a/mail/mail-folder-cache.h b/mail/mail-folder-cache.h deleted file mode 100644 index 8e9fa34fe5..0000000000 --- a/mail/mail-folder-cache.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Peter Williams <peterw@ximian.com> - * Michael Zucchi <notzed@ximian.com> - * Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2009 Intel Corporation - * - */ - -#ifndef MAIL_FOLDER_CACHE_H -#define MAIL_FOLDER_CACHE_H - -#include <camel/camel.h> - -/* Standard GObject macros */ -#define MAIL_TYPE_FOLDER_CACHE \ - (mail_folder_cache_get_type ()) -#define MAIL_FOLDER_CACHE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), MAIL_TYPE_FOLDER_CACHE, MailFolderCache)) -#define MAIL_FOLDER_CACHE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), MAIL_TYPE_FOLDER_CACHE, MailFolderCacheClass)) -#define MAIL_IS_FOLDER_CACHE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), MAIL_TYPE_FOLDER_CACHE)) -#define MAIL_IS_FOLDER_CACHE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), MAIL_TYPE_FOLDER_CACHE)) -#define MAIL_FOLDER_CACHE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), MAIL_TYPE_FOLDER_CACHE, MailFolderCacheClass)) - -G_BEGIN_DECLS - -/* Avoid a circular dependency. */ -struct _EMailSession; - -typedef struct _MailFolderCache MailFolderCache; -typedef struct _MailFolderCacheClass MailFolderCacheClass; -typedef struct _MailFolderCachePrivate MailFolderCachePrivate; - -/** - * NoteDoneFunc: - * - * The signature of a function to be registered as a callback for - * mail_folder_cache_note_store() - */ -typedef gboolean (*NoteDoneFunc) (MailFolderCache *cache, - CamelStore *store, - CamelFolderInfo *info, - gpointer data); - -/** - * MailFolderCache: - * - * Contains only private data that should be read and manipulated using the - * functions below. - */ -struct _MailFolderCache { - GObject parent; - MailFolderCachePrivate *priv; -}; - -struct _MailFolderCacheClass { - GObjectClass parent_class; - - /* Signals */ - void (*folder_available) (MailFolderCache *cache, - CamelStore *store, - const gchar *folder_name); - void (*folder_unavailable) (MailFolderCache *cache, - CamelStore *store, - const gchar *folder_name); - void (*folder_deleted) (MailFolderCache *cache, - CamelStore *store, - const gchar *folder_name); - void (*folder_renamed) (MailFolderCache *cache, - CamelStore *store, - const gchar *old_folder_name, - const gchar *new_folder_name); - void (*folder_unread_updated) - (MailFolderCache *cache, - CamelStore *store, - const gchar *folder_name, - gint unread); - void (*folder_changed) (MailFolderCache *cache, - CamelStore *store, - gint new_messages, - const gchar *msg_uid, - const gchar *msg_sender, - const gchar *msg_subject); -}; - -GType mail_folder_cache_get_type (void) G_GNUC_CONST; -MailFolderCache * - mail_folder_cache_new (struct _EMailSession *session); -struct _EMailSession * - mail_folder_cache_get_session (MailFolderCache *cache); -void mail_folder_cache_note_store (MailFolderCache *cache, - CamelStore *store, - GCancellable *cancellable, - NoteDoneFunc done, - gpointer data); -void mail_folder_cache_note_folder (MailFolderCache *cache, - CamelFolder *folder); -gboolean mail_folder_cache_get_folder_from_uri - (MailFolderCache *cache, - const gchar *uri, - CamelFolder **folderp); -gboolean mail_folder_cache_get_folder_info_flags - (MailFolderCache *cache, - CamelFolder *folder, - CamelFolderInfoFlags *flags); -gboolean mail_folder_cache_get_folder_has_children - (MailFolderCache *cache, - CamelFolder *folder, - gboolean *found); -void mail_folder_cache_get_local_folder_uris - (MailFolderCache *cache, - GQueue *out_queue); -void mail_folder_cache_get_remote_folder_uris - (MailFolderCache *cache, - GQueue *out_queue); - -G_END_DECLS - -#endif /* MAIL_FOLDER_CACHE_H */ diff --git a/mail/mail-mt.c b/mail/mail-mt.c deleted file mode 100644 index 526571f61f..0000000000 --- a/mail/mail-mt.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <gtk/gtk.h> - -#include <libedataserver/e-flag.h> - -#include <e-util/e-alert-sink.h> -#include <shell/e-shell-view.h> - -#include "mail-mt.h" - -/*#define MALLOC_CHECK*/ -#define d(x) - -/* XXX This is a dirty hack on a dirty hack. We really need - * to rework or get rid of the functions that use this. */ -const gchar *shell_builtin_backend = "mail"; - -static guint mail_msg_seq; /* sequence number of each message */ - -/* Table of active messages. Must hold mail_msg_lock to access. */ -static GHashTable *mail_msg_active_table; -static GMutex *mail_msg_lock; -static GCond *mail_msg_cond; - -static void -mail_msg_cancelled (CamelOperation *operation, - gpointer user_data) -{ - mail_msg_cancel (GPOINTER_TO_UINT (user_data)); -} - -static gboolean -mail_msg_submit (EActivity *activity) -{ - EShell *shell; - EShellBackend *shell_backend; - - shell = e_shell_get_default (); - shell_backend = e_shell_get_backend_by_name ( - shell, shell_builtin_backend); - - e_shell_backend_add_activity (shell_backend, activity); - - return FALSE; -} - -gpointer -mail_msg_new (MailMsgInfo *info) -{ - MailMsg *msg; - GCancellable *cancellable; - - g_mutex_lock (mail_msg_lock); - - msg = g_slice_alloc0 (info->size); - msg->info = info; - msg->ref_count = 1; - msg->seq = mail_msg_seq++; - msg->activity = e_activity_new (); - - cancellable = camel_operation_new (); - - e_activity_set_percent (msg->activity, 0.0); - e_activity_set_cancellable (msg->activity, cancellable); - - g_signal_connect ( - cancellable, "cancelled", - G_CALLBACK (mail_msg_cancelled), - GINT_TO_POINTER (msg->seq)); - - g_object_unref (cancellable); - - g_hash_table_insert ( - mail_msg_active_table, GINT_TO_POINTER (msg->seq), msg); - - d(printf("New message %p\n", msg)); - - g_mutex_unlock (mail_msg_lock); - - return msg; -} - -#ifdef MALLOC_CHECK -#include <mcheck.h> - -static void -checkmem (gpointer p) -{ - if (p) { - gint status = mprobe (p); - - switch (status) { - case MCHECK_HEAD: - printf("Memory underrun at %p\n", p); - abort (); - case MCHECK_TAIL: - printf("Memory overrun at %p\n", p); - abort (); - case MCHECK_FREE: - printf("Double free %p\n", p); - abort (); - } - } -} -#endif - -static gboolean -mail_msg_free (MailMsg *mail_msg) -{ - /* This is an idle callback. */ - - if (mail_msg->activity != NULL) - g_object_unref (mail_msg->activity); - - if (mail_msg->error != NULL) - g_error_free (mail_msg->error); - - g_slice_free1 (mail_msg->info->size, mail_msg); - - return FALSE; -} - -gpointer -mail_msg_ref (gpointer msg) -{ - MailMsg *mail_msg = msg; - - g_return_val_if_fail (mail_msg != NULL, msg); - g_return_val_if_fail (mail_msg->ref_count > 0, msg); - - g_atomic_int_inc (&mail_msg->ref_count); - - return msg; -} - -void -mail_msg_unref (gpointer msg) -{ - MailMsg *mail_msg = msg; - - g_return_if_fail (mail_msg != NULL); - g_return_if_fail (mail_msg->ref_count > 0); - - if (g_atomic_int_dec_and_test (&mail_msg->ref_count)) { - -#ifdef MALLOC_CHECK - checkmem (mail_msg); - checkmem (mail_msg->cancel); - checkmem (mail_msg->priv); -#endif - d(printf("Free message %p\n", msg)); - - if (mail_msg->info->free) - mail_msg->info->free (mail_msg); - - g_mutex_lock (mail_msg_lock); - - g_hash_table_remove ( - mail_msg_active_table, - GINT_TO_POINTER (mail_msg->seq)); - g_cond_broadcast (mail_msg_cond); - - g_mutex_unlock (mail_msg_lock); - - /* Destroy the message from an idle callback - * so we know we're in the main loop thread. */ - g_idle_add ((GSourceFunc) mail_msg_free, mail_msg); - } -} - -void -mail_msg_check_error (gpointer msg) -{ - EShell *shell; - EShellView *shell_view; - EShellWindow *shell_window = NULL; - EShellContent *shell_content; - GtkApplication *application; - MailMsg *m = msg; - gchar *what; - GList *list, *iter; - -#ifdef MALLOC_CHECK - checkmem (m); - checkmem (m->cancel); - checkmem (m->priv); -#endif - - if (e_activity_handle_cancellation (m->activity, m->error)) - return; - - e_activity_set_state (m->activity, E_ACTIVITY_COMPLETED); - - if (m->error == NULL) - return; - - /* XXX Hmm, no explanation of why this is needed. It looks like - * a lame hack and will be removed at some point, if only to - * reintroduce whatever issue made this necessary so we can - * document it the source code this time. */ - if (g_error_matches (m->error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INVALID_UID)) - return; - - shell = e_shell_get_default (); - application = GTK_APPLICATION (shell); - list = gtk_application_get_windows (application); - - /* Find the most recently used EShellWindow. */ - for (iter = list; iter != NULL; iter = g_list_next (iter)) { - if (E_IS_SHELL_WINDOW (iter->data)) { - shell_window = E_SHELL_WINDOW (iter->data); - break; - } - } - - /* If we can't find an EShellWindow then... well, screw it. */ - if (shell_window == NULL) - return; - - shell_view = e_shell_window_get_shell_view ( - shell_window, shell_builtin_backend); - shell_content = e_shell_view_get_shell_content (shell_view); - - if (m->info->desc && (what = m->info->desc (m))) { - e_alert_submit ( - E_ALERT_SINK (shell_content), - "mail:async-error", what, - m->error->message, NULL); - g_free (what); - } else - e_alert_submit ( - E_ALERT_SINK (shell_content), - "mail:async-error-nodescribe", - m->error->message, NULL); -} - -void -mail_msg_cancel (guint msgid) -{ - MailMsg *msg; - GCancellable *cancellable = NULL; - - g_mutex_lock (mail_msg_lock); - - msg = g_hash_table_lookup ( - mail_msg_active_table, GINT_TO_POINTER (msgid)); - - /* Hold a reference to the GCancellable so it doesn't finalize - * itself on us between unlocking the mutex and cancelling. */ - if (msg != NULL) { - cancellable = e_activity_get_cancellable (msg->activity); - if (g_cancellable_is_cancelled (cancellable)) - cancellable = NULL; - else - g_object_ref (cancellable); - } - - g_mutex_unlock (mail_msg_lock); - - if (cancellable != NULL) { - g_cancellable_cancel (cancellable); - g_object_unref (cancellable); - } -} - -gboolean -mail_msg_active (void) -{ - gboolean active; - - g_mutex_lock (mail_msg_lock); - active = g_hash_table_size (mail_msg_active_table) > 0; - g_mutex_unlock (mail_msg_lock); - - return active; -} - -/* **************************************** */ - -static GHookList cancel_hook_list; - -GHook * -mail_cancel_hook_add (GHookFunc func, - gpointer data) -{ - GHook *hook; - - g_mutex_lock (mail_msg_lock); - - if (!cancel_hook_list.is_setup) - g_hook_list_init (&cancel_hook_list, sizeof (GHook)); - - hook = g_hook_alloc (&cancel_hook_list); - hook->func = func; - hook->data = data; - - g_hook_append (&cancel_hook_list, hook); - - g_mutex_unlock (mail_msg_lock); - - return hook; -} - -void -mail_cancel_hook_remove (GHook *hook) -{ - g_mutex_lock (mail_msg_lock); - - g_return_if_fail (cancel_hook_list.is_setup); - g_hook_destroy_link (&cancel_hook_list, hook); - - g_mutex_unlock (mail_msg_lock); -} - -void -mail_cancel_all (void) -{ - camel_operation_cancel_all (); - - g_mutex_lock (mail_msg_lock); - - if (cancel_hook_list.is_setup) - g_hook_list_invoke (&cancel_hook_list, FALSE); - - g_mutex_unlock (mail_msg_lock); -} - -static guint idle_source_id = 0; -G_LOCK_DEFINE_STATIC (idle_source_id); -static GAsyncQueue *main_loop_queue = NULL; -static GAsyncQueue *msg_reply_queue = NULL; -static GThread *main_thread = NULL; - -static gboolean -mail_msg_idle_cb (void) -{ - MailMsg *msg; - - g_return_val_if_fail (main_loop_queue != NULL, FALSE); - g_return_val_if_fail (msg_reply_queue != NULL, FALSE); - - G_LOCK (idle_source_id); - idle_source_id = 0; - G_UNLOCK (idle_source_id); - /* check the main loop queue */ - while ((msg = g_async_queue_try_pop (main_loop_queue)) != NULL) { - GCancellable *cancellable; - - cancellable = e_activity_get_cancellable (msg->activity); - - g_idle_add_full ( - G_PRIORITY_DEFAULT, - (GSourceFunc) mail_msg_submit, - g_object_ref (msg->activity), - (GDestroyNotify) g_object_unref); - if (msg->info->exec != NULL) - msg->info->exec (msg, cancellable, &msg->error); - if (msg->info->done != NULL) - msg->info->done (msg); - mail_msg_unref (msg); - } - - /* check the reply queue */ - while ((msg = g_async_queue_try_pop (msg_reply_queue)) != NULL) { - if (msg->info->done != NULL) - msg->info->done (msg); - mail_msg_check_error (msg); - mail_msg_unref (msg); - } - return FALSE; -} - -static void -mail_msg_proxy (MailMsg *msg) -{ - GCancellable *cancellable; - - cancellable = e_activity_get_cancellable (msg->activity); - - if (msg->info->desc != NULL) { - gchar *text = msg->info->desc (msg); - camel_operation_push_message (cancellable, "%s", text); - g_free (text); - } - - g_idle_add_full ( - G_PRIORITY_DEFAULT, - (GSourceFunc) mail_msg_submit, - g_object_ref (msg->activity), - (GDestroyNotify) g_object_unref); - - if (msg->info->exec != NULL) - msg->info->exec (msg, cancellable, &msg->error); - - if (msg->info->desc != NULL) - camel_operation_pop_message (cancellable); - - g_async_queue_push (msg_reply_queue, msg); - - G_LOCK (idle_source_id); - if (idle_source_id == 0) - idle_source_id = g_idle_add ( - (GSourceFunc) mail_msg_idle_cb, NULL); - G_UNLOCK (idle_source_id); -} - -void -mail_msg_init (void) -{ - mail_msg_lock = g_mutex_new (); - mail_msg_cond = g_cond_new (); - - main_loop_queue = g_async_queue_new (); - msg_reply_queue = g_async_queue_new (); - - mail_msg_active_table = g_hash_table_new (NULL, NULL); - main_thread = g_thread_self (); -} - -static gint -mail_msg_compare (const MailMsg *msg1, - const MailMsg *msg2) -{ - gint priority1 = msg1->priority; - gint priority2 = msg2->priority; - - if (priority1 == priority2) - return 0; - - return (priority1 < priority2) ? 1 : -1; -} - -static gpointer -create_thread_pool (gpointer data) -{ - GThreadPool *thread_pool; - gint max_threads = GPOINTER_TO_INT (data); - - /* once created, run forever */ - thread_pool = g_thread_pool_new ( - (GFunc) mail_msg_proxy, NULL, max_threads, FALSE, NULL); - g_thread_pool_set_sort_function ( - thread_pool, (GCompareDataFunc) mail_msg_compare, NULL); - - return thread_pool; -} - -void -mail_msg_main_loop_push (gpointer msg) -{ - g_async_queue_push_sorted (main_loop_queue, msg, - (GCompareDataFunc) mail_msg_compare, NULL); - - G_LOCK (idle_source_id); - if (idle_source_id == 0) - idle_source_id = g_idle_add ( - (GSourceFunc) mail_msg_idle_cb, NULL); - G_UNLOCK (idle_source_id); -} - -void -mail_msg_unordered_push (gpointer msg) -{ - static GOnce once = G_ONCE_INIT; - - g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (10)); - - g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL); -} - -void -mail_msg_fast_ordered_push (gpointer msg) -{ - static GOnce once = G_ONCE_INIT; - - g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (1)); - - g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL); -} - -void -mail_msg_slow_ordered_push (gpointer msg) -{ - static GOnce once = G_ONCE_INIT; - - g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (1)); - - g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL); -} - -gboolean -mail_in_main_thread (void) -{ - return (g_thread_self () == main_thread); -} - -/* ********************************************************************** */ - -struct _call_msg { - MailMsg base; - - mail_call_t type; - MailMainFunc func; - gpointer ret; - va_list ap; - EFlag *done; -}; - -static void -do_call (struct _call_msg *m, - GCancellable *cancellable, - GError **error) -{ - gpointer p1, *p2, *p3, *p4, *p5; - gint i1; - va_list ap; - - G_VA_COPY (ap, m->ap); - - switch (m->type) { - case MAIL_CALL_p_p: - p1 = va_arg (ap, gpointer ); - m->ret = m->func (p1); - break; - case MAIL_CALL_p_pp: - p1 = va_arg (ap, gpointer ); - p2 = va_arg (ap, gpointer ); - m->ret = m->func (p1, p2); - break; - case MAIL_CALL_p_ppp: - p1 = va_arg (ap, gpointer ); - p2 = va_arg (ap, gpointer ); - p3 = va_arg (ap, gpointer ); - m->ret = m->func (p1, p2, p3); - break; - case MAIL_CALL_p_pppp: - p1 = va_arg (ap, gpointer ); - p2 = va_arg (ap, gpointer ); - p3 = va_arg (ap, gpointer ); - p4 = va_arg (ap, gpointer ); - m->ret = m->func (p1, p2, p3, p4); - break; - case MAIL_CALL_p_ppppp: - p1 = va_arg (ap, gpointer ); - p2 = va_arg (ap, gpointer ); - p3 = va_arg (ap, gpointer ); - p4 = va_arg (ap, gpointer ); - p5 = va_arg (ap, gpointer ); - m->ret = m->func (p1, p2, p3, p4, p5); - break; - case MAIL_CALL_p_ppippp: - p1 = va_arg (ap, gpointer ); - p2 = va_arg (ap, gpointer ); - i1 = va_arg (ap, gint); - p3 = va_arg (ap, gpointer ); - p4 = va_arg (ap, gpointer ); - p5 = va_arg (ap, gpointer ); - m->ret = m->func (p1, p2, i1, p3, p4, p5); - break; - } - - e_activity_set_state ( - m->base.activity, - g_cancellable_is_cancelled (cancellable) ? - E_ACTIVITY_CANCELLED : E_ACTIVITY_COMPLETED); - - if (m->done != NULL) - e_flag_set (m->done); -} - -static MailMsgInfo mail_call_info = { - sizeof (struct _call_msg), - (MailMsgDescFunc) NULL, - (MailMsgExecFunc) do_call, - (MailMsgDoneFunc) NULL, - (MailMsgFreeFunc) NULL -}; - -gpointer -mail_call_main (mail_call_t type, - MailMainFunc func, - ...) -{ - GCancellable *cancellable; - struct _call_msg *m; - gpointer ret; - va_list ap; - - va_start (ap, func); - - m = mail_msg_new (&mail_call_info); - m->type = type; - m->func = func; - G_VA_COPY (m->ap, ap); - - cancellable = e_activity_get_cancellable (m->base.activity); - - if (mail_in_main_thread ()) - do_call (m, cancellable, &m->base.error); - else { - mail_msg_ref (m); - m->done = e_flag_new (); - mail_msg_main_loop_push (m); - e_flag_wait (m->done); - e_flag_free (m->done); - } - - va_end (ap); - - ret = m->ret; - mail_msg_unref (m); - - return ret; -} - -void -mail_mt_set_backend (gchar *backend) -{ - shell_builtin_backend = backend; -} - diff --git a/mail/mail-mt.h b/mail/mail-mt.h deleted file mode 100644 index 0b595072b6..0000000000 --- a/mail/mail-mt.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _MAIL_MT -#define _MAIL_MT - -#include <camel/camel.h> -#include <e-util/e-activity.h> - -typedef struct _MailMsg MailMsg; -typedef struct _MailMsgInfo MailMsgInfo; - -typedef gchar * (*MailMsgDescFunc) (MailMsg *msg); -typedef void (*MailMsgExecFunc) (MailMsg *msg, - GCancellable *cancellable, - GError **error); -typedef void (*MailMsgDoneFunc) (MailMsg *msg); -typedef void (*MailMsgFreeFunc) (MailMsg *msg); -typedef void (*MailMsgDispatchFunc) (gpointer msg); - -struct _MailMsg { - MailMsgInfo *info; - volatile gint ref_count; - guint seq; /* seq number for synchronisation */ - gint priority; /* priority (default = 0) */ - EActivity *activity; - GError *error; /* up to the caller to use this */ -}; - -struct _MailMsgInfo { - gsize size; - MailMsgDescFunc desc; - MailMsgExecFunc exec; - MailMsgDoneFunc done; - MailMsgFreeFunc free; -}; - -/* setup ports */ -void mail_msg_init (void); - -gboolean mail_in_main_thread (void); - -/* allocate a new message */ -gpointer mail_msg_new (MailMsgInfo *info); -gpointer mail_msg_ref (gpointer msg); -void mail_msg_unref (gpointer msg); -void mail_msg_check_error (gpointer msg); -void mail_msg_cancel (guint msgid); -gboolean mail_msg_active (void); - -/* dispatch a message */ -void mail_msg_main_loop_push (gpointer msg); -void mail_msg_unordered_push (gpointer msg); -void mail_msg_fast_ordered_push (gpointer msg); -void mail_msg_slow_ordered_push (gpointer msg); - -/* To implement the stop button */ -GHook * mail_cancel_hook_add (GHookFunc func, gpointer data); -void mail_cancel_hook_remove (GHook *hook); -void mail_cancel_all (void); - -/* request a string/password */ -gchar *mail_get_password (CamelService *service, const gchar *prompt, - gboolean secret, gboolean *cache); - -void mail_mt_set_backend (gchar *backend); - -/* Call a function in the GUI thread, wait for it to return, type is - * the marshaller to use. FIXME This thing is horrible, please put - * it out of its misery. */ -typedef enum { - MAIL_CALL_p_p, - MAIL_CALL_p_pp, - MAIL_CALL_p_ppp, - MAIL_CALL_p_pppp, - MAIL_CALL_p_ppppp, - MAIL_CALL_p_ppippp -} mail_call_t; - -typedef gpointer (*MailMainFunc)(); - -gpointer mail_call_main (mail_call_t type, MailMainFunc func, ...); - -#endif /* _MAIL_MT */ diff --git a/mail/mail-ops.c b/mail/mail-ops.c deleted file mode 100644 index 27b48c2aa8..0000000000 --- a/mail/mail-ops.c +++ /dev/null @@ -1,1690 +0,0 @@ -/* - * mail-ops.c: callbacks for the mail toolbar/menus - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Dan Winship <danw@ximian.com> - * Jeffrey Stedfast <fejj@ximian.com> - * Peter Williams <peterw@ximian.com> - * Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> - -#include <glib/gstdio.h> -#include <glib/gi18n.h> - -#include <libedataserver/e-data-server-util.h> -#include "e-util/e-account-utils.h" - -#include "em-filter-rule.h" -#include "em-utils.h" -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-tools.h" - -#include "e-mail-session.h" -#include "e-mail-session-utils.h" - -#define w(x) -#define d(x) - -/* XXX Make this a preprocessor definition. */ -const gchar *x_mailer = "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT; - -/* used for both just filtering a folder + uid's, and for filtering a whole folder */ -/* used both for fetching mail, and for filtering mail */ -struct _filter_mail_msg { - MailMsg base; - - EMailSession *session; - CamelFolder *source_folder; /* where they come from */ - GPtrArray *source_uids; /* uids to copy, or NULL == copy all */ - CamelUIDCache *cache; /* UID cache if we are to cache the uids, NULL otherwise */ - CamelFilterDriver *driver; - gint delete; /* delete messages after filtering them? */ - CamelFolder *destination; /* default destination for any messages, NULL for none */ -}; - -/* since fetching also filters, we subclass the data here */ -struct _fetch_mail_msg { - struct _filter_mail_msg fmsg; - - CamelStore *store; - GCancellable *cancellable; /* we have our own cancellation - * struct, the other should be empty */ - gint keep; /* keep on server? */ - - void (*done)(gpointer data); - gpointer data; -}; - -static gchar * -em_filter_folder_element_desc (struct _filter_mail_msg *m) -{ - return g_strdup (_("Filtering Selected Messages")); -} - -/* filter a folder, or a subset thereof, uses source_folder/source_uids */ -/* this is shared with fetch_mail */ -static void -em_filter_folder_element_exec (struct _filter_mail_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *folder; - GPtrArray *uids, *folder_uids = NULL; - - folder = m->source_folder; - - if (folder == NULL || camel_folder_get_message_count (folder) == 0) - return; - - if (m->destination) { - camel_folder_freeze (m->destination); - camel_filter_driver_set_default_folder (m->driver, m->destination); - } - - camel_folder_freeze (folder); - - if (m->source_uids) - uids = m->source_uids; - else - folder_uids = uids = camel_folder_get_uids (folder); - - camel_filter_driver_filter_folder ( - m->driver, folder, m->cache, uids, m->delete, - cancellable, error); - camel_filter_driver_flush (m->driver, error); - - if (folder_uids) - camel_folder_free_uids (folder, folder_uids); - - /* sync our source folder */ - if (!m->cache) - camel_folder_synchronize_sync ( - folder, FALSE, cancellable, error); - camel_folder_thaw (folder); - - if (m->destination) - camel_folder_thaw (m->destination); - - /* this may thaw/unref source folders, do it here so we dont do - * it in the main thread see also fetch_mail_fetch () below */ - g_object_unref (m->driver); - m->driver = NULL; -} - -static void -em_filter_folder_element_done (struct _filter_mail_msg *m) -{ -} - -static void -em_filter_folder_element_free (struct _filter_mail_msg *m) -{ - mail_session_flush_filter_log (m->session); - - if (m->session) - g_object_unref (m->session); - - if (m->source_folder) - g_object_unref (m->source_folder); - - if (m->source_uids) - em_utils_uids_free (m->source_uids); - - if (m->destination) - g_object_unref (m->destination); - - if (m->driver) - g_object_unref (m->driver); -} - -static MailMsgInfo em_filter_folder_element_info = { - sizeof (struct _filter_mail_msg), - (MailMsgDescFunc) em_filter_folder_element_desc, - (MailMsgExecFunc) em_filter_folder_element_exec, - (MailMsgDoneFunc) em_filter_folder_element_done, - (MailMsgFreeFunc) em_filter_folder_element_free -}; - -void -mail_filter_folder (EMailSession *session, - CamelFolder *source_folder, - GPtrArray *uids, - const gchar *type, - gboolean notify) -{ - struct _filter_mail_msg *m; - - m = mail_msg_new (&em_filter_folder_element_info); - m->session = g_object_ref (session); - m->source_folder = g_object_ref (source_folder); - m->source_uids = uids; - m->cache = NULL; - m->delete = FALSE; - - m->driver = camel_session_get_filter_driver ( - CAMEL_SESSION (session), type, NULL); - - if (!notify) { - /* FIXME: have a #define NOTIFY_FILTER_NAME macro? */ - /* the filter name has to stay in sync with mail-session::get_filter_driver */ - camel_filter_driver_remove_rule_by_name (m->driver, "new-mail-notification"); - } - - mail_msg_unordered_push (m); -} - -/* ********************************************************************** */ - -static gchar * -fetch_mail_desc (struct _fetch_mail_msg *m) -{ - return g_strdup (_("Fetching Mail")); -} - -static void -fetch_mail_exec (struct _fetch_mail_msg *m, - GCancellable *cancellable, - GError **error) -{ - struct _filter_mail_msg *fm = (struct _filter_mail_msg *) m; - CamelFolder *folder = NULL; - CamelService *service; - CamelSession *session; - CamelURL *url; - gboolean is_local_delivery; - const gchar *uid; - gint i; - - service = CAMEL_SERVICE (m->store); - session = camel_service_get_session (service); - - fm->destination = e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_LOCAL_INBOX); - if (fm->destination == NULL) - goto exit; - g_object_ref (fm->destination); - - url = camel_service_new_camel_url (service); - is_local_delivery = em_utils_is_local_delivery_mbox_file (url); - - if (is_local_delivery) { - gchar *path; - gchar *url_string; - - path = mail_tool_do_movemail (m->store, error); - url_string = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); - - if (path && (!error || !*error)) { - camel_folder_freeze (fm->destination); - camel_filter_driver_set_default_folder ( - fm->driver, fm->destination); - camel_filter_driver_filter_mbox ( - fm->driver, path, url_string, - cancellable, error); - camel_folder_thaw (fm->destination); - - if (!error || !*error) - g_unlink (path); - } - - g_free (path); - g_free (url_string); - } else { - uid = camel_service_get_uid (service); - - folder = fm->source_folder = - e_mail_session_get_inbox_sync ( - fm->session, uid, cancellable, error); - } - - camel_url_free (url); - - if (folder != NULL) { - /* This handles 'keep on server' stuff, if we have any new - * uid's to copy across, we need to copy them to a new array - * 'cause of the way fetch_mail_free works. */ - CamelUIDCache *cache = NULL; - CamelStore *parent_store; - CamelService *service; - const gchar *data_dir; - gchar *cachename; - - parent_store = camel_folder_get_parent_store (folder); - - service = CAMEL_SERVICE (parent_store); - data_dir = camel_service_get_user_data_dir (service); - - cachename = g_build_filename (data_dir, "uid-cache", NULL); - cache = camel_uid_cache_new (cachename); - g_free (cachename); - - if (cache) { - GPtrArray *folder_uids, *cache_uids, *uids; - - folder_uids = camel_folder_get_uids (folder); - cache_uids = camel_uid_cache_get_new_uids (cache, folder_uids); - if (cache_uids) { - /* need to copy this, sigh */ - fm->source_uids = uids = g_ptr_array_new (); - g_ptr_array_set_size (uids, cache_uids->len); - for (i = 0; i < cache_uids->len; i++) - uids->pdata[i] = g_strdup (cache_uids->pdata[i]); - camel_uid_cache_free_uids (cache_uids); - - fm->cache = cache; - em_filter_folder_element_exec (fm, cancellable, error); - - /* need to uncancel so writes/etc. don't fail */ - if (g_cancellable_is_cancelled (m->cancellable)) - g_cancellable_reset (m->cancellable); - - /* save the cache of uids that we've just downloaded */ - camel_uid_cache_save (cache); - } - - if (fm->delete && (!error || !*error)) { - /* not keep on server - just delete all - * the actual messages on the server */ - for (i = 0; i < folder_uids->len; i++) { - camel_folder_delete_message ( - folder, folder_uids->pdata[i]); - } - } - - if ((fm->delete || cache_uids) && (!error || !*error)) { - /* expunge messages (downloaded so far) */ - /* FIXME Not passing a GCancellable or GError here. */ - camel_folder_synchronize_sync ( - folder, fm->delete, NULL, NULL); - } - - camel_uid_cache_destroy (cache); - camel_folder_free_uids (folder, folder_uids); - } else { - em_filter_folder_element_exec (fm, cancellable, error); - } - - /* we unref the source folder here since we - * may now block in finalize (we try to - * disconnect cleanly) */ - g_object_unref (fm->source_folder); - fm->source_folder = NULL; - } - -exit: - /* we unref this here as it may have more work to do (syncing - * folders and whatnot) before we are really done */ - /* should this be cancellable too? (i.e. above unregister above) */ - if (fm->driver) { - g_object_unref (fm->driver); - fm->driver = NULL; - } - - /* also disconnect if not a local delivery mbox; - * there is no need to keep the connection alive forever */ - if (!is_local_delivery) - em_utils_disconnect_service_sync ( - service, TRUE, cancellable, NULL); -} - -static void -fetch_mail_done (struct _fetch_mail_msg *m) -{ - if (m->done) - m->done (m->data); -} - -static void -fetch_mail_free (struct _fetch_mail_msg *m) -{ - if (m->store != NULL) - g_object_unref (m->store); - - if (m->cancellable != NULL) - g_object_unref (m->cancellable); - - em_filter_folder_element_free ((struct _filter_mail_msg *) m); -} - -static MailMsgInfo fetch_mail_info = { - sizeof (struct _fetch_mail_msg), - (MailMsgDescFunc) fetch_mail_desc, - (MailMsgExecFunc) fetch_mail_exec, - (MailMsgDoneFunc) fetch_mail_done, - (MailMsgFreeFunc) fetch_mail_free -}; - -/* ouch, a 'do everything' interface ... */ -void -mail_fetch_mail (CamelStore *store, - gint keep, - const gchar *type, - GCancellable *cancellable, - CamelFilterGetFolderFunc get_folder, - gpointer get_data, - CamelFilterStatusFunc *status, - gpointer status_data, - void (*done)(gpointer data), - gpointer data) -{ - struct _fetch_mail_msg *m; - struct _filter_mail_msg *fm; - CamelSession *session; - - g_return_if_fail (CAMEL_IS_STORE (store)); - - session = camel_service_get_session (CAMEL_SERVICE (store)); - - m = mail_msg_new (&fetch_mail_info); - fm = (struct _filter_mail_msg *) m; - fm->session = g_object_ref (session); - m->store = g_object_ref (store); - fm->delete = !keep; - fm->cache = NULL; - if (cancellable) - m->cancellable = g_object_ref (cancellable); - m->done = done; - m->data = data; - - fm->driver = camel_session_get_filter_driver (session, type, NULL); - camel_filter_driver_set_folder_func (fm->driver, get_folder, get_data); - if (status) - camel_filter_driver_set_status_func (fm->driver, status, status_data); - - mail_msg_unordered_push (m); -} - -/* ********************************************************************** */ -/* sending stuff */ -/* ** SEND MAIL *********************************************************** */ - -static const gchar *normal_recipients[] = { - CAMEL_RECIPIENT_TYPE_TO, - CAMEL_RECIPIENT_TYPE_CC, - CAMEL_RECIPIENT_TYPE_BCC -}; - -static const gchar *resent_recipients[] = { - CAMEL_RECIPIENT_TYPE_RESENT_TO, - CAMEL_RECIPIENT_TYPE_RESENT_CC, - CAMEL_RECIPIENT_TYPE_RESENT_BCC -}; - -struct _send_queue_msg { - MailMsg base; - - EMailSession *session; - CamelFolder *queue; - CamelTransport *transport; - - CamelFilterDriver *driver; - - /* we use camelfilterstatusfunc, even though its not the filter doing it */ - CamelFilterStatusFunc *status; - gpointer status_data; - - void (*done)(gpointer data); - gpointer data; -}; - -static void report_status (struct _send_queue_msg *m, - enum camel_filter_status_t status, - gint pc, - const gchar *desc, - ...); - -/* send 1 message to a specific transport */ -static void -mail_send_message (struct _send_queue_msg *m, - CamelFolder *queue, - const gchar *uid, - CamelTransport *transport, - CamelFilterDriver *driver, - GCancellable *cancellable, - GError **error) -{ - EAccount *account = NULL; - const CamelInternetAddress *iaddr; - CamelAddress *from, *recipients; - CamelMessageInfo *info = NULL; - CamelProvider *provider; - gchar *transport_uid = NULL; - gchar *sent_folder_uri = NULL; - const gchar *resent_from, *tmp; - CamelFolder *folder = NULL; - GString *err = NULL; - struct _camel_header_raw *xev, *header; - CamelMimeMessage *message; - gint i; - GError *local_error = NULL; - - message = camel_folder_get_message_sync ( - queue, uid, cancellable, error); - if (!message) - return; - - camel_medium_set_header (CAMEL_MEDIUM (message), "X-Mailer", x_mailer); - - err = g_string_new (""); - xev = mail_tool_remove_xevolution_headers (message); - - tmp = camel_header_raw_find (&xev, "X-Evolution-Account", NULL); - if (tmp != NULL) { - gchar *name; - - name = g_strstrip (g_strdup (tmp)); - if ((account = e_get_account_by_uid (name)) - /* 'old' x-evolution-account stored the name, how silly */ - || (account = e_get_account_by_name (name))) { - if (account->transport) { - CamelService *service; - gchar *transport_uid; - - transport_uid = g_strconcat ( - account->uid, "-transport", NULL); - service = camel_session_get_service ( - CAMEL_SESSION (m->session), - transport_uid); - g_free (transport_uid); - - if (CAMEL_IS_TRANSPORT (service)) - transport = CAMEL_TRANSPORT (service); - } - - sent_folder_uri = g_strdup (account->sent_folder_uri); - } - g_free (name); - } - - if (!account) { - /* default back to these headers */ - tmp = camel_header_raw_find(&xev, "X-Evolution-Transport", NULL); - if (tmp) - transport_uid = g_strstrip (g_strdup (tmp)); - - tmp = camel_header_raw_find(&xev, "X-Evolution-Fcc", NULL); - if (tmp) - sent_folder_uri = g_strstrip (g_strdup (tmp)); - } - - if (transport != NULL) { - const gchar *uid; - - /* Let the dialog know the right account it is using. */ - uid = camel_service_get_uid (CAMEL_SERVICE (transport)); - report_status (m, CAMEL_FILTER_STATUS_ACTION, 0, uid); - } - - /* Check for email sending */ - from = (CamelAddress *) camel_internet_address_new (); - resent_from = camel_medium_get_header (CAMEL_MEDIUM (message), "Resent-From"); - if (resent_from) { - camel_address_decode (from, resent_from); - } else { - iaddr = camel_mime_message_get_from (message); - camel_address_copy (from, CAMEL_ADDRESS (iaddr)); - } - - recipients = (CamelAddress *) camel_internet_address_new (); - for (i = 0; i < 3; i++) { - const gchar *type; - - type = resent_from ? resent_recipients[i] : normal_recipients[i]; - iaddr = camel_mime_message_get_recipients (message, type); - camel_address_cat (recipients, CAMEL_ADDRESS (iaddr)); - } - - if (camel_address_length (recipients) > 0) { - if (!em_utils_connect_service_sync ( - CAMEL_SERVICE (transport), cancellable, error)) - goto exit; - - if (!camel_transport_send_to_sync ( - transport, message, from, - recipients, cancellable, error)) - goto exit; - } - - /* Now check for posting, failures are ignored */ - info = camel_message_info_new (NULL); - camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0); - - for (header = xev; header; header = header->next) { - gchar *uri; - - if (strcmp(header->name, "X-Evolution-PostTo") != 0) - continue; - - /* TODO: don't lose errors */ - - uri = g_strstrip (g_strdup (header->value)); - /* FIXME Not passing a GCancellable or GError here. */ - folder = e_mail_session_uri_to_folder_sync ( - m->session, uri, 0, NULL, NULL); - if (folder) { - /* FIXME Not passing a GCancellable or GError here. */ - camel_folder_append_message_sync ( - folder, message, info, NULL, NULL, NULL); - g_object_unref (folder); - folder = NULL; - } - g_free (uri); - } - - /* post process */ - mail_tool_restore_xevolution_headers (message, xev); - - if (driver) { - camel_filter_driver_filter_message ( - driver, message, info, NULL, NULL, - NULL, "", cancellable, &local_error); - - if (local_error != NULL) { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto exit; - - /* sending mail, filtering failed */ - g_string_append_printf ( - err, _("Failed to apply outgoing filters: %s"), - local_error->message); - - g_clear_error (&local_error); - } - } - - provider = camel_service_get_provider (CAMEL_SERVICE (transport)); - - if (provider == NULL - || !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER)) { - GError *local_error = NULL; - - if (sent_folder_uri) { - folder = e_mail_session_uri_to_folder_sync ( - m->session, sent_folder_uri, 0, - cancellable, &local_error); - if (folder == NULL) { - g_string_append_printf ( - err, _("Failed to append to %s: %s\n" - "Appending to local 'Sent' folder instead."), - sent_folder_uri, - local_error ? - local_error->message : - _("Unknown error")); - if (local_error) - g_clear_error (&local_error); - } - } - - if (!folder) { - folder = e_mail_session_get_local_folder ( - m->session, E_MAIL_LOCAL_FOLDER_SENT); - g_object_ref (folder); - } - - if (!camel_folder_append_message_sync ( - folder, message, info, - NULL, cancellable, &local_error)) { - - CamelFolder *sent_folder; - - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto exit; - - sent_folder = e_mail_session_get_local_folder ( - m->session, E_MAIL_LOCAL_FOLDER_SENT); - - if (folder != sent_folder) { - const gchar *description; - - description = camel_folder_get_description (folder); - if (err->len) - g_string_append(err, "\n\n"); - g_string_append_printf ( - err, _("Failed to append to %s: %s\n" - "Appending to local 'Sent' folder instead."), - description, local_error->message); - g_object_ref (sent_folder); - g_object_unref (folder); - folder = sent_folder; - - g_clear_error (&local_error); - camel_folder_append_message_sync ( - folder, message, info, - NULL, cancellable, &local_error); - } - - if (local_error != NULL) { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto exit; - - if (err->len) - g_string_append(err, "\n\n"); - g_string_append_printf ( - err, _("Failed to append to local 'Sent' folder: %s"), - local_error->message); - } - } - } - - if (local_error == NULL) { - /* Mark the draft message for deletion, if present. */ - e_mail_session_handle_draft_headers_sync ( - m->session, message, cancellable, &local_error); - if (local_error != NULL) { - g_warning ("%s: Failed to handle draft headers: %s", G_STRFUNC, local_error->message); - g_clear_error (&local_error); - } - - /* Set flags on the original source message, if present. - * Source message refers to the message being forwarded - * or replied to. */ - e_mail_session_handle_source_headers_sync ( - m->session, message, cancellable, &local_error); - if (local_error != NULL) { - g_warning ("%s: Failed to handle source headers: %s", G_STRFUNC, local_error->message); - g_clear_error (&local_error); - } - } - - if (local_error == NULL) { - camel_folder_set_message_flags ( - queue, uid, CAMEL_MESSAGE_DELETED | - CAMEL_MESSAGE_SEEN, ~0); - /* Sync it to disk, since if it crashes in between, - * we keep sending it again on next start. */ - /* FIXME Not passing a GCancellable or GError here. */ - camel_folder_synchronize_sync (queue, FALSE, NULL, NULL); - } - - if (err->len) { - /* set the culmulative exception report */ - g_set_error ( - &local_error, CAMEL_ERROR, - CAMEL_ERROR_GENERIC, "%s", err->str); - } - -exit: - if (local_error != NULL) - g_propagate_error (error, local_error); - - /* FIXME Not passing a GCancellable or GError here. */ - if (folder) { - camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); - g_object_unref (folder); - } - if (info) - camel_message_info_free (info); - g_object_unref (recipients); - g_object_unref (from); - g_free (sent_folder_uri); - g_free (transport_uid); - camel_header_raw_clear (&xev); - g_string_free (err, TRUE); - g_object_unref (message); -} - -/* ** SEND MAIL QUEUE ***************************************************** */ - -static void -report_status (struct _send_queue_msg *m, - enum camel_filter_status_t status, - gint pc, - const gchar *desc, - ...) -{ - va_list ap; - gchar *str; - - if (m->status) { - va_start (ap, desc); - str = g_strdup_vprintf (desc, ap); - va_end (ap); - m->status (m->driver, status, pc, str, m->status_data); - g_free (str); - } -} - -static void -send_queue_exec (struct _send_queue_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *sent_folder; - GPtrArray *uids, *send_uids = NULL; - gint i, j; - GError *local_error = NULL; - - d(printf("sending queue\n")); - - sent_folder = - e_mail_session_get_local_folder ( - m->session, E_MAIL_LOCAL_FOLDER_SENT); - - if (!(uids = camel_folder_get_uids (m->queue))) - return; - - send_uids = g_ptr_array_sized_new (uids->len); - for (i = 0, j = 0; i < uids->len; i++) { - CamelMessageInfo *info; - - info = camel_folder_get_message_info (m->queue, uids->pdata[i]); - if (info) { - if ((camel_message_info_flags (info) & CAMEL_MESSAGE_DELETED) == 0) - send_uids->pdata[j++] = uids->pdata[i]; - camel_folder_free_message_info (m->queue, info); - } - } - - send_uids->len = j; - if (send_uids->len == 0) { - /* nothing to send */ - camel_folder_free_uids (m->queue, uids); - g_ptr_array_free (send_uids, TRUE); - return; - } - - camel_operation_push_message (cancellable, _("Sending message")); - - /* NB: This code somewhat abuses the 'exception' stuff. Apart from - * fatal problems, it is also used as a mechanism to accumualte - * warning messages and present them back to the user. */ - - for (i = 0, j = 0; i < send_uids->len; i++) { - gint pc = (100 * i) / send_uids->len; - - report_status ( - m, CAMEL_FILTER_STATUS_START, pc, - _("Sending message %d of %d"), i+1, - send_uids->len); - - camel_operation_progress ( - cancellable, (i + 1) * 100 / send_uids->len); - - mail_send_message ( - m, m->queue, send_uids->pdata[i], m->transport, - m->driver, cancellable, &local_error); - if (local_error != NULL) { - if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - /* merge exceptions into one */ - if (m->base.error != NULL) { - gchar *old_message; - - old_message = g_strdup ( - m->base.error->message); - g_clear_error (&m->base.error); - g_set_error ( - &m->base.error, CAMEL_ERROR, - CAMEL_ERROR_GENERIC, - "%s\n\n%s", old_message, - local_error->message); - g_free (old_message); - - g_clear_error (&local_error); - } else { - g_propagate_error (&m->base.error, local_error); - local_error = NULL; - } - - /* keep track of the number of failures */ - j++; - } else { - /* transfer the USER_CANCEL error to the - * async op exception and then break */ - g_propagate_error (&m->base.error, local_error); - local_error = NULL; - break; - } - } - } - - j += (send_uids->len - i); - - if (j > 0) - report_status ( - m, CAMEL_FILTER_STATUS_END, 100, - _("Failed to send %d of %d messages"), - j, send_uids->len); - else if (g_error_matches ( - m->base.error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - report_status (m, CAMEL_FILTER_STATUS_END, 100, _("Canceled.")); - else - report_status (m, CAMEL_FILTER_STATUS_END, 100, _("Complete.")); - - if (m->driver) { - g_object_unref (m->driver); - m->driver = NULL; - } - - camel_folder_free_uids (m->queue, uids); - g_ptr_array_free (send_uids, TRUE); - - /* FIXME Not passing a GCancellable or GError here. */ - if (j <= 0 && m->base.error == NULL) - camel_folder_synchronize_sync (m->queue, TRUE, NULL, NULL); - - /* FIXME Not passing a GCancellable or GError here. */ - if (sent_folder) - camel_folder_synchronize_sync (sent_folder, FALSE, NULL, NULL); - - camel_operation_pop_message (cancellable); -} - -static void -send_queue_done (struct _send_queue_msg *m) -{ - if (m->done) - m->done (m->data); -} - -static gchar * -send_queue_desc (struct _send_queue_msg *m) -{ - return g_strdup (_("Sending message")); -} - -static void -send_queue_free (struct _send_queue_msg *m) -{ - if (m->session != NULL) - g_object_unref (m->session); - if (m->driver != NULL) - g_object_unref (m->driver); - if (m->transport != NULL) - g_object_unref (m->transport); - g_object_unref (m->queue); -} - -static MailMsgInfo send_queue_info = { - sizeof (struct _send_queue_msg), - (MailMsgDescFunc) send_queue_desc, - (MailMsgExecFunc) send_queue_exec, - (MailMsgDoneFunc) send_queue_done, - (MailMsgFreeFunc) send_queue_free -}; - -/* same interface as fetch_mail, just 'cause i'm lazy today - * (and we need to run it from the same spot?) */ -void -mail_send_queue (EMailSession *session, - CamelFolder *queue, - CamelTransport *transport, - const gchar *type, - GCancellable *cancellable, - CamelFilterGetFolderFunc get_folder, - gpointer get_data, - CamelFilterStatusFunc *status, - gpointer status_data, - void (*done)(gpointer data), - gpointer data) -{ - struct _send_queue_msg *m; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - - m = mail_msg_new (&send_queue_info); - m->session = g_object_ref (session); - m->queue = g_object_ref (queue); - m->transport = g_object_ref (transport); - if (G_IS_CANCELLABLE (cancellable)) - e_activity_set_cancellable (m->base.activity, cancellable); - m->status = status; - m->status_data = status_data; - m->done = done; - m->data = data; - - m->driver = camel_session_get_filter_driver ( - CAMEL_SESSION (session), type, NULL); - camel_filter_driver_set_folder_func (m->driver, get_folder, get_data); - - mail_msg_unordered_push (m); -} - -/* ** TRANSFER MESSAGES **************************************************** */ - -struct _transfer_msg { - MailMsg base; - - EMailSession *session; - CamelFolder *source; - GPtrArray *uids; - gboolean delete; - gchar *dest_uri; - guint32 dest_flags; - - void (*done)(gboolean ok, gpointer data); - gpointer data; -}; - -static gchar * -transfer_messages_desc (struct _transfer_msg *m) -{ - return g_strdup_printf ( - m->delete ? - _("Moving messages to '%s'") : - _("Copying messages to '%s'"), - m->dest_uri); - -} - -static void -transfer_messages_exec (struct _transfer_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *dest; - - dest = e_mail_session_uri_to_folder_sync ( - m->session, m->dest_uri, m->dest_flags, - cancellable, error); - if (dest == NULL) - return; - - if (dest == m->source) { - g_object_unref (dest); - /* no-op */ - return; - } - - camel_folder_freeze (m->source); - camel_folder_freeze (dest); - - camel_folder_transfer_messages_to_sync ( - m->source, m->uids, dest, m->delete, NULL, - cancellable, error); - - /* make sure all deleted messages are marked as seen */ - - if (m->delete) { - gint i; - - for (i = 0; i < m->uids->len; i++) - camel_folder_set_message_flags ( - m->source, m->uids->pdata[i], - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); - } - - camel_folder_thaw (m->source); - camel_folder_thaw (dest); - - /* FIXME Not passing a GCancellable or GError here. */ - camel_folder_synchronize_sync (dest, FALSE, NULL, NULL); - g_object_unref (dest); -} - -static void -transfer_messages_done (struct _transfer_msg *m) -{ - if (m->done) - m->done (m->base.error == NULL, m->data); -} - -static void -transfer_messages_free (struct _transfer_msg *m) -{ - g_object_unref (m->session); - g_object_unref (m->source); - g_free (m->dest_uri); - em_utils_uids_free (m->uids); -} - -static MailMsgInfo transfer_messages_info = { - sizeof (struct _transfer_msg), - (MailMsgDescFunc) transfer_messages_desc, - (MailMsgExecFunc) transfer_messages_exec, - (MailMsgDoneFunc) transfer_messages_done, - (MailMsgFreeFunc) transfer_messages_free -}; - -void -mail_transfer_messages (EMailSession *session, - CamelFolder *source, - GPtrArray *uids, - gboolean delete_from_source, - const gchar *dest_uri, - guint32 dest_flags, - void (*done) (gboolean ok, - gpointer data), - gpointer data) -{ - struct _transfer_msg *m; - - g_return_if_fail (CAMEL_IS_FOLDER (source)); - g_return_if_fail (uids != NULL); - g_return_if_fail (dest_uri != NULL); - - m = mail_msg_new (&transfer_messages_info); - m->session = g_object_ref (session); - m->source = g_object_ref (source); - m->uids = uids; - m->delete = delete_from_source; - m->dest_uri = g_strdup (dest_uri); - m->dest_flags = dest_flags; - m->done = done; - m->data = data; - - mail_msg_slow_ordered_push (m); -} - -/* ** SYNC FOLDER ********************************************************* */ - -struct _sync_folder_msg { - MailMsg base; - - CamelFolder *folder; - void (*done) (CamelFolder *folder, gpointer data); - gpointer data; -}; - -static gchar * -sync_folder_desc (struct _sync_folder_msg *m) -{ - return g_strdup_printf (_("Storing folder '%s'"), - camel_folder_get_full_name (m->folder)); -} - -static void -sync_folder_exec (struct _sync_folder_msg *m, - GCancellable *cancellable, - GError **error) -{ - camel_folder_synchronize_sync ( - m->folder, FALSE, cancellable, error); -} - -static void -sync_folder_done (struct _sync_folder_msg *m) -{ - if (m->done) - m->done (m->folder, m->data); -} - -static void -sync_folder_free (struct _sync_folder_msg *m) -{ - if (m->folder) - g_object_unref (m->folder); -} - -static MailMsgInfo sync_folder_info = { - sizeof (struct _sync_folder_msg), - (MailMsgDescFunc) sync_folder_desc, - (MailMsgExecFunc) sync_folder_exec, - (MailMsgDoneFunc) sync_folder_done, - (MailMsgFreeFunc) sync_folder_free -}; - -void -mail_sync_folder (CamelFolder *folder, - void (*done) (CamelFolder *folder, - gpointer data), - gpointer data) -{ - struct _sync_folder_msg *m; - - m = mail_msg_new (&sync_folder_info); - m->folder = g_object_ref (folder); - m->data = data; - m->done = done; - - mail_msg_slow_ordered_push (m); -} - -/* ** SYNC STORE ********************************************************* */ - -struct _sync_store_msg { - MailMsg base; - - CamelStore *store; - gint expunge; - void (*done) (CamelStore *store, gpointer data); - gpointer data; -}; - -static gchar * -sync_store_desc (struct _sync_store_msg *m) -{ - CamelURL *url; - gchar *uri, *res; - - url = camel_service_new_camel_url (CAMEL_SERVICE (m->store)); - uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); - camel_url_free (url); - - res = g_strdup_printf (m->expunge - ?_("Expunging and storing account '%s'") - :_("Storing account '%s'"), - uri); - g_free (uri); - - return res; -} - -static void -sync_store_exec (struct _sync_store_msg *m, - GCancellable *cancellable, - GError **error) -{ - camel_store_synchronize_sync ( - m->store, m->expunge, - cancellable, error); -} - -static void -sync_store_done (struct _sync_store_msg *m) -{ - if (m->done) - m->done (m->store, m->data); -} - -static void -sync_store_free (struct _sync_store_msg *m) -{ - g_object_unref (m->store); -} - -static MailMsgInfo sync_store_info = { - sizeof (struct _sync_store_msg), - (MailMsgDescFunc) sync_store_desc, - (MailMsgExecFunc) sync_store_exec, - (MailMsgDoneFunc) sync_store_done, - (MailMsgFreeFunc) sync_store_free -}; - -void -mail_sync_store (CamelStore *store, - gint expunge, - void (*done) (CamelStore *store, - gpointer data), - gpointer data) -{ - struct _sync_store_msg *m; - - m = mail_msg_new (&sync_store_info); - m->store = g_object_ref (store); - m->expunge = expunge; - m->data = data; - m->done = done; - - mail_msg_slow_ordered_push (m); -} - -/* ******************************************************************************** */ - -static gchar * -refresh_folder_desc (struct _sync_folder_msg *m) -{ - return g_strdup_printf ( - _("Refreshing folder '%s'"), - camel_folder_get_full_name (m->folder)); -} - -static void -refresh_folder_exec (struct _sync_folder_msg *m, - GCancellable *cancellable, - GError **error) -{ - camel_folder_refresh_info_sync ( - m->folder, cancellable, error); -} - -/* we just use the sync stuff where we can, since it would be the same */ -static MailMsgInfo refresh_folder_info = { - sizeof (struct _sync_folder_msg), - (MailMsgDescFunc) refresh_folder_desc, - (MailMsgExecFunc) refresh_folder_exec, - (MailMsgDoneFunc) sync_folder_done, - (MailMsgFreeFunc) sync_folder_free -}; - -void -mail_refresh_folder (CamelFolder *folder, - void (*done) (CamelFolder *folder, - gpointer data), - gpointer data) -{ - struct _sync_folder_msg *m; - - m = mail_msg_new (&refresh_folder_info); - m->folder = g_object_ref (folder); - m->data = data; - m->done = done; - - mail_msg_slow_ordered_push (m); -} - -/* ******************************************************************************** */ - -static gboolean -folder_is_from_source_uid (CamelFolder *folder, - const gchar *source_uid) -{ - CamelStore *store; - const gchar *uid; - - store = camel_folder_get_parent_store (folder); - uid = camel_service_get_uid (CAMEL_SERVICE (store)); - - return (g_strcmp0 (uid, source_uid) == 0); -} - -/* This is because pop3 accounts are hidden under local Inbox, - * thus whenever an expunge is done on a local trash or Inbox, - * then also all active pop3 accounts should be expunged. */ -static gboolean -expunge_pop3_stores (CamelFolder *expunging, - GCancellable *cancellable, - GError **error) -{ - GHashTable *expunging_uids; - CamelStore *parent_store; - CamelService *service; - CamelSession *session; - GPtrArray *uids; - EAccount *account; - EIterator *iter; - gboolean success = TRUE; - guint ii; - - parent_store = camel_folder_get_parent_store (expunging); - - service = CAMEL_SERVICE (parent_store); - session = camel_service_get_session (service); - - uids = camel_folder_get_uids (expunging); - - if (uids == NULL) - return TRUE; - - expunging_uids = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - - for (ii = 0; ii < uids->len; ii++) { - CamelMessageInfo *info; - CamelMessageFlags flags = 0; - CamelMimeMessage *message; - const gchar *pop3_uid; - const gchar *source_uid; - - info = camel_folder_get_message_info ( - expunging, uids->pdata[ii]); - - if (info != NULL) { - flags = camel_message_info_flags (info); - camel_folder_free_message_info (expunging, info); - } - - /* Only interested in deleted messages. */ - if ((flags & CAMEL_MESSAGE_DELETED) == 0) - continue; - - /* because the UID in the local store doesn't - * match with the UID in the pop3 store */ - message = camel_folder_get_message_sync ( - expunging, uids->pdata[ii], cancellable, NULL); - - if (message == NULL) - continue; - - pop3_uid = camel_medium_get_header ( - CAMEL_MEDIUM (message), "X-Evolution-POP3-UID"); - source_uid = camel_mime_message_get_source (message); - - if (pop3_uid != NULL) - g_hash_table_insert ( - expunging_uids, - g_strstrip (g_strdup (pop3_uid)), - g_strstrip (g_strdup (source_uid))); - - g_object_unref (message); - } - - camel_folder_free_uids (expunging, uids); - uids = NULL; - - if (g_hash_table_size (expunging_uids) == 0) { - g_hash_table_destroy (expunging_uids); - return TRUE; - } - - for (iter = e_list_get_iterator ((EList *) e_get_account_list ()); - e_iterator_is_valid (iter); e_iterator_next (iter)) { - account = (EAccount *) e_iterator_get (iter); - - if (account->enabled && - account->source && account->source->url && - g_str_has_prefix (account->source->url, "pop://")) { - CamelFolder *folder; - CamelService *service; - CamelSettings *settings; - gboolean any_found = FALSE, delete_expunged = FALSE, keep_on_server = FALSE; - - service = camel_session_get_service ( - session, account->uid); - - if (!CAMEL_IS_STORE (service)) - continue; - - settings = camel_service_get_settings (service); - if (!settings) - continue; - - g_object_get ( - settings, - "delete-expunged", &delete_expunged, - "keep-on-server", &keep_on_server, - NULL); - - if (!keep_on_server || !delete_expunged) - continue; - - folder = e_mail_session_get_inbox_sync ( - E_MAIL_SESSION (session), - account->uid, cancellable, error); - - /* Abort the loop on error. */ - if (folder == NULL) { - success = FALSE; - break; - } - - uids = camel_folder_get_uids (folder); - if (uids) { - for (ii = 0; ii < uids->len; ii++) { - /* ensure the ID is from this account, - * as it's generated by evolution */ - const gchar *source_uid; - - source_uid = g_hash_table_lookup ( - expunging_uids, uids->pdata[ii]); - if (folder_is_from_source_uid (folder, source_uid)) { - any_found = TRUE; - camel_folder_delete_message (folder, uids->pdata[ii]); - } - } - camel_folder_free_uids (folder, uids); - } - - if (any_found) - success = camel_folder_synchronize_sync (folder, TRUE, cancellable, error); - - g_object_unref (folder); - - /* Abort the loop on error. */ - if (!success) - break; - } - } - - if (iter) - g_object_unref (iter); - - g_hash_table_destroy (expunging_uids); - - return success; -} - -static gchar * -expunge_folder_desc (struct _sync_folder_msg *m) -{ - return g_strdup_printf ( - _("Expunging folder '%s'"), - camel_folder_get_full_name (m->folder)); -} - -static void -expunge_folder_exec (struct _sync_folder_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *local_inbox; - CamelStore *parent_store; - CamelService *service; - CamelSession *session; - gboolean is_local_inbox_or_trash; - gboolean store_is_local; - gboolean success = TRUE; - const gchar *uid; - - parent_store = camel_folder_get_parent_store (m->folder); - - service = CAMEL_SERVICE (parent_store); - session = camel_service_get_session (service); - - uid = camel_service_get_uid (service); - store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0); - - local_inbox = - e_mail_session_get_local_folder ( - E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_INBOX); - is_local_inbox_or_trash = (m->folder == local_inbox); - - if (store_is_local && !is_local_inbox_or_trash) { - CamelFolder *trash; - - trash = camel_store_get_trash_folder_sync ( - parent_store, cancellable, error); - - if (trash == NULL) - return; - - is_local_inbox_or_trash = (m->folder == trash); - - g_object_unref (trash); - } - - /* do this before expunge, to know which messages will be expunged */ - if (is_local_inbox_or_trash) - success = expunge_pop3_stores (m->folder, cancellable, error); - - if (success) - camel_folder_expunge_sync (m->folder, cancellable, error); -} - -/* we just use the sync stuff where we can, since it would be the same */ -static MailMsgInfo expunge_folder_info = { - sizeof (struct _sync_folder_msg), - (MailMsgDescFunc) expunge_folder_desc, - (MailMsgExecFunc) expunge_folder_exec, - (MailMsgDoneFunc) sync_folder_done, - (MailMsgFreeFunc) sync_folder_free -}; - -void -mail_expunge_folder (CamelFolder *folder) -{ - struct _sync_folder_msg *m; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - m = mail_msg_new (&expunge_folder_info); - m->folder = g_object_ref (folder); - - mail_msg_slow_ordered_push (m); -} - -/* ******************************************************************************** */ - -struct _empty_trash_msg { - MailMsg base; - - CamelStore *store; -}; - -static gchar * -empty_trash_desc (struct _empty_trash_msg *m) -{ - CamelService *service; - const gchar *display_name; - - service = CAMEL_SERVICE (m->store); - display_name = camel_service_get_display_name (service); - - return g_strdup_printf ( - _("Emptying trash in '%s'"), display_name); -} - -static void -empty_trash_exec (struct _empty_trash_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelService *service; - CamelFolder *trash; - const gchar *uid; - gboolean success = TRUE; - - service = CAMEL_SERVICE (m->store); - uid = camel_service_get_uid (service); - - if (!em_utils_connect_service_sync (service, cancellable, error)) - return; - - trash = camel_store_get_trash_folder_sync ( - m->store, cancellable, error); - - if (trash == NULL) - return; - - /* do this before expunge, to know which messages will be expunged */ - if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) - success = expunge_pop3_stores (trash, cancellable, error); - - if (success) - camel_folder_expunge_sync (trash, cancellable, error); - - g_object_unref (trash); -} - -static void -empty_trash_done (struct _empty_trash_msg *m) -{ -} - -static void -empty_trash_free (struct _empty_trash_msg *m) -{ - if (m->store) - g_object_unref (m->store); -} - -static MailMsgInfo empty_trash_info = { - sizeof (struct _empty_trash_msg), - (MailMsgDescFunc) empty_trash_desc, - (MailMsgExecFunc) empty_trash_exec, - (MailMsgDoneFunc) empty_trash_done, - (MailMsgFreeFunc) empty_trash_free -}; - -void -mail_empty_trash (CamelStore *store) -{ - struct _empty_trash_msg *m; - - g_return_if_fail (CAMEL_IS_STORE (store)); - - m = mail_msg_new (&empty_trash_info); - m->store = g_object_ref (store); - - mail_msg_slow_ordered_push (m); -} - -/* ** Execute Shell Command ************************************************ */ - -void -mail_execute_shell_command (CamelFilterDriver *driver, - gint argc, - gchar **argv, - gpointer data) -{ - if (argc <= 0) - return; - - g_spawn_async (NULL, argv, NULL, 0, NULL, data, NULL, NULL); -} - -/* ------------------------------------------------------------------------- */ - -struct _disconnect_msg { - MailMsg base; - - CamelStore *store; -}; - -static gchar * -disconnect_service_desc (struct _disconnect_msg *m) -{ - gchar *name, *res; - - name = camel_service_get_name (CAMEL_SERVICE (m->store), TRUE); - res = g_strdup_printf (_("Disconnecting %s"), name ? name : ""); - g_free (name); - - return res; -} - -static void -disconnect_service_exec (struct _disconnect_msg *m, - GCancellable *cancellable, - GError **error) -{ - em_utils_disconnect_service_sync ( - CAMEL_SERVICE (m->store), TRUE, cancellable, error); -} - -static void -disconnect_service_free (struct _disconnect_msg *m) -{ - g_object_unref (m->store); -} - -static MailMsgInfo disconnect_service_info = { - sizeof (struct _disconnect_msg), - (MailMsgDescFunc) disconnect_service_desc, - (MailMsgExecFunc) disconnect_service_exec, - (MailMsgDoneFunc) NULL, - (MailMsgFreeFunc) disconnect_service_free -}; - -gint -mail_disconnect_store (CamelStore *store) -{ - struct _disconnect_msg *m; - gint id; - - g_return_val_if_fail (store != NULL, -1); - - m = mail_msg_new (&disconnect_service_info); - m->store = g_object_ref (store); - - id = m->base.seq; - mail_msg_unordered_push (m); - - return id; -} diff --git a/mail/mail-ops.h b/mail/mail-ops.h deleted file mode 100644 index b8eb184c7e..0000000000 --- a/mail/mail-ops.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Peter Williams <peterw@ximian.com> - * Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef MAIL_OPS_H -#define MAIL_OPS_H - -G_BEGIN_DECLS - -#include <camel/camel.h> - -#include <mail/mail-mt.h> -#include <mail/e-mail-backend.h> - -void mail_transfer_messages (EMailSession *session, - CamelFolder *source, - GPtrArray *uids, - gboolean delete_from_source, - const gchar *dest_uri, - guint32 dest_flags, - void (*done) (gboolean ok, gpointer data), - gpointer data); - -void mail_sync_folder (CamelFolder *folder, - void (*done) (CamelFolder *folder, gpointer data), gpointer data); - -void mail_sync_store (CamelStore *store, gint expunge, - void (*done) (CamelStore *store, gpointer data), gpointer data); - -void mail_refresh_folder (CamelFolder *folder, - void (*done) (CamelFolder *folder, gpointer data), - gpointer data); - -void mail_expunge_folder (CamelFolder *folder); -void mail_empty_trash (CamelStore *store); - -/* transfer (copy/move) a folder */ -void mail_xfer_folder (const gchar *src_uri, const gchar *dest_uri, gboolean remove_source, - void (*done) (gchar *src_uri, gchar *dest_uri, gboolean remove_source, - CamelFolder *folder, gpointer data), - gpointer data); - -/* yeah so this is messy, but it does a lot, maybe i can consolidate all user_data's to be the one */ -void mail_send_queue (EMailSession *session, - CamelFolder *queue, - CamelTransport *transport, - const gchar *type, - GCancellable *cancellable, - CamelFilterGetFolderFunc get_folder, - gpointer get_data, - CamelFilterStatusFunc *status, - gpointer status_data, - void (*done)(gpointer data), - gpointer data); - -void mail_fetch_mail (CamelStore *store, - gint keep, - const gchar *type, - GCancellable *cancellable, - CamelFilterGetFolderFunc get_folder, - gpointer get_data, - CamelFilterStatusFunc *status, - gpointer status_data, - void (*done)(gpointer data), - gpointer data); - -void mail_filter_folder (EMailSession *session, - CamelFolder *source_folder, - GPtrArray *uids, - const gchar *type, - gboolean notify); - -/* filter driver execute shell command async callback */ -void mail_execute_shell_command (CamelFilterDriver *driver, gint argc, gchar **argv, gpointer data); - -gint mail_disconnect_store (CamelStore *store); - -G_END_DECLS - -#endif /* MAIL_OPS_H */ diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c index 4e206ea221..05a48c47ce 100644 --- a/mail/mail-send-recv.c +++ b/mail/mail-send-recv.c @@ -29,22 +29,26 @@ #include <glib/gi18n.h> -#include "libedataserver/e-account-list.h" +#include <libedataserver/e-account-list.h> -#include "shell/e-shell.h" -#include "e-util/e-account-utils.h" -#include "e-util/e-util.h" +#include <shell/e-shell.h> +#include <e-util/e-util.h> -#include "e-mail-folder-utils.h" -#include "e-mail-session.h" +#include <libemail-utils/e-account-utils.h> +#include <libemail-utils/mail-mt.h> + +#include <libemail-engine/e-mail-folder-utils.h> +#include <libemail-engine/e-mail-session.h> +#include <libemail-engine/mail-folder-cache.h> +#include <libemail-engine/mail-ops.h> +#include <libemail-engine/mail-tools.h> + +#include "e-mail-account-store.h" +#include "e-mail-ui-session.h" #include "em-event.h" #include "em-filter-rule.h" #include "em-utils.h" -#include "mail-folder-cache.h" -#include "mail-mt.h" -#include "mail-ops.h" #include "mail-send-recv.h" -#include "mail-tools.h" #define d(x) @@ -501,7 +505,7 @@ build_dialog (GtkWindow *parent, EMEventTargetSendReceive *target; GQueue queue = G_QUEUE_INIT; - account_store = e_mail_session_get_account_store (session); + account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session)); /* Convert the outgoing account to a CamelTransport. */ if (outgoing_account != NULL) { diff --git a/mail/mail-send-recv.h b/mail/mail-send-recv.h index cd11a4a9bb..fb49493060 100644 --- a/mail/mail-send-recv.h +++ b/mail/mail-send-recv.h @@ -24,7 +24,7 @@ #define MAIL_SEND_RECV_H #include <gtk/gtk.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> G_BEGIN_DECLS diff --git a/mail/mail-tools.c b/mail/mail-tools.c deleted file mode 100644 index 30ac175a18..0000000000 --- a/mail/mail-tools.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Dan Winship <danw@ximian.com> - * Peter Williams <peterw@ximian.com> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> - -#include <glib/gstdio.h> - -#include <glib/gi18n.h> - -#include "e-mail-session.h" -#include "em-utils.h" -#include "mail-folder-cache.h" -#include "mail-tools.h" - -/* **************************************** */ - -#ifndef G_OS_WIN32 - -static gchar * -mail_tool_get_local_movemail_path (CamelStore *store, - GError **error) -{ - const gchar *uid; - guchar *safe_uid, *c; - const gchar *data_dir; - gchar *path, *full; - struct stat st; - - uid = camel_service_get_uid (CAMEL_SERVICE (store)); - safe_uid = (guchar *) g_strdup ((const gchar *) uid); - for (c = safe_uid; *c; c++) - if (strchr("/:;=|%&#!*^()\\, ", *c) || !isprint((gint) *c)) - *c = '_'; - - data_dir = mail_session_get_data_dir (); - path = g_build_filename (data_dir, "spool", NULL); - - if (g_stat (path, &st) == -1 && g_mkdir_with_parents (path, 0700) == -1) { - g_set_error ( - error, G_FILE_ERROR, - g_file_error_from_errno (errno), - _("Could not create spool directory '%s': %s"), - path, g_strerror (errno)); - g_free (path); - return NULL; - } - - full = g_strdup_printf("%s/movemail.%s", path, safe_uid); - g_free (path); - g_free (safe_uid); - - return full; -} - -#endif - -gchar * -mail_tool_do_movemail (CamelStore *store, - GError **error) -{ -#ifndef G_OS_WIN32 - CamelService *service; - CamelProvider *provider; - CamelSettings *settings; - const gchar *src_path; - gchar *dest_path; - struct stat sb; - gboolean success; - - g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); - - service = CAMEL_SERVICE (store); - provider = camel_service_get_provider (service); - settings = camel_service_get_settings (service); - - g_return_val_if_fail (provider != NULL, NULL); - - if (g_strcmp0 (provider->protocol, "mbox") != 0) { - /* This is really only an internal error anyway */ - g_set_error ( - error, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_URL_INVALID, - _("Trying to movemail a non-mbox source '%s'"), - camel_service_get_uid (CAMEL_SERVICE (store))); - return NULL; - } - - src_path = camel_local_settings_get_path ( - CAMEL_LOCAL_SETTINGS (settings)); - - /* Set up our destination. */ - dest_path = mail_tool_get_local_movemail_path (store, error); - if (dest_path == NULL) - return NULL; - - /* Movemail from source to dest_path */ - success = camel_movemail (src_path, dest_path, error) != -1; - - if (g_stat (dest_path, &sb) < 0 || sb.st_size == 0) { - g_unlink (dest_path); /* Clean up the movemail.foo file. */ - g_free (dest_path); - return NULL; - } - - if (!success) { - g_free (dest_path); - return NULL; - } - - return dest_path; -#else - /* Unclear yet whether camel-movemail etc makes any sense on - * Win32, at least it is not ported yet. - */ - g_warning("%s: Not implemented", __FUNCTION__); - return NULL; -#endif -} - -gchar * -mail_tool_generate_forward_subject (CamelMimeMessage *msg) -{ - const gchar *subject; - gchar *fwd_subj; - const gint max_subject_length = 1024; - - subject = camel_mime_message_get_subject (msg); - - if (subject && *subject) { - /* Truncate insanely long subjects */ - if (strlen (subject) < max_subject_length) { - fwd_subj = g_strdup_printf ("[Fwd: %s]", subject); - } else { - /* We can't use %.*s because it depends on the - * locale being C/POSIX or UTF-8 to work correctly - * in glibc. */ - fwd_subj = g_malloc (max_subject_length + 11); - memcpy (fwd_subj, "[Fwd: ", 6); - memcpy (fwd_subj + 6, subject, max_subject_length); - memcpy (fwd_subj + 6 + max_subject_length, "...]", 5); - } - } else { - const CamelInternetAddress *from; - gchar *fromstr; - - from = camel_mime_message_get_from (msg); - if (from) { - fromstr = camel_address_format (CAMEL_ADDRESS (from)); - fwd_subj = g_strdup_printf ("[Fwd: %s]", fromstr); - g_free (fromstr); - } else - fwd_subj = g_strdup ("[Fwd: No Subject]"); - } - - return fwd_subj; -} - -struct _camel_header_raw * -mail_tool_remove_xevolution_headers (CamelMimeMessage *message) -{ - struct _camel_header_raw *scan, *list = NULL; - - for (scan = ((CamelMimePart *) message)->headers; scan; scan = scan->next) - if (!strncmp(scan->name, "X-Evolution", 11)) - camel_header_raw_append (&list, scan->name, scan->value, scan->offset); - - for (scan = list; scan; scan = scan->next) - camel_medium_remove_header ((CamelMedium *) message, scan->name); - - return list; -} - -void -mail_tool_restore_xevolution_headers (CamelMimeMessage *message, - struct _camel_header_raw *xev) -{ - CamelMedium *medium; - - medium = CAMEL_MEDIUM (message); - - for (; xev; xev = xev->next) - camel_medium_add_header (medium, xev->name, xev->value); -} - -CamelMimePart * -mail_tool_make_message_attachment (CamelMimeMessage *message) -{ - CamelMimePart *part; - const gchar *subject; - struct _camel_header_raw *xev; - gchar *desc; - - subject = camel_mime_message_get_subject (message); - if (subject) - desc = g_strdup_printf (_("Forwarded message - %s"), subject); - else - desc = g_strdup (_("Forwarded message")); - - /* rip off the X-Evolution headers */ - xev = mail_tool_remove_xevolution_headers (message); - camel_header_raw_clear (&xev); - - /* remove Bcc headers */ - camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc"); - - part = camel_mime_part_new (); - camel_mime_part_set_disposition (part, "inline"); - camel_mime_part_set_description (part, desc); - camel_medium_set_content ( - CAMEL_MEDIUM (part), CAMEL_DATA_WRAPPER (message)); - camel_mime_part_set_content_type (part, "message/rfc822"); - g_free (desc); - - return part; -} diff --git a/mail/mail-tools.h b/mail/mail-tools.h deleted file mode 100644 index 94b19c0d12..0000000000 --- a/mail/mail-tools.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Peter Williams <peterw@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef MAIL_TOOLS_H -#define MAIL_TOOLS_H - -#include <camel/camel.h> - -/* Does a camel_movemail into the local movemail folder - * and returns the path to the new movemail folder that was created. which shoudl be freed later */ -gchar *mail_tool_do_movemail (CamelStore *store, GError **error); - -struct _camel_header_raw *mail_tool_remove_xevolution_headers (CamelMimeMessage *message); -void mail_tool_restore_xevolution_headers (CamelMimeMessage *message, struct _camel_header_raw *); - -/* Generates the subject for a message forwarding @msg */ -gchar *mail_tool_generate_forward_subject (CamelMimeMessage *msg); - -/* Make a message into an attachment */ -CamelMimePart *mail_tool_make_message_attachment (CamelMimeMessage *message); - -#endif diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c index f5039d98ff..4b10e829de 100644 --- a/mail/mail-vfolder.c +++ b/mail/mail-vfolder.c @@ -31,20 +31,23 @@ #include "e-util/e-alert-dialog.h" #include "e-util/e-util-private.h" +#include "libemail-utils/mail-mt.h" +#include "libemail-engine/mail-folder-cache.h" +#include "libemail-engine/e-mail-folder-utils.h" +#include "libemail-engine/e-mail-session.h" +#include "libemail-engine/e-mail-utils.h" +#include "libemail-engine/mail-ops.h" +#include "libemail-engine/mail-tools.h" + #include "e-mail-backend.h" -#include "e-mail-session.h" -#include "e-mail-folder-utils.h" #include "em-folder-tree-model.h" #include "em-utils.h" #include "em-vfolder-context.h" #include "em-vfolder-editor.h" #include "em-vfolder-rule.h" #include "mail-autofilter.h" -#include "mail-folder-cache.h" -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-tools.h" #include "mail-vfolder.h" +#include "e-mail-ui-session.h" #define d(x) /* (printf("%s:%s: ", G_STRLOC, G_STRFUNC), (x))*/ @@ -1020,7 +1023,7 @@ vfolder_load_storage (EMailBackend *backend) config_dir = mail_session_get_config_dir (); session = e_mail_backend_get_session (backend); - vfolder_store = e_mail_session_get_vfolder_store (session); + vfolder_store = e_mail_ui_session_get_vfolder_store (E_MAIL_UI_SESSION(session)); g_signal_connect ( vfolder_store, "folder-deleted", diff --git a/mail/message-list.c b/mail/message-list.c index 98fd90babb..405e9d08cd 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -58,13 +58,16 @@ #include "table/e-tree-memory-callbacks.h" #include "table/e-tree-memory.h" -#include "e-mail-label-list-store.h" -#include "em-utils.h" -#include "mail-config.h" -#include "mail-mt.h" -#include "mail-ops.h" -#include "mail-tools.h" -#include "message-list.h" +#include "libemail-utils/mail-mt.h" +#include "libemail-engine/e-mail-utils.h" +#include "libemail-engine/mail-config.h" +#include "libemail-engine/mail-ops.h" +#include "libemail-engine/mail-tools.h" + +#include "mail/e-mail-label-list-store.h" +#include "mail/e-mail-ui-session.h" +#include "mail/em-utils.h" +#include "mail/message-list.h" #if HAVE_CLUTTER #include <clutter/clutter.h> @@ -1709,7 +1712,8 @@ ml_tree_value_at_ex (ETreeModel *etm, /* Get all applicable labels. */ struct LabelsData ld; - ld.store = e_mail_session_get_label_store (session); + ld.store = e_mail_ui_session_get_label_store ( + E_MAIL_UI_SESSION (session)); ld.labels_tag2iter = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gtk_tree_iter_free); for_node_and_subtree_if_collapsed (message_list, path, msg_info, add_all_labels_foreach, &ld); @@ -1791,7 +1795,8 @@ ml_tree_value_at_ex (ETreeModel *etm, struct LabelsData ld; GString *result = g_string_new (""); - ld.store = e_mail_session_get_label_store (session); + ld.store = e_mail_ui_session_get_label_store ( + E_MAIL_UI_SESSION (session)); ld.labels_tag2iter = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gtk_tree_iter_free); for_node_and_subtree_if_collapsed (message_list, path, msg_info, add_all_labels_foreach, &ld); @@ -4764,7 +4769,7 @@ regen_list_done (struct _regen_list_msg *m) GCancellable *cancellable; gboolean searching; - cancellable = e_activity_get_cancellable (m->base.activity); + cancellable = m->base.cancellable; if (m->ml->priv->destroyed) return; @@ -4956,7 +4961,7 @@ mail_regen_cancel (MessageList *ml) MailMsg *mm = link->data; GCancellable *cancellable; - cancellable = e_activity_get_cancellable (mm->activity); + cancellable = mm->cancellable; g_cancellable_cancel (cancellable); } diff --git a/mail/message-list.h b/mail/message-list.h index bd2e97b6f8..44a312e667 100644 --- a/mail/message-list.h +++ b/mail/message-list.h @@ -27,7 +27,7 @@ #include <camel/camel.h> #include <table/e-tree.h> -#include <mail/e-mail-session.h> +#include <libemail-engine/e-mail-session.h> /* Standard GObject macros */ #define MESSAGE_LIST_TYPE \ |