This file is indexed.

/usr/share/tcltk/iwidgets4.0.1/scripts/spindate.itk is in iwidgets4 4.0.1-6.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
# Spindate 
# ----------------------------------------------------------------------
# Implements a Date spinner widget.  A date spinner contains three
# Spinner widgets:  one Spinner for months, one SpinInt for days,
# and one SpinInt for years.  Months can be specified as abbreviated
# strings, integers or a user-defined list.  Options exist to manage to 
# behavior, appearance, and format of each component spinner.
#
# ----------------------------------------------------------------------
#  AUTHOR: Sue Yockey                  EMAIL: yockey@actc.com
#          Mark L. Ulferts                    mulferts@austin.dsccc.com
#
#   @(#) $Id: spindate.itk,v 1.5 2001/08/22 15:51:13 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.
# ======================================================================

#
# Default resources.
#
option add *Spindate.monthLabel "Month" widgetDefault
option add *Spindate.dayLabel "Day" widgetDefault
option add *Spindate.yearLabel "Year" widgetDefault
option add *Spindate.monthWidth 4 widgetDefault
option add *Spindate.dayWidth 4 widgetDefault
option add *Spindate.yearWidth 4 widgetDefault

#
# Usual options.
#
itk::usual Spindate {
    keep -background -cursor -foreground -labelfont -textbackground -textfont 
}

# ------------------------------------------------------------------
#                            SPINDATE
# ------------------------------------------------------------------
itcl::class iwidgets::Spindate {
    inherit itk::Widget 
    
    constructor {args} {}
    destructor {}
    
    itk_option define -labelpos labelPos Position w
    itk_option define -orient orient Orient vertical 
    itk_option define -monthon monthOn MonthOn true 
    itk_option define -dayon dayOn DayOn true 
    itk_option define -yearon yearOn YearOn true 
    itk_option define -datemargin dateMargin Margin 1 
    itk_option define -yeardigits yearDigits YearDigits 4
    itk_option define -monthformat monthFormat MonthFormat integer 

    public {
	method get {{format "-string"}} 
	method show {{date now}} 
    }

    protected {
	method _packDate {{when later}} 
	variable _repack {}             ;# Reconfiguration flag.
    }

    private {
	method _lastDay {month year}
	method _spinMonth {direction} 
	method _spinDay {direction} 

	variable _monthFormatStr "%m"
	variable _yearFormatStr "%Y"
	variable _interior
    }
}

#
# Provide a lowercased access method for the Spindate class.
# 
proc ::iwidgets::spindate {pathName args} {
    uplevel ::iwidgets::Spindate $pathName $args
}

# ------------------------------------------------------------------
#                        CONSTRUCTOR
# ------------------------------------------------------------------
itcl::body iwidgets::Spindate::constructor {args} {
    set _interior $itk_interior

    set clicks [clock seconds]

    #
    # Create Month Spinner
    #
    itk_component add month {
	iwidgets::Spinner $itk_interior.month  -fixed 2 -justify right \
	    -decrement [itcl::code $this _spinMonth -1] \
	    -increment [itcl::code $this _spinMonth 1] 
    } {
	keep -background -cursor -arroworient -foreground \
		-labelfont -labelmargin -relief -textbackground \
		-textfont -repeatdelay -repeatinterval

	rename -labeltext -monthlabel monthLabel Text
	rename -width -monthwidth monthWidth Width
    }

    #
    # Take off the default bindings for selction and motion.
    #
    bind [$itk_component(month) component entry] <1> {break}
    bind [$itk_component(month) component entry] <Button1-Motion> {break}
    
    #
    # Create Day Spinner
    #
    itk_component add day {
	iwidgets::Spinint $itk_interior.day -fixed 2 -justify right \
	    -decrement [itcl::code $this _spinDay -1] \
	    -increment [itcl::code $this _spinDay 1]
    } {
	keep -background -cursor -arroworient -foreground \
		-labelfont -labelmargin -relief -textbackground \
		-textfont -repeatdelay -repeatinterval

	rename -labeltext -daylabel dayLabel Text
	rename -width -daywidth dayWidth Width
    }
    
    #
    # Take off the default bindings for selction and motion.
    #
    bind [$itk_component(day) component entry] <1> {break}
    bind [$itk_component(day) component entry] <Button1-Motion> {break}
    
    #
    # Create Year Spinner
    #
    itk_component add year {
	iwidgets::Spinint $itk_interior.year -fixed 2 -justify right \
	    -range {1900 3000}
    } {
	keep -background -cursor -arroworient -foreground \
		-labelfont -labelmargin -relief -textbackground \
		-textfont -repeatdelay -repeatinterval

	rename -labeltext -yearlabel yearLabel Text
	rename -width -yearwidth yearWidth Width
    }

    #
    # Take off the default bindings for selction and motion.
    #
    bind [$itk_component(year) component entry] <1> {break}
    bind [$itk_component(year) component entry] <Button1-Motion> {break}
    
    #
    # Initialize the widget based on the command line options.
    #
    eval itk_initialize $args

    #
    # Show the current date.
    #
    show now
}

# ------------------------------------------------------------------
#                           DESTRUCTOR
# ------------------------------------------------------------------
itcl::body iwidgets::Spindate::destructor {} {
    if {$_repack != ""} {after cancel $_repack}
}

# ------------------------------------------------------------------
#                             OPTIONS
# ------------------------------------------------------------------

# ------------------------------------------------------------------
# OPTION: -labelpos
#
# Specifies the location of all 3 spinners' labels.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::labelpos {
    switch $itk_option(-labelpos) {
	n {
	    $itk_component(month) configure -labelpos n
	    $itk_component(day) configure -labelpos n
	    $itk_component(year) configure -labelpos n
	    
	    #
	    # Un-align labels
	    #
	    $itk_component(month) configure -labelmargin 1
	    $itk_component(day) configure -labelmargin 1
	    $itk_component(year) configure -labelmargin 1 
	}
	
	s {
	    $itk_component(month) configure -labelpos s
	    $itk_component(day) configure -labelpos s
	    $itk_component(year) configure -labelpos s
	    
	    #
	    # Un-align labels
	    #
	    $itk_component(month) configure -labelmargin 1
	    $itk_component(day) configure -labelmargin 1
	    $itk_component(year) configure -labelmargin 1 
	}
	
	w {
	    $itk_component(month) configure -labelpos w
	    $itk_component(day) configure -labelpos w
	    $itk_component(year) configure -labelpos w
	}
	
	e {
	    $itk_component(month) configure -labelpos e
	    $itk_component(day) configure -labelpos e
	    $itk_component(year) configure -labelpos e
	    
	    #
	    # Un-align labels
	    #
	    $itk_component(month) configure -labelmargin 1
	    $itk_component(day) configure -labelmargin 1
	    $itk_component(year) configure -labelmargin 1 
	}
	
	default {
	    error "bad labelpos option \"$itk_option(-labelpos)\",\
		    should be n, s, w or e" 
	}
    }

    _packDate
}

# ------------------------------------------------------------------
# OPTION: -orient
# 
# Specifies the orientation of the 3 spinners for Month, Day 
# and year.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::orient {
    _packDate
}

# ------------------------------------------------------------------
# OPTION: -monthon
# 
# Specifies whether or not to display the month spinner.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::monthon {
    _packDate
}

# ------------------------------------------------------------------
# OPTION: -dayon
# 
# Specifies whether or not to display the day spinner.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::dayon {
    _packDate
}

# ------------------------------------------------------------------
# OPTION: -yearon
# 
# Specifies whether or not to display the year spinner.
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::yearon {
    _packDate
}

# ------------------------------------------------------------------
# OPTION: -datemargin
# 
# Specifies the margin space between the month and day spinners 
# and the day and year spinners. 
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::datemargin {
    _packDate
}

# ------------------------------------------------------------------
# OPTION: -yeardigits
#
# Number of digits for year display, 2 or 4 
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::yeardigits {
    set clicks [clock seconds]

    switch $itk_option(-yeardigits) {
	"2" {
	    $itk_component(year) configure -width 2 -fixed 2
	    $itk_component(year) clear
	    $itk_component(year) insert 0 [clock format $clicks -format "%y"]
	    set _yearFormatStr "%y"
	}
	
	"4" {
	    $itk_component(year) configure -width 4 -fixed 4
	    $itk_component(year) clear
	    $itk_component(year) insert 0 [clock format $clicks -format "%Y"]
	    set _yearFormatStr "%Y"
	}
	
	default {
	    error "bad yeardigits option \"$itk_option(-yeardigits)\",\
		    should be 2 or 4"
	}
    } 
}

# ------------------------------------------------------------------
# OPTION: -monthformat
#
# Format of month display, integers (1-12) or brief strings (Jan - 
# Dec), or full strings (January - December).
# ------------------------------------------------------------------
itcl::configbody iwidgets::Spindate::monthformat {
    set clicks [clock seconds]

    if {$itk_option(-monthformat) == "brief"} {
	$itk_component(month) configure -width 3 -fixed 3
	$itk_component(month) delete 0 end
	$itk_component(month) insert 0 [clock format $clicks -format "%b"]
	set _monthFormatStr "%b"
	
    } elseif {$itk_option(-monthformat) == "full"} {
	$itk_component(month) configure -width 9 -fixed 9
	$itk_component(month) delete 0 end
	$itk_component(month) insert 0 [clock format $clicks -format "%B"]
	set _monthFormatStr "%B"
	
    } elseif {$itk_option(-monthformat) == "integer"} {
	$itk_component(month) configure -width 2 -fixed 2 
	$itk_component(month) delete 0 end
	$itk_component(month) insert 0 [clock format $clicks -format "%m"]
	set _monthFormatStr "%m"
	
    } else {
	error "bad monthformat option\
		\"$itk_option(-monthformat)\", should be\
		\"integer\", \"brief\" or \"full\""
    }
}

# ------------------------------------------------------------------
#                            METHODS
# ------------------------------------------------------------------

# ------------------------------------------------------------------
# METHOD: get ?format?
#
# Return the current contents of the spindate widget 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 dates 
# and their formats.
# ------------------------------------------------------------------
itcl::body iwidgets::Spindate::get {{format "-string"}} { 
    set month [$itk_component(month) get]
    set day [$itk_component(day) get]
    set year [$itk_component(year) get]

    if {[regexp {[0-9]+} $month]} {
	set datestr "$month/$day/$year"
    } else {
	set datestr "$day $month $year"
    }

    switch -- $format {
	"-string" {
	    return $datestr
	}
	"-clicks" {
	    return [clock scan $datestr]
	}
	default {
	    error "bad format option \"$format\":\
                   should be -string or -clicks"
	}
    }
}

# ------------------------------------------------------------------
# PUBLIC METHOD: show date
#
# Changes the currently displayed date to be that of the date 
# argument.  The date may be specified either as a string or an
# integer clock value.  Reference the clock command for more 
# information on obtaining dates and their formats.
# ------------------------------------------------------------------
itcl::body iwidgets::Spindate::show {{date "now"}} {
    #
    # Convert the date to a clock clicks value.
    #
    if {$date == "now"} {
	set seconds [clock seconds]
    } else {
	if {[catch {clock format $date}] == 0} {
	    set seconds $date
	} elseif {[catch {set seconds [clock scan $date]}] != 0} {
	    error "bad date: \"$date\", must be a valid date\
               string, clock clicks value or the keyword now"
	}
    }

    #
    # Display the month based on the -monthformat option.
    #
    switch $itk_option(-monthformat) {
	"brief" {
	    $itk_component(month) delete 0 end
	    $itk_component(month) insert 0 [clock format $seconds -format "%b"]
	}	
	"full" {
	    $itk_component(month) delete 0 end
	    $itk_component(month) insert 0 [clock format $seconds -format "%B"]
	}	
	"integer" {
	    $itk_component(month) delete 0 end
	    $itk_component(month) insert 0 [clock format $seconds -format "%m"]
	}
    }

    #
    # Display the day.
    #
    $itk_component(day) delete 0 end
    $itk_component(day) insert end [clock format $seconds -format "%d"]

    #
    # Display the year based on the -yeardigits option.
    #
    switch $itk_option(-yeardigits) {
	"2" {
	    $itk_component(year) delete 0 end
	    $itk_component(year) insert 0 [clock format $seconds -format "%y"]
	}
	
	"4" {
	    $itk_component(year) delete 0 end
	    $itk_component(year) insert 0 [clock format $seconds -format "%Y"]
	}
    }

    return
}

# ----------------------------------------------------------------
# PRIVATE METHOD: _spinMonth direction
#
# Increment or decrement month value.  We need to get the values
# for all three fields so we can make sure the day agrees with
# the month.  Should the current day be greater than the day for
# the spun month, then the day is set to the last day for the
# new month.
# ----------------------------------------------------------------
itcl::body iwidgets::Spindate::_spinMonth {direction} {
    set month [$itk_component(month) get]
    set day [$itk_component(day) get]
    set year [$itk_component(year) get]

    #
    # There appears to be a bug in the Tcl clock command in that it
    # can't scan a date like "12/31/1999 1 month" or any other date with
    # a year above 2000, but it has no problem scanning "07/01/1998 1 month".
    # So, we're going to play a game and increment by days until this
    # is fixed in Tcl.
    #
    if {$direction == 1} {
	set incrdays 32
	set day 01
    } else {
	set incrdays -28
	set day 28
    }

    if {[regexp {[0-9]+} $month]} {
	set clicks [clock scan "$month/$day/$year $incrdays day"]
    } else {
	set clicks [clock scan "$day $month $year $incrdays day"]
    }

    $itk_component(month) clear
    $itk_component(month) insert 0 \
	[clock format $clicks -format $_monthFormatStr]

    set currday [$itk_component(day) get]
    set lastday [_lastDay [$itk_component(month) get] $year]

    if {$currday > $lastday} {
	$itk_component(day) clear
	$itk_component(day) insert end $lastday
    }
}

# ----------------------------------------------------------------
# PRIVATE METHOD: _spinDay direction
#
# Increment or decrement day value.  If the previous day was the
# first, then set the new day to the last day for the current
# month.  If it was the last day of the month, change it to the
# first.  Otherwise, spin it to the next day.
# ----------------------------------------------------------------
itcl::body iwidgets::Spindate::_spinDay {direction} {
    set month [$itk_component(month) get]
    set day [$itk_component(day) get]
    set year [$itk_component(year) get]
    set lastday [_lastDay $month $year]
    set currclicks [get -clicks]

    $itk_component(day) delete 0 end

    if {(($day == "01") || ($day == "1")) && ($direction == -1)} {
	$itk_component(day) insert 0 $lastday
        return
    }

    if {($day == $lastday) && ($direction == 1)} {
	$itk_component(day) insert 0 "01"
        return
    }

    set clicks [clock scan "$direction day" -base $currclicks]
    $itk_component(day) insert 0 [clock format $clicks -format "%d"]
}

# ------------------------------------------------------------------
# PRIVATE METHOD: _packDate when
#
# Pack the components of the date spinner.  If "when" is "now", the 
# change is applied immediately.  If it is "later" or it is not 
# specified, then the change is applied later, when the application 
# is idle.
# ------------------------------------------------------------------
itcl::body iwidgets::Spindate::_packDate {{when later}} {
    if {$when == "later"} {
	if {$_repack == ""} {
	    set _repack [after idle [itcl::code $this _packDate now]]
	}
	return
    } elseif {$when != "now"} {
	error "bad option \"$when\": should be now or later"
    }

    #
    # Turn off the minsizes for all the rows and columns.  
    #
    for {set i 0} {$i < 5} {incr i} {
	grid rowconfigure $_interior $i -minsize 0
	grid columnconfigure $_interior $i -minsize 0
    }

    set _repack ""

    #
    # Based on the orientation, use the grid to place the components into
    # the proper rows and columns.
    #
    switch $itk_option(-orient) {
	vertical {
	    set row -1
	    
	    if {$itk_option(-monthon)} {
		grid $itk_component(month) -row [incr row] -column 0 \
		    -sticky nsew 
	    } else {
		grid forget $itk_component(month)
	    }
	    
	    if {$itk_option(-dayon)} {
		if {$itk_option(-dayon)} {
		    grid rowconfigure $_interior [incr row] \
			-minsize $itk_option(-datemargin)
		}

		grid $itk_component(day) -row [incr row] -column 0 \
		    -sticky nsew 
	    } else {
		grid forget $itk_component(day)
	    }
	    
	    if {$itk_option(-yearon)} {
		if {$itk_option(-monthon) || $itk_option(-dayon)} {
		    grid rowconfigure $_interior [incr row] \
			-minsize $itk_option(-datemargin)
		}

		grid $itk_component(year) -row [incr row] -column 0 \
		    -sticky nsew 
	    } else {
		grid forget $itk_component(year)
	    }
	    
	    if {$itk_option(-labelpos) == "w"} {
		iwidgets::Labeledwidget::alignlabels $itk_component(month) \
			$itk_component(day) $itk_component(year)
	    }
	}
	
	horizontal {
	    set column -1

	    if {$itk_option(-monthon)} {
		grid $itk_component(month) -row 0 -column [incr column] \
		    -sticky nsew 
	    } else {
		grid forget $itk_component(month)
	    }
	    
	    if {$itk_option(-dayon)} {
		if {$itk_option(-monthon)} {
		    grid columnconfigure $_interior [incr column] \
			-minsize $itk_option(-datemargin)
		}

		grid $itk_component(day) -row 0 -column [incr column] \
		    -sticky nsew 
	    } else {
		grid forget $itk_component(day)
	    }
	    
	    if {$itk_option(-yearon)} {
		if {$itk_option(-monthon) || $itk_option(-dayon)} {
		    grid columnconfigure $_interior [incr column] \
			-minsize $itk_option(-datemargin)
		}

		grid $itk_component(year) -row 0 -column [incr column] \
		    -sticky nsew 
	    } else {
		grid forget $itk_component(year)
	    }
	    
	    #
	    # Un-align labels.
	    #
	    $itk_component(month) configure -labelmargin 1
	    $itk_component(day) configure -labelmargin 1
	    $itk_component(year) configure -labelmargin 1
	}
	
	default {
	    error "bad orient option \"$itk_option(-orient)\", should\
		    be \"vertical\" or \"horizontal\""
	} 
    }
} 

# ------------------------------------------------------------------
# PRIVATE 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.
# ------------------------------------------------------------------
itcl::body iwidgets::Spindate::_lastDay {month year} {
    set lastone 28

    for {set lastone 28} {$lastone < 32} {incr lastone} {
	if {[regexp {[0-9]+} $month]} {
	  if {[catch {clock scan "$month/[expr {$lastone + 1}]/$year"}] != 0} {
		return $lastone
	  }
	} else {
	  if {[catch {clock scan "[expr {$lastone + 1}] $month $year"}] != 0} {
		return $lastone
	  }
	}
    }
}