/ftr-gwt-library-date/src/main/java/eu/future/earth/gwt/client/date/weeklist/WeekListPanel.java
Java | 647 lines | 525 code | 94 blank | 28 comment | 68 complexity | ebe7df3b546e17b4b16b1216cd952e77 MD5 | raw file
Possible License(s): Apache-2.0
1/* 2 * Copyright 2007 Future Earth, info@future-earth.eu 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package eu.future.earth.gwt.client.date.weeklist; 18 19import java.util.ArrayList; 20import java.util.Calendar; 21import java.util.Date; 22import java.util.GregorianCalendar; 23import java.util.List; 24 25import org.cobogw.gwt.user.client.CSS; 26 27import com.allen_sauer.gwt.dnd.client.drop.AbstractDropController; 28import com.google.gwt.core.client.GWT; 29import com.google.gwt.event.shared.HandlerRegistration; 30import com.google.gwt.user.client.DOM; 31import com.google.gwt.user.client.ui.AbsolutePanel; 32import com.google.gwt.user.client.ui.Grid; 33import com.google.gwt.user.client.ui.HTML; 34import com.google.gwt.user.client.ui.HorizontalPanel; 35import com.google.gwt.user.client.ui.ScrollPanel; 36import com.google.gwt.user.client.ui.VerticalPanel; 37 38import eu.future.earth.gwt.client.FtrGwtDateCss; 39import eu.future.earth.gwt.client.date.DateEvent; 40import eu.future.earth.gwt.client.date.DateEvent.DateEventActions; 41import eu.future.earth.gwt.client.date.DateEventListener; 42import eu.future.earth.gwt.client.date.DatePanel; 43import eu.future.earth.gwt.client.date.DateRenderer; 44import eu.future.earth.gwt.client.date.DateUtils; 45import eu.future.earth.gwt.client.date.EventPanel; 46import eu.future.earth.gwt.client.date.HasDateEventHandlers; 47import eu.future.earth.gwt.client.date.PanelType; 48import eu.future.earth.gwt.client.date.week.DayEventElement; 49import eu.future.earth.gwt.client.date.week.DayHeader; 50import eu.future.earth.gwt.client.date.week.whole.DayEventpanel; 51import eu.future.earth.gwt.client.date.week.whole.DayPanelParent; 52import eu.future.earth.gwt.client.date.week.whole.WholeDayDragController; 53import eu.future.earth.gwt.client.date.week.whole.WholeDayPanelDropController; 54 55public class WeekListPanel<T> extends VerticalPanel implements DateEventListener<T>, DatePanel<T>, HasDateEventHandlers<T>, DayPanelParent<T> { 56 57 private AbsolutePanel wholeDayDragPanel = new AbsolutePanel(); 58 59 private WholeDayDragController wholeDayDragController = null; 60 61 private List<AbstractDropController> dropControllers = new ArrayList<AbstractDropController>(); 62 63 private ArrayList<DayEventElement<T>> dayList = new ArrayList<DayEventElement<T>>(); 64 65 private HorizontalPanel headerPanel = new HorizontalPanel(); 66 67 private VerticalPanel topPanelDays = new VerticalPanel(); 68 69 private Grid labels = new Grid(); 70 71 private Grid dayEvents = new Grid(); 72 73 // private Grid mainPanel = new Grid(1, 2); 74 75 private Grid daysGrid = new Grid(); 76 77 private WeekListPanelDragController weekDragController = null; 78 79 private AbsolutePanel dragPanel = new AbsolutePanel(); 80 81 private ScrollPanel scroller = new ScrollPanel(dragPanel); 82 83 private Calendar current = new GregorianCalendar(); 84 85 private int daysShown = 7; 86 87 private int firstDayOfWeek = Calendar.MONDAY; 88 89 public WeekListPanel(DateRenderer<T> newRenderer) { 90 this(DateUtils.countDays(newRenderer), newRenderer); 91 } 92 93 public int getTopScrollable() { 94 return daysGrid.getAbsoluteTop(); 95 } 96 97 public WeekListPanel(int newNumberOfDays, DateRenderer<T> newRenderer) { 98 this(newNumberOfDays, newRenderer, true); 99 } 100 101 private boolean showDayLabel = true; 102 103 public WeekListPanel(int newNumberOfDays, DateRenderer<T> newRenderer, boolean newShowDayLabel) { 104 super(); 105 showDayLabel = newShowDayLabel; 106 super.setWidth("100%"); 107 daysShown = newNumberOfDays; 108 labels.resize(1, newNumberOfDays); 109 daysGrid.resize(1, newNumberOfDays); 110 dayEvents.resize(1, newNumberOfDays); 111 112 renderer = newRenderer; 113 if (renderer.enableDragAndDrop()) { 114 weekDragController = new WeekListPanelDragController(dragPanel); 115 wholeDayDragController = new WholeDayDragController(wholeDayDragPanel); 116 } 117 118 dragPanel.add(daysGrid); 119 headerPanel.setWidth("100%"); 120 headerPanel.setStyleName(FtrGwtDateCss.WEEK_HEADER); 121 // mainPanel.setWidth("100%"); 122 // mainPanel.setCellPadding(0); 123 // mainPanel.setCellSpacing(0); 124 125 topPanelDays.setWidth("100%"); 126 labels.setWidth("100%"); 127 dayEvents.setWidth("100%"); 128 daysGrid.setWidth("100%"); 129 daysGrid.setStyleName(FtrGwtDateCss.WEEK_BODY); 130 CSS.setProperty(daysGrid, CSS.A.HEIGHT, "100%"); 131 CSS.setProperty(daysGrid, CSS.A.BORDER_COLOR, "#d0e4f6"); 132 CSS.setProperty(daysGrid, CSS.A.BORDER_STYLE, CSS.V.BORDER_STYLE.SOLID); 133 CSS.setProperty(daysGrid, CSS.A.BORDER_WIDTH, "1px"); 134 daysGrid.setCellPadding(0); 135 daysGrid.setCellSpacing(0); 136 137 dragPanel.setWidth("100%"); 138 super.add(headerPanel); 139 super.setCellVerticalAlignment(headerPanel, VerticalPanel.ALIGN_BOTTOM); 140 super.add(scroller); 141 142 headerSpaceBefore = new HTML(" "); 143 headerPanel.add(headerSpaceBefore); 144 headerPanel.add(topPanelDays); 145 146 headerSpaceAfter = new HTML(" "); 147 headerPanel.add(headerSpaceAfter); 148 headerPanel.setSpacing(0); 149 if (showDayLabel) { 150 topPanelDays.add(labels); 151 } 152 if (renderer.showWholeDayEventView()) { 153 topPanelDays.add(wholeDayDragPanel); 154 wholeDayDragPanel.add(dayEvents); 155 wholeDayDragPanel.setStyleName(FtrGwtDateCss.DATE_DAY_FULL); 156 wholeDayDragPanel.setWidth("100%"); 157 158 dayEvents.setStyleName(FtrGwtDateCss.WEEK_HEADER_EVENTS); 159 dayEvents.setCellPadding(0); 160 dayEvents.setCellSpacing(0); 161 162 dayEvents.setWidth("100%"); 163 } 164 165 topPanelDays.setSpacing(0); 166 167 super.setSpacing(0); 168 current.setFirstDayOfWeek(firstDayOfWeek); 169 current.setTime(new Date()); 170 current.set(Calendar.HOUR_OF_DAY, 0); 171 current.set(Calendar.MINUTE, 0); 172 current.set(Calendar.SECOND, 0); 173 current.set(Calendar.MILLISECOND, 0); 174 buildPanel(); 175 176 } 177 178 private DateRenderer<T> renderer = null; 179 180 public DateRenderer<T> getRenderer() { 181 return renderer; 182 } 183 184 public void setRenderer(DateRenderer<T> renderer) { 185 this.renderer = renderer; 186 buildPanel(); 187 } 188 189 private Date firstLogical = null; 190 191 private Date lastLogical = null; 192 193 @SuppressWarnings("unchecked") 194 public void buildPanel() { 195 if (renderer.enableDragAndDrop()) { 196 for (AbstractDropController dropController : dropControllers) { 197 if (dropController instanceof WeekListDayDropController<?>) { 198 final WeekListDayDropController<T> real = (WeekListDayDropController<T>) dropController; 199 weekDragController.unregisterDropController(real); 200 } else { 201 if (renderer.showWholeDayEventView()) { 202 if (dropController instanceof WholeDayPanelDropController<?>) { 203 final WholeDayPanelDropController<T> real = (WholeDayPanelDropController<T>) dropController; 204 wholeDayDragController.unregisterDropController(real); 205 } 206 } 207 } 208 } 209 210 for (int i = 0; i < dayList.size(); i++) { 211 final DayEventElement<T> result = dayList.get(i); 212 result.destroy(); 213 result.clearEvents(); 214 } 215 dropControllers.clear(); 216 } 217 dayList.clear(); 218 219 labels.clear(); 220 dayEvents.clear(); 221 daysGrid.clear(); 222 223 DOM.removeElementAttribute(scroller.getElement(), "style"); 224 225 DOM.setStyleAttribute(scroller.getElement(), "overflow", "auto"); 226 DOM.setStyleAttribute(scroller.getElement(), "overflowY", "auto"); 227 DOM.setStyleAttribute(scroller.getElement(), "position", "relative"); 228 229 DOM.setStyleAttribute(scroller.getElement(), "overflowX", "hidden"); 230 scroller.setStyleName(FtrGwtDateCss.WEEK_SCROLLER); 231 232 headerSpaceAfter.setWidth("16px"); 233 headerPanel.setCellWidth(headerSpaceAfter, "16px"); 234 235 // mainPanel.getCellFormatter().setStyleName(0, 0, FtrGwtDateCss.HOUR_MAIN_PANEL); 236 // mainPanel.getCellFormatter().setHorizontalAlignment(0, 0, ALIGN_RIGHT); 237 Calendar helperCal = new GregorianCalendar(); 238 helperCal.setTime(current.getTime()); 239 helperCal.setFirstDayOfWeek(getFirstDayOfWeek()); 240 if (daysShown > 1) { 241 helperCal.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek()); 242 } 243 firstLogical = helperCal.getTime(); 244 final Calendar today = new GregorianCalendar(); 245 final String colWide = (100 / daysShown) + "%"; 246 for (int i = 0; i < daysShown; i++) { 247 if (renderer.showDay(helperCal.get(Calendar.DAY_OF_WEEK))) { 248 249 final Date currentDate = helperCal.getTime(); 250 251 final WeekListDayPanel<T> dayPanel = new WeekListDayPanel<T>(renderer); 252 253 if (DateUtils.isSameDay(today, helperCal)) { 254 dayPanel.addStyleName(FtrGwtDateCss.DATE_DAY_TODAY); 255 } 256 dayPanel.setDay(helperCal); 257 dayPanel.addDateEventHandler(this); 258 daysGrid.setWidget(0, i, dayPanel); 259 if (renderer.enableDragAndDrop()) { 260 final WeekListDayDropController<T> dayController = new WeekListDayDropController<T>(dayPanel, this); 261 dropControllers.add(dayController); 262 weekDragController.registerDropController(dayController); 263 } 264 daysGrid.getCellFormatter().setWidth(0, i, colWide); 265 // Set the headers 266 final DayHeader<T> label = new DayHeader<T>(currentDate, renderer); 267 labels.setWidget(0, i, label); 268 labels.getCellFormatter().setWidth(0, i, colWide); 269 label.addDateEventHandler(this); 270 if (renderer.showWholeDayEventView()) { 271 final DayEventpanel<T> eventPanel = new DayEventpanel<T>(renderer, currentDate, this); 272 dayEvents.setWidget(0, i, eventPanel); 273 if (renderer.enableDragAndDrop()) { 274 final WholeDayPanelDropController<T> dayController = new WholeDayPanelDropController<T>(eventPanel); 275 dropControllers.add(dayController); 276 wholeDayDragController.registerDropController(dayController); 277 } 278 dayEvents.getCellFormatter().setWidth(0, i, colWide); 279 eventPanel.addDateEventHandler(this); 280 eventPanel.setDay(helperCal); 281 dayList.add(eventPanel); 282 } 283 dayList.add(dayPanel); 284 } else { 285 i--; 286 } 287 helperCal.add(Calendar.DAY_OF_WEEK, 1); 288 } 289 lastLogical = helperCal.getTime(); 290 int topNeeds = getTopPanelNeeds(); 291 topPanelDays.setHeight(topNeeds + "px"); 292 scroller.setHeight((headerPanel.getOffsetHeight()) + "px"); 293 } 294 295 public void setDate(Date activeday) { 296 GWT.log("Setting to " + activeday, null); 297 final Calendar test = new GregorianCalendar(); 298 test.setTime(activeday); 299 test.set(Calendar.HOUR_OF_DAY, 0); 300 test.set(Calendar.MINUTE, 0); 301 test.set(Calendar.SECOND, 0); 302 test.set(Calendar.MILLISECOND, 0); 303 if (DateUtils.isSameDay(test, current)) { 304 return; 305 } 306 current.setTime(activeday); 307 current.set(Calendar.HOUR_OF_DAY, 0); 308 current.set(Calendar.MINUTE, 0); 309 current.set(Calendar.SECOND, 0); 310 current.set(Calendar.MILLISECOND, 0); 311 // buildPanel(); 312 modifyDate(); 313 } 314 315 @SuppressWarnings("unchecked") 316 private void modifyDate() { 317 if (dayList != null) { 318 for (int i = 0; i < dayList.size(); i++) { 319 final DayEventElement<T> result = dayList.get(i); 320 result.clearEvents(); 321 } 322 } 323 Calendar helperCal = new GregorianCalendar(); 324 helperCal.setFirstDayOfWeek(getFirstDayOfWeek()); 325 helperCal.setTime(current.getTime()); 326 if (daysShown > 1) { 327 helperCal.set(Calendar.DAY_OF_WEEK, helperCal.getFirstDayOfWeek()); 328 } 329 GWT.log("Start on " + helperCal.getTime(), null); 330 firstLogical = helperCal.getTime(); 331 final Calendar today = new GregorianCalendar(); 332 for (int i = 0; i < daysShown; i++) { 333 if (renderer.showDay(helperCal.get(Calendar.DAY_OF_WEEK))) { 334 WeekListDayPanel<T> dayPanel = (WeekListDayPanel<T>) daysGrid.getWidget(0, i); 335 dayPanel.setDay(helperCal); 336 if (DateUtils.isSameDay(today, helperCal)) { 337 dayPanel.addStyleName(FtrGwtDateCss.DATE_DAY_TODAY); 338 } else { 339 dayPanel.removeStyleName(FtrGwtDateCss.DATE_DAY_TODAY); 340 } 341 final DayHeader<T> label = (DayHeader<T>) labels.getWidget(0, i); 342 label.setDate(helperCal.getTime()); 343 if (renderer.showWholeDayEventView()) { 344 final DayEventpanel<T> eventPanel = (DayEventpanel<T>) dayEvents.getWidget(0, i); 345 eventPanel.setDay(helperCal); 346 } 347 } 348 helperCal.add(Calendar.DAY_OF_WEEK, 1); 349 } 350 lastLogical = helperCal.getTime(); 351 352 } 353 354 public int getDaysShown() { 355 return daysShown; 356 } 357 358 public PanelType getType() { 359 return PanelType.WEEK_LIST; 360 } 361 362 public int getFirstDayOfWeek() { 363 return firstDayOfWeek; 364 } 365 366 public void setDaysShown(int newDaysShown) { 367 if (daysShown == newDaysShown) { 368 return; 369 } 370 this.daysShown = newDaysShown; 371 buildPanel(); 372 } 373 374 public void setFirstDayOfWeek(int newFirstDayOfWeek) { 375 if (firstDayOfWeek == newFirstDayOfWeek) { 376 return; 377 } 378 this.firstDayOfWeek = newFirstDayOfWeek; 379 current.setFirstDayOfWeek(firstDayOfWeek); 380 buildPanel(); 381 } 382 383 @SuppressWarnings("unchecked") 384 private void createPanel(DayEventElement<T> result, T newEvent, boolean partOfBatch) { 385 final EventPanel<T> entry = (EventPanel<T>) renderer.createPanel(newEvent, getType()); 386 if (entry != null) { 387 if (renderer.showWholeDayEventView()) { 388 if (wholeDayDragController != null && entry.isDraggable()) { 389 wholeDayDragController.makeDraggable(entry, entry.getDraggableItem()); 390 } 391 } 392 result.addEvent(entry, partOfBatch); 393 entry.addParentDateEventHandler(this); 394 } 395 } 396 397 public void notifyReady(DateEventActions action, T data, boolean reload) { 398 if (reload) { 399 loadData(); 400 } 401 switch (action) { 402 case ADD_DONE: { 403 addEventData(data); 404 break; 405 } 406 case REMOVE_DONE: { 407 removeEventData(data); 408 break; 409 } 410 case UPDATE_DONE: { 411 updateEventData(data); 412 break; 413 } 414 default: 415 break; 416 } 417 DateEvent.fire(this, action, data); 418 } 419 420 public void loadData() { 421 clearData(); 422 renderer.getEventsForRange(getFirstDateShow(), getLastDateShow(), this, true); 423 } 424 425 public void handleDateEvent(DateEvent<T> newEvent) { 426 switch (newEvent.getCommand()) { 427 case DRAG_DROP: { 428 renderer.updateEvent(renderer.createUpdateHandler(this, newEvent.getData())); 429 break; 430 } 431 case UPDATE: { 432 renderer.updateEvent(renderer.createUpdateHandler(this, newEvent.getData())); 433 break; 434 } 435 case REMOVE: { 436 renderer.removeEvent(renderer.createRemoveHandler(this, newEvent.getData())); 437 break; 438 } 439 case ADD: { 440 renderer.addEvent(renderer.createAddHandler(this, newEvent.getData())); 441 break; 442 } 443 case ADD_DONE: { 444 addEventData(newEvent.getData()); 445 DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData()); 446 break; 447 } 448 case REMOVE_DONE: { 449 removeEventData(newEvent.getData()); 450 DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData()); 451 break; 452 } 453 case UPDATE_DONE: { 454 updateEventData(newEvent.getData()); 455 DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData()); 456 break; 457 } 458 case EDIT: { 459 renderer.editAfterClick(newEvent.getData(), this); 460 break; 461 } 462 case RELOAD: { 463 loadData(); 464 DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData()); 465 break; 466 } 467 default: 468 DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData()); 469 break; 470 } 471 } 472 473 public HandlerRegistration addDateEventHandler(DateEventListener<? extends T> handler) { 474 return addHandler(handler, DateEvent.getType()); 475 } 476 477 public Date next() { 478 if (daysShown > 1) { 479 current.add(Calendar.DAY_OF_WEEK, 7); 480 } else { 481 current.add(Calendar.DAY_OF_WEEK, 1); 482 } 483 // current.add(Calendar.DAY_OF_WEEK, daysShown); 484 // buildPanel(); 485 modifyDate(); 486 return current.getTime(); 487 } 488 489 public Date prev() { 490 if (daysShown > 1) { 491 current.add(Calendar.DAY_OF_WEEK, -7); 492 } else { 493 current.add(Calendar.DAY_OF_WEEK, -1); 494 } 495 // buildPanel(); 496 modifyDate(); 497 return current.getTime(); 498 } 499 500 public Date nextMore() { 501 if (daysShown > 1) { 502 current.add(Calendar.MONTH, 1); 503 } else { 504 current.add(Calendar.DAY_OF_WEEK, 7); 505 } 506 // buildPanel(); 507 modifyDate(); 508 return current.getTime(); 509 } 510 511 public Date prevMore() { 512 if (daysShown > 1) { 513 current.add(Calendar.MONTH, -1); 514 } else { 515 current.add(Calendar.DAY_OF_WEEK, -7); 516 } 517 // buildPanel(); 518 modifyDate(); 519 return current.getTime(); 520 } 521 522 public void updateEventData(T newEvent) { 523 removeEventData(newEvent); 524 addEventData(newEvent); 525 } 526 527 public void removeEventData(T newEvent) { 528 for (DayEventElement<T> panel : dayList) { 529 EventPanel<? extends T> removed = panel.removeEvent(newEvent); 530 if (removed != null) { 531 removed.clearParent(); 532 return; 533 } 534 } 535 536 } 537 538 public void addEventsByList(List<? extends T> events) { 539 if (events != null) { 540 for (int i = 0; i < events.size(); i++) { 541 addEventData(events.get(i), true); 542 } 543 } 544 545 for (DayEventElement<T> panel : dayList) { 546 panel.repaintEvents(); 547 } 548 } 549 550 private void addEventData(T newEvent, boolean isPartOfBatch) { 551 for (DayEventElement<T> panel : dayList) { 552 if (panel.isDay(newEvent)) { 553 createPanel(panel, newEvent, isPartOfBatch); 554 } 555 } 556 } 557 558 public void addEventData(T newEvent) { 559 addEventData(newEvent, false); 560 } 561 562 private HTML headerSpaceBefore; 563 564 private HTML headerSpaceAfter; 565 566 public int getHeight() { 567 return height; 568 } 569 570 public void repaint() { 571 for (DayEventElement<T> panel : dayList) { 572 panel.repaintEvents(); 573 } 574 } 575 576 private int width = 100; 577 578 private int height = 400; 579 580 public void setPixelSize(int newWidth, int newHeight) { 581 width = newWidth; 582 int topDragNeeds = getTopPanelNeeds(); 583 topPanelDays.setHeight(topDragNeeds + "px"); 584 585 height = newHeight; 586 scroller.setHeight((height - headerPanel.getOffsetHeight()) + "px"); 587 super.setWidth(width + "px"); 588 int wi = width; 589 if (wi < 0) { 590 wi = this.getElement().getOffsetWidth(); 591 } 592 int maxWi = wi / getDaysShown(); 593 for (int i = 0; i < dayList.size(); i++) { 594 final DayEventElement<T> result = dayList.get(i); 595 result.setElementWide(maxWi); 596 } 597 GWT.log("Panle " + width + " Result " + maxWi, null); 598 repaint(); 599 } 600 601 public int getTopPanelNeeds() { 602 int max = 0; 603 if (renderer.showWholeDayEventView()) { 604 for (DayEventElement<T> panel : dayList) { 605 if (panel instanceof DayEventpanel<?>) { 606 final DayEventpanel<T> real = (DayEventpanel<T>) panel; 607 final int newTest = real.neededHeight(); 608 if (newTest > max) { 609 max = newTest; 610 } 611 } 612 } 613 wholeDayDragPanel.setHeight(max + "px"); 614 } 615 return max + labels.getOffsetHeight(); 616 } 617 618 public Date getFirstDateShow() { 619 return firstLogical; 620 } 621 622 public Date getLastDateShow() { 623 return lastLogical; 624 } 625 626 public Date getFirstDateLogical() { 627 return firstLogical; 628 } 629 630 public Date getLastDateLogical() { 631 return lastLogical; 632 } 633 634 public void clearData() { 635 if (dayList != null) { 636 for (DayEventElement<T> panel : dayList) { 637 panel.clearEvents(); 638 } 639 } 640 } 641 642 public void setEvents(List<? extends T> events) { 643 clearData(); 644 addEventsByList(events); 645 } 646 647}