summaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
authorJohn Ahlroos <john@vaadin.com>2013-03-27 16:33:28 +0200
committerVaadin Code Review <review@vaadin.com>2013-04-03 08:03:37 +0000
commit217ba18e53a8607a9e2480574ec1c3da11f4037f (patch)
tree2c38b306985b77144e0797e8bc83d386c8575aa3 /server/src
parent1d25d6d6427f94e93e3bf7417aa968aaa9673dab (diff)
downloadvaadin-framework-217ba18e53a8607a9e2480574ec1c3da11f4037f.tar.gz
vaadin-framework-217ba18e53a8607a9e2480574ec1c3da11f4037f.zip
Integrate Calendar into core #11079
Everything else integrated, except TB3 tests (ticket #11090, old TB2 tests used instead) Change-Id: If1700d7680a6c0a45f84d6e3c7b80e6536da78c8
Diffstat (limited to 'server/src')
-rw-r--r--server/src/com/vaadin/ui/Calendar.java1822
-rw-r--r--server/src/com/vaadin/ui/components/calendar/CalendarComponentEvent.java51
-rw-r--r--server/src/com/vaadin/ui/components/calendar/CalendarComponentEvents.java603
-rw-r--r--server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java86
-rw-r--r--server/src/com/vaadin/ui/components/calendar/CalendarTargetDetails.java80
-rw-r--r--server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java566
-rw-r--r--server/src/com/vaadin/ui/components/calendar/event/BasicEvent.java251
-rw-r--r--server/src/com/vaadin/ui/components/calendar/event/BasicEventProvider.java173
-rw-r--r--server/src/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java40
-rw-r--r--server/src/com/vaadin/ui/components/calendar/event/CalendarEvent.java146
-rw-r--r--server/src/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java112
-rw-r--r--server/src/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java91
-rw-r--r--server/src/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java78
-rw-r--r--server/src/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java69
-rw-r--r--server/src/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java73
-rw-r--r--server/src/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java69
-rw-r--r--server/src/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java76
-rw-r--r--server/src/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java81
18 files changed, 4467 insertions, 0 deletions
diff --git a/server/src/com/vaadin/ui/Calendar.java b/server/src/com/vaadin/ui/Calendar.java
new file mode 100644
index 0000000000..4bf2885a8c
--- /dev/null
+++ b/server/src/com/vaadin/ui/Calendar.java
@@ -0,0 +1,1822 @@
+/*
+ * Copyright 2000-2013 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.Date;
+import java.util.EventListener;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+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 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.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;
+
+/**
+ * <p>
+ * 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.
+ * </p>
+ *
+ * <li>You can set the viewable date range with the {@link #setStartDate(Date)}
+ * and {@link #setEndDate(Date)} methods. Calendar has a default date range of
+ * one week</li>
+ *
+ * <li>Calendar has two kind of views: monthly and weekly view</li>
+ *
+ * <li>If date range is seven days or shorter, the weekly view is used.</li>
+ *
+ * <li>Calendar queries its events by using a
+ * {@link com.vaadin.addon.calendar.event.CalendarEventProvider
+ * CalendarEventProvider}. By default, a
+ * {@link com.vaadin.addon.calendar.event.BasicEventProvider BasicEventProvider}
+ * is used.</li>
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class Calendar extends AbstractComponent implements
+ CalendarComponentEvents.NavigationNotifier,
+ CalendarComponentEvents.EventMoveNotifier,
+ CalendarComponentEvents.RangeSelectNotifier,
+ CalendarComponentEvents.EventResizeNotifier,
+ CalendarEventProvider.EventSetChangeListener, DropTarget,
+ CalendarEditableEventProvider, Action.Container {
+
+ /**
+ * Calendar can use either 12 hours clock or 24 hours clock.
+ */
+ public enum TimeFormat {
+
+ Format12H(), Format24H();
+ }
+
+ /** Defines currently active format for time. 12H/24H. */
+ protected TimeFormat currentTimeFormat;
+
+ /** Internal calendar data source. */
+ protected java.util.Calendar currentCalendar = java.util.Calendar
+ .getInstance();
+
+ /** Defines the component's active time zone. */
+ protected TimeZone timezone;
+
+ /** Defines the calendar's date range starting point. */
+ protected Date startDate = null;
+
+ /** Defines the calendar's date range ending point. */
+ protected Date endDate = null;
+
+ /** Event provider. */
+ private CalendarEventProvider calendarEventProvider;
+
+ /**
+ * Internal buffer for the events that are retrieved from the event
+ * provider.
+ */
+ protected List<CalendarEvent> events;
+
+ /** Date format that will be used in the UIDL for dates. */
+ protected DateFormat df_date = new SimpleDateFormat("yyyy-MM-dd");
+
+ /** Time format that will be used in the UIDL for time. */
+ protected DateFormat df_time = new SimpleDateFormat("HH:mm:ss");
+
+ /** Date format that will be used in the UIDL for both date and time. */
+ protected DateFormat df_date_time = new SimpleDateFormat(
+ DateConstants.CLIENT_DATE_FORMAT + "-"
+ + DateConstants.CLIENT_TIME_FORMAT);
+
+ /**
+ * Week view's scroll position. Client sends updates to this value so that
+ * scroll position wont reset all the time.
+ */
+ private int scrollTop = 0;
+
+ /** Caption format for the weekly view */
+ private String weeklyCaptionFormat = null;
+
+ /** Map from event ids to event handlers */
+ private final Map<String, EventListener> handlers;
+
+ /**
+ * Drop Handler for Vaadin DD. By default null.
+ */
+ private DropHandler dropHandler;
+
+ /**
+ * First day to show for a week
+ */
+ private int firstDay = 1;
+
+ /**
+ * Last day to show for a week
+ */
+ private int lastDay = 7;
+
+ /**
+ * First hour to show for a day
+ */
+ private int firstHour = 0;
+
+ /**
+ * Last hour to show for a day
+ */
+ private int lastHour = 23;
+
+ /**
+ * List of action handlers.
+ */
+ private LinkedList<Action.Handler> actionHandlers = null;
+
+ /**
+ * Action mapper.
+ */
+ private KeyMapper<Action> actionMapper = null;
+
+ /**
+ *
+ */
+ private CalendarServerRpcImpl rpc = new CalendarServerRpcImpl();
+
+ /**
+ * Returns the logger for the calendar
+ */
+ protected Logger getLogger() {
+ return Logger.getLogger(Calendar.class.getName());
+ }
+
+ /**
+ * Construct a Vaadin Calendar with a BasicEventProvider and no caption.
+ * Default date range is one week.
+ */
+ public Calendar() {
+ this(null, new BasicEventProvider());
+ }
+
+ /**
+ * Construct a Vaadin Calendar with a BasicEventProvider and the provided
+ * caption. Default date range is one week.
+ *
+ * @param caption
+ */
+ public Calendar(String caption) {
+ this(caption, new BasicEventProvider());
+ }
+
+ /**
+ * <p>
+ * Construct a Vaadin Calendar with event provider. Event provider is
+ * obligatory, because calendar component will query active events through
+ * it.
+ * </p>
+ *
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @param eventProvider
+ * Event provider, cannot be null.
+ */
+ public Calendar(CalendarEventProvider eventProvider) {
+ this(null, eventProvider);
+ }
+
+ /**
+ * <p>
+ * Construct a Vaadin Calendar with event provider and a caption. Event
+ * provider is obligatory, because calendar component will query active
+ * events through it.
+ * </p>
+ *
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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 HashMap<String, EventListener>();
+ setDefaultHandlers();
+ currentCalendar.setTime(new Date());
+ setEventProvider(eventProvider);
+ getState().firstDayOfWeek = firstDay;
+ getState().lastVisibleDayOfWeek = lastDay;
+ getState().firstHourOfDay = firstHour;
+ getState().lastHourOfDay = lastHour;
+ setTimeFormat(null);
+
+ }
+
+ @Override
+ public CalendarState getState() {
+ return (CalendarState) super.getState();
+ }
+
+ @Override
+ public void beforeClientResponse(boolean initial) {
+ super.beforeClientResponse(initial);
+
+ initCalendarWithLocale();
+
+ getState().format24H = TimeFormat.Format24H == getTimeFormat();
+ setupDaysAndActions();
+ setupCalendarEvents();
+ rpc.scroll(scrollTop);
+ }
+
+ /**
+ * Set all the wanted default handlers here. This is always called after
+ * constructing this object. All other events have default handlers except
+ * range and event click.
+ */
+ protected void setDefaultHandlers() {
+ setHandler(new BasicBackwardHandler());
+ setHandler(new BasicForwardHandler());
+ setHandler(new BasicWeekClickHandler());
+ setHandler(new BasicDateClickHandler());
+ setHandler(new BasicEventMoveHandler());
+ setHandler(new BasicEventResizeHandler());
+ }
+
+ /**
+ * Gets the calendar's start date.
+ *
+ * @return First visible date.
+ */
+ public Date getStartDate() {
+ if (startDate == null) {
+ currentCalendar.set(java.util.Calendar.DAY_OF_WEEK,
+ currentCalendar.getFirstDayOfWeek());
+ return currentCalendar.getTime();
+ }
+ return startDate;
+ }
+
+ /**
+ * Sets start date for the calendar. This and {@link #setEndDate(Date)}
+ * control the range of dates visible on the component. The default range is
+ * one week.
+ *
+ * @param date
+ * First visible date to show.
+ */
+ public void setStartDate(Date date) {
+ if (!date.equals(startDate)) {
+ startDate = date;
+ markAsDirty();
+ }
+ }
+
+ /**
+ * Gets the calendar's end date.
+ *
+ * @return Last visible date.
+ */
+ public Date getEndDate() {
+ if (endDate == null) {
+ currentCalendar.set(java.util.Calendar.DAY_OF_WEEK,
+ currentCalendar.getFirstDayOfWeek() + 6);
+ return currentCalendar.getTime();
+ }
+ return endDate;
+ }
+
+ /**
+ * Sets end date for the calendar. Starting from startDate, only six weeks
+ * will be shown if duration to endDate is longer than six weeks.
+ *
+ * This and {@link #setStartDate(Date)} control the range of dates visible
+ * on the component. The default range is one week.
+ *
+ * @param date
+ * Last visible date to show.
+ */
+ public void setEndDate(Date date) {
+ if (startDate != null && startDate.after(date)) {
+ startDate = (Date) date.clone();
+ markAsDirty();
+ } else if (!date.equals(endDate)) {
+ endDate = date;
+ markAsDirty();
+ }
+ }
+
+ /**
+ * Sets the locale to be used in the Calendar component.
+ *
+ * @see com.vaadin.ui.AbstractComponent#setLocale(java.util.Locale)
+ */
+ @Override
+ public void setLocale(Locale newLocale) {
+ super.setLocale(newLocale);
+ initCalendarWithLocale();
+ }
+
+ /**
+ * Initialize the java calendar instance with the current locale and
+ * timezone.
+ */
+ private void initCalendarWithLocale() {
+ if (timezone != null) {
+ currentCalendar = java.util.Calendar.getInstance(timezone,
+ getLocale());
+
+ } else {
+ currentCalendar = java.util.Calendar.getInstance(getLocale());
+ }
+ }
+
+ private void setupCalendarEvents() {
+ int durationInDays = (int) (((endDate.getTime()) - startDate.getTime()) / DateConstants.DAYINMILLIS);
+ durationInDays++;
+ if (durationInDays > 60) {
+ throw new RuntimeException("Daterange is too big (max 60) = "
+ + durationInDays);
+ }
+
+ Date firstDateToShow = expandStartDate(startDate, durationInDays > 7);
+ Date lastDateToShow = expandEndDate(endDate, durationInDays > 7);
+
+ currentCalendar.setTime(firstDateToShow);
+ events = getEventProvider().getEvents(firstDateToShow, lastDateToShow);
+
+ List<CalendarState.Event> calendarStateEvents = new ArrayList<CalendarState.Event>();
+ if (events != null) {
+ for (int i = 0; i < events.size(); i++) {
+ CalendarEvent e = events.get(i);
+ CalendarState.Event event = new CalendarState.Event();
+ event.index = i;
+ event.caption = e.getCaption() == null ? "" : e.getCaption();
+ event.dateFrom = df_date.format(e.getStart());
+ event.dateTo = df_date.format(e.getEnd());
+ event.timeFrom = df_time.format(e.getStart());
+ event.timeTo = df_time.format(e.getEnd());
+ event.description = e.getDescription() == null ? "" : e
+ .getDescription();
+ event.styleName = e.getStyleName() == null ? "" : e
+ .getStyleName();
+ event.allDay = e.isAllDay();
+ calendarStateEvents.add(event);
+ }
+ }
+ getState().events = calendarStateEvents;
+ }
+
+ 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<CalendarDateRange, Set<Action>> actionMap = new HashMap<CalendarDateRange, Set<Action>>();
+
+ List<CalendarState.Day> days = new ArrayList<CalendarState.Day>();
+
+ // Send all dates to client from server. This
+ // approach was taken because gwt doesn't
+ // support date localization properly.
+ while (currentCalendar.getTime().compareTo(lastDateToShow) < 1) {
+ final Date date = currentCalendar.getTime();
+ final CalendarState.Day day = new CalendarState.Day();
+ day.date = df_date.format(date);
+ day.localizedDateFormat = weeklyCaptionFormatter.format(date);
+ day.dayOfWeek = getDowByLocale(currentCalendar);
+ day.week = currentCalendar.get(java.util.Calendar.WEEK_OF_YEAR);
+
+ days.add(day);
+
+ // Get actions for a specific date
+ if (actionHandlers != null) {
+ for (Action.Handler actionHandler : actionHandlers) {
+
+ // Create calendar which omits time
+ GregorianCalendar cal = new GregorianCalendar(
+ getTimeZone(), getLocale());
+ cal.clear();
+ cal.set(currentCalendar.get(java.util.Calendar.YEAR),
+ currentCalendar.get(java.util.Calendar.MONTH),
+ currentCalendar.get(java.util.Calendar.DATE));
+
+ // Get day start and end times
+ Date start = cal.getTime();
+ cal.add(java.util.Calendar.DATE, 1);
+ Date end = cal.getTime();
+
+ boolean monthView = (durationInDays > 7);
+
+ /**
+ * If in day or week view add actions for each half-an-hour.
+ * If in month view add actions for each day
+ */
+ if (monthView) {
+ setActionsForDay(actionMap, start, end, actionHandler);
+ } else {
+ setActionsForEachHalfHour(actionMap, start, end,
+ actionHandler);
+ }
+
+ }
+ }
+
+ currentCalendar.add(java.util.Calendar.DATE, 1);
+ }
+ state.days = days;
+ state.actions = createActionsList(actionMap);
+ }
+
+ private void setActionsForEachHalfHour(
+ Map<CalendarDateRange, Set<Action>> actionMap, Date start,
+ Date end, Action.Handler actionHandler) {
+ GregorianCalendar cal = new GregorianCalendar(getTimeZone(),
+ getLocale());
+ cal.setTime(start);
+ while (cal.getTime().before(end)) {
+ Date s = cal.getTime();
+ cal.add(java.util.Calendar.MINUTE, 30);
+ Date e = cal.getTime();
+ CalendarDateRange range = new CalendarDateRange(s, e, getTimeZone());
+ Action[] actions = actionHandler.getActions(range, this);
+ if (actions != null) {
+ Set<Action> actionSet = new HashSet<Action>(
+ Arrays.asList(actions));
+ actionMap.put(range, actionSet);
+ }
+ }
+ }
+
+ private void setActionsForDay(
+ Map<CalendarDateRange, Set<Action>> actionMap, Date start,
+ Date end, Action.Handler actionHandler) {
+ CalendarDateRange range = new CalendarDateRange(start, end,
+ getTimeZone());
+ Action[] actions = actionHandler.getActions(range, this);
+ if (actions != null) {
+ Set<Action> actionSet = new HashSet<Action>(Arrays.asList(actions));
+ actionMap.put(range, actionSet);
+ }
+ }
+
+ private List<CalendarState.Action> createActionsList(
+ Map<CalendarDateRange, Set<Action>> actionMap) {
+ if (actionMap.isEmpty()) {
+ return null;
+ }
+
+ List<CalendarState.Action> calendarActions = new ArrayList<CalendarState.Action>();
+
+ SimpleDateFormat formatter = new SimpleDateFormat(
+ DateConstants.ACTION_DATE_FORMAT_PATTERN);
+ formatter.setTimeZone(getTimeZone());
+
+ for (Entry<CalendarDateRange, Set<Action>> entry : actionMap.entrySet()) {
+ CalendarDateRange range = entry.getKey();
+ Set<Action> actions = entry.getValue();
+ for (Action action : actions) {
+ String key = actionMapper.key(action);
+ CalendarState.Action calendarAction = new CalendarState.Action();
+ calendarAction.actionKey = key;
+ calendarAction.caption = action.getCaption();
+ setResource(key, action.getIcon());
+ calendarAction.iconKey = key;
+ calendarAction.startDate = formatter.format(range.getStart());
+ calendarAction.endDate = formatter.format(range.getEnd());
+ calendarActions.add(calendarAction);
+ }
+ }
+
+ return calendarActions;
+ }
+
+ /**
+ * Gets currently active time format. Value is either TimeFormat.Format12H
+ * or TimeFormat.Format24H.
+ *
+ * @return TimeFormat Format for the time.
+ */
+ public TimeFormat getTimeFormat() {
+ if (currentTimeFormat == null) {
+ SimpleDateFormat f = (SimpleDateFormat) SimpleDateFormat
+ .getTimeInstance(SimpleDateFormat.SHORT, getLocale());
+ String p = f.toPattern();
+ if (p.indexOf("HH") != -1 || p.indexOf("H") != -1) {
+ return TimeFormat.Format24H;
+ }
+ return TimeFormat.Format12H;
+ }
+ return currentTimeFormat;
+ }
+
+ /**
+ * Example: <code>setTimeFormat(TimeFormat.Format12H);</code></br> 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;
+ }
+
+ /**
+ * <p>
+ * This method restricts the weekdays that are shown. This affects both the
+ * monthly and the weekly view. The general contract is that <b>firstDay <
+ * lastDay</b>.
+ * </p>
+ *
+ * <p>
+ * Note that this only affects the rendering process. Events are still
+ * requested by the dates set by {@link #setStartDate(Date)} and
+ * {@link #setEndDate(Date)}.
+ * </p>
+ *
+ * @param firstDay
+ * the first day of the week to show, between 1 and 7
+ */
+ public void setFirstVisibleDayOfWeek(int firstDay) {
+ if (this.firstDay != firstDay && firstDay >= 1 && firstDay <= 7
+ && getLastVisibleDayOfWeek() >= firstDay) {
+ this.firstDay = firstDay;
+ getState().firstVisibleDayOfWeek = firstDay;
+ }
+ }
+
+ /**
+ * Get the first visible day of the week. Returns the weekdays as integers
+ * represented by {@link java.util.Calendar#DAY_OF_WEEK}
+ *
+ * @return An integer representing the week day according to
+ * {@link java.util.Calendar#DAY_OF_WEEK}
+ */
+ public int getFirstVisibleDayOfWeek() {
+ return firstDay;
+ }
+
+ /**
+ * <p>
+ * This method restricts the weekdays that are shown. This affects both the
+ * monthly and the weekly view. The general contract is that <b>firstDay <
+ * lastDay</b>.
+ * </p>
+ *
+ * <p>
+ * Note that this only affects the rendering process. Events are still
+ * requested by the dates set by {@link #setStartDate(Date)} and
+ * {@link #setEndDate(Date)}.
+ * </p>
+ *
+ * @param lastDay
+ * the first day of the week to show, between 1 and 7
+ */
+ public void setLastVisibleDayOfWeek(int lastDay) {
+ if (this.lastDay != lastDay && lastDay >= 1 && lastDay <= 7
+ && getFirstVisibleDayOfWeek() <= lastDay) {
+ this.lastDay = lastDay;
+ getState().lastVisibleDayOfWeek = lastDay;
+ }
+ }
+
+ /**
+ * Get the last visible day of the week. Returns the weekdays as integers
+ * represented by {@link java.util.Calendar#DAY_OF_WEEK}
+ *
+ * @return An integer representing the week day according to
+ * {@link java.util.Calendar#DAY_OF_WEEK}
+ */
+ public int getLastVisibleDayOfWeek() {
+ return lastDay;
+ }
+
+ /**
+ * <p>
+ * This method restricts the hours that are shown per day. This affects the
+ * weekly view. The general contract is that <b>firstHour < lastHour</b>.
+ * </p>
+ *
+ * <p>
+ * Note that this only affects the rendering process. Events are still
+ * requested by the dates set by {@link #setStartDate(Date)} and
+ * {@link #setEndDate(Date)}.
+ * </p>
+ *
+ * @param firstHour
+ * the first hour of the day to show, between 0 and 23
+ */
+ 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;
+ }
+
+ /**
+ * <p>
+ * This method restricts the hours that are shown per day. This affects the
+ * weekly view. The general contract is that <b>firstHour < lastHour</b>.
+ * </p>
+ *
+ * <p>
+ * Note that this only affects the rendering process. Events are still
+ * requested by the dates set by {@link #setStartDate(Date)} and
+ * {@link #setEndDate(Date)}.
+ * </p>
+ *
+ * @param lastHour
+ * the first hour of the day to show, between 0 and 23
+ */
+ 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() && isEnabled();
+ }
+
+ /**
+ * Is the user allowed to trigger click events
+ *
+ * @return true if the client is allowed to click events
+ * @see #isClientChangeAllowed()
+ */
+ protected boolean isEventClickAllowed() {
+ return isEnabled();
+ }
+
+ /**
+ * 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 com.vaadin.addon.calendar.event.CalendarEventProvider
+ * 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 com.vaadin.addon.calendar.event.BasicEventProvider
+ * 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 com.vaadin.addon.calendar.event.CalendarEventProvider
+ * CalendarEventProvider} currently used
+ */
+ public CalendarEventProvider getEventProvider() {
+ return calendarEventProvider;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarEvents.EventChangeListener#eventChange
+ * (com.vaadin.addon.calendar.ui.CalendarEvents.EventChange)
+ */
+ 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);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardHandler)
+ */
+ public void setHandler(ForwardHandler listener) {
+ setHandler(ForwardEvent.EVENT_ID, ForwardEvent.class, listener,
+ ForwardHandler.forwardMethod);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardHandler)
+ */
+ public void setHandler(BackwardHandler listener) {
+ setHandler(BackwardEvent.EVENT_ID, BackwardEvent.class, listener,
+ BackwardHandler.backwardMethod);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.DateClickHandler)
+ */
+ public void setHandler(DateClickHandler listener) {
+ setHandler(DateClickEvent.EVENT_ID, DateClickEvent.class, listener,
+ DateClickHandler.dateClickMethod);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventClickHandler)
+ */
+ public void setHandler(EventClickHandler listener) {
+ setHandler(EventClick.EVENT_ID, EventClick.class, listener,
+ EventClickHandler.eventClickMethod);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClickHandler)
+ */
+ public void setHandler(WeekClickHandler listener) {
+ setHandler(WeekClick.EVENT_ID, WeekClick.class, listener,
+ WeekClickHandler.weekClickMethod);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeHandler
+ * )
+ */
+ public void setHandler(EventResizeHandler listener) {
+ setHandler(EventResize.EVENT_ID, EventResize.class, listener,
+ EventResizeHandler.eventResizeMethod);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.RangeSelectNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.RangeSelectHandler
+ * )
+ */
+ public void setHandler(RangeSelectHandler listener) {
+ setHandler(RangeSelectEvent.EVENT_ID, RangeSelectEvent.class, listener,
+ RangeSelectHandler.rangeSelectMethod);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveHandler)
+ */
+ public void setHandler(EventMoveHandler listener) {
+ setHandler(MoveEvent.EVENT_ID, MoveEvent.class, listener,
+ EventMoveHandler.eventMoveMethod);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.CalendarEventNotifier
+ * #getHandler(java.lang.String)
+ */
+ public EventListener getHandler(String eventId) {
+ return handlers.get(eventId);
+ }
+
+ /**
+ * Get the currently active drop handler
+ */
+ 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;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.event.dd.DropTarget#translateDropTargetDetails(java.util.Map)
+ */
+ public TargetDetails translateDropTargetDetails(
+ Map<String, Object> clientVariables) {
+ Map<String, Object> serverVariables = new HashMap<String, Object>(1);
+
+ if (clientVariables.containsKey("dropSlotIndex")) {
+ int slotIndex = (Integer) clientVariables.get("dropSlotIndex");
+ int dayIndex = (Integer) clientVariables.get("dropDayIndex");
+
+ currentCalendar.setTime(getStartOfDay(currentCalendar, startDate));
+ currentCalendar.add(java.util.Calendar.DATE, dayIndex);
+
+ // change this if slot length is modified
+ currentCalendar.add(java.util.Calendar.MINUTE, slotIndex * 30);
+
+ serverVariables.put("dropTime", currentCalendar.getTime());
+
+ } else {
+ int dayIndex = (Integer) clientVariables.get("dropDayIndex");
+ currentCalendar.setTime(expandStartDate(startDate, true));
+ currentCalendar.add(java.util.Calendar.DATE, dayIndex);
+ serverVariables.put("dropDay", currentCalendar.getTime());
+ }
+
+ CalendarTargetDetails td = new CalendarTargetDetails(serverVariables,
+ this);
+ td.setHasDropTime(clientVariables.containsKey("dropSlotIndex"));
+
+ return td;
+ }
+
+ /**
+ * Sets a container as a data source for the events in the calendar.
+ * Equivalent for doing
+ * <code>Calendar.setEventProvider(new ContainerEventProvider(container))</code>
+ *
+ * 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(com.vaadin.data.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() {
+ public void eventSetChange(EventSetChangeEvent changeEvent) {
+ // Repaint if events change
+ markAsDirty();
+ }
+ });
+ provider.addEventChangeListener(new EventChangeListener() {
+ 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
+ * <code>Calendar.setEventProvider(new ContainerEventProvider(container))</code>
+ *
+ * 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() {
+ public void eventSetChange(EventSetChangeEvent changeEvent) {
+ // Repaint if events change
+ markAsDirty();
+ }
+ });
+ provider.addEventChangeListener(new EventChangeListener() {
+ public void eventChange(EventChangeEvent changeEvent) {
+ // Repaint if event changes
+ markAsDirty();
+ }
+ });
+ setEventProvider(provider);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventProvider#getEvents(java.
+ * util.Date, java.util.Date)
+ */
+ public List<CalendarEvent> getEvents(Date startDate, Date endDate) {
+ return getEventProvider().getEvents(startDate, endDate);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#addEvent
+ * (com.vaadin.addon.calendar.event.CalendarEvent)
+ */
+ public void addEvent(CalendarEvent event) {
+ if (getEventProvider() instanceof CalendarEditableEventProvider) {
+ CalendarEditableEventProvider provider = (CalendarEditableEventProvider) getEventProvider();
+ provider.addEvent(event);
+ markAsDirty();
+ } else {
+ throw new UnsupportedOperationException(
+ "Event provider does not support adding events");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#removeEvent
+ * (com.vaadin.addon.calendar.event.CalendarEvent)
+ */
+ public void removeEvent(CalendarEvent event) {
+ if (getEventProvider() instanceof CalendarEditableEventProvider) {
+ CalendarEditableEventProvider provider = (CalendarEditableEventProvider) getEventProvider();
+ provider.removeEvent(event);
+ markAsDirty();
+ } else {
+ throw new UnsupportedOperationException(
+ "Event provider does not support removing events");
+ }
+ }
+
+ /**
+ * Adds an action handler to the calender that handles event produced by the
+ * context menu.
+ *
+ * <p>
+ * The {@link Handler#getActions(Object, Object)} parameters depend on what
+ * view the Calendar is in:
+ * <ul>
+ * <li>If the Calendar is in <i>Day or Week View</i> then the target
+ * parameter will be a {@link CalendarDateRange} with a range of
+ * half-an-hour. The {@link Handler#getActions(Object, Object)} method will
+ * be called once per half-hour slot.</li>
+ * <li>If the Calendar is in <i>Month View</i> then the target parameter
+ * will be a {@link CalendarDateRange} with a range of one day. The
+ * {@link Handler#getActions(Object, Object)} will be called once for each
+ * day.
+ * </ul>
+ * The Dates passed into the {@link CalendarDateRange} are in the same
+ * timezone as the calendar is.
+ * </p>
+ *
+ * <p>
+ * The {@link Handler#handleAction(Action, Object, Object)} parameters
+ * depend on what the context menu is called upon:
+ * <ul>
+ * <li>If the context menu is called upon an event then the target parameter
+ * is the event, i.e. instanceof {@link CalendarEvent}</li>
+ * <li>If the context menu is called upon an empty slot then the target is a
+ * {@link Date} representing that slot
+ * </ul>
+ * </p>
+ */
+ public void addActionHandler(Handler actionHandler) {
+ if (actionHandler != null) {
+ if (actionHandlers == null) {
+ actionHandlers = new LinkedList<Action.Handler>();
+ actionMapper = new KeyMapper<Action>();
+ }
+ if (!actionHandlers.contains(actionHandler)) {
+ actionHandlers.add(actionHandler);
+ markAsDirty();
+ }
+ }
+ }
+
+ /**
+ * Is the calendar in a mode where all days of the month is shown
+ *
+ * @return Returns true if calendar is in monthly mode and false if it is in
+ * weekly mode
+ */
+ public boolean isMonthlyMode() {
+ CalendarState state = (CalendarState) getState(false);
+ if (state.days != null) {
+ return state.days.size() > 7;
+ } else {
+ // Default mode
+ return true;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.event.Action.Container#removeActionHandler(com.vaadin.event
+ * .Action.Handler)
+ */
+ public void removeActionHandler(Handler actionHandler) {
+ if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
+ actionHandlers.remove(actionHandler);
+ if (actionHandlers.isEmpty()) {
+ actionHandlers = null;
+ actionMapper = null;
+ }
+ markAsDirty();
+ }
+ }
+
+ private class CalendarServerRpcImpl implements CalendarServerRpc {
+
+ @Override
+ public void eventMove(int eventIndex, String newDate) {
+ if (!isClientChangeAllowed()) {
+ return;
+ }
+ if (newDate != null) {
+ try {
+ Date d = df_date_time.parse(newDate);
+ if (eventIndex >= 0 && eventIndex < events.size()
+ && events.get(eventIndex) != null) {
+ fireEventMove(eventIndex, d);
+ }
+ } catch (ParseException e) {
+ getLogger().log(Level.WARNING, e.getMessage());
+ }
+ }
+ }
+
+ @Override
+ public void rangeSelect(String range) {
+ if (!isClientChangeAllowed()) {
+ return;
+ }
+
+ if (range != null && range.length() > 14 && range.contains("TO")) {
+ String[] dates = range.split("TO");
+ try {
+ Date d1 = df_date.parse(dates[0]);
+ Date d2 = df_date.parse(dates[1]);
+
+ fireRangeSelect(d1, d2, true);
+
+ } catch (ParseException e) {
+ // NOP
+ }
+ } else if (range != null && range.length() > 12
+ && range.contains(":")) {
+ String[] dates = range.split(":");
+ if (dates.length == 3) {
+ try {
+ Date d = df_date.parse(dates[0]);
+ currentCalendar.setTime(d);
+ int startMinutes = Integer.parseInt(dates[1]);
+ int endMinutes = Integer.parseInt(dates[2]);
+ currentCalendar.add(java.util.Calendar.MINUTE,
+ startMinutes);
+ Date start = currentCalendar.getTime();
+ currentCalendar.add(java.util.Calendar.MINUTE,
+ endMinutes - startMinutes);
+ Date end = currentCalendar.getTime();
+ fireRangeSelect(start, end, false);
+ } catch (ParseException e) {
+ // NOP
+ } catch (NumberFormatException e) {
+ // NOP
+ }
+ }
+ }
+ }
+
+ @Override
+ public void forward() {
+ fireEvent(new ForwardEvent(Calendar.this));
+ }
+
+ @Override
+ public void backward() {
+ fireEvent(new BackwardEvent(Calendar.this));
+ }
+
+ @Override
+ public void dateClick(String date) {
+ if (!isClientChangeAllowed()) {
+ return;
+ }
+ if (date != null && date.length() > 6) {
+ try {
+ Date d = df_date.parse(date);
+ fireDateClick(d);
+ } catch (ParseException e) {
+ }
+ }
+ }
+
+ @Override
+ public void weekClick(String event) {
+ if (!isClientChangeAllowed()) {
+ return;
+ }
+ if (event.length() > 0 && event.contains("w")) {
+ String[] splitted = event.split("w");
+ if (splitted.length == 2) {
+ try {
+ int yr = 1900 + Integer.parseInt(splitted[0]);
+ int week = Integer.parseInt(splitted[1]);
+ fireWeekClick(week, yr);
+ } catch (NumberFormatException e) {
+ // NOP
+ }
+ }
+ }
+ }
+
+ @Override
+ public void eventClick(int eventIndex) {
+ if (!isEventClickAllowed()) {
+ return;
+ }
+ if (eventIndex >= 0 && eventIndex < events.size()
+ && events.get(eventIndex) != null) {
+ fireEventClick(eventIndex);
+ }
+ }
+
+ @Override
+ public void eventResize(int eventIndex, String newStartDate,
+ String newEndDate) {
+ if (!isClientChangeAllowed()) {
+ return;
+ }
+ if (newStartDate != null && !"".equals(newStartDate)
+ && newEndDate != null && !"".equals(newEndDate)) {
+ try {
+ Date newStartTime = df_date_time.parse(newStartDate);
+ Date newEndTime = df_date_time.parse(newEndDate);
+
+ fireEventResize(eventIndex, newStartTime, newEndTime);
+ } catch (ParseException e) {
+ // NOOP
+ }
+ }
+ }
+
+ @Override
+ public void scroll(int scrollPosition) {
+ scrollTop = scrollPosition;
+ markAsDirty();
+ }
+
+ @Override
+ public void actionOnEmptyCell(String actionKey, String startDate,
+ String endDate) {
+ Action action = actionMapper.get(actionKey);
+ SimpleDateFormat formatter = new SimpleDateFormat(
+ DateConstants.ACTION_DATE_FORMAT_PATTERN);
+ formatter.setTimeZone(getTimeZone());
+ try {
+ Date start = formatter.parse(startDate);
+ for (Action.Handler ah : actionHandlers) {
+ ah.handleAction(action, this, start);
+ }
+
+ } catch (ParseException e) {
+ getLogger().log(Level.WARNING,
+ "Could not parse action date string");
+ }
+
+ }
+
+ @Override
+ public void actionOnEvent(String actionKey, String startDate,
+ String endDate, int eventIndex) {
+ Action action = actionMapper.get(actionKey);
+ SimpleDateFormat formatter = new SimpleDateFormat(
+ DateConstants.ACTION_DATE_FORMAT_PATTERN);
+ formatter.setTimeZone(getTimeZone());
+ for (Action.Handler ah : actionHandlers) {
+ ah.handleAction(action, this, events.get(eventIndex));
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvent.java b/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvent.java
new file mode 100644
index 0000000000..1f012157b5
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvent.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2013 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.components.calendar;
+
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.Component;
+
+/**
+ * All Calendar events extends this class.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ *
+ */
+@SuppressWarnings("serial")
+public class CalendarComponentEvent extends Component.Event {
+
+ /**
+ * Set the source of the event
+ *
+ * @param source
+ * The source calendar
+ *
+ */
+ public CalendarComponentEvent(Calendar source) {
+ super(source);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.Component.Event#getComponent()
+ */
+ @Override
+ public Calendar getComponent() {
+ return (Calendar) super.getComponent();
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvents.java b/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvents.java
new file mode 100644
index 0000000000..1904d69898
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/CalendarComponentEvents.java
@@ -0,0 +1,603 @@
+/*
+ * Copyright 2000-2013 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.components.calendar;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.EventListener;
+
+import com.vaadin.shared.ui.calendar.CalendarEventId;
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+import com.vaadin.util.ReflectTools;
+
+/**
+ * Interface for all Vaadin Calendar events.
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ */
+public interface CalendarComponentEvents extends Serializable {
+
+ /**
+ * Notifier interface for notifying listener of calendar events
+ */
+ public interface CalendarEventNotifier extends Serializable {
+ /**
+ * Get the assigned event handler for the given eventId.
+ *
+ * @param eventId
+ * @return the assigned eventHandler, or null if no handler is assigned
+ */
+ public EventListener getHandler(String eventId);
+ }
+
+ /**
+ * Notifier interface for event drag & drops.
+ */
+ public interface EventMoveNotifier extends CalendarEventNotifier {
+
+ /**
+ * Set the EventMoveHandler.
+ *
+ * @param listener
+ * EventMoveHandler to be added
+ */
+ public void setHandler(EventMoveHandler listener);
+
+ }
+
+ /**
+ * MoveEvent is sent when existing event is dragged to a new position.
+ */
+ @SuppressWarnings("serial")
+ public class MoveEvent extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.EVENTMOVE;
+
+ /** Index for the moved Schedule.Event. */
+ private CalendarEvent calendarEvent;
+
+ /** New starting date for the moved Calendar.Event. */
+ private Date newStart;
+
+ /**
+ * MoveEvent needs the target event and new start date.
+ *
+ * @param source
+ * Calendar component.
+ * @param calendarEvent
+ * Target event.
+ * @param newStart
+ * Target event's new start date.
+ */
+ public MoveEvent(Calendar source, CalendarEvent calendarEvent,
+ Date newStart) {
+ super(source);
+
+ this.calendarEvent = calendarEvent;
+ this.newStart = newStart;
+ }
+
+ /**
+ * Get target event.
+ *
+ * @return Target event.
+ */
+ public CalendarEvent getCalendarEvent() {
+ return calendarEvent;
+ }
+
+ /**
+ * Get new start date.
+ *
+ * @return New start date.
+ */
+ public Date getNewStart() {
+ return newStart;
+ }
+ }
+
+ /**
+ * Handler interface for when events are being dragged on the calendar
+ *
+ */
+ public interface EventMoveHandler extends EventListener, Serializable {
+
+ /** Trigger method for the MoveEvent. */
+ public static final Method eventMoveMethod = ReflectTools.findMethod(
+ EventMoveHandler.class, "eventMove", MoveEvent.class);
+
+ /**
+ * This method will be called when event has been moved to a new
+ * position.
+ *
+ * @param event
+ * MoveEvent containing specific information of the new
+ * position and target event.
+ */
+ public void eventMove(MoveEvent event);
+ }
+
+ /**
+ * Handler interface for day or time cell drag-marking with mouse.
+ */
+ public interface RangeSelectNotifier extends Serializable,
+ CalendarEventNotifier {
+
+ /**
+ * Set the RangeSelectHandler that listens for drag-marking.
+ *
+ * @param listener
+ * RangeSelectHandler to be added.
+ */
+ public void setHandler(RangeSelectHandler listener);
+ }
+
+ /**
+ * RangeSelectEvent is sent when day or time cells are drag-marked with
+ * mouse.
+ */
+ @SuppressWarnings("serial")
+ public class RangeSelectEvent extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.RANGESELECT;
+
+ /** Calendar event's start date. */
+ private Date start;
+
+ /** Calendar event's end date. */
+ private Date end;
+
+ /**
+ * Defines the event's view mode.
+ */
+ private boolean monthlyMode;
+
+ /**
+ * RangeSelectEvent needs a start and end date.
+ *
+ * @param source
+ * Calendar component.
+ * @param start
+ * Start date.
+ * @param end
+ * End date.
+ * @param monthlyMode
+ * Calendar view mode.
+ */
+ public RangeSelectEvent(Calendar source, Date start, Date end,
+ boolean monthlyMode) {
+ super(source);
+ this.start = start;
+ this.end = end;
+ this.monthlyMode = monthlyMode;
+ }
+
+ /**
+ * Get start date.
+ *
+ * @return Start date.
+ */
+ public Date getStart() {
+ return start;
+ }
+
+ /**
+ * Get end date.
+ *
+ * @return End date.
+ */
+ public Date getEnd() {
+ return end;
+ }
+
+ /**
+ * Gets the event's view mode. Calendar can be be either in monthly or
+ * weekly mode, depending on the active date range.
+ *
+ * @deprecated User {@link Calendar#isMonthlyMode()} instead
+ *
+ * @return Returns true when monthly view is active.
+ */
+ @Deprecated
+ public boolean isMonthlyMode() {
+ return monthlyMode;
+ }
+ }
+
+ /** RangeSelectHandler handles RangeSelectEvent. */
+ public interface RangeSelectHandler extends EventListener, Serializable {
+
+ /** Trigger method for the RangeSelectEvent. */
+ public static final Method rangeSelectMethod = ReflectTools
+ .findMethod(RangeSelectHandler.class, "rangeSelect",
+ RangeSelectEvent.class);
+
+ /**
+ * This method will be called when day or time cells are drag-marked
+ * with mouse.
+ *
+ * @param event
+ * RangeSelectEvent that contains range start and end date.
+ */
+ public void rangeSelect(RangeSelectEvent event);
+ }
+
+ /** Notifier interface for navigation listening. */
+ public interface NavigationNotifier extends Serializable {
+ /**
+ * Add a forward navigation listener.
+ *
+ * @param handler
+ * ForwardHandler to be added.
+ */
+ public void setHandler(ForwardHandler handler);
+
+ /**
+ * Add a backward navigation listener.
+ *
+ * @param handler
+ * BackwardHandler to be added.
+ */
+ public void setHandler(BackwardHandler handler);
+
+ /**
+ * Add a date click listener.
+ *
+ * @param handler
+ * DateClickHandler to be added.
+ */
+ public void setHandler(DateClickHandler handler);
+
+ /**
+ * Add a event click listener.
+ *
+ * @param handler
+ * EventClickHandler to be added.
+ */
+ public void setHandler(EventClickHandler handler);
+
+ /**
+ * Add a week click listener.
+ *
+ * @param handler
+ * WeekClickHandler to be added.
+ */
+ public void setHandler(WeekClickHandler handler);
+ }
+
+ /**
+ * ForwardEvent is sent when forward navigation button is clicked.
+ */
+ @SuppressWarnings("serial")
+ public class ForwardEvent extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.FORWARD;
+
+ /**
+ * ForwardEvent needs only the source component.
+ *
+ * @param source
+ * Calendar component.
+ */
+ public ForwardEvent(Calendar source) {
+ super(source);
+ }
+ }
+
+ /** ForwardHandler handles ForwardEvent. */
+ public interface ForwardHandler extends EventListener, Serializable {
+
+ /** Trigger method for the ForwardEvent. */
+ public static final Method forwardMethod = ReflectTools.findMethod(
+ ForwardHandler.class, "forward", ForwardEvent.class);
+
+ /**
+ * This method will be called when date range is moved forward.
+ *
+ * @param event
+ * ForwardEvent
+ */
+ public void forward(ForwardEvent event);
+ }
+
+ /**
+ * BackwardEvent is sent when backward navigation button is clicked.
+ */
+ @SuppressWarnings("serial")
+ public class BackwardEvent extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.BACKWARD;
+
+ /**
+ * BackwardEvent needs only the source source component.
+ *
+ * @param source
+ * Calendar component.
+ */
+ public BackwardEvent(Calendar source) {
+ super(source);
+ }
+ }
+
+ /** BackwardHandler handles BackwardEvent. */
+ public interface BackwardHandler extends EventListener, Serializable {
+
+ /** Trigger method for the BackwardEvent. */
+ public static final Method backwardMethod = ReflectTools.findMethod(
+ BackwardHandler.class, "backward", BackwardEvent.class);
+
+ /**
+ * This method will be called when date range is moved backwards.
+ *
+ * @param event
+ * BackwardEvent
+ */
+ public void backward(BackwardEvent event);
+ }
+
+ /**
+ * DateClickEvent is sent when a date is clicked.
+ */
+ @SuppressWarnings("serial")
+ public class DateClickEvent extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.DATECLICK;
+
+ /** Date that was clicked. */
+ private Date date;
+
+ /** DateClickEvent needs the target date that was clicked. */
+ public DateClickEvent(Calendar source, Date date) {
+ super(source);
+ this.date = date;
+ }
+
+ /**
+ * Get clicked date.
+ *
+ * @return Clicked date.
+ */
+ public Date getDate() {
+ return date;
+ }
+ }
+
+ /** DateClickHandler handles DateClickEvent. */
+ public interface DateClickHandler extends EventListener, Serializable {
+
+ /** Trigger method for the DateClickEvent. */
+ public static final Method dateClickMethod = ReflectTools.findMethod(
+ DateClickHandler.class, "dateClick", DateClickEvent.class);
+
+ /**
+ * This method will be called when a date is clicked.
+ *
+ * @param event
+ * DateClickEvent containing the target date.
+ */
+ public void dateClick(DateClickEvent event);
+ }
+
+ /**
+ * EventClick is sent when an event is clicked.
+ */
+ @SuppressWarnings("serial")
+ public class EventClick extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.EVENTCLICK;
+
+ /** Clicked source event. */
+ private CalendarEvent calendarEvent;
+
+ /** Target source event is needed for the EventClick. */
+ public EventClick(Calendar source, CalendarEvent calendarEvent) {
+ super(source);
+ this.calendarEvent = calendarEvent;
+ }
+
+ /**
+ * Get the clicked event.
+ *
+ * @return Clicked event.
+ */
+ public CalendarEvent getCalendarEvent() {
+ return calendarEvent;
+ }
+ }
+
+ /** EventClickHandler handles EventClick. */
+ public interface EventClickHandler extends EventListener, Serializable {
+
+ /** Trigger method for the EventClick. */
+ public static final Method eventClickMethod = ReflectTools.findMethod(
+ EventClickHandler.class, "eventClick", EventClick.class);
+
+ /**
+ * This method will be called when an event is clicked.
+ *
+ * @param event
+ * EventClick containing the target event.
+ */
+ public void eventClick(EventClick event);
+ }
+
+ /**
+ * WeekClick is sent when week is clicked.
+ */
+ @SuppressWarnings("serial")
+ public class WeekClick extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.WEEKCLICK;
+
+ /** Target week. */
+ private int week;
+
+ /** Target year. */
+ private int year;
+
+ /**
+ * WeekClick needs a target year and week.
+ *
+ * @param source
+ * Target source.
+ * @param week
+ * Target week.
+ * @param year
+ * Target year.
+ */
+ public WeekClick(Calendar source, int week, int year) {
+ super(source);
+ this.week = week;
+ this.year = year;
+ }
+
+ /**
+ * Get week as a integer. See {@link java.util.Calendar} for the allowed
+ * values.
+ *
+ * @return Week as a integer.
+ */
+ public int getWeek() {
+ return week;
+ }
+
+ /**
+ * Get year as a integer. See {@link java.util.Calendar} for the allowed
+ * values.
+ *
+ * @return Year as a integer
+ */
+ public int getYear() {
+ return year;
+ }
+ }
+
+ /** WeekClickHandler handles WeekClicks. */
+ public interface WeekClickHandler extends EventListener, Serializable {
+
+ /** Trigger method for the WeekClick. */
+ public static final Method weekClickMethod = ReflectTools.findMethod(
+ WeekClickHandler.class, "weekClick", WeekClick.class);
+
+ /**
+ * This method will be called when a week is clicked.
+ *
+ * @param event
+ * WeekClick containing the target week and year.
+ */
+ public void weekClick(WeekClick event);
+ }
+
+ /**
+ * EventResize is sent when an event is resized
+ */
+ @SuppressWarnings("serial")
+ public class EventResize extends CalendarComponentEvent {
+
+ public static final String EVENT_ID = CalendarEventId.EVENTRESIZE;
+
+ private CalendarEvent calendarEvent;
+
+ private Date startTime;
+
+ private Date endTime;
+
+ public EventResize(Calendar source, CalendarEvent calendarEvent,
+ Date startTime, Date endTime) {
+ super(source);
+ this.calendarEvent = calendarEvent;
+ this.startTime = startTime;
+ this.endTime = endTime;
+ }
+
+ /**
+ * Get target event.
+ *
+ * @return Target event.
+ */
+ public CalendarEvent getCalendarEvent() {
+ return calendarEvent;
+ }
+
+ /**
+ * @deprecated Use {@link #getNewStart()} instead
+ *
+ * @return the new start time
+ */
+ @Deprecated
+ public Date getNewStartTime() {
+ return startTime;
+ }
+
+ /**
+ * Returns the updated start date/time of the event
+ *
+ * @return The new date for the event
+ */
+ public Date getNewStart() {
+ return startTime;
+ }
+
+ /**
+ * @deprecated Use {@link #getNewEnd()} instead
+ *
+ * @return the new end time
+ */
+ @Deprecated
+ public Date getNewEndTime() {
+ return endTime;
+ }
+
+ /**
+ * Returns the updates end date/time of the event
+ *
+ * @return The new date for the event
+ */
+ public Date getNewEnd() {
+ return endTime;
+ }
+ }
+
+ /**
+ * Notifier interface for event resizing.
+ */
+ public interface EventResizeNotifier extends Serializable {
+
+ /**
+ * Set a EventResizeHandler.
+ *
+ * @param handler
+ * EventResizeHandler to be set
+ */
+ public void setHandler(EventResizeHandler handler);
+ }
+
+ /**
+ * Handler for EventResize event.
+ */
+ public interface EventResizeHandler extends EventListener, Serializable {
+
+ /** Trigger method for the EventResize. */
+ public static final Method eventResizeMethod = ReflectTools.findMethod(
+ EventResizeHandler.class, "eventResize", EventResize.class);
+
+ void eventResize(EventResize event);
+ }
+
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java b/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java
new file mode 100644
index 0000000000..01b766a6db
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2013 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.components.calendar;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Class for representing a date range.
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ *
+ */
+@SuppressWarnings("serial")
+public class CalendarDateRange implements Serializable {
+
+ private Date start;
+
+ private Date end;
+
+ private final transient TimeZone tz;
+
+ /**
+ * Constructor
+ *
+ * @param start
+ * The start date and time of the date range
+ * @param end
+ * The end date and time of the date range
+ */
+ public CalendarDateRange(Date start, Date end, TimeZone tz) {
+ super();
+ this.start = start;
+ this.end = end;
+ this.tz = tz;
+ }
+
+ /**
+ * Get the start date of the date range
+ *
+ * @return the start Date of the range
+ */
+ public Date getStart() {
+ return start;
+ }
+
+ /**
+ * Get the end date of the date range
+ *
+ * @return the end Date of the range
+ */
+ public Date getEnd() {
+ return end;
+ }
+
+ /**
+ * Is a date in the date range
+ *
+ * @param date
+ * The date to check
+ * @return true if the date range contains a date start and end of range
+ * inclusive; false otherwise
+ */
+ public boolean inRange(Date date) {
+ if (date == null) {
+ return false;
+ }
+
+ return date.compareTo(start) >= 0 && date.compareTo(end) <= 0;
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarTargetDetails.java b/server/src/com/vaadin/ui/components/calendar/CalendarTargetDetails.java
new file mode 100644
index 0000000000..1a3ef67377
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/CalendarTargetDetails.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2000-2013 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.components.calendar;
+
+import java.util.Date;
+import java.util.Map;
+
+import com.vaadin.event.dd.DropTarget;
+import com.vaadin.event.dd.TargetDetailsImpl;
+import com.vaadin.ui.Calendar;
+
+/**
+ * Drop details for {@link com.vaadin.ui.addon.calendar.ui.Calendar Calendar}.
+ * When something is dropped on the Calendar, this class contains the specific
+ * details of the drop point. Specifically, this class gives access to the date
+ * where the drop happened. If the Calendar was in weekly mode, the date also
+ * includes the start time of the slot.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class CalendarTargetDetails extends TargetDetailsImpl {
+
+ private boolean hasDropTime;
+
+ public CalendarTargetDetails(Map<String, Object> rawDropData,
+ DropTarget dropTarget) {
+ super(rawDropData, dropTarget);
+ }
+
+ /**
+ * @return true if {@link #getDropTime()} will return a date object with the
+ * time set to the start of the time slot where the drop happened
+ */
+ public boolean hasDropTime() {
+ return hasDropTime;
+ }
+
+ /**
+ * Does the dropped item have a time associated with it
+ *
+ * @param hasDropTime
+ */
+ public void setHasDropTime(boolean hasDropTime) {
+ this.hasDropTime = hasDropTime;
+ }
+
+ /**
+ * @return the date where the drop happened
+ */
+ public Date getDropTime() {
+ if (hasDropTime) {
+ return (Date) getData("dropTime");
+ } else {
+ return (Date) getData("dropDay");
+ }
+ }
+
+ /**
+ * @return the {@link com.vaadin.ui.addon.calendar.ui.Calendar Calendar}
+ * instance which was the target of the drop
+ */
+ public Calendar getTargetCalendar() {
+ return (Calendar) getTarget();
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
new file mode 100644
index 0000000000..b01140eb88
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
@@ -0,0 +1,566 @@
+/*
+ * Copyright 2000-2013 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.components.calendar;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Container.Indexed;
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeNotifier;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeNotifier;
+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.MoveEvent;
+import com.vaadin.ui.components.calendar.event.BasicEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEditableEventProvider;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeListener;
+import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeNotifier;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider.EventSetChangeNotifier;
+
+/**
+ * A event provider which uses a {@link Container} as a datasource. Container
+ * used as data source.
+ *
+ * NOTE: The data source must be sorted by date!
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class ContainerEventProvider implements CalendarEditableEventProvider,
+ EventSetChangeNotifier, EventChangeNotifier, EventMoveHandler,
+ EventResizeHandler, Container.ItemSetChangeListener,
+ Property.ValueChangeListener {
+
+ // Default property ids
+ public static final String CAPTION_PROPERTY = "caption";
+ public static final String DESCRIPTION_PROPERTY = "description";
+ public static final String STARTDATE_PROPERTY = "start";
+ public static final String ENDDATE_PROPERTY = "end";
+ public static final String STYLENAME_PROPERTY = "styleName";
+
+ /**
+ * Internal class to keep the container index which item this event
+ * represents
+ *
+ */
+ private class ContainerCalendarEvent extends BasicEvent {
+ private final int index;
+
+ public ContainerCalendarEvent(int containerIndex) {
+ super();
+ index = containerIndex;
+ }
+
+ public int getContainerIndex() {
+ return index;
+ }
+ }
+
+ /**
+ * Listeners attached to the container
+ */
+ private final List<EventSetChangeListener> eventSetChangeListeners = new LinkedList<CalendarEventProvider.EventSetChangeListener>();
+ private final List<EventChangeListener> eventChangeListeners = new LinkedList<CalendarEvent.EventChangeListener>();
+
+ /**
+ * The event cache contains the events previously created by
+ * {@link #getEvents(Date, Date)}
+ */
+ private final List<CalendarEvent> eventCache = new LinkedList<CalendarEvent>();
+
+ /**
+ * The container used as datasource
+ */
+ private Indexed container;
+
+ /**
+ * Container properties. Defaults based on using the {@link BasicEvent}
+ * helper class.
+ */
+ private Object captionProperty = CAPTION_PROPERTY;
+ private Object descriptionProperty = DESCRIPTION_PROPERTY;
+ private Object startDateProperty = STARTDATE_PROPERTY;
+ private Object endDateProperty = ENDDATE_PROPERTY;
+ private Object styleNameProperty = STYLENAME_PROPERTY;
+
+ /**
+ * Constructor
+ *
+ * @param container
+ * Container to use as a data source.
+ */
+ public ContainerEventProvider(Container.Indexed container) {
+ this.container = container;
+ listenToContainerEvents();
+ }
+
+ /**
+ * Set the container data source
+ *
+ * @param container
+ * The container to use as datasource
+ *
+ */
+ public void setContainerDataSource(Container.Indexed container) {
+ // Detach the previous container
+ detachContainerDataSource();
+
+ this.container = container;
+ listenToContainerEvents();
+ }
+
+ /**
+ * Returns the container used as data source
+ *
+ */
+ public Container.Indexed getContainerDataSource() {
+ return container;
+ }
+
+ /**
+ * Attaches listeners to the container so container events can be processed
+ */
+ private void listenToContainerEvents() {
+ if (container instanceof ItemSetChangeNotifier) {
+ ((ItemSetChangeNotifier) container).addItemSetChangeListener(this);
+ }
+ if (container instanceof ValueChangeNotifier) {
+ ((ValueChangeNotifier) container).addValueChangeListener(this);
+ }
+ }
+
+ /**
+ * Removes listeners from the container so no events are processed
+ */
+ private void ignoreContainerEvents() {
+ if (container instanceof ItemSetChangeNotifier) {
+ ((ItemSetChangeNotifier) container)
+ .removeItemSetChangeListener(this);
+ }
+ if (container instanceof ValueChangeNotifier) {
+ ((ValueChangeNotifier) container).removeValueChangeListener(this);
+ }
+ }
+
+ /**
+ * Converts an event in the container to an {@link CalendarEvent}
+ *
+ * @param index
+ * The index of the item in the container to get the event for
+ * @return
+ */
+ private CalendarEvent getEvent(int index) {
+
+ // Check the event cache first
+ for (CalendarEvent e : eventCache) {
+ if (e instanceof ContainerCalendarEvent
+ && ((ContainerCalendarEvent) e).getContainerIndex() == index) {
+ return e;
+ } else if (container.getIdByIndex(index) == e) {
+ return e;
+ }
+ }
+
+ final Object id = container.getIdByIndex(index);
+ Item item = container.getItem(id);
+ CalendarEvent event;
+ if (id instanceof CalendarEvent) {
+ /*
+ * If we are using the BeanItemContainer or another container which
+ * stores the objects as ids then just return the instances
+ */
+ event = (CalendarEvent) id;
+
+ } else {
+ /*
+ * Else we use the properties to create the event
+ */
+ BasicEvent basicEvent = new ContainerCalendarEvent(index);
+
+ // Set values from property values
+ if (captionProperty != null
+ && item.getItemPropertyIds().contains(captionProperty)) {
+ basicEvent.setCaption(String.valueOf(item.getItemProperty(
+ captionProperty).getValue()));
+ }
+ if (descriptionProperty != null
+ && item.getItemPropertyIds().contains(descriptionProperty)) {
+ basicEvent.setDescription(String.valueOf(item.getItemProperty(
+ descriptionProperty).getValue()));
+ }
+ if (startDateProperty != null
+ && item.getItemPropertyIds().contains(startDateProperty)) {
+ basicEvent.setStart((Date) item.getItemProperty(
+ startDateProperty).getValue());
+ }
+ if (endDateProperty != null
+ && item.getItemPropertyIds().contains(endDateProperty)) {
+ basicEvent.setEnd((Date) item.getItemProperty(endDateProperty)
+ .getValue());
+ }
+ if (styleNameProperty != null
+ && item.getItemPropertyIds().contains(styleNameProperty)) {
+ basicEvent.setDescription(String.valueOf(item.getItemProperty(
+ descriptionProperty).getValue()));
+ }
+ event = basicEvent;
+ }
+ return event;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventProvider#getEvents(java.
+ * util.Date, java.util.Date)
+ */
+ public List<CalendarEvent> getEvents(Date startDate, Date endDate) {
+ eventCache.clear();
+
+ int[] rangeIndexes = getFirstAndLastEventIndex(startDate, endDate);
+ for (int i = rangeIndexes[0]; i <= rangeIndexes[1]
+ && i < container.size(); i++) {
+ eventCache.add(getEvent(i));
+ }
+ return Collections.unmodifiableList(eventCache);
+ }
+
+ /**
+ * Get the first event for a date
+ *
+ * @param date
+ * The date to search for, NUll returns first event in container
+ * @return Returns an array where the first item is the start index and the
+ * second item is the end item
+ */
+ private int[] getFirstAndLastEventIndex(Date start, Date end) {
+ int startIndex = 0;
+ int size = container.size();
+ int endIndex = size - 1;
+
+ if (start != null) {
+ /*
+ * Iterating from the start of the container, if range is in the end
+ * of the container then this will be slow TODO This could be
+ * improved by using some sort of divide and conquer algorithm
+ */
+ while (startIndex < size) {
+ Object id = container.getIdByIndex(startIndex);
+ Item item = container.getItem(id);
+ Date d = (Date) item.getItemProperty(startDateProperty)
+ .getValue();
+ if (d.compareTo(start) >= 0) {
+ break;
+ }
+ startIndex++;
+ }
+ }
+
+ if (end != null) {
+ /*
+ * Iterate from the start index until range ends
+ */
+ endIndex = startIndex;
+ while (endIndex < size - 1) {
+ Object id = container.getIdByIndex(endIndex);
+ Item item = container.getItem(id);
+ Date d = (Date) item.getItemProperty(endDateProperty)
+ .getValue();
+ if (d == null) {
+ // No end date present, use start date
+ d = (Date) item.getItemProperty(startDateProperty)
+ .getValue();
+ }
+ if (d.compareTo(end) >= 0) {
+ endIndex--;
+ break;
+ }
+ endIndex++;
+ }
+ }
+
+ return new int[] { startIndex, endIndex };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventProvider.EventSetChangeNotifier
+ * #addListener(com.vaadin.addon.calendar.event.CalendarEventProvider.
+ * EventSetChangeListener)
+ */
+ public void addEventSetChangeListener(EventSetChangeListener listener) {
+ if (!eventSetChangeListeners.contains(listener)) {
+ eventSetChangeListeners.add(listener);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventProvider.EventSetChangeNotifier
+ * #removeListener(com.vaadin.addon.calendar.event.CalendarEventProvider.
+ * EventSetChangeListener)
+ */
+ public void removeEventSetChangeListener(EventSetChangeListener listener) {
+ eventSetChangeListeners.remove(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEvent.EventChangeNotifier#addListener
+ * (com.vaadin.addon.calendar.event.CalendarEvent.EventChangeListener)
+ */
+ public void addEventChangeListener(EventChangeListener listener) {
+ if (eventChangeListeners.contains(listener)) {
+ eventChangeListeners.add(listener);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.addon.calendar.event.CalendarEvent.EventChangeNotifier#
+ * removeListener
+ * (com.vaadin.addon.calendar.event.CalendarEvent.EventChangeListener)
+ */
+ public void removeEventChangeListener(EventChangeListener listener) {
+ eventChangeListeners.remove(listener);
+ }
+
+ /**
+ * Get the property which provides the caption of the event
+ */
+ public Object getCaptionProperty() {
+ return captionProperty;
+ }
+
+ /**
+ * Set the property which provides the caption of the event
+ */
+ public void setCaptionProperty(Object captionProperty) {
+ this.captionProperty = captionProperty;
+ }
+
+ /**
+ * Get the property which provides the description of the event
+ */
+ public Object getDescriptionProperty() {
+ return descriptionProperty;
+ }
+
+ /**
+ * Set the property which provides the description of the event
+ */
+ public void setDescriptionProperty(Object descriptionProperty) {
+ this.descriptionProperty = descriptionProperty;
+ }
+
+ /**
+ * Get the property which provides the starting date and time of the event
+ */
+ public Object getStartDateProperty() {
+ return startDateProperty;
+ }
+
+ /**
+ * Set the property which provides the starting date and time of the event
+ */
+ public void setStartDateProperty(Object startDateProperty) {
+ this.startDateProperty = startDateProperty;
+ }
+
+ /**
+ * Get the property which provides the ending date and time of the event
+ */
+ public Object getEndDateProperty() {
+ return endDateProperty;
+ }
+
+ /**
+ * Set the property which provides the ending date and time of the event
+ */
+ public void setEndDateProperty(Object endDateProperty) {
+ this.endDateProperty = endDateProperty;
+ }
+
+ /**
+ * Get the property which provides the style name for the event
+ */
+ public Object getStyleNameProperty() {
+ return styleNameProperty;
+ }
+
+ /**
+ * Set the property which provides the style name for the event
+ */
+ public void setStyleNameProperty(Object styleNameProperty) {
+ this.styleNameProperty = styleNameProperty;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange
+ * (com.vaadin.data.Container.ItemSetChangeEvent)
+ */
+ public void containerItemSetChange(ItemSetChangeEvent event) {
+ if (event.getContainer() == container) {
+ // Trigger an eventset change event when the itemset changes
+ for (EventSetChangeListener listener : eventSetChangeListeners) {
+ listener.eventSetChange(new EventSetChangeEvent(this));
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin.data
+ * .Property.ValueChangeEvent)
+ */
+ public void valueChange(ValueChangeEvent event) {
+ /*
+ * TODO Need to figure out how to get the item which triggered the the
+ * valuechange event and then trigger a EventChange event to the
+ * listeners
+ */
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveHandler
+ * #eventMove
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.MoveEvent)
+ */
+ public void eventMove(MoveEvent event) {
+ CalendarEvent ce = event.getCalendarEvent();
+ if (eventCache.contains(ce)) {
+ int index;
+ if (ce instanceof ContainerCalendarEvent) {
+ index = ((ContainerCalendarEvent) ce).getContainerIndex();
+ } else {
+ index = container.indexOfId(ce);
+ }
+
+ long eventLength = ce.getEnd().getTime() - ce.getStart().getTime();
+ Date newEnd = new Date(event.getNewStart().getTime() + eventLength);
+
+ ignoreContainerEvents();
+ Item item = container.getItem(container.getIdByIndex(index));
+ item.getItemProperty(startDateProperty).setValue(
+ event.getNewStart());
+ item.getItemProperty(endDateProperty).setValue(newEnd);
+ listenToContainerEvents();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeHandler
+ * #eventResize
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResize)
+ */
+ public void eventResize(EventResize event) {
+ CalendarEvent ce = event.getCalendarEvent();
+ if (eventCache.contains(ce)) {
+ int index;
+ if (ce instanceof ContainerCalendarEvent) {
+ index = ((ContainerCalendarEvent) ce).getContainerIndex();
+ } else {
+ index = container.indexOfId(ce);
+ }
+ ignoreContainerEvents();
+ Item item = container.getItem(container.getIdByIndex(index));
+ item.getItemProperty(startDateProperty).setValue(
+ event.getNewStart());
+ item.getItemProperty(endDateProperty).setValue(event.getNewEnd());
+ listenToContainerEvents();
+ }
+ }
+
+ /**
+ * If you are reusing the container which previously have been attached to
+ * this ContainerEventProvider call this method to remove this event
+ * providers container listeners before attaching it to an other
+ * ContainerEventProvider
+ */
+ public void detachContainerDataSource() {
+ ignoreContainerEvents();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#addEvent
+ * (com.vaadin.addon.calendar.event.CalendarEvent)
+ */
+ public void addEvent(CalendarEvent event) {
+ Item item;
+ try {
+ item = container.addItem(event);
+ } catch (UnsupportedOperationException uop) {
+ // Thrown if container does not support adding items with custom
+ // ids. JPAContainer for example.
+ item = container.getItem(container.addItem());
+ }
+ if (item != null) {
+ item.getItemProperty(getCaptionProperty()).setValue(
+ event.getCaption());
+ item.getItemProperty(getStartDateProperty()).setValue(
+ event.getStart());
+ item.getItemProperty(getEndDateProperty()).setValue(event.getEnd());
+ item.getItemProperty(getStyleNameProperty()).setValue(
+ event.getStyleName());
+ item.getItemProperty(getDescriptionProperty()).setValue(
+ event.getDescription());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#removeEvent
+ * (com.vaadin.addon.calendar.event.CalendarEvent)
+ */
+ public void removeEvent(CalendarEvent event) {
+ container.removeItem(event);
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/event/BasicEvent.java b/server/src/com/vaadin/ui/components/calendar/event/BasicEvent.java
new file mode 100644
index 0000000000..ab342dfabf
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/event/BasicEvent.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.event;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeNotifier;
+
+/**
+ * Simple implementation of
+ * {@link com.vaadin.addon.calendar.event.CalendarEvent CalendarEvent}. Has
+ * setters for all required fields and fires events when this event is changed.
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicEvent implements EditableCalendarEvent, EventChangeNotifier {
+
+ private String caption;
+ private String description;
+ private Date end;
+ private Date start;
+ private String styleName;
+ private transient List<EventChangeListener> listeners = new ArrayList<EventChangeListener>();
+
+ private boolean isAllDay;
+
+ /**
+ * Default constructor
+ */
+ public BasicEvent() {
+
+ }
+
+ /**
+ * Constructor for creating an event with the same start and end date
+ *
+ * @param caption
+ * The caption for the event
+ * @param description
+ * The description for the event
+ * @param date
+ * The date the event occurred
+ */
+ public BasicEvent(String caption, String description, Date date) {
+ this.caption = caption;
+ this.description = description;
+ start = date;
+ end = date;
+ }
+
+ /**
+ * Constructor for creating an event with a start date and an end date.
+ * Start date should be before the end date
+ *
+ * @param caption
+ * The caption for the event
+ * @param description
+ * The description for the event
+ * @param startDate
+ * The start date of the event
+ * @param endDate
+ * The end date of the event
+ */
+ public BasicEvent(String caption, String description, Date startDate,
+ Date endDate) {
+ this.caption = caption;
+ this.description = description;
+ start = startDate;
+ end = endDate;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.addon.calendar.event.CalendarEvent#getCaption()
+ */
+ public String getCaption() {
+ return caption;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.addon.calendar.event.CalendarEvent#getDescription()
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.addon.calendar.event.CalendarEvent#getEnd()
+ */
+ public Date getEnd() {
+ return end;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.addon.calendar.event.CalendarEvent#getStart()
+ */
+ public Date getStart() {
+ return start;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.addon.calendar.event.CalendarEvent#getStyleName()
+ */
+ public String getStyleName() {
+ return styleName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.addon.calendar.event.CalendarEvent#isAllDay()
+ */
+ public boolean isAllDay() {
+ return isAllDay;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventEditor#setCaption(java.lang
+ * .String)
+ */
+ public void setCaption(String caption) {
+ this.caption = caption;
+ fireEventChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventEditor#setDescription(java
+ * .lang.String)
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ fireEventChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventEditor#setEnd(java.util.
+ * Date)
+ */
+ public void setEnd(Date end) {
+ this.end = end;
+ fireEventChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventEditor#setStart(java.util
+ * .Date)
+ */
+ public void setStart(Date start) {
+ this.start = start;
+ fireEventChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventEditor#setStyleName(java
+ * .lang.String)
+ */
+ public void setStyleName(String styleName) {
+ this.styleName = styleName;
+ fireEventChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventEditor#setAllDay(boolean)
+ */
+ public void setAllDay(boolean isAllDay) {
+ this.isAllDay = isAllDay;
+ fireEventChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeListener
+ * )
+ */
+ public void addEventChangeListener(EventChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeNotifier
+ * #removeListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeListener
+ * )
+ */
+ public void removeEventChangeListener(EventChangeListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Fires an event change event to the listeners. Should be triggered when
+ * some property of the event changes.
+ */
+ protected void fireEventChange() {
+ EventChangeEvent event = new EventChangeEvent(this);
+
+ for (EventChangeListener listener : listeners) {
+ listener.eventChange(event);
+ }
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/event/BasicEventProvider.java b/server/src/com/vaadin/ui/components/calendar/event/BasicEventProvider.java
new file mode 100644
index 0000000000..0314652245
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/event/BasicEventProvider.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.event;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider.EventSetChangeNotifier;
+
+/**
+ * <p>
+ * Simple implementation of
+ * {@link com.vaadin.addon.calendar.event.CalendarEventProvider
+ * CalendarEventProvider}. Use {@link #addEvent(CalendarEvent)} and
+ * {@link #removeEvent(CalendarEvent)} to add / remove events.
+ * </p>
+ *
+ * <p>
+ * {@link com.vaadin.addon.calendar.event.CalendarEventProvider.EventSetChangeNotifier
+ * EventSetChangeNotifier} and
+ * {@link com.vaadin.addon.calendar.event.CalendarEvent.EventChangeListener
+ * EventChangeListener} are also implemented, so the Calendar is notified when
+ * an event is added, changed or removed.
+ * </p>
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicEventProvider implements CalendarEditableEventProvider,
+ EventSetChangeNotifier, CalendarEvent.EventChangeListener {
+
+ protected List<CalendarEvent> eventList = new ArrayList<CalendarEvent>();
+
+ private List<EventSetChangeListener> listeners = new ArrayList<EventSetChangeListener>();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEventProvider#getEvents(java.
+ * util.Date, java.util.Date)
+ */
+ public List<CalendarEvent> getEvents(Date startDate, Date endDate) {
+ ArrayList<CalendarEvent> activeEvents = new ArrayList<CalendarEvent>();
+
+ for (CalendarEvent ev : eventList) {
+ long from = startDate.getTime();
+ long to = endDate.getTime();
+
+ if (ev.getStart() != null && ev.getEnd() != null) {
+ long f = ev.getStart().getTime();
+ long t = ev.getEnd().getTime();
+ // Select only events that overlaps with startDate and
+ // endDate.
+ if ((f <= to && f >= from) || (t >= from && t <= to)
+ || (f <= from && t >= to)) {
+ activeEvents.add(ev);
+ }
+ }
+ }
+
+ return activeEvents;
+ }
+
+ /**
+ * Does this event provider container this event
+ *
+ * @param event
+ * The event to check for
+ * @return If this provider has the event then true is returned, else false
+ */
+ public boolean containsEvent(BasicEvent event) {
+ return eventList.contains(event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventSetChangeNotifier
+ * #addListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventSetChangeListener
+ * )
+ */
+ public void addEventSetChangeListener(EventSetChangeListener listener) {
+ listeners.add(listener);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventSetChangeNotifier
+ * #removeListener
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventSetChangeListener
+ * )
+ */
+ public void removeEventSetChangeListener(EventSetChangeListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Fires a eventsetchange event. The event is fired when either an event is
+ * added or removed to the event provider
+ */
+ protected void fireEventSetChange() {
+ EventSetChangeEvent event = new EventSetChangeEvent(this);
+
+ for (EventSetChangeListener listener : listeners) {
+ listener.eventSetChange(event);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventChangeListener
+ * #eventChange
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventSetChange)
+ */
+ public void eventChange(EventChangeEvent changeEvent) {
+ // naive implementation
+ fireEventSetChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#addEvent
+ * (com.vaadin.addon.calendar.event.CalendarEvent)
+ */
+ public void addEvent(CalendarEvent event) {
+ eventList.add(event);
+ if (event instanceof BasicEvent) {
+ ((BasicEvent) event).addEventChangeListener(this);
+ }
+ fireEventSetChange();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.event.CalendarEditableEventProvider#removeEvent
+ * (com.vaadin.addon.calendar.event.CalendarEvent)
+ */
+ public void removeEvent(CalendarEvent event) {
+ eventList.remove(event);
+ if (event instanceof BasicEvent) {
+ ((BasicEvent) event).removeEventChangeListener(this);
+ }
+ fireEventSetChange();
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java b/server/src/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java
new file mode 100644
index 0000000000..145d2b4aa4
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/event/CalendarEditableEventProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.event;
+
+/**
+ * An event provider which allows adding and removing events
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ */
+public interface CalendarEditableEventProvider extends CalendarEventProvider {
+
+ /**
+ * Adds an event to the event provider
+ *
+ * @param event
+ * The event to add
+ */
+ void addEvent(CalendarEvent event);
+
+ /**
+ * Removes an event from the event provider
+ *
+ * @param event
+ * The event
+ */
+ void removeEvent(CalendarEvent event);
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/event/CalendarEvent.java b/server/src/com/vaadin/ui/components/calendar/event/CalendarEvent.java
new file mode 100644
index 0000000000..531ee72c7f
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/event/CalendarEvent.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.event;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * Event in the calendar. Customize your own event by implementing this
+ * interface.
+ * </p>
+ *
+ * <li>Start and end fields are mandatory.</li>
+ *
+ * <li>In "allDay" events longer than one day, starting and ending clock times
+ * are omitted in UI and only dates are shown.</li>
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ *
+ */
+public interface CalendarEvent extends Serializable {
+
+ /**
+ * Gets start date of event.
+ *
+ * @return Start date.
+ */
+ public Date getStart();
+
+ /**
+ * Get end date of event.
+ *
+ * @return End date;
+ */
+ public Date getEnd();
+
+ /**
+ * Gets caption of event.
+ *
+ * @return Caption text
+ */
+ public String getCaption();
+
+ /**
+ * Gets description of event. Shown as a tooltip over the event.
+ *
+ * @return Description text.
+ */
+ public String getDescription();
+
+ /**
+ * <p>
+ * Gets style name of event. In the client, style name will be set to the
+ * event's element class name and can be styled by CSS
+ * </p>
+ * Styling example:</br> <code>Java code: </br>
+ * event.setStyleName("color1");
+ * </br></br>
+ * CSS:</br>
+ * .v-calendar-event-color1 {</br>
+ * &nbsp;&nbsp;&nbsp;background-color: #9effae;</br>}</code>
+ *
+ * @return Style name.
+ */
+ public String getStyleName();
+
+ /**
+ * An all-day event typically does not occur at a specific time but targets
+ * a whole day or days. The rendering of all-day events differs from normal
+ * events.
+ *
+ * @return true if this event is an all-day event, false otherwise
+ */
+ public boolean isAllDay();
+
+ /**
+ * Event to signal that an event has changed.
+ */
+ @SuppressWarnings("serial")
+ public class EventChangeEvent implements Serializable {
+
+ private CalendarEvent source;
+
+ public EventChangeEvent(CalendarEvent source) {
+ this.source = source;
+ }
+
+ /**
+ * @return the {@link com.vaadin.addon.calendar.event.CalendarEvent
+ * CalendarEvent} that has changed
+ */
+ public CalendarEvent getCalendarEvent() {
+ return source;
+ }
+ }
+
+ /**
+ * Listener for EventSetChange events.
+ */
+ public interface EventChangeListener extends Serializable {
+
+ /**
+ * Called when an Event has changed.
+ */
+ public void eventChange(EventChangeEvent eventChangeEvent);
+ }
+
+ /**
+ * Notifier interface for EventChange events.
+ */
+ public interface EventChangeNotifier extends Serializable {
+
+ /**
+ * Add a listener to listen for EventChangeEvents. These events are
+ * fired when a events properties are changed.
+ *
+ * @param listener
+ * The listener to add
+ */
+ void addEventChangeListener(EventChangeListener listener);
+
+ /**
+ * Remove a listener from the event provider.
+ *
+ * @param listener
+ * The listener to remove
+ */
+ void removeEventChangeListener(EventChangeListener listener);
+ }
+
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java b/server/src/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java
new file mode 100644
index 0000000000..fefb2ca9b6
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/event/CalendarEventProvider.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.event;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Interface for querying events. The Vaadin Calendar always has a
+ * CalendarEventProvider set.
+ *
+ * @since 7.1.0
+ * @author Vaadin Ltd.
+ */
+public interface CalendarEventProvider extends Serializable {
+ /**
+ * <p>
+ * Gets all available events in the target date range between startDate and
+ * endDate. The Vaadin Calendar queries the events from the range that is
+ * shown, which is not guaranteed to be the same as the date range that is
+ * set.
+ * </p>
+ *
+ * <p>
+ * For example, if you set the date range to be monday 22.2.2010 - wednesday
+ * 24.2.2000, the used Event Provider will be queried for events between
+ * monday 22.2.2010 00:00 and sunday 28.2.2010 23:59. Generally you can
+ * expect the date range to be expanded to whole days and whole weeks.
+ * </p>
+ *
+ * @param startDate
+ * Start date
+ * @param endDate
+ * End date
+ * @return List of events
+ */
+ public List<CalendarEvent> getEvents(Date startDate, Date endDate);
+
+ /**
+ * Event to signal that the set of events has changed and the calendar
+ * should refresh its view from the
+ * {@link com.vaadin.addon.calendar.event.CalendarEventProvider
+ * CalendarEventProvider} .
+ *
+ */
+ @SuppressWarnings("serial")
+ public class EventSetChangeEvent implements Serializable {
+
+ private CalendarEventProvider source;
+
+ public EventSetChangeEvent(CalendarEventProvider source) {
+ this.source = source;
+ }
+
+ /**
+ * @return the
+ * {@link com.vaadin.addon.calendar.event.CalendarEventProvider
+ * CalendarEventProvider} that has changed
+ */
+ public CalendarEventProvider getProvider() {
+ return source;
+ }
+ }
+
+ /**
+ * Listener for EventSetChange events.
+ */
+ public interface EventSetChangeListener extends Serializable {
+
+ /**
+ * Called when the set of Events has changed.
+ */
+ public void eventSetChange(EventSetChangeEvent changeEvent);
+ }
+
+ /**
+ * Notifier interface for EventSetChange events.
+ */
+ public interface EventSetChangeNotifier extends Serializable {
+
+ /**
+ * Add a listener for listening to when new events are adding or removed
+ * from the event provider.
+ *
+ * @param listener
+ * The listener to add
+ */
+ void addEventSetChangeListener(EventSetChangeListener listener);
+
+ /**
+ * Remove a listener which listens to {@link EventSetChangeEvent}-events
+ *
+ * @param listener
+ * The listener to remove
+ */
+ void removeEventSetChangeListener(EventSetChangeListener listener);
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java b/server/src/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java
new file mode 100644
index 0000000000..e8a27ad50f
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/event/EditableCalendarEvent.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.event;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * Extension to the basic {@link com.vaadin.addon.calendar.event.CalendarEvent
+ * CalendarEvent}. This interface provides setters (and thus editing
+ * capabilities) for all {@link com.vaadin.addon.calendar.event.CalendarEvent
+ * CalendarEvent} fields. For descriptions on the fields, refer to the extended
+ * interface.
+ * </p>
+ *
+ * <p>
+ * This interface is used by some of the basic Calendar event handlers in the
+ * <code>com.vaadin.addon.calendar.ui.handler</code> package to determine
+ * whether an event can be edited.
+ * </p>
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+public interface EditableCalendarEvent extends CalendarEvent {
+
+ /**
+ * Set the visible text in the calendar for the event.
+ *
+ * @param caption
+ * The text to show in the calendar
+ */
+ void setCaption(String caption);
+
+ /**
+ * Set the description of the event. This is shown in the calendar when
+ * hoovering over the event.
+ *
+ * @param description
+ * The text which describes the event
+ */
+ void setDescription(String description);
+
+ /**
+ * Set the end date of the event. Must be after the start date.
+ *
+ * @param end
+ * The end date to set
+ */
+ void setEnd(Date end);
+
+ /**
+ * Set the start date for the event. Must be before the end date
+ *
+ * @param start
+ * The start date of the event
+ */
+ void setStart(Date start);
+
+ /**
+ * Set the style name for the event used for styling the event cells
+ *
+ * @param styleName
+ * The stylename to use
+ *
+ */
+ void setStyleName(String styleName);
+
+ /**
+ * Does the event span the whole day. If so then set this to true
+ *
+ * @param isAllDay
+ * True if the event spans the whole day. In this case the start
+ * and end times are ignored.
+ */
+ void setAllDay(boolean isAllDay);
+
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java b/server/src/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java
new file mode 100644
index 0000000000..fc2bfd6df4
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/handler/BasicBackwardHandler.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.handler;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import com.vaadin.shared.ui.calendar.DateConstants;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardHandler;
+
+/**
+ * Implements basic functionality needed to enable backwards navigation.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicBackwardHandler implements BackwardHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardHandler#
+ * backward
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardEvent)
+ */
+ public void backward(BackwardEvent event) {
+ Date start = event.getComponent().getStartDate();
+ Date end = event.getComponent().getEndDate();
+
+ // calculate amount to move back
+ int durationInDays = (int) (((end.getTime()) - start.getTime()) / DateConstants.DAYINMILLIS);
+ durationInDays++;
+ durationInDays = -durationInDays;
+
+ // set new start and end times
+ Calendar javaCalendar = event.getComponent().getInternalCalendar();
+ javaCalendar.setTime(start);
+ javaCalendar.add(java.util.Calendar.DATE, durationInDays);
+ Date newStart = javaCalendar.getTime();
+
+ javaCalendar.setTime(end);
+ javaCalendar.add(java.util.Calendar.DATE, durationInDays);
+ Date newEnd = javaCalendar.getTime();
+
+ setDates(event, newStart, newEnd);
+ }
+
+ /**
+ * Set the start and end dates for the event
+ *
+ * @param event
+ * The event that the start and end dates should be set
+ * @param start
+ * The start date
+ * @param end
+ * The end date
+ */
+ protected void setDates(BackwardEvent event, Date start, Date end) {
+ event.getComponent().setStartDate(start);
+ event.getComponent().setEndDate(end);
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java b/server/src/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java
new file mode 100644
index 0000000000..c91a238b86
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/handler/BasicDateClickHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.handler;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickHandler;
+
+/**
+ * Implements basic functionality needed to switch to day view when a single day
+ * is clicked.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicDateClickHandler implements DateClickHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.DateClickHandler
+ * #dateClick
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.DateClickEvent)
+ */
+ public void dateClick(DateClickEvent event) {
+ Date clickedDate = event.getDate();
+
+ Calendar javaCalendar = event.getComponent().getInternalCalendar();
+ javaCalendar.setTime(clickedDate);
+
+ // as times are expanded, this is all that is needed to show one day
+ Date start = javaCalendar.getTime();
+ Date end = javaCalendar.getTime();
+
+ setDates(event, start, end);
+ }
+
+ /**
+ * Set the start and end dates for the event
+ *
+ * @param event
+ * The event that the start and end dates should be set
+ * @param start
+ * The start date
+ * @param end
+ * The end date
+ */
+ protected void setDates(DateClickEvent event, Date start, Date end) {
+ event.getComponent().setStartDate(start);
+ event.getComponent().setEndDate(end);
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java b/server/src/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java
new file mode 100644
index 0000000000..139837f339
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/handler/BasicEventMoveHandler.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.handler;
+
+import java.util.Date;
+
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventMoveHandler;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+import com.vaadin.ui.components.calendar.event.EditableCalendarEvent;
+
+/**
+ * Implements basic functionality needed to enable moving events.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicEventMoveHandler implements EventMoveHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventMoveHandler
+ * #eventMove
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.MoveEvent)
+ */
+ public void eventMove(MoveEvent event) {
+ CalendarEvent calendarEvent = event.getCalendarEvent();
+
+ if (calendarEvent instanceof EditableCalendarEvent) {
+
+ EditableCalendarEvent editableEvent = (EditableCalendarEvent) calendarEvent;
+
+ Date newFromTime = event.getNewStart();
+
+ // Update event dates
+ long length = editableEvent.getEnd().getTime()
+ - editableEvent.getStart().getTime();
+ setDates(editableEvent, newFromTime, new Date(newFromTime.getTime()
+ + length));
+ }
+ }
+
+ /**
+ * Set the start and end dates for the event
+ *
+ * @param event
+ * The event that the start and end dates should be set
+ * @param start
+ * The start date
+ * @param end
+ * The end date
+ */
+ protected void setDates(EditableCalendarEvent event, Date start, Date end) {
+ event.setStart(start);
+ event.setEnd(end);
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java b/server/src/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java
new file mode 100644
index 0000000000..c052d0d77b
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/handler/BasicEventResizeHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.handler;
+
+import java.util.Date;
+
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+import com.vaadin.ui.components.calendar.event.EditableCalendarEvent;
+
+/**
+ * Implements basic functionality needed to enable event resizing.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicEventResizeHandler implements EventResizeHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResizeHandler
+ * #eventResize
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResize)
+ */
+ public void eventResize(EventResize event) {
+ CalendarEvent calendarEvent = event.getCalendarEvent();
+
+ if (calendarEvent instanceof EditableCalendarEvent) {
+ Date newStartTime = event.getNewStart();
+ Date newEndTime = event.getNewEnd();
+
+ EditableCalendarEvent editableEvent = (EditableCalendarEvent) calendarEvent;
+
+ setDates(editableEvent, newStartTime, newEndTime);
+ }
+ }
+
+ /**
+ * Set the start and end dates for the event
+ *
+ * @param event
+ * The event that the start and end dates should be set
+ * @param start
+ * The start date
+ * @param end
+ * The end date
+ */
+ protected void setDates(EditableCalendarEvent event, Date start, Date end) {
+ event.setStart(start);
+ event.setEnd(end);
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java b/server/src/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java
new file mode 100644
index 0000000000..a5307ffd5c
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/handler/BasicForwardHandler.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.handler;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import com.vaadin.shared.ui.calendar.DateConstants;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardHandler;
+
+/**
+ * Implements basic functionality needed to enable forward navigation.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicForwardHandler implements ForwardHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardHandler#forward
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardEvent)
+ */
+ public void forward(ForwardEvent event) {
+ Date start = event.getComponent().getStartDate();
+ Date end = event.getComponent().getEndDate();
+
+ // calculate amount to move forward
+ int durationInDays = (int) (((end.getTime()) - start.getTime()) / DateConstants.DAYINMILLIS);
+ durationInDays++;
+
+ // set new start and end times
+ Calendar javaCalendar = Calendar.getInstance();
+ javaCalendar.setTime(start);
+ javaCalendar.add(java.util.Calendar.DATE, durationInDays);
+ Date newStart = javaCalendar.getTime();
+
+ javaCalendar.setTime(end);
+ javaCalendar.add(java.util.Calendar.DATE, durationInDays);
+ Date newEnd = javaCalendar.getTime();
+
+ setDates(event, newStart, newEnd);
+ }
+
+ /**
+ * Set the start and end dates for the event
+ *
+ * @param event
+ * The event that the start and end dates should be set
+ * @param start
+ * The start date
+ * @param end
+ * The end date
+ */
+ protected void setDates(ForwardEvent event, Date start, Date end) {
+ event.getComponent().setStartDate(start);
+ event.getComponent().setEndDate(end);
+ }
+}
diff --git a/server/src/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java b/server/src/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java
new file mode 100644
index 0000000000..49efe49e48
--- /dev/null
+++ b/server/src/com/vaadin/ui/components/calendar/handler/BasicWeekClickHandler.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2013 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.components.calendar.handler;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClick;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClickHandler;
+
+/**
+ * Implements basic functionality needed to change to week view when a week
+ * number is clicked.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd.
+ */
+@SuppressWarnings("serial")
+public class BasicWeekClickHandler implements WeekClickHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClickHandler
+ * #weekClick
+ * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClick)
+ */
+ public void weekClick(WeekClick event) {
+ int week = event.getWeek();
+ int year = event.getYear();
+
+ // set correct year and month
+ Calendar javaCalendar = event.getComponent().getInternalCalendar();
+ javaCalendar.set(GregorianCalendar.YEAR, year);
+ javaCalendar.set(GregorianCalendar.WEEK_OF_YEAR, week);
+
+ // starting at the beginning of the week
+ javaCalendar.set(GregorianCalendar.DAY_OF_WEEK,
+ javaCalendar.getFirstDayOfWeek());
+ Date start = javaCalendar.getTime();
+
+ // ending at the end of the week
+ javaCalendar.add(GregorianCalendar.DATE, 6);
+ Date end = javaCalendar.getTime();
+
+ setDates(event, start, end);
+
+ // times are automatically expanded, no need to worry about them
+ }
+
+ /**
+ * Set the start and end dates for the event
+ *
+ * @param event
+ * The event that the start and end dates should be set
+ * @param start
+ * The start date
+ * @param end
+ * The end date
+ */
+ protected void setDates(WeekClick event, Date start, Date end) {
+ event.getComponent().setStartDate(start);
+ event.getComponent().setEndDate(end);
+ }
+
+}