[evolution] eds-I#165 - Add backend to access Nextcloud Notes



commit a5eec0c5c3c2faca7066fa5b611f1c1e66a4ea6e
Author: Milan Crha <mcrha redhat com>
Date:   Fri Mar 6 09:29:20 2020 +0100

    eds-I#165 - Add backend to access Nextcloud Notes
    
    Related to https://gitlab.gnome.org/GNOME/evolution-data-server/issues/165

 po/POTFILES.in                                     |   1 +
 src/calendar/gui/e-comp-editor-memo.c              | 136 ++++++-
 src/calendar/gui/e-comp-editor-page-attachments.c  |  15 +
 src/modules/CMakeLists.txt                         |   1 +
 src/modules/cal-config-webdav-notes/CMakeLists.txt |  17 +
 .../evolution-cal-config-webdav-notes.c            | 440 +++++++++++++++++++++
 6 files changed, 605 insertions(+), 5 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a9aed0ef59..6e67c78c36 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -415,6 +415,7 @@ src/modules/cal-config-google/e-google-chooser-button.c
 src/modules/cal-config-local/evolution-cal-config-local.c
 src/modules/cal-config-weather/evolution-cal-config-weather.c
 src/modules/cal-config-webcal/evolution-cal-config-webcal.c
+src/modules/cal-config-webdav-notes/evolution-cal-config-webdav-notes.c
 src/modules/calendar/e-cal-attachment-handler.c
 src/modules/calendar/e-cal-base-shell-backend.c
 src/modules/calendar/e-cal-base-shell-content.c
diff --git a/src/calendar/gui/e-comp-editor-memo.c b/src/calendar/gui/e-comp-editor-memo.c
index 1a1bff2f74..ee1bb04060 100644
--- a/src/calendar/gui/e-comp-editor-memo.c
+++ b/src/calendar/gui/e-comp-editor-memo.c
@@ -31,15 +31,90 @@
 #include "e-comp-editor-memo.h"
 
 struct _ECompEditorMemoPrivate {
+       ECompEditorPropertyPart *summary;
        ECompEditorPropertyPart *dtstart;
+       ECompEditorPropertyPart *classification;
+       ECompEditorPropertyPart *status;
+       ECompEditorPropertyPart *url;
        ECompEditorPropertyPart *categories;
        ECompEditorPropertyPart *description;
+       ECompEditorPage *attachments_page;
 
        gpointer insensitive_info_alert;
 };
 
 G_DEFINE_TYPE (ECompEditorMemo, e_comp_editor_memo, E_TYPE_COMP_EDITOR)
 
+/* A rough code to mimic what Nextcloud does, it's not accurate, but it's close
+   enough to work similarly. It skips leading whitespaces and uses up to the first
+   100 letters of the first non-empty line as the base file name. */
+static gchar *
+ece_memo_construct_summary (const gchar *description)
+{
+       GString *base_filename;
+       gunichar uchr;
+       gboolean add_space = FALSE;
+
+       if (!description || !*description || !g_utf8_validate (description, -1, NULL))
+               return g_strdup (_("New note"));
+
+       base_filename = g_string_sized_new (102);
+
+       while (uchr = g_utf8_get_char (description), g_unichar_isspace (uchr))
+               description = g_utf8_next_char (description);
+
+       while (uchr = g_utf8_get_char (description), uchr && uchr != '\r' && uchr != '\n') {
+               if (g_unichar_isspace (uchr)) {
+                       add_space = TRUE;
+               } else if ((uchr >> 8) != 0 || !strchr ("\"/\\?:*|", (uchr & 0xFF))) {
+                       if (base_filename->len >= 98)
+                               break;
+
+                       if (add_space) {
+                               g_string_append_c (base_filename, ' ');
+                               add_space = FALSE;
+                       }
+
+                       g_string_append_unichar (base_filename, uchr);
+
+                       if (base_filename->len >= 100)
+                               break;
+               }
+
+               description = g_utf8_next_char (description);
+       }
+
+       if (!base_filename->len)
+               g_string_append (base_filename, _("New note"));
+
+       return g_string_free (base_filename, FALSE);
+}
+
+static void
+ece_memo_description_changed_cb (GtkTextBuffer *text_buffer,
+                                gpointer user_data)
+{
+       ECompEditorMemo *memo_editor = user_data;
+       GtkTextIter text_iter_start, text_iter_end;
+       GtkWidget *entry;
+       gchar *value, *summary;
+
+       g_return_if_fail (GTK_IS_TEXT_BUFFER (text_buffer));
+       g_return_if_fail (E_IS_COMP_EDITOR_MEMO (memo_editor));
+       g_return_if_fail (!e_comp_editor_property_part_get_visible (memo_editor->priv->summary));
+
+       gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
+       gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end);
+       value = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE);
+
+       summary = ece_memo_construct_summary (value);
+       entry = e_comp_editor_property_part_get_edit_widget (memo_editor->priv->summary);
+       gtk_entry_set_text (GTK_ENTRY (entry), summary);
+
+       g_free (summary);
+       g_free (value);
+}
+
 static void
 ece_memo_notify_target_client_cb (GObject *object,
                                  GParamSpec *param,
@@ -48,6 +123,9 @@ ece_memo_notify_target_client_cb (GObject *object,
        ECompEditorMemo *memo_editor;
        ECompEditor *comp_editor;
        ECalClient *cal_client;
+       GtkAction *action;
+       GtkWidget *description_widget;
+       GtkTextBuffer *text_buffer;
        gboolean supports_date;
 
        g_return_if_fail (E_IS_COMP_EDITOR_MEMO (object));
@@ -55,10 +133,54 @@ ece_memo_notify_target_client_cb (GObject *object,
        memo_editor = E_COMP_EDITOR_MEMO (object);
        comp_editor = E_COMP_EDITOR (memo_editor);
        cal_client = e_comp_editor_get_target_client (comp_editor);
+       description_widget = gtk_bin_get_child (GTK_BIN (e_comp_editor_property_part_get_edit_widget 
(memo_editor->priv->description)));
+       text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (description_widget));
+
+       if (cal_client && e_client_check_capability (E_CLIENT (cal_client), 
E_CAL_STATIC_CAPABILITY_SIMPLE_MEMO)) {
+               if (e_comp_editor_property_part_get_visible (memo_editor->priv->summary)) {
+                       g_signal_connect (text_buffer, "changed",
+                               G_CALLBACK (ece_memo_description_changed_cb), memo_editor);
+
+                       gtk_widget_grab_focus (description_widget);
+               }
 
-       supports_date = !cal_client || !e_client_check_capability (E_CLIENT (cal_client), 
E_CAL_STATIC_CAPABILITY_NO_MEMO_START_DATE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->summary, FALSE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->dtstart, FALSE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->classification, FALSE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->status, FALSE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->url, FALSE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->categories, FALSE);
 
-       e_comp_editor_property_part_set_visible (memo_editor->priv->dtstart, supports_date);
+               gtk_widget_hide (GTK_WIDGET (memo_editor->priv->attachments_page));
+
+               action = e_comp_editor_get_action (comp_editor, "view-categories");
+               gtk_action_set_sensitive (action, FALSE);
+
+               action = e_comp_editor_get_action (comp_editor, "option-attendees");
+               gtk_action_set_visible (action, FALSE);
+       } else {
+               supports_date = !cal_client || !e_client_check_capability (E_CLIENT (cal_client), 
E_CAL_STATIC_CAPABILITY_NO_MEMO_START_DATE);
+
+               if (!e_comp_editor_property_part_get_visible (memo_editor->priv->summary)) {
+                       g_signal_handlers_disconnect_by_func (text_buffer,
+                               G_CALLBACK (ece_memo_description_changed_cb), memo_editor);
+               }
+
+               e_comp_editor_property_part_set_visible (memo_editor->priv->summary, TRUE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->dtstart, supports_date);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->classification, TRUE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->status, TRUE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->url, TRUE);
+               e_comp_editor_property_part_set_visible (memo_editor->priv->categories, TRUE);
+
+               gtk_widget_show (GTK_WIDGET (memo_editor->priv->attachments_page));
+
+               action = e_comp_editor_get_action (comp_editor, "view-categories");
+               gtk_action_set_sensitive (action, TRUE);
+
+               action = e_comp_editor_get_action (comp_editor, "option-attendees");
+               gtk_action_set_visible (action, TRUE);
+       }
 }
 
 static void
@@ -182,7 +304,7 @@ e_comp_editor_memo_constructed (GObject *object)
        ECompEditorMemo *memo_editor;
        ECompEditor *comp_editor;
        ECompEditorPage *page;
-       ECompEditorPropertyPart *part, *summary;
+       ECompEditorPropertyPart *part;
        EFocusTracker *focus_tracker;
        GtkWidget *edit_widget;
 
@@ -198,7 +320,7 @@ e_comp_editor_memo_constructed (GObject *object)
 
        part = e_comp_editor_property_part_summary_new (focus_tracker);
        e_comp_editor_page_add_property_part (page, part, 0, 2, 2, 1);
-       summary = part;
+       memo_editor->priv->summary = part;
 
        part = e_comp_editor_property_part_dtstart_new (C_("ECompEditor", "Sta_rt date:"), TRUE, TRUE);
        e_comp_editor_page_add_property_part (page, part, 0, 3, 2, 1);
@@ -206,6 +328,7 @@ e_comp_editor_memo_constructed (GObject *object)
 
        part = e_comp_editor_property_part_classification_new ();
        e_comp_editor_page_add_property_part (page, part, 0, 4, 2, 1);
+       memo_editor->priv->classification = part;
 
        edit_widget = e_comp_editor_property_part_get_edit_widget (part);
        gtk_widget_set_halign (edit_widget, GTK_ALIGN_START);
@@ -213,6 +336,7 @@ e_comp_editor_memo_constructed (GObject *object)
 
        part = e_comp_editor_property_part_status_new (I_CAL_VJOURNAL_COMPONENT);
        e_comp_editor_page_add_property_part (page, part, 0, 5, 2, 1);
+       memo_editor->priv->status = part;
 
        edit_widget = e_comp_editor_property_part_get_edit_widget (part);
        gtk_widget_set_halign (edit_widget, GTK_ALIGN_START);
@@ -220,6 +344,7 @@ e_comp_editor_memo_constructed (GObject *object)
 
        part = e_comp_editor_property_part_url_new (focus_tracker);
        e_comp_editor_page_add_property_part (page, part, 0, 6, 2, 1);
+       memo_editor->priv->url = part;
 
        part = e_comp_editor_property_part_categories_new (focus_tracker);
        e_comp_editor_page_add_property_part (page, part, 0, 7, 2, 1);
@@ -233,10 +358,11 @@ e_comp_editor_memo_constructed (GObject *object)
 
        page = e_comp_editor_page_attachments_new (comp_editor);
        e_comp_editor_add_page (comp_editor, C_("ECompEditorPage", "Attachments"), page);
+       memo_editor->priv->attachments_page = page;
 
        ece_memo_setup_ui (memo_editor);
 
-       edit_widget = e_comp_editor_property_part_get_edit_widget (summary);
+       edit_widget = e_comp_editor_property_part_get_edit_widget (memo_editor->priv->summary);
        e_binding_bind_property (edit_widget, "text", comp_editor, "title-suffix", 0);
        gtk_widget_grab_focus (edit_widget);
 
diff --git a/src/calendar/gui/e-comp-editor-page-attachments.c 
b/src/calendar/gui/e-comp-editor-page-attachments.c
index a0dffaaf66..7c3ab0015d 100644
--- a/src/calendar/gui/e-comp-editor-page-attachments.c
+++ b/src/calendar/gui/e-comp-editor-page-attachments.c
@@ -648,6 +648,7 @@ ecep_attachments_setup_ui (ECompEditorPageAttachments *page_attachments)
        ECompEditor *comp_editor;
        GtkUIManager *ui_manager;
        GtkActionGroup *action_group;
+       GtkAction *action;
        GError *error = NULL;
 
        g_return_if_fail (E_IS_COMP_EDITOR_PAGE_ATTACHMENTS (page_attachments));
@@ -660,12 +661,26 @@ ecep_attachments_setup_ui (ECompEditorPageAttachments *page_attachments)
                action_group, editable_entries,
                G_N_ELEMENTS (editable_entries), page_attachments);
 
+       action = gtk_action_group_get_action (action_group, "attachments-attach");
+
+       e_binding_bind_property (
+               page_attachments, "visible",
+               action, "visible",
+               G_BINDING_SYNC_CREATE);
+
        action_group = e_comp_editor_get_action_group (comp_editor, "individual");
 
        gtk_action_group_add_actions (
                action_group, options_entries,
                G_N_ELEMENTS (options_entries), page_attachments);
 
+       action = gtk_action_group_get_action (action_group, "page-attachments");
+
+       e_binding_bind_property (
+               page_attachments, "visible",
+               action, "visible",
+               G_BINDING_SYNC_CREATE);
+
        gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
        if (error != NULL) {
                g_warning ("%s: Failed to add UI from string: %s", G_STRFUNC, error->message);
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
index 88fefb2f49..7c7629ab6b 100644
--- a/src/modules/CMakeLists.txt
+++ b/src/modules/CMakeLists.txt
@@ -72,6 +72,7 @@ add_subdirectory(cal-config-contacts)
 add_subdirectory(cal-config-google)
 add_subdirectory(cal-config-local)
 add_subdirectory(cal-config-webcal)
+add_subdirectory(cal-config-webdav-notes)
 add_subdirectory(composer-autosave)
 add_subdirectory(composer-to-meeting)
 add_subdirectory(config-lookup)
diff --git a/src/modules/cal-config-webdav-notes/CMakeLists.txt 
b/src/modules/cal-config-webdav-notes/CMakeLists.txt
new file mode 100644
index 0000000000..1e0ea083ad
--- /dev/null
+++ b/src/modules/cal-config-webdav-notes/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(extra_deps)
+set(sources
+       evolution-cal-config-webdav-notes.c
+)
+set(extra_defines)
+set(extra_cflags)
+set(extra_incdirs)
+set(extra_ldflags)
+
+add_evolution_module(module-cal-config-webdav-notes
+       sources
+       extra_deps
+       extra_defines
+       extra_cflags
+       extra_incdirs
+       extra_ldflags
+)
diff --git a/src/modules/cal-config-webdav-notes/evolution-cal-config-webdav-notes.c 
b/src/modules/cal-config-webdav-notes/evolution-cal-config-webdav-notes.c
new file mode 100644
index 0000000000..b232fab3d9
--- /dev/null
+++ b/src/modules/cal-config-webdav-notes/evolution-cal-config-webdav-notes.c
@@ -0,0 +1,440 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat, Inc. (www.redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "evolution-config.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/libebackend.h>
+#include <libedataserverui/libedataserverui.h>
+
+#include <e-util/e-util.h>
+
+typedef ESourceConfigBackend ECalConfigWebDAVNotes;
+typedef ESourceConfigBackendClass ECalConfigWebDAVNotesClass;
+
+typedef struct _Context Context;
+
+struct _Context {
+       ESourceConfigBackend *backend;          /* not referenced */
+       ESource *scratch_source;                /* not referenced */
+
+       GtkWidget *url_entry;
+       GtkWidget *find_button;
+};
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+/* Forward Declarations */
+GType e_cal_config_webdav_notes_get_type (void);
+
+G_DEFINE_DYNAMIC_TYPE (ECalConfigWebDAVNotes, e_cal_config_webdav_notes, E_TYPE_SOURCE_CONFIG_BACKEND)
+
+static Context *
+cal_config_webdav_notes_context_new (ESourceConfigBackend *backend,
+                               ESource *scratch_source)
+{
+       Context *context;
+
+       context = g_slice_new0 (Context);
+       context->backend = backend;
+       context->scratch_source = scratch_source;
+
+       return context;
+}
+
+static void
+cal_config_webdav_notes_context_free (Context *context)
+{
+       g_clear_object (&context->url_entry);
+       g_clear_object (&context->find_button);
+
+       g_slice_free (Context, context);
+}
+
+static GtkWindow *
+caldav_config_get_dialog_parent_cb (ECredentialsPrompter *prompter,
+                                   GtkWindow *dialog)
+{
+       return dialog;
+}
+
+static void
+cal_config_webdav_notes_run_dialog (GtkButton *button,
+                              Context *context)
+{
+       ESourceConfig *config;
+       ESourceRegistry *registry;
+       ESourceWebdav *webdav_extension;
+       ECalClientSourceType source_type;
+       ECredentialsPrompter *prompter;
+       SoupURI *uri;
+       gchar *base_url;
+       GtkDialog *dialog;
+       gpointer parent;
+       gulong handler_id;
+       guint supports_filter = 0;
+       const gchar *title = NULL;
+
+       config = e_source_config_backend_get_config (context->backend);
+       registry = e_source_config_get_registry (config);
+
+       parent = gtk_widget_get_toplevel (GTK_WIDGET (config));
+       parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
+       source_type = e_cal_source_config_get_source_type (E_CAL_SOURCE_CONFIG (config));
+
+       switch (source_type) {
+       case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
+               supports_filter = E_WEBDAV_RESOURCE_SUPPORTS_WEBDAV_NOTES;
+               title = _("Choose Notes");
+               break;
+       default:
+               g_return_if_reached ();
+       }
+
+       webdav_extension = e_source_get_extension (context->scratch_source, 
E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+
+       uri = e_source_webdav_dup_soup_uri (webdav_extension);
+
+       prompter = e_credentials_prompter_new (registry);
+       e_credentials_prompter_set_auto_prompt (prompter, FALSE);
+       base_url = soup_uri_to_string (uri, FALSE);
+
+       dialog = e_webdav_discover_dialog_new (parent, title, prompter, context->scratch_source, base_url, 
supports_filter);
+
+       if (parent != NULL)
+               e_binding_bind_property (
+                       parent, "icon-name",
+                       dialog, "icon-name",
+                       G_BINDING_SYNC_CREATE);
+
+       handler_id = g_signal_connect (prompter, "get-dialog-parent",
+               G_CALLBACK (caldav_config_get_dialog_parent_cb), dialog);
+
+       e_webdav_discover_dialog_refresh (dialog);
+
+       if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT) {
+               gchar *href = NULL, *display_name = NULL, *color = NULL, *email;
+               guint supports = 0;
+               GtkWidget *content;
+
+               content = e_webdav_discover_dialog_get_content (dialog);
+
+               if (e_webdav_discover_content_get_selected (content, 0, &href, &supports, &display_name, 
&color)) {
+                       soup_uri_free (uri);
+                       uri = soup_uri_new (href);
+
+                       if (uri) {
+                               e_source_set_display_name (context->scratch_source, display_name);
+
+                               e_source_webdav_set_display_name (webdav_extension, display_name);
+                               e_source_webdav_set_soup_uri (webdav_extension, uri);
+
+                               if (color && *color) {
+                                       ESourceSelectable *selectable_extension;
+                                       const gchar *extension_name;
+
+                                       switch (source_type) {
+                                               case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
+                                                       extension_name = E_SOURCE_EXTENSION_MEMO_LIST;
+                                                       break;
+                                               default:
+                                                       g_return_if_reached ();
+                                       }
+
+                                       selectable_extension = e_source_get_extension 
(context->scratch_source, extension_name);
+
+                                       e_source_selectable_set_color (selectable_extension, color);
+                               }
+                       }
+
+                       g_free (href);
+                       g_free (display_name);
+                       g_free (color);
+
+                       href = NULL;
+                       display_name = NULL;
+                       color = NULL;
+               }
+
+               email = e_webdav_discover_content_get_user_address (content);
+               if (email && *email)
+                       e_source_webdav_set_email_address (webdav_extension, email);
+               g_free (email);
+       }
+
+       g_signal_handler_disconnect (prompter, handler_id);
+
+       gtk_widget_destroy (GTK_WIDGET (dialog));
+
+       g_object_unref (prompter);
+       if (uri)
+               soup_uri_free (uri);
+       g_free (base_url);
+}
+
+static gboolean
+cal_config_webdav_notes_uri_to_text (GBinding *binding,
+                               const GValue *source_value,
+                               GValue *target_value,
+                               gpointer user_data)
+{
+       SoupURI *soup_uri;
+       gchar *text;
+
+       soup_uri = g_value_get_boxed (source_value);
+       soup_uri_set_user (soup_uri, NULL);
+
+       if (soup_uri_get_host (soup_uri)) {
+               text = soup_uri_to_string (soup_uri, FALSE);
+       } else {
+               GObject *target;
+
+               text = NULL;
+               target = g_binding_get_target (binding);
+               g_object_get (target, g_binding_get_target_property (binding), &text, NULL);
+
+               if (!text || !*text) {
+                       g_free (text);
+                       text = soup_uri_to_string (soup_uri, FALSE);
+               }
+       }
+
+       g_value_take_string (target_value, text);
+
+       return TRUE;
+}
+
+static gboolean
+cal_config_webdav_notes_text_to_uri (GBinding *binding,
+                               const GValue *source_value,
+                               GValue *target_value,
+                               gpointer user_data)
+{
+       ESource *source;
+       SoupURI *soup_uri;
+       ESourceAuthentication *extension;
+       const gchar *extension_name;
+       const gchar *text;
+       const gchar *user;
+
+       text = g_value_get_string (source_value);
+       soup_uri = soup_uri_new (text);
+
+       if (!soup_uri)
+               soup_uri = soup_uri_new ("http://";);
+
+       source = E_SOURCE (user_data);
+       extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+       extension = e_source_get_extension (source, extension_name);
+       user = e_source_authentication_get_user (extension);
+
+       soup_uri_set_user (soup_uri, user);
+
+       g_value_take_boxed (target_value, soup_uri);
+
+       return TRUE;
+}
+
+static gboolean
+cal_config_webdav_notes_allow_creation (ESourceConfigBackend *backend)
+{
+       ESourceConfig *config;
+       ECalClientSourceType source_type;
+
+       config = e_source_config_backend_get_config (backend);
+       source_type = e_cal_source_config_get_source_type (E_CAL_SOURCE_CONFIG (config));
+
+       return source_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
+}
+
+static void
+cal_config_webdav_notes_insert_widgets (ESourceConfigBackend *backend,
+                                       ESource *scratch_source)
+{
+       ESourceConfig *config;
+       ESource *collection_source;
+       ESourceExtension *extension;
+       ECalClientSourceType source_type;
+       GtkWidget *widget;
+       Context *context;
+       const gchar *extension_name;
+       const gchar *label;
+       const gchar *uid;
+
+       config = e_source_config_backend_get_config (backend);
+       collection_source = e_source_config_get_collection_source (config);
+
+       e_cal_source_config_add_offline_toggle (
+               E_CAL_SOURCE_CONFIG (config), scratch_source);
+
+       uid = e_source_get_uid (scratch_source);
+       context = cal_config_webdav_notes_context_new (backend, scratch_source);
+
+       g_object_set_data_full (
+               G_OBJECT (backend), uid, context,
+               (GDestroyNotify) cal_config_webdav_notes_context_free);
+
+       if (collection_source) {
+               widget = gtk_label_new ("");
+               g_object_set (G_OBJECT (widget),
+                       "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
+                       "selectable", TRUE,
+                       "xalign", 0.0f,
+                       NULL);
+               e_source_config_insert_widget (config, scratch_source, _("URL:"), widget);
+               gtk_widget_show (widget);
+
+               extension = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+
+               e_binding_bind_property_full (
+                       extension, "soup-uri",
+                       widget, "label",
+                       G_BINDING_SYNC_CREATE,
+                       cal_config_webdav_notes_uri_to_text,
+                       NULL,
+                       g_object_ref (scratch_source),
+                       (GDestroyNotify) g_object_unref);
+
+               e_binding_bind_property (
+                       widget, "label",
+                       widget, "tooltip-text",
+                       G_BINDING_SYNC_CREATE);
+       } else {
+               widget = gtk_entry_new ();
+               e_source_config_insert_widget (
+                       config, scratch_source, _("URL:"), widget);
+               context->url_entry = g_object_ref (widget);
+               gtk_widget_show (widget);
+       }
+
+       e_source_config_add_secure_connection_for_webdav (config, scratch_source);
+
+       source_type = e_cal_source_config_get_source_type (E_CAL_SOURCE_CONFIG (config));
+
+       if (!collection_source) {
+               e_source_config_add_user_entry (config, scratch_source);
+
+               g_warn_if_fail (source_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS);
+
+               label = _("Find Notes");
+
+               widget = gtk_button_new_with_label (label);
+               e_source_config_insert_widget (config, scratch_source, NULL, widget);
+               context->find_button = g_object_ref (widget);
+               gtk_widget_show (widget);
+
+               g_signal_connect (
+                       widget, "clicked",
+                       G_CALLBACK (cal_config_webdav_notes_run_dialog), context);
+       }
+
+       e_source_config_add_refresh_interval (config, scratch_source);
+
+       extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
+       extension = e_source_get_extension (scratch_source, extension_name);
+
+       if (context->url_entry) {
+               e_binding_bind_property_full (
+                       extension, "soup-uri",
+                       context->url_entry, "text",
+                       G_BINDING_BIDIRECTIONAL |
+                       G_BINDING_SYNC_CREATE,
+                       cal_config_webdav_notes_uri_to_text,
+                       cal_config_webdav_notes_text_to_uri,
+                       g_object_ref (scratch_source),
+                       (GDestroyNotify) g_object_unref);
+       }
+}
+
+static gboolean
+cal_config_webdav_notes_check_complete (ESourceConfigBackend *backend,
+                                       ESource *scratch_source)
+{
+       Context *context;
+       const gchar *uid;
+       const gchar *uri_string;
+       SoupURI *soup_uri;
+       gboolean complete;
+
+       uid = e_source_get_uid (scratch_source);
+       context = g_object_get_data (G_OBJECT (backend), uid);
+       g_return_val_if_fail (context != NULL, FALSE);
+
+       if (!context->url_entry)
+               return TRUE;
+
+       uri_string = gtk_entry_get_text (GTK_ENTRY (context->url_entry));
+       soup_uri = soup_uri_new (uri_string);
+
+       if (soup_uri) {
+               if (g_strcmp0 (soup_uri_get_scheme (soup_uri), "caldav") == 0)
+                       soup_uri_set_scheme (soup_uri, SOUP_URI_SCHEME_HTTP);
+
+               complete = soup_uri_get_host (soup_uri) && SOUP_URI_VALID_FOR_HTTP (soup_uri);
+       } else {
+               complete = FALSE;
+       }
+
+       if (soup_uri != NULL)
+               soup_uri_free (soup_uri);
+
+       gtk_widget_set_sensitive (context->find_button, complete);
+
+       e_util_set_entry_issue_hint (context->url_entry, complete ? NULL : _("URL is not a valid http:// nor 
https:// URL"));
+
+       return complete;
+}
+
+static void
+e_cal_config_webdav_notes_class_init (ESourceConfigBackendClass *class)
+{
+       EExtensionClass *extension_class;
+
+       extension_class = E_EXTENSION_CLASS (class);
+       extension_class->extensible_type = E_TYPE_CAL_SOURCE_CONFIG;
+
+       class->parent_uid = "webdav-notes-stub";
+       class->backend_name = "webdav-notes";
+       class->allow_creation = cal_config_webdav_notes_allow_creation;
+       class->insert_widgets = cal_config_webdav_notes_insert_widgets;
+       class->check_complete = cal_config_webdav_notes_check_complete;
+}
+
+static void
+e_cal_config_webdav_notes_class_finalize (ESourceConfigBackendClass *class)
+{
+}
+
+static void
+e_cal_config_webdav_notes_init (ESourceConfigBackend *backend)
+{
+}
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+       e_cal_config_webdav_notes_register_type (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}


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