Version 4 of timeentry

Updated 2005-11-10 04:23:10

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 seconds
                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