Index: trunk/src/tool.c =================================================================== --- trunk/src/tool.c (revision 12376) +++ trunk/src/tool.c (revision 12377) @@ -141,6 +141,11 @@ wrap_void(adjust_attached_objects, ()); } +pcb_bool pcb_tool_undo_act(void) +{ + wrap_retv(undo_act, return pcb_true, ()); +} + #warning tool TODO: move this out to a tool plugin #include "tool_arc.h" Index: trunk/src/tool.h =================================================================== --- trunk/src/tool.h (revision 12376) +++ trunk/src/tool.h (revision 12377) @@ -25,6 +25,8 @@ #include +#include "pcb_bool.h" + typedef int pcb_toolid_t; #define PCB_TOOLID_INVALID (-1) @@ -36,6 +38,7 @@ /* tool implementation */ void (*notify_mode)(void); void (*adjust_attached_objects)(void); + int (*undo_act)(void); } pcb_tool_t; vtp0_t pcb_tools; @@ -64,6 +67,7 @@ void pcb_tool_notify_mode(void); void pcb_tool_adjust_attached_objects(void); +pcb_bool pcb_tool_undo_act(void); Index: trunk/src/tool_arc.c =================================================================== --- trunk/src/tool_arc.c (revision 12376) +++ trunk/src/tool_arc.c (revision 12377) @@ -34,6 +34,7 @@ #include "crosshair.h" #include "data.h" #include "draw.h" +#include "search.h" #include "tool.h" #include "undo.h" @@ -100,8 +101,31 @@ pcb_crosshair.AttachedBox.otherway = pcb_gui->shift_is_pressed(); } +pcb_bool pcb_tool_arc_undo_act(void) +{ + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_SECOND) { + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + pcb_notify_crosshair_change(pcb_true); + return pcb_false; + } + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_THIRD) { + void *ptr1, *ptr2, *ptr3; + /* guaranteed to succeed */ + pcb_search_obj_by_location(PCB_TYPE_ARC, &ptr1, &ptr2, &ptr3, + pcb_crosshair.AttachedBox.Point1.X, pcb_crosshair.AttachedBox.Point1.Y, 0); + pcb_arc_get_end((pcb_arc_t *) ptr2, 0, &pcb_crosshair.AttachedBox.Point2.X, &pcb_crosshair.AttachedBox.Point2.Y); + pcb_crosshair.AttachedBox.Point1.X = pcb_crosshair.AttachedBox.Point2.X; + pcb_crosshair.AttachedBox.Point1.Y = pcb_crosshair.AttachedBox.Point2.Y; + pcb_adjust_attached_objects(); + if (--pcb_added_lines == 0) + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_SECOND; + } + return pcb_true; +} + pcb_tool_t pcb_tool_arc = { "arc", NULL, 100, pcb_tool_arc_notify_mode, - pcb_tool_arc_adjust_attached_objects + pcb_tool_arc_adjust_attached_objects, + pcb_tool_arc_undo_act }; Index: trunk/src/tool_arc.h =================================================================== --- trunk/src/tool_arc.h (revision 12376) +++ trunk/src/tool_arc.h (revision 12377) @@ -2,3 +2,4 @@ void pcb_tool_arc_notify_mode(void); void pcb_tool_arc_adjust_attached_objects(void); +pcb_bool pcb_tool_arc_undo_act(void); Index: trunk/src/tool_arrow.c =================================================================== --- trunk/src/tool_arrow.c (revision 12376) +++ trunk/src/tool_arrow.c (revision 12377) @@ -148,5 +148,6 @@ pcb_tool_t pcb_tool_arrow = { "arrow", NULL, 10, pcb_tool_arrow_notify_mode, - pcb_tool_arrow_adjust_attached_objects + pcb_tool_arrow_adjust_attached_objects, + NULL }; Index: trunk/src/tool_buffer.c =================================================================== --- trunk/src/tool_buffer.c (revision 12376) +++ trunk/src/tool_buffer.c (revision 12377) @@ -92,5 +92,6 @@ pcb_tool_t pcb_tool_buffer = { "buffer", NULL, 100, pcb_tool_buffer_notify_mode, + NULL, NULL }; Index: trunk/src/tool_copy.c =================================================================== --- trunk/src/tool_copy.c (revision 12376) +++ trunk/src/tool_copy.c (revision 12377) @@ -68,8 +68,17 @@ } } +pcb_bool pcb_tool_copy_undo_act(void) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) + return pcb_false; + return pcb_true; +} + pcb_tool_t pcb_tool_copy = { "copy", NULL, 100, pcb_tool_copy_notify_mode, - NULL + NULL, + pcb_tool_copy_undo_act }; Index: trunk/src/tool_copy.h =================================================================== --- trunk/src/tool_copy.h (revision 12376) +++ trunk/src/tool_copy.h (revision 12377) @@ -1,3 +1,4 @@ extern pcb_tool_t pcb_tool_copy; void pcb_tool_copy_notify_mode(void); +pcb_bool pcb_tool_copy_undo_act(void); Index: trunk/src/tool_insert.c =================================================================== --- trunk/src/tool_insert.c (revision 12376) +++ trunk/src/tool_insert.c (revision 12377) @@ -106,8 +106,17 @@ InsertedPoint = *pnt; } +pcb_bool pcb_tool_insert_undo_act(void) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) + return pcb_false; + return pcb_true; +} + pcb_tool_t pcb_tool_insert = { "insert", NULL, 100, pcb_tool_insert_notify_mode, - pcb_tool_insert_adjust_attached_objects + pcb_tool_insert_adjust_attached_objects, + pcb_tool_insert_undo_act }; Index: trunk/src/tool_insert.h =================================================================== --- trunk/src/tool_insert.h (revision 12376) +++ trunk/src/tool_insert.h (revision 12377) @@ -2,3 +2,4 @@ void pcb_tool_insert_notify_mode(void); void pcb_tool_insert_adjust_attached_objects(void); +pcb_bool pcb_tool_insert_undo_act(void); Index: trunk/src/tool_line.c =================================================================== --- trunk/src/tool_line.c (revision 12376) +++ trunk/src/tool_line.c (revision 12377) @@ -246,8 +246,75 @@ } } +pcb_bool pcb_tool_line_undo_act(void) +{ + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_SECOND) { + if (conf_core.editor.auto_drc) + pcb_undo(pcb_true); /* undo the connection find */ + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + pcb_route_reset(&pcb_crosshair.Route); + pcb_crosshair_set_local_ref(0, 0, pcb_false); + return pcb_false; + } + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_THIRD) { + int type; + void *ptr1, *ptr3, *ptrtmp; + pcb_line_t *ptr2; + /* this search is guaranteed to succeed */ + pcb_search_obj_by_location(PCB_TYPE_LINE | PCB_TYPE_RATLINE, &ptr1, + &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, 0); + ptr2 = (pcb_line_t *) ptrtmp; + + /* save both ends of line */ + pcb_crosshair.AttachedLine.Point2.X = ptr2->Point1.X; + pcb_crosshair.AttachedLine.Point2.Y = ptr2->Point1.Y; + if ((type = pcb_undo(pcb_true))) + pcb_board_set_changed_flag(pcb_true); + /* check that the undo was of the right type */ + if ((type & PCB_UNDO_CREATE) == 0) { + /* wrong undo type, restore anchor points */ + pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.AttachedLine.Point1.X; + pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.AttachedLine.Point1.Y; + return pcb_false; + } + /* move to new anchor */ + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y; + /* check if an intermediate point was removed */ + if (type & PCB_UNDO_REMOVE) { + /* this search should find the restored line */ + pcb_search_obj_by_location(PCB_TYPE_LINE | PCB_TYPE_RATLINE, &ptr1, + &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y, 0); + ptr2 = (pcb_line_t *) ptrtmp; + if (conf_core.editor.auto_drc) { + /* undo loses PCB_FLAG_FOUND */ + PCB_FLAG_SET(PCB_FLAG_FOUND, ptr2); + pcb_line_invalidate_draw(CURRENT, ptr2); + } + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = ptr2->Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = ptr2->Point2.Y; + } + pcb_crosshair_grid_fit(pcb_crosshair.X, pcb_crosshair.Y); + pcb_adjust_attached_objects(); + if (--pcb_added_lines == 0) { + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_SECOND; + lastLayer = CURRENT; + } + else { + /* this search is guaranteed to succeed too */ + pcb_search_obj_by_location(PCB_TYPE_LINE | PCB_TYPE_RATLINE, &ptr1, + &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, 0); + ptr2 = (pcb_line_t *) ptrtmp; + lastLayer = (pcb_layer_t *) ptr1; + } + return pcb_false; + } + return pcb_true; +} + pcb_tool_t pcb_tool_line = { "line", NULL, 100, pcb_tool_line_notify_mode, - pcb_tool_line_adjust_attached_objects + pcb_tool_line_adjust_attached_objects, + pcb_tool_line_undo_act }; Index: trunk/src/tool_line.h =================================================================== --- trunk/src/tool_line.h (revision 12376) +++ trunk/src/tool_line.h (revision 12377) @@ -2,3 +2,4 @@ void pcb_tool_line_notify_mode(void); void pcb_tool_line_adjust_attached_objects(void); +pcb_bool pcb_tool_line_undo_act(void); Index: trunk/src/tool_lock.c =================================================================== --- trunk/src/tool_lock.c (revision 12376) +++ trunk/src/tool_lock.c (revision 12377) @@ -96,5 +96,6 @@ pcb_tool_t pcb_tool_lock = { "lock", NULL, 100, pcb_tool_lock_notify_mode, + NULL, NULL }; Index: trunk/src/tool_move.c =================================================================== --- trunk/src/tool_move.c (revision 12376) +++ trunk/src/tool_move.c (revision 12377) @@ -76,8 +76,17 @@ } } +pcb_bool pcb_tool_move_undo_act(void) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) + return pcb_false; + return pcb_true; +} + pcb_tool_t pcb_tool_move = { "move", NULL, 100, pcb_tool_move_notify_mode, - NULL + NULL, + pcb_tool_move_undo_act }; Index: trunk/src/tool_move.h =================================================================== --- trunk/src/tool_move.h (revision 12376) +++ trunk/src/tool_move.h (revision 12377) @@ -1,3 +1,4 @@ extern pcb_tool_t pcb_tool_move; void pcb_tool_move_notify_mode(void); +pcb_bool pcb_tool_move_undo_act(void); Index: trunk/src/tool_poly.c =================================================================== --- trunk/src/tool_poly.c (revision 12376) +++ trunk/src/tool_poly.c (revision 12377) @@ -78,8 +78,18 @@ pcb_line_adjust_attached(); } +pcb_bool pcb_tool_poly_undo_act(void) +{ + if (pcb_crosshair.AttachedPolygon.PointN) { + pcb_polygon_go_to_prev_point(); + return pcb_false; + } + return pcb_true; +} + pcb_tool_t pcb_tool_poly = { "poly", NULL, 100, pcb_tool_poly_notify_mode, - pcb_tool_poly_adjust_attached_objects + pcb_tool_poly_adjust_attached_objects, + pcb_tool_poly_undo_act }; Index: trunk/src/tool_poly.h =================================================================== --- trunk/src/tool_poly.h (revision 12376) +++ trunk/src/tool_poly.h (revision 12377) @@ -2,3 +2,4 @@ void pcb_tool_poly_notify_mode(void); void pcb_tool_poly_adjust_attached_objects(void); +pcb_bool pcb_tool_poly_undo_act(void); Index: trunk/src/tool_polyhole.c =================================================================== --- trunk/src/tool_polyhole.c (revision 12376) +++ trunk/src/tool_polyhole.c (revision 12377) @@ -109,8 +109,18 @@ pcb_line_adjust_attached(); } +pcb_bool pcb_tool_polyhole_undo_act(void) +{ + if (pcb_crosshair.AttachedPolygon.PointN) { + pcb_polygon_go_to_prev_point(); + return pcb_false; + } + return pcb_true; +} + pcb_tool_t pcb_tool_polyhole = { "polyhole", NULL, 100, pcb_tool_polyhole_notify_mode, - pcb_tool_polyhole_adjust_attached_objects + pcb_tool_polyhole_adjust_attached_objects, + pcb_tool_polyhole_undo_act }; Index: trunk/src/tool_polyhole.h =================================================================== --- trunk/src/tool_polyhole.h (revision 12376) +++ trunk/src/tool_polyhole.h (revision 12377) @@ -2,3 +2,4 @@ void pcb_tool_polyhole_notify_mode(void); void pcb_tool_polyhole_adjust_attached_objects(void); +pcb_bool pcb_tool_polyhole_undo_act(void); Index: trunk/src/tool_rectangle.c =================================================================== --- trunk/src/tool_rectangle.c (revision 12376) +++ trunk/src/tool_rectangle.c (revision 12377) @@ -90,8 +90,17 @@ } } +pcb_bool pcb_tool_rectangle_undo_act(void) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedBox.State != PCB_CH_STATE_FIRST) + return pcb_false; + return pcb_true; +} + pcb_tool_t pcb_tool_rectangle = { "rectangle", NULL, 100, pcb_tool_rectangle_notify_mode, - pcb_tool_rectangle_adjust_attached_objects + pcb_tool_rectangle_adjust_attached_objects, + pcb_tool_rectangle_undo_act }; Index: trunk/src/tool_rectangle.h =================================================================== --- trunk/src/tool_rectangle.h (revision 12376) +++ trunk/src/tool_rectangle.h (revision 12377) @@ -2,3 +2,4 @@ void pcb_tool_rectangle_notify_mode(void); void pcb_tool_rectangle_adjust_attached_objects(void); +pcb_bool pcb_tool_rectangle_undo_act(void); Index: trunk/src/tool_remove.c =================================================================== --- trunk/src/tool_remove.c (revision 12376) +++ trunk/src/tool_remove.c (revision 12377) @@ -60,5 +60,6 @@ pcb_tool_t pcb_tool_remove = { "remove", NULL, 100, pcb_tool_remove_notify_mode, + NULL, NULL }; Index: trunk/src/tool_rotate.c =================================================================== --- trunk/src/tool_rotate.c (revision 12376) +++ trunk/src/tool_rotate.c (revision 12377) @@ -44,5 +44,6 @@ pcb_tool_t pcb_tool_rotate = { "rotate", NULL, 100, pcb_tool_rotate_notify_mode, + NULL, NULL }; Index: trunk/src/tool_text.c =================================================================== --- trunk/src/tool_text.c (revision 12376) +++ trunk/src/tool_text.c (revision 12377) @@ -67,5 +67,6 @@ pcb_tool_t pcb_tool_text = { "text", NULL, 100, pcb_tool_text_notify_mode, + NULL, NULL }; Index: trunk/src/tool_thermal.c =================================================================== --- trunk/src/tool_thermal.c (revision 12376) +++ trunk/src/tool_thermal.c (revision 12377) @@ -61,5 +61,6 @@ pcb_tool_t pcb_tool_thermal = { "thermal", NULL, 100, pcb_tool_thermal_notify_mode, + NULL, NULL }; Index: trunk/src/tool_via.c =================================================================== --- trunk/src/tool_via.c (revision 12376) +++ trunk/src/tool_via.c (revision 12377) @@ -65,5 +65,6 @@ pcb_tool_t pcb_tool_via = { "via", NULL, 100, pcb_tool_via_notify_mode, + NULL, NULL }; Index: trunk/src/undo_act.c =================================================================== --- trunk/src/undo_act.c (revision 12376) +++ trunk/src/undo_act.c (revision 12377) @@ -40,6 +40,16 @@ #include "obj_line_draw.h" +#include "tool.h" +#include "tool_arc.h" +#include "tool_copy.h" +#include "tool_insert.h" +#include "tool_line.h" +#include "tool_move.h" +#include "tool_poly.h" +#include "tool_polyhole.h" +#include "tool_rectangle.h" + /* --------------------------------------------------------------------------- */ static const char pcb_acts_Atomic[] = "Atomic(Save|Restore|Close|Block)"; @@ -128,108 +138,35 @@ { const char *function = PCB_ACTION_ARG(0); if (!function || !*function) { - /* don't allow undo in the middle of an operation */ - if (conf_core.editor.mode != PCB_MODE_POLYGON_HOLE && pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) - return 1; - if (pcb_crosshair.AttachedBox.State != PCB_CH_STATE_FIRST && conf_core.editor.mode != PCB_MODE_ARC) - return 1; + pcb_bool undo = pcb_true; /* undo the last operation */ pcb_notify_crosshair_change(pcb_false); - if ((conf_core.editor.mode == PCB_MODE_POLYGON || conf_core.editor.mode == PCB_MODE_POLYGON_HOLE) && pcb_crosshair.AttachedPolygon.PointN) { - pcb_polygon_go_to_prev_point(); - pcb_notify_crosshair_change(pcb_true); - return 0; + if (conf_core.editor.mode == PCB_MODE_POLYGON) { + undo = pcb_tool_poly_undo_act(); } + if (conf_core.editor.mode == PCB_MODE_POLYGON_HOLE) { + undo = pcb_tool_polyhole_undo_act(); + } /* move anchor point if undoing during line creation */ if (conf_core.editor.mode == PCB_MODE_LINE) { - if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_SECOND) { - if (conf_core.editor.auto_drc) - pcb_undo(pcb_true); /* undo the connection find */ - pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; - pcb_route_reset(&pcb_crosshair.Route); - pcb_crosshair_set_local_ref(0, 0, pcb_false); - pcb_notify_crosshair_change(pcb_true); - return 0; - } - if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_THIRD) { - int type; - void *ptr1, *ptr3, *ptrtmp; - pcb_line_t *ptr2; - /* this search is guaranteed to succeed */ - pcb_search_obj_by_location(PCB_TYPE_LINE | PCB_TYPE_RATLINE, &ptr1, - &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, 0); - ptr2 = (pcb_line_t *) ptrtmp; - - /* save both ends of line */ - pcb_crosshair.AttachedLine.Point2.X = ptr2->Point1.X; - pcb_crosshair.AttachedLine.Point2.Y = ptr2->Point1.Y; - if ((type = pcb_undo(pcb_true))) - pcb_board_set_changed_flag(pcb_true); - /* check that the undo was of the right type */ - if ((type & PCB_UNDO_CREATE) == 0) { - /* wrong undo type, restore anchor points */ - pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.AttachedLine.Point1.X; - pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.AttachedLine.Point1.Y; - pcb_notify_crosshair_change(pcb_true); - return 0; - } - /* move to new anchor */ - pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X; - pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y; - /* check if an intermediate point was removed */ - if (type & PCB_UNDO_REMOVE) { - /* this search should find the restored line */ - pcb_search_obj_by_location(PCB_TYPE_LINE | PCB_TYPE_RATLINE, &ptr1, - &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y, 0); - ptr2 = (pcb_line_t *) ptrtmp; - if (conf_core.editor.auto_drc) { - /* undo loses PCB_FLAG_FOUND */ - PCB_FLAG_SET(PCB_FLAG_FOUND, ptr2); - pcb_line_invalidate_draw(CURRENT, ptr2); - } - pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = ptr2->Point2.X; - pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = ptr2->Point2.Y; - } - pcb_crosshair_grid_fit(pcb_crosshair.X, pcb_crosshair.Y); - pcb_adjust_attached_objects(); - if (--pcb_added_lines == 0) { - pcb_crosshair.AttachedLine.State = PCB_CH_STATE_SECOND; - lastLayer = CURRENT; - } - else { - /* this search is guaranteed to succeed too */ - pcb_search_obj_by_location(PCB_TYPE_LINE | PCB_TYPE_RATLINE, &ptr1, - &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, 0); - ptr2 = (pcb_line_t *) ptrtmp; - lastLayer = (pcb_layer_t *) ptr1; - } - pcb_notify_crosshair_change(pcb_true); - return 0; - } + undo = pcb_tool_line_undo_act(); } if (conf_core.editor.mode == PCB_MODE_ARC) { - if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_SECOND) { - pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; - pcb_notify_crosshair_change(pcb_true); - return 0; - } - if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_THIRD) { - void *ptr1, *ptr2, *ptr3; - /* guaranteed to succeed */ - pcb_search_obj_by_location(PCB_TYPE_ARC, &ptr1, &ptr2, &ptr3, - pcb_crosshair.AttachedBox.Point1.X, pcb_crosshair.AttachedBox.Point1.Y, 0); - pcb_arc_get_end((pcb_arc_t *) ptr2, 0, &pcb_crosshair.AttachedBox.Point2.X, &pcb_crosshair.AttachedBox.Point2.Y); - pcb_crosshair.AttachedBox.Point1.X = pcb_crosshair.AttachedBox.Point2.X; - pcb_crosshair.AttachedBox.Point1.Y = pcb_crosshair.AttachedBox.Point2.Y; - pcb_adjust_attached_objects(); - if (--pcb_added_lines == 0) - pcb_crosshair.AttachedBox.State = PCB_CH_STATE_SECOND; - } + undo = pcb_tool_arc_undo_act(); } + if (conf_core.editor.mode == PCB_MODE_COPY) + undo = pcb_tool_copy_undo_act(); + if (conf_core.editor.mode == PCB_MODE_MOVE) + undo = pcb_tool_move_undo_act(); + if (conf_core.editor.mode == PCB_MODE_RECTANGLE) + undo = pcb_tool_rectangle_undo_act(); + if (conf_core.editor.mode == PCB_MODE_INSERT_POINT) + undo = pcb_tool_insert_undo_act(); /* undo the last destructive operation */ - if (pcb_undo(pcb_true)) - pcb_board_set_changed_flag(pcb_true); + if (undo) + if (pcb_undo(pcb_true)) + pcb_board_set_changed_flag(pcb_true); } else if (function) { switch (pcb_funchash_get(function, NULL)) {