Subversion Repository Public Repository

litesoft

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