📄 datefield.itk
字号:
[clock format $seconds -format "$format" -gmt $itk_option(-gmt)] } else { # Note that it doesn't matter what -int is set to. $itk_component(date) insert end $date } if {$itk_option(-int)} { _setField year } else { _setField month } return}# ------------------------------------------------------------------# PUBLIC METHOD: isvalid## Returns a boolean indication of the validity of the currently# displayed date value. For example, 3/3/1960 is valid whereas# 02/29/1997 is invalid.# ------------------------------------------------------------------itcl::body iwidgets::Datefield::isvalid {} { if {[catch {clock scan [$itk_component(date) get]}] != 0} { return 0 } else { return 1 }}# ------------------------------------------------------------------# 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::Datefield::_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::Datefield::_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. # _whichField # # If we are using an international date the split char is "-" # otherwise it is "/". # if {$itk_option(-int)} { set split_char "-" } else { set split_char "/" } # # 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 day, month, and year. # set icursor [$itk_component(date) index insert] set splist [split [$itk_component(date) get] "$split_char"] # A bunch of added variables to allow for the use of int dates if {$itk_option(-int)} { set order {year month day} set year [lindex $splist 0] set month [lindex $splist 1] set day [lindex $splist 2] set year_start_pos 0 set year_second_pos 1 set year_third_pos 2 set year_fourth_pos 3 set year_end_pos 4 set month_start_pos 5 set month_second_pos 6 set month_end_pos 7 set day_start_pos 8 set day_second_pos 9 set day_end_pos 10 } else { set order {month day year} set month [lindex $splist 0] set day [lindex $splist 1] set year [lindex $splist 2] set month_start_pos 0 set month_second_pos 1 set month_end_pos 2 set day_start_pos 3 set day_second_pos 4 set day_end_pos 5 set year_start_pos 6 set year_second_pos 7 set year_third_pos 8 set year_fourth_pos 9 set year_end_pos 10 } # # 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 10 characters. If # so ring the bell and break. # if {[regexp {[0-9]} $char]} { if {[$itk_component(date) index insert] == 10} { bell return -code break } # # If we are currently in the month 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 {$_cfield == "month"} { if {[$itk_component(date) index insert] == $month_start_pos} { if {$itk_option(-iq) == "low"} { $itk_component(date) delete $month_start_pos $itk_component(date) insert $month_start_pos $char } else { # # Otherwise, we're slightly smarter. If the number # is less than two insert it at position zero. If # this makes the month greater than twelve, set the # number at position one to zero which makes in # effect puts the month back in range. # regsub {([0-9])([0-9])} $month "$char\\2" month2b if {$char < 2} { $itk_component(date) delete $month_start_pos $itk_component(date) insert $month_start_pos $char if {$month2b > 12} { $itk_component(date) delete $month_second_pos $itk_component(date) insert $month_second_pos 0 $itk_component(date) icursor $month_second_pos } elseif {$month2b == "00"} { $itk_component(date) delete $month_second_pos $itk_component(date) insert $month_second_pos 1 $itk_component(date) icursor $month_second_pos } # # Finally, if the number is greater than one we'll # assume that they really mean to be entering a zero # followed by their number, do so for them, and # proceed to skip to the next field which is the # day field. # } else { $itk_component(date) delete $month_start_pos $month_end_pos $itk_component(date) insert $month_start_pos 0$char _setField day } } # # Else, we're at the second month position. Again, if we aren't # too smart, let them enter anything. Otherwise, if the # number makes the month exceed twelve, set the month to # zero followed by their number to get it back into range. # } else { regsub {([0-9])([0-9])} $month "\\1$char" month2b if {$itk_option(-iq) == "low"} { $itk_component(date) delete $month_second_pos $itk_component(date) insert $month_second_pos $char } else { if {$month2b > 12} { $itk_component(date) delete $month_start_pos $month_end_pos $itk_component(date) insert $month_start_pos 0$char } elseif {$month2b == "00"} { bell return -code break } else { $itk_component(date) delete $month_second_pos $itk_component(date) insert $month_second_pos $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] "$split_char"] set month [lindex $splist [lsearch $order month]] if {$day > [set endday [_lastDay $month $year]]} { set icursor [$itk_component(date) index insert] $itk_component(date) delete $day_start_pos $day_end_pos $itk_component(date) insert $day_start_pos $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 first cursor position for the day # we are processing # the first character of the day field. If we have an iq # of low accept any input. # if {[$itk_component(date) index insert] == $day_start_pos} { if {$itk_option(-iq) == "low"} { $itk_component(date) delete $day_start_pos $itk_component(date) insert $day_start_pos $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 $day_start_pos $day_end_pos $itk_component(date) insert $day_start_pos 01 $itk_component(date) icursor $day_second_pos # # 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 $day_start_pos $itk_component(date) insert $day_start_pos $char if {$day2b > $endofMonth} { $itk_component(date) delete $day_second_pos $itk_component(date) insert $day_second_pos 0 $itk_component(date) icursor $day_second_pos } # # 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 $day_start_pos $itk_component(date) insert $day_start_pos $char if {$day2b > $endofMonth} { $itk_component(date) delete $day_start_pos $day_end_pos $itk_component(date) insert $day_start_pos $endofMonth $itk_component(date) icursor $day_second_pos } # # 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 or end. # } else { $itk_component(date) delete $day_start_pos $day_end_pos $itk_component(date) insert $day_start_pos 0$char $itk_component(date) icursor $day_end_pos if {!$itk_option(-int)} { _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 $day_second_pos $itk_component(date) insert $day_second_pos $char $itk_component(date) icursor $day_end_pos if {!$itk_option(-int)} { _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"} {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -