1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020 |
- /*
- * Copyright 2000-2014 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
- package com.vaadin.ui;
-
- import java.lang.reflect.Method;
- import java.text.DateFormat;
- import java.text.DateFormatSymbols;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Date;
- import java.util.EventListener;
- import java.util.GregorianCalendar;
- import java.util.HashMap;
- import java.util.LinkedHashSet;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.Set;
- import java.util.TimeZone;
- import java.util.logging.Level;
- import java.util.logging.Logger;
-
- import org.jsoup.nodes.Attributes;
- import org.jsoup.nodes.Element;
-
- import com.vaadin.data.Container;
- import com.vaadin.data.util.BeanItemContainer;
- import com.vaadin.event.Action;
- import com.vaadin.event.Action.Handler;
- import com.vaadin.event.dd.DropHandler;
- import com.vaadin.event.dd.DropTarget;
- import com.vaadin.event.dd.TargetDetails;
- import com.vaadin.server.KeyMapper;
- import com.vaadin.server.PaintException;
- import com.vaadin.server.PaintTarget;
- import com.vaadin.shared.ui.calendar.CalendarEventId;
- import com.vaadin.shared.ui.calendar.CalendarServerRpc;
- import com.vaadin.shared.ui.calendar.CalendarState;
- import com.vaadin.shared.ui.calendar.DateConstants;
- import com.vaadin.ui.components.calendar.CalendarComponentEvent;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardEvent;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.BackwardHandler;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickHandler;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClick;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClickHandler;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventMoveHandler;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResize;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardEvent;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.ForwardHandler;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.RangeSelectEvent;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.RangeSelectHandler;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClick;
- import com.vaadin.ui.components.calendar.CalendarComponentEvents.WeekClickHandler;
- import com.vaadin.ui.components.calendar.CalendarDateRange;
- import com.vaadin.ui.components.calendar.CalendarTargetDetails;
- import com.vaadin.ui.components.calendar.ContainerEventProvider;
- import com.vaadin.ui.components.calendar.event.BasicEventProvider;
- import com.vaadin.ui.components.calendar.event.CalendarEditableEventProvider;
- import com.vaadin.ui.components.calendar.event.CalendarEvent;
- import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeEvent;
- import com.vaadin.ui.components.calendar.event.CalendarEvent.EventChangeListener;
- import com.vaadin.ui.components.calendar.event.CalendarEventProvider;
- import com.vaadin.ui.components.calendar.handler.BasicBackwardHandler;
- import com.vaadin.ui.components.calendar.handler.BasicDateClickHandler;
- import com.vaadin.ui.components.calendar.handler.BasicEventMoveHandler;
- import com.vaadin.ui.components.calendar.handler.BasicEventResizeHandler;
- import com.vaadin.ui.components.calendar.handler.BasicForwardHandler;
- import com.vaadin.ui.components.calendar.handler.BasicWeekClickHandler;
- import com.vaadin.ui.declarative.DesignAttributeHandler;
- import com.vaadin.ui.declarative.DesignContext;
-
- /**
- * <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, LegacyComponent {
-
- /**
- * 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();
-
- private Integer customFirstDayOfWeek;
-
- /**
- * 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
- protected CalendarState getState(boolean markAsDirty) {
- return (CalendarState) super.getState(markAsDirty);
- }
-
- @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.MILLISECOND, 0);
- currentCalendar.set(java.util.Calendar.SECOND, 0);
- currentCalendar.set(java.util.Calendar.MINUTE, 0);
- currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
- 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.MILLISECOND, 0);
- currentCalendar.set(java.util.Calendar.SECOND, 59);
- currentCalendar.set(java.util.Calendar.MINUTE, 59);
- currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 23);
- 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());
- }
-
- if (customFirstDayOfWeek != null) {
- currentCalendar.setFirstDayOfWeek(customFirstDayOfWeek);
- }
- }
-
- 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 = getWeek(currentCalendar);
- day.yearOfWeek = getYearOfWeek(currentCalendar);
-
- 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);
- cal.add(java.util.Calendar.SECOND, -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 int getWeek(java.util.Calendar calendar) {
- return calendar.get(java.util.Calendar.WEEK_OF_YEAR);
- }
-
- private int getYearOfWeek(java.util.Calendar calendar) {
- // Would use calendar.getWeekYear() but it's only available since 1.7.
- int week = getWeek(calendar);
- int month = calendar.get(java.util.Calendar.MONTH);
- int year = calendar.get(java.util.Calendar.YEAR);
-
- if (week == 1 && month == java.util.Calendar.DECEMBER) {
- return year + 1;
- }
-
- return year;
- }
-
- 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 LinkedHashSet<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 LinkedHashSet<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;
- if (getLocale() == null) {
- f = (SimpleDateFormat) SimpleDateFormat
- .getTimeInstance(SimpleDateFormat.SHORT);
- } else {
- 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();
- }
-
- /**
- * Is the user allowed to trigger click events. Returns {@code true} by
- * default. Subclass can override this method to disallow firing event
- * clicks got from the client side.
- *
- * @return true if the client is allowed to click events
- * @see #isClientChangeAllowed()
- * @deprecated As of 7.4, override {@link #fireEventClick(Integer)} instead.
- */
- @Deprecated
- protected boolean isEventClickAllowed() {
- return true;
- }
-
- /**
- * Fires an event when the user selecing moving forward/backward in the
- * calendar.
- *
- * @param forward
- * True if the calendar moved forward else backward is assumed.
- */
- protected void fireNavigationEvent(boolean forward) {
- if (forward) {
- fireEvent(new ForwardEvent(this));
- } else {
- fireEvent(new BackwardEvent(this));
- }
- }
-
- /**
- * Fires an event move event to all server side move listerners
- *
- * @param index
- * The index of the event in the events list
- * @param newFromDatetime
- * The changed from date time
- */
- protected void fireEventMove(int index, Date newFromDatetime) {
- MoveEvent event = new MoveEvent(this, events.get(index),
- newFromDatetime);
-
- if (calendarEventProvider instanceof EventMoveHandler) {
- // Notify event provider if it is an event move handler
- ((EventMoveHandler) calendarEventProvider).eventMove(event);
- }
-
- // Notify event move handler attached by using the
- // setHandler(EventMoveHandler) method
- fireEvent(event);
- }
-
- /**
- * Fires event when a week was clicked in the calendar.
- *
- * @param week
- * The week that was clicked
- * @param year
- * The year of the week
- */
- protected void fireWeekClick(int week, int year) {
- fireEvent(new WeekClick(this, week, year));
- }
-
- /**
- * Fires event when a date was clicked in the calendar. Uses an existing
- * event from the event cache.
- *
- * @param index
- * The index of the event in the event cache.
- */
- protected void fireEventClick(Integer index) {
- fireEvent(new EventClick(this, events.get(index)));
- }
-
- /**
- * Fires event when a date was clicked in the calendar. Creates a new event
- * for the date and passes it to the listener.
- *
- * @param date
- * The date and time that was clicked
- */
- protected void fireDateClick(Date date) {
- fireEvent(new DateClickEvent(this, date));
- }
-
- /**
- * Fires an event range selected event. The event is fired when a user
- * highlights an area in the calendar. The highlighted areas start and end
- * dates are returned as arguments.
- *
- * @param from
- * The start date and time of the highlighted area
- * @param to
- * The end date and time of the highlighted area
- * @param monthlyMode
- * Is the calendar in monthly mode
- */
- protected void fireRangeSelect(Date from, Date to, boolean monthlyMode) {
- fireEvent(new RangeSelectEvent(this, from, to, monthlyMode));
- }
-
- /**
- * Fires an event resize event. The event is fired when a user resizes the
- * event in the calendar causing the time range of the event to increase or
- * decrease. The new start and end times are returned as arguments to this
- * method.
- *
- * @param index
- * The index of the event in the event cache
- * @param startTime
- * The new start date and time of the event
- * @param endTime
- * The new end date and time of the event
- */
- protected void fireEventResize(int index, Date startTime, Date endTime) {
- EventResize event = new EventResize(this, events.get(index), startTime,
- endTime);
-
- if (calendarEventProvider instanceof EventResizeHandler) {
- // Notify event provider if it is an event resize handler
- ((EventResizeHandler) calendarEventProvider).eventResize(event);
- }
-
- // Notify event resize handler attached by using the
- // setHandler(EventMoveHandler) method
- fireEvent(event);
- }
-
- /**
- * Localized display names for week days starting from sunday. Returned
- * array's length is always 7.
- *
- * @return Array of localized weekday names.
- */
- protected String[] getDayNamesShort() {
- DateFormatSymbols s = new DateFormatSymbols(getLocale());
- return Arrays.copyOfRange(s.getWeekdays(), 1, 8);
- }
-
- /**
- * Localized display names for months starting from January. Returned
- * array's length is always 12.
- *
- * @return Array of localized month names.
- */
- protected String[] getMonthNamesShort() {
- DateFormatSymbols s = new DateFormatSymbols(getLocale());
- return Arrays.copyOf(s.getShortMonths(), 12);
- }
-
- /**
- * Gets a date that is first day in the week that target given date belongs
- * to.
- *
- * @param date
- * Target date
- * @return Date that is first date in same week that given date is.
- */
- protected Date getFirstDateForWeek(Date date) {
- int firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
- currentCalendar.setTime(date);
- while (firstDayOfWeek != currentCalendar
- .get(java.util.Calendar.DAY_OF_WEEK)) {
- currentCalendar.add(java.util.Calendar.DATE, -1);
- }
- return currentCalendar.getTime();
- }
-
- /**
- * Gets a date that is last day in the week that target given date belongs
- * to.
- *
- * @param date
- * Target date
- * @return Date that is last date in same week that given date is.
- */
- protected Date getLastDateForWeek(Date date) {
- currentCalendar.setTime(date);
- currentCalendar.add(java.util.Calendar.DATE, 1);
- int firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
- // Roll to weeks last day using firstdayofweek. Roll until FDofW is
- // found and then roll back one day.
- while (firstDayOfWeek != currentCalendar
- .get(java.util.Calendar.DAY_OF_WEEK)) {
- currentCalendar.add(java.util.Calendar.DATE, 1);
- }
- currentCalendar.add(java.util.Calendar.DATE, -1);
- return currentCalendar.getTime();
- }
-
- /**
- * Calculates the end time of the day using the given calendar and date
- *
- * @param date
- * @param calendar
- * the calendar instance to be used in the calculation. The given
- * instance is unchanged in this operation.
- * @return the given date, with time set to the end of the day
- */
- private static Date getEndOfDay(java.util.Calendar calendar, Date date) {
- java.util.Calendar calendarClone = (java.util.Calendar) calendar
- .clone();
-
- calendarClone.setTime(date);
- calendarClone.set(java.util.Calendar.MILLISECOND,
- calendarClone.getActualMaximum(java.util.Calendar.MILLISECOND));
- calendarClone.set(java.util.Calendar.SECOND,
- calendarClone.getActualMaximum(java.util.Calendar.SECOND));
- calendarClone.set(java.util.Calendar.MINUTE,
- calendarClone.getActualMaximum(java.util.Calendar.MINUTE));
- calendarClone.set(java.util.Calendar.HOUR,
- calendarClone.getActualMaximum(java.util.Calendar.HOUR));
- calendarClone.set(java.util.Calendar.HOUR_OF_DAY,
- calendarClone.getActualMaximum(java.util.Calendar.HOUR_OF_DAY));
-
- return calendarClone.getTime();
- }
-
- /**
- * Calculates the end time of the day using the given calendar and date
- *
- * @param date
- * @param calendar
- * the calendar instance to be used in the calculation. The given
- * instance is unchanged in this operation.
- * @return the given date, with time set to the end of the day
- */
- private static Date getStartOfDay(java.util.Calendar calendar, Date date) {
- java.util.Calendar calendarClone = (java.util.Calendar) calendar
- .clone();
-
- calendarClone.setTime(date);
- calendarClone.set(java.util.Calendar.MILLISECOND, 0);
- calendarClone.set(java.util.Calendar.SECOND, 0);
- calendarClone.set(java.util.Calendar.MINUTE, 0);
- calendarClone.set(java.util.Calendar.HOUR, 0);
- calendarClone.set(java.util.Calendar.HOUR_OF_DAY, 0);
-
- return calendarClone.getTime();
- }
-
- /**
- * Finds the first day of the week and returns a day representing the start
- * of that day
- *
- * @param start
- * The actual date
- * @param expandToFullWeek
- * Should the returned date be moved to the start of the week
- * @return If expandToFullWeek is set then it returns the first day of the
- * week, else it returns a clone of the actual date with the time
- * set to the start of the day
- */
- protected Date expandStartDate(Date start, boolean expandToFullWeek) {
- // If the duration is more than week, use monthly view and get startweek
- // and endweek. Example if views daterange is from tuesday to next weeks
- // wednesday->expand to monday to nextweeks sunday. If firstdayofweek =
- // monday
- if (expandToFullWeek) {
- start = getFirstDateForWeek(start);
-
- } else {
- start = (Date) start.clone();
- }
-
- // Always expand to the start of the first day to the end of the last
- // day
- start = getStartOfDay(currentCalendar, start);
-
- return start;
- }
-
- /**
- * Finds the last day of the week and returns a day representing the end of
- * that day
- *
- * @param end
- * The actual date
- * @param expandToFullWeek
- * Should the returned date be moved to the end of the week
- * @return If expandToFullWeek is set then it returns the last day of the
- * week, else it returns a clone of the actual date with the time
- * set to the end of the day
- */
- protected Date expandEndDate(Date end, boolean expandToFullWeek) {
- // If the duration is more than week, use monthly view and get startweek
- // and endweek. Example if views daterange is from tuesday to next weeks
- // wednesday->expand to monday to nextweeks sunday. If firstdayofweek =
- // monday
- if (expandToFullWeek) {
- end = getLastDateForWeek(end);
-
- } else {
- end = (Date) end.clone();
- }
-
- // Always expand to the start of the first day to the end of the last
- // day
- end = getEndOfDay(currentCalendar, end);
-
- return end;
- }
-
- /**
- * Set the {@link 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)
- */
- @Override
- public void eventSetChange(EventSetChangeEvent changeEvent) {
- // sanity check
- if (calendarEventProvider == changeEvent.getProvider()) {
- markAsDirty();
- }
- }
-
- /**
- * Set the handler for the given type information. Mirrors
- * {@link #addListener(String, Class, Object, Method) addListener} from
- * AbstractComponent
- *
- * @param eventId
- * A unique id for the event. Usually one of
- * {@link CalendarEventId}
- * @param eventType
- * The class of the event, most likely a subclass of
- * {@link CalendarComponentEvent}
- * @param listener
- * A listener that listens to the given event
- * @param listenerMethod
- * The method on the lister to call when the event is triggered
- */
- protected void setHandler(String eventId, Class<?> eventType,
- EventListener listener, Method listenerMethod) {
- if (handlers.get(eventId) != null) {
- removeListener(eventId, eventType, handlers.get(eventId));
- handlers.remove(eventId);
- }
-
- if (listener != null) {
- addListener(eventId, eventType, listener, listenerMethod);
- handlers.put(eventId, listener);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.calendar.ui.CalendarComponentEvents.NavigationNotifier
- * #addListener
- * (com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardHandler)
- */
- @Override
- 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)
- */
- @Override
- 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)
- */
- @Override
- 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)
- */
- @Override
- 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)
- */
- @Override
- 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
- * )
- */
- @Override
- 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
- * )
- */
- @Override
- 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)
- */
- @Override
- 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)
- */
- @Override
- public EventListener getHandler(String eventId) {
- return handlers.get(eventId);
- }
-
- /**
- * Get the currently active drop handler
- */
- @Override
- public DropHandler getDropHandler() {
- return dropHandler;
- }
-
- /**
- * Set the drop handler for the calendar See {@link DropHandler} for
- * implementation details.
- *
- * @param dropHandler
- * The drop handler to set
- */
- public void setDropHandler(DropHandler dropHandler) {
- this.dropHandler = dropHandler;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.DropTarget#translateDropTargetDetails(java.util.Map)
- */
- @Override
- public TargetDetails translateDropTargetDetails(
- Map<String, Object> clientVariables) {
- Map<String, Object> serverVariables = new HashMap<String, Object>();
-
- 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());
- }
- serverVariables.put("mouseEvent", clientVariables.get("mouseEvent"));
-
- 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() {
- @Override
- public void eventSetChange(EventSetChangeEvent changeEvent) {
- // Repaint if events change
- markAsDirty();
- }
- });
- provider.addEventChangeListener(new EventChangeListener() {
- @Override
- public void eventChange(EventChangeEvent changeEvent) {
- // Repaint if event changes
- markAsDirty();
- }
- });
- setEventProvider(provider);
- }
-
- /**
- * Sets a container as a data source for the events in the calendar.
- * Equivalent for doing
- * <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() {
- @Override
- public void eventSetChange(EventSetChangeEvent changeEvent) {
- // Repaint if events change
- markAsDirty();
- }
- });
- provider.addEventChangeListener(new EventChangeListener() {
- @Override
- public void eventChange(EventChangeEvent changeEvent) {
- // Repaint if event changes
- markAsDirty();
- }
- });
- setEventProvider(provider);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.calendar.event.CalendarEventProvider#getEvents(java.
- * util.Date, java.util.Date)
- */
- @Override
- 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)
- */
- @Override
- 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)
- */
- @Override
- 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>
- */
- @Override
- 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 = 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)
- */
- @Override
- 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 (date != null && date.length() > 6) {
- try {
- Date d = df_date.parse(date);
- fireDateClick(d);
- } catch (ParseException e) {
- }
- }
- }
-
- @Override
- public void weekClick(String event) {
- if (event.length() > 0 && event.contains("w")) {
- String[] splitted = event.split("w");
- if (splitted.length == 2) {
- try {
- int yr = 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, Calendar.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, Calendar.this, events.get(eventIndex));
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.server.VariableOwner#changeVariables(java.lang.Object,
- * java.util.Map)
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- /*
- * Only defined to fulfill the LegacyComponent interface used for
- * calendar drag & drop. No implementation required.
- */
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.ui.LegacyComponent#paintContent(com.vaadin.server.PaintTarget)
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (dropHandler != null) {
- dropHandler.getAcceptCriterion().paint(target);
- }
- }
-
- /**
- * Sets whether the event captions are rendered as HTML.
- * <p>
- * If set to true, the captions are rendered in the browser as HTML and the
- * developer is responsible for ensuring no harmful HTML is used. If set to
- * false, the caption is rendered in the browser as plain text.
- * <p>
- * The default is false, i.e. to render that caption as plain text.
- *
- * @param captionAsHtml
- * true if the captions are rendered as HTML, false if rendered
- * as plain text
- */
- public void setEventCaptionAsHtml(boolean eventCaptionAsHtml) {
- getState().eventCaptionAsHtml = eventCaptionAsHtml;
- }
-
- /**
- * Checks whether event captions are rendered as HTML
- * <p>
- * The default is false, i.e. to render that caption as plain text.
- *
- * @return true if the captions are rendered as HTML, false if rendered as
- * plain text
- */
- public boolean isEventCaptionAsHtml() {
- return getState(false).eventCaptionAsHtml;
- }
-
- @Override
- public void readDesign(Element design, DesignContext designContext) {
- super.readDesign(design, designContext);
-
- Attributes attr = design.attributes();
- if (design.hasAttr("time-format")) {
- setTimeFormat(TimeFormat.valueOf("Format"
- + design.attr("time-format").toUpperCase()));
- }
-
- if (design.hasAttr("start-date")) {
- setStartDate(DesignAttributeHandler.readAttribute("start-date",
- attr, Date.class));
- }
- if (design.hasAttr("end-date")) {
- setEndDate(DesignAttributeHandler.readAttribute("end-date", attr,
- Date.class));
- }
- };
-
- @Override
- public void writeDesign(Element design, DesignContext designContext) {
- super.writeDesign(design, designContext);
-
- if (currentTimeFormat != null) {
- design.attr("time-format",
- (currentTimeFormat == TimeFormat.Format12H ? "12h" : "24h"));
- }
- if (startDate != null) {
- design.attr("start-date", df_date.format(getStartDate()));
- }
- if (endDate != null) {
- design.attr("end-date", df_date.format(getEndDate()));
- }
- if (!getTimeZone().equals(TimeZone.getDefault())) {
- design.attr("time-zone", getTimeZone().getID());
- }
- }
-
- @Override
- protected Collection<String> getCustomAttributes() {
- Collection<String> customAttributes = super.getCustomAttributes();
- customAttributes.add("time-format");
- customAttributes.add("start-date");
- customAttributes.add("end-date");
- return customAttributes;
- }
-
- /**
- * Allow setting first day of week depending on Locale. Set to null if you
- * want first day of week depend on locale
- *
- * @since 7.6
- * @param dayOfWeek
- */
- public void setFirstDayOfWeek(Integer dayOfWeek) {
- int minimalSupported = java.util.Calendar.SUNDAY;
- int maximalSupported = java.util.Calendar.SATURDAY;
- if (dayOfWeek != null
- && (dayOfWeek < minimalSupported || dayOfWeek > maximalSupported)) {
- throw new IllegalArgumentException(
- String.format(
- "Day of week must be between %s and %s. Actually received: %s",
- minimalSupported, maximalSupported, dayOfWeek));
- }
- customFirstDayOfWeek = dayOfWeek;
- markAsDirty();
- }
- }
|