All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vaadin.v7.client.ui.VCalendar Maven / Gradle / Ivy

There is a newer version: 8.27.3
Show newest version
/*
 * Copyright (C) 2000-2024 Vaadin Ltd
 *
 * This program is available under Vaadin Commercial License and Service Terms.
 *
 * See  for the full
 * license.
 */
package com.vaadin.v7.client.ui;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.dd.VHasDropHandler;
import com.vaadin.v7.client.ui.calendar.schedule.CalendarDay;
import com.vaadin.v7.client.ui.calendar.schedule.CalendarEvent;
import com.vaadin.v7.client.ui.calendar.schedule.DayToolbar;
import com.vaadin.v7.client.ui.calendar.schedule.MonthGrid;
import com.vaadin.v7.client.ui.calendar.schedule.SimpleDayCell;
import com.vaadin.v7.client.ui.calendar.schedule.SimpleDayToolbar;
import com.vaadin.v7.client.ui.calendar.schedule.SimpleWeekToolbar;
import com.vaadin.v7.client.ui.calendar.schedule.WeekGrid;
import com.vaadin.v7.client.ui.calendar.schedule.WeeklyLongEvents;
import com.vaadin.v7.client.ui.calendar.schedule.dd.CalendarDropHandler;
import com.vaadin.v7.shared.ui.calendar.CalendarState.EventSortOrder;
import com.vaadin.v7.shared.ui.calendar.DateConstants;

/**
 * Client side implementation for Calendar.
 *
 * @since 7.1
 * @author Vaadin Ltd.
 */
public class VCalendar extends Composite implements VHasDropHandler {

    public static final String ATTR_FIRSTDAYOFWEEK = "firstDay";
    public static final String ATTR_LASTDAYOFWEEK = "lastDay";
    public static final String ATTR_FIRSTHOUROFDAY = "firstHour";
    public static final String ATTR_LASTHOUROFDAY = "lastHour";

    // private boolean hideWeekends;
    private String[] monthNames;
    private String[] dayNames;
    private boolean format;
    private final DockPanel outer = new DockPanel();
    private int rows;

    private boolean rangeSelectAllowed = true;
    private boolean rangeMoveAllowed = true;
    private boolean eventResizeAllowed = true;
    private boolean eventMoveAllowed = true;

    private final SimpleDayToolbar nameToolbar = new SimpleDayToolbar();

    private final DayToolbar dayToolbar = new DayToolbar(this);
    private final SimpleWeekToolbar weekToolbar;
    private WeeklyLongEvents weeklyLongEvents;
    private MonthGrid monthGrid;
    private WeekGrid weekGrid;
    private int intWidth = 0;
    private int intHeight = 0;

    protected final DateTimeFormat dateformat_datetime = DateTimeFormat
            .getFormat("yyyy-MM-dd HH:mm:ss");
    protected final DateTimeFormat dateformat_date = DateTimeFormat
            .getFormat("yyyy-MM-dd");
    protected final DateTimeFormat time12format_date = DateTimeFormat
            .getFormat("h:mm a");
    protected final DateTimeFormat time24format_date = DateTimeFormat
            .getFormat("HH:mm");

    private boolean readOnly = false;
    private boolean disabled = false;

    private boolean isHeightUndefined = false;

    private boolean isWidthUndefined = false;
    private int firstDay;
    private int lastDay;
    private int firstHour;
    private int lastHour;

    private EventSortOrder eventSortOrder = EventSortOrder.DURATION_DESC;

    private static final EventDurationComparator DEFAULT_COMPARATOR = new EventDurationComparator(
            false);

    private CalendarDropHandler dropHandler;

    /**
     * Listener interface for listening to event click events.
     */
    public interface DateClickListener {
        /**
         * Triggered when a date was clicked.
         *
         * @param date
         *            The date and time that was clicked
         */
        void dateClick(String date);
    }

    /**
     * Listener interface for listening to week number click events.
     */
    public interface WeekClickListener {
        /**
         * Called when a week number was selected.
         *
         * @param event
         *            The format of the vent string is "w"
         */
        void weekClick(String event);
    }

    /**
     * Listener interface for listening to forward events.
     */
    public interface ForwardListener {

        /**
         * Called when the calendar should move one view forward.
         */
        void forward();
    }

    /**
     * Listener interface for listening to backward events.
     */
    public interface BackwardListener {

        /**
         * Called when the calendar should move one view backward.
         */
        void backward();
    }

    /**
     * Listener interface for listening to selection events.
     */
    public interface RangeSelectListener {

        /**
         * Called when a user selected a new event by highlighting an area of
         * the calendar.
         *
         * FIXME Fix the value nonsense.
         *
         * @param value
         *            The format of the value string is
         *            "::" if called from the
         *            {@link SimpleWeekToolbar} and "TO"
         *            if called from {@link MonthGrid}
         */
        void rangeSelected(String value);
    }

    /**
     * Listener interface for listening to click events.
     */
    public interface EventClickListener {
        /**
         * Called when an event was clicked.
         *
         * @param event
         *            The event that was clicked
         */
        void eventClick(CalendarEvent event);
    }

    /**
     * Listener interface for listening to event moved events. Occurs when a
     * user drags an event to a new position
     */
    public interface EventMovedListener {
        /**
         * Triggered when an event was dragged to a new position and the start
         * and end dates was changed.
         *
         * @param event
         *            The event that was moved
         */
        void eventMoved(CalendarEvent event);
    }

    /**
     * Listener interface for when an event gets resized (its start or end date
     * changes).
     */
    public interface EventResizeListener {
        /**
         * Triggers when the time limits for the event was changed.
         *
         * @param event
         *            The event that was changed. The new time limits have been
         *            updated in the event before calling this method
         */
        void eventResized(CalendarEvent event);
    }

    /**
     * Listener interface for listening to scroll events.
     */
    public interface ScrollListener {
        /**
         * Triggered when the calendar is scrolled.
         *
         * @param scrollPosition
         *            The scroll position in pixels as returned by
         *            {@link ScrollPanel#getScrollPosition()}
         */
        void scroll(int scrollPosition);
    }

    /**
     * Listener interface for listening to mouse events.
     */
    public interface MouseEventListener {
        /**
         * Triggered when a user wants an context menu.
         *
         * @param event
         *            The context menu event
         *
         * @param widget
         *            The widget that the context menu should be added to
         */
        void contextMenu(ContextMenuEvent event, Widget widget);
    }

    private abstract static class AbstractEventComparator
            implements Comparator {

        @Override
        public int compare(CalendarEvent e1, CalendarEvent e2) {
            if (e1.isAllDay() != e2.isAllDay()) {
                if (e2.isAllDay()) {
                    return 1;
                }
                return -1;
            }
            int result = doCompare(e1, e2);
            if (result == 0) {
                return indexCompare(e1, e2);
            }
            return result;
        }

        protected int indexCompare(CalendarEvent e1, CalendarEvent e2) {
            return ((Integer) e2.getIndex()).compareTo(e1.getIndex());
        }

        protected abstract int doCompare(CalendarEvent o1, CalendarEvent o2);
    }

    private static class EventDurationComparator
            extends AbstractEventComparator {

        EventDurationComparator(boolean ascending) {
            isAscending = ascending;
        }

        @Override
        public int doCompare(CalendarEvent e1, CalendarEvent e2) {
            int result = durationCompare(e1, e2, isAscending);
            if (result == 0) {
                return StartDateComparator.startDateCompare(e1, e2,
                        isAscending);
            }
            return result;
        }

        static int durationCompare(CalendarEvent e1, CalendarEvent e2,
                boolean ascending) {
            int result = doDurationCompare(e1, e2);
            return ascending ? -result : result;
        }

        private static int doDurationCompare(CalendarEvent e1,
                CalendarEvent e2) {
            Long d1 = e1.getRangeInMilliseconds();
            Long d2 = e2.getRangeInMilliseconds();
            if (!d1.equals(0L) && !d2.equals(0L)) {
                return d2.compareTo(d1);
            }

            if (d2.equals(0L) && d1.equals(0L)) {
                return 0;
            } else if (d2.equals(0L) && d1 >= DateConstants.DAYINMILLIS) {
                return -1;
            } else if (d2.equals(0L) && d1 < DateConstants.DAYINMILLIS) {
                return 1;
            } else if (d1.equals(0L) && d2 >= DateConstants.DAYINMILLIS) {
                return 1;
            } else if (d1.equals(0L) && d2 < DateConstants.DAYINMILLIS) {
                return -1;
            }
            return d2.compareTo(d1);
        }

        private boolean isAscending;

    }

    private static class StartDateComparator extends AbstractEventComparator {

        StartDateComparator(boolean ascending) {
            isAscending = ascending;
        }

        @Override
        public int doCompare(CalendarEvent e1, CalendarEvent e2) {
            int result = startDateCompare(e1, e2, isAscending);
            if (result == 0) {
                // show a longer event after a shorter event
                return EventDurationComparator.durationCompare(e1, e2,
                        isAscending);
            }
            return result;
        }

        static int startDateCompare(CalendarEvent e1, CalendarEvent e2,
                boolean ascending) {
            int result = e1.getStartTime().compareTo(e2.getStartTime());
            return ascending ? -result : result;
        }

        private boolean isAscending;
    }

    /**
     * Default constructor.
     */
    public VCalendar() {
        weekToolbar = new SimpleWeekToolbar(this);
        initWidget(outer);
        setStylePrimaryName("v-calendar");
        blockSelect(getElement());
    }

    /**
     * Hack for IE to not select text when dragging.
     *
     * @param e
     *            The element to apply the hack on
     */
    private native void blockSelect(Element e)
    /*-{
        e.onselectstart = function() {
            return false;
        }

        e.ondragstart = function() {
            return false;
        }
    }-*/;

    private void updateEventsToWeekGrid(CalendarEvent[] events) {
        List allDayLong = new ArrayList();
        List belowDayLong = new ArrayList();

        for (CalendarEvent e : events) {
            if (e.isAllDay()) {
                // Event is set on one "allDay" event or more than one.
                allDayLong.add(e);

            } else {
                // Event is set only on one day.
                belowDayLong.add(e);
            }
        }

        weeklyLongEvents.addEvents(allDayLong);

        for (CalendarEvent e : belowDayLong) {
            weekGrid.addEvent(e);
        }
    }

    /**
     * Adds events to the month grid.
     *
     * @param events
     *            The events to add
     * @param drawImmediately
     *            Should the grid be rendered immediately. (currently not in
     *            use)
     *
     */
    public void updateEventsToMonthGrid(Collection events,
            boolean drawImmediately) {
        for (CalendarEvent e : sortEvents(events)) {
            // FIXME Why is drawImmediately not used ?????
            addEventToMonthGrid(e, false);
        }
    }

    private void addEventToMonthGrid(CalendarEvent e,
            boolean renderImmediately) {
        Date when = e.getStart();
        Date to = e.getEnd();
        boolean eventAdded = false;
        boolean inProgress = false; // Event adding has started
        boolean eventMoving = false;
        List dayCells = new ArrayList();
        List timeCells = new ArrayList();
        for (int row = 0; row < monthGrid.getRowCount(); row++) {
            if (eventAdded) {
                break;
            }
            for (int cell = 0; cell < monthGrid.getCellCount(row); cell++) {
                SimpleDayCell sdc = (SimpleDayCell) monthGrid.getWidget(row,
                        cell);
                if (isEventInDay(when, to, sdc.getDate())
                        && isEventInDayWithTime(when, to, sdc.getDate(),
                                e.getEndTime(), e.isAllDay())) {
                    if (!eventMoving) {
                        eventMoving = sdc.getMoveEvent() != null;
                    }
                    long d = e.getRangeInMilliseconds();
                    if ((d > 0 && d <= DateConstants.DAYINMILLIS)
                            && !e.isAllDay()) {
                        timeCells.add(sdc);
                    } else {
                        dayCells.add(sdc);
                    }
                    inProgress = true;
                    continue;
                } else if (inProgress) {
                    eventAdded = true;
                    inProgress = false;
                    break;
                }
            }
        }

        updateEventSlotIndex(e, dayCells);
        updateEventSlotIndex(e, timeCells);

        for (SimpleDayCell sdc : dayCells) {
            sdc.addCalendarEvent(e);
        }
        for (SimpleDayCell sdc : timeCells) {
            sdc.addCalendarEvent(e);
        }

        if (renderImmediately) {
            reDrawAllMonthEvents(!eventMoving);
        }
    }

    /*
     * We must also handle the special case when the event lasts exactly for 24
     * hours, thus spanning two days e.g. from 1.1.2001 00:00 to 2.1.2001 00:00.
     * That special case still should span one day when rendered.
     */
    @SuppressWarnings("deprecation")
    // Date methods are not deprecated in GWT
    private boolean isEventInDayWithTime(Date from, Date to, Date date,
            Date endTime, boolean isAllDay) {
        return (isAllDay || !(to.getDay() == date.getDay()
                && from.getDay() != to.getDay() && isMidnight(endTime)));
    }

    private void updateEventSlotIndex(CalendarEvent e,
            List cells) {
        if (cells.isEmpty()) {
            return;
        }

        if (e.getSlotIndex() == -1) {
            // Update slot index
            int newSlot = -1;
            for (SimpleDayCell sdc : cells) {
                int slot = sdc.getEventCount();
                if (slot > newSlot) {
                    newSlot = slot;
                }
            }
            newSlot++;

            for (int i = 0; i < newSlot; i++) {
                // check for empty slot
                if (isSlotEmpty(e, i, cells)) {
                    newSlot = i;
                    break;
                }
            }
            e.setSlotIndex(newSlot);
        }
    }

    private void reDrawAllMonthEvents(boolean clearCells) {
        for (int row = 0; row < monthGrid.getRowCount(); row++) {
            for (int cell = 0; cell < monthGrid.getCellCount(row); cell++) {
                SimpleDayCell sdc = (SimpleDayCell) monthGrid.getWidget(row,
                        cell);
                sdc.reDraw(clearCells);
            }
        }
    }

    private boolean isSlotEmpty(CalendarEvent addedEvent, int slotIndex,
            List cells) {
        for (SimpleDayCell sdc : cells) {
            CalendarEvent e = sdc.getCalendarEvent(slotIndex);
            if (e != null && !e.equals(addedEvent)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Remove a month event from the view.
     *
     * @param target
     *            The event to remove
     *
     * @param repaintImmediately
     *            Should we repaint after the event was removed?
     */
    public void removeMonthEvent(CalendarEvent target,
            boolean repaintImmediately) {
        if (target != null && target.getSlotIndex() >= 0) {
            // Remove event
            for (int row = 0; row < monthGrid.getRowCount(); row++) {
                for (int cell = 0; cell < monthGrid.getCellCount(row); cell++) {
                    SimpleDayCell sdc = (SimpleDayCell) monthGrid.getWidget(row,
                            cell);
                    if (sdc == null) {
                        return;
                    }
                    sdc.removeEvent(target, repaintImmediately);
                }
            }
        }
    }

    /**
     * Updates an event in the month grid.
     *
     * @param changedEvent
     *            The event that has changed
     */
    public void updateEventToMonthGrid(CalendarEvent changedEvent) {
        removeMonthEvent(changedEvent, true);
        changedEvent.setSlotIndex(-1);
        addEventToMonthGrid(changedEvent, true);
    }

    /**
     * Sort the events by current sort order.
     *
     * @param events
     *            The events to sort
     * @return An array where the events has been sorted
     */
    public CalendarEvent[] sortEvents(Collection events) {
        if (EventSortOrder.DURATION_DESC.equals(eventSortOrder)) {
            return sortEventsByDuration(events);
        } else if (!EventSortOrder.UNSORTED.equals(eventSortOrder)) {
            CalendarEvent[] sorted = events
                    .toArray(new CalendarEvent[events.size()]);
            switch (eventSortOrder) {
            case DURATION_ASC:
                Arrays.sort(sorted, new EventDurationComparator(true));
                break;
            case START_DATE_ASC:
                Arrays.sort(sorted, new StartDateComparator(true));
                break;
            case START_DATE_DESC:
                Arrays.sort(sorted, new StartDateComparator(false));
                break;
            }
            return sorted;
        }
        return events.toArray(new CalendarEvent[events.size()]);
    }

    /**
     * Sort the event by how long they are.
     *
     * @param events
     *            The events to sort
     * @return An array where the events has been sorted
     * @deprecated use {@link #sortEvents(Collection)} method which shorts
     *             events by current sort order.
     */
    @Deprecated
    public CalendarEvent[] sortEventsByDuration(
            Collection events) {
        CalendarEvent[] sorted = events
                .toArray(new CalendarEvent[events.size()]);
        Arrays.sort(sorted, getEventComparator());
        return sorted;
    }

    /*
     * Check if the given event occurs at the given date.
     */
    private boolean isEventInDay(Date eventWhen, Date eventTo, Date gridDate) {
        if (eventWhen.compareTo(gridDate) <= 0
                && eventTo.compareTo(gridDate) >= 0) {

            return true;
        }

        return false;
    }

    /**
     * Re-render the week grid.
     *
     * @param daysCount
     *            The amount of days to include in the week
     * @param days
     *            The days
     * @param today
     *            Todays date
     * @param realDayNames
     *            The names of the dates
     */
    @SuppressWarnings("deprecation")
    public void updateWeekGrid(int daysCount, List days,
            Date today, String[] realDayNames) {
        weekGrid.setFirstHour(getFirstHourOfTheDay());
        weekGrid.setLastHour(getLastHourOfTheDay());
        weekGrid.getTimeBar().updateTimeBar(is24HFormat());

        dayToolbar.clear();
        dayToolbar.addBackButton();
        dayToolbar.setVerticalSized(isHeightUndefined);
        dayToolbar.setHorizontalSized(isWidthUndefined);
        weekGrid.clearDates();
        weekGrid.setDisabled(isDisabledOrReadOnly());

        for (CalendarDay day : days) {
            String date = day.getDate();
            String localizedDateFormat = day.getLocalizedDateFormat();
            Date d = dateformat_date.parse(date);
            int dayOfWeek = day.getDayOfWeek();
            if (dayOfWeek < getFirstDayNumber()
                    || dayOfWeek > getLastDayNumber()) {
                continue;
            }
            boolean isToday = false;
            int dayOfMonth = d.getDate();
            if (today.getDate() == dayOfMonth && today.getYear() == d.getYear()
                    && today.getMonth() == d.getMonth()) {
                isToday = true;
            }
            dayToolbar.add(realDayNames[dayOfWeek - 1], date,
                    localizedDateFormat, isToday ? "today" : null);
            weeklyLongEvents.addDate(d);
            weekGrid.addDate(d);
            if (isToday) {
                weekGrid.setToday(d, today);
            }
        }
        dayToolbar.addNextButton();
    }

    /**
     * Updates the events in the Month view.
     *
     * @param daysCount
     *            How many days there are
     * @param daysUidl
     *
     * @param today
     *            Todays date
     */
    @SuppressWarnings("deprecation")
    public void updateMonthGrid(int daysCount, List days,
            Date today) {
        int columns = getLastDayNumber() - getFirstDayNumber() + 1;
        rows = (int) Math.ceil(daysCount / (double) 7);

        monthGrid = new MonthGrid(this, rows, columns);
        monthGrid.setEnabled(!isDisabledOrReadOnly());
        weekToolbar.removeAllRows();
        int pos = 0;
        boolean monthNameDrawn = true;
        boolean firstDayFound = false;
        boolean lastDayFound = false;

        for (CalendarDay day : days) {
            String date = day.getDate();
            Date d = dateformat_date.parse(date);
            int dayOfWeek = day.getDayOfWeek();
            int week = day.getWeek();

            int dayOfMonth = d.getDate();

            // reset at start of each month
            if (dayOfMonth == 1) {
                monthNameDrawn = false;
                if (firstDayFound) {
                    lastDayFound = true;
                }
                firstDayFound = true;
            }

            if (dayOfWeek < getFirstDayNumber()
                    || dayOfWeek > getLastDayNumber()) {
                continue;
            }
            int y = (pos / columns);
            int x = pos - (y * columns);
            if (x == 0 && daysCount > 7) {
                // Add week to weekToolbar for navigation
                weekToolbar.addWeek(week, day.getYearOfWeek());
            }
            final SimpleDayCell cell = new SimpleDayCell(this, y, x);
            cell.setMonthGrid(monthGrid);
            cell.setDate(d);
            cell.addDomHandler(new ContextMenuHandler() {
                @Override
                public void onContextMenu(ContextMenuEvent event) {
                    if (mouseEventListener != null) {
                        event.preventDefault();
                        event.stopPropagation();
                        mouseEventListener.contextMenu(event, cell);
                    }
                }
            }, ContextMenuEvent.getType());

            if (!firstDayFound) {
                cell.addStyleDependentName("prev-month");
            } else if (lastDayFound) {
                cell.addStyleDependentName("next-month");
            }

            if (dayOfMonth >= 1 && !monthNameDrawn) {
                cell.setMonthNameVisible(true);
                monthNameDrawn = true;
            }

            if (today.getDate() == dayOfMonth && today.getYear() == d.getYear()
                    && today.getMonth() == d.getMonth()) {
                cell.setToday(true);

            }
            monthGrid.setWidget(y, x, cell);
            pos++;
        }
    }

    public void setSizeForChildren(int newWidth, int newHeight) {
        intWidth = newWidth;
        intHeight = newHeight;
        isWidthUndefined = intWidth == -1;
        dayToolbar.setVerticalSized(isHeightUndefined);
        dayToolbar.setHorizontalSized(isWidthUndefined);
        recalculateWidths();
        recalculateHeights();
    }

    /**
     * Recalculates the heights of the sub-components in the calendar.
     */
    protected void recalculateHeights() {
        if (monthGrid != null) {

            if (intHeight == -1) {
                monthGrid.addStyleDependentName("sizedheight");
            } else {
                monthGrid.removeStyleDependentName("sizedheight");
            }

            monthGrid.updateCellSizes(intWidth - weekToolbar.getOffsetWidth(),
                    intHeight - nameToolbar.getOffsetHeight());
            weekToolbar.setHeightPX((intHeight == -1) ? intHeight
                    : intHeight - nameToolbar.getOffsetHeight());

        } else if (weekGrid != null) {
            weekGrid.setHeightPX((intHeight == -1) ? intHeight
                    : intHeight - weeklyLongEvents.getOffsetHeight()
                            - dayToolbar.getOffsetHeight());
        }
    }

    /**
     * Recalculates the widths of the sub-components in the calendar.
     */
    protected void recalculateWidths() {
        if (!isWidthUndefined) {
            nameToolbar.setWidthPX(intWidth);
            dayToolbar.setWidthPX(intWidth);

            if (monthGrid != null) {
                monthGrid.updateCellSizes(
                        intWidth - weekToolbar.getOffsetWidth(),
                        intHeight - nameToolbar.getOffsetHeight());
            } else if (weekGrid != null) {
                weekGrid.setWidthPX(intWidth);
                weeklyLongEvents.setWidthPX(weekGrid.getInternalWidth());
            }
        } else {
            dayToolbar.setWidthPX(intWidth);
            nameToolbar.setWidthPX(intWidth);

            if (monthGrid != null) {
                if (intWidth == -1) {
                    monthGrid.addStyleDependentName("sizedwidth");

                } else {
                    monthGrid.removeStyleDependentName("sizedwidth");
                }
            } else if (weekGrid != null) {
                weekGrid.setWidthPX(intWidth);
                weeklyLongEvents.setWidthPX(weekGrid.getInternalWidth());
            }
        }
    }

    /**
     * Get the date format used to format dates only (excludes time).
     *
     * @return
     */
    public DateTimeFormat getDateFormat() {
        return dateformat_date;
    }

    /**
     * Get the time format used to format time only (excludes date).
     *
     * @return
     */
    public DateTimeFormat getTimeFormat() {
        if (is24HFormat()) {
            return time24format_date;
        }
        return time12format_date;
    }

    /**
     * Get the date and time format to format the dates (includes both date and
     * time).
     *
     * @return
     */
    public DateTimeFormat getDateTimeFormat() {
        return dateformat_datetime;
    }

    /**
     * Is the calendar either disabled or readonly.
     *
     * @return
     */
    public boolean isDisabledOrReadOnly() {
        return disabled || readOnly;
    }

    /**
     * Is the component disabled.
     */
    public boolean isDisabled() {
        return disabled;
    }

    /**
     * Is the component disabled.
     *
     * @param disabled
     *            True if disabled
     */
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

    /**
     * Is the component read-only.
     */
    public boolean isReadOnly() {
        return readOnly;
    }

    /**
     * Is the component read-only.
     *
     * @param readOnly
     *            True if component is readonly
     */
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    /**
     * Get the month grid component.
     *
     * @return
     */
    public MonthGrid getMonthGrid() {
        return monthGrid;
    }

    /**
     * Get he week grid component.
     *
     * @return
     */
    public WeekGrid getWeekGrid() {
        return weekGrid;
    }

    /**
     * Calculates correct size for all cells (size / amount of cells ) and
     * distributes any overflow over all the cells.
     *
     * @param totalSize
     *            the total amount of size reserved for all cells
     * @param numberOfCells
     *            the number of cells
     * @param sizeModifier
     *            a modifier which is applied to all cells before distributing
     *            the overflow
     * @return an integer array that contains the correct size for each cell
     */
    public static int[] distributeSize(int totalSize, int numberOfCells,
            int sizeModifier) {
        int[] cellSizes = new int[numberOfCells];
        int startingSize = totalSize / numberOfCells;
        int cellSizeOverFlow = totalSize % numberOfCells;

        for (int i = 0; i < numberOfCells; i++) {
            cellSizes[i] = startingSize + sizeModifier;
        }

        // distribute size overflow amongst all slots
        int j = 0;
        while (cellSizeOverFlow > 0) {
            cellSizes[j]++;
            cellSizeOverFlow--;
            j++;
            if (j >= numberOfCells) {
                j = 0;
            }
        }

        // cellSizes[numberOfCells - 1] += cellSizeOverFlow;

        return cellSizes;
    }

    /**
     * Returns the default comparator which can compare calendar events by
     * duration.
     *
     * @deprecated this returns just one default comparator, but there are
     *             number of comparators that are used to sort events depending
     *             on order.
     *
     * @return
     */
    @Deprecated
    public static Comparator getEventComparator() {
        return DEFAULT_COMPARATOR;
    }

    /**
     * Is the date at midnight.
     *
     * @param date
     *            The date to check
     *
     * @return
     */
    @SuppressWarnings("deprecation")
    public static boolean isMidnight(Date date) {
        return (date.getHours() == 0 && date.getMinutes() == 0
                && date.getSeconds() == 0);
    }

    /**
     * Are the dates equal (uses second resolution).
     *
     * @param date1
     *            The first the to compare
     * @param date2
     *            The second date to compare
     * @return
     */
    @SuppressWarnings("deprecation")
    public static boolean areDatesEqualToSecond(Date date1, Date date2) {
        return date1.getYear() == date2.getYear()
                && date1.getMonth() == date2.getMonth()
                && date1.getDay() == date2.getDay()
                && date1.getHours() == date2.getHours()
                && date1.getSeconds() == date2.getSeconds();
    }

    /**
     * Is the calendar event zero seconds long and is occurring at midnight.
     *
     * @param event
     *            The event to check
     * @return
     */
    public static boolean isZeroLengthMidnightEvent(CalendarEvent event) {
        return areDatesEqualToSecond(event.getStartTime(), event.getEndTime())
                && isMidnight(event.getEndTime());
    }

    /**
     * Should the 24h time format be used.
     *
     * @param format
     *            True if the 24h format should be used else the 12h format is
     *            used
     */
    public void set24HFormat(boolean format) {
        this.format = format;
    }

    /**
     * Is the 24h time format used.
     */
    public boolean is24HFormat() {
        return format;
    }

    /**
     * Set the names of the week days.
     *
     * @param names
     *            The names of the days (Monday, Thursday,...)
     */
    public void setDayNames(String[] names) {
        assert (names.length == 7);
        dayNames = names;
    }

    /**
     * Get the names of the week days.
     */
    public String[] getDayNames() {
        return dayNames;
    }

    /**
     * Set the names of the months.
     *
     * @param names
     *            The names of the months (January, February,...)
     */
    public void setMonthNames(String[] names) {
        assert (names.length == 12);
        monthNames = names;
    }

    /**
     * Get the month names.
     */
    public String[] getMonthNames() {
        return monthNames;
    }

    /**
     * Set the number when a week starts.
     *
     * @param dayNumber
     *            The number of the day
     */
    public void setFirstDayNumber(int dayNumber) {
        assert (dayNumber >= 1 && dayNumber <= 7);
        firstDay = dayNumber;
    }

    /**
     * Get the number when a week starts.
     */
    public int getFirstDayNumber() {
        return firstDay;
    }

    /**
     * Set the number when a week ends.
     *
     * @param dayNumber
     *            The number of the day
     */
    public void setLastDayNumber(int dayNumber) {
        assert (dayNumber >= 1 && dayNumber <= 7);
        lastDay = dayNumber;
    }

    /**
     * Get the number when a week ends.
     */
    public int getLastDayNumber() {
        return lastDay;
    }

    /**
     * Set the first hour of the day.
     *
     * @param hour
     *            The first hour of the day
     */
    public void setFirstHourOfTheDay(int hour) {
        assert (hour >= 0 && hour <= 23);
        firstHour = hour;
    }

    /**
     * Get the first hour of the day.
     *
     * @return The first hour of the day
     */
    public int getFirstHourOfTheDay() {
        return firstHour;
    }

    /**
     * Set the last hour of the day.
     *
     * @param hour
     *            The last hour of the day
     */
    public void setLastHourOfTheDay(int hour) {
        assert (hour >= 0 && hour <= 23);
        lastHour = hour;
    }

    /**
     * Get the last hour of the day.
     *
     * @return The last hour of the day
     */
    public int getLastHourOfTheDay() {
        return lastHour;
    }

    /**
     * Re-renders the whole week view.
     *
     * @param scroll
     *            The amount of pixels to scroll the week view
     * @param today
     *            Todays date
     * @param daysInMonth
     *            How many days are there in the month
     * @param firstDayOfWeek
     *            The first day of the week
     * @param events
     *            The events to render
     */
    public void updateWeekView(int scroll, Date today, int daysInMonth,
            int firstDayOfWeek, Collection events,
            List days) {

        while (outer.getWidgetCount() > 0) {
            outer.remove(0);
        }

        monthGrid = null;
        String[] realDayNames = new String[getDayNames().length];
        int j = 0;

        if (firstDayOfWeek == 2) {
            for (int i = 1; i < getDayNames().length; i++) {
                realDayNames[j++] = getDayNames()[i];
            }
            realDayNames[j] = getDayNames()[0];
        } else {
            for (int i = 0; i < getDayNames().length; i++) {
                realDayNames[j++] = getDayNames()[i];
            }

        }

        weeklyLongEvents = new WeeklyLongEvents(this);
        if (weekGrid == null) {
            weekGrid = new WeekGrid(this, is24HFormat());
        }
        updateWeekGrid(daysInMonth, days, today, realDayNames);
        updateEventsToWeekGrid(sortEvents(events));
        outer.add(dayToolbar, DockPanel.NORTH);
        outer.add(weeklyLongEvents, DockPanel.NORTH);
        outer.add(weekGrid, DockPanel.SOUTH);
        weekGrid.setVerticalScrollPosition(scroll);
    }

    /**
     * Re-renders the whole month view.
     *
     * @param firstDayOfWeek
     *            The first day of the week
     * @param today
     *            Todays date
     * @param daysInMonth
     *            Amount of days in the month
     * @param events
     *            The events to render
     * @param days
     *            The day information
     */
    public void updateMonthView(int firstDayOfWeek, Date today, int daysInMonth,
            Collection events, List days) {

        // Remove all week numbers from bar
        while (outer.getWidgetCount() > 0) {
            outer.remove(0);
        }

        int firstDay = getFirstDayNumber();
        int lastDay = getLastDayNumber();
        int daysPerWeek = lastDay - firstDay + 1;
        int j = 0;

        String[] dayNames = getDayNames();
        String[] realDayNames = new String[daysPerWeek];

        if (firstDayOfWeek == 2) {
            for (int i = firstDay; i < lastDay + 1; i++) {
                if (i == 7) {
                    realDayNames[j++] = dayNames[0];
                } else {
                    realDayNames[j++] = dayNames[i];
                }
            }
        } else {
            for (int i = firstDay - 1; i < lastDay; i++) {
                realDayNames[j++] = dayNames[i];
            }
        }

        nameToolbar.setDayNames(realDayNames);

        weeklyLongEvents = null;
        weekGrid = null;

        updateMonthGrid(daysInMonth, days, today);

        outer.add(nameToolbar, DockPanel.NORTH);
        outer.add(weekToolbar, DockPanel.WEST);
        weekToolbar.updateCellHeights();
        outer.add(monthGrid, DockPanel.CENTER);

        updateEventsToMonthGrid(events, false);
    }

    private DateClickListener dateClickListener;

    /**
     * Sets the listener for listening to event clicks.
     *
     * @param listener
     *            The listener to use
     */
    public void setListener(DateClickListener listener) {
        dateClickListener = listener;
    }

    /**
     * Gets the listener for listening to event clicks.
     *
     * @return
     */
    public DateClickListener getDateClickListener() {
        return dateClickListener;
    }

    private ForwardListener forwardListener;

    /**
     * Set the listener which listens to forward events from the calendar.
     *
     * @param listener
     *            The listener to use
     */
    public void setListener(ForwardListener listener) {
        forwardListener = listener;
    }

    /**
     * Get the listener which listens to forward events from the calendar.
     *
     * @return
     */
    public ForwardListener getForwardListener() {
        return forwardListener;
    }

    private BackwardListener backwardListener;

    /**
     * Set the listener which listens to backward events from the calendar.
     *
     * @param listener
     *            The listener to use
     */
    public void setListener(BackwardListener listener) {
        backwardListener = listener;
    }

    /**
     * Set the listener which listens to backward events from the calendar.
     *
     * @return
     */
    public BackwardListener getBackwardListener() {
        return backwardListener;
    }

    private WeekClickListener weekClickListener;

    /**
     * Set the listener that listens to user clicking on the week numbers.
     *
     * @param listener
     *            The listener to use
     */
    public void setListener(WeekClickListener listener) {
        weekClickListener = listener;
    }

    /**
     * Get the listener that listens to user clicking on the week numbers.
     *
     * @return
     */
    public WeekClickListener getWeekClickListener() {
        return weekClickListener;
    }

    private RangeSelectListener rangeSelectListener;

    /**
     * Set the listener that listens to the user highlighting a region in the
     * calendar.
     *
     * @param listener
     *            The listener to use
     */
    public void setListener(RangeSelectListener listener) {
        rangeSelectListener = listener;
    }

    /**
     * Get the listener that listens to the user highlighting a region in the
     * calendar.
     *
     * @return
     */
    public RangeSelectListener getRangeSelectListener() {
        return rangeSelectListener;
    }

    private EventClickListener eventClickListener;

    /**
     * Get the listener that listens to the user clicking on the events.
     */
    public EventClickListener getEventClickListener() {
        return eventClickListener;
    }

    /**
     * Set the listener that listens to the user clicking on the events.
     *
     * @param listener
     *            The listener to use
     */
    public void setListener(EventClickListener listener) {
        eventClickListener = listener;
    }

    private EventMovedListener eventMovedListener;

    /**
     * Get the listener that listens to when event is dragged to a new location.
     *
     * @return
     */
    public EventMovedListener getEventMovedListener() {
        return eventMovedListener;
    }

    /**
     * Set the listener that listens to when event is dragged to a new location.
     *
     * @param eventMovedListener
     *            The listener to use
     */
    public void setListener(EventMovedListener eventMovedListener) {
        this.eventMovedListener = eventMovedListener;
    }

    private ScrollListener scrollListener;

    /**
     * Get the listener that listens to when the calendar widget is scrolled.
     *
     * @return
     */
    public ScrollListener getScrollListener() {
        return scrollListener;
    }

    /**
     * Set the listener that listens to when the calendar widget is scrolled.
     *
     * @param scrollListener
     *            The listener to use
     */
    public void setListener(ScrollListener scrollListener) {
        this.scrollListener = scrollListener;
    }

    private EventResizeListener eventResizeListener;

    /**
     * Get the listener that listens to when an events time limits are being
     * adjusted.
     *
     * @return
     */
    public EventResizeListener getEventResizeListener() {
        return eventResizeListener;
    }

    /**
     * Set the listener that listens to when an events time limits are being
     * adjusted.
     *
     * @param eventResizeListener
     *            The listener to use
     */
    public void setListener(EventResizeListener eventResizeListener) {
        this.eventResizeListener = eventResizeListener;
    }

    private MouseEventListener mouseEventListener;
    private boolean forwardNavigationEnabled = true;
    private boolean backwardNavigationEnabled = true;
    private boolean eventCaptionAsHtml = false;

    /**
     * Get the listener that listen to mouse events.
     *
     * @return
     */
    public MouseEventListener getMouseEventListener() {
        return mouseEventListener;
    }

    /**
     * Set the listener that listen to mouse events.
     *
     * @param mouseEventListener
     *            The listener to use
     */
    public void setListener(MouseEventListener mouseEventListener) {
        this.mouseEventListener = mouseEventListener;
    }

    /**
     * Is selecting a range allowed?
     */
    public boolean isRangeSelectAllowed() {
        return rangeSelectAllowed;
    }

    /**
     * Set selecting a range allowed.
     *
     * @param rangeSelectAllowed
     *            Should selecting a range be allowed
     */
    public void setRangeSelectAllowed(boolean rangeSelectAllowed) {
        this.rangeSelectAllowed = rangeSelectAllowed;
    }

    /**
     * Is moving a range allowed.
     *
     * @return
     */
    public boolean isRangeMoveAllowed() {
        return rangeMoveAllowed;
    }

    /**
     * Is moving a range allowed.
     *
     * @param rangeMoveAllowed
     *            Is it allowed
     */
    public void setRangeMoveAllowed(boolean rangeMoveAllowed) {
        this.rangeMoveAllowed = rangeMoveAllowed;
    }

    /**
     * Is resizing an event allowed.
     */
    public boolean isEventResizeAllowed() {
        return eventResizeAllowed;
    }

    /**
     * Is resizing an event allowed.
     *
     * @param eventResizeAllowed
     *            True if allowed false if not
     */
    public void setEventResizeAllowed(boolean eventResizeAllowed) {
        this.eventResizeAllowed = eventResizeAllowed;
    }

    /**
     * Is moving an event allowed.
     */
    public boolean isEventMoveAllowed() {
        return eventMoveAllowed;
    }

    /**
     * Is moving an event allowed.
     *
     * @param eventMoveAllowed
     *            True if moving is allowed, false if not
     */
    public void setEventMoveAllowed(boolean eventMoveAllowed) {
        this.eventMoveAllowed = eventMoveAllowed;
    }

    public boolean isBackwardNavigationEnabled() {
        return backwardNavigationEnabled;
    }

    public void setBackwardNavigationEnabled(boolean enabled) {
        backwardNavigationEnabled = enabled;
    }

    public boolean isForwardNavigationEnabled() {
        return forwardNavigationEnabled;
    }

    public void setForwardNavigationEnabled(boolean enabled) {
        forwardNavigationEnabled = enabled;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.vaadin.client.ui.dd.VHasDropHandler#getDropHandler()
     */
    @Override
    public CalendarDropHandler getDropHandler() {
        return dropHandler;
    }

    /**
     * Set the drop handler.
     *
     * @param dropHandler
     *            The drophandler to use
     */
    public void setDropHandler(CalendarDropHandler dropHandler) {
        this.dropHandler = dropHandler;
    }

    /**
     * Sets whether the event captions are rendered as HTML.
     * 

* If set to true, the captions are rendered in the browser as HTML and the * developer is responsible for ensuring no harmful HTML is used. If set to * false, the caption is rendered in the browser as plain text. *

* The default is false, i.e. to render that caption as plain text. * * @param eventCaptionAsHtml * {@code true} if the captions are rendered as HTML, * {@code false} if rendered as plain text */ public void setEventCaptionAsHtml(boolean eventCaptionAsHtml) { this.eventCaptionAsHtml = eventCaptionAsHtml; } /** * Checks whether event captions are rendered as HTML *

* The default is false, i.e. to render that caption as plain text. * * @return true if the captions are rendered as HTML, false if rendered as * plain text */ public boolean isEventCaptionAsHtml() { return eventCaptionAsHtml; } /** * Set sort strategy for events. * * @param order * sort order */ public void setSortOrder(EventSortOrder order) { if (order == null) { eventSortOrder = EventSortOrder.DURATION_DESC; } else { eventSortOrder = order; } } /** * Return currently active sort order. * * @return current sort order */ public EventSortOrder getSortOrder() { return eventSortOrder; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy