Subversion Repository Public Repository

litesoft

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

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