[evolution/webkit-composer] Save/Restore caret position when switching composer modes.



commit 608cf94d84df29bb8b04e807374555ac3de9e15c
Author: Tomas Popela <tpopela redhat com>
Date:   Fri Jul 12 14:17:06 2013 +0200

    Save/Restore caret position when switching composer modes.

 composer/e-composer-private.c |   51 ++++++++++++++++++++++++-----------------
 e-util/e-editor-selection.c   |    5 +++-
 e-util/e-editor-widget.c      |   27 +++++++++-------------
 3 files changed, 45 insertions(+), 38 deletions(-)
---
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index efb258d..ec795dd 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -791,11 +791,13 @@ composer_move_caret (EMsgComposer *composer)
        WebKitDOMElement *element;
        GSettings *settings;
        gboolean start_bottom;
+       gboolean has_paragraphs_in_body = TRUE;
 
        /* When there is an option composer-reply-start-bottom set we have
         * to move the caret between reply and signature. */
        settings = g_settings_new ("org.gnome.evolution.mail");
        start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom");
+       g_object_unref (settings);
 
        editor = e_msg_composer_get_editor (composer);
        editor_widget = e_editor_get_editor_widget (editor);
@@ -806,20 +808,29 @@ composer_move_caret (EMsgComposer *composer)
        body = webkit_dom_document_get_body (document);
        new_range = webkit_dom_document_create_range (document);
 
-       /* If we were just changing composer mode we don't want to insert
-        * new div and we want to set caret to the beginning */
-       element = webkit_dom_document_get_element_by_id (document, "-x-evo-changing-mode");
+       element = webkit_dom_document_get_element_by_id (document, "-x-evo-caret-position");
+       /* Caret position found => composer mode changed */
        if (element) {
-               webkit_dom_node_remove_child (
-                       WEBKIT_DOM_NODE (body),
-                       WEBKIT_DOM_NODE (element),
-                       NULL);
+               e_editor_selection_restore_caret_position (e_editor_widget_get_selection (editor_widget));
+               return;
        }
 
        list = webkit_dom_document_get_elements_by_class_name (document, "-x-evo-paragraph");
+       /* Situation when wrapped paragraph is just in signature and not in message body */
+       if (webkit_dom_node_list_get_length (list) == 1) {
+               WebKitDOMElement *signature;
+
+               signature = webkit_dom_document_query_selector (document, ".-x-evolution-signature", NULL);
+               if (signature && webkit_dom_element_query_selector (signature, ".-x-evo-paragraph", NULL))
+                       has_paragraphs_in_body = FALSE;
+       }
+
+       if (webkit_dom_node_list_get_length (list) == 0)
+               has_paragraphs_in_body = FALSE;
+
        blockquotes = webkit_dom_document_get_elements_by_tag_name (document, "blockquote");
 
-       if (webkit_dom_node_list_get_length (list) == 0) {
+       if (!has_paragraphs_in_body) {
                element = webkit_dom_document_create_element (document, "DIV", NULL);
                webkit_dom_element_set_class_name (WEBKIT_DOM_ELEMENT (element), "-x-evo-paragraph");
                webkit_dom_html_element_set_id (WEBKIT_DOM_HTML_ELEMENT (element), "-x-evo-input-start");
@@ -828,7 +839,7 @@ composer_move_caret (EMsgComposer *composer)
 
        if (start_bottom) {
                if (webkit_dom_node_list_get_length (blockquotes) != 0) {
-                       if (webkit_dom_node_list_get_length (list) == 0) {
+                       if (!has_paragraphs_in_body) {
                                webkit_dom_node_insert_before (
                                        WEBKIT_DOM_NODE (body),
                                        WEBKIT_DOM_NODE (element),
@@ -836,31 +847,32 @@ composer_move_caret (EMsgComposer *composer)
                                                webkit_dom_node_list_item (blockquotes, 0)),
                                        NULL);
                        }
-                       input_start = webkit_dom_document_get_element_by_id (document, "-x-evo-input-start");
 
-                       /* Move caret between reply and signature. */
+                       input_start = webkit_dom_document_get_element_by_id (document, "-x-evo-input-start");
                        if (input_start)
                                webkit_dom_range_select_node_contents (new_range, WEBKIT_DOM_NODE 
(input_start), NULL);
+
                        webkit_dom_range_collapse (new_range, FALSE, NULL);
                } else {
-                       if (webkit_dom_node_list_get_length (list) == 0) {
-                               if (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)))
+                       if (!has_paragraphs_in_body) {
+                               if (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body))) {
                                        webkit_dom_node_insert_before (
                                                WEBKIT_DOM_NODE (body),
                                                WEBKIT_DOM_NODE (element),
                                                webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
                                                NULL);
-                               else
+                               } else {
                                        webkit_dom_node_append_child (
                                                WEBKIT_DOM_NODE (body),
                                                WEBKIT_DOM_NODE (element),
                                                NULL);
+                               }
                        }
 
                        webkit_dom_range_select_node_contents (new_range,
-                                       WEBKIT_DOM_NODE (
-                                               webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body))),
-                                       NULL);
+                               WEBKIT_DOM_NODE (
+                                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body))),
+                               NULL);
                        webkit_dom_range_collapse (new_range, TRUE, NULL);
                }
 
@@ -869,8 +881,7 @@ composer_move_caret (EMsgComposer *composer)
                        G_CALLBACK (composer_size_allocate_cb), NULL);
        } else {
                /* Move caret on the beginning of message */
-               if (webkit_dom_node_list_get_length (list) == 0) {
-
+               if (!has_paragraphs_in_body) {
                        if (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body))) {
                                webkit_dom_node_insert_before (
                                        WEBKIT_DOM_NODE (body),
@@ -905,8 +916,6 @@ composer_move_caret (EMsgComposer *composer)
 
        webkit_dom_dom_selection_remove_all_ranges (dom_selection);
        webkit_dom_dom_selection_add_range (dom_selection, new_range);
-
-       g_object_unref (settings);
 }
 
 static void
diff --git a/e-util/e-editor-selection.c b/e-util/e-editor-selection.c
index 2223156..62c06dc 100644
--- a/e-util/e-editor-selection.c
+++ b/e-util/e-editor-selection.c
@@ -2596,12 +2596,15 @@ e_editor_selection_save_caret_position (EEditorSelection *selection)
 
 static void
 move_caret_into_element (WebKitDOMDocument *document,
-            WebKitDOMElement *element)
+                        WebKitDOMElement *element)
 {
        WebKitDOMDOMWindow *window;
        WebKitDOMDOMSelection *window_selection;
        WebKitDOMRange *new_range;
 
+       if (!element)
+               return;
+
        window = webkit_dom_document_get_default_view (document);
        window_selection = webkit_dom_dom_window_get_selection (window);
        new_range = webkit_dom_document_create_range (document);
diff --git a/e-util/e-editor-widget.c b/e-util/e-editor-widget.c
index 6f7b2a4..6ddedaa 100644
--- a/e-util/e-editor-widget.c
+++ b/e-util/e-editor-widget.c
@@ -1531,7 +1531,6 @@ void
 e_editor_widget_set_html_mode (EEditorWidget *widget,
                                gboolean html_mode)
 {
-       gboolean changing = FALSE;
        gint result;
 
        g_return_if_fail (E_IS_EDITOR_WIDGET (widget));
@@ -1561,9 +1560,7 @@ e_editor_widget_set_html_mode (EEditorWidget *widget,
 
                result = gtk_dialog_run (GTK_DIALOG (dialog));
 
-               if (result == GTK_RESPONSE_OK) {
-                       changing = TRUE;
-               } else {
+               if (result != GTK_RESPONSE_OK) {
                        gtk_widget_destroy (dialog);
                        /* Nothing has changed, but notify anyway */
                        g_object_notify (G_OBJECT (widget), "html-mode");
@@ -1573,9 +1570,6 @@ e_editor_widget_set_html_mode (EEditorWidget *widget,
                gtk_widget_destroy (dialog);
        }
 
-       if (html_mode)
-               changing = TRUE;
-
        if (html_mode == widget->priv->html_mode)
                return;
 
@@ -1588,21 +1582,22 @@ e_editor_widget_set_html_mode (EEditorWidget *widget,
                /* FIXME WEBKIT: Process smileys! */
        } else {
                gchar *plain;
+               GRegex *regex;
 
-               plain = e_editor_widget_get_text_plain (widget);
+               /* Save caret position -> it will be restored in e-composer-private.c */
+               e_editor_selection_save_caret_position (e_editor_widget_get_selection (widget));
 
-               if (*plain) {
-                       if (changing) {
-                               gchar *tmp;
-                               tmp = g_strconcat (plain, UNICODE_HIDDEN_SPACE, NULL);
-                               g_free (plain);
-                               plain = tmp;
-                       }
+               /* We need to get plain text from composer, but we need <br> instead of \n */
+               regex = g_regex_new ("\n", 0, 0, NULL);
+               plain = g_regex_replace_literal (regex,
+                                                e_editor_widget_get_text_plain (widget),
+                                                -1, 0, "<br>", 0, NULL);
 
+               if (*plain)
                        e_editor_widget_set_text_plain (widget, plain);
-               }
 
                g_free (plain);
+               g_regex_unref (regex);
        }
 
        g_object_notify (G_OBJECT (widget), "html-mode");


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