[evolution-data-server] Bug 725320 - [Camel] Let the store preconfigure settings the first time
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 725320 - [Camel] Let the store preconfigure settings the first time
- Date: Fri, 22 Jan 2016 16:11:24 +0000 (UTC)
commit 1be0d6f2127802c093c4f089b675ab283d4cd3d3
Author: Milan Crha <mcrha redhat com>
Date: Fri Jan 22 17:10:03 2016 +0100
Bug 725320 - [Camel] Let the store preconfigure settings the first time
camel/camel-enums.h | 3 +-
camel/camel-offline-store.c | 2 +-
camel/camel-store.c | 185 +++++++++++++++++++++++++
camel/camel-store.h | 46 ++++++-
camel/providers/imapx/camel-imapx-store.c | 210 ++++++++++++++++++++++++++++-
docs/reference/camel/camel-sections.txt | 3 +
docs/reference/eds/eds-sections.txt | 2 +
libedataserver/e-source-mail-account.c | 71 ++++++++++-
libedataserver/e-source-mail-account.h | 5 +
9 files changed, 522 insertions(+), 5 deletions(-)
---
diff --git a/camel/camel-enums.h b/camel/camel-enums.h
index 022a482..5ca476f 100644
--- a/camel/camel-enums.h
+++ b/camel/camel-enums.h
@@ -410,7 +410,8 @@ typedef enum { /*< flags >*/
CAMEL_STORE_REAL_JUNK_FOLDER = 1 << 4,
CAMEL_STORE_CAN_EDIT_FOLDERS = 1 << 5,
CAMEL_STORE_USE_CACHE_DIR = 1 << 6,
- CAMEL_STORE_CAN_DELETE_FOLDERS_AT_ONCE = 1 << 7
+ CAMEL_STORE_CAN_DELETE_FOLDERS_AT_ONCE = 1 << 7,
+ CAMEL_STORE_SUPPORTS_INITIAL_SETUP = 1 << 8
} CamelStoreFlags;
/**
diff --git a/camel/camel-offline-store.c b/camel/camel-offline-store.c
index edec1ab..0965c76 100644
--- a/camel/camel-offline-store.c
+++ b/camel/camel-offline-store.c
@@ -180,7 +180,7 @@ camel_offline_store_set_online_sync (CamelOfflineStore *store,
g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), FALSE);
- if (store->priv->online == online)
+ if (camel_offline_store_get_online (store) == online)
return TRUE;
service = CAMEL_SERVICE (store);
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 1912081..fe42ad9 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -63,6 +63,7 @@ struct _AsyncContext {
gchar *folder_name_2;
gboolean expunge;
guint32 flags;
+ GHashTable *save_setup;
};
struct _SignalClosure {
@@ -95,6 +96,11 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (
static void
async_context_free (AsyncContext *async_context)
{
+ if (async_context->save_setup) {
+ g_hash_table_destroy (async_context->save_setup);
+ async_context->save_setup = NULL;
+ }
+
g_free (async_context->folder_name_1);
g_free (async_context->folder_name_2);
@@ -510,6 +516,15 @@ store_synchronize_sync (CamelStore *store,
}
static gboolean
+store_initial_setup_sync (CamelStore *store,
+ GHashTable *out_save_setup,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return TRUE;
+}
+
+static gboolean
store_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
@@ -579,6 +594,7 @@ camel_store_class_init (CamelStoreClass *class)
class->get_junk_folder_sync = store_get_junk_folder_sync;
class->get_trash_folder_sync = store_get_trash_folder_sync;
class->synchronize_sync = store_synchronize_sync;
+ class->initial_setup_sync = store_initial_setup_sync;
signals[FOLDER_CREATED] = g_signal_new (
"folder-created",
@@ -2919,6 +2935,175 @@ camel_store_synchronize_finish (CamelStore *store,
}
/**
+ * camel_store_initial_setup_sync:
+ * @store: a #CamelStore
+ * @out_save_setup: (out) (transfer container) (element-type utf8 utf8): setup values to save
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Runs initial setup for the @store. It's meant to preset some
+ * values the first time the account connects to the server after
+ * it had been created. The function should return %TRUE even if
+ * it didn't populate anything. The default implementation does
+ * just that.
+ *
+ * The save_setup result, if not %NULL, should be freed using
+ * g_hash_table_destroy(). It's not an error to have it %NULL,
+ * it only means the @store doesn't have anything to save.
+ * Both the key and the value in the hash are newly allocated
+ * UTF-8 strings, owned by the hash table.
+ *
+ * The @store advertises support of this function by including
+ * CAMEL_STORE_SUPPORTS_INITIAL_SETUP in CamelStore::flags.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 3.20
+ **/
+gboolean
+camel_store_initial_setup_sync (CamelStore *store,
+ GHashTable **out_save_setup,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GHashTable *save_setup;
+ CamelStoreClass *class;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (out_save_setup != NULL, FALSE);
+
+ *out_save_setup = NULL;
+
+ class = CAMEL_STORE_GET_CLASS (store);
+ g_return_val_if_fail (class->initial_setup_sync != NULL, FALSE);
+
+ save_setup = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ success = class->initial_setup_sync (store, save_setup, cancellable, error);
+
+ if (!success || !g_hash_table_size (save_setup)) {
+ g_hash_table_destroy (save_setup);
+ save_setup = NULL;
+ }
+
+ CAMEL_CHECK_GERROR (store, initial_setup_sync, success, error);
+
+ *out_save_setup = save_setup;
+
+ return success;
+}
+
+static void
+store_initial_setup_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ gboolean success;
+ AsyncContext *async_context;
+ GError *local_error = NULL;
+
+ async_context = (AsyncContext *) task_data;
+
+ success = camel_store_initial_setup_sync (
+ CAMEL_STORE (source_object),
+ &async_context->save_setup,
+ cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_boolean (task, success);
+ }
+}
+
+/**
+ * camel_store_initial_setup:
+ * @store: a #CamelStore
+ * @io_priority: the I/O priority of the request
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: data to pass to the callback function
+ *
+ * Runs initial setup for the @store asynchronously.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_store_initial_setup_finish() to get the result of the operation.
+ *
+ * The @store advertises support of this function by including
+ * CAMEL_STORE_SUPPORTS_INITIAL_SETUP in CamelStore::flags.
+ *
+ * Since: 3.20
+ **/
+void
+camel_store_initial_setup (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ AsyncContext *async_context;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ async_context = g_slice_new0 (AsyncContext);
+
+ task = g_task_new (store, cancellable, callback, user_data);
+ g_task_set_source_tag (task, camel_store_initial_setup);
+ g_task_set_priority (task, io_priority);
+
+ g_task_set_task_data (
+ task, async_context,
+ (GDestroyNotify) async_context_free);
+
+ g_task_run_in_thread (task, store_initial_setup_thread);
+
+ g_object_unref (task);
+}
+
+/**
+ * camel_store_initial_setup_finish:
+ * @store: a #CamelStore
+ * @result: a #GAsyncResult
+ * @out_save_setup: (out) (transfer container) (element-type utf8 utf8): setup values to save
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_store_initial_setup().
+ *
+ * The save_setup result, if not %NULL, should be freed using
+ * g_hash_table_destroy(). It's not an error to have it %NULL,
+ * it only means the @store doesn't have anything to save.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 3.20
+ **/
+gboolean
+camel_store_initial_setup_finish (CamelStore *store,
+ GAsyncResult *result,
+ GHashTable **out_save_setup,
+ GError **error)
+{
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+ g_return_val_if_fail (out_save_setup != NULL, FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, store), FALSE);
+
+ g_return_val_if_fail (
+ g_async_result_is_tagged (
+ result, camel_store_initial_setup), FALSE);
+
+ async_context = g_task_get_task_data (G_TASK (result));
+ *out_save_setup = async_context->save_setup;
+ async_context->save_setup = NULL;
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+/**
* camel_store_maybe_run_db_maintenance:
* @store: a #CamelStore instance
* @error: (allow-none): return location for a #GError, or %NULL
diff --git a/camel/camel-store.h b/camel/camel-store.h
index 028ce28..570f08c 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -61,6 +61,32 @@
#define CAMEL_STORE_ERROR \
(camel_store_error_quark ())
+/**
+ * @CAMEL_STORE_SETUP_ARCHIVE_FOLDER: Name of an Archive folder key
+ * @CAMEL_STORE_SETUP_DRAFTS_FOLDER: Name of a Drafts folder key
+ * @CAMEL_STORE_SETUP_SENT_FOLDER: Name of a Sent folder key
+ * @CAMEL_STORE_SETUP_TEMPLATES_FOLDER: Name of a Templates folder key
+ *
+ * Key names to a hash table with values to preset for the account used
+ * as in the camel_store_initial_setup_sync() function.
+ *
+ * The key name consists of up to four parts: Source:Extension:Property[:Type]
+ * Source can be 'Collection', 'Account', 'Submission', 'Transport', 'Backend'.
+ * Extension is any extension name; it's up to the key creator to make sure
+ * the extension belongs to that particular Source.
+ * Property is a property name in the Extension.
+ * Type is an optional letter describing the type of the value; if not set, then
+ * string is used. Available values are: 'b' for boolean, 'i' for integer,
+ * 's' for string, 'f' for folder full path.
+ * All the part values are case sensitive.
+ *
+ * Since: 3.20
+ **/
+#define CAMEL_STORE_SETUP_ARCHIVE_FOLDER "Account:Mail Account:archive-folder:f"
+#define CAMEL_STORE_SETUP_DRAFTS_FOLDER "Submission:Mail Composition:drafts-folder:f"
+#define CAMEL_STORE_SETUP_SENT_FOLDER "Submission:Mail Submission:sent-folder:f"
+#define CAMEL_STORE_SETUP_TEMPLATES_FOLDER "Submission:Mail Composition:templates-folder:f"
+
G_BEGIN_DECLS
/**
@@ -176,9 +202,13 @@ struct _CamelStoreClass {
gboolean expunge,
GCancellable *cancellable,
GError **error);
+ gboolean (*initial_setup_sync) (CamelStore *store,
+ GHashTable *save_setup,
+ GCancellable *cancellable,
+ GError **error);
/* Reserved slots for methods. */
- gpointer reserved_for_methods[21];
+ gpointer reserved_for_methods[20];
/* Signals */
void (*folder_created) (CamelStore *store,
@@ -355,6 +385,20 @@ void camel_store_synchronize (CamelStore *store,
gboolean camel_store_synchronize_finish (CamelStore *store,
GAsyncResult *result,
GError **error);
+gboolean camel_store_initial_setup_sync (CamelStore *store,
+ GHashTable **out_save_setup,
+ GCancellable *cancellable,
+ GError **error);
+void camel_store_initial_setup (CamelStore *store,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_store_initial_setup_finish
+ (CamelStore *store,
+ GAsyncResult *result,
+ GHashTable **out_save_setup,
+ GError **error);
gboolean camel_store_maybe_run_db_maintenance
(CamelStore *store,
GError **error);
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 148d53b..28d1a75 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -2230,6 +2230,213 @@ exit:
return success;
}
+static gchar *
+imapx_find_folder_for_initial_setup (CamelFolderInfo *root,
+ const gchar *path)
+{
+ CamelFolderInfo *finfo, *next;
+ gchar *folder_fullname = NULL;
+ gchar **path_parts;
+ gint ii;
+
+ if (!root || !path)
+ return NULL;
+
+ path_parts = g_strsplit (path, "/", -1);
+ if (!path_parts)
+ return NULL;
+
+ finfo = root;
+
+ for (ii = 0; path_parts[ii] && finfo; ii++) {
+ gchar *folded_path;
+
+ folded_path = g_utf8_casefold (path_parts[ii], -1);
+ if (!folded_path)
+ break;
+
+ for (next = NULL; finfo; finfo = finfo->next) {
+ gchar *folded_display_name;
+ gint cmp;
+
+ if ((finfo->flags & (CAMEL_FOLDER_NOSELECT | CAMEL_FOLDER_VIRTUAL)) != 0)
+ continue;
+
+ folded_display_name = g_utf8_casefold (finfo->display_name, -1);
+ if (!folded_display_name)
+ continue;
+
+ cmp = g_utf8_collate (folded_path, folded_display_name);
+
+ g_free (folded_display_name);
+
+ if (cmp == 0) {
+ next = finfo;
+ break;
+ }
+ }
+
+ g_free (folded_path);
+
+ finfo = next;
+ if (finfo) {
+ if (path_parts[ii + 1])
+ finfo = finfo->child;
+ else
+ folder_fullname = g_strdup (finfo->full_name);
+ }
+ }
+
+ g_strfreev (path_parts);
+
+ return folder_fullname;
+}
+
+static void
+imapx_check_initial_setup_group (CamelFolderInfo *finfo,
+ GHashTable *save_setup,
+ const gchar *main_key,
+ const gchar *additional_key,
+ const gchar *additional_key_value,
+ const gchar **names,
+ guint n_names)
+{
+ gchar *folder_fullname = NULL;
+ gint ii;
+
+ g_return_if_fail (finfo != NULL);
+ g_return_if_fail (save_setup != NULL);
+ g_return_if_fail (main_key != NULL);
+ g_return_if_fail (names != NULL);
+ g_return_if_fail (n_names > 0);
+
+ /* First check the folder names in the user's locale */
+ for (ii = 0; ii < n_names && !folder_fullname; ii++) {
+ gchar *name;
+
+ /* In the same level as the Inbox */
+ folder_fullname = imapx_find_folder_for_initial_setup (finfo, g_dpgettext2 (GETTEXT_PACKAGE,
"IMAPDefaults", names[ii]));
+
+ if (folder_fullname)
+ break;
+
+ /* as a subfolder of the Inbox */
+ name = g_strconcat ("INBOX/", g_dpgettext2 (GETTEXT_PACKAGE, "IMAPDefaults", names[ii]),
NULL);
+ folder_fullname = imapx_find_folder_for_initial_setup (finfo, name);
+ g_free (name);
+ }
+
+ /* Then repeat with the english name (as written in the code) */
+ for (ii = 0; ii < n_names && !folder_fullname; ii++) {
+ gchar *name;
+
+ /* Do not try the same folder name twice */
+ if (g_strcmp0 (g_dpgettext2 (GETTEXT_PACKAGE, "IMAPDefaults", names[ii]), names[ii]) == 0)
+ continue;
+
+ folder_fullname = imapx_find_folder_for_initial_setup (finfo, names[ii]);
+
+ if (folder_fullname)
+ break;
+
+ name = g_strconcat ("INBOX/", names[ii], NULL);
+ folder_fullname = imapx_find_folder_for_initial_setup (finfo, name);
+ g_free (name);
+ }
+
+ if (folder_fullname) {
+ g_hash_table_insert (save_setup,
+ g_strdup (main_key),
+ g_strdup (folder_fullname));
+
+ if (additional_key) {
+ g_hash_table_insert (save_setup,
+ g_strdup (additional_key),
+ g_strdup (additional_key_value));
+ }
+
+ g_free (folder_fullname);
+ }
+}
+
+static gboolean
+imapx_initial_setup_sync (CamelStore *store,
+ GHashTable *save_setup,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* Translators: The strings in "IMAPDefaults" context are folder names as can be presented
+ by the server; There's checked for the localized version of it and for the non-localized
+ version as well. It's always the folder name (eventually path) as provided by the server,
+ when returned in given localization. it can be checked semi-easily in the case of
+ the GMail variants, by changing the GMail interface language in the GMail Preferences. */
+ const gchar *draft_names[] = {
+ NC_("IMAPDefaults", "[Gmail]/Drafts"),
+ NC_("IMAPDefaults", "Drafts"),
+ NC_("IMAPDefaults", "Draft")
+ };
+ const gchar *sent_names[] = {
+ NC_("IMAPDefaults", "[Gmail]/Sent Mail"),
+ NC_("IMAPDefaults", "Sent"),
+ NC_("IMAPDefaults", "Sent Items")
+ };
+ const gchar *junk_names[] = {
+ NC_("IMAPDefaults", "[Gmail]/Spam"),
+ NC_("IMAPDefaults", "Junk"),
+ NC_("IMAPDefaults", "Junk E-mail"),
+ NC_("IMAPDefaults", "Junk Email"),
+ NC_("IMAPDefaults", "Spam"),
+ NC_("IMAPDefaults", "Bulk Mail")
+ };
+ const gchar *trash_names[] = {
+ NC_("IMAPDefaults", "[Gmail]/Trash"),
+ NC_("IMAPDefaults", "Trash"),
+ NC_("IMAPDefaults", "Deleted Items")
+ };
+ CamelFolderInfo *finfo;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (store), FALSE);
+ g_return_val_if_fail (save_setup != NULL, FALSE);
+
+ finfo = camel_store_get_folder_info_sync (store, NULL,
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL,
+ cancellable, &local_error);
+
+ if (!finfo) {
+ if (local_error) {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ imapx_check_initial_setup_group (finfo, save_setup,
+ CAMEL_STORE_SETUP_DRAFTS_FOLDER, NULL, NULL,
+ draft_names, G_N_ELEMENTS (draft_names));
+
+ imapx_check_initial_setup_group (finfo, save_setup,
+ CAMEL_STORE_SETUP_SENT_FOLDER, NULL, NULL,
+ sent_names, G_N_ELEMENTS (sent_names));
+
+ /* It's a folder path inside the account, thus not use the 'f' type, but the 's' type. */
+ imapx_check_initial_setup_group (finfo, save_setup,
+ "Backend:Imapx Backend:real-junk-path:s",
+ "Backend:Imapx Backend:use-real-junk-path:b", "true",
+ junk_names, G_N_ELEMENTS (junk_names));
+
+ /* It's a folder path inside the account, thus not use the 'f' type, but the 's' type. */
+ imapx_check_initial_setup_group (finfo, save_setup,
+ "Backend:Imapx Backend:real-trash-path:s",
+ "Backend:Imapx Backend:use-real-trash-path:b", "true",
+ trash_names, G_N_ELEMENTS (trash_names));
+
+ camel_folder_info_free (finfo);
+
+ return TRUE;
+}
+
static void
imapx_migrate_to_user_cache_dir (CamelService *service)
{
@@ -2273,7 +2480,7 @@ imapx_store_initable_init (GInitable *initable,
store = CAMEL_STORE (initable);
service = CAMEL_SERVICE (initable);
- store->flags |= CAMEL_STORE_USE_CACHE_DIR;
+ store->flags |= CAMEL_STORE_USE_CACHE_DIR | CAMEL_STORE_SUPPORTS_INITIAL_SETUP;
imapx_migrate_to_user_cache_dir (service);
/* Chain up to parent interface's init() method. */
@@ -2580,6 +2787,7 @@ camel_imapx_store_class_init (CamelIMAPXStoreClass *class)
store_class->create_folder_sync = imapx_store_create_folder_sync;
store_class->delete_folder_sync = imapx_store_delete_folder_sync;
store_class->rename_folder_sync = imapx_store_rename_folder_sync;
+ store_class->initial_setup_sync = imapx_initial_setup_sync;
class->mailbox_created = imapx_store_mailbox_created;
class->mailbox_renamed = imapx_store_mailbox_renamed;
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index 7125a8f..e663a3a 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -2133,6 +2133,9 @@ camel_store_rename_folder_finish
camel_store_synchronize_sync
camel_store_synchronize
camel_store_synchronize_finish
+camel_store_initial_setup_sync
+camel_store_initial_setup
+camel_store_initial_setup_finish
camel_store_maybe_run_db_maintenance
<SUBSECTION Standard>
CAMEL_STORE
diff --git a/docs/reference/eds/eds-sections.txt b/docs/reference/eds/eds-sections.txt
index 7e5d611..1733133 100644
--- a/docs/reference/eds/eds-sections.txt
+++ b/docs/reference/eds/eds-sections.txt
@@ -3416,6 +3416,8 @@ e_source_mail_account_set_identity_uid
e_source_mail_account_dup_archive_folder
e_source_mail_account_get_archive_folder
e_source_mail_account_set_archive_folder
+e_source_mail_account_get_needs_initial_setup
+e_source_mail_account_set_needs_initial_setup
<SUBSECTION Standard>
ESourceMailAccountPrivate
E_IS_SOURCE_MAIL_ACCOUNT
diff --git a/libedataserver/e-source-mail-account.c b/libedataserver/e-source-mail-account.c
index 1e0dce7..7679043 100644
--- a/libedataserver/e-source-mail-account.c
+++ b/libedataserver/e-source-mail-account.c
@@ -47,12 +47,14 @@
struct _ESourceMailAccountPrivate {
gchar *identity_uid;
gchar *archive_folder;
+ gboolean needs_initial_setup;
};
enum {
PROP_0,
PROP_IDENTITY_UID,
- PROP_ARCHIVE_FOLDER
+ PROP_ARCHIVE_FOLDER,
+ PROP_NEEDS_INITIAL_SETUP
};
G_DEFINE_TYPE (
@@ -78,6 +80,12 @@ source_mail_account_set_property (GObject *object,
E_SOURCE_MAIL_ACCOUNT (object),
g_value_get_string (value));
return;
+
+ case PROP_NEEDS_INITIAL_SETUP:
+ e_source_mail_account_set_needs_initial_setup (
+ E_SOURCE_MAIL_ACCOUNT (object),
+ g_value_get_boolean (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -103,6 +111,13 @@ source_mail_account_get_property (GObject *object,
e_source_mail_account_dup_archive_folder (
E_SOURCE_MAIL_ACCOUNT (object)));
return;
+
+ case PROP_NEEDS_INITIAL_SETUP:
+ g_value_set_boolean (
+ value,
+ e_source_mail_account_get_needs_initial_setup (
+ E_SOURCE_MAIL_ACCOUNT (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -163,6 +178,19 @@ e_source_mail_account_class_init (ESourceMailAccountClass *class)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS |
E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_NEEDS_INITIAL_SETUP,
+ g_param_spec_boolean (
+ "needs-initial-setup",
+ "Needs Initial Setup",
+ "Whether the account needs to do an initial setup",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
}
static void
@@ -336,3 +364,44 @@ e_source_mail_account_set_archive_folder (ESourceMailAccount *extension,
g_object_notify (G_OBJECT (extension), "archive-folder");
}
+
+/**
+ * e_source_mail_account_get_needs_initial_setup:
+ * @extension: an #ESourceMailAccount
+ *
+ * Check whether the mail account needs to do its initial setup.
+ *
+ * Returns: %TRUE, when the account needs to run its initial setup
+ *
+ * Since: 3.20
+ **/
+gboolean
+e_source_mail_account_get_needs_initial_setup (ESourceMailAccount *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_MAIL_ACCOUNT (extension), FALSE);
+
+ return extension->priv->needs_initial_setup;
+}
+
+/**
+ * e_source_mail_account_set_needs_initial_setup:
+ * @extension: an #ESourceMailAccount
+ * @needs_initial_setup: value to set
+ *
+ * Sets whether the account needs to run its initial setup.
+ *
+ * Since: 3.20
+ **/
+void
+e_source_mail_account_set_needs_initial_setup (ESourceMailAccount *extension,
+ gboolean needs_initial_setup)
+{
+ g_return_if_fail (E_IS_SOURCE_MAIL_ACCOUNT (extension));
+
+ if ((extension->priv->needs_initial_setup ? 1 : 0) == (needs_initial_setup ? 1 : 0))
+ return;
+
+ extension->priv->needs_initial_setup = needs_initial_setup;
+
+ g_object_notify (G_OBJECT (extension), "needs-initial-setup");
+}
diff --git a/libedataserver/e-source-mail-account.h b/libedataserver/e-source-mail-account.h
index 4095b28..e89e467 100644
--- a/libedataserver/e-source-mail-account.h
+++ b/libedataserver/e-source-mail-account.h
@@ -92,6 +92,11 @@ gchar * e_source_mail_account_dup_archive_folder
void e_source_mail_account_set_archive_folder
(ESourceMailAccount *extension,
const gchar *archive_folder);
+gboolean e_source_mail_account_get_needs_initial_setup
+ (ESourceMailAccount *extension);
+void e_source_mail_account_set_needs_initial_setup
+ (ESourceMailAccount *extension,
+ gboolean needs_initial_setup);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]