[evolution-data-server] I#138 - Notify clients when backend is refreshing its content



commit 28b0e26216001c1199d292a929a4889770ad21a6
Author: Milan Crha <mcrha redhat com>
Date:   Fri Aug 9 12:03:07 2019 +0200

    I#138 - Notify clients when backend is refreshing its content
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/138

 .../backends/ldap/e-book-backend-ldap.c            |  5 +-
 src/addressbook/libedata-book/e-book-backend.c     | 99 ++++++++++++++++++++++
 src/addressbook/libedata-book/e-book-backend.h     | 13 +++
 .../libedata-book/e-book-meta-backend.c            |  4 +
 src/addressbook/libedata-book/e-data-book-view.c   | 18 ++++
 src/addressbook/libedata-book/e-data-book-view.h   |  1 +
 src/calendar/libedata-cal/e-cal-backend.c          | 99 ++++++++++++++++++++++
 src/calendar/libedata-cal/e-cal-backend.h          | 13 +++
 src/calendar/libedata-cal/e-cal-meta-backend.c     |  4 +
 9 files changed, 255 insertions(+), 1 deletion(-)
---
diff --git a/src/addressbook/backends/ldap/e-book-backend-ldap.c 
b/src/addressbook/backends/ldap/e-book-backend-ldap.c
index 90500b633..af37eea9f 100644
--- a/src/addressbook/backends/ldap/e-book-backend-ldap.c
+++ b/src/addressbook/backends/ldap/e-book-backend-ldap.c
@@ -4690,8 +4690,10 @@ generate_cache_dtor (LDAPOp *op)
        g_free (contact_list_op);
 
        g_rec_mutex_lock (&eds_ldap_handler_lock);
-       if (ldap_backend && ldap_backend->priv)
+       if (ldap_backend && ldap_backend->priv) {
+               e_book_backend_foreach_view_notify_progress (E_BOOK_BACKEND (ldap_backend), TRUE, 0, NULL);
                ldap_backend->priv->generate_cache_in_progress = FALSE;
+       }
        g_rec_mutex_unlock (&eds_ldap_handler_lock);
 }
 
@@ -4752,6 +4754,7 @@ generate_cache (EBookBackendLDAP *book_backend_ldap)
        }
 
        priv->generate_cache_in_progress = TRUE;
+       e_book_backend_foreach_view_notify_progress (E_BOOK_BACKEND (book_backend_ldap), TRUE, 0, 
_("Refreshing…"));
 
        g_rec_mutex_unlock (&eds_ldap_handler_lock);
 
diff --git a/src/addressbook/libedata-book/e-book-backend.c b/src/addressbook/libedata-book/e-book-backend.c
index f2fb21ab1..e63b0994a 100644
--- a/src/addressbook/libedata-book/e-book-backend.c
+++ b/src/addressbook/libedata-book/e-book-backend.c
@@ -2717,6 +2717,105 @@ e_book_backend_list_views (EBookBackend *backend)
        return list;
 }
 
+/**
+ * EBookBackendForeachViewFunc:
+ * @backend: an #EBookBackend
+ * @view: an #EDataBookView
+ * @user_data: user data for the function
+ *
+ * Callback function used by e_book_backend_foreach_view().
+ *
+ * Returns: %TRUE, to continue, %FALSE to stop further processing.
+ *
+ * Since: 3.34
+ **/
+
+/**
+ * e_book_backend_foreach_view:
+ * @backend: an #EBookBackend
+ * @func: (scope call): an #EBookBackendForeachViewFunc function to call
+ * @user_data: (closure func): user data to pass to @func
+ *
+ * Calls @func for each existing view (as returned by e_book_backend_list_views()).
+ * The @func can return %FALSE to stop early.
+ *
+ * Returns: whether the call had been stopped by @func
+ *
+ * Since: 3.34
+ **/
+gboolean
+e_book_backend_foreach_view (EBookBackend *backend,
+                            EBookBackendForeachViewFunc func,
+                            gpointer user_data)
+{
+       GList *views, *link;
+       gboolean stopped = FALSE;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), FALSE);
+       g_return_val_if_fail (func != NULL, FALSE);
+
+       views = e_book_backend_list_views (backend);
+
+       for (link = views; link && !stopped; link = g_list_next (link)) {
+               stopped = !func (backend, link->data, user_data);
+       }
+
+       g_list_free_full (views, g_object_unref);
+
+       return stopped;
+}
+
+struct NotifyProgressData {
+       gboolean only_completed_views;
+       gint percent;
+       const gchar *message;
+};
+
+static gboolean
+ebb_notify_progress_cb (EBookBackend *backend,
+                       EDataBookView *view,
+                       gpointer user_data)
+{
+       struct NotifyProgressData *npd = user_data;
+
+       g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (view), FALSE);
+       g_return_val_if_fail (npd != NULL, FALSE);
+
+       if (!npd->only_completed_views || e_data_book_view_is_completed (view))
+               e_data_book_view_notify_progress (view, npd->percent, npd->message);
+
+       return TRUE;
+}
+
+/**
+ * e_book_backend_foreach_view_notify_progress:
+ * @backend: an #EBookBackend
+ * @only_completed_views: whether notify in completed views only
+ * @percent: percent complete
+ * @message: (nullable): message describing the operation in progress, or %NULL
+ *
+ * Notifies each view of the @backend about progress. When @only_completed_views
+ * is %TRUE, notifies only completed views.
+ *
+ * Since: 3.34
+ **/
+void
+e_book_backend_foreach_view_notify_progress (EBookBackend *backend,
+                                            gboolean only_completed_views,
+                                            gint percent,
+                                            const gchar *message)
+{
+       struct NotifyProgressData npd;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+
+       npd.only_completed_views = only_completed_views;
+       npd.percent = percent;
+       npd.message = message;
+
+       e_book_backend_foreach_view (backend, ebb_notify_progress_cb, &npd);
+}
+
 /**
  * e_book_backend_get_backend_property:
  * @backend: an #EBookBackend
diff --git a/src/addressbook/libedata-book/e-book-backend.h b/src/addressbook/libedata-book/e-book-backend.h
index aa3e5d3f9..aa917098d 100644
--- a/src/addressbook/libedata-book/e-book-backend.h
+++ b/src/addressbook/libedata-book/e-book-backend.h
@@ -353,6 +353,19 @@ void               e_book_backend_remove_view      (EBookBackend *backend,
                                                 EDataBookView *view);
 GList *                e_book_backend_list_views       (EBookBackend *backend);
 
+typedef gboolean (*EBookBackendForeachViewFunc)        (EBookBackend *backend,
+                                                EDataBookView *view,
+                                                gpointer user_data);
+
+gboolean       e_book_backend_foreach_view     (EBookBackend *backend,
+                                                EBookBackendForeachViewFunc func,
+                                                gpointer user_data);
+void           e_book_backend_foreach_view_notify_progress
+                                               (EBookBackend *backend,
+                                                gboolean only_completed_views,
+                                                gint percent,
+                                                const gchar *message);
+
 void           e_book_backend_notify_update    (EBookBackend *backend,
                                                 const EContact *contact);
 void           e_book_backend_notify_remove    (EBookBackend *backend,
diff --git a/src/addressbook/libedata-book/e-book-meta-backend.c 
b/src/addressbook/libedata-book/e-book-meta-backend.c
index ff7c9d5b7..e3677dae1 100644
--- a/src/addressbook/libedata-book/e-book-meta-backend.c
+++ b/src/addressbook/libedata-book/e-book-meta-backend.c
@@ -776,6 +776,8 @@ ebmb_refresh_internal_sync (EBookMetaBackend *meta_backend,
        if (g_cancellable_set_error_if_cancelled (cancellable, error))
                goto done;
 
+       e_book_backend_foreach_view_notify_progress (E_BOOK_BACKEND (meta_backend), TRUE, 0, 
_("Refreshing…"));
+
        if (!e_backend_get_online (E_BACKEND (meta_backend)) ||
            !e_book_meta_backend_ensure_connected_sync (meta_backend, cancellable, with_connection_error ? 
error : NULL) ||
            !e_backend_get_online (E_BACKEND (meta_backend))) { /* Failed connecting moves backend to offline 
*/
@@ -865,6 +867,8 @@ ebmb_refresh_internal_sync (EBookMetaBackend *meta_backend,
 
        g_mutex_unlock (&meta_backend->priv->property_lock);
 
+       e_book_backend_foreach_view_notify_progress (E_BOOK_BACKEND (meta_backend), TRUE, 0, NULL);
+
        g_signal_emit (meta_backend, signals[REFRESH_COMPLETED], 0, NULL);
 
        return success;
diff --git a/src/addressbook/libedata-book/e-data-book-view.c 
b/src/addressbook/libedata-book/e-data-book-view.c
index fbf0f9c28..3ab4ccd0a 100644
--- a/src/addressbook/libedata-book/e-data-book-view.c
+++ b/src/addressbook/libedata-book/e-data-book-view.c
@@ -835,6 +835,24 @@ e_data_book_view_get_flags (EDataBookView *view)
        return view->priv->flags;
 }
 
+/**
+ * e_data_book_view_is_completed:
+ * @view: an #EDataBookView
+ *
+ * Returns: whether the @view had been completed; that is,
+ *    whether e_data_book_view_notify_complete() had been called
+ *    since the @view had been started.
+ *
+ * Since: 3.34
+ **/
+gboolean
+e_data_book_view_is_completed (EDataBookView *view)
+{
+       g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (view), FALSE);
+
+       return view->priv->complete;
+}
+
 /*
  * Queue @vcard to be sent as a change notification.
  */
diff --git a/src/addressbook/libedata-book/e-data-book-view.h 
b/src/addressbook/libedata-book/e-data-book-view.h
index 887b8dc48..2cb6c46f2 100644
--- a/src/addressbook/libedata-book/e-data-book-view.h
+++ b/src/addressbook/libedata-book/e-data-book-view.h
@@ -87,6 +87,7 @@ EBookBackendSExp *
                e_data_book_view_get_sexp       (EDataBookView *view);
 EBookClientViewFlags
                e_data_book_view_get_flags      (EDataBookView *view);
+gboolean       e_data_book_view_is_completed   (EDataBookView *view);
 void           e_data_book_view_notify_update  (EDataBookView *view,
                                                 const EContact *contact);
 
diff --git a/src/calendar/libedata-cal/e-cal-backend.c b/src/calendar/libedata-cal/e-cal-backend.c
index 3c94401c0..4fc950c3e 100644
--- a/src/calendar/libedata-cal/e-cal-backend.c
+++ b/src/calendar/libedata-cal/e-cal-backend.c
@@ -1538,6 +1538,105 @@ e_cal_backend_list_views (ECalBackend *backend)
        return list;
 }
 
+/**
+ * ECalBackendForeachViewFunc:
+ * @backend: an #ECalBackend
+ * @view: an #EDataCalView
+ * @user_data: user data for the function
+ *
+ * Callback function used by e_cal_backend_foreach_view().
+ *
+ * Returns: %TRUE, to continue, %FALSE to stop further processing.
+ *
+ * Since: 3.34
+ **/
+
+/**
+ * e_cal_backend_foreach_view:
+ * @backend: an #ECalBackend
+ * @func: (scope call): an #ECalBackendForeachViewFunc function to call
+ * @user_data: (closure func): user data to pass to @func
+ *
+ * Calls @func for each existing view (as returned by e_cal_backend_list_views()).
+ * The @func can return %FALSE to stop early.
+ *
+ * Returns: whether the call had been stopped by @func
+ *
+ * Since: 3.34
+ **/
+gboolean
+e_cal_backend_foreach_view (ECalBackend *backend,
+                           ECalBackendForeachViewFunc func,
+                           gpointer user_data)
+{
+       GList *views, *link;
+       gboolean stopped = FALSE;
+
+       g_return_val_if_fail (E_IS_CAL_BACKEND (backend), FALSE);
+       g_return_val_if_fail (func != NULL, FALSE);
+
+       views = e_cal_backend_list_views (backend);
+
+       for (link = views; link && !stopped; link = g_list_next (link)) {
+               stopped = !func (backend, link->data, user_data);
+       }
+
+       g_list_free_full (views, g_object_unref);
+
+       return stopped;
+}
+
+struct NotifyProgressData {
+       gboolean only_completed_views;
+       gint percent;
+       const gchar *message;
+};
+
+static gboolean
+ecb_notify_progress_cb (ECalBackend *backend,
+                       EDataCalView *view,
+                       gpointer user_data)
+{
+       struct NotifyProgressData *npd = user_data;
+
+       g_return_val_if_fail (E_IS_DATA_CAL_VIEW (view), FALSE);
+       g_return_val_if_fail (npd != NULL, FALSE);
+
+       if (!npd->only_completed_views || e_data_cal_view_is_completed (view))
+               e_data_cal_view_notify_progress (view, npd->percent, npd->message);
+
+       return TRUE;
+}
+
+/**
+ * e_cal_backend_foreach_view_notify_progress:
+ * @backend: an #ECalBackend
+ * @only_completed_views: whether notify in completed views only
+ * @percent: percent complete
+ * @message: (nullable): message describing the operation in progress, or %NULL
+ *
+ * Notifies each view of the @backend about progress. When @only_completed_views
+ * is %TRUE, notifies only completed views.
+ *
+ * Since: 3.34
+ **/
+void
+e_cal_backend_foreach_view_notify_progress (ECalBackend *backend,
+                                           gboolean only_completed_views,
+                                           gint percent,
+                                           const gchar *message)
+{
+       struct NotifyProgressData npd;
+
+       g_return_if_fail (E_IS_CAL_BACKEND (backend));
+
+       npd.only_completed_views = only_completed_views;
+       npd.percent = percent;
+       npd.message = message;
+
+       e_cal_backend_foreach_view (backend, ecb_notify_progress_cb, &npd);
+}
+
 /**
  * e_cal_backend_open_sync:
  * @backend: an #ECalBackend
diff --git a/src/calendar/libedata-cal/e-cal-backend.h b/src/calendar/libedata-cal/e-cal-backend.h
index 57d17fbe7..90bd43fd6 100644
--- a/src/calendar/libedata-cal/e-cal-backend.h
+++ b/src/calendar/libedata-cal/e-cal-backend.h
@@ -243,6 +243,19 @@ void               e_cal_backend_remove_view       (ECalBackend *backend,
                                                 EDataCalView *view);
 GList *                e_cal_backend_list_views        (ECalBackend *backend);
 
+typedef gboolean (*ECalBackendForeachViewFunc) (ECalBackend *backend,
+                                                EDataCalView *view,
+                                                gpointer user_data);
+
+gboolean       e_cal_backend_foreach_view      (ECalBackend *backend,
+                                                ECalBackendForeachViewFunc func,
+                                                gpointer user_data);
+void           e_cal_backend_foreach_view_notify_progress
+                                               (ECalBackend *backend,
+                                                gboolean only_completed_views,
+                                                gint percent,
+                                                const gchar *message);
+
 gchar *                e_cal_backend_get_backend_property
                                                (ECalBackend *backend,
                                                 const gchar *prop_name);
diff --git a/src/calendar/libedata-cal/e-cal-meta-backend.c b/src/calendar/libedata-cal/e-cal-meta-backend.c
index 4389ee977..0e48f7825 100644
--- a/src/calendar/libedata-cal/e-cal-meta-backend.c
+++ b/src/calendar/libedata-cal/e-cal-meta-backend.c
@@ -678,6 +678,8 @@ ecmb_refresh_internal_sync (ECalMetaBackend *meta_backend,
        if (g_cancellable_set_error_if_cancelled (cancellable, error))
                goto done;
 
+       e_cal_backend_foreach_view_notify_progress (E_CAL_BACKEND (meta_backend), TRUE, 0, _("Refreshing…"));
+
        if (!e_backend_get_online (E_BACKEND (meta_backend)) ||
            !e_cal_meta_backend_ensure_connected_sync (meta_backend, cancellable, with_connection_error ? 
error : NULL) ||
            !e_backend_get_online (E_BACKEND (meta_backend))) { /* Failed connecting moves backend to offline 
*/
@@ -766,6 +768,8 @@ ecmb_refresh_internal_sync (ECalMetaBackend *meta_backend,
 
        g_mutex_unlock (&meta_backend->priv->property_lock);
 
+       e_cal_backend_foreach_view_notify_progress (E_CAL_BACKEND (meta_backend), TRUE, 0, NULL);
+
        g_signal_emit (meta_backend, signals[REFRESH_COMPLETED], 0, NULL);
 
        return success;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]