📄 datefield.itk
字号:
$itk_component(date) insert 0 0$char } elseif {$month2b == "00"} { bell return -code break } else { $itk_component(date) delete 1 $itk_component(date) insert 1 $char } } _setField day } # # Now, the month processing is complete and if we're of a # high level of intelligence, then we'll make sure that the # current value for the day is valid for this month. If # it is beyond the last day for this month, change it to # be the last day of the new month. # if {$itk_option(-iq) == "high"} { set splist [split [$itk_component(date) get] "/"] set month [lindex $splist 0] if {$day > [set endday [_lastDay $month $year]]} { set icursor [$itk_component(date) index insert] $itk_component(date) delete 3 5 $itk_component(date) insert 3 $endday $itk_component(date) icursor $icursor } } # # Finally, return with a code of break to stop any normal # processing in that we've done all that is necessary. # return -code break } # # This next block of code is for processing of the day field # which is quite similar is strategy to that of the month. # if {$_cfield == "day"} { if {$itk_option(-iq) == "high"} { set endofMonth [_lastDay $month $year] } else { set endofMonth 31 } # # If we are at the third cursor position we are porcessing # the first character of the day field. If we have an iq # of low accept any input. # if {[$itk_component(date) index insert] == 3} { if {$itk_option(-iq) == "low"} { $itk_component(date) delete 3 $itk_component(date) insert 3 $char } else { # # If the day to be is double zero, then make the # day be the first. # regsub {([0-9])([0-9])} $day "$char\\2" day2b if {$day2b == "00"} { $itk_component(date) delete 3 5 $itk_component(date) insert 3 01 $itk_component(date) icursor 4 # # Otherwise, if the character is less than four # and the month is not Feburary, insert the number # and if this makes the day be beyond the valid # range for this month, than set to be back in # range. # } elseif {($char < 4) && ($month != "02")} { $itk_component(date) delete 3 $itk_component(date) insert 3 $char if {$day2b > $endofMonth} { $itk_component(date) delete 4 $itk_component(date) insert 4 0 $itk_component(date) icursor 4 } # # For Feburary with a number to be entered of # less than three, make sure the number doesn't # make the day be greater than the correct range # and if so adjust the input. # } elseif {$char < 3} { $itk_component(date) delete 3 $itk_component(date) insert 3 $char if {$day2b > $endofMonth} { $itk_component(date) delete 3 5 $itk_component(date) insert 3 $endofMonth $itk_component(date) icursor 4 } # # Finally, if the number is greater than three, # set the day to be zero followed by the number # entered and proceed to the year field. # } else { $itk_component(date) delete 3 5 $itk_component(date) insert 3 0$char _setField year } } # # Else, we're dealing with the second number in the day # field. If we're not too bright accept anything, otherwise # if the day is beyond the range for this month or equal to # zero then ring the bell. # } else { regsub {([0-9])([0-9])} $day "\\1$char" day2b if {($itk_option(-iq) != "low") && \ (($day2b > $endofMonth) || ($day2b == "00"))} { bell } else { $itk_component(date) delete 4 $itk_component(date) insert 4 $char _setField year } } # # Return with a code of break to prevent normal processing. # return -code break } # # This month and day we're tough, the code for the year is # comparitively simple. Accept any input and if we are really # sharp, then make sure the day is correct for the month # given the year. In short, handle leap years. # if {$_cfield == "year"} { if {$itk_option(-iq) == "low"} { $itk_component(date) delete $icursor $itk_component(date) insert $icursor $char } else { set prevdate [get] if {[$itk_component(date) index insert] == 6} { set yrdgt [lindex [split [lindex \ [split $prevdate "/"] 2] ""] 0] if {$char != $yrdgt} { if {$char == 1} { $itk_component(date) delete $icursor end $itk_component(date) insert $icursor 1999 } elseif {$char == 2} { $itk_component(date) delete $icursor end $itk_component(date) insert $icursor 2000 } else { bell return -code break } } $itk_component(date) icursor 7 return -code break } $itk_component(date) delete $icursor $itk_component(date) insert $icursor $char if {[catch {clock scan [get]}] != 0} { $itk_component(date) delete 6 end $itk_component(date) insert end \ [lindex [split $prevdate "/"] 2] $itk_component(date) icursor $icursor bell return -code break } if {$itk_option(-iq) == "high"} { set splist [split [$itk_component(date) get] "/"] set year [lindex $splist 2] if {$day > [set endday [_lastDay $month $year]]} { set icursor [$itk_component(date) index insert] $itk_component(date) delete 3 5 $itk_component(date) insert 3 $endday $itk_component(date) icursor $icursor } } } return -code break } # # Process the plus and the up arrow keys. They both yeild the same # effect, they increment the day by one. # } elseif {($sym == "plus") || ($sym == "Up")} { if {[catch {show [clock scan "1 day" -base [get -clicks]]}] != 0} { bell } return -code break # # Process the minus and the down arrow keys which decrement the day. # } elseif {($sym == "minus") || ($sym == "Down")} { if {[catch {show [clock scan "-1 day" -base [get -clicks]]}] != 0} { bell } return -code break # # A tab key moves the day/month/year field forward by one unless # the current field is the year. In that case we'll let tab # do what is supposed to and pass the focus onto the next widget. # } elseif {($sym == "Tab") && ($state == 0)} { if {$_cfield != "year"} { _moveField forward return -code break } else { _setField "month" return -code continue } # # A ctrl-tab key moves the day/month/year field backwards by one # unless the current field is the month. In that case we'll let # tab take the focus to a previous widget. # } elseif {($sym == "Tab") && ($state == 4)} { if {$_cfield != "month"} { _moveField backward return -code break } else { set _cfield "month" return -code continue } # # A right arrow key moves the insert cursor to the right one. # } elseif {$sym == "Right"} { _forward return -code break # # 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. # } elseif {$sym == "Left" || $sym == "BackSpace" || $sym == "Delete"} { _backward return -code break } elseif {($sym == "Control_L") || ($sym == "Shift_L") || \ ($sym == "Control_R") || ($sym == "Shift_R")} { return -code break # # A Return key invokes the optionally specified command option. # } elseif {$sym == "Return"} { uplevel #0 $itk_option(-command) return -code break } else { bell return -code break }}# ------------------------------------------------------------------# PROTECTED METHOD: _setField field## Internal method which adjusts the field to be that of the # argument, setting the insert cursor appropriately.# ------------------------------------------------------------------body iwidgets::Datefield::_setField {field} { set _cfield $field switch $field { "month" { $itk_component(date) icursor 0 } "day" { $itk_component(date) icursor 3 } "year" { $itk_component(date) icursor 8 } default { error "bad field: \"$field\", must be month, day or year" } }}# ------------------------------------------------------------------# PROTECTED METHOD: _moveField## Internal method for moving the field forward or backward by one.# ------------------------------------------------------------------body iwidgets::Datefield::_moveField {direction} { set index [lsearch $_fields $_cfield] if {$direction == "forward"} { set newIndex [expr $index + 1] } else { set newIndex [expr $index - 1] } if {$newIndex == [llength $_fields]} { set newIndex 0 } if {$newIndex < 0} { set newIndex [expr [llength $_fields] - 1] } _setField [lindex $_fields $newIndex] return}# ------------------------------------------------------------------# PROTECTED METHOD: _whichField## Internal method which returns the current field that the cursor# is currently within.# ------------------------------------------------------------------body iwidgets::Datefield::_whichField {} { set icursor [$itk_component(date) index insert] switch $icursor { 0 - 1 { set _cfield "month" } 3 - 4 { set _cfield "day" } 6 - 7 - 8 - 9 { set _cfield "year" } }}# ------------------------------------------------------------------# PROTECTED METHOD: _forward## Internal method which moves the cursor forward by one character# jumping over the slashes and wrapping.# ------------------------------------------------------------------body iwidgets::Datefield::_forward {} { set icursor [$itk_component(date) index insert] switch $icursor { 1 { _setField day } 4 { _setField year } 9 - 10 { _setField month } default { $itk_component(date) icursor [expr $icursor + 1] } }}# ------------------------------------------------------------------# PROTECTED METHOD: _backward## Internal method which moves the cursor backward by one character# jumping over the slashes and wrapping.# ------------------------------------------------------------------body iwidgets::Datefield::_backward {} { set icursor [$itk_component(date) index insert] switch $icursor { 6 { _setField day } 3 { _setField month } 0 { _setField year } default { $itk_component(date) icursor [expr $icursor -1] } }}# ------------------------------------------------------------------# PROTECTED METHOD: _lastDay month year## Internal method which determines the last day of the month for# the given month and year. We start at 28 and go forward till# we fail. Crude but effective.# ------------------------------------------------------------------body iwidgets::Datefield::_lastDay {month year} { set lastone 28 for {set lastone 28} {$lastone < 32} {incr lastone} { if {[catch {clock scan $month/[expr $lastone + 1]/$year}] != 0} { return $lastone } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -