diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index 5aeac421..f079f211 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -1002,7 +1002,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" open file or opening a new(not existing) file. 'noundoreset': do not reset the undo history 'symbol': do not load symbols (used if loading a symbol instead of a schematic) - 'nofullzoom': do not do a full zoom on new schematic. + 'nofullzoom': do not do a full zoom on new schematic. + 'nodraw': do not draw.
  • load_new_window [f]
  •     Load schematic in a new tab/window. If 'f' not given prompt user
        if 'f' is given as empty '{}' then open untitled.sch 
    @@ -1575,7 +1576,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Remove leading and trailing chars matching any character in 'sep' from str
  • trim_wires
  •     Remove operlapping wires, join lines, trim wires at intersections 
    -
  • undo [redo [set_modify]
  • +   
  • undo [redo [set_modify]]
  •     Undo last action. Optional integers redo and set_modify are passed to pop_undo() 
  • undo_type disk|memory
  •     Use disk file ('disk') or RAM ('memory') for undo bufer
    diff --git a/src/callback.c b/src/callback.c index 9a1f64d5..6c1a6f5a 100644 --- a/src/callback.c +++ b/src/callback.c @@ -190,6 +190,8 @@ static void start_line(double mx, double my) static void start_wire(double mx, double my) { + dbg(1, "start_wire(): ui_state=%d, ui_state2=%d last_command=%d\n", + xctx->ui_state, xctx->ui_state2, xctx->last_command); xctx->last_command = STARTWIRE; if(xctx->ui_state & STARTWIRE) { if(xctx->constr_mv != 2) { @@ -1340,6 +1342,9 @@ static int end_place_move_copy_zoom() static int check_menu_start_commands(double c_snap) { + dbg(1, "check_menu_start_commands(): ui_state=%d, ui_state2=%d last_command=%d\n", + xctx->ui_state, xctx->ui_state2, xctx->last_command); + if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT)) { break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1); xctx->ui_state &=~MENUSTART; @@ -1360,10 +1365,22 @@ static int check_menu_start_commands(double c_snap) return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) { - xctx->mx_double_save=xctx->mousex_snap; - xctx->my_double_save=xctx->mousey_snap; - new_wire(PLACE, xctx->mousex_snap, xctx->mousey_snap); + int prev_state = xctx->ui_state; + if(xctx->semaphore >= 2) return 0; + start_wire(xctx->mousex_snap, xctx->mousey_snap); + if(prev_state == STARTWIRE) { + tcleval("set constr_mv 0" ); + xctx->constr_mv=0; + } xctx->ui_state &=~MENUSTART; + xctx->ui_state2 = 0; + + /* + * xctx->mx_double_save=xctx->mousex_snap; + * xctx->my_double_save=xctx->mousey_snap; + * new_wire(PLACE, xctx->mousex_snap, xctx->mousey_snap); + * xctx->ui_state &=~MENUSTART; + */ return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTSNAPWIRE)) { @@ -1377,10 +1394,22 @@ static int check_menu_start_commands(double c_snap) return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTLINE)) { - xctx->mx_double_save=xctx->mousex_snap; - xctx->my_double_save=xctx->mousey_snap; - new_line(PLACE, xctx->mousex_snap, xctx->mousey_snap); + int prev_state = xctx->ui_state; + if(xctx->semaphore >= 2) return 0; + start_line(xctx->mousex_snap, xctx->mousey_snap); + if(prev_state == STARTLINE) { + tcleval("set constr_mv 0" ); + xctx->constr_mv=0; + } xctx->ui_state &=~MENUSTART; + xctx->ui_state2 = 0; + + /* + * xctx->mx_double_save=xctx->mousex_snap; + * xctx->my_double_save=xctx->mousey_snap; + * new_line(PLACE, xctx->mousex_snap, xctx->mousey_snap); + * xctx->ui_state &=~MENUSTART; + */ return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTRECT)) { @@ -2794,7 +2823,7 @@ int rstate; /* (reduced state, without ShiftMask) */ tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] " "-message {Run circuit simulation?}"); if(strcmp(tclresult(),"ok")==0) { - tcleval("[xschem get top_path].menubar.simulate invoke"); + tcleval("[xschem get top_path].menubar invoke Simulate"); } break; } diff --git a/src/save.c b/src/save.c index c0210aa0..145fa283 100644 --- a/src/save.c +++ b/src/save.c @@ -3493,7 +3493,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler /* xctx->time_last_modify = time(NULL); */ /* file does not exist, set mtime to current time */ xctx->time_last_modify = 0; /* file does not exist, set mtime to 0 (undefined)*/ } - } + } else {xctx->time_last_modify = 0;} /* undefined */ if(generator) { char *cmd; cmd = get_generator_command(fname); diff --git a/src/scheduler.c b/src/scheduler.c index 7a46ccbc..51af0134 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1797,7 +1797,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg return TCL_ERROR; } if((i = get_instance(argv[3])) < 0 ) { - Tcl_SetResult(interp, "xschem getprop: instance not found", TCL_STATIC); + Tcl_AppendResult(interp, "xschem getprop: instance not found:", argv[3], NULL); return TCL_ERROR; } if(!strcmp(argv[2], "instance_notcl")) with_quotes = 2; @@ -2035,6 +2035,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg my_snprintf(res, S(res), "hilight_nets=%d\n", xctx->hilight_nets); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "semaphore=%d\n", xctx->semaphore); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "ui_state=%d\n", xctx->ui_state); Tcl_AppendResult(interp, res, NULL); + my_snprintf(res, S(res), "ui_state2=%d\n", xctx->ui_state2); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "last_command=%d\n", xctx->last_command); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "prep_net_structs=%d\n", xctx->prep_net_structs); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "prep_hi_structs=%d\n", xctx->prep_hi_structs); Tcl_AppendResult(interp, res, NULL); @@ -2697,6 +2698,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg set_modify(1); } else { + xctx->last_command = 0; xctx->ui_state |= MENUSTART; xctx->ui_state2 = MENUSTARTLINE; } @@ -2784,10 +2786,11 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg * 'noundoreset': do not reset the undo history * 'symbol': do not load symbols (used if loading a symbol instead of a schematic) * 'nofullzoom': do not do a full zoom on new schematic. + * 'nodraw': do not draw. */ else if(!strcmp(argv[1], "load") ) { - int load_symbols = 1, force = 1, undo_reset = 1, nofullzoom = 0; + int load_symbols = 1, force = 1, undo_reset = 1, nofullzoom = 0, nodraw = 0; size_t i; if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(argc > 3) { @@ -2796,6 +2799,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg if(!strcmp(argv[i], "gui")) force = 0; if(!strcmp(argv[i], "noundoreset")) undo_reset = 0; if(!strcmp(argv[i], "nofullzoom")) nofullzoom = 1; + if(!strcmp(argv[i], "nodraw")) {nofullzoom = 1; nodraw = 1;} } } if(argc>2) { @@ -2820,9 +2824,11 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else dbg(0, "xschem load: %s already open: %s\n", f, win_path); } if(!skip) { + int ret; clear_all_hilights(); unselect_all(1); - if(!undo_reset) xctx->push_undo(); + /* no implicit undo: if needed do it before loading */ + /* if(!undo_reset) xctx->push_undo(); */ xctx->currsch = 0; remove_symbols(); if(!nofullzoom) { @@ -2832,15 +2838,17 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg xctx->yorigin=CADINITIALY; } dbg(1, "scheduler: undo_reset=%d\n", undo_reset); - load_schematic(load_symbols, f, undo_reset, !force); + ret = load_schematic(load_symbols, f, undo_reset, !force); + dbg(1, "xschem load: ret=%d\n", ret); tclvareval("update_recent_file {", f, "}", NULL); my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], "."); if(xctx->portmap[xctx->currsch].table) str_hash_free(&xctx->portmap[xctx->currsch]); str_hash_init(&xctx->portmap[xctx->currsch], HASHSIZE); xctx->sch_path_hash[xctx->currsch] = 0; xctx->sch_inst_number[xctx->currsch] = 1; - if(nofullzoom) draw(); - else zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97); + if(nofullzoom) { + if(!nodraw) draw(); + } else zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97); } } } @@ -6110,6 +6118,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg set_modify(1); } else { + xctx->last_command = 0; xctx->ui_state |= MENUSTART; xctx->ui_state2 = MENUSTARTWIRE; } diff --git a/src/token.c b/src/token.c index 584724f4..18c8454e 100644 --- a/src/token.c +++ b/src/token.c @@ -1868,7 +1868,6 @@ static int has_included_subcircuit(int inst, int symbol, char **result) tclvareval("has_included_subcircuit {", get_cell(symname, 0), "} {", translated_sym_def, "}", NULL); my_free(_ALLOC_ID_, &templ); - my_free(_ALLOC_ID_, &symname); my_free(_ALLOC_ID_, &symname_attr); if(tclresult()[0]) { char *subckt_pin, *pin_save; @@ -1935,14 +1934,16 @@ static int has_included_subcircuit(int inst, int symbol, char **result) ret = 1; my_mstrcat(_ALLOC_ID_, result, tmp_result, NULL); } else { - dbg(0, "has_included_subcircuit(): symbol and .subckt pins do not match. Discard .subckt port order\n"); + dbg(0, "has_included_subcircuit(): %s symbol and .subckt pins do not match. Discard port order\n", + symname); if(has_x) - tcleval("alert_ {has_included_subcircuit(): " - "symbol and .subckt pins do not match. Discard .subckt port order}"); + tclvareval("alert_ {has_included_subcircuit(): ", symname, + " symbol and .subckt pins do not match. Discard .subckt port order}", NULL); } if(tmp_result) my_free(_ALLOC_ID_, &tmp_result); my_free(_ALLOC_ID_, &subckt_pinlist); } + my_free(_ALLOC_ID_, &symname); } my_free(_ALLOC_ID_, &spice_sym_def); return ret; diff --git a/src/xschem.tcl b/src/xschem.tcl index e9df503f..f4adc72c 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -1797,14 +1797,14 @@ proc cellview {} { frame $sf.f$i pack $sf.f$i -side top -fill x label $sf.f$i.l -text $sym -width 20 -anchor w -padx 4 -borderwidth 1 \ - -relief sunken -pady 1 -bg grey80 -font $font + -relief sunken -pady 1 -font $font # puts $sf.f$i.s entry $sf.f$i.s -width 50 -borderwidth 1 -relief sunken -font $font if { $spice_sym_def eq {}} { if {![file exists $abs_sch]} { $sf.f$i.s configure -bg red } elseif {$default_sch ne $sch} { - $sf.f$i.s configure -bg cyan + $sf.f$i.s configure -bg green } } balloon $sf.f$i.s $abs_sch @@ -1823,14 +1823,14 @@ proc cellview {} { bind $sf.f$i.s " if {\[$sf.f$i.s get\] ne {$sch}} { if { \[file exists \[abs_sym_path \[$sf.f$i.s get\]\]\] } { - $sf.f$i.s configure -bg cyan + $sf.f$i.s configure -bg green } else { puts \"$sch --- \[$sf.f$i.s get\]\" $sf.f$i.s configure -bg red } } else { if { \[file exists \[abs_sym_path \[$sf.f$i.s get\]\]\] } { - $sf.f$i.s configure -bg grey90 + $sf.f$i.s configure -bg [option get . background {}] } else { $sf.f$i.s configure -bg red } @@ -1858,27 +1858,53 @@ proc cellview {} { ############ traversal -# This proc traverses the hierarchy and prints all instances in design. - -proc traversal_editfile {w parent_sch sch} { - global traversal_cnt - # puts "parent sch: $parent_sch" - set sf .cv.center.f.scrl - if {[$w get] ne $sch} { - if { [file exists [abs_sym_path [$w get]]] } { - $w configure -bg cyan +proc traversal_update_schematic {w parent_sch instname default_sch} { + if {$parent_sch eq {}} {return} + puts "traversal_update_schematic: $w $parent_sch $instname--> [$w get]" + set current [xschem get current_name] + xschem load $parent_sch noundoreset nodraw + set sch [xschem getprop instance $instname schematic] + if { $sch ne [$w get]} { + if { [$w get] eq $default_sch} { + xschem setprop instance $instname schematic fast ;# remove schematic attr on instance } else { + xschem setprop instance $instname schematic [$w get] fast ;# set schematic attr on instance + } + xschem set_modify 1 + xschem save + } + xschem load $current noundoreset nodraw +} + +proc traversal_setlabels {w parent_sch sch instname default_sch inst_spice_sym_def sym_spice_sym_def} { + global traversal_cnt + set sf .cv.center.f.scrl + puts "traversal_setlabels $w $parent_sch $sch $instname" + traversal_update_schematic $w $parent_sch $instname $default_sch + if {[$w get] ne $default_sch} { + if { $sym_spice_sym_def ne {}} { + $w configure -fg green + $w configure -bg [option get . background {}] + } elseif {$inst_spice_sym_def ne {}} { + $w configure -fg red + $w configure -bg [option get . background {}] + } elseif { [file exists [abs_sym_path [$w get]]] } { + $w configure -fg [option get . foreground {}] + $w configure -bg green + } else { + $w configure -fg [option get . foreground {}] $w configure -bg red } } else { if { [file exists [abs_sym_path [$w get]]] } { - $w configure -bg grey90 + $w configure -bg [option get . background {}] } else { $w configure -bg red } } } +# This proc traverses the hierarchy and prints all instances in design. proc traversal {{only_subckts 0} {all_hierarchy 1}} { global keep_symbols traversal_cnt set traversal_cnt 0 @@ -1899,8 +1925,8 @@ proc traversal {{only_subckts 0} {all_hierarchy 1}} { frame .cv.top label .cv.top.inst -text {INSTANCE} -width 25 -bg grey60 -anchor w -padx 4 -font $font - label .cv.top.sym -text {SYMBOL} -width 35 -bg grey60 -anchor w -padx 4 -font $font - label .cv.top.sch -text SCHEMATIC -width 35 -bg grey60 -anchor w -padx 4 -font $font + label .cv.top.sym -text {SYMBOL} -width 30 -bg grey60 -anchor w -padx 4 -font $font + label .cv.top.sch -text SCHEMATIC -width 45 -bg grey60 -anchor w -padx 4 -font $font label .cv.top.pad -text { } -bg grey60 -font $font pack .cv.top.inst -side left -fill x -expand 1 pack .cv.top.sym .cv.top.sch -side left -fill x @@ -1924,12 +1950,12 @@ proc traversal {{only_subckts 0} {all_hierarchy 1}} { bind .cv.center.f {sframeyview .cv.center} bind .cv { sframeyview .cv.center scroll -0.1} bind .cv { sframeyview .cv.center scroll 0.1} - + bind .cv {destroy .cv} } # recursive procedure proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} { - global nolist_libs traversal_cnt + global nolist_libs traversal_cnt retval if {[info tclversion] >= 8.5} { set font {TkDefaultFont 10 bold} ;# Monospace } else { @@ -1945,12 +1971,13 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} { for {set i 0} { $i < $instances} { incr i} { set instname [xschem getprop instance $i name] set symbol [xschem getprop instance $i cell::name] + set default_sch [add_ext $symbol .sch] set abs_symbol [abs_sym_path $symbol] set type [xschem getprop symbol $symbol type] set schematic [xschem get_sch_from_sym $i] set sch_exists [expr {[file exists $schematic] ? {} : {**missing**}}] set sch_tail [rel_sym_path $schematic] - set sch_rootname [file rootname [file tail $schematic]] + set sch_rootname [file tail [file rootname $sch_tail]] set inst_spice_sym_def [xschem getprop instance $i spice_sym_def] set sym_spice_sym_def [xschem getprop instance $i cell::spice_sym_def] if {$only_subckts && ($type ne {subcircuit})} { continue } @@ -1970,10 +1997,10 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} { pack $sf.f$traversal_cnt -side top -fill x label $sf.f$traversal_cnt.i -text "[spaces $level 2]$schpath$instname" \ -width 25 -anchor w -padx 4 -borderwidth 1 \ - -relief sunken -pady 1 -bg grey80 -font $font - label $sf.f$traversal_cnt.l -text $symbol -width 35 -anchor w -padx 4 -borderwidth 1 \ - -relief sunken -pady 1 -bg grey80 -font $font - entry $sf.f$traversal_cnt.s -width 35 -borderwidth 1 -relief sunken -font $font + -relief sunken -pady 1 -font $font + label $sf.f$traversal_cnt.l -text $symbol -width 30 -anchor w -padx 4 -borderwidth 1 \ + -relief sunken -pady 1 -font $font + entry $sf.f$traversal_cnt.s -width 45 -borderwidth 1 -relief sunken -font $font if {$type eq {subcircuit}} { if {$inst_spice_sym_def ne {}} { @@ -1993,13 +2020,18 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} { if { {$sym_spice_sym_def} eq {} && {$inst_spice_sym_def} eq {}} { xschem load_new_window \[$sf.f$traversal_cnt.s get\] } elseif {{$sym_spice_sym_def} ne {}} { - viewdata {$sym_spice_sym_def} + editdata {$sym_spice_sym_def} {Symbol spice_sym_def attribute} } else { - viewdata {$inst_spice_sym_def} + editdata {$inst_spice_sym_def} {Instance spice_sym_def attribute} }" if { $sym_spice_sym_def eq {} && $inst_spice_sym_def eq {}} { - bind $sf.f$traversal_cnt.s "traversal_editfile %W $parent_sch $sch_tail" + bind $sf.f$traversal_cnt.s " + traversal_setlabels %W {$parent_sch} $sch_tail {$instname} {$default_sch} \ + {$inst_spice_sym_def} {$sym_spice_sym_def} + " } + traversal_setlabels $sf.f$traversal_cnt.s {} $sch_tail $instname $default_sch \ + $inst_spice_sym_def $sym_spice_sym_def pack $sf.f$traversal_cnt.i -side left -fill x -expand 1 pack $sf.f$traversal_cnt.l $sf.f$traversal_cnt.s -side left -fill x pack $sf.f$traversal_cnt.bsym $sf.f$traversal_cnt.bsch -side left @@ -6035,6 +6067,40 @@ proc infowindow {} { return {} } +proc editdata {{data {}} {title {Edit data}} } { + global text_tabs_setting tabstop retval + set window .editdata + set retval $data + xschem set semaphore [expr {[xschem get semaphore] +1}] + toplevel $window + wm title $window $title + wm iconname $window $title + # wm transient $window [xschem get topwindow] + frame $window.buttons + pack $window.buttons -side bottom -fill x -pady 2m + button $window.buttons.ok -text OK -command " + set retval \[$window.text get 1.0 {end - 1 chars}\]; destroy $window + " + button $window.buttons.cancel -text Cancel -command "destroy $window" + pack $window.buttons.ok -side left -expand 1 + pack $window.buttons.cancel -side left -expand 1 + + eval text $window.text -undo 1 -relief sunken -bd 2 -yscrollcommand \"$window.yscroll set\" -setgrid 1 \ + -xscrollcommand \"$window.xscroll set\" -wrap none -height 30 $text_tabs_setting + scrollbar $window.yscroll -command "$window.text yview" + scrollbar $window.xscroll -command "$window.text xview" -orient horiz + pack $window.yscroll -side right -fill y + pack $window.text -expand yes -fill both + pack $window.xscroll -side bottom -fill x + bind $window "$window.buttons.cancel invoke" + + # 20171103 insert at insertion cursor(insert tag) instead of 0.0 + $window.text insert insert $data + tkwait window $window + xschem set semaphore [expr {[xschem get semaphore] -1}] + return $retval +} + proc textwindow {filename {ro {}}} { global textwindow_wcounter global textwindow_w @@ -8706,7 +8772,7 @@ if { [info exists has_x]} { option add *activeForeground black startupFile option add *background {grey80} startupFile option add *activeBackground {#f8f8f8} startupFile - option add *disabledForeground {black} startupFile + option add *disabledForeground {grey50} startupFile option add *disabledBackground {grey70} startupFile option add *readonlyBackground {grey70} startupFile option add *highlightBackground {white} startupFile @@ -8724,7 +8790,7 @@ if { [info exists has_x]} { option add *activeForeground white startupFile option add *background {grey20} startupFile option add *activeBackground {grey10} startupFile - option add *disabledForeground {white} startupFile + option add *disabledForeground {grey50} startupFile option add *disabledBackground {grey20} startupFile option add *readonlyBackground {grey20} startupFile option add *highlightBackground {black} startupFile