[evolution-ews] Bug #670939 - Reminder to change out of office status
- From: Fabiano Fidêncio <ffidencio src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Bug #670939 - Reminder to change out of office status
- Date: Thu, 11 Apr 2013 20:47:37 +0000 (UTC)
commit 952805f476bee0a7eae4092aec690b8923d1514a
Author: Fabiano Fidêncio <fidencio redhat com>
Date: Tue Mar 26 16:32:24 2013 +0100
Bug #670939 - Reminder to change out of office status
src/camel/Makefile.am | 31 ++-
src/camel/camel-ews-enums.h | 34 ++
src/camel/camel-ews-store.c | 239 +++++++++-
src/camel/camel-ews-store.h | 15 +
src/configuration/Makefile.am | 2 +
src/configuration/e-ews-ooo-notificator.c | 526 ++++++++++++++++++++
src/configuration/e-ews-ooo-notificator.h | 64 +++
src/configuration/module-ews-configuration.c | 2 +
.../module-ews-configuration.error.xml | 4 +
9 files changed, 914 insertions(+), 3 deletions(-)
---
diff --git a/src/camel/Makefile.am b/src/camel/Makefile.am
index d9a6616..7d16f83 100644
--- a/src/camel/Makefile.am
+++ b/src/camel/Makefile.am
@@ -3,6 +3,24 @@ NULL =
camel_provider_LTLIBRARIES = libcamelews.la
camel_provider_DATA = libcamelews.urls
+ENUM_TYPES = camel-ews-enums.h
+
+camel-ews-enumtypes.h: $(top_srcdir)/enumtypes.h.template $(ENUM_TYPES)
+ $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template $(top_srcdir)/enumtypes.h.template \
+ --fhead "#ifndef CAMEL_EWS_ENUMTYPES_H\n#define CAMEL_EWS_ENUMTYPES_H\n" \
+ --ftail "#endif /* CAMEL_EWS_ENUMTYPES_H */\n" \
+ $(ENUM_TYPES)) > $@
+
+camel-ews-enumtypes.c: $(top_srcdir)/enumtypes.h.template $(ENUM_TYPES)
+ $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template $(top_srcdir)/enumtypes.c.template \
+ --fhead "#include \"camel-ews-enumtypes.h\"" \
+ $(ENUM_TYPES)) > $@
+
+ENUM_GENERATED = \
+ camel-ews-enumtypes.h \
+ camel-ews-enumtypes.c \
+ $(NULL)
+
libcamelews_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_srcdir) \
@@ -21,6 +39,7 @@ libcamelews_la_CPPFLAGS = \
$(NULL)
libcamelews_la_SOURCES = \
+ camel-ews-enumtypes.c \
camel-ews-folder.c \
camel-ews-store-summary.c \
camel-ews-store.c \
@@ -31,6 +50,8 @@ libcamelews_la_SOURCES = \
$(NULL)
noinst_HEADERS = \
+ camel-ews-enums.h \
+ camel-ews-enumtypes.h \
camel-ews-folder.h \
camel-ews-private.h \
camel-ews-store-summary.h \
@@ -55,6 +76,14 @@ libcamelews_la_LIBADD = \
$(E_DATA_SERVER_LIBS) \
$(NULL)
-EXTRA_DIST = libcamelews.urls
+BUILT_SOURCES = \
+ $(ENUM_GENERATED) \
+ $(NULL)
+
+EXTRA_DIST = \
+ libcamelews.urls \
+ $(NULL)
+
+CLEANFILES = $(BUILT_SOURCES)
-include $(top_srcdir)/git.mk
diff --git a/src/camel/camel-ews-enums.h b/src/camel/camel-ews-enums.h
new file mode 100644
index 0000000..8c2af2d
--- /dev/null
+++ b/src/camel/camel-ews-enums.h
@@ -0,0 +1,34 @@
+/*
+ * camel-ews-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 CAMEL_EWS_ENUMS_H
+#define CAMEL_EWS_ENUMS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ CAMEL_EWS_STORE_OOO_ALERT_STATE_UNKNOWN,
+ CAMEL_EWS_STORE_OOO_ALERT_STATE_NOTIFIED,
+ CAMEL_EWS_STORE_OOO_ALERT_STATE_CLOSED
+} CamelEwsStoreOooAlertState;
+
+G_END_DECLS
+
+#endif /* CAMEL_EWS_ENUMS_H */
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index f8676bb..9f9801f 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -44,11 +44,13 @@
#include "server/camel-ews-settings.h"
#include "server/e-ews-item-change.h"
#include "server/e-ews-message.h"
+#include "server/e-ews-oof-settings.h"
#include "camel-ews-folder.h"
#include "camel-ews-store.h"
#include "camel-ews-summary.h"
#include "camel-ews-utils.h"
+#include "camel-ews-enumtypes.h"
#ifdef G_OS_WIN32
#include <winsock2.h>
@@ -69,6 +71,8 @@ struct _CamelEwsStorePrivate {
GMutex get_finfo_lock;
EEwsConnection *connection;
GMutex connection_lock;
+ gboolean has_ooo_set;
+ CamelEwsStoreOooAlertState ooo_alert_state;
GSList *public_folders; /* EEwsFolder * objects */
};
@@ -79,6 +83,12 @@ static void camel_ews_store_initable_init (GInitableIface *interface);
static void camel_ews_subscribable_init (CamelSubscribableInterface *interface);
static GInitableIface *parent_initable_interface;
+enum {
+ PROP_0,
+ PROP_HAS_OOO_SET,
+ PROP_OOO_ALERT_STATE
+};
+
G_DEFINE_TYPE_WITH_CODE (
CamelEwsStore, camel_ews_store, CAMEL_TYPE_OFFLINE_STORE,
G_IMPLEMENT_INTERFACE (
@@ -87,6 +97,96 @@ G_DEFINE_TYPE_WITH_CODE (
CAMEL_TYPE_SUBSCRIBABLE, camel_ews_subscribable_init))
static void
+ews_store_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_HAS_OOO_SET:
+ camel_ews_store_set_has_ooo_set (
+ CAMEL_EWS_STORE (object),
+ g_value_get_boolean (value));
+ return;
+ case PROP_OOO_ALERT_STATE:
+ camel_ews_store_set_ooo_alert_state (
+ CAMEL_EWS_STORE (object),
+ g_value_get_enum (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+ews_store_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_HAS_OOO_SET:
+ g_value_set_boolean (
+ value,
+ camel_ews_store_get_has_ooo_set (
+ CAMEL_EWS_STORE (object)));
+ return;
+ case PROP_OOO_ALERT_STATE:
+ g_value_set_enum (
+ value,
+ camel_ews_store_get_ooo_alert_state (
+ CAMEL_EWS_STORE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+void
+camel_ews_store_set_has_ooo_set (CamelEwsStore *ews_store,
+ gboolean has_ooo_set)
+{
+ g_return_if_fail (CAMEL_IS_EWS_STORE (ews_store));
+
+ if ((ews_store->priv->has_ooo_set ? 1 : 0) == (has_ooo_set ? 1 : 0))
+ return;
+
+ ews_store->priv->has_ooo_set = has_ooo_set;
+ g_object_notify (G_OBJECT (ews_store), "has-ooo-set");
+}
+
+gboolean
+camel_ews_store_get_has_ooo_set (const CamelEwsStore *ews_store)
+{
+ g_return_val_if_fail (CAMEL_IS_EWS_STORE (ews_store), FALSE);
+
+ return ews_store->priv->has_ooo_set;
+}
+
+void
+camel_ews_store_set_ooo_alert_state (CamelEwsStore *ews_store,
+ CamelEwsStoreOooAlertState state)
+{
+ g_return_if_fail (CAMEL_IS_EWS_STORE (ews_store));
+
+ if (ews_store->priv->ooo_alert_state == state)
+ return;
+
+ ews_store->priv->ooo_alert_state = state;
+ g_object_notify (G_OBJECT (ews_store), "ooo-alert-state");
+}
+
+CamelEwsStoreOooAlertState
+camel_ews_store_get_ooo_alert_state (const CamelEwsStore *ews_store)
+{
+ g_return_val_if_fail (
+ CAMEL_IS_EWS_STORE (ews_store),
+ CAMEL_EWS_STORE_OOO_ALERT_STATE_UNKNOWN);
+
+ return ews_store->priv->ooo_alert_state;
+}
+
+static void
ews_migrate_to_user_cache_dir (CamelService *service)
{
const gchar *user_data_dir, *user_cache_dir;
@@ -488,6 +588,43 @@ ews_update_folder_hierarchy (CamelEwsStore *ews_store,
g_free (sync_state);
}
+static void
+ews_update_has_ooo_set (CamelSession *session,
+ GCancellable *cancellable,
+ gpointer user_data,
+ GError **error)
+{
+
+ CamelEwsStore *ews_store = user_data;
+ EEwsOofSettings *oof_settings;
+ EEwsOofState oof_state;
+ GError *local_error = NULL;
+
+ camel_operation_push_message (cancellable, _("Checking \"Out of Office\" settings"));
+
+ oof_settings = e_ews_oof_settings_new_sync (ews_store->priv->connection, cancellable, &local_error);
+ if (local_error != NULL) {
+ g_propagate_error (error, local_error);
+ camel_operation_pop_message (cancellable);
+ return;
+ }
+
+ oof_state = e_ews_oof_settings_get_state (oof_settings);
+ switch (oof_state) {
+ case E_EWS_OOF_STATE_ENABLED:
+ camel_ews_store_set_has_ooo_set (ews_store, TRUE);
+ break;
+ case E_EWS_OOF_STATE_DISABLED:
+ case E_EWS_OOF_STATE_SCHEDULED:
+ camel_ews_store_set_has_ooo_set (ews_store, FALSE);
+ break;
+ default:
+ break;
+ }
+
+ camel_operation_pop_message (cancellable);
+}
+
static gboolean
ews_connect_sync (CamelService *service,
GCancellable *cancellable,
@@ -516,13 +653,23 @@ ews_connect_sync (CamelService *service,
success = camel_session_authenticate_sync (
session, service, NULL, cancellable, error);
- g_object_unref (session);
+ if (success) {
+ CamelEwsStoreOooAlertState state;
+
+ state = camel_ews_store_get_ooo_alert_state (ews_store);
+ if (state == CAMEL_EWS_STORE_OOO_ALERT_STATE_UNKNOWN)
+ camel_session_submit_job (
+ session,
+ ews_update_has_ooo_set,
+ g_object_ref (ews_store),
+ g_object_unref);
- if (success)
camel_offline_store_set_online_sync (
CAMEL_OFFLINE_STORE (ews_store),
TRUE, cancellable, NULL);
+ }
+ g_object_unref (session);
return success;
}
@@ -2591,6 +2738,67 @@ camel_ews_store_maybe_disconnect (CamelEwsStore *store,
}
static void
+ews_store_unset_oof_settings_state (CamelSession *session,
+ GCancellable *cancellable,
+ gpointer user_data,
+ GError **error)
+{
+
+ CamelEwsStore *ews_store = user_data;
+ EEwsConnection *connection;
+ EEwsOofSettings *oof_settings;
+ EEwsOofState state;
+ GError *local_error = NULL;
+
+ camel_operation_push_message (cancellable, _("Unsetting the \"Out of Office\" status"));
+
+ connection = camel_ews_store_ref_connection (ews_store);
+ oof_settings = e_ews_oof_settings_new_sync (connection, cancellable, &local_error);
+ g_object_unref (connection);
+ if (local_error != NULL) {
+ g_propagate_error (error, local_error);
+ camel_operation_pop_message (cancellable);
+ return;
+ }
+
+ state = e_ews_oof_settings_get_state (oof_settings);
+ if (state == E_EWS_OOF_STATE_DISABLED) {
+ g_object_unref (oof_settings);
+ camel_operation_pop_message (cancellable);
+ return;
+ }
+
+ e_ews_oof_settings_set_state (oof_settings, E_EWS_OOF_STATE_DISABLED);
+ e_ews_oof_settings_submit_sync (oof_settings, cancellable, error);
+ g_object_unref (oof_settings);
+ if (local_error != NULL)
+ g_propagate_error (error, local_error);
+
+ camel_operation_pop_message (cancellable);
+
+}
+
+void
+camel_ews_store_unset_oof_settings_state (CamelEwsStore *ews_store)
+{
+ CamelService *service;
+ CamelSession *session;
+
+ g_return_if_fail (CAMEL_IS_EWS_STORE (ews_store));
+
+ service = CAMEL_SERVICE (ews_store);
+ session = camel_service_ref_session (service);
+
+ camel_session_submit_job (
+ session,
+ ews_store_unset_oof_settings_state,
+ g_object_ref (ews_store),
+ g_object_unref);
+
+ g_object_unref (session);
+}
+
+static void
ews_store_dispose (GObject *object)
{
CamelEwsStore *ews_store;
@@ -2642,9 +2850,36 @@ camel_ews_store_class_init (CamelEwsStoreClass *class)
g_type_class_add_private (class, sizeof (CamelEwsStorePrivate));
object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = ews_store_set_property;
+ object_class->get_property = ews_store_get_property;
object_class->dispose = ews_store_dispose;
object_class->finalize = ews_store_finalize;
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_OOO_SET,
+ g_param_spec_boolean (
+ "has-ooo-set",
+ "Has OOO Set",
+ "Has Out of Office state set",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_OOO_ALERT_STATE,
+ g_param_spec_enum (
+ "ooo-alert-state",
+ "Out of Office Alert State",
+ "The state of the Out of Office Alert",
+ E_TYPE_EWS_STORE_OOO_ALERT_STATE,
+ CAMEL_EWS_STORE_OOO_ALERT_STATE_UNKNOWN,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
service_class = CAMEL_SERVICE_CLASS (class);
service_class->settings_type = CAMEL_TYPE_EWS_SETTINGS;
service_class->query_auth_types_sync = ews_store_query_auth_types_sync;
diff --git a/src/camel/camel-ews-store.h b/src/camel/camel-ews-store.h
index 0420f47..9d934f6 100644
--- a/src/camel/camel-ews-store.h
+++ b/src/camel/camel-ews-store.h
@@ -25,6 +25,7 @@
#define CAMEL_EWS_STORE_H
#include <camel/camel.h>
+#include <camel/camel-ews-enums.h>
#include "server/e-ews-connection.h"
@@ -93,6 +94,20 @@ void camel_ews_store_ensure_unique_path
void camel_ews_store_update_foreign_subfolders
(CamelEwsStore *ews_store,
const gchar *fid);
+void camel_ews_store_set_has_ooo_set
+ (CamelEwsStore *ews_store,
+ gboolean has_ooo_set);
+gboolean camel_ews_store_get_has_ooo_set
+ (const CamelEwsStore *ews_store);
+void camel_ews_store_set_ooo_alert_state
+ (CamelEwsStore *ews_store,
+ CamelEwsStoreOooAlertState state);
+CamelEwsStoreOooAlertState
+ camel_ews_store_get_ooo_alert_state
+ (const CamelEwsStore *ews_store);
+void camel_ews_store_unset_oof_settings_state
+ (CamelEwsStore *ews_store);
+
G_END_DECLS
diff --git a/src/configuration/Makefile.am b/src/configuration/Makefile.am
index 2896857..e37d41d 100644
--- a/src/configuration/Makefile.am
+++ b/src/configuration/Makefile.am
@@ -41,6 +41,8 @@ module_ews_configuration_la_SOURCES = \
e-ews-search-user.h \
e-ews-subscribe-foreign-folder.c \
e-ews-subscribe-foreign-folder.h \
+ e-ews-ooo-notificator.c \
+ e-ews-ooo-notificator.h \
$(NULL)
module_ews_configuration_la_LIBADD = \
diff --git a/src/configuration/e-ews-ooo-notificator.c b/src/configuration/e-ews-ooo-notificator.c
new file mode 100644
index 0000000..d97f48d
--- /dev/null
+++ b/src/configuration/e-ews-ooo-notificator.c
@@ -0,0 +1,526 @@
+/*
+ * e-ews-ooo-notificator.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-ews-ooo-notificator.h"
+#include "camel/camel-ews-store.h"
+#include "server/e-ews-oof-settings.h"
+
+#include <shell/e-shell.h>
+#include <shell/e-shell-view.h>
+#include <mail/e-mail-backend.h>
+#include <mail/e-mail-ui-session.h>
+#include <glib/gi18n-lib.h>
+
+#define E_EWS_OOO_NOTIFICATOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_EWS_OOO_NOTIFICATOR, EEwsOooNotificatorPrivate))
+
+typedef gboolean (*EEwsOooNotificationDispatcherFunction) (gpointer data);
+
+struct _EEwsOooNotificatorPrivate
+{
+ EShell *shell;
+ EMailAccountStore *account_store;
+ GList *stores;
+ GHashTable *alerts;
+};
+
+typedef struct _EEwsOooNotificatorDispatcherData
+{
+ EEwsOooNotificator *extension;
+ CamelEwsStore *ews_store;
+ guint timeout_id;
+} EEwsOooNotificatorDispatcherData;
+
+G_DEFINE_DYNAMIC_TYPE (
+ EEwsOooNotificator,
+ e_ews_ooo_notificator,
+ E_TYPE_EXTENSION)
+
+/* Forward declarations */
+static void e_ews_ooo_notificator_has_ooo_set_cb (EEwsOooNotificator *extension,
+ GParamSpec *pspec,
+ CamelEwsStore *ews_store);
+static void e_ews_ooo_notificator_service_disabled_cb (EEwsOooNotificator *extension,
+ CamelService *service,
+ EMailAccountStore *account_store);
+static void e_ews_ooo_notificator_service_removed_cb (EEwsOooNotificator *extension,
+ CamelService *service,
+ EMailAccountStore *session);
+static void e_ews_ooo_notificator_service_added_cb (EEwsOooNotificator *extension,
+ CamelService *service,
+ EMailAccountStore *session);
+static void e_ews_ooo_notificator_online_cb (EEwsOooNotificator* extension,
+ GParamSpec *pspec,
+ EShell *shell);
+
+static EShellView *
+e_ews_ooo_notificator_get_extensible (EEwsOooNotificator *extension)
+{
+ EExtensible *extensible;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (extension));
+
+ return E_SHELL_VIEW (extensible);
+}
+
+static void
+e_ews_ooo_notificator_dispatcher_data_free (gpointer user_data)
+{
+ EEwsOooNotificatorDispatcherData *data = user_data;
+
+ if (data->extension)
+ g_object_unref (data->extension);
+ if (data->ews_store)
+ g_object_unref (data->ews_store);
+ g_free (data);
+}
+
+static void
+e_ews_ooo_notificator_unset_on_server_cb (EEwsOooNotificatorDispatcherData *data,
+ GtkAction *action)
+{
+ EAlert *alert;
+ camel_ews_store_unset_oof_settings_state (data->ews_store);
+ camel_ews_store_set_ooo_alert_state (
+ data->ews_store, CAMEL_EWS_STORE_OOO_ALERT_STATE_CLOSED);
+
+ alert = g_hash_table_lookup (data->extension->priv->alerts, data->ews_store);
+ if (alert)
+ g_hash_table_remove (data->extension->priv->alerts, data->ews_store);
+
+ if (data->timeout_id) {
+ g_source_remove (data->timeout_id);
+ data->timeout_id = 0;
+ }
+}
+
+static void
+e_ews_ooo_notificator_dismiss_cb (EEwsOooNotificatorDispatcherData *data,
+ gint response_id,
+ EAlert *alert)
+{
+
+ if (response_id == GTK_RESPONSE_CLOSE) {
+ camel_ews_store_set_ooo_alert_state (
+ data->ews_store, CAMEL_EWS_STORE_OOO_ALERT_STATE_CLOSED);
+ g_hash_table_remove (data->extension->priv->alerts, data->ews_store);
+ }
+
+ if (data->timeout_id) {
+ g_source_remove (data->timeout_id);
+ data->timeout_id = 0;
+ }
+}
+
+static void
+e_ews_ooo_notificator_hide_notification (EEwsOooNotificator *extension,
+ CamelEwsStore *ews_store)
+{
+ EAlert *alert;
+
+ alert = g_hash_table_lookup (extension->priv->alerts, ews_store);
+ if (alert) {
+ e_alert_response (alert, GTK_RESPONSE_NONE);
+ g_hash_table_remove (extension->priv->alerts, ews_store);
+ }
+}
+
+static gboolean
+e_ews_ooo_notificator_hide_notification_by_timeout_cb (gpointer user_data)
+{
+ EEwsOooNotificatorDispatcherData *data = user_data;
+
+ e_ews_ooo_notificator_hide_notification (data->extension, data->ews_store);
+
+ return FALSE;
+}
+
+static void
+e_ews_ooo_notificator_show_notification (EEwsOooNotificator *extension,
+ CamelEwsStore *ews_store)
+{
+ EAlert *alert;
+ EShellView *view;
+ EShellContent *shell_content;
+ EEwsOooNotificatorDispatcherData *data;
+ GtkAction *action;
+ const gchar *account_name;
+
+ data = g_new0 (EEwsOooNotificatorDispatcherData, 1);
+ data->extension = g_object_ref (extension);
+ data->ews_store = g_object_ref (ews_store);
+
+ view = e_ews_ooo_notificator_get_extensible (extension);
+ shell_content = e_shell_view_get_shell_content (view);
+
+ account_name = camel_service_get_display_name (CAMEL_SERVICE (ews_store));
+ alert = e_alert_new ("ews:has-ooo-set", account_name, NULL);
+
+ g_signal_connect_swapped (
+ alert,
+ "response",
+ G_CALLBACK (e_ews_ooo_notificator_dismiss_cb), data);
+
+ action = gtk_action_new (
+ "ooo-unset-on-server",
+ _("Unset on Server"),
+ _("Unset the \"Out of Office\" status"),
+ GTK_STOCK_OK);
+ g_signal_connect_swapped (
+ action,
+ "activate",
+ G_CALLBACK (e_ews_ooo_notificator_unset_on_server_cb), data);
+ e_alert_add_action (alert, action, 0);
+
+ g_hash_table_insert (extension->priv->alerts, ews_store, alert);
+ e_alert_sink_submit_alert (E_ALERT_SINK (shell_content), alert);
+
+ /* If the user doesn't cancel the notify, it will be hide automatically in 5 minutes */
+ data->timeout_id = g_timeout_add_seconds_full (
+ G_PRIORITY_DEFAULT, 300,
+ e_ews_ooo_notificator_hide_notification_by_timeout_cb,
+ data, e_ews_ooo_notificator_dispatcher_data_free);
+}
+
+static gboolean
+e_ews_ooo_notificator_has_ooo_set (gpointer user_data)
+{
+ EEwsOooNotificatorDispatcherData *data = user_data;
+ CamelEwsStoreOooAlertState alert_state;
+ gboolean has_ooo_set;
+
+ alert_state = camel_ews_store_get_ooo_alert_state (data->ews_store);
+ has_ooo_set = camel_ews_store_get_has_ooo_set (data->ews_store);
+
+ if (has_ooo_set && alert_state == CAMEL_EWS_STORE_OOO_ALERT_STATE_UNKNOWN) {
+ e_ews_ooo_notificator_show_notification (data->extension, data->ews_store);
+ camel_ews_store_set_ooo_alert_state (data->ews_store,
CAMEL_EWS_STORE_OOO_ALERT_STATE_NOTIFIED);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+e_ews_ooo_notificator_service_disabled (gpointer user_data)
+{
+ EEwsOooNotificatorDispatcherData *data = user_data;
+ CamelEwsStoreOooAlertState state;
+
+ e_ews_ooo_notificator_hide_notification (data->extension, data->ews_store);
+ state = camel_ews_store_get_ooo_alert_state (data->ews_store);
+ if (state != CAMEL_EWS_STORE_OOO_ALERT_STATE_CLOSED)
+ camel_ews_store_set_ooo_alert_state (data->ews_store,
CAMEL_EWS_STORE_OOO_ALERT_STATE_UNKNOWN);
+ camel_ews_store_set_has_ooo_set (data->ews_store, FALSE);
+
+ return FALSE;
+}
+
+static gboolean
+e_ews_ooo_notificator_service_removed (gpointer user_data)
+{
+ EEwsOooNotificatorDispatcherData *data = user_data;
+
+ e_ews_ooo_notificator_hide_notification (data->extension, data->ews_store);
+ g_signal_handlers_disconnect_by_func (
+ data->ews_store,
+ e_ews_ooo_notificator_has_ooo_set_cb,
+ data->extension);
+ data->extension->priv->stores = g_list_remove (
+ data->extension->priv->stores, data->ews_store);
+ g_object_unref (data->ews_store);
+
+ return FALSE;
+}
+
+/*
+ * GTK+ UI calls cannot be done in a dedicated thread.
+ * So, let's ensure that our functions (that do something in the UI) will run
+ * in the main thread, calling them through g_timeout_add_full().
+ */
+static void
+e_ews_ooo_notificator_dispatcher (EEwsOooNotificatorDispatcherData *data,
+ EEwsOooNotificationDispatcherFunction function,
+ GDestroyNotify destroy_data)
+{
+ g_timeout_add_full (G_PRIORITY_DEFAULT, 1, function, data, destroy_data);
+}
+
+static void
+e_ews_ooo_notificator_has_ooo_set_cb (EEwsOooNotificator *extension,
+ GParamSpec *pspec,
+ CamelEwsStore *ews_store)
+{
+ EEwsOooNotificatorDispatcherData *data;
+
+ data = g_new0 (EEwsOooNotificatorDispatcherData, 1);
+ data->extension = g_object_ref (extension);
+ data->ews_store = g_object_ref (ews_store);
+
+ e_ews_ooo_notificator_dispatcher (
+ data,
+ e_ews_ooo_notificator_has_ooo_set,
+ e_ews_ooo_notificator_dispatcher_data_free);
+}
+
+static void
+e_ews_ooo_notificator_service_disabled_cb (EEwsOooNotificator *extension,
+ CamelService *service,
+ EMailAccountStore *account_store)
+{
+
+ EEwsOooNotificatorDispatcherData *data;
+
+ if (!CAMEL_IS_EWS_STORE (service))
+ return;
+
+ data = g_new0 (EEwsOooNotificatorDispatcherData, 1);
+ data->extension = g_object_ref (extension);
+ data->ews_store = g_object_ref (CAMEL_EWS_STORE (service));
+
+ e_ews_ooo_notificator_dispatcher (
+ data,
+ e_ews_ooo_notificator_service_disabled,
+ e_ews_ooo_notificator_dispatcher_data_free);
+}
+
+static void
+e_ews_ooo_notificator_service_removed_cb (EEwsOooNotificator *extension,
+ CamelService *service,
+ EMailAccountStore *session)
+{
+ EEwsOooNotificatorDispatcherData *data;
+
+ if (!CAMEL_IS_EWS_STORE (service))
+ return;
+
+ data = g_new0 (EEwsOooNotificatorDispatcherData, 1);
+ data->extension = g_object_ref (extension);
+ data->ews_store = g_object_ref (CAMEL_EWS_STORE (service));
+
+ e_ews_ooo_notificator_dispatcher (
+ data,
+ e_ews_ooo_notificator_service_removed,
+ e_ews_ooo_notificator_dispatcher_data_free);
+}
+
+static void
+e_ews_ooo_notificator_service_added_cb (EEwsOooNotificator *extension,
+ CamelService *service,
+ EMailAccountStore *session)
+{
+ CamelEwsStore *ews_store;
+
+ if (!CAMEL_IS_EWS_STORE (service))
+ return;
+
+ ews_store = CAMEL_EWS_STORE (service);
+ g_signal_connect_swapped (
+ ews_store, "notify::has-ooo-set",
+ G_CALLBACK (e_ews_ooo_notificator_has_ooo_set_cb), extension);
+ extension->priv->stores = g_list_append (extension->priv->stores, g_object_ref (ews_store));
+}
+
+static void
+e_ews_ooo_notificator_online_cb (EEwsOooNotificator* extension,
+ GParamSpec *pspec,
+ EShell *shell)
+{
+ GList *l;
+
+ if (e_shell_get_online (shell))
+ return;
+
+ for (l = extension->priv->stores; l; l = l->next) {
+ EEwsOooNotificatorDispatcherData *data;
+
+ data = g_new0 (EEwsOooNotificatorDispatcherData, 1);
+ data->extension = g_object_ref (extension);
+ data->ews_store = g_object_ref (CAMEL_EWS_STORE (l->data));
+
+ e_ews_ooo_notificator_dispatcher (
+ data,
+ e_ews_ooo_notificator_service_disabled,
+ e_ews_ooo_notificator_dispatcher_data_free);
+ }
+}
+
+static void
+e_ews_ooo_notificator_init (EEwsOooNotificator *extension)
+{
+ extension->priv = E_EWS_OOO_NOTIFICATOR_GET_PRIVATE (extension);
+
+ extension->priv->alerts = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref,
g_object_unref);
+}
+
+static void
+e_ews_ooo_notificator_constructed (GObject *object)
+{
+ EEwsOooNotificator *extension;
+ EShell *shell;
+ EShellView *view;
+ EShellBackend *backend;
+ EMailAccountStore *account_store;
+ EMailSession *session;
+ GList *stores, *l;
+ const gchar *view_name;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_ews_ooo_notificator_parent_class)->constructed (object);
+
+ extension = E_EWS_OOO_NOTIFICATOR (object);
+ view = e_ews_ooo_notificator_get_extensible (extension);
+ view_name = e_shell_view_get_name (view);
+
+ if (g_strcmp0 (view_name, "mail") != 0)
+ return;
+
+ backend = e_shell_view_get_shell_backend (view);
+ shell = e_shell_backend_get_shell (backend);
+ session = e_mail_backend_get_session (E_MAIL_BACKEND (backend));
+ account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session));
+ stores = camel_session_list_services (CAMEL_SESSION (session));
+
+ extension->priv->shell = shell;
+ extension->priv->account_store = g_object_ref (account_store);
+
+ for (l = stores; l; l = l->next) {
+ CamelService *service = l->data;
+ CamelEwsStore *ews_store;
+ gboolean has_ooo_set;
+
+ if (!CAMEL_IS_EWS_STORE (service))
+ continue;
+
+ ews_store = CAMEL_EWS_STORE (service);
+ has_ooo_set = camel_ews_store_get_has_ooo_set (ews_store);
+
+ if (has_ooo_set) {
+ e_ews_ooo_notificator_show_notification (extension, ews_store);
+ camel_ews_store_set_ooo_alert_state (ews_store,
CAMEL_EWS_STORE_OOO_ALERT_STATE_NOTIFIED);
+ }
+
+ g_signal_connect_swapped (
+ ews_store, "notify::has-ooo-set",
+ G_CALLBACK (e_ews_ooo_notificator_has_ooo_set_cb), extension);
+ extension->priv->stores = g_list_append (extension->priv->stores, g_object_ref (ews_store));
+ }
+
+ g_signal_connect_swapped (
+ account_store, "service-disabled",
+ G_CALLBACK (e_ews_ooo_notificator_service_disabled_cb), extension);
+
+ g_signal_connect_swapped (
+ account_store, "service-removed",
+ G_CALLBACK (e_ews_ooo_notificator_service_removed_cb), extension);
+
+ g_signal_connect_swapped (
+ account_store, "service-added",
+ G_CALLBACK (e_ews_ooo_notificator_service_added_cb), extension);
+
+ g_signal_connect_swapped (
+ shell, "notify::online",
+ G_CALLBACK (e_ews_ooo_notificator_online_cb), extension);
+
+ g_list_free_full (stores, g_object_unref);
+}
+
+static void
+e_ews_ooo_notificator_dispose (GObject *object)
+{
+ EEwsOooNotificator *extension;
+ GList *l;
+
+ extension = E_EWS_OOO_NOTIFICATOR (object);
+
+ if (extension->priv->shell) {
+ g_signal_handlers_disconnect_by_data (extension->priv->shell, extension);
+ extension->priv->shell = NULL;
+ }
+
+ if (extension->priv->account_store) {
+ g_signal_handlers_disconnect_by_data (extension->priv->account_store, extension);
+ g_object_unref (extension->priv->account_store);
+ extension->priv->account_store = NULL;
+ }
+
+ for (l = extension->priv->stores; l; l = l->next) {
+ CamelService *service = l->data;
+
+ if (service) {
+ g_signal_handlers_disconnect_by_data (service, extension);
+ g_object_unref (service);
+ }
+ }
+ g_list_free (extension->priv->stores);
+ extension->priv->stores = NULL;
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_ews_ooo_notificator_parent_class)->dispose (object);
+}
+
+static void
+e_ews_ooo_notificator_finalize (GObject *object)
+{
+ EEwsOooNotificator *extension;
+
+ extension = E_EWS_OOO_NOTIFICATOR (object);
+
+ if (extension->priv->alerts) {
+ g_hash_table_destroy (extension->priv->alerts);
+ extension->priv->alerts = NULL;
+ }
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_ews_ooo_notificator_parent_class)->finalize (object);
+}
+
+static void
+e_ews_ooo_notificator_class_init (EEwsOooNotificatorClass *class)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = e_ews_ooo_notificator_constructed;
+ object_class->dispose = e_ews_ooo_notificator_dispose;
+ object_class->finalize = e_ews_ooo_notificator_finalize;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_SHELL_VIEW;
+
+ g_type_class_add_private (class, sizeof (EEwsOooNotificatorPrivate));
+}
+
+static void
+e_ews_ooo_notificator_class_finalize (EEwsOooNotificatorClass *class)
+{
+}
+
+void
+e_ews_ooo_notificator_type_register (GTypeModule *type_module)
+{
+ /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+ * function, so we have to wrap it with a public function in
+ * order to register types from a separate compilation unit. */
+ e_ews_ooo_notificator_register_type (type_module);
+}
diff --git a/src/configuration/e-ews-ooo-notificator.h b/src/configuration/e-ews-ooo-notificator.h
new file mode 100644
index 0000000..a80efab
--- /dev/null
+++ b/src/configuration/e-ews-ooo-notificator.h
@@ -0,0 +1,64 @@
+/*
+ * e-ews-ooo-notificator.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_EWS_OOO_NOTIFICATOR_H
+#define E_EWS_OOO_NOTIFICATOR_H
+
+#include <libebackend/libebackend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_EWS_OOO_NOTIFICATOR \
+ (e_ews_ooo_notificator_get_type ())
+#define E_EWS_OOO_NOTIFICATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_EWS_OOO_NOTIFICATOR, EEwsOooNotificator))
+#define E_EWS_OOO_NOTIFICATOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_EWS_OOO_NOTIFICATOR, EEwsOooNotificatorClass))
+#define E_IS_EWS_OOO_NOTIFICATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_EWS_OOO_NOTIFICATOR))
+#define E_IS_EWS_OOO_NOTIFICATOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_EWS_OOO_NOTIFICATOR))
+#define E_EWS_OOO_NOTIFICATOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_EWS_OOO_NOTIFICATOR, EEwsOooNotificatorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EEwsOooNotificator EEwsOooNotificator;
+typedef struct _EEwsOooNotificatorClass EEwsOooNotificatorClass;
+typedef struct _EEwsOooNotificatorPrivate EEwsOooNotificatorPrivate;
+
+struct _EEwsOooNotificator {
+ EExtension parent;
+ EEwsOooNotificatorPrivate *priv;
+};
+
+struct _EEwsOooNotificatorClass {
+ EExtensionClass parent_class;
+};
+
+GType e_ews_ooo_notificator_get_type (void);
+void e_ews_ooo_notificator_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_EWS_OOO_NOTIFICATOR_H */
+
diff --git a/src/configuration/module-ews-configuration.c b/src/configuration/module-ews-configuration.c
index 036b2d9..2e6c7bd 100644
--- a/src/configuration/module-ews-configuration.c
+++ b/src/configuration/module-ews-configuration.c
@@ -31,6 +31,7 @@
#include "e-mail-config-ews-oal-combo-box.h"
#include "e-mail-config-ews-delegates-page.h"
#include "e-mail-config-ews-ooo-page.h"
+#include "e-ews-ooo-notificator.h"
#include "e-ews-config-ui-extension.h"
#include "server/e-source-ews-folder.h"
@@ -55,6 +56,7 @@ e_module_load (GTypeModule *type_module)
e_mail_config_ews_delegates_page_type_register (type_module);
e_mail_config_ews_ooo_page_type_register (type_module);
e_ews_config_ui_extension_type_register (type_module);
+ e_ews_ooo_notificator_type_register (type_module);
e_source_ews_folder_type_register (type_module);
}
diff --git a/src/configuration/module-ews-configuration.error.xml
b/src/configuration/module-ews-configuration.error.xml
index eaa6802..f950531 100644
--- a/src/configuration/module-ews-configuration.error.xml
+++ b/src/configuration/module-ews-configuration.error.xml
@@ -21,4 +21,8 @@
<_secondary>The reported error was "{0}".</_secondary>
</error>
+ <error type="info" id="has-ooo-set">
+ <_primary>Your Exchange account "{0}" has the status set as "Out of Office".</_primary>
+ </error>
+
</error-list>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]