[gtksourceview] Fix selection on redo
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview] Fix selection on redo
- Date: Mon, 14 Apr 2014 17:51:18 +0000 (UTC)
commit ee95815f8e450f107fcedd00351c16911ce03cea
Author: Jesse van den Kieboom <jessevdk gmail com>
Date: Mon Apr 14 19:01:28 2014 +0200
Fix selection on redo
This fixes the selection on redo by storing the to-redo
selection (i.e. current selection) on undo and vice versa.
This keeps the selection state consistent with the selection
whenever an undo/redo happens (since an undo can only be redone
and vice versa)
https://bugzilla.gnome.org/show_bug.cgi?id=672893
gtksourceview/gtksourceundomanagerdefault.c | 138 +++++++++++++++++---------
1 files changed, 90 insertions(+), 48 deletions(-)
---
diff --git a/gtksourceview/gtksourceundomanagerdefault.c b/gtksourceview/gtksourceundomanagerdefault.c
index 47c8bcd..adc0aa4 100644
--- a/gtksourceview/gtksourceundomanagerdefault.c
+++ b/gtksourceview/gtksourceundomanagerdefault.c
@@ -68,9 +68,6 @@ struct _GtkSourceUndoInsertAction
gchar *text;
gint length;
gint chars;
-
- gint selection_start;
- gint selection_end;
};
struct _GtkSourceUndoDeleteAction
@@ -79,9 +76,6 @@ struct _GtkSourceUndoDeleteAction
gint end;
gchar *text;
gboolean forward;
-
- gint selection_start;
- gint selection_end;
};
struct _GtkSourceUndoAction
@@ -94,6 +88,9 @@ struct _GtkSourceUndoAction
GtkSourceUndoDeleteAction delete;
} action;
+ gint selection_insert;
+ gint selection_bound;
+
gint order_in_group;
/* It is TRUE whether the action can be merged with the following action. */
@@ -473,23 +470,23 @@ gtk_source_undo_manager_can_redo_impl (GtkSourceUndoManager *manager)
static void
set_cursor (GtkTextBuffer *buffer,
- gint selection_start,
- gint selection_end)
+ gint selection_insert,
+ gint selection_bound)
{
- GtkTextIter start;
- GtkTextIter end;
+ GtkTextIter insert_iter;
+ GtkTextIter bound_iter;
/* Place the cursor at the requested position */
- gtk_text_buffer_get_iter_at_offset (buffer, &start, selection_start);
+ gtk_text_buffer_get_iter_at_offset (buffer, &insert_iter, selection_insert);
- if (selection_start == selection_end)
+ if (selection_insert == selection_bound)
{
- gtk_text_buffer_place_cursor (buffer, &start);
+ gtk_text_buffer_place_cursor (buffer, &insert_iter);
}
else
{
- gtk_text_buffer_get_iter_at_offset (buffer, &end, selection_end);
- gtk_text_buffer_select_range (buffer, &start, &end);
+ gtk_text_buffer_get_iter_at_offset (buffer, &bound_iter, selection_bound);
+ gtk_text_buffer_select_range (buffer, &insert_iter, &bound_iter);
}
}
@@ -583,13 +580,57 @@ action_list_delete_last (GPtrArray *array)
}
static void
+selection_bounds_offsets (GtkTextBuffer *buffer,
+ gint *insert_offset,
+ gint *bound_offset)
+{
+ GtkTextIter insiter, seliter;
+ GtkTextMark *insmark, *selmark;
+
+ insmark = gtk_text_buffer_get_insert (buffer);
+ selmark = gtk_text_buffer_get_selection_bound (buffer);
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &insiter, insmark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &seliter, selmark);
+
+ *insert_offset = gtk_text_iter_get_offset (&insiter);
+ *bound_offset = gtk_text_iter_get_offset (&seliter);
+}
+
+static void
+selection_bounds_to_action (GtkTextBuffer *buffer,
+ GtkSourceUndoAction *undo_action)
+{
+ selection_bounds_offsets (buffer,
+ &undo_action->selection_insert,
+ &undo_action->selection_bound);
+}
+
+static void
+undo_action_swap_selection (GtkSourceUndoAction *action,
+ gint *selection_insert,
+ gint *selection_bound)
+{
+ gint insert_tmp, bound_tmp;
+
+ insert_tmp = *selection_insert;
+ bound_tmp = *selection_bound;
+
+ *selection_insert = action->selection_insert;
+ *selection_bound = action->selection_bound;
+
+ action->selection_insert = insert_tmp;
+ action->selection_bound = bound_tmp;
+}
+
+static void
gtk_source_undo_manager_undo_impl (GtkSourceUndoManager *manager)
{
GtkSourceUndoManagerDefault *manager_default;
GtkSourceUndoAction *undo_action;
gboolean modified = FALSE;
- gint selection_start = -1;
- gint selection_end;
+ gint selection_insert;
+ gint selection_bound;
manager_default = GTK_SOURCE_UNDO_MANAGER_DEFAULT (manager);
@@ -599,6 +640,11 @@ gtk_source_undo_manager_undo_impl (GtkSourceUndoManager *manager)
gtk_source_undo_manager_begin_not_undoable_action (manager);
+ /* Initially obtain restored selection from the buffer. */
+ selection_bounds_offsets (manager_default->priv->buffer,
+ &selection_insert,
+ &selection_bound);
+
do
{
undo_action = action_list_nth_data (manager_default->priv->actions,
@@ -619,6 +665,12 @@ gtk_source_undo_manager_undo_impl (GtkSourceUndoManager *manager)
!manager_default->priv->modified_undoing_group);
}
+ /* Swap the current selection into the action while obtaining
+ * the selection after undo from undo_action */
+ undo_action_swap_selection (undo_action,
+ &selection_insert,
+ &selection_bound);
+
switch (undo_action->action_type)
{
case GTK_SOURCE_UNDO_ACTION_DELETE:
@@ -626,9 +678,6 @@ gtk_source_undo_manager_undo_impl (GtkSourceUndoManager *manager)
undo_action->action.delete.start,
undo_action->action.delete.text,
strlen (undo_action->action.delete.text));
-
- selection_start = undo_action->action.delete.selection_start;
- selection_end = undo_action->action.delete.selection_end;
break;
case GTK_SOURCE_UNDO_ACTION_INSERT:
@@ -636,9 +685,6 @@ gtk_source_undo_manager_undo_impl (GtkSourceUndoManager *manager)
undo_action->action.insert.pos,
undo_action->action.insert.pos +
undo_action->action.insert.chars);
-
- selection_start = undo_action->action.insert.selection_start;
- selection_end = undo_action->action.insert.selection_end;
break;
default:
@@ -650,11 +696,11 @@ gtk_source_undo_manager_undo_impl (GtkSourceUndoManager *manager)
} while (undo_action->order_in_group > 1);
- if (selection_start >= 0)
+ if (selection_insert >= 0)
{
set_cursor (manager_default->priv->buffer,
- selection_start,
- selection_end);
+ selection_insert,
+ selection_bound);
}
if (modified)
@@ -688,13 +734,18 @@ gtk_source_undo_manager_redo_impl (GtkSourceUndoManager *manager)
GtkSourceUndoManagerDefault *manager_default;
GtkSourceUndoAction *undo_action;
gboolean modified = FALSE;
- gint selection_start = -1;
- gint selection_end;
+ gint selection_insert;
+ gint selection_bound;
manager_default = GTK_SOURCE_UNDO_MANAGER_DEFAULT (manager);
g_return_if_fail (manager_default->priv->can_redo);
+ /* Initially obtain restored selection from the buffer. */
+ selection_bounds_offsets (manager_default->priv->buffer,
+ &selection_insert,
+ &selection_bound);
+
undo_action = action_list_nth_data (manager_default->priv->actions,
manager_default->priv->next_redo);
g_return_if_fail (undo_action != NULL);
@@ -711,6 +762,12 @@ gtk_source_undo_manager_redo_impl (GtkSourceUndoManager *manager)
--manager_default->priv->next_redo;
+ /* Swap the current selection into the action while obtaining
+ * the selection after undo from undo_action */
+ undo_action_swap_selection (undo_action,
+ &selection_insert,
+ &selection_bound);
+
switch (undo_action->action_type)
{
case GTK_SOURCE_UNDO_ACTION_DELETE:
@@ -718,15 +775,10 @@ gtk_source_undo_manager_redo_impl (GtkSourceUndoManager *manager)
undo_action->action.delete.start,
undo_action->action.delete.end);
- selection_start = undo_action->action.delete.selection_start;
- selection_end = undo_action->action.delete.selection_end;
break;
case GTK_SOURCE_UNDO_ACTION_INSERT:
- selection_start = undo_action->action.insert.selection_start;
- selection_end = undo_action->action.insert.selection_end;
-
insert_text (manager_default->priv->buffer,
undo_action->action.insert.pos,
undo_action->action.insert.text,
@@ -748,11 +800,11 @@ gtk_source_undo_manager_redo_impl (GtkSourceUndoManager *manager)
} while ((undo_action != NULL) && (undo_action->order_in_group > 1));
- if (selection_start >= 0)
+ if (selection_insert >= 0)
{
set_cursor (manager_default->priv->buffer,
- selection_start,
- selection_end);
+ selection_insert,
+ selection_bound);
}
if (modified)
@@ -841,14 +893,10 @@ insert_text_handler (GtkTextBuffer *buffer,
GtkSourceUndoManagerDefault *manager)
{
GtkSourceUndoAction undo_action;
- GtkTextIter selstart;
- GtkTextIter selend;
if (manager->priv->running_not_undoable_actions > 0)
return;
- gtk_text_buffer_get_selection_bounds (buffer, &selstart, &selend);
-
undo_action.action_type = GTK_SOURCE_UNDO_ACTION_INSERT;
undo_action.action.insert.pos = gtk_text_iter_get_offset (pos);
@@ -856,8 +904,7 @@ insert_text_handler (GtkTextBuffer *buffer,
undo_action.action.insert.length = length;
undo_action.action.insert.chars = g_utf8_strlen (text, length);
- undo_action.action.insert.selection_start = gtk_text_iter_get_offset (&selstart);
- undo_action.action.insert.selection_end = gtk_text_iter_get_offset (&selend);
+ selection_bounds_to_action (buffer, &undo_action);
if ((undo_action.action.insert.chars > 1) || (g_utf8_get_char (text) == '\n'))
@@ -878,14 +925,10 @@ delete_range_handler (GtkTextBuffer *buffer,
{
GtkSourceUndoAction undo_action;
GtkTextIter insert_iter;
- GtkTextIter selstart;
- GtkTextIter selend;
if (um->priv->running_not_undoable_actions > 0)
return;
- gtk_text_buffer_get_selection_bounds (buffer, &selstart, &selend);
-
undo_action.action_type = GTK_SOURCE_UNDO_ACTION_DELETE;
gtk_text_iter_order (start, end);
@@ -898,8 +941,7 @@ delete_range_handler (GtkTextBuffer *buffer,
undo_action.action.delete.start,
undo_action.action.delete.end);
- undo_action.action.delete.selection_start = gtk_text_iter_get_offset (&selstart);
- undo_action.action.delete.selection_end = gtk_text_iter_get_offset (&selend);
+ selection_bounds_to_action (buffer, &undo_action);
/* figure out if the user used the Delete or the Backspace key */
gtk_text_buffer_get_iter_at_mark (buffer, &insert_iter,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]