From 2442a3dfc05bd44ed7af5017ce4c4d94b3cd078b Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Mon, 29 Nov 2021 02:47:37 +0100 Subject: [PATCH] runtime menu option to set undo stack on disk or in memory --- src/callback.c | 2 +- src/in_memory_undo.c | 6 ++-- src/save.c | 28 +++++++++++---- src/scheduler.c | 33 +++++++++++++++-- src/xinit.c | 16 +++------ src/xschem.tcl | 84 ++++++++++++++++++++++++++++++-------------- 6 files changed, 120 insertions(+), 49 deletions(-) diff --git a/src/callback.c b/src/callback.c index a4aa1c79..eef6bedf 100644 --- a/src/callback.c +++ b/src/callback.c @@ -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?\""); } diff --git a/src/in_memory_undo.c b/src/in_memory_undo.c index 32c6bb14..5c553cb5 100644 --- a/src/in_memory_undo.c +++ b/src/in_memory_undo.c @@ -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;slotuslot[slot].lines); my_free(805, &xctx->uslot[slot].rects); diff --git a/src/save.c b/src/save.c index 950748be..91e4ae9d 100644 --- a/src/save.c +++ b/src/save.c @@ -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; iundo_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); diff --git a/src/scheduler.c b/src/scheduler.c index 020d12e9..9bf9a39a 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -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; diff --git a/src/xinit.c b/src/xinit.c index e7e080d0..2f430dd8 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -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