ESourceWebdav: Add "resource-query" property.
authorMatthew Barnes <mbarnes@redhat.com>
Mon, 27 Aug 2012 15:44:46 +0000 (11:44 -0400)
committerMatthew Barnes <mbarnes@redhat.com>
Mon, 27 Aug 2012 16:12:55 +0000 (12:12 -0400)
Retain the query portion of a WebDAV URI, and update migration to
preserve it from the old XML-based ESource URIs.

Also reimplement the "soup-uri" property.  Using bi-directional property
bindings from one property to many properties results in feedback loops.
Instead, listen for "notify" signals from URI component properties and
emit a "notify::soup-uri" signal, but don't actually update the internal
SoupURI until a copy is requested.

This makes Facebook birthday calendars work again, which has the form:
webcal://www.facebook.com/ical/b.php?uid=<<UID>>&key=<<KEY>>

docs/reference/libedataserver/libedataserver-sections.txt
libedataserver/e-source-webdav.c
libedataserver/e-source-webdav.h
services/evolution-source-registry/evolution-source-registry-migrate-sources.c

index a7af852..54f9b28 100644 (file)
@@ -991,6 +991,9 @@ e_source_webdav_set_ignore_invalid_cert
 e_source_webdav_get_resource_path
 e_source_webdav_dup_resource_path
 e_source_webdav_set_resource_path
+e_source_webdav_get_resource_query
+e_source_webdav_dup_resource_query
+e_source_webdav_set_resource_query
 e_source_webdav_dup_soup_uri
 e_source_webdav_set_soup_uri
 e_source_webdav_get_avoid_ifmatch
index 2a2a017..c624e1b 100644 (file)
@@ -59,10 +59,11 @@ struct _ESourceWebdavPrivate {
        gchar *display_name;
        gchar *email_address;
        gchar *resource_path;
+       gchar *resource_query;
        gboolean avoid_ifmatch;
        gboolean calendar_auto_schedule;
        gboolean ignore_invalid_cert;
-       SoupURI *uri;
+       SoupURI *soup_uri;
 };
 
 enum {
@@ -73,6 +74,7 @@ enum {
        PROP_EMAIL_ADDRESS,
        PROP_IGNORE_INVALID_CERT,
        PROP_RESOURCE_PATH,
+       PROP_RESOURCE_QUERY,
        PROP_SOUP_URI
 };
 
@@ -81,210 +83,142 @@ G_DEFINE_TYPE (
        e_source_webdav,
        E_TYPE_SOURCE_EXTENSION)
 
-static gboolean
-source_webdav_host_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+static void
+source_webdav_notify_cb (GObject *object,
+                         GParamSpec *pspec,
+                         ESourceWebdav *extension)
 {
-       GObject *target;
-       SoupURI *soup_uri;
-       const gchar *host;
-
-       host = g_value_get_string (source_value);
-
-       target = g_binding_get_target (binding);
-       g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
-
-       soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-       soup_uri_set_host (soup_uri, host);
-       g_value_take_boxed (target_value, soup_uri);
-
-       return TRUE;
+       g_object_notify (G_OBJECT (extension), "soup-uri");
 }
 
 static gboolean
-source_webdav_soup_uri_to_host (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+source_webdav_user_to_method (GBinding *binding,
+                              const GValue *source_value,
+                              GValue *target_value,
+                              gpointer user_data)
 {
-       SoupURI *soup_uri;
+       const gchar *user;
 
-       soup_uri = g_value_get_boxed (source_value);
-       g_value_set_string (target_value, soup_uri->host);
+       user = g_value_get_string (source_value);
+       if (user == NULL || *user == '\0')
+               g_value_set_string (target_value, "none");
+       else
+               g_value_set_string (target_value, "plain/password");
 
        return TRUE;
 }
 
-static gboolean
-source_webdav_path_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+static void
+source_webdav_update_properties_from_soup_uri (ESourceWebdav *webdav_extension)
 {
-       GObject *target;
+       ESource *source;
+       ESourceExtension *extension;
        SoupURI *soup_uri;
-       const gchar *path;
+       const gchar *extension_name;
 
-       path = g_value_get_string (source_value);
+       /* Do not use e_source_webdav_dup_soup_uri() here.  That
+        * builds the URI from properties we haven't yet updated. */
+       g_mutex_lock (webdav_extension->priv->property_lock);
+       soup_uri = soup_uri_copy (webdav_extension->priv->soup_uri);
+       g_mutex_unlock (webdav_extension->priv->property_lock);
 
-       /* soup_uri_set_path() warns on NULL. */
-       if (path == NULL)
-               path = "";
+       extension = E_SOURCE_EXTENSION (webdav_extension);
+       source = e_source_extension_get_source (extension);
 
-       target = g_binding_get_target (binding);
-       g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
+       g_object_set (
+               extension,
+               "resource-path", soup_uri->path,
+               "resource-query", soup_uri->query,
+               NULL);
 
-       soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-       soup_uri_set_path (soup_uri, path);
-       g_value_take_boxed (target_value, soup_uri);
+       extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+       extension = e_source_get_extension (source, extension_name);
 
-       return TRUE;
-}
+       g_object_set (
+               extension,
+               "host", soup_uri->host,
+               "port", soup_uri->port,
+               "user", soup_uri->user,
+               NULL);
 
-static gboolean
-source_webdav_soup_uri_to_path (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-       SoupURI *soup_uri;
+       extension_name = E_SOURCE_EXTENSION_SECURITY;
+       extension = e_source_get_extension (source, extension_name);
 
-       soup_uri = g_value_get_boxed (source_value);
-       g_value_set_string (target_value, soup_uri->path);
+       g_object_set (
+               extension,
+               "secure", (soup_uri->scheme == SOUP_URI_SCHEME_HTTPS),
+               NULL);
 
-       return TRUE;
+       soup_uri_free (soup_uri);
 }
 
-static gboolean
-source_webdav_port_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
+static void
+source_webdav_update_soup_uri_from_properties (ESourceWebdav *webdav_extension)
 {
-       GObject *target;
+       ESource *source;
+       ESourceExtension *extension;
        SoupURI *soup_uri;
+       const gchar *extension_name;
+       gchar *user;
+       gchar *host;
+       gchar *path;
+       gchar *query;
        guint port;
+       gboolean secure;
 
-       port = g_value_get_uint (source_value);
-
-       target = g_binding_get_target (binding);
-       g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
-
-       soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-       soup_uri_set_port (soup_uri, port);
-       g_value_take_boxed (target_value, soup_uri);
+       extension = E_SOURCE_EXTENSION (webdav_extension);
+       source = e_source_extension_get_source (extension);
 
-       return TRUE;
-}
+       g_object_get (
+               extension,
+               "resource-path", &path,
+               "resource-query", &query,
+               NULL);
 
-static gboolean
-source_webdav_soup_uri_to_port (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-       SoupURI *soup_uri;
+       extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+       extension = e_source_get_extension (source, extension_name);
 
-       soup_uri = g_value_get_boxed (source_value);
-       g_value_set_uint (target_value, soup_uri->port);
+       g_object_get (
+               extension,
+               "user", &user,
+               "host", &host,
+               "port", &port,
+               NULL);
 
-       return TRUE;
-}
+       extension_name = E_SOURCE_EXTENSION_SECURITY;
+       extension = e_source_get_extension (source, extension_name);
 
-static gboolean
-source_webdav_secure_to_soup_uri (GBinding *binding,
-                                  const GValue *source_value,
-                                  GValue *target_value,
-                                  gpointer user_data)
-{
-       GObject *target;
-       SoupURI *soup_uri;
-       gboolean secure;
+       g_object_get (
+               extension,
+               "secure", &secure,
+               NULL);
 
-       secure = g_value_get_boolean (source_value);
+       g_mutex_lock (webdav_extension->priv->property_lock);
 
-       target = g_binding_get_target (binding);
-       g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
+       soup_uri = webdav_extension->priv->soup_uri;
 
-       soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
-       if (secure)
+       /* Try not to disturb the scheme, in case it's "webcal" or some
+        * other non-standard value.  But if we have to change it, do it. */
+       if (secure && soup_uri->scheme != SOUP_URI_SCHEME_HTTPS)
                soup_uri_set_scheme (soup_uri, SOUP_URI_SCHEME_HTTPS);
-       else
+       if (!secure && soup_uri->scheme == SOUP_URI_SCHEME_HTTPS)
                soup_uri_set_scheme (soup_uri, SOUP_URI_SCHEME_HTTP);
-       g_value_take_boxed (target_value, soup_uri);
-
-       return TRUE;
-}
-
-static gboolean
-source_webdav_soup_uri_to_secure (GBinding *binding,
-                                  const GValue *source_value,
-                                  GValue *target_value,
-                                  gpointer user_data)
-{
-       SoupURI *soup_uri;
-       gboolean secure;
 
-       soup_uri = g_value_get_boxed (source_value);
-       secure = (soup_uri->scheme == SOUP_URI_SCHEME_HTTPS);
-       g_value_set_boolean (target_value, secure);
-
-       return TRUE;
-}
-
-static gboolean
-source_webdav_user_to_soup_uri (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-       GObject *target;
-       SoupURI *soup_uri;
-       const gchar *user;
-
-       user = g_value_get_string (source_value);
-
-       target = g_binding_get_target (binding);
-       g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
-
-       soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
        soup_uri_set_user (soup_uri, user);
-       g_value_take_boxed (target_value, soup_uri);
-
-       return TRUE;
-}
+       soup_uri_set_host (soup_uri, host);
+       soup_uri_set_port (soup_uri, port);
 
-static gboolean
-source_webdav_soup_uri_to_user (GBinding *binding,
-                                const GValue *source_value,
-                                GValue *target_value,
-                                gpointer user_data)
-{
-       SoupURI *soup_uri;
+       /* SoupURI doesn't like NULL paths. */
+       soup_uri_set_path (soup_uri, (path != NULL) ? path : "");
 
-       soup_uri = g_value_get_boxed (source_value);
-       g_value_set_string (target_value, soup_uri->user);
+       soup_uri_set_query (soup_uri, query);
 
-       return TRUE;
-}
+       g_mutex_unlock (webdav_extension->priv->property_lock);
 
-static gboolean
-source_webdav_user_to_method (GBinding *binding,
-                              const GValue *source_value,
-                              GValue *target_value,
-                              gpointer user_data)
-{
-       const gchar *user;
-
-       user = g_value_get_string (source_value);
-       if (user == NULL || *user == '\0')
-               g_value_set_string (target_value, "none");
-       else
-               g_value_set_string (target_value, "plain/password");
-
-       return TRUE;
+       g_free (user);
+       g_free (host);
+       g_free (path);
+       g_free (query);
 }
 
 static void
@@ -330,6 +264,12 @@ source_webdav_set_property (GObject *object,
                                g_value_get_string (value));
                        return;
 
+               case PROP_RESOURCE_QUERY:
+                       e_source_webdav_set_resource_query (
+                               E_SOURCE_WEBDAV (object),
+                               g_value_get_string (value));
+                       return;
+
                case PROP_SOUP_URI:
                        e_source_webdav_set_soup_uri (
                                E_SOURCE_WEBDAV (object),
@@ -389,6 +329,13 @@ source_webdav_get_property (GObject *object,
                                E_SOURCE_WEBDAV (object)));
                        return;
 
+               case PROP_RESOURCE_QUERY:
+                       g_value_take_string (
+                               value,
+                               e_source_webdav_dup_resource_query (
+                               E_SOURCE_WEBDAV (object)));
+                       return;
+
                case PROP_SOUP_URI:
                        g_value_take_boxed (
                                value,
@@ -412,8 +359,9 @@ source_webdav_finalize (GObject *object)
        g_free (priv->display_name);
        g_free (priv->email_address);
        g_free (priv->resource_path);
+       g_free (priv->resource_query);
 
-       soup_uri_free (priv->uri);
+       soup_uri_free (priv->soup_uri);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_source_webdav_parent_class)->finalize (object);
@@ -423,76 +371,59 @@ static void
 source_webdav_constructed (GObject *object)
 {
        ESource *source;
-       ESourceExtension *this_extension;
-       ESourceExtension *other_extension;
+       ESourceExtension *extension;
        const gchar *extension_name;
 
        /* Chain up to parent's constructed() method. */
        G_OBJECT_CLASS (e_source_webdav_parent_class)->constructed (object);
 
-       this_extension = E_SOURCE_EXTENSION (object);
-       source = e_source_extension_get_source (this_extension);
+       /* XXX I *think* we don't need to worry about disconnecting the
+        *     signals.  ESourceExtensions are only added, never removed,
+        *     and they all finalize with their ESource.  At least that's
+        *     how it's supposed to work if everyone follows the rules. */
 
-       g_object_bind_property_full (
-               this_extension, "resource-path",
-               this_extension, "soup-uri",
-               G_BINDING_BIDIRECTIONAL |
-               G_BINDING_SYNC_CREATE,
-               source_webdav_path_to_soup_uri,
-               source_webdav_soup_uri_to_path,
-               NULL, (GDestroyNotify) NULL);
+       extension = E_SOURCE_EXTENSION (object);
+       source = e_source_extension_get_source (extension);
+
+       g_signal_connect (
+               extension, "notify::resource-path",
+               G_CALLBACK (source_webdav_notify_cb), object);
 
-       /* Bind to properties of other extensions for convenience. */
+       g_signal_connect (
+               extension, "notify::resource-query",
+               G_CALLBACK (source_webdav_notify_cb), object);
 
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
-       other_extension = e_source_get_extension (source, extension_name);
+       extension = e_source_get_extension (source, extension_name);
 
-       g_object_bind_property_full (
-               other_extension, "host",
-               this_extension, "soup-uri",
-               G_BINDING_BIDIRECTIONAL |
-               G_BINDING_SYNC_CREATE,
-               source_webdav_host_to_soup_uri,
-               source_webdav_soup_uri_to_host,
-               NULL, (GDestroyNotify) NULL);
+       g_signal_connect (
+               extension, "notify::host",
+               G_CALLBACK (source_webdav_notify_cb), object);
 
-       g_object_bind_property_full (
-               other_extension, "port",
-               this_extension, "soup-uri",
-               G_BINDING_BIDIRECTIONAL |
-               G_BINDING_SYNC_CREATE,
-               source_webdav_port_to_soup_uri,
-               source_webdav_soup_uri_to_port,
-               NULL, (GDestroyNotify) NULL);
+       g_signal_connect (
+               extension, "notify::port",
+               G_CALLBACK (source_webdav_notify_cb), object);
 
-       g_object_bind_property_full (
-               other_extension, "user",
-               this_extension, "soup-uri",
-               G_BINDING_BIDIRECTIONAL |
-               G_BINDING_SYNC_CREATE,
-               source_webdav_user_to_soup_uri,
-               source_webdav_soup_uri_to_user,
-               NULL, (GDestroyNotify) NULL);
+       g_signal_connect (
+               extension, "notify::user",
+               G_CALLBACK (source_webdav_notify_cb), object);
 
+       /* This updates the authentication method
+        * based on whether a user name was given. */
        g_object_bind_property_full (
-               other_extension, "user",
-               other_extension, "method",
+               extension, "user",
+               extension, "method",
                G_BINDING_SYNC_CREATE,
                source_webdav_user_to_method,
                NULL,
                NULL, (GDestroyNotify) NULL);
 
        extension_name = E_SOURCE_EXTENSION_SECURITY;
-       other_extension = e_source_get_extension (source, extension_name);
+       extension = e_source_get_extension (source, extension_name);
 
-       g_object_bind_property_full (
-               other_extension, "secure",
-               this_extension, "soup-uri",
-               G_BINDING_BIDIRECTIONAL |
-               G_BINDING_SYNC_CREATE,
-               source_webdav_secure_to_soup_uri,
-               source_webdav_soup_uri_to_secure,
-               NULL, (GDestroyNotify) NULL);
+       g_signal_connect (
+               extension, "notify::secure",
+               G_CALLBACK (source_webdav_notify_cb), object);
 }
 
 static void
@@ -587,6 +518,18 @@ e_source_webdav_class_init (ESourceWebdavClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_RESOURCE_QUERY,
+               g_param_spec_string (
+                       "resource-query",
+                       "Resource Query",
+                       "Query to access a WebDAV resource",
+                       NULL,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       E_SOURCE_PARAM_SETTING));
+
+       g_object_class_install_property (
+               object_class,
                PROP_SOUP_URI,
                g_param_spec_boxed (
                        "soup-uri",
@@ -603,9 +546,9 @@ e_source_webdav_init (ESourceWebdav *extension)
        extension->priv->property_lock = g_mutex_new ();
 
        /* Initialize this enough for SOUP_URI_IS_VALID() to pass. */
-       extension->priv->uri = soup_uri_new (NULL);
-       extension->priv->uri->scheme = SOUP_URI_SCHEME_HTTP;
-       extension->priv->uri->path = g_strdup ("");
+       extension->priv->soup_uri = soup_uri_new (NULL);
+       extension->priv->soup_uri->scheme = SOUP_URI_SCHEME_HTTP;
+       extension->priv->soup_uri->path = g_strdup ("");
 }
 
 /**
@@ -1014,6 +957,100 @@ e_source_webdav_set_resource_path (ESourceWebdav *extension,
 }
 
 /**
+ * e_source_webdav_get_resource_query:
+ * @extension: an #ESourceWebdav
+ *
+ * Returns the URI query required to access a resource on a WebDAV server.
+ *
+ * This is typically used when the #ESourceWebdav:resource-path points not
+ * to the resource itself but to a web program that generates the resource
+ * content on-the-fly.  The #ESourceWebdav:resource-query holds the input
+ * values for the program.
+ *
+ * Returns: the query to access a WebDAV resource
+ *
+ * Since: 3.6
+ **/
+const gchar *
+e_source_webdav_get_resource_query (ESourceWebdav *extension)
+{
+       g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
+
+       return extension->priv->resource_query;
+}
+
+/**
+ * e_source_webdav_dup_resource_query:
+ * @extension: an #ESourceWebdav
+ *
+ * Thread-safe variation of e_source_webdav_get_resource_query().
+ * Use this function when accessing @extension from multiple threads.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: the newly-allocated copy of #ESourceWebdav:resource-query
+ *
+ * Since: 3.6
+ **/
+gchar *
+e_source_webdav_dup_resource_query (ESourceWebdav *extension)
+{
+       const gchar *protected;
+       gchar *duplicate;
+
+       g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
+
+       g_mutex_lock (extension->priv->property_lock);
+
+       protected = e_source_webdav_get_resource_query (extension);
+       duplicate = g_strdup (protected);
+
+       g_mutex_unlock (extension->priv->property_lock);
+
+       return duplicate;
+}
+
+/**
+ * e_source_webdav_set_resource_query:
+ * @extension: an #ESourceWebdav
+ * @resource_query: (allow-none): the query to access a WebDAV resource,
+ *                  or %NULL
+ *
+ * Sets the URI query required to access a resource on a WebDAV server.
+ *
+ * This is typically used when the #ESourceWebdav:resource-path points not
+ * to the resource itself but to a web program that generates the resource
+ * content on-the-fly.  The #ESourceWebdav:resource-query holds the input
+ * values for the program.
+ *
+ * The internal copy of @resource_query is automatically stripped of leading
+ * and trailing whitespace.  If the resulting string is empty, %NULL is set
+ * instead.
+ *
+ * Since: 3.6
+ **/
+void
+e_source_webdav_set_resource_query (ESourceWebdav *extension,
+                                    const gchar *resource_query)
+{
+       g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
+
+       g_mutex_lock (extension->priv->property_lock);
+
+       if (g_strcmp0 (extension->priv->resource_query, resource_query) == 0) {
+               g_mutex_unlock (extension->priv->property_lock);
+               return;
+       }
+
+       g_free (extension->priv->resource_query);
+       extension->priv->resource_query = e_util_strdup_strip (resource_query);
+
+       g_mutex_unlock (extension->priv->property_lock);
+
+       g_object_notify (G_OBJECT (extension), "resource-query");
+}
+
+/**
  * e_source_webdav_dup_soup_uri:
  * @extension: an #ESourceWebdav
  *
@@ -1033,9 +1070,12 @@ e_source_webdav_dup_soup_uri (ESourceWebdav *extension)
 
        g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
 
+       /* Keep this outside of the property lock. */
+       source_webdav_update_soup_uri_from_properties (extension);
+
        g_mutex_lock (extension->priv->property_lock);
 
-       duplicate = soup_uri_copy (extension->priv->uri);
+       duplicate = soup_uri_copy (extension->priv->soup_uri);
 
        g_mutex_unlock (extension->priv->property_lock);
 
@@ -1045,34 +1085,35 @@ e_source_webdav_dup_soup_uri (ESourceWebdav *extension)
 /**
  * e_source_webdav_set_soup_uri:
  * @extension: an #ESourceWebdav
- * @uri: a #SoupURI
+ * @soup_uri: a #SoupURI
  *
  * This is a convenience function which propagates the components of
  * @uri to the #ESourceAuthentication extension, the #ESourceSecurity
- * extension, and @extension itself.  (The "query" and "fragment"
- * components of @uri are ignored.)
+ * extension, and @extension itself.  (The "fragment" component of
+ * @uri is ignored.)
  *
  * Since: 3.6
  **/
 void
 e_source_webdav_set_soup_uri (ESourceWebdav *extension,
-                              SoupURI *uri)
+                              SoupURI *soup_uri)
 {
        g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
-       g_return_if_fail (SOUP_URI_IS_VALID (uri));
+       g_return_if_fail (SOUP_URI_IS_VALID (soup_uri));
 
        g_mutex_lock (extension->priv->property_lock);
 
-       if (extension->priv->uri && soup_uri_equal (extension->priv->uri, uri)) {
-               g_mutex_unlock (extension->priv->property_lock);
-               return;
-       }
+       /* Do not test for URI equality because our
+        * internal SoupURI might not be up-to-date. */
 
-       soup_uri_free (extension->priv->uri);
-       extension->priv->uri = soup_uri_copy (uri);
+       soup_uri_free (extension->priv->soup_uri);
+       extension->priv->soup_uri = soup_uri_copy (soup_uri);
 
        g_mutex_unlock (extension->priv->property_lock);
 
+       g_object_freeze_notify (G_OBJECT (extension));
+       source_webdav_update_properties_from_soup_uri (extension);
        g_object_notify (G_OBJECT (extension), "soup-uri");
+       g_object_thaw_notify (G_OBJECT (extension));
 }
 
index 1e69471..797d238 100644 (file)
@@ -115,9 +115,16 @@ gchar *            e_source_webdav_dup_resource_path
 void           e_source_webdav_set_resource_path
                                                (ESourceWebdav *extension,
                                                 const gchar *resource_path);
+const gchar *  e_source_webdav_get_resource_query
+                                               (ESourceWebdav *extension);
+gchar *                e_source_webdav_dup_resource_query
+                                               (ESourceWebdav *extension);
+void           e_source_webdav_set_resource_query
+                                               (ESourceWebdav *extension,
+                                                const gchar *resource_query);
 SoupURI *      e_source_webdav_dup_soup_uri    (ESourceWebdav *extension);
 void           e_source_webdav_set_soup_uri    (ESourceWebdav *extension,
-                                                SoupURI *uri);
+                                                SoupURI *soup_uri);
 
 G_END_DECLS
 
index cabc692..99f8025 100644 (file)
@@ -2254,6 +2254,12 @@ migrate_parse_caldav_source (ParseData *parse_data)
                        E_SOURCE_EXTENSION_WEBDAV_BACKEND,
                        "ResourcePath", parse_data->soup_uri->path);
 
+       if (parse_data->soup_uri->query != NULL)
+               g_key_file_set_string (
+                       parse_data->key_file,
+                       E_SOURCE_EXTENSION_WEBDAV_BACKEND,
+                       "ResourceQuery", parse_data->soup_uri->query);
+
        parse_data->property_func = migrate_parse_caldav_property;
 }
 
@@ -2502,6 +2508,12 @@ migrate_parse_webcal_source (ParseData *parse_data)
                        E_SOURCE_EXTENSION_WEBDAV_BACKEND,
                        "ResourcePath", parse_data->soup_uri->path);
 
+       if (parse_data->soup_uri->query != NULL)
+               g_key_file_set_string (
+                       parse_data->key_file,
+                       E_SOURCE_EXTENSION_WEBDAV_BACKEND,
+                       "ResourceQuery", parse_data->soup_uri->query);
+
        /* Webcal Backend has no special properties to parse. */
 }
 
@@ -2546,6 +2558,12 @@ migrate_parse_webdav_source (ParseData *parse_data)
                        E_SOURCE_EXTENSION_WEBDAV_BACKEND,
                        "ResourcePath", parse_data->soup_uri->path);
 
+       if (parse_data->soup_uri->query != NULL)
+               g_key_file_set_string (
+                       parse_data->key_file,
+                       E_SOURCE_EXTENSION_WEBDAV_BACKEND,
+                       "ResourceQuery", parse_data->soup_uri->query);
+
        parse_data->property_func = migrate_parse_webdav_property;
 }