Artifact 4c4121f70aaac39756082ad7d850987d2876815f:
- File addons/dialogwin/dialogwin.tcl — part of check-in [8995b4234c] at 2017-04-13 18:09:43 on branch trunk — try not loading compass_utils in RamDebugger unless necessary (user: ramsan size: 82231)
package require Tcl 8.5 package require Tk 8.5 catch { package require img::png } # to auto load from GiD catch { auto_load msgcat::mc msgcat::mc "" } package require msgcat package require snit namespace eval ::dialogwinmsgs { ::msgcat::mcload [file join [file dirname [info script]] msgs] } if { [info commands _] eq "" } { proc _ { args } { set ret [uplevel 1 ::msgcat::mc $args] regexp {(.*)#C#(.*)} $ret {} ret return $ret } } if { [info procs GetImage] == "" || ![info exists ::GIDDEFAULT] } { #using without GiD GetImage not exists, then return always dialogwinquestionhead image create photo dialogwinquestionhead -data { R0lGODlhKAAoAKUAAPHY8+y9+dmX1bxLt7EMprATqsIXtsE0tdaGz+bK2s94yt4UxeUNzNgK wcgEscQLsbEDocQjtOElzfEb2PMW1OQczMF5uuOr2dssyfw06vUk3M1ZvsScwMWrttFIwaw2 qfY86tG4vvLW1uHV1NrExrSSpMw+uPhH79GYwftV+t8zyPXj5bRqqPxo/NxcyPos5cBYsN6j zuG42Nw+xMSivNx4xOxC3L8rr8xkvORM0MlrueBkyLxDtP///////////yH+FUNyZWF0ZWQg d2l0aCBUaGUgR0lNUAAh+QQBCgA/ACwAAAAAKAAoAAAG/sCfcEgsGo/IpHLJbDqf0Kj0CAhY AdOmYEDodguGAyKRNSoM6IWa0Wg4HhDIgFwORAwSyYRSoTAmDAtsDnEWWRcGGBkaExIbFhwd HRwKHoJuEB9SFxEgIIwbIQkJIiMiCSQhJSaDmVAJEScnjCgAIre4uAkdA36EA08mJymMCj+3 tremuCMdGL4QKE0IICkZFCorK8srCSGiuQkse24ETSotJ3sux7c/CR4YGBbbuBwU+A0QhkoC Jy0v8JngtkLFHgoe2t0KwcfPgwJLPLRIMWHPBBgdQpDYgK8iB4UrYuDLB0GGkhktQByk0EiF HnwqaKzI9aMGvj4MHhhDksAG/sCOI4N6IDET1w8ZfW5SWAAjiYx/GlgmnephxExTK37EkDBy T4UFB5IIANGiItCREhIUdYfA4p+RFW4kiWGDGL4/XhEqFFEzKEu8GsIikfGCIsuVe3D8WPbj wsGkBzW8SIgEQIQUATu+pTBjGd8ciC1SeJFBcZJOLyoyYMmaAguNJFBM6NMHUMcXIAQo0YH7 8J7NfDBwDWpxjwZPWZ0aWNS14h5Hlab+vZ2C3ZIDkn8fZKCiAwkSNFgk9U1Bw7ALTGQ8YGT2 sG5lHUxMP1xthxMcDczirWBVl46OFhVmAxZOfJBfaxOEsNYKONhW0QuyoAfFDQ6s9tYGCWC1 AiOHTkGYmxQr8FAhAyRSsEFGMczQkWQZqCDhFAgQ0EaJwFXEiAcElrGCDg840EYDbJC4QAMe xFDGERfocMAdBdywAQI5HinllFRWaeWVWB4RBAA7 } proc GetImage { filename } { return dialogwinquestionhead } } namespace eval img {} if { [info command img::ok-16] eq "" } { image create photo img::ok-16 -data { iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAABl0RVh0 U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVDiNhZNJbFtlFIW//3/v2X5xYsd1 GshUAjHUBZIQEC1FGcxQFaRmUYkghBTEggUbJIqirpBYsABBGBZ0BUJIBSHKAkQqCiyqUKdQhiA5 UBJAzeAkpolN4inxs9/ws6pVVpztuee7i3uPUEpxvUYnh+IINS41lVCe6AUQUv3quWIaJU5PTSQX rp8X1wCjk0NSCHXS7/O/eOTgfYGbW2Nae7gbieRqcZWlzUXv3A/fWtVa9WWlxGtTE0mvDhidHJJS 8y7s39c9MDY41uCwg6OqSKGjCz+6NDBkAFyDj2c+qvy+/NcvniuHpyaSngQQQp28tWvfwBMjjzes Wym2qmv4ZJD94RHuiBwhbNxIxSmRd9KMjzxlxrtidwuhXgAQx14fjPv9xs8nHnsmuLo7iy597A3c woHmB2k1ewCw3DKLxR/JWlewnDItRoxXP31rx6raAxKhxocH+gMFZ42SnUMXfjRhULZzuJ4NQEBr pKuxD0MG2HULlOwNEv0HAwj1tC41leiItmnZyiIRXzt37jlKyGjFkCY1z8KUBgBNRgsHmh8iZ6X5 x0rT2dKhSU0lpPJE7w3hDvK1DIm2Z4mFDtNq9hDxt2PqTf85ccTfzj3R4xTsDVpDbShP9MprpqNs PFz+T45rU3MquJ4DgBZ/tOtYT2d7lyPz/Fm4iC58WG6Jkp3F9WqYergezpQXOJd+A0M0YFsGc8vz s9JzxfR6NuNG/d1crSxwPnOKr9feZDb3GaYeqodXSimmll8hb/1NNNDJymba9VwxLVHidDI1Z+01 biMoo5TtLSy3SE/oUH17ujhHcv19itUcptZMk9bB95fnLJT4QPvjm5XchzPverlS9v6H48eN7O4S Ag3LLmEIk91agctb57HsHUwtRDzyAJ9/92UlV8i/NDUxc7b+ykJ6yVhH512jhx9pcFQFFDRoewjq EVxl42LjOoozFz+pXMmspi69t5DYnN+qCqUUQoigr9FoHH6+/0SopfG5o/cOBuJtffKm5tsJ6s0s bf/GfCblfXHpq9r2RuHUhbdT7ziWuwMU620UQviBYN9YrD/aE34yENIOaYYeQ4FrO4uVvP3Txvz2 mfmzyymgDJSVUt6/yJ93Q2rwEU0AAAAASUVORK5CYII= } } if { [info command img::ok-close-16] eq "" } { image create photo img::ok-close-16 -data { iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI WXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAC7UlEQVQ4y32TS2icVRiGn3PO /8+1k8xMQoKaIhqhhppYLwHRutBJqZp0IZGirYgErAu1AbFW8LIQbHQhKCiCYIVSvICLLBQShG5U UNsSsZTYtCVTTBhNyWRm/pn//p/jRiuW1A8+Pnh5eVbfI7jGvH/0lV6Rad9iMMKKuy8+99SRtc16 4upg/szMQ6qr9qqyvXuzdlZKoQjjxJgodzLqlGcevPXl2U0BB158VDw8df172dLGC4VUSaTlFiyZ RWJhMGgT4sdt09iQn343e/nAkcPHEgDrH8DoZOZNVawdzNi9pOQWUrKAugqAJUWx3JwarthtYBpA ATx+aGT7tp0cL6S7ZM4qkJYFUiqHLTIomUKiAEFttU6URGRLwWj5xtz8T3O/r0qA/h3h88rGEgIk AiW4spYwKGFYXqqxr/IR81+dxbIs2T/IQQAJYBd1JSHBmBhEiBABkgD1910+f4mn93xIZWKIyakR tIno6rEqW2/LCKv7OqVkVzIQJT6x8Yi1i9Y2SBAiZnmpzr7xo4ztGeLQ2/fjaodIu6RKSZ/vJmkZ eto0nCB0woCW2+GZ3V/z8w8XiXSbc79V2fvIJ4xNbOPwO/cRmg5e3KETuTRdNw5craXXMHpl0V2s +y4d43PnWD/TT3zLF8cW2D/+JQ+MD/LSzN14SYt21MKJHJqhw4WzjaXI15ECsHKm3H+XvctSMHxP kbTK8sFrv7DrsZuZfmsY37i0YxcnatMIHOpekxOfr35c/TE4IQDsPMXd73b/Ori9sLWvkKeczrO2 qBnaUUIpQWIMQRLjhj6NwOXC+Y2148/WRry6+VMB6Ah/bTFa6LmDSWHH6dhE5HsNXuLRiVycsEPT d1j3HFZqDW/29ctPNi/phSuPBOBvmOrKyfD79IDeKfJxj58EdCIPJ3Bpei7rbZelM63qN28096+f 03PXlAlJoe92ufeGUTVRHFA3SYFo1XR15VQ898dp/ZlJaP6vjf9B/etKDOjNSn8BbbRhsLdiTR8A AAAldEVYdGRhdGU6Y3JlYXRlADIwMTAtMDItMTFUMDE6MDU6MDUtMDY6MDC9toJLAAAAJXRFWHRk YXRlOm1vZGlmeQAyMDA4LTA2LTEzVDAwOjI2OjI0LTA1OjAwGDmmwgAAAABJRU5ErkJggg== } } if { [info command img::fileclose16] eq "" } { image create photo img::fileclose16 -data { R0lGODlhEAAQAIQAAPwCBCQiJBwaHAQCBDQyNDw6PFxaXFRSVERGRCwqLAwODGRiZHx6fPz+/Gxq bAwKDCQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEA AAAALAAAAAAQABAAAAVaICCOZGmeqBgEwjCkRGEcSKK4JrEcBrMgAdeLVDg0GguGsYEbBQyGYyN6 FDoPDIf0+LCKBIgetQERDgGDBGIpNY8GioAU0m6KXFw883w3+/l9f4AkfimGIn4hACH+aENyZWF0 ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxs IHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs= } } if { [info command img::nav1downarrow16] eq "" } { image create photo img::nav1downarrow16 -data { R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIYhI+py+0PUZi0zmTtypflV0Vd RJbm6fgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29y IDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29t ADs= } } if { [info commands tkTabToWindow] == "" } { interp alias "" tkTabToWindow "" tk::TabToWindow #::tk::unsupported::ExposePrivateCommand tkTabToWindow } if { [info commands tkButtonInvoke] == "" } { interp alias "" tkButtonInvoke "" tk::ButtonInvoke #::tk::unsupported::ExposePrivateCommand tkButtonInvoke } package provide dialogwinR 1.32 package provide dialogwin 1.32 ################################################################################ # This software is copyrighted by Ramon Ribó (RAMSAN) ramsan@cimne.upc.es. # (http://gid.cimne.upc.es/ramsan) The following terms apply to all files # associated with the software unless explicitly disclaimed in individual files. # The authors hereby grant permission to use, copy, modify, distribute, # and license this software and its documentation for any purpose, provided # that existing copyright notices are retained in all copies and that this # notice is included verbatim in any distributions. No written agreement, # license, or royalty fee is required for any of the authorized uses. # Modifications to this software may be copyrighted by their authors # and need not follow the licensing terms described here, provided that # the new terms are clearly indicated on the first page of each file where # they apply. # IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY # FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES # ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY # DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE # IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE # NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR # MODIFICATIONS. ################################################################################ if { [info commands CCGetRGB] eq "" } { proc CCGetRGB { w color} { set ret $color set n [ scan $color \#%2x%2x%2x r g b] if { $n != 3} { set rgb [ winfo rgb $w $color] set r [ expr int( [ lindex $rgb 0]/256.0)] set g [ expr int( [ lindex $rgb 1]/256.0)] set b [ expr int( [ lindex $rgb 2]/256.0)] set ret [ format \#%02x%02x%02x $r $g $b] } return $ret } } if { [info commands CCColorActivo] eq "" } { proc CCColorActivo { color_usuario { factor 17} } { set ret "" set color_nuevo [ CCGetRGB . $color_usuario] set n [ scan $color_nuevo \#%2x%2x%2x r g b] if { $n == 3} { set r [ expr $r + $factor] if { $r > 255} { set r 255} set g [ expr $g + $factor] if { $g > 255} { set g 255} set b [ expr $b + $factor] if { $b > 255} { set b 255} set ret [ format \#%2x%2x%2x $r $g $b] } return $ret } } namespace eval DialogWin { variable w variable action variable user variable oldGrab variable grabStatus variable grab } #current styles are: # ridgeframe # separator # proc DialogWin::Init { winparent title style { morebuttons "" } { OKname "" } { Cancelname "" } } { variable action variable w variable grab set grab 1 if { [string match *nograb $style] } { set grab 0 } if { $winparent == "." } { set winparent "" } set w $winparent.__dialogwin catch { destroy $w } # set i 0 # while { [winfo exists $w] } { # incr i # set w $winparent.__dialogwin$i # } toplevel $w if { $::tcl_platform(platform) == "windows" } { wm attributes $w -toolwindow 1 } wm title $w $title wm withdraw $w switch $style { ridgeframe { frame $w.f -relief ridge -bd 2 frame $w.buts grid $w.f -sticky ewns -padx 2 -pady 2 grid $w.buts -sticky ew if { $::tcl_version >= 8.5 } { grid anchor $w.buts center } } separator - separator_nograb { frame $w.f -bd 0 frame $w.sep -bd 2 -relief raised -height 2 frame $w.buts grid $w.f -sticky ewns -padx 2 -pady 2 grid $w.sep -sticky ew grid $w.buts -sticky ew if { $::tcl_version >= 8.5 } { grid anchor $w.buts center } } default { error "error: only accepted styles ridgeframe, separator_nograb and separator" } } $w.buts conf -bg [CCColorActivo [$w cget -bg]] if { $OKname == "" } { set OKname [_ OK] } if { $Cancelname != "" } { set CancelName $Cancelname } elseif { $OKname == "-" } { set CancelName [_ Close] } else { set CancelName [_ Cancel] } set butwidth 7 if { [string length $OKname] > $butwidth } { set butwidth [string length $OKname] } if { [string length $CancelName] > $butwidth } { set butwidth [string length $CancelName] } foreach i $morebuttons { if { [string length $i] > $butwidth } { set butwidth [string length $i] } } set usedletters [string tolower [string index $OKname 0]] if { [string tolower [string index $CancelName 0]] != $usedletters } { lappend usedletters [string tolower [string index $CancelName 0]] set underlinecancel 0 } else { lappend usedletters [string tolower [string index $CancelName 1]] set underlinecancel 1 } if { $OKname != "-" } { button $w.buts.ok -text $OKname -width $butwidth -und 0 -command \ [namespace code "set action 1"] } set togrid "" if { $morebuttons != "" } { set iaction 2 foreach i $morebuttons { for { set ipos 0 } { $ipos < [string length $i] } { incr ipos } { set letter [string tolower [string index $i $ipos]] if { [regexp {[a-zA-Z]} $letter] && [lsearch $usedletters $letter] == -1 } { break } } if { $ipos < [string length $i] } { button $w.buts.b$iaction -text $i -width $butwidth -und $ipos \ -command [namespace code "set action $iaction"] bind $w <Alt-$letter> \ "tkButtonInvoke $w.buts.b$iaction" bind $w.buts.b$iaction <Return> "tkButtonInvoke $w.buts.b$iaction" lappend usedletters [string tolower [string index $i $ipos]] } else { button $w.buts.b$iaction -text $i -width $butwidth \ -command [namespace code "set action $iaction"] } lappend togrid $w.buts.b$iaction incr iaction } } if { $Cancelname != "-" } { button $w.buts.cancel -text $CancelName -width $butwidth -und $underlinecancel -command \ [namespace code "set action 0"] } if { $OKname != "-" } { set togrid "$w.buts.ok $togrid" } if { $Cancelname != "-" } { set togrid "$togrid $w.buts.cancel" } eval grid $togrid -padx 2 -pady 4 if { $OKname != "-" } { bind $w.buts.ok <Return> "tkButtonInvoke $w.buts.ok" catch { bind $w <Alt-[string tolower [string index $OKname 0]]> "tkButtonInvoke $w.buts.ok" } focus $w.buts.ok } elseif { $Cancelname != "-" } { focus $w.buts.cancel } if { $Cancelname != "-" } { bind $w <Escape> "tkButtonInvoke $w.buts.cancel" bind $w.buts.cancel <Return> "tkButtonInvoke $w.buts.cancel" catch { bind $w <Alt-[string tolower [string index $CancelName $underlinecancel]]> \ "tkButtonInvoke $w.buts.cancel" } wm protocol $w WM_DELETE_WINDOW "tkButtonInvoke $w.buts.cancel" } else { bind $w <Escape> [namespace code "set action -1"] wm protocol $w WM_DELETE_WINDOW [namespace code "set action -1"] } grid columnconf $w 0 -weight 1 grid rowconf $w 0 -weight 1 return $w.f } proc DialogWin::InvokeOK { { visible 1 } } { variable w if { ![winfo exists $w.buts.ok] } { return } if { $visible } { tkButtonInvoke $w.buts.ok } else { $w.buts.ok invoke } } proc DialogWin::InvokeCancel { { visible 1 } } { variable w if { ![winfo exists $w.buts.cancel] } { return } if { $visible } { tkButtonInvoke $w.buts.cancel } else { $w.buts.cancel invoke } } proc DialogWin::FocusCancel {} { variable w focus $w.buts.cancel } proc DialogWin::InvokeButton { num { visible 1 } } { variable w if { ![winfo exists $w.buts] } { return } if { $num < 2 } { WarnWin "DialogWin::InvokeButton num>2" return } foreach i [winfo children $w.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { if { $visible } { tkButtonInvoke $i } else { $i invoke } return } } WarnWin "DialogWin::InvokeButton num bad" } proc DialogWin::FocusButton { num } { variable w if { $num < 2 } { WarnWin "DialogWin::FocusButton num>2" return } foreach i [winfo children $w.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { focus $i return } } WarnWin "DialogWin::FocusButton num bad" } proc DialogWin::CreateWindow { { geom "" } { minwidth "" } { minheight "" } } { CreateWindowNoWait $geom $minwidth $minheight return [WaitForWindow 0] } proc DialogWin::CreateWindowNoWait { { geom "" } { minwidth "" } { minheight "" } } { variable w variable grab variable oldGrab variable grabStatus set top [winfo toplevel [winfo parent $w]] wm withdraw $w update idletasks if { $geom != "" } { wm geom $w $geom } else { if { $minwidth != "" && [winfo reqwidth $w] < $minwidth } { set width $minwidth } else { set width [winfo reqwidth $w] } if { $minheight != "" && [winfo reqheight $w] < $minheight } { set height $minheight } else { set height [winfo reqheight $w] } if { [wm state $top] == "withdrawn" } { set x [expr [winfo screenwidth $top]/2-$width/2] set y [expr [winfo screenheight $top]/2-$height/2] } else { set x [expr [winfo x $top]+[winfo width $top]/2-$width/2] set y [expr [winfo y $top]+[winfo height $top]/2-$height/2] } if { $x < 0 } { set x 0 } if { $y < 0 } { set y 0 } wm geom $w ${width}x${height}+${x}+$y } wm deiconify $w update idletasks wm geom $w [wm geom $w] focus $w set oldGrab [grab current .] if {[string compare $oldGrab ""]} { set grabStatus [grab status $oldGrab] grab release $oldGrab } if { $grab } { grab $w } } proc DialogWin::WaitForWindow { { raise "" } } { variable action variable w if { $raise == "" } { # this is to avoid the 2 second problem in KDE 2 if { $::tcl_platform(platform) == "windows" } { set raise 1 } else { set raise 0 } } if { $raise } { raise [winfo toplevel $w] } vwait [namespace which -variable action] return $action } proc DialogWin::DestroyWindow {} { variable w variable oldGrab variable grabStatus if {[string compare $oldGrab ""]} { if {[string compare $grabStatus "global"]} { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab $oldGrab } } else { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab -global $oldGrab } } } destroy $w set w "" } # NOTE: initial value of variables is not transferred proc CopyNamespace { nfrom nto } { set comm "namespace eval $nto {\n" foreach i [info vars ${nfrom}::*] { append comm "variable [namespace tail $i]\n" } foreach i [info commands ${nfrom}::*] { set args "" foreach j [info args $i] { if { [info default $i $j kk] } { lappend args [list $j $kk] } else { lappend args $j } } append comm "proc [namespace tail $i] { $args } {\n[info body $i]\n}\n" } append comm "}" eval $comm } namespace eval DialogWinTop { variable user variable nameprefix __ } proc DialogWinTop::SetNamePrefix { prefix } { variable nameprefix $prefix } # command for OK is first; for cancel is last proc DialogWinTop::Init { winparent title style commands { morebuttons "" } { OKname "" } \ { Cancelname "" } } { variable nameprefix if { $winparent == "." } { set winparent "" } set w $winparent.${nameprefix}dialogwintop set i 0 while { [winfo exists $w] } { incr i set w $winparent.${nameprefix}dialogwintop$i } toplevel $w if { $::tcl_platform(platform) == "windows" } { wm attributes $w -toolwindow 1 } wm title $w $title switch $style { ridgeframe { frame $w.f -relief ridge -bd 2 frame $w.buts grid $w.f -sticky ewns -padx 2 -pady 2 grid $w.buts -sticky ew if { $::tcl_version >= 8.5 } { grid anchor $w.buts center } } separator { frame $w.f -bd 0 frame $w.sep -bd 2 -relief raised -height 2 frame $w.buts grid $w.f -sticky ewns -padx 2 -pady 2 grid $w.sep -sticky ew grid $w.buts -sticky ew if { $::tcl_version >= 8.5 } { grid anchor $w.buts center } } default { error "error: only accepted styles ridgeframe and separator" } } $w.buts conf -bg [CCColorActivo [$w cget -bg]] if { $OKname == "" } { set OKname [_ OK] } if { $Cancelname != "" } { set CancelName $Cancelname } elseif { $OKname == "-" } { set CancelName [_ Close] } else { set CancelName [_ Cancel] } set butwidth 7 if { [string length $OKname] > $butwidth } { set butwidth [string length $OKname] } if { [string length $CancelName] > $butwidth } { set butwidth [string length $CancelName] } foreach i $morebuttons { if { [string length $i] > $butwidth } { set butwidth [string length $i] } } set usedletters [list [string tolower [string index $OKname 0]]] if { [string tolower [string index $CancelName 0]] != $usedletters } { lappend usedletters [string tolower [string index $CancelName 0]] set underlinecancel 0 } else { lappend usedletters [string tolower [string index $CancelName 1]] set underlinecancel 1 } set icomm 0 if { $OKname != "-" } { button $w.buts.ok -text $OKname -width $butwidth -und 0 -command \ "[lindex $commands 0] $w.f" incr icomm } set letterbindings "" set togrid "" if { $morebuttons != "" } { foreach i $morebuttons { for { set ipos 0 } { $ipos < [string length $i] } { incr ipos } { set letter [string tolower [string index $i $ipos]] if { [regexp {[a-zA-Z]} $letter] && [lsearch $usedletters $letter] == -1 } { break } } if { $ipos < [string length $i] } { button $w.buts.b$icomm -text $i -width $butwidth -und $ipos \ -command "[lindex $commands $icomm] $w.f" set letter [string tolower [string index $i $ipos]] bind $w <Alt-$letter> "tkButtonInvoke $w.buts.b$icomm" lappend letterbindings $letter "tkButtonInvoke $w.buts.b$icomm" bind $w.buts.b$icomm <Return> "tkButtonInvoke $w.buts.b$icomm" lappend usedletters [string tolower [string index $i $ipos]] } else { button $w.buts.b$icomm -text $i -width $butwidth \ -command "[lindex $commands $icomm] $w.f" } lappend togrid $w.buts.b$icomm incr icomm } } if { $Cancelname != "-" } { button $w.buts.cancel -text $CancelName -width $butwidth -und $underlinecancel -command \ "[lindex $commands $icomm] $w.f" } if { $OKname != "-" } { set togrid "$w.buts.ok $togrid" } if { $Cancelname != "-" } { set togrid "$togrid $w.buts.cancel" } eval grid $togrid -padx 2 -pady 4 if { $OKname != "-" } { bind $w.buts.ok <Return> "tkButtonInvoke $w.buts.ok" set letter [string tolower [string index $OKname 0]] catch { bind $w <Alt-$letter> "tkButtonInvoke $w.buts.ok" lappend letterbindings $letter "tkButtonInvoke $w.buts.ok" } focus $w.buts.ok } elseif { $Cancelname != "-" } { focus $w.buts.cancel } if { $Cancelname != "-" } { bind $w <Escape> "tkButtonInvoke $w.buts.cancel" bind $w.buts.cancel <Return> "tkButtonInvoke $w.buts.cancel" set letter [string tolower [string index $CancelName $underlinecancel]] catch { bind $w <Alt-$letter> "tkButtonInvoke $w.buts.cancel" lappend letterbindings $letter "tkButtonInvoke $w.buts.cancel" } wm protocol $w WM_DELETE_WINDOW "tkButtonInvoke $w.buts.cancel" } elseif { $OKname != "-" } { bind $w <Escape> "tkButtonInvoke $w.buts.ok" wm protocol $w WM_DELETE_WINDOW "tkButtonInvoke $w.buts.ok" } else { bind $w <Escape> "tkButtonInvoke $w.buts.b0" wm protocol $w WM_DELETE_WINDOW "tkButtonInvoke $w.buts.b0" } bind $w <Destroy> { if { [winfo class %W] == "Toplevel" } { DialogWinTop::DestroyWindow %W } } foreach but [winfo children $w.buts] { foreach "letter command" $letterbindings { bind $but <KeyPress-$letter> $command } } grid columnconf $w 0 -weight 1 grid rowconf $w 0 -weight 1 return $w.f } proc DialogWinTop::DestroyWindow { w } { variable oldGrab variable grabStatus variable taborder if { [info exists taborder($w)] } { unset taborder($w) } if {[string compare $oldGrab ""]} { if {[string compare $grabStatus "global"]} { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab $oldGrab } } else { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab -global $oldGrab } } } } proc lreverse L { set res {} set i [llength $L] while {$i} {lappend res [lindex $L [incr i -1]]} set res } proc DialogWinTop::TabOrderPrevNext { w what } { variable taborder set tabo $taborder([winfo toplevel $w]) set ipos [lsearch $tabo $w] set tabo [concat [lrange $tabo [expr {$ipos+1}] end] [lrange $tabo 0 [expr {$ipos-1}]]] if { $what eq "prev" } { set tabo [lreverse $tabo] } foreach w $tabo { if { [tk::FocusOK $w] } { tk::TabToWindow $w return } } return } proc DialogWinTop::SetTabOrder { winlist } { variable taborder set top [winfo toplevel [lindex $winlist 0]] set taborder($top) $winlist foreach w $winlist { bind $w <Tab> "DialogWinTop::TabOrderPrevNext $w next; break" bind $w <<PrevWindow>> "DialogWinTop::TabOrderPrevNext $w prev; break" } } proc DialogWinTop::InvokeOK { f } { if { ![winfo exists $f] } { return } set w [winfo toplevel $f] tkButtonInvoke $w.buts.ok } proc DialogWinTop::InvokeCancel { f { visible 1 } } { variable w if { ![winfo exists $f] } { return } set w [winfo toplevel $f] if { $visible } { tkButtonInvoke $w.buts.cancel } else { $w.buts.cancel invoke } } proc DialogWinTop::InvokeButton { f num { visible 1 } } { if { ![winfo exists $f] } { return } set w [winfo toplevel $f] if { $num < 2 } { WarnWin "DialogWinTop::InvokeButton num>2" return } if { $visible } { tkButtonInvoke $w.buts.b[expr $num-1] } else { $w.buts.b[expr $num-1] invoke } } proc DialogWinTop::FocusButton { f num } { set w [winfo toplevel $f] if { $num < 2 } { WarnWin "DialogWinTop::FocusButton num>2" return } foreach i [winfo children $w.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { focus $i return } } WarnWin "DialogWinTop::FocusButton num bad" } # what= 0 disable ; =1 enable proc DialogWinTop::EnableDisableButton { f name what } { variable w set w [winfo toplevel $f] foreach i [winfo children $w.buts] { if { $name == [$i cget -text] } { switch $what { 1 { $i conf -state normal } 0 { $i conf -state disabled } } return } } WarnWin "DialogWin::EnableDisableButton name bad" } proc DialogWinTop::CreateWindow { f { geom "" } { minwidth "" } { minheight "" } { grab 0 } } { variable oldGrab variable grabStatus set w [winfo parent $f] set top [winfo toplevel [winfo parent $w]] wm withdraw $w update idletasks if { $geom != "" } { wm geom $w $geom } else { if { $minwidth != "" && [winfo reqwidth $w] < $minwidth } { set width $minwidth } else { set width [winfo reqwidth $w] } if { $minheight != "" && [winfo reqheight $w] < $minheight } { set height $minheight } else { set height [winfo reqheight $w] } if { [wm state $top] == "withdrawn" } { set x [expr [winfo screenwidth $top]/2-$width/2] set y [expr [winfo screenheight $top]/2-$height/2] } else { set x [expr [winfo x $top]+[winfo width $top]/2-$width/2] set y [expr [winfo y $top]+[winfo height $top]/2-$height/2] } if { $x < 0 } { set x 0 } if { $y < 0 } { set y 0 } wm geom $w ${width}x${height}+${x}+$y } wm deiconify $w update idletasks #wm geom $w [wm geom $w] if {!$grab } { set oldGrab "" set grabStatus "" } else { set oldGrab [grab current $w] if {[string compare $oldGrab ""]} { set grabStatus [grab status $oldGrab] grab release $oldGrab } grab $w } focus $w } # proc DialogWin::messageBox { args } { # if { [info exists DialogWin2::w] } { # after 500 [list DialogWin::messageBox $args] # return # } # CopyNamespace ::DialogWin ::DialogWin2 # array set opts [list -default "" -icon question-32.png -message "" -parent . -title "" \ # -type ok] # for { set i 0 } { $i < [llength $args] } { incr i } { # set opt [lindex $args $i] # if { ![info exists opts($opt)] } { # error "unknown option '$opt' in DialogWin::messageBox" # } # incr i # set opts($opt) [lindex $args $i] # } # switch -- $opts(-type) { # abortretryignore { # set buts [list Abort Retry Ignore] # } # ok { # set buts [list OK] # } # okcancel { # set buts [list OK Cancel] # } # retrycancel { # set buts [list Retry Cancel] # } # yesno { # set buts [list Yes No] # } # yesnocancel { # set buts [list Yes No Cancel] # } # default { # error "unknown type: '$opts(-type)' in DialogWin::messageBox" # } # } # if { $opts(-default) == "" } { # set opts(-defaultpos) 0 # } else { # set opts(-defaultpos) [lsearch -regexp $buts "(?iq)$opts(-default)"] # if { $opts(-defaultpos) == -1 } { # error "bad default option: '$opts(-default)' in DialogWin::messageBox" # } # } # set f [DialogWin2::Init $opts(-parent) $opts(-title) separator $buts - -] # set w [winfo toplevel $f] # label $f.l1 -image [GetImage question-32.png] -grid 0 # label $f.msg -justify left -text $opts(-message) -wraplength 3i -grid "1 px5 py5" # supergrid::go $f # DialogWin2::FocusButton [expr $opts(-defaultpos)+2] # set action [DialogWin2::CreateWindow] # while 1 { # switch -- $action { # -1 { # if { [lsearch $buts Cancel] != -1 } { # catch { # DialogWin2::DestroyWindow # namespace delete ::DialogWin2 # } # return cancel # } # if { [lsearch $buts OK] != -1 } { # DialogWin2::DestroyWindow # namespace delete ::DialogWin2 # return ok # } # } # default { # DialogWin2::DestroyWindow # namespace delete ::DialogWin2 # return [string tolower [lindex $buts [expr $action-2]]] # } # } # set action [DialogWin2::WaitForWindow] # } # } # for compatibility proc DialogWin::messageBox { args } { #return [eval DialogWinTop::messageBox $args] return [eval snit_messageBox $args] } proc DialogWinTop::messageBox { args } { return [eval snit_messageBox $args] } proc MessageWin { text title {image question-32.png} {parent .} {check_no_more 1}} { if { $parent eq "." } { set parent "" } set w [dialogwin_snit $parent.%AUTO% -title $title -okname \ [_ "Ok"] -cancelname "-"] set f [$w giveframe] ttk::label $f.l1 -image [GetImage $image] ttk::label $f.msg -justify left -text $text -wraplength 3i set ::MessageWin_skip_more_windows 0 if { $check_no_more} { ttk::checkbutton $f.cb -text [_ "Skip this window"] -offvalue 0 -onvalue 1 \ -variable ::MessageWin_skip_more_windows } grid $f.l1 $f.msg -sticky nw grid configure $f.msg -padx 5 -pady 5 if { $check_no_more} { grid $f.cb -sticky nw -padx 5 \ -column 1 # -columnspan 2 } set action [$w createwindow] destroy $w return $::MessageWin_skip_more_windows } proc WarnWin { text {parent .} {id 0} {title ""} } { #puts $::errorInfo # WarnWinText "$id: before MessageWin" set check_no_more 0 if { $id != 0} { set check_no_more 1 } if { ![ info exists ::GidPriv(MessageWin,NoMoreModal$id)]} { set ::GidPriv(MessageWin,NoMoreModal$id) 0 } if { $::GidPriv(MessageWin,NoMoreModal$id) } { WarnWinText "Warning: $text" set ret 1 } else { if {$title eq ""} { set title [_ "Warning"] } set ret [ MessageWin $text $title question-32.png $parent $check_no_more] set ::GidPriv(MessageWin,NoMoreModal$id) $ret } # WarnWinText "$id: after MessageWin: ret=$ret=" } proc InfoWin { text {parent .} {id 0}} { # WarnWinText "$id: before MessageWin" set check_no_more 0 if { $id != 0} { set check_no_more 1 } if { ![ info exists ::GidPriv(MessageWin,NoMoreModal$id)]} { set ::GidPriv(MessageWin,NoMoreModal$id) 0 } if { $::GidPriv(MessageWin,NoMoreModal$id) } { WarnWinText "Warning: $text" set ret 1 } else { set ret [ MessageWin $text [_ "Warning"] info-32.png $parent $check_no_more] set ::GidPriv(MessageWin,NoMoreModal$id) $ret } # WarnWinText "$id: after MessageWin: ret=$ret=" } proc CreateWarnWinId { text} { set total_sum 0 set check_sum 0 for { set i 0} { $i < [ string length $text]} { incr i} { set char [ string index $i] set total_sum [ expr $total_sum + $char] set check_sum [ expr $check_sum ^ $char] } set window_id [ expr ( ( $total_sum & 0xffffff) << 8) | $check_sum] return $window_id } proc ResetNoMoreChecks {} { foreach idx [ array names ::GidPriv MessageWin,NoMoreModal*] { unset ::GidPriv($idx) } } proc WarnWin_hideerror { text errordata { parent .} } { if { $parent eq "." } { set parent "" } set w [dialogwin_snit $parent.%AUTO% -title [_ Warning] -okname [_ Ok] \ -cancelname -] set f [$w giveframe] ttk::label $f.l1 -image [GetImage question-32.png] ttk::label $f.msg -justify left -text $text -wraplength 3i grid $f.l1 $f.msg -sticky nw grid configure $f.msg -padx 5 -pady 5 bind $w <2> [list error $text $errordata] set action [$w createwindow] destroy $w } proc snit_messageBox { args } { array set opts [list -default "" -icon question-32.png -message "" -parent . -title "" \ -type ok -do_not_ask_again 0 -do_not_ask_again_key "" -accdict ""] for { set i 0 } { $i < [llength $args] } { incr i } { set opt [lindex $args $i] if { ![info exists opts($opt)] } { error [_ "unknown option '%s' in snit_messageBox" $opt] } incr i set opts($opt) [lindex $args $i] } if { $opts(-do_not_ask_again) } { if { $opts(-type) ni "ok okcancel yesno yesnocancel" } { error "error. option -do_not_ask_again can only be used for types 'ok','okcancel','yesno' and 'yesnocancel'" } set d [dialogwin_snit give_typeuservar_value do_not_ask_again ""] if { $opts(-do_not_ask_again_key) eq "" } { set opts(-do_not_ask_again_key) $opts(-message) } if { [dict exists $d $opts(-do_not_ask_again_key)] } { return [dict get $d $opts(-do_not_ask_again_key)] } } switch -- $opts(-type) { abortretryignore { set retbuts [list abort retry ignore] set buts [list [_ Abort] [_ Retry] [_ Ignore]] } ok { set retbuts [list ok] set buts [list [_ OK]] } okcancel { set retbuts [list ok cancel] set buts [list [_ OK] [_ Cancel]] } retrycancel { set retbuts [list retry cancel] set buts [list [_ Retry] [_ Cancel]] } yesno { set retbuts [list yes no] set buts [list [_ Yes] [_ No]] } yesnocancel { set retbuts [list yes no cancel] set buts [list [_ Yes] [_ No] [_ Cancel]] } default { error [_ "unknown type: '%s' in snit_messageBox" $opts(-type)] } } if { $opts(-default) == "" } { set opts(-defaultpos) 0 } else { set opts(-defaultpos) [lsearch -regexp $retbuts "(?iq)$opts(-default)"] if { $opts(-defaultpos) == -1 } { error [_ "bad default option: '%s' in snit_messageBox" $opts(-default)] } } if { $opts(-parent) eq "." } { set w .%AUTO% } else { set w $opts(-parent).%AUTO% } set w [dialogwin_snit $w -title $opts(-title) -morebuttons $buts \ -okname - -cancelname - -transient 1] set f [$w giveframe] set icons [dict create \ question "question-32.png" \ warning "warning-32.png" \ error "error-32.png" \ info "info-32.png"] if { [dict exists $icons $opts(-icon)] } { set opts(-icon) [dict get $icons $opts(-icon)] } ttk::label $f.l1 -image [GetImage $opts(-icon)] if { [winfo screenwidth .] < 300 } { set wraplength 1.5i } else { set wraplength 3i } ttk::label $f.msg -justify left -text $opts(-message) -wraplength $wraplength grid $f.l1 $f.msg -sticky nw grid configure $f.msg -padx 5 -pady 5 if { $opts(-do_not_ask_again) } { ttk::checkbutton $f.cb1 -text [_ "Do not show again for this session"] -variable \ [$w give_uservar do_not_ask_again 0] grid $f.cb1 - -sticky w } dict for "binding but" $opts(-accdict) { set pos [lsearch -regexp $retbuts "(?iq)$but"] if { $pos == -1 } { error [_ "bad binding option button: '%s' in snit_messageBox" $but] } bind $w $binding [list $w invokebutton [expr {$pos+2}] 0] } $w focusbutton [expr $opts(-defaultpos)+2] set action [$w createwindow] if { $opts(-do_not_ask_again) && [$w give_uservar_value do_not_ask_again] } { set do_not_ask_again 1 } else { set do_not_ask_again 0 } destroy $w switch -- $action { -1 - 0 { if { [lsearch -exact $buts [_ Cancel]] != -1 } { return cancel } return [lindex $retbuts end] } default { set ipos [expr {$action-2}] if { [lindex $retbuts $ipos] ne "cancel" && $do_not_ask_again } { set d [dialogwin_snit give_typeuservar_value do_not_ask_again ""] if { $opts(-do_not_ask_again_key) eq "" } { set opts(-do_not_ask_again_key) $opts(-message) } dict set d $opts(-do_not_ask_again_key) [lindex $retbuts $ipos] dialogwin_snit set_typeuservar_value do_not_ask_again $d } return [lindex $retbuts $ipos] } } } proc tk_dialog_snit {w title text textsmall bitmap image default args} { if { $w == "" } { set parent "." } else { regsub {[.][^.]*$} $w {} parent } if {$parent == ""} { set parent "." } return [eval [list tk_dialog_snit1 $parent $title $text $textsmall $image $default] \ $args] } proc tk_dialog_snit1 { parent title text textsmall image default args} { if { $parent eq "." } { set w .%AUTO% } else { set w $parent.%AUTO% } set w [dialogwin_snit $w -title $title -morebuttons $args \ -okname - -cancelname -] set f [$w giveframe] label $f.l1 -image $image label $f.msg -justify left -text $text -wraplength 3i grid $f.l1 $f.msg -sticky nw grid configure $f.msg -padx 5 -pady 5 if { $textsmall ne "" } { set size [expr {[font actual [$f.msg cget -font] -size]-2}] label $f.ts -text $textsmall -font "-size $size" grid $f.ts - sticky nw } $w focusbutton [expr $default+2] set action [$w createwindow] destroy $w switch -- $action { -1 - 0 { return -1 } default { return [expr {$action-2}] } } } #-------------------------------------------------------------------------------- # dialogwin_snit #-------------------------------------------------------------------------------- # NOTE: examples at the end # style: ridgeframe or separator # entrytype: entry or noneditable_entry or password # -callback: calls function when user presses a button. Adds argument $w snit::widget dialogwin_snit { option -title "" option -style separator option -grab 1 option -transient 0 option -callback "" option -morebuttons "" option -okname "" option -cancelname "" option -geometry "" option -minwidth "" option -minheight "" option -entrytype "" ;# entry,password,noneditable_entry option -entrytext "" option -entrylabel "" option -entrydefault "" option -entryvalues "" option -repeat_answer_check 0 option -frame_grid_cmd "" option -toplevel_cmd "" option -show_frame_toplevel_toggle 1 option -frame_toplevel toplevel option -topbuttons 0 option -dockmenu "" if { $::tcl_platform(os) ne "Darwin" } { hulltype frame } else { hulltype toplevel } delegate method * to hull delegate option * to hull variable action -1 variable oldGrab "" variable oldFocus "" variable grabStatus variable entryvalue variable repeat_my_answer 0 variable uservar variable typeuservar variable traces "" variable destroy_handlers "" constructor args { $self configurelist $args if { $options(-frame_toplevel) eq "toplevel" } { if { $::tcl_platform(os) ne "Darwin" } { wm manage $win } wm withdraw $win } if {0&& [info commands ttk::button] eq "" } { set button_cmd button set label_cmd label set entry_cmd entry set combo_cmd ComboBox set frame_cmd frame set checkbutton_cmd checkbutton set radiobutton_cmd radiobutton } else { set button_cmd ttk::button set label_cmd ttk::label set entry_cmd ttk::entry set combo_cmd ttk::combobox set frame_cmd ttk::frame set checkbutton_cmd ttk::checkbutton set radiobutton_cmd ttk::radiobutton } if { $options(-okname) eq "" } { set options(-okname) [_ "Ok"] } if { $options(-cancelname) eq "" } { set options(-cancelname) [_ "Cancel"] if { $options(-okname) eq "-" && $options(-morebuttons) eq "" } { set options(-cancelname) [_ "Close"] } } if { $options(-frame_grid_cmd) eq "" } { set show_frame_toplevel_toggle 0 set topbuttons 0 } else { set show_frame_toplevel_toggle $options(-show_frame_toplevel_toggle) set topbuttons $options(-topbuttons) } set current_row -1 if { $topbuttons || $show_frame_toplevel_toggle } { ttk::frame $win.f0 if { $show_frame_toplevel_toggle } { frame $win.f0.c -background #880000 -bd 1 -relief solid -height 4 \ -cursor hand2 bind $win.f0.c <ButtonRelease-1> [mymethod toogle_frame_toplevel] bind $win.f0.c <ButtonRelease-3> [mymethod contextual_dock_menu %X %Y] tooltip::tooltip $win.f0.c [_ "Press here to dock or undock the window"] grid $win.f0.c -sticky ew -row 0 -column 0 } grid columnconfigure $win.f0 0 -weight 1 if { $options(-topbuttons) } { ttk::frame $win.f0.buts set col 0 if { $options(-okname) ne "-" } { ttk::button $win.f0.buts.b1 -image img::ok-16 -command [mymethod _applyaction 1] \ -style Toolbutton tooltip::tooltip $win.f0.buts.b1 $options(-okname) grid $win.f0.buts.b1 -row 0 -column $col incr col } if { [llength $options(-morebuttons)] == 1 } { $win.f0.buts.b1 configure -image img::ok-close-16 ttk::button $win.f0.buts.b2 -image img::ok-16 -command [mymethod _applyaction 2] \ -style Toolbutton tooltip::tooltip $win.f0.buts.b2 [lindex $options(-morebuttons) 0] grid $win.f0.buts.b2 -row 0 -column $col incr col } elseif { [llength $options(-morebuttons)] } { ttk::menubutton $win.f0.buts.b2 -image img::nav1downarrow16 -menu $win.f0.buts.b2.m \ -style Toolbutton menu $win.f0.buts.b2.m -tearoff 0 set iaction 2 foreach txt $options(-morebuttons) { $win.f0.buts.b2.m add command -label $txt -command [mymethod _applyaction $iaction] incr iaction } grid $win.f0.buts.b2 -row 0 -column $col incr col } if { $options(-cancelname) ne "-" } { ttk::button $win.f0.buts.b3 -image img::fileclose16 -command [mymethod _applyaction 0] \ -style Toolbutton tooltip::tooltip $win.f0.buts.b3 $options(-cancelname) grid $win.f0.buts.b3 -row 0 -column $col incr col } grid $win.f0.buts -row 0 -column 1 -sticky e -sticky ew } grid $win.f0 -sticky ew -padx 2 -pady 0 incr current_row } else { set options(-topbuttons) 0 } switch $options(-style) { ridgeframe { $frame_cmd $win.f catch { $win.f configure -relief ridge -bd 2 } frame $win.buts grid $win.f -sticky ewns -padx 2 -pady 2 incr current_row grid $win.buts -sticky ew catch { grid anchor $win.buts center } } separator - separator_right { $frame_cmd $win.f catch { $win.f configure -bd 0 } frame $win.sep -bd 2 -relief raised -height 2 frame $win.buts grid $win.f -sticky ewns -padx 2 -pady 2 incr current_row grid $win.sep -sticky ew grid $win.buts -sticky ew catch { grid anchor $win.buts center } } default { error "error: only accepted styles ridgeframe and separator" } } $win.buts conf -background [CCColorActivo [$win cget -background]] grid columnconfigure $win 0 -weight 1 grid rowconfigure $win $current_row -weight 1 set butwidth 7 if { [string length $options(-okname)] > $butwidth } { set butwidth [string length $options(-okname)] } if { [string length $options(-cancelname)] > $butwidth } { set butwidth [string length $options(-cancelname)] } foreach i $options(-morebuttons) { if { [string length $i] > $butwidth } { set butwidth [string length $i] } } # if { [catch { package present tile }] == 0 } { # set butwidth [expr {-1*$butwidth}] # } set butwidth [expr {-1*$butwidth}] set usedletters "" if { $options(-okname) != "-" } { for { set ipos 0 } { $ipos < [string length $options(-okname)] } { incr ipos } { set letter [string tolower [string index $options(-okname) $ipos]] if { [regexp {[a-zA-Z]} $letter] && [lsearch $usedletters $letter] == -1 } { break } } if { $ipos < [string length $options(-okname)] } { $button_cmd $win.buts.ok -text $options(-okname) -width $butwidth -und $ipos -command \ [mymethod _applyaction 1] bind $win <Alt-$letter> [mymethod _button_invoke $win.buts.ok] bind $win.buts.ok <Return> "[mymethod _button_invoke $win.buts.ok] ;break" lappend usedletters $letter set widget($letter) $win.buts.ok } else { $button_cmd $win.buts.ok -text $options(-okname) -width $butwidth -command \ [mymethod _applyaction 1] } } if { $options(-cancelname) ne "-" } { for { set ipos 0 } { $ipos < [string length $options(-cancelname)] } { incr ipos } { set letter [string tolower [string index $options(-cancelname) $ipos]] if { [regexp {[a-zA-Z]} $letter] && [lsearch $usedletters $letter] == -1 } { break } } if { $ipos < [string length $options(-cancelname)] } { set underlinecancel $ipos lappend usedletters [string tolower [string index $options(-cancelname) $ipos]] } else { set underlinecancel "" } } set togrid "" set iaction 2 foreach i $options(-morebuttons) { for { set ipos 0 } { $ipos < [string length $i] } { incr ipos } { set letter [string tolower [string index $i $ipos]] if { [regexp {[a-zA-Z]} $letter] && [lsearch $usedletters $letter] == -1 } { break } } if { $ipos < [string length $i] } { $button_cmd $win.buts.b$iaction -text $i -width $butwidth -und $ipos \ -command [mymethod _applyaction $iaction] bind $win <Alt-$letter> [mymethod _button_invoke $win.buts.b$iaction] bind $win.buts.b$iaction <Return> "[mymethod _button_invoke $win.buts.b$iaction] ;break" lappend usedletters $letter set widget($letter) $win.buts.b$iaction } else { $button_cmd $win.buts.b$iaction -text $i -width $butwidth \ -command [mymethod _applyaction $iaction] } lappend togrid $win.buts.b$iaction incr iaction } if { $options(-cancelname) ne "-" } { if { $underlinecancel != "" } { $button_cmd $win.buts.cancel -text $options(-cancelname) -width $butwidth \ -und $underlinecancel -command [mymethod _applyaction 0] set letter [string tolower [string index $options(-cancelname) $underlinecancel]] bind $win <Alt-$letter> [mymethod _button_invoke $win.buts.cancel] bind $win.buts.cancel <Return> "[mymethod _button_invoke $win.buts.cancel] ;break" set widget($letter) $win.buts.cancel } else { $button_cmd $win.buts.cancel -text $options(-cancelname) -width $butwidth \ -command [mymethod _applyaction 0] } } if { $options(-okname) ne "-" } { set togrid "$win.buts.ok $togrid" } if { $options(-cancelname) ne "-" } { set togrid "$togrid $win.buts.cancel" } if { $options(-repeat_answer_check) } { checkbutton $win.buts.repeat -text [_ "Repeat my answer"] \ -variable [myvar repeat_my_answer] $win.buts.repeat configure -background [CCColorActivo [$win cget -background]] } if { [llength $togrid] } { grid {*}$togrid -padx 2 -pady 4 } else { catch { grid forget $win.buts grid forget $win.sep } } if { $options(-repeat_answer_check) } { grid {*}$togrid -row 1 grid $win.buts.repeat {*}[lrepeat [expr {[llength $togrid]-1}] -] \ -sticky w -padx 2 -pady 2 -row 0 # grid $win.buts.repeat -row 0 -column [llength $togrid] -sticky w -padx 2 # grid $win.buts.repeat {*}[lrepeat [expr {[llength $togrid]-1}] -] \ # -sticky w -padx 2 -pady 2 } switch -- $options(-style) { "separator_right" { grid configure {*}$togrid -sticky e grid columnconfigure $win.buts 0 -weight 1 } } if { $options(-okname) != "-" } { focus $win.buts.ok } elseif { $options(-cancelname) != "-" } { focus $win.buts.cancel } foreach i $togrid { foreach letter $usedletters { bind $i <Key-$letter> [mymethod _button_invoke $widget($letter)] bind $i <Control-$letter> { continue } } } if { $options(-cancelname) ne "-" } { bind $win <Escape> [mymethod _button_invoke $win.buts.cancel] bind $win.buts.cancel <Return> "[mymethod _button_invoke $win.buts.cancel] ;break" if { $options(-frame_toplevel) eq "toplevel" } { wm protocol $win WM_DELETE_WINDOW [mymethod _button_invoke $win.buts.cancel] } } else { bind $win <Escape> [mymethod _applyaction -1] if { $options(-frame_toplevel) eq "toplevel" } { wm protocol $win WM_DELETE_WINDOW [mymethod _applyaction -1] } } if { $options(-entrytext) ne "" } { if { [winfo screenwidth .] < 300 } { set wraplength 100 } else { set wraplength 300 } $label_cmd $win.f.l0 -text $options(-entrytext) -wraplength $wraplength \ -justify left grid $win.f.l0 - -sticky w -pady "2 5" } if { $options(-entrytype) ne "" } { $label_cmd $win.f.l -text $options(-entrylabel) switch $options(-entrytype) { entry { if { $options(-entryvalues) eq "" } { $entry_cmd $win.f.e -textvariable [varname entryvalue] -width 40 } else { $combo_cmd $win.f.e -textvariable [varname entryvalue] -width 40 \ -values $options(-entryvalues) } } password { $entry_cmd $win.f.e -textvariable [varname entryvalue] -width 40 -show * } noneditable_entry { if { [llength $options(-entryvalues)] == 2 && [string is boolean [lindex $options(-entryvalues) 0]] && [string is boolean [lindex $options(-entryvalues) 1]] } { destroy $win.f.l $checkbutton_cmd $win.f.l -text $options(-entrylabel) -variable [varname entryvalue] $frame_cmd $win.f.e } elseif { [llength $options(-entryvalues)] <= 5 } { set fr [$frame_cmd $win.f.e] set idx 0 foreach i $options(-entryvalues) { $radiobutton_cmd $fr.r$idx -text $i -variable [varname entryvalue] \ -value $i grid $fr.r$idx -sticky w -padx 2 -pady 2 incr idx } } else { $combo_cmd $win.f.e -textvariable [varname entryvalue] -width 40 \ -values $options(-entryvalues) -state readonly } } } set entryvalue $options(-entrydefault) grid $win.f.l $win.f.e -sticky w -padx 3 -pady 3 grid configure $win.f.e -sticky ew grid columnconfigure $win.f 1 -weight 1 if { [winfo exists $win.f.l0] } { update idletasks $win.f.l0 configure -wraplength [expr {[winfo reqwidth $win.f]-5}] } if { [winfo class $win.f.e] ni "TFrame Frame" } { tk::TabToWindow $win.f.e } bind $win <Return> [mymethod invokeok] } } destructor { set action -1 if { $oldGrab ne "" } { if { [info exists grabStatus] && $grabStatus ne "global" } { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab $oldGrab } } else { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab -global $oldGrab } } } catch { focus $oldFocus } foreach i $traces { trace remove variable {*}$i } foreach i $destroy_handlers { uplevel #0 $i } } onconfigure -title {value} { set options(-title) $value if { $options(-frame_toplevel) eq "toplevel" } { # catch is here as win is a frame in some cases catch { wm title $win $options(-title) } } } method giveframe {} { return $win.f } method giveframe_background {} { set err [catch { $win.f cget -background } bg] if { $err } { set style [$win.f cget -style] if { $style eq "" } { set style [winfo class $win.f] } set err [catch { ttk::style lookup $style -background } bg] if { $err } { set bg white } } return $bg } method invokeok { { visible 1 } } { if { ![winfo exists $win.buts.ok] } { return } if { $visible } { $self _button_invoke $win.buts.ok } else { $win.buts.ok invoke } } method invokecancel { { visible 1 } } { if { ![winfo exists $win.buts.cancel] } { return } if { $visible } { $self _button_invoke $win.buts.cancel } else { $win.buts.cancel invoke } } method invokebutton { num { visible 1 } } { if { ![winfo exists $win.buts] } { return } if { $num < 2 } { error "error in dialogwin_snit invokebutton num<2" } foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { if { $visible } { $self _button_invoke $i } else { $i invoke } return } } error "error in dialogwin_snit invokebutton num bad" } method focusok {} { if { ![winfo exists $win.buts.ok] } { return } focus $win.buts.ok } method focuscancel {} { if { ![winfo exists $win.buts.cancel] } { return } focus $win.buts.cancel } method focusbutton { num } { if { $num < 2 } { error "error in dialogwin_snit focusbutton num must be > 2" } foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { focus $i return } } error "error in dialogwin_snit focusbutton num bad" } method enableok {} { if { ![winfo exists $win.buts.ok] } { return } $win.buts.ok configure -state normal } method enablecancel {} { if { ![winfo exists $win.buts.cancel] } { return } $win.buts.cancel configure -state normal } method enablebutton { num } { if { $num < 2 } { error "error in dialogwin_snit enablebutton num must be > 2" } foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { $i configure -state normal return } } error "error in dialogwin_snit enablebutton num bad" } method disableok {} { if { ![winfo exists $win.buts.ok] } { return } $win.buts.ok configure -state disabled } method disablecancel {} { if { ![winfo exists $win.buts.cancel] } { return } $win.buts.cancel configure -state disabled } method disablebutton { num } { if { $num < 2 } { error "error in dialogwin_snit disablebutton num must be > 2" } foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { $i configure -state disabled return } } error "error in dialogwin_snit disablebutton num bad" } method _button_invoke { w } { if { [winfo class $w] eq "TButton" } { $w instate !disabled { $w state pressed update idletasks after 100 $w state !pressed update idletasks uplevel #0 [list $w invoke] } } else { if {[$w cget -state] ne "disabled"} { set oldRelief [$w cget -relief] set oldState [$w cget -state] $w configure -state active -relief sunken update idletasks after 100 $w configure -state $oldState -relief $oldRelief uplevel #0 [list $w invoke] } } } method changebuttonoptions { num args } { if { $num == 0 } { eval [list $win.buts.cancel configure] $args } elseif { $num == 1 } { eval [list $win.buts.ok configure] $args } else { foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { eval [list $i configure] $args return } } error "error in dialogwin_snit changebuttonoptions num bad" } } method changebuttongridoptions { num args } { if { $num == 0 } { eval [list grid configure $win.buts.cancel] $args } elseif { $num == 1 } { eval [list grid configure $win.buts.ok] $args } else { foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { eval [list grid configure $i] $args return } } error "error in dialogwin_snit changebuttongridoptions num bad" } } method showhidebutton { num what } { if { $num == 0 } { set b $win.buts.cancel } elseif { $num == 1 } { set b $win.buts.ok } else { foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { set b $i break } } } switch $what { show { grid $b } hide { set i [grid info $b] if { $i eq "" } { return } grid columnconfigure $win.buts [dict get $i -column] \ -minsize [winfo width $b] grid remove $b } } } method contextual_dock_menu { x y } { destroy $win.dockmenu set menu [menu $win.dockmenu -tearoff 0] $menu add command -label [_ "Toggle dock/undock"] -command \ [mymethod toogle_frame_toplevel] if { $options(-dockmenu) ne "" } { $menu add separator foreach d $options(-dockmenu) { $menu add {*}$d } } tk_popup $menu $x $y 0 } method tooltip_button { num args } { package require tooltip if { $num == 0 } { set b $win.buts.cancel } elseif { $num == 1 } { set b $win.buts.ok } else { foreach i [winfo children $win.buts] { if { [regexp "\\m$num\\M" [$i cget -command]] } { set b $i break } } } if { [llength $args] == 1 } { tooltip::tooltip $b [lindex $args 0] } elseif { [llength $args] > 1 } { error "error in tooltip_button arguments" } return [tooltip::tooltip $b] } method createwindow {} { $self createwindownowait if { ![winfo exists $win] } { return } return [$self waitforwindow 0] } method toogle_frame_toplevel {} { switch $options(-frame_toplevel) { toplevel { set options(-frame_toplevel) frame } frame { set options(-frame_toplevel) toplevel } } $self createwindow } method createwindownowait {} { if { $options(-frame_toplevel) eq "toplevel" } { $self createwindownowait_as_toplevel } else { $self createwindownowait_as_frame } } method createwindownowait_as_frame {} { if { [winfo exists $win.f0.buts] } { if { [winfo exists $win.sep] } { grid remove $win.sep } grid remove $win.buts grid $win.f0.buts } $win configure -bd 1 -relief ridge update idletasks wm forget $win focus $win set err [catch { uplevel #0 $options(-frame_grid_cmd) }] if { $err } { after idle [list $self createwindownowait_as_toplevel] } } method createwindownowait_as_toplevel {} { set parent [winfo parent $win] set top [winfo toplevel $parent] if { $::tcl_platform(os) ne "Darwin" } { wm manage $win } wm withdraw $win update if { ![winfo exists $win] } { return } wm title $win $options(-title) if { $::tcl_platform(os) eq "Windows CE" } { bind $win <ConfigureRequest> { if { "%W" eq [winfo toplevel %W] } { etcl::autofit %W }} bind $win <Expose> { if { "%W" eq [winfo toplevel %W] } { etcl::autofit %W }} } #update idletasks if { [winfo exists $win.f0.buts] } { if { [winfo exists $win.sep] } { grid $win.sep } grid $win.buts grid remove $win.f0.buts } lassign "" width height x y if { [catch { package present twapi }] == 0 } { lassign [twapi::get_desktop_workarea] scr_x scr_y scr_w scr_h set scr_w [expr {$scr_w-$scr_x}] set scr_h [expr {$scr_h-$scr_y}] } else { lassign [list 0 0 [winfo screenwidth $top] [winfo screenheight $top]] \ scr_x scr_y scr_w scr_h } if { $options(-geometry) ne "" && $options(-geometry) ne "zoomed" } { if { ![regexp {(\d+)x(\d+)(?:\+([-\d]+)\+([-\d]+))?} \ $options(-geometry) {} width height x y] } { regexp {^\+([-\d]+)\+([-\d]+)$} \ $options(-geometry) {} x y } } if { $width eq "" || $height eq "" } { if { $options(-minwidth) != "" && [winfo reqwidth $win] < $options(-minwidth) } { set width $options(-minwidth) } else { set width [winfo reqwidth $win] } if { $options(-minheight) != "" && [winfo reqheight $win] < $options(-minheight) } { set height $options(-minheight) } else { set height [winfo reqheight $win] } if { $width > $scr_w } { set width $scr_w } if { $height > $scr_h } { set height $scr_h } } if { $x eq "" || $y eq "" } { set big 0 if { $width > .8*$scr_w } { set big 1 } if { $height > .8*$scr_h } { set big 1 } if { $big || [wm state $top] == "withdrawn" } { set x [expr {$scr_x+$scr_w/2-$width/2}] set y [expr {$scr_y+$scr_h/2-$height/2}] } else { set x [expr [winfo rootx $parent]+[winfo width $parent]/2-$width/2] set y [expr [winfo rooty $parent]+[winfo height $parent]/2-$height/2] } if { $x+$width > $scr_w+$scr_x } { set x [expr {$scr_x+$scr_w-$width}] } if { $y+$height > $scr_h+$scr_y } { set y [expr {$scr_y+$scr_h-$height}] } if { $x < 0 } { set x 0 } if { $width > $scr_w } { set width $scr_w } set err [catch { package present wce }] if { !$err } { foreach "x0 y0 x1 y1" [wce sipinfo] break if { $y < $y0 } { set y $y0 } if { $height > $y1-$y0 } { set height [expr {$y1-$y0}] } } else { if { $y < 0 } { set y 0 } if { $height > $scr_h } { set height $scr_h } } } wm geometry $win ${width}x${height}+${x}+$y if { $options(-transient) } { if { [wm state $top] ne "withdrawn" } { wm transient $win $parent } if { $::tcl_platform(platform) eq "unix" } { wm attributes $win -type dialog } } update if { ![winfo exists $win] } { return } # this is necessary because with just one geometry is does not work always ok wm geometry $win ${width}x${height}+${x}+$y wm deiconify $win update idletasks wm geometry $win [wm geometry $win] set oldFocus [focus -displayof $win] focus $win if { $options(-grab) } { set oldGrab [grab current $win] if { $oldGrab ne "" && [winfo exists $oldGrab] } { set grabStatus [grab status $oldGrab] grab release $oldGrab } catch { grab $win } } else { set oldGrab "" } update if { ![winfo exists $win] } { return } set focus [focus -lastfor $win] if { $focus ne "" } { tk::TabToWindow $focus } if { $focus eq "" } { set focus $win } focus -force $focus if { $options(-toplevel_cmd) ne "" } { uplevel #0 $options(-toplevel_cmd) } } method _applyaction { value } { set action $value if { $options(-callback) ne "" } { uplevel #0 $options(-callback) $win } } method giveaction {} { return $action } method waitforwindow { { raise 0 } } { if { $raise == "" } { # this is to avoid the 2 second problem in KDE 2 if { $::tcl_platform(platform) == "windows" } { set raise 1 } else { set raise 0 } } if { $raise } { raise [winfo toplevel $win] } if { $options(-callback) ne "" } { return } set action -2 vwait [varname action] if { ![info exists action] } { return -1 } return $action } method withdrawwindow {} { if { $options(-grab) } { grab release $win if { $oldGrab ne "" } { if { [info exists grabStatus] && $grabStatus ne "global" } { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab $oldGrab } } else { if { [winfo exists $oldGrab] && [winfo ismapped $oldGrab] } { grab -global $oldGrab } } } set oldGrab "" catch { focus $oldFocus } set oldFocus "" } wm withdraw $win } method deiconifywindow {} { set oldFocus [focus -displayof $win] focus $win if { $options(-grab) } { set oldGrab [grab current $win] if { $oldGrab ne "" && [winfo exists $oldGrab] } { set grabStatus [grab status $oldGrab] grab release $oldGrab } catch { grab $win } } else { set oldGrab "" } wm deiconify $win } method iswaiting {} { if { [info exists action] && $action == -2 } { return 1 } return 0 } method giveentryvalue {} { return $entryvalue } method give_repeat_my_answer {} { return $repeat_my_answer } method exists_uservar { key } { return [info exists uservar($key)] } method give_uservar { args } { switch -- [llength $args] { 1 { #nothing } 2 { set uservar([lindex $args 0]) [lindex $args 1] } default { error "error in give_uservar" } } return [varname uservar([lindex $args 0])] } method set_uservar_value { key newvalue } { set uservar($key) $newvalue } # only activate write traces if different method update_uservar_value { key newvalue } { if { $newvalue ne $uservar($key) } { set uservar($key) $newvalue } } method give_uservar_value { args } { set key [lindex $args 0] switch -- [llength $args] { 1 { return $uservar($key) } 2 { if { [info exists uservar($key)] } { return $uservar($key) } else { return [lindex $args 1] } } default { error "error in give_uservar_value" } } } method unset_uservar { key } { unset -nocomplain uservar($key) } typemethod exists_typeuservar { key } { return [info exists typeuservar($key)] } typemethod set_typeuservar_value { key newvalue } { set typeuservar($key) $newvalue } typemethod give_typeuservar_value { args } { set key [lindex $args 0] switch -- [llength $args] { 1 { return $typeuservar($key) } 2 { if { [info exists typeuservar($key)] } { return $typeuservar($key) } else { return [lindex $args 1] } } default { error "error in give_typeuservar_value" } } } typemethod unset_typeuservar { key} { unset typeuservar($key) } typemethod clear_do_not_ask_again { message } { if { ![info exists typeuservar(do_not_ask_again)] } { return } set d $typeuservar(do_not_ask_again) dict unset d $message set typeuservar(do_not_ask_again) $d } method add_trace_to_uservar { key cmd } { trace add variable [varname uservar($key)] write "$cmd;#" lappend traces [list [varname uservar($key)] write "$cmd;#"] } method add_traceN_to_uservar { key cmd } { append cmd " \[[list $self give_uservar_value $key]\]" trace add variable [varname uservar($key)] write "$cmd;#" lappend traces [list [varname uservar($key)] write "$cmd;#"] } method eval_uservar_traces { key } { set uservar($key) $uservar($key) } # dict contains values and active widgets for these values # example: if dict contains: # value1 "w1 w2" value2 "w3 w4" # when value of key is changed to 'value1', widgets w1 w2 will be enabled # and widgets w3 w4 will be disabled # if widget is a number, it refers to a button # if there is a negative sign in front of the widget name, it makes the opposite method enable_disable_on_key { args } { set optional { { -clear "" 0 } } set compulsory "key dict" parse_args $optional $compulsory $args if { $clear } { $self remove_traces_to_uservar $key [mymethod _enable_disable_on_key_helper]* } $self add_trace_to_uservar $key [mymethod _enable_disable_on_key_helper \ $key $dict] catch { $self _enable_disable_on_key_helper $key $dict } } method _enable_disable_on_key_helper { key dict args } { dict for "n v" $dict { if { $n ne $uservar($key) } { foreach w $v { if { [string is integer $w] } { switch $w { 1 { $self disableok } 0 { $self disablecancel } default { $self disablebutton $w } } } else { set i_action disable if { [regexp {^([-+])(.*)} $w {} sign w] } { if { $sign eq "-" } { set i_action enable } else { continue } } $self _enable_disable_widget $w $i_action } } } } set n $uservar($key) if { [dict exists $dict $n] } { set v [dict get $dict $n] } elseif { [dict exists $dict ""] } { set v [dict get $dict ""] } else { set v "" } foreach w $v { if { [string is integer $w] } { switch $w { 1 { $self enableok } 0 { $self enablecancel } default { $self enablebutton $w } } } else { set i_action enable if { [regexp {^([-+])(.*)} $w {} sign w] } { if { $sign eq "-" } { set i_action disable } } $self _enable_disable_widget $w $i_action } } } method _enable_disable_widget { w enable_disable } { switch [winfo class $w] { Canvas { switch $enable_disable { enable { $w itemconfigure all -fill black } disable { $w itemconfigure all -fill grey } } } default { switch $enable_disable { enable { set err [catch { $w state !disabled }] if { $err } { catch { $w configure -state normal } } } disable { set err [catch { $w state disabled }] if { $err } { catch { $w configure -state disabled } } } } } } foreach i [winfo children $w] { $self _enable_disable_widget $i $enable_disable } } # dict contains values and "key2 newvalue" pairs for these values # example: if dict contains: # value1 "key2 1" value2 "key2 0 key3 v" default "key4 1" # when value of key is changed to 'value1', the value of key "key2" is # changed to "1". when value of key is changed to 'value2', the value # of key "key2" is changed t0 "0" and the value of "key3" is changed to "v" # for any other value, key4 is changed to 1 # there can be a "default" value that is applied if none of the other values apply # if a value for a variable is not given, it is just updated to raise traces method change_key_on_key { args } { set optional { { -clear "" 0 } { -initialize boolean 1 } } set compulsory "key dict" parse_args $optional $compulsory $args if { $clear } { $self remove_traces_to_uservar $key [mymethod _change_key_on_key_helper]* } $self add_trace_to_uservar $key [mymethod _change_key_on_key_helper \ $key $dict] if { $initialize } { catch { $self _change_key_on_key_helper $key $dict } } } method _change_key_on_key_helper { key dict args } { set n $uservar($key) if { [dict exists $dict $n] } { set v [dict get $dict $n] if { [llength $v]%2 == 1 } { lappend v $uservar([lindex $v end]) } foreach "k v" $v { set uservar($k) $v } } elseif { [dict exists $dict default] } { set v [dict get $dict default] if { [llength $v]%2 == 1 } { lappend v $uservar([lindex $v end]) } foreach "k v" $v { set uservar($k) $v } } } method has_traces_to_uservar { key { cmd_pattern "" } } { foreach i $traces { if { [lindex $i 0] eq [varname uservar($key)] } { if { $cmd_pattern eq "" || [string match $cmd_pattern [lindex $i 2]] } { return 1 } } } return 0 } method remove_traces_to_uservar { key { cmd_pattern "" } } { foreach i $traces { if { [lindex $i 0] eq [varname uservar($key)] } { if { $cmd_pattern eq "" || [string match $cmd_pattern [lindex $i 2]] } { trace remove variable {*}$i } } } } method add_destroy_handler { cmd } { lappend destroy_handlers $cmd } method remove_destroy_handler { cmd } { set ipos [lsearch -exact $destroy_handlers $cmd] if { $ipos != -1 } { set destroy_handlers [lreplace $destroy_handlers $ipos $ipos] } } } #-------------------------------------------------------------------------------- # dialogwin_snit EXAMPLES #-------------------------------------------------------------------------------- # SIMPLE: only text and buttons if 0 { dialogwin_snit $win._ask -title [_ "Action"] -okname [_ "New password"] \ -morebuttons [list [_ "Uncrypt"]] -entrytext [_ "Choose action to perform"]: set action [$win._ask createwindow] destroy $win._ask if { $action <= 0 } { return } if { $action == 2 } { $wordnoter_db enterpage $options(-page) - $data return } } # MEDIUM: text and buttons and entry if 0 { dialogwin_snit $win._ask -title [_ "Enter password"] -entrytype password \ -entrylabel [_ "Password"]: -entrytext [_ "Enter password to encrypt"]: set action [$win._ask createwindow] while 1 { if { $action <= 0 } { destroy $win._ask return } set pass [string trim [$win._ask giveentryvalue]] if { [string length $pass] < 4 } { $self warnwin [_ "Password must have at least 4 characters"] } else { break } set action [$win._ask waitforwindow] } } # COMPLEX: user defined widgets if 0 { set w [dialogwin_snit $win._ask -title [_ "Change page type"] -entrytext \ [_ "Choose a new page type for page '%s'" $page] \ -morebuttons [list [_ "Yes to all"] [_ "No to all"] [_ No]]] #-grab 0 -callback [mymethod preferences_win_apply] -okname - set f [$w giveframe] if { $type eq "" } { set type Normal } label $f.l1 -text [_ "Current type: %s" $type] label $f.l2 -text [_ "New type:"] ComboBox $f.cb1 -textvariable [$w give_uservar newtype $type] -values \ [list Normal Home] -editable 0 tk::TabToWindow $f.cb1 bind $f.cb1 <Return> [list $w invokeok] grid $f.l1 - -sticky w -pady 2 grid $f.l2 $f.cb1 -sticky w -padx 2 -pady "2 4" grid configure $f.cb1 -sticky ew grid columnconfigure $f 1 -weight 1 set action [$w createwindow] set newtype [$w give_uservar_value newtype] destroy $w if { $action <= 0 } { return } if { $newtype eq "Normal" } { set newtype "" } # switch -- [$w giveaction] { # -1 - 0 { destroy $w } # 1 - 2 { # # if { [$w giveaction] == 1 } { destroy $w } # } # } } # one exemple without buttons if 0 { wm withdraw . set w .ask dialogwin_snit $w -title [_ "Action"] -okname - -cancelname - \ -entrytext [_ "Choose action to perform"]: -entrytype entry set action [$w createwindow] puts [$w giveentryvalue] destroy $w exit } snit::widgetadaptor wizard_snit { option -image "" option -on_exit_callback "" delegate method * to hull delegate option * to hull # every element is composed of: title build_callback check_callback has_finish_button # is_labelframe is_hidden previous_page # check_callback can be void on all pages except the last variable dataList "" variable curr_callback variable frame constructor {args} { installhull using dialogwin_snit -callback [mymethod _callback] \ -morebuttons [list [_ Previous] [_ Next] [_ Finish] [_ Cancel]] \ -okname - -cancelname - -geometry 500x300 -transient 1 $self configurelist $args set f [$win giveframe] ttk::label $f.l1 if { $options(-image) ne "" } { $f.l1 configure -image $options(-image) } set frame [ttk::labelframe $f.f1] grid $f.l1 $frame -sticky nsew grid configure $frame -padx 5 -pady 5 grid columnconfigure $f 1 -weight 1 grid rowconfigure $f 0 -weight 1 set curr_callback 0 $win changebuttongridoptions 5 -padx "20 0" $win createwindow } method create_page { args } { set optional { { -check_callback callback "" } { -has_finish_button boolean 0 } { -is_labelframe boolean 1 } { -is_hidden boolean 0 } { -previous_page number|title "" } } set compulsory "title build_callback" parse_args $optional $compulsory $args if { $previous_page ne "" && ![string is integer -strict $previous_page] } { set ipos [lsearch -exact -index 0 $dataList $previous_page] if { $ipos == -1 } { error "error in create_page. previous_page not existant" } set previous_page [expr {$ipos+1}] } set elm [list $title $build_callback $check_callback $has_finish_button \ $is_labelframe $is_hidden $previous_page] lappend dataList $elm return [llength $dataList] } method edit_page { num args } { incr num -1 set optional { { -title title "" } { -build_callback callback "" } { -check_callback callback "" } { -has_finish_button boolean -1 } { -is_labelframe boolean -1 } { -is_hidden boolean -1 } { -previous_page number|title "" } } set compulsory "" parse_args $optional $compulsory $args if { $previous_page ne "" && ![string is integer -strict $previous_page] } { set ipos [lsearch -exact -index 0 $dataList $previous_page] if { $ipos == -1 } { error "error in edit_page. previous_page not existant" } set previous_page [expr {$ipos+1}] } set idx 0 foreach i $optional { foreach "opt type def" $i break set opt [string trimleft $opt -] if { [set $opt] ne $def } { lset dataList $num $idx [set $opt] } incr idx } } method open_page { num } { set curr_callback [expr {$num-1}] $self _open_window ahead } method _open_window { direction } { while 1 { set elm [lindex $dataList $curr_callback] if { $elm eq "" } { return } foreach [list title build_callback check_callback has_finish_button \ is_labelframe is_hidden previous_page] $elm break if { !$is_hidden } { break } switch $direction { ahead { incr curr_callback } behind { incr curr_callback -1 } } } eval destroy [winfo children $frame] set i [grid info $frame] destroy $frame if { $is_labelframe } { ttk::labelframe $frame -text $title } else { ttk::frame $frame } eval grid $frame $i lappend build_callback $win $frame uplevel #0 $build_callback $win configure -title $title if { $curr_callback == 0 } { $win disablebutton 2 } else { $win enablebutton 2 } if { $curr_callback == [llength $dataList]-1 } { $win disablebutton 3 $win showhidebutton 4 show } else { $win enablebutton 3 if { $has_finish_button == 1 } { $win showhidebutton 4 show } else { $win showhidebutton 4 hide } } if { [wm state $win] ne "normal" } { $self deiconifywindow } } method _callback { f } { switch -- [$win giveaction] { -1 - 0 - 5 { return [$self withdraw] } 2 { set previous_page [lindex $dataList $curr_callback 6] if { $previous_page ne "" } { set curr_callback [expr {$previous_page-1}] } else { incr curr_callback -1 } $self _open_window behind } 3 - 4 { set check_callback [lindex $dataList $curr_callback 2] set ret "" if { $check_callback ne "" } { lappend check_callback $win $frame if { [$win giveaction] == 4 } { lappend check_callback finish } else { lappend check_callback next } set err [catch { uplevel #0 $check_callback } ret] if { $err } { if { $ret ne "" } { snit_messageBox -parent $win -message $ret } return } } if { $ret eq "finish" || [$win giveaction] == 4 } { return [$self withdraw] } elseif { [string is integer -strict $ret] } { set curr_callback [expr {$ret-1}] } elseif { $ret ne "" } { set ipos [lsearch -exact -index 0 $dataList $ret] if { $ipos == -1 } { error "error in check_callback return value. page not existant" } set curr_callback $ipos } else { incr curr_callback } $self _open_window ahead } } } method withdraw {} { if { $options(-on_exit_callback) ne "" } { uplevel #0 $options(-on_exit_callback) $win } $self withdrawwindow #destroy $win return "" } } ################################################################################ # parse args # # example: # proc myproc { args } { # set optional { # { -view_binding binding "" } # { -file file "" } # { -restart_file boolean 0 } # { -flag1 "" 0 } # } # set compulsory "levels" # parse_args $optional $compulsory $args # # if { $view_binding ne "" } { puts hohoho } # if { $flag1 } { puts "activated flag" } # } # ################################################################################ if { 1|| [catch { package require compass_utils }] } { proc ::parse_args { args } { set optional { { -raise_compulsory_error boolean 1 } { -compulsory_min min_number "" } } set compulsory "optional compulsory arguments" if { [info level] == 1 } { set cmdname [list [info nameofexecutable]] if { ![info exists ::starkit::topdir] } { lappend cmdname $::argv0 } } else { set cmdname [lindex [info level [expr {[info level]-1}]] 0] } if { [llength $args] > [llength $compulsory] && [string match -* [lindex $args 0]] } { parse_args $optional $compulsory $args } else { set raise_compulsory_error 1 set compulsory_min "" if { [llength $args] != [llength $compulsory] } { uplevel 1 [list error [_parse_args_string $cmdname $optional \ $compulsory $arguments]] return "" } lassign $args {*}$compulsory } foreach i $optional { lassign $i name namevalue default set opts_value($name) $namevalue if { [llength $i] > 2 } { set opts($name) $default } } while { (!$raise_compulsory_error || [llength $arguments] > [llength $compulsory]) && [string match -* [lindex $arguments 0]] } { if { [lindex $arguments 0] eq "--" } { set arguments [lrange $arguments 1 end] break } lassign [lrange $arguments 0 1] name value if { [regexp {(.*)=(.*)} $name {} name value] } { set has_att_value 1 } else { set has_att_value 0 } if { [info exists opts_value($name)] } { if { $has_att_value } { set opts($name) $value set arguments [lrange $arguments 1 end] } elseif { $opts_value($name) eq "" } { set opts($name) 1 set arguments [lrange $arguments 1 end] } else { set opts($name) $value set arguments [lrange $arguments 2 end] } } else { uplevel 1 [list error [_parse_args_string $cmdname $optional \ $compulsory $arguments]] return "" } } if { $raise_compulsory_error } { if { $compulsory_min ne "" } { if { [llength $arguments] < $compulsory_min || \ [llength $arguments] > [llength $compulsory] } { uplevel 1 [list error [_parse_args_string $cmdname $optional $compulsory $arguments]] return "" } } elseif { [llength $arguments] != [llength $compulsory] } { uplevel 1 [list error [_parse_args_string $cmdname $optional \ $compulsory $arguments]] return "" } } foreach name [array names opts] { uplevel 1 [list set [string trimleft $name -] $opts($name)] } set inum 0 foreach i $compulsory { uplevel 1 [list set $i [lindex $arguments $inum]] incr inum } return [lrange $arguments $inum end] } proc ::_parse_args_string { cmd optional compulsory arguments } { set str "error. usage: $cmd " foreach i $optional { foreach "name namevalue default" $i break append str "?$name $namevalue? " } append str $compulsory append str "\n\targs: $arguments" return $str } }