[dia] change: port Change(s) to DiaChange



commit 9e1b3a3112bca7405503985954b59737c2c37752
Author: Zander Brown <zbrown gnome org>
Date:   Sun Sep 29 18:28:20 2019 +0100

    change: port Change(s) to DiaChange

 app/commands.c                          |  48 +-
 app/connectionpoint_ops.c               |  12 +-
 app/create_object.c                     |   8 +-
 app/dia-change.h                        |  28 ++
 app/dia-props.c                         |  15 +-
 app/diagram.c                           |  68 +--
 app/disp_callbacks.c                    |  22 +-
 app/find-and-replace.c                  |  36 +-
 app/layer-editor/dia-layer-editor.c     |  10 +-
 app/layer-editor/dia-layer-properties.c |   2 +-
 app/layer-editor/dia-layer-widget.c     |   6 +-
 app/layer-editor/layer_dialog.c         |  95 ++--
 app/layer-editor/layer_dialog.h         |  35 +-
 app/menus.c                             |   2 +-
 app/modify_tool.c                       |  23 +-
 app/object_ops.c                        |  16 +-
 app/pagesetup.c                         |   2 +-
 app/properties-dialog.c                 |  25 +-
 app/textedit.c                          |  35 +-
 app/undo.c                              | 865 +++++++++++++++++++-------------
 app/undo.h                              | 173 +++++--
 21 files changed, 913 insertions(+), 613 deletions(-)
---
diff --git a/app/commands.c b/app/commands.c
index 03f6baa5..ca0c237b 100644
--- a/app/commands.c
+++ b/app/commands.c
@@ -216,7 +216,7 @@ insert_text (DDisplay *ddisp, Focus *focus, const gchar *text)
     object_add_updates (obj, ddisp->diagram);
 
     if (modified && (change != NULL)) {
-      undo_object_change (ddisp->diagram, obj, change);
+      dia_object_change_change_new (ddisp->diagram, obj, change);
       any_modified = TRUE;
     }
 
@@ -280,7 +280,7 @@ received_clipboard_image_handler (GtkClipboard *clipboard,
     object_add_updates (obj, dia);
     change = dia_object_set_pixbuf (obj, pixbuf);
     if (change) {
-      undo_object_change (dia, obj, change);
+      dia_object_change_change_new (dia, obj, change);
       /* ... and after the change */
       object_add_updates (obj, dia);
       diagram_modified (dia);
@@ -313,7 +313,7 @@ received_clipboard_image_handler (GtkClipboard *clipboard,
         g_free (change);
       }
       /* allow undo of the whole thing */
-      undo_insert_objects (dia, g_list_prepend (NULL, obj), 1);
+      dia_insert_objects_change_new (dia, g_list_prepend (NULL, obj), 1);
 
       diagram_add_object (dia, obj);
       diagram_select (dia, obj);
@@ -354,7 +354,7 @@ received_clipboard_content_handler (GtkClipboard     *clipboard,
       DiaContext *ctx = dia_context_new (_("Clipboard Paste"));
 
       if (ifilter->import_mem_func) {
-        Change *change = undo_import_change_setup (ddisp->diagram);
+        DiaChange *change = dia_import_change_new (ddisp->diagram);
 
         if (!ifilter->import_mem_func (data,
                                        len,
@@ -367,7 +367,7 @@ received_clipboard_content_handler (GtkClipboard     *clipboard,
                                    type_name);
           dia_context_release (ctx);
         }
-        if (undo_import_change_done (ddisp->diagram, change)) {
+        if (dia_import_change_done (ddisp->diagram, change)) {
           undo_set_transactionpoint (ddisp->diagram->undo);
           diagram_modified (ddisp->diagram);
           diagram_flush (ddisp->diagram);
@@ -637,7 +637,7 @@ edit_cut_callback (GtkAction *action)
 {
   GList *cut_list;
   DDisplay *ddisp;
-  Change *change;
+  DiaChange *change;
 
   ddisp = ddisplay_active ();
   if (!ddisp) {
@@ -652,8 +652,8 @@ edit_cut_callback (GtkAction *action)
 
     cnp_store_objects (object_copy_list (cut_list), 0);
 
-    change = undo_delete_objects_children (ddisp->diagram, cut_list);
-    (change->apply) (change, ddisp->diagram);
+    change = dia_delete_objects_change_new_with_children (ddisp->diagram, cut_list);
+    dia_change_apply (change, ddisp->diagram);
 
     ddisplay_do_update_menu_sensitivity (ddisp);
     diagram_flush (ddisp->diagram);
@@ -671,7 +671,7 @@ edit_paste_callback (GtkAction *action)
   DDisplay *ddisp;
   Point paste_corner;
   Point delta;
-  Change *change;
+  DiaChange *change;
   int generation = 0;
 
   ddisp = ddisplay_active();
@@ -710,8 +710,8 @@ edit_paste_callback (GtkAction *action)
       object_list_move_delta (paste_list, &delta);
     }
 
-    change = undo_insert_objects (ddisp->diagram, paste_list, 0);
-    (change->apply) (change, ddisp->diagram);
+    change = dia_insert_objects_change_new (ddisp->diagram, paste_list, 0);
+    dia_change_apply (change, ddisp->diagram);
 
     diagram_modified (ddisp->diagram);
     undo_set_transactionpoint (ddisp->diagram->undo);
@@ -739,7 +739,7 @@ edit_duplicate_callback (GtkAction *action)
   GList *duplicate_list;
   DDisplay *ddisp;
   Point delta;
-  Change *change;
+  DiaChange *change;
 
   ddisp = ddisplay_active ();
   if (!ddisp || textedit_mode (ddisp)) {
@@ -753,8 +753,8 @@ edit_duplicate_callback (GtkAction *action)
 
   object_list_move_delta (duplicate_list, &delta);
 
-  change = undo_insert_objects (ddisp->diagram, duplicate_list, 0);
-  (change->apply) (change, ddisp->diagram);
+  change = dia_insert_objects_change_new (ddisp->diagram, duplicate_list, 0);
+  dia_change_apply (change, ddisp->diagram);
 
   diagram_modified (ddisp->diagram);
   undo_set_transactionpoint (ddisp->diagram->undo);
@@ -772,16 +772,16 @@ objects_move_up_layer (GtkAction *action)
 {
   DDisplay *ddisp = ddisplay_active ();
   GList *selected_list;
-  Change *change;
+  DiaChange *change;
 
   if (!ddisp || textedit_mode (ddisp)) {
     return;
   }
   selected_list = diagram_get_sorted_selected (ddisp->diagram);
 
-  change = undo_move_object_other_layer (ddisp->diagram, selected_list, TRUE);
+  change = dia_move_object_to_layer_change_new (ddisp->diagram, selected_list, TRUE);
 
-  (change->apply) (change, ddisp->diagram);
+  dia_change_apply (change, ddisp->diagram);
 
   diagram_modified (ddisp->diagram);
   undo_set_transactionpoint (ddisp->diagram->undo);
@@ -796,7 +796,7 @@ objects_move_down_layer (GtkAction *action)
 {
   DDisplay *ddisp = ddisplay_active ();
   GList *selected_list;
-  Change *change;
+  DiaChange *change;
 
   if (!ddisp || textedit_mode(ddisp)) {
     return;
@@ -805,9 +805,9 @@ objects_move_down_layer (GtkAction *action)
 
   /* Must check if move is legal here */
 
-  change = undo_move_object_other_layer (ddisp->diagram, selected_list, FALSE);
+  change = dia_move_object_to_layer_change_new (ddisp->diagram, selected_list, FALSE);
 
-  (change->apply) (change, ddisp->diagram);
+  dia_change_apply (change, ddisp->diagram);
 
   diagram_modified (ddisp->diagram);
   undo_set_transactionpoint (ddisp->diagram->undo);
@@ -904,7 +904,7 @@ edit_cut_text_callback (GtkAction *action)
 
   if (text_delete_all (focus->text, &change, obj)) {
     object_add_updates (obj, ddisp->diagram);
-    undo_object_change (ddisp->diagram, obj, change);
+    dia_object_change_change_new (ddisp->diagram, obj, change);
     undo_set_transactionpoint (ddisp->diagram->undo);
     diagram_modified (ddisp->diagram);
     diagram_flush (ddisp->diagram);
@@ -954,13 +954,13 @@ edit_delete_callback (GtkAction *action)
     }
     object_add_updates (focus->obj, ddisp->diagram);
   } else {
-    Change *change = NULL;
+    DiaChange *change = NULL;
     diagram_selected_break_external (ddisp->diagram);
 
     delete_list = diagram_get_sorted_selected (ddisp->diagram);
-    change = undo_delete_objects_children (ddisp->diagram, delete_list);
+    change = dia_delete_objects_change_new_with_children (ddisp->diagram, delete_list);
     g_list_free (delete_list);
-    (change->apply) (change, ddisp->diagram);
+    dia_change_apply (change, ddisp->diagram);
   }
   diagram_modified (ddisp->diagram);
   diagram_update_extents (ddisp->diagram);
diff --git a/app/connectionpoint_ops.c b/app/connectionpoint_ops.c
index bdffc2ab..35286ed4 100644
--- a/app/connectionpoint_ops.c
+++ b/app/connectionpoint_ops.c
@@ -214,12 +214,12 @@ diagram_unconnect_selected(Diagram *dia)
       Handle *handle = selected_obj->handles[i];
 
       if ((handle->connected_to != NULL) &&
-         (handle->connect_type == HANDLE_CONNECTABLE)){
-         /* don't do this if type is HANDLE_CONNECTABLE_BREAK */
-       if (!diagram_is_selected(dia, handle->connected_to->object)) {
-         Change *change = undo_unconnect(dia, selected_obj, handle);
-         (change->apply)(change, dia);
-       }
+          (handle->connect_type == HANDLE_CONNECTABLE)){
+          /* don't do this if type is HANDLE_CONNECTABLE_BREAK */
+        if (!diagram_is_selected(dia, handle->connected_to->object)) {
+          DiaChange *change = dia_unconnect_change_new (dia, selected_obj, handle);
+          dia_change_apply (change, dia);
+        }
       }
     }
 
diff --git a/app/create_object.c b/app/create_object.c
index 3efc2236..add9ad21 100644
--- a/app/create_object.c
+++ b/app/create_object.c
@@ -157,9 +157,9 @@ create_object_button_release(CreateObjectTool *tool, GdkEventButton *event,
   for (; parent_candidates != NULL; parent_candidates = g_list_next(parent_candidates)) {
     DiaObject *parent_obj = (DiaObject *) parent_candidates->data;
     if (obj != parent_obj
-       && object_within_parent(obj, parent_obj)) {
-      Change *change = undo_parenting(ddisp->diagram, parent_obj, obj, TRUE);
-      (change->apply)(change, ddisp->diagram);
+        && object_within_parent (obj, parent_obj)) {
+      DiaChange *change = dia_parenting_change_new (ddisp->diagram, parent_obj, obj, TRUE);
+      dia_change_apply (change, ddisp->diagram);
       break;
     /*
     obj->parent = parent_obj;
@@ -171,7 +171,7 @@ create_object_button_release(CreateObjectTool *tool, GdkEventButton *event,
 
   list = g_list_prepend(list, tool->obj);
 
-  undo_insert_objects(ddisp->diagram, list, 1);
+  dia_insert_objects_change_new (ddisp->diagram, list, 1);
 
   if (tool->moving) {
     if (tool->handle->connect_type != HANDLE_NONCONNECTABLE) {
diff --git a/app/dia-change.h b/app/dia-change.h
index f834dc19..3c8d4c89 100644
--- a/app/dia-change.h
+++ b/app/dia-change.h
@@ -47,10 +47,38 @@ typedef struct _DiaChangeClass DiaChangeClass;
 #define DIA_CHANGE_CLASS_NAME(class) (g_type_name (DIA_CHANGE_CLASS_TYPE (class)))
 #define G_VALUE_HOLDS_CHANGE(value)  (G_TYPE_CHECK_VALUE_TYPE ((value), DIA_TYPE_CHANGE))
 
+
+#define DIA_DEFINE_CHANGE(TypeName, type_name)                               \
+  G_DEFINE_TYPE (TypeName, type_name, DIA_TYPE_CHANGE)                       \
+                                                                             \
+  static void type_name##_apply             (DiaChange        *change,       \
+                                             Diagram          *diagram);     \
+  static void type_name##_revert            (DiaChange        *change,       \
+                                             Diagram          *diagram);     \
+  static void type_name##_free              (DiaChange        *change);      \
+                                                                             \
+  static void                                                                \
+  type_name##_class_init (TypeName##Class *klass)                            \
+  {                                                                          \
+    DiaChangeClass *change_class = DIA_CHANGE_CLASS (klass);                 \
+                                                                             \
+    change_class->apply = type_name##_apply;                                 \
+    change_class->revert = type_name##_revert;                               \
+    change_class->free = type_name##_free;                                   \
+  }                                                                          \
+                                                                             \
+  static void                                                                \
+  type_name##_init (TypeName *klass)                                         \
+  {                                                                          \
+  }
+
 struct _DiaChange {
   GTypeInstance g_type_instance;
 
   grefcount refs;
+
+  DiaChange *next;
+  DiaChange *prev;
 };
 
 struct _DiaChangeClass {
diff --git a/app/dia-props.c b/app/dia-props.c
index 41697732..aab2bfc6 100644
--- a/app/dia-props.c
+++ b/app/dia-props.c
@@ -319,12 +319,15 @@ diagram_properties_respond(GtkWidget *widget,
     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));
+      dia_mem_swap_change_new (active_diagram,
+                               &active_diagram->grid,
+                               sizeof(active_diagram->grid));
+      dia_mem_swap_change_new (active_diagram,
+                               &active_diagram->data->bg_color,
+                               sizeof(active_diagram->data->bg_color));
+      dia_mem_swap_change_new (active_diagram,
+                               &active_diagram->pagebreak_color,
+                               sizeof(active_diagram->pagebreak_color));
       undo_set_transactionpoint(active_diagram->undo);
 
       active_diagram->grid.dynamic =
diff --git a/app/diagram.c b/app/diagram.c
index fe8ec8c7..6515c8e8 100644
--- a/app/diagram.c
+++ b/app/diagram.c
@@ -759,8 +759,8 @@ diagram_selected_break_external (Diagram *dia)
       other_obj = con_point->object;
       if (g_list_find (dia->data->selected, other_obj) == NULL) {
         /* other_obj is not selected, break connection */
-        Change *change = undo_unconnect (dia, obj, obj->handles[i]);
-        (change->apply) (change, dia);
+        DiaChange *change = dia_unconnect_change_new (dia, obj, obj->handles[i]);
+        dia_change_apply (change, dia);
         object_add_updates (obj, dia);
       }
     }
@@ -781,10 +781,10 @@ diagram_selected_break_external (Diagram *dia)
             con_point = other_obj->handles[j]->connected_to;
 
             if (con_point && (con_point->object == obj)) {
-              Change *change;
+              DiaChange *change;
               connected_list = g_list_previous (connected_list);
-              change = undo_unconnect (dia, other_obj, other_obj->handles[j]);
-              (change->apply) (change, dia);
+              change = dia_unconnect_change_new (dia, other_obj, other_obj->handles[j]);
+              dia_change_apply (change, dia);
               if (connected_list == NULL)
                 connected_list = obj->connections[i]->connected;
             }
@@ -1109,14 +1109,14 @@ strip_connections(DiaObject *obj, GList *not_strip_list, Diagram *dia)
 {
   int i;
   Handle *handle;
-  Change *change;
+  DiaChange *change;
 
   for (i=0;i<obj->num_handles;i++) {
     handle = obj->handles[i];
     if ((handle->connected_to != NULL) &&
-       (g_list_find(not_strip_list, handle->connected_to->object)==NULL)) {
-      change = undo_unconnect(dia, obj, handle);
-      (change->apply)(change, dia);
+        (g_list_find(not_strip_list, handle->connected_to->object)==NULL)) {
+      change = dia_unconnect_change_new (dia, obj, handle);
+      dia_change_apply (change, dia);
     }
   }
 }
@@ -1179,15 +1179,15 @@ void diagram_parent_selected(Diagram *dia)
       if (oe1->extent.right <= oe2->extent.right
         && oe1->extent.bottom <= oe2->extent.bottom)
       {
-       Change *change;
-       change = undo_parenting(dia, oe2->object, oe1->object, TRUE);
-       (change->apply)(change, dia);
-       any_parented = TRUE;
-       /*
-        oe1->object->parent = oe2->object;
-       oe2->object->children = g_list_append(oe2->object->children, oe1->object);
-       */
-       break;
+        DiaChange *change;
+        change = dia_parenting_change_new (dia, oe2->object, oe1->object, TRUE);
+        dia_change_apply (change, dia);
+        any_parented = TRUE;
+        /*
+              oe1->object->parent = oe2->object;
+        oe2->object->children = g_list_append(oe2->object->children, oe1->object);
+        */
+        break;
       }
     }
   }
@@ -1204,7 +1204,7 @@ void diagram_unparent_selected(Diagram *dia)
 {
   GList *list;
   DiaObject *obj, *parent;
-  Change *change;
+  DiaChange *change;
   gboolean any_unparented = FALSE;
 
   for (list = dia->data->selected; list != NULL; list = g_list_next(list))
@@ -1215,8 +1215,8 @@ void diagram_unparent_selected(Diagram *dia)
     if (!parent)
       continue;
 
-    change = undo_parenting(dia, parent, obj, FALSE);
-    (change->apply)(change, dia);
+    change = dia_parenting_change_new (dia, parent, obj, FALSE);
+    dia_change_apply (change, dia);
     any_unparented = TRUE;
     /*
     parent->children = g_list_remove(parent->children, obj);
@@ -1248,11 +1248,11 @@ void diagram_unparent_children_selected(Diagram *dia)
      * way.  If needed, we can make a parent undo with a list of children.
      */
     while (obj->children != NULL) {
-      Change *change;
+      DiaChange *change;
       child = (DiaObject *) obj->children->data;
-      change = undo_parenting(dia, obj, child, FALSE);
+      change = dia_parenting_change_new (dia, obj, child, FALSE);
       /* This will remove one item from the list, so the while terminates. */
-      (change->apply)(change, dia);
+      dia_change_apply (change, dia);
     }
     if (obj->children != NULL)
       printf("Obj still has %d children\n",
@@ -1273,7 +1273,7 @@ diagram_group_selected (Diagram *dia)
   DiaObject *group;
   DiaObject *obj;
   GList *orig_list;
-  Change *change;
+  DiaChange *change;
 
   if (g_list_length (dia->data->selected) < 1) {
     message_error (_("Trying to group with no selected objects."));
@@ -1310,8 +1310,8 @@ diagram_group_selected (Diagram *dia)
   data_remove_all_selected (dia->data);
 
   group = group_create (group_list);
-  change = undo_group_objects (dia, group_list, group, orig_list);
-  (change->apply) (change, dia);
+  change = dia_group_objects_change_new (dia, group_list, group, orig_list);
+  dia_change_apply (change, dia);
 
   /* Select the created group */
   diagram_select (dia, group);
@@ -1341,7 +1341,7 @@ void diagram_ungroup_selected(Diagram *dia)
     group = (DiaObject *)selected->data;
 
     if (IS_GROUP(group)) {
-      Change *change;
+      DiaChange *change;
 
       /* Fix selection */
       diagram_unselect_object(dia, group);
@@ -1350,8 +1350,8 @@ void diagram_ungroup_selected(Diagram *dia)
 
       group_index = dia_layer_object_get_index (dia->data->active_layer, group);
 
-      change = undo_ungroup_objects(dia, group_list, group, group_index);
-      (change->apply)(change, dia);
+      change = dia_ungroup_objects_change_new (dia, group_list, group, group_index);
+      dia_change_apply (change, dia);
 
       diagram_select_list(dia, group_list);
       any_groups = 1;
@@ -1399,7 +1399,7 @@ diagram_place_under_selected (Diagram *dia)
   object_add_updates_list (sorted_list, dia);
   dia_layer_add_objects_first (dia->data->active_layer, sorted_list);
 
-  undo_reorder_objects (dia, g_list_copy (sorted_list), orig_list);
+  dia_reorder_objects_change_new (dia, g_list_copy (sorted_list), orig_list);
 
   diagram_modified (dia);
   diagram_flush (dia);
@@ -1421,7 +1421,7 @@ diagram_place_over_selected(Diagram *dia)
   object_add_updates_list (sorted_list, dia);
   dia_layer_add_objects (dia->data->active_layer, sorted_list);
 
-  undo_reorder_objects(dia, g_list_copy(sorted_list), orig_list);
+  dia_reorder_objects_change_new (dia, g_list_copy (sorted_list), orig_list);
 
   diagram_modified(dia);
   diagram_flush(dia);
@@ -1464,7 +1464,7 @@ diagram_place_up_selected(Diagram *dia)
 
   dia_layer_set_object_list (dia->data->active_layer, new_list);
 
-  undo_reorder_objects(dia, g_list_copy(sorted_list), orig_list);
+  dia_reorder_objects_change_new (dia, g_list_copy (sorted_list), orig_list);
 
   diagram_modified(dia);
   diagram_flush(dia);
@@ -1510,7 +1510,7 @@ diagram_place_down_selected (Diagram *dia)
 
   dia_layer_set_object_list (dia->data->active_layer, new_list);
 
-  undo_reorder_objects(dia, g_list_copy(sorted_list), orig_list);
+  dia_reorder_objects_change_new (dia, g_list_copy (sorted_list), orig_list);
 
   diagram_modified(dia);
   diagram_flush(dia);
diff --git a/app/disp_callbacks.c b/app/disp_callbacks.c
index 9b6c11dd..25b21190 100644
--- a/app/disp_callbacks.c
+++ b/app/disp_callbacks.c
@@ -79,7 +79,7 @@ object_menu_item_proxy(GtkWidget *widget, gpointer data)
   diagram_update_connections_object(ddisp->diagram, obj, TRUE);
 
   if (obj_change != NULL) {
-    undo_object_change(ddisp->diagram, obj, obj_change);
+    dia_object_change_change_new (ddisp->diagram, obj, obj_change);
   }
   diagram_modified(ddisp->diagram);
 
@@ -198,7 +198,7 @@ _convert_to_path_callback (GtkAction *action, gpointer data)
   }
   g_list_free (selected);
   if (change_list) {
-    undo_object_change(ddisp->diagram, NULL, change_list);
+    dia_object_change_change_new (ddisp->diagram, NULL, change_list);
 
     diagram_modified(ddisp->diagram);
     diagram_update_extents(ddisp->diagram);
@@ -232,19 +232,19 @@ _combine_to_path_callback (GtkAction *action, gpointer data)
   obj = create_standard_path_from_list (cut_list, GPOINTER_TO_INT (data));
   if (obj) {
     /* remove the objects just combined */
-    Change *change = undo_delete_objects_children(dia, cut_list);
-    (change->apply)(change, dia);
+    DiaChange *change = dia_delete_objects_change_new_with_children (dia, cut_list);
+    dia_change_apply (change, dia);
     /* add the new object with undo */
-    undo_insert_objects(dia, g_list_prepend(NULL, obj), 1);
+    dia_insert_objects_change_new (dia, g_list_prepend (NULL, obj), 1);
     diagram_add_object (dia, obj);
     diagram_select(dia, obj);
-    undo_set_transactionpoint(ddisp->diagram->undo);
+    undo_set_transactionpoint (ddisp->diagram->undo);
     object_add_updates(obj, dia);
   } else {
     /* path combination result is empty, this is just a delete */
-    Change *change = undo_delete_objects_children(ddisp->diagram, cut_list);
-    (change->apply)(change, ddisp->diagram);
-    undo_set_transactionpoint(ddisp->diagram->undo);
+    DiaChange *change = dia_delete_objects_change_new_with_children (ddisp->diagram, cut_list);
+    dia_change_apply (change, ddisp->diagram);
+    undo_set_transactionpoint (ddisp->diagram->undo);
   }
   ddisplay_do_update_menu_sensitivity(ddisp);
   diagram_flush(dia);
@@ -554,7 +554,7 @@ handle_key_event(DDisplay *ddisp, Focus *focus,
 
   if (modified) {
     if (obj_change != NULL) {
-      undo_object_change(ddisp->diagram, obj, obj_change);
+      dia_object_change_change_new (ddisp->diagram, obj, obj_change);
       undo_set_transactionpoint(ddisp->diagram->undo);
     }
     diagram_update_extents(ddisp->diagram);
@@ -1213,7 +1213,7 @@ ddisplay_drop_object(DDisplay *ddisp, gint x, gint y, DiaObjectType *otype,
   diagram_flush(ddisp->diagram);
 
   list = g_list_prepend(NULL, obj);
-  undo_insert_objects(ddisp->diagram, list, 1);
+  dia_insert_objects_change_new (ddisp->diagram, list, 1);
   diagram_update_extents(ddisp->diagram);
 
   undo_set_transactionpoint(ddisp->diagram->undo);
diff --git a/app/find-and-replace.c b/app/find-and-replace.c
index 3961ee5d..b96d5470 100644
--- a/app/find-and-replace.c
+++ b/app/find-and-replace.c
@@ -110,7 +110,7 @@ _match_text_prop (DiaObject *obj, const SearchData *sd, const gchar *replacement
   } else {
     g_free (repl);
   }
-  
+
   return is_match;
 }
 
@@ -333,7 +333,7 @@ find_func (gpointer data, gpointer user_data)
 {
   DiaObject *obj = data;
   SearchData *sd = (SearchData *)user_data;
-  
+
   if (!sd->found) {
     if (_matches (obj, sd)) {
       if (!sd->first)
@@ -363,33 +363,33 @@ _replace (DiaObject *obj, const SearchData *sd, const char *replacement)
   prop_list_free (plist);
 
   if (obj_change)
-    undo_object_change(sd->diagram, obj, obj_change);
-    
+    dia_object_change_change_new (sd->diagram, obj, obj_change);
+
   object_add_updates(obj, sd->diagram);
   diagram_update_connections_object(sd->diagram, obj, TRUE);
   diagram_modified(sd->diagram);
   diagram_object_modified(sd->diagram, obj);
   diagram_update_extents(sd->diagram);
   diagram_flush(sd->diagram);
-  
+
   return TRUE;
 }
 
 static gint
 fnr_respond (GtkWidget *widget, gint response_id, gpointer data)
 {
-  const gchar *search = gtk_entry_get_text (g_object_get_data (G_OBJECT (widget), "search-entry")); 
+  const gchar *search = gtk_entry_get_text (g_object_get_data (G_OBJECT (widget), "search-entry"));
   const gchar *replace;
   DDisplay *ddisp = (DDisplay*)data;
   SearchData sd = { 0, };
   sd.diagram = ddisp->diagram;
-  sd.flags =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON ( 
+  sd.flags =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON (
                   g_object_get_data (G_OBJECT (widget), "match-case"))) ? MATCH_CASE : 0;
-  sd.flags |= gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON ( 
+  sd.flags |= gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON (
                   g_object_get_data (G_OBJECT (widget), "match-word"))) ? MATCH_WORD : 0;
-  sd.flags |= gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON ( 
+  sd.flags |= gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON (
                  g_object_get_data (G_OBJECT (widget), "match-all-properties"))) ? MATCH_ALL_PROPERTIES : 0;
-  
+
 
   switch (response_id) {
   case RESPONSE_FIND :
@@ -485,7 +485,7 @@ fnr_dialog_setup_common (GtkWidget *dialog, gboolean is_replace, DDisplay *ddisp
   gtk_entry_set_width_chars (GTK_ENTRY (search_entry), 30);
   gtk_box_pack_start (GTK_BOX (hbox), search_entry, TRUE, TRUE, 0);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 6);
-  
+
   if (is_replace) {
     GtkWidget *replace_entry;
 
@@ -513,7 +513,7 @@ fnr_dialog_setup_common (GtkWidget *dialog, gboolean is_replace, DDisplay *ddisp
   g_object_set_data (G_OBJECT (dialog), "match-all-properties", match_all_properties);
   if (is_replace)
     gtk_widget_set_sensitive (GTK_WIDGET (match_all_properties), FALSE);
-    
+
 
   gtk_widget_show_all (vbox);
 }
@@ -534,7 +534,7 @@ edit_find_callback(GtkAction *action)
   dialog = g_object_get_data (G_OBJECT (ddisp->shell), "edit-find-dialog");
   if (!dialog) {
     dialog = gtk_dialog_new_with_buttons (
-               _("Find"), 
+               _("Find"),
                GTK_WINDOW (ddisp->shell), GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
                GTK_STOCK_FIND, RESPONSE_FIND,
@@ -544,7 +544,7 @@ edit_find_callback(GtkAction *action)
   }
   g_object_set_data (G_OBJECT (ddisp->shell), "edit-find-dialog", dialog);
 
-  gtk_dialog_run (GTK_DIALOG (dialog));  
+  gtk_dialog_run (GTK_DIALOG (dialog));
 }
 
 /**
@@ -569,11 +569,11 @@ edit_replace_callback(GtkAction *action)
                GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
                _("Replace _All"), RESPONSE_REPLACE_ALL,
                NULL);
-    /* not adding the button in the list above to modify it's text; 
-     * the default "Find and Replace" is just too long for my taste ;) 
+    /* not adding the button in the list above to modify it's text;
+     * the default "Find and Replace" is just too long for my taste ;)
      */
     button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Replace"), RESPONSE_REPLACE);
-    gtk_button_set_image (GTK_BUTTON (button), 
+    gtk_button_set_image (GTK_BUTTON (button),
                           gtk_image_new_from_stock (GTK_STOCK_FIND_AND_REPLACE, GTK_ICON_SIZE_BUTTON));
 
     gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_FIND, RESPONSE_FIND);
@@ -582,5 +582,5 @@ edit_replace_callback(GtkAction *action)
   }
   g_object_set_data (G_OBJECT (ddisp->shell), "edit-replace-dialog", dialog);
 
-  gtk_dialog_run (GTK_DIALOG (dialog));  
+  gtk_dialog_run (GTK_DIALOG (dialog));
 }
diff --git a/app/layer-editor/dia-layer-editor.c b/app/layer-editor/dia-layer-editor.c
index fe07f71a..4c41e1e1 100644
--- a/app/layer-editor/dia-layer-editor.c
+++ b/app/layer-editor/dia-layer-editor.c
@@ -250,7 +250,7 @@ new_layer (GtkWidget *widget, DiaLayerEditor *self)
 
     gtk_list_select_item (GTK_LIST (priv->list), pos);
 
-    undo_layer (dia, layer, TYPE_ADD_LAYER, dia->data->layers->len - pos);
+    dia_layer_change_new (dia, layer, TYPE_ADD_LAYER, dia->data->layers->len - pos);
     undo_set_transactionpoint (dia->undo);
 
     g_free (new_layer_name);
@@ -306,8 +306,8 @@ delete_layer (GtkWidget *widget, DiaLayerEditor *self)
     pos = gtk_list_child_position (GTK_LIST (priv->list), selected);
     gtk_container_remove (GTK_CONTAINER (priv->list), selected);
 
-    undo_layer (dia, layer, TYPE_DELETE_LAYER,
-                dia->data->layers->len - pos);
+    dia_layer_change_new (dia, layer, TYPE_DELETE_LAYER,
+                          dia->data->layers->len - pos);
     undo_set_transactionpoint (dia->undo);
 
     if (--pos < 0) {
@@ -358,7 +358,7 @@ raise_layer (GtkWidget *widget, DiaLayerEditor *self)
       diagram_add_update_all (dia);
       diagram_flush (dia);
 
-      undo_layer (dia, layer, TYPE_RAISE_LAYER, 0);
+      dia_layer_change_new (dia, layer, TYPE_RAISE_LAYER, 0);
       undo_set_transactionpoint (dia->undo);
     }
   }
@@ -404,7 +404,7 @@ lower_layer (GtkWidget *widget, DiaLayerEditor *self)
       diagram_add_update_all (dia);
       diagram_flush (dia);
 
-      undo_layer (dia, layer, TYPE_LOWER_LAYER, 0);
+      dia_layer_change_new (dia, layer, TYPE_LOWER_LAYER, 0);
       undo_set_transactionpoint (dia->undo);
     }
   }
diff --git a/app/layer-editor/dia-layer-properties.c b/app/layer-editor/dia-layer-properties.c
index 311d8e3a..5045b47b 100644
--- a/app/layer-editor/dia-layer-properties.c
+++ b/app/layer-editor/dia-layer-properties.c
@@ -145,7 +145,7 @@ dia_layer_properties_response (GtkDialog *dialog,
     diagram_add_update_all (priv->diagram);
     diagram_flush (priv->diagram);
 
-    undo_layer (priv->diagram, layer, TYPE_ADD_LAYER, pos);
+    dia_layer_change_new (priv->diagram, layer, TYPE_ADD_LAYER, pos);
     undo_set_transactionpoint (priv->diagram->undo);
   } else {
     g_critical ("Huh, no layer or diagram");
diff --git a/app/layer-editor/dia-layer-widget.c b/app/layer-editor/dia-layer-widget.c
index 430ee5d8..64dd0afc 100644
--- a/app/layer-editor/dia-layer-widget.c
+++ b/app/layer-editor/dia-layer-widget.c
@@ -278,16 +278,16 @@ visible_clicked (GtkToggleButton *widget,
 {
   DiaLayerWidget *self = DIA_LAYER_WIDGET (userdata);
   DiaLayerWidgetPrivate *priv = dia_layer_widget_get_instance_private (self);
-  struct LayerVisibilityChange *change;
+  DiaChange *change;
 
   /* Have to use this internal_call hack 'cause there's no way to switch
    * a toggle button without causing the 'clicked' event:(
    */
   if (!priv->internal_call) {
     Diagram *dia = DIA_DIAGRAM (dia_layer_get_parent_diagram (priv->layer));
-    change = undo_layer_visibility (dia, priv->layer, priv->shifted);
+    change = dia_layer_visibility_change_new (dia, priv->layer, priv->shifted);
     /** This apply kills 'lw', thus we have to hold onto 'lw->dia' */
-    layer_visibility_change_apply (change, dia);
+    dia_change_apply (change, dia);
     undo_set_transactionpoint (dia->undo);
   }
 }
diff --git a/app/layer-editor/layer_dialog.c b/app/layer-editor/layer_dialog.c
index d0f80052..9ad0af7e 100644
--- a/app/layer-editor/layer_dialog.c
+++ b/app/layer-editor/layer_dialog.c
@@ -139,9 +139,22 @@ layer_dialog_set_diagram (Diagram *dia)
 
 /******** layer changes: */
 
+struct _DiaLayerChange {
+  DiaChange change;
+
+  enum LayerChangeType type;
+  DiaLayer *layer;
+  int index;
+  int applied;
+};
+
+DIA_DEFINE_CHANGE (DiaLayerChange, dia_layer_change)
+
+
 static void
-layer_change_apply(struct LayerChange *change, Diagram *dia)
+dia_layer_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaLayerChange *change = DIA_LAYER_CHANGE (self);
   change->applied = 1;
 
   switch (change->type) {
@@ -162,9 +175,12 @@ layer_change_apply(struct LayerChange *change, Diagram *dia)
   diagram_add_update_all(dia);
 }
 
+
 static void
-layer_change_revert(struct LayerChange *change, Diagram *dia)
+dia_layer_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaLayerChange *change = DIA_LAYER_CHANGE (self);
+
   switch (change->type) {
   case TYPE_DELETE_LAYER:
     data_add_layer_at(dia->data, change->layer, change->index);
@@ -185,9 +201,12 @@ layer_change_revert(struct LayerChange *change, Diagram *dia)
   change->applied = 0;
 }
 
+
 static void
-layer_change_free (struct LayerChange *change)
+dia_layer_change_free (DiaChange *self)
 {
+  DiaLayerChange *change = DIA_LAYER_CHANGE (self);
+
   switch (change->type) {
     case TYPE_DELETE_LAYER:
       if (change->applied) {
@@ -206,30 +225,40 @@ layer_change_free (struct LayerChange *change)
   }
 }
 
-Change *
-undo_layer(Diagram *dia, DiaLayer *layer, enum LayerChangeType type, int index)
+DiaChange *
+dia_layer_change_new (Diagram *dia, DiaLayer *layer, enum LayerChangeType type, int index)
 {
-  struct LayerChange *change;
-
-  change = g_new0(struct LayerChange, 1);
-
-  change->change.apply = (UndoApplyFunc) layer_change_apply;
-  change->change.revert = (UndoRevertFunc) layer_change_revert;
-  change->change.free = (UndoFreeFunc) layer_change_free;
+  DiaLayerChange *change = dia_change_new (DIA_TYPE_LAYER_CHANGE);
 
   change->type = type;
   change->layer = layer;
   change->index = index;
   change->applied = 1;
 
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
+
+
+struct _DiaLayerVisibilityChange {
+  DiaChange change;
+
+  GList *original_visibility;
+  DiaLayer *layer;
+  gboolean is_exclusive;
+  int applied;
+};
+
+DIA_DEFINE_CHANGE (DiaLayerVisibilityChange, dia_layer_visibility_change)
+
+
 void
-layer_visibility_change_apply(struct LayerVisibilityChange *change,
-                             Diagram *dia)
+dia_layer_visibility_change_apply (DiaChange *self,
+                                   Diagram   *dia)
 {
+  DiaLayerVisibilityChange *change = DIA_LAYER_VISIBILITY_CHANGE (self);
   GPtrArray *layers;
   DiaLayer *layer = change->layer;
   int visible = FALSE;
@@ -261,12 +290,15 @@ layer_visibility_change_apply(struct LayerVisibilityChange *change,
   diagram_add_update_all (dia);
 }
 
-/** Revert to the visibility before this change was applied.
+
+/*
+ * Revert to the visibility before this change was applied.
  */
 static void
-layer_visibility_change_revert(struct LayerVisibilityChange *change,
-                              Diagram *dia)
+dia_layer_visibility_change_revert (DiaChange *self,
+                                    Diagram   *dia)
 {
+  DiaLayerVisibilityChange *change = DIA_LAYER_VISIBILITY_CHANGE (self);
   GList *vis = change->original_visibility;
   GPtrArray *layers = dia->data->layers;
   int i;
@@ -284,26 +316,24 @@ layer_visibility_change_revert(struct LayerVisibilityChange *change,
   diagram_add_update_all(dia);
 }
 
+
 static void
-layer_visibility_change_free(struct LayerVisibilityChange *change)
+dia_layer_visibility_change_free (DiaChange *self)
 {
-  g_list_free(change->original_visibility);
+  DiaLayerVisibilityChange *change = DIA_LAYER_VISIBILITY_CHANGE (self);
+
+  g_list_free (change->original_visibility);
 }
 
-struct LayerVisibilityChange *
-undo_layer_visibility(Diagram *dia, DiaLayer *layer, gboolean exclusive)
+
+DiaChange *
+dia_layer_visibility_change_new (Diagram *dia, DiaLayer *layer, gboolean exclusive)
 {
-  struct LayerVisibilityChange *change;
+  DiaLayerVisibilityChange *change = dia_change_new (DIA_TYPE_LAYER_VISIBILITY_CHANGE);
   GList *visibilities = NULL;
   int i;
   GPtrArray *layers = dia->data->layers;
 
-  change = g_new0(struct LayerVisibilityChange, 1);
-
-  change->change.apply = (UndoApplyFunc) layer_visibility_change_apply;
-  change->change.revert = (UndoRevertFunc) layer_visibility_change_revert;
-  change->change.free = (UndoFreeFunc) layer_visibility_change_free;
-
   for (i = 0; i < layers->len; i++) {
     DiaLayer *temp_layer = DIA_LAYER (g_ptr_array_index (layers, i));
     visibilities = g_list_append (visibilities, GINT_TO_POINTER (dia_layer_is_visible (temp_layer)));
@@ -313,8 +343,9 @@ undo_layer_visibility(Diagram *dia, DiaLayer *layer, gboolean exclusive)
   change->layer = layer;
   change->is_exclusive = exclusive;
 
-  undo_push_change(dia->undo, (Change *) change);
-  return change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
 /*!
diff --git a/app/layer-editor/layer_dialog.h b/app/layer-editor/layer_dialog.h
index 687acb20..a34369e3 100644
--- a/app/layer-editor/layer_dialog.h
+++ b/app/layer-editor/layer_dialog.h
@@ -30,33 +30,22 @@ enum LayerChangeType {
   TYPE_LOWER_LAYER,
 };
 
-struct LayerChange {
-  Change change;
+#define DIA_TYPE_LAYER_CHANGE dia_layer_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaLayerChange, dia_layer_change, DIA, LAYER_CHANGE, DiaChange)
 
-  enum LayerChangeType type;
-  DiaLayer *layer;
-  int index;
-  int applied;
-};
+DiaChange *dia_layer_change_new            (Diagram              *dia,
+                                            DiaLayer             *layer,
+                                            enum LayerChangeType  type,
+                                            int                   index);
 
-struct LayerVisibilityChange {
-  Change change;
 
-  GList *original_visibility;
-  DiaLayer *layer;
-  gboolean is_exclusive;
-  int applied;
-};
+#define DIA_TYPE_LAYER_VISIBILITY_CHANGE dia_layer_visibility_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaLayerVisibilityChange, dia_layer_visibility_change, DIA, LAYER_VISIBILITY_CHANGE, 
DiaChange)
+
+DiaChange *dia_layer_visibility_change_new (Diagram  *dia,
+                                            DiaLayer *layer,
+                                            gboolean  exclusive);
 
-Change                       *undo_layer                    (Diagram                      *dia,
-                                                             DiaLayer                     *layer,
-                                                             enum LayerChangeType         ,
-                                                             int                           index);
-struct LayerVisibilityChange *undo_layer_visibility         (Diagram                      *dia,
-                                                             DiaLayer                     *layer,
-                                                             gboolean                      exclusive);
-void                          layer_visibility_change_apply (struct LayerVisibilityChange *change,
-                                                             Diagram                      *dia);
 
 void layer_dialog_create      (void);
 void layer_dialog_show        (void);
diff --git a/app/menus.c b/app/menus.c
index f9b91df4..bfe82028 100644
--- a/app/menus.c
+++ b/app/menus.c
@@ -1236,7 +1236,7 @@ plugin_callback (GtkWidget *widget, gpointer data)
     change = cbf->callback (diadata, ddisp ? ddisp->diagram->filename : NULL, 0, cbf->user_data);
     if (change != NULL) {
       if (ddisp) {
-        undo_object_change(ddisp->diagram, NULL, change);
+        dia_object_change_change_new (ddisp->diagram, NULL, change);
        /*
         * - can not call object_add_update() w/o object
         * - could call object_add_updates_list() with the selected objects,
diff --git a/app/modify_tool.c b/app/modify_tool.c
index eacf1c34..bdadf74d 100644
--- a/app/modify_tool.c
+++ b/app/modify_tool.c
@@ -508,7 +508,7 @@ modify_motion (ModifyTool     *tool,
     object_add_updates_list(ddisp->diagram->data->selected, ddisp->diagram);
     objchange = object_list_move_delta(ddisp->diagram->data->selected, &delta);
     if (objchange != NULL) {
-      undo_object_change(ddisp->diagram, tool->object, objchange);
+      dia_object_change_change_new (ddisp->diagram, tool->object, objchange);
     }
     object_add_updates_list(ddisp->diagram->data->selected, ddisp->diagram);
 
@@ -576,11 +576,11 @@ modify_motion (ModifyTool     *tool,
     if (tool->break_connections) {
       /* break connections to the handle currently selected. */
       if (tool->handle->connected_to!=NULL) {
-        Change *change = undo_unconnect (ddisp->diagram,
-                                         tool->object,
-                                         tool->handle);
+        DiaChange *change = dia_unconnect_change_new (ddisp->diagram,
+                                                      tool->object,
+                                                      tool->handle);
 
-        (change->apply)(change, ddisp->diagram);
+        dia_change_apply (change, ddisp->diagram);
       }
     }
 
@@ -626,7 +626,7 @@ modify_motion (ModifyTool     *tool,
                                                 &to, connectionpoint,
                                                 HANDLE_MOVE_USER, 
gdk_event_to_dia_ModifierKeys(event->state));
     if (objchange != NULL) {
-      undo_object_change(ddisp->diagram, tool->object, objchange);
+      dia_object_change_change_new (ddisp->diagram, tool->object, objchange);
     }
     object_add_updates(tool->object, ddisp->diagram);
 
@@ -728,8 +728,8 @@ modify_button_release(ModifyTool *tool, GdkEventButton *event,
        list = g_list_next(list); i++;
       }
 
-      undo_move_objects(ddisp->diagram, tool->orig_pos, dest_pos,
-                       parent_list_affected(ddisp->diagram->data->selected));
+      dia_move_objects_change_new (ddisp->diagram, tool->orig_pos, dest_pos,
+                                   parent_list_affected (ddisp->diagram->data->selected));
     }
 
     ddisplay_connect_selected(ddisp); /* pushes UNDO info */
@@ -747,8 +747,9 @@ modify_button_release(ModifyTool *tool, GdkEventButton *event,
     tool->state = STATE_NONE;
 
     if (tool->orig_pos != NULL) {
-      undo_move_handle(ddisp->diagram, tool->handle, tool->object,
-                      *tool->orig_pos, tool->last_to, gdk_event_to_dia_ModifierKeys(event->state));
+      dia_move_handle_change_new (ddisp->diagram, tool->handle, tool->object,
+                                  *tool->orig_pos, tool->last_to,
+                                  gdk_event_to_dia_ModifierKeys (event->state));
     }
 
     /* Final move: */
@@ -757,7 +758,7 @@ modify_button_release(ModifyTool *tool, GdkEventButton *event,
                                               &tool->last_to, NULL,
                                               
HANDLE_MOVE_USER_FINAL,gdk_event_to_dia_ModifierKeys(event->state));
     if (objchange != NULL) {
-      undo_object_change(ddisp->diagram, tool->object, objchange);
+      dia_object_change_change_new (ddisp->diagram, tool->object, objchange);
     }
 
     object_add_updates(tool->object, ddisp->diagram);
diff --git a/app/object_ops.c b/app/object_ops.c
index f6c203e5..21812416 100644
--- a/app/object_ops.c
+++ b/app/object_ops.c
@@ -130,9 +130,11 @@ object_connect_display(DDisplay *ddisp, DiaObject *obj, Handle *handle,
                                                       obj, snap_to_objects);
 
     if (connectionpoint != NULL) {
-      Change *change = undo_connect(ddisp->diagram, obj, handle,
-                                   connectionpoint);
-      (change->apply)(change, ddisp->diagram);
+      DiaChange *change = dia_connect_change_new (ddisp->diagram,
+                                                  obj,
+                                                  handle,
+                                                  connectionpoint);
+      dia_change_apply (change, ddisp->diagram);
     }
   }
 }
@@ -362,7 +364,7 @@ object_list_align_v(GList *objects, Diagram *dia, int align)
     list = g_list_next(list);
   }
 
-  undo_move_objects(dia, orig_pos, dest_pos, g_list_copy(objects));
+  dia_move_objects_change_new (dia, orig_pos, dest_pos, g_list_copy (objects));
   g_list_free (unconnected);
 }
 
@@ -519,7 +521,7 @@ object_list_align_h(GList *objects, Diagram *dia, int align)
     list = g_list_next(list);
   }
 
-  undo_move_objects(dia, orig_pos, dest_pos, g_list_copy(objects));
+  dia_move_objects_change_new (dia, orig_pos, dest_pos, g_list_copy (objects));
   g_list_free (unconnected);
 }
 
@@ -658,7 +660,7 @@ object_list_align_connected (GList *objects, Diagram *dia, int align)
   }
 
   /* eating all the passed in parameters */
-  undo_move_objects (dia, orig_pos, dest_pos, movelist);
+  dia_move_objects_change_new (dia, orig_pos, dest_pos, movelist);
   g_list_free (to_be_moved);
   g_list_free (connected);
 }
@@ -710,5 +712,5 @@ object_list_nudge(GList *objects, Diagram *dia, Direction dir, real step)
   }
   /* if anything is connected not anymore */
   diagram_unconnect_selected(dia);
-  undo_move_objects(dia, orig_pos, dest_pos, g_list_copy(objects));
+  dia_move_objects_change_new (dia, orig_pos, dest_pos, g_list_copy(objects));
 }
diff --git a/app/pagesetup.c b/app/pagesetup.c
index 8b76f424..a76ebaf7 100644
--- a/app/pagesetup.c
+++ b/app/pagesetup.c
@@ -167,7 +167,7 @@ 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));
+  dia_mem_swap_change_new (ps->dia, &ps->dia->data->paper, sizeof(ps->dia->data->paper));
   undo_set_transactionpoint(ps->dia->undo);
 
   g_free(ps->dia->data->paper.name);
diff --git a/app/properties-dialog.c b/app/properties-dialog.c
index d9a0fd8e..09736c7e 100644
--- a/app/properties-dialog.c
+++ b/app/properties-dialog.c
@@ -131,18 +131,19 @@ properties_respond(GtkWidget *widget,
       object_add_updates_list(current_objects, current_dia);
 
       for (tmp = current_objects; tmp != NULL; tmp = tmp->next) {
-       DiaObject *current_obj = (DiaObject*)tmp->data;
-       obj_change = current_obj->ops->apply_properties_from_dialog(current_obj, object_part);
-       object_add_updates(current_obj, current_dia);
-       diagram_update_connections_object(current_dia, current_obj, TRUE);
-
-       if (obj_change != NULL) {
-         undo_object_change(current_dia, current_obj, obj_change);
-         set_tp = set_tp && TRUE;
-       } else
-         set_tp = FALSE;
-
-       diagram_object_modified(current_dia, current_obj);
+        DiaObject *current_obj = (DiaObject*)tmp->data;
+        obj_change = current_obj->ops->apply_properties_from_dialog(current_obj, object_part);
+        object_add_updates(current_obj, current_dia);
+        diagram_update_connections_object(current_dia, current_obj, TRUE);
+
+        if (obj_change != NULL) {
+          dia_object_change_change_new (current_dia, current_obj, obj_change);
+          set_tp = set_tp && TRUE;
+        } else {
+          set_tp = FALSE;
+        }
+
+        diagram_object_modified(current_dia, current_obj);
       }
 
       diagram_modified(current_dia);
diff --git a/app/textedit.c b/app/textedit.c
index 6bd282f5..171ec1c6 100644
--- a/app/textedit.c
+++ b/app/textedit.c
@@ -42,18 +42,6 @@
 #include "object_ops.h"
 #include "text.h"
 
-typedef struct TextEditChange {
-  Change obj_change;
-
-  /** The text before editing began */
-  gchar *orig_text;
-  /** The text after editing finished */
-  gchar *new_text;
-  /** The Text item that this change happened to (in case there's more than
-   *  one on an object). */
-  Text *text;
-} TextEditChange;
-
 static void textedit_end_edit(DDisplay *ddisp, Focus *focus);
 
 /** Returns TRUE if the given display is currently in text-edit mode. */
@@ -116,7 +104,7 @@ textedit_exit(DDisplay *ddisp)
  * textedit_enter if necessary.  By return from this function, we will
  * be in textedit mode.
  * @param ddisp The display in use
- * @param focus The text focus to edit 
+ * @param focus The text focus to edit
  */
 static void
 textedit_begin_edit(DDisplay *ddisp, Focus *focus)
@@ -137,7 +125,7 @@ textedit_begin_edit(DDisplay *ddisp, Focus *focus)
  * @param focus The text focus to stop editing
  */
 static void
-textedit_end_edit(DDisplay *ddisp, Focus *focus) 
+textedit_end_edit(DDisplay *ddisp, Focus *focus)
 {
   /* During destruction of the diagram the display may already be gone */
   if (!ddisp)
@@ -164,10 +152,10 @@ textedit_move_focus(DDisplay *ddisp, Focus *focus, gboolean forwards)
   }
   if (forwards) {
     Focus *new_focus = focus_next_on_diagram((DiagramData *) ddisp->diagram);
-    if (new_focus != NULL) give_focus(new_focus);    
+    if (new_focus != NULL) give_focus(new_focus);
   } else {
     Focus *new_focus = focus_previous_on_diagram((DiagramData *) ddisp->diagram);
-    if (new_focus != NULL) give_focus(new_focus);    
+    if (new_focus != NULL) give_focus(new_focus);
   }
   focus = get_active_focus((DiagramData *) ddisp->diagram);
 
@@ -213,7 +201,7 @@ textedit_activate_object(DDisplay *ddisp, DiaObject *obj, Point *clicked)
     if (focus != NULL) {
       textedit_end_edit(ddisp, focus);
     }
-    give_focus(new_focus); 
+    give_focus(new_focus);
     if (clicked) {
       text_set_cursor(new_focus->text, clicked, ddisp->renderer);
     }
@@ -249,7 +237,7 @@ textedit_activate_first(DDisplay *ddisp)
   }
   g_list_free (selected);
   if (new_focus != NULL) {
-    give_focus(new_focus); 
+    give_focus(new_focus);
     textedit_begin_edit(ddisp, new_focus);
     diagram_flush(ddisp->diagram);
     return TRUE;
@@ -312,14 +300,3 @@ textedit_remove_focus_all(Diagram *diagram)
     textedit_exit(ddisplay_active());
   }
 }
-
-/* *************** Textedit-mode related Undo ******************* */
-
-/* Each edit of a text part of an object counts as one undo after it's
- * done.  While editing, full undo is available, but afterwards the
- * changes get merged into one.  This is done by sticking a TextEditChange
- * on the undo stack at the beginning with the original text, and then
- * at the end removing every change after that one.  This is why non-text-edit
- * changes are not allowed in text edit mode:  It would break the undo.
- */
-
diff --git a/app/undo.c b/app/undo.c
index 0767c8e8..aceeb96c 100644
--- a/app/undo.c
+++ b/app/undo.c
@@ -37,42 +37,53 @@
 
 void undo_update_menus(UndoStack *stack);
 
+/**
+ * DiaTransactionPointChange:
+ *
+ * Fake #DiaChange used as a marker
+ */
+struct _DiaTransactionPointChange {
+  DiaChange change;
+};
+
+DIA_DEFINE_CHANGE (DiaTransactionPointChange, dia_transaction_point_change)
+
+
 static void
-transaction_point_pointer(Change *change, Diagram *dia)
+dia_transaction_point_change_apply (DiaChange *self, Diagram *dia)
 {
-  /* Empty function used to track transactionpoints. */
 }
 
-static int
-is_transactionpoint(Change *change)
+
+static void
+dia_transaction_point_change_revert (DiaChange *self, Diagram *dia)
 {
-  return change->apply == transaction_point_pointer;
 }
 
-static Change *
-new_transactionpoint(void)
+
+static void
+dia_transaction_point_change_free (DiaChange *self)
 {
-  Change *transaction = g_new0(Change, 1);
+}
 
-  if (transaction) {
-    transaction->apply = transaction_point_pointer;
-    transaction->revert = transaction_point_pointer;
-    transaction->free = NULL;
-  }
 
-  return transaction;
+static DiaChange *
+dia_transaction_point_change_new (void)
+{
+  return dia_change_new (DIA_TYPE_TRANSACTION_POINT_CHANGE);
 }
 
+
 UndoStack *
 new_undo_stack(Diagram *dia)
 {
   UndoStack *stack;
-  Change *transaction;
+  DiaChange *transaction;
 
   stack = g_new(UndoStack, 1);
   if (stack!=NULL){
     stack->dia = dia;
-    transaction = new_transactionpoint();
+    transaction = dia_transaction_point_change_new ();
     transaction->next = transaction->prev = NULL;
     stack->last_change = transaction;
     stack->current_change = transaction;
@@ -93,8 +104,8 @@ undo_destroy(UndoStack *stack)
 static void
 undo_remove_redo_info(UndoStack *stack)
 {
-  Change *change;
-  Change *next_change;
+  DiaChange *change;
+  DiaChange *next_change;
 
   DEBUG_PRINTF(("UNDO: Removing redo info\n"));
 
@@ -104,16 +115,14 @@ undo_remove_redo_info(UndoStack *stack)
 
   while (change != NULL) {
     next_change = change->next;
-    if (change->free)
-      (change->free)(change);
-    g_free(change);
+    dia_change_unref (change);
     change = next_change;
   }
   undo_update_menus(stack);
 }
 
 void
-undo_push_change(UndoStack *stack, Change *change)
+undo_push_change(UndoStack *stack, DiaChange *change)
 {
   if (stack->current_change != stack->last_change)
     undo_remove_redo_info(stack);
@@ -131,8 +140,8 @@ undo_push_change(UndoStack *stack, Change *change)
 static void
 undo_delete_lowest_transaction(UndoStack *stack)
 {
-  Change *change;
-  Change *next_change;
+  DiaChange *change;
+  DiaChange *next_change;
 
   /* Find the lowest change: */
   change = stack->current_change;
@@ -150,13 +159,11 @@ undo_delete_lowest_transaction(UndoStack *stack)
 
     next_change = change->next;
     DEBUG_PRINTF(("freeing one change from the bottom.\n"));
-    if (change->free)
-      (change->free)(change);
-    g_free(change);
+    dia_change_unref (change);
     change = next_change;
-  } while (!is_transactionpoint(change));
+  } while (!DIA_IS_TRANSACTION_POINT_CHANGE (change));
 
-  if (is_transactionpoint(change)) {
+  if (DIA_IS_TRANSACTION_POINT_CHANGE (change)) {
     stack->depth--;
     DEBUG_PRINTF(("Decreasing stack depth to: %d\n", stack->depth));
   }
@@ -167,14 +174,14 @@ undo_delete_lowest_transaction(UndoStack *stack)
 void
 undo_set_transactionpoint(UndoStack *stack)
 {
-  Change *transaction;
+  DiaChange *transaction;
 
-  if (is_transactionpoint(stack->current_change))
+  if (DIA_IS_TRANSACTION_POINT_CHANGE(stack->current_change))
     return;
 
   DEBUG_PRINTF(("UNDO: Push new transactionpoint at %d\n", stack->depth));
 
-  transaction = new_transactionpoint();
+  transaction = dia_transaction_point_change_new ();
 
   undo_push_change(stack, transaction);
   stack->depth++;
@@ -190,8 +197,8 @@ undo_set_transactionpoint(UndoStack *stack)
 void
 undo_revert_to_last_tp(UndoStack *stack)
 {
-  Change *change;
-  Change *prev_change;
+  DiaChange *change;
+  DiaChange *prev_change;
 
   if (stack->current_change->prev == NULL)
     return; /* Can't revert first transactionpoint */
@@ -199,9 +206,9 @@ undo_revert_to_last_tp(UndoStack *stack)
   change = stack->current_change;
   do {
     prev_change = change->prev;
-    (change->revert)(change, stack->dia);
+    dia_change_revert (change, stack->dia);
     change = prev_change;
-  } while (!is_transactionpoint(change));
+  } while (!DIA_IS_TRANSACTION_POINT_CHANGE(change));
   stack->current_change  = change;
   stack->depth--;
   undo_update_menus(stack);
@@ -211,8 +218,8 @@ undo_revert_to_last_tp(UndoStack *stack)
 void
 undo_apply_to_next_tp(UndoStack *stack)
 {
-  Change *change;
-  Change *next_change;
+  DiaChange *change;
+  DiaChange *next_change;
 
   change = stack->current_change;
 
@@ -221,10 +228,10 @@ undo_apply_to_next_tp(UndoStack *stack)
 
   do {
     next_change = change->next;
-    (change->apply)(change, stack->dia);
+    dia_change_apply (change, stack->dia);
     change = next_change;
   } while ( (change != NULL) &&
-           (!is_transactionpoint(change)) );
+           (!DIA_IS_TRANSACTION_POINT_CHANGE(change)) );
   if (change == NULL)
     change = stack->last_change;
   stack->current_change = change;
@@ -237,7 +244,7 @@ undo_apply_to_next_tp(UndoStack *stack)
 void
 undo_clear(UndoStack *stack)
 {
-  Change *change;
+  DiaChange *change;
 
   DEBUG_PRINTF(("undo_clear()\n"));
 
@@ -294,25 +301,31 @@ undo_available(UndoStack *stack, gboolean undo)
   }
 }
 
-/** Remove items from the undo stack until we hit an undo item of a given
+/**
+ * undo_remove_to:
+ * @stack: The undo stack to remove items from.
+ * @type: Indicator of undo type to remove: An apply function.
+ *
+ * Remove items from the undo stack until we hit an undo item of a given
  *  type (indicated by its apply function).  Beware that the items are not
  *  just reverted, but totally removed.  This also takes with it all the
  *  changes above current_change.
  *
- * @param stack The undo stack to remove items from.
- * @param type Indicator of undo type to remove: An apply function.
- * @returns The Change object that stopped the search, if any was found,
- * or NULL otherwise.  In the latter case, the undo stack will be empty.
+ * Returns: The #DiaChange object that stopped the search, if any was found,
+ * or %NULL otherwise.  In the latter case, the undo stack will be empty.
  */
-Change*
-undo_remove_to(UndoStack *stack, UndoApplyFunc *type)
+DiaChange *
+undo_remove_to(UndoStack *stack, GType type)
 {
-  Change *current_change = stack->current_change;
+  DiaChange *current_change = stack->current_change;
   if (current_change == NULL)
     return NULL;
-  while (current_change && current_change->apply != *type) {
+
+  while (current_change &&
+         !g_type_is_a (DIA_CHANGE_TYPE (current_change), type)) {
     current_change = current_change->prev;
   }
+
   if (current_change != NULL) {
     stack->current_change = current_change;
     undo_remove_redo_info(stack);
@@ -334,17 +347,21 @@ undo_remove_to(UndoStack *stack, UndoApplyFunc *type)
 
 /******** Move object list: */
 
-struct MoveObjectsChange {
-  Change change;
+struct _DiaMoveObjectsChange {
+  DiaChange change;
 
   Point *orig_pos;
   Point *dest_pos;
   GList *obj_list;
 };
 
+DIA_DEFINE_CHANGE (DiaMoveObjectsChange, dia_move_objects_change)
+
+
 static void
-move_objects_apply(struct MoveObjectsChange *change, Diagram *dia)
+dia_move_objects_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaMoveObjectsChange *change = DIA_MOVE_OBJECTS_CHANGE (self);
   GList *list;
   int i;
   DiaObject *obj;
@@ -356,7 +373,7 @@ move_objects_apply(struct MoveObjectsChange *change, Diagram *dia)
   while (list != NULL) {
     obj = (DiaObject *)  list->data;
 
-    obj->ops->move(obj, &change->dest_pos[i]);
+    dia_object_move (obj, &change->dest_pos[i]);
 
     list = g_list_next(list); i++;
   }
@@ -373,9 +390,11 @@ move_objects_apply(struct MoveObjectsChange *change, Diagram *dia)
   object_add_updates_list(change->obj_list, dia);
 }
 
+
 static void
-move_objects_revert(struct MoveObjectsChange *change, Diagram *dia)
+dia_move_objects_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaMoveObjectsChange *change = DIA_MOVE_OBJECTS_CHANGE (self);
   GList *list;
   int i;
   DiaObject *obj;
@@ -387,7 +406,7 @@ move_objects_revert(struct MoveObjectsChange *change, Diagram *dia)
   while (list != NULL) {
     obj = (DiaObject *)  list->data;
 
-    obj->ops->move(obj, &change->orig_pos[i]);
+    dia_object_move(obj, &change->orig_pos[i]);
 
     list = g_list_next(list); i++;
   }
@@ -404,39 +423,42 @@ move_objects_revert(struct MoveObjectsChange *change, Diagram *dia)
   object_add_updates_list(change->obj_list, dia);
 }
 
+
 static void
-move_objects_free(struct MoveObjectsChange *change)
+dia_move_objects_change_free (DiaChange *self)
 {
+  DiaMoveObjectsChange *change = DIA_MOVE_OBJECTS_CHANGE (self);
+
   g_free(change->orig_pos);
   g_free(change->dest_pos);
   g_list_free(change->obj_list);
 }
 
-extern Change *
-undo_move_objects(Diagram *dia, Point *orig_pos, Point *dest_pos,
-                 GList *obj_list)
-{
-  struct MoveObjectsChange *change;
-
-  change = g_new0(struct MoveObjectsChange, 1);
 
-  change->change.apply = (UndoApplyFunc) move_objects_apply;
-  change->change.revert = (UndoRevertFunc) move_objects_revert;
-  change->change.free = (UndoFreeFunc) move_objects_free;
+DiaChange *
+dia_move_objects_change_new (Diagram *dia,
+                             Point   *orig_pos,
+                             Point   *dest_pos,
+                             GList   *obj_list)
+{
+  DiaMoveObjectsChange *change = dia_change_new (DIA_TYPE_MOVE_OBJECTS_CHANGE);
 
   change->orig_pos = orig_pos;
   change->dest_pos = dest_pos;
   change->obj_list = obj_list;
 
   DEBUG_PRINTF(("UNDO: Push new move objects at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
+
+
 /********** Move handle: */
 
-struct MoveHandleChange {
-  Change change;
+struct _DiaMoveHandleChange {
+  DiaChange change;
 
   Point orig_pos;
   Point dest_pos;
@@ -446,11 +468,17 @@ struct MoveHandleChange {
   int modifiers;
 };
 
+DIA_DEFINE_CHANGE (DiaMoveHandleChange, dia_move_handle_change)
+
+
 static void
-move_handle_apply(struct MoveHandleChange *change, Diagram *dia)
+dia_move_handle_change_apply (DiaChange *self, Diagram *dia)
 {
-  object_add_updates(change->obj, dia);
-  change->obj->ops->move_handle(change->obj, change->handle,
+  DiaMoveHandleChange *change = DIA_MOVE_HANDLE_CHANGE (self);
+
+  object_add_updates (change->obj, dia);
+  dia_object_move_handle (change->obj,
+                          change->handle,
                                &change->dest_pos, NULL,
                                HANDLE_MOVE_USER_FINAL, change->modifiers);
   object_add_updates(change->obj, dia);
@@ -458,10 +486,13 @@ move_handle_apply(struct MoveHandleChange *change, Diagram *dia)
 }
 
 static void
-move_handle_revert(struct MoveHandleChange *change, Diagram *dia)
+dia_move_handle_change_revert (DiaChange *self, Diagram *dia)
 {
-  object_add_updates(change->obj, dia);
-  change->obj->ops->move_handle(change->obj, change->handle,
+  DiaMoveHandleChange *change = DIA_MOVE_HANDLE_CHANGE (self);
+
+  object_add_updates (change->obj, dia);
+  dia_object_move_handle (change->obj,
+                          change->handle,
                                &change->orig_pos, NULL,
                                HANDLE_MOVE_USER_FINAL, change->modifiers);
   object_add_updates(change->obj, dia);
@@ -469,24 +500,20 @@ move_handle_revert(struct MoveHandleChange *change, Diagram *dia)
 }
 
 static void
-move_handle_free(struct MoveHandleChange *change)
+dia_move_handle_change_free (DiaChange *self)
 {
 }
 
 
-Change *
-undo_move_handle(Diagram *dia,
-                Handle *handle, DiaObject *obj,
-                Point orig_pos, Point dest_pos,
-                int modifiers)
+DiaChange *
+dia_move_handle_change_new (Diagram   *dia,
+                            Handle    *handle,
+                            DiaObject *obj,
+                            Point      orig_pos,
+                            Point      dest_pos,
+                            int        modifiers)
 {
-  struct MoveHandleChange *change;
-
-  change = g_new0(struct MoveHandleChange, 1);
-
-  change->change.apply = (UndoApplyFunc) move_handle_apply;
-  change->change.revert = (UndoRevertFunc) move_handle_revert;
-  change->change.free = (UndoFreeFunc) move_handle_free;
+  DiaMoveHandleChange *change = dia_change_new (DIA_TYPE_MOVE_HANDLE_CHANGE);
 
   change->orig_pos = orig_pos;
   change->dest_pos = dest_pos;
@@ -497,14 +524,15 @@ undo_move_handle(Diagram *dia,
 
   DEBUG_PRINTF(("UNDO: Push new move handle at %d\n", depth(dia->undo)));
 
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
 /***************** Connect object: */
 
-struct ConnectChange {
-  Change change;
+struct _DiaConnectChange {
+  DiaChange change;
 
   DiaObject *obj;
   Handle *handle;
@@ -512,13 +540,19 @@ struct ConnectChange {
   Point handle_pos;
 };
 
+DIA_DEFINE_CHANGE (DiaConnectChange, dia_connect_change)
+
+
 static void
-connect_apply(struct ConnectChange *change, Diagram *dia)
+dia_connect_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaConnectChange *change = DIA_CONNECT_CHANGE (self);
+
   object_connect(change->obj, change->handle, change->connectionpoint);
 
-  object_add_updates(change->obj, dia);
-  change->obj->ops->move_handle(change->obj, change->handle ,
+  object_add_updates (change->obj, dia);
+  dia_object_move_handle (change->obj,
+                          change->handle,
                                &change->connectionpoint->pos,
                                change->connectionpoint,
                                HANDLE_MOVE_CONNECTED, 0);
@@ -526,35 +560,37 @@ connect_apply(struct ConnectChange *change, Diagram *dia)
   object_add_updates(change->obj, dia);
 }
 
+
 static void
-connect_revert(struct ConnectChange *change, Diagram *dia)
+dia_connect_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaConnectChange *change = DIA_CONNECT_CHANGE (self);
+
   object_unconnect(change->obj, change->handle);
 
-  object_add_updates(change->obj, dia);
-  change->obj->ops->move_handle(change->obj, change->handle ,
+  object_add_updates (change->obj, dia);
+  dia_object_move_handle (change->obj,
+                          change->handle,
                                &change->handle_pos, NULL,
                                HANDLE_MOVE_CONNECTED, 0);
 
   object_add_updates(change->obj, dia);
 }
 
+
 static void
-connect_free(struct ConnectChange *change)
+dia_connect_change_free (DiaChange *self)
 {
 }
 
-extern Change *
-undo_connect(Diagram *dia, DiaObject *obj, Handle *handle,
-            ConnectionPoint *connectionpoint)
-{
-  struct ConnectChange *change;
 
-  change = g_new0(struct ConnectChange, 1);
-
-  change->change.apply = (UndoApplyFunc) connect_apply;
-  change->change.revert = (UndoRevertFunc) connect_revert;
-  change->change.free = (UndoFreeFunc) connect_free;
+DiaChange *
+dia_connect_change_new (Diagram         *dia,
+                        DiaObject       *obj,
+                        Handle          *handle,
+                        ConnectionPoint *connectionpoint)
+{
+  DiaConnectChange *change = dia_change_new (DIA_TYPE_CONNECT_CHANGE);
 
   change->obj = obj;
   change->handle = handle;
@@ -562,66 +598,75 @@ undo_connect(Diagram *dia, DiaObject *obj, Handle *handle,
   change->connectionpoint = connectionpoint;
 
   DEBUG_PRINTF(("UNDO: Push new connect at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
+
+
 /*************** Unconnect object: */
 
-struct UnconnectChange {
-  Change change;
+struct _DiaUnconnectChange {
+  DiaChange change;
 
   DiaObject *obj;
   Handle *handle;
   ConnectionPoint *connectionpoint;
 };
 
+DIA_DEFINE_CHANGE (DiaUnconnectChange, dia_unconnect_change)
+
+
 static void
-unconnect_apply(struct UnconnectChange *change, Diagram *dia)
+dia_unconnect_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaUnconnectChange *change = DIA_UNCONNECT_CHANGE (self);
+
   object_unconnect(change->obj, change->handle);
 
   object_add_updates(change->obj, dia);
 }
 
+
 static void
-unconnect_revert(struct UnconnectChange *change, Diagram *dia)
+dia_unconnect_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaUnconnectChange *change = DIA_UNCONNECT_CHANGE (self);
+
   object_connect(change->obj, change->handle, change->connectionpoint);
 
   object_add_updates(change->obj, dia);
 }
 
+
 static void
-unconnect_free(struct UnconnectChange *change)
+dia_unconnect_change_free (DiaChange *self)
 {
 }
 
-extern Change *
-undo_unconnect(Diagram *dia, DiaObject *obj, Handle *handle)
-{
-  struct UnconnectChange *change;
-
-  change = g_new0(struct UnconnectChange, 1);
 
-  change->change.apply = (UndoApplyFunc) unconnect_apply;
-  change->change.revert = (UndoRevertFunc) unconnect_revert;
-  change->change.free = (UndoFreeFunc) unconnect_free;
+DiaChange *
+dia_unconnect_change_new (Diagram *dia, DiaObject *obj, Handle *handle)
+{
+  DiaUnconnectChange *change = dia_change_new (DIA_TYPE_UNCONNECT_CHANGE);
 
   change->obj = obj;
   change->handle = handle;
   change->connectionpoint = handle->connected_to;
 
   DEBUG_PRINTF(("UNDO: Push new unconnect at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
 
+
 /******** Delete object list: */
 
-struct DeleteObjectsChange {
-  Change change;
+struct _DiaDeleteObjectsChange {
+  DiaChange change;
 
   DiaLayer *layer;
   GList *obj_list; /* Owning reference when applied */
@@ -629,9 +674,13 @@ struct DeleteObjectsChange {
   int applied;
 };
 
+DIA_DEFINE_CHANGE (DiaDeleteObjectsChange, dia_delete_objects_change)
+
+
 static void
-delete_objects_apply(struct DeleteObjectsChange *change, Diagram *dia)
+dia_delete_objects_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaDeleteObjectsChange *change = DIA_DELETE_OBJECTS_CHANGE (self);
   GList *list;
 
   DEBUG_PRINTF(("delete_objects_apply()\n"));
@@ -656,9 +705,11 @@ delete_objects_apply(struct DeleteObjectsChange *change, Diagram *dia)
 }
 
 static void
-delete_objects_revert(struct DeleteObjectsChange *change, Diagram *dia)
+dia_delete_objects_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaDeleteObjectsChange *change = DIA_DELETE_OBJECTS_CHANGE (self);
   GList *list;
+
   DEBUG_PRINTF(("delete_objects_revert()\n"));
   change->applied = 0;
   dia_layer_set_object_list (change->layer,
@@ -675,9 +726,12 @@ delete_objects_revert(struct DeleteObjectsChange *change, Diagram *dia)
   }
 }
 
+
 static void
-delete_objects_free(struct DeleteObjectsChange *change)
+dia_delete_objects_change_free (DiaChange *self)
 {
+  DiaDeleteObjectsChange *change = DIA_DELETE_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF(("delete_objects_free()\n"));
   if (change->applied)
     destroy_object_list(change->obj_list);
@@ -686,27 +740,23 @@ delete_objects_free(struct DeleteObjectsChange *change)
   g_list_free(change->original_objects);
 }
 
+
 /*
   This function deletes specified objects along with any children
   they might have.
   undo_delete_objects() only deletes the objects that are specified.
 */
-Change *
-undo_delete_objects_children(Diagram *dia, GList *obj_list)
+DiaChange *
+dia_delete_objects_change_new_with_children (Diagram *dia, GList *obj_list)
 {
-  return undo_delete_objects(dia, parent_list_affected(obj_list));
+  return dia_delete_objects_change_new (dia, parent_list_affected (obj_list));
 }
 
-Change *
-undo_delete_objects(Diagram *dia, GList *obj_list)
-{
-  struct DeleteObjectsChange *change;
 
-  change = g_new0(struct DeleteObjectsChange, 1);
-
-  change->change.apply = (UndoApplyFunc) delete_objects_apply;
-  change->change.revert = (UndoRevertFunc) delete_objects_revert;
-  change->change.free = (UndoFreeFunc) delete_objects_free;
+DiaChange *
+dia_delete_objects_change_new (Diagram *dia, GList *obj_list)
+{
+  DiaDeleteObjectsChange *change = dia_change_new (DIA_TYPE_DELETE_OBJECTS_CHANGE);
 
   change->layer = dia->data->active_layer;
   change->obj_list = obj_list;
@@ -714,23 +764,31 @@ undo_delete_objects(Diagram *dia, GList *obj_list)
   change->applied = 0;
 
   DEBUG_PRINTF(("UNDO: Push new delete objects at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
+
+
 /******** Insert object list: */
 
-struct InsertObjectsChange {
-  Change change;
+struct _DiaInsertObjectsChange {
+  DiaChange change;
 
   DiaLayer *layer;
   GList *obj_list; /* Owning reference when not applied */
   int applied;
 };
 
+DIA_DEFINE_CHANGE (DiaInsertObjectsChange, dia_insert_objects_change)
+
+
 static void
-insert_objects_apply (struct InsertObjectsChange *change, Diagram *dia)
+dia_insert_objects_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaInsertObjectsChange *change = DIA_INSERT_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF (("insert_objects_apply()\n"));
   change->applied = 1;
   dia_layer_add_objects (change->layer, g_list_copy (change->obj_list));
@@ -738,8 +796,9 @@ insert_objects_apply (struct InsertObjectsChange *change, Diagram *dia)
 }
 
 static void
-insert_objects_revert(struct InsertObjectsChange *change, Diagram *dia)
+dia_insert_objects_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaInsertObjectsChange *change = DIA_INSERT_OBJECTS_CHANGE (self);
   GList *list;
 
   DEBUG_PRINTF(("insert_objects_revert()\n"));
@@ -761,8 +820,10 @@ insert_objects_revert(struct InsertObjectsChange *change, Diagram *dia)
 }
 
 static void
-insert_objects_free(struct InsertObjectsChange *change)
+dia_insert_objects_change_free (DiaChange *self)
 {
+  DiaInsertObjectsChange *change = DIA_INSERT_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF(("insert_objects_free()\n"));
   if (!change->applied)
     destroy_object_list(change->obj_list);
@@ -770,30 +831,28 @@ insert_objects_free(struct InsertObjectsChange *change)
     g_list_free(change->obj_list);
 }
 
-Change *
-undo_insert_objects(Diagram *dia, GList *obj_list, int applied)
-{
-  struct InsertObjectsChange *change;
-
-  change = g_new0(struct InsertObjectsChange, 1);
 
-  change->change.apply = (UndoApplyFunc) insert_objects_apply;
-  change->change.revert = (UndoRevertFunc) insert_objects_revert;
-  change->change.free = (UndoFreeFunc) insert_objects_free;
+DiaChange *
+dia_insert_objects_change_new (Diagram *dia, GList *obj_list, int applied)
+{
+  DiaInsertObjectsChange *change = dia_change_new (DIA_TYPE_INSERT_OBJECTS_CHANGE);
 
   change->layer = dia->data->active_layer;
   change->obj_list = obj_list;
   change->applied = applied;
 
   DEBUG_PRINTF(("UNDO: Push new insert objects at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
+
+
 /******** Reorder object list: */
 
-struct ReorderObjectsChange {
-  Change change;
+struct _DiaReorderObjectsChange {
+  DiaChange parent;
 
   DiaLayer *layer;
   GList *changed_list; /* Owning reference when applied */
@@ -801,43 +860,49 @@ struct ReorderObjectsChange {
   GList *reordered_objects;
 };
 
+DIA_DEFINE_CHANGE (DiaReorderObjectsChange, dia_reorder_objects_change)
+
+
 static void
-reorder_objects_apply(struct ReorderObjectsChange *change, Diagram *dia)
+dia_reorder_objects_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaReorderObjectsChange *change = DIA_REORDER_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF (("reorder_objects_apply()\n"));
   dia_layer_set_object_list (change->layer,
                              g_list_copy (change->reordered_objects));
   object_add_updates_list (change->changed_list, dia);
 }
 
+
 static void
-reorder_objects_revert (struct ReorderObjectsChange *change, Diagram *dia)
+dia_reorder_objects_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaReorderObjectsChange *change = DIA_REORDER_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF (("reorder_objects_revert()\n"));
   dia_layer_set_object_list (change->layer,
                              g_list_copy(change->original_objects));
   object_add_updates_list (change->changed_list, dia);
 }
 
+
 static void
-reorder_objects_free(struct ReorderObjectsChange *change)
+dia_reorder_objects_change_free (DiaChange *self)
 {
+  DiaReorderObjectsChange *change = DIA_REORDER_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF(("reorder_objects_free()\n"));
   g_list_free(change->changed_list);
   g_list_free(change->original_objects);
   g_list_free(change->reordered_objects);
 }
 
-Change *
-undo_reorder_objects(Diagram *dia, GList *changed_list, GList *orig_list)
-{
-  struct ReorderObjectsChange *change;
-
-  change = g_new0(struct ReorderObjectsChange, 1);
 
-  change->change.apply = (UndoApplyFunc) reorder_objects_apply;
-  change->change.revert = (UndoRevertFunc) reorder_objects_revert;
-  change->change.free = (UndoFreeFunc) reorder_objects_free;
+DiaChange *
+dia_reorder_objects_change_new (Diagram *dia, GList *changed_list, GList *orig_list)
+{
+  DiaReorderObjectsChange *change = dia_change_new (DIA_TYPE_REORDER_OBJECTS_CHANGE);
 
   change->layer = dia->data->active_layer;
   change->changed_list = changed_list;
@@ -845,19 +910,25 @@ undo_reorder_objects(Diagram *dia, GList *changed_list, GList *orig_list)
   change->reordered_objects = g_list_copy (dia_layer_get_object_list (DIA_DIAGRAM_DATA (dia)->active_layer));
 
   DEBUG_PRINTF(("UNDO: Push new reorder objects at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
+
+
 /******** ObjectChange: */
 
-struct ObjectChangeChange {
-  Change change;
+struct _DiaObjectChangeChange {
+  DiaChange change;
 
   DiaObject *obj;
   ObjectChange *obj_change;
 };
 
+DIA_DEFINE_CHANGE (DiaObjectChangeChange, dia_object_change_change)
+
+
 static void
 _connections_update_func (gpointer data, gpointer user_data)
 {
@@ -866,10 +937,14 @@ _connections_update_func (gpointer data, gpointer user_data)
 
   diagram_update_connections_object(dia, obj, TRUE);
 }
+
+
 static void
-object_change_apply(struct ObjectChangeChange *change,
-                   Diagram *dia)
+dia_object_change_change_apply (DiaChange *self,
+                                Diagram   *dia)
 {
+  DiaObjectChangeChange *change = DIA_OBJECT_CHANGE_CHANGE (self);
+
   if (change->obj)
     object_add_updates(change->obj, dia);
 
@@ -878,7 +953,7 @@ object_change_apply(struct ObjectChangeChange *change,
   if (change->obj) {
     /* Make sure object updates its data: */
     Point p = change->obj->position;
-    (change->obj->ops->move)(change->obj,&p);
+    dia_object_move (change->obj, &p);
 
     object_add_updates(change->obj, dia);
     diagram_update_connections_object(dia, change->obj, TRUE);
@@ -890,10 +965,13 @@ object_change_apply(struct ObjectChangeChange *change,
   }
 }
 
+
 static void
-object_change_revert(struct ObjectChangeChange *change,
-                    Diagram *dia)
+dia_object_change_change_revert (DiaChange *self,
+                                 Diagram   *dia)
 {
+  DiaObjectChangeChange *change = DIA_OBJECT_CHANGE_CHANGE (self);
+
   if (change->obj)
     object_add_updates(change->obj, dia);
 
@@ -902,7 +980,7 @@ object_change_revert(struct ObjectChangeChange *change,
   if (change->obj) {
     /* Make sure object updates its data: */
     Point p = change->obj->position;
-    (change->obj->ops->move)(change->obj,&p);
+    dia_object_move (change->obj, &p);
 
     object_add_updates(change->obj, dia);
     diagram_update_connections_object(dia, change->obj, TRUE);
@@ -913,33 +991,33 @@ object_change_revert(struct ObjectChangeChange *change,
   }
 }
 
+
 static void
-object_change_free(struct ObjectChangeChange *change)
+dia_object_change_change_free (DiaChange *self)
 {
+  DiaObjectChangeChange *change = DIA_OBJECT_CHANGE_CHANGE (self);
+
   DEBUG_PRINTF(("state_change_free()\n"));
   if (change->obj_change->free)
     (*change->obj_change->free)(change->obj_change);
   g_free(change->obj_change);
 }
 
-Change *
-undo_object_change(Diagram *dia, DiaObject *obj,
-                  ObjectChange *obj_change)
-{
-  struct ObjectChangeChange *change;
-
-  change = g_new0(struct ObjectChangeChange, 1);
 
-  change->change.apply = (UndoApplyFunc) object_change_apply;
-  change->change.revert = (UndoRevertFunc) object_change_revert;
-  change->change.free = (UndoFreeFunc) object_change_free;
+DiaChange *
+dia_object_change_change_new (Diagram      *dia,
+                              DiaObject    *obj,
+                              ObjectChange *obj_change)
+{
+  DiaObjectChangeChange *change = dia_change_new (DIA_TYPE_OBJECT_CHANGE_CHANGE);
 
   change->obj = obj;
   change->obj_change = obj_change;
 
   DEBUG_PRINTF(("UNDO: Push new obj_change at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
 /******** Group object list: */
@@ -950,8 +1028,8 @@ undo_object_change(Diagram *dia, DiaObject *obj,
  * group, and those positions have to be restored in the undo.
  */
 
-struct GroupObjectsChange {
-  Change change;
+struct _DiaGroupObjectsChange {
+  DiaChange parent;
 
   DiaLayer *layer;
   DiaObject *group;   /* owning reference if not applied */
@@ -963,9 +1041,14 @@ struct GroupObjectsChange {
   int applied;
 };
 
+DIA_DEFINE_CHANGE (DiaGroupObjectsChange, dia_group_objects_change)
+
+
 static void
-group_objects_apply(struct GroupObjectsChange *change, Diagram *dia)
+dia_group_objects_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaGroupObjectsChange *change = DIA_GROUP_OBJECTS_CHANGE (self);
+
   GList *list;
 
   DEBUG_PRINTF(("group_objects_apply()\n"));
@@ -991,9 +1074,12 @@ group_objects_apply(struct GroupObjectsChange *change, Diagram *dia)
   }
 }
 
+
 static void
-group_objects_revert (struct GroupObjectsChange *change, Diagram *dia)
+dia_group_objects_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaGroupObjectsChange *change = DIA_GROUP_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF (("group_objects_revert()\n"));
   change->applied = 0;
 
@@ -1007,9 +1093,12 @@ group_objects_revert (struct GroupObjectsChange *change, Diagram *dia)
   properties_hide_if_shown (dia, change->group);
 }
 
+
 static void
-group_objects_free(struct GroupObjectsChange *change)
+dia_group_objects_change_free (DiaChange *self)
 {
+  DiaGroupObjectsChange *change = DIA_GROUP_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF(("group_objects_free()\n"));
   if (!change->applied) {
     group_destroy_shallow(change->group);
@@ -1020,17 +1109,14 @@ group_objects_free(struct GroupObjectsChange *change)
   g_list_free(change->orig_list);
 }
 
-Change *
-undo_group_objects(Diagram *dia, GList *obj_list, DiaObject *group,
-                  GList *orig_list)
-{
-  struct GroupObjectsChange *change;
-
-  change = g_new0(struct GroupObjectsChange, 1);
 
-  change->change.apply = (UndoApplyFunc) group_objects_apply;
-  change->change.revert = (UndoRevertFunc) group_objects_revert;
-  change->change.free = (UndoFreeFunc) group_objects_free;
+DiaChange *
+dia_group_objects_change_new (Diagram   *dia,
+                              GList     *obj_list,
+                              DiaObject *group,
+                              GList     *orig_list)
+{
+  DiaGroupObjectsChange *change = dia_change_new (DIA_TYPE_GROUP_OBJECTS_CHANGE);
 
   change->layer = dia->data->active_layer;
   change->group = group;
@@ -1039,14 +1125,17 @@ undo_group_objects(Diagram *dia, GList *obj_list, DiaObject *group,
   change->applied = 1;
 
   DEBUG_PRINTF(("UNDO: Push new group objects at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+
+  return DIA_CHANGE (change);
 }
 
 /******** Ungroup object list: */
 
-struct UngroupObjectsChange {
-  Change change;
+
+struct _DiaUngroupObjectsChange {
+  DiaChange parent;
 
   DiaLayer *layer;
   DiaObject *group;   /* owning reference if applied */
@@ -1055,9 +1144,14 @@ struct UngroupObjectsChange {
   int applied;
 };
 
+DIA_DEFINE_CHANGE (DiaUngroupObjectsChange, dia_ungroup_objects_change)
+
+
 static void
-ungroup_objects_apply(struct UngroupObjectsChange *change, Diagram *dia)
+dia_ungroup_objects_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaUngroupObjectsChange *change = DIA_UNGROUP_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF(("ungroup_objects_apply()\n"));
 
   change->applied = 1;
@@ -1072,9 +1166,11 @@ ungroup_objects_apply(struct UngroupObjectsChange *change, Diagram *dia)
   properties_hide_if_shown (dia, change->group);
 }
 
+
 static void
-ungroup_objects_revert(struct UngroupObjectsChange *change, Diagram *dia)
+dia_ungroup_objects_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaUngroupObjectsChange *change = DIA_UNGROUP_OBJECTS_CHANGE (self);
   GList *list;
 
   DEBUG_PRINTF(("ungroup_objects_revert()\n"));
@@ -1098,10 +1194,14 @@ ungroup_objects_revert(struct UngroupObjectsChange *change, Diagram *dia)
   }
 }
 
+
 static void
-ungroup_objects_free(struct UngroupObjectsChange *change)
+dia_ungroup_objects_change_free (DiaChange *self)
 {
+  DiaUngroupObjectsChange *change = DIA_UNGROUP_OBJECTS_CHANGE (self);
+
   DEBUG_PRINTF(("ungroup_objects_free()\n"));
+
   if (change->applied) {
     group_destroy_shallow(change->group);
     change->group = NULL;
@@ -1109,17 +1209,14 @@ ungroup_objects_free(struct UngroupObjectsChange *change)
   }
 }
 
-Change *
-undo_ungroup_objects(Diagram *dia, GList *obj_list, DiaObject *group,
-                    int group_index)
-{
-  struct UngroupObjectsChange *change;
-
-  change = g_new0(struct UngroupObjectsChange, 1);
 
-  change->change.apply = (UndoApplyFunc) ungroup_objects_apply;
-  change->change.revert = (UndoRevertFunc) ungroup_objects_revert;
-  change->change.free = (UndoFreeFunc) ungroup_objects_free;
+DiaChange *
+dia_ungroup_objects_change_new (Diagram   *dia,
+                                GList     *obj_list,
+                                DiaObject *group,
+                                int        group_index)
+{
+  DiaUngroupObjectsChange *change = dia_change_new (DIA_TYPE_UNGROUP_OBJECTS_CHANGE);
 
   change->layer = dia->data->active_layer;
   change->group = group;
@@ -1128,18 +1225,24 @@ undo_ungroup_objects(Diagram *dia, GList *obj_list, DiaObject *group,
   change->applied = 1;
 
   DEBUG_PRINTF(("UNDO: Push new ungroup objects at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, (Change *) change);
-  return (Change *)change;
+  undo_push_change (dia->undo, DIA_CHANGE (change));
+  return DIA_CHANGE (change);
 }
 
+
+
 /******* PARENTING */
 
-struct ParentChange {
-  Change change;
+struct _DiaParentingChange {
+  DiaChange parent_instance;
+
   DiaObject *parentobj, *childobj;
   gboolean parent;
 };
 
+DIA_DEFINE_CHANGE (DiaParentingChange, dia_parenting_change)
+
+
 /** Performs the actual parenting of a child to a parent.
  * Since no display changes arise from this, we need call no update. */
 static void
@@ -1149,6 +1252,7 @@ parent_object(Diagram *dia, DiaObject *parent, DiaObject *child)
   parent->children = g_list_prepend(parent->children, child);
 }
 
+
 /** Performs the actual removal of a child from a parent.
  * Since no display changes arise from this, we need call no update. */
 static void
@@ -1158,62 +1262,77 @@ unparent_object(Diagram *dia, DiaObject *parent, DiaObject *child)
   parent->children = g_list_remove(parent->children, child);
 }
 
+
 /** Applies the given ParentChange */
 static void
-parent_change_apply(Change *change, Diagram *dia)
+dia_parenting_change_apply (DiaChange *change, Diagram *dia)
 {
-  struct ParentChange *parentchange = (struct ParentChange*)change;
+  DiaParentingChange *parentchange = DIA_PARENTING_CHANGE (change);
+
   if (parentchange->parent) {
-    parent_object(dia, parentchange->parentobj, parentchange->childobj);
+    parent_object (dia, parentchange->parentobj, parentchange->childobj);
   } else {
-    unparent_object(dia, parentchange->parentobj, parentchange->childobj);
+    unparent_object (dia, parentchange->parentobj, parentchange->childobj);
   }
 }
 
+
 /** Reverts the given ParentChange */
 static void
-parent_change_revert(Change *change, Diagram *dia)
+dia_parenting_change_revert (DiaChange *change, Diagram *dia)
 {
-  struct ParentChange *parentchange = (struct ParentChange*)change;
+  DiaParentingChange *parentchange = DIA_PARENTING_CHANGE (change);
+
   if (!parentchange->parent) {
-    parent_object(dia, parentchange->parentobj, parentchange->childobj);
+    parent_object (dia, parentchange->parentobj, parentchange->childobj);
   } else {
-    unparent_object(dia, parentchange->parentobj, parentchange->childobj);
+    unparent_object (dia, parentchange->parentobj, parentchange->childobj);
   }
 }
 
+
 /** Frees items in the change -- none really */
 static void
-parent_change_free(Change *change)
+dia_parenting_change_free (DiaChange *change)
 {
 }
 
-/** Create a new Change object for parenting/unparenting.
- * `parent' is TRUE if applying this change makes childobj a
+
+/**
+ * dia_parenting_change_new:
+ *
+ *
+ * Create a new #DiaChange object for parenting/unparenting.
+ * `parent' is %TRUE if applying this change makes childobj a
  * child of parentobj.
+ *
+ * Since: 0.98
  */
-Change *
-undo_parenting(Diagram *dia, DiaObject* parentobj, DiaObject* childobj,
-              gboolean parent)
+DiaChange *
+dia_parenting_change_new (Diagram   *dia,
+                          DiaObject *parentobj,
+                          DiaObject *childobj,
+                          gboolean   parent)
 {
-  struct ParentChange *parentchange = g_new0(struct ParentChange, 1);
-  Change *change = (Change*)parentchange;
-  change->apply = parent_change_apply;
-  change->revert = parent_change_revert;
-  change->free = parent_change_free;
+  DiaParentingChange *parentchange = dia_change_new (DIA_TYPE_PARENTING_CHANGE);
 
   parentchange->parentobj = parentobj;
   parentchange->childobj = childobj;
   parentchange->parent = parent;
 
-  DEBUG_PRINTF(("UNDO: Push new obj_change at %d\n", dia->undo->depth));
-  undo_push_change(dia->undo, change);
-  return change;
+  DEBUG_PRINTF (("UNDO: Push new obj_change at %d\n", dia->undo->depth));
+  undo_push_change (dia->undo, DIA_CHANGE (parentchange));
+
+  return DIA_CHANGE (parentchange);
 }
 
+
+
 /* ********* MOVE TO OTHER LAYER  */
-typedef struct _MoveObjectToLayerChange {
-  Change change;
+
+struct _DiaMoveObjectToLayerChange {
+  DiaChange parent;
+
   /** The objects we are moving */
   GList *objects;
   /** All objects in the original layer */
@@ -1221,7 +1340,10 @@ typedef struct _MoveObjectToLayerChange {
   /** The active layer when started */
   DiaLayer *orig_layer;
   gboolean moving_up;
-} MoveObjectToLayerChange;
+};
+
+DIA_DEFINE_CHANGE (DiaMoveObjectToLayerChange, dia_move_object_to_layer_change)
+
 
 /*!
  * BEWARE: we need to notify the DiagramTree somehow - maybe
@@ -1252,21 +1374,27 @@ move_object_layer_relative (Diagram *dia, GList *objects, gint dist)
   data_set_active_layer (dia->data, target);
 }
 
+
 static void
-move_object_to_layer_apply(MoveObjectToLayerChange *change, Diagram *dia)
+dia_move_object_to_layer_change_apply (DiaChange *self, Diagram *dia)
 {
+  DiaMoveObjectToLayerChange *change = DIA_MOVE_OBJECT_TO_LAYER_CHANGE (self);
+
   if (change->moving_up) {
-    move_object_layer_relative(dia, change->objects, 1);
+    move_object_layer_relative (dia, change->objects, 1);
   } else {
-    move_object_layer_relative(dia, change->objects, -1);
+    move_object_layer_relative (dia, change->objects, -1);
   }
 }
 
+
 static void
-move_object_to_layer_revert(MoveObjectToLayerChange *change, Diagram *dia)
+dia_move_object_to_layer_change_revert (DiaChange *self, Diagram *dia)
 {
+  DiaMoveObjectToLayerChange *change = DIA_MOVE_OBJECT_TO_LAYER_CHANGE (self);
+
   if (change->moving_up) {
-    move_object_layer_relative(dia, change->objects, -1);
+    move_object_layer_relative (dia, change->objects, -1);
   } else {
     diagram_unselect_objects (dia, change->objects);
     move_object_layer_relative (dia, change->objects, 1);
@@ -1276,25 +1404,26 @@ move_object_to_layer_revert(MoveObjectToLayerChange *change, Diagram *dia)
   }
 }
 
+
 static void
-move_object_to_layer_free(MoveObjectToLayerChange *change)
+dia_move_object_to_layer_change_free (DiaChange *self)
 {
-  g_list_free(change->objects);
-  g_list_free(change->orig_list);
+  DiaMoveObjectToLayerChange *change = DIA_MOVE_OBJECT_TO_LAYER_CHANGE (self);
+
+  g_list_free (change->objects);
+  g_list_free (change->orig_list);
+
   change->objects = NULL;
   change->orig_list = NULL;
 }
 
-Change *
-undo_move_object_other_layer(Diagram *dia, GList *selected_list,
-                            gboolean moving_up)
+
+DiaChange *
+dia_move_object_to_layer_change_new (Diagram  *dia,
+                                     GList    *selected_list,
+                                     gboolean  moving_up)
 {
-  MoveObjectToLayerChange *movetolayerchange
-    = g_new0(MoveObjectToLayerChange, 1);
-  Change *change = (Change*)movetolayerchange;
-  change->apply = (UndoApplyFunc) move_object_to_layer_apply;
-  change->revert = (UndoRevertFunc) move_object_to_layer_revert;
-  change->free = (UndoFreeFunc) move_object_to_layer_free;
+  DiaMoveObjectToLayerChange *movetolayerchange = dia_change_new (DIA_TYPE_MOVE_OBJECT_TO_LAYER_CHANGE);
 
   movetolayerchange->orig_layer = dia->data->active_layer;
   movetolayerchange->orig_list = g_list_copy (dia_layer_get_object_list (DIA_DIAGRAM_DATA 
(dia)->active_layer));
@@ -1302,21 +1431,29 @@ undo_move_object_other_layer(Diagram *dia, GList *selected_list,
   movetolayerchange->moving_up = moving_up;
 
   DEBUG_PRINTF (("UNDO: Push new obj_layer_change at %d\n", dia->undo->depth));
-  undo_push_change (dia->undo, change);
-  return change;
+  undo_push_change (dia->undo, DIA_CHANGE (movetolayerchange));
+
+  return DIA_CHANGE (movetolayerchange);
 }
 
-typedef struct _ImportChange {
-  Change change;
+
+
+struct _DiaImportChange {
+  DiaChange parent;
 
   Diagram *dia;     /*!< the diagram under inspection */
   GList   *layers;  /*!< layers added */
   GList   *objects; /*!< objects added */
-} ImportChange;
+};
+
+DIA_DEFINE_CHANGE (DiaImportChange, dia_import_change)
+
+
 static void
-_import_change_apply (ImportChange *change,
-                     Diagram      *dia)
+dia_import_change_apply (DiaChange *self,
+                         Diagram   *dia)
 {
+  DiaImportChange *change = DIA_IMPORT_CHANGE (self);
   GList *list;
   DiaLayer *layer = dia->data->active_layer;
 
@@ -1337,10 +1474,12 @@ _import_change_apply (ImportChange *change,
   diagram_update_extents (change->dia);
 }
 
+
 static void
-_import_change_revert (ImportChange *change,
-                       Diagram      *dia)
+dia_import_change_revert (DiaChange *self,
+                          Diagram   *diagram)
 {
+  DiaImportChange *change = DIA_IMPORT_CHANGE (self);
   GList *list;
 
   /* otherwise we might end up with an empty selection */
@@ -1357,9 +1496,13 @@ _import_change_revert (ImportChange *change,
   }
   diagram_update_extents (change->dia);
 }
+
+
 static void
-_import_change_free (ImportChange *change)
+dia_import_change_free (DiaChange *self)
 {
+  DiaImportChange *change = DIA_IMPORT_CHANGE (self);
+
   g_return_if_fail (change->dia != NULL);
 
   /* FIXME: do we need to delete more? */
@@ -1367,73 +1510,92 @@ _import_change_free (ImportChange *change)
   g_list_free (change->layers);
 }
 
+
 /* listen on the diagram for object add */
 static void
-_import_object_add (DiagramData  *dia,
-                    DiaLayer     *layer,
-                    DiaObject    *obj,
-                    ImportChange *change)
+_import_object_add (DiagramData     *dia,
+                    DiaLayer        *layer,
+                    DiaObject       *obj,
+                    DiaImportChange *change)
 {
-  g_return_if_fail (change->dia == DIA_DIAGRAM(dia));
+  g_return_if_fail (change->dia == DIA_DIAGRAM (dia));
 
   if (!obj)
     change->layers = g_list_prepend (change->layers, layer);
   else
     change->objects = g_list_prepend (change->objects, obj);
 }
-/*!
- * \brief Create an import change object listening on diagram additions
- * @param dia the diagram to watch
+
+
+/**
+ * undo_import_change_setup:
+ * @dia: the #Diagram to watch
+ *
+ * Create an import change object listening on diagram additions
+ *
+ * Since: 0.98
  */
-Change *
-undo_import_change_setup (Diagram *dia)
+DiaChange *
+dia_import_change_new (Diagram *dia)
 {
-  ImportChange *change = g_new0 (ImportChange, 1);
+  DiaImportChange *change = dia_change_new (DIA_TYPE_IMPORT_CHANGE);
 
   change->dia = dia;
-  change->change.apply  = (UndoApplyFunc)  _import_change_apply;
-  change->change.revert = (UndoRevertFunc) _import_change_revert;
-  change->change.free   = (UndoFreeFunc)   _import_change_free;
 
-  g_signal_connect (G_OBJECT(dia), "object_add", G_CALLBACK(_import_object_add), change);
+  g_signal_connect (G_OBJECT (dia),
+                    "object_add",
+                    G_CALLBACK (_import_object_add),
+                    change);
 
-  return &change->change;
+  return DIA_CHANGE (change);
 }
-/*!
- * \brief Finish listening on the diagram changes
- * @param chg the change object created by undo_import_change_setup()
- * @return TRUE if the change was added to the undo stack, FALSE otherwise
+
+
+/**
+ * dia_import_change_done
+ * @dia: the #Diagram
+ * @chg: the #DiaChange object created by dia_import_change_new()
+ *
+ * Finish listening on the diagram changes
+ *
+ * Returns: %TRUE if the change was added to the undo stack, %FALSE otherwise
+ *
+ * Since: 0.98
  */
 gboolean
-undo_import_change_done (Diagram *dia, Change *chg)
+dia_import_change_done (Diagram *dia, DiaChange *chg)
 {
-  ImportChange *change = (ImportChange *)chg;
+  DiaImportChange *change;
 
-  /* Some type checking first */
-  g_return_val_if_fail (change != NULL, FALSE);
-  g_return_val_if_fail (change->change.apply == (UndoApplyFunc)_import_change_apply, FALSE);
-  g_return_val_if_fail (change->change.revert == (UndoRevertFunc)_import_change_revert, FALSE);
-  g_return_val_if_fail (change->change.free == (UndoFreeFunc)_import_change_free, FALSE);
+  g_return_val_if_fail (chg && DIA_IS_IMPORT_CHANGE (chg), FALSE);
+
+  change = DIA_IMPORT_CHANGE (chg);
 
   /* stop listening on this diagram */
   g_signal_handlers_disconnect_by_func (change->dia, _import_object_add, change);
 
   if (change->layers != NULL || change->objects != NULL) {
-    undo_push_change(dia->undo, (Change *) change);
+    undo_push_change (dia->undo, chg);
     return TRUE;
   }
   return FALSE;
 }
 
-typedef struct _MemSwapChange {
-  Change change;
+
+
+struct _DiaMemSwapChange {
+  DiaChange parent;
 
   gsize   size;
   guint8 *dest;   /* for 'write trough' */
-  guint8  mem[1]; /* real size during alloc */
-} MemSwapChange;
+  guint8 *mem;
+};
+
+DIA_DEFINE_CHANGE (DiaMemSwapChange, dia_mem_swap_change)
+
+
 static void
-_swap_mem(MemSwapChange *change, Diagram *dia)
+_swap_mem (DiaMemSwapChange *change, Diagram *dia)
 {
   gsize  i;
 
@@ -1442,36 +1604,61 @@ _swap_mem(MemSwapChange *change, Diagram *dia)
     change->mem[i] = change->dest[i];
     change->dest[i] = tmp;
   }
-  diagram_add_update_all(dia);
-  diagram_flush(dia);
+  diagram_add_update_all (dia);
+  diagram_flush (dia);
 }
 
-/*!
- * \brief Record a memory region for undo (before actually changing it)
+
+static void
+dia_mem_swap_change_apply (DiaChange *change,
+                           Diagram   *diagram)
+{
+  _swap_mem (DIA_MEM_SWAP_CHANGE (change), diagram);
+}
+
+
+static void
+dia_mem_swap_change_revert (DiaChange *change,
+                            Diagram   *diagram)
+{
+  _swap_mem (DIA_MEM_SWAP_CHANGE (change), diagram);
+}
+
+
+static void
+dia_mem_swap_change_free (DiaChange *change)
+{
+  DiaMemSwapChange *self = DIA_MEM_SWAP_CHANGE (change);
+
+  g_clear_pointer (&self->mem, g_free);
+}
+
+
+/**
+ * dia_mem_swap_change_new:
+ * @dia: the Diagram to record the change for
+ * @dest: a pointer somewhere in the Diagram
+ * @size: of the region to copy and restore
+ *
+ * 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
+ * Since: 0.98
  */
-Change *
-undo_change_memswap (Diagram *dia, gpointer dest, gsize size)
+DiaChange *
+dia_mem_swap_change_new (Diagram *dia, gpointer dest, gsize size)
 {
-  MemSwapChange *change = (MemSwapChange *)g_malloc (sizeof(MemSwapChange)+size);
+  DiaMemSwapChange *change = dia_change_new (DIA_TYPE_MEM_SWAP_CHANGE);
   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;
+  change->mem = g_malloc (size);
   /* initialize for swap */
   for (i = 0; i < size; ++i)
     change->mem[i] = change->dest[i];
 
   DEBUG_PRINTF(("UNDO: Push new memswap_change(%zd) at %d\n", size, dia->undo->depth));
-  undo_push_change(dia->undo, &change->change);
+  undo_push_change (dia->undo, DIA_CHANGE (change));
 
-  return &change->change;
+  return DIA_CHANGE (change);
 }
diff --git a/app/undo.h b/app/undo.h
index 438a4411..cefcb00f 100644
--- a/app/undo.h
+++ b/app/undo.h
@@ -20,34 +20,22 @@
 
 
 typedef struct _UndoStack UndoStack;
-typedef struct _Change Change;
 
 #include "diagram.h"
 
-typedef void (*UndoApplyFunc)(Change *change, Diagram *dia);
-typedef void (*UndoRevertFunc)(Change *change, Diagram *dia);
-typedef void (*UndoFreeFunc)(Change *change);
-
-struct _Change {
-  /* If apply == transaction_point_pointer then this is a transaction
-     point */
-  UndoApplyFunc  apply;
-  UndoRevertFunc revert;
-  UndoFreeFunc   free; /* Remove extra data. Then this object is freed */
-  Change *prev, *next;
-};
+#include "dia-change.h"
 
 struct _UndoStack {
   Diagram *dia;
-  Change *last_change; /* Points to the object on the top of stack. */
-  Change *current_change; /* Points to the last object currently applied */
-  Change *last_save;   /* Points to current_change at the time of last save. */
+  DiaChange *last_change; /* Points to the object on the top of stack. */
+  DiaChange *current_change; /* Points to the last object currently applied */
+  DiaChange *last_save;   /* Points to current_change at the time of last save. */
   int depth;
 };
 
 UndoStack *new_undo_stack(Diagram *dia);
 void undo_destroy(UndoStack *stack);
-void undo_push_change(UndoStack *stack, Change *change);
+void undo_push_change(UndoStack *stack, DiaChange *change);
 void undo_set_transactionpoint(UndoStack *stack);
 void undo_revert_to_last_tp(UndoStack *stack);
 void undo_apply_to_next_tp(UndoStack *stack);
@@ -55,43 +43,136 @@ void undo_clear(UndoStack *stack);
 void undo_mark_save(UndoStack *stack);
 gboolean undo_is_saved(UndoStack *stack);
 gboolean undo_available(UndoStack *stack, gboolean undo);
-Change* undo_remove_to(UndoStack *stack, UndoApplyFunc *type);
+DiaChange* undo_remove_to(UndoStack *stack, GType type);
 
 /* Specific undo functions: */
 
-Change *undo_move_objects(Diagram *dia, Point *orig_pos,
-                         Point *dest_pos, GList *obj_list);
-Change *undo_move_handle(Diagram *dia,
-                        Handle *handle, DiaObject *obj,
-                        Point orig_pos, Point dest_pos,
-                        int modifiers);
-Change *undo_connect(Diagram *dia, DiaObject *obj, Handle *handle,
-                    ConnectionPoint *connectionpoint);
-Change *undo_unconnect(Diagram *dia, DiaObject *obj, Handle *handle);
-Change *undo_delete_objects_children(Diagram *dia, GList *obj_list);
-Change *undo_delete_objects(Diagram *dia, GList *obj_list); /* Reads current obj list */
-Change *undo_insert_objects(Diagram *dia, GList *obj_list,
-                           int applied);
-Change *undo_reorder_objects(Diagram *dia, GList *changed_list,
-                            GList *orig_list); /* Reads current obj list */
-Change *undo_object_change(Diagram *dia, DiaObject *obj,
-                          ObjectChange *obj_change);
-Change *undo_group_objects(Diagram *dia, GList *obj_list,
-                          DiaObject *group, GList *orig_list);
-Change *undo_ungroup_objects(Diagram *dia, GList *obj_list,
-                            DiaObject *group, int group_index);
-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);
+#define DIA_TYPE_TRANSACTION_POINT_CHANGE dia_transaction_point_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaTransactionPointChange, dia_transaction_point_change, DIA, 
TRANSACTION_POINT_CHANGE, DiaChange)
+
+#define DIA_TYPE_MOVE_OBJECTS_CHANGE dia_move_objects_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaMoveObjectsChange, dia_move_objects_change, DIA, MOVE_OBJECTS_CHANGE, DiaChange)
+
+DiaChange *dia_move_objects_change_new                 (Diagram   *dia,
+                                                        Point     *orig_pos,
+                                                        Point     *dest_pos,
+                                                        GList     *obj_list);
+
+
+#define DIA_TYPE_MOVE_HANDLE_CHANGE dia_move_handle_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaMoveHandleChange, dia_move_handle_change, DIA, MOVE_HANDLE_CHANGE, DiaChange)
+
+DiaChange *dia_move_handle_change_new                  (Diagram   *dia,
+                                                        Handle    *handle,
+                                                        DiaObject *obj,
+                                                        Point      orig_pos,
+                                                        Point      dest_pos,
+                                                        int        modifiers);
+
+
+#define DIA_TYPE_CONNECT_CHANGE dia_connect_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaConnectChange, dia_connect_change, DIA, CONNECT_CHANGE, DiaChange)
+
+DiaChange *dia_connect_change_new                      (Diagram   *dia,
+                                                        DiaObject *obj,
+                                                        Handle    *handle,
+                                                        ConnectionPoint *connectionpoint);
+
+
+#define DIA_TYPE_UNCONNECT_CHANGE dia_unconnect_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaUnconnectChange, dia_unconnect_change, DIA, UNCONNECT_CHANGE, DiaChange)
+
+DiaChange *dia_unconnect_change_new                    (Diagram   *dia,
+                                                        DiaObject *obj,
+                                                        Handle    *handle);
+
+
+#define DIA_TYPE_DELETE_OBJECTS_CHANGE dia_delete_objects_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaDeleteObjectsChange, dia_delete_objects_change, DIA, DELETE_OBJECTS_CHANGE, 
DiaChange)
+
+DiaChange *dia_delete_objects_change_new_with_children (Diagram   *dia,
+                                                        GList     *obj_list);
+DiaChange *dia_delete_objects_change_new               (Diagram   *dia,
+                                                        GList     *obj_list); /* Reads current obj list */
+
+
+#define DIA_TYPE_INSERT_OBJECTS_CHANGE dia_insert_objects_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaInsertObjectsChange, dia_insert_objects_change, DIA, INSERT_OBJECTS_CHANGE, 
DiaChange)
+
+DiaChange *dia_insert_objects_change_new               (Diagram   *dia,
+                                                        GList     *obj_list,
+                                                        int        applied);
+
+
+#define DIA_TYPE_REORDER_OBJECTS_CHANGE dia_reorder_objects_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaReorderObjectsChange, dia_reorder_objects_change, DIA, REORDER_OBJECTS_CHANGE, 
DiaChange)
+
+DiaChange *dia_reorder_objects_change_new              (Diagram   *dia,
+                                                        GList     *changed_list,
+                                                        GList     *orig_list); /* Reads current obj list */
+
+
+#define DIA_TYPE_OBJECT_CHANGE_CHANGE dia_object_change_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaObjectChangeChange, dia_object_change_change, DIA, OBJECT_CHANGE_CHANGE, DiaChange)
+
+DiaChange *dia_object_change_change_new                (Diagram      *dia,
+                                                        DiaObject    *obj,
+                                                        ObjectChange *obj_change);
+
+
+#define DIA_TYPE_GROUP_OBJECTS_CHANGE dia_group_objects_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaGroupObjectsChange, dia_group_objects_change, DIA, GROUP_OBJECTS_CHANGE, DiaChange)
+
+DiaChange *dia_group_objects_change_new                (Diagram   *dia,
+                                                        GList     *obj_list,
+                                                        DiaObject *group,
+                                                        GList     *orig_list);
+
+
+#define DIA_TYPE_UNGROUP_OBJECTS_CHANGE dia_ungroup_objects_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaUngroupObjectsChange, dia_ungroup_objects_change, DIA, UNGROUP_OBJECTS_CHANGE, 
DiaChange)
+
+DiaChange *dia_ungroup_objects_change_new              (Diagram   *dia,
+                                                        GList     *obj_list,
+                                                        DiaObject *group,
+                                                        int        group_index);
+
+
+#define DIA_TYPE_PARENTING_CHANGE dia_parenting_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaParentingChange, dia_parenting_change, DIA, PARENTING_CHANGE, DiaChange)
+
+DiaChange *dia_parenting_change_new                    (Diagram   *dia,
+                                                        DiaObject *parentobj,
+                                                        DiaObject *childobj,
+                                                        gboolean   parent);
+
+
+#define DIA_TYPE_MOVE_OBJECT_TO_LAYER_CHANGE dia_move_object_to_layer_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaMoveObjectToLayerChange, dia_move_object_to_layer_change, DIA, 
MOVE_OBJECT_TO_LAYER_CHANGE, DiaChange)
+
+DiaChange *dia_move_object_to_layer_change_new         (Diagram   *diagram,
+                                                        GList     *selected_list,
+                                                        gboolean   moving_up);
+
+
+#define DIA_TYPE_IMPORT_CHANGE dia_import_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaImportChange, dia_import_change, DIA, IMPORT_CHANGE, DiaChange)
 
 /* Create an import change object listening on diagram additions/removals */
-Change *undo_import_change_setup (Diagram *diagram);
+DiaChange *dia_import_change_new                       (Diagram   *diagram);
 /* Finish listening on the diagram changes */
-gboolean undo_import_change_done (Diagram *dia, Change *chg);
+gboolean   dia_import_change_done                      (Diagram   *dia,
+                                                        DiaChange *chg);
+
+
+#define DIA_TYPE_MEM_SWAP_CHANGE dia_mem_swap_change_get_type ()
+G_DECLARE_FINAL_TYPE (DiaMemSwapChange, dia_mem_swap_change, DIA, MEM_SWAP_CHANGE, DiaChange)
 
 /* handle with care, just plain memory copy */
-Change *undo_change_memswap (Diagram *dia, gpointer dest, gsize size);
+DiaChange *dia_mem_swap_change_new                     (Diagram   *dia,
+                                                        gpointer   dest,
+                                                        gsize      size);
+
 
 #endif /* UNDO_H */
 


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