[evolution-mapi] Make it work with API changes for 3.5.3
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Make it work with API changes for 3.5.3
- Date: Fri, 22 Jun 2012 14:16:33 +0000 (UTC)
commit 2ae3ff016b0bbffb78c1b7cb11098b7f99c256bf
Author: Milan Crha <mcrha redhat com>
Date: Fri Jun 22 16:15:09 2012 +0200
Make it work with API changes for 3.5.3
Makefile.am | 1 -
autogen.sh | 4 +-
configure.ac | 27 +-
eplugin-rule.mk | 11 -
po/POTFILES.in | 15 +-
src/Makefile.am | 4 +-
src/account-setup-eplugin/Makefile.am | 52 -
.../e-mapi-account-listener.c | 1312 --------------
.../e-mapi-account-listener.h | 55 -
.../e-mapi-account-settings.c | 826 ---------
src/account-setup-eplugin/e-mapi-account-setup.c | 1794 --------------------
src/account-setup-eplugin/e-mapi-account-setup.h | 65 -
.../org-gnome-exchange-mapi.eplug.xml | 127 --
src/addressbook/e-book-backend-mapi-contacts.c | 35 +-
src/addressbook/e-book-backend-mapi-factory.c | 6 +-
src/addressbook/e-book-backend-mapi-gal.c | 26 +-
src/addressbook/e-book-backend-mapi.c | 228 ++--
src/addressbook/e-book-backend-mapi.h | 7 +-
src/calendar/e-cal-backend-mapi-factory.c | 6 +-
src/calendar/e-cal-backend-mapi.c | 410 +++---
src/calendar/e-cal-backend-mapi.h | 2 +-
src/camel/Makefile.am | 2 +
src/camel/camel-mapi-store.c | 94 +-
src/collection/Makefile.am | 35 +
src/collection/e-mapi-backend-factory.c | 100 ++
src/collection/e-mapi-backend-factory.h | 64 +
src/collection/e-mapi-backend.c | 573 +++++++
src/collection/e-mapi-backend.h | 63 +
.../module-mapi-backend.c} | 36 +-
src/configuration/Makefile.am | 57 +
src/configuration/e-book-config-mapi.c | 75 +
src/configuration/e-book-config-mapi.h | 63 +
src/configuration/e-book-config-mapigal.c | 106 ++
src/configuration/e-book-config-mapigal.h | 63 +
src/configuration/e-cal-config-mapi.c | 75 +
src/configuration/e-cal-config-mapi.h | 63 +
src/configuration/e-mail-config-mapi-backend.c | 841 +++++++++
src/configuration/e-mail-config-mapi-backend.h | 63 +
src/configuration/e-mail-config-mapi-extension.c | 121 ++
.../e-mail-config-mapi-extension.h} | 30 +-
src/configuration/e-mail-config-mapi-page.c | 296 ++++
src/configuration/e-mail-config-mapi-page.h | 71 +
src/configuration/e-mapi-config-ui-extension.c | 154 ++
.../e-mapi-config-ui-extension.h} | 43 +-
src/configuration/e-mapi-config-utils.c | 1698 ++++++++++++++++++
src/configuration/e-mapi-config-utils.h | 74 +
.../e-mapi-edit-folder-permissions.c | 52 +-
.../e-mapi-edit-folder-permissions.h | 10 +-
.../e-mapi-search-gal-user.c | 2 +-
.../e-mapi-search-gal-user.h | 0
.../e-mapi-subscribe-foreign-folder.c | 34 +-
.../e-mapi-subscribe-foreign-folder.h | 0
src/configuration/module-mapi-configuration.c | 49 +
src/libexchangemapi/Makefile.am | 4 +-
src/libexchangemapi/e-mapi-book-utils.c | 2 +-
src/libexchangemapi/e-mapi-book-utils.h | 2 +-
src/libexchangemapi/e-mapi-cal-recur-utils.c | 3 +-
src/libexchangemapi/e-mapi-cal-tz-utils.c | 6 +-
src/libexchangemapi/e-mapi-cal-utils.c | 5 +-
src/libexchangemapi/e-mapi-cal-utils.h | 2 +-
src/libexchangemapi/e-mapi-connection.c | 137 +-
src/libexchangemapi/e-mapi-connection.h | 12 +-
src/libexchangemapi/e-mapi-folder.c | 376 ++---
src/libexchangemapi/e-mapi-folder.h | 54 +-
src/libexchangemapi/e-mapi-mail-utils.c | 2 +-
src/libexchangemapi/e-mapi-utils.c | 105 ++-
src/libexchangemapi/e-mapi-utils.h | 11 +
src/libexchangemapi/e-source-mapi-folder.c | 488 ++++++
src/libexchangemapi/e-source-mapi-folder.h | 99 ++
69 files changed, 6236 insertions(+), 5092 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index daba3e9..6fe03d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,6 @@ DIST_SUBDIRS= src po
EXTRA_DIST = \
ChangeLog \
- eplugin-rule.mk \
intltool-merge.in \
intltool-update.in \
intltool-extract.in
diff --git a/autogen.sh b/autogen.sh
index d3e2104..3f6236e 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -12,14 +12,14 @@ REQUIRED_INTLTOOL_VERSION=0.35.5
(test -f $srcdir/configure.ac \
&& test -f $srcdir/ChangeLog \
- && test -d $srcdir/src/account-setup-eplugin) || {
+ && test -d $srcdir/src/configuration) || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
echo " top-level $PKG_NAME directory"
exit 1
}
which gnome-autogen.sh || {
- echo "You need to install gnome-common from the GNOME SVN"
+ echo "You need to install gnome-common from the GNOME git"
exit 1
}
USE_GNOME2_MACROS=1 . gnome-autogen.sh
diff --git a/configure.ac b/configure.ac
index f6c5184..ab88a7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,6 @@ m4_define([evo_minimum_version], [ema_version])
m4_define([libmapi_minimum_version], [1.0])
m4_define([glib_minimum_version], [2.16.1])
m4_define([gtk_minimum_version], [2.99.2])
-m4_define([gconf_minimum_version], [2.0.0])
dnl ***********************************
dnl Automake 1.11 - Silent Build Rules
@@ -102,8 +101,7 @@ dnl Check for GNOME Platform
dnl *****************************
PKG_CHECK_MODULES(GNOME_PLATFORM,
[glib-2.0 >= glib_minimum_version
- gtk+-3.0 >= gtk_minimum_version
- gconf-2.0 >= gconf_minimum_version])
+ gtk+-3.0 >= gtk_minimum_version])
dnl ********************************
dnl Check for evolution-data-server
@@ -119,9 +117,10 @@ PKG_CHECK_MODULES(LIBEDATABOOK, libedata-book-$EDS_PACKAGE >= eds_minimum_versio
PKG_CHECK_MODULES(CAMEL, camel-$EDS_PACKAGE >= eds_minimum_version)
dnl ****************************
-dnl Check for evolution plugins
+dnl Check for evolution stuff
dnl ****************************
-PKG_CHECK_MODULES(EVOLUTION_PLUGIN, evolution-plugin-3.0 >= evo_minimum_version)
+PKG_CHECK_MODULES(EVOLUTION_SHELL, evolution-shell-3.0 >= evo_minimum_version)
+PKG_CHECK_MODULES(EVOLUTION_MAIL, evolution-mail-3.0 >= evo_minimum_version)
dnl ****************************
dnl Check for LibMAPI
@@ -164,18 +163,9 @@ AC_SUBST(EVO_REQUIRED)
LIBMAPI_REQUIRED=libmapi_minimum_version
AC_SUBST(LIBMAPI_REQUIRED)
-dnl *******************************
-dnl Add evolution plugin rules here
-dnl *******************************
-EVO_PLUGIN_RULE=$srcdir/eplugin-rule.mk
-AC_SUBST_FILE(EVO_PLUGIN_RULE)
-
dnl *******************
dnl Special directories
dnl *******************
-plugindir=`$PKG_CONFIG --variable=plugindir evolution-plugin-3.0`
-AC_SUBST(plugindir)
-
ebook_backenddir=`$PKG_CONFIG --variable=backenddir libedata-book-1.2`
AC_SUBST(ebook_backenddir)
@@ -188,6 +178,12 @@ AC_SUBST(camel_providerdir)
edataserver_privincludedir=`$PKG_CONFIG --variable=privincludedir libedataserver-$EDS_PACKAGE`
AC_SUBST(edataserver_privincludedir)
+eds_moduledir=`$PKG_CONFIG --variable=moduledir libebackend-1.2`
+AC_SUBST(eds_moduledir)
+
+evo_moduledir=`$PKG_CONFIG --variable=moduledir evolution-shell-3.0`
+AC_SUBST(evo_moduledir)
+
libmapi_ldif_dir=`$PKG_CONFIG --variable=datadir libmapi`/setup
AC_SUBST(libmapi_ldif_dir)
@@ -205,10 +201,11 @@ dnl **************************
AC_CONFIG_FILES([
Makefile
src/Makefile
-src/account-setup-eplugin/Makefile
src/addressbook/Makefile
src/calendar/Makefile
src/camel/Makefile
+src/collection/Makefile
+src/configuration/Makefile
src/libexchangemapi/Makefile
src/libexchangemapi/libexchangemapi-]EVO_MAPI_API_VERSION_MACRO[.pc:src/libexchangemapi/libexchangemapi.pc.in
po/Makefile.in
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c44f2ec..85b08dd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,10 +1,3 @@
-src/account-setup-eplugin/e-mapi-account-listener.c
-src/account-setup-eplugin/e-mapi-account-setup.c
-src/account-setup-eplugin/e-mapi-account-settings.c
-src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
-src/account-setup-eplugin/e-mapi-search-gal-user.c
-src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c
-src/account-setup-eplugin/org-gnome-exchange-mapi.eplug.xml
src/addressbook/e-book-backend-mapi.c
src/addressbook/e-book-backend-mapi-contacts.c
src/addressbook/e-book-backend-mapi-gal.c
@@ -13,6 +6,14 @@ src/camel/camel-mapi-folder.c
src/camel/camel-mapi-provider.c
src/camel/camel-mapi-store.c
src/camel/camel-mapi-transport.c
+src/collection/e-mapi-backend.c
+src/configuration/e-book-config-mapigal.c
+src/configuration/e-mail-config-mapi-backend.c
+src/configuration/e-mail-config-mapi-page.c
+src/configuration/e-mapi-config-utils.c
+src/configuration/e-mapi-edit-folder-permissions.c
+src/configuration/e-mapi-search-gal-user.c
+src/configuration/e-mapi-subscribe-foreign-folder.c
src/libexchangemapi/e-mapi-cal-utils.c
src/libexchangemapi/e-mapi-connection.c
src/libexchangemapi/e-mapi-folder.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 7e02ee8..122a097 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS=libexchangemapi calendar addressbook camel account-setup-eplugin
-DIST_SUBDIRS=libexchangemapi calendar addressbook camel account-setup-eplugin
+SUBDIRS=libexchangemapi addressbook calendar camel collection configuration
+
-include $(top_srcdir)/git.mk
diff --git a/src/addressbook/e-book-backend-mapi-contacts.c b/src/addressbook/e-book-backend-mapi-contacts.c
index 7cc87a3..ae9cea6 100644
--- a/src/addressbook/e-book-backend-mapi-contacts.c
+++ b/src/addressbook/e-book-backend-mapi-contacts.c
@@ -33,20 +33,14 @@
#include <glib/gi18n-lib.h>
#include <sys/time.h>
-/*
-** #include <glib/gi18n-lib.h>
-*/
-#include <libedataserver/e-sexp.h>
-#include "libedataserver/e-flag.h"
-#include <libebook/e-contact.h>
+#include <libedataserver/libedataserver.h>
+#include <libedata-book/libedata-book.h>
+#include <libebook/libebook.h>
#include <camel/camel.h>
-#include <libedata-book/e-book-backend-sexp.h>
-#include <libedata-book/e-data-book.h>
-#include <libedata-book/e-data-book-view.h>
-
#include "e-book-backend-mapi-contacts.h"
+#include "e-source-mapi-folder.h"
G_DEFINE_TYPE (EBookBackendMAPIContacts, e_book_backend_mapi_contacts, E_TYPE_BOOK_BACKEND_MAPI)
@@ -146,7 +140,7 @@ transfer_contact_cb (EMapiConnection *conn,
g_return_val_if_fail (tc->ebma != NULL, FALSE);
g_return_val_if_fail (object != NULL, FALSE);
- tc->contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uri (tc->ebma));
+ tc->contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uid (tc->ebma));
if (tc->contact)
return e_book_backend_mapi_notify_contact_update (tc->ebma, NULL, tc->contact, obj_index, obj_total, NULL);
@@ -202,7 +196,7 @@ transfer_contacts_cb (EMapiConnection *conn,
g_return_val_if_fail (object != NULL, FALSE);
g_return_val_if_fail (tcd->ebma != NULL, FALSE);
- contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uri (tcd->ebma));
+ contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uid (tcd->ebma));
if (contact) {
if (tcd->cards)
*tcd->cards = g_slist_prepend (*tcd->cards, e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));
@@ -319,6 +313,7 @@ static void
ebbm_contacts_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
{
ESource *source = e_backend_get_source (E_BACKEND (ebma));
+ ESourceMapiFolder *ext_mapi_folder;
EBookBackendMAPIContactsPrivate *priv = ((EBookBackendMAPIContacts *) ebma)->priv;
GError *err = NULL;
@@ -328,10 +323,11 @@ ebbm_contacts_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean
return;
}
- priv->fid = 0;
- priv->is_public_folder = g_strcmp0 (e_source_get_property (source, "public"), "yes") == 0;
- priv->foreign_username = e_source_get_duped_property (source, "foreign-username");
- e_mapi_util_mapi_id_from_string (e_source_get_property (source, "folder-id"), &priv->fid);
+ ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+
+ priv->fid = e_source_mapi_folder_get_id (ext_mapi_folder);
+ priv->is_public_folder = e_source_mapi_folder_is_public (ext_mapi_folder);
+ priv->foreign_username = e_source_mapi_folder_dup_foreign_username (ext_mapi_folder);
if (priv->foreign_username && !*priv->foreign_username) {
g_free (priv->foreign_username);
@@ -350,6 +346,7 @@ static void
ebbm_contacts_connection_status_changed (EBookBackendMAPI *ebma, gboolean is_online)
{
ESource *source;
+ ESourceMapiFolder *ext_mapi_folder;
e_book_backend_notify_readonly (E_BOOK_BACKEND (ebma), !is_online);
@@ -357,7 +354,9 @@ ebbm_contacts_connection_status_changed (EBookBackendMAPI *ebma, gboolean is_onl
return;
source = e_backend_get_source (E_BACKEND (ebma));
- if (source && g_strcmp0 (e_source_get_property (source, "server-notification"), "true") == 0) {
+ ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+
+ if (e_source_mapi_folder_get_server_notification (ext_mapi_folder)) {
EMapiConnection *conn;
mapi_object_t obj_folder;
gboolean status;
@@ -505,7 +504,7 @@ ebbm_contacts_create_contacts (EBookBackendMAPI *ebma, GCancellable *cancellable
/* UID of the contact is nothing but the concatenated string of hex id of folder and the message.*/
e_contact_set (contact, E_CONTACT_UID, id);
- e_contact_set (contact, E_CONTACT_BOOK_URI, e_book_backend_mapi_get_book_uri (ebma));
+ e_contact_set (contact, E_CONTACT_BOOK_URI, e_book_backend_mapi_get_book_uid (ebma));
g_free (id);
diff --git a/src/addressbook/e-book-backend-mapi-factory.c b/src/addressbook/e-book-backend-mapi-factory.c
index ef10df5..bbbcd64 100644
--- a/src/addressbook/e-book-backend-mapi-factory.c
+++ b/src/addressbook/e-book-backend-mapi-factory.c
@@ -23,9 +23,11 @@
#include <config.h>
-#include <libedata-book/e-book-backend-factory.h>
+#include <libedata-book/libedata-book.h>
+
#include "e-book-backend-mapi-contacts.h"
#include "e-book-backend-mapi-gal.h"
+#include "e-source-mapi-folder.h"
typedef EBookBackendFactory EBookBackendMapiContactsFactory;
typedef EBookBackendFactoryClass EBookBackendMapiContactsFactoryClass;
@@ -88,6 +90,8 @@ e_book_backend_mapi_gal_factory_init (EBookBackendFactory *factory)
G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module)
{
+ e_source_mapi_folder_type_register (type_module);
+
e_book_backend_mapi_contacts_factory_register_type (type_module);
e_book_backend_mapi_gal_factory_register_type (type_module);
}
diff --git a/src/addressbook/e-book-backend-mapi-gal.c b/src/addressbook/e-book-backend-mapi-gal.c
index b4711cb..d92fab2 100644
--- a/src/addressbook/e-book-backend-mapi-gal.c
+++ b/src/addressbook/e-book-backend-mapi-gal.c
@@ -34,15 +34,12 @@
#include <sys/time.h>
-#include <libedataserver/e-sexp.h>
-#include "libedataserver/e-flag.h"
-#include <libebook/e-contact.h>
-
-#include <libedata-book/e-book-backend-sexp.h>
-#include <libedata-book/e-data-book.h>
-#include <libedata-book/e-data-book-view.h>
+#include <libedataserver/libedataserver.h>
+#include <libedata-book/libedata-book.h>
+#include <libebook/libebook.h>
#include "e-book-backend-mapi-gal.h"
+#include "e-source-mapi-folder.h"
/* default value for "partial-count", upper bound of objects to download during partial search */
#define DEFAULT_PARTIAL_COUNT 50
@@ -81,7 +78,7 @@ transfer_gal_cb (EMapiConnection *conn,
g_return_val_if_fail (object != NULL, FALSE);
g_return_val_if_fail (tg != NULL, FALSE);
- contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uri (tg->ebma));
+ contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uid (tg->ebma));
if (!contact) {
/* this is GAL, just ignore them */
return TRUE;
@@ -173,6 +170,7 @@ ebbm_gal_transfer_contacts (EBookBackendMAPI *ebma,
struct TransferGalData tg = { 0 };
EMapiConnection *conn;
ESource *source;
+ ESourceMapiFolder *ext_mapi_folder;
GSList *get_mids = NULL;
const GSList *iter;
gint partial_count = -1;
@@ -188,14 +186,12 @@ ebbm_gal_transfer_contacts (EBookBackendMAPI *ebma,
}
source = e_backend_get_source (E_BACKEND (ebma));
- if (source &&
- !e_book_backend_mapi_is_marked_for_offline (ebma) &&
- g_strcmp0 (e_source_get_property (source, "allow-partial"), "true") == 0) {
- const gchar *partial_count_str = e_source_get_property (source, "partial-count");
+ ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
- partial_count = 0;
- if (partial_count_str)
- partial_count = atoi (partial_count_str);
+ if (ext_mapi_folder &&
+ !e_book_backend_mapi_is_marked_for_offline (ebma) &&
+ e_source_mapi_folder_get_allow_partial (ext_mapi_folder)) {
+ partial_count = e_source_mapi_folder_get_partial_count (ext_mapi_folder);
if (partial_count <= 0)
partial_count = DEFAULT_PARTIAL_COUNT;
diff --git a/src/addressbook/e-book-backend-mapi.c b/src/addressbook/e-book-backend-mapi.c
index 2fb8378..1142114 100644
--- a/src/addressbook/e-book-backend-mapi.c
+++ b/src/addressbook/e-book-backend-mapi.c
@@ -26,14 +26,13 @@
#endif
#include <stdlib.h>
-#include <fcntl.h>
#include <string.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
-#include <libebook/e-contact.h>
-#include <libedataserver/e-data-server-util.h>
+#include <libebook/libebook.h>
+#include <libedataserver/libedataserver.h>
#include <camel/camel.h>
#include <e-mapi-operation-queue.h>
@@ -43,7 +42,10 @@
#include "e-book-backend-mapi.h"
-G_DEFINE_TYPE (EBookBackendMAPI, e_book_backend_mapi, E_TYPE_BOOK_BACKEND)
+static void e_book_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (EBookBackendMAPI, e_book_backend_mapi, E_TYPE_BOOK_BACKEND,
+ G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_book_backend_mapi_authenticator_init))
struct _EBookBackendMAPIPrivate
{
@@ -51,8 +53,7 @@ struct _EBookBackendMAPIPrivate
GMutex *conn_lock;
EMapiConnection *conn;
- gchar *profile;
- gchar *book_uri;
+ gchar *book_uid;
gboolean marked_for_offline;
GThread *update_cache_thread;
@@ -71,6 +72,35 @@ struct _EBookBackendMAPIPrivate
GMutex *running_views_lock;
};
+static CamelMapiSettings *
+ebbm_get_collection_settings (EBookBackendMAPI *ebbm)
+{
+ ESource *source;
+ ESource *collection;
+ ESourceCamel *extension;
+ ESourceRegistry *registry;
+ CamelSettings *settings;
+ const gchar *extension_name;
+
+ source = e_backend_get_source (E_BACKEND (ebbm));
+ registry = e_book_backend_get_registry (E_BOOK_BACKEND (ebbm));
+
+ extension_name = e_source_camel_get_extension_name ("mapi");
+ e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
+
+ /* The collection settings live in our parent data source. */
+ collection = e_source_registry_find_extension (
+ registry, source, extension_name);
+ g_return_val_if_fail (collection != NULL, NULL);
+
+ extension = e_source_get_extension (collection, extension_name);
+ settings = e_source_camel_get_settings (extension);
+
+ g_object_unref (collection);
+
+ return CAMEL_MAPI_SETTINGS (settings);
+}
+
static glong
get_current_time_ms (void)
{
@@ -322,12 +352,18 @@ ebbm_maybe_invoke_cache_update (EBookBackendMAPI *ebma)
}
}
-static void
-ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gchar *password, GError **error)
+static ESourceAuthenticationResult
+ebbm_connect_user (EBookBackendMAPI *ebma,
+ GCancellable *cancellable,
+ const GString *password,
+ GError **error)
{
EBookBackendMAPIPrivate *priv = ebma->priv;
- GError *mapi_error = NULL;
EMapiConnection *old_conn;
+ CamelMapiSettings *settings;
+ GError *mapi_error = NULL;
+
+ settings = ebbm_get_collection_settings (ebma);
if (!e_backend_get_online (E_BACKEND (ebma))) {
ebbm_notify_connection_status (ebma, FALSE);
@@ -342,18 +378,18 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
e_book_backend_mapi_unlock_connection (ebma);
- return;
+ return E_SOURCE_AUTHENTICATION_ERROR;
}
old_conn = priv->conn;
priv->conn = NULL;
- priv->conn = e_mapi_connection_new (priv->profile,
- password,
- cancellable,
- &mapi_error);
+ priv->conn = e_mapi_connection_new (
+ e_book_backend_get_registry (E_BOOK_BACKEND (ebma)),
+ camel_mapi_settings_get_profile (settings),
+ password, cancellable, &mapi_error);
if (!priv->conn) {
- priv->conn = e_mapi_connection_find (priv->profile);
+ priv->conn = e_mapi_connection_find (camel_mapi_settings_get_profile (settings));
if (priv->conn && !e_mapi_connection_connected (priv->conn))
e_mapi_connection_reconnect (priv->conn, password, cancellable, &mapi_error);
}
@@ -362,6 +398,8 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
g_object_unref (old_conn);
if (!priv->conn || mapi_error) {
+ gboolean is_network_error = g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR);
+
if (priv->conn) {
g_object_unref (priv->conn);
priv->conn = NULL;
@@ -374,7 +412,8 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
g_error_free (mapi_error);
ebbm_notify_connection_status (ebma, FALSE);
- return;
+
+ return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : E_SOURCE_AUTHENTICATION_REJECTED;
}
e_book_backend_mapi_unlock_connection (ebma);
@@ -385,15 +424,21 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
ebbm_maybe_invoke_cache_update (ebma);
}
}
+
+ return E_SOURCE_AUTHENTICATION_ACCEPTED;
}
static void
-ebbm_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
+ebbm_open (EBookBackendMAPI *ebma,
+ GCancellable *cancellable,
+ gboolean only_if_exists,
+ GError **perror)
{
EBookBackendMAPIPrivate *priv = ebma->priv;
ESource *source = e_backend_get_source (E_BACKEND (ebma));
- const gchar *offline;
- const gchar *cache_dir, *krb_sso;
+ ESourceOffline *offline_extension;
+ CamelMapiSettings *settings;
+ const gchar *cache_dir;
GError *error = NULL;
if (e_book_backend_is_opened (E_BOOK_BACKEND (ebma))) {
@@ -401,15 +446,14 @@ ebbm_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_e
return;
}
- offline = e_source_get_property (source, "offline_sync");
- priv->marked_for_offline = offline && g_str_equal (offline, "1");
+ settings = ebbm_get_collection_settings (ebma);
- if (priv->book_uri)
- g_free (priv->book_uri);
- priv->book_uri = e_source_get_uri (source);
+ offline_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_OFFLINE);
+ priv->marked_for_offline = e_source_offline_get_stay_synchronized (offline_extension);
- g_free (priv->profile);
- priv->profile = g_strdup (e_source_get_property (source, "profile"));
+ if (priv->book_uid)
+ g_free (priv->book_uid);
+ priv->book_uid = e_source_dup_uid (source);
cache_dir = e_book_backend_get_cache_dir (E_BOOK_BACKEND (ebma));
@@ -446,14 +490,33 @@ ebbm_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_e
}
e_book_backend_notify_online (E_BOOK_BACKEND (ebma), TRUE);
- krb_sso = e_source_get_property (source, "kerberos");
- if (!krb_sso || !g_str_equal (krb_sso, "required")) {
- e_book_backend_notify_auth_required (E_BOOK_BACKEND (ebma),
- TRUE, NULL);
- } else {
- ebbm_connect_user (ebma, cancellable, NULL, perror);
- e_book_backend_notify_opened (E_BOOK_BACKEND (ebma), NULL);
+
+
+ if (!camel_mapi_settings_get_kerberos (settings) ||
+ ebbm_connect_user (ebma, cancellable, NULL, &error) != E_SOURCE_AUTHENTICATION_ACCEPTED) {
+ ESourceRegistry *registry;
+
+ registry = e_book_backend_get_registry (E_BOOK_BACKEND (ebma));
+
+ e_source_registry_authenticate_sync (
+ registry, source,
+ E_SOURCE_AUTHENTICATOR (ebma),
+ cancellable, &error);
}
+
+ if (error && perror)
+ g_propagate_error (perror, g_error_copy (error));
+
+ e_book_backend_notify_opened (E_BOOK_BACKEND (ebma), error);
+}
+
+static ESourceAuthenticationResult
+ebbm_try_password_sync (ESourceAuthenticator *authenticator,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return ebbm_connect_user (E_BOOK_BACKEND_MAPI (authenticator), cancellable, password, error);
}
static void
@@ -467,7 +530,7 @@ ebbm_remove (EBookBackendMAPI *ebma, GCancellable *cancellable, GError **error)
priv = ebma->priv;
- if (!priv->book_uri)
+ if (!priv->book_uid)
return;
e_book_backend_mapi_lock_connection (ebma);
@@ -524,34 +587,17 @@ ebbm_get_backend_property (EBookBackendMAPI *ebma, const gchar *prop_name, gchar
}
static void
-ebbm_authenticate_user (EBookBackendMAPI *ebma, GCancellable *cancellable, ECredentials *credentials, GError **error)
-{
- const gchar *password;
-
- if (!e_backend_get_online (E_BACKEND (ebma))) {
- ebbm_notify_connection_status (ebma, FALSE);
- } else {
- password = e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD);
- ebbm_connect_user (ebma, cancellable, password, error);
- }
-}
-
-static void
ebbm_notify_online_cb (EBookBackend *backend, GParamSpec *pspec)
{
EBookBackendMAPI *ebma = E_BOOK_BACKEND_MAPI (backend);
EBookBackendMAPIPrivate *priv = ebma->priv;
- ESource *esource;
- const gchar *krb_sso = NULL;
gboolean online;
online = e_backend_get_online (E_BACKEND (backend));
- e_book_backend_notify_online (backend, online);
if (e_book_backend_is_opened (backend)) {
e_book_backend_mapi_lock_connection (ebma);
- esource = e_backend_get_source (E_BACKEND (ebma));
if (!online) {
e_book_backend_notify_readonly (backend, TRUE);
ebbm_notify_connection_status (ebma, FALSE);
@@ -562,23 +608,12 @@ ebbm_notify_online_cb (EBookBackend *backend, GParamSpec *pspec)
}
} else {
ebbm_notify_connection_status (ebma, TRUE);
- if (!priv->conn) {
- krb_sso = e_source_get_property (esource,
- "kerberos");
- if (!krb_sso
- || !g_str_equal (krb_sso, "required")) {
- e_book_backend_notify_auth_required (backend, TRUE, NULL);
- } else {
- ebbm_connect_user (ebma, NULL, NULL,
- NULL);
- e_book_backend_notify_opened (backend,
- NULL);
- }
- }
}
e_book_backend_mapi_unlock_connection (ebma);
}
+
+ e_book_backend_notify_online (backend, online);
}
static void
@@ -770,7 +805,6 @@ typedef enum {
OP_GET_CONTACT_LIST,
OP_START_BOOK_VIEW,
OP_STOP_BOOK_VIEW,
- OP_AUTHENTICATE_USER,
OP_GET_BACKEND_PROPERTY
} OperationType;
@@ -791,12 +825,6 @@ typedef struct {
typedef struct {
OperationBase base;
- ECredentials *credentials;
-} OperationAuthenticateUser;
-
-typedef struct {
- OperationBase base;
-
gchar *str;
} OperationStr;
@@ -1026,20 +1054,6 @@ ebbm_operation_cb (OperationBase *op, gboolean cancelled, EBookBackend *backend)
g_object_unref (opbv->book_view);
} break;
- case OP_AUTHENTICATE_USER: {
- OperationAuthenticateUser *opau = (OperationAuthenticateUser *) op;
-
- if (!cancelled) {
- if (ebmac->op_authenticate_user)
- ebmac->op_authenticate_user (ebma, op->cancellable, opau->credentials, &error);
- else
- error = EDB_ERROR (NOT_SUPPORTED);
-
- e_book_backend_notify_opened (E_BOOK_BACKEND (ebma), error);
- }
-
- e_credentials_free (opau->credentials);
- } break;
case OP_GET_BACKEND_PROPERTY: {
OperationStr *ops = (OperationStr *) op;
const gchar *prop_name = ops->str;
@@ -1286,35 +1300,6 @@ ebbm_op_stop_book_view (EBookBackend *backend, EDataBookView *book_view)
}
static void
-ebbm_op_authenticate_user (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials)
-{
- OperationAuthenticateUser *op;
- EBookBackendMAPI *ebbm;
- EBookBackendMAPIPrivate *priv;
-
- g_return_if_fail (backend != NULL);
- g_return_if_fail (E_IS_BOOK_BACKEND_MAPI (backend));
-
- ebbm = E_BOOK_BACKEND_MAPI (backend);
- priv = ebbm->priv;
- g_return_if_fail (priv != NULL);
-
- if (cancellable)
- g_object_ref (cancellable);
-
- g_object_ref (ebbm);
-
- op = g_new0 (OperationAuthenticateUser, 1);
- op->base.ot = OP_AUTHENTICATE_USER;
- op->base.book = NULL;
- op->base.opid = 0;
- op->base.cancellable = cancellable;
- op->credentials = e_credentials_new_clone (credentials);
-
- e_mapi_operation_queue_push (priv->op_queue, op);
-}
-
-static void
e_book_backend_mapi_init (EBookBackendMAPI *ebma)
{
ebma->priv = G_TYPE_INSTANCE_GET_PRIVATE (ebma, E_TYPE_BOOK_BACKEND_MAPI, EBookBackendMAPIPrivate);
@@ -1360,8 +1345,7 @@ ebbm_dispose (GObject *object)
UNREF (priv->db);
UNREF (priv->update_cache);
- FREE (priv->profile);
- FREE (priv->book_uri);
+ FREE (priv->book_uid);
g_hash_table_destroy (priv->running_views);
g_mutex_free (priv->running_views_lock);
@@ -1397,11 +1381,9 @@ e_book_backend_mapi_class_init (EBookBackendMAPIClass *klass)
backend_class->get_contact_list = ebbm_op_get_contact_list;
backend_class->start_book_view = ebbm_op_start_book_view;
backend_class->stop_book_view = ebbm_op_stop_book_view;
- backend_class->authenticate_user = ebbm_op_authenticate_user;
backend_class->get_backend_property = ebbm_op_get_backend_property;
klass->op_open = ebbm_open;
klass->op_remove = ebbm_remove;
- klass->op_authenticate_user = ebbm_authenticate_user;
klass->op_get_contact = ebbm_get_contact;
klass->op_get_contact_list = ebbm_get_contact_list;
@@ -1413,13 +1395,19 @@ e_book_backend_mapi_class_init (EBookBackendMAPIClass *klass)
klass->op_transfer_contacts = NULL;
}
+static void
+e_book_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+ interface->try_password_sync = ebbm_try_password_sync;
+}
+
const gchar *
-e_book_backend_mapi_get_book_uri (EBookBackendMAPI *ebma)
+e_book_backend_mapi_get_book_uid (EBookBackendMAPI *ebma)
{
g_return_val_if_fail (E_IS_BOOK_BACKEND_MAPI (ebma), NULL);
g_return_val_if_fail (ebma->priv != NULL, NULL);
- return ebma->priv->book_uri;
+ return ebma->priv->book_uid;
}
void
diff --git a/src/addressbook/e-book-backend-mapi.h b/src/addressbook/e-book-backend-mapi.h
index 49abb27..97e6429 100644
--- a/src/addressbook/e-book-backend-mapi.h
+++ b/src/addressbook/e-book-backend-mapi.h
@@ -24,11 +24,8 @@
#include <glib.h>
#include <gio/gio.h>
-#include <libedata-book/e-book-backend.h>
-#include <libedata-book/e-data-book.h>
-#include <libedata-book/e-data-book-view.h>
+#include <libedata-book/libedata-book.h>
-#include <libedata-book/e-book-backend-sqlitedb.h>
#include "e-mapi-connection.h"
#include "e-mapi-defs.h"
#include "e-mapi-utils.h"
@@ -100,7 +97,7 @@ typedef struct
GType e_book_backend_mapi_get_type (void);
-const gchar *e_book_backend_mapi_get_book_uri (EBookBackendMAPI *ebma);
+const gchar *e_book_backend_mapi_get_book_uid (EBookBackendMAPI *ebma);
void e_book_backend_mapi_lock_connection (EBookBackendMAPI *ebma);
void e_book_backend_mapi_unlock_connection (EBookBackendMAPI *ebma);
EMapiConnection *e_book_backend_mapi_get_connection (EBookBackendMAPI *ebma);
diff --git a/src/calendar/e-cal-backend-mapi-factory.c b/src/calendar/e-cal-backend-mapi-factory.c
index a5e6460..d61263b 100644
--- a/src/calendar/e-cal-backend-mapi-factory.c
+++ b/src/calendar/e-cal-backend-mapi-factory.c
@@ -23,7 +23,9 @@
#include <config.h>
-#include <libedata-cal/e-cal-backend-factory.h>
+#include <libedata-cal/libedata-cal.h>
+
+#include "e-source-mapi-folder.h"
#include "e-cal-backend-mapi.h"
#define FACTORY_NAME "mapi"
@@ -118,6 +120,8 @@ e_cal_backend_mapi_todos_factory_init (ECalBackendFactory *factory)
G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module)
{
+ e_source_mapi_folder_type_register (type_module);
+
e_cal_backend_mapi_events_factory_register_type (type_module);
e_cal_backend_mapi_journal_factory_register_type (type_module);
e_cal_backend_mapi_todos_factory_register_type (type_module);
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index 19b35f2..ec487fa 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -30,13 +30,14 @@
#include <libical/icaltz-util.h>
-#include <libedata-cal/e-cal-backend-file-store.h>
-#include <libedataserver/e-data-server-util.h>
+#include <libedata-cal/libedata-cal.h>
+#include <libedataserver/libedataserver.h>
#include <e-mapi-connection.h>
#include <e-mapi-cal-utils.h>
#include <e-mapi-utils.h>
#include <e-mapi-operation-queue.h>
+#include <e-source-mapi-folder.h>
#include "e-cal-backend-mapi.h"
@@ -55,7 +56,10 @@
#define EDC_ERROR(_code) e_data_cal_create_error (_code, NULL)
#define EDC_ERROR_EX(_code, _msg) e_data_cal_create_error (_code, _msg)
-G_DEFINE_TYPE (ECalBackendMAPI, e_cal_backend_mapi, E_TYPE_CAL_BACKEND)
+static void e_cal_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (ECalBackendMAPI, e_cal_backend_mapi, E_TYPE_CAL_BACKEND,
+ G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_cal_backend_mapi_authenticator_init))
typedef struct {
GCond *cond;
@@ -68,17 +72,10 @@ struct _ECalBackendMAPIPrivate {
EMapiOperationQueue *op_queue;
mapi_id_t fid;
- gchar *profile;
gboolean is_public_folder;
gchar *foreign_username;
EMapiConnection *conn;
- /* These fields are entirely for access rights */
- gchar *owner_name;
- gchar *owner_email;
- gchar *user_name;
- gchar *user_email;
-
/* A mutex to control access to the private structure */
GMutex *mutex;
ECalBackendStore *store;
@@ -102,6 +99,35 @@ struct _ECalBackendMAPIPrivate {
GCancellable *cancellable;
};
+static CamelMapiSettings *
+ecbm_get_collection_settings (ECalBackendMAPI *ecbm)
+{
+ ESource *source;
+ ESource *collection;
+ ESourceCamel *extension;
+ ESourceRegistry *registry;
+ CamelSettings *settings;
+ const gchar *extension_name;
+
+ source = e_backend_get_source (E_BACKEND (ecbm));
+ registry = e_cal_backend_get_registry (E_CAL_BACKEND (ecbm));
+
+ extension_name = e_source_camel_get_extension_name ("mapi");
+ e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
+
+ /* The collection settings live in our parent data source. */
+ collection = e_source_registry_find_extension (
+ registry, source, extension_name);
+ g_return_val_if_fail (collection != NULL, NULL);
+
+ extension = e_source_get_extension (collection, extension_name);
+ settings = e_source_camel_get_settings (extension);
+
+ g_object_unref (collection);
+
+ return CAMEL_MAPI_SETTINGS (settings);
+}
+
static gboolean
ecbm_open_folder (ECalBackendMAPI *ecbm,
EMapiConnection *conn,
@@ -185,44 +211,92 @@ get_comp_mid (icalcomponent *icalcomp, mapi_id_t *mid)
}
}
+static ESource *
+ecbm_find_identity_source (ECalBackendMAPI *cbmapi)
+{
+ ESourceRegistry *registry;
+ GList *all_sources, *my_sources, *iter;
+ CamelMapiSettings *settings;
+ ESource *res = NULL;
+
+ g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), NULL);
+
+ settings = ecbm_get_collection_settings (cbmapi);
+ g_return_val_if_fail (settings != NULL, NULL);
+
+ registry = e_cal_backend_get_registry (E_CAL_BACKEND (cbmapi));
+ all_sources = e_source_registry_list_sources (registry, NULL);
+ my_sources = e_mapi_utils_filter_sources_for_profile (all_sources,
+ camel_mapi_settings_get_profile (settings));
+ g_list_free_full (all_sources, g_object_unref);
+
+ for (iter = my_sources; iter; iter = iter->next) {
+ ESource *source = iter->data;
+
+ if (!source)
+ continue;
+
+ if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_IDENTITY)) {
+ res = g_object_ref (source);
+ break;
+ }
+ }
+
+ g_list_free_full (my_sources, g_object_unref);
+
+ return res;
+}
+
static const gchar *
ecbm_get_owner_name (ECalBackendMAPI *cbmapi)
{
- ECalBackendMAPIPrivate *priv;
+ ESource *identity_source;
+ ESourceMailIdentity *identity_ext;
+ const gchar *res = NULL;
- priv = cbmapi->priv;
+ identity_source = ecbm_find_identity_source (cbmapi);
+ if (!identity_source)
+ return NULL;
+
+ identity_ext = e_source_get_extension (identity_source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
+ if (identity_ext)
+ res = e_source_mail_identity_get_name (identity_ext);
- return priv->owner_name;
+ g_object_unref (identity_source);
+
+ return res;
}
static const gchar *
ecbm_get_owner_email (ECalBackendMAPI *cbmapi)
{
- ECalBackendMAPIPrivate *priv;
+ ESource *identity_source;
+ ESourceMailIdentity *identity_ext;
+ const gchar *res = NULL;
- priv = cbmapi->priv;
+ identity_source = ecbm_find_identity_source (cbmapi);
+ if (!identity_source)
+ return NULL;
+
+ identity_ext = e_source_get_extension (identity_source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
+ if (identity_ext)
+ res = e_source_mail_identity_get_address (identity_ext);
- return priv->owner_email;
+ g_object_unref (identity_source);
+
+ return res;
}
static const gchar *
ecbm_get_user_name (ECalBackendMAPI *cbmapi)
{
- ECalBackendMAPIPrivate *priv;
-
- priv = cbmapi->priv;
-
- return priv->user_name;
+ return ecbm_get_owner_name (cbmapi);
}
static const gchar *
ecbm_get_user_email (ECalBackendMAPI *cbmapi)
{
- ECalBackendMAPIPrivate *priv;
-
- priv = cbmapi->priv;
-
- return priv->user_email;
+ return ecbm_get_owner_email (cbmapi);
}
static gboolean
@@ -252,12 +326,10 @@ ecbm_get_backend_property (ECalBackend *backend, EDataCal *cal, const gchar *pro
);
} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS)) {
ECalBackendMAPI *cbmapi;
- ECalBackendMAPIPrivate *priv;
cbmapi = E_CAL_BACKEND_MAPI (backend);
- priv = cbmapi->priv;
- *prop_value = g_strdup (priv->user_email);
+ *prop_value = g_strdup (ecbm_get_user_email (cbmapi));
} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS)) {
/* We don't support email alarms. This should not have been called. */
*prop_value = NULL;
@@ -394,7 +466,7 @@ notify_view_progress (ECalBackendMAPI *cbmapi, guint index, guint total)
/* To translators: This message is displayed on the status bar when calendar/tasks/memo items are being fetched from the server. */
progress_string = g_strdup_printf (_("Loading items in folder %s"),
- e_source_peek_name (e_backend_get_source (E_BACKEND (cbmapi))));
+ e_source_get_display_name (e_backend_get_source (E_BACKEND (cbmapi))));
pd.msg = progress_string;
@@ -1041,36 +1113,6 @@ run_delta_thread (ECalBackendMAPI *cbmapi)
}
static void
-ecbm_connect (ECalBackendMAPI *cbmapi, GError **perror)
-{
- ECalBackendMAPIPrivate *priv;
-
- priv = cbmapi->priv;
-
- if (!priv->fid) {
- g_propagate_error (perror, EDC_ERROR_EX (OtherError, "No folder ID set"));
- return;
- }
-
- if (!priv->conn || !e_mapi_connection_connected (priv->conn)) {
- g_propagate_error (perror, EDC_ERROR (AuthenticationFailed));
- return;
- }
-
- /* We have established a connection */
- if (priv->store && priv->fid) {
- e_cal_backend_notify_online (E_CAL_BACKEND (cbmapi), TRUE);
-
- if (priv->mode_changed && !priv->dthread) {
- priv->mode_changed = FALSE;
- run_delta_thread (cbmapi);
- }
- }
-
- priv->mode_changed = FALSE;
-}
-
-static void
ecbm_server_notification_cb (EMapiConnection *conn,
guint event_mask,
gpointer event_data,
@@ -1138,11 +1180,15 @@ ecbm_server_notification_cb (EMapiConnection *conn,
run_delta_thread (cbmapi);
}
-static void
-ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar *password, GError **perror)
+static ESourceAuthenticationResult
+ecbm_connect_user (ECalBackend *backend,
+ GCancellable *cancellable,
+ const GString *password,
+ GError **perror)
{
ECalBackendMAPI *cbmapi;
ECalBackendMAPIPrivate *priv;
+ CamelMapiSettings *settings;
EMapiConnection *old_conn;
GError *mapi_error = NULL;
@@ -1152,10 +1198,13 @@ ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar
priv = cbmapi->priv;
old_conn = priv->conn;
+ settings = ecbm_get_collection_settings (cbmapi);
- priv->conn = e_mapi_connection_new (priv->profile, password, cancellable, &mapi_error);
+ priv->conn = e_mapi_connection_new (
+ e_cal_backend_get_registry (backend),
+ camel_mapi_settings_get_profile (settings), password, cancellable, &mapi_error);
if (!priv->conn) {
- priv->conn = e_mapi_connection_find (priv->profile);
+ priv->conn = e_mapi_connection_find (camel_mapi_settings_get_profile (settings));
if (priv->conn
&& !e_mapi_connection_connected (priv->conn)) {
e_mapi_connection_reconnect (priv->conn, password, cancellable, &mapi_error);
@@ -1168,9 +1217,11 @@ ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar
if (priv->conn && e_mapi_connection_connected (priv->conn)) {
/* Success */
ESource *source;
+ ESourceMapiFolder *ext_mapi_folder;
source = e_backend_get_source (E_BACKEND (cbmapi));
- if (source && g_strcmp0 (e_source_get_property (source, "server-notification"), "true") == 0) {
+ ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ if (ext_mapi_folder && e_source_mapi_folder_get_server_notification (ext_mapi_folder)) {
mapi_object_t obj_folder;
gboolean status;
@@ -1186,36 +1237,67 @@ ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar
g_signal_connect (priv->conn, "server-notification", G_CALLBACK (ecbm_server_notification_cb), cbmapi);
}
} else {
- mapi_error_to_edc_error (perror, mapi_error, g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR) ? OtherError : AuthenticationFailed, NULL);
+ gboolean is_network_error = g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR);
+
+ mapi_error_to_edc_error (perror, mapi_error, is_network_error ? OtherError : AuthenticationFailed, NULL);
if (mapi_error)
g_error_free (mapi_error);
g_static_mutex_unlock (&auth_mutex);
- return;
+ return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : E_SOURCE_AUTHENTICATION_REJECTED;
}
if (mapi_error) {
mapi_error_to_edc_error (perror, mapi_error, AuthenticationFailed, NULL);
g_error_free (mapi_error);
g_static_mutex_unlock (&auth_mutex);
- return;
+ return E_SOURCE_AUTHENTICATION_REJECTED;
}
g_static_mutex_unlock (&auth_mutex);
- ecbm_connect (cbmapi, perror);
+ if (!priv->fid) {
+ g_propagate_error (perror, EDC_ERROR_EX (OtherError, "No folder ID set"));
+ return E_SOURCE_AUTHENTICATION_ERROR;
+ }
+
+ if (!priv->conn || !e_mapi_connection_connected (priv->conn)) {
+ g_propagate_error (perror, EDC_ERROR (AuthenticationFailed));
+ return E_SOURCE_AUTHENTICATION_REJECTED;
+ }
+
+ /* We have established a connection */
+ if (priv->store && priv->fid) {
+ e_cal_backend_notify_online (E_CAL_BACKEND (cbmapi), TRUE);
+
+ if (priv->mode_changed && !priv->dthread) {
+ priv->mode_changed = FALSE;
+ run_delta_thread (cbmapi);
+ }
+ }
+
+ priv->mode_changed = FALSE;
+
+ return E_SOURCE_AUTHENTICATION_ACCEPTED;
}
static void
-ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
+ecbm_open (ECalBackend *backend,
+ EDataCal *cal,
+ GCancellable *cancellable,
+ gboolean only_if_exists,
+ GError **perror)
{
ECalBackendMAPI *cbmapi;
ECalBackendMAPIPrivate *priv;
ESource *esource;
- const gchar *fid = NULL;
- const gchar *cache_dir, *krb_sso = NULL;
+ ESourceMapiFolder *ext_mapi_folder;
+ guint64 fid;
+ const gchar *cache_dir;
+ CamelMapiSettings *settings;
+ GError *error = NULL;
- if (e_cal_backend_is_opened (E_CAL_BACKEND (backend))) {
+ if (e_cal_backend_is_opened (backend)) {
e_cal_backend_notify_opened (backend, NULL);
return /* Success */;
}
@@ -1223,9 +1305,12 @@ ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gbool
cbmapi = E_CAL_BACKEND_MAPI (backend);
priv = cbmapi->priv;
+ settings = ecbm_get_collection_settings (cbmapi);
+
esource = e_backend_get_source (E_BACKEND (cbmapi));
- fid = e_source_get_property (esource, "folder-id");
- if (!(fid && *fid)) {
+ ext_mapi_folder = e_source_get_extension (esource, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ fid = e_source_mapi_folder_get_id (ext_mapi_folder);
+ if (!fid) {
g_propagate_error (perror, EDC_ERROR_EX (OtherError, "No folder ID set"));
e_cal_backend_notify_opened (backend, EDC_ERROR_EX (OtherError, "No folder ID set"));
return;
@@ -1255,13 +1340,13 @@ ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gbool
/* Not for remote */
if (!e_backend_get_online (E_BACKEND (backend))) {
- const gchar *display_contents = NULL;
+ ESourceOffline *offline_extension;
cbmapi->priv->read_only = TRUE;
- display_contents = e_source_get_property (esource, "offline_sync");
+ offline_extension = e_source_get_extension (esource, E_SOURCE_EXTENSION_OFFLINE);
- if (!display_contents || !g_str_equal (display_contents, "1")) {
+ if (!e_source_offline_get_stay_synchronized (offline_extension)) {
g_mutex_unlock (priv->mutex);
g_propagate_error (perror, EDC_ERROR (RepositoryOffline));
e_cal_backend_notify_opened (backend, EDC_ERROR (RepositoryOffline));
@@ -1275,51 +1360,48 @@ ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gbool
return /* Success */;
}
- g_free (priv->profile);
- g_free (priv->user_name);
- g_free (priv->user_email);
- g_free (priv->owner_name);
- g_free (priv->owner_email);
g_free (priv->foreign_username);
- priv->profile = e_source_get_duped_property (esource, "profile");
- priv->user_name = e_source_get_duped_property (esource, "acl-user-name");
- priv->user_email = e_source_get_duped_property (esource, "acl-user-email");
- priv->owner_name = e_source_get_duped_property (esource, "acl-owner-name");
- priv->owner_email = e_source_get_duped_property (esource, "acl-owner-email");
-
- e_mapi_util_mapi_id_from_string (fid, &priv->fid);
- priv->is_public_folder = g_strcmp0 (e_source_get_property (esource, "public"), "yes") == 0;
- priv->foreign_username = e_source_get_duped_property (esource, "foreign-username");
+ priv->fid = fid;
+ priv->is_public_folder = e_source_mapi_folder_is_public (ext_mapi_folder);
+ priv->foreign_username = e_source_mapi_folder_dup_foreign_username (ext_mapi_folder);
if (priv->foreign_username && !*priv->foreign_username) {
g_free (priv->foreign_username);
priv->foreign_username = NULL;
}
- krb_sso = e_source_get_property (esource, "kerberos");
g_mutex_unlock (priv->mutex);
e_cal_backend_notify_online (backend, TRUE);
e_cal_backend_notify_readonly (backend, priv->read_only);
- if (!krb_sso || !g_str_equal (krb_sso, "required")) {
- e_cal_backend_notify_auth_required (backend, TRUE, NULL);
- } else {
- ecbm_connect_user (backend, cancellable, NULL, perror);
- e_cal_backend_notify_opened (backend, NULL);
+ if (!camel_mapi_settings_get_kerberos (settings) ||
+ ecbm_connect_user (backend, cancellable, NULL, &error) != E_SOURCE_AUTHENTICATION_ACCEPTED) {
+ ESourceRegistry *registry;
+
+ registry = e_cal_backend_get_registry (backend);
+
+ e_source_registry_authenticate_sync (
+ registry, esource,
+ E_SOURCE_AUTHENTICATOR (backend),
+ cancellable, &error);
}
+
+ if (error && perror)
+ g_propagate_error (perror, g_error_copy (error));
+
+ e_cal_backend_notify_opened (backend, error);
}
-static void
-ecbm_authenticate_user (ECalBackend *backend, GCancellable *cancellable, ECredentials *credentials, GError **perror)
-{
- const gchar *password;
- g_static_mutex_lock (&auth_mutex);
- password = e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD);
- g_static_mutex_unlock (&auth_mutex);
- ecbm_connect_user (backend, cancellable, password, perror);
+static ESourceAuthenticationResult
+ecbm_try_password_sync (ESourceAuthenticator *authenticator,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return ecbm_connect_user (E_CAL_BACKEND (authenticator), cancellable, password, error);
}
static gboolean
@@ -1509,7 +1591,6 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
ECalComponent *comp;
mapi_id_t mid = 0;
gchar *tmp = NULL;
- struct cal_cbdata cbdata = { 0 };
struct icaltimetype current;
GError *mapi_error = NULL;
@@ -1547,22 +1628,23 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
e_cal_component_set_created (comp, ¤t);
e_cal_component_set_last_modified (comp, ¤t);
- cbdata.kind = kind;
- cbdata.username = (gchar *) ecbm_get_user_name (cbmapi);
- cbdata.useridtype = (gchar *) "SMTP";
- cbdata.userid = (gchar *) ecbm_get_user_email (cbmapi);
- cbdata.ownername = (gchar *) ecbm_get_owner_name (cbmapi);
- cbdata.owneridtype = (gchar *) "SMTP";
- cbdata.ownerid = (gchar *) ecbm_get_owner_email (cbmapi);
- cbdata.get_timezone = (icaltimezone * (*)(gpointer data, const gchar *tzid)) ecbm_internal_get_timezone;
- cbdata.get_tz_data = cbmapi;
-
/* Check if object exists */
if (e_backend_get_online (E_BACKEND (backend))) {
+ struct cal_cbdata cbdata = { 0 };
gboolean status;
mapi_object_t obj_folder;
gboolean has_attendees = e_cal_component_has_attendees (comp);
+ cbdata.kind = kind;
+ cbdata.username = g_strdup (ecbm_get_user_name (cbmapi));
+ cbdata.useridtype = (gchar *) "SMTP";
+ cbdata.userid = g_strdup (ecbm_get_user_email (cbmapi));
+ cbdata.ownername = g_strdup (ecbm_get_owner_name (cbmapi));
+ cbdata.owneridtype = (gchar *) "SMTP";
+ cbdata.ownerid = g_strdup (ecbm_get_owner_email (cbmapi));
+ cbdata.get_timezone = (icaltimezone * (*)(gpointer data, const gchar *tzid)) ecbm_internal_get_timezone;
+ cbdata.get_tz_data = cbmapi;
+
/* Create an appointment */
cbdata.comp = comp;
cbdata.is_modify = FALSE;
@@ -1583,6 +1665,11 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
e_mapi_connection_close_folder (priv->conn, &obj_folder, cancellable, &mapi_error);
}
+ g_free (cbdata.username);
+ g_free (cbdata.userid);
+ g_free (cbdata.ownername);
+ g_free (cbdata.ownerid);
+
if (!mid) {
g_object_unref (comp);
mapi_error_to_edc_error (error, mapi_error, OtherError, _("Failed to create item on a server"));
@@ -2384,8 +2471,6 @@ ecbm_notify_online_cb (ECalBackend *backend, GParamSpec *pspec)
{
ECalBackendMAPI *cbmapi;
ECalBackendMAPIPrivate *priv;
- ESource *esource = NULL;
- const gchar *krb_sso = NULL;
gboolean online;
cbmapi = E_CAL_BACKEND_MAPI (backend);
@@ -2395,17 +2480,9 @@ ecbm_notify_online_cb (ECalBackend *backend, GParamSpec *pspec)
g_mutex_lock (priv->mutex);
- esource = e_backend_get_source (E_BACKEND (cbmapi));
- krb_sso = e_source_get_property (esource, "kerberos");
- e_cal_backend_notify_online (backend, online);
-
priv->mode_changed = TRUE;
if (online) {
priv->read_only = FALSE;
- if (e_cal_backend_is_opened (backend)
- && ! (krb_sso && g_str_equal (krb_sso, "required"))) {
- e_cal_backend_notify_auth_required (backend, TRUE, NULL);
- }
} else {
priv->read_only = TRUE;
@@ -2414,6 +2491,7 @@ ecbm_notify_online_cb (ECalBackend *backend, GParamSpec *pspec)
}
e_cal_backend_notify_readonly (backend, priv->read_only);
+ e_cal_backend_notify_online (backend, online);
g_mutex_unlock (priv->mutex);
}
@@ -2472,7 +2550,6 @@ ecbm_internal_get_timezone (ECalBackend *backend, const gchar *tzid)
typedef enum {
OP_GET_BACKEND_PROPERTY,
OP_OPEN,
- OP_AUTHENTICATE_USER,
OP_REFRESH,
OP_REMOVE,
OP_CREATE_OBJECTS,
@@ -2507,13 +2584,6 @@ typedef struct {
typedef struct {
OperationBase base;
- ECredentials *credentials;
- GCancellable *cancellable;
-} OperationAuthenticateUser;
-
-typedef struct {
- OperationBase base;
-
GSList *calobjs;
} OperationCreate;
@@ -2601,16 +2671,6 @@ ecbm_operation_cb (OperationBase *op, gboolean cancelled, ECalBackend *backend)
e_data_cal_respond_open (op->cal, op->opid, error);
}
} break;
- case OP_AUTHENTICATE_USER: {
- OperationAuthenticateUser *opau = (OperationAuthenticateUser *) op;
-
- if (!cancelled) {
- ecbm_authenticate_user (backend, op->cancellable, opau->credentials, &error);
-
- e_cal_backend_notify_opened (backend, error);
- }
- e_credentials_free (opau->credentials);
- } break;
case OP_REFRESH: {
if (!cancelled) {
ecbm_refresh (backend, op->cal, op->cancellable, &error);
@@ -3099,34 +3159,6 @@ ecbm_op_open (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *c
e_mapi_operation_queue_push (priv->op_queue, op);
}
-static void
-ecbm_op_authenticate_user (ECalBackend *backend, GCancellable *cancellable, ECredentials *credentials)
-{
- OperationAuthenticateUser *op;
- ECalBackendMAPI *cbmapi;
- ECalBackendMAPIPrivate *priv;
-
- g_return_if_fail (backend != NULL);
- g_return_if_fail (E_IS_CAL_BACKEND_MAPI (backend));
-
- cbmapi = E_CAL_BACKEND_MAPI (backend);
- priv = cbmapi->priv;
- g_return_if_fail (priv != NULL);
-
- g_object_ref (cbmapi);
- if (cancellable)
- g_object_ref (cancellable);
-
- op = g_new0 (OperationAuthenticateUser, 1);
- op->base.ot = OP_AUTHENTICATE_USER;
- op->base.cal = NULL;
- op->base.opid = 0;
- op->base.cancellable = cancellable;
- op->credentials = e_credentials_new_clone (credentials);
-
- e_mapi_operation_queue_push (priv->op_queue, op);
-}
-
STR_OP_DEF (ecbm_op_get_backend_property, OP_GET_BACKEND_PROPERTY)
BASE_OP_DEF (ecbm_op_refresh, OP_REFRESH)
BASE_OP_DEF (ecbm_op_remove, OP_REMOVE)
@@ -3430,31 +3462,6 @@ ecbm_finalize (GObject *object)
priv->store = NULL;
}
- if (priv->profile) {
- g_free (priv->profile);
- priv->profile = NULL;
- }
-
- if (priv->user_name) {
- g_free (priv->user_name);
- priv->user_name = NULL;
- }
-
- if (priv->user_email) {
- g_free (priv->user_email);
- priv->user_email = NULL;
- }
-
- if (priv->owner_name) {
- g_free (priv->owner_name);
- priv->owner_name = NULL;
- }
-
- if (priv->owner_email) {
- g_free (priv->owner_email);
- priv->owner_email = NULL;
- }
-
if (priv->sendoptions_sync_timeout) {
g_source_remove (priv->sendoptions_sync_timeout);
priv->sendoptions_sync_timeout = 0;
@@ -3493,7 +3500,6 @@ e_cal_backend_mapi_class_init (ECalBackendMAPIClass *class)
/* functions done asynchronously */
backend_class->get_backend_property = ecbm_op_get_backend_property;
backend_class->open = ecbm_op_open;
- backend_class->authenticate_user = ecbm_op_authenticate_user;
backend_class->refresh = ecbm_op_refresh;
backend_class->remove = ecbm_op_remove;
backend_class->get_object = ecbm_op_get_object;
@@ -3515,6 +3521,12 @@ e_cal_backend_mapi_class_init (ECalBackendMAPIClass *class)
}
static void
+e_cal_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+ interface->try_password_sync = ecbm_try_password_sync;
+}
+
+static void
e_cal_backend_mapi_init (ECalBackendMAPI *cbmapi)
{
ECalBackendMAPIPrivate *priv;
diff --git a/src/calendar/e-cal-backend-mapi.h b/src/calendar/e-cal-backend-mapi.h
index 91374d0..dc8689f 100644
--- a/src/calendar/e-cal-backend-mapi.h
+++ b/src/calendar/e-cal-backend-mapi.h
@@ -26,7 +26,7 @@
#include <glib.h>
-#include <libedata-cal/e-cal-backend.h>
+#include <libedata-cal/libedata-cal.h>
G_BEGIN_DECLS
diff --git a/src/camel/Makefile.am b/src/camel/Makefile.am
index ce4cc97..6b7ab43 100644
--- a/src/camel/Makefile.am
+++ b/src/camel/Makefile.am
@@ -7,6 +7,7 @@ AM_CPPFLAGS = -I.. \
-I$(top_srcdir)/src/ \
-I$(top_srcdir)/src/camel \
-I$(top_srcdir)/src/libexchangemapi \
+ $(EVOLUTION_MAIL_CFLAGS) \
$(CAMEL_CFLAGS) \
$(LIBECAL_CFLAGS) \
$(LIBMAPI_CFLAGS) \
@@ -31,6 +32,7 @@ noinst_HEADERS = \
libcamelmapi_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED)
libcamelmapi_la_LIBADD = \
$(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+ $(EVOLUTION_MAIL_LIBS) \
$(CAMEL_LIBS) \
$(LIBECAL_LIBS) \
$(LIBMAPI_LIBS)
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index c5cb5a5..2a42fcc 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -35,6 +35,7 @@
#include <errno.h>
#include <libmapi/libmapi.h>
+#include <libemail-engine/e-mail-session.h>
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
@@ -313,7 +314,7 @@ mapi_convert_to_folder_info (CamelMapiStore *store,
name = escape_slash (e_mapi_folder_get_name (folder));
- id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_fid (folder));
+ id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_id (folder));
fi = camel_folder_info_new ();
@@ -518,7 +519,7 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, GCancellable *cancellab
gchar *fid = NULL, *parent_id = NULL, *tmp = NULL;
guint *folder_type = g_new0 (guint, 1);
- fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_fid((EMapiFolder *)(temp_list->data)));
+ fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_id ((EMapiFolder *)(temp_list->data)));
parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_parent_id ((EMapiFolder *)(temp_list->data)));
full_name = g_hash_table_lookup (priv->id_hash, fid);
if (!full_name) {
@@ -569,7 +570,7 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, GCancellable *cancellab
if (!msi) {
msi = (CamelMapiStoreInfo *) camel_mapi_store_summary_add_from_full (store->summary,
info->full_name,
- e_mapi_folder_get_fid (folder),
+ e_mapi_folder_get_id (folder),
e_mapi_folder_get_parent_id (folder),
info->flags,
folder->category == E_MAPI_FOLDER_CATEGORY_PERSONAL ? CAMEL_MAPI_STORE_FOLDER_FLAG_PERSONAL :
@@ -600,7 +601,7 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, GCancellable *cancellab
if (!msi) {
msi = (CamelMapiStoreInfo *) camel_mapi_store_summary_add_from_full (store->summary,
info->full_name,
- e_mapi_folder_get_fid (folder),
+ e_mapi_folder_get_id (folder),
e_mapi_folder_get_parent_id (folder),
info->flags,
CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC | CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC_REAL,
@@ -693,12 +694,17 @@ unescape_folder_names (CamelFolderInfo *fi)
}
static CamelFolderInfo *
-mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
- guint32 flags, GError **error)
+mapi_get_folder_info_offline (CamelStore *store,
+ const gchar *top,
+ guint32 flags,
+ GCancellable *cancellable,
+ GError **error)
{
CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
- CamelNetworkSettings *network_settings;
+ CamelMapiSettings *settings;
CamelFolderInfo *fi;
+ ESourceRegistry *registry = NULL;
+ GList *my_sources = NULL;
GPtrArray *folders;
gchar *path;
gint i, count;
@@ -708,9 +714,23 @@ mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
subscribed = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
- network_settings = CAMEL_NETWORK_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+ settings = CAMEL_MAPI_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
folders = g_ptr_array_new ();
+ if (subscription_list) {
+ GError *local_error = NULL;
+
+ registry = e_source_registry_new_sync (cancellable, &local_error);
+ if (registry) {
+ GList *all_sources = e_source_registry_list_sources (registry, NULL);
+
+ my_sources = e_mapi_utils_filter_sources_for_profile (all_sources,
+ camel_mapi_settings_get_profile (settings));
+
+ g_list_free_full (all_sources, g_object_unref);
+ }
+ }
+
if (!top || !*top)
top = "";
@@ -778,15 +798,10 @@ mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
folder_type = mapi_folders_hash_table_type_lookup (mapi_store, camel_store_info_path (mapi_store->summary, si));
if (folder_type != E_MAPI_FOLDER_TYPE_UNKNOWN && folder_type != E_MAPI_FOLDER_TYPE_MAIL) {
- gchar *fid = e_mapi_util_mapi_id_to_string (msi->folder_id);
-
- if (e_mapi_folder_is_subscribed_as_esource (folder_type,
- camel_network_settings_get_host (network_settings),
- camel_network_settings_get_user (network_settings),
- fid))
+ if (e_mapi_folder_is_subscribed_as_esource (my_sources,
+ camel_mapi_settings_get_profile (settings),
+ msi->folder_id))
fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
-
- g_free (fid);
}
}
@@ -823,6 +838,10 @@ mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0 ?
_("No public folder found") : _("No folder found"));
+ g_list_free_full (my_sources, g_object_unref);
+ if (registry)
+ g_object_unref (registry);
+
return fi;
}
@@ -1191,7 +1210,7 @@ mapi_store_get_folder_info_sync (CamelStore *store,
}
}
- return mapi_get_folder_info_offline (store, top, flags, error);
+ return mapi_get_folder_info_offline (store, top, flags, cancellable, error);
}
static CamelFolder *
@@ -1792,8 +1811,6 @@ mapi_store_subscribe_folder_sync (CamelSubscribable *subscribable,
} else {
CamelSettings *settings;
CamelMapiSettings *mapi_settings;
- CamelNetworkSettings *network_settings;
- gchar *folder_id;
guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
/* remember the folder, thus it can be removed and checked in Subscriptions dialog */
@@ -1802,31 +1819,22 @@ mapi_store_subscribe_folder_sync (CamelSubscribable *subscribable,
settings = camel_service_get_settings (CAMEL_SERVICE (mapi_store));
mapi_settings = CAMEL_MAPI_SETTINGS (settings);
- network_settings = CAMEL_NETWORK_SETTINGS (settings);
-
- folder_id = e_mapi_util_mapi_id_to_string (msi->folder_id);
- if (!e_mapi_folder_add_as_esource (folder_type,
+ if (!e_mapi_folder_add_as_esource (NULL, folder_type,
camel_mapi_settings_get_profile (mapi_settings),
- camel_mapi_settings_get_domain (mapi_settings),
- camel_mapi_settings_get_realm (mapi_settings),
- camel_network_settings_get_host (network_settings),
- camel_network_settings_get_user (network_settings),
- camel_mapi_settings_get_kerberos (mapi_settings),
TRUE /* camel_offline_settings_get_stay_synchronized (CAMEL_OFFLINE_SETTINGS (mapi_settings)) */,
E_MAPI_FOLDER_CATEGORY_PUBLIC,
NULL,
use_folder_name,
- folder_id,
+ msi->folder_id,
+ (gint) msi->folder_id,
+ cancellable,
error)) {
camel_store_summary_info_free (mapi_store->summary, si);
- g_free (folder_id);
g_free (path);
return FALSE;
}
-
- g_free (folder_id);
}
camel_store_summary_info_free (mapi_store->summary, si);
camel_store_summary_save (mapi_store->summary);
@@ -1884,17 +1892,14 @@ mapi_store_unsubscribe_folder_sync (CamelSubscribable *subscribable,
g_debug ("%s: Failed to find subscribed by folder ID", G_STRFUNC);
}
} else {
- CamelSettings *settings;
- CamelNetworkSettings *network_settings;
- guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
+ CamelMapiSettings *settings;
- settings = camel_service_get_settings (CAMEL_SERVICE (mapi_store));
- network_settings = CAMEL_NETWORK_SETTINGS (settings);
+ settings = CAMEL_MAPI_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (mapi_store)));
- res = e_mapi_folder_remove_as_esource (folder_type,
- camel_network_settings_get_host (network_settings),
- camel_network_settings_get_user (network_settings),
- camel_mapi_store_folder_id_lookup (mapi_store, folder_name),
+ res = e_mapi_folder_remove_as_esource (NULL,
+ camel_mapi_settings_get_profile (settings),
+ msi->folder_id,
+ cancellable,
error);
}
@@ -2516,6 +2521,7 @@ mapi_authenticate_sync (CamelService *service,
const gchar *profile;
const gchar *password;
GError *mapi_error = NULL;
+ GString *password_str;
settings = camel_service_get_settings (service);
mapi_settings = CAMEL_MAPI_SETTINGS (settings);
@@ -2544,7 +2550,11 @@ mapi_authenticate_sync (CamelService *service,
return CAMEL_AUTHENTICATION_ERROR;
}
- store->priv->conn = e_mapi_connection_new (profile, password, cancellable, &mapi_error);
+ password_str = g_string_new (password);
+ store->priv->conn = e_mapi_connection_new (
+ e_mail_session_get_registry (E_MAIL_SESSION (camel_service_get_session (service))),
+ profile, password_str, cancellable, &mapi_error);
+ g_string_free (password_str, TRUE);
if (store->priv->conn && e_mapi_connection_connected (store->priv->conn)) {
result = CAMEL_AUTHENTICATION_ACCEPTED;
diff --git a/src/collection/Makefile.am b/src/collection/Makefile.am
new file mode 100644
index 0000000..f6b4ab3
--- /dev/null
+++ b/src/collection/Makefile.am
@@ -0,0 +1,35 @@
+NULL =
+
+eds_module_LTLIBRARIES = module-mapi-backend.la
+
+module_mapi_backend_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"module-mapi-backend\" \
+ -I$(top_srcdir)/src/libexchangemapi \
+ $(LIBEDATASERVER_CFLAGS) \
+ $(LIBEBACKEND_CFLAGS) \
+ $(LIBMAPI_CFLAGS) \
+ $(CAMEL_CFLAGS) \
+ $(NULL)
+
+module_mapi_backend_la_SOURCES = \
+ module-mapi-backend.c \
+ e-mapi-backend.c \
+ e-mapi-backend.h \
+ e-mapi-backend-factory.c \
+ e-mapi-backend-factory.h \
+ $(NULL)
+
+module_mapi_backend_la_LIBADD = \
+ $(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+ $(LIBEDATASERVER_LIBS) \
+ $(LIBEBACKEND_LIBS) \
+ $(LIBMAPI_LIBS) \
+ $(CAMEL_LIBS) \
+ $(NULL)
+
+module_mapi_backend_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED) \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/src/collection/e-mapi-backend-factory.c b/src/collection/e-mapi-backend-factory.c
new file mode 100644
index 0000000..18dcc24
--- /dev/null
+++ b/src/collection/e-mapi-backend-factory.c
@@ -0,0 +1,100 @@
+/*
+ * e-mapi-backend-factory.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-mapi-backend-factory.h"
+
+#include "e-mapi-backend.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+ EMapiBackendFactory,
+ e_mapi_backend_factory,
+ E_TYPE_COLLECTION_BACKEND_FACTORY)
+
+static void
+mapi_backend_prepare_mail_account_source (ESource *source)
+{
+ ESourceBackend *extension;
+ const gchar *extension_name;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+ e_source_backend_set_backend_name (extension, "mapi");
+}
+
+static void
+mapi_backend_prepare_mail_transport_source (ESource *source)
+{
+ ESourceBackend *extension;
+ const gchar *extension_name;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+ extension = e_source_get_extension (source, extension_name);
+ e_source_backend_set_backend_name (extension, "mapi");
+}
+
+static void
+mapi_backend_factory_prepare_mail (ECollectionBackendFactory *factory,
+ ESource *mail_account_source,
+ ESource *mail_identity_source,
+ ESource *mail_transport_source)
+{
+ ECollectionBackendFactoryClass *parent_class;
+
+ /* Chain up to parent's prepare_mail() method. */
+ parent_class =
+ E_COLLECTION_BACKEND_FACTORY_CLASS (
+ e_mapi_backend_factory_parent_class);
+ parent_class->prepare_mail (
+ factory,
+ mail_account_source,
+ mail_identity_source,
+ mail_transport_source);
+
+ mapi_backend_prepare_mail_account_source (mail_account_source);
+ mapi_backend_prepare_mail_transport_source (mail_transport_source);
+}
+
+static void
+e_mapi_backend_factory_class_init (EMapiBackendFactoryClass *class)
+{
+ ECollectionBackendFactoryClass *factory_class;
+
+ factory_class = E_COLLECTION_BACKEND_FACTORY_CLASS (class);
+ factory_class->factory_name = "mapi";
+ factory_class->backend_type = E_TYPE_MAPI_BACKEND;
+ factory_class->prepare_mail = mapi_backend_factory_prepare_mail;
+}
+
+static void
+e_mapi_backend_factory_class_finalize (EMapiBackendFactoryClass *class)
+{
+}
+
+static void
+e_mapi_backend_factory_init (EMapiBackendFactory *factory)
+{
+}
+
+void
+e_mapi_backend_factory_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_mapi_backend_factory_register_type (type_module);
+}
diff --git a/src/collection/e-mapi-backend-factory.h b/src/collection/e-mapi-backend-factory.h
new file mode 100644
index 0000000..2c339ac
--- /dev/null
+++ b/src/collection/e-mapi-backend-factory.h
@@ -0,0 +1,64 @@
+/*
+ * e-mapi-backend-factory.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_MAPI_BACKEND_FACTORY_H
+#define E_MAPI_BACKEND_FACTORY_H
+
+#include <libebackend/libebackend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAPI_BACKEND_FACTORY \
+ (e_mapi_backend_factory_get_type ())
+#define E_MAPI_BACKEND_FACTORY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAPI_BACKEND_FACTORY, EMapiBackendFactory))
+#define E_MAPI_BACKEND_FACTORY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAPI_BACKEND_FACTORY, EMapiBackendFactoryClass))
+#define E_IS_MAPI_BACKEND_FACTORY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAPI_BACKEND_FACTORY))
+#define E_IS_MAPI_BACKEND_FACTORY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAPI_BACKEND_FACTORY))
+#define E_MAPI_BACKEND_FACTORY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAPI_BACKEND_FACTORY, EMapiBackendFactoryClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMapiBackendFactory EMapiBackendFactory;
+typedef struct _EMapiBackendFactoryClass EMapiBackendFactoryClass;
+typedef struct _EMapiBackendFactoryPrivate EMapiBackendFactoryPrivate;
+
+struct _EMapiBackendFactory {
+ ECollectionBackendFactory parent;
+ EMapiBackendFactoryPrivate *priv;
+};
+
+struct _EMapiBackendFactoryClass {
+ ECollectionBackendFactoryClass parent_class;
+};
+
+GType e_mapi_backend_factory_get_type (void) G_GNUC_CONST;
+void e_mapi_backend_factory_type_register
+ (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAPI_BACKEND_FACTORY_H */
diff --git a/src/collection/e-mapi-backend.c b/src/collection/e-mapi-backend.c
new file mode 100644
index 0000000..82e8dd1
--- /dev/null
+++ b/src/collection/e-mapi-backend.c
@@ -0,0 +1,573 @@
+/*
+ * e-mapi-backend.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-mapi-backend.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <e-mapi-connection.h>
+#include <e-mapi-folder.h>
+#include <e-mapi-utils.h>
+#include <e-source-mapi-folder.h>
+#include <camel-mapi-settings.h>
+
+#define E_MAPI_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAPI_BACKEND, EMapiBackendPrivate))
+
+struct _EMapiBackendPrivate {
+ /* Folder ID -> ESource */
+ GHashTable *folders;
+
+ gboolean need_update_folders;
+};
+
+static void e_mapi_backend_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMapiBackend,
+ e_mapi_backend,
+ E_TYPE_COLLECTION_BACKEND,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_SOURCE_AUTHENTICATOR,
+ e_mapi_backend_authenticator_init))
+
+static CamelMapiSettings *
+mapi_backend_get_settings (EMapiBackend *backend)
+{
+ ESource *source;
+ ESourceCamel *extension;
+ CamelSettings *settings;
+ const gchar *extension_name;
+
+ source = e_backend_get_source (E_BACKEND (backend));
+ extension_name = e_source_camel_get_extension_name ("mapi");
+ extension = e_source_get_extension (source, extension_name);
+ settings = e_source_camel_get_settings (extension);
+
+ return CAMEL_MAPI_SETTINGS (settings);
+}
+
+static void
+mapi_backend_queue_auth_session (EMapiBackend *backend)
+{
+ ESourceRegistryServer *server;
+ EAuthenticationSession *session;
+ ESource *source;
+
+ backend->priv->need_update_folders = FALSE;
+
+ server = e_collection_backend_ref_server (E_COLLECTION_BACKEND (backend));
+ source = e_backend_get_source (E_BACKEND (backend));
+
+ session = e_authentication_session_new (
+ server, E_SOURCE_AUTHENTICATOR (backend),
+ e_source_get_uid (source));
+
+ e_source_registry_server_queue_auth_session (server, session);
+
+ g_object_unref (session);
+ g_object_unref (server);
+}
+
+struct SyndFoldersData
+{
+ EMapiBackend *backend;
+ GSList *folders;
+ gchar *profile;
+};
+
+static void
+sync_folders_data_free (gpointer data)
+{
+ struct SyndFoldersData *sfd = data;
+
+ if (!sfd)
+ return;
+
+ e_mapi_folder_free_list (sfd->folders);
+ g_object_unref (sfd->backend);
+ g_free (sfd->profile);
+ g_free (sfd);
+}
+
+static gboolean
+mapi_backend_sync_folders_idle_cb (gpointer user_data)
+{
+ struct SyndFoldersData *sfd = user_data;
+ GSList *iter;
+ GList *configured, *all_sources, *citer;
+ ESourceRegistryServer *server;
+ EMapiBackend *backend;
+ GSList *mapi_folders;
+ gboolean has_gal = FALSE;
+ gint color_seed;
+
+ g_return_val_if_fail (sfd != NULL, FALSE);
+ g_return_val_if_fail (sfd->backend != NULL, FALSE);
+ g_return_val_if_fail (sfd->profile != NULL, FALSE);
+
+ backend = sfd->backend;
+ mapi_folders = sfd->folders;
+
+ server = e_collection_backend_ref_server (E_COLLECTION_BACKEND (backend));
+ all_sources = e_source_registry_server_list_sources (server, NULL);
+ configured = e_mapi_utils_filter_sources_for_profile (all_sources, sfd->profile);
+ g_list_free_full (all_sources, g_object_unref);
+
+ color_seed = g_list_length (configured);
+
+ for (iter = mapi_folders; iter; iter = iter->next) {
+ EMapiFolder *folder = iter->data;
+ ESource *source;
+
+ if (e_mapi_folder_get_category (folder) != E_MAPI_FOLDER_CATEGORY_PERSONAL)
+ continue;
+
+ switch (e_mapi_folder_get_type (folder)) {
+ case E_MAPI_FOLDER_TYPE_APPOINTMENT:
+ case E_MAPI_FOLDER_TYPE_CONTACT:
+ case E_MAPI_FOLDER_TYPE_MEMO:
+ case E_MAPI_FOLDER_TYPE_JOURNAL:
+ case E_MAPI_FOLDER_TYPE_TASK:
+ break;
+ default:
+ continue;
+ }
+
+ source = e_mapi_utils_get_source_for_folder (configured, sfd->profile, e_mapi_folder_get_id (folder));
+ if (source) {
+ if (g_strcmp0 (e_source_get_display_name (source), e_mapi_folder_get_name (folder)) != 0)
+ e_source_set_display_name (source, e_mapi_folder_get_name (folder));
+
+ configured = g_list_remove (configured, source);
+ g_object_unref (source);
+ } else {
+ gchar *fid_str, *res_id;
+ const gchar *parent_id;
+
+ source = e_backend_get_source (E_BACKEND (backend));
+
+ parent_id = e_source_get_uid (source);
+ fid_str = e_mapi_util_mapi_id_to_string (e_mapi_folder_get_id (folder));
+ res_id = g_strconcat (parent_id ? parent_id : "mapi", ".", fid_str, NULL);
+ g_free (fid_str);
+
+ source = e_collection_backend_new_child (E_COLLECTION_BACKEND (backend), res_id);
+
+ if (e_mapi_folder_populate_esource (
+ source,
+ configured,
+ e_mapi_folder_get_type (folder),
+ sfd->profile,
+ TRUE,
+ E_MAPI_FOLDER_CATEGORY_PERSONAL,
+ NULL,
+ e_mapi_folder_get_name (folder),
+ e_mapi_folder_get_id (folder),
+ color_seed,
+ NULL,
+ NULL)) {
+ color_seed++;
+ e_source_registry_server_add_source (server, source);
+ }
+
+ g_free (res_id);
+ g_object_unref (source);
+ }
+ }
+
+ /* those which left are either mail sources, GAL or removed from the server */
+ for (citer = configured; citer; citer = citer->next) {
+ ESource *source = citer->data;
+ ESourceMapiFolder *folder_ext;
+ const gchar *foreign_user_name;
+
+ if (!e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER))
+ continue;
+
+ if (!e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK) &&
+ !e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR) &&
+ !e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST) &&
+ !e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+ continue;
+
+ folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ if (e_source_mapi_folder_is_public (folder_ext))
+ continue;
+
+ foreign_user_name = e_source_mapi_folder_get_foreign_username (folder_ext);
+ if (foreign_user_name && *foreign_user_name)
+ continue;
+
+ /* test GAL */
+ if (!has_gal && e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
+ ESourceAddressBook *book_ext;
+
+ book_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+ has_gal = g_strcmp0 ("mapigal", e_source_backend_get_backend_name (E_SOURCE_BACKEND (book_ext))) == 0;
+ if (has_gal)
+ continue;
+ }
+
+ e_source_registry_server_remove_source (server, source);
+ }
+
+ /* add GAL, if not there already */
+ if (!has_gal) {
+ ESource *source;
+
+ source = e_collection_backend_new_child (E_COLLECTION_BACKEND (backend), "mapigal");
+
+ if (e_mapi_folder_populate_esource (
+ source,
+ configured,
+ E_MAPI_FOLDER_TYPE_CONTACT,
+ sfd->profile,
+ FALSE,
+ E_MAPI_FOLDER_CATEGORY_PERSONAL,
+ NULL,
+ _("Global Address List"),
+ -1,
+ 0,
+ NULL,
+ NULL)) {
+ ESourceAddressBook *book_ext;
+ /* ESourceContancts *contacts_ext; */
+
+ book_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+ e_source_backend_set_backend_name (E_SOURCE_BACKEND (book_ext), "mapigal");
+
+ /* exclude GAL from Birthday & Anniversaries calendar by default */
+ /* but it is not accessible from outside (yet)
+ contacts_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CONTACTS_BACKEND);
+ e_source_contacts_set_include_me (contacts_ext, FALSE); */
+
+ e_source_registry_server_add_source (server, source);
+ }
+
+ g_object_unref (source);
+ }
+
+ g_list_free_full (configured, g_object_unref);
+ g_object_unref (server);
+
+ return FALSE;
+}
+
+static void
+mapi_backend_source_changed_cb (ESource *source,
+ EMapiBackend *backend)
+{
+ /* does nothing currently */
+ if (!e_source_get_enabled (source)) {
+ backend->priv->need_update_folders = TRUE;
+ return;
+ }
+
+ if (e_source_get_enabled (source) &&
+ e_backend_get_online (E_BACKEND (backend)) &&
+ backend->priv->need_update_folders)
+ mapi_backend_queue_auth_session (backend);
+}
+
+static void
+mapi_backend_dispose (GObject *object)
+{
+ EMapiBackendPrivate *priv;
+
+ priv = E_MAPI_BACKEND_GET_PRIVATE (object);
+
+ g_hash_table_remove_all (priv->folders);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mapi_backend_parent_class)->dispose (object);
+}
+
+static void
+mapi_backend_finalize (GObject *object)
+{
+ EMapiBackendPrivate *priv;
+
+ priv = E_MAPI_BACKEND_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->folders);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mapi_backend_parent_class)->finalize (object);
+}
+
+static void
+mapi_backend_populate (ECollectionBackend *backend)
+{
+ ESource *source;
+ EMapiBackend *mapi_backend = E_MAPI_BACKEND (backend);
+
+ source = e_backend_get_source (E_BACKEND (backend));
+
+ mapi_backend->priv->need_update_folders = TRUE;
+
+ /* do not do anything, if account is disabled */
+ if (!e_source_get_enabled (source) ||
+ !e_backend_get_online (E_BACKEND (backend)))
+ return;
+
+ /* We test authentication passwords by attempting to synchronize
+ * the folder hierarchy. Since we want to synchronize the folder
+ * hierarchy immediately on startup, schedule an authentication
+ * session first thing. */
+ mapi_backend_queue_auth_session (mapi_backend);
+
+ g_signal_connect (
+ source, "changed",
+ G_CALLBACK (mapi_backend_source_changed_cb), backend);
+}
+
+static gchar *
+mapi_backend_dup_resource_id (ECollectionBackend *backend,
+ ESource *child_source)
+{
+ ESourceMapiFolder *extension;
+ const gchar *extension_name;
+ gchar *fid_str, *res_id;
+ const gchar *parent_id;
+ ESource *source;
+
+ extension_name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+ extension = e_source_get_extension (child_source, extension_name);
+ source = e_backend_get_source (E_BACKEND (backend));
+
+ parent_id = e_source_get_uid (source);
+ fid_str = e_mapi_util_mapi_id_to_string (e_source_mapi_folder_get_id (extension));
+ res_id = g_strconcat (parent_id ? parent_id : "mapi", ".", fid_str, NULL);
+ g_free (fid_str);
+
+ return res_id;
+}
+
+static void
+mapi_backend_child_added (ECollectionBackend *backend,
+ ESource *child_source)
+{
+ EMapiBackendPrivate *priv;
+ ESource *collection_source;
+ const gchar *extension_name;
+ gboolean is_mail = FALSE;
+
+ priv = E_MAPI_BACKEND_GET_PRIVATE (backend);
+
+ collection_source = e_backend_get_source (E_BACKEND (backend));
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ is_mail |= e_source_has_extension (child_source, extension_name);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ is_mail |= e_source_has_extension (child_source, extension_name);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+ is_mail |= e_source_has_extension (child_source, extension_name);
+
+ /* Synchronize mail-related display names with the collection. */
+ if (is_mail)
+ g_object_bind_property (
+ collection_source, "display-name",
+ child_source, "display-name",
+ G_BINDING_SYNC_CREATE);
+
+ /* Synchronize mail-related user with the collection identity. */
+ extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+ if (is_mail && e_source_has_extension (child_source, extension_name)) {
+ ESourceAuthentication *auth_child_extension;
+ ESourceCollection *collection_extension;
+
+ extension_name = E_SOURCE_EXTENSION_COLLECTION;
+ collection_extension = e_source_get_extension (
+ collection_source, extension_name);
+
+ extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+ auth_child_extension = e_source_get_extension (
+ child_source, extension_name);
+
+ g_object_bind_property (
+ collection_extension, "identity",
+ auth_child_extension, "user",
+ G_BINDING_SYNC_CREATE);
+ }
+
+ /* We track MAPI folders in a hash table by folder ID. */
+ extension_name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+ if (e_source_has_extension (child_source, extension_name)) {
+ ESourceMapiFolder *extension;
+ gchar *folder_id;
+
+ extension = e_source_get_extension (
+ child_source, extension_name);
+ folder_id = e_mapi_util_mapi_id_to_string (e_source_mapi_folder_get_id (extension));
+ if (folder_id != NULL)
+ g_hash_table_insert (
+ priv->folders, folder_id,
+ g_object_ref (child_source));
+ }
+
+ /* Chain up to parent's child_added() method. */
+ E_COLLECTION_BACKEND_CLASS (e_mapi_backend_parent_class)->
+ child_added (backend, child_source);
+}
+
+static void
+mapi_backend_child_removed (ECollectionBackend *backend,
+ ESource *child_source)
+{
+ EMapiBackendPrivate *priv;
+ const gchar *extension_name;
+
+ priv = E_MAPI_BACKEND_GET_PRIVATE (backend);
+
+ /* We track MAPI folders in a hash table by folder ID. */
+ extension_name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+ if (e_source_has_extension (child_source, extension_name)) {
+ ESourceMapiFolder *extension;
+ gchar *folder_id;
+
+ extension = e_source_get_extension (child_source, extension_name);
+ folder_id = e_mapi_util_mapi_id_to_string (e_source_mapi_folder_get_id (extension));
+ if (folder_id != NULL)
+ g_hash_table_remove (priv->folders, folder_id);
+ g_free (folder_id);
+ }
+
+ /* Chain up to parent's child_removed() method. */
+ E_COLLECTION_BACKEND_CLASS (e_mapi_backend_parent_class)->
+ child_removed (backend, child_source);
+}
+
+static ESourceAuthenticationResult
+mapi_backend_try_password_sync (ESourceAuthenticator *authenticator,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EMapiBackend *backend;
+ EMapiConnection *conn;
+ CamelMapiSettings *settings;
+ GSList *mapi_folders = NULL;
+ GError *mapi_error = NULL;
+
+ backend = E_MAPI_BACKEND (authenticator);
+ settings = mapi_backend_get_settings (backend);
+
+ conn = e_mapi_connection_new (NULL,
+ camel_mapi_settings_get_profile (settings),
+ password, cancellable, &mapi_error);
+
+ if (!conn) {
+ ESourceAuthenticationResult res = E_SOURCE_AUTHENTICATION_ERROR;
+
+ backend->priv->need_update_folders = TRUE;
+
+ if (g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_PASSWORD_CHANGE_REQUIRED) ||
+ g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_PASSWORD_EXPIRED))
+ res = E_SOURCE_AUTHENTICATION_REJECTED;
+
+ g_propagate_error (error, mapi_error);
+
+ return res;
+ }
+
+ if (e_mapi_connection_get_folders_list (conn, &mapi_folders, NULL, NULL, cancellable, &mapi_error)) {
+ struct SyndFoldersData *sfd;
+
+ sfd = g_new0 (struct SyndFoldersData, 1);
+ sfd->folders = mapi_folders;
+ sfd->backend = g_object_ref (backend);
+ sfd->profile = camel_mapi_settings_dup_profile (settings);
+
+ g_idle_add_full (
+ G_PRIORITY_DEFAULT_IDLE,
+ mapi_backend_sync_folders_idle_cb, sfd,
+ sync_folders_data_free);
+ } else {
+ ESource *source = e_backend_get_source (E_BACKEND (backend));
+
+ backend->priv->need_update_folders = TRUE;
+
+ g_message ("%s: Failed to get list of user's folders for '%s': %s",
+ G_STRFUNC, e_source_get_display_name (source), mapi_error ? mapi_error->message : "Unknown error");
+ }
+
+ g_object_unref (conn);
+ g_clear_error (&mapi_error);
+
+ return E_SOURCE_AUTHENTICATION_ACCEPTED;
+}
+
+static void
+e_mapi_backend_class_init (EMapiBackendClass *class)
+{
+ GObjectClass *object_class;
+ ECollectionBackendClass *backend_class;
+
+ g_type_class_add_private (class, sizeof (EMapiBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = mapi_backend_dispose;
+ object_class->finalize = mapi_backend_finalize;
+
+ backend_class = E_COLLECTION_BACKEND_CLASS (class);
+ backend_class->populate = mapi_backend_populate;
+ backend_class->dup_resource_id = mapi_backend_dup_resource_id;
+ backend_class->child_added = mapi_backend_child_added;
+ backend_class->child_removed = mapi_backend_child_removed;
+
+ /* This generates an ESourceCamel subtype for CamelMapiSettings. */
+ e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
+}
+
+static void
+e_mapi_backend_class_finalize (EMapiBackendClass *class)
+{
+}
+
+static void
+e_mapi_backend_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+ interface->try_password_sync = mapi_backend_try_password_sync;
+}
+
+static void
+e_mapi_backend_init (EMapiBackend *backend)
+{
+ backend->priv = E_MAPI_BACKEND_GET_PRIVATE (backend);
+
+ backend->priv->folders = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+}
+
+void
+e_mapi_backend_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_mapi_backend_register_type (type_module);
+}
diff --git a/src/collection/e-mapi-backend.h b/src/collection/e-mapi-backend.h
new file mode 100644
index 0000000..d30e65c
--- /dev/null
+++ b/src/collection/e-mapi-backend.h
@@ -0,0 +1,63 @@
+/*
+ * e-mapi-backend.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_MAPI_BACKEND_H
+#define E_MAPI_BACKEND_H
+
+#include <libebackend/libebackend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAPI_BACKEND \
+ (e_mapi_backend_get_type ())
+#define E_MAPI_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAPI_BACKEND, EMapiBackend))
+#define E_MAPI_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAPI_BACKEND, EMapiBackendClass))
+#define E_IS_MAPI_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAPI_BACKEND))
+#define E_IS_MAPI_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAPI_BACKEND))
+#define E_MAPI_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAPI_BACKEND, EMapiBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMapiBackend EMapiBackend;
+typedef struct _EMapiBackendClass EMapiBackendClass;
+typedef struct _EMapiBackendPrivate EMapiBackendPrivate;
+
+struct _EMapiBackend {
+ ECollectionBackend parent;
+ EMapiBackendPrivate *priv;
+};
+
+struct _EMapiBackendClass {
+ ECollectionBackendClass parent_class;
+};
+
+GType e_mapi_backend_get_type (void) G_GNUC_CONST;
+void e_mapi_backend_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAPI_BACKEND_H */
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/collection/module-mapi-backend.c
similarity index 55%
copy from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
copy to src/collection/module-mapi-backend.c
index debf5b5..50cd84f 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
+++ b/src/collection/module-mapi-backend.c
@@ -1,5 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ * module-mapi-backend.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
@@ -13,22 +14,27 @@
* 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:
- * Milan Crha <mcrha redhat com>
- *
- * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
- *
*/
-#ifndef E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
-#define E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
+#include "e-source-mapi-folder.h"
+
+#include "e-mapi-backend.h"
+#include "e-mapi-backend-factory.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
-#include <gtk/gtk.h>
-#include <camel/camel.h>
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ e_mapi_backend_type_register (type_module);
+ e_mapi_backend_factory_type_register (type_module);
-void e_mapi_subscribe_foreign_folder (GtkWindow *parent,
- CamelSession *session,
- CamelStore *store);
+ e_source_mapi_folder_type_register (type_module);
+}
-#endif /* E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H */
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/src/configuration/Makefile.am b/src/configuration/Makefile.am
new file mode 100644
index 0000000..d3cb06a
--- /dev/null
+++ b/src/configuration/Makefile.am
@@ -0,0 +1,57 @@
+NULL =
+
+evo_module_LTLIBRARIES = module-mapi-configuration.la
+
+module_mapi_configuration_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"module-mapi-configuration\" \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/libexchangemapi \
+ $(LIBECAL_CFLAGS) \
+ $(LIBEDATASERVER_CFLAGS) \
+ $(CAMEL_CFLAGS) \
+ $(EVOLUTION_MAIL_CFLAGS) \
+ $(EVOLUTION_SHELL_CFLAGS) \
+ $(LIBMAPI_CFLAGS) \
+ $(NULL)
+
+module_mapi_configuration_la_SOURCES = \
+ module-mapi-configuration.c \
+ e-book-config-mapi.c \
+ e-book-config-mapi.h \
+ e-book-config-mapigal.c \
+ e-book-config-mapigal.h \
+ e-cal-config-mapi.c \
+ e-cal-config-mapi.h \
+ e-mail-config-mapi-backend.c \
+ e-mail-config-mapi-backend.h \
+ e-mail-config-mapi-page.c \
+ e-mail-config-mapi-page.h \
+ e-mail-config-mapi-extension.c \
+ e-mail-config-mapi-extension.h \
+ e-mapi-config-ui-extension.c \
+ e-mapi-config-ui-extension.h \
+ e-mapi-config-utils.c \
+ e-mapi-config-utils.h \
+ e-mapi-edit-folder-permissions.c \
+ e-mapi-edit-folder-permissions.h \
+ e-mapi-search-gal-user.c \
+ e-mapi-search-gal-user.h \
+ e-mapi-subscribe-foreign-folder.c \
+ e-mapi-subscribe-foreign-folder.h \
+ $(NULL)
+
+module_mapi_configuration_la_LIBADD = \
+ $(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+ $(LIBECAL_LIBS) \
+ $(LIBEDATASERVER_LIBS) \
+ $(CAMEL_LIBS) \
+ $(EVOLUTION_MAIL_LIBS) \
+ $(EVOLUTION_SHELL_LIBS) \
+ $(LIBMAPI_LIBS) \
+ $(NULL)
+
+module_mapi_configuration_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/src/configuration/e-book-config-mapi.c b/src/configuration/e-book-config-mapi.c
new file mode 100644
index 0000000..48c954d
--- /dev/null
+++ b/src/configuration/e-book-config-mapi.c
@@ -0,0 +1,75 @@
+/*
+ * e-book-config-mapi.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 <misc/e-book-source-config.h>
+
+#include "e-book-config-mapi.h"
+#include "e-mapi-config-utils.h"
+
+G_DEFINE_DYNAMIC_TYPE (EBookConfigMapi, e_book_config_mapi, E_TYPE_SOURCE_CONFIG_BACKEND)
+
+static gboolean
+book_config_mapi_allow_creation (ESourceConfigBackend *backend)
+{
+ return TRUE;
+}
+
+static void
+book_config_mapi_insert_widgets (ESourceConfigBackend *backend,
+ ESource *scratch_source)
+{
+ e_mapi_config_utils_insert_widgets (backend, scratch_source);
+}
+
+static void
+e_book_config_mapi_class_init (EBookConfigMapiClass *class)
+{
+ EExtensionClass *extension_class;
+ ESourceConfigBackendClass *backend_class;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_BOOK_SOURCE_CONFIG;
+
+ backend_class = E_SOURCE_CONFIG_BACKEND_CLASS (class);
+ backend_class->backend_name = "mapi";
+ backend_class->allow_creation = book_config_mapi_allow_creation;
+ backend_class->insert_widgets = book_config_mapi_insert_widgets;
+}
+
+static void
+e_book_config_mapi_class_finalize (EBookConfigMapiClass *class)
+{
+}
+
+static void
+e_book_config_mapi_init (EBookConfigMapi *backend)
+{
+}
+
+void
+e_book_config_mapi_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_book_config_mapi_register_type (type_module);
+}
diff --git a/src/configuration/e-book-config-mapi.h b/src/configuration/e-book-config-mapi.h
new file mode 100644
index 0000000..1274551
--- /dev/null
+++ b/src/configuration/e-book-config-mapi.h
@@ -0,0 +1,63 @@
+/*
+ * e-book-config-mapi.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_BOOK_CONFIG_MAPI_H
+#define E_BOOK_CONFIG_MAPI_H
+
+#include <misc/e-source-config-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_CONFIG_MAPI \
+ (e_book_config_mapi_get_type ())
+#define E_BOOK_CONFIG_MAPI(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_BOOK_CONFIG_MAPI, EBookConfigMapi))
+#define E_BOOK_CONFIG_MAPI_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_BOOK_CONFIG_MAPI, EBookConfigMapiClass))
+#define E_IS_BOOK_CONFIG_MAPI(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_BOOK_CONFIG_MAPI))
+#define E_IS_BOOK_CONFIG_MAPI_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_BOOK_CONFIG_MAPI))
+#define E_BOOK_CONFIG_MAPI_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_BOOK_CONFIG_MAPI, EBookConfigMapiClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookConfigMapi EBookConfigMapi;
+typedef struct _EBookConfigMapiClass EBookConfigMapiClass;
+typedef struct _EBookConfigMapiPrivate EBookConfigMapiPrivate;
+
+struct _EBookConfigMapi {
+ ESourceConfigBackend parent;
+ EBookConfigMapiPrivate *priv;
+};
+
+struct _EBookConfigMapiClass {
+ ESourceConfigBackendClass parent_class;
+};
+
+GType e_book_config_mapi_get_type (void) G_GNUC_CONST;
+void e_book_config_mapi_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_BOOK_CONFIG_MAPI_H */
diff --git a/src/configuration/e-book-config-mapigal.c b/src/configuration/e-book-config-mapigal.c
new file mode 100644
index 0000000..fe7945c
--- /dev/null
+++ b/src/configuration/e-book-config-mapigal.c
@@ -0,0 +1,106 @@
+/*
+ * e-book-config-mapigal.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 <glib/gi18n-lib.h>
+
+#include <misc/e-book-source-config.h>
+
+#include "e-source-mapi-folder.h"
+#include "e-book-config-mapigal.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+ EBookConfigMapigal,
+ e_book_config_mapigal,
+ E_TYPE_SOURCE_CONFIG_BACKEND)
+
+static gboolean
+book_config_mapigal_allow_creation (ESourceConfigBackend *backend)
+{
+ return FALSE;
+}
+
+static void
+book_config_mapigal_insert_widgets (ESourceConfigBackend *backend,
+ ESource *scratch_source)
+{
+ ESourceBackend *backend_ext;
+ ESourceMapiFolder *folder_ext;
+ ESourceConfig *config;
+ GtkWidget *widget;
+
+ if (!e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
+ return;
+
+ backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+ if (!backend_ext || g_strcmp0 (e_source_backend_get_backend_name (backend_ext), "mapigal") != 0)
+ return;
+
+ folder_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ g_return_if_fail (folder_ext != NULL);
+
+ config = e_source_config_backend_get_config (backend);
+ e_book_source_config_add_offline_toggle (E_BOOK_SOURCE_CONFIG (config), scratch_source);
+
+ widget = gtk_check_button_new_with_mnemonic (_("Allow _partial search results"));
+ e_source_config_insert_widget (config, scratch_source, NULL, widget);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ folder_ext, "allow-partial",
+ widget, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+}
+
+static void
+e_book_config_mapigal_class_init (EBookConfigMapigalClass *class)
+{
+ EExtensionClass *extension_class;
+ ESourceConfigBackendClass *backend_class;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_BOOK_SOURCE_CONFIG;
+
+ backend_class = E_SOURCE_CONFIG_BACKEND_CLASS (class);
+ backend_class->backend_name = "mapigal";
+ backend_class->allow_creation = book_config_mapigal_allow_creation;
+ backend_class->insert_widgets = book_config_mapigal_insert_widgets;
+}
+
+static void
+e_book_config_mapigal_class_finalize (EBookConfigMapigalClass *class)
+{
+}
+
+static void
+e_book_config_mapigal_init (EBookConfigMapigal *backend)
+{
+}
+
+void
+e_book_config_mapigal_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_book_config_mapigal_register_type (type_module);
+}
diff --git a/src/configuration/e-book-config-mapigal.h b/src/configuration/e-book-config-mapigal.h
new file mode 100644
index 0000000..d1bad9c
--- /dev/null
+++ b/src/configuration/e-book-config-mapigal.h
@@ -0,0 +1,63 @@
+/*
+ * e-book-config-mapigal.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_BOOK_CONFIG_MAPIGAL_H
+#define E_BOOK_CONFIG_MAPIGAL_H
+
+#include <misc/e-source-config-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_CONFIG_MAPIGAL \
+ (e_book_config_mapigal_get_type ())
+#define E_BOOK_CONFIG_MAPIGAL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_BOOK_CONFIG_MAPIGAL, EBookConfigMapigal))
+#define E_BOOK_CONFIG_MAPIGAL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_BOOK_CONFIG_MAPIGAL, EBookConfigMapigalClass))
+#define E_IS_BOOK_CONFIG_MAPIGAL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_BOOK_CONFIG_MAPIGAL))
+#define E_IS_BOOK_CONFIG_MAPIGAL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_BOOK_CONFIG_MAPIGAL))
+#define E_BOOK_CONFIG_MAPIGAL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_BOOK_CONFIG_MAPIGAL, EBookConfigMapigalClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookConfigMapigal EBookConfigMapigal;
+typedef struct _EBookConfigMapigalClass EBookConfigMapigalClass;
+typedef struct _EBookConfigMapigalPrivate EBookConfigMapigalPrivate;
+
+struct _EBookConfigMapigal {
+ ESourceConfigBackend parent;
+ EBookConfigMapigalPrivate *priv;
+};
+
+struct _EBookConfigMapigalClass {
+ ESourceConfigBackendClass parent_class;
+};
+
+GType e_book_config_mapigal_get_type (void) G_GNUC_CONST;
+void e_book_config_mapigal_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_BOOK_CONFIG_MAPIGAL_H */
diff --git a/src/configuration/e-cal-config-mapi.c b/src/configuration/e-cal-config-mapi.c
new file mode 100644
index 0000000..b724c1f
--- /dev/null
+++ b/src/configuration/e-cal-config-mapi.c
@@ -0,0 +1,75 @@
+/*
+ * e-cal-config-mapi.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 <misc/e-cal-source-config.h>
+
+#include "e-cal-config-mapi.h"
+#include "e-mapi-config-utils.h"
+
+G_DEFINE_DYNAMIC_TYPE (ECalConfigMapi, e_cal_config_mapi, E_TYPE_SOURCE_CONFIG_BACKEND)
+
+static gboolean
+cal_config_mapi_allow_creation (ESourceConfigBackend *backend)
+{
+ return TRUE;
+}
+
+static void
+cal_config_mapi_insert_widgets (ESourceConfigBackend *backend,
+ ESource *scratch_source)
+{
+ e_mapi_config_utils_insert_widgets (backend, scratch_source);
+}
+
+static void
+e_cal_config_mapi_class_init (ECalConfigMapiClass *class)
+{
+ EExtensionClass *extension_class;
+ ESourceConfigBackendClass *backend_class;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_CAL_SOURCE_CONFIG;
+
+ backend_class = E_SOURCE_CONFIG_BACKEND_CLASS (class);
+ backend_class->backend_name = "mapi";
+ backend_class->allow_creation = cal_config_mapi_allow_creation;
+ backend_class->insert_widgets = cal_config_mapi_insert_widgets;
+}
+
+static void
+e_cal_config_mapi_class_finalize (ECalConfigMapiClass *class)
+{
+}
+
+static void
+e_cal_config_mapi_init (ECalConfigMapi *backend)
+{
+}
+
+void
+e_cal_config_mapi_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_cal_config_mapi_register_type (type_module);
+}
diff --git a/src/configuration/e-cal-config-mapi.h b/src/configuration/e-cal-config-mapi.h
new file mode 100644
index 0000000..af0ee5b
--- /dev/null
+++ b/src/configuration/e-cal-config-mapi.h
@@ -0,0 +1,63 @@
+/*
+ * e-cal-config-mapi.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_CAL_CONFIG_MAPI_H
+#define E_CAL_CONFIG_MAPI_H
+
+#include <misc/e-source-config-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_CONFIG_MAPI \
+ (e_cal_config_mapi_get_type ())
+#define E_CAL_CONFIG_MAPI(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_CONFIG_MAPI, ECalConfigMapi))
+#define E_CAL_CONFIG_MAPI_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_CONFIG_MAPI, ECalConfigMapiClass))
+#define E_IS_CAL_CONFIG_MAPI(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_CONFIG_MAPI))
+#define E_IS_CAL_CONFIG_MAPI_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_CONFIG_MAPI))
+#define E_CAL_CONFIG_MAPI_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_CONFIG_MAPI, ECalConfigMapiClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalConfigMapi ECalConfigMapi;
+typedef struct _ECalConfigMapiClass ECalConfigMapiClass;
+typedef struct _ECalConfigMapiPrivate ECalConfigMapiPrivate;
+
+struct _ECalConfigMapi {
+ ESourceConfigBackend parent;
+ ECalConfigMapiPrivate *priv;
+};
+
+struct _ECalConfigMapiClass {
+ ESourceConfigBackendClass parent_class;
+};
+
+GType e_cal_config_mapi_get_type (void) G_GNUC_CONST;
+void e_cal_config_mapi_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_CAL_CONFIG_MAPI_H */
diff --git a/src/configuration/e-mail-config-mapi-backend.c b/src/configuration/e-mail-config-mapi-backend.c
new file mode 100644
index 0000000..4f40e8e
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-backend.c
@@ -0,0 +1,841 @@
+/*
+ * e-mail-config-mapi-backend.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 <glib/gi18n-lib.h>
+
+#include <camel/camel.h>
+#include <libebackend/libebackend.h>
+#include <libedataserver/libedataserver.h>
+
+#include <e-util/e-dialog-utils.h>
+#include <mail/e-mail-config-auth-check.h>
+#include <mail/e-mail-config-receiving-page.h>
+#include <shell/e-shell.h>
+
+#include "camel-mapi-settings.h"
+#include "e-mapi-folder.h"
+#include "e-mapi-connection.h"
+#include "e-mapi-utils.h"
+#include "e-mapi-config-utils.h"
+
+#include "e-mail-config-mapi-backend.h"
+
+#define E_MAIL_CONFIG_MAPI_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackendPrivate))
+
+struct _EMailConfigMapiBackendPrivate {
+ gint unused;
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+ EMailConfigMapiBackend,
+ e_mail_config_mapi_backend,
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND)
+
+enum {
+ COL_MAPI_FULL_NAME = 0,
+ COL_MAPI_ACCOUNT,
+ COL_MAPI_INDEX,
+ COLS_MAX
+};
+
+static void
+tree_selection_changed (GtkTreeSelection *selection, GtkDialog *dialog)
+{
+ gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_ACCEPT, gtk_tree_selection_get_selected (selection, NULL, NULL));
+}
+
+static gboolean
+transform_security_method_to_boolean (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer not_used)
+{
+ CamelNetworkSecurityMethod security_method;
+ gboolean use_ssl;
+
+ security_method = g_value_get_enum (source_value);
+ use_ssl = (security_method != CAMEL_NETWORK_SECURITY_METHOD_NONE);
+ g_value_set_boolean (target_value, use_ssl);
+
+ return TRUE;
+}
+
+static gboolean
+transform_boolean_to_security_method (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer not_used)
+{
+ CamelNetworkSecurityMethod security_method;
+ gboolean use_ssl;
+
+ use_ssl = g_value_get_boolean (source_value);
+ if (use_ssl)
+ security_method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
+ else
+ security_method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
+ g_value_set_enum (target_value, security_method);
+
+ return TRUE;
+}
+
+struct ECreateProfileData
+{
+ const gchar *username;
+ struct SRowSet *rowset;
+ gint index;
+ EFlag *flag;
+};
+
+static gboolean
+create_profile_callback_in_main (gpointer user_data)
+{
+ struct ECreateProfileData *cpd = user_data;
+ gint response;
+ gint i, index = 0;
+ GtkTreeIter iter;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *selection;
+ GtkWidget *dialog, *view;
+ GtkBox *content_area;
+
+ g_return_val_if_fail (cpd != NULL, FALSE);
+
+ dialog = gtk_dialog_new_with_buttons (_("Select username"),
+ NULL, GTK_DIALOG_MODAL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ /*Tree View */
+ view = gtk_tree_view_new ();
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
+ -1, _("Full name"), renderer,
+ "text", COL_MAPI_FULL_NAME, NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
+ -1, _("Username"), renderer,
+ "text", COL_MAPI_ACCOUNT, NULL);
+
+ gtk_tree_view_column_set_resizable (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE);
+ gtk_tree_view_column_set_resizable (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 1), TRUE);
+
+ /* Model for TreeView */
+ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (store));
+
+ for (i = 0; i < cpd->rowset->cRows; i++) {
+ const gchar *fullname = e_mapi_util_find_row_propval (&(cpd->rowset->aRow[i]), PidTagDisplayName);
+ const gchar *account = e_mapi_util_find_row_propval (&(cpd->rowset->aRow[i]), PidTagAccount);
+
+ if (fullname && account) {
+ gtk_list_store_append (store, &iter);
+ /* Preserve the index inside the store*/
+ gtk_list_store_set (store, &iter,
+ COL_MAPI_FULL_NAME, fullname,
+ COL_MAPI_ACCOUNT, account,
+ COL_MAPI_INDEX, i, -1);
+ }
+ }
+
+ /* Pack the TreeView into dialog's content area */
+ content_area = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
+
+ gtk_box_pack_start (content_area, gtk_label_new (_("There are more users with similar user name on a server.\nPlease select that you would like to use from the below list.")), TRUE, TRUE, 6);
+ gtk_box_pack_start (content_area, view, TRUE, TRUE, 6);
+
+ gtk_widget_show_all (GTK_WIDGET (content_area));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ g_signal_connect (selection, "changed", G_CALLBACK (tree_selection_changed), dialog);
+ tree_selection_changed (selection, GTK_DIALOG (dialog));
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ if (response == GTK_RESPONSE_ACCEPT) {
+ /* Get the index from the selected value */
+ if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_MAPI_INDEX, &index, -1);
+ else
+ index = cpd->rowset->cRows + 1;
+ } else /* If we return a value > available, we are canceling the login.*/
+ index = cpd->rowset->cRows + 1;
+
+ gtk_widget_destroy (dialog);
+
+ cpd->index = index;
+ e_flag_set (cpd->flag);
+
+ return FALSE;
+}
+
+/* Callback for ProcessNetworkProfile. If we have more than one username,
+ we need to let the user select. */
+static gint
+create_profile_callback_in_thread (struct SRowSet *rowset,
+ gconstpointer data)
+{
+ struct ECreateProfileData cpd;
+ const gchar *username = (const gchar *) data;
+ gint i;
+
+ /* If we can find the exact username, then find & return its index. */
+ for (i = 0; i < rowset->cRows; i++) {
+ const gchar *account = e_mapi_util_find_row_propval (&(rowset->aRow[i]), PidTagAccount);
+
+ if (account && g_strcmp0 (username, account) == 0)
+ return i;
+ }
+
+ cpd.username = username;
+ cpd.rowset = rowset;
+ cpd.index = -1;
+ cpd.flag = e_flag_new ();
+
+ g_timeout_add (100, create_profile_callback_in_main, &cpd);
+
+ e_flag_wait (cpd.flag);
+ e_flag_free (cpd.flag);
+
+ return cpd.index;
+}
+
+static gboolean
+validate_credentials_test (ESourceRegistry *registry,
+ EMapiProfileData *empd,
+ CamelMapiSettings *mapi_settings,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ gboolean status, success = FALSE;
+ struct mapi_context *mapi_ctx = NULL;
+
+ status = e_mapi_utils_create_mapi_context (&mapi_ctx, perror);
+ status = status && e_mapi_create_profile (mapi_ctx, empd, create_profile_callback_in_thread, empd->username, NULL, perror);
+ if (status && !g_cancellable_is_cancelled (cancellable)) {
+ /* profile was created, try to connect to the server */
+ EMapiConnection *conn;
+ gchar *profname;
+
+ status = FALSE;
+ profname = e_mapi_util_profile_name (mapi_ctx, empd, FALSE);
+
+ conn = e_mapi_connection_new (registry, profname, empd->password, cancellable, perror);
+ if (conn) {
+ status = e_mapi_connection_connected (conn);
+ g_object_unref (conn);
+ }
+
+ g_free (profname);
+ }
+
+ if (status) {
+ /* Things are successful */
+ gchar *profname = NULL;
+
+ profname = e_mapi_util_profile_name (mapi_ctx, empd, FALSE);
+ camel_mapi_settings_set_profile (mapi_settings, profname);
+ g_free (profname);
+
+ success = TRUE;
+ }
+
+ e_mapi_utils_destroy_mapi_context (mapi_ctx);
+
+ return success;
+}
+
+typedef struct _EMailConfigMapiAuthenticator EMailConfigMapiAuthenticator;
+typedef struct _EMailConfigMapiAuthenticatorClass EMailConfigMapiAuthenticatorClass;
+
+struct _EMailConfigMapiAuthenticator {
+ GObject parent;
+
+ gchar *username;
+ gchar *domain;
+ gchar *server;
+ gboolean use_ssl;
+ gboolean krb_sso;
+ gchar *krb_realm;
+ CamelMapiSettings *mapi_settings;
+ EMailConfigServiceBackend *backend;
+ gboolean success;
+};
+
+struct _EMailConfigMapiAuthenticatorClass {
+ GObjectClass parent_class;
+};
+
+static ESourceAuthenticationResult
+mail_config_mapi_authenticator_try_password_sync (ESourceAuthenticator *auth,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EMailConfigMapiAuthenticator *mapi_authenticator = (EMailConfigMapiAuthenticator *) auth;
+ EMailConfigServicePage *page;
+ ESourceRegistry *registry;
+ EMapiProfileData empd;
+ GError *mapi_error = NULL;
+
+ empd.username = mapi_authenticator->username;
+ empd.domain = mapi_authenticator->domain;
+ empd.server = mapi_authenticator->server;
+ empd.password = (GString *) password;
+ empd.use_ssl = mapi_authenticator->use_ssl;
+ empd.krb_sso = mapi_authenticator->krb_sso;
+ empd.krb_realm = mapi_authenticator->krb_realm;
+
+ page = e_mail_config_service_backend_get_page (mapi_authenticator->backend);
+ registry = e_mail_config_service_page_get_registry (page);
+
+ mapi_authenticator->success = validate_credentials_test (
+ registry,
+ &empd,
+ mapi_authenticator->mapi_settings,
+ cancellable,
+ &mapi_error);
+
+ if (mapi_error) {
+ gboolean is_network_error = g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR);
+
+ g_warn_if_fail (!mapi_authenticator->success);
+ mapi_authenticator->success = FALSE;
+
+ g_propagate_error (error, mapi_error);
+
+ return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : E_SOURCE_AUTHENTICATION_REJECTED;
+ }
+
+ g_warn_if_fail (mapi_authenticator->success);
+
+ return E_SOURCE_AUTHENTICATION_ACCEPTED;
+}
+
+#define E_TYPE_MAIL_CONFIG_MAPI_AUTHENTICATOR (e_mail_config_mapi_authenticator_get_type ())
+
+GType e_mail_config_mapi_authenticator_get_type (void) G_GNUC_CONST;
+
+static void e_mail_config_mapi_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_EXTENDED (EMailConfigMapiAuthenticator, e_mail_config_mapi_authenticator, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_mail_config_mapi_authenticator_authenticator_init))
+
+static void
+mail_config_mapi_authenticator_finalize (GObject *object)
+{
+ EMailConfigMapiAuthenticator *mapi_authenticator = (EMailConfigMapiAuthenticator *) object;
+
+ g_free (mapi_authenticator->username);
+ g_free (mapi_authenticator->domain);
+ g_free (mapi_authenticator->server);
+ g_free (mapi_authenticator->krb_realm);
+ g_object_unref (mapi_authenticator->mapi_settings);
+ g_object_unref (mapi_authenticator->backend);
+
+ G_OBJECT_CLASS (e_mail_config_mapi_authenticator_parent_class)->finalize (object);
+}
+
+static void
+e_mail_config_mapi_authenticator_class_init (EMailConfigMapiAuthenticatorClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = mail_config_mapi_authenticator_finalize;
+}
+
+static void
+e_mail_config_mapi_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+ interface->try_password_sync = mail_config_mapi_authenticator_try_password_sync;
+}
+
+static void
+e_mail_config_mapi_authenticator_init (EMailConfigMapiAuthenticator *mapi_authenticator)
+{
+}
+
+static void
+validate_credentials_idle (GObject *button,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ EMailConfigMapiAuthenticator *mapi_authenticator = user_data;
+
+ g_return_if_fail (mapi_authenticator != NULL);
+
+ if (mapi_authenticator->success)
+ e_notice (NULL, GTK_MESSAGE_INFO, "%s", _("Authentication finished successfully."));
+ else
+ e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Authentication failed."));
+}
+
+static void
+validate_credentials_thread (GObject *button,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ EMailConfigMapiAuthenticator *mapi_authenticator = user_data;
+ EMailConfigServicePage *page;
+ ESourceRegistry *registry;
+
+ g_return_if_fail (mapi_authenticator != NULL);
+
+ page = e_mail_config_service_backend_get_page (mapi_authenticator->backend);
+ registry = e_mail_config_service_page_get_registry (page);
+
+ if (mapi_authenticator->krb_sso) {
+ GError *error = NULL;
+ EMapiProfileData empd;
+
+ empd.username = mapi_authenticator->username;
+ empd.domain = mapi_authenticator->domain;
+ empd.server = mapi_authenticator->server;
+ empd.use_ssl = mapi_authenticator->use_ssl;
+ empd.krb_sso = mapi_authenticator->krb_sso;
+ empd.krb_realm = mapi_authenticator->krb_realm;
+
+ e_mapi_util_trigger_krb_auth (&empd, &error);
+ g_clear_error (&error);
+
+ mapi_authenticator->success = validate_credentials_test (
+ registry,
+ &empd,
+ mapi_authenticator->mapi_settings,
+ cancellable,
+ perror);
+ } else {
+ ESource *source;
+
+ source = e_mail_config_service_backend_get_source (mapi_authenticator->backend);
+
+ e_source_registry_authenticate_sync (
+ registry, source, E_SOURCE_AUTHENTICATOR (mapi_authenticator),
+ cancellable, perror);
+ }
+}
+
+static void
+validate_credentials_cb (GtkWidget *widget,
+ EMailConfigServiceBackend *backend)
+{
+ EMapiProfileData empd = { 0 };
+ CamelSettings *settings;
+ CamelMapiSettings *mapi_settings;
+ CamelNetworkSettings *network_settings;
+ const gchar *host;
+ const gchar *user;
+ GError *error = NULL;
+
+ if (!e_mapi_config_utils_is_online ()) {
+ e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Cannot authenticate MAPI accounts in offline mode"));
+ return;
+ }
+
+ settings = e_mail_config_service_backend_get_settings (backend);
+ mapi_settings = CAMEL_MAPI_SETTINGS (settings);
+ network_settings = CAMEL_NETWORK_SETTINGS (settings);
+
+ host = camel_network_settings_get_host (network_settings);
+ user = camel_network_settings_get_user (network_settings);
+
+ /* Silently remove domain part from a username when user enters it as such.
+ This change will be visible in the UI on new edit open. */
+ if (user != NULL && strchr (user, '\\') != NULL) {
+ gchar *at;
+
+ at = strrchr (user, '\\') + 1;
+ camel_network_settings_set_user (network_settings, at);
+ user = camel_network_settings_get_user (network_settings);
+ }
+
+ empd.server = host;
+ empd.username = user;
+ e_mapi_util_profiledata_from_settings (&empd, mapi_settings);
+
+ if (!empd.username || !*(empd.username)
+ || !empd.server || !*(empd.server)
+ || ((!empd.domain || !*(empd.domain))
+ && !empd.krb_sso)) {
+ e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Server, username and domain name cannot be empty. Please fill them with correct values."));
+ return;
+ } else if (empd.krb_sso && (!empd.krb_realm || !*(empd.krb_realm))) {
+ e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Realm name cannot be empty when kerberos is selected. Please fill them with correct values."));
+ return;
+ }
+
+ if (COMPLETE_PROFILEDATA (&empd)) {
+ EMailConfigMapiAuthenticator *mapi_authenticator;
+
+ mapi_authenticator = g_object_new (E_TYPE_MAIL_CONFIG_MAPI_AUTHENTICATOR, NULL);
+
+ mapi_authenticator->username = g_strdup (empd.username);
+ mapi_authenticator->domain = g_strdup (empd.domain);
+ mapi_authenticator->server = g_strdup (empd.server);
+ mapi_authenticator->use_ssl = empd.use_ssl;
+ mapi_authenticator->krb_sso = empd.krb_sso;
+ mapi_authenticator->krb_realm = g_strdup (empd.krb_realm);
+ mapi_authenticator->mapi_settings = g_object_ref (mapi_settings);
+ mapi_authenticator->backend = g_object_ref (backend);
+ mapi_authenticator->success = FALSE;
+
+ e_mapi_config_utils_run_in_thread_with_feedback_modal (e_mapi_config_utils_get_widget_toplevel_window (widget),
+ G_OBJECT (widget),
+ _("Connecting to the server, please wait..."),
+ validate_credentials_thread,
+ validate_credentials_idle,
+ mapi_authenticator,
+ g_object_unref);
+ } else {
+ e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Authentication failed."));
+ }
+
+ if (error)
+ g_error_free (error);
+
+ if (empd.password) {
+ memset (empd.password->str, 0, empd.password->len);
+ g_string_free (empd.password, TRUE);
+ }
+}
+
+static ESource *
+mail_config_mapi_backend_new_collection (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServiceBackendClass *class;
+ ESourceBackend *extension;
+ ESource *source;
+ const gchar *extension_name;
+
+ /* This backend serves double duty. One instance holds the
+ * mail account source, another holds the mail transport source.
+ * We can differentiate by examining the EMailConfigServicePage
+ * the backend is associated with. We return a new collection
+ * for both the Receiving Page and Sending Page. Although the
+ * Sending Page instance ultimately gets discarded, it's still
+ * needed to avoid creating a [Mapi Backend] extension in the
+ * mail transport source. */
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+
+ source = e_source_new (NULL, NULL, NULL);
+ extension_name = E_SOURCE_EXTENSION_COLLECTION;
+ extension = e_source_get_extension (source, extension_name);
+ e_source_backend_set_backend_name (extension, class->backend_name);
+
+ return source;
+}
+
+static void
+mail_config_mapi_backend_insert_widgets (EMailConfigServiceBackend *backend,
+ GtkBox *parent)
+{
+ EMailConfigServicePage *page;
+ ESource *source;
+ ESourceExtension *extension;
+ CamelSettings *settings;
+ GtkWidget *hgrid = NULL;
+ GtkWidget *label, *entry;
+ GtkWidget *auth_button;
+ GtkWidget *secure_conn;
+ GtkWidget *krb_sso;
+ GtkGrid *content_grid;
+ gchar *markup;
+ gint irow;
+
+ page = e_mail_config_service_backend_get_page (backend);
+
+ /* This backend serves double duty. One instance holds the
+ * mail account source, another holds the mail transport source.
+ * We can differentiate by examining the EMailConfigServicePage
+ * the backend is associated with. This method only applies to
+ * the Receiving Page. */
+ if (!E_IS_MAIL_CONFIG_RECEIVING_PAGE (page))
+ return;
+
+ /* This needs to come _after_ the page type check so we don't
+ * introduce a backend extension in the mail transport source. */
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ content_grid = GTK_GRID (gtk_grid_new ());
+ gtk_widget_set_margin_left (GTK_WIDGET (content_grid), 12);
+ gtk_grid_set_row_spacing (content_grid, 6);
+ gtk_grid_set_column_spacing (content_grid, 6);
+ gtk_box_pack_start (GTK_BOX (parent), GTK_WIDGET (content_grid), FALSE, FALSE, 0);
+
+ irow = 0;
+
+ markup = g_markup_printf_escaped ("<b>%s</b>", _("Configuration"));
+ label = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ g_free (markup);
+
+ gtk_grid_attach (content_grid, label, 0, irow, 2, 1);
+ irow++;
+
+ label = gtk_label_new_with_mnemonic (_("_Server:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+ entry = gtk_entry_new ();
+ gtk_widget_set_hexpand (entry, TRUE);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+
+ g_object_bind_property (
+ settings, "host",
+ entry, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+ gtk_grid_attach (content_grid, entry, 1, irow, 1, 1);
+ irow++;
+
+ label = gtk_label_new_with_mnemonic (_("User_name:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+ entry = gtk_entry_new ();
+ gtk_widget_set_hexpand (entry, TRUE);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+
+ g_object_bind_property (
+ settings, "user",
+ entry, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+ gtk_grid_attach (content_grid, entry, 1, irow, 1, 1);
+ irow++;
+
+ /* Domain name & Authenticate Button */
+ hgrid = g_object_new (GTK_TYPE_GRID,
+ "column-homogeneous", FALSE,
+ "column-spacing", 6,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ NULL);
+ gtk_widget_set_hexpand (hgrid, TRUE);
+
+ label = gtk_label_new_with_mnemonic (_("_Domain name:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+ entry = gtk_entry_new ();
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+ gtk_widget_set_hexpand (entry, TRUE);
+ gtk_container_add (GTK_CONTAINER (hgrid), entry);
+ g_object_bind_property (
+ settings, "domain",
+ entry, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ auth_button = gtk_button_new_with_mnemonic (_("_Authenticate"));
+ gtk_container_add (GTK_CONTAINER (hgrid), auth_button);
+ g_signal_connect (auth_button, "clicked", G_CALLBACK (validate_credentials_cb), backend);
+
+ gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+ gtk_grid_attach (content_grid, hgrid, 1, irow, 1, 1);
+ irow++;
+
+ secure_conn = gtk_check_button_new_with_mnemonic (_("_Use secure connection"));
+ gtk_widget_set_hexpand (secure_conn, TRUE);
+
+ gtk_grid_attach (content_grid, secure_conn, 1, irow, 1, 1);
+ irow++;
+
+ g_object_bind_property_full (
+ settings, "security-method",
+ secure_conn, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE,
+ transform_security_method_to_boolean,
+ transform_boolean_to_security_method,
+ NULL, (GDestroyNotify) NULL);
+
+ krb_sso = gtk_check_button_new_with_mnemonic (_("_Kerberos authentication"));
+ gtk_widget_set_hexpand (secure_conn, TRUE);
+
+ g_object_bind_property (
+ settings, "kerberos",
+ krb_sso, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ gtk_grid_attach (content_grid, krb_sso, 1, irow, 1, 1);
+ irow++;
+
+ label = gtk_label_new_with_mnemonic (_("_Realm name:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+ g_object_bind_property (
+ settings, "kerberos",
+ label, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ entry = gtk_entry_new ();
+ gtk_widget_set_hexpand (entry, TRUE);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+
+ g_object_bind_property (
+ settings, "realm",
+ entry, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ settings, "kerberos",
+ entry, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+ gtk_grid_attach (content_grid, entry, 1, irow, 1, 1);
+
+ source = e_mail_config_service_backend_get_collection (backend);
+ extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION);
+
+ /* The collection identity is the user name. */
+ g_object_bind_property (
+ settings, "user",
+ extension, "identity",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ gtk_widget_show_all (GTK_WIDGET (content_grid));
+}
+
+static void
+mail_config_mapi_backend_setup_defaults (EMailConfigServiceBackend *backend)
+{
+ CamelSettings *settings;
+ EMailConfigServicePage *page;
+ const gchar *email_address;
+ gchar **parts = NULL;
+
+ page = e_mail_config_service_backend_get_page (backend);
+
+ /* This backend serves double duty. One instance holds the
+ * mail account source, another holds the mail transport source.
+ * We can differentiate by examining the EMailConfigServicePage
+ * the backend is associated with. This method only applies to
+ * the Receiving Page. */
+ if (!E_IS_MAIL_CONFIG_RECEIVING_PAGE (page))
+ return;
+
+ /* This needs to come _after_ the page type check so we don't
+ * introduce a backend extension in the mail transport source. */
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ email_address = e_mail_config_service_page_get_email_address (page);
+ if (email_address != NULL)
+ parts = g_strsplit (email_address, "@", 2);
+
+ if (parts != NULL && g_strv_length (parts) >= 2) {
+ CamelNetworkSettings *network_settings;
+ gchar *host;
+
+ g_strstrip (parts[0]); /* user name */
+ g_strstrip (parts[1]); /* domain name */
+
+ host = g_strdup_printf ("exchange.%s", parts[1]);
+
+ network_settings = CAMEL_NETWORK_SETTINGS (settings);
+ camel_network_settings_set_host (network_settings, host);
+ camel_network_settings_set_user (network_settings, parts[0]);
+
+ g_free (host);
+ }
+
+ g_strfreev (parts);
+}
+
+static gboolean
+mail_config_mapi_backend_check_complete (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServicePage *page;
+ CamelSettings *settings;
+ CamelMapiSettings *mapi_settings;
+ const gchar *profile;
+
+ page = e_mail_config_service_backend_get_page (backend);
+
+ /* This backend serves double duty. One instance holds the
+ * mail account source, another holds the mail transport source.
+ * We can differentiate by examining the EMailConfigServicePage
+ * the backend is associated with. This method only applies to
+ * the Receiving Page. */
+ if (!E_IS_MAIL_CONFIG_RECEIVING_PAGE (page))
+ return TRUE;
+
+ /* This needs to come _after_ the page type check so we don't
+ * introduce a backend extension in the mail transport source. */
+ settings = e_mail_config_service_backend_get_settings (backend);
+ mapi_settings = CAMEL_MAPI_SETTINGS (settings);
+
+ /* We assume that if the profile is set, then the setting is valid. */
+ profile = camel_mapi_settings_get_profile (mapi_settings);
+
+ /* Profile not set. Do not proceed with account creation.*/
+ return (profile != NULL && *profile != '\0');
+}
+
+static void
+e_mail_config_mapi_backend_class_init (EMailConfigMapiBackendClass *class)
+{
+ EMailConfigServiceBackendClass *backend_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigMapiBackendPrivate));
+
+ backend_class = E_MAIL_CONFIG_SERVICE_BACKEND_CLASS (class);
+ backend_class->backend_name = "mapi";
+ backend_class->new_collection = mail_config_mapi_backend_new_collection;
+ backend_class->insert_widgets = mail_config_mapi_backend_insert_widgets;
+ backend_class->setup_defaults = mail_config_mapi_backend_setup_defaults;
+ backend_class->check_complete = mail_config_mapi_backend_check_complete;
+}
+
+static void
+e_mail_config_mapi_backend_class_finalize (EMailConfigMapiBackendClass *class)
+{
+}
+
+static void
+e_mail_config_mapi_backend_init (EMailConfigMapiBackend *backend)
+{
+ backend->priv = E_MAIL_CONFIG_MAPI_BACKEND_GET_PRIVATE (backend);
+}
+
+void
+e_mail_config_mapi_backend_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_mail_config_mapi_backend_register_type (type_module);
+}
diff --git a/src/configuration/e-mail-config-mapi-backend.h b/src/configuration/e-mail-config-mapi-backend.h
new file mode 100644
index 0000000..feb16a1
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-backend.h
@@ -0,0 +1,63 @@
+/*
+ * e-mail-config-mapi-backend.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_CONFIG_MAPI_BACKEND_H
+#define E_MAIL_CONFIG_MAPI_BACKEND_H
+
+#include <mail/e-mail-config-service-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_MAPI_BACKEND \
+ (e_mail_config_mapi_backend_get_type ())
+#define E_MAIL_CONFIG_MAPI_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackend))
+#define E_MAIL_CONFIG_MAPI_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackendClass))
+#define E_IS_MAIL_CONFIG_MAPI_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND))
+#define E_IS_MAIL_CONFIG_MAPI_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_MAPI_BACKEND))
+#define E_MAIL_CONFIG_MAPI_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigMapiBackend EMailConfigMapiBackend;
+typedef struct _EMailConfigMapiBackendClass EMailConfigMapiBackendClass;
+typedef struct _EMailConfigMapiBackendPrivate EMailConfigMapiBackendPrivate;
+
+struct _EMailConfigMapiBackend {
+ EMailConfigServiceBackend parent;
+ EMailConfigMapiBackendPrivate *priv;
+};
+
+struct _EMailConfigMapiBackendClass {
+ EMailConfigServiceBackendClass parent_class;
+};
+
+GType e_mail_config_mapi_backend_get_type (void) G_GNUC_CONST;
+void e_mail_config_mapi_backend_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_MAPI_BACKEND_H */
diff --git a/src/configuration/e-mail-config-mapi-extension.c b/src/configuration/e-mail-config-mapi-extension.c
new file mode 100644
index 0000000..186d685
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-extension.c
@@ -0,0 +1,121 @@
+/*
+ * e-mail-config-mapi-extension.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 <mail/e-mail-config-notebook.h>
+
+#include "e-mail-config-mapi-page.h"
+#include "camel-mapi-settings.h"
+
+#include "e-mail-config-mapi-extension.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+ EMailConfigMapiExtension,
+ e_mail_config_mapi_extension,
+ E_TYPE_EXTENSION)
+
+static void
+e_mail_config_mapi_extension_constructed (GObject *object)
+{
+ EExtension *extension;
+ EExtensible *extensible;
+ ESource *source;
+ ESourceBackend *backend_ext;
+ EMailConfigNotebook *notebook;
+ const gchar *backend_name;
+ const gchar *extension_name;
+
+ extension = E_EXTENSION (object);
+ extensible = e_extension_get_extensible (extension);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_mapi_extension_parent_class)->constructed (object);
+
+ notebook = E_MAIL_CONFIG_NOTEBOOK (extensible);
+ source = e_mail_config_notebook_get_account_source (notebook);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ backend_ext = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (backend_ext);
+
+ if (g_strcmp0 (backend_name, "mapi") == 0) {
+ ESource *profile_source;
+ ESourceCamel *camel_ext;
+ ESourceRegistry *registry;
+ EMailSession *mail_session;
+ CamelSettings *settings;
+ const gchar *profile;
+
+ mail_session = e_mail_config_notebook_get_session (notebook);
+ registry = e_mail_session_get_registry (mail_session);
+
+ if (e_source_get_parent (source))
+ profile_source = e_source_registry_ref_source (registry, e_source_get_parent (source));
+ else
+ profile_source = g_object_ref (source);
+
+ camel_ext = e_source_get_extension (profile_source, e_source_camel_get_extension_name (backend_name));
+ settings = e_source_camel_get_settings (camel_ext);
+ profile = camel_mapi_settings_get_profile (CAMEL_MAPI_SETTINGS (settings));
+
+ /* add page only when editing already configured accounts */
+ if (profile && *profile) {
+ EMailConfigPage *page;
+
+ page = e_mail_config_mapi_page_new (source, registry);
+ e_mail_config_notebook_add_page (notebook, page);
+ }
+
+ g_object_unref (profile_source);
+ }
+}
+
+static void
+e_mail_config_mapi_extension_class_init (EMailConfigMapiExtensionClass *class)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = e_mail_config_mapi_extension_constructed;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_MAIL_CONFIG_NOTEBOOK;
+}
+
+static void
+e_mail_config_mapi_extension_class_finalize (EMailConfigMapiExtensionClass *class)
+{
+}
+
+static void
+e_mail_config_mapi_extension_init (EMailConfigMapiExtension *extension)
+{
+}
+
+void
+e_mail_config_mapi_extension_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_mail_config_mapi_extension_register_type (type_module);
+}
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/configuration/e-mail-config-mapi-extension.h
similarity index 58%
copy from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
copy to src/configuration/e-mail-config-mapi-extension.h
index debf5b5..4981f4d 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
+++ b/src/configuration/e-mail-config-mapi-extension.h
@@ -1,5 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ * e-mail-config-mapi-extension.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
@@ -13,22 +14,21 @@
* 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:
- * Milan Crha <mcrha redhat com>
- *
- * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
- *
*/
-#ifndef E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
-#define E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
+#ifndef E_MAIL_CONFIG_MAPI_EXTENSION_H
+#define E_MAIL_CONFIG_MAPI_EXTENSION_H
+
+#include <libebackend/libebackend.h>
+
+G_BEGIN_DECLS
+
+typedef EExtension EMailConfigMapiExtension;
+typedef EExtensionClass EMailConfigMapiExtensionClass;
-#include <gtk/gtk.h>
-#include <camel/camel.h>
+GType e_mail_config_mapi_extension_get_type (void);
+void e_mail_config_mapi_extension_type_register (GTypeModule *type_module);
-void e_mapi_subscribe_foreign_folder (GtkWindow *parent,
- CamelSession *session,
- CamelStore *store);
+G_END_DECLS
-#endif /* E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H */
+#endif /* E_MAIL_CONFIG_MAPI_EXTENSION_H */
diff --git a/src/configuration/e-mail-config-mapi-page.c b/src/configuration/e-mail-config-mapi-page.c
new file mode 100644
index 0000000..408d0b3
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-page.c
@@ -0,0 +1,296 @@
+/*
+ * e-mail-config-mapi-page.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 <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-security-page.h>
+
+#include "e-mapi-config-utils.h"
+
+#include "e-mail-config-mapi-page.h"
+
+#define E_MAIL_CONFIG_MAPI_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPagePrivate))
+
+#define E_MAIL_CONFIG_MAPI_PAGE_SORT_ORDER \
+ (E_MAIL_CONFIG_SECURITY_PAGE_SORT_ORDER + 10)
+
+struct _EMailConfigMapiPagePrivate {
+ ESource *account_source;
+ ESourceRegistry *registry;
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_SOURCE,
+ PROP_SOURCE_REGISTRY
+};
+
+static void e_mail_config_mapi_page_interface_init (EMailConfigPageInterface *interface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (EMailConfigMapiPage, e_mail_config_mapi_page, GTK_TYPE_BOX, 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (E_TYPE_MAIL_CONFIG_PAGE, e_mail_config_mapi_page_interface_init))
+
+static void
+folder_size_clicked_cb (GtkWidget *button,
+ EMailConfigMapiPage *page)
+{
+ ESource *source, *setting_source;
+ ESourceCamel *camel_ext;
+ ESourceRegistry *registry;
+ CamelSettings *settings;
+
+ g_return_if_fail (page != NULL);
+
+ source = e_mail_config_mapi_page_get_account_source (page);
+ registry = e_mail_config_mapi_page_get_source_registry (page);
+
+ if (e_source_get_parent (source))
+ setting_source = e_source_registry_ref_source (registry, e_source_get_parent (source));
+ else
+ setting_source = g_object_ref (source);
+
+ camel_ext = e_source_get_extension (setting_source, e_source_camel_get_extension_name ("mapi"));
+ settings = e_source_camel_get_settings (camel_ext);
+
+ e_mapi_config_utils_run_folder_size_dialog (registry, source, CAMEL_MAPI_SETTINGS (settings));
+
+ g_object_unref (setting_source);
+}
+
+static void
+mail_config_mapi_page_set_account_source (EMailConfigMapiPage *page,
+ ESource *account_source)
+{
+ g_return_if_fail (E_IS_SOURCE (account_source));
+ g_return_if_fail (page->priv->account_source == NULL);
+
+ page->priv->account_source = g_object_ref (account_source);
+}
+
+static void
+mail_config_mapi_page_set_source_registry (EMailConfigMapiPage *page,
+ ESourceRegistry *registry)
+{
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (page->priv->registry == NULL);
+
+ page->priv->registry = g_object_ref (registry);
+}
+
+static void
+mail_config_mapi_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_SOURCE:
+ mail_config_mapi_page_set_account_source (
+ E_MAIL_CONFIG_MAPI_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SOURCE_REGISTRY:
+ mail_config_mapi_page_set_source_registry (
+ E_MAIL_CONFIG_MAPI_PAGE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_mapi_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_mapi_page_get_account_source (
+ E_MAIL_CONFIG_MAPI_PAGE (object)));
+ return;
+
+ case PROP_SOURCE_REGISTRY:
+ g_value_set_object (
+ value,
+ e_mail_config_mapi_page_get_source_registry (
+ E_MAIL_CONFIG_MAPI_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_mapi_page_dispose (GObject *object)
+{
+ EMailConfigMapiPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_MAPI_PAGE_GET_PRIVATE (object);
+
+ if (priv->account_source != NULL) {
+ g_object_unref (priv->account_source);
+ priv->account_source = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_mapi_page_parent_class)->dispose (object);
+}
+
+static void
+mail_config_mapi_page_constructed (GObject *object)
+{
+ EMailConfigMapiPage *page = E_MAIL_CONFIG_MAPI_PAGE (object);
+ GtkWidget *widget;
+ GtkGrid *content_grid;
+ gchar *markup;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_mapi_page_parent_class)->constructed (object);
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ content_grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_spacing (content_grid, 6);
+ gtk_grid_set_column_spacing (content_grid, 6);
+ gtk_box_pack_start (GTK_BOX (page), GTK_WIDGET (content_grid), FALSE, FALSE, 0);
+
+ markup = g_markup_printf_escaped ("<b>%s</b>", _("MAPI Settings"));
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (content_grid, widget, 0, 0, 2, 1);
+
+ widget = gtk_label_new (_("View the size of all Exchange folders"));
+ gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
+ gtk_grid_attach (content_grid, widget, 0, 1, 1, 1);
+
+ widget = gtk_button_new_with_mnemonic (_("Folder _Size"));
+ g_signal_connect (widget, "clicked", G_CALLBACK (folder_size_clicked_cb), page);
+ gtk_grid_attach (content_grid, widget, 1, 1, 1, 1);
+
+ gtk_widget_show_all (GTK_WIDGET (page));
+}
+
+static void
+e_mail_config_mapi_page_class_init (EMailConfigMapiPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigMapiPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_mapi_page_set_property;
+ object_class->get_property = mail_config_mapi_page_get_property;
+ object_class->dispose = mail_config_mapi_page_dispose;
+ object_class->constructed = mail_config_mapi_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_SOURCE,
+ g_param_spec_object (
+ "account-source",
+ "Account Source",
+ "Mail account source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE_REGISTRY,
+ g_param_spec_object (
+ "source-registry",
+ "Source Registry",
+ NULL,
+ E_TYPE_SOURCE_REGISTRY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+e_mail_config_mapi_page_class_finalize (EMailConfigMapiPageClass *class)
+{
+}
+
+static void
+e_mail_config_mapi_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("MAPI Settings");
+ interface->sort_order = E_MAIL_CONFIG_MAPI_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_mapi_page_init (EMailConfigMapiPage *page)
+{
+ page->priv = E_MAIL_CONFIG_MAPI_PAGE_GET_PRIVATE (page);
+}
+
+void
+e_mail_config_mapi_page_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_mail_config_mapi_page_register_type (type_module);
+}
+
+EMailConfigPage *
+e_mail_config_mapi_page_new (ESource *account_source,
+ ESourceRegistry *registry)
+{
+ EMailConfigPage *page;
+
+ g_return_val_if_fail (E_IS_SOURCE (account_source), NULL);
+
+ page = g_object_new (E_TYPE_MAIL_CONFIG_MAPI_PAGE,
+ "account-source", account_source,
+ "source-registry", registry,
+ NULL);
+
+ return page;
+}
+
+ESource *
+e_mail_config_mapi_page_get_account_source (EMailConfigMapiPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_MAPI_PAGE (page), NULL);
+
+ return page->priv->account_source;
+}
+
+ESourceRegistry *
+e_mail_config_mapi_page_get_source_registry (EMailConfigMapiPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_MAPI_PAGE (page), NULL);
+
+ return page->priv->registry;
+}
diff --git a/src/configuration/e-mail-config-mapi-page.h b/src/configuration/e-mail-config-mapi-page.h
new file mode 100644
index 0000000..6098d82
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-page.h
@@ -0,0 +1,71 @@
+/*
+ * e-mail-config-mapi-page.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_CONFIG_MAPI_PAGE_H
+#define E_MAIL_CONFIG_MAPI_PAGE_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/libedataserver.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_MAPI_PAGE \
+ (e_mail_config_mapi_page_get_type ())
+#define E_MAIL_CONFIG_MAPI_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPage))
+#define E_MAIL_CONFIG_MAPI_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPageClass))
+#define E_IS_MAIL_CONFIG_MAPI_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE))
+#define E_IS_MAIL_CONFIG_MAPI_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_MAPI_PAGE))
+#define E_MAIL_CONFIG_MAPI_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPage))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigMapiPage EMailConfigMapiPage;
+typedef struct _EMailConfigMapiPageClass EMailConfigMapiPageClass;
+typedef struct _EMailConfigMapiPagePrivate EMailConfigMapiPagePrivate;
+
+struct _EMailConfigMapiPage {
+ GtkBox parent;
+ EMailConfigMapiPagePrivate *priv;
+};
+
+struct _EMailConfigMapiPageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_mapi_page_get_type (void) G_GNUC_CONST;
+void e_mail_config_mapi_page_type_register (GTypeModule *type_module);
+EMailConfigPage * e_mail_config_mapi_page_new (ESource *account_source,
+ ESourceRegistry *registry);
+
+ESource * e_mail_config_mapi_page_get_account_source (EMailConfigMapiPage *page);
+ESourceRegistry * e_mail_config_mapi_page_get_source_registry (EMailConfigMapiPage *page);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_MAPI_PAGE_H */
diff --git a/src/configuration/e-mapi-config-ui-extension.c b/src/configuration/e-mapi-config-ui-extension.c
new file mode 100644
index 0000000..cdaf2ac
--- /dev/null
+++ b/src/configuration/e-mapi-config-ui-extension.c
@@ -0,0 +1,154 @@
+/*
+ * e-mapi-config-ui-extension.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 <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <shell/e-shell-view.h>
+
+#include "e-mapi-config-utils.h"
+
+#include "e-mapi-config-ui-extension.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+ EMapiConfigUIExtension,
+ e_mapi_config_ui_extension,
+ E_TYPE_EXTENSION)
+
+static void
+e_mapi_config_ui_extension_shell_view_toggled_cb (EShellView *shell_view,
+ EMapiConfigUIExtension *ui_ext)
+{
+ EShellViewClass *shell_view_class;
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+ gpointer key = NULL, value = NULL;
+ const gchar *ui_def;
+ gboolean is_active, need_update;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+ g_return_if_fail (ui_ext != NULL);
+
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ g_return_if_fail (shell_view_class != NULL);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ need_update = ui_ext->current_ui_id != 0;
+ if (ui_ext->current_ui_id) {
+ gtk_ui_manager_remove_ui (ui_manager, ui_ext->current_ui_id);
+ ui_ext->current_ui_id = 0;
+ }
+
+ is_active = e_shell_view_is_active (shell_view);
+ if (!is_active) {
+ if (need_update)
+ gtk_ui_manager_ensure_update (ui_manager);
+
+ return;
+ }
+
+ if (!g_hash_table_lookup_extended (ui_ext->ui_definitions, shell_view_class->ui_manager_id, &key, &value)) {
+ gchar *ui_definition = NULL;
+
+ e_mapi_config_utils_init_ui (shell_view, shell_view_class->ui_manager_id, &ui_definition);
+ g_hash_table_insert (ui_ext->ui_definitions, g_strdup (shell_view_class->ui_manager_id), ui_definition);
+ }
+
+ ui_def = g_hash_table_lookup (ui_ext->ui_definitions, shell_view_class->ui_manager_id);
+ if (ui_def) {
+ GError *error = NULL;
+
+ ui_ext->current_ui_id = gtk_ui_manager_add_ui_from_string (ui_manager, ui_def, -1, &error);
+ need_update = TRUE;
+
+ if (error) {
+ g_warning ("%s: Failed to add ui definition: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ }
+
+ if (need_update)
+ gtk_ui_manager_ensure_update (ui_manager);
+}
+
+static void
+e_mapi_config_ui_extension_constructed (GObject *object)
+{
+ EExtension *extension;
+ EExtensible *extensible;
+
+ extension = E_EXTENSION (object);
+ extensible = e_extension_get_extensible (extension);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mapi_config_ui_extension_parent_class)->constructed (object);
+
+ g_signal_connect (E_SHELL_VIEW (extensible), "toggled", G_CALLBACK (e_mapi_config_ui_extension_shell_view_toggled_cb), extension);
+}
+
+static void
+e_mapi_config_ui_extension_finalize (GObject *object)
+{
+ EMapiConfigUIExtension *ui_ext = (EMapiConfigUIExtension *) object;
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mapi_config_ui_extension_parent_class)->finalize (object);
+
+ g_hash_table_destroy (ui_ext->ui_definitions);
+}
+
+static void
+e_mapi_config_ui_extension_class_init (EMapiConfigUIExtensionClass *class)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = e_mapi_config_ui_extension_constructed;
+ object_class->finalize = e_mapi_config_ui_extension_finalize;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_SHELL_VIEW;
+}
+
+static void
+e_mapi_config_ui_extension_class_finalize (EMapiConfigUIExtensionClass *class)
+{
+}
+
+static void
+e_mapi_config_ui_extension_init (EMapiConfigUIExtension *extension)
+{
+ extension->current_ui_id = 0;
+ extension->ui_definitions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+}
+
+void
+e_mapi_config_ui_extension_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_mapi_config_ui_extension_register_type (type_module);
+}
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/configuration/e-mapi-config-ui-extension.h
similarity index 50%
copy from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
copy to src/configuration/e-mapi-config-ui-extension.h
index debf5b5..d7b999d 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
+++ b/src/configuration/e-mapi-config-ui-extension.h
@@ -1,5 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ * e-mapi-config-ui-extension.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
@@ -13,22 +14,34 @@
* 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:
- * Milan Crha <mcrha redhat com>
- *
- * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
- *
*/
-#ifndef E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
-#define E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
+#ifndef E_MAPI_CONFIG_UI_EXTENSION_H
+#define E_MAPI_CONFIG_UI_EXTENSION_H
+
+#include <libebackend/libebackend.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EMapiConfigUIExtension EMapiConfigUIExtension;
+typedef struct _EMapiConfigUIExtensionClass EMapiConfigUIExtensionClass;
+
+struct _EMapiConfigUIExtension
+{
+ EExtension parent;
+
+ guint current_ui_id;
+ GHashTable *ui_definitions;
+};
+
+struct _EMapiConfigUIExtensionClass
+{
+ EExtensionClass parent;
+};
-#include <gtk/gtk.h>
-#include <camel/camel.h>
+GType e_mapi_config_ui_extension_get_type (void);
+void e_mapi_config_ui_extension_type_register (GTypeModule *type_module);
-void e_mapi_subscribe_foreign_folder (GtkWindow *parent,
- CamelSession *session,
- CamelStore *store);
+G_END_DECLS
-#endif /* E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H */
+#endif /* E_MAPI_CONFIG_UI_EXTENSION_H */
diff --git a/src/configuration/e-mapi-config-utils.c b/src/configuration/e-mapi-config-utils.c
new file mode 100644
index 0000000..69ce568
--- /dev/null
+++ b/src/configuration/e-mapi-config-utils.c
@@ -0,0 +1,1698 @@
+/*
+ * e-mapi-config-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 <string.h>
+#include <unistd.h>
+#include <glib/gi18n-lib.h>
+
+#include <gtk/gtk.h>
+#include <libedataserver/libedataserver.h>
+#include <libedataserverui/libedataserverui.h>
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-util.h>
+#include <mail/em-folder-tree.h>
+#include <misc/e-book-source-config.h>
+#include <misc/e-cal-source-config.h>
+#include <shell/e-shell.h>
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+#include <shell/e-shell-window.h>
+
+#include "e-mapi-folder.h"
+#include "e-mapi-connection.h"
+#include "e-mapi-utils.h"
+#include "e-source-mapi-folder.h"
+
+#include "e-mapi-subscribe-foreign-folder.h"
+#include "e-mapi-edit-folder-permissions.h"
+
+#include "camel/camel-mapi-store.h"
+#include "camel/camel-mapi-store-summary.h"
+
+#include "e-mapi-config-utils.h"
+
+struct RunWithFeedbackData
+{
+ GtkWindow *parent;
+ GtkWidget *dialog;
+ GCancellable *cancellable;
+ GObject *with_object;
+ EMapiSetupFunc thread_func;
+ EMapiSetupFunc idle_func;
+ gpointer user_data;
+ GDestroyNotify free_user_data;
+ GError *error;
+ gboolean run_modal;
+};
+
+static void
+free_run_with_feedback_data (gpointer ptr)
+{
+ struct RunWithFeedbackData *rfd = ptr;
+
+ if (!rfd)
+ return;
+
+ if (rfd->dialog)
+ gtk_widget_destroy (rfd->dialog);
+
+ g_object_unref (rfd->cancellable);
+ g_object_unref (rfd->with_object);
+
+ if (rfd->free_user_data)
+ rfd->free_user_data (rfd->user_data);
+
+ g_clear_error (&rfd->error);
+
+ g_free (rfd);
+}
+
+static gboolean
+run_with_feedback_idle (gpointer user_data)
+{
+ struct RunWithFeedbackData *rfd = user_data;
+ gboolean was_cancelled = FALSE;
+
+ g_return_val_if_fail (rfd != NULL, FALSE);
+
+ if (!g_cancellable_is_cancelled (rfd->cancellable)) {
+ if (rfd->idle_func && !rfd->error)
+ rfd->idle_func (rfd->with_object, rfd->user_data, rfd->cancellable, &rfd->error);
+
+ was_cancelled = g_cancellable_is_cancelled (rfd->cancellable);
+
+ if (rfd->dialog) {
+ gtk_widget_destroy (rfd->dialog);
+ rfd->dialog = NULL;
+ }
+ } else {
+ was_cancelled = TRUE;
+ }
+
+ if (!was_cancelled) {
+ if (rfd->error)
+ e_notice (rfd->parent, GTK_MESSAGE_ERROR, "%s", rfd->error->message);
+ }
+
+ free_run_with_feedback_data (rfd);
+
+ return FALSE;
+}
+
+static gpointer
+run_with_feedback_thread (gpointer user_data)
+{
+ struct RunWithFeedbackData *rfd = user_data;
+
+ g_return_val_if_fail (rfd != NULL, NULL);
+ g_return_val_if_fail (rfd->thread_func != NULL, NULL);
+
+ if (!g_cancellable_is_cancelled (rfd->cancellable))
+ rfd->thread_func (rfd->with_object, rfd->user_data, rfd->cancellable, &rfd->error);
+
+ g_idle_add (run_with_feedback_idle, rfd);
+
+ return NULL;
+}
+
+static void
+run_with_feedback_response_cb (GtkWidget *dialog,
+ gint resonse_id,
+ struct RunWithFeedbackData *rfd)
+{
+ g_return_if_fail (rfd != NULL);
+
+ rfd->dialog = NULL;
+
+ g_cancellable_cancel (rfd->cancellable);
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+e_mapi_config_utils_run_in_thread_with_feedback_general (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EMapiSetupFunc thread_func,
+ EMapiSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data,
+ gboolean run_modal)
+{
+ GtkWidget *dialog, *label, *content;
+ struct RunWithFeedbackData *rfd;
+
+ g_return_if_fail (with_object != NULL);
+ g_return_if_fail (description != NULL);
+ g_return_if_fail (thread_func != NULL);
+
+ dialog = gtk_dialog_new_with_buttons ("",
+ parent,
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ NULL);
+
+ label = gtk_label_new (description);
+ gtk_widget_show (label);
+
+ content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ gtk_container_add (GTK_CONTAINER (content), label);
+ gtk_container_set_border_width (GTK_CONTAINER (content), 12);
+
+ rfd = g_new0 (struct RunWithFeedbackData, 1);
+ rfd->parent = parent;
+ rfd->dialog = dialog;
+ rfd->cancellable = g_cancellable_new ();
+ rfd->with_object = g_object_ref (with_object);
+ rfd->thread_func = thread_func;
+ rfd->idle_func = idle_func;
+ rfd->user_data = user_data;
+ rfd->free_user_data = free_user_data;
+ rfd->error = NULL;
+ rfd->run_modal = run_modal;
+
+ g_signal_connect (dialog, "response", G_CALLBACK (run_with_feedback_response_cb), rfd);
+
+ if (run_modal) {
+ GCancellable *cancellable;
+
+ cancellable = g_object_ref (rfd->cancellable);
+
+ g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ g_cancellable_cancel (cancellable);
+ g_object_unref (cancellable);
+ } else {
+ gtk_widget_show (dialog);
+
+ g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+ }
+}
+
+void
+e_mapi_config_utils_run_in_thread_with_feedback (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EMapiSetupFunc thread_func,
+ EMapiSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data)
+{
+ e_mapi_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, FALSE);
+}
+
+void
+e_mapi_config_utils_run_in_thread_with_feedback_modal (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EMapiSetupFunc thread_func,
+ EMapiSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data)
+{
+ e_mapi_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, TRUE);
+}
+
+typedef struct _EMapiConfigUtilsAuthenticator EMapiConfigUtilsAuthenticator;
+typedef struct _EMapiConfigUtilsAuthenticatorClass EMapiConfigUtilsAuthenticatorClass;
+
+struct _EMapiConfigUtilsAuthenticator {
+ GObject parent;
+
+ ESourceRegistry *registry;
+ CamelMapiSettings *mapi_settings;
+ EMapiConnection *conn;
+};
+
+struct _EMapiConfigUtilsAuthenticatorClass {
+ GObjectClass parent_class;
+};
+
+static ESourceAuthenticationResult
+mapi_config_utils_authenticator_try_password_sync (ESourceAuthenticator *auth,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EMapiConfigUtilsAuthenticator *authenticator = (EMapiConfigUtilsAuthenticator *) auth;
+ EMapiProfileData empd;
+ CamelNetworkSettings *network_settings;
+ GError *mapi_error = NULL;
+
+ network_settings = CAMEL_NETWORK_SETTINGS (authenticator->mapi_settings);
+
+ empd.server = camel_network_settings_get_host (network_settings);
+ empd.username = camel_network_settings_get_user (network_settings);
+ e_mapi_util_profiledata_from_settings (&empd, authenticator->mapi_settings);
+
+ authenticator->conn = e_mapi_connection_new (
+ authenticator->registry,
+ camel_mapi_settings_get_profile (authenticator->mapi_settings),
+ password, cancellable, &mapi_error);
+
+ if (mapi_error) {
+ g_warn_if_fail (!authenticator->conn);
+ authenticator->conn = NULL;
+
+ g_propagate_error (error, mapi_error);
+
+ return E_SOURCE_AUTHENTICATION_ERROR;
+ }
+
+ g_warn_if_fail (authenticator->conn);
+
+ return E_SOURCE_AUTHENTICATION_ACCEPTED;
+}
+
+#define E_TYPE_MAPI_CONFIG_UTILS_AUTHENTICATOR (e_mapi_config_utils_authenticator_get_type ())
+
+GType e_mapi_config_utils_authenticator_get_type (void) G_GNUC_CONST;
+
+static void e_mapi_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_EXTENDED (EMapiConfigUtilsAuthenticator, e_mapi_config_utils_authenticator, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_mapi_config_utils_authenticator_authenticator_init))
+
+static void
+mapi_config_utils_authenticator_finalize (GObject *object)
+{
+ EMapiConfigUtilsAuthenticator *authenticator = (EMapiConfigUtilsAuthenticator *) object;
+
+ g_object_unref (authenticator->registry);
+ g_object_unref (authenticator->mapi_settings);
+ if (authenticator->conn)
+ g_object_unref (authenticator->conn);
+
+ G_OBJECT_CLASS (e_mapi_config_utils_authenticator_parent_class)->finalize (object);
+}
+
+static void
+e_mapi_config_utils_authenticator_class_init (EMapiConfigUtilsAuthenticatorClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = mapi_config_utils_authenticator_finalize;
+}
+
+static void
+e_mapi_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+ interface->try_password_sync = mapi_config_utils_authenticator_try_password_sync;
+}
+
+static void
+e_mapi_config_utils_authenticator_init (EMapiConfigUtilsAuthenticator *authenticator)
+{
+}
+
+EMapiConnection *
+e_mapi_config_utils_open_connection_for (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelMapiSettings *mapi_settings,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ const gchar *profile;
+ EMapiConnection *conn = NULL;
+ EMapiProfileData empd = { 0 };
+ CamelNetworkSettings *network_settings;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (registry != NULL, NULL);
+ g_return_val_if_fail (source != NULL, NULL);
+ g_return_val_if_fail (mapi_settings != NULL, NULL);
+
+ profile = camel_mapi_settings_get_profile (mapi_settings);
+
+ /* use the one from mailer, if there, otherwise open new */
+ conn = e_mapi_connection_find (profile);
+ if (conn)
+ return conn;
+
+ network_settings = CAMEL_NETWORK_SETTINGS (mapi_settings);
+
+ empd.server = camel_network_settings_get_host (network_settings);
+ empd.username = camel_network_settings_get_user (network_settings);
+ e_mapi_util_profiledata_from_settings (&empd, mapi_settings);
+
+ if (empd.krb_sso)
+ conn = e_mapi_connection_new (registry, profile, NULL, cancellable, &local_error);
+
+ while (!conn && !g_cancellable_is_cancelled (cancellable) && !local_error) {
+ if (empd.krb_sso) {
+ e_mapi_util_trigger_krb_auth (&empd, &local_error);
+ g_clear_error (&local_error);
+
+ conn = e_mapi_connection_new (registry, profile, NULL, cancellable, &local_error);
+ } else {
+ EMapiConfigUtilsAuthenticator *authenticator = g_object_new (E_TYPE_MAPI_CONFIG_UTILS_AUTHENTICATOR, NULL);
+
+ authenticator->mapi_settings = g_object_ref (mapi_settings);
+ authenticator->registry = g_object_ref (registry);
+
+ e_source_registry_authenticate_sync (
+ registry, source, E_SOURCE_AUTHENTICATOR (authenticator),
+ cancellable, &local_error);
+
+ if (authenticator->conn)
+ conn = g_object_ref (authenticator->conn);
+
+ g_object_unref (authenticator);
+ }
+ }
+
+ if (local_error)
+ g_propagate_error (perror, local_error);
+
+ return conn;
+}
+
+#define FOLDERSIZE_MENU_ITEM 0
+
+enum {
+ COL_FOLDERSIZE_NAME = 0,
+ COL_FOLDERSIZE_SIZE,
+ COL_FOLDERSIZE_MAX
+};
+
+typedef struct
+{
+ GtkDialog *dialog;
+ GtkGrid *spinner_grid;
+
+ ESourceRegistry *registry;
+ ESource *source;
+ CamelMapiSettings *mapi_settings;
+
+ GSList *folder_list;
+ GCancellable *cancellable;
+ GError *error;
+} FolderSizeDialogData;
+
+static gboolean
+mapi_settings_get_folder_size_idle (gpointer user_data)
+{
+ GtkWidget *widget;
+ GtkCellRenderer *renderer;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkBox *content_area;
+ FolderSizeDialogData *fsd = user_data;
+
+ g_return_val_if_fail (fsd != NULL, FALSE);
+
+ if (g_cancellable_is_cancelled (fsd->cancellable))
+ goto cleanup;
+
+ /* Hide progress bar. Set status*/
+ gtk_widget_destroy (GTK_WIDGET (fsd->spinner_grid));
+
+ if (fsd->folder_list) {
+ GtkWidget *scrolledwindow, *tree_view;
+ GSList *fiter;
+
+ scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_show (scrolledwindow);
+
+ /*Tree View */
+ tree_view = gtk_tree_view_new ();
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),-1,
+ _("Folder"), renderer, "text", COL_FOLDERSIZE_NAME,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),-1,
+ _("Size"), renderer, "text", COL_FOLDERSIZE_SIZE,
+ NULL);
+ /* Model for TreeView */
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (store));
+
+ /* Populate model with data */
+ for (fiter = fsd->folder_list; fiter; fiter = fiter->next) {
+ EMapiFolder *folder = fiter->data;
+ gchar *folder_size = g_format_size (folder->size);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_FOLDERSIZE_NAME, folder->folder_name,
+ COL_FOLDERSIZE_SIZE, folder_size,
+ -1);
+
+ g_free (folder_size);
+ }
+
+ gtk_container_add (GTK_CONTAINER (scrolledwindow), tree_view);
+ widget = scrolledwindow;
+ } else if (fsd->error) {
+ gchar *msg = g_strconcat (_("Unable to retrieve folder size information"), "\n", fsd->error->message, NULL);
+ widget = gtk_label_new (msg);
+ g_free (msg);
+ } else {
+ widget = gtk_label_new (_("Unable to retrieve folder size information"));
+ }
+
+ gtk_widget_show_all (widget);
+
+ /* Pack into content_area */
+ content_area = GTK_BOX (gtk_dialog_get_content_area (fsd->dialog));
+ gtk_box_pack_start (content_area, widget, TRUE, TRUE, 6);
+
+ cleanup:
+ e_mapi_folder_free_list (fsd->folder_list);
+ g_object_unref (fsd->registry);
+ g_object_unref (fsd->source);
+ g_object_unref (fsd->mapi_settings);
+ g_object_unref (fsd->cancellable);
+ g_clear_error (&fsd->error);
+ g_free (fsd);
+
+ return FALSE;
+}
+
+static gpointer
+mapi_settings_get_folder_size_thread (gpointer user_data)
+{
+ FolderSizeDialogData *fsd = user_data;
+ EMapiConnection *conn;
+
+ g_return_val_if_fail (fsd != NULL, NULL);
+
+ fsd->folder_list = NULL;
+ conn = e_mapi_config_utils_open_connection_for (GTK_WINDOW (fsd->dialog),
+ fsd->registry,
+ fsd->source,
+ fsd->mapi_settings,
+ fsd->cancellable,
+ &fsd->error);
+
+ if (conn && e_mapi_connection_connected (conn)) {
+ fsd->folder_list = NULL;
+ e_mapi_connection_get_folders_list (conn,
+ &fsd->folder_list,
+ NULL, NULL,
+ fsd->cancellable, &fsd->error);
+ }
+
+ if (conn)
+ g_object_unref (conn);
+
+ g_idle_add (mapi_settings_get_folder_size_idle, fsd);
+
+ return NULL;
+}
+
+void
+e_mapi_config_utils_run_folder_size_dialog (ESourceRegistry *registry,
+ ESource *source,
+ CamelMapiSettings *mapi_settings)
+{
+ GtkBox *content_area;
+ GtkWidget *spinner, *alignment, *dialog;
+ GtkWidget *spinner_label;
+ GCancellable *cancellable;
+ FolderSizeDialogData *fsd;
+
+ g_return_if_fail (mapi_settings != NULL);
+
+ dialog = gtk_dialog_new_with_buttons (_("Folder Size"), NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ fsd = g_new0 (FolderSizeDialogData, 1);
+ fsd->dialog = GTK_DIALOG (dialog);
+
+ gtk_window_set_default_size (GTK_WINDOW (fsd->dialog), 250, 300);
+
+ content_area = GTK_BOX (gtk_dialog_get_content_area (fsd->dialog));
+
+ spinner = gtk_spinner_new ();
+ gtk_spinner_start (GTK_SPINNER (spinner));
+ spinner_label = gtk_label_new (_("Fetching folder listâ"));
+
+ fsd->spinner_grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_column_spacing (fsd->spinner_grid, 6);
+ gtk_grid_set_column_homogeneous (fsd->spinner_grid, FALSE);
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (fsd->spinner_grid), GTK_ORIENTATION_HORIZONTAL);
+
+ alignment = gtk_alignment_new (1.0, 0.5, 0.0, 1.0);
+ gtk_container_add (GTK_CONTAINER (alignment), spinner);
+ gtk_misc_set_alignment (GTK_MISC (spinner_label), 0.0, 0.5);
+
+ gtk_container_add (GTK_CONTAINER (fsd->spinner_grid), alignment);
+ gtk_container_add (GTK_CONTAINER (fsd->spinner_grid), spinner_label);
+
+ /* Pack the TreeView into dialog's content area */
+ gtk_box_pack_start (content_area, GTK_WIDGET (fsd->spinner_grid), TRUE, TRUE, 6);
+ gtk_widget_show_all (GTK_WIDGET (fsd->dialog));
+
+ cancellable = g_cancellable_new ();
+ fsd->registry = g_object_ref (registry);
+ fsd->source = g_object_ref (source);
+ fsd->mapi_settings = g_object_ref (mapi_settings);
+ fsd->cancellable = g_object_ref (cancellable);
+
+ g_return_if_fail (g_thread_create (mapi_settings_get_folder_size_thread, fsd, FALSE, NULL));
+
+ /* Start the dialog */
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ g_cancellable_cancel (cancellable);
+ g_object_unref (cancellable);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static gchar *
+get_profile_name_from_folder_tree (EShellView *shell_view,
+ gchar **pfolder_path,
+ CamelStore **pstore)
+{
+ EShellSidebar *shell_sidebar;
+ EMFolderTree *folder_tree;
+ gchar *profile = NULL, *selected_path = NULL;
+ CamelStore *selected_store = NULL;
+
+ /* Get hold of Folder Tree */
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+ if (em_folder_tree_get_selected (folder_tree, &selected_store, &selected_path) ||
+ em_folder_tree_store_root_selected (folder_tree, &selected_store)) {
+ if (selected_store) {
+ CamelProvider *provider = camel_service_get_provider (CAMEL_SERVICE (selected_store));
+
+ if (provider && g_ascii_strcasecmp (provider->protocol, "mapi") == 0) {
+ CamelService *service;
+ CamelSettings *settings;
+
+ service = CAMEL_SERVICE (selected_store);
+ settings = camel_service_get_settings (service);
+ g_object_get (settings, "profile", &profile, NULL);
+
+ if (pstore && profile)
+ *pstore = g_object_ref (selected_store);
+
+ if (pfolder_path)
+ *pfolder_path = selected_path;
+ else
+ g_free (selected_path);
+
+ selected_path = NULL;
+ }
+
+ g_object_unref (selected_store);
+ }
+
+ g_free (selected_path);
+ }
+
+ g_object_unref (folder_tree);
+
+ return profile;
+}
+
+static void
+action_folder_size_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ gchar *profile;
+ CamelSession *session;
+ CamelStore *store = NULL;
+ CamelMapiSettings *mapi_settings;
+
+ profile = get_profile_name_from_folder_tree (shell_view, NULL, &store);
+ if (profile && store) {
+ ESourceRegistry *registry;
+ ESource *source;
+
+ mapi_settings = CAMEL_MAPI_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+ session = camel_service_get_session (CAMEL_SERVICE (store));
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+ source = e_source_registry_ref_source (registry, camel_service_get_uid (CAMEL_SERVICE (store)));
+
+ e_mapi_config_utils_run_folder_size_dialog (
+ registry, source, mapi_settings);
+
+ g_object_unref (source);
+ }
+
+ g_free (profile);
+ if (store)
+ g_object_unref (store);
+}
+
+static void
+action_subscribe_foreign_folder_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ gchar *profile;
+ GtkWindow *parent;
+ EShellBackend *backend;
+ CamelSession *session = NULL;
+ CamelStore *store = NULL;
+
+ profile = get_profile_name_from_folder_tree (shell_view, NULL, &store);
+ if (!profile)
+ return;
+
+ parent = GTK_WINDOW (e_shell_view_get_shell_window (shell_view));
+ backend = e_shell_view_get_shell_backend (shell_view);
+ g_object_get (G_OBJECT (backend), "session", &session, NULL);
+
+ e_mapi_subscribe_foreign_folder (parent, session, store);
+
+ g_object_unref (session);
+ g_object_unref (store);
+ g_free (profile);
+}
+
+static void
+action_folder_permissions_mail_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ gchar *profile, *folder_path = NULL;
+ EShellWindow *shell_window;
+ GtkWindow *parent;
+ CamelStore *store = NULL;
+ CamelMapiStore *mapi_store;
+ CamelNetworkSettings *network_settings;
+ CamelStoreInfo *si;
+
+ profile = get_profile_name_from_folder_tree (shell_view, &folder_path, &store);
+ if (!profile)
+ return;
+
+ mapi_store = CAMEL_MAPI_STORE (store);
+ g_return_if_fail (mapi_store != NULL);
+ g_return_if_fail (folder_path != NULL);
+
+ network_settings = CAMEL_NETWORK_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+ g_return_if_fail (network_settings != NULL);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ parent = GTK_WINDOW (shell_window);
+
+ si = camel_store_summary_path (mapi_store->summary, folder_path);
+ if (!si) {
+ e_notice (parent, GTK_MESSAGE_ERROR, _("Cannot edit permissions of folder '%s', choose other folder."), folder_path);
+ } else {
+ CamelMapiStoreInfo *msi = (CamelMapiStoreInfo *) si;
+ ESourceRegistry *registry = e_shell_get_registry (e_shell_window_get_shell (shell_window));
+ ESource *source;
+
+ source = e_source_registry_ref_source (registry, camel_service_get_uid (CAMEL_SERVICE (store)));
+ g_return_if_fail (source != NULL);
+
+ e_mapi_edit_folder_permissions (parent,
+ registry,
+ source,
+ CAMEL_MAPI_SETTINGS (network_settings),
+ camel_service_get_display_name (CAMEL_SERVICE (store)),
+ folder_path,
+ msi->folder_id,
+ (msi->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_FOREIGN) != 0 ? E_MAPI_FOLDER_CATEGORY_FOREIGN :
+ (msi->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? E_MAPI_FOLDER_CATEGORY_PUBLIC :
+ E_MAPI_FOLDER_CATEGORY_PERSONAL,
+ msi->foreign_username,
+ FALSE);
+
+ g_object_unref (source);
+ }
+
+ g_object_unref (store);
+ g_free (folder_path);
+}
+
+static void
+mapi_ui_enable_actions (GtkActionGroup *action_group,
+ const GtkActionEntry *entries,
+ guint n_entries,
+ gboolean can_show,
+ gboolean is_online)
+{
+ gint ii;
+
+ g_return_if_fail (action_group != NULL);
+ g_return_if_fail (entries != NULL);
+
+ for (ii = 0; ii < n_entries; ii++) {
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (action_group, entries[ii].name);
+ if (!action)
+ continue;
+
+ gtk_action_set_visible (action, can_show);
+ if (can_show)
+ gtk_action_set_sensitive (action, is_online);
+ }
+}
+
+static GtkActionEntry mail_account_context_entries[] = {
+
+ { "mail-mapi-folder-size",
+ NULL,
+ N_("Folder size..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_folder_size_cb) },
+
+ { "mail-mapi-subscribe-foreign-folder",
+ NULL,
+ N_("Subscribe to folder of other user..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_subscribe_foreign_folder_cb) }
+};
+
+static GtkActionEntry mail_folder_context_entries[] = {
+ { "mail-mapi-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit MAPI folder permissions"),
+ G_CALLBACK (action_folder_permissions_mail_cb) }
+};
+
+static const gchar *mapi_ui_mail_def =
+ "<popup name=\"mail-folder-popup\">\n"
+ " <placeholder name=\"mail-folder-popup-actions\">\n"
+ " <menuitem action=\"mail-mapi-folder-size\"/>\n"
+ " <menuitem action=\"mail-mapi-subscribe-foreign-folder\"/>\n"
+ " <menuitem action=\"mail-mapi-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+mapi_ui_update_actions_mail_cb (EShellView *shell_view,
+ GtkActionEntry *entries)
+{
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ EShellSidebar *shell_sidebar;
+ EMFolderTree *folder_tree;
+ CamelStore *selected_store = NULL;
+ gchar *selected_path = NULL;
+ gboolean account_node = FALSE, folder_node = FALSE;
+ gboolean online = FALSE;
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+ if (em_folder_tree_get_selected (folder_tree, &selected_store, &selected_path) ||
+ em_folder_tree_store_root_selected (folder_tree, &selected_store)) {
+ if (selected_store) {
+ CamelProvider *provider = camel_service_get_provider (CAMEL_SERVICE (selected_store));
+
+ if (provider && g_ascii_strcasecmp (provider->protocol, "mapi") == 0) {
+ account_node = !selected_path || !*selected_path;
+ folder_node = !account_node;
+ }
+
+ g_object_unref (selected_store);
+ }
+ }
+ g_object_unref (folder_tree);
+
+ g_free (selected_path);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ action_group = e_lookup_action_group (ui_manager, "mail");
+
+ if (account_node || folder_node) {
+ EShellBackend *backend;
+ CamelSession *session = NULL;
+
+ backend = e_shell_view_get_shell_backend (shell_view);
+ g_object_get (G_OBJECT (backend), "session", &session, NULL);
+
+ online = session && camel_session_get_online (session);
+
+ if (session)
+ g_object_unref (session);
+ }
+
+ mapi_ui_enable_actions (action_group, mail_account_context_entries, G_N_ELEMENTS (mail_account_context_entries), account_node, online);
+ mapi_ui_enable_actions (action_group, mail_folder_context_entries, G_N_ELEMENTS (mail_folder_context_entries), folder_node, online);
+}
+
+static void
+mapi_ui_init_mail (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (mapi_ui_mail_def);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action_group = e_shell_window_get_action_group (shell_window, "mail");
+
+ /* Add actions to the "mail" action group. */
+ e_action_group_add_actions_localized (action_group, GETTEXT_PACKAGE,
+ mail_account_context_entries, G_N_ELEMENTS (mail_account_context_entries), shell_view);
+ e_action_group_add_actions_localized (action_group, GETTEXT_PACKAGE,
+ mail_folder_context_entries, G_N_ELEMENTS (mail_folder_context_entries), shell_view);
+
+ /* Decide whether we want this option to be visible or not */
+ g_signal_connect (shell_view, "update-actions",
+ G_CALLBACK (mapi_ui_update_actions_mail_cb),
+ shell_view);
+
+ g_object_unref (action_group);
+}
+
+static gboolean
+get_selected_mapi_source (EShellView *shell_view,
+ ESource **selected_source,
+ ESourceRegistry **registry)
+{
+ ESource *source;
+ EShellSidebar *shell_sidebar;
+ ESourceSelector *selector = NULL;
+
+ g_return_val_if_fail (shell_view != NULL, FALSE);
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ g_return_val_if_fail (shell_sidebar != NULL, FALSE);
+
+ g_object_get (shell_sidebar, "selector", &selector, NULL);
+ g_return_val_if_fail (selector != NULL, FALSE);
+
+ source = e_source_selector_ref_primary_selection (selector);
+ if (source) {
+ ESourceBackend *backend_ext = NULL;
+
+ if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MEMO_LIST);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+
+ if (!backend_ext ||
+ g_strcmp0 (e_source_backend_get_backend_name (backend_ext), "mapi") != 0) {
+ g_object_unref (source);
+ source = NULL;
+ }
+ }
+
+ if (source && registry)
+ *registry = g_object_ref (e_source_selector_get_registry (selector));
+
+ g_object_unref (selector);
+
+ if (selected_source)
+ *selected_source = source;
+ else if (source)
+ g_object_unref (source);
+
+ return source != NULL;
+}
+
+/* how many menu entries are defined; all calendar/tasks/memos/contacts
+ actions should have same count */
+#define MAPI_ESOURCE_NUM_ENTRIES 1
+
+static void
+update_mapi_source_entries_cb (EShellView *shell_view,
+ GtkActionEntry *entries)
+{
+ GtkActionGroup *action_group;
+ EShell *shell;
+ EShellWindow *shell_window;
+ const gchar *group;
+ gboolean is_mapi_source, is_online;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+ g_return_if_fail (entries != NULL);
+
+ if (strstr (entries->name, "calendar"))
+ group = "calendar";
+ else if (strstr (entries->name, "tasks"))
+ group = "tasks";
+ else if (strstr (entries->name, "memos"))
+ group = "memos";
+ else if (strstr (entries->name, "contacts"))
+ group = "contacts";
+ else
+ g_return_if_reached ();
+
+ is_mapi_source = get_selected_mapi_source (shell_view, NULL, NULL);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ is_online = shell && e_shell_get_online (shell);
+ action_group = e_shell_window_get_action_group (shell_window, group);
+
+ mapi_ui_enable_actions (action_group, entries, MAPI_ESOURCE_NUM_ENTRIES, is_mapi_source, is_online);
+}
+
+static void
+setup_mapi_source_actions (EShellView *shell_view,
+ GtkUIManager *ui_manager,
+ GtkActionEntry *entries,
+ guint n_entries)
+{
+ EShellWindow *shell_window;
+ const gchar *group;
+
+ g_return_if_fail (shell_view != NULL);
+ g_return_if_fail (ui_manager != NULL);
+ g_return_if_fail (entries != NULL);
+ g_return_if_fail (n_entries > 0);
+ g_return_if_fail (n_entries == MAPI_ESOURCE_NUM_ENTRIES);
+
+ if (strstr (entries->name, "calendar"))
+ group = "calendar";
+ else if (strstr (entries->name, "tasks"))
+ group = "tasks";
+ else if (strstr (entries->name, "memos"))
+ group = "memos";
+ else if (strstr (entries->name, "contacts"))
+ group = "contacts";
+ else
+ g_return_if_reached ();
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ e_action_group_add_actions_localized (
+ e_shell_window_get_action_group (shell_window, group), GETTEXT_PACKAGE,
+ entries, MAPI_ESOURCE_NUM_ENTRIES, shell_view);
+
+ g_signal_connect (shell_view, "update-actions", G_CALLBACK (update_mapi_source_entries_cb), entries);
+}
+
+static void
+action_folder_permissions_source_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ ESourceRegistry *registry = NULL;
+ ESource *source = NULL, *parent_source;
+ ESourceMapiFolder *folder_ext;
+ mapi_id_t folder_id = 0;
+ const gchar *foreign_username;
+ gboolean is_public;
+ ESourceCamel *extension;
+ CamelSettings *settings;
+ const gchar *extension_name;
+
+ g_return_if_fail (action != NULL);
+ g_return_if_fail (shell_view != NULL);
+ g_return_if_fail (get_selected_mapi_source (shell_view, &source, ®istry));
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER));
+ g_return_if_fail (gtk_action_get_name (action) != NULL);
+
+ folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ folder_id = e_source_mapi_folder_get_id (folder_ext);
+ g_return_if_fail (folder_id != 0);
+
+ foreign_username = e_source_mapi_folder_get_foreign_username (folder_ext);
+ is_public = !foreign_username && e_source_mapi_folder_is_public (folder_ext);
+
+ parent_source = e_source_registry_ref_source (registry, e_source_get_parent (source));
+
+ extension_name = e_source_camel_get_extension_name ("mapi");
+ extension = e_source_get_extension (parent_source, extension_name);
+ settings = e_source_camel_get_settings (extension);
+
+ e_mapi_edit_folder_permissions (NULL,
+ registry,
+ source,
+ CAMEL_MAPI_SETTINGS (settings),
+ e_source_get_display_name (parent_source),
+ e_source_get_display_name (source),
+ folder_id,
+ foreign_username ? E_MAPI_FOLDER_CATEGORY_FOREIGN :
+ is_public ? E_MAPI_FOLDER_CATEGORY_PUBLIC :
+ E_MAPI_FOLDER_CATEGORY_PERSONAL,
+ foreign_username,
+ strstr (gtk_action_get_name (action), "calendar") != NULL);
+
+ g_object_unref (source);
+ g_object_unref (parent_source);
+ g_object_unref (registry);
+}
+
+static GtkActionEntry calendar_context_entries[] = {
+
+ { "calendar-mapi-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit MAPI calendar permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+static const gchar *mapi_ui_cal_def =
+ "<popup name=\"calendar-popup\">\n"
+ " <placeholder name=\"calendar-popup-actions\">\n"
+ " <menuitem action=\"calendar-mapi-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+mapi_ui_init_calendar (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (mapi_ui_cal_def);
+
+ setup_mapi_source_actions (shell_view, ui_manager,
+ calendar_context_entries, G_N_ELEMENTS (calendar_context_entries));
+}
+
+GtkActionEntry tasks_context_entries[] = {
+
+ { "tasks-mapi-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit MAPI tasks permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+const gchar *mapi_ui_task_def =
+ "<popup name=\"task-list-popup\">\n"
+ " <placeholder name=\"task-list-popup-actions\">\n"
+ " <menuitem action=\"tasks-mapi-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+mapi_ui_init_tasks (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (mapi_ui_task_def);
+
+ setup_mapi_source_actions (shell_view, ui_manager,
+ tasks_context_entries, G_N_ELEMENTS (tasks_context_entries));
+}
+
+static GtkActionEntry memos_context_entries[] = {
+
+ { "memos-mapi-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit MAPI memos permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+const gchar *mapi_ui_memo_def =
+ "<popup name=\"memo-list-popup\">\n"
+ " <placeholder name=\"memo-list-popup-actions\">\n"
+ " <menuitem action=\"memos-mapi-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+mapi_ui_init_memos (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (mapi_ui_memo_def);
+
+ setup_mapi_source_actions (shell_view, ui_manager,
+ memos_context_entries, G_N_ELEMENTS (memos_context_entries));
+}
+
+static GtkActionEntry contacts_context_entries[] = {
+
+ { "contacts-mapi-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit MAPI contacts permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+const gchar *mapi_ui_book_def =
+ "<popup name=\"address-book-popup\">\n"
+ " <placeholder name=\"address-book-popup-actions\">\n"
+ " <menuitem action=\"contacts-mapi-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+mapi_ui_init_contacts (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (mapi_ui_book_def);
+
+ setup_mapi_source_actions (shell_view, ui_manager,
+ contacts_context_entries, G_N_ELEMENTS (contacts_context_entries));
+}
+
+void
+e_mapi_config_utils_init_ui (EShellView *shell_view,
+ const gchar *ui_manager_id,
+ gchar **ui_definition)
+{
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+
+ g_return_if_fail (shell_view != NULL);
+ g_return_if_fail (ui_manager_id != NULL);
+ g_return_if_fail (ui_definition != NULL);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.mail") == 0)
+ mapi_ui_init_mail (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.calendars") == 0)
+ mapi_ui_init_calendar (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.tasks") == 0)
+ mapi_ui_init_tasks (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.memos") == 0)
+ mapi_ui_init_memos (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.contacts") == 0)
+ mapi_ui_init_contacts (ui_manager, shell_view, ui_definition);
+}
+
+gboolean
+e_mapi_config_utils_is_online (void)
+{
+ EShell *shell;
+
+ shell = e_shell_get_default ();
+
+ return shell && e_shell_get_online (shell);
+}
+
+GtkWindow *
+e_mapi_config_utils_get_widget_toplevel_window (GtkWidget *widget)
+{
+ if (!widget)
+ return NULL;
+
+ if (!GTK_IS_WINDOW (widget))
+ widget = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (widget))
+ return GTK_WINDOW (widget);
+
+ return NULL;
+}
+
+enum {
+ NAME_COL,
+ FID_COL,
+ FOLDER_COL,
+ NUM_COLS
+};
+
+static gboolean
+check_node (GtkTreeStore *ts, EMapiFolder *folder, GtkTreeIter iter)
+{
+ GtkTreeModel *ts_model;
+ mapi_id_t fid;
+
+ ts_model = GTK_TREE_MODEL (ts);
+
+ gtk_tree_model_get (ts_model, &iter, 1, &fid, -1);
+ if (fid && folder->parent_folder_id == fid) {
+ /* Do something */
+ GtkTreeIter node;
+ gtk_tree_store_append (ts, &node, &iter);
+ gtk_tree_store_set (ts, &node, NAME_COL, folder->folder_name, FID_COL, folder->folder_id, FOLDER_COL, folder,-1);
+ return TRUE;
+ }
+
+ if (gtk_tree_model_iter_has_child (ts_model, &iter)) {
+ GtkTreeIter child;
+ gtk_tree_model_iter_children (ts_model, &child, &iter);
+ if (check_node (ts, folder, child))
+ return TRUE;
+ }
+
+ if (gtk_tree_model_iter_next (ts_model, &iter)) {
+ return check_node (ts, folder, iter);
+ }
+
+ return FALSE;
+}
+
+static void
+add_to_store (GtkTreeStore *ts, EMapiFolder *folder)
+{
+ GtkTreeModel *ts_model;
+ GtkTreeIter iter;
+
+ ts_model = GTK_TREE_MODEL (ts);
+
+ g_return_if_fail (gtk_tree_model_get_iter_first (ts_model, &iter));
+ if (!check_node (ts, folder, iter)) {
+ GtkTreeIter node;
+ gtk_tree_store_append (ts, &node, &iter);
+ gtk_tree_store_set (ts, &node, NAME_COL, folder->folder_name, FID_COL, folder->folder_id, FOLDER_COL, folder, -1);
+ }
+}
+
+static void
+traverse_tree (GtkTreeModel *model, GtkTreeIter iter, EMapiFolderType folder_type, gboolean *pany_sub_used)
+{
+ gboolean any_sub_used = FALSE;
+ gboolean has_next = TRUE;
+
+ do {
+ gboolean sub_used = FALSE;
+ GtkTreeIter next = iter;
+ EMapiFolder *folder = NULL;
+
+ has_next = gtk_tree_model_iter_next (model, &next);
+
+ if (gtk_tree_model_iter_has_child (model, &iter)) {
+ GtkTreeIter child;
+
+ gtk_tree_model_iter_children (model, &child, &iter);
+ traverse_tree (model, child, folder_type, &sub_used);
+ }
+
+ gtk_tree_model_get (model, &iter, FOLDER_COL, &folder, -1);
+ if (folder && (e_mapi_folder_get_type (folder) == folder_type || (folder_type == E_MAPI_FOLDER_TYPE_MEMO && e_mapi_folder_get_type (folder) == E_MAPI_FOLDER_TYPE_JOURNAL))) {
+ sub_used = TRUE;
+ }
+
+ if (sub_used)
+ any_sub_used = TRUE;
+ else if (pany_sub_used && folder)
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+ iter = next;
+ } while (has_next);
+
+ if (pany_sub_used && any_sub_used)
+ *pany_sub_used = TRUE;
+}
+
+static void
+add_folders (GSList *folders, GtkTreeStore *ts, EMapiFolderType folder_type)
+{
+ GSList *tmp = folders;
+ GtkTreeIter iter;
+ GtkTreeModel *model = GTK_TREE_MODEL (ts);
+ gchar *node = _("Personal Folders");
+
+ /* add all... */
+ gtk_tree_store_append (ts, &iter, NULL);
+ gtk_tree_store_set (ts, &iter, NAME_COL, node, -1);
+ while (tmp) {
+ EMapiFolder *folder = tmp->data;
+ add_to_store (ts, folder);
+ tmp = tmp->next;
+ }
+
+ /* ... then remove those which don't belong to folder_type */
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ traverse_tree (model, iter, folder_type, NULL);
+ }
+}
+
+static void
+select_folder (GtkTreeModel *model,
+ mapi_id_t fid,
+ GtkWidget *tree_view)
+{
+ GtkTreeIter iter, next;
+ gboolean found = FALSE, can = TRUE;
+
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (tree_view != NULL);
+
+ if (!gtk_tree_model_get_iter_first (model, &iter))
+ return;
+
+ while (!found && can) {
+ EMapiFolder *folder = NULL;
+
+ gtk_tree_model_get (model, &iter, FOLDER_COL, &folder, -1);
+
+ if (folder && e_mapi_folder_get_id (folder) == fid) {
+ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), &iter);
+ found = TRUE;
+ break;
+ }
+
+ can = FALSE;
+ if (gtk_tree_model_iter_children (model, &next, &iter)) {
+ iter = next;
+ can = TRUE;
+ }
+
+ next = iter;
+ if (!can && gtk_tree_model_iter_next (model, &next)) {
+ iter = next;
+ can = TRUE;
+ }
+
+ if (!can && gtk_tree_model_iter_parent (model, &next, &iter)) {
+ while (!can) {
+ iter = next;
+
+ if (gtk_tree_model_iter_next (model, &iter)) {
+ can = TRUE;
+ break;
+ }
+
+ iter = next;
+ if (!gtk_tree_model_iter_parent (model, &next, &iter))
+ break;
+ }
+ }
+ }
+}
+
+static void
+e_mapi_cursor_change (GtkTreeView *treeview,
+ ESource *source)
+{
+ ESourceMapiFolder *folder_ext;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ mapi_id_t pfid;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ if (!selection)
+ return;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_tree_model_get (model, &iter, FID_COL, &pfid, -1);
+ } else {
+ pfid = 0;
+ }
+
+ folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ e_source_mapi_folder_set_parent_id (folder_ext, pfid);
+}
+
+struct EMapiFolderStructureData
+{
+ EMapiFolderType folder_type;
+ GSList *folders;
+ GtkWidget *tree_view;
+ ESource *source;
+ ESource *child_source;
+ ESourceRegistry *registry;
+};
+
+static void
+e_mapi_folder_structure_data_free (gpointer ptr)
+{
+ struct EMapiFolderStructureData *fsd = ptr;
+
+ if (!fsd)
+ return;
+
+ e_mapi_folder_free_list (fsd->folders);
+ g_object_unref (fsd->tree_view);
+ g_object_unref (fsd->source);
+ g_object_unref (fsd->child_source);
+ g_object_unref (fsd->registry);
+ g_free (fsd);
+}
+
+static void
+e_mapi_download_folder_structure_idle (GObject *source_obj,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct EMapiFolderStructureData *fsd = user_data;
+ ESourceMapiFolder *folder_ext;
+ GtkTreeStore *tree_store;
+
+ g_return_if_fail (fsd != NULL);
+ g_return_if_fail (fsd->tree_view != NULL);
+ g_return_if_fail (source_obj != NULL);
+ g_return_if_fail (E_IS_SOURCE (source_obj));
+
+ tree_store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fsd->tree_view)));
+ g_return_if_fail (tree_store != NULL);
+
+ add_folders (fsd->folders, tree_store, fsd->folder_type);
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (fsd->tree_view));
+
+ folder_ext = e_source_get_extension (fsd->child_source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ if (e_source_mapi_folder_get_id (folder_ext)) {
+ select_folder (GTK_TREE_MODEL (tree_store),
+ e_source_mapi_folder_get_id (folder_ext),
+ fsd->tree_view);
+ }
+}
+
+static void
+e_mapi_download_folder_structure_thread (GObject *source_obj,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct EMapiFolderStructureData *fsd = user_data;
+ const gchar *extension_name;
+ ESource *source;
+ ESourceCamel *extension;
+ EMapiConnection *conn;
+ CamelSettings *settings;
+ CamelMapiSettings *mapi_settings;
+
+ g_return_if_fail (fsd != NULL);
+ g_return_if_fail (fsd->tree_view != NULL);
+ g_return_if_fail (source_obj != NULL);
+ g_return_if_fail (E_IS_SOURCE (source_obj));
+
+ source = E_SOURCE (source_obj);
+
+ extension_name = e_source_camel_get_extension_name ("mapi");
+ g_return_if_fail (e_source_has_extension (source, extension_name));
+
+ extension = e_source_get_extension (source, extension_name);
+ settings = e_source_camel_get_settings (extension);
+ mapi_settings = CAMEL_MAPI_SETTINGS (settings);
+
+ conn = e_mapi_config_utils_open_connection_for (NULL,
+ fsd->registry,
+ source,
+ mapi_settings,
+ cancellable,
+ perror);
+
+ if (!conn)
+ return;
+
+ if (conn && e_mapi_connection_connected (conn)) {
+ fsd->folders = e_mapi_connection_peek_folders_list (conn);
+ if (fsd->folders)
+ fsd->folders = e_mapi_folder_copy_list (fsd->folders);
+ }
+
+ if (conn)
+ g_object_unref (conn);
+}
+
+static gboolean
+e_mapi_invoke_folder_structure_download_idle (gpointer user_data)
+{
+ struct EMapiFolderStructureData *fsd = user_data;
+
+ g_return_val_if_fail (fsd != NULL, FALSE);
+
+ e_mapi_config_utils_run_in_thread_with_feedback (e_mapi_config_utils_get_widget_toplevel_window (fsd->tree_view),
+ G_OBJECT (fsd->source),
+ _("Searching remote MAPI folder structure, please wait..."),
+ e_mapi_download_folder_structure_thread,
+ e_mapi_download_folder_structure_idle,
+ fsd,
+ e_mapi_folder_structure_data_free);
+
+ return FALSE;
+}
+
+void
+e_mapi_config_utils_insert_widgets (ESourceConfigBackend *backend,
+ ESource *scratch_source)
+{
+ ESourceBackend *backend_ext = NULL;
+ ESourceMapiFolder *folder_ext;
+ ESourceConfig *config;
+ GtkWidget *widget;
+ gboolean is_new_source;
+ EMapiFolderType folder_type = E_MAPI_FOLDER_TYPE_UNKNOWN;
+
+ g_return_if_fail (backend != NULL);
+ g_return_if_fail (scratch_source != NULL);
+
+ if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
+ backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+ folder_type = E_MAPI_FOLDER_TYPE_CONTACT;
+ } else if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_CALENDAR)) {
+ backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_CALENDAR);
+ folder_type = E_MAPI_FOLDER_TYPE_APPOINTMENT;
+ } else if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_TASK_LIST)) {
+ backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_TASK_LIST);
+ folder_type = E_MAPI_FOLDER_TYPE_TASK;
+ } else if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_MEMO_LIST)) {
+ backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_MEMO_LIST);
+ folder_type = E_MAPI_FOLDER_TYPE_MEMO;
+ }
+
+ if (!backend_ext || g_strcmp0 (e_source_backend_get_backend_name (backend_ext), "mapi") != 0)
+ return;
+
+ folder_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ g_return_if_fail (folder_ext != NULL);
+
+ config = e_source_config_backend_get_config (backend);
+ if (E_IS_BOOK_SOURCE_CONFIG (config))
+ e_book_source_config_add_offline_toggle (E_BOOK_SOURCE_CONFIG (config), scratch_source);
+ else if (E_IS_CAL_SOURCE_CONFIG (config))
+ e_cal_source_config_add_offline_toggle (E_CAL_SOURCE_CONFIG (config), scratch_source);
+
+ widget = gtk_check_button_new_with_mnemonic (_("Lis_ten for server notifications"));
+ e_source_config_insert_widget (config, scratch_source, NULL, widget);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ folder_ext, "server-notification",
+ widget, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ /* no extra options for subscribed folders */
+ if (e_source_mapi_folder_is_public (folder_ext) ||
+ e_source_mapi_folder_get_foreign_username (folder_ext))
+ return;
+
+ is_new_source = e_source_mapi_folder_get_id (folder_ext) == 0;
+ if (is_new_source && !e_mapi_config_utils_is_online ()) {
+ const gchar *msg;
+
+ switch (folder_type) {
+ case E_MAPI_FOLDER_TYPE_APPOINTMENT:
+ msg = _("Cannot create MAPI calendar in offline mode");
+ break;
+ case E_MAPI_FOLDER_TYPE_TASK:
+ msg = _("Cannot create MAPI task list in offline mode");
+ break;
+ case E_MAPI_FOLDER_TYPE_MEMO:
+ msg = _("Cannot create MAPI memo list in offline mode");
+ break;
+ case E_MAPI_FOLDER_TYPE_CONTACT:
+ msg = _("Cannot create MAPI address book in offline mode");
+ break;
+ default:
+ g_warn_if_reached ();
+ msg = _("Cannot create MAPI source in offline mode");
+ break;
+ }
+
+ widget = gtk_label_new (msg);
+ gtk_widget_show (widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+
+ e_source_config_insert_widget (config, scratch_source, NULL, widget);
+ } else {
+ GtkGrid *content_grid;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeStore *tree_store;
+ GtkWidget *tree_view, *scrolled_window;
+ ESource *parent_source;
+
+ content_grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_spacing (content_grid, 2);
+ gtk_grid_set_column_spacing (content_grid, 6);
+
+ widget = gtk_label_new_with_mnemonic (_("_Location:"));
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_grid_attach (content_grid, widget, 0, 0, 1, 1);
+
+ tree_store = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_POINTER);
+
+ parent_source = e_source_config_get_collection_source (config);
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (e_source_get_display_name (parent_source), renderer, "text", NAME_COL, NULL);
+ tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+ g_object_set (tree_view, "expander-column", column, "headers-visible", TRUE, NULL);
+ gtk_widget_set_sensitive (tree_view, is_new_source);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+ g_object_set (scrolled_window, "height-request", 150, NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (widget), scrolled_window);
+ g_signal_connect (G_OBJECT (tree_view), "cursor-changed", G_CALLBACK (e_mapi_cursor_change), scratch_source);
+ gtk_widget_show_all (scrolled_window);
+
+ gtk_grid_attach (content_grid, scrolled_window, 0, 1, 1, 1);
+
+ if (e_mapi_config_utils_is_online ()) {
+ struct EMapiFolderStructureData *fsd;
+
+ fsd = g_new0 (struct EMapiFolderStructureData, 1);
+ fsd->folder_type = folder_type;
+ fsd->folders = NULL;
+ fsd->tree_view = g_object_ref (tree_view);
+ fsd->source = g_object_ref (parent_source);
+ fsd->child_source = g_object_ref (scratch_source);
+ fsd->registry = g_object_ref (e_source_config_get_registry (config));
+
+ g_idle_add (e_mapi_invoke_folder_structure_download_idle, fsd);
+ }
+
+ gtk_widget_set_hexpand (GTK_WIDGET (content_grid), TRUE);
+ gtk_widget_set_vexpand (GTK_WIDGET (content_grid), TRUE);
+ gtk_widget_show_all (GTK_WIDGET (content_grid));
+
+ e_source_config_insert_widget (config, scratch_source, NULL, GTK_WIDGET (content_grid));
+ }
+}
diff --git a/src/configuration/e-mapi-config-utils.h b/src/configuration/e-mapi-config-utils.h
new file mode 100644
index 0000000..f119749
--- /dev/null
+++ b/src/configuration/e-mapi-config-utils.h
@@ -0,0 +1,74 @@
+/*
+ * e-mapi-config-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_MAPI_CONFIG_UTILS_H
+#define E_MAPI_CONFIG_UTILS_H
+
+#include <gtk/gtk.h>
+
+#include <shell/e-shell-view.h>
+#include <misc/e-source-config.h>
+#include <misc/e-source-config-backend.h>
+
+#include "e-mapi-connection.h"
+#include "camel-mapi-settings.h"
+
+typedef void (* EMapiSetupFunc) (GObject *with_object,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror);
+
+void e_mapi_config_utils_run_in_thread_with_feedback (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EMapiSetupFunc thread_func,
+ EMapiSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data);
+
+void e_mapi_config_utils_run_in_thread_with_feedback_modal (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EMapiSetupFunc thread_func,
+ EMapiSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data);
+
+EMapiConnection * e_mapi_config_utils_open_connection_for (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelMapiSettings *mapi_settings,
+ GCancellable *cancellable,
+ GError **perror);
+
+void e_mapi_config_utils_run_folder_size_dialog (ESourceRegistry *registry,
+ ESource *source,
+ CamelMapiSettings *mapi_settings);
+
+void e_mapi_config_utils_init_ui (EShellView *shell_view,
+ const gchar *ui_manager_id,
+ gchar **ui_definition);
+
+gboolean e_mapi_config_utils_is_online (void);
+
+GtkWindow * e_mapi_config_utils_get_widget_toplevel_window (GtkWidget *widget);
+
+void e_mapi_config_utils_insert_widgets (ESourceConfigBackend *backend,
+ ESource *scratch_source);
+
+#endif /* E_MAPI_CONFIG_UTILS */
diff --git a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c b/src/configuration/e-mapi-edit-folder-permissions.c
similarity index 97%
rename from src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
rename to src/configuration/e-mapi-edit-folder-permissions.c
index 8c8ef73..0c7d41d 100644
--- a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
+++ b/src/configuration/e-mapi-edit-folder-permissions.c
@@ -28,7 +28,7 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
-#include "e-mapi-account-setup.h"
+#include "e-mapi-config-utils.h"
#include "e-mapi-edit-folder-permissions.h"
#include "e-mapi-search-gal-user.h"
#include "e-mapi-utils.h"
@@ -45,9 +45,9 @@ enum {
struct EMapiPermissionsDialogWidgets
{
- gchar *login_profile;
- gchar *login_username;
- gchar *login_url;
+ ESourceRegistry *registry;
+ ESource *source;
+ CamelMapiSettings *mapi_settings;
mapi_id_t folder_id;
EMapiFolderCategory folder_category;
gchar *foreign_username;
@@ -149,9 +149,9 @@ edit_permissions_widgets_free (gpointer ptr)
if (!widgets)
return;
- g_free (widgets->login_profile);
- g_free (widgets->login_username);
- g_free (widgets->login_url);
+ g_object_unref (widgets->registry);
+ g_object_unref (widgets->source);
+ g_object_unref (widgets->mapi_settings);
g_free (widgets->foreign_username);
if (widgets->conn)
e_mapi_utils_unref_in_thread (G_OBJECT (widgets->conn));
@@ -270,7 +270,7 @@ edit_permissions_response_cb (GObject *dialog,
write_entries = g_slist_reverse (write_entries);
}
- e_mapi_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
+ e_mapi_config_utils_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
_("Writing folder permissions, please wait..."),
write_folder_permissions_thread,
write_folder_permissions_idle,
@@ -705,14 +705,14 @@ read_folder_permissions_thread (GObject *dialog,
widgets = g_object_get_data (dialog, E_MAPI_PERM_DLG_WIDGETS);
g_return_if_fail (widgets != NULL);
- g_return_if_fail (widgets->login_profile != NULL);
- g_return_if_fail (widgets->login_username != NULL);
- g_return_if_fail (widgets->login_url != NULL);
-
- widgets->conn = e_mapi_account_open_connection_for (GTK_WINDOW (dialog),
- widgets->login_profile,
- widgets->login_username,
- widgets->login_url,
+ g_return_if_fail (widgets->registry != NULL);
+ g_return_if_fail (widgets->source != NULL);
+ g_return_if_fail (widgets->mapi_settings != NULL);
+
+ widgets->conn = e_mapi_config_utils_open_connection_for (GTK_WINDOW (dialog),
+ widgets->registry,
+ widgets->source,
+ widgets->mapi_settings,
cancellable,
perror);
@@ -894,9 +894,9 @@ create_permissions_tree_view (GObject *dialog,
users in the given store */
void
e_mapi_edit_folder_permissions (GtkWindow *parent,
- const gchar *login_profile,
- const gchar *login_username,
- const gchar *login_url,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelMapiSettings *mapi_settings,
const gchar *account_name,
const gchar *folder_name,
mapi_id_t folder_id,
@@ -916,17 +916,17 @@ e_mapi_edit_folder_permissions (GtkWindow *parent,
gchar *str;
gint row, ii;
- g_return_if_fail (login_profile != NULL);
- g_return_if_fail (login_username != NULL);
- g_return_if_fail (login_url != NULL);
+ g_return_if_fail (registry != NULL);
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (mapi_settings != NULL);
g_return_if_fail (account_name != NULL);
g_return_if_fail (folder_name != NULL);
g_return_if_fail (folder_id != 0);
widgets = g_new0 (struct EMapiPermissionsDialogWidgets, 1);
- widgets->login_profile = g_strdup (login_profile);
- widgets->login_username = g_strdup (login_username);
- widgets->login_url = g_strdup (login_url);
+ widgets->registry = g_object_ref (registry);
+ widgets->source = g_object_ref (source);
+ widgets->mapi_settings = g_object_ref (mapi_settings);
widgets->folder_id = folder_id;
widgets->folder_category = folder_category;
widgets->foreign_username = g_strdup (foreign_username);
@@ -1275,7 +1275,7 @@ e_mapi_edit_folder_permissions (GtkWindow *parent,
found_entries = g_new0 (GSList *, 1);
- e_mapi_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
+ e_mapi_config_utils_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
_("Reading folder permissions, please wait..."),
read_folder_permissions_thread,
read_folder_permissions_idle,
diff --git a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.h b/src/configuration/e-mapi-edit-folder-permissions.h
similarity index 86%
rename from src/account-setup-eplugin/e-mapi-edit-folder-permissions.h
rename to src/configuration/e-mapi-edit-folder-permissions.h
index 8e9d613..3927bdb 100644
--- a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.h
+++ b/src/configuration/e-mapi-edit-folder-permissions.h
@@ -26,13 +26,15 @@
#include <gtk/gtk.h>
#include <libmapi/libmapi.h>
+#include <libedataserver/libedataserver.h>
-#include <e-mapi-folder.h>
+#include "e-mapi-folder.h"
+#include "camel-mapi-settings.h"
void e_mapi_edit_folder_permissions (GtkWindow *parent,
- const gchar *login_profile,
- const gchar *login_username,
- const gchar *login_url,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelMapiSettings *mapi_settings,
const gchar *account_name,
const gchar *folder_name,
mapi_id_t folder_id,
diff --git a/src/account-setup-eplugin/e-mapi-search-gal-user.c b/src/configuration/e-mapi-search-gal-user.c
similarity index 99%
rename from src/account-setup-eplugin/e-mapi-search-gal-user.c
rename to src/configuration/e-mapi-search-gal-user.c
index 2cc6044..c09007b 100644
--- a/src/account-setup-eplugin/e-mapi-search-gal-user.c
+++ b/src/configuration/e-mapi-search-gal-user.c
@@ -28,7 +28,7 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
-#include "e-mapi-account-setup.h"
+#include "e-mapi-config-utils.h"
#include "e-mapi-search-gal-user.h"
#include "e-mapi-utils.h"
#include "e-mapi-defs.h"
diff --git a/src/account-setup-eplugin/e-mapi-search-gal-user.h b/src/configuration/e-mapi-search-gal-user.h
similarity index 100%
rename from src/account-setup-eplugin/e-mapi-search-gal-user.h
rename to src/configuration/e-mapi-search-gal-user.h
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c b/src/configuration/e-mapi-subscribe-foreign-folder.c
similarity index 96%
rename from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c
rename to src/configuration/e-mapi-subscribe-foreign-folder.c
index e382295..ff77e62 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c
+++ b/src/configuration/e-mapi-subscribe-foreign-folder.c
@@ -28,12 +28,13 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
-#include <libedataserverui/e-name-selector.h>
+#include <libedataserverui/libedataserverui.h>
+#include <libemail-engine/e-mail-session.h>
#include "camel/camel-mapi-store.h"
#include "camel/camel-mapi-store-summary.h"
-#include "e-mapi-account-setup.h"
+#include "e-mapi-config-utils.h"
#include "e-mapi-search-gal-user.h"
#include "e-mapi-subscribe-foreign-folder.h"
#include "e-mapi-utils.h"
@@ -366,12 +367,13 @@ check_foreign_folder_idle (GObject *with_object,
GError **perror)
{
struct EMapiCheckForeignFolderData *cffd = user_data;
- gchar *fid, *folder_name;
+ gchar *folder_name;
const gchar *base_username, *base_foldername;
CamelSettings *settings;
CamelMapiSettings *mapi_settings;
CamelMapiStore *mapi_store;
- CamelNetworkSettings *network_settings;
+ ESourceRegistry *registry = NULL;
+ CamelSession *session;
EMapiFolderType folder_type;
g_return_if_fail (with_object != NULL);
@@ -383,9 +385,6 @@ check_foreign_folder_idle (GObject *with_object,
if (!cffd->folder_id)
return;
- fid = e_mapi_util_mapi_id_to_string (cffd->folder_id);
- g_return_if_fail (fid != NULL);
-
base_username = cffd->user_displayname ? cffd->user_displayname : cffd->username;
base_foldername = cffd->folder_displayname ? cffd->folder_displayname : cffd->orig_foldername;
@@ -399,7 +398,9 @@ check_foreign_folder_idle (GObject *with_object,
mapi_store = CAMEL_MAPI_STORE (with_object);
settings = camel_service_get_settings (CAMEL_SERVICE (mapi_store));
mapi_settings = CAMEL_MAPI_SETTINGS (settings);
- network_settings = CAMEL_NETWORK_SETTINGS (settings);
+ session = camel_service_get_session (CAMEL_SERVICE (mapi_store));
+ if (E_IS_MAIL_SESSION (session))
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
folder_type = e_mapi_folder_type_from_string (cffd->folder_container_class);
if ((folder_type == E_MAPI_FOLDER_TYPE_MAIL &&
@@ -410,25 +411,22 @@ check_foreign_folder_idle (GObject *with_object,
base_username,
base_foldername,
perror)) ||
- (folder_type != E_MAPI_FOLDER_TYPE_MAIL && !e_mapi_folder_add_as_esource (folder_type,
+ (folder_type != E_MAPI_FOLDER_TYPE_MAIL && !e_mapi_folder_add_as_esource (registry,
+ folder_type,
camel_mapi_settings_get_profile (mapi_settings),
- camel_mapi_settings_get_domain (mapi_settings),
- camel_mapi_settings_get_realm (mapi_settings),
- camel_network_settings_get_host (network_settings),
- camel_network_settings_get_user (network_settings),
- camel_mapi_settings_get_kerberos (mapi_settings),
TRUE /* camel_offline_settings_get_stay_synchronized (CAMEL_OFFLINE_SETTINGS (mapi_settings)) */,
E_MAPI_FOLDER_CATEGORY_FOREIGN,
cffd->username,
folder_name,
- fid,
+ cffd->folder_id,
+ 0,
+ cancellable,
perror))) {
/* to not destroy the dialog on error */
cffd->folder_id = 0;
}
g_free (folder_name);
- g_free (fid);
}
static void
@@ -508,7 +506,7 @@ subscribe_foreign_response_cb (GObject *dialog,
description = g_strdup_printf (_("Testing availability of folder '%s' of user '%s', please wait..."), cffd->orig_foldername, cffd->username);
- e_mapi_run_in_thread_with_feedback (
+ e_mapi_config_utils_run_in_thread_with_feedback (
GTK_WINDOW (dialog),
G_OBJECT (cstore),
description,
@@ -629,7 +627,7 @@ e_mapi_subscribe_foreign_folder (GtkWindow *parent,
row++;
- name_selector = e_name_selector_new ();
+ name_selector = e_name_selector_new (e_mail_session_get_registry (E_MAIL_SESSION (session)));
name_selector_model = e_name_selector_peek_model (name_selector);
e_name_selector_model_add_section (name_selector_model, "User", _("User"), NULL);
name_selector_dialog = e_name_selector_peek_dialog (name_selector);
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/configuration/e-mapi-subscribe-foreign-folder.h
similarity index 100%
rename from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
rename to src/configuration/e-mapi-subscribe-foreign-folder.h
diff --git a/src/configuration/module-mapi-configuration.c b/src/configuration/module-mapi-configuration.c
new file mode 100644
index 0000000..0709493
--- /dev/null
+++ b/src/configuration/module-mapi-configuration.c
@@ -0,0 +1,49 @@
+/*
+ * module-mapi-mail-config.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-book-config-mapi.h"
+#include "e-book-config-mapigal.h"
+#include "e-cal-config-mapi.h"
+#include "e-mail-config-mapi-backend.h"
+#include "e-mail-config-mapi-page.h"
+#include "e-mail-config-mapi-extension.h"
+#include "e-mapi-config-ui-extension.h"
+#include "e-source-mapi-folder.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ e_book_config_mapi_type_register (type_module);
+ e_book_config_mapigal_type_register (type_module);
+ e_cal_config_mapi_type_register (type_module);
+ e_mail_config_mapi_backend_type_register (type_module);
+ e_mail_config_mapi_page_type_register (type_module);
+ e_mail_config_mapi_extension_type_register (type_module);
+ e_mapi_config_ui_extension_type_register (type_module);
+
+ e_source_mapi_folder_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/src/libexchangemapi/Makefile.am b/src/libexchangemapi/Makefile.am
index 4786f8c..d6efaba 100644
--- a/src/libexchangemapi/Makefile.am
+++ b/src/libexchangemapi/Makefile.am
@@ -42,7 +42,9 @@ libexchangemapi_1_0_la_SOURCES = \
e-mapi-mail-utils.c \
e-mapi-mail-utils.h \
e-mapi-operation-queue.c \
- e-mapi-operation-queue.h
+ e-mapi-operation-queue.h \
+ e-source-mapi-folder.c \
+ e-source-mapi-folder.h
libexchangemapi_1_0_la_LIBADD = \
diff --git a/src/libexchangemapi/e-mapi-book-utils.c b/src/libexchangemapi/e-mapi-book-utils.c
index 476d8d4..6ca91d4 100644
--- a/src/libexchangemapi/e-mapi-book-utils.c
+++ b/src/libexchangemapi/e-mapi-book-utils.c
@@ -22,7 +22,7 @@
#include <config.h>
#endif
-#include <libedataserver/e-sexp.h>
+#include <libedataserver/libedataserver.h>
#include "e-mapi-book-utils.h"
diff --git a/src/libexchangemapi/e-mapi-book-utils.h b/src/libexchangemapi/e-mapi-book-utils.h
index 6ec2d9c..b01d479 100644
--- a/src/libexchangemapi/e-mapi-book-utils.h
+++ b/src/libexchangemapi/e-mapi-book-utils.h
@@ -21,7 +21,7 @@
#ifndef E_MAPI_BOOK_UTILS_H
#define E_MAPI_BOOK_UTILS_H
-#include <libebook/e-contact.h>
+#include <libebook/libebook.h>
#include <e-mapi-connection.h>
#include <e-mapi-defs.h>
diff --git a/src/libexchangemapi/e-mapi-cal-recur-utils.c b/src/libexchangemapi/e-mapi-cal-recur-utils.c
index 9e1f7b4..250f643 100644
--- a/src/libexchangemapi/e-mapi-cal-recur-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-recur-utils.c
@@ -25,8 +25,9 @@
#include <config.h>
#endif
+#include <libecal/libecal.h>
+
#include "e-mapi-cal-recur-utils.h"
-#include <libecal/e-cal-util.h>
/* Reader/Writer versions */
#define READER_VERSION 0x3004
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.c b/src/libexchangemapi/e-mapi-cal-tz-utils.c
index 689311d..af091eb 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.c
@@ -81,8 +81,8 @@ e_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tz_location)
}
static struct icaltimetype
-tm_to_icaltimetype (struct tm *tm,
- gboolean dst)
+e_mapi_tm_to_icaltimetype (struct tm *tm,
+ gboolean dst)
{
struct icaltimetype itt;
@@ -112,7 +112,7 @@ get_offset (icaltimezone *zone,
time_t now = time (NULL);
gmtime_r (&now, &local);
- tt = tm_to_icaltimetype (&local, dst);
+ tt = e_mapi_tm_to_icaltimetype (&local, dst);
offset = icaltimezone_get_utc_offset (zone, &tt, NULL);
return offset / -60;
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index 2abf26f..e756537 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -27,9 +27,8 @@
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
-#include <fcntl.h>
-#include <libecal/e-cal-util.h>
-#include <libedataserver/e-data-server-util.h>
+#include <libecal/libecal.h>
+#include <libedataserver/libedataserver.h>
#include "e-mapi-mail-utils.h"
#include "e-mapi-cal-utils.h"
diff --git a/src/libexchangemapi/e-mapi-cal-utils.h b/src/libexchangemapi/e-mapi-cal-utils.h
index d4f056f..ae536cf 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.h
+++ b/src/libexchangemapi/e-mapi-cal-utils.h
@@ -24,7 +24,7 @@
#ifndef E_MAPI_CAL_UTILS_H
#define E_MAPI_CAL_UTILS_H
-#include <libecal/e-cal-component.h>
+#include <libecal/libecal.h>
#include "e-mapi-connection.h"
#include "e-mapi-defs.h"
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index b18d8a1..c5c241a 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -28,10 +28,7 @@
#include <glib/gi18n-lib.h>
#include <camel/camel.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
-#include <libedataserver/e-data-server-util.h>
-#include <libedataserver/e-flag.h>
+#include <libedataserver/libedataserver.h>
#include <tevent.h>
@@ -52,7 +49,7 @@
static void register_connection (EMapiConnection *conn);
static void unregister_connection (EMapiConnection *conn);
static gboolean mapi_profile_create (struct mapi_context *mapi_ctx, const EMapiProfileData *empd, mapi_profile_callback_t callback, gconstpointer data, GCancellable *cancellable, GError **perror, gboolean use_locking);
-static struct mapi_session *mapi_profile_load (struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror);
+static struct mapi_session *mapi_profile_load (ESourceRegistry *registry, struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror);
/* GObject foo - begin */
@@ -165,6 +162,8 @@ make_mapi_error (GError **perror, const gchar *context, enum MAPISTATUS mapi_sta
}
struct _EMapiConnectionPrivate {
+ ESourceRegistry *registry;
+
struct mapi_context *mapi_ctx;
struct mapi_session *session;
GStaticRecMutex session_lock;
@@ -410,6 +409,10 @@ e_mapi_connection_finalize (GObject *object)
e_flag_free (priv->notification_flag);
priv->notification_flag = NULL;
+
+ if (priv->registry)
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
}
if (G_OBJECT_CLASS (e_mapi_connection_parent_class)->finalize)
@@ -555,7 +558,11 @@ e_mapi_connection_find (const gchar *profile)
/* Creates a new connection object and connects to a server as defined in 'profile' */
EMapiConnection *
-e_mapi_connection_new (const gchar *profile, const gchar *password, GCancellable *cancellable, GError **perror)
+e_mapi_connection_new (ESourceRegistry *registry,
+ const gchar *profile,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **perror)
{
EMapiConnection *conn;
EMapiConnectionPrivate *priv;
@@ -568,7 +575,7 @@ e_mapi_connection_new (const gchar *profile, const gchar *password, GCancellable
if (!e_mapi_utils_create_mapi_context (&mapi_ctx, perror))
return NULL;
- session = mapi_profile_load (mapi_ctx, profile, password, cancellable, perror);
+ session = mapi_profile_load (registry, mapi_ctx, profile, password ? password->str : NULL, cancellable, perror);
if (!session) {
e_mapi_utils_destroy_mapi_context (mapi_ctx);
return NULL;
@@ -580,6 +587,7 @@ e_mapi_connection_new (const gchar *profile, const gchar *password, GCancellable
LOCK ();
mapi_object_init (&priv->msg_store);
+ priv->registry = registry ? g_object_ref (registry) : NULL;
priv->mapi_ctx = mapi_ctx;
priv->session = session;
@@ -632,7 +640,10 @@ e_mapi_connection_close (EMapiConnection *conn)
}
gboolean
-e_mapi_connection_reconnect (EMapiConnection *conn, const gchar *password, GCancellable *cancellable, GError **perror)
+e_mapi_connection_reconnect (EMapiConnection *conn,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **perror)
{
enum MAPISTATUS ms;
@@ -644,7 +655,7 @@ e_mapi_connection_reconnect (EMapiConnection *conn, const gchar *password, GCanc
if (priv->session)
e_mapi_connection_close (conn);
- priv->session = mapi_profile_load (priv->mapi_ctx, priv->profile, password, cancellable, perror);
+ priv->session = mapi_profile_load (priv->registry, priv->mapi_ctx, priv->profile, password ? password->str : NULL, cancellable, perror);
if (!priv->session) {
e_mapi_debug_print ("%s: %s: Login failed ", G_STRLOC, G_STRFUNC);
UNLOCK ();
@@ -6503,6 +6514,7 @@ e_mapi_connection_disable_notifications (EMapiConnection *conn,
struct tcp_data
{
+ ESourceRegistry *registry;
struct mapi_context *mapi_ctx;
const gchar *profname;
const gchar *password;
@@ -6516,57 +6528,59 @@ struct tcp_data
static gboolean
try_create_profile_main_thread_cb (struct tcp_data *data)
{
- EAccountList *accounts;
EMapiProfileData empd = { 0 };
- EIterator *iter;
- GConfClient *gconf;
+ GList *all_sources;
+ ESource *source;
g_return_val_if_fail (data != NULL, FALSE);
+ if (!data->registry) {
+ e_flag_set (data->eflag);
+ return FALSE;
+ }
- gconf = gconf_client_get_default ();
- accounts = e_account_list_new (gconf);
- for (iter = e_list_get_iterator (E_LIST (accounts)); e_iterator_is_valid (iter); e_iterator_next (iter)) {
- EAccount *account = E_ACCOUNT (e_iterator_get (iter));
- if (account && account->source && account->source->url && g_ascii_strncasecmp (account->source->url, "mapi://", 7) == 0) {
- CamelURL *url;
- CamelSettings *settings;
- const gchar *url_string;
-
- url_string = e_account_get_string (account, E_ACCOUNT_SOURCE_URL);
- url = camel_url_new (url_string, NULL);
-
- settings = g_object_new (CAMEL_TYPE_MAPI_SETTINGS, NULL);
- camel_settings_load_from_url (settings, url);
-
- empd.server = url->host;
- empd.username = url->user;
- e_mapi_util_profiledata_from_settings (&empd, CAMEL_MAPI_SETTINGS (settings));
- /* cast away the const, but promise not to touch it */
- empd.password = (gchar*)data->password;
-
- if (COMPLETE_PROFILEDATA(&empd)) {
- gchar *profname = e_mapi_util_profile_name (data->mapi_ctx, &empd, FALSE);
-
- if (profname && g_str_equal (profname, data->profname)) {
- /* do not use locking here, because when this is called then other thread is holding the lock */
- data->has_profile = mapi_profile_create (data->mapi_ctx, &empd, NULL, NULL, NULL, data->perror, FALSE);
-
- g_free (profname);
- g_object_unref (settings);
- camel_url_free (url);
- break;
- }
+ all_sources = e_source_registry_list_sources (data->registry, NULL);
+ source = e_mapi_utils_get_master_source (all_sources, data->profname);
- g_free (profname);
+ if (source) {
+ ESourceCamel *extension;
+ CamelSettings *settings;
+ const gchar *extension_name;
+ CamelNetworkSettings *network_settings;
+
+ extension_name = e_source_camel_get_extension_name ("mapi");
+ extension = e_source_get_extension (source, extension_name);
+ settings = e_source_camel_get_settings (extension);
+
+ network_settings = CAMEL_NETWORK_SETTINGS (settings);
+
+ empd.server = camel_network_settings_get_host (network_settings);
+ empd.username = camel_network_settings_get_user (network_settings);
+ e_mapi_util_profiledata_from_settings (&empd, CAMEL_MAPI_SETTINGS (settings));
+
+ if (data->password)
+ empd.password = g_string_new (data->password);
+ else
+ data->password = NULL;
+
+ if (COMPLETE_PROFILEDATA (&empd)) {
+ gchar *profname = e_mapi_util_profile_name (data->mapi_ctx, &empd, FALSE);
+
+ if (profname && g_str_equal (profname, data->profname)) {
+ /* do not use locking here, because when this is called then other thread is holding the lock */
+ data->has_profile = mapi_profile_create (data->mapi_ctx, &empd, NULL, NULL, NULL, data->perror, FALSE);
}
- g_object_unref (settings);
- camel_url_free (url);
+ g_free (profname);
+ }
+
+ if (empd.password) {
+ if (empd.password->len)
+ memset (empd.password->str, 0, empd.password->len);
+ g_string_free (empd.password, TRUE);
}
}
- g_object_unref (accounts);
- g_object_unref (gconf);
+ g_list_free_full (all_sources, g_object_unref);
e_flag_set (data->eflag);
@@ -6574,7 +6588,12 @@ try_create_profile_main_thread_cb (struct tcp_data *data)
}
static gboolean
-try_create_profile (struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror)
+try_create_profile (ESourceRegistry *registry,
+ struct mapi_context *mapi_ctx,
+ const gchar *profname,
+ const gchar *password,
+ GCancellable *cancellable,
+ GError **perror)
{
struct tcp_data data;
@@ -6582,6 +6601,7 @@ try_create_profile (struct mapi_context *mapi_ctx, const gchar *profname, const
g_return_val_if_fail (profname != NULL, FALSE);
g_return_val_if_fail (*profname != 0, FALSE);
+ data.registry = registry;
data.mapi_ctx = mapi_ctx;
data.profname = profname;
data.password = password;
@@ -6604,7 +6624,12 @@ try_create_profile (struct mapi_context *mapi_ctx, const gchar *profname, const
}
static struct mapi_session *
-mapi_profile_load (struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror)
+mapi_profile_load (ESourceRegistry *registry,
+ struct mapi_context *mapi_ctx,
+ const gchar *profname,
+ const gchar *password,
+ GCancellable *cancellable,
+ GError **perror)
{
enum MAPISTATUS ms = MAPI_E_SUCCESS;
struct mapi_session *session = NULL;
@@ -6627,7 +6652,7 @@ mapi_profile_load (struct mapi_context *mapi_ctx, const gchar *profname, const g
e_mapi_debug_print("Loading profile %s ", profname);
ms = MapiLogonEx (mapi_ctx, &session, profname, password);
- if (ms == MAPI_E_NOT_FOUND && try_create_profile (mapi_ctx, profname, password, cancellable, perror))
+ if (ms == MAPI_E_NOT_FOUND && try_create_profile (registry, mapi_ctx, profname, password, cancellable, perror))
ms = MapiLogonEx (mapi_ctx, &session, profname, password);
if (ms != MAPI_E_SUCCESS) {
@@ -6684,7 +6709,7 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
}
/*We need all the params before proceeding.*/
- e_return_val_mapi_error_if_fail (COMPLETE_PROFILEDATA(empd),
+ e_return_val_mapi_error_if_fail (COMPLETE_PROFILEDATA (empd) && empd->password && empd->password->len,
MAPI_E_INVALID_PARAMETER, FALSE);
if (use_locking)
@@ -6700,7 +6725,7 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
/* don't bother to check error - it would be valid if we got an error */
ms = CreateProfile (mapi_ctx, profname, empd->username,
- empd->password, OC_PROFILE_NOPASSWORD);
+ empd->password->str, OC_PROFILE_NOPASSWORD);
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "CreateProfile", ms);
goto cleanup;
@@ -6732,7 +6757,7 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
/* Login now */
e_mapi_debug_print("Logging into the server... ");
- ms = MapiLogonProvider (mapi_ctx, &session, profname, empd->password,
+ ms = MapiLogonProvider (mapi_ctx, &session, profname, empd->password->str,
PROVIDER_ID_NSPI);
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "MapiLogonProvider", ms);
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index 2eebbff..25c3450 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -31,6 +31,7 @@
#include <libmapi/libmapi.h>
#include <libmapi/mapi_nameid.h>
+#include <libedataserver/libedataserver.h>
/* Standard GObject macros */
#define E_MAPI_TYPE_CONNECTION (e_mapi_connection_get_type ())
@@ -229,13 +230,14 @@ struct _EMapiConnectionClass {
};
GType e_mapi_connection_get_type (void);
-EMapiConnection * e_mapi_connection_new (const gchar *profile,
- const gchar *password,
+EMapiConnection * e_mapi_connection_new (ESourceRegistry *registry,
+ const gchar *profile,
+ const GString *password,
GCancellable *cancellable,
GError **perror);
EMapiConnection * e_mapi_connection_find (const gchar *profile);
gboolean e_mapi_connection_reconnect (EMapiConnection *conn,
- const gchar *password,
+ const GString *password,
GCancellable *cancellable,
GError **perror);
gboolean e_mapi_connection_close (EMapiConnection *conn);
@@ -515,7 +517,7 @@ gboolean e_mapi_connection_disable_notifications (EMapiConnection *conn,
typedef struct {
const gchar *username;
- gchar *password;
+ GString *password;
const gchar *domain;
const gchar *server;
gboolean use_ssl;
@@ -525,7 +527,7 @@ typedef struct {
#define COMPLETE_PROFILEDATA(x) \
((x)->username && *(x)->username && (x)->server && *(x)->server \
- && (((x)->domain && *(x)->domain && (x)->password && *(x)->password) \
+ && (((x)->domain && *(x)->domain) \
|| ((x)->krb_sso && (x)->krb_realm && *(x)->krb_realm)))
gboolean e_mapi_create_profile (struct mapi_context *mapi_ctx,
diff --git a/src/libexchangemapi/e-mapi-folder.c b/src/libexchangemapi/e-mapi-folder.c
index cb81763..a1cdb13 100644
--- a/src/libexchangemapi/e-mapi-folder.c
+++ b/src/libexchangemapi/e-mapi-folder.c
@@ -27,12 +27,12 @@
#include <glib/gi18n-lib.h>
-#include <libedataserver/e-source.h>
-#include <libedataserver/e-source-group.h>
-#include <libedataserver/e-source-list.h>
+#include <libedataserver/libedataserver.h>
#include "e-mapi-connection.h"
#include "e-mapi-folder.h"
+#include "e-mapi-utils.h"
+#include "e-source-mapi-folder.h"
#define d(x)
@@ -143,7 +143,7 @@ e_mapi_folder_get_name (EMapiFolder *folder)
}
guint64
-e_mapi_folder_get_fid (EMapiFolder *folder)
+e_mapi_folder_get_id (EMapiFolder *folder)
{
return folder->folder_id;
}
@@ -166,6 +166,12 @@ e_mapi_folder_get_type (EMapiFolder *folder)
return folder->container_class;
}
+EMapiFolderCategory
+e_mapi_folder_get_category (EMapiFolder *folder)
+{
+ return folder->category;
+}
+
guint32
e_mapi_folder_get_unread_count (EMapiFolder *folder)
{
@@ -252,258 +258,174 @@ e_mapi_folder_pick_color_spec (gint move_by,
return g_strdup_printf ("#%06x", color);
}
-#define MAPI_URI_PREFIX "mapi://"
-
-static const gchar *
-get_gconf_key_for_folder_type (EMapiFolderType folder_type)
+gboolean
+e_mapi_folder_populate_esource (ESource *source,
+ const GList *sources,
+ EMapiFolderType folder_type,
+ const gchar *profile,
+ gboolean offline_sync,
+ EMapiFolderCategory folder_category,
+ const gchar *foreign_username, /* NULL for public folder */
+ const gchar *folder_name,
+ mapi_id_t folder_id,
+ gint color_seed,
+ GCancellable *cancellable,
+ GError **perror)
{
- if (folder_type == E_MAPI_FOLDER_TYPE_APPOINTMENT)
- return CALENDAR_SOURCES;
- else if (folder_type == E_MAPI_FOLDER_TYPE_TASK)
- return TASK_SOURCES;
- else if (folder_type == E_MAPI_FOLDER_TYPE_MEMO)
- return JOURNAL_SOURCES;
- else if (folder_type == E_MAPI_FOLDER_TYPE_JOURNAL)
- return JOURNAL_SOURCES;
- else if (folder_type == E_MAPI_FOLDER_TYPE_CONTACT)
- return ADDRESSBOOK_SOURCES;
+ ESource *master_source;
+ gboolean res = FALSE;
- return NULL;
-}
+ master_source = e_mapi_utils_get_master_source (sources, profile);
-gboolean
-e_mapi_folder_add_as_esource (EMapiFolderType folder_type,
- const gchar *login_profile,
- const gchar *login_domain,
- const gchar *login_realm,
- const gchar *login_host,
- const gchar *login_user,
- gboolean login_kerberos,
- gboolean offline_sync,
- EMapiFolderCategory folder_category,
- const gchar *foreign_username, /* NULL for public folder */
- const gchar *folder_name,
- const gchar *fid,
- GError **perror)
-{
- ESourceList *source_list = NULL;
- ESourceGroup *group = NULL;
- const gchar *conf_key = NULL;
- GConfClient* client;
- GSList *sources;
- ESource *source = NULL;
- gchar *relative_uri = NULL;
- gchar *base_uri = NULL;
-
- g_return_val_if_fail (login_profile != NULL, FALSE);
- g_return_val_if_fail (login_host != NULL, FALSE);
- g_return_val_if_fail (login_user != NULL, FALSE);
- g_return_val_if_fail (folder_name != NULL, FALSE);
- g_return_val_if_fail (fid != NULL, FALSE);
- g_return_val_if_fail (folder_category == E_MAPI_FOLDER_CATEGORY_PUBLIC || folder_category == E_MAPI_FOLDER_CATEGORY_FOREIGN, FALSE);
- if (folder_category == E_MAPI_FOLDER_CATEGORY_FOREIGN)
- g_return_val_if_fail (foreign_username != NULL, FALSE);
-
- conf_key = get_gconf_key_for_folder_type (folder_type);
- if (!conf_key) {
- g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, unsupported folder type")));
- return FALSE;
- }
+ if (master_source) {
+ ESourceBackend *backend_ext;
- client = gconf_client_get_default ();
- source_list = e_source_list_new_for_gconf (client, conf_key);
- base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, login_user, login_host);
- group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
- if (!group) {
- g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, group of sources not found")));
- g_object_unref (source_list);
- g_object_unref (client);
- g_free (base_uri);
-
- return FALSE;
- }
+ e_source_set_parent (source, e_source_get_uid (master_source));
+ e_source_set_display_name (source, folder_name);
+
+ switch (folder_type) {
+ case E_MAPI_FOLDER_TYPE_APPOINTMENT:
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+ break;
+ case E_MAPI_FOLDER_TYPE_JOURNAL:
+ case E_MAPI_FOLDER_TYPE_MEMO:
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MEMO_LIST);
+ break;
+ case E_MAPI_FOLDER_TYPE_TASK:
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
+ break;
+ case E_MAPI_FOLDER_TYPE_CONTACT:
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+ break;
+ default:
+ backend_ext = NULL;
+ break;
+ }
- sources = e_source_group_peek_sources (group);
- for (; sources != NULL; sources = g_slist_next (sources)) {
- ESource *source = E_SOURCE (sources->data);
- gchar *folder_id = e_source_get_duped_property (source, "folder-id");
- if (folder_id) {
- if (g_str_equal (fid, folder_id)) {
- g_propagate_error (perror,
- g_error_new (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER,
- _("Cannot add folder, folder already exists as '%s'"), e_source_peek_name (source)));
-
- g_object_unref (source_list);
- g_object_unref (client);
- g_free (folder_id);
- g_free (base_uri);
-
- return FALSE;
+ if (backend_ext) {
+ ESourceMapiFolder *folder_ext;
+ ESourceOffline *offline_ext;
+
+ e_source_backend_set_backend_name (backend_ext , "mapi");
+
+ folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ e_source_mapi_folder_set_id (folder_ext, folder_id);
+ if (folder_category == E_MAPI_FOLDER_CATEGORY_PUBLIC)
+ e_source_mapi_folder_set_is_public (folder_ext, TRUE);
+ else
+ e_source_mapi_folder_set_foreign_username (folder_ext, foreign_username);
+
+ offline_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_OFFLINE);
+ e_source_offline_set_stay_synchronized (offline_ext, offline_sync);
+
+ /* set also color for calendar-like sources */
+ if (folder_type != E_MAPI_FOLDER_TYPE_CONTACT) {
+ gchar *color_str;
+
+ color_str = e_mapi_folder_pick_color_spec (1 + g_list_length ((GList *) sources), folder_type != E_MAPI_FOLDER_TYPE_APPOINTMENT);
+ e_source_selectable_set_color (E_SOURCE_SELECTABLE (backend_ext), color_str);
+ g_free (color_str);
}
- g_free (folder_id);
+ res = TRUE;
+ } else {
+ g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, unsupported folder type")));
}
- }
-
- relative_uri = g_strconcat (";", fid, NULL);
- source = e_source_new (folder_name, relative_uri);
- e_source_set_property (source, "username", login_user);
- e_source_set_property (source, "host", login_host);
- e_source_set_property (source, "profile", login_profile);
- e_source_set_property (source, "domain", login_domain);
- e_source_set_property (source, "realm", login_realm);
- e_source_set_property (source, "folder-id", fid);
- e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0");
- e_source_set_property (source, "delete", "yes");
- if (folder_category == E_MAPI_FOLDER_CATEGORY_PUBLIC)
- e_source_set_property (source, "public", "yes");
- else
- e_source_set_property (source, "foreign-username", foreign_username);
- if (login_kerberos) {
- e_source_set_property (source, "kerberos", "required");
} else {
- e_source_set_property (source, "auth", "1");
- e_source_set_property (source, "auth-type", "plain/password");
+ g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, master source not found")));
}
- /* set also color for calendar-like sources */
- if (folder_type != E_MAPI_FOLDER_TYPE_CONTACT) {
- GSList *sources = e_source_group_peek_sources (group);
- gchar *color_str;
+ return res;
+}
- color_str = e_mapi_folder_pick_color_spec (1 + g_slist_length (sources), folder_type != E_MAPI_FOLDER_TYPE_APPOINTMENT);
- e_source_set_color_spec (source, color_str);
- g_free (color_str);
+gboolean
+e_mapi_folder_add_as_esource (ESourceRegistry *pregistry,
+ EMapiFolderType folder_type,
+ const gchar *profile,
+ gboolean offline_sync,
+ EMapiFolderCategory folder_category,
+ const gchar *foreign_username, /* NULL for public folder */
+ const gchar *folder_name,
+ mapi_id_t folder_id,
+ gint color_seed,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ ESourceRegistry *registry;
+ GList *sources;
+ ESource *source;
+ gboolean res = FALSE;
+
+ registry = pregistry;
+ if (!registry) {
+ registry = e_source_registry_new_sync (cancellable, perror);
+ if (!registry)
+ return FALSE;
}
- e_source_group_add_source (group, source, -1);
-
+ sources = e_source_registry_list_sources (registry, NULL);
+ source = e_source_new (NULL, NULL, NULL);
+
+ if (e_mapi_folder_populate_esource (
+ source,
+ sources,
+ folder_type,
+ profile,
+ offline_sync,
+ folder_category,
+ foreign_username,
+ folder_name,
+ folder_id,
+ color_seed,
+ cancellable,
+ perror)) {
+ res = e_source_registry_commit_source_sync (registry, source, cancellable, perror);
+ }
g_object_unref (source);
- g_object_unref (client);
- g_free (relative_uri);
- g_free (base_uri);
- if (!e_source_list_sync (source_list, perror)) {
- g_object_unref (source_list);
- return FALSE;
- }
+ g_list_free_full (sources, g_object_unref);
+ if (!pregistry)
+ g_object_unref (registry);
- g_object_unref (source_list);
- return TRUE;
+ return res;
}
gboolean
-e_mapi_folder_remove_as_esource (EMapiFolderType folder_type,
- const gchar *login_host,
- const gchar *login_user,
- const gchar *fid,
+e_mapi_folder_remove_as_esource (ESourceRegistry *pregistry,
+ const gchar *profile,
+ mapi_id_t folder_id,
+ GCancellable *cancellable,
GError **perror)
{
- ESourceList *source_list = NULL;
- ESourceGroup *group = NULL;
- const gchar *conf_key = NULL;
- GConfClient* client;
- GSList *sources = NULL;
- gchar *base_uri = NULL;
-
- g_return_val_if_fail (login_host != NULL, FALSE);
- g_return_val_if_fail (login_user != NULL, FALSE);
- g_return_val_if_fail (fid != NULL, FALSE);
-
- conf_key = get_gconf_key_for_folder_type (folder_type);
- if (!conf_key) {
- g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot remove folder, unsupported folder type")));
- return FALSE;
+ ESourceRegistry *registry;
+ ESource *source;
+ GList *sources;
+ gboolean res = TRUE;
+
+ registry = pregistry;
+ if (!registry) {
+ registry = e_source_registry_new_sync (cancellable, perror);
+ if (!registry)
+ return FALSE;
}
- client = gconf_client_get_default ();
- source_list = e_source_list_new_for_gconf (client, conf_key);
- base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, login_user, login_host);
- group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
- if (!group) {
- g_free (base_uri);
- g_object_unref (source_list);
- g_object_unref (client);
-
- return TRUE;
- }
-
- sources = e_source_group_peek_sources (group);
- for (; sources != NULL; sources = g_slist_next (sources)) {
- ESource *source = E_SOURCE (sources->data);
- gchar *folder_id = e_source_get_duped_property (source, "folder-id");
- if (folder_id) {
- if (g_str_equal (fid, folder_id)) {
- g_free (folder_id);
-
- e_source_group_remove_source (group, source);
- break;
- }
+ sources = e_source_registry_list_sources (registry, NULL);
+ source = e_mapi_utils_get_source_for_folder (sources, profile, folder_id);
- g_free (folder_id);
- }
- }
+ if (source)
+ res = e_source_remove_sync (source, cancellable, perror);
- g_free (base_uri);
- g_object_unref (source_list);
- g_object_unref (client);
+ g_list_free_full (sources, g_object_unref);
+ if (!pregistry)
+ g_object_unref (registry);
- return TRUE;
+ return res;
}
gboolean
-e_mapi_folder_is_subscribed_as_esource (EMapiFolderType folder_type,
- const gchar *login_host,
- const gchar *login_user,
- const gchar *fid)
+e_mapi_folder_is_subscribed_as_esource (const GList *esources,
+ const gchar *profile,
+ mapi_id_t fid)
{
- ESourceList *source_list = NULL;
- ESourceGroup *group = NULL;
- const gchar *conf_key = NULL;
- GConfClient* client;
- GSList *sources = NULL;
- gchar *base_uri = NULL;
- gboolean found = FALSE;
-
- g_return_val_if_fail (login_host != NULL, FALSE);
- g_return_val_if_fail (login_user != NULL, FALSE);
- g_return_val_if_fail (fid != NULL, FALSE);
-
- conf_key = get_gconf_key_for_folder_type (folder_type);
- if (!conf_key)
- return FALSE;
-
- client = gconf_client_get_default ();
- source_list = e_source_list_new_for_gconf (client, conf_key);
- base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, login_user, login_host);
- group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
- if (!group) {
- g_free (base_uri);
- g_object_unref (source_list);
- g_object_unref (client);
-
- return FALSE;
- }
-
- sources = e_source_group_peek_sources (group);
- for (; sources != NULL; sources = g_slist_next (sources)) {
- ESource *source = E_SOURCE (sources->data);
- gchar *folder_id = e_source_get_duped_property (source, "folder-id");
- if (folder_id) {
- if (g_str_equal (fid, folder_id)) {
- g_free (folder_id);
-
- found = TRUE;
- break;
- }
-
- g_free (folder_id);
- }
- }
-
- g_free (base_uri);
- g_object_unref (source_list);
- g_object_unref (client);
-
- return found;
+ return e_mapi_utils_get_source_for_folder (esources, profile, fid) != NULL;
}
diff --git a/src/libexchangemapi/e-mapi-folder.h b/src/libexchangemapi/e-mapi-folder.h
index e65a087..2e4b9b7 100644
--- a/src/libexchangemapi/e-mapi-folder.h
+++ b/src/libexchangemapi/e-mapi-folder.h
@@ -27,14 +27,7 @@
#include <glib.h>
#include <libmapi/libmapi.h>
-
-#define CALENDAR_SOURCES "/apps/evolution/calendar/sources"
-#define TASK_SOURCES "/apps/evolution/tasks/sources"
-#define JOURNAL_SOURCES "/apps/evolution/memos/sources"
-#define SELECTED_CALENDARS "/apps/evolution/calendar/display/selected_calendars"
-#define SELECTED_TASKS "/apps/evolution/calendar/tasks/selected_tasks"
-#define SELECTED_JOURNALS "/apps/evolution/calendar/memos/selected_memos"
-#define ADDRESSBOOK_SOURCES "/apps/evolution/addressbook/sources"
+#include <libedataserver/libedataserver.h>
typedef enum {
E_MAPI_FOLDER_TYPE_UNKNOWN = 0,
@@ -96,9 +89,10 @@ EMapiFolder * e_mapi_folder_copy (EMapiFolder *src);
void e_mapi_folder_free (EMapiFolder *folder);
const gchar * e_mapi_folder_get_name (EMapiFolder *folder);
-mapi_id_t e_mapi_folder_get_fid (EMapiFolder *folder);
+mapi_id_t e_mapi_folder_get_id (EMapiFolder *folder);
mapi_id_t e_mapi_folder_get_parent_id (EMapiFolder *folder);
EMapiFolderType e_mapi_folder_get_type (EMapiFolder *folder);
+EMapiFolderCategory e_mapi_folder_get_category (EMapiFolder *folder);
guint32 e_mapi_folder_get_unread_count (EMapiFolder *folder);
guint32 e_mapi_folder_get_total_count (EMapiFolder *folder);
gboolean e_mapi_folder_is_root (EMapiFolder *folder);
@@ -109,29 +103,39 @@ void e_mapi_folder_free_list (GSList *folder_list);
gchar * e_mapi_folder_pick_color_spec (gint move_by,
gboolean around_middle);
-gboolean e_mapi_folder_add_as_esource (EMapiFolderType folder_type,
- const gchar *login_profile,
- const gchar *login_domain,
- const gchar *login_realm,
- const gchar *login_host,
- const gchar *login_user,
- gboolean login_kerberos,
+gboolean e_mapi_folder_populate_esource (ESource *source,
+ const GList *sources,
+ EMapiFolderType folder_type,
+ const gchar *profile,
+ gboolean offline_sync,
+ EMapiFolderCategory folder_category,
+ const gchar *foreign_username, /* NULL for public folder */
+ const gchar *folder_name,
+ mapi_id_t folder_id,
+ gint color_seed,
+ GCancellable *cancellable,
+ GError **perror);
+
+gboolean e_mapi_folder_add_as_esource (ESourceRegistry *pregistry,
+ EMapiFolderType folder_type,
+ const gchar *profile,
gboolean offline_sync,
EMapiFolderCategory folder_category,
const gchar *foreign_username, /* NULL for public folder */
const gchar *folder_name,
- const gchar *fid,
+ mapi_id_t folder_id,
+ gint color_seed,
+ GCancellable *cancellable,
GError **perror);
-gboolean e_mapi_folder_remove_as_esource (EMapiFolderType folder_type,
- const gchar *login_host,
- const gchar *login_user,
- const gchar *fid,
+gboolean e_mapi_folder_remove_as_esource (ESourceRegistry *pregistry,
+ const gchar *profile,
+ mapi_id_t folder_id,
+ GCancellable *cancellable,
GError **perror);
gboolean e_mapi_folder_is_subscribed_as_esource
- (EMapiFolderType folder_type,
- const gchar *login_host,
- const gchar *login_user,
- const gchar *fid);
+ (const GList *esources,
+ const gchar *profile,
+ mapi_id_t fid);
#endif
diff --git a/src/libexchangemapi/e-mapi-mail-utils.c b/src/libexchangemapi/e-mapi-mail-utils.c
index a60e920..05130e2 100644
--- a/src/libexchangemapi/e-mapi-mail-utils.c
+++ b/src/libexchangemapi/e-mapi-mail-utils.c
@@ -22,7 +22,7 @@
#endif
#include <camel/camel.h>
-#include <libecal/e-cal-util.h>
+#include <libecal/libecal.h>
#include "e-mapi-defs.h"
#include "e-mapi-utils.h"
diff --git a/src/libexchangemapi/e-mapi-utils.c b/src/libexchangemapi/e-mapi-utils.c
index 47bf2d3..6ae30c8 100644
--- a/src/libexchangemapi/e-mapi-utils.c
+++ b/src/libexchangemapi/e-mapi-utils.c
@@ -28,10 +28,11 @@
#include <glib.h>
#include <gio/gio.h>
-#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/libedataserver.h>
#include "e-mapi-utils.h"
#include "e-mapi-mail-utils.h"
+#include "e-source-mapi-folder.h"
#ifdef G_OS_WIN32
/* Undef the similar macro from pthread.h, it doesn't check if
@@ -655,7 +656,9 @@ e_mapi_util_profiledata_from_settings (EMapiProfileData *empd, CamelMapiSettings
}
gboolean
-e_mapi_util_trigger_krb_auth (const EMapiProfileData *empd, GError **error) {
+e_mapi_util_trigger_krb_auth (const EMapiProfileData *empd,
+ GError **error)
+{
gint success = FALSE;
GError *local_error = NULL;
GDBusConnection *connection;
@@ -1279,3 +1282,101 @@ e_mapi_utils_unref_in_thread (GObject *object)
g_object_unref (object);
}
}
+
+static gboolean
+is_for_profile (ESource *source,
+ const gchar *profile)
+{
+ ESourceCamel *extension;
+ CamelMapiSettings *settings;
+ const gchar *extension_name;
+
+ if (!source)
+ return FALSE;
+
+ if (!profile)
+ return TRUE;
+
+ extension_name = e_source_camel_get_extension_name ("mapi");
+ if (!e_source_has_extension (source, extension_name))
+ return FALSE;
+
+ extension = e_source_get_extension (source, extension_name);
+ settings = CAMEL_MAPI_SETTINGS (e_source_camel_get_settings (extension));
+
+ return settings && g_strcmp0 (camel_mapi_settings_get_profile (settings), profile) == 0;
+}
+
+/* filters @esources thus the resulting list will contain ESource-s only for @profile;
+ free returned list with g_list_free_full (list, g_object_unref); */
+GList *
+e_mapi_utils_filter_sources_for_profile (const GList *esources,
+ const gchar *profile)
+{
+ GList *found = NULL;
+ const GList *iter;
+ ESource *master_source;
+
+ master_source = e_mapi_utils_get_master_source (esources, profile);
+ if (!master_source)
+ return NULL;
+
+ for (iter = esources; iter; iter = iter->next) {
+ ESource *source = iter->data;
+
+ if (is_for_profile (source, profile) ||
+ g_strcmp0 (e_source_get_uid (master_source), e_source_get_parent (source)) == 0)
+ found = g_list_prepend (found, g_object_ref (source));
+ }
+
+ return g_list_reverse (found);
+}
+
+/* returns (not-reffed) member of @esources, which is for @profile and @folder_id */
+ESource *
+e_mapi_utils_get_source_for_folder (const GList *esources,
+ const gchar *profile,
+ mapi_id_t folder_id)
+{
+ ESource *master_source;
+ const GList *iter;
+
+ master_source = e_mapi_utils_get_master_source (esources, profile);
+ if (!master_source)
+ return NULL;
+
+ for (iter = esources; iter; iter = iter->next) {
+ ESource *source = iter->data;
+
+ if ((is_for_profile (source, profile) ||
+ g_strcmp0 (e_source_get_uid (master_source), e_source_get_parent (source)) == 0) &&
+ e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER)) {
+ ESourceMapiFolder *folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+
+ g_return_val_if_fail (folder_ext != NULL, NULL);
+
+ if (e_source_mapi_folder_get_id (folder_ext) == folder_id)
+ return source;
+ }
+ }
+
+ return NULL;
+}
+
+/* returns (not-reffed) member of @esources, which is master (with no parent) source for @profile */
+ESource *
+e_mapi_utils_get_master_source (const GList *esources,
+ const gchar *profile)
+{
+ const GList *iter;
+
+ for (iter = esources; iter; iter = iter->next) {
+ ESource *source = iter->data;
+
+ if (!e_source_get_parent (source) &&
+ is_for_profile (source, profile))
+ return source;
+ }
+
+ return NULL;
+}
diff --git a/src/libexchangemapi/e-mapi-utils.h b/src/libexchangemapi/e-mapi-utils.h
index 1e66f70..f9577c2 100644
--- a/src/libexchangemapi/e-mapi-utils.h
+++ b/src/libexchangemapi/e-mapi-utils.h
@@ -24,6 +24,8 @@
#ifndef E_MAPI_UTILS_H
#define E_MAPI_UTILS_H
+#include <libedataserver/libedataserver.h>
+
#include "camel-mapi-settings.h"
#include "e-mapi-debug.h"
#include "e-mapi-connection.h"
@@ -128,4 +130,13 @@ gboolean e_mapi_utils_copy_to_mapi_SPropValue (TALLOC_CTX *mem_ctx,
void e_mapi_utils_unref_in_thread (GObject *object);
+GList * e_mapi_utils_filter_sources_for_profile (const GList *esources,
+ const gchar *profile);
+
+ESource * e_mapi_utils_get_source_for_folder (const GList *esources,
+ const gchar *profile,
+ mapi_id_t folder_id);
+
+ESource * e_mapi_utils_get_master_source (const GList *esources,
+ const gchar *profile);
#endif
diff --git a/src/libexchangemapi/e-source-mapi-folder.c b/src/libexchangemapi/e-source-mapi-folder.c
new file mode 100644
index 0000000..06d2e7b
--- /dev/null
+++ b/src/libexchangemapi/e-source-mapi-folder.c
@@ -0,0 +1,488 @@
+/*
+ * e-source-mapi-folder.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-source-mapi-folder.h"
+
+#define E_SOURCE_MAPI_FOLDER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolderPrivate))
+
+struct _ESourceMapiFolderPrivate {
+ GMutex *property_lock;
+ guint64 fid;
+ guint64 parent_fid;
+ gboolean is_public;
+ gboolean server_notification;
+ gchar *foreign_username;
+ gboolean allow_partial;
+ gint partial_count;
+};
+
+enum {
+ PROP_0,
+ PROP_ID,
+ PROP_PARENT_ID,
+ PROP_IS_PUBLIC,
+ PROP_SERVER_NOTIFICATION,
+ PROP_FOREIGN_USERNAME,
+ PROP_ALLOW_PARTIAL,
+ PROP_PARTIAL_COUNT
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+ ESourceMapiFolder,
+ e_source_mapi_folder,
+ E_TYPE_SOURCE_EXTENSION)
+
+static void
+source_mapi_folder_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ID:
+ e_source_mapi_folder_set_id (
+ E_SOURCE_MAPI_FOLDER (object),
+ g_value_get_uint64 (value));
+ return;
+
+ case PROP_PARENT_ID:
+ e_source_mapi_folder_set_parent_id (
+ E_SOURCE_MAPI_FOLDER (object),
+ g_value_get_uint64 (value));
+ return;
+
+ case PROP_IS_PUBLIC:
+ e_source_mapi_folder_set_is_public (
+ E_SOURCE_MAPI_FOLDER (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SERVER_NOTIFICATION:
+ e_source_mapi_folder_set_server_notification (
+ E_SOURCE_MAPI_FOLDER (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_FOREIGN_USERNAME:
+ e_source_mapi_folder_set_foreign_username (
+ E_SOURCE_MAPI_FOLDER (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_ALLOW_PARTIAL:
+ e_source_mapi_folder_set_allow_partial (
+ E_SOURCE_MAPI_FOLDER (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_PARTIAL_COUNT:
+ e_source_mapi_folder_set_partial_count (
+ E_SOURCE_MAPI_FOLDER (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_mapi_folder_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ID:
+ g_value_set_uint64 (
+ value,
+ e_source_mapi_folder_get_id (
+ E_SOURCE_MAPI_FOLDER (object)));
+ return;
+
+ case PROP_PARENT_ID:
+ g_value_set_uint64 (
+ value,
+ e_source_mapi_folder_get_parent_id (
+ E_SOURCE_MAPI_FOLDER (object)));
+ return;
+
+ case PROP_IS_PUBLIC:
+ g_value_set_boolean (
+ value,
+ e_source_mapi_folder_is_public (
+ E_SOURCE_MAPI_FOLDER (object)));
+ return;
+
+ case PROP_SERVER_NOTIFICATION:
+ g_value_set_boolean (
+ value,
+ e_source_mapi_folder_get_server_notification (
+ E_SOURCE_MAPI_FOLDER (object)));
+ return;
+
+ case PROP_FOREIGN_USERNAME:
+ g_value_take_string (
+ value,
+ e_source_mapi_folder_dup_foreign_username (
+ E_SOURCE_MAPI_FOLDER (object)));
+ return;
+
+ case PROP_ALLOW_PARTIAL:
+ g_value_set_boolean (
+ value,
+ e_source_mapi_folder_get_allow_partial (
+ E_SOURCE_MAPI_FOLDER (object)));
+ return;
+
+ case PROP_PARTIAL_COUNT:
+ g_value_set_int (
+ value,
+ e_source_mapi_folder_get_partial_count (
+ E_SOURCE_MAPI_FOLDER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_mapi_folder_finalize (GObject *object)
+{
+ ESourceMapiFolderPrivate *priv;
+
+ priv = E_SOURCE_MAPI_FOLDER_GET_PRIVATE (object);
+
+ g_mutex_free (priv->property_lock);
+
+ g_free (priv->foreign_username);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_source_mapi_folder_parent_class)->finalize (object);
+}
+
+static void
+e_source_mapi_folder_class_init (ESourceMapiFolderClass *class)
+{
+ GObjectClass *object_class;
+ ESourceExtensionClass *extension_class;
+
+ g_type_class_add_private (class, sizeof (ESourceMapiFolderPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = source_mapi_folder_set_property;
+ object_class->get_property = source_mapi_folder_get_property;
+ object_class->finalize = source_mapi_folder_finalize;
+
+ extension_class = E_SOURCE_EXTENSION_CLASS (class);
+ extension_class->name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ID,
+ g_param_spec_uint64 (
+ "id",
+ "ID",
+ "The server-assigned folder ID",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PARENT_ID,
+ g_param_spec_uint64 (
+ "parent-id",
+ "Parent ID",
+ "The server-assigned folder's parent ID",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IS_PUBLIC,
+ g_param_spec_boolean (
+ "is-public",
+ "Is Public",
+ "Folder is a public folder",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SERVER_NOTIFICATION,
+ g_param_spec_boolean (
+ "server-notification",
+ "Server Notification",
+ "Whether to listen for server notifications on this folder",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FOREIGN_USERNAME,
+ g_param_spec_string (
+ "foreign-username",
+ "Foreign Username",
+ "Set for folders belonging to other (foreign) users",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ALLOW_PARTIAL,
+ g_param_spec_boolean (
+ "allow-partial",
+ "Allow Partial",
+ "Allow Partial fetching for GAL",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PARTIAL_COUNT,
+ g_param_spec_int (
+ "partial-count",
+ "Partial Count",
+ "Count of contacts for Partial fetching of GAL",
+ G_MININT, G_MAXINT, 50,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+}
+
+static void
+e_source_mapi_folder_class_finalize (ESourceMapiFolderClass *class)
+{
+}
+
+static void
+e_source_mapi_folder_init (ESourceMapiFolder *extension)
+{
+ extension->priv = E_SOURCE_MAPI_FOLDER_GET_PRIVATE (extension);
+ extension->priv->property_lock = g_mutex_new ();
+
+ extension->priv->fid = 0;
+ extension->priv->parent_fid = 0;
+ extension->priv->is_public = FALSE;
+ extension->priv->server_notification = FALSE;
+ extension->priv->foreign_username = NULL;
+ extension->priv->allow_partial = TRUE;
+ extension->priv->partial_count = 50;
+}
+
+void
+e_source_mapi_folder_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_source_mapi_folder_register_type (type_module);
+}
+
+guint64
+e_source_mapi_folder_get_id (ESourceMapiFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), 0);
+
+ return extension->priv->fid;
+}
+
+void
+e_source_mapi_folder_set_id (ESourceMapiFolder *extension,
+ guint64 id)
+{
+ g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+ if (extension->priv->fid == id)
+ return;
+
+ extension->priv->fid = id;
+
+ g_object_notify (G_OBJECT (extension), "id");
+}
+
+guint64
+e_source_mapi_folder_get_parent_id (ESourceMapiFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), 0);
+
+ return extension->priv->parent_fid;
+}
+
+void
+e_source_mapi_folder_set_parent_id (ESourceMapiFolder *extension,
+ guint64 id)
+{
+ g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+ if (extension->priv->parent_fid == id)
+ return;
+
+ extension->priv->parent_fid = id;
+
+ g_object_notify (G_OBJECT (extension), "parent-id");
+}
+
+gboolean
+e_source_mapi_folder_is_public (ESourceMapiFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+ return extension->priv->is_public;
+}
+
+void
+e_source_mapi_folder_set_is_public (ESourceMapiFolder *extension,
+ gboolean is_public)
+{
+ g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+ if ((extension->priv->is_public ? 1 : 0) == (is_public ? 1 : 0))
+ return;
+
+ extension->priv->is_public = is_public;
+
+ g_object_notify (G_OBJECT (extension), "is-public");
+}
+
+gboolean
+e_source_mapi_folder_get_allow_partial (ESourceMapiFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+ return extension->priv->allow_partial;
+}
+
+void
+e_source_mapi_folder_set_allow_partial (ESourceMapiFolder *extension,
+ gboolean allow_partial)
+{
+ g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+ if ((extension->priv->allow_partial ? 1 : 0) == (allow_partial ? 1 : 0))
+ return;
+
+ extension->priv->allow_partial = allow_partial;
+
+ g_object_notify (G_OBJECT (extension), "allow-partial");
+}
+
+gint
+e_source_mapi_folder_get_partial_count (ESourceMapiFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+ return extension->priv->partial_count;
+}
+
+void
+e_source_mapi_folder_set_partial_count (ESourceMapiFolder *extension,
+ gint partial_count)
+{
+ g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+ if (extension->priv->partial_count == partial_count)
+ return;
+
+ extension->priv->partial_count = partial_count;
+
+ g_object_notify (G_OBJECT (extension), "partial-count");
+}
+
+gboolean
+e_source_mapi_folder_get_server_notification (ESourceMapiFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+ return extension->priv->server_notification;
+}
+
+void
+e_source_mapi_folder_set_server_notification (ESourceMapiFolder *extension,
+ gboolean server_notification)
+{
+ g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+ if ((extension->priv->server_notification ? 1 : 0) == (server_notification ? 1 : 0))
+ return;
+
+ extension->priv->server_notification = server_notification;
+
+ g_object_notify (G_OBJECT (extension), "server-notification");
+}
+
+const gchar *
+e_source_mapi_folder_get_foreign_username (ESourceMapiFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), NULL);
+
+ return extension->priv->foreign_username;
+}
+
+gchar *
+e_source_mapi_folder_dup_foreign_username (ESourceMapiFolder *extension)
+{
+ gchar *duplicate;
+
+ g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), NULL);
+
+ g_mutex_lock (extension->priv->property_lock);
+
+ duplicate = g_strdup (e_source_mapi_folder_get_foreign_username (extension));
+
+ g_mutex_unlock (extension->priv->property_lock);
+
+ return duplicate;
+}
+
+void
+e_source_mapi_folder_set_foreign_username (ESourceMapiFolder *extension,
+ const gchar *foreign_username)
+{
+ g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+ g_mutex_lock (extension->priv->property_lock);
+
+ if (foreign_username && !*foreign_username)
+ foreign_username = NULL;
+
+ if (g_strcmp0 (extension->priv->foreign_username, foreign_username) == 0) {
+ g_mutex_unlock (extension->priv->property_lock);
+ return;
+ }
+
+ g_free (extension->priv->foreign_username);
+ extension->priv->foreign_username = g_strdup (foreign_username);
+
+ g_mutex_unlock (extension->priv->property_lock);
+
+ g_object_notify (G_OBJECT (extension), "foreign-username");
+}
diff --git a/src/libexchangemapi/e-source-mapi-folder.h b/src/libexchangemapi/e-source-mapi-folder.h
new file mode 100644
index 0000000..4d7d620
--- /dev/null
+++ b/src/libexchangemapi/e-source-mapi-folder.h
@@ -0,0 +1,99 @@
+/*
+ * e-source-mapi-folder.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_SOURCE_MAPI_FOLDER_H
+#define E_SOURCE_MAPI_FOLDER_H
+
+#include <libedataserver/libedataserver.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOURCE_MAPI_FOLDER \
+ (e_source_mapi_folder_get_type ())
+#define E_SOURCE_MAPI_FOLDER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolder))
+#define E_SOURCE_MAPI_FOLDER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolderClass))
+#define E_IS_SOURCE_MAPI_FOLDER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SOURCE_MAPI_FOLDER))
+#define E_IS_SOURCE_MAPI_FOLDER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SOURCE_MAPI_FOLDER))
+#define E_SOURCE_MAPI_FOLDER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolderClass))
+
+#define E_SOURCE_EXTENSION_MAPI_FOLDER "Exchange MAPI Folder"
+
+G_BEGIN_DECLS
+
+typedef struct _ESourceMapiFolder ESourceMapiFolder;
+typedef struct _ESourceMapiFolderClass ESourceMapiFolderClass;
+typedef struct _ESourceMapiFolderPrivate ESourceMapiFolderPrivate;
+
+struct _ESourceMapiFolder {
+ ESourceExtension parent;
+ ESourceMapiFolderPrivate *priv;
+};
+
+struct _ESourceMapiFolderClass {
+ ESourceExtensionClass parent_class;
+};
+
+GType e_source_mapi_folder_get_type (void) G_GNUC_CONST;
+void e_source_mapi_folder_type_register (GTypeModule *type_module);
+
+guint64 e_source_mapi_folder_get_id (ESourceMapiFolder *extension);
+void e_source_mapi_folder_set_id (ESourceMapiFolder *extension,
+ guint64 id);
+
+guint64 e_source_mapi_folder_get_parent_id (ESourceMapiFolder *extension);
+void e_source_mapi_folder_set_parent_id (ESourceMapiFolder *extension,
+ guint64 id);
+
+gboolean e_source_mapi_folder_is_public (ESourceMapiFolder *extension);
+void e_source_mapi_folder_set_is_public (ESourceMapiFolder *extension,
+ gboolean is_public);
+
+gboolean e_source_mapi_folder_get_allow_partial (ESourceMapiFolder *extension);
+void e_source_mapi_folder_set_allow_partial (ESourceMapiFolder *extension,
+ gboolean allow_partial);
+
+gint e_source_mapi_folder_get_partial_count (ESourceMapiFolder *extension);
+void e_source_mapi_folder_set_partial_count (ESourceMapiFolder *extension,
+ gint partial_count);
+
+gboolean e_source_mapi_folder_get_server_notification
+ (ESourceMapiFolder *extension);
+void e_source_mapi_folder_set_server_notification
+ (ESourceMapiFolder *extension,
+ gboolean server_notification);
+
+const gchar * e_source_mapi_folder_get_foreign_username
+ (ESourceMapiFolder *extension);
+gchar * e_source_mapi_folder_dup_foreign_username
+ (ESourceMapiFolder *extension);
+void e_source_mapi_folder_set_foreign_username
+ (ESourceMapiFolder *extension,
+ const gchar *foreign_username);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_MAPI_FOLDER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]