diff options
author | Milan Crha <mcrha@redhat.com> | 2020-11-19 16:56:56 +0100 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2020-11-19 16:56:56 +0100 |
commit | 9f9f5c12f518db081010cacfcc982a15e1fed04d (patch) | |
tree | 5e3e8d89daaacf331d28a5c878f0ff41d0fc6ac1 | |
parent | 74fa03dc54b9c6e60bdcf6264cbb40da50677b6f (diff) | |
download | evolution-data-server-9f9f5c12f518db081010cacfcc982a15e1fed04d.tar.gz |
I#273 - Camel: Save folder changes periodically
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/273
-rw-r--r-- | src/camel/camel-folder.c | 133 | ||||
-rw-r--r-- | src/camel/camel-local-settings.h | 12 | ||||
-rw-r--r-- | src/camel/camel-offline-folder.c | 161 | ||||
-rw-r--r-- | src/camel/camel-offline-settings.c | 41 | ||||
-rw-r--r-- | src/camel/camel-offline-store.c | 22 | ||||
-rw-r--r-- | src/camel/camel-store-settings.c | 77 | ||||
-rw-r--r-- | src/camel/camel-store-settings.h | 5 | ||||
-rw-r--r-- | src/camel/camel-store.c | 31 | ||||
-rw-r--r-- | src/camel/camel-store.h | 6 | ||||
-rw-r--r-- | src/camel/camel-vee-store.c | 8 |
10 files changed, 289 insertions, 207 deletions
diff --git a/src/camel/camel-folder.c b/src/camel/camel-folder.c index a0e7c5c9e..f39ace33a 100644 --- a/src/camel/camel-folder.c +++ b/src/camel/camel-folder.c @@ -36,6 +36,7 @@ #include "camel-operation.h" #include "camel-session.h" #include "camel-store.h" +#include "camel-store-settings.h" #include "camel-vtrash-folder.h" #include "camel-string-utils.h" @@ -70,6 +71,10 @@ struct _CamelFolderPrivate { CamelThreeState mark_seen; gint mark_seen_timeout; + + GMutex store_changes_lock; + guint store_changes_id; + gboolean store_changes_after_frozen; }; struct _AsyncContext { @@ -133,6 +138,110 @@ G_DEFINE_BOXED_TYPE (CamelFolderQuotaInfo, camel_folder_quota_info_clone, camel_folder_quota_info_free) + +static void +folder_store_changes_job_cb (CamelSession *session, + GCancellable *cancellable, + gpointer user_data, + GError **error) +{ + CamelFolder *folder = user_data; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + + camel_folder_synchronize_sync (folder, FALSE, cancellable, error); +} + +static gboolean +folder_schedule_store_changes_job (gpointer user_data) +{ + CamelFolder *folder = user_data; + GSource *source; + + source = g_main_current_source (); + + if (g_source_is_destroyed (source)) + return FALSE; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); + + g_mutex_lock (&folder->priv->store_changes_lock); + + if (folder->priv->store_changes_id == g_source_get_id (source)) { + CamelSession *session; + CamelStore *parent_store; + + folder->priv->store_changes_id = 0; + + parent_store = camel_folder_get_parent_store (folder); + session = parent_store ? camel_service_ref_session (CAMEL_SERVICE (parent_store)) : NULL; + if (session) { + gchar *description; + + /* Translators: The first “%s” is replaced with an account name and the second “%s” + is replaced with a full path name. The spaces around “:” are intentional, as + the whole “%s : %s” is meant as an absolute identification of the folder. */ + description = g_strdup_printf (_("Storing changes in folder “%s : %s”"), + camel_service_get_display_name (CAMEL_SERVICE (parent_store)), + camel_folder_get_full_name (folder)); + + camel_session_submit_job (session, description, + folder_store_changes_job_cb, + g_object_ref (folder), g_object_unref); + + g_free (description); + } + + g_clear_object (&session); + } + + g_mutex_unlock (&folder->priv->store_changes_lock); + + return FALSE; +} + +static void +folder_maybe_schedule_folder_change_store (CamelFolder *folder) +{ + CamelStore *store; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + + g_mutex_lock (&folder->priv->store_changes_lock); + + if (folder->priv->store_changes_id) + g_source_remove (folder->priv->store_changes_id); + folder->priv->store_changes_id = 0; + folder->priv->store_changes_after_frozen = FALSE; + + if (camel_folder_is_frozen (folder)) { + folder->priv->store_changes_after_frozen = TRUE; + g_mutex_unlock (&folder->priv->store_changes_lock); + + return; + } + + store = camel_folder_get_parent_store (folder); + + if (store && camel_store_get_can_auto_save_changes (store)) { + CamelSettings *settings; + gint interval = -1; + + settings = camel_service_ref_settings (CAMEL_SERVICE (store)); + if (settings && CAMEL_IS_STORE_SETTINGS (settings)) + interval = camel_store_settings_get_store_changes_interval (CAMEL_STORE_SETTINGS (settings)); + g_clear_object (&settings); + + if (interval == 0) + folder_schedule_store_changes_job (folder); + else if (interval > 0) + folder->priv->store_changes_id = g_timeout_add_seconds (interval, + folder_schedule_store_changes_job, folder); + } + + g_mutex_unlock (&folder->priv->store_changes_lock); +} + static void async_context_free (AsyncContext *async_context) { @@ -190,6 +299,9 @@ folder_emit_changed_cb (gpointer user_data) g_signal_emit (folder, signals[CHANGED], 0, changes); + if (changes && changes->uid_changed && changes->uid_changed->len > 0) + folder_maybe_schedule_folder_change_store (folder); + camel_folder_change_info_free (changes); return FALSE; @@ -688,6 +800,12 @@ folder_dispose (GObject *object) folder->priv->parent_store = NULL; } + g_mutex_lock (&folder->priv->store_changes_lock); + if (folder->priv->store_changes_id) + g_source_remove (folder->priv->store_changes_id); + folder->priv->store_changes_id = 0; + g_mutex_unlock (&folder->priv->store_changes_lock); + /* Chain up to parent's dispose () method. */ G_OBJECT_CLASS (camel_folder_parent_class)->dispose (object); } @@ -712,6 +830,7 @@ folder_finalize (GObject *object) g_rec_mutex_clear (&priv->lock); g_mutex_clear (&priv->change_lock); + g_mutex_clear (&priv->store_changes_lock); /* Chain up to parent's finalize () method. */ G_OBJECT_CLASS (camel_folder_parent_class)->finalize (object); @@ -1019,6 +1138,18 @@ folder_thaw (CamelFolder *folder) if (folder->priv->summary) camel_folder_summary_save (folder->priv->summary, NULL); } + + if (!camel_folder_is_frozen (folder)) { + g_mutex_lock (&folder->priv->store_changes_lock); + if (folder->priv->store_changes_after_frozen) { + folder->priv->store_changes_after_frozen = FALSE; + g_mutex_unlock (&folder->priv->store_changes_lock); + + folder_maybe_schedule_folder_change_store (folder); + } else { + g_mutex_unlock (&folder->priv->store_changes_lock); + } + } } static gboolean @@ -1423,10 +1554,12 @@ camel_folder_init (CamelFolder *folder) folder->priv = camel_folder_get_instance_private (folder); folder->priv->frozen = 0; folder->priv->changed_frozen = camel_folder_change_info_new (); + folder->priv->store_changes_after_frozen = FALSE; g_rec_mutex_init (&folder->priv->lock); g_mutex_init (&folder->priv->change_lock); g_mutex_init (&folder->priv->property_lock); + g_mutex_init (&folder->priv->store_changes_lock); } G_DEFINE_QUARK (camel-folder-error-quark, camel_folder_error) diff --git a/src/camel/camel-local-settings.h b/src/camel/camel-local-settings.h index ea5b76cce..04c705e41 100644 --- a/src/camel/camel-local-settings.h +++ b/src/camel/camel-local-settings.h @@ -77,15 +77,15 @@ gchar * camel_local_settings_dup_path (CamelLocalSettings *settings); void camel_local_settings_set_path (CamelLocalSettings *settings, const gchar *path); gboolean camel_local_settings_get_filter_all - (CamelLocalSettings *settings); + (CamelLocalSettings *settings); void camel_local_settings_set_filter_all - (CamelLocalSettings *settings, - gboolean filter_all); + (CamelLocalSettings *settings, + gboolean filter_all); gboolean camel_local_settings_get_filter_junk - (CamelLocalSettings *settings); + (CamelLocalSettings *settings); void camel_local_settings_set_filter_junk - (CamelLocalSettings *settings, - gboolean filter_junk); + (CamelLocalSettings *settings, + gboolean filter_junk); G_END_DECLS diff --git a/src/camel/camel-offline-folder.c b/src/camel/camel-offline-folder.c index abaf7bd6a..270fd18b3 100644 --- a/src/camel/camel-offline-folder.c +++ b/src/camel/camel-offline-folder.c @@ -37,10 +37,6 @@ typedef struct _OfflineDownsyncData OfflineDownsyncData; struct _CamelOfflineFolderPrivate { CamelThreeState offline_sync; - GMutex store_changes_lock; - guint store_changes_id; - gboolean store_changes_after_frozen; - GMutex ongoing_downloads_lock; GHashTable *ongoing_downloads; /* gchar * UID ~> g_thread_self() */ }; @@ -234,112 +230,6 @@ offline_folder_downsync_background (CamelSession *session, } static void -offline_folder_store_changes_job_cb (CamelSession *session, - GCancellable *cancellable, - gpointer user_data, - GError **error) -{ - CamelFolder *folder = user_data; - - g_return_if_fail (CAMEL_IS_OFFLINE_FOLDER (folder)); - - camel_folder_synchronize_sync (folder, FALSE, cancellable, error); -} - -static gboolean -offline_folder_schedule_store_changes_job (gpointer user_data) -{ - CamelOfflineFolder *offline_folder = user_data; - GSource *source; - - source = g_main_current_source (); - - if (g_source_is_destroyed (source)) - return FALSE; - - g_return_val_if_fail (CAMEL_IS_OFFLINE_FOLDER (offline_folder), FALSE); - - g_mutex_lock (&offline_folder->priv->store_changes_lock); - if (offline_folder->priv->store_changes_id == g_source_get_id (source)) { - CamelSession *session; - CamelStore *parent_store; - - offline_folder->priv->store_changes_id = 0; - - parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (offline_folder)); - session = parent_store ? camel_service_ref_session (CAMEL_SERVICE (parent_store)) : NULL; - if (session) { - gchar *description; - - /* Translators: The first “%s” is replaced with an account name and the second “%s” - is replaced with a full path name. The spaces around “:” are intentional, as - the whole “%s : %s” is meant as an absolute identification of the folder. */ - description = g_strdup_printf (_("Storing changes in folder “%s : %s”"), - camel_service_get_display_name (CAMEL_SERVICE (parent_store)), - camel_folder_get_full_name (CAMEL_FOLDER (offline_folder))); - - camel_session_submit_job (session, description, - offline_folder_store_changes_job_cb, - g_object_ref (offline_folder), g_object_unref); - - g_free (description); - } - - g_clear_object (&session); - } - g_mutex_unlock (&offline_folder->priv->store_changes_lock); - - return FALSE; -} - -static void -offline_folder_maybe_schedule_folder_change_store (CamelOfflineFolder *offline_folder) -{ - CamelSession *session; - CamelStore *store; - - g_return_if_fail (CAMEL_IS_OFFLINE_FOLDER (offline_folder)); - - g_mutex_lock (&offline_folder->priv->store_changes_lock); - - if (offline_folder->priv->store_changes_id) - g_source_remove (offline_folder->priv->store_changes_id); - offline_folder->priv->store_changes_id = 0; - offline_folder->priv->store_changes_after_frozen = FALSE; - - if (camel_folder_is_frozen (CAMEL_FOLDER (offline_folder))) { - offline_folder->priv->store_changes_after_frozen = TRUE; - g_mutex_unlock (&offline_folder->priv->store_changes_lock); - - return; - } - - store = camel_folder_get_parent_store (CAMEL_FOLDER (offline_folder)); - session = store ? camel_service_ref_session (CAMEL_SERVICE (store)) : NULL; - - if (session && camel_session_get_online (session) && CAMEL_IS_OFFLINE_STORE (store) && - camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) { - CamelSettings *settings; - gint interval = -1; - - settings = camel_service_ref_settings (CAMEL_SERVICE (store)); - if (settings && CAMEL_IS_OFFLINE_SETTINGS (settings)) - interval = camel_offline_settings_get_store_changes_interval (CAMEL_OFFLINE_SETTINGS (settings)); - g_clear_object (&settings); - - if (interval == 0) - offline_folder_schedule_store_changes_job (offline_folder); - else if (interval > 0) - offline_folder->priv->store_changes_id = g_timeout_add_seconds (interval, - offline_folder_schedule_store_changes_job, offline_folder); - } - - g_clear_object (&session); - - g_mutex_unlock (&offline_folder->priv->store_changes_lock); -} - -static void offline_folder_changed (CamelFolder *folder, CamelFolderChangeInfo *changes) { @@ -380,9 +270,6 @@ offline_folder_changed (CamelFolder *folder, } g_object_unref (session); - - if (changes && changes->uid_changed && changes->uid_changed->len > 0) - offline_folder_maybe_schedule_folder_change_store (CAMEL_OFFLINE_FOLDER (folder)); } static void @@ -420,26 +307,10 @@ offline_folder_get_property (GObject *object, } static void -offline_folder_dispose (GObject *object) -{ - CamelOfflineFolder *offline_folder = CAMEL_OFFLINE_FOLDER (object); - - g_mutex_lock (&offline_folder->priv->store_changes_lock); - if (offline_folder->priv->store_changes_id) - g_source_remove (offline_folder->priv->store_changes_id); - offline_folder->priv->store_changes_id = 0; - g_mutex_unlock (&offline_folder->priv->store_changes_lock); - - /* Chain up to parent's method. */ - G_OBJECT_CLASS (camel_offline_folder_parent_class)->dispose (object); -} - -static void offline_folder_finalize (GObject *object) { CamelOfflineFolder *offline_folder = CAMEL_OFFLINE_FOLDER (object); - g_mutex_clear (&offline_folder->priv->store_changes_lock); g_mutex_clear (&offline_folder->priv->ongoing_downloads_lock); g_hash_table_destroy (offline_folder->priv->ongoing_downloads); @@ -448,31 +319,6 @@ offline_folder_finalize (GObject *object) G_OBJECT_CLASS (camel_offline_folder_parent_class)->finalize (object); } -static void -offline_folder_thaw (CamelFolder *folder) -{ - /* Chain up to parent's method. */ - CAMEL_FOLDER_CLASS (camel_offline_folder_parent_class)->thaw (folder); - - if (!camel_folder_is_frozen (folder)) { - CamelOfflineFolder *offline_folder; - - g_return_if_fail (CAMEL_IS_OFFLINE_FOLDER (folder)); - - offline_folder = CAMEL_OFFLINE_FOLDER (folder); - - g_mutex_lock (&offline_folder->priv->store_changes_lock); - if (offline_folder->priv->store_changes_after_frozen) { - offline_folder->priv->store_changes_after_frozen = FALSE; - g_mutex_unlock (&offline_folder->priv->store_changes_lock); - - offline_folder_maybe_schedule_folder_change_store (offline_folder); - } else { - g_mutex_unlock (&offline_folder->priv->store_changes_lock); - } - } -} - static gboolean offline_folder_downsync_sync (CamelOfflineFolder *offline, const gchar *expression, @@ -621,17 +467,12 @@ static void camel_offline_folder_class_init (CamelOfflineFolderClass *class) { GObjectClass *object_class; - CamelFolderClass *folder_class; object_class = G_OBJECT_CLASS (class); object_class->set_property = offline_folder_set_property; object_class->get_property = offline_folder_get_property; - object_class->dispose = offline_folder_dispose; object_class->finalize = offline_folder_finalize; - folder_class = CAMEL_FOLDER_CLASS (class); - folder_class->thaw = offline_folder_thaw; - class->downsync_sync = offline_folder_downsync_sync; g_object_class_install_property ( @@ -653,9 +494,7 @@ camel_offline_folder_init (CamelOfflineFolder *folder) { folder->priv = camel_offline_folder_get_instance_private (folder); - g_mutex_init (&folder->priv->store_changes_lock); g_mutex_init (&folder->priv->ongoing_downloads_lock); - folder->priv->store_changes_after_frozen = FALSE; folder->priv->offline_sync = CAMEL_THREE_STATE_INCONSISTENT; folder->priv->ongoing_downloads = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL); diff --git a/src/camel/camel-offline-settings.c b/src/camel/camel-offline-settings.c index ab41ffcb2..b78dd6d42 100644 --- a/src/camel/camel-offline-settings.c +++ b/src/camel/camel-offline-settings.c @@ -24,7 +24,6 @@ struct _CamelOfflineSettingsPrivate { gboolean stay_synchronized; - gint store_changes_interval; gboolean limit_by_age; CamelTimeUnit limit_unit; gint limit_value; @@ -33,7 +32,6 @@ struct _CamelOfflineSettingsPrivate { enum { PROP_0, PROP_STAY_SYNCHRONIZED, - PROP_STORE_CHANGES_INTERVAL, PROP_LIMIT_BY_AGE, PROP_LIMIT_UNIT, PROP_LIMIT_VALUE @@ -57,12 +55,6 @@ offline_settings_set_property (GObject *object, g_value_get_boolean (value)); return; - case PROP_STORE_CHANGES_INTERVAL: - camel_offline_settings_set_store_changes_interval ( - CAMEL_OFFLINE_SETTINGS (object), - g_value_get_int (value)); - return; - case PROP_LIMIT_BY_AGE: camel_offline_settings_set_limit_by_age ( CAMEL_OFFLINE_SETTINGS (object), @@ -99,13 +91,6 @@ offline_settings_get_property (GObject *object, CAMEL_OFFLINE_SETTINGS (object))); return; - case PROP_STORE_CHANGES_INTERVAL: - g_value_set_int ( - value, - camel_offline_settings_get_store_changes_interval ( - CAMEL_OFFLINE_SETTINGS (object))); - return; - case PROP_LIMIT_BY_AGE: g_value_set_boolean ( value, @@ -155,21 +140,6 @@ camel_offline_settings_class_init (CamelOfflineSettingsClass *class) g_object_class_install_property ( object_class, - PROP_STORE_CHANGES_INTERVAL, - g_param_spec_int ( - "store-changes-interval", - "Store Changes Interval", - "Interval, in seconds, to store folder changes", - G_MININT, - G_MAXINT, - 3, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_EXPLICIT_NOTIFY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property ( - object_class, PROP_LIMIT_BY_AGE, g_param_spec_boolean ( "limit-by-age", @@ -261,6 +231,7 @@ camel_offline_settings_set_stay_synchronized (CamelOfflineSettings *settings, g_object_notify (G_OBJECT (settings), "stay-synchronized"); } + /** * camel_offline_settings_get_store_changes_interval: * @settings: a #CamelOfflineSettings @@ -273,13 +244,12 @@ camel_offline_settings_set_stay_synchronized (CamelOfflineSettings *settings, * * Since: 3.18 **/ - gint camel_offline_settings_get_store_changes_interval (CamelOfflineSettings *settings) { g_return_val_if_fail (CAMEL_IS_OFFLINE_SETTINGS (settings), -1); - return settings->priv->store_changes_interval; + return camel_store_settings_get_store_changes_interval (CAMEL_STORE_SETTINGS (settings)); } /** @@ -299,12 +269,7 @@ camel_offline_settings_set_store_changes_interval (CamelOfflineSettings *setting { g_return_if_fail (CAMEL_IS_OFFLINE_SETTINGS (settings)); - if (settings->priv->store_changes_interval == interval) - return; - - settings->priv->store_changes_interval = interval; - - g_object_notify (G_OBJECT (settings), "store-changes-interval"); + camel_store_settings_set_store_changes_interval (CAMEL_STORE_SETTINGS (settings), interval); } /** diff --git a/src/camel/camel-offline-store.c b/src/camel/camel-offline-store.c index d58c3e2de..981a4d12e 100644 --- a/src/camel/camel-offline-store.c +++ b/src/camel/camel-offline-store.c @@ -110,6 +110,24 @@ offline_store_downsync_folders_thread (CamelSession *session, offline_store_downsync_folders_sync (store, cancellable, error); } +static gboolean +offline_store_get_can_auto_save_changes (CamelStore *store) +{ + CamelSession *session; + gboolean res; + + g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), FALSE); + + session = camel_service_ref_session (CAMEL_SERVICE (store)); + + res = session && camel_session_get_online (session) && + camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store)); + + g_clear_object (&session); + + return res; +} + static void offline_store_constructed (GObject *object) { @@ -164,6 +182,7 @@ camel_offline_store_class_init (CamelOfflineStoreClass *class) { GObjectClass *object_class; CamelServiceClass *service_class; + CamelStoreClass *store_class; object_class = G_OBJECT_CLASS (class); object_class->constructed = offline_store_constructed; @@ -173,6 +192,9 @@ camel_offline_store_class_init (CamelOfflineStoreClass *class) service_class = CAMEL_SERVICE_CLASS (class); service_class->settings_type = CAMEL_TYPE_OFFLINE_SETTINGS; + store_class = CAMEL_STORE_CLASS (class); + store_class->get_can_auto_save_changes = offline_store_get_can_auto_save_changes; + g_object_class_install_property ( object_class, PROP_ONLINE, diff --git a/src/camel/camel-store-settings.c b/src/camel/camel-store-settings.c index 1dc49d7ec..ce7d30965 100644 --- a/src/camel/camel-store-settings.c +++ b/src/camel/camel-store-settings.c @@ -19,11 +19,13 @@ struct _CamelStoreSettingsPrivate { gboolean filter_inbox; + gint store_changes_interval; }; enum { PROP_0, - PROP_FILTER_INBOX + PROP_FILTER_INBOX, + PROP_STORE_CHANGES_INTERVAL }; G_DEFINE_TYPE_WITH_PRIVATE ( @@ -43,6 +45,12 @@ store_settings_set_property (GObject *object, CAMEL_STORE_SETTINGS (object), g_value_get_boolean (value)); return; + + case PROP_STORE_CHANGES_INTERVAL: + camel_store_settings_set_store_changes_interval ( + CAMEL_STORE_SETTINGS (object), + g_value_get_int (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -61,6 +69,13 @@ store_settings_get_property (GObject *object, camel_store_settings_get_filter_inbox ( CAMEL_STORE_SETTINGS (object))); return; + + case PROP_STORE_CHANGES_INTERVAL: + g_value_set_int ( + value, + camel_store_settings_get_store_changes_interval ( + CAMEL_STORE_SETTINGS (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -87,6 +102,21 @@ camel_store_settings_class_init (CamelStoreSettingsClass *class) G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_STORE_CHANGES_INTERVAL, + g_param_spec_int ( + "store-changes-interval", + "Store Changes Interval", + "Interval, in seconds, to store folder changes", + G_MININT, + G_MAXINT, + 3, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_STATIC_STRINGS)); } static void @@ -137,3 +167,48 @@ camel_store_settings_set_filter_inbox (CamelStoreSettings *settings, g_object_notify (G_OBJECT (settings), "filter-inbox"); } + +/** + * camel_store_settings_get_store_changes_interval: + * @settings: a #CamelStoreSettings + * + * Returns the interval, in seconds, for the changes in the folder being + * saved automatically. 0 means immediately, while -1 means turning off + * automatic folder change saving. + * + * Returns: the interval for automatic store of folder changes + * + * Since: 3.38.2 + **/ +gint +camel_store_settings_get_store_changes_interval (CamelStoreSettings *settings) +{ + g_return_val_if_fail (CAMEL_IS_STORE_SETTINGS (settings), -1); + + return settings->priv->store_changes_interval; +} + +/** + * camel_store_settings_set_store_changes_interval: + * @settings: a #CamelStoreSettings + * @interval: the interval, in seconds + * + * Sets the interval, in seconds, for the changes in the folder being + * saved automatically. 0 means immediately, while -1 means turning off + * automatic folder change saving. + * + * Since: 3.38.2 + **/ +void +camel_store_settings_set_store_changes_interval (CamelStoreSettings *settings, + gint interval) +{ + g_return_if_fail (CAMEL_IS_STORE_SETTINGS (settings)); + + if (settings->priv->store_changes_interval == interval) + return; + + settings->priv->store_changes_interval = interval; + + g_object_notify (G_OBJECT (settings), "store-changes-interval"); +} diff --git a/src/camel/camel-store-settings.h b/src/camel/camel-store-settings.h index 010fa8692..fe9ec164a 100644 --- a/src/camel/camel-store-settings.h +++ b/src/camel/camel-store-settings.h @@ -76,6 +76,11 @@ gboolean camel_store_settings_get_filter_inbox void camel_store_settings_set_filter_inbox (CamelStoreSettings *settings, gboolean filter_inbox); +gint camel_store_settings_get_store_changes_interval + (CamelStoreSettings *settings); +void camel_store_settings_set_store_changes_interval + (CamelStoreSettings *settings, + gint interval); G_END_DECLS diff --git a/src/camel/camel-store.c b/src/camel/camel-store.c index 5c0ecfc21..11f032cc9 100644 --- a/src/camel/camel-store.c +++ b/src/camel/camel-store.c @@ -563,6 +563,12 @@ store_initable_init (GInitable *initable, return TRUE; } +static gboolean +store_get_can_auto_save_changes (CamelStore *store) +{ + return TRUE; +} + static void camel_store_class_init (CamelStoreClass *class) { @@ -586,6 +592,7 @@ camel_store_class_init (CamelStoreClass *class) class->get_trash_folder_sync = store_get_trash_folder_sync; class->synchronize_sync = store_synchronize_sync; class->initial_setup_sync = store_initial_setup_sync; + class->get_can_auto_save_changes = store_get_can_auto_save_changes; signals[FOLDER_CREATED] = g_signal_new ( "folder-created", @@ -3333,3 +3340,27 @@ camel_store_delete_cached_folder (CamelStore *store, camel_object_bag_remove (store->priv->folders, folder); g_object_unref (folder); } + +/** + * camel_store_get_can_auto_save_changes: + * @store: a #CamelStore + * + * Returns whether there can be done automatic save of folder changes. + * Default is TRUE. The descendants can overwrite it with CamelStoreClass::get_can_auto_save_changes(). + * + * Return: Whether there can be done automatic save of folder changes. + * + * Since: 3.38.2 + **/ +gboolean +camel_store_get_can_auto_save_changes (CamelStore *store) +{ + CamelStoreClass *klass; + + g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE); + + klass = CAMEL_STORE_GET_CLASS (store); + g_return_val_if_fail (klass != NULL, FALSE); + + return klass->get_can_auto_save_changes && klass->get_can_auto_save_changes (store); +} diff --git a/src/camel/camel-store.h b/src/camel/camel-store.h index 45c309ebf..76e2b791b 100644 --- a/src/camel/camel-store.h +++ b/src/camel/camel-store.h @@ -206,9 +206,11 @@ struct _CamelStoreClass { GHashTable *out_save_setup, GCancellable *cancellable, GError **error); + gboolean (*get_can_auto_save_changes) + (CamelStore *store); /* Padding for future expansion */ - gpointer reserved_methods[20]; + gpointer reserved_methods[19]; /* Signals */ void (*folder_created) (CamelStore *store, @@ -416,6 +418,8 @@ gboolean camel_store_maybe_run_db_maintenance void camel_store_delete_cached_folder (CamelStore *store, const gchar *folder_name); +gboolean camel_store_get_can_auto_save_changes + (CamelStore *store); G_END_DECLS diff --git a/src/camel/camel-vee-store.c b/src/camel/camel-vee-store.c index a8414b210..09bac5e4e 100644 --- a/src/camel/camel-vee-store.c +++ b/src/camel/camel-vee-store.c @@ -514,6 +514,13 @@ vee_store_rename_folder_sync (CamelStore *store, return TRUE; } +static gboolean +vee_store_get_can_auto_save_changes (CamelStore *store) +{ + /* Let only the real folder auto-save the changes */ + return FALSE; +} + static void camel_vee_store_class_init (CamelVeeStoreClass *class) { @@ -538,6 +545,7 @@ camel_vee_store_class_init (CamelVeeStoreClass *class) store_class->get_trash_folder_sync = vee_store_get_trash_folder_sync; store_class->delete_folder_sync = vee_store_delete_folder_sync; store_class->rename_folder_sync = vee_store_rename_folder_sync; + store_class->get_can_auto_save_changes = vee_store_get_can_auto_save_changes; g_object_class_install_property ( object_class, |