diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index dca9d276..b0d5f73f 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -510,16 +510,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" - - - - - - - - - - @@ -596,6 +586,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" if '3' argument is given combine '1' and '2'
Copy selection to clipboard
+ + Copy hierarchy info from tab/window "from" to tab/window "to" + Example: xschem copy_hierarchy .drw .x1.drw
if deltax and deltay (and optionally rot and flip) are given copy selection
to specified offset, otherwise start a GUI copy operation
@@ -699,6 +692,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
+ get schematic associated with instance 'inst'
get value of token 'tok' in string 'str'
'with_quotes' (default:0) is an integer passed to get_tok_value()
@@ -1052,7 +1048,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
what = read | clear | info | switch | switch_back
Load /clear / switch additional raw files
- Delete loaded simulation raw file+ Unload all simulation raw files
xschem raw_query list: get list of saved simulation variables
xschem raw_query vars: get number of simulation variables
@@ -1140,13 +1136,14 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
List a 2-item list of all pins and directions of current schematic
Example: xschem sch_pinlist
--> {PLUS} {in} {OUT} {out} {MINUS} {in} {VCC} {inout} {VSS} {inout}
- +
When a symbol is selected edit corresponding schematic
in a new tab/window if not already open.
If nothing selected open another window of the second
schematic (issues a warning).
if 'new_process' is given start a new xschem process
- if 'nodraw' is given do not draw loaded schematic
+ if 'nodraw' is given do not draw loaded schematic
+ returns '1' if a new schematic was opened, 0 otherwise
Search instances / wires / rects / texts with attribute string containing 'tok'
and value 'val'
@@ -1422,6 +1419,18 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/actions.c b/src/actions.c
index 9ac3f44c..87408686 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -1573,8 +1573,11 @@ void symbol_in_new_window(int new_process)
}
}
-void copy_hierarchy_data(Xschem_ctx *from, Xschem_ctx *to)
+int copy_hierarchy_data(const char *from_win_path, const char *to_win_path)
{
+ int n;
+ Xschem_ctx **save_xctx;
+ Xschem_ctx *from, *to;
char **sch;
char **sch_path;
int *sch_path_hash;
@@ -1585,7 +1588,18 @@ void copy_hierarchy_data(Xschem_ctx *from, Xschem_ctx *to)
int i, j;
Str_hashentry **fromnext;
Str_hashentry **tonext;
+
+ if(!get_window_count()) { return 0; }
+ save_xctx = get_save_xctx();
+ n = get_tab_or_window_number(from_win_path);
+ if(n >= 0) {
+ from = save_xctx[n];
+ } else return 0;
+ n = get_tab_or_window_number(to_win_path);
+ if(n >= 0) {
+ to = save_xctx[n];
+ } else return 0;
sch = from->sch;
sch_path = from->sch_path;
sch_path_hash = from->sch_path_hash;
@@ -1629,21 +1643,29 @@ void copy_hierarchy_data(Xschem_ctx *from, Xschem_ctx *to)
}
}
}
+ return 1;
}
- /* 20111007 duplicate current schematic if no inst selected */
-void schematic_in_new_window(int new_process, int dr)
+/* 20111007 duplicate current schematic if no inst selected */
+/* if force set to 1 force opening another new schematic even if already open */
+int schematic_in_new_window(int new_process, int dr, int force)
{
char filename[PATH_MAX];
char win_path[WINDOW_PATH_SIZE];
rebuild_selected_array();
- if(xctx->lastsel !=1 || xctx->sel_array[0].type!=ELEMENT) {
+ if(xctx->lastsel == 0) {
if(new_process) new_xschem_process(xctx->sch[xctx->currsch], 0);
- else new_schematic("create", "noalert", xctx->sch[xctx->currsch], dr);
+ else new_schematic("create", force ? "noalert" : "", xctx->sch[xctx->currsch], dr);
+ return 1;
}
- else {
+ else if(xctx->lastsel > 1) {
+ return 0;
+ }
+ else { /* xctx->lastsel == 1 */
+ if(xctx->inst[xctx->sel_array[0].n].ptr < 0 ) return 0;
+ if(!(xctx->inst[xctx->sel_array[0].n].ptr+ xctx->sym)->type) return 0;
+ if(xctx->sel_array[0].type != ELEMENT) return 0;
if( /* do not descend if not subcircuit */
- (xctx->inst[xctx->sel_array[0].n].ptr+ xctx->sym)->type &&
strcmp(
(xctx->inst[xctx->sel_array[0].n].ptr+ xctx->sym)->type,
"subcircuit"
@@ -1652,13 +1674,14 @@ void schematic_in_new_window(int new_process, int dr)
(xctx->inst[xctx->sel_array[0].n].ptr+ xctx->sym)->type,
"primitive"
)
- ) return;
+ ) return 0;
get_sch_from_sym(filename, xctx->inst[xctx->sel_array[0].n].ptr+ xctx->sym, xctx->sel_array[0].n);
- if(!check_loaded(filename, win_path)) {
+ if(force || !check_loaded(filename, win_path)) {
if(new_process) new_xschem_process(filename, 0);
else new_schematic("create", "noalert", filename, dr);
}
}
+ return 1;
}
void launcher(void)
diff --git a/src/callback.c b/src/callback.c
index 464bd498..b68bf3f2 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -1838,7 +1838,8 @@ int rstate; /* (reduced state, without ShiftMask) */
{
int save = xctx->semaphore;
xctx->semaphore--; /* so semaphore for current context wll be saved correctly */
- schematic_in_new_window(0, 1);
+ /* schematic_in_new_window(0, 1, 0); */
+ tcleval("open_sub_schematic");
xctx->semaphore = save;
break;
}
@@ -1847,7 +1848,7 @@ int rstate; /* (reduced state, without ShiftMask) */
{
int save = xctx->semaphore;
xctx->semaphore--; /* so semaphore for current context wll be saved correctly */
- schematic_in_new_window(1, 1);
+ schematic_in_new_window(1, 1, 0);
xctx->semaphore = save;
break;
}
diff --git a/src/scheduler.c b/src/scheduler.c
index 9ec21b2b..17aafc18 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -547,6 +547,20 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
+
+ /* copy_hierarchy to from
+ * Copy hierarchy info from tab/window "from" to tab/window "to"
+ * Example: xschem copy_hierarchy .drw .x1.drw */
+ else if(!strcmp(argv[1], "copy_hierarchy"))
+ {
+ int ret = 0;
+ if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
+ if(argc > 3) {
+ ret = copy_hierarchy_data(argv[2], argv[3]);
+ }
+ Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
+ }
+
/* copy_objects [deltax deltay [rot flip]]
* if deltax and deltay (and optionally rot and flip) are given copy selection
* to specified offset, otherwise start a GUI copy operation */
@@ -1088,7 +1102,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
break;
case 'l':
- if(!strcmp(argv[2], "lastsel")) { /* number of selected objects */
+ if(!strcmp(argv[2], "last_created_window")) { /* return win_path of last created tab or window */
+ Tcl_SetResult(interp, get_last_created_window(), TCL_VOLATILE);
+ }
+ else if(!strcmp(argv[2], "lastsel")) { /* number of selected objects */
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
rebuild_selected_array();
Tcl_SetResult(interp, my_itoa(xctx->lastsel),TCL_VOLATILE);
@@ -1561,6 +1578,27 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
+ /* get_sch_from_sym inst
+ * get schematic associated with instance 'inst' */
+ else if(!strcmp(argv[1], "get_sch_from_sym") )
+ {
+ int inst = -1;
+ char filename[PATH_MAX];
+ my_strncpy(filename, "", S(filename));
+ if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
+ if(argc > 2) {
+ if((inst = get_instance(argv[2])) < 0 ) {
+ Tcl_SetResult(interp, "xschem get_sch_from_sym: instance not found", TCL_STATIC);
+ return TCL_ERROR;
+ } else {
+ if( xctx->inst[inst].ptr >= 0 ) {
+ get_sch_from_sym(filename, xctx->inst[inst].ptr+ xctx->sym, inst);
+ }
+ }
+ }
+ Tcl_SetResult(interp, filename, TCL_VOLATILE);
+ }
+
/* get_tok str tok [with_quotes]
* get value of token 'tok' in string 'str'
* 'with_quotes' (default:0) is an integer passed to get_tok_value() */
@@ -3197,12 +3235,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
/* raw_clear
- * Delete loaded simulation raw file */
+ * Unload all simulation raw files */
else if(!strcmp(argv[1], "raw_clear"))
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
- extra_rawfile(3, NULL, NULL);
- free_rawfile(&xctx->raw, 1);
+ extra_rawfile(3, NULL, NULL); /* unload additional raw files */
+ free_rawfile(&xctx->raw, 1); /* unload base (current) raw file */
Tcl_ResetResult(interp);
}
@@ -3762,25 +3800,29 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
- /* schematic_in_new_window [new_process] [nodraw]
+ /* schematic_in_new_window [new_process] [nodraw] [force]
* When a symbol is selected edit corresponding schematic
* in a new tab/window if not already open.
* If nothing selected open another window of the second
* schematic (issues a warning).
* if 'new_process' is given start a new xschem process
- * if 'nodraw' is given do not draw loaded schematic */
+ * if 'nodraw' is given do not draw loaded schematic
+ * returns '1' if a new schematic was opened, 0 otherwise */
else if(!strcmp(argv[1], "schematic_in_new_window"))
{
+ int res = 0;
int new_process = 0;
int nodraw = 0;
+ int force = 0;
int i;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
for(i = 2; i < argc; i++) {
if(!strcmp(argv[i], "new_process")) new_process = 1;
if(!strcmp(argv[i], "nodraw")) nodraw = 1;
+ if(!strcmp(argv[i], "force")) force = 1;
}
- schematic_in_new_window(new_process, !nodraw);
- Tcl_ResetResult(interp);
+ res = schematic_in_new_window(new_process, !nodraw, force);
+ Tcl_SetResult(interp, my_itoa(res), TCL_VOLATILE);
}
/* search regex|exact select tok val [match_case]
@@ -4764,8 +4806,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
del_object_table();
}
else if(argc > 2 && atoi(argv[2]) == 2) {
- Xschem_ctx **save_xctx = get_save_xctx();
- copy_hierarchy_data(save_xctx[0], save_xctx[1]);
+ copy_hierarchy_data(".drw", ".x1.drw");
}
else if(argc > 2 && atoi(argv[2]) == 3) {
Xschem_ctx **save_xctx = get_save_xctx();
diff --git a/src/xinit.c b/src/xinit.c
index e81e3a85..60714f77 100644
--- a/src/xinit.c
+++ b/src/xinit.c
@@ -42,6 +42,7 @@ static Xschem_ctx *save_xctx[MAX_NEW_WINDOWS]; /* save pointer to current schema
static char window_path[MAX_NEW_WINDOWS][WINDOW_PATH_SIZE];
/* ==0 if no additional windows/tabs, ==1 if one additional window/tab, ... */
static int window_count = 0;
+static int last_created_window = -1;
/* ----------------------------------------------------------------------- */
/* EWMH message handling routines 20071027... borrowed from wmctrl code */
@@ -94,6 +95,15 @@ char *get_window_path(int i)
return window_path[i];
}
+char *get_last_created_window(void)
+{
+ if(last_created_window >= 0) {
+ return window_path[last_created_window];
+ } else {
+ return "";
+ }
+}
+
int get_window_count(void)
{
return window_count;
@@ -1204,7 +1214,7 @@ void preview_window(const char *what, const char *win_path, const char *fname)
}
-static int get_tab_or_window_number(const char *win_path)
+int get_tab_or_window_number(const char *win_path)
{
int i, n = -1;
Xschem_ctx *ctx, **save_xctx = get_save_xctx();
@@ -1522,7 +1532,7 @@ static void create_new_window(int *window_count, const char *noconfirm, const ch
n = -1;
for(i = 1; i < MAX_NEW_WINDOWS; ++i) { /* search 1st free slot */
if(save_xctx[i] == NULL) {
- n = i;
+ last_created_window = n = i;
break;
}
}
@@ -1627,6 +1637,7 @@ static void create_new_tab(int *window_count, const char *noconfirm, const char
dbg(0, "new_schematic(\"newtab\"...): no more free slots\n");
return;
}
+ last_created_window = i;
/* tcl code to create the tab button */
my_snprintf(nn, S(nn), "%d", i);
if(has_x) {
@@ -1911,7 +1922,6 @@ static void destroy_all_tabs(int *window_count, int force)
int new_schematic(const char *what, const char *win_path, const char *fname, int dr)
{
int tabbed_interface;
-
tabbed_interface = tclgetboolvar("tabbed_interface");
dbg(1, "new_schematic(): current_win_path=%s, what=%s, win_path=%s\n", xctx->current_win_path, what, win_path);
if(!strcmp(what, "ntabs")) {
diff --git a/src/xschem.h b/src/xschem.h
index 459e06ff..299d9fa4 100644
--- a/src/xschem.h
+++ b/src/xschem.h
@@ -1260,8 +1260,8 @@ extern int check_lib(int what, const char *s);
extern int floaters_from_selected_inst();
extern void select_all(void);
extern void change_linewidth(double w);
-extern void copy_hierarchy_data(Xschem_ctx *from, Xschem_ctx *to);
-extern void schematic_in_new_window(int new_process, int dr);
+extern int copy_hierarchy_data(const char *from_win_path, const char *to_win_path);
+extern int schematic_in_new_window(int new_process, int dr, int force);
extern void symbol_in_new_window(int new_process);
extern void new_xschem_process(const char *cell, int symbol);
extern void ask_new_file(void);
@@ -1456,9 +1456,11 @@ extern void mem_delete_undo(void);
extern void mem_clear_undo(void);
extern void load_schematic(int load_symbol, const char *fname, int reset_undo, int alert);
/* check if filename already in an open window/tab */
+extern int get_tab_or_window_number(const char *win_path);
extern void swap_tabs(void);
extern void swap_windows(int dr);
extern int check_loaded(const char *f, char *win_path);
+extern char *get_last_created_window(void);
extern char *get_window_path(int i);
extern int get_window_count(void);
extern Xschem_ctx **get_save_xctx(void);
diff --git a/src/xschem.tcl b/src/xschem.tcl
index 2b4956c7..ba91db59 100644
--- a/src/xschem.tcl
+++ b/src/xschem.tcl
@@ -2960,6 +2960,34 @@ proc save_file_dialog { msg ext global_initdir {initialf {}} {overwrt 1} } {
return $r
}
+# opens indicated instance (or selected one) into a separate tab/window
+# keeping the hierarchy path, as it was descended into (as with 'e' key).
+proc open_sub_schematic {{inst {}} {inst_number 0}} {
+ set one_sel [expr {[xschem get lastsel] == 1}]
+ if { $inst eq {} && $one_sel} {
+ set inst [lindex [xschem selected_set] 0]
+ xschem unselect_all
+ } else {
+ set instlist {}
+ # get list of instances (instance names only)
+ foreach {i s t} [xschem instance_list] {lappend instlist $i}
+ # if provided $inst is not in the list return 0
+ if {[lsearch -exact $instlist $inst] == -1} {return 0}
+ }
+ # open a new top level in another window / tab
+ set schname [xschem get_sch_from_sym $inst]
+ set res [xschem schematic_in_new_window force]
+ # if successfull descend into indicated sub-schematic
+ if {$res} {
+ xschem new_schematic switch [xschem get last_created_window]
+ xschem select instance $inst fast
+ xschem descend
+ return 1
+ }
+ return 0
+}
+
+
proc is_xschem_file {f} {
if { ![file exists $f] } { return 0
} elseif { [file isdirectory $f] } { return 0 }
@@ -6854,7 +6882,8 @@ proc build_widgets { {topwin {} } } {
toolbar_add FileOpen "xschem load" "Open File" $topwin
$topwin.menubar.file.menu add command -label "Open schematic in new window/tab" \
- -command "xschem schematic_in_new_window" -accelerator Alt+E
+ -command "open_sub_schematic" -accelerator Alt+E
+ # -command "xschem schematic_in_new_window" -accelerator Alt+E
$topwin.menubar.file.menu add command -label "Open symbol in new window/tab" \
-command "xschem symbol_in_new_window" -accelerator Alt+I
diff --git a/xschem_library/examples/poweramp.sch b/xschem_library/examples/poweramp.sch
index b3478ace..07df4d5c 100644
--- a/xschem_library/examples/poweramp.sch
+++ b/xschem_library/examples/poweramp.sch
@@ -322,7 +322,7 @@ C {spice_probe.sym} 670 -1120 0 0 {name=p43 analysis=tran }
C {spice_probe.sym} 950 -1200 0 0 {name=p44 analysis=tran }
C {launcher.sym} 1000 -270 0 0 {name=h1
descr="Backannotate"
-tclcommand="xschem annotate_op $netlist_dir/poweramp_op.raw"}
+tclcommand="xschem annotate_op $netlist_dir/poweramp.raw"}
C {spice_probe.sym} 350 -1210 0 0 {name=p45 analysis=tran }
C {spice_probe.sym} 350 -1050 0 0 {name=p46 analysis=tran }
C {launcher.sym} 1145 -1165 0 0 {name=h5
@@ -354,11 +354,11 @@ vvss vss 0 dc 0
.control
save all
op
-write poweramp_op.raw
+write poweramp.raw
+set appendwrite
tran 2e-7 0.025 uic
* .FOUR 20k v(outm,outp)
* .probe i(*)
-plot outp outm
save p(r*) p(v*)
write poweramp.raw
quit 0