disable a widget hierarchy

I needed to disable a whole group of widgets:

I don't think this is complete, but maybe if we added some missing bits and pieces, it will be and it could be added to tklib?

 # gui::recursivestate --
 #
 #        Set state for a window and its children, recursively.

 proc gui::recursivestate {w newstate} {
     variable widgetstates
     set clist [$w configure]
     set idx [lsearch $clist [list -state *]]
     if { $idx > -1 } {
         set slist [lindex $clist $idx]
         set currentstate [lindex $slist 4]
         set widgetstates($w) $currentstate
         $w configure -state $newstate
     }
     foreach c [winfo children $w] {
         gui::recursivestate $c $newstate
     }
 }

 # gui::restorestate --
 #
 #        Restore widgets previously affected by recursivestate to their
 #        native state.

 proc gui::restorestate {} {
     variable widgetstates
     foreach {w oldstate} [array get widgetstates] {
         $w configure -state $oldstate
     }
     array set widgetstates {}
 }

MGS [2004/02/16] - I use a slightly different version:

 proc lib::state {mode W {new normal}} {
   variable state
   switch -- $mode {
     reset {
       if { [info exists state($W)] } {
         if { [catch {$W configure -state $state($W)} error] } {
           puts stderr "  \[$::errorCode\] $error\n"
         }
         unset state($W)
       }
       foreach w [winfo children $W] {
         state $mode $w $new
       }
     }
     set {
       if { [catch {$W cget -state} old] } {
         puts stderr "  \[$W\] $old\n"
       } else {
         if { [catch {$W configure -state $new} error] } {
           puts stderr "  \[$W\] $error\n"
         } elseif { ![info exists state($W)] } {
           set state($W) $old
         }
       }
       foreach w [winfo children $W] {
         if { [string equal [winfo toplevel $w] $W] } {
           state $mode $w $new
         }
       }
     }
   }
 }