runtime menu option to set undo stack on disk or in memory

This commit is contained in:
Stefan Frederik 2021-11-29 02:47:37 +01:00
parent 03f973e203
commit 2442a3dfc0
6 changed files with 120 additions and 49 deletions

View File

@ -739,7 +739,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
tcleval("new_window destroy_all"); /* close child schematics */
if(tclresult()[0] == '1') {
if(xctx->modified) {
tcleval("tk_messageBox -type okcancel -message \""
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
"[get_cell [xschem get schname] 0]"
": UNSAVED data: want to exit?\"");
}

View File

@ -190,7 +190,7 @@ static void free_undo_symbols(int slot)
xctx->uslot[slot].symbols = 0;
}
static void init_undo()
static void init_undo(void)
{
int slot;
@ -205,8 +205,8 @@ static void init_undo()
xctx->uslot[slot].bptr = my_calloc(170, cadlayers, sizeof(xRect *));
xctx->uslot[slot].aptr = my_calloc(171, cadlayers, sizeof(xArc *));
xctx->uslot[slot].pptr = my_calloc(172, cadlayers, sizeof(xPoly *));
xctx->undo_initialized = 1;
}
xctx->undo_initialized = 1;
}
}
@ -237,7 +237,7 @@ void mem_delete_undo(void)
int slot;
dbg(1, "mem_delete_undo(): undo_initialized = %d\n", xctx->undo_initialized);
if(!xctx->undo_initialized) return;
(*xctx->clear_undo_ptr)();
mem_clear_undo();
for(slot = 0;slot<MAX_UNDO; slot++) {
my_free(804, &xctx->uslot[slot].lines);
my_free(805, &xctx->uslot[slot].rects);

View File

@ -1139,24 +1139,41 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2
update_conn_cues(0, 0);
}
void clear_undo(void)
{
xctx->cur_undo_ptr = 0;
xctx->tail_undo_ptr = 0;
xctx->head_undo_ptr = 0;
}
void delete_undo(void)
{
int i;
char diff_name[PATH_MAX]; /* overflow safe 20161122 */
dbg(1, "delete_undo(): undo_initialized = %d\n", xctx->undo_initialized);
if(!xctx->undo_initialized) return;
clear_undo();
for(i=0; i<MAX_UNDO; i++) {
my_snprintf(diff_name, S(diff_name), "%s/undo%d",xctx->undo_dirname, i);
xunlink(diff_name);
}
rmdir(xctx->undo_dirname);
my_free(895, &xctx->undo_dirname);
xctx->undo_initialized = 0;
}
void clear_undo(void)
/* create undo directory in XSCHEM_TEMP_DIR */
static void init_undo(void)
{
xctx->cur_undo_ptr = 0;
xctx->tail_undo_ptr = 0;
xctx->head_undo_ptr = 0;
if(!xctx->undo_initialized) {
/* create undo directory */
if( !my_strdup(644, &xctx->undo_dirname, create_tmpdir("xschem_undo_") )) {
fprintf(errfp, "xinit(): problems creating tmp undo dir\n");
tcleval("exit");
}
xctx->undo_initialized = 1;
}
}
void push_undo(void)
@ -1172,8 +1189,7 @@ void push_undo(void)
if(xctx->no_undo)return;
dbg(1, "push_undo(): cur_undo_ptr=%d tail_undo_ptr=%d head_undo_ptr=%d\n",
xctx->cur_undo_ptr, xctx->tail_undo_ptr, xctx->head_undo_ptr);
init_undo();
#if HAS_POPEN==1
my_snprintf(diff_name, S(diff_name), "gzip --fast -c > %s/undo%d",
xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);

View File

@ -429,7 +429,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
tcleval("new_window destroy_all"); /* close child schematics */
if(tclresult()[0] == '1') {
if(xctx->modified) {
tcleval("tk_messageBox -type okcancel -message \""
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
"[get_cell [xschem get schname] 0]"
": UNSAVED data: want to exit?\"");
}
@ -885,6 +885,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
printf("prep_hash_inst=%d\n", xctx->prep_hash_inst);
printf("prep_hash_wires=%d\n", xctx->prep_hash_wires);
printf("need_reb_sel_arr=%d\n", xctx->need_reb_sel_arr);
printf("undo_type=%d\n", xctx->undo_type);
printf("******* end global variables:*******\n");
}
@ -2421,7 +2422,35 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
(*xctx->pop_undo_ptr)(redo, set_modify); /* 2nd param: set_modify_status */
Tcl_ResetResult(interp);
}
else if(!strcmp(argv[1],"undo_type")) {
cmd_found = 1;
if(argc > 2) {
dbg(1, "xschem undo_type %s\n", argv[2]);
if(!strcmp(argv[2], "disk")) {
if(xctx->undo_type == 1) {
mem_delete_undo(); /*reset memory undo */
}
/* redefine undo function pointers */
xctx->push_undo_ptr = push_undo;
xctx->pop_undo_ptr = pop_undo;
xctx->delete_undo_ptr = delete_undo;
xctx->clear_undo_ptr = clear_undo;
xctx->undo_type = 0; /* disk */
} else { /* "memory" */
if(xctx->undo_type == 0) {
delete_undo(); /*reset disk undo */
}
/* redefine undo function pointers */
xctx->push_undo_ptr = mem_push_undo;
xctx->pop_undo_ptr = mem_pop_undo;
xctx->delete_undo_ptr = mem_delete_undo;
xctx->clear_undo_ptr = mem_clear_undo;
xctx->undo_type = 1; /* memory */
}
}
}
else if(!strcmp(argv[1],"unhilight_all"))
{
xRect boundbox;

View File

@ -403,20 +403,13 @@ void alloc_xschem_data(const char *top_path)
xctx->tail_undo_ptr = 0;
xctx->undo_dirname = NULL;
xctx->undo_type = 0; /* 0: on disk, 1: in memory */
if(!strcmp(tclgetvar("undo_type"), "disk")) xctx->undo_type = 0;
else xctx->undo_type = 1; /* "memory" */
xctx->push_undo_ptr = &push_undo;
xctx->pop_undo_ptr = &pop_undo;
xctx->delete_undo_ptr = &delete_undo;
xctx->clear_undo_ptr = &clear_undo;
xctx->undo_initialized = 0; /* in_memory_undo */
if(xctx->undo_type == 0) {
/* create undo directory */
if( !my_strdup(644, &xctx->undo_dirname, create_tmpdir("xschem_undo_") )) {
fprintf(errfp, "xinit(): problems creating tmp undo dir\n");
tcleval("exit");
}
dbg(1, "undo_dirname=%s\n", xctx->undo_dirname);
}
xctx->undo_initialized = 0;
xctx->zoom=CADINITIALZOOM;
xctx->mooz=1/CADINITIALZOOM;
xctx->xorigin=CADINITIALX;
@ -1001,7 +994,7 @@ void new_schematic(const char *what, const char *top_path, const char *tk_win_pa
dbg(1, "new_schematic() destroy\n");
/* reset old focused window so callback() will force repaint on expose events */
if(xctx->modified && has_x) {
tcleval("tk_messageBox -type okcancel -message \""
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
"[get_cell [xschem get schname] 0]"
": UNSAVED data: want to exit?\"");
if(strcmp(tclresult(),"ok")==0) close = 1;
@ -1580,6 +1573,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
/* [m]allocate dynamic memory */
/* */
alloc_xschem_data("");
/* global context / graphic preferences/settings */
pixdata=my_calloc(641, cadlayers, sizeof(char*));
for(i=0;i<cadlayers;i++)

View File

@ -3629,7 +3629,7 @@ set tctx::global_list {
search_value selected_tok show_infowindow show_pin_net_names simconf_default_geometry simconf_vpos
spiceprefix split_files svg_colors svg_font_name symbol symbol_width sym_txt tclcmd_txt
text_line_default_geometry textwindow_fileid textwindow_filename textwindow_w tmp_bus_char
toolbar_horiz toolbar_visible top_subckt transparent_svg
toolbar_horiz toolbar_visible top_subckt transparent_svg undo_type
use_label_prefix use_lab_wire user_wants_copy_cell verilog_2001
viewdata_fileid viewdata_filename viewdata_w xschem_libs xschem_listen_port
}
@ -3788,12 +3788,39 @@ proc pack_widgets { { topwin {} } } {
}
}
# if undo_type == disk save undo to disk
# if undo_type == memory keep undo in memory
# In memory undo is faster but in case of crashes nothing can be recovered
# On disk undo is slower but can be used to recover state just before a crash
proc switch_undo {} {
global undo_type
if { $undo_type eq {memory} } {
set res [tk_messageBox -type yesno -parent [xschem get topwindow] \
-message {Ok to keep undo in memory? Undo will be reset.\
Memory undo is faster but in case of crashes nothing can be recovered.}]
if {$res eq {yes} } {
xschem undo_type $undo_type
} else {
set undo_type disk
}
} else { ;# disk
set res [tk_messageBox -type yesno -parent [xschem get topwindow] \
-message {Ok to save undo on disk? Undo will be reset.\
Disk undo is slower but in case of crashes previous state can be recovered.}]
if {$res eq {yes} } {
xschem undo_type $undo_type
} else {
set undo_type memory
}
}
}
proc build_widgets { {topwin {} } } {
global XSCHEM_SHAREDIR
global colors recentfile color_ps transparent_svg menu_debug_var enable_stretch
global netlist_show flat_netlist split_files hspice_netlist tmp_bus_char
global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width
global cadgrid draw_window show_pin_net_names toolbar_visible hide_symbols
global cadgrid draw_window show_pin_net_names toolbar_visible hide_symbols undo_type
global disable_unique_names persistent_command autotrim_wires en_hilight_conn_inst
global local_netlist_dir editor netlist_type netlist_dir spiceprefix initial_geometry
set mbg {}
@ -3880,12 +3907,14 @@ proc build_widgets { {topwin {} } } {
# toolbar_create FileMerge "xschem merge" "Merge File" $topwin
$topwin.menubar.file.menu add command -label "Reload" -accelerator {Alt+S} \
-command {
if { [string compare [tk_messageBox -type okcancel -message {Are you sure you want to reload?}] ok]==0 } {
if { [string compare [tk_messageBox -type okcancel -parent [xschem get topwindow] \
-message {Are you sure you want to reload?}] ok]==0 } {
xschem reload
}
}
toolbar_create FileReload {
if { [string compare [tk_messageBox -type okcancel -message {Are you sure you want to reload?}] ok]==0 } {
if { [string compare [tk_messageBox -type okcancel -parent [xschem get topwindow] \
-message {Are you sure you want to reload?}] ok]==0 } {
xschem reload
}
} "Reload File" $topwin
@ -3913,6 +3942,8 @@ proc build_widgets { {topwin {} } } {
-command {
if { $menu_debug_var==1 } {xschem debug 1} else { xschem debug 0}
}
$topwin.menubar.option.menu add checkbutton -label "Undo buffer on Disk" -variable undo_type \
-onvalue disk -offvalue memory -command {switch_undo}
$topwin.menubar.option.menu add checkbutton -label "Enable stretch" -variable enable_stretch \
-accelerator Y
$topwin.menubar.option.menu add checkbutton -label "Show netlist win" -variable netlist_show \
@ -3939,23 +3970,23 @@ proc build_widgets { {topwin {} } } {
-command {
xschem redraw
}
$topwin.menubar.option.menu add command -label "Half Snap Threshold" -accelerator G -command {
xschem set cadsnap [expr {[xschem get cadsnap] / 2.0} ]
}
$topwin.menubar.option.menu add command -label "Double Snap Threshold" -accelerator Shift-G -command {
xschem set cadsnap [expr {[xschem get cadsnap] * 2.0} ]
}
$topwin.menubar.option.menu add checkbutton -label "Variable grid point size" -variable big_grid_points \
-command { xschem redraw }
$topwin.menubar.option.menu add checkbutton -label "Symbol text" -variable sym_txt \
-accelerator {Ctrl+B} -command { xschem set sym_txt $sym_txt; xschem redraw }
$topwin.menubar.option.menu add checkbutton -label "Toggle variable line width" -variable change_lw \
-accelerator {_}
$topwin.menubar.option.menu add checkbutton -label "Increment Hilight Color" -variable incr_hilight
$topwin.menubar.option.menu add command -label "Set line width" \
-command {
input_line "Enter linewidth (float):" "xschem line_width"
}
$topwin.menubar.option.menu add command -label "Set symbol width" \
-command {
input_line "Enter Symbol width ($symbol_width)" "set symbol_width" $symbol_width
}
$topwin.menubar.option.menu add checkbutton -label "Show net names on symbol pins" -variable show_pin_net_names \
-command {
xschem show_pin_net_names
xschem redraw
}
$topwin.menubar.option.menu add separator
$topwin.menubar.option.menu add radiobutton -label "Spice netlist" -variable netlist_type -value spice \
-accelerator {Shift+V} \
@ -4033,12 +4064,6 @@ proc build_widgets { {topwin {} } } {
# toolbar_create ViewZoomOut "xschem zoom_out" "Zoom Out" $topwin
$topwin.menubar.view.menu add command -label "Zoom box" -command "xschem zoom_box" -accelerator Z
# toolbar_create ViewZoomBox "xschem zoom_box" "Zoom Box" $topwin
$topwin.menubar.view.menu add command -label "Half Snap Threshold" -accelerator G -command {
xschem set cadsnap [expr {[xschem get cadsnap] / 2.0} ]
}
$topwin.menubar.view.menu add command -label "Double Snap Threshold" -accelerator Shift-G -command {
xschem set cadsnap [expr {[xschem get cadsnap] * 2.0} ]
}
$topwin.menubar.view.menu add command -label "Set snap value" \
-command {
input_line "Enter snap value ( default: [xschem get cadsnap_default] current: [xschem get cadsnap])" \
@ -4051,6 +4076,7 @@ proc build_widgets { {topwin {} } } {
$topwin.menubar.view.menu add checkbutton -label "View only Probes" -variable only_probes \
-accelerator {5} \
-command { xschem only_probes }
$topwin.menubar.view.menu add checkbutton -label "Increment Hilight Color" -variable incr_hilight
$topwin.menubar.view.menu add command -label "Toggle colorscheme" -accelerator {Shift+O} -command {
xschem toggle_colorscheme
xschem change_colors 1
@ -4076,11 +4102,14 @@ proc build_widgets { {topwin {} } } {
-command {
if { $draw_window == 1} { xschem set draw_window 1} else { xschem set draw_window 0}
}
$topwin.menubar.view.menu add checkbutton -label "Show net names on symbol pins" -variable show_pin_net_names \
-command {
xschem show_pin_net_names
xschem redraw
}
$topwin.menubar.view.menu add checkbutton -label "Symbol text" -variable sym_txt \
-accelerator {Ctrl+B} -command { xschem set sym_txt $sym_txt; xschem redraw }
$topwin.menubar.view.menu add checkbutton -label "Toggle variable line width" -variable change_lw \
-accelerator {_}
$topwin.menubar.view.menu add command -label "Set line width" \
-command {
input_line "Enter linewidth (float):" "xschem line_width"
}
$topwin.menubar.view.menu add checkbutton -label "Show Toolbar" -variable toolbar_visible \
-command "
if { \$toolbar_visible } \" toolbar_show $topwin\" else \"toolbar_hide $topwin\"
@ -4503,6 +4532,9 @@ set_ne to_png {gm convert}
## ps to pdf conversion
set_ne to_pdf {ps2pdf}
## undo_type: disk or memory
set_ne undo_type disk
## max number of windows (including main) a single xschem process can handle
set_ne max_new_windows -1 ;# this is set by xinit.c
## remember edit_prop widget size