Subversion Repository Public Repository

litesoft

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

Diff revisions: vs.
  @@ -1 +1 @@
1 - /*
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 *
653 653 * <p>It has following features:
654 654 *
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 private static final String STYLE_DATE_PICKER = "goog-date-picker";
827 827 private static final String STYLE_GRID = "grid";
828 828 private static final String STYLE_CONTROL = "control";
829 829 private static final String STYLE_CONTROL_BLOCK = "control-block";
830 830 private static final String STYLE_CONTROL_PANE = "control-pane";
831 831 private static final String STYLE_CONTROL_MENU = "control-menu";
832 832 private static final String STYLE_CONTROL_TODAY = "control-today";
833 833 private static final String STYLE_TITLE = "title";
834 834 private static final String STYLE_WEEK_NAMES = "week-names";
835 835 private static final String STYLE_WEEK_NUMBERS = "numbers";
836 836 private static final String STYLE_WEEKDAY = "weekday";
837 837 private static final String STYLE_WEEKEND_START = "weekend-start";
838 838 private static final String STYLE_WEEKEND_END = "weekend-end";
839 839 private static final String STYLE_OTHER_MONTHS = "other-month";
840 840 private static final String STYLE_TODAY = "today";
841 841 private static final String STYLE_SELECTED = "selected";
842 842 // Unique numbers representing various actions available in the controls.
843 843 private static final int ACTION_PREV_MONTH = 0;
844 844 private static final int ACTION_SET_MONTH = 1;
845 845 private static final int ACTION_NEXT_MONTH = 2;
846 846 private static final int ACTION_PREV_YEAR = 3;
847 847 private static final int ACTION_SET_YEAR = 4;
848 848 private static final int ACTION_NEXT_YEAR = 5;
849 849 private static final int ACTION_TODAY = 6;
850 850 private static final int ACTION_CLOSE = 7;
851 851 // Unique numbers representing formating actions.
852 852 private static final int FORMAT_ACTION_REMOVE = 0;
853 853 private static final int FORMAT_ACTION_ADD = 1;
854 854 private LocaleCalendarUtils dateTable;
855 855 private ChangeListenerCollection changeListeners
856 856 = new ChangeListenerCollection();
857 857 private HorizontalPanel control = new HorizontalPanel();
858 858 private FlexTable grid;
859 859 // menu based action
860 860 private int weekOfYearOffset = 0;
861 861 private boolean showYearMonthListing = true;
862 862 private boolean showTodayButton = false;
863 863 private int monthAction;
864 864 private int yearAction;
865 865 private DatePickerCell today;
866 866 private final VerticalPanel panel = new VerticalPanel();
867 867 private int prevMonthSize;
868 868 private int prevMonthDays;
869 869 private int currMonthSize;
870 870 private int nextMonthDays;
871 871 private int gridStart;
872 872 /**
873 873 * Constructor of the DatePicker class.
874 874 *
875 875 */
876 876 public DatePicker() {
877 877 super(true); // hide dialogue box when clicked outside
878 878 dateTable = new LocaleCalendarUtils(false);
879 879 dateTable.specialDate(LocaleCalendarUtils.TODAY).setTag(STYLE_TODAY);
880 880 dateTable.specialDate(LocaleCalendarUtils.SELECTED).setTag(STYLE_SELECTED);
881 881 grid = new FlexTable();
882 882 grid.setWidth("100%");
883 883 grid.setStyleName(STYLE_GRID);
884 884 panel.addStyleName(STYLE_DATE_PICKER);
885 885 panel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
886 886 drawControlPane();
887 887 panel.add(control);
888 888 // grid operations
889 889 addDaysOfWeek();
890 890 initialGrid();
891 891 gridUpdate();
892 892 panel.add(grid);
893 893 // today label
894 894 today = dateTable.todayCell();
895 895 today.setValue(ACTION_TODAY);
896 896 today.addStyleName(STYLE_CONTROL_TODAY);
897 897 today.addClickListener(this);
898 898 enableTodayButton();
899 899 super.setWidget(panel);
900 900 }
901 901 /**
902 902 * Public method complete ClickListner interface. This adds a listener to the
903 903 * listeners for Change events. Namely, a date clicked by the user.
904 904 *
905 905 * @param listener - listener for events
906 906 */
907 907 public void addChangeListener(ChangeListener listener) {
908 908 changeListeners.add(listener);
909 909 }
910 910 /**
911 911 * Public method onChange which is fired when user clicks on the
912 912 * list menu in the widget.
913 913 * @param sender - widget on which user clicked.
914 914 *
915 915 */
916 916 public void onChange(Widget sender) {
917 917 if (sender instanceof ListBox) {
918 918 ListBox list = (ListBox)sender;
919 919 String val = list.getValue(list.getSelectedIndex());
920 920 int ival = Integer.valueOf( val ).intValue();
921 921 if (list == dateTable.monthNames()) {
922 922 action(monthAction, ival);
923 923 } else {
924 924 action(yearAction, ival);
925 925 }
926 926 changeListeners.fireChange(this);
927 927 }
928 928 }
929 929 /**
930 930 * Public method onClick which is fired when user clicks on the widget.
931 931 * @param sender - widget on which user clicked.
932 932 *
933 933 */
934 934 public void onClick(Widget sender) {
935 935 if (sender instanceof DatePickerCell) {
936 936 DatePickerCell cell = (DatePickerCell)sender;
937 937 int type = cell.type();
938 938 int value = cell.value();
939 939 if (type == LocaleCalendarUtils.TYPE_CONTROL) {
940 940 action(value);
941 941 } else {
942 942 formatSpecialDates(FORMAT_ACTION_REMOVE);
943 943 dateTable.selectedDate(type, value);
944 944 if (type == LocaleCalendarUtils.TYPE_CURR_MONTH) {
945 945 formatSpecialDates(FORMAT_ACTION_ADD);
946 946 } else {
947 947 gridUpdate();
948 948 }
949 949 }
950 950 changeListeners.fireChange(this);
951 951 }
952 952 }
953 953 /**
954 954 * Public method removeChangeListener() removes a element from the list of
955 955 * listeners which will get fired on an widget change event. Example for
956 956 * listener change event is user click on a date.
957 957 *
958 958 * @param listener - listener for widget change events
959 959 *
960 960 */
961 961 public void removeChangeListener(ChangeListener listener) {
962 962 changeListeners.remove(listener);
963 963 }
964 964 /**
965 965 * Public method to get the value of the user selected date for the
966 966 * DatePicker object.
967 967 *
968 968 * @return Date - value of the selected date
969 969 */
970 970 public Date selectedDate() {
971 971 return dateTable;
972 972 }
973 973 /**
974 974 * Public method to set the default day and date of the widget.
975 975 * Date picker for the given month and year will be displayed.
976 976 * The given date will be marked as the selected date.
977 977 *
978 978 * @param date - Java Date value to be set
979 979 */
980 980 public void setFullDate(Date date) {
981 981 formatSpecialDates(FORMAT_ACTION_REMOVE);
982 982 dateTable.setFullDate(date);
983 983 gridUpdate();
984 984 }
985 985 /**
986 986 * Public method to set a given special formatting for the given date.
987 987 *
988 988 * @param date - Date to be formatted specially
989 989 * @param style - CSS style to be used
990 990 */
991 991 public void setSpecialDate(Date date, String style) {
992 992 DatePickerDate specialDay = dateTable.addSpecialDay(date);
993 993 specialDay.setTag(style);
994 994 formatSpecialDates(FORMAT_ACTION_ADD);
995 995 }
996 996 /**
997 997 * Public method to enable or disable displaying the trailing
998 998 * and leading dates from previous and next months.
999 999 *
1000 1000 * @param show - A boolean indicating whether to show or not
1001 1001 *
1002 1002 */
1003 1003 public void showAdjacentMonths(boolean show) {
1004 1004 dateTable.enableAdjacentMonths(show);
1005 1005 gridUpdate();
1006 1006 }
1007 1007 /**
1008 1008 * Public method to display the listing of adjacent months and years by
1009 1009 * clicking on the month or year in the title.
1010 1010 *
1011 1011 * @param show - A boolean indicating whether to show or not
1012 1012 *
1013 1013 */
1014 1014 public void showTodayButton(boolean show) {
1015 1015 this.showTodayButton = show;
1016 1016 enableTodayButton();
1017 1017 }
1018 1018 /**
1019 1019 * Public method to enable or disable displaying the week number of the year.
1020 1020 * (implementation not completed)
1021 1021 *
1022 1022 * @param show - A boolean indicating whether to show or not
1023 1023 *
1024 1024 */
1025 1025 public void showWeekOfYear(boolean show) {
1026 1026 this.weekOfYearOffset = show ? 1 : 0;
1027 1027 gridUpdate();
1028 1028 }
1029 1029 /**
1030 1030 * Public method to display the listing of adjacent months and years by
1031 1031 * clicking on the month or year in the title.
1032 1032 *
1033 1033 * @param show - A boolean indicating whether to show or not
1034 1034 *
1035 1035 */
1036 1036 public void showYearMonthListing(boolean show) {
1037 1037 this.showYearMonthListing = show;
1038 1038 drawControlPane();
1039 1039 }
1040 1040 private void action(int actionNum, int arg) {
1041 1041 formatSpecialDates(FORMAT_ACTION_REMOVE);
1042 1042 switch(actionNum) {
1043 1043 case ACTION_SET_MONTH:
1044 1044 dateTable.setMonth(arg);
1045 1045 break;
1046 1046 case ACTION_SET_YEAR:
1047 1047 dateTable.setYear(arg);
1048 1048 break;
1049 1049 }
1050 1050 gridUpdate();
1051 1051 }
1052 1052 private void action(int actionNum) {
1053 1053 if (actionNum == ACTION_CLOSE) {
1054 1054 this.hide();
1055 1055 } else {
1056 1056 formatSpecialDates(FORMAT_ACTION_REMOVE);
1057 1057 switch(actionNum) {
1058 1058 case ACTION_PREV_MONTH:
1059 1059 dateTable.addMonths(-1);
1060 1060 break;
1061 1061 case ACTION_NEXT_MONTH:
1062 1062 dateTable.addMonths(1);
1063 1063 break;
1064 1064 case ACTION_PREV_YEAR:
1065 1065 dateTable.addMonths(-12);
1066 1066 break;
1067 1067 case ACTION_NEXT_YEAR:
1068 1068 dateTable.addMonths(12);
1069 1069 break;
1070 1070 case ACTION_TODAY:
1071 1071 dateTable.setToday();
1072 1072 break;
1073 1073 }
1074 1074 gridUpdate();
1075 1075 }
1076 1076 }
1077 1077 private void addDaysOfWeek() {
1078 1078 String[] dayOfWeekNames = LocaleCalendarUtils.dayOfWeekNames();
1079 1079 for (int col = 0; col < 7; col++) {
1080 1080 int dayOfWeek = (col + dateTable.weekStart()) % 7;
1081 1081 grid.setText(0, col + weekOfYearOffset, dayOfWeekNames[dayOfWeek]);
1082 1082 grid.getCellFormatter().setStyleName(0, col + weekOfYearOffset,
1083 1083 STYLE_WEEK_NAMES);
1084 1084 }
1085 1085 }
1086 1086 private void addWeekOfYear() {
1087 1087 String[] weekOfYear = dateTable.weekOfYear();
1088 1088 for (int row = 0; row < 7; row++) {
1089 1089 grid.setText(row + 1, 0, weekOfYear[row]);
1090 1090 grid.getCellFormatter().addStyleName(row + 1, 0, STYLE_WEEK_NUMBERS);
1091 1091 }
1092 1092 }
1093 1093 private void colFormat(int tableRow,
1094 1094 int tableCol,
1095 1095 int weekendStart,
1096 1096 int weekendEnd,
1097 1097 DatePickerCell w) {
1098 1098 String style;
1099 1099 if (tableCol == (weekendStart + weekOfYearOffset)) {
1100 1100 style = STYLE_WEEKEND_START;
1101 1101 } else if (tableCol == (weekendEnd + weekOfYearOffset)) {
1102 1102 style = STYLE_WEEKEND_END;
1103 1103 } else {
1104 1104 style = STYLE_WEEKDAY;
1105 1105 }
1106 1106 w.setStyleName(style);
1107 1107 grid.getCellFormatter().addStyleName(tableRow, tableCol, style);
1108 1108 }
1109 1109 private void dateFormat(int diffFromMonthStart, String style, int action) {
1110 1110 if ( diffFromMonthStart < -prevMonthDays
1111 1111 || diffFromMonthStart >= currMonthSize + nextMonthDays ) {
1112 1112 return;
1113 1113 }
1114 1114 int i = diffFromMonthStart + prevMonthDays + gridStart;
1115 1115 int row = i / 7;
1116 1116 int col = i % 7;
1117 1117 int tableRow = row + 1;
1118 1118 int tableCol = col + weekOfYearOffset;
1119 1119 switch(action) {
1120 1120 case FORMAT_ACTION_REMOVE:
1121 1121 grid.getCellFormatter().removeStyleName(tableRow, tableCol, style);
1122 1122 grid.getWidget(tableRow, tableCol).removeStyleName(style);
1123 1123 break;
1124 1124 case FORMAT_ACTION_ADD:
1125 1125 grid.getCellFormatter().addStyleName(tableRow, tableCol, style);
1126 1126 grid.getWidget(tableRow, tableCol).addStyleName(style);
1127 1127 break;
1128 1128 }
1129 1129 }
1130 1130 private void drawControlPane() {
1131 1131 control.clear();
1132 1132 control.setWidth("100%");
1133 1133 control.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
1134 1134 control.addStyleName(STYLE_CONTROL_PANE);
1135 1135 Widget yearControl = drawControls(dateTable.yearNames(),
1136 1136 dateTable.yearName(),
1137 1137 ACTION_PREV_YEAR,
1138 1138 ACTION_NEXT_YEAR,
1139 1139 ACTION_SET_YEAR );
1140 1140 Widget monthControl = drawControls(dateTable.monthNames(),
1141 1141 dateTable.monthName(),
1142 1142 ACTION_PREV_MONTH,
1143 1143 ACTION_NEXT_MONTH,
1144 1144 ACTION_SET_MONTH );
1145 1145 if (dateTable.isYearBeforeMonth()) {
1146 1146 control.add(yearControl);
1147 1147 control.add(monthControl);
1148 1148 } else {
1149 1149 control.add(monthControl);
1150 1150 control.add(yearControl);
1151 1151 }
1152 1152 }
1153 1153 private Widget drawControls( ListBox names, Label name,
1154 1154 int prev, int next, int set ) {
1155 1155 HorizontalPanel hp = new HorizontalPanel();
1156 1156 hp.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
1157 1157 hp.addStyleName(STYLE_CONTROL_BLOCK);
1158 1158 if (names == dateTable.monthNames()) {
1159 1159 monthAction = set;
1160 1160 } else {
1161 1161 yearAction = set;
1162 1162 }
1163 1163 // move left
1164 1164 if (!showYearMonthListing || set == ACTION_SET_MONTH) {
1165 1165 DatePickerCell left = new DatePickerCell("\u00ab"); // \u00ab is <<
1166 1166 left.setType(LocaleCalendarUtils.TYPE_CONTROL);
1167 1167 left.setValue(prev);
1168 1168 left.addStyleName(STYLE_CONTROL);
1169 1169 left.addClickListener(this);
1170 1170 hp.add(left);
1171 1171 }
1172 1172 // Need list box or not
1173 1173 if (showYearMonthListing) {
1174 1174 names.setVisibleItemCount(1);
1175 1175 names.addStyleName(STYLE_CONTROL_MENU);
1176 1176 names.addChangeListener(this);
1177 1177 hp.add(names);
1178 1178 } else {
1179 1179 name.addStyleName(STYLE_TITLE);
1180 1180 hp.add(name);
1181 1181 }
1182 1182 // move right
1183 1183 if (!showYearMonthListing || set == ACTION_SET_MONTH) {
1184 1184 DatePickerCell right = new DatePickerCell("\u00bb"); // \u00ab is >>
1185 1185 right.setType(LocaleCalendarUtils.TYPE_CONTROL);
1186 1186 right.setValue(next);
1187 1187 right.addStyleName(STYLE_CONTROL);
1188 1188 right.addClickListener(this);
1189 1189 hp.add(right);
1190 1190 }
1191 1191 return hp;
1192 1192 }
1193 1193 private void enableTodayButton () {
1194 1194 if (showTodayButton) {
1195 1195 panel.add(today);
1196 1196 } else {
1197 1197 panel.remove(today);
1198 1198 }
1199 1199 }
1200 1200 private void formatSpecialDates(int action) {
1201 1201 int numSpecialDays = dateTable.numSpecialDays();
1202 1202 for (int i = 0; i < numSpecialDays; i++) {
1203 1203 DatePickerDate date = dateTable.specialDate(i);
1204 1204 dateFormat(date.dayDiff(), date.tag(), action);
1205 1205 }
1206 1206 }
1207 1207 private void gridUpdate() {
1208 1208 DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();
1209 1209 DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
1210 1210 DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();
1211 1211 prevMonthSize = dateTable.prevMonthSize();
1212 1212 prevMonthDays = dateTable.prevMonthDays();
1213 1213 currMonthSize = dateTable.currMonthSize();
1214 1214 nextMonthDays = dateTable.nextMonthDays();
1215 1215 gridStart = dateTable.gridStart();
1216 1216 int weekendStart = dateTable.weekendStart();
1217 1217 int weekendEnd = dateTable.weekendEnd();
1218 1218 if (weekOfYearOffset > 0) {
1219 1219 addWeekOfYear();
1220 1220 }
1221 1221 int rowCount = grid.getRowCount();
1222 1222 for (int i = rowCount - 1; i > 0; i--) { // 0th row is the week names
1223 1223 grid.removeRow(i);
1224 1224 }
1225 1225 for (int i = 0; i < prevMonthDays; i++) {
1226 1226 int row = i / 7;
1227 1227 int col = i % 7;
1228 1228 int tableRow = row + 1;
1229 1229 int tableCol = col + weekOfYearOffset;
1230 1230 int dayOfMonth = prevMonthSize - prevMonthDays + i; // 0 based
1231 1231 colFormat(tableRow, tableCol,
1232 1232 weekendStart, weekendEnd,
1233 1233 dayOfMonthNamesPrev[dayOfMonth]);
1234 1234 grid.setWidget(tableRow, tableCol, dayOfMonthNamesPrev[dayOfMonth]);
1235 1235 grid.getCellFormatter().addStyleName(tableRow, tableCol,
1236 1236 STYLE_OTHER_MONTHS);
1237 1237 }
1238 1238 for (int i = 0; i < currMonthSize; i++) {
1239 1239 int row = (gridStart + prevMonthDays + i) / 7;
1240 1240 int col = (gridStart + prevMonthDays + i) % 7;
1241 1241 int tableRow = row + 1;
1242 1242 int tableCol = col + weekOfYearOffset;
1243 1243 colFormat(tableRow, tableCol, weekendStart, weekendEnd,
1244 1244 dayOfMonthNames[i]);
1245 1245 grid.setWidget(tableRow, tableCol, dayOfMonthNames[i]);
1246 1246 }
1247 1247 for (int i = 0; i < nextMonthDays; i++) {
1248 1248 int row = (currMonthSize + prevMonthDays + i) / 7;
1249 1249 int col = (currMonthSize + prevMonthDays + i) % 7;
1250 1250 int tableRow = row + 1;
1251 1251 int tableCol = col + weekOfYearOffset;
1252 1252 colFormat(tableRow, tableCol, weekendStart, weekendEnd,
1253 1253 dayOfMonthNamesNext[i]);
1254 1254 grid.setWidget(tableRow, tableCol, dayOfMonthNamesNext[i]);
1255 1255 grid.getCellFormatter().addStyleName(tableRow, tableCol,
1256 1256 STYLE_OTHER_MONTHS);
1257 1257 }
1258 1258 formatSpecialDates(FORMAT_ACTION_ADD);
1259 1259 }
1260 1260 private void initialGrid() {
1261 1261 DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
1262 1262 DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();
1263 1263 DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();
1264 1264 for (int i = 0; i < 31; i++) {
1265 1265 dayOfMonthNamesPrev[i].addClickListener(this);
1266 1266 dayOfMonthNamesNext[i].addClickListener(this);
1267 1267 dayOfMonthNames[i].addClickListener(this);
1268 1268 }
1269 1269 }