1 # file: .../tcl-lib/snacced.tcl
3 # $Header: /cvs/root/Security/SecuritySNACCRuntime/tcl-lib/Attic/snacced.tcl,v 1.1.1.1 2001/05/18 23:14:11 mb Exp $
4 # $Log: snacced.tcl,v $
5 # Revision 1.1.1.1 2001/05/18 23:14:11 mb
6 # Move from private repository to open source repository
8 # Revision 1.1.1.1 1999/03/16 18:06:56 aram
9 # Originals from SMIME Free Library.
11 # Revision 1.2 1997/02/28 13:39:57 wan
12 # Modifications collected for new version 1.3: Bug fixes, tk4.2.
14 # Revision 1.1 1997/01/01 23:12:00 rj
19 # int, enum and bit string editors with scrollbar
21 #\[banner "initialization"]---------------------------------------------------------------------------------------------------------
25 #tk colormodel . monochrome
27 # check all types whether they were marked as PDU.
28 # collect them in an associative array (indexed by module name)
29 foreach t
[snacc types
] \
31 if {[lindex [snacc type
$t] 1] == {pdu
}} \
33 set module
[lindex $t 0]
34 set type
[lindex $t 1]
35 lappend pdus
($module) $type
39 #foreach n [array names pdus] \
41 # debug "module $n: $pdus($n)"
44 #\[banner "debugging aid"]----------------------------------------------------------------------------------------------------------
51 if $debug {puts $text}
54 #\[banner "help texts"]-------------------------------------------------------------------------------------------------------------
56 set helptext
(about
) "SnaccEd $version"
58 set helptext
(manoeuv
) \
61 show/hide subnodes (except for lists)
63 perform action (selected with button 3's popup)
67 open/close value editor
68 on canvas, list or text
75 select action mode (for button 1)
77 pops up menu for text import/export
80 #\[banner "File loading and saving"]------------------------------------------------------------------------------------------------
82 # called from file_reload and file_load_from
83 # clears the display so that only the file's root gets shown
84 proc file_prune
{fileref
} \
86 upvar #0 $fileref file
89 set handle
$file(handle
)
91 list_cleanup
/$handle $handle
94 ed_addnode
$tree {} {} {} $handle $handle valid
98 # this function is called from the "File" menu.
99 # it reloads the file contents from its old origin:
100 proc file_reload
{fileref
} \
103 upvar #0 $fileref file
104 # file_prune must be called before the snacc object is modified:
106 $file(toplevel) config
-cursor watch
108 if {[catch {snacc
read $file(handle
)} msg
]} \
110 tk_dialog .d
load "Couldn't reload: $msg" warning
0 Dismiss
117 $file(toplevel) config
-cursor arrow
121 # this function is called from the "File" menu.
122 # it lets the user select a file and loads its contents
123 proc file_load_from
{fileref
} \
126 upvar #0 $fileref file
127 if {[selbox fn ct
]} \
129 # file_prune must be called before the snacc object is modified:
131 $file(toplevel) config
-cursor watch
133 if {[catch {snacc
read $file(handle
) $ct $fn} msg
]} \
135 tk_dialog .d
load "Couldn't load $fn: $msg" warning
0 Dismiss
142 $file(toplevel) config
-cursor arrow
147 # this function is called from the "File" menu.
148 # it saves the file contents to its old origin:
149 proc file_save
{fileref
} \
152 upvar #0 $fileref file
153 $file(toplevel) config
-cursor watch
155 if {[catch {snacc write
$file(handle
)} msg
]} \
157 tk_dialog .d save
"Couldn't save: $msg" warning
0 Dismiss
164 $file(toplevel) config
-cursor arrow
168 # this function is called from the "File" menu.
169 # it lets the user select a file and saves the file's contents
170 proc file_save_as
{fileref
} \
173 upvar #0 $fileref file
174 if {[selbox fn
{}]} \
176 $file(toplevel) config
-cursor watch
178 if {[catch {snacc write
$file(handle
) $fn} msg
]} \
180 tk_dialog .d save
"Couldn't save $fn: $msg" warning
0 Dismiss
187 $file(toplevel) config
-cursor arrow
192 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
193 # this function is called from prune_or_add_children, list_click, new_choice, toggle_se* and set_or_add_root
194 # it adds the node's children to the display
195 # some of the children may already be displayed (this is usually the case when the function gets called from list_click or set_or_add_root).
196 # ed_addnode will be called for every child.
198 proc ed_expand
{tree treepath snaccpath
} \
200 set canvas [$tree canvas]
202 set info [snacc
info $snaccpath]
203 set type
[lindex $info 2]
211 foreach elem
[lindex $info 3] \
213 set name
[lindex $elem 0]
214 set validity
[lindex $elem 1]
215 debug
" $validity $name"
216 ed_addnode
$tree $treepath $treepath $snaccpath $name $name $validity
222 set len
[lindex $info 3]
223 set varname var
:$treepath
224 upvar #0 $varname var
225 debug
[list treepath
=$treepath]
226 debug
[list varname
=$varname]
227 debug
[list idlist
=$var(idlist
)]
228 debug
[list expand
list ($type) len
=$len]
229 for {set i
0} {$i < $len} {incr i
} \
231 set id
[lindex $var(idlist
) $i]
232 debug
[list index
$i id
$id]
235 ed_addnode
$tree $treepath $treepath $snaccpath $id $i valid
241 set name
[lindex $info 3]
242 set validity
[lindex $info 4]
243 debug
" $validity $name"
244 ed_addnode
$tree $treepath $treepath $snaccpath $name $name $validity
249 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
251 # ed_addnode is called from set_or_add_root, new_file, file_prune and ed_expand.
252 # the node may already be displayed (this is usually the case when the function ed_expand gets called from list_click or set_or_add_root). in this case the node gets moved to the right position.
253 # otherwise the node is created at the right place.
256 # tree name of the tree widget
257 # treeparent tag of the displayed parent node. this is usually the same as the treeparentpath, except when the display gets extended into the parent direction where the root tag is {}
258 # treeparentpath tag of the logical parent node.
259 # snaccparentpath names of the
260 # treenode node's name, gets appended to the treeparentpath
261 # snaccnode node's name, gets appended to the snaccparentpath
264 proc ed_addnode
{tree treeparent treeparentpath snaccparentpath treenode snaccnode validity
} \
266 set canvas [$tree canvas]
268 set treepath
"$treeparentpath/$treenode"
269 set snaccpath
"$snaccparentpath $snaccnode"
271 if [llength [$canvas find withtag
$treepath]] \
273 debug
[list movelink
$treepath $treeparent]
274 $tree movelink
$treepath $treeparent
278 #debug [list addnode $snaccpath]
279 if {[llength $snaccparentpath] > 0} \
281 set nodelabeltext
$snaccnode
285 set finfo
[snacc finfo
[string range
$snaccpath 1 end
]]
286 if {[lindex $finfo 0] == {}} \
288 set nodelabeltext
{(unnamed
)}
292 set nodelabeltext
[lindex $finfo 0]
295 $canvas create
text 0 0 -text $nodelabeltext -tags [list $validity-label
$treepath $treepath:label]
297 set line
[$canvas create line
0 0 0 0]
299 # fix for canvas bug: for reverse video, the canvas displays black items on a black background
300 if {[tk colormodel .
] == {monochrome
} && [lindex [$canvas config
-background] 4] == {black
}} \
302 $canvas itemconfigure
$treepath -fill white
303 $canvas itemconfigure
$line -fill white
306 if {$validity == {void
}} \
308 if {[tk colormodel .
] == {color
}} \
310 # #b0b0b0 is the light grey of disabled checkbuttons:
311 $canvas itemconfigure
$treepath -fill #b0b0b0
312 $canvas itemconfigure
$line -fill #b0b0b0
316 $canvas itemconfigure
$treepath -stipple gray50
317 $canvas itemconfigure
$line -stipple gray50
321 debug
[list addlink
$treeparent $treepath $line]
322 $tree addlink
$treeparent $treepath $line
326 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
328 proc prune_or_add_children
{canvas} \
332 set id
[$canvas find withtag current
]
339 set treepath
[lindex [$canvas gettags
$id] 1]
340 set snaccpath
[tree2snacc
$treepath]
341 set type
[lindex [snacc
info $snaccpath] 2]
344 SEQUENCE
\ OF
- SET
\ OF
349 if {[$tree isleaf
$treepath]} \
351 debug
[list expanding
$treepath $snaccpath]
352 ed_expand
$tree $treepath $snaccpath
356 debug
[list cutting
$treepath]
357 # !!! list_cleanup usually has to be called with the node that gets removed!
358 # in this case calling it with the node that stays around doesn't hurt because it is guaranteed not to be a SEQUENCE OF or SET OF type (they are handled a few lines above)
359 list_cleanup
$treepath $snaccpath
360 $tree prune
$treepath
368 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
369 # this function has to be called whenever a subtree that may contain SET OF or SEQUENCE of types gets removed from the display
370 # it must be called *before* the snacc object gets destroyed, the function examines it!
371 proc list_cleanup
{treepath snaccpath
} \
373 set info [snacc
info $snaccpath]
374 set type
[lindex $info 2]
377 SET
- SEQUENCE
- CHOICE
379 foreach elem
[lindex $info 3] \
381 set name
[lindex $elem 0]
382 set validity
[lindex $elem 1]
383 if {$validity == {valid
}} \
385 set subtreepath
"$treepath/$name"
386 set subsnaccpath
"$snaccpath $name"
387 list_cleanup
$subtreepath $subsnaccpath
391 SET
\ OF
- SEQUENCE
\ OF
393 set varname var
:$treepath
395 debug
[list varname
=$varname]
396 if {[info exists
$varname]} \
398 set idlist
[set $varname\(idlist
)]
399 debug
[list idlist
=$idlist]
405 set subtreepath
"$treepath/$id"
406 set subsnaccpath
"$snaccpath $i"
407 list_cleanup
$subtreepath $subsnaccpath
417 # this function must be called when calling "$tree root $treepath".
418 # it calls list_cleanup for all nodes that are neither parent nor in the subtree pointed to by $treepath.
419 proc list_cleanup_not_me
{treepath snaccpath
} \
421 if {[set i
[llength $snaccpath]] > 1} \
424 set parenttreepath
[join [lrange [split $treepath /] 0 $i] /]
426 set parentsnaccpath
[lrange $snaccpath 0 $i]
428 set info [snacc
info $parentsnaccpath]
429 set type
[lindex $info 2]
432 SET
- SEQUENCE
- CHOICE
434 foreach elem
[lindex $info 3] \
436 set name
[lindex $elem 0]
437 set validity
[lindex $elem 1]
438 if {$validity == {valid
}} \
440 set subparenttreepath
"$parenttreepath/$name"
441 set subparentsnaccpath
"$parentsnaccpath $name"
442 if {$subparenttreepath != $treepath} \
444 list_cleanup
$subparenttreepath $subparentsnaccpath
449 SET
\ OF
- SEQUENCE
\ OF
451 set varname var
:$parenttreepath
453 debug
[list varname
=$varname]
454 set idlist
[set $varname\(idlist
)]
455 debug
[list idlist
=$idlist]
461 set subparenttreepath
"$parenttreepath/$id"
462 set subparentsnaccpath
"$parentsnaccpath $i"
463 if {$subparenttreepath != $treepath} \
465 list_cleanup
$subparenttreepath $subparentsnaccpath
466 set $varname\(idlist
) [lreplace [set $varname\(idlist
)] $i $i 0]
474 list_cleanup_not_me
$parenttreepath $parentsnaccpath
478 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
479 # /file0/files/1/name \(-> { file0 files 0 name}
481 proc tree2snacc
{treepath
} \
484 foreach elem
[lrange [split $treepath /] 1 end
] \
487 if {[regexp {^
[0-9]} $elem]} \
489 set varname var
:$subtreepath
491 set idlist
[set $varname\(idlist
)]
494 foreach lid
$idlist \
496 if {$lid == $id} break
499 if {$index == [llength $idlist]} \
501 error "tree2snacc: id $id not found in idlist [list $idlist]"
509 append subtreepath
/$treeelem
510 append subsnaccpath
" $snaccelem"
511 debug
[list >>$subtreepath--$subsnaccpath<<]
513 debug
[list >>$subtreepath--$subsnaccpath<<]
517 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
518 proc import_text
{text_w treepath
} \
520 if {[selbox fn
{}]} \
522 if {[catch {set text [snacc import
$fn]} msg
]} \
524 tk_dialog .d import
"Couldn't import $fn: $msg" warning
0 Dismiss
528 $text_w delete
0.0 end
529 $text_w insert end
$text
530 snacc
set [tree2snacc
$treepath] $text
535 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
536 proc export_text
{text_w
} \
538 if {[selbox fn
{}]} \
540 if {[catch {snacc export
[$text_w get
0.0 end
] $fn} msg
]} \
542 tk_dialog .d import
"Couldn't export $fn: $msg" warning
0 Dismiss
547 proc frame_resize_bindings
{fileref treepath
} \
549 upvar #0 $fileref file
551 set frame $file(canvas).edit
$treepath
553 bind $frame <ButtonPress-1
> [list frame_resize_start
$fileref %x
%y
]
554 bind $frame <Button1-Motion
> [list frame_resize_cont
$fileref $treepath %x
%y
]
555 bind $frame <ButtonRelease-1
> [list frame_resize_end
$fileref $treepath]
557 $frame config
-cursor bottom_right_corner
560 proc frame_resize_start
{fileref x y
} \
562 #debug [list frame_resize_start $fileref $x $y]
564 upvar #0 $fileref file
566 set file(resize_x
) $x
567 set file(resize_y
) $y
570 proc frame_resize_cont
{fileref treepath x y
} \
572 #debug [list frame_resize_cont $fileref $treepath $x $y]
574 upvar #0 $fileref file
576 set frame $file(canvas).edit
$treepath
577 set frametag
$treepath:edit
579 set oldw
[lindex [$file(canvas) itemconfig
$frametag -width] 4]
580 set oldh
[lindex [$file(canvas) itemconfig
$frametag -height] 4]
581 debug
"old: $oldw x $oldh"
582 set neww
[max
1 [expr $oldw+$x-$file(resize_x
)]]
583 set newh
[max
1 [expr $oldh+$y-$file(resize_y
)]]
584 debug
"new: $neww x $newh"
585 $file(canvas) itemconfig
$frametag -width $neww -height $newh
586 set file(resize_x
) $x
587 set file(resize_y
) $y
590 proc frame_resize_end
{fileref treepath
} \
592 #debug [list frame_resize_end $fileref $treepath]
594 upvar #0 $fileref file
596 $file(tree
) nodeconfig
$treepath
600 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
601 # toggle content editor
602 proc toggle_editor
{canvas} \
605 set id
[$canvas find withtag current
]
612 set treepath
[lindex [$canvas gettags
$id] 1]
613 set snaccpath
[tree2snacc
$treepath]
614 set frame $canvas.edit
$treepath
615 if [llength [$canvas find withtag
$treepath:edit
]] \
617 debug
"removing editor for [list $treepath]"
618 $canvas delete
$treepath:edit
620 $tree nodeconfig
$treepath -remove {}
624 debug
"opening editor for [list $treepath]"
626 set fileref
[lindex [split $treepath /] 1]
628 frame $frame -borderwidth 3 -bg #cdb79e
629 set cleanup
[list [list destroy $frame]]
631 set info [snacc
info $snaccpath]
632 set type
[lindex $info 2]
638 set label $frame.
label
639 label $label -text NULL
644 set value
[snacc get
$snaccpath]
646 set var var
:$treepath
650 set button $frame.
button
651 #checkbutton $button -variable $var
652 checkbutton $button -onvalue TRUE
-offvalue FALSE
-variable $var -textvariable $var -command [list debug
[list $canvas $treepath]]
655 trace variable $var w change_simple
659 set value
[snacc get
$snaccpath]
661 set var var
:$treepath
665 if {[lindex $info 0] != {{} {}}} \
667 set typeinfo
[snacc type
[lindex $info 0]]
669 foreach elem
[lindex $typeinfo 3] \
671 set en
[lindex $elem 0]
672 set ev
[lindex $elem 1]
673 set button $frame.
button$en
674 radiobutton $button -text $en -variable $var -value $ev -anchor w
679 set entry $frame.
entry
680 entry $entry -textvariable $var -width 9 -relief sunken
682 int_entry_bindings
$entry
684 pack $entry -anchor w
-fill x
688 trace variable $var w change_simple
692 set typeinfo
[snacc type
[lindex $info 0]]
694 if {[catch {set value
[snacc get
$snaccpath]} msg
] == 1} \
696 global errorInfo errorCode
697 if {$errorCode == {SNACC ILLENUM
}} \
699 set value
[lindex [lindex $typeinfo 3] 0]
700 snacc
set $snaccpath $value
701 append msg
"--setting to first legal symbolic value \"$value\""
702 tk_dialog .d illenum
"$msg" warning
0 Dismiss
706 error $msg $errorInfo $errorCode
710 set var var
:$treepath
714 foreach ev
[lindex $typeinfo 3] \
716 set button $frame.
button$ev
717 radiobutton $button -text $ev -variable $var -value $ev -anchor w
721 trace variable $var w change_simple
725 set value
[snacc get
$snaccpath]
727 set var var
:$treepath
731 set entry $frame.
entry
732 entry $entry -textvariable $var -relief sunken
735 frame_resize_bindings
$fileref $treepath
739 trace variable $var w change_simple
743 set value
[snacc get
$snaccpath]
745 set var var
:$treepath
750 if {[lindex $info 0] != {{} {}}} \
752 set typeinfo
[snacc type
[lindex $info 0]]
754 foreach elem
[lindex $typeinfo 3] \
756 set en
[lindex $elem 0]
757 set ev
[lindex $elem 1]
758 set max_ev
[max
$ev $max_ev]
759 set button $frame.
button$en
760 checkbutton $button -text $en -variable $var:$ev -command [list toggle_bit
$var $ev] -anchor w
765 set entry $frame.
entry
766 entry $entry -textvariable $var -relief sunken
767 set len
[max
8 [string length
$value] [expr $max_ev + 1]]
770 debug
[list length of
entry is
$len]
771 $entry config
-width $len
773 pack $entry -anchor w
-fill x
775 bit_string_entry_bindings
$entry
779 trace variable $var w change_bits
780 set $var $value; # trigger the trace
784 set value
[snacc get
$snaccpath]
786 set var var
:$treepath
790 set entry $frame.
entry
791 entry $entry -textvariable $var -relief sunken
792 pack $entry -fill both
794 frame_resize_bindings
$fileref $treepath
798 trace variable $var w change_simple
802 set value
[snacc get
$snaccpath]
807 text $text -borderwidth 2 -relief sunken
-yscrollcommand [list $sb set] -width 32 -height 8
808 scrollbar $sb -relief sunken
-command [list $text yview
] -width 10 -cursor arrow
810 pack $sb -side right
-fill y
811 pack $text -side left
-expand true
-fill both
813 bind $text <ButtonPress-2
> [list $text scan mark
%y
]
814 bind $text <Button2-Motion
> [list $text scan dragto
%y
]
816 bind $text <Leave
> "snacc set \[tree2snacc $treepath\] \[$text get 0.0 end\]"
817 bind $text <FocusOut
> "snacc set \[tree2snacc $treepath\] \[$text get 0.0 end\]"
821 $m add command
-label Load...
-command "[list import_text $text $treepath]; [list $m unpost]"
822 $m add command
-label Save...
-command "[list export_text $text]; [list $m unpost]"
824 bind $text <ButtonPress-3
> "[list $m] post \[expr %X -16\] \[expr %Y -8\]"
825 bind $m <ButtonPress-3
> [list $m unpost
]
826 bind $m <Any-Leave
> [list $m unpost
]
828 $text insert end
$value
831 frame_resize_bindings
$fileref $treepath
836 set typeinfo
[snacc type
[lindex $info 0]]
840 set varelems
[lindex $info 3]
841 set typeelems
[lindex $typeinfo 3]
843 for {set i
0; set len
[llength $varelems]} {$i < $len} {incr i
} \
845 set varelem
[lindex $varelems $i]
846 set typeelem
[lindex $typeelems $i]
848 set name
[lindex $varelem 0]
849 set validity
[lindex $varelem 1]
850 debug
" $validity $name"
852 set var var
:$treepath:$name
856 set button $frame.
$name
857 checkbutton $button -text $name -onvalue valid
-offvalue void
-variable $var -command [list toggle_se
* $canvas $treepath $name] -anchor w
858 if {[lindex $typeelem 4] == {mandatory
}} \
860 #$button configure -disabledforeground [lindex [$button configure -fg] 4] -state disabled
861 $button configure
-state disabled
869 set len
[lindex $info 3]
871 set varname var
:$treepath
872 upvar #0 $varname var
873 if {![info exists var
(idlist
)]} \
878 # no! needs a longer lifetime!
879 #lappend cleanup [list global $varname] [list unset $varname]
881 # set mbar $frame.mbar
885 scrollbar $sb -command [list $list yview
] -width 10 -relief sunken
-cursor arrow
886 # listbox $list -yscroll [list $sb set] -relief sunken -width 4 -height 5
887 text $list -borderwidth 2 -relief sunken
-yscrollcommand [list $sb set] -width 4 -height 8 -exportselection 0
888 pack $sb -side right
-fill y
889 pack $list -side left
-expand true
-fill both
891 # frame $mbar -relief raised -bd 2
892 # pack $mbar -side top -fill x
894 # set mode $mbar.mode
895 # set mode $frame.mode
897 # menubutton $mode -text Mode -menu $m
900 set lm
"[list list_mode $canvas $treepath]; [list $m unpost]"
901 $m add
radiobutton -label Display
-variable ${varname
}(mode
) -value display
-command $lm
903 $m add
radiobutton -label Insert
-variable ${varname
}(mode
) -value insert
-command $lm
904 $m add
radiobutton -label Append
-variable ${varname
}(mode
) -value append -command $lm
905 $m add
radiobutton -label Delete
-variable ${varname
}(mode
) -value delete
-command $lm
906 # pack $mode -side left
908 # pack $mode -side top -fill x
910 $list tag config display
-background #b2dfee -relief raised
911 bind $list <Button-1
> [list list_click
$canvas $treepath]
912 bind $list <Double-Button-1
> { }
913 bind $list <Triple-Button-1
> { }
914 bind $list <Button1-Motion
> { }
916 bind $list <ButtonPress-3
> "[list $m] post \[expr %X-16\] \[expr %Y-8\]"
917 bind $m <ButtonPress-3
> [list $m unpost
]
918 bind $m <Any-Leave
> [list $m unpost
]
921 for {set i
0} {$i < $len} {incr i
} \
923 $list insert end
[format "%4d\n" $i]
925 if {[llength $var(idlist
)] > $i} \
927 if {[set id
[lindex $var(idlist
) $i]]} \
929 set line
[expr $i + 1]
930 $list tag add display
$line.0 $line.end
935 set var
(idlist
) [linsert $var(idlist
) $i 0]
939 frame_resize_bindings
$fileref $treepath
943 set name
[lindex $info 3]
944 set validity
[lindex $info 4]
945 set typeinfo
[snacc type
[lindex $info 0]]
947 set var var
:$treepath
948 set oldvar oldvar
:$treepath
953 foreach elem
[lindex $typeinfo 3] \
955 set en
[lindex $elem 0]
956 set button $frame.
button$en
957 radiobutton $button -text $en -variable $var -value $en -command [list new_choice
$canvas $treepath] -anchor w
960 debug
" $validity $name"
964 error "unexpected type $type"
968 scan [$canvas bbox
$treepath:label] "%d%d%d%d" lx uy rx ly
969 $canvas create window
$lx $ly -anchor nw
-tags [list edit
$treepath $treepath:edit
] -window $frame
971 update idletasks
; # calculate frame's size (needed by tree widget)
973 # explicitly set the frame's width&height to avoid nasty effects when resizing:
974 scan [$canvas bbox
$treepath:edit
] "%d%d%d%d" lx uy rx ly
975 $canvas itemconfig
$treepath:edit
-width [expr $rx - $lx] -height [expr $ly - $uy]
977 #debug [list cleanup = [join $cleanup \;]]
978 $tree nodeconfig
$treepath -remove [join $cleanup \;]
984 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
985 proc list_click
{canvas treepath
} \
988 set snaccpath
[tree2snacc
$treepath]
990 debug
[list treepath
=$treepath]
991 debug
[list snaccpath
=$snaccpath]
992 debug
[list tree2snacc
: [tree2snacc
$treepath]]
993 set varname var
:$treepath
994 upvar #0 $varname var
995 set frame $canvas.edit
$treepath
998 debug
[list list_click
: $list]
999 debug
[list varname
=$varname]
1000 debug
[list idlist
=$var(idlist
)]
1001 # debug [$list tag ranges display]
1002 set text_index
[$list index current
]
1003 #debug [list index: $index]
1004 if {$text_index != ""} \
1006 # strip the column number:
1007 set line
[lindex [split $text_index .
] 0]
1008 # lines numbers start at 1, indices at 0:
1009 set index
[expr $line - 1]
1010 set len
[llength $var(idlist
)]
1011 set tags
[$list tag names
$text_index]
1016 debug
[list tags
: $tags]
1017 debug
[list line
: $line]
1018 if {$index < $len} \
1020 set id
[lindex $var(idlist
) $index]
1021 debug
[list index
$index id
$id]
1024 $list tag remove display
$line.0 $line.end
1025 list_cleanup
$treepath/$id "$snaccpath $index"
1026 debug
[list $tree rmlink
$treepath/$id]
1027 $tree rmlink
$treepath/$id
1028 set var
(idlist
) [lreplace $var(idlist
) $index $index 0]
1032 $list tag add display
$line.0 $line.end
1033 set var
(idlist
) [lreplace $var(idlist
) $index $index [incr var
(lastid
)]]
1034 ed_expand
$tree $treepath $snaccpath
1041 if {$var(mode
) == {append}} {incr index
}
1042 debug
[list insert
$index 0]
1043 set var
(idlist
) [linsert $var(idlist
) $index 0]
1044 debug
[list $var(idlist
)]
1045 debug
[list catch [list snacc
set "$snaccpath {insert $index}" {}]]
1046 catch [list snacc
set "$snaccpath {insert $index}" {}]
1047 set file(modified
) 1
1048 debug
[list [snacc get
$snaccpath]]
1050 $list insert end
[format "%4d\n" [expr [lindex [split [$list index end
] .
] 0] - 1]]
1052 for {set i
$len} {$i > $index} {incr i
-1} \
1054 set line
[expr $i + 1]
1055 if {[set id
[lindex $var(idlist
) $i]]} \
1057 debug
[list $canvas itemconfigure
$treepath/$id:label -text $i]
1058 $canvas itemconfigure
$treepath/$id:label -text $i
1059 if {![lindex $var(idlist
) [expr $i - 1]]} \
1061 debug
[list $list tag add display
$line.0 $line.end
]
1062 $list tag add display
$line.0 $line.end
1067 if {![lindex $var(idlist
) [expr $i - 1]]} \
1069 debug
[list $list tag remove display
$line.0 $line.end
]
1070 $list tag remove display
$line.0 $line.end
1074 set line
[expr $index + 1]
1075 debug
[list $list tag remove display
$line.0 $line.end
]
1076 $list tag remove display
$line.0 $line.end
1080 if {$index < $len} \
1082 debug
[list delete
$index]
1084 if {[set id
[lindex $var(idlist
) $index]]} \
1086 # list_cleanup must be called before the snacc object is modified:
1087 list_cleanup
$treepath/$id "$snaccpath $index"
1088 $tree rmlink
$treepath/$id
1091 for {set i
$index} {$i < $len} {incr i
} \
1093 set line
[expr $i + 1]
1094 if {[set id
[lindex $var(idlist
) [expr $i + 1]]]} \
1096 debug
[list $canvas itemconfigure
$treepath/$id:label -text $i]
1097 $canvas itemconfigure
$treepath/$id:label -text $i
1098 if {![lindex $var(idlist
) $i]} \
1100 debug
[list $list tag add display
$line.0 $line.end
]
1101 $list tag add display
$line.0 $line.end
1106 if {[lindex $var(idlist
) $i]} \
1108 debug
[list $list tag remove display
$line.0 $line.end
]
1109 $list tag remove display
$line.0 $line.end
1114 set var
(idlist
) [lreplace $var(idlist
) $index $index]
1115 debug
[list $var(idlist
)]
1116 debug
[list snacc
unset "$snaccpath $index"]
1117 snacc
unset "$snaccpath $index"
1118 set file(modified
) 1
1119 debug
[list [snacc get
$snaccpath]]
1120 $list delete
[$list index
{end
- 1 line
}] [$list index end
]
1128 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1129 proc list_mode
{canvas treepath
} \
1131 set var var
:$treepath
1133 set mode
[set ${var
}(mode
)]
1134 set frame $canvas.edit
$treepath
1135 set list $frame.
list
1139 display
{set cursor arrow
}
1140 insert
{set cursor based_arrow_up
}
1141 append {set cursor based_arrow_down
}
1142 delete
{set cursor pirate
}
1144 $list config
-cursor $cursor
1146 debug
[list list_mode
: ${var
}(mode
) set to
$mode]
1149 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1150 proc toggle_bit
{var i
} \
1153 set bit
[set $var:$i]
1156 debug
[list toggle_bit
$val $i to
$bit]
1158 set pre
[string range
$val 0 [expr $i - 1]]
1161 for {set l
[string length
$val]} {$l < $i} {incr l
} \
1164 debug
[list appending
: $val]
1167 set post
[string range
$val [expr $i + 1] end
]
1169 debug
[list toggle_bit combining
$pre $fill $bit $post]
1170 set $var $pre$fill$bit$post
1173 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1174 proc change_bits
{var element op
} \
1178 debug
[list change_bits
$var set to
$val]
1180 debug
[list set l
[string length
$val]]
1181 set l
[string length
$val]
1182 for {set i
0} {$i < $l} {incr i
} \
1185 if {[info exists
$var:$i]} \
1187 debug
[list set $var:$i [string index
$val $i]]
1188 set $var:$i [string index
$val $i]
1192 debug
[list non-exist
: $var:$i]
1196 foreach bitvar
[info globals
$var:*] \
1198 set i
[lindex [split $bitvar :] 2]
1206 change_simple
$var $element $op
1209 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1210 proc change_simple
{var element op
} \
1214 debug
[list change_simple
$var set to
$val]
1216 set treepath
[lindex [split $var :] 1]
1217 debug
[list treepath
= $treepath]
1218 set fileref
[lindex [split $treepath /] 1]
1219 upvar #0 $fileref file
1220 set canvas $file(canvas)
1221 debug
[list canvas= $canvas]
1222 set snaccpath
[tree2snacc
$treepath]
1223 debug
[list snaccpath
= $snaccpath]
1224 snacc
set $snaccpath $val
1225 set file(modified
) 1
1228 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1229 proc new_choice
{canvas treepath
} \
1232 set snaccpath
[tree2snacc
$treepath]
1234 set var var
:$treepath
1235 set oldvar oldvar
:$treepath
1238 set oldval
[set $oldvar]
1240 set fileref
[lindex [split $treepath /] 1]
1241 upvar #0 $fileref file
1243 debug
"$file(modified)"
1244 debug
[list new choice
: $snaccpath = $val]
1246 # list_cleanup must be called before the snacc object is modified:
1247 list_cleanup
$treepath/$oldval "$snaccpath $oldval"
1249 catch {snacc
set $snaccpath [list $val {}]}
1250 set file(modified
) 1
1251 debug
"$file(modified)"
1253 if {[llength [$canvas find withtag
"$treepath/$oldval"]]} \
1255 $tree rmlink
"$treepath/$oldval"
1256 ed_expand
$tree $treepath $snaccpath
1263 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1264 proc toggle_se
* {canvas treepath name
} \
1267 set snaccpath
[tree2snacc
$treepath]
1269 set var var
:$treepath:$name
1273 set fileref
[lindex [split $treepath /] 1]
1274 upvar #0 $fileref file
1276 debug
"$snaccpath $name = $val"
1278 # this procedure is called after the button value has changed, so adjust the display to the current (new) setting:
1279 if {$val == {void
}} \
1281 # (change valid \(-> void)
1282 # list_cleanup must be called before the snacc object is modified:
1283 list_cleanup
$treepath/$name "$snaccpath $name"
1284 snacc
unset "$snaccpath $name"
1288 # (change void \(-> valid)
1289 catch {snacc
set "$snaccpath $name" {}}
1291 set file(modified
) 1
1293 if {[llength [$canvas find withtag
"$treepath/$name"]]} \
1295 debug
[list rmlink
"$treepath/$name"]
1296 $tree rmlink
"$treepath/$name"
1297 # a bug in the tree widget requires us to redraw here:
1299 ed_expand
$tree $treepath $snaccpath
1304 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1305 # add/drop parent and siblings
1306 proc set_or_add_root
{canvas} \
1309 set id
[$canvas find withtag current
]
1316 set treepath
[lindex [$canvas gettags
$id] 1]
1317 set snaccpath
[tree2snacc
$treepath]
1319 if {[llength $snaccpath] == 1} \
1321 debug
"at root already"
1325 if {[$tree isroot
$treepath]} \
1328 debug
[list expanding
[list $treepath $snaccpath]]
1329 set i
[llength $snaccpath]
1333 set treeparentpath
[join [lrange [split $treepath /] 0 $i] /]
1334 set treeparentnode
[lindex [split $treepath /] $i]
1336 set snaccparentpath
[lrange $snaccpath 0 $i]
1337 set snaccparentnode
[lindex $snaccpath $i]
1339 set treeparentparentpath
[join [lrange [split $treepath /] 0 $i] /]
1341 set snaccparentparentpath
[lrange $snaccpath 0 $i]
1343 #debug [list ed_addnode $tree {} $parentparentpath $parentnode valid]
1344 ed_addnode
$tree {} $treeparentparentpath $snaccparentparentpath $treeparentnode $snaccparentnode valid
1345 #debug [list ed_expand $tree $parentpath]
1346 ed_expand
$tree $treeparentpath $snaccparentpath
1350 # hide everything above this subtree:
1351 # debug "cutting $path"
1352 list_cleanup_not_me
$treepath $snaccpath
1353 $tree root
$treepath
1355 # debug [snacc info $path]
1361 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1364 if {[selbox fn ct nullfn
]} \
1366 debug
"fn=$fn ct=$ct"
1369 if {[catch {set f
[snacc
open $ct $fn create
]} msg
]} \
1371 tk_dialog .d
load "Couldn't open $fn {$ct}: $msg" warning
0 Dismiss
1377 if {[catch {set f
[snacc create
$ct]} msg
]} \
1379 tk_dialog .d create
"Couldn't create {$ct}: $msg" warning
0 Dismiss
1389 #\[sep]-----------------------------------------------------------------------------------------------------------------------------
1394 # returns 1 on `cancel', otherwise exits or returns 0
1395 proc close_file
{fileref
} \
1397 upvar #0 $fileref file
1399 if {$file(modified
)} \
1401 set fi
[snacc finfo
$file(handle
)]
1402 set fn
[lindex $fi 0]
1403 set hasfn
[expr {$fn != {}}]
1404 set isrw
[expr {[lindex $fi 1] == {rw
}}]
1405 set msg
{There are unsaved changes
}
1408 append msg
" in `$fn'"
1410 append msg
{. Save them?
}
1411 switch [lindex {save discard cancel
} [tk_dialog .d modified
$msg questhead
0 Yes No Cancel
]] \
1419 if {$hasfn && $isrw} \
1421 if {[file_save
$fileref]} \
1428 if {[file_save_as
$fileref]} \
1437 destroy $file(toplevel)
1439 if {![incr #files -1]} \
1449 for {set i
0} {${#files}} {incr i} \
1451 if {[winfo exists .
[set fileref
file$i]]} \
1453 if {[close_file
$fileref]} \
1461 proc new_file
{handle
} \
1465 while {[winfo exists
[set toplevel .
[set fileref
file${#file}]]]} \
1471 upvar #0 $fileref file
1473 set file(handle
) $handle
1475 set file(toplevel) [toplevel $toplevel]
1476 wm title
$toplevel snaccEd
1477 wm minsize
$toplevel 150 100
1478 wm geometry
$toplevel 500x500
1483 set file(modified
) 0
1485 $toplevel config
-cursor arrow
1487 set menubar
$toplevel.
menu
1488 frame $menubar -relief raised
-bd 2
1489 pack $menubar -side top
-fill x
1491 set filem
$menubar.
file
1493 menubutton $filem -text File
-menu $m
1495 $m add command
-label Reload
-command [list file_reload
$fileref]
1496 $m add command
-label Load...
-command [list file_load_from
$fileref]
1497 $m add command
-label Save
-command [list file_save
$fileref]
1498 $m add command
-label {Save As...
} -command [list file_save_as
$fileref]
1499 $m add command
-label Close
-command [list close_file
$fileref]
1501 $m add command
-label Open...
-command file_open
1503 $m add command
-label Quit
-command file_quit
1504 set fi
[snacc finfo
$handle]
1505 set hasnofn
[expr {[lindex $fi 0] == {}}]
1506 set isro
[expr {[lindex $fi 1] == {ro
}}]
1509 $m entryconfigure Reload
-state disabled
1511 if {$hasnofn ||
$isro} \
1513 $m entryconfigure Save
-state disabled
1515 pack $filem -side left
1517 set help
$menubar.help
1519 menubutton $help -text Help
-menu $help.m
1521 $m add command
-label About
-command "help [list $m] \$helptext(about)"
1522 $m add command
-label Manoeuvering
-command "help [list $m] \$helptext(manoeuv)"
1523 pack $help -side right
1525 tk_menuBar
$menubar $filem $help
1530 pack $toplevel.f0
-expand true
-fill both
1531 pack $toplevel.f1
-fill x
1533 set file(canvas) [set canvas [canvas $toplevel.c
-width 0 -height 0]]
1535 set hsb
[scrollbar $toplevel.hsb
-orient horiz
-relief sunken
-command [list $canvas xview
]]
1536 set vsb
[scrollbar $toplevel.vsb
-relief sunken
-command [list $canvas yview
]]
1538 $canvas config
-xscroll [list $hsb set] -yscroll [list $vsb set]
1540 set blind
[frame $toplevel.blind
-width [lindex [$vsb config
-width] 4]]
1542 pack $vsb -in $toplevel.f0
-side right
-fill y
1543 pack $canvas -in $toplevel.f0
-side left
-expand true
-fill both
1545 pack $blind -in $toplevel.f1
-side right
1546 pack $hsb -in $toplevel.f1
-side left
-expand true
-fill x
1548 bind $canvas <ButtonPress-2
> [list $canvas scan mark
%x
%y
]
1549 bind $canvas <Button2-Motion
> [list $canvas scan dragto
%x
%y
]
1551 $canvas bind valid-label
<Button-1
> {prune_or_add_children
%W
}
1552 $canvas bind valid-label
<Button-2
> {toggle_editor
%W
}
1553 $canvas bind valid-label
<Button-3
> {set_or_add_root
%W
}
1555 set file(tree
) [set tree
[tree
$canvas.t
]]
1557 ed_addnode
$tree {} {} {} $handle $handle valid
1561 tkwait visibility
$toplevel
1581 set ct
[lrange $argv 0 1]
1582 set fn
[lindex $argv 2]
1583 if {[catch {set f
[snacc
open $ct $fn create
]} msg
]} \
1585 tk_dialog .d
load "Couldn't open $fn {$ct}: $msg" warning
0 Dismiss
1589 elseif
{$argc == 2} \
1591 set ct
[lrange $argv 0 1]
1592 if {[catch {set f
[snacc create
$ct]} msg
]} \
1594 tk_dialog .d create
"Couldn't create {$ct}: $msg" warning
0 Dismiss