[evolution-data-server] I#297 - CalDAV: Support calendar-order property
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#297 - CalDAV: Support calendar-order property
- Date: Wed, 10 Feb 2021 14:01:18 +0000 (UTC)
commit 95a516250405b4ba3ab209bb25618ac97c4456b7
Author: Milan Crha <mcrha redhat com>
Date: Wed Feb 10 14:57:58 2021 +0100
I#297 - CalDAV: Support calendar-order property
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/297
CMakeLists.txt | 4 +-
src/libebackend/e-webdav-collection-backend.c | 15 +++-
src/libedataserver/e-data-server-util.c | 95 +++++++++++++++++++++
src/libedataserver/e-data-server-util.h | 2 +
src/libedataserver/e-source-address-book.c | 108 +++++++++++++++++++++++-
src/libedataserver/e-source-address-book.h | 4 +
src/libedataserver/e-source-registry.c | 32 +------
src/libedataserver/e-source-selectable.c | 72 +++++++++++++++-
src/libedataserver/e-source-selectable.h | 3 +
src/libedataserver/e-source-webdav.c | 70 ++++++++++++++-
src/libedataserver/e-source-webdav.h | 3 +
src/libedataserver/e-webdav-discover.c | 29 +++++--
src/libedataserver/e-webdav-discover.h | 1 +
src/libedataserver/e-webdav-session.c | 48 +++++++++--
src/libedataserver/e-webdav-session.h | 11 ++-
src/libedataserverui/e-webdav-discover-widget.c | 10 ++-
src/libedataserverui/e-webdav-discover-widget.h | 3 +-
17 files changed, 447 insertions(+), 63 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6c1b9e0ae..e8177fcc9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,11 +56,11 @@ set(LIBEBACKEND_CURRENT 10)
set(LIBEBACKEND_REVISION 0)
set(LIBEBACKEND_AGE 0)
-set(LIBEDATASERVER_CURRENT 25)
+set(LIBEDATASERVER_CURRENT 26)
set(LIBEDATASERVER_REVISION 0)
set(LIBEDATASERVER_AGE 0)
-set(LIBEDATASERVERUI_CURRENT 2)
+set(LIBEDATASERVERUI_CURRENT 3)
set(LIBEDATASERVERUI_REVISION 0)
set(LIBEDATASERVERUI_AGE 0)
diff --git a/src/libebackend/e-webdav-collection-backend.c b/src/libebackend/e-webdav-collection-backend.c
index 7f3165244..1a88b1520 100644
--- a/src/libebackend/e-webdav-collection-backend.c
+++ b/src/libebackend/e-webdav-collection-backend.c
@@ -88,6 +88,7 @@ webdav_collection_add_found_source (ECollectionBackend *collection,
SoupURI *uri,
const gchar *display_name,
const gchar *color,
+ guint order,
gboolean calendar_auto_schedule,
gboolean is_subscribed_icalendar,
GHashTable *known_sources)
@@ -205,7 +206,12 @@ webdav_collection_add_found_source (ECollectionBackend *collection,
e_source_webdav_set_display_name (webdav_extension, display_name);
- if (source_type != E_WEBDAV_DISCOVER_SUPPORTS_CONTACTS) {
+ if (source_type == E_WEBDAV_DISCOVER_SUPPORTS_CONTACTS) {
+ if (is_new || e_source_webdav_get_order (webdav_extension) ==
e_source_address_book_get_order (E_SOURCE_ADDRESS_BOOK (backend)))
+ e_source_address_book_set_order (E_SOURCE_ADDRESS_BOOK (backend), order);
+
+ e_source_webdav_set_order (webdav_extension, order);
+ } else {
/* Also check whether the color format is as expected; cannot
use gdk_rgba_parse() here, because it requires gdk/gtk. */
if (color && sscanf (color, "#%02x%02x%02x", &rr, &gg, &bb) == 3) {
@@ -222,6 +228,11 @@ webdav_collection_add_found_source (ECollectionBackend *collection,
g_free (safe_color);
}
+ if (is_new || e_source_webdav_get_order (webdav_extension) ==
e_source_selectable_get_order (E_SOURCE_SELECTABLE (backend)))
+ e_source_selectable_set_order (E_SOURCE_SELECTABLE (backend), order);
+
+ e_source_webdav_set_order (webdav_extension, order);
+
if (is_new && calendar_auto_schedule)
e_source_webdav_set_calendar_auto_schedule (webdav_extension, TRUE);
}
@@ -259,7 +270,7 @@ webdav_collection_process_discovered_sources (ECollectionBackend *collection,
for (ii = 0; ii < n_source_types; ii++) {
if ((discovered_source->supports & source_types[ii]) == source_types[ii])
webdav_collection_add_found_source (collection, source_types[ii], soup_uri,
- discovered_source->display_name, discovered_source->color,
+ discovered_source->display_name, discovered_source->color,
discovered_source->order,
(discovered_source->supports &
E_WEBDAV_DISCOVER_SUPPORTS_CALENDAR_AUTO_SCHEDULE) != 0,
(discovered_source->supports &
E_WEBDAV_DISCOVER_SUPPORTS_SUBSCRIBED_ICALENDAR) != 0,
known_sources);
diff --git a/src/libedataserver/e-data-server-util.c b/src/libedataserver/e-data-server-util.c
index ee9851707..5c8116af5 100644
--- a/src/libedataserver/e-data-server-util.c
+++ b/src/libedataserver/e-data-server-util.c
@@ -33,14 +33,18 @@
#include <glib-object.h>
#include "e-source.h"
+#include "e-source-address-book.h"
#include "e-source-authentication.h"
#include "e-source-backend.h"
+#include "e-source-calendar.h"
#include "e-source-collection.h"
#include "e-source-enumtypes.h"
#include "e-source-mail-identity.h"
#include "e-source-mail-submission.h"
#include "e-source-mail-transport.h"
+#include "e-source-memo-list.h"
#include "e-source-registry.h"
+#include "e-source-task-list.h"
#include "camel/camel.h"
#include "e-data-server-util.h"
@@ -3310,3 +3314,94 @@ e_util_can_use_collection_as_credential_source (ESource *collection_source,
return can_use_collection;
}
+
+static gboolean
+e_util_source_compare_get_order (ESource *source,
+ guint *out_order)
+{
+ const gchar *extensions[] = {
+ E_SOURCE_EXTENSION_ADDRESS_BOOK, /* keep it as the first - see below */
+ E_SOURCE_EXTENSION_CALENDAR,
+ E_SOURCE_EXTENSION_MEMO_LIST,
+ E_SOURCE_EXTENSION_TASK_LIST
+ };
+ gint ii;
+
+ for (ii = 0; ii < G_N_ELEMENTS (extensions); ii++) {
+ if (e_source_has_extension (source, extensions[ii])) {
+ ESourceExtension *extension = e_source_get_extension (source, extensions[ii]);
+
+ if (ii == 0) /* E_SOURCE_EXTENSION_ADDRESS_BOOK */
+ *out_order = e_source_address_book_get_order (E_SOURCE_ADDRESS_BOOK
(extension));
+ else
+ *out_order = e_source_selectable_get_order (E_SOURCE_SELECTABLE (extension));
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * e_util_source_compare_for_sort:
+ * @source_a: the first #ESource
+ * @source_b: the second #ESource
+ *
+ * Compares two #ESource-s in a way suitable for user interface.
+ * It can be used as a #GCompareFunc.
+ *
+ * This is also used by e_source_registry_build_display_tree().
+ *
+ * Returns: an integer less than, equal to, or greater than zero,
+ * if @source_a is <, == or > than @source_b.
+ *
+ * Since: 3.40
+ **/
+gint
+e_util_source_compare_for_sort (ESource *source_a,
+ ESource *source_b)
+{
+ guint order_a = 0, order_b = 0;
+ const gchar *uid_a, *uid_b;
+
+ if (!source_a || !source_b)
+ return (source_a ? 1 : 0) - (source_b ? 1 : 0);
+
+ uid_a = e_source_get_uid (source_a);
+ uid_b = e_source_get_uid (source_b);
+
+ /* Sanity check, with runtime warnings. */
+ if (uid_a == NULL) {
+ g_warn_if_reached ();
+ uid_a = "";
+ }
+ if (uid_b == NULL) {
+ g_warn_if_reached ();
+ uid_b = "";
+ }
+
+ /* The built-in "local-stub" source comes first at depth 1. */
+
+ if (g_strcmp0 (uid_a, "local-stub") == 0)
+ return -1;
+
+ if (g_strcmp0 (uid_b, "local-stub") == 0)
+ return 1;
+
+ /* The built-in "system-*" sources come first at depth 2. */
+
+ if (g_str_has_prefix (uid_a, "system-"))
+ return -1;
+
+ if (g_str_has_prefix (uid_b, "system-"))
+ return 1;
+
+ if (e_util_source_compare_get_order (source_a, &order_a) &&
+ e_util_source_compare_get_order (source_b, &order_b)) {
+ if (order_a != order_b)
+ return order_a < order_b ? -1 : 1;
+ }
+
+ return e_source_compare_by_display_name (source_a, source_b);
+}
diff --git a/src/libedataserver/e-data-server-util.h b/src/libedataserver/e-data-server-util.h
index bfddb2399..526d8a542 100644
--- a/src/libedataserver/e-data-server-util.h
+++ b/src/libedataserver/e-data-server-util.h
@@ -293,6 +293,8 @@ gboolean e_util_identity_can_send (struct _ESourceRegistry *registry,
gboolean e_util_can_use_collection_as_credential_source
(struct _ESource *collection_source,
struct _ESource *child_source);
+gint e_util_source_compare_for_sort (struct _ESource *source_a,
+ struct _ESource *source_b);
G_END_DECLS
diff --git a/src/libedataserver/e-source-address-book.c b/src/libedataserver/e-source-address-book.c
index 9a2be6e81..a3e0d671b 100644
--- a/src/libedataserver/e-source-address-book.c
+++ b/src/libedataserver/e-source-address-book.c
@@ -38,21 +38,121 @@
#include <libedataserver/e-data-server-util.h>
-G_DEFINE_TYPE (
- ESourceAddressBook,
- e_source_address_book,
- E_TYPE_SOURCE_BACKEND)
+struct _ESourceAddressBookPrivate {
+ guint order;
+};
+
+enum {
+ PROP_0,
+ PROP_ORDER
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (ESourceAddressBook, e_source_address_book, E_TYPE_SOURCE_BACKEND)
+
+static void
+source_address_book_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORDER:
+ e_source_address_book_set_order (
+ E_SOURCE_ADDRESS_BOOK (object),
+ g_value_get_uint (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_address_book_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORDER:
+ g_value_set_uint (
+ value,
+ e_source_address_book_get_order (
+ E_SOURCE_ADDRESS_BOOK (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
static void
e_source_address_book_class_init (ESourceAddressBookClass *class)
{
+ GObjectClass *object_class;
ESourceExtensionClass *extension_class;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = source_address_book_set_property;
+ object_class->get_property = source_address_book_get_property;
+
extension_class = E_SOURCE_EXTENSION_CLASS (class);
extension_class->name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ORDER,
+ g_param_spec_uint (
+ "order",
+ "Order",
+ "A sorting order of the source",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
}
static void
e_source_address_book_init (ESourceAddressBook *extension)
{
+ extension->priv = e_source_address_book_get_instance_private (extension);
+}
+
+/**
+ * e_source_address_book_get_order:
+ * @extension: an #ESourceAddressBook
+ *
+ * Returns: the sorting order of the source, if known. Zero is the default.
+ *
+ * Since: 3.40
+ **/
+guint
+e_source_address_book_get_order (ESourceAddressBook *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_ADDRESS_BOOK (extension), 0);
+
+ return extension->priv->order;
+}
+
+/**
+ * e_source_address_book_set_order:
+ * @extension: an #ESourceAddressBook
+ * @order: a sorting order
+ *
+ * Set the sorting order of the source.
+ *
+ * Since: 3.40
+ **/
+void
+e_source_address_book_set_order (ESourceAddressBook *extension,
+ guint order)
+{
+ g_return_if_fail (E_IS_SOURCE_ADDRESS_BOOK (extension));
+
+ if (extension->priv->order == order)
+ return;
+
+ extension->priv->order = order;
+
+ g_object_notify (G_OBJECT (extension), "order");
}
diff --git a/src/libedataserver/e-source-address-book.h b/src/libedataserver/e-source-address-book.h
index 8960470f4..9d5963f34 100644
--- a/src/libedataserver/e-source-address-book.h
+++ b/src/libedataserver/e-source-address-book.h
@@ -79,6 +79,10 @@ struct _ESourceAddressBookClass {
GType e_source_address_book_get_type (void) G_GNUC_CONST;
+guint e_source_address_book_get_order (ESourceAddressBook *extension);
+void e_source_address_book_set_order (ESourceAddressBook *extension,
+ guint order);
+
G_END_DECLS
#endif /* E_SOURCE_ADDRESS_BOOK_H */
diff --git a/src/libedataserver/e-source-registry.c b/src/libedataserver/e-source-registry.c
index 9664bccf4..3d61eb802 100644
--- a/src/libedataserver/e-source-registry.c
+++ b/src/libedataserver/e-source-registry.c
@@ -2714,38 +2714,8 @@ source_registry_compare_nodes (GNode *node_a,
{
ESource *source_a = E_SOURCE (node_a->data);
ESource *source_b = E_SOURCE (node_b->data);
- const gchar *uid_a, *uid_b;
- uid_a = e_source_get_uid (source_a);
- uid_b = e_source_get_uid (source_b);
-
- /* Sanity check, with runtime warnings. */
- if (uid_a == NULL) {
- g_warn_if_reached ();
- uid_a = "";
- }
- if (uid_b == NULL) {
- g_warn_if_reached ();
- uid_b = "";
- }
-
- /* The built-in "local-stub" source comes first at depth 1. */
-
- if (g_strcmp0 (uid_a, "local-stub") == 0)
- return -1;
-
- if (g_strcmp0 (uid_b, "local-stub") == 0)
- return 1;
-
- /* The built-in "system-*" sources come first at depth 2. */
-
- if (g_str_has_prefix (uid_a, "system-"))
- return -1;
-
- if (g_str_has_prefix (uid_b, "system-"))
- return 1;
-
- return e_source_compare_by_display_name (source_a, source_b);
+ return e_util_source_compare_for_sort (source_a, source_b);
}
/* Helper for e_source_registry_build_display_tree() */
diff --git a/src/libedataserver/e-source-selectable.c b/src/libedataserver/e-source-selectable.c
index ef089c68b..ddff58a91 100644
--- a/src/libedataserver/e-source-selectable.c
+++ b/src/libedataserver/e-source-selectable.c
@@ -32,12 +32,14 @@
struct _ESourceSelectablePrivate {
gchar *color;
gboolean selected;
+ guint order;
};
enum {
PROP_0,
PROP_COLOR,
- PROP_SELECTED
+ PROP_SELECTED,
+ PROP_ORDER
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (
@@ -63,6 +65,12 @@ source_selectable_set_property (GObject *object,
E_SOURCE_SELECTABLE (object),
g_value_get_boolean (value));
return;
+
+ case PROP_ORDER:
+ e_source_selectable_set_order (
+ E_SOURCE_SELECTABLE (object),
+ g_value_get_uint (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -88,6 +96,13 @@ source_selectable_get_property (GObject *object,
e_source_selectable_get_selected (
E_SOURCE_SELECTABLE (object)));
return;
+
+ case PROP_ORDER:
+ g_value_set_uint (
+ value,
+ e_source_selectable_get_order (
+ E_SOURCE_SELECTABLE (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -146,6 +161,20 @@ e_source_selectable_class_init (ESourceSelectableClass *class)
G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS |
E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ORDER,
+ g_param_spec_uint (
+ "order",
+ "Order",
+ "Preferred sorting order",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
}
static void
@@ -288,3 +317,44 @@ e_source_selectable_set_selected (ESourceSelectable *extension,
g_object_notify (G_OBJECT (extension), "selected");
}
+/**
+ * e_source_selectable_get_order:
+ * @extension: an #ESourceSelectable
+ *
+ * Returns the preferred sorting order for the #ESource
+ * to which @extension belongs. Default is 0.
+ *
+ * Returns: the preferred sorting order for the #ESource
+ *
+ * Since: 3.40
+ **/
+guint
+e_source_selectable_get_order (ESourceSelectable *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_SELECTABLE (extension), 0);
+
+ return extension->priv->order;
+}
+
+/**
+ * e_source_selectable_set_order:
+ * @extension: an #ESourceSelectable
+ * @selected: selected state
+ *
+ * Sets the sorting order for the #ESource to which @extension belongs.
+ *
+ * Since: 3.40
+ **/
+void
+e_source_selectable_set_order (ESourceSelectable *extension,
+ guint order)
+{
+ g_return_if_fail (E_IS_SOURCE_SELECTABLE (extension));
+
+ if (extension->priv->order == order)
+ return;
+
+ extension->priv->order = order;
+
+ g_object_notify (G_OBJECT (extension), "order");
+}
diff --git a/src/libedataserver/e-source-selectable.h b/src/libedataserver/e-source-selectable.h
index df418bf09..33dea25dd 100644
--- a/src/libedataserver/e-source-selectable.h
+++ b/src/libedataserver/e-source-selectable.h
@@ -77,6 +77,9 @@ gboolean e_source_selectable_get_selected
void e_source_selectable_set_selected
(ESourceSelectable *extension,
gboolean selected);
+guint e_source_selectable_get_order (ESourceSelectable *extension);
+void e_source_selectable_set_order (ESourceSelectable *extension,
+ guint order);
G_END_DECLS
diff --git a/src/libedataserver/e-source-webdav.c b/src/libedataserver/e-source-webdav.c
index b3432ff4d..91f9ac564 100644
--- a/src/libedataserver/e-source-webdav.c
+++ b/src/libedataserver/e-source-webdav.c
@@ -68,6 +68,7 @@ struct _ESourceWebdavPrivate {
gboolean avoid_ifmatch;
gboolean calendar_auto_schedule;
SoupURI *soup_uri;
+ guint order;
};
enum {
@@ -80,7 +81,8 @@ enum {
PROP_RESOURCE_PATH,
PROP_RESOURCE_QUERY,
PROP_SOUP_URI,
- PROP_SSL_TRUST
+ PROP_SSL_TRUST,
+ PROP_ORDER
};
G_DEFINE_TYPE_WITH_PRIVATE (
@@ -322,6 +324,12 @@ source_webdav_set_property (GObject *object,
E_SOURCE_WEBDAV (object),
g_value_get_string (value));
return;
+
+ case PROP_ORDER:
+ e_source_webdav_set_order (
+ E_SOURCE_WEBDAV (object),
+ g_value_get_uint (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -396,6 +404,13 @@ source_webdav_get_property (GObject *object,
e_source_webdav_dup_ssl_trust (
E_SOURCE_WEBDAV (object)));
return;
+
+ case PROP_ORDER:
+ g_value_set_uint (
+ value,
+ e_source_webdav_get_order (
+ E_SOURCE_WEBDAV (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -621,6 +636,20 @@ e_source_webdav_class_init (ESourceWebdavClass *class)
G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS |
E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ORDER,
+ g_param_spec_uint (
+ "order",
+ "Order",
+ "A sorting order of the resource",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
}
static void
@@ -1586,3 +1615,42 @@ e_source_webdav_set_ssl_trust_response (ESourceWebdav *extension,
g_free (host);
g_free (hash);
}
+
+/**
+ * e_source_webdav_get_order:
+ * @extension: an #ESourceWebdav
+ *
+ * Returns: the sorting order of the resource, if known. Zero is the default.
+ *
+ * Since: 3.40
+ **/
+guint
+e_source_webdav_get_order (ESourceWebdav *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), 0);
+
+ return extension->priv->order;
+}
+
+/**
+ * e_source_webdav_set_order:
+ * @extension: an #ESourceWebdav
+ * @order: a sorting order
+ *
+ * Set the sorting order of the resource.
+ *
+ * Since: 3.40
+ **/
+void
+e_source_webdav_set_order (ESourceWebdav *extension,
+ guint order)
+{
+ g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
+
+ if (extension->priv->order == order)
+ return;
+
+ extension->priv->order = order;
+
+ g_object_notify (G_OBJECT (extension), "order");
+}
diff --git a/src/libedataserver/e-source-webdav.h b/src/libedataserver/e-source-webdav.h
index f1c8da856..e72e553f4 100644
--- a/src/libedataserver/e-source-webdav.h
+++ b/src/libedataserver/e-source-webdav.h
@@ -153,6 +153,9 @@ ETrustPromptResponse
void e_source_webdav_set_ssl_trust_response
(ESourceWebdav *extension,
ETrustPromptResponse response);
+guint e_source_webdav_get_order (ESourceWebdav *extension);
+void e_source_webdav_set_order (ESourceWebdav *extension,
+ guint order);
G_END_DECLS
diff --git a/src/libedataserver/e-webdav-discover.c b/src/libedataserver/e-webdav-discover.c
index 0aefa5aae..bad613a2b 100644
--- a/src/libedataserver/e-webdav-discover.c
+++ b/src/libedataserver/e-webdav-discover.c
@@ -91,6 +91,7 @@ e_webdav_discover_split_resources (WebDAVDiscoverData *wdd,
discovered->display_name = g_strdup (resource->display_name);
discovered->description = g_strdup (resource->description);
discovered->color = g_strdup (resource->color);
+ discovered->order = resource->order;
if (resource->kind == E_WEBDAV_RESOURCE_KIND_ADDRESSBOOK) {
wdd->addressbooks = g_slist_prepend (wdd->addressbooks, discovered);
@@ -146,8 +147,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
if (full_href && *full_href && GPOINTER_TO_INT (g_hash_table_contains
(wdd->covered_hrefs, full_href)) != 2 &&
e_webdav_session_list_sync (webdav, full_href, E_WEBDAV_DEPTH_THIS_AND_CHILDREN,
- E_WEBDAV_LIST_SUPPORTS | E_WEBDAV_LIST_DISPLAY_NAME |
E_WEBDAV_LIST_DESCRIPTION |
- E_WEBDAV_LIST_COLOR | E_WEBDAV_LIST_ONLY_ADDRESSBOOK | E_WEBDAV_LIST_ALL,
+ E_WEBDAV_LIST_ONLY_ADDRESSBOOK | E_WEBDAV_LIST_ALL,
&resources, wdd->cancellable, &local_error)) {
e_webdav_discover_split_resources (wdd, resources);
g_slist_free_full (resources, e_webdav_resource_free);
@@ -183,8 +183,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
if (full_href && *full_href && GPOINTER_TO_INT (g_hash_table_contains
(wdd->covered_hrefs, full_href)) != 2 &&
e_webdav_session_list_sync (webdav, full_href, E_WEBDAV_DEPTH_THIS_AND_CHILDREN,
- E_WEBDAV_LIST_SUPPORTS | E_WEBDAV_LIST_DISPLAY_NAME |
E_WEBDAV_LIST_DESCRIPTION |
- E_WEBDAV_LIST_COLOR | E_WEBDAV_LIST_ONLY_CALENDAR | E_WEBDAV_LIST_ALL,
+ E_WEBDAV_LIST_ONLY_CALENDAR | E_WEBDAV_LIST_ALL,
&resources, wdd->cancellable, &local_error)) {
e_webdav_discover_split_resources (wdd, resources);
g_slist_free_full (resources, e_webdav_resource_free);
@@ -269,7 +268,6 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
if (GPOINTER_TO_INT (g_hash_table_contains (wdd->covered_hrefs, href)) != 2 &&
!g_cancellable_is_cancelled (wdd->cancellable) &&
e_webdav_session_list_sync (webdav, href, E_WEBDAV_DEPTH_THIS,
- E_WEBDAV_LIST_SUPPORTS | E_WEBDAV_LIST_DISPLAY_NAME | E_WEBDAV_LIST_DESCRIPTION |
E_WEBDAV_LIST_COLOR |
(is_calendar ? E_WEBDAV_LIST_ONLY_CALENDAR : 0) | (is_addressbook ?
E_WEBDAV_LIST_ONLY_ADDRESSBOOK : 0) | E_WEBDAV_LIST_ALL,
&resources, wdd->cancellable, &local_error)) {
e_webdav_discover_split_resources (wdd, resources);
@@ -295,7 +293,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
e_webdav_resource_new (E_WEBDAV_RESOURCE_KIND_WEBDAV_NOTES,
E_WEBDAV_RESOURCE_SUPPORTS_WEBDAV_NOTES, href, NULL,
_("Notes"),
- NULL, 0, 0, 0, NULL, NULL));
+ NULL, 0, 0, 0, NULL, NULL, 0));
e_webdav_discover_split_resources (wdd, resources);
@@ -760,6 +758,22 @@ e_webdav_discover_sources_sync (ESource *source,
out_certificate_pem, out_certificate_errors, out_discovered_sources,
out_calendar_user_addresses, cancellable, error);
}
+static gint
+e_webdav_discover_cmp_sources (gconstpointer ptr1,
+ gconstpointer ptr2)
+{
+ const EWebDAVDiscoveredSource *source1 = ptr1;
+ const EWebDAVDiscoveredSource *source2 = ptr2;
+
+ if (!source1 || !source2)
+ return (source1 ? 1 : 0) - (source2 ? 1 : 0);
+
+ if (source1->order != source2->order)
+ return source1->order < source2->order ? -1 : 1;
+
+ return g_strcmp0 (source1->display_name, source2->display_name);
+}
+
/**
* e_webdav_discover_sources_full_sync:
* @source: an #ESource from which to take connection details
@@ -1017,7 +1031,7 @@ e_webdav_discover_sources_full_sync (ESource *source,
*out_calendar_user_addresses = g_slist_reverse (*out_calendar_user_addresses);
if (out_discovered_sources && *out_discovered_sources)
- *out_discovered_sources = g_slist_reverse (*out_discovered_sources);
+ *out_discovered_sources = g_slist_sort (*out_discovered_sources,
e_webdav_discover_cmp_sources);
g_hash_table_destroy (wdd.covered_hrefs);
} else {
@@ -1056,6 +1070,7 @@ e_webdav_discovered_source_copy (EWebDAVDiscoveredSource *discovered_source)
copy->display_name = g_strdup (discovered_source->display_name);
copy->description = g_strdup (discovered_source->description);
copy->color = g_strdup (discovered_source->color);
+ copy->order = discovered_source->order;
return copy;
}
diff --git a/src/libedataserver/e-webdav-discover.h b/src/libedataserver/e-webdav-discover.h
index 8b6966826..028d3c6e9 100644
--- a/src/libedataserver/e-webdav-discover.h
+++ b/src/libedataserver/e-webdav-discover.h
@@ -48,6 +48,7 @@ typedef struct _EWebDAVDiscoveredSource {
gchar *display_name;
gchar *description;
gchar *color;
+ guint order;
} EWebDAVDiscoveredSource;
void e_webdav_discover_free_discovered_sources
diff --git a/src/libedataserver/e-webdav-session.c b/src/libedataserver/e-webdav-session.c
index fbf8a0acb..0976510ff 100644
--- a/src/libedataserver/e-webdav-session.c
+++ b/src/libedataserver/e-webdav-session.c
@@ -66,6 +66,7 @@ G_DEFINE_BOXED_TYPE (EWebDAVAccessControlEntry, e_webdav_access_control_entry, e
* @last_modified: optional last modified time of the resource, or 0
* @description: (nullable): optional description of the resource, or %NULL
* @color: (nullable): optional color of the resource, or %NULL
+ * @order: sort order of the resource, or 0
*
* Some values of the resource are not always valid, depending on the @kind,
* but also whether server stores such values and whether it had been asked
@@ -89,7 +90,8 @@ e_webdav_resource_new (EWebDAVResourceKind kind,
glong creation_date,
glong last_modified,
const gchar *description,
- const gchar *color)
+ const gchar *color,
+ guint order)
{
EWebDAVResource *resource;
@@ -105,6 +107,7 @@ e_webdav_resource_new (EWebDAVResourceKind kind,
resource->last_modified = last_modified;
resource->description = g_strdup (description);
resource->color = g_strdup (color);
+ resource->order = order;
return resource;
}
@@ -135,7 +138,8 @@ e_webdav_resource_copy (const EWebDAVResource *src)
src->creation_date,
src->last_modified,
src->description,
- src->color);
+ src->color,
+ src->order);
}
/**
@@ -3569,6 +3573,27 @@ e_webdav_session_extract_content_length (xmlNodePtr parent)
return length;
}
+static guint
+e_webdav_session_extract_uint (xmlNodePtr parent,
+ const gchar *prop_ns_href,
+ const gchar *prop_name)
+{
+ gchar *value_str;
+ guint64 value;
+
+ g_return_val_if_fail (parent != NULL, 0);
+
+ value_str = e_webdav_session_extract_nonempty (parent, prop_ns_href, prop_name, NULL, NULL);
+ if (!value_str)
+ return 0;
+
+ value = g_ascii_strtoull (value_str, NULL, 10);
+
+ g_free (value_str);
+
+ return (guint) value;
+}
+
static glong
e_webdav_session_extract_datetime (xmlNodePtr parent,
const gchar *ns_href,
@@ -3622,6 +3647,7 @@ e_webdav_session_list_cb (EWebDAVSession *webdav,
gchar *description;
gchar *color;
gchar *source_href = NULL;
+ guint order;
kind = e_webdav_session_extract_kind (prop_node);
if (kind == E_WEBDAV_RESOURCE_KIND_UNKNOWN)
@@ -3655,6 +3681,7 @@ e_webdav_session_list_cb (EWebDAVSession *webdav,
description = e_webdav_session_extract_nonempty (prop_node, E_WEBDAV_NS_CALDAV,
"calendar-description",
E_WEBDAV_NS_CARDDAV, "addressbook-description");
color = e_webdav_session_extract_nonempty (prop_node, E_WEBDAV_NS_ICAL, "calendar-color",
NULL, NULL);
+ order = e_webdav_session_extract_uint (prop_node, E_WEBDAV_NS_ICAL, "calendar-order");
resource = e_webdav_resource_new (kind, supports,
source_href ? source_href : href,
@@ -3665,7 +3692,8 @@ e_webdav_session_list_cb (EWebDAVSession *webdav,
creation_date,
last_modified,
NULL, /* description */
- NULL); /* color */
+ NULL, /* color */
+ order);
resource->etag = etag;
resource->display_name = display_name;
resource->content_type = content_type;
@@ -3745,8 +3773,7 @@ e_webdav_session_list_sync (EWebDAVSession *webdav,
if (calendar_props && (
(flags & E_WEBDAV_LIST_SUPPORTS) != 0 ||
- (flags & E_WEBDAV_LIST_DESCRIPTION) != 0 ||
- (flags & E_WEBDAV_LIST_COLOR) != 0)) {
+ (flags & E_WEBDAV_LIST_DESCRIPTION) != 0)) {
e_xml_document_add_namespaces (xml, "C", E_WEBDAV_NS_CALDAV, NULL);
}
@@ -3792,10 +3819,14 @@ e_webdav_session_list_sync (EWebDAVSession *webdav,
}
}
- if (calendar_props && (flags & E_WEBDAV_LIST_COLOR) != 0) {
+ if (calendar_props && ((flags & E_WEBDAV_LIST_COLOR) != 0 || (flags & E_WEBDAV_LIST_ORDER) != 0)) {
e_xml_document_add_namespaces (xml, "IC", E_WEBDAV_NS_ICAL, NULL);
- e_xml_document_add_empty_element (xml, E_WEBDAV_NS_ICAL, "calendar-color");
+ if ((flags & E_WEBDAV_LIST_COLOR) != 0)
+ e_xml_document_add_empty_element (xml, E_WEBDAV_NS_ICAL, "calendar-color");
+
+ if ((flags & E_WEBDAV_LIST_ORDER) != 0)
+ e_xml_document_add_empty_element (xml, E_WEBDAV_NS_ICAL, "calendar-order");
}
e_xml_document_end_element (xml); /* prop */
@@ -4981,7 +5012,8 @@ e_webdav_session_principal_property_search_cb (EWebDAVSession *webdav,
0, /* creation_date */
0, /* last_modified */
NULL, /* description */
- NULL); /* color */
+ NULL, /* color */
+ 0); /* order */
resource->display_name = display_name;
*out_principals = g_slist_prepend (*out_principals, resource);
diff --git a/src/libedataserver/e-webdav-session.h b/src/libedataserver/e-webdav-session.h
index a9f6f5b0a..fd9050daf 100644
--- a/src/libedataserver/e-webdav-session.h
+++ b/src/libedataserver/e-webdav-session.h
@@ -116,6 +116,7 @@ typedef struct _EWebDAVResource {
glong last_modified;
gchar *description;
gchar *color;
+ guint order;
} EWebDAVResource;
GType e_webdav_resource_get_type (void) G_GNUC_CONST;
@@ -130,13 +131,14 @@ EWebDAVResource *
glong creation_date,
glong last_modified,
const gchar *description,
- const gchar *color);
+ const gchar *color,
+ guint order);
EWebDAVResource *
e_webdav_resource_copy (const EWebDAVResource *src);
void e_webdav_resource_free (gpointer ptr /* EWebDAVResource * */);
typedef enum {
- E_WEBDAV_LIST_ALL = 0xFFFFFFFF,
+ E_WEBDAV_LIST_ALL = 0x00FFFFFF,
E_WEBDAV_LIST_NONE = 0,
E_WEBDAV_LIST_SUPPORTS = 1 << 0,
E_WEBDAV_LIST_ETAG = 1 << 1,
@@ -147,8 +149,9 @@ typedef enum {
E_WEBDAV_LIST_LAST_MODIFIED = 1 << 6,
E_WEBDAV_LIST_DESCRIPTION = 1 << 7,
E_WEBDAV_LIST_COLOR = 1 << 8,
- E_WEBDAV_LIST_ONLY_CALENDAR = 1 << 9,
- E_WEBDAV_LIST_ONLY_ADDRESSBOOK = 1 << 10
+ E_WEBDAV_LIST_ORDER = 1 << 9,
+ E_WEBDAV_LIST_ONLY_CALENDAR = 1 << 28,
+ E_WEBDAV_LIST_ONLY_ADDRESSBOOK = 1 << 29
} EWebDAVListFlags;
/**
diff --git a/src/libedataserverui/e-webdav-discover-widget.c b/src/libedataserverui/e-webdav-discover-widget.c
index dbb1d4a7e..7bbb7db99 100644
--- a/src/libedataserverui/e-webdav-discover-widget.c
+++ b/src/libedataserverui/e-webdav-discover-widget.c
@@ -62,6 +62,7 @@ enum {
COL_SUPPORTS_STRING,
COL_COLOR_GDKRGBA,
COL_SHOW_COLOR_BOOLEAN,
+ COL_ORDER_UINT,
N_COLUMNS
};
@@ -151,7 +152,8 @@ e_webdav_discover_content_new (ECredentialsPrompter *credentials_prompter,
G_TYPE_STRING, /* COL_DESCRIPTION_STRING */
G_TYPE_STRING, /* COL_SUPPORTS_STRING */
GDK_TYPE_RGBA, /* COL_COLOR_GDKRGBA */
- G_TYPE_BOOLEAN); /* COL_SHOW_COLOR_BOOLEAN */
+ G_TYPE_BOOLEAN,/* COL_SHOW_COLOR_BOOLEAN */
+ G_TYPE_UINT); /* COL_ORDER_UINT */
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
g_object_unref (list_store);
@@ -359,6 +361,7 @@ e_webdav_discover_content_get_base_url (GtkWidget *content)
* @out_display_name: (out): an output location of the sources display name
* @out_color: (out): an output location of the string representation of the color
* for the source, as set on the server
+ * @out_order: (out): an output location of the preferred sorting order
*
* Returns information about selected source at index @index. The function can be called
* multiple times, with the index starting at zero and as long as it doesn't return %FALSE.
@@ -377,7 +380,8 @@ e_webdav_discover_content_get_selected (GtkWidget *content,
gchar **out_href,
guint *out_supports,
gchar **out_display_name,
- gchar **out_color)
+ gchar **out_color,
+ guint *out_order)
{
EWebDAVDiscoverContent *self;
GtkTreeSelection *selection;
@@ -413,6 +417,7 @@ e_webdav_discover_content_get_selected (GtkWidget *content,
COL_SUPPORTS_UINT, out_supports,
COL_DISPLAY_NAME_STRING, out_display_name,
COL_COLOR_STRING, out_color,
+ COL_ORDER_UINT, out_order,
-1);
}
}
@@ -547,6 +552,7 @@ e_webdav_discover_content_fill_discovered_sources (GtkTreeView *tree_view,
COL_SUPPORTS_UINT, source->supports,
COL_DISPLAY_NAME_STRING, source->display_name,
COL_COLOR_STRING, colorstr,
+ COL_ORDER_UINT, source->order,
COL_DESCRIPTION_STRING, description_markup,
COL_SUPPORTS_STRING, supports->str,
COL_COLOR_GDKRGBA, show_color ? &rgba : NULL,
diff --git a/src/libedataserverui/e-webdav-discover-widget.h b/src/libedataserverui/e-webdav-discover-widget.h
index 5d44d58df..5e91e9501 100644
--- a/src/libedataserverui/e-webdav-discover-widget.h
+++ b/src/libedataserverui/e-webdav-discover-widget.h
@@ -57,7 +57,8 @@ gboolean e_webdav_discover_content_get_selected (GtkWidget *content,
gchar **out_href,
guint *out_supports,
gchar **out_display_name,
- gchar **out_color);
+ gchar **out_color,
+ guint *out_order);
gchar * e_webdav_discover_content_get_user_address
(GtkWidget *content);
void e_webdav_discover_content_refresh (GtkWidget *content,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]