[evolution/webkit-composer: 34/181] Implement word-wrap
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit-composer: 34/181] Implement word-wrap
- Date: Sun, 10 Feb 2013 12:11:22 +0000 (UTC)
commit 6cccb425bb0ef610640f7b8a84e95e282c9a4e86
Author: Dan VrÃtil <dvratil redhat com>
Date: Fri Aug 10 14:23:38 2012 +0200
Implement word-wrap
e-util/e-editor-actions.c | 5 +-
e-util/e-editor-selection.c | 170 +++++++++++++++++++++++++++++++++++++++++++
e-util/e-editor-selection.h | 1 +
3 files changed, 172 insertions(+), 4 deletions(-)
---
diff --git a/e-util/e-editor-actions.c b/e-util/e-editor-actions.c
index 6627c19..93af22d 100644
--- a/e-util/e-editor-actions.c
+++ b/e-util/e-editor-actions.c
@@ -1057,10 +1057,7 @@ static void
action_wrap_lines_cb (GtkAction *action,
EEditor *editor)
{
- /* FIXME WEBKIT */
- /*
- e_editor_widget_wrap_lines (editor);
- */
+ e_editor_selection_wrap_lines (editor->priv->selection);
}
/*****************************************************************************
diff --git a/e-util/e-editor-selection.c b/e-util/e-editor-selection.c
index e592ed8..f1818a2 100644
--- a/e-util/e-editor-selection.c
+++ b/e-util/e-editor-selection.c
@@ -30,11 +30,14 @@
#include <webkit/webkitdom.h>
#include <string.h>
#include <stdlib.h>
+#include <ctype.h>
#define E_EDITOR_SELECTION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_EDITOR_SELECTION, EEditorSelectionPrivate))
+#define WORD_WRAP_LENGTH 71
+
struct _EEditorSelectionPrivate {
@@ -1310,3 +1313,170 @@ e_editor_selection_insert_image (EEditorSelection *selection,
webkit_dom_document_exec_command (
document, "insertImage", FALSE, image_uri);
}
+
+static gint
+find_where_to_break_line (WebKitDOMNode *node,
+ gint max_len)
+{
+ gchar *str, *text_start;
+ gunichar uc;
+ gint pos, last_space;
+
+ text_start = webkit_dom_text_get_whole_text ((WebKitDOMText *) node);
+
+ pos = 0;
+ last_space = 0;
+ str = text_start;
+ do {
+ uc = g_utf8_get_char (str);
+ if (!uc) {
+ g_free (text_start);
+ if (pos <= max_len) {
+ return pos;
+ } else {
+ return last_space;
+ }
+ }
+
+ /* If last_space is zero then the word is longer than
+ * WORD_WRAP_LENGTH characters, so continue untill we find
+ * a space */
+ if ((pos > max_len) && (last_space > 0)) {
+ g_free (text_start);
+ return last_space;
+ }
+
+ if (g_unichar_isspace (uc)) {
+ last_space = pos;
+ }
+
+ pos += 1;
+ str = g_utf8_next_char (str);
+ } while (*str);
+
+ g_free (text_start);
+ return max_len;
+}
+
+void
+e_editor_selection_wrap_lines (EEditorSelection *selection)
+{
+ WebKitDOMRange *range;
+ WebKitDOMNode *node, *start_node;
+ WebKitDOMDocument *document;
+ WebKitDOMElement *element;
+ WebKitDOMDocumentFragment *fragment;
+ gint len;
+ gchar *html;
+
+ g_return_if_fail (E_IS_EDITOR_SELECTION (selection));
+
+ document = webkit_web_view_get_dom_document (selection->priv->webview);
+ range = editor_selection_get_current_range (selection);
+
+ /* Extend the range to include entire nodes */
+ webkit_dom_range_select_node_contents (
+ range,
+ webkit_dom_range_get_common_ancestor_container (range, NULL),
+ NULL);
+
+ /* Copy the selection from DOM, wrap the lines and then paste it back
+ * using the DOM command which will overwrite the selection, and
+ * record it as an undoable action */
+ fragment = webkit_dom_range_clone_contents (range, NULL);
+ node = WEBKIT_DOM_NODE (fragment);
+
+ start_node = node;
+ len = 0;
+ while (node) {
+ /* Find nearest text node */
+ if (webkit_dom_node_get_node_type (node) != 3) {
+ if (webkit_dom_node_has_child_nodes (node)) {
+ node = webkit_dom_node_get_first_child (node);
+ } else if (webkit_dom_node_get_next_sibling (node)) {
+ node = webkit_dom_node_get_next_sibling (node);
+ } else {
+ if (webkit_dom_node_is_equal_node (node, start_node)) {
+ break;
+ }
+
+ node = webkit_dom_node_get_parent_node (node);
+ if (node) {
+ node = webkit_dom_node_get_next_sibling (node);
+ }
+ }
+ continue;
+ }
+
+ /* If length of this node + what we already have is still less
+ * then 71 characters, then just join it and continue to next
+ * node */
+ if ((webkit_dom_character_data_get_length (
+ (WebKitDOMCharacterData *) node) + len) < WORD_WRAP_LENGTH) {
+
+ len += webkit_dom_character_data_get_length (
+ (WebKitDOMCharacterData *) node);
+
+ } else {
+ gint offset;
+
+ /* Find where we can line-break the node so that it
+ * effectively fills the rest of current row */
+ offset = find_where_to_break_line (node, WORD_WRAP_LENGTH - len);
+
+ if (offset > 0) {
+ /* Split the node and append <BR> tag to it */
+ webkit_dom_text_split_text (
+ (WebKitDOMText *) node, len + offset, NULL);
+
+ element = webkit_dom_document_create_element (
+ document, "BR", NULL);
+
+ /* WebKit throws warning when ref_child is NULL */
+ if (webkit_dom_node_get_next_sibling (node)) {
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (node),
+ WEBKIT_DOM_NODE (element),
+ webkit_dom_node_get_next_sibling (node),
+ NULL);
+ } else {
+ webkit_dom_node_append_child (
+ webkit_dom_node_get_parent_node (node),
+ WEBKIT_DOM_NODE (element),
+ NULL);
+ }
+
+ len = 0;
+ }
+ }
+
+ /* Skip to next node */
+ if (webkit_dom_node_get_next_sibling (node)) {
+ node = webkit_dom_node_get_next_sibling (node);
+ } else {
+ if (webkit_dom_node_is_equal_node (node, start_node)) {
+ break;
+ }
+
+ node = webkit_dom_node_get_parent_node (node);
+ if (node) {
+ node = webkit_dom_node_get_next_sibling (node);
+ }
+ }
+ }
+
+ /* Create a wrapper DIV and put the processed content into it */
+ element = webkit_dom_document_create_element (document, "DIV", NULL);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (start_node), NULL);
+
+ /* Get HTML code of the processed content */
+ html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+
+ /* Overwrite the current selection be the processed content, so that
+ * "UNDO" and "REDO" buttons work as expected */
+ e_editor_selection_insert_html (selection, html);
+
+ g_free (html);
+}
\ No newline at end of file
diff --git a/e-util/e-editor-selection.h b/e-util/e-editor-selection.h
index a444f5f..9ee9ad5 100644
--- a/e-util/e-editor-selection.h
+++ b/e-util/e-editor-selection.h
@@ -196,6 +196,7 @@ void e_editor_selection_insert_image (EEditorSelection *selection,
const gchar *image_uri);
void e_editor_selection_insert_text (EEditorSelection *selection,
const gchar *plain_text);
+void e_editor_selection_wrap_lines (EEditorSelection *selection);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]