[gtk/wip/otte/undo: 9/17] entry: Redo recording of undo
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/undo: 9/17] entry: Redo recording of undo
- Date: Mon, 18 Feb 2019 17:13:10 +0000 (UTC)
commit ec991f540556a2662fde027214ac631b5c3cd846
Author: Benjamin Otte <otte redhat com>
Date: Sun Aug 16 07:33:21 2015 +0200
entry: Redo recording of undo
Add a start/end way of capturing the begin and end of an undoable
action. This is necessary because the entry code distinguishes between
changing the contents and updating the cursor position on a very high
level.
And we want to capture the cursor position update in the undo
implementation.
As a nice side effect, the 2 functions are nicely exportable (even for
public API) should we want to. And I guess we might want to for at least
entry completion and comboboxes.
gtk/gtkentry.c | 111 +++++++++++++++++++++++++---------------------
gtk/gtkentryundocommand.c | 4 +-
2 files changed, 62 insertions(+), 53 deletions(-)
---
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 438d0e07e5..c83f5afc7d 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -5371,17 +5371,6 @@ gtk_entry_remove_password_hint (gpointer data)
return FALSE;
}
-static void
-gtk_entry_record_undo_command (GtkEntry *entry,
- const GtkEntrySnapshot *before)
-{
- GtkUndoCommand *command;
-
- command = gtk_entry_undo_command_new (entry, before);
- gtk_undo_stack_push (entry->priv->undo_stack, command);
- g_object_unref (command);
-}
-
/* Default signal handlers
*/
static void
@@ -5391,8 +5380,6 @@ gtk_entry_real_insert_text (GtkEditable *editable,
gint *position)
{
GtkEntry *entry = GTK_ENTRY (editable);
- GtkEntryPrivate *priv = entry->priv;
- GtkEntrySnapshot snapshot = { NULL, };
guint n_inserted;
gint n_chars;
@@ -5403,21 +5390,12 @@ gtk_entry_real_insert_text (GtkEditable *editable,
* following signal handlers: buffer_inserted_text(), buffer_notify_display_text(),
* buffer_notify_text(), buffer_notify_length()
*/
- if (priv->undo_mode == GTK_ENTRY_UNDO_RECORD)
- gtk_entry_snapshot_init_from_entry (&snapshot, entry);
-
begin_change (entry);
n_inserted = gtk_entry_buffer_insert_text (get_buffer (entry), *position, new_text, n_chars);
end_change (entry);
- if (priv->undo_mode == GTK_ENTRY_UNDO_RECORD)
- {
- gtk_entry_record_undo_command (entry, &snapshot);
- gtk_entry_snapshot_clear (&snapshot);
- }
-
if (n_inserted != n_chars)
gtk_widget_error_bell (GTK_WIDGET (editable));
@@ -5430,29 +5408,17 @@ gtk_entry_real_delete_text (GtkEditable *editable,
gint end_pos)
{
GtkEntry *entry = GTK_ENTRY (editable);
- GtkEntryPrivate *priv = entry->priv;
- GtkEntrySnapshot snapshot = { NULL, };
/*
* The actual deletion from the buffer. This will end up firing the
* following signal handlers: buffer_deleted_text(), buffer_notify_display_text(),
* buffer_notify_text(), buffer_notify_length()
*/
-
- if (priv->undo_mode == GTK_ENTRY_UNDO_RECORD)
- gtk_entry_snapshot_init_from_entry (&snapshot, entry);
-
begin_change (entry);
gtk_entry_buffer_delete_text (get_buffer (entry), start_pos, end_pos - start_pos);
end_change (entry);
-
- if (priv->undo_mode == GTK_ENTRY_UNDO_RECORD)
- {
- gtk_entry_record_undo_command (entry, &snapshot);
- gtk_entry_snapshot_clear (&snapshot);
- }
}
/* GtkEntryBuffer signal handlers
@@ -5843,12 +5809,55 @@ gtk_entry_delete_from_cursor (GtkEntry *entry,
gtk_entry_pend_cursor_blink (entry);
}
+typedef struct _GtkEntryRecording GtkEntryRecording;
+struct _GtkEntryRecording {
+ GtkEntryUndoMode old_mode;
+ GtkEntrySnapshot snapshot;
+};
+
+static GtkEntryRecording *
+gtk_entry_start_recording (GtkEntry *entry)
+{
+ GtkEntryRecording *recording;
+
+ g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
+
+ recording = g_slice_new0 (GtkEntryRecording);
+ recording->old_mode = gtk_entry_set_undo_mode (entry, GTK_ENTRY_UNDO_RECORD);
+ gtk_entry_snapshot_init_from_entry (&recording->snapshot, entry);
+
+ return recording;
+}
+
+static void
+gtk_entry_end_recording (GtkEntry *entry,
+ GtkEntryRecording *recording,
+ gboolean commit)
+{
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+ g_return_if_fail (recording != NULL);
+
+ if (commit)
+ {
+ GtkUndoCommand *command;
+
+ command = gtk_entry_undo_command_new (entry, &recording->snapshot);
+ gtk_undo_stack_push (entry->priv->undo_stack, command);
+ g_object_unref (command);
+ }
+
+ gtk_entry_set_undo_mode (entry, recording->old_mode);
+
+ gtk_entry_snapshot_clear (&recording->snapshot);
+ g_slice_free (GtkEntryRecording, recording);
+}
+
static void
gtk_entry_backspace (GtkEntry *entry)
{
GtkEntryPrivate *priv = entry->priv;
GtkEditable *editable = GTK_EDITABLE (entry);
- GtkEntryUndoMode old_mode;
+ GtkEntryRecording *recording;
gint prev_pos;
gtk_entry_reset_im_context (entry);
@@ -5861,9 +5870,9 @@ gtk_entry_backspace (GtkEntry *entry)
if (priv->selection_bound != priv->current_pos)
{
- old_mode = gtk_entry_set_undo_mode (entry, GTK_ENTRY_UNDO_RECORD);
+ recording = gtk_entry_start_recording (entry);
gtk_editable_delete_selection (editable);
- gtk_entry_set_undo_mode (entry, old_mode);
+ gtk_entry_end_recording (entry, recording, TRUE);
return;
}
@@ -5875,7 +5884,7 @@ gtk_entry_backspace (GtkEntry *entry)
PangoLogAttr *log_attrs;
gint n_attrs;
- old_mode = gtk_entry_set_undo_mode (entry, GTK_ENTRY_UNDO_RECORD);
+ recording = gtk_entry_start_recording (entry);
pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
@@ -5912,7 +5921,7 @@ gtk_entry_backspace (GtkEntry *entry)
gtk_editable_delete_text (editable, prev_pos, priv->current_pos);
}
- gtk_entry_set_undo_mode (entry, old_mode);
+ gtk_entry_end_recording (entry, recording, TRUE);
g_free (log_attrs);
}
@@ -5953,7 +5962,7 @@ gtk_entry_cut_clipboard (GtkEntry *entry)
{
GtkEntryPrivate *priv = entry->priv;
GtkEditable *editable = GTK_EDITABLE (entry);
- GtkEntryUndoMode old_mode;
+ GtkEntryRecording *recording;
gint start, end;
if (!priv->visible)
@@ -5968,9 +5977,9 @@ gtk_entry_cut_clipboard (GtkEntry *entry)
{
if (gtk_editable_get_selection_bounds (editable, &start, &end))
{
- old_mode = gtk_entry_set_undo_mode (entry, GTK_ENTRY_UNDO_RECORD);
+ recording = gtk_entry_start_recording (entry);
gtk_editable_delete_text (editable, start, end);
- gtk_entry_set_undo_mode (entry, old_mode);
+ gtk_entry_end_recording (entry, recording, TRUE);
}
}
else
@@ -6162,16 +6171,16 @@ gtk_entry_delete_surrounding_cb (GtkIMContext *slave,
GtkEntry *entry)
{
GtkEntryPrivate *priv = entry->priv;
- GtkEntryUndoMode old_mode;
+ GtkEntryRecording *recording;
- old_mode = gtk_entry_set_undo_mode (entry, GTK_ENTRY_UNDO_RECORD);
+ recording = gtk_entry_start_recording (entry);
if (priv->editable)
gtk_editable_delete_text (GTK_EDITABLE (entry),
priv->current_pos + offset,
priv->current_pos + offset + n_chars);
- gtk_entry_set_undo_mode (entry, old_mode);
+ gtk_entry_end_recording (entry, recording, TRUE);
return TRUE;
}
@@ -6186,14 +6195,14 @@ gtk_entry_enter_text (GtkEntry *entry,
{
GtkEntryPrivate *priv = entry->priv;
GtkEditable *editable = GTK_EDITABLE (entry);
- GtkEntryUndoMode old_mode;
+ GtkEntryRecording *recording;
gint tmp_pos;
gboolean old_need_im_reset;
old_need_im_reset = priv->need_im_reset;
priv->need_im_reset = FALSE;
- old_mode = gtk_entry_set_undo_mode (entry, GTK_ENTRY_UNDO_RECORD);
+ recording = gtk_entry_start_recording (entry);
if (gtk_editable_get_selection_bounds (editable, NULL, NULL))
gtk_editable_delete_selection (editable);
@@ -6207,7 +6216,7 @@ gtk_entry_enter_text (GtkEntry *entry,
gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos);
gtk_editable_set_position (editable, tmp_pos);
- gtk_entry_set_undo_mode (entry, old_mode);
+ gtk_entry_end_recording (entry, recording, TRUE);
priv->need_im_reset = old_need_im_reset;
}
@@ -7457,7 +7466,7 @@ paste_received (GtkClipboard *clipboard,
GtkEntry *entry = GTK_ENTRY (data);
GtkEditable *editable = GTK_EDITABLE (entry);
GtkEntryPrivate *priv = entry->priv;
- GtkEntryUndoMode old_mode;
+ GtkEntryRecording *recording;
guint button;
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (priv->multipress_gesture));
@@ -7497,14 +7506,14 @@ paste_received (GtkClipboard *clipboard,
}
begin_change (entry);
- old_mode = gtk_entry_set_undo_mode (entry, GTK_ENTRY_UNDO_RECORD);
+ recording = gtk_entry_start_recording (entry);
if (gtk_editable_get_selection_bounds (editable, &start, &end))
gtk_editable_delete_text (editable, start, end);
pos = priv->current_pos;
gtk_editable_insert_text (editable, text, length, &pos);
gtk_editable_set_position (editable, pos);
- gtk_entry_set_undo_mode (entry, old_mode);
+ gtk_entry_end_recording (entry, recording, TRUE);
end_change (entry);
if (completion &&
diff --git a/gtk/gtkentryundocommand.c b/gtk/gtkentryundocommand.c
index e7812cf617..b8d2f18071 100644
--- a/gtk/gtkentryundocommand.c
+++ b/gtk/gtkentryundocommand.c
@@ -196,9 +196,9 @@ gtk_entry_undo_command_describe (GtkUndoCommand *command)
if (before_len == after_len && before_len == prefix_len)
return g_strdup (_("No changes")); /* huh? */
else if (prefix_len + suffix_len == before_len)
- return g_strdup_printf (_("Entered `%*s'"), after_len - prefix_len - suffix_len, priv->after.text +
prefix_len);
+ return g_strdup_printf (_("Entered `%.*s'"), after_len - prefix_len - suffix_len, priv->after.text +
prefix_len);
else if (prefix_len + suffix_len == after_len)
- return g_strdup_printf (_("Deleted `%*s'"), before_len - prefix_len - suffix_len, priv->before.text +
prefix_len);
+ return g_strdup_printf (_("Deleted `%.*s'"), before_len - prefix_len - suffix_len, priv->before.text +
prefix_len);
else
return g_strdup (_("Text changed"));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]