[gtk/wip/otte/undo: 17/17] undo: Add a way to record multiple commands into one



commit 21e0327ed6259e8f5abe03d77ce5b2390ce74c38
Author: Benjamin Otte <otte redhat com>
Date:   Mon Aug 24 21:20:10 2015 +0200

    undo: Add a way to record multiple commands into one
    
    This is a so far just a simple object that collects commands, merges
    them and then combines them into a single GtkUndoCommandChain at the
    end. It's supposed to be used with a mechanism that goes
      begin_user_action();
      /* do stuff */
      end_user_action();
    The begin_user_action() would create the recorder, then all new commands
    would be put into the recorder and end_user_action() would then finish
    the recorder and extract one resulting command.

 gtk/Makefile.am              |   2 +
 gtk/gtkundorecorder.c        | 154 +++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkundorecorderprivate.h |  60 +++++++++++++++++
 3 files changed, 216 insertions(+)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 17927696f0..8df024d2c1 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -532,6 +532,7 @@ gtk_private_h_sources =             \
        gtktreeprivate.h        \
        gtkundocommandchainprivate.h    \
        gtkundocommandprivate.h \
+       gtkundorecorderprivate.h        \
        gtkundostackprivate.h   \
        gtkundoundocommandprivate.h     \
        gtkwidgetprivate.h      \
@@ -868,6 +869,7 @@ gtk_base_c_sources =                \
        gtktypebuiltins.c       \
        gtkundocommand.c        \
        gtkundocommandchain.c   \
+       gtkundorecorder.c       \
        gtkundostack.c          \
        gtkundoundocommand.c    \
        gtkvolumebutton.c       \
diff --git a/gtk/gtkundorecorder.c b/gtk/gtkundorecorder.c
new file mode 100644
index 0000000000..9411328742
--- /dev/null
+++ b/gtk/gtkundorecorder.c
@@ -0,0 +1,154 @@
+/*
+ * 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 "gtkundorecorderprivate.h"
+
+#include <glib/gi18n-lib.h>
+
+#include "gtkundocommandchainprivate.h"
+
+typedef struct _GtkUndoRecorderPrivate GtkUndoRecorderPrivate;
+struct _GtkUndoRecorderPrivate {
+  GSList *commands;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GtkUndoRecorder, gtk_undo_recorder, G_TYPE_OBJECT,
+                         G_ADD_PRIVATE (GtkUndoRecorder))
+
+static void
+gtk_undo_recorder_dispose (GObject *object)
+{
+  gtk_undo_recorder_clear (GTK_UNDO_RECORDER (object));
+
+  G_OBJECT_CLASS (gtk_undo_recorder_parent_class)->dispose (object);
+}
+
+static void
+gtk_undo_recorder_class_init (GtkUndoRecorderClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = gtk_undo_recorder_dispose;
+}
+
+static void
+gtk_undo_recorder_init (GtkUndoRecorder *recorder)
+{
+}
+
+GtkUndoRecorder *
+gtk_undo_recorder_new (void)
+{
+  return g_object_new (GTK_TYPE_UNDO_RECORDER, NULL);
+}
+
+void
+gtk_undo_recorder_push (GtkUndoRecorder *recorder,
+                        GtkUndoCommand  *command)
+{
+  GtkUndoRecorderPrivate *priv = gtk_undo_recorder_get_instance_private (recorder);
+
+  g_return_if_fail (GTK_IS_UNDO_RECORDER (recorder));
+  g_return_if_fail (GTK_IS_UNDO_COMMAND (command));
+
+  if (priv->commands)
+    {
+      GtkUndoCommand *merge;
+
+      merge = gtk_undo_command_merge (priv->commands->data, command);
+      if (merge == NULL)
+        {
+          /* undo commands cancel out */
+          g_object_unref (priv->commands->data);
+          priv->commands = g_slist_remove (priv->commands, priv->commands->data);
+          return;
+        }
+      else if (GTK_IS_UNDO_COMMAND_CHAIN (merge))
+        {
+        }
+    }
+  else
+    {
+      g_object_ref (command);
+    }
+
+  priv->commands = g_slist_prepend (priv->commands, command);
+}
+
+GtkUndoCommand *
+gtk_undo_recorder_create_command_chain (const GSList *list)
+{
+  GtkUndoCommand **commands;
+  GtkUndoCommand *result;
+  gsize i, n_commands;
+
+  n_commands = g_slist_length ((GSList *) list);
+  commands = g_newa (GtkUndoCommand *, n_commands);
+
+  for (i = 0; i < n_commands; i++)
+    {
+      commands[i] = list->data;
+      list = list->next;
+    }
+
+  result = gtk_undo_command_chain_new (commands, n_commands);
+
+  return result;
+}
+
+GtkUndoCommand *
+gtk_undo_recorder_finish (GtkUndoRecorder *recorder)
+{
+  GtkUndoRecorderPrivate *priv = gtk_undo_recorder_get_instance_private (recorder);
+  GtkUndoCommand *result;
+
+  g_return_val_if_fail (GTK_IS_UNDO_RECORDER (recorder), NULL);
+
+  if (priv->commands == NULL)
+    {
+      result = NULL;
+    }
+  else if (priv->commands->next == NULL)
+    {
+      result = g_object_ref (priv->commands->data);
+    }
+  else
+    {
+      result = gtk_undo_recorder_create_command_chain (priv->commands);
+    }
+
+  gtk_undo_recorder_clear (recorder);
+
+  return result;
+}
+
+void
+gtk_undo_recorder_clear (GtkUndoRecorder *recorder)
+{
+  GtkUndoRecorderPrivate *priv = gtk_undo_recorder_get_instance_private (recorder);
+
+  g_return_if_fail (GTK_IS_UNDO_RECORDER (recorder));
+
+  g_slist_free_full (priv->commands, g_object_unref);
+
+  priv->commands = NULL;
+}
+
diff --git a/gtk/gtkundorecorderprivate.h b/gtk/gtkundorecorderprivate.h
new file mode 100644
index 0000000000..f5f41bdb4c
--- /dev/null
+++ b/gtk/gtkundorecorderprivate.h
@@ -0,0 +1,60 @@
+/*
+ * 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_RECORDER_PRIVATE_H__
+#define __GTK_UNDO_RECORDER_PRIVATE_H__
+
+#include <gtk/gtkundocommandprivate.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_UNDO_RECORDER           (gtk_undo_recorder_get_type ())
+#define GTK_UNDO_RECORDER(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_UNDO_RECORDER, 
GtkUndoRecorder))
+#define GTK_UNDO_RECORDER_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_UNDO_RECORDER, 
GtkUndoRecorderClass))
+#define GTK_IS_UNDO_RECORDER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_UNDO_RECORDER))
+#define GTK_IS_UNDO_RECORDER_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_UNDO_RECORDER))
+#define GTK_UNDO_RECORDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_UNDO_RECORDER, 
GtkUndoRecorderClass))
+
+typedef struct _GtkUndoRecorder           GtkUndoRecorder;
+typedef struct _GtkUndoRecorderClass      GtkUndoRecorderClass;
+
+struct _GtkUndoRecorder
+{
+  GObject parent;
+};
+
+struct _GtkUndoRecorderClass
+{
+  GObjectClass parent_class;
+};
+
+GType                   gtk_undo_recorder_get_type       (void) G_GNUC_CONST;
+
+GtkUndoRecorder *       gtk_undo_recorder_new            (void);
+
+void                    gtk_undo_recorder_push           (GtkUndoRecorder                *recorder,
+                                                          GtkUndoCommand                 *command);
+
+GtkUndoCommand *        gtk_undo_recorder_finish         (GtkUndoRecorder                *recorder);
+void                    gtk_undo_recorder_clear          (GtkUndoRecorder                *recorder);
+
+
+G_END_DECLS
+
+#endif /* __GTK_UNDO_RECORDER_PRIVATE_H__ */


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