[dia] Bug 158570 - undoable background color change (and more)



commit ab126c00ba596e187ce038c926d6e35c9af4cbd4
Author: Hans Breuer <hans breuer org>
Date:   Sun Aug 22 16:42:08 2010 +0200

    Bug 158570 - undoable background color change (and more)
    
    Not only the diagram's background color change can be undone,
    but also grid settings as well a paper info changes.

 app/dia-props.c |   11 +++++++++++
 app/pagesetup.c |    4 ++++
 app/undo.c      |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/undo.h      |    2 ++
 4 files changed, 67 insertions(+), 0 deletions(-)
---
diff --git a/app/dia-props.c b/app/dia-props.c
index cde369b..4377924 100644
--- a/app/dia-props.c
+++ b/app/dia-props.c
@@ -31,6 +31,7 @@
 #include "display.h"
 #include "widgets.h"
 #include "display.h"
+#include "undo.h"
 
 static GtkWidget *dialog = NULL;
 static GtkWidget *dynamic_check;
@@ -318,6 +319,16 @@ diagram_properties_respond(GtkWidget *widget,
   if (response_id == GTK_RESPONSE_OK ||
       response_id == GTK_RESPONSE_APPLY) {
     if (active_diagram) {
+      /* we do not bother for the actual change, just record the 
+       * whole possible change */
+      undo_change_memswap (active_diagram, 
+        &active_diagram->grid, sizeof(active_diagram->grid));
+      undo_change_memswap (active_diagram, 
+        &active_diagram->data->bg_color, sizeof(active_diagram->data->bg_color));
+      undo_change_memswap (active_diagram, 
+        &active_diagram->pagebreak_color, sizeof(active_diagram->pagebreak_color));
+      undo_set_transactionpoint(active_diagram->undo);
+
       active_diagram->grid.dynamic =
         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dynamic_check));
       active_diagram->grid.width_x =
diff --git a/app/pagesetup.c b/app/pagesetup.c
index 4c83afb..efdfc3f 100644
--- a/app/pagesetup.c
+++ b/app/pagesetup.c
@@ -168,6 +168,9 @@ pagesetup_changed(GtkWidget *wid, PageSetup *ps)
 static void
 pagesetup_apply(GtkWidget *wid, PageSetup *ps)
 {
+  undo_change_memswap (ps->dia, &ps->dia->data->paper, sizeof(ps->dia->data->paper));
+  undo_set_transactionpoint(ps->dia->undo);
+
   g_free(ps->dia->data->paper.name);
   ps->dia->data->paper.name =
     g_strdup(dia_page_layout_get_paper(DIA_PAGE_LAYOUT(ps->paper)));
@@ -198,6 +201,7 @@ pagesetup_apply(GtkWidget *wid, PageSetup *ps)
   gtk_dialog_set_response_sensitive(GTK_DIALOG(ps->window), GTK_RESPONSE_APPLY, FALSE);
   ps->changed = FALSE;
 
+  
   /* update diagram -- this is needed to reposition page boundaries */
   diagram_set_modified(ps->dia, TRUE);
   diagram_add_update_all(ps->dia);
diff --git a/app/undo.c b/app/undo.c
index 2ec8a13..e6a80e5 100644
--- a/app/undo.c
+++ b/app/undo.c
@@ -1282,3 +1282,53 @@ undo_move_object_other_layer(Diagram *dia, GList *selected_list,
   undo_push_change(dia->undo, change);
   return change;
 }
+
+typedef struct _MemSwapChange {
+  Change change;
+  
+  gsize   size;
+  guint8 *dest;   /* for 'write trough' */
+  guint8  mem[1]; /* real size during alloc */
+} MemSwapChange;
+static void
+_swap_mem(MemSwapChange *change, Diagram *dia)
+{
+  gsize  i;
+
+  for (i = 0; i < change->size; ++i) {
+    guint8 tmp = change->mem[i];
+    change->mem[i] = change->dest[i];
+    change->dest[i] = tmp;
+  }
+  diagram_add_update_all(dia);
+  diagram_flush(dia);
+}
+/*!
+ * \brief Record a memory region for undo (before actually changing it)
+ *
+ * @dia  : the Diagram to record the change for
+ * @dest : a pointer somewhere in the Diagram 
+ * @size : of the region to copy and restore
+ */
+Change *
+undo_change_memswap (Diagram *dia, gpointer dest, gsize size)
+{
+  MemSwapChange *change = (MemSwapChange *)g_malloc (sizeof(MemSwapChange)+size);
+  gsize i;
+  
+  change->change.apply = (UndoApplyFunc)_swap_mem;
+  change->change.revert = (UndoRevertFunc)_swap_mem;
+  /* just calling g_free() on the change is enough */
+  change->change.free = NULL;
+  
+  change->dest = dest;
+  change->size = size;
+  /* initialize for swap */
+  for (i = 0; i < size; ++i)
+    change->mem[i] = change->dest[i];
+
+  DEBUG_PRINTF(("UNDO: Push new memswap_change(%d) at %d\n", size, depth(dia->undo)));
+  undo_push_change(dia->undo, &change->change);
+
+  return &change->change;
+}
diff --git a/app/undo.h b/app/undo.h
index 7040c0b..4bb5d12 100644
--- a/app/undo.h
+++ b/app/undo.h
@@ -84,6 +84,8 @@ Change *undo_parenting(Diagram *dia, DiaObject *parentobj, DiaObject *childobj,
 		       gboolean parent);
 Change *undo_move_object_other_layer(Diagram *diagram, GList *selected_list,
 				     gboolean moving_up);
+/* handle with care, just plain memory copy */
+Change *undo_change_memswap (Diagram *dia, gpointer dest, gsize size);
 
 #endif /* UNDO_H */
 



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