[dia] Bug 626921 - Pasting text (multiple chars) can not be undone



commit 60b7583e833eb7a5bf5b0125bf18d6d821cb8aee
Author: Hans Breuer <hans breuer org>
Date:   Sat Aug 14 12:52:27 2010 +0200

    Bug 626921 - Pasting text (multiple chars) can not be undone
    
    lib/objchange.[ch] :
    Implement change_list_create() and change_list_add() to accumulate
    a list of changes to be reverted/applied in one step.
    lib/text.c :
    Use it in text_key_event() rather than overwriting the one change
    to return with multiple text char changes.

 lib/objchange.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/objchange.h |    3 ++
 lib/text.c      |    5 +++-
 3 files changed, 79 insertions(+), 1 deletions(-)
---
diff --git a/lib/objchange.c b/lib/objchange.c
index 2f0a560..88bd672 100644
--- a/lib/objchange.c
+++ b/lib/objchange.c
@@ -83,3 +83,75 @@ ObjectChange *new_object_state_change(DiaObject *obj,
   return (ObjectChange *)change;
 }
 
+typedef struct _ObjectChangeList ObjectChangeList;
+struct _ObjectChangeList {
+  ObjectChange object_change;
+  
+  GPtrArray *changes;
+};
+
+static void
+_change_list_apply (ObjectChange *change_list, DiaObject *obj)
+{
+  ObjectChangeList *list = (ObjectChangeList *)change_list;
+  guint i;
+  
+  for (i = 0; i < list->changes->len; ++i) {
+    ObjectChange * change = (ObjectChange *)g_ptr_array_index(list->changes, i);
+    
+    change->apply (change, obj /*?*/);
+  }
+}
+static void
+_change_list_revert (ObjectChange *change_list, DiaObject *obj)
+{
+  ObjectChangeList *list = (ObjectChangeList *)change_list;
+  guint i;
+  
+  for (i = list->changes->len - 1;/* i >= 0 */; --i) {
+    ObjectChange * change = (ObjectChange *)g_ptr_array_index(list->changes, i);
+    
+    change->revert (change, obj /*?*/);
+    if (i == 0)
+      break; /* break here, i>=0 does not work as loop condition (it's always TRUE) */
+  }
+}
+static void
+_change_list_free (ObjectChange *change_list)
+{
+  ObjectChangeList *list = (ObjectChangeList *)change_list;
+  guint i;
+
+  for (i = 0; i < list->changes->len; ++i) {
+    ObjectChange * change = (ObjectChange *)g_ptr_array_index(list->changes, i);
+    
+    if (change->free)
+      change->free (change);
+  }
+  g_ptr_array_free (list->changes, FALSE);
+  /* must not delete the object itself, so no:
+  g_free (change_list);
+   */
+}
+/* An empty list of changes to accumulate many to one change */
+ObjectChange *
+change_list_create (void)
+{
+  ObjectChangeList *list = g_new (ObjectChangeList, 1);
+  
+  list->object_change.apply  = _change_list_apply;
+  list->object_change.revert = _change_list_revert;
+  list->object_change.free   = _change_list_free;
+  
+  list->changes = g_ptr_array_new ();
+  
+  return (ObjectChange *)list;
+}
+
+void
+change_list_add (ObjectChange *change_list, ObjectChange *change)
+{
+  ObjectChangeList *list = (ObjectChangeList *)change_list;
+  
+  g_ptr_array_add (list->changes, change);
+}
diff --git a/lib/objchange.h b/lib/objchange.h
index d0e9566..dbf5e91 100644
--- a/lib/objchange.h
+++ b/lib/objchange.h
@@ -75,4 +75,7 @@ ObjectChange *new_object_state_change(DiaObject *obj,
 				      GetStateFunc get_state,
 				      SetStateFunc set_state );
 
+ObjectChange *change_list_create (void);
+void change_list_add (ObjectChange *change_list, ObjectChange *change);
+
 #endif /* OBJCHANGE_H */
diff --git a/lib/text.c b/lib/text.c
index 16d1861..22b276a 100644
--- a/lib/text.c
+++ b/lib/text.c
@@ -992,12 +992,15 @@ text_key_event(Focus *focus,
           if (str && *str == '\r')
             break; /* avoid putting junk into our string */
           return_val = TRUE;
+	  *change = change_list_create();
           for (utf = str; utf && *utf && strlen > 0 ;
 	       utf = g_utf8_next_char (utf), strlen--) {
+	    ObjectChange *step;
             c = g_utf8_get_char (utf);
             
-            *change = text_create_change (text, TYPE_INSERT_CHAR, c,
+            step = text_create_change (text, TYPE_INSERT_CHAR, c,
                                           text->cursor_pos, text->cursor_row);
+	    change_list_add (*change, step);
             text_insert_char (text, c);
           }
         }



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