[evolution] Bug 789571 - Handle webcal:// URI to add new On The Web calendar



commit 73a7fd56a5543b54d32cb8b663ecb2e804a08149
Author: Milan Crha <mcrha redhat com>
Date:   Thu Nov 16 17:30:21 2017 +0100

    Bug 789571 - Handle webcal:// URI to add new On The Web calendar

 data/org.gnome.Evolution.desktop.in.in          |    2 +-
 src/e-util/e-source-config.c                    |   45 ++++++++++
 src/e-util/e-source-config.h                    |    3 +
 src/modules/calendar/e-cal-base-shell-backend.c |   99 +++++++++++++++++++++++
 4 files changed, 148 insertions(+), 1 deletions(-)
---
diff --git a/data/org.gnome.Evolution.desktop.in.in b/data/org.gnome.Evolution.desktop.in.in
index c0d07e6..f047013 100644
--- a/data/org.gnome.Evolution.desktop.in.in
+++ b/data/org.gnome.Evolution.desktop.in.in
@@ -17,7 +17,7 @@ X-GNOME-Bugzilla-Component=BugBuddyBugs
 X-GNOME-Bugzilla-Version=@BASE_VERSION@.x
 
X-GNOME-Bugzilla-OtherBinaries=evolution-addressbook-factory;evolution-calendar-factory;evolution-source-registry;evolution-user-prompter;
 X-GNOME-UsesNotifications=true
-MimeType=text/calendar;text/x-vcard;text/directory;application/mbox;message/rfc822;x-scheme-handler/mailto;
+MimeType=text/calendar;text/x-vcard;text/directory;application/mbox;message/rfc822;x-scheme-handler/mailto;x-scheme-handler/webcal;
 
 [Desktop Action new-window]
 _Name=New Window
diff --git a/src/e-util/e-source-config.c b/src/e-util/e-source-config.c
index e6e788d..c46c6ad 100644
--- a/src/e-util/e-source-config.c
+++ b/src/e-util/e-source-config.c
@@ -1121,6 +1121,30 @@ e_source_config_get_page (ESourceConfig *config,
        return page;
 }
 
+void
+e_source_config_select_page (ESourceConfig *config,
+                            ESource *scratch_source)
+{
+       Candidate *candidate;
+       GPtrArray *array;
+       gint index;
+
+       g_return_if_fail (E_IS_SOURCE_CONFIG (config));
+       g_return_if_fail (E_IS_SOURCE (scratch_source));
+
+       array = config->priv->candidates;
+
+       for (index = 0; index < array->len; index++) {
+               candidate = g_ptr_array_index (array, index);
+               if (e_source_equal (scratch_source, candidate->scratch_source)) {
+                       gtk_combo_box_set_active (GTK_COMBO_BOX (config->priv->type_combo), index);
+                       return;
+               }
+       }
+
+       g_warn_if_reached ();
+}
+
 const gchar *
 e_source_config_get_backend_extension_name (ESourceConfig *config)
 {
@@ -1194,6 +1218,27 @@ e_source_config_get_collection_source (ESourceConfig *config)
        return config->priv->collection_source;
 }
 
+GSList * /* (transfer full) (element-type #ESource) */
+e_source_config_list_candidates (ESourceConfig *config)
+{
+       GSList *candidates = NULL;
+       GPtrArray *array;
+       gint index;
+
+       g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL);
+
+       array = config->priv->candidates;
+
+       for (index = 0; index < array->len; index++) {
+               Candidate *candidate;
+
+               candidate = g_ptr_array_index (array, index);
+               candidates = g_slist_prepend (candidates, g_object_ref (candidate->scratch_source));
+       }
+
+       return g_slist_reverse (candidates);
+}
+
 ESourceRegistry *
 e_source_config_get_registry (ESourceConfig *config)
 {
diff --git a/src/e-util/e-source-config.h b/src/e-util/e-source-config.h
index 93bb4e1..596f62e 100644
--- a/src/e-util/e-source-config.h
+++ b/src/e-util/e-source-config.h
@@ -83,6 +83,8 @@ void          e_source_config_insert_widget   (ESourceConfig *config,
                                                 GtkWidget *widget);
 GtkWidget *    e_source_config_get_page        (ESourceConfig *config,
                                                 ESource *scratch_source);
+void           e_source_config_select_page     (ESourceConfig *config,
+                                                ESource *scratch_source);
 const gchar *  e_source_config_get_backend_extension_name
                                                (ESourceConfig *config);
 GList *                e_source_config_list_eligible_collections
@@ -92,6 +94,7 @@ ESource *     e_source_config_get_original_source
                                                (ESourceConfig *config);
 ESource *      e_source_config_get_collection_source
                                                (ESourceConfig *config);
+GSList *       e_source_config_list_candidates (ESourceConfig *config); /* ESource * */
 ESourceRegistry *
                e_source_config_get_registry    (ESourceConfig *config);
 void           e_source_config_resize_window   (ESourceConfig *config);
diff --git a/src/modules/calendar/e-cal-base-shell-backend.c b/src/modules/calendar/e-cal-base-shell-backend.c
index e7f524a..245ac45 100644
--- a/src/modules/calendar/e-cal-base-shell-backend.c
+++ b/src/modules/calendar/e-cal-base-shell-backend.c
@@ -42,6 +42,100 @@ struct _ECalBaseShellBackendPrivate {
 
 G_DEFINE_ABSTRACT_TYPE (ECalBaseShellBackend, e_cal_base_shell_backend, E_TYPE_SHELL_BACKEND)
 
+static void
+cal_base_shell_backend_handle_webcal_uri (EShellBackend *shell_backend,
+                                         const gchar *uri)
+{
+       EShell *shell;
+       ESourceRegistry *registry;
+       ESourceConfig *source_config;
+       const gchar *extension_name;
+       GtkWidget *config;
+       GtkWidget *dialog;
+       GtkWindow *window, *active_window;
+       GSList *candidates, *link;
+
+       g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+       g_return_if_fail (uri != NULL);
+
+       shell = e_shell_backend_get_shell (shell_backend);
+
+       active_window = e_shell_get_active_window (shell);
+       registry = e_shell_get_registry (shell);
+       config = e_cal_source_config_new (registry, NULL, E_CAL_CLIENT_SOURCE_TYPE_EVENTS);
+       source_config = E_SOURCE_CONFIG (config);
+
+       extension_name = e_source_config_get_backend_extension_name (source_config);
+
+       dialog = e_source_config_dialog_new (source_config);
+       window = GTK_WINDOW (dialog);
+
+       if (active_window)
+               gtk_window_set_transient_for (window, active_window);
+       gtk_window_set_icon_name (window, "x-office-calendar");
+       gtk_window_set_title (window, _("New Calendar"));
+
+       gtk_widget_show (dialog);
+
+       /* Can do this only after the dialog is shown, thus the list
+          of candidates is populated. */
+       candidates = e_source_config_list_candidates (source_config);
+
+       for (link = candidates; link; link = g_slist_next (link)) {
+               ESource *candidate = link->data;
+
+               if (e_source_has_extension (candidate, extension_name)) {
+                       const gchar *backend_name;
+
+                       backend_name = e_source_backend_get_backend_name (
+                               e_source_get_extension (candidate, extension_name));
+                       if (g_strcmp0 (backend_name, "webcal") == 0) {
+                               ESourceWebdav *webdav_extension;
+                               SoupURI *soup_uri;
+
+                               soup_uri = soup_uri_new (uri);
+                               if (!soup_uri) {
+                                       /* Just a fallback when the passed-in URI is invalid,
+                                          to have set something in the UI. */
+                                       soup_uri = soup_uri_new (NULL);
+                                       soup_uri_set_path (soup_uri, uri);
+                               }
+
+                               /* https everywhere */
+                               soup_uri_set_scheme (soup_uri, "https");
+
+                               if (soup_uri_get_path (soup_uri)) {
+                                       gchar *basename;
+
+                                       basename = g_path_get_basename (soup_uri_get_path (soup_uri));
+                                       if (basename && g_utf8_strlen (basename, -1) > 3) {
+                                               gchar *dot;
+
+                                               dot = strrchr (basename, '.');
+                                               if (dot && strlen (dot) <= 4)
+                                                       *dot = '\0';
+
+                                               if (*basename)
+                                                       e_source_set_display_name (candidate, basename);
+                                       }
+
+                                       g_free (basename);
+                               }
+
+                               webdav_extension = e_source_get_extension (candidate, 
E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+                               e_source_webdav_set_soup_uri (webdav_extension, soup_uri);
+
+                               e_source_config_select_page (source_config, candidate);
+
+                               soup_uri_free (soup_uri);
+                               break;
+                       }
+               }
+       }
+
+       g_slist_free_full (candidates, g_object_unref);
+}
+
 static gboolean
 cal_base_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
                                      const gchar *uri)
@@ -51,6 +145,11 @@ cal_base_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
        g_return_val_if_fail (E_IS_CAL_BASE_SHELL_BACKEND (shell_backend), FALSE);
        g_return_val_if_fail (uri != NULL, FALSE);
 
+       if (g_str_has_prefix (uri, "webcal:")) {
+               cal_base_shell_backend_handle_webcal_uri (shell_backend, uri);
+               return TRUE;
+       }
+
        klass = E_CAL_BASE_SHELL_BACKEND_GET_CLASS (shell_backend);
        g_return_val_if_fail (klass != NULL, FALSE);
 


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