123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- /*
- @ITMillApache2LicenseForJavaFiles@
- */
-
- package com.itmill.toolkit.terminal.gwt.client.ui;
-
- import java.util.Date;
- import java.util.Iterator;
- import java.util.List;
-
- import com.google.gwt.user.client.DOM;
- import com.google.gwt.user.client.Event;
- import com.google.gwt.user.client.Timer;
- import com.google.gwt.user.client.ui.ClickListener;
- import com.google.gwt.user.client.ui.FlexTable;
- import com.google.gwt.user.client.ui.MouseListener;
- import com.google.gwt.user.client.ui.MouseListenerCollection;
- import com.google.gwt.user.client.ui.SourcesMouseEvents;
- import com.google.gwt.user.client.ui.SourcesTableEvents;
- import com.google.gwt.user.client.ui.TableListener;
- import com.google.gwt.user.client.ui.Widget;
- import com.itmill.toolkit.terminal.gwt.client.DateTimeService;
- import com.itmill.toolkit.terminal.gwt.client.LocaleService;
-
- public class ICalendarPanel extends FlexTable implements MouseListener,
- ClickListener {
-
- private final IDateField datefield;
-
- private IEventButton prevYear;
-
- private IEventButton nextYear;
-
- private IEventButton prevMonth;
-
- private IEventButton nextMonth;
-
- private ITime time;
-
- private Date minDate = null;
-
- private Date maxDate = null;
-
- private CalendarEntrySource entrySource;
-
- /* Needed to identify resolution changes */
- private int resolution = IDateField.RESOLUTION_YEAR;
-
- /* Needed to identify locale changes */
- private String locale = LocaleService.getDefaultLocale();
-
- public ICalendarPanel(IDateField parent) {
- datefield = parent;
- setStyleName(IDateField.CLASSNAME + "-calendarpanel");
- // buildCalendar(true);
- addTableListener(new DateClickListener(this));
- }
-
- public ICalendarPanel(IDateField parent, Date min, Date max) {
- datefield = parent;
- setStyleName(IDateField.CLASSNAME + "-calendarpanel");
- // buildCalendar(true);
- addTableListener(new DateClickListener(this));
-
- }
-
- private void buildCalendar(boolean forceRedraw) {
- final boolean needsMonth = datefield.getCurrentResolution() > IDateField.RESOLUTION_YEAR;
- boolean needsBody = datefield.getCurrentResolution() >= IDateField.RESOLUTION_DAY;
- final boolean needsTime = datefield.getCurrentResolution() >= IDateField.RESOLUTION_HOUR;
- buildCalendarHeader(forceRedraw, needsMonth);
- clearCalendarBody(!needsBody);
- if (needsBody) {
- buildCalendarBody();
- }
- if (needsTime) {
- buildTime(forceRedraw);
- } else if (time != null) {
- remove(time);
- time = null;
- }
- }
-
- private void clearCalendarBody(boolean remove) {
- if (!remove) {
- for (int row = 2; row < 8; row++) {
- for (int col = 0; col < 7; col++) {
- setHTML(row, col, " ");
- }
- }
- } else if (getRowCount() > 2) {
- while (getRowCount() > 2) {
- removeRow(2);
- }
- }
- }
-
- private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) {
- if (forceRedraw) {
- if (prevMonth == null) { // Only do once
- prevYear = new IEventButton();
- prevYear.setHTML("«");
- prevYear.setStyleName("i-button-prevyear");
- nextYear = new IEventButton();
- nextYear.setHTML("»");
- nextYear.setStyleName("i-button-nextyear");
- prevYear.addMouseListener(this);
- nextYear.addMouseListener(this);
- prevYear.addClickListener(this);
- nextYear.addClickListener(this);
- setWidget(0, 0, prevYear);
- setWidget(0, 4, nextYear);
-
- if (needsMonth) {
- prevMonth = new IEventButton();
- prevMonth.setHTML("‹");
- prevMonth.setStyleName("i-button-prevmonth");
- nextMonth = new IEventButton();
- nextMonth.setHTML("›");
- nextMonth.setStyleName("i-button-nextmonth");
- prevMonth.addMouseListener(this);
- nextMonth.addMouseListener(this);
- prevMonth.addClickListener(this);
- nextMonth.addClickListener(this);
- setWidget(0, 3, nextMonth);
- setWidget(0, 1, prevMonth);
- }
-
- getFlexCellFormatter().setColSpan(0, 2, 3);
- getRowFormatter().addStyleName(0,
- IDateField.CLASSNAME + "-calendarpanel-header");
- } else if (!needsMonth) {
- // Remove month traverse buttons
- prevMonth.removeClickListener(this);
- prevMonth.removeMouseListener(this);
- nextMonth.removeClickListener(this);
- nextMonth.removeMouseListener(this);
- remove(prevMonth);
- remove(nextMonth);
- prevMonth = null;
- nextMonth = null;
- }
-
- // Print weekday names
- final int firstDay = datefield.getDateTimeService()
- .getFirstDayOfWeek();
- for (int i = 0; i < 7; i++) {
- int day = i + firstDay;
- if (day > 6) {
- day = 0;
- }
- if (datefield.getCurrentResolution() > IDateField.RESOLUTION_MONTH) {
- setHTML(1, i, "<strong>"
- + datefield.getDateTimeService().getShortDay(day)
- + "</strong>");
- } else {
- setHTML(1, i, "");
- }
- }
- }
-
- final String monthName = needsMonth ? datefield.getDateTimeService()
- .getMonth(datefield.getShowingDate().getMonth()) : "";
- final int year = datefield.getShowingDate().getYear() + 1900;
- setHTML(0, 2, "<span class=\"" + IDateField.CLASSNAME
- + "-calendarpanel-month\">" + monthName + " " + year
- + "</span>");
- }
-
- private void buildCalendarBody() {
- // date actually selected?
- Date currentDate = datefield.getCurrentDate();
- Date showing = datefield.getShowingDate();
- boolean selected = (currentDate != null
- && currentDate.getMonth() == showing.getMonth() && currentDate
- .getYear() == showing.getYear());
-
- final int startWeekDay = datefield.getDateTimeService()
- .getStartWeekDay(datefield.getShowingDate());
- final int numDays = DateTimeService.getNumberOfDaysInMonth(datefield
- .getShowingDate());
- int dayCount = 0;
- final Date today = new Date();
- final Date curr = new Date(datefield.getShowingDate().getTime());
- for (int row = 2; row < 8; row++) {
- for (int col = 0; col < 7; col++) {
- if (!(row == 2 && col < startWeekDay)) {
- if (dayCount < numDays) {
- final int selectedDate = ++dayCount;
- String title = "";
- if (entrySource != null) {
- curr.setDate(dayCount);
- final List entries = entrySource.getEntries(curr,
- IDateField.RESOLUTION_DAY);
- if (entries != null) {
- for (final Iterator it = entries.iterator(); it
- .hasNext();) {
- final CalendarEntry entry = (CalendarEntry) it
- .next();
- title += (title.length() > 0 ? ", " : "")
- + entry.getStringForDate(curr);
- }
- }
- }
- final String baseclass = IDateField.CLASSNAME
- + "-calendarpanel-day";
- String cssClass = baseclass;
- if (!isEnabledDate(curr)) {
- cssClass += " " + baseclass + "-disabled";
- }
- if (selected
- && datefield.getShowingDate().getDate() == dayCount) {
- cssClass += " " + baseclass + "-selected";
- }
- if (today.getDate() == dayCount
- && today.getMonth() == datefield
- .getShowingDate().getMonth()
- && today.getYear() == datefield
- .getShowingDate().getYear()) {
- cssClass += " " + baseclass + "-today";
- }
- if (title.length() > 0) {
- cssClass += " " + baseclass + "-entry";
- }
- setHTML(row, col, "<span title=\"" + title
- + "\" class=\"" + cssClass + "\">"
- + selectedDate + "</span>");
- } else {
- break;
- }
-
- }
- }
- }
- }
-
- private void buildTime(boolean forceRedraw) {
- if (time == null) {
- time = new ITime(datefield);
- setText(8, 0, ""); // Add new row
- getFlexCellFormatter().setColSpan(8, 0, 7);
- setWidget(8, 0, time);
- }
- time.updateTime(forceRedraw);
- }
-
- /**
- *
- * @param forceRedraw
- * Build all from scratch, in case of e.g. locale changes
- */
- public void updateCalendar() {
- // Locale and resolution changes force a complete redraw
- buildCalendar(locale != datefield.getCurrentLocale()
- || resolution != datefield.getCurrentResolution());
- if (datefield instanceof ITextualDate) {
- ((ITextualDate) datefield).buildDate();
- }
- locale = datefield.getCurrentLocale();
- resolution = datefield.getCurrentResolution();
- }
-
- public void onClick(Widget sender) {
- // processClickEvent(sender, true);
- }
-
- private boolean isEnabledDate(Date date) {
- if ((minDate != null && date.before(minDate))
- || (maxDate != null && date.after(maxDate))) {
- return false;
- }
- return true;
- }
-
- private void processClickEvent(Widget sender, boolean updateVariable) {
- if (!datefield.isEnabled() || datefield.isReadonly()) {
- return;
- }
- Date showingDate = datefield.getShowingDate();
- if (!updateVariable) {
- if (sender == prevYear) {
- showingDate.setYear(showingDate.getYear() - 1);
- updateCalendar();
- } else if (sender == nextYear) {
- showingDate.setYear(showingDate.getYear() + 1);
- updateCalendar();
- } else if (sender == prevMonth) {
- showingDate.setMonth(showingDate.getMonth() - 1);
- updateCalendar();
- } else if (sender == nextMonth) {
- showingDate.setMonth(showingDate.getMonth() + 1);
- updateCalendar();
- }
- } else {
- if (datefield.getCurrentResolution() == IDateField.RESOLUTION_YEAR
- || datefield.getCurrentResolution() == IDateField.RESOLUTION_MONTH) {
- // Due to current UI, update variable if res=year/month
- datefield.setCurrentDate(new Date(showingDate.getTime()));
- if (datefield.getCurrentResolution() == IDateField.RESOLUTION_MONTH) {
- datefield.getClient().updateVariable(datefield.getId(),
- "month", datefield.getCurrentDate().getMonth() + 1,
- false);
- }
- datefield.getClient().updateVariable(datefield.getId(), "year",
- datefield.getCurrentDate().getYear() + 1900,
- datefield.isImmediate());
- }
- }
- }
-
- private Timer timer;
-
- public void onMouseDown(final Widget sender, int x, int y) {
- if (sender instanceof IEventButton) {
- processClickEvent(sender, false);
- timer = new Timer() {
- public void run() {
- processClickEvent(sender, false);
- }
- };
- timer.scheduleRepeating(100);
- }
- }
-
- public void onMouseEnter(Widget sender) {
- }
-
- public void onMouseLeave(Widget sender) {
- if (timer != null) {
- timer.cancel();
- }
- }
-
- public void onMouseMove(Widget sender, int x, int y) {
- }
-
- public void onMouseUp(Widget sender, int x, int y) {
- if (timer != null) {
- timer.cancel();
- }
- processClickEvent(sender, true);
- }
-
- private class IEventButton extends IButton implements SourcesMouseEvents {
-
- private MouseListenerCollection mouseListeners;
-
- public IEventButton() {
- super();
- sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS | Event.ONCLICK
- | Event.MOUSEEVENTS);
- }
-
- public void addMouseListener(MouseListener listener) {
- if (mouseListeners == null) {
- mouseListeners = new MouseListenerCollection();
- }
- mouseListeners.add(listener);
- }
-
- public void removeMouseListener(MouseListener listener) {
- if (mouseListeners != null) {
- mouseListeners.remove(listener);
- }
- }
-
- public void onBrowserEvent(Event event) {
- super.onBrowserEvent(event);
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEDOWN:
- case Event.ONMOUSEUP:
- case Event.ONMOUSEMOVE:
- case Event.ONMOUSEOVER:
- case Event.ONMOUSEOUT:
- if (mouseListeners != null) {
- mouseListeners.fireMouseEvent(this, event);
- }
- break;
- }
- }
- }
-
- private class DateClickListener implements TableListener {
-
- private final ICalendarPanel cal;
-
- public DateClickListener(ICalendarPanel panel) {
- cal = panel;
- }
-
- public void onCellClicked(SourcesTableEvents sender, int row, int col) {
- if (sender != cal || row < 2 || row > 7
- || !cal.datefield.isEnabled() || cal.datefield.isReadonly()) {
- return;
- }
-
- final String text = cal.getText(row, col);
- if (text.equals(" ")) {
- return;
- }
-
- try {
- final Integer day = new Integer(text);
- final Date newDate = cal.datefield.getShowingDate();
- newDate.setDate(day.intValue());
- if (!isEnabledDate(newDate)) {
- return;
- }
- if (cal.datefield.getCurrentDate() == null) {
- cal.datefield.setCurrentDate(new Date(newDate.getTime()));
-
- // Init variables with current time
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "hour", newDate.getHours(), false);
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "min", newDate.getMinutes(), false);
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "sec", newDate.getSeconds(), false);
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "msec", datefield.getMilliseconds(), false);
- }
-
- cal.datefield.getCurrentDate().setTime(newDate.getTime());
- cal.datefield.getClient().updateVariable(cal.datefield.getId(),
- "day", cal.datefield.getCurrentDate().getDate(), false);
- cal.datefield.getClient().updateVariable(cal.datefield.getId(),
- "month", cal.datefield.getCurrentDate().getMonth() + 1,
- false);
- cal.datefield.getClient().updateVariable(cal.datefield.getId(),
- "year",
- cal.datefield.getCurrentDate().getYear() + 1900,
- cal.datefield.isImmediate());
-
- if (datefield instanceof ITextualDate
- && resolution < IDateField.RESOLUTION_HOUR) {
- ((IToolkitOverlay) getParent()).hide();
- } else {
- updateCalendar();
- }
-
- } catch (final NumberFormatException e) {
- // Not a number, ignore and stop here
- return;
- }
- }
-
- }
-
- public void setLimits(Date min, Date max) {
- if (min != null) {
- final Date d = new Date(min.getTime());
- d.setHours(0);
- d.setMinutes(0);
- d.setSeconds(1);
- minDate = d;
- } else {
- minDate = null;
- }
- if (max != null) {
- final Date d = new Date(max.getTime());
- d.setHours(24);
- d.setMinutes(59);
- d.setSeconds(59);
- maxDate = d;
- } else {
- maxDate = null;
- }
- }
-
- public void setCalendarEntrySource(CalendarEntrySource entrySource) {
- this.entrySource = entrySource;
- }
-
- public CalendarEntrySource getCalendarEntrySource() {
- return entrySource;
- }
-
- public interface CalendarEntrySource {
- public List getEntries(Date date, int resolution);
- }
-
- /**
- * Sets focus to Calendar panel.
- *
- * @param focus
- */
- public void setFocus(boolean focus) {
- nextYear.setFocus(focus);
- }
-
- }
|