[geary/wip/728002-webkit2: 77/96] Update and mostly reenable composer clipboard actions.



commit 7b2727906c4dddcb9e7485525f02dcec7872c356
Author: Michael James Gratton <mike vee net>
Date:   Wed Jan 4 15:40:58 2017 +1100

    Update and mostly reenable composer clipboard actions.
    
    * src/client/components/client-web-view.vala (copy_clipboard): Fixed to
      actually copy, not cut. Removed can_copy_clipboard since it's no longer
      implementable or useful.
    
    * src/client/composer/composer-web-view.vala (ComposerWebView): Remove
      can_cut_clipboard and can_paste_clipboard, since they are no longer
      implementable or useful. Implement simple part of insert_text so
      pasting plain text works, but still need to handle scroll update.
    
    * src/client/composer/composer-widget.vala (ComposerWidget): Fix keyboard
      shortcut for copying. Remove old WK1 clipboard related events. Update
      clipboard actions' state using selection changed signal. Handle pasting
      plain and rich text via the editor.
    
    * src/client/web-process/util-composer.vala (insert_clipboard_text):
      Remove code moved back to ComposerWebView.

 src/client/components/client-web-view.vala |   14 +----
 src/client/composer/composer-web-view.vala |   91 +++++++++++++++++++++-------
 src/client/composer/composer-widget.vala   |   33 ++++++----
 src/client/web-process/util-composer.vala  |   60 ------------------
 4 files changed, 91 insertions(+), 107 deletions(-)
---
diff --git a/src/client/components/client-web-view.vala b/src/client/components/client-web-view.vala
index 52a4f53..fe49820 100644
--- a/src/client/components/client-web-view.vala
+++ b/src/client/components/client-web-view.vala
@@ -334,20 +334,10 @@ public class ClientWebView : WebKit.WebView {
     }
 
     /**
-     * Sends a copy command to the web view.
+     * Copies selected content and sends it to the clipboard.
      */
     public void copy_clipboard() {
-        execute_editing_command(WebKit.EDITING_COMMAND_CUT);
-    }
-
-    public bool can_copy_clipboard() {
-        // can_execute_editing_command.begin(
-        //     WebKit.EDITING_COMMAND_COPY,
-        //     null,
-        //     (obj, res) => {
-        //         return can_execute_editing_command.end(res);
-        //     });
-        return false;
+        execute_editing_command(WebKit.EDITING_COMMAND_COPY);
     }
 
     public void reset_zoom() {
diff --git a/src/client/composer/composer-web-view.vala b/src/client/composer/composer-web-view.vala
index a3f1c0f..58e61e6 100644
--- a/src/client/composer/composer-web-view.vala
+++ b/src/client/composer/composer-web-view.vala
@@ -119,46 +119,93 @@ public class ComposerWebView : ClientWebView {
     }
 
     /**
-     * Sends a cut command to the editor.
+     * Cuts selected content and sends it to the clipboard.
      */
     public void cut_clipboard() {
         execute_editing_command(WebKit.EDITING_COMMAND_CUT);
     }
 
-    public bool can_cut_clipboard() {
-        // can_execute_editing_command.begin(
-        //     WebKit.EDITING_COMMAND_CUT,
-        //     null,
-        //     (obj, res) => {
-        //         return can_execute_editing_command.end(res);
-        //     });
-        return false;
+    /**
+     * Pastes plain text from the clipboard into the view.
+     */
+    public void paste_plain_text() {
+        get_clipboard(Gdk.SELECTION_CLIPBOARD).request_text((clipboard, text) => {
+                if (text != null) {
+                    insert_text(text);
+                }
+            });
     }
 
     /**
-     * Sends a paste command to the editor.
+     * Pastes rich text from the clipboard into the view.
      */
-    public void paste_clipboard() {
+    public void paste_rich_text() {
         execute_editing_command(WebKit.EDITING_COMMAND_PASTE);
     }
 
-    public bool can_paste_clipboard() {
-        // can_execute_editing_command.begin(
-        //     WebKit.EDITING_COMMAND_PASTE,
-        //     null,
-        //     (obj, res) => {
-        //         return can_execute_editing_command.end(res);
-        //     });
-        return false;
-    }
-
     /**
      * Inserts some text at the current cursor location.
      */
     public void insert_text(string text) {
-        // XXX
+        execute_editing_command_with_argument("inserttext", text);
+
+        // XXX scroll to insertion point:
+
+        // The inserttext command will not scroll if needed, but we
+        // can't use the clipboard for plain text. WebKit allows us to
+        // scroll a node into view, but not an arbitrary position
+        // within a text node. So we add a placeholder node at the
+        // cursor position, scroll to that, then remove the
+        // placeholder node.
+        // try {
+        //     WebKit.DOM.DOMSelection selection = document.default_view.get_selection();
+        //     WebKit.DOM.Node selection_base_node = selection.get_base_node();
+        //     long selection_base_offset = selection.get_base_offset();
+
+        //     WebKit.DOM.NodeList selection_child_nodes = selection_base_node.get_child_nodes();
+        //     WebKit.DOM.Node ref_child = selection_child_nodes.item(selection_base_offset);
+
+        //     WebKit.DOM.Element placeholder = document.create_element("SPAN");
+        //     WebKit.DOM.Text placeholder_text = document.create_text_node("placeholder");
+        //     placeholder.append_child(placeholder_text);
+
+        //     if (selection_base_node.node_name == "#text") {
+        //         WebKit.DOM.Node? left = get_left_text(selection_base_node, selection_base_offset);
+
+        //         WebKit.DOM.Node parent = selection_base_node.parent_node;
+        //         if (left != null)
+        //             parent.insert_before(left, selection_base_node);
+        //         parent.insert_before(placeholder, selection_base_node);
+        //         parent.remove_child(selection_base_node);
+
+        //         placeholder.scroll_into_view_if_needed(false);
+        //         parent.insert_before(selection_base_node, placeholder);
+        //         if (left != null)
+        //             parent.remove_child(left);
+        //         parent.remove_child(placeholder);
+        //         selection.set_base_and_extent(selection_base_node, selection_base_offset, 
selection_base_node, selection_base_offset);
+        //     } else {
+        //         selection_base_node.insert_before(placeholder, ref_child);
+        //         placeholder.scroll_into_view_if_needed(false);
+        //         selection_base_node.remove_child(placeholder);
+        //     }
+        // } catch (Error err) {
+        //     debug("Error scrolling pasted text into view: %s", err.message);
+        // }
     }
 
+    // private WebKit.DOM.Node? get_left_text(WebKit.WebPage page, WebKit.DOM.Node node, long offset) {
+    //     WebKit.DOM.Document document = page.get_dom_document();
+    //     string node_value = node.node_value;
+
+    //     // Offset is in unicode characters, but index is in bytes. We need to get the corresponding
+    //     // byte index for the given offset.
+    //     int char_count = node_value.char_count();
+    //     int index = offset > char_count ? node_value.length : node_value.index_of_nth_char(offset);
+
+    //     return offset > 0 ? document.create_text_node(node_value[0:index]) : null;
+    // }
+
     /**
      * Inserts some HTML at the current cursor location.
      */
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index be5e2e6..b725f40 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -127,7 +127,7 @@ public class ComposerWidget : Gtk.EventBox {
         action_accelerators.set(ACTION_UNDO, "<Ctrl>z");
         action_accelerators.set(ACTION_REDO, "<Ctrl><Shift>z");
         action_accelerators.set(ACTION_CUT, "<Ctrl>x");
-        action_accelerators.set(ACTION_COPY, "<Ctrl>x");
+        action_accelerators.set(ACTION_COPY, "<Ctrl>c");
         action_accelerators.set(ACTION_PASTE, "<Ctrl>v");
         action_accelerators.set(ACTION_PASTE_WITH_FORMATTING, "<Ctrl><Shift>v");
         action_accelerators.set(ACTION_INSERT_IMAGE, "<Ctrl>g");
@@ -469,12 +469,9 @@ public class ComposerWidget : Gtk.EventBox {
         this.editor.mouse_target_changed.connect(on_mouse_target_changed);
         this.editor.get_editor_state().notify["typing-attributes"].connect(on_typing_attributes_changed);
         // this.editor.move_focus.connect(update_actions);
-        // this.editor.copy_clipboard.connect(update_actions);
-        // this.editor.cut_clipboard.connect(update_actions);
-        // this.editor.paste_clipboard.connect(update_actions);
         // this.editor.undo.connect(update_actions);
         // this.editor.redo.connect(update_actions);
-        this.editor.selection_changed.connect(update_actions);
+        this.editor.selection_changed.connect(on_selection_changed);
         this.editor.key_press_event.connect(on_editor_key_press);
         //this.editor.user_changed_contents.connect(reset_draft_timer);
 
@@ -1637,22 +1634,16 @@ public class ComposerWidget : Gtk.EventBox {
         c.store();
     }
 
-    private void on_clipboard_text_received(Gtk.Clipboard clipboard, string? text) {
-        if (text != null) {
-            this.editor.insert_text(text);
-        }
-    }
-
     private void on_paste(SimpleAction action, Variant? param) {
         if (this.container.get_focus() == this.editor)
-            get_clipboard(Gdk.SELECTION_CLIPBOARD).request_text(on_clipboard_text_received);
+            this.editor.paste_plain_text();
         else if (this.container.get_focus() is Gtk.Editable)
             ((Gtk.Editable) this.container.get_focus()).paste_clipboard();
     }
 
     private void on_paste_with_formatting(SimpleAction action, Variant? param) {
         if (this.container.get_focus() == this.editor)
-            this.editor.paste_clipboard();
+            this.editor.paste_rich_text();
     }
 
     private void on_select_all(SimpleAction action, Variant? param) {
@@ -1922,6 +1913,14 @@ public class ComposerWidget : Gtk.EventBox {
                 }
             });
 
+        // 4. Update the clipboard
+        // get_clipboard(Gdk.SELECTION_CLIPBOARD).request_targets(
+        //     (_, targets) => {
+        //         foreach (Gdk.Atom atom in targets) {
+        //             debug("atom name: %s", atom.name());
+        //         }
+        //     });
+
         return Gdk.EVENT_PROPAGATE;
     }
 
@@ -2216,6 +2215,14 @@ public class ComposerWidget : Gtk.EventBox {
         this.signature_html = account_sig;
     }
 
+    private void on_selection_changed(bool has_selection) {
+        get_action(ACTION_CUT).set_enabled(has_selection);
+        get_action(ACTION_COPY).set_enabled(has_selection);
+        get_action(ACTION_REMOVE_FORMAT).set_enabled(
+            has_selection && this.editor.is_rich_text
+        );
+    }
+
     private void on_typing_attributes_changed() {
         uint mask = this.editor.get_editor_state().get_typing_attributes();
         this.actions.change_action_state(
diff --git a/src/client/web-process/util-composer.vala b/src/client/web-process/util-composer.vala
index ad12337..d9c51b8 100644
--- a/src/client/web-process/util-composer.vala
+++ b/src/client/web-process/util-composer.vala
@@ -27,66 +27,6 @@ namespace Util.Composer {
         Util.DOM.linkify_document(page.get_dom_document());
     }
 
-    public void insert_clipboard_text(WebKit.WebPage page, string text) {
-        // Insert plain text from clipboard.
-        WebKit.DOM.Document document = page.get_dom_document();
-        document.exec_command("inserttext", false, text);
-
-        // The inserttext command will not scroll if needed, but we
-        // can't use the clipboard for plain text. WebKit allows us to
-        // scroll a node into view, but not an arbitrary position
-        // within a text node. So we add a placeholder node at the
-        // cursor position, scroll to that, then remove the
-        // placeholder node.
-        // try {
-        //     WebKit.DOM.DOMSelection selection = document.default_view.get_selection();
-        //     WebKit.DOM.Node selection_base_node = selection.get_base_node();
-        //     long selection_base_offset = selection.get_base_offset();
-
-        //     WebKit.DOM.NodeList selection_child_nodes = selection_base_node.get_child_nodes();
-        //     WebKit.DOM.Node ref_child = selection_child_nodes.item(selection_base_offset);
-
-        //     WebKit.DOM.Element placeholder = document.create_element("SPAN");
-        //     WebKit.DOM.Text placeholder_text = document.create_text_node("placeholder");
-        //     placeholder.append_child(placeholder_text);
-
-        //     if (selection_base_node.node_name == "#text") {
-        //         WebKit.DOM.Node? left = get_left_text(selection_base_node, selection_base_offset);
-
-        //         WebKit.DOM.Node parent = selection_base_node.parent_node;
-        //         if (left != null)
-        //             parent.insert_before(left, selection_base_node);
-        //         parent.insert_before(placeholder, selection_base_node);
-        //         parent.remove_child(selection_base_node);
-
-        //         placeholder.scroll_into_view_if_needed(false);
-        //         parent.insert_before(selection_base_node, placeholder);
-        //         if (left != null)
-        //             parent.remove_child(left);
-        //         parent.remove_child(placeholder);
-        //         selection.set_base_and_extent(selection_base_node, selection_base_offset, 
selection_base_node, selection_base_offset);
-        //     } else {
-        //         selection_base_node.insert_before(placeholder, ref_child);
-        //         placeholder.scroll_into_view_if_needed(false);
-        //         selection_base_node.remove_child(placeholder);
-        //     }
-        // } catch (Error err) {
-        //     debug("Error scrolling pasted text into view: %s", err.message);
-        // }
-    }
-
-    // private WebKit.DOM.Node? get_left_text(WebKit.WebPage page, WebKit.DOM.Node node, long offset) {
-    //     WebKit.DOM.Document document = page.get_dom_document();
-    //     string node_value = node.node_value;
-
-    //     // Offset is in unicode characters, but index is in bytes. We need to get the corresponding
-    //     // byte index for the given offset.
-    //     int char_count = node_value.char_count();
-    //     int index = offset > char_count ? node_value.length : node_value.index_of_nth_char(offset);
-
-    //     return offset > 0 ? document.create_text_node(node_value[0:index]) : null;
-    // }
-
     public bool handle_key_press(WebKit.WebPage page, Gdk.EventKey event) {
         WebKit.DOM.Document document = page.get_dom_document();
         if (event.keyval == Gdk.Key.Tab) {


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