home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / comanche.exe / lib / iwidgets3.0.0 / scripts / spindate.itk < prev    next >
Text File  |  1999-02-24  |  22KB  |  701 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.1 1998/07/27 18:53:18 stanton 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. 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. 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 [code $this _spinMonth -1] \
  113.         -increment [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 [code $this _spinDay -1] \
  135.         -increment [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. 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. 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. configbody iwidgets::Spindate::orient {
  261.     _packDate
  262. }
  263.  
  264. # ------------------------------------------------------------------
  265. # OPTION: -monthon
  266. # Specifies whether or not to display the month spinner.
  267. # ------------------------------------------------------------------
  268. configbody iwidgets::Spindate::monthon {
  269.     _packDate
  270. }
  271.  
  272. # ------------------------------------------------------------------
  273. # OPTION: -dayon
  274. # Specifies whether or not to display the day spinner.
  275. # ------------------------------------------------------------------
  276. configbody iwidgets::Spindate::dayon {
  277.     _packDate
  278. }
  279.  
  280. # ------------------------------------------------------------------
  281. # OPTION: -yearon
  282. # Specifies whether or not to display the year spinner.
  283. # ------------------------------------------------------------------
  284. 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. 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. 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. 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. 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. 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. 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 lastday [_lastDay [$itk_component(month) get] $year]
  504.  
  505.     if {$day > $lastday} {
  506.     $itk_component(day) clear
  507.     $itk_component(day) insert end $lastday
  508.     }
  509. }
  510.  
  511. # ----------------------------------------------------------------
  512. # PRIVATE METHOD: _spinDay direction
  513. #
  514. # Increment or decrement day value.  If the previous day was the
  515. # first, then set the new day to the last day for the current
  516. # month.  If it was the last day of the month, change it to the
  517. # first.  Otherwise, spin it to the next day.
  518. # ----------------------------------------------------------------
  519. body iwidgets::Spindate::_spinDay {direction} {
  520.     set month [$itk_component(month) get]
  521.     set day [$itk_component(day) get]
  522.     set year [$itk_component(year) get]
  523.     set lastday [_lastDay $month $year]
  524.     set currclicks [get -clicks]
  525.  
  526.     $itk_component(day) delete 0 end
  527.  
  528.     if {(($day == "01") || ($day == "1")) && ($direction == -1)} {
  529.     $itk_component(day) insert 0 $lastday
  530.         return
  531.     }
  532.  
  533.     if {($day == $lastday) && ($direction == 1)} {
  534.     $itk_component(day) insert 0 "01"
  535.         return
  536.     }
  537.  
  538.     set clicks [clock scan "$direction day" -base $currclicks]
  539.     $itk_component(day) insert 0 [clock format $clicks -format "%d"]
  540. }
  541.  
  542. # ------------------------------------------------------------------
  543. # PRIVATE METHOD: _packDate when
  544. #
  545. # Pack the components of the date spinner.  If "when" is "now", the 
  546. # change is applied immediately.  If it is "later" or it is not 
  547. # specified, then the change is applied later, when the application 
  548. # is idle.
  549. # ------------------------------------------------------------------
  550. body iwidgets::Spindate::_packDate {{when later}} {
  551.     if {$when == "later"} {
  552.     if {$_repack == ""} {
  553.         set _repack [after idle [code $this _packDate now]]
  554.     }
  555.     return
  556.     } elseif {$when != "now"} {
  557.     error "bad option \"$when\": should be now or later"
  558.     }
  559.  
  560.     #
  561.     # Turn off the minsizes for all the rows and columns.  
  562.     #
  563.     for {set i 0} {$i < 5} {incr i} {
  564.     grid rowconfigure $_interior $i -minsize 0
  565.     grid columnconfigure $_interior $i -minsize 0
  566.     }
  567.  
  568.     #
  569.     # Get some boolean 1/0 values for the -monthon and -dayon options.
  570.     # We need this later so that Tcl doesn't complain about operands
  571.     # of || being strings.
  572.     #
  573.     set monthon [expr {$itk_option(-monthon) == "1"}]
  574.     set dayon [expr {$itk_option(-dayon) == "1"}]
  575.  
  576.     set _repack ""
  577.  
  578.     #
  579.     # Based on the orientation, use the grid to place the components into
  580.     # the proper rows and columns.
  581.     #
  582.     switch $itk_option(-orient) {
  583.     vertical {
  584.         set row -1
  585.         
  586.         if {$itk_option(-monthon)} {
  587.         grid $itk_component(month) -row [incr row] -column 0 \
  588.             -sticky nsew 
  589.         } else {
  590.         grid forget $itk_component(month)
  591.         }
  592.         
  593.         if {$itk_option(-dayon)} {
  594.         if {$itk_option(-dayon)} {
  595.             grid rowconfigure $_interior [incr row] \
  596.             -minsize $itk_option(-datemargin)
  597.         }
  598.  
  599.         grid $itk_component(day) -row [incr row] -column 0 \
  600.             -sticky nsew 
  601.         } else {
  602.         grid forget $itk_component(day)
  603.         }
  604.         
  605.         if {$itk_option(-yearon)} {
  606.         if {$monthon || $dayon} {
  607.             grid rowconfigure $_interior [incr row] \
  608.             -minsize $itk_option(-datemargin)
  609.         }
  610.  
  611.         grid $itk_component(year) -row [incr row] -column 0 \
  612.             -sticky nsew 
  613.         } else {
  614.         grid forget $itk_component(year)
  615.         }
  616.         
  617.         if {$itk_option(-labelpos) == "w"} {
  618.         iwidgets::Labeledwidget::alignlabels $itk_component(month) \
  619.             $itk_component(day) $itk_component(year)
  620.         }
  621.     }
  622.     
  623.     horizontal {
  624.         set column -1
  625.  
  626.         if {$itk_option(-monthon)} {
  627.         grid $itk_component(month) -row 0 -column [incr column] \
  628.             -sticky nsew 
  629.         } else {
  630.         grid forget $itk_component(month)
  631.         }
  632.         
  633.         if {$itk_option(-dayon)} {
  634.         if {$itk_option(-monthon)} {
  635.             grid columnconfigure $_interior [incr column] \
  636.             -minsize $itk_option(-datemargin)
  637.         }
  638.  
  639.         grid $itk_component(day) -row 0 -column [incr column] \
  640.             -sticky nsew 
  641.         } else {
  642.         grid forget $itk_component(day)
  643.         }
  644.         
  645.         if {$itk_option(-yearon)} {
  646.         if {$monthon || $dayon} {
  647.             grid columnconfigure $_interior [incr column] \
  648.             -minsize $itk_option(-datemargin)
  649.         }
  650.  
  651.         grid $itk_component(year) -row 0 -column [incr column] \
  652.             -sticky nsew 
  653.         } else {
  654.         grid forget $itk_component(year)
  655.         }
  656.         
  657.         #
  658.         # Un-align labels.
  659.         #
  660.         $itk_component(month) configure -labelmargin 1
  661.         $itk_component(day) configure -labelmargin 1
  662.         $itk_component(year) configure -labelmargin 1
  663.     }
  664.     
  665.     default {
  666.         error "bad orient option \"$itk_option(-orient)\", should\
  667.             be \"vertical\" or \"horizontal\""
  668.     } 
  669.     }
  670.  
  671. # ------------------------------------------------------------------
  672. # PRIVATE METHOD: _lastDay month year
  673. #
  674. # Internal method which determines the last day of the month for
  675. # the given month and year.  We start at 28 and go forward till
  676. # we fail.  Crude but effective.
  677. # ------------------------------------------------------------------
  678. body iwidgets::Spindate::_lastDay {month year} {
  679.     set lastone 28
  680.  
  681.     for {set lastone 28} {$lastone < 32} {incr lastone} {
  682.     if {[regexp {[0-9]+} $month]} {
  683.         if {[catch {clock scan "$month/[expr $lastone + 1]/$year"}] != 0} {
  684.         return $lastone
  685.         }
  686.     } else {
  687.         if {[catch {clock scan "[expr $lastone + 1] $month $year"}] != 0} {
  688.         return $lastone
  689.         }
  690.     }
  691.     }
  692. }
  693.