summaryrefslogtreecommitdiff
path: root/modules/tclsci/tcl/BWidget
diff options
context:
space:
mode:
authorShashank2017-05-29 12:40:26 +0530
committerShashank2017-05-29 12:40:26 +0530
commit0345245e860375a32c9a437c4a9d9cae807134e9 (patch)
treead51ecbfa7bcd3cc5f09834f1bb8c08feaa526a4 /modules/tclsci/tcl/BWidget
downloadscilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.gz
scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.bz2
scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.zip
CMSCOPE changed
Diffstat (limited to 'modules/tclsci/tcl/BWidget')
-rwxr-xr-xmodules/tclsci/tcl/BWidget/arrow.tcl551
-rwxr-xr-xmodules/tclsci/tcl/BWidget/bitmap.tcl94
-rwxr-xr-xmodules/tclsci/tcl/BWidget/button.tcl393
-rwxr-xr-xmodules/tclsci/tcl/BWidget/buttonbox.tcl419
-rwxr-xr-xmodules/tclsci/tcl/BWidget/color.tcl493
-rwxr-xr-xmodules/tclsci/tcl/BWidget/combobox.tcl885
-rwxr-xr-xmodules/tclsci/tcl/BWidget/dialog.tcl357
-rwxr-xr-xmodules/tclsci/tcl/BWidget/dragsite.tcl197
-rwxr-xr-xmodules/tclsci/tcl/BWidget/dropsite.tcl456
-rwxr-xr-xmodules/tclsci/tcl/BWidget/dynhelp.tcl793
-rwxr-xr-xmodules/tclsci/tcl/BWidget/entry.tcl472
-rwxr-xr-xmodules/tclsci/tcl/BWidget/font.tcl566
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/bold.gifbin0 -> 118 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/copy.gifbin0 -> 145 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/cut.gifbin0 -> 130 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/dragfile.gifbin0 -> 949 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/dragicon.gifbin0 -> 1012 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/error.gifbin0 -> 259 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/file.gifbin0 -> 860 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/folder.gifbin0 -> 139 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/hourglass.gifbin0 -> 211 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/info.gifbin0 -> 256 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/italic.gifbin0 -> 111 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/minus.xbm5
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/new.gifbin0 -> 131 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/opcopy.xbm5
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/open.gifbin0 -> 139 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/openfold.gifbin0 -> 146 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/oplink.xbm5
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/opmove.xbm5
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/overstrike.gifbin0 -> 119 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/palette.gifbin0 -> 151 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/passwd.gifbin0 -> 481 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/paste.gifbin0 -> 159 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/plus.xbm5
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/print.gifbin0 -> 140 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/question.gifbin0 -> 265 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/redo.gifbin0 -> 70 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/save.gifbin0 -> 138 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/target.xbm9
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/underline.gifbin0 -> 119 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/undo.gifbin0 -> 115 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/images/warning.gifbin0 -> 254 bytes
-rwxr-xr-xmodules/tclsci/tcl/BWidget/init.tcl54
-rwxr-xr-xmodules/tclsci/tcl/BWidget/label.tcl329
-rwxr-xr-xmodules/tclsci/tcl/BWidget/labelentry.tcl100
-rwxr-xr-xmodules/tclsci/tcl/BWidget/labelframe.tcl160
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/da.rc52
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/de.rc52
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/en.rc52
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/es.rc53
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/fr.rc52
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/hu.rc52
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/nl.rc52
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/no.rc52
-rwxr-xr-xmodules/tclsci/tcl/BWidget/lang/pl.rc104
-rwxr-xr-xmodules/tclsci/tcl/BWidget/listbox.tcl1726
-rwxr-xr-xmodules/tclsci/tcl/BWidget/mainframe.tcl713
-rwxr-xr-xmodules/tclsci/tcl/BWidget/messagedlg.tcl128
-rwxr-xr-xmodules/tclsci/tcl/BWidget/notebook.tcl1166
-rwxr-xr-xmodules/tclsci/tcl/BWidget/pagesmgr.tcl294
-rwxr-xr-xmodules/tclsci/tcl/BWidget/panedw.tcl385
-rwxr-xr-xmodules/tclsci/tcl/BWidget/panelframe.tcl246
-rwxr-xr-xmodules/tclsci/tcl/BWidget/passwddlg.tcl182
-rwxr-xr-xmodules/tclsci/tcl/BWidget/pkgIndex.tcl84
-rwxr-xr-xmodules/tclsci/tcl/BWidget/progressbar.tcl208
-rwxr-xr-xmodules/tclsci/tcl/BWidget/progressdlg.tcl87
-rwxr-xr-xmodules/tclsci/tcl/BWidget/scrollframe.tcl262
-rwxr-xr-xmodules/tclsci/tcl/BWidget/scrollview.tcl254
-rwxr-xr-xmodules/tclsci/tcl/BWidget/scrollw.tcl294
-rwxr-xr-xmodules/tclsci/tcl/BWidget/separator.tcl75
-rwxr-xr-xmodules/tclsci/tcl/BWidget/spinbox.tcl331
-rwxr-xr-xmodules/tclsci/tcl/BWidget/statusbar.tcl422
-rwxr-xr-xmodules/tclsci/tcl/BWidget/titleframe.tcl170
-rwxr-xr-xmodules/tclsci/tcl/BWidget/tree.tcl2251
-rwxr-xr-xmodules/tclsci/tcl/BWidget/utils.tcl680
-rwxr-xr-xmodules/tclsci/tcl/BWidget/widget.tcl1610
-rwxr-xr-xmodules/tclsci/tcl/BWidget/wizard.tcl1028
-rwxr-xr-xmodules/tclsci/tcl/BWidget/xpm2image.tcl115
79 files changed, 19585 insertions, 0 deletions
diff --git a/modules/tclsci/tcl/BWidget/arrow.tcl b/modules/tclsci/tcl/BWidget/arrow.tcl
new file mode 100755
index 000000000..e51753a92
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/arrow.tcl
@@ -0,0 +1,551 @@
+# ------------------------------------------------------------------------------
+# arrow.tcl
+# This file is part of Unifix BWidget Toolkit
+# ------------------------------------------------------------------------------
+# Index of commands:
+# Public commands
+# - ArrowButton::create
+# - ArrowButton::configure
+# - ArrowButton::cget
+# - ArrowButton::invoke
+# Private commands (redraw commands)
+# - ArrowButton::_redraw
+# - ArrowButton::_redraw_state
+# - ArrowButton::_redraw_relief
+# - ArrowButton::_redraw_whole
+# Private commands (event bindings)
+# - ArrowButton::_destroy
+# - ArrowButton::_enter
+# - ArrowButton::_leave
+# - ArrowButton::_press
+# - ArrowButton::_release
+# - ArrowButton::_repeat
+# ------------------------------------------------------------------------------
+
+namespace eval ArrowButton {
+ Widget::define ArrowButton arrow DynamicHelp
+
+ Widget::tkinclude ArrowButton button .c \
+ include [list \
+ -borderwidth -bd \
+ -relief -highlightbackground \
+ -highlightcolor -highlightthickness -takefocus]
+
+ Widget::declare ArrowButton [list \
+ [list -type Enum button 0 [list arrow button]] \
+ [list -dir Enum top 0 [list top bottom left right]] \
+ [list -width Int 15 0 "%d >= 0"] \
+ [list -height Int 15 0 "%d >= 0"] \
+ [list -ipadx Int 0 0 "%d >= 0"] \
+ [list -ipady Int 0 0 "%d >= 0"] \
+ [list -clean Int 2 0 "%d >= 0 && %d <= 2"] \
+ [list -activeforeground TkResource "" 0 button] \
+ [list -activebackground TkResource "" 0 button] \
+ [list -disabledforeground TkResource "" 0 button] \
+ [list -foreground TkResource "" 0 button] \
+ [list -background TkResource "" 0 button] \
+ [list -state TkResource "" 0 button] \
+ [list -troughcolor TkResource "" 0 scrollbar] \
+ [list -arrowbd Int 1 0 "%d >= 0 && %d <= 2"] \
+ [list -arrowrelief Enum raised 0 [list raised sunken]] \
+ [list -command String "" 0] \
+ [list -armcommand String "" 0] \
+ [list -disarmcommand String "" 0] \
+ [list -repeatdelay Int 0 0 "%d >= 0"] \
+ [list -repeatinterval Int 0 0 "%d >= 0"] \
+ [list -fg Synonym -foreground] \
+ [list -bg Synonym -background] \
+ ]
+ DynamicHelp::include ArrowButton balloon
+
+ bind BwArrowButtonC <Enter> {ArrowButton::_enter %W}
+ bind BwArrowButtonC <Leave> {ArrowButton::_leave %W}
+ bind BwArrowButtonC <ButtonPress-1> {ArrowButton::_press %W}
+ bind BwArrowButtonC <ButtonRelease-1> {ArrowButton::_release %W}
+ bind BwArrowButtonC <Key-space> {ArrowButton::invoke %W; break}
+ bind BwArrowButtonC <Return> {ArrowButton::invoke %W; break}
+ bind BwArrowButton <Configure> {ArrowButton::_redraw_whole %W %w %h}
+ bind BwArrowButton <Destroy> {ArrowButton::_destroy %W}
+
+ variable _grab
+ variable _moved
+
+ array set _grab {current "" pressed "" oldstate "normal" oldrelief ""}
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ArrowButton::create
+# -----------------------------------------------------------------------------
+proc ArrowButton::create { path args } {
+ # Initialize configuration mappings and parse arguments
+ array set submaps [list ArrowButton [list ] .c [list ]]
+ array set submaps [Widget::parseArgs ArrowButton $args]
+
+ # Create the class frame (so we can do the option db queries)
+ frame $path -class ArrowButton -borderwidth 0 -highlightthickness 0
+ Widget::initFromODB ArrowButton $path $submaps(ArrowButton)
+
+ # Create the canvas with the initial options
+ eval [list canvas $path.c] $submaps(.c)
+
+ # Compute the width and height of the canvas from the width/height
+ # of the ArrowButton and the borderwidth/hightlightthickness.
+ set w [Widget::getMegawidgetOption $path -width]
+ set h [Widget::getMegawidgetOption $path -height]
+ set bd [Widget::cget $path -borderwidth]
+ set ht [Widget::cget $path -highlightthickness]
+ set pad [expr {2*($bd+$ht)}]
+
+ $path.c configure -width [expr {$w-$pad}] -height [expr {$h-$pad}]
+ bindtags $path [list $path BwArrowButton [winfo toplevel $path] all]
+ bindtags $path.c [list $path.c BwArrowButtonC [winfo toplevel $path.c] all]
+ pack $path.c -expand yes -fill both
+
+ DynamicHelp::sethelp $path $path.c 1
+
+ set ::ArrowButton::_moved($path) 0
+
+ return [Widget::create ArrowButton $path]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ArrowButton::configure
+# -----------------------------------------------------------------------------
+proc ArrowButton::configure { path args } {
+ set res [Widget::configure $path $args]
+
+ set ch1 [expr {[Widget::hasChanged $path -width w] |
+ [Widget::hasChanged $path -height h] |
+ [Widget::hasChanged $path -borderwidth bd] |
+ [Widget::hasChanged $path -highlightthickness ht]}]
+ set ch2 [expr {[Widget::hasChanged $path -type val] |
+ [Widget::hasChanged $path -ipadx val] |
+ [Widget::hasChanged $path -ipady val] |
+ [Widget::hasChanged $path -arrowbd val] |
+ [Widget::hasChanged $path -clean val] |
+ [Widget::hasChanged $path -dir val]}]
+
+ if { $ch1 } {
+ set pad [expr {2*($bd+$ht)}]
+ $path.c configure \
+ -width [expr {$w-$pad}] -height [expr {$h-$pad}] \
+ -borderwidth $bd -highlightthickness $ht
+ set ch2 1
+ }
+ if { $ch2 } {
+ _redraw_whole $path [winfo width $path] [winfo height $path]
+ } else {
+ _redraw_relief $path
+ _redraw_state $path
+ }
+ DynamicHelp::sethelp $path $path.c
+
+ return $res
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ArrowButton::cget
+# -----------------------------------------------------------------------------
+proc ArrowButton::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::invoke
+# ------------------------------------------------------------------------------
+proc ArrowButton::invoke { path } {
+ if { ![string equal [winfo class $path] "ArrowButton"] } {
+ set path [winfo parent $path]
+ }
+ if { ![string equal [Widget::getoption $path -state] "disabled"] } {
+ set oldstate [Widget::getoption $path -state]
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ set oldrelief [Widget::getoption $path -relief]
+ configure $path -state active -relief sunken
+ } else {
+ set oldrelief [Widget::getoption $path -arrowrelief]
+ configure $path -state active -arrowrelief sunken
+ }
+ update idletasks
+ if {[llength [set cmd [Widget::getoption $path -armcommand]]]} {
+ uplevel \#0 $cmd
+ }
+ after 10
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ configure $path -state $oldstate -relief $oldrelief
+ } else {
+ configure $path -state $oldstate -arrowrelief $oldrelief
+ }
+ if {[llength [set cmd [Widget::getoption $path -disarmcommand]]]} {
+ uplevel \#0 $cmd
+ }
+ if {[llength [set cmd [Widget::getoption $path -command]]]} {
+ uplevel \#0 $cmd
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_redraw
+# ------------------------------------------------------------------------------
+proc ArrowButton::_redraw { path width height } {
+ variable _moved
+
+ set _moved($path) 0
+ set type [Widget::getoption $path -type]
+ set dir [Widget::getoption $path -dir]
+ set bd [expr {[$path.c cget -borderwidth] + [$path.c cget -highlightthickness] + 1}]
+ set clean [Widget::getoption $path -clean]
+ if { [string equal $type "arrow"] } {
+ if { [set id [$path.c find withtag rect]] == "" } {
+ $path.c create rectangle $bd $bd [expr {$width-$bd-1}] [expr {$height-$bd-1}] -tags rect
+ } else {
+ $path.c coords $id $bd $bd [expr {$width-$bd-1}] [expr {$height-$bd-1}]
+ }
+ $path.c lower rect
+ set arrbd [Widget::getoption $path -arrowbd]
+ set bd [expr {$bd+$arrbd-1}]
+ } else {
+ $path.c delete rect
+ }
+ # w and h are max width and max height of arrow
+ set w [expr {$width - 2*([Widget::getoption $path -ipadx]+$bd)}]
+ set h [expr {$height - 2*([Widget::getoption $path -ipady]+$bd)}]
+
+ if { $w < 2 } {set w 2}
+ if { $h < 2 } {set h 2}
+
+ if { $clean > 0 } {
+ # arrange for base to be odd
+ if { [string equal $dir "top"] || [string equal $dir "bottom"] } {
+ if { !($w % 2) } {
+ incr w -1
+ }
+ if { $clean == 2 } {
+ # arrange for h = (w+1)/2
+ set h2 [expr {($w+1)/2}]
+ if { $h2 > $h } {
+ set w [expr {2*$h-1}]
+ } else {
+ set h $h2
+ }
+ }
+ } else {
+ if { !($h % 2) } {
+ incr h -1
+ }
+ if { $clean == 2 } {
+ # arrange for w = (h+1)/2
+ set w2 [expr {($h+1)/2}]
+ if { $w2 > $w } {
+ set h [expr {2*$w-1}]
+ } else {
+ set w $w2
+ }
+ }
+ }
+ }
+
+ set x0 [expr {($width-$w)/2}]
+ set y0 [expr {($height-$h)/2}]
+ set x1 [expr {$x0+$w-1}]
+ set y1 [expr {$y0+$h-1}]
+
+ switch $dir {
+ top {
+ set xd [expr {($x0+$x1)/2}]
+ if { [set id [$path.c find withtag poly]] == "" } {
+ $path.c create polygon $x0 $y1 $x1 $y1 $xd $y0 -tags poly
+ } else {
+ $path.c coords $id $x0 $y1 $x1 $y1 $xd $y0
+ }
+ if { [string equal $type "arrow"] } {
+ if { [set id [$path.c find withtag bot]] == "" } {
+ $path.c create line $x0 $y1 $x1 $y1 $xd $y0 -tags bot
+ } else {
+ $path.c coords $id $x0 $y1 $x1 $y1 $xd $y0
+ }
+ if { [set id [$path.c find withtag top]] == "" } {
+ $path.c create line $x0 $y1 $xd $y0 -tags top
+ } else {
+ $path.c coords $id $x0 $y1 $xd $y0
+ }
+ $path.c itemconfigure top -width $arrbd
+ $path.c itemconfigure bot -width $arrbd
+ } else {
+ $path.c delete top
+ $path.c delete bot
+ }
+ }
+ bottom {
+ set xd [expr {($x0+$x1)/2}]
+ if { [set id [$path.c find withtag poly]] == "" } {
+ $path.c create polygon $x1 $y0 $x0 $y0 $xd $y1 -tags poly
+ } else {
+ $path.c coords $id $x1 $y0 $x0 $y0 $xd $y1
+ }
+ if { [string equal $type "arrow"] } {
+ if { [set id [$path.c find withtag top]] == "" } {
+ $path.c create line $x1 $y0 $x0 $y0 $xd $y1 -tags top
+ } else {
+ $path.c coords $id $x1 $y0 $x0 $y0 $xd $y1
+ }
+ if { [set id [$path.c find withtag bot]] == "" } {
+ $path.c create line $x1 $y0 $xd $y1 -tags bot
+ } else {
+ $path.c coords $id $x1 $y0 $xd $y1
+ }
+ $path.c itemconfigure top -width $arrbd
+ $path.c itemconfigure bot -width $arrbd
+ } else {
+ $path.c delete top
+ $path.c delete bot
+ }
+ }
+ left {
+ set yd [expr {($y0+$y1)/2}]
+ if { [set id [$path.c find withtag poly]] == "" } {
+ $path.c create polygon $x1 $y0 $x1 $y1 $x0 $yd -tags poly
+ } else {
+ $path.c coords $id $x1 $y0 $x1 $y1 $x0 $yd
+ }
+ if { [string equal $type "arrow"] } {
+ if { [set id [$path.c find withtag bot]] == "" } {
+ $path.c create line $x1 $y0 $x1 $y1 $x0 $yd -tags bot
+ } else {
+ $path.c coords $id $x1 $y0 $x1 $y1 $x0 $yd
+ }
+ if { [set id [$path.c find withtag top]] == "" } {
+ $path.c create line $x1 $y0 $x0 $yd -tags top
+ } else {
+ $path.c coords $id $x1 $y0 $x0 $yd
+ }
+ $path.c itemconfigure top -width $arrbd
+ $path.c itemconfigure bot -width $arrbd
+ } else {
+ $path.c delete top
+ $path.c delete bot
+ }
+ }
+ right {
+ set yd [expr {($y0+$y1)/2}]
+ if { [set id [$path.c find withtag poly]] == "" } {
+ $path.c create polygon $x0 $y1 $x0 $y0 $x1 $yd -tags poly
+ } else {
+ $path.c coords $id $x0 $y1 $x0 $y0 $x1 $yd
+ }
+ if { [string equal $type "arrow"] } {
+ if { [set id [$path.c find withtag top]] == "" } {
+ $path.c create line $x0 $y1 $x0 $y0 $x1 $yd -tags top
+ } else {
+ $path.c coords $id $x0 $y1 $x0 $y0 $x1 $yd
+ }
+ if { [set id [$path.c find withtag bot]] == "" } {
+ $path.c create line $x0 $y1 $x1 $yd -tags bot
+ } else {
+ $path.c coords $id $x0 $y1 $x1 $yd
+ }
+ $path.c itemconfigure top -width $arrbd
+ $path.c itemconfigure bot -width $arrbd
+ } else {
+ $path.c delete top
+ $path.c delete bot
+ }
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_redraw_state
+# ------------------------------------------------------------------------------
+proc ArrowButton::_redraw_state { path } {
+ set state [Widget::getoption $path -state]
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ switch $state {
+ normal {set bg -background; set fg -foreground}
+ active {set bg -activebackground; set fg -activeforeground}
+ disabled {set bg -background; set fg -disabledforeground}
+ }
+ set fg [Widget::getoption $path $fg]
+ $path.c configure -background [Widget::getoption $path $bg]
+ $path.c itemconfigure poly -fill $fg -outline $fg
+ } else {
+ switch $state {
+ normal {set stipple ""; set bg [Widget::getoption $path -background] }
+ active {set stipple ""; set bg [Widget::getoption $path -activebackground] }
+ disabled {set stipple gray50; set bg black }
+ }
+ set thrc [Widget::getoption $path -troughcolor]
+ $path.c configure -background [Widget::getoption $path -background]
+ $path.c itemconfigure rect -fill $thrc -outline $thrc
+ $path.c itemconfigure poly -fill $bg -outline $bg -stipple $stipple
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_redraw_relief
+# ------------------------------------------------------------------------------
+proc ArrowButton::_redraw_relief { path } {
+ variable _moved
+
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ if { [string equal [Widget::getoption $path -relief] "sunken"] } {
+ if { !$_moved($path) } {
+ $path.c move poly 1 1
+ set _moved($path) 1
+ }
+ } else {
+ if { $_moved($path) } {
+ $path.c move poly -1 -1
+ set _moved($path) 0
+ }
+ }
+ } else {
+ set col3d [BWidget::get3dcolor $path [Widget::getoption $path -background]]
+ switch [Widget::getoption $path -arrowrelief] {
+ raised {set top [lindex $col3d 1]; set bot [lindex $col3d 0]}
+ sunken {set top [lindex $col3d 0]; set bot [lindex $col3d 1]}
+ }
+ $path.c itemconfigure top -fill $top
+ $path.c itemconfigure bot -fill $bot
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_redraw_whole
+# ------------------------------------------------------------------------------
+proc ArrowButton::_redraw_whole { path width height } {
+ _redraw $path $width $height
+ _redraw_relief $path
+ _redraw_state $path
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_enter
+# ------------------------------------------------------------------------------
+proc ArrowButton::_enter { path } {
+ variable _grab
+ set path [winfo parent $path]
+ set _grab(current) $path
+ if { ![string equal [Widget::getoption $path -state] "disabled"] } {
+ set _grab(oldstate) [Widget::getoption $path -state]
+ configure $path -state active
+ if { $_grab(pressed) == $path } {
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ set _grab(oldrelief) [Widget::getoption $path -relief]
+ configure $path -relief sunken
+ } else {
+ set _grab(oldrelief) [Widget::getoption $path -arrowrelief]
+ configure $path -arrowrelief sunken
+ }
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_leave
+# ------------------------------------------------------------------------------
+proc ArrowButton::_leave { path } {
+ variable _grab
+ set path [winfo parent $path]
+ set _grab(current) ""
+ if { ![string equal [Widget::getoption $path -state] "disabled"] } {
+ configure $path -state $_grab(oldstate)
+ if { $_grab(pressed) == $path } {
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ configure $path -relief $_grab(oldrelief)
+ } else {
+ configure $path -arrowrelief $_grab(oldrelief)
+ }
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_press
+# ------------------------------------------------------------------------------
+proc ArrowButton::_press { path } {
+ variable _grab
+ set path [winfo parent $path]
+ if { ![string equal [Widget::getoption $path -state] "disabled"] } {
+ set _grab(pressed) $path
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ set _grab(oldrelief) [Widget::getoption $path -relief]
+ configure $path -relief sunken
+ } else {
+ set _grab(oldrelief) [Widget::getoption $path -arrowrelief]
+ configure $path -arrowrelief sunken
+ }
+ if {[llength [set cmd [Widget::getoption $path -armcommand]]]} {
+ uplevel \#0 $cmd
+ if { [set delay [Widget::getoption $path -repeatdelay]] > 0 ||
+ [set delay [Widget::getoption $path -repeatinterval]] > 0 } {
+ after $delay [list ArrowButton::_repeat $path]
+ }
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_release
+# ------------------------------------------------------------------------------
+proc ArrowButton::_release { path } {
+ variable _grab
+ set path [winfo parent $path]
+ if { $_grab(pressed) == $path } {
+ set _grab(pressed) ""
+ if { [string equal [Widget::getoption $path -type] "button"] } {
+ configure $path -relief $_grab(oldrelief)
+ } else {
+ configure $path -arrowrelief $_grab(oldrelief)
+ }
+ if {[llength [set cmd [Widget::getoption $path -disarmcommand]]]} {
+ uplevel \#0 $cmd
+ }
+ if { $_grab(current) == $path &&
+ ![string equal [Widget::getoption $path -state] "disabled"] &&
+ [llength [set cmd [Widget::getoption $path -command]]]} {
+ uplevel \#0 $cmd
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_repeat
+# ------------------------------------------------------------------------------
+proc ArrowButton::_repeat { path } {
+ variable _grab
+ if { $_grab(current) == $path && $_grab(pressed) == $path &&
+ ![string equal [Widget::getoption $path -state] "disabled"] &&
+ [llength [set cmd [Widget::getoption $path -armcommand]]]} {
+ uplevel \#0 $cmd
+ }
+ if { $_grab(pressed) == $path &&
+ ([set delay [Widget::getoption $path -repeatinterval]] > 0 ||
+ [set delay [Widget::getoption $path -repeatdelay]] > 0) } {
+ after $delay [list ArrowButton::_repeat $path]
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ArrowButton::_destroy
+# ------------------------------------------------------------------------------
+proc ArrowButton::_destroy { path } {
+ variable _moved
+ Widget::destroy $path
+ unset _moved($path)
+}
diff --git a/modules/tclsci/tcl/BWidget/bitmap.tcl b/modules/tclsci/tcl/BWidget/bitmap.tcl
new file mode 100755
index 000000000..3e157d520
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/bitmap.tcl
@@ -0,0 +1,94 @@
+# ------------------------------------------------------------------------------
+# bitmap.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: bitmap.tcl,v 1.4 2003/10/20 21:23:52 damonc Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - Bitmap::get
+# - Bitmap::_init
+# ----------------------------------------------------------------------------
+namespace eval Bitmap {
+ Widget::define Bitmap bitmap -classonly
+
+ variable path
+ variable _bmp
+ variable _types {
+ photo .gif
+ photo .ppm
+ bitmap .xbm
+ photo .xpm
+ }
+
+ proc use {} {}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Bitmap::get
+# ----------------------------------------------------------------------------
+proc Bitmap::get { name } {
+ variable path
+ variable _bmp
+ variable _types
+
+ if {[info exists _bmp($name)]} {
+ return $_bmp($name)
+ }
+
+ # --- Nom de fichier avec extension ---------------------------------
+ set ext [file extension $name]
+ if { $ext != "" } {
+ if { ![info exists _bmp($ext)] } {
+ error "$ext not supported"
+ }
+
+ if { [file exists $name] } {
+ if {[string equal $ext ".xpm"]} {
+ set _bmp($name) [xpm-to-image $name]
+ return $_bmp($name)
+ }
+ if {![catch {set _bmp($name) [image create $_bmp($ext) -file $name]}]} {
+ return $_bmp($name)
+ }
+ }
+ }
+
+ foreach dir $path {
+ foreach {type ext} $_types {
+ if { [file exists [file join $dir $name$ext]] } {
+ if {[string equal $ext ".xpm"]} {
+ set _bmp($name) [xpm-to-image [file join $dir $name$ext]]
+ return $_bmp($name)
+ } else {
+ if {![catch {set _bmp($name) [image create $type -file [file join $dir $name$ext]]}]} {
+ return $_bmp($name)
+ }
+ }
+ }
+ }
+ }
+
+ return -code error "$name not found"
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Bitmap::_init
+# ----------------------------------------------------------------------------
+proc Bitmap::_init { } {
+ global env
+ variable path
+ variable _bmp
+ variable _types
+
+ set path [list "." [file join $::BWIDGET::LIBRARY images]]
+ set supp [image types]
+ foreach {type ext} $_types {
+ if { [lsearch $supp $type] != -1} {
+ set _bmp($ext) $type
+ }
+ }
+}
+
+
+Bitmap::_init
diff --git a/modules/tclsci/tcl/BWidget/button.tcl b/modules/tclsci/tcl/BWidget/button.tcl
new file mode 100755
index 000000000..5b8fc23c5
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/button.tcl
@@ -0,0 +1,393 @@
+# ----------------------------------------------------------------------------
+# button.tcl
+# This file is part of Unifix BWidget Toolkit
+# ----------------------------------------------------------------------------
+# Index of commands:
+# Public commands
+# - Button::create
+# - Button::configure
+# - Button::cget
+# - Button::invoke
+# Private commands (event bindings)
+# - Button::_destroy
+# - Button::_enter
+# - Button::_leave
+# - Button::_press
+# - Button::_release
+# - Button::_repeat
+# ----------------------------------------------------------------------------
+
+namespace eval Button {
+ Widget::define Button button DynamicHelp
+
+ set remove [list -command -relief -text -textvariable -underline -state]
+ if {[info tclversion] > 8.3} {
+ lappend remove -repeatdelay -repeatinterval
+ }
+ Widget::tkinclude Button button :cmd remove $remove
+
+ Widget::declare Button {
+ {-name String "" 0}
+ {-text String "" 0}
+ {-textvariable String "" 0}
+ {-underline Int -1 0 "%d >= -1"}
+ {-armcommand String "" 0}
+ {-disarmcommand String "" 0}
+ {-command String "" 0}
+ {-state TkResource "" 0 button}
+ {-repeatdelay Int 0 0 "%d >= 0"}
+ {-repeatinterval Int 0 0 "%d >= 0"}
+ {-relief Enum raised 0 {raised sunken flat ridge solid groove link}}
+ }
+
+ DynamicHelp::include Button balloon
+
+ Widget::syncoptions Button "" :cmd {-text {} -underline {}}
+
+ variable _current ""
+ variable _pressed ""
+
+ bind BwButton <Enter> {Button::_enter %W}
+ bind BwButton <Leave> {Button::_leave %W}
+ bind BwButton <ButtonPress-1> {Button::_press %W}
+ bind BwButton <ButtonRelease-1> {Button::_release %W}
+ bind BwButton <Key-space> {Button::invoke %W; break}
+ bind BwButton <Return> {Button::invoke %W; break}
+ bind BwButton <<Invoke>> {Button::invoke %W; break}
+ bind BwButton <Destroy> {Widget::destroy %W}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::create
+# ----------------------------------------------------------------------------
+proc Button::create { path args } {
+ array set maps [list Button {} :cmd {}]
+ array set maps [Widget::parseArgs Button $args]
+ if {$::Widget::_theme} {
+ eval [concat [list ttk::button $path] $maps(:cmd)]
+ } else {
+ eval [concat [list button $path] $maps(:cmd)]
+ }
+ Widget::initFromODB Button $path $maps(Button)
+
+ # Do some extra configuration on the button
+ set var [Widget::getMegawidgetOption $path -textvariable]
+ set st [Widget::getMegawidgetOption $path -state]
+ if { ![string length $var] } {
+ set desc [BWidget::getname [Widget::getMegawidgetOption $path -name]]
+ if { [llength $desc] } {
+ set text [lindex $desc 0]
+ set under [lindex $desc 1]
+ Widget::configure $path [list -text $text]
+ Widget::configure $path [list -underline $under]
+ } else {
+ set text [Widget::getMegawidgetOption $path -text]
+ set under [Widget::getMegawidgetOption $path -underline]
+ }
+ } else {
+ set under -1
+ set text ""
+ Widget::configure $path [list -underline $under]
+ }
+
+ $path configure -text $text -underline $under \
+ -textvariable $var -state $st
+ # Map relief flat on Toolbutton for ttk
+ set relief [Widget::getMegawidgetOption $path -relief]
+ if {$::Widget::_theme} {
+ if { [string equal $relief "link"] } {
+ $path configure -style Toolbutton
+ }
+ } else {
+ if { [string equal $relief "link"] } {
+ set relief "flat"
+ }
+ $path configure -relief $relief
+ }
+ bindtags $path [list $path BwButton [winfo toplevel $path] all]
+
+ set accel1 [string tolower [string index $text $under]]
+ set accel2 [string toupper $accel1]
+ if { $accel1 != "" } {
+ bind [winfo toplevel $path] <Alt-$accel1> [list Button::invoke $path]
+ bind [winfo toplevel $path] <Alt-$accel2> [list Button::invoke $path]
+ }
+
+ DynamicHelp::sethelp $path $path 1
+
+ return [Widget::create Button $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::configure
+# ----------------------------------------------------------------------------
+proc Button::configure { path args } {
+ set oldunder [$path:cmd cget -underline]
+ if { $oldunder != -1 } {
+ set oldaccel1 [string tolower [string index [$path:cmd cget -text] $oldunder]]
+ set oldaccel2 [string toupper $oldaccel1]
+ } else {
+ set oldaccel1 ""
+ set oldaccel2 ""
+ }
+ set res [Widget::configure $path $args]
+
+ # Extract all the modified bits we're interested in
+ foreach {cr cs cv cn ct cu} [Widget::hasChangedX $path \
+ -relief -state -textvariable -name -text -underline] break
+ if { $cr || $cs } {
+ set relief [Widget::cget $path -relief]
+ set state [Widget::cget $path -state]
+ if { $::Widget::_theme} {
+ if { [string equal $relief "link"] } {
+ $path:cmd configure -style Toolbutton
+ } else {
+ $path:cmd configure -style ""
+ }
+ } else {
+ if { [string equal $relief "link"] } {
+ if { [string equal $state "active"] } {
+ set relief "raised"
+ } else {
+ set relief "flat"
+ }
+ }
+ $path:cmd configure -relief $relief
+ }
+ $path:cmd configure -state $state
+ }
+
+ if { $cv || $cn || $ct || $cu } {
+ set var [Widget::cget $path -textvariable]
+ set text [Widget::cget $path -text]
+ set under [Widget::cget $path -underline]
+ if { ![string length $var] } {
+ set desc [BWidget::getname [Widget::cget $path -name]]
+ if { [llength $desc] } {
+ set text [lindex $desc 0]
+ set under [lindex $desc 1]
+ }
+ } else {
+ set under -1
+ set text ""
+ }
+ set top [winfo toplevel $path]
+ if { $oldaccel1 != "" } {
+ bind $top <Alt-$oldaccel1> {}
+ bind $top <Alt-$oldaccel2> {}
+ }
+ set accel1 [string tolower [string index $text $under]]
+ set accel2 [string toupper $accel1]
+ if { $accel1 != "" } {
+ bind $top <Alt-$accel1> [list Button::invoke $path]
+ bind $top <Alt-$accel2> [list Button::invoke $path]
+ }
+ $path:cmd configure -text $text -underline $under -textvariable $var
+ }
+ DynamicHelp::sethelp $path $path
+
+ set res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::cget
+# ----------------------------------------------------------------------------
+proc Button::cget { path option } {
+ Widget::cget $path $option
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::identify
+# ----------------------------------------------------------------------------
+proc Button::identify { path args } {
+ eval $path:cmd identify $args
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::instate
+# ----------------------------------------------------------------------------
+proc Button::instate { path args } {
+ eval $path:cmd instate $args
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::state
+# ----------------------------------------------------------------------------
+proc Button::state { path args } {
+ eval $path:cmd state $args
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::invoke
+# ----------------------------------------------------------------------------
+proc Button::invoke { path } {
+ if { ![string equal [$path:cmd cget -state] "disabled"] } {
+ if { $::Widget::_theme} {
+ $path:cmd configure -state active
+ $path:cmd state pressed
+ } else {
+ $path:cmd configure -state active -relief sunken
+ }
+ update idletasks
+ set cmd [Widget::getMegawidgetOption $path -armcommand]
+ if { $cmd != "" } {
+ uplevel \#0 $cmd
+ }
+ after 100
+ $path:cmd configure -state [Widget::getMegawidgetOption $path -state]
+ if { $::Widget::_theme} {
+ $path:cmd state !pressed
+ } else {
+ set relief [Widget::getMegawidgetOption $path -relief]
+ if { [string equal $relief "link"] } {
+ set relief flat
+ }
+ $path:cmd configure -relief $relief
+ }
+ set cmd [Widget::getMegawidgetOption $path -disarmcommand]
+ if { $cmd != "" } {
+ uplevel \#0 $cmd
+ }
+ set cmd [Widget::getMegawidgetOption $path -command]
+ if { $cmd != "" } {
+ uplevel \#0 $cmd
+ }
+ }
+}
+
+# ----------------------------------------------------------------------------
+# Command Button::_enter
+# ----------------------------------------------------------------------------
+proc Button::_enter { path } {
+ variable _current
+ variable _pressed
+
+ set _current $path
+ if { ![string equal [$path:cmd cget -state] "disabled"] } {
+ $path:cmd configure -state active
+ if { $::Widget::_theme } {
+ # $path:cmd state active
+ } else {
+ if { $_pressed == $path } {
+ $path:cmd configure -relief sunken
+ } elseif { [string equal [Widget::cget $path -relief] "link"] } {
+ $path:cmd configure -relief raised
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::_leave
+# ----------------------------------------------------------------------------
+proc Button::_leave { path } {
+ variable _current
+ variable _pressed
+
+ set _current ""
+ if { ![string equal [$path:cmd cget -state] "disabled"] } {
+ $path:cmd configure -state [Widget::cget $path -state]
+ if { $::Widget::_theme } {
+ } else {
+ set relief [Widget::cget $path -relief]
+ if { $_pressed == $path } {
+ if { [string equal $relief "link"] } {
+ set relief raised
+ }
+ $path:cmd configure -relief $relief
+ } elseif { [string equal $relief "link"] } {
+ $path:cmd configure -relief flat
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::_press
+# ----------------------------------------------------------------------------
+proc Button::_press { path } {
+ variable _pressed
+
+ if { ![string equal [$path:cmd cget -state] "disabled"] } {
+ set _pressed $path
+ if { $::Widget::_theme} {
+ ttk::clickToFocus $path
+ $path state pressed
+ } else {
+ $path:cmd configure -relief sunken
+ }
+ set cmd [Widget::getMegawidgetOption $path -armcommand]
+ if { $cmd != "" } {
+ uplevel \#0 $cmd
+ set repeatdelay [Widget::getMegawidgetOption $path -repeatdelay]
+ set repeatint [Widget::getMegawidgetOption $path -repeatinterval]
+ if { $repeatdelay > 0 } {
+ after $repeatdelay "Button::_repeat $path"
+ } elseif { $repeatint > 0 } {
+ after $repeatint "Button::_repeat $path"
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::_release
+# ----------------------------------------------------------------------------
+proc Button::_release { path } {
+ variable _current
+ variable _pressed
+
+ if { $_pressed == $path } {
+ set _pressed ""
+ after cancel "Button::_repeat $path"
+ if { $::Widget::_theme} {
+ $path state !pressed
+ } else {
+ set relief [Widget::getMegawidgetOption $path -relief]
+ if { [string equal $relief "link"] } {
+ set relief raised
+ }
+ $path:cmd configure -relief $relief
+ }
+ set cmd [Widget::getMegawidgetOption $path -disarmcommand]
+ if { $cmd != "" } {
+ uplevel \#0 $cmd
+ }
+ if { $_current == $path &&
+ ![string equal [$path:cmd cget -state] "disabled"] && \
+ [set cmd [Widget::getMegawidgetOption $path -command]] != "" } {
+ uplevel \#0 $cmd
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Button::_repeat
+# ----------------------------------------------------------------------------
+proc Button::_repeat { path } {
+ variable _current
+ variable _pressed
+
+ if { $_current == $path && $_pressed == $path &&
+ ![string equal [$path:cmd cget -state] "disabled"] &&
+ [set cmd [Widget::getMegawidgetOption $path -armcommand]] != "" } {
+ uplevel \#0 $cmd
+ }
+ if { $_pressed == $path &&
+ ([set delay [Widget::getMegawidgetOption $path -repeatinterval]] >0 ||
+ [set delay [Widget::getMegawidgetOption $path -repeatdelay]] > 0) } {
+ after $delay "Button::_repeat $path"
+ }
+}
+
diff --git a/modules/tclsci/tcl/BWidget/buttonbox.tcl b/modules/tclsci/tcl/BWidget/buttonbox.tcl
new file mode 100755
index 000000000..9fefc2a37
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/buttonbox.tcl
@@ -0,0 +1,419 @@
+# ----------------------------------------------------------------------------
+# buttonbox.tcl
+# This file is part of Unifix BWidget Toolkit
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - ButtonBox::create
+# - ButtonBox::configure
+# - ButtonBox::cget
+# - ButtonBox::add
+# - ButtonBox::itemconfigure
+# - ButtonBox::itemcget
+# - ButtonBox::setfocus
+# - ButtonBox::invoke
+# - ButtonBox::index
+# - ButtonBox::_destroy
+# ----------------------------------------------------------------------------
+
+namespace eval ButtonBox {
+ Widget::define ButtonBox buttonbox Button
+
+ Widget::declare ButtonBox {
+ {-background TkResource "" 0 frame}
+ {-orient Enum horizontal 1 {horizontal vertical}}
+ {-state Enum "normal" 0 {normal disabled}}
+ {-homogeneous Boolean 1 1}
+ {-spacing Int 10 0 "%d >= 0"}
+ {-padx TkResource "" 0 button}
+ {-pady TkResource "" 0 button}
+ {-default Int -1 0 "%d >= -1"}
+ {-bg Synonym -background}
+ }
+
+ Widget::addmap ButtonBox "" :cmd {-background {}}
+
+ bind ButtonBox <Destroy> [list ButtonBox::_destroy %W]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::create
+# ----------------------------------------------------------------------------
+proc ButtonBox::create { path args } {
+ Widget::init ButtonBox $path $args
+
+ variable $path
+ upvar 0 $path data
+
+ eval [list frame $path] [Widget::subcget $path :cmd] \
+ [list -class ButtonBox -takefocus 0 -highlightthickness 0]
+ # For 8.4+ we don't want to inherit the padding
+ catch {$path configure -padx 0 -pady 0}
+
+ set data(max) 0
+ set data(nbuttons) 0
+ set data(buttons) [list]
+ set data(default) [Widget::getoption $path -default]
+
+ return [Widget::create ButtonBox $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::configure
+# ----------------------------------------------------------------------------
+proc ButtonBox::configure { path args } {
+ variable $path
+ upvar 0 $path data
+
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -default val] } {
+ if { $data(default) != -1 && $val != -1 } {
+ set but $path.b$data(default)
+ if { [winfo exists $but] } {
+ $but configure -default normal
+ }
+ set but $path.b$val
+ if { [winfo exists $but] } {
+ $but configure -default active
+ }
+ set data(default) $val
+ } else {
+ Widget::setoption $path -default $data(default)
+ }
+ }
+
+ if {[Widget::hasChanged $path -state val]} {
+ foreach i $data(buttons) {
+ $path.b$i configure -state $val
+ }
+ }
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::cget
+# ----------------------------------------------------------------------------
+proc ButtonBox::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::add
+# ----------------------------------------------------------------------------
+proc ButtonBox::add { path args } {
+ return [eval [linsert $args 0 insert $path end]]
+}
+
+
+proc ButtonBox::insert { path idx args } {
+ variable $path
+ upvar 0 $path data
+
+ set but $path.b$data(nbuttons)
+ set spacing [Widget::getoption $path -spacing]
+
+ ## Save the current spacing setting for this button. Buttons
+ ## appended to the end of the box have their spacing applied
+ ## to their left while all other have their spacing applied
+ ## to their right.
+ if {$idx == "end"} {
+ set data(spacing,$data(nbuttons)) [list left $spacing]
+ lappend data(buttons) $data(nbuttons)
+ } else {
+ set data(spacing,$data(nbuttons)) [list right $spacing]
+ set data(buttons) [linsert $data(buttons) $idx $data(nbuttons)]
+ }
+
+ if { $data(nbuttons) == $data(default) } {
+ set style active
+ } elseif { $data(default) == -1 } {
+ set style disabled
+ } else {
+ set style normal
+ }
+
+ array set flags $args
+ set tags ""
+ if { [info exists flags(-tags)] } {
+ set tags $flags(-tags)
+ unset flags(-tags)
+ set args [array get flags]
+ }
+
+ if { $::Widget::_theme} {
+ eval [list Button::create $but] \
+ $args [list -default $style]
+ } else {
+ eval [list Button::create $but \
+ -background [Widget::getoption $path -background]\
+ -padx [Widget::getoption $path -padx] \
+ -pady [Widget::getoption $path -pady]] \
+ $args [list -default $style]
+ }
+
+ # ericm@scriptics.com: set up tags, just like the menu items
+ foreach tag $tags {
+ lappend data(tags,$tag) $but
+ if { ![info exists data(tagstate,$tag)] } {
+ set data(tagstate,$tag) 0
+ }
+ }
+ set data(buttontags,$but) $tags
+ # ericm@scriptics.com
+
+ _redraw $path
+
+ incr data(nbuttons)
+
+ return $but
+}
+
+
+proc ButtonBox::delete { path idx } {
+ variable $path
+ upvar 0 $path data
+
+ set i [lindex $data(buttons) $idx]
+ set data(buttons) [lreplace $data(buttons) $idx $idx]
+ destroy $path.b$i
+}
+
+
+# ButtonBox::setbuttonstate --
+#
+# Set the state of a given button tag. If this makes any buttons
+# enable-able (ie, all of their tags are TRUE), enable them.
+#
+# Arguments:
+# path the button box widget name
+# tag the tag to modify
+# state the new state of $tag (0 or 1)
+#
+# Results:
+# None.
+
+proc ButtonBox::setbuttonstate {path tag state} {
+ variable $path
+ upvar 0 $path data
+ # First see if this is a real tag
+ if { [info exists data(tagstate,$tag)] } {
+ set data(tagstate,$tag) $state
+ foreach but $data(tags,$tag) {
+ set expression "1"
+ foreach buttontag $data(buttontags,$but) {
+ append expression " && $data(tagstate,$buttontag)"
+ }
+ if { [expr $expression] } {
+ set state normal
+ } else {
+ set state disabled
+ }
+ $but configure -state $state
+ }
+ }
+ return
+}
+
+# ButtonBox::getbuttonstate --
+#
+# Retrieve the state of a given button tag.
+#
+# Arguments:
+# path the button box widget name
+# tag the tag to modify
+#
+# Results:
+# None.
+
+proc ButtonBox::getbuttonstate {path tag} {
+ variable $path
+ upvar 0 $path data
+ # First see if this is a real tag
+ if { [info exists data(tagstate,$tag)] } {
+ return $data(tagstate,$tag)
+ } else {
+ error "unknown tag $tag"
+ }
+}
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::itemconfigure
+# ----------------------------------------------------------------------------
+proc ButtonBox::itemconfigure { path index args } {
+ if { [set idx [lsearch $args -default]] != -1 } {
+ set args [lreplace $args $idx [expr {$idx+1}]]
+ }
+ return [eval [list Button::configure $path.b[index $path $index]] $args]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::itemcget
+# ----------------------------------------------------------------------------
+proc ButtonBox::itemcget { path index option } {
+ return [Button::cget $path.b[index $path $index] $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::setfocus
+# ----------------------------------------------------------------------------
+proc ButtonBox::setfocus { path index } {
+ set but $path.b[index $path $index]
+ if { [winfo exists $but] } {
+ focus $but
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::invoke
+# ----------------------------------------------------------------------------
+proc ButtonBox::invoke { path index } {
+ set but $path.b[index $path $index]
+ if { [winfo exists $but] } {
+ Button::invoke $but
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::index
+# ----------------------------------------------------------------------------
+proc ButtonBox::index { path index } {
+ variable $path
+ upvar 0 $path data
+
+ set n [expr {$data(nbuttons) - 1}]
+
+ if {[string equal $index "default"]} {
+ set res [Widget::getoption $path -default]
+ } elseif {$index == "end" || $index == "last"} {
+ set res $n
+ } elseif {![string is integer -strict $index]} {
+ ## It's not an integer. Search the text of each button
+ ## in the box and return the index that matches.
+ foreach i $data(buttons) {
+ set w $path.b$i
+ lappend text [$w cget -text]
+ lappend names [$w cget -name]
+ }
+ set res [lsearch -exact [concat $names $text] $index]
+ } else {
+ set res $index
+ if {$index > $n} { set res $n }
+ }
+ return $res
+}
+
+
+# ButtonBox::gettags --
+#
+# Return a list of all the tags on all the buttons in a buttonbox.
+#
+# Arguments:
+# path the buttonbox to query.
+#
+# Results:
+# taglist a list of tags on the buttons in the buttonbox
+
+proc ButtonBox::gettags {path} {
+ upvar ::ButtonBox::$path data
+ set taglist {}
+ foreach tag [array names data "tags,*"] {
+ lappend taglist [string range $tag 5 end]
+ }
+ return $taglist
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::_redraw
+# ----------------------------------------------------------------------------
+proc ButtonBox::_redraw { path } {
+ variable $path
+ upvar 0 $path data
+ Widget::getVariable $path buttons
+
+ # For tk >= 8.4, -uniform gridding option is used.
+ # Otherwise, there is the constraint, that button size may not change after
+ # creation.
+ set uniformAvailable [expr {0 <= [package vcompare [info patchlevel] 8.4.0]}]
+
+ ## We re-grid the buttons from left-to-right. As we go through
+ ## each button, we check its spacing and which direction the
+ ## spacing applies to. Once spacing has been applied to an index,
+ ## it is not changed. This means spacing takes precedence from
+ ## left-to-right.
+
+ set idx 0
+ set idxs [list]
+ foreach i $data(buttons) {
+ set dir [lindex $data(spacing,$i) 0]
+ set spacing [lindex $data(spacing,$i) 1]
+ set but $path.b$i
+ if {[string equal [Widget::getoption $path -orient] "horizontal"]} {
+ grid $but -column $idx -row 0 -sticky nsew
+ if { [Widget::getoption $path -homogeneous] } {
+ if {$uniformAvailable} {
+ grid columnconfigure $path $idx -uniform koen -weight 1
+ } else {
+ set req [winfo reqwidth $but]
+ if { $req > $data(max) } {
+ grid columnconfigure $path [expr {2*$i}] -minsize $req
+ set data(max) $req
+ }
+ grid columnconfigure $path $idx -weight 1
+ }
+ } else {
+ grid columnconfigure $path $idx -weight 0
+ }
+
+ set col [expr {$idx - 1}]
+ if {[string equal $dir "right"]} { set col [expr {$idx + 1}] }
+ if {$col > 0 && [lsearch $idxs $col] < 0} {
+ lappend idxs $col
+ grid columnconfigure $path $col -minsize $spacing
+ }
+ } else {
+ grid $but -column 0 -row $idx -sticky nsew
+ grid rowconfigure $path $idx -weight 0
+
+ set row [expr {$idx - 1}]
+ if {[string equal $dir "right"]} { set row [expr {$idx + 1}] }
+ if {$row > 0 && [lsearch $idxs $row] < 0} {
+ lappend idxs $row
+ grid rowconfigure $path $row -minsize $spacing
+ }
+ }
+ incr idx 2
+ }
+
+ if {!$uniformAvailable} {
+ # Now that the maximum size has been calculated, go back through
+ # and correctly set the size for homogeneous horizontal buttons.
+ if { [string equal [Widget::getoption $path -orient] "horizontal"] && [Widget::getoption $path -homogeneous] } {
+ set idx 0
+ foreach i $data(buttons) {
+ grid columnconfigure $path $idx -minsize $data(max)
+ incr idx 2
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ButtonBox::_destroy
+# ----------------------------------------------------------------------------
+proc ButtonBox::_destroy { path } {
+ variable $path
+ upvar 0 $path data
+ Widget::destroy $path
+ unset data
+}
diff --git a/modules/tclsci/tcl/BWidget/color.tcl b/modules/tclsci/tcl/BWidget/color.tcl
new file mode 100755
index 000000000..dd545eddc
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/color.tcl
@@ -0,0 +1,493 @@
+namespace eval SelectColor {
+ Widget::define SelectColor color Dialog
+
+ Widget::declare SelectColor {
+ {-title String "Select a color" 0}
+ {-parent String "" 0}
+ {-color TkResource "" 0 {label -background}}
+ {-type Enum "dialog" 1 {dialog popup}}
+ {-placement String "center" 1}
+ }
+
+ variable _baseColors {
+ \#0000ff \#00ff00 \#00ffff \#ff0000 \#ff00ff \#ffff00
+ \#000099 \#009900 \#009999 \#990000 \#990099 \#999900
+ \#000000 \#333333 \#666666 \#999999 \#cccccc \#ffffff
+ }
+
+ variable _userColors {
+ \#ffffff \#ffffff \#ffffff \#ffffff \#ffffff \#ffffff
+ \#ffffff \#ffffff \#ffffff \#ffffff \#ffffff
+ }
+
+ if {[string equal $::tcl_platform(platform) "unix"]} {
+ set useTkDialogue 0
+ } else {
+ set useTkDialogue 1
+ }
+
+ variable _selectype
+ variable _selection
+ variable _wcolor
+ variable _image
+ variable _hsv
+}
+
+proc SelectColor::create { path args } {
+ Widget::init SelectColor $path $args
+
+ set type [Widget::cget $path -type]
+
+ switch -- [Widget::cget $path -type] {
+ "dialog" {
+ return [eval [list SelectColor::dialog $path] $args]
+ }
+
+ "popup" {
+ set list [list at center left right above below]
+ set placement [Widget::cget $path -placement]
+ set where [lindex $placement 0]
+
+ if {[lsearch $list $where] < 0} {
+ return -code error \
+ [BWidget::badOptionString placement $placement $list]
+ }
+
+ ## If they specified a parent and didn't pass a second argument
+ ## in the placement, set the placement relative to the parent.
+ set parent [Widget::cget $path -parent]
+ if {[string length $parent]} {
+ if {[llength $placement] == 1} { lappend placement $parent }
+ }
+ return [eval [list SelectColor::menu $path $placement] $args]
+ }
+ }
+}
+
+proc SelectColor::menu {path placement args} {
+ variable _baseColors
+ variable _userColors
+ variable _wcolor
+ variable _selectype
+ variable _selection
+
+ Widget::init SelectColor $path $args
+ set top [toplevel $path]
+ set parent [winfo toplevel [winfo parent $top]]
+ wm withdraw $top
+ wm transient $top $parent
+ wm overrideredirect $top 1
+ catch { wm attributes $top -topmost 1 }
+
+ set frame [frame $top.frame \
+ -highlightthickness 0 \
+ -relief raised -borderwidth 2]
+ set col 0
+ set row 0
+ set count 0
+ set colors [concat $_baseColors $_userColors]
+ foreach color $colors {
+ set f [frame $frame.c$count \
+ -highlightthickness 2 \
+ -highlightcolor white \
+ -relief solid -borderwidth 1 \
+ -width 16 -height 16 -background $color]
+ bind $f <1> "set SelectColor::_selection $count; break"
+ bind $f <Enter> {focus %W}
+ grid $f -column $col -row $row
+ incr count
+ if {[incr col] == 6 } {
+ set col 0
+ incr row
+ }
+ }
+ set f [label $frame.c$count \
+ -highlightthickness 2 \
+ -highlightcolor white \
+ -relief flat -borderwidth 0 \
+ -width 16 -height 16 -image [Bitmap::get palette]]
+ grid $f -column $col -row $row
+ bind $f <1> "set SelectColor::_selection $count; break"
+ bind $f <Enter> {focus %W}
+ pack $frame
+
+ bind $top <1> {set SelectColor::_selection -1}
+ bind $top <Escape> {set SelectColor::_selection -2}
+ bind $top <FocusOut> [subst {if {"%W" == "$top"} \
+ {set SelectColor::_selection -2}}]
+ eval [list BWidget::place $top 0 0] $placement
+
+ wm deiconify $top
+ raise $top
+ if {$::tcl_platform(platform) == "unix"} {
+ tkwait visibility $top
+ update
+ }
+ BWidget::SetFocusGrab $top $frame.c0
+
+ vwait SelectColor::_selection
+ BWidget::RestoreFocusGrab $top $frame.c0 destroy
+ Widget::destroy $top
+ if {$_selection == $count} {
+ array set opts {
+ -parent -parent
+ -title -title
+ -color -initialcolor
+ }
+ if {[Widget::theme]} {
+ set native 1
+ set nativecmd [list tk_chooseColor -parent $parent]
+ foreach {key val} $args {
+ if {![info exists opts($key)]} {
+ set native 0
+ break
+ }
+ lappend nativecmd $opts($key) $val
+ }
+ if {$native} {
+ return [eval $nativecmd]
+ }
+ }
+ return [eval [list dialog $path] $args]
+ } else {
+ return [lindex $colors $_selection]
+ }
+}
+
+
+proc SelectColor::dialog {path args} {
+ variable _baseColors
+ variable _userColors
+ variable _widget
+ variable _selection
+ variable _image
+ variable _hsv
+
+ Widget::init SelectColor $path:SelectColor $args
+ set top [Dialog::create $path \
+ -title [Widget::cget $path:SelectColor -title] \
+ -parent [Widget::cget $path:SelectColor -parent] \
+ -separator 1 -default 0 -cancel 1 -anchor e]
+ wm resizable $top 0 0
+ set dlgf [$top getframe]
+ set fg [frame $dlgf.fg]
+ set desc [list \
+ base _baseColors "Base colors" \
+ user _userColors "User colors"]
+ set count 0
+ foreach {type varcol defTitle} $desc {
+ set col 0
+ set lin 0
+ set title [lindex [BWidget::getname "${type}Colors"] 0]
+ if {![string length $title]} {
+ set title $defTitle
+ }
+ set titf [TitleFrame $fg.$type -text $title]
+ set subf [$titf getframe]
+ foreach color [set $varcol] {
+ set fround [frame $fg.round$count \
+ -highlightthickness 1 \
+ -relief sunken -borderwidth 2]
+ set fcolor [frame $fg.color$count -width 16 -height 12 \
+ -highlightthickness 0 \
+ -relief flat -borderwidth 0 \
+ -background $color]
+ pack $fcolor -in $fround
+ grid $fround -in $subf -row $lin -column $col -padx 1 -pady 1
+
+ bind $fround <ButtonPress-1> [list SelectColor::_select_rgb $count]
+ bind $fcolor <ButtonPress-1> [list SelectColor::_select_rgb $count]
+
+ bind $fround <Double-1> \
+ "SelectColor::_select_rgb [list $count]; [list $top] invoke 0"
+ bind $fcolor <Double-1> \
+ "SelectColor::_select_rgb [list $count]; [list $top] invoke 0"
+
+ incr count
+ if {[incr col] == 6} {
+ incr lin
+ set col 0
+ }
+ }
+ pack $titf -anchor w -pady 2
+ }
+ set fround [frame $fg.round \
+ -highlightthickness 0 \
+ -relief sunken -borderwidth 2]
+ set fcolor [frame $fg.color \
+ -width 50 \
+ -highlightthickness 0 \
+ -relief flat -borderwidth 0]
+ pack $fcolor -in $fround -fill y -expand yes
+ pack $fround -anchor e -pady 2 -fill y -expand yes
+
+ set fd [frame $dlgf.fd]
+ set f1 [frame $fd.f1 -relief sunken -borderwidth 2]
+ set f2 [frame $fd.f2 -relief sunken -borderwidth 2]
+ set c1 [canvas $f1.c -width 200 -height 200 -bd 0 -highlightthickness 0]
+ set c2 [canvas $f2.c -width 15 -height 200 -bd 0 -highlightthickness 0]
+
+ for {set val 0} {$val < 40} {incr val} {
+ $c2 create rectangle 0 [expr {5*$val}] 15 [expr {5*$val+5}] -tags val[expr {39-$val}]
+ }
+ $c2 create polygon 0 0 10 5 0 10 -fill black -outline white -tags target
+
+ pack $c1 $c2
+ pack $f1 $f2 -side left -padx 10 -anchor n
+
+ pack $fg $fd -side left -anchor n -fill y
+
+ bind $c1 <ButtonPress-1> [list SelectColor::_select_hue_sat %x %y]
+ bind $c1 <B1-Motion> [list SelectColor::_select_hue_sat %x %y]
+
+ bind $c2 <ButtonPress-1> [list SelectColor::_select_value %x %y]
+ bind $c2 <B1-Motion> [list SelectColor::_select_value %x %y]
+
+ if {![info exists _image] || [catch {image type $_image}]} {
+ set _image [image create photo -width 200 -height 200]
+ for {set x 0} {$x < 200} {incr x 4} {
+ for {set y 0} {$y < 200} {incr y 4} {
+ $_image put \
+ [eval [list format "\#%04x%04x%04x"] \
+ [hsvToRgb [expr {$x/196.0}] [expr {(196-$y)/196.0}] 0.85]] \
+ -to $x $y [expr {$x+4}] [expr {$y+4}]
+ }
+ }
+ }
+ $c1 create image 0 0 -anchor nw -image $_image
+ $c1 create bitmap 0 0 \
+ -bitmap @[file join $::BWIDGET::LIBRARY "images" "target.xbm"] \
+ -anchor nw -tags target
+
+ set _selection -1
+ set _widget(fcolor) $fg
+ set _widget(chs) $c1
+ set _widget(cv) $c2
+ set rgb [winfo rgb $path [Widget::cget $path:SelectColor -color]]
+ set _hsv [eval rgbToHsv $rgb]
+ _set_rgb [eval [list format "\#%04x%04x%04x"] $rgb]
+ _set_hue_sat [lindex $_hsv 0] [lindex $_hsv 1]
+ _set_value [lindex $_hsv 2]
+
+ $top add -name ok
+ $top add -name cancel
+ set res [$top draw]
+ if {$res == 0} {
+ set color [$fg.color cget -background]
+ } else {
+ set color ""
+ }
+ destroy $top
+ return $color
+}
+
+proc SelectColor::setcolor { idx color } {
+ variable _userColors
+ set _userColors [lreplace $_userColors $idx $idx $color]
+}
+
+proc SelectColor::_select_rgb {count} {
+ variable _baseColors
+ variable _userColors
+ variable _selection
+ variable _widget
+ variable _hsv
+
+ set frame $_widget(fcolor)
+ if {$_selection >= 0} {
+ $frame.round$_selection configure \
+ -relief sunken -highlightthickness 1 -borderwidth 2
+ }
+ $frame.round$count configure \
+ -relief flat -highlightthickness 2 -borderwidth 1
+ focus $frame.round$count
+ set _selection $count
+ set bg [$frame.color$count cget -background]
+ set user [expr {$_selection-[llength $_baseColors]}]
+ if {$user >= 0 &&
+ [string equal \
+ [winfo rgb $frame.color$_selection $bg] \
+ [winfo rgb $frame.color$_selection white]]} {
+ set bg [$frame.color cget -bg]
+ $frame.color$_selection configure -background $bg
+ set _userColors [lreplace $_userColors $user $user $bg]
+ } else {
+ set _hsv [eval rgbToHsv [winfo rgb $frame.color$count $bg]]
+ _set_hue_sat [lindex $_hsv 0] [lindex $_hsv 1]
+ _set_value [lindex $_hsv 2]
+ $frame.color configure -background $bg
+ }
+}
+
+
+proc SelectColor::_set_rgb {rgb} {
+ variable _selection
+ variable _baseColors
+ variable _userColors
+ variable _widget
+
+ set frame $_widget(fcolor)
+ $frame.color configure -background $rgb
+ set user [expr {$_selection-[llength $_baseColors]}]
+ if {$user >= 0} {
+ $frame.color$_selection configure -background $rgb
+ set _userColors [lreplace $_userColors $user $user $rgb]
+ }
+}
+
+
+proc SelectColor::_select_hue_sat {x y} {
+ variable _widget
+ variable _hsv
+
+ if {$x < 0} {
+ set x 0
+ } elseif {$x > 200} {
+ set x 200
+ }
+ if {$y < 0 } {
+ set y 0
+ } elseif {$y > 200} {
+ set y 200
+ }
+ set hue [expr {$x/200.0}]
+ set sat [expr {(200-$y)/200.0}]
+ set _hsv [lreplace $_hsv 0 1 $hue $sat]
+ $_widget(chs) coords target [expr {$x-9}] [expr {$y-9}]
+ _draw_values $hue $sat
+ _set_rgb [eval [list format "\#%04x%04x%04x"] [eval [list hsvToRgb] $_hsv]]
+}
+
+
+proc SelectColor::_set_hue_sat {hue sat} {
+ variable _widget
+
+ set x [expr {$hue*200-9}]
+ set y [expr {(1-$sat)*200-9}]
+ $_widget(chs) coords target $x $y
+ _draw_values $hue $sat
+}
+
+
+
+proc SelectColor::_select_value {x y} {
+ variable _widget
+ variable _hsv
+
+ if {$y < 0} {
+ set y 0
+ } elseif {$y > 200} {
+ set y 200
+ }
+ $_widget(cv) coords target 0 [expr {$y-5}] 10 $y 0 [expr {$y+5}]
+ set _hsv [lreplace $_hsv 2 2 [expr {(200-$y)/200.0}]]
+ _set_rgb [eval [list format "\#%04x%04x%04x"] [eval [list hsvToRgb] $_hsv]]
+}
+
+
+proc SelectColor::_draw_values {hue sat} {
+ variable _widget
+
+ for {set val 0} {$val < 40} {incr val} {
+ set l [hsvToRgb $hue $sat [expr {$val/39.0}]]
+ set col [eval [list format "\#%04x%04x%04x"] $l]
+ $_widget(cv) itemconfigure val$val -fill $col -outline $col
+ }
+}
+
+
+proc SelectColor::_set_value {value} {
+ variable _widget
+
+ set y [expr {int((1-$value)*200)}]
+ $_widget(cv) coords target 0 [expr {$y-5}] 10 $y 0 [expr {$y+5}]
+}
+
+
+# --
+# Taken from tk8.0/demos/tcolor.tcl
+# --
+# The procedure below converts an HSB value to RGB. It takes hue, saturation,
+# and value components (floating-point, 0-1.0) as arguments, and returns a
+# list containing RGB components (integers, 0-65535) as result. The code
+# here is a copy of the code on page 616 of "Fundamentals of Interactive
+# Computer Graphics" by Foley and Van Dam.
+
+proc SelectColor::hsvToRgb {hue sat val} {
+ set v [expr {round(65535.0*$val)}]
+ if {$sat == 0} {
+ return [list $v $v $v]
+ } else {
+ set hue [expr {$hue*6.0}]
+ if {$hue >= 6.0} {
+ set hue 0.0
+ }
+ set i [expr {int($hue)}]
+ set f [expr {$hue-$i}]
+ set p [expr {round(65535.0*$val*(1 - $sat))}]
+ set q [expr {round(65535.0*$val*(1 - ($sat*$f)))}]
+ set t [expr {round(65535.0*$val*(1 - ($sat*(1 - $f))))}]
+ switch $i {
+ 0 {return [list $v $t $p]}
+ 1 {return [list $q $v $p]}
+ 2 {return [list $p $v $t]}
+ 3 {return [list $p $q $v]}
+ 4 {return [list $t $p $v]}
+ 5 {return [list $v $p $q]}
+ }
+ }
+}
+
+
+# --
+# Taken from tk8.0/demos/tcolor.tcl
+# --
+# The procedure below converts an RGB value to HSB. It takes red, green,
+# and blue components (0-65535) as arguments, and returns a list containing
+# HSB components (floating-point, 0-1) as result. The code here is a copy
+# of the code on page 615 of "Fundamentals of Interactive Computer Graphics"
+# by Foley and Van Dam.
+
+proc SelectColor::rgbToHsv {red green blue} {
+ if {$red > $green} {
+ set max $red.0
+ set min $green.0
+ } else {
+ set max $green.0
+ set min $red.0
+ }
+ if {$blue > $max} {
+ set max $blue.0
+ } else {
+ if {$blue < $min} {
+ set min $blue.0
+ }
+ }
+ set range [expr {$max-$min}]
+ if {$max == 0} {
+ set sat 0
+ } else {
+ set sat [expr {($max-$min)/$max}]
+ }
+ if {$sat == 0} {
+ set hue 0
+ } else {
+ set rc [expr {($max - $red)/$range}]
+ set gc [expr {($max - $green)/$range}]
+ set bc [expr {($max - $blue)/$range}]
+ if {$red == $max} {
+ set hue [expr {.166667*($bc - $gc)}]
+ } else {
+ if {$green == $max} {
+ set hue [expr {.166667*(2 + $rc - $bc)}]
+ } else {
+ set hue [expr {.166667*(4 + $gc - $rc)}]
+ }
+ }
+ if {$hue < 0.0} {
+ set hue [expr {$hue + 1.0}]
+ }
+ }
+ return [list $hue $sat [expr {$max/65535}]]
+}
+
diff --git a/modules/tclsci/tcl/BWidget/combobox.tcl b/modules/tclsci/tcl/BWidget/combobox.tcl
new file mode 100755
index 000000000..13389d32c
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/combobox.tcl
@@ -0,0 +1,885 @@
+# ----------------------------------------------------------------------------
+# combobox.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: combobox.tcl,v 1.42.2.1 2009/08/10 11:28:50 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - ComboBox::create
+# - ComboBox::configure
+# - ComboBox::cget
+# - ComboBox::setvalue
+# - ComboBox::getvalue
+# - ComboBox::clearvalue
+# - ComboBox::_create_popup
+# - ComboBox::_mapliste
+# - ComboBox::_unmapliste
+# - ComboBox::_select
+# - ComboBox::_modify_value
+# ----------------------------------------------------------------------------
+
+# ComboBox uses the 8.3 -listvariable listbox option
+package require Tk 8.3
+
+namespace eval ComboBox {
+ Widget::define ComboBox combobox ArrowButton Entry ListBox
+
+ Widget::tkinclude ComboBox frame :cmd \
+ include {-relief -borderwidth -bd -background} \
+ initialize {-relief sunken -borderwidth 2}
+
+ Widget::bwinclude ComboBox Entry .e \
+ remove {-relief -bd -borderwidth -bg} \
+ rename {-background -entrybg}
+
+ Widget::declare ComboBox {
+ {-height TkResource 0 0 listbox}
+ {-values String "" 0}
+ {-images String "" 0}
+ {-indents String "" 0}
+ {-modifycmd String "" 0}
+ {-postcommand String "" 0}
+ {-expand Enum none 0 {none tab}}
+ {-autocomplete Boolean 0 0}
+ {-autopost Boolean 0 0}
+ {-bwlistbox Boolean 0 0}
+ {-listboxwidth Int 0 0}
+ {-hottrack Boolean 0 0}
+ }
+
+ Widget::addmap ComboBox ArrowButton .a {
+ -background {} -foreground {} -disabledforeground {} -state {}
+ }
+
+ Widget::syncoptions ComboBox Entry .e {-text {}}
+
+ ::bind BwComboBox <FocusIn> [list after idle {BWidget::refocus %W %W.e}]
+ ::bind BwComboBox <Destroy> [list ComboBox::_destroy %W]
+
+ ::bind ListBoxHotTrack <Motion> {
+ %W selection clear 0 end
+ %W activate @%x,%y
+ %W selection set @%x,%y
+ }
+
+ variable _index
+}
+
+
+# ComboBox::create --
+#
+# Create a combobox widget with the given options.
+#
+# Arguments:
+# path name of the new widget.
+# args optional arguments to the widget.
+#
+# Results:
+# path name of the new widget.
+
+proc ComboBox::create { path args } {
+ array set maps [list ComboBox {} :cmd {} .e {} .a {}]
+ array set maps [Widget::parseArgs ComboBox $args]
+
+ eval [list frame $path] $maps(:cmd) \
+ [list -highlightthickness 0 -takefocus 0 -class ComboBox]
+ Widget::initFromODB ComboBox $path $maps(ComboBox)
+
+ bindtags $path [list $path BwComboBox [winfo toplevel $path] all]
+
+ set entry [eval [list Entry::create $path.e] $maps(.e) \
+ [list -relief flat -borderwidth 0 -takefocus 1]]
+
+ ::bind $path.e <FocusOut> [list $path _focus_out]
+ ::bind $path <<TraverseIn>> [list $path _traverse_in]
+
+ if {[Widget::cget $path -autocomplete]} {
+ ::bind $path.e <KeyRelease> [list $path _auto_complete %K]
+ }
+
+ if {[Widget::cget $path -autopost]} {
+ ::bind $path.e <KeyRelease> +[list $path _auto_post %K]
+ } else {
+ ::bind $entry <Key-Up> [list ComboBox::_unmapliste $path]
+ ::bind $entry <Key-Down> [list ComboBox::_mapliste $path]
+ }
+
+ if {[string equal [tk windowingsystem] "x11"]} {
+ set ipadx 0
+ set width 11
+ } else {
+ set ipadx 2
+ set width 15
+ }
+ set height [winfo reqheight $entry]
+ set arrow [eval [list ArrowButton::create $path.a] $maps(.a) \
+ [list -width $width -height $height \
+ -highlightthickness 0 -borderwidth 1 -takefocus 0 \
+ -dir bottom -type button -ipadx $ipadx \
+ -command [list ComboBox::_mapliste $path] \
+ ]]
+
+ pack $arrow -side right -fill y
+ pack $entry -side left -fill both -expand yes
+
+ set editable [Widget::cget $path -editable]
+ Entry::configure $path.e -editable $editable
+ if {$editable} {
+ ::bind $entry <ButtonPress-1> [list ComboBox::_unmapliste $path]
+ } else {
+ ::bind $entry <ButtonPress-1> [list ArrowButton::invoke $path.a]
+ if { ![string equal [Widget::cget $path -state] "disabled"] } {
+ Entry::configure $path.e -takefocus 1
+ }
+ }
+
+ ::bind $path <ButtonPress-1> [list ComboBox::_unmapliste $path]
+ ::bind $entry <Control-Up> [list ComboBox::_modify_value $path previous]
+ ::bind $entry <Control-Down> [list ComboBox::_modify_value $path next]
+ ::bind $entry <Control-Prior> [list ComboBox::_modify_value $path first]
+ ::bind $entry <Control-Next> [list ComboBox::_modify_value $path last]
+
+ if {$editable} {
+ set expand [Widget::cget $path -expand]
+ if {[string equal "tab" $expand]} {
+ # Expand entry value on Tab (from -values)
+ ::bind $entry <Tab> "[list ComboBox::_expand $path]; break"
+ } elseif {[string equal "auto" $expand]} {
+ # Expand entry value anytime (from -values)
+ #::bind $entry <Key> "[list ComboBox::_expand $path]; break"
+ }
+ }
+
+ ## If we have images, we have to use a BWidget ListBox.
+ set bw [Widget::cget $path -bwlistbox]
+ if {[llength [Widget::cget $path -images]]} {
+ Widget::configure $path [list -bwlistbox 1]
+ } else {
+ Widget::configure $path [list -bwlistbox $bw]
+ }
+
+ set ComboBox::_index($path) -1
+
+ return [Widget::create ComboBox $path]
+}
+
+
+# ComboBox::configure --
+#
+# Configure subcommand for ComboBox widgets. Works like regular
+# widget configure command.
+#
+# Arguments:
+# path Name of the ComboBox widget.
+# args Additional optional arguments:
+# ?-option?
+# ?-option value ...?
+#
+# Results:
+# Depends on arguments. If no arguments are given, returns a complete
+# list of configuration information. If one argument is given, returns
+# the configuration information for that option. If more than one
+# argument is given, returns nothing.
+
+proc ComboBox::configure { path args } {
+ set res [Widget::configure $path $args]
+ set entry $path.e
+
+
+ set list [list -images -values -bwlistbox -hottrack -autocomplete -autopost]
+ foreach {ci cv cb ch cac cap} [eval [linsert $list 0 Widget::hasChangedX $path]] { break }
+
+ if { $ci } {
+ set images [Widget::cget $path -images]
+ if {[llength $images]} {
+ Widget::configure $path [list -bwlistbox 1]
+ } else {
+ Widget::configure $path [list -bwlistbox 0]
+ }
+ }
+
+ ## If autocomplete toggled, turn bindings on/off
+ if { $cac } {
+ if {[Widget::cget $path -autocomplete]} {
+ ::bind $entry <KeyRelease> +[list $path _auto_complete %K]
+ } else {
+ set bindings [split [::bind $entry <KeyRelease>] \n]
+ if {[set idx [lsearch $bindings [list $path _auto_complete %K]]] != -1} {
+ ::bind $entry <KeyRelease> [join [lreplace $bindings $idx $idx] \n]
+ }
+ }
+ }
+
+ ## If autopost toggled, turn bindings on/off
+ if { $cap } {
+ if {[Widget::cget $path -autopost]} {
+ ::bind $entry <KeyRelease> +[list $path _auto_post %K]
+ set bindings [split [::bind $entry <Key-Up>] \n]
+ if {[set idx [lsearch $bindings [list ComboBox::_unmapliste $path]]] != -1} {
+ ::bind $entry <Key-Up> [join [lreplace $bindings $idx $idx] \n]
+ }
+ set bindings [split [::bind $entry <Key-Down>] \n]
+ if {[set idx [lsearch $bindings [list ComboBox::_mapliste $path]]] != -1} {
+ ::bind $entry <Key-Down> [join [lreplace $bindings $idx $idx] \n]
+ }
+ } else {
+ set bindings [split [::bind $entry <KeyRelease>] \n]
+ if {[set idx [lsearch $bindings [list $path _auto_post %K]]] != -1} {
+ ::bind $entry <KeyRelease> [join [lreplace $bindings $idx $idx] \n]
+ }
+ ::bind $entry <Key-Up> +[list ComboBox::_unmapliste $path]
+ ::bind $entry <Key-Down> +[list ComboBox::_mapliste $path]
+ }
+ }
+
+ set bw [Widget::cget $path -bwlistbox]
+
+ ## If the images, bwlistbox, hottrack or values have changed,
+ ## destroy the shell so that it will re-create itself the next
+ ## time around.
+ if { $ci || $cb || $ch || ($bw && $cv) } {
+ destroy $path.shell
+ }
+
+ set chgedit [Widget::hasChangedX $path -editable]
+ if {$chgedit} {
+ if {[Widget::cget $path -editable]} {
+ ::bind $entry <ButtonPress-1> [list ComboBox::_unmapliste $path]
+ Entry::configure $entry -editable true
+ } else {
+ ::bind $entry <ButtonPress-1> [list ArrowButton::invoke $path.a]
+ Entry::configure $entry -editable false
+
+ # Make sure that non-editable comboboxes can still be tabbed to.
+
+ if { ![string equal [Widget::cget $path -state] "disabled"] } {
+ Entry::configure $entry -takefocus 1
+ }
+ }
+ }
+
+ if {$chgedit || [Widget::hasChangedX $path -expand]} {
+ # Unset what we may have created.
+ ::bind $entry <Tab> {}
+ if {[Widget::cget $path -editable]} {
+ set expand [Widget::cget $path -expand]
+ if {[string equal "tab" $expand]} {
+ # Expand entry value on Tab (from -values)
+ ::bind $entry <Tab> "[list ComboBox::_expand $path]; break"
+ } elseif {[string equal "auto" $expand]} {
+ # Expand entry value anytime (from -values)
+ #::bind $entry <Key> "[list ComboBox::_expand $path]; break"
+ }
+ }
+ }
+
+ # if state changed to normal and -editable false, the edit must take focus
+ if { [Widget::hasChangedX $path -state] \
+ && ![string equal [Widget::cget $path -state] "disabled"] \
+ && ![Widget::cget $path -editable] } {
+ Entry::configure $entry -takefocus 1
+ }
+
+ # if the dropdown listbox is shown, simply force the actual entry
+ # colors into it. If it is not shown, the next time the dropdown
+ # is shown it'll get the actual colors anyway
+ if {[winfo exists $path.shell.listb]} {
+ $path.shell.listb configure \
+ -bg [Widget::cget $path -entrybg] \
+ -fg [Widget::cget $path -foreground] \
+ -selectbackground [Widget::cget $path -selectbackground] \
+ -selectforeground [Widget::cget $path -selectforeground]
+ }
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::cget
+# ----------------------------------------------------------------------------
+proc ComboBox::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::setvalue
+# ----------------------------------------------------------------------------
+proc ComboBox::setvalue { path index } {
+ variable _index
+
+ set values [Widget::getMegawidgetOption $path -values]
+ set value [Entry::cget $path.e -text]
+ switch -- $index {
+ next {
+ if { [set idx [lsearch -exact $values $value]] != -1 } {
+ incr idx
+ } else {
+ set idx [lsearch -exact $values "$value*"]
+ }
+ }
+ previous {
+ if { [set idx [lsearch -exact $values $value]] != -1 } {
+ incr idx -1
+ } else {
+ set idx [lsearch -exact $values "$value*"]
+ }
+ }
+ first {
+ set idx 0
+ }
+ last {
+ set idx [expr {[llength $values]-1}]
+ }
+ default {
+ if { [string index $index 0] == "@" } {
+ set idx [string range $index 1 end]
+ if { ![string is integer -strict $idx] } {
+ return -code error "bad index \"$index\""
+ }
+ } else {
+ return -code error "bad index \"$index\""
+ }
+ }
+ }
+ if { $idx >= 0 && $idx < [llength $values] } {
+ set newval [lindex $values $idx]
+ set _index($path) $idx
+ Entry::configure $path.e -text $newval
+ return 1
+ }
+ return 0
+}
+
+
+proc ComboBox::icursor { path idx } {
+ return [$path.e icursor $idx]
+}
+
+
+proc ComboBox::get { path } {
+ return [$path.e get]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::getvalue
+# ----------------------------------------------------------------------------
+proc ComboBox::getvalue { path } {
+ variable _index
+ set values [Widget::getMegawidgetOption $path -values]
+ set value [Entry::cget $path.e -text]
+ # Check if an index was saved by the last setvalue operation
+ # If this index still matches it is returned
+ # This is necessary for the case when values is not unique
+ if { $_index($path) >= 0 \
+ && $_index($path) < [llength $values] \
+ && $value eq [lindex $values $_index($path)]} {
+ return $_index($path)
+ }
+
+ return [lsearch -exact $values $value]
+}
+
+
+proc ComboBox::getlistbox { path } {
+ _create_popup $path
+ return $path.shell.listb
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::post
+# ----------------------------------------------------------------------------
+proc ComboBox::post { path } {
+ _mapliste $path
+ return
+}
+
+
+proc ComboBox::unpost { path } {
+ _unmapliste $path
+ return
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::bind
+# ----------------------------------------------------------------------------
+proc ComboBox::bind { path args } {
+ return [eval [list ::bind $path.e] $args]
+}
+
+
+proc ComboBox::insert { path idx args } {
+ upvar #0 [Widget::varForOption $path -values] values
+
+ if {[Widget::cget $path -bwlistbox]} {
+ set l [$path getlistbox]
+ set i [eval [linsert $args 0 $l insert $idx #auto]]
+ set text [$l itemcget $i -text]
+ if {$idx == "end"} {
+ lappend values $text
+ } else {
+ set values [linsert $values $idx $text]
+ }
+ } else {
+ set values [eval [list linsert $values $idx] $args]
+ }
+}
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::clearvalue
+# ----------------------------------------------------------------------------
+proc ComboBox::clearvalue { path } {
+ Entry::configure $path.e -text ""
+}
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_create_popup
+# ----------------------------------------------------------------------------
+proc ComboBox::_create_popup { path } {
+ set shell $path.shell
+
+ if {[winfo exists $shell]} { return }
+
+ set lval [Widget::cget $path -values]
+ set h [Widget::cget $path -height]
+ set bw [Widget::cget $path -bwlistbox]
+
+ if { $h <= 0 } {
+ set len [llength $lval]
+ if { $len < 3 } {
+ set h 3
+ } elseif { $len > 10 } {
+ set h 10
+ } else {
+ set h $len
+ }
+ }
+
+ if {[string equal [tk windowingsystem] "x11"]} {
+ set sbwidth 11
+ } else {
+ set sbwidth 15
+ }
+
+ toplevel $shell -relief solid -bd 1
+ wm withdraw $shell
+ wm overrideredirect $shell 1
+ # these commands cause the combobox to behave strangely on OS X
+ if {! $Widget::_aqua } {
+ update idle
+ wm transient $shell [winfo toplevel $path]
+ catch { wm attributes $shell -topmost 1 }
+ }
+
+ set sw [ScrolledWindow $shell.sw -managed 1 -size $sbwidth -ipad 0]
+
+ if {$bw} {
+ set listb [ListBox $shell.listb \
+ -relief flat -borderwidth 0 -highlightthickness 0 \
+ -selectmode single -selectfill 1 -autofocus 0 -height $h \
+ -font [Widget::cget $path -font] \
+ -bg [Widget::cget $path -entrybg] \
+ -fg [Widget::cget $path -foreground] \
+ -selectbackground [Widget::cget $path -selectbackground] \
+ -selectforeground [Widget::cget $path -selectforeground]]
+
+ set values [Widget::cget $path -values]
+ set images [Widget::cget $path -images]
+ foreach value $values image $images {
+ $listb insert end #auto -text $value -image $image
+ }
+ $listb bindText <1> [list ComboBox::_select $path]
+ $listb bindImage <1> [list ComboBox::_select $path]
+ if {[Widget::cget $path -hottrack]} {
+ $listb bindText <Enter> [list $listb selection set]
+ $listb bindImage <Enter> [list $listb selection set]
+ }
+ } else {
+ set listb [listbox $shell.listb \
+ -relief flat -borderwidth 0 -highlightthickness 0 \
+ -exportselection false \
+ -font [Widget::cget $path -font] \
+ -height $h \
+ -bg [Widget::cget $path -entrybg] \
+ -fg [Widget::cget $path -foreground] \
+ -selectbackground [Widget::cget $path -selectbackground] \
+ -selectforeground [Widget::cget $path -selectforeground] \
+ -listvariable [Widget::varForOption $path -values]]
+ ::bind $listb <ButtonRelease-1> [list ComboBox::_select $path @%x,%y]
+
+ if {[Widget::cget $path -hottrack]} {
+ bindtags $listb [concat [bindtags $listb] ListBoxHotTrack]
+ }
+ }
+ pack $sw -fill both -expand yes
+ $sw setwidget $listb
+
+ ::bind $listb <Return> "ComboBox::_select [list $path] \[$listb curselection\]"
+ ::bind $listb <Escape> [list ComboBox::_unmapliste $path]
+ ::bind $listb <FocusOut> [list ComboBox::_focus_out $path]
+}
+
+
+proc ComboBox::_recreate_popup { path } {
+ variable background
+ variable foreground
+
+ set shell $path.shell
+ set lval [Widget::cget $path -values]
+ set h [Widget::cget $path -height]
+ set bw [Widget::cget $path -bwlistbox]
+
+ if { $h <= 0 } {
+ set len [llength $lval]
+ if { $len < 3 } {
+ set h 3
+ } elseif { $len > 10 } {
+ set h 10
+ } else {
+ set h $len
+ }
+ }
+
+ if { [string equal [tk windowingsystem] "x11"] } {
+ set sbwidth 11
+ } else {
+ set sbwidth 15
+ }
+
+ _create_popup $path
+
+ if {![Widget::cget $path -editable]} {
+ if {[info exists background]} {
+ $path.e configure -bg $background
+ $path.e configure -fg $foreground
+ unset background
+ unset foreground
+ }
+ }
+
+ set listb $shell.listb
+ destroy $shell.sw
+ set sw [ScrolledWindow $shell.sw -managed 1 -size $sbwidth -ipad 0]
+ $listb configure \
+ -height $h \
+ -font [Widget::cget $path -font] \
+ -bg [Widget::cget $path -entrybg] \
+ -fg [Widget::cget $path -foreground] \
+ -selectbackground [Widget::cget $path -selectbackground] \
+ -selectforeground [Widget::cget $path -selectforeground]
+ pack $sw -fill both -expand yes
+ $sw setwidget $listb
+ raise $listb
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_mapliste
+# ----------------------------------------------------------------------------
+proc ComboBox::_mapliste { path } {
+ set listb $path.shell.listb
+ if {[winfo exists $path.shell] &&
+ [string equal [wm state $path.shell] "normal"]} {
+ _unmapliste $path
+ return
+ }
+
+ if { [Widget::cget $path -state] == "disabled" } {
+ return
+ }
+ if {[llength [set cmd [Widget::getMegawidgetOption $path -postcommand]]]} {
+ uplevel \#0 $cmd
+ }
+ if { ![llength [Widget::getMegawidgetOption $path -values]] } {
+ return
+ }
+
+ _recreate_popup $path
+
+ ArrowButton::configure $path.a -relief sunken
+ update
+
+ set bw [Widget::cget $path -bwlistbox]
+
+ $listb selection clear 0 end
+ set values [Widget::getMegawidgetOption $path -values]
+ set curval [Entry::cget $path.e -text]
+ if { [set idx [lsearch -exact $values $curval]] != -1 ||
+ [set idx [lsearch -exact $values "$curval*"]] != -1 } {
+ if {$bw} {
+ set idx [$listb items $idx]
+ } else {
+ $listb activate $idx
+ }
+ $listb selection set $idx
+ $listb see $idx
+ } else {
+ set idx 0
+ if {$bw} {
+ set idx [$listb items 0]
+ } else {
+ $listb activate $idx
+ }
+ $listb selection set $idx
+ $listb see $idx
+ }
+
+ set width [Widget::cget $path -listboxwidth]
+ if {!$width} { set width [winfo width $path] }
+ BWidget::place $path.shell $width 0 below $path
+ wm deiconify $path.shell
+ raise $path.shell
+ BWidget::focus set $listb
+ if {! $Widget::_aqua } {
+ BWidget::grab global $path
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_unmapliste
+# ----------------------------------------------------------------------------
+proc ComboBox::_unmapliste { path {refocus 1} } {
+ # On aqua, state is zoomed, otherwise normal
+ if {[winfo exists $path.shell] && \
+ ( [string equal [wm state $path.shell] "normal"] ||
+ [string equal [wm state $path.shell] "zoomed"] ) } {
+ if {! $Widget::_aqua } {
+ BWidget::grab release $path
+ BWidget::focus release $path.shell.listb $refocus
+ # Update now because otherwise [focus -force...] makes the app hang!
+ if {$refocus} {
+ update
+ focus -force $path.e
+ }
+ }
+ wm withdraw $path.shell
+ ArrowButton::configure $path.a -relief raised
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_select
+# ----------------------------------------------------------------------------
+proc ComboBox::_select { path index } {
+ set index [$path.shell.listb index $index]
+ _unmapliste $path
+ if { $index != -1 } {
+ if { [setvalue $path @$index] } {
+ set cmd [Widget::getMegawidgetOption $path -modifycmd]
+ if {[llength $cmd]} {
+ uplevel \#0 $cmd
+ }
+ }
+ }
+ $path.e selection clear
+ if {[$path.e cget -exportselection]} {
+ $path.e selection range 0 end
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_modify_value
+# ----------------------------------------------------------------------------
+proc ComboBox::_modify_value { path direction } {
+ if {[setvalue $path $direction]
+ && [llength [set cmd [Widget::getMegawidgetOption $path -modifycmd]]]} {
+ uplevel \#0 $cmd
+ }
+}
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_expand
+# ----------------------------------------------------------------------------
+proc ComboBox::_expand {path} {
+ set values [Widget::getMegawidgetOption $path -values]
+ if {![llength $values]} {
+ bell
+ return 0
+ }
+
+ set found {}
+ set curval [Entry::cget $path.e -text]
+ set curlen [$path.e index insert]
+ if {$curlen < [string length $curval]} {
+ # we are somewhere in the middle of a string.
+ # if the full value matches some string in the listbox,
+ # reorder values to start matching after that string.
+ set idx [lsearch -exact $values $curval]
+ if {$idx >= 0} {
+ set values [concat [lrange $values [expr {$idx+1}] end] \
+ [lrange $values 0 $idx]]
+ }
+ }
+ if {$curlen == 0} {
+ set found $values
+ } else {
+ foreach val $values {
+ if {[string equal -length $curlen $curval $val]} {
+ lappend found $val
+ }
+ }
+ }
+ if {[llength $found]} {
+ Entry::configure $path.e -text [lindex $found 0]
+ if {[llength $found] > 1} {
+ set best [_best_match $found [string range $curval 0 $curlen]]
+ set blen [string length $best]
+ $path.e icursor $blen
+ $path.e selection range $blen end
+ }
+ } else {
+ bell
+ }
+ return [llength $found]
+}
+
+# best_match --
+# finds the best unique match in a list of names
+# The extra $e in this argument allows us to limit the innermost loop a
+# little further.
+# Arguments:
+# l list to find best unique match in
+# e currently best known unique match
+# Returns:
+# longest unique match in the list
+#
+proc ComboBox::_best_match {l {e {}}} {
+ set ec [lindex $l 0]
+ if {[llength $l]>1} {
+ set e [string length $e]; incr e -1
+ set ei [string length $ec]; incr ei -1
+ foreach l $l {
+ while {$ei>=$e && [string first $ec $l]} {
+ set ec [string range $ec 0 [incr ei -1]]
+ }
+ }
+ }
+ return $ec
+}
+# possibly faster
+#proc match {string1 string2} {
+# set i 1
+# while {[string equal -length $i $string1 $string2]} { incr i }
+# return [string range $string1 0 [expr {$i-2}]]
+#}
+#proc matchlist {list} {
+# set list [lsort $list]
+# return [match [lindex $list 0] [lindex $list end]]
+#}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_traverse_in
+# Called when widget receives keyboard focus due to keyboard traversal.
+# ----------------------------------------------------------------------------
+proc ComboBox::_traverse_in { path } {
+ if {[$path.e selection present] != 1} {
+ # Autohighlight the selection, but not if one existed
+ $path.e selection range 0 end
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ComboBox::_focus_out
+# ----------------------------------------------------------------------------
+proc ComboBox::_focus_out { path } {
+ if {[string first $path [focus]] != 0} {
+ # we lost focus to some other app or window, so remove the listbox
+ return [_unmapliste $path 0]
+ }
+}
+
+proc ComboBox::_auto_complete { path key } {
+ ## Any key string with more than one character and is not entirely
+ ## lower-case is considered a function key and is thus ignored.
+ if {[string length $key] > 1 && [string tolower $key] != $key} { return }
+
+ set text [string map [list {[} {\[} {]} {\]}] [$path.e get]]
+ if {[string equal $text ""]} { return }
+ set values [Widget::cget $path -values]
+ set x [lsearch $values $text*]
+ if {$x < 0} { return }
+
+ set idx [$path.e index insert]
+ $path.e configure -text [lindex $values $x]
+ $path.e icursor $idx
+ $path.e select range insert end
+}
+
+proc ComboBox::_auto_post { path key } {
+ if {[string equal $key "Escape"] || [string equal $key "Return"]} {
+ _unmapliste $path
+ return
+ }
+ if {[catch {$path.shell.listb curselection} x] || $x == ""} {
+ if {[string equal $key "Up"]} {
+ _unmapliste $path
+ return
+ }
+ set x -1
+ }
+ if {([string length $key] > 1 && [string tolower $key] != $key) && \
+ [string equal $key "BackSpace"] != 0 && \
+ [string equal $key "Up"] != 0 && \
+ [string equal $key "Down"] != 0} {
+ return
+ }
+
+ # post the listbox
+ _create_popup $path
+ set width [Widget::cget $path -listboxwidth]
+ if {!$width} { set width [winfo width $path] }
+ BWidget::place $path.shell $width 0 below $path
+ wm deiconify $path.shell
+ BWidget::grab release $path
+ BWidget::focus release $path.shell.listb 1
+ focus -force $path.e
+
+ set values [Widget::cget $path -values]
+ switch -- $key {
+ Up {
+ if {[incr x -1] < 0} {
+ set x 0
+ } else {
+ Entry::configure $path.e -text [lindex $values $x]
+ }
+ }
+ Down {
+ if {[incr x] >= [llength $values]} {
+ set x [expr {[llength $values] - 1}]
+ } else {
+ Entry::configure $path.e -text [lindex $values $x]
+ }
+ }
+ default {
+ # auto-select within the listbox the item closest to the entry's value
+ set text [string map [list {[} {\[} {]} {\]}] [$path.e get]]
+ if {[string equal $text ""]} {
+ set x 0
+ } else {
+ set x [lsearch $values $text*]
+ }
+ }
+ }
+
+ if {$x >= 0} {
+ $path.shell.listb selection clear 0 end
+ $path.shell.listb selection set $x
+ $path.shell.listb see $x
+ }
+}
+# ------------------------------------------------------------------------------
+# Command ComboBox::_destroy
+# ------------------------------------------------------------------------------
+proc ComboBox::_destroy { path } {
+ variable _index
+ Widget::destroy $path
+ unset _index($path)
+}
diff --git a/modules/tclsci/tcl/BWidget/dialog.tcl b/modules/tclsci/tcl/BWidget/dialog.tcl
new file mode 100755
index 000000000..209e151f6
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/dialog.tcl
@@ -0,0 +1,357 @@
+# ----------------------------------------------------------------------------
+# dialog.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: dialog.tcl,v 1.15.2.1 2010/08/04 13:07:59 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - Dialog::create
+# - Dialog::configure
+# - Dialog::cget
+# - Dialog::getframe
+# - Dialog::add
+# - Dialog::itemconfigure
+# - Dialog::itemcget
+# - Dialog::invoke
+# - Dialog::setfocus
+# - Dialog::enddialog
+# - Dialog::draw
+# - Dialog::withdraw
+# - Dialog::_destroy
+# ----------------------------------------------------------------------------
+
+# JDC: added -transient and -place flag
+
+namespace eval Dialog {
+ Widget::define Dialog dialog ButtonBox
+
+ Widget::bwinclude Dialog ButtonBox .bbox \
+ remove {-orient} \
+ initialize {-spacing 10 -padx 10}
+
+ Widget::declare Dialog {
+ {-title String "" 0}
+ {-geometry String "" 0}
+ {-modal Enum local 0 {none local global}}
+ {-bitmap TkResource "" 1 label}
+ {-image TkResource "" 1 label}
+ {-separator Boolean 0 1}
+ {-cancel Int -1 0 "%d >= -1"}
+ {-parent String "" 0}
+ {-side Enum bottom 1 {bottom left top right}}
+ {-anchor Enum c 1 {n e w s c}}
+ {-class String Dialog 1}
+ {-transient Boolean 1 1}
+ {-place Enum center 0 {none center left right above below}}
+ }
+
+ Widget::addmap Dialog "" :cmd {-background {}}
+ Widget::addmap Dialog "" .frame {-background {}}
+
+ bind BwDialog <Destroy> [list Dialog::_destroy %W]
+
+ variable _widget
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::create
+# ----------------------------------------------------------------------------
+proc Dialog::create { path args } {
+ global tcl_platform
+ variable _widget
+
+ array set maps [list Dialog {} .bbox {}]
+ array set maps [Widget::parseArgs Dialog $args]
+
+ # Check to see if the -class flag was specified
+ set dialogClass "Dialog"
+ array set dialogArgs $maps(Dialog)
+ if { [info exists dialogArgs(-class)] } {
+ set dialogClass $dialogArgs(-class)
+ }
+
+ if { [string equal $tcl_platform(platform) "unix"] } {
+ set re raised
+ set bd 1
+ } else {
+ set re flat
+ set bd 0
+ }
+ toplevel $path -relief $re -borderwidth $bd -class $dialogClass
+ wm withdraw $path
+
+ Widget::initFromODB Dialog $path $maps(Dialog)
+
+ bindtags $path [list $path BwDialog all]
+ wm overrideredirect $path 1
+ wm title $path [Widget::cget $path -title]
+ set parent [Widget::cget $path -parent]
+ if { ![winfo exists $parent] } {
+ set parent [winfo parent $path]
+ }
+ # JDC: made transient optional
+ if { [Widget::getoption $path -transient] } {
+ wm transient $path [winfo toplevel $parent]
+ }
+
+ set side [Widget::cget $path -side]
+ if { [string equal $side "left"] || [string equal $side "right"] } {
+ set orient vertical
+ } else {
+ set orient horizontal
+ }
+
+ set bbox [eval [list ButtonBox::create $path.bbox] $maps(.bbox) \
+ -orient $orient]
+ set frame [frame $path.frame -relief flat -borderwidth 0]
+ set bg [Widget::cget $path -background]
+ $path configure -background $bg
+ $frame configure -background $bg
+ if { [set bitmap [Widget::getoption $path -image]] != "" } {
+ set label [label $path.label -image $bitmap -background $bg]
+ } elseif { [set bitmap [Widget::getoption $path -bitmap]] != "" } {
+ set label [label $path.label -bitmap $bitmap -background $bg]
+ }
+ if { [Widget::getoption $path -separator] } {
+ Separator::create $path.sep -orient $orient -background $bg
+ }
+ set _widget($path,realized) 0
+ set _widget($path,nbut) 0
+
+ set cancel [Widget::getoption $path -cancel]
+ bind $path <Escape> [list ButtonBox::invoke $path.bbox $cancel]
+ if {$cancel != -1} {
+ wm protocol $path WM_DELETE_WINDOW [list ButtonBox::invoke $path.bbox $cancel]
+ }
+ bind $path <Return> [list ButtonBox::invoke $path.bbox default]
+
+ return [Widget::create Dialog $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::configure
+# ----------------------------------------------------------------------------
+proc Dialog::configure { path args } {
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -title title] } {
+ wm title $path $title
+ }
+ if { [Widget::hasChanged $path -background bg] } {
+ if { [winfo exists $path.label] } {
+ $path.label configure -background $bg
+ }
+ if { [winfo exists $path.sep] } {
+ Separator::configure $path.sep -background $bg
+ }
+ }
+ if { [Widget::hasChanged $path -cancel cancel] } {
+ bind $path <Escape> [list ButtonBox::invoke $path.bbox $cancel]
+ if {$cancel == -1} {
+ wm protocol $path WM_DELETE_WINDOW ""
+ } else {
+ wm protocol $path WM_DELETE_WINDOW [list ButtonBox::invoke $path.bbox $cancel]
+ }
+ }
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::cget
+# ----------------------------------------------------------------------------
+proc Dialog::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::getframe
+# ----------------------------------------------------------------------------
+proc Dialog::getframe { path } {
+ return $path.frame
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::add
+# ----------------------------------------------------------------------------
+proc Dialog::add { path args } {
+ variable _widget
+
+ if {[string equal $::tcl_platform(platform) "windows"]
+ && $::tk_version >= 8.4} {
+ set width -11
+ } else {
+ set width 8
+ }
+ set cmd [list ButtonBox::add $path.bbox -width $width \
+ -command [list Dialog::enddialog $path $_widget($path,nbut)]]
+ set res [eval $cmd $args]
+ incr _widget($path,nbut)
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::itemconfigure
+# ----------------------------------------------------------------------------
+proc Dialog::itemconfigure { path index args } {
+ return [eval [list ButtonBox::itemconfigure $path.bbox $index] $args]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::itemcget
+# ----------------------------------------------------------------------------
+proc Dialog::itemcget { path index option } {
+ return [ButtonBox::itemcget $path.bbox $index $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::invoke
+# ----------------------------------------------------------------------------
+proc Dialog::invoke { path index } {
+ ButtonBox::invoke $path.bbox $index
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::setfocus
+# ----------------------------------------------------------------------------
+proc Dialog::setfocus { path index } {
+ ButtonBox::setfocus $path.bbox $index
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::enddialog
+# ----------------------------------------------------------------------------
+proc Dialog::enddialog { path result } {
+ variable _widget
+
+ set _widget($path,result) $result
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::draw
+# ----------------------------------------------------------------------------
+proc Dialog::draw { path {focus ""} {overrideredirect 0} {geometry ""}} {
+ variable _widget
+
+ set parent [Widget::getoption $path -parent]
+ if { !$_widget($path,realized) } {
+ set _widget($path,realized) 1
+ if { [llength [winfo children $path.bbox]] } {
+ set side [Widget::getoption $path -side]
+ if {[string equal $side "left"] || [string equal $side "right"]} {
+ set pad -padx
+ set fill y
+ } else {
+ set pad -pady
+ set fill x
+ }
+ pack $path.bbox -side $side -padx 1m -pady 1m \
+ -anchor [Widget::getoption $path -anchor]
+ if { [winfo exists $path.sep] } {
+ pack $path.sep -side $side -fill $fill $pad 2m
+ }
+ }
+ if { [winfo exists $path.label] } {
+ pack $path.label -side left -anchor n -padx 3m -pady 3m
+ }
+ pack $path.frame -padx 1m -pady 1m -fill both -expand yes
+ }
+
+ set geom [Widget::getMegawidgetOption $path -geometry]
+ if { $geom != "" } {
+ wm geometry $path $geom
+ }
+
+ if { [string equal $geometry ""] && ($geom == "") } {
+ set place [Widget::getoption $path -place]
+ if { ![string equal $place none] } {
+ if { [winfo exists $parent] } {
+ BWidget::place $path 0 0 $place $parent
+ } else {
+ BWidget::place $path 0 0 $place
+ }
+ }
+ } else {
+ if { $geom != "" } {
+ wm geometry $path $geom
+ } else {
+ wm geometry $path $geometry
+ }
+ }
+ update idletasks
+ wm overrideredirect $path $overrideredirect
+ wm deiconify $path
+
+ # patch by Bastien Chevreux (bach@mwgdna.com)
+ # As seen on Windows systems *sigh*
+ # When the toplevel is withdrawn, the tkwait command will wait forever.
+ # So, check that we are not withdrawn
+ if {![winfo exists $parent] || \
+ ([wm state [winfo toplevel $parent]] != "withdrawn")} {
+ tkwait visibility $path
+ }
+ BWidget::focus set $path
+ if { [winfo exists $focus] } {
+ focus -force $focus
+ } else {
+ ButtonBox::setfocus $path.bbox default
+ }
+
+ if { [set grab [Widget::cget $path -modal]] != "none" } {
+ BWidget::grab $grab $path
+ if {[info exists _widget($path,result)]} {
+ unset _widget($path,result)
+ }
+ tkwait variable Dialog::_widget($path,result)
+ if { [info exists _widget($path,result)] } {
+ set res $_widget($path,result)
+ unset _widget($path,result)
+ } else {
+ set res -1
+ }
+ withdraw $path
+ return $res
+ }
+ return ""
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::withdraw
+# ----------------------------------------------------------------------------
+proc Dialog::withdraw { path } {
+ BWidget::grab release $path
+ BWidget::focus release $path
+ if { [winfo exists $path] } {
+ wm withdraw $path
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Dialog::_destroy
+# ----------------------------------------------------------------------------
+proc Dialog::_destroy { path } {
+ variable _widget
+
+ Dialog::enddialog $path -1
+
+ BWidget::grab release $path
+ BWidget::focus release $path
+ if {[info exists _widget($path,result)]} {
+ unset _widget($path,result)
+ }
+ unset _widget($path,realized)
+ unset _widget($path,nbut)
+
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/dragsite.tcl b/modules/tclsci/tcl/BWidget/dragsite.tcl
new file mode 100755
index 000000000..bb7b3e7e4
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/dragsite.tcl
@@ -0,0 +1,197 @@
+# ------------------------------------------------------------------------------
+# dragsite.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: dragsite.tcl,v 1.8 2003/10/20 21:23:52 damonc Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - DragSite::include
+# - DragSite::setdrag
+# - DragSite::register
+# - DragSite::_begin_drag
+# - DragSite::_init_drag
+# - DragSite::_end_drag
+# - DragSite::_update_operation
+# ----------------------------------------------------------------------------
+
+namespace eval DragSite {
+ Widget::define DragSite dragsite -classonly
+
+ Widget::declare DragSite [list \
+ [list -dragevent Enum 1 0 [list 1 2 3]] \
+ [list -draginitcmd String "" 0] \
+ [list -dragendcmd String "" 0] \
+ ]
+
+ variable _topw ".drag"
+ variable _tabops
+ variable _state
+ variable _x0
+ variable _y0
+
+ bind BwDrag1 <ButtonPress-1> {DragSite::_begin_drag press %W %s %X %Y}
+ bind BwDrag1 <B1-Motion> {DragSite::_begin_drag motion %W %s %X %Y}
+ bind BwDrag2 <ButtonPress-2> {DragSite::_begin_drag press %W %s %X %Y}
+ bind BwDrag2 <B2-Motion> {DragSite::_begin_drag motion %W %s %X %Y}
+ bind BwDrag3 <ButtonPress-3> {DragSite::_begin_drag press %W %s %X %Y}
+ bind BwDrag3 <B3-Motion> {DragSite::_begin_drag motion %W %s %X %Y}
+
+ proc use {} {}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DragSite::include
+# ----------------------------------------------------------------------------
+proc DragSite::include { class type event } {
+ set dragoptions [list \
+ [list -dragenabled Boolean 0 0] \
+ [list -draginitcmd String "" 0] \
+ [list -dragendcmd String "" 0] \
+ [list -dragtype String $type 0] \
+ [list -dragevent Enum $event 0 [list 1 2 3]] \
+ ]
+ Widget::declare $class $dragoptions
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DragSite::setdrag
+# Widget interface to register
+# ----------------------------------------------------------------------------
+proc DragSite::setdrag { path subpath initcmd endcmd {force 0}} {
+ set cen [Widget::hasChanged $path -dragenabled en]
+ set cdragevt [Widget::hasChanged $path -dragevent dragevt]
+ if { $en } {
+ if { $force || $cen || $cdragevt } {
+ register $subpath \
+ -draginitcmd $initcmd \
+ -dragendcmd $endcmd \
+ -dragevent $dragevt
+ }
+ } else {
+ register $subpath
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DragSite::register
+# ----------------------------------------------------------------------------
+proc DragSite::register { path args } {
+ upvar \#0 DragSite::$path drag
+
+ if { [info exists drag] } {
+ bind $path $drag(evt) {}
+ unset drag
+ }
+ Widget::init DragSite .drag$path $args
+ set event [Widget::getMegawidgetOption .drag$path -dragevent]
+ set initcmd [Widget::getMegawidgetOption .drag$path -draginitcmd]
+ set endcmd [Widget::getMegawidgetOption .drag$path -dragendcmd]
+ set tags [bindtags $path]
+ set idx [lsearch $tags "BwDrag*"]
+ Widget::destroy .drag$path
+ if { $initcmd != "" } {
+ if { $idx != -1 } {
+ bindtags $path [lreplace $tags $idx $idx BwDrag$event]
+ } else {
+ bindtags $path [concat $tags BwDrag$event]
+ }
+ set drag(initcmd) $initcmd
+ set drag(endcmd) $endcmd
+ set drag(evt) $event
+ } elseif { $idx != -1 } {
+ bindtags $path [lreplace $tags $idx $idx]
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DragSite::_begin_drag
+# ----------------------------------------------------------------------------
+proc DragSite::_begin_drag { event source state X Y } {
+ variable _x0
+ variable _y0
+ variable _state
+
+ switch -- $event {
+ press {
+ set _x0 $X
+ set _y0 $Y
+ set _state "press"
+ }
+ motion {
+ if { ![info exists _state] } {
+ # This is just extra protection. There seem to be
+ # rare cases where the motion comes before the press.
+ return
+ }
+ if { [string equal $_state "press"] } {
+ if { abs($_x0-$X) > 3 || abs($_y0-$Y) > 3 } {
+ set _state "done"
+ _init_drag $source $state $X $Y
+ }
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DragSite::_init_drag
+# ----------------------------------------------------------------------------
+proc DragSite::_init_drag { source state X Y } {
+ variable _topw
+ upvar \#0 DragSite::$source drag
+
+ destroy $_topw
+ toplevel $_topw
+ wm withdraw $_topw
+ wm overrideredirect $_topw 1
+
+ set info [uplevel \#0 $drag(initcmd) [list $source $X $Y .drag]]
+ if { $info != "" } {
+ set type [lindex $info 0]
+ set ops [lindex $info 1]
+ set data [lindex $info 2]
+
+ if { [winfo children $_topw] == "" } {
+ if { [string equal $type "BITMAP"] || [string equal $type "IMAGE"] } {
+ label $_topw.l -image [Bitmap::get dragicon] -relief flat -bd 0
+ } else {
+ label $_topw.l -image [Bitmap::get dragfile] -relief flat -bd 0
+ }
+ pack $_topw.l
+ }
+ wm geometry $_topw +[expr {$X+1}]+[expr {$Y+1}]
+ wm deiconify $_topw
+ if {[catch {tkwait visibility $_topw}]} {
+ return
+ }
+ BWidget::grab set $_topw
+ BWidget::focus set $_topw
+
+ bindtags $_topw [list $_topw DragTop]
+ DropSite::_init_drag $_topw $drag(evt) $source $state $X $Y $type $ops $data
+ } else {
+ destroy $_topw
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DragSite::_end_drag
+# ----------------------------------------------------------------------------
+proc DragSite::_end_drag { source target op type data result } {
+ variable _topw
+ upvar \#0 DragSite::$source drag
+
+ BWidget::grab release $_topw
+ BWidget::focus release $_topw
+ destroy $_topw
+ if { $drag(endcmd) != "" } {
+ uplevel \#0 $drag(endcmd) [list $source $target $op $type $data $result]
+ }
+}
+
+
diff --git a/modules/tclsci/tcl/BWidget/dropsite.tcl b/modules/tclsci/tcl/BWidget/dropsite.tcl
new file mode 100755
index 000000000..06412f54e
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/dropsite.tcl
@@ -0,0 +1,456 @@
+# ------------------------------------------------------------------------------
+# dropsite.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: dropsite.tcl,v 1.8 2009/06/30 16:17:37 oehhar Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - DropSite::include
+# - DropSite::setdrop
+# - DropSite::register
+# - DropSite::setcursor
+# - DropSite::setoperation
+# - DropSite::_update_operation
+# - DropSite::_compute_operation
+# - DropSite::_draw_operation
+# - DropSite::_init_drag
+# - DropSite::_motion
+# - DropSite::_release
+# ----------------------------------------------------------------------------
+
+
+namespace eval DropSite {
+ Widget::define DropSite dropsite -classonly
+
+ Widget::declare DropSite [list \
+ [list -dropovercmd String "" 0] \
+ [list -dropcmd String "" 0] \
+ [list -droptypes String "" 0] \
+ ]
+
+ proc use {} {}
+
+ variable _top ".drag"
+ variable _opw ".drag.\#op"
+ variable _target ""
+ variable _status 0
+ variable _tabops
+ variable _defops
+ variable _source
+ variable _type
+ variable _data
+ variable _evt
+ # key win unix
+ # shift 1 | 1 -> 1
+ # control 4 | 4 -> 4
+ # alt 8 | 16 -> 24
+ # meta | 64 -> 88
+
+ array set _tabops {
+ mod,none 0
+ mod,shift 1
+ mod,control 4
+ mod,alt 24
+ ops,copy 1
+ ops,move 1
+ ops,link 1
+ }
+
+ if { $tcl_platform(platform) == "unix" } {
+ set _tabops(mod,alt) 8
+ } else {
+ set _tabops(mod,alt) 16
+ }
+ array set _defops \
+ [list \
+ copy,mod shift \
+ move,mod control \
+ link,mod alt \
+ copy,img @[file join $::BWIDGET::LIBRARY "images" "opcopy.xbm"] \
+ move,img @[file join $::BWIDGET::LIBRARY "images" "opmove.xbm"] \
+ link,img @[file join $::BWIDGET::LIBRARY "images" "oplink.xbm"]]
+
+ bind DragTop <KeyPress-Shift_L> {DropSite::_update_operation [expr %s | 1]}
+ bind DragTop <KeyPress-Shift_R> {DropSite::_update_operation [expr %s | 1]}
+ bind DragTop <KeyPress-Control_L> {DropSite::_update_operation [expr %s | 4]}
+ bind DragTop <KeyPress-Control_R> {DropSite::_update_operation [expr %s | 4]}
+ if { $tcl_platform(platform) == "unix" } {
+ bind DragTop <KeyPress-Alt_L> {DropSite::_update_operation [expr %s | 8]}
+ bind DragTop <KeyPress-Alt_R> {DropSite::_update_operation [expr %s | 8]}
+ } else {
+ bind DragTop <KeyPress-Alt_L> {DropSite::_update_operation [expr %s | 16]}
+ bind DragTop <KeyPress-Alt_R> {DropSite::_update_operation [expr %s | 16]}
+ }
+
+ bind DragTop <KeyRelease-Shift_L> {DropSite::_update_operation [expr %s & ~1]}
+ bind DragTop <KeyRelease-Shift_R> {DropSite::_update_operation [expr %s & ~1]}
+ bind DragTop <KeyRelease-Control_L> {DropSite::_update_operation [expr %s & ~4]}
+ bind DragTop <KeyRelease-Control_R> {DropSite::_update_operation [expr %s & ~4]}
+ if { $tcl_platform(platform) == "unix" } {
+ bind DragTop <KeyRelease-Alt_L> {DropSite::_update_operation [expr %s & ~8]}
+ bind DragTop <KeyRelease-Alt_R> {DropSite::_update_operation [expr %s & ~8]}
+ } else {
+ bind DragTop <KeyRelease-Alt_L> {DropSite::_update_operation [expr %s & ~16]}
+ bind DragTop <KeyRelease-Alt_R> {DropSite::_update_operation [expr %s & ~16]}
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::include
+# ----------------------------------------------------------------------------
+proc DropSite::include { class types } {
+ set dropoptions [list \
+ [list -dropenabled Boolean 0 0] \
+ [list -dropovercmd String "" 0] \
+ [list -dropcmd String "" 0] \
+ [list -droptypes String $types 0] \
+ ]
+ Widget::declare $class $dropoptions
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::setdrop
+# Widget interface to register
+# ----------------------------------------------------------------------------
+proc DropSite::setdrop { path subpath dropover drop {force 0}} {
+ set cen [Widget::hasChanged $path -dropenabled en]
+ set ctypes [Widget::hasChanged $path -droptypes types]
+ if { $en } {
+ if { $force || $cen || $ctypes } {
+ register $subpath \
+ -droptypes $types \
+ -dropcmd $drop \
+ -dropovercmd $dropover
+ }
+ } else {
+ register $subpath
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::register
+# ----------------------------------------------------------------------------
+proc DropSite::register { path args } {
+ variable _tabops
+ variable _defops
+ upvar \#0 DropSite::$path drop
+
+ Widget::init DropSite .drop$path $args
+ if { [info exists drop] } {
+ unset drop
+ }
+ set dropcmd [Widget::getMegawidgetOption .drop$path -dropcmd]
+ set types [Widget::getMegawidgetOption .drop$path -droptypes]
+ set overcmd [Widget::getMegawidgetOption .drop$path -dropovercmd]
+ Widget::destroy .drop$path
+ if { $dropcmd != "" && $types != "" } {
+ set drop(dropcmd) $dropcmd
+ set drop(overcmd) $overcmd
+ foreach {type ops} $types {
+ set drop($type,ops) {}
+ set masklist {}
+ foreach {descop lmod} $ops {
+ if { ![llength $descop] || [llength $descop] > 3 } {
+ return -code error "invalid operation description \"$descop\""
+ }
+ foreach {subop baseop imgop} $descop {
+ set subop [string trim $subop]
+ if { ![string length $subop] } {
+ return -code error "sub operation is empty"
+ }
+ if { ![string length $baseop] } {
+ set baseop $subop
+ }
+ if { [info exists drop($type,ops,$subop)] } {
+ return -code error "operation \"$subop\" already defined"
+ }
+ if { ![info exists _tabops(ops,$baseop)] } {
+ return -code error "invalid base operation \"$baseop\""
+ }
+ if { ![string equal $subop $baseop] &&
+ [info exists _tabops(ops,$subop)] } {
+ return -code error "sub operation \"$subop\" is a base operation"
+ }
+ if { ![string length $imgop] } {
+ set imgop $_defops($baseop,img)
+ }
+ }
+ if { [string equal $lmod "program"] } {
+ set drop($type,ops,$subop) $baseop
+ set drop($type,img,$subop) $imgop
+ } else {
+ if { ![string length $lmod] } {
+ set lmod $_defops($baseop,mod)
+ }
+ set mask 0
+ foreach mod $lmod {
+ if { ![info exists _tabops(mod,$mod)] } {
+ return -code error "invalid modifier \"$mod\""
+ }
+ set mask [expr {$mask | $_tabops(mod,$mod)}]
+ }
+ if { ($mask == 0) != ([string equal $subop "default"]) } {
+ return -code error "sub operation default can only be used with modifier \"none\""
+ }
+ set drop($type,mod,$mask) $subop
+ set drop($type,ops,$subop) $baseop
+ set drop($type,img,$subop) $imgop
+ lappend masklist $mask
+ }
+ }
+ if { ![info exists drop($type,mod,0)] } {
+ set drop($type,mod,0) default
+ set drop($type,ops,default) copy
+ set drop($type,img,default) $_defops(copy,img)
+ lappend masklist 0
+ }
+ set drop($type,ops,force) copy
+ set drop($type,img,force) $_defops(copy,img)
+ foreach mask [lsort -integer -decreasing $masklist] {
+ lappend drop($type,ops) $mask $drop($type,mod,$mask)
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::setcursor
+# ----------------------------------------------------------------------------
+proc DropSite::setcursor { cursor } {
+ catch {.drag configure -cursor $cursor}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::setoperation
+# ----------------------------------------------------------------------------
+proc DropSite::setoperation { op } {
+ variable _curop
+ variable _dragops
+ variable _target
+ variable _type
+ upvar \#0 DropSite::$_target drop
+
+ if { [info exist drop($_type,ops,$op)] &&
+ $_dragops($drop($_type,ops,$op)) } {
+ set _curop $op
+ } else {
+ # force to a copy operation
+ set _curop force
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::_init_drag
+# ----------------------------------------------------------------------------
+proc DropSite::_init_drag { top evt source state X Y type ops data } {
+ variable _top
+ variable _source
+ variable _type
+ variable _data
+ variable _target
+ variable _status
+ variable _state
+ variable _dragops
+ variable _opw
+ variable _evt
+
+ if {[info exists _dragops]} {
+ unset _dragops
+ }
+ array set _dragops {copy 1 move 0 link 0}
+ foreach op $ops {
+ set _dragops($op) 1
+ }
+ set _target ""
+ set _status 0
+ set _top $top
+ set _source $source
+ set _type $type
+ set _data $data
+
+ label $_opw -relief flat -bd 0 -highlightthickness 0 \
+ -foreground black -background white
+
+ bind $top <ButtonRelease-$evt> {DropSite::_release %X %Y}
+ bind $top <B$evt-Motion> {DropSite::_motion %X %Y}
+ bind $top <Motion> {DropSite::_release %X %Y}
+ set _state $state
+ set _evt $evt
+ _motion $X $Y
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::_update_operation
+# ----------------------------------------------------------------------------
+proc DropSite::_update_operation { state } {
+ variable _top
+ variable _status
+ variable _state
+
+ if { $_status & 3 } {
+ set _state $state
+ _motion [winfo pointerx $_top] [winfo pointery $_top]
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::_compute_operation
+# ----------------------------------------------------------------------------
+proc DropSite::_compute_operation { target state type } {
+ variable _curop
+ variable _dragops
+ upvar \#0 DropSite::$target drop
+
+ foreach {mask op} $drop($type,ops) {
+ if { ($state & $mask) == $mask } {
+ if { $_dragops($drop($type,ops,$op)) } {
+ set _curop $op
+ return
+ }
+ }
+ }
+ set _curop force
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::_draw_operation
+# ----------------------------------------------------------------------------
+proc DropSite::_draw_operation { target type } {
+ variable _opw
+ variable _curop
+ variable _dragops
+ variable _tabops
+ variable _status
+
+ upvar \#0 DropSite::$target drop
+
+ if { !($_status & 1) } {
+ catch {place forget $_opw}
+ return
+ }
+
+ if { 0 } {
+ if { ![info exist drop($type,ops,$_curop)] ||
+ !$_dragops($drop($type,ops,$_curop)) } {
+ # force to a copy operation
+ set _curop copy
+ catch {
+ $_opw configure -bitmap $_tabops(img,copy)
+ place $_opw -relx 1 -rely 1 -anchor se
+ }
+ }
+ } elseif { [string equal $_curop "default"] } {
+ catch {place forget $_opw}
+ } else {
+ catch {
+ $_opw configure -bitmap $drop($type,img,$_curop)
+ place $_opw -relx 1 -rely 1 -anchor se
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::_motion
+# ----------------------------------------------------------------------------
+proc DropSite::_motion { X Y } {
+ variable _top
+ variable _target
+ variable _status
+ variable _state
+ variable _curop
+ variable _type
+ variable _data
+ variable _source
+ variable _evt
+
+ set script [bind $_top <B$_evt-Motion>]
+ bind $_top <B$_evt-Motion> {}
+ bind $_top <Motion> {}
+ wm geometry $_top "+[expr {$X+1}]+[expr {$Y+1}]"
+ update
+ if { ![winfo exists $_top] } {
+ return
+ }
+ set path [winfo containing $X $Y]
+ if { ![string equal $path $_target] } {
+ # path != current target
+ if { $_status & 2 } {
+ # current target is valid and has recall status
+ # generate leave event
+ upvar \#0 DropSite::$_target drop
+ uplevel \#0 $drop(overcmd) [list $_target $_source leave $X $Y $_curop $_type $_data]
+ }
+ set _target $path
+ upvar \#0 DropSite::$_target drop
+ if { [info exists drop($_type,ops)] } {
+ # path is a valid target
+ _compute_operation $_target $_state $_type
+ if { $drop(overcmd) != "" } {
+ set arg [list $_target $_source enter $X $Y $_curop $_type $_data]
+ set _status [uplevel \#0 $drop(overcmd) $arg]
+ } else {
+ set _status 1
+ catch {$_top configure -cursor based_arrow_down}
+ }
+ _draw_operation $_target $_type
+ update
+ catch {
+ bind $_top <B$_evt-Motion> {DropSite::_motion %X %Y}
+ bind $_top <Motion> {DropSite::_release %X %Y}
+ }
+ return
+ } else {
+ set _status 0
+ catch {$_top configure -cursor dot}
+ _draw_operation "" ""
+ }
+ } elseif { $_status & 2 } {
+ upvar \#0 DropSite::$_target drop
+ _compute_operation $_target $_state $_type
+ set arg [list $_target $_source motion $X $Y $_curop $_type $_data]
+ set _status [uplevel \#0 $drop(overcmd) $arg]
+ _draw_operation $_target $_type
+ }
+ update
+ catch {
+ bind $_top <B$_evt-Motion> {DropSite::_motion %X %Y}
+ bind $_top <Motion> {DropSite::_release %X %Y}
+ }
+}
+
+
+
+# ----------------------------------------------------------------------------
+# Command DropSite::_release
+# ----------------------------------------------------------------------------
+proc DropSite::_release { X Y } {
+ variable _target
+ variable _status
+ variable _curop
+ variable _source
+ variable _type
+ variable _data
+
+ if { $_status & 1 } {
+ upvar \#0 DropSite::$_target drop
+
+ set res [uplevel \#0 $drop(dropcmd) [list $_target $_source $X $Y $_curop $_type $_data]]
+ DragSite::_end_drag $_source $_target $drop($_type,ops,$_curop) $_type $_data $res
+ } else {
+ if { $_status & 2 } {
+ # notify leave event
+ upvar \#0 DropSite::$_target drop
+ uplevel \#0 $drop(overcmd) [list $_target $_source leave $X $Y $_curop $_type $_data]
+ }
+ DragSite::_end_drag $_source "" "" $_type $_data 0
+ }
+}
diff --git a/modules/tclsci/tcl/BWidget/dynhelp.tcl b/modules/tclsci/tcl/BWidget/dynhelp.tcl
new file mode 100755
index 000000000..937499224
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/dynhelp.tcl
@@ -0,0 +1,793 @@
+# ----------------------------------------------------------------------------
+# dynhelp.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: dynhelp.tcl,v 1.20.2.1 2009/08/12 07:20:21 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - DynamicHelp::configure
+# - DynamicHelp::include
+# - DynamicHelp::sethelp
+# - DynamicHelp::register
+# - DynamicHelp::_motion_balloon
+# - DynamicHelp::_motion_info
+# - DynamicHelp::_leave_info
+# - DynamicHelp::_menu_info
+# - DynamicHelp::_show_help
+# - DynamicHelp::_init
+# ----------------------------------------------------------------------------
+
+namespace eval DynamicHelp {
+ Widget::define DynamicHelp dynhelp -classonly
+
+ if {$::tcl_version >= 8.5} {
+ set fontdefault TkTooltipFont
+ } elseif {$Widget::_aqua} {
+ set fontdefault {helvetica 11}
+ } else {
+ set fontdefault {helvetica 8}
+ }
+
+ Widget::declare DynamicHelp [list\
+ {-foreground TkResource black 0 label}\
+ {-topbackground TkResource black 0 {label -foreground}}\
+ {-background TkResource "#FFFFC0" 0 label}\
+ {-borderwidth TkResource 1 0 label}\
+ {-justify TkResource left 0 label}\
+ [list -font TkResource $fontdefault 0 label]\
+ {-delay Int 600 0 "%d >= 100 & %d <= 2000"}\
+ {-state Enum "normal" 0 {normal disabled}}\
+ {-padx TkResource 1 0 label}\
+ {-pady TkResource 1 0 label}\
+ {-bd Synonym -borderwidth}\
+ {-bg Synonym -background}\
+ {-fg Synonym -foreground}\
+ {-topbg Synonym -topbackground}\
+ ]
+
+ proc use {} {}
+
+ variable _registered
+ variable _canvases
+ variable _texts
+
+ variable _top ".help_shell"
+ variable _id ""
+ variable _delay 600
+ variable _current_balloon ""
+ variable _current_variable ""
+ variable _saved
+
+ Widget::init DynamicHelp $_top {}
+
+ bind BwHelpBalloon <Enter> {DynamicHelp::_motion_balloon enter %W %X %Y}
+ bind BwHelpBalloon <Motion> {DynamicHelp::_motion_balloon motion %W %X %Y}
+ bind BwHelpBalloon <Leave> {DynamicHelp::_motion_balloon leave %W %X %Y}
+ bind BwHelpBalloon <Button> {DynamicHelp::_motion_balloon button %W %X %Y}
+ bind BwHelpBalloon <Destroy> {DynamicHelp::_unset_help %W}
+
+ bind BwHelpVariable <Enter> {DynamicHelp::_motion_info %W}
+ bind BwHelpVariable <Leave> {DynamicHelp::_leave_info %W}
+ bind BwHelpVariable <Destroy> {DynamicHelp::_unset_help %W}
+
+ bind BwHelpMenu <<MenuSelect>> {DynamicHelp::_menu_info select %W}
+ bind BwHelpMenu <Unmap> {DynamicHelp::_menu_info unmap %W}
+ bind BwHelpMenu <Destroy> {DynamicHelp::_unset_help %W}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::configure
+# ----------------------------------------------------------------------------
+proc DynamicHelp::configure { args } {
+ variable _top
+ variable _delay
+
+ set res [Widget::configure $_top $args]
+ if { [Widget::hasChanged $_top -delay val] } {
+ set _delay $val
+ }
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::include
+# ----------------------------------------------------------------------------
+proc DynamicHelp::include { class type } {
+ set helpoptions [list \
+ [list -helptext String "" 0] \
+ [list -helpvar String "" 0] \
+ [list -helpcmd String "" 0] \
+ [list -helptype Enum $type 0 [list balloon variable]] \
+ ]
+ Widget::declare $class $helpoptions
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::sethelp
+# ----------------------------------------------------------------------------
+proc DynamicHelp::sethelp { path subpath {force 0}} {
+ foreach {ctype ctext cvar} [Widget::hasChangedX $path \
+ -helptype -helptext -helpvar] break
+ if { $force || $ctype || $ctext || $cvar } {
+ set htype [Widget::cget $path -helptype]
+ switch $htype {
+ balloon {
+ return [register $subpath balloon \
+ [Widget::cget $path -helptext]]
+ }
+ variable {
+ return [register $subpath variable \
+ [Widget::cget $path -helpvar] \
+ [Widget::cget $path -helptext]]
+ }
+ }
+ return [register $subpath $htype]
+ }
+}
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::register
+#
+# DynamicHelp::register path balloon ?itemOrTag? text
+# DynamicHelp::register path variable ?itemOrTag? text varName
+# DynamicHelp::register path menu varName
+# DynamicHelp::register path menuentry index text
+# ----------------------------------------------------------------------------
+proc DynamicHelp::register { path type args } {
+ variable _registered
+
+ set len [llength $args]
+ if {$type == "balloon" && $len > 1} {
+ switch -exact -- [winfo class $path] {
+ "Canvas" { set type canvasBalloon }
+ "Text" -
+ "Ctext" { set type textBalloon }
+ }
+ }
+ if {$type == "variable" && $len > 2} {
+ switch -exact -- [winfo class $path] {
+ "Canvas" { set type canvasVariable }
+ "Text" -
+ "Ctext" { set type textVariable }
+ }
+ }
+
+ if { ![winfo exists $path] } {
+ _unset_help $path
+ return 0
+ }
+
+ switch $type {
+ balloon {
+ set text [lindex $args 0]
+ if {$text == ""} {
+ if {[info exists _registered($path,balloon)]} {
+ unset _registered($path,balloon)
+ }
+ return 0
+ }
+
+ _add_balloon $path $text
+ }
+
+ canvasBalloon {
+ set tagOrItem [lindex $args 0]
+ set text [lindex $args 1]
+ if {$text == ""} {
+ if {[info exists _registered($path,$tagOrItem,balloon)]} {
+ unset _registered($path,$tagOrItem,balloon)
+ }
+ return 0
+ }
+
+ _add_canvas_balloon $path $text $tagOrItem
+ }
+
+ textBalloon {
+ set tagOrItem [lindex $args 0]
+ set text [lindex $args 1]
+ if {$text == ""} {
+ if {[info exists _registered($path,$tagOrItem,balloon)]} {
+ unset _registered($path,$tagOrItem,balloon)
+ }
+ return 0
+ }
+
+ _add_text_balloon $path $text $tagOrItem
+ }
+
+ variable {
+ set var [lindex $args 0]
+ set text [lindex $args 1]
+ if {$text == "" || $var == ""} {
+ if {[info exists _registered($path,variable)]} {
+ unset _registered($path,variable)
+ }
+ return 0
+ }
+
+ _add_variable $path $text $var
+ }
+
+ canvasVariable {
+ set tagOrItem [lindex $args 0]
+ set var [lindex $args 1]
+ set text [lindex $args 2]
+ if {$text == "" || $var == ""} {
+ if {[info exists _registered($path,$tagOrItem,variable)]} {
+ unset _registered($path,$tagOrItem,variable)
+ }
+ return 0
+ }
+
+ _add_canvas_variable $path $text $var $tagOrItem
+ }
+
+ textVariable {
+ set tagOrItem [lindex $args 0]
+ set var [lindex $args 1]
+ set text [lindex $args 2]
+ if {$text == "" || $var == ""} {
+ if {[info exists _registered($path,$tagOrItem,variable)]} {
+ unset _registered($path,$tagOrItem,variable)
+ }
+ return 0
+ }
+
+ _add_text_variable $path $text $var $tagOrItem
+ }
+
+ menu {
+ set var [lindex $args 0]
+ if {$var == ""} {
+ set cpath [BWidget::clonename $path]
+ if {[winfo exists $cpath]} { set path $cpath }
+ if {[info exists _registered($path)]} {
+ unset _registered($path)
+ }
+ return 0
+ }
+
+ _add_menu $path $var
+ }
+
+ menuentry {
+ set cpath [BWidget::clonename $path]
+ if { [winfo exists $cpath] } { set path $cpath }
+ if {![info exists _registered($path)]} { return 0 }
+
+ set text [lindex $args 1]
+ set index [lindex $args 0]
+ if {$text == "" || $index == ""} {
+ set idx [lsearch $_registered($path) [list $index *]]
+ set _registered($path) [lreplace $_registered($path) $idx $idx]
+ return 0
+ }
+
+ _add_menuentry $path $text $index
+ }
+
+ default {
+ _unset_help $path
+ return 0
+ }
+ }
+
+ return 1
+}
+
+
+proc DynamicHelp::add { path args } {
+ variable _registered
+
+ array set data {
+ -type balloon
+ -text ""
+ -item ""
+ -index -1
+ -command ""
+ -variable ""
+ }
+ if {[winfo exists $path] && [winfo class $path] == "Menu"} {
+ set data(-type) menu
+ }
+ array set data $args
+
+ set item $path
+
+ switch -- $data(-type) {
+ "balloon" {
+ if {$data(-item) != ""} {
+ switch -exact -- [winfo class $path] {
+ "Canvas" {
+ _add_canvas_balloon $path $data(-text) $data(-item)
+ set item $path,$data(-item)
+ }
+ "Text" -
+ "Ctext" {
+ _add_text_balloon $path $data(-text) $data(-item)
+ set item $path,$data(-item)
+ }
+ default {
+ _add_balloon $path $data(-text)
+ }
+ }
+ } else {
+ _add_balloon $path $data(-text)
+ }
+
+ if {$data(-variable) != ""} {
+ set _registered($item,balloonVar) $data(-variable)
+ }
+ }
+
+ "variable" {
+ set var $data(-variable)
+ if {$data(-item) != ""} {
+ switch -exact -- [winfo class $path] {
+ "Canvas" {
+ _add_canvas_variable $path $data(-text) $var $data(-item)
+ set item $path,$data(-item)
+ }
+ "Text" -
+ "Ctext" {
+ _add_text_variable $path $data(-text) $var $data(-item)
+ set item $path,$data(-item)
+ }
+ default {
+ _add_variable $path $data(-text) $var
+ }
+ }
+ } else {
+ _add_variable $path $data(-text) $var
+ }
+ }
+
+ "menu" {
+ if {$data(-index) != -1} {
+ set cpath [BWidget::clonename $path]
+ if { [winfo exists $cpath] } { set path $cpath }
+ if {![info exists _registered($path)]} { return 0 }
+ _add_menuentry $path $data(-text) $data(-index)
+ set item $path,$data(-index)
+ } else {
+ _add_menu $path $data(-variable)
+ }
+ }
+
+ default {
+ return 0
+ }
+ }
+
+ if {$data(-command) != ""} {set _registered($item,command) $data(-command)}
+
+ return 1
+}
+
+
+proc DynamicHelp::delete { path } {
+ _unset_help $path
+}
+
+
+proc DynamicHelp::_add_bind_tag { path tag } {
+ set evt [bindtags $path]
+ set idx [lsearch $evt $tag]
+ set evt [lreplace $evt $idx $idx]
+ lappend evt $tag
+ bindtags $path $evt
+}
+
+
+proc DynamicHelp::_add_balloon { path text } {
+ variable _registered
+ set _registered($path,balloon) $text
+ _add_bind_tag $path BwHelpBalloon
+}
+
+
+proc DynamicHelp::_add_canvas_balloon { path text tagOrItem } {
+ variable _canvases
+ variable _registered
+
+ set _registered($path,$tagOrItem,balloon) $text
+
+ if {![info exists _canvases($path,balloon)]} {
+ ## This canvas doesn't have the bindings yet.
+
+ _add_bind_tag $path BwHelpBalloon
+
+ $path bind BwHelpBalloon <Enter> \
+ {DynamicHelp::_motion_balloon enter %W %X %Y 1}
+ $path bind BwHelpBalloon <Motion> \
+ {DynamicHelp::_motion_balloon motion %W %X %Y 1}
+ $path bind BwHelpBalloon <Leave> \
+ {DynamicHelp::_motion_balloon leave %W %X %Y 1}
+ $path bind BwHelpBalloon <Button> \
+ {DynamicHelp::_motion_balloon button %W %X %Y 1}
+
+ set _canvases($path,balloon) 1
+ }
+
+ $path addtag BwHelpBalloon withtag $tagOrItem
+}
+
+
+proc DynamicHelp::_add_text_balloon { path text tagOrItem } {
+ variable _texts
+ variable _registered
+
+ set _registered($path,$tagOrItem,balloon) $text
+
+ if { ![info exists _texts($path,$tagOrItem,balloon)] } {
+ $path tag bind $tagOrItem <Enter> \
+ [list DynamicHelp::_motion_balloon enter $path %X %Y 0 1]
+ $path tag bind $tagOrItem <Motion> \
+ [list DynamicHelp::_motion_balloon motion $path %X %Y 0 1]
+ $path tag bind $tagOrItem <Leave> \
+ [list DynamicHelp::_motion_balloon leave $path %X %Y 0 1]
+ $path tag bind $tagOrItem <Button> \
+ [list DynamicHelp::_motion_balloon button $path %X %Y 0 1]
+
+ set _texts($path,$tagOrItem,balloon) 1
+ }
+}
+
+
+proc DynamicHelp::_add_variable { path text varName } {
+ variable _registered
+ set _registered($path,variable) [list $varName $text]
+ _add_bind_tag $path BwHelpVariable
+}
+
+
+proc DynamicHelp::_add_canvas_variable { path text varName tagOrItem } {
+ variable _canvases
+ variable _registered
+
+ set _registered($path,$tagOrItem,variable) [list $varName $text]
+
+ if {![info exists _canvases($path,variable)]} {
+ ## This canvas doesn't have the bindings yet.
+
+ _add_bind_tag $path BwHelpVariable
+
+ $path bind BwHelpVariable <Enter> \
+ {DynamicHelp::_motion_info %W 1}
+ $path bind BwHelpVariable <Motion> \
+ {DynamicHelp::_motion_info %W 1}
+ $path bind BwHelpVariable <Leave> \
+ {DynamicHelp::_leave_info %W 1}
+
+ set _canvases($path,variable) 1
+ }
+
+ $path addtag BwHelpVariable withtag $tagOrItem
+}
+
+
+proc DynamicHelp::_add_text_variable { path text varName tagOrItem } {
+ variable _texts
+ variable _registered
+
+ set _registered($path,$tagOrItem,variable) [list $varName $text]
+
+ if {![info exists _texts($path,$tagOrItem,variable)]} {
+
+ $path tag bind $tagOrItem <Enter> \
+ [list DynamicHelp::_motion_info $path 0 1]
+ $path tag bind $tagOrItem <Motion> \
+ [list DynamicHelp::_motion_info $path 0 1]
+ $path tag bind $tagOrItem <Leave> \
+ [list DynamicHelp::_leave_info $path 0 1]
+
+ set _texts($path,$tagOrItem,variable) 1
+ }
+}
+
+
+proc DynamicHelp::_add_menu { path varName } {
+ variable _registered
+
+ set cpath [BWidget::clonename $path]
+ if { [winfo exists $cpath] } { set path $cpath }
+
+ set _registered($path) [list $varName]
+ _add_bind_tag $path BwHelpMenu
+}
+
+
+proc DynamicHelp::_add_menuentry { path text index } {
+ variable _registered
+
+ set idx [lsearch $_registered($path) [list $index *]]
+ set list [list $index $text]
+ if { $idx == -1 } {
+ lappend _registered($path) $list
+ } else {
+ set _registered($path) \
+ [lreplace $_registered($path) $idx $idx $list]
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_motion_balloon
+# ----------------------------------------------------------------------------
+proc DynamicHelp::_motion_balloon { type path x y {isCanvasItem 0} {isTextItem 0} } {
+ variable _top
+ variable _id
+ variable _delay
+ variable _current_balloon
+
+ set w $path
+ if {$isCanvasItem} {
+ set path [_get_canvas_path $path balloon]
+ } elseif {$isTextItem} {
+ set path [_get_text_path $path balloon]
+ }
+
+ if { $_current_balloon != $path && $type == "enter" } {
+ set _current_balloon $path
+ set type "motion"
+ destroy $_top
+ }
+ if { $_current_balloon == $path } {
+ if { $_id != "" } {
+ after cancel $_id
+ set _id ""
+ }
+ if { $type == "motion" } {
+ if { ![winfo exists $_top] } {
+ set cmd [list DynamicHelp::_show_help $path $w $x $y]
+ set _id [after $_delay $cmd]
+ }
+ # Bug 923942 proposes to destroy on motion to remove dynhelp on motion.
+ # this might be an optional behaviour in future versions
+ } else {
+ destroy $_top
+ set _current_balloon ""
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_motion_info
+# ----------------------------------------------------------------------------
+proc DynamicHelp::_motion_info { path {isCanvasItem 0} {isTextItem 0} } {
+ variable _saved
+ variable _registered
+ variable _current_variable
+
+ if {$isCanvasItem} {
+ set path [_get_canvas_path $path variable]
+ } elseif {$isTextItem} {
+ set path [_get_text_path $path variable]
+ }
+
+ if { $_current_variable != $path
+ && [info exists _registered($path,variable)] } {
+
+ set varName [lindex $_registered($path,variable) 0]
+ if {![info exists _saved]} { set _saved [GlobalVar::getvar $varName] }
+ set string [lindex $_registered($path,variable) 1]
+ if {[info exists _registered($path,command)]} {
+ set string [uplevel #0 $_registered($path,command)]
+ }
+ GlobalVar::setvar $varName $string
+ set _current_variable $path
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_leave_info
+# Leave event may be called twice (in case of pointer grab)
+# ----------------------------------------------------------------------------
+proc DynamicHelp::_leave_info { path {isCanvasItem 0} {isTextItem 0} } {
+ variable _saved
+ variable _registered
+ variable _current_variable
+
+ if {$isCanvasItem} {
+ set path [_get_canvas_path $path variable]
+ } elseif {$isTextItem} {
+ set path [_get_text_path $path variable]
+ }
+
+ if { [string equal $_current_variable $path] \
+ && [info exists _registered($path,variable)] } {
+ set varName [lindex $_registered($path,variable) 0]
+ GlobalVar::setvar $varName $_saved
+ unset _saved
+ set _current_variable ""
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_menu_info
+# ----------------------------------------------------------------------------
+# We have to check for unmap event on Unix. On Windows, unmap
+# is not delivered, but <<MenuSelect>> is triggered appropriately when menu
+# is unmapped.
+proc DynamicHelp::_menu_info { event path } {
+ variable _registered
+
+ if { [info exists _registered($path)] } {
+ set index [$path index active]
+ set varName [lindex $_registered($path) 0]
+ if { ![string equal $event "unmap"] &&
+ ![string equal $index "none"] &&
+ [set idx [lsearch $_registered($path) [list $index *]]] != -1 } {
+ set string [lindex [lindex $_registered($path) $idx] 1]
+ if {[info exists _registered($path,$index,command)]} {
+ set string [uplevel #0 $_registered($path,$index,command)]
+ }
+ GlobalVar::setvar $varName $string
+ } else {
+ GlobalVar::setvar $varName ""
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_show_help
+# ----------------------------------------------------------------------------
+proc DynamicHelp::_show_help { path w x y } {
+ variable _top
+ variable _registered
+ variable _id
+ variable _delay
+
+ if { [Widget::getoption $_top -state] == "disabled" } { return }
+
+ if { [info exists _registered($path,balloon)] } {
+ destroy $_top
+
+ set string $_registered($path,balloon)
+
+ if {[info exists _registered($path,balloonVar)]} {
+ upvar #0 $_registered($path,balloonVar) var
+ if {[info exists var]} { set string $var }
+ }
+
+ if {[info exists _registered($path,command)]} {
+ set string [uplevel #0 $_registered($path,command)]
+ }
+
+ if {$string == ""} { return }
+
+ toplevel $_top -relief flat \
+ -bg [Widget::getoption $_top -topbackground] \
+ -bd [Widget::getoption $_top -borderwidth] \
+ -screen [winfo screen $w]
+
+ wm withdraw $_top
+ if { $Widget::_aqua } {
+ ::tk::unsupported::MacWindowStyle style $_top help none
+ } else {
+ wm overrideredirect $_top 1
+ }
+
+ catch { wm attributes $_top -topmost 1 }
+
+ label $_top.label -text $string \
+ -relief flat -bd 0 -highlightthickness 0 \
+ -padx [Widget::getoption $_top -padx] \
+ -pady [Widget::getoption $_top -pady] \
+ -foreground [Widget::getoption $_top -foreground] \
+ -background [Widget::getoption $_top -background] \
+ -font [Widget::getoption $_top -font] \
+ -justify [Widget::getoption $_top -justify]
+
+
+ pack $_top.label -side left
+ update idletasks
+
+ if {![winfo exists $_top]} {return}
+
+ set scrwidth [winfo vrootwidth .]
+ set scrheight [winfo vrootheight .]
+ set width [winfo reqwidth $_top]
+ set height [winfo reqheight $_top]
+
+ # On windows multi screen configurations, coordinates may get outside
+ # the main screen. We suppose that all screens have the same size
+ # because it is not possible to query the size of the other screens.
+
+ set screenx [expr {$x % $scrwidth} ]
+ set screeny [expr {$y % $scrheight} ]
+
+ # Increment the required size by the deplacement from the passed point
+ incr width 8
+ incr height 12
+
+ if { $screenx+$width > $scrwidth } {
+ set x [expr {$x + ($scrwidth - $screenx) - ($width - 8)}]
+ } else {
+ incr x 8
+ }
+ if { $screeny+$height > $scrheight } {
+ set y [expr {$y - $height}]
+ } else {
+ incr y 12
+ }
+
+ wm geometry $_top "+$x+$y"
+ update idletasks
+
+ if {![winfo exists $_top]} { return }
+ wm deiconify $_top
+ raise $_top
+ }
+}
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_unset_help
+# ----------------------------------------------------------------------------
+proc DynamicHelp::_unset_help { path } {
+ variable _canvases
+ variable _texts
+ variable _registered
+ variable _top
+ variable _current_balloon
+
+ if {[info exists _registered($path)]} { unset _registered($path) }
+ if {[winfo exists $path]} {
+ set cpath [BWidget::clonename $path]
+ if {[info exists _registered($cpath)]} { unset _registered($cpath) }
+ }
+ array unset _canvases $path,*
+ array unset _texts $path,*
+ array unset _registered $path,*
+ if {[string equal $path $_current_balloon]} {destroy $_top}
+}
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_get_canvas_path
+# ----------------------------------------------------------------------------
+proc DynamicHelp::_get_canvas_path { path type {item ""} } {
+ variable _registered
+
+ if {$item == ""} { set item [$path find withtag current] }
+
+ ## Check the tags related to this item for the one that
+ ## represents our text. If we have text specific to this
+ ## item or for 'all' items, they override any other tags.
+ eval [list lappend tags $item all] [$path itemcget $item -tags]
+ foreach tag $tags {
+ set check $path,$tag
+ if {![info exists _registered($check,$type)]} { continue }
+ return $check
+ }
+
+ return $path
+}
+
+# ----------------------------------------------------------------------------
+# Command DynamicHelp::_get_text_path
+# ----------------------------------------------------------------------------
+proc DynamicHelp::_get_text_path { path type {item ""} } {
+ variable _registered
+
+ if {$item == ""} { set item [$path tag names current] }
+
+ ## Check the tags related to this item for the one that
+ ## represents our text. If we have text specific to this
+ ## item or for 'all' items, they override any other tags.
+ eval [list lappend tags $item all] $item
+ foreach tag $tags {
+ set check $path,$tag
+ if {![info exists _registered($check,$type)]} { continue }
+ return $check
+ }
+
+ return $path
+}
diff --git a/modules/tclsci/tcl/BWidget/entry.tcl b/modules/tclsci/tcl/BWidget/entry.tcl
new file mode 100755
index 000000000..ebf308f48
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/entry.tcl
@@ -0,0 +1,472 @@
+# ------------------------------------------------------------------------------
+# entry.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: entry.tcl,v 1.22 2009/06/10 08:48:06 oehhar Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - Entry::create
+# - Entry::configure
+# - Entry::cget
+# - Entry::_destroy
+# - Entry::_init_drag_cmd
+# - Entry::_end_drag_cmd
+# - Entry::_drop_cmd
+# - Entry::_over_cmd
+# - Entry::_auto_scroll
+# - Entry::_scroll
+# ------------------------------------------------------------------------------
+
+namespace eval Entry {
+ Widget::define Entry entry DragSite DropSite DynamicHelp
+
+ # Note: -textvariable is pulled off of the tk entry and put onto the
+ # BW Entry so that we avoid the TkResource test for it, which screws up
+ # the existance/non-existance bits of the -textvariable.
+ Widget::tkinclude Entry entry :cmd \
+ remove { -state -background -foreground -textvariable
+ -disabledforeground -disabledbackground }
+
+ set declare [list \
+ [list -background TkResource "" 0 entry] \
+ [list -foreground TkResource "" 0 entry] \
+ [list -state Enum normal 0 [list normal disabled]] \
+ [list -text String "" 0] \
+ [list -textvariable String "" 0] \
+ [list -editable Boolean 1 0] \
+ [list -command String "" 0] \
+ [list -relief TkResource "" 0 entry] \
+ [list -borderwidth TkResource "" 0 entry] \
+ [list -fg Synonym -foreground] \
+ [list -bg Synonym -background] \
+ [list -bd Synonym -borderwidth] \
+ ]
+
+ if {![package vsatisfies [package provide Tk] 8.4]} {
+ ## If we're not running version 8.4 or higher, get our
+ ## disabled resources from the button widget.
+ lappend declare [list -disabledforeground TkResource "" 0 button]
+ lappend declare [list -disabledbackground TkResource "" 0 \
+ {button -background}]
+ } else {
+ lappend declare [list -disabledforeground TkResource "" 0 entry]
+ lappend declare [list -disabledbackground TkResource "" 0 entry]
+ }
+
+ Widget::declare Entry $declare
+ Widget::addmap Entry "" :cmd { -textvariable {} }
+
+ DynamicHelp::include Entry balloon
+ DragSite::include Entry "" 3
+ DropSite::include Entry {
+ TEXT {move {}}
+ FGCOLOR {move {}}
+ BGCOLOR {move {}}
+ COLOR {move {}}
+ }
+
+ foreach event [bind Entry] {
+ bind BwEntry $event [bind Entry $event]
+ }
+
+ # Copy is kind of a special event. It should be enabled when the
+ # widget is editable but not disabled, and not when the widget is disabled.
+ # To make this a bit easier to manage, we will handle it separately.
+
+ bind BwEntry <<Copy>> {}
+ bind BwEditableEntry <<Copy>> [bind Entry <<Copy>>]
+
+ bind BwEntry <Return> [list Entry::invoke %W]
+ bind BwEntry <Destroy> [list Entry::_destroy %W]
+ bind BwDisabledEntry <Destroy> [list Entry::_destroy %W]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::create
+# ------------------------------------------------------------------------------
+proc Entry::create { path args } {
+ variable $path
+ upvar 0 $path data
+
+ array set maps [list Entry {} :cmd {}]
+ array set maps [Widget::parseArgs Entry $args]
+
+ set data(afterid) ""
+ eval [list entry $path] $maps(:cmd)
+ Widget::initFromODB Entry $path $maps(Entry)
+ set state [Widget::getMegawidgetOption $path -state]
+ set editable [Widget::getMegawidgetOption $path -editable]
+ set text [Widget::getMegawidgetOption $path -text]
+ if { $editable && [string equal $state "normal"] } {
+ bindtags $path [list $path BwEntry [winfo toplevel $path] all]
+ $path configure -takefocus 1 -insertontime 600
+ } else {
+ bindtags $path [list $path BwDisabledEntry [winfo toplevel $path] all]
+ $path configure -takefocus 0 -insertontime 0
+ }
+ if { $editable == 0 } {
+ $path configure -cursor left_ptr
+ }
+ if { [string equal $state "disabled"] } {
+ $path configure \
+ -foreground [Widget::getMegawidgetOption $path -disabledforeground] \
+ -background [Widget::getMegawidgetOption $path -disabledbackground]
+ } else {
+ $path configure \
+ -foreground [Widget::getMegawidgetOption $path -foreground] \
+ -background [Widget::getMegawidgetOption $path -background]
+ bindtags $path [linsert [bindtags $path] 2 BwEditableEntry]
+ }
+ if { [string length $text] } {
+ set varName [$path cget -textvariable]
+ if { ![string equal $varName ""] } {
+ uplevel \#0 [list set $varName [Widget::cget $path -text]]
+ } else {
+ set validateState [$path cget -validate]
+ $path configure -validate none
+ $path delete 0 end
+ $path configure -validate $validateState
+ $path insert 0 [Widget::getMegawidgetOption $path -text]
+ }
+ }
+
+ DragSite::setdrag $path $path Entry::_init_drag_cmd Entry::_end_drag_cmd 1
+ DropSite::setdrop $path $path Entry::_over_cmd Entry::_drop_cmd 1
+ DynamicHelp::sethelp $path $path 1
+
+ Widget::create Entry $path
+ proc ::$path { cmd args } \
+ "return \[Entry::_path_command [list $path] \$cmd \$args\]"
+ return $path
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::configure
+# ------------------------------------------------------------------------------
+proc Entry::configure { path args } {
+ # Cheat by setting the -text value to the current contents of the entry
+ # This might be better hidden behind a function in ::Widget.
+ set Widget::Entry::${path}:opt(-text) [$path:cmd get]
+
+ set res [Widget::configure $path $args]
+
+ # Extract the modified bits that we are interested in.
+ set vars [list chstate cheditable chfg chdfg chbg chdbg chtext]
+ set opts [list -state -editable -foreground -disabledforeground \
+ -background -disabledbackground -text]
+ foreach $vars [eval [linsert $opts 0 Widget::hasChangedX $path]] { break }
+
+ if { $chstate || $cheditable } {
+ set state [Widget::getMegawidgetOption $path -state]
+ set editable [Widget::getMegawidgetOption $path -editable]
+ set btags [bindtags $path]
+ if { $editable && [string equal $state "normal"] } {
+ set idx [lsearch $btags BwDisabledEntry]
+ if { $idx != -1 } {
+ bindtags $path [lreplace $btags $idx $idx BwEntry]
+ }
+ $path:cmd configure -takefocus 1 -insertontime 600
+ } else {
+ set idx [lsearch $btags BwEntry]
+ if { $idx != -1 } {
+ bindtags $path [lreplace $btags $idx $idx BwDisabledEntry]
+ }
+ $path:cmd configure -takefocus 0 -insertontime 0
+ if { [string equal [focus] $path] } {
+ focus .
+ }
+ }
+ }
+
+ if { $chstate || $chfg || $chdfg || $chbg || $chdbg } {
+ set state [Widget::getMegawidgetOption $path -state]
+ if { [string equal $state "disabled"] } {
+ $path:cmd configure \
+ -fg [Widget::cget $path -disabledforeground] \
+ -bg [Widget::cget $path -disabledbackground]
+ } else {
+ $path:cmd configure \
+ -fg [Widget::cget $path -foreground] \
+ -bg [Widget::cget $path -background]
+ }
+ }
+ if { $chstate } {
+ if { [string equal $state "disabled"] } {
+ set idx [lsearch -exact [bindtags $path] BwEditableEntry]
+ if { $idx != -1 } {
+ bindtags $path [lreplace [bindtags $path] $idx $idx]
+ }
+ } else {
+ set idx [expr {[lsearch [bindtags $path] Bw*Entry] + 1}]
+ bindtags $path [linsert [bindtags $path] $idx BwEditableEntry]
+ }
+ }
+
+ if { $cheditable } {
+ if { $editable } {
+ $path:cmd configure -cursor xterm
+ } else {
+ $path:cmd configure -cursor left_ptr
+ }
+ }
+
+ if { $chtext } {
+ # Oh my lordee-ba-goordee
+ # Do some magic to prevent multiple validation command firings.
+ # If there is a textvariable, set that to the right value; if not,
+ # disable validation, delete the old text, enable, then set the text.
+ set varName [$path:cmd cget -textvariable]
+ if { ![string equal $varName ""] } {
+ uplevel \#0 [list set $varName \
+ [Widget::getMegawidgetOption $path -text]]
+ } else {
+ set validateState [$path:cmd cget -validate]
+ $path:cmd configure -validate none
+ $path:cmd delete 0 end
+ $path:cmd configure -validate $validateState
+ $path:cmd insert 0 [Widget::getMegawidgetOption $path -text]
+ }
+ }
+
+ DragSite::setdrag $path $path Entry::_init_drag_cmd Entry::_end_drag_cmd
+ DropSite::setdrop $path $path Entry::_over_cmd Entry::_drop_cmd
+ DynamicHelp::sethelp $path $path
+
+ return $res
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::cget
+# ------------------------------------------------------------------------------
+proc Entry::cget { path option } {
+ if { [string equal "-text" $option] } {
+ return [$path:cmd get]
+ }
+ Widget::cget $path $option
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::invoke
+# ------------------------------------------------------------------------------
+proc Entry::invoke { path } {
+ if {[llength [set cmd [Widget::getMegawidgetOption $path -command]]]} {
+ uplevel \#0 $cmd
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_path_command
+# ------------------------------------------------------------------------------
+proc Entry::_path_command { path cmd larg } {
+ switch -exact -- $cmd {
+ configure - cget - invoke {
+ return [eval [linsert $larg 0 Entry::$cmd $path]]
+ }
+ default {
+ return [eval [linsert $larg 0 $path:cmd $cmd]]
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_init_drag_cmd
+# ------------------------------------------------------------------------------
+proc Entry::_init_drag_cmd { path X Y top } {
+ variable $path
+ upvar 0 $path data
+
+ if {[llength [set cmd [Widget::getoption $path -draginitcmd]]]} {
+ return [uplevel \#0 $cmd [list $path $X $Y $top]]
+ }
+ set type [Widget::getoption $path -dragtype]
+ if { $type == "" } {
+ set type "TEXT"
+ }
+ if { [set drag [$path get]] != "" } {
+ if { [$path:cmd selection present] } {
+ set idx [$path:cmd index @[expr {$X-[winfo rootx $path]}]]
+ set sel0 [$path:cmd index sel.first]
+ set sel1 [expr {[$path:cmd index sel.last]-1}]
+ if { $idx >= $sel0 && $idx <= $sel1 } {
+ set drag [string range $drag $sel0 $sel1]
+ set data(dragstart) $sel0
+ set data(dragend) [expr {$sel1+1}]
+ if { ![Widget::getoption $path -editable] ||
+ [Widget::getoption $path -state] == "disabled" } {
+ return [list $type {copy} $drag]
+ } else {
+ return [list $type {copy move} $drag]
+ }
+ }
+ } else {
+ set data(dragstart) 0
+ set data(dragend) end
+ if { ![Widget::getoption $path -editable] ||
+ [Widget::getoption $path -state] == "disabled" } {
+ return [list $type {copy} $drag]
+ } else {
+ return [list $type {copy move} $drag]
+ }
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_end_drag_cmd
+# ------------------------------------------------------------------------------
+proc Entry::_end_drag_cmd { path target op type dnddata result } {
+ variable $path
+ upvar 0 $path data
+
+ if {[llength [set cmd [Widget::getoption $path -dragendcmd]]]} {
+ return [uplevel \#0 $cmd [list $path $target $op $type $dnddata $result]]
+ }
+ if { $result && $op == "move" && $path != $target } {
+ $path:cmd delete $data(dragstart) $data(dragend)
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_drop_cmd
+# ------------------------------------------------------------------------------
+proc Entry::_drop_cmd { path source X Y op type dnddata } {
+ variable $path
+ upvar 0 $path data
+
+ if { $data(afterid) != "" } {
+ after cancel $data(afterid)
+ set data(afterid) ""
+ }
+ if {[llength [set cmd [Widget::getoption $path -dropcmd]]]} {
+ set idx [$path:cmd index @[expr {$X-[winfo rootx $path]}]]
+ return [uplevel \#0 $cmd [list $path $source $idx $op $type $dnddata]]
+ }
+ if { $type == "COLOR" || $type == "FGCOLOR" } {
+ configure $path -foreground $dnddata
+ } elseif { $type == "BGCOLOR" } {
+ configure $path -background $dnddata
+ } else {
+ $path:cmd icursor @[expr {$X-[winfo rootx $path]}]
+ if { $op == "move" && $path == $source } {
+ $path:cmd delete $data(dragstart) $data(dragend)
+ }
+ set sel0 [$path index insert]
+ $path:cmd insert insert $dnddata
+ set sel1 [$path index insert]
+ $path:cmd selection range $sel0 $sel1
+ }
+ return 1
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_over_cmd
+# ------------------------------------------------------------------------------
+proc Entry::_over_cmd { path source event X Y op type dnddata } {
+ variable $path
+ upvar 0 $path data
+
+ set x [expr {$X-[winfo rootx $path]}]
+ if { [string equal $event "leave"] } {
+ if { [string length $data(afterid)] } {
+ after cancel $data(afterid)
+ set data(afterid) ""
+ }
+ } elseif { [_auto_scroll $path $x] } {
+ return 2
+ }
+
+ if {[llength [set cmd [Widget::getoption $path -dropovercmd]]]} {
+ set x [expr {$X-[winfo rootx $path]}]
+ set idx [$path:cmd index @$x]
+ set res [uplevel \#0 $cmd [list $path $source $event $idx $op $type $dnddata]]
+ return $res
+ }
+
+ if { [string equal $type "COLOR"] ||
+ [string equal $type "FGCOLOR"] ||
+ [string equal $type "BGCOLOR"] } {
+ DropSite::setcursor based_arrow_down
+ return 1
+ }
+ if { [Widget::getoption $path -editable]
+ && [string equal [Widget::getoption $path -state] "normal"] } {
+ if { ![string equal $event "leave"] } {
+ $path:cmd selection clear
+ $path:cmd icursor @$x
+ DropSite::setcursor based_arrow_down
+ return 3
+ }
+ }
+ DropSite::setcursor dot
+ return 0
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_auto_scroll
+# ------------------------------------------------------------------------------
+proc Entry::_auto_scroll { path x } {
+ variable $path
+ upvar 0 $path data
+
+ set xmax [winfo width $path]
+ if { $x <= 10 && [$path:cmd index @0] > 0 } {
+ if { $data(afterid) == "" } {
+ set data(afterid) [after 100 [list Entry::_scroll $path -1 $x $xmax]]
+ DropSite::setcursor sb_left_arrow
+ }
+ return 1
+ } else {
+ if { $x >= $xmax-10 && [$path:cmd index @$xmax] < [$path:cmd index end] } {
+ if { $data(afterid) == "" } {
+ set data(afterid) [after 100 [list Entry::_scroll $path 1 $x $xmax]]
+ DropSite::setcursor sb_right_arrow
+ }
+ return 1
+ } else {
+ if { $data(afterid) != "" } {
+ after cancel $data(afterid)
+ set data(afterid) ""
+ }
+ }
+ }
+ return 0
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_scroll
+# ------------------------------------------------------------------------------
+proc Entry::_scroll { path dir x xmax } {
+ variable $path
+ upvar 0 $path data
+
+ $path:cmd xview scroll $dir units
+ $path:cmd icursor @$x
+ if { ($dir == -1 && [$path:cmd index @0] > 0) ||
+ ($dir == 1 && [$path:cmd index @$xmax] < [$path:cmd index end]) } {
+ set data(afterid) [after 100 [list Entry::_scroll $path $dir $x $xmax]]
+ } else {
+ set data(afterid) ""
+ DropSite::setcursor dot
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Entry::_destroy
+# ------------------------------------------------------------------------------
+proc Entry::_destroy { path } {
+ variable $path
+ upvar 0 $path data
+ Widget::destroy $path
+ unset data
+}
diff --git a/modules/tclsci/tcl/BWidget/font.tcl b/modules/tclsci/tcl/BWidget/font.tcl
new file mode 100755
index 000000000..e9238a286
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/font.tcl
@@ -0,0 +1,566 @@
+# ----------------------------------------------------------------------------
+# font.tcl
+# This file is part of Unifix BWidget Toolkit
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - SelectFont::create
+# - SelectFont::configure
+# - SelectFont::cget
+# - SelectFont::_draw
+# - SelectFont::_destroy
+# - SelectFont::_modstyle
+# - SelectFont::_update
+# - SelectFont::_getfont
+# - SelectFont::_init
+# ----------------------------------------------------------------------------
+
+namespace eval SelectFont {
+ Widget::define SelectFont font Dialog LabelFrame ScrolledWindow
+
+ Widget::declare SelectFont {
+ {-title String "Font selection" 0}
+ {-parent String "" 0}
+ {-background TkResource "" 0 frame}
+
+ {-type Enum dialog 0 {dialog toolbar}}
+ {-font TkResource "" 0 label}
+ {-initialcolor String "" 0}
+ {-families String "all" 1}
+ {-querysystem Boolean 1 0}
+ {-nosizes Boolean 0 1}
+ {-styles String "bold italic underline overstrike" 1}
+ {-command String "" 0}
+ {-sampletext String "Sample Text" 0}
+ {-bg Synonym -background}
+ }
+
+ variable _families
+ variable _styleOff
+ array set _styleOff [list bold normal italic roman]
+ variable _sizes {4 5 6 7 8 9 10 11 12 13 14 15 16 \
+ 17 18 19 20 21 22 23 24}
+
+ # Set up preset lists of fonts, so the user can avoid the painfully slow
+ # loadfont process if desired.
+ if { [string equal $::tcl_platform(platform) "windows"] } {
+ set presetVariable [list \
+ 7x14 \
+ Arial \
+ {Arial Narrow} \
+ {Lucida Sans} \
+ {MS Sans Serif} \
+ {MS Serif} \
+ {Times New Roman} \
+ ]
+ set presetFixed [list \
+ 6x13 \
+ {Courier New} \
+ FixedSys \
+ Terminal \
+ ]
+ set presetAll [list \
+ 6x13 \
+ 7x14 \
+ Arial \
+ {Arial Narrow} \
+ {Courier New} \
+ FixedSys \
+ {Lucida Sans} \
+ {MS Sans Serif} \
+ {MS Serif} \
+ Terminal \
+ {Times New Roman} \
+ ]
+ } else {
+ set presetVariable [list \
+ helvetica \
+ lucida \
+ lucidabright \
+ {times new roman} \
+ ]
+ set presetFixed [list \
+ courier \
+ fixed \
+ {lucida typewriter} \
+ screen \
+ serif \
+ terminal \
+ ]
+ set presetAll [list \
+ courier \
+ fixed \
+ helvetica \
+ lucida \
+ lucidabright \
+ {lucida typewriter} \
+ screen \
+ serif \
+ terminal \
+ {times new roman} \
+ ]
+ }
+ array set _families [list \
+ presetvariable $presetVariable \
+ presetfixed $presetFixed \
+ presetall $presetAll \
+ ]
+
+ variable _widget
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::create
+# ----------------------------------------------------------------------------
+proc SelectFont::create { path args } {
+ variable _families
+ variable _sizes
+ variable $path
+ upvar 0 $path data
+
+ # Initialize the internal rep of the widget options
+ Widget::init SelectFont "$path#SelectFont" $args
+
+ if { [Widget::getoption "$path#SelectFont" -querysystem] } {
+ loadfont [Widget::getoption "$path#SelectFont" -families]
+ }
+
+ set bg [Widget::getoption "$path#SelectFont" -background]
+ set _styles [Widget::getoption "$path#SelectFont" -styles]
+ if { [Widget::getoption "$path#SelectFont" -type] == "dialog" } {
+ Dialog::create $path -modal local -anchor e -default 0 -cancel 1 \
+ -background $bg \
+ -title [Widget::getoption "$path#SelectFont" -title] \
+ -parent [Widget::getoption "$path#SelectFont" -parent]
+
+ set frame [Dialog::getframe $path]
+ set topf [frame $frame.topf -relief flat -borderwidth 0 -background $bg]
+
+ set labf1 [LabelFrame::create $topf.labf1 -text "Font" -name font \
+ -side top -anchor w -relief flat -background $bg]
+ set sw [ScrolledWindow::create [LabelFrame::getframe $labf1].sw \
+ -background $bg]
+ set lbf [listbox $sw.lb \
+ -height 5 -width 25 -exportselection false -selectmode browse]
+ ScrolledWindow::setwidget $sw $lbf
+ LabelFrame::configure $labf1 -focus $lbf
+ if { [Widget::getoption "$path#SelectFont" -querysystem] } {
+ set fam [Widget::getoption "$path#SelectFont" -families]
+ } else {
+ set fam "preset"
+ append fam [Widget::getoption "$path#SelectFont" -families]
+ }
+ eval [list $lbf insert end] $_families($fam)
+ set script "set [list SelectFont::${path}(family)] \[%W curselection\];\
+ SelectFont::_update [list $path]"
+ bind $lbf <ButtonRelease-1> $script
+ bind $lbf <space> $script
+ bind $lbf <1> [list focus %W]
+ bind $lbf <Up> $script
+ bind $lbf <Down> $script
+ pack $sw -fill both -expand yes
+
+ set labf2 [LabelFrame::create $topf.labf2 -text "Size" -name size \
+ -side top -anchor w -relief flat -background $bg]
+ set sw [ScrolledWindow::create [LabelFrame::getframe $labf2].sw \
+ -scrollbar vertical -background $bg]
+ set lbs [listbox $sw.lb \
+ -height 5 -width 6 -exportselection false -selectmode browse]
+ ScrolledWindow::setwidget $sw $lbs
+ LabelFrame::configure $labf2 -focus $lbs
+ eval [list $lbs insert end] $_sizes
+ set script "set [list SelectFont::${path}(size)] \[%W curselection\];\
+ SelectFont::_update [list $path]"
+ bind $lbs <ButtonRelease-1> $script
+ bind $lbs <space> $script
+ bind $lbs <1> [list focus %W]
+ bind $lbs <Up> $script
+ bind $lbs <Down> $script
+ pack $sw -fill both -expand yes
+
+ set labf3 [LabelFrame::create $topf.labf3 -text "Style" -name style \
+ -side top -anchor w -relief sunken -bd 1 -background $bg]
+ set subf [LabelFrame::getframe $labf3]
+ foreach st $_styles {
+ set name [lindex [BWidget::getname $st] 0]
+ if { $name == "" } {
+ set name [string toupper $name 0]
+ }
+ checkbutton $subf.$st -text $name \
+ -variable SelectFont::$path\($st\) \
+ -background $bg \
+ -command [list SelectFont::_update $path]
+ bind $subf.$st <Return> break
+ pack $subf.$st -anchor w
+ }
+ LabelFrame::configure $labf3 -focus $subf.[lindex $_styles 0]
+
+ pack $labf1 -side left -anchor n -fill both -expand yes
+ if { ![Widget::getoption "$path#SelectFont" -nosizes] } {
+ pack $labf2 -side left -anchor n -fill both -expand yes -padx 8
+ }
+ pack $labf3 -side left -anchor n -fill both -expand yes
+
+ set botf [frame $frame.botf -width 100 -height 50 \
+ -bg white -bd 0 -relief flat \
+ -highlightthickness 1 -takefocus 0 \
+ -highlightbackground black \
+ -highlightcolor black]
+
+ set lab [label $botf.label \
+ -background white -foreground black \
+ -borderwidth 0 -takefocus 0 -highlightthickness 0 \
+ -text [Widget::getoption "$path#SelectFont" -sampletext]]
+ place $lab -relx 0.5 -rely 0.5 -anchor c
+
+ pack $topf -pady 4 -fill both -expand yes
+
+ if { [Widget::getoption "$path#SelectFont" -initialcolor] != ""} {
+ set thecolor [Widget::getoption "$path#SelectFont" -initialcolor]
+ set colf [frame $frame.colf]
+
+ set frc [frame $colf.frame -width 50 -height 20 -bg $thecolor -bd 0 -relief flat\
+ -highlightthickness 1 -takefocus 0 \
+ -highlightbackground black \
+ -highlightcolor black]
+
+ set script "set [list SelectFont::${path}(fontcolor)] \[tk_chooseColor -parent $colf.button -initialcolor \[set [list SelectFont::${path}(fontcolor)]\]\];\
+ SelectFont::_update [list $path]"
+
+ set but [button $colf.button -command $script \
+ -text "Color..."]
+
+ $lab configure -foreground $thecolor
+ $frc configure -bg $thecolor
+
+ pack $but -side left
+ pack $frc -side left -padx 5
+
+ set data(frc) $frc
+ set data(fontcolor) $thecolor
+
+ pack $colf -pady 4 -fill x -expand true
+
+ } else {
+ set data(fontcolor) -1
+ }
+ pack $botf -pady 4 -fill x
+
+ Dialog::add $path -name ok
+ Dialog::add $path -name cancel
+
+ set data(label) $lab
+ set data(lbf) $lbf
+ set data(lbs) $lbs
+
+ _getfont $path
+
+ Widget::create SelectFont $path 0
+
+ return [_draw $path]
+ } else {
+ if { [Widget::getoption "$path#SelectFont" -querysystem] } {
+ set fams [Widget::getoption "$path#SelectFont" -families]
+ } else {
+ set fams "preset"
+ append fams [Widget::getoption "$path#SelectFont" -families]
+ }
+ if {[Widget::theme]} {
+ ttk::frame $path
+ set lbf [ttk::combobox $path.font \
+ -takefocus 0 -exportselection 0 \
+ -values $_families($fams) \
+ -textvariable SelectFont::${path}(family) \
+ -state readonly]
+ set lbs [ttk::combobox $path.size \
+ -takefocus 0 -exportselection 0 \
+ -width 4 \
+ -values $_sizes \
+ -textvariable SelectFont::${path}(size) \
+ -state readonly]
+ bind $lbf <<ComboboxSelected>> [list SelectFont::_update $path]
+ bind $lbs <<ComboboxSelected>> [list SelectFont::_update $path]
+ } else {
+ frame $path -background $bg
+ set lbf [ComboBox::create $path.font \
+ -highlightthickness 0 -takefocus 0 -background $bg \
+ -values $_families($fams) \
+ -textvariable SelectFont::$path\(family\) \
+ -editable 0 \
+ -modifycmd [list SelectFont::_update $path]]
+ set lbs [ComboBox::create $path.size \
+ -highlightthickness 0 -takefocus 0 -background $bg \
+ -width 4 \
+ -values $_sizes \
+ -textvariable SelectFont::$path\(size\) \
+ -editable 0 \
+ -modifycmd [list SelectFont::_update $path]]
+ }
+ bind $path <Destroy> [list SelectFont::_destroy $path]
+ pack $lbf -side left -anchor w
+ pack $lbs -side left -anchor w -padx 4
+ foreach st $_styles {
+ if {$::Widget::_theme} {
+ ttk::checkbutton $path.$st -takefocus 0 \
+ -style BWSlim.Toolbutton \
+ -image [Bitmap::get $st] \
+ -variable SelectFont::${path}($st) \
+ -command [list SelectFont::_update $path]
+ } else {
+ button $path.$st \
+ -highlightthickness 0 -takefocus 0 -padx 0 -pady 0 \
+ -background $bg \
+ -image [Bitmap::get $st] \
+ -command [list SelectFont::_modstyle $path $st]
+ }
+ pack $path.$st -side left -anchor w
+ }
+ set data(label) ""
+ set data(lbf) $lbf
+ set data(lbs) $lbs
+ _getfont $path
+
+ return [Widget::create SelectFont $path]
+ }
+
+ return $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::configure
+# ----------------------------------------------------------------------------
+proc SelectFont::configure { path args } {
+ set _styles [Widget::getoption "$path#SelectFont" -styles]
+
+ set res [Widget::configure "$path#SelectFont" $args]
+
+ if { [Widget::hasChanged "$path#SelectFont" -font font] } {
+ _getfont $path
+ }
+ if { [Widget::hasChanged "$path#SelectFont" -background bg] } {
+ switch -- [Widget::getoption "$path#SelectFont" -type] {
+ dialog {
+ Dialog::configure $path -background $bg
+ set topf [Dialog::getframe $path].topf
+ $topf configure -background $bg
+ foreach labf {labf1 labf2} {
+ LabelFrame::configure $topf.$labf -background $bg
+ set subf [LabelFrame::getframe $topf.$labf]
+ ScrolledWindow::configure $subf.sw -background $bg
+ $subf.sw.lb configure -background $bg
+ }
+ LabelFrame::configure $topf.labf3 -background $bg
+ set subf [LabelFrame::getframe $topf.labf3]
+ foreach w [winfo children $subf] {
+ $w configure -background $bg
+ }
+ }
+ toolbar {
+ $path configure -background $bg
+ ComboBox::configure $path.font -background $bg
+ ComboBox::configure $path.size -background $bg
+ foreach st $_styles {
+ $path.$st configure -background $bg
+ }
+ }
+ }
+ }
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::cget
+# ----------------------------------------------------------------------------
+proc SelectFont::cget { path option } {
+ return [Widget::cget "$path#SelectFont" $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::loadfont
+# ----------------------------------------------------------------------------
+proc SelectFont::loadfont {{which all}} {
+ variable _families
+
+ # initialize families
+ if {![info exists _families(all)]} {
+ set _families(all) [lsort -dictionary [font families]]
+ }
+ if {[regexp {fixed|variable} $which] \
+ && ![info exists _families($which)]} {
+ # initialize families
+ set _families(fixed) {}
+ set _families(variable) {}
+ foreach family $_families(all) {
+ if { [font metrics [list $family] -fixed] } {
+ lappend _families(fixed) $family
+ } else {
+ lappend _families(variable) $family
+ }
+ }
+ }
+ return
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::_draw
+# ----------------------------------------------------------------------------
+proc SelectFont::_draw { path } {
+ variable $path
+ upvar 0 $path data
+
+ $data(lbf) selection clear 0 end
+ $data(lbf) selection set $data(family)
+ $data(lbf) activate $data(family)
+ $data(lbf) see $data(family)
+ $data(lbs) selection clear 0 end
+ $data(lbs) selection set $data(size)
+ $data(lbs) activate $data(size)
+ $data(lbs) see $data(size)
+ _update $path
+
+ if { [Dialog::draw $path] == 0 } {
+ set result [Widget::getoption "$path#SelectFont" -font]
+ set color $data(fontcolor)
+
+ if { $color == "" } {
+ set color #000000
+ }
+
+ } else {
+ set result ""
+ if {$data(fontcolor) == -1} {
+ set color -1
+ } else {
+ set color ""
+ }
+ }
+ unset data
+ Widget::destroy "$path#SelectFont"
+ destroy $path
+ if { $color != -1 } {
+ return [list $result $color]
+ } else {
+ return $result
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::_modstyle
+# ----------------------------------------------------------------------------
+proc SelectFont::_modstyle { path style } {
+ variable $path
+ upvar 0 $path data
+
+ $path.$style configure -relief [expr {$data($style) ? "raised" : "sunken"}]
+ set data($style) [expr {!$data($style)}]
+ _update $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::_update
+# ----------------------------------------------------------------------------
+proc SelectFont::_update { path } {
+ variable _families
+ variable _sizes
+ variable _styleOff
+ variable $path
+ upvar 0 $path data
+
+ set type [Widget::getoption "$path#SelectFont" -type]
+ set _styles [Widget::getoption "$path#SelectFont" -styles]
+ if { [Widget::getoption "$path#SelectFont" -querysystem] } {
+ set fams [Widget::getoption "$path#SelectFont" -families]
+ } else {
+ set fams "preset"
+ append fams [Widget::getoption "$path#SelectFont" -families]
+ }
+ if { $type == "dialog" } {
+ set curs [$path:cmd cget -cursor]
+ $path:cmd configure -cursor watch
+ }
+ if { [Widget::getoption "$path#SelectFont" -type] == "dialog" } {
+ set font [list [lindex $_families($fams) $data(family)] \
+ [lindex $_sizes $data(size)]]
+ } else {
+ set font [list $data(family) $data(size)]
+ }
+ foreach st $_styles {
+ if { $data($st) } {
+ lappend font $st
+ } elseif {[info exists _styleOff($st)]} {
+ # This adds the default bold/italic value to a font
+ #lappend font $_styleOff($st)
+ }
+ }
+ Widget::setoption "$path#SelectFont" -font $font
+ if { $type == "dialog" } {
+ $data(label) configure -font $font
+ $path:cmd configure -cursor $curs
+ if { ($data(fontcolor) != "") && ($data(fontcolor) != -1) } {
+ $data(label) configure -foreground $data(fontcolor)
+ $data(frc) configure -bg $data(fontcolor)
+ } elseif { $data(fontcolor) == "" } {
+ #If no color is selected, restore previous one
+ set data(fontcolor) [$data(label) cget -foreground]
+
+ }
+ } elseif { [set cmd [Widget::getoption "$path#SelectFont" -command]] != "" } {
+ uplevel \#0 $cmd
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::_getfont
+# ----------------------------------------------------------------------------
+proc SelectFont::_getfont { path } {
+ variable _families
+ variable _sizes
+ variable $path
+ upvar 0 $path data
+
+ array set font [font actual [Widget::getoption "$path#SelectFont" -font]]
+ set data(bold) [expr {![string equal $font(-weight) "normal"]}]
+ set data(italic) [expr {![string equal $font(-slant) "roman"]}]
+ set data(underline) $font(-underline)
+ set data(overstrike) $font(-overstrike)
+ set _styles [Widget::getoption "$path#SelectFont" -styles]
+ if { [Widget::getoption "$path#SelectFont" -querysystem] } {
+ set fams [Widget::getoption "$path#SelectFont" -families]
+ } else {
+ set fams "preset"
+ append fams [Widget::getoption "$path#SelectFont" -families]
+ }
+ if { [Widget::getoption "$path#SelectFont" -type] == "dialog" } {
+ set idxf [lsearch $_families($fams) $font(-family)]
+ set idxs [lsearch $_sizes $font(-size)]
+ set data(family) [expr {$idxf >= 0 ? $idxf : 0}]
+ set data(size) [expr {$idxs >= 0 ? $idxs : 0}]
+ } else {
+ set data(family) $font(-family)
+ set data(size) $font(-size)
+ if {![Widget::theme]} {
+ foreach st $_styles {
+ $path.$st configure \
+ -relief [expr {$data($st) ? "sunken":"raised"}]
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command SelectFont::_destroy
+# ----------------------------------------------------------------------------
+proc SelectFont::_destroy { path } {
+ variable $path
+ upvar 0 $path data
+ unset data
+ Widget::destroy "$path#SelectFont"
+}
diff --git a/modules/tclsci/tcl/BWidget/images/bold.gif b/modules/tclsci/tcl/BWidget/images/bold.gif
new file mode 100755
index 000000000..ddfe700d3
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/bold.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/copy.gif b/modules/tclsci/tcl/BWidget/images/copy.gif
new file mode 100755
index 000000000..362e72795
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/copy.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/cut.gif b/modules/tclsci/tcl/BWidget/images/cut.gif
new file mode 100755
index 000000000..988965c07
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/cut.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/dragfile.gif b/modules/tclsci/tcl/BWidget/images/dragfile.gif
new file mode 100755
index 000000000..a04b6db3e
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/dragfile.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/dragicon.gif b/modules/tclsci/tcl/BWidget/images/dragicon.gif
new file mode 100755
index 000000000..6ec0e55eb
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/dragicon.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/error.gif b/modules/tclsci/tcl/BWidget/images/error.gif
new file mode 100755
index 000000000..a4ed2e9d3
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/error.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/file.gif b/modules/tclsci/tcl/BWidget/images/file.gif
new file mode 100755
index 000000000..c64635ce2
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/file.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/folder.gif b/modules/tclsci/tcl/BWidget/images/folder.gif
new file mode 100755
index 000000000..262aed56c
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/folder.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/hourglass.gif b/modules/tclsci/tcl/BWidget/images/hourglass.gif
new file mode 100755
index 000000000..bac625a3e
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/hourglass.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/info.gif b/modules/tclsci/tcl/BWidget/images/info.gif
new file mode 100755
index 000000000..0286c268d
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/info.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/italic.gif b/modules/tclsci/tcl/BWidget/images/italic.gif
new file mode 100755
index 000000000..cf44c94a5
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/italic.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/minus.xbm b/modules/tclsci/tcl/BWidget/images/minus.xbm
new file mode 100755
index 000000000..5b848cd46
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/minus.xbm
@@ -0,0 +1,5 @@
+#define minus_width 9
+#define minus_height 9
+static char minus_bits[] = {
+ 0xff,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x7d,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0xff,0x01};
diff --git a/modules/tclsci/tcl/BWidget/images/new.gif b/modules/tclsci/tcl/BWidget/images/new.gif
new file mode 100755
index 000000000..74eb0a5c9
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/new.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/opcopy.xbm b/modules/tclsci/tcl/BWidget/images/opcopy.xbm
new file mode 100755
index 000000000..b4cce8538
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/opcopy.xbm
@@ -0,0 +1,5 @@
+#define opcopy_width 11
+#define opcopy_height 11
+static char opcopy_bits[] = {
+ 0xff,0xff,0x01,0xfc,0x21,0xfc,0x21,0xfc,0x21,0xfc,0xfd,0xfd,0x21,0xfc,0x21,
+ 0xfc,0x21,0xfc,0x01,0xfc,0xff,0xff};
diff --git a/modules/tclsci/tcl/BWidget/images/open.gif b/modules/tclsci/tcl/BWidget/images/open.gif
new file mode 100755
index 000000000..d344541c9
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/open.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/openfold.gif b/modules/tclsci/tcl/BWidget/images/openfold.gif
new file mode 100755
index 000000000..fc8adc589
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/openfold.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/oplink.xbm b/modules/tclsci/tcl/BWidget/images/oplink.xbm
new file mode 100755
index 000000000..cdc3acd65
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/oplink.xbm
@@ -0,0 +1,5 @@
+#define oplink_width 11
+#define oplink_height 11
+static char oplink_bits[] = {
+ 0xff,0xff,0x01,0xfc,0xf1,0xfc,0xe1,0xfc,0xf1,0xfc,0xb9,0xfc,0x19,0xfc,0x09,
+ 0xfc,0x11,0xfc,0x01,0xfc,0xff,0xff};
diff --git a/modules/tclsci/tcl/BWidget/images/opmove.xbm b/modules/tclsci/tcl/BWidget/images/opmove.xbm
new file mode 100755
index 000000000..68f81a8d3
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/opmove.xbm
@@ -0,0 +1,5 @@
+#define opmove_width 11
+#define opmove_height 11
+static char opmove_bits[] = {
+ 0xff,0xff,0x01,0xfc,0x01,0xfc,0x51,0xfc,0x89,0xfc,0xfd,0xfd,0x89,0xfc,0x51,
+ 0xfc,0x01,0xfc,0x01,0xfc,0xff,0xff};
diff --git a/modules/tclsci/tcl/BWidget/images/overstrike.gif b/modules/tclsci/tcl/BWidget/images/overstrike.gif
new file mode 100755
index 000000000..c06413e8f
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/overstrike.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/palette.gif b/modules/tclsci/tcl/BWidget/images/palette.gif
new file mode 100755
index 000000000..b41ff24f4
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/palette.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/passwd.gif b/modules/tclsci/tcl/BWidget/images/passwd.gif
new file mode 100755
index 000000000..7536cd851
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/passwd.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/paste.gif b/modules/tclsci/tcl/BWidget/images/paste.gif
new file mode 100755
index 000000000..f55d355d6
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/paste.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/plus.xbm b/modules/tclsci/tcl/BWidget/images/plus.xbm
new file mode 100755
index 000000000..4b307b875
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/plus.xbm
@@ -0,0 +1,5 @@
+#define plus_width 9
+#define plus_height 9
+static char plus_bits[] = {
+ 0xff,0x01,0x01,0x01,0x11,0x01,0x11,0x01,0x7d,0x01,0x11,0x01,0x11,0x01,0x01,
+ 0x01,0xff,0x01};
diff --git a/modules/tclsci/tcl/BWidget/images/print.gif b/modules/tclsci/tcl/BWidget/images/print.gif
new file mode 100755
index 000000000..d8c750f06
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/print.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/question.gif b/modules/tclsci/tcl/BWidget/images/question.gif
new file mode 100755
index 000000000..c6522fe38
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/question.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/redo.gif b/modules/tclsci/tcl/BWidget/images/redo.gif
new file mode 100755
index 000000000..becbd7cb8
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/redo.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/save.gif b/modules/tclsci/tcl/BWidget/images/save.gif
new file mode 100755
index 000000000..17a747905
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/save.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/target.xbm b/modules/tclsci/tcl/BWidget/images/target.xbm
new file mode 100755
index 000000000..ec2a943d8
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/target.xbm
@@ -0,0 +1,9 @@
+#define target_width 24
+#define target_height 24
+static unsigned char target_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3e, 0xe0, 0x03, 0x3e, 0xe0, 0x03, 0x3e, 0xe0, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/modules/tclsci/tcl/BWidget/images/underline.gif b/modules/tclsci/tcl/BWidget/images/underline.gif
new file mode 100755
index 000000000..53ac2e587
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/underline.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/undo.gif b/modules/tclsci/tcl/BWidget/images/undo.gif
new file mode 100755
index 000000000..6041810b3
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/undo.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/images/warning.gif b/modules/tclsci/tcl/BWidget/images/warning.gif
new file mode 100755
index 000000000..c78eee99b
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/images/warning.gif
Binary files differ
diff --git a/modules/tclsci/tcl/BWidget/init.tcl b/modules/tclsci/tcl/BWidget/init.tcl
new file mode 100755
index 000000000..eba5a16f4
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/init.tcl
@@ -0,0 +1,54 @@
+namespace eval Widget {}
+proc Widget::_opt_defaults {{prio widgetDefault}} {
+ if {$::tcl_version >= 8.4} {
+ set plat [tk windowingsystem]
+ } else {
+ set plat $::tcl_platform(platform)
+ }
+ switch -exact $plat {
+ "aqua" {
+ }
+ "win32" -
+ "windows" {
+ #option add *Listbox.background SystemWindow $prio
+ option add *ListBox.background SystemWindow $prio
+ #option add *Button.padY 0 $prio
+ option add *ButtonBox.padY 0 $prio
+ option add *Dialog.padY 0 $prio
+ option add *Dialog.anchor e $prio
+ }
+ "x11" -
+ default {
+ option add *Scrollbar.width 12 $prio
+ option add *Scrollbar.borderWidth 1 $prio
+ option add *Dialog.separator 1 $prio
+ option add *MainFrame.relief raised $prio
+ option add *MainFrame.separator none $prio
+ }
+ }
+}
+Widget::_opt_defaults
+
+# Try to load lang file corresponding to current msgcat locale
+proc Widget::_opt_lang {} {
+ set langfile [file join $::BWIDGET::LIBRARY "lang" "en.rc"]
+ if {0 != [llength [info commands ::msgcat::mcpreferences]]} {
+ foreach lang [::msgcat::mcpreferences] {
+ set l [file join $::BWIDGET::LIBRARY "lang" "$lang.rc"]
+ if {[file readable $l]} {
+ set langfile $l
+ break
+ }
+ }
+ }
+ option read $langfile
+}
+Widget::_opt_lang
+
+## Add a TraverseIn binding to standard Tk widgets to handle some of
+## the BWidget-specific things we do.
+bind Entry <<TraverseIn>> { %W selection range 0 end; %W icursor end }
+bind Spinbox <<TraverseIn>> { %W selection range 0 end; %W icursor end }
+
+bind all <Key-Tab> { Widget::traverseTo [Widget::focusNext %W] }
+bind all <<PrevWindow>> { Widget::traverseTo [Widget::focusPrev %W] }
diff --git a/modules/tclsci/tcl/BWidget/label.tcl b/modules/tclsci/tcl/BWidget/label.tcl
new file mode 100755
index 000000000..b15ab017a
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/label.tcl
@@ -0,0 +1,329 @@
+# ------------------------------------------------------------------------------
+# label.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: label.tcl,v 1.10.2.2 2010/11/21 19:35:48 oehhar Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - Label::create
+# - Label::configure
+# - Label::cget
+# - Label::setfocus
+# - Label::_drag_cmd
+# - Label::_drop_cmd
+# - Label::_over_cmd
+# ------------------------------------------------------------------------------
+
+namespace eval Label {
+ Widget::define Label label DragSite DropSite DynamicHelp
+
+ if {$::Widget::_theme} {
+ Widget::tkinclude Label label .l \
+ remove { -foreground -text -textvariable -underline -state}
+ } else {
+ Widget::tkinclude Label label .l \
+ remove { -foreground -text -textvariable -underline }
+ }
+
+ Widget::declare Label {
+ {-name String "" 0}
+ {-text String "" 0}
+ {-textvariable String "" 0}
+ {-underline Int -1 0 "%d >= -1"}
+ {-focus String "" 0}
+ {-foreground TkResource "" 0 label}
+ {-disabledforeground TkResource "" 0 button}
+ {-state Enum normal 0 {normal disabled}}
+
+ {-fg Synonym -foreground}
+ }
+
+ DynamicHelp::include Label balloon
+ DragSite::include Label "" 1
+ DropSite::include Label {
+ TEXT {move {}}
+ IMAGE {move {}}
+ BITMAP {move {}}
+ FGCOLOR {move {}}
+ BGCOLOR {move {}}
+ COLOR {move {}}
+ }
+
+ Widget::syncoptions Label "" .l {-text {} -underline {}}
+
+ bind BwLabel <FocusIn> [list Label::setfocus %W]
+ bind BwLabel <Destroy> [list Label::_destroy %W]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Label::create
+# ------------------------------------------------------------------------------
+proc Label::create { path args } {
+ array set maps [list Label {} .l {}]
+ array set maps [Widget::parseArgs Label $args]
+ frame $path -class Label -borderwidth 0 -highlightthickness 0 -relief flat -padx 0 -pady 0
+ Widget::initFromODB Label $path $maps(Label)
+
+ if {$::Widget::_theme} {
+ eval [list ttk::label $path.l] $maps(.l)
+ } else {
+ eval [list label $path.l] $maps(.l)
+ }
+
+ if {$::Widget::_theme} {
+ if { [Widget::cget $path -state] != "normal" } {
+ $path.l state disabled
+ }
+ } else {
+ if { [Widget::cget $path -state] == "normal" } {
+ set fg [Widget::cget $path -foreground]
+ } else {
+ set fg [Widget::cget $path -disabledforeground]
+ }
+ $path.l configure -foreground $fg
+ }
+
+ set var [Widget::cget $path -textvariable]
+ if { $var == "" &&
+ [Widget::cget $path -image] == "" &&
+ ($::Widget::_theme || [Widget::cget $path -bitmap] == "")} {
+ set desc [BWidget::getname [Widget::cget $path -name]]
+ if { $desc != "" } {
+ set text [lindex $desc 0]
+ set under [lindex $desc 1]
+ } else {
+ set text [Widget::cget $path -text]
+ set under [Widget::cget $path -underline]
+ }
+ } else {
+ set under -1
+ set text ""
+ }
+
+ $path.l configure -text $text -textvariable $var \
+ -underline $under
+
+ set accel [string tolower [string index $text $under]]
+ if { $accel != "" } {
+ bind [winfo toplevel $path] <Alt-$accel> "Label::setfocus $path"
+ }
+
+ bindtags $path [list BwLabel [winfo toplevel $path] all]
+ bindtags $path.l [list $path.l $path Label [winfo toplevel $path] all]
+ pack $path.l -expand yes -fill both
+
+ set dragendcmd [Widget::cget $path -dragendcmd]
+ DragSite::setdrag $path $path.l Label::_init_drag_cmd $dragendcmd 1
+ DropSite::setdrop $path $path.l Label::_over_cmd Label::_drop_cmd 1
+ DynamicHelp::sethelp $path $path.l 1
+
+ return [Widget::create Label $path]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Label::configure
+# ------------------------------------------------------------------------------
+proc Label::configure { path args } {
+ set oldunder [$path.l cget -underline]
+ if { $oldunder != -1 } {
+ set oldaccel [string tolower [string index [$path.l cget -text] $oldunder]]
+ } else {
+ set oldaccel ""
+ }
+ set res [Widget::configure $path $args]
+
+ set cfg [Widget::hasChanged $path -foreground fg]
+ set cst [Widget::hasChanged $path -state state]
+
+ if {$::Widget::_theme} {
+ if { $cfg } {
+ $path.l configure -fg $fg
+ }
+ if { $cst } {
+ if { $state == "normal" } {
+ $path.l state !disabled
+ } else {
+ $path.l state disabled
+ }
+ }
+ } else {
+ set cdfg [Widget::hasChanged $path -disabledforeground dfg]
+ if { $cst || $cfg || $cdfg } {
+ if { $state == "normal" } {
+ $path.l configure -fg $fg
+ } else {
+ $path.l configure -fg $dfg
+ }
+ }
+ }
+
+ set cv [Widget::hasChanged $path -textvariable var]
+ set cb [Widget::hasChanged $path -image img]
+ if {$::Widget::_theme} {
+ set ci 0
+ set bmp ""
+ } else {
+ set ci [Widget::hasChanged $path -bitmap bmp]
+ }
+ set cn [Widget::hasChanged $path -name name]
+ set ct [Widget::hasChanged $path -text text]
+ set cu [Widget::hasChanged $path -underline under]
+
+ if { $cv || $cb || $ci || $cn || $ct || $cu } {
+ if { $var == "" && $img == "" && $bmp == "" } {
+ set desc [BWidget::getname $name]
+ if { $desc != "" } {
+ set text [lindex $desc 0]
+ set under [lindex $desc 1]
+ }
+ } else {
+ set under -1
+ set text ""
+ }
+ set top [winfo toplevel $path]
+ if { $oldaccel != "" } {
+ bind $top <Alt-$oldaccel> {}
+ }
+ set accel [string tolower [string index $text $under]]
+ if { $accel != "" } {
+ bind $top <Alt-$accel> [list Label::setfocus $path]
+ }
+ $path.l configure -text $text -underline $under -textvariable $var
+ }
+
+ set force [Widget::hasChanged $path -dragendcmd dragend]
+ DragSite::setdrag $path $path.l Label::_init_drag_cmd $dragend $force
+ DropSite::setdrop $path $path.l Label::_over_cmd Label::_drop_cmd
+ DynamicHelp::sethelp $path $path.l
+
+ return $res
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Label::cget
+# ------------------------------------------------------------------------------
+proc Label::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Label::identify
+# ----------------------------------------------------------------------------
+proc Label::identify { path args } {
+ eval $path.l identify $args
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Label::instate
+# ----------------------------------------------------------------------------
+proc Label::instate { path args } {
+ eval $path.l instate $args
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Label::state
+# ----------------------------------------------------------------------------
+proc Label::state { path args } {
+ eval $path.l state $args
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Label::setfocus
+# ------------------------------------------------------------------------------
+proc Label::setfocus { path } {
+ if { [string equal [Widget::cget $path -state] "normal"] } {
+ set w [Widget::cget $path -focus]
+ if { [winfo exists $w] && [Widget::focusOK $w] } {
+ focus $w
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Label::_init_drag_cmd
+# ------------------------------------------------------------------------------
+proc Label::_init_drag_cmd { path X Y top } {
+ set path [winfo parent $path]
+ if { [set cmd [Widget::cget $path -draginitcmd]] != "" } {
+ return [uplevel \#0 $cmd [list $path $X $Y $top]]
+ }
+ if { [set data [$path.l cget -image]] != "" } {
+ set type "IMAGE"
+ pack [label $top.l -image $data]
+ } elseif { [set data [$path.l cget -bitmap]] != "" } {
+ set type "BITMAP"
+ pack [label $top.l -bitmap $data]
+ } else {
+ set data [$path.l cget -text]
+ set type "TEXT"
+ }
+ set usertype [Widget::getoption $path -dragtype]
+ if { $usertype != "" } {
+ set type $usertype
+ }
+ return [list $type {copy} $data]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Label::_drop_cmd
+# ------------------------------------------------------------------------------
+proc Label::_drop_cmd { path source X Y op type data } {
+ set path [winfo parent $path]
+ if { [set cmd [Widget::cget $path -dropcmd]] != "" } {
+ return [uplevel \#0 $cmd [list $path $source $X $Y $op $type $data]]
+ }
+ if { $type == "COLOR" || $type == "FGCOLOR" } {
+ configure $path -foreground $data
+ } elseif { $type == "BGCOLOR" } {
+ configure $path -background $data
+ } else {
+ set text ""
+ set image ""
+ set bitmap ""
+ switch -- $type {
+ IMAGE {set image $data}
+ BITMAP {set bitmap $data}
+ default {
+ set text $data
+ if { [set var [$path.l cget -textvariable]] != "" } {
+ configure $path -image "" -bitmap ""
+ GlobalVar::setvar $var $data
+ return
+ }
+ }
+ }
+ configure $path -text $text -image $image -bitmap $bitmap
+ }
+ return 1
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Label::_over_cmd
+# ------------------------------------------------------------------------------
+proc Label::_over_cmd { path source event X Y op type data } {
+ set path [winfo parent $path]
+ if { [set cmd [Widget::cget $path -dropovercmd]] != "" } {
+ return [uplevel \#0 $cmd [list $path $source $event $X $Y $op $type $data]]
+ }
+ if { [Widget::getoption $path -state] == "normal" ||
+ $type == "COLOR" || $type == "FGCOLOR" || $type == "BGCOLOR" } {
+ DropSite::setcursor based_arrow_down
+ return 1
+ }
+ DropSite::setcursor dot
+ return 0
+}
+
+
+proc Label::_destroy { path } {
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/labelentry.tcl b/modules/tclsci/tcl/BWidget/labelentry.tcl
new file mode 100755
index 000000000..0e1718c6d
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/labelentry.tcl
@@ -0,0 +1,100 @@
+# ------------------------------------------------------------------------------
+# labelentry.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: labelentry.tcl,v 1.6 2003/10/20 21:23:52 damonc Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - LabelEntry::create
+# - LabelEntry::configure
+# - LabelEntry::cget
+# - LabelEntry::bind
+# ------------------------------------------------------------------------------
+
+namespace eval LabelEntry {
+ Widget::define LabelEntry labelentry Entry LabelFrame
+
+ Widget::bwinclude LabelEntry LabelFrame .labf \
+ remove {-relief -borderwidth -focus} \
+ rename {-text -label} \
+ prefix {label -justify -width -anchor -height -font -textvariable}
+
+ Widget::bwinclude LabelEntry Entry .e \
+ remove {-fg -bg} \
+ rename {-foreground -entryfg -background -entrybg}
+
+ Widget::addmap LabelEntry "" :cmd {-background {}}
+
+ Widget::syncoptions LabelEntry Entry .e {-text {}}
+ Widget::syncoptions LabelEntry LabelFrame .labf {-label -text -underline {}}
+
+ ::bind BwLabelEntry <FocusIn> [list focus %W.labf]
+ ::bind BwLabelEntry <Destroy> [list LabelEntry::_destroy %W]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command LabelEntry::create
+# ------------------------------------------------------------------------------
+proc LabelEntry::create { path args } {
+ array set maps [list LabelEntry {} :cmd {} .labf {} .e {}]
+ array set maps [Widget::parseArgs LabelEntry $args]
+
+ eval [list frame $path] $maps(:cmd) -class LabelEntry \
+ -relief flat -bd 0 -highlightthickness 0 -takefocus 0
+ Widget::initFromODB LabelEntry $path $maps(LabelEntry)
+
+ set labf [eval [list LabelFrame::create $path.labf] $maps(.labf) \
+ [list -relief flat -borderwidth 0 -focus $path.e]]
+ set subf [LabelFrame::getframe $labf]
+ set entry [eval [list Entry::create $path.e] $maps(.e)]
+
+ pack $entry -in $subf -fill both -expand yes
+ pack $labf -fill both -expand yes
+
+ bindtags $path [list $path BwLabelEntry [winfo toplevel $path] all]
+
+ return [Widget::create LabelEntry $path]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command LabelEntry::configure
+# ------------------------------------------------------------------------------
+proc LabelEntry::configure { path args } {
+ return [Widget::configure $path $args]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command LabelEntry::cget
+# ------------------------------------------------------------------------------
+proc LabelEntry::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command LabelEntry::bind
+# ------------------------------------------------------------------------------
+proc LabelEntry::bind { path args } {
+ return [eval [list ::bind $path.e] $args]
+}
+
+
+#------------------------------------------------------------------------------
+# Command LabelEntry::_path_command
+#------------------------------------------------------------------------------
+proc LabelEntry::_path_command { path cmd larg } {
+ if { [string equal $cmd "configure"] ||
+ [string equal $cmd "cget"] ||
+ [string equal $cmd "bind"] } {
+ return [eval [list LabelEntry::$cmd $path] $larg]
+ } else {
+ return [eval [list $path.e:cmd $cmd] $larg]
+ }
+}
+
+
+proc LabelEntry::_destroy { path } {
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/labelframe.tcl b/modules/tclsci/tcl/BWidget/labelframe.tcl
new file mode 100755
index 000000000..7769ffdb2
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/labelframe.tcl
@@ -0,0 +1,160 @@
+# ------------------------------------------------------------------------------
+# labelframe.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: labelframe.tcl,v 1.6 2003/10/20 21:23:52 damonc Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - LabelFrame::create
+# - LabelFrame::getframe
+# - LabelFrame::configure
+# - LabelFrame::cget
+# - LabelFrame::align
+# ------------------------------------------------------------------------------
+
+namespace eval LabelFrame {
+ Widget::define LabelFrame labelframe Label
+
+ Widget::bwinclude LabelFrame Label .l \
+ remove {
+ -highlightthickness -highlightcolor -highlightbackground
+ -takefocus -relief -borderwidth
+ -cursor
+ -dragenabled -draginitcmd -dragendcmd -dragevent -dragtype
+ -dropenabled -droptypes -dropovercmd -dropcmd} \
+ initialize {-anchor w}
+
+ Widget::declare LabelFrame {
+ {-relief TkResource flat 0 frame}
+ {-borderwidth TkResource 0 0 frame}
+ {-side Enum left 1 {left right top bottom}}
+ {-bd Synonym -borderwidth}
+ }
+
+ Widget::addmap LabelFrame "" :cmd {-background {}}
+ Widget::addmap LabelFrame "" .f {-background {} -relief {} -borderwidth {}}
+
+ Widget::syncoptions LabelFrame Label .l {-text {} -underline {}}
+
+ bind BwLabelFrame <FocusIn> [list Label::setfocus %W.l]
+ bind BwLabelFrame <Destroy> [list LabelFrame::_destroy %W]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command LabelFrame::create
+# ----------------------------------------------------------------------------
+proc LabelFrame::create { path args } {
+ Widget::init LabelFrame $path $args
+
+ set path [eval [list frame $path] [Widget::subcget $path :cmd] \
+ -relief flat -bd 0 -takefocus 0 -highlightthickness 0 \
+ -class LabelFrame]
+
+ set label [eval [list Label::create $path.l] [Widget::subcget $path .l] \
+ -takefocus 0 -highlightthickness 0 -relief flat \
+ -borderwidth 0 -dropenabled 0 -dragenabled 0]
+ set frame [eval [list frame $path.f] [Widget::subcget $path .f] \
+ -highlightthickness 0 -takefocus 0]
+
+ switch [Widget::getoption $path -side] {
+ left {set packopt "-side left"}
+ right {set packopt "-side right"}
+ top {set packopt "-side top -fill x"}
+ bottom {set packopt "-side bottom -fill x"}
+ }
+
+ eval [list pack $label] $packopt
+ pack $frame -fill both -expand yes
+
+ bindtags $path [list $path BwLabelFrame [winfo toplevel $path] all]
+
+ return [Widget::create LabelFrame $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command LabelFrame::getframe
+# ----------------------------------------------------------------------------
+proc LabelFrame::getframe { path } {
+ return $path.f
+}
+
+
+# ----------------------------------------------------------------------------
+# Command LabelFrame::configure
+# ----------------------------------------------------------------------------
+proc LabelFrame::configure { path args } {
+ return [Widget::configure $path $args]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command LabelFrame::cget
+# ----------------------------------------------------------------------------
+proc LabelFrame::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command LabelFrame::align
+# This command align label of all widget given by args of class LabelFrame
+# (or "derived") by setting their width to the max one +1
+# ----------------------------------------------------------------------------
+proc LabelFrame::align { args } {
+ set maxlen 0
+ set wlist {}
+ foreach wl $args {
+ foreach w $wl {
+ if { ![info exists Widget::_class($w)] } {
+ continue
+ }
+ set class $Widget::_class($w)
+ if { [string equal $class "LabelFrame"] } {
+ set textopt -text
+ set widthopt -width
+ } else {
+ upvar 0 Widget::${class}::map classmap
+ set textopt ""
+ set widthopt ""
+ set notdone 2
+ foreach {option lmap} [array get classmap] {
+ foreach {subpath subclass realopt} $lmap {
+ if { [string equal $subclass "LabelFrame"] } {
+ if { [string equal $realopt "-text"] } {
+ set textopt $option
+ incr notdone -1
+ break
+ }
+ if { [string equal $realopt "-width"] } {
+ set widthopt $option
+ incr notdone -1
+ break
+ }
+ }
+ }
+ if { !$notdone } {
+ break
+ }
+ }
+ if { $notdone } {
+ continue
+ }
+ }
+ set len [string length [$w cget $textopt]]
+ if { $len > $maxlen } {
+ set maxlen $len
+ }
+ lappend wlist $w $widthopt
+ }
+ }
+ incr maxlen
+ foreach {w widthopt} $wlist {
+ $w configure $widthopt $maxlen
+ }
+}
+
+
+proc LabelFrame::_destroy { path } {
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/lang/da.rc b/modules/tclsci/tcl/BWidget/lang/da.rc
new file mode 100755
index 000000000..09e9fdde5
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/da.rc
@@ -0,0 +1,52 @@
+! -----------------------------------------------------------------------------
+! da.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of Danish resources
+! -----------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons -----------------------------------------------
+
+*abortName: &Annullér
+*retryName: P&røv igen
+*ignoreName: &Ignorer
+*okName: &OK
+*cancelName: &Cancel
+*yesName: &Ja
+*noName: &Nej
+
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: Fed
+*italicName: Kursiv
+*underlineName: Understreg
+*overstrikeName: Overstreg
+*fontName: &Font
+*sizeName: &Størrelse
+*styleName: St&il
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: &Brugernavn
+*passwordName: &Password
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Font-valg
+*SelectFont.sampletext: Eksempeltekst æøå
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Besked
+*MessageDlg.infoTitle: Information
+*MessageDlg.questionTitle: Spørgsmål
+*MessageDlg.warningTitle: Advarsel
+*MessageDlg.errorTitle: Fejl
+
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Indtast brugernavn og password
diff --git a/modules/tclsci/tcl/BWidget/lang/de.rc b/modules/tclsci/tcl/BWidget/lang/de.rc
new file mode 100755
index 000000000..541e9eda7
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/de.rc
@@ -0,0 +1,52 @@
+! ------------------------------------------------------------------------------
+! de.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of german resources
+! ------------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+*abortName: &Abbrechen
+*retryName: &Wiederholen
+*ignoreName: &Ignorieren
+*okName: &OK
+*cancelName: &Abbrechen
+*yesName: &Ja
+*noName: &Nein
+
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: Fett
+*italicName: Kursiv
+*underlineName: Unterstrichen
+*overstrikeName: Durchgestrichen
+*fontName: &Schriftart
+*sizeName: S&chriftgrad
+*styleName: Sc&hriftschnitt
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: &Login
+*passwordName: &Password
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Schrift Auswahl
+*SelectFont.sampletext: Beispieltext
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Meldung
+*MessageDlg.infoTitle: Hinweis
+*MessageDlg.questionTitle: Frage
+*MessageDlg.warningTitle: Warnung
+*MessageDlg.errorTitle: Fehler
+
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Enter login and password
diff --git a/modules/tclsci/tcl/BWidget/lang/en.rc b/modules/tclsci/tcl/BWidget/lang/en.rc
new file mode 100755
index 000000000..760f07b82
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/en.rc
@@ -0,0 +1,52 @@
+! ------------------------------------------------------------------------------
+! en.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of english resources
+! ------------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+*abortName: &Abort
+*retryName: &Retry
+*ignoreName: &Ignore
+*okName: &OK
+*cancelName: &Cancel
+*yesName: &Yes
+*noName: &No
+
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: Bold
+*italicName: Italic
+*underlineName: Underline
+*overstrikeName: Overstrike
+*fontName: &Font
+*sizeName: &Size
+*styleName: St&yle
+
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: &Login
+*passwordName: &Password
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Font selection
+*SelectFont.sampletext: Sample text
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Message
+*MessageDlg.infoTitle: Information
+*MessageDlg.questionTitle: Question
+*MessageDlg.warningTitle: Warning
+*MessageDlg.errorTitle: Error
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Enter login and password
diff --git a/modules/tclsci/tcl/BWidget/lang/es.rc b/modules/tclsci/tcl/BWidget/lang/es.rc
new file mode 100755
index 000000000..65e589705
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/es.rc
@@ -0,0 +1,53 @@
+! ------------------------------------------------------------------------------
+! es.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of spanish resources
+! daniel@rawbyte.com
+! ------------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+*abortName: A&bortar
+*retryName: &Reintentar
+*ignoreName: &Ignorar
+*okName: &OK
+*cancelName: &Anular
+*yesName: &Sí
+*noName: &No
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: &Negrita
+*italicName: &Cursiva
+*underlineName: &Subrayado
+*overstrikeName: &Tachado
+*fontName: &Fuente
+*sizeName: &Tamaño
+*styleName: &Estilo
+
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: Nombre de &usuario
+*passwordName: &Contraseña
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Selección de fuente
+*SelectFont.sampletext: Texto de Ejemplo
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Indicación
+*MessageDlg.infoTitle: Información
+*MessageDlg.questionTitle: Pregunta
+*MessageDlg.warningTitle: Atención
+*MessageDlg.errorTitle: Error
+
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Introduzca su nombre de usuario y contraseña
+
diff --git a/modules/tclsci/tcl/BWidget/lang/fr.rc b/modules/tclsci/tcl/BWidget/lang/fr.rc
new file mode 100755
index 000000000..03edeb72a
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/fr.rc
@@ -0,0 +1,52 @@
+! ------------------------------------------------------------------------------
+! fr.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of french resources
+! ------------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+*abortName: A&bandonner
+*retryName: &Réessayer
+*ignoreName: &Ignorer
+*okName: &OK
+*cancelName: &Annuler
+*yesName: &Oui
+*noName: &Non
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: &Gras
+*italicName: &Italique
+*underlineName: &Souligné
+*overstrikeName: &Barré
+*fontName: &Police
+*sizeName: &Taille
+*styleName: St&yle
+
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: Nom de l'&utilisateur
+*passwordName: Mot de &passe
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Sélection d'une police
+*SelectFont.sampletext: Texte d'exemple
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Message
+*MessageDlg.infoTitle: Information
+*MessageDlg.questionTitle: Question
+*MessageDlg.warningTitle: Attention
+*MessageDlg.errorTitle: Erreur
+
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Entrez le login et le mot de passe
diff --git a/modules/tclsci/tcl/BWidget/lang/hu.rc b/modules/tclsci/tcl/BWidget/lang/hu.rc
new file mode 100755
index 000000000..806b6555b
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/hu.rc
@@ -0,0 +1,52 @@
+! ------------------------------------------------------------------------------
+! hu.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of english resources
+! ------------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+*abortName: &Megszakítás
+*retryName: Új&ra
+*ignoreName: &Kihagyás
+*okName: &OK
+*cancelName: Még&sem
+*yesName: &Igen
+*noName: &Nem
+
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: Félkövér
+*italicName: DÅ‘lt
+*underlineName: Aláhúzott
+*overstrikeName: Felülírás
+*fontName: &Betűtípus
+*sizeName: &Méret
+*styleName: S&tílus
+
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: &Felhasználónév
+*passwordName: &Jelszó
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Betűtípus kiválasztása
+*SelectFont.sampletext: Példaszöveg
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Ãœzenet
+*MessageDlg.infoTitle: Információ
+*MessageDlg.questionTitle: Kérdés
+*MessageDlg.warningTitle: Figyelmeztetés
+*MessageDlg.errorTitle: Hiba
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Add meg a felhasználónevet és a jelszót
diff --git a/modules/tclsci/tcl/BWidget/lang/nl.rc b/modules/tclsci/tcl/BWidget/lang/nl.rc
new file mode 100755
index 000000000..fc5a22581
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/nl.rc
@@ -0,0 +1,52 @@
+! ------------------------------------------------------------------------------
+! nl.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of Dutch resources
+! ------------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+*abortName: Af&breken
+*retryName: Opnie&uw proberen
+*ignoreName: N&egeren
+*okName: &OK
+*cancelName: &Annuleren
+*yesName: &Ja
+*noName: &Nee
+
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: Vet
+*italicName: Cursief
+*underlineName: Onderstrepen
+*overstrikeName: Doorhalen
+*fontName: &Lettertype
+*sizeName: &Grootte
+*styleName: &Stijl
+
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: &Inlognaam
+*passwordName: &Wachtwoord
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Lettertypeselectie
+*SelectFont.sampletext: Voorbeeldtekst
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Bericht
+*MessageDlg.infoTitle: Informatie
+*MessageDlg.questionTitle: Vraag
+*MessageDlg.warningTitle: Waarschuwing
+*MessageDlg.errorTitle: Fout
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Voer inlognaam en wachtwoord in
diff --git a/modules/tclsci/tcl/BWidget/lang/no.rc b/modules/tclsci/tcl/BWidget/lang/no.rc
new file mode 100755
index 000000000..8ba8558f6
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/no.rc
@@ -0,0 +1,52 @@
+! ------------------------------------------------------------------------------
+! no.rc
+! This file is part of Unifix BWidget Toolkit
+! Definition of norwegian resources
+! ------------------------------------------------------------------------------
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+*abortName: &Om
+*retryName: &Prøv igjen
+*ignoreName: &Ignore
+*okName: &OK
+*cancelName: &Avbryt
+*yesName: &Ja
+*noName: &Nei
+
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+*boldName: Halvfet
+*italicName: Kursiv
+*underlineName: Understreking
+*overstrikeName: Overstryke
+*fontName: &Skrift
+*sizeName: &Størrelse
+*styleName: St&il
+
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+*loginName: &Logg inn
+*passwordName: &Passord
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+*SelectFont.title: Skriftvalg
+*SelectFont.sampletext: Prøve tekst
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+*MessageDlg.noneTitle: Melding
+*MessageDlg.infoTitle: Informasjon
+*MessageDlg.questionTitle: Spørsmål
+*MessageDlg.warningTitle: Advarsel
+*MessageDlg.errorTitle: Feil
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+*PasswdDlg.title: Skriv inn logginn og passord
diff --git a/modules/tclsci/tcl/BWidget/lang/pl.rc b/modules/tclsci/tcl/BWidget/lang/pl.rc
new file mode 100755
index 000000000..887b0f9b1
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/lang/pl.rc
@@ -0,0 +1,104 @@
+! ------------------------------------------------------------------------------
+
+! pl.rc
+
+! This file is part of Unifix BWidget Toolkit
+
+! Definition of english resources
+
+! ------------------------------------------------------------------------------
+
+
+
+
+
+! --- symbolic names of buttons ------------------------------------------------
+
+
+
+*abortName: &Porzuć
+
+*retryName: P&onów
+
+*ignoreName: &Ignoruj
+
+*okName: &OK
+
+*cancelName: &Anyluj
+
+*yesName: &Tak
+
+*noName: &Nie
+
+
+
+
+
+! --- symbolic names of label of SelectFont dialog ----------------------------
+
+
+
+*boldName: Pogrubiona
+
+*italicName: Kursywa
+
+*underlineName: Podkreślenie
+
+*overstrikeName: Przekreślenie
+
+*fontName: &Czcionka:
+
+*sizeName: &Rozmiar:
+
+*styleName: St&yl czcionki:
+
+
+
+
+
+! --- symbolic names of label of PasswdDlg dialog -----------------------------
+
+
+
+*loginName: &Login
+
+*passwordName: &Hasło
+
+
+
+
+
+! --- resource for SelectFont dialog ------------------------------------------
+
+
+
+*SelectFont.title: Wybór czcionki
+
+*SelectFont.sampletext: Przykładowy tekst
+
+
+
+
+
+! --- resource for MessageDlg dialog ------------------------------------------
+
+
+
+*MessageDlg.noneTitle: Wiadomość
+
+*MessageDlg.infoTitle: Informacja
+
+*MessageDlg.questionTitle: Pytanie
+
+*MessageDlg.warningTitle: Ostrzeżenie
+
+*MessageDlg.errorTitle: BÅ‚Ä…d
+
+
+
+! --- resource for PasswdDlg dialog -------------------------------------------
+
+
+
+*PasswdDlg.title: Wpisz login i hasło
+
diff --git a/modules/tclsci/tcl/BWidget/listbox.tcl b/modules/tclsci/tcl/BWidget/listbox.tcl
new file mode 100755
index 000000000..2e454095d
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/listbox.tcl
@@ -0,0 +1,1726 @@
+# ----------------------------------------------------------------------------
+# listbox.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: listbox.tcl,v 1.29.2.3 2010/05/12 08:12:34 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - ListBox::create
+# - ListBox::configure
+# - ListBox::cget
+# - ListBox::insert
+# - ListBox::itemconfigure
+# - ListBox::itemcget
+# - ListBox::bindText
+# - ListBox::bindImage
+# - ListBox::delete
+# - ListBox::move
+# - ListBox::reorder
+# - ListBox::selection
+# - ListBox::exists
+# - ListBox::index
+# - ListBox::item - deprecated
+# - ListBox::items
+# - ListBox::see
+# - ListBox::edit
+# - ListBox::xview
+# - ListBox::yview
+# - ListBox::_update_edit_size
+# - ListBox::_destroy
+# - ListBox::_see
+# - ListBox::_update_scrollregion
+# - ListBox::_draw_item
+# - ListBox::_redraw_items
+# - ListBox::_redraw_selection
+# - ListBox::_redraw_listbox
+# - ListBox::_redraw_idle
+# - ListBox::_resize
+# - ListBox::_init_drag_cmd
+# - ListBox::_drop_cmd
+# - ListBox::_over_cmd
+# - ListBox::_auto_scroll
+# - ListBox::_scroll
+# ----------------------------------------------------------------------------
+
+namespace eval ListBox {
+ Widget::define ListBox listbox DragSite DropSite DynamicHelp
+
+ namespace eval Item {
+ Widget::declare ListBox::Item {
+ {-indent Int 0 0 "%d >= 0"}
+ {-text String "" 0}
+ {-font String "" 0}
+ {-foreground String "" 0}
+ {-image TkResource "" 0 label}
+ {-window String "" 0}
+ {-data String "" 0}
+
+ {-fill Synonym -foreground}
+ {-fg Synonym -foreground}
+ }
+ }
+
+ DynamicHelp::include ListBox::Item balloon
+
+ Widget::tkinclude ListBox canvas .c \
+ remove {
+ -insertwidth -insertbackground -insertborderwidth -insertofftime
+ -insertontime -selectborderwidth -closeenough -confine -scrollregion
+ -xscrollincrement -yscrollincrement -width -height
+ } \
+ initialize {
+ -relief sunken -borderwidth 2 -takefocus 1
+ -highlightthickness 1 -width 200
+ }
+
+ DragSite::include ListBox "LISTBOX_ITEM" 1
+ DropSite::include ListBox {
+ LISTBOX_ITEM {copy {} move {}}
+ }
+
+ Widget::declare ListBox {
+ {-deltax Int 10 0 "%d >= 0"}
+ {-deltay Int 15 0 "%d >= 0"}
+ {-padx Int 20 0 "%d >= 0"}
+ {-foreground TkResource "" 0 listbox}
+ {-background TkResource "" 0 listbox}
+ {-selectbackground TkResource "" 0 listbox}
+ {-selectforeground TkResource "" 0 listbox}
+ {-font TkResource "" 0 listbox}
+ {-width TkResource "" 0 listbox}
+ {-height TkResource "" 0 listbox}
+ {-redraw Boolean 1 0}
+ {-multicolumn Boolean 0 0}
+ {-dropovermode Flag "wpi" 0 "wpi"}
+ {-selectmode Enum none 0 {none single multiple}}
+ {-fg Synonym -foreground}
+ {-bg Synonym -background}
+ {-dropcmd String "ListBox::_drag_and_drop" 0}
+ {-autofocus Boolean 1 1}
+ {-selectfill Boolean 0 1}
+ }
+
+ Widget::addmap ListBox "" .c {-deltay -yscrollincrement}
+
+ bind ListBox <FocusIn> [list after idle {BWidget::refocus %W %W.c}]
+ bind ListBox <Destroy> [list ListBox::_destroy %W]
+ bind ListBox <Configure> [list ListBox::_resize %W]
+ bind ListBoxFocus <1> [list focus %W]
+ bind ListBox <Key-Up> [list ListBox::_keyboard_navigation %W -1]
+ bind ListBox <Key-Down> [list ListBox::_keyboard_navigation %W 1]
+
+ variable _edit
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::create
+# ----------------------------------------------------------------------------
+proc ListBox::create { path args } {
+ Widget::init ListBox $path $args
+
+ variable $path
+ upvar 0 $path data
+
+ frame $path -class ListBox -bd 0 -highlightthickness 0 -relief flat \
+ -takefocus 0
+ # For 8.4+ we don't want to inherit the padding
+ catch {$path configure -padx 0 -pady 0}
+ # widget informations
+ set data(nrows) -1
+
+ # items informations
+ set data(items) {}
+ set data(selitems) {}
+
+ # update informations
+ set data(upd,level) 0
+ set data(upd,afterid) ""
+ set data(upd,level) 0
+ set data(upd,delete) {}
+
+ # drag and drop informations
+ set data(dnd,scroll) ""
+ set data(dnd,afterid) ""
+ set data(dnd,item) ""
+
+ eval [list canvas $path.c] [Widget::subcget $path .c] \
+ [list -xscrollincrement 8]
+ pack $path.c -expand yes -fill both
+
+ DragSite::setdrag $path $path.c ListBox::_init_drag_cmd \
+ [Widget::cget $path -dragendcmd] 1
+ DropSite::setdrop $path $path.c ListBox::_over_cmd ListBox::_drop_cmd 1
+
+ Widget::create ListBox $path
+
+ set w [Widget::cget $path -width]
+ set h [Widget::cget $path -height]
+ set dy [Widget::cget $path -deltay]
+ $path.c configure -width [expr {$w*8}] -height [expr {$h*$dy}]
+
+ # Insert $path into the canvas bindings, so that anyone binding
+ # directly onto the widget will see their bindings activated when
+ # the canvas has focus.
+ set bindtags [bindtags $path.c]
+ set bindtags [linsert $bindtags 1 $path]
+ # Let any click within the canvas focus on the canvas so that
+ # MouseWheel scroll events will be properly handled by the canvas.
+ if {[Widget::cget $path -autofocus]} {
+ lappend bindtags ListBoxFocus
+ BWidget::bindMouseWheel $path.c
+ }
+ bindtags $path.c $bindtags
+
+ # Add slightly modified up/down bindings to the canvas, in case
+ # it gets the focus (like with -autofocus).
+ bind $path.c <Key-Up> {ListBox::_keyboard_navigation [winfo parent %W] -1}
+ bind $path.c <Key-Down> {ListBox::_keyboard_navigation [winfo parent %W] 1}
+
+ _configureSelectmode $path [Widget::getoption $path -selectmode]
+
+ return $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_configureSelectmode
+# ----------------------------------------------------------------------------
+# Configure the selectmode
+proc ListBox::_configureSelectmode { path selectmode {previous none} } {
+ # clear current binding
+ switch -exact -- $previous {
+ single {
+ $path _bindText <Button-1> ""
+ $path _bindImage <Button-1> ""
+ }
+ multiple {
+ $path _bindText <ButtonRelease-1> ""
+ $path _bindText <Shift-ButtonRelease-1> ""
+ $path _bindText <Control-ButtonRelease-1> ""
+
+ $path _bindImage <ButtonRelease-1> ""
+ $path _bindImage <Shift-ButtonRelease-1> ""
+ $path _bindImage <Control-ButtonRelease-1> ""
+ }
+ }
+ # set new bindings
+ switch -exact -- $selectmode {
+ single {
+ $path _bindText <Button-1> [list ListBox::_mouse_select $path set]
+ $path _bindImage <Button-1> [list ListBox::_mouse_select $path set]
+ if {1 < [llength [ListBox::selection $path get]]} {
+ ListBox::selection $path clear
+ }
+ }
+ multiple {
+ set cmd ListBox::_multiple_select
+ $path _bindText <ButtonRelease-1> [list $cmd $path n %x %y]
+ $path _bindText <Shift-ButtonRelease-1> [list $cmd $path s %x %y]
+ $path _bindText <Control-ButtonRelease-1> [list $cmd $path c %x %y]
+
+ $path _bindImage <ButtonRelease-1> [list $cmd $path n %x %y]
+ $path _bindImage <Shift-ButtonRelease-1> [list $cmd $path s %x %y]
+ $path _bindImage <Control-ButtonRelease-1> [list $cmd $path c %x %y]
+ }
+ default {
+ if {0 < [llength [ListBox::selection $path get]]} {
+ ListBox::selection $path clear
+ }
+ }
+ }
+}
+# ----------------------------------------------------------------------------
+# Command ListBox::configure
+# ----------------------------------------------------------------------------
+proc ListBox::configure { path args } {
+ set selectmodePrevious [Widget::getoption $path -selectmode]
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -selectmode selectmode] } {
+ _configureSelectmode $path $selectmode $selectmodePrevious
+ }
+
+ set ch1 [expr {[Widget::hasChanged $path -deltay dy] |
+ [Widget::hasChanged $path -padx val] |
+ [Widget::hasChanged $path -multicolumn val]}]
+
+ set ch2 [expr {[Widget::hasChanged $path -selectbackground val] |
+ [Widget::hasChanged $path -selectforeground val]}]
+
+ set redraw 0
+ if { [Widget::hasChanged $path -height h] } {
+ $path.c configure -height [expr {$h*$dy}]
+ set redraw 1
+ }
+ if { [Widget::hasChanged $path -width w] } {
+ $path.c configure -width [expr {$w*8}]
+ set redraw 1
+ }
+
+ if { [Widget::hasChanged $path -background bg] } {
+ $path.c itemconfigure box -fill $bg
+ }
+
+ if { !$redraw } {
+ if { $ch1 } {
+ _redraw_idle $path 2
+ } elseif { $ch2 } {
+ _redraw_idle $path 1
+ }
+ }
+
+ if { [Widget::hasChanged $path -redraw bool] && $bool } {
+ variable $path
+ upvar 0 $path data
+ set lvl $data(upd,level)
+ set data(upd,level) 0
+ _redraw_idle $path $lvl
+ }
+ set force [Widget::hasChanged $path -dragendcmd dragend]
+ DragSite::setdrag $path $path.c ListBox::_init_drag_cmd $dragend $force
+ DropSite::setdrop $path $path.c ListBox::_over_cmd ListBox::_drop_cmd
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::cget
+# ----------------------------------------------------------------------------
+proc ListBox::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::insert
+# ----------------------------------------------------------------------------
+proc ListBox::insert { path index item args } {
+ variable $path
+ upvar 0 $path data
+
+ set item [Widget::nextIndex $path $item]
+
+ if {[info exists data(exists,$item)]} {
+ return -code error "item \"$item\" already exists"
+ }
+
+ Widget::init ListBox::Item $path.$item $args
+
+ set data(items) [linsert $data(items) $index $item]
+ set data(exists,$item) 1
+ set data(upd,create,$item) $item
+
+ _redraw_idle $path 2
+ return $item
+}
+
+# Bastien Chevreux (bach@mwgdna.com)
+# The multipleinsert command performs inserts several items at once into
+# the list. It is faster than calling insert multiple times as it uses the
+# Widget::copyinit command for initializing all items after the 1st. The
+# speedup factor is between 2 and 3 for typical usage, but could be higher
+# for inserts with many options.
+#
+# Syntax: path and index are as in the insert command
+# args is a list of even numbered elements where the 1st of each pair
+# corresponds to the item of 'insert' and the second to args of 'insert'.
+# ----------------------------------------------------------------------------
+# Command ListBox::multipleinsert
+# ----------------------------------------------------------------------------
+proc ListBox::multipleinsert { path index args } {
+ variable $path
+ upvar 0 $path data
+
+ # If we got only one list as arg, take the first element as args
+ # This enables callers to use
+ # $list multipleinsert index $thelist
+ # instead of
+ # eval $list multipleinsert index $thelist
+
+ if {[llength $args] == 1} {
+ set args [lindex $args 0]
+ }
+
+ set count 0
+ foreach {item iargs} $args {
+ if {[info exists data(exists,$item)]} {
+ return -code error "item \"$item\" already exists"
+ }
+
+ if {$count==0} {
+ Widget::init ListBox::Item $path.$item $iargs
+ set firstpath $path.$item
+ } else {
+ Widget::copyinit ListBox::Item $firstpath $path.$item $iargs
+ }
+
+ set data(items) [linsert $data(items) $index $item]
+ set data(exists,$item) 1
+ set data(upd,create,$item) $item
+
+ incr count
+ }
+
+ _redraw_idle $path 2
+ return $item
+}
+
+# ----------------------------------------------------------------------------
+# Command ListBox::itemconfigure
+# ----------------------------------------------------------------------------
+proc ListBox::itemconfigure { path item args } {
+ variable $path
+ upvar 0 $path data
+
+ if { [lsearch -exact $data(items) $item] == -1 } {
+ return -code error "item \"$item\" does not exist"
+ }
+
+ set oldind [Widget::getoption $path.$item -indent]
+
+ set res [Widget::configure $path.$item $args]
+ set chind [Widget::hasChanged $path.$item -indent indent]
+ set chw [Widget::hasChanged $path.$item -window win]
+ set chi [Widget::hasChanged $path.$item -image img]
+ set cht [Widget::hasChanged $path.$item -text txt]
+ set chf [Widget::hasChanged $path.$item -font fnt]
+ set chfg [Widget::hasChanged $path.$item -foreground fg]
+ set idn [$path.c find withtag n:$item]
+
+ _set_help $path $item
+
+ if { $idn == "" } {
+ # item is not drawn yet
+ _redraw_idle $path 2
+ return $res
+ }
+
+ set oldb [$path.c bbox $idn]
+ set coords [$path.c coords $idn]
+ set padx [Widget::getoption $path -padx]
+ set x0 [expr {[lindex $coords 0]-$padx-$oldind+$indent}]
+ set y0 [lindex $coords 1]
+ if { $chw || $chi } {
+ # -window or -image modified
+ set idi [$path.c find withtag i:$item]
+ set type [lindex [$path.c gettags $idi] 0]
+ if { [string length $win] } {
+ if { [string equal $type "win"] } {
+ $path.c itemconfigure $idi -window $win
+ } else {
+ $path.c delete $idi
+ $path.c create window $x0 $y0 -window $win -anchor w \
+ -tags [list win i:$item]
+ }
+ } elseif { [string length $img] } {
+ if { [string equal $type "img"] } {
+ $path.c itemconfigure $idi -image $img
+ } else {
+ $path.c delete $idi
+ $path.c create image $x0 $y0 -image $img -anchor w \
+ -tags [list img imgbind i:$item]
+ }
+ } else {
+ $path.c delete $idi
+ }
+ }
+
+ if { $cht || $chf || $chfg } {
+ # -text or -font modified, or -foreground modified
+ set fnt [_getoption $path $item -font]
+ set fg [_getoption $path $item -foreground]
+ $path.c itemconfigure $idn -text $txt -font $fnt -fill $fg
+ _redraw_idle $path 1
+ }
+
+ if { $chind } {
+ # -indent modified
+ $path.c coords $idn [expr {$x0+$padx}] $y0
+ $path.c coords i:$item $x0 $y0
+ _redraw_idle $path 1
+ }
+
+ if { [Widget::getoption $path -multicolumn] && ($cht || $chf || $chind) } {
+ set bbox [$path.c bbox $idn]
+ if { [lindex $bbox 2] > [lindex $oldb 2] } {
+ _redraw_idle $path 2
+ }
+ }
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::itemcget
+# ----------------------------------------------------------------------------
+proc ListBox::itemcget { path item option } {
+ return [Widget::cget $path.$item $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_bindText
+# ----------------------------------------------------------------------------
+proc ListBox::_bindText { path event script {tag click} } {
+ if { $script != "" } {
+ set map [list %W $path]
+ set script [string map $map $script]
+ append script " \[ListBox::_get_current [list $path]\]"
+ }
+ $path.c bind $tag $event $script
+}
+
+# ----------------------------------------------------------------------------
+# Command ListBox::bindText
+# ----------------------------------------------------------------------------
+proc ListBox::bindText { path event script } {
+ _bindText $path $event $script clickbind
+}
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_bindImage
+# ----------------------------------------------------------------------------
+proc ListBox::_bindImage { path event script {tag img} } {
+ if { $script != "" } {
+ set map [list %W $path]
+ set script [string map $map $script]
+ append script " \[ListBox::_get_current [list $path]\]"
+ }
+ $path.c bind $tag $event $script
+}
+
+# ----------------------------------------------------------------------------
+# Command ListBox::bindImage
+# ----------------------------------------------------------------------------
+proc ListBox::bindImage { path event script } {
+ _bindImage $path $event $script imgbind
+}
+
+# ----------------------------------------------------------------------------
+# Command ListBox::delete
+# ----------------------------------------------------------------------------
+proc ListBox::delete { path args } {
+ variable $path
+ upvar 0 $path data
+ Widget::getVariable $path help
+
+ foreach litems $args {
+ foreach item $litems {
+ set idx [lsearch -exact $data(items) $item]
+ if { $idx != -1 } {
+ set data(items) [lreplace $data(items) $idx $idx]
+ array unset help $item
+ Widget::destroy $path.$item
+ if { [info exists data(exists,$item)] } {
+ unset data(exists,$item)
+ }
+ if { [info exists data(upd,create,$item)] } {
+ unset data(upd,create,$item)
+ } else {
+ lappend data(upd,delete) $item
+ }
+ }
+ }
+ }
+
+ set sel $data(selitems)
+ set data(selitems) {}
+ eval [list selection $path set] $sel
+ _redraw_idle $path 2
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::move
+# ----------------------------------------------------------------------------
+proc ListBox::move { path item index } {
+ variable $path
+ upvar 0 $path data
+
+ if { [set idx [lsearch -exact $data(items) $item]] == -1 } {
+ return -code error "item \"$item\" does not exist"
+ }
+
+ set data(items) [linsert [lreplace $data(items) $idx $idx] $index $item]
+
+ _redraw_idle $path 2
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::reorder
+# ----------------------------------------------------------------------------
+proc ListBox::reorder { path neworder } {
+ variable $path
+ upvar 0 $path data
+
+ set data(items) [BWidget::lreorder $data(items) $neworder]
+ _redraw_idle $path 2
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::selection
+# ----------------------------------------------------------------------------
+proc ListBox::selection { path cmd args } {
+ variable $path
+ upvar 0 $path data
+
+ switch -- $cmd {
+ set {
+ set data(selitems) {}
+ foreach item $args {
+ if { [lsearch -exact $data(selitems) $item] == -1 } {
+ if { [lsearch -exact $data(items) $item] != -1 } {
+ lappend data(selitems) $item
+ }
+ }
+ }
+ }
+ add {
+ foreach item $args {
+ if { [lsearch -exact $data(selitems) $item] == -1 } {
+ if { [lsearch -exact $data(items) $item] != -1 } {
+ lappend data(selitems) $item
+ }
+ }
+ }
+ }
+ remove {
+ foreach item $args {
+ if { [set idx [lsearch -exact $data(selitems) $item]] != -1 } {
+ set data(selitems) [lreplace $data(selitems) $idx $idx]
+ }
+ }
+ }
+ clear {
+ set data(selitems) {}
+ }
+ get {
+ return $data(selitems)
+ }
+ includes {
+ return [expr {[lsearch -exact $data(selitems) $args] != -1}]
+ }
+ default {
+ return
+ }
+ }
+
+ _redraw_idle $path 1
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::exists
+# ----------------------------------------------------------------------------
+proc ListBox::exists { path item } {
+ variable $path
+ upvar 0 $path data
+
+ return [expr {[lsearch -exact $data(items) $item] != -1}]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::index
+# ----------------------------------------------------------------------------
+proc ListBox::index { path item } {
+ variable $path
+ upvar 0 $path data
+ if {[string equal $item "active"]} { return [$path selection get] }
+ return [lsearch -exact $data(items) $item]
+}
+
+
+# ----------------------------------------------------------------------------
+# ListBox::find
+# Returns the item given a position.
+# findInfo @x,y ?confine?
+# lineNumber
+# ----------------------------------------------------------------------------
+proc ListBox::find {path findInfo {confine ""}} {
+ variable $path
+ upvar 0 $path widgetData
+
+ if {[regexp -- {^@([0-9]+),([0-9]+)$} $findInfo match x y]} {
+ set x [$path.c canvasx $x]
+ set y [$path.c canvasy $y]
+ } elseif {[regexp -- {^[0-9]+$} $findInfo lineNumber]} {
+ set dy [Widget::getoption $path -deltay]
+ set y [expr {$dy*($lineNumber+0.5)}]
+ set confine ""
+ } else {
+ return -code error "invalid find spec \"$findInfo\""
+ }
+
+ set found 0
+ set xi 0
+ foreach xs $widgetData(xlist) {
+ if {$x <= $xs} {
+ foreach id [$path.c find overlapping $xi $y $xs $y] {
+ set ltags [$path.c gettags $id]
+ set item [lindex $ltags 0]
+ if { [string equal $item "item"] ||
+ [string equal $item "img"] ||
+ [string equal $item "win"] } {
+ # item is the label or image/window of the node
+ set item [string range [lindex $ltags 1] 2 end]
+ set found 1
+ break
+ }
+ }
+ break
+ }
+ set xi $xs
+ }
+
+ if {$found} {
+ if {[string equal $confine "confine"]} {
+ # test if x stand inside node bbox
+ set xi [expr {[lindex [$path.c coords n:$item] 0]-[Widget::getoption $path -padx]}]
+ set xs [lindex [$path.c bbox n:$item] 2]
+ if {$x >= $xi && $x <= $xs} {
+ return $item
+ }
+ } else {
+ return $item
+ }
+ }
+ return ""
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::item - deprecated
+# ----------------------------------------------------------------------------
+proc ListBox::item { path first {last ""} } {
+ variable $path
+ upvar 0 $path data
+
+ if { ![string length $last] } {
+ return [lindex $data(items) $first]
+ } else {
+ return [lrange $data(items) $first $last]
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::items
+# ----------------------------------------------------------------------------
+proc ListBox::items { path {first ""} {last ""}} {
+ variable $path
+ upvar 0 $path data
+
+ if { ![string length $first] } {
+ return $data(items)
+ }
+
+ if { ![string length $last] } {
+ return [lindex $data(items) $first]
+ } else {
+ return [lrange $data(items) $first $last]
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::see
+# ----------------------------------------------------------------------------
+proc ListBox::see { path item } {
+ variable $path
+ upvar 0 $path data
+
+ if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
+ after cancel $data(upd,afterid)
+ _redraw_listbox $path
+ }
+ set idn [$path.c find withtag n:$item]
+ if { $idn != "" } {
+ set idi [$path.c find withtag i:$item]
+ if { $idi == "" } { set idi $idn }
+ ListBox::_see $path $idn right
+ ListBox::_see $path $idi left
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::edit
+# ----------------------------------------------------------------------------
+proc ListBox::edit { path item text {verifycmd ""} {clickres 0} {select 1}} {
+ variable _edit
+ variable $path
+ upvar 0 $path data
+
+ if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
+ after cancel $data(upd,afterid)
+ _redraw_listbox $path
+ }
+ set idn [$path.c find withtag n:$item]
+ if { $idn != "" } {
+ ListBox::_see $path $idn right
+ ListBox::_see $path $idn left
+
+ set oldfg [$path.c itemcget $idn -fill]
+ set sbg [Widget::getoption $path -selectbackground]
+ set coords [$path.c coords $idn]
+ set x [lindex $coords 0]
+ set y [lindex $coords 1]
+ set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}]
+ set w [expr {[winfo width $path] - 2*$bd}]
+ set wmax [expr {[$path.c canvasx $w]-$x}]
+
+ $path.c itemconfigure $idn -fill [Widget::getoption $path -background]
+ $path.c itemconfigure s:$item -fill {} -outline {}
+
+ set _edit(text) $text
+ set _edit(wait) 0
+
+ set frame [frame $path.edit \
+ -relief flat -borderwidth 0 -highlightthickness 0 \
+ -background [Widget::getoption $path -background]]
+ set ent [entry $frame.edit \
+ -width 0 \
+ -relief solid \
+ -borderwidth 1 \
+ -highlightthickness 0 \
+ -foreground [_getoption $path $item -foreground] \
+ -background [Widget::getoption $path -background] \
+ -selectforeground [Widget::getoption $path -selectforeground] \
+ -selectbackground $sbg \
+ -font [_getoption $path $item -font] \
+ -textvariable ListBox::_edit(text)]
+ pack $ent -ipadx 8 -anchor w
+
+ set idw [$path.c create window $x $y -window $frame -anchor w]
+ trace variable ListBox::_edit(text) w [list ListBox::_update_edit_size $path $ent $idw $wmax]
+ tkwait visibility $ent
+ grab $frame
+ BWidget::focus set $ent
+ _update_edit_size $path $ent $idw $wmax
+ update
+ if { $select } {
+ $ent selection range 0 end
+ $ent icursor end
+ $ent xview end
+ }
+
+ bindtags $ent [list $ent Entry]
+ bind $ent <Escape> {set ListBox::_edit(wait) 0}
+ bind $ent <Return> {set ListBox::_edit(wait) 1}
+ if { $clickres == 0 || $clickres == 1 } {
+ bind $frame <Button> [list set ListBox::_edit(wait) $clickres]
+ }
+
+ set ok 0
+ while { !$ok } {
+ tkwait variable ListBox::_edit(wait)
+ if { !$_edit(wait) || [llength $verifycmd]==0 ||
+ [uplevel \#0 $verifycmd [list $_edit(text)]] } {
+ set ok 1
+ }
+ }
+ trace vdelete ListBox::_edit(text) w [list ListBox::_update_edit_size $path $ent $idw $wmax]
+ grab release $frame
+ BWidget::focus release $ent
+ destroy $frame
+ $path.c delete $idw
+ $path.c itemconfigure $idn -fill $oldfg
+ $path.c itemconfigure s:$item -fill $sbg -outline $sbg
+
+ if { $_edit(wait) } {
+ return $_edit(text)
+ }
+ }
+ return ""
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::xview
+# ----------------------------------------------------------------------------
+proc ListBox::xview { path args } {
+ return [eval [linsert $args 0 $path.c xview]]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::yview
+# ----------------------------------------------------------------------------
+proc ListBox::yview { path args } {
+ return [eval [linsert $args 0 $path.c yview]]
+}
+
+
+proc ListBox::getcanvas { path } {
+ return $path.c
+}
+
+
+proc ListBox::curselection { path } {
+ return [$path selection get]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_update_edit_size
+# ----------------------------------------------------------------------------
+proc ListBox::_update_edit_size { path entry idw wmax args } {
+ set entw [winfo reqwidth $entry]
+ if { $entw >= $wmax } {
+ $path.c itemconfigure $idw -width $wmax
+ } else {
+ $path.c itemconfigure $idw -width 0
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_getoption
+# Returns the value of option for node. If empty, returned value is those
+# of the ListBox.
+# ----------------------------------------------------------------------------
+proc ListBox::_getoption { path item option } {
+ set value [Widget::getoption $path.$item $option]
+ if {![string length $value]} {
+ set value [Widget::getoption $path $option]
+ }
+ return $value
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_destroy
+# ----------------------------------------------------------------------------
+proc ListBox::_destroy { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { $data(upd,afterid) != "" } {
+ after cancel $data(upd,afterid)
+ }
+ if { $data(dnd,afterid) != "" } {
+ after cancel $data(dnd,afterid)
+ }
+ foreach item $data(items) {
+ Widget::destroy $path.$item
+ }
+
+ Widget::destroy $path
+ unset data
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_see
+# ----------------------------------------------------------------------------
+proc ListBox::_see { path idn side } {
+ set bbox [$path.c bbox $idn]
+ set scrl [$path.c cget -scrollregion]
+
+ set ymax [lindex $scrl 3]
+ set dy [$path.c cget -yscrollincrement]
+ set yv [$path.c yview]
+ set yv0 [expr {round([lindex $yv 0]*$ymax/$dy)}]
+ set yv1 [expr {round([lindex $yv 1]*$ymax/$dy)}]
+ set y [expr {int([lindex [$path.c coords $idn] 1]/$dy)}]
+ if { $y < $yv0 } {
+ $path.c yview scroll [expr {$y-$yv0}] units
+ } elseif { $y >= $yv1 } {
+ $path.c yview scroll [expr {$y-$yv1+1}] units
+ }
+
+ set xmax [lindex $scrl 2]
+ set dx [$path.c cget -xscrollincrement]
+ set xv [$path.c xview]
+ if { [string equal $side "right"] } {
+ set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}]
+ set x1 [expr {int([lindex $bbox 2]/$dx)}]
+ if { $x1 >= $xv1 } {
+ $path.c xview scroll [expr {$x1-$xv1+1}] units
+ }
+ } else {
+ set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}]
+ set x0 [expr {int([lindex $bbox 0]/$dx)}]
+ if { $x0 < $xv0 } {
+ $path.c xview scroll [expr {$x0-$xv0}] units
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_update_scrollregion
+# ----------------------------------------------------------------------------
+proc ListBox::_update_scrollregion { path } {
+ set bd [$path.c cget -borderwidth]
+ set ht [$path.c cget -highlightthickness]
+ set bd [expr {2*($bd + $ht)}]
+ set w [expr {[winfo width $path] - $bd}]
+ set h [expr {[winfo height $path] - $bd}]
+ set xinc [$path.c cget -xscrollincrement]
+ set yinc [$path.c cget -yscrollincrement]
+ set bbox [$path.c bbox item win img]
+ if { [llength $bbox] } {
+ set xs [lindex $bbox 2]
+ set ys [lindex $bbox 3]
+
+ if { $w < $xs } {
+ set w [expr {int($xs)}]
+ if { [set r [expr {$w % $xinc}]] } {
+ set w [expr {$w+$xinc-$r}]
+ }
+ }
+ if { $h < $ys } {
+ set h [expr {int($ys)}]
+ if { [set r [expr {$h % $yinc}]] } {
+ set h [expr {$h+$yinc-$r}]
+ }
+ }
+ }
+
+ $path.c configure -scrollregion [list 0 0 $w $h]
+}
+
+
+proc ListBox::_update_select_fill { path } {
+ variable $path
+ upvar 0 $path data
+
+ set width [winfo width $path]
+
+ foreach item $data(items) {
+ set bbox [$path.c bbox n:$item]
+ set bbox [list 0 [lindex $bbox 1] $width [lindex $bbox 3]]
+ $path.c coords b:$item $bbox
+ }
+
+ _redraw_selection $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_draw_item
+# ----------------------------------------------------------------------------
+proc ListBox::_draw_item {path item x0 x1 y bg selfill multi ww} {
+ set indent [Widget::getoption $path.$item -indent]
+ set i [$path.c create text [expr {$x1+$indent}] $y \
+ -text [Widget::getoption $path.$item -text] \
+ -fill [_getoption $path $item -foreground] \
+ -font [_getoption $path $item -font] \
+ -anchor w \
+ -tags [list item n:$item click clickbind]]
+
+ if { $selfill && !$multi } {
+ set bbox [$path.c bbox n:$item]
+ set bbox [list 0 [lindex $bbox 1] $ww [lindex $bbox 3]]
+ set tags [list box b:$item click clickbind]
+ $path.c create rect $bbox -fill $bg -width 0 -tags $tags
+ $path.c raise $i
+ }
+
+ if { [set win [Widget::getoption $path.$item -window]] != "" } {
+ $path.c create window [expr {$x0+$indent}] $y \
+ -window $win -anchor w -tags [list win i:$item]
+ } elseif { [set img [Widget::getoption $path.$item -image]] != "" } {
+ $path.c create image [expr {$x0+$indent}] $y \
+ -image $img -anchor w -tags [list img imgbind i:$item]
+ }
+
+ _set_help $path $item
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_redraw_items
+# ----------------------------------------------------------------------------
+proc ListBox::_redraw_items { path } {
+ variable $path
+ upvar 0 $path data
+
+ set cursor [$path.c cget -cursor]
+ $path.c configure -cursor watch
+ update idletasks ; # make sure watch cursor is reflected
+ set dx [Widget::getoption $path -deltax]
+ set dy [Widget::getoption $path -deltay]
+ set padx [Widget::getoption $path -padx]
+ set y0 [expr {$dy/2}]
+ set x0 4
+ set x1 [expr {$x0+$padx}]
+ set nitem 0
+ set width 0
+ set drawn {}
+ set data(xlist) {}
+ if { [Widget::cget $path -multicolumn] } {
+ set nrows $data(nrows)
+ } else {
+ set nrows [llength $data(items)]
+ }
+ foreach item $data(upd,delete) {
+ $path.c delete i:$item n:$item s:$item b:$item
+ }
+ # Pass these to _draw_item so it doesn't have to request them
+ # for each item.
+ set bg [Widget::cget $path -background]
+ set selfill [Widget::cget $path -selectfill]
+ set multi [Widget::cget $path -multicolumn]
+ set ww [winfo width $path]
+ foreach item $data(items) {
+ if { [info exists data(upd,create,$item)] } {
+ _draw_item $path $item $x0 $x1 $y0 $bg $selfill $multi $ww
+ unset data(upd,create,$item)
+ } else {
+ set indent [Widget::getoption $path.$item -indent]
+ $path.c coords n:$item [expr {$x1+$indent}] $y0
+ $path.c coords i:$item [expr {$x0+$indent}] $y0
+ }
+ set font [_getoption $path $item -font]
+ set text [Widget::getoption $path.$item -text]
+ set tw [font measure $font $text]
+ if {$tw > $width} { set width $tw }
+ incr y0 $dy
+ incr nitem
+ lappend drawn n:$item
+ if { $nitem == $nrows } {
+ set x2 [expr {$x1 + $width}]
+ set y0 [expr {$dy/2}]
+ set drawn {}
+ set x0 [expr {$x2+$dx}]
+ set x1 [expr {$x0+$padx}]
+ set nitem 0
+ lappend data(xlist) $x2
+ set width 0
+ }
+ }
+ if { $nitem && $nitem < $nrows } {
+ lappend data(xlist) [expr {$x1 + $width}]
+ }
+ set data(upd,delete) {}
+ $path.c configure -cursor $cursor
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_redraw_selection
+# ----------------------------------------------------------------------------
+proc ListBox::_redraw_selection { path } {
+ variable $path
+ upvar 0 $path data
+
+ set selbg [Widget::getoption $path -selectbackground]
+ set selfg [Widget::getoption $path -selectforeground]
+ set selfill [Widget::getoption $path -selectfill]
+ set multi [Widget::getoption $path -multicolumn]
+ foreach id [$path.c find withtag sel] {
+ set item [string range [lindex [$path.c gettags $id] 1] 2 end]
+ if {-1 == [lsearch -exact $data(upd,delete) $item]} {
+ $path.c itemconfigure "n:$item" \
+ -fill [_getoption $path $item -foreground]
+ }
+ }
+ $path.c delete sel
+ if {$selfill && !$multi} {
+ # cache window width for use below
+ set width [winfo width $path]
+ }
+ foreach item $data(selitems) {
+ set bbox [$path.c bbox "n:$item"]
+ if { [llength $bbox] } {
+ if { $selfill && !$multi } {
+ # With -selectfill, make box occupy full width of widget
+ set bbox [list 0 [lindex $bbox 1] $width [lindex $bbox 3]]
+ }
+ set tags [list sel s:$item click clickbind]
+ set id [$path.c create rectangle $bbox \
+ -fill $selbg -outline $selbg -tags $tags]
+ if {$selfg != ""} {
+ # Don't allow an empty fill - that would be transparent
+ $path.c itemconfigure "n:$item" -fill $selfg
+ }
+ $path.c lower $id
+ $path.c lower b:$item
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_redraw_listbox
+# ----------------------------------------------------------------------------
+proc ListBox::_redraw_listbox { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { [Widget::getoption $path -redraw] } {
+ if { $data(upd,level) == 2 } {
+ _redraw_items $path
+ }
+ _redraw_selection $path
+ _update_scrollregion $path
+ if {[Widget::cget $path -selectfill]} {
+ _update_select_fill $path
+ }
+ set data(upd,level) 0
+ set data(upd,afterid) ""
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_redraw_idle
+# ----------------------------------------------------------------------------
+proc ListBox::_redraw_idle { path level } {
+ variable $path
+ upvar 0 $path data
+
+ if { $data(nrows) != -1 } {
+ # widget is realized
+ if { [Widget::getoption $path -redraw] && $data(upd,afterid) == "" } {
+ set data(upd,afterid) \
+ [after idle [list ListBox::_redraw_listbox $path]]
+ }
+ }
+ if { $level > $data(upd,level) } {
+ set data(upd,level) $level
+ }
+ return ""
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_resize
+# ----------------------------------------------------------------------------
+proc ListBox::_resize { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { [Widget::getoption $path -multicolumn] } {
+ set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}]
+ set h [expr {[winfo height $path] - 2*$bd}]
+ set nrows [expr {$h/[$path.c cget -yscrollincrement]}]
+ if { $nrows == 0 } {
+ set nrows 1
+ }
+ if { $nrows != $data(nrows) } {
+ set data(nrows) $nrows
+ _redraw_idle $path 2
+ } else {
+ _update_scrollregion $path
+ }
+ } elseif { $data(nrows) == -1 } {
+ # first Configure event
+ set data(nrows) 0
+ ListBox::_redraw_listbox $path
+ if {[Widget::cget $path -selectfill]} {
+ _update_select_fill $path
+ }
+ } else {
+ if {[Widget::cget $path -selectfill]} {
+ _update_select_fill $path
+ }
+
+ _update_scrollregion $path
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_init_drag_cmd
+# ----------------------------------------------------------------------------
+proc ListBox::_init_drag_cmd { path X Y top } {
+ set path [winfo parent $path]
+ set ltags [$path.c gettags current]
+ set item [lindex $ltags 0]
+ if { [string equal $item "item"] ||
+ [string equal $item "img"] ||
+ [string equal $item "win"] } {
+ set item [string range [lindex $ltags 1] 2 end]
+ if {[llength [set cmd [Widget::getoption $path -draginitcmd]]]} {
+ return [uplevel \#0 $cmd [list $path $item $top]]
+ }
+ if { [set type [Widget::getoption $path -dragtype]] == "" } {
+ set type "LISTBOX_ITEM"
+ }
+ if { [set img [Widget::getoption $path.$item -image]] != "" } {
+ pack [label $top.l -image $img -padx 0 -pady 0]
+ }
+ return [list $type {copy move link} $item]
+ }
+ return {}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_drop_cmd
+# ----------------------------------------------------------------------------
+proc ListBox::_drop_cmd { path source X Y op type dnddata } {
+ set path [winfo parent $path]
+ variable $path
+ upvar 0 $path data
+
+ if { [string length $data(dnd,afterid)] } {
+ after cancel $data(dnd,afterid)
+ set data(dnd,afterid) ""
+ }
+ $path.c delete drop
+ set data(dnd,scroll) ""
+ if { [llength $data(dnd,item)] || ![llength $data(items)] } {
+ if {[llength [set cmd [Widget::getoption $path -dropcmd]]]} {
+ return [uplevel \#0 $cmd [list $path $source $data(dnd,item) $op $type $dnddata]]
+ }
+ }
+ return 0
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_over_cmd
+# ----------------------------------------------------------------------------
+proc ListBox::_over_cmd { path source event X Y op type dnddata } {
+ set path [winfo parent $path]
+ variable $path
+ upvar 0 $path data
+
+ if { [string equal $event "leave"] } {
+ # we leave the window listbox
+ $path.c delete drop
+ if { [string length $data(dnd,afterid)] } {
+ after cancel $data(dnd,afterid)
+ set data(dnd,afterid) ""
+ }
+ set data(dnd,scroll) ""
+ return 0
+ }
+
+ if { [string equal $event "enter"] } {
+ # we enter the window listbox - dnd data initialization
+ set mode [Widget::getoption $path -dropovermode]
+ set data(dnd,mode) 0
+ foreach c {w p i} {
+ set data(dnd,mode) [expr {($data(dnd,mode) << 1) | ([string first $c $mode] != -1)}]
+ }
+ }
+
+ set x [expr {$X-[winfo rootx $path]}]
+ set y [expr {$Y-[winfo rooty $path]}]
+ $path.c delete drop
+ set data(dnd,item) ""
+
+ # test for auto-scroll unless mode is widget only
+ if { $data(dnd,mode) != 4 && [_auto_scroll $path $x $y] != "" } {
+ return 2
+ }
+
+ if { $data(dnd,mode) & 4 } {
+ # dropovermode includes widget
+ set target [list widget]
+ set vmode 4
+ } else {
+ set target [list ""]
+ set vmode 0
+ }
+ if { ($data(dnd,mode) & 2) && ![llength $data(items)] } {
+ # dropovermode includes position and listbox is empty
+ lappend target "" 0
+ set vmode [expr {$vmode | 2}]
+ }
+
+ if { ($data(dnd,mode) & 3) && [llength $data(items)]} {
+ # dropovermode includes item or position
+ # we extract the box (xi,yi,xs,ys) where we can find item around x,y
+ set len [llength $data(items)]
+ set xc [$path.c canvasx $x]
+ set yc [$path.c canvasy $y]
+ set dy [$path.c cget -yscrollincrement]
+ set line [expr {int($yc/$dy)}]
+ set yi [expr {$line*$dy}]
+ set ys [expr {$yi+$dy}]
+ set xi 0
+ set pos $line
+ if { [Widget::getoption $path -multicolumn] } {
+ set nrows $data(nrows)
+ } else {
+ set nrows $len
+ }
+ if { $line < $nrows } {
+ foreach xs $data(xlist) {
+ if { $xc <= $xs } {
+ break
+ }
+ set xi $xs
+ incr pos $nrows
+ }
+ if { $pos < $len } {
+ set item [lindex $data(items) $pos]
+ set xi [expr {[lindex [$path.c coords n:$item] 0]-[Widget::getoption $path -padx]-1}]
+ if { $data(dnd,mode) & 1 } {
+ # dropovermode includes item
+ lappend target $item
+ set vmode [expr {$vmode | 1}]
+ } else {
+ lappend target ""
+ }
+
+ if { $data(dnd,mode) & 2 } {
+ # dropovermode includes position
+ if { $yc >= $yi+$dy/2 } {
+ # position is after $item
+ incr pos
+ set yl $ys
+ } else {
+ # position is before $item
+ set yl $yi
+ }
+ lappend target $pos
+ set vmode [expr {$vmode | 2}]
+ } else {
+ lappend target ""
+ }
+ } else {
+ lappend target "" ""
+ }
+ } else {
+ lappend target "" ""
+ }
+
+ if { ($vmode & 3) == 3 } {
+ # result have both item and position
+ # we compute what is the preferred method
+ if { $yc-$yi <= 3 || $ys-$yc <= 3 } {
+ lappend target "position"
+ } else {
+ lappend target "item"
+ }
+ }
+ }
+
+ if {$vmode && [llength [set cmd [Widget::getoption $path -dropovercmd]]]} {
+ # user-defined dropover command
+ set res [uplevel \#0 $cmd [list $source $target $op $type $dnddata]]
+ set code [lindex $res 0]
+ set vmode 0
+ if {$code & 1} {
+ # update vmode
+ switch -exact -- [lindex $res 1] {
+ item {set vmode 1}
+ position {set vmode 2}
+ widget {set vmode 4}
+ }
+ }
+ } else {
+ if { ($vmode & 3) == 3 } {
+ # result have both item and position
+ # we choose the preferred method
+ if { [string equal [lindex $target 3] "position"] } {
+ set vmode [expr {$vmode & ~1}]
+ } else {
+ set vmode [expr {$vmode & ~2}]
+ }
+ }
+
+ if { $data(dnd,mode) == 4 || $data(dnd,mode) == 0 } {
+ # dropovermode is widget or empty - recall is not necessary
+ set code 1
+ } else {
+ set code 3
+ }
+ }
+
+ # draw dnd visual following vmode
+ if {[llength $data(items)]} {
+ if { $vmode & 1 } {
+ set data(dnd,item) [list "item" [lindex $target 1]]
+ $path.c create rectangle $xi $yi $xs $ys -tags drop
+ } elseif { $vmode & 2 } {
+ set data(dnd,item) [concat "position" [lindex $target 2]]
+ $path.c create line $xi $yl $xs $yl -tags drop
+ } elseif { $vmode & 4 } {
+ set data(dnd,item) [list "widget"]
+ } else {
+ set code [expr {$code & 2}]
+ }
+ }
+
+ if { $code & 1 } {
+ DropSite::setcursor based_arrow_down
+ } else {
+ DropSite::setcursor dot
+ }
+ return $code
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_auto_scroll
+# ----------------------------------------------------------------------------
+proc ListBox::_auto_scroll { path x y } {
+ variable $path
+ upvar 0 $path data
+
+ set xmax [winfo width $path]
+ set ymax [winfo height $path]
+ set scroll {}
+ if { $y <= 6 } {
+ if { [lindex [$path.c yview] 0] > 0 } {
+ set scroll [list yview -1]
+ DropSite::setcursor sb_up_arrow
+ }
+ } elseif { $y >= $ymax-6 } {
+ if { [lindex [$path.c yview] 1] < 1 } {
+ set scroll [list yview 1]
+ DropSite::setcursor sb_down_arrow
+ }
+ } elseif { $x <= 6 } {
+ if { [lindex [$path.c xview] 0] > 0 } {
+ set scroll [list xview -1]
+ DropSite::setcursor sb_left_arrow
+ }
+ } elseif { $x >= $xmax-6 } {
+ if { [lindex [$path.c xview] 1] < 1 } {
+ set scroll [list xview 1]
+ DropSite::setcursor sb_right_arrow
+ }
+ }
+
+ if { [string length $data(dnd,afterid)] && ![string equal $data(dnd,scroll) $scroll] } {
+ after cancel $data(dnd,afterid)
+ set data(dnd,afterid) ""
+ }
+
+ set data(dnd,scroll) $scroll
+ if { [llength $scroll] && ![string length $data(dnd,afterid)] } {
+ set data(dnd,afterid) [after 200 [list ListBox::_scroll $path $scroll]]
+ }
+ return $data(dnd,afterid)
+
+}
+
+# -----------------------------------------------------------------------------
+# Command ListBox::_multiple_select
+# -----------------------------------------------------------------------------
+proc ListBox::_multiple_select { path mode x y idx } {
+
+ variable $path
+ upvar 0 $path data
+
+
+ if { ![info exists data(anchor)] || ![info exists data(sel_anchor)] } {
+ set data(anchor) $idx
+ set data(sel_anchor) {}
+ }
+
+ switch -exact -- $mode {
+ n {
+ _mouse_select $path set $idx
+ set data(anchor) $idx
+ set data(sel_anchor) {}
+ }
+ c {
+ set l [$path selection get]
+ if { [lsearch -exact $l $idx] >= 0 } {
+ _mouse_select $path remove $idx
+ } else {
+ _mouse_select $path add $idx
+ }
+ set data(anchor) $idx
+ set data(sel_anchor) {}
+ }
+ s {
+ eval [list $path _mouse_select remove] $data(sel_anchor)
+
+ set ix [$path index $idx]
+ set ia [$path index $data(anchor)]
+ if { $ix > $ia } {
+ set istart $ia
+ set iend $ix
+ } else {
+ set istart $ix
+ set iend $ia
+ }
+
+ for { set i $istart } { $i <= $iend } { incr i } {
+ set l [$path selection get]
+ set t [$path items $i]
+ set li [lsearch -exact $l $t]
+ if { $li < 0 } {
+ _mouse_select $path add $t
+ lappend data(sel_anchor) $t
+ }
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ListBox::_scroll
+# ----------------------------------------------------------------------------
+proc ListBox::_scroll { path scroll} {
+ variable $path
+ upvar 0 $path data
+ set cmd [lindex $scroll 0]
+ set dir [lindex $scroll 1]
+ if { ($dir == -1 && [lindex [$path.c $cmd] 0] > 0) ||
+ ($dir == 1 && [lindex [$path.c $cmd] 1] < 1) } {
+ $path $cmd scroll $dir units
+ set data(dnd,afterid) \
+ [after 50 [list ListBox::_scroll $path $scroll]]
+ } else {
+ set data(dnd,afterid) ""
+ DropSite::setcursor dot
+ }
+}
+
+# ListBox::_set_help --
+#
+# Register dynamic help for an item in the listbox.
+#
+# Arguments:
+# path ListBox to query
+# item Item in the listbox
+# force Optional argument to force a reset of the help
+#
+# Results:
+# none
+proc ListBox::_set_help { path node } {
+ Widget::getVariable $path help
+
+ set item $path.$node
+ set opts [list -helptype -helptext -helpvar]
+ foreach {cty ctx cv} [eval [linsert $opts 0 Widget::hasChangedX $item]] break
+ set text [Widget::getoption $item -helptext]
+
+ ## If we've never set help for this item before, and text is not blank,
+ ## we need to setup help. We also need to reset help if any of the
+ ## options have changed.
+ if { (![info exists help($node)] && $text != "") || $cty || $ctx || $cv } {
+ set help($node) 1
+ set type [Widget::getoption $item -helptype]
+ switch $type {
+ balloon {
+ DynamicHelp::register $path.c balloon n:$node $text
+ DynamicHelp::register $path.c balloon i:$node $text
+ DynamicHelp::register $path.c balloon b:$node $text
+ }
+ variable {
+ set var [Widget::getoption $item -helpvar]
+ DynamicHelp::register $path.c variable n:$node $var $text
+ DynamicHelp::register $path.c variable i:$node $var $text
+ DynamicHelp::register $path.c variable b:$node $var $text
+ }
+ }
+ }
+}
+
+# ListBox::_mouse_select --
+#
+# Handle selection commands that are done by the mouse. If the
+# selection command returns true, we generate a <<ListboxSelect>>
+# event for the listbox.
+#
+# Arguments:
+# Standard arguments passed to a selection command.
+#
+# Results:
+# none
+proc ListBox::_mouse_select { path cmd args } {
+ eval [linsert $args 0 selection $path $cmd]
+ switch -- $cmd {
+ "add" - "clear" - "remove" - "set" {
+ event generate $path <<ListboxSelect>>
+ }
+ }
+}
+
+
+proc ListBox::_get_current { path } {
+ set t [$path.c gettags current]
+ return [string range [lindex $t 1] 2 end]
+}
+
+
+# ListBox::_drag_and_drop --
+#
+# A default command to handle drag-and-drop functions local to this
+# listbox. With this as the default -dropcmd, the user can simply
+# enable drag-and-drop and be able to move items within this list
+# with no further code.
+#
+# Arguments:
+# Standard arguments passed to a dropcmd.
+#
+# Results:
+# none
+proc ListBox::_drag_and_drop { path from endItem operation type startItem } {
+ set items [$path items]
+
+ ## This proc only handles drag-and-drop commands within itself.
+ ## If the widget this came from is not our widget (minus the canvas),
+ ## we don't want to do anything. They need to handle this themselves.
+ if {[winfo parent $from] != $path} { return }
+
+ set place [lindex $endItem 0]
+ set i [lindex $endItem 1]
+
+ switch -- $place {
+ "position" {
+ set idx $i
+ }
+ "item" {
+ set idx [$path index $i]
+ }
+ "widget" {
+ set idx [llength $items]
+ }
+ }
+
+ # Check if startItem is part of the current selection and process the
+ # whole selection if so
+ set selItems [selection $path get]
+ if {-1 != [lsearch -exact $selItems $startItem]} {
+ set dragItems $selItems
+ } else {
+ set dragItems [list $startItem]
+ }
+
+ # get drag indexes (to sort them)
+ foreach dragItem $dragItems {
+ lappend dragIdx [$path index $dragItem]
+ }
+ foreach pos [lsort -integer -indices $dragIdx] {
+ set dragItem [lindex $dragItems $pos]
+ set dragIdx [$path index $dragItem]
+ if {$idx > $dragIdx} { incr idx -1 }
+ if {[string equal $operation "copy"]} {
+ set options [Widget::options $path.$dragItem]
+ eval [linsert $options 0 $path insert $idx $dragItem\#auto]
+ incr idx
+ } else {
+ $path move $dragItem $idx
+ set idx [$path index $dragItem]
+ incr idx
+ }
+ }
+}
+
+
+proc ListBox::_keyboard_navigation { path dir } {
+ variable $path
+ upvar 0 $path data
+
+ set sel [$path index [lindex [$path selection get] end]]
+ if {$dir > 0} {
+ incr sel
+ if {$sel >= [llength $data(items)]} { return }
+ } else {
+ incr sel -1
+ if {$sel < 0} { return }
+ }
+ set item [lindex $data(items) $sel]
+ $path see $item
+ _mouse_select $path set $item
+}
diff --git a/modules/tclsci/tcl/BWidget/mainframe.tcl b/modules/tclsci/tcl/BWidget/mainframe.tcl
new file mode 100755
index 000000000..e66bf572f
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/mainframe.tcl
@@ -0,0 +1,713 @@
+# ----------------------------------------------------------------------------
+# mainframe.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: mainframe.tcl,v 1.24.2.1 2010/11/09 16:05:43 oehhar Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - MainFrame::create
+# - MainFrame::configure
+# - MainFrame::cget
+# - MainFrame::getframe
+# - MainFrame::addtoolbar
+# - MainFrame::gettoolbar
+# - MainFrame::addindicator
+# - MainFrame::getindicator
+# - MainFrame::getmenu
+# - MainFrame::menuonly
+# - MainFrame::showtoolbar
+# - MainFrame::showstatusbar
+# - MainFrame::_create_menubar
+# - MainFrame::_create_entries
+# - MainFrame::_parse_name
+# - MainFrame::_parse_accelerator
+# ----------------------------------------------------------------------------
+
+namespace eval MainFrame {
+ Widget::define MainFrame mainframe ProgressBar
+
+ Widget::bwinclude MainFrame ProgressBar .status.prg \
+ remove {
+ -fg -bg -bd -troughcolor -background -borderwidth
+ -relief -orient -width -height
+ } \
+ rename {
+ -maximum -progressmax
+ -variable -progressvar
+ -type -progresstype
+ -foreground -progressfg
+ }
+
+ Widget::declare MainFrame {
+ {-width TkResource 0 0 frame}
+ {-height TkResource 0 0 frame}
+ {-background TkResource "" 0 frame}
+ {-textvariable String "" 0}
+ {-menu String {} 1}
+ {-separator Enum both 1 {none top bottom both}}
+ {-bg Synonym -background}
+
+ {-menubarfont String "" 0}
+ {-menuentryfont String "" 0}
+ {-statusbarfont String "" 0}
+ }
+
+ Widget::addmap MainFrame "" .frame {-width {} -height {} -background {}}
+ Widget::addmap MainFrame "" .topf {-background {}}
+ Widget::addmap MainFrame "" .botf {-background {}}
+ Widget::addmap MainFrame "" .status {-background {}}
+ Widget::addmap MainFrame "" .status.label {-background {}}
+ Widget::addmap MainFrame "" .status.indf {-background {}}
+ Widget::addmap MainFrame "" .status.prgf {-background {}}
+ Widget::addmap MainFrame ProgressBar .status.prg {-background {} -background -troughcolor}
+
+ variable _widget
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::create
+# ----------------------------------------------------------------------------
+proc MainFrame::create { path args } {
+ global tcl_platform
+ variable _widget
+
+ if {[Widget::theme]} {
+ set path [ttk::frame $path]
+ } else {
+ set path [frame $path -takefocus 0 -highlightthickness 0]
+ }
+ set top [winfo parent $path]
+ if { ![string equal [winfo toplevel $path] $top] } {
+ destroy $path
+ return -code error "parent must be a toplevel"
+ }
+ Widget::init MainFrame $path $args
+
+ if { $tcl_platform(platform) == "unix" } {
+ set relief raised
+ set bd 1
+ } else {
+ set relief flat
+ set bd 0
+ }
+ if {[Widget::theme]} {
+ set userframe [eval [list ttk::frame $path.frame] \
+ [Widget::subcget $path .frame]]
+ set topframe [ttk::frame $path.topf]
+ set botframe [ttk::frame $path.botf]
+ } else {
+ set userframe [eval [list frame $path.frame] \
+ [Widget::subcget $path .frame] \
+ -relief $relief -borderwidth $bd]
+ set topframe [eval [list frame $path.topf] \
+ [Widget::subcget $path .topf]]
+ set botframe [eval [list frame $path.botf] \
+ -relief $relief -borderwidth $bd \
+ [Widget::subcget $path .botf]]
+ }
+
+ pack $topframe -fill x
+ grid columnconfigure $topframe 0 -weight 1
+
+ if {![Widget::theme]} {
+ set bg [Widget::cget $path -background]
+ $path configure -background $bg
+ }
+ if { $tcl_platform(platform) != "unix" } {
+ set sepopt [Widget::getoption $path -separator]
+ if { $sepopt == "both" || $sepopt == "top" } {
+ if {[Widget::theme]} {
+ set sep [ttk::separator $path.sep -orient horizontal]
+ } else {
+ set sep [Separator::create $path.sep -orient horizontal -background $bg]
+ }
+ pack $sep -fill x
+ }
+ if { $sepopt == "both" || $sepopt == "bottom" } {
+ if {[Widget::theme]} {
+ set sep [ttk::separator $botframe.sep -orient horizontal]
+ } else {
+ set sep [Separator::create $botframe.sep -orient horizontal -background $bg]
+ }
+ pack $sep -fill x
+ }
+ }
+
+ # --- status bar ---------------------------------------------------------
+ if {[string length [Widget::getoption $path -statusbarfont]]} {
+ set sbfnt [list -font [Widget::getoption $path -statusbarfont]]
+ } else {
+ set sbfnt ""
+ }
+
+ if {[Widget::theme]} {
+ set status [ttk::frame $path.status]
+ set label [eval [list ttk::label $status.label \
+ -textvariable [Widget::getoption $path -textvariable]] $sbfnt]
+ set indframe [ttk::frame $status.indf]
+ set prgframe [ttk::frame $status.prgf]
+ } else {
+ set status [frame $path.status -background $bg]
+ set label [eval [list label $status.label \
+ -textvariable [Widget::getoption $path -textvariable] \
+ -background $bg] $sbfnt]
+ set indframe [frame $status.indf -background $bg]
+ set prgframe [frame $status.prgf -background $bg]
+ }
+
+ place $label -anchor w -x 0 -rely 0.5
+ place $indframe -anchor ne -relx 1 -y 0 -relheight 1
+ pack $prgframe -in $indframe -side left -padx 2
+ $status configure -height [winfo reqheight $label]
+
+ set progress [eval [list ProgressBar::create $status.prg] \
+ [Widget::subcget $path .status.prg] \
+ -width 50 \
+ -height [expr {[winfo reqheight $label]-2}] \
+ -borderwidth 1 \
+ -relief sunken]
+ pack $status -in $botframe -fill x -pady 2
+ pack $botframe -side bottom -fill x
+ pack $userframe -fill both -expand yes
+
+ set _widget($path,top) $top
+ set _widget($path,ntoolbar) 0
+ set _widget($path,nindic) 0
+
+ set menu [Widget::getoption $path -menu]
+ if { [llength $menu] } {
+ _create_menubar $path $menu
+ }
+
+ bind $path <Destroy> [list MainFrame::_destroy %W]
+
+ return [Widget::create MainFrame $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::configure
+# ----------------------------------------------------------------------------
+proc MainFrame::configure { path args } {
+ variable _widget
+
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -textvariable newv] } {
+ uplevel \#0 $path.status.label configure -textvariable [list $newv]
+ }
+
+ # The ttk frame has no -background
+ if {![Widget::theme] && [Widget::hasChanged $path -background bg] } {
+ if {$::tcl_platform(platform) == "unix"} {
+ set listmenu [$_widget($path,top) cget -menu]
+ while { [llength $listmenu] } {
+ set newlist {}
+ foreach menu $listmenu {
+ $menu configure -background $bg
+ set newlist [concat $newlist [winfo children $menu]]
+ }
+ set listmenu $newlist
+ }
+ }
+ foreach sep {.sep .botf.sep} {
+ if {[winfo exists $path.$sep]} {
+ Separator::configure $path.$sep -background $bg
+ }
+ }
+ foreach w [winfo children $path.topf] {
+ $w configure -background $bg
+ }
+ }
+
+ if { [Widget::hasChanged $path -menubarfont newmbfnt] } {
+ if {[string length $newmbfnt]} {
+ set mbfnt [list -font $newmbfnt]
+ } else {
+ set mbfnt ""
+ }
+ set top $_widget($path,top)
+ if {[string equal $top .]} {
+ eval [list .menubar configure] $mbfnt
+ } else {
+ eval [list $top.menubar configure] $mbfnt
+ }
+ }
+ if { [Widget::hasChanged $path -menuentryfont newmefnt] } {
+ if {[string length $newmefnt]} {
+ set mefnt [list -font $newmefnt]
+ } else {
+ set mefnt ""
+ }
+ set top $_widget($path,top)
+ if {[string equal $top .]} {
+ set mb .menubar
+ } else {
+ set mb $top.menubar
+ }
+ set l [winfo children $mb]
+ while {[llength $l]} {
+ set e [lindex $l 0]
+ set l [lrange $l 1 end]
+ if {[string length $e] == 0} {continue}
+ lappend l [winfo children $e]
+ eval [list $e configure] $mefnt
+ }
+ }
+
+
+ if { [Widget::hasChanged $path -statusbarfont newsbfnt] } {
+ if {[string length $newsbfnt]} {
+ set sbfnt [list -font $newsbfnt]
+ } else {
+ set sbfnt ""
+ }
+ for {set index 0} {$index<$_widget($path,nindic)} {incr index} {
+ set indic $path.status.indf.f$index
+ eval [list $indic configure] $sbfnt
+ }
+ eval [list $path.status.label configure] $sbfnt
+ $path.status configure -height [winfo reqheight $path.status.label]
+
+ $path.status.prg configure \
+ -height [expr {[winfo reqheight $path.status.label]-2}]
+ }
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::cget
+# ----------------------------------------------------------------------------
+proc MainFrame::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::getframe
+# ----------------------------------------------------------------------------
+proc MainFrame::getframe { path } {
+ return $path.frame
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::addtoolbar
+# ----------------------------------------------------------------------------
+proc MainFrame::addtoolbar { path } {
+ global tcl_platform
+ variable _widget
+
+ set index $_widget($path,ntoolbar)
+ set toolframe $path.topf.f$index
+ set toolbar $path.topf.tb$index
+ set bg [Widget::getoption $path -background]
+ if { $tcl_platform(platform) == "unix" } {
+ if {[Widget::theme]} {
+ ttk::frame $toolframe -padding 1
+ } else {
+ frame $toolframe -relief raised -borderwidth 1 \
+ -takefocus 0 -highlightthickness 0 -background $bg
+ }
+ } else {
+ if {[Widget::theme]} {
+ ttk::frame $toolframe
+ set sep [ttk::separator $toolframe.sep -orient horizontal]
+ } else {
+ frame $toolframe -relief flat -borderwidth 0 -takefocus 0 \
+ -highlightthickness 0 -background $bg
+ set sep [Separator::create $toolframe.sep -orient horizontal -background $bg]
+ }
+ pack $sep -fill x
+ }
+ if {[Widget::theme]} {
+ set toolbar [ttk::frame $toolbar -padding 2]
+ } else {
+ set toolbar [frame $toolbar -relief flat -borderwidth 2 \
+ -takefocus 0 -highlightthickness 0 -background $bg]
+ }
+ pack $toolbar -in $toolframe -anchor w -expand yes -fill x
+ incr _widget($path,ntoolbar)
+ grid $toolframe -column 0 -row $index -sticky ew
+ return $toolbar
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::gettoolbar
+# ----------------------------------------------------------------------------
+proc MainFrame::gettoolbar { path index } {
+ return $path.topf.tb$index
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::addindicator
+# ----------------------------------------------------------------------------
+proc MainFrame::addindicator { path args } {
+ variable _widget
+
+ if {[string length [Widget::getoption $path -statusbarfont]]} {
+ set sbfnt [list -font [Widget::getoption $path -statusbarfont]]
+ } else {
+ set sbfnt ""
+ }
+
+ set index $_widget($path,nindic)
+ set indic $path.status.indf.f$index
+ eval [list label $indic] $args -relief sunken -borderwidth 1 \
+ -takefocus 0 -highlightthickness 0 $sbfnt
+
+ pack $indic -side left -anchor w -padx 2 -fill y -expand 1
+
+ incr _widget($path,nindic)
+
+ return $indic
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::getindicator
+# ----------------------------------------------------------------------------
+proc MainFrame::getindicator { path index } {
+ return $path.status.indf.f$index
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::getmenu
+# ----------------------------------------------------------------------------
+proc MainFrame::getmenu { path menuid } {
+ variable _widget
+
+ if { [info exists _widget($path,menuid,$menuid)] } {
+ return $_widget($path,menuid,$menuid)
+ }
+ return ""
+}
+
+
+# -----------------------------------------------------------------------------
+# Command MainFrame::setmenustate
+# -----------------------------------------------------------------------------
+proc MainFrame::setmenustate { path tag state } {
+ variable _widget
+
+ # Set menustate to enabled when ALL of its tags are enabled.
+
+ # First see if this is a real tag
+ if { [info exists _widget($path,tagstate,$tag)] } {
+ if { ![string equal $state "disabled"] } {
+ set _widget($path,tagstate,$tag) 1
+ } else {
+ set _widget($path,tagstate,$tag) 0
+ }
+ foreach {menu entry} $_widget($path,tags,$tag) {
+ set expression "1"
+ foreach menutag $_widget($path,menutags,[list $menu $entry]) {
+ append expression " && $_widget($path,tagstate,$menutag)"
+ }
+ if { [expr $expression] } {
+ set state normal
+ } else {
+ set state disabled
+ }
+ $menu entryconfigure $entry -state $state
+ }
+ }
+ return
+}
+
+# -----------------------------------------------------------------------------
+# Command MainFrame::getmenustate
+# -----------------------------------------------------------------------------
+proc MainFrame::getmenustate { path tag } {
+ variable _widget
+
+ if {$_widget($path,tagstate,$tag)} {
+ return normal
+ } else {
+ return disabled
+ }
+}
+
+# -----------------------------------------------------------------------------
+# Command MainFrame::menuonly
+# ----------------------d------------------------------------------------------
+proc MainFrame::menuonly { path } {
+ variable _widget
+
+ catch {pack forget $path.sep}
+ catch {pack forget $path.botf.sep}
+ catch {pack forget $path.frame}
+}
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::showtoolbar
+# ----------------------------------------------------------------------------
+proc MainFrame::showtoolbar { path index bool } {
+ variable _widget
+
+ set toolframe $path.topf.f$index
+ if { [winfo exists $toolframe] } {
+ if { !$bool && [llength [grid info $toolframe]] } {
+ grid forget $toolframe
+ $path.topf configure -height 1
+ } elseif { $bool && ![llength [grid info $toolframe]] } {
+ grid $toolframe -column 0 -row $index -sticky ew
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::showstatusbar
+# ----------------------------------------------------------------------------
+proc MainFrame::showstatusbar { path name } {
+ set status $path.status
+ set botframe $path.botf
+ if { [string equal $name "none"] } {
+ pack forget $status
+ } else {
+ pack $status -fill x -in $botframe -fill x -pady 2
+ switch -- $name {
+ status {
+ catch {pack forget $status.prg}
+ }
+ progression {
+ pack $status.prg -in $status.prgf
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::_destroy
+# ----------------------------------------------------------------------------
+proc MainFrame::_destroy { path } {
+ variable _widget
+
+ Widget::destroy $path
+ catch {destroy [$_widget($path,top) cget -menu]}
+ $_widget($path,top) configure -menu {}
+
+ # Unset all of the state vars associated with this main frame.
+ foreach index [array names _widget $path,*] {
+ unset _widget($index)
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::_create_menubar
+# ----------------------------------------------------------------------------
+proc MainFrame::_create_menubar { path descmenu } {
+ variable _widget
+ global tcl_platform
+
+ set top $_widget($path,top)
+
+ foreach {v x} {mbfnt -menubarfont mefnt -menuentryfont} {
+ if {[string length [Widget::getoption $path $x]]} {
+ set $v [list -font [Widget::getoption $path $x]]
+ } else {
+ set $v ""
+ }
+ }
+
+ if { ![Widget::theme] && $tcl_platform(platform) == "unix"
+ && [tk windowingsystem] !="aqua" } {
+ set menuopts [list -background [Widget::getoption $path -background] \
+ -borderwidth 1]
+ } else {
+ set menuopts [list]
+ }
+ set menubar [eval [list menu $top.menubar -tearoff 0] $menuopts $mbfnt]
+ $top configure -menu $menubar
+
+ set count 0
+ foreach {name tags menuid tearoff entries} $descmenu {
+ set opt [_parse_name $name]
+ if {[string length $menuid]
+ && ![info exists _widget($path,menuid,$menuid)] } {
+ # menu has identifier
+ # we use it for its pathname, to enable special menu entries
+ # (help, system, ...)
+ set menu $menubar.$menuid
+ } else {
+ set menu $menubar.menu$count
+ }
+ eval [list $menubar add cascade] $opt [list -menu $menu]
+ eval [list menu $menu -tearoff $tearoff] $menuopts $mefnt
+ foreach tag $tags {
+ lappend _widget($path,tags,$tag) $menubar $count
+ # ericm@scriptics: Add a tagstate tracker
+ if { ![info exists _widget($path,tagstate,$tag)] } {
+ set _widget($path,tagstate,$tag) 1
+ }
+ }
+ # ericm@scriptics: Add mapping from menu items to tags
+ set _widget($path,menutags,[list $menubar $count]) $tags
+
+ if { [string length $menuid] } {
+ # menu has identifier
+ set _widget($path,menuid,$menuid) $menu
+ }
+ _create_entries $path $menu $menuopts $entries
+ incr count
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::_create_entries
+# ----------------------------------------------------------------------------
+proc MainFrame::_create_entries { path menu menuopts entries } {
+ variable _widget
+
+ set count [$menu cget -tearoff]
+ set registered 0
+ foreach entry $entries {
+ set len [llength $entry]
+ set type [lindex $entry 0]
+
+ if { [string equal $type "separator"] } {
+ $menu add separator
+ incr count
+ continue
+ }
+
+ # entry name and tags
+ set opt [_parse_name [lindex $entry 1]]
+ set tags [lindex $entry 2]
+ foreach tag $tags {
+ lappend _widget($path,tags,$tag) $menu $count
+ # ericm@scriptics: Add a tagstate tracker
+ if { ![info exists _widget($path,tagstate,$tag)] } {
+ set _widget($path,tagstate,$tag) 1
+ }
+ }
+ # ericm@scriptics: Add mapping from menu items to tags
+ set _widget($path,menutags,[list $menu $count]) $tags
+
+ if {[string equal $type "cascade"] || [string equal $type "cascad"]} {
+ set menuid [lindex $entry 3]
+ set tearoff [lindex $entry 4]
+ set submenu $menu.menu$count
+ eval [list $menu add cascade] $opt [list -menu $submenu]
+ eval [list menu $submenu -tearoff $tearoff] $menuopts
+ if { [string length $menuid] } {
+ # menu has identifier
+ set _widget($path,menuid,$menuid) $submenu
+ }
+ _create_entries $path $submenu $menuopts [lindex $entry 5]
+ incr count
+ continue
+ }
+
+ # entry help description
+ set desc [lindex $entry 3]
+ if { [string length $desc] } {
+ if { !$registered } {
+ DynamicHelp::register $menu menu [Widget::getoption $path -textvariable]
+ set registered 1
+ }
+ DynamicHelp::register $menu menuentry $count $desc
+ }
+
+ # entry accelerator
+ set accel [_parse_accelerator [lindex $entry 4]]
+ if { [llength $accel] } {
+ lappend opt -accelerator [lindex $accel 0]
+ bind $_widget($path,top) [lindex $accel 1] [list $menu invoke $count]
+ }
+
+ # user options
+ set useropt [lrange $entry 5 end]
+ if { [string equal $type "command"] ||
+ [string equal $type "radiobutton"] ||
+ [string equal $type "checkbutton"] } {
+ eval [list $menu add $type] $opt $useropt
+ } else {
+ return -code error "invalid menu type \"$type\""
+ }
+ incr count
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command MainFrame::_parse_name
+# ----------------------------------------------------------------------------
+proc MainFrame::_parse_name { menuname } {
+ set idx [string first "&" $menuname]
+ if { $idx == -1 } {
+ return [list -label $menuname]
+ } else {
+ set beg [string range $menuname 0 [expr {$idx-1}]]
+ set end [string range $menuname [expr {$idx+1}] end]
+ append beg $end
+ return [list -label $beg -underline $idx]
+ }
+}
+
+
+# MainFrame::_parse_accelerator --
+#
+# Given a key combo description, construct an appropriate human readable
+# string (for display on as a menu accelerator) and the corresponding
+# bind event.
+#
+# Arguments:
+# desc a list with the following format:
+# ?sequence? key
+# sequence may be None, Ctrl, Alt, or CtrlAlt
+# key may be any key
+#
+# Results:
+# {accel event} a list containing the accelerator string and the event
+
+proc MainFrame::_parse_accelerator { desc } {
+ if { [llength $desc] == 1 } {
+ set seq None
+ set key [string tolower [lindex $desc 0]]
+ # If the key is an F key (ie, F1, F2, etc), it has to be capitalized
+ if {[regexp {^f([1-9]|([12][0-9]|3[0-5]))$} $key]} {
+ set key [string toupper $key]
+ }
+ } elseif { [llength $desc] == 2 } {
+ set seq [lindex $desc 0]
+ set key [string tolower [lindex $desc 1]]
+ # If the key is an F key (ie, F1, F2, etc), it has to be capitalized
+ if {[regexp {^f([1-9]|([12][0-9]|3[0-5]))$} $key]} {
+ set key [string toupper $key]
+ }
+ } else {
+ return {}
+ }
+ switch -- $seq {
+ None {
+ set accel "[string toupper $key]"
+ set event "<Key-$key>"
+ }
+ Ctrl {
+ set accel "Ctrl+[string toupper $key]"
+ set event "<Control-Key-$key>"
+ }
+ Alt {
+ set accel "Alt+[string toupper $key]"
+ set event "<Alt-Key-$key>"
+ }
+ CtrlAlt {
+ set accel "Ctrl+Alt+[string toupper $key]"
+ set event "<Control-Alt-Key-$key>"
+ }
+ default {
+ return -code error "invalid accelerator code $seq"
+ }
+ }
+ return [list $accel $event]
+}
diff --git a/modules/tclsci/tcl/BWidget/messagedlg.tcl b/modules/tclsci/tcl/BWidget/messagedlg.tcl
new file mode 100755
index 000000000..effe6ed90
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/messagedlg.tcl
@@ -0,0 +1,128 @@
+# ------------------------------------------------------------------------------
+# messagedlg.tcl
+# This file is part of Unifix BWidget Toolkit
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - MessageDlg::create
+# ------------------------------------------------------------------------------
+
+namespace eval MessageDlg {
+ Widget::define MessageDlg messagedlg Dialog
+
+ Widget::tkinclude MessageDlg message .frame.msg \
+ remove [list -cursor -highlightthickness \
+ -highlightbackground -highlightcolor \
+ -relief -borderwidth -takefocus -textvariable \
+ ] \
+ rename [list -text -message] \
+ initialize [list -aspect 800 -anchor c -justify center]
+
+ Widget::bwinclude MessageDlg Dialog :cmd \
+ remove [list -modal -image -bitmap -side -anchor -separator \
+ -homogeneous -padx -pady -spacing]
+
+ Widget::declare MessageDlg {
+ {-icon Enum info 0 {none error info question warning}}
+ {-type Enum user 0 {abortretryignore ok okcancel \
+ retrycancel yesno yesnocancel user}}
+ {-buttons String "" 0}
+ {-buttonwidth String 0 0}
+ }
+
+ Widget::addmap MessageDlg "" tkMBox {
+ -parent {} -message {} -default {} -title {}
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command MessageDlg::create
+# ------------------------------------------------------------------------------
+proc MessageDlg::create { path args } {
+ global tcl_platform
+
+ array set maps [list MessageDlg {} :cmd {} .frame.msg {} tkMBox {}]
+ array set maps [Widget::parseArgs MessageDlg $args]
+ Widget::initFromODB MessageDlg "$path#Message" $maps(MessageDlg)
+
+ array set dialogArgs $maps(:cmd)
+
+ set type [Widget::cget "$path#Message" -type]
+ set icon [Widget::cget "$path#Message" -icon]
+ set width [Widget::cget "$path#Message" -buttonwidth]
+
+ set defb -1
+ set canb -1
+ switch -- $type {
+ abortretryignore {set lbut {abort retry ignore}; set defb 0}
+ ok {set lbut {ok}; set defb 0 }
+ okcancel {set lbut {ok cancel}; set defb 0; set canb 1}
+ retrycancel {set lbut {retry cancel}; set defb 0; set canb 1}
+ yesno {set lbut {yes no}; set defb 0; set canb 1}
+ yesnocancel {set lbut {yes no cancel}; set defb 0; set canb 2}
+ user {set lbut [Widget::cget "$path#Message" -buttons]}
+ }
+
+ # If the user didn't specify a default button, use our type-specific
+ # default, adding its flag/value to the "user" settings and to the tkMBox
+ # settings
+ if { ![info exists dialogArgs(-default)] } {
+ lappend maps(:cmd) -default $defb
+ lappend maps(tkMBox) -default $defb
+ }
+ if { ![info exists dialogArgs(-cancel)] } {
+ lappend maps(:cmd) -cancel $canb
+ }
+
+ # Same with title as with default
+ if { ![info exists dialogArgs(-title)] } {
+ set frame [frame $path -class MessageDlg]
+ set title [option get $frame "${icon}Title" MessageDlg]
+ destroy $frame
+ if { $title == "" } {
+ set title "Message"
+ }
+ lappend maps(:cmd) -title $title
+ lappend maps(tkMBox) -title $title
+ }
+
+ # Create the "user" type dialog
+ if { $type == "user" } {
+ if { $icon != "none" } {
+ set image [Bitmap::get $icon]
+ } else {
+ set image ""
+ }
+ eval [list Dialog::create $path] $maps(:cmd) \
+ [list -image $image -modal local -side bottom -anchor e]
+ foreach but $lbut {
+ Dialog::add $path -text $but -name $but -width $width
+ }
+ set frame [Dialog::getframe $path]
+
+ eval [list message $frame.msg] $maps(.frame.msg) \
+ [list -relief flat -borderwidth 0 -highlightthickness 0 \
+ -textvariable ""]
+ pack $frame.msg -side left -padx 3m -pady 1m -fill x -expand yes
+
+ set res [Dialog::draw $path]
+ destroy $path
+ } else {
+ # Do some translation of args into tk_messageBox syntax, then create
+ # the tk_messageBox
+ array set tkMBoxArgs $maps(tkMBox)
+ set tkMBoxArgs(-default) [lindex $lbut $tkMBoxArgs(-default)]
+ if { ![string equal $icon "none"] } {
+ set tkMBoxArgs(-icon) $icon
+ }
+ if {[info exists tkMBoxArgs(-parent)]
+ && ![winfo exists $tkMBoxArgs(-parent)]} {
+ unset tkMBoxArgs(-parent)
+ }
+ set tkMBoxArgs(-type) $type
+ set res [eval [list tk_messageBox] [array get tkMBoxArgs]]
+ set res [lsearch $lbut $res]
+ }
+ Widget::destroy "$path#Message"
+ return $res
+}
diff --git a/modules/tclsci/tcl/BWidget/notebook.tcl b/modules/tclsci/tcl/BWidget/notebook.tcl
new file mode 100755
index 000000000..f5532a4be
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/notebook.tcl
@@ -0,0 +1,1166 @@
+# ---------------------------------------------------------------------------
+# notebook.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: notebook.tcl,v 1.25.2.1 2009/08/10 11:28:50 oehhar Exp $
+# ---------------------------------------------------------------------------
+# Index of commands:
+# - NoteBook::create
+# - NoteBook::configure
+# - NoteBook::cget
+# - NoteBook::compute_size
+# - NoteBook::insert
+# - NoteBook::delete
+# - NoteBook::itemconfigure
+# - NoteBook::itemcget
+# - NoteBook::bindtabs
+# - NoteBook::raise
+# - NoteBook::see
+# - NoteBook::page
+# - NoteBook::pages
+# - NoteBook::index
+# - NoteBook::getframe
+# - NoteBook::_test_page
+# - NoteBook::_itemconfigure
+# - NoteBook::_compute_width
+# - NoteBook::_get_x_page
+# - NoteBook::_xview
+# - NoteBook::_highlight
+# - NoteBook::_select
+# - NoteBook::_redraw
+# - NoteBook::_draw_page
+# - NoteBook::_draw_arrows
+# - NoteBook::_draw_area
+# - NoteBook::_resize
+# ---------------------------------------------------------------------------
+
+namespace eval NoteBook {
+ Widget::define NoteBook notebook ArrowButton DynamicHelp
+
+ namespace eval Page {
+ Widget::declare NoteBook::Page {
+ {-state Enum normal 0 {normal disabled}}
+ {-createcmd String "" 0}
+ {-raisecmd String "" 0}
+ {-leavecmd String "" 0}
+ {-image TkResource "" 0 label}
+ {-text String "" 0}
+ {-foreground String "" 0}
+ {-background String "" 0}
+ {-activeforeground String "" 0}
+ {-activebackground String "" 0}
+ {-disabledforeground String "" 0}
+ }
+ }
+
+ DynamicHelp::include NoteBook::Page balloon
+
+ Widget::bwinclude NoteBook ArrowButton .c.fg \
+ include {-foreground -background -activeforeground \
+ -activebackground -disabledforeground -repeatinterval \
+ -repeatdelay -borderwidth} \
+ initialize {-borderwidth 1}
+ Widget::bwinclude NoteBook ArrowButton .c.fd \
+ include {-foreground -background -activeforeground \
+ -activebackground -disabledforeground -repeatinterval \
+ -repeatdelay -borderwidth} \
+ initialize {-borderwidth 1}
+
+ Widget::declare NoteBook {
+ {-foreground TkResource "" 0 button}
+ {-background TkResource "" 0 button}
+ {-activebackground TkResource "" 0 button}
+ {-activeforeground TkResource "" 0 button}
+ {-disabledforeground TkResource "" 0 button}
+ {-font TkResource "" 0 button}
+ {-side Enum top 0 {top bottom}}
+ {-homogeneous Boolean 0 0}
+ {-borderwidth Int 1 0 "%d >= 1 && %d <= 2"}
+ {-internalborderwidth Int 10 0 "%d >= 0"}
+ {-width Int 0 0 "%d >= 0"}
+ {-height Int 0 0 "%d >= 0"}
+
+ {-repeatdelay BwResource "" 0 ArrowButton}
+ {-repeatinterval BwResource "" 0 ArrowButton}
+
+ {-fg Synonym -foreground}
+ {-bg Synonym -background}
+ {-bd Synonym -borderwidth}
+ {-ibd Synonym -internalborderwidth}
+
+ {-arcradius Int 2 0 "%d >= 0 && %d <= 8"}
+ {-tabbevelsize Int 0 0 "%d >= 0 && %d <= 8"}
+ {-tabpady Padding {0 6} 0 "%d >= 0"}
+ }
+
+ Widget::addmap NoteBook "" .c {-background {}}
+
+ variable _warrow 12
+
+ bind NoteBook <Configure> [list NoteBook::_resize %W]
+ bind NoteBook <Destroy> [list NoteBook::_destroy %W]
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::create
+# ---------------------------------------------------------------------------
+proc NoteBook::create { path args } {
+ variable $path
+ upvar 0 $path data
+
+ Widget::init NoteBook $path $args
+
+ set data(base) 0
+ set data(select) ""
+ set data(pages) {}
+ set data(pages) {}
+ set data(cpt) 0
+ set data(realized) 0
+ set data(wpage) 0
+
+ _compute_height $path
+
+ # Create the canvas
+ set w [expr {[Widget::cget $path -width]+4}]
+ set h [expr {[Widget::cget $path -height]+$data(hpage)+4}]
+
+ frame $path -class NoteBook -borderwidth 0 -highlightthickness 0 \
+ -relief flat
+ eval [list canvas $path.c] [Widget::subcget $path .c] \
+ [list -relief flat -borderwidth 0 -highlightthickness 0 \
+ -width $w -height $h]
+ pack $path.c -expand yes -fill both
+
+ # Removing the Canvas global bindings from our canvas as
+ # application specific bindings on that tag may interfere with its
+ # operation here. [SF item #459033]
+
+ set bindings [bindtags $path.c]
+ set pos [lsearch -exact $bindings Canvas]
+ if {$pos >= 0} {
+ set bindings [lreplace $bindings $pos $pos]
+ }
+ bindtags $path.c $bindings
+
+ # Create the arrow button
+ eval [list ArrowButton::create $path.c.fg] [Widget::subcget $path .c.fg] \
+ [list -highlightthickness 0 -type button -dir left \
+ -armcommand [list NoteBook::_xview $path -1]]
+
+ eval [list ArrowButton::create $path.c.fd] [Widget::subcget $path .c.fd] \
+ [list -highlightthickness 0 -type button -dir right \
+ -armcommand [list NoteBook::_xview $path 1]]
+
+ Widget::create NoteBook $path
+
+ set bg [Widget::cget $path -background]
+ foreach {data(dbg) data(lbg)} [BWidget::get3dcolor $path $bg] {break}
+
+ return $path
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::configure
+# ---------------------------------------------------------------------------
+proc NoteBook::configure { path args } {
+ variable $path
+ upvar 0 $path data
+
+ set res [Widget::configure $path $args]
+ set redraw 0
+ set opts [list -font -homogeneous -tabpady]
+ foreach {cf ch cp} [eval Widget::hasChangedX $path $opts] {break}
+ if {$cf || $ch || $cp} {
+ if { $cf || $cp } {
+ _compute_height $path
+ }
+ _compute_width $path
+ set redraw 1
+ }
+ set chibd [Widget::hasChanged $path -internalborderwidth ibd]
+ set chbg [Widget::hasChanged $path -background bg]
+ if {$chibd || $chbg} {
+ foreach page $data(pages) {
+ $path.f$page configure \
+ -borderwidth $ibd -background $bg
+ }
+ }
+
+ if {$chbg} {
+ set col [BWidget::get3dcolor $path $bg]
+ set data(dbg) [lindex $col 0]
+ set data(lbg) [lindex $col 1]
+ set redraw 1
+ }
+ if { [Widget::hasChanged $path -foreground fg] ||
+ [Widget::hasChanged $path -borderwidth bd] ||
+ [Widget::hasChanged $path -arcradius radius] ||
+ [Widget::hasChanged $path -tabbevelsize bevel] ||
+ [Widget::hasChanged $path -side side] } {
+ set redraw 1
+ }
+ set wc [Widget::hasChanged $path -width w]
+ set hc [Widget::hasChanged $path -height h]
+ if { $wc || $hc } {
+ $path.c configure \
+ -width [expr {$w + 4}] \
+ -height [expr {$h + $data(hpage) + 4}]
+ }
+ if { $redraw } {
+ _redraw $path
+ }
+
+ return $res
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::cget
+# ---------------------------------------------------------------------------
+proc NoteBook::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::compute_size
+# ---------------------------------------------------------------------------
+proc NoteBook::compute_size { path } {
+ variable $path
+ upvar 0 $path data
+
+ set wmax 0
+ set hmax 0
+ update idletasks
+ foreach page $data(pages) {
+ set w [winfo reqwidth $path.f$page]
+ set h [winfo reqheight $path.f$page]
+ set wmax [expr {$w>$wmax ? $w : $wmax}]
+ set hmax [expr {$h>$hmax ? $h : $hmax}]
+ }
+ configure $path -width $wmax -height $hmax
+ # Sven... well ok so this is called twice in some cases...
+ NoteBook::_redraw $path
+ # Sven end
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::insert
+# ---------------------------------------------------------------------------
+proc NoteBook::insert { path index page args } {
+ variable $path
+ upvar 0 $path data
+
+ if { [lsearch -exact $data(pages) $page] != -1 } {
+ return -code error "page \"$page\" already exists"
+ }
+
+ set f $path.f$page
+ Widget::init NoteBook::Page $f $args
+
+ set data(pages) [linsert $data(pages) $index $page]
+ # If the page doesn't exist, create it; if it does reset its bg and ibd
+ if { ![winfo exists $f] } {
+ frame $f \
+ -relief flat \
+ -background [Widget::cget $path -background] \
+ -borderwidth [Widget::cget $path -internalborderwidth]
+ set data($page,realized) 0
+ } else {
+ $f configure \
+ -background [Widget::cget $path -background] \
+ -borderwidth [Widget::cget $path -internalborderwidth]
+ }
+ _compute_height $path
+ _compute_width $path
+ _draw_page $path $page 1
+ _set_help $path $page
+ _redraw $path
+
+ return $f
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::delete
+# ---------------------------------------------------------------------------
+proc NoteBook::delete { path page {destroyframe 1} } {
+ variable $path
+ upvar 0 $path data
+
+ set pos [_test_page $path $page]
+ set data(pages) [lreplace $data(pages) $pos $pos]
+ _compute_width $path
+ $path.c delete p:$page
+ if { $data(select) == $page } {
+ set data(select) ""
+ }
+ if { $pos < $data(base) } {
+ incr data(base) -1
+ }
+ if { $destroyframe } {
+ destroy $path.f$page
+ unset data($page,width) data($page,realized)
+ }
+ _redraw $path
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::itemconfigure
+# ---------------------------------------------------------------------------
+proc NoteBook::itemconfigure { path page args } {
+ _test_page $path $page
+ set res [_itemconfigure $path $page $args]
+ _redraw $path
+
+ return $res
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::itemcget
+# ---------------------------------------------------------------------------
+proc NoteBook::itemcget { path page option } {
+ _test_page $path $page
+ return [Widget::cget $path.f$page $option]
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::bindtabs
+# ---------------------------------------------------------------------------
+proc NoteBook::bindtabs { path event script } {
+ if { $script != "" } {
+ append script " \[NoteBook::_get_page_name [list $path] current 1\]"
+ $path.c bind "page" $event $script
+ } else {
+ $path.c bind "page" $event {}
+ }
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::move
+# ---------------------------------------------------------------------------
+proc NoteBook::move { path page index } {
+ variable $path
+ upvar 0 $path data
+
+ set pos [_test_page $path $page]
+ set data(pages) [linsert [lreplace $data(pages) $pos $pos] $index $page]
+ _redraw $path
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::raise
+# ---------------------------------------------------------------------------
+proc NoteBook::raise { path {page ""} } {
+ variable $path
+ upvar 0 $path data
+
+ if { $page != "" } {
+ _test_page $path $page
+ _select $path $page
+ }
+ return $data(select)
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::see
+# ---------------------------------------------------------------------------
+proc NoteBook::see { path page } {
+ variable $path
+ upvar 0 $path data
+
+ set pos [_test_page $path $page]
+ if { $pos < $data(base) } {
+ set data(base) $pos
+ _redraw $path
+ } else {
+ set w [expr {[winfo width $path]-1}]
+ set fpage [expr {[_get_x_page $path $pos] + $data($page,width) + 6}]
+ set idx $data(base)
+ while { $idx < $pos && $fpage > $w } {
+ set fpage [expr {$fpage - $data([lindex $data(pages) $idx],width)}]
+ incr idx
+ }
+ if { $idx != $data(base) } {
+ set data(base) $idx
+ _redraw $path
+ }
+ }
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::page
+# ---------------------------------------------------------------------------
+proc NoteBook::page { path first {last ""} } {
+ variable $path
+ upvar 0 $path data
+
+ if { $last == "" } {
+ return [lindex $data(pages) $first]
+ } else {
+ return [lrange $data(pages) $first $last]
+ }
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::pages
+# ---------------------------------------------------------------------------
+proc NoteBook::pages { path {first ""} {last ""}} {
+ variable $path
+ upvar 0 $path data
+
+ if { ![string length $first] } {
+ return $data(pages)
+ }
+
+ if { ![string length $last] } {
+ return [lindex $data(pages) $first]
+ } else {
+ return [lrange $data(pages) $first $last]
+ }
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::index
+# ---------------------------------------------------------------------------
+proc NoteBook::index { path page } {
+ variable $path
+ upvar 0 $path data
+
+ return [lsearch -exact $data(pages) $page]
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_destroy
+# ---------------------------------------------------------------------------
+proc NoteBook::_destroy { path } {
+ variable $path
+ upvar 0 $path data
+
+ foreach page $data(pages) {
+ Widget::destroy $path.f$page
+ }
+ Widget::destroy $path
+ unset data
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::getframe
+# ---------------------------------------------------------------------------
+proc NoteBook::getframe { path page } {
+ return $path.f$page
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_test_page
+# ---------------------------------------------------------------------------
+proc NoteBook::_test_page { path page } {
+ variable $path
+ upvar 0 $path data
+
+ if { [set pos [lsearch -exact $data(pages) $page]] == -1 } {
+ return -code error "page \"$page\" does not exists"
+ }
+ return $pos
+}
+
+proc NoteBook::_getoption { path page option } {
+ set value [Widget::cget $path.f$page $option]
+ if {![string length $value]} {
+ set value [Widget::cget $path $option]
+ }
+ return $value
+}
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_itemconfigure
+# ---------------------------------------------------------------------------
+proc NoteBook::_itemconfigure { path page lres } {
+ variable $path
+ upvar 0 $path data
+
+ set res [Widget::configure $path.f$page $lres]
+ if { [Widget::hasChanged $path.f$page -text foo] } {
+ _compute_width $path
+ } elseif { [Widget::hasChanged $path.f$page -image foo] } {
+ _compute_height $path
+ _compute_width $path
+ }
+ if { [Widget::hasChanged $path.f$page -state state] &&
+ $state == "disabled" && $data(select) == $page } {
+ set data(select) ""
+ }
+ _set_help $path $page
+ return $res
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_compute_width
+# ---------------------------------------------------------------------------
+proc NoteBook::_compute_width { path } {
+ variable $path
+ upvar 0 $path data
+
+ set wmax 0
+ set wtot 0
+ set hmax $data(hpage)
+ set font [Widget::cget $path -font]
+ if { ![info exists data(textid)] } {
+ set data(textid) [$path.c create text 0 -100 -font $font -anchor nw]
+ }
+ set id $data(textid)
+ $path.c itemconfigure $id -font $font
+ foreach page $data(pages) {
+ $path.c itemconfigure $id -text [Widget::cget $path.f$page -text]
+ # Get the bbox for this text to determine its width, then substract
+ # 6 from the width to account for canvas bbox oddness w.r.t. widths of
+ # simple text.
+ foreach {x1 y1 x2 y2} [$path.c bbox $id] break
+ set x2 [expr {$x2 - 6}]
+ set wtext [expr {$x2 - $x1 + 20}]
+ if { [set img [Widget::cget $path.f$page -image]] != "" } {
+ set wtext [expr {$wtext + [image width $img] + 4}]
+ set himg [expr {[image height $img] + 6}]
+ if { $himg > $hmax } {
+ set hmax $himg
+ }
+ }
+ set wmax [expr {$wtext > $wmax ? $wtext : $wmax}]
+ incr wtot $wtext
+ set data($page,width) $wtext
+ }
+ if { [Widget::cget $path -homogeneous] } {
+ foreach page $data(pages) {
+ set data($page,width) $wmax
+ }
+ set wtot [expr {$wmax * [llength $data(pages)]}]
+ }
+ set data(hpage) $hmax
+ set data(wpage) $wtot
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_compute_height
+# ---------------------------------------------------------------------------
+proc NoteBook::_compute_height { path } {
+ variable $path
+ upvar 0 $path data
+
+ set font [Widget::cget $path -font]
+ set pady0 [Widget::_get_padding $path -tabpady 0]
+ set pady1 [Widget::_get_padding $path -tabpady 1]
+ set metrics [font metrics $font -linespace]
+ set imgh 0
+ set lines 1
+ foreach page $data(pages) {
+ set img [Widget::cget $path.f$page -image]
+ set text [Widget::cget $path.f$page -text]
+ set len [llength [split $text \n]]
+ if {$len > $lines} { set lines $len}
+ if {$img != ""} {
+ set h [image height $img]
+ if {$h > $imgh} { set imgh $h }
+ }
+ }
+ set height [expr {$metrics * $lines}]
+ if {$imgh > $height} { set height $imgh }
+ set data(hpage) [expr {$height + $pady0 + $pady1}]
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_get_x_page
+# ---------------------------------------------------------------------------
+proc NoteBook::_get_x_page { path pos } {
+ variable _warrow
+ variable $path
+ upvar 0 $path data
+
+ set base $data(base)
+ # notebook tabs start flush with the left side of the notebook
+ set x 0
+ if { $pos < $base } {
+ foreach page [lrange $data(pages) $pos [expr {$base-1}]] {
+ incr x [expr {-$data($page,width)}]
+ }
+ } elseif { $pos > $base } {
+ foreach page [lrange $data(pages) $base [expr {$pos-1}]] {
+ incr x $data($page,width)
+ }
+ }
+ return $x
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_xview
+# ---------------------------------------------------------------------------
+proc NoteBook::_xview { path inc } {
+ variable $path
+ upvar 0 $path data
+
+ if { $inc == -1 } {
+ set base [expr {$data(base)-1}]
+ set dx $data([lindex $data(pages) $base],width)
+ } else {
+ set dx [expr {-$data([lindex $data(pages) $data(base)],width)}]
+ set base [expr {$data(base)+1}]
+ }
+
+ if { $base >= 0 && $base < [llength $data(pages)] } {
+ set data(base) $base
+ $path.c move page $dx 0
+ _draw_area $path
+ _draw_arrows $path
+ }
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_highlight
+# ---------------------------------------------------------------------------
+proc NoteBook::_highlight { type path page } {
+ variable $path
+ upvar 0 $path data
+
+ if { [string equal [Widget::cget $path.f$page -state] "disabled"] } {
+ return
+ }
+
+ switch -- $type {
+ on {
+ $path.c itemconfigure "$page:poly" \
+ -fill [_getoption $path $page -activebackground]
+ $path.c itemconfigure "$page:text" \
+ -fill [_getoption $path $page -activeforeground]
+ }
+ off {
+ $path.c itemconfigure "$page:poly" \
+ -fill [_getoption $path $page -background]
+ $path.c itemconfigure "$page:text" \
+ -fill [_getoption $path $page -foreground]
+ }
+ }
+}
+
+
+# ---------------------------------------------------------------------------
+# Command NoteBook::_select
+# ---------------------------------------------------------------------------
+proc NoteBook::_select { path page } {
+ variable $path
+ upvar 0 $path data
+
+ if {![string equal [Widget::cget $path.f$page -state] "normal"]} { return }
+
+ set oldsel $data(select)
+
+ if {[string equal $page $oldsel]} { return }
+
+ if { ![string equal $oldsel ""] } {
+ set cmd [Widget::cget $path.f$oldsel -leavecmd]
+ if { ![string equal $cmd ""] } {
+ set code [catch {uplevel \#0 $cmd} res]
+ if { $code == 1 || $res == 0 } {
+ return -code $code $res
+ }
+ }
+ set data(select) ""
+ _draw_page $path $oldsel 0
+ }
+
+ set data(select) $page
+ if { ![string equal $page ""] } {
+ if { !$data($page,realized) } {
+ set data($page,realized) 1
+ set cmd [Widget::cget $path.f$page -createcmd]
+ if { ![string equal $cmd ""] } {
+ uplevel \#0 $cmd
+ }
+ }
+ set cmd [Widget::cget $path.f$page -raisecmd]
+ if { ![string equal $cmd ""] } {
+ uplevel \#0 $cmd
+ }
+ _draw_page $path $page 0
+ }
+
+ _draw_area $path
+}
+
+
+# -----------------------------------------------------------------------------
+# Command NoteBook::_redraw
+# -----------------------------------------------------------------------------
+proc NoteBook::_redraw { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { !$data(realized) } { return }
+
+ _compute_height $path
+
+ foreach page $data(pages) {
+ _draw_page $path $page 0
+ }
+ _draw_area $path
+ _draw_arrows $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command NoteBook::_draw_page
+# ----------------------------------------------------------------------------
+proc NoteBook::_draw_page { path page create } {
+ variable $path
+ upvar 0 $path data
+
+ # --- calcul des coordonnees et des couleurs de l'onglet ------------------
+ set pos [lsearch -exact $data(pages) $page]
+ set bg [_getoption $path $page -background]
+
+ # lookup the tab colors
+ set fgt $data(lbg)
+ set fgb $data(dbg)
+
+ set h $data(hpage)
+ set xd [_get_x_page $path $pos]
+ set xf [expr {$xd + $data($page,width)}]
+
+ # Set the initial text offsets -- a few pixels down, centered left-to-right
+ set textOffsetY [expr [Widget::_get_padding $path -tabpady 0] + 3]
+ set textOffsetX 9
+
+ # Coordinates of the tab corners are:
+ # c3 c4
+ #
+ # c2 c5
+ #
+ # c1 c6
+ #
+ # where
+ # c1 = $xd, $h
+ # c2 = $xd+$xBevel, $arcRadius+2
+ # c3 = $xd+$xBevel+$arcRadius, $arcRadius
+ # c4 = $xf+1-$xBevel, $arcRadius
+ # c5 = $xf+$arcRadius-$xBevel, $arcRadius+2
+ # c6 = $xf+$arcRadius, $h
+
+ set top 2
+ set arcRadius [Widget::cget $path -arcradius]
+ set xBevel [Widget::cget $path -tabbevelsize]
+
+ if { $data(select) != $page } {
+ if { $pos == 0 } {
+ # The leftmost page is a special case -- it is drawn with its
+ # tab a little indented. To achieve this, we incr xd. We also
+ # decr textOffsetX, so that the text doesn't move left/right.
+ incr xd 2
+ incr textOffsetX -2
+ }
+ } else {
+ # The selected page's text is raised higher than the others
+ incr top -2
+ }
+
+ # Precompute some coord values that we use a lot
+ set topPlusRadius [expr {$top + $arcRadius}]
+ set rightPlusRadius [expr {$xf + $arcRadius}]
+ set leftPlusRadius [expr {$xd + $arcRadius}]
+
+ # Sven
+ set side [Widget::cget $path -side]
+ set tabsOnBottom [string equal $side "bottom"]
+
+ set h1 [expr {[winfo height $path]}]
+ set bd [Widget::cget $path -borderwidth]
+ if {$bd < 1} { set bd 1 }
+
+ if { $tabsOnBottom } {
+ # adjust to keep bottom edge in view
+ incr h1 -1
+ set top [expr {$top * -1}]
+ set topPlusRadius [expr {$topPlusRadius * -1}]
+ # Hrm... the canvas has an issue with drawing diagonal segments
+ # of lines from the bottom to the top, so we have to draw this line
+ # backwards (ie, lt is actually the bottom, drawn from right to left)
+ set lt [list \
+ $rightPlusRadius [expr {$h1-$h-1}] \
+ [expr {$rightPlusRadius - $xBevel}] [expr {$h1 + $topPlusRadius}] \
+ [expr {$xf - $xBevel}] [expr {$h1 + $top}] \
+ [expr {$leftPlusRadius + $xBevel}] [expr {$h1 + $top}] \
+ ]
+ set lb [list \
+ [expr {$leftPlusRadius + $xBevel}] [expr {$h1 + $top}] \
+ [expr {$xd + $xBevel}] [expr {$h1 + $topPlusRadius}] \
+ $xd [expr {$h1-$h-1}] \
+ ]
+ # Because we have to do this funky reverse order thing, we have to
+ # swap the top/bottom colors too.
+ set tmp $fgt
+ set fgt $fgb
+ set fgb $tmp
+ } else {
+ set lt [list \
+ $xd $h \
+ [expr {$xd + $xBevel}] $topPlusRadius \
+ [expr {$leftPlusRadius + $xBevel}] $top \
+ [expr {$xf + 1 - $xBevel}] $top \
+ ]
+ set lb [list \
+ [expr {$xf + 1 - $xBevel}] [expr {$top + 1}] \
+ [expr {$rightPlusRadius - $xBevel}] $topPlusRadius \
+ $rightPlusRadius $h \
+ ]
+ }
+
+ set img [Widget::cget $path.f$page -image]
+
+ set ytext $top
+ if { $tabsOnBottom } {
+ # The "+ 2" below moves the text closer to the bottom of the tab,
+ # so it doesn't look so cramped. I should be able to achieve the
+ # same goal by changing the anchor of the text and using this formula:
+ # ytext = $top + $h1 - $textOffsetY
+ # but that doesn't quite work (I think the linespace from the text
+ # gets in the way)
+ incr ytext [expr {$h1 - $h + 2}]
+ }
+ incr ytext $textOffsetY
+
+ set xtext [expr {$xd + $textOffsetX}]
+ if { $img != "" } {
+ # if there's an image, put it on the left and move the text right
+ set ximg $xtext
+ incr xtext [expr {[image width $img] + 2}]
+ }
+
+ if { $data(select) == $page } {
+ set bd [Widget::cget $path -borderwidth]
+ if {$bd < 1} { set bd 1 }
+ set fg [_getoption $path $page -foreground]
+ } else {
+ set bd 1
+ if { [Widget::cget $path.f$page -state] == "normal" } {
+ set fg [_getoption $path $page -foreground]
+ } else {
+ set fg [_getoption $path $page -disabledforeground]
+ }
+ }
+
+ # --- creation ou modification de l'onglet --------------------------------
+ # Sven
+ if { $create } {
+ # Create the tab region
+ eval [list $path.c create polygon] [concat $lt $lb] [list \
+ -tags [list page p:$page $page:poly] \
+ -outline $bg \
+ -fill $bg \
+ ]
+ eval [list $path.c create line] $lt [list \
+ -tags [list page p:$page $page:top top] -fill $fgt -width $bd]
+ eval [list $path.c create line] $lb [list \
+ -tags [list page p:$page $page:bot bot] -fill $fgb -width $bd]
+ $path.c create text $xtext $ytext \
+ -text [Widget::cget $path.f$page -text] \
+ -font [Widget::cget $path -font] \
+ -fill $fg \
+ -anchor nw \
+ -tags [list page p:$page $page:text]
+
+ $path.c bind p:$page <ButtonPress-1> \
+ [list NoteBook::_select $path $page]
+ $path.c bind p:$page <Enter> \
+ [list NoteBook::_highlight on $path $page]
+ $path.c bind p:$page <Leave> \
+ [list NoteBook::_highlight off $path $page]
+ } else {
+ $path.c coords "$page:text" $xtext $ytext
+
+ $path.c itemconfigure "$page:text" \
+ -text [Widget::cget $path.f$page -text] \
+ -font [Widget::cget $path -font] \
+ -fill $fg
+ }
+ eval [list $path.c coords "$page:poly"] [concat $lt $lb]
+ eval [list $path.c coords "$page:top"] $lt
+ eval [list $path.c coords "$page:bot"] $lb
+ $path.c itemconfigure "$page:poly" -fill $bg -outline $bg
+ $path.c itemconfigure "$page:top" -fill $fgt -width $bd
+ $path.c itemconfigure "$page:bot" -fill $fgb -width $bd
+
+ # Sven end
+
+ if { $img != "" } {
+ # Sven
+ set id [$path.c find withtag $page:img]
+ if { [string equal $id ""] } {
+ set id [$path.c create image $ximg $ytext \
+ -anchor nw \
+ -tags [list page p:$page $page:img]]
+ }
+ $path.c coords $id $ximg $ytext
+ $path.c itemconfigure $id -image $img
+ # Sven end
+ } else {
+ $path.c delete $page:img
+ }
+
+ if { $data(select) == $page } {
+ $path.c raise p:$page
+ } elseif { $pos == 0 } {
+ if { $data(select) == "" } {
+ $path.c raise p:$page
+ } else {
+ $path.c lower p:$page p:$data(select)
+ }
+ } else {
+ set pred [lindex $data(pages) [expr {$pos-1}]]
+ if { $data(select) != $pred || $pos == 1 } {
+ $path.c lower p:$page p:$pred
+ } else {
+ $path.c lower p:$page p:[lindex $data(pages) [expr {$pos-2}]]
+ }
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command NoteBook::_draw_arrows
+# -----------------------------------------------------------------------------
+proc NoteBook::_draw_arrows { path } {
+ variable _warrow
+ variable $path
+ upvar 0 $path data
+
+ set w [expr {[winfo width $path]-1}]
+ set h [expr {$data(hpage)-1}]
+ set nbpages [llength $data(pages)]
+ set xl 0
+ set xr [expr {$w-$_warrow+1}]
+ # Sven
+ set side [Widget::cget $path -side]
+ if { [string equal $side "bottom"] } {
+ set h1 [expr {[winfo height $path]-1}]
+ set bd [Widget::cget $path -borderwidth]
+ if {$bd < 1} { set bd 1 }
+ set y0 [expr {$h1 - $data(hpage) + $bd}]
+ } else {
+ set y0 1
+ }
+ # Sven end (all y positions where replaced with $y0 later)
+
+ if { $data(base) > 0 } {
+ # Sven
+ if { ![llength [$path.c find withtag "leftarrow"]] } {
+ $path.c create window $xl $y0 \
+ -width $_warrow \
+ -height $h \
+ -anchor nw \
+ -window $path.c.fg \
+ -tags "leftarrow"
+ } else {
+ $path.c coords "leftarrow" $xl $y0
+ $path.c itemconfigure "leftarrow" -width $_warrow -height $h
+ }
+ # Sven end
+ } else {
+ $path.c delete "leftarrow"
+ }
+
+ if { $data(base) < $nbpages-1 &&
+ $data(wpage) + [_get_x_page $path 0] + 6 > $w } {
+ # Sven
+ if { ![llength [$path.c find withtag "rightarrow"]] } {
+ $path.c create window $xr $y0 \
+ -width $_warrow \
+ -height $h \
+ -window $path.c.fd \
+ -anchor nw \
+ -tags "rightarrow"
+ } else {
+ $path.c coords "rightarrow" $xr $y0
+ $path.c itemconfigure "rightarrow" -width $_warrow -height $h
+ }
+ # Sven end
+ } else {
+ $path.c delete "rightarrow"
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command NoteBook::_draw_area
+# -----------------------------------------------------------------------------
+proc NoteBook::_draw_area { path } {
+ variable $path
+ upvar 0 $path data
+
+ set w [expr {[winfo width $path] - 1}]
+ set h [expr {[winfo height $path] - 1}]
+ set bd [Widget::cget $path -borderwidth]
+ if {$bd < 1} { set bd 1 }
+ set x0 [expr {$bd - 1}]
+
+ set arcRadius [Widget::cget $path -arcradius]
+
+ # Sven
+ set side [Widget::cget $path -side]
+ if {"$side" == "bottom"} {
+ set y0 0
+ set y1 [expr {$h - $data(hpage)}]
+ set yo $y1
+ } else {
+ set y0 $data(hpage)
+ set y1 $h
+ set yo [expr {$h-$y0}]
+ }
+ # Sven end
+ set dbg $data(dbg)
+ set sel $data(select)
+ if { $sel == "" } {
+ set xd [expr {$w/2}]
+ set xf $xd
+ set lbg $data(dbg)
+ } else {
+ set xd [_get_x_page $path [lsearch -exact $data(pages) $data(select)]]
+ set xf [expr {$xd + $data($sel,width) + $arcRadius + 1}]
+ set lbg $data(lbg)
+ }
+
+ # Sven
+ if { [llength [$path.c find withtag rect]] == 0} {
+ $path.c create line $xd $y0 $x0 $y0 $x0 $y1 \
+ -tags "rect toprect1"
+ $path.c create line $w $y0 $xf $y0 \
+ -tags "rect toprect2"
+ $path.c create line 1 $h $w $h $w $y0 \
+ -tags "rect botrect"
+ }
+ if {"$side" == "bottom"} {
+ $path.c coords "toprect1" $w $y0 $x0 $y0 $x0 $y1
+ $path.c coords "toprect2" $x0 $y1 $xd $y1
+ $path.c coords "botrect" $xf $y1 $w $y1 $w $y0
+ $path.c itemconfigure "toprect1" -fill $lbg -width $bd
+ $path.c itemconfigure "toprect2" -fill $dbg -width $bd
+ $path.c itemconfigure "botrect" -fill $dbg -width $bd
+ } else {
+ $path.c coords "toprect1" $xd $y0 $x0 $y0 $x0 $y1
+ $path.c coords "toprect2" $w $y0 $xf $y0
+ $path.c coords "botrect" $x0 $h $w $h $w $y0
+ $path.c itemconfigure "toprect1" -fill $lbg -width $bd
+ $path.c itemconfigure "toprect2" -fill $lbg -width $bd
+ $path.c itemconfigure "botrect" -fill $dbg -width $bd
+ }
+ $path.c raise "rect"
+ # Sven end
+
+ if { $sel != "" } {
+ # Sven
+ if { [llength [$path.c find withtag "window"]] == 0 } {
+ $path.c create window 2 [expr {$y0+1}] \
+ -width [expr {$w-3}] \
+ -height [expr {$yo-3}] \
+ -anchor nw \
+ -tags "window" \
+ -window $path.f$sel
+ }
+ $path.c coords "window" 2 [expr {$y0+1}]
+ $path.c itemconfigure "window" \
+ -width [expr {$w-3}] \
+ -height [expr {$yo-3}] \
+ -window $path.f$sel
+ # Sven end
+ } else {
+ $path.c delete "window"
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command NoteBook::_resize
+# -----------------------------------------------------------------------------
+proc NoteBook::_resize { path } {
+ variable $path
+ upvar 0 $path data
+
+ if {!$data(realized)} {
+ if { [set width [Widget::cget $path -width]] == 0 ||
+ [set height [Widget::cget $path -height]] == 0 } {
+ compute_size $path
+ }
+ set data(realized) 1
+ }
+
+ NoteBook::_redraw $path
+}
+
+
+# Tree::_set_help --
+#
+# Register dynamic help for a node in the tree.
+#
+# Arguments:
+# path Tree to query
+# node Node in the tree
+# force Optional argument to force a reset of the help
+#
+# Results:
+# none
+# Tree::_set_help --
+#
+# Register dynamic help for a node in the tree.
+#
+# Arguments:
+# path Tree to query
+# node Node in the tree
+# force Optional argument to force a reset of the help
+#
+# Results:
+# none
+proc NoteBook::_set_help { path page } {
+ Widget::getVariable $path help
+
+ set item $path.f$page
+ set opts [list -helptype -helptext -helpvar]
+ foreach {cty ctx cv} [eval [list Widget::hasChangedX $item] $opts] break
+ set text [Widget::getoption $item -helptext]
+
+ ## If we've never set help for this item before, and text is not blank,
+ ## we need to setup help. We also need to reset help if any of the
+ ## options have changed.
+ if { (![info exists help($page)] && $text != "") || $cty || $ctx || $cv } {
+ set help($page) 1
+ set type [Widget::getoption $item -helptype]
+ switch $type {
+ balloon {
+ DynamicHelp::register $path.c balloon p:$page $text
+ }
+ variable {
+ set var [Widget::getoption $item -helpvar]
+ DynamicHelp::register $path.c variable p:$page $var $text
+ }
+ }
+ }
+}
+
+
+proc NoteBook::_get_page_name { path {item current} {tagindex end-1} } {
+ return [string range [lindex [$path.c gettags $item] $tagindex] 2 end]
+}
diff --git a/modules/tclsci/tcl/BWidget/pagesmgr.tcl b/modules/tclsci/tcl/BWidget/pagesmgr.tcl
new file mode 100755
index 000000000..d6ce1b626
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/pagesmgr.tcl
@@ -0,0 +1,294 @@
+# ------------------------------------------------------------------------------
+# pagesmgr.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: pagesmgr.tcl,v 1.6 2003/10/20 21:23:52 damonc Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - PagesManager::create
+# - PagesManager::configure
+# - PagesManager::cget
+# - PagesManager::compute_size
+# - PagesManager::add
+# - PagesManager::delete
+# - PagesManager::raise
+# - PagesManager::page
+# - PagesManager::pages
+# - PagesManager::getframe
+# - PagesManager::_test_page
+# - PagesManager::_select
+# - PagesManager::_redraw
+# - PagesManager::_draw_area
+# - PagesManager::_realize
+# ------------------------------------------------------------------------------
+package require Tcl 8.1.1
+
+namespace eval PagesManager {
+ Widget::define PagesManager pagesmgr
+
+ Widget::declare PagesManager {
+ {-background TkResource "" 0 frame}
+ {-cursor TkResource "" 0 frame}
+ {-width Int 0 0 "%d >= 0"}
+ {-height Int 0 0 "%d >= 0"}
+ }
+
+ Widget::addmap PagesManager "" :cmd { -width {} -height {} -cursor {} }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::create
+# ------------------------------------------------------------------------------
+proc PagesManager::create { path args } {
+ variable $path
+ upvar 0 $path data
+
+ Widget::init PagesManager $path $args
+
+ set data(select) ""
+ set data(pages) {}
+ set data(cpt) 0
+ set data(realized) 0
+
+ # --- creation du canvas -----------------------------------------------------------------
+ eval canvas $path -relief flat -bd 0 -highlightthickness 0 \
+ [Widget::subcget $path :cmd]
+
+ bind $path <Configure> [list PagesManager::_realize $path]
+ bind $path <Destroy> [list PagesManager::_destroy $path]
+
+ return [Widget::create PagesManager $path]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::configure
+# ------------------------------------------------------------------------------
+proc PagesManager::configure { path args } {
+ return [Widget::configure $path $args]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::cget
+# ------------------------------------------------------------------------------
+proc PagesManager::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::compute_size
+# ------------------------------------------------------------------------------
+proc PagesManager::compute_size { path } {
+ variable $path
+ upvar 0 $path data
+
+ set wmax 0
+ set hmax 0
+ update idletasks
+ foreach page $data(pages) {
+ set w [winfo reqwidth $path.f$page]
+ set h [winfo reqheight $path.f$page]
+ set wmax [expr {$w>$wmax ? $w : $wmax}]
+ set hmax [expr {$h>$hmax ? $h : $hmax}]
+ }
+ configure $path -width $wmax -height $hmax
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::add
+# ------------------------------------------------------------------------------
+proc PagesManager::add { path page } {
+ variable $path
+ upvar 0 $path data
+
+ if { [lsearch -exact $data(pages) $page] != -1 } {
+ return -code error "page \"$page\" already exists"
+ }
+
+ lappend data(pages) $page
+
+ frame $path.f$page -relief flat \
+ -background [Widget::cget $path -background] -borderwidth 0
+
+ return $path.f$page
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::delete
+# ------------------------------------------------------------------------------
+proc PagesManager::delete { path page } {
+ variable $path
+ upvar 0 $path data
+
+ set pos [_test_page $path $page]
+ set data(pages) [lreplace $data(pages) $pos $pos]
+ if { $data(select) == $page } {
+ set data(select) ""
+ }
+ destroy $path.f$page
+ _redraw $path
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::raise
+# ------------------------------------------------------------------------------
+proc PagesManager::raise { path {page ""} } {
+ variable $path
+ upvar 0 $path data
+
+ if { $page != "" } {
+ _test_page $path $page
+ _select $path $page
+ }
+ return $data(select)
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::page - deprecated, use pages
+# ------------------------------------------------------------------------------
+proc PagesManager::page { path first {last ""} } {
+ variable $path
+ upvar 0 $path data
+
+ if { $last == "" } {
+ return [lindex $data(pages) $first]
+ } else {
+ return [lrange $data(pages) $first $last]
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::pages
+# ------------------------------------------------------------------------------
+proc PagesManager::pages { path {first ""} {last ""} } {
+ variable $path
+ upvar 0 $path data
+
+ if { ![string length $first] } {
+ return $data(pages)
+ }
+
+ if { ![string length $last] } {
+ return [lindex $data(pages) $first]
+ } else {
+ return [lrange $data(pages) $first $last]
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::getframe
+# ------------------------------------------------------------------------------
+proc PagesManager::getframe { path page } {
+ return $path.f$page
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::_test_page
+# ------------------------------------------------------------------------------
+proc PagesManager::_test_page { path page } {
+ variable $path
+ upvar 0 $path data
+
+ if { [set pos [lsearch $data(pages) $page]] == -1 } {
+ return -code error "page \"$page\" does not exists"
+ }
+ return $pos
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::_select
+# ------------------------------------------------------------------------------
+proc PagesManager::_select { path page } {
+ variable $path
+ upvar 0 $path data
+
+ set oldsel $data(select)
+ if { $page != $oldsel } {
+ set data(select) $page
+ _draw_area $path
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::_redraw
+# ------------------------------------------------------------------------------
+proc PagesManager::_redraw { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { !$data(realized) } {
+ return
+ }
+ _draw_area $path
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::_draw_area
+# ------------------------------------------------------------------------------
+proc PagesManager::_draw_area { path } {
+ variable $path
+ upvar 0 $path data
+
+ set w [winfo width $path]
+ set h [winfo height $path]
+ set sel $data(select)
+ if { $sel != "" } {
+ if { [llength [$path:cmd find withtag "window"]] } {
+ $path:cmd coords "window" 0 0
+ $path:cmd itemconfigure "window" \
+ -width $w \
+ -height $h \
+ -window $path.f$sel
+ } else {
+ $path:cmd create window 0 0 \
+ -width $w \
+ -height $h \
+ -anchor nw \
+ -tags "window" \
+ -window $path.f$sel
+ }
+ } else {
+ $path:cmd delete "window"
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::_realize
+# ------------------------------------------------------------------------------
+proc PagesManager::_realize { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { [set width [Widget::cget $path -width]] == 0 ||
+ [set height [Widget::cget $path -height]] == 0 } {
+ compute_size $path
+ }
+
+ set data(realized) 1
+ _draw_area $path
+ bind $path <Configure> [list PagesManager::_draw_area $path]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command PagesManager::_destroy
+# ------------------------------------------------------------------------------
+proc PagesManager::_destroy { path } {
+ variable $path
+ upvar 0 $path data
+ Widget::destroy $path
+ unset data
+}
diff --git a/modules/tclsci/tcl/BWidget/panedw.tcl b/modules/tclsci/tcl/BWidget/panedw.tcl
new file mode 100755
index 000000000..7c72bfea0
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/panedw.tcl
@@ -0,0 +1,385 @@
+# ----------------------------------------------------------------------------
+# panedw.tcl
+# This file is part of Unifix BWidget Toolkit
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - PanedWindow::create
+# - PanedWindow::configure
+# - PanedWindow::cget
+# - PanedWindow::add
+# - PanedWindow::getframe
+# - PanedWindow::_apply_weights
+# - PanedWindow::_destroy
+# - PanedWindow::_beg_move_sash
+# - PanedWindow::_move_sash
+# - PanedWindow::_end_move_sash
+# - PanedWindow::_realize
+# ----------------------------------------------------------------------------
+
+# JDC: added option to choose behavior of weights
+# -weights extra : only apply weights to extra space (as current (>= 1.3.1) with grid command)
+# -weights available : apply weights to total available space (as before (<1.3.1) with place command)
+
+namespace eval PanedWindow {
+ Widget::define PanedWindow panedw
+
+ namespace eval Pane {
+ Widget::declare PanedWindow::Pane {
+ {-minsize Int 0 0 "%d >= 0"}
+ {-weight Int 1 0 "%d >= 0"}
+ }
+ }
+
+ Widget::declare PanedWindow {
+ {-side Enum top 1 {top left bottom right}}
+ {-width Int 10 1 "%d >=3"}
+ {-pad Int 4 1 "%d >= 0"}
+ {-background TkResource "" 0 frame}
+ {-bg Synonym -background}
+ {-activator Enum "" 1 {line button}}
+ {-weights Enum extra 1 {extra available}}
+ }
+
+ variable _panedw
+}
+
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::create
+# ----------------------------------------------------------------------------
+proc PanedWindow::create { path args } {
+ variable _panedw
+
+ Widget::init PanedWindow $path $args
+
+ frame $path -background [Widget::cget $path -background] -class PanedWindow
+ set _panedw($path,nbpanes) 0
+ set _panedw($path,weights) ""
+ set _panedw($path,configuredone) 0
+
+ set activator [Widget::getoption $path -activator]
+ if {[string equal $activator ""]} {
+ if { $::tcl_platform(platform) != "windows" } {
+ Widget::setMegawidgetOption $path -activator button
+ } else {
+ Widget::setMegawidgetOption $path -activator line
+ }
+ }
+ if {[string equal [Widget::getoption $path -activator] "line"]} {
+ Widget::setMegawidgetOption $path -width 3
+ }
+
+ bind $path <Configure> [list PanedWindow::_realize $path %w %h]
+ bind $path <Destroy> [list PanedWindow::_destroy $path]
+
+ return [Widget::create PanedWindow $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::configure
+# ----------------------------------------------------------------------------
+proc PanedWindow::configure { path args } {
+ variable _panedw
+
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -background bg] && $_panedw($path,nbpanes) > 0 } {
+ $path:cmd configure -background $bg
+ $path.f0 configure -background $bg
+ for {set i 1} {$i < $_panedw($path,nbpanes)} {incr i} {
+ set frame $path.sash$i
+ $frame configure -background $bg
+ $frame.sep configure -background $bg
+ $frame.but configure -background $bg
+ $path.f$i configure -background $bg
+ $path.f$i.frame configure -background $bg
+ }
+ }
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::cget
+# ----------------------------------------------------------------------------
+proc PanedWindow::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::add
+# ----------------------------------------------------------------------------
+proc PanedWindow::add { path args } {
+ variable _panedw
+
+ set num $_panedw($path,nbpanes)
+ Widget::init PanedWindow::Pane $path.f$num $args
+ set bg [Widget::getoption $path -background]
+
+ set wbut [Widget::getoption $path -width]
+ set pad [Widget::getoption $path -pad]
+ set width [expr {$wbut+2*$pad}]
+ set side [Widget::getoption $path -side]
+ set weight [Widget::getoption $path.f$num -weight]
+ lappend _panedw($path,weights) $weight
+
+ if { $num > 0 } {
+ set frame [frame $path.sash$num -relief flat -bd 0 \
+ -highlightthickness 0 -width $width -height $width -bg $bg]
+ set sep [frame $frame.sep -bd 5 -relief raised \
+ -highlightthickness 0 -bg $bg]
+ set but [frame $frame.but -bd 1 -relief raised \
+ -highlightthickness 0 -bg $bg -width $wbut -height $wbut]
+ set sepsize 2
+
+ set activator [Widget::getoption $path -activator]
+ if {$activator == "button"} {
+ set activator $but
+ set placeButton 1
+ } else {
+ set activator $sep
+ $sep configure -bd 1
+ set placeButton 0
+ }
+ if {[string equal $side "top"] || [string equal $side "bottom"]} {
+ place $sep -relx 0.5 -y 0 -width $sepsize -relheight 1.0 -anchor n
+ if { $placeButton } {
+ if {[string equal $side "top"]} {
+ place $but -relx 0.5 -y [expr {6+$wbut/2}] -anchor c
+ } else {
+ place $but -relx 0.5 -rely 1.0 -y [expr {-6-$wbut/2}] \
+ -anchor c
+ }
+ }
+ $activator configure -cursor sb_h_double_arrow
+ grid $frame -column [expr {2*$num-1}] -row 0 -sticky ns
+ grid columnconfigure $path [expr {2*$num-1}] -weight 0
+ } else {
+ place $sep -x 0 -rely 0.5 -height $sepsize -relwidth 1.0 -anchor w
+ if { $placeButton } {
+ if {[string equal $side "left"]} {
+ place $but -rely 0.5 -x [expr {6+$wbut/2}] -anchor c
+ } else {
+ place $but -rely 0.5 -relx 1.0 -x [expr {-6-$wbut/2}] \
+ -anchor c
+ }
+ }
+ $activator configure -cursor sb_v_double_arrow
+ grid $frame -row [expr {2*$num-1}] -column 0 -sticky ew
+ grid rowconfigure $path [expr {2*$num-1}] -weight 0
+ }
+ bind $activator <ButtonPress-1> \
+ [list PanedWindow::_beg_move_sash $path $num %X %Y]
+ } else {
+ if { [string equal $side "top"] || \
+ [string equal $side "bottom"] } {
+ grid rowconfigure $path 0 -weight 1
+ } else {
+ grid columnconfigure $path 0 -weight 1
+ }
+ }
+
+ set pane [frame $path.f$num -bd 0 -relief flat \
+ -highlightthickness 0 -bg $bg]
+ set user [frame $path.f$num.frame -bd 0 -relief flat \
+ -highlightthickness 0 -bg $bg]
+ if { [string equal $side "top"] || [string equal $side "bottom"] } {
+ grid $pane -column [expr {2*$num}] -row 0 -sticky nsew
+ grid columnconfigure $path [expr {2*$num}] -weight $weight
+ } else {
+ grid $pane -row [expr {2*$num}] -column 0 -sticky nsew
+ grid rowconfigure $path [expr {2*$num}] -weight $weight
+ }
+ pack $user -fill both -expand yes
+ incr _panedw($path,nbpanes)
+ if {$_panedw($path,configuredone)} {
+ _realize $path [winfo width $path] [winfo height $path]
+ }
+
+ return $user
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::getframe
+# ----------------------------------------------------------------------------
+proc PanedWindow::getframe { path index } {
+ if { [winfo exists $path.f$index.frame] } {
+ return $path.f$index.frame
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::_beg_move_sash
+# ----------------------------------------------------------------------------
+proc PanedWindow::_beg_move_sash { path num x y } {
+ variable _panedw
+
+ set fprev $path.f[expr {$num-1}]
+ set fnext $path.f$num
+ set wsash [expr {[Widget::getoption $path -width] + 2*[Widget::getoption $path -pad]}]
+
+ $path.sash$num.but configure -relief sunken
+ set top [toplevel $path.sash -borderwidth 1 -relief raised]
+
+ set minszg [Widget::getoption $fprev -minsize]
+ set minszd [Widget::getoption $fnext -minsize]
+ set side [Widget::getoption $path -side]
+
+ if { [string equal $side "top"] || [string equal $side "bottom"] } {
+ $top configure -cursor sb_h_double_arrow
+ set h [winfo height $path]
+ set yr [winfo rooty $path.sash$num]
+ set xmin [expr {$wsash/2+[winfo rootx $fprev]+$minszg}]
+ set xmax [expr {-$wsash/2-1+[winfo rootx $fnext]+[winfo width $fnext]-$minszd}]
+ wm overrideredirect $top 1
+ wm geom $top "2x${h}+$x+$yr"
+
+ update idletasks
+ grab set $top
+ bind $top <ButtonRelease-1> [list PanedWindow::_end_move_sash $path $top $num $xmin $xmax %X rootx width]
+ bind $top <Motion> [list PanedWindow::_move_sash $top $xmin $xmax %X +%%d+$yr]
+ _move_sash $top $xmin $xmax $x "+%d+$yr"
+ } else {
+ $top configure -cursor sb_v_double_arrow
+ set w [winfo width $path]
+ set xr [winfo rootx $path.sash$num]
+ set ymin [expr {$wsash/2+[winfo rooty $fprev]+$minszg}]
+ set ymax [expr {-$wsash/2-1+[winfo rooty $fnext]+[winfo height $fnext]-$minszd}]
+ wm overrideredirect $top 1
+ wm geom $top "${w}x2+$xr+$y"
+
+ update idletasks
+ grab set $top
+ bind $top <ButtonRelease-1> [list PanedWindow::_end_move_sash \
+ $path $top $num $ymin $ymax %Y rooty height]
+ bind $top <Motion> [list PanedWindow::_move_sash \
+ $top $ymin $ymax %Y +$xr+%%d]
+ _move_sash $top $ymin $ymax $y "+$xr+%d"
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::_move_sash
+# ----------------------------------------------------------------------------
+proc PanedWindow::_move_sash { top min max v form } {
+
+ if { $v < $min } {
+ set v $min
+ } elseif { $v > $max } {
+ set v $max
+ }
+ wm geom $top [format $form $v]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::_end_move_sash
+# ----------------------------------------------------------------------------
+proc PanedWindow::_end_move_sash { path top num min max v rootv size } {
+ variable _panedw
+
+ destroy $top
+ if { $v < $min } {
+ set v $min
+ } elseif { $v > $max } {
+ set v $max
+ }
+ set fprev $path.f[expr {$num-1}]
+ set fnext $path.f$num
+
+ $path.sash$num.but configure -relief raised
+
+ set wsash [expr {[Widget::getoption $path -width] + 2*[Widget::getoption $path -pad]}]
+ set dv [expr {$v-[winfo $rootv $path.sash$num]-$wsash/2}]
+ set w1 [winfo $size $fprev]
+ set w2 [winfo $size $fnext]
+
+ for {set i 0} {$i < $_panedw($path,nbpanes)} {incr i} {
+ if { $i == $num-1} {
+ $fprev configure -$size [expr {[winfo $size $fprev]+$dv}]
+ } elseif { $i == $num } {
+ $fnext configure -$size [expr {[winfo $size $fnext]-$dv}]
+ } else {
+ $path.f$i configure -$size [winfo $size $path.f$i]
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::_realize
+# ----------------------------------------------------------------------------
+proc PanedWindow::_realize { path width height } {
+ variable _panedw
+
+ set x 0
+ set y 0
+ set hc [winfo reqheight $path]
+ set hmax 0
+ for {set i 0} {$i < $_panedw($path,nbpanes)} {incr i} {
+ $path.f$i configure \
+ -width [winfo reqwidth $path.f$i.frame] \
+ -height [winfo reqheight $path.f$i.frame]
+ place $path.f$i.frame -x 0 -y 0 -relwidth 1 -relheight 1
+ }
+
+ bind $path <Configure> {}
+
+ _apply_weights $path
+ set _panedw($path,configuredone) 1
+ return
+}
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::_apply_weights
+# ----------------------------------------------------------------------------
+proc PanedWindow::_apply_weights { path } {
+ variable _panedw
+
+ set weights [Widget::getoption $path -weights]
+ if {[string equal $weights "extra"]} {
+ return
+ }
+
+ set side [Widget::getoption $path -side]
+ if {[string equal $side "top"] || [string equal $side "bottom"] } {
+ set size width
+ } else {
+ set size height
+ }
+ set wsash [expr {[Widget::getoption $path -width] + 2*[Widget::getoption $path -pad]}]
+ set rs [winfo $size $path]
+ set s [expr {$rs - ($_panedw($path,nbpanes) - 1) * $wsash}]
+
+ set tw 0.0
+ foreach w $_panedw($path,weights) {
+ set tw [expr {$tw + $w}]
+ }
+
+ for {set i 0} {$i < $_panedw($path,nbpanes)} {incr i} {
+ set rw [lindex $_panedw($path,weights) $i]
+ set ps [expr {int($rw / $tw * $s)}]
+ $path.f$i configure -$size $ps
+ }
+ return
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanedWindow::_destroy
+# ----------------------------------------------------------------------------
+proc PanedWindow::_destroy { path } {
+ variable _panedw
+
+ for {set i 0} {$i < $_panedw($path,nbpanes)} {incr i} {
+ Widget::destroy $path.f$i
+ }
+ unset _panedw($path,nbpanes)
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/panelframe.tcl b/modules/tclsci/tcl/BWidget/panelframe.tcl
new file mode 100755
index 000000000..fb8bc1937
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/panelframe.tcl
@@ -0,0 +1,246 @@
+# ----------------------------------------------------------------------------
+# panelframe.tcl
+# Create PanelFrame widgets.
+# A PanelFrame is a boxed frame that allows you to place items
+# in the label area (liked combined frame+toolbar). It uses the
+# highlight colors the default frame color.
+# $Id: panelframe.tcl,v 1.1 2004/09/09 22:17:51 hobbs Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - PanelFrame::create
+# - PanelFrame::configure
+# - PanelFrame::cget
+# - PanelFrame::getframe
+# - PanelFrame::add
+# - PanelFrame::remove
+# - PanelFrame::items
+# ----------------------------------------------------------------------------
+
+namespace eval PanelFrame {
+ Widget::define PanelFrame panelframe
+
+ Widget::declare PanelFrame {
+ {-background TkResource "" 0 frame}
+ {-borderwidth TkResource 1 0 frame}
+ {-relief TkResource flat 0 frame}
+ {-panelbackground TkResource "" 0 {entry -selectbackground}}
+ {-panelforeground TkResource "" 0 {entry -selectforeground}}
+ {-width Int 0 0}
+ {-height Int 0 0}
+ {-font TkResource "" 0 label}
+ {-text String "" 0}
+ {-textvariable String "" 0}
+ {-ipad String 1 0}
+ {-bg Synonym -background}
+ {-bd Synonym -borderwidth}
+ }
+ # Should we have automatic state handling?
+ #{-state TkResource "" 0 label}
+
+ Widget::addmap PanelFrame "" :cmd {
+ -panelbackground -background
+ -width {} -height {} -borderwidth {} -relief {}
+ }
+ Widget::addmap PanelFrame "" .title {
+ -panelbackground -background
+ }
+ Widget::addmap PanelFrame "" .title.text {
+ -panelbackground -background
+ -panelforeground -foreground
+ -text {} -textvariable {} -font {}
+ }
+ Widget::addmap PanelFrame "" .frame {
+ -background {}
+ }
+
+ if {0} {
+ # This would be code to have an automated close button
+ #{-closebutton Boolean 0 0}
+ Widget::addmap PanelFrame "" .title.close {
+ -panelbackground -background
+ -panelforeground -foreground
+ }
+ variable HaveMarlett \
+ [expr {[lsearch -exact [font families] "Marlett"] != -1}]
+
+ variable imgdata {
+ #define close_width 16
+ #define close_height 16
+ static char close_bits[] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x08,
+ 0x38, 0x1c, 0x70, 0x0e,
+ 0xe0, 0x07, 0xc0, 0x03,
+ 0xc0, 0x03, 0xe0, 0x07,
+ 0x70, 0x0e, 0x38, 0x1c,
+ 0x10, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+ }
+ # We use the same -foreground as the default -panelbackground
+ image create bitmap ::PanelFrame::X -data $imgdata \
+ -foreground [lindex $Widget::PanelFrame::opt(-panelbackground) 1]
+ }
+
+ bind PanelFrame <Destroy> [list Widget::destroy %W]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanelFrame::create
+# ----------------------------------------------------------------------------
+proc PanelFrame::create { path args } {
+ variable HaveMarlett
+
+ Widget::init PanelFrame $path $args
+
+ set lblopts [list -bd 0 -highlightthickness 0]
+ set outer [eval [list frame $path -class PanelFrame] \
+ [Widget::subcget $path :cmd]]
+ set title [eval [list frame $path.title] \
+ [Widget::subcget $path .title]]
+ set tlbl [eval [list label $path.title.text] $lblopts -anchor w \
+ [Widget::subcget $path .title.text]]
+ set inner [eval [list frame $path.frame] \
+ [Widget::subcget $path .frame]]
+
+ foreach {ipadx ipady} [_padval [Widget::cget $path -ipad]] { break }
+
+ if {0} {
+ set btnopts [list -padx 0 -pady 0 -relief flat -overrelief raised \
+ -bd 1 -highlightthickness 0]
+ set clbl [eval [list button $path.title.close] $btnopts \
+ [Widget::subcget $path .title.close]]
+ set close [Widget::cget $path -closebutton]
+ if {$HaveMarlett} {
+ $clbl configure -font "Marlett -14" -text \u0072
+ } else {
+ $clbl configure -image ::PanelFrame::X
+ }
+ if {$close} {
+ pack $path.title.close -side right -padx $ipadx -pady $ipady
+ }
+ }
+
+ grid $path.title -row 0 -column 0 -sticky ew
+ grid $path.frame -row 1 -column 0 -sticky news
+ grid columnconfigure $path 0 -weight 1
+ grid rowconfigure $path 1 -weight 1
+
+ pack $path.title.text -side left -fill x -anchor w \
+ -padx $ipadx -pady $ipady
+
+ return [Widget::create PanelFrame $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanelFrame::configure
+# ----------------------------------------------------------------------------
+proc PanelFrame::configure { path args } {
+ set res [Widget::configure $path $args]
+
+ if {[Widget::hasChanged $path -ipad ipad]} {
+ }
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command PanelFrame::cget
+# ----------------------------------------------------------------------------
+proc PanelFrame::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+# ----------------------------------------------------------------------------
+# Command PanelFrame::getframe
+# ----------------------------------------------------------------------------
+proc PanelFrame::getframe { path } {
+ return $path.frame
+}
+
+# ------------------------------------------------------------------------
+# Command PanelFrame::add
+# ------------------------------------------------------------------------
+proc PanelFrame::add {path w args} {
+ variable _widget
+
+ array set opts [list \
+ -side right \
+ -fill none \
+ -expand 0 \
+ -pad [Widget::cget $path -ipad] \
+ ]
+ foreach {key val} $args {
+ if {[info exists opts($key)]} {
+ set opts($key) $val
+ } else {
+ set msg "unknown option \"$key\", must be one of: "
+ append msg [join [lsort [array names opts]] {, }]
+ return -code error $msg
+ }
+ }
+ foreach {ipadx ipady} [_padval $opts(-pad)] { break }
+
+ set f $path.title
+
+ lappend _widget($path,items) $w
+ pack $w -in $f -padx $ipadx -pady $ipady -side $opts(-side) \
+ -fill $opts(-fill) -expand $opts(-expand)
+
+ return $w
+}
+
+# ------------------------------------------------------------------------
+# Command PanelFrame::remove
+# ------------------------------------------------------------------------
+proc PanelFrame::remove {path args} {
+ variable _widget
+
+ set destroy [string equal [lindex $args 0] "-destroy"]
+ if {$destroy} {
+ set args [lrange $args 1 end]
+ }
+ foreach w $args {
+ set idx [lsearch -exact $_widget($path,items) $w]
+ if {$idx == -1} {
+ # ignore unknown
+ continue
+ }
+ if {$destroy} {
+ destroy $w
+ } elseif {[winfo exists $w]} {
+ pack forget $w
+ }
+ set _widget($path,items) [lreplace $_widget($path,items) $idx $idx]
+ }
+}
+
+# ------------------------------------------------------------------------
+# Command PanelFrame::delete
+# ------------------------------------------------------------------------
+proc PanelFrame::delete {path args} {
+ return [PanelFrame::remove $path -destroy $args]
+}
+
+# ------------------------------------------------------------------------
+# Command PanelFrame::items
+# ------------------------------------------------------------------------
+proc PanelFrame::items {path} {
+ variable _widget
+ return $_widget($path,items)
+}
+
+proc PanelFrame::_padval {padval} {
+ set len [llength $padval]
+ foreach {a b} $padval { break }
+ if {$len == 0 || $len > 2} {
+ return -code error \
+ "invalid pad value \"$padval\", must be 1 or 2 pixel values"
+ } elseif {$len == 1} {
+ return [list $a $a]
+ } elseif {$len == 2} {
+ return $padval
+ }
+}
diff --git a/modules/tclsci/tcl/BWidget/passwddlg.tcl b/modules/tclsci/tcl/BWidget/passwddlg.tcl
new file mode 100755
index 000000000..551d0ab9a
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/passwddlg.tcl
@@ -0,0 +1,182 @@
+# -----------------------------------------------------------------------------
+# passwddlg.tcl
+# This file is part of Unifix BWidget Toolkit
+# by Stephane Lavirotte (Stephane.Lavirotte@sophia.inria.fr)
+# $Id: passwddlg.tcl,v 1.12 2009/06/11 15:42:51 oehhar Exp $
+# -----------------------------------------------------------------------------
+# Index of commands:
+# - PasswdDlg::create
+# - PasswdDlg::configure
+# - PasswdDlg::cget
+# - PasswdDlg::_verifonlogin
+# - PasswdDlg::_verifonpasswd
+# - PasswdDlg::_max
+#------------------------------------------------------------------------------
+
+namespace eval PasswdDlg {
+ Widget::define PasswdDlg passwddlg Dialog LabelEntry
+
+ Widget::bwinclude PasswdDlg Dialog :cmd \
+ remove {-image -bitmap -side -default -cancel -separator} \
+ initialize {-modal local -anchor e}
+
+ Widget::bwinclude PasswdDlg LabelEntry .frame.lablog \
+ remove [list -command -justify -name -show -side \
+ -state -takefocus -width -xscrollcommand -padx -pady \
+ -dragenabled -dragendcmd -dragevent -draginitcmd \
+ -dragtype -dropenabled -dropcmd -dropovercmd -droptypes \
+ ] \
+ prefix [list login -editable -helptext -helpvar -label \
+ -text -textvariable -underline \
+ ] \
+ initialize [list -relief sunken -borderwidth 2 \
+ -labelanchor w -width 15 -loginlabel "Login" \
+ ]
+
+ Widget::bwinclude PasswdDlg LabelEntry .frame.labpass \
+ remove [list -command -width -show -side -takefocus \
+ -xscrollcommand -dragenabled -dragendcmd -dragevent \
+ -draginitcmd -dragtype -dropenabled -dropcmd \
+ -dropovercmd -droptypes -justify -padx -pady -name \
+ ] \
+ prefix [list passwd -editable -helptext -helpvar -label \
+ -state -text -textvariable -underline \
+ ] \
+ initialize [list -relief sunken -borderwidth 2 \
+ -labelanchor w -width 15 -passwdlabel "Password" \
+ ]
+
+ Widget::declare PasswdDlg {
+ {-type Enum ok 0 {ok okcancel}}
+ {-labelwidth TkResource -1 0 {label -width}}
+ {-command String "" 0}
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command PasswdDlg::create
+# -----------------------------------------------------------------------------
+proc PasswdDlg::create { path args } {
+
+ array set maps [list PasswdDlg {} :cmd {} .frame.lablog {} \
+ .frame.labpass {}]
+ array set maps [Widget::parseArgs PasswdDlg $args]
+
+ Widget::initFromODB PasswdDlg "$path#PasswdDlg" $maps(PasswdDlg)
+
+ # Extract the PasswdDlg megawidget options (those that don't map to a
+ # subwidget)
+ set type [Widget::cget "$path#PasswdDlg" -type]
+ set cmd [Widget::cget "$path#PasswdDlg" -command]
+
+ set defb -1
+ set canb -1
+ switch -- $type {
+ ok { set lbut {ok}; set defb 0 }
+ okcancel { set lbut {ok cancel} ; set defb 0; set canb 1 }
+ }
+
+ eval [list Dialog::create $path] $maps(:cmd) \
+ [list -class PasswdDlg -image [Bitmap::get passwd] \
+ -side bottom -default $defb -cancel $canb]
+ foreach but $lbut {
+ if { $but == "ok" && $cmd != "" } {
+ Dialog::add $path -text $but -name $but -command $cmd
+ } else {
+ Dialog::add $path -text $but -name $but
+ }
+ }
+
+ set frame [Dialog::getframe $path]
+ bind $path <Return> ""
+ bind $frame <Destroy> [list Widget::destroy $path\#PasswdDlg]
+
+ set lablog [eval [list LabelEntry::create $frame.lablog] \
+ $maps(.frame.lablog) \
+ [list -name login -dragenabled 0 -dropenabled 0 \
+ -command [list PasswdDlg::_verifonpasswd \
+ $path $frame.labpass]]]
+
+ set labpass [eval [list LabelEntry::create $frame.labpass] \
+ $maps(.frame.labpass) \
+ [list -name password -show "*" \
+ -dragenabled 0 -dropenabled 0 \
+ -command [list PasswdDlg::_verifonlogin \
+ $path $frame.lablog]]]
+
+ # compute label width
+ if {[$lablog cget -labelwidth] == 0} {
+ set loglabel [$lablog cget -label]
+ set passlabel [$labpass cget -label]
+ set labwidth [_max [string length $loglabel] [string length $passlabel]]
+ incr labwidth 1
+ $lablog configure -labelwidth $labwidth
+ $labpass configure -labelwidth $labwidth
+ }
+
+ Widget::create PasswdDlg $path 0
+
+ pack $frame.lablog $frame.labpass -fill x -expand 1
+
+ # added by bach@mwgdna.com
+ # give focus to loginlabel unless the state is disabled
+ if {[$lablog cget -editable]} {
+ focus $frame.lablog.e
+ } else {
+ focus $frame.labpass.e
+ }
+ set res [Dialog::draw $path]
+
+ if { $res == 0 } {
+ set res [list [$lablog.e cget -text] [$labpass.e cget -text]]
+ } else {
+ set res [list]
+ }
+ Widget::destroy "$path#PasswdDlg"
+ destroy $path
+
+ return $res
+}
+
+# -----------------------------------------------------------------------------
+# Command PasswdDlg::configure
+# -----------------------------------------------------------------------------
+
+proc PasswdDlg::configure { path args } {
+ set res [Widget::configure "$path#PasswdDlg" $args]
+}
+
+# -----------------------------------------------------------------------------
+# Command PasswdDlg::cget
+# -----------------------------------------------------------------------------
+
+proc PasswdDlg::cget { path option } {
+ return [Widget::cget "$path#PasswdDlg" $option]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command PasswdDlg::_verifonlogin
+# -----------------------------------------------------------------------------
+proc PasswdDlg::_verifonlogin { path labpass } {
+ Dialog::enddialog $path 0
+}
+
+# -----------------------------------------------------------------------------
+# Command PasswdDlg::_verifonpasswd
+# -----------------------------------------------------------------------------
+proc PasswdDlg::_verifonpasswd { path labpass } {
+ if {[string equal [$labpass cget -state] "disabled"]} {
+ Dialog::enddialog $path 0
+ } else {
+ focus $labpass
+ }
+}
+
+# -----------------------------------------------------------------------------
+# Command PasswdDlg::_max
+# -----------------------------------------------------------------------------
+proc PasswdDlg::_max { val1 val2 } {
+ return [expr {($val1 > $val2) ? ($val1) : ($val2)}]
+}
diff --git a/modules/tclsci/tcl/BWidget/pkgIndex.tcl b/modules/tclsci/tcl/BWidget/pkgIndex.tcl
new file mode 100755
index 000000000..884aeed01
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/pkgIndex.tcl
@@ -0,0 +1,84 @@
+
+# @@ Meta Begin
+# Package BWidget 1.9.4
+# Meta activestatetags ActiveTcl Public
+# Meta as::author {Jeff Hobbs} {Damon Courtney}
+# Meta as::build::date 2011-01-27
+# Meta as::origin http://sourceforge.net/projects/tcllib
+# Meta category Widget set
+# Meta description The BWidget Toolkit is a high-level widget set for
+# Meta description Tcl/Tk. They feature a professional look and feel
+# Meta description and don't require a compiled extension library.
+# Meta license BSD
+# Meta platform tcl
+# Meta recommend {Tk 8.5a6}
+# Meta recommend {tile 0.6 1}
+# Meta require {Tcl 8.1.1}
+# Meta require {Tk 8.3}
+# Meta subject bwidget widget toolkit Tk megawidget
+# Meta summary A suite of megawidgets for Tk
+# @@ Meta End
+
+
+if {![package vsatisfies [package provide Tcl] 8.1]} return
+
+package ifneeded BWidget 1.9.4 [string map [list @ $dir] {
+ # ACTIVESTATE TEAPOT-PKG BEGIN REQUIREMENTS
+
+ package require Tcl 8.1.1
+ package require Tk 8.3
+
+ # ACTIVESTATE TEAPOT-PKG END REQUIREMENTS
+
+ set dir {@}
+ eval "package require Tk 8.1.1;\
+ [list tclPkgSetup $dir BWidget 1.9.4 {
+ {arrow.tcl source {ArrowButton ArrowButton::create ArrowButton::use}}
+ {labelframe.tcl source {LabelFrame LabelFrame::create LabelFrame::use}}
+ {labelentry.tcl source {LabelEntry LabelEntry::create LabelEntry::use}}
+ {bitmap.tcl source {Bitmap::get Bitmap::use}}
+ {button.tcl source {Button Button::create Button::use}}
+ {buttonbox.tcl source {ButtonBox ButtonBox::create ButtonBox::use}}
+ {combobox.tcl source {ComboBox ComboBox::create ComboBox::use}}
+ {label.tcl source {Label Label::create Label::use}}
+ {entry.tcl source {Entry Entry::create Entry::use}}
+ {pagesmgr.tcl source {PagesManager PagesManager::create PagesManager::use}}
+ {notebook.tcl source {NoteBook NoteBook::create NoteBook::use}}
+ {panedw.tcl source {PanedWindow PanedWindow::create PanedWindow::use}}
+ {scrollw.tcl source {ScrolledWindow ScrolledWindow::create ScrolledWindow::use}}
+ {scrollview.tcl source {ScrollView ScrollView::create ScrollView::use}}
+ {scrollframe.tcl source {ScrollableFrame ScrollableFrame::create ScrollableFrame::use}}
+ {panelframe.tcl source {PanelFrame PanelFrame::create PanelFrame::use}}
+ {progressbar.tcl source {ProgressBar ProgressBar::create ProgressBar::use}}
+ {progressdlg.tcl source {ProgressDlg ProgressDlg::create ProgressDlg::use}}
+ {passwddlg.tcl source {PasswdDlg PasswdDlg::create PasswdDlg::use}}
+ {dragsite.tcl source {DragSite::register DragSite::include DragSite::use}}
+ {dropsite.tcl source {DropSite::register DropSite::include DropSite::use}}
+ {separator.tcl source {Separator Separator::create Separator::use}}
+ {spinbox.tcl source {SpinBox SpinBox::create SpinBox::use}}
+ {statusbar.tcl source {StatusBar StatusBar::create StatusBar::use}}
+ {titleframe.tcl source {TitleFrame TitleFrame::create TitleFrame::use}}
+ {mainframe.tcl source {MainFrame MainFrame::create MainFrame::use}}
+ {listbox.tcl source {ListBox ListBox::create ListBox::use}}
+ {tree.tcl source {Tree Tree::create Tree::use}}
+ {color.tcl source {SelectColor SelectColor::menu SelectColor::dialog SelectColor::setcolor}}
+ {dynhelp.tcl source {DynamicHelp::configure DynamicHelp::use DynamicHelp::register DynamicHelp::include DynamicHelp::add DynamicHelp::delete}}
+ {dialog.tcl source {Dialog Dialog::create Dialog::use}}
+ {messagedlg.tcl source {MessageDlg MessageDlg::create MessageDlg::use}}
+ {font.tcl source {SelectFont SelectFont::create SelectFont::use SelectFont::loadfont}}
+ {widgetdoc.tcl source {Widget::generate-doc Widget::generate-widget-doc}}
+ {wizard.tcl source {Wizard Wizard::create Wizard::use SimpleWizard ClassicWizard}}
+ {xpm2image.tcl source {xpm-to-image}}
+ }]; \
+ [list namespace eval ::BWIDGET {}]; \
+ [list set ::BWIDGET::LIBRARY $dir]; \
+ [list source [file join $dir widget.tcl]]; \
+ [list source [file join $dir init.tcl]]; \
+ [list source [file join $dir utils.tcl]];"
+
+ # ACTIVESTATE TEAPOT-PKG BEGIN DECLARE
+
+ package provide BWidget 1.9.4
+
+ # ACTIVESTATE TEAPOT-PKG END DECLARE
+ }]
diff --git a/modules/tclsci/tcl/BWidget/progressbar.tcl b/modules/tclsci/tcl/BWidget/progressbar.tcl
new file mode 100755
index 000000000..73c48f255
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/progressbar.tcl
@@ -0,0 +1,208 @@
+# ----------------------------------------------------------------------------
+# progressbar.tcl
+# This file is part of Unifix BWidget Toolkit
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - ProgressBar::create
+# - ProgressBar::configure
+# - ProgressBar::cget
+# - ProgressBar::_destroy
+# - ProgressBar::_modify
+# ----------------------------------------------------------------------------
+
+namespace eval ProgressBar {
+ Widget::define ProgressBar progressbar
+
+ Widget::declare ProgressBar {
+ {-type Enum normal 0
+ {normal incremental infinite nonincremental_infinite}}
+ {-maximum Int 100 0 "%d > 0"}
+ {-background TkResource "" 0 frame}
+ {-foreground TkResource "blue" 0 label}
+ {-borderwidth TkResource 2 0 frame}
+ {-troughcolor TkResource "" 0 scrollbar}
+ {-relief TkResource sunken 0 label}
+ {-orient Enum horizontal 1 {horizontal vertical}}
+ {-variable String "" 0}
+ {-idle Boolean 0 0}
+ {-width TkResource 100 0 frame}
+ {-height TkResource 4m 0 frame}
+ {-bg Synonym -background}
+ {-fg Synonym -foreground}
+ {-bd Synonym -borderwidth}
+ }
+
+ Widget::addmap ProgressBar "" :cmd {-background {} -width {} -height {}}
+ Widget::addmap ProgressBar "" .bar {
+ -troughcolor -background -borderwidth {} -relief {}
+ }
+
+ variable _widget
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressBar::create
+# ----------------------------------------------------------------------------
+proc ProgressBar::create { path args } {
+ variable _widget
+
+ array set maps [list ProgressBar {} :cmd {} .bar {}]
+ array set maps [Widget::parseArgs ProgressBar $args]
+ eval frame $path $maps(:cmd) -class ProgressBar -bd 0 \
+ -highlightthickness 0 -relief flat
+ Widget::initFromODB ProgressBar $path $maps(ProgressBar)
+
+ set c [eval [list canvas $path.bar] $maps(.bar) -highlightthickness 0]
+ set fg [Widget::cget $path -foreground]
+ if { [string equal [Widget::cget $path -orient] "horizontal"] } {
+ $path.bar create rectangle -1 0 0 0 -fill $fg -outline $fg -tags rect
+ } else {
+ $path.bar create rectangle 0 1 0 0 -fill $fg -outline $fg -tags rect
+ }
+
+ set _widget($path,val) 0
+ set _widget($path,dir) 1
+ set _widget($path,var) [Widget::cget $path -variable]
+ if {$_widget($path,var) != ""} {
+ GlobalVar::tracevar variable $_widget($path,var) w \
+ [list ProgressBar::_modify $path]
+ set _widget($path,afterid) \
+ [after idle [list ProgressBar::_modify $path]]
+ }
+
+ bind $path.bar <Destroy> [list ProgressBar::_destroy $path]
+ bind $path.bar <Configure> [list ProgressBar::_modify $path]
+
+ return [Widget::create ProgressBar $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressBar::configure
+# ----------------------------------------------------------------------------
+proc ProgressBar::configure { path args } {
+ variable _widget
+
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChangedX $path -variable] } {
+ set newv [Widget::cget $path -variable]
+ if { $_widget($path,var) != "" } {
+ GlobalVar::tracevar vdelete $_widget($path,var) w \
+ [list ProgressBar::_modify $path]
+ }
+ if { $newv != "" } {
+ set _widget($path,var) $newv
+ GlobalVar::tracevar variable $newv w \
+ [list ProgressBar::_modify $path]
+ if {![info exists _widget($path,afterid)]} {
+ set _widget($path,afterid) \
+ [after idle [list ProgressBar::_modify $path]]
+ }
+ } else {
+ set _widget($path,var) ""
+ }
+ }
+
+ foreach {cbd cor cma} [Widget::hasChangedX $path -borderwidth \
+ -orient -maximum] break
+
+ if { $cbd || $cor || $cma } {
+ if {![info exists _widget($path,afterid)]} {
+ set _widget($path,afterid) \
+ [after idle [list ProgressBar::_modify $path]]
+ }
+ }
+ if { [Widget::hasChangedX $path -foreground] } {
+ set fg [Widget::cget $path -foreground]
+ $path.bar itemconfigure rect -fill $fg -outline $fg
+ }
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressBar::cget
+# ----------------------------------------------------------------------------
+proc ProgressBar::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressBar::_modify
+# ----------------------------------------------------------------------------
+proc ProgressBar::_modify { path args } {
+ variable _widget
+
+ catch {unset _widget($path,afterid)}
+ if { ![GlobalVar::exists $_widget($path,var)] ||
+ [set val [GlobalVar::getvar $_widget($path,var)]] < 0 } {
+ catch {place forget $path.bar}
+ } else {
+ place $path.bar -relx 0 -rely 0 -relwidth 1 -relheight 1
+ set type [Widget::getoption $path -type]
+ if { $val != 0 && $type != "normal" && \
+ $type != "nonincremental_infinite"} {
+ set val [expr {$val+$_widget($path,val)}]
+ }
+ set _widget($path,val) $val
+ set max [Widget::getoption $path -maximum]
+ set bd [expr {2*[$path.bar cget -bd]}]
+ set w [winfo width $path.bar]
+ set h [winfo height $path.bar]
+ if {$type == "infinite" || $type == "nonincremental_infinite"} {
+ # JDC: New infinite behaviour
+ set tval [expr {$val % $max}]
+ if { $tval < ($max / 2.0) } {
+ set x0 [expr {double($tval) / double($max) * 1.5}]
+ } else {
+ set x0 [expr {(1.0-(double($tval) / double($max))) * 1.5}]
+ }
+ set x1 [expr {$x0 + 0.25}]
+ # convert coords to ints to prevent triggering canvas refresh
+ # bug related to fractional coords
+ if {[Widget::getoption $path -orient] == "horizontal"} {
+ $path.bar coords rect [expr {int($x0*$w)}] 0 \
+ [expr {int($x1*$w)}] $h
+ } else {
+ $path.bar coords rect 0 [expr {int($h-$x0*$h)}] $w \
+ [expr {int($x1*$h)}]
+ }
+ } else {
+ if { $val > $max } {set val $max}
+ if {[Widget::getoption $path -orient] == "horizontal"} {
+ $path.bar coords rect -1 0 [expr {int(double($val)*$w/$max)}] $h
+ } else {
+ $path.bar coords rect 0 [expr {$h+1}] $w \
+ [expr {int($h*(1.0 - double($val)/$max))}]
+ }
+ }
+ }
+ if {![Widget::cget $path -idle]} {
+ update idletasks
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressBar::_destroy
+# ----------------------------------------------------------------------------
+proc ProgressBar::_destroy { path } {
+ variable _widget
+
+ if {[info exists _widget($path,afterid)]} {
+ after cancel $_widget($path,afterid)
+ unset _widget($path,afterid)
+ }
+ if {[info exists _widget($path,var)]} {
+ if {$_widget($path,var) != ""} {
+ GlobalVar::tracevar vdelete $_widget($path,var) w \
+ [list ProgressBar::_modify $path]
+ }
+ unset _widget($path,var)
+ }
+ unset _widget($path,dir)
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/progressdlg.tcl b/modules/tclsci/tcl/BWidget/progressdlg.tcl
new file mode 100755
index 000000000..bd2a2768a
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/progressdlg.tcl
@@ -0,0 +1,87 @@
+# ----------------------------------------------------------------------------
+# progressdlg.tcl
+# This file is part of Unifix BWidget Toolkit
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - ProgressDlg::create
+# ----------------------------------------------------------------------------
+
+namespace eval ProgressDlg {
+ Widget::define ProgressDlg progressdlg Dialog ProgressBar
+
+ Widget::bwinclude ProgressDlg Dialog :cmd \
+ remove {
+ -modal -image -bitmap -side -anchor -cancel -default
+ -homogeneous -padx -pady -spacing
+ }
+
+ Widget::bwinclude ProgressDlg ProgressBar .frame.pb \
+ remove {-orient -width -height}
+
+ Widget::declare ProgressDlg {
+ {-width TkResource 25 0 label}
+ {-height TkResource 2 0 label}
+ {-textvariable TkResource "" 0 label}
+ {-font TkResource "" 0 label}
+ {-stop String "" 0}
+ {-command String "" 0}
+ }
+
+ Widget::addmap ProgressDlg :cmd .frame.msg \
+ {-width {} -height {} -textvariable {} -font {} -background {}}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressDlg::create
+# ----------------------------------------------------------------------------
+proc ProgressDlg::create { path args } {
+ array set maps [list ProgressDlg {} :cmd {} .frame.msg {} .frame.pb {}]
+ array set maps [Widget::parseArgs ProgressDlg $args]
+
+ eval [list Dialog::create] $path $maps(:cmd) \
+ [list -image [Bitmap::get hourglass] \
+ -modal none -side bottom -anchor e -class ProgressDlg]
+
+ Widget::initFromODB ProgressDlg "$path#ProgressDlg" $maps(ProgressDlg)
+
+ wm protocol $path WM_DELETE_WINDOW {;}
+
+ set frame [Dialog::getframe $path]
+ bind $frame <Destroy> [list Widget::destroy $path\#ProgressDlg]
+ $frame configure -cursor watch
+
+ eval [list label $frame.msg] $maps(.frame.msg) \
+ -relief flat -borderwidth 0 \
+ -highlightthickness 0 -anchor w -justify left
+ pack $frame.msg -side top -pady 3m -anchor nw -fill x -expand yes
+
+ eval [list ProgressBar::create] $frame.pb $maps(.frame.pb) -width 100
+ pack $frame.pb -side bottom -anchor w -fill x -expand yes
+
+ set stop [Widget::cget "$path#ProgressDlg" -stop]
+ set cmd [Widget::cget "$path#ProgressDlg" -command]
+ if { $stop != "" && $cmd != "" } {
+ Dialog::add $path -text $stop -name $stop -command $cmd
+ }
+ Dialog::draw $path
+ BWidget::grab local $path
+
+ return [Widget::create ProgressDlg $path 0]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressDlg::configure
+# ----------------------------------------------------------------------------
+proc ProgressDlg::configure { path args } {
+ return [Widget::configure "$path#ProgressDlg" $args]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ProgressDlg::cget
+# ----------------------------------------------------------------------------
+proc ProgressDlg::cget { path option } {
+ return [Widget::cget "$path#ProgressDlg" $option]
+}
diff --git a/modules/tclsci/tcl/BWidget/scrollframe.tcl b/modules/tclsci/tcl/BWidget/scrollframe.tcl
new file mode 100755
index 000000000..fc5e43a1f
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/scrollframe.tcl
@@ -0,0 +1,262 @@
+# ----------------------------------------------------------------------------
+# scrollframe.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: scrollframe.tcl,v 1.11 2009/07/17 15:29:51 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - ScrollableFrame::create
+# - ScrollableFrame::configure
+# - ScrollableFrame::cget
+# - ScrollableFrame::getframe
+# - ScrollableFrame::see
+# - ScrollableFrame::xview
+# - ScrollableFrame::yview
+# - ScrollableFrame::_resize
+# ----------------------------------------------------------------------------
+
+namespace eval ScrollableFrame {
+ Widget::define ScrollableFrame scrollframe
+
+ # If themed, there is no background and -bg option
+ if {[Widget::theme]} {
+ Widget::declare ScrollableFrame {
+ {-width Int 0 0 {}}
+ {-height Int 0 0 {}}
+ {-areawidth Int 0 0 {}}
+ {-areaheight Int 0 0 {}}
+ {-constrainedwidth Boolean 0 0}
+ {-constrainedheight Boolean 0 0}
+ {-xscrollcommand TkResource "" 0 canvas}
+ {-yscrollcommand TkResource "" 0 canvas}
+ {-xscrollincrement TkResource "" 0 canvas}
+ {-yscrollincrement TkResource "" 0 canvas}
+ }
+ } else {
+ Widget::declare ScrollableFrame {
+ {-background TkResource "" 0 frame}
+ {-width Int 0 0 {}}
+ {-height Int 0 0 {}}
+ {-areawidth Int 0 0 {}}
+ {-areaheight Int 0 0 {}}
+ {-constrainedwidth Boolean 0 0}
+ {-constrainedheight Boolean 0 0}
+ {-xscrollcommand TkResource "" 0 canvas}
+ {-yscrollcommand TkResource "" 0 canvas}
+ {-xscrollincrement TkResource "" 0 canvas}
+ {-yscrollincrement TkResource "" 0 canvas}
+ {-bg Synonym -background}
+ }
+ }
+
+ Widget::addmap ScrollableFrame "" :cmd {
+ -width {} -height {}
+ -xscrollcommand {} -yscrollcommand {}
+ -xscrollincrement {} -yscrollincrement {}
+ }
+ if { ! [Widget::theme]} {
+ Widget::addmap ScrollableFrame "" .frame {-background {}}
+ }
+
+ variable _widget
+
+ bind BwScrollableFrame <Configure> [list ScrollableFrame::_resize %W]
+ bind BwScrollableFrame <Destroy> [list Widget::destroy %W]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::create
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::create { path args } {
+ Widget::init ScrollableFrame $path $args
+
+ set canvas [eval [list canvas $path] [Widget::subcget $path :cmd] \
+ -highlightthickness 0 -borderwidth 0 -relief flat]
+
+ if {[Widget::theme]} {
+ set frame [eval [list ttk::frame $path.frame] \
+ [Widget::subcget $path .frame]]
+ set bg [ttk::style lookup TFrame -background]
+ } else {
+ set frame [eval [list frame $path.frame] \
+ [Widget::subcget $path .frame] \
+ -highlightthickness 0 -borderwidth 0 -relief flat]
+ set bg [$frame cget -background]
+ }
+ # Give canvas frame (or theme) background
+ $canvas configure -background $bg
+
+ $canvas create window 0 0 -anchor nw -window $frame -tags win \
+ -width [Widget::cget $path -areawidth] \
+ -height [Widget::cget $path -areaheight]
+
+ bind $frame <Configure> \
+ [list ScrollableFrame::_frameConfigure $canvas]
+ # add <unmap> binding: <configure> is not called when frame
+ # becomes so small that it suddenly falls outside of currently visible area.
+ # but now we need to add a <map> binding too
+ bind $frame <Map> \
+ [list ScrollableFrame::_frameConfigure $canvas]
+ bind $frame <Unmap> \
+ [list ScrollableFrame::_frameConfigure $canvas 1]
+
+ bindtags $path [list $path BwScrollableFrame [winfo toplevel $path] all]
+
+ return [Widget::create ScrollableFrame $path]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::configure
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::configure { path args } {
+ set res [Widget::configure $path $args]
+ set upd 0
+
+ set modcw [Widget::hasChanged $path -constrainedwidth cw]
+ set modw [Widget::hasChanged $path -areawidth w]
+ if { $modcw || (!$cw && $modw) } {
+ if { $cw } {
+ set w [winfo width $path]
+ }
+ set upd 1
+ }
+
+ set modch [Widget::hasChanged $path -constrainedheight ch]
+ set modh [Widget::hasChanged $path -areaheight h]
+ if { $modch || (!$ch && $modh) } {
+ if { $ch } {
+ set h [winfo height $path]
+ }
+ set upd 1
+ }
+
+ if { $upd } {
+ $path:cmd itemconfigure win -width $w -height $h
+ }
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::cget
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::getframe
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::getframe { path } {
+ return $path.frame
+}
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::see
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::see { path widget {vert top} {horz left} {xOffset 0} {yOffset 0}} {
+ set x0 [winfo x $widget]
+ set y0 [winfo y $widget]
+ set x1 [expr {$x0+[winfo width $widget]}]
+ set y1 [expr {$y0+[winfo height $widget]}]
+ set xb0 [$path:cmd canvasx 0]
+ set yb0 [$path:cmd canvasy 0]
+ set xb1 [$path:cmd canvasx [winfo width $path]]
+ set yb1 [$path:cmd canvasy [winfo height $path]]
+ set dx 0
+ set dy 0
+
+ if { [string equal $horz "left"] } {
+ if { $x1 > $xb1 } {
+ set dx [expr {$x1-$xb1}]
+ }
+ if { $x0 < $xb0+$dx } {
+ set dx [expr {$x0-$xb0}]
+ }
+ } elseif { [string equal $horz "right"] } {
+ if { $x0 < $xb0 } {
+ set dx [expr {$x0-$xb0}]
+ }
+ if { $x1 > $xb1+$dx } {
+ set dx [expr {$x1-$xb1}]
+ }
+ }
+
+ if { [string equal $vert "top"] } {
+ if { $y1 > $yb1 } {
+ set dy [expr {$y1-$yb1}]
+ }
+ if { $y0 < $yb0+$dy } {
+ set dy [expr {$y0-$yb0}]
+ }
+ } elseif { [string equal $vert "bottom"] } {
+ if { $y0 < $yb0 } {
+ set dy [expr {$y0-$yb0}]
+ }
+ if { $y1 > $yb1+$dy } {
+ set dy [expr {$y1-$yb1}]
+ }
+ }
+
+ if {($dx + $xOffset) != 0} {
+ set x [expr {($xb0+$dx+$xOffset)/[winfo width $path.frame]}]
+ $path:cmd xview moveto $x
+ }
+ if {($dy + $yOffset) != 0} {
+ set y [expr {($yb0+$dy+$yOffset)/[winfo height $path.frame]}]
+ $path:cmd yview moveto $y
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::xview
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::xview { path args } {
+ return [eval [list $path:cmd xview] $args]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::yview
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::yview { path args } {
+ return [eval [list $path:cmd yview] $args]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::_resize
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::_resize { path } {
+ if { [Widget::getoption $path -constrainedwidth] } {
+ $path:cmd itemconfigure win -width [winfo width $path]
+ }
+ if { [Widget::getoption $path -constrainedheight] } {
+ $path:cmd itemconfigure win -height [winfo height $path]
+ }
+ # scollregion must also be reset when canvas size changes
+ _frameConfigure $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command ScrollableFrame::_frameConfigure
+# ----------------------------------------------------------------------------
+proc ScrollableFrame::_max {a b} {return [expr {$a <= $b ? $b : $a}]}
+proc ScrollableFrame::_frameConfigure {canvas {unmap 0}} {
+ # This ensures that we don't get funny scrollability in the frame
+ # when it is smaller than the canvas space
+ # use [winfo] to get height & width of frame
+
+ # [winfo] doesn't work for unmapped frame
+ set frameh [expr {$unmap ? 0 : [winfo height $canvas.frame]}]
+ set framew [expr {$unmap ? 0 : [winfo width $canvas.frame]}]
+
+ set height [_max $frameh [winfo height $canvas]]
+ set width [_max $framew [winfo width $canvas]]
+
+ $canvas:cmd configure -scrollregion [list 0 0 $width $height]
+}
diff --git a/modules/tclsci/tcl/BWidget/scrollview.tcl b/modules/tclsci/tcl/BWidget/scrollview.tcl
new file mode 100755
index 000000000..5fd06f5cd
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/scrollview.tcl
@@ -0,0 +1,254 @@
+# ------------------------------------------------------------------------------
+# scrollview.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: scrollview.tcl,v 1.7 2003/11/05 18:04:29 hobbs Exp $
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - ScrolledWindow::create
+# - ScrolledWindow::configure
+# - ScrolledWindow::cget
+# - ScrolledWindow::_set_hscroll
+# - ScrolledWindow::_set_vscroll
+# - ScrolledWindow::_update_scroll
+# - ScrolledWindow::_set_view
+# - ScrolledWindow::_resize
+# ------------------------------------------------------------------------------
+
+namespace eval ScrollView {
+ Widget::define ScrollView scrollview
+
+ Widget::tkinclude ScrollView canvas :cmd \
+ include {-relief -borderwidth -background -width -height -cursor} \
+ initialize {-relief flat -borderwidth 0 -width 30 -height 30 \
+ -cursor crosshair}
+
+ Widget::declare ScrollView {
+ {-width TkResource 30 0 canvas}
+ {-height TkResource 30 0 canvas}
+ {-background TkResource "" 0 canvas}
+ {-foreground String black 0}
+ {-fill String "" 0}
+ {-relief TkResource flat 0 canvas}
+ {-borderwidth TkResource 0 0 canvas}
+ {-cursor TkResource crosshair 0 canvas}
+ {-window String "" 0}
+ {-fg Synonym -foreground}
+ {-bg Synonym -background}
+ {-bd Synonym -borderwidth}
+ }
+
+ bind BwScrollView <B1-Motion> [list ScrollView::_set_view %W motion %x %y]
+ bind BwScrollView <ButtonPress-1> [list ScrollView::_set_view %W set %x %y]
+ bind BwScrollView <Configure> [list ScrollView::_resize %W]
+ bind BwScrollView <Destroy> [list ScrollView::_destroy %W]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::create
+# ------------------------------------------------------------------------------
+proc ScrollView::create { path args } {
+ Widget::init ScrollView $path $args
+ eval [list canvas $path] [Widget::subcget $path :cmd] -highlightthickness 0
+
+ Widget::create ScrollView $path
+
+ Widget::getVariable $path _widget
+
+ set w [Widget::cget $path -window]
+ set _widget(bd) [Widget::cget $path -borderwidth]
+ set _widget(width) [Widget::cget $path -width]
+ set _widget(height) [Widget::cget $path -height]
+
+ if {[winfo exists $w]} {
+ set _widget(oldxscroll) [$w cget -xscrollcommand]
+ set _widget(oldyscroll) [$w cget -yscrollcommand]
+ $w configure \
+ -xscrollcommand [list ScrollView::_set_hscroll $path] \
+ -yscrollcommand [list ScrollView::_set_vscroll $path]
+ }
+ $path:cmd create rectangle -2 -2 -2 -2 \
+ -fill [Widget::cget $path -fill] \
+ -outline [Widget::cget $path -foreground] \
+ -tags view
+
+ bindtags $path [list $path BwScrollView [winfo toplevel $path] all]
+
+ return $path
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::configure
+# ------------------------------------------------------------------------------
+proc ScrollView::configure { path args } {
+ Widget::getVariable $path _widget
+
+ set oldw [Widget::getoption $path -window]
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -window w] } {
+ if { [winfo exists $oldw] } {
+ $oldw configure \
+ -xscrollcommand $_widget(oldxscroll) \
+ -yscrollcommand $_widget(oldyscroll)
+ }
+ if { [winfo exists $w] } {
+ set _widget(oldxscroll) [$w cget -xscrollcommand]
+ set _widget(oldyscroll) [$w cget -yscrollcommand]
+ $w configure \
+ -xscrollcommand [list ScrollView::_set_hscroll $path] \
+ -yscrollcommand [list ScrollView::_set_vscroll $path]
+ } else {
+ $path:cmd coords view -2 -2 -2 -2
+ set _widget(oldxscroll) {}
+ set _widget(oldyscroll) {}
+ }
+ }
+
+ if { [Widget::hasChanged $path -fill fill] |
+ [Widget::hasChanged $path -foreground fg] } {
+ $path:cmd itemconfigure view \
+ -fill $fill \
+ -outline $fg
+ }
+
+ return $res
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::cget
+# ------------------------------------------------------------------------------
+proc ScrollView::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::_set_hscroll
+# ------------------------------------------------------------------------------
+proc ScrollView::_set_hscroll { path vmin vmax } {
+ Widget::getVariable $path _widget
+
+ set c [$path:cmd coords view]
+ set x0 [expr {$vmin*$_widget(width)+$_widget(bd)}]
+ set x1 [expr {$vmax*$_widget(width)+$_widget(bd)-1}]
+ $path:cmd coords view $x0 [lindex $c 1] $x1 [lindex $c 3]
+ if { $_widget(oldxscroll) != "" } {
+ uplevel \#0 $_widget(oldxscroll) $vmin $vmax
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::_set_vscroll
+# ------------------------------------------------------------------------------
+proc ScrollView::_set_vscroll { path vmin vmax } {
+ Widget::getVariable $path _widget
+
+ set c [$path:cmd coords view]
+ set y0 [expr {$vmin*$_widget(height)+$_widget(bd)}]
+ set y1 [expr {$vmax*$_widget(height)+$_widget(bd)-1}]
+ $path:cmd coords view [lindex $c 0] $y0 [lindex $c 2] $y1
+ if { $_widget(oldyscroll) != "" } {
+ uplevel \#0 $_widget(oldyscroll) $vmin $vmax
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::_update_scroll
+# ------------------------------------------------------------------------------
+proc ScrollView::_update_scroll { path callscroll hminmax vminmax } {
+ Widget::getVariable $path _widget
+
+ set c [$path:cmd coords view]
+ set hmin [lindex $hminmax 0]
+ set hmax [lindex $hminmax 1]
+ set vmin [lindex $vminmax 0]
+ set vmax [lindex $vminmax 1]
+ set x0 [expr {$hmin*$_widget(width)+$_widget(bd)}]
+ set x1 [expr {$hmax*$_widget(width)+$_widget(bd)-1}]
+ set y0 [expr {$vmin*$_widget(height)+$_widget(bd)}]
+ set y1 [expr {$vmax*$_widget(height)+$_widget(bd)-1}]
+ $path:cmd coords view $x0 $y0 $x1 $y1
+ if { $callscroll } {
+ if { $_widget(oldxscroll) != "" } {
+ uplevel \#0 $_widget(oldxscroll) $hmin $hmax
+ }
+ if { $_widget(oldyscroll) != "" } {
+ uplevel \#0 $_widget(oldyscroll) $vmin $vmax
+ }
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::_set_view
+# ------------------------------------------------------------------------------
+proc ScrollView::_set_view { path cmd x y } {
+ Widget::getVariable $path _widget
+
+ set w [Widget::getoption $path -window]
+ if {[winfo exists $w]} {
+ if {[string equal $cmd "set"]} {
+ set c [$path:cmd coords view]
+ set x0 [lindex $c 0]
+ set y0 [lindex $c 1]
+ set x1 [lindex $c 2]
+ set y1 [lindex $c 3]
+ if {$x >= $x0 && $x <= $x1 &&
+ $y >= $y0 && $y <= $y1} {
+ set _widget(dx) [expr {$x-$x0}]
+ set _widget(dy) [expr {$y-$y0}]
+ return
+ } else {
+ set x0 [expr {$x-($x1-$x0)/2}]
+ set y0 [expr {$y-($y1-$y0)/2}]
+ set _widget(dx) [expr {$x-$x0}]
+ set _widget(dy) [expr {$y-$y0}]
+ set vh [expr {double($x0-$_widget(bd))/$_widget(width)}]
+ set vv [expr {double($y0-$_widget(bd))/$_widget(height)}]
+ }
+ } elseif {[string equal $cmd "motion"]} {
+ set vh [expr {double($x-$_widget(dx)-$_widget(bd))/$_widget(width)}]
+ set vv [expr {double($y-$_widget(dy)-$_widget(bd))/$_widget(height)}]
+ }
+ $w xview moveto $vh
+ $w yview moveto $vv
+ _update_scroll $path 1 [$w xview] [$w yview]
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::_resize
+# ------------------------------------------------------------------------------
+proc ScrollView::_resize { path } {
+ Widget::getVariable $path _widget
+
+ set _widget(bd) [Widget::getoption $path -borderwidth]
+ set _widget(width) [expr {[winfo width $path]-2*$_widget(bd)}]
+ set _widget(height) [expr {[winfo height $path]-2*$_widget(bd)}]
+ set w [Widget::getoption $path -window]
+ if { [winfo exists $w] } {
+ _update_scroll $path 0 [$w xview] [$w yview]
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# Command ScrollView::_destroy
+# ------------------------------------------------------------------------------
+proc ScrollView::_destroy { path } {
+ Widget::getVariable $path _widget
+
+ set w [Widget::getoption $path -window]
+ if { [winfo exists $w] } {
+ $w configure \
+ -xscrollcommand $_widget(oldxscroll) \
+ -yscrollcommand $_widget(oldyscroll)
+ }
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/scrollw.tcl b/modules/tclsci/tcl/BWidget/scrollw.tcl
new file mode 100755
index 000000000..d81a5a4f4
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/scrollw.tcl
@@ -0,0 +1,294 @@
+# -----------------------------------------------------------------------------
+# scrollw.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: scrollw.tcl,v 1.13.2.1 2010/11/23 08:21:17 oehhar Exp $
+# -----------------------------------------------------------------------------
+# Index of commands:
+# - ScrolledWindow::create
+# - ScrolledWindow::getframe
+# - ScrolledWindow::setwidget
+# - ScrolledWindow::configure
+# - ScrolledWindow::cget
+# - ScrolledWindow::_set_hframe
+# - ScrolledWindow::_set_vscroll
+# - ScrolledWindow::_setData
+# - ScrolledWindow::_setSBSize
+# - ScrolledWindow::_realize
+# -----------------------------------------------------------------------------
+
+namespace eval ScrolledWindow {
+ Widget::define ScrolledWindow scrollw
+
+ Widget::declare ScrolledWindow {
+ {-background TkResource "" 0 button}
+ {-scrollbar Enum both 0 {none both vertical horizontal}}
+ {-auto Enum both 0 {none both vertical horizontal}}
+ {-sides Enum se 0 {ne en nw wn se es sw ws}}
+ {-size Int 0 1 "%d >= 0"}
+ {-ipad Int 1 1 "%d >= 0"}
+ {-managed Boolean 1 1}
+ {-relief TkResource flat 0 frame}
+ {-borderwidth TkResource 0 0 frame}
+ {-bg Synonym -background}
+ {-bd Synonym -borderwidth}
+ }
+
+ Widget::addmap ScrolledWindow "" :cmd {-relief {} -borderwidth {}}
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::create
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::create { path args } {
+ Widget::init ScrolledWindow $path $args
+
+ Widget::getVariable $path data
+
+ set bg [Widget::cget $path -background]
+ set sbsize [Widget::cget $path -size]
+
+ if { $::Widget::_theme } {
+ set sw [eval [list ttk::frame $path \
+ -relief flat -borderwidth 0 -takefocus 0] \
+ [Widget::subcget $path :cmd]]
+ ttk::scrollbar $path.hscroll \
+ -takefocus 0 -orient horiz
+ ttk::scrollbar $path.vscroll \
+ -takefocus 0 -orient vert
+ } else {
+ set sw [eval [list frame $path \
+ -relief flat -borderwidth 0 -background $bg \
+ -highlightthickness 0 -takefocus 0] \
+ [Widget::subcget $path :cmd]]
+ scrollbar $path.hscroll \
+ -highlightthickness 0 -takefocus 0 \
+ -orient horiz \
+ -relief sunken \
+ -bg $bg
+ scrollbar $path.vscroll \
+ -highlightthickness 0 -takefocus 0 \
+ -orient vert \
+ -relief sunken \
+ -bg $bg
+ }
+
+ set data(realized) 0
+
+ _setData $path \
+ [Widget::cget $path -scrollbar] \
+ [Widget::cget $path -auto] \
+ [Widget::cget $path -sides]
+
+ if {[Widget::cget $path -managed]} {
+ set data(hsb,packed) $data(hsb,present)
+ set data(vsb,packed) $data(vsb,present)
+ } else {
+ set data(hsb,packed) 0
+ set data(vsb,packed) 0
+ }
+ if { ! $::Widget::_theme } {
+ if {$sbsize} {
+ $path.vscroll configure -width $sbsize
+ $path.hscroll configure -width $sbsize
+ } else {
+ set sbsize [$path.vscroll cget -width]
+ }
+ }
+ set data(ipad) [Widget::cget $path -ipad]
+
+ if {$data(hsb,packed)} {
+ grid $path.hscroll -column 1 -row $data(hsb,row) \
+ -sticky ew -ipady $data(ipad)
+ }
+ if {$data(vsb,packed)} {
+ grid $path.vscroll -column $data(vsb,column) -row 1 \
+ -sticky ns -ipadx $data(ipad)
+ }
+
+ grid columnconfigure $path 1 -weight 1
+ grid rowconfigure $path 1 -weight 1
+
+ bind $path <Configure> [list ScrolledWindow::_realize $path]
+ bind $path <Destroy> [list ScrolledWindow::_destroy $path]
+
+ return [Widget::create ScrolledWindow $path]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::getframe
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::getframe { path } {
+ return $path
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::setwidget
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::setwidget { path widget } {
+ Widget::getVariable $path data
+
+ if {[info exists data(widget)] && [winfo exists $data(widget)]
+ && ![string equal $data(widget) $widget]} {
+ grid remove $data(widget)
+ $data(widget) configure -xscrollcommand "" -yscrollcommand ""
+ }
+ set data(widget) $widget
+ grid $widget -in $path -row 1 -column 1 -sticky news
+
+ $path.hscroll configure -command [list $widget xview]
+ $path.vscroll configure -command [list $widget yview]
+ $widget configure \
+ -xscrollcommand [list ScrolledWindow::_set_hscroll $path] \
+ -yscrollcommand [list ScrolledWindow::_set_vscroll $path]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::configure
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::configure { path args } {
+ Widget::getVariable $path data
+
+ set res [Widget::configure $path $args]
+ if { ! $::Widget::_theme && [Widget::hasChanged $path -background bg] } {
+ $path configure -background $bg
+ catch {$path.hscroll configure -background $bg}
+ catch {$path.vscroll configure -background $bg}
+ }
+
+ if {[Widget::hasChanged $path -scrollbar scrollbar] | \
+ [Widget::hasChanged $path -auto auto] | \
+ [Widget::hasChanged $path -sides sides]} {
+ _setData $path $scrollbar $auto $sides
+ foreach {vmin vmax} [$path.hscroll get] { break }
+ set data(hsb,packed) [expr {$data(hsb,present) && \
+ (!$data(hsb,auto) || ($vmin != 0 || $vmax != 1))}]
+ foreach {vmin vmax} [$path.vscroll get] { break }
+ set data(vsb,packed) [expr {$data(vsb,present) && \
+ (!$data(vsb,auto) || ($vmin != 0 || $vmax != 1))}]
+
+ set data(ipad) [Widget::cget $path -ipad]
+
+ if {$data(hsb,packed)} {
+ grid $path.hscroll -column 1 -row $data(hsb,row) \
+ -sticky ew -ipady $data(ipad)
+ } else {
+ if {![info exists data(hlock)]} {
+ set data(hsb,packed) 0
+ grid remove $path.hscroll
+ }
+ }
+ if {$data(vsb,packed)} {
+ grid $path.vscroll -column $data(vsb,column) -row 1 \
+ -sticky ns -ipadx $data(ipad)
+ } else {
+ if {![info exists data(hlock)]} {
+ set data(vsb,packed) 0
+ grid remove $path.vscroll
+ }
+ }
+ }
+ return $res
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::cget
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::_set_hscroll
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::_set_hscroll { path vmin vmax } {
+ Widget::getVariable $path data
+
+ if {$data(realized) && $data(hsb,present)} {
+ if {$data(hsb,auto) && ![info exists data(hlock)]} {
+ if {$data(hsb,packed) && $vmin == 0 && $vmax == 1} {
+ set data(hsb,packed) 0
+ grid remove $path.hscroll
+ set data(hlock) 1
+ update idletasks
+ unset data(hlock)
+ } elseif {!$data(hsb,packed) && ($vmin != 0 || $vmax != 1)} {
+ set data(hsb,packed) 1
+ grid $path.hscroll -column 1 -row $data(hsb,row) \
+ -sticky ew -ipady $data(ipad)
+ set data(hlock) 1
+ update idletasks
+ unset data(hlock)
+ }
+ }
+ $path.hscroll set $vmin $vmax
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::_set_vscroll
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::_set_vscroll { path vmin vmax } {
+ Widget::getVariable $path data
+
+ if {$data(realized) && $data(vsb,present)} {
+ if {$data(vsb,auto) && ![info exists data(vlock)]} {
+ if {$data(vsb,packed) && $vmin == 0 && $vmax == 1} {
+ set data(vsb,packed) 0
+ grid remove $path.vscroll
+ set data(vlock) 1
+ update idletasks
+ unset data(vlock)
+ } elseif {!$data(vsb,packed) && ($vmin != 0 || $vmax != 1) } {
+ set data(vsb,packed) 1
+ grid $path.vscroll -column $data(vsb,column) -row 1 \
+ -sticky ns -ipadx $data(ipad)
+ set data(vlock) 1
+ update idletasks
+ unset data(vlock)
+ }
+ }
+ $path.vscroll set $vmin $vmax
+ }
+}
+
+
+proc ScrolledWindow::_setData {path scrollbar auto sides} {
+ Widget::getVariable $path data
+
+ set sb [lsearch {none horizontal vertical both} $scrollbar]
+ set auto [lsearch {none horizontal vertical both} $auto]
+
+ set data(hsb,present) [expr {($sb & 1) != 0}]
+ set data(hsb,auto) [expr {($auto & 1) != 0}]
+ set data(hsb,row) [expr {[string match *n* $sides] ? 0 : 2}]
+
+ set data(vsb,present) [expr {($sb & 2) != 0}]
+ set data(vsb,auto) [expr {($auto & 2) != 0}]
+ set data(vsb,column) [expr {[string match *w* $sides] ? 0 : 2}]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::_realize
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::_realize { path } {
+ Widget::getVariable $path data
+
+ bind $path <Configure> {}
+ set data(realized) 1
+}
+
+
+# -----------------------------------------------------------------------------
+# Command ScrolledWindow::_destroy
+# -----------------------------------------------------------------------------
+proc ScrolledWindow::_destroy { path } {
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/separator.tcl b/modules/tclsci/tcl/BWidget/separator.tcl
new file mode 100755
index 000000000..bae87b5ac
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/separator.tcl
@@ -0,0 +1,75 @@
+# ------------------------------------------------------------------------------
+# separator.tcl
+# This file is part of Unifix BWidget Toolkit
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - Separator::create
+# - Separator::configure
+# - Separator::cget
+# ------------------------------------------------------------------------------
+
+namespace eval Separator {
+ Widget::define Separator separator
+
+ Widget::declare Separator {
+ {-background TkResource "" 0 frame}
+ {-cursor TkResource "" 0 frame}
+ {-relief Enum groove 0 {ridge groove}}
+ {-orient Enum horizontal 1 {horizontal vertical}}
+ {-bg Synonym -background}
+ }
+ Widget::addmap Separator "" :cmd { -background {} -cursor {} }
+
+ bind Separator <Destroy> [list Widget::destroy %W]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Separator::create
+# ------------------------------------------------------------------------------
+proc Separator::create { path args } {
+ array set maps [list Separator {} :cmd {}]
+ array set maps [Widget::parseArgs Separator $args]
+ eval [list frame $path] $maps(:cmd) -class Separator
+ Widget::initFromODB Separator $path $maps(Separator)
+
+ if { [Widget::cget $path -orient] == "horizontal" } {
+ $path configure -borderwidth 1 -height 2
+ } else {
+ $path configure -borderwidth 1 -width 2
+ }
+
+ if { [string equal [Widget::cget $path -relief] "groove"] } {
+ $path configure -relief sunken
+ } else {
+ $path configure -relief raised
+ }
+
+ return [Widget::create Separator $path]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Separator::configure
+# ------------------------------------------------------------------------------
+proc Separator::configure { path args } {
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -relief relief] } {
+ if { $relief == "groove" } {
+ $path:cmd configure -relief sunken
+ } else {
+ $path:cmd configure -relief raised
+ }
+ }
+
+ return $res
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Separator::cget
+# ------------------------------------------------------------------------------
+proc Separator::cget { path option } {
+ return [Widget::cget $path $option]
+}
diff --git a/modules/tclsci/tcl/BWidget/spinbox.tcl b/modules/tclsci/tcl/BWidget/spinbox.tcl
new file mode 100755
index 000000000..a89e3754f
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/spinbox.tcl
@@ -0,0 +1,331 @@
+# spinbox.tcl --
+#
+# BWidget SpinBox implementation.
+#
+# Copyright (c) 1999 by Unifix
+# Copyright (c) 2000 by Ajuba Solutions
+# All rights reserved.
+#
+# RCS: @(#) $Id: spinbox.tcl,v 1.12 2003/10/20 21:23:52 damonc Exp $
+# -----------------------------------------------------------------------------
+# Index of commands:
+# - SpinBox::create
+# - SpinBox::configure
+# - SpinBox::cget
+# - SpinBox::setvalue
+# - SpinBox::_destroy
+# - SpinBox::_modify_value
+# - SpinBox::_test_options
+# -----------------------------------------------------------------------------
+
+namespace eval SpinBox {
+ Widget::define SpinBox spinbox Entry ArrowButton
+
+ Widget::tkinclude SpinBox frame :cmd \
+ include {-background -borderwidth -bg -bd -relief} \
+ initialize {-relief sunken -borderwidth 2}
+
+ Widget::bwinclude SpinBox Entry .e \
+ remove {-relief -bd -borderwidth -fg -bg} \
+ rename {-foreground -entryfg -background -entrybg}
+
+ Widget::declare SpinBox {
+ {-range String "" 0}
+ {-values String "" 0}
+ {-modifycmd String "" 0}
+ {-repeatdelay Int 400 0 {%d >= 0}}
+ {-repeatinterval Int 100 0 {%d >= 0}}
+ {-foreground TkResource black 0 {button}}
+ }
+
+ Widget::addmap SpinBox "" :cmd {-background {}}
+ Widget::addmap SpinBox ArrowButton .arrup {
+ -foreground {} -background {} -disabledforeground {} -state {} \
+ -repeatinterval {} -repeatdelay {}
+ }
+ Widget::addmap SpinBox ArrowButton .arrdn {
+ -foreground {} -background {} -disabledforeground {} -state {} \
+ -repeatinterval {} -repeatdelay {}
+ }
+
+ ::bind SpinBox <FocusIn> [list after idle {BWidget::refocus %W %W.e}]
+ ::bind SpinBox <Destroy> [list SpinBox::_destroy %W]
+
+ variable _widget
+}
+
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::create
+# -----------------------------------------------------------------------------
+proc SpinBox::create { path args } {
+ array set maps [list SpinBox {} :cmd {} .e {} .arrup {} .arrdn {}]
+ array set maps [Widget::parseArgs SpinBox $args]
+ eval [list frame $path] $maps(:cmd) \
+ [list -highlightthickness 0 -takefocus 0 -class SpinBox]
+ Widget::initFromODB SpinBox $path $maps(SpinBox)
+
+ set entry [eval [list Entry::create $path.e] $maps(.e) -relief flat -bd 0]
+ bindtags $path.e [linsert [bindtags $path.e] 1 SpinBoxEntry]
+
+ set farr [frame $path.farr -relief flat -bd 0 -highlightthickness 0]
+ set height [expr {[winfo reqheight $path.e]/2-2}]
+ set width 11
+ set arrup [eval [list ArrowButton::create $path.arrup -dir top] \
+ $maps(.arrup) \
+ [list -highlightthickness 0 -borderwidth 1 -takefocus 0 \
+ -type button -width $width -height $height \
+ -armcommand [list SpinBox::_modify_value $path next arm] \
+ -disarmcommand [list SpinBox::_modify_value $path next disarm]]]
+ set arrdn [eval [list ArrowButton::create $path.arrdn -dir bottom] \
+ $maps(.arrdn) \
+ [list -highlightthickness 0 -borderwidth 1 -takefocus 0 \
+ -type button -width $width -height $height \
+ -armcommand [list SpinBox::_modify_value $path previous arm] \
+ -disarmcommand [list SpinBox::_modify_value $path previous disarm]]]
+
+ # --- update SpinBox value ---
+ _test_options $path
+ set val [Entry::cget $path.e -text]
+ if { [string equal $val ""] } {
+ Entry::configure $path.e -text $::SpinBox::_widget($path,curval)
+ } else {
+ set ::SpinBox::_widget($path,curval) $val
+ }
+
+ grid $arrup -in $farr -column 0 -row 0 -sticky nsew
+ grid $arrdn -in $farr -column 0 -row 2 -sticky nsew
+ grid rowconfigure $farr 0 -weight 1
+ grid rowconfigure $farr 2 -weight 1
+
+ pack $farr -side right -fill y
+ pack $entry -side left -fill both -expand yes
+
+ ::bind $entry <Key-Up> [list SpinBox::_modify_value $path next activate]
+ ::bind $entry <Key-Down> [list SpinBox::_modify_value $path previous activate]
+ ::bind $entry <Key-Prior> [list SpinBox::_modify_value $path last activate]
+ ::bind $entry <Key-Next> [list SpinBox::_modify_value $path first activate]
+
+ ::bind $farr <Configure> {grid rowconfigure %W 1 -minsize [expr {%h%%2}]}
+
+ return [Widget::create SpinBox $path]
+}
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::configure
+# -----------------------------------------------------------------------------
+proc SpinBox::configure { path args } {
+ set res [Widget::configure $path $args]
+ if { [Widget::hasChangedX $path -values] ||
+ [Widget::hasChangedX $path -range] } {
+ _test_options $path
+ }
+ return $res
+}
+
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::cget
+# -----------------------------------------------------------------------------
+proc SpinBox::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::setvalue
+# -----------------------------------------------------------------------------
+proc SpinBox::setvalue { path index } {
+ variable _widget
+
+ set values [Widget::getMegawidgetOption $path -values]
+ set value [Entry::cget $path.e -text]
+
+ if { [llength $values] } {
+ # --- -values SpinBox ---
+ switch -- $index {
+ next {
+ if { [set idx [lsearch $values $value]] != -1 } {
+ incr idx
+ } elseif { [set idx [lsearch $values "$value*"]] == -1 } {
+ set idx [lsearch $values $_widget($path,curval)]
+ }
+ }
+ previous {
+ if { [set idx [lsearch $values $value]] != -1 } {
+ incr idx -1
+ } elseif { [set idx [lsearch $values "$value*"]] == -1 } {
+ set idx [lsearch $values $_widget($path,curval)]
+ }
+ }
+ first {
+ set idx 0
+ }
+ last {
+ set idx [expr {[llength $values]-1}]
+ }
+ default {
+ if { [string index $index 0] == "@" } {
+ set idx [string range $index 1 end]
+ if { [catch {string compare [expr {int($idx)}] $idx} res] || $res != 0 } {
+ return -code error "bad index \"$index\""
+ }
+ } else {
+ return -code error "bad index \"$index\""
+ }
+ }
+ }
+ if { $idx >= 0 && $idx < [llength $values] } {
+ set newval [lindex $values $idx]
+ } else {
+ return 0
+ }
+ } else {
+ # --- -range SpinBox ---
+ foreach {vmin vmax incr} [Widget::getMegawidgetOption $path -range] {
+ break
+ }
+ # Allow zero padding on the value; strip it out for calculation by
+ # scanning the value into a floating point number.
+ scan $value %f value
+ switch -- $index {
+ next {
+ if { [catch {expr {double($value-$vmin)/$incr}} idx] } {
+ set newval $_widget($path,curval)
+ } else {
+ set newval [expr {$vmin+(round($idx)+1)*$incr}]
+ if { $newval < $vmin } {
+ set newval $vmin
+ } elseif { $newval > $vmax } {
+ set newval $vmax
+ }
+ }
+ }
+ previous {
+ if { [catch {expr {double($value-$vmin)/$incr}} idx] } {
+ set newval $_widget($path,curval)
+ } else {
+ set newval [expr {$vmin+(round($idx)-1)*$incr}]
+ if { $newval < $vmin } {
+ set newval $vmin
+ } elseif { $newval > $vmax } {
+ set newval $vmax
+ }
+ }
+ }
+ first {
+ set newval $vmin
+ }
+ last {
+ set newval $vmax
+ }
+ default {
+ if { [string index $index 0] == "@" } {
+ set idx [string range $index 1 end]
+ if { [catch {string compare [expr {int($idx)}] $idx} res] || $res != 0 } {
+ return -code error "bad index \"$index\""
+ }
+ set newval [expr {$vmin+int($idx)*$incr}]
+ if { $newval < $vmin || $newval > $vmax } {
+ return 0
+ }
+ } else {
+ return -code error "bad index \"$index\""
+ }
+ }
+ }
+ }
+ set _widget($path,curval) $newval
+ Entry::configure $path.e -text $newval
+ return 1
+}
+
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::getvalue
+# -----------------------------------------------------------------------------
+proc SpinBox::getvalue { path } {
+ variable _widget
+
+ set values [Widget::getMegawidgetOption $path -values]
+ set value [Entry::cget $path.e -text]
+
+ if { [llength $values] } {
+ # --- -values SpinBox ---
+ return [lsearch $values $value]
+ } else {
+ foreach {vmin vmax incr} [Widget::getMegawidgetOption $path -range] {
+ break
+ }
+ if { ![catch {expr {double($value-$vmin)/$incr}} idx] &&
+ $idx == int($idx) } {
+ return [expr {int($idx)}]
+ }
+ return -1
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::bind
+# -----------------------------------------------------------------------------
+proc SpinBox::bind { path args } {
+ return [eval [list ::bind $path.e] $args]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::_modify_value
+# -----------------------------------------------------------------------------
+proc SpinBox::_modify_value { path direction reason } {
+ if { $reason == "arm" || $reason == "activate" } {
+ SpinBox::setvalue $path $direction
+ }
+ if { ($reason == "disarm" || $reason == "activate") &&
+ [set cmd [Widget::getMegawidgetOption $path -modifycmd]] != "" } {
+ uplevel \#0 $cmd
+ }
+}
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::_test_options
+# -----------------------------------------------------------------------------
+proc SpinBox::_test_options { path } {
+ set values [Widget::getMegawidgetOption $path -values]
+ if { [llength $values] } {
+ set ::SpinBox::_widget($path,curval) [lindex $values 0]
+ } else {
+ foreach {vmin vmax incr} [Widget::getMegawidgetOption $path -range] {
+ break
+ }
+ set update 0
+ if { [catch {expr {int($vmin)}}] } {
+ set vmin 0
+ set update 1
+ }
+ if { [catch {expr {$vmax<$vmin}} res] || $res } {
+ set vmax $vmin
+ set update 1
+ }
+ if { [catch {expr {$incr<0}} res] || $res } {
+ set incr 1
+ set update 1
+ }
+ # Only do the set back (which is expensive) if we changed a value
+ if { $update } {
+ Widget::setMegawidgetOption $path -range [list $vmin $vmax $incr]
+ }
+ set ::SpinBox::_widget($path,curval) $vmin
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command SpinBox::_destroy
+# -----------------------------------------------------------------------------
+proc SpinBox::_destroy { path } {
+ variable _widget
+
+ unset _widget($path,curval)
+ Widget::destroy $path
+}
diff --git a/modules/tclsci/tcl/BWidget/statusbar.tcl b/modules/tclsci/tcl/BWidget/statusbar.tcl
new file mode 100755
index 000000000..568c4acda
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/statusbar.tcl
@@ -0,0 +1,422 @@
+# ------------------------------------------------------------------------
+# statusbar.tcl
+# Create a status bar Tk widget
+#
+# Provides a status bar to be placed at the bottom of a toplevel.
+# Currently does not support being placed in a toplevel that has
+# gridding applied (via widget -setgrid or wm grid).
+#
+# Ensure that the widget is placed at the very bottom of the toplevel,
+# otherwise the resize behavior may behave oddly.
+# ------------------------------------------------------------------------
+
+package require Tk 8.3
+
+if {0} {
+ proc sample {} {
+ # sample usage
+ eval destroy [winfo children .]
+ pack [text .t -width 0 -height 0] -fill both -expand 1
+
+ set sbar .s
+ StatusBar $sbar
+ pack $sbar -side bottom -fill x
+ set f [$sbar getframe]
+
+ # Specify -width 1 for the label widget so it truncates nicely
+ # instead of requesting large sizes for long messages
+ set w [label $f.status -width 1 -anchor w -textvariable ::STATUS]
+ set ::STATUS "This is a status message"
+ # give the entry weight, as we want it to be the one that expands
+ $sbar add $w -weight 1
+
+ # BWidget's progressbar
+ set w [ProgressBar $f.bpbar -orient horizontal \
+ -variable ::PROGRESS -bd 1 -relief sunken]
+ set ::PROGRESS 50
+ $sbar add $w
+ }
+}
+
+namespace eval StatusBar {
+ Widget::define StatusBar statusbar
+
+ Widget::declare StatusBar {
+ {-background TkResource "" 0 frame}
+ {-borderwidth TkResource 0 0 frame}
+ {-relief TkResource flat 0 frame}
+ {-showseparator Boolean 1 0}
+ {-showresizesep Boolean 0 0}
+ {-showresize Boolean 1 0}
+ {-width TkResource 100 0 frame}
+ {-height TkResource 18 0 frame}
+ {-ipad String 1 0}
+ {-pad String 0 0}
+ {-bg Synonym -background}
+ {-bd Synonym -borderwidth}
+ }
+
+ # -background, -borderwidth and -relief apply to outer frame, but relief
+ # should be left flat for proper look
+ Widget::addmap StatusBar "" :cmd {
+ -background {} -width {} -height {} -borderwidth {} -relief {}
+ }
+ Widget::addmap StatusBar "" .sbar {
+ -background {}
+ }
+ Widget::addmap StatusBar "" .resize {
+ -background {}
+ }
+ Widget::addmap StatusBar "" .hsep {
+ -background {}
+ }
+
+ # -pad provides general padding around the status bar
+ # -ipad provides padding around each status bar item
+ # Padding can be a list of {padx pady}
+
+ variable HaveMarlett \
+ [expr {[lsearch -exact [font families] "Marlett"] != -1}]
+
+ bind StatusResize <1> \
+ [namespace code [list begin_resize %W %X %Y]]
+ bind StatusResize <B1-Motion> \
+ [namespace code [list continue_resize %W %X %Y]]
+ bind StatusResize <ButtonRelease-1> \
+ [namespace code [list end_resize %W %X %Y]]
+
+ bind StatusBar <Destroy> [list StatusBar::_destroy %W]
+
+ # PNG version has partial alpha transparency for better look
+ variable pngdata {
+ iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAFM0aXcAAAABGdBTUEAAYagM
+ eiWXwAAAGJJREFUGJW9kVEOgCAMQzs8GEezN69fkKlbUAz2r3l5NGTA+pCU+Q
+ IA5sv39wGgZKClZGBhJMVTklRr3VNwMz04mVfQzQiEm79EkrYZycxIkq8kkv2
+ v6RFGku9TUrj8RGr9AGy6mhv2ymLwAAAAAElFTkSuQmCC
+ }
+ variable gifdata {
+ R0lGODlhDwAPAJEAANnZ2f///4CAgD8/PyH5BAEAAAAALAAAAAAPAA8AAAJEh
+ I+py+1IQvh4IZlG0Qg+QshkAokGQfAvZCBIhG8hA0Ea4UPIQJBG+BAyEKQhCH
+ bIQAgNEQCAIA0hAyE0AEIGgjSEDBQAOw==
+ }
+ if {[package provide img::png] != ""} {
+ image create photo ::StatusBar::resizer -format PNG -data $pngdata
+ } else {
+ image create photo ::StatusBar::resizer -format GIF -data $gifdata
+ }
+}
+
+
+# ------------------------------------------------------------------------
+# Command StatusBar::create
+# ------------------------------------------------------------------------
+proc StatusBar::create { path args } {
+ variable _widget
+ variable HaveMarlett
+
+ # Allow for img::png loaded after initial source
+ if {[package provide img::png] != ""} {
+ variable pngdata
+ ::StatusBar::resizer configure -format PNG -data $pngdata
+ }
+
+ Widget::init StatusBar $path $args
+
+ eval [list frame $path -class StatusBar] [Widget::subcget $path :cmd]
+
+ foreach {padx pady} [_padval [Widget::cget $path -pad]] \
+ {ipadx ipady} [_padval [Widget::cget $path -ipad]] { break }
+
+ if {[Widget::theme]} {
+ set sbar [ttk::frame $path.sbar -padding [list $padx $pady]]
+ } else {
+ set sbar [eval [list frame $path.sbar -padx $padx -pady $pady] \
+ [Widget::subcget $path .sbar]]
+ }
+ if {[string equal $::tcl_platform(platform) "windows"]} {
+ set cursor size_nw_se
+ } else {
+ set cursor sizing; # bottom_right_corner ??
+ }
+ set resize [eval [list label $path.resize] \
+ [Widget::subcget $path .resize] \
+ [list -borderwidth 0 -relief flat -anchor se \
+ -cursor $cursor -anchor se -padx 0 -pady 0]]
+ if {$HaveMarlett} {
+ $resize configure -font "Marlett -16" -text \u006f
+ } else {
+ $resize configure -image ::StatusBar::resizer
+ }
+ bindtags $resize [list all [winfo toplevel $path] StatusResize $resize]
+
+ if {[Widget::theme]} {
+ set fsep [ttk::separator $path.hsep -orient horizontal]
+ } else {
+ set fsep [eval [list frame $path.hsep -bd 1 -height 2 -relief sunken] \
+ [Widget::subcget $path .hsep]]
+ }
+ set sep [_sep $path sepresize {}]
+
+ grid $fsep -row 0 -column 0 -columnspan 3 -sticky ew
+ grid $sbar -row 1 -column 0 -sticky news
+ grid $sep -row 1 -column 1 -sticky ns -padx $ipadx -pady $ipady
+ grid $resize -row 1 -column 2 -sticky news
+ grid columnconfigure $path 0 -weight 1
+ if {![Widget::cget $path -showseparator]} {
+ grid remove $fsep
+ }
+ if {![Widget::cget $path -showresize]} {
+ grid remove $sep $resize
+ } elseif {![Widget::cget $path -showresizesep]} {
+ grid remove $sep
+ }
+ set _widget($path,items) {}
+
+ return [Widget::create StatusBar $path]
+}
+
+
+# ------------------------------------------------------------------------
+# Command StatusBar::configure
+# ------------------------------------------------------------------------
+proc StatusBar::configure { path args } {
+ variable _widget
+
+ set res [Widget::configure $path $args]
+
+ foreach {chshow chshowrsep chshowsep chipad chpad} \
+ [Widget::hasChangedX $path -showresize -showresizesep -showseparator \
+ -ipad -pad] { break }
+
+ if {$chshow} {
+ set show [Widget::cget $path -showresize]
+ set showrsep [Widget::cget $path -showresizesep]
+ if {$show} {
+ if {$showrsep} {
+ grid $path.sepresize
+ }
+ grid $path.resize
+ } else {
+ grid remove $path.sepresize $path.resize
+ }
+ }
+ if {$chshowsep} {
+ if {$show} {
+ grid $path.hsep
+ } else {
+ grid remove $path.hsep
+ }
+ }
+ if {$chipad} {
+ foreach {ipadx ipady} [_padval [Widget::cget $path -ipad]] { break }
+ foreach w [grid slaves $path.sbar] {
+ grid configure $w -padx $ipadx -pady $ipady
+ }
+ }
+ if {$chpad} {
+ foreach {padx pady} [_padval [Widget::cget $path -pad]] { break }
+ if {[string equal [winfo class $path.sbar] "TFrame"]} {
+ $path.sbar configure -padding [list $padx $pady]
+ } else {
+ $path.sbar configure -padx $padx -pady $pady
+ }
+ }
+ return $res
+}
+
+
+# ------------------------------------------------------------------------
+# Command StatusBar::cget
+# ------------------------------------------------------------------------
+proc StatusBar::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+# ------------------------------------------------------------------------
+# Command StatusBar::getframe
+# ------------------------------------------------------------------------
+proc StatusBar::getframe {path} {
+ # This is the frame that users should place their statusbar widgets in
+ return $path.sbar
+}
+
+# ------------------------------------------------------------------------
+# Command StatusBar::add
+# ------------------------------------------------------------------------
+proc StatusBar::add {path w args} {
+ variable _widget
+
+ array set opts [list \
+ -weight 0 \
+ -separator 1 \
+ -sticky news \
+ -pad [Widget::cget $path -ipad] \
+ ]
+ foreach {key val} $args {
+ if {[info exists opts($key)]} {
+ set opts($key) $val
+ } else {
+ set msg "unknown option \"$key\", must be one of: "
+ append msg [join [lsort [array names opts]] {, }]
+ return -code error $msg
+ }
+ }
+ foreach {ipadx ipady} [_padval $opts(-pad)] { break }
+
+ set sbar $path.sbar
+ foreach {cols rows} [grid size $sbar] break
+ # Add separator if requested, and we aren't the first element
+ if {$opts(-separator) && $cols != 0} {
+ set sep [_sep $path sep[winfo name $w]]
+ # only append name, to distinguish us from them
+ lappend _widget($path,items) [winfo name $sep]
+ grid $sep -in $sbar -row 0 -column $cols \
+ -sticky ns -padx $ipadx -pady $ipady
+ incr cols
+ }
+
+ lappend _widget($path,items) $w
+ grid $w -in $sbar -row 0 -column $cols -sticky $opts(-sticky) \
+ -padx $ipadx -pady $ipady
+ grid columnconfigure $sbar $cols -weight $opts(-weight)
+
+ return $w
+}
+
+# ------------------------------------------------------------------------
+# Command StatusBar::delete
+# ------------------------------------------------------------------------
+proc StatusBar::remove {path args} {
+ variable _widget
+
+ set destroy [string equal [lindex $args 0] "-destroy"]
+ if {$destroy} {
+ set args [lrange $args 1 end]
+ }
+ foreach w $args {
+ set idx [lsearch -exact $_widget($path,items) $w]
+ if {$idx == -1 || ![winfo exists $w]} {
+ # ignore unknown or non-widget items (like our separators)
+ continue
+ }
+ # separator is always previous item
+ set sidx [expr {$idx - 1}]
+ set sep [lindex $_widget($path,items) $sidx]
+ if {[string match .* $sep]} {
+ # not one of our separators
+ incr sidx
+ } elseif {$sep != ""} {
+ # destroy separator too
+ set sep $path.sbar.$sep
+ destroy $sep
+ }
+ if {$destroy} {
+ destroy $w
+ } else {
+ grid forget $w
+ }
+ if {$idx == 0} {
+ # separator of next item is no longer necessary
+ set sep [lindex $_widget($path,items) [expr {$idx + 1}]]
+ if {$sep != "" && ![string match .* $sep]} {
+ incr idx
+ set sep $path.sbar.$sep
+ destroy $sep
+ }
+ }
+ set _widget($path,items) [lreplace $_widget($path,items) $sidx $idx]
+ }
+}
+
+# ------------------------------------------------------------------------
+# Command StatusBar::delete
+# ------------------------------------------------------------------------
+proc StatusBar::delete {path args} {
+ return [StatusBar::remove $path -destroy $args]
+}
+
+# ------------------------------------------------------------------------
+# Command StatusBar::items
+# ------------------------------------------------------------------------
+proc StatusBar::items {path} {
+ variable _widget
+ return $_widget($path,items)
+}
+
+proc StatusBar::_sep {path name {sub .sbar}} {
+ if {[Widget::theme]} {
+ return [ttk::separator $path$sub.$name -orient vertical]
+ } else {
+ return [frame $path$sub.$name -bd 1 -width 2 -relief sunken]
+ }
+}
+
+proc StatusBar::_padval {padval} {
+ set len [llength $padval]
+ foreach {a b} $padval { break }
+ if {$len == 0 || $len > 2} {
+ return -code error \
+ "invalid pad value \"$padval\", must be 1 or 2 pixel values"
+ } elseif {$len == 1} {
+ return [list $a $a]
+ } elseif {$len == 2} {
+ return $padval
+ }
+}
+
+# ------------------------------------------------------------------------
+# Command StatusBar::_destroy
+# ------------------------------------------------------------------------
+proc StatusBar::_destroy { path } {
+ variable _widget
+ variable resize
+ array unset widget $path,*
+ array unset resize $path.resize,*
+ Widget::destroy $path
+}
+
+# The following proc handles the mouse click on the resize control. It stores
+# the original size of the window and the initial coords of the mouse relative
+# to the root.
+
+proc StatusBar::begin_resize {w rootx rooty} {
+ variable resize
+ set t [winfo toplevel $w]
+ set relx [expr {$rootx - [winfo rootx $t]}]
+ set rely [expr {$rooty - [winfo rooty $t]}]
+ set resize($w,x) $relx
+ set resize($w,y) $rely
+ set resize($w,w) [winfo width $t]
+ set resize($w,h) [winfo height $t]
+ set resize($w,winc) 1
+ set resize($w,hinc) 1
+ set resize($w,grid) [wm grid $t]
+}
+
+# The following proc handles mouse motion on the resize control by asking the
+# wm to adjust the size of the window.
+
+proc StatusBar::continue_resize {w rootx rooty} {
+ variable resize
+ if {[llength $resize($w,grid)]} {
+ # at this time, we don't know how to handle gridded resizing
+ return
+ }
+ set t [winfo toplevel $w]
+ set relx [expr {$rootx - [winfo rootx $t]}]
+ set rely [expr {$rooty - [winfo rooty $t]}]
+ set width [expr {$relx - $resize($w,x) + $resize($w,w)}]
+ set height [expr {$rely - $resize($w,y) + $resize($w,h)}]
+ if {$width < 0} { set width 0 }
+ if {$height < 0} { set height 0 }
+ wm geometry $t ${width}x${height}
+}
+
+# The following proc cleans up when the user releases the mouse button.
+
+proc StatusBar::end_resize {w rootx rooty} {
+ variable resize
+ #continue_resize $w $rootx $rooty
+ #wm grid $t $resize($w,grid)
+ array unset resize $w,*
+}
diff --git a/modules/tclsci/tcl/BWidget/titleframe.tcl b/modules/tclsci/tcl/BWidget/titleframe.tcl
new file mode 100755
index 000000000..d077c88af
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/titleframe.tcl
@@ -0,0 +1,170 @@
+# ------------------------------------------------------------------------------
+# titleframe.tcl
+# This file is part of Unifix BWidget Toolkit
+# ------------------------------------------------------------------------------
+# Index of commands:
+# - TitleFrame::create
+# - TitleFrame::configure
+# - TitleFrame::cget
+# - TitleFrame::getframe
+# - TitleFrame::_place
+# ------------------------------------------------------------------------------
+
+namespace eval TitleFrame {
+ Widget::define TitleFrame titleframe
+
+ Widget::declare TitleFrame {
+ {-relief TkResource groove 0 frame}
+ {-borderwidth TkResource 2 0 frame}
+ {-font TkResource "" 0 label}
+ {-foreground TkResource "" 0 label}
+ {-state TkResource "" 0 label}
+ {-background TkResource "" 0 frame}
+ {-text String "" 0}
+ {-ipad Int 4 0 "%d >=0"}
+ {-side Enum left 0 {left center right}}
+ {-baseline Enum center 0 {top center bottom}}
+ {-fg Synonym -foreground}
+ {-bg Synonym -background}
+ {-bd Synonym -borderwidth}
+ }
+
+ Widget::addmap TitleFrame "" :cmd {-background {}}
+ Widget::addmap TitleFrame "" .l {
+ -background {} -foreground {} -text {} -font {}
+ }
+ Widget::addmap TitleFrame "" .l {-state {}}
+ Widget::addmap TitleFrame "" .p {-background {}}
+ Widget::addmap TitleFrame "" .b {
+ -background {} -relief {} -borderwidth {}
+ }
+ Widget::addmap TitleFrame "" .b.p {-background {}}
+ Widget::addmap TitleFrame "" .f {-background {}}
+}
+
+
+# ------------------------------------------------------------------------------
+# Command TitleFrame::create
+# ------------------------------------------------------------------------------
+proc TitleFrame::create { path args } {
+ Widget::init TitleFrame $path $args
+
+ set frame [eval [list frame $path] [Widget::subcget $path :cmd] \
+ -class TitleFrame -relief flat -bd 0 -highlightthickness 0]
+
+ set padtop [eval [list frame $path.p] [Widget::subcget $path :cmd] \
+ -relief flat -borderwidth 0]
+ set border [eval [list frame $path.b] [Widget::subcget $path .b] -highlightthickness 0]
+ set label [eval [list label $path.l] [Widget::subcget $path .l] \
+ -highlightthickness 0 \
+ -relief flat \
+ -bd 0 -padx 2 -pady 0]
+ set padbot [eval [list frame $border.p] [Widget::subcget $path .p] \
+ -relief flat -bd 0 -highlightthickness 0]
+ set frame [eval [list frame $path.f] [Widget::subcget $path .f] \
+ -relief flat -bd 0 -highlightthickness 0]
+ set height [winfo reqheight $label]
+
+ switch [Widget::getoption $path -side] {
+ left { set relx 0.0; set x 5; set anchor nw }
+ center { set relx 0.5; set x 0; set anchor n }
+ right { set relx 1.0; set x -5; set anchor ne }
+ }
+ set bd [Widget::getoption $path -borderwidth]
+ switch [Widget::getoption $path -baseline] {
+ top {
+ set y 0
+ set htop $height
+ set hbot 1
+ }
+ center {
+ set y 0
+ set htop [expr {$height/2}]
+ set hbot [expr {$height/2+$height%2+1}]
+ }
+ bottom {
+ set y [expr {$bd+1}]
+ set htop 1
+ set hbot $height
+ }
+ }
+ $padtop configure -height $htop
+ $padbot configure -height $hbot
+
+ set pad [Widget::getoption $path -ipad]
+ pack $padbot -side top -fill x
+ pack $frame -in $border -fill both -expand yes -padx $pad -pady $pad
+
+ pack $padtop -side top -fill x
+ pack $border -fill both -expand yes
+
+ place $label -relx $relx -x $x -anchor $anchor -y $y
+
+ bind $label <Configure> [list TitleFrame::_place $path]
+ bind $path <Destroy> [list Widget::destroy %W]
+
+ return [Widget::create TitleFrame $path]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command TitleFrame::configure
+# ------------------------------------------------------------------------------
+proc TitleFrame::configure { path args } {
+ set res [Widget::configure $path $args]
+
+ if { [Widget::hasChanged $path -ipad pad] } {
+ pack configure $path.f -padx $pad -pady $pad
+ }
+ if { [Widget::hasChanged $path -borderwidth val] |
+ [Widget::hasChanged $path -font val] |
+ [Widget::hasChanged $path -side val] |
+ [Widget::hasChanged $path -baseline val] } {
+ _place $path
+ }
+
+ return $res
+}
+
+
+# ------------------------------------------------------------------------------
+# Command TitleFrame::cget
+# ------------------------------------------------------------------------------
+proc TitleFrame::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command TitleFrame::getframe
+# ------------------------------------------------------------------------------
+proc TitleFrame::getframe { path } {
+ return $path.f
+}
+
+
+# ------------------------------------------------------------------------------
+# Command TitleFrame::_place
+# ------------------------------------------------------------------------------
+proc TitleFrame::_place { path } {
+ set height [winfo height $path.l]
+ switch [Widget::getoption $path -side] {
+ left { set relx 0.0; set x 10; set anchor nw }
+ center { set relx 0.5; set x 0; set anchor n }
+ right { set relx 1.0; set x -10; set anchor ne }
+ }
+ set bd [Widget::getoption $path -borderwidth]
+ switch [Widget::getoption $path -baseline] {
+ top { set htop $height; set hbot 1; set y 0 }
+ center { set htop [expr {$height/2}]; set hbot [expr {$height/2+$height%2+1}]; set y 0 }
+ bottom { set htop 1; set hbot $height; set y [expr {$bd+1}] }
+ }
+ $path.p configure -height $htop
+ $path.b.p configure -height $hbot
+
+ place $path.l -relx $relx -x $x -anchor $anchor -y $y
+}
+
+
+
+
diff --git a/modules/tclsci/tcl/BWidget/tree.tcl b/modules/tclsci/tcl/BWidget/tree.tcl
new file mode 100755
index 000000000..122bec8e4
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/tree.tcl
@@ -0,0 +1,2251 @@
+# ----------------------------------------------------------------------------
+# tree.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: tree.tcl,v 1.60.2.3 2010/12/14 21:24:15 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - Tree::create
+# - Tree::configure
+# - Tree::cget
+# - Tree::insert
+# - Tree::itemconfigure
+# - Tree::itemcget
+# - Tree::bindArea
+# - Tree::bindText
+# - Tree::bindImage
+# - Tree::delete
+# - Tree::move
+# - Tree::reorder
+# - Tree::selection
+# - Tree::exists
+# - Tree::parent
+# - Tree::index
+# - Tree::nodes
+# - Tree::see
+# - Tree::opentree
+# - Tree::closetree
+# - Tree::edit
+# - Tree::xview
+# - Tree::yview
+# - Tree::_update_edit_size
+# - Tree::_destroy
+# - Tree::_see
+# - Tree::_recexpand
+# - Tree::_subdelete
+# - Tree::_update_scrollregion
+# - Tree::_cross_event
+# - Tree::_draw_node
+# - Tree::_draw_subnodes
+# - Tree::_update_nodes
+# - Tree::_draw_tree
+# - Tree::_redraw_tree
+# - Tree::_redraw_selection
+# - Tree::_redraw_idle
+# - Tree::_drag_cmd
+# - Tree::_drop_cmd
+# - Tree::_over_cmd
+# - Tree::_auto_scroll
+# - Tree::_scroll
+# ----------------------------------------------------------------------------
+
+namespace eval Tree {
+ Widget::define Tree tree DragSite DropSite DynamicHelp
+
+ namespace eval Node {
+ Widget::declare Tree::Node {
+ {-text String "" 0}
+ {-font TkResource "" 0 listbox}
+ {-image TkResource "" 0 label}
+ {-window String "" 0}
+ {-fill TkResource black 0 {listbox -foreground}}
+ {-data String "" 0}
+ {-open Boolean 0 0}
+ {-selectable Boolean 1 0}
+ {-drawcross Enum auto 0 {auto always never allways}}
+ {-padx Int -1 0 "%d >= -1"}
+ {-deltax Int -1 0 "%d >= -1"}
+ {-anchor String "w" 0 ""}
+ }
+ }
+
+ DynamicHelp::include Tree::Node balloon
+
+ Widget::tkinclude Tree canvas .c \
+ remove {
+ -insertwidth -insertbackground -insertborderwidth -insertofftime
+ -insertontime -selectborderwidth -closeenough -confine -scrollregion
+ -xscrollincrement -yscrollincrement -width -height
+ } \
+ initialize {
+ -relief sunken -borderwidth 2 -takefocus 1
+ -highlightthickness 1 -width 200
+ }
+
+ Widget::declare Tree {
+ {-deltax Int 10 0 "%d >= 0"}
+ {-deltay Int 15 0 "%d >= 0"}
+ {-padx Int 20 0 "%d >= 0"}
+ {-background TkResource "" 0 listbox}
+ {-selectbackground TkResource "" 0 listbox}
+ {-selectforeground TkResource "" 0 listbox}
+ {-selectcommand String "" 0}
+ {-width TkResource "" 0 listbox}
+ {-height TkResource "" 0 listbox}
+ {-selectfill Boolean 0 0}
+ {-showlines Boolean 1 0}
+ {-linesfill TkResource black 0 {listbox -foreground}}
+ {-linestipple TkResource "" 0 {label -bitmap}}
+ {-crossfill TkResource black 0 {listbox -foreground}}
+ {-redraw Boolean 1 0}
+ {-opencmd String "" 0}
+ {-closecmd String "" 0}
+ {-dropovermode Flag "wpn" 0 "wpn"}
+ {-bg Synonym -background}
+
+ {-crossopenimage String "" 0}
+ {-crosscloseimage String "" 0}
+ {-crossopenbitmap String "" 0}
+ {-crossclosebitmap String "" 0}
+ }
+
+ DragSite::include Tree "TREE_NODE" 1
+ DropSite::include Tree {
+ TREE_NODE {copy {} move {}}
+ }
+
+ Widget::addmap Tree "" .c {-deltay -yscrollincrement}
+
+ # Trees on windows have a white (system window) background
+ if { $::tcl_platform(platform) == "windows" } {
+ option add *Tree.c.background SystemWindow widgetDefault
+ option add *TreeNode.fill SystemWindowText widgetDefault
+ }
+
+ bind Tree <FocusIn> [list after idle {BWidget::refocus %W %W.c}]
+ bind Tree <Destroy> [list Tree::_destroy %W]
+ bind Tree <Configure> [list Tree::_update_scrollregion %W]
+
+
+ bind TreeSentinalStart <Button-1> {
+ if { $::Tree::sentinal(%W) } {
+ set ::Tree::sentinal(%W) 0
+ break
+ }
+ }
+
+ bind TreeSentinalEnd <Button-1> {
+ set ::Tree::sentinal(%W) 0
+ }
+
+ bind TreeFocus <Button-1> [list focus %W]
+
+ variable _edit
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::create
+# ----------------------------------------------------------------------------
+proc Tree::create { path args } {
+ variable $path
+ upvar 0 $path data
+
+ Widget::init Tree $path $args
+ set ::Tree::sentinal($path.c) 0
+
+ if {[Widget::cget $path -crossopenbitmap] == ""} {
+ set file [file join $::BWIDGET::LIBRARY images "minus.xbm"]
+ Widget::configure $path [list -crossopenbitmap @$file]
+ }
+ if {[Widget::cget $path -crossclosebitmap] == ""} {
+ set file [file join $::BWIDGET::LIBRARY images "plus.xbm"]
+ Widget::configure $path [list -crossclosebitmap @$file]
+ }
+
+ set data(root) {{}}
+ set data(selnodes) {}
+ set data(upd,level) 0
+ set data(upd,nodes) {}
+ set data(upd,afterid) ""
+ set data(dnd,scroll) ""
+ set data(dnd,afterid) ""
+ set data(dnd,selnodes) {}
+ set data(dnd,node) ""
+
+ frame $path -class Tree -bd 0 -highlightthickness 0 -relief flat \
+ -takefocus 0
+ # For 8.4+ we don't want to inherit the padding
+ catch {$path configure -padx 0 -pady 0}
+ eval [list canvas $path.c] [Widget::subcget $path .c] -xscrollincrement 8
+ bindtags $path.c [list TreeSentinalStart TreeFocus $path.c Canvas \
+ [winfo toplevel $path] all TreeSentinalEnd]
+ pack $path.c -expand yes -fill both
+ $path.c bind cross <ButtonPress-1> [list Tree::_cross_event $path]
+
+ # Added by ericm@scriptics.com
+ # These allow keyboard traversal of the tree
+ bind $path.c <KeyPress-Up> [list Tree::_keynav up $path]
+ bind $path.c <KeyPress-Down> [list Tree::_keynav down $path]
+ bind $path.c <KeyPress-Right> [list Tree::_keynav right $path]
+ bind $path.c <KeyPress-Left> [list Tree::_keynav left $path]
+ bind $path.c <KeyPress-space> [list +Tree::_keynav space $path]
+
+ # These allow keyboard control of the scrolling
+ bind $path.c <Control-KeyPress-Up> [list $path.c yview scroll -1 units]
+ bind $path.c <Control-KeyPress-Down> [list $path.c yview scroll 1 units]
+ bind $path.c <Control-KeyPress-Left> [list $path.c xview scroll -1 units]
+ bind $path.c <Control-KeyPress-Right> [list $path.c xview scroll 1 units]
+ # ericm@scriptics.com
+
+ BWidget::bindMouseWheel $path.c
+
+ DragSite::setdrag $path $path.c Tree::_init_drag_cmd \
+ [Widget::cget $path -dragendcmd] 1
+ DropSite::setdrop $path $path.c Tree::_over_cmd Tree::_drop_cmd 1
+
+ Widget::create Tree $path
+
+ set w [Widget::cget $path -width]
+ set h [Widget::cget $path -height]
+ set dy [Widget::cget $path -deltay]
+ $path.c configure -width [expr {$w*8}] -height [expr {$h*$dy}]
+
+ # ericm
+ # Bind <Button-1> to select the clicked node -- no reason not to, right?
+
+ ## Bind button 1 to select the node via the _mouse_select command.
+ ## This command will generate the proper <<TreeSelect>> virtual event
+ ## when necessary.
+ set selectcmd Tree::_mouse_select
+ Tree::bindText $path <Button-1> [list $selectcmd $path set]
+ Tree::bindImage $path <Button-1> [list $selectcmd $path set]
+ Tree::bindText $path <Control-Button-1> [list $selectcmd $path toggle]
+ Tree::bindImage $path <Control-Button-1> [list $selectcmd $path toggle]
+
+ # Add sentinal bindings for double-clicking on items, to handle the
+ # gnarly Tk bug wherein:
+ # ButtonClick
+ # ButtonClick
+ # On a canvas item translates into button click on the item, button click
+ # on the canvas, double-button on the item, single button click on the
+ # canvas (which can happen if the double-button on the item causes some
+ # other event to be handled in between when the button clicks are examined
+ # for the canvas)
+ $path.c bind TreeItemSentinal <Double-Button-1> \
+ [list set ::Tree::sentinal($path.c) 1]
+ # ericm
+
+ return $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::configure
+# ----------------------------------------------------------------------------
+proc Tree::configure { path args } {
+ variable $path
+ upvar 0 $path data
+
+ set res [Widget::configure $path $args]
+
+ set ch1 [expr {[Widget::hasChanged $path -deltax val] |
+ [Widget::hasChanged $path -deltay dy] |
+ [Widget::hasChanged $path -padx val] |
+ [Widget::hasChanged $path -showlines val]}]
+
+ set ch2 [expr {[Widget::hasChanged $path -selectbackground val] |
+ [Widget::hasChanged $path -selectforeground val]}]
+
+ if { [Widget::hasChanged $path -linesfill fill] |
+ [Widget::hasChanged $path -linestipple stipple] } {
+ $path.c itemconfigure line -fill $fill -stipple $stipple
+ }
+
+ if { [Widget::hasChanged $path -crossfill fill] } {
+ $path.c itemconfigure cross -foreground $fill
+ }
+
+ if {[Widget::hasChanged $path -selectfill fill]} {
+ # Make sure that the full-width boxes have either all or none
+ # of the standard node bindings
+ if {$fill} {
+ foreach event [$path.c bind "node"] {
+ $path.c bind "box" $event [$path.c bind "node" $event]
+ }
+ } else {
+ foreach event [$path.c bind "node"] {
+ $path.c bind "box" $event {}
+ }
+ }
+ }
+
+ if { $ch1 } {
+ _redraw_idle $path 3
+ } elseif { $ch2 } {
+ _redraw_idle $path 1
+ }
+
+ if { [Widget::hasChanged $path -height h] } {
+ $path.c configure -height [expr {$h*$dy}]
+ }
+ if { [Widget::hasChanged $path -width w] } {
+ $path.c configure -width [expr {$w*8}]
+ }
+
+ if { [Widget::hasChanged $path -redraw bool] && $bool } {
+ set upd $data(upd,level)
+ set data(upd,level) 0
+ _redraw_idle $path $upd
+ }
+
+ set force [Widget::hasChanged $path -dragendcmd dragend]
+ DragSite::setdrag $path $path.c Tree::_init_drag_cmd $dragend $force
+ DropSite::setdrop $path $path.c Tree::_over_cmd Tree::_drop_cmd
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::cget
+# ----------------------------------------------------------------------------
+proc Tree::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::insert
+# ----------------------------------------------------------------------------
+proc Tree::insert { path index parent node args } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ set node [Widget::nextIndex $path $node]
+
+ if { [info exists data($node)] } {
+ return -code error "node \"$node\" already exists"
+ }
+ set parent [_node_name $path $parent]
+ if { ![info exists data($parent)] } {
+ return -code error "node \"$parent\" does not exist"
+ }
+
+ Widget::init Tree::Node $path.$node $args
+ if {[string equal $index "end"]} {
+ lappend data($parent) $node
+ } else {
+ incr index
+ set data($parent) [linsert $data($parent) $index $node]
+ }
+ set data($node) [list $parent]
+
+ if { [string equal $parent "root"] } {
+ _redraw_idle $path 3
+ } elseif { [visible $path $parent] } {
+ # parent is visible...
+ if { [Widget::getMegawidgetOption $path.$parent -open] } {
+ # ...and opened -> redraw whole
+ _redraw_idle $path 3
+ } else {
+ # ...and closed -> redraw cross
+ MergeFlag $path $parent 8
+ _redraw_idle $path 2
+ }
+ }
+
+ return $node
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::itemconfigure
+# ----------------------------------------------------------------------------
+proc Tree::itemconfigure { path node args } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { [string equal $node "root"] || ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+
+ set result [Widget::configure $path.$node $args]
+
+ _set_help $path $node
+
+ if { [visible $path $node] } {
+ set lopt {}
+ set flag 0
+ foreach opt {-window -image -drawcross -font -text -fill} {
+ set flag [expr {$flag << 1}]
+ if { [Widget::hasChanged $path.$node $opt val] } {
+ set flag [expr {$flag | 1}]
+ }
+ }
+
+ if { [Widget::hasChanged $path.$node -open val] } {
+ if {[llength $data($node)] > 1} {
+ # node have subnodes - full redraw
+ _redraw_idle $path 3
+ } else {
+ # force a redraw of the plus/minus sign
+ set flag [expr {$flag | 8}]
+ }
+ }
+
+ if {$data(upd,level) < 3 && [Widget::hasChanged $path.$node -padx x]} {
+ _redraw_idle $path 3
+ }
+
+ if { $data(upd,level) < 3 && $flag } {
+ MergeFlag $path $node $flag
+ _redraw_idle $path 2
+ }
+ }
+ return $result
+}
+
+proc Tree::MergeFlag { path node flag } {
+ variable $path
+ upvar 0 $path data
+
+ # data(upd,nodes) is a key-val list: emulate a dict by an array
+ array set n $data(upd,nodes)
+ if {![info exists n($node)]} {
+ lappend data(upd,nodes) $node $flag
+ } else {
+ set n($node) [expr {$n($node) | $flag}]
+ set data(upd,nodes) [array get n]
+ }
+ return
+}
+
+# ----------------------------------------------------------------------------
+# Command Tree::itemcget
+# ----------------------------------------------------------------------------
+proc Tree::itemcget { path node option } {
+ # Instead of upvar'ing $path as data for this test, just directly refer to
+ # it, as that is faster.
+ set node [_node_name $path $node]
+ if { [string equal $node "root"] || \
+ ![info exists ::Tree::${path}($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+
+ return [Widget::cget $path.$node $option]
+}
+
+# ----------------------------------------------------------------------------
+# Command Tree::bindArea
+# ----------------------------------------------------------------------------
+proc Tree::bindArea { path event script } {
+ bind $path.c $event $script
+}
+
+# ----------------------------------------------------------------------------
+# Command Tree::bindText
+# ----------------------------------------------------------------------------
+proc Tree::bindText { path event script } {
+ if {[string length $script]} {
+ append script " \[Tree::_get_node_name [list $path] current 2 1\]"
+ }
+ $path.c bind "node" $event $script
+ if {[Widget::getoption $path -selectfill]} {
+ $path.c bind "box" $event $script
+ } else {
+ $path.c bind "box" $event {}
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::bindImage
+# ----------------------------------------------------------------------------
+proc Tree::bindImage { path event script } {
+ if {[string length $script]} {
+ append script " \[Tree::_get_node_name [list $path] current 2 1\]"
+ }
+ $path.c bind "img" $event $script
+ if {[Widget::getoption $path -selectfill]} {
+ $path.c bind "box" $event $script
+ } else {
+ $path.c bind "box" $event {}
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::delete
+# ----------------------------------------------------------------------------
+proc Tree::delete { path args } {
+ variable $path
+ upvar 0 $path data
+
+ set sel 0
+ foreach lnodes $args {
+ foreach node $lnodes {
+ set node [_node_name $path $node]
+ if { ![string equal $node "root"] && [info exists data($node)] } {
+ set parent [lindex $data($node) 0]
+ set idx [lsearch -exact $data($parent) $node]
+ set data($parent) [lreplace $data($parent) $idx $idx]
+ incr sel [_subdelete $path [list $node]]
+ }
+ }
+ }
+ if {$sel} {
+ # if selection changed, call the selectcommand
+ __call_selectcmd $path
+ }
+
+ _redraw_idle $path 3
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::move
+# ----------------------------------------------------------------------------
+proc Tree::move { path parent node index } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { [string equal $node "root"] || ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+ if { ![info exists data($parent)] } {
+ return -code error "node \"$parent\" does not exist"
+ }
+ set p $parent
+ while { ![string equal $p "root"] } {
+ if { [string equal $p $node] } {
+ return -code error "node \"$parent\" is a descendant of \"$node\""
+ }
+ set p [parent $path $p]
+ }
+
+ set oldp [lindex $data($node) 0]
+ set idx [lsearch -exact $data($oldp) $node]
+ set data($oldp) [lreplace $data($oldp) $idx $idx]
+ set data($node) [concat [list $parent] [lrange $data($node) 1 end]]
+ if { [string equal $index "end"] } {
+ lappend data($parent) $node
+ } else {
+ incr index
+ set data($parent) [linsert $data($parent) $index $node]
+ }
+ if { ([string equal $oldp "root"] ||
+ ([visible $path $oldp] && [Widget::getoption $path.$oldp -open])) ||
+ ([string equal $parent "root"] ||
+ ([visible $path $parent] && [Widget::getoption $path.$parent -open])) } {
+ _redraw_idle $path 3
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::reorder
+# ----------------------------------------------------------------------------
+proc Tree::reorder { path node neworder } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+ set children [lrange $data($node) 1 end]
+ if { [llength $children] } {
+ set children [BWidget::lreorder $children $neworder]
+ set data($node) [linsert $children 0 [lindex $data($node) 0]]
+ if { [visible $path $node] && [Widget::getoption $path.$node -open] } {
+ _redraw_idle $path 3
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::selection
+# ----------------------------------------------------------------------------
+proc Tree::selection { path cmd args } {
+ variable $path
+ upvar 0 $path data
+
+ switch -- $cmd {
+ toggle {
+ foreach node $args {
+ set node [_node_name $path $node]
+ if {![info exists data($node)]} {
+ return -code error \
+ "$path selection toggle: Cannot toggle unknown node \"$node\"."
+ }
+ }
+ foreach node $args {
+ set node [_node_name $path $node]
+ if {[$path selection includes $node]} {
+ $path selection remove $node
+ } else {
+ $path selection add $node
+ }
+ }
+ }
+ set {
+ foreach node $args {
+ set node [_node_name $path $node]
+ if {![info exists data($node)]} {
+ return -code error \
+ "$path selection set: Cannot select unknown node \"$node\"."
+ }
+ }
+ set data(selnodes) {}
+ foreach node $args {
+ set node [_node_name $path $node]
+ if { [Widget::getoption $path.$node -selectable] } {
+ if { [lsearch -exact $data(selnodes) $node] == -1 } {
+ lappend data(selnodes) $node
+ }
+ }
+ }
+ __call_selectcmd $path
+ }
+ add {
+ foreach node $args {
+ set node [_node_name $path $node]
+ if {![info exists data($node)]} {
+ return -code error \
+ "$path selection add: Cannot select unknown node \"$node\"."
+ }
+ }
+ foreach node $args {
+ set node [_node_name $path $node]
+ if { [Widget::getoption $path.$node -selectable] } {
+ if { [lsearch -exact $data(selnodes) $node] == -1 } {
+ lappend data(selnodes) $node
+ }
+ }
+ }
+ __call_selectcmd $path
+ }
+ range {
+ # Here's our algorithm:
+ # make a list of all nodes, then take the range from node1
+ # to node2 and select those nodes
+ #
+ # This works because of how this widget handles redraws:
+ # The tree is always completely redrawn, and always from
+ # top to bottom. So the list of visible nodes *is* the
+ # list of nodes, and we can use that to decide which nodes
+ # to select.
+
+ if {[llength $args] != 2} {
+ return -code error \
+ "wrong#args: Expected $path selection range node1 node2"
+ }
+
+ foreach {node1 node2} $args break
+
+ set node1 [_node_name $path $node1]
+ set node2 [_node_name $path $node2]
+ if {![info exists data($node1)]} {
+ return -code error \
+ "$path selection range: Cannot start range at unknown node \"$node1\"."
+ }
+ if {![info exists data($node2)]} {
+ return -code error \
+ "$path selection range: Cannot end range at unknown node \"$node2\"."
+ }
+
+ set nodes {}
+ foreach nodeItem [$path.c find withtag node] {
+ set node [Tree::_get_node_name $path $nodeItem 2]
+ if { [Widget::getoption $path.$node -selectable] } {
+ lappend nodes $node
+ }
+ }
+ # surles: Set the root string to the first element on the list.
+ if {$node1 == "root"} {
+ set node1 [lindex $nodes 0]
+ }
+ if {$node2 == "root"} {
+ set node2 [lindex $nodes 0]
+ }
+
+ # Find the first visible ancestor of node1, starting with node1
+ while {[set index1 [lsearch -exact $nodes $node1]] == -1} {
+ set node1 [lindex $data($node1) 0]
+ }
+ # Find the first visible ancestor of node2, starting with node2
+ while {[set index2 [lsearch -exact $nodes $node2]] == -1} {
+ set node2 [lindex $data($node2) 0]
+ }
+ # If the nodes were given in backwards order, flip the
+ # indices now
+ if { $index2 < $index1 } {
+ incr index1 $index2
+ set index2 [expr {$index1 - $index2}]
+ set index1 [expr {$index1 - $index2}]
+ }
+ set data(selnodes) [lrange $nodes $index1 $index2]
+ __call_selectcmd $path
+ }
+ remove {
+ foreach node $args {
+ set node [_node_name $path $node]
+ if { [set idx [lsearch -exact $data(selnodes) $node]] != -1 } {
+ set data(selnodes) [lreplace $data(selnodes) $idx $idx]
+ }
+ }
+ __call_selectcmd $path
+ }
+ clear {
+ if {[llength $args] != 0} {
+ return -code error \
+ "wrong#args: Expected $path selection clear"
+ }
+ set data(selnodes) {}
+ __call_selectcmd $path
+ }
+ get {
+ if {[llength $args] != 0} {
+ return -code error \
+ "wrong#args: Expected $path selection get"
+ }
+ set nodes [list]
+ foreach node $data(selnodes) {
+ lappend nodes [_node_name_rev $path $node]
+ }
+ return $nodes
+ }
+ includes {
+ if {[llength $args] != 1} {
+ return -code error \
+ "wrong#args: Expected $path selection includes node"
+ }
+ set node [lindex $args 0]
+ set node [_node_name $path $node]
+ return [expr {[lsearch -exact $data(selnodes) $node] != -1}]
+ }
+ default {
+ return
+ }
+ }
+ _redraw_idle $path 1
+}
+
+
+proc Tree::getcanvas { path } {
+ return $path.c
+}
+
+
+proc Tree::__call_selectcmd { path } {
+ variable $path
+ upvar 0 $path data
+
+ set selectcmd [Widget::getoption $path -selectcommand]
+ if {[llength $selectcmd]} {
+ lappend selectcmd $path
+ lappend selectcmd $data(selnodes)
+ uplevel \#0 $selectcmd
+ }
+ return
+}
+
+# ----------------------------------------------------------------------------
+# Command Tree::exists
+# ----------------------------------------------------------------------------
+proc Tree::exists { path node } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ return [info exists data($node)]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::visible
+# ----------------------------------------------------------------------------
+proc Tree::visible { path node } {
+ set node [_node_name $path $node]
+ set idn [$path.c find withtag n:$node]
+ return [llength $idn]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::parent
+# ----------------------------------------------------------------------------
+proc Tree::parent { path node } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+ return [lindex $data($node) 0]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::index
+# ----------------------------------------------------------------------------
+proc Tree::index { path node } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { [string equal $node "root"] || ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+ set parent [lindex $data($node) 0]
+ return [expr {[lsearch -exact $data($parent) $node] - 1}]
+}
+
+
+# ----------------------------------------------------------------------------
+# Tree::find
+# Returns the node given a position.
+# findInfo @x,y ?confine?
+# lineNumber
+# ----------------------------------------------------------------------------
+proc Tree::find {path findInfo {confine ""}} {
+ if {[regexp -- {^@([0-9]+),([0-9]+)$} $findInfo match x y]} {
+ set x [$path.c canvasx $x]
+ set y [$path.c canvasy $y]
+ } elseif {[regexp -- {^[0-9]+$} $findInfo lineNumber]} {
+ set dy [Widget::getoption $path -deltay]
+ set y [expr {$dy*($lineNumber+0.5)}]
+ set confine ""
+ } else {
+ return -code error "invalid find spec \"$findInfo\""
+ }
+
+ set found 0
+ set region [$path.c bbox all]
+ if {[llength $region]} {
+ set xi [lindex $region 0]
+ set xs [lindex $region 2]
+ foreach id [$path.c find overlapping $xi $y $xs $y] {
+ set ltags [$path.c gettags $id]
+ set item [lindex $ltags 1]
+ if { [string equal $item "node"] ||
+ [string equal $item "img"] ||
+ [string equal $item "win"] } {
+ # item is the label or image/window of the node
+ set node [Tree::_get_node_name $path $id 2]
+ set found 1
+ break
+ }
+ }
+ }
+
+ if {$found} {
+ if {![string equal $confine ""]} {
+ # test if x stand inside node bbox
+ set padx [_get_node_padx $path $node]
+ set xi [expr {[lindex [$path.c coords n:$node] 0] - $padx}]
+ set xs [lindex [$path.c bbox n:$node] 2]
+ if {$x >= $xi && $x <= $xs} {
+ return [_node_name_rev $path $node]
+ }
+ } else {
+ return [_node_name_rev $path $node]
+ }
+ }
+ return ""
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::line
+# Returns the line where a node was drawn.
+# ----------------------------------------------------------------------------
+proc Tree::line {path node} {
+ set node [_node_name $path $node]
+ set item [$path.c find withtag n:$node]
+ if {[string length $item]} {
+ set dy [Widget::getoption $path -deltay]
+ set y [lindex [$path.c coords $item] 1]
+ set line [expr {int($y/$dy)}]
+ } else {
+ set line -1
+ }
+ return $line
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::nodes
+# ----------------------------------------------------------------------------
+proc Tree::nodes { path node {first ""} {last ""} } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+
+ if { ![string length $first] } {
+ return [lrange $data($node) 1 end]
+ }
+
+ if { ![string length $last] } {
+ return [lindex [lrange $data($node) 1 end] $first]
+ } else {
+ return [lrange [lrange $data($node) 1 end] $first $last]
+ }
+}
+
+
+# Tree::visiblenodes --
+#
+# Retrieve a list of all the nodes in a tree.
+#
+# Arguments:
+# path tree to retrieve nodes for.
+#
+# Results:
+# nodes list of nodes in the tree.
+
+proc Tree::visiblenodes { path } {
+ variable $path
+ upvar 0 $path data
+
+ # Root is always open (?), so all of its children automatically get added
+ # to the result, and to the stack.
+ set st [lrange $data(root) 1 end]
+ set result $st
+
+ while {[llength $st]} {
+ set node [lindex $st end]
+ set st [lreplace $st end end]
+ # Danger, danger! Using getMegawidgetOption is fragile, but much
+ # much faster than going through cget.
+ if { [Widget::getMegawidgetOption $path.$node -open] } {
+ set nodes [lrange $data($node) 1 end]
+ set result [concat $result $nodes]
+ set st [concat $st $nodes]
+ }
+ }
+ return $result
+}
+
+# ----------------------------------------------------------------------------
+# Command Tree::see
+# ----------------------------------------------------------------------------
+proc Tree::see { path node } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
+ after cancel $data(upd,afterid)
+ _redraw_tree $path
+ }
+ set idn [$path.c find withtag n:$node]
+ if { $idn != "" } {
+ Tree::_see $path $idn
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::opentree
+# ----------------------------------------------------------------------------
+# JDC: added option recursive
+proc Tree::opentree { path node {recursive 1} } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { [string equal $node "root"] || ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+
+ _recexpand $path $node 1 $recursive [Widget::getoption $path -opencmd]
+ _redraw_idle $path 3
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::closetree
+# ----------------------------------------------------------------------------
+proc Tree::closetree { path node {recursive 1} } {
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { [string equal $node "root"] || ![info exists data($node)] } {
+ return -code error "node \"$node\" does not exist"
+ }
+
+ _recexpand $path $node 0 $recursive [Widget::getoption $path -closecmd]
+ _redraw_idle $path 3
+}
+
+
+proc Tree::toggle { path node } {
+ if {[$path itemcget $node -open]} {
+ $path closetree $node 0
+ } else {
+ $path opentree $node 0
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::edit
+# ----------------------------------------------------------------------------
+proc Tree::edit { path node text {verifycmd ""} {clickres 0} {select 1}} {
+ variable _edit
+ variable $path
+ upvar 0 $path data
+
+ set node [_node_name $path $node]
+ if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
+ after cancel $data(upd,afterid)
+ _redraw_tree $path
+ }
+ set idn [$path.c find withtag n:$node]
+ if { $idn != "" } {
+ Tree::_see $path $idn
+
+ set oldfg [$path.c itemcget $idn -fill]
+ set sbg [Widget::getoption $path -selectbackground]
+ set coords [$path.c coords $idn]
+ set x [lindex $coords 0]
+ set y [lindex $coords 1]
+ set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}]
+ set w [expr {[winfo width $path] - 2*$bd}]
+ set wmax [expr {[$path.c canvasx $w]-$x}]
+
+ set _edit(text) $text
+ set _edit(wait) 0
+
+ $path.c itemconfigure $idn -fill [Widget::getoption $path -background]
+ $path.c itemconfigure s:$node -fill {} -outline {}
+
+ set frame [frame $path.edit \
+ -relief flat -borderwidth 0 -highlightthickness 0 \
+ -background [Widget::getoption $path -background]]
+ set ent [entry $frame.edit \
+ -width 0 \
+ -relief solid \
+ -borderwidth 1 \
+ -highlightthickness 0 \
+ -foreground [Widget::getoption $path.$node -fill] \
+ -background [Widget::getoption $path -background] \
+ -selectforeground [Widget::getoption $path -selectforeground] \
+ -selectbackground $sbg \
+ -font [Widget::getoption $path.$node -font] \
+ -textvariable Tree::_edit(text)]
+ pack $ent -ipadx 8 -anchor w
+
+ set idw [$path.c create window $x $y -window $frame -anchor w]
+ trace variable Tree::_edit(text) w \
+ [list Tree::_update_edit_size $path $ent $idw $wmax]
+ tkwait visibility $ent
+ grab $frame
+ BWidget::focus set $ent
+
+ _update_edit_size $path $ent $idw $wmax
+ update
+ if { $select } {
+ $ent selection range 0 end
+ $ent icursor end
+ $ent xview end
+ }
+
+ bindtags $ent [list $ent Entry]
+ bind $ent <Escape> {set Tree::_edit(wait) 0}
+ bind $ent <Return> {set Tree::_edit(wait) 1}
+ if { $clickres == 0 || $clickres == 1 } {
+ bind $frame <Button> [list set Tree::_edit(wait) $clickres]
+ }
+
+ set ok 0
+ while { !$ok } {
+ tkwait variable Tree::_edit(wait)
+ if { !$_edit(wait) || [llength $verifycmd]==0 ||
+ [uplevel \#0 $verifycmd [list $_edit(text)]] } {
+ set ok 1
+ }
+ }
+
+ trace vdelete Tree::_edit(text) w \
+ [list Tree::_update_edit_size $path $ent $idw $wmax]
+ grab release $frame
+ BWidget::focus release $ent
+ destroy $frame
+ $path.c delete $idw
+ $path.c itemconfigure $idn -fill $oldfg
+ $path.c itemconfigure s:$node -fill $sbg -outline $sbg
+
+ if { $_edit(wait) } {
+ return $_edit(text)
+ }
+ }
+ return ""
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::xview
+# ----------------------------------------------------------------------------
+proc Tree::xview { path args } {
+ return [eval [linsert $args 0 $path.c xview]]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::yview
+# ----------------------------------------------------------------------------
+proc Tree::yview { path args } {
+ return [eval [linsert $args 0 $path.c yview]]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_update_edit_size
+# ----------------------------------------------------------------------------
+proc Tree::_update_edit_size { path entry idw wmax args } {
+ set entw [winfo reqwidth $entry]
+ if { $entw+8 >= $wmax } {
+ $path.c itemconfigure $idw -width $wmax
+ } else {
+ $path.c itemconfigure $idw -width 0
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_see
+# ----------------------------------------------------------------------------
+proc Tree::_see { path idn } {
+ set bbox [$path.c bbox $idn]
+ set scrl [$path.c cget -scrollregion]
+
+ set ymax [lindex $scrl 3]
+ set dy [$path.c cget -yscrollincrement]
+ set yv [$path yview]
+ set yv0 [expr {round([lindex $yv 0]*$ymax/$dy)}]
+ set yv1 [expr {round([lindex $yv 1]*$ymax/$dy)}]
+ set y [expr {int([lindex [$path.c coords $idn] 1]/$dy)}]
+ if { $y < $yv0 } {
+ $path.c yview scroll [expr {$y-$yv0}] units
+ } elseif { $y >= $yv1 } {
+ $path.c yview scroll [expr {$y-$yv1+1}] units
+ }
+
+ set xmax [lindex $scrl 2]
+ set dx [$path.c cget -xscrollincrement]
+ set xv [$path xview]
+ set x0 [expr {int([lindex $bbox 0]/$dx)}]
+ set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}]
+ set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}]
+ if { $x0 >= $xv1 || $x0 < $xv0 } {
+ $path.c xview scroll [expr {$x0-$xv0}] units
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_recexpand
+# ----------------------------------------------------------------------------
+# JDC : added option recursive
+proc Tree::_recexpand { path node expand recursive cmd } {
+ variable $path
+ upvar 0 $path data
+
+ if { [Widget::getoption $path.$node -open] != $expand } {
+ Widget::setoption $path.$node -open $expand
+ if {[llength $cmd]} {
+ uplevel \#0 $cmd [list $node]
+ }
+ }
+
+ if { $recursive } {
+ foreach subnode [lrange $data($node) 1 end] {
+ _recexpand $path $subnode $expand $recursive $cmd
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_subdelete
+# ----------------------------------------------------------------------------
+proc Tree::_subdelete { path lnodes } {
+ variable $path
+ upvar 0 $path data
+
+ set sel $data(selnodes)
+ set selchanged 0
+
+ while { [llength $lnodes] } {
+ set lsubnodes [list]
+ foreach node $lnodes {
+ foreach subnode [lrange $data($node) 1 end] {
+ lappend lsubnodes $subnode
+ }
+ unset data($node)
+ set idx [lsearch -exact $sel $node]
+ if { $idx >= 0 } {
+ set sel [lreplace $sel $idx $idx]
+ incr selchanged
+ }
+ if { [set win [Widget::getoption $path.$node -window]] != "" } {
+ destroy $win
+ }
+ Widget::destroy $path.$node
+ }
+ set lnodes $lsubnodes
+ }
+
+ set data(selnodes) $sel
+ # return number of sel items changes
+ return $selchanged
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_update_scrollregion
+# ----------------------------------------------------------------------------
+proc Tree::_update_scrollregion { path } {
+ set bd [expr {2*([$path.c cget -borderwidth]+[$path.c cget -highlightthickness])}]
+ set w [expr {[winfo width $path] - $bd}]
+ set h [expr {[winfo height $path] - $bd}]
+ set xinc [$path.c cget -xscrollincrement]
+ set yinc [$path.c cget -yscrollincrement]
+ set bbox [$path.c bbox node]
+ if { [llength $bbox] } {
+ set xs [lindex $bbox 2]
+ set ys [lindex $bbox 3]
+
+ if { $w < $xs } {
+ set w [expr {int($xs)}]
+ if { [set r [expr {$w % $xinc}]] } {
+ set w [expr {$w+$xinc-$r}]
+ }
+ }
+ if { $h < $ys } {
+ set h [expr {int($ys)}]
+ if { [set r [expr {$h % $yinc}]] } {
+ set h [expr {$h+$yinc-$r}]
+ }
+ }
+ }
+
+ $path.c configure -scrollregion [list 0 0 $w $h]
+
+ if {[Widget::getoption $path -selectfill]} {
+ _redraw_selection $path
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_cross_event
+# ----------------------------------------------------------------------------
+proc Tree::_cross_event { path } {
+ variable $path
+ upvar 0 $path data
+
+ set node [Tree::_get_node_name $path current 1]
+ if { [Widget::getoption $path.$node -open] } {
+ Tree::itemconfigure $path $node -open 0
+ if {[llength [set cmd [Widget::getoption $path -closecmd]]]} {
+ uplevel \#0 $cmd [list $node]
+ }
+ } else {
+ Tree::itemconfigure $path $node -open 1
+ if {[llength [set cmd [Widget::getoption $path -opencmd]]]} {
+ uplevel \#0 $cmd [list $node]
+ }
+ }
+}
+
+
+proc Tree::_draw_cross { path node open x y } {
+ set idc [$path.c find withtag c:$node]
+
+ if { $open } {
+ set img [Widget::cget $path -crossopenimage]
+ set bmp [Widget::cget $path -crossopenbitmap]
+ } else {
+ set img [Widget::cget $path -crosscloseimage]
+ set bmp [Widget::cget $path -crossclosebitmap]
+ }
+
+ ## If we already have a cross for this node, we just adjust the image.
+ if {$idc != ""} {
+ if {$img == ""} {
+ $path.c itemconfigure $idc -bitmap $bmp
+ } else {
+ $path.c itemconfigure $idc -image $img
+ }
+ return
+ }
+
+ ## Create a new image for the cross. If the user has specified an
+ ## image, it overrides a bitmap.
+ if {$img == ""} {
+ $path.c create bitmap $x $y \
+ -bitmap $bmp \
+ -background [$path.c cget -background] \
+ -foreground [Widget::getoption $path -crossfill] \
+ -tags [list cross c:$node] -anchor c
+ } else {
+ $path.c create image $x $y \
+ -image $img \
+ -tags [list cross c:$node] -anchor c
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_draw_node
+# ----------------------------------------------------------------------------
+proc Tree::_draw_node { path node x0 y0 deltax deltay padx showlines } {
+ variable $path
+ upvar 0 $path data
+
+ set x1 [expr {$x0+$deltax+5}]
+ set y1 $y0
+ if { $showlines } {
+ $path.c create line $x0 $y0 $x1 $y0 \
+ -fill [Widget::getoption $path -linesfill] \
+ -stipple [Widget::getoption $path -linestipple] \
+ -tags line
+ }
+ $path.c create text [expr {$x1+$padx}] $y0 \
+ -text [Widget::getoption $path.$node -text] \
+ -fill [Widget::getoption $path.$node -fill] \
+ -font [Widget::getoption $path.$node -font] \
+ -anchor w \
+ -tags [Tree::_get_node_tags $path $node [list node n:$node]]
+ set len [expr {[llength $data($node)] > 1}]
+ set dc [Widget::getoption $path.$node -drawcross]
+ set exp [Widget::getoption $path.$node -open]
+
+ if { $len && $exp } {
+ set y1 [_draw_subnodes $path [lrange $data($node) 1 end] \
+ [expr {$x0+$deltax}] $y0 $deltax $deltay $padx $showlines]
+ }
+
+ if {![string equal $dc "never"]
+ && ($len || [string equal $dc "always"] || [string equal $dc "allways"])} {
+ _draw_cross $path $node $exp $x0 $y0
+ }
+
+ if { [set win [Widget::getoption $path.$node -window]] != "" } {
+ set a [Widget::cget $path.$node -anchor]
+ $path.c create window $x1 $y0 -window $win -anchor $a \
+ -tags [Tree::_get_node_tags $path $node [list win i:$node]]
+ } elseif { [set img [Widget::getoption $path.$node -image]] != "" } {
+ set a [Widget::cget $path.$node -anchor]
+ $path.c create image $x1 $y0 -image $img -anchor $a \
+ -tags [Tree::_get_node_tags $path $node [list img i:$node]]
+ }
+ set box [$path.c bbox n:$node i:$node]
+ set id [$path.c create rect 0 [lindex $box 1] \
+ [winfo screenwidth $path] [lindex $box 3] \
+ -tags [Tree::_get_node_tags $path $node [list box b:$node]] \
+ -fill {} -outline {}]
+ $path.c lower $id
+
+ _set_help $path $node
+
+ return $y1
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_draw_subnodes
+# ----------------------------------------------------------------------------
+proc Tree::_draw_subnodes { path nodes x0 y0 deltax deltay padx showlines } {
+ set y1 $y0
+ foreach node $nodes {
+ set padx [_get_node_padx $path $node]
+ set deltax [_get_node_deltax $path $node]
+ set yp $y1
+ set y1 [_draw_node $path $node $x0 [expr {$y1+$deltay}] $deltax $deltay $padx $showlines]
+ }
+ # Only draw a line to the invisible root node above the tree widget when
+ # there are multiple top nodes.
+ set len [llength $nodes]
+ if { $showlines && $len && !($y0 < 0 && $len < 2) } {
+ set id [$path.c create line $x0 $y0 $x0 [expr {$yp+$deltay}] \
+ -fill [Widget::getoption $path -linesfill] \
+ -stipple [Widget::getoption $path -linestipple] \
+ -tags line]
+
+ $path.c lower $id
+ }
+ return $y1
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_update_nodes
+# ----------------------------------------------------------------------------
+proc Tree::_update_nodes { path } {
+ variable $path
+ upvar 0 $path data
+
+ foreach {node flag} $data(upd,nodes) {
+ set idn [$path.c find withtag "n:$node"]
+ if { $idn == "" } {
+ continue
+ }
+ set padx [_get_node_padx $path $node]
+ set deltax [_get_node_deltax $path $node]
+ set c [$path.c coords $idn]
+ set x1 [expr {[lindex $c 0]-$padx}]
+ set x0 [expr {$x1-$deltax-5}]
+ set y0 [lindex $c 1]
+ if { $flag & 48 } {
+ # -window or -image modified
+ set win [Widget::getoption $path.$node -window]
+ set img [Widget::getoption $path.$node -image]
+ set anc [Widget::cget $path.$node -anchor]
+ set idi [$path.c find withtag i:$node]
+ set type [lindex [$path.c gettags $idi] 1]
+ if { [string length $win] } {
+ if { [string equal $type "win"] } {
+ $path.c itemconfigure $idi -window $win
+ } else {
+ $path.c delete $idi
+ $path.c create window $x1 $y0 -window $win -anchor $anc \
+ -tags [_get_node_tags $path $node [list win i:$node]]
+ }
+ } elseif { [string length $img] } {
+ if { [string equal $type "img"] } {
+ $path.c itemconfigure $idi -image $img
+ } else {
+ $path.c delete $idi
+ $path.c create image $x1 $y0 -image $img -anchor $anc \
+ -tags [_get_node_tags $path $node [list img i:$node]]
+ }
+ } else {
+ $path.c delete $idi
+ }
+ }
+
+ if { $flag & 8 } {
+ # -drawcross modified
+ set len [expr {[llength $data($node)] > 1}]
+ set dc [Widget::getoption $path.$node -drawcross]
+ set exp [Widget::getoption $path.$node -open]
+
+ if {![string equal $dc "never"]
+ && ($len || [string equal $dc "always"] || [string equal $dc "allways"])} {
+ _draw_cross $path $node $exp $x0 $y0
+ } else {
+ set idc [$path.c find withtag c:$node]
+ $path.c delete $idc
+ }
+ }
+
+ if { $flag & 7 } {
+ # -font, -text or -fill modified
+ $path.c itemconfigure $idn \
+ -text [Widget::getoption $path.$node -text] \
+ -fill [Widget::getoption $path.$node -fill] \
+ -font [Widget::getoption $path.$node -font]
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_draw_tree
+# ----------------------------------------------------------------------------
+proc Tree::_draw_tree { path } {
+ variable $path
+ upvar 0 $path data
+
+ $path.c delete all
+ set cursor [$path.c cget -cursor]
+ $path.c configure -cursor watch
+ _draw_subnodes $path [lrange $data(root) 1 end] 8 \
+ [expr {-[Widget::getoption $path -deltay]/2}] \
+ [Widget::getoption $path -deltax] \
+ [Widget::getoption $path -deltay] \
+ [Widget::getoption $path -padx] \
+ [Widget::getoption $path -showlines]
+ $path.c configure -cursor $cursor
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_redraw_tree
+# ----------------------------------------------------------------------------
+proc Tree::_redraw_tree { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { [Widget::getoption $path -redraw] } {
+ if { $data(upd,level) == 2 } {
+ _update_nodes $path
+ } elseif { $data(upd,level) == 3 } {
+ _draw_tree $path
+ }
+ _redraw_selection $path
+ _update_scrollregion $path
+ set data(upd,nodes) {}
+ set data(upd,level) 0
+ set data(upd,afterid) ""
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_redraw_selection
+# ----------------------------------------------------------------------------
+proc Tree::_redraw_selection { path } {
+ variable $path
+ upvar 0 $path data
+
+ set selbg [Widget::getoption $path -selectbackground]
+ set selfg [Widget::getoption $path -selectforeground]
+ set fill [Widget::getoption $path -selectfill]
+ if {$fill} {
+ set scroll [$path.c cget -scrollregion]
+ if {[llength $scroll]} {
+ set xmax [expr {[lindex $scroll 2]-1}]
+ } else {
+ set xmax [winfo width $path]
+ }
+ }
+ foreach id [$path.c find withtag sel] {
+ set node [Tree::_get_node_name $path $id 1]
+ $path.c itemconfigure "n:$node" -fill [Widget::getoption $path.$node -fill]
+ }
+ $path.c delete sel
+ foreach node $data(selnodes) {
+ set bbox [$path.c bbox "n:$node"]
+ if { [llength $bbox] } {
+ if {$fill} {
+ # get the image to (if any), as it may have different height
+ set bbox [$path.c bbox "n:$node" "i:$node"]
+ set bbox [list 0 [lindex $bbox 1] $xmax [lindex $bbox 3]]
+ }
+ set id [$path.c create rectangle $bbox -tags [list sel s:$node] \
+ -fill $selbg -outline $selbg]
+ if {$selfg != ""} {
+ # Don't allow an empty fill - that would be transparent
+ $path.c itemconfigure "n:$node" -fill $selfg
+ }
+ $path.c lower $id
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_redraw_idle
+# ----------------------------------------------------------------------------
+proc Tree::_redraw_idle { path level } {
+ variable $path
+ upvar 0 $path data
+
+ if { [Widget::getoption $path -redraw] && $data(upd,afterid) == "" } {
+ set data(upd,afterid) [after idle [list Tree::_redraw_tree $path]]
+ }
+ if { $level > $data(upd,level) } {
+ set data(upd,level) $level
+ }
+ return ""
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_init_drag_cmd
+# ----------------------------------------------------------------------------
+proc Tree::_init_drag_cmd { path X Y top } {
+ set path [winfo parent $path]
+ set ltags [$path.c gettags current]
+ set item [lindex $ltags 1]
+ if { [string equal $item "node"] ||
+ [string equal $item "img"] ||
+ [string equal $item "win"] } {
+ set node [Tree::_get_node_name $path current 2]
+ if {[llength [set cmd [Widget::getoption $path -draginitcmd]]]} {
+ return [uplevel \#0 $cmd [list $path $node $top]]
+ }
+ if { [set type [Widget::getoption $path -dragtype]] == "" } {
+ set type "TREE_NODE"
+ }
+ if { [set img [Widget::getoption $path.$node -image]] != "" } {
+ pack [label $top.l -image $img -padx 0 -pady 0]
+ }
+ return [list $type {copy move link} $node]
+ }
+ return {}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_drop_cmd
+# ----------------------------------------------------------------------------
+proc Tree::_drop_cmd { path source X Y op type dnddata } {
+ set path [winfo parent $path]
+ variable $path
+ upvar 0 $path data
+
+ $path.c delete drop
+ if { [string length $data(dnd,afterid)] } {
+ after cancel $data(dnd,afterid)
+ set data(dnd,afterid) ""
+ }
+ set data(dnd,scroll) ""
+ if {[llength [set cmd [Widget::getoption $path -dropcmd]]]} {
+ return [uplevel \#0 $cmd \
+ [list $path $source $data(dnd,node) $op $type $dnddata]]
+ }
+ return 0
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_over_cmd
+# ----------------------------------------------------------------------------
+proc Tree::_over_cmd { path source event X Y op type dnddata } {
+ set path [winfo parent $path]
+ variable $path
+ upvar 0 $path data
+
+ if { [string equal $event "leave"] } {
+ # we leave the window tree
+ $path.c delete drop
+ if { [string length $data(dnd,afterid)] } {
+ after cancel $data(dnd,afterid)
+ set data(dnd,afterid) ""
+ }
+ set data(dnd,scroll) ""
+ return 0
+ }
+
+ if { [string equal $event "enter"] } {
+ # we enter the window tree - dnd data initialization
+ set mode [Widget::getoption $path -dropovermode]
+ set data(dnd,mode) 0
+ foreach c {w p n} {
+ set data(dnd,mode) [expr {($data(dnd,mode) << 1) | ([string first $c $mode] != -1)}]
+ }
+ set bbox [$path.c bbox all]
+ if { [llength $bbox] } {
+ set data(dnd,xs) [lindex $bbox 2]
+ set data(dnd,empty) 0
+ } else {
+ set data(dnd,xs) 0
+ set data(dnd,empty) 1
+ }
+ set data(dnd,node) {}
+ }
+
+ set x [expr {$X-[winfo rootx $path]}]
+ set y [expr {$Y-[winfo rooty $path]}]
+ $path.c delete drop
+ set data(dnd,node) {}
+
+ # test for auto-scroll unless mode is widget only
+ if { $data(dnd,mode) != 4 && [_auto_scroll $path $x $y] != "" } {
+ return 2
+ }
+
+ if { $data(dnd,mode) & 4 } {
+ # dropovermode includes widget
+ set target [list widget]
+ set vmode 4
+ } else {
+ set target [list ""]
+ set vmode 0
+ }
+ if { ($data(dnd,mode) & 2) && $data(dnd,empty) } {
+ # dropovermode includes position and tree is empty
+ lappend target [list root 0]
+ set vmode [expr {$vmode | 2}]
+ }
+
+ set xc [$path.c canvasx $x]
+ set xs $data(dnd,xs)
+ if { $xc <= $xs } {
+ set yc [$path.c canvasy $y]
+ set dy [$path.c cget -yscrollincrement]
+ set line [expr {int($yc/$dy)}]
+ set xi 0
+ set yi [expr {$line*$dy}]
+ set ys [expr {$yi+$dy}]
+ set found 0
+ foreach id [$path.c find overlapping $xi $yi $xs $ys] {
+ set ltags [$path.c gettags $id]
+ set item [lindex $ltags 1]
+ if { [string equal $item "node"] ||
+ [string equal $item "img"] ||
+ [string equal $item "win"] } {
+ # item is the label or image/window of the node
+ set node [Tree::_get_node_name $path $id 2]
+ set found 1
+ break
+ }
+ }
+ if {$found} {
+ set padx [_get_node_padx $path $node]
+ set deltax [_get_node_deltax $path $node]
+ set xi [expr {[lindex [$path.c coords n:$node] 0] - $padx - 1}]
+ if { $data(dnd,mode) & 1 } {
+ # dropovermode includes node
+ lappend target $node
+ set vmode [expr {$vmode | 1}]
+ } else {
+ lappend target ""
+ }
+
+ if { $data(dnd,mode) & 2 } {
+ # dropovermode includes position
+ if { $yc >= $yi+$dy/2 } {
+ # position is after $node
+ if { [Widget::getoption $path.$node -open] &&
+ [llength $data($node)] > 1 } {
+ # $node is open and have subnodes
+ # drop position is 0 in children of $node
+ set parent $node
+ set index 0
+ set xli [expr {$xi-5}]
+ } else {
+ # $node is not open and doesn't have subnodes
+ # drop position is after $node in children of parent of $node
+ set parent [lindex $data($node) 0]
+ set index [lsearch -exact $data($parent) $node]
+ set xli [expr {$xi - $deltax - 5}]
+ }
+ set yl $ys
+ } else {
+ # position is before $node
+ # drop position is before $node in children of parent of $node
+ set parent [lindex $data($node) 0]
+ set index [expr {[lsearch -exact $data($parent) $node] - 1}]
+ set xli [expr {$xi - $deltax - 5}]
+ set yl $yi
+ }
+ lappend target [list $parent $index]
+ set vmode [expr {$vmode | 2}]
+ } else {
+ lappend target {}
+ }
+
+ if { ($vmode & 3) == 3 } {
+ # result have both node and position
+ # we compute what is the preferred method
+ if { $yc-$yi <= 3 || $ys-$yc <= 3 } {
+ lappend target "position"
+ } else {
+ lappend target "node"
+ }
+ }
+ }
+ }
+
+ if {$vmode && [llength [set cmd [Widget::getoption $path -dropovercmd]]]} {
+ # user-defined dropover command
+ set res [uplevel \#0 $cmd [list $path $source $target $op $type $dnddata]]
+ set code [lindex $res 0]
+ set newmode 0
+ if { $code & 1 } {
+ # update vmode
+ set mode [lindex $res 1]
+ if { ($vmode & 1) && [string equal $mode "node"] } {
+ set newmode 1
+ } elseif { ($vmode & 2) && [string equal $mode "position"] } {
+ set newmode 2
+ } elseif { ($vmode & 4) && [string equal $mode "widget"] } {
+ set newmode 4
+ }
+ }
+ set vmode $newmode
+ } else {
+ if { ($vmode & 3) == 3 } {
+ # result have both item and position
+ # we choose the preferred method
+ if { [string equal [lindex $target 3] "position"] } {
+ set vmode [expr {$vmode & ~1}]
+ } else {
+ set vmode [expr {$vmode & ~2}]
+ }
+ }
+
+ if { $data(dnd,mode) == 4 || $data(dnd,mode) == 0 } {
+ # dropovermode is widget or empty - recall is not necessary
+ set code 1
+ } else {
+ set code 3
+ }
+ }
+
+ if {!$data(dnd,empty)} {
+ # draw dnd visual following vmode
+ if { $vmode & 1 } {
+ set data(dnd,node) [list "node" [lindex $target 1]]
+ $path.c create rectangle $xi $yi $xs $ys -tags drop
+ } elseif { $vmode & 2 } {
+ set data(dnd,node) [concat "position" [lindex $target 2]]
+ $path.c create line $xli [expr {$yl-$dy/2}] $xli $yl $xs $yl -tags drop
+ } elseif { $vmode & 4 } {
+ set data(dnd,node) [list "widget"]
+ } else {
+ set code [expr {$code & 2}]
+ }
+ }
+
+ if { $code & 1 } {
+ DropSite::setcursor based_arrow_down
+ } else {
+ DropSite::setcursor dot
+ }
+ return $code
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_auto_scroll
+# ----------------------------------------------------------------------------
+proc Tree::_auto_scroll { path x y } {
+ variable $path
+ upvar 0 $path data
+
+ set xmax [winfo width $path]
+ set ymax [winfo height $path]
+ set scroll {}
+ if { $y <= 6 } {
+ if { [lindex [$path.c yview] 0] > 0 } {
+ set scroll [list yview -1]
+ DropSite::setcursor sb_up_arrow
+ }
+ } elseif { $y >= $ymax-6 } {
+ if { [lindex [$path.c yview] 1] < 1 } {
+ set scroll [list yview 1]
+ DropSite::setcursor sb_down_arrow
+ }
+ } elseif { $x <= 6 } {
+ if { [lindex [$path.c xview] 0] > 0 } {
+ set scroll [list xview -1]
+ DropSite::setcursor sb_left_arrow
+ }
+ } elseif { $x >= $xmax-6 } {
+ if { [lindex [$path.c xview] 1] < 1 } {
+ set scroll [list xview 1]
+ DropSite::setcursor sb_right_arrow
+ }
+ }
+
+ if { [string length $data(dnd,afterid)] && ![string equal $data(dnd,scroll) $scroll] } {
+ after cancel $data(dnd,afterid)
+ set data(dnd,afterid) ""
+ }
+
+ set data(dnd,scroll) $scroll
+ if { [string length $scroll] && ![string length $data(dnd,afterid)] } {
+ set data(dnd,afterid) [after 200 [list Tree::_scroll $path $scroll]]
+ }
+ return $data(dnd,afterid)
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_scroll
+# ----------------------------------------------------------------------------
+proc Tree::_scroll { path scroll } {
+ variable $path
+ upvar 0 $path data
+ set cmd [lindex $scroll 0]
+ set dir [lindex $scroll 1]
+ if { ($dir == -1 && [lindex [$path.c $cmd] 0] > 0) ||
+ ($dir == 1 && [lindex [$path.c $cmd] 1] < 1) } {
+ $path.c $cmd scroll $dir units
+ set data(dnd,afterid) [after 50 [list Tree::_scroll $path $scroll]]
+ } else {
+ set data(dnd,afterid) ""
+ DropSite::setcursor dot
+ }
+}
+
+# Tree::_keynav --
+#
+# Handle navigational keypresses on the tree.
+#
+# Arguments:
+# which tag indicating the direction of motion:
+# up move to the node graphically above current
+# down move to the node graphically below current
+# left close current if open, else move to parent
+# right open current if closed, else move to child
+# open open current if closed, close current if open
+# win name of the tree widget
+#
+# Results:
+# None.
+
+proc Tree::_keynav {which win} {
+ # check for an empty tree
+ if {[$win nodes root] eq ""} {
+ return
+ }
+
+ # Keyboard navigation is riddled with special cases. In order to avoid
+ # the complex logic, we will instead make a list of all the visible,
+ # selectable nodes, then do a simple next or previous operation.
+
+ # One easy way to get all of the visible nodes is to query the canvas
+ # object for all the items with the "node" tag; since the tree is always
+ # completely redrawn, this list will be in vertical order.
+ set nodes {}
+ foreach nodeItem [$win.c find withtag node] {
+ set node [Tree::_get_node_name $win $nodeItem 2]
+ if { [Widget::cget $win.$node -selectable] } {
+ lappend nodes $node
+ }
+ }
+
+ # Keyboard navigation is all relative to the current node
+ # surles: Get the current node for single or multiple selection schemas.
+ set node [_get_current_node $win]
+
+ switch -exact -- $which {
+ "up" {
+ # Up goes to the node that is vertically above the current node
+ # (NOT necessarily the current node's parent)
+ if { [string equal $node ""] } {
+ return
+ }
+ set index [lsearch -exact $nodes $node]
+ incr index -1
+ if { $index >= 0 } {
+ $win selection set [lindex $nodes $index]
+ _set_current_node $win [lindex $nodes $index]
+ $win see [lindex $nodes $index]
+ event generate $win <<TreeSelect>>
+ return
+ }
+ }
+ "down" {
+ # Down goes to the node that is vertically below the current node
+ if { [string equal $node ""] } {
+ $win selection set [lindex $nodes 0]
+ _set_current_node $win [lindex $nodes 0]
+ $win see [lindex $nodes 0]
+ event generate $win <<TreeSelect>>
+ return
+ }
+
+ set index [lsearch -exact $nodes $node]
+ incr index
+ if { $index < [llength $nodes] } {
+ $win selection set [lindex $nodes $index]
+ _set_current_node $win [lindex $nodes $index]
+ $win see [lindex $nodes $index]
+ event generate $win <<TreeSelect>>
+ return
+ }
+ }
+ "right" {
+ # On a right arrow, if the current node is closed, open it.
+ # If the current node is open, go to its first child
+ if { [string equal $node ""] } {
+ return
+ }
+ set open [$win itemcget $node -open]
+ if { $open } {
+ if { [llength [$win nodes $node]] } {
+ set index [lsearch -exact $nodes $node]
+ incr index
+ if { $index < [llength $nodes] } {
+ $win selection set [lindex $nodes $index]
+ _set_current_node $win [lindex $nodes $index]
+ $win see [lindex $nodes $index]
+ event generate $win <<TreeSelect>>
+ return
+ }
+ }
+ } else {
+ $win itemconfigure $node -open 1
+ if {[llength [set cmd [Widget::getoption $win -opencmd]]]} {
+ uplevel \#0 $cmd [list $node]
+ }
+ return
+ }
+ }
+ "left" {
+ # On a left arrow, if the current node is open, close it.
+ # If the current node is closed, go to its parent.
+ if { [string equal $node ""] } {
+ return
+ }
+ set open [$win itemcget $node -open]
+ if { $open } {
+ $win itemconfigure $node -open 0
+ if {[llength [set cmd [Widget::getoption $win -closecmd]]]} {
+ uplevel \#0 $cmd [list $node]
+ }
+ return
+ } else {
+ set parent [$win parent $node]
+ if { [string equal $parent "root"] } {
+ set parent $node
+ } else {
+ while { ![$win itemcget $parent -selectable] } {
+ set parent [$win parent $parent]
+ if { [string equal $parent "root"] } {
+ set parent $node
+ break
+ }
+ }
+ }
+ $win selection set $parent
+ _set_current_node $win $parent
+ $win see $parent
+ event generate $win <<TreeSelect>>
+ return
+ }
+ }
+ "space" {
+ if { [string equal $node ""] } {
+ return
+ }
+ set open [$win itemcget $node -open]
+ if { [llength [$win nodes $node]] } {
+
+ # Toggle the open status of the chosen node.
+
+ $win itemconfigure $node -open [expr {$open?0:1}]
+
+ if {$open} {
+ # Node was open, is now closed. Call the close-cmd
+
+ if {[llength [set cmd [Widget::getoption $win -closecmd]]]} {
+ uplevel \#0 $cmd [list $node]
+ }
+ } else {
+ # Node was closed, is now open. Call the open-cmd
+
+ if {[llength [set cmd [Widget::getoption $win -opencmd]]]} {
+ uplevel \#0 $cmd [list $node]
+ }
+ }
+ }
+ }
+ }
+ return
+}
+
+# Tree::_get_current_node --
+#
+# Get the current node for either single or multiple
+# node selection trees. If the tree allows for
+# multiple selection, return the cursor node. Otherwise,
+# if there is a selection, return the first node in the
+# list. If there is no selection, return the root node.
+#
+# arguments:
+# win name of the tree widget
+#
+# Results:
+# The current node.
+
+proc Tree::_get_current_node {win} {
+ if {[info exists selectTree::selectCursor($win)]} {
+ set result $selectTree::selectCursor($win)
+ } elseif {[llength [set selList [$win selection get]]]} {
+ set result [lindex $selList 0]
+ } else {
+ set result ""
+ }
+ return $result
+}
+
+# Tree::_set_current_node --
+#
+# Set the current node for either single or multiple
+# node selection trees.
+#
+# arguments:
+# win Name of the tree widget
+# node The current node.
+#
+# Results:
+# None.
+
+proc Tree::_set_current_node {win node} {
+ if {[info exists selectTree::selectCursor($win)]} {
+ set selectTree::selectCursor($win) $node
+ }
+ return
+}
+
+# Tree::_get_node_name --
+#
+# Given a canvas item, get the name of the tree node represented by that
+# item.
+#
+# Arguments:
+# path tree to query
+# item Optional canvas item to examine; if omitted,
+# defaults to "current"
+# tagindex Optional tag index, since the n:nodename tag is not
+# in the same spot for all canvas items. If omitted,
+# defaults to "end-1", so it works with "current" item.
+#
+# Results:
+# node name of the tree node.
+
+proc Tree::_get_node_name {path {item current} {tagindex end-1} {truename 0}} {
+ set node [string range [lindex [$path.c gettags $item] $tagindex] 2 end]
+ if {$truename} {
+ return [_node_name_rev $path $node]
+ }
+ return $node
+}
+
+# Tree::_get_node_padx --
+#
+# Given a node in the tree, return it's padx value. If the value is
+# less than 0, default to the padx of the entire tree.
+#
+# Arguments:
+# path Tree to query
+# node Node in the tree
+#
+# Results:
+# padx The numeric padx value
+proc Tree::_get_node_padx {path node} {
+ set padx [Widget::getoption $path.$node -padx]
+ if {$padx < 0} { set padx [Widget::getoption $path -padx] }
+ return $padx
+}
+
+# Tree::_get_node_deltax --
+#
+# Given a node in the tree, return it's deltax value. If the value is
+# less than 0, default to the deltax of the entire tree.
+#
+# Arguments:
+# path Tree to query
+# node Node in the tree
+#
+# Results:
+# deltax The numeric deltax value
+proc Tree::_get_node_deltax {path node} {
+ set deltax [Widget::getoption $path.$node -deltax]
+ if {$deltax < 0} { set deltax [Widget::getoption $path -deltax] }
+ return $deltax
+}
+
+
+# Tree::_get_node_tags --
+#
+# Given a node in the tree, return a list of tags to apply to its
+# canvas item.
+#
+# Arguments:
+# path Tree to query
+# node Node in the tree
+# tags A list of tags to add to the final list
+#
+# Results:
+# list The list of tags to apply to the canvas item
+proc Tree::_get_node_tags {path node {tags ""}} {
+ eval [linsert $tags 0 lappend list TreeItemSentinal]
+ if {[Widget::getoption $path.$node -helptext] == "" &&
+ [Widget::getoption $path.$node -helpcmd] == ""} { return $list }
+
+ switch -- [Widget::getoption $path.$node -helptype] {
+ balloon {
+ lappend list BwHelpBalloon
+ }
+ variable {
+ lappend list BwHelpVariable
+ }
+ }
+ return $list
+}
+
+# Tree::_set_help --
+#
+# Register dynamic help for a node in the tree.
+#
+# Arguments:
+# path Tree to query
+# node Node in the tree
+# force Optional argument to force a reset of the help
+#
+# Results:
+# none
+proc Tree::_set_help { path node } {
+ Widget::getVariable $path help
+
+ set item $path.$node
+ set opts [list -helptype -helptext -helpvar -helpcmd]
+ foreach {cty ctx cv cc} [eval [linsert $opts 0 Widget::hasChangedX $item]] break
+ set text [Widget::getoption $item -helptext]
+ set cmd [Widget::getoption $item -helpcmd]
+
+ ## If we've never set help for this item before, and text or cmd is not
+ ## blank, we need to setup help. We also need to reset help if any of the
+ ## options have changed.
+ if { (![info exists help($node)] && ($text != "" || $cmd != ""))
+ || $cty || $ctx || $cv } {
+ set help($node) 1
+ set type [Widget::getoption $item -helptype]
+ set var [Widget::getoption $item -helpvar]
+ DynamicHelp::add $path.c -item n:$node -type $type -text $text -variable $var -command $cmd
+ DynamicHelp::add $path.c -item i:$node -type $type -text $text -variable $var -command $cmd
+ DynamicHelp::add $path.c -item b:$node -type $type -text $text -variable $var -command $cmd
+ }
+}
+
+proc Tree::_mouse_select { path cmd args } {
+ eval [linsert $args 0 selection $path $cmd]
+ switch -- $cmd {
+ "add" - "clear" - "remove" - "set" - "toggle" {
+ event generate $path <<TreeSelect>>
+ }
+ }
+}
+
+proc Tree::_node_name { path node } {
+ # Make sure node names are safe as tags and variable names
+ set map [list & \1 | \2 ^ \3 ! \4 :: \5]
+ return [string map $map $node]
+}
+
+proc Tree::_node_name_rev { path node } {
+ # Allow reverse interpretation of node names
+ set map [list \1 & \2 | \3 ^ \4 ! \5 ::]
+ return [string map $map $node]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Tree::_destroy
+# ----------------------------------------------------------------------------
+proc Tree::_destroy { path } {
+ variable $path
+ upvar 0 $path data
+
+ if { $data(upd,afterid) != "" } {
+ after cancel $data(upd,afterid)
+ }
+ if { $data(dnd,afterid) != "" } {
+ after cancel $data(dnd,afterid)
+ }
+ _subdelete $path [lrange $data(root) 1 end]
+ Widget::destroy $path
+ unset data
+}
diff --git a/modules/tclsci/tcl/BWidget/utils.tcl b/modules/tclsci/tcl/BWidget/utils.tcl
new file mode 100755
index 000000000..5fe804f2a
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/utils.tcl
@@ -0,0 +1,680 @@
+# ----------------------------------------------------------------------------
+# utils.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: utils.tcl,v 1.15.2.1 2009/09/03 17:29:03 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - GlobalVar::exists
+# - GlobalVar::setvarvar
+# - GlobalVar::getvarvar
+# - BWidget::assert
+# - BWidget::clonename
+# - BWidget::get3dcolor
+# - BWidget::XLFDfont
+# - BWidget::place
+# - BWidget::grab
+# - BWidget::focus
+# ----------------------------------------------------------------------------
+
+namespace eval GlobalVar {
+ proc use {} {}
+}
+
+
+namespace eval BWidget {
+ variable _top
+ variable _gstack {}
+ variable _fstack {}
+ proc use {} {}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command GlobalVar::exists
+# ----------------------------------------------------------------------------
+proc GlobalVar::exists { varName } {
+ return [uplevel \#0 [list info exists $varName]]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command GlobalVar::setvar
+# ----------------------------------------------------------------------------
+proc GlobalVar::setvar { varName value } {
+ return [uplevel \#0 [list set $varName $value]]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command GlobalVar::getvar
+# ----------------------------------------------------------------------------
+proc GlobalVar::getvar { varName } {
+ return [uplevel \#0 [list set $varName]]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command GlobalVar::tracevar
+# ----------------------------------------------------------------------------
+proc GlobalVar::tracevar { cmd varName args } {
+ return [uplevel \#0 [list trace $cmd $varName] $args]
+}
+
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::lreorder
+# ----------------------------------------------------------------------------
+proc BWidget::lreorder { list neworder } {
+ set pos 0
+ set newlist {}
+ foreach e $neworder {
+ if { [lsearch -exact $list $e] != -1 } {
+ lappend newlist $e
+ set tabelt($e) 1
+ }
+ }
+ set len [llength $newlist]
+ if { !$len } {
+ return $list
+ }
+ if { $len == [llength $list] } {
+ return $newlist
+ }
+ set pos 0
+ foreach e $list {
+ if { ![info exists tabelt($e)] } {
+ set newlist [linsert $newlist $pos $e]
+ }
+ incr pos
+ }
+ return $newlist
+}
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::assert
+# ----------------------------------------------------------------------------
+proc BWidget::assert { exp {msg ""}} {
+ set res [uplevel 1 expr $exp]
+ if { !$res} {
+ if { $msg == "" } {
+ return -code error "Assertion failed: {$exp}"
+ } else {
+ return -code error $msg
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::clonename
+# ----------------------------------------------------------------------------
+proc BWidget::clonename { menu } {
+ set path ""
+ set menupath ""
+ set found 0
+ foreach widget [lrange [split $menu "."] 1 end] {
+ if { $found || [winfo class "$path.$widget"] == "Menu" } {
+ set found 1
+ append menupath "#" $widget
+ append path "." $menupath
+ } else {
+ append menupath "#" $widget
+ append path "." $widget
+ }
+ }
+ return $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::getname
+# ----------------------------------------------------------------------------
+proc BWidget::getname { name } {
+ if { [string length $name] } {
+ set text [option get . "${name}Name" ""]
+ if { [string length $text] } {
+ return [parsetext $text]
+ }
+ }
+ return {}
+ }
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::parsetext
+# ----------------------------------------------------------------------------
+proc BWidget::parsetext { text } {
+ set result ""
+ set index -1
+ set start 0
+ while { [string length $text] } {
+ set idx [string first "&" $text]
+ if { $idx == -1 } {
+ append result $text
+ set text ""
+ } else {
+ set char [string index $text [expr {$idx+1}]]
+ if { $char == "&" } {
+ append result [string range $text 0 $idx]
+ set text [string range $text [expr {$idx+2}] end]
+ set start [expr {$start+$idx+1}]
+ } else {
+ append result [string range $text 0 [expr {$idx-1}]]
+ set text [string range $text [expr {$idx+1}] end]
+ incr start $idx
+ set index $start
+ }
+ }
+ }
+ return [list $result $index]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::get3dcolor
+# ----------------------------------------------------------------------------
+proc BWidget::get3dcolor { path bgcolor } {
+ foreach val [winfo rgb $path $bgcolor] {
+ lappend dark [expr {60*$val/100}]
+ set tmp1 [expr {14*$val/10}]
+ if { $tmp1 > 65535 } {
+ set tmp1 65535
+ }
+ set tmp2 [expr {(65535+$val)/2}]
+ lappend light [expr {($tmp1 > $tmp2) ? $tmp1:$tmp2}]
+ }
+ return [list [eval format "#%04x%04x%04x" $dark] [eval format "#%04x%04x%04x" $light]]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::XLFDfont
+# ----------------------------------------------------------------------------
+proc BWidget::XLFDfont { cmd args } {
+ switch -- $cmd {
+ create {
+ set font "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
+ }
+ configure {
+ set font [lindex $args 0]
+ set args [lrange $args 1 end]
+ }
+ default {
+ return -code error "XLFDfont: commande incorrect: $cmd"
+ }
+ }
+ set lfont [split $font "-"]
+ if { [llength $lfont] != 15 } {
+ return -code error "XLFDfont: description XLFD incorrect: $font"
+ }
+
+ foreach {option value} $args {
+ switch -- $option {
+ -foundry { set index 1 }
+ -family { set index 2 }
+ -weight { set index 3 }
+ -slant { set index 4 }
+ -size { set index 7 }
+ default { return -code error "XLFDfont: option incorrecte: $option" }
+ }
+ set lfont [lreplace $lfont $index $index $value]
+ }
+ return [join $lfont "-"]
+}
+
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::place
+# ----------------------------------------------------------------------------
+#
+# Notes:
+# For Windows systems with more than one monitor the available screen area may
+# have negative positions. Geometry settings with negative numbers are used
+# under X to place wrt the right or bottom of the screen. On windows, Tk
+# continues to do this. However, a geometry such as 100x100+-200-100 can be
+# used to place a window onto a secondary monitor. Passing the + gets Tk
+# to pass the remainder unchanged so the Windows manager then handles -200
+# which is a position on the left hand monitor.
+# I've tested this for left, right, above and below the primary monitor.
+# Currently there is no way to ask Tk the extent of the Windows desktop in
+# a multi monitor system. Nor what the legal co-ordinate range might be.
+#
+proc BWidget::place { path w h args } {
+ variable _top
+
+ update idletasks
+
+ # If the window is not mapped, it may have any current size.
+ # Then use required size, but bound it to the screen width.
+ # This is mostly inexact, because any toolbars will still be removed
+ # which may reduce size.
+ if { $w == 0 && [winfo ismapped $path] } {
+ set w [winfo width $path]
+ } else {
+ if { $w == 0 } {
+ set w [winfo reqwidth $path]
+ }
+ set vsw [winfo vrootwidth $path]
+ if { $w > $vsw } { set w $vsw }
+ }
+
+ if { $h == 0 && [winfo ismapped $path] } {
+ set h [winfo height $path]
+ } else {
+ if { $h == 0 } {
+ set h [winfo reqheight $path]
+ }
+ set vsh [winfo vrootheight $path]
+ if { $h > $vsh } { set h $vsh }
+ }
+
+ set arglen [llength $args]
+ if { $arglen > 3 } {
+ return -code error "BWidget::place: bad number of argument"
+ }
+
+ if { $arglen > 0 } {
+ set where [lindex $args 0]
+ set list [list "at" "center" "left" "right" "above" "below"]
+ set idx [lsearch $list $where]
+ if { $idx == -1 } {
+ return -code error [BWidget::badOptionString position $where $list]
+ }
+ if { $idx == 0 } {
+ set err [catch {
+ # purposely removed the {} around these expressions - [PT]
+ set x [expr int([lindex $args 1])]
+ set y [expr int([lindex $args 2])]
+ }]
+ if { $err } {
+ return -code error "BWidget::place: incorrect position"
+ }
+ if {$::tcl_platform(platform) == "windows"} {
+ # handle windows multi-screen. -100 != +-100
+ if {[string index [lindex $args 1] 0] != "-"} {
+ set x "+$x"
+ }
+ if {[string index [lindex $args 2] 0] != "-"} {
+ set y "+$y"
+ }
+ } else {
+ if { $x >= 0 } {
+ set x "+$x"
+ }
+ if { $y >= 0 } {
+ set y "+$y"
+ }
+ }
+ } else {
+ if { $arglen == 2 } {
+ set widget [lindex $args 1]
+ if { ![winfo exists $widget] } {
+ return -code error "BWidget::place: \"$widget\" does not exist"
+ }
+ } else {
+ set widget .
+ }
+ set sw [winfo screenwidth $path]
+ set sh [winfo screenheight $path]
+ if { $idx == 1 } {
+ if { $arglen == 2 } {
+ # center to widget
+ set x0 [expr {[winfo rootx $widget] + ([winfo width $widget] - $w)/2}]
+ set y0 [expr {[winfo rooty $widget] + ([winfo height $widget] - $h)/2}]
+ } else {
+ # center to screen
+ set x0 [expr {($sw - $w)/2 - [winfo vrootx $path]}]
+ set y0 [expr {($sh - $h)/2 - [winfo vrooty $path]}]
+ }
+ set x "+$x0"
+ set y "+$y0"
+ if {$::tcl_platform(platform) != "windows"} {
+ if { $x0+$w > $sw } {set x "-0"; set x0 [expr {$sw-$w}]}
+ if { $x0 < 0 } {set x "+0"}
+ if { $y0+$h > $sh } {set y "-0"; set y0 [expr {$sh-$h}]}
+ if { $y0 < 0 } {set y "+0"}
+ }
+ } else {
+ set x0 [winfo rootx $widget]
+ set y0 [winfo rooty $widget]
+ set x1 [expr {$x0 + [winfo width $widget]}]
+ set y1 [expr {$y0 + [winfo height $widget]}]
+ if { $idx == 2 || $idx == 3 } {
+ set y "+$y0"
+ if {$::tcl_platform(platform) != "windows"} {
+ if { $y0+$h > $sh } {set y "-0"; set y0 [expr {$sh-$h}]}
+ if { $y0 < 0 } {set y "+0"}
+ }
+ if { $idx == 2 } {
+ # try left, then right if out, then 0 if out
+ if { $x0 >= $w } {
+ set x [expr {$x0-$w}]
+ } elseif { $x1+$w <= $sw } {
+ set x "+$x1"
+ } else {
+ set x "+0"
+ }
+ } else {
+ # try right, then left if out, then 0 if out
+ if { $x1+$w <= $sw } {
+ set x "+$x1"
+ } elseif { $x0 >= $w } {
+ set x [expr {$x0-$w}]
+ } else {
+ set x "-0"
+ }
+ }
+ } else {
+ set x "+$x0"
+ if {$::tcl_platform(platform) != "windows"} {
+ if { $x0+$w > $sw } {set x "-0"; set x0 [expr {$sw-$w}]}
+ if { $x0 < 0 } {set x "+0"}
+ }
+ if { $idx == 4 } {
+ # try top, then bottom, then 0
+ if { $h <= $y0 } {
+ set y [expr {$y0-$h}]
+ } elseif { $y1+$h <= $sh } {
+ set y "+$y1"
+ } else {
+ set y "+0"
+ }
+ } else {
+ # try bottom, then top, then 0
+ if { $y1+$h <= $sh } {
+ set y "+$y1"
+ } elseif { $h <= $y0 } {
+ set y [expr {$y0-$h}]
+ } else {
+ set y "-0"
+ }
+ }
+ }
+ }
+ }
+
+ ## If there's not a + or - in front of the number, we need to add one.
+ if {[string is integer [string index $x 0]]} { set x +$x }
+ if {[string is integer [string index $y 0]]} { set y +$y }
+
+ wm geometry $path "${w}x${h}${x}${y}"
+ } else {
+ wm geometry $path "${w}x${h}"
+ }
+ update idletasks
+}
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::grab
+# ----------------------------------------------------------------------------
+proc BWidget::grab { option path } {
+ variable _gstack
+
+ if { $option == "release" } {
+ catch {::grab release $path}
+ while { [llength $_gstack] } {
+ set grinfo [lindex $_gstack end]
+ set _gstack [lreplace $_gstack end end]
+ foreach {oldg mode} $grinfo {
+ if { ![string equal $oldg $path] && [winfo exists $oldg] } {
+ if { $mode == "global" } {
+ catch {::grab -global $oldg}
+ } else {
+ catch {::grab $oldg}
+ }
+ return
+ }
+ }
+ }
+ } else {
+ set oldg [::grab current]
+ if { $oldg != "" } {
+ lappend _gstack [list $oldg [::grab status $oldg]]
+ }
+ if { $option == "global" } {
+ ::grab -global $path
+ } else {
+ ::grab $path
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command BWidget::focus
+# ----------------------------------------------------------------------------
+proc BWidget::focus { option path {refocus 1} } {
+ variable _fstack
+
+ if { $option == "release" } {
+ while { [llength $_fstack] } {
+ set oldf [lindex $_fstack end]
+ set _fstack [lreplace $_fstack end end]
+ if { ![string equal $oldf $path] && [winfo exists $oldf] } {
+ if {$refocus} {catch {::focus -force $oldf}}
+ return
+ }
+ }
+ } elseif { $option == "set" } {
+ lappend _fstack [::focus]
+ ::focus -force $path
+ }
+}
+
+# BWidget::refocus --
+#
+# Helper function used to redirect focus from a container frame in
+# a megawidget to a component widget. Only redirects focus if
+# focus is already on the container.
+#
+# Arguments:
+# container container widget to redirect from.
+# component component widget to redirect to.
+#
+# Results:
+# None.
+
+proc BWidget::refocus {container component} {
+ if { [string equal $container [::focus]] } {
+ ::focus $component
+ }
+ return
+}
+
+## These mirror tk::(Set|Restore)FocusGrab
+
+# BWidget::SetFocusGrab --
+# swap out current focus and grab temporarily (for dialogs)
+# Arguments:
+# grab new window to grab
+# focus window to give focus to
+# Results:
+# Returns nothing
+#
+proc BWidget::SetFocusGrab {grab {focus {}}} {
+ variable _focusGrab
+ set index "$grab,$focus"
+
+ lappend _focusGrab($index) [::focus]
+ set oldGrab [::grab current $grab]
+ lappend _focusGrab($index) $oldGrab
+ if {[winfo exists $oldGrab]} {
+ lappend _focusGrab($index) [::grab status $oldGrab]
+ }
+ # The "grab" command will fail if another application
+ # already holds the grab. So catch it.
+ catch {::grab $grab}
+ if {[winfo exists $focus]} {
+ ::focus $focus
+ }
+}
+
+# BWidget::RestoreFocusGrab --
+# restore old focus and grab (for dialogs)
+# Arguments:
+# grab window that had taken grab
+# focus window that had taken focus
+# destroy destroy|withdraw - how to handle the old grabbed window
+# Results:
+# Returns nothing
+#
+proc BWidget::RestoreFocusGrab {grab focus {destroy destroy}} {
+ variable _focusGrab
+ set index "$grab,$focus"
+ if {[info exists _focusGrab($index)]} {
+ foreach {oldFocus oldGrab oldStatus} $_focusGrab($index) break
+ unset _focusGrab($index)
+ } else {
+ set oldGrab ""
+ }
+
+ catch {::focus $oldFocus}
+ ::grab release $grab
+ if {[string equal $destroy "withdraw"]} {
+ wm withdraw $grab
+ } else {
+ ::destroy $grab
+ }
+ if {[winfo exists $oldGrab] && [winfo ismapped $oldGrab]} {
+ if {[string equal $oldStatus "global"]} {
+ ::grab -global $oldGrab
+ } else {
+ ::grab $oldGrab
+ }
+ }
+}
+
+# BWidget::badOptionString --
+#
+# Helper function to return a proper error string when an option
+# doesn't match a list of given options.
+#
+# Arguments:
+# type A string that represents the type of option.
+# value The value that is in-valid.
+# list A list of valid options.
+#
+# Results:
+# None.
+proc BWidget::badOptionString {type value list} {
+ set last [lindex $list end]
+ set list [lreplace $list end end]
+ return "bad $type \"$value\": must be [join $list ", "], or $last"
+}
+
+
+proc BWidget::wrongNumArgsString { string } {
+ return "wrong # args: should be \"$string\""
+}
+
+
+proc BWidget::read_file { file } {
+ set fp [open $file]
+ set x [read $fp [file size $file]]
+ close $fp
+ return $x
+}
+
+
+proc BWidget::classes { class } {
+ variable use
+
+ ${class}::use
+ set classes [list $class]
+ if {![info exists use($class)]} { return }
+ foreach class $use($class) {
+ if {![string equal $class "-classonly"]} {
+ eval lappend classes [classes $class]
+ }
+ }
+ return [lsort -unique $classes]
+}
+
+
+proc BWidget::library { args } {
+ variable use
+
+ set libs [list widget init utils]
+ set classes [list]
+ foreach class $args {
+ ${class}::use
+ eval lappend classes [classes $class]
+ }
+
+ eval lappend libs [lsort -unique $classes]
+
+ set library ""
+ foreach lib $libs {
+ if {![info exists use($lib,file)]} {
+ set file [file join $::BWIDGET::LIBRARY $lib.tcl]
+ } else {
+ set file [file join $::BWIDGET::LIBRARY $use($lib,file).tcl]
+ }
+ append library [read_file $file]
+ }
+
+ return $library
+}
+
+
+proc BWidget::inuse { class } {
+ variable ::Widget::_inuse
+
+ if {![info exists _inuse($class)]} { return 0 }
+ return [expr $_inuse($class) > 0]
+}
+
+
+proc BWidget::write { filename {mode w} } {
+ variable use
+
+ if {![info exists use(classes)]} { return }
+
+ set classes [list]
+ foreach class $use(classes) {
+ if {![inuse $class]} { continue }
+ lappend classes $class
+ }
+
+ set fp [open $filename $mode]
+ puts $fp [eval library $classes]
+ close $fp
+
+ return
+}
+
+
+# BWidget::bindMouseWheel --
+#
+# Bind mouse wheel actions to a given widget.
+#
+# Arguments:
+# widget - The widget to bind.
+#
+# Results:
+# None.
+proc BWidget::bindMouseWheel { widget } {
+ if {[bind all <MouseWheel>] eq ""} {
+ # style::as and Tk 8.5 have global bindings
+ # Only enable these if no global binding for MouseWheel exists
+ bind $widget <MouseWheel> \
+ {%W yview scroll [expr {-%D/24}] units}
+ bind $widget <Shift-MouseWheel> \
+ {%W yview scroll [expr {-%D/120}] pages}
+ bind $widget <Control-MouseWheel> \
+ {%W yview scroll [expr {-%D/120}] units}
+ }
+
+ if {[bind all <Button-4>] eq ""} {
+ # style::as and Tk 8.5 have global bindings
+ # Only enable these if no global binding for them exists
+ bind $widget <Button-4> {event generate %W <MouseWheel> -delta 120}
+ bind $widget <Button-5> {event generate %W <MouseWheel> -delta -120}
+ }
+}
+
+
diff --git a/modules/tclsci/tcl/BWidget/widget.tcl b/modules/tclsci/tcl/BWidget/widget.tcl
new file mode 100755
index 000000000..a0c0fa8fa
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/widget.tcl
@@ -0,0 +1,1610 @@
+# ----------------------------------------------------------------------------
+# widget.tcl
+# This file is part of Unifix BWidget Toolkit
+# $Id: widget.tcl,v 1.35 2009/07/02 16:22:18 oehhar Exp $
+# ----------------------------------------------------------------------------
+# Index of commands:
+# - Widget::tkinclude
+# - Widget::bwinclude
+# - Widget::declare
+# - Widget::addmap
+# - Widget::init
+# - Widget::destroy
+# - Widget::setoption
+# - Widget::configure
+# - Widget::cget
+# - Widget::subcget
+# - Widget::hasChanged
+# - Widget::options
+# - Widget::_get_tkwidget_options
+# - Widget::_test_tkresource
+# - Widget::_test_bwresource
+# - Widget::_test_synonym
+# - Widget::_test_string
+# - Widget::_test_flag
+# - Widget::_test_enum
+# - Widget::_test_int
+# - Widget::_test_boolean
+# ----------------------------------------------------------------------------
+# Each megawidget gets a namespace of the same name inside the Widget namespace
+# Each of these has an array opt, which contains information about the
+# megawidget options. It maps megawidget options to a list with this format:
+# {optionType defaultValue isReadonly {additionalOptionalInfo}}
+# Option types and their additional optional info are:
+# TkResource {genericTkWidget genericTkWidgetOptionName}
+# BwResource {nothing}
+# Enum {list of enumeration values}
+# Int {Boundary information}
+# Boolean {nothing}
+# String {nothing}
+# Flag {string of valid flag characters}
+# Synonym {nothing}
+# Color {nothing}
+#
+# Next, each namespace has an array map, which maps class options to their
+# component widget options:
+# map(-foreground) => {.e -foreground .f -foreground}
+#
+# Each has an array ${path}:opt, which contains the value of each megawidget
+# option for a particular instance $path of the megawidget, and an array
+# ${path}:mod, which stores the "changed" status of configuration options.
+
+# Steps for creating a bwidget megawidget:
+# 1. parse args to extract subwidget spec
+# 2. Create frame with appropriate class and command line options
+# 3. Get initialization options from optionDB, using frame
+# 4. create subwidgets
+
+# Uses newer string operations
+package require Tcl 8.1.1
+
+namespace eval Widget {
+ variable _optiontype
+ variable _class
+ variable _tk_widget
+
+ # This controls whether we try to use themed widgets from Tile
+ variable _theme 0
+
+ variable _aqua [expr {($::tcl_version >= 8.4) &&
+ [string equal [tk windowingsystem] "aqua"]}]
+
+ array set _optiontype {
+ TkResource Widget::_test_tkresource
+ BwResource Widget::_test_bwresource
+ Enum Widget::_test_enum
+ Int Widget::_test_int
+ Boolean Widget::_test_boolean
+ String Widget::_test_string
+ Flag Widget::_test_flag
+ Synonym Widget::_test_synonym
+ Color Widget::_test_color
+ Padding Widget::_test_padding
+ }
+
+ proc use {} {}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::tkinclude
+# Includes tk widget resources to BWidget widget.
+# class class name of the BWidget
+# tkwidget tk widget to include
+# subpath subpath to configure
+# args additionnal args for included options
+# ----------------------------------------------------------------------------
+proc Widget::tkinclude { class tkwidget subpath args } {
+ foreach {cmd lopt} $args {
+ # cmd can be
+ # include options to include lopt = {opt ...}
+ # remove options to remove lopt = {opt ...}
+ # rename options to rename lopt = {opt newopt ...}
+ # prefix options to prefix lopt = {pref opt opt ..}
+ # initialize set default value for options lopt = {opt value ...}
+ # readonly set readonly flag for options lopt = {opt flag ...}
+ switch -- $cmd {
+ remove {
+ foreach option $lopt {
+ set remove($option) 1
+ }
+ }
+ include {
+ foreach option $lopt {
+ set include($option) 1
+ }
+ }
+ prefix {
+ set prefix [lindex $lopt 0]
+ foreach option [lrange $lopt 1 end] {
+ set rename($option) "-$prefix[string range $option 1 end]"
+ }
+ }
+ rename -
+ readonly -
+ initialize {
+ array set $cmd $lopt
+ }
+ default {
+ return -code error "invalid argument \"$cmd\""
+ }
+ }
+ }
+
+ namespace eval $class {}
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::map classmap
+ upvar 0 ${class}::map$subpath submap
+ upvar 0 ${class}::optionExports exports
+
+ set foo [$tkwidget ".ericFoo###"]
+ # create resources informations from tk widget resources
+ foreach optdesc [_get_tkwidget_options $tkwidget] {
+ set option [lindex $optdesc 0]
+ if { (![info exists include] || [info exists include($option)]) &&
+ ![info exists remove($option)] } {
+ if { [llength $optdesc] == 3 } {
+ # option is a synonym
+ set syn [lindex $optdesc 1]
+ if { ![info exists remove($syn)] } {
+ # original option is not removed
+ if { [info exists rename($syn)] } {
+ set classopt($option) [list Synonym $rename($syn)]
+ } else {
+ set classopt($option) [list Synonym $syn]
+ }
+ }
+ } else {
+ if { [info exists rename($option)] } {
+ set realopt $option
+ set option $rename($option)
+ } else {
+ set realopt $option
+ }
+ if { [info exists initialize($option)] } {
+ set value $initialize($option)
+ } else {
+ set value [lindex $optdesc 1]
+ }
+ if { [info exists readonly($option)] } {
+ set ro $readonly($option)
+ } else {
+ set ro 0
+ }
+ set classopt($option) \
+ [list TkResource $value $ro [list $tkwidget $realopt]]
+
+ # Add an option database entry for this option
+ set optionDbName ".[lindex [_configure_option $realopt ""] 0]"
+ if { ![string equal $subpath ":cmd"] } {
+ set optionDbName "$subpath$optionDbName"
+ }
+ option add *${class}$optionDbName $value widgetDefault
+ lappend exports($option) "$optionDbName"
+
+ # Store the forward and backward mappings for this
+ # option <-> realoption pair
+ lappend classmap($option) $subpath "" $realopt
+ set submap($realopt) $option
+ }
+ }
+ }
+ ::destroy $foo
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::bwinclude
+# Includes BWidget resources to BWidget widget.
+# class class name of the BWidget
+# subclass BWidget class to include
+# subpath subpath to configure
+# args additionnal args for included options
+# ----------------------------------------------------------------------------
+proc Widget::bwinclude { class subclass subpath args } {
+ foreach {cmd lopt} $args {
+ # cmd can be
+ # include options to include lopt = {opt ...}
+ # remove options to remove lopt = {opt ...}
+ # rename options to rename lopt = {opt newopt ...}
+ # prefix options to prefix lopt = {prefix opt opt ...}
+ # initialize set default value for options lopt = {opt value ...}
+ # readonly set readonly flag for options lopt = {opt flag ...}
+ switch -- $cmd {
+ remove {
+ foreach option $lopt {
+ set remove($option) 1
+ }
+ }
+ include {
+ foreach option $lopt {
+ set include($option) 1
+ }
+ }
+ prefix {
+ set prefix [lindex $lopt 0]
+ foreach option [lrange $lopt 1 end] {
+ set rename($option) "-$prefix[string range $option 1 end]"
+ }
+ }
+ rename -
+ readonly -
+ initialize {
+ array set $cmd $lopt
+ }
+ default {
+ return -code error "invalid argument \"$cmd\""
+ }
+ }
+ }
+
+ namespace eval $class {}
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::map classmap
+ upvar 0 ${class}::map$subpath submap
+ upvar 0 ${class}::optionExports exports
+ upvar 0 ${subclass}::opt subclassopt
+ upvar 0 ${subclass}::optionExports subexports
+
+ # create resources informations from BWidget resources
+ foreach {option optdesc} [array get subclassopt] {
+ set subOption $option
+ if { (![info exists include] || [info exists include($option)]) &&
+ ![info exists remove($option)] } {
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ # option is a synonym
+ set syn [lindex $optdesc 1]
+ if { ![info exists remove($syn)] } {
+ if { [info exists rename($syn)] } {
+ set classopt($option) [list Synonym $rename($syn)]
+ } else {
+ set classopt($option) [list Synonym $syn]
+ }
+ }
+ } else {
+ if { [info exists rename($option)] } {
+ set realopt $option
+ set option $rename($option)
+ } else {
+ set realopt $option
+ }
+ if { [info exists initialize($option)] } {
+ set value $initialize($option)
+ } else {
+ set value [lindex $optdesc 1]
+ }
+ if { [info exists readonly($option)] } {
+ set ro $readonly($option)
+ } else {
+ set ro [lindex $optdesc 2]
+ }
+ set classopt($option) \
+ [list $type $value $ro [lindex $optdesc 3]]
+
+ # Add an option database entry for this option
+ foreach optionDbName $subexports($subOption) {
+ if { ![string equal $subpath ":cmd"] } {
+ set optionDbName "$subpath$optionDbName"
+ }
+ # Only add the option db entry if we are overriding the
+ # normal widget default
+ if { [info exists initialize($option)] } {
+ option add *${class}$optionDbName $value \
+ widgetDefault
+ }
+ lappend exports($option) "$optionDbName"
+ }
+
+ # Store the forward and backward mappings for this
+ # option <-> realoption pair
+ lappend classmap($option) $subpath $subclass $realopt
+ set submap($realopt) $option
+ }
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::declare
+# Declares new options to BWidget class.
+# ----------------------------------------------------------------------------
+proc Widget::declare { class optlist } {
+ variable _optiontype
+
+ namespace eval $class {}
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::optionExports exports
+ upvar 0 ${class}::optionClass optionClass
+
+ foreach optdesc $optlist {
+ set option [lindex $optdesc 0]
+ set optdesc [lrange $optdesc 1 end]
+ set type [lindex $optdesc 0]
+
+ if { ![info exists _optiontype($type)] } {
+ # invalid resource type
+ return -code error "invalid option type \"$type\""
+ }
+
+ if { [string equal $type "Synonym"] } {
+ # test existence of synonym option
+ set syn [lindex $optdesc 1]
+ if { ![info exists classopt($syn)] } {
+ return -code error "unknow option \"$syn\" for Synonym \"$option\""
+ }
+ set classopt($option) [list Synonym $syn]
+ continue
+ }
+
+ # all other resource may have default value, readonly flag and
+ # optional arg depending on type
+ set value [lindex $optdesc 1]
+ set ro [lindex $optdesc 2]
+ set arg [lindex $optdesc 3]
+
+ if { [string equal $type "BwResource"] } {
+ # We don't keep BwResource. We simplify to type of sub BWidget
+ set subclass [lindex $arg 0]
+ set realopt [lindex $arg 1]
+ if { ![string length $realopt] } {
+ set realopt $option
+ }
+
+ upvar 0 ${subclass}::opt subclassopt
+ if { ![info exists subclassopt($realopt)] } {
+ return -code error "unknow option \"$realopt\""
+ }
+ set suboptdesc $subclassopt($realopt)
+ if { $value == "" } {
+ # We initialize default value
+ set value [lindex $suboptdesc 1]
+ }
+ set type [lindex $suboptdesc 0]
+ set ro [lindex $suboptdesc 2]
+ set arg [lindex $suboptdesc 3]
+ set optionDbName ".[lindex [_configure_option $option ""] 0]"
+ option add *${class}${optionDbName} $value widgetDefault
+ set exports($option) $optionDbName
+ set classopt($option) [list $type $value $ro $arg]
+ continue
+ }
+
+ # retreive default value for TkResource
+ if { [string equal $type "TkResource"] } {
+ set tkwidget [lindex $arg 0]
+ set foo [$tkwidget ".ericFoo##"]
+ set realopt [lindex $arg 1]
+ if { ![string length $realopt] } {
+ set realopt $option
+ }
+ set tkoptions [_get_tkwidget_options $tkwidget]
+ if { ![string length $value] } {
+ # We initialize default value
+ set ind [lsearch $tkoptions [list $realopt *]]
+ set value [lindex [lindex $tkoptions $ind] end]
+ }
+ set optionDbName ".[lindex [_configure_option $option ""] 0]"
+ option add *${class}${optionDbName} $value widgetDefault
+ set exports($option) $optionDbName
+ set classopt($option) [list TkResource $value $ro \
+ [list $tkwidget $realopt]]
+ set optionClass($option) [lindex [$foo configure $realopt] 1]
+ ::destroy $foo
+ continue
+ }
+
+ set optionDbName ".[lindex [_configure_option $option ""] 0]"
+ option add *${class}${optionDbName} $value widgetDefault
+ set exports($option) $optionDbName
+ # for any other resource type, we keep original optdesc
+ set classopt($option) [list $type $value $ro $arg]
+ }
+}
+
+
+proc Widget::define { class filename args } {
+ variable ::BWidget::use
+ set use($class) $args
+ set use($class,file) $filename
+ lappend use(classes) $class
+
+ if {[set x [lsearch -exact $args "-classonly"]] > -1} {
+ set args [lreplace $args $x $x]
+ } else {
+ interp alias {} ::${class} {} ${class}::create
+ proc ::${class}::use {} {}
+
+ bind $class <Destroy> [list Widget::destroy %W]
+ }
+
+ foreach class $args { ${class}::use }
+}
+
+
+proc Widget::create { class path {rename 1} } {
+ if {$rename} { rename $path ::$path:cmd }
+ proc ::$path { cmd args } \
+ [subst {return \[eval \[linsert \$args 0 ${class}::\$cmd [list $path]\]\]}]
+ return $path
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::addmap
+# ----------------------------------------------------------------------------
+proc Widget::addmap { class subclass subpath options } {
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::optionExports exports
+ upvar 0 ${class}::optionClass optionClass
+ upvar 0 ${class}::map classmap
+ upvar 0 ${class}::map$subpath submap
+
+ foreach {option realopt} $options {
+ if { ![string length $realopt] } {
+ set realopt $option
+ }
+ set val [lindex $classopt($option) 1]
+ set optDb ".[lindex [_configure_option $realopt ""] 0]"
+ if { ![string equal $subpath ":cmd"] } {
+ set optDb "$subpath$optDb"
+ }
+ option add *${class}${optDb} $val widgetDefault
+ lappend exports($option) $optDb
+ # Store the forward and backward mappings for this
+ # option <-> realoption pair
+ lappend classmap($option) $subpath $subclass $realopt
+ set submap($realopt) $option
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::syncoptions
+# ----------------------------------------------------------------------------
+proc Widget::syncoptions { class subclass subpath options } {
+ upvar 0 ${class}::sync classync
+
+ foreach {option realopt} $options {
+ if { ![string length $realopt] } {
+ set realopt $option
+ }
+ set classync($option) [list $subpath $subclass $realopt]
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::init
+# ----------------------------------------------------------------------------
+proc Widget::init { class path options } {
+ variable _inuse
+ variable _class
+ variable _optiontype
+
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::$path:opt pathopt
+ upvar 0 ${class}::$path:mod pathmod
+ upvar 0 ${class}::map classmap
+ upvar 0 ${class}::$path:init pathinit
+
+ if { [info exists pathopt] } {
+ unset pathopt
+ }
+ if { [info exists pathmod] } {
+ unset pathmod
+ }
+ # We prefer to use the actual widget for option db queries, but if it
+ # doesn't exist yet, do the next best thing: create a widget of the
+ # same class and use that.
+ set fpath $path
+ set rdbclass [string map [list :: ""] $class]
+ if { ![winfo exists $path] } {
+ set fpath ".#BWidget.#Class#$class"
+ # encapsulation frame to not pollute '.' childspace
+ if {![winfo exists ".#BWidget"]} { frame ".#BWidget" }
+ if { ![winfo exists $fpath] } {
+ frame $fpath -class $rdbclass
+ }
+ }
+ foreach {option optdesc} [array get classopt] {
+ set pathmod($option) 0
+ if { [info exists classmap($option)] } {
+ continue
+ }
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ continue
+ }
+ if { [string equal $type "TkResource"] } {
+ set alt [lindex [lindex $optdesc 3] 1]
+ } else {
+ set alt ""
+ }
+ set optdb [lindex [_configure_option $option $alt] 0]
+ set def [option get $fpath $optdb $rdbclass]
+ if { [string length $def] } {
+ set pathopt($option) $def
+ } else {
+ set pathopt($option) [lindex $optdesc 1]
+ }
+ }
+
+ if {![info exists _inuse($class)]} { set _inuse($class) 0 }
+ incr _inuse($class)
+
+ set _class($path) $class
+ foreach {option value} $options {
+ if { ![info exists classopt($option)] } {
+ unset pathopt
+ unset pathmod
+ return -code error "unknown option \"$option\""
+ }
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ set option [lindex $optdesc 1]
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ }
+ # this may fail if a wrong enum element was used
+ if {[catch {
+ $_optiontype($type) $option $value [lindex $optdesc 3]
+ } msg]} {
+ if {[info exists pathopt]} {
+ unset pathopt
+ }
+ unset pathmod
+ return -code error $msg
+ }
+ set pathopt($option) $msg
+ set pathinit($option) $pathopt($option)
+ }
+}
+
+# Bastien Chevreux (bach@mwgdna.com)
+#
+# copyinit performs basically the same job as init, but it uses a
+# existing template to initialize its values. So, first a perferct copy
+# from the template is made just to be altered by any existing options
+# afterwards.
+# But this still saves time as the first initialization parsing block is
+# skipped.
+# As additional bonus, items that differ in just a few options can be
+# initialized faster by leaving out the options that are equal.
+
+# This function is currently used only by ListBox::multipleinsert, but other
+# calls should follow :)
+
+# ----------------------------------------------------------------------------
+# Command Widget::copyinit
+# ----------------------------------------------------------------------------
+proc Widget::copyinit { class templatepath path options } {
+ variable _class
+ variable _optiontype
+ upvar 0 ${class}::opt classopt \
+ ${class}::$path:opt pathopt \
+ ${class}::$path:mod pathmod \
+ ${class}::$path:init pathinit \
+ ${class}::$templatepath:opt templatepathopt \
+ ${class}::$templatepath:mod templatepathmod \
+ ${class}::$templatepath:init templatepathinit
+
+ if { [info exists pathopt] } {
+ unset pathopt
+ }
+ if { [info exists pathmod] } {
+ unset pathmod
+ }
+
+ # We use the template widget for option db copying, but it has to exist!
+ array set pathmod [array get templatepathmod]
+ array set pathopt [array get templatepathopt]
+ array set pathinit [array get templatepathinit]
+
+ set _class($path) $class
+ foreach {option value} $options {
+ if { ![info exists classopt($option)] } {
+ unset pathopt
+ unset pathmod
+ return -code error "unknown option \"$option\""
+ }
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ set option [lindex $optdesc 1]
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ }
+ set pathopt($option) [$_optiontype($type) $option $value [lindex $optdesc 3]]
+ set pathinit($option) $pathopt($option)
+ }
+}
+
+# Widget::parseArgs --
+#
+# Given a widget class and a command-line spec, cannonize and validate
+# the given options, and return a keyed list consisting of the
+# component widget and its masked portion of the command-line spec, and
+# one extra entry consisting of the portion corresponding to the
+# megawidget itself.
+#
+# Arguments:
+# class widget class to parse for.
+# options command-line spec
+#
+# Results:
+# result keyed list of portions of the megawidget and that segment of
+# the command line in which that portion is interested.
+
+proc Widget::parseArgs {class options} {
+ variable _optiontype
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::map classmap
+
+ foreach {option val} $options {
+ if { ![info exists classopt($option)] } {
+ error "unknown option \"$option\""
+ }
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ set option [lindex $optdesc 1]
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ }
+ if { [string equal $type "TkResource"] } {
+ # Make sure that the widget used for this TkResource exists
+ Widget::_get_tkwidget_options [lindex [lindex $optdesc 3] 0]
+ }
+ set val [$_optiontype($type) $option $val [lindex $optdesc 3]]
+
+ if { [info exists classmap($option)] } {
+ foreach {subpath subclass realopt} $classmap($option) {
+ lappend maps($subpath) $realopt $val
+ }
+ } else {
+ lappend maps($class) $option $val
+ }
+ }
+ return [array get maps]
+}
+
+# Widget::initFromODB --
+#
+# Initialize a megawidgets options with information from the option
+# database and from the command-line arguments given.
+#
+# Arguments:
+# class class of the widget.
+# path path of the widget -- should already exist.
+# options command-line arguments.
+#
+# Results:
+# None.
+
+proc Widget::initFromODB {class path options} {
+ variable _inuse
+ variable _class
+
+ upvar 0 ${class}::$path:opt pathopt
+ upvar 0 ${class}::$path:mod pathmod
+ upvar 0 ${class}::map classmap
+
+ if { [info exists pathopt] } {
+ unset pathopt
+ }
+ if { [info exists pathmod] } {
+ unset pathmod
+ }
+ # We prefer to use the actual widget for option db queries, but if it
+ # doesn't exist yet, do the next best thing: create a widget of the
+ # same class and use that.
+ set fpath [_get_window $class $path]
+ set rdbclass [string map [list :: ""] $class]
+ if { ![winfo exists $path] } {
+ set fpath ".#BWidget.#Class#$class"
+ # encapsulation frame to not pollute '.' childspace
+ if {![winfo exists ".#BWidget"]} { frame ".#BWidget" }
+ if { ![winfo exists $fpath] } {
+ frame $fpath -class $rdbclass
+ }
+ }
+
+ foreach {option optdesc} [array get ${class}::opt] {
+ set pathmod($option) 0
+ if { [info exists classmap($option)] } {
+ continue
+ }
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ continue
+ }
+ if { [string equal $type "TkResource"] } {
+ set alt [lindex [lindex $optdesc 3] 1]
+ } else {
+ set alt ""
+ }
+ set optdb [lindex [_configure_option $option $alt] 0]
+ set def [option get $fpath $optdb $rdbclass]
+ if { [string length $def] } {
+ set pathopt($option) $def
+ } else {
+ set pathopt($option) [lindex $optdesc 1]
+ }
+ }
+
+ if {![info exists _inuse($class)]} { set _inuse($class) 0 }
+ incr _inuse($class)
+
+ set _class($path) $class
+ array set pathopt $options
+}
+
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::destroy
+# ----------------------------------------------------------------------------
+proc Widget::destroy { path } {
+ variable _class
+ variable _inuse
+
+ if {![info exists _class($path)]} { return }
+
+ set class $_class($path)
+ upvar 0 ${class}::$path:opt pathopt
+ upvar 0 ${class}::$path:mod pathmod
+ upvar 0 ${class}::$path:init pathinit
+
+ if {[info exists _inuse($class)]} { incr _inuse($class) -1 }
+
+ if {[info exists pathopt]} {
+ unset pathopt
+ }
+ if {[info exists pathmod]} {
+ unset pathmod
+ }
+ if {[info exists pathinit]} {
+ unset pathinit
+ }
+
+ if {![string equal [info commands $path] ""]} { rename $path "" }
+
+ ## Unset any variables used in this widget.
+ foreach var [info vars ::${class}::$path:*] { unset $var }
+
+ unset _class($path)
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::configure
+# ----------------------------------------------------------------------------
+proc Widget::configure { path options } {
+ set len [llength $options]
+ if { $len <= 1 } {
+ return [_get_configure $path $options]
+ } elseif { $len % 2 == 1 } {
+ return -code error "incorrect number of arguments"
+ }
+
+ variable _class
+ variable _optiontype
+
+ set class $_class($path)
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::map classmap
+ upvar 0 ${class}::$path:opt pathopt
+ upvar 0 ${class}::$path:mod pathmod
+
+ set window [_get_window $class $path]
+ foreach {option value} $options {
+ if { ![info exists classopt($option)] } {
+ return -code error "unknown option \"$option\""
+ }
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ set option [lindex $optdesc 1]
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ }
+ if { ![lindex $optdesc 2] } {
+ set newval [$_optiontype($type) $option $value [lindex $optdesc 3]]
+ if { [info exists classmap($option)] } {
+ set window [_get_window $class $window]
+ foreach {subpath subclass realopt} $classmap($option) {
+ # Interpretation of special pointers:
+ # | subclass | subpath | widget | path | class |
+ # +----------+---------+------------------+----------------+-context-+
+ # | :cmd | :cmd | herited widget | window:cmd |window |
+ # | :cmd | * | subwidget | window.subpath | window |
+ # | "" | :cmd | herited widget | window:cmd | window |
+ # | "" | * | own | window | window |
+ # | * | :cmd | own | window | current |
+ # | * | * | subwidget | window.subpath | current |
+ if { [string length $subclass] && ! [string equal $subclass ":cmd"] } {
+ if { [string equal $subpath ":cmd"] } {
+ set subpath ""
+ }
+ set curval [${subclass}::cget $window$subpath $realopt]
+ ${subclass}::configure $window$subpath $realopt $newval
+ } else {
+ set curval [$window$subpath cget $realopt]
+ $window$subpath configure $realopt $newval
+ }
+ }
+ } else {
+ set curval $pathopt($option)
+ set pathopt($option) $newval
+ }
+ set pathmod($option) [expr {![string equal $newval $curval]}]
+ }
+ }
+
+ return {}
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::cget
+# ----------------------------------------------------------------------------
+proc Widget::cget { path option } {
+ variable _class
+ if { ![info exists _class($path)] } {
+ return -code error "unknown widget $path"
+ }
+
+ set class $_class($path)
+ if { ![info exists ${class}::opt($option)] } {
+ return -code error "unknown option \"$option\""
+ }
+
+ set optdesc [set ${class}::opt($option)]
+ set type [lindex $optdesc 0]
+ if {[string equal $type "Synonym"]} {
+ set option [lindex $optdesc 1]
+ }
+
+ if { [info exists ${class}::map($option)] } {
+ foreach {subpath subclass realopt} [set ${class}::map($option)] {break}
+ set path "[_get_window $class $path]$subpath"
+ return [$path cget $realopt]
+ }
+ upvar 0 ${class}::$path:opt pathopt
+ set pathopt($option)
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::subcget
+# ----------------------------------------------------------------------------
+proc Widget::subcget { path subwidget } {
+ variable _class
+ set class $_class($path)
+ upvar 0 ${class}::$path:opt pathopt
+ upvar 0 ${class}::map$subwidget submap
+ upvar 0 ${class}::$path:init pathinit
+
+ set result {}
+ foreach realopt [array names submap] {
+ if { [info exists pathinit($submap($realopt))] } {
+ lappend result $realopt $pathopt($submap($realopt))
+ }
+ }
+ return $result
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::hasChanged
+# ----------------------------------------------------------------------------
+proc Widget::hasChanged { path option pvalue } {
+ variable _class
+ upvar $pvalue value
+ set class $_class($path)
+ upvar 0 ${class}::$path:mod pathmod
+
+ set value [Widget::cget $path $option]
+ set result $pathmod($option)
+ set pathmod($option) 0
+
+ return $result
+}
+
+proc Widget::hasChangedX { path option args } {
+ variable _class
+ set class $_class($path)
+ upvar 0 ${class}::$path:mod pathmod
+
+ set result $pathmod($option)
+ set pathmod($option) 0
+ foreach option $args {
+ lappend result $pathmod($option)
+ set pathmod($option) 0
+ }
+
+ set result
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::setoption
+# ----------------------------------------------------------------------------
+proc Widget::setoption { path option value } {
+# variable _class
+
+# set class $_class($path)
+# upvar 0 ${class}::$path:opt pathopt
+
+# set pathopt($option) $value
+ Widget::configure $path [list $option $value]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::getoption
+# ----------------------------------------------------------------------------
+proc Widget::getoption { path option } {
+# set class $::Widget::_class($path)
+# upvar 0 ${class}::$path:opt pathopt
+
+# return $pathopt($option)
+ return [Widget::cget $path $option]
+}
+
+# Widget::getMegawidgetOption --
+#
+# Bypass the superfluous checks in cget and just directly peer at the
+# widget's data space. This is much more fragile than cget, so it
+# should only be used with great care, in places where speed is critical.
+#
+# Arguments:
+# path widget to lookup options for.
+# option option to retrieve.
+#
+# Results:
+# value option value.
+
+proc Widget::getMegawidgetOption {path option} {
+ variable _class
+ set class $_class($path)
+ upvar 0 ${class}::${path}:opt pathopt
+ set pathopt($option)
+}
+
+# Widget::setMegawidgetOption --
+#
+# Bypass the superfluous checks in cget and just directly poke at the
+# widget's data space. This is much more fragile than configure, so it
+# should only be used with great care, in places where speed is critical.
+#
+# Arguments:
+# path widget to lookup options for.
+# option option to retrieve.
+# value option value.
+#
+# Results:
+# value option value.
+
+proc Widget::setMegawidgetOption {path option value} {
+ variable _class
+ set class $_class($path)
+ upvar 0 ${class}::${path}:opt pathopt
+ set pathopt($option) $value
+}
+
+# ----------------------------------------------------------------------------
+# Command Widget::_get_window
+# returns the window corresponding to widget path
+# ----------------------------------------------------------------------------
+proc Widget::_get_window { class path } {
+ set idx [string last "#" $path]
+ if { $idx != -1 && [string equal [string range $path [expr {$idx+1}] end] $class] } {
+ return [string range $path 0 [expr {$idx-1}]]
+ } else {
+ return $path
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_get_configure
+# returns the configuration list of options
+# (as tk widget do - [$w configure ?option?])
+# ----------------------------------------------------------------------------
+proc Widget::_get_configure { path options } {
+ variable _class
+
+ set class $_class($path)
+ upvar 0 ${class}::opt classopt
+ upvar 0 ${class}::map classmap
+ upvar 0 ${class}::$path:opt pathopt
+ upvar 0 ${class}::$path:mod pathmod
+
+ set len [llength $options]
+ if { !$len } {
+ set result {}
+ foreach option [lsort [array names classopt]] {
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ set syn $option
+ set option [lindex $optdesc 1]
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ } else {
+ set syn ""
+ }
+ if { [string equal $type "TkResource"] } {
+ set alt [lindex [lindex $optdesc 3] 1]
+ } else {
+ set alt ""
+ }
+ set res [_configure_option $option $alt]
+ if { $syn == "" } {
+ lappend result [concat $option $res [list [lindex $optdesc 1]] [list [cget $path $option]]]
+ } else {
+ lappend result [list $syn [lindex $res 0]]
+ }
+ }
+ return $result
+ } elseif { $len == 1 } {
+ set option [lindex $options 0]
+ if { ![info exists classopt($option)] } {
+ return -code error "unknown option \"$option\""
+ }
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ if { [string equal $type "Synonym"] } {
+ set option [lindex $optdesc 1]
+ set optdesc $classopt($option)
+ set type [lindex $optdesc 0]
+ }
+ if { [string equal $type "TkResource"] } {
+ set alt [lindex [lindex $optdesc 3] 1]
+ } else {
+ set alt ""
+ }
+ set res [_configure_option $option $alt]
+ return [concat $option $res [list [lindex $optdesc 1]] [list [cget $path $option]]]
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_configure_option
+# ----------------------------------------------------------------------------
+proc Widget::_configure_option { option altopt } {
+ variable _optiondb
+ variable _optionclass
+
+ if { [info exists _optiondb($option)] } {
+ set optdb $_optiondb($option)
+ } else {
+ set optdb [string range $option 1 end]
+ }
+ if { [info exists _optionclass($option)] } {
+ set optclass $_optionclass($option)
+ } elseif { [string length $altopt] } {
+ if { [info exists _optionclass($altopt)] } {
+ set optclass $_optionclass($altopt)
+ } else {
+ set optclass [string range $altopt 1 end]
+ }
+ } else {
+ set optclass [string range $option 1 end]
+ }
+ return [list $optdb $optclass]
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_get_tkwidget_options
+# ----------------------------------------------------------------------------
+proc Widget::_get_tkwidget_options { tkwidget } {
+ variable _tk_widget
+ variable _optiondb
+ variable _optionclass
+
+ set widget ".#BWidget.#$tkwidget"
+ # encapsulation frame to not pollute '.' childspace
+ if {![winfo exists ".#BWidget"]} { frame ".#BWidget" }
+ if { ![winfo exists $widget] || ![info exists _tk_widget($tkwidget)] } {
+ set widget [$tkwidget $widget]
+ # JDC: Withdraw toplevels, otherwise visible
+ if {[string equal $tkwidget "toplevel"]} {
+ wm withdraw $widget
+ }
+ set config [$widget configure]
+ foreach optlist $config {
+ set opt [lindex $optlist 0]
+ if { [llength $optlist] == 2 } {
+ set refsyn [lindex $optlist 1]
+ # search for class
+ set idx [lsearch $config [list * $refsyn *]]
+ if { $idx == -1 } {
+ if { [string index $refsyn 0] == "-" } {
+ # search for option (tk8.1b1 bug)
+ set idx [lsearch $config [list $refsyn * *]]
+ } else {
+ # last resort
+ set idx [lsearch $config [list -[string tolower $refsyn] * *]]
+ }
+ if { $idx == -1 } {
+ # fed up with "can't read classopt()"
+ return -code error "can't find option of synonym $opt"
+ }
+ }
+ set syn [lindex [lindex $config $idx] 0]
+ # JDC: used 4 (was 3) to get def from optiondb
+ set def [lindex [lindex $config $idx] 4]
+ lappend _tk_widget($tkwidget) [list $opt $syn $def]
+ } else {
+ # JDC: used 4 (was 3) to get def from optiondb
+ set def [lindex $optlist 4]
+ lappend _tk_widget($tkwidget) [list $opt $def]
+ set _optiondb($opt) [lindex $optlist 1]
+ set _optionclass($opt) [lindex $optlist 2]
+ }
+ }
+ }
+ return $_tk_widget($tkwidget)
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_test_tkresource
+# ----------------------------------------------------------------------------
+proc Widget::_test_tkresource { option value arg } {
+# set tkwidget [lindex $arg 0]
+# set realopt [lindex $arg 1]
+ foreach {tkwidget realopt} $arg break
+ set path ".#BWidget.#$tkwidget"
+ set old [$path cget $realopt]
+ $path configure $realopt $value
+ set res [$path cget $realopt]
+ $path configure $realopt $old
+
+ return $res
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_test_bwresource
+# ----------------------------------------------------------------------------
+proc Widget::_test_bwresource { option value arg } {
+ return -code error "bad option type BwResource in widget"
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_test_synonym
+# ----------------------------------------------------------------------------
+proc Widget::_test_synonym { option value arg } {
+ return -code error "bad option type Synonym in widget"
+}
+
+# ----------------------------------------------------------------------------
+# Command Widget::_test_color
+# ----------------------------------------------------------------------------
+proc Widget::_test_color { option value arg } {
+ if {[catch {winfo rgb . $value} color]} {
+ return -code error "bad $option value \"$value\": must be a colorname \
+ or #RRGGBB triplet"
+ }
+
+ return $value
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_test_string
+# ----------------------------------------------------------------------------
+proc Widget::_test_string { option value arg } {
+ set value
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::_test_flag
+# ----------------------------------------------------------------------------
+proc Widget::_test_flag { option value arg } {
+ set len [string length $value]
+ set res ""
+ for {set i 0} {$i < $len} {incr i} {
+ set c [string index $value $i]
+ if { [string first $c $arg] == -1 } {
+ return -code error "bad [string range $option 1 end] value \"$value\": characters must be in \"$arg\""
+ }
+ if { [string first $c $res] == -1 } {
+ append res $c
+ }
+ }
+ return $res
+}
+
+
+# -----------------------------------------------------------------------------
+# Command Widget::_test_enum
+# -----------------------------------------------------------------------------
+proc Widget::_test_enum { option value arg } {
+ if { [lsearch $arg $value] == -1 } {
+ set last [lindex $arg end]
+ set sub [lreplace $arg end end]
+ if { [llength $sub] } {
+ set str "[join $sub ", "] or $last"
+ } else {
+ set str $last
+ }
+ return -code error "bad [string range $option 1 end] value \"$value\": must be $str"
+ }
+ return $value
+}
+
+
+# -----------------------------------------------------------------------------
+# Command Widget::_test_int
+# -----------------------------------------------------------------------------
+proc Widget::_test_int { option value arg } {
+ if { ![string is int -strict $value] || \
+ ([string length $arg] && \
+ ![expr [string map [list %d $value] $arg]]) } {
+ return -code error "bad $option value\
+ \"$value\": must be integer ($arg)"
+ }
+ return $value
+}
+
+
+# -----------------------------------------------------------------------------
+# Command Widget::_test_boolean
+# -----------------------------------------------------------------------------
+proc Widget::_test_boolean { option value arg } {
+ if { ![string is boolean -strict $value] } {
+ return -code error "bad $option value \"$value\": must be boolean"
+ }
+
+ # Get the canonical form of the boolean value (1 for true, 0 for false)
+ return [string is true $value]
+}
+
+
+# -----------------------------------------------------------------------------
+# Command Widget::_test_padding
+# -----------------------------------------------------------------------------
+proc Widget::_test_padding { option values arg } {
+ set len [llength $values]
+ if {$len < 1 || $len > 2} {
+ return -code error "bad pad value \"$values\":\
+ must be positive screen distance"
+ }
+
+ foreach value $values {
+ if { ![string is int -strict $value] || \
+ ([string length $arg] && \
+ ![expr [string map [list %d $value] $arg]]) } {
+ return -code error "bad pad value \"$value\":\
+ must be positive screen distance ($arg)"
+ }
+ }
+ return $values
+}
+
+
+# Widget::_get_padding --
+#
+# Return the requesting padding value for a padding option.
+#
+# Arguments:
+# path Widget to get the options for.
+# option The name of the padding option.
+# index The index of the padding. If the index is empty,
+# the first padding value is returned.
+#
+# Results:
+# Return a numeric value that can be used for padding.
+proc Widget::_get_padding { path option {index 0} } {
+ set pad [Widget::cget $path $option]
+ set val [lindex $pad $index]
+ if {$val == ""} { set val [lindex $pad 0] }
+ return $val
+}
+
+
+# -----------------------------------------------------------------------------
+# Command Widget::focusNext
+# Same as tk_focusNext, but call Widget::focusOK
+# -----------------------------------------------------------------------------
+proc Widget::focusNext { w } {
+ set cur $w
+ while 1 {
+
+ # Descend to just before the first child of the current widget.
+
+ set parent $cur
+ set children [winfo children $cur]
+ set i -1
+
+ # Look for the next sibling that isn't a top-level.
+
+ while 1 {
+ incr i
+ if {$i < [llength $children]} {
+ set cur [lindex $children $i]
+ if {[string equal [winfo toplevel $cur] $cur]} {
+ continue
+ } else {
+ break
+ }
+ }
+
+ # No more siblings, so go to the current widget's parent.
+ # If it's a top-level, break out of the loop, otherwise
+ # look for its next sibling.
+
+ set cur $parent
+ if {[string equal [winfo toplevel $cur] $cur]} {
+ break
+ }
+ set parent [winfo parent $parent]
+ set children [winfo children $parent]
+ set i [lsearch -exact $children $cur]
+ }
+ if {[string equal $cur $w] || [focusOK $cur]} {
+ return $cur
+ }
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Command Widget::focusPrev
+# Same as tk_focusPrev, except:
+# + Don't traverse from a child to a direct ancestor
+# + Call Widget::focusOK instead of tk::focusOK
+# -----------------------------------------------------------------------------
+proc Widget::focusPrev { w } {
+ set cur $w
+ set origParent [winfo parent $w]
+ while 1 {
+
+ # Collect information about the current window's position
+ # among its siblings. Also, if the window is a top-level,
+ # then reposition to just after the last child of the window.
+
+ if {[string equal [winfo toplevel $cur] $cur]} {
+ set parent $cur
+ set children [winfo children $cur]
+ set i [llength $children]
+ } else {
+ set parent [winfo parent $cur]
+ set children [winfo children $parent]
+ set i [lsearch -exact $children $cur]
+ }
+
+ # Go to the previous sibling, then descend to its last descendant
+ # (highest in stacking order. While doing this, ignore top-levels
+ # and their descendants. When we run out of descendants, go up
+ # one level to the parent.
+
+ while {$i > 0} {
+ incr i -1
+ set cur [lindex $children $i]
+ if {[string equal [winfo toplevel $cur] $cur]} {
+ continue
+ }
+ set parent $cur
+ set children [winfo children $parent]
+ set i [llength $children]
+ }
+ set cur $parent
+ if {[string equal $cur $w]} {
+ return $cur
+ }
+ # If we are just at the original parent of $w, skip it as a
+ # potential focus accepter. Extra safety in this is to see if
+ # that parent is also a proc (not a C command), which is what
+ # BWidgets makes for any megawidget. Could possibly also check
+ # for '[info commands ::${origParent}:cmd] != ""'. [Bug 765667]
+ if {[string equal $cur $origParent]
+ && [info procs ::$origParent] != ""} {
+ continue
+ }
+ if {[focusOK $cur]} {
+ return $cur
+ }
+ }
+}
+
+
+# ----------------------------------------------------------------------------
+# Command Widget::focusOK
+# Same as tk_focusOK, but handles -editable option and whole tags list.
+# ----------------------------------------------------------------------------
+proc Widget::focusOK { w } {
+ set code [catch {$w cget -takefocus} value]
+ if { $code == 1 } {
+ return 0
+ }
+ if {($code == 0) && ($value != "")} {
+ if {$value == 0} {
+ return 0
+ } elseif {$value == 1} {
+ return [winfo viewable $w]
+ } else {
+ set value [uplevel \#0 $value $w]
+ if {$value != ""} {
+ return $value
+ }
+ }
+ }
+ if {![winfo viewable $w]} {
+ return 0
+ }
+ set code [catch {$w cget -state} value]
+ if {($code == 0) && ($value == "disabled")} {
+ return 0
+ }
+ set code [catch {$w cget -editable} value]
+ if {($code == 0) && ($value == 0)} {
+ return 0
+ }
+
+ set top [winfo toplevel $w]
+ foreach tags [bindtags $w] {
+ if { ![string equal $tags $top] &&
+ ![string equal $tags "all"] &&
+ [regexp Key [bind $tags]] } {
+ return 1
+ }
+ }
+ return 0
+}
+
+
+proc Widget::traverseTo { w } {
+ set focus [focus]
+ if {![string equal $focus ""]} {
+ event generate $focus <<TraverseOut>>
+ }
+ focus $w
+
+ event generate $w <<TraverseIn>>
+}
+
+
+# Widget::varForOption --
+#
+# Retrieve a fully qualified variable name for the option specified.
+# If the option is not one for which a variable exists, throw an error
+# (ie, those options that map directly to widget options).
+#
+# Arguments:
+# path megawidget to get an option var for.
+# option option to get a var for.
+#
+# Results:
+# varname name of the variable, fully qualified, suitable for tracing.
+
+proc Widget::varForOption {path option} {
+ variable _class
+ variable _optiontype
+
+ set class $_class($path)
+ upvar 0 ${class}::$path:opt pathopt
+
+ if { ![info exists pathopt($option)] } {
+ error "unable to find variable for option \"$option\""
+ }
+ set varname "::Widget::${class}::$path:opt($option)"
+ return $varname
+}
+
+# Widget::getVariable --
+#
+# Get a variable from within the namespace of the widget.
+#
+# Arguments:
+# path Megawidget to get the variable for.
+# varName The variable name to retrieve.
+# newVarName The variable name to refer to in the calling proc.
+#
+# Results:
+# Creates a reference to newVarName in the calling proc.
+proc Widget::getVariable { path varName {newVarName ""} } {
+ variable _class
+ set class $_class($path)
+ if {![string length $newVarName]} { set newVarName $varName }
+ uplevel 1 [list upvar \#0 ${class}::$path:$varName $newVarName]
+}
+
+# Widget::options --
+#
+# Return a key-value list of options for a widget. This can
+# be used to serialize the options of a widget and pass them
+# on to a new widget with the same options.
+#
+# Arguments:
+# path Widget to get the options for.
+# args A list of options. If empty, all options are returned.
+#
+# Results:
+# Returns list of options as: -option value -option value ...
+proc Widget::options { path args } {
+ if {[llength $args]} {
+ foreach option $args {
+ lappend options [_get_configure $path $option]
+ }
+ } else {
+ set options [_get_configure $path {}]
+ }
+
+ set result [list]
+ foreach list $options {
+ if {[llength $list] < 5} { continue }
+ lappend result [lindex $list 0] [lindex $list end]
+ }
+ return $result
+}
+
+
+# Widget::getOption --
+#
+# Given a list of widgets, determine which option value to use.
+# The widgets are given to the command in order of highest to
+# lowest. Starting with the lowest widget, whichever one does
+# not match the default option value is returned as the value.
+# If all the widgets are default, we return the highest widget's
+# value.
+#
+# Arguments:
+# option The option to check.
+# default The default value. If any widget in the list
+# does not match this default, its value is used.
+# args A list of widgets.
+#
+# Results:
+# Returns the value of the given option to use.
+#
+proc Widget::getOption { option default args } {
+ for {set i [expr [llength $args] -1]} {$i >= 0} {incr i -1} {
+ set widget [lindex $args $i]
+ set value [Widget::cget $widget $option]
+ if {[string equal $value $default]} { continue }
+ return $value
+ }
+ return $value
+}
+
+
+proc Widget::nextIndex { path node } {
+ Widget::getVariable $path autoIndex
+ if {![info exists autoIndex]} { set autoIndex -1 }
+ return [string map [list #auto [incr autoIndex]] $node]
+}
+
+
+proc Widget::exists { path } {
+ variable _class
+ return [info exists _class($path)]
+}
+
+proc Widget::theme {{bool {}}} {
+ # Private, *experimental* API that may change at any time - JH
+ variable _theme
+ if {[llength [info level 0]] == 2} {
+ # set theme-ability
+ if {[catch {package require Tk 8.5a6}]
+ && [catch {package require tile 0.6}]
+ && [catch {package require tile 1}]} {
+ return -code error "BWidget's theming requires tile 0.6+"
+ } else {
+ catch {style default BWSlim.Toolbutton -padding 0}
+ }
+ set _theme [string is true -strict $bool]
+ }
+ return $_theme
+}
diff --git a/modules/tclsci/tcl/BWidget/wizard.tcl b/modules/tclsci/tcl/BWidget/wizard.tcl
new file mode 100755
index 000000000..b2fe80d90
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/wizard.tcl
@@ -0,0 +1,1028 @@
+# ------------------------------------------------------------------------------
+# wizard.tcl
+#
+# ------------------------------------------------------------------------------
+# Index of commands:
+#
+# Public commands
+# - Wizard::create
+# - Wizard::configure
+# - Wizard::cget
+#
+# Private commands (event bindings)
+# - Wizard::_destroy
+# ------------------------------------------------------------------------------
+
+namespace eval Wizard {
+ Widget::define Wizard wizard ButtonBox Separator PagesManager
+
+ namespace eval Step {
+ Widget::declare Wizard::Step {
+ {-type String "step" 1 }
+ {-data String "" 0 }
+ {-title String "" 0 }
+ {-default String "next" 0 }
+ {-text1 String "" 0 }
+ {-text2 String "" 0 }
+ {-text3 String "" 0 }
+ {-text4 String "" 0 }
+ {-text5 String "" 0 }
+ {-icon String "" 0 }
+ {-image String "" 0 }
+ {-bitmap String "" 0 }
+ {-iconbitmap String "" 0 }
+
+ {-create Boolean "0" 1 }
+ {-appendorder Boolean "1" 0 }
+
+ {-nexttext String "Next >" 0 }
+ {-backtext String "< Back" 0 }
+ {-helptext String "Help" 0 }
+ {-canceltext String "Cancel" 0 }
+ {-finishtext String "Finish" 0 }
+ {-separatortext String "" 0 }
+
+ {-createcommand String "" 0 }
+ {-raisecommand String "" 0 }
+ {-nextcommand String "" 0 }
+ {-backcommand String "" 0 }
+ {-helpcommand String "" 0 }
+ {-cancelcommand String "" 0 }
+ {-finishcommand String "" 0 }
+
+ }
+ }
+
+ namespace eval Branch {
+ Widget::declare Wizard::Branch {
+ {-type String "branch" 1 }
+ {-command String "" 0 }
+ {-action Enum "merge" 0 {merge terminate} }
+ }
+ }
+
+ namespace eval Widget {
+ Widget::declare Wizard::Widget {
+ {-type String "widget" 1 }
+ {-step String "" 1 }
+ {-widget String "" 1 }
+ }
+ }
+
+ namespace eval layout {}
+
+ Widget::tkinclude Wizard frame :cmd \
+ include { -width -height -background -foreground -cursor }
+
+ Widget::declare Wizard {
+ {-type Enum "dialog" 1 {dialog frame} }
+ {-width TkResource "450" 0 frame}
+ {-height TkResource "300" 0 frame}
+ {-relief TkResource "flat" 0 frame}
+ {-borderwidth TkResource "0" 0 frame}
+ {-background TkResource "" 0 frame}
+ {-foreground String "black" 0 }
+ {-title String "Wizard" 0 }
+
+ {-autobuttons Boolean "1" 0 }
+ {-helpbutton Boolean "0" 1 }
+ {-finishbutton Boolean "0" 1 }
+ {-resizable String "0 0" 0 }
+ {-separator Boolean "1" 1 }
+ {-parent String "." 1 }
+ {-transient Boolean "1" 1 }
+ {-place Enum "center" 1
+ {none center left right above below}}
+
+ {-icon String "" 0 }
+ {-image String "" 0 }
+ {-bitmap String "" 0 }
+ {-iconbitmap String "" 0 }
+ {-raisecommand String "" 0 }
+ {-createcommand String "" 0 }
+ {-separatortext String "" 0 }
+
+ {-fg Synonym -foreground }
+ {-bg Synonym -background }
+ {-bd Synonym -borderwidth }
+ }
+
+ image create photo Wizard::none
+
+ Widget::addmap Wizard "" :cmd { -background {} -relief {} -borderwidth {} }
+
+ Widget::addmap Wizard "" .steps { -width {} -height {} }
+
+ bind Wizard <Destroy> [list Wizard::_destroy %W]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Wizard::create
+# ------------------------------------------------------------------------------
+proc Wizard::create { path args } {
+ array set maps [list Wizard {} :cmd {}]
+ array set maps [Widget::parseArgs Wizard $args]
+
+ Widget::initFromODB Wizard $path $maps(Wizard)
+
+ Widget::getVariable $path data
+ Widget::getVariable $path branches
+
+ array set data {
+ steps ""
+ buttons ""
+ order ""
+ current ""
+ }
+
+ array set branches {
+ root ""
+ }
+
+ set frame $path
+
+ set type [Widget::cget $path -type]
+
+ if {[string equal $type "dialog"]} {
+ set top $path
+ eval [list toplevel $path] $maps(:cmd) -class Wizard
+ wm withdraw $path
+ wm protocol $path WM_DELETE_WINDOW [list $path cancel]
+ if {[Widget::cget $path -transient]} {
+ wm transient $path [Widget::cget $path -parent]
+ }
+ eval wm resizable $path [Widget::cget $path -resizable]
+
+ bind $path <Escape> [list $path cancel]
+ bind $path <<WizardFinish>> [list destroy $path]
+ bind $path <<WizardCancel>> [list destroy $path]
+ } else {
+ set top [winfo toplevel $path]
+ eval [list frame $path] $maps(:cmd) -class Wizard
+ }
+
+ wm title $top [Widget::cget $path -title]
+
+ PagesManager $path.steps
+ pack $path.steps -expand 1 -fill both
+
+ widgets $path set steps -widget $path.steps
+
+ if {[Widget::cget $path -separator]} {
+ frame $path.separator
+ pack $path.separator -fill x
+
+ label $path.separator.l -text [Widget::cget $path -separatortext]
+ pack $path.separator.l -side left
+
+ Separator $path.separator.s -orient horizontal
+ pack $path.separator.s -side left -expand 1 -fill x -pady 2
+
+ widgets $path set separator -widget $path.separator.s
+ widgets $path set separatortext -widget $path.separator.l
+ widgets $path set separatorframe -widget $path.separator
+ }
+
+ ButtonBox $path.buttons -spacing 2 -homogeneous 1
+ pack $path.buttons -anchor se -padx 10 -pady 5
+
+ widgets $path set buttons -widget $path.buttons
+
+ insert $path button end back -text "< Back" -command "$path back" -width 12
+ insert $path button end next -text "Next >" -command "$path next"
+ if {[Widget::cget $path -finishbutton]} {
+ insert $path button end finish -text "Finish" -command "$path finish"
+ }
+ insert $path button end cancel -text "Cancel" -command "$path cancel"
+
+ if {[Widget::cget $path -helpbutton]} {
+ $path.buttons configure -spacing 10
+ insert $path button 0 help -text "Help" -command "$path help"
+ $path.buttons configure -spacing 2
+ }
+
+ return [Widget::create Wizard $path]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Wizard::configure
+# ------------------------------------------------------------------------------
+proc Wizard::configure { path args } {
+ set res [Widget::configure $path $args]
+
+ if {[Widget::hasChanged $path -title title]} {
+ wm title [winfo toplevel $path] $title
+ }
+
+ if {[Widget::hasChanged $path -resizable resize]} {
+ eval wm resizable [winfo toplevel $path] $resize
+ }
+
+ return $res
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Wizard::cget
+# ------------------------------------------------------------------------------
+proc Wizard::cget { path option } {
+ return [Widget::cget $path $option]
+}
+
+
+proc Wizard::itemcget { path item option } {
+ Widget::getVariable $path items
+ Widget::getVariable $path steps
+ Widget::getVariable $path buttons
+ Widget::getVariable $path widgets
+
+ if {![exists $path $item]} {
+ ## It's not an item. Just pass the configure to the widget.
+ set item [$path widgets get $item]
+ return [eval $item configure $args]
+ }
+
+ if {[_is_step $path $item]} {
+ ## It's a step
+ return [Widget::cget $items($item) $option]
+ }
+
+ if {[_is_branch $path $item]} {
+ ## It's a branch
+ return [Widget::cget $items($item) $option]
+ }
+
+ if {[info exists buttons($item)]} {
+ ## It's a button
+ return [$path.buttons itemcget $items($item) $option]
+ }
+
+ return -code error "item \"$item\" does not exist"
+}
+
+
+proc Wizard::itemconfigure { path item args } {
+ Widget::getVariable $path items
+ Widget::getVariable $path steps
+ Widget::getVariable $path buttons
+ Widget::getVariable $path widgets
+
+ if {![exists $path $item]} {
+ ## It's not an item. Just pass the configure to the widget.
+ set item [$path widgets get $item]
+ return [eval $item configure $args]
+ }
+
+ if {[info exists steps($item)]} {
+ ## It's a step.
+ set res [Widget::configure $items($item) $args]
+
+ if {$item == [$path step current]} {
+ if {[Widget::hasChanged $items($item) -title title]} {
+ wm title [winfo toplevel $path] $title
+ }
+ }
+
+ return $res
+ }
+
+ if {[_is_branch $path $item]} {
+ ## It's a branch
+ return [Widget::configure $items($item) $args]
+ }
+
+ if {[info exists buttons($item)]} {
+ ## It's a button.
+ return [eval $path.buttons itemconfigure [list $items($item)] $args]
+ }
+
+ return -code error "item \"$item\" does not exist"
+}
+
+
+proc Wizard::show { path } {
+ wm deiconify [winfo toplevel $path]
+}
+
+
+proc Wizard::invoke { path button } {
+ Widget::getVariable $path buttons
+ if {![info exists buttons($button)]} {
+ return -code error "button \"$button\" does not exist"
+ }
+ [$path widgets get $button] invoke
+}
+
+
+proc Wizard::insert { path type idx args } {
+ Widget::getVariable $path items
+ Widget::getVariable $path widgets
+ Widget::getVariable $path branches
+
+ switch -- $type {
+ "button" {
+ set node [lindex $args 0]
+ }
+
+ "step" - "branch" {
+ set node [lindex $args 1]
+ set branch [lindex $args 0]
+
+ if {![info exists branches($branch)]} {
+ return -code error "branch \"$branch\" does not exist"
+ }
+ }
+
+ default {
+ set types [list button branch step]
+ set err [BWidget::badOptionString option $type $types]
+ return -code error $err
+ }
+ }
+
+ if {[exists $path $node]} {
+ return -code error "item \"$node\" already exists"
+ }
+
+ eval _insert_$type $path $idx $args
+}
+
+
+proc Wizard::back { path } {
+ Widget::getVariable $path data
+ Widget::getVariable $path items
+ set step [$path raise]
+ if {![string equal $step ""]} {
+ set cmd [Widget::cget $items($step) -backcommand]
+ if {![string equal $cmd ""]} {
+ set res [uplevel #0 $cmd]
+ if {!$res} { return }
+ }
+ }
+
+ set data(order) [lreplace $data(order) end end]
+ set item [lindex $data(order) end]
+
+ $path raise $item
+
+ event generate $path <<WizardStep>>
+ event generate $path <<WizardBack>>
+
+ return $item
+}
+
+
+proc Wizard::next { path } {
+ Widget::getVariable $path data
+ Widget::getVariable $path items
+
+ set step [$path raise]
+ if {![string equal $step ""]} {
+ set cmd [Widget::cget $items($step) -nextcommand]
+ if {![string equal $cmd ""]} {
+ set res [uplevel #0 $cmd]
+ if {!$res} { return }
+ }
+ }
+
+ set item [step $path next]
+
+ if {[Widget::cget $items($item) -appendorder]} {
+ lappend data(order) $item
+ }
+
+ $path raise $item
+
+ event generate $path <<WizardStep>>
+ event generate $path <<WizardNext>>
+
+ return $item
+}
+
+
+proc Wizard::cancel { path } {
+ Widget::getVariable $path items
+ set step [$path raise]
+ if {![string equal $step ""]} {
+ set cmd [Widget::cget $items($step) -cancelcommand]
+ if {![string equal $cmd ""]} {
+ set res [uplevel #0 $cmd]
+ if {!$res} { return }
+ }
+ }
+
+ event generate $path <<WizardCancel>>
+}
+
+
+proc Wizard::finish { path } {
+ Widget::getVariable $path items
+ set step [$path raise]
+ if {![string equal $step ""]} {
+ set cmd [Widget::cget $items($step) -finishcommand]
+ if {![string equal $cmd ""]} {
+ set res [uplevel #0 $cmd]
+ if {!$res} { return }
+ }
+ }
+
+ event generate $path <<WizardFinish>>
+}
+
+
+proc Wizard::help { path } {
+ Widget::getVariable $path items
+ set step [$path raise]
+ if {![string equal $step ""]} {
+ set cmd [Widget::cget $items($step) -helpcommand]
+ if {![string equal $cmd ""]} {
+ uplevel #0 $cmd
+ }
+ }
+
+ event generate $path <<WizardHelp>>
+}
+
+
+proc Wizard::step { path node {start ""} {traverse 1} } {
+ Widget::getVariable $path data
+ Widget::getVariable $path items
+ Widget::getVariable $path branches
+
+ if {![string equal $start ""]} {
+ if {![exists $path $start]} {
+ return -code error "item \"$start\" does not exist"
+ }
+ }
+
+ switch -- $node {
+ "current" {
+ set item [$path raise]
+ }
+
+ "end" - "last" {
+ ## Keep looping through 'next' until we hit the end.
+ set item [$path step next]
+ while {![string equal $item ""]} {
+ set last $item
+ set item [$path step next $item]
+ }
+ set item $last
+ }
+
+ "back" - "previous" {
+ if {[string equal $start ""]} {
+ set item [lindex $data(order) end-1]
+ } else {
+ set idx [lsearch $data(order) $start]
+ incr idx -1
+ if {$idx < 0} { return }
+ set item [lindex $data(order) $idx]
+ }
+ }
+
+ "next" {
+ set step [$path raise]
+ if {![string equal $start ""]} { set step $start }
+
+ set branch [$path branch $step]
+ if {$traverse && [_is_branch $path $step]} {
+ ## This step is a branch. Let's figure out where to go next.
+ if {[traverse $path $step]} {
+ ## It's ok to traverse into this branch.
+ ## Set step to null so that we'll end up finding the
+ ## first step in the branch.
+ set branch $step
+ set step ""
+ }
+ }
+
+ set idx [lsearch $branches($branch) $step]
+ incr idx
+
+ set item [lindex $branches($branch) $idx]
+
+ if {$idx >= [llength $branches($branch)]} {
+ ## We've reached the end of this branch.
+ ## If it's the root branch, or this branch terminates we return.
+ if {[string equal $branch "root"]
+ || [Widget::cget $items($branch) -action] == "terminate"} {
+ return
+ }
+
+ ## We want to merge back with our parent branch.
+ set item [step $path next $branch 0]
+ }
+
+ ## If this step is a branch, find the next step after it.
+ if {$traverse && [_is_branch $path $item]} {
+ set item [$path step next $item]
+ }
+ }
+
+ default {
+ if {![exists $path $node]} {
+ return -code error "item \"$node\" does not exist"
+ }
+ set item $node
+ }
+ }
+
+ return $item
+}
+
+
+proc Wizard::nodes { path branch {first ""} {last ""} } {
+ Widget::getVariable $path data
+ Widget::getVariable $path branches
+ if {$first == ""} { return $branches($branch) }
+ if {$last == ""} { return [lindex $branches($branch) $first] }
+ return [lrange $data(steps) $first $last]
+}
+
+
+proc Wizard::index { path item } {
+ Widget::getVariable $path branches
+ set branch [$path branch $item]
+ return [lsearch $branches($branch) $item]
+}
+
+
+proc Wizard::raise { path {item ""} } {
+ Widget::getVariable $path data
+ Widget::getVariable $path items
+
+ set steps $path.steps
+ set buttons $path.buttons
+
+ if {[string equal $item ""]} { return $data(current) }
+
+ $path createStep $item
+
+ ## Eval the global raisecommand if we have one, appending the item.
+ set cmd [Widget::cget $path -raisecommand]
+ if {![string equal $cmd ""]} {
+ uplevel #0 $cmd [list $item]
+ }
+
+ ## Eval this item's raisecommand if we have one.
+ set cmd [Widget::cget $items($item) -raisecommand]
+ if {![string equal $cmd ""]} {
+ uplevel #0 $cmd
+ }
+
+ set title [getoption $path $item -title]
+ wm title [winfo toplevel $path] $title
+
+ if {[Widget::cget $path -separator]} {
+ set txt [getoption $path $item -separatortext]
+ $path itemconfigure separatortext -text $txt
+ }
+
+ set default [Widget::cget $items($item) -default]
+ set button [lsearch $data(buttons) $default]
+ $buttons setfocus $button
+
+ $steps raise $item
+
+ set data(current) $item
+
+ set back [$path step back]
+ set next [$path step next]
+
+ if {[Widget::cget $path -autobuttons]} {
+ set txt [Widget::cget $items($item) -backtext]
+ $path itemconfigure back -text $txt -state normal
+ set txt [Widget::cget $items($item) -nexttext]
+ $path itemconfigure next -text $txt -state normal
+ set txt [Widget::cget $items($item) -canceltext]
+ $path itemconfigure cancel -text $txt -state normal
+ if {[Widget::cget $path -helpbutton]} {
+ set txt [Widget::cget $items($item) -helptext]
+ $path itemconfigure help -text $txt
+ }
+
+ if {[Widget::cget $path -finishbutton]} {
+ set txt [Widget::cget $items($item) -finishtext]
+ $path itemconfigure finish -text $txt -state disabled
+ }
+
+ if {[string equal $back ""]} {
+ $path itemconfigure back -state disabled
+ }
+
+ if {[string equal $next ""]} {
+ if {[Widget::cget $path -finishbutton]} {
+ $path itemconfigure next -state disabled
+ $path itemconfigure finish -state normal
+ } else {
+ set txt [Widget::cget $items($item) -finishtext]
+ $path itemconfigure next -text $txt -command [list $path finish]
+ }
+ $path itemconfigure back -state disabled
+ $path itemconfigure cancel -state disabled
+ } else {
+ set txt [Widget::cget $items($item) -nexttext]
+ $path itemconfigure next -text $txt -command [list $path next]
+ }
+ }
+
+ event generate $path <<WizardStep>>
+
+ if {[string equal $next ""]} { event generate $path <<WizardLastStep>> }
+ if {[string equal $back ""]} { event generate $path <<WizardFirstStep>> }
+
+ return $item
+}
+
+
+proc Wizard::widgets { path command args } {
+ Widget::getVariable $path items
+ Widget::getVariable $path widgets
+ Widget::getVariable $path stepWidgets
+
+ switch -- $command {
+ "set" {
+ set node [lindex $args 0]
+ if {[string equal $node ""]} {
+ set err [BWidget::wrongNumArgsString \
+ "$path widgets set <name> ?option ..?"]
+ return -code error $err
+ }
+ set args [lreplace $args 0 0]
+ set item $path.#widget#$node
+
+ Widget::init Wizard::Widget $item $args
+ set step [Widget::cget $item -step]
+ set widget [Widget::cget $item -widget]
+ if {[string equal $step ""]} {
+ set widgets($node) $widget
+ } else {
+ set stepWidgets($step,$node) $widget
+ }
+ return $widget
+ }
+
+ "get" {
+ set node [lindex $args 0]
+ if {[string equal $node ""]} {
+ return [array names widgets]
+ }
+ set args [lreplace $args 0 0]
+
+ array set map [list Wizard::Widget {}]
+ array set map [Widget::parseArgs Wizard::Widget $args]
+ array set data $map(Wizard::Widget)
+
+ if {[info exists data(-step)]} {
+ set step $data(-step)
+ } else {
+ set step [$path step current]
+ }
+
+ ## If a widget exists for this step, return it.
+ if {[info exists stepWidgets($step,$node)]} {
+ return $stepWidgets($step,$node)
+ }
+
+ ## See if a widget exists on the global level.
+ if {![info exists widgets($node)]} {
+ return -code error "item \"$node\" does not exist"
+ }
+ return $widgets($node)
+ }
+
+ default {
+ set err [BWidget::badOptionString option $command [list get set]]
+ return -code error $err
+ }
+ }
+}
+
+
+proc Wizard::variable { path step option } {
+ set item $path.$step
+ return [Widget::varForOption $item $option]
+}
+
+
+proc Wizard::branch { path {node "current"} } {
+ Widget::getVariable $path data
+ if {[string equal $node "current"]} { set item [$path step current] }
+ if {[string equal $node ""]} { return "root" }
+ if {[info exists data($node,branch)]} { return $data($node,branch) }
+ return -code error "item \"$node\" does not exist"
+}
+
+
+proc Wizard::traverse { path node } {
+ Widget::getVariable $path items
+
+ if {$node == "root"} { return 1 }
+
+ if {![_is_branch $path $node]} {
+ return -code error "branch \"$node\" does not exist"
+ }
+
+ set cmd [Widget::cget $items($node) -command]
+ if {[string equal $cmd ""]} { return 1 }
+ return [uplevel #0 $cmd]
+}
+
+
+proc Wizard::exists { path item } {
+ Widget::getVariable $path items
+ return [info exists items($item)]
+}
+
+
+proc Wizard::createStep { path item {delete 0} } {
+ Widget::getVariable $path data
+ Widget::getVariable $path items
+ Widget::getVariable $path steps
+
+ if {![_is_step $path $item]} { return }
+
+ if {$delete} {
+ if {[$path.steps exists $item]} {
+ $path.steps delete $item
+ }
+ if {[info exists data($item,realized)]} {
+ unset data($item,realized)
+ }
+ }
+
+ if {![info exists data($item,realized)]} {
+ ## Eval the global createcommand if we have one, appending the item.
+ set cmd [Widget::cget $path -createcommand]
+ if {![string equal $cmd ""]} {
+ uplevel #0 $cmd [list $item]
+ }
+
+ ## Eval this item's createcommand if we have one.
+ set cmd [Widget::cget $items($item) -createcommand]
+ if {![string equal $cmd ""]} {
+ uplevel #0 $cmd
+ }
+
+ set data($item,realized) 1
+ }
+
+ return
+}
+
+
+proc Wizard::getoption { path item option } {
+ Widget::getVariable $path items
+ return [Widget::getOption $option "" $path $items($item)]
+}
+
+
+proc Wizard::reorder { path parent nodes } {
+ Widget::getVariable $path branches
+ set branches($parent) $nodes
+}
+
+
+proc Wizard::_insert_button { path idx node args } {
+ Widget::getVariable $path data
+ Widget::getVariable $path items
+ Widget::getVariable $path buttons
+ Widget::getVariable $path widgets
+
+ set buttons($node) 1
+ set widgets($node) [eval $path.buttons insert $idx $args]
+ set item [string map [list $path.buttons.b {}] $widgets($node)]
+ set items($node) $item
+ return $widgets($node)
+}
+
+
+proc Wizard::_insert_step { path idx branch node args } {
+ Widget::getVariable $path data
+ Widget::getVariable $path steps
+ Widget::getVariable $path items
+ Widget::getVariable $path widgets
+ Widget::getVariable $path branches
+
+ set steps($node) 1
+ lappend data(steps) $node
+ set data($node,branch) $branch
+ if {$idx == "end"} {
+ lappend branches($branch) $node
+ } else {
+ set branches($branch) [linsert $branches($branch) $idx $node]
+ }
+
+ set items($node) $path.$node
+ Widget::init Wizard::Step $items($node) $args
+ set widgets($node) [$path.steps add $node]
+ if {[Widget::cget $items($node) -create]} { $path createStep $node }
+ return $widgets($node)
+}
+
+
+proc Wizard::_insert_branch { path idx branch node args } {
+ Widget::getVariable $path data
+ Widget::getVariable $path items
+ Widget::getVariable $path branches
+
+ set branches($node) [list]
+ lappend data(branches) $node
+ set data($node,branch) $branch
+ if {$idx == "end"} {
+ lappend branches($branch) $node
+ } else {
+ set branches($branch) [linsert $branches($branch) $idx $node]
+ }
+
+ set items($node) $path.$node
+ Widget::init Wizard::Branch $items($node) $args
+}
+
+
+proc Wizard::_is_step { path node } {
+ Widget::getVariable $path steps
+ return [info exists steps($node)]
+}
+
+
+proc Wizard::_is_branch { path node } {
+ Widget::getVariable $path branches
+ return [info exists branches($node)]
+}
+
+
+# ------------------------------------------------------------------------------
+# Command Wizard::_destroy
+# ------------------------------------------------------------------------------
+proc Wizard::_destroy { path } {
+ Widget::destroy $path
+}
+
+
+proc SimpleWizard { path args } {
+ option add *WizLayoutSimple*Label.padX 5 interactive
+ option add *WizLayoutSimple*Label.anchor nw interactive
+ option add *WizLayoutSimple*Label.justify left interactive
+ option add *WizLayoutSimple*Label.borderWidth 0 interactive
+ option add *WizLayoutSimple*Label.highlightThickness 0 interactive
+
+ set cmd [list Wizard::layout::simple $path]
+ return [eval [list Wizard $path] $args [list -createcommand $cmd]]
+}
+
+
+proc ClassicWizard { path args } {
+ option add *WizLayoutClassic*Label.padX 5 interactive
+ option add *WizLayoutClassic*Label.anchor nw interactive
+ option add *WizLayoutClassic*Label.justify left interactive
+ option add *WizLayoutClassic*Label.borderWidth 0 interactive
+ option add *WizLayoutClassic*Label.highlightThickness 0 interactive
+
+ set cmd [list Wizard::layout::classic $path]
+ return [eval [list Wizard $path] $args [list -createcommand $cmd]]
+}
+
+
+proc Wizard::layout::simple { wizard step } {
+ set frame [$wizard widgets get $step]
+
+ set layout [$wizard widgets set layout -widget $frame.layout -step $step]
+
+ foreach w [list titleframe pretext posttext clientArea] {
+ set $w [$wizard widgets set $w -widget $layout.$w -step $step]
+ }
+
+ foreach w [list title subtitle icon] {
+ set $w [$wizard widgets set $w -widget $titleframe.$w -step $step]
+ }
+
+ frame $layout -class WizLayoutSimple
+
+ pack $layout -expand 1 -fill both
+
+ # Client area. This is where the caller places its widgets.
+ frame $clientArea -bd 8 -relief flat
+
+ Separator $layout.sep1 -relief groove -orient horizontal
+
+ # title and subtitle and icon
+ frame $titleframe -bd 4 -relief flat -background white
+ label $title -background white -textvariable [$wizard variable $step -text1]
+ label $subtitle -height 2 -background white -padx 15 -width 40 \
+ -textvariable [$wizard variable $step -text2]
+
+ label $icon -borderwidth 0 -background white -anchor c
+ set iconImage [$wizard getoption $step -icon]
+ if {![string equal $iconImage ""]} { $icon configure -image $iconImage }
+
+ set labelfont [font actual [$title cget -font]]
+ $title configure -font [concat $labelfont -weight bold]
+
+ # put the title, subtitle and icon inside the frame we've built for them
+ grid $title -in $titleframe -row 0 -column 0 -sticky nsew
+ grid $subtitle -in $titleframe -row 1 -column 0 -sticky nsew
+ grid $icon -in $titleframe -row 0 -column 1 -rowspan 2 -padx 8
+ grid columnconfigure $titleframe 0 -weight 1
+ grid columnconfigure $titleframe 1 -weight 0
+
+ # pre and post text.
+ label $pretext -textvariable [$wizard variable $step -text3]
+ label $posttext -textvariable [$wizard variable $step -text4]
+
+ # when our label widgets change size we want to reset the
+ # wraplength to that same size.
+ foreach widget {title subtitle pretext posttext} {
+ bind [set $widget] <Configure> {
+ # yeah, I know this looks weird having two after idle's, but
+ # it helps prevent the geometry manager getting into a tight
+ # loop under certain circumstances
+ #
+ # note that subtracting 10 is just a somewhat arbitrary number
+ # to provide a little padding...
+ after idle {after idle {%W configure -wraplength [expr {%w -10}]}}
+ }
+ }
+
+ grid $titleframe -row 0 -column 0 -sticky nsew -padx 0
+ grid $layout.sep1 -row 1 -sticky ew
+ grid $pretext -row 2 -sticky nsew -padx 8 -pady 8
+ grid $clientArea -row 3 -sticky nsew -padx 8 -pady 8
+ grid $posttext -row 4 -sticky nsew -padx 8 -pady 8
+
+ grid columnconfigure $layout 0 -weight 1
+ grid rowconfigure $layout 0 -weight 0
+ grid rowconfigure $layout 1 -weight 0
+ grid rowconfigure $layout 2 -weight 0
+ grid rowconfigure $layout 3 -weight 1
+ grid rowconfigure $layout 4 -weight 0
+}
+
+proc Wizard::layout::classic { wizard step } {
+ set frame [$wizard widgets get $step]
+
+ set layout [$wizard widgets set layout -widget $frame.layout -step $step]
+ foreach w [list title subtitle icon pretext posttext clientArea] {
+ set $w [$wizard widgets set $w -widget $layout.$w -step $step]
+ }
+
+ frame $layout -class WizLayoutClassic
+
+ pack $layout -expand 1 -fill both
+
+ # Client area. This is where the caller places its widgets.
+ frame $clientArea -bd 8 -relief flat
+
+ Separator $layout.sep1 -relief groove -orient vertical
+
+ # title and subtitle
+ label $title -textvariable [$wizard variable $step -text1]
+ label $subtitle -textvariable [$wizard variable $step -text2] -height 2
+
+ array set labelfont [font actual [$title cget -font]]
+ incr labelfont(-size) 6
+ set labelfont(-weight) bold
+ $title configure -font [array get labelfont]
+
+ # pre and post text.
+ label $pretext -textvariable [$wizard variable $step -text3]
+ label $posttext -textvariable [$wizard variable $step -text4]
+
+ # when our label widgets change size we want to reset the
+ # wraplength to that same size.
+ foreach widget {title subtitle pretext posttext} {
+ bind [set $widget] <Configure> {
+ # yeah, I know this looks weird having two after idle's, but
+ # it helps prevent the geometry manager getting into a tight
+ # loop under certain circumstances
+ #
+ # note that subtracting 10 is just a somewhat arbitrary number
+ # to provide a little padding...
+ after idle {after idle {%W configure -wraplength [expr {%w -10}]}}
+ }
+ }
+
+ label $icon -borderwidth 1 -relief sunken -background white \
+ -anchor c -width 96 -image Wizard::none
+ set iconImage [$wizard getoption $step -icon]
+ if {![string equal $iconImage ""]} { $icon configure -image $iconImage }
+
+ grid $icon -row 0 -column 0 -sticky nsew -padx 8 -pady 8 -rowspan 5
+ grid $title -row 0 -column 1 -sticky ew -padx 8 -pady 8
+ grid $subtitle -row 1 -column 1 -sticky ew -padx 8 -pady 8
+ grid $pretext -row 2 -column 1 -sticky ew -padx 8
+ grid $clientArea -row 3 -column 1 -sticky nsew -padx 8
+ grid $posttext -row 4 -column 1 -sticky ew -padx 8 -pady 24
+
+ grid columnconfigure $layout 0 -weight 0
+ grid columnconfigure $layout 1 -weight 1
+
+ grid rowconfigure $layout 0 -weight 0
+ grid rowconfigure $layout 1 -weight 0
+ grid rowconfigure $layout 2 -weight 0
+ grid rowconfigure $layout 3 -weight 1
+ grid rowconfigure $layout 4 -weight 0
+}
diff --git a/modules/tclsci/tcl/BWidget/xpm2image.tcl b/modules/tclsci/tcl/BWidget/xpm2image.tcl
new file mode 100755
index 000000000..7df22c59b
--- /dev/null
+++ b/modules/tclsci/tcl/BWidget/xpm2image.tcl
@@ -0,0 +1,115 @@
+# ----------------------------------------------------------------------------
+# xpm2image.tcl
+# Slightly modified xpm-to-image command
+# $Id: xpm2image.tcl,v 1.5 2004/09/09 22:17:03 hobbs Exp $
+# ------------------------------------------------------------------------------
+#
+# Copyright 1996 by Roger E. Critchlow Jr., San Francisco, California
+# All rights reserved, fair use permitted, caveat emptor.
+# rec@elf.org
+#
+# ----------------------------------------------------------------------------
+
+proc xpm-to-image { file } {
+ set f [open $file]
+ set string [read $f]
+ close $f
+
+ #
+ # parse the strings in the xpm data
+ #
+ set xpm {}
+ foreach line [split $string "\n"] {
+ if {[regexp {^"([^\"]*)"} $line all meat]} {
+ if {[string first XPMEXT $meat] == 0} {
+ break
+ }
+ lappend xpm $meat
+ }
+ }
+ #
+ # extract the sizes in the xpm data
+ #
+ set sizes [lindex $xpm 0]
+ set nsizes [llength $sizes]
+ if { $nsizes == 4 || $nsizes == 6 || $nsizes == 7 } {
+ set data(width) [lindex $sizes 0]
+ set data(height) [lindex $sizes 1]
+ set data(ncolors) [lindex $sizes 2]
+ set data(chars_per_pixel) [lindex $sizes 3]
+ set data(x_hotspot) 0
+ set data(y_hotspot) 0
+ if {[llength $sizes] >= 6} {
+ set data(x_hotspot) [lindex $sizes 4]
+ set data(y_hotspot) [lindex $sizes 5]
+ }
+ } else {
+ error "size line {$sizes} in $file did not compute"
+ }
+
+ #
+ # extract the color definitions in the xpm data
+ #
+ foreach line [lrange $xpm 1 $data(ncolors)] {
+ set colors [split $line \t]
+ set cname [lindex $colors 0]
+ lappend data(cnames) $cname
+ if { [string length $cname] != $data(chars_per_pixel) } {
+ error "color definition {$line} in file $file has a bad size color name"
+ }
+ foreach record [lrange $colors 1 end] {
+ set key [lindex $record 0]
+ set color [string tolower [join [lrange $record 1 end] { }]]
+ set data(color-$key-$cname) $color
+ if { [string equal -nocase $color "none"] } {
+ set data(transparent) $cname
+ }
+ }
+ foreach key {c g g4 m} {
+ if {[info exists data(color-$key-$cname)]} {
+ set color $data(color-$key-$cname)
+ set data(color-$cname) $color
+ set data(cname-$color) $cname
+ lappend data(colors) $color
+ break
+ }
+ }
+ if { ![info exists data(color-$cname)] } {
+ error "color definition {$line} in $file failed to define a color"
+ }
+ }
+
+ #
+ # extract the image data in the xpm data
+ #
+ set image [image create photo -width $data(width) -height $data(height)]
+ set y 0
+ foreach line [lrange $xpm [expr {1+$data(ncolors)}] [expr {1+$data(ncolors)+$data(height)}]] {
+ set x 0
+ set pixels {}
+ while { [string length $line] > 0 } {
+ set pixel [string range $line 0 [expr {$data(chars_per_pixel)-1}]]
+ set c $data(color-$pixel)
+ if { [string equal $c none] } {
+ if { [string length $pixels] } {
+ $image put [list $pixels] -to [expr {$x-[llength $pixels]}] $y
+ set pixels {}
+ }
+ } else {
+ lappend pixels $c
+ }
+ set line [string range $line $data(chars_per_pixel) end]
+ incr x
+ }
+ if { [llength $pixels] } {
+ $image put [list $pixels] -to [expr {$x-[llength $pixels]}] $y
+ }
+ incr y
+ }
+
+ #
+ # return the image
+ #
+ return $image
+}
+