diff options
6 files changed, 314 insertions, 29 deletions
diff --git a/client/src/com/vaadin/client/ui/Action.java b/client/src/com/vaadin/client/ui/Action.java index ffc3c4c7d4..e1b85dcb82 100644 --- a/client/src/com/vaadin/client/ui/Action.java +++ b/client/src/com/vaadin/client/ui/Action.java @@ -67,4 +67,16 @@ public abstract class Action implements Command { public void setIconUrl(String url) { iconUrl = url; } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Action [owner=" + owner + ", iconUrl=" + iconUrl + ", caption=" + + caption + "]"; + } + } diff --git a/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java b/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java index 5a83579d46..49cd2386ac 100644 --- a/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java +++ b/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java @@ -17,6 +17,7 @@ package com.vaadin.client.ui.calendar; import java.text.ParseException; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -267,6 +268,18 @@ public class CalendarConnector extends AbstractComponentConnector implements return CalendarConnector.this.getActionsBetween( start, end); + + } else if (widget instanceof MonthEventLabel) { + MonthEventLabel mel = (MonthEventLabel) widget; + CalendarEvent event = mel.getCalendarEvent(); + Action[] actions = CalendarConnector.this + .getActionsBetween(event.getStartTime(), + event.getEndTime()); + for (Action action : actions) { + ((VCalendarAction) action).setEvent(event); + } + return actions; + } else if (widget instanceof DateCell) { /* * Week and Day view @@ -284,22 +297,15 @@ public class CalendarConnector extends AbstractComponentConnector implements */ DateCellDayEvent dayEvent = (DateCellDayEvent) widget; CalendarEvent event = dayEvent.getCalendarEvent(); + Action[] actions = CalendarConnector.this .getActionsBetween(event.getStartTime(), event.getEndTime()); + for (Action action : actions) { ((VCalendarAction) action).setEvent(event); } - return actions; - } else if (widget instanceof MonthEventLabel) { - MonthEventLabel mel = (MonthEventLabel) widget; - CalendarEvent event = mel.getCalendarEvent(); - Action[] actions = CalendarConnector.this - .getActionsBetween(event.getStartTime(), - event.getEndTime()); - for (Action action : actions) { - ((VCalendarAction) action).setEvent(event); - } + return actions; } return null; @@ -456,27 +462,55 @@ public class CalendarConnector extends AbstractComponentConnector implements private Action[] getActionsBetween(Date start, Date end) { List<Action> actions = new ArrayList<Action>(); + List<String> ids = new ArrayList<String>(); + for (int i = 0; i < actionKeys.size(); i++) { - final String actionKey = actionKeys.get(i); - Date actionStartDate; - Date actionEndDate; - try { - actionStartDate = getActionStartDate(actionKey); - actionEndDate = getActionEndDate(actionKey); - } catch (ParseException pe) { - VConsole.error("Failed to parse action date"); - continue; - } + String actionKey = actionKeys.get(i); + String id = getActionID(actionKey); + if (!ids.contains(id)) { + + Date actionStartDate; + Date actionEndDate; + try { + actionStartDate = getActionStartDate(actionKey); + actionEndDate = getActionEndDate(actionKey); + } catch (ParseException pe) { + VConsole.error("Failed to parse action date"); + continue; + } - boolean startIsValid = start.compareTo(actionStartDate) >= 0; - boolean endIsValid = end.compareTo(actionEndDate) <= 0; - if (startIsValid && endIsValid) { - VCalendarAction a = new VCalendarAction(this, rpc, actionKey); - a.setCaption(getActionCaption(actionKey)); - a.setIconUrl(getActionIcon(actionKey)); - a.setActionStartDate(start); - a.setActionEndDate(end); - actions.add(a); + // Case 0: action inside event timeframe + // Action should start AFTER or AT THE SAME TIME as the event, + // and + // Action should end BEFORE or AT THE SAME TIME as the event + boolean test0 = actionStartDate.compareTo(start) >= 0 + && actionEndDate.compareTo(end) <= 0; + + // Case 1: action intersects start of timeframe + // Action end time must be between start and end of event + boolean test1 = actionEndDate.compareTo(start) > 0 + && actionEndDate.compareTo(end) <= 0; + + // Case 2: action intersects end of timeframe + // Action start time must be between start and end of event + boolean test2 = actionStartDate.compareTo(start) >= 0 + && actionStartDate.compareTo(end) < 0; + + // Case 3: event inside action timeframe + // Action should start AND END before the event is complete + boolean test3 = start.compareTo(actionStartDate) >= 0 + && end.compareTo(actionEndDate) <= 0; + + if (test0 || test1 || test2 || test3) { + VCalendarAction a = new VCalendarAction(this, rpc, + actionKey); + a.setCaption(getActionCaption(actionKey)); + a.setIconUrl(getActionIcon(actionKey)); + a.setActionStartDate(start); + a.setActionEndDate(end); + actions.add(a); + ids.add(id); + } } } @@ -496,6 +530,7 @@ public class CalendarConnector extends AbstractComponentConnector implements for (CalendarState.Action action : actions) { String id = action.actionKey + "-" + action.startDate + "-" + action.endDate; + actionMap.put(id + "_k", action.actionKey); actionMap.put(id + "_c", action.caption); actionMap.put(id + "_s", action.startDate); actionMap.put(id + "_e", action.endDate); @@ -507,6 +542,20 @@ public class CalendarConnector extends AbstractComponentConnector implements actionMap.remove(id + "_i"); } } + + Collections.sort(actionKeys); + } + + /** + * Get the original action ID that was passed in from the shared state + * + * @since 7.1.2 + * @param actionKey + * the unique action key + * @return + */ + public String getActionID(String actionKey) { + return actionMap.get(actionKey + "_k"); } /** diff --git a/server/src/com/vaadin/ui/Calendar.java b/server/src/com/vaadin/ui/Calendar.java index c3385baa2c..8b8cc7b475 100644 --- a/server/src/com/vaadin/ui/Calendar.java +++ b/server/src/com/vaadin/ui/Calendar.java @@ -535,6 +535,7 @@ public class Calendar extends AbstractComponent implements // 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); diff --git a/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java b/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java index 01b766a6db..b78fda3136 100644 --- a/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java +++ b/server/src/com/vaadin/ui/components/calendar/CalendarDateRange.java @@ -83,4 +83,15 @@ public class CalendarDateRange implements Serializable { return date.compareTo(start) >= 0 && date.compareTo(end) <= 0; } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "CalendarDateRange [start=" + start + ", end=" + end + "]"; + } + } diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarActionsMenuTest.html b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionsMenuTest.html new file mode 100644 index 0000000000..3830faa7de --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionsMenuTest.html @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.calendar.CalendarActionsMenuTest?restartApplication</td> + <td></td> +</tr> +<tr> + <td>contextmenu</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarActionsMenuTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[1]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>//td[@id='gwt-uid-5']/div</td> + <td>ACTION</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarActionsMenuTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[2]</td> + <td>127,5</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarActionsMenuTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td> + <td>155,9</td> +</tr> +<tr> + <td>contextmenu</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarActionsMenuTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[3]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[34]/domChild[1]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>//td[@id='gwt-uid-6']/div</td> + <td>ACTION</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarActionsMenuTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[3]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[13]</td> + <td>139,0</td> +</tr> +<tr> + <td>contextmenu</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarActionsMenuTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[3]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[14]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>//td[@id='gwt-uid-14']/div</td> + <td>ACTION</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarActionsMenuTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[3]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[13]</td> + <td>139,0</td> +</tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarActionsMenuTest.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionsMenuTest.java new file mode 100644 index 0000000000..77225b2e4c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionsMenuTest.java @@ -0,0 +1,141 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.calendar; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Calendar; +import com.vaadin.ui.Calendar.TimeFormat; +import com.vaadin.ui.Notification; +import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClick; +import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClickHandler; +import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventMoveHandler; +import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler; +import com.vaadin.ui.components.calendar.CalendarComponentEvents.MoveEvent; +import com.vaadin.ui.components.calendar.event.BasicEvent; +import com.vaadin.ui.components.calendar.event.CalendarEvent; +import com.vaadin.ui.components.calendar.event.CalendarEventProvider; + +public class CalendarActionsMenuTest extends AbstractTestUI { + + private Calendar calendar; + + @Override + protected void setup(VaadinRequest request) { + calendar = new Calendar(new CalendarEventProvider() { + + @Override + public List<com.vaadin.ui.components.calendar.event.CalendarEvent> getEvents( + Date startDate, Date endDate) { + + List<CalendarEvent> events = new ArrayList<CalendarEvent>(); + + CalendarEvent event = null; + try { + event = new BasicEvent("NAME", "TOOLTIP", + new SimpleDateFormat("yyyy-MM-dd hh:mm") + .parse("2013-01-01 07:00"), + new SimpleDateFormat("yyyy-MM-dd hh:mm") + .parse("2013-01-01 11:00")); + } catch (ParseException e) { + // Nothing to do + } + events.add(event); + + try { + event = new BasicEvent("NAME 2", "TOOLTIP2", + new SimpleDateFormat("yyyy-MM-dd hh:mm") + .parse("2013-01-03 07:00"), + new SimpleDateFormat("yyyy-MM-dd hh:mm") + .parse("2013-01-04 11:00")); + } catch (ParseException e) { + // Nothing to do + } + events.add(event); + + return events; + } + + }); + try { + calendar.setStartDate(new SimpleDateFormat("yyyy-MM-dd") + .parse("2013-01-01")); + calendar.setEndDate(new SimpleDateFormat("yyyy-MM-dd") + .parse("2013-01-31")); + } catch (ParseException e) { + // Nothing to do + } + calendar.setImmediate(true); + calendar.setFirstVisibleHourOfDay(6); + calendar.setLastVisibleHourOfDay(22); + calendar.setTimeFormat(TimeFormat.Format24H); + calendar.setHandler((EventResizeHandler) null); + + setEnabled(true); + calendar.addActionHandler(new Handler() { + @Override + public void handleAction(Action action, Object sender, Object target) { + Notification.show("ACTION CLICKED"); + + } + + @Override + public Action[] getActions(Object target, Object sender) { + return new Action[] { new Action("ACTION") }; + } + }); + calendar.setHandler(new EventClickHandler() { + private static final long serialVersionUID = -177173530105538438L; + + @Override + public void eventClick(EventClick event) { + Notification.show("EVENT CLICKED"); + } + }); + + calendar.setHandler(new EventMoveHandler() { + @Override + public void eventMove(MoveEvent event) { + Notification.show("EVENT MOVED"); + } + }); + addComponent(calendar); + calendar.setSizeFull(); + setSizeFull(); + + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return "The context should appear if you right click on a calendar event regardless of view mode"; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return 12181; + } + +} |