[evolution-data-server] CamelSession: Add a "user-alert" signal.



commit 339771fe2a2f88b1cf4e706c466fdb5e6f9e6424
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Nov 26 21:14:44 2013 -0500

    CamelSession: Add a "user-alert" signal.
    
    This replaces the interactive "alert_user()" method since the
    interactive aspect is no longer used and proved difficult for
    applications to handle correctly.
    
    New functions:
    
      camel_session_user_alert()
    
    Removed functions:
    
      camel_session_alert_user()

 camel/camel-session.c                      |  140 +++++++++++++++++++++-------
 camel/camel-session.h                      |   18 ++--
 camel/providers/imapx/camel-imapx-server.c |   43 +++++----
 docs/reference/camel/camel-sections.txt    |    2 +-
 4 files changed, 141 insertions(+), 62 deletions(-)
---
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 123e41d..02619fd 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -38,6 +38,7 @@
 #include <glib/gstdio.h>
 
 #include "camel-debug.h"
+#include "camel-enumtypes.h"
 #include "camel-file-utils.h"
 #include "camel-folder.h"
 #include "camel-mime-message.h"
@@ -58,6 +59,7 @@
 #define d(x)
 
 typedef struct _AsyncContext AsyncContext;
+typedef struct _SignalClosure SignalClosure;
 typedef struct _JobData JobData;
 
 struct _CamelSessionPrivate {
@@ -83,6 +85,13 @@ struct _AsyncContext {
        gchar *auth_mechanism;
 };
 
+struct _SignalClosure {
+       GWeakRef session;
+       CamelService *service;
+       CamelSessionAlertType alert_type;
+       gchar *alert_message;
+};
+
 struct _JobData {
        CamelSession *session;
        GCancellable *cancellable;
@@ -103,6 +112,7 @@ enum {
 enum {
        JOB_STARTED,
        JOB_FINISHED,
+       USER_ALERT,
        LAST_SIGNAL
 };
 
@@ -129,6 +139,19 @@ async_context_free (AsyncContext *async_context)
 }
 
 static void
+signal_closure_free (SignalClosure *signal_closure)
+{
+       g_weak_ref_set (&signal_closure->session, NULL);
+
+       if (signal_closure->service != NULL)
+               g_object_unref (signal_closure->service);
+
+       g_free (signal_closure->alert_message);
+
+       g_slice_free (SignalClosure, signal_closure);
+}
+
+static void
 job_data_free (JobData *job_data)
 {
        g_object_unref (job_data->session);
@@ -210,6 +233,27 @@ session_start_job_cb (gpointer user_data)
        return FALSE;
 }
 
+static gboolean
+session_emit_user_alert_cb (gpointer user_data)
+{
+       SignalClosure *signal_closure = user_data;
+       CamelSession *session;
+
+       session = g_weak_ref_get (&signal_closure->session);
+
+       if (session != NULL) {
+               g_signal_emit (
+                       session,
+                       signals[USER_ALERT], 0,
+                       signal_closure->service,
+                       signal_closure->alert_type,
+                       signal_closure->alert_message);
+               g_object_unref (session);
+       }
+
+       return G_SOURCE_REMOVE;
+}
+
 static void
 session_set_user_data_dir (CamelSession *session,
                            const gchar *user_data_dir)
@@ -786,6 +830,28 @@ camel_session_class_init (CamelSessionClass *class)
                G_TYPE_NONE, 2,
                G_TYPE_CANCELLABLE,
                G_TYPE_POINTER);
+
+       /**
+        * CamelSession::user-alert:
+        * @session: the #CamelSession that received the signal
+        * @service: the #CamelService issuing the alert
+        * @type: the #CamelSessionAlertType
+        * @message: the alert message
+        *
+        * This purpose of this signal is to propagate a server-issued alert
+        * message from @service to a user interface.  The @type hints at the
+        * severity of the alert message.
+        **/
+       signals[USER_ALERT] = g_signal_new (
+               "user-alert",
+               G_OBJECT_CLASS_TYPE (class),
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (CamelSessionClass, user_alert),
+               NULL, NULL, NULL,
+               G_TYPE_NONE, 3,
+               CAMEL_TYPE_SERVICE,
+               CAMEL_TYPE_SESSION_ALERT_TYPE,
+               G_TYPE_STRING);
 }
 
 static void
@@ -1232,39 +1298,6 @@ camel_session_forget_password (CamelSession *session,
 }
 
 /**
- * camel_session_alert_user:
- * @session: a #CamelSession
- * @type: the type of alert (info, warning, or error)
- * @prompt: the message for the user
- * @button_captions: List of button captions to use. If NULL, only "Dismiss" button is shown.
- * @cancellable: (allow-non): optional #GCancellable object, or %NULL
- *
- * Presents the given @prompt to the user, in the style indicated by
- * @type. If @cancel is %TRUE, the user will be able to accept or
- * cancel. Otherwise, the message is purely informational.
- *
- * Returns: Index of pressed button from @button_captions, -1 if NULL.
- */
-gint
-camel_session_alert_user (CamelSession *session,
-                          CamelSessionAlertType type,
-                          const gchar *prompt,
-                          GList *button_captions,
-                          GCancellable *cancellable)
-{
-       CamelSessionClass *class;
-
-       g_return_val_if_fail (CAMEL_IS_SESSION (session), -1);
-       g_return_val_if_fail (prompt != NULL, -1);
-
-       class = CAMEL_SESSION_GET_CLASS (session);
-       g_return_val_if_fail (class->alert_user != NULL, -1);
-
-       return class->alert_user (
-               session, type, prompt, button_captions, cancellable);
-}
-
-/**
  * camel_session_trust_prompt:
  * @session: a #CamelSession
  * @service: a #CamelService
@@ -1306,6 +1339,47 @@ camel_session_trust_prompt (CamelSession *session,
 }
 
 /**
+ * camel_session_user_alert:
+ * @session: a #CamelSession
+ * @service: a #CamelService
+ * @type: a #CamelSessionAlertType
+ * @message: the message for the user
+ *
+ * Emits a #CamelSession:user_alert signal from an idle source on the main
+ * loop.  The idle source's priority is #G_PRIORITY_LOW.
+ *
+ * The purpose of the signal is to propagate a server-issued alert message
+ * from @service to a user interface.  The @type hints at the nature of the
+ * alert message.
+ *
+ * Since: 3.12
+ */
+void
+camel_session_user_alert (CamelSession *session,
+                          CamelService *service,
+                          CamelSessionAlertType type,
+                          const gchar *message)
+{
+       SignalClosure *signal_closure;
+
+       g_return_if_fail (CAMEL_IS_SESSION (session));
+       g_return_if_fail (CAMEL_IS_SERVICE (service));
+       g_return_if_fail (message != NULL);
+
+       signal_closure = g_slice_new0 (SignalClosure);
+       g_weak_ref_set (&signal_closure->session, session);
+       signal_closure->service = g_object_ref (service);
+       signal_closure->alert_type = type;
+       signal_closure->alert_message = g_strdup (message);
+
+       camel_session_idle_add (
+               session, G_PRIORITY_LOW,
+               session_emit_user_alert_cb,
+               signal_closure,
+               (GDestroyNotify) signal_closure_free);
+}
+
+/**
  * camel_session_lookup_addressbook:
  *
  * Since: 2.22
diff --git a/camel/camel-session.h b/camel/camel-session.h
index 30f4722..c56ef25 100644
--- a/camel/camel-session.h
+++ b/camel/camel-session.h
@@ -113,11 +113,6 @@ struct _CamelSessionClass {
                                                 CamelService *service,
                                                 const gchar *item,
                                                 GError **error);
-       gint            (*alert_user)           (CamelSession *session,
-                                                CamelSessionAlertType type,
-                                                const gchar *prompt,
-                                                GList *button_captions,
-                                                GCancellable *cancellable);
        CamelCertTrust  (*trust_prompt)         (CamelSession *session,
                                                 CamelService *service,
                                                 GTlsCertificate *certificate,
@@ -171,6 +166,10 @@ struct _CamelSessionClass {
        void            (*job_finished)         (CamelSession *session,
                                                 GCancellable *cancellable,
                                                 const GError *error);
+       void            (*user_alert)           (CamelSession *session,
+                                                CamelService *service,
+                                                CamelSessionAlertType type,
+                                                const gchar *message);
 };
 
 GType          camel_session_get_type          (void);
@@ -203,15 +202,14 @@ gboolean  camel_session_forget_password   (CamelSession *session,
                                                 CamelService *service,
                                                 const gchar *item,
                                                 GError **error);
-gint           camel_session_alert_user        (CamelSession *session,
-                                                CamelSessionAlertType type,
-                                                const gchar *prompt,
-                                                GList *button_captions,
-                                                GCancellable *cancellable);
 CamelCertTrust camel_session_trust_prompt      (CamelSession *session,
                                                 CamelService *service,
                                                 GTlsCertificate *certificate,
                                                 GTlsCertificateFlags errors);
+void           camel_session_user_alert        (CamelSession *session,
+                                                CamelService *service,
+                                                CamelSessionAlertType type,
+                                                const gchar *message);
 gboolean       camel_session_get_online        (CamelSession *session);
 void           camel_session_set_online        (CamelSession *session,
                                                 gboolean online);
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index da9fd27..6a9d385 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -2743,37 +2743,44 @@ imapx_untagged_ok_no_bad (CamelIMAPXServer *is,
                break;
        case IMAPX_ALERT:
                c (is->tagprefix, "ALERT!: %s\n", is->priv->context->sinfo->text);
-               g_mutex_lock (&is->priv->known_alerts_lock);
+               {
+                       const gchar *alert_message;
+                       gboolean emit_alert = FALSE;
+
+                       g_mutex_lock (&is->priv->known_alerts_lock);
 
-               if (is->priv->context->sinfo->text &&
-                   !g_hash_table_lookup (is->priv->known_alerts, is->priv->context->sinfo->text)) {
-                       CamelIMAPXStore *store;
+                       alert_message = is->priv->context->sinfo->text;
+
+                       if (alert_message != NULL) {
+                               emit_alert = !g_hash_table_contains (
+                                       is->priv->known_alerts,
+                                       alert_message);
+                       }
 
-                       store = camel_imapx_server_ref_store (is);
-                       if (store) {
-                               const gchar *alert = is->priv->context->sinfo->text;
-                               gchar *msg;
+                       if (emit_alert) {
+                               CamelIMAPXStore *store;
                                CamelService *service;
                                CamelSession *session;
 
-                               g_hash_table_insert (is->priv->known_alerts, g_strdup (alert), 
GINT_TO_POINTER (1));
+                               store = camel_imapx_server_ref_store (is);
+
+                               g_hash_table_add (
+                                       is->priv->known_alerts,
+                                       g_strdup (alert_message));
 
                                service = CAMEL_SERVICE (store);
                                session = camel_service_get_session (service);
 
-                               msg = g_strdup_printf (
-                                       _("Alert from IMAP server %s:\n%s"),
-                                       camel_service_get_display_name (service), alert);
-                               camel_session_alert_user (
-                                       session, CAMEL_SESSION_ALERT_WARNING,
-                                       msg, NULL, cancellable);
-                               g_free (msg);
+                               camel_session_user_alert (
+                                       session, service,
+                                       CAMEL_SESSION_ALERT_WARNING,
+                                       alert_message);
 
                                g_object_unref (store);
                        }
-               }
 
-               g_mutex_unlock (&is->priv->known_alerts_lock);
+                       g_mutex_unlock (&is->priv->known_alerts_lock);
+               }
                break;
        case IMAPX_PARSE:
                c (is->tagprefix, "PARSE: %s\n", is->priv->context->sinfo->text);
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index be4fe80..75f5fac 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -1909,8 +1909,8 @@ camel_session_list_services
 camel_session_remove_services
 camel_session_get_password
 camel_session_forget_password
-camel_session_alert_user
 camel_session_trust_prompt
+camel_session_user_alert
 camel_session_get_online
 camel_session_set_online
 camel_session_get_filter_driver


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