home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / spindate.itk < prev    next >
Text File  |  2003-09-01  |  21KB  |  694 lines

  1. # Spindate 
  2. # ----------------------------------------------------------------------
  3. # Implements a Date spinner widget.  A date spinner contains three
  4. # Spinner widgets:  one Spinner for months, one SpinInt for days,
  5. # and one SpinInt for years.  Months can be specified as abbreviated
  6. # strings, integers or a user-defined list.  Options exist to manage to 
  7. # behavior, appearance, and format of each component spinner.
  8. #
  9. # ----------------------------------------------------------------------
  10. #  AUTHOR: Sue Yockey                  EMAIL: yockey@actc.com
  11. #          Mark L. Ulferts                    mulferts@austin.dsccc.com
  12. #
  13. #   @(#) $Id: spindate.itk,v 1.5 2001/08/22 15:51:13 smithc Exp $
  14. # ----------------------------------------------------------------------
  15. #            Copyright (c) 1997 DSC Technologies Corporation
  16. # ======================================================================
  17. # Permission to use, copy, modify, distribute and license this software 
  18. # and its documentation for any purpose, and without fee or written 
  19. # agreement with DSC, is hereby granted, provided that the above copyright 
  20. # notice appears in all copies and that both the copyright notice and 
  21. # warranty disclaimer below appear in supporting documentation, and that 
  22. # the names of DSC Technologies Corporation or DSC Communications 
  23. # Corporation not be used in advertising or publicity pertaining to the 
  24. # software without specific, written prior permission.
  25. # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  26. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
  27. # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
  28. # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 
  29. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 
  30. # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 
  31. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  32. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
  33. # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
  34. # SOFTWARE.
  35. # ======================================================================
  36.  
  37. #
  38. # Default resources.
  39. #
  40. option add *Spindate.monthLabel "Month" widgetDefault
  41. option add *Spindate.dayLabel "Day" widgetDefault
  42. option add *Spindate.yearLabel "Year" widgetDefault
  43. option add *Spindate.monthWidth 4 widgetDefault
  44. option add *Spindate.dayWidth 4 widgetDefault
  45. option add *Spindate.yearWidth 4 widgetDefault
  46.  
  47. #
  48. # Usual options.
  49. #
  50. itk::usual Spindate {
  51.     keep -background -cursor -foreground -labelfont -textbackground -textfont 
  52. }
  53.  
  54. # ------------------------------------------------------------------
  55. #                            SPINDATE
  56. # ------------------------------------------------------------------
  57. itcl::class iwidgets::Spindate {
  58.     inherit itk::Widget 
  59.     
  60.     constructor {args} {}
  61.     destructor {}
  62.     
  63.     itk_option define -labelpos labelPos Position w
  64.     itk_option define -orient orient Orient vertical 
  65.     itk_option define -monthon monthOn MonthOn true 
  66.     itk_option define -dayon dayOn DayOn true 
  67.     itk_option define -yearon yearOn YearOn true 
  68.     itk_option define -datemargin dateMargin Margin 1 
  69.     itk_option define -yeardigits yearDigits YearDigits 4
  70.     itk_option define -monthformat monthFormat MonthFormat integer 
  71.  
  72.     public {
  73.     method get {{format "-string"}} 
  74.     method show {{date now}} 
  75.     }
  76.  
  77.     protected {
  78.     method _packDate {{when later}} 
  79.     variable _repack {}             ;# Reconfiguration flag.
  80.     }
  81.  
  82.     private {
  83.     method _lastDay {month year}
  84.     method _spinMonth {direction} 
  85.     method _spinDay {direction} 
  86.  
  87.     variable _monthFormatStr "%m"
  88.     variable _yearFormatStr "%Y"
  89.     variable _interior
  90.     }
  91. }
  92.  
  93. #
  94. # Provide a lowercased access method for the Spindate class.
  95. proc ::iwidgets::spindate {pathName args} {
  96.     uplevel ::iwidgets::Spindate $pathName $args
  97. }
  98.  
  99. # ------------------------------------------------------------------
  100. #                        CONSTRUCTOR
  101. # ------------------------------------------------------------------
  102. itcl::body iwidgets::Spindate::constructor {args} {
  103.     set _interior $itk_interior
  104.  
  105.     set clicks [clock seconds]
  106.  
  107.     #
  108.     # Create Month Spinner
  109.     #
  110.     itk_component add month {
  111.     iwidgets::Spinner $itk_interior.month  -fixed 2 -justify right \
  112.         -decrement [itcl::code $this _spinMonth -1] \
  113.         -increment [itcl::code $this _spinMonth 1] 
  114.     } {
  115.     keep -background -cursor -arroworient -foreground \
  116.         -labelfont -labelmargin -relief -textbackground \
  117.         -textfont -repeatdelay -repeatinterval
  118.  
  119.     rename -labeltext -monthlabel monthLabel Text
  120.     rename -width -monthwidth monthWidth Width
  121.     }
  122.  
  123.     #
  124.     # Take off the default bindings for selction and motion.
  125.     #
  126.     bind [$itk_component(month) component entry] <1> {break}
  127.     bind [$itk_component(month) component entry] <Button1-Motion> {break}
  128.     
  129.     #
  130.     # Create Day Spinner
  131.     #
  132.     itk_component add day {
  133.     iwidgets::Spinint $itk_interior.day -fixed 2 -justify right \
  134.         -decrement [itcl::code $this _spinDay -1] \
  135.         -increment [itcl::code $this _spinDay 1]
  136.     } {
  137.     keep -background -cursor -arroworient -foreground \
  138.         -labelfont -labelmargin -relief -textbackground \
  139.         -textfont -repeatdelay -repeatinterval
  140.  
  141.     rename -labeltext -daylabel dayLabel Text
  142.     rename -width -daywidth dayWidth Width
  143.     }
  144.     
  145.     #
  146.     # Take off the default bindings for selction and motion.
  147.     #
  148.     bind [$itk_component(day) component entry] <1> {break}
  149.     bind [$itk_component(day) component entry] <Button1-Motion> {break}
  150.     
  151.     #
  152.     # Create Year Spinner
  153.     #
  154.     itk_component add year {
  155.     iwidgets::Spinint $itk_interior.year -fixed 2 -justify right \
  156.         -range {1900 3000}
  157.     } {
  158.     keep -background -cursor -arroworient -foreground \
  159.         -labelfont -labelmargin -relief -textbackground \
  160.         -textfont -repeatdelay -repeatinterval
  161.  
  162.     rename -labeltext -yearlabel yearLabel Text
  163.     rename -width -yearwidth yearWidth Width
  164.     }
  165.  
  166.     #
  167.     # Take off the default bindings for selction and motion.
  168.     #
  169.     bind [$itk_component(year) component entry] <1> {break}
  170.     bind [$itk_component(year) component entry] <Button1-Motion> {break}
  171.     
  172.     #
  173.     # Initialize the widget based on the command line options.
  174.     #
  175.     eval itk_initialize $args
  176.  
  177.     #
  178.     # Show the current date.
  179.     #
  180.     show now
  181. }
  182.  
  183. # ------------------------------------------------------------------
  184. #                           DESTRUCTOR
  185. # ------------------------------------------------------------------
  186. itcl::body iwidgets::Spindate::destructor {} {
  187.     if {$_repack != ""} {after cancel $_repack}
  188. }
  189.  
  190. # ------------------------------------------------------------------
  191. #                             OPTIONS
  192. # ------------------------------------------------------------------
  193.  
  194. # ------------------------------------------------------------------
  195. # OPTION: -labelpos
  196. #
  197. # Specifies the location of all 3 spinners' labels.
  198. # ------------------------------------------------------------------
  199. itcl::configbody iwidgets::Spindate::labelpos {
  200.     switch $itk_option(-labelpos) {
  201.     n {
  202.         $itk_component(month) configure -labelpos n
  203.         $itk_component(day) configure -labelpos n
  204.         $itk_component(year) configure -labelpos n
  205.         
  206.         #
  207.         # Un-align labels
  208.         #
  209.         $itk_component(month) configure -labelmargin 1
  210.         $itk_component(day) configure -labelmargin 1
  211.         $itk_component(year) configure -labelmargin 1 
  212.     }
  213.     
  214.     s {
  215.         $itk_component(month) configure -labelpos s
  216.         $itk_component(day) configure -labelpos s
  217.         $itk_component(year) configure -labelpos s
  218.         
  219.         #
  220.         # Un-align labels
  221.         #
  222.         $itk_component(month) configure -labelmargin 1
  223.         $itk_component(day) configure -labelmargin 1
  224.         $itk_component(year) configure -labelmargin 1 
  225.     }
  226.     
  227.     w {
  228.         $itk_component(month) configure -labelpos w
  229.         $itk_component(day) configure -labelpos w
  230.         $itk_component(year) configure -labelpos w
  231.     }
  232.     
  233.     e {
  234.         $itk_component(month) configure -labelpos e
  235.         $itk_component(day) configure -labelpos e
  236.         $itk_component(year) configure -labelpos e
  237.         
  238.         #
  239.         # Un-align labels
  240.         #
  241.         $itk_component(month) configure -labelmargin 1
  242.         $itk_component(day) configure -labelmargin 1
  243.         $itk_component(year) configure -labelmargin 1 
  244.     }
  245.     
  246.     default {
  247.         error "bad labelpos option \"$itk_option(-labelpos)\",\
  248.             should be n, s, w or e" 
  249.     }
  250.     }
  251.  
  252.     _packDate
  253. }
  254.  
  255. # ------------------------------------------------------------------
  256. # OPTION: -orient
  257. # Specifies the orientation of the 3 spinners for Month, Day 
  258. # and year.
  259. # ------------------------------------------------------------------
  260. itcl::configbody iwidgets::Spindate::orient {
  261.     _packDate
  262. }
  263.  
  264. # ------------------------------------------------------------------
  265. # OPTION: -monthon
  266. # Specifies whether or not to display the month spinner.
  267. # ------------------------------------------------------------------
  268. itcl::configbody iwidgets::Spindate::monthon {
  269.     _packDate
  270. }
  271.  
  272. # ------------------------------------------------------------------
  273. # OPTION: -dayon
  274. # Specifies whether or not to display the day spinner.
  275. # ------------------------------------------------------------------
  276. itcl::configbody iwidgets::Spindate::dayon {
  277.     _packDate
  278. }
  279.  
  280. # ------------------------------------------------------------------
  281. # OPTION: -yearon
  282. # Specifies whether or not to display the year spinner.
  283. # ------------------------------------------------------------------
  284. itcl::configbody iwidgets::Spindate::yearon {
  285.     _packDate
  286. }
  287.  
  288. # ------------------------------------------------------------------
  289. # OPTION: -datemargin
  290. # Specifies the margin space between the month and day spinners 
  291. # and the day and year spinners. 
  292. # ------------------------------------------------------------------
  293. itcl::configbody iwidgets::Spindate::datemargin {
  294.     _packDate
  295. }
  296.  
  297. # ------------------------------------------------------------------
  298. # OPTION: -yeardigits
  299. #
  300. # Number of digits for year display, 2 or 4 
  301. # ------------------------------------------------------------------
  302. itcl::configbody iwidgets::Spindate::yeardigits {
  303.     set clicks [clock seconds]
  304.  
  305.     switch $itk_option(-yeardigits) {
  306.     "2" {
  307.         $itk_component(year) configure -width 2 -fixed 2
  308.         $itk_component(year) clear
  309.         $itk_component(year) insert 0 [clock format $clicks -format "%y"]
  310.         set _yearFormatStr "%y"
  311.     }
  312.     
  313.     "4" {
  314.         $itk_component(year) configure -width 4 -fixed 4
  315.         $itk_component(year) clear
  316.         $itk_component(year) insert 0 [clock format $clicks -format "%Y"]
  317.         set _yearFormatStr "%Y"
  318.     }
  319.     
  320.     default {
  321.         error "bad yeardigits option \"$itk_option(-yeardigits)\",\
  322.             should be 2 or 4"
  323.     }
  324.     } 
  325. }
  326.  
  327. # ------------------------------------------------------------------
  328. # OPTION: -monthformat
  329. #
  330. # Format of month display, integers (1-12) or brief strings (Jan - 
  331. # Dec), or full strings (January - December).
  332. # ------------------------------------------------------------------
  333. itcl::configbody iwidgets::Spindate::monthformat {
  334.     set clicks [clock seconds]
  335.  
  336.     if {$itk_option(-monthformat) == "brief"} {
  337.     $itk_component(month) configure -width 3 -fixed 3
  338.     $itk_component(month) delete 0 end
  339.     $itk_component(month) insert 0 [clock format $clicks -format "%b"]
  340.     set _monthFormatStr "%b"
  341.     
  342.     } elseif {$itk_option(-monthformat) == "full"} {
  343.     $itk_component(month) configure -width 9 -fixed 9
  344.     $itk_component(month) delete 0 end
  345.     $itk_component(month) insert 0 [clock format $clicks -format "%B"]
  346.     set _monthFormatStr "%B"
  347.     
  348.     } elseif {$itk_option(-monthformat) == "integer"} {
  349.     $itk_component(month) configure -width 2 -fixed 2 
  350.     $itk_component(month) delete 0 end
  351.     $itk_component(month) insert 0 [clock format $clicks -format "%m"]
  352.     set _monthFormatStr "%m"
  353.     
  354.     } else {
  355.     error "bad monthformat option\
  356.         \"$itk_option(-monthformat)\", should be\
  357.         \"integer\", \"brief\" or \"full\""
  358.     }
  359. }
  360.  
  361. # ------------------------------------------------------------------
  362. #                            METHODS
  363. # ------------------------------------------------------------------
  364.  
  365. # ------------------------------------------------------------------
  366. # METHOD: get ?format?
  367. #
  368. # Return the current contents of the spindate widget in one of 
  369. # two formats string or as an integer clock value using the -string 
  370. # and -clicks options respectively.  The default is by string.  
  371. # Reference the clock command for more information on obtaining dates 
  372. # and their formats.
  373. # ------------------------------------------------------------------
  374. itcl::body iwidgets::Spindate::get {{format "-string"}} { 
  375.     set month [$itk_component(month) get]
  376.     set day [$itk_component(day) get]
  377.     set year [$itk_component(year) get]
  378.  
  379.     if {[regexp {[0-9]+} $month]} {
  380.     set datestr "$month/$day/$year"
  381.     } else {
  382.     set datestr "$day $month $year"
  383.     }
  384.  
  385.     switch -- $format {
  386.     "-string" {
  387.         return $datestr
  388.     }
  389.     "-clicks" {
  390.         return [clock scan $datestr]
  391.     }
  392.     default {
  393.         error "bad format option \"$format\":\
  394.                    should be -string or -clicks"
  395.     }
  396.     }
  397. }
  398.  
  399. # ------------------------------------------------------------------
  400. # PUBLIC METHOD: show date
  401. #
  402. # Changes the currently displayed date to be that of the date 
  403. # argument.  The date may be specified either as a string or an
  404. # integer clock value.  Reference the clock command for more 
  405. # information on obtaining dates and their formats.
  406. # ------------------------------------------------------------------
  407. itcl::body iwidgets::Spindate::show {{date "now"}} {
  408.     #
  409.     # Convert the date to a clock clicks value.
  410.     #
  411.     if {$date == "now"} {
  412.     set seconds [clock seconds]
  413.     } else {
  414.     if {[catch {clock format $date}] == 0} {
  415.         set seconds $date
  416.     } elseif {[catch {set seconds [clock scan $date]}] != 0} {
  417.         error "bad date: \"$date\", must be a valid date\
  418.                string, clock clicks value or the keyword now"
  419.     }
  420.     }
  421.  
  422.     #
  423.     # Display the month based on the -monthformat option.
  424.     #
  425.     switch $itk_option(-monthformat) {
  426.     "brief" {
  427.         $itk_component(month) delete 0 end
  428.         $itk_component(month) insert 0 [clock format $seconds -format "%b"]
  429.     }    
  430.     "full" {
  431.         $itk_component(month) delete 0 end
  432.         $itk_component(month) insert 0 [clock format $seconds -format "%B"]
  433.     }    
  434.     "integer" {
  435.         $itk_component(month) delete 0 end
  436.         $itk_component(month) insert 0 [clock format $seconds -format "%m"]
  437.     }
  438.     }
  439.  
  440.     #
  441.     # Display the day.
  442.     #
  443.     $itk_component(day) delete 0 end
  444.     $itk_component(day) insert end [clock format $seconds -format "%d"]
  445.  
  446.     #
  447.     # Display the year based on the -yeardigits option.
  448.     #
  449.     switch $itk_option(-yeardigits) {
  450.     "2" {
  451.         $itk_component(year) delete 0 end
  452.         $itk_component(year) insert 0 [clock format $seconds -format "%y"]
  453.     }
  454.     
  455.     "4" {
  456.         $itk_component(year) delete 0 end
  457.         $itk_component(year) insert 0 [clock format $seconds -format "%Y"]
  458.     }
  459.     }
  460.  
  461.     return
  462. }
  463.  
  464. # ----------------------------------------------------------------
  465. # PRIVATE METHOD: _spinMonth direction
  466. #
  467. # Increment or decrement month value.  We need to get the values
  468. # for all three fields so we can make sure the day agrees with
  469. # the month.  Should the current day be greater than the day for
  470. # the spun month, then the day is set to the last day for the
  471. # new month.
  472. # ----------------------------------------------------------------
  473. itcl::body iwidgets::Spindate::_spinMonth {direction} {
  474.     set month [$itk_component(month) get]
  475.     set day [$itk_component(day) get]
  476.     set year [$itk_component(year) get]
  477.  
  478.     #
  479.     # There appears to be a bug in the Tcl clock command in that it
  480.     # can't scan a date like "12/31/1999 1 month" or any other date with
  481.     # a year above 2000, but it has no problem scanning "07/01/1998 1 month".
  482.     # So, we're going to play a game and increment by days until this
  483.     # is fixed in Tcl.
  484.     #
  485.     if {$direction == 1} {
  486.     set incrdays 32
  487.     set day 01
  488.     } else {
  489.     set incrdays -28
  490.     set day 28
  491.     }
  492.  
  493.     if {[regexp {[0-9]+} $month]} {
  494.     set clicks [clock scan "$month/$day/$year $incrdays day"]
  495.     } else {
  496.     set clicks [clock scan "$day $month $year $incrdays day"]
  497.     }
  498.  
  499.     $itk_component(month) clear
  500.     $itk_component(month) insert 0 \
  501.     [clock format $clicks -format $_monthFormatStr]
  502.  
  503.     set currday [$itk_component(day) get]
  504.     set lastday [_lastDay [$itk_component(month) get] $year]
  505.  
  506.     if {$currday > $lastday} {
  507.     $itk_component(day) clear
  508.     $itk_component(day) insert end $lastday
  509.     }
  510. }
  511.  
  512. # ----------------------------------------------------------------
  513. # PRIVATE METHOD: _spinDay direction
  514. #
  515. # Increment or decrement day value.  If the previous day was the
  516. # first, then set the new day to the last day for the current
  517. # month.  If it was the last day of the month, change it to the
  518. # first.  Otherwise, spin it to the next day.
  519. # ----------------------------------------------------------------
  520. itcl::body iwidgets::Spindate::_spinDay {direction} {
  521.     set month [$itk_component(month) get]
  522.     set day [$itk_component(day) get]
  523.     set year [$itk_component(year) get]
  524.     set lastday [_lastDay $month $year]
  525.     set currclicks [get -clicks]
  526.  
  527.     $itk_component(day) delete 0 end
  528.  
  529.     if {(($day == "01") || ($day == "1")) && ($direction == -1)} {
  530.     $itk_component(day) insert 0 $lastday
  531.         return
  532.     }
  533.  
  534.     if {($day == $lastday) && ($direction == 1)} {
  535.     $itk_component(day) insert 0 "01"
  536.         return
  537.     }
  538.  
  539.     set clicks [clock scan "$direction day" -base $currclicks]
  540.     $itk_component(day) insert 0 [clock format $clicks -format "%d"]
  541. }
  542.  
  543. # ------------------------------------------------------------------
  544. # PRIVATE METHOD: _packDate when
  545. #
  546. # Pack the components of the date spinner.  If "when" is "now", the 
  547. # change is applied immediately.  If it is "later" or it is not 
  548. # specified, then the change is applied later, when the application 
  549. # is idle.
  550. # ------------------------------------------------------------------
  551. itcl::body iwidgets::Spindate::_packDate {{when later}} {
  552.     if {$when == "later"} {
  553.     if {$_repack == ""} {
  554.         set _repack [after idle [itcl::code $this _packDate now]]
  555.     }
  556.     return
  557.     } elseif {$when != "now"} {
  558.     error "bad option \"$when\": should be now or later"
  559.     }
  560.  
  561.     #
  562.     # Turn off the minsizes for all the rows and columns.  
  563.     #
  564.     for {set i 0} {$i < 5} {incr i} {
  565.     grid rowconfigure $_interior $i -minsize 0
  566.     grid columnconfigure $_interior $i -minsize 0
  567.     }
  568.  
  569.     set _repack ""
  570.  
  571.     #
  572.     # Based on the orientation, use the grid to place the components into
  573.     # the proper rows and columns.
  574.     #
  575.     switch $itk_option(-orient) {
  576.     vertical {
  577.         set row -1
  578.         
  579.         if {$itk_option(-monthon)} {
  580.         grid $itk_component(month) -row [incr row] -column 0 \
  581.             -sticky nsew 
  582.         } else {
  583.         grid forget $itk_component(month)
  584.         }
  585.         
  586.         if {$itk_option(-dayon)} {
  587.         if {$itk_option(-dayon)} {
  588.             grid rowconfigure $_interior [incr row] \
  589.             -minsize $itk_option(-datemargin)
  590.         }
  591.  
  592.         grid $itk_component(day) -row [incr row] -column 0 \
  593.             -sticky nsew 
  594.         } else {
  595.         grid forget $itk_component(day)
  596.         }
  597.         
  598.         if {$itk_option(-yearon)} {
  599.         if {$itk_option(-monthon) || $itk_option(-dayon)} {
  600.             grid rowconfigure $_interior [incr row] \
  601.             -minsize $itk_option(-datemargin)
  602.         }
  603.  
  604.         grid $itk_component(year) -row [incr row] -column 0 \
  605.             -sticky nsew 
  606.         } else {
  607.         grid forget $itk_component(year)
  608.         }
  609.         
  610.         if {$itk_option(-labelpos) == "w"} {
  611.         iwidgets::Labeledwidget::alignlabels $itk_component(month) \
  612.             $itk_component(day) $itk_component(year)
  613.         }
  614.     }
  615.     
  616.     horizontal {
  617.         set column -1
  618.  
  619.         if {$itk_option(-monthon)} {
  620.         grid $itk_component(month) -row 0 -column [incr column] \
  621.             -sticky nsew 
  622.         } else {
  623.         grid forget $itk_component(month)
  624.         }
  625.         
  626.         if {$itk_option(-dayon)} {
  627.         if {$itk_option(-monthon)} {
  628.             grid columnconfigure $_interior [incr column] \
  629.             -minsize $itk_option(-datemargin)
  630.         }
  631.  
  632.         grid $itk_component(day) -row 0 -column [incr column] \
  633.             -sticky nsew 
  634.         } else {
  635.         grid forget $itk_component(day)
  636.         }
  637.         
  638.         if {$itk_option(-yearon)} {
  639.         if {$itk_option(-monthon) || $itk_option(-dayon)} {
  640.             grid columnconfigure $_interior [incr column] \
  641.             -minsize $itk_option(-datemargin)
  642.         }
  643.  
  644.         grid $itk_component(year) -row 0 -column [incr column] \
  645.             -sticky nsew 
  646.         } else {
  647.         grid forget $itk_component(year)
  648.         }
  649.         
  650.         #
  651.         # Un-align labels.
  652.         #
  653.         $itk_component(month) configure -labelmargin 1
  654.         $itk_component(day) configure -labelmargin 1
  655.         $itk_component(year) configure -labelmargin 1
  656.     }
  657.     
  658.     default {
  659.         error "bad orient option \"$itk_option(-orient)\", should\
  660.             be \"vertical\" or \"horizontal\""
  661.     } 
  662.     }
  663.  
  664. # ------------------------------------------------------------------
  665. # PRIVATE METHOD: _lastDay month year
  666. #
  667. # Internal method which determines the last day of the month for
  668. # the given month and year.  We start at 28 and go forward till
  669. # we fail.  Crude but effective.
  670. # ------------------------------------------------------------------
  671. itcl::body iwidgets::Spindate::_lastDay {month year} {
  672.     set lastone 28
  673.  
  674.     for {set lastone 28} {$lastone < 32} {incr lastone} {
  675.     if {[regexp {[0-9]+} $month]} {
  676.       if {[catch {clock scan "$month/[expr {$lastone + 1}]/$year"}] != 0} {
  677.         return $lastone
  678.       }
  679.     } else {
  680.       if {[catch {clock scan "[expr {$lastone + 1}] $month $year"}] != 0} {
  681.         return $lastone
  682.       }
  683.     }
  684.     }
  685. }
  686.