12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024 |
- /*
- * Copyright 2000-2016 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.v7.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.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.ui.AbstractComponent;
- import com.vaadin.ui.LegacyComponent;
- import com.vaadin.ui.declarative.DesignAttributeHandler;
- import com.vaadin.ui.declarative.DesignContext;
- import com.vaadin.v7.data.Container;
- import com.vaadin.v7.data.util.BeanItemContainer;
- import com.vaadin.v7.shared.ui.calendar.CalendarEventId;
- import com.vaadin.v7.shared.ui.calendar.CalendarServerRpc;
- import com.vaadin.v7.shared.ui.calendar.CalendarState;
- import com.vaadin.v7.shared.ui.calendar.CalendarState.EventSortOrder;
- import com.vaadin.v7.shared.ui.calendar.DateConstants;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvent;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.BackwardEvent;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.BackwardHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.DateClickEvent;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.DateClickHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.EventClick;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.EventClickHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.EventMoveHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.EventResize;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.EventResizeHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.ForwardEvent;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.ForwardHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.MoveEvent;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.RangeSelectEvent;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.RangeSelectHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.WeekClick;
- import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents.WeekClickHandler;
- import com.vaadin.v7.ui.components.calendar.CalendarDateRange;
- import com.vaadin.v7.ui.components.calendar.CalendarTargetDetails;
- import com.vaadin.v7.ui.components.calendar.ContainerEventProvider;
- import com.vaadin.v7.ui.components.calendar.event.BasicEventProvider;
- import com.vaadin.v7.ui.components.calendar.event.CalendarEditableEventProvider;
- import com.vaadin.v7.ui.components.calendar.event.CalendarEvent;
- import com.vaadin.v7.ui.components.calendar.event.CalendarEvent.EventChangeEvent;
- import com.vaadin.v7.ui.components.calendar.event.CalendarEvent.EventChangeListener;
- import com.vaadin.v7.ui.components.calendar.event.CalendarEventProvider;
- import com.vaadin.v7.ui.components.calendar.handler.BasicBackwardHandler;
- import com.vaadin.v7.ui.components.calendar.handler.BasicDateClickHandler;
- import com.vaadin.v7.ui.components.calendar.handler.BasicEventMoveHandler;
- import com.vaadin.v7.ui.components.calendar.handler.BasicEventResizeHandler;
- import com.vaadin.v7.ui.components.calendar.handler.BasicForwardHandler;
- import com.vaadin.v7.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 CalendarEventProvider}. By
- * default, a {@link BasicEventProvider} is used.</li>
- *
- * @since 7.1
- * @author Vaadin Ltd.
- *
- * @deprecated As of 8.0, no replacement available.
- */
- @SuppressWarnings("serial")
- @Deprecated
- public class Calendar extends AbstractLegacyComponent
- 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.
- */
- @Deprecated
- 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();
-
- /**
- * The cached minimum minute shown when using
- * {@link #autoScaleVisibleHoursOfDay()}.
- */
- private Integer minTimeInMinutes;
-
- /**
- * The cached maximum minute shown when using
- * {@link #autoScaleVisibleHoursOfDay()}.
- */
- private Integer maxTimeInMinutes;
-
- 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 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);
- cacheMinMaxTimeOfDay(events);
-
- 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;
- }
-
- /**
- * Stores the minimum and maximum time-of-day in minutes for the events.
- *
- * @param events
- * A list of calendar events. Can be <code>null</code>.
- */
- private void cacheMinMaxTimeOfDay(List<CalendarEvent> events) {
- minTimeInMinutes = null;
- maxTimeInMinutes = null;
- if (events != null) {
- for (CalendarEvent event : events) {
- int minuteOfDayStart = getMinuteOfDay(event.getStart());
- int minuteOfDayEnd = getMinuteOfDay(event.getEnd());
- if (minTimeInMinutes == null) {
- minTimeInMinutes = minuteOfDayStart;
- maxTimeInMinutes = minuteOfDayEnd;
- } else {
- if (minuteOfDayStart < minTimeInMinutes) {
- minTimeInMinutes = minuteOfDayStart;
- }
- if (minuteOfDayEnd > maxTimeInMinutes) {
- maxTimeInMinutes = minuteOfDayEnd;
- }
- }
- }
- }
- }
-
- private static int getMinuteOfDay(Date date) {
- java.util.Calendar calendar = java.util.Calendar.getInstance();
- calendar.setTime(date);
- return calendar.get(java.util.Calendar.HOUR_OF_DAY) * 60
- + calendar.get(java.util.Calendar.MINUTE);
- }
-
- /**
- * Sets the displayed start and end time to fit all current events that were
- * retrieved from the last call to getEvents().
- * <p>
- * If no events exist, nothing happens.
- * <p>
- * <b>NOTE: triggering this method only does this once for the current
- * events - events that are not in the current visible range, are
- * ignored!</b>
- *
- * @see #setFirstVisibleHourOfDay(int)
- * @see #setLastVisibleHourOfDay(int)
- */
- public void autoScaleVisibleHoursOfDay() {
- if (minTimeInMinutes != null) {
- setFirstVisibleHourOfDay(minTimeInMinutes / 60);
- // Do not show the final hour if last minute ends on it
- setLastVisibleHourOfDay((maxTimeInMinutes - 1) / 60);
- }
- }
-
- /**
- * Resets the {@link #setFirstVisibleHourOfDay(int)} and
- * {@link #setLastVisibleHourOfDay(int)} to the default values, 0 and 23
- * respectively.
- *
- * @see #autoScaleVisibleHoursOfDay()
- * @see #setFirstVisibleHourOfDay(int)
- * @see #setLastVisibleHourOfDay(int)
- */
- public void resetVisibleHoursOfDay() {
- setFirstVisibleHourOfDay(0);
- setLastVisibleHourOfDay(23);
- }
-
- private void setupDaysAndActions() {
- // Make sure we have a up-to-date locale
- initCalendarWithLocale();
-
- CalendarState state = getState();
-
- state.firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
-
- // If only one is null, throw exception
- // If both are null, set defaults
- if (startDate == null ^ endDate == null) {
- String message = "Schedule cannot be painted without a proper date range.\n";
- if (startDate == null) {
- throw new IllegalStateException(message
- + "You must set a start date using setStartDate(Date).");
-
- } else {
- throw new IllegalStateException(message
- + "You must set an end date using setEndDate(Date).");
- }
-
- } else if (startDate == null && endDate == null) {
- // set defaults
- startDate = getStartDate();
- endDate = getEndDate();
- }
-
- int durationInDays = (int) ((endDate.getTime() - startDate.getTime())
- / DateConstants.DAYINMILLIS);
- durationInDays++;
- if (durationInDays > 60) {
- throw new RuntimeException(
- "Daterange is too big (max 60) = " + durationInDays);
- }
-
- state.dayNames = getDayNamesShort();
- state.monthNames = getMonthNamesShort();
-
- // Use same timezone in all dates this component handles.
- // Show "now"-marker in browser within given timezone.
- Date now = new Date();
- currentCalendar.setTime(now);
- now = currentCalendar.getTime();
-
- // Reset time zones for custom date formats
- df_date.setTimeZone(currentCalendar.getTimeZone());
- df_time.setTimeZone(currentCalendar.getTimeZone());
-
- state.now = df_date.format(now) + " " + df_time.format(now);
-
- Date firstDateToShow = expandStartDate(startDate, durationInDays > 7);
- Date lastDateToShow = expandEndDate(endDate, durationInDays > 7);
-
- currentCalendar.setTime(firstDateToShow);
-
- DateFormat weeklyCaptionFormatter = getWeeklyCaptionFormatter();
- weeklyCaptionFormatter.setTimeZone(currentCalendar.getTimeZone());
-
- Map<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>
- * You can use {@link #autoScaleVisibleHoursOfDay()} for automatic scaling
- * of the visible hours based on current events.
- *
- * @param firstHour
- * the first hour of the day to show, between 0 and 23
- * @see #autoScaleVisibleHoursOfDay()
- */
- public void setFirstVisibleHourOfDay(int firstHour) {
- if (this.firstHour != firstHour && firstHour >= 0 && firstHour <= 23
- && firstHour <= getLastVisibleHourOfDay()) {
- this.firstHour = firstHour;
- getState().firstHourOfDay = firstHour;
- }
- }
-
- /**
- * Returns the first visible hour in the week view. Returns the hour using a
- * 24h time format
- *
- */
- public int getFirstVisibleHourOfDay() {
- return firstHour;
- }
-
- /**
- * This method restricts the hours that are shown per day. This affects the
- * weekly view. The general contract is that <b>firstHour < lastHour</b>.
- * <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>
- * You can use {@link #autoScaleVisibleHoursOfDay()} for automatic scaling
- * of the visible hours based on current events.
- *
- * @param lastHour
- * the first hour of the day to show, between 0 and 23
- * @see #autoScaleVisibleHoursOfDay()
- */
- public void setLastVisibleHourOfDay(int lastHour) {
- if (this.lastHour != lastHour && lastHour >= 0 && lastHour <= 23
- && lastHour >= getFirstVisibleHourOfDay()) {
- this.lastHour = lastHour;
- getState().lastHourOfDay = lastHour;
- }
- }
-
- /**
- * Returns the last visible hour in the week view. Returns the hour using a
- * 24h time format
- *
- */
- public int getLastVisibleHourOfDay() {
- return lastHour;
- }
-
- /**
- * Gets the date caption format for the weekly view.
- *
- * @return The pattern used in caption of dates in weekly view.
- */
- public String getWeeklyCaptionFormat() {
- return weeklyCaptionFormat;
- }
-
- /**
- * Sets custom date format for the weekly view. This is the caption of the
- * date. Format could be like "mmm MM/dd".
- *
- * @param dateFormatPattern
- * The date caption pattern.
- */
- public void setWeeklyCaptionFormat(String dateFormatPattern) {
- if (weeklyCaptionFormat == null && dateFormatPattern != null
- || weeklyCaptionFormat != null
- && !weeklyCaptionFormat.equals(dateFormatPattern)) {
- weeklyCaptionFormat = dateFormatPattern;
- markAsDirty();
- }
- }
-
- /**
- * Sets sort order for events. By default sort order is
- * {@link EventSortOrder#DURATION_DESC}.
- *
- * @param order
- * sort strategy for events
- */
- public void setEventSortOrder(EventSortOrder order) {
- if (order == null) {
- getState().eventSortOrder = EventSortOrder.DURATION_DESC;
- } else {
- getState().eventSortOrder = EventSortOrder.values()[order
- .ordinal()];
- }
- }
-
- /**
- * Returns sort order for events.
- *
- * @return currently active sort strategy
- */
- public EventSortOrder getEventSortOrder() {
- EventSortOrder order = getState(false).eventSortOrder;
- if (order == null) {
- return EventSortOrder.DURATION_DESC;
- } else {
- return order;
- }
- }
-
- private DateFormat getWeeklyCaptionFormatter() {
- if (weeklyCaptionFormat != null) {
- return new SimpleDateFormat(weeklyCaptionFormat, getLocale());
- } else {
- return SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT,
- getLocale());
- }
- }
-
- /**
- * Get the day of week by the given calendar and its locale
- *
- * @param calendar
- * The calendar to use
- * @return
- */
- private static int getDowByLocale(java.util.Calendar calendar) {
- int fow = calendar.get(java.util.Calendar.DAY_OF_WEEK);
-
- // monday first
- if (calendar.getFirstDayOfWeek() == java.util.Calendar.MONDAY) {
- fow = fow == java.util.Calendar.SUNDAY ? 7 : fow - 1;
- }
-
- return fow;
- }
-
- /**
- * Is the user allowed to trigger events which alters the events
- *
- * @return true if the client is allowed to send changes to server
- * @see #isEventClickAllowed()
- */
- protected boolean isClientChangeAllowed() {
- return !isReadOnly();
- }
-
- /**
- * Is the user allowed to trigger click events. Returns {@code true} by
- * default. Subclass can override this method to disallow firing event
- * clicks got from the client side.
- *
- * @return true if the client is allowed to click events
- * @see #isClientChangeAllowed()
- * @deprecated As of 7.4, override {@link #fireEventClick(Integer)} instead.
- */
- @Deprecated
- protected boolean isEventClickAllowed() {
- return true;
- }
-
- /**
- * Fires an event when the user selecing moving forward/backward in the
- * calendar.
- *
- * @param forward
- * True if the calendar moved forward else backward is assumed.
- */
- protected void fireNavigationEvent(boolean forward) {
- if (forward) {
- fireEvent(new ForwardEvent(this));
- } else {
- fireEvent(new BackwardEvent(this));
- }
- }
-
- /**
- * Fires an event move event to all server side move listerners
- *
- * @param index
- * The index of the event in the events list
- * @param newFromDatetime
- * The changed from date time
- */
- protected void fireEventMove(int index, Date newFromDatetime) {
- MoveEvent event = new MoveEvent(this, events.get(index),
- newFromDatetime);
-
- if (calendarEventProvider instanceof EventMoveHandler) {
- // Notify event provider if it is an event move handler
- ((EventMoveHandler) calendarEventProvider).eventMove(event);
- }
-
- // Notify event move handler attached by using the
- // setHandler(EventMoveHandler) method
- fireEvent(event);
- }
-
- /**
- * Fires event when a week was clicked in the calendar.
- *
- * @param week
- * The week that was clicked
- * @param year
- * The year of the week
- */
- protected void fireWeekClick(int week, int year) {
- fireEvent(new WeekClick(this, week, year));
- }
-
- /**
- * Fires event when a date was clicked in the calendar. Uses an existing
- * event from the event cache.
- *
- * @param index
- * The index of the event in the event cache.
- */
- protected void fireEventClick(Integer index) {
- fireEvent(new EventClick(this, events.get(index)));
- }
-
- /**
- * Fires event when a date was clicked in the calendar. Creates a new event
- * for the date and passes it to the listener.
- *
- * @param date
- * The date and time that was clicked
- */
- protected void fireDateClick(Date date) {
- fireEvent(new DateClickEvent(this, date));
- }
-
- /**
- * Fires an event range selected event. The event is fired when a user
- * highlights an area in the calendar. The highlighted areas start and end
- * dates are returned as arguments.
- *
- * @param from
- * The start date and time of the highlighted area
- * @param to
- * The end date and time of the highlighted area
- * @param monthlyMode
- * Is the calendar in monthly mode
- */
- protected void fireRangeSelect(Date from, Date to, boolean monthlyMode) {
- fireEvent(new RangeSelectEvent(this, from, to, monthlyMode));
- }
-
- /**
- * Fires an event resize event. The event is fired when a user resizes the
- * event in the calendar causing the time range of the event to increase or
- * decrease. The new start and end times are returned as arguments to this
- * method.
- *
- * @param index
- * The index of the event in the event cache
- * @param startTime
- * The new start date and time of the event
- * @param endTime
- * The new end date and time of the event
- */
- protected void fireEventResize(int index, Date startTime, Date endTime) {
- EventResize event = new EventResize(this, events.get(index), startTime,
- endTime);
-
- if (calendarEventProvider instanceof EventResizeHandler) {
- // Notify event provider if it is an event resize handler
- ((EventResizeHandler) calendarEventProvider).eventResize(event);
- }
-
- // Notify event resize handler attached by using the
- // setHandler(EventMoveHandler) method
- fireEvent(event);
- }
-
- /**
- * Localized display names for week days starting from sunday. Returned
- * array's length is always 7.
- *
- * @return Array of localized weekday names.
- */
- protected String[] getDayNamesShort() {
- DateFormatSymbols s = new DateFormatSymbols(getLocale());
- return Arrays.copyOfRange(s.getWeekdays(), 1, 8);
- }
-
- /**
- * Localized display names for months starting from January. Returned
- * array's length is always 12.
- *
- * @return Array of localized month names.
- */
- protected String[] getMonthNamesShort() {
- DateFormatSymbols s = new DateFormatSymbols(getLocale());
- return Arrays.copyOf(s.getShortMonths(), 12);
- }
-
- /**
- * Gets a date that is first day in the week that target given date belongs
- * to.
- *
- * @param date
- * Target date
- * @return Date that is first date in same week that given date is.
- */
- protected Date getFirstDateForWeek(Date date) {
- int firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
- currentCalendar.setTime(date);
- while (firstDayOfWeek != currentCalendar
- .get(java.util.Calendar.DAY_OF_WEEK)) {
- currentCalendar.add(java.util.Calendar.DATE, -1);
- }
- return currentCalendar.getTime();
- }
-
- /**
- * Gets a date that is last day in the week that target given date belongs
- * to.
- *
- * @param date
- * Target date
- * @return Date that is last date in same week that given date is.
- */
- protected Date getLastDateForWeek(Date date) {
- currentCalendar.setTime(date);
- currentCalendar.add(java.util.Calendar.DATE, 1);
- int firstDayOfWeek = currentCalendar.getFirstDayOfWeek();
- // Roll to weeks last day using firstdayofweek. Roll until FDofW is
- // found and then roll back one day.
- while (firstDayOfWeek != currentCalendar
- .get(java.util.Calendar.DAY_OF_WEEK)) {
- currentCalendar.add(java.util.Calendar.DATE, 1);
- }
- currentCalendar.add(java.util.Calendar.DATE, -1);
- return currentCalendar.getTime();
- }
-
- /**
- * Calculates the end time of the day using the given calendar and date
- *
- * @param date
- * @param calendar
- * the calendar instance to be used in the calculation. The given
- * instance is unchanged in this operation.
- * @return the given date, with time set to the end of the day
- */
- private static Date getEndOfDay(java.util.Calendar calendar, Date date) {
- java.util.Calendar calendarClone = (java.util.Calendar) calendar
- .clone();
-
- calendarClone.setTime(date);
- calendarClone.set(java.util.Calendar.MILLISECOND,
- calendarClone.getActualMaximum(java.util.Calendar.MILLISECOND));
- calendarClone.set(java.util.Calendar.SECOND,
- calendarClone.getActualMaximum(java.util.Calendar.SECOND));
- calendarClone.set(java.util.Calendar.MINUTE,
- calendarClone.getActualMaximum(java.util.Calendar.MINUTE));
- calendarClone.set(java.util.Calendar.HOUR,
- calendarClone.getActualMaximum(java.util.Calendar.HOUR));
- calendarClone.set(java.util.Calendar.HOUR_OF_DAY,
- calendarClone.getActualMaximum(java.util.Calendar.HOUR_OF_DAY));
-
- return calendarClone.getTime();
- }
-
- /**
- * Calculates the end time of the day using the given calendar and date
- *
- * @param date
- * @param calendar
- * the calendar instance to be used in the calculation. The given
- * instance is unchanged in this operation.
- * @return the given date, with time set to the end of the day
- */
- private static Date getStartOfDay(java.util.Calendar calendar, Date date) {
- java.util.Calendar calendarClone = (java.util.Calendar) calendar
- .clone();
-
- calendarClone.setTime(date);
- calendarClone.set(java.util.Calendar.MILLISECOND, 0);
- calendarClone.set(java.util.Calendar.SECOND, 0);
- calendarClone.set(java.util.Calendar.MINUTE, 0);
- calendarClone.set(java.util.Calendar.HOUR, 0);
- calendarClone.set(java.util.Calendar.HOUR_OF_DAY, 0);
-
- return calendarClone.getTime();
- }
-
- /**
- * Finds the first day of the week and returns a day representing the start
- * of that day
- *
- * @param start
- * The actual date
- * @param expandToFullWeek
- * Should the returned date be moved to the start of the week
- * @return If expandToFullWeek is set then it returns the first day of the
- * week, else it returns a clone of the actual date with the time
- * set to the start of the day
- */
- protected Date expandStartDate(Date start, boolean expandToFullWeek) {
- // If the duration is more than week, use monthly view and get startweek
- // and endweek. Example if views daterange is from tuesday to next weeks
- // wednesday->expand to monday to nextweeks sunday. If firstdayofweek =
- // monday
- if (expandToFullWeek) {
- start = getFirstDateForWeek(start);
-
- } else {
- start = (Date) start.clone();
- }
-
- // Always expand to the start of the first day to the end of the last
- // day
- start = getStartOfDay(currentCalendar, start);
-
- return start;
- }
-
- /**
- * Finds the last day of the week and returns a day representing the end of
- * that day
- *
- * @param end
- * The actual date
- * @param expandToFullWeek
- * Should the returned date be moved to the end of the week
- * @return If expandToFullWeek is set then it returns the last day of the
- * week, else it returns a clone of the actual date with the time
- * set to the end of the day
- */
- protected Date expandEndDate(Date end, boolean expandToFullWeek) {
- // If the duration is more than week, use monthly view and get startweek
- // and endweek. Example if views daterange is from tuesday to next weeks
- // wednesday->expand to monday to nextweeks sunday. If firstdayofweek =
- // monday
- if (expandToFullWeek) {
- end = getLastDateForWeek(end);
-
- } else {
- end = (Date) end.clone();
- }
-
- // Always expand to the start of the first day to the end of the last
- // day
- end = getEndOfDay(currentCalendar, end);
-
- return end;
- }
-
- /**
- * Set the {@link CalendarEventProvider} to be used with this calendar. The
- * EventProvider is used to query for events to show, and must be non-null.
- * By default a {@link BasicEventProvider} is used.
- *
- * @param calendarEventProvider
- * the calendarEventProvider to set. Cannot be null.
- */
- public void setEventProvider(CalendarEventProvider calendarEventProvider) {
- if (calendarEventProvider == null) {
- throw new IllegalArgumentException(
- "Calendar event provider cannot be null");
- }
-
- // remove old listener
- if (getEventProvider() instanceof EventSetChangeNotifier) {
- ((EventSetChangeNotifier) getEventProvider())
- .removeEventSetChangeListener(this);
- }
-
- this.calendarEventProvider = calendarEventProvider;
-
- // add new listener
- if (calendarEventProvider instanceof EventSetChangeNotifier) {
- ((EventSetChangeNotifier) calendarEventProvider)
- .addEventSetChangeListener(this);
- }
- }
-
- /**
- * @return the {@link CalendarEventProvider} currently used
- */
- public CalendarEventProvider getEventProvider() {
- return calendarEventProvider;
- }
-
- @Override
- public void eventSetChange(EventSetChangeEvent changeEvent) {
- // sanity check
- if (calendarEventProvider == changeEvent.getProvider()) {
- markAsDirty();
- }
- }
-
- /**
- * Set the handler for the given type information. Mirrors
- * {@link #addListener(String, Class, Object, Method) addListener} from
- * AbstractComponent
- *
- * @param eventId
- * A unique id for the event. Usually one of
- * {@link CalendarEventId}
- * @param eventType
- * The class of the event, most likely a subclass of
- * {@link CalendarComponentEvent}
- * @param listener
- * A listener that listens to the given event
- * @param listenerMethod
- * The method on the lister to call when the event is triggered
- */
- protected void setHandler(String eventId, Class<?> eventType,
- EventListener listener, Method listenerMethod) {
- if (handlers.get(eventId) != null) {
- removeListener(eventId, eventType, handlers.get(eventId));
- handlers.remove(eventId);
- }
-
- if (listener != null) {
- addListener(eventId, eventType, listener, listenerMethod);
- handlers.put(eventId, listener);
- }
- }
-
- @Override
- public void setHandler(ForwardHandler listener) {
- setHandler(ForwardEvent.EVENT_ID, ForwardEvent.class, listener,
- ForwardHandler.forwardMethod);
- }
-
- @Override
- public void setHandler(BackwardHandler listener) {
- setHandler(BackwardEvent.EVENT_ID, BackwardEvent.class, listener,
- BackwardHandler.backwardMethod);
- }
-
- @Override
- public void setHandler(DateClickHandler listener) {
- setHandler(DateClickEvent.EVENT_ID, DateClickEvent.class, listener,
- DateClickHandler.dateClickMethod);
- }
-
- @Override
- public void setHandler(EventClickHandler listener) {
- setHandler(EventClick.EVENT_ID, EventClick.class, listener,
- EventClickHandler.eventClickMethod);
- }
-
- @Override
- public void setHandler(WeekClickHandler listener) {
- setHandler(WeekClick.EVENT_ID, WeekClick.class, listener,
- WeekClickHandler.weekClickMethod);
- }
-
- @Override
- public void setHandler(EventResizeHandler listener) {
- setHandler(EventResize.EVENT_ID, EventResize.class, listener,
- EventResizeHandler.eventResizeMethod);
- }
-
- @Override
- public void setHandler(RangeSelectHandler listener) {
- setHandler(RangeSelectEvent.EVENT_ID, RangeSelectEvent.class, listener,
- RangeSelectHandler.rangeSelectMethod);
-
- }
-
- @Override
- public void setHandler(EventMoveHandler listener) {
- setHandler(MoveEvent.EVENT_ID, MoveEvent.class, listener,
- EventMoveHandler.eventMoveMethod);
- }
-
- @Override
- public EventListener getHandler(String eventId) {
- return handlers.get(eventId);
- }
-
- /**
- * Get the currently active drop handler
- */
- @Override
- public DropHandler getDropHandler() {
- return dropHandler;
- }
-
- /**
- * Set the drop handler for the calendar See {@link DropHandler} for
- * implementation details.
- *
- * @param dropHandler
- * The drop handler to set
- */
- public void setDropHandler(DropHandler dropHandler) {
- this.dropHandler = dropHandler;
- }
-
- @Override
- public TargetDetails translateDropTargetDetails(
- Map<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(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);
- }
-
- @Override
- public List<CalendarEvent> getEvents(Date startDate, Date endDate) {
- List<CalendarEvent> events = getEventProvider().getEvents(startDate,
- endDate);
- cacheMinMaxTimeOfDay(events);
- return events;
- }
-
- @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");
- }
- }
-
- @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<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;
- }
- }
-
- @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));
- }
- }
- }
-
- @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.
- */
- }
-
- @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 independent of Locale. Set to null if you
- * want first day of week being defined by the locale
- *
- * @since 7.6
- * @param dayOfWeek
- * any of java.util.Calendar.SUNDAY..java.util.Calendar.SATURDAY
- * or null to revert to default first day of week by locale
- */
- 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();
- }
- }
|