[http://incrtcl.sourceforge.net/iwidgets/iwidgets/timeentry.gif] Docs can be found at http://incrtcl.sourceforge.net/iwidgets/iwidgets/timeentry.html and http://purl.org/tcl/home/man/iwidgets3.0/timeentry.n.html ---- This is a spinbox widget that only allows valid times to be entered. I tried to make this as much like the spinbox in the Windows "Date and Time" dialog. This is only for a 24 hour clock, but it wouldn´t take too much modification to support a 12 hour format. There´s probably an easier way to do this, so please edit this page if you know of one. -Paul Walton proc validateTime {spinbox originalString newString index adjust} { # Check if the colons are present. if { [string match {*:*:*} $newString] == 0 } { return 0 } # Split up each field into its own variable. set time [split $newString :] set hour [lindex $time 0] set minutes [lindex $time 1] set seconds [lindex $time 2] # Check if valid digits were entered in each field. if { $hour != "" && ![string match {[0-9]} $hour] && ![string match {[0-1][0-9]} $hour] && ![string match {2[0-3]} $hour] } { #invalid hour return 0 } if { $minutes != "" && ![string match {[0-9]} $minutes] && ![string match {[0-5][0-9]} $minutes] } { #invalid minutes return 0 } if { $seconds != "" && ![string match {[0-9]} $seconds] && ![string match {[0-5][0-9]} $seconds] } { #invalid minutes return 0 } # Adjust the index position of the cursor appropiately. set diff [expr { [string length $hour:$minutes:$seconds] - [string length $originalString] }] set newIndex $index if { $diff > 0 } { incr newIndex $diff } switch -- $adjust { up {set adjust 1} down {set adjust -1} default {set adjust 0} } set indexColon1 [string first {:} $newString] set indexColon2 [string last {:} $newString] if { $index <= $indexColon1 } { set field hour if { $adjust != 0 } { if { $hour == "" } { set hour 0 } scan $hour %d hour incr hour $adjust if { $hour == 24 } { set hour 0 } if { $hour == -1 } { set hour 23 } } } if { $index > $indexColon1 && $index <= $indexColon2 } { set field minutes if { $adjust != 0 } { if { $minutes == "" } { set minutes 0 } scan $minutes %d minutes incr minutes $adjust if { $minutes == 60 } { set minutes 0 } if { $minutes == -1 } { set minutes 59 } } } if { $index > $indexColon2 } { set field seconds if { $adjust != 0 } { if { $seconds == "" } { set seconds 0 } scan $seconds %d seconds incr seconds $adjust if { $seconds == 60 } { set seconds 0 } if { $seconds == -1 } { set seconds 59 } } } if { $index == -1 } { set field none } if { $field != "hour" || $adjust != 0 } { set increaseBy [expr {abs([string length $hour]-2)}] set hour [string repeat 0 $increaseBy]$hour incr newIndex $increaseBy } if { $field != "minutes" || $adjust != 0 } { set increaseBy [expr {abs([string length $minutes]-2)}] set minutes [string repeat 0 $increaseBy]$minutes if { $indexColon2 < $index } { incr newIndex $increaseBy } } if { $field != "seconds" || $adjust != 0 } { set increaseBy [expr {abs([string length $seconds]-2)}] set seconds [string repeat 0 $increaseBy]$seconds } if { $adjust != 0 } { switch -- $field { hour {set newIndex 2} minutes {set newIndex [string last {:} $hour:$minutes:$seconds]} seconds {set newIndex end} } } # Write the validated data with possible corrections to the spinbox. $spinbox configure -validate none $spinbox delete 0 end $spinbox insert 0 $hour:$minutes:$seconds $spinbox icursor $newIndex after idle [list $spinbox configure -validate all] return 0 } spinbox .spin -width 8 -validatecommand {validateTime %W %s %P %i ""} -validate all -command {validateTime %W %s %s [%W index insert] %d}] .spin insert 0 00:00:00 pack .spin ---- [Category Command], a part of [incr Widgets]