[evolution-mapi] Bug #668637 - May not be able to create books/calendars in offline
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Bug #668637 - May not be able to create books/calendars in offline
- Date: Fri, 27 Jan 2012 17:04:11 +0000 (UTC)
commit 987221e3f08cda8920e4d12f49d97a01b05d4eac
Author: Milan Crha <mcrha redhat com>
Date: Fri Jan 27 18:03:28 2012 +0100
Bug #668637 - May not be able to create books/calendars in offline
.../e-mapi-account-listener.c | 2 +-
.../e-mapi-account-settings.c | 148 ++-
src/account-setup-eplugin/e-mapi-account-setup.c | 969 +++++++++++++++-----
src/account-setup-eplugin/e-mapi-account-setup.h | 8 +
4 files changed, 831 insertions(+), 296 deletions(-)
---
diff --git a/src/account-setup-eplugin/e-mapi-account-listener.c b/src/account-setup-eplugin/e-mapi-account-listener.c
index c043885..3768069 100644
--- a/src/account-setup-eplugin/e-mapi-account-listener.c
+++ b/src/account-setup-eplugin/e-mapi-account-listener.c
@@ -949,7 +949,7 @@ update_account_sources_async (gpointer worker_data, gboolean cancelled, gpointer
csd->profile_name = g_strdup (profile);
csd->account = g_object_ref (account);
- g_timeout_add_seconds (1, check_for_account_conn_cb, csd);
+ g_timeout_add_seconds (5, check_for_account_conn_cb, csd);
}
camel_url_free (url);
diff --git a/src/account-setup-eplugin/e-mapi-account-settings.c b/src/account-setup-eplugin/e-mapi-account-settings.c
index 6aa4a85..235d436 100644
--- a/src/account-setup-eplugin/e-mapi-account-settings.c
+++ b/src/account-setup-eplugin/e-mapi-account-settings.c
@@ -48,6 +48,7 @@
#include <mail/em-folder-tree.h>
#include "e-mapi-account-listener.h"
+#include "e-mapi-account-setup.h"
#include "e-mapi-subscribe-foreign-folder.h"
#include "e-mapi-edit-folder-permissions.h"
@@ -68,26 +69,35 @@ typedef struct
GtkGrid *spinner_grid;
gchar *profile;
+ gchar *username;
+ gchar *host;
GSList *folder_list;
- EMapiConnection *conn;
+ GCancellable *cancellable;
+ GError *error;
} FolderSizeDialogData;
static gboolean
-fill_folder_size_dialog_cb (gpointer data)
+mapi_settings_get_folder_size_idle (gpointer user_data)
{
GtkWidget *widget;
GtkCellRenderer *renderer;
GtkListStore *store;
GtkTreeIter iter;
GtkBox *content_area;
- FolderSizeDialogData *dialog_data = (FolderSizeDialogData *)data;
+ 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 (dialog_data->spinner_grid));
+ gtk_widget_destroy (GTK_WIDGET (fsd->spinner_grid));
- if (dialog_data->folder_list) {
+ 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);
@@ -109,8 +119,8 @@ fill_folder_size_dialog_cb (gpointer data)
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (store));
/* Populate model with data */
- while (dialog_data->folder_list) {
- EMapiFolder *folder = (EMapiFolder *) dialog_data->folder_list->data;
+ for (fiter = fsd->folder_list; fiter; fiter = fiter->next) {
+ EMapiFolder *folder = fiter->data;
gchar *folder_size = g_format_size_for_display (folder->size);
gtk_list_store_append (store, &iter);
@@ -118,12 +128,16 @@ fill_folder_size_dialog_cb (gpointer data)
COL_FOLDERSIZE_NAME, folder->folder_name,
COL_FOLDERSIZE_SIZE, folder_size,
-1);
- dialog_data->folder_list = g_slist_next (dialog_data->folder_list);
+
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"));
}
@@ -131,91 +145,117 @@ fill_folder_size_dialog_cb (gpointer data)
gtk_widget_show_all (widget);
/* Pack into content_area */
- content_area = GTK_BOX (gtk_dialog_get_content_area (dialog_data->dialog));
+ content_area = GTK_BOX (gtk_dialog_get_content_area (fsd->dialog));
gtk_box_pack_start (content_area, widget, TRUE, TRUE, 6);
- if (dialog_data->conn)
- g_object_unref (dialog_data->conn);
+ cleanup:
+ e_mapi_folder_free_list (fsd->folder_list);
+ g_free (fsd->profile);
+ g_free (fsd->username);
+ g_free (fsd->host);
+ g_object_unref (fsd->cancellable);
+ g_clear_error (&fsd->error);
+ g_free (fsd);
return FALSE;
}
static gpointer
-mapi_settings_get_folder_size (gpointer data)
+mapi_settings_get_folder_size_thread (gpointer user_data)
{
- FolderSizeDialogData *dialog_data = (FolderSizeDialogData *)data;
+ FolderSizeDialogData *fsd = user_data;
+ EMapiConnection *conn;
+
+ g_return_val_if_fail (fsd != NULL, NULL);
+
+ fsd->folder_list = NULL;
+ conn = e_mapi_account_open_connection_for (GTK_WINDOW (fsd->dialog),
+ fsd->profile,
+ fsd->username,
+ fsd->host,
+ 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);
+ }
- dialog_data->folder_list = NULL;
- dialog_data->conn = e_mapi_connection_find (dialog_data->profile);
- if (dialog_data->conn && e_mapi_connection_connected (dialog_data->conn))
- dialog_data->folder_list = e_mapi_connection_peek_folders_list (dialog_data->conn);
+ if (conn)
+ g_object_unref (conn);
- g_timeout_add (100, fill_folder_size_dialog_cb, dialog_data);
+ g_idle_add (mapi_settings_get_folder_size_idle, fsd);
return NULL;
}
static void
-mapi_settings_run_folder_size_dialog (const gchar *profile, gpointer data)
+mapi_settings_run_folder_size_dialog (CamelMapiSettings *mapi_settings)
{
GtkBox *content_area;
- GtkWidget *spinner, *alignment;
+ GtkWidget *spinner, *alignment, *dialog;
GtkWidget *spinner_label;
- FolderSizeDialogData *dialog_data;
+ GCancellable *cancellable;
+ FolderSizeDialogData *fsd;
- dialog_data = g_new0 (FolderSizeDialogData, 1);
+ g_return_if_fail (mapi_settings != NULL);
- dialog_data->dialog = (GtkDialog *)gtk_dialog_new_with_buttons (_("Folder Size"), NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
- NULL);
+ dialog = gtk_dialog_new_with_buttons (_("Folder Size"), NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
+ NULL);
- gtk_window_set_default_size (GTK_WINDOW (dialog_data->dialog), 250, 300);
+ fsd = g_new0 (FolderSizeDialogData, 1);
+ fsd->dialog = GTK_DIALOG (dialog);
- content_area = GTK_BOX (gtk_dialog_get_content_area (dialog_data->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â"));
- dialog_data->spinner_grid = GTK_GRID (gtk_grid_new ());
- gtk_grid_set_column_spacing (dialog_data->spinner_grid, 6);
- gtk_grid_set_column_homogeneous (dialog_data->spinner_grid, FALSE);
- gtk_orientable_set_orientation (GTK_ORIENTABLE (dialog_data->spinner_grid), GTK_ORIENTATION_HORIZONTAL);
+ 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 (dialog_data->spinner_grid), alignment);
- gtk_container_add (GTK_CONTAINER (dialog_data->spinner_grid), spinner_label);
+ 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 (dialog_data->spinner_grid), TRUE, TRUE, 6);
- gtk_widget_show_all (GTK_WIDGET (dialog_data->dialog));
+ gtk_box_pack_start (content_area, GTK_WIDGET (fsd->spinner_grid), TRUE, TRUE, 6);
+ gtk_widget_show_all (GTK_WIDGET (fsd->dialog));
- dialog_data->profile = g_strdup (profile);
+ cancellable = g_cancellable_new ();
+ fsd->profile = g_strdup (camel_mapi_settings_get_profile (mapi_settings));
+ fsd->username = g_strdup (camel_network_settings_get_user (CAMEL_NETWORK_SETTINGS (mapi_settings)));
+ fsd->host = g_strdup (camel_network_settings_get_host (CAMEL_NETWORK_SETTINGS (mapi_settings)));
+ fsd->cancellable = g_object_ref (cancellable);
- /* Fetch folder list and size information in a thread */
- g_thread_create (mapi_settings_get_folder_size, dialog_data, FALSE, NULL);
+ g_return_if_fail (g_thread_create (mapi_settings_get_folder_size_thread, fsd, FALSE, NULL));
/* Start the dialog */
- gtk_dialog_run (dialog_data->dialog);
-
- gtk_widget_destroy (GTK_WIDGET (dialog_data->dialog));
+ gtk_dialog_run (GTK_DIALOG (dialog));
- g_free (dialog_data->profile);
- g_free (dialog_data);
+ g_cancellable_cancel (cancellable);
+ g_object_unref (cancellable);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
}
static void
folder_size_clicked (GtkButton *button,
CamelMapiSettings *mapi_settings)
{
- const gchar *profile;
-
- profile = camel_mapi_settings_get_profile (mapi_settings);
- mapi_settings_run_folder_size_dialog (profile, NULL);
+ mapi_settings_run_folder_size_dialog (mapi_settings);
}
static gchar *
@@ -271,12 +311,18 @@ action_folder_size_cb (GtkAction *action,
EShellView *shell_view)
{
gchar *profile;
+ CamelStore *store = NULL;
+ CamelMapiSettings *mapi_settings;
- profile = get_profile_name_from_folder_tree (shell_view, NULL, NULL);
- if (profile)
- mapi_settings_run_folder_size_dialog (profile, NULL);
+ profile = get_profile_name_from_folder_tree (shell_view, NULL, &store);
+ if (profile && store) {
+ mapi_settings = CAMEL_MAPI_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+ mapi_settings_run_folder_size_dialog (mapi_settings);
+ }
g_free (profile);
+ if (store)
+ g_object_unref (store);
}
static void
diff --git a/src/account-setup-eplugin/e-mapi-account-setup.c b/src/account-setup-eplugin/e-mapi-account-setup.c
index fd8af88..bbfaead 100644
--- a/src/account-setup-eplugin/e-mapi-account-setup.c
+++ b/src/account-setup-eplugin/e-mapi-account-setup.c
@@ -31,6 +31,7 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
+#include <libedataserver/e-flag.h>
#include <libedataserver/e-xml-hash-utils.h>
#include <libedataserver/e-credentials.h>
#include <libedataserverui/e-passwords.h>
@@ -38,7 +39,6 @@
#include <e-util/e-dialog-utils.h>
#include <e-util/e-plugin-util.h>
#include "mail/em-config.h"
-#include "e-mapi-account-setup.h"
#include <addressbook/gui/widgets/eab-config.h>
#include <calendar/gui/e-cal-config.h>
#include <shell/e-shell.h>
@@ -47,6 +47,8 @@
#include <e-mapi-connection.h>
#include <e-mapi-utils.h>
+#include "e-mapi-account-setup.h"
+
#define d(x)
gint e_plugin_lib_enable (EPlugin *ep, gint enable);
@@ -94,6 +96,16 @@ e_mapi_accounts_peek_config_listener ()
return config_listener;
}
+static gboolean
+e_mapi_test_is_online (void)
+{
+ EShell *shell;
+
+ shell = e_shell_get_default ();
+
+ return shell && e_shell_get_online (shell);
+}
+
enum {
COL_MAPI_FULL_NAME = 0,
COL_MAPI_ACCOUNT,
@@ -142,38 +154,29 @@ transform_boolean_to_security_method (GBinding *binding,
return TRUE;
}
-/* Callback for ProcessNetworkProfile. If we have more than one username,
- we need to let the user select. */
-static uint32_t
-create_profile_callback (struct SRowSet *rowset, gconstpointer data)
+struct ECreateProfileData
{
- struct SPropValue *lpProp_fullname, *lpProp_account;
+ 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;
- guint32 i, index = 0;
+ gint i, index = 0;
GtkTreeIter iter;
GtkListStore *store;
GtkCellRenderer *renderer;
GtkTreeSelection *selection;
GtkWidget *dialog, *view;
GtkBox *content_area;
- const gchar *username = (const gchar *)data;
- /* If we can find the exact username, then find & return its index. */
- for (i = 0; i < rowset->cRows; i++) {
- lpProp_account = get_SPropValue_SRow(&(rowset->aRow[i]), PR_ACCOUNT_UNICODE);
- if (!lpProp_account)
- lpProp_account = get_SPropValue_SRow(&(rowset->aRow[i]), PR_ACCOUNT);
+ g_return_val_if_fail (cpd != NULL, FALSE);
- if (lpProp_account && lpProp_account->value.lpszA &&
- !g_strcmp0 (username, lpProp_account->value.lpszA))
- return i;
- }
-
- /* NOTE: A good way would be display the list of username entries */
- /* using GtkEntryCompletion in the username gtkentry. But plugins */
- /* as of now does not have access to it */
-
- /*TODO : Fix strings*/
dialog = gtk_dialog_new_with_buttons (_("Select username"),
NULL, GTK_DIALOG_MODAL,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
@@ -199,21 +202,16 @@ create_profile_callback (struct SRowSet *rowset, gconstpointer data)
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 < rowset->cRows; i++) {
- lpProp_fullname = get_SPropValue_SRow(&(rowset->aRow[i]), PR_DISPLAY_NAME_UNICODE);
- if (!lpProp_fullname)
- lpProp_fullname = get_SPropValue_SRow(&(rowset->aRow[i]), PR_DISPLAY_NAME);
- lpProp_account = get_SPropValue_SRow(&(rowset->aRow[i]), PR_ACCOUNT_UNICODE);
- if (!lpProp_account)
- lpProp_account = get_SPropValue_SRow(&(rowset->aRow[i]), PR_ACCOUNT);
-
- if (lpProp_fullname && lpProp_fullname->value.lpszA &&
- lpProp_account && lpProp_account->value.lpszA) {
+ 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, lpProp_fullname->value.lpszA,
- COL_MAPI_ACCOUNT, lpProp_account->value.lpszA,
+ COL_MAPI_FULL_NAME, fullname,
+ COL_MAPI_ACCOUNT, account,
COL_MAPI_INDEX, i, -1);
}
}
@@ -236,33 +234,188 @@ create_profile_callback (struct SRowSet *rowset, gconstpointer data)
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 = rowset->cRows + 1;
+ index = cpd->rowset->cRows + 1;
} else /* If we return a value > available, we are canceling the login.*/
- index = rowset->cRows + 1;
+ index = cpd->rowset->cRows + 1;
gtk_widget_destroy (dialog);
- return index;
+ 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 char*
-prompt_password(const gchar *user, const gchar *host, const gchar *key,
- EMConfigTargetSettings *account)
+static gchar *
+prompt_password (const gchar *user,
+ const gchar *host,
+ const gchar *key)
{
- guint32 pw_flags = E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET;
+ guint32 pw_flags = E_PASSWORDS_REMEMBER_FOREVER | E_PASSWORDS_SECRET;
gchar *password, *title;
gboolean save = TRUE;
title = g_strdup_printf (_("Enter Password for %s %s"), user, host);
- password = e_passwords_ask_password (title, NULL, key, title, pw_flags,
- &save, NULL);
+ password = e_passwords_ask_password (title, NULL, key, title, pw_flags, &save, NULL);
g_free (title);
return password;
}
+static GtkWindow *
+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;
+}
+
+struct EMapiValidateCredentialsData
+{
+ gchar *username;
+ gchar *password;
+ gchar *domain;
+ gchar *server;
+ gboolean use_ssl;
+ gboolean krb_sso;
+ gchar *krb_realm;
+ gchar *key;
+ CamelMapiSettings *mapi_settings;
+ gboolean success;
+};
+
+static void
+e_mapi_validate_credentials_data_free (gpointer ptr)
+{
+ struct EMapiValidateCredentialsData *vcd = ptr;
+
+ if (!vcd)
+ return;
+
+ g_free (vcd->username);
+ e_credentials_util_safe_free_string (vcd->password);
+ g_free (vcd->domain);
+ g_free (vcd->server);
+ g_free (vcd->krb_realm);
+ g_free (vcd->key);
+ g_object_unref (vcd->mapi_settings);
+ g_free (vcd);
+}
+
+static void
+validate_credentials_idle (GObject *button,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct EMapiValidateCredentialsData *vcd = user_data;
+
+ g_return_if_fail (vcd != NULL);
+
+ if (vcd->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)
+{
+ struct EMapiValidateCredentialsData *vcd = user_data;
+ EMapiProfileData empd;
+ gboolean status;
+ struct mapi_context *mapi_ctx = NULL;
+
+
+ g_return_if_fail (vcd != NULL);
+
+ empd.username = vcd->username;
+ empd.password = vcd->password;
+ empd.domain = vcd->domain;
+ empd.server = vcd->server;
+ empd.use_ssl = vcd->use_ssl;
+ empd.krb_sso = vcd->krb_sso;
+ empd.krb_realm = vcd->krb_realm;
+
+ 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 (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 (vcd->mapi_settings, profname);
+ g_free (profname);
+
+ vcd->success = TRUE;
+ } else {
+ e_passwords_forget_password (NULL, vcd->key);
+ }
+
+ e_mapi_utils_destroy_mapi_context (mapi_ctx);
+}
+
static void
-validate_credentials (GtkWidget *widget, EConfig *config)
+validate_credentials_cb (GtkWidget *widget,
+ EConfig *config)
{
EMConfigTargetSettings *target_account = (EMConfigTargetSettings *)(config->target);
CamelURL *url = NULL;
@@ -275,8 +428,8 @@ validate_credentials (GtkWidget *widget, EConfig *config)
const gchar *user;
GError *error = NULL;
- if (!e_shell_get_online (e_shell_get_default ())) {
- e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Cannot create MAPI folders in offline mode."));
+ if (!e_mapi_test_is_online ()) {
+ e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Cannot authenticate MAPI accounts in offline mode"));
return;
}
@@ -312,7 +465,7 @@ validate_credentials (GtkWidget *widget, EConfig *config)
return;
}
- url = g_malloc0 (sizeof (CamelURL));
+ url = camel_url_new ("dummy://", NULL);
camel_settings_save_to_url (settings, url);
key = camel_url_to_string (url, CAMEL_URL_HIDE_PARAMS);
camel_url_free (url);
@@ -320,55 +473,30 @@ validate_credentials (GtkWidget *widget, EConfig *config)
if (empd.krb_sso) {
e_mapi_util_trigger_krb_auth (&empd, &error);
} else {
- empd.password = prompt_password(empd.username, empd.server,
- key, target_account);
+ empd.password = prompt_password (empd.username, empd.server, key);
}
- if (COMPLETE_PROFILEDATA(&empd)) {
- gboolean status;
- struct mapi_context *mapi_ctx = NULL;
-
- status = e_mapi_utils_create_mapi_context (&mapi_ctx, &error);
- status = status && e_mapi_create_profile (mapi_ctx, &empd, (mapi_profile_callback_t) create_profile_callback, empd.username, NULL, &error);
- if (status) {
- /* 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 (profname, empd.password, NULL, &error);
- 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);
-
- e_notice (NULL, GTK_MESSAGE_INFO, "%s", _("Authentication finished successfully."));
- } else {
- gchar *e;
-
- e_passwords_forget_password (NULL, key);
-
- e = g_strconcat (_("Authentication failed."), "\n", error ? error->message : NULL, NULL);
-
- e_notice (NULL, GTK_MESSAGE_ERROR, "%s", e);
-
- g_free (e);
- }
-
- e_mapi_utils_destroy_mapi_context (mapi_ctx);
+ if (COMPLETE_PROFILEDATA (&empd)) {
+ struct EMapiValidateCredentialsData *vcd = g_new0 (struct EMapiValidateCredentialsData, 1);
+
+ vcd->username = g_strdup (empd.username);
+ vcd->password = g_strdup (empd.password);
+ vcd->domain = g_strdup (empd.domain);
+ vcd->server = g_strdup (empd.server);
+ vcd->use_ssl = empd.use_ssl;
+ vcd->krb_sso = empd.krb_sso;
+ vcd->krb_realm = g_strdup (empd.krb_realm);
+ vcd->key = g_strdup (key);
+ vcd->mapi_settings = g_object_ref (vcd->mapi_settings);
+ vcd->success = FALSE;
+
+ e_mapi_run_in_thread_with_feedback_modal (get_widget_toplevel_window (widget),
+ G_OBJECT (widget),
+ _("Connecting to a server, please wait..."),
+ validate_credentials_thread,
+ validate_credentials_idle,
+ vcd,
+ e_mapi_validate_credentials_data_free);
} else {
e_passwords_forget_password (NULL, key);
e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Authentication failed."));
@@ -377,7 +505,7 @@ validate_credentials (GtkWidget *widget, EConfig *config)
if (error)
g_error_free (error);
- g_free (empd.password);
+ e_credentials_util_safe_free_string (empd.password);
g_free (key);
}
@@ -419,7 +547,7 @@ org_gnome_e_mapi_account_setup (EPlugin *epl, EConfigHookItemFactoryData *data)
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), data->config);
+ g_signal_connect (auth_button, "clicked", G_CALLBACK (validate_credentials_cb), data->config);
gtk_table_attach (GTK_TABLE (data->parent), label, 0, 1, row, row+1, 0, 0, 0, 0);
gtk_widget_show_all (GTK_WIDGET (hgrid));
@@ -704,8 +832,119 @@ e_mapi_source_to_folder_category (ESource *source)
return E_MAPI_FOLDER_CATEGORY_PERSONAL;
}
+struct EMapiFolderStructureData
+{
+ EMapiFolderType folder_type;
+ GSList *folders;
+ GtkWidget *tree_view;
+ ESource *source;
+};
+
+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_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;
+ GtkTreeStore *tree_store;
+ ESource *source;
+
+ 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);
+ 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));
+
+ if (e_source_get_property (source, "folder-id")) {
+ mapi_id_t fid;
+
+ e_mapi_util_mapi_id_from_string (e_source_get_property (source, "folder-id"), &fid);
+
+ select_folder (GTK_TREE_MODEL (tree_store), fid, 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;
+ ESource *source;
+ EMapiConnection *conn;
+
+ 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);
+
+ conn = e_mapi_account_open_connection_for (NULL,
+ e_source_get_property (source, "profile"),
+ e_source_get_property (source, "username"),
+ e_source_get_property (source, "host"),
+ 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_run_in_thread_with_feedback (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;
+}
+
static GtkWidget *
-e_mapi_create (GtkWidget *parent, ESource *source, EMapiFolderType folder_type)
+e_mapi_create (GtkWidget *dialog,
+ GtkWidget *parent,
+ ESource *source,
+ EMapiFolderType folder_type)
{
GtkWidget *table, *label, *scroll, *tv;
gchar *uri_text, *profile = NULL;
@@ -715,9 +954,7 @@ e_mapi_create (GtkWidget *parent, ESource *source, EMapiFolderType folder_type)
GtkTreeStore *ts;
GtkTreeViewColumn *tvc;
const gchar *acc;
- GSList *folders;
- EMapiConnection *conn;
- mapi_id_t fid = 0;
+ gboolean is_new_source;
uri_text = e_source_get_uri (source);
if (uri_text && g_ascii_strncasecmp (uri_text, MAPI_URI_PREFIX, MAPI_PREFIX_LENGTH)) {
@@ -739,25 +976,29 @@ e_mapi_create (GtkWidget *parent, ESource *source, EMapiFolderType folder_type)
break;
}
- folders = NULL;
group = e_source_peek_group (source);
profile = g_strdup (e_source_get_property (source, "profile"));
- if (profile == NULL) {
+ is_new_source = e_source_get_property (source, "folder-id") == NULL;
+ if (is_new_source) {
+ gchar *tmp;
+
+ g_free (profile);
+
profile = e_source_group_get_property (group, "profile");
e_source_set_property (source, "profile", profile);
+
+ tmp = e_source_group_get_property (group, "username");
+ e_source_set_property (source, "username", tmp);
+ g_free (tmp);
+
+ tmp = e_source_group_get_property (group, "host");
+ e_source_set_property (source, "host", tmp);
+ g_free (tmp);
}
- conn = e_mapi_connection_find (profile);
g_free (profile);
- if (conn && e_mapi_connection_connected (conn))
- folders = e_mapi_connection_peek_folders_list (conn);
+
acc = e_source_group_peek_name (group);
ts = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_INT64, G_TYPE_POINTER);
-
- add_folders (folders, ts, folder_type);
-
- if (conn)
- g_object_unref (conn);
-
table = g_object_new (GTK_TYPE_TABLE, NULL);
if (folder_type == E_MAPI_FOLDER_TYPE_CONTACT) {
@@ -767,34 +1008,69 @@ e_mapi_create (GtkWidget *parent, ESource *source, EMapiFolderType folder_type)
gtk_table_attach (GTK_TABLE (parent), table, 0, 2, row, row + 1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
}
- label = gtk_label_new_with_mnemonic (_("_Location:"));
- gtk_widget_show (label);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ if (is_new_source && !e_mapi_test_is_online ()) {
+ const gchar *msg;
- rcell = gtk_cell_renderer_text_new ();
- tvc = gtk_tree_view_column_new_with_attributes (acc, rcell, "text", NAME_COL, NULL);
- tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ts));
- gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tvc);
- g_object_set (tv,"expander-column", tvc, "headers-visible", TRUE, NULL);
- gtk_tree_view_expand_all (GTK_TREE_VIEW (tv));
+ 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;
+ }
- if (e_source_get_property (source, "folder-id")) {
- e_mapi_util_mapi_id_from_string (e_source_get_property (source, "folder-id"), &fid);
- select_folder (GTK_TREE_MODEL (ts), fid, tv);
+ label = gtk_label_new (msg);
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ } else {
+ label = gtk_label_new_with_mnemonic (_("_Location:"));
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+
+ rcell = gtk_cell_renderer_text_new ();
+ tvc = gtk_tree_view_column_new_with_attributes (acc, rcell, "text", NAME_COL, NULL);
+ tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ts));
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tvc);
+ g_object_set (tv,"expander-column", tvc, "headers-visible", TRUE, NULL);
+ gtk_widget_set_sensitive (tv, is_new_source);
+
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+ g_object_set (scroll, "height-request", 150, NULL);
+ gtk_container_add (GTK_CONTAINER (scroll), tv);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), tv);
+ g_signal_connect (G_OBJECT (tv), "cursor-changed", G_CALLBACK (e_mapi_cursor_change), source);
+ gtk_widget_show_all (scroll);
+
+ gtk_table_attach (GTK_TABLE (table), scroll, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+
+ if (e_mapi_test_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 (tv);
+ fsd->source = g_object_ref (source);
+
+ g_idle_add (e_mapi_invoke_folder_structure_download_idle, fsd);
+ }
}
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
- g_object_set (scroll, "height-request", 150, NULL);
- gtk_container_add (GTK_CONTAINER (scroll), tv);
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), tv);
- g_signal_connect (G_OBJECT (tv), "cursor-changed", G_CALLBACK (e_mapi_cursor_change), source);
- gtk_widget_show_all (scroll);
-
- gtk_table_attach (GTK_TABLE (table), scroll, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
-
gtk_widget_show_all (table);
return table;
@@ -805,7 +1081,7 @@ e_mapi_create_addressbook (EPlugin *epl, EConfigHookItemFactoryData *data)
{
EABConfigTargetSource *t = (EABConfigTargetSource *) data->target;
- return e_mapi_create (data->parent, t->source, E_MAPI_FOLDER_TYPE_CONTACT);
+ return e_mapi_create (data->target->widget, data->parent, t->source, E_MAPI_FOLDER_TYPE_CONTACT);
}
GtkWidget *
@@ -828,7 +1104,7 @@ e_mapi_create_calendar (EPlugin *epl, EConfigHookItemFactoryData *data)
g_return_val_if_reached (NULL);
}
- return e_mapi_create (data->parent, t->source, folder_type);
+ return e_mapi_create (data->target->widget, data->parent, t->source, folder_type);
}
gboolean
@@ -849,6 +1125,10 @@ e_mapi_book_check (EPlugin *epl, EConfigHookPageCheckData *data)
g_free (uri_text);
+ if (!e_source_get_property (source, "folder-id") &&
+ !e_mapi_test_is_online ())
+ return FALSE;
+
/* does not have a parent-fid which is needed for folder creation on server */
return e_source_get_property (source, "parent-fid") ||
e_source_get_property (source, "foreign-username") ||
@@ -886,86 +1166,192 @@ emas_open_folder (ESource *source,
return res;
}
-void
-e_mapi_book_commit (EPlugin *epl, EConfigTarget *target)
+struct EMapiCreateFolderData
{
- EABConfigTargetSource *t = (EABConfigTargetSource *) target;
- ESource *source = t->source;
- gchar *uri_text, *r_uri, *sfid;
- const gchar *kerberos = NULL;
- ESourceGroup *grp;
+ ESource *source;
+ gchar *folder_name;
+ gchar *folder_type;
+
+ gchar * (* create_error_string) (const gchar *folder_name, const GError *error);
+ mapi_id_t parent_fid;
+ mapi_id_t *created_fid;
+};
+
+static void
+e_mapi_create_folder_data_free (gpointer ptr)
+{
+ struct EMapiCreateFolderData *cfd = ptr;
+
+ if (!cfd)
+ return;
+
+ g_object_unref (cfd->source);
+ g_free (cfd->folder_name);
+ g_free (cfd->folder_type);
+ g_free (cfd);
+}
+
+static void
+e_mapi_create_folder_thread (GObject *source_obj,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct EMapiCreateFolderData *cfd = user_data;
EMapiConnection *conn;
mapi_id_t fid, pfid;
mapi_object_t obj_folder;
+ ESource *source;
GError *mapi_error = NULL;
- uri_text = e_source_get_uri (source);
- if (uri_text && g_ascii_strncasecmp (uri_text, MAPI_URI_PREFIX, MAPI_PREFIX_LENGTH))
- return;
+ g_return_if_fail (cfd != NULL);
+ g_return_if_fail (cfd->folder_name != NULL);
+ g_return_if_fail (cfd->folder_type != NULL);
+ g_return_if_fail (cfd->created_fid != NULL);
+ g_return_if_fail (source_obj != NULL);
- switch (e_mapi_source_to_folder_category (source)) {
- case E_MAPI_FOLDER_CATEGORY_FOREIGN:
- case E_MAPI_FOLDER_CATEGORY_PUBLIC:
- /* no extra changes for subscribed folders */
+ source = E_SOURCE (source_obj);
+ conn = e_mapi_account_open_connection_for (NULL,
+ e_source_get_property (source, "profile"),
+ e_source_get_property (source, "username"),
+ e_source_get_property (source, "host"),
+ cancellable,
+ perror);
+
+ if (!conn)
return;
- default:
- break;
- }
e_mapi_util_mapi_id_from_string (e_source_get_property (source, "parent-fid"), &pfid);
- /* the profile should be already connected */
- conn = e_mapi_connection_find (e_source_get_property (source, "profile"));
- g_return_if_fail (conn != NULL);
-
fid = 0;
- if (emas_open_folder (source, conn, pfid, &obj_folder, NULL, NULL)) {
- if (!e_mapi_connection_create_folder (conn, &obj_folder, e_source_peek_name (source), IPF_CONTACT, &fid, NULL, &mapi_error))
+ if (emas_open_folder (source, conn, pfid, &obj_folder, cancellable, &mapi_error)) {
+ if (!e_mapi_connection_create_folder (conn, &obj_folder, cfd->folder_name, cfd->folder_type, &fid, cancellable, &mapi_error))
fid = 0;
- e_mapi_connection_close_folder (conn, &obj_folder, NULL, NULL);
+ e_mapi_connection_close_folder (conn, &obj_folder, cancellable, &mapi_error);
}
g_object_unref (conn);
if (!fid) {
- if (mapi_error) {
- e_notice (NULL, GTK_MESSAGE_ERROR, _("Failed to create address book '%s': %s"), e_source_peek_name (source), mapi_error->message);
- g_error_free (mapi_error);
+ gchar *error_str;
+
+ if (cfd->create_error_string)
+ error_str = cfd->create_error_string (cfd->folder_name, mapi_error);
+ else if (mapi_error) {
+ error_str = g_strdup_printf (_("Failed to create folder '%s': %s"), cfd->folder_name, mapi_error->message);
} else {
- e_notice (NULL, GTK_MESSAGE_ERROR, _("Failed to create address book '%s'"), e_source_peek_name (source));
+ error_str = g_strdup_printf (_("Failed to create folder '%s'"), cfd->folder_name);
}
- return;
+ g_return_if_fail (error_str != NULL);
+
+ g_set_error_literal (perror, E_MAPI_ERROR, mapi_error ? mapi_error->code : MAPI_E_CALL_FAILED, error_str);
+
+ g_clear_error (&mapi_error);
+ g_free (error_str);
}
- sfid = e_mapi_util_mapi_id_to_string (fid);
- r_uri = g_strconcat (";", sfid, NULL);
- e_source_set_relative_uri (source, r_uri);
+ *cfd->created_fid = fid;
+}
+
+static gchar *
+create_book_error_string (const gchar *folder_name,
+ const GError *error)
+{
+ if (error)
+ return g_strdup_printf (_("Failed to create address book '%s': %s"), folder_name, error->message);
+
+ return g_strdup_printf (_("Failed to create address book '%s'"), folder_name);
+}
+
+void
+e_mapi_book_commit (EPlugin *epl, EConfigTarget *target)
+{
+ EABConfigTargetSource *t = (EABConfigTargetSource *) target;
+ ESource *source = t->source;
+ gchar *uri_text, *tmp;
+ ESourceGroup *grp;
+
+ uri_text = e_source_get_uri (source);
+ if (uri_text && g_ascii_strncasecmp (uri_text, MAPI_URI_PREFIX, MAPI_PREFIX_LENGTH))
+ return;
+
+ switch (e_mapi_source_to_folder_category (source)) {
+ case E_MAPI_FOLDER_CATEGORY_FOREIGN:
+ case E_MAPI_FOLDER_CATEGORY_PUBLIC:
+ /* no extra changes for subscribed folders */
+ return;
+ default:
+ break;
+ }
grp = e_source_peek_group (source);
e_source_set_property (source, "auth", "plain/password");
- e_source_set_property(source, "user", NULL);
- e_source_set_property(source, "username", e_source_group_get_property (grp, "username") ? e_source_group_get_property (grp, "username") : e_source_group_get_property (grp, "user"));
- e_source_set_property(source, "host", e_source_group_get_property (grp, "host"));
- e_source_set_property(source, "profile", e_source_group_get_property (grp, "profile"));
- e_source_set_property(source, "domain", e_source_group_get_property (grp, "domain"));
- e_source_set_property(source, "realm", e_source_group_get_property (grp, "realm"));
- kerberos = e_source_group_get_property (grp, "kerberos");
- e_source_set_property(source, "kerberos", kerberos);
- if (kerberos && g_str_equal (kerberos, "required")) {
+ e_source_set_property (source, "user", NULL);
+
+ tmp = e_source_group_get_property (grp, "username");
+ if (!tmp)
+ tmp = e_source_group_get_property (grp, "user");
+ e_source_set_property(source, "username", tmp);
+ g_free (tmp);
+
+ tmp = e_source_group_get_property (grp, "host");
+ e_source_set_property(source, "host", tmp);
+ g_free (tmp);
+
+ tmp = e_source_group_get_property (grp, "profile");
+ e_source_set_property(source, "profile", tmp);
+ g_free (tmp);
+
+ tmp = e_source_group_get_property (grp, "domain");
+ e_source_set_property(source, "domain", tmp);
+ g_free (tmp);
+
+ tmp = e_source_group_get_property (grp, "realm");
+ e_source_set_property(source, "realm", tmp);
+ g_free (tmp);
+
+ tmp = e_source_group_get_property (grp, "kerberos");
+ e_source_set_property (source, "kerberos", tmp);
+ if (tmp && g_str_equal (tmp, "required")) {
e_source_set_property (source, "auth", NULL);
e_source_set_property (source, "auth-type", NULL);
}
- e_source_set_relative_uri (source, g_strconcat (";",e_source_peek_name (source), NULL));
+ g_free (tmp);
e_source_set_property (source, "completion", "true");
- e_source_set_property (source, "public", "no");
- e_source_set_property (source, "folder-id", sfid);
-
- g_free (r_uri);
- g_free (sfid);
+ e_source_set_property (source, "public", NULL);
+
+ if (!e_source_get_property (source, "folder-id")) {
+ struct EMapiCreateFolderData *cfd;
+ gchar *r_uri, *sfid;
+ mapi_id_t fid = 0;
+
+ cfd = g_new0 (struct EMapiCreateFolderData, 1);
+ cfd->source = g_object_ref (source);
+ cfd->folder_name = g_strdup (e_source_peek_name (source));
+ cfd->folder_type = g_strdup (IPF_CONTACT);
+ cfd->create_error_string = create_book_error_string;
+ cfd->created_fid = &fid;
+
+ e_mapi_run_in_thread_with_feedback_modal (get_widget_toplevel_window (target->widget),
+ G_OBJECT (source),
+ _("Creating address book on a server, please wait..."),
+ e_mapi_create_folder_thread,
+ NULL,
+ cfd,
+ e_mapi_create_folder_data_free);
+
+ if (!fid)
+ return;
- return;
+ sfid = e_mapi_util_mapi_id_to_string (fid);
+ r_uri = g_strconcat (";", sfid, NULL);
+ e_source_set_relative_uri (source, r_uri);
+ e_source_set_property (source, "folder-id", sfid);
+ g_free (r_uri);
+ g_free (sfid);
+ }
}
/* New calendar/task list/memo list */
@@ -987,24 +1373,54 @@ e_mapi_cal_check (EPlugin *epl, EConfigHookPageCheckData *data)
g_free (uri_text);
+ if (!e_source_get_property (source, "folder-id") &&
+ !e_mapi_test_is_online ())
+ return FALSE;
+
return e_source_get_property (source, "parent-fid") ||
e_source_get_property (source, "foreign-username") ||
g_strcmp0 (e_source_get_property (source, "public"), "yes") == 0;
}
+static gchar *
+create_cal_error_string (const gchar *folder_name,
+ const GError *error)
+{
+ if (error)
+ return g_strdup_printf (_("Failed to create calendar '%s': %s"), folder_name, error->message);
+
+ return g_strdup_printf (_("Failed to create calendar '%s'"), folder_name);
+}
+
+static gchar *
+create_task_error_string (const gchar *folder_name,
+ const GError *error)
+{
+ if (error)
+ return g_strdup_printf (_("Failed to create task list '%s': %s"), folder_name, error->message);
+
+ return g_strdup_printf (_("Failed to create task list '%s'"), folder_name);
+}
+
+static gchar *
+create_memo_error_string (const gchar *folder_name,
+ const GError *error)
+{
+ if (error)
+ return g_strdup_printf (_("Failed to create memo list '%s': %s"), folder_name, error->message);
+
+ return g_strdup_printf (_("Failed to create memo list '%s'"), folder_name);
+}
+
void
e_mapi_cal_commit (EPlugin *epl, EConfigTarget *target)
{
- EMapiConnection *conn;
ECalConfigTargetSource *t = (ECalConfigTargetSource *) target;
ESourceGroup *group;
ESource *source = t->source;
- gchar *tmp, *sfid;
- mapi_id_t fid, pfid;
- mapi_object_t obj_folder;
+ gchar *tmp;
const gchar *type;
gchar *uri_text = e_source_get_uri (source);
- GError *mapi_error = NULL;
if (!uri_text || g_ascii_strncasecmp (uri_text, MAPI_URI_PREFIX, MAPI_PREFIX_LENGTH))
return;
@@ -1034,38 +1450,6 @@ e_mapi_cal_commit (EPlugin *epl, EConfigTarget *target)
return;
}
- e_mapi_util_mapi_id_from_string (e_source_get_property (source, "parent-fid"), &pfid);
-
- /* the profile should be already connected */
- conn = e_mapi_connection_find (e_source_get_property (source, "profile"));
- g_return_if_fail (conn != NULL);
-
- fid = 0;
- if (emas_open_folder (source, conn, pfid, &obj_folder, NULL, NULL)) {
- if (!e_mapi_connection_create_folder (conn, &obj_folder, e_source_peek_name (source), type, &fid, NULL, &mapi_error))
- fid = 0;
- e_mapi_connection_close_folder (conn, &obj_folder, NULL, NULL);
- }
-
- g_object_unref (conn);
-
- if (!fid) {
- if (mapi_error) {
- e_notice (NULL, GTK_MESSAGE_ERROR, _("Failed to create calendar '%s': %s"), e_source_peek_name (source), mapi_error->message);
- g_error_free (mapi_error);
- } else {
- e_notice (NULL, GTK_MESSAGE_ERROR, _("Failed to create calendar '%s'"), e_source_peek_name (source));
- }
-
- return;
- }
-
- sfid = e_mapi_util_mapi_id_to_string (fid);
- tmp = g_strconcat (";", sfid, NULL);
- e_source_set_relative_uri (source, tmp);
- g_free (tmp);
- g_free (sfid);
-
e_source_set_property (source, "auth", "1");
e_source_set_property (source, "auth-type", "plain/password");
e_source_set_property (source, "public", "no");
@@ -1100,12 +1484,6 @@ e_mapi_cal_commit (EPlugin *epl, EConfigTarget *target)
}
g_free (tmp);
- tmp = e_mapi_util_mapi_id_to_string (fid);
- e_source_set_property (source, "folder-id", tmp);
- g_free (tmp);
-
- e_source_set_property (source, "offline_sync", "0");
-
/* Delegatees can never create folders for delegators. So we can copy safely. */
tmp = e_source_group_get_property (group, "acl-user-name");
e_source_set_property (source, "acl-user-name", tmp);
@@ -1120,8 +1498,55 @@ e_mapi_cal_commit (EPlugin *epl, EConfigTarget *target)
e_source_set_property (source, "acl-owner-email", tmp);
g_free (tmp);
- // Update the folder list in the plugin and EMapiFolder
- return;
+ if (!e_source_get_property (source, "folder-id")) {
+ struct EMapiCreateFolderData *cfd;
+ const gchar *msg = NULL;
+ gchar *r_uri, *sfid;
+ mapi_id_t fid = 0;
+
+ cfd = g_new0 (struct EMapiCreateFolderData, 1);
+ cfd->source = g_object_ref (source);
+ cfd->folder_name = g_strdup (e_source_peek_name (source));
+ cfd->folder_type = g_strdup (type);
+ switch (t->source_type) {
+ case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
+ cfd->create_error_string = create_cal_error_string;
+ msg = _("Creating calendar on a server, please wait...");
+ break;
+ case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
+ cfd->create_error_string = create_task_error_string;
+ msg = _("Creating task list on a server, please wait...");
+ break;
+ case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
+ cfd->create_error_string = create_memo_error_string;
+ msg = _("Creating memo list on a server, please wait...");
+ break;
+ default:
+ g_warn_if_reached ();
+ msg = "???";
+ break;
+ }
+ cfd->created_fid = &fid;
+
+ e_mapi_run_in_thread_with_feedback_modal (get_widget_toplevel_window (target->widget),
+ G_OBJECT (source),
+ msg,
+ e_mapi_create_folder_thread,
+ NULL,
+ cfd,
+ e_mapi_create_folder_data_free);
+
+ if (!fid)
+ return;
+
+ sfid = e_mapi_util_mapi_id_to_string (fid);
+ r_uri = g_strconcat (";", sfid, NULL);
+ e_source_set_relative_uri (source, r_uri);
+ e_source_set_property (source, "folder-id", sfid);
+
+ g_free (r_uri);
+ g_free (sfid);
+ }
}
struct RunWithFeedbackData
@@ -1135,6 +1560,7 @@ struct RunWithFeedbackData
gpointer user_data;
GDestroyNotify free_user_data;
GError *error;
+ gboolean run_modal;
};
static void
@@ -1177,6 +1603,8 @@ run_with_feedback_idle (gpointer user_data)
gtk_widget_destroy (rfd->dialog);
rfd->dialog = NULL;
}
+ } else {
+ was_cancelled = TRUE;
}
if (!was_cancelled) {
@@ -1189,6 +1617,19 @@ run_with_feedback_idle (gpointer user_data)
return FALSE;
}
+static gboolean
+run_with_feedback_response_idle (gpointer user_data)
+{
+ struct RunWithFeedbackData *rfd = user_data;
+
+ g_return_val_if_fail (rfd != NULL, FALSE);
+
+ if (rfd->dialog)
+ gtk_dialog_response (GTK_DIALOG (rfd->dialog), GTK_RESPONSE_CLOSE);
+
+ return FALSE;
+}
+
static gpointer
run_with_feedback_thread (gpointer user_data)
{
@@ -1200,7 +1641,10 @@ run_with_feedback_thread (gpointer user_data)
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);
+ if (rfd->run_modal)
+ g_idle_add (run_with_feedback_response_idle, rfd);
+ else
+ g_idle_add (run_with_feedback_idle, rfd);
return NULL;
}
@@ -1212,20 +1656,24 @@ run_with_feedback_response_cb (GtkWidget *dialog,
{
g_return_if_fail (rfd != NULL);
- rfd->dialog = NULL;
+ if (!rfd->run_modal)
+ rfd->dialog = NULL;
+
g_cancellable_cancel (rfd->cancellable);
- gtk_widget_destroy (dialog);
+ if (!rfd->run_modal)
+ gtk_widget_destroy (dialog);
}
-void
-e_mapi_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)
+static void
+e_mapi_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;
@@ -1258,12 +1706,45 @@ e_mapi_run_in_thread_with_feedback (GtkWindow *parent,
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);
- gtk_widget_show (dialog);
+ if (run_modal) {
+ g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ run_with_feedback_idle (rfd);
+ } else {
+ gtk_widget_show (dialog);
+
+ g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+ }
+}
+
+void
+e_mapi_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_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, FALSE);
+}
- g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+void
+e_mapi_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_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, TRUE);
}
EMapiConnection *
diff --git a/src/account-setup-eplugin/e-mapi-account-setup.h b/src/account-setup-eplugin/e-mapi-account-setup.h
index 3239872..6d5d82e 100644
--- a/src/account-setup-eplugin/e-mapi-account-setup.h
+++ b/src/account-setup-eplugin/e-mapi-account-setup.h
@@ -47,6 +47,14 @@ void e_mapi_run_in_thread_with_feedback (GtkWindow *parent,
gpointer user_data,
GDestroyNotify free_user_data);
+void e_mapi_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_account_open_connection_for (GtkWindow *parent,
const gchar *login_profile,
const gchar *login_username,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]