Index: trunk/src/obj_text.c =================================================================== --- trunk/src/obj_text.c (revision 15092) +++ trunk/src/obj_text.c (revision 15093) @@ -381,22 +381,26 @@ } /* moves a text without allocating memory for the name between board and buffer */ -void *pcb_textop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t * layer, pcb_text_t * text) +void *pcb_textop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *dstly, pcb_text_t *text) { - pcb_layer_t *lay = &ctx->buffer.dst->Layer[pcb_layer_id(ctx->buffer.src, layer)]; + pcb_layer_t *srcly = text->parent.layer; - pcb_r_delete_entry(layer->text_tree, (pcb_box_t *) text); - pcb_poly_restore_to_poly(ctx->buffer.src, PCB_TYPE_TEXT, layer, text); + assert(text->parent_type == PCB_PARENT_LAYER); + if ((dstly == NULL) || (dstly == srcly)) /* auto layer in dst */ + dstly = &ctx->buffer.dst->Layer[pcb_layer_id(ctx->buffer.src, srcly)]; + pcb_r_delete_entry(srcly->text_tree, (pcb_box_t *) text); + pcb_poly_restore_to_poly(ctx->buffer.src, PCB_TYPE_TEXT, srcly, text); + textlist_remove(text); - textlist_append(&lay->Text, text); + textlist_append(&dstly->Text, text); - if (!lay->text_tree) - lay->text_tree = pcb_r_create_tree(); - pcb_r_insert_entry(lay->text_tree, (pcb_box_t *) text); - pcb_poly_clear_from_poly(ctx->buffer.dst, PCB_TYPE_TEXT, lay, text); + if (!dstly->text_tree) + dstly->text_tree = pcb_r_create_tree(); + pcb_r_insert_entry(dstly->text_tree, (pcb_box_t *) text); + pcb_poly_clear_from_poly(ctx->buffer.dst, PCB_TYPE_TEXT, dstly, text); - PCB_SET_PARENT(text, layer, lay); + PCB_SET_PARENT(text, layer, dstly); return text; } Index: trunk/src/tool_remove.c =================================================================== --- trunk/src/tool_remove.c (revision 15092) +++ trunk/src/tool_remove.c (revision 15093) @@ -48,6 +48,7 @@ void pcb_tool_remove_notify_mode(void) { void *ptr1, *ptr2, *ptr3; + pcb_any_obj_t *obj; int type; if ((type = pcb_search_screen(pcb_tool_note.X, pcb_tool_note.Y, PCB_REMOVE_TYPES | PCB_LOOSE_SUBC, &ptr1, &ptr2, &ptr3)) != PCB_TYPE_NONE) { @@ -57,6 +58,16 @@ } if (type == PCB_TYPE_ELEMENT) pcb_event(PCB_EVENT_RUBBER_REMOVE_ELEMENT, "ppp", ptr1, ptr2, ptr3); + + /* preserve original parent over the board layer pcb_search_screen operated on - + this is essential for undo: it needs to put back the object to the original + layer (e.g. inside a subc) instead of on the board layer */ + obj = ptr2; + if (obj->parent_type == PCB_PARENT_LAYER) + ptr1 = obj->parent.layer; + else if (obj->parent_type == PCB_PARENT_DATA) + ptr1 = obj->parent.data; + pcb_remove_object(type, ptr1, ptr2, ptr3); pcb_undo_inc_serial(); pcb_board_set_changed_flag(pcb_true); Index: trunk/src/undo_old.c =================================================================== --- trunk/src/undo_old.c (revision 15092) +++ trunk/src/undo_old.c (revision 15093) @@ -66,6 +66,7 @@ #include "obj_elem_draw.h" #include "obj_poly_draw.h" +#include "obj_subc_parent.h" #define STEP_REMOVELIST 500 #define STEP_UNDOLIST 500 @@ -554,11 +555,23 @@ { void *ptr1, *ptr2, *ptr3; int type; + Removed *r = &Entry->Data.Removed; + pcb_data_t *data = PCB->Data; /* lookup entry by it's ID */ type = pcb_search_obj_by_id(pcb_removelist, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != PCB_TYPE_NONE) { - pcb_move_obj_to_buffer(PCB, PCB->Data, pcb_removelist, type, ptr1, ptr2, ptr3); + if (r->p_subc_id > 0) { /* need to use a subc layer - putting back a floater */ + void *p1, *p2, *p3; + if (pcb_search_obj_by_id(PCB->Data, &p1, &p2, &p3, r->p_subc_id, PCB_TYPE_SUBC) != 0) { + pcb_subc_t *subc = p2; + if (r->p_subc_layer < subc->data->LayerN) { + data = subc->data; + ptr1 = &data->Layer[r->p_subc_layer]; + } + } + } + pcb_move_obj_to_buffer(PCB, data, pcb_removelist, type, ptr1, ptr2, ptr3); if (pcb_undo_and_draw) DrawRecoveredObject((pcb_any_obj_t *)ptr2); Entry->Type = PCB_UNDO_CREATE; @@ -1007,6 +1020,11 @@ */ void pcb_undo_move_obj_to_remove(int Type, void *Ptr1, void *Ptr2, void *Ptr3) { + UndoListTypePtr Entry; + Removed *r; + pcb_any_obj_t *o = Ptr3; + pcb_subc_t *subc; + if (Locked) return; @@ -1013,7 +1031,32 @@ if (!pcb_removelist) pcb_removelist = pcb_buffer_new(NULL); - GetUndoSlot(PCB_UNDO_REMOVE, PCB_OBJECT_ID(Ptr3), Type); + Entry = GetUndoSlot(PCB_UNDO_REMOVE, PCB_OBJECT_ID(Ptr3), Type); + r = &Entry->Data.Removed; + r->p_subc_id = 0; + + switch(o->type) { + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_TEXT: + case PCB_OBJ_POLY: + subc = pcb_obj_parent_subc(Ptr3); + if (subc != NULL) { + r->p_subc_id = subc->ID; + r->p_subc_layer = o->parent.layer - subc->data->Layer; + } + break; + case PCB_OBJ_PSTK: + subc = pcb_obj_parent_subc(Ptr3); + if (subc != NULL) + r->p_subc_id = subc->ID; + break; +#warning subc TODO: floater subc in subc should remember its subc parent too + default: + break; + } + + pcb_move_obj_to_buffer(PCB, pcb_removelist, PCB->Data, Type, Ptr1, Ptr2, Ptr3); } Index: trunk/src/undo_old_str.h =================================================================== --- trunk/src/undo_old_str.h (revision 15092) +++ trunk/src/undo_old_str.h (revision 15093) @@ -8,6 +8,11 @@ pcb_coord_t DX, DY; /* movement vector */ } MoveType, *MoveTypePtr; +typedef struct { + long p_subc_id; /* parent subc ID (0 if parent is not a subc) */ + int p_subc_layer; /* parent subc layer index, for layer objects */ +} Removed; + typedef struct { /* information about removed polygon points */ pcb_coord_t X, Y; /* data */ int ID; @@ -52,6 +57,7 @@ union { /* some additional information */ ChangeNameType ChangeName; MoveType Move; + Removed Removed; RemovedPointType RemovedPoint; RotateType Rotate; MoveToLayer MoveToLayer;