Index: undo.c =================================================================== --- undo.c (revision 10661) +++ undo.c (revision 10662) @@ -55,6 +55,7 @@ #include "rotate.h" #include "search.h" #include "undo.h" +#include "undo_old.h" #include "flag_str.h" #include "conf_core.h" #include "compat_misc.h" @@ -66,81 +67,12 @@ #define STEP_REMOVELIST 500 #define STEP_UNDOLIST 500 - static pcb_bool between_increment_and_restore = pcb_false; static pcb_bool added_undo_between_increment_and_restore = pcb_false; -/* --------------------------------------------------------------------------- - * some local data types - */ -typedef struct { /* information about a change command */ - char *Name; -} ChangeNameType, *ChangeNameTypePtr; +#include "undo_old_str.h" -typedef struct { /* information about a move command */ - pcb_coord_t DX, DY; /* movement vector */ -} MoveType, *MoveTypePtr; - -typedef struct { /* information about removed polygon points */ - pcb_coord_t X, Y; /* data */ - int ID; - pcb_cardinal_t Index; /* index in a polygons array of points */ - pcb_bool last_in_contour; /* Whether the point was the last in its contour */ -} RemovedPointType, *RemovedPointTypePtr; - -typedef struct { /* information about rotation */ - pcb_coord_t CenterX, CenterY; /* center of rotation */ - pcb_cardinal_t Steps; /* number of steps */ -} RotateType, *RotateTypePtr; - -typedef struct { /* information about moves between layers */ - pcb_cardinal_t OriginalLayer; /* the index of the original layer */ -} MoveToLayer; - -typedef struct { /* information about layer changes */ - int old_index; - int new_index; -} LayerChangeType, *LayerChangeTypePtr; - -typedef struct { /* information about poly clear/restore */ - pcb_bool Clear; /* pcb_true was clear, pcb_false was restore */ - pcb_layer_t *Layer; -} ClearPolyType, *ClearPolyTypePtr; - -typedef struct { - pcb_angle_t angle[2]; -} AngleChangeType; - -typedef struct { /* information about netlist lib changes */ - pcb_lib_t *old; - pcb_lib_t *lib; -} NetlistChangeType, *NetlistChangeTypePtr; - -typedef struct { /* holds information about an operation */ - int Serial, /* serial number of operation */ - Type, /* type of operation */ - Kind, /* type of object with given ID */ - ID; /* object ID */ - union { /* some additional information */ - ChangeNameType ChangeName; - MoveType Move; - RemovedPointType RemovedPoint; - RotateType Rotate; - MoveToLayer MoveToLayer; - pcb_flag_t Flags; - pcb_coord_t Size; - LayerChangeType LayerChange; - ClearPolyType ClearPoly; - NetlistChangeType NetlistChange; - long int CopyID; - AngleChangeType AngleChange; - } Data; -} UndoListType, *UndoListTypePtr; - -/* --------------------------------------------------------------------------- - * some local variables - */ -static pcb_data_t *RemoveList = NULL; /* list of removed objects */ +pcb_data_t *RemoveList = NULL; /* list of removed objects */ static UndoListTypePtr UndoList = NULL; /* list of operations */ static int Serial = 1, /* serial number */ SavedSerial; @@ -147,60 +79,14 @@ static size_t UndoN, RedoN, /* number of entries */ UndoMax; static pcb_bool Locked = pcb_false; /* do not add entries if */ -static pcb_bool andDraw = pcb_true; +pcb_bool pcb_undo_and_draw = pcb_true; /* flag is set; prevents from */ /* infinite loops */ /* --------------------------------------------------------------------------- - * some local prototypes - */ -static void DrawRecoveredObject(int, void *, void *, void *); -static pcb_bool UndoRotate(UndoListTypePtr); -static pcb_bool UndoChangeName(UndoListTypePtr); -static pcb_bool UndoCopyOrCreate(UndoListTypePtr); -static pcb_bool UndoMove(UndoListTypePtr); -static pcb_bool UndoRemove(UndoListTypePtr); -static pcb_bool UndoRemovePoint(UndoListTypePtr); -static pcb_bool UndoInsertPoint(UndoListTypePtr); -static pcb_bool UndoRemoveContour(UndoListTypePtr); -static pcb_bool UndoInsertContour(UndoListTypePtr); -static pcb_bool UndoMoveToLayer(UndoListTypePtr); -static pcb_bool UndoFlag(UndoListTypePtr); -static pcb_bool UndoMirror(UndoListTypePtr); -static pcb_bool UndoOtherSide(UndoListTypePtr); -static pcb_bool UndoChangeSize(UndoListTypePtr); -static pcb_bool UndoChange2ndSize(UndoListTypePtr); -static pcb_bool UndoChangeAngles(UndoListTypePtr); -static pcb_bool UndoChangeRadii(UndoListTypePtr); -static pcb_bool UndoChangeClearSize(UndoListTypePtr); -static pcb_bool UndoChangeMaskSize(UndoListTypePtr); -static pcb_bool UndoClearPoly(UndoListTypePtr); -static int PerformUndo(UndoListTypePtr); - -static pcb_undo_old_free(UndoListTypePtr ptr) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - switch (ptr->Type) { - case PCB_UNDO_CHANGENAME: - case PCB_UNDO_CHANGEPINNUM: - free(ptr->Data.ChangeName.Name); - break; - case PCB_UNDO_REMOVE: - type = pcb_search_obj_by_id(RemoveList, &ptr1, &ptr2, &ptr3, ptr->ID, ptr->Kind); - if (type != PCB_TYPE_NONE) - pcb_destroy_object(RemoveList, type, ptr1, ptr2, ptr3); - break; - default: - break; - } -} - -/* --------------------------------------------------------------------------- * adds a command plus some data to the undo list */ -static UndoListTypePtr GetUndoSlot(int CommandType, int ID, int Kind, size_t item_len) +void *GetUndoSlot(int CommandType, int ID, int Kind, size_t item_len) { UndoListTypePtr ptr; size_t limit = ((size_t)conf_core.editor.undo_warning_size) * 1024; @@ -245,654 +131,6 @@ } /* --------------------------------------------------------------------------- - * redraws the recovered object - */ -static void DrawRecoveredObject(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - if (Type & (PCB_TYPE_LINE | PCB_TYPE_TEXT | PCB_TYPE_POLYGON | PCB_TYPE_ARC)) { - pcb_layer_t *layer; - - layer = LAYER_PTR(pcb_layer_id(RemoveList, (pcb_layer_t *) Ptr1)); - pcb_draw_obj(Type, (void *) layer, Ptr2); - } - else - pcb_draw_obj(Type, Ptr1, Ptr2); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a 'rotate' operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoRotate(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - pcb_obj_rotate90(type, ptr1, ptr2, ptr3, - Entry->Data.Rotate.CenterX, Entry->Data.Rotate.CenterY, (4 - Entry->Data.Rotate.Steps) & 0x03); - Entry->Data.Rotate.Steps = (4 - Entry->Data.Rotate.Steps) & 0x03; - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a clear/restore poly operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoClearPoly(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - if (Entry->Data.ClearPoly.Clear) - pcb_poly_restore_to_poly(PCB->Data, type, Entry->Data.ClearPoly.Layer, ptr3); - else - pcb_poly_clear_from_poly(PCB->Data, type, Entry->Data.ClearPoly.Layer, ptr3); - Entry->Data.ClearPoly.Clear = !Entry->Data.ClearPoly.Clear; - return pcb_true; - } - return pcb_false; -} - -/* --------------------------------------------------------------------------- - * recovers an object from a 'change name' operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoChangeName(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - Entry->Data.ChangeName.Name = (char *) (pcb_chg_obj_name(type, ptr1, ptr2, ptr3, Entry->Data.ChangeName.Name)); - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a 'change oinnum' operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoChangePinnum(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - Entry->Data.ChangeName.Name = (char *) (pcb_chg_obj_pinnum(type, ptr1, ptr2, ptr3, Entry->Data.ChangeName.Name)); - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a 2ndSize change operation - */ -static pcb_bool UndoChange2ndSize(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - pcb_coord_t swap; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - swap = ((pcb_pin_t *) ptr2)->DrillingHole; - if (andDraw) - pcb_erase_obj(type, ptr1, ptr2); - ((pcb_pin_t *) ptr2)->DrillingHole = Entry->Data.Size; - Entry->Data.Size = swap; - pcb_draw_obj(type, ptr1, ptr2); - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a ChangeAngles change operation - */ -static pcb_bool UndoChangeAngles(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - double old_sa, old_da; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type == PCB_TYPE_ARC) { - pcb_layer_t *Layer = (pcb_layer_t *) ptr1; - pcb_arc_t *a = (pcb_arc_t *) ptr2; - pcb_r_delete_entry(Layer->arc_tree, (pcb_box_t *) a); - old_sa = a->StartAngle; - old_da = a->Delta; - if (andDraw) - pcb_erase_obj(type, Layer, a); - a->StartAngle = Entry->Data.AngleChange.angle[0]; - a->Delta = Entry->Data.AngleChange.angle[1]; - pcb_arc_bbox(a); - pcb_r_insert_entry(Layer->arc_tree, (pcb_box_t *) a, 0); - Entry->Data.AngleChange.angle[0] = old_sa; - Entry->Data.AngleChange.angle[1] = old_da; - pcb_draw_obj(type, ptr1, a); - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a ChangeRadii change operation - */ -static pcb_bool UndoChangeRadii(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - pcb_coord_t old_w, old_h; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type == PCB_TYPE_ARC) { - pcb_layer_t *Layer = (pcb_layer_t *) ptr1; - pcb_arc_t *a = (pcb_arc_t *) ptr2; - pcb_r_delete_entry(Layer->arc_tree, (pcb_box_t *) a); - old_w = a->Width; - old_h = a->Height; - if (andDraw) - pcb_erase_obj(type, Layer, a); - a->Width = Entry->Data.Move.DX; - a->Height = Entry->Data.Move.DY; - pcb_arc_bbox(a); - pcb_r_insert_entry(Layer->arc_tree, (pcb_box_t *) a, 0); - Entry->Data.Move.DX = old_w; - Entry->Data.Move.DY = old_h; - pcb_draw_obj(type, ptr1, a); - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a clearance size change operation - */ -static pcb_bool UndoChangeClearSize(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - pcb_coord_t swap; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - swap = ((pcb_pin_t *) ptr2)->Clearance; - pcb_poly_restore_to_poly(PCB->Data, type, ptr1, ptr2); - if (andDraw) - pcb_erase_obj(type, ptr1, ptr2); - ((pcb_pin_t *) ptr2)->Clearance = Entry->Data.Size; - pcb_poly_clear_from_poly(PCB->Data, type, ptr1, ptr2); - Entry->Data.Size = swap; - if (andDraw) - pcb_draw_obj(type, ptr1, ptr2); - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a mask size change operation - */ -static pcb_bool UndoChangeMaskSize(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - pcb_coord_t swap; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type & (PCB_TYPE_VIA | PCB_TYPE_PIN | PCB_TYPE_PAD)) { - swap = (type == PCB_TYPE_PAD ? ((pcb_pad_t *) ptr2)->Mask : ((pcb_pin_t *) ptr2)->Mask); - if (andDraw) - pcb_erase_obj(type, ptr1, ptr2); - if (type == PCB_TYPE_PAD) - ((pcb_pad_t *) ptr2)->Mask = Entry->Data.Size; - else - ((pcb_pin_t *) ptr2)->Mask = Entry->Data.Size; - Entry->Data.Size = swap; - if (andDraw) - pcb_draw_obj(type, ptr1, ptr2); - return (pcb_true); - } - return (pcb_false); -} - - -/* --------------------------------------------------------------------------- - * recovers an object from a Size change operation - */ -static pcb_bool UndoChangeSize(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3, *ptr1e; - int type; - pcb_coord_t swap; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type == PCB_TYPE_ELEMENT_NAME) - ptr1e = NULL; - else - ptr1e = ptr1; - - if (type != PCB_TYPE_NONE) { - /* Wow! can any object be treated as a pin type for size change?? */ - /* pins, vias, lines, and arcs can. Text can't but it has it's own mechanism */ - swap = ((pcb_pin_t *) ptr2)->Thickness; - pcb_poly_restore_to_poly(PCB->Data, type, ptr1, ptr2); - if ((andDraw) && (ptr1e != NULL)) - pcb_erase_obj(type, ptr1e, ptr2); - ((pcb_pin_t *) ptr2)->Thickness = Entry->Data.Size; - Entry->Data.Size = swap; - pcb_poly_clear_from_poly(PCB->Data, type, ptr1, ptr2); - if (andDraw) - pcb_draw_obj(type, ptr1, ptr2); - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a FLAG change operation - */ -static pcb_bool UndoFlag(UndoListTypePtr Entry) -{ - void *ptr1, *ptr1e, *ptr2, *ptr3; - int type; - pcb_flag_t swap; - int must_redraw; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - pcb_flag_t f1, f2; - pcb_pin_t *pin = (pcb_pin_t *) ptr2; - - if ((type == PCB_TYPE_ELEMENT) || (type == PCB_TYPE_ELEMENT_NAME)) - ptr1e = NULL; - else - ptr1e = ptr1; - - swap = pin->Flags; - - must_redraw = 0; - f1 = pcb_flag_mask(pin->Flags, ~DRAW_FLAGS); - f2 = pcb_flag_mask(Entry->Data.Flags, ~DRAW_FLAGS); - - if (!PCB_FLAG_EQ(f1, f2)) - must_redraw = 1; - - if (andDraw && must_redraw && (ptr1e != NULL)) - pcb_erase_obj(type, ptr1e, ptr2); - - pin->Flags = Entry->Data.Flags; - - Entry->Data.Flags = swap; - - if (andDraw && must_redraw) - pcb_draw_obj(type, ptr1, ptr2); - return (pcb_true); - } - pcb_message(PCB_MSG_ERROR, "hace Internal error: Can't find ID %d type %08x\n", Entry->ID, Entry->Kind); - pcb_message(PCB_MSG_ERROR, "for UndoFlag Operation. Previous flags: %s\n", pcb_strflg_f2s(Entry->Data.Flags, 0)); - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a mirror operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoMirror(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type == PCB_TYPE_ELEMENT) { - pcb_element_t *element = (pcb_element_t *) ptr3; - if (andDraw) - pcb_elem_invalidate_erase(element); - pcb_element_mirror(PCB->Data, element, Entry->Data.Move.DY); - if (andDraw) - pcb_elem_invalidate_draw(element); - return (pcb_true); - } - pcb_message(PCB_MSG_ERROR, "hace Internal error: UndoMirror on object type %d\n", type); - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers a subc from an other-side operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoOtherSide(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type == PCB_TYPE_SUBC) { - pcb_subc_t *subc = (pcb_subc_t *)ptr3; - if (andDraw) - EraseSubc(subc); - pcb_subc_change_side(subc, Entry->Data.Move.DY); - if (andDraw) - DrawSubc(subc); - return (pcb_true); - } - pcb_message(PCB_MSG_ERROR, "hace Internal error: UndoOtherside on object type %x\n", type); - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a 'copy' or 'create' operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoCopyOrCreate(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - if (!RemoveList) - RemoveList = pcb_buffer_new(NULL); - if (andDraw) - pcb_erase_obj(type, ptr1, ptr2); - /* in order to make this re-doable we move it to the RemoveList */ - pcb_move_obj_to_buffer(PCB, RemoveList, PCB->Data, type, ptr1, ptr2, ptr3); - Entry->Type = PCB_UNDO_REMOVE; - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers an object from a 'move' operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoMove(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - pcb_move_obj(type, ptr1, ptr2, ptr3, -Entry->Data.Move.DX, -Entry->Data.Move.DY); - Entry->Data.Move.DX *= -1; - Entry->Data.Move.DY *= -1; - return (pcb_true); - } - return (pcb_false); -} - -/* ---------------------------------------------------------------------- - * recovers an object from a 'remove' operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoRemove(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(RemoveList, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - if (andDraw) - DrawRecoveredObject(type, ptr1, ptr2, ptr3); - pcb_move_obj_to_buffer(PCB, PCB->Data, RemoveList, type, ptr1, ptr2, ptr3); - Entry->Type = PCB_UNDO_CREATE; - return (pcb_true); - } - return (pcb_false); -} - -/* ---------------------------------------------------------------------- - * recovers an object from a 'move to another layer' operation - * returns pcb_true if anything has been recovered - */ -static pcb_bool UndoMoveToLayer(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - int type; - pcb_layer_id_t swap; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); - if (type != PCB_TYPE_NONE) { - swap = pcb_layer_id(PCB->Data, (pcb_layer_t *) ptr1); - pcb_move_obj_to_layer(type, ptr1, ptr2, ptr3, LAYER_PTR(Entry->Data.MoveToLayer.OriginalLayer), pcb_true); - Entry->Data.MoveToLayer.OriginalLayer = swap; - return (pcb_true); - } - return (pcb_false); -} - -/* --------------------------------------------------------------------------- - * recovers a removed polygon point - * returns pcb_true on success - */ -static pcb_bool UndoRemovePoint(UndoListTypePtr Entry) -{ - pcb_layer_t *layer; - pcb_polygon_t *polygon; - void *ptr3; - int type; - - /* lookup entry (polygon not point was saved) by it's ID */ - assert(Entry->Kind == PCB_TYPE_POLYGON); - type = pcb_search_obj_by_id(PCB->Data, (void **) &layer, (void **) &polygon, &ptr3, Entry->ID, Entry->Kind); - switch (type) { - case PCB_TYPE_POLYGON: /* restore the removed point */ - { - /* recover the point */ - if (andDraw && layer->meta.real.vis) - pcb_poly_invalidate_erase(polygon); - pcb_insert_point_in_object(PCB_TYPE_POLYGON, layer, polygon, - &Entry->Data.RemovedPoint.Index, - Entry->Data.RemovedPoint.X, - Entry->Data.RemovedPoint.Y, pcb_true, Entry->Data.RemovedPoint.last_in_contour); - - polygon->Points[Entry->Data.RemovedPoint.Index].ID = Entry->Data.RemovedPoint.ID; - if (andDraw && layer->meta.real.vis) - pcb_poly_invalidate_draw(layer, polygon); - Entry->Type = PCB_UNDO_INSERT_POINT; - Entry->ID = Entry->Data.RemovedPoint.ID; - Entry->Kind = PCB_TYPE_POLYGON_POINT; - return (pcb_true); - } - - default: - return (pcb_false); - } -} - -/* --------------------------------------------------------------------------- - * recovers an inserted polygon point - * returns pcb_true on success - */ -static pcb_bool UndoInsertPoint(UndoListTypePtr Entry) -{ - pcb_layer_t *layer; - pcb_polygon_t *polygon; - pcb_point_t *pnt; - int type; - pcb_cardinal_t point_idx; - pcb_cardinal_t hole; - pcb_bool last_in_contour = pcb_false; - - assert(Entry->Kind == PCB_TYPE_POLYGON_POINT); - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(PCB->Data, (void **) &layer, (void **) &polygon, (void **) &pnt, Entry->ID, Entry->Kind); - switch (type) { - case PCB_TYPE_POLYGON_POINT: /* removes an inserted polygon point */ - { - if (andDraw && layer->meta.real.vis) - pcb_poly_invalidate_erase(polygon); - - /* Check whether this point was at the end of its contour. - * If so, we need to flag as such when re-adding the point - * so it goes back in the correct place - */ - point_idx = pcb_poly_point_idx(polygon, pnt); - for (hole = 0; hole < polygon->HoleIndexN; hole++) - if (point_idx == polygon->HoleIndex[hole] - 1) - last_in_contour = pcb_true; - if (point_idx == polygon->PointN - 1) - last_in_contour = pcb_true; - Entry->Data.RemovedPoint.last_in_contour = last_in_contour; - - Entry->Data.RemovedPoint.X = pnt->X; - Entry->Data.RemovedPoint.Y = pnt->Y; - Entry->Data.RemovedPoint.ID = pnt->ID; - Entry->ID = polygon->ID; - Entry->Kind = PCB_TYPE_POLYGON; - Entry->Type = PCB_UNDO_REMOVE_POINT; - Entry->Data.RemovedPoint.Index = point_idx; - pcb_destroy_object(PCB->Data, PCB_TYPE_POLYGON_POINT, layer, polygon, pnt); - if (andDraw && layer->meta.real.vis) - pcb_poly_invalidate_draw(layer, polygon); - return (pcb_true); - } - - default: - return (pcb_false); - } -} - -static pcb_bool UndoSwapCopiedObject(UndoListTypePtr Entry) -{ - void *ptr1, *ptr2, *ptr3; - void *ptr1b, *ptr2b, *ptr3b; - pcb_any_obj_t *obj, *obj2; - int type; - long int swap_id; - - /* lookup entry by it's ID */ - type = pcb_search_obj_by_id(RemoveList, &ptr1, &ptr2, &ptr3, Entry->Data.CopyID, Entry->Kind); - if (type == PCB_TYPE_NONE) - return pcb_false; - - type = pcb_search_obj_by_id(PCB->Data, &ptr1b, &ptr2b, &ptr3b, Entry->ID, Entry->Kind); - if (type == PCB_TYPE_NONE) - return pcb_false; - - obj = (pcb_any_obj_t *) ptr2; - obj2 = (pcb_any_obj_t *) ptr2b; - - swap_id = obj->ID; - obj->ID = obj2->ID; - obj2->ID = swap_id; - - pcb_move_obj_to_buffer(PCB, RemoveList, PCB->Data, type, ptr1b, ptr2b, ptr3b); - - if (andDraw) - DrawRecoveredObject(Entry->Kind, ptr1, ptr2, ptr3); - - obj = (pcb_any_obj_t *) pcb_move_obj_to_buffer(PCB, PCB->Data, RemoveList, type, ptr1, ptr2, ptr3); - if (Entry->Kind == PCB_TYPE_POLYGON) - pcb_poly_init_clip(PCB->Data, (pcb_layer_t *) ptr1b, (pcb_polygon_t *) obj); - return (pcb_true); -} - -/* --------------------------------------------------------------------------- - * recovers an removed polygon point - * returns pcb_true on success - */ -static pcb_bool UndoRemoveContour(UndoListTypePtr Entry) -{ - assert(Entry->Kind == PCB_TYPE_POLYGON); - return UndoSwapCopiedObject(Entry); -} - -/* --------------------------------------------------------------------------- - * recovers an inserted polygon point - * returns pcb_true on success - */ -static pcb_bool UndoInsertContour(UndoListTypePtr Entry) -{ - assert(Entry->Kind == PCB_TYPE_POLYGON); - return UndoSwapCopiedObject(Entry); -} - -/* --------------------------------------------------------------------------- - * undo a layer change - * returns pcb_true on success - */ -static pcb_bool UndoLayerMove(UndoListTypePtr Entry) -{ - LayerChangeTypePtr l = &Entry->Data.LayerChange; - int tmp; - - tmp = l->new_index; - l->new_index = l->old_index; - l->old_index = tmp; - - if (pcb_layer_move(l->old_index, l->new_index, -1)) - return pcb_false; - else - return pcb_true; -} - -/* --------------------------------------------------------------------------- - * undo a netlist change - * returns pcb_true on success - */ -static pcb_bool UndoNetlistChange(UndoListTypePtr Entry) -{ - NetlistChangeTypePtr l = &Entry->Data.NetlistChange; - unsigned int i, j; - pcb_lib_t *lib, *saved; - - lib = l->lib; - saved = l->old; - - /* iterate over each net */ - for (i = 0; i < lib->MenuN; i++) { - free(lib->Menu[i].Name); - free(lib->Menu[i].directory); - free(lib->Menu[i].Style); - - /* iterate over each pin on the net */ - for (j = 0; j < lib->Menu[i].EntryN; j++) { - if (!lib->Menu[i].Entry[j].ListEntry_dontfree) - free((char*)lib->Menu[i].Entry[j].ListEntry); - - free((char*)lib->Menu[i].Entry[j].Package); - free((char*)lib->Menu[i].Entry[j].Value); - free((char*)lib->Menu[i].Entry[j].Description); - } - } - - free(lib->Menu); - - *lib = *saved; - - pcb_netlist_changed(0); - return pcb_true; -} - -/* --------------------------------------------------------------------------- * undo of any 'hard to recover' operation * * returns the bitfield for the types of operations that were undone @@ -907,7 +145,7 @@ unique = conf_core.editor.unique_names; conf_force_set_bool(conf_core.editor.unique_names, 0); - andDraw = draw; + pcb_undo_and_draw = draw; if (Serial == 0) { pcb_message(PCB_MSG_ERROR, _("ERROR: Attempt to pcb_undo() with Serial == 0\n" " Please save your work and report this bug.\n")); @@ -942,7 +180,7 @@ /* Loop over all entries with the correct serial number */ for (; UndoN && ptr->Serial == Serial; ptr--, UndoN--, RedoN++) { - int undid = PerformUndo(ptr); + int undid = pcb_undo_old_perform(ptr); if (undid == 0) error_undoing = pcb_true; Types |= undid; @@ -953,7 +191,7 @@ if (error_undoing) pcb_message(PCB_MSG_ERROR, _("ERROR: Failed to undo some operations\n")); - if (Types && andDraw) + if (Types && pcb_undo_and_draw) pcb_draw(); /* restore the unique flag setting */ @@ -962,127 +200,6 @@ return Types; } -static int PerformUndo(UndoListTypePtr ptr) -{ - switch (ptr->Type) { - case PCB_UNDO_CHANGENAME: - if (UndoChangeName(ptr)) - return (PCB_UNDO_CHANGENAME); - break; - - case PCB_UNDO_CHANGEPINNUM: - if (UndoChangePinnum(ptr)) - return (PCB_UNDO_CHANGEPINNUM); - break; - - case PCB_UNDO_CREATE: - if (UndoCopyOrCreate(ptr)) - return (PCB_UNDO_CREATE); - break; - - case PCB_UNDO_MOVE: - if (UndoMove(ptr)) - return (PCB_UNDO_MOVE); - break; - - case PCB_UNDO_REMOVE: - if (UndoRemove(ptr)) - return (PCB_UNDO_REMOVE); - break; - - case PCB_UNDO_REMOVE_POINT: - if (UndoRemovePoint(ptr)) - return (PCB_UNDO_REMOVE_POINT); - break; - - case PCB_UNDO_INSERT_POINT: - if (UndoInsertPoint(ptr)) - return (PCB_UNDO_INSERT_POINT); - break; - - case PCB_UNDO_REMOVE_CONTOUR: - if (UndoRemoveContour(ptr)) - return (PCB_UNDO_REMOVE_CONTOUR); - break; - - case PCB_UNDO_INSERT_CONTOUR: - if (UndoInsertContour(ptr)) - return (PCB_UNDO_INSERT_CONTOUR); - break; - - case PCB_UNDO_ROTATE: - if (UndoRotate(ptr)) - return (PCB_UNDO_ROTATE); - break; - - case PCB_UNDO_CLEAR: - if (UndoClearPoly(ptr)) - return (PCB_UNDO_CLEAR); - break; - - case PCB_UNDO_MOVETOLAYER: - if (UndoMoveToLayer(ptr)) - return (PCB_UNDO_MOVETOLAYER); - break; - - case PCB_UNDO_FLAG: - if (UndoFlag(ptr)) - return (PCB_UNDO_FLAG); - break; - - case PCB_UNDO_CHANGESIZE: - if (UndoChangeSize(ptr)) - return (PCB_UNDO_CHANGESIZE); - break; - - case PCB_UNDO_CHANGECLEARSIZE: - if (UndoChangeClearSize(ptr)) - return (PCB_UNDO_CHANGECLEARSIZE); - break; - - case PCB_UNDO_CHANGEMASKSIZE: - if (UndoChangeMaskSize(ptr)) - return (PCB_UNDO_CHANGEMASKSIZE); - break; - - case PCB_UNDO_CHANGE2NDSIZE: - if (UndoChange2ndSize(ptr)) - return (PCB_UNDO_CHANGE2NDSIZE); - break; - - case PCB_UNDO_CHANGEANGLES: - if (UndoChangeAngles(ptr)) - return (PCB_UNDO_CHANGEANGLES); - break; - - case PCB_UNDO_CHANGERADII: - if (UndoChangeRadii(ptr)) - return (PCB_UNDO_CHANGERADII); - break; - - case PCB_UNDO_LAYERMOVE: - if (UndoLayerMove(ptr)) - return (PCB_UNDO_LAYERMOVE); - break; - - case PCB_UNDO_NETLISTCHANGE: - if (UndoNetlistChange(ptr)) - return (PCB_UNDO_NETLISTCHANGE); - break; - - case PCB_UNDO_MIRROR: - if (UndoMirror(ptr)) - return (PCB_UNDO_MIRROR); - break; - - case PCB_UNDO_OTHERSIDE: - if (UndoOtherSide(ptr)) - return (PCB_UNDO_OTHERSIDE); - break; - } - return 0; -} - /* --------------------------------------------------------------------------- * redo of any 'hard to recover' operation * @@ -1094,7 +211,7 @@ int Types = 0; pcb_bool error_undoing = pcb_false; - andDraw = draw; + pcb_undo_and_draw = draw; if (RedoN == 0) { pcb_message(PCB_MSG_INFO, _("Nothing to redo. Perhaps changes have been made since last undo\n")); @@ -1122,7 +239,7 @@ /* and loop over all entries with the correct serial number */ for (; RedoN && ptr->Serial == Serial; ptr++, UndoN++, RedoN--) { - int undid = PerformUndo(ptr); + int undid = pcb_undo_old_perform(ptr); if (undid == 0) error_undoing = pcb_true; Types |= undid; @@ -1136,7 +253,7 @@ if (error_undoing) pcb_message(PCB_MSG_ERROR, _("ERROR: Failed to redo some operations\n")); - if (Types && andDraw) + if (Types && pcb_undo_and_draw) pcb_draw(); return Types; @@ -1211,439 +328,6 @@ } /* --------------------------------------------------------------------------- - * adds an object to the list of clearpoly objects - */ -void pcb_undo_add_obj_to_clear_poly(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_bool clear) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CLEAR, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.ClearPoly.Clear = clear; - undo->Data.ClearPoly.Layer = (pcb_layer_t *) Ptr1; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of mirrored objects - */ -void pcb_undo_add_obj_to_mirror(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_coord_t yoff) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_MIRROR, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.Move.DY = yoff; - } -} - -/* --------------------------------------------------------------------------- - * adds an subc to the list of objects tossed to the other side - */ -void pcb_undo_add_subc_to_otherside(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_coord_t yoff) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_OTHERSIDE, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.Move.DY = yoff; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of rotated objects - */ -void pcb_undo_add_obj_to_rotate(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_coord_t CenterX, pcb_coord_t CenterY, pcb_uint8_t Steps) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_ROTATE, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.Rotate.CenterX = CenterX; - undo->Data.Rotate.CenterY = CenterY; - undo->Data.Rotate.Steps = Steps; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of removed objects and removes it from - * the current PCB - */ -void pcb_undo_move_obj_to_remove(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - if (Locked) - return; - - if (!RemoveList) - RemoveList = pcb_buffer_new(NULL); - - GetUndoSlot(PCB_UNDO_REMOVE, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - pcb_move_obj_to_buffer(PCB, RemoveList, PCB->Data, Type, Ptr1, Ptr2, Ptr3); -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of removed polygon/... points - */ -void pcb_undo_add_obj_to_remove_point(int Type, void *Ptr1, void *Ptr2, pcb_cardinal_t index) -{ - UndoListTypePtr undo; - pcb_polygon_t *polygon = (pcb_polygon_t *) Ptr2; - pcb_cardinal_t hole; - pcb_bool last_in_contour = pcb_false; - - if (!Locked) { - switch (Type) { - case PCB_TYPE_POLYGON_POINT: - { - /* save the ID of the parent object; else it will be - * impossible to recover the point - */ - undo = GetUndoSlot(PCB_UNDO_REMOVE_POINT, PCB_OBJECT_ID(polygon), PCB_TYPE_POLYGON, sizeof(UndoListType)); - undo->Data.RemovedPoint.X = polygon->Points[index].X; - undo->Data.RemovedPoint.Y = polygon->Points[index].Y; - undo->Data.RemovedPoint.ID = polygon->Points[index].ID; - undo->Data.RemovedPoint.Index = index; - - /* Check whether this point was at the end of its contour. - * If so, we need to flag as such when re-adding the point - * so it goes back in the correct place - */ - for (hole = 0; hole < polygon->HoleIndexN; hole++) - if (index == polygon->HoleIndex[hole] - 1) - last_in_contour = pcb_true; - if (index == polygon->PointN - 1) - last_in_contour = pcb_true; - undo->Data.RemovedPoint.last_in_contour = last_in_contour; - } - break; - } - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of inserted polygon/... points - */ -void pcb_undo_add_obj_to_insert_point(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - if (!Locked) - GetUndoSlot(PCB_UNDO_INSERT_POINT, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); -} - -static void CopyObjectToUndoList(int undo_type, int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - UndoListTypePtr undo; - pcb_any_obj_t *copy; - - if (Locked) - return; - - if (!RemoveList) - RemoveList = pcb_buffer_new(NULL); - - undo = GetUndoSlot(undo_type, PCB_OBJECT_ID(Ptr2), Type, sizeof(UndoListType)); - copy = (pcb_any_obj_t *) pcb_copy_obj_to_buffer(PCB, RemoveList, PCB->Data, Type, Ptr1, Ptr2, Ptr3); - undo->Data.CopyID = copy->ID; -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of removed contours - * (Actually just takes a copy of the whole polygon to restore) - */ -void pcb_undo_add_obj_to_remove_contour(int Type, pcb_layer_t * Layer, pcb_polygon_t * Polygon) -{ - CopyObjectToUndoList(PCB_UNDO_REMOVE_CONTOUR, Type, Layer, Polygon, NULL); -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of insert contours - * (Actually just takes a copy of the whole polygon to restore) - */ -void pcb_undo_add_obj_to_insert_contour(int Type, pcb_layer_t * Layer, pcb_polygon_t * Polygon) -{ - CopyObjectToUndoList(PCB_UNDO_INSERT_CONTOUR, Type, Layer, Polygon, NULL); -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of moved objects - */ -void pcb_undo_add_obj_to_move(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_coord_t DX, pcb_coord_t DY) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_MOVE, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.Move.DX = DX; - undo->Data.Move.DY = DY; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects with changed names - */ -void pcb_undo_add_obj_to_change_name(int Type, void *Ptr1, void *Ptr2, void *Ptr3, char *OldName) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGENAME, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.ChangeName.Name = OldName; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects with changed pinnums - */ -void pcb_undo_add_obj_to_change_pinnum(int Type, void *Ptr1, void *Ptr2, void *Ptr3, char *OldName) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGEPINNUM, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.ChangeName.Name = OldName; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects moved to another layer - */ -void pcb_undo_add_obj_to_move_to_layer(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_MOVETOLAYER, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.MoveToLayer.OriginalLayer = pcb_layer_id(PCB->Data, (pcb_layer_t *) Ptr1); - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of created objects - */ -void pcb_undo_add_obj_to_create(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - if (!Locked) - GetUndoSlot(PCB_UNDO_CREATE, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - pcb_poly_clear_from_poly(PCB->Data, Type, Ptr1, Ptr2); -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects with flags changed - */ -void pcb_undo_add_obj_to_flag(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_FLAG, PCB_OBJECT_ID(Ptr2), Type, sizeof(UndoListType)); - undo->Data.Flags = ((pcb_pin_t *) Ptr2)->Flags; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects with Size changes - */ -void pcb_undo_add_obj_to_size(int Type, void *ptr1, void *ptr2, void *ptr3) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGESIZE, PCB_OBJECT_ID(ptr2), Type, sizeof(UndoListType)); - switch (Type) { - case PCB_TYPE_PIN: - case PCB_TYPE_VIA: - undo->Data.Size = ((pcb_pin_t *) ptr2)->Thickness; - break; - case PCB_TYPE_LINE: - case PCB_TYPE_ELEMENT_LINE: - undo->Data.Size = ((pcb_line_t *) ptr2)->Thickness; - break; - case PCB_TYPE_TEXT: - case PCB_TYPE_ELEMENT_NAME: - undo->Data.Size = ((pcb_text_t *) ptr2)->Scale; - break; - case PCB_TYPE_PAD: - undo->Data.Size = ((pcb_pad_t *) ptr2)->Thickness; - break; - case PCB_TYPE_ARC: - case PCB_TYPE_ELEMENT_ARC: - undo->Data.Size = ((pcb_arc_t *) ptr2)->Thickness; - break; - } - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects with Size changes - */ -void pcb_undo_add_obj_to_clear_size(int Type, void *ptr1, void *ptr2, void *ptr3) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGECLEARSIZE, PCB_OBJECT_ID(ptr2), Type, sizeof(UndoListType)); - switch (Type) { - case PCB_TYPE_PIN: - case PCB_TYPE_VIA: - undo->Data.Size = ((pcb_pin_t *) ptr2)->Clearance; - break; - case PCB_TYPE_LINE: - undo->Data.Size = ((pcb_line_t *) ptr2)->Clearance; - break; - case PCB_TYPE_PAD: - undo->Data.Size = ((pcb_pad_t *) ptr2)->Clearance; - break; - case PCB_TYPE_ARC: - undo->Data.Size = ((pcb_arc_t *) ptr2)->Clearance; - break; - } - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects with Size changes - */ -void pcb_undo_add_obj_to_mask_size(int Type, void *ptr1, void *ptr2, void *ptr3) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGEMASKSIZE, PCB_OBJECT_ID(ptr2), Type, sizeof(UndoListType)); - switch (Type) { - case PCB_TYPE_PIN: - case PCB_TYPE_VIA: - undo->Data.Size = ((pcb_pin_t *) ptr2)->Mask; - break; - case PCB_TYPE_PAD: - undo->Data.Size = ((pcb_pad_t *) ptr2)->Mask; - break; - } - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of objects with 2ndSize changes - */ -void pcb_undo_add_obj_to_2nd_size(int Type, void *ptr1, void *ptr2, void *ptr3) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGE2NDSIZE, PCB_OBJECT_ID(ptr2), Type, sizeof(UndoListType)); - if (Type == PCB_TYPE_PIN || Type == PCB_TYPE_VIA) - undo->Data.Size = ((pcb_pin_t *) ptr2)->DrillingHole; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of changed angles. Note that you must - * call this before changing the angles, passing the new start/delta. - */ -void pcb_undo_add_obj_to_change_angles(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - UndoListTypePtr undo; - pcb_arc_t *a = (pcb_arc_t *) Ptr3; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGEANGLES, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.AngleChange.angle[0] = a->StartAngle; - undo->Data.AngleChange.angle[1] = a->Delta; - } -} - -/* --------------------------------------------------------------------------- - * adds an object to the list of changed radii. Note that you must - * call this before changing the radii, passing the new width/height. - */ -void pcb_undo_add_obj_to_change_radii(int Type, void *Ptr1, void *Ptr2, void *Ptr3) -{ - UndoListTypePtr undo; - pcb_arc_t *a = (pcb_arc_t *) Ptr3; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_CHANGERADII, PCB_OBJECT_ID(Ptr3), Type, sizeof(UndoListType)); - undo->Data.Move.DX = a->Width; - undo->Data.Move.DY = a->Height; - } -} - -/* --------------------------------------------------------------------------- - * adds a layer change (new, delete, move) to the undo list. - */ -void pcb_undo_add_layer_move(int old_index, int new_index) -{ - UndoListTypePtr undo; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_LAYERMOVE, 0, 0, sizeof(UndoListType)); - undo->Data.LayerChange.old_index = old_index; - undo->Data.LayerChange.new_index = new_index; - } -} - -/* --------------------------------------------------------------------------- - * adds a netlist change to the undo list - */ -void pcb_undo_add_netlist_lib(pcb_lib_t *lib) -{ - UndoListTypePtr undo; - unsigned int i, j; - pcb_lib_t *old; - - if (!Locked) { - undo = GetUndoSlot(PCB_UNDO_NETLISTCHANGE, 0, 0, sizeof(UndoListType)); - /* keep track of where the data needs to go */ - undo->Data.NetlistChange.lib = lib; - - /* and what the old data is that we'll need to restore */ - undo->Data.NetlistChange.old = (pcb_lib_t *) malloc(sizeof(pcb_lib_t *)); - old = undo->Data.NetlistChange.old; - old->MenuN = lib->MenuN; - old->MenuMax = lib->MenuMax; - old->Menu = (pcb_lib_menu_t *) malloc(old->MenuMax * sizeof(pcb_lib_menu_t)); - if (old->Menu == NULL) { - fprintf(stderr, "malloc() failed in AddNetlistLibToUndoList\n"); - exit(1); - } - - /* iterate over each net */ - for (i = 0; i < lib->MenuN; i++) { - old->Menu[i].EntryN = lib->Menu[i].EntryN; - old->Menu[i].EntryMax = lib->Menu[i].EntryMax; - - old->Menu[i].Name = lib->Menu[i].Name ? pcb_strdup(lib->Menu[i].Name) : NULL; - - old->Menu[i].directory = lib->Menu[i].directory ? pcb_strdup(lib->Menu[i].directory) : NULL; - - old->Menu[i].Style = lib->Menu[i].Style ? pcb_strdup(lib->Menu[i].Style) : NULL; - - - old->Menu[i].Entry = (pcb_lib_entry_t *) malloc(old->Menu[i].EntryMax * sizeof(pcb_lib_entry_t)); - if (old->Menu[i].Entry == NULL) { - fprintf(stderr, "malloc() failed in AddNetlistLibToUndoList\n"); - exit(1); - } - - /* iterate over each pin on the net */ - for (j = 0; j < lib->Menu[i].EntryN; j++) { - - old->Menu[i].Entry[j].ListEntry = lib->Menu[i].Entry[j].ListEntry ? pcb_strdup(lib->Menu[i].Entry[j].ListEntry) : NULL; - old->Menu[i].Entry[j].ListEntry_dontfree = 0; - - old->Menu[i].Entry[j].Package = lib->Menu[i].Entry[j].Package ? pcb_strdup(lib->Menu[i].Entry[j].Package) : NULL; - - old->Menu[i].Entry[j].Value = lib->Menu[i].Entry[j].Value ? pcb_strdup(lib->Menu[i].Entry[j].Value) : NULL; - - old->Menu[i].Entry[j].Description = - lib->Menu[i].Entry[j].Description ? pcb_strdup(lib->Menu[i].Entry[j].Description) : NULL; - - - } - } - - } -} - -/* --------------------------------------------------------------------------- * set lock flag */ void pcb_undo_lock(void) @@ -1667,55 +351,6 @@ return (Locked); } -#ifndef NDEBUG -static const char *undo_type2str(int type) -{ - static char buff[32]; - switch(type) { - case PCB_UNDO_CHANGENAME: return "changename"; - case PCB_UNDO_MOVE: return "move"; - case PCB_UNDO_REMOVE: return "remove"; - case PCB_UNDO_REMOVE_POINT: return "remove_point"; - case PCB_UNDO_INSERT_POINT: return "insert_point"; - case PCB_UNDO_REMOVE_CONTOUR: return "remove_contour"; - case PCB_UNDO_INSERT_CONTOUR: return "insert_contour"; - case PCB_UNDO_ROTATE: return "rotate"; - case PCB_UNDO_CREATE: return "create"; - case PCB_UNDO_MOVETOLAYER: return "movetolayer"; - case PCB_UNDO_FLAG: return "flag"; - case PCB_UNDO_CHANGESIZE: return "changesize"; - case PCB_UNDO_CHANGE2NDSIZE: return "change2ndsize"; - case PCB_UNDO_MIRROR: return "mirror"; - case PCB_UNDO_OTHERSIDE: return "otherside"; - case PCB_UNDO_CHANGECLEARSIZE: return "chngeclearsize"; - case PCB_UNDO_CHANGEMASKSIZE: return "changemasksize"; - case PCB_UNDO_CHANGEANGLES: return "changeangles"; - case PCB_UNDO_CHANGERADII: return "changeradii"; - case PCB_UNDO_LAYERMOVE: return "layermove"; - case PCB_UNDO_CLEAR: return "clear"; - case PCB_UNDO_NETLISTCHANGE: return "netlistchange"; - case PCB_UNDO_CHANGEPINNUM: return "changepinnum"; - } - sprintf(buff, "Unknown %d", type); - return buff; -} - -void undo_dump(void) -{ - size_t n; - int last_serial = -2; - printf("Serial=%d\n", Serial); - for(n = 0; n < UndoN; n++) { - if (last_serial != UndoList[n].Serial) { - printf("--- serial=%d\n", UndoList[n].Serial); - last_serial = UndoList[n].Serial; - } - printf(" type=%s kind=%d ID=%d\n", undo_type2str(UndoList[n].Type), UndoList[n].Kind, UndoList[n].ID); - } -} - -#endif - int undo_check(void) { size_t n; @@ -1741,3 +376,19 @@ } return 0; } + +#ifndef NDEBUG +void undo_dump(void) +{ + size_t n; + int last_serial = -2; + printf("Serial=%d\n", Serial); + for(n = 0; n < UndoN; n++) { + if (last_serial != UndoList[n].Serial) { + printf("--- serial=%d\n", UndoList[n].Serial); + last_serial = UndoList[n].Serial; + } + printf(" type=%s kind=%d ID=%d\n", undo_type2str(UndoList[n].Type), UndoList[n].Kind, UndoList[n].ID); + } +} +#endif