From bf344309f0e03ad8590160712061530bc927c486 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Wed, 29 Oct 2025 09:06:07 +0100 Subject: [PATCH] implement "nodraw" flag in all object selections in the "xschem select" command, implement the "nodraw" flag in "xschem search" command --- doc/xschem_man/developer_info.html | 12 ++--- src/hilight.c | 6 +-- src/scheduler.c | 27 ++++++---- src/select.c | 80 +++++++++++++++++++----------- src/xschem.h | 2 +- 5 files changed, 75 insertions(+), 52 deletions(-) diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index 6369efa0..d75c05ef 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -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 -
  • 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')
    @@ -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::<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)
    -
  • select instance|wire|text id [clear] [fast]
  • +    if 'no_match_case' is specified do not consider case sensitivity in search
    +    if 'nodraw' is specified do not draw search result
    +
  • 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.
    @@ -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 
  • select_all
  •     Selects all objects in schematic 
    diff --git a/src/hilight.c b/src/hilight.c index 9b8673c9..f90bfc92 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -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); } diff --git a/src/scheduler.c b/src/scheduler.c index 38778dd8..610bf5a3 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -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:: 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) { diff --git a/src/select.c b/src/select.c index 7561173d..73a7e23b 100644 --- a/src/select.c +++ b/src/select.c @@ -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:"",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:"",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:"",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:"",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:"",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:"",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; } diff --git a/src/xschem.h b/src/xschem.h index 2c72d534..6aca17ed 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -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);