<> [JOB] 2016-07-08 Playing with TclOO... The following source implements a TclOO megawidget based on [tablelist] with some extended features to manipulate the tablelist content. [WikiDBImage xtablelist_demo.png] **Features** The following additional commands are implemented: * Move selected items up or down, * reverse the list order, * delete selected items, * delete all, but just keep selected items (exceptional delete), * undo previous operations (restore content to it's original state), * save listbox to file, * restore content from file **Source Code** The megawidget source is divided into various files to keep public and private interface separated. ***pkgIndex.tcl*** ====== # Tcl package index file package ifneeded xtablelist 0.3 \ " [list source [file join $dir xtablelist.tcl]]; \ [list source [file join $dir xtablelist_public.tcl]]; \ [list source [file join $dir xtablelist_private.tcl]]; \ [list source [file join $dir xtablelist_readwrite.tcl]]; \ [list source [file join $dir xtablelist_filesel.tcl]]; \ [list source [file join $dir xtablelist_popupmenu.tcl]]; \ " ====== ***xtablelist.tcl*** ====== # ----------------------------------------------------------------------------- # xtablelist.tcl --- # ----------------------------------------------------------------------------- # (c) 2016, Johann Oberdorfer - Engineering Support | CAD | Software # johann.oberdorfer [at] gmail.com # www.johann-oberdorfer.eu # ----------------------------------------------------------------------------- # This source file is distributed under the BSD license. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the BSD License for more details. # ----------------------------------------------------------------------------- # Purpose: # A TclOO class template to extend tablelist functionality. # Might be usefull as a starting point. # ----------------------------------------------------------------------------- # TclOO naming conventions: # public methods - starts with lower case declaration names, whereas # private methods - starts with uppercase naming, so we use CamelCase ... # ----------------------------------------------------------------------------- # Credits: # tablelist widget: Copyright (c) 2000-2015 Csaba Nemethi # tooltip: Copyright (c) 1996-2007 Jeffrey Hobbs # autoscroll: Copyright (c) 2003 Kevin B Kenny # icons used from: Open Icon Library # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # widget commands: # xtablelist::xtablelist # xtablelist::configure # xtablelist::cget # # xtablelist::... + all commands from original tablelist # for more sub-command refer as well to the # public class interface # # ----------------------------------------------------------------------------- # widget options # # -xhideoption boolean "yes",1 / "no",0 (default: "yes"), # hide/show popup-menu # to manipulate tablelist column display # default is "yes": show relev. menu items # # -xshowbuttons boolean (default: "yes"), # show sidebar action buttons to manipulate tablelist content # -xsortoption boolean (default: "yes"), # hide/show popup-menu to modify tablelist column sort order # # -xfileread boolean (default: "no"), # allows reading in a previously stored file, # # -xfilesave boolean (default: "no") # allows to saving tablelist data to a file # # -xfilereadpostcmd # file read post command (default: ""), # if defined, allows to e.g. set widget state of depending # action buttons in the caller program # # -xdeletepostcmd # table entry delete post command (default: "") # # -xrefreshpostcmd # executed after a delete / refresh action takes place # # -xselectpostcmd # specify a command to be executed after selecting # an item in the tablelist (default: "") # # -xmoveovereffect # boolean (default: "no"), # enable visual "move over" effect # # virtual events: # # <> - delete, modified or sort action took place # <> - undo, nothing changed so far! # ----------------------------------------------------------------------------- # Hint: # some of the options need to be specified when creating the widget # and are not fully configureable later on once the widget has been # created (open issue to be implemented later on...) # ----------------------------------------------------------------------------- # for development: try to find autoscroll, etc ... set this_file [file normalize [file dirname [info script]]] # where to find required packages... # set auto_path [linsert $auto_path 0 [file join $this_file ".." "contrib" ]] package require Tk package require TclOO package require tablelist_tile package require tooltip package require autoscroll package provide xtablelist 0.3 # workaround for aqua if { [tk windowingsystem] eq "aqua" } { interp alias {} ttk::scrollbar {} ::scrollbar } namespace eval xtablelist { # the widget's interface declaration namespace export \ addValues \ deleteAllItems set this_dir [file dirname [info script]] set image_dir [file join $this_dir "images"] set image_file [file join $this_dir "ImageLib.tcl"] proc LoadImages {image_dir {patterns {*.gif}}} { foreach p $patterns { foreach file [glob -nocomplain -directory $image_dir $p] { set img [file tail [file rootname $file]] if { ![info exists images($img)] } { set images($img) [image create photo -file $file] } }} return [array get images] } proc xtablelist {path args} { # this is a tk-like wrapper around my... class so that # object creation works like other tk widgets set obj [XTableList create tmp $path {*}$args] # rename oldName newName rename $obj ::$path return $path } } # ----------------------------------------------------------------------------- # Tk widget 'a like interface declaration # ----------------------------------------------------------------------------- oo::class create XTableList { variable tblwidget variable widgetOptions variable widgetCompounds constructor {path args} { # --------------------------------------------------------------- # read images from library file or alternatively one by one # --------------------------------------------------------------- set image_file $::xtablelist::image_file set image_dir $::xtablelist::image_dir if { [file exists $image_file] } { source $image_file array set widgetCompounds [array get images] } else { array set widgetCompounds [::tablelistbrowser::LoadImages \ [file join $image_dir] {"*.gif" "*.png"}] } # --------------------------------------------------------------- array set widgetCompounds { undo_flag 0 sortby -1 undoList {} DELIM "@" default_dir "" } # declaration of additional (configureable) widget options array set widgetOptions { -xtabheader {} -xmoveovereffect 1 -xhideoption 1 -xsortoption 1 -xshowbuttons 1 -xfileread 1 -xfilesave 1 -xfilereadpostcmd "" -xdeletepostcmd "" -xrefreshpostcmd "" -xselectpostcmd "" } switch -- $::tcl_platform(platform) { "windows" { set widgetCompounds(default_dir) $::env(TEMP) } "unix" - default { set widgetCompounds(default_dir) $::env(HOME) } } # we use a frame for this specific widget class set f [ttk::frame $path -class xtablelist] # we must rename the widget command # since it clashes with the object being created set widget ${path}_ my Build $f rename $path $widget my configure {*}$args } destructor { # add a destructor to clean up the widget set w [namespace tail [self]] catch {bind $w {}} catch {destroy $w} } method cget { {opt "" } } { my variable tblwidget my variable widgetOptions if { [string length $opt] == 0 } { return [array get widgetOptions] } if { [info exists widgetOptions($opt) ] } { return $widgetOptions($opt) } return [$tblwidget cget $opt] } method configure { args } { my variable tblwidget my variable widgetOptions if {[llength $args] == 0} { # return all tablelist options set opt_list [$tblwidget configure] # as well as all custom options foreach xopt [array get widgetOptions] { lappend opt_list $xopt } return $opt_list } elseif {[llength $args] == 1} { # return configuration value for this option set opt $args if { [info exists widgetOptions($opt) ] } { return $widgetOptions($opt) } return [$tblwidget cget $opt] } # error checking if {[expr {[llength $args]%2}] == 1} { return -code error "value for \"[lindex $args end]\" missing" } # process the new configuration options... array set opts $args foreach opt_name [array names opts] { set opt_value $opts($opt_name) # overwrite with new value if { [info exists widgetOptions($opt_name)] } { set widgetOptions($opt_name) $opt_value } # some options need action from the widgets side switch -- $opt_name { -labelcommand { # replace sortcolumn command by our own method... if { [my GetBoolean $widgetOptions(-xsortoption)] } { $tblwidget configure \ -labelcommand "[namespace code {my SortByColumnCmd}]" } else { $tblwidget configure -labelcommand $opt_value } } -xtabheader { my InitializeTabHeader $opt_value } -xmoveovereffect { if { [my GetBoolean $widgetOptions(-xmoveovereffect)] } { my EnableMoveover } else { $tblwidget configure -activestyle none } } -xhideoption {} -xsortoption {} -xshowbuttons {} -xfileread {} -xfilesave {} -xfilereadpostcmd {} -xdeletepostcmd {} -xrefreshpostcmd {} -xselectpostcmd {} default { # ------------------------------------------------------- # if the configure option wasn't one of our special one's, # pass control over to the original tablelist widget # ------------------------------------------------------- if {[catch {$tblwidget configure $opt_name $opt_value} result]} { return -code error $result } } } } } method insert {method args} { # overloaded tablelist method my variable tblwidget my variable widgetCompounds # maintain undo list + button states... lappend widgetCompounds(undoList) {*}$args # hand over to tablelist widget... if {[catch {$tblwidget insert $method {*}$args} result]} { return -code error $result } my UpdateStatusInfo [$tblwidget get 0 end] } method insertlist {method args} { # overloaded tablelist method my variable tblwidget # maintain undo list + button states... lappend widgetCompounds(undoList) {*}$args if {[catch {$tblwidget insertlist $method {*}$args} result]} { return -code error $result } my UpdateStatusInfo [$tblwidget get 0 end] } method unknown {method args} { # if the command wasn't one of our special one's, # pass control over to the original tablelist widget my variable tblwidget if {[catch {$tblwidget $method {*}$args} result]} { return -code error $result } } } # ----------------------------------------------------------------------------- # Private interface methods # ----------------------------------------------------------------------------- oo::define XTableList { method SortByColumnCmd {args} { my variable tblwidget my variable widgetCompounds # set tbl [lindex $args 0] set idx [lindex $args 1] set widgetCompounds(sortby) $idx ::tablelist::sortByColumn $tblwidget $idx } method InitBindings {} { my variable tblwidget bind [$tblwidget bodypath] { set t [winfo parent %W] set x [expr {%x + [winfo x %W]}] set y [expr {%y + [winfo y %W]}] set oo_my [winfo parent $t] # move up hierachy until our own class is reached: # notes: # - maybe there is a more convinient way to adress a class member function ? # - pls note that the member function needs to start with lowercase char # otherwise it's hidden in global namespace while { [winfo exists $oo_my] } { # puts "--> $oo_my : [winfo class $oo_my]" if { [winfo class $oo_my] == "xtablelist" } { break } set oo_my [winfo parent $oo_my] } $oo_my showContextMenu \ [$t nearestcolumn $x] [$t nearest $y] %X %Y } } method Build {frm} { # build the (mega-) widget # frm - parent frame widget path my variable tblwidget my variable widgetOptions my variable widgetCompounds # status line # ----------- set f [ttk::frame $frm.flabel] pack $f -side bottom -fill both ttk::label $f.lbl -text "" pack $f.lbl -side bottom -fill x -anchor w set widgetCompounds(label) $f.lbl # listbox and two scrollbars embedded into a frame set f [ttk::frame $frm.f] pack $f -side left -fill both -expand true # a.) right set fright [ttk::frame $f.fright] pack $fright -side right -fill y ttk::scrollbar $fright.scrolly -orient vertical pack $fright.scrolly -side top -fill y -expand true ttk::frame $fright.spacery -height 15 pack $fright.spacery -side bottom # b.) left set fleft [ttk::frame $f.fleft] pack $fleft -side left -fill both -expand true # left/top frame set fltop [ttk::frame $fleft.fltop] # left/bottom x scrollbar ttk::scrollbar $fleft.scrollx -orient horizontal # pack scrollbar 1st, so that it won't disappear while panning pack $fleft.scrollx -side bottom -fill x pack $fltop -side top -fill both -expand true # another frame for the tablelist object set fxx [ttk::frame $fltop.fleft] pack $fxx -side top -fill both -expand true ::tablelist::tablelist $fxx.tlist \ -selectmode extended \ -takefocus 0 \ -activestyle none \ -xscrollcommand "$fleft.scrollx set" \ -yscrollcommand "$fright.scrolly set" pack $fxx.tlist -side bottom -fill both -expand true set tblwidget $fxx.tlist bind $tblwidget <> \ "+ [namespace code {my SelectionCallback}]" bind $tblwidget <> \ "+ event generate $tblwidget <>" $fleft.scrollx configure -command "$fxx.tlist xview" $fright.scrolly configure -command "$fxx.tlist yview" # enable auto scrolling... autoscroll::autoscroll $fleft.scrollx autoscroll::autoscroll $fright.scrolly # icon-box for list manipulation ... # ---------------------------------- set f1 [ttk::frame $frm.f1] pack $f1 -side right -fill both if { [my GetBoolean $widgetOptions(-xshowbuttons)] } { ttk::button $f1.b1 -image $widgetCompounds(up) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 1" ::tooltip::tooltip $f1.b1 "Move-Up" pack $f1.b1 -pady 1 set widgetCompounds(b1) $f1.b1 ttk::button $f1.b1i -image $widgetCompounds(reverselist) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 10" ::tooltip::tooltip $f1.b1i "Reverse the list order" pack $f1.b1i -pady 1 set widgetCompounds(b1i) $f1.b1i ttk::button $f1.b2 -image $widgetCompounds(down) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 2" ::tooltip::tooltip $f1.b2 "Move-Down" pack $f1.b2 -pady 1 set widgetCompounds(b2) $f1.b2 ttk::button $f1.b3 -image $widgetCompounds(delete) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 3" ::tooltip::tooltip $f1.b3 "Remove item(s) from the list" pack $f1.b3 -pady 1 set widgetCompounds(b3) $f1.b3 ttk::button $f1.b3i -image $widgetCompounds(delete_reverse) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 5" ::tooltip::tooltip $f1.b3i "Remove All item(s)- except selected" pack $f1.b3i -pady 1 set widgetCompounds(b3i) $f1.b3i ttk::button $f1.b4 -image $widgetCompounds(reload) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 4" ::tooltip::tooltip $f1.b4 "Undo previous operation" pack $f1.b4 -pady 1 set widgetCompounds(b4) $f1.b4 } elseif {$widgetOptions(-xshowbuttons) == "arrows"} { ttk::button $f1.b1 -image $widgetCompounds(up) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 1" ::tooltip::tooltip $f1.b1 "Move-Up" pack $f1.b1 -pady 1 set widgetCompounds(b1) $f1.b1 ttk::button $f1.b2 -image $widgetCompounds(down) \ -style Toolbutton \ -command "[namespace code {my ToolbuttonCallback}] 2" ::tooltip::tooltip $f1.b2 "Move-Down" pack $f1.b2 -pady 1 set widgetCompounds(b2) $f1.b2 } if { [my GetBoolean $widgetOptions(-xfileread)] } { ttk::button $f1.b8 -image $widgetCompounds(folder) \ -style Toolbutton \ -command "[namespace code {my OpenFromFile}]" ::tooltip::tooltip $f1.b8 "Open Listbox content from file" pack $f1.b8 -pady 1 -side bottom set widgetCompounds(b8) $f1.b8 } if { [my GetBoolean $widgetOptions(-xfilesave)] } { ttk::button $f1.b5 -image $widgetCompounds(filesaveas) \ -style Toolbutton \ -command "[namespace code {my Save2File}]" ::tooltip::tooltip $f1.b5 "Save Listbox to file" pack $f1.b5 -pady 1 -side bottom set widgetCompounds(b7) $f1.b5 } # disabled by default: if { [my GetBoolean $widgetOptions(-xshowbuttons)] } { $widgetCompounds(b1) configure -state disabled $widgetCompounds(b2) configure -state disabled $widgetCompounds(b3) configure -state disabled $widgetCompounds(b3i) configure -state disabled $widgetCompounds(b4) configure -state disabled } elseif {$widgetOptions(-xshowbuttons) == "arrows"} { $widgetCompounds(b1) configure -state disabled $widgetCompounds(b2) configure -state disabled } #$tlist($w,b6) configure -state disabled if { [my GetBoolean $widgetOptions(-xfilesave)] } { $widgetCompounds(b7) configure -state disabled } # note: There is also a popup-menu, which corresponds with # the button box. So, if you do any changes here, # do not forget to maintain there as well! set widgetCompounds(mstate) disabled my InitBindings } } ====== ***xtablelist_public.tcl*** ====== # ----------------------------------------------------------------------------- # xtablelist_public.tcl --- # ----------------------------------------------------------------------------- # Purpose: # A TclOO class template to extend tablelist functionality. # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Public interface # ----------------------------------------------------------------------------- oo::define XTableList { method info {} { puts [self class] } method selectArrowCallback {} { # this function is called every time an up-down arrow is selected # by default, it's empty, but can be predefined to suit the needs # in the caller application set dummy 0 } # unused method deleteAllItems {} { my variable tblwidget my variable widgetCompounds $tblwidget delete 0 end my UpdateStatusInfo {} # "Undo" button also needs to be disabled if { [winfo exists widgetCompounds(b4)] } { $widgetCompounds(b4) configure -state disabled } } method addValues {lst {mode ""}} { my variable tblwidget my variable widgetCompounds if {![info exists widgetCompounds(undoList)]} { set widgetCompounds(undoList) {} } # re-initialize variable (if necessary) if {$mode == ""} { $tblwidget delete 0 end set widgetCompounds(undoList) {} } # populate columns with information ... # ------------------------------------- set cnt 0 foreach sublist $lst { $tblwidget insert end $sublist lappend widgetCompounds(undoList) $sublist incr cnt } # update status text my UpdateStatusInfo $lst } } ====== ***xtablelist_private.tcl*** ====== # ----------------------------------------------------------------------------- # xtablelist_private.tcl --- # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Private interface methods # ----------------------------------------------------------------------------- oo::define XTableList { method GetBoolean {value {errorValue 1}} { # returns the value of a (presumably) boolean string (ie: it should # do the right thing if the string is "yes", "no", "true", 1, etc # # value - value to be converted # errorValue - a default value to be returned in case of an error # # Returns: # a 1 or zero, or the value of errorValue if the string isn't # a proper boolean value if {[catch {expr {([string trim $value])?1:0}} res]} { return $errorValue } else { return $res } } method GetTblColumnNames {} { # retrieve all column names, regardless if they are hidden or not my variable tblwidget set col_names {} foreach {with name pos} [$tblwidget cget -columns] { lappend col_names $name } return $col_names } method GetOnlyVisibleTblColumnNames {} { # retrieve only column names which are not hidden my variable tblwidget set cnt 0 set col_names {} foreach {with name pos} [$tblwidget cget -columns] { if { ! [$tblwidget columncget $cnt -hide] } { lappend col_names $name } incr cnt } return $col_names } method InitializeTabHeader {kword_list} { my variable tblwidget set cols "" set cnt 0 foreach i $kword_list { set descr [lindex $i 0] set visual [lindex $i 1] set orient [lindex $i 2] if {[string length $orient] == 0} { set orient "left" } regsub -all " " $descr "_" descr if {$descr != "..." && [string range $descr end end] != ":"} { set descr "${descr}:" } # could be either a string or an integer: if {$visual == "hidden"} { set width 20 } else { set width $visual } append cols "$width $descr $orient " incr cnt } $tblwidget configure -columns $cols # hide specific columns as indicated with "hidden" in declaration array set cnt 0 foreach i $kword_list { if {[set width [lindex $i 1]] == "hidden"} { $tblwidget columnconfigure $cnt -hide yes } incr cnt } # expand last *visible* column # ---------------------------- set cnt 0 set lastcol 0 # tablelist -columns option are always 3 attributes each... foreach {w col pos} [$tblwidget cget -columns] { if {[$tblwidget columncget $cnt -hide] == 0} {set lastcol $cnt} incr cnt } if {$lastcol > 0} { $tblwidget configure -stretch $lastcol } } method SelectionCallback {} { my variable tblwidget my variable widgetCompounds my variable widgetOptions if { ![my GetBoolean $widgetOptions(-xshowbuttons)] } { return } # manage visualisation mode of toolboxes set csel [$tblwidget curselection] if {$widgetOptions(-xshowbuttons) == "arrows"} { if {$csel == {}} { $widgetCompounds(b1) configure -state disabled $widgetCompounds(b2) configure -state disabled } else { $widgetCompounds(b1) configure -state normal $widgetCompounds(b2) configure -state normal } } else { if {$csel == {}} { $widgetCompounds(b1) configure -state disabled $widgetCompounds(b2) configure -state disabled $widgetCompounds(b3) configure -state disabled $widgetCompounds(b3i) configure -state disabled } else { $widgetCompounds(b1) configure -state normal $widgetCompounds(b2) configure -state normal $widgetCompounds(b3) configure -state normal $widgetCompounds(b3i) configure -state normal } } # does it make sense to enable undo button: if {$widgetCompounds(undo_flag) == 1} { $widgetCompounds(b4) configure -state normal event generate $tblwidget <> } else { $widgetCompounds(b4) configure -state disabled event generate $tblwidget <> } # move-up if {[lsearch $csel 0] != -1} { $widgetCompounds(b1) configure -state disabled } # move-down set data [$tblwidget get 0 end] set len [expr [llength $data] -1] if {[lsearch $csel $len] != -1} { $widgetCompounds(b2) configure -state disabled } # evaluate post command in parent namespace... if {$widgetOptions(-xselectpostcmd) != ""} { catch {uplevel $widgetOptions(-xselectpostcmd)} } } method UpdateStatusInfo {lst} { # method to maintain additional status information my variable tblwidget my variable widgetCompounds my variable widgetOptions set msg "" switch -- [set cnt [llength $lst]] { 0 { $widgetCompounds(label) configure -text "Tablelist is empty." if { [my GetBoolean $widgetOptions(-xfilesave)] } { $widgetCompounds(b7) configure -state disabled } # required to manage state, when the widget is popping up! set widgetCompounds(mstate) disabled # maintain pop-up menu # note: catch is required if the pop-up is not "pinned" on # the screen (which is most likely the case!) if { [my GetBoolean $widgetOptions(-xhideoption)] } { set idx_list {8 9 10} } else { set idx_list {5 6 7} } $widgetCompounds(b1i) configure -state disabled return } 1 { $widgetCompounds(b1i) configure -state disabled $widgetCompounds(label) configure -text "1 item in tablelist. $msg" } default { $widgetCompounds(b1i) configure -state normal $widgetCompounds(label) configure -text "$cnt items in tablelist. $msg" } } if { [my GetBoolean $widgetOptions(-xfilesave)] } { $widgetCompounds(b7) configure -state normal } set widgetCompounds(mstate) normal if { [my GetBoolean $widgetOptions(-xhideoption)] } { set idx_list {8 9 10} } else { set idx_list {5 6 7} } catch { # @@@ foreach idx $idx_list { $widgetCompounds(m_$tblwidget) entryconfigure $idx -state normal } } } method ToolbuttonCallback {nr} { my variable tblwidget my variable widgetCompounds my variable widgetOptions # refresh if {$nr == 4} { $tblwidget delete 0 end eval $tblwidget insert end $widgetCompounds(undoList) set widgetCompounds(sortby) -1 set widgetCompounds(undo_flag) 0 my UpdateStatusInfo $widgetCompounds(undoList) # evaluate post command in parent namespace... if {$widgetOptions(-xrefreshpostcmd) != ""} { catch {uplevel $widgetOptions(-xrefreshpostcmd)} } my SelectionCallback return } # reverse the list if {$nr == 10} { set data [$tblwidget get 0 end] set data_len [llength $data] set csel [$tblwidget curselection] set reversed_data {} set reversed_csel {} for {set cnt [expr {$data_len -1}]} {$cnt >= 0} {incr cnt -1} { lappend reversed_data [lindex $data $cnt] } foreach idx $csel { lappend reversed_csel [expr {$data_len - $idx }] } $tblwidget delete 0 end eval $tblwidget insert end $reversed_data # highlight again ... foreach idx $reversed_csel { set idx1 [expr {$idx -1}] $tblwidget selection set $idx1 $idx1 } # re-position listbox acc. to current selection set csel [$tblwidget curselection] $tblwidget see [lindex $csel 0] my selectArrowCallback set widgetCompounds(undo_flag) 1 } set csel [$tblwidget curselection] if {$csel == {}} { # call get's important, if more than one widgets exists # at the same time, and the focus get's lost/shiftet: # action buttons are still enabled, but # the following call 'll disable them accordingly my SelectionCallback return } switch -- $nr { 1 { # move-up if {[lsearch $csel 0] != -1} { return } set data [$tblwidget get 0 end] for {set cnt 0} {$cnt < [llength $data]} {incr cnt} { set cnt0 [expr $cnt -1] set tmp0 [lindex [lrange $data $cnt0 $cnt0] 0] set tmp [lindex [lrange $data $cnt $cnt] 0] if {[lsearch $csel $cnt] != -1} { set data [lreplace $data $cnt0 $cnt0 $tmp] set data [lreplace $data $cnt $cnt $tmp0] } } $tblwidget delete 0 end eval $tblwidget insert end $data # highlight again ... foreach idx $csel { set idx0 [expr $idx -1] $tblwidget selection set $idx0 $idx0 } # 06.06.05: and (!) position listbox as it was before! $tblwidget see [lindex $csel 0] my selectArrowCallback set widgetCompounds(undo_flag) 1 } 2 { # move-down set data [$tblwidget get 0 end] set len [expr [llength $data] -1] if {[lsearch $csel $len] != -1} { return } set cnt 0 for {set cnt [llength $data]} {$cnt >= 0} {incr cnt -1} { set cnt1 [expr $cnt +1] set tmp1 [lindex [lrange $data $cnt1 $cnt1] 0] set tmp [lindex [lrange $data $cnt $cnt] 0] if {[lsearch $csel $cnt] != -1} { set data [lreplace $data $cnt $cnt $tmp1] set data [lreplace $data $cnt1 $cnt1 $tmp] } } $tblwidget delete 0 end eval $tblwidget insert end $data # highlight again ... foreach idx $csel { set idx1 [expr $idx +1] $tblwidget selection set $idx1 $idx1 } # set visual region as it was before... $tblwidget see [lindex $csel 0] my selectArrowCallback set widgetCompounds(undo_flag) 1 } 3 { # does not work with empty lines: # foreach i [lsort -decreasing $csel] { $w delete $i $i } set data [$tblwidget get 0 end] set cnt 0 for {set cnt [llength $data]} {$cnt >= 0} {incr cnt -1} { # check if index is within current selection # if true - remove list item ! if {[lsearch $csel $cnt] != -1} { set data [lreplace $data $cnt $cnt] } } $tblwidget delete 0 end eval $tblwidget insert end $data my UpdateStatusInfo $data # evaluate post command in parent namespace... if {$widgetOptions(-xdeletepostcmd) != ""} { catch {uplevel $widgetOptions(-xdeletepostcmd)} } set widgetCompounds(undo_flag) 1 } 5 { # inverse delete = delete all, except selected set data [$tblwidget get 0 end] set new_data {} for {set cnt 0} {$cnt < [llength $data]} {incr cnt 1} { # check if the current index is *not* part of the selection ... if {[lsearch $csel $cnt] != -1} { lappend new_data [lindex $data $cnt] # puts "--> [lindex $data $cnt]" } } $tblwidget delete 0 end eval $tblwidget insert end $new_data my UpdateStatusInfo $new_data # evaluate post command in parent namespace... if {$widgetOptions(-xdeletepostcmd) != ""} { catch {uplevel $widgetOptions(-xdeletepostcmd)} } set widgetCompounds(undo_flag) 1 } } my SelectionCallback } method EnableMoveover {} { my variable tblwidget # move-over effect: bind [$tblwidget bodypath] {+ set t [winfo parent %W] set x [expr {%x + [winfo x %W]}] set y [expr {%y + [winfo y %W]}] # set cell [$t nearestcell $x $y] # puts "Clicked on cell: $cell " # set rownum [lindex [split $cell ","] 0] focus $t $t configure -activestyle frame $t activate "@$x,$y" } bind [$tblwidget bodypath] {+ set t [winfo parent %W] $t configure -activestyle none } } } ====== ***xtablelist_popupmenu.tcl*** ====== # ----------------------------------------------------------------------------- # xtablelist_popupmenu.tcl --- # ----------------------------------------------------------------------------- oo::define XTableList { # unused method showColumnByIndex {idx} { my variable tblwidget my variable widgetCompounds set cnt 0 foreach column [my GetTblColumnNames] { if {$cnt == $idx} { $tblwidget columnconfigure $cnt -hide false set widgetCompounds(hide_column,$cnt) 0 } incr cnt } } # sort the list based on a particular column method SortCmd {index} { my variable tblwidget my variable widgetCompounds $tblwidget sortbycolumn $index set widgetCompounds(sortby) $index } method HideColumnCmd {index} { my variable tblwidget my variable widgetCompounds # hiding all columns doesn't make sense ... if {[llength [my GetOnlyVisibleTblColumnNames]] == 1} { tk_messageBox \ -parent $tblwidget \ -title "Warning" \ -icon "warning" \ -message "Cannot hide all columns!" \ -type ok return } if { $widgetCompounds(hide_column,$index) } { $tblwidget columnconfigure $index -hide true } else { $tblwidget columnconfigure $index -hide false } } method ShowAllColumnsCmd {} { my variable tblwidget my variable widgetCompounds set cnt 0 foreach column [my GetTblColumnNames] { $tblwidget columnconfigure $cnt -hide false set widgetCompounds(hide_column,$cnt) 0 incr cnt } } method showContextMenu {colx coly rootx rooty} { # x,y are the coordinates relative to the upper-left corner of the # listbox; rootx,rooty are screen coordinates (for knowing where # to place the menu). w is the name of the mclistbox widget that was # clicked on. my variable tblwidget my variable widgetOptions my variable widgetCompounds # re-create widget all the time: set contextMenu $tblwidget.tblContextMenu catch {destroy $contextMenu} set columnLabel [$tblwidget columncget $colx -title] set colIndex $colx set column $columnLabel set m [menu $contextMenu -tearoff 1] if { [my GetBoolean $widgetOptions(-xsortoption)] } { menu $m.sort_by -tearoff 1 $m add cascade \ -label "Sort by ..." \ -menu $m.sort_by set cnt 0 set cbrk_cnt 0 set col_names [my GetOnlyVisibleTblColumnNames] foreach i $col_names { # manage multi column menu, otherwise the menu limits # would exceed screen dimensions # --------------------------------------------------- if {[llength $col_names] > 39} { if {$cbrk_cnt < 10} { incr cbrk_cnt set cbrk 0 } else { set cbrk_cnt 1 set cbrk 1 } } else {set cbrk 0} # --------------------------------------------------- $m.sort_by add radiobutton \ -variable "[namespace current]::widgetCompounds(sortby)" \ -value $cnt \ -label $i \ -command "[namespace code {my SortCmd}] $cnt" \ -columnbreak $cbrk incr cnt } $m add command \ -label "Sort by: $columnLabel" \ -command "[namespace code {my SortCmd}] $colIndex" $m add separator } # -------------------------------------------------- # *only* show context-menu if specified by argument: # -------------------------------------------------- if { [my GetBoolean $widgetOptions(-xhideoption)] } { menu $m.hide_column -tearoff 1 $m add cascade \ -label "Hide column..." \ -menu $m.hide_column # $m.hide_column add command \ # -label "Hide column:" -state disabled set cnt 0 set cbrk_cnt 0 set col_names [my GetOnlyVisibleTblColumnNames] foreach i $col_names { # manage multi column menu, otherwise the menu limits # would exceed screen dimensions # --------------------------------------------------- if {[llength $col_names] > 39} { if {$cbrk_cnt < 10} { incr cbrk_cnt set cbrk 0 } else { set cbrk_cnt 1 set cbrk 1 } } else {set cbrk 0} # --------------------------------------------------- set colLabel [$tblwidget columncget $cnt -title] $m.hide_column add checkbutton \ -variable "[namespace current]::widgetCompounds(hide_column,$cnt)" \ -label $colLabel \ -command "[namespace code {my HideColumnCmd}] $cnt" \ -columnbreak $cbrk incr cnt } $m add command \ -label "Hide column: $columnLabel" \ -command "\ set [namespace current]::widgetCompounds(hide_column,$colIndex) 1; [namespace code {my HideColumnCmd}] $colIndex" # separator doesn't work in column mode if {[llength $col_names] <= 39} { $m.hide_column add separator } foreach m_item [list $m $m.hide_column] { $m_item add command \ -label "Show All" \ -command "[namespace code {my ShowAllColumnsCmd}]" } $m add separator } # manage visualisation mode # [$w get 0 end] is too slow if the listbox is pretty full... if {[info exists widgetCompounds(mstate)]} { set st $widgetCompounds(mstate) } else { set st disabled } $m add command \ -label "File Operations:" -state disabled if { [my GetBoolean $widgetOptions(-xfilesave)] } { $m add command \ -label "Save to file..." \ -command "[namespace code {my Save2File}]" \ -state $st } if { [my GetBoolean $widgetOptions(-xfileread)] } { $m add command \ -label "Open from file..." \ -command "[namespace code {my OpenFromFile}]" \ -state $st } # ----------------------- tk_popup $m $rootx $rooty # ----------------------- # make sure, popup-window stays on top # when using "tear-off" the 1st time wm withdraw $m wm deiconify $m } } ====== ***xtablelist_readwrite.tcl*** ====== # ----------------------------------------------------------------------------- # xtablelist_readwrite.tcl --- # ----------------------------------------------------------------------------- oo::define XTableList { method GetAllVisibleItems {} { # only take visible columns into account # "...what you see is what you get..." my variable tblwidget set is_hidden {} set cnt 0 foreach column [my GetTblColumnNames] { lappend is_hidden [$tblwidget columncget $cnt -hide] incr cnt } set lst {} foreach i [$tblwidget get 0 end] { set cnt 0 set sublst {} foreach xitem $i { if {[lindex $is_hidden $cnt] != 1} { lappend sublst $xitem } incr cnt } lappend lst $sublst } return $lst } method Write2File {fname} { my variable tblwidget my variable widgetCompounds if {$fname == ""} { return } set lst [my GetAllVisibleItems] set fp [open $fname "w"] foreach i $lst { # regsub -all "\{" $i "" i # regsub -all "\}" $i "" i set str "" foreach item $i { if {$str == ""} { set str $item } else { append str $widgetCompounds(DELIM) append str $item } } puts $fp $str } close $fp } method Save2File {} { my variable tblwidget #-now we use this one- set fname [xtablelist::getfilename \ -parent $tblwidget \ -title "Select file where to store Listbox information:" \ -oktext " Save to File... "] if {[string length $fname] > 0} { my Write2File $fname } } method OpenFromFile {} { my variable tblwidget my variable widgetCompounds set in_file [ \ tk_getOpenFile \ -parent $tblwidget \ -title "Select file:" \ -initialdir $widgetCompounds(default_dir) \ -defaultextension {.txt} \ -filetypes {{"Text-Files" "*.txt*"} {all "*.*"}} \ -initialfile ""] # read values from file and uptdate listbox ... if {$in_file != ""} { set data {} set fp [open $in_file "r"] while {![eof $fp]} { set i [string trim [gets $fp]] if {$i != ""} { lappend data [split $i $widgetCompounds(DELIM)] } } close $fp # foreach i $data {puts "--> $i <--"} my addValues $data # finally execute post command catch { $widgetOptions(-xfilereadpostcmd) } } } } ====== ***xtablelist_filesel.tcl*** ====== # ------------------------------------------------------------------------- # xtablelist_filesel.tcl --- # ------------------------------------------------------------------------- # # Purpose: # Utility package supporting a more convinient file selection dialog. # The following additional features where added: # - the possibility to generate a file-name, # - use the dialog's default file-name, # which might be sufficient for most of all cases, # - use standard file selection dialog # # ------------------------------------------------------------------------- # ------------------------------------------------------------------------- # file action utility dialog ... # ------------------------------------------------------------------------- namespace eval xtablelist { variable widgetDefaults variable widgetImages switch -- $::tcl_platform(platform) { "windows" { set homeDir $::env(TEMP) } "unix" - default { set homeDir $::env(HOME) } } array set widgetDefaults { title "Selection file:" DEFNAME "NONAME" def_ext ".txt" oktext " OK " ENTRY_WITH 45 is_ok 0 } set widgetDefaults(init_dir) $homeDir set widgetDefaults(defaultfile) [file join $homeDir "NONAME.txt"] set widgetDefaults(filetypes) {{"Text-Files" "*.txt*"} {all "*.*"}} # initializing required images... set imgdir [file join [file dirname [info script]] "images"] proc LoadImages1 {imgdir {patterns {*.gif *.png}}} { foreach pattern $patterns { foreach file [glob -nocomplain -directory $imgdir $pattern] { set img [file tail [file rootname $file]] if { ![info exists images($img)]} { set images($img) [image create photo -file $file] } } } return [array get images] } array set widgetImages [LoadImages1 $imgdir] } proc xtablelist::PositionWindow {} { variable widgetDefaults wm geometry $widgetDefaults(this) "+250+350" } proc xtablelist::_ok_callback {} { variable widgetDefaults if [file exists [set fname [$widgetDefaults(input_entry) get]]] { set answer [tk_messageBox \ -parent $widgetDefaults(this) \ -title "Question: " \ -message "$fname\nalready exists\noverwrite ?" \ -type yesno -icon question] if {$answer eq "no"} { set widgetDefaults(is_ok) 2 return } } set widgetDefaults(is_ok) 1 } proc xtablelist::EntryBindingsCmd {} { variable widgetDefaults variable widgetImages if {[$widgetDefaults(input_entry) get] == ""} { $widgetDefaults(input_label) configure -image $widgetImages(isempty) $widgetDefaults(ok_button) configure -state disabled } else { $widgetDefaults(input_label) configure -image $widgetImages(ok) $widgetDefaults(ok_button) configure -state normal } } proc xtablelist::SelectFileCmd {} { variable widgetDefaults variable widgetImages set log_file [tk_getSaveFile \ -initialdir $widgetDefaults(init_dir) \ -defaultextension $widgetDefaults(def_ext) \ -filetypes $widgetDefaults(filetypes) \ -initialfile "" -title "Select file dialog..." \ -parent $widgetDefaults(this)] if {$log_file != ""} { set widgetDefaults(init_dir) [file dirname $log_file] set widgetDefaults(entry_val) $log_file $widgetDefaults(input_label) configure -image $widgetImages(ok) $widgetDefaults(ok_button) configure -state normal } } proc xtablelist::GenerateFilename {} { variable widgetDefaults variable widgetImages # note: it is not possible under windows to use ":" as date separator! # clock format [clock seconds] -format "%H:%M:%S" set fname [clock format [clock seconds] -format "%Y-%m-%d"] append fname "_" append fname $widgetDefaults(DEFNAME) append fname $widgetDefaults(def_ext) set widgetDefaults(entry_val) [file join $widgetDefaults(init_dir) $fname] $widgetDefaults(input_label) configure -image $widgetImages(ok) } proc xtablelist::CancelCmd {} { variable widgetDefaults set widgetDefaults(is_ok) 2 } # ------------------------------------------------------------------------- # gui declaration # ------------------------------------------------------------------------- proc xtablelist::getfilename {args} { variable widgetDefaults variable widgetImages set wparent "" set ind 0 while { $ind < [llength $args] } { switch -exact -- [lindex $args $ind] { "-parent" { incr ind set wparent [lindex $args $ind] incr ind } "-title" { incr ind set widgetDefaults(title) [lindex $args $ind] incr ind } "-defaultfile" { incr ind set widgetDefaults(defaultfile) [lindex $args $ind] incr ind } "-defaultext" { incr ind set widgetDefaults(def_ext) [lindex $args $ind] incr ind } "-filetypes" { incr ind set widgetDefaults(filetypes) [lindex $args $ind] incr ind } "-oktext" { incr ind set widgetDefaults(oktext) [lindex $args $ind] incr ind } default { puts "unknown option [lindex $args $ind]" return "" } } } set w $wparent.getfilename set widgetDefaults(this) $w catch {destroy $w} toplevel $w wm title $w $widgetDefaults(title) wm iconname $w $widgetDefaults(title) PositionWindow wm transient $w $wparent bind $w "[namespace current]::CancelCmd" set f [ttk::frame $w.info -relief flat] pack $f -side top -fill x -padx 1 -pady 1 ttk::label $f.img -image $widgetImages(job_engineering_logo) set msg " Select a filename or press \"generate-filename\" to create one." ttk::label $f.msg -text $msg pack $f.img $f.msg -side left # button row # ---------- set f [ttk::frame $w.buttons -relief groove] pack $f -side bottom -fill x -pady 2 # image + button # -------------- set fb [ttk::frame $f.img_button] # pack follows later on: pack $fb -side left -fill x -expand true ttk::button $fb.ok \ -text $widgetDefaults(oktext) \ -image $widgetImages(filesaveas) \ -compound left \ -command "[namespace current]::_ok_callback" \ -state disabled pack $fb.ok -side left -padx 4 -pady 4 set widgetDefaults(ok_button) $fb.ok ttk::button $f.cancel \ -text "Cancel" \ -command "[namespace current]::CancelCmd" pack $fb $f.cancel -side left -padx 4 -pady 4 -expand true set f [ttk::frame $w.rbuttons] pack $f -side bottom -fill x -padx 2 -pady 2 ttk::button $f.getlatest \ -text "Generate filename ..." \ -command "[namespace current]::GenerateFilename" \ -style Toolbutton pack $f.getlatest -padx 4 -pady 4 set f_file1 [ttk::frame $f.part_num1] pack $f_file1 -fill x -expand true ttk::label $f_file1.img -image $widgetImages(isempty) pack $f_file1.img -side left set widgetDefaults(input_label) $f_file1.img pack [ttk::label $f_file1.lb -text "File-name:"] -side left ttk::entry $f_file1.en \ -width $widgetDefaults(ENTRY_WITH) \ -textvariable "[namespace current]::widgetDefaults(entry_val)" pack $f_file1.en -side left -fill x -padx 4 -expand true set widgetDefaults(input_entry) $f_file1.en ttk::button $f_file1.b \ -text "..." \ -command "[namespace current]::SelectFileCmd" pack $f_file1.b -side left bind $widgetDefaults(input_entry) "[namespace current]::EntryBindingsCmd" bind $widgetDefaults(input_entry) "[namespace current]::EntryBindingsCmd" set widgetDefaults(entry_val) $widgetDefaults(defaultfile) focus $widgetDefaults(input_entry) if {[$widgetDefaults(input_entry) get] != ""} { $widgetDefaults(input_label) configure -image $widgetImages(ok) $widgetDefaults(input_entry) selection range 0 end $widgetDefaults(ok_button) configure -state normal } # wait user grab $widgetDefaults(this) tkwait variable "[namespace current]::widgetDefaults(is_ok)" grab release $widgetDefaults(this) if { $widgetDefaults(is_ok) == 1 } { set retval [$widgetDefaults(input_entry) get] } else { set retval "" } destroy $w return $retval } # ------------------------------------------------------------------------- # test-run ... # ------------------------------------------------------------------------- if 0 { package require Tk wm withdraw . catch {console show} set rval [xtablelist::getfilename \ -parent "" \ -title "Select file where to store Listbox information:" \ -defaultfile [file join $env(HOME) "Test.txt"] \ -filetypes {{"Text-Files" "*.txt"} {all "*.*"}} \ -defaultext ".txt" \ -oktext " Save to File... "] puts "File selection result: \"$rval\"" } ====== ***xtablelist_demo.tcl*** ====== # ----------------------------------------------------------------------------- # xtablelist_demo.tcl --- # ----------------------------------------------------------------------------- # for development: try to find autoscroll, etc ... set dir [file normalize [file dirname [info script]]] # where to find required packages... set auto_path [linsert $auto_path 0 [file join $dir "."]] set auto_path [linsert $auto_path 0 [file join $dir "../lib"]] package require Tk package require TclOO package require autoscroll package require tablelist_tile package require xtablelist # catch {console show} # 1st example: set t [xtablelist::xtablelist .t \ -showseparators "yes" \ -labelcommand "tablelist::sortByColumn" \ -width 80 -height 10 \ -xfilesave 1 \ -xfileread 1 \ -xshowbuttons "yes" \ -xrefreshpostcmd {puts "Refresh postcommand done."}] pack $t -fill both -expand true # maybe some configuration changes later on ... $t configure -xmoveovereffect "yes" # create some random test data... set header { {"ID" 10 left} {"Category" 22 left} {"test-column" 16 left} {"Hello\\nWorld" 10 left} {"test" "hidden" center} {"last\\ncolumn" 10 left} } $t configure -xtabheader $header set data_list {} set cnt 0 while {$cnt < 40} { lappend data_list \ [list $cnt \ [expr {$cnt +3}] [expr {$cnt +4}] \ [expr {$cnt +1}] [expr {$cnt +2}] \ [expr {$cnt +5}]] incr cnt } foreach item $data_list { $t insert end $item } # 2nd example: set t1 [xtablelist::xtablelist .t1 \ -showseparators "yes" \ -labelcommand "tablelist::sortByColumn" \ -width 80 -height 10 \ -xfilesave 1 \ -xfileread 1 \ -xshowbuttons "yes" \ -xrefreshpostcmd {puts "Refresh postcommand done."}] pack $t1 -fill both -expand true set header { {"ID" 10 left} {"Info_Procs" 20 left} {"Body" hidden left} } $t1 configure \ -snipstring "..." \ -xtabheader $header set data_list {} set cnt 0 foreach p [lsort -dictionary [info procs]] { # set body [string map {"\n" " "} [info body $p]] set row [list $cnt $p [string trim [info body $p]]] $t1 insert end $row incr cnt } ====== ***ImageLib.tcl*** ====== # ImageLib.tcl --- # Automatically created by: CreateImageLib.tcl set images(up) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABHNCSVQICAgIfAhkiAAAABl0RVh0 U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAL/SURBVDiNtZRNaFxVFMd/5368eZkxRmQs bTEGxbZC0IWMpU5SbCmxILapFCO2LgSlWbhLbFJBcKErP0BcCIqCdeEiUAviQoJIwIgW3biwCoYG jTImTIXWTjsz7+O4yLzwUkuSgjlwuPdd7vmd/z33vCuqymaY2RTqZoLdRjfunXTvg2zfNh8PT01p 8r+AByf9S9vv6DuGQWr627vA6Hox65ZiYMIdva1Ufvlg9WhpaM+RYs+t5eN7J4IX1ouTtbpicCyo FEulmacOniidr8+SpBG7ynv4dPrjxpVW48i3b0Rf3rTiR8al13o3/cSBZ0uLV+f46/IFapfmWLh8 nsf2PVnyzp0ZnAx33RR4cFK6U2dnDu97pie1LS5c/BFnHNZ4fl36nkZSZ6h6qBuNv6qOye0bAo+M iFXc54/uHundUt5qfln6Dmt8xx2I8MPCF5RuKcrAg0NbjHfTlVHx64Jrd9v3qv1Du/t3VPxPta+x YvHOUwgCfGBQ28Z45dzCWfruvMfdf+9D/V099vSa4IEX/fh9d1WO7a8Mhz/XZjFOCMMCYVggCD2R aeAKQlAw4CPO/XmGygMPh33bdg5XJ/ypPGulK6rj7vG+rTumnjt0qss5j5KikjAzf5pYWtSvzXMt +Wc5SuHwzpNoqmgKzXaLs9OfXK1f/OPp2bfizyD3gxgr478vznW98sHzAFgvzVdPfBj6wNFoLxLZ Bt4bBFAF44R3PnqtGbc17CCKOBkDVoNnX4/2X1cWNdbiA8+V1hK+YDAGEEFVsVaI2xp+82Yk19d3 FfhGZozQiP9GbYwLBOMEEUFTRewNeRsEi6WZXkIMGCs4bzBOiNspsjZ3dVfIsjkRKWRrzbgBCppC mihJpGgC6EpMUUQKIrJKpMuAgO98u84cVTjQO4pKirEgIizfHqTpyhvTDcRAJCJxNne5BDYHdUD9 5NvHy2sfmHomImcKJKKqmeI8NBuzZKbjHb2kHY+BJFMJtIG2qqb/eTY7SWzOM6jtbElz8CQHV83B /gXtSQriGSyg6AAAAABJRU5ErkJggg== }] set images(filesaveas) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAMAAADzapwJAAAAAXNSR0IArs4c6QAAAU1QTFRFtQBI AAAAOGeLP2qJO2yRP2yGQWyKPG2RQm6IZmhkSW6CZ2lkQnCSP3KWTXKCVHJ7bnBrRHicVHeAV3h9 TXmRbXRlbnRlUXmKU3mKW3pycnVrR32iR32jXnx5YH1udXlsSoCmW36ISoCod3l1ToewfIFtbIV3 UIixUImyf4F+UYu1aImTU4y1cIqCg4WAbY2OWJK9W5bBYpa7XJfDjo+NXpnGXprHYJzKYJ3LlJaR Yp/OY6DOY6HQZ6LOZ6PSa6XTm52ZdKjTdKjUdanVga3Rj7bbsbGwuLi4yMjIysrKy8vLzMzLytDE zs7Oz8/NzNHF0NDQ0tbM09jM2NrY3t7e3t7f397e3t/f39/e39/f4ODg4eHh4eLh4uLh4+Pj5eXl 5ubm5+fn6Ojo6eno6uvq6+vr7Ozs7e3t7u7u8PDv8PDw8PDx9vb2+vn6////640m9AAAAAF0Uk5T AEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYLFTEZSbLK vAAAACJ0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUCBvbiBhIE1hY4eod0MAAAEjSURBVBjT bc9nV8IwFIDhNKJ1G/feVXBhapGoqLgnLowURa2oqSv2/3/0pvRAOfh+aO95mnNPihBCsz0YauhG 1bWuHOwe7qcGmqu0f6uzLTKS2ktP1YV0dHkSno3DyaQ5UV/h9iX/FVmk5lrXWJkHZwg0jim00KHm kg9Jlc8Mq7HkcVcKITCNUbqJhbgVcZ933HcJ91a8gXX8KNaVkvNnOMvYdmyemtYqnL9UW8gL8I3O jKgRMyz9SghX8bS/OoOZYUQtnBFCunPACdeR8kO5r1I6bgJ2HBffivBBZjHTs4DO08MRQS3XJKgX 9wXTRRMikti5O27zPOd2jms8fw+ESIG8npb71L5+voEU/1bY0zzPC9gLFeKaFJ8VajqB3yT/hP4A lj1VqgSJVQgAAAAASUVORK5CYII= }] set images(folder) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAMAAADzapwJAAAAAXNSR0IArs4c6QAAAhlQTFRFAAAN PDw8RUVFRkZGSkpKTU1NLFWJUlJSVVVVOVqFVVdTVlhUVllXV1lVWFpWWlpaWVtYWlxZWlxbW11Z M2OhXF5bXl5eNGShNGSiXV9bXl9cNWWkNWakNWalNWelNmekYWFhNmelNmemN2ilN2imOGmmOWmn OWmoO2mlOmuoZWVlPGumQW+pRG+ma2tqQnKvb29vTHSmcnJyVnqmdnZ2TX22VX6xToC2enp6UYG4 e3t7YH+laX+aa4SlXom9dYumkZGQcJjFc5nEj5ehi5iolpeVcJ7PcZ7PdKDQnJ2bnJ2cgKLLm5+j np+hn6CeoKCffKbTfabUfqfUoqOlgKnVhqjPpKWnhKvVpaamhKvWpqampqeph63XqKioja3Sia7Y qqqqiq/Yq6uri7DZjLHXrKysjbHZra2tjrLYj7LakLLZjrPZrq6ukLPZr6+vlbPWkrTbkrXakrXb sbGxlLbblLbclbbclLfclbfcs7Ozlrjclrjdm7fZl7jctbW0nbnamrrdnbzeubm5ob7eor/go7/e vb29p8Hep8HfqMPiqcTiwcHBqcXiqsXhxMTEycnIts7my8vLzc3Nz8/P0NDQvtPq0NHQv9TqwNTq 0tLS09PT1dXU1NXX2tra3Nzc3d3d4ODg4eHh4uLi4uPl4+Pj4+Tm5OXn5eXl5ebo5ubm5ufp6enp 9/f3+Pj4+fn5+vr6+/v7/f39/v7+lBbl4QAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBI WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYLFTEsHwEOnwAAACJ0RVh0Q29tbWVudABDcmVhdGVk IHdpdGggR0lNUCBvbiBhIE1hY4eod0MAAAE3SURBVBjTY2CAAm5ebl5ePj4pBlTAvWbtuvUbNvgL QPkWVmDANXfWrJmTJ21yEIUIm8yaMnnSpIlc87yAYPamja6CYGGjyZV56UkJ3IsWLVy4YMHq5VMk wcIGk/JSE2KjuFf6eXp6zl+yZJowWFivPzU6LNiXZ9WKFcuWLV26eI4QWFirz0VeVVVVWU1NDUip qqjIyCoBhRW67Z2mT506dToEzJgxY4I0UFiszda7JxsJVPWqAIX5m6zjuoqQQHmrOlCYo864prMa AZJL6zWBwuzFhu2dDTBQmxbTmA8SZs3R7WgBCVSUFGTGx8TENIaqAYVZEjSayxIjgwJgoNBRDijM FCGT5eGOBMLtQN5h8tEOcUMGgaZgYWez3BRkkKEPEma20bFEAeaKIGFGTnEUICHCxkAiAADVtH2Y SZPqewAAAABJRU5ErkJggg== }] set images(mail) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAMAAADzapwJAAAAAXNSR0IArs4c6QAAAsRQTFRFNmut VTFgXzRlQD1zHUeBHkiCWzxYIkqFdDpQJUyHbD86J06Jb0oLNFCHYFETR1Q/MFaMMVeNQlSNYU19 f1IEJF+fNluSQlmGilEJZFNxllAFglIyaF0Wj1QDNWKeLWSmNmOfPmKZRmCZOGSgX2YaVmkhMWep MmiqYWsKkldAO2ejQGeYkVwdUGOYNWqsfmA/Z2ksrVcWaWonRGqbOW2vZ2hmaHEUpWEYa3EsR3Cu cHEta21qz1oAmGgmTXKkj2lDbncbzF4AbnBtSHWsjGpVQ3ezw2MJymIARHi0RXm1THivV3ajwWcJ Rnyy1GQAdXs2T3qyVXmsw2kNq20wwGsLdXd0UXy0eX85U362S4G3Wn6xVX+3eXt4q3YeXICzUIW8 XIOwvXUlfoB9WYe4XIa/sXwsWoi5Yoa5r4Aug4WCx30l1Xgwt4ExaouyYI2/hZBBynw8YY7A03wy iIqHcY2vt4YtaY+8co6wt4c1uIg9eZK7wYo6fJSxvY1CcJfEcpnGxY5F24k8c5rHw5E/dJvIu5JR eprDwpJNmZiQyZBh4o46tphmf6DIgaLKuJtvxZpTy5lO4pgm2JhKu55y35sniaXIz51Qi6fKjKjL janM359Qj6vOkKzP4KM90KVd5aI+4aQ+46JTqauo5aNO5KNU5KdBlbHVmbHPlrLWm7LQ3qpd56pL 66lasbOvrLS85K5U465bo7bPr7bL46+CqbnM4LRrwLq57rhkssHVrsLb6bxz67108rxutMTXssXe wsTB9L5x7sB3uMjcu8rex8nGwsvTycvI9MZ878Sg+8Z+v8/iy87KwNDjzc/L98qGzdLV786a5dC/ y9flzNjm09vk3d/c8dzL3+He2eLq6evo7vDt7/Hu8PLv8fPw8vTx9fP38/Xy+fTy9Pfz9vj09/n2 +/j9+Pr3+fv4+vz5/fzz/P/7/v/8YPjk8wAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBI WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYLFTAZUKn7/QAAACJ0RVh0Q29tbWVudABDcmVhdGVk IHdpdGggR0lNUCBvbiBhIE1hY4eod0MAAAGvSURBVBjTY2Bg6ChGB6YMQFD8Gh0Ug4QzTz9/8ezJ kyePgejx40dP75zOBAknvT794vHjB4+AQo8f3Xv8YtHrJJBwzOvHR148uAcEd+/effJi7Z3XMSDh 0Nf37519DhS6e+fOvdfnb95+HQoWPmErJRu8+c6tuw9vvd5/+zZU2L5x0rxpDebXQG7YdhUk7AQS 1pnV316R6GPjXtB57PpjkLA1SFhiQm1rVtDicwfWFF18ua789u0tN0DCIs2llSFrju9efbAr+yi7 wO3bNZf2AoX5qjNi/U7uvrB+/gZD9svsp28bHyoBCnNJ56S67Vm6dcrcyexnTrG/fq290puBgd9C RZ9HZsn2iQu62ffNOSzGqWjXJsjA7++Qn2/AoblwVR/7oZUzZ67obWkqFAcKm+UbMU2XdHFk31mW Funr5eURH8UCEjZjmq5nskmYfWWYl6enp0dgPQvQaH9VDbZ0Nb2NV5zZZ6e4BtT3TOVmBwmHWzGl yaup74gTZe/Jq+Pm5hYE+Yafn58pQV5IOVdBjpd95jJ2Bjhgio7W9bS0tFTSYq9CEmZkggFmdlaw CAAubtLM/zAGbQAAAABJRU5ErkJggg== }] set images(reload) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI WXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH1gcaChMjSyiLTwAAArdJREFUOMutlE1rE1EUht9z5yOt qa39NNaKjSKiVAtWhYJYqShtlSwEEcGVyPwGl/4BF+ouGxf6C2bhR6GgoBQXxbYLsdQWa2maJpiJ zUczNzP3uknCZJiktXjgMHDP4TnvvHPmAv8YsbguY3H94G59DPuL7Vhc7/zv4CsT5wEg0wy+X8W7 wmkXP8MAHgJ47odul1No1/rw6d0iAHSZBrf2BI7F9UkAbyb1/kX38sDZYltJrdbKZQd5noGdE4hE IoFwagC9CeD97fFRFFpd/Mla4HIHjBFIJXDbBlMJVrIAYkA0Gq3Cw6bBi4HgWFw/AWDl+q1RlGUR aStZkyAcCaYQpGbDzknYeQGqfCUPXDMN7qgBgl9cvXTaJlAoZW1CuvVFl2yoCsGxRe3MA+0yDe4A QBB4SvaGkMyvQlEYujsPA2DQKARZaZBwsS2WoIcJA5HBQI+DwNCoFQqp6Ohph7ZVxMzscl392tRF qC1oCG2yx4S2jlZspRNyZnY5C+CMaXAyDU4AoJDWFNoQrEBFRBmSS5+zLoC7psG/e+u2W6hCjwVB G1phy5xbkqoDIHQqwb/5t8cD3djrL00AVo/Ou7k/pTQA4OkTJCt9VB3AC/K4afCE96yZYgJAUsov v62FCcKwqDnjCdPguk+U9GVdsTqZ5TfxeHpH6XRcLtVSKDv5TLtfgau+1CpPxf9GXjVUKbKfH0Tx 5A2WSqxlYhfGoyK5kRmzVmW8mAZV+r3JPFB4FSs+xQSAlt+Kr4NjbC6VtB70dx9Ybx9y7x0ZYT/W PoqEB1YFKhWg8Nqh+C6jGnxlWqwcitJLrjoaAUSMcpFhZod7ycn+krZwahARACbygZnHlprvI4+U 7r5z7A4x9EkXWwuv3NfClaJHKCLST2qoRYqNdbkzP+c61SEUsG5B2eiK9W5DnRV/AfIcOgCbYwEf AAAAAElFTkSuQmCC }] set images(delete_reverse) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABHNCSVQICAgIfAhkiAAAABl0RVh0 U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPESURBVDiNtZVfaFt1FMe/53eT3CQ3N+uS tmnarC6hGGVizdrRTgoTJutDUJ988GnI9jSqgmzgWwhbQV8mqAx98MXhk0/Cxh7WgQ4GrStkxbbU bSk1/ZPENqHrTW5u7r+fD2lcm9YyhR74wu8Pv8/v/A7n/A5xznEYxg6FCsBx0CYRCQD8ANwA3DIg KkAdgLatLc659Z/AROSTge7vgPfDRGe8QL/AeYdF9FcNmFnh/JdLwE9EVOCcV/ac3y/GPp8v9Anw +juq+k3HwMBL7cmk6OrthaO9HWapBH15GRt379bXHzxY/Nnr/fhr4PdKpVI8EByNRtuubGyMDpvm 98fHxry+06epns/D2tqCVa2CiSIESYLY0wN1dpb/ef26+itj57/q7JzIZrPP9gUPDg46+1Q1/unC wr1X0ulOR1cXak+egJsmwHlDtg1YFjgRvPE4rM1N/JFOF76Ix99e8ngeT09PG0BLVoRCoeClbPaz 7mQy4OzpQTWTga0ogKY9V73eULWK6vQ0nMEgQmfPBscWF6/IshxssnaB/X6/WzKMd4PnzjnUR48A Vd0Xyut1QNeBWg3KxASC/f1On66/19XV5d4DTqfTjrdyubDzyBGReTwwi0XwWm0XlDQNpGng6+sw 5+ehT01Bm5oCMQaHKHrfXF3tTKfTjtZ0c/UuL7/qDYdNY27OZWazEHw+MFEEt+2Gh5oGXi7DNgxw zkG2DUYEq1yGLxKx+paWXvsNmAVg7gTbJMuKoSiAYcDO5wHGwBkDMQYiaohzMMbAOQcHYNs2yOWC oWkcfv8WALs1xnp1dHReKxREoa0NzOl8DiMCa14gCI1xc93phOD3o7a25tpIJucA6LvAqVTKppGR Z5zzolEsQozFQERAC3wnFEQQYzEYxSIgCGvS0JCSSqX2eIxAIFCxYrHx1du3NWlgAEySdnu9reZc kCR4Tp7E6p07mh6Nfh4IBP4p7dbKo5mZmW5rZOSHUCJx5uipU0JtchJWoQAmCA0vAXDbBguF4B4a wubDh1Yhk7lH9+9/mEgk8gD4fmAAcM1fvXqiPj7+o9zbG+1OJt22qsIulcArFTBZBgsGQV4v8rdu aUout+i5du2D+OXLC834/hsYKysrnnZB6Hg8PDzGi8WP5L4+LoXDoisQYHq5bKv5fH3r6VOiUOjL lycnv92wrPVIJFLb9fQDOogA4Oj6jRuR0s2bb+i5XAKVygkmy7OOY8cygQsXMp0XL64BKDdT7EXB Oy8QAbgURXHIsmxuP7kOYN9P/kXB/8sOref9DbaUvAtd86h8AAAAAElFTkSuQmCC }] set images(down) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABHNCSVQICAgIfAhkiAAAABl0RVh0 U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAL8SURBVDiNtZRPbBRVHMc/781Md1bTGMCk hYNtOIiAnkw0bSFpNCGeOEAwMRyMMaReNCY0JXpFozQWT3JWExsEIzaxJkSREGiJIglRNCqVDSEI xlKqsN3ZeX9+HnZ2O112Wznwkl/e78283+f33nd+v1Eiwv0Y+r5QgbDdi4GR6AaermWjNX9NjZru ewLj6Xp76COsNzhvsT7FeYvzBusNqUs4dPittonbgwFQnP7jCFW7QNUukLqk4T+3cc8Kl7nHoVD/ a98KYEFYrBqR2lrEs1I1LQtehHgEX3signHVFU/c0HjLSHRSPIONjKFKRHws4vF4vNQsdRUSW27s GRiOFo+uOTU1agaXgL2TsZ7uR5/es/3NYhhEOLGx8xYvFrRHh4L3CQm3iAoaHcAru96IRcCYKhMn xhdmb/15sM5Tea0GhqO9m9Y/uX/H4MvFC9e+oWLnsVSp+jvMVa+R2H9BAQIiEOtOtvbs5uTUVwuX r8/snx4177bUeOo9M/brlR/Gvz13LNm8rp8gVBhV5u/qDFbfIYo1HbEmijXFYszW9bs4f/FscuXG pYk89C4wwNqSG5r+5evvf7z0ndm4tp/ZtITq8EQZMIoDOuKAvp4dlK5etj/9fu7nyrx7sZmjWpXN ln2qU6nowvZnX+gNH6roi/PHCUKNDhVKweOrtlGZ0zIxefS6M/aJ6YMy18xoWW5nDshtbczg5Imj /xTcKjas6SfsUEQFzYaH+yi61Xx5/IvbQvBMK2hbMMCpMblqU7vt2OSn5e5oE+sefKxmhc0c/ny8 XE3NzjMHkt/axbeUIj8GRsKdqzvXfLz7+ZceCCLFJ599WL45e3Pf6dH0g+XiloCVUgoIcqYB3fda sPeR3t7hoKBUaaZ05Oz77nXA58wBTkTsEnAGjKg1TJjzg2zWT70avBMEuuv8ITOUppgMaDOoBUw2 W8DUwVEO2Ow3r00OYtqs03pL16/Q/E+sX1NnlvVdQ4LmE6dAKiL+ro/XTufMryerw10OLpKD/Qce AIZcIO5IFQAAAABJRU5ErkJggg== }] set images(ok) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAFzUkdC AK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dE AAAAAAAA+UO7fwAAAAlwSFlzAABJ0gAASdIBqEWK+AAAAAl2cEFnAAAAGAAAABgAeEylpgAAA3dJ REFUSMftlE1MHGUYx/8zszO7M8t+FOxSoHZbRCzFtLQH2lCbIMWqbUiNsSH2YGNMPBlNLxZ64qKk 1XixMTGNmnjxq0YvhESFkm1AUJvCtnalAlKWlcrusuzMztc7X15Y3a5LacB48p/887555nmeXybP kxf4X2uI2khxW1dZG0u7LlEMNUeI3j14Tun/1wAdPRA0wz/T9fz5Ssdx8MngRSmR+i1hqKRz4G05 ms+j1wtQia9n/yMHAz6vB7oTx6vPnvU981jnTs7jfr8wb12A1m7fTreLf+VI83HPbHIUSXEaKhFx fXpCMWzz8w0DOJr+6OiB426FLCKr3EGFtw6TczecqcTNhMmJ724I0H7WezLkr9rdEG6k55eicNEC eFcFvox8qpu2fWqoB+a6AU/3lPtpuC4ca+kQ/shOghgqQr56RMa/03WS+2KgV/q+uKYk4MQJMKXi FrHeaqrbxwu8GylxFl5uM5YlCaOxEWLazulSNXcBWl/nt7Z3+xcydWXKE2f8r6Fgjdu7hL0Mw73Q 3NDs+T3zMxwHCPDV6B/tUyzHOj3QK6VLAf5ucGZTAIx1tXV36/btVTuY/rE+Obmc+smC0XmIk5Mj JDDxeFPbrupQOZ2WZlHhCyORzNhD44PXv3kjuxeAc88/YBj7q6aH9tSEq6oZUY3j6IEnvfvqm1oY sL9EVO/X5f6K2m1bqumUdBsM7YbtcLgSvUIM0zy1WnMAcOUvtuM0Ch43Z1kmND0HWYuhrmYrWxnc HBwaHz528NH99JIUh2kYCPprMHbjB802yQeXz8kT91qMv4ZZ28L2JdILT2VlkQ9X1rK2bSKr3AHL 0mgI11OWrSCnpeHhfBBlHVdvXRNli+uIDyvkvgAzwyT14GH9oiyR8MzCXP2WTZWc4PZC1jKQtQx0 QwZAgWeDiETHZJXoL0fOL1/DGir52B3uLnuOoZgPd4UfFraFQoyii7BsAt4dwPxi2ozFp0a/fVM8 tFbzf6xpXgO9uUsg2HPz9mRsLBZVABYsw0PTdcTiU6atOS/hPl9iZpWYa3pEl5cS5OPgDvuB+fRi o08Q2FvxuCrl9PcuvyP1AeBW7FqpoVZ810ZRRXemlJtf5I/4Q+wF2Pj1x8/Ek9k5qACsNeyUmgG9 0rTwLHQ+3wFgF9kqOlcfctG3fGOqCOAUgPKx/15/ArQwg1fnUtydAAAAJXRFWHRkYXRlOmNyZWF0 ZQAyMDEwLTAyLTE3VDA2OjQ2OjUwLTA3OjAwat5j0AAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMC0w MS0xMVQwOToxMzoyNS0wNzowMAO3oKwAAAA0dEVYdExpY2Vuc2UAaHR0cDovL2NyZWF0aXZlY29t bW9ucy5vcmcvbGljZW5zZXMvR1BMLzIuMC9sagaoAAAAE3RFWHRTb3VyY2UAR05PTUUtQ29sb3Jz qplE4gAAADF0RVh0U291cmNlX1VSTABodHRwOi8vY29kZS5nb29nbGUuY29tL3AvZ25vbWUtY29s b3JzL1AdtesAAAAASUVORK5CYII= }] set images(delete) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAMAAADzapwJAAAAAXNSR0IArs4c6QAAAF1QTFRFAAAA xwgAzRUA0R4A1ycA3jIA6QIA6h0D/gEA/hoC6i8I4zoA/ikG/jUL6EMA60cS7V4e/kcU/lYd73It +2cq/XY38oc9/oZH9JVJ+phV/qFm/qx1/riG/sSX/sui1vsBTgAAAAF0Uk5TAEDm2GYAAAABYktH RACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYLFTAtcR0PSAAAALhJREFUGNN9 0dkSgyAMBVCSgBsVqIji1v//zLoB6kzLE3PmTshVxn4fpdKdKKmSSQmDDl6KoMYgnvpZvNidk3FO 766kX5a543zPOtdqgC0ipZ/nyXEKeg6Xopum0fK7Mia4HcfBtqtWSdenuB36fssiXgtxsofCrefx 2pOJtrlN01QAj6zT+l3XefJzX4SqfpVZ8NgNIS+L4vRLN4CsCE5oYrfdQxx1XGz1OBwxrQuQVrl+ B4A/f/cLR24LBcAhtFwAAAAASUVORK5CYII= }] set images(printer) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAMAAADzapwJAAAAAXNSR0IArs4c6QAAAV9QTFRFAAAA a2lobGtpbGxpbW1rbm1sbm5scXFudnV0dnd0d3d1eHl3enp3fX57gYB/g4OAhISBhYWDh4aDh4eF ioqIi4qIiouIi4uIi4uJjIyKjo2KkpKQk5ORlJSSlJSUlZWVl5eVmZmXnJuanJyanZybnpyanp6e n5+dn5+foaGfoqKgo6Ogo6OhpaSjpaWkpqWkpqamp6enqKinq6qpq6uprKuoq6urrKuqra2tr7Cu sLCws7OxtLS0tbW0t7e1uLe1uLi4ubq4urq4urq5vLy7vLy8vb29vr68v7+/wMDAw8PDxMTExcXF x8fGyMjHy8vJy8vLzc3Nzs7O09PT1NTU4ODf4eHh4uLi5OTj5OTk5eXl5+fm5+fn6Ofn6Ojo6eno 6enp6urq6+vr7Ozs7e3t7u7u8O/u8PDw8fDu8fDw8vLy8/Py9/b19/f3+Pf3+fn4+fn5+vr6+/v7 /f39////KTpVyAAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwY AAAAB3RJTUUH3AYLFTIVaynVVAAAACJ0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUCBvbiBh IE1hY4eod0MAAAD7SURBVBjTY2DAAyyRALJwSTEUlKAKhwUEiEgEBsWhC4dJy8jIxiWiC0sAgaRk EppweGSUrGxCUjKacGRgkKJeUnIqsjCvZUlUTJyvX0pqeoklL1y0xDIrCgqyLLV5YaIZlmzMUCBk GuHPCxEtyS1BAgkJwSBx3jSr6CKvlOTU1KT4+Nj4+Hhxd7BwsHy2R2h+QVFhUVFeXl5OJo8DWDhE joOdjYWNlYWFmZmJkZ2NywYs7O1srqyqoqKkIMrHLyAoKCwFEfZ0tLc2MTYy0jc00NXR0lRXswAL 8/rwogANMU6wC+1c3TyAwMXV1cXJycnWDOIfXnTAzUAiAACtUkaqnD2S7AAAAABJRU5ErkJggg== }] set images(reverselist) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABHNCSVQICAgIfAhkiAAAABl0RVh0 U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOwSURBVDiNtZRfTBxVFMa/e2dmB3aBFRZK FWSLLYWlqYXShYTFSK3GtFRt++qfxBdNjG9uGh/0ycQHM4/qg2nfNCYY20STmkhatDjQYghIS/gj WJZlLbusXbplt8vOzD0+dHczrlvoS09ycmbO3Pubb7659zIiwuMI/lioAOTiRiCouMHwvqSwl8mi DiI4uMTWGUdYmHRVWPhU14zkTmBmtyIQVF7nEvvcd2B/eWtrq+qp8cDpqEI6ncLdzQT+XFja+uPG dEaY4iyAc7pmiB3BfWeVj+tqd30YePGwc3dtA5ySG2lrA4spHVkzBdmowi65Dfx+FYZHLqdvx8KD v31mvL0tOBBUjjxRWTPSfniPGgnFN9ciMadDVY2WfXvFEb/f+dfmNfydWEQ2I1CB3fC5+zH066V0 fCP6hq4ZF0uCez+Quao6Qi7V3ZC8fydkGtZ7AEYBuBnHO25nTfDVgTPqVOwS7iTXkc0I1KiNOFD3 PC4MfZ0kIdp1zYgUg2UAh7a2so2miI9aBh3TNSOTe3YXwEeBoDLzy9Xh8z3dR8tH1r6HEBbiZhhp TwJ7vfuUxVsLpwB8UQzmALqYhIRl0GkbtBC6Znwbji6NRSKraKr2FfrhxCyan2orZxx9pazgagVv BOETXTNiD/sRJPDVWmwtVVlWW+glM3G4XJUA0F1qjmwZNEoCE/lGIKhIAL4DcNo+MB5fp2fbOwv3 WSuDMocKEmgOBJXi7XuRldrSgaCiMo4rntqarqPdJ9Uy2fVAOQg/z52DoAfL97jv3cIcS5i4Mv7D VjQWnSCBF0qCc3AX4xhtaGhoC3S85Lge+hGbW4n/jatQq9HjfQXXpoezK+HQHAn06pqReuhZoWtG igT6V1cjK5OzY6a/6QTyyvNRJrvgbzqBydkxM7QSWiGBfl0zUsAOh5CuGQkQ+haW5qPzyzeF3zsA RVIBAIqkwu8dwPzyTbGwNB8FoU/XjMInlbSCMcZzL+UA2KE3Ja+rno12d/ZW19c9ySfCP6Hr6eOI rq+J8Uk9YaSp+/cvrVtkgxXAjDEGQMolt1UGgPvO8JbqZj70XM+xysb6PWw1ukwj45fvbd6m/ulv rDkAAoAFwCIiYkSUVyhtkxwAa3uNH/S0yBcO+jqcN2an0hsr1smZQWsqD7SlmQfnAXIRUC6+bjvF O6uf4eeTq/TWzKA1lgfZoXbwIynOJXn2M+c/C3SvhFILgElE5iN7nKv5oJyn+WqHiu1WhR1mV8ty sP+A8zB7/AuncspNor9CdAAAAABJRU5ErkJggg== }] set images(isempty) [image create photo -data { iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBI WXMAAAsTAAALEwEAmpwYAAAACXZwQWcAAAAYAAAAGAB4TKWmAAADkklEQVRIx+1US2xUVRj+eu/M GZ37AJf42GkrpQ0aTVxQbXRnQhOTaWKiCCqlU6cQ9o6ZVzqtwYUJ2BfWtqPBsOjCgAsXRor1sTFC x3bDRlACovS+5869587c34UztaEPinFl/JN/c873OPf/bz7gP1m5XLork3/7+X8DK9x5kMmne4SI uBARI19l8umercTvBbtKKI7kfbfqkuu6VBzJ+5sRm1in4pBTcbbENgmJwlCGqlWXwjCkMAzJtMwN iU1x3dCIc5845+Q4NhWGMpTLvfPChiMSqEUHACIAIPCAQ5IkHE0dZzHG5pommXy6J8bYXOqtYywe l2BXLBBoVTBsoQfWGrTc+bIYY3NHU8eZJMnwuY8YY3AcB6PjJ3nAeSnK2KHUwDEWlyTYjgVZUuBW KhibPMU5D3oL2eL5be3BMA0KagHZjkVBwEk3NBp+t0CarpHPPbqt/U6e75GmrdDQSM7f1pLXmRg6 8YCTYerk+x6FYUie79EfK7fI86vbEhc3Orw4v3Cl67l9iz9e+iHxxN4nxfj9cdgVC261At/zoEgq XNfF+MQHnAdbj0XY7KKQLZ4POC+NjZ9CNMoQhuFfTSEYi2FiYhS1ICjdbebiZheZfLqHMTY80D8o CkILPL8KIgIRQRRFdHR04vLlS51d3fsWL84vXLkng+bf1H8kxSRZguWYkGUVqrIDoiDCtHQoioL2 9g7xp/JiYiuTDaMiFo3OHekbYJIUh2kZkOMKbMvCifeGYVkWVGUHNGMFkiThtYOvMxaJzm22aHEj 8b7DSSbLMizHhCKpME0T09Mf8loQTJfLi51tbY+LqqJCN1egKipaW9vE5eWlxLPdXeu+RFgjnogI 4rlkcpDJigLLNiHHFeiGgZmZKc5rQW8uW+zntaC39PEM1w0dqrITmn4biqLgwIGDTBSEc3eNinpY BxFBisvQDR2zs1NcN41XC9niBQByIVu8YNn2K2fOfMI1TYOq7EQYhqjX6gDWR8XqiObnv/7l6Wee Ki8tlV9qb98jcp9jdnYquHHz1uGT749+CYABuA+A+N0331/dvWf38rVrP+9/9LFW0fc8nD37Kbcr zssjQyc+A/4Op2YWRQDEAMSSqb79D+7aVQKAX69ff3NqcuYLAEGj641HRQFE+pJvvPjIQw9PA8CN 324emhyb+hyA3+jaWgM0SDEAkeRgXzcFVDt9+qNvG0C/YfBPsP/X1vUnKKIevOk3P2MAAAAldEVY dGNyZWF0ZS1kYXRlADIwMDktMTEtMTVUMjM6MDQ6MjUtMDc6MDBt/LoyAAAAJXRFWHRkYXRlOmNy ZWF0ZQAyMDEwLTAxLTExVDA5OjEwOjE5LTA3OjAw0PLOhAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAx MC0wMS0xMVQwOToxMDoxOS0wNzowMKGvdjgAAAA0dEVYdExpY2Vuc2UAaHR0cDovL2NyZWF0aXZl Y29tbW9ucy5vcmcvbGljZW5zZXMvR1BMLzIuMC9sagaoAAAAJXRFWHRtb2RpZnktZGF0ZQAyMDA5 LTExLTE1VDIzOjA0OjI1LTA3OjAwMk3MBgAAABd0RVh0U291cmNlAEdOT01FIEljb24gVGhlbWXB +SZpAAAAIHRFWHRTb3VyY2VfVVJMAGh0dHA6Ly9hcnQuZ25vbWUub3JnLzLkkXkAAAAASUVORK5C YII= }] set images(job_engineering_logo) [image create photo -data { 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 nv8PbNpb9t40/Q8AAAAASUVORK5CYII= }] ====== <> Widget | TclOO