| # |
| # Timefield |
| # ---------------------------------------------------------------------- |
| # Implements a time entry field with adjustable built-in intelligence |
| # levels. |
| # ---------------------------------------------------------------------- |
| # AUTHOR: John A. Tucker E-mail: jatucker@austin.dsccc.com |
| # |
| # @(#) $Id: timefield.itk,v 1.6 2001/08/17 19:05:44 smithc Exp $ |
| # ---------------------------------------------------------------------- |
| # Copyright (c) 1997 DSC Technologies Corporation |
| # ====================================================================== |
| # Permission to use, copy, modify, distribute and license this software |
| # and its documentation for any purpose, and without fee or written |
| # agreement with DSC, is hereby granted, provided that the above copyright |
| # notice appears in all copies and that both the copyright notice and |
| # warranty disclaimer below appear in supporting documentation, and that |
| # the names of DSC Technologies Corporation or DSC Communications |
| # Corporation not be used in advertising or publicity pertaining to the |
| # software without specific, written prior permission. |
| # |
| # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
| # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 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. IN NO EVENT SHALL |
| # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
| # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
| # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, |
| # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
| # SOFTWARE. |
| # ====================================================================== |
| |
| # |
| # Use option database to override default resources of base classes. |
| # |
| option add *Timefield.justify center widgetDefault |
| |
| |
| # |
| # Usual options. |
| # |
| itk::usual Timefield { |
| keep -background -borderwidth -cursor -foreground -highlightcolor \ |
| -highlightthickness -labelfont -textbackground -textfont |
| } |
| |
| # ------------------------------------------------------------------ |
| # TIMEFIELD |
| # ------------------------------------------------------------------ |
| itcl::class iwidgets::Timefield { |
| |
| inherit iwidgets::Labeledwidget |
| |
| constructor {args} {} |
| |
| itk_option define -childsitepos childSitePos Position e |
| itk_option define -command command Command {} |
| itk_option define -seconds seconds Seconds on |
| itk_option define -format format Format civilian |
| itk_option define -iq iq Iq high |
| itk_option define -gmt gmt GMT no |
| itk_option define -state state State normal |
| |
| public { |
| method get {{format "-string"}} |
| method isvalid {} |
| method show {{time "now"}} |
| } |
| |
| protected { |
| method _backwardCivilian {} |
| method _backwardMilitary {} |
| method _focusIn {} |
| method _forwardCivilian {} |
| method _forwardMilitary {} |
| method _keyPress {char sym state} |
| method _moveField {direction} |
| method _setField {field} |
| method _whichField {} |
| method _toggleAmPm {} |
| |
| variable _cfield hour |
| variable _formatString "%r" |
| variable _fields {} |
| variable _numFields 4 |
| variable _forward {} |
| variable _backward {} |
| variable _timeVar "" |
| |
| common _militaryFields {hour minute second} |
| common _civilianFields {hour minute second ampm} |
| } |
| } |
| |
| # |
| # Provide a lowercased access method for the timefield class. |
| # |
| proc iwidgets::timefield {pathName args} { |
| uplevel iwidgets::Timefield $pathName $args |
| } |
| |
| # ------------------------------------------------------------------ |
| # CONSTRUCTOR |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::constructor {args} { |
| component hull configure -borderwidth 0 |
| |
| # |
| # Create an entry field for entering the time. |
| # |
| itk_component add time { |
| entry $itk_interior.time |
| } { |
| keep -borderwidth -cursor -exportselection \ |
| -foreground -highlightcolor -highlightthickness \ |
| -insertbackground -justify -relief -textvariable |
| |
| rename -font -textfont textFont Font |
| rename -highlightbackground -background background Background |
| rename -background -textbackground textBackground Background |
| } |
| |
| # |
| # Create the child site widget. |
| # |
| itk_component add -protected dfchildsite { |
| frame $itk_interior.dfchildsite |
| } |
| set itk_interior $itk_component(dfchildsite) |
| |
| # |
| # Add timefield event bindings for focus in and keypress events. |
| # |
| bind $itk_component(time) <FocusIn> [itcl::code $this _focusIn] |
| bind $itk_component(time) <KeyPress> [itcl::code $this _keyPress %A %K %s] |
| bind $itk_component(time) <1> "focus $itk_component(time); break" |
| |
| # |
| # Disable some mouse button event bindings: |
| # Button Motion |
| # Double-Clicks |
| # Triple-Clicks |
| # Button2 |
| # |
| bind $itk_component(time) <Button1-Motion> break |
| bind $itk_component(time) <Button2-Motion> break |
| bind $itk_component(time) <Double-Button> break |
| bind $itk_component(time) <Triple-Button> break |
| bind $itk_component(time) <2> break |
| |
| # |
| # Initialize the widget based on the command line options. |
| # |
| eval itk_initialize $args |
| |
| # |
| # Initialize the time to the current time. |
| # |
| show |
| } |
| |
| # ------------------------------------------------------------------ |
| # OPTIONS |
| # ------------------------------------------------------------------ |
| |
| # ------------------------------------------------------------------ |
| # OPTION: -childsitepos |
| # |
| # Specifies the position of the child site in the widget. Valid |
| # locations are n, s, e, and w. |
| # ------------------------------------------------------------------ |
| itcl::configbody iwidgets::Timefield::childsitepos { |
| set parent [winfo parent $itk_component(time)] |
| |
| switch $itk_option(-childsitepos) { |
| n { |
| grid $itk_component(dfchildsite) -row 0 -column 0 -sticky ew |
| grid $itk_component(time) -row 1 -column 0 -sticky nsew |
| |
| grid rowconfigure $parent 0 -weight 0 |
| grid rowconfigure $parent 1 -weight 1 |
| grid columnconfigure $parent 0 -weight 1 |
| grid columnconfigure $parent 1 -weight 0 |
| } |
| |
| e { |
| grid $itk_component(dfchildsite) -row 0 -column 1 -sticky ns |
| grid $itk_component(time) -row 0 -column 0 -sticky nsew |
| |
| grid rowconfigure $parent 0 -weight 1 |
| grid rowconfigure $parent 1 -weight 0 |
| grid columnconfigure $parent 0 -weight 1 |
| grid columnconfigure $parent 1 -weight 0 |
| } |
| |
| s { |
| grid $itk_component(dfchildsite) -row 1 -column 0 -sticky ew |
| grid $itk_component(time) -row 0 -column 0 -sticky nsew |
| |
| grid rowconfigure $parent 0 -weight 1 |
| grid rowconfigure $parent 1 -weight 0 |
| grid columnconfigure $parent 0 -weight 1 |
| grid columnconfigure $parent 1 -weight 0 |
| } |
| |
| w { |
| grid $itk_component(dfchildsite) -row 0 -column 0 -sticky ns |
| grid $itk_component(time) -row 0 -column 1 -sticky nsew |
| |
| grid rowconfigure $parent 0 -weight 1 |
| grid rowconfigure $parent 1 -weight 0 |
| grid columnconfigure $parent 0 -weight 0 |
| grid columnconfigure $parent 1 -weight 1 |
| } |
| |
| default { |
| error "bad childsite option\ |
| \"$itk_option(-childsitepos)\":\ |
| should be n, e, s, or w" |
| } |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # OPTION: -command |
| # |
| # Command invoked upon detection of return key press event. |
| # ------------------------------------------------------------------ |
| itcl::configbody iwidgets::Timefield::command {} |
| |
| # ------------------------------------------------------------------ |
| # OPTION: -iq |
| # |
| # Specifies the level of intelligence to be shown in the actions |
| # taken by the time field during the processing of keypress events. |
| # Valid settings include high or low. With a high iq, |
| # the time prevents the user from typing in an invalid time. For |
| # example, if the current time is 05/31/1997 and the user changes |
| # the hour to 04, then the minute will be instantly modified for them |
| # to be 30. In addition, leap seconds are fully taken into account. |
| # A setting of low iq instructs the widget to do no validity checking |
| # at all during time entry. With a low iq level, it is assumed that |
| # the validity will be determined at a later time using the time's |
| # isvalid command. |
| # ------------------------------------------------------------------ |
| itcl::configbody iwidgets::Timefield::iq { |
| |
| switch $itk_option(-iq) { |
| high - low { |
| |
| } |
| default { |
| error "bad iq option \"$itk_option(-iq)\": should be high or low" |
| } |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # OPTION: -format |
| # |
| # Specifies the time format displayed in the entry widget. |
| # ------------------------------------------------------------------ |
| itcl::configbody iwidgets::Timefield::format { |
| |
| switch $itk_option(-format) { |
| civilian { |
| set _backward _backwardCivilian |
| set _forward _forwardCivilian |
| set _fields $_civilianFields |
| set _numFields 4 |
| set _formatString "%r" |
| $itk_component(time) config -width 11 |
| } |
| military { |
| set _backward _backwardMilitary |
| set _forward _forwardMilitary |
| set _fields $_militaryFields |
| set _numFields 3 |
| set _formatString "%T" |
| $itk_component(time) config -width 8 |
| } |
| default { |
| error "bad iq option \"$itk_option(-iq)\":\ |
| should be civilian or military" |
| } |
| } |
| |
| # |
| # Update the current contents of the entry field to reflect |
| # the configured format. |
| # |
| show $_timeVar |
| } |
| |
| # ------------------------------------------------------------------ |
| # OPTION: -gmt |
| # |
| # This option is used for GMT time. Must be a boolean value. |
| # ------------------------------------------------------------------ |
| itcl::configbody iwidgets::Timefield::gmt { |
| switch $itk_option(-gmt) { |
| 0 - no - false - off { } |
| 1 - yes - true - on { } |
| default { |
| error "bad gmt option \"$itk_option(-gmt)\": should be boolean" |
| } |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # OPTION: -state |
| # |
| # Disable the |
| # ------------------------------------------------------------------ |
| itcl::configbody iwidgets::Timefield::state { |
| switch -- $itk_option(-state) { |
| normal { |
| $itk_component(time) configure -state normal |
| } |
| disabled { |
| focus $itk_component(hull) |
| $itk_component(time) configure -state disabled |
| } |
| default { |
| error "Invalid value for -state: $itk_option(-state). Should be\ |
| \"normal\" or \"disabled\"." |
| } |
| } |
| } |
| |
| |
| # ------------------------------------------------------------------ |
| # METHODS |
| # ------------------------------------------------------------------ |
| |
| # ------------------------------------------------------------------ |
| # PUBLIC METHOD: get ?format? |
| # |
| # Return the current contents of the timefield in one of two formats |
| # string or as an integer clock value using the -string and -clicks |
| # options respectively. The default is by string. Reference the |
| # clock command for more information on obtaining times and their |
| # formats. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::get {{format "-string"}} { |
| set _timeVar [$itk_component(time) get] |
| |
| switch -- $format { |
| "-string" { |
| return $_timeVar |
| } |
| "-clicks" { |
| return [::clock scan $_timeVar -gmt $itk_option(-gmt)] |
| } |
| default { |
| error "bad format option \"$format\":\ |
| should be -string or -clicks" |
| } |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # PUBLIC METHOD: show time |
| # |
| # Changes the currently displayed time to be that of the time |
| # argument. The time may be specified either as a string or an |
| # integer clock value. Reference the clock command for more |
| # information on obtaining times and their formats. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::show {{time "now"}} { |
| set icursor [$itk_component(time) index insert] |
| |
| if {$time == {}} { |
| set time "now" |
| } |
| |
| switch -regexp -- $time { |
| |
| {^now$} { |
| set seconds [::clock seconds] |
| } |
| |
| {^[0-9]+$} { |
| if { [catch {::clock format $time -gmt $itk_option(-gmt)}] } { |
| error "bad time: \"$time\", must be a valid time \ |
| string, clock clicks value or the keyword now" |
| } |
| set seconds $time |
| } |
| |
| default { |
| if {[catch {set seconds [::clock scan $time -gmt $itk_option(-gmt)]}]} { |
| error "bad time: \"$time\", must be a valid time \ |
| string, clock clicks value or the keyword now" |
| } |
| } |
| } |
| |
| set _timeVar [::clock format $seconds -format $_formatString \ |
| -gmt $itk_option(-gmt)] |
| |
| $itk_component(time) delete 0 end |
| $itk_component(time) insert end $_timeVar |
| $itk_component(time) icursor $icursor |
| |
| return $_timeVar |
| } |
| |
| # ------------------------------------------------------------------ |
| # PUBLIC METHOD: isvalid |
| # |
| # Returns a boolean indication of the validity of the currently |
| # displayed time value. For example, 09:59::59 is valid whereas |
| # 26:59:59 is invalid. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::isvalid {} { |
| set _timeVar [$itk_component(time) get] |
| return [expr {([catch {::clock scan $_timeVar -gmt $itk_option(-gmt)}] == 0)}] |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _focusIn |
| # |
| # This method is bound to the <FocusIn> event. It resets the |
| # insert cursor and field settings to be back to their last known |
| # positions. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_focusIn {} { |
| _setField $_cfield |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _keyPress |
| # |
| # This method is the workhorse of the class. It is bound to the |
| # <KeyPress> event and controls the processing of all key strokes. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_keyPress {char sym state} { |
| |
| # |
| # Determine which field we are in currently. This is needed |
| # since the user may have moved to this position via a mouse |
| # selection and so it would not be in the position we last |
| # knew it to be. |
| # |
| set _cfield [_whichField ] |
| |
| # |
| # Set up a few basic variables we'll be needing throughout the |
| # rest of the method such as the position of the insert cursor |
| # and the currently displayed minute, hour, and second. |
| # |
| set inValid 0 |
| set icursor [$itk_component(time) index insert] |
| set lastField [lindex $_fields end] |
| |
| set prevtime $_timeVar |
| regexp {^([0-9])([0-9]):([0-9])([0-9]):([0-9])([0-9]).*$} \ |
| $_timeVar dummy \ |
| hour1 hour2 minute1 minute2 second1 second2 |
| set hour "$hour1$hour2" |
| set minute "$minute1$minute2" |
| set second "$second1$second2" |
| |
| # |
| # Process numeric keystrokes. This involes a fair amount of |
| # processing with step one being to check and make sure we |
| # aren't attempting to insert more that 6 characters. If |
| # so ring the bell and break. |
| # |
| if {![catch {expr {int($char)}}]} { |
| |
| # If we are currently in the hour field then we process the |
| # number entered based on the cursor position. If we are at |
| # at the first position and our iq is low, then accept any |
| # input. |
| # |
| # if the current format is military, then |
| # validate the hour field which can be [00 - 23] |
| # |
| switch $_cfield { |
| hour { |
| if {$itk_option(-iq) == "low"} { |
| $itk_component(time) delete $icursor |
| $itk_component(time) insert $icursor $char |
| |
| } elseif {$itk_option(-format) == "military"} { |
| if {$icursor == 0} { |
| # |
| # if the digit is less than 2, then |
| # the second hour digit is valid for 0-9 |
| # |
| if {$char < 2} { |
| $itk_component(time) delete 0 1 |
| $itk_component(time) insert 0 $char |
| |
| # |
| # if the digit is equal to 2, then |
| # the second hour digit is valid for 0-3 |
| # |
| } elseif {$char == 2} { |
| $itk_component(time) delete 0 1 |
| $itk_component(time) insert 0 $char |
| |
| if {$hour2 > 3} { |
| $itk_component(time) delete 1 2 |
| $itk_component(time) insert 1 "0" |
| $itk_component(time) icursor 1 |
| } |
| |
| # |
| # if the digit is greater than 2, then |
| # set the first hour digit to 0 and the |
| # second hour digit to the value. |
| # |
| } elseif {$char > 2} { |
| $itk_component(time) delete 0 2 |
| $itk_component(time) insert 0 "0$char" |
| set icursor 1 |
| } else { |
| set inValid 1 |
| } |
| |
| # |
| # if the insertion cursor is for the second hour digit, then |
| # format is military, then it can only be valid if the first |
| # hour digit is less than 2 or the new digit is less than 4 |
| # |
| } else { |
| if {$hour1 < 2 || $char < 4} { |
| $itk_component(time) delete 1 2 |
| $itk_component(time) insert 1 $char |
| } else { |
| set inValid 1 |
| } |
| } |
| |
| # |
| # The format is civilian, so we need to |
| # validate the hour field which can be [01 - 12] |
| # |
| } else { |
| if {$icursor == 0} { |
| # |
| # if the digit is 0, then |
| # the second hour digit is valid for 1-9 |
| # so just insert it. |
| # |
| if {$char == 0 && $hour2 != 0} { |
| $itk_component(time) delete 0 1 |
| $itk_component(time) insert 0 $char |
| |
| # |
| # if the digit is equal to 1, then |
| # the second hour digit is valid for 0-2 |
| # |
| } elseif {$char == 1} { |
| $itk_component(time) delete 0 1 |
| $itk_component(time) insert 0 $char |
| |
| if {$hour2 > 2} { |
| $itk_component(time) delete 1 2 |
| $itk_component(time) insert 1 0 |
| set icursor 1 |
| } |
| |
| # |
| # if the digit is greater than 1, then |
| # set the first hour digit to 0 and the |
| # second hour digit to the value. |
| # |
| } elseif {$char > 1} { |
| $itk_component(time) delete 0 2 |
| $itk_component(time) insert 0 "0$char" |
| set icursor 1 |
| |
| } else { |
| set inValid 1 |
| } |
| |
| # |
| # The insertion cursor is at the second hour digit, so |
| # it can only be valid if the firs thour digit is 0 |
| # or the new digit is less than or equal to 2 |
| # |
| } else { |
| if {$hour1 == 0 || $char <= 2} { |
| $itk_component(time) delete 1 2 |
| $itk_component(time) insert 1 $char |
| } else { |
| set inValid 1 |
| } |
| } |
| } |
| |
| if {$inValid} { |
| bell |
| } elseif {$icursor == 1} { |
| _setField minute |
| } |
| } |
| |
| minute { |
| if {$itk_option(-iq) == "low" || $char < 6 || $icursor == 4} { |
| $itk_component(time) delete $icursor |
| $itk_component(time) insert $icursor $char |
| } elseif {$itk_option(-iq) == "high"} { |
| if {$char > 5} { |
| $itk_component(time) delete 3 5 |
| $itk_component(time) insert 3 "0$char" |
| set icursor 4 |
| } |
| } |
| |
| if {$icursor == 4} { |
| _setField second |
| } |
| } |
| |
| second { |
| if {$itk_option(-iq) == "low" || $char < 6 || $icursor == 7} { |
| $itk_component(time) delete $icursor |
| $itk_component(time) insert $icursor $char |
| |
| } elseif {$itk_option(-iq) == "high"} { |
| if {$char > 5} { |
| $itk_component(time) delete 6 8 |
| $itk_component(time) insert 6 "0$char" |
| set icursor 7 |
| } |
| } |
| |
| if {$icursor == 7} { |
| _moveField forward |
| } |
| } |
| } |
| |
| set _timeVar [$itk_component(time) get] |
| return -code break |
| } |
| |
| # |
| # Process the plus and the up arrow keys. They both yield the same |
| # effect, they increment the minute by one. |
| # |
| switch $sym { |
| p - P { |
| if {$itk_option(-format) == "civilian"} { |
| $itk_component(time) delete 9 10 |
| $itk_component(time) insert 9 P |
| _setField hour |
| } |
| } |
| |
| a - A { |
| if {$itk_option(-format) == "civilian"} { |
| $itk_component(time) delete 9 10 |
| $itk_component(time) insert 9 A |
| _setField hour |
| } |
| } |
| |
| plus - Up { |
| if {$_cfield == "ampm"} { |
| _toggleAmPm |
| } else { |
| set newclicks [::clock scan "$prevtime 1 $_cfield"] |
| show [::clock format $newclicks -format $_formatString] |
| } |
| } |
| |
| minus - Down { |
| # |
| # Process the minus and the down arrow keys which decrement the value |
| # of the field in which the cursor is currently positioned. |
| # |
| if {$_cfield == "ampm"} { |
| _toggleAmPm |
| } else { |
| set newclicks [::clock scan "$prevtime 1 $_cfield ago"] |
| show [::clock format $newclicks -format $_formatString] |
| } |
| } |
| |
| Tab { |
| # |
| # A tab key moves the "hour:minute:second" field forward by one unless |
| # the current field is the second. In that case we'll let tab |
| # do what is supposed to and pass the focus onto the next widget. |
| # |
| if {$state == 0} { |
| |
| if {($itk_option(-format) == "civilian" && $_cfield == $lastField)} { |
| _setField hour |
| return -code continue |
| } |
| _moveField forward |
| |
| # |
| # A ctrl-tab key moves the hour:minute:second field backwards by one |
| # unless the current field is the hour. In that case we'll let |
| # tab take the focus to a previous widget. |
| # |
| } elseif {$state == 4} { |
| if {$_cfield == "hour"} { |
| _setField hour |
| return -code continue |
| } |
| _moveField backward |
| } |
| } |
| |
| Right { |
| # |
| # A right arrow key moves the insert cursor to the right one. |
| # |
| $_forward |
| } |
| |
| Left - BackSpace - Delete { |
| # |
| # A left arrow, backspace, or delete key moves the insert cursor |
| # to the left one. This is what you expect for the left arrow |
| # and since the whole widget always operates in overstrike mode, |
| # it makes the most sense for backspace and delete to do the same. |
| # |
| $_backward |
| } |
| |
| Return { |
| # |
| # A Return key invokes the optionally specified command option. |
| # |
| uplevel #0 $itk_option(-command) |
| } |
| |
| default { |
| |
| } |
| } |
| |
| return -code break |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _toggleAmPm |
| # |
| # Internal method which toggles the displayed time |
| # between "AM" and "PM" when format is "civilian". |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_toggleAmPm {} { |
| set firstChar [string index $_timeVar 9] |
| $itk_component(time) delete 9 10 |
| $itk_component(time) insert 9 [expr {($firstChar == "A") ? "P" : "A"}] |
| $itk_component(time) icursor 9 |
| set _timeVar [$itk_component(time) get] |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _setField field |
| # |
| # Adjusts the current field to be that of the argument, setting the |
| # insert cursor appropriately. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_setField {field} { |
| |
| # Move the position of the cursor to the first character of the |
| # field given by the argument: |
| # |
| # Field First Character Index |
| # ----- --------------------- |
| # hour 0 |
| # minute 3 |
| # second 6 |
| # ampm 9 |
| # |
| switch $field { |
| hour { |
| $itk_component(time) icursor 0 |
| } |
| minute { |
| $itk_component(time) icursor 3 |
| } |
| second { |
| $itk_component(time) icursor 6 |
| } |
| ampm { |
| if {$itk_option(-format) == "military"} { |
| error "bad field: \"$field\", must be hour, minute or second" |
| } |
| $itk_component(time) icursor 9 |
| } |
| default { |
| if {$itk_option(-format) == "military"} { |
| error "bad field: \"$field\", must be hour, minute or second" |
| } else { |
| error "bad field: \"$field\", must be hour, minute, second or ampm" |
| } |
| } |
| } |
| |
| set _cfield $field |
| |
| return $_cfield |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _moveField |
| # |
| # Moves the cursor one field forward or backward. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_moveField {direction} { |
| |
| # Since the value "_fields" list variable is always either value: |
| # military => {hour minute second} |
| # civilian => {hour minute second ampm} |
| # |
| # the index of the previous or next field index can be determined |
| # by subtracting or adding 1 to current the index, respectively. |
| # |
| set index [lsearch $_fields $_cfield] |
| expr {($direction == "forward") ? [incr index] : [incr index -1]} |
| |
| if {$index == $_numFields} { |
| set index 0 |
| } elseif {$index < 0} { |
| set index [expr {$_numFields-1}] |
| } |
| |
| _setField [lindex $_fields $index] |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _whichField |
| # |
| # Returns the current field that the cursor is positioned within. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_whichField {} { |
| |
| # Return the current field based on the position of the cursor. |
| # |
| # Field Index |
| # ----- ----- |
| # hour 0,1 |
| # minute 3,4 |
| # second 6,7 |
| # ampm 9,10 |
| # |
| set icursor [$itk_component(time) index insert] |
| switch $icursor { |
| 0 - 1 { |
| set _cfield hour |
| } |
| 3 - 4 { |
| set _cfield minute |
| } |
| 6 - 7 { |
| set _cfield second |
| } |
| 9 - 10 { |
| set _cfield ampm |
| } |
| } |
| |
| return $_cfield |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _forwardCivilian |
| # |
| # Internal method which moves the cursor forward by one character |
| # jumping over the slashes and wrapping. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_forwardCivilian {} { |
| |
| # |
| # If the insertion cursor is at the second digit |
| # of either the hour, minute or second field, then |
| # move the cursor to the first digit of the right-most field. |
| # |
| # else move the insertion cursor right one character |
| # |
| set icursor [$itk_component(time) index insert] |
| switch $icursor { |
| 1 { |
| _setField minute |
| } |
| 4 { |
| _setField second |
| } |
| 7 { |
| _setField ampm |
| } |
| 9 - 10 { |
| _setField hour |
| } |
| default { |
| $itk_component(time) icursor [expr {$icursor+1}] |
| } |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _forwardMilitary |
| # |
| # Internal method which moves the cursor forward by one character |
| # jumping over the slashes and wrapping. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_forwardMilitary {} { |
| |
| # |
| # If the insertion cursor is at the second digit of either |
| # the hour, minute or second field, then move the cursor to |
| # the first digit of the right-most field. |
| # |
| # else move the insertion cursor right one character |
| # |
| set icursor [$itk_component(time) index insert] |
| switch $icursor { |
| 1 { |
| _setField minute |
| } |
| 4 { |
| _setField second |
| } |
| 7 { |
| _setField hour |
| } |
| default { |
| $itk_component(time) icursor [expr {$icursor+1}] |
| } |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _backwardCivilian |
| # |
| # Internal method which moves the cursor backward by one character |
| # jumping over the ":" and wrapping. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_backwardCivilian {} { |
| |
| # |
| # If the insertion cursor is at the first character |
| # of either the minute or second field or at the ampm |
| # field, then move the cursor to the second character |
| # of the left-most field. |
| # |
| # else if the insertion cursor is at the first digit of the |
| # hour field, then move the cursor to the first character |
| # of the ampm field. |
| # |
| # else move the insertion cursor left one character |
| # |
| set icursor [$itk_component(time) index insert] |
| switch $icursor { |
| 9 { |
| _setField second |
| $itk_component(time) icursor 7 |
| } |
| 6 { |
| _setField minute |
| $itk_component(time) icursor 4 |
| } |
| 3 { |
| _setField hour |
| $itk_component(time) icursor 1 |
| } |
| 0 { |
| _setField ampm |
| $itk_component(time) icursor 9 |
| } |
| default { |
| $itk_component(time) icursor [expr {$icursor-1}] |
| } |
| } |
| } |
| |
| # ------------------------------------------------------------------ |
| # PROTECTED METHOD: _backwardMilitary |
| # |
| # Internal method which moves the cursor backward by one character |
| # jumping over the slashes and wrapping. |
| # ------------------------------------------------------------------ |
| itcl::body iwidgets::Timefield::_backwardMilitary {} { |
| |
| # |
| # If the insertion cursor is at the first digit of either |
| # the minute or second field, then move the cursor to the |
| # second character of the left-most field. |
| # |
| # else if the insertion cursor is at the first digit of the |
| # hour field, then move the cursor to the second digit |
| # of the second field. |
| # |
| # else move the insertion cursor left one character |
| # |
| set icursor [$itk_component(time) index insert] |
| switch $icursor { |
| 6 { |
| _setField minute |
| $itk_component(time) icursor 4 |
| } |
| 3 { |
| _setField hour |
| $itk_component(time) icursor 1 |
| } |
| 0 { |
| _setField second |
| $itk_component(time) icursor 7 |
| } |
| default { |
| $itk_component(time) icursor [expr {$icursor-1}] |
| } |
| } |
| } |