/* * Copyright 2000-2014 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.vaadin.ui; import java.lang.reflect.Method; import java.text.DateFormat; import java.text.DateFormatSymbols; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.EventListener; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TimeZone; import java.util.logging.Level; import java.util.logging.Logger; import org.jsoup.nodes.Attributes; import org.jsoup.nodes.Element; import com.vaadin.data.Container; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.DropTarget; import com.vaadin.event.dd.TargetDetails; import com.vaadin.server.KeyMapper; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.shared.ui.calendar.CalendarEventId; import com.vaadin.shared.ui.calendar.CalendarServerRpc; import com.vaadin.shared.ui.calendar.CalendarState; import com.vaadin.shared.ui.calendar.DateConstants; import com.vaadin.ui.components.calendar.CalendarComponentEvent; import com.vaadin.ui.components.calendar.CalendarComponentEvents; import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardEvent; import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardHandler; import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent; import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickHandler; import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClick; import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClickHandler; import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventMoveHandler; import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize; import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler; import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardEvent; import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardHandler; import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent; import com.vaadin.ui.components.calendar.CalendarComponentEvents.RangeSelectEvent; import com.vaadin.ui.components.calendar.CalendarComponentEvents.RangeSelectHandler; import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClick; import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClickHandler; import com.vaadin.ui.components.calendar.CalendarDateRange; import com.vaadin.ui.components.calendar.CalendarTargetDetails; import com.vaadin.ui.components.calendar.ContainerEventProvider; import com.vaadin.ui.components.calendar.event.BasicEventProvider; import com.vaadin.ui.components.calendar.event.CalendarEditableEventProvider; import com.vaadin.ui.components.calendar.event.CalendarEvent; import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeEvent; import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeListener; import com.vaadin.ui.components.calendar.event.CalendarEventProvider; import com.vaadin.ui.components.calendar.handler.BasicBackwardHandler; import com.vaadin.ui.components.calendar.handler.BasicDateClickHandler; import com.vaadin.ui.components.calendar.handler.BasicEventMoveHandler; import com.vaadin.ui.components.calendar.handler.BasicEventResizeHandler; import com.vaadin.ui.components.calendar.handler.BasicForwardHandler; import com.vaadin.ui.components.calendar.handler.BasicWeekClickHandler; import com.vaadin.ui.declarative.DesignAttributeHandler; import com.vaadin.ui.declarative.DesignContext; /** *
* Vaadin Calendar is for visualizing events in a calendar. Calendar events can * be visualized in the variable length view depending on the start and end * dates. *
* ** Construct a Vaadin Calendar with event provider. Event provider is * obligatory, because calendar component will query active events through * it. *
* ** By default, Vaadin Calendar will show dates from the start of the current * week to the end of the current week. Use {@link #setStartDate(Date)} and * {@link #setEndDate(Date)} to change this. *
* * @param eventProvider * Event provider, cannot be null. */ public Calendar(CalendarEventProvider eventProvider) { this(null, eventProvider); } /** ** Construct a Vaadin Calendar with event provider and a caption. Event * provider is obligatory, because calendar component will query active * events through it. *
* ** By default, Vaadin Calendar will show dates from the start of the current * week to the end of the current week. Use {@link #setStartDate(Date)} and * {@link #setEndDate(Date)} to change this. *
* * @param eventProvider * Event provider, cannot be null. */ // this is the constructor every other constructor calls public Calendar(String caption, CalendarEventProvider eventProvider) { registerRpc(rpc); setCaption(caption); handlers = new HashMapnull
.
*/
private void cacheMinMaxTimeOfDay(List* If no events exist, nothing happens. *
* NOTE: triggering this method only does this once for the current
* events - events that are not in the current visible range, are
* ignored!
*
* @see #setFirstVisibleHourOfDay(int)
* @see #setLastVisibleHourOfDay(int)
*/
public void autoScaleVisibleHoursOfDay() {
if (minTimeInMinutes != null) {
setFirstVisibleHourOfDay(minTimeInMinutes / 60);
// Do not show the final hour if last minute ends on it
setLastVisibleHourOfDay((maxTimeInMinutes - 1) / 60);
}
}
/**
* Resets the {@link #setFirstVisibleHourOfDay(int)} and
* {@link #setLastVisibleHourOfDay(int)} to the default values, 0 and 23
* respectively.
*
* @see #autoScaleVisibleHoursOfDay()
* @see #setFirstVisibleHourOfDay(int)
* @see #setLastVisibleHourOfDay(int)
*/
public void resetVisibleHoursOfDay() {
setFirstVisibleHourOfDay(0);
setLastVisibleHourOfDay(23);
}
private void setupDaysAndActions() {
// Make sure we have a up-to-date locale
initCalendarWithLocale();
CalendarState state = getState();
state.firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
// If only one is null, throw exception
// If both are null, set defaults
if (startDate == null ^ endDate == null) {
String message = "Schedule cannot be painted without a proper date range.\n";
if (startDate == null) {
throw new IllegalStateException(message
+ "You must set a start date using setStartDate(Date).");
} else {
throw new IllegalStateException(message
+ "You must set an end date using setEndDate(Date).");
}
} else if (startDate == null && endDate == null) {
// set defaults
startDate = getStartDate();
endDate = getEndDate();
}
int durationInDays = (int) ((endDate.getTime() - startDate.getTime())
/ DateConstants.DAYINMILLIS);
durationInDays++;
if (durationInDays > 60) {
throw new RuntimeException(
"Daterange is too big (max 60) = " + durationInDays);
}
state.dayNames = getDayNamesShort();
state.monthNames = getMonthNamesShort();
// Use same timezone in all dates this component handles.
// Show "now"-marker in browser within given timezone.
Date now = new Date();
currentCalendar.setTime(now);
now = currentCalendar.getTime();
// Reset time zones for custom date formats
df_date.setTimeZone(currentCalendar.getTimeZone());
df_time.setTimeZone(currentCalendar.getTimeZone());
state.now = df_date.format(now) + " " + df_time.format(now);
Date firstDateToShow = expandStartDate(startDate, durationInDays > 7);
Date lastDateToShow = expandEndDate(endDate, durationInDays > 7);
currentCalendar.setTime(firstDateToShow);
DateFormat weeklyCaptionFormatter = getWeeklyCaptionFormatter();
weeklyCaptionFormatter.setTimeZone(currentCalendar.getTimeZone());
Map
* This method restricts the weekdays that are shown. This affects both the
* monthly and the weekly view. The general contract is that firstDay <
* lastDay.
*
* Note that this only affects the rendering process. Events are still
* requested by the dates set by {@link #setStartDate(Date)} and
* {@link #setEndDate(Date)}.
*
* This method restricts the weekdays that are shown. This affects both the
* monthly and the weekly view. The general contract is that firstDay <
* lastDay.
*
* Note that this only affects the rendering process. Events are still
* requested by the dates set by {@link #setStartDate(Date)} and
* {@link #setEndDate(Date)}.
*
* Note that this only affects the rendering process. Events are still
* requested by the dates set by {@link #setStartDate(Date)} and
* {@link #setEndDate(Date)}.
*
* You can use {@link #autoScaleVisibleHoursOfDay()} for automatic scaling
* of the visible hours based on current events.
*
* @param firstHour
* the first hour of the day to show, between 0 and 23
* @see #autoScaleVisibleHoursOfDay()
*/
public void setFirstVisibleHourOfDay(int firstHour) {
if (this.firstHour != firstHour && firstHour >= 0 && firstHour <= 23
&& firstHour <= getLastVisibleHourOfDay()) {
this.firstHour = firstHour;
getState().firstHourOfDay = firstHour;
}
}
/**
* Returns the first visible hour in the week view. Returns the hour using a
* 24h time format
*
*/
public int getFirstVisibleHourOfDay() {
return firstHour;
}
/**
* This method restricts the hours that are shown per day. This affects the
* weekly view. The general contract is that firstHour < lastHour.
*
* Note that this only affects the rendering process. Events are still
* requested by the dates set by {@link #setStartDate(Date)} and
* {@link #setEndDate(Date)}.
*
* You can use {@link #autoScaleVisibleHoursOfDay()} for automatic scaling
* of the visible hours based on current events.
*
* @param lastHour
* the first hour of the day to show, between 0 and 23
* @see #autoScaleVisibleHoursOfDay()
*/
public void setLastVisibleHourOfDay(int lastHour) {
if (this.lastHour != lastHour && lastHour >= 0 && lastHour <= 23
&& lastHour >= getFirstVisibleHourOfDay()) {
this.lastHour = lastHour;
getState().lastHourOfDay = lastHour;
}
}
/**
* Returns the last visible hour in the week view. Returns the hour using a
* 24h time format
*
*/
public int getLastVisibleHourOfDay() {
return lastHour;
}
/**
* Gets the date caption format for the weekly view.
*
* @return The pattern used in caption of dates in weekly view.
*/
public String getWeeklyCaptionFormat() {
return weeklyCaptionFormat;
}
/**
* Sets custom date format for the weekly view. This is the caption of the
* date. Format could be like "mmm MM/dd".
*
* @param dateFormatPattern
* The date caption pattern.
*/
public void setWeeklyCaptionFormat(String dateFormatPattern) {
if (weeklyCaptionFormat == null && dateFormatPattern != null
|| weeklyCaptionFormat != null
&& !weeklyCaptionFormat.equals(dateFormatPattern)) {
weeklyCaptionFormat = dateFormatPattern;
markAsDirty();
}
}
private DateFormat getWeeklyCaptionFormatter() {
if (weeklyCaptionFormat != null) {
return new SimpleDateFormat(weeklyCaptionFormat, getLocale());
} else {
return SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT,
getLocale());
}
}
/**
* Get the day of week by the given calendar and its locale
*
* @param calendar
* The calendar to use
* @return
*/
private static int getDowByLocale(java.util.Calendar calendar) {
int fow = calendar.get(java.util.Calendar.DAY_OF_WEEK);
// monday first
if (calendar.getFirstDayOfWeek() == java.util.Calendar.MONDAY) {
fow = fow == java.util.Calendar.SUNDAY ? 7 : fow - 1;
}
return fow;
}
/**
* Is the user allowed to trigger events which alters the events
*
* @return true if the client is allowed to send changes to server
* @see #isEventClickAllowed()
*/
protected boolean isClientChangeAllowed() {
return !isReadOnly();
}
/**
* Is the user allowed to trigger click events. Returns {@code true} by
* default. Subclass can override this method to disallow firing event
* clicks got from the client side.
*
* @return true if the client is allowed to click events
* @see #isClientChangeAllowed()
* @deprecated As of 7.4, override {@link #fireEventClick(Integer)} instead.
*/
@Deprecated
protected boolean isEventClickAllowed() {
return true;
}
/**
* Fires an event when the user selecing moving forward/backward in the
* calendar.
*
* @param forward
* True if the calendar moved forward else backward is assumed.
*/
protected void fireNavigationEvent(boolean forward) {
if (forward) {
fireEvent(new ForwardEvent(this));
} else {
fireEvent(new BackwardEvent(this));
}
}
/**
* Fires an event move event to all server side move listerners
*
* @param index
* The index of the event in the events list
* @param newFromDatetime
* The changed from date time
*/
protected void fireEventMove(int index, Date newFromDatetime) {
MoveEvent event = new MoveEvent(this, events.get(index),
newFromDatetime);
if (calendarEventProvider instanceof EventMoveHandler) {
// Notify event provider if it is an event move handler
((EventMoveHandler) calendarEventProvider).eventMove(event);
}
// Notify event move handler attached by using the
// setHandler(EventMoveHandler) method
fireEvent(event);
}
/**
* Fires event when a week was clicked in the calendar.
*
* @param week
* The week that was clicked
* @param year
* The year of the week
*/
protected void fireWeekClick(int week, int year) {
fireEvent(new WeekClick(this, week, year));
}
/**
* Fires event when a date was clicked in the calendar. Uses an existing
* event from the event cache.
*
* @param index
* The index of the event in the event cache.
*/
protected void fireEventClick(Integer index) {
fireEvent(new EventClick(this, events.get(index)));
}
/**
* Fires event when a date was clicked in the calendar. Creates a new event
* for the date and passes it to the listener.
*
* @param date
* The date and time that was clicked
*/
protected void fireDateClick(Date date) {
fireEvent(new DateClickEvent(this, date));
}
/**
* Fires an event range selected event. The event is fired when a user
* highlights an area in the calendar. The highlighted areas start and end
* dates are returned as arguments.
*
* @param from
* The start date and time of the highlighted area
* @param to
* The end date and time of the highlighted area
* @param monthlyMode
* Is the calendar in monthly mode
*/
protected void fireRangeSelect(Date from, Date to, boolean monthlyMode) {
fireEvent(new RangeSelectEvent(this, from, to, monthlyMode));
}
/**
* Fires an event resize event. The event is fired when a user resizes the
* event in the calendar causing the time range of the event to increase or
* decrease. The new start and end times are returned as arguments to this
* method.
*
* @param index
* The index of the event in the event cache
* @param startTime
* The new start date and time of the event
* @param endTime
* The new end date and time of the event
*/
protected void fireEventResize(int index, Date startTime, Date endTime) {
EventResize event = new EventResize(this, events.get(index), startTime,
endTime);
if (calendarEventProvider instanceof EventResizeHandler) {
// Notify event provider if it is an event resize handler
((EventResizeHandler) calendarEventProvider).eventResize(event);
}
// Notify event resize handler attached by using the
// setHandler(EventMoveHandler) method
fireEvent(event);
}
/**
* Localized display names for week days starting from sunday. Returned
* array's length is always 7.
*
* @return Array of localized weekday names.
*/
protected String[] getDayNamesShort() {
DateFormatSymbols s = new DateFormatSymbols(getLocale());
return Arrays.copyOfRange(s.getWeekdays(), 1, 8);
}
/**
* Localized display names for months starting from January. Returned
* array's length is always 12.
*
* @return Array of localized month names.
*/
protected String[] getMonthNamesShort() {
DateFormatSymbols s = new DateFormatSymbols(getLocale());
return Arrays.copyOf(s.getShortMonths(), 12);
}
/**
* Gets a date that is first day in the week that target given date belongs
* to.
*
* @param date
* Target date
* @return Date that is first date in same week that given date is.
*/
protected Date getFirstDateForWeek(Date date) {
int firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
currentCalendar.setTime(date);
while (firstDayOfWeek != currentCalendar
.get(java.util.Calendar.DAY_OF_WEEK)) {
currentCalendar.add(java.util.Calendar.DATE, -1);
}
return currentCalendar.getTime();
}
/**
* Gets a date that is last day in the week that target given date belongs
* to.
*
* @param date
* Target date
* @return Date that is last date in same week that given date is.
*/
protected Date getLastDateForWeek(Date date) {
currentCalendar.setTime(date);
currentCalendar.add(java.util.Calendar.DATE, 1);
int firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
// Roll to weeks last day using firstdayofweek. Roll until FDofW is
// found and then roll back one day.
while (firstDayOfWeek != currentCalendar
.get(java.util.Calendar.DAY_OF_WEEK)) {
currentCalendar.add(java.util.Calendar.DATE, 1);
}
currentCalendar.add(java.util.Calendar.DATE, -1);
return currentCalendar.getTime();
}
/**
* Calculates the end time of the day using the given calendar and date
*
* @param date
* @param calendar
* the calendar instance to be used in the calculation. The given
* instance is unchanged in this operation.
* @return the given date, with time set to the end of the day
*/
private static Date getEndOfDay(java.util.Calendar calendar, Date date) {
java.util.Calendar calendarClone = (java.util.Calendar) calendar
.clone();
calendarClone.setTime(date);
calendarClone.set(java.util.Calendar.MILLISECOND,
calendarClone.getActualMaximum(java.util.Calendar.MILLISECOND));
calendarClone.set(java.util.Calendar.SECOND,
calendarClone.getActualMaximum(java.util.Calendar.SECOND));
calendarClone.set(java.util.Calendar.MINUTE,
calendarClone.getActualMaximum(java.util.Calendar.MINUTE));
calendarClone.set(java.util.Calendar.HOUR,
calendarClone.getActualMaximum(java.util.Calendar.HOUR));
calendarClone.set(java.util.Calendar.HOUR_OF_DAY,
calendarClone.getActualMaximum(java.util.Calendar.HOUR_OF_DAY));
return calendarClone.getTime();
}
/**
* Calculates the end time of the day using the given calendar and date
*
* @param date
* @param calendar
* the calendar instance to be used in the calculation. The given
* instance is unchanged in this operation.
* @return the given date, with time set to the end of the day
*/
private static Date getStartOfDay(java.util.Calendar calendar, Date date) {
java.util.Calendar calendarClone = (java.util.Calendar) calendar
.clone();
calendarClone.setTime(date);
calendarClone.set(java.util.Calendar.MILLISECOND, 0);
calendarClone.set(java.util.Calendar.SECOND, 0);
calendarClone.set(java.util.Calendar.MINUTE, 0);
calendarClone.set(java.util.Calendar.HOUR, 0);
calendarClone.set(java.util.Calendar.HOUR_OF_DAY, 0);
return calendarClone.getTime();
}
/**
* Finds the first day of the week and returns a day representing the start
* of that day
*
* @param start
* The actual date
* @param expandToFullWeek
* Should the returned date be moved to the start of the week
* @return If expandToFullWeek is set then it returns the first day of the
* week, else it returns a clone of the actual date with the time
* set to the start of the day
*/
protected Date expandStartDate(Date start, boolean expandToFullWeek) {
// If the duration is more than week, use monthly view and get startweek
// and endweek. Example if views daterange is from tuesday to next weeks
// wednesday->expand to monday to nextweeks sunday. If firstdayofweek =
// monday
if (expandToFullWeek) {
start = getFirstDateForWeek(start);
} else {
start = (Date) start.clone();
}
// Always expand to the start of the first day to the end of the last
// day
start = getStartOfDay(currentCalendar, start);
return start;
}
/**
* Finds the last day of the week and returns a day representing the end of
* that day
*
* @param end
* The actual date
* @param expandToFullWeek
* Should the returned date be moved to the end of the week
* @return If expandToFullWeek is set then it returns the last day of the
* week, else it returns a clone of the actual date with the time
* set to the end of the day
*/
protected Date expandEndDate(Date end, boolean expandToFullWeek) {
// If the duration is more than week, use monthly view and get startweek
// and endweek. Example if views daterange is from tuesday to next weeks
// wednesday->expand to monday to nextweeks sunday. If firstdayofweek =
// monday
if (expandToFullWeek) {
end = getLastDateForWeek(end);
} else {
end = (Date) end.clone();
}
// Always expand to the start of the first day to the end of the last
// day
end = getEndOfDay(currentCalendar, end);
return end;
}
/**
* Set the {@link CalendarEventProvider} to be used with this calendar. The
* EventProvider is used to query for events to show, and must be non-null.
* By default a {@link BasicEventProvider} is used.
*
* @param calendarEventProvider
* the calendarEventProvider to set. Cannot be null.
*/
public void setEventProvider(CalendarEventProvider calendarEventProvider) {
if (calendarEventProvider == null) {
throw new IllegalArgumentException(
"Calendar event provider cannot be null");
}
// remove old listener
if (getEventProvider() instanceof EventSetChangeNotifier) {
((EventSetChangeNotifier) getEventProvider())
.removeEventSetChangeListener(this);
}
this.calendarEventProvider = calendarEventProvider;
// add new listener
if (calendarEventProvider instanceof EventSetChangeNotifier) {
((EventSetChangeNotifier) calendarEventProvider)
.addEventSetChangeListener(this);
}
}
/**
* @return the {@link CalendarEventProvider} currently used
*/
public CalendarEventProvider getEventProvider() {
return calendarEventProvider;
}
@Override
public void eventSetChange(EventSetChangeEvent changeEvent) {
// sanity check
if (calendarEventProvider == changeEvent.getProvider()) {
markAsDirty();
}
}
/**
* Set the handler for the given type information. Mirrors
* {@link #addListener(String, Class, Object, Method) addListener} from
* AbstractComponent
*
* @param eventId
* A unique id for the event. Usually one of
* {@link CalendarEventId}
* @param eventType
* The class of the event, most likely a subclass of
* {@link CalendarComponentEvent}
* @param listener
* A listener that listens to the given event
* @param listenerMethod
* The method on the lister to call when the event is triggered
*/
protected void setHandler(String eventId, Class> eventType,
EventListener listener, Method listenerMethod) {
if (handlers.get(eventId) != null) {
removeListener(eventId, eventType, handlers.get(eventId));
handlers.remove(eventId);
}
if (listener != null) {
addListener(eventId, eventType, listener, listenerMethod);
handlers.put(eventId, listener);
}
}
@Override
public void setHandler(ForwardHandler listener) {
setHandler(ForwardEvent.EVENT_ID, ForwardEvent.class, listener,
ForwardHandler.forwardMethod);
}
@Override
public void setHandler(BackwardHandler listener) {
setHandler(BackwardEvent.EVENT_ID, BackwardEvent.class, listener,
BackwardHandler.backwardMethod);
}
@Override
public void setHandler(DateClickHandler listener) {
setHandler(DateClickEvent.EVENT_ID, DateClickEvent.class, listener,
DateClickHandler.dateClickMethod);
}
@Override
public void setHandler(EventClickHandler listener) {
setHandler(EventClick.EVENT_ID, EventClick.class, listener,
EventClickHandler.eventClickMethod);
}
@Override
public void setHandler(WeekClickHandler listener) {
setHandler(WeekClick.EVENT_ID, WeekClick.class, listener,
WeekClickHandler.weekClickMethod);
}
@Override
public void setHandler(EventResizeHandler listener) {
setHandler(EventResize.EVENT_ID, EventResize.class, listener,
EventResizeHandler.eventResizeMethod);
}
@Override
public void setHandler(RangeSelectHandler listener) {
setHandler(RangeSelectEvent.EVENT_ID, RangeSelectEvent.class, listener,
RangeSelectHandler.rangeSelectMethod);
}
@Override
public void setHandler(EventMoveHandler listener) {
setHandler(MoveEvent.EVENT_ID, MoveEvent.class, listener,
EventMoveHandler.eventMoveMethod);
}
@Override
public EventListener getHandler(String eventId) {
return handlers.get(eventId);
}
/**
* Get the currently active drop handler
*/
@Override
public DropHandler getDropHandler() {
return dropHandler;
}
/**
* Set the drop handler for the calendar See {@link DropHandler} for
* implementation details.
*
* @param dropHandler
* The drop handler to set
*/
public void setDropHandler(DropHandler dropHandler) {
this.dropHandler = dropHandler;
}
@Override
public TargetDetails translateDropTargetDetails(
Map
* The {@link Handler#getActions(Object, Object)} parameters depend on what
* view the Calendar is in:
*
* The {@link Handler#handleAction(Action, Object, Object)} parameters
* depend on what the context menu is called upon:
* setTimeFormat(TimeFormat.Format12H);
* Set to null, if you want the format being defined by the locale.
*
* @param format
* Set 12h or 24h format. Default is defined by the locale.
*/
public void setTimeFormat(TimeFormat format) {
currentTimeFormat = format;
markAsDirty();
}
/**
* Returns a time zone that is currently used by this component.
*
* @return Component's Time zone
*/
public TimeZone getTimeZone() {
if (timezone == null) {
return currentCalendar.getTimeZone();
}
return timezone;
}
/**
* Set time zone that this component will use. Null value sets the default
* time zone.
*
* @param zone
* Time zone to use
*/
public void setTimeZone(TimeZone zone) {
timezone = zone;
if (!currentCalendar.getTimeZone().equals(zone)) {
if (zone == null) {
zone = TimeZone.getDefault();
}
currentCalendar.setTimeZone(zone);
df_date_time.setTimeZone(zone);
markAsDirty();
}
}
/**
* Get the internally used Calendar instance. This is the currently used
* instance of {@link java.util.Calendar} but is bound to change during the
* lifetime of the component.
*
* @return the currently used java calendar
*/
public java.util.Calendar getInternalCalendar() {
return currentCalendar;
}
/**
* Calendar.setEventProvider(new ContainerEventProvider(container))
*
* Use this method if you are adding a container which uses the default
* property ids like {@link BeanItemContainer} for instance. If you are
* using custom properties instead use
* {@link Calendar#setContainerDataSource(Container.Indexed, Object, Object, Object, Object, Object)}
*
* Please note that the container must be sorted by date!
*
* @param container
* The container to use as a datasource
*/
public void setContainerDataSource(Container.Indexed container) {
ContainerEventProvider provider = new ContainerEventProvider(container);
provider.addEventSetChangeListener(
new CalendarEventProvider.EventSetChangeListener() {
@Override
public void eventSetChange(
EventSetChangeEvent changeEvent) {
// Repaint if events change
markAsDirty();
}
});
provider.addEventChangeListener(new EventChangeListener() {
@Override
public void eventChange(EventChangeEvent changeEvent) {
// Repaint if event changes
markAsDirty();
}
});
setEventProvider(provider);
}
/**
* Sets a container as a data source for the events in the calendar.
* Equivalent for doing
* Calendar.setEventProvider(new ContainerEventProvider(container))
*
* Please note that the container must be sorted by date!
*
* @param container
* The container to use as a data source
* @param captionProperty
* The property that has the caption, null if no caption property
* is present
* @param descriptionProperty
* The property that has the description, null if no description
* property is present
* @param startDateProperty
* The property that has the starting date
* @param endDateProperty
* The property that has the ending date
* @param styleNameProperty
* The property that has the stylename, null if no stylname
* property is present
*/
public void setContainerDataSource(Container.Indexed container,
Object captionProperty, Object descriptionProperty,
Object startDateProperty, Object endDateProperty,
Object styleNameProperty) {
ContainerEventProvider provider = new ContainerEventProvider(container);
provider.setCaptionProperty(captionProperty);
provider.setDescriptionProperty(descriptionProperty);
provider.setStartDateProperty(startDateProperty);
provider.setEndDateProperty(endDateProperty);
provider.setStyleNameProperty(styleNameProperty);
provider.addEventSetChangeListener(
new CalendarEventProvider.EventSetChangeListener() {
@Override
public void eventSetChange(
EventSetChangeEvent changeEvent) {
// Repaint if events change
markAsDirty();
}
});
provider.addEventChangeListener(new EventChangeListener() {
@Override
public void eventChange(EventChangeEvent changeEvent) {
// Repaint if event changes
markAsDirty();
}
});
setEventProvider(provider);
}
@Override
public List
*
* The Dates passed into the {@link CalendarDateRange} are in the same
* timezone as the calendar is.
*
*
*
* If set to true, the captions are rendered in the browser as HTML and the * developer is responsible for ensuring no harmful HTML is used. If set to * false, the caption is rendered in the browser as plain text. *
* The default is false, i.e. to render that caption as plain text. * * @param captionAsHtml * true if the captions are rendered as HTML, false if rendered * as plain text */ public void setEventCaptionAsHtml(boolean eventCaptionAsHtml) { getState().eventCaptionAsHtml = eventCaptionAsHtml; } /** * Checks whether event captions are rendered as HTML *
* The default is false, i.e. to render that caption as plain text.
*
* @return true if the captions are rendered as HTML, false if rendered as
* plain text
*/
public boolean isEventCaptionAsHtml() {
return getState(false).eventCaptionAsHtml;
}
@Override
public void readDesign(Element design, DesignContext designContext) {
super.readDesign(design, designContext);
Attributes attr = design.attributes();
if (design.hasAttr("time-format")) {
setTimeFormat(TimeFormat.valueOf(
"Format" + design.attr("time-format").toUpperCase()));
}
if (design.hasAttr("start-date")) {
setStartDate(DesignAttributeHandler.readAttribute("start-date",
attr, Date.class));
}
if (design.hasAttr("end-date")) {
setEndDate(DesignAttributeHandler.readAttribute("end-date", attr,
Date.class));
}
};
@Override
public void writeDesign(Element design, DesignContext designContext) {
super.writeDesign(design, designContext);
if (currentTimeFormat != null) {
design.attr("time-format",
currentTimeFormat == TimeFormat.Format12H ? "12h" : "24h");
}
if (startDate != null) {
design.attr("start-date", df_date.format(getStartDate()));
}
if (endDate != null) {
design.attr("end-date", df_date.format(getEndDate()));
}
if (!getTimeZone().equals(TimeZone.getDefault())) {
design.attr("time-zone", getTimeZone().getID());
}
}
@Override
protected Collection