[dia] Bug 318182 - let undo restore size of automatically resized shapes



commit 02f2ae578cdc56d359710000370b034f2e9db162
Author: Hans Breuer <hans breuer org>
Date:   Mon Jun 13 22:02:48 2011 +0200

    Bug 318182 - let undo restore size of automatically resized shapes
    
    ATM only objects derived from Element will get resized by text change
    undo, but it should be simple to extend if other objects need it.

 app/commands.c |    2 +-
 lib/text.c     |   75 +++++++++++++++++++++++++++++++++++++++++++++++--------
 lib/text.h     |    2 +-
 3 files changed, 66 insertions(+), 13 deletions(-)
---
diff --git a/app/commands.c b/app/commands.c
index 328cfad..b5be0b0 100644
--- a/app/commands.c
+++ b/app/commands.c
@@ -733,7 +733,7 @@ edit_cut_text_callback (GtkAction *action)
 
   prop_list_free(textprops);
 
-  if (text_delete_all(focus->text, &change)) { 
+  if (text_delete_all(focus->text, &change, obj)) { 
     object_add_updates(obj, ddisp->diagram);
     undo_object_change(ddisp->diagram, obj, change);
     undo_set_transactionpoint(ddisp->diagram->undo);
diff --git a/lib/text.c b/lib/text.c
index cfc4484..4d23515 100644
--- a/lib/text.c
+++ b/lib/text.c
@@ -33,6 +33,7 @@
 #include "objchange.h"
 #include "textline.h"
 #include "attributes.h"
+#include "object.h"
 
 static int text_key_event(Focus *focus, 
 			  guint keystate, guint keysym,
@@ -57,6 +58,13 @@ struct TextObjectChange {
   int pos;
   int row;
   gchar *str;
+
+  /* the owning object ... */
+  DiaObject *obj;
+  /* ... and it's size position properties, which might change
+   * as a side-effect of changing the text
+   */
+  GPtrArray *props;
 };
 
 #define CURSOR_HEIGHT_RATIO 20
@@ -166,7 +174,8 @@ text_get_descent(Text *text)
 }
 
 static ObjectChange *text_create_change(Text *text, TextChangeType type,
-					gunichar ch, int pos, int row);
+					gunichar ch, int pos, int row,
+					DiaObject *obj);
 
 static void
 calc_width(Text *text)
@@ -872,7 +881,7 @@ text_delete_key_handler(Focus *focus, ObjectChange ** change)
   if (text->cursor_pos >= text_get_line_strlen(text, row)) {
     if (row+1 < text->numlines) {
       *change = text_create_change(text, TYPE_JOIN_ROW, 'Q',
-				   text->cursor_pos, row);
+				   text->cursor_pos, row, focus->obj);
     } else {
       return FALSE;
     }
@@ -882,7 +891,7 @@ text_delete_key_handler(Focus *focus, ObjectChange ** change)
       utf = g_utf8_next_char (utf);
     c = g_utf8_get_char (utf);
     *change = text_create_change (text, TYPE_DELETE_FORWARD, c,
-				  text->cursor_pos, text->cursor_row);
+				  text->cursor_pos, text->cursor_row, focus->obj);
   }
   text_delete_forward(text);
   return TRUE;;
@@ -961,7 +970,8 @@ text_key_event(Focus *focus,
         if (text->cursor_pos <= 0) {
           if (row > 0) {
             *change = text_create_change(text, TYPE_JOIN_ROW, 'Q',
-                                         text_get_line_strlen(text, row-1), row-1);
+                                         text_get_line_strlen(text, row-1), row-1,
+					 focus->obj);
           } else {
             return_val = FALSE;
             break;
@@ -973,7 +983,8 @@ text_key_event(Focus *focus,
           c = g_utf8_get_char (utf);
           *change = text_create_change (text, TYPE_DELETE_BACKWARD, c,
                                         text->cursor_pos - 1,
-                                        text->cursor_row);
+                                        text->cursor_row,
+					focus->obj);
         }
         text_delete_backward(text);
         break;
@@ -981,7 +992,8 @@ text_key_event(Focus *focus,
       case GDK_KP_Enter:
         return_val = TRUE;
         *change = text_create_change(text, TYPE_SPLIT_ROW, 'Q',
-                                     text->cursor_pos, text->cursor_row);
+                                     text->cursor_pos, text->cursor_row,
+				     focus->obj);
         text_split_line(text);
         break;
       case GDK_Shift_L:
@@ -1006,7 +1018,8 @@ text_key_event(Focus *focus,
             c = g_utf8_get_char (utf);
             
             step = text_create_change (text, TYPE_INSERT_CHAR, c,
-                                          text->cursor_pos, text->cursor_row);
+                                       text->cursor_pos, text->cursor_row,
+				       focus->obj);
 	    change_list_add (*change, step);
             text_insert_char (text, c);
           }
@@ -1029,11 +1042,12 @@ int text_is_empty(Text *text)
 }
 
 int
-text_delete_all(Text *text, ObjectChange **change)
+text_delete_all(Text *text, ObjectChange **change, DiaObject *obj)
 {
   if (!text_is_empty(text)) {
     *change = text_create_change(text, TYPE_DELETE_ALL,
-				 0, text->cursor_pos, text->cursor_row);
+				 0, text->cursor_pos, text->cursor_row,
+				 obj);
     
     text_set_string(text, "");
     calc_ascent_descent(text);
@@ -1144,6 +1158,11 @@ static void
 text_change_apply(struct TextObjectChange *change, DiaObject *obj)
 {
   Text *text = change->text;
+
+  /* remember previous position/size */
+  if (change->obj->ops->get_props)
+    change->obj->ops->get_props(change->obj, change->props);
+
   switch (change->type) {
   case TYPE_INSERT_CHAR:
     text->cursor_pos = change->pos;
@@ -1212,21 +1231,55 @@ text_change_revert(struct TextObjectChange *change, DiaObject *obj)
     text->cursor_row = change->row;
     break;
   }
+  /* restore previous position/size */
+  if (change->obj->ops->set_props)
+    change->obj->ops->set_props(change->obj, change->props);
 }
 
 static void
-text_change_free(struct TextObjectChange *change) {
+text_change_free(struct TextObjectChange *change) 
+{
   g_free(change->str);
+  prop_list_free(change->props);
+}
+
+/* If some object does not properly resize when undoing
+ * text changes consider adding some additional properties.
+ *
+ * The list can contain more properties than supported by
+ * the specific object, the'll get ignored than.
+ */
+static PropDescription _prop_descs[] = {
+  { "elem_corner", PROP_TYPE_POINT },
+  { "elem_width", PROP_TYPE_REAL },
+  { "elem_height", PROP_TYPE_REAL },
+    PROP_DESC_END
+};
+
+static GPtrArray *
+make_posision_and_size_prop_list (void)
+{
+  GPtrArray *props;
+
+  props = prop_list_from_descs(_prop_descs,pdtpp_true);
+
+  return props;
 }
 
 static ObjectChange *
 text_create_change(Text *text, TextChangeType type,
-		   gunichar ch, int pos, int row)
+		   gunichar ch, int pos, int row, DiaObject *obj)
 {
   struct TextObjectChange *change;
 
   change = g_new0(struct TextObjectChange, 1);
 
+  change->obj = obj;
+  change->props = make_posision_and_size_prop_list ();
+  /* remember previous position/size */
+  if (change->obj->ops->get_props)
+    change->obj->ops->get_props(change->obj, change->props);
+
   change->obj_change.apply = (ObjectChangeApplyFunc) text_change_apply;
   change->obj_change.revert = (ObjectChangeRevertFunc) text_change_revert;
   change->obj_change.free = (ObjectChangeFreeFunc) text_change_free;
diff --git a/lib/text.h b/lib/text.h
index 6927857..a003015 100644
--- a/lib/text.h
+++ b/lib/text.h
@@ -78,7 +78,7 @@ void text_set_cursor(Text *text, Point *clicked_point,
 void text_set_cursor_at_end( Text* text );
 void text_grab_focus(Text *text, DiaObject *object);
 int text_is_empty(Text *text);
-int text_delete_all(Text *text, ObjectChange **change);
+int text_delete_all(Text *text, ObjectChange **change, DiaObject *obj);
 void text_get_attributes(Text *text, TextAttributes *attr);
 void text_set_attributes(Text *text, TextAttributes *attr);
 



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