Index: trunk/src/change.c =================================================================== --- trunk/src/change.c (revision 19598) +++ trunk/src/change.c (revision 19599) @@ -95,6 +95,19 @@ pcb_pstkop_change_2nd_size }; +pcb_opfunc_t ChangeRotFunctions = { + NULL, + pcb_textop_change_rot, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + pcb_pstkop_rotate +}; + static pcb_opfunc_t ChangeThermalFunctions = { NULL, NULL, @@ -326,6 +339,28 @@ return change; } +/* -------------------------------------------------------------------------- + * changes the internal/self rotation all selected and visible objects + * returns pcb_true if anything has changed + */ +pcb_bool pcb_chg_selected_rot(int types, double Difference, pcb_bool fixIt) +{ + pcb_bool change = pcb_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeRotFunctions, &ctx, pcb_false, types, pcb_false); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + /* ---------------------------------------------------------------------- * changes the clearance flag (join) of all selected and visible lines * and/or arcs. Returns pcb_true if anything has changed @@ -605,6 +640,29 @@ } /* --------------------------------------------------------------------------- + * changes the internal/self rotation of the passed object + * Returns pcb_true if anything is changed + */ +pcb_bool pcb_chg_obj_rot(int Type, void *Ptr1, void *Ptr2, void *Ptr3, double Difference, pcb_bool fixIt, pcb_bool incundo) +{ + pcb_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = (pcb_object_operation(&ChangeRotFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + if (incundo) + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- * changes the name of the passed object * returns the old name * Index: trunk/src/change.h =================================================================== --- trunk/src/change.h (revision 19598) +++ trunk/src/change.h (revision 19599) @@ -50,6 +50,9 @@ #define PCB_CHANGE2NDSIZE_TYPES \ (PCB_OBJ_PSTK | PCB_OBJ_SUBC | PCB_OBJ_SUBC_PART) +#define PCB_CHANGEROT_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_TEXT) + /* We include polygons here only to inform the user not to do it that way. */ #define PCB_CHANGECLEARSIZE_TYPES \ (PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_SUBC | \ @@ -73,6 +76,7 @@ pcb_bool pcb_chg_selected_size(int, pcb_coord_t, pcb_bool); pcb_bool pcb_chg_selected_clear_size(int, pcb_coord_t, pcb_bool); pcb_bool pcb_chg_selected_2nd_size(int, pcb_coord_t, pcb_bool); +pcb_bool pcb_chg_selected_rot(int, double, pcb_bool); pcb_bool pcb_chg_selected_join(int); pcb_bool pcb_set_selected_join(int); pcb_bool pcb_clr_selected_join(int); @@ -83,6 +87,7 @@ pcb_bool pcb_chg_obj_thermal(int Type, void *Ptr1, void *Ptr2, void *Ptr3, int therm_type, unsigned long lid); pcb_bool pcb_chg_obj_clear_size(int, void *, void *, void *, pcb_coord_t, pcb_bool); pcb_bool pcb_chg_obj_2nd_size(int, void *, void *, void *, pcb_coord_t, pcb_bool, pcb_bool); +pcb_bool pcb_chg_obj_rot(int, void *, void *, void *, double, pcb_bool, pcb_bool); pcb_bool pcb_chg_obj_join(int, void *, void *, void *); pcb_bool pcb_set_obj_join(int, void *, void *, void *); pcb_bool pcb_clr_obj_join(int, void *, void *, void *); Index: trunk/src/obj_pstk.c =================================================================== --- trunk/src/obj_pstk.c (revision 19598) +++ trunk/src/obj_pstk.c (revision 19599) @@ -1265,3 +1265,19 @@ shp = pcb_pstk_shape_at(pcb, ps, layer); return shp->clearance; } + +void pcb_pstk_pre(pcb_pstk_t *pstk) +{ + pcb_data_t *data = pstk->parent.data; + if (data->padstack_tree != NULL) + pcb_r_delete_entry(data->padstack_tree, (pcb_box_t *)pstk); + pcb_poly_restore_to_poly(data, PCB_OBJ_PSTK, NULL, pstk); +} + +void pcb_pstk_post(pcb_pstk_t *pstk) +{ + pcb_data_t *data = pstk->parent.data; + if (data->padstack_tree != NULL) + pcb_r_insert_entry(data->padstack_tree, (pcb_box_t *)pstk); + pcb_poly_clear_from_poly(data, PCB_OBJ_PSTK, NULL, pstk); +} Index: trunk/src/obj_pstk.h =================================================================== --- trunk/src/obj_pstk.h (revision 19598) +++ trunk/src/obj_pstk.h (revision 19599) @@ -95,6 +95,9 @@ void pcb_pstk_bbox(pcb_pstk_t *ps); void pcb_pstk_copper_bbox(pcb_box_t *dst, pcb_pstk_t *ps); +void pcb_pstk_pre(pcb_pstk_t *pstk); +void pcb_pstk_post(pcb_pstk_t *pstk); + /* hash and eq */ int pcb_pstk_eq(const pcb_host_trans_t *tr1, const pcb_pstk_t *p1, const pcb_host_trans_t *tr2, const pcb_pstk_t *p2); unsigned int pcb_pstk_hash(const pcb_host_trans_t *tr, const pcb_pstk_t *p); Index: trunk/src/obj_text.c =================================================================== --- trunk/src/obj_text.c (revision 19598) +++ trunk/src/obj_text.c (revision 19599) @@ -464,6 +464,28 @@ return NULL; } +/* changes the rotation of a text object */ +void *pcb_textop_change_rot(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + int value = ctx->chgsize.is_absolute ? ctx->chgsize.value : Text->rot + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text)) + return NULL; + if (value != Text->rot) { + pcb_undo_add_obj_to_rot(PCB_OBJ_TEXT, Layer, Text, Text); + pcb_text_invalidate_erase(Layer, Text); + pcb_r_delete_entry(Layer->text_tree, (pcb_box_t *) Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + Text->rot = value; + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); + pcb_r_insert_entry(Layer->text_tree, (pcb_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_text_invalidate_draw(Layer, Text); + return Text; + } + return NULL; +} + /* sets data of a text object and calculates bounding box; memory must have already been allocated the one for the new string is allocated */ void *pcb_textop_change_name(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) Index: trunk/src/obj_text_op.h =================================================================== --- trunk/src/obj_text_op.h (revision 19598) +++ trunk/src/obj_text_op.h (revision 19599) @@ -34,6 +34,7 @@ void *pcb_textop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t * layer, pcb_text_t * text); void *pcb_textop_change_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); void *pcb_textop_change_2nd_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_change_rot(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); void *pcb_textop_change_name(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); void *pcb_textop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); void *pcb_textop_set_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); Index: trunk/src/undo_old.c =================================================================== --- trunk/src/undo_old.c (revision 19598) +++ trunk/src/undo_old.c (revision 19599) @@ -334,6 +334,49 @@ } /* --------------------------------------------------------------------------- + * recovers an object from a Size change operation + */ +static pcb_bool UndoChangeRot(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3, *ptr1e; + int type; + double swap; + pcb_bool ret = pcb_false; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + ptr1e = ptr1; + + + if (pcb_undo_and_draw) + pcb_draw_obj((pcb_any_obj_t *)ptr2); + + switch(type) { + case PCB_OBJ_PSTK: + swap = ((pcb_pstk_t *)ptr2)->rot; + pcb_pstk_pre(((pcb_pstk_t *)ptr2)); + ((pcb_pstk_t *)ptr2)->rot = Entry->Data.Size; + Entry->Data.Size = swap; + pcb_pstk_post(((pcb_pstk_t *)ptr2)); + ret = pcb_true; + break; + + case PCB_OBJ_TEXT: + swap = ((pcb_text_t *)ptr2)->rot; + pcb_text_pre(((pcb_text_t *)ptr2)); + ((pcb_text_t *)ptr2)->rot = Entry->Data.Size; + Entry->Data.Size = swap; + pcb_text_post(((pcb_text_t *)ptr2)); + ret = pcb_true; + break; + } + + if (pcb_undo_and_draw) + pcb_draw_obj((pcb_any_obj_t *)ptr2); + return ret; +} + +/* --------------------------------------------------------------------------- * recovers an object from a FLAG change operation */ static pcb_bool UndoFlag(UndoListTypePtr Entry) @@ -789,6 +832,11 @@ return 0; break; + case PCB_UNDO_CHANGEROT: + if (UndoChangeRot(ptr)) + return 0; + break; + case PCB_UNDO_CHANGECLEARSIZE: if (UndoChangeClearSize(ptr)) return 0; @@ -1114,6 +1162,26 @@ } /* --------------------------------------------------------------------------- + * adds an object to the list of objects with rot changes + */ +void pcb_undo_add_obj_to_rot(int Type, void *ptr1, void *ptr2, void *ptr3) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGEROT, PCB_OBJECT_ID(ptr2), Type); + switch (Type) { + case PCB_OBJ_PSTK: + undo->Data.Size = ((pcb_pstk_t *) ptr2)->rot; + break; + case PCB_OBJ_TEXT: + undo->Data.Size = ((pcb_text_t *) ptr2)->rot; + 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) @@ -1261,6 +1329,7 @@ case PCB_UNDO_MOVETOLAYER: return "movetolayer"; case PCB_UNDO_FLAG: return "flag"; case PCB_UNDO_CHANGESIZE: return "changesize"; + case PCB_UNDO_CHANGEROT: return "changerot"; case PCB_UNDO_OTHERSIDE: return "otherside"; case PCB_UNDO_CHANGECLEARSIZE: return "chngeclearsize"; case PCB_UNDO_CHANGEANGLES: return "changeangles"; Index: trunk/src/undo_old.h =================================================================== --- trunk/src/undo_old.h (revision 19598) +++ trunk/src/undo_old.h (revision 19599) @@ -54,6 +54,7 @@ void pcb_undo_add_obj_to_flag(void *obj); void pcb_undo_add_obj_to_size(int, void *, void *, void *); void pcb_undo_add_obj_to_2nd_size(int Type, void *ptr1, void *ptr2, void *ptr3); +void pcb_undo_add_obj_to_rot(int Type, void *ptr1, void *ptr2, void *ptr3); void pcb_undo_add_obj_to_clear_size(int, void *, void *, void *); void pcb_undo_add_obj_to_change_angles(int, void *, void *, void *); void pcb_undo_add_obj_to_change_radii(int, void *, void *, void *); @@ -85,7 +86,8 @@ PCB_UNDO_NETLISTCHANGE = 0x080000, /* netlist change */ PCB_UNDO_CHANGERADII = 0x200000, /* change arc radii */ PCB_UNDO_OTHERSIDE = 0x400000, /* change side of board (subcircuit) */ - PCB_UNDO_ROTATE = 0x800000 /* rotations at arbitrary angle */ + PCB_UNDO_ROTATE = 0x800000, /* rotations at arbitrary angle */ + PCB_UNDO_CHANGEROT = 0x1000000 /* change internal/self rotation of an object */ } pcb_undo_op_t; const char *undo_type2str(int type);