[gtksourceview/wip/undo-redo] UndoManager: new implementation based on GQueues (not finished)
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/undo-redo] UndoManager: new implementation based on GQueues (not finished)
- Date: Sun, 31 Aug 2014 16:59:06 +0000 (UTC)
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]