Index: trunk/src/extobj.h =================================================================== --- trunk/src/extobj.h (revision 28734) +++ trunk/src/extobj.h (revision 28735) @@ -29,6 +29,8 @@ #include +#include "board.h" +#include "data.h" #include "obj_common.h" #include "obj_subc.h" #include "draw.h" @@ -133,5 +135,39 @@ eo->edit_geo(sc, edit_obj); } +PCB_INLINE void pcb_extobj_new_subc(pcb_any_obj_t *edit_obj, pcb_subc_t *subc_copy_attr_from) +{ + pcb_data_t *data; + pcb_board_t *pcb; + pcb_subc_t *sc; + char tmp[128]; + if (edit_obj->parent_type == PCB_PARENT_DATA) + data = edit_obj->parent.data; + else if (edit_obj->parent_type == PCB_PARENT_LAYER) + data = edit_obj->parent.layer->parent.data; + else + return; + + pcb = pcb_data_get_top(data); + if (pcb == NULL) + return; + + sc = pcb_subc_new(); + sc->ID = pcb_create_ID_get(); + pcb_subc_reg(pcb->Data, sc); + pcb_obj_id_reg(pcb->Data, sc); + + if (subc_copy_attr_from != NULL) + pcb_attribute_copy_all(&sc->Attributes, &subc_copy_attr_from->Attributes); + + sprintf(tmp, "%ld", sc->ID); + pcb_attribute_put(&edit_obj->Attributes, "extobj::subcobj", tmp); + sprintf(tmp, "%ld", edit_obj->ID); + pcb_attribute_put(&sc->Attributes, "extobj::editobj", tmp); + + pcb_extobj_edit_pre(edit_obj); + pcb_extobj_edit_geo(edit_obj); +} + #endif Index: trunk/src/obj_common.c =================================================================== --- trunk/src/obj_common.c (revision 28734) +++ trunk/src/obj_common.c (revision 28735) @@ -39,6 +39,7 @@ #include "obj_subc.h" #include "obj_subc_parent.h" #include "obj_term.h" +#include "extobj.h" const char *pcb_obj_type_name(pcb_objtype_t type) { @@ -124,12 +125,58 @@ return ID++; } +static void pcb_attribute_copy_all_smart(pcb_attribute_list_t *dest, const pcb_attribute_list_t *src, pcb_any_obj_t *dstobj) +{ + int i, exto = 0; + const char *subcobj; + + for (i = 0; i < src->Number; i++) { + if (strncmp(src->List[i].name, "extobj", 6) == 0) { + exto = 1; + if (strcmp(src->List[i].name+6, "::subcobj") == 0) { + subcobj = src->List[i].value; + continue; /* do not copy, will be re-generated */ + } + } + + pcb_attribute_put(dest, src->List[i].name, src->List[i].value); + } + if (exto) { + pcb_subc_t *copy_from = NULL; + if (subcobj != NULL) { + pcb_data_t *data; + + if (dstobj->parent_type == PCB_PARENT_DATA) + data = dstobj->parent.data; + else if (dstobj->parent_type == PCB_PARENT_LAYER) + data = dstobj->parent.layer->parent.data; + else + data = NULL; + + if (data != NULL) { + char *end; + long id = strtol(subcobj, &end, 10); + if (*end == '\0') { + copy_from = htip_get(&data->id2obj, id); + if ((copy_from != NULL) && (copy_from->type != PCB_OBJ_SUBC)) + copy_from = NULL; + } + } + } + pcb_extobj_new_subc(dstobj, copy_from); + } +} + + void pcb_obj_add_attribs(void *obj, const pcb_attribute_list_t *src, pcb_bool smart) { pcb_any_obj_t *o = obj; if (src == NULL) return; - pcb_attribute_copy_all(&o->Attributes, src); + if (smart) + pcb_attribute_copy_all_smart(&o->Attributes, src, obj); + else + pcb_attribute_copy_all(&o->Attributes, src); } void pcb_obj_center(const pcb_any_obj_t *obj, pcb_coord_t *x, pcb_coord_t *y)