[gtk/wip/otte/undo: 1/17] undo: Add skeleton of base classes



commit cb7756c9058e656fd2cb3c5e0bba51bc98499226
Author: Benjamin Otte <otte redhat com>
Date:   Sun Aug 2 06:26:00 2015 +0200

    undo: Add skeleton of base classes

 gtk/Makefile.am             |   4 ++
 gtk/gtkundocommand.c        | 117 +++++++++++++++++++++++++++++++
 gtk/gtkundocommandprivate.h |  68 ++++++++++++++++++
 gtk/gtkundostack.c          | 164 ++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkundostackprivate.h   |  61 ++++++++++++++++
 5 files changed, 414 insertions(+)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 4fd509cdac..f75dfc4736 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -529,6 +529,8 @@ gtk_private_h_sources =             \
        gtktooltipprivate.h     \
        gtktreedatalist.h       \
        gtktreeprivate.h        \
+       gtkundocommandprivate.h \
+       gtkundostackprivate.h   \
        gtkwidgetprivate.h      \
        gtkwin32themeprivate.h  \
        gtkwindowprivate.h      \
@@ -860,6 +862,8 @@ gtk_base_c_sources =                \
        gtktreeview.c           \
        gtktreeviewcolumn.c     \
        gtktypebuiltins.c       \
+       gtkundocommand.c        \
+       gtkundostack.c          \
        gtkvolumebutton.c       \
        gtkviewport.c           \
        gtkwidget.c             \
diff --git a/gtk/gtkundocommand.c b/gtk/gtkundocommand.c
new file mode 100644
index 0000000000..8fbe0e6798
--- /dev/null
+++ b/gtk/gtkundocommand.c
@@ -0,0 +1,117 @@
+/*
+ * 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 "gtkundocommandprivate.h"
+
+#include <glib/gi18n-lib.h>
+
+typedef struct _GtkUndoCommandPrivate GtkUndoCommandPrivate;
+struct _GtkUndoCommandPrivate {
+  gint64 timestamp;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GtkUndoCommand, gtk_undo_command, G_TYPE_OBJECT,
+                         G_ADD_PRIVATE (GtkUndoCommand))
+
+static gboolean
+gtk_undo_command_real_undo (GtkUndoCommand *command)
+{
+  g_warning ("%s class failed to implement undo", G_OBJECT_TYPE_NAME (command));
+
+  return FALSE;
+}
+
+gboolean
+gtk_undo_command_real_redo (GtkUndoCommand *command)
+{
+  g_warning ("%s class failed to implement redo", G_OBJECT_TYPE_NAME (command));
+
+  return FALSE;
+}
+
+GtkUndoCommand *
+gtk_undo_command_real_merge (GtkUndoCommand *command,
+                             GtkUndoCommand *followup)
+{
+  return NULL;
+}
+
+char *
+gtk_undo_command_real_describe (GtkUndoCommand *command)
+{
+  g_warning ("%s class failed to implement undo", G_OBJECT_TYPE_NAME (command));
+
+  /* translators: This string is the fallback message that gets used
+   * when undo commands are improperly implemented and don't have a
+   * proper description. */
+  return g_strdup (_("unknown undo command"));
+}
+
+static void
+gtk_undo_command_class_init (GtkUndoCommandClass *klass)
+{
+  klass->undo = gtk_undo_command_real_undo;
+  klass->redo = gtk_undo_command_real_redo;
+  klass->merge = gtk_undo_command_real_merge;
+  klass->describe = gtk_undo_command_real_describe;
+}
+
+static void
+gtk_undo_command_init (GtkUndoCommand *command)
+{
+  GtkUndoCommandPrivate *priv = gtk_undo_command_get_instance_private (command);
+
+  priv->timestamp = g_get_real_time ();
+}
+
+gboolean
+gtk_undo_command_undo (GtkUndoCommand *command)
+{
+  g_return_val_if_fail (GTK_IS_UNDO_COMMAND (command), FALSE);
+
+  return GTK_UNDO_COMMAND_GET_CLASS (command)->undo (command);
+}
+
+gboolean
+gtk_undo_command_redo (GtkUndoCommand *command)
+{
+  g_return_val_if_fail (GTK_IS_UNDO_COMMAND (command), FALSE);
+
+  return GTK_UNDO_COMMAND_GET_CLASS (command)->redo (command);
+}
+
+GtkUndoCommand *
+gtk_undo_command_merge (GtkUndoCommand *command,
+                        GtkUndoCommand *followup_command)
+{
+  g_return_val_if_fail (GTK_IS_UNDO_COMMAND (command), NULL);
+  g_return_val_if_fail (GTK_IS_UNDO_COMMAND (followup_command), NULL);
+
+  return GTK_UNDO_COMMAND_GET_CLASS (command)->merge (command, followup_command);
+}
+
+char *
+gtk_undo_command_describe (GtkUndoCommand *command)
+{
+  g_return_val_if_fail (GTK_IS_UNDO_COMMAND (command), NULL);
+
+  return GTK_UNDO_COMMAND_GET_CLASS (command)->describe (command);
+}
diff --git a/gtk/gtkundocommandprivate.h b/gtk/gtkundocommandprivate.h
new file mode 100644
index 0000000000..aba26cc7ff
--- /dev/null
+++ b/gtk/gtkundocommandprivate.h
@@ -0,0 +1,68 @@
+/*
+ * 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_COMMAND_PRIVATE_H__
+#define __GTK_UNDO_COMMAND_PRIVATE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_UNDO_COMMAND           (gtk_undo_command_get_type ())
+#define GTK_UNDO_COMMAND(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_UNDO_COMMAND, 
GtkUndoCommand))
+#define GTK_UNDO_COMMAND_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_UNDO_COMMAND, 
GtkUndoCommandClass))
+#define GTK_IS_UNDO_COMMAND(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_UNDO_COMMAND))
+#define GTK_IS_UNDO_COMMAND_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_UNDO_COMMAND))
+#define GTK_UNDO_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_UNDO_COMMAND, 
GtkUndoCommandClass))
+
+typedef struct _GtkUndoCommand           GtkUndoCommand;
+typedef struct _GtkUndoCommandClass      GtkUndoCommandClass;
+
+struct _GtkUndoCommand
+{
+  GObject parent;
+};
+
+struct _GtkUndoCommandClass
+{
+  GObjectClass parent_class;
+
+  /* undo the command, return FALSE if undo failed */
+  gboolean              (* undo)                        (GtkUndoCommand                *command);
+  /* run the command again, return FALSE if redo failed */
+  gboolean              (* redo)                        (GtkUndoCommand                *command);
+  /* merge this command with a followup command, return NULL if merge not possible */
+  GtkUndoCommand *      (* merge)                       (GtkUndoCommand                *command,
+                                                         GtkUndoCommand                *followup_command);
+  /* get a translated string describing the command */
+  char *                (* describe)                    (GtkUndoCommand                *command);
+};
+
+GType                   gtk_undo_command_get_type       (void) G_GNUC_CONST;
+
+gboolean                gtk_undo_command_undo           (GtkUndoCommand                *command);
+gboolean                gtk_undo_command_redo           (GtkUndoCommand                *command);
+GtkUndoCommand *        gtk_undo_command_merge          (GtkUndoCommand                *command,
+                                                         GtkUndoCommand                *followup_command);
+char *                  gtk_undo_command_describe       (GtkUndoCommand                *command);
+
+
+G_END_DECLS
+
+#endif /* __GTK_UNDO_COMMAND_PRIVATE_H__ */
diff --git a/gtk/gtkundostack.c b/gtk/gtkundostack.c
new file mode 100644
index 0000000000..2cdc81a76b
--- /dev/null
+++ b/gtk/gtkundostack.c
@@ -0,0 +1,164 @@
+/*
+ * 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 "gtkundostackprivate.h"
+
+#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
+
+typedef struct _GtkUndoStackPrivate GtkUndoStackPrivate;
+struct _GtkUndoStackPrivate {
+  GSequence *commands;          /* latest added command is at front of queue */
+};
+
+static void gtk_undo_stack_list_model_iface_init (GListModelInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkUndoStack, gtk_undo_stack, G_TYPE_OBJECT,
+                         G_ADD_PRIVATE (GtkUndoStack);
+                         G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_undo_stack_list_model_iface_init));
+
+static GType
+gtk_undo_stack_list_model_get_item_type (GListModel *list)
+{
+  return GTK_TYPE_UNDO_COMMAND;
+}
+
+static guint
+gtk_undo_stack_list_model_get_n_items (GListModel *list)
+{
+  GtkUndoStackPrivate *priv = gtk_undo_stack_get_instance_private (GTK_UNDO_STACK (list));
+
+  return g_sequence_get_length (priv->commands);
+}
+
+static gpointer
+gtk_undo_stack_list_model_get_item (GListModel *list,
+                                    guint       position)
+{
+  GtkUndoStackPrivate *priv = gtk_undo_stack_get_instance_private (GTK_UNDO_STACK (list));
+  guint len;
+
+  /* XXX: This is sloooow. */
+  len = g_sequence_get_length (priv->commands);
+  if (position >= len)
+    return NULL;
+
+  return g_object_ref (g_sequence_get (g_sequence_get_iter_at_pos (priv->commands, len - position - 1)));
+}
+
+static void
+gtk_undo_stack_list_model_iface_init (GListModelInterface *iface)
+{
+  iface->get_item_type = gtk_undo_stack_list_model_get_item_type;
+  iface->get_n_items = gtk_undo_stack_list_model_get_n_items;
+  iface->get_item = gtk_undo_stack_list_model_get_item;
+}
+
+static void
+gtk_undo_stack_dispose (GObject *object)
+{
+  GtkUndoStack *stack = GTK_UNDO_STACK (object);
+
+  gtk_undo_stack_clear (stack);
+
+  G_OBJECT_CLASS (gtk_undo_stack_parent_class)->dispose (object);
+}
+
+static void
+gtk_undo_stack_finalize (GObject *object)
+{
+  GtkUndoStack *stack = GTK_UNDO_STACK (object);
+  GtkUndoStackPrivate *priv = gtk_undo_stack_get_instance_private (stack);
+
+  g_sequence_free (priv->commands);
+
+  G_OBJECT_CLASS (gtk_undo_stack_parent_class)->finalize (object);
+}
+
+static void
+gtk_undo_stack_class_init (GtkUndoStackClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = gtk_undo_stack_dispose;
+  object_class->finalize = gtk_undo_stack_finalize;
+}
+
+static void
+gtk_undo_stack_init (GtkUndoStack *stack)
+{
+  GtkUndoStackPrivate *priv = gtk_undo_stack_get_instance_private (stack);
+
+  priv->commands = g_sequence_new (g_object_unref);
+}
+
+GtkUndoStack *
+gtk_undo_stack_new (void)
+{
+  return g_object_new (GTK_TYPE_UNDO_STACK, NULL);
+}
+
+void
+gtk_undo_stack_clear (GtkUndoStack *stack)
+{
+  GtkUndoStackPrivate *priv = gtk_undo_stack_get_instance_private (stack);
+  guint len;
+
+  g_return_if_fail (GTK_IS_UNDO_STACK (stack));
+
+  len = g_sequence_get_length (priv->commands);
+
+  g_sequence_remove_range (g_sequence_get_begin_iter (priv->commands),
+                           g_sequence_get_end_iter (priv->commands));
+
+  g_list_model_items_changed (G_LIST_MODEL (stack), 0, len, 0);
+}
+
+void
+gtk_undo_stack_push (GtkUndoStack   *stack,
+                     GtkUndoCommand *command)
+{
+  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));
+
+  g_object_ref (command);
+  g_sequence_prepend (priv->commands, command);
+
+  g_list_model_items_changed (G_LIST_MODEL (stack), 0, 0, 1);
+}
+
+gboolean
+gtk_undo_stack_undo (GtkUndoStack *stack)
+{
+  g_return_val_if_fail (GTK_IS_UNDO_STACK (stack), FALSE);
+
+  return FALSE;
+}
+
+gboolean
+gtk_undo_stack_redo (GtkUndoStack *stack)
+{
+  g_return_val_if_fail (GTK_IS_UNDO_STACK (stack), FALSE);
+
+  return FALSE;
+}
diff --git a/gtk/gtkundostackprivate.h b/gtk/gtkundostackprivate.h
new file mode 100644
index 0000000000..033298cfe9
--- /dev/null
+++ b/gtk/gtkundostackprivate.h
@@ -0,0 +1,61 @@
+/*
+ * 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_STACK_PRIVATE_H__
+#define __GTK_UNDO_STACK_PRIVATE_H__
+
+#include <gtk/gtkundocommandprivate.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_UNDO_STACK           (gtk_undo_stack_get_type ())
+#define GTK_UNDO_STACK(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_UNDO_STACK, GtkUndoStack))
+#define GTK_UNDO_STACK_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_UNDO_STACK, GtkUndoStackClass))
+#define GTK_IS_UNDO_STACK(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_UNDO_STACK))
+#define GTK_IS_UNDO_STACK_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_UNDO_STACK))
+#define GTK_UNDO_STACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_UNDO_STACK, 
GtkUndoStackClass))
+
+typedef struct _GtkUndoStack           GtkUndoStack;
+typedef struct _GtkUndoStackClass      GtkUndoStackClass;
+
+struct _GtkUndoStack
+{
+  GObject parent;
+};
+
+struct _GtkUndoStackClass
+{
+  GObjectClass parent_class;
+};
+
+GType                   gtk_undo_stack_get_type       (void) G_GNUC_CONST;
+
+GtkUndoStack *          gtk_undo_stack_new            (void);
+
+void                    gtk_undo_stack_clear          (GtkUndoStack     *stack);
+void                    gtk_undo_stack_push           (GtkUndoStack     *stack,
+                                                       GtkUndoCommand   *command);
+
+gboolean                gtk_undo_stack_undo           (GtkUndoStack     *stack);
+gboolean                gtk_undo_stack_redo           (GtkUndoStack     *stack);
+
+
+G_END_DECLS
+
+#endif /* __GTK_UNDO_STACK_PRIVATE_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]