[gtk/wip/otte/undo: 4/17] undo: Actually implement undo
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/undo: 4/17] undo: Actually implement undo
- Date: Mon, 18 Feb 2019 17:12:44 +0000 (UTC)
commit 130625662887d23f480b398645bff064acaa675a
Author: Benjamin Otte <otte redhat com>
Date: Thu Aug 6 02:10:47 2015 +0200
undo: Actually implement undo
gtk/Makefile.am | 2 +
gtk/gtkundostack.c | 60 ++++++++++++++--
gtk/gtkundoundocommand.c | 151 ++++++++++++++++++++++++++++++++++++++++
gtk/gtkundoundocommandprivate.h | 56 +++++++++++++++
4 files changed, 262 insertions(+), 7 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 6d404e4d58..d1b05a8cc3 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -532,6 +532,7 @@ gtk_private_h_sources = \
gtktreeprivate.h \
gtkundocommandprivate.h \
gtkundostackprivate.h \
+ gtkundoundocommandprivate.h \
gtkwidgetprivate.h \
gtkwin32themeprivate.h \
gtkwindowprivate.h \
@@ -866,6 +867,7 @@ gtk_base_c_sources = \
gtktypebuiltins.c \
gtkundocommand.c \
gtkundostack.c \
+ gtkundoundocommand.c \
gtkvolumebutton.c \
gtkviewport.c \
gtkwidget.c \
diff --git a/gtk/gtkundostack.c b/gtk/gtkundostack.c
index 2cdc81a76b..3b6a358499 100644
--- a/gtk/gtkundostack.c
+++ b/gtk/gtkundostack.c
@@ -24,6 +24,8 @@
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
+#include "gtkundoundocommandprivate.h"
+
typedef struct _GtkUndoStackPrivate GtkUndoStackPrivate;
struct _GtkUndoStackPrivate {
GSequence *commands; /* latest added command is at front of queue */
@@ -132,27 +134,71 @@ gtk_undo_stack_clear (GtkUndoStack *stack)
g_list_model_items_changed (G_LIST_MODEL (stack), 0, len, 0);
}
-void
-gtk_undo_stack_push (GtkUndoStack *stack,
- GtkUndoCommand *command)
+static void
+gtk_undo_stack_push_internal (GtkUndoStack *stack,
+ GtkUndoCommand *command,
+ gboolean replace)
{
GtkUndoStackPrivate *priv = gtk_undo_stack_get_instance_private (stack);
- g_return_if_fail (GTK_IS_UNDO_STACK (stack));
- g_return_if_fail (GTK_IS_UNDO_COMMAND (command));
+ if (replace)
+ g_sequence_remove (g_sequence_get_begin_iter (priv->commands));
g_object_ref (command);
g_sequence_prepend (priv->commands, command);
- g_list_model_items_changed (G_LIST_MODEL (stack), 0, 0, 1);
+ g_list_model_items_changed (G_LIST_MODEL (stack), 0, replace ? 1 : 0, 1);
+}
+
+void
+gtk_undo_stack_push (GtkUndoStack *stack,
+ GtkUndoCommand *command)
+{
+ g_return_if_fail (GTK_IS_UNDO_STACK (stack));
+ g_return_if_fail (GTK_IS_UNDO_COMMAND (command));
+
+ gtk_undo_stack_push_internal (stack, command, FALSE);
}
gboolean
gtk_undo_stack_undo (GtkUndoStack *stack)
{
+ GtkUndoStackPrivate *priv = gtk_undo_stack_get_instance_private (stack);
+ GtkUndoCommand *command, *undo;
+ GSequenceIter *begin_iter, *end_iter;
+ gboolean replace = FALSE;
+
g_return_val_if_fail (GTK_IS_UNDO_STACK (stack), FALSE);
- return FALSE;
+ begin_iter = g_sequence_get_begin_iter (priv->commands);
+ if (g_sequence_iter_is_end (begin_iter))
+ return FALSE;
+
+ undo = g_sequence_get (begin_iter);
+
+ if (GTK_IS_UNDO_UNDO_COMMAND (undo))
+ {
+ begin_iter = g_sequence_iter_next (begin_iter);
+ end_iter = g_sequence_iter_move (begin_iter, gtk_undo_undo_command_get_n_items (GTK_UNDO_UNDO_COMMAND
(undo)));
+ if (g_sequence_iter_is_end (end_iter))
+ return FALSE;
+
+ undo = g_sequence_get (end_iter);
+ end_iter = g_sequence_iter_next (end_iter);
+ replace = TRUE;
+ }
+ else
+ {
+ end_iter = g_sequence_iter_next (begin_iter);
+ replace = FALSE;
+ }
+
+ gtk_undo_command_undo (undo);
+ command = gtk_undo_undo_command_new (begin_iter, end_iter);
+ gtk_undo_stack_push_internal (stack, command, replace);
+ g_object_unref (command);
+
+ return TRUE;
}
gboolean
diff --git a/gtk/gtkundoundocommand.c b/gtk/gtkundoundocommand.c
new file mode 100644
index 0000000000..0c119c9d0b
--- /dev/null
+++ b/gtk/gtkundoundocommand.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2015 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkundoundocommandprivate.h"
+
+#include <glib/gi18n-lib.h>
+
+typedef struct _GtkUndoUndoCommandPrivate GtkUndoUndoCommandPrivate;
+struct _GtkUndoUndoCommandPrivate {
+ GSequence *commands; /* sequence of GtkUndoCommand, first to undo command first */
+};
+
+G_DEFINE_TYPE_WITH_CODE (GtkUndoUndoCommand, gtk_undo_undo_command, GTK_TYPE_UNDO_COMMAND,
+ G_ADD_PRIVATE (GtkUndoUndoCommand))
+
+static gboolean
+gtk_undo_undo_command_undo (GtkUndoCommand *command)
+{
+ GtkUndoUndoCommandPrivate *priv = gtk_undo_undo_command_get_instance_private (GTK_UNDO_UNDO_COMMAND
(command));
+ GSequenceIter *iter;
+ gboolean result;
+
+ result = FALSE;
+
+ for (iter = g_sequence_get_begin_iter (priv->commands);
+ !g_sequence_iter_is_end (iter);
+ iter = g_sequence_iter_next (iter))
+ {
+ result |= gtk_undo_command_redo (g_sequence_get (iter));
+ }
+
+ return result;
+}
+
+gboolean
+gtk_undo_undo_command_redo (GtkUndoCommand *command)
+{
+ GtkUndoUndoCommandPrivate *priv = gtk_undo_undo_command_get_instance_private (GTK_UNDO_UNDO_COMMAND
(command));
+ GSequenceIter *iter;
+ gboolean result;
+
+ result = FALSE;
+
+ iter = g_sequence_get_end_iter (priv->commands);
+ while (!g_sequence_iter_is_begin (iter))
+ {
+ iter = g_sequence_iter_prev (iter);
+
+ result |= gtk_undo_command_undo (g_sequence_get (iter));
+ }
+
+ return result;
+}
+
+GtkUndoCommand *
+gtk_undo_undo_command_merge (GtkUndoCommand *command,
+ GtkUndoCommand *followup)
+{
+ return NULL;
+}
+
+char *
+gtk_undo_undo_command_describe (GtkUndoCommand *command)
+{
+ GtkUndoUndoCommandPrivate *priv = gtk_undo_undo_command_get_instance_private (GTK_UNDO_UNDO_COMMAND
(command));
+
+ return g_strdup_printf (_("Undo last %u commands"), g_sequence_get_length (priv->commands));
+}
+
+static void
+gtk_undo_undo_command_finalize (GObject *object)
+{
+ GtkUndoUndoCommandPrivate *priv = gtk_undo_undo_command_get_instance_private (GTK_UNDO_UNDO_COMMAND
(object));
+
+ g_sequence_free (priv->commands);
+
+ G_OBJECT_CLASS (gtk_undo_undo_command_parent_class)->finalize (object);
+}
+
+static void
+gtk_undo_undo_command_class_init (GtkUndoUndoCommandClass *klass)
+{
+ GtkUndoCommandClass *undo_class = GTK_UNDO_COMMAND_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gtk_undo_undo_command_finalize;
+
+ undo_class->undo = gtk_undo_undo_command_undo;
+ undo_class->redo = gtk_undo_undo_command_redo;
+ undo_class->merge = gtk_undo_undo_command_merge;
+ undo_class->describe = gtk_undo_undo_command_describe;
+}
+
+static void
+gtk_undo_undo_command_init (GtkUndoUndoCommand *command)
+{
+ GtkUndoUndoCommandPrivate *priv = gtk_undo_undo_command_get_instance_private (GTK_UNDO_UNDO_COMMAND
(command));
+
+ priv->commands = g_sequence_new (g_object_unref);
+}
+
+GtkUndoCommand *
+gtk_undo_undo_command_new (GSequenceIter *begin_iter,
+ GSequenceIter *end_iter)
+{
+ GtkUndoUndoCommand *result;
+ GtkUndoUndoCommandPrivate *priv;
+ GSequenceIter *iter;
+
+ g_return_val_if_fail (begin_iter != NULL, NULL);
+ g_return_val_if_fail (end_iter != NULL, NULL);
+
+ result = g_object_new (GTK_TYPE_UNDO_UNDO_COMMAND, NULL);
+
+ priv = gtk_undo_undo_command_get_instance_private (result);
+ for (iter = begin_iter; iter != end_iter; iter = g_sequence_iter_next (iter))
+ {
+ g_sequence_prepend (priv->commands, g_object_ref (g_sequence_get (iter)));
+ }
+
+ return GTK_UNDO_COMMAND (result);
+}
+
+guint
+gtk_undo_undo_command_get_n_items (GtkUndoUndoCommand *command)
+{
+ GtkUndoUndoCommandPrivate *priv = gtk_undo_undo_command_get_instance_private (GTK_UNDO_UNDO_COMMAND
(command));
+
+ g_return_val_if_fail (GTK_IS_UNDO_UNDO_COMMAND (command), 0);
+
+ return g_sequence_get_length (priv->commands);
+}
+
diff --git a/gtk/gtkundoundocommandprivate.h b/gtk/gtkundoundocommandprivate.h
new file mode 100644
index 0000000000..530720f9fc
--- /dev/null
+++ b/gtk/gtkundoundocommandprivate.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2015 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_UNDO_UNDO_COMMAND_PRIVATE_H__
+#define __GTK_UNDO_UNDO_COMMAND_PRIVATE_H__
+
+#include <gtk/gtkundocommandprivate.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_UNDO_UNDO_COMMAND (gtk_undo_undo_command_get_type ())
+#define GTK_UNDO_UNDO_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_UNDO_UNDO_COMMAND,
GtkUndoUndoCommand))
+#define GTK_UNDO_UNDO_COMMAND_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_UNDO_UNDO_COMMAND,
GtkUndoUndoCommandClass))
+#define GTK_IS_UNDO_UNDO_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_UNDO_UNDO_COMMAND))
+#define GTK_IS_UNDO_UNDO_COMMAND_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_UNDO_UNDO_COMMAND))
+#define GTK_UNDO_UNDO_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_UNDO_UNDO_COMMAND,
GtkUndoUndoCommandClass))
+
+typedef struct _GtkUndoUndoCommand GtkUndoUndoCommand;
+typedef struct _GtkUndoUndoCommandClass GtkUndoUndoCommandClass;
+
+struct _GtkUndoUndoCommand
+{
+ GtkUndoCommand parent;
+};
+
+struct _GtkUndoUndoCommandClass
+{
+ GtkUndoCommandClass parent_class;
+};
+
+GType gtk_undo_undo_command_get_type (void) G_GNUC_CONST;
+
+GtkUndoCommand * gtk_undo_undo_command_new (GSequenceIter *begin_iter,
+ GSequenceIter *end_iter);
+
+guint gtk_undo_undo_command_get_n_items (GtkUndoUndoCommand *command);
+
+G_END_DECLS
+
+#endif /* __GTK_UNDO_UNDO_COMMAND_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]