[evolution/email-factory-3-4: 2/23] Add EMailUISession to provide alert user and filter functionality.



commit ba6b3ec9ad8aae8f9f5698a6c15587c0d334cd2b
Author: Srinivasa Ragavan <sragavan gnome org>
Date:   Mon Oct 17 12:31:44 2011 +0530

    Add EMailUISession to provide alert user and filter functionality.

 mail/Makefile.am         |    4 +-
 mail/e-mail-backend.c    |    3 +-
 mail/e-mail-ui-session.c |  486 ++++++++++++++++++++++++++++++++++++++++++++++
 mail/e-mail-ui-session.h |   73 +++++++
 4 files changed, 563 insertions(+), 3 deletions(-)
---
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 0a26f2e..8661de4 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -70,8 +70,7 @@ 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-store.h					\
@@ -144,6 +143,7 @@ libevolution_mail_la_SOURCES =				\
 	e-mail-paned-view.c				\
 	e-mail-reader-utils.c				\
 	e-mail-reader.c					\
+	e-mail-ui-session.c				\
 	e-mail-sidebar.c				\
 	e-mail-store-utils.c				\
 	e-mail-tag-editor.c				\
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index 974fc94..21f3e46 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -56,6 +56,7 @@
 #include "libemail-engine/mail-ops.h"
 #include "mail/mail-vfolder.h"
 #include "mail/mail-send-recv.h"
+#include "mail/e-mail-ui-session.h"
 
 #define E_MAIL_BACKEND_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -878,7 +879,7 @@ 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);	
 	folder_cache = e_mail_session_get_folder_cache (priv->session);
 
diff --git a/mail/e-mail-ui-session.c b/mail/e-mail-ui-session.c
new file mode 100644
index 0000000..0f04101
--- /dev/null
+++ b/mail/e-mail-ui-session.c
@@ -0,0 +1,486 @@
+/*
+ * 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>
+
+#include <gconf/gconf-client.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 "libemail-utils/e-account-utils.h"
+#include "e-util/e-alert-dialog.h"
+#include "e-util/e-util-private.h"
+#include "libemail-utils/gconf-bridge.h"
+
+#include "libemail-engine/e-mail-folder-utils.h"
+#include "libemail-engine/e-mail-junk-filter.h"
+#include "libemail-engine/e-mail-local.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))
+
+struct _EMailUISessionPrivate {
+	FILE *filter_logfile;
+};
+
+G_DEFINE_TYPE_WITH_CODE (
+	EMailUISession,
+	e_mail_ui_session,
+	E_TYPE_MAIL_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;
+	EFlag *done;
+
+	guint allow_cancel : 1;
+	guint result : 1;
+	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)
+{
+	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 !allow_cancel, then we've already replied */
+	if (m->allow_cancel) {
+		m->result = button == GTK_RESPONSE_OK;
+		e_flag_set (m->done);
+	}
+
+	user_message_response_free (dialog, button, m);
+}
+
+static void
+user_message_exec (struct _user_message_msg *m,
+                   GCancellable *cancellable,
+                   GError **error)
+{
+	GtkWindow *parent;
+	const gchar *error_type;
+
+	if (!m->ismain && user_message_dialog != NULL) {
+		g_queue_push_tail (&user_message_queue, mail_msg_ref (m));
+		return;
+	}
+
+	switch (m->type) {
+		case CAMEL_SESSION_ALERT_INFO:
+			error_type = m->allow_cancel ?
+				"mail:session-message-info-cancel" :
+				"mail:session-message-info";
+			break;
+		case CAMEL_SESSION_ALERT_WARNING:
+			error_type = m->allow_cancel ?
+				"mail:session-message-warning-cancel" :
+				"mail:session-message-warning";
+			break;
+		case CAMEL_SESSION_ALERT_ERROR:
+			error_type = m->allow_cancel ?
+				"mail:session-message-error-cancel" :
+				"mail:session-message-error";
+			break;
+		default:
+			error_type = NULL;
+			g_return_if_reached ();
+	}
+
+	/* Pull in the active window from the shell to get a parent window */
+	parent = e_shell_get_active_window (e_shell_get_default ());
+	user_message_dialog = e_alert_dialog_new_for_args (
+		parent, error_type, m->prompt, NULL);
+	g_object_set (user_message_dialog, "resizable", TRUE, NULL);
+
+	/* 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 {
+		g_signal_connect (
+			user_message_dialog, "response",
+			G_CALLBACK (user_message_response), m);
+		gtk_widget_show (user_message_dialog);
+	}
+}
+
+static void
+user_message_free (struct _user_message_msg *m)
+{
+	g_free (m->prompt);
+	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)
+{
+	EShell *shell;
+	EShellBackend *shell_backend;
+	CamelFilterDriver *driver;
+	EFilterRule *rule = NULL;
+	const gchar *config_dir;
+	gchar *user, *system;
+	GConfClient *client;
+	ERuleContext *fc;
+	EMailUISessionPrivate *priv;
+
+	priv = E_MAIL_UI_SESSION_GET_PRIVATE (session);
+
+	shell = e_shell_get_default ();
+	shell_backend = e_shell_get_backend_by_name (shell, "mail");
+	g_return_val_if_fail (E_IS_MAIL_BACKEND (shell_backend), NULL);
+
+	client = gconf_client_get_default ();
+
+	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 (
+		E_MAIL_BACKEND (shell_backend));
+	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 (gconf_client_get_bool (client, "/apps/evolution/mail/filters/log", NULL)) {
+		if (priv->filter_logfile == NULL) {
+			gchar *filename;
+
+			filename = gconf_client_get_string (
+				client, "/apps/evolution/mail/filters/logfile", NULL);
+			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 (client);
+
+	return driver;
+}
+
+static void
+mail_ui_session_dispose (GObject *object)
+{
+	EMailUISessionPrivate *priv;
+
+	priv = E_MAIL_UI_SESSION_GET_PRIVATE (object);
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_mail_ui_session_parent_class)->dispose (object);
+}
+
+static void
+mail_ui_session_finalize (GObject *object)
+{
+	EMailUISessionPrivate *priv;
+
+	priv = E_MAIL_UI_SESSION_GET_PRIVATE (object);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_mail_ui_session_parent_class)->finalize (object);
+}
+
+
+static void
+mail_ui_session_constructed (GObject *object)
+{
+	EMailUISessionPrivate *priv;
+
+	priv = E_MAIL_UI_SESSION_GET_PRIVATE (object);
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_mail_ui_session_parent_class)->constructed (object);
+}
+
+static gboolean
+mail_ui_session_alert_user (CamelSession *session,
+                         CamelSessionAlertType type,
+                         const gchar *prompt,
+                         gboolean cancel)
+{
+	struct _user_message_msg *m;
+	GCancellable *cancellable;
+	gboolean result = TRUE;
+
+	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->allow_cancel = cancel;
+
+	if (cancel)
+		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 (cancel) {
+		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
+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->dispose = mail_ui_session_dispose;
+	object_class->finalize = mail_ui_session_finalize;
+	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;
+}
+
+static void
+e_mail_ui_session_init (EMailUISession *session)
+{
+
+}
+
+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);
+}
+
diff --git a/mail/e-mail-ui-session.h b/mail/e-mail-ui-session.h
new file mode 100644
index 0000000..44ca178
--- /dev/null
+++ b/mail/e-mail-ui-session.h
@@ -0,0 +1,73 @@
+/*
+ * 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-session.h>
+#include <libemail-engine/mail-folder-cache.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;
+};
+
+GType		e_mail_ui_session_get_type		(void);
+EMailSession *	e_mail_ui_session_new			(void);
+
+G_END_DECLS
+
+#endif /* E_MAIL_UI_SESSION_H */



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