implement "nodraw" flag in all object selections in the "xschem select" command, implement the "nodraw" flag in "xschem search" command

This commit is contained in:
stefan schippers 2025-10-29 09:06:07 +01:00
parent 2763c6010f
commit bf344309f0
5 changed files with 75 additions and 52 deletions

View File

@ -1450,7 +1450,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
if 'new_process' is given start a new xschem process
if 'nodraw' is given do not draw loaded schematic
returns '1' if a new schematic was opened, 0 otherwise </pre>
<li><kbd> search regex|exact select tok val [match_case]</kbd></li><pre>
<li><kbd> search regex|exact select tok val [no_match_case] [nodraw]</kbd></li><pre>
Search instances / wires / rects / texts with attribute string containing 'tok'
and value 'val'
search can be exact ('exact') or as a regular expression ('regex')
@ -1466,11 +1466,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
cell::name : will search for 'val' in the symbol name
cell::&lt;attr&gt; will search for 'val' in symbol attribute 'attr'
example: xschem search regex 0 cell::template GAIN=100
match_case:
1 : Match case
0 : Do not match case
If not given assume 1 (Match case)</pre>
<li><kbd> select instance|wire|text id [clear] [fast]</kbd></li><pre>
if 'no_match_case' is specified do not consider case sensitivity in search
if 'nodraw' is specified do not draw search result</pre>
<li><kbd> select instance|wire|text id [clear] [fast] [nodraw]</kbd></li><pre>
select rect|line|poly|arc layer id [clear] [fast]
Select indicated instance or wire or text, or
Select indicated (layer, number) rectangle, line, polygon, arc.
@ -1478,7 +1476,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
for all other objects 'id' is the position in the respective arrays
if 'clear' is specified does an unselect operation
if 'fast' is specified avoid sending information to infowindow and status bar
if 'nodraw' is given on select instance do not draw selection
if 'nodraw' is given do not draw selection
returns 1 if something selected, 0 otherwise </pre>
<li><kbd> select_all</kbd></li><pre>
Selects all objects in schematic </pre>

View File

@ -772,7 +772,7 @@ int win_regexec(const char *options, const char *pattern, const char *name)
* 0 : regex search
* 1 : exact search
*/
int search(const char *tok, const char *val, int sub, int sel, int match_case)
int search(const char *tok, const char *val, int sub, int sel, int match_case, int dr)
{
int save_draw;
int i,c, col = 7,tmp,bus=0;
@ -1060,11 +1060,11 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case)
if(found) {
if(tclgetboolvar("incr_hilight")) incr_hilight_color();
if(sel == -1) {
draw();
if(dr) draw();
}
if(sel) {
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
draw_selection(xctx->gc[SELLAYER], 0);
if(dr) draw_selection(xctx->gc[SELLAYER], 0);
}
else redraw_hilights(0);
}

View File

@ -5104,7 +5104,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_SetResult(interp, my_itoa(res), TCL_VOLATILE);
}
/* search regex|exact select tok val [match_case]
/* search regex|exact select tok val [no_match_case] [nodraw]
* Search instances / wires / rects / texts with attribute string containing 'tok'
* and value 'val'
* search can be exact ('exact') or as a regular expression ('regex')
@ -5120,10 +5120,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* cell::name : will search for 'val' in the symbol name
* cell::<attr> will search for 'val' in symbol attribute 'attr'
* example: xschem search regex 0 cell::template GAIN=100
* match_case:
* 1 : Match case
* 0 : Do not match case
* If not given assume 1 (Match case)
* if 'no_match_case' is specified do not consider case sensitivity in search
* if 'nodraw' is specified do not draw search result
*/
else if(!strcmp(argv[1], "search") || !strcmp(argv[1], "searchmenu"))
{
@ -5132,16 +5130,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
/* xschem search regex|exact 0|1|-1 tok val [match_case] */
int select, r;
int match_case = 1;
int draw = 1;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 6 && argv[6][0] == '0') match_case = 0;
if(argc > 6) {
int i;
for(i = 0; i < argc; i++) {
if(!strcmp(argv[i], "no_match_case")) match_case = 0;
if(!strcmp(argv[i], "nodraw")) draw = 0;
}
}
if(argc < 6) {
Tcl_SetResult(interp, "xschem search requires 4 or 5 additional fields.", TCL_STATIC);
return TCL_ERROR;
}
if(argc > 5) {
select = atoi(argv[3]);
if(!strcmp(argv[2], "regex") ) r = search(argv[4],argv[5],0,select, match_case);
else r = search(argv[4],argv[5],1,select, match_case);
if(!strcmp(argv[2], "regex") ) r = search(argv[4],argv[5],0,select, match_case, draw);
else r = search(argv[4],argv[5],1,select, match_case, draw);
if(r == 0) {
if(has_x && !strcmp(argv[1], "searchmenu"))
tcleval("tk_messageBox -type ok -parent [xschem get topwindow] -message {Not found.}");
@ -5153,7 +5158,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
/* select instance|wire|text id [clear] [fast]
/* select instance|wire|text id [clear] [fast] [nodraw]
* select rect|line|poly|arc layer id [clear] [fast]
* Select indicated instance or wire or text, or
* Select indicated (layer, number) rectangle, line, polygon, arc.
@ -5161,7 +5166,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* for all other objects 'id' is the position in the respective arrays
* if 'clear' is specified does an unselect operation
* if 'fast' is specified avoid sending information to infowindow and status bar
* if 'nodraw' is given on select instance do not draw selection
* if 'nodraw' is given do not draw selection
* returns 1 if something selected, 0 otherwise */
else if(!strcmp(argv[1], "select"))
{
@ -5184,7 +5189,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
for(i = 4; i < argc; i++) {
if(!strcmp(argv[i], "clear")) sel = 0;
if(!strcmp(argv[i], "fast")) fast |= 1;
if(!strcmp(argv[i], "nodraw") && !strcmp(argv[2], "instance")) fast |= 2;
if(!strcmp(argv[i], "nodraw")) fast |= 2;
}
}
if(!strcmp(argv[2], "instance") && argc > 3) {

View File

@ -902,7 +902,7 @@ void select_wire(int i,unsigned short select_mode, int fast, int override_lock)
/*my_strncpy(s,xctx->wire[i].prop_ptr!=NULL?xctx->wire[i].prop_ptr:"<NULL>",256); */
if(!strboolcmp(get_tok_value(xctx->wire[i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if( !fast )
if(!(fast & 1))
{
my_snprintf(str, S(str), "Info: selected wire: n=%d end1=%d end2=%d\nnode=%s",i,
xctx->wire[i].end1, xctx->wire[i].end2,
@ -925,16 +925,22 @@ void select_wire(int i,unsigned short select_mode, int fast, int override_lock)
if( xctx->wire[i].sel == SELECTED) set_first_sel(WIRE, i, 0);
if(select_mode) {
dbg(1, "select(): wire[%d].end1=%d, ,end2=%d\n", i, xctx->wire[i].end1, xctx->wire[i].end2);
if(xctx->wire[i].bus)
drawtempline(xctx->gc[SELLAYER], THICK, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2);
else
drawtempline(xctx->gc[SELLAYER], ADD, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2);
if(xctx->wire[i].bus) {
if(!(fast & 2)) drawtempline(xctx->gc[SELLAYER], THICK, xctx->wire[i].x1, xctx->wire[i].y1,
xctx->wire[i].x2, xctx->wire[i].y2);
} else {
if(!(fast & 2)) drawtempline(xctx->gc[SELLAYER], ADD, xctx->wire[i].x1, xctx->wire[i].y1,
xctx->wire[i].x2, xctx->wire[i].y2);
}
}
else {
if(xctx->wire[i].bus)
drawtempline(xctx->gctiled, THICK, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2);
else
drawtempline(xctx->gctiled, NOW, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2);
if(xctx->wire[i].bus) {
if(!(fast & 2)) drawtempline(xctx->gctiled, THICK, xctx->wire[i].x1, xctx->wire[i].y1,
xctx->wire[i].x2, xctx->wire[i].y2);
} else {
if(!(fast & 2)) drawtempline(xctx->gctiled, NOW, xctx->wire[i].x1, xctx->wire[i].y1,
xctx->wire[i].x2, xctx->wire[i].y2);
}
}
xctx->need_reb_sel_arr=1;
}
@ -1061,6 +1067,10 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc
xctx->need_reb_sel_arr=1;
}
/* fast == 1: do not update status line
* fast == 2: do not draw / undraw selected elements
* fast == 3: 1 + 2
*/
void select_text(int i, unsigned short select_mode, int fast, int override_lock)
{
char str[1024]; /* overflow safe */
@ -1070,7 +1080,7 @@ void select_text(int i, unsigned short select_mode, int fast, int override_lock)
#endif
if(!strboolcmp(get_tok_value(xctx->text[i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast) {
if(!(fast & 1)) {
my_strncpy(s,xctx->text[i].prop_ptr!=NULL?xctx->text[i].prop_ptr:"<NULL>",S(s));
my_snprintf(str, S(str), "Info: selected text %d: properties: %s", i,s);
statusmsg(str,3);
@ -1084,12 +1094,12 @@ void select_text(int i, unsigned short select_mode, int fast, int override_lock)
#endif
if(select_mode) {
set_first_sel(xTEXT, i, 0);
draw_temp_string(xctx->gc[SELLAYER],ADD, get_text_floater(i),
if(!(fast & 2)) draw_temp_string(xctx->gc[SELLAYER],ADD, get_text_floater(i),
xctx->text[i].rot, xctx->text[i].flip, xctx->text[i].hcenter, xctx->text[i].vcenter,
xctx->text[i].x0, xctx->text[i].y0,
xctx->text[i].xscale, xctx->text[i].yscale);
} else {
draw_temp_string(xctx->gctiled,NOW, get_text_floater(i),
if(!(fast & 2)) draw_temp_string(xctx->gctiled,NOW, get_text_floater(i),
xctx->text[i].rot, xctx->text[i].flip, xctx->text[i].hcenter, xctx->text[i].vcenter,
xctx->text[i].x0, xctx->text[i].y0,
xctx->text[i].xscale, xctx->text[i].yscale);
@ -1102,6 +1112,10 @@ void select_text(int i, unsigned short select_mode, int fast, int override_lock)
xctx->need_reb_sel_arr=1;
}
/* fast == 1: do not update status line
* fast == 2: do not draw / undraw selected elements
* fast == 3: 1 + 2
*/
void select_box(int c, int i, unsigned short select_mode, int fast, int override_lock)
{
char str[1024]; /* overflow safe */
@ -1109,7 +1123,7 @@ void select_box(int c, int i, unsigned short select_mode, int fast, int override
if(!strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast)
if(!(fast & 1))
{
my_strncpy(s,xctx->rect[c][i].prop_ptr!=NULL?xctx->rect[c][i].prop_ptr:"<NULL>",S(s));
my_snprintf(str, S(str), "Info: selected box : layer=%d, n=%d properties: %s",c-4,i,s);
@ -1130,11 +1144,11 @@ void select_box(int c, int i, unsigned short select_mode, int fast, int override
} else {
xctx->rect[c][i].sel |= select_mode;
}
drawtemprect(xctx->gc[SELLAYER], ADD, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
if(!(fast & 2)) drawtemprect(xctx->gc[SELLAYER], ADD, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
xctx->rect[c][i].x2, xctx->rect[c][i].y2);
} else {
xctx->rect[c][i].sel = 0;
drawtemprect(xctx->gctiled, NOW, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
if(!(fast & 2)) drawtemprect(xctx->gctiled, NOW, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
xctx->rect[c][i].x2, xctx->rect[c][i].y2);
}
if( xctx->rect[c][i].sel == (SELECTED1|SELECTED2|SELECTED3|SELECTED4)) xctx->rect[c][i].sel = SELECTED;
@ -1144,11 +1158,15 @@ void select_box(int c, int i, unsigned short select_mode, int fast, int override
/* fast == 1: do not update status line
* fast == 2: do not draw / undraw selected elements
* fast == 3: 1 + 2
*/
void select_arc(int c, int i, unsigned short select_mode, int fast, int override_lock)
{
char str[1024]; /* overflow safe */
char s[256]; /* overflow safe */
if(!fast)
if(!(fast & 1))
{
my_strncpy(s,xctx->rect[c][i].prop_ptr!=NULL?xctx->rect[c][i].prop_ptr:"<NULL>",S(s));
my_snprintf(str, S(str), "Info: selected arc : layer=%d, n=%d properties: %s",c-4,i,s);
@ -1161,11 +1179,11 @@ void select_arc(int c, int i, unsigned short select_mode, int fast, int override
}
if(select_mode) {
xctx->arc[c][i].sel = select_mode;
drawtemparc(xctx->gc[SELLAYER], ADD, xctx->arc[c][i].x, xctx->arc[c][i].y,
if(!(fast & 2)) drawtemparc(xctx->gc[SELLAYER], ADD, xctx->arc[c][i].x, xctx->arc[c][i].y,
xctx->arc[c][i].r, xctx->arc[c][i].a, xctx->arc[c][i].b);
} else {
xctx->arc[c][i].sel = 0;
drawtemparc(xctx->gctiled, NOW, xctx->arc[c][i].x, xctx->arc[c][i].y,
if(!(fast & 2)) drawtemparc(xctx->gctiled, NOW, xctx->arc[c][i].x, xctx->arc[c][i].y,
xctx->arc[c][i].r, xctx->arc[c][i].a, xctx->arc[c][i].b);
}
if(xctx->arc[c][i].sel == SELECTED) set_first_sel(ARC, i, c);
@ -1182,7 +1200,7 @@ void select_polygon(int c, int i, unsigned short select_mode, int fast, int over
if(!strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast)
if(!(fast & 1) )
{
my_strncpy(s,xctx->poly[c][i].prop_ptr!=NULL?xctx->poly[c][i].prop_ptr:"<NULL>",S(s));
my_snprintf(str, S(str), "Info: selected polygon: layer=%d, n=%d properties: %s",c-4,i,s);
@ -1195,11 +1213,11 @@ void select_polygon(int c, int i, unsigned short select_mode, int fast, int over
bezier = 2 + !strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr, "bezier", 0), "true");
xctx->poly[c][i].sel = select_mode;
if(select_mode) {
drawtemppolygon(xctx->gc[SELLAYER], NOW,
if(!(fast & 2)) drawtemppolygon(xctx->gc[SELLAYER], NOW,
xctx->poly[c][i].x, xctx->poly[c][i].y, xctx->poly[c][i].points, bezier);
}
else {
drawtemppolygon(xctx->gctiled, NOW,
if(!(fast & 2)) drawtemppolygon(xctx->gctiled, NOW,
xctx->poly[c][i].x, xctx->poly[c][i].y, xctx->poly[c][i].points, bezier);
}
if(xctx->poly[c][i].sel == SELECTED) set_first_sel(POLYGON, i, c);
@ -1213,7 +1231,7 @@ void select_line(int c, int i, unsigned short select_mode, int fast, int overrid
if(!strboolcmp(get_tok_value(xctx->line[c][i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast)
if(!(fast & 1) )
{
my_strncpy(s,xctx->line[c][i].prop_ptr!=NULL?xctx->line[c][i].prop_ptr:"<NULL>",S(s));
my_snprintf(str, S(str), "Info: selected line: layer=%d, n=%d properties: %s",c-4,i,s);
@ -1234,20 +1252,22 @@ void select_line(int c, int i, unsigned short select_mode, int fast, int overrid
}
if(xctx->line[c][i].sel == SELECTED) set_first_sel(LINE, i, c);
if(select_mode) {
if(xctx->line[c][i].bus)
drawtempline(xctx->gc[SELLAYER], THICK, xctx->line[c][i].x1, xctx->line[c][i].y1,
if(xctx->line[c][i].bus) {
if(!(fast & 2)) drawtempline(xctx->gc[SELLAYER], THICK, xctx->line[c][i].x1, xctx->line[c][i].y1,
xctx->line[c][i].x2, xctx->line[c][i].y2);
else
drawtempline(xctx->gc[SELLAYER], ADD, xctx->line[c][i].x1, xctx->line[c][i].y1,
} else {
if(!(fast & 2)) drawtempline(xctx->gc[SELLAYER], ADD, xctx->line[c][i].x1, xctx->line[c][i].y1,
xctx->line[c][i].x2, xctx->line[c][i].y2);
}
}
else {
if(xctx->line[c][i].bus)
drawtempline(xctx->gctiled, THICK, xctx->line[c][i].x1, xctx->line[c][i].y1,
if(xctx->line[c][i].bus) {
if(!(fast & 2)) drawtempline(xctx->gctiled, THICK, xctx->line[c][i].x1, xctx->line[c][i].y1,
xctx->line[c][i].x2, xctx->line[c][i].y2);
else
drawtempline(xctx->gctiled, NOW, xctx->line[c][i].x1, xctx->line[c][i].y1,
} else {
if(!(fast & 2)) drawtempline(xctx->gctiled, NOW, xctx->line[c][i].x1, xctx->line[c][i].y1,
xctx->line[c][i].x2, xctx->line[c][i].y2);
}
}
xctx->need_reb_sel_arr=1;
}

View File

@ -1342,7 +1342,7 @@ extern Hilight_hashentry *inst_hilight_hash_lookup(int i, int value, int what);
/* wrapper to bus_hilight_hash_lookup that provides a signal path instead of using xctx->sch_path */
extern Hilight_hashentry *hier_hilight_hash_lookup(const char *token, int value, const char *path, int what);
extern Hilight_hashentry *hilight_lookup(const char *token, int value, int what);
extern int search(const char *tok, const char *val, int sub, int sel, int match_case);
extern int search(const char *tok, const char *val, int sub, int sel, int match_case, int dr);
extern int process_options(int argc, char **argv);
extern void calc_drawing_bbox(xRect *boundbox, int selected);
extern int ps_draw(int what, int fullzoom, int eps);