diff --git a/doc/xschem_man/commands.html b/doc/xschem_man/commands.html
index 0a4f589e..02f5777a 100644
--- a/doc/xschem_man/commands.html
+++ b/doc/xschem_man/commands.html
@@ -229,6 +229,7 @@ ctrl+alt 's' Save-as symbol
- 't' Place text
shift 'T' Toggle *_ignore flag on selected instances
alt 'u' Align to current grid selected objects
+ctrl 'u' Unselect attached floater objects
shift 'U' Redo
- 'u' Undo
- 'v' Constrained vertical move/copy of objects
diff --git a/src/callback.c b/src/callback.c
index d2ca603d..25e807b5 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -2383,6 +2383,54 @@ static int grabscreen(const char *win_path, int event, int mx, int my, KeySym ke
}
#endif
+void unselect_attached_floaters(void)
+{
+ int c, i, found = 0;
+ for(c = 0; c < cadlayers; c++) {
+ for(i = 0; i < xctx->rects[c]; i++) {
+ if(get_tok_value(xctx->rect[c][i].prop_ptr, "name", 0)[0]) {
+ found = 1;
+ select_box(c, i, 0, 1, 0);
+ }
+ }
+ for(i = 0; i < xctx->lines[c]; i++) {
+ if(get_tok_value(xctx->line[c][i].prop_ptr, "name", 0)[0]) {
+ found = 1;
+ select_line(c, i, 0, 1);
+ }
+ }
+
+ for(i = 0; i < xctx->polygons[c]; i++) {
+ if(get_tok_value(xctx->poly[c][i].prop_ptr, "name", 0)[0]) {
+ found = 1;
+ select_polygon(c, i, 0, 1);
+ }
+ }
+ for(i = 0; i < xctx->arcs[c]; i++) {
+ if(get_tok_value(xctx->arc[c][i].prop_ptr, "name", 0)[0]) {
+ found = 1;
+ select_arc(c, i, 0, 1);
+ }
+ }
+ }
+ for(i = 0; i < xctx->wires; i++) {
+ if(get_tok_value(xctx->wire[i].prop_ptr, "name", 0)[0]) {
+ found = 1;
+ select_wire(i, 0, 1);
+ }
+ }
+ for(i = 0; i < xctx->texts; i++) {
+ if(get_tok_value(xctx->text[i].prop_ptr, "name", 0)[0]) {
+ found = 1;
+ select_text(i, 0, 1);
+ }
+ }
+ if(found) {
+ rebuild_selected_array();
+ draw_selection(xctx->gc[SELLAYER],0);
+ }
+}
+
static void handle_enter_notify(int draw_xhair, int crosshair_size)
{
struct stat buf;
@@ -3477,7 +3525,11 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
draw();
return;
}
- if(0 && (key=='u') && rstate==ControlMask) /* testmode */
+ if(key=='u' && rstate==ControlMask) /* unselect attached floater elements */
+ {
+ unselect_attached_floaters();
+ }
+ if(0 && (key=='|') && rstate==ControlMask) /* testmode */
{
static int x = 0;
@@ -3973,21 +4025,6 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
check_unique_names(1);
return;
}
- if( 0 && (key==';') && (state & ControlMask) ) /* testmode */
- {
- return;
- }
- if(0 && key=='~' && (state & ControlMask)) { /* testmode */
- return;
- }
- if(0 && key=='|' && !(state & ControlMask)) { /* testmode */
- return;
- }
- if(0 && key=='|' && (state & ControlMask)) /* testmode */
- {
- return;
- }
-
if(key=='f' && rstate == ControlMask) /* search */
{
if(xctx->semaphore >= 2) return;
diff --git a/src/editprop.c b/src/editprop.c
index 3a7f9323..ee8f1ac3 100644
--- a/src/editprop.c
+++ b/src/editprop.c
@@ -1637,6 +1637,7 @@ static int update_symbol(const char *result, int x, int selected_inst)
/* preserve backslashes in name ---------0---------------------------------->. */
my_strdup(_ALLOC_ID_, &name, get_tok_value(xctx->inst[*ii].prop_ptr, "name", 1));
if(name && name[0] ) {
+ char *old_name = NULL;
dbg(1, "update_symbol(): prefix!='\\0', name=%s\n", name);
/* change prefix if changing symbol type; */
if(prefix && old_prefix && old_prefix != prefix) {
@@ -1649,11 +1650,14 @@ static int update_symbol(const char *result, int x, int selected_inst)
if(!pushed) { xctx->push_undo(); pushed=1;}
if(!k) hash_names(-1, XINSERT);
hash_names(*ii, XDELETE);
- dbg(1, "update_symbol(): delete %s\n", xctx->inst[*ii].instname);
+ dbg(0, "update_symbol(): delete %s\n", xctx->inst[*ii].instname);
+ my_strdup2(_ALLOC_ID_, &old_name, xctx->inst[*ii].instname);
new_prop_string(*ii, ptr, /* sets also inst[].instname */
tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
hash_names(*ii, XINSERT);
- dbg(1, "update_symbol(): insert %s\n", xctx->inst[*ii].instname);
+ update_attached_object_refs(old_name, *ii, 1);
+ dbg(0, "update_symbol(): insert %s\n", xctx->inst[*ii].instname);
+ my_free(_ALLOC_ID_, &old_name);
}
set_inst_flags(&xctx->inst[*ii]);
} /* end for(k=0;klastsel; ++k) */
diff --git a/src/keys.help b/src/keys.help
index a73197bf..a473aa45 100644
--- a/src/keys.help
+++ b/src/keys.help
@@ -169,6 +169,7 @@ ctrl+alt 's' Save-as symbol
- 't' Place text
shift 'T' Toggle *_ignore flag on selected instances
alt 'u' Align to current grid selected objects
+ctrl 'u' Unselect attached floater objects
shift 'U' Redo
- 'u' Undo
- 'v' Constrained vertical move/copy of objects
diff --git a/src/move.c b/src/move.c
index f03b7871..20ee6f99 100644
--- a/src/move.c
+++ b/src/move.c
@@ -513,12 +513,13 @@ void draw_selection(GC g, int interruptable)
xctx->movelastsel = i;
}
-static void update_attached_object_refs(int from, int to)
+/* sel: if set to 1 change references only on selected items, like in a copy operation.
+ * If set to 0 operate on all objects with matching name=... attribute */
+void update_attached_object_refs(const char *from_name, int inst, int sel)
{
int i, c;
- char *to_name = xctx->inst[to].instname;
- char *from_name = xctx->inst[from].instname;
- const char *attach = get_tok_value(xctx->inst[to].prop_ptr, "attach", 0);
+ char *to_name = xctx->inst[inst].instname;
+ const char *attach = get_tok_value(xctx->inst[inst].prop_ptr, "attach", 0);
char *new_attach;
if(!from_name || !from_name[0]) return;
@@ -526,12 +527,12 @@ static void update_attached_object_refs(int from, int to)
if(!attach[0]) return;
new_attach = str_replace(attach, from_name, to_name, 1, 1);
- my_strdup(_ALLOC_ID_, &xctx->inst[to].prop_ptr,
- subst_token(xctx->inst[to].prop_ptr, "attach", new_attach) );
+ my_strdup(_ALLOC_ID_, &xctx->inst[inst].prop_ptr,
+ subst_token(xctx->inst[inst].prop_ptr, "attach", new_attach) );
for(c = 0; c < cadlayers; c++) {
for(i = 0; i < xctx->rects[c]; i++) {
- if(xctx->rect[c][i].sel == SELECTED) {
+ if(!sel || xctx->rect[c][i].sel == SELECTED) {
if( !strcmp(from_name, get_tok_value(xctx->rect[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->rect[c][i].prop_ptr,
subst_token(xctx->rect[c][i].prop_ptr, "name", to_name) );
@@ -547,7 +548,7 @@ static void update_attached_object_refs(int from, int to)
}
}
for(i = 0; i < xctx->lines[c]; i++) {
- if(xctx->line[c][i].sel == SELECTED &&
+ if((!sel || xctx->line[c][i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->line[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->line[c][i].prop_ptr,
subst_token(xctx->line[c][i].prop_ptr, "name", to_name) );
@@ -555,7 +556,7 @@ static void update_attached_object_refs(int from, int to)
}
for(i = 0; i < xctx->polygons[c]; i++) {
- if(xctx->poly[c][i].sel == SELECTED &&
+ if((!sel || xctx->poly[c][i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->poly[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->poly[c][i].prop_ptr,
subst_token(xctx->poly[c][i].prop_ptr, "name", to_name) );
@@ -563,7 +564,7 @@ static void update_attached_object_refs(int from, int to)
}
}
for(i = 0; i < xctx->arcs[c]; i++) {
- if(xctx->arc[c][i].sel == SELECTED &&
+ if((!sel || xctx->arc[c][i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->arc[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->arc[c][i].prop_ptr,
subst_token(xctx->arc[c][i].prop_ptr, "name", to_name) );
@@ -571,14 +572,14 @@ static void update_attached_object_refs(int from, int to)
}
}
for(i = 0; i < xctx->wires; i++) {
- if(xctx->wire[i].sel == SELECTED &&
+ if((!sel || xctx->wire[i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->wire[i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr,
subst_token(xctx->wire[i].prop_ptr, "name", to_name) );
}
}
for(i = 0; i < xctx->texts; i++) {
- if(xctx->text[i].sel == SELECTED &&
+ if((!sel || xctx->text[i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->text[i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->text[i].prop_ptr,
subst_token(xctx->text[i].prop_ptr, "name", to_name) );
@@ -957,7 +958,7 @@ void copy_objects(int what)
new_prop_string(xctx->instances, xctx->inst[n].prop_ptr, /* sets also inst[].instname */
tclgetboolvar("disable_unique_names"));
- update_attached_object_refs(n, xctx->instances);
+ update_attached_object_refs(xctx->inst[n].instname, xctx->instances, 1);
hash_names(xctx->instances, XINSERT);
xctx->instances++; /* symbol_bbox calls translate and translate must have updated xctx->instances */
diff --git a/src/scheduler.c b/src/scheduler.c
index 38e6866e..538e1bbf 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -5461,7 +5461,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
} else {
char *translated_sym = NULL;
int sym_number = -1;
- char *subst = NULL;
+ char *subst = NULL, *old_name = NULL;;
+
if(!fast) {
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
xctx->push_undo();
@@ -5469,7 +5470,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
- if(argc > 4 && !strcmp(argv[4], "name") && fast == 0) hash_names(-1, XINSERT);
+ if(argc > 4 && !strcmp(argv[4], "name")) {
+ if(fast == 0) {
+ hash_names(-1, XINSERT);
+ }
+ my_strdup2(_ALLOC_ID_, &old_name, xctx->inst[inst].instname);
+ }
if(argc > 5) {
if(!strcmp(argv[4], "allprops")) {
hash_names(-1, XINSERT);
@@ -5486,7 +5492,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
hash_names(inst, XDELETE);
new_prop_string(inst, subst, tclgetboolvar("disable_unique_names"));
-
+ if(old_name) {
+ update_attached_object_refs(old_name, inst, 0);
+ }
my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name));
sym_number=match_symbol(translated_sym);
@@ -5495,6 +5503,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
xctx->inst[inst].ptr=sym_number;
}
if(subst) my_free(_ALLOC_ID_, &subst);
+ if(old_name) my_free(_ALLOC_ID_, &old_name);
set_inst_flags(&xctx->inst[inst]);
hash_names(inst, XINSERT);
if(!fast) {
@@ -6215,6 +6224,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
+ /* unselect_attached_floaters
+ * Unselect objects (not symbol instances) attached to some instance with a
+ * non empty name=... attribute */
+ else if(!strcmp(argv[1], "unselect_attached_floaters"))
+ {
+ if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
+ unselect_attached_floaters();
+ }
/* update_all_sym_bboxes
* Update all symbol bounding boxes */
else if(!strcmp(argv[1], "update_all_sym_bboxes"))
diff --git a/src/select.c b/src/select.c
index c90d85f5..8386da34 100644
--- a/src/select.c
+++ b/src/select.c
@@ -1282,7 +1282,7 @@ Selected select_object(double mx,double my, unsigned short select_mode,
break;
case ELEMENT:
if(xctx->inst[sel.n].sel) xctx->already_selected = 1;
- select_element(sel.n,select_mode,0, override_lock);
+ select_element(sel.n, select_mode,0, override_lock);
break;
default:
break;
diff --git a/src/xschem.h b/src/xschem.h
index 84e30e0e..d4e74449 100644
--- a/src/xschem.h
+++ b/src/xschem.h
@@ -1402,6 +1402,7 @@ extern void abort_operation(void);
extern void draw_crosshair(int what, int state);
extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr);
/* extern void snapped_wire(double c_snap); */
+extern void unselect_attached_floaters(void);
extern int callback(const char *win_path, int event, int mx, int my, KeySym key,
int button, int aux, int state);
extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h);
@@ -1546,6 +1547,8 @@ extern void new_line(int what, double mx_snap, double my_snap);
extern void new_arc(int what, double sweep, double mousex_snap, double mousey_snap);
extern void arc_3_points(double x1, double y1, double x2, double y2, double x3, double y3,
double *x, double *y, double *r, double *a, double *b);
+/* sel: if set to 1 change references only on selected items, like in a copy operation */
+extern void update_attached_object_refs(const char *from_name, int inst, int sel);
extern void move_objects(int what,int merge, double dx, double dy);
extern void check_collapsing_objects();
extern void redraw_w_a_l_r_p_z_rubbers(int force); /* redraw wire, arcs, line, polygon rubbers */
diff --git a/src/xschem.tcl b/src/xschem.tcl
index dd5d47cb..e35d90e6 100644
--- a/src/xschem.tcl
+++ b/src/xschem.tcl
@@ -8680,6 +8680,8 @@ proc build_widgets { {topwin {} } } {
-command "xschem net_label 0" -accelerator Alt-Shift-L
$topwin.menubar.sym add command -label "Change selected inst. texts to floaters" \
-command "xschem floaters_from_selected_inst"
+ $topwin.menubar.sym add command -label "Unselect attached floaters" \
+ -command "xschem unselect_attached_floaters"
$topwin.menubar.sym add command -label "Print list of highlight nets" \
-command "xschem print_hilight_net 1" -accelerator J
$topwin.menubar.sym add command -label "Print list of highlight nets, with buses expanded" \