Merge remote-tracking branch 'supercd/master' into SuperChayan
This commit is contained in:
commit
dafb0c870d
|
|
@ -23,6 +23,9 @@ src/eval_expr.c
|
|||
src/parselabel.c
|
||||
src/parselabel.h
|
||||
|
||||
# Config file for C/C++ code formatter (clang-format)
|
||||
.clang-format
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
src/rawtovcd
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ ctrl+alt 's' Save-as symbol
|
|||
- 't' Place text
|
||||
shift 'T' Toggle *_ignore flag on selected instances
|
||||
alt 'u' Align to current grid selected objects
|
||||
ctrl 'u' Unselect attached floater objects
|
||||
shift 'U' Redo
|
||||
- 'u' Undo
|
||||
- 'v' Constrained vertical move/copy of objects
|
||||
|
|
|
|||
|
|
@ -138,6 +138,11 @@ name="mchanged_name" model=\"nmos\" w="20u" l="3u" m="10"
|
|||
<li><kbd>text_layer_<n></kbd></li>
|
||||
<p> This attribute sets the layer of symbol text item number <kbd>n</kbd>. This allows
|
||||
instance based symbol text color customization.</p>
|
||||
<li><kbd>attach</kbd></li>
|
||||
<p> An attribute <kbd>attach="x1 g3 p4"</kbd> will "attach" specified objects that have a matching <kbd>name=...</kbd>
|
||||
attribute. These objects can be any xschem objects, like other elements, wires, rectangles, polygons, texts etc.<br>
|
||||
Attached objects will be selected when selecting the component with this attribute set.
|
||||
This allows to create "object groups"</p>
|
||||
<li><kbd>highlight</kbd></li>
|
||||
<p>If set to <kbd>true</kbd> the symbol will be highlighted when one of the nets attached to its pins are highlighted.</p>
|
||||
<li><kbd>net_name</kbd></li>
|
||||
|
|
|
|||
|
|
@ -551,7 +551,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li><kbd> abort_operation</kbd></li><pre>
|
||||
|
|
@ -814,6 +813,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> textlayer </kbd> layer number for texts </li>
|
||||
<li><kbd> top_path </kbd> get top hier path of current window (always "" for tabbed if) </li>
|
||||
<li><kbd> topwindow </kbd> same as top_path but main window returned as "." </li>
|
||||
<li><kbd> ui_state </kbd> return UI state </li>
|
||||
<li><kbd> version </kbd> return xschem version </li>
|
||||
<li><kbd> wirelayer </kbd> layer used for wires </li>
|
||||
<li><kbd> wires </kbd> number of wires </li>
|
||||
|
|
@ -828,6 +828,15 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
return result of get_cell function </pre>
|
||||
<li><kbd> get_cell_w_ext cell n_dirs</kbd></li><pre>
|
||||
return result of get_cell_w_ext function </pre>
|
||||
<li><kbd> get_fqdevice instname param modelparam</kbd></li><pre>
|
||||
get the full pathname of "instname" device
|
||||
modelparam:
|
||||
0: current, 1: modelparam, 2: modelvoltage
|
||||
param: device parameter, like ib, gm, vth
|
||||
set param to {} (empty str) for just branch current of 2 terminal device
|
||||
for parameters like "vth" modelparam must be 2
|
||||
for parameters like "ib" modelparam must be 0
|
||||
for parameters like "gm" modelparam must be 1</pre>
|
||||
<li><kbd> getprop instance|instance_pin|symbol|text ref</kbd></li><pre>
|
||||
|
||||
getprop instance inst
|
||||
|
|
@ -981,13 +990,17 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> is_generator symbol</kbd></li><pre>
|
||||
tell if 'symbol' is a generator (symbol(param1,param2,...) </pre>
|
||||
<li><kbd> line [x1 y1 x2 y2] [pos] [propstring] [draw]</kbd></li><pre>
|
||||
line
|
||||
line gui
|
||||
if 'x1 y1 x2 y2'is given place line on current
|
||||
layer (rectcolor) at indicated coordinates.
|
||||
if 'pos' is given insert at given position in rectangle array.
|
||||
if 'pos' is given insert at given position in line array.
|
||||
if 'pos' set to -1 append to last element in line array.
|
||||
'propstring' is the attribute string. Set to empty if not given.
|
||||
if 'draw' is set to 1 (default) draw the new object, else don't
|
||||
If no coordinates are given start a GUI operation of line placement </pre>
|
||||
If no coordinates are given start a GUI operation of line placement
|
||||
if `gui` argument is given start a line GUI placement with 1st point
|
||||
set to current mouse coordinates </pre>
|
||||
<li><kbd> line_width n</kbd></li><pre>
|
||||
set line width to floating point number 'n' </pre>
|
||||
<li><kbd> list_hierarchy</kbd></li><pre>
|
||||
|
|
@ -1153,8 +1166,10 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
If not given take from symbol template attribute.</pre>
|
||||
<li><kbd> place_text</kbd></li><pre>
|
||||
Start a GUI placement of a text object </pre>
|
||||
<li><kbd> polygon</kbd></li><pre>
|
||||
Start a GUI placement of a polygon </pre>
|
||||
<li><kbd> polygon [gui]</kbd></li><pre>
|
||||
Start a GUI placement of a polygon
|
||||
if `gui` argument is given start a polygon GUI placement with 1st point
|
||||
set to current mouse coordinates </pre>
|
||||
<li><kbd> preview_window create|draw|destroy|close [win_path] [file]</kbd></li><pre>
|
||||
destroy: will delete preview schematic data and destroy container window
|
||||
close: same as destroy but leave the container window.
|
||||
|
|
@ -1192,8 +1207,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> push_undo</kbd></li><pre>
|
||||
Push current state on undo stack </pre>
|
||||
<li><kbd> raw what ...</kbd></li><pre>
|
||||
what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
|
||||
read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
|
||||
what = add | clear | datasets | index | info | loaded | list |
|
||||
new | points | rawfile | del | read | set | rename |
|
||||
sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
|
||||
|
||||
xschem raw read filename [type [sweep1 sweep2]]
|
||||
if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
|
||||
|
|
@ -1208,6 +1224,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
xschem raw del name
|
||||
delete named vector from current raw file
|
||||
|
||||
xschem raw rename old_name new_name
|
||||
rename a node in the loaded raw file.
|
||||
|
||||
xschem raw info
|
||||
print information about loaded raw files and show the currently active one.
|
||||
|
||||
|
|
@ -1284,7 +1303,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
new dataset do not start with a header row.
|
||||
Lines beginning with '#' are comments and ignored
|
||||
|
||||
time var_a var_b var_c
|
||||
time var_a var_b var_cnode in the loaded raw file.
|
||||
# this is a comment, ignored
|
||||
0.0 0.0 1.8 0.3
|
||||
<single empty line: ignored>
|
||||
|
|
@ -1325,14 +1344,19 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
Rebuild selection list</pre>
|
||||
<li><kbd> record_global_node n node</kbd></li><pre>
|
||||
call the record_global_node function (list of netlist global nodes) </pre>
|
||||
<li><kbd> rect [x1 y1 x2 y2] [pos] [propstring] [draw]</kbd></li><pre>
|
||||
if 'x1 y1 x2 y2'is given place recangle on current
|
||||
layer (rectcolor) at indicated coordinates.
|
||||
if 'pos' is given insert at given position in rectangle array.
|
||||
if 'pos' set to -1 append rectangle to last element in rectangle array.
|
||||
'propstring' is the attribute string. Set to empty if not given.
|
||||
if 'draw' is set to 1 (default) draw the new object, else don't
|
||||
If no coordinates are given start a GUI operation of rectangle placement </pre>
|
||||
<li><kbd> rect ...</kbd></li><pre>
|
||||
rect [x1 y1 x2 y2] [pos] [propstring] [draw]
|
||||
if 'x1 y1 x2 y2'is given place recangle on current
|
||||
layer (rectcolor) at indicated coordinates.
|
||||
if 'pos' is given insert at given position in rectangle array.
|
||||
if 'pos' set to -1 append rectangle to last element in rectangle array.
|
||||
'propstring' is the attribute string. Set to empty if not given.
|
||||
if 'draw' is set to 1 (default) draw the new object, else don't
|
||||
rect
|
||||
If no coordinates are given start a GUI operation of rectangle placement
|
||||
rect gui
|
||||
if `gui` argument is given start a GUI placement of a rectangle with 1st
|
||||
point starting from current mouse coordinates </pre>
|
||||
<li><kbd> redo</kbd></li><pre>
|
||||
Redo last undone action </pre>
|
||||
<li><kbd> redraw</kbd></li><pre>
|
||||
|
|
@ -1634,6 +1658,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
Unhighlight selected nets/pins </pre>
|
||||
<li><kbd> unselect_all [draw]</kbd></li><pre>
|
||||
Unselect everything. If draw is given and set to '0' no drawing is done </pre>
|
||||
<li><kbd> unselect_attached_floaters</kbd></li><pre>
|
||||
Unselect objects (not symbol instances) attached to some instance with a
|
||||
non empty name=... attribute </pre>
|
||||
<li><kbd> update_all_sym_bboxes</kbd></li><pre>
|
||||
Update all symbol bounding boxes </pre>
|
||||
<li><kbd> update_op</kbd></li><pre>
|
||||
|
|
@ -1649,8 +1676,12 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> wire_coord n</kbd></li><pre>
|
||||
return 4 coordinates of wire[n] </pre>
|
||||
<li><kbd> wire [x1 y1 x2 y2] [pos] [prop] [sel]</kbd></li><pre>
|
||||
wire
|
||||
wire gui
|
||||
Place a new wire
|
||||
if no coordinates are given start a GUI wire placement </pre>
|
||||
if no coordinates are given start a GUI wire placement
|
||||
if `gui` argument is given start a GUI placement of a wire with 1st point
|
||||
starting from current mouse coordinates </pre>
|
||||
<li><kbd> wire_cut [x y] [noalign]</kbd></li><pre>
|
||||
start a wire cut operation. Point the mouse in the middle of a wire and
|
||||
Alt-click right button.
|
||||
|
|
@ -1732,6 +1763,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -551,6 +551,19 @@ verilog_format="xnor #(@risedel , @falldel ) @name ( @@Z , @@A , @@B );"
|
|||
</ul>
|
||||
<h3>PREDEFINED SYMBOL VALUES</h3>
|
||||
<ul>
|
||||
<li><kbd>@name</kbd></li>
|
||||
<p> This expands to the instance name of the symbol (like C1, R2, X3, ...)
|
||||
It is replaced with the value of the <kbd>name=...</kbd> attribute given when placing an instance of the symbol
|
||||
in a schematic.</p>
|
||||
<li><kbd>#pattern#@name</kbd></li>
|
||||
<p> This is a variation of the above where <kbd>pattern</kbd> is prefixed to all substituted <kbd>@name</kbd>
|
||||
patterns. The difference with <kbd>pattern@name</kbd> is that in case of vector instances (this means
|
||||
a placement of an instance with <kbd>name=R2[3:0]</kbd>, for example) the <kbd>pattern</kbd> string
|
||||
is added to all single instances when expanding the name. see below examples.<br>
|
||||
<kbd>pattern@name</kbd> where <kbd>name=R2[2:0]</kbd> is given in the instance placement,
|
||||
expands to <kbd>patternR2[2],R2[1],R2[0]</kbd><br>
|
||||
<kbd>#pattern#@name</kbd> where <kbd>name=R2[2:0]</kbd> is given in the instance placement,
|
||||
expands to <kbd>patternR2[2],patternR2[1],patternR2[0]</kbd><br>
|
||||
<li><kbd>@symname</kbd></li>
|
||||
<p> This expands to the name of the symbol</p>
|
||||
<li><kbd>@symref</kbd></li>
|
||||
|
|
|
|||
167
src/actions.c
167
src/actions.c
|
|
@ -1066,7 +1066,7 @@ void clear_partial_selected_wires(void)
|
|||
rebuild_selected_array();
|
||||
for(j=0; j < xctx->lastsel; ++j) if(xctx->sel_array[j].type == WIRE) {
|
||||
int wire = xctx->sel_array[j].n;
|
||||
select_wire(wire, 0, 1);
|
||||
select_wire(wire, 0, 1, 1);
|
||||
}
|
||||
xctx->need_reb_sel_arr = 1;
|
||||
rebuild_selected_array();
|
||||
|
|
@ -1229,7 +1229,7 @@ int unselect_partial_sel_wires(void)
|
|||
while(wptr) {
|
||||
xWire *w = &xctx->wire[wptr->n];
|
||||
if(touch(w->x1, w->y1, w->x2, w->y2, pinx0, piny0) && w->sel && w->sel != SELECTED) {
|
||||
select_wire(wptr->n, 0, 1);
|
||||
select_wire(wptr->n, 0, 1, 1);
|
||||
changed = 1;
|
||||
}
|
||||
wptr = wptr->next;
|
||||
|
|
@ -1258,7 +1258,7 @@ int unselect_partial_sel_wires(void)
|
|||
}
|
||||
if(touch(w->x1, w->y1, w->x2, w->y2, x0, y0) && w->sel && w->sel != SELECTED) {
|
||||
xctx->wire[wptr->n].sel = 0;
|
||||
select_wire(wptr->n, 0, 1);
|
||||
select_wire(wptr->n, 0, 1, 1);
|
||||
changed = 1;
|
||||
}
|
||||
wptr = wptr->next;
|
||||
|
|
@ -1295,8 +1295,8 @@ void attach_labels_to_inst(int interactive) /* offloaded from callback.c 201710
|
|||
int use_label_prefix;
|
||||
int found=0;
|
||||
|
||||
my_strdup(_ALLOC_ID_, &symname_pin, tcleval("rel_sym_path [find_file_first lab_pin.sym]"));
|
||||
my_strdup(_ALLOC_ID_, &symname_wire, tcleval("rel_sym_path [find_file_first lab_wire.sym]"));
|
||||
my_strdup(_ALLOC_ID_, &symname_pin, tcleval("find_file_first lab_pin.sym"));
|
||||
my_strdup(_ALLOC_ID_, &symname_wire, tcleval("find_file_first lab_wire.sym"));
|
||||
if(symname_pin && symname_wire) {
|
||||
rebuild_selected_array();
|
||||
k = xctx->lastsel;
|
||||
|
|
@ -1450,12 +1450,11 @@ void delete_files(void)
|
|||
|
||||
void place_net_label(int type)
|
||||
{
|
||||
unselect_all(1);
|
||||
if(type == 1) {
|
||||
const char *lab = tcleval("rel_sym_path [find_file_first lab_pin.sym]");
|
||||
const char *lab = tcleval("find_file_first lab_pin.sym");
|
||||
place_symbol(-1, lab, xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/*to_push_undo*/);
|
||||
} else {
|
||||
const char *lab = tcleval("rel_sym_path [find_file_first lab_wire.sym]");
|
||||
const char *lab = tcleval("find_file_first lab_wire.sym");
|
||||
place_symbol(-1, lab, xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/*to_push_undo*/);
|
||||
}
|
||||
move_objects(START,0,0,0);
|
||||
|
|
@ -1478,13 +1477,14 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
|
|||
char name[PATH_MAX];
|
||||
char name1[PATH_MAX];
|
||||
char tclev = 0;
|
||||
|
||||
if(symbol_name==NULL) {
|
||||
tcleval("load_file_dialog {Choose symbol} *.\\{sym,tcl\\} INITIALINSTDIR");
|
||||
my_strncpy(name1, tclresult(), S(name1));
|
||||
} else {
|
||||
my_strncpy(name1, trim_chars(symbol_name, " \t\n"), S(name1));
|
||||
my_strncpy(name1, abs_sym_path(trim_chars(symbol_name, " \t\n"), ""), S(name1));
|
||||
}
|
||||
|
||||
if(!name1[0]) return 0;
|
||||
dbg(1, "place_symbol(): 1: name1=%s first_call=%d\n",name1, first_call);
|
||||
/* remove tcleval( given in file selector, if any ... */
|
||||
if(strstr(name1, "tcleval(")) {
|
||||
|
|
@ -1562,7 +1562,11 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
|
|||
/* After having assigned prop_ptr to new instance translate symbol reference
|
||||
* to resolve @params --> res.tcl(@value\) --> res.tcl(100) */
|
||||
my_strncpy(name, translate(n, name), S(name));
|
||||
i = match_symbol(name);
|
||||
/* parameters like res.tcl(@value\) have been resolved, so reload symbol removing previous */
|
||||
if(strcmp(name, name1)) {
|
||||
remove_symbol(i);
|
||||
i = match_symbol(name);
|
||||
}
|
||||
xctx->inst[n].ptr = i;
|
||||
set_inst_flags(&xctx->inst[n]);
|
||||
hash_names(n, XINSERT);
|
||||
|
|
@ -1576,6 +1580,50 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
|
|||
if(xctx->prep_hash_inst) hash_inst(XINSERT, n); /* no need to rehash, add item */
|
||||
/* xctx->prep_hash_inst=0; */
|
||||
|
||||
/* embed a (locked) graph object floater inside the symbol */
|
||||
if(xctx->sym[i].type && !strcmp(xctx->sym[i].type, "scope")) {
|
||||
char *prop = NULL;
|
||||
|
||||
my_strdup(_ALLOC_ID_, &xctx->inst[n].prop_ptr,
|
||||
subst_token(xctx->inst[n].prop_ptr, "attach", xctx->inst[n].instname));
|
||||
my_mstrcat(_ALLOC_ID_, &prop, "name=", xctx->inst[n].instname, "\n", NULL);
|
||||
my_mstrcat(_ALLOC_ID_, &prop, "flags=graph,unlocked\n", NULL);
|
||||
my_mstrcat(_ALLOC_ID_, &prop, "lock=1\n", NULL);
|
||||
my_mstrcat(_ALLOC_ID_, &prop, "color=8\n", NULL);
|
||||
if(xctx->sym[i].rects[PINLAYER] == 0) {
|
||||
if(xctx->lastsel == 1 && xctx->sel_array[0].type==ELEMENT) {
|
||||
my_mstrcat(_ALLOC_ID_, &prop, "node=\"tcleval([xschem get_fqdevice [xschem translate ",
|
||||
xctx->inst[n].instname, " @device]])\"\n", NULL);
|
||||
my_strdup(_ALLOC_ID_, &xctx->inst[n].prop_ptr,
|
||||
subst_token(xctx->inst[n].prop_ptr, "device", xctx->inst[xctx->sel_array[0].n].instname));
|
||||
} else {
|
||||
const char msg[]="scope_ammeter is being inserted but no selected ammeter device/vsource to link to\n";
|
||||
dbg(0, "%s", msg);
|
||||
if(has_x) tclvareval("alert_ {", msg, "} {}", NULL);
|
||||
if(xctx->inst[n].instname) my_free(_ALLOC_ID_, &xctx->inst[n].instname);
|
||||
if(xctx->inst[n].name) my_free(_ALLOC_ID_, &xctx->inst[n].name);
|
||||
if(xctx->inst[n].prop_ptr) my_free(_ALLOC_ID_, &xctx->inst[n].prop_ptr);
|
||||
if(xctx->inst[n].lab) my_free(_ALLOC_ID_, &xctx->inst[n].lab);
|
||||
if(prop) my_free(_ALLOC_ID_, &prop);
|
||||
xctx->instances--;
|
||||
return 0;
|
||||
}
|
||||
} else if(xctx->sym[i].rects[PINLAYER] == 1) {
|
||||
my_mstrcat(_ALLOC_ID_, &prop,
|
||||
"node=\"tcleval(",
|
||||
"[xschem translate ", xctx->inst[n].instname, " @#0:net_name]",
|
||||
")\"\n", NULL);
|
||||
} else {
|
||||
my_mstrcat(_ALLOC_ID_, &prop,
|
||||
"node=\"tcleval(",
|
||||
"[xschem translate ", xctx->inst[n].instname, " @#0:net_name] ",
|
||||
"[xschem translate ", xctx->inst[n].instname, " @#1:net_name] -",
|
||||
")\"\n", NULL);
|
||||
}
|
||||
storeobject(-1, x + 20, y-125, x + 130 , y - 25, xRECT, 2, SELECTED, prop);
|
||||
my_free(_ALLOC_ID_, &prop);
|
||||
}
|
||||
|
||||
if(draw_sym & 3) {
|
||||
bbox(ADD, xctx->inst[n].x1, xctx->inst[n].y1, xctx->inst[n].x2, xctx->inst[n].y2);
|
||||
}
|
||||
|
|
@ -1587,6 +1635,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
|
|||
/* hilight new element 24122002 */
|
||||
|
||||
if(draw_sym & 4 ) {
|
||||
unselect_all(1);
|
||||
select_element(n, SELECTED,0, 1);
|
||||
drawtemparc(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
drawtemprect(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);
|
||||
|
|
@ -2214,7 +2263,7 @@ int change_sch_path(int instnumber, int dr)
|
|||
char *ptr;
|
||||
size_t pathlen;
|
||||
int res = 0;
|
||||
if(level <= 0 ) return 0;
|
||||
if(level < 0 ) return 0;
|
||||
my_strdup2(_ALLOC_ID_, &instname, get_tok_value(xctx->hier_attr[level].prop_ptr, "name", 0));
|
||||
my_strdup2(_ALLOC_ID_, &expanded_instname, expandlabel(instname, &inst_mult));
|
||||
my_strdup2(_ALLOC_ID_, &path, xctx->sch_path[xctx->currsch]);
|
||||
|
|
@ -2261,6 +2310,7 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title)
|
|||
int inst_mult, inst_number;
|
||||
int save_ok = 0;
|
||||
int i, n = 0;
|
||||
int descend_ok = 1;
|
||||
|
||||
if(xctx->currsch + 1 >= CADMAXHIER) {
|
||||
dbg(0, "descend_schematic(): max hierarchy depth reached: %d", CADMAXHIER);
|
||||
|
|
@ -2416,24 +2466,25 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title)
|
|||
dbg(1, "descend_schematic(): filename=%s\n", filename);
|
||||
/* we are descending from a parent schematic downloaded from the web */
|
||||
if(!tclgetboolvar("keep_symbols")) remove_symbols();
|
||||
load_schematic(1, filename, (set_title & 1), alert);
|
||||
if(xctx->hilight_nets) {
|
||||
prepare_netlist_structs(0);
|
||||
propagate_hilights(1, 0, XINSERT_NOREPLACE);
|
||||
}
|
||||
dbg(1, "descend_schematic(): before zoom(): prep_hash_inst=%d\n", xctx->prep_hash_inst);
|
||||
|
||||
if(xctx->rects[GRIDLAYER] > 0 && tcleval("info exists ngspice::ngspice_data")[0] == '0') {
|
||||
Graph_ctx *gr = &xctx->graph_struct;
|
||||
xRect *r = &xctx->rect[GRIDLAYER][0];
|
||||
if(r->flags & 1) {
|
||||
backannotate_at_cursor_b_pos(r, gr);
|
||||
descend_ok = load_schematic(1, filename, (set_title & 1), alert);
|
||||
if(descend_ok) {
|
||||
if(xctx->hilight_nets) {
|
||||
prepare_netlist_structs(0);
|
||||
propagate_hilights(1, 0, XINSERT_NOREPLACE);
|
||||
}
|
||||
dbg(1, "descend_schematic(): before zoom(): prep_hash_inst=%d\n", xctx->prep_hash_inst);
|
||||
|
||||
if(xctx->rects[GRIDLAYER] > 0 && tcleval("info exists ngspice::ngspice_data")[0] == '0') {
|
||||
Graph_ctx *gr = &xctx->graph_struct;
|
||||
xRect *r = &xctx->rect[GRIDLAYER][0];
|
||||
if(r->flags & 1) {
|
||||
backannotate_at_cursor_b_pos(r, gr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
|
||||
}
|
||||
return 1;
|
||||
return descend_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2449,7 +2500,7 @@ void go_back(int what)
|
|||
char filename[PATH_MAX];
|
||||
int prev_sch_type;
|
||||
int confirm = what & 1;
|
||||
int set_title = !(confirm & 2);
|
||||
int set_title = !(what & 2);
|
||||
|
||||
save_ok=1;
|
||||
dbg(1,"go_back(): sch[xctx->currsch]=%s\n", xctx->sch[xctx->currsch]);
|
||||
|
|
@ -3132,61 +3183,11 @@ void new_wire(int what, double mx_snap, double my_snap)
|
|||
xctx->ui_state &= ~STARTWIRE;
|
||||
}
|
||||
if( (what & RUBBER) ) {
|
||||
if(xctx->manhattan_lines & 1) {
|
||||
xctx->nl_xx1=xctx->nl_x1;xctx->nl_yy1=xctx->nl_y1;
|
||||
xctx->nl_xx2=xctx->nl_x2;xctx->nl_yy2=xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1);
|
||||
drawtempline(xctx->gctiled, NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1);
|
||||
xctx->nl_xx1=xctx->nl_x1;xctx->nl_yy1=xctx->nl_y1;
|
||||
xctx->nl_xx2=xctx->nl_x2;xctx->nl_yy2=xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(xctx->gctiled, NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
restore_selection(xctx->nl_x1, xctx->nl_y1, xctx->nl_x2, xctx->nl_y2);
|
||||
xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap;
|
||||
if(!(what & CLEAR)) {
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1);
|
||||
drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1);
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
}
|
||||
} else if(xctx->manhattan_lines & 2) {
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2);
|
||||
drawtempline(xctx->gctiled, NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2);
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy2,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(xctx->gctiled, NOW, xctx->nl_xx1,xctx->nl_yy2,xctx->nl_xx2,xctx->nl_yy2);
|
||||
restore_selection(xctx->nl_x1, xctx->nl_y1, xctx->nl_x2, xctx->nl_y2);
|
||||
xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap;
|
||||
if(!(what & CLEAR)) {
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2);
|
||||
drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2);
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy2,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx1,xctx->nl_yy2,xctx->nl_xx2,xctx->nl_yy2);
|
||||
}
|
||||
} else {
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(xctx->gctiled, NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
restore_selection(xctx->nl_x1, xctx->nl_y1, xctx->nl_x2, xctx->nl_y2);
|
||||
xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap;
|
||||
if(!(what & CLEAR)) {
|
||||
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
|
||||
xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
}
|
||||
drawtemp_manhattanline(xctx->gctiled, NOW, xctx->nl_x1, xctx->nl_y1, xctx->nl_x2, xctx->nl_y2);
|
||||
restore_selection(xctx->nl_x1, xctx->nl_y1, xctx->nl_x2, xctx->nl_y2);
|
||||
xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap;
|
||||
if(!(what & CLEAR)) {
|
||||
drawtemp_manhattanline(xctx->gc[WIRELAYER], NOW, xctx->nl_x1, xctx->nl_y1, xctx->nl_x2, xctx->nl_y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3830,7 +3831,7 @@ int place_text(int draw_text, double mx, double my)
|
|||
dbg(1,"props=%s, txt=%s\n", props, txt);
|
||||
|
||||
create_text(draw_text, mx, my, 0, 0, txt, props, atof(hsize), atof(vsize));
|
||||
select_text(xctx->texts - 1, SELECTED, 0);
|
||||
select_text(xctx->texts - 1, SELECTED, 0, 1);
|
||||
rebuild_selected_array(); /* sets xctx->ui_state |= SELECTION */
|
||||
drawtemprect(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);
|
||||
drawtempline(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);
|
||||
|
|
|
|||
3523
src/callback.c
3523
src/callback.c
File diff suppressed because it is too large
Load Diff
111
src/draw.c
111
src/draw.c
|
|
@ -930,10 +930,14 @@ static void drawgrid()
|
|||
double mult;
|
||||
#if DRAW_ALL_CAIRO==0
|
||||
int i=0;
|
||||
const char *psize_ptr;
|
||||
int big_gr = tclgetboolvar("big_grid_points");
|
||||
int grid_point_size = -1;
|
||||
char dash_arr[2];
|
||||
int axes = tclgetboolvar("draw_grid_axes");
|
||||
|
||||
psize_ptr = tclgetvar("grid_point_size");
|
||||
if(psize_ptr[0]) grid_point_size = atoi(psize_ptr);
|
||||
if(axes) {
|
||||
dash_arr[0] = dash_arr[1] = (char) 3;
|
||||
XSetDashes(display, xctx->gc[GRIDLAYER], 0, dash_arr, 1);
|
||||
|
|
@ -959,9 +963,8 @@ static void drawgrid()
|
|||
delta = delta * pow(CADGRIDMULTIPLY, mult);
|
||||
}
|
||||
|
||||
/* while(delta < CADGRIDTHRESHOLD) delta *= CADGRIDMULTIPLY; */ /* <-- to be improved,but works */
|
||||
|
||||
|
||||
/* ************************ Draw axes ****************** */
|
||||
#if DRAW_ALL_CAIRO==1
|
||||
xax =floor(xctx->xorigin*xctx->mooz) + 0.5; yax = floor(xctx->yorigin*xctx->mooz) + 0.5;
|
||||
#else
|
||||
|
|
@ -1007,26 +1010,36 @@ static void drawgrid()
|
|||
#endif
|
||||
}
|
||||
}
|
||||
/* ************************ /Draw axes ****************** */
|
||||
|
||||
#if DRAW_ALL_CAIRO==0
|
||||
if(axes) {
|
||||
if(grid_point_size != -1) {
|
||||
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
|
||||
grid_point_size, LineSolid, CapProjecting, LINEJOIN);
|
||||
} else if(!big_gr) {
|
||||
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
|
||||
0, LineSolid, LINECAP, LINEJOIN);
|
||||
} else {
|
||||
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
|
||||
XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(grid_point_size >= 0) big_gr = 1;
|
||||
|
||||
tmp = floor((xctx->areay1+1)/delta)*delta-fmod(-xctx->yorigin*xctx->mooz, delta);
|
||||
for(x=floor((xctx->areax1+1)/delta)*delta-fmod(-xctx->xorigin*xctx->mooz, delta); x < xctx->areax2; x += delta) {
|
||||
xx = x;
|
||||
#if DRAW_ALL_CAIRO==1
|
||||
xx = floor(x) + 0.5;
|
||||
#endif
|
||||
if((int)xx == (int)xax) continue;
|
||||
if(axes && (int)xx == (int)xax) continue;
|
||||
for(y=tmp; y < xctx->areay2; y += delta) {
|
||||
yy = y;
|
||||
#if DRAW_ALL_CAIRO==1
|
||||
yy = floor(y) + 0.5;
|
||||
#endif
|
||||
if((int)yy == (int)yax) continue;
|
||||
if(axes && (int)yy == (int)yax) continue;
|
||||
#if DRAW_ALL_CAIRO==1
|
||||
if(xctx->draw_window) {
|
||||
cairo_move_to(xctx->cairo_ctx, xx, yy) ;
|
||||
|
|
@ -1087,6 +1100,12 @@ static void drawgrid()
|
|||
if(xctx->draw_pixmap) cairo_stroke(xctx->cairo_save_ctx);
|
||||
if(xctx->draw_window) cairo_stroke(xctx->cairo_ctx);
|
||||
#endif
|
||||
|
||||
#if DRAW_ALL_CAIRO==0
|
||||
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
|
||||
XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if !defined(__unix__) && HAS_CAIRO==1
|
||||
|
|
@ -1356,6 +1375,45 @@ void drawtempline(GC gc, int what, double linex1,double liney1,double linex2,dou
|
|||
}
|
||||
}
|
||||
|
||||
void drawtemp_manhattanline(GC gc, int what, double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double origin_shifted_x2, origin_shifted_y2;
|
||||
if(tclgetboolvar("orthogonal_wiring")) {
|
||||
/* Origin shift the cartesian coordinate p2(x2,y2) w.r.t. p1(x1,y1) */
|
||||
origin_shifted_x2 = x2 - x1;
|
||||
origin_shifted_y2 = y2 - y1;
|
||||
/* Draw whichever component of the resulting orthogonal-wire is bigger (either horizontal or vertical), first */
|
||||
if(origin_shifted_x2*origin_shifted_x2 > origin_shifted_y2*origin_shifted_y2)
|
||||
xctx->manhattan_lines = 1;
|
||||
else
|
||||
xctx->manhattan_lines = 2;
|
||||
}
|
||||
if(xctx->manhattan_lines & 1) {
|
||||
xctx->nl_xx1 = x1; xctx->nl_yy1 = y1;
|
||||
xctx->nl_xx2 = x2; xctx->nl_yy2 = y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1);
|
||||
drawtempline(gc, what, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1);
|
||||
xctx->nl_xx1 = x1; xctx->nl_yy1 = y1;
|
||||
xctx->nl_xx2 = x2; xctx->nl_yy2 = y2;
|
||||
ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(gc, what, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
} else if(xctx->manhattan_lines & 2) {
|
||||
xctx->nl_xx1 = x1; xctx->nl_yy1 = y1;
|
||||
xctx->nl_xx2 = x2; xctx->nl_yy2 = y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2);
|
||||
drawtempline(gc, what, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2);
|
||||
xctx->nl_xx1 = x1; xctx->nl_yy1 = y1;
|
||||
xctx->nl_xx2 = x2; xctx->nl_yy2 = y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy2,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(gc, what, xctx->nl_xx1,xctx->nl_yy2,xctx->nl_xx2,xctx->nl_yy2);
|
||||
} else {
|
||||
xctx->nl_xx1 = x1; xctx->nl_yy1 = y1;
|
||||
xctx->nl_xx2 = x2; xctx->nl_yy2 = y2;
|
||||
ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
drawtempline(gc, what, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
|
||||
}
|
||||
}
|
||||
|
||||
void drawtemparc(GC gc, int what, double x, double y, double r, double a, double b)
|
||||
{
|
||||
static int i=0;
|
||||
|
|
@ -2838,7 +2896,7 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
|
|||
/* background */
|
||||
filledrect(0, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
|
||||
/* graph bounding box */
|
||||
drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 0, -1, -1);
|
||||
drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
|
||||
|
||||
bbox(START, 0.0, 0.0, 0.0, 0.0);
|
||||
bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
|
||||
|
|
@ -3055,10 +3113,9 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
gr->gh = gr->gy2 - gr->gy1;
|
||||
/* set margins */
|
||||
tmp = gr->rw * 0.14;
|
||||
gr->marginx = tmp < 50 ? 50 : tmp;
|
||||
gr->marginx = tmp;
|
||||
tmp = gr->rh * 0.14;
|
||||
gr->marginy = tmp < 40 ? 40 : tmp;
|
||||
|
||||
gr->marginy = tmp;
|
||||
/* calculate graph bounding box (container - margin)
|
||||
* This is the box where plot is done */
|
||||
gr->x1 = gr->rx1 + gr->marginx;
|
||||
|
|
@ -3083,14 +3140,15 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
|
||||
/* x axis, y axis text sizes */
|
||||
gr->txtsizey = gr->h / gr->divy * 0.0095;
|
||||
tmp = gr->marginx * 0.003;
|
||||
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
||||
tmp = gr->marginy * 0.02;
|
||||
tmp = gr->marginx * 0.004;
|
||||
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
||||
/* tmp = gr->marginy * 0.02;
|
||||
* if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
||||
*/
|
||||
gr->txtsizey *= gr->magy;
|
||||
|
||||
gr->txtsizex = gr->w / gr->divx * 0.0033;
|
||||
tmp = gr->marginy * 0.0063;
|
||||
gr->txtsizex = gr->w / gr->divx * 0.0070;
|
||||
tmp = gr->marginy * 0.0065;
|
||||
if(tmp < gr->txtsizex) gr->txtsizex = tmp;
|
||||
gr->txtsizex *= gr->magx;
|
||||
|
||||
|
|
@ -3258,7 +3316,7 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee
|
|||
if(gr->unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", stok ? stok : "" , gr->unitx_suffix);
|
||||
else my_snprintf(tmpstr, S(tmpstr), "%s", stok ? stok : "");
|
||||
draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0,
|
||||
gr->rx1 + 2 + gr->rw / n_nodes * wcnt, gr->ry2-5, gr->txtsizelab, gr->txtsizelab);
|
||||
gr->rx1 + 2 + gr->rw / n_nodes * wcnt, gr->ry2-2, gr->txtsizelab, gr->txtsizelab);
|
||||
}
|
||||
|
||||
if(gr->legend || gr->digital) {
|
||||
|
|
@ -3782,7 +3840,7 @@ int find_closest_wave(int i, Graph_ctx *gr)
|
|||
* 8: all drawing, if not set do only XCopyArea / x-cursor if specified
|
||||
* ct is a pointer used in windows for cairo
|
||||
*/
|
||||
void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
||||
void draw_graph(int i, int flags, Graph_ctx *gr, void *ct)
|
||||
{
|
||||
int wc = 4, wave_color = 4;
|
||||
char *node = NULL, *color = NULL, *sweep = NULL;
|
||||
|
|
@ -3804,7 +3862,6 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
int save_extra_idx = -1;
|
||||
double cursor1, cursor2;
|
||||
|
||||
|
||||
if(xctx->only_probes) return;
|
||||
if(RECT_OUTSIDE( gr->sx1, gr->sy1, gr->sx2, gr->sy2,
|
||||
xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2)) return;
|
||||
|
|
@ -4089,7 +4146,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
if((gr->mode == 2) || (xxfollowing >= start && xxprevious <= end)) {
|
||||
if(first == -1) first = p;
|
||||
/* Build poly x array. Translate from graph coordinates to screen coords */
|
||||
point[poly_npoints].x = (short)S_X(xx);
|
||||
point[poly_npoints].x = (short)CLIP(S_X(xx), -30000, 30000);
|
||||
if(dataset == -1 || dataset == sweepvar_wrap) {
|
||||
/* cursor1: show measurements on nodes in graph */
|
||||
if(flags & 2 && measure_p == -1 && cnt) {
|
||||
|
|
@ -4770,8 +4827,11 @@ static void draw_images_all(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2, double ry2)
|
||||
void svg_embedded_graph(FILE *fd, int i, double rx1, double ry1, double rx2, double ry2)
|
||||
{
|
||||
#ifndef __unix__
|
||||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||
#endif
|
||||
#if HAS_CAIRO==1
|
||||
Zoom_info zi;
|
||||
char *ptr = NULL;
|
||||
|
|
@ -4821,7 +4881,9 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
|
|||
xctx->draw_pixmap=1;
|
||||
save = xctx->do_copy_area;
|
||||
xctx->do_copy_area=0;
|
||||
draw();
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, NULL);
|
||||
|
||||
#ifdef __unix__
|
||||
png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual,
|
||||
xctx->xrect[0].width, xctx->xrect[0].height);
|
||||
|
|
@ -4834,12 +4896,9 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
|
|||
cairo_set_source_surface(ct, xctx->cairo_save_sfc, 0, 0);
|
||||
cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint(ct);
|
||||
for(int i = 0; i < xctx->rects[GRIDLAYER]; ++i) {
|
||||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||
if(r->flags & 1) {
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
|
||||
}
|
||||
if(r->flags & 1) {
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
|
||||
}
|
||||
#endif
|
||||
closure.buffer = NULL;
|
||||
|
|
|
|||
|
|
@ -594,7 +594,11 @@ FILE *my_fopen(const char *f, const char *m)
|
|||
|
||||
st = stat(f, &buf);
|
||||
if(st) return NULL; /* not existing or error */
|
||||
#ifdef __unix__
|
||||
if(!S_ISREG(buf.st_mode)) return NULL; /* not a regular file/symlink to a regular file */
|
||||
#else
|
||||
/* TBD */
|
||||
#endif
|
||||
fd = fopen(f, m);
|
||||
return fd;
|
||||
}
|
||||
|
|
@ -1637,6 +1641,7 @@ static int update_symbol(const char *result, int x, int selected_inst)
|
|||
/* preserve backslashes in name ---------0---------------------------------->. */
|
||||
my_strdup(_ALLOC_ID_, &name, get_tok_value(xctx->inst[*ii].prop_ptr, "name", 1));
|
||||
if(name && name[0] ) {
|
||||
char *old_name = NULL;
|
||||
dbg(1, "update_symbol(): prefix!='\\0', name=%s\n", name);
|
||||
/* change prefix if changing symbol type; */
|
||||
if(prefix && old_prefix && old_prefix != prefix) {
|
||||
|
|
@ -1650,10 +1655,13 @@ static int update_symbol(const char *result, int x, int selected_inst)
|
|||
if(!k) hash_names(-1, XINSERT);
|
||||
hash_names(*ii, XDELETE);
|
||||
dbg(1, "update_symbol(): delete %s\n", xctx->inst[*ii].instname);
|
||||
my_strdup2(_ALLOC_ID_, &old_name, xctx->inst[*ii].instname);
|
||||
new_prop_string(*ii, ptr, /* sets also inst[].instname */
|
||||
tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
|
||||
hash_names(*ii, XINSERT);
|
||||
update_attached_floaters(old_name, *ii, 1);
|
||||
dbg(1, "update_symbol(): insert %s\n", xctx->inst[*ii].instname);
|
||||
my_free(_ALLOC_ID_, &old_name);
|
||||
}
|
||||
set_inst_flags(&xctx->inst[*ii]);
|
||||
} /* end for(k=0;k<xctx->lastsel; ++k) */
|
||||
|
|
|
|||
|
|
@ -274,10 +274,11 @@ static int kklex()
|
|||
while (c != 0 && isalnum(c) && i < length);
|
||||
str--;
|
||||
symbuf[i] = '\0';
|
||||
s = getsym (symbuf);
|
||||
s = getsym(symbuf);
|
||||
kklval.tptr = s;
|
||||
dbg(dbglev, "ylex: FNCT=%s\n", symbuf);
|
||||
return FNCT;
|
||||
if(s) return FNCT;
|
||||
return 0; /* error : undefined identifier */
|
||||
}
|
||||
/* Any other character is a token by itself. */
|
||||
return c;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
static double distance; /* safe to keep even with multiple schematics */
|
||||
static Selected sel; /* safe to keep even with multiple schematics */
|
||||
|
||||
static void find_closest_wire(double mx, double my)
|
||||
static void find_closest_wire(double mx, double my, int override_lock)
|
||||
/* returns the net that is closest to the mouse pointer */
|
||||
/* if there are nets and distance < CADWIREMINDIST */
|
||||
{
|
||||
|
|
@ -42,14 +42,15 @@ static void find_closest_wire(double mx, double my)
|
|||
w = i; d = tmp;
|
||||
}
|
||||
}
|
||||
if( d <= threshold && w!=-1)
|
||||
if( w != -1 && d <= threshold &&
|
||||
(override_lock || strboolcmp(get_tok_value(xctx->wire[w].prop_ptr, "lock", 0), "true")) )
|
||||
{
|
||||
sel.n = w; sel.type = WIRE;
|
||||
distance = d;
|
||||
}
|
||||
}
|
||||
|
||||
static void find_closest_bezier(double mx, double my, int c, int i, int *l, int *col)
|
||||
static double find_closest_bezier(double mx, double my, double d, int c, int i, int *l, int *col)
|
||||
{
|
||||
const double bez_steps = 1.0/8.0; /* divide the t = [0,1] interval into 8 steps */
|
||||
int b;
|
||||
|
|
@ -97,16 +98,17 @@ static void find_closest_bezier(double mx, double my, int c, int i, int *l, int
|
|||
xp1 = (1 - t1) * (1 - t1) * x0 + 2 * (1 - t1) * t1 * x1 + t1 * t1 * x2;
|
||||
yp1 = (1 - t1) * (1 - t1) * y0 + 2 * (1 - t1) * t1 * y1 + t1 * t1 * y2;
|
||||
ORDER(xp, yp, xp1, yp1);
|
||||
if( (tmp = dist(xp, yp, xp1, yp1, mx, my)) < distance )
|
||||
if( (tmp = dist(xp, yp, xp1, yp1, mx, my)) < d )
|
||||
{
|
||||
*l = i; distance = tmp; *col = c;
|
||||
dbg(1, "find_closest_bezier(): distance=%.16g n=%d\n", distance, i);
|
||||
*l = i; d = tmp; *col = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg(1, "find_closest_bezier(): d=%.16g n=%d\n", d, i);
|
||||
return d;
|
||||
}
|
||||
|
||||
static void find_closest_polygon(double mx, double my)
|
||||
static void find_closest_polygon(double mx, double my, int override_lock)
|
||||
/* returns the polygon that is closest to the mouse pointer */
|
||||
/* if there are lines and distance < CADWIREMINDIST */
|
||||
{
|
||||
|
|
@ -126,15 +128,7 @@ static void find_closest_polygon(double mx, double my)
|
|||
bezier = bezier && (p->points > 2);
|
||||
|
||||
if(bezier) {
|
||||
double ds = xctx->cadhalfdotsize;
|
||||
|
||||
find_closest_bezier(mx, my, c, i, &l, &col);
|
||||
for(j = 0; j < p->points; j++) {
|
||||
if( POINTINSIDE(mx, my, p->x[j] - ds, p->y[j] - ds, p->x[j] + ds, p->y[j] + ds)) {
|
||||
l = i; d = 0.0;col = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
d = find_closest_bezier(mx, my, d, c, i, &l, &col);
|
||||
} else {
|
||||
for(j=0; j<xctx->poly[c][i].points-1; ++j) {
|
||||
x1 = p->x[j];
|
||||
|
|
@ -145,13 +139,14 @@ static void find_closest_polygon(double mx, double my)
|
|||
if( (tmp = dist(x1, y1, x2, y2, mx, my)) < d )
|
||||
{
|
||||
l = i; d = tmp;col = c;
|
||||
dbg(1, "find_closest_polygon(): d=%.16g n=%d\n", d, i);
|
||||
}
|
||||
}
|
||||
dbg(1, "find_closest_polygon(): d=%.16g n=%d\n", d, i);
|
||||
}
|
||||
} /* end for i */
|
||||
} /* end for c */
|
||||
if( d <= threshold && l!=-1)
|
||||
if( d <= threshold && l!=-1 &&
|
||||
(override_lock || strboolcmp(get_tok_value(xctx->poly[col][l].prop_ptr, "lock", 0), "true")))
|
||||
{
|
||||
sel.n = l; sel.type = POLYGON; sel.col = col;
|
||||
distance = d;
|
||||
|
|
@ -159,7 +154,7 @@ static void find_closest_polygon(double mx, double my)
|
|||
}
|
||||
|
||||
|
||||
static void find_closest_line(double mx, double my)
|
||||
static void find_closest_line(double mx, double my, int override_lock)
|
||||
/* returns the line that is closest to the mouse pointer */
|
||||
/* if there are lines and distance < CADWIREMINDIST */
|
||||
{
|
||||
|
|
@ -181,7 +176,8 @@ static void find_closest_line(double mx, double my)
|
|||
}
|
||||
} /* end for i */
|
||||
} /* end for c */
|
||||
if( d <= threshold && l!=-1)
|
||||
if( d <= threshold && l!=-1 &&
|
||||
(override_lock || strboolcmp(get_tok_value(xctx->line[col][l].prop_ptr, "lock", 0), "true")))
|
||||
{
|
||||
sel.n = l; sel.type = LINE; sel.col = col;
|
||||
distance = d;
|
||||
|
|
@ -326,7 +322,7 @@ void xfind_closest_net_or_symbol_pin(double mx, double my, double *x, double *y)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void find_closest_arc(double mx, double my)
|
||||
static void find_closest_arc(double mx, double my, int override_lock)
|
||||
{
|
||||
double dist, angle, angle1, angle2;
|
||||
int i, c, r=-1, col;
|
||||
|
|
@ -371,7 +367,8 @@ static void find_closest_arc(double mx, double my)
|
|||
}
|
||||
} /* end for i */
|
||||
} /* end for c */
|
||||
if( r!=-1 && d <= threshold ) /* * pow(xctx->arc[col][r].r, 2)) */
|
||||
if(r!=-1 && d <= threshold &&
|
||||
strboolcmp(get_tok_value(xctx->arc[col][r].prop_ptr, "lock", 0), "true"))
|
||||
{
|
||||
sel.n = r; sel.type = ARC; sel.col = col;
|
||||
distance = d;
|
||||
|
|
@ -439,7 +436,7 @@ static void find_closest_element(double mx, double my, int override_lock)
|
|||
}
|
||||
}
|
||||
|
||||
static void find_closest_text(double mx, double my)
|
||||
static void find_closest_text(double mx, double my, int override_lock)
|
||||
{
|
||||
short rot, flip;
|
||||
double xx1, xx2, yy1, yy2;
|
||||
|
|
@ -476,7 +473,9 @@ static void find_closest_text(double mx, double my)
|
|||
dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n", i, d);
|
||||
}
|
||||
} /* end for i */
|
||||
if( d <= threshold && r!=-1)
|
||||
|
||||
if( r != -1 && d <= threshold &&
|
||||
(override_lock || strboolcmp(get_tok_value(xctx->text[r].prop_ptr, "lock", 0), "true")) )
|
||||
{
|
||||
sel.n = r; sel.type = xTEXT;
|
||||
distance = d;
|
||||
|
|
@ -487,14 +486,14 @@ Selected find_closest_obj(double mx, double my, int override_lock)
|
|||
{
|
||||
sel.n = 0L; sel.col = 0; sel.type = 0;
|
||||
distance = DBL_MAX;
|
||||
find_closest_line(mx, my);
|
||||
find_closest_polygon(mx, my);
|
||||
find_closest_line(mx, my, override_lock);
|
||||
find_closest_polygon(mx, my, override_lock);
|
||||
/* dbg(1, "1 find_closest_obj(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type); */
|
||||
find_closest_box(mx, my, override_lock);
|
||||
find_closest_arc(mx, my);
|
||||
find_closest_arc(mx, my, override_lock);
|
||||
/* dbg(1, "2 find_closest_obj(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type); */
|
||||
find_closest_text(mx, my);
|
||||
find_closest_wire(mx, my);
|
||||
find_closest_text(mx, my, override_lock);
|
||||
find_closest_wire(mx, my, override_lock);
|
||||
find_closest_element(mx, my, override_lock);
|
||||
return sel; /*sel.type = 0 if nothing found */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ ctrl+alt 's' Save-as symbol
|
|||
- 't' Place text
|
||||
shift 'T' Toggle *_ignore flag on selected instances
|
||||
alt 'u' Align to current grid selected objects
|
||||
ctrl 'u' Unselect attached floater objects
|
||||
shift 'U' Redo
|
||||
- 'u' Undo
|
||||
- 'v' Constrained vertical move/copy of objects
|
||||
|
|
|
|||
125
src/move.c
125
src/move.c
|
|
@ -378,25 +378,25 @@ void draw_selection(GC g, int interruptable)
|
|||
if(xctx->wire[n].sel==SELECTED)
|
||||
{
|
||||
if(xctx->wire[n].bus)
|
||||
drawtempline(g, THICK, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay,
|
||||
drawtemp_manhattanline(g, THICK, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay,
|
||||
xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay);
|
||||
else
|
||||
drawtempline(g, ADD, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay,
|
||||
drawtemp_manhattanline(g, ADD, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay,
|
||||
xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay);
|
||||
}
|
||||
else if(xctx->wire[n].sel==SELECTED1)
|
||||
{
|
||||
if(xctx->wire[n].bus)
|
||||
drawtempline(g, THICK, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, xctx->rx2, xctx->ry2);
|
||||
drawtemp_manhattanline(g, THICK, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, xctx->rx2, xctx->ry2);
|
||||
else
|
||||
drawtempline(g, ADD, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, xctx->rx2, xctx->ry2);
|
||||
drawtemp_manhattanline(g, ADD, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, xctx->rx2, xctx->ry2);
|
||||
}
|
||||
else if(xctx->wire[n].sel==SELECTED2)
|
||||
{
|
||||
if(xctx->wire[n].bus)
|
||||
drawtempline(g, THICK, xctx->rx1, xctx->ry1, xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay);
|
||||
drawtemp_manhattanline(g, THICK, xctx->rx1, xctx->ry1, xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay);
|
||||
else
|
||||
drawtempline(g, ADD, xctx->rx1, xctx->ry1, xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay);
|
||||
drawtemp_manhattanline(g, ADD, xctx->rx1, xctx->ry1, xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay);
|
||||
}
|
||||
break;
|
||||
case LINE:
|
||||
|
|
@ -513,6 +513,82 @@ void draw_selection(GC g, int interruptable)
|
|||
xctx->movelastsel = i;
|
||||
}
|
||||
|
||||
/* sel: if set to 1 change references only on selected items, like in a copy operation.
|
||||
* If set to 0 operate on all objects with matching name=... attribute */
|
||||
void update_attached_floaters(const char *from_name, int inst, int sel)
|
||||
{
|
||||
int i, c;
|
||||
char *to_name = xctx->inst[inst].instname;
|
||||
const char *attach = get_tok_value(xctx->inst[inst].prop_ptr, "attach", 0);
|
||||
char *new_attach;
|
||||
|
||||
if(!from_name || !from_name[0]) return;
|
||||
if(!to_name || !to_name[0]) return;
|
||||
if(!attach[0]) return;
|
||||
|
||||
new_attach = str_replace(attach, from_name, to_name, 1, 1);
|
||||
my_strdup(_ALLOC_ID_, &xctx->inst[inst].prop_ptr,
|
||||
subst_token(xctx->inst[inst].prop_ptr, "attach", new_attach) );
|
||||
|
||||
for(c = 0; c < cadlayers; c++) {
|
||||
for(i = 0; i < xctx->rects[c]; i++) {
|
||||
if(!sel || xctx->rect[c][i].sel == SELECTED) {
|
||||
if( !strcmp(from_name, get_tok_value(xctx->rect[c][i].prop_ptr, "name", 0))) {
|
||||
my_strdup(_ALLOC_ID_, &xctx->rect[c][i].prop_ptr,
|
||||
subst_token(xctx->rect[c][i].prop_ptr, "name", to_name) );
|
||||
}
|
||||
if(c == GRIDLAYER) {
|
||||
const char *node = get_tok_value(xctx->rect[c][i].prop_ptr, "node", 2);
|
||||
if(node && node[0]) {
|
||||
const char *new_node = str_replace(node, from_name, to_name, 1, -1);
|
||||
my_strdup(_ALLOC_ID_, &xctx->rect[c][i].prop_ptr,
|
||||
subst_token(xctx->rect[c][i].prop_ptr, "node", new_node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->lines[c]; i++) {
|
||||
if((!sel || xctx->line[c][i].sel == SELECTED) &&
|
||||
!strcmp(from_name, get_tok_value(xctx->line[c][i].prop_ptr, "name", 0))) {
|
||||
my_strdup(_ALLOC_ID_, &xctx->line[c][i].prop_ptr,
|
||||
subst_token(xctx->line[c][i].prop_ptr, "name", to_name) );
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < xctx->polygons[c]; i++) {
|
||||
if((!sel || xctx->poly[c][i].sel == SELECTED) &&
|
||||
!strcmp(from_name, get_tok_value(xctx->poly[c][i].prop_ptr, "name", 0))) {
|
||||
my_strdup(_ALLOC_ID_, &xctx->poly[c][i].prop_ptr,
|
||||
subst_token(xctx->poly[c][i].prop_ptr, "name", to_name) );
|
||||
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->arcs[c]; i++) {
|
||||
if((!sel || xctx->arc[c][i].sel == SELECTED) &&
|
||||
!strcmp(from_name, get_tok_value(xctx->arc[c][i].prop_ptr, "name", 0))) {
|
||||
my_strdup(_ALLOC_ID_, &xctx->arc[c][i].prop_ptr,
|
||||
subst_token(xctx->arc[c][i].prop_ptr, "name", to_name) );
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->wires; i++) {
|
||||
if((!sel || xctx->wire[i].sel == SELECTED) &&
|
||||
!strcmp(from_name, get_tok_value(xctx->wire[i].prop_ptr, "name", 0))) {
|
||||
my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr,
|
||||
subst_token(xctx->wire[i].prop_ptr, "name", to_name) );
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->texts; i++) {
|
||||
if((!sel || xctx->text[i].sel == SELECTED) &&
|
||||
!strcmp(from_name, get_tok_value(xctx->text[i].prop_ptr, "name", 0))) {
|
||||
my_strdup(_ALLOC_ID_, &xctx->text[i].prop_ptr,
|
||||
subst_token(xctx->text[i].prop_ptr, "name", to_name) );
|
||||
set_text_flags(&xctx->text[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void copy_objects(int what)
|
||||
{
|
||||
int tmpi, c, i, n, k /*, tmp */ ;
|
||||
|
|
@ -881,6 +957,9 @@ void copy_objects(int what)
|
|||
newpropcnt++;
|
||||
new_prop_string(xctx->instances, xctx->inst[n].prop_ptr, /* sets also inst[].instname */
|
||||
tclgetboolvar("disable_unique_names"));
|
||||
|
||||
update_attached_floaters(xctx->inst[n].instname, xctx->instances, 1);
|
||||
|
||||
hash_names(xctx->instances, XINSERT);
|
||||
xctx->instances++; /* symbol_bbox calls translate and translate must have updated xctx->instances */
|
||||
symbol_bbox(xctx->instances-1,
|
||||
|
|
@ -1056,10 +1135,36 @@ void move_objects(int what, int merge, double dx, double dy)
|
|||
if(wire[n].sel == SELECTED1) wire[n].sel = SELECTED2;
|
||||
else if(wire[n].sel == SELECTED2) wire[n].sel = SELECTED1;
|
||||
}
|
||||
wire[n].x1=xctx->rx1;
|
||||
wire[n].y1=xctx->ry1;
|
||||
wire[n].x2=xctx->rx2;
|
||||
wire[n].y2=xctx->ry2;
|
||||
|
||||
if(wire[n].sel & (SELECTED|SELECTED1))
|
||||
{
|
||||
if(xctx->manhattan_lines & 1) xctx->manhattan_lines=2;
|
||||
else if(xctx->manhattan_lines & 2) xctx->manhattan_lines=1;
|
||||
}
|
||||
wire[n].x1 = xctx->rx1;
|
||||
wire[n].y1 = xctx->ry1;
|
||||
if(xctx->manhattan_lines&1)
|
||||
{
|
||||
wire[n].x2 = xctx->rx2;
|
||||
wire[n].y2 = xctx->ry1;
|
||||
storeobject(-1, xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2,WIRE,0,0,NULL);
|
||||
hash_wire(XINSERT, xctx->wires-1, 1);
|
||||
drawline(WIRELAYER,ADD, xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2, 0, NULL);
|
||||
}
|
||||
else if(xctx->manhattan_lines&2)
|
||||
{
|
||||
wire[n].x2 = xctx->rx1;
|
||||
wire[n].y2 = xctx->ry2;
|
||||
storeobject(-1, xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2,WIRE,0,0,NULL);
|
||||
hash_wire(XINSERT, xctx->wires-1, 1);
|
||||
drawline(WIRELAYER,ADD, xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
wire[n].x2 = xctx->rx2;
|
||||
wire[n].y2 = xctx->ry2;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -678,7 +678,7 @@ static void print_wires(void)
|
|||
ptr=xctx->wire_spatial_table[0][1];
|
||||
while(ptr)
|
||||
{
|
||||
select_wire(ptr->n,SELECTED, 1);
|
||||
select_wire(ptr->n,SELECTED, 1, 1);
|
||||
rebuild_selected_array();
|
||||
ptr=ptr->next;
|
||||
}
|
||||
|
|
|
|||
10
src/paste.c
10
src/paste.c
|
|
@ -48,7 +48,7 @@ static void merge_text(FILE *fd)
|
|||
xctx->text[i].sel=0;
|
||||
load_ascii_string(&xctx->text[i].prop_ptr,fd);
|
||||
set_text_flags(&xctx->text[i]);
|
||||
select_text(i,SELECTED, 1);
|
||||
select_text(i,SELECTED, 1, 1);
|
||||
xctx->texts++;
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ static void merge_wire(FILE *fd)
|
|||
load_ascii_string( &ptr, fd);
|
||||
storeobject(-1, x1,y1,x2,y2,WIRE,0,SELECTED,ptr);
|
||||
my_free(_ALLOC_ID_, &ptr);
|
||||
select_wire(i, SELECTED, 1);
|
||||
select_wire(i, SELECTED, 1, 1);
|
||||
}
|
||||
|
||||
static void merge_box(FILE *fd)
|
||||
|
|
@ -172,7 +172,7 @@ static void merge_arc(FILE *fd)
|
|||
ptr[i].dash = 0;
|
||||
}
|
||||
|
||||
select_arc(c,i, SELECTED, 1);
|
||||
select_arc(c,i, SELECTED, 1, 1);
|
||||
xctx->arcs[c]++;
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +232,7 @@ static void merge_polygon(FILE *fd)
|
|||
ptr[i].dash = 0;
|
||||
}
|
||||
|
||||
select_polygon(c,i, SELECTED, 1);
|
||||
select_polygon(c,i, SELECTED, 1, 1);
|
||||
xctx->polygons[c]++;
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ static void merge_line(FILE *fd)
|
|||
ptr[i].bus = 1;
|
||||
else
|
||||
ptr[i].bus = 0;
|
||||
select_line(c,i, SELECTED, 1);
|
||||
select_line(c,i, SELECTED, 1, 1);
|
||||
xctx->lines[c]++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,8 +250,9 @@ static int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
|
||||
static int ps_embedded_graph(int i, double rx1, double ry1, double rx2, double ry2)
|
||||
{
|
||||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||
#if defined(HAS_LIBJPEG) && HAS_CAIRO==1
|
||||
Zoom_info zi;
|
||||
double rw, rh, scale;
|
||||
|
|
@ -269,7 +270,7 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
|
|||
int quality=40;
|
||||
const char *quality_attr;
|
||||
size_t oLength;
|
||||
int i;
|
||||
int j;
|
||||
double sx1, sy1, sx2, sy2;
|
||||
|
||||
/* screen position */
|
||||
|
|
@ -323,7 +324,9 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
|
|||
d_c = tclgetboolvar("dark_colorscheme");
|
||||
tclsetboolvar("dark_colorscheme", 0);
|
||||
build_colors(0, 0);
|
||||
draw();
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, NULL);
|
||||
|
||||
dbg(1, "width=%d, rwi=%d height=%d rhi=%d\n", xctx->xrect[0].width, rwi, xctx->xrect[0].height, rhi);
|
||||
#ifdef __unix__
|
||||
png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual,
|
||||
|
|
@ -337,13 +340,8 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
|
|||
cairo_set_source_surface(ct, xctx->cairo_save_sfc, 0, 0);
|
||||
cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint(ct);
|
||||
for (i = 0; i < xctx->rects[GRIDLAYER]; ++i) {
|
||||
xRect* r2 = &xctx->rect[GRIDLAYER][i];
|
||||
if (r2->flags & 1) {
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
|
||||
}
|
||||
}
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
|
||||
#endif
|
||||
cairo_image_surface_write_to_jpeg_mem(png_sfc, &jpgData, &fileSize, quality);
|
||||
|
||||
|
|
@ -382,10 +380,10 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
|
|||
fprintf(fd, "} exec\n");
|
||||
|
||||
#if 1 /* break lines */
|
||||
for (i = 0; i < oLength; ++i)
|
||||
for (j = 0; j < oLength; ++j)
|
||||
{
|
||||
fputc(ascii85EncodedJpeg[i],fd);
|
||||
if(i > 0 && (i % 64) == 0)
|
||||
fputc(ascii85EncodedJpeg[j],fd);
|
||||
if(j > 0 && (j % 64) == 0)
|
||||
{
|
||||
fputc('\n',fd);
|
||||
/* if (ascii85Encode[i+1]=='%') idx=63; imageMagic does this for some reason?!
|
||||
|
|
@ -1449,8 +1447,8 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
|
|||
continue;
|
||||
}
|
||||
if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */
|
||||
xRect* r = &xctx->rect[c][i];
|
||||
ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2);
|
||||
xRect *r = &xctx->rect[c][i];
|
||||
ps_embedded_graph(i, r->x1, r->y1, r->x2, r->y2);
|
||||
}
|
||||
if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) {
|
||||
ps_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
|
||||
|
|
|
|||
47
src/save.c
47
src/save.c
|
|
@ -1014,17 +1014,16 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
|
|||
return res;
|
||||
}
|
||||
dbg(1, "raw_read(): type=%s\n", type ? type : "<NULL>");
|
||||
*rawptr = my_calloc(_ALLOC_ID_, 1, sizeof(Raw));
|
||||
raw = *rawptr;
|
||||
raw->level = -1;
|
||||
raw->annot_p = -1;
|
||||
raw->sweep1 = sweep1;
|
||||
raw->sweep2 = sweep2;
|
||||
raw->annot_sweep_idx = -1;
|
||||
|
||||
int_hash_init(&raw->table, HASHSIZE);
|
||||
fd = my_fopen(f, fopen_read_mode);
|
||||
if(fd) {
|
||||
*rawptr = my_calloc(_ALLOC_ID_, 1, sizeof(Raw));
|
||||
raw = *rawptr;
|
||||
raw->level = -1;
|
||||
raw->annot_p = -1;
|
||||
raw->sweep1 = sweep1;
|
||||
raw->sweep2 = sweep2;
|
||||
raw->annot_sweep_idx = -1;
|
||||
int_hash_init(&raw->table, HASHSIZE);
|
||||
if((res = read_dataset(fd, rawptr, type, no_warning)) == 1) {
|
||||
int i;
|
||||
set_modify(-2); /* clear text floater caches */
|
||||
|
|
@ -1044,12 +1043,13 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
|
|||
xRect *r;
|
||||
r = &xctx->rect[GRIDLAYER][0];
|
||||
if(r->flags & 1) {
|
||||
setup_graph_data(0, 0, &xctx->graph_struct);
|
||||
backannotate_at_cursor_b_pos(r, &xctx->graph_struct);
|
||||
/* don't overwrite xctx->graph_struct, being used in draw_graph() which calls raw_read() */
|
||||
Graph_ctx gr_ctx;
|
||||
setup_graph_data(0, 0, &gr_ctx);
|
||||
backannotate_at_cursor_b_pos(r, &gr_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* free_rawfile(rawptr, 0, 0); */ /* do not free: already done in read_dataset()->extra_rawfile() */
|
||||
if(!no_warning) {
|
||||
|
|
@ -1074,6 +1074,22 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
|
|||
return 0;
|
||||
}
|
||||
|
||||
int raw_renamevar(const char *old_name, const char *new_name)
|
||||
{
|
||||
int n, ret = 0;
|
||||
Raw *raw = xctx->raw;
|
||||
Int_hashentry *entry;
|
||||
|
||||
n = get_raw_index(old_name, &entry);
|
||||
if(n < 0) return ret;
|
||||
dbg(1, "n=%d, %s \n", n, entry->token);
|
||||
int_hash_lookup(&raw->table, entry->token, 0, XDELETE);
|
||||
my_strdup2(_ALLOC_ID_, &raw->names[n], new_name);
|
||||
int_hash_lookup(&raw->table, raw->names[n], n, XINSERT); /* update hash table */
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int raw_deletevar(const char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -1206,6 +1222,7 @@ int extra_rawfile(int what, const char *file, const char *type, double sweep1, d
|
|||
if(what == 0) return 0;
|
||||
/* if not already done insert base raw file (if there is one) into xctx->extra_raw_arr[0] */
|
||||
if(xctx->raw && xctx->extra_raw_n == 0) {
|
||||
dbg(1, "insert extra_raw_arr[0]\n");
|
||||
xctx->extra_raw_arr[xctx->extra_raw_n] = xctx->raw;
|
||||
xctx->extra_raw_n++;
|
||||
}
|
||||
|
|
@ -1277,7 +1294,8 @@ int extra_rawfile(int what, const char *file, const char *type, double sweep1, d
|
|||
if(!no_warning) {
|
||||
dbg(0, "extra_rawfile() read: %s not found or no \"%s\" analysis\n", f, type ? type : "<unspecified>");
|
||||
}
|
||||
if(xctx->extra_raw_n) { /* only restore if raw wiles were not deleted due to a failure in read_raw() */
|
||||
if(xctx->extra_raw_n) { /* only restore if raw files were not deleted due to a failure in read_raw() */
|
||||
dbg(1, "extra_rawfile(): read: restore previous, extra_idx=%d\n", xctx->extra_idx);
|
||||
xctx->raw = save; /* restore */
|
||||
xctx->extra_prev_idx = xctx->extra_idx;
|
||||
}
|
||||
|
|
@ -2783,7 +2801,8 @@ static void load_inst(int k, FILE *fd)
|
|||
if(name[0] == '/') my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, rel_sym_path(name));
|
||||
else my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, name);
|
||||
#else
|
||||
my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, rel_sym_path(name));
|
||||
if(isupper(name[0]) && name[1] == ':' && name[1] == '/') my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, rel_sym_path(name));
|
||||
else my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, name);
|
||||
#endif
|
||||
my_free(_ALLOC_ID_, &tmp);
|
||||
if(fscanf(fd, "%lf %lf %hd %hd", &xctx->inst[i].x0, &xctx->inst[i].y0,
|
||||
|
|
|
|||
318
src/scheduler.c
318
src/scheduler.c
|
|
@ -1725,6 +1725,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_SetResult(interp, top_path,TCL_VOLATILE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if(!strcmp(argv[2], "ui_state")) { /* return UI state */
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
Tcl_SetResult(interp, my_itoa(xctx->ui_state), TCL_VOLATILE);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
if(!strcmp(argv[2], "version")) { /* return xschem version */
|
||||
Tcl_SetResult(interp, XSCHEM_VERSION, TCL_VOLATILE);
|
||||
|
|
@ -1798,8 +1804,34 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_SetResult(interp, (char *)get_cell_w_ext(argv[2], atoi(argv[3])), TCL_VOLATILE);
|
||||
}
|
||||
}
|
||||
|
||||
/************ end xschem get subcommands *************/
|
||||
|
||||
|
||||
/* get_fqdevice instname param modelparam
|
||||
* get the full pathname of "instname" device
|
||||
* modelparam:
|
||||
* 0: current, 1: modelparam, 2: modelvoltage
|
||||
* param: device parameter, like ib, gm, vth
|
||||
* set param to {} (empty str) for just branch current of 2 terminal device
|
||||
* for parameters like "vth" modelparam must be 2
|
||||
* for parameters like "ib" modelparam must be 0
|
||||
* for parameters like "gm" modelparam must be 1
|
||||
*/
|
||||
else if(!strcmp(argv[1], "get_fqdevice"))
|
||||
{
|
||||
char *fqdev;
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
if(argc > 4) {
|
||||
fqdev = get_fqdevice(argv[3], atoi(argv[4]), argv[2]);
|
||||
Tcl_SetResult(interp, fqdev, TCL_VOLATILE);
|
||||
my_free(_ALLOC_ID_, &fqdev);
|
||||
} else if(argc > 2) {
|
||||
fqdev = get_fqdevice("", 0, argv[2]);
|
||||
Tcl_SetResult(interp, fqdev, TCL_VOLATILE);
|
||||
my_free(_ALLOC_ID_, &fqdev);
|
||||
}
|
||||
}
|
||||
|
||||
/* getprop instance|instance_pin|symbol|text ref
|
||||
*
|
||||
* getprop instance inst
|
||||
|
|
@ -2103,6 +2135,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
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), "drag_elements=%d\n", xctx->drag_elements); 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);
|
||||
|
|
@ -2760,13 +2793,17 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
break;
|
||||
case 'l': /*----------------------------------------------*/
|
||||
/* line [x1 y1 x2 y2] [pos] [propstring] [draw]
|
||||
* line
|
||||
* line gui
|
||||
* if 'x1 y1 x2 y2'is given place line on current
|
||||
* layer (rectcolor) at indicated coordinates.
|
||||
* if 'pos' is given insert at given position in rectangle array.
|
||||
* if 'pos' is given insert at given position in line array.
|
||||
* if 'pos' set to -1 append to last element in line array.
|
||||
* 'propstring' is the attribute string. Set to empty if not given.
|
||||
* if 'draw' is set to 1 (default) draw the new object, else don't
|
||||
* If no coordinates are given start a GUI operation of line placement */
|
||||
* If no coordinates are given start a GUI operation of line placement
|
||||
* if `gui` argument is given start a line GUI placement with 1st point
|
||||
* set to current mouse coordinates */
|
||||
if(!strcmp(argv[1], "line"))
|
||||
{
|
||||
double x1,y1,x2,y2;
|
||||
|
|
@ -2792,6 +2829,21 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
}
|
||||
set_modify(1);
|
||||
}
|
||||
else if(argc == 3 && !strcmp(argv[2], "gui")) {
|
||||
int prev_state = xctx->ui_state;
|
||||
int infix_interface = tclgetboolvar("infix_interface");
|
||||
if(infix_interface) {
|
||||
start_line(xctx->mousex_snap, xctx->mousey_snap);
|
||||
if(prev_state == STARTLINE) {
|
||||
tcleval("set constr_mv 0" );
|
||||
xctx->constr_mv=0;
|
||||
}
|
||||
} else {
|
||||
xctx->last_command = 0;
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTLINE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
xctx->last_command = 0;
|
||||
xctx->ui_state |= MENUSTART;
|
||||
|
|
@ -2888,11 +2940,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else if(!strcmp(argv[1], "load") )
|
||||
{
|
||||
int load_symbols = 1, force = 1, undo_reset = 1, nofullzoom = 0, nodraw = 0;
|
||||
int keep_symbols = 0;
|
||||
size_t i;
|
||||
int keep_symbols = 0, first;
|
||||
int i;
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
|
||||
|
||||
for(i = 2; i < argc; i++) {
|
||||
if(argv[i][0] == '-') {
|
||||
if(!strcmp(argv[i], "-nosymbols")) {
|
||||
|
|
@ -2912,8 +2963,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc>i) {
|
||||
first = i;
|
||||
if(argc==2) {
|
||||
ask_new_file();
|
||||
tcleval("load_additional_files");
|
||||
} else
|
||||
for(i = first; i < argc; i++) {
|
||||
char f[PATH_MAX + 100];
|
||||
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[i], home_dir);
|
||||
tcleval(f);
|
||||
|
|
@ -2940,34 +2995,41 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
unselect_all(1);
|
||||
/* no implicit undo: if needed do it before loading */
|
||||
/* if(!undo_reset) xctx->push_undo(); */
|
||||
if(undo_reset) xctx->currsch = 0;
|
||||
if(!keep_symbols) remove_symbols();
|
||||
if(!nofullzoom) {
|
||||
xctx->zoom=CADINITIALZOOM;
|
||||
xctx->mooz=1/CADINITIALZOOM;
|
||||
xctx->xorigin=CADINITIALX;
|
||||
xctx->yorigin=CADINITIALY;
|
||||
if(i == first) {
|
||||
if(undo_reset) xctx->currsch = 0;
|
||||
if(!keep_symbols) remove_symbols();
|
||||
if(!nofullzoom) {
|
||||
xctx->zoom=CADINITIALZOOM;
|
||||
xctx->mooz=1/CADINITIALZOOM;
|
||||
xctx->xorigin=CADINITIALX;
|
||||
xctx->yorigin=CADINITIALY;
|
||||
}
|
||||
}
|
||||
dbg(1, "scheduler: undo_reset=%d\n", undo_reset);
|
||||
ret = load_schematic(load_symbols, f, undo_reset, !force);
|
||||
dbg(1, "xschem load: ret=%d\n", ret);
|
||||
if(undo_reset) {
|
||||
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(i > first) {
|
||||
ret = new_schematic("create", "noconfirm", f, 1);
|
||||
if(undo_reset) {
|
||||
tclvareval("update_recent_file {", f, "}", NULL);
|
||||
}
|
||||
} else {
|
||||
ret = load_schematic(load_symbols, f, undo_reset, !force);
|
||||
dbg(1, "xschem load: f=%s, ret=%d\n", f, ret);
|
||||
if(undo_reset) {
|
||||
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) {
|
||||
if(!nodraw) 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(argc==2) {
|
||||
ask_new_file();
|
||||
}
|
||||
Tcl_SetResult(interp, xctx->sch[xctx->currsch], TCL_STATIC);
|
||||
}
|
||||
|
||||
|
|
@ -2980,13 +3042,32 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int cancel = 0;
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
if(argc > 2) {
|
||||
if(!is_from_web(argv[2])) {
|
||||
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[2], home_dir);
|
||||
tcleval(f);
|
||||
/* tclvareval("file normalize {", tclresult(), "}", NULL); */
|
||||
my_strncpy(f, abs_sym_path(tclresult(), ""), S(f));
|
||||
} else {
|
||||
my_strncpy(f, argv[2], S(f));
|
||||
int i;
|
||||
for(i = 2; i < argc; i++) {
|
||||
if(!is_from_web(argv[i])) {
|
||||
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[i], home_dir);
|
||||
tcleval(f);
|
||||
/* tclvareval("file normalize {", tclresult(), "}", NULL); */
|
||||
my_strncpy(f, abs_sym_path(tclresult(), ""), S(f));
|
||||
} else {
|
||||
my_strncpy(f, argv[i], S(f));
|
||||
}
|
||||
if(f[0]) {
|
||||
char win_path[WINDOW_PATH_SIZE];
|
||||
dbg(1, "f=%s\n", f);
|
||||
if(check_loaded(f, win_path)) {
|
||||
char msg[PATH_MAX + 100];
|
||||
my_snprintf(msg, S(msg),
|
||||
"tk_messageBox -type okcancel -icon warning -parent [xschem get topwindow] "
|
||||
"-message {Warning: %s already open.}", f);
|
||||
tcleval(msg);
|
||||
if(strcmp(tclresult(), "ok")) continue;
|
||||
}
|
||||
new_schematic("create", "noconfirm", f, 1);
|
||||
tclvareval("update_recent_file {", f, "}", NULL);
|
||||
} else {
|
||||
new_schematic("create", NULL, NULL, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tcleval("load_file_dialog {Load file} *.\\{sch,sym,tcl\\} INITIALLOADDIR");
|
||||
|
|
@ -2995,14 +3076,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
} else {
|
||||
cancel = 1;
|
||||
}
|
||||
}
|
||||
if(!cancel) {
|
||||
if(f[0]) {
|
||||
dbg(1, "f=%s\n", f);
|
||||
new_schematic("create", "noconfirm", f, 1);
|
||||
tclvareval("update_recent_file {", f, "}", NULL);
|
||||
} else {
|
||||
new_schematic("create", NULL, NULL, 1);
|
||||
if(!cancel) {
|
||||
if(f[0]) {
|
||||
dbg(1, "f=%s\n", f);
|
||||
new_schematic("create", "noconfirm", f, 1);
|
||||
tclvareval("update_recent_file {", f, "}", NULL);
|
||||
} else {
|
||||
new_schematic("create", NULL, NULL, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
|
|
@ -3604,7 +3685,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
tclvareval("set INITIALINSTDIR [file dirname {",
|
||||
abs_sym_path(tcl_hook2(xctx->inst[xctx->sel_array[0].n].name), ""), "}]", NULL);
|
||||
}
|
||||
unselect_all(1);
|
||||
xctx->mx_double_save = xctx->mousex_snap;
|
||||
xctx->my_double_save = xctx->mousey_snap;
|
||||
if(argc > 3) {
|
||||
|
|
@ -3646,13 +3726,28 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
/* polygon
|
||||
* Start a GUI placement of a polygon */
|
||||
/* polygon [gui]
|
||||
* Start a GUI placement of a polygon
|
||||
* if `gui` argument is given start a polygon GUI placement with 1st point
|
||||
* set to current mouse coordinates */
|
||||
else if(!strcmp(argv[1], "polygon"))
|
||||
{
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTPOLYGON;
|
||||
if(argc > 2 && !strcmp(argv[2], "gui")) {
|
||||
int infix_interface = tclgetboolvar("infix_interface");
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
xctx->last_command = 0;
|
||||
new_polygon(PLACE, xctx->mousex_snap, xctx->mousey_snap);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTPOLYGON;
|
||||
}
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTPOLYGON;
|
||||
}
|
||||
}
|
||||
|
||||
/* preview_window create|draw|destroy|close [win_path] [file]
|
||||
|
|
@ -3969,8 +4064,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
case 'r': /*----------------------------------------------*/
|
||||
|
||||
/* raw what ...
|
||||
* what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
|
||||
* read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
|
||||
* what = add | clear | datasets | index | info | loaded | list |
|
||||
* new | points | rawfile | del | read | set | rename |
|
||||
* sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
|
||||
*
|
||||
* xschem raw read filename [type [sweep1 sweep2]]
|
||||
* if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
|
||||
|
|
@ -3985,6 +4081,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
* xschem raw del name
|
||||
* delete named vector from current raw file
|
||||
*
|
||||
* xschem raw rename old_name new_name
|
||||
* rename a node in the loaded raw file.
|
||||
*
|
||||
* xschem raw info
|
||||
* print information about loaded raw files and show the currently active one.
|
||||
*
|
||||
|
|
@ -4061,7 +4160,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
* new dataset do not start with a header row.
|
||||
* Lines beginning with '#' are comments and ignored
|
||||
*
|
||||
* time var_a var_b var_c
|
||||
* time var_a var_b var_cnode in the loaded raw file.
|
||||
* # this is a comment, ignored
|
||||
* 0.0 0.0 1.8 0.3
|
||||
* <single empty line: ignored>
|
||||
|
|
@ -4129,9 +4228,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
update_op();
|
||||
}
|
||||
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
|
||||
} else if(argc > 3 && !strcmp(argv[2], "del")) {
|
||||
ret = raw_deletevar(argv[3]);
|
||||
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
|
||||
} else if(argc > 2 && !strcmp(argv[2], "clear")) {
|
||||
if(argc > 4) {
|
||||
ret = extra_rawfile(3, argv[3], argv[4], -1.0, -1.0);
|
||||
|
|
@ -4164,6 +4260,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_SetResult(interp, dtoa(val), TCL_VOLATILE);
|
||||
}
|
||||
}
|
||||
} else if(argc > 3 && !strcmp(argv[2], "del")) {
|
||||
ret = raw_deletevar(argv[3]);
|
||||
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
|
||||
} else if(argc > 4 && !strcmp(argv[2], "rename")) {
|
||||
ret = raw_renamevar(argv[3], argv[4]);
|
||||
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
|
||||
} else if(argc > 3 && !strcmp(argv[2], "index")) {
|
||||
/* xschem raw index v(ldcp) */
|
||||
int idx;
|
||||
|
|
@ -4372,7 +4474,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
}
|
||||
|
||||
/* rebuild_connectivity
|
||||
Rebuild logical connectivity abstraction of schematic */
|
||||
* Rebuild logical connectivity abstraction of schematic */
|
||||
else if(!strcmp(argv[1], "rebuild_connectivity"))
|
||||
{
|
||||
int err = 0;
|
||||
|
|
@ -4411,14 +4513,19 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
|
||||
}
|
||||
|
||||
/* rect [x1 y1 x2 y2] [pos] [propstring] [draw]
|
||||
* if 'x1 y1 x2 y2'is given place recangle on current
|
||||
* layer (rectcolor) at indicated coordinates.
|
||||
* if 'pos' is given insert at given position in rectangle array.
|
||||
* if 'pos' set to -1 append rectangle to last element in rectangle array.
|
||||
* 'propstring' is the attribute string. Set to empty if not given.
|
||||
* if 'draw' is set to 1 (default) draw the new object, else don't
|
||||
* If no coordinates are given start a GUI operation of rectangle placement */
|
||||
/* rect ...
|
||||
* rect [x1 y1 x2 y2] [pos] [propstring] [draw]
|
||||
* if 'x1 y1 x2 y2'is given place recangle on current
|
||||
* layer (rectcolor) at indicated coordinates.
|
||||
* if 'pos' is given insert at given position in rectangle array.
|
||||
* if 'pos' set to -1 append rectangle to last element in rectangle array.
|
||||
* 'propstring' is the attribute string. Set to empty if not given.
|
||||
* if 'draw' is set to 1 (default) draw the new object, else don't
|
||||
* rect
|
||||
* If no coordinates are given start a GUI operation of rectangle placement
|
||||
* rect gui
|
||||
* if `gui` argument is given start a GUI placement of a rectangle with 1st
|
||||
* point starting from current mouse coordinates */
|
||||
else if(!strcmp(argv[1], "rect"))
|
||||
{
|
||||
double x1,y1,x2,y2;
|
||||
|
|
@ -4448,8 +4555,18 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
xctx->draw_window = save;
|
||||
}
|
||||
set_modify(1);
|
||||
}
|
||||
else {
|
||||
} else if(argc > 2 && !strcmp(argv[2], "gui")) {
|
||||
int infix_interface = tclgetboolvar("infix_interface");
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
xctx->last_command = 0;
|
||||
new_rect(PLACE,xctx->mousex_snap, xctx->mousey_snap);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTRECT;
|
||||
}
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTRECT;
|
||||
}
|
||||
|
|
@ -4960,7 +5077,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int n=atoi(argv[3]);
|
||||
int valid = n < xctx->wires && n >= 0;
|
||||
if(valid) {
|
||||
select_wire(n, sel, fast);
|
||||
select_wire(n, sel, fast, 1);
|
||||
xctx->ui_state |= SELECTION;
|
||||
}
|
||||
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
|
||||
|
|
@ -4970,7 +5087,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int n=atoi(argv[4]);
|
||||
int valid = n < xctx->lines[c] && n >= 0 && c < cadlayers && c >= 0;
|
||||
if(valid) {
|
||||
select_line(c, n, sel, fast);
|
||||
select_line(c, n, sel, fast, 0);
|
||||
xctx->ui_state |= SELECTION;
|
||||
}
|
||||
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
|
||||
|
|
@ -4990,7 +5107,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int n=atoi(argv[4]);
|
||||
int valid = n < xctx->arcs[c] && n >= 0 && c < cadlayers && c >= 0;
|
||||
if(valid) {
|
||||
select_arc(c, n, sel, fast);
|
||||
select_arc(c, n, sel, fast, 0);
|
||||
xctx->ui_state |= SELECTION;
|
||||
}
|
||||
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
|
||||
|
|
@ -5000,7 +5117,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int n=atoi(argv[4]);
|
||||
int valid = n < xctx->polygons[c] && n >= 0 && c < cadlayers && c >= 0;
|
||||
if(valid) {
|
||||
select_polygon(c, n, sel, fast);
|
||||
select_polygon(c, n, sel, fast, 0);
|
||||
xctx->ui_state |= SELECTION;
|
||||
}
|
||||
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
|
||||
|
|
@ -5009,7 +5126,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int n=atoi(argv[3]);
|
||||
int valid = n < xctx->texts && n >= 0;
|
||||
if(valid) {
|
||||
select_text(n, sel, fast);
|
||||
select_text(n, sel, fast, 0);
|
||||
xctx->ui_state |= SELECTION;
|
||||
}
|
||||
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
|
||||
|
|
@ -5461,7 +5578,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
} else {
|
||||
char *translated_sym = NULL;
|
||||
int sym_number = -1;
|
||||
char *subst = NULL;
|
||||
char *subst = NULL, *old_name = NULL;;
|
||||
|
||||
if(!fast) {
|
||||
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
|
||||
xctx->push_undo();
|
||||
|
|
@ -5469,7 +5587,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
xctx->prep_hash_inst=0;
|
||||
xctx->prep_net_structs=0;
|
||||
xctx->prep_hi_structs=0;
|
||||
if(argc > 4 && !strcmp(argv[4], "name") && fast == 0) hash_names(-1, XINSERT);
|
||||
if(argc > 4 && !strcmp(argv[4], "name")) {
|
||||
if(fast == 0) {
|
||||
hash_names(-1, XINSERT);
|
||||
}
|
||||
my_strdup2(_ALLOC_ID_, &old_name, xctx->inst[inst].instname);
|
||||
}
|
||||
if(argc > 5) {
|
||||
if(!strcmp(argv[4], "allprops")) {
|
||||
hash_names(-1, XINSERT);
|
||||
|
|
@ -5486,7 +5609,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
}
|
||||
hash_names(inst, XDELETE);
|
||||
new_prop_string(inst, subst, tclgetboolvar("disable_unique_names"));
|
||||
|
||||
if(old_name) {
|
||||
update_attached_floaters(old_name, inst, 0);
|
||||
}
|
||||
my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name));
|
||||
sym_number=match_symbol(translated_sym);
|
||||
|
||||
|
|
@ -5495,6 +5620,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
xctx->inst[inst].ptr=sym_number;
|
||||
}
|
||||
if(subst) my_free(_ALLOC_ID_, &subst);
|
||||
if(old_name) my_free(_ALLOC_ID_, &old_name);
|
||||
set_inst_flags(&xctx->inst[inst]);
|
||||
hash_names(inst, XINSERT);
|
||||
if(!fast) {
|
||||
|
|
@ -5927,22 +6053,22 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
select_element(n, SELECTED, 1, 1);
|
||||
break;
|
||||
case WIRE:
|
||||
select_wire(n, SELECTED, 1);
|
||||
select_wire(n, SELECTED, 1, 1);
|
||||
break;
|
||||
case xTEXT:
|
||||
select_text(n, SELECTED, 1);
|
||||
select_text(n, SELECTED, 1, 1);
|
||||
break;
|
||||
case xRECT:
|
||||
select_box(c, n, SELECTED, 1, 0);
|
||||
select_box(c, n, SELECTED, 1, 1);
|
||||
break;
|
||||
case LINE:
|
||||
select_line(c, n, SELECTED, 1);
|
||||
select_line(c, n, SELECTED, 1, 1);
|
||||
break;
|
||||
case POLYGON:
|
||||
select_polygon(c, n, SELECTED, 1);
|
||||
select_polygon(c, n, SELECTED, 1, 1);
|
||||
break;
|
||||
case ARC:
|
||||
select_arc(c, n, SELECTED, 1);
|
||||
select_arc(c, n, SELECTED, 1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -6215,6 +6341,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
/* unselect_attached_floaters
|
||||
* Unselect objects (not symbol instances) attached to some instance with a
|
||||
* non empty name=... attribute */
|
||||
else if(!strcmp(argv[1], "unselect_attached_floaters"))
|
||||
{
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
unselect_attached_floaters();
|
||||
}
|
||||
/* update_all_sym_bboxes
|
||||
* Update all symbol bounding boxes */
|
||||
else if(!strcmp(argv[1], "update_all_sym_bboxes"))
|
||||
|
|
@ -6295,8 +6429,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
}
|
||||
}
|
||||
/* wire [x1 y1 x2 y2] [pos] [prop] [sel]
|
||||
* wire
|
||||
* wire gui
|
||||
* Place a new wire
|
||||
* if no coordinates are given start a GUI wire placement */
|
||||
* if no coordinates are given start a GUI wire placement
|
||||
* if `gui` argument is given start a GUI placement of a wire with 1st point
|
||||
* starting from current mouse coordinates */
|
||||
else if(!strcmp(argv[1], "wire"))
|
||||
{
|
||||
double x1,y1,x2,y2;
|
||||
|
|
@ -6324,7 +6462,21 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
if(tclgetboolvar("autotrim_wires")) trim_wires();
|
||||
set_modify(1);
|
||||
}
|
||||
else {
|
||||
else if(argc > 2 && !strcmp(argv[2], "gui")) {
|
||||
int prev_state = xctx->ui_state;
|
||||
int infix_interface = tclgetboolvar("infix_interface");
|
||||
if(infix_interface) {
|
||||
start_wire(xctx->mousex_snap, xctx->mousey_snap);
|
||||
if(prev_state == STARTWIRE) {
|
||||
tcleval("set constr_mv 0" );
|
||||
xctx->constr_mv=0;
|
||||
}
|
||||
} else {
|
||||
xctx->last_command = 0;
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTWIRE;
|
||||
}
|
||||
} else {
|
||||
xctx->last_command = 0;
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTWIRE;
|
||||
|
|
|
|||
183
src/select.c
183
src/select.c
|
|
@ -735,7 +735,7 @@ void bbox(int what,double x1,double y1, double x2, double y2)
|
|||
|
||||
/* n = -1 : clear first selected info
|
||||
* n = -2 : return first selected element if still selected, or get first from
|
||||
* selected list. Id no elements selected return first selected item (j = 0)
|
||||
* selected list. If no elements selected return first selected item (j = 0)
|
||||
* n >= 0 : store indicated element as first selected
|
||||
*/
|
||||
int set_first_sel(unsigned short type, int n, unsigned int col)
|
||||
|
|
@ -896,10 +896,12 @@ void unselect_all(int dr)
|
|||
}
|
||||
}
|
||||
|
||||
void select_wire(int i,unsigned short select_mode, int fast)
|
||||
void select_wire(int i,unsigned short select_mode, int fast, int override_lock)
|
||||
{
|
||||
char str[1024]; /* overflow safe */
|
||||
/*my_strncpy(s,xctx->wire[i].prop_ptr!=NULL?xctx->wire[i].prop_ptr:"<NULL>",256); */
|
||||
if(!strboolcmp(get_tok_value(xctx->wire[i].prop_ptr, "lock", 0), "true") &&
|
||||
select_mode == SELECTED && !override_lock) return;
|
||||
if( !fast )
|
||||
{
|
||||
my_snprintf(str, S(str), "Info: selected wire: n=%d end1=%d end2=%d\nnode=%s",i,
|
||||
|
|
@ -937,6 +939,68 @@ void select_wire(int i,unsigned short select_mode, int fast)
|
|||
xctx->need_reb_sel_arr=1;
|
||||
}
|
||||
|
||||
|
||||
static int select_attached_floaters(int inst, const char *name)
|
||||
{
|
||||
int i, c;
|
||||
int found = 0;
|
||||
char *attach = NULL;
|
||||
char *att_save, *att_ptr;
|
||||
if(!name || !name[0]) return found;
|
||||
my_strdup2(_ALLOC_ID_, &attach, name);
|
||||
att_ptr = attach;
|
||||
while( (name = my_strtok_r(att_ptr, " \n", "\"", 0, &att_save)) ) {
|
||||
att_ptr = NULL;
|
||||
for(c = 0; c < cadlayers; c++) {
|
||||
for(i = 0; i < xctx->rects[c]; i++) {
|
||||
if(!strcmp(name, get_tok_value(xctx->rect[c][i].prop_ptr, "name", 0))) {
|
||||
found = 1;
|
||||
select_box(c, i, SELECTED, 1, 1);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->lines[c]; i++) {
|
||||
if(!strcmp(name, get_tok_value(xctx->line[c][i].prop_ptr, "name", 0))) {
|
||||
found = 1;
|
||||
select_line(c, i, SELECTED, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < xctx->polygons[c]; i++) {
|
||||
if(!strcmp(name, get_tok_value(xctx->poly[c][i].prop_ptr, "name", 0))) {
|
||||
found = 1;
|
||||
select_polygon(c, i, SELECTED, 1, 1);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->arcs[c]; i++) {
|
||||
if(!strcmp(name, get_tok_value(xctx->arc[c][i].prop_ptr, "name", 0))) {
|
||||
found = 1;
|
||||
select_arc(c, i, SELECTED, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->wires; i++) {
|
||||
if(!strcmp(name, get_tok_value(xctx->wire[i].prop_ptr, "name", 0))) {
|
||||
found = 1;
|
||||
select_wire(i, SELECTED, 1, 1);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->texts; i++) {
|
||||
if(!strcmp(name, get_tok_value(xctx->text[i].prop_ptr, "name", 0))) {
|
||||
found = 1;
|
||||
select_text(i, SELECTED, 1, 1);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < xctx->instances; i++) {
|
||||
if(i != inst && !strcmp(name, xctx->inst[i].instname)) {
|
||||
found = 1;
|
||||
select_element(i, SELECTED, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
my_free(_ALLOC_ID_, &attach);
|
||||
return found;
|
||||
}
|
||||
|
||||
/* fast == 1: do not update status line
|
||||
* fast == 2: do not draw / undraw selected elements
|
||||
* fast == 3: 1 + 2
|
||||
|
|
@ -991,16 +1055,21 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc
|
|||
}
|
||||
}
|
||||
}
|
||||
if(!fast && select_mode == SELECTED) {
|
||||
select_attached_floaters(i, get_tok_value(xctx->inst[i].prop_ptr, "attach", 0));
|
||||
}
|
||||
xctx->need_reb_sel_arr=1;
|
||||
}
|
||||
|
||||
void select_text(int i,unsigned short select_mode, int fast)
|
||||
void select_text(int i, unsigned short select_mode, int fast, int override_lock)
|
||||
{
|
||||
char str[1024]; /* overflow safe */
|
||||
char s[256]; /* overflow safe */
|
||||
#if HAS_CAIRO==1
|
||||
int customfont;
|
||||
#endif
|
||||
if(!strboolcmp(get_tok_value(xctx->text[i].prop_ptr, "lock", 0), "true") &&
|
||||
select_mode == SELECTED && !override_lock) return;
|
||||
if(!fast) {
|
||||
my_strncpy(s,xctx->text[i].prop_ptr!=NULL?xctx->text[i].prop_ptr:"<NULL>",S(s));
|
||||
my_snprintf(str, S(str), "Info: selected text %d: properties: %s", i,s);
|
||||
|
|
@ -1075,7 +1144,7 @@ void select_box(int c, int i, unsigned short select_mode, int fast, int override
|
|||
|
||||
|
||||
|
||||
void select_arc(int c, int i, unsigned short select_mode, int fast)
|
||||
void select_arc(int c, int i, unsigned short select_mode, int fast, int override_lock)
|
||||
{
|
||||
char str[1024]; /* overflow safe */
|
||||
char s[256]; /* overflow safe */
|
||||
|
|
@ -1105,11 +1174,14 @@ void select_arc(int c, int i, unsigned short select_mode, int fast)
|
|||
xctx->need_reb_sel_arr=1;
|
||||
}
|
||||
|
||||
void select_polygon(int c, int i, unsigned short select_mode, int fast )
|
||||
void select_polygon(int c, int i, unsigned short select_mode, int fast, int override_lock )
|
||||
{
|
||||
char str[1024]; /* overflow safe */
|
||||
char s[256]; /* overflow safe */
|
||||
int bezier;
|
||||
|
||||
if(!strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr, "lock", 0), "true") &&
|
||||
select_mode == SELECTED && !override_lock) return;
|
||||
if(!fast)
|
||||
{
|
||||
my_strncpy(s,xctx->poly[c][i].prop_ptr!=NULL?xctx->poly[c][i].prop_ptr:"<NULL>",S(s));
|
||||
|
|
@ -1134,10 +1206,13 @@ void select_polygon(int c, int i, unsigned short select_mode, int fast )
|
|||
xctx->need_reb_sel_arr=1;
|
||||
}
|
||||
|
||||
void select_line(int c, int i, unsigned short select_mode, int fast )
|
||||
void select_line(int c, int i, unsigned short select_mode, int fast, int override_lock )
|
||||
{
|
||||
char str[1024]; /* overflow safe */
|
||||
char s[256]; /* overflow safe */
|
||||
|
||||
if(!strboolcmp(get_tok_value(xctx->line[c][i].prop_ptr, "lock", 0), "true") &&
|
||||
select_mode == SELECTED && !override_lock) return;
|
||||
if(!fast)
|
||||
{
|
||||
my_strncpy(s,xctx->line[c][i].prop_ptr!=NULL?xctx->line[c][i].prop_ptr:"<NULL>",S(s));
|
||||
|
|
@ -1193,19 +1268,19 @@ Selected select_object(double mx,double my, unsigned short select_mode,
|
|||
{
|
||||
case WIRE:
|
||||
if(xctx->wire[sel.n].sel) xctx->already_selected = 1;
|
||||
select_wire(sel.n, select_mode, 0);
|
||||
select_wire(sel.n, select_mode, 0, override_lock);
|
||||
break;
|
||||
case xTEXT:
|
||||
if(xctx->text[sel.n].sel) xctx->already_selected = 1;
|
||||
select_text(sel.n, select_mode, 0);
|
||||
select_text(sel.n, select_mode, 0, override_lock);
|
||||
break;
|
||||
case LINE:
|
||||
if(xctx->line[sel.col][sel.n].sel) xctx->already_selected = 1;
|
||||
select_line(sel.col, sel.n, select_mode,0);
|
||||
select_line(sel.col, sel.n, select_mode,0, override_lock);
|
||||
break;
|
||||
case POLYGON:
|
||||
if(xctx->poly[sel.col][sel.n].sel) xctx->already_selected = 1;
|
||||
select_polygon(sel.col, sel.n, select_mode,0);
|
||||
select_polygon(sel.col, sel.n, select_mode,0, override_lock);
|
||||
break;
|
||||
case xRECT:
|
||||
if(xctx->rect[sel.col][sel.n].sel) xctx->already_selected = 1;
|
||||
|
|
@ -1213,11 +1288,11 @@ Selected select_object(double mx,double my, unsigned short select_mode,
|
|||
break;
|
||||
case ARC:
|
||||
if(xctx->arc[sel.col][sel.n].sel) xctx->already_selected = 1;
|
||||
select_arc(sel.col,sel.n, select_mode,0);
|
||||
select_arc(sel.col,sel.n, select_mode,0, override_lock);
|
||||
break;
|
||||
case ELEMENT:
|
||||
if(xctx->inst[sel.n].sel) xctx->already_selected = 1;
|
||||
select_element(sel.n,select_mode,0, override_lock);
|
||||
select_element(sel.n, select_mode,0, override_lock);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1260,10 +1335,10 @@ void select_attached_nets(void)
|
|||
for(wptr=xctx->wire_spatial_table[sqx][sqy]; wptr; wptr=wptr->next) {
|
||||
i = wptr->n;
|
||||
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) {
|
||||
select_wire(i,SELECTED1, 1);
|
||||
select_wire(i,SELECTED1, 1, 0);
|
||||
}
|
||||
if(xctx->wire[i].x2 == x0 && xctx->wire[i].y2 == y0) {
|
||||
select_wire(i,SELECTED2, 1);
|
||||
select_wire(i,SELECTED2, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1286,10 +1361,10 @@ void select_attached_nets(void)
|
|||
i = wptr->n;
|
||||
if(i == wire) continue;
|
||||
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) {
|
||||
select_wire(i,SELECTED1, 1);
|
||||
select_wire(i,SELECTED1, 1, 0);
|
||||
}
|
||||
if(xctx->wire[i].x2 == x0 && xctx->wire[i].y2 == y0) {
|
||||
select_wire(i,SELECTED2, 1);
|
||||
select_wire(i,SELECTED2, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1316,23 +1391,23 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
|
|||
if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2))
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
select_wire(i, SELECTED, 1);
|
||||
select_wire(i, SELECTED, 1, 0);
|
||||
}
|
||||
else if(stretch && POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) )
|
||||
{
|
||||
xctx->ui_state |= SELECTION;
|
||||
select_wire(i, SELECTED1, 1);
|
||||
select_wire(i, SELECTED1, 1, 0);
|
||||
}
|
||||
else if(stretch && POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2) )
|
||||
{
|
||||
xctx->ui_state |= SELECTION;
|
||||
select_wire(i, SELECTED2, 1);
|
||||
select_wire(i, SELECTED2, 1, 0);
|
||||
}
|
||||
} else {
|
||||
if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2))
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
select_wire(i, 0, 1);
|
||||
select_wire(i, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1358,7 +1433,7 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
|
|||
if(RECT_INSIDE(xx1,yy1, xx2, yy2,x1,y1,x2,y2))
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
sel ? select_text(i, SELECTED, 1): select_text(i, 0, 1);
|
||||
sel ? select_text(i, SELECTED, 1, 0): select_text(i, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->instances; ++i)
|
||||
|
|
@ -1367,9 +1442,7 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
|
|||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
if(sel) {
|
||||
if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) {
|
||||
select_element(i, SELECTED, 1, 1);
|
||||
}
|
||||
select_element(i, SELECTED, 1, 0);
|
||||
} else {
|
||||
select_element(i, 0, 1, 0);
|
||||
}
|
||||
|
|
@ -1403,14 +1476,14 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
|
|||
}
|
||||
if(flag) {
|
||||
if(selected_points==0) {
|
||||
select_polygon(c, i, 0, 1);
|
||||
select_polygon(c, i, 0, 1, 0);
|
||||
}
|
||||
if(selected_points==xctx->poly[c][i].points) {
|
||||
xctx->ui_state |= SELECTION;
|
||||
select_polygon(c, i, SELECTED, 1);
|
||||
select_polygon(c, i, SELECTED, 1, 0);
|
||||
} else if(selected_points) {
|
||||
/* for polygon, SELECTED1 means partial sel */
|
||||
if(sel && stretch) select_polygon(c, i, SELECTED1,1);
|
||||
if(sel && stretch) select_polygon(c, i, SELECTED1, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1421,23 +1494,23 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
|
|||
if(RECT_INSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2))
|
||||
{
|
||||
xctx->ui_state |= SELECTION;
|
||||
select_line(c,i,SELECTED,1);
|
||||
select_line(c, i, SELECTED, 1, 0);
|
||||
}
|
||||
else if(stretch && POINTINSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1, x1,y1,x2,y2) )
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
select_line(c, i,SELECTED1,1);
|
||||
select_line(c, i, SELECTED1, 1, 0);
|
||||
}
|
||||
else if(stretch && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) )
|
||||
{
|
||||
xctx->ui_state |= SELECTION;
|
||||
select_line(c, i,SELECTED2,1);
|
||||
select_line(c, i, SELECTED2, 1, 0);
|
||||
}
|
||||
} else {
|
||||
if(RECT_INSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2))
|
||||
{
|
||||
xctx->ui_state |= SELECTION;
|
||||
select_line(c,i,0,1);
|
||||
select_line(c, i, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1454,22 +1527,22 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
|
|||
arc_bbox(x, y, r, a, b, &tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2);
|
||||
if(RECT_INSIDE(tmp.x1, tmp.y1, tmp.x2, tmp.y2, x1,y1,x2,y2)) {
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
sel? select_arc(c, i, SELECTED,1): select_arc(c, i, 0,1);
|
||||
sel? select_arc(c, i, SELECTED,1, 0): select_arc(c, i, 0,1, 0);
|
||||
}
|
||||
else if( sel && stretch && POINTINSIDE(x, y, x1, y1, x2, y2) )
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
select_arc(c, i,SELECTED1,1);
|
||||
select_arc(c, i,SELECTED1,1, 0);
|
||||
}
|
||||
else if( sel && stretch && POINTINSIDE(xb, yb, x1, y1, x2, y2) )
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
select_arc(c, i,SELECTED3,1);
|
||||
select_arc(c, i,SELECTED3,1, 0);
|
||||
}
|
||||
else if( sel && stretch && POINTINSIDE(xa, ya, x1, y1, x2, y2) )
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
select_arc(c, i,SELECTED2,1);
|
||||
select_arc(c, i,SELECTED2,1, 0);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->rects[c]; ++i)
|
||||
|
|
@ -1480,9 +1553,7 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
|
|||
|
||||
|
||||
if(sel) {
|
||||
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) {
|
||||
select_box(c,i, SELECTED, 1, 1);
|
||||
}
|
||||
select_box(c,i, SELECTED, 1, 0);
|
||||
} else {
|
||||
select_box(c,i, 0, 1, 0);
|
||||
}
|
||||
|
|
@ -1544,7 +1615,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
|
|||
ly2 = xctx->wire[i].y2;
|
||||
if(lineclip(&lx1, &ly1, &lx2, &ly2, x1,y1,x2,y2)) {
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
sel ? select_wire(i,SELECTED, 1): select_wire(i,0, 1);
|
||||
sel ? select_wire(i,SELECTED, 1, 0): select_wire(i,0, 1, 0);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->texts; ++i)
|
||||
|
|
@ -1570,7 +1641,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
|
|||
if(RECT_TOUCH(xx1, yy1, xx2, yy2,x1,y1,x2,y2))
|
||||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
sel ? select_text(i, SELECTED, 1): select_text(i, 0, 1);
|
||||
sel ? select_text(i, SELECTED, 1, 0): select_text(i, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->instances; ++i)
|
||||
|
|
@ -1579,9 +1650,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
|
|||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
if(sel) {
|
||||
if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) {
|
||||
select_element(i, SELECTED, 1, 1);
|
||||
}
|
||||
select_element(i, SELECTED, 1, 0);
|
||||
} else {
|
||||
select_element(i, 0, 1, 0);
|
||||
}
|
||||
|
|
@ -1605,7 +1674,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
|
|||
}
|
||||
}
|
||||
if(flag) {
|
||||
sel ? select_polygon(c, i, SELECTED, 1): select_polygon(c, i, 0, 1);
|
||||
sel ? select_polygon(c, i, SELECTED, 1, 0): select_polygon(c, i, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->lines[c]; ++i)
|
||||
|
|
@ -1617,7 +1686,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
|
|||
ly2 = xctx->line[c][i].y2;
|
||||
if(lineclip(&lx1, &ly1, &lx2, &ly2, x1,y1,x2,y2)) {
|
||||
xctx->ui_state |= SELECTION;
|
||||
sel? select_line(c,i,SELECTED,1): select_line(c,i,0,1);
|
||||
sel? select_line(c, i, SELECTED, 1, 0): select_line(c, i, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->arcs[c]; ++i) {
|
||||
|
|
@ -1633,7 +1702,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
|
|||
arc_bbox(x, y, r, a, b, &tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2);
|
||||
if(RECT_TOUCH(tmp.x1, tmp.y1, tmp.x2, tmp.y2, x1,y1,x2,y2)) {
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
sel? select_arc(c, i, SELECTED,1): select_arc(c, i, 0,1);
|
||||
sel? select_arc(c, i, SELECTED,1, 0): select_arc(c, i, 0,1, 0);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->rects[c]; ++i)
|
||||
|
|
@ -1642,9 +1711,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
|
|||
{
|
||||
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
|
||||
if(sel) {
|
||||
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) {
|
||||
select_box(c,i, SELECTED, 1, 1);
|
||||
}
|
||||
select_box(c,i, SELECTED, 1, 0);
|
||||
} else {
|
||||
select_box(c,i, 0, 1, 0);
|
||||
}
|
||||
|
|
@ -1688,6 +1755,8 @@ int floaters_from_selected_inst()
|
|||
}
|
||||
my_strdup2(_ALLOC_ID_, &xctx->inst[i].prop_ptr,
|
||||
subst_token(xctx->inst[i].prop_ptr, "hide_texts", "true"));
|
||||
my_strdup2(_ALLOC_ID_, &xctx->inst[i].prop_ptr,
|
||||
subst_token(xctx->inst[i].prop_ptr, "attach", xctx->inst[i].instname));
|
||||
set_inst_flags(&xctx->inst[i]);
|
||||
for(t = 0; t < sym->texts; t++) {
|
||||
double txtx0, txty0;
|
||||
|
|
@ -1730,33 +1799,35 @@ void select_all(void)
|
|||
|
||||
for(i=0;i<xctx->wires; ++i)
|
||||
{
|
||||
select_wire(i,SELECTED, 1);
|
||||
select_wire(i,SELECTED, 1, 0);
|
||||
}
|
||||
for(i=0;i<xctx->texts; ++i)
|
||||
{
|
||||
select_text(i, SELECTED, 1);
|
||||
select_text(i, SELECTED, 1, 0);
|
||||
}
|
||||
for(i=0;i<xctx->instances; ++i)
|
||||
{
|
||||
select_element(i,SELECTED,1, 0);
|
||||
select_element(i, SELECTED, 1, 0);
|
||||
/* following not done in select_element() due to fast=1 argument */
|
||||
select_attached_floaters(i, get_tok_value(xctx->inst[i].prop_ptr, "attach", 0));
|
||||
}
|
||||
for(c=0;c<cadlayers; ++c)
|
||||
{
|
||||
for(i=0;i<xctx->polygons[c]; ++i)
|
||||
{
|
||||
select_polygon(c,i,SELECTED,1);
|
||||
select_polygon(c, i, SELECTED, 1, 0);
|
||||
}
|
||||
for(i=0;i<xctx->lines[c]; ++i)
|
||||
{
|
||||
select_line(c,i,SELECTED,1);
|
||||
select_line(c, i, SELECTED, 1, 0);
|
||||
}
|
||||
for(i=0;i<xctx->arcs[c]; ++i)
|
||||
{
|
||||
select_arc(c,i, SELECTED, 1);
|
||||
select_arc(c, i, SELECTED, 1, 0);
|
||||
}
|
||||
for(i=0;i<xctx->rects[c]; ++i)
|
||||
{
|
||||
select_box(c,i, SELECTED, 1, 0);
|
||||
select_box(c, i, SELECTED, 1, 0);
|
||||
}
|
||||
} /* end for c */
|
||||
drawtemparc(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ function process( i,j, iprefix, saveinstr, savetype, saveanalysis)
|
|||
} else if( $1 ~ /^\*\.(ipin|opin|iopin)/ ) {
|
||||
num=split($2,name,",")
|
||||
for(i=1;i<=num;i++) print $1 " " name[i]
|
||||
} else if( $1 ~ /\.subckt/) {
|
||||
} else if( tolower($1) ~ /\.subckt/) {
|
||||
# remove m=.. from subcircuit definition since m= is a multiplier not a param
|
||||
sub(/ m=[0-9]+/," ",$0)
|
||||
gsub(","," ",$0)
|
||||
|
|
|
|||
|
|
@ -173,10 +173,9 @@ static int spice_netlist(FILE *fd, int spice_stop )
|
|||
int err = 0;
|
||||
int i, flag = 0;
|
||||
const char *type;
|
||||
int top_sub;
|
||||
int top_sub = tclgetboolvar("lvs_netlist") || tclgetboolvar("top_is_subckt");
|
||||
int lvs_ignore = tclgetboolvar("lvs_ignore");
|
||||
|
||||
top_sub = tclgetboolvar("lvs_netlist") || tclgetboolvar("top_is_subckt");
|
||||
|
||||
if(!spice_stop) {
|
||||
dbg(1, "spice_netlist(): invoke prepare_netlist_structs for %s\n", xctx->current_name);
|
||||
xctx->prep_net_structs = 0;
|
||||
|
|
@ -278,6 +277,7 @@ int global_spice_netlist(int global, int alert) /* netlister driver */
|
|||
int found_top_symbol = 0;
|
||||
int npins = 0; /* top schematic number of i/o ports */
|
||||
Sch_pin_record *pinnumber_list = NULL; /* list of top sch i/o ports ordered wrt sim_pinnumber attr */
|
||||
int uppercase_subckt = tclgetboolvar("uppercase_subckt");
|
||||
|
||||
exit_code = 0; /* reset exit code */
|
||||
split_f = tclgetboolvar("split_files");
|
||||
|
|
@ -341,7 +341,10 @@ int global_spice_netlist(int global, int alert) /* netlister driver */
|
|||
}
|
||||
top_sub = tclgetboolvar("lvs_netlist") || tclgetboolvar("top_is_subckt");
|
||||
if(!top_sub) fprintf(fd,"**");
|
||||
fprintf(fd,".subckt %s", get_cell(xctx->sch[xctx->currsch], 0));
|
||||
if(uppercase_subckt)
|
||||
fprintf(fd,".SUBCKT %s", get_cell(xctx->sch[xctx->currsch], 0));
|
||||
else
|
||||
fprintf(fd,".subckt %s", get_cell(xctx->sch[xctx->currsch], 0));
|
||||
pinnumber_list = sort_schematic_pins(&npins); /* sort pins according to sim_pinnumber attr */
|
||||
|
||||
/* print top subckt ipin/opins */
|
||||
|
|
@ -405,7 +408,10 @@ int global_spice_netlist(int global, int alert) /* netlister driver */
|
|||
/* /20100217 */
|
||||
|
||||
if(!top_sub) fprintf(fd,"**");
|
||||
fprintf(fd, ".ends\n");
|
||||
if(uppercase_subckt)
|
||||
fprintf(fd, ".ENDS\n");
|
||||
else
|
||||
fprintf(fd, ".ends\n");
|
||||
|
||||
|
||||
if(split_f) {
|
||||
|
|
@ -572,7 +578,7 @@ int global_spice_netlist(int global, int alert) /* netlister driver */
|
|||
|
||||
|
||||
/* 20150922 added split_files check */
|
||||
if(!split_f) fprintf(fd, ".end\n");
|
||||
if( !top_sub && !split_f) fprintf(fd, ".end\n");
|
||||
|
||||
dbg(1, "global_spice_netlist(): starting awk on netlist!\n");
|
||||
|
||||
|
|
@ -612,7 +618,8 @@ int spice_block_netlist(FILE *fd, int i, int alert)
|
|||
char *sym_def = NULL;
|
||||
char *name = NULL;
|
||||
const char *default_schematic;
|
||||
|
||||
int uppercase_subckt = tclgetboolvar("uppercase_subckt");
|
||||
|
||||
split_f = tclgetboolvar("split_files");
|
||||
|
||||
if(!strboolcmp( get_tok_value(xctx->sym[i].prop_ptr,"spice_stop",0),"true") )
|
||||
|
|
@ -657,7 +664,10 @@ int spice_block_netlist(FILE *fd, int i, int alert)
|
|||
} else {
|
||||
const char *s = get_cell(sanitize(name), 0);
|
||||
fprintf(fd, "** sch_path: %s\n", sanitized_abs_sym_path(filename, ""));
|
||||
fprintf(fd, ".subckt %s ", s);
|
||||
if(uppercase_subckt)
|
||||
fprintf(fd, ".SUBCKT %s ", s);
|
||||
else
|
||||
fprintf(fd, ".subckt %s ", s);
|
||||
print_spice_subckt_nodes(fd, i);
|
||||
|
||||
my_strdup(_ALLOC_ID_, &extra, get_tok_value(xctx->sym[i].prop_ptr,"extra",0) );
|
||||
|
|
@ -680,7 +690,10 @@ int spice_block_netlist(FILE *fd, int i, int alert)
|
|||
fprintf(fd, "%s\n", xctx->schprop);
|
||||
fprintf(fd,"**** end user architecture code\n");
|
||||
}
|
||||
fprintf(fd, ".ends\n\n");
|
||||
if(uppercase_subckt)
|
||||
fprintf(fd, ".ENDS\n\n");
|
||||
else
|
||||
fprintf(fd, ".ends\n\n");
|
||||
}
|
||||
if(split_f) {
|
||||
int save;
|
||||
|
|
|
|||
|
|
@ -1035,7 +1035,7 @@ void svg_draw(void)
|
|||
{
|
||||
if(xctx->rect[c][i].flags & 1) { /* graph */
|
||||
xRect *r = &xctx->rect[c][i];
|
||||
svg_embedded_graph(fd, r, r->x1, r->y1, r->x2, r->y2);
|
||||
svg_embedded_graph(fd, i, r->x1, r->y1, r->x2, r->y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
113
src/token.c
113
src/token.c
|
|
@ -184,6 +184,7 @@ int match_symbol(const char *name) /* never returns -1, if symbol not found loa
|
|||
int i,found;
|
||||
|
||||
found=0;
|
||||
dbg(1, "match_symbol(): name=%s\n", name);
|
||||
for(i=0;i<xctx->symbols; ++i) {
|
||||
/* dbg(1, "match_symbol(): name=%s, sym[i].name=%s\n",name, xctx->sym[i].name);*/
|
||||
if(xctx->x_strcmp(name, xctx->sym[i].name) == 0)
|
||||
|
|
@ -1198,8 +1199,8 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200
|
|||
}
|
||||
}
|
||||
my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
|
||||
if(strstr(result, "expr(") ) {
|
||||
result = eval_expr(result);
|
||||
if(strstr(result, "expr(")) {
|
||||
my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
|
||||
}
|
||||
dbg(1, "print_vhdl_primitive(): after translate3() result=%s\n", result);
|
||||
}
|
||||
|
|
@ -2152,7 +2153,8 @@ int print_spice_element(FILE *fd, int inst)
|
|||
const char *str_ptr=NULL;
|
||||
register int c, state=TOK_BEGIN, space;
|
||||
char *template=NULL,*format=NULL, *s, *name=NULL, *token=NULL;
|
||||
const char *lab, *value = NULL;
|
||||
const char *lab;
|
||||
const char *value = NULL;
|
||||
/* char *translatedvalue = NULL; */
|
||||
size_t sizetok=0;
|
||||
size_t token_pos=0;
|
||||
|
|
@ -2462,8 +2464,8 @@ int print_spice_element(FILE *fd, int inst)
|
|||
value = spiceprefixtag;
|
||||
}
|
||||
|
||||
if(strstr(value, "expr(") ) {
|
||||
value = eval_expr(value);
|
||||
if(strstr(value, "expr(")) {
|
||||
value = eval_expr(value);
|
||||
}
|
||||
/* token=%xxxx and xxxx is not defined in prop_ptr or template: return xxxx */
|
||||
if(!token_exists && token[0] =='%') {
|
||||
|
|
@ -2517,8 +2519,8 @@ int print_spice_element(FILE *fd, int inst)
|
|||
if(result) {
|
||||
my_strdup(_ALLOC_ID_, &result, tcl_hook2(result));
|
||||
}
|
||||
if(strstr(result, "expr(") ) {
|
||||
result = eval_expr(result);
|
||||
if(strstr(result, "expr(")) {
|
||||
my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
|
||||
}
|
||||
if(result) fprintf(fd, "%s", result);
|
||||
dbg(1, "print_spice_element(): returning |%s|\n", result);
|
||||
|
|
@ -3154,8 +3156,8 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
|
|||
}
|
||||
}
|
||||
my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
|
||||
if(strstr(result, "expr(") ) {
|
||||
result = eval_expr(result);
|
||||
if(strstr(result, "expr(")) {
|
||||
my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
|
||||
}
|
||||
dbg(1, "print_verilog_primitive(): after translate3() result=%s\n", result);
|
||||
}
|
||||
|
|
@ -3779,6 +3781,99 @@ const char *spice_get_node(const char *token)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* caller must free returned value
|
||||
* get the full pathname of "instname" device
|
||||
* modelparam:
|
||||
* 0: current, 1: modelparam, 2: modelvoltage
|
||||
* param: device parameter, like "ib", "gm", "vth"
|
||||
* set param to {} (empty str) for just branch current of 2 terminal device
|
||||
* for parameters like "vth" modelparam must be 2
|
||||
* for parameters like "ib" modelparam must be 0
|
||||
* for parameters like "gm" modelparam must be 1
|
||||
*/
|
||||
char *get_fqdevice(const char *param, int modelparam, const char *instname)
|
||||
{
|
||||
int start_level; /* hierarchy level where waves were loaded */
|
||||
char *fqdev = NULL;
|
||||
const char *path = xctx->sch_path[xctx->currsch] + 1;
|
||||
char *dev = NULL;
|
||||
size_t len;
|
||||
int idx;
|
||||
int sim_is_xyce = tcleval("sim_is_xyce")[0] == '1' ? 1 : 0;
|
||||
int skip = 0;
|
||||
char *iprefix = modelparam == 0 ? "i(" : modelparam == 1 ? "" : "v(";
|
||||
char *ipostfix = modelparam == 1 ? "" : ")";
|
||||
int prefix;
|
||||
|
||||
start_level = sch_waves_loaded();
|
||||
/* skip path components that are above the level where raw file was loaded */
|
||||
while(*path && skip < start_level) {
|
||||
if(*path == '.') skip++;
|
||||
++path;
|
||||
}
|
||||
my_strdup2(_ALLOC_ID_, &dev, instname);
|
||||
strtolower(dev);
|
||||
prefix=dev[0];
|
||||
len = strlen(path) + strlen(dev) + 40; /* some extra chars for i(..) wrapper */
|
||||
fqdev = my_malloc(_ALLOC_ID_, len);
|
||||
if(!sim_is_xyce) {
|
||||
int vsource = (prefix == 'v') || (prefix == 'e');
|
||||
if(path[0]) {
|
||||
if(vsource) {
|
||||
my_snprintf(fqdev, len, "i(%c.%s%s)", prefix, path, dev);
|
||||
} else if(prefix=='q') {
|
||||
my_snprintf(fqdev, len, "%s@%c.%s%s[%s]%s",
|
||||
iprefix, prefix, path, dev, param ? param : "ic", ipostfix);
|
||||
} else if(prefix=='d' || prefix == 'm') {
|
||||
my_snprintf(fqdev, len, "%s@%c.%s%s[%s]%s",
|
||||
iprefix, prefix, path, dev, param ? param : "id", ipostfix);
|
||||
} else if(prefix=='i') {
|
||||
my_snprintf(fqdev, len, "i(@%c.%s%s[current])", prefix, path, dev);
|
||||
} else {
|
||||
my_snprintf(fqdev, len, "i(@%c.%s%s[i])", prefix, path, dev);
|
||||
}
|
||||
} else {
|
||||
if(vsource) {
|
||||
my_snprintf(fqdev, len, "i(%s)", dev);
|
||||
} else if(prefix == 'q') {
|
||||
my_snprintf(fqdev, len, "%s@%s[%s]%s", iprefix, dev, param ? param : "ic", ipostfix);
|
||||
} else if(prefix == 'd' || prefix == 'm') {
|
||||
my_snprintf(fqdev, len, "%s@%s[%s]%s", iprefix, dev, param ? param : "id", ipostfix);
|
||||
} else if(prefix == 'i') {
|
||||
my_snprintf(fqdev, len, "i(@%s[current])", dev);
|
||||
} else {
|
||||
my_snprintf(fqdev, len, "i(@%s[i])", dev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my_snprintf(fqdev, len, "i(%s%s)", path, dev);
|
||||
}
|
||||
dbg(1, "fqdev=%s\n", fqdev);
|
||||
strtolower(fqdev);
|
||||
idx = get_raw_index(fqdev, NULL);
|
||||
/* special handling for resistors that are converted to b sources:
|
||||
* i(@r.x4.r1[i]) --> i(@b.x4.br1[i])
|
||||
*/
|
||||
if(idx < 0 && !strncmp(fqdev, "i(@r", 4)) {
|
||||
if(path[0]) {
|
||||
my_snprintf(fqdev, len, "i(@b.%sb%s[i])", path, dev);
|
||||
} else {
|
||||
my_snprintf(fqdev, len, "i(@b%s[i])", dev);
|
||||
}
|
||||
dbg(1, "fqdev=%s\n", fqdev);
|
||||
}
|
||||
|
||||
|
||||
my_free(_ALLOC_ID_, &dev);
|
||||
return fqdev;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* substitute given tokens in a string with their corresponding values */
|
||||
/* ex.: name=@name w=@w l=@l ---> name=m112 w=3e-6 l=0.8e-6 */
|
||||
/* if s==NULL return emty string */
|
||||
|
|
|
|||
|
|
@ -1179,7 +1179,7 @@ static int source_tcl_file(char *s)
|
|||
fprintf(errfp, "Tcl_AppInit() error: can not execute %s, please fix:\n", s);
|
||||
fprintf(errfp, "%s", tclresult());
|
||||
#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >=6
|
||||
fprintf(errfp, "Line No: %d\n", Tcl_GetErrorLine(interp));
|
||||
fprintf(errfp, "\nLine No: %d\n", Tcl_GetErrorLine(interp));
|
||||
#endif
|
||||
fprintf(errfp, "\n");
|
||||
#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >=6
|
||||
|
|
@ -1666,6 +1666,7 @@ static void create_new_window(int *window_count, const char *noconfirm, const ch
|
|||
tclvareval("set_bindings ", window_path[n], NULL);
|
||||
tclvareval("set_replace_key_binding ", window_path[n], NULL);
|
||||
tclvareval("save_ctx ", window_path[n], NULL);
|
||||
tcleval("eval_user_startup_commands");
|
||||
/* restore previous context,
|
||||
* because the Expose event after new window creation does a context switch prev win -> new win
|
||||
*
|
||||
|
|
@ -2060,6 +2061,7 @@ void change_linewidth(double w)
|
|||
double cs = tclgetdoublevar("cadsnap");
|
||||
if(tclgetboolvar("change_lw")) {
|
||||
xctx->lw=xctx->mooz * 0.09 * cs;
|
||||
if(xctx->lw > 100.) xctx->lw = 100.;
|
||||
xctx->cadhalfdotsize = CADHALFDOTSIZE * (cs < 20. ? cs : 20.) / 10.;
|
||||
}
|
||||
/* explicitly set line width */
|
||||
|
|
@ -2891,6 +2893,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
|
|||
if(has_x) {
|
||||
tclsetintvar("tctx::max_new_windows", MAX_NEW_WINDOWS);
|
||||
tcleval("pack_widgets; set_bindings .drw");
|
||||
tcleval("eval_user_startup_commands");
|
||||
}
|
||||
|
||||
fs=tclgetintvar("fullscreen");
|
||||
|
|
|
|||
29
src/xschem.h
29
src/xschem.h
|
|
@ -163,8 +163,8 @@ extern char win_temp_dir[PATH_MAX];
|
|||
#define CADINITIALY -870
|
||||
#define CADZOOMSTEP 1.2
|
||||
#define CADMOVESTEP 200
|
||||
#define CADMAXZOOM 1000000.0
|
||||
#define CADMINZOOM 0.000001
|
||||
#define CADMAXZOOM 10000.0
|
||||
#define CADMINZOOM 0.005
|
||||
#define CADHALFDOTSIZE 3.7
|
||||
#define CADNULLNODE -1 /* no valid node number */
|
||||
#define CADWIREMINDIST 8.0
|
||||
|
|
@ -375,7 +375,7 @@ extern char win_temp_dir[PATH_MAX];
|
|||
* show_label also used on metal option type symbols (pass-through symbols)
|
||||
* to optionally short two nets (using *_ignore=[true|false] attribute) */
|
||||
#define IS_LABEL_SH_OR_PIN(type) (!(strcmp(type,"label") && strcmp(type,"ipin") && strcmp(type,"opin") && \
|
||||
strcmp(type,"show_label") && strcmp(type,"iopin") && strcmp(type,"bus_tap")))
|
||||
strcmp(type,"scope") && strcmp(type,"show_label") && strcmp(type,"iopin") && strcmp(type,"bus_tap")))
|
||||
#define IS_LABEL_OR_PIN(type) (!(strcmp(type,"label") && strcmp(type,"ipin") && \
|
||||
strcmp(type,"opin") && strcmp(type,"iopin")))
|
||||
#define IS_PIN(type) (!(strcmp(type,"ipin") && strcmp(type,"opin") && strcmp(type,"iopin")))
|
||||
|
|
@ -954,7 +954,7 @@ typedef struct {
|
|||
int lastsel;
|
||||
int maxsel;
|
||||
Selected *sel_array;
|
||||
Selected first_sel; /* first selected instance (used as master when editing multile pbjects) */
|
||||
Selected first_sel; /* first selected instance (used as master when editing multiple objects) */
|
||||
int prep_net_structs;
|
||||
int prep_hi_structs;
|
||||
int prep_hash_inst;
|
||||
|
|
@ -1259,6 +1259,7 @@ extern int embed_rawfile(const char *rawfile);
|
|||
extern int read_rawfile_from_attr(const char *b64s, size_t length, const char *type);
|
||||
extern int raw_read_from_attr(Raw **rawptr, const char *type, double sweep1, double sweep2);
|
||||
extern int raw_add_vector(const char *varname, const char *expr, int sweep_idx);
|
||||
extern int raw_renamevar(const char *old_name, const char *new_name);
|
||||
extern int raw_deletevar(const char *name);
|
||||
extern int new_rawfile(const char *name, const char *type, const char *sweepvar,
|
||||
double start, double end, double step);
|
||||
|
|
@ -1329,7 +1330,7 @@ extern int process_options(int argc, char **argv);
|
|||
extern void calc_drawing_bbox(xRect *boundbox, int selected);
|
||||
extern int ps_draw(int what, int fullzoom, int eps);
|
||||
extern void svg_draw(void);
|
||||
extern void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2, double ry2);
|
||||
extern void svg_embedded_graph(FILE *fd, int i, double rx1, double ry1, double rx2, double ry2);
|
||||
extern void set_viewport_size(int w, int h, double lw);
|
||||
extern void print_image();
|
||||
extern const char *get_trailing_path(const char *str, int no_of_dir, int skip_ext);
|
||||
|
|
@ -1400,9 +1401,11 @@ extern void tclmainloop(void);
|
|||
extern int Tcl_AppInit(Tcl_Interp *interp);
|
||||
extern void abort_operation(void);
|
||||
extern void draw_crosshair(int what, int state);
|
||||
extern void draw_snap_cursor(int what);
|
||||
extern void start_line(double mx, double my);
|
||||
extern void start_wire(double mx, double my);
|
||||
extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr);
|
||||
/* extern void snapped_wire(double c_snap); */
|
||||
extern void unselect_attached_floaters(void);
|
||||
extern int callback(const char *win_path, int event, int mx, int my, KeySym key,
|
||||
int button, int aux, int state);
|
||||
extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h);
|
||||
|
|
@ -1425,6 +1428,7 @@ extern void filledrect(int c, int what, double rectx1,double recty1,
|
|||
|
||||
|
||||
extern void drawtempline(GC gc, int what, double x1,double y1,double x2,double y2);
|
||||
extern void drawtemp_manhattanline(GC gc, int what, double x1,double y1,double x2,double y2);
|
||||
|
||||
/* instead of doing a drawtemprect(xctx->gctiled, NOW, ....) do 4
|
||||
* XCopy Area operations. Used if fix_broken_tiled_fill is set */
|
||||
|
|
@ -1547,6 +1551,8 @@ extern void new_line(int what, double mx_snap, double my_snap);
|
|||
extern void new_arc(int what, double sweep, double mousex_snap, double mousey_snap);
|
||||
extern void arc_3_points(double x1, double y1, double x2, double y2, double x3, double y3,
|
||||
double *x, double *y, double *r, double *a, double *b);
|
||||
/* sel: if set to 1 change references only on selected items, like in a copy operation */
|
||||
extern void update_attached_floaters(const char *from_name, int inst, int sel);
|
||||
extern void move_objects(int what,int merge, double dx, double dy);
|
||||
extern void check_collapsing_objects();
|
||||
extern void redraw_w_a_l_r_p_z_rubbers(int force); /* redraw wire, arcs, line, polygon rubbers */
|
||||
|
|
@ -1611,6 +1617,7 @@ extern char *trim_chars(const char *str, const char *sep);
|
|||
extern char *find_nth(const char *str, const char *sep, const char *quote, int keep_quote, int n);
|
||||
extern int isonlydigit(const char *s);
|
||||
extern const char *spice_get_node(const char *token);
|
||||
extern char *get_fqdevice(const char *param, int modelparam, const char *instname);
|
||||
extern const char *translate(int inst, const char* s);
|
||||
extern const char* translate2(Lcc *lcc, int level, char* s);
|
||||
extern const char *translate3(const char* s, int eat_escapes, const char *s1,
|
||||
|
|
@ -1688,13 +1695,13 @@ extern const char *expandlabel(const char *s, int *m);
|
|||
extern void parse(const char *s);
|
||||
extern void clear_expandlabel_data(void);
|
||||
extern void merge_file(int selection_load, const char ext[]);
|
||||
extern void select_wire(int i, unsigned short select_mode, int fast);
|
||||
extern void select_wire(int i, unsigned short select_mode, int fast, int override_lock);
|
||||
extern void select_element(int i, unsigned short select_mode, int fast, int override_lock);
|
||||
extern void select_text(int i, unsigned short select_mode, int fast);
|
||||
extern void select_text(int i, unsigned short select_mode, int fast, int override_lock);
|
||||
extern void select_box(int c, int i, unsigned short select_mode, int fast, int override_lock);
|
||||
extern void select_arc(int c, int i, unsigned short select_mode, int fast);
|
||||
extern void select_line(int c, int i, unsigned short select_mode, int fast);
|
||||
extern void select_polygon(int c, int i, unsigned short select_mode, int fast );
|
||||
extern void select_arc(int c, int i, unsigned short select_mode, int fast, int override_lock);
|
||||
extern void select_line(int c, int i, unsigned short select_mode, int fast, int override_lock);
|
||||
extern void select_polygon(int c, int i, unsigned short select_mode, int fast, int override_lock );
|
||||
extern const char *net_name(int i, int j, int *mult, int hash_prefix_unnamed_net, int erc);
|
||||
extern int record_global_node(int what, FILE *fp, const char *node);
|
||||
extern int count_items(const char *s, const char *sep, const char *quote);
|
||||
|
|
|
|||
644
src/xschem.tcl
644
src/xschem.tcl
|
|
@ -628,6 +628,10 @@ proc from_eng {i} {
|
|||
## convert number to engineering form
|
||||
proc to_eng {args} {
|
||||
set suffix {}
|
||||
|
||||
if {[ catch {uplevel #0 expr [join $args]} i]} {
|
||||
return [join $args]
|
||||
}
|
||||
set i [uplevel #0 expr [join $args]]
|
||||
set absi [expr {abs($i)}]
|
||||
|
||||
|
|
@ -1836,6 +1840,7 @@ proc simconf_add {tool} {
|
|||
############ cellview
|
||||
# proc cellview prints symbol bindings (default binding or "schematic" attr in symbol)
|
||||
# of all symbols used in current and sub schematics.
|
||||
# the derived_symbols parameter of cellview should be either empty or 'derived_symbols'
|
||||
proc cellview_setlabels {w symbol derived_symbol} {
|
||||
global dark_gui_colorscheme netlist_type
|
||||
if {$dark_gui_colorscheme} {
|
||||
|
|
@ -1937,6 +1942,8 @@ proc cellview_edit_sym {w} {
|
|||
xschem load_new_window $sym
|
||||
}
|
||||
|
||||
# derived_symbols: empty or 'derived_symbols'
|
||||
# upd: never set by caller (used iinternally to update)
|
||||
proc cellview { {derived_symbols {}} {upd 0}} {
|
||||
global keep_symbols nolist_libs dark_gui_colorscheme netlist_type
|
||||
|
||||
|
|
@ -2095,10 +2102,9 @@ proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch
|
|||
set save_netlist_type [xschem get netlist_type]
|
||||
# puts "traversal_setlabels: $w parent: |$parent_sch| inst: $instname def: $sym_sch $inst_sch --> [$w get]"
|
||||
# update schematic
|
||||
if {$parent_sch ne {}} {
|
||||
if {$parent_sch ne {} && $sym_spice_sym_def eq {} && $inst_spice_sym_def eq {} } {
|
||||
set current [xschem get current_name]
|
||||
if { $inst_sch ne [$w get] } {
|
||||
puts "update attr"
|
||||
xschem load -undoreset -nodraw $parent_sch
|
||||
if { [$w get] eq $sym_sch} {
|
||||
xschem setprop -fast instance $instname schematic ;# remove schematic attr on instance
|
||||
|
|
@ -2224,6 +2230,7 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} {
|
|||
set instances [xschem get instances]
|
||||
set current_level [xschem get currsch]
|
||||
for {set i 0} { $i < $instances} { incr i} {
|
||||
# puts "hier_traversal: i=$i, current_level=$current_level, parent_sch=$parent_sch"
|
||||
set instname [xschem getprop instance $i name]
|
||||
set symbol [xschem getprop instance $i cell::name]
|
||||
set default_sch [add_ext $symbol .sch]
|
||||
|
|
@ -2301,8 +2308,10 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} {
|
|||
if {$descended} {
|
||||
incr level
|
||||
set dp [hier_traversal $level $only_subckts 1]
|
||||
xschem go_back 1
|
||||
xschem go_back 2
|
||||
incr level -1
|
||||
} else { ;# descended into a blank schematic. Go back.
|
||||
xschem go_back 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3973,6 +3982,7 @@ proc open_sub_schematic {{inst {}} {inst_number 0}} {
|
|||
|
||||
|
||||
proc is_xschem_file {f} {
|
||||
# puts "is_xschem_file $f"
|
||||
regsub {\(.*} $f {} f ;# remove trailing generator args (gen.tcl(....)) if any
|
||||
if { ![file exists $f] } { return 0
|
||||
} elseif { [file isdirectory $f] } { return 0 }
|
||||
|
|
@ -3987,6 +3997,13 @@ proc is_xschem_file {f} {
|
|||
} else {
|
||||
fconfigure $fd -translation binary
|
||||
while { [gets $fd line] >=0 } {
|
||||
|
||||
#### Can not use this. schematics may containg 8 bit extended characters
|
||||
# if {[regexp {[^[:print:][:space:]]} $line]} { ;# line contains non ascii chars
|
||||
# close $fd
|
||||
# return 0
|
||||
# }
|
||||
|
||||
# this is a script. not an xschem file
|
||||
if { $nline == 0 && [regexp {^#!} $line] } {
|
||||
#### too dangerous executing an arbitrary script...
|
||||
|
|
@ -4365,8 +4382,10 @@ proc file_dialog_display_preview {f} {
|
|||
proc file_dialog_right_listboxselect {dirselect} {
|
||||
global file_dialog_yview file_dialog_dir1 file_dialog_dir2 file_dialog_retval file_dialog_sel
|
||||
global OS file_dialog_loadfile file_dialog_index1 file_dialog_files1 file_dialog_globfilter
|
||||
global file_dialog_others
|
||||
set file_dialog_yview [.load.l.paneright.f.list yview]
|
||||
set file_dialog_sel [.load.l.paneright.f.list curselection]
|
||||
set file_dialog_sel [lindex [.load.l.paneright.f.list curselection] 0]
|
||||
|
||||
if { $file_dialog_sel ne {} } {
|
||||
set curr_dir [abs_sym_path [lindex $file_dialog_files1 $file_dialog_index1]]
|
||||
set curr_item [.load.l.paneright.f.list get $file_dialog_sel]
|
||||
|
|
@ -4399,6 +4418,17 @@ proc file_dialog_right_listboxselect {dirselect} {
|
|||
|
||||
set file_dialog_dir1 $curr_dir
|
||||
set file_dialog_dir2 $curr_item
|
||||
|
||||
set file_dialog_others {}
|
||||
if {$file_dialog_loadfile == 1} {
|
||||
foreach i [lrange [.load.l.paneright.f.list curselection] 1 end] {
|
||||
set file_dialog_retval [.load.l.paneright.f.list get $i]
|
||||
lappend file_dialog_others [file_dialog_getresult 1 0]
|
||||
}
|
||||
}
|
||||
set file_dialog_retval {} ;# we used this variable above to communicate with file_dialog_getresult
|
||||
|
||||
|
||||
if { [file isdirectory $file_dialog_d]} {
|
||||
bind .load.l.paneright.draw <Expose> {}
|
||||
bind .load.l.paneright.draw <Configure> {}
|
||||
|
|
@ -4421,6 +4451,16 @@ proc file_dialog_right_listboxselect {dirselect} {
|
|||
}
|
||||
}
|
||||
|
||||
proc load_additional_files {} {
|
||||
global file_dialog_others
|
||||
|
||||
if {$file_dialog_others ne {} } {
|
||||
foreach i $file_dialog_others {
|
||||
xschem load_new_window $i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# global_initdir: name of global variable containing the initial directory
|
||||
# loadfile: set to 0 if calling for saving instead of loading a file
|
||||
# set to 2 for non blocking operation (symbol insertion)
|
||||
|
|
@ -4458,7 +4498,8 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
set_ne file_dialog_files2 {}
|
||||
panedwindow .load.l -orient horizontal -height 8c
|
||||
if { $loadfile == 2} {frame .load.l.recent -takefocus 0}
|
||||
frame .load.l.paneleft -takefocus 0 -highlightcolor red -highlightthickness 2 -bg {grey90}
|
||||
frame .load.l.paneleft -takefocus 0 -highlightcolor red -highlightthickness 2 -bg {grey90} \
|
||||
-highlightbackground [option get . background {}]
|
||||
eval [subst {listbox .load.l.paneleft.list -listvariable file_dialog_names1 -width 40 -height 12 \
|
||||
-fg black -background {grey90} -highlightthickness 0 -relief flat -borderwidth 0 \
|
||||
-yscrollcommand ".load.l.paneleft.yscroll set" -selectmode browse \
|
||||
|
|
@ -4469,9 +4510,6 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
file_dialog_set_colors1
|
||||
scrollbar .load.l.paneleft.yscroll -command ".load.l.paneleft.list yview" -takefocus 0
|
||||
scrollbar .load.l.paneleft.xscroll -command ".load.l.paneleft.list xview" -orient horiz -takefocus 0
|
||||
pack .load.l.paneleft.yscroll -side right -fill y
|
||||
pack .load.l.paneleft.xscroll -side bottom -fill x
|
||||
pack .load.l.paneleft.list -fill both -expand true -padx 12
|
||||
bind .load.l.paneleft.list <<ListboxSelect>> {
|
||||
set file_dialog_sel [.load.l.paneleft.list curselection]
|
||||
if { $file_dialog_sel ne {} } {
|
||||
|
|
@ -4486,14 +4524,12 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
panedwindow .load.l.paneright -orient vertical
|
||||
frame .load.l.paneright.f -takefocus 0
|
||||
frame .load.l.paneright.draw -background white -height 3.8c -takefocus 0
|
||||
.load.l.paneright add .load.l.paneright.f
|
||||
.load.l.paneright add .load.l.paneright.draw -minsize 150
|
||||
|
||||
|
||||
if { ![catch {.load.l.paneright panecget .load.l.paneright.f -stretch}]} {
|
||||
set optnever {-stretch never}
|
||||
set optalways {-stretch always}
|
||||
|
|
@ -4506,17 +4542,19 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
eval .load.l.paneright paneconfigure .load.l.paneright.f $optnever
|
||||
eval .load.l.paneright paneconfigure .load.l.paneright.draw $optalways
|
||||
|
||||
|
||||
if {$global_initdir eq {INITIALINSTDIR}} {
|
||||
set selmode browse
|
||||
} else {
|
||||
set selmode extended
|
||||
}
|
||||
|
||||
listbox .load.l.paneright.f.list -background {grey90} -listvariable file_dialog_files2 -width 20 -height 12\
|
||||
-fg black -highlightcolor red -highlightthickness 2 \
|
||||
-yscrollcommand ".load.l.paneright.f.yscroll set" -selectmode browse \
|
||||
-highlightbackground [option get . background {}] \
|
||||
-yscrollcommand ".load.l.paneright.f.yscroll set" -selectmode $selmode \
|
||||
-xscrollcommand ".load.l.paneright.f.xscroll set" -exportselection 0
|
||||
scrollbar .load.l.paneright.f.yscroll -command ".load.l.paneright.f.list yview" -takefocus 0
|
||||
scrollbar .load.l.paneright.f.xscroll -command ".load.l.paneright.f.list xview" -orient horiz -takefocus 0
|
||||
pack .load.l.paneright.f.yscroll -side right -fill y
|
||||
pack .load.l.paneright.f.xscroll -side bottom -fill x
|
||||
pack .load.l.paneright.f.list -side bottom -fill both -expand true
|
||||
|
||||
if { $loadfile == 2} {
|
||||
.load.l add .load.l.recent
|
||||
|
|
@ -4560,10 +4598,12 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
.load.l.paneleft.list selection set $file_dialog_index1
|
||||
}
|
||||
label .load.buttons_bot.label -text { File:}
|
||||
entry .load.buttons_bot.entry -highlightcolor red -highlightthickness 2
|
||||
entry .load.buttons_bot.entry -highlightcolor red -highlightthickness 2 \
|
||||
-highlightbackground [option get . background {}] -takefocus 0
|
||||
entry_replace_selection .load.buttons_bot.entry
|
||||
label .load.buttons_bot.srclab -text { Search:}
|
||||
entry .load.buttons_bot.src -width 18 -highlightcolor red -highlightthickness 2
|
||||
entry .load.buttons_bot.src -width 18 -highlightcolor red -highlightthickness 2 \
|
||||
-highlightbackground [option get . background {}]
|
||||
entry_replace_selection .load.buttons_bot.src
|
||||
.load.buttons_bot.src delete 0 end
|
||||
.load.buttons_bot.src insert 0 $file_dialog_globfilter
|
||||
|
|
@ -4591,28 +4631,6 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
set file_dialog_retval { }
|
||||
}
|
||||
|
||||
# radiobutton .load.buttons_bot.all -text All -variable file_dialog_globfilter -value {*} -takefocus 0 \
|
||||
# -command {
|
||||
# set file_dialog_ext $file_dialog_globfilter
|
||||
# setglob $file_dialog_dir1
|
||||
# .load.buttons_bot.src delete 0 end
|
||||
# .load.buttons_bot.src insert 0 $file_dialog_globfilter
|
||||
# }
|
||||
# radiobutton .load.buttons_bot.sym -text .sym -variable file_dialog_globfilter -value {*.sym} -takefocus 0 \
|
||||
# -command {
|
||||
# set file_dialog_ext $file_dialog_globfilter
|
||||
# setglob $file_dialog_dir1
|
||||
# .load.buttons_bot.src delete 0 end
|
||||
# .load.buttons_bot.src insert 0 $file_dialog_globfilter
|
||||
# }
|
||||
# radiobutton .load.buttons_bot.sch -text .sch -variable file_dialog_globfilter -value {*.sch} -takefocus 0 \
|
||||
# -command {
|
||||
# set file_dialog_ext $file_dialog_globfilter
|
||||
# setglob $file_dialog_dir1
|
||||
# .load.buttons_bot.src delete 0 end
|
||||
# .load.buttons_bot.src insert 0 $file_dialog_globfilter
|
||||
# }
|
||||
|
||||
button .load.buttons.up -width 5 -text Up -command {load_file_dialog_up $file_dialog_dir1} -takefocus 0
|
||||
label .load.buttons.mkdirlab -text { New dir: }
|
||||
entry .load.buttons.newdir -width 16 -takefocus 0
|
||||
|
|
@ -4635,19 +4653,28 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
file_dialog_set_colors1
|
||||
.load.l.paneleft.list xview moveto 1
|
||||
}
|
||||
|
||||
pack .load.l -expand true -fill both
|
||||
pack .load.l.paneleft.yscroll -side right -fill y
|
||||
pack .load.l.paneleft.xscroll -side bottom -fill x
|
||||
pack .load.l.paneleft.list -fill both -expand true -padx 12
|
||||
|
||||
pack .load.buttons.home .load.buttons.up .load.buttons.pwd .load.buttons.path -side left
|
||||
pack .load.buttons.mkdirlab -side left
|
||||
pack .load.buttons.newdir -expand true -fill x -side left
|
||||
pack .load.buttons.rmdir .load.buttons.mkdir -side right
|
||||
# pack .load.buttons_bot.all .load.buttons_bot.sym .load.buttons_bot.sch -side left
|
||||
pack .load.buttons_bot.srclab -side left
|
||||
pack .load.buttons_bot.src -side left
|
||||
pack .load.buttons_bot.label -side left
|
||||
pack .load.buttons_bot.entry -side left -fill x -expand true
|
||||
|
||||
pack .load.l.paneright.f.yscroll -side right -fill y
|
||||
pack .load.l.paneright.f.xscroll -side bottom -fill x
|
||||
pack .load.l.paneright.f.list -side bottom -fill both -expand true
|
||||
|
||||
pack .load.buttons_bot.cancel .load.buttons_bot.ok -side left
|
||||
pack .load.buttons_bot -side bottom -fill x
|
||||
pack .load.buttons -side bottom -fill x
|
||||
pack .load.l -expand true -fill both
|
||||
if { [info exists file_dialog_default_geometry]} {
|
||||
wm geometry .load "${file_dialog_default_geometry}"
|
||||
}
|
||||
|
|
@ -4681,7 +4708,8 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
destroy .load
|
||||
set $global_initdir \"\$file_dialog_dir1\"
|
||||
"
|
||||
|
||||
bind .load <KeyPress-H> {.load.buttons.home invoke }
|
||||
bind .load <KeyPress-U> {.load.buttons.up invoke }
|
||||
### update
|
||||
|
||||
if { [info exists file_dialog_v_sp0] } {
|
||||
|
|
@ -4770,6 +4798,253 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
|
|||
return [file_dialog_getresult $loadfile $confirm_overwrt]
|
||||
}
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
##### new alternate insert_symbol browser
|
||||
#######################################################################
|
||||
|
||||
#### Display preview of selected symbol
|
||||
proc insert_symbol_focusin {{paths {}} {maxdepth -1}} {
|
||||
global insert_symbol new_symbol_browser_ext
|
||||
xschem abort_operation
|
||||
set insert_symbol(ext) $new_symbol_browser_ext
|
||||
insert_symbol_filelist $paths $maxdepth
|
||||
}
|
||||
|
||||
proc insert_symbol_preview {{paths {}}} {
|
||||
# puts insert_symbol_preview
|
||||
global insert_symbol
|
||||
xschem preview_window close .ins.center.right {}
|
||||
.ins.center.right configure -bg white
|
||||
bind .ins.center.right <Expose> {}
|
||||
bind .ins.center.right <Configure> {}
|
||||
set sel [.ins.center.left.l curselection]
|
||||
if {$sel eq {}} {
|
||||
set sel [.ins.center.left.l index active]
|
||||
.ins.center.left.l selection set active
|
||||
}
|
||||
if {$sel ne {}} {
|
||||
set f [lindex $insert_symbol(fullpathlist) $sel 0]
|
||||
if {$f ne {}} {
|
||||
set type [is_xschem_file $f]
|
||||
if {$type ne {0}} {
|
||||
set dir [rel_sym_path $f $paths]
|
||||
.ins.top.dir_e configure -state normal
|
||||
.ins.top.dir_e delete 0 end
|
||||
.ins.top.dir_e insert 0 $dir
|
||||
.ins.top.dir_e configure -state readonly
|
||||
|
||||
|
||||
.ins.top2.dir_e configure -state normal
|
||||
.ins.top2.dir_e delete 0 end
|
||||
.ins.top2.dir_e insert 0 $f
|
||||
.ins.top2.dir_e configure -state readonly
|
||||
.ins.center.right configure -bg {}
|
||||
xschem preview_window create .ins.center.right {}
|
||||
xschem preview_window draw .ins.center.right [list $f]
|
||||
bind .ins.center.right <Expose> "xschem preview_window draw .ins.center.right [list $f]"
|
||||
bind .ins.center.right <Configure> "xschem preview_window draw .ins.center.right [list $f]"
|
||||
}
|
||||
insert_symbol_place
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc get_list_of_dirs_with_symbols {{paths {}} {levels -1} {level -1}} {
|
||||
global pathlist
|
||||
if {$level == -1} { set level 0}
|
||||
if {$paths eq {}} {set paths $pathlist}
|
||||
|
||||
foreach i $paths {
|
||||
set filelist [glob -nocomplain -directory $i -type f *]
|
||||
set there_are_symbols 0
|
||||
foreach f $filelist {
|
||||
if {[regexp {\.(sch|sym|tcl)$} $f]} {
|
||||
# if {[is_xschem_file $f] ne {0}} { }
|
||||
set there_are_symbols 1
|
||||
break
|
||||
}
|
||||
}
|
||||
if {$there_are_symbols} {
|
||||
puts $i
|
||||
}
|
||||
|
||||
set dirlist [glob -nocomplain -directory $i -type d *]
|
||||
if {$levels >=0 && $level + 1 > $levels} {return}
|
||||
foreach d $dirlist {
|
||||
get_list_of_dirs_with_symbols $d $levels [expr {$level + 1} ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#### fill list of files matching pattern
|
||||
proc insert_symbol_filelist {paths {maxdepth -1}} {
|
||||
# puts "insert_symbol_filelist: paths=$paths"
|
||||
global insert_symbol
|
||||
set insert_symbol(regex) [.ins.top.pat_e get]
|
||||
|
||||
#check if regex is valid
|
||||
set err [catch {regexp $insert_symbol(regex) {12345}} res]
|
||||
if {$err} {return}
|
||||
|
||||
set f [match_file $insert_symbol(regex) $paths $maxdepth]
|
||||
set filelist {}
|
||||
set insert_symbol(fullpathlist) {}
|
||||
set sel [.ins.center.left.l curselection]
|
||||
if {$sel eq {}} { set sel 0}
|
||||
.ins.center.left.l activate $sel
|
||||
foreach i $f {
|
||||
|
||||
set err [catch {regexp $insert_symbol(ext) $i} type]
|
||||
if {!$err && $type} {
|
||||
set fname [rel_sym_path $i $paths]
|
||||
lappend filelist $fname
|
||||
lappend insert_symbol(fullpathlist) $i
|
||||
}
|
||||
}
|
||||
# sort lists using filelist as key
|
||||
set files {}
|
||||
foreach f $filelist ff $insert_symbol(fullpathlist) {
|
||||
lappend files [list $f $ff]
|
||||
}
|
||||
set files [lsort -dictionary -index 0 $files]
|
||||
set filelist {}
|
||||
set insert_symbol(fullpathlist) {}
|
||||
|
||||
foreach f $files {
|
||||
lassign $f ff fff
|
||||
lappend filelist $ff
|
||||
lappend insert_symbol(fullpathlist) $fff
|
||||
}
|
||||
|
||||
# assign listbox variable all at the end, it is faster...
|
||||
set insert_symbol(list) $filelist
|
||||
set insert_symbol(nitems) [llength $filelist]
|
||||
# .ins.center.left.l selection clear 0 end
|
||||
# .ins.center.left.l selection set 0
|
||||
}
|
||||
|
||||
proc insert_symbol_place {} {
|
||||
# puts insert_symbol_place
|
||||
global insert_symbol
|
||||
set sel [.ins.center.left.l curselection]
|
||||
if {$sel eq {}} {
|
||||
set sel [.ins.center.left.l index active]
|
||||
.ins.center.left.l selection set active
|
||||
}
|
||||
if {$sel ne {}} {
|
||||
set f [lindex $insert_symbol(fullpathlist) $sel 0]
|
||||
if {$f ne {}} {
|
||||
set type [is_xschem_file $f]
|
||||
if {$type ne {0}} {
|
||||
xschem abort_operation
|
||||
xschem place_symbol $f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#### paths: list of paths to use for listing symbols
|
||||
#### maxdepth: how many levels to descend for each $paths directory (-1: no limit)
|
||||
proc insert_symbol {{paths {}} {maxdepth -1} {ext {.*}}} {
|
||||
global insert_symbol
|
||||
set paths [cleanup_paths $paths] ;# remove ~ and other strange path combinations
|
||||
# xschem set semaphore [expr {[xschem get semaphore] +1}]
|
||||
set insert_symbol(ext) $ext
|
||||
if {[winfo exists .ins]} {
|
||||
raise .ins
|
||||
return
|
||||
}
|
||||
toplevel .ins
|
||||
frame .ins.top -takefocus 0
|
||||
frame .ins.top2 -takefocus 0
|
||||
panedwindow .ins.center -orient horizontal -height 8c
|
||||
frame .ins.center.leftdir -takefocus 0
|
||||
frame .ins.center.left -takefocus 0
|
||||
frame .ins.center.right -width 250 -height 250 -bg white -takefocus 0
|
||||
.ins.center add .ins.center.leftdir
|
||||
.ins.center add .ins.center.left
|
||||
.ins.center add .ins.center.right
|
||||
frame .ins.bottom -takefocus 0
|
||||
pack .ins.top -side top -fill x
|
||||
pack .ins.top2 -side top -fill x
|
||||
pack .ins.center -side top -expand 1 -fill both
|
||||
pack .ins.bottom -side top -fill x
|
||||
|
||||
listbox .ins.center.leftdir.l -listvariable insert_symbol(dirs) -width 20 -height 20 \
|
||||
-yscrollcommand ".ins.center.leftdir.s set" -highlightcolor red -highlightthickness 2 \
|
||||
-activestyle underline -highlightbackground [option get . background {}] \
|
||||
-exportselection 0
|
||||
|
||||
listbox .ins.center.left.l -listvariable insert_symbol(list) -width 40 -height 20 \
|
||||
-yscrollcommand ".ins.center.left.s set" -highlightcolor red -highlightthickness 2 \
|
||||
-activestyle underline -highlightbackground [option get . background {}] \
|
||||
-exportselection 0
|
||||
|
||||
scrollbar .ins.center.leftdir.s -command ".ins.center.leftdir.l yview" -takefocus 0
|
||||
scrollbar .ins.center.left.s -command ".ins.center.left.l yview" -takefocus 0
|
||||
|
||||
pack .ins.center.left.l -expand 1 -fill both -side left
|
||||
pack .ins.center.left.s -fill y -side left
|
||||
|
||||
pack .ins.center.leftdir.l -expand 1 -fill both -side left
|
||||
pack .ins.center.leftdir.s -fill y -side left
|
||||
|
||||
label .ins.top2.dir_l -text {Full path:}
|
||||
entry .ins.top2.dir_e -width 60 -state readonly \
|
||||
-readonlybackground [option get . background {}] -takefocus 0
|
||||
label .ins.top.pat_l -text Pattern:
|
||||
entry .ins.top.pat_e -width 20 -highlightcolor red -highlightthickness 2 \
|
||||
-highlightbackground [option get . background {}]
|
||||
label .ins.top.dir_l -text { Symbol ref: }
|
||||
entry .ins.top.dir_e -width 40 -state readonly \
|
||||
-readonlybackground [option get . background {}] -takefocus 0
|
||||
label .ins.top.ext_l -text Ext:
|
||||
entry .ins.top.ext_e -width 15 -takefocus 0 -state normal -textvariable new_symbol_browser_ext
|
||||
if {[info exists insert_symbol(regex)]} {
|
||||
.ins.top.pat_e insert 0 $insert_symbol(regex)
|
||||
}
|
||||
|
||||
bind .ins <KeyPress-Escape> {.ins.bottom.dismiss invoke}
|
||||
bind .ins <KeyRelease> "
|
||||
if {{%K} eq {Tab} && {%W} eq {.ins.center.left.l}} {
|
||||
insert_symbol_filelist [list $paths] [list $maxdepth]
|
||||
insert_symbol_preview [list $paths]
|
||||
}
|
||||
"
|
||||
bind .ins.center.left.l <<ListboxSelect>> "insert_symbol_preview [list $paths]"
|
||||
bind .ins.center.left.l <Enter> "insert_symbol_focusin [list $paths] [list $maxdepth]"
|
||||
label .ins.bottom.n -text { N. of items:}
|
||||
label .ins.bottom.nitems -textvariable insert_symbol(nitems)
|
||||
button .ins.bottom.dismiss -takefocus 0 -text Dismiss -command {
|
||||
if { [xschem get ui_state] & 8192 } {
|
||||
xschem abort_operation
|
||||
} else {
|
||||
xschem preview_window close .ins.center.right {}
|
||||
destroy .ins
|
||||
}
|
||||
}
|
||||
pack .ins.bottom.dismiss -side left
|
||||
pack .ins.bottom.n -side left
|
||||
pack .ins.bottom.nitems -side left
|
||||
pack .ins.top2.dir_l -side left
|
||||
pack .ins.top2.dir_e -side left -fill x -expand 1
|
||||
pack .ins.top.pat_l -side left
|
||||
pack .ins.top.pat_e -side left
|
||||
pack .ins.top.dir_l -side left
|
||||
pack .ins.top.dir_e -side left
|
||||
pack .ins.top.ext_l -side left
|
||||
pack .ins.top.ext_e -side left
|
||||
insert_symbol_filelist $paths $maxdepth
|
||||
# tkwait window .ins
|
||||
# xschem set semaphore [expr {[xschem get semaphore] -1}]
|
||||
return {}
|
||||
}
|
||||
#######################################################################
|
||||
##### /new alternate insert_symbol browser
|
||||
#######################################################################
|
||||
|
||||
# get last n path components: example , n=1 --> /aaa/bbb/ccc/ddd.sch -> ccc/ddd.sch
|
||||
proc get_cell {s n } {
|
||||
set slist [file split $s]
|
||||
|
|
@ -6447,12 +6722,17 @@ proc editdata {{data {}} {title {Edit data}} } {
|
|||
# wm transient $window [xschem get topwindow]
|
||||
frame $window.buttons
|
||||
pack $window.buttons -side bottom -fill x -pady 2m
|
||||
button $window.buttons.copy -text Copy -command "
|
||||
clipboard clear
|
||||
clipboard append \[$window.text get 1.0 {end - 1 chars}\]
|
||||
"
|
||||
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
|
||||
pack $window.buttons.copy -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
|
||||
|
|
@ -6567,27 +6847,39 @@ proc viewdata {data {ro {}} {win .view}} {
|
|||
return $tctx::rcode
|
||||
}
|
||||
|
||||
proc sub_match_file { f {paths {}} } {
|
||||
global pathlist match_file_dir_arr
|
||||
proc sub_match_file { f {paths {}} {maxdepth -1} } {
|
||||
global pathlist match_file_dir_arr match_file_level nolist_libs
|
||||
set res {}
|
||||
if {$paths eq {}} {set paths $pathlist}
|
||||
foreach i $paths {
|
||||
foreach j [glob -nocomplain -directory $i *] {
|
||||
# puts "--> $j $f"
|
||||
# set jj [regsub {/ $} [file normalize ${j}/\ ] {}]
|
||||
set skip 0
|
||||
foreach k $nolist_libs {
|
||||
if {[regexp $k $j]} {
|
||||
set skip 1
|
||||
break
|
||||
}
|
||||
}
|
||||
if {$skip} { continue }
|
||||
|
||||
if {[file isdirectory $j] && [file readable $j]} {
|
||||
set jj [regsub {/ $} [file normalize ${j}/\ ] {}]
|
||||
if {[array names match_file_dir_arr -exact $jj] == {}} {
|
||||
set match_file_dir_arr($jj) 1
|
||||
# puts "********** directory $jj"
|
||||
set sub_res [sub_match_file $f $j] ;# recursive call
|
||||
if {$sub_res != {} } {set res [concat $res $sub_res]}
|
||||
if { $maxdepth == -1 || $match_file_level < $maxdepth} {
|
||||
set jj [regsub {/ $} [file normalize ${j}/\ ] {}]
|
||||
# if {[array names match_file_dir_arr -exact $jj] == {}} { ... }
|
||||
if {![info exists match_file_dir_arr($jj)]} {
|
||||
set match_file_dir_arr($jj) 1
|
||||
incr match_file_level
|
||||
set sub_res [sub_match_file $f $j $maxdepth] ;# recursive call
|
||||
incr match_file_level -1
|
||||
if {$sub_res != {} } {set res [concat $res $sub_res]}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# set fname [file tail $j]
|
||||
set fname $j
|
||||
if {[regexp $f $fname]} {
|
||||
lappend res $j
|
||||
if {![info exists match_file_dir_arr($j)]} {
|
||||
set match_file_dir_arr($j) 1
|
||||
if {[regexp $f $j]} {
|
||||
lappend res $j
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6598,37 +6890,56 @@ proc sub_match_file { f {paths {}} } {
|
|||
# find files into $paths directories matching $f
|
||||
# use $pathlist global search path if $paths empty
|
||||
# recursively descend directories
|
||||
proc match_file { f {paths {}} } {
|
||||
global match_file_dir_arr
|
||||
proc match_file { f {paths {}} {maxdepth -1} } {
|
||||
global match_file_dir_arr match_file_level
|
||||
set err [catch {regexp $f {12345}} res]
|
||||
if {$err} {return {}}
|
||||
set match_file_level 0
|
||||
catch {unset match_file_dir_arr}
|
||||
set res [sub_match_file $f $paths]
|
||||
set res [sub_match_file $f $paths $maxdepth]
|
||||
catch {unset match_file_dir_arr}
|
||||
return $res
|
||||
}
|
||||
|
||||
proc sub_find_file { f {paths {}} {first 0} } {
|
||||
global pathlist match_file_dir_arr
|
||||
proc sub_find_file { f {paths {}} {first 0} {maxdepth -1}} {
|
||||
global pathlist match_file_dir_arr match_file_level nolist_libs
|
||||
set res {}
|
||||
if {$paths eq {}} {set paths $pathlist}
|
||||
foreach i $paths {
|
||||
foreach j [glob -nocomplain -directory $i *] {
|
||||
# puts "--> $j $f"
|
||||
|
||||
set skip 0
|
||||
foreach k $nolist_libs {
|
||||
if {[regexp $k $j]} {
|
||||
set skip 1
|
||||
break
|
||||
}
|
||||
}
|
||||
if {$skip} { continue }
|
||||
|
||||
if {[file isdirectory $j] && [file readable $j]} {
|
||||
set jj [regsub {/ $} [file normalize ${j}/\ ] {}]
|
||||
if {[array names match_file_dir_arr -exact $jj] == {}} {
|
||||
set match_file_dir_arr($jj) 1
|
||||
# puts "********** directory $jj"
|
||||
set sub_res [sub_find_file $f $j $first] ;# recursive call
|
||||
if {$sub_res != {} } {
|
||||
set res [concat $res $sub_res]
|
||||
if {$first} {return $res}
|
||||
if { $maxdepth == -1 || $match_file_level < $maxdepth} {
|
||||
set jj [regsub {/ $} [file normalize ${j}/\ ] {}]
|
||||
# if {[array names match_file_dir_arr -exact $jj] == {}} { ... }
|
||||
if {![info exists match_file_dir_arr($jj)]} {
|
||||
set match_file_dir_arr($jj) 1
|
||||
incr match_file_level
|
||||
set sub_res [sub_find_file $f $j $first $maxdepth] ;# recursive call
|
||||
incr match_file_level -1
|
||||
if {$sub_res != {} } {
|
||||
set res [concat $res $sub_res]
|
||||
if {$first} {return $res}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
set fname [file tail $j]
|
||||
if {$fname == $f} {
|
||||
lappend res $j
|
||||
if {$first} {return $res}
|
||||
if {![info exists match_file_dir_arr($j)]} {
|
||||
set match_file_dir_arr($j) 1
|
||||
if {$fname == $f} {
|
||||
lappend res $j
|
||||
if {$first} {return $res}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6639,10 +6950,11 @@ proc sub_find_file { f {paths {}} {first 0} } {
|
|||
# find given file $f into $paths directories
|
||||
# use $pathlist global search path if $paths empty
|
||||
# recursively descend directories
|
||||
proc find_file { f {paths {}} } {
|
||||
global match_file_dir_arr
|
||||
proc find_file { f {paths {}} {maxdepth -1}} {
|
||||
global match_file_dir_arr match_file_level
|
||||
set match_file_level 0
|
||||
catch {unset match_file_dir_arr}
|
||||
set res [sub_find_file $f $paths 0]
|
||||
set res [sub_find_file $f $paths 0 $maxdepth]
|
||||
catch {unset match_file_dir_arr}
|
||||
return $res
|
||||
}
|
||||
|
|
@ -6651,10 +6963,11 @@ proc find_file { f {paths {}} } {
|
|||
# use $pathlist global search path if $paths empty
|
||||
# recursively descend directories
|
||||
# only return FIRST FOUND
|
||||
proc find_file_first { f {paths {}} } {
|
||||
global match_file_dir_arr
|
||||
proc find_file_first { f {paths {}} {maxdepth -1}} {
|
||||
global match_file_dir_arr match_file_level
|
||||
set match_file_level 0
|
||||
catch {unset match_file_dir_arr}
|
||||
set res [sub_find_file $f $paths 1]
|
||||
set res [sub_find_file $f $paths 1 $maxdepth]
|
||||
catch {unset match_file_dir_arr}
|
||||
return $res
|
||||
}
|
||||
|
|
@ -6740,16 +7053,24 @@ proc try_download_url {dirname sch_or_sym} {
|
|||
# if file is in a library directory (a $pathlist dir)
|
||||
# Example: rel_sym_path /home/schippes/share/xschem/xschem_library/devices/iopin.sym
|
||||
# devices/iopin.sym
|
||||
proc rel_sym_path {symbol} {
|
||||
proc rel_sym_path {symbol {paths {}} } {
|
||||
global OS pathlist env
|
||||
# puts "rel_sym_path: $symbol $paths"
|
||||
|
||||
if { $paths eq {}} {set paths $pathlist}
|
||||
regsub {^~/} $symbol ${env(HOME)}/ symbol
|
||||
if {![regexp {^/} $symbol]} {
|
||||
set symbol [pwd]/$symbol
|
||||
}
|
||||
# if {$OS eq "Windows"} {
|
||||
# if {![regexp {^[A-Za-z]\:/} $symbol]} {
|
||||
# set symbol [pwd]/$symbol
|
||||
# }
|
||||
# } else {
|
||||
# if {![regexp {^/} $symbol]} {
|
||||
# set symbol [pwd]/$symbol
|
||||
# }
|
||||
# }
|
||||
set curr_dirname [pwd]
|
||||
set name {}
|
||||
foreach path_elem $pathlist {
|
||||
foreach path_elem $paths {
|
||||
if { ![string compare $path_elem .] && [info exist curr_dirname]} {
|
||||
set path_elem $curr_dirname
|
||||
}
|
||||
|
|
@ -6783,9 +7104,10 @@ proc rel_sym_path {symbol} {
|
|||
# given a symbol reference 'sym' return its absolute path
|
||||
# Example: % abs_sym_path devices/iopin.sch
|
||||
# /home/schippes/share/xschem/xschem_library/devices/iopin.sym
|
||||
proc abs_sym_path {fname {ext {} } } {
|
||||
proc abs_sym_path {fname {ext {} } {paths {}}} {
|
||||
global pathlist OS
|
||||
|
||||
if { $paths eq {}} {set paths $pathlist}
|
||||
set curr_dirname [pwd]
|
||||
## empty: do nothing
|
||||
if {$fname eq {} } return {}
|
||||
|
|
@ -6845,9 +7167,9 @@ proc abs_sym_path {fname {ext {} } } {
|
|||
## if file does not exists but directory does return anyway
|
||||
if { [file exists [file dirname "$tmpfname"]] } { return "$tmpfname" }
|
||||
}
|
||||
## if fname is present in one of the pathlist paths get the absolute path
|
||||
## if fname is present in one of the paths paths get the absolute path
|
||||
set name {}
|
||||
foreach path_elem $pathlist {
|
||||
foreach path_elem $paths {
|
||||
if { ![string compare $path_elem .] && [info exist curr_dirname]} {
|
||||
set path_elem $curr_dirname
|
||||
}
|
||||
|
|
@ -7848,42 +8170,36 @@ proc no_open_dialogs {} {
|
|||
## "file_dialog_*" only one load_file_dialog window is allowed
|
||||
|
||||
set tctx::global_list {
|
||||
PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS
|
||||
INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH
|
||||
add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow
|
||||
autotrim_wires orthogonal_wiring snap_cursor bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers
|
||||
cadsnap cadence_compat cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv
|
||||
copy_cell crosshair_layer crosshair_size cursor_2_hook snap_cursor_size custom_label_prefix custom_token
|
||||
dark_colors dark_colorscheme dark_gui_colorscheme delay_flag
|
||||
dim_bg dim_value disable_unique_names do_all_inst draw_crosshair
|
||||
draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size
|
||||
edit_symbol_prop_new_sel editprop_sympath en_hilight_conn_inst enable_dim_bg enable_stretch
|
||||
enter_text_default_geometry filetmp fix_broken_tiled_fill flat_netlist fullscreen
|
||||
gaw_fd gaw_tcp_address graph_autoload graph_bus
|
||||
graph_change_done graph_digital graph_dialog_default_geometry
|
||||
graph_legend graph_linewidth_mult graph_logx
|
||||
graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color graph_sel_wave
|
||||
graph_selected graph_sort graph_unlocked graph_use_ctrl_key
|
||||
hide_empty_graphs hide_symbols tctx::hsize
|
||||
incr_hilight incremental_select infix_interface infowindow_text intuitive_interface
|
||||
keep_symbols launcher_default_program
|
||||
light_colors line_width live_cursor2_backannotate local_netlist_dir lvs_ignore
|
||||
lvs_netlist measure_text netlist_dir netlist_show netlist_type no_ask_save
|
||||
no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes path pathlist
|
||||
persistent_command preserve_unchanged_attrs prev_symbol ps_colors ps_paper_size rainbow_colors
|
||||
tctx::rcode recentfile
|
||||
retval retval_orig rotated_text search_case search_exact search_found search_schematic
|
||||
search_select search_value select_touch selected_tok show_hidden_texts show_infowindow
|
||||
show_infowindow_after_netlist
|
||||
simconf_default_geometry simconf_vpos simulate_bg spiceprefix split_files svg_colors
|
||||
svg_font_name sym_txt symbol symbol_width tabstop tclcmd_txt tclstop text_line_default_geometry
|
||||
text_replace_selection text_tabs_setting textwindow_fileid textwindow_filename textwindow_w
|
||||
toolbar_horiz toolbar_list
|
||||
toolbar_visible top_is_subckt transparent_svg undo_type use_lab_wire unselect_partial_sel_wires
|
||||
use_label_prefix use_tclreadline
|
||||
user_wants_copy_cell verilog_2001 verilog_bitblast viewdata_fileid viewdata_filename viewdata_w
|
||||
tctx::vsize xschem_libs xschem_listen_port zoom_full_center orthogonal_wiring snap_cursor
|
||||
snap_cursor_size cadence_compat use_cursor_for_selection
|
||||
INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR PDK PDK_ROOT SKYWATER_MODELS
|
||||
SKYWATER_STDCELLS XSCHEM_LIBRARY_PATH add_all_windows_drives auto_hilight
|
||||
auto_hilight_graph_nodes autofocus_mainwindow autotrim_wires bespice_listen_port big_grid_points
|
||||
bus_replacement_char cadence_compat cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale
|
||||
change_lw color_ps compare_sch constr_mv copy_cell crosshair_layer crosshair_size cursor_2_hook
|
||||
custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag
|
||||
dim_bg dim_value disable_unique_names do_all_inst draw_crosshair draw_grid draw_grid_axes
|
||||
draw_window edit_prop_pos edit_prop_size edit_symbol_prop_new_sel editprop_sympath
|
||||
en_hilight_conn_inst enable_dim_bg enable_stretch enter_text_default_geometry filetmp
|
||||
fix_broken_tiled_fill flat_netlist fullscreen gaw_fd gaw_tcp_address graph_autoload graph_bus
|
||||
graph_change_done graph_dialog_default_geometry graph_digital graph_legend graph_linewidth_mult
|
||||
graph_logx graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color
|
||||
graph_sel_wave graph_selected graph_sort graph_unlocked graph_use_ctrl_key hide_empty_graphs
|
||||
hide_symbols incr_hilight incremental_select infix_interface infowindow_text intuitive_interface
|
||||
keep_symbols launcher_default_program light_colors line_width live_cursor2_backannotate
|
||||
local_netlist_dir lvs_ignore lvs_netlist measure_text netlist_dir netlist_show netlist_type
|
||||
new_symbol_browser new_symbol_browser_depth new_symbol_browser_ext new_symbol_browser_paths
|
||||
no_ask_save no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes
|
||||
orthogonal_wiring path pathlist persistent_command preserve_unchanged_attrs prev_symbol ps_colors
|
||||
ps_paper_size rainbow_colors recentfile retval retval_orig rotated_text search_case search_exact
|
||||
search_found search_schematic search_select search_value select_touch selected_tok
|
||||
show_hidden_texts show_infowindow show_infowindow_after_netlist simconf_default_geometry
|
||||
simconf_vpos simulate_bg snap_cursor snap_cursor_size spiceprefix split_files svg_colors
|
||||
svg_font_name sym_txt symbol symbol_width tabstop tclcmd_txt tclstop tctx::colors tctx::hsize
|
||||
tctx::rcode tctx::vsize text_line_default_geometry text_replace_selection text_tabs_setting
|
||||
textwindow_fileid textwindow_filename textwindow_w toolbar_horiz toolbar_list toolbar_visible
|
||||
top_is_subckt transparent_svg undo_type unselect_partial_sel_wires uppercase_subckt
|
||||
use_cursor_for_selection use_lab_wire use_label_prefix use_tclreadline user_wants_copy_cell
|
||||
verilog_2001 verilog_bitblast
|
||||
viewdata_fileid viewdata_filename viewdata_w xschem_libs xschem_listen_port zoom_full_center
|
||||
}
|
||||
|
||||
## list of global arrays to save/restore on context switching
|
||||
|
|
@ -8268,7 +8584,7 @@ proc load_raw {{type {}}} {
|
|||
|
||||
proc build_widgets { {topwin {} } } {
|
||||
global XSCHEM_SHAREDIR tabbed_interface simulate_bg OS sim
|
||||
global dark_gui_colorscheme draw_crosshair
|
||||
global dark_gui_colorscheme draw_crosshair grid_point_size
|
||||
global recentfile color_ps transparent_svg menu_debug_var enable_stretch
|
||||
global netlist_show flat_netlist split_files compare_sch intuitive_interface
|
||||
global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width cadence_compat
|
||||
|
|
@ -8332,7 +8648,11 @@ proc build_widgets { {topwin {} } } {
|
|||
}
|
||||
$topwin.menubar.file add command -label "Component browser" -accelerator {Shift-Ins, Ctrl-I} \
|
||||
-command {
|
||||
load_file_dialog {Insert symbol} *.sym INITIALINSTDIR 2
|
||||
if {$new_symbol_browser} {
|
||||
insert_symbol $new_symbol_browser_paths $new_symbol_browser_depth $new_symbol_browser_ext
|
||||
} else {
|
||||
load_file_dialog {Insert symbol} *.sym INITIALINSTDIR 2
|
||||
}
|
||||
}
|
||||
$topwin.menubar.file add command -label "Open" -command "xschem load" -accelerator {Ctrl+O}
|
||||
$topwin.menubar.file add command -label "Open Most Recent" \
|
||||
|
|
@ -8421,6 +8741,19 @@ proc build_widgets { {topwin {} } } {
|
|||
$topwin.menubar.option add checkbutton -label "Draw persistent snap cursor" -variable snap_cursor \
|
||||
-selectcolor $selectcolor -accelerator {Alt-Z}
|
||||
|
||||
$topwin.menubar.option add cascade -label "Crosshair" \
|
||||
-menu $topwin.menubar.option.crosshair
|
||||
menu $topwin.menubar.option.crosshair -tearoff 0
|
||||
|
||||
$topwin.menubar.option.crosshair add checkbutton -label "Draw snap cursor" \
|
||||
-variable snap_cursor -selectcolor $selectcolor
|
||||
$topwin.menubar.option.crosshair add checkbutton -label "Draw crosshair" \
|
||||
-variable draw_crosshair -selectcolor $selectcolor -accelerator {Alt-X}
|
||||
$topwin.menubar.option.crosshair add command -label "Crosshair size" \
|
||||
-command {
|
||||
input_line "Enter crosshair size (int, 0 = full screen width):" \
|
||||
"set crosshair_size" $crosshair_size
|
||||
}
|
||||
$topwin.menubar.option add command -label "Replace \[ and \] for buses in SPICE netlist" \
|
||||
-command {
|
||||
input_line "Enter two characters to replace default bus \[\] delimiters:" "set bus_replacement_char"
|
||||
|
|
@ -8601,6 +8934,10 @@ proc build_widgets { {topwin {} } } {
|
|||
set change_lw 0
|
||||
input_line "Enter linewidth (float):" "xschem line_width"
|
||||
}
|
||||
$topwin.menubar.view add command -label "Set grid point size" \
|
||||
-command {
|
||||
input_line "Enter Grid point size (int or -1: $grid_point_size)" "set grid_point_size" $grid_point_size
|
||||
}
|
||||
$topwin.menubar.view add checkbutton -label "Tabbed interface" -variable tabbed_interface \
|
||||
-selectcolor $selectcolor -command setup_tabbed_interface
|
||||
|
||||
|
|
@ -8675,6 +9012,8 @@ proc build_widgets { {topwin {} } } {
|
|||
-command "xschem net_label 0" -accelerator Alt-Shift-L
|
||||
$topwin.menubar.sym add command -label "Change selected inst. texts to floaters" \
|
||||
-command "xschem floaters_from_selected_inst"
|
||||
$topwin.menubar.sym add command -label "Unselect attached floaters" \
|
||||
-command "xschem unselect_attached_floaters"
|
||||
$topwin.menubar.sym add command -label "Print list of highlight nets" \
|
||||
-command "xschem print_hilight_net 1" -accelerator J
|
||||
$topwin.menubar.sym add command -label "Print list of highlight nets, with buses expanded" \
|
||||
|
|
@ -8834,7 +9173,7 @@ proc build_widgets { {topwin {} } } {
|
|||
-selectcolor $selectcolor -variable auto_hilight_graph_nodes
|
||||
$topwin.menubar.simulation.graph add command -label {Add waveform graph} -command {xschem add_graph}
|
||||
$topwin.menubar.simulation.graph add command -label {Add waveform reload launcher} -command {
|
||||
xschem place_symbol [rel_sym_path [find_file_first launcher.sym]] "name=h5\ndescr=\"load waves\"
|
||||
xschem place_symbol [find_file_first launcher.sym] "name=h5\ndescr=\"load waves\"
|
||||
tclcommand=\"xschem raw_read \$netlist_dir/[file tail [file rootname [xschem get current_name]]].raw tran\"
|
||||
"
|
||||
}
|
||||
|
|
@ -8864,7 +9203,8 @@ tclcommand=\"xschem raw_read \$netlist_dir/[file tail [file rootname [xschem get
|
|||
xschem set format {}
|
||||
}
|
||||
}
|
||||
|
||||
$topwin.menubar.simulation.lvs add checkbutton -label "Upper case .SUBCKT and .ENDS" \
|
||||
-selectcolor $selectcolor -variable uppercase_subckt
|
||||
$topwin.menubar.simulation.lvs add checkbutton -label "Top level is a .subckt" \
|
||||
-selectcolor $selectcolor -variable top_is_subckt
|
||||
|
||||
|
|
@ -8947,12 +9287,27 @@ proc trace_set_paths {varname idxname op} {
|
|||
uplevel #0 set_paths
|
||||
}
|
||||
}
|
||||
proc cleanup_paths {paths} {
|
||||
global env
|
||||
set pathlist {}
|
||||
foreach i $paths {
|
||||
regsub {^~$} $i ${env(HOME)} i
|
||||
regsub {^~/} $i ${env(HOME)}/ i
|
||||
if { ![string compare $i .] } {
|
||||
lappend pathlist $i
|
||||
} elseif { [ regexp {\.\.\/} $i] } {
|
||||
lappend pathlist [file normalize $i]
|
||||
} elseif { [ file exists $i] } {
|
||||
lappend pathlist $i
|
||||
}
|
||||
}
|
||||
return $pathlist
|
||||
}
|
||||
|
||||
# when XSCHEM_LIBRARY_PATH is changed call this function to refresh and cache
|
||||
# new library search path.
|
||||
proc set_paths {} {
|
||||
global XSCHEM_LIBRARY_PATH env pathlist OS add_all_windows_drives file_dialog_names1
|
||||
set pathlist {}
|
||||
global XSCHEM_LIBRARY_PATH pathlist OS add_all_windows_drives
|
||||
# puts stderr "caching search paths"
|
||||
if { [info exists XSCHEM_LIBRARY_PATH] } {
|
||||
if {$OS == "Windows"} {
|
||||
|
|
@ -8966,17 +9321,8 @@ proc set_paths {} {
|
|||
} else {
|
||||
set pathlist_orig [split $XSCHEM_LIBRARY_PATH :]
|
||||
}
|
||||
foreach i $pathlist_orig {
|
||||
regsub {^~$} $i ${env(HOME)} i
|
||||
regsub {^~/} $i ${env(HOME)}/ i
|
||||
if { ![string compare $i .] } {
|
||||
lappend pathlist $i
|
||||
} elseif { [ regexp {\.\.\/} $i] } {
|
||||
lappend pathlist [file normalize $i]
|
||||
} elseif { [ file exists $i] } {
|
||||
lappend pathlist $i
|
||||
}
|
||||
}
|
||||
|
||||
set pathlist [cleanup_paths $pathlist_orig]
|
||||
}
|
||||
if {$pathlist eq {}} { set pathlist [pwd] }
|
||||
set_initial_dirs
|
||||
|
|
@ -9067,6 +9413,15 @@ proc source_user_tcl_files {} {
|
|||
}
|
||||
}
|
||||
|
||||
proc eval_user_startup_commands {} {
|
||||
global user_startup_commands
|
||||
if {[info exists user_startup_commands]} {
|
||||
if {[catch {uplevel #0 $user_startup_commands} res]} {
|
||||
puts "executing $user_startup_commands:\n\n$res"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc eval_postinit_commands {} {
|
||||
global postinit_commands
|
||||
if {[info exists postinit_commands]} {
|
||||
|
|
@ -9296,6 +9651,7 @@ set_ne local_netlist_dir 0 ;# if set use <sch_dir>/simulation for netlist and si
|
|||
set_ne bus_replacement_char {} ;# use {<>} to replace [] with <> in bussed signals
|
||||
set_ne lvs_netlist 0
|
||||
set_ne top_is_subckt 0
|
||||
set_ne uppercase_subckt 0
|
||||
set_ne lvs_ignore 0
|
||||
set_ne hide_empty_graphs 0 ;# if set to 1 waveform boxes will be hidden if no raw file loaded
|
||||
set_ne graph_use_ctrl_key 0;# if set forces to use Control key to operate on graphs
|
||||
|
|
@ -9331,6 +9687,7 @@ set_ne enable_stretch 0
|
|||
set_ne constr_mv 0
|
||||
set_ne unselect_partial_sel_wires 0
|
||||
set_ne load_file_dialog_fullpath 1
|
||||
set_ne file_dialog_others {} ;# contains 2nd, 3rd, ... selected filenames on mult. selections in load file
|
||||
|
||||
# if set show selected elements while dragging the selection rectangle.
|
||||
# once selected these can not be unselected by retracting the selection rectangle
|
||||
|
|
@ -9340,6 +9697,7 @@ set_ne select_touch 1
|
|||
|
||||
set_ne draw_grid 1
|
||||
set_ne big_grid_points 0
|
||||
set_ne grid_point_size -1 ;# grid point size (>=0) or unspecified (-1)
|
||||
set_ne draw_grid_axes 1
|
||||
set_ne persistent_command 0
|
||||
set_ne intuitive_interface 1
|
||||
|
|
@ -9399,6 +9757,12 @@ set_ne tabbed_interface 1
|
|||
## case insensitive symbol lookup (on case insensitive filesystems only!)
|
||||
set_ne case_insensitive 0
|
||||
|
||||
## New alternate symbol placement browser (default: not enabled).
|
||||
set_ne new_symbol_browser 0
|
||||
set_ne new_symbol_browser_paths {} ;# if empty use xschem search paths
|
||||
set_ne new_symbol_browser_depth 2 ;# depth to descend into each dir of the search paths
|
||||
set_ne new_symbol_browser_ext {\.(sym|tcl)$} ;# file extensions (a regex) to look for
|
||||
|
||||
set_ne file_dialog_ext {*}
|
||||
|
||||
## remember edit_prop widget size
|
||||
|
|
|
|||
27
src/xschemrc
27
src/xschemrc
|
|
@ -295,6 +295,9 @@
|
|||
#### enable to scale grid point size as done with lines at close zoom, default: 0
|
||||
# set big_grid_points 0
|
||||
|
||||
#### explicitly set grid point size in pixels. Default: -1 (not set)
|
||||
# set grid_point_size 2
|
||||
|
||||
#### enable drawing grid axes. Default: enabled (1)
|
||||
# set draw_grid_axes 1
|
||||
|
||||
|
|
@ -543,6 +546,17 @@
|
|||
# }
|
||||
# }
|
||||
|
||||
###########################################################################
|
||||
#### TCL COMMANDS TO BE EXECUTED AFTER ANY NEW WINDOW CREATION
|
||||
###########################################################################
|
||||
#### this hook is useful to execute user UI code (like event binding,
|
||||
#### new buttons / menu entries etc).
|
||||
# set user_startup_commands {
|
||||
# bind [xschem get current_win_path] <Key-plus> {
|
||||
# puts Hello
|
||||
# }
|
||||
# }
|
||||
|
||||
###########################################################################
|
||||
#### TCL COMMANDS TO BE EXECUTED AFTER GENERATING NETLIST
|
||||
###########################################################################
|
||||
|
|
@ -569,6 +583,19 @@
|
|||
#### or tab is open.
|
||||
# set tabbed_interface 0
|
||||
|
||||
###########################################################################
|
||||
#### ALTERNATE SYMBOL PLACEMENT BROWSER
|
||||
###########################################################################
|
||||
#### uses a new symbol placement widget. Default: not enabled (0)
|
||||
# set new_symbol_browser 1
|
||||
#### defines a list of paths to search for. If empty uses all xschem
|
||||
#### XSCHEM_LIBRARY_PATH paths
|
||||
# set new_symbol_browser_paths [list ... ... ... ]
|
||||
#### defines the depth to descend into each path. default: 2
|
||||
# set new_symbol_browser_depth 3
|
||||
#### defines the extensions to search for. Default: {\.(sym|tcl)$}
|
||||
# set new_symbol_browser_ext {\.(sch|sym|tcl)$}
|
||||
|
||||
###########################################################################
|
||||
#### CASE INSENSITIVE SYMBOL LOOKUP
|
||||
###########################################################################
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
v {xschem version=3.4.6 file_version=1.2
|
||||
*
|
||||
* This file is part of XSCHEM,
|
||||
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
|
||||
* simulation.
|
||||
* Copyright (C) 1998-2024 Stefan Frederik Schippers
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
}
|
||||
G {}
|
||||
K {type=scope
|
||||
template="name=l1"
|
||||
highlight=true}
|
||||
V {}
|
||||
S {}
|
||||
E {}
|
||||
L 4 0 0 10 -20 {}
|
||||
B 5 -1.25 -1.25 1.25 1.25 {name=p dir=in}
|
||||
P 4 5 10 -20 10 -140 140 -140 140 -20 10 -20 {}
|
||||
T {@#0:net_name} 12.5 -18.125 0 0 0.2 0.2 {layer=4}
|
||||
T {@#0:spice_get_voltage} 12.5 -139.375 0 0 0.15 0.15 {layer=15}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
v {xschem version=3.4.6 file_version=1.2
|
||||
*
|
||||
* This file is part of XSCHEM,
|
||||
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
|
||||
* simulation.
|
||||
* Copyright (C) 1998-2024 Stefan Frederik Schippers
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
}
|
||||
G {}
|
||||
K {type=scope
|
||||
template="name=l1"
|
||||
highlight=true}
|
||||
V {}
|
||||
S {}
|
||||
E {}
|
||||
L 4 0 0 10 -20 {}
|
||||
L 4 0 -160 10 -140 {}
|
||||
B 5 -1.25 -161.25 1.25 -158.75 {name=p dir=in}
|
||||
B 5 -1.25 -1.25 1.25 1.25 {name=m dir=in}
|
||||
P 4 5 10 -20 10 -140 140 -140 140 -20 10 -20 {}
|
||||
T {@#1:net_name} 12.5 -18.125 0 0 0.2 0.2 {layer=4}
|
||||
T {@#0:net_name} 12.5 -153.125 0 0 0.2 0.2 {layer=4}
|
||||
T {@spice_get_diff_voltage} 12.5 -139.375 0 0 0.15 0.15 {layer=15}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
v {xschem version=3.4.6 file_version=1.2
|
||||
*
|
||||
* This file is part of XSCHEM,
|
||||
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
|
||||
* simulation.
|
||||
* Copyright (C) 1998-2024 Stefan Frederik Schippers
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
}
|
||||
G {}
|
||||
K {type=scope
|
||||
template="name=l1"
|
||||
highlight=true}
|
||||
V {}
|
||||
S {}
|
||||
E {}
|
||||
P 4 5 10 -20 10 -140 140 -140 140 -20 10 -20 {}
|
||||
T {@device} 12.5 -18.125 0 0 0.2 0.2 {layer=4}
|
||||
T {tcleval(@spice_get_node [xschem get_fqdevice @device ] )} 12.5 -139.375 0 0 0.15 0.15 {layer=17}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
v {xschem version=3.4.6RC file_version=1.2
|
||||
v {xschem version=3.4.6 file_version=1.2
|
||||
*
|
||||
* This file is part of XSCHEM,
|
||||
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
|
||||
|
|
@ -24,6 +24,15 @@ K {}
|
|||
V {}
|
||||
S {}
|
||||
E {}
|
||||
B 2 520 -415 630 -315 {name=l4
|
||||
flags=graph,unlocked
|
||||
lock=1
|
||||
color=8
|
||||
node="tcleval([xschem get_fqdevice [xschem translate l4 @device]])"
|
||||
y1=-0.00014
|
||||
y2=0.00013
|
||||
x1=0.00044464632
|
||||
x2=0.00046163671}
|
||||
T {( @#0:resolved_net )} 440 -265 0 1 0.2 0.2 {name=l2 layer=15}
|
||||
T {( @#0:resolved_net )} 100 -285 0 1 0.2 0.2 {name=p1 layer=15}
|
||||
T {( @#0:resolved_net )} 100 -235 0 1 0.2 0.2 {name=p2 layer=15}
|
||||
|
|
@ -49,3 +58,6 @@ m=1}
|
|||
C {parax_cap.sym} 630 -230 0 0 {name=C3 gnd=0 value=\{COUT\} m=1}
|
||||
C {vsource.sym} 150 -260 1 0 {name=V1 value=0}
|
||||
C {vsource.sym} 150 -210 1 0 {name=V2 value=0}
|
||||
C {scope_ammeter.sym} 500 -290 0 0 {name=l4
|
||||
attach=l4
|
||||
device=R1}
|
||||
|
|
|
|||
|
|
@ -26,34 +26,34 @@ K {}
|
|||
V {}
|
||||
S {}
|
||||
E {}
|
||||
L 2 105 -1005 105 -775 {}
|
||||
L 2 145 -1005 145 -775 {}
|
||||
L 2 185 -1005 185 -775 {}
|
||||
L 2 225 -1005 225 -775 {}
|
||||
L 2 265 -1005 265 -775 {}
|
||||
L 2 305 -1005 305 -775 {}
|
||||
L 2 345 -1005 345 -775 {}
|
||||
L 2 385 -1005 385 -775 {}
|
||||
L 2 65 -975 395 -975 {}
|
||||
L 2 65 -935 395 -935 {}
|
||||
L 2 65 -895 395 -895 {}
|
||||
L 2 65 -855 395 -855 {}
|
||||
L 2 65 -815 395 -815 {}
|
||||
L 4 65 -1015 65 -755 {}
|
||||
L 4 55 -775 405 -775 {}
|
||||
L 4 105 -775 105 -765 {}
|
||||
L 4 145 -775 145 -765 {}
|
||||
L 4 185 -775 185 -765 {}
|
||||
L 4 225 -775 225 -765 {}
|
||||
L 4 265 -775 265 -765 {}
|
||||
L 4 305 -775 305 -765 {}
|
||||
L 4 345 -775 345 -765 {}
|
||||
L 4 385 -775 385 -765 {}
|
||||
L 4 55 -815 65 -815 {}
|
||||
L 4 55 -855 65 -855 {}
|
||||
L 4 55 -895 65 -895 {}
|
||||
L 4 55 -935 65 -935 {}
|
||||
L 4 55 -975 65 -975 {}
|
||||
L 2 95 -1105 95 -875 {}
|
||||
L 2 135 -1105 135 -875 {}
|
||||
L 2 175 -1105 175 -875 {}
|
||||
L 2 215 -1105 215 -875 {}
|
||||
L 2 255 -1105 255 -875 {}
|
||||
L 2 295 -1105 295 -875 {}
|
||||
L 2 335 -1105 335 -875 {}
|
||||
L 2 375 -1105 375 -875 {}
|
||||
L 2 55 -1075 385 -1075 {}
|
||||
L 2 55 -1035 385 -1035 {}
|
||||
L 2 55 -995 385 -995 {}
|
||||
L 2 55 -955 385 -955 {}
|
||||
L 2 55 -915 385 -915 {}
|
||||
L 4 55 -1115 55 -855 {}
|
||||
L 4 45 -875 395 -875 {}
|
||||
L 4 95 -875 95 -865 {}
|
||||
L 4 135 -875 135 -865 {}
|
||||
L 4 175 -875 175 -865 {}
|
||||
L 4 215 -875 215 -865 {}
|
||||
L 4 255 -875 255 -865 {}
|
||||
L 4 295 -875 295 -865 {}
|
||||
L 4 335 -875 335 -865 {}
|
||||
L 4 375 -875 375 -865 {}
|
||||
L 4 45 -915 55 -915 {}
|
||||
L 4 45 -955 55 -955 {}
|
||||
L 4 45 -995 55 -995 {}
|
||||
L 4 45 -1035 55 -1035 {}
|
||||
L 4 45 -1075 55 -1075 {}
|
||||
L 4 610 -1100 630 -1140 {}
|
||||
L 4 630 -1140 650 -1100 {}
|
||||
L 4 650 -1100 670 -1140 {}
|
||||
|
|
@ -83,13 +83,13 @@ L 4 960 -340 970 -340 {}
|
|||
L 4 960 -340 970 -330 {}
|
||||
L 4 970 -330 980 -340 {}
|
||||
L 4 970 -340 980 -340 {}
|
||||
B 2 1260 -560 1680 -390 {flags=graph
|
||||
B 2 1370 -555 1790 -385 {flags=graph
|
||||
y1 = -0.00068
|
||||
y2 = 22
|
||||
divy = 6
|
||||
subdivy=1
|
||||
x1=2.9358714e-05
|
||||
x2=0.0010293582
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
divx=8
|
||||
node="PANEL
|
||||
LED" unitx=m
|
||||
|
|
@ -104,13 +104,13 @@ autoload=0
|
|||
|
||||
sim_type=tran
|
||||
xrawfile=$netlist_dir/solar_panel.raw}
|
||||
B 2 1260 -390 1680 -220 {flags=graph
|
||||
B 2 1370 -385 1790 -215 {flags=graph
|
||||
y1 = -0.0012
|
||||
y2 = 6.8
|
||||
divy = 4
|
||||
subdivy=1
|
||||
x1=2.9358714e-05
|
||||
x2=0.0010293582
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
divx=8
|
||||
unitx=m
|
||||
color="7 4 6"
|
||||
|
|
@ -123,13 +123,13 @@ autoload=0
|
|||
|
||||
sim_type=tran
|
||||
xrawfile=$netlist_dir/solar_panel.raw}
|
||||
B 2 1260 -750 1680 -560 {flags=graph
|
||||
B 2 1370 -745 1790 -555 {flags=graph
|
||||
y1 = -2.7e-05
|
||||
y2 = 100
|
||||
divy = 5
|
||||
subdivy=1
|
||||
x1=2.9358714e-05
|
||||
x2=0.0010293582
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
divx=9
|
||||
|
||||
unitx=m subdivx=4
|
||||
|
|
@ -146,13 +146,13 @@ autoload=0
|
|||
|
||||
sim_type=tran
|
||||
xrawfile=$netlist_dir/solar_panel.raw}
|
||||
B 2 1260 -940 1680 -750 {flags=graph
|
||||
B 2 1370 -935 1790 -745 {flags=graph
|
||||
y1 = 0
|
||||
y2 = 1
|
||||
divy = 5
|
||||
subdivy=1
|
||||
x1=2.9358714e-05
|
||||
x2=0.0010293582
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
divx=9
|
||||
|
||||
unitx=u subdivx=4
|
||||
|
|
@ -169,13 +169,13 @@ autoload=0
|
|||
|
||||
sim_type=tran
|
||||
xrawfile=$netlist_dir/solar_panel.raw}
|
||||
B 2 1260 -1140 1680 -950 {flags=graph
|
||||
B 2 1370 -1135 1790 -945 {flags=graph
|
||||
y1 = 0
|
||||
y2 = 1
|
||||
divy = 5
|
||||
subdivy=1
|
||||
x1=2.9358714e-05
|
||||
x2=0.0010293582
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
divx=9
|
||||
|
||||
unitx=u subdivx=4
|
||||
|
|
@ -193,29 +193,65 @@ autoload=0
|
|||
|
||||
sim_type=tran
|
||||
xrawfile=$netlist_dir/solar_panel.raw}
|
||||
B 18 65 -960 320 -775 {}
|
||||
A 5 320 -960 5.590169943749475 243.434948822922 360 {fill=true}
|
||||
P 7 6 395 -775 340 -931.25 335 -945 322.5 -960 310 -965 65 -975 {}
|
||||
T {2x10 1W white LED} 1240 -200 0 0 0.4 0.4 {layer=8}
|
||||
T {2xseries 1W white LEDs} 1220 -140 0 0 0.4 0.4 {}
|
||||
T {2.5} 95 -755 0 0 0.2 0.2 {}
|
||||
T {5.0} 135 -755 0 0 0.2 0.2 {}
|
||||
T {7.5} 175 -755 0 0 0.2 0.2 {}
|
||||
T {10.0} 215 -755 0 0 0.2 0.2 {}
|
||||
T {12.5} 255 -755 0 0 0.2 0.2 {}
|
||||
T {15.0} 295 -755 0 0 0.2 0.2 {}
|
||||
T {17.5} 335 -755 0 0 0.2 0.2 {}
|
||||
T {20.0} 375 -755 0 0 0.2 0.2 {}
|
||||
T {2.5} 35 -980 0 0 0.2 0.2 {}
|
||||
T {2.0} 35 -940 0 0 0.2 0.2 {}
|
||||
T {1.5} 35 -895 0 0 0.2 0.2 {}
|
||||
T {1.0} 35 -860 0 0 0.2 0.2 {}
|
||||
T {0.5} 35 -820 0 0 0.2 0.2 {}
|
||||
T {25C, 1000W/m2} 190 -1030 0 0 0.2 0.2 {}
|
||||
T {V} 410 -765 0 0 0.4 0.4 {}
|
||||
T {I} 40 -1020 0 0 0.4 0.4 {}
|
||||
T {SOLAR PANEL} 145 -1055 0 0 0.4 0.4 {}
|
||||
T {Maximum Power} 307.5 -980 0 0 0.2 0.2 {layer=8}
|
||||
B 2 1210 -605 1320 -505 {name=l21
|
||||
flags=graph,unlocked
|
||||
lock=1
|
||||
color=8
|
||||
node="tcleval([xschem translate l21 @#0:net_name] [xschem translate l21 @#1:net_name] -)"
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
y1=-4.8
|
||||
y2=15}
|
||||
B 2 400 -735 510 -635 {name=l22
|
||||
flags=graph,unlocked
|
||||
lock=1
|
||||
color=8
|
||||
node="tcleval([xschem translate l22 @#0:net_name])"
|
||||
y1=0.00033
|
||||
y2=21
|
||||
x1=5e-10
|
||||
x2=0.001}
|
||||
B 2 600 -485 710 -385 {name=l23
|
||||
flags=graph,unlocked
|
||||
lock=1
|
||||
color=8
|
||||
node="tcleval([xschem get_fqdevice [xschem translate l23 @device]])"
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
y1=-2.9
|
||||
y2=6.8}
|
||||
B 2 640 -295 750 -195 {name=l26
|
||||
flags=graph,unlocked
|
||||
lock=1
|
||||
color=8
|
||||
node="tcleval([xschem get_fqdevice [xschem translate l26 @device]])"
|
||||
x1=5e-10
|
||||
x2=0.001
|
||||
y1=-2.9
|
||||
y2=6.8}
|
||||
B 18 55 -1060 310 -875 {}
|
||||
A 5 310 -1060 5.590169943749475 243.434948822922 360 {fill=true}
|
||||
P 7 6 385 -875 330 -1031.25 325 -1045 312.5 -1060 300 -1065 55 -1075 {}
|
||||
T {2x10 1W white LED} 1350 -195 0 0 0.4 0.4 {layer=8}
|
||||
T {2xseries 1W white LEDs} 1330 -135 0 0 0.4 0.4 {}
|
||||
T {2.5} 85 -855 0 0 0.2 0.2 {}
|
||||
T {5.0} 125 -855 0 0 0.2 0.2 {}
|
||||
T {7.5} 165 -855 0 0 0.2 0.2 {}
|
||||
T {10.0} 205 -855 0 0 0.2 0.2 {}
|
||||
T {12.5} 245 -855 0 0 0.2 0.2 {}
|
||||
T {15.0} 285 -855 0 0 0.2 0.2 {}
|
||||
T {17.5} 325 -855 0 0 0.2 0.2 {}
|
||||
T {20.0} 365 -855 0 0 0.2 0.2 {}
|
||||
T {2.5} 25 -1080 0 0 0.2 0.2 {}
|
||||
T {2.0} 25 -1040 0 0 0.2 0.2 {}
|
||||
T {1.5} 25 -995 0 0 0.2 0.2 {}
|
||||
T {1.0} 25 -960 0 0 0.2 0.2 {}
|
||||
T {0.5} 25 -920 0 0 0.2 0.2 {}
|
||||
T {25C, 1000W/m2} 180 -1130 0 0 0.2 0.2 {}
|
||||
T {V} 400 -865 0 0 0.4 0.4 {}
|
||||
T {I} 30 -1120 0 0 0.4 0.4 {}
|
||||
T {SOLAR PANEL} 135 -1155 0 0 0.4 0.4 {}
|
||||
T {Maximum Power} 297.5 -1080 0 0 0.2 0.2 {layer=8}
|
||||
T {set between 0 and 1
|
||||
to simulate
|
||||
sun radiation
|
||||
|
|
@ -232,21 +268,21 @@ T {Floater text
|
|||
example} 870 -440 0 0 0.4 0.4 {}
|
||||
T {@spice_get_current} 875 -598.75 0 0 0.3 0.3 {layer=7 name=L2}
|
||||
T {@spice_get_current} 1015 -268.75 0 0 0.3 0.3 {layer=7 name=C1}
|
||||
N 1010 -210 1100 -210 {lab=0}
|
||||
N 1100 -300 1100 -210 {lab=0}
|
||||
N 1010 -180 1100 -180 {lab=0}
|
||||
N 1100 -300 1100 -180 {lab=0}
|
||||
N 640 -610 730 -610 {lab=#net1}
|
||||
N 1010 -440 1040 -440 {lab=VO}
|
||||
N 1010 -440 1010 -310 {lab=VO}
|
||||
N 1010 -250 1010 -210 {lab=0}
|
||||
N 530 -610 580 -610 {lab=PANEL}
|
||||
N 1010 -250 1010 -180 {lab=0}
|
||||
N 360 -610 580 -610 {lab=PANEL}
|
||||
N 1010 -610 1010 -440 {lab=VO}
|
||||
N 820 -610 860 -610 {lab=SW}
|
||||
N 820 -610 820 -490 {lab=SW}
|
||||
N 790 -610 820 -610 {lab=SW}
|
||||
N 820 -210 1010 -210 {lab=0}
|
||||
N 800 -210 820 -210 {lab=0}
|
||||
N 820 -180 1010 -180 {lab=0}
|
||||
N 800 -180 820 -180 {lab=0}
|
||||
N 1000 -610 1010 -610 {lab=VO}
|
||||
N 1100 -440 1140 -440 {lab=LED}
|
||||
N 1100 -440 1280 -440 {lab=LED}
|
||||
N 1100 -440 1100 -360 {lab=LED}
|
||||
N 820 -430 820 -390 { lab=#net2}
|
||||
N 920 -610 940 -610 { lab=#net3}
|
||||
|
|
@ -295,12 +331,14 @@ N 770 -1080 770 -1030 {
|
|||
lab=TRIANG}
|
||||
N 770 -1030 890 -1030 {
|
||||
lab=TRIANG}
|
||||
N 820 -330 820 -210 {
|
||||
N 820 -330 820 -180 {
|
||||
lab=0}
|
||||
N 1190 -480 1190 -440 {lab=LED}
|
||||
N 1190 -670 1190 -640 {lab=PANEL}
|
||||
C {title.sym} 160 -40 0 0 {name=l1 author="Stefan Schippers"}
|
||||
C {code_shown.sym} 170 -310 0 0 {name=CONTROL
|
||||
C {code_shown.sym} 180 -310 0 0 {name=CONTROL
|
||||
value="tcleval(
|
||||
.probe alli
|
||||
.option savecurrents
|
||||
.control
|
||||
* example of tcl evaluation of code blocks:
|
||||
* current path: $path
|
||||
|
|
@ -318,24 +356,26 @@ C {code.sym} 20 -240 0 0 {name=MODELS value=".MODEL DIODE D(IS=1.139e-08 RS=0.99
|
|||
.MODEL swmod SW(VT=0.5 VH=0.01 RON=0.01 ROFF=10000000)
|
||||
"}
|
||||
C {lab_pin.sym} 650 -530 0 1 {name=l4 lab=PANEL }
|
||||
C {lab_pin.sym} 800 -210 0 0 {name=l6 lab=0 }
|
||||
C {lab_pin.sym} 800 -180 0 0 {name=l6 lab=0 }
|
||||
C {ammeter.sym} 1070 -440 3 0 {name=Vled}
|
||||
C {ind.sym} 890 -610 3 1 {name=L2
|
||||
m=1
|
||||
value=40u
|
||||
footprint=1206
|
||||
device=inductor
|
||||
hide_texts=true}
|
||||
C {lab_pin.sym} 1140 -440 0 1 {name=l7 lab=LED }
|
||||
hide_texts=true
|
||||
attach=L2}
|
||||
C {lab_pin.sym} 1280 -440 0 1 {name=l7 lab=LED }
|
||||
C {lab_pin.sym} 820 -550 0 1 {name=l9 lab=SW }
|
||||
C {capa.sym} 1010 -280 0 0 {name=C1
|
||||
m=1
|
||||
value=500n
|
||||
footprint=1206
|
||||
device="ceramic capacitor"
|
||||
hide_texts=true}
|
||||
hide_texts=true
|
||||
attach=C1}
|
||||
C {lab_pin.sym} 1010 -400 0 1 {name=l10 lab=VO }
|
||||
C {lab_pin.sym} 530 -610 0 0 {name=l3 lab=PANEL }
|
||||
C {lab_pin.sym} 360 -610 0 0 {name=l3 lab=PANEL }
|
||||
C {ammeter.sym} 970 -610 3 0 {name=Vind}
|
||||
C {isource_table.sym} 1100 -330 0 0 {name=G2[9..0] CTRL="V(LED)" TABLE="
|
||||
+ (0, 0)
|
||||
|
|
@ -403,3 +443,15 @@ C {spice_probe.sym} 850 -1030 0 1 {name=p4 analysis=tran}
|
|||
C {spice_probe.sym} 810 -890 0 1 {name=p5 analysis=tran}
|
||||
C {spice_probe.sym} 760 -670 0 0 {name=p6 analysis=tran}
|
||||
C {spice_probe.sym} 160 -450 0 0 {name=p7 analysis=tran}
|
||||
C {lab_show.sym} 440 -610 2 0 {name=l24}
|
||||
C {lab_pin.sym} 1190 -670 0 0 {name=l25 lab=PANEL }
|
||||
C {scope2.sym} 1190 -480 0 0 {name=l21
|
||||
attach=l21}
|
||||
C {scope.sym} 380 -610 0 0 {name=l22
|
||||
attach=l22}
|
||||
C {scope_ammeter.sym} 580 -360 0 0 {name=l23
|
||||
attach=l23
|
||||
device=Vcap}
|
||||
C {scope_ammeter.sym} 620 -170 0 0 {name=l26
|
||||
attach=l26
|
||||
device=Vdiode}
|
||||
|
|
|
|||
Loading…
Reference in New Issue