[evolution/gnome-3-16] Bug 748217 - undo of Ctrl-Backspace and Ctrl-Delete is broken for multi-character strings
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/gnome-3-16] Bug 748217 - undo of Ctrl-Backspace and Ctrl-Delete is broken for multi-character strings
- Date: Tue, 21 Apr 2015 11:29:32 +0000 (UTC)
commit bfa1117b4dbaad5c4a22a0b6417c13ca0e4e9ab4
Author: Tomas Popela <tpopela redhat com>
Date: Tue Apr 21 13:22:48 2015 +0200
Bug 748217 - undo of Ctrl-Backspace and Ctrl-Delete is broken for multi-character strings
Correct the current undo/redo implementation of delete operation to handle
the Ctrl+Backspace and Ctrl+Delete cases.
e-util/e-html-editor-view.c | 161 ++++++++++++++++++++++++++++++-------------
1 files changed, 114 insertions(+), 47 deletions(-)
---
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index eec8244..9a0cf33 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -4114,7 +4114,8 @@ fix_structure_after_delete_before_quoted_content (EHTMLEditorView *view)
static void
save_history_for_delete_or_backspace (EHTMLEditorView *view,
- gboolean delete_key)
+ gboolean delete_key,
+ gboolean control_key)
{
EHTMLEditorSelection *selection;
EHTMLEditorViewHistoryEvent *ev;
@@ -4158,46 +4159,98 @@ save_history_for_delete_or_backspace (EHTMLEditorView *view,
block_selection_changed_callbacks (view);
range_clone = webkit_dom_range_clone_range (range, NULL);
- if (delete_key) {
- glong offset = webkit_dom_range_get_start_offset (range_clone, NULL);
- webkit_dom_range_set_end (
- range_clone,
- webkit_dom_range_get_end_container (range_clone, NULL),
- offset + 1,
- NULL);
+ if (control_key) {
+ WebKitDOMRange *tmp_range;
+
+ /* Control + Delete/Backspace deletes previous/next word. */
+ webkit_dom_dom_selection_modify (
+ dom_selection, "move", delete_key ? "right" : "left", "word");
+ tmp_range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+ if (delete_key)
+ webkit_dom_range_set_end (
+ range_clone,
+ webkit_dom_range_get_end_container (tmp_range, NULL),
+ webkit_dom_range_get_end_offset (tmp_range, NULL),
+ NULL);
+ else
+ webkit_dom_range_set_start (
+ range_clone,
+ webkit_dom_range_get_start_container (tmp_range, NULL),
+ webkit_dom_range_get_start_offset (tmp_range, NULL),
+ NULL);
+ g_object_unref (tmp_range);
} else {
- webkit_dom_range_set_start (
- range_clone,
- webkit_dom_range_get_start_container (range_clone, NULL),
- webkit_dom_range_get_start_offset (range_clone, NULL) - 1,
- NULL);
+ if (delete_key) {
+ glong offset = webkit_dom_range_get_start_offset (range_clone, NULL);
+ webkit_dom_range_set_end (
+ range_clone,
+ webkit_dom_range_get_end_container (range_clone, NULL),
+ offset + 1,
+ NULL);
+ } else {
+ webkit_dom_range_set_start (
+ range_clone,
+ webkit_dom_range_get_start_container (range_clone, NULL),
+ webkit_dom_range_get_start_offset (range_clone, NULL) - 1,
+ NULL);
+ }
}
fragment = webkit_dom_range_clone_contents (range_clone, NULL);
- g_object_unref (range_clone);
if (!webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment))) {
g_free (ev);
unblock_selection_changed_callbacks (view);
g_object_unref (range);
+ g_object_unref (range_clone);
g_object_unref (dom_selection);
return;
}
- if (delete_key) {
- e_html_editor_selection_get_selection_coordinates (
- selection, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x,
&ev->after.end.y);
+ if (control_key) {
+ if (delete_key) {
+ ev->after.start.x = ev->before.start.x;
+ ev->after.start.y = ev->before.start.y;
+ ev->after.end.x = ev->before.end.x;
+ ev->after.end.y = ev->before.end.y;
+
+ webkit_dom_range_collapse (range_clone, TRUE, NULL);
+ webkit_dom_dom_selection_remove_all_ranges (dom_selection);
+ webkit_dom_dom_selection_add_range (dom_selection, range_clone);
+ } else {
+ WebKitDOMRange *tmp_range;
+
+ tmp_range = webkit_dom_range_clone_range (range_clone, NULL);
+ /* Prepare the selection to the right position after
+ * delete and save it. */
+ webkit_dom_range_collapse (range_clone, TRUE, NULL);
+ webkit_dom_dom_selection_remove_all_ranges (dom_selection);
+ webkit_dom_dom_selection_add_range (dom_selection, range_clone);
+ e_html_editor_selection_get_selection_coordinates (
+ selection, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x,
&ev->after.end.y);
+ /* Restore the selection where it was before the
+ * history event was saved. */
+ webkit_dom_range_collapse (tmp_range, FALSE, NULL);
+ webkit_dom_dom_selection_remove_all_ranges (dom_selection);
+ webkit_dom_dom_selection_add_range (dom_selection, tmp_range);
+ g_object_unref (tmp_range);
+ }
} else {
- webkit_dom_dom_selection_modify (dom_selection, "move", "left", "character");
- e_html_editor_selection_get_selection_coordinates (
- selection, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x,
&ev->after.end.y);
- webkit_dom_dom_selection_modify (dom_selection, "move", "right", "character");
- }
+ if (delete_key) {
+ e_html_editor_selection_get_selection_coordinates (
+ selection, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x,
&ev->after.end.y);
+ } else {
+ webkit_dom_dom_selection_modify (dom_selection, "move", "left", "character");
+ e_html_editor_selection_get_selection_coordinates (
+ selection, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x,
&ev->after.end.y);
+ webkit_dom_dom_selection_modify (dom_selection, "move", "right", "character");
- if (!delete_key) {
- ev->after.end.x = ev->after.start.x;
- ev->after.end.y = ev->after.start.y;
+ ev->after.end.x = ev->after.start.x;
+ ev->after.end.y = ev->after.start.y;
+ }
}
+ g_object_unref (range_clone);
+
if (delete_key) {
webkit_dom_node_insert_before (
WEBKIT_DOM_NODE (fragment),
@@ -4716,7 +4769,8 @@ html_editor_view_key_press_event (GtkWidget *widget,
}
e_html_editor_selection_restore (view->priv->selection);
}
- save_history_for_delete_or_backspace (view, event->keyval == GDK_KEY_Delete);
+ save_history_for_delete_or_backspace (
+ view, event->keyval == GDK_KEY_Delete, ((event)->state & GDK_CONTROL_MASK));
if (event->keyval == GDK_KEY_BackSpace && !view->priv->html_mode) {
if (delete_character_from_quoted_line_start (view))
return TRUE;
@@ -11007,6 +11061,7 @@ static void
undo_delete (EHTMLEditorView *view,
EHTMLEditorViewHistoryEvent *event)
{
+ EHTMLEditorSelection *selection;
gboolean empty, single_block;
gchar *content;
WebKitDOMDocument *document;
@@ -11016,6 +11071,8 @@ undo_delete (EHTMLEditorView *view,
WebKitDOMElement *element;
WebKitDOMNode *first_child, *fragment;
+ selection = e_html_editor_view_get_selection (view);
+
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
dom_window = webkit_dom_document_get_default_view (document);
dom_selection = webkit_dom_dom_window_get_selection (dom_window);
@@ -11042,11 +11099,8 @@ undo_delete (EHTMLEditorView *view,
/* Redoing Return key press */
if (empty) {
- EHTMLEditorSelection *selection;
WebKitDOMNode *node;
- selection = e_html_editor_view_get_selection (view);
-
range = get_range_for_point (document, event->before.start);
webkit_dom_dom_selection_remove_all_ranges (dom_selection);
webkit_dom_dom_selection_add_range (dom_selection, range);
@@ -11071,14 +11125,11 @@ undo_delete (EHTMLEditorView *view,
/* Multi block delete */
if (WEBKIT_DOM_IS_ELEMENT (first_child) && !single_block) {
- EHTMLEditorSelection *selection;
WebKitDOMNode *node, *parent, *last_child;
WebKitDOMNode *parent_deleted_content;
WebKitDOMNode *parent_current_block;
WebKitDOMNode *insert_before;
- selection = e_html_editor_view_get_selection (view);
-
range = get_range_for_point (document, event->before.start);
webkit_dom_dom_selection_remove_all_ranges (dom_selection);
webkit_dom_dom_selection_add_range (dom_selection, range);
@@ -11188,7 +11239,7 @@ undo_delete (EHTMLEditorView *view,
* otherwise the selection was not callapsed so select the deleted
* content as it was before the delete occured. */
if (webkit_dom_document_fragment_query_selector (event->data.fragment,
"span#-x-evo-selection-start-marker", NULL))
- e_html_editor_selection_restore (e_html_editor_view_get_selection (view));
+ e_html_editor_selection_restore (selection);
else
restore_selection_to_history_event_state (view, event->before);
@@ -11201,6 +11252,12 @@ undo_delete (EHTMLEditorView *view,
g_object_unref (dom_selection);
}
+static gboolean
+event_selection_was_collapsed (EHTMLEditorViewHistoryEvent *ev)
+{
+ return (ev->before.start.x == ev->before.end.x) && (ev->before.start.y == ev->before.end.y);
+}
+
static void
redo_delete (EHTMLEditorView *view,
EHTMLEditorViewHistoryEvent *event)
@@ -11216,7 +11273,9 @@ redo_delete (EHTMLEditorView *view,
restore_selection_to_history_event_state (view, event->before);
if (webkit_dom_document_fragment_query_selector (fragment, "span#-x-evo-selection-start-marker",
NULL)) {
- gboolean delete = FALSE;
+ gboolean delete = FALSE, control_key = FALSE;
+ glong length = 1;
+ gint ii;
WebKitDOMDOMWindow *dom_window;
WebKitDOMDOMSelection *dom_selection;
@@ -11224,18 +11283,32 @@ redo_delete (EHTMLEditorView *view,
g_object_unref (dom_window);
dom_selection = webkit_dom_dom_window_get_selection (dom_window);
+ control_key = event_selection_was_collapsed (event);
+ if (control_key) {
+ gchar *text_content;
+
+ text_content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (fragment));
+ length = g_utf8_strlen (text_content, -1);
+ control_key = control_key && length > 1;
+
+ g_free (text_content);
+ }
+
/* Check if the event was delete or backspace press. */
delete = WEBKIT_DOM_IS_ELEMENT (first_child);
delete = delete && element_has_id (WEBKIT_DOM_ELEMENT (first_child),
"-x-evo-selection-start-marker");
- if (delete)
- webkit_dom_dom_selection_modify (dom_selection, "extend", "right", "character");
- else
- webkit_dom_dom_selection_modify (dom_selection, "extend", "left", "character");
- g_object_unref (dom_selection);
- }
+ for (ii = 0; ii < length; ii++) {
+ e_html_editor_view_exec_command (
+ view,
+ delete ? E_HTML_EDITOR_VIEW_COMMAND_FORWARD_DELETE :
+ E_HTML_EDITOR_VIEW_COMMAND_DELETE,
+ NULL);
+ }
- e_html_editor_view_exec_command (view, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+ g_object_unref (dom_selection);
+ } else
+ e_html_editor_view_exec_command (view, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
e_html_editor_view_force_spell_check_for_current_paragraph (view);
}
@@ -12356,12 +12429,6 @@ e_html_editor_view_redo (EHTMLEditorView *view)
view->priv->undo_redo_in_progress = FALSE;
}
-static gboolean
-event_selection_was_collapsed (EHTMLEditorViewHistoryEvent *ev)
-{
- return (ev->before.start.x == ev->before.end.x) && (ev->before.start.y == ev->before.end.y);
-}
-
void
e_html_editor_view_undo (EHTMLEditorView *view)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]