[gtksourceview/wip/undo-redo] UndoManager: new implementation based on GQueues (not finished)



commit 3980a4a852f930afe40644b7bea2d76eb6a7f2c5
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Aug 31 17:40:40 2014 +0200

    UndoManager: new implementation based on GQueues (not finished)

 gtksourceview/gtksourceundomanagerdefault.c |  150 +++++++++++++++++++++++++++
 1 files changed, 150 insertions(+), 0 deletions(-)
---
diff --git a/gtksourceview/gtksourceundomanagerdefault.c b/gtksourceview/gtksourceundomanagerdefault.c
index f843613..9a6bcbe 100644
--- a/gtksourceview/gtksourceundomanagerdefault.c
+++ b/gtksourceview/gtksourceundomanagerdefault.c
@@ -134,6 +134,143 @@ G_DEFINE_TYPE_WITH_CODE (GtkSourceUndoManagerDefault,
                          G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_UNDO_MANAGER,
                                                 gtk_source_undo_manager_iface_init))
 
+/* ActionInsert implementation */
+
+static Action *
+action_insert_new (void)
+{
+       Action *action;
+
+       action = g_slice_new0 (Action);
+       action->action_type = ACTION_TYPE_INSERT;
+
+       return action;
+}
+
+static void
+action_insert_free (Action *action)
+{
+       g_assert (action->action_type == ACTION_TYPE_INSERT);
+
+       g_free (action->action.insert.text);
+       g_slice_free (Action, action);
+}
+
+/* ActionDelete implementation */
+
+static Action *
+action_delete_new (void)
+{
+       Action *action;
+
+       action = g_slice_new0 (Action);
+       action->action_type = ACTION_TYPE_DELETE;
+
+       return action;
+}
+
+static void
+action_delete_free (Action *action)
+{
+       g_assert (action->action_type == ACTION_TYPE_DELETE);
+
+       g_free (action->action.delete.text);
+       g_slice_free (Action, action);
+}
+
+/* Action functions. The Action struct can be seen as an interface. All the
+ * switch (action->action_type) are grouped in this section.
+ */
+
+static void
+action_free (Action *action)
+{
+       if (action == NULL)
+       {
+               return;
+       }
+
+       switch (action->action_type)
+       {
+               case ACTION_TYPE_INSERT:
+                       action_insert_free (action);
+                       break;
+
+               case ACTION_TYPE_DELETE:
+                       action_delete_free (action);
+                       break;
+
+               default:
+                       g_return_if_reached ();
+                       break;
+       }
+}
+
+/* Utilities functions */
+
+static ActionGroup *
+action_group_new (void)
+{
+       ActionGroup *group;
+
+       group = g_slice_new (ActionGroup);
+       group->actions = g_queue_new ();
+
+       return group;
+}
+
+static void
+action_group_free (ActionGroup *group)
+{
+       if (group != NULL)
+       {
+               g_queue_free_full (group->actions, (GDestroyNotify) action_free);
+               g_slice_free (ActionGroup, group);
+       }
+}
+
+static void
+remove_last_action_group (GtkSourceUndoManagerDefault *manager)
+{
+       ActionGroup *group;
+
+       if (manager->priv->location == manager->priv->action_groups->tail)
+       {
+               manager->priv->location = NULL;
+       }
+
+       if (manager->priv->saved_location == manager->priv->action_groups->tail)
+       {
+               manager->priv->saved_location = NULL;
+       }
+
+       group = g_queue_pop_tail (manager->priv->action_groups);
+       action_group_free (group);
+}
+
+static void
+remove_redo_action_groups (GtkSourceUndoManagerDefault *manager)
+{
+       while (manager->priv->location != NULL)
+       {
+               remove_last_action_group (manager);
+       }
+}
+
+static void
+insert_action (GtkSourceUndoManagerDefault *manager,
+              Action                      *new_action)
+{
+       ActionGroup *group;
+
+       remove_redo_action_groups (manager);
+
+       group = action_group_new ();
+       g_queue_push_tail (group->actions, new_action);
+
+       g_queue_push_tail (manager->priv->action_groups, group);
+}
+
 /* Buffer signal handlers */
 
 static void
@@ -143,6 +280,12 @@ insert_text_cb (GtkTextBuffer               *buffer,
                gint                         length,
                GtkSourceUndoManagerDefault *manager)
 {
+       Action *action = action_insert_new ();
+
+       action->action.insert.pos = gtk_text_iter_get_offset (location);
+       action->action.insert.text = g_strndup (text, length);
+
+       insert_action (manager, action);
 }
 
 static void
@@ -275,6 +418,11 @@ gtk_source_undo_manager_default_dispose (GObject *object)
 static void
 gtk_source_undo_manager_default_finalize (GObject *object)
 {
+       GtkSourceUndoManagerDefault *manager = GTK_SOURCE_UNDO_MANAGER_DEFAULT (object);
+
+       g_queue_free_full (manager->priv->action_groups,
+                          (GDestroyNotify) action_group_free);
+
        G_OBJECT_CLASS (gtk_source_undo_manager_default_parent_class)->finalize (object);
 }
 
@@ -311,6 +459,8 @@ static void
 gtk_source_undo_manager_default_init (GtkSourceUndoManagerDefault *manager)
 {
        manager->priv = gtk_source_undo_manager_default_get_instance_private (manager);
+
+       manager->priv->action_groups = g_queue_new ();
 }
 
 /* Interface implementation */


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