cleanup in tabbed/multi-context code, remoevd redundant functions, more tests in xschemtest

This commit is contained in:
Stefan Frederik 2022-01-11 01:09:56 +01:00
parent d6b513e1e2
commit 7d3c19441d
10 changed files with 116 additions and 135 deletions

View File

@ -982,9 +982,12 @@ void symbol_in_new_window(void)
if(xctx->lastsel !=1 || xctx->sel_array[0].type!=ELEMENT)
{
my_strncpy(filename, xctx->sch[xctx->currsch], S(filename));
if(tclgetvar("tabbed_interface")[0] == '1' && !check_loaded(filename, win_path)) {
tcleval("create_new_tab");
tclvareval("xschem load ", filename, NULL);
if(tclgetvar("tabbed_interface")[0] == '1') {
dbg(1, "symbol_in_new_window(): filename=%s, current=%s\n",
filename, xctx->sch[xctx->currsch]);
if(!check_loaded(filename, win_path)) {
new_schematic("create", NULL, filename);
}
} else {
new_xschem_process(filename, 1);
}
@ -994,8 +997,7 @@ void symbol_in_new_window(void)
my_strncpy(filename, abs_sym_path(xctx->inst[xctx->sel_array[0].n].name, ""), S(filename));
if(tclgetvar("tabbed_interface")[0] == '1') {
if(!check_loaded(filename, win_path)) {
tcleval("create_new_tab");
tclvareval("xschem load ", filename, NULL);
new_schematic("create", NULL, filename);
}
} else {
new_xschem_process(filename, 1);
@ -1040,8 +1042,7 @@ void schematic_in_new_window(void)
if(tclgetvar("tabbed_interface")[0] == '1') {
if(!check_loaded(filename, win_path)) {
tcleval("create_new_tab");
tclvareval("xschem load ", filename, NULL);
new_schematic("create", NULL, filename);
}
} else {
new_xschem_process(filename, 0);

View File

@ -814,7 +814,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
tclvareval("restore_ctx ", winpath, NULL);
tclvareval("housekeeping_ctx", NULL);
}
new_schematic("switch", winpath, "");
new_schematic("switch_win", winpath, "");
}
/* artificially set semaphore to allow only redraw operations in switched schematic,
* so we don't need to switch tcl context which is costly performance-wise
@ -1636,7 +1636,6 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
}
if(key=='o' && state == ControlMask) /* load */
{
if(xctx->semaphore >= 2) break;
ask_new_file();
break;
@ -2579,7 +2578,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
if(redraw_only) {
xctx->semaphore--; /* decrement articially incremented semaphore (see above) */
dbg(1, "callback(): semaphore >=2 restoring window context: %s <-- %s\n", old_winpath, winpath);
if(old_winpath[0]) new_schematic("switch", old_winpath, "");
if(old_winpath[0]) new_schematic("switch_win", old_winpath, "");
}
else
if(strcmp(old_winpath, winpath)) {

View File

@ -1544,15 +1544,25 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1],"load") )
{
int load_symbols = 1, force = 0, i;
cmd_found = 1;
if(argc==3) {
if(!has_x || !xctx->modified || save(1) != -1 ) { /* save(1)==-1 --> user cancel */
if(argc > 3) {
for(i = 3; i < argc; i++) {
if(!strcmp(argv[i], "symbol")) load_symbols = 0;
if(!strcmp(argv[i], "force")) force = 1;
}
}
if(argc>2) {
i = strlen(argv[2]);
if(i > 4 && !strcmp(argv[2] + i - 4, ".sym")) {
load_symbols = 0;
}
if(force || !has_x || !xctx->modified || save(1) != -1 ) { /* save(1)==-1 --> user cancel */
char f[PATH_MAX];
char win_path[WINDOW_PATH_SIZE];
int skip = 0;
dbg(1, "scheduler(): load: filename=%s\n", argv[2]);
my_strncpy(f, abs_sym_path(argv[2], ""), S(f));
if(f[0] && check_loaded(f, win_path)) {
char msg[PATH_MAX + 100];
my_snprintf(msg, S(msg), "alert_ {xschem load: %s already open: %s}", f, win_path);
@ -1565,7 +1575,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
xctx->currsch = 0;
unselect_all();
remove_symbols();
load_schematic(1, f, 1);
load_schematic(load_symbols, f, 1);
tclvareval("update_recent_file {", f, "}", NULL);
my_strdup(375, &xctx->sch_path[xctx->currsch],".");
xctx->sch_path_hash[xctx->currsch] = 0;
@ -1594,26 +1604,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
tclvareval("update_recent_file {", fullname, "}", NULL);
}
}
else if(!strcmp(argv[1],"load_symbol") )
{
cmd_found = 1;
if(argc==3) {
char f[PATH_MAX];
dbg(1, "scheduler(): load: filename=%s\n", argv[2]);
my_strncpy(f, abs_sym_path(argv[2], ""), S(f));
clear_all_hilights();
xctx->currsch = 0;
unselect_all();
remove_symbols();
load_schematic(0, f, 1);
my_strdup(374, &xctx->sch_path[xctx->currsch],".");
xctx->sch_path_hash[xctx->currsch] = 0;
xctx->sch_inst_number[xctx->currsch] = 1;
zoom_full(1, 0, 1, 0.97);
}
}
else if(!strcmp(argv[1],"log"))
{
cmd_found = 1;
@ -1719,11 +1709,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1],"new_schematic"))
{
int r;
char s[20];
cmd_found = 1;
if(argc == 3) new_schematic(argv[2], NULL, NULL);
else if(argc == 4) new_schematic(argv[2], argv[3], NULL);
else if(argc == 5) new_schematic(argv[2], argv[3], argv[4]);
Tcl_ResetResult(interp);
if(argc == 3) r = new_schematic(argv[2], NULL, NULL);
else if(argc == 4) r = new_schematic(argv[2], argv[3], NULL);
else if(argc == 5) r = new_schematic(argv[2], argv[3], argv[4]);
my_snprintf(s, S(s), "%d", r);
Tcl_SetResult(interp, s, TCL_VOLATILE);
}
else if(!strcmp(argv[1],"new_symbol_window"))

View File

@ -84,7 +84,6 @@ void hier_psprint(void) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;
unselect_all();
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
xctx->pop_undo(0, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
ps_draw(4); /* trailer */
@ -298,8 +297,6 @@ void global_spice_netlist(int global) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;
unselect_all();
/* remove_symbols(); */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
xctx->pop_undo(0, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */

View File

@ -113,8 +113,6 @@ void global_tedax_netlist(int global) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;
unselect_all();
/* remove_symbols(); */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
xctx->pop_undo(0, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */

View File

@ -320,8 +320,6 @@ void global_verilog_netlist(int global) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;
unselect_all();
/* remove_symbols(); */
/* load_schematic(1,xctx->sch[xctx->currsch], 0); */
xctx->pop_undo(0, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */

View File

@ -378,8 +378,6 @@ void global_vhdl_netlist(int global) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;
unselect_all();
/* remove_symbols(); */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
xctx->pop_undo(0, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */

View File

@ -972,8 +972,11 @@ int check_loaded(const char *f, char *win_path)
int found = 0;
for(i = 0; i < MAX_NEW_WINDOWS; i++) {
ctx = save_xctx[i];
/* if only one schematic it is not yet saved in save_xctx */
if(window_count == 0 && i == 0) ctx = xctx;
if(ctx) {
if(!strcmp(ctx->sch[ctx->currsch], f)) {
dbg(1, "check_loaded(): f=%s, sch=%s\n", f, ctx->sch[ctx->currsch]);
found = 1;
my_strncpy(win_path, window_path[i], S(window_path[i]));
break;
@ -983,14 +986,21 @@ int check_loaded(const char *f, char *win_path)
return found;
}
/* caller (via new_schematic() ) should take care of switching tcl context
* before calling this function, see callback()
*
* tclvareval("save_ctx ", old_winpath, NULL);
* tclvareval("restore_ctx ", winpath, NULL);
* tclvareval("housekeeping_ctx", NULL);
*/
static void switch_window(int *window_count, const char *win_path)
{
int i, n;
Tk_Window tkwin;
if(*window_count) {
dbg(1, "new_schematic() switch: %s\n", win_path);
dbg(1, "new_schematic(\"switch_win\"...): %s\n", win_path);
tkwin = Tk_NameToWindow(interp, win_path, mainwindow); /* NULL if win_path not existing */
if(!tkwin) dbg(0, "new_schematic(\"switch\",...): Warning: %s has been destroyed\n", win_path);
if(!tkwin) dbg(0, "new_schematic(\"switch_win\",...): Warning: %s has been destroyed\n", win_path);
n = -1;
if(tkwin) for(i = 0; i < MAX_NEW_WINDOWS; i++) {
if(!strcmp(win_path, window_path[i])) {
@ -999,7 +1009,7 @@ static void switch_window(int *window_count, const char *win_path)
}
}
if(n == -1) {
dbg(0, "new_schematic(\"switch\"...): no window to switch to found: %s\n", win_path);
dbg(0, "new_schematic(\"switch_win\"...): no window to switch to found: %s\n", win_path);
return;
}
/* if window was closed then tkwin == 0 --> do nothing */
@ -1115,10 +1125,12 @@ static void create_new_window(int *window_count, const char *fname)
windowid(toppath);
}
static void create_new_tab(int *window_count, const char *win_path, const char *fname)
static void create_new_tab(int *window_count, const char *fname)
{
int i, n;
char open_path[WINDOW_PATH_SIZE];
char nn[WINDOW_PATH_SIZE];
char win_path[WINDOW_PATH_SIZE];
dbg(1, "new_schematic() new_tab, creating...\n");
if(*window_count && fname && fname[0] && check_loaded(fname, open_path)) {
@ -1157,6 +1169,19 @@ static void create_new_tab(int *window_count, const char *win_path, const char *
dbg(0, "new_schematic(\"newtab\"...): no more free slots\n");
return;
}
/* tcl code to create the tab button */
my_snprintf(nn, S(nn), "%d", n);
tclvareval(
"button ", xctx->top_path, ".tabs.x", nn, " -padx 2 -pady 0 -text Tab2 "
"-command \"xschem new_schematic switch_tab .x", nn, ".drw\"", NULL);
tclvareval(
"if {![info exists tctx::tab_bg] } {set tctx::tab_bg [",
xctx->top_path, ".tabs.x", nn, " cget -bg]}", NULL);
tclvareval("pack ", xctx->top_path, ".tabs.x", nn,
" -before ", xctx->top_path, ".tabs.add -side left", NULL);
/* */
my_snprintf(win_path, S(win_path), "%s.x%d.drw", xctx->top_path, n);
my_strncpy(window_path[n], win_path, S(window_path[n]));
xctx = NULL;
alloc_xschem_data("", win_path); /* alloc data into xctx */
@ -1399,7 +1424,7 @@ int new_schematic(const char *what, const char *win_path, const char *fname)
if(!tabbed_interface) {
create_new_window(&window_count, fname);
} else {
create_new_tab(&window_count, win_path, fname);
create_new_tab(&window_count, fname);
}
} else if(!strcmp(what, "destroy")) {
if(!tabbed_interface) {
@ -1413,12 +1438,10 @@ int new_schematic(const char *what, const char *win_path, const char *fname)
} else {
destroy_all_tabs(&window_count);
}
} else if(!strcmp(what, "switch")) {
if(!tabbed_interface) {
switch_window(&window_count, win_path);
} else {
switch_tab(&window_count, win_path);
}
} else if(!strcmp(what, "switch_win")) {
switch_window(&window_count, win_path); /* see comments in switch_window() */
} else if(!strcmp(what, "switch_tab")) {
switch_tab(&window_count, win_path);
}
return window_count;
}

View File

@ -3720,14 +3720,13 @@ proc setup_tabbed_interface {} {
set top_path {}
if { $tabbed_interface } {
frame $top_path.tabs
button $top_path.tabs.x0 -padx 2 -pady 0 -text Main -command {xschem new_schematic switch .drw}
# button $topwin.tabs.x1 -padx 2 -pady 0 -text Tab1 -command {xschem new_schematic switch .x1.drw}
# button $topwin.tabs.x2 -padx 2 -pady 0 -text Tab2 -command {xschem new_schematic switch .x2.drw}
button $top_path.tabs.add -padx 0 -pady 0 -text { + } -command create_new_tab
# pack $topwin.tabs.x0 $topwin.tabs.x1 $topwin.tabs.x2 $topwin.tabs.add -side left
pack $top_path.tabs.x0 $top_path.tabs.add -side left
pack $top_path.tabs -fill x -side top -expand false -side top -before $top_path.drw
if { ![winfo exists $top_path.tabs] } {
frame $top_path.tabs
button $top_path.tabs.x0 -padx 2 -pady 0 -text Main -command "xschem new_schematic switch_tab .drw"
button $top_path.tabs.add -padx 0 -pady 0 -text { + } -command "xschem new_schematic create"
pack $top_path.tabs.x0 $top_path.tabs.add -side left
pack $top_path.tabs -fill x -side top -expand false -side top -before $top_path.drw
}
} else {
destroy $top_path.tabs
}
@ -3797,24 +3796,6 @@ proc next_tab {} {
$top_path.tabs.x$next_tab invoke
}
proc create_new_tab {} {
global tabbed_interface
if { !$tabbed_interface} {return}
set top_path [xschem get top_path]
set found 0
for { set i 1} { $i < $tctx::max_new_windows} { incr i} {
if { ![winfo exists ${top_path}.tabs.x$i] } {
button $top_path.tabs.x$i -padx 2 -pady 0 -text Tab2 -command "xschem new_schematic switch .x$i.drw"
if {![info exists tctx::tab_bg] } {set tctx::tab_bg [$top_path.tabs.x$i cget -bg]}
pack $top_path.tabs.x$i -before .tabs.add -side left
xschem new_schematic create .x$i.drw
set found 1
break
}
}
if {!$found} { puts "no more available tabs"}
}
proc set_tab_names {} {
global tabbed_interface has_x
@ -3833,45 +3814,6 @@ proc set_tab_names {} {
}
}
proc test2 {} {
global tabbed_interface
set tabbed_interface 0
xschem load [abs_sym_path testbench.sch]
xschem load_new_window [abs_sym_path poweramp.sch]
xschem load_new_window [abs_sym_path mos_power_ampli.sch]
xschem load_new_window [abs_sym_path rom8k.sch]
xschem load_new_window [abs_sym_path autozero_comp.sch]
xschem load_new_window [abs_sym_path LCC_instances.sch]
xschem load_new_window [abs_sym_path simulate_ff.sch]
xschem load_new_window [abs_sym_path led_driver.sch]
xschem load_new_window [abs_sym_path solar_panel.sch]
}
proc test1 {} {
global tabbed_interface
set tabbed_interface 1
setup_tabbed_interface
xschem load [abs_sym_path testbench.sch]
create_new_tab
xschem load [abs_sym_path poweramp.sch]
create_new_tab
xschem load [abs_sym_path mos_power_ampli.sch]
create_new_tab
xschem load [abs_sym_path rom8k.sch]
create_new_tab
xschem load [abs_sym_path autozero_comp.sch]
create_new_tab
xschem load [abs_sym_path LCC_instances.sch]
create_new_tab
xschem load [abs_sym_path simulate_ff.sch]
create_new_tab
xschem load [abs_sym_path led_driver.sch]
create_new_tab
xschem load [abs_sym_path solar_panel.sch]
}
proc raise_dialog {parent window_path } {
if {[winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped $parent] &&
[wm stackorder .dialog isbelow $parent ]} {
@ -4260,12 +4202,13 @@ proc build_widgets { {topwin {} } } {
$topwin.menubar.file.menu add command -label "PNG Export" -command "xschem print png" -accelerator {Ctrl+*}
$topwin.menubar.file.menu add command -label "SVG Export" -command "xschem print svg" -accelerator {Alt+*}
$topwin.menubar.file.menu add separator
$topwin.menubar.file.menu add command -label "Exit" -accelerator {Ctrl+Q} -command "
if { \[xschem get current_win_path\] eq {.drw} } {
xschem exit
} else {
xschem new_schematic destroy \[xschem get current_win_path\] {}
}"
$topwin.menubar.file.menu add command -label "Exit" -accelerator {Ctrl+Q} -command {
if {[xschem get current_win_path] eq {.drw} } {
xschem exit
} else {
xschem new_schematic destroy [xschem get current_win_path] {}
}
}
$topwin.menubar.option.menu add checkbutton -label "Color Postscript/SVG" -variable color_ps \
-command {
if { $color_ps==1 } {xschem set color_ps 1} else { xschem set color_ps 0}
@ -4349,9 +4292,9 @@ proc build_widgets { {topwin {} } } {
$topwin.menubar.edit.menu add command -label "Delete" -command "xschem delete" -accelerator Del
toolbar_create EditDelete "xschem delete" "Delete" $topwin
$topwin.menubar.edit.menu add command -label "Select all" -command "xschem select_all" -accelerator Ctrl+A
$topwin.menubar.edit.menu add command -label "Edit selected schematic in new window" \
$topwin.menubar.edit.menu add command -label "Edit schematic in new window/tab" \
-command "xschem schematic_in_new_window" -accelerator Alt+E
$topwin.menubar.edit.menu add command -label "Edit selected symbol in new window" \
$topwin.menubar.edit.menu add command -label "Edit symbol in new window/tab" \
-command "xschem symbol_in_new_window" -accelerator Alt+I
$topwin.menubar.edit.menu add command -label "Duplicate objects" -command "xschem copy_objects" -accelerator C
toolbar_create EditDuplicate "xschem copy_objects" "Duplicate objects" $topwin
@ -4633,12 +4576,13 @@ proc build_widgets { {topwin {} } } {
wm geometry $rootwin $initial_geometry
#wm maxsize . 1600 1200
if { $rootwin == {.}} {
wm protocol $rootwin WM_DELETE_WINDOW "
if { \[xschem get current_win_path\] eq {.drw} } {
wm protocol $rootwin WM_DELETE_WINDOW {
if { [xschem get current_win_path] eq {.drw} } {
xschem exit
} else {
xschem new_schematic destroy \[xschem get current_win_path\] {}
}"
xschem new_schematic destroy [xschem get current_win_path] {}
}
}
} else {
wm protocol $topwin WM_DELETE_WINDOW "xschem new_schematic destroy $topwin.drw {}"
}

View File

@ -46,6 +46,34 @@ proc draw_test {{filelist {-}} {hide_graphs 0}} {
}
set show_pin_net_names 0
}
proc test_windows { {tabs 0} {destroy 1} } {
global tabbed_interface
xschem clear force
set tabbed_interface $tabs
setup_tabbed_interface
xschem load [abs_sym_path testbench.sch]
xschem load_new_window [abs_sym_path poweramp.sch]
xschem load_new_window [abs_sym_path mos_power_ampli.sch]
xschem load_new_window [abs_sym_path rom8k.sch]
xschem load_new_window [abs_sym_path autozero_comp.sch]
xschem load_new_window [abs_sym_path LCC_instances.sch]
xschem load_new_window [abs_sym_path simulate_ff.sch]
xschem load_new_window [abs_sym_path led_driver.sch]
xschem load_new_window [abs_sym_path solar_panel.sch]
update
if {[xschem new_schematic ntabs] == 8} {set res OK} else {set res FAIL}
if {$tabs} {
puts "test tabbed windows: $res"
} else {
puts "test multiple windows: $res"
}
if {$destroy} {
after 2000
xschem new_schematic destroy_all
xschem clear force
}
}
## select all loaded schematic and paste 32 times in different places,
## check if number of elements after paste matches.
@ -198,6 +226,8 @@ proc xschemtest {{view 0}} {
copy_paste_test mos_power_ampli.sch
draw_trim_wiregrid
test_xschem_simulation simulate_ff.sch
test_windows 0 ;# windows
test_windows 1 ;# tabs
}]
puts "Test time: [lindex $t 0] microseconds"
}