Subversion Repository Public Repository

litesoft

Diff Revisions 151 vs 948 for /trunk/Java/GWT/Client/src/org/litesoft/GWT/forms/client/components/nonpublic/datepicker/DatePicker.java

Diff revisions: vs.
  @@ -1 +1 @@
1 - // This Source Code is Copyright & Licenced as indicated below
2 1 * Copyright 2007 Google Inc.
3 2 *
4 3 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 4 * use this file except in compliance with the License. You may obtain a copy of
6 5 * the License at
7 6 *
8 7 * http://www.apache.org/licenses/LICENSE-2.0
9 8 *
10 9 * Unless required by applicable law or agreed to in writing, software
11 10 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 11 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 12 * License for the specific language governing permissions and limitations under
14 13 * the License.
15 14 */
16 15 * DatePicker widget displays a small Gregorian calendar dates to select
17 16 * a date by the user.
18 17 * <p/>
19 18 * <p>It has following features:
20 19 * <p/>
21 20 * <ul>
22 21 * <li>Fully internationalized by default locale</li>
23 22 * <li>Optional display of dates form the adjacent dates months</li>
24 23 * <li>Add a special formatting for a given day</li>
25 24 * <li>Select any date as the start date and month.
26 25 * Today's date is the default selection and the default displayed month.</li>
27 26 * </ul>
28 27 * </p>
29 28 * <p>CSS hooks:
30 29 * <table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0">
31 30 * <tbody>
32 31 * <tr>
33 32 * <td style="FONT-WEIGHT:bold">
34 33 * Style name<br/>
35 34 * </td>
36 35 * <td style="FONT-WEIGHT:bold">
37 36 * Widget region affected<br/>
38 37 * </td>
39 38 * </tr>
40 39 * <tr>
41 40 * <td>
42 41 * .goog-date-picker<br/>
43 42 * </td>
44 43 * <td>
45 44 * Entire widget<br/>
46 45 * </td>
47 46 * </tr>
48 47 * <tr>
49 48 * <td>
50 49 * .goog-date-picker .grid<br/>
51 50 * </td>
52 51 * <td>
53 52 * Grid in the DatePicker.
54 53 * This includes week names and the date numbers.<br/>
55 54 * </td>
56 55 * </tr>
57 56 * <tr>
58 57 * <td>
59 58 * .goog-date-picker .title<br/>
60 59 * </td>
61 60 * <td>
62 61 * Month and Year titles on the top<br/>
63 62 * </td>
64 63 * </tr>
65 64 * <tr>
66 65 * <td>
67 66 * .goog-date-picker .control<br/>
68 67 * </td>
69 68 * <td>
70 69 * Month and year increment and decrement buttons<br/>
71 70 * </td>
72 71 * </tr>
73 72 * <tr>
74 73 * <td>
75 74 * .goog-date-picker .control-menu<br/>
76 75 * </td>
77 76 * <td>
78 77 * Month and year list available by clicking on them<br/>
79 78 * </td>
80 79 * </tr>
81 80 * <tr>
82 81 * <td>
83 82 * .goog-date-picker .control-block<br/>
84 83 * </td>
85 84 * <td>
86 85 * The block of month/year display with its
87 86 * increment decrement controls<br/>
88 87 * </td>
89 88 * </tr>
90 89 * <tr>
91 90 * <td>
92 91 * .goog-date-picker .control-pane<br/>
93 92 * </td>
94 93 * <td>
95 94 * Top area containing month and year controls<br/>
96 95 * </td>
97 96 * </tr>
98 97 * <tr>
99 98 * <td>
100 99 * .goog-date-picker .control-today<br/>
101 100 * </td>
102 101 * <td>
103 102 * Clickable today button<br/>
104 103 * </td>
105 104 * </tr>
106 105 * <tr>
107 106 * <td>
108 107 * .goog-date-picker .weekday<br/>
109 108 * </td>
110 109 * <td>
111 110 * Any date<br/>
112 111 * </td>
113 112 * </tr>
114 113 * <tr>
115 114 * <td>
116 115 * .goog-date-picker .week-names<br/>
117 116 * </td>
118 117 * <td>
119 118 * Weekday names<br/>
120 119 * </td>
121 120 * </tr>
122 121 * <tr>
123 122 * <td>
124 123 * .goog-date-picker .week-numbers<br/>
125 124 * </td>
126 125 * <td>
127 126 * Week of the year number<br/>
128 127 * </td>
129 128 * </tr>
130 129 * <tr>
131 130 * <td>
132 131 * .goog-date-picker .weekend-start<br/>
133 132 * </td>
134 133 * <td>
135 134 * Weekend startdate<br/>
136 135 * </td>
137 136 * </tr>
138 137 * <tr>
139 138 * <td>
140 139 * .goog-date-picker .weekend-end<br/>
141 140 * </td>
142 141 * <td>
143 142 * Weekend end date<br/>
144 143 * </td>
145 144 * </tr>
146 145 * <tr>
147 146 * <td>
148 147 * .goog-date-picker .today<br/>
149 148 * </td>
150 149 * <td>
151 150 * Special formatting for today
152 151 * </td>
153 152 * </tr>
154 153 * <tr>
155 154 * <td>
156 155 * .goog-date-picker .selected<br/>
157 156 * </td>
158 157 * <td>
159 158 * Special formatting for the selected date<br/>
160 159 * </td>
161 160 * </tr>
162 161 * <tr>
163 162 * <td>
164 163 * .goog-date-picker .other-month
165 164 * </td>
166 165 * <td>
167 166 * Opacity reducing formatting for the adjacent months<br/>
168 167 * </td>
169 168 * </tr>
170 169 * </tbody>
171 170 * </table>
172 171 * </p>
173 172 * <p>Following are the incomplete features.
174 173 * Some components of these features exist.
175 174 * However, they do not function completely.
176 175 * <ul>
177 176 * <li>Optional display week numbers</li>
178 177 * </ul>
179 178 * </p>
180 179 * <p>Desired features
181 180 * <ul>
182 181 * <li>Disable calendar functions beyond an end date.
183 182 * This is useful when document archives. Default today.</li>
184 183 * <li>Disable calendar functions beyond an start date.
185 184 * This is useful for reservation systems. Default today.</li>
186 185 * <li>Disable calendar functions on a specific date.
187 186 * This is useful for reservation systems.</li>
188 187 * <li>Right to Left layout depending on the page layout.</li>
189 188 * </ul>
190 189 * </p>
191 190 */
192 191 ChangeListener,
193 192 SourcesChangeEvents
194 193 private static final String STYLE_DATE_PICKER = "goog-date-picker";
195 194 private static final String STYLE_GRID = "grid";
196 195 private static final String STYLE_CONTROL = "control";
197 196 private static final String STYLE_CONTROL_BLOCK = "control-block";
198 197 private static final String STYLE_CONTROL_PANE = "control-pane";
199 198 private static final String STYLE_CONTROL_MENU = "control-menu";
200 199 private static final String STYLE_CONTROL_TODAY = "control-today";
201 200 private static final String STYLE_TITLE = "title";
202 201 private static final String STYLE_WEEK_NAMES = "week-names";
203 202 private static final String STYLE_WEEK_NUMBERS = "numbers";
204 203 private static final String STYLE_WEEKDAY = "weekday";
205 204 private static final String STYLE_WEEKEND_START = "weekend-start";
206 205 private static final String STYLE_WEEKEND_END = "weekend-end";
207 206 private static final String STYLE_OTHER_MONTHS = "other-month";
208 207 private static final String STYLE_TODAY = "today";
209 208 private static final String STYLE_SELECTED = "selected";
210 209 // Unique numbers representing various actions available in the controls.
211 210 private static final int ACTION_PREV_MONTH = 0;
212 211 private static final int ACTION_SET_MONTH = 1;
213 212 private static final int ACTION_NEXT_MONTH = 2;
214 213 private static final int ACTION_PREV_YEAR = 3;
215 214 private static final int ACTION_SET_YEAR = 4;
216 215 private static final int ACTION_NEXT_YEAR = 5;
217 216 private static final int ACTION_TODAY = 6;
218 217 private static final int ACTION_CLOSE = 7;
219 218 // Unique numbers representing formating actions.
220 219 private static final int FORMAT_ACTION_REMOVE = 0;
221 220 private static final int FORMAT_ACTION_ADD = 1;
222 221 private LocaleCalendarUtils dateTable;
223 222 private ChangeListenerCollection changeListeners = new ChangeListenerCollection();
224 223 private HorizontalPanel control = new HorizontalPanel();
225 224 private FlexTable grid;
226 225 // menu based action
227 226 private int weekOfYearOffset = 0;
228 227 private boolean showYearMonthListing = true;
229 228 private boolean showTodayButton = false;
230 229 private int monthAction;
231 230 private int yearAction;
232 231 private DatePickerCell today;
233 232 private final VerticalPanel panel = new VerticalPanel();
234 233 private int prevMonthSize;
235 234 private int prevMonthDays;
236 235 private int currMonthSize;
237 236 private int nextMonthDays;
238 237 private int gridStart;
239 238 /**
240 239 * Constructor of the DatePicker class.
241 240 */
242 241 public DatePicker()
243 242 {
244 243 super( true ); // hide dialogue box when clicked outside
245 244 dateTable = new LocaleCalendarUtils( false );
246 245 dateTable.specialDate( LocaleCalendarUtils.TODAY ).setTag( STYLE_TODAY );
247 246 dateTable.specialDate( LocaleCalendarUtils.SELECTED ).setTag( STYLE_SELECTED );
248 247 grid = new FlexTable();
249 248 grid.setWidth( "100%" );
250 249 grid.setStyleName( STYLE_GRID );
251 250 panel.addStyleName( STYLE_DATE_PICKER );
252 251 panel.setHorizontalAlignment( VerticalPanel.ALIGN_CENTER );
253 252 drawControlPane();
254 253 panel.add( control );
255 254 // grid operations
256 255 addDaysOfWeek();
257 256 initialGrid();
258 257 gridUpdate();
259 258 panel.add( grid );
260 259 // today label
261 260 today = dateTable.todayCell();
262 261 today.setValue( ACTION_TODAY );
263 262 today.addStyleName( STYLE_CONTROL_TODAY );
264 263 today.addClickListener( this );
265 264 enableTodayButton();
266 265 super.setWidget( panel );
267 266 }
268 267 /**
269 268 * Public method complete ClickListner interface. This adds a listener to the
270 269 * listeners for Change events. Namely, a date clicked by the user.
271 270 *
272 271 * @param listener - listener for events
273 272 */
274 273 public void addChangeListener( ChangeListener listener )
275 274 {
276 275 changeListeners.add( listener );
277 276 }
278 277 /**
279 278 * Public method onChange which is fired when user clicks on the
280 279 * list menu in the widget.
281 280 *
282 281 * @param sender - widget on which user clicked.
283 282 */
284 283 public void onChange( Widget sender )
285 284 {
286 285 if ( sender instanceof ListBox )
287 286 {
288 287 ListBox list = (ListBox) sender;
289 288 String val = list.getValue( list.getSelectedIndex() );
290 289 int ival = Integer.valueOf( val ).intValue();
291 290 if ( list == dateTable.monthNames() )
292 291 {
293 292 action( monthAction, ival );
294 293 }
295 294 else
296 295 {
297 296 action( yearAction, ival );
298 297 }
299 298 changeListeners.fireChange( this );
300 299 }
301 300 }
302 301 /**
303 302 * Public method onClick which is fired when user clicks on the widget.
304 303 *
305 304 * @param sender - widget on which user clicked.
306 305 */
307 306 public void onClick( Widget sender )
308 307 {
309 308 if ( sender instanceof DatePickerCell )
310 309 {
311 310 DatePickerCell cell = (DatePickerCell) sender;
312 311 int type = cell.type();
313 312 int value = cell.value();
314 313 if ( type == LocaleCalendarUtils.TYPE_CONTROL )
315 314 {
316 315 action( value );
317 316 }
318 317 else
319 318 {
320 319 formatSpecialDates( FORMAT_ACTION_REMOVE );
321 320 dateTable.selectedDate( type, value );
322 321 if ( type == LocaleCalendarUtils.TYPE_CURR_MONTH )
323 322 {
324 323 formatSpecialDates( FORMAT_ACTION_ADD );
325 324 }
326 325 else
327 326 {
328 327 gridUpdate();
329 328 }
330 329 }
331 330 changeListeners.fireChange( this );
332 331 }
333 332 }
334 333 /**
335 334 * Public method removeChangeListener() removes a element from the list of
336 335 * listeners which will get fired on an widget change event. Example for
337 336 * listener change event is user click on a date.
338 337 *
339 338 * @param listener - listener for widget change events
340 339 */
341 340 public void removeChangeListener( ChangeListener listener )
342 341 {
343 342 changeListeners.remove( listener );
344 343 }
345 344 /**
346 345 * Public method to get the value of the user selected date for the
347 346 * DatePicker object.
348 347 *
349 348 * @return Date - value of the selected date
350 349 */
351 350 public Date selectedDate()
352 351 {
353 352 return dateTable;
354 353 }
355 354 /**
356 355 * Public method to set the default day and date of the widget.
357 356 * Date picker for the given month and year will be displayed.
358 357 * The given date will be marked as the selected date.
359 358 *
360 359 * @param date - Java Date value to be set
361 360 */
362 361 public void setFullDate( Date date )
363 362 {
364 363 formatSpecialDates( FORMAT_ACTION_REMOVE );
365 364 dateTable.setFullDate( date );
366 365 gridUpdate();
367 366 }
368 367 /**
369 368 * Public method to set a given special formatting for the given date.
370 369 *
371 370 * @param date - Date to be formatted specially
372 371 * @param style - CSS style to be used
373 372 */
374 373 public void setSpecialDate( Date date, String style )
375 374 {
376 375 DatePickerDate specialDay = dateTable.addSpecialDay( date );
377 376 specialDay.setTag( style );
378 377 formatSpecialDates( FORMAT_ACTION_ADD );
379 378 }
380 379 /**
381 380 * Public method to enable or disable displaying the trailing
382 381 * and leading dates from previous and next months.
383 382 *
384 383 * @param show - A boolean indicating whether to show or not
385 384 */
386 385 public void showAdjacentMonths( boolean show )
387 386 {
388 387 dateTable.enableAdjacentMonths( show );
389 388 gridUpdate();
390 389 }
391 390 /**
392 391 * Public method to display the listing of adjacent months and years by
393 392 * clicking on the month or year in the title.
394 393 *
395 394 * @param show - A boolean indicating whether to show or not
396 395 */
397 396 public void showTodayButton( boolean show )
398 397 {
399 398 this.showTodayButton = show;
400 399 enableTodayButton();
401 400 }
402 401 /**
403 402 * Public method to enable or disable displaying the week number of the year.
404 403 * (implementation not completed)
405 404 *
406 405 * @param show - A boolean indicating whether to show or not
407 406 */
408 407 public void showWeekOfYear( boolean show )
409 408 {
410 409 this.weekOfYearOffset = show ? 1 : 0;
411 410 gridUpdate();
412 411 }
413 412 /**
414 413 * Public method to display the listing of adjacent months and years by
415 414 * clicking on the month or year in the title.
416 415 *
417 416 * @param show - A boolean indicating whether to show or not
418 417 */
419 418 public void showYearMonthListing( boolean show )
420 419 {
421 420 this.showYearMonthListing = show;
422 421 drawControlPane();
423 422 }
424 423 private void action( int actionNum, int arg )
425 424 {
426 425 formatSpecialDates( FORMAT_ACTION_REMOVE );
427 426 switch ( actionNum )
428 427 {
429 428 case ACTION_SET_MONTH:
430 429 dateTable.setMonth( arg );
431 430 break;
432 431 case ACTION_SET_YEAR:
433 432 dateTable.setYear( arg );
434 433 break;
435 434 }
436 435 gridUpdate();
437 436 }
438 437 private void action( int actionNum )
439 438 {
440 439 if ( actionNum == ACTION_CLOSE )
441 440 {
442 441 this.hide();
443 442 }
444 443 else
445 444 {
446 445 formatSpecialDates( FORMAT_ACTION_REMOVE );
447 446 switch ( actionNum )
448 447 {
449 448 case ACTION_PREV_MONTH:
450 449 dateTable.addMonths( -1 );
451 450 break;
452 451 case ACTION_NEXT_MONTH:
453 452 dateTable.addMonths( 1 );
454 453 break;
455 454 case ACTION_PREV_YEAR:
456 455 dateTable.addMonths( -12 );
457 456 break;
458 457 case ACTION_NEXT_YEAR:
459 458 dateTable.addMonths( 12 );
460 459 break;
461 460 case ACTION_TODAY:
462 461 dateTable.setToday();
463 462 break;
464 463 }
465 464 gridUpdate();
466 465 }
467 466 }
468 467 private void addDaysOfWeek()
469 468 {
470 469 String[] dayOfWeekNames = LocaleCalendarUtils.dayOfWeekNames();
471 470 for ( int col = 0; col < 7; col++ )
472 471 {
473 472 int dayOfWeek = (col + dateTable.weekStart()) % 7;
474 473 grid.setText( 0, col + weekOfYearOffset, dayOfWeekNames[dayOfWeek] );
475 474 grid.getCellFormatter().setStyleName( 0, col + weekOfYearOffset, STYLE_WEEK_NAMES );
476 475 }
477 476 }
478 477 private void addWeekOfYear()
479 478 {
480 479 String[] weekOfYear = dateTable.weekOfYear();
481 480 for ( int row = 0; row < 7; row++ )
482 481 {
483 482 grid.setText( row + 1, 0, weekOfYear[row] );
484 483 grid.getCellFormatter().addStyleName( row + 1, 0, STYLE_WEEK_NUMBERS );
485 484 }
486 485 }
487 486 private void colFormat( int tableRow, int tableCol, int weekendStart, int weekendEnd, DatePickerCell w )
488 487 {
489 488 String style;
490 489 if ( tableCol == (weekendStart + weekOfYearOffset) )
491 490 {
492 491 style = STYLE_WEEKEND_START;
493 492 }
494 493 else if ( tableCol == (weekendEnd + weekOfYearOffset) )
495 494 {
496 495 style = STYLE_WEEKEND_END;
497 496 }
498 497 else
499 498 {
500 499 style = STYLE_WEEKDAY;
501 500 }
502 501 w.setStyleName( style );
503 502 grid.getCellFormatter().addStyleName( tableRow, tableCol, style );
504 503 }
505 504 private void dateFormat( int diffFromMonthStart, String style, int action )
506 505 {
507 506 if ( diffFromMonthStart < -prevMonthDays || diffFromMonthStart >= currMonthSize + nextMonthDays )
508 507 {
509 508 return;
510 509 }
511 510 int i = diffFromMonthStart + prevMonthDays + gridStart;
512 511 int row = i / 7;
513 512 int col = i % 7;
514 513 int tableRow = row + 1;
515 514 int tableCol = col + weekOfYearOffset;
516 515 switch ( action )
517 516 {
518 517 case FORMAT_ACTION_REMOVE:
519 518 grid.getCellFormatter().removeStyleName( tableRow, tableCol, style );
520 519 grid.getWidget( tableRow, tableCol ).removeStyleName( style );
521 520 break;
522 521 case FORMAT_ACTION_ADD:
523 522 grid.getCellFormatter().addStyleName( tableRow, tableCol, style );
524 523 grid.getWidget( tableRow, tableCol ).addStyleName( style );
525 524 break;
526 525 }
527 526 }
528 527 private void drawControlPane()
529 528 {
530 529 control.clear();
531 530 control.setWidth( "100%" );
532 531 control.setHorizontalAlignment( HorizontalPanel.ALIGN_CENTER );
533 532 control.addStyleName( STYLE_CONTROL_PANE );
534 533 Widget yearControl = drawControls( dateTable.yearNames(), dateTable.yearName(), ACTION_PREV_YEAR, ACTION_NEXT_YEAR, ACTION_SET_YEAR );
535 534 Widget monthControl = drawControls( dateTable.monthNames(), dateTable.monthName(), ACTION_PREV_MONTH, ACTION_NEXT_MONTH, ACTION_SET_MONTH );
536 535 if ( dateTable.isYearBeforeMonth() )
537 536 {
538 537 control.add( yearControl );
539 538 control.add( monthControl );
540 539 }
541 540 else
542 541 {
543 542 control.add( monthControl );
544 543 control.add( yearControl );
545 544 }
546 545 }
547 546 private Widget drawControls( ListBox names, Label name, int prev, int next, int set )
548 547 {
549 548 HorizontalPanel hp = new HorizontalPanel();
550 549 hp.setHorizontalAlignment( HorizontalPanel.ALIGN_CENTER );
551 550 hp.addStyleName( STYLE_CONTROL_BLOCK );
552 551 if ( names == dateTable.monthNames() )
553 552 {
554 553 monthAction = set;
555 554 }
556 555 else
557 556 {
558 557 yearAction = set;
559 558 }
560 559 // move left
561 560 if ( !showYearMonthListing || set == ACTION_SET_MONTH )
562 561 {
563 562 DatePickerCell left = new DatePickerCell( "\u00ab" ); // \u00ab is <<
564 563 left.setType( LocaleCalendarUtils.TYPE_CONTROL );
565 564 left.setValue( prev );
566 565 left.addStyleName( STYLE_CONTROL );
567 566 left.addClickListener( this );
568 567 hp.add( left );
569 568 }
570 569 // Need list box or not
571 570 if ( showYearMonthListing )
572 571 {
573 572 names.setVisibleItemCount( 1 );
574 573 names.addStyleName( STYLE_CONTROL_MENU );
575 574 names.addChangeListener( this );
576 575 hp.add( names );
577 576 }
578 577 else
579 578 {
580 579 name.addStyleName( STYLE_TITLE );
581 580 hp.add( name );
582 581 }
583 582 // move right
584 583 if ( !showYearMonthListing || set == ACTION_SET_MONTH )
585 584 {
586 585 DatePickerCell right = new DatePickerCell( "\u00bb" ); // \u00ab is >>
587 586 right.setType( LocaleCalendarUtils.TYPE_CONTROL );
588 587 right.setValue( next );
589 588 right.addStyleName( STYLE_CONTROL );
590 589 right.addClickListener( this );
591 590 hp.add( right );
592 591 }
593 592 return hp;
594 593 }
595 594 private void enableTodayButton()
596 595 {
597 596 if ( showTodayButton )
598 597 {
599 598 panel.add( today );
600 599 }
601 600 else
602 601 {
603 602 panel.remove( today );
604 603 }
605 604 }
606 605 private void formatSpecialDates( int action )
607 606 {
608 607 int numSpecialDays = dateTable.numSpecialDays();
609 608 for ( int i = 0; i < numSpecialDays; i++ )
610 609 {
611 610 DatePickerDate date = dateTable.specialDate( i );
612 611 dateFormat( date.dayDiff(), date.tag(), action );
613 612 }
614 613 }
615 614 private void gridUpdate()
616 615 {
617 616 DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();
618 617 DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
619 618 DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();
620 619 prevMonthSize = dateTable.prevMonthSize();
621 620 prevMonthDays = dateTable.prevMonthDays();
622 621 currMonthSize = dateTable.currMonthSize();
623 622 nextMonthDays = dateTable.nextMonthDays();
624 623 gridStart = dateTable.gridStart();
625 624 int weekendStart = dateTable.weekendStart();
626 625 int weekendEnd = dateTable.weekendEnd();
627 626 if ( weekOfYearOffset > 0 )
628 627 {
629 628 addWeekOfYear();
630 629 }
631 630 int rowCount = grid.getRowCount();
632 631 for ( int i = rowCount - 1; i > 0; i-- )
633 632 { // 0th row is the week names
634 633 grid.removeRow( i );
635 634 }
636 635 for ( int i = 0; i < prevMonthDays; i++ )
637 636 {
638 637 int row = i / 7;
639 638 int col = i % 7;
640 639 int tableRow = row + 1;
641 640 int tableCol = col + weekOfYearOffset;
642 641 int dayOfMonth = prevMonthSize - prevMonthDays + i; // 0 based
643 642 colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNamesPrev[dayOfMonth] );
644 643 grid.setWidget( tableRow, tableCol, dayOfMonthNamesPrev[dayOfMonth] );
645 644 grid.getCellFormatter().addStyleName( tableRow, tableCol, STYLE_OTHER_MONTHS );
646 645 }
647 646 for ( int i = 0; i < currMonthSize; i++ )
648 647 {
649 648 int row = (gridStart + prevMonthDays + i) / 7;
650 649 int col = (gridStart + prevMonthDays + i) % 7;
651 650 int tableRow = row + 1;
652 651 int tableCol = col + weekOfYearOffset;
653 652 colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNames[i] );
654 653 grid.setWidget( tableRow, tableCol, dayOfMonthNames[i] );
655 654 }
656 655 for ( int i = 0; i < nextMonthDays; i++ )
657 656 {
658 657 int row = (currMonthSize + prevMonthDays + i) / 7;
659 658 int col = (currMonthSize + prevMonthDays + i) % 7;
660 659 int tableRow = row + 1;
661 660 int tableCol = col + weekOfYearOffset;
662 661 colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNamesNext[i] );
663 662 grid.setWidget( tableRow, tableCol, dayOfMonthNamesNext[i] );
664 663 grid.getCellFormatter().addStyleName( tableRow, tableCol, STYLE_OTHER_MONTHS );
665 664 }
666 665 formatSpecialDates( FORMAT_ACTION_ADD );
667 666 }
668 667 private void initialGrid()
669 668 {
670 669 DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
671 670 DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();
672 671 DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();
673 672 for ( int i = 0; i < 31; i++ )
674 673 {
675 674 dayOfMonthNamesPrev[i].addClickListener( this );
676 675 dayOfMonthNamesNext[i].addClickListener( this );
677 676 dayOfMonthNames[i].addClickListener( this );
678 677 }
679 678 }
679 + // This Source Code is Copyright & Licenced as indicated below
680 680 * Copyright 2007 Google Inc.
681 681 *
682 682 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
683 683 * use this file except in compliance with the License. You may obtain a copy of
684 684 * the License at
685 685 *
686 686 * http://www.apache.org/licenses/LICENSE-2.0
687 687 *
688 688 * Unless required by applicable law or agreed to in writing, software
689 689 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
690 690 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
691 691 * License for the specific language governing permissions and limitations under
692 692 * the License.
693 693 */
694 694 * DatePicker widget displays a small Gregorian calendar dates to select
695 695 * a date by the user.
696 696 * <p/>
697 697 * <p>It has following features:
698 698 * <p/>
699 699 * <ul>
700 700 * <li>Fully internationalized by default locale</li>
701 701 * <li>Optional display of dates form the adjacent dates months</li>
702 702 * <li>Add a special formatting for a given day</li>
703 703 * <li>Select any date as the start date and month.
704 704 * Today's date is the default selection and the default displayed month.</li>
705 705 * </ul>
706 706 * </p>
707 707 * <p>CSS hooks:
708 708 * <table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0">
709 709 * <tbody>
710 710 * <tr>
711 711 * <td style="FONT-WEIGHT:bold">
712 712 * Style name<br/>
713 713 * </td>
714 714 * <td style="FONT-WEIGHT:bold">
715 715 * Widget region affected<br/>
716 716 * </td>
717 717 * </tr>
718 718 * <tr>
719 719 * <td>
720 720 * .goog-date-picker<br/>
721 721 * </td>
722 722 * <td>
723 723 * Entire widget<br/>
724 724 * </td>
725 725 * </tr>
726 726 * <tr>
727 727 * <td>
728 728 * .goog-date-picker .grid<br/>
729 729 * </td>
730 730 * <td>
731 731 * Grid in the DatePicker.
732 732 * This includes week names and the date numbers.<br/>
733 733 * </td>
734 734 * </tr>
735 735 * <tr>
736 736 * <td>
737 737 * .goog-date-picker .title<br/>
738 738 * </td>
739 739 * <td>
740 740 * Month and Year titles on the top<br/>
741 741 * </td>
742 742 * </tr>
743 743 * <tr>
744 744 * <td>
745 745 * .goog-date-picker .control<br/>
746 746 * </td>
747 747 * <td>
748 748 * Month and year increment and decrement buttons<br/>
749 749 * </td>
750 750 * </tr>
751 751 * <tr>
752 752 * <td>
753 753 * .goog-date-picker .control-menu<br/>
754 754 * </td>
755 755 * <td>
756 756 * Month and year list available by clicking on them<br/>
757 757 * </td>
758 758 * </tr>
759 759 * <tr>
760 760 * <td>
761 761 * .goog-date-picker .control-block<br/>
762 762 * </td>
763 763 * <td>
764 764 * The block of month/year display with its
765 765 * increment decrement controls<br/>
766 766 * </td>
767 767 * </tr>
768 768 * <tr>
769 769 * <td>
770 770 * .goog-date-picker .control-pane<br/>
771 771 * </td>
772 772 * <td>
773 773 * Top area containing month and year controls<br/>
774 774 * </td>
775 775 * </tr>
776 776 * <tr>
777 777 * <td>
778 778 * .goog-date-picker .control-today<br/>
779 779 * </td>
780 780 * <td>
781 781 * Clickable today button<br/>
782 782 * </td>
783 783 * </tr>
784 784 * <tr>
785 785 * <td>
786 786 * .goog-date-picker .weekday<br/>
787 787 * </td>
788 788 * <td>
789 789 * Any date<br/>
790 790 * </td>
791 791 * </tr>
792 792 * <tr>
793 793 * <td>
794 794 * .goog-date-picker .week-names<br/>
795 795 * </td>
796 796 * <td>
797 797 * Weekday names<br/>
798 798 * </td>
799 799 * </tr>
800 800 * <tr>
801 801 * <td>
802 802 * .goog-date-picker .week-numbers<br/>
803 803 * </td>
804 804 * <td>
805 805 * Week of the year number<br/>
806 806 * </td>
807 807 * </tr>
808 808 * <tr>
809 809 * <td>
810 810 * .goog-date-picker .weekend-start<br/>
811 811 * </td>
812 812 * <td>
813 813 * Weekend startdate<br/>
814 814 * </td>
815 815 * </tr>
816 816 * <tr>
817 817 * <td>
818 818 * .goog-date-picker .weekend-end<br/>
819 819 * </td>
820 820 * <td>
821 821 * Weekend end date<br/>
822 822 * </td>
823 823 * </tr>
824 824 * <tr>
825 825 * <td>
826 826 * .goog-date-picker .today<br/>
827 827 * </td>
828 828 * <td>
829 829 * Special formatting for today
830 830 * </td>
831 831 * </tr>
832 832 * <tr>
833 833 * <td>
834 834 * .goog-date-picker .selected<br/>
835 835 * </td>
836 836 * <td>
837 837 * Special formatting for the selected date<br/>
838 838 * </td>
839 839 * </tr>
840 840 * <tr>
841 841 * <td>
842 842 * .goog-date-picker .other-month
843 843 * </td>
844 844 * <td>
845 845 * Opacity reducing formatting for the adjacent months<br/>
846 846 * </td>
847 847 * </tr>
848 848 * </tbody>
849 849 * </table>
850 850 * </p>
851 851 * <p>Following are the incomplete features.
852 852 * Some components of these features exist.
853 853 * However, they do not function completely.
854 854 * <ul>
855 855 * <li>Optional display week numbers</li>
856 856 * </ul>
857 857 * </p>
858 858 * <p>Desired features
859 859 * <ul>
860 860 * <li>Disable calendar functions beyond an end date.
861 861 * This is useful when document archives. Default today.</li>
862 862 * <li>Disable calendar functions beyond an start date.
863 863 * This is useful for reservation systems. Default today.</li>
864 864 * <li>Disable calendar functions on a specific date.
865 865 * This is useful for reservation systems.</li>
866 866 * <li>Right to Left layout depending on the page layout.</li>
867 867 * </ul>
868 868 * </p>
869 869 */
870 870 ChangeListener,
871 871 SourcesChangeEvents {
872 872 private static final String STYLE_DATE_PICKER = "goog-date-picker";
873 873 private static final String STYLE_GRID = "grid";
874 874 private static final String STYLE_CONTROL = "control";
875 875 private static final String STYLE_CONTROL_BLOCK = "control-block";
876 876 private static final String STYLE_CONTROL_PANE = "control-pane";
877 877 private static final String STYLE_CONTROL_MENU = "control-menu";
878 878 private static final String STYLE_CONTROL_TODAY = "control-today";
879 879 private static final String STYLE_TITLE = "title";
880 880 private static final String STYLE_WEEK_NAMES = "week-names";
881 881 private static final String STYLE_WEEK_NUMBERS = "numbers";
882 882 private static final String STYLE_WEEKDAY = "weekday";
883 883 private static final String STYLE_WEEKEND_START = "weekend-start";
884 884 private static final String STYLE_WEEKEND_END = "weekend-end";
885 885 private static final String STYLE_OTHER_MONTHS = "other-month";
886 886 private static final String STYLE_TODAY = "today";
887 887 private static final String STYLE_SELECTED = "selected";
888 888 // Unique numbers representing various actions available in the controls.
889 889 private static final int ACTION_PREV_MONTH = 0;
890 890 private static final int ACTION_SET_MONTH = 1;
891 891 private static final int ACTION_NEXT_MONTH = 2;
892 892 private static final int ACTION_PREV_YEAR = 3;
893 893 private static final int ACTION_SET_YEAR = 4;
894 894 private static final int ACTION_NEXT_YEAR = 5;
895 895 private static final int ACTION_TODAY = 6;
896 896 private static final int ACTION_CLOSE = 7;
897 897 // Unique numbers representing formating actions.
898 898 private static final int FORMAT_ACTION_REMOVE = 0;
899 899 private static final int FORMAT_ACTION_ADD = 1;
900 900 private LocaleCalendarUtils dateTable;
901 901 private ChangeListenerCollection changeListeners = new ChangeListenerCollection();
902 902 private HorizontalPanel control = new HorizontalPanel();
903 903 private FlexTable grid;
904 904 // menu based action
905 905 private int weekOfYearOffset = 0;
906 906 private boolean showYearMonthListing = true;
907 907 private boolean showTodayButton = false;
908 908 private int monthAction;
909 909 private int yearAction;
910 910 private DatePickerCell today;
911 911 private final VerticalPanel panel = new VerticalPanel();
912 912 private int prevMonthSize;
913 913 private int prevMonthDays;
914 914 private int currMonthSize;
915 915 private int nextMonthDays;
916 916 private int gridStart;
917 917 /**
918 918 * Constructor of the DatePicker class.
919 919 */
920 920 public DatePicker() {
921 921 super( true ); // hide dialogue box when clicked outside
922 922 dateTable = new LocaleCalendarUtils( false );
923 923 dateTable.specialDate( LocaleCalendarUtils.TODAY ).setTag( STYLE_TODAY );
924 924 dateTable.specialDate( LocaleCalendarUtils.SELECTED ).setTag( STYLE_SELECTED );
925 925 grid = new FlexTable();
926 926 grid.setWidth( "100%" );
927 927 grid.setStyleName( STYLE_GRID );
928 928 panel.addStyleName( STYLE_DATE_PICKER );
929 929 panel.setHorizontalAlignment( VerticalPanel.ALIGN_CENTER );
930 930 drawControlPane();
931 931 panel.add( control );
932 932 // grid operations
933 933 addDaysOfWeek();
934 934 initialGrid();
935 935 gridUpdate();
936 936 panel.add( grid );
937 937 // today label
938 938 today = dateTable.todayCell();
939 939 today.setValue( ACTION_TODAY );
940 940 today.addStyleName( STYLE_CONTROL_TODAY );
941 941 today.addClickListener( this );
942 942 enableTodayButton();
943 943 super.setWidget( panel );
944 944 }
945 945 /**
946 946 * Public method complete ClickListner interface. This adds a listener to the
947 947 * listeners for Change events. Namely, a date clicked by the user.
948 948 *
949 949 * @param listener - listener for events
950 950 */
951 951 public void addChangeListener( ChangeListener listener ) {
952 952 changeListeners.add( listener );
953 953 }
954 954 /**
955 955 * Public method onChange which is fired when user clicks on the
956 956 * list menu in the widget.
957 957 *
958 958 * @param sender - widget on which user clicked.
959 959 */
960 960 public void onChange( Widget sender ) {
961 961 if ( sender instanceof ListBox ) {
962 962 ListBox list = (ListBox) sender;
963 963 String val = list.getValue( list.getSelectedIndex() );
964 964 int ival = Integer.valueOf( val ).intValue();
965 965 if ( list == dateTable.monthNames() ) {
966 966 action( monthAction, ival );
967 967 } else {
968 968 action( yearAction, ival );
969 969 }
970 970 changeListeners.fireChange( this );
971 971 }
972 972 }
973 973 /**
974 974 * Public method onClick which is fired when user clicks on the widget.
975 975 *
976 976 * @param sender - widget on which user clicked.
977 977 */
978 978 public void onClick( Widget sender ) {
979 979 if ( sender instanceof DatePickerCell ) {
980 980 DatePickerCell cell = (DatePickerCell) sender;
981 981 int type = cell.type();
982 982 int value = cell.value();
983 983 if ( type == LocaleCalendarUtils.TYPE_CONTROL ) {
984 984 action( value );
985 985 } else {
986 986 formatSpecialDates( FORMAT_ACTION_REMOVE );
987 987 dateTable.selectedDate( type, value );
988 988 if ( type == LocaleCalendarUtils.TYPE_CURR_MONTH ) {
989 989 formatSpecialDates( FORMAT_ACTION_ADD );
990 990 } else {
991 991 gridUpdate();
992 992 }
993 993 }
994 994 changeListeners.fireChange( this );
995 995 }
996 996 }
997 997 /**
998 998 * Public method removeChangeListener() removes a element from the list of
999 999 * listeners which will get fired on an widget change event. Example for
1000 1000 * listener change event is user click on a date.
1001 1001 *
1002 1002 * @param listener - listener for widget change events
1003 1003 */
1004 1004 public void removeChangeListener( ChangeListener listener ) {
1005 1005 changeListeners.remove( listener );
1006 1006 }
1007 1007 /**
1008 1008 * Public method to get the value of the user selected date for the
1009 1009 * DatePicker object.
1010 1010 *
1011 1011 * @return Date - value of the selected date
1012 1012 */
1013 1013 public Date selectedDate() {
1014 1014 return dateTable;
1015 1015 }
1016 1016 /**
1017 1017 * Public method to set the default day and date of the widget.
1018 1018 * Date picker for the given month and year will be displayed.
1019 1019 * The given date will be marked as the selected date.
1020 1020 *
1021 1021 * @param date - Java Date value to be set
1022 1022 */
1023 1023 public void setFullDate( Date date ) {
1024 1024 formatSpecialDates( FORMAT_ACTION_REMOVE );
1025 1025 dateTable.setFullDate( date );
1026 1026 gridUpdate();
1027 1027 }
1028 1028 /**
1029 1029 * Public method to set a given special formatting for the given date.
1030 1030 *
1031 1031 * @param date - Date to be formatted specially
1032 1032 * @param style - CSS style to be used
1033 1033 */
1034 1034 public void setSpecialDate( Date date, String style ) {
1035 1035 DatePickerDate specialDay = dateTable.addSpecialDay( date );
1036 1036 specialDay.setTag( style );
1037 1037 formatSpecialDates( FORMAT_ACTION_ADD );
1038 1038 }
1039 1039 /**
1040 1040 * Public method to enable or disable displaying the trailing
1041 1041 * and leading dates from previous and next months.
1042 1042 *
1043 1043 * @param show - A boolean indicating whether to show or not
1044 1044 */
1045 1045 public void showAdjacentMonths( boolean show ) {
1046 1046 dateTable.enableAdjacentMonths( show );
1047 1047 gridUpdate();
1048 1048 }
1049 1049 /**
1050 1050 * Public method to display the listing of adjacent months and years by
1051 1051 * clicking on the month or year in the title.
1052 1052 *
1053 1053 * @param show - A boolean indicating whether to show or not
1054 1054 */
1055 1055 public void showTodayButton( boolean show ) {
1056 1056 this.showTodayButton = show;
1057 1057 enableTodayButton();
1058 1058 }
1059 1059 /**
1060 1060 * Public method to enable or disable displaying the week number of the year.
1061 1061 * (implementation not completed)
1062 1062 *
1063 1063 * @param show - A boolean indicating whether to show or not
1064 1064 */
1065 1065 public void showWeekOfYear( boolean show ) {
1066 1066 this.weekOfYearOffset = show ? 1 : 0;
1067 1067 gridUpdate();
1068 1068 }
1069 1069 /**
1070 1070 * Public method to display the listing of adjacent months and years by
1071 1071 * clicking on the month or year in the title.
1072 1072 *
1073 1073 * @param show - A boolean indicating whether to show or not
1074 1074 */
1075 1075 public void showYearMonthListing( boolean show ) {
1076 1076 this.showYearMonthListing = show;
1077 1077 drawControlPane();
1078 1078 }
1079 1079 private void action( int actionNum, int arg ) {
1080 1080 formatSpecialDates( FORMAT_ACTION_REMOVE );
1081 1081 switch ( actionNum ) {
1082 1082 case ACTION_SET_MONTH:
1083 1083 dateTable.setMonth( arg );
1084 1084 break;
1085 1085 case ACTION_SET_YEAR:
1086 1086 dateTable.setYear( arg );
1087 1087 break;
1088 1088 }
1089 1089 gridUpdate();
1090 1090 }
1091 1091 private void action( int actionNum ) {
1092 1092 if ( actionNum == ACTION_CLOSE ) {
1093 1093 this.hide();
1094 1094 } else {
1095 1095 formatSpecialDates( FORMAT_ACTION_REMOVE );
1096 1096 switch ( actionNum ) {
1097 1097 case ACTION_PREV_MONTH:
1098 1098 dateTable.addMonths( -1 );
1099 1099 break;
1100 1100 case ACTION_NEXT_MONTH:
1101 1101 dateTable.addMonths( 1 );
1102 1102 break;
1103 1103 case ACTION_PREV_YEAR:
1104 1104 dateTable.addMonths( -12 );
1105 1105 break;
1106 1106 case ACTION_NEXT_YEAR:
1107 1107 dateTable.addMonths( 12 );
1108 1108 break;
1109 1109 case ACTION_TODAY:
1110 1110 dateTable.setToday();
1111 1111 break;
1112 1112 }
1113 1113 gridUpdate();
1114 1114 }
1115 1115 }
1116 1116 private void addDaysOfWeek() {
1117 1117 String[] dayOfWeekNames = LocaleCalendarUtils.dayOfWeekNames();
1118 1118 for ( int col = 0; col < 7; col++ ) {
1119 1119 int dayOfWeek = (col + dateTable.weekStart()) % 7;
1120 1120 grid.setText( 0, col + weekOfYearOffset, dayOfWeekNames[dayOfWeek] );
1121 1121 grid.getCellFormatter().setStyleName( 0, col + weekOfYearOffset, STYLE_WEEK_NAMES );
1122 1122 }
1123 1123 }
1124 1124 private void addWeekOfYear() {
1125 1125 String[] weekOfYear = dateTable.weekOfYear();
1126 1126 for ( int row = 0; row < 7; row++ ) {
1127 1127 grid.setText( row + 1, 0, weekOfYear[row] );
1128 1128 grid.getCellFormatter().addStyleName( row + 1, 0, STYLE_WEEK_NUMBERS );
1129 1129 }
1130 1130 }
1131 1131 private void colFormat( int tableRow, int tableCol, int weekendStart, int weekendEnd, DatePickerCell w ) {
1132 1132 String style;
1133 1133 if ( tableCol == (weekendStart + weekOfYearOffset) ) {
1134 1134 style = STYLE_WEEKEND_START;
1135 1135 } else if ( tableCol == (weekendEnd + weekOfYearOffset) ) {
1136 1136 style = STYLE_WEEKEND_END;
1137 1137 } else {
1138 1138 style = STYLE_WEEKDAY;
1139 1139 }
1140 1140 w.setStyleName( style );
1141 1141 grid.getCellFormatter().addStyleName( tableRow, tableCol, style );
1142 1142 }
1143 1143 private void dateFormat( int diffFromMonthStart, String style, int action ) {
1144 1144 if ( diffFromMonthStart < -prevMonthDays || diffFromMonthStart >= currMonthSize + nextMonthDays ) {
1145 1145 return;
1146 1146 }
1147 1147 int i = diffFromMonthStart + prevMonthDays + gridStart;
1148 1148 int row = i / 7;
1149 1149 int col = i % 7;
1150 1150 int tableRow = row + 1;
1151 1151 int tableCol = col + weekOfYearOffset;
1152 1152 switch ( action ) {
1153 1153 case FORMAT_ACTION_REMOVE:
1154 1154 grid.getCellFormatter().removeStyleName( tableRow, tableCol, style );
1155 1155 grid.getWidget( tableRow, tableCol ).removeStyleName( style );
1156 1156 break;
1157 1157 case FORMAT_ACTION_ADD:
1158 1158 grid.getCellFormatter().addStyleName( tableRow, tableCol, style );
1159 1159 grid.getWidget( tableRow, tableCol ).addStyleName( style );
1160 1160 break;
1161 1161 }
1162 1162 }
1163 1163 private void drawControlPane() {
1164 1164 control.clear();
1165 1165 control.setWidth( "100%" );
1166 1166 control.setHorizontalAlignment( HorizontalPanel.ALIGN_CENTER );
1167 1167 control.addStyleName( STYLE_CONTROL_PANE );
1168 1168 Widget yearControl = drawControls( dateTable.yearNames(), dateTable.yearName(), ACTION_PREV_YEAR, ACTION_NEXT_YEAR, ACTION_SET_YEAR );
1169 1169 Widget monthControl = drawControls( dateTable.monthNames(), dateTable.monthName(), ACTION_PREV_MONTH, ACTION_NEXT_MONTH, ACTION_SET_MONTH );
1170 1170 if ( dateTable.isYearBeforeMonth() ) {
1171 1171 control.add( yearControl );
1172 1172 control.add( monthControl );
1173 1173 } else {
1174 1174 control.add( monthControl );
1175 1175 control.add( yearControl );
1176 1176 }
1177 1177 }
1178 1178 private Widget drawControls( ListBox names, Label name, int prev, int next, int set ) {
1179 1179 HorizontalPanel hp = new HorizontalPanel();
1180 1180 hp.setHorizontalAlignment( HorizontalPanel.ALIGN_CENTER );
1181 1181 hp.addStyleName( STYLE_CONTROL_BLOCK );
1182 1182 if ( names == dateTable.monthNames() ) {
1183 1183 monthAction = set;
1184 1184 } else {
1185 1185 yearAction = set;
1186 1186 }
1187 1187 // move left
1188 1188 if ( !showYearMonthListing || set == ACTION_SET_MONTH ) {
1189 1189 DatePickerCell left = new DatePickerCell( "\u00ab" ); // \u00ab is <<
1190 1190 left.setType( LocaleCalendarUtils.TYPE_CONTROL );
1191 1191 left.setValue( prev );
1192 1192 left.addStyleName( STYLE_CONTROL );
1193 1193 left.addClickListener( this );
1194 1194 hp.add( left );
1195 1195 }
1196 1196 // Need list box or not
1197 1197 if ( showYearMonthListing ) {
1198 1198 names.setVisibleItemCount( 1 );
1199 1199 names.addStyleName( STYLE_CONTROL_MENU );
1200 1200 names.addChangeListener( this );
1201 1201 hp.add( names );
1202 1202 } else {
1203 1203 name.addStyleName( STYLE_TITLE );
1204 1204 hp.add( name );
1205 1205 }
1206 1206 // move right
1207 1207 if ( !showYearMonthListing || set == ACTION_SET_MONTH ) {
1208 1208 DatePickerCell right = new DatePickerCell( "\u00bb" ); // \u00ab is >>
1209 1209 right.setType( LocaleCalendarUtils.TYPE_CONTROL );
1210 1210 right.setValue( next );
1211 1211 right.addStyleName( STYLE_CONTROL );
1212 1212 right.addClickListener( this );
1213 1213 hp.add( right );
1214 1214 }
1215 1215 return hp;
1216 1216 }
1217 1217 private void enableTodayButton() {
1218 1218 if ( showTodayButton ) {
1219 1219 panel.add( today );
1220 1220 } else {
1221 1221 panel.remove( today );
1222 1222 }
1223 1223 }
1224 1224 private void formatSpecialDates( int action ) {
1225 1225 int numSpecialDays = dateTable.numSpecialDays();
1226 1226 for ( int i = 0; i < numSpecialDays; i++ ) {
1227 1227 DatePickerDate date = dateTable.specialDate( i );
1228 1228 dateFormat( date.dayDiff(), date.tag(), action );
1229 1229 }
1230 1230 }
1231 1231 private void gridUpdate() {
1232 1232 DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();
1233 1233 DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
1234 1234 DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();
1235 1235 prevMonthSize = dateTable.prevMonthSize();
1236 1236 prevMonthDays = dateTable.prevMonthDays();
1237 1237 currMonthSize = dateTable.currMonthSize();
1238 1238 nextMonthDays = dateTable.nextMonthDays();
1239 1239 gridStart = dateTable.gridStart();
1240 1240 int weekendStart = dateTable.weekendStart();
1241 1241 int weekendEnd = dateTable.weekendEnd();
1242 1242 if ( weekOfYearOffset > 0 ) {
1243 1243 addWeekOfYear();
1244 1244 }
1245 1245 int rowCount = grid.getRowCount();
1246 1246 for ( int i = rowCount - 1; i > 0; i-- ) { // 0th row is the week names
1247 1247 grid.removeRow( i );
1248 1248 }
1249 1249 for ( int i = 0; i < prevMonthDays; i++ ) {
1250 1250 int row = i / 7;
1251 1251 int col = i % 7;
1252 1252 int tableRow = row + 1;
1253 1253 int tableCol = col + weekOfYearOffset;
1254 1254 int dayOfMonth = prevMonthSize - prevMonthDays + i; // 0 based
1255 1255 colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNamesPrev[dayOfMonth] );
1256 1256 grid.setWidget( tableRow, tableCol, dayOfMonthNamesPrev[dayOfMonth] );
1257 1257 grid.getCellFormatter().addStyleName( tableRow, tableCol, STYLE_OTHER_MONTHS );
1258 1258 }
1259 1259 for ( int i = 0; i < currMonthSize; i++ ) {
1260 1260 int row = (gridStart + prevMonthDays + i) / 7;
1261 1261 int col = (gridStart + prevMonthDays + i) % 7;
1262 1262 int tableRow = row + 1;
1263 1263 int tableCol = col + weekOfYearOffset;
1264 1264 colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNames[i] );
1265 1265 grid.setWidget( tableRow, tableCol, dayOfMonthNames[i] );
1266 1266 }
1267 1267 for ( int i = 0; i < nextMonthDays; i++ ) {
1268 1268 int row = (currMonthSize + prevMonthDays + i) / 7;
1269 1269 int col = (currMonthSize + prevMonthDays + i) % 7;
1270 1270 int tableRow = row + 1;
1271 1271 int tableCol = col + weekOfYearOffset;
1272 1272 colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNamesNext[i] );
1273 1273 grid.setWidget( tableRow, tableCol, dayOfMonthNamesNext[i] );
1274 1274 grid.getCellFormatter().addStyleName( tableRow, tableCol, STYLE_OTHER_MONTHS );
1275 1275 }
1276 1276 formatSpecialDates( FORMAT_ACTION_ADD );
1277 1277 }
1278 1278 private void initialGrid() {
1279 1279 DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
1280 1280 DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();
1281 1281 DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();
1282 1282 for ( int i = 0; i < 31; i++ ) {
1283 1283 dayOfMonthNamesPrev[i].addClickListener( this );
1284 1284 dayOfMonthNamesNext[i].addClickListener( this );
1285 1285 dayOfMonthNames[i].addClickListener( this );
1286 1286 }
1287 1287 }