You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ICalendarField.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.itmill.toolkit.demo.reservation.gwt.client.ui;
  5. import java.util.ArrayList;
  6. import java.util.Date;
  7. import java.util.HashMap;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import com.google.gwt.user.client.DOM;
  11. import com.google.gwt.user.client.Element;
  12. import com.google.gwt.user.client.ui.FlexTable;
  13. import com.google.gwt.user.client.ui.SimplePanel;
  14. import com.google.gwt.user.client.ui.SourcesTableEvents;
  15. import com.google.gwt.user.client.ui.TableListener;
  16. import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
  17. import com.itmill.toolkit.terminal.gwt.client.DateTimeService;
  18. import com.itmill.toolkit.terminal.gwt.client.UIDL;
  19. import com.itmill.toolkit.terminal.gwt.client.ui.CalendarEntry;
  20. import com.itmill.toolkit.terminal.gwt.client.ui.CalendarPanel;
  21. import com.itmill.toolkit.terminal.gwt.client.ui.IDateField;
  22. public class ICalendarField extends IDateField {
  23. private final CalendarPanel calPanel;
  24. private SimplePanel hourPanel;
  25. private FlexTable hourTable;
  26. private final EntrySource entrySource;
  27. private final TableListener ftListener = new HourTableListener();
  28. private int realResolution = RESOLUTION_DAY;
  29. private static final String CLASSNAME = IDateField.CLASSNAME
  30. + "-entrycalendar";
  31. public ICalendarField() {
  32. super();
  33. setStyleName(CLASSNAME);
  34. calPanel = new CalendarPanel(this);
  35. add(calPanel);
  36. entrySource = new EntrySource();
  37. calPanel.setCalendarEntrySource(entrySource);
  38. calPanel.addTableListener(new TableListener() {
  39. public void onCellClicked(SourcesTableEvents sender, int row,
  40. int cell) {
  41. buildDayView(date);
  42. }
  43. });
  44. }
  45. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  46. super.updateFromUIDL(uidl, client);
  47. // We want to draw our own hour list
  48. realResolution = currentResolution;
  49. currentResolution = RESOLUTION_DAY;
  50. if (uidl.hasAttribute("min")) {
  51. final String mins = uidl.getStringAttribute("min");
  52. final long min = (mins != null ? Long.parseLong(mins) : 0);
  53. final String maxs = uidl.getStringAttribute("max");
  54. final long max = (maxs != null ? Long.parseLong(maxs) : 0);
  55. final Date minDate = (min > 0 ? new Date(min) : null);
  56. final Date maxDate = (max > 0 ? new Date(max) : null);
  57. calPanel.setLimits(minDate, maxDate);
  58. }
  59. entrySource.clear();
  60. for (final Iterator cit = uidl.getChildIterator(); cit.hasNext();) {
  61. final UIDL child = (UIDL) cit.next();
  62. if (child.getTag().equals("items")) {
  63. for (final Iterator iit = child.getChildIterator(); iit
  64. .hasNext();) {
  65. final UIDL item = (UIDL) iit.next();
  66. entrySource.addItem(item);
  67. }
  68. break;
  69. }
  70. }
  71. calPanel.updateCalendar();
  72. buildDayView(date);
  73. }
  74. protected void buildDayView(Date date) {
  75. boolean firstRender = true;
  76. if (hourPanel == null) {
  77. hourPanel = new SimplePanel();
  78. hourPanel.setStyleName(CLASSNAME + "-hours");
  79. calPanel.getFlexCellFormatter().setColSpan(8, 0, 7);
  80. calPanel.setWidget(8, 0, hourPanel);
  81. } else {
  82. firstRender = false;
  83. hourPanel.clear();
  84. }
  85. hourTable = new FlexTable();
  86. hourTable.addTableListener(ftListener);
  87. hourPanel.add(hourTable);
  88. hourTable.setCellSpacing(1);
  89. for (int i = 0; i < 24; i++) {
  90. String style = (i % 2 == 0 ? "even" : "odd");
  91. if (realResolution >= RESOLUTION_HOUR) {
  92. if (this.date != null && this.date.getHours() == i) {
  93. style = "selected";
  94. }
  95. }
  96. hourTable.getRowFormatter().setStyleName(i,
  97. CLASSNAME + "-row-" + style);
  98. String hstr = (i < 10 ? "0" : "") + i + ":00";
  99. if (dts.isTwelveHourClock()) {
  100. final String ampm = (i < 12 ? "am" : "pm");
  101. hstr = (i <= 12 ? i : i - 12) + ":00 " + ampm;
  102. }
  103. hourTable.setHTML(i, 0, "<span>" + hstr + "</span>");
  104. hourTable.getCellFormatter()
  105. .setStyleName(i, 0, CLASSNAME + "-time");
  106. }
  107. final List entries = entrySource.getEntries(date,
  108. DateTimeService.RESOLUTION_DAY);
  109. int currentCol = 1;
  110. for (final Iterator it = entries.iterator(); it.hasNext();) {
  111. final CalendarEntry entry = (CalendarEntry) it.next();
  112. int start = 0;
  113. int hours = 24;
  114. if (!entry.isNotime()) {
  115. Date d = entry.getStart();
  116. // TODO consider month&year as well
  117. start = (d.getDate() < date.getDate() ? 0 : d.getHours());
  118. d = entry.getEnd();
  119. hours = (d.getDate() > date.getDate() ? 24 : d.getHours())
  120. - start;
  121. if (hours == 0) {
  122. // We can't draw entries smaller than
  123. // one
  124. hours = 1;
  125. }
  126. }
  127. int col = currentCol;
  128. if (col > 1) {
  129. while (!hourTable.isCellPresent(start, col - 1)) {
  130. col--;
  131. }
  132. }
  133. hourTable.setHTML(start, col, "<span>"
  134. + (entry.getTitle() != null ? entry.getTitle() : "&nbsp")
  135. + "</span>");
  136. hourTable.getFlexCellFormatter().setRowSpan(start, col, hours);
  137. hourTable.getFlexCellFormatter().setStyleName(start, col,
  138. CLASSNAME + "-entry");
  139. final String sn = entry.getStyleName();
  140. if (sn != null && !sn.equals("")) {
  141. hourTable.getFlexCellFormatter().addStyleName(start, col,
  142. CLASSNAME + "-" + entry.getStyleName());
  143. }
  144. final Element el = hourTable.getFlexCellFormatter().getElement(
  145. start, col);
  146. String tooltip;
  147. if (DateTimeService.isSameDay(entry.getStart(), entry.getEnd())) {
  148. tooltip = (start < 10 ? "0" : "") + start + ":00";
  149. if (dts.isTwelveHourClock()) {
  150. final String ampm = (start < 12 ? "am" : "pm");
  151. tooltip = (start <= 12 ? start : start - 12) + ":00 "
  152. + ampm;
  153. }
  154. tooltip += " (" + hours + "h) ";
  155. if (entry.getTitle() != null) {
  156. tooltip += entry.getTitle() + "\n ";
  157. }
  158. } else {
  159. tooltip = entry.getStringForDate(entry.getEnd()) + "\n ";
  160. }
  161. if (entry.getDescription() != null) {
  162. tooltip += "\"" + entry.getDescription() + "\"";
  163. }
  164. DOM.setElementProperty(el, "title", tooltip);
  165. currentCol++;
  166. }
  167. // int hour = new Date().getHours()+1; // scroll to current hour
  168. final int hour = this.date.getHours() + 1; // scroll to selected
  169. // hour
  170. final int h1 = hourPanel.getOffsetHeight() / 2;
  171. final int oh = hourTable.getOffsetHeight();
  172. final int h2 = (int) (hour / 24.0 * oh);
  173. final int scrollTop = h2 - h1;
  174. final Element el = hourPanel.getElement();
  175. setScrollTop(el, scrollTop);
  176. }
  177. private native void setScrollTop(Element el, int scrollTop) /*-{
  178. el.scrollTop = scrollTop;
  179. }-*/;
  180. private class HourTableListener implements TableListener {
  181. public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
  182. if (realResolution < RESOLUTION_HOUR || date == null) {
  183. return;
  184. }
  185. date.setHours(row);
  186. client.updateVariable(id, "hour", row, immediate);
  187. }
  188. }
  189. private class EntrySource implements CalendarPanel.CalendarEntrySource {
  190. private final HashMap dates = new HashMap();
  191. public void addItem(UIDL item) {
  192. final String styleName = item.getStringAttribute("styleName");
  193. final Integer id = new Integer(item.getIntAttribute("id"));
  194. final long start = Long.parseLong(item.getStringAttribute("start"));
  195. final Date startDate = new Date(start);
  196. long end = -1;
  197. try {
  198. end = Long.parseLong(item.getStringAttribute("end"));
  199. } catch (final Exception IGNORED) {
  200. // IGNORED attribute not required
  201. }
  202. final Date endDate = (end > 0 && end != start ? new Date(end)
  203. : new Date(start));
  204. final String title = item.getStringAttribute("title");
  205. final String desc = item.getStringAttribute("description");
  206. final boolean notime = item.getBooleanAttribute("notime");
  207. final CalendarEntry entry = new CalendarEntry(styleName, startDate,
  208. endDate, title, desc, notime);
  209. // TODO should remove+readd if the same entry (id) is
  210. // added again
  211. for (final Date d = entry.getStart(); d.getYear() <= entry.getEnd()
  212. .getYear()
  213. && d.getMonth() <= entry.getEnd().getYear()
  214. && d.getDate() <= entry.getEnd().getDate(); d.setTime(d
  215. .getTime() + 86400000)) {
  216. final String key = d.getYear() + "" + d.getMonth() + ""
  217. + d.getDate();
  218. ArrayList l = (ArrayList) dates.get(key);
  219. if (l == null) {
  220. l = new ArrayList();
  221. dates.put(key, l);
  222. }
  223. l.add(entry);
  224. }
  225. }
  226. public List getEntries(Date date, int resolution) {
  227. final List entries = (List) dates.get(date.getYear() + ""
  228. + date.getMonth() + "" + date.getDate());
  229. final ArrayList res = new ArrayList();
  230. if (entries == null) {
  231. return res;
  232. }
  233. for (final Iterator it = entries.iterator(); it.hasNext();) {
  234. final CalendarEntry item = (CalendarEntry) it.next();
  235. if (DateTimeService.isInRange(date, item.getStart(), item
  236. .getEnd(), resolution)) {
  237. res.add(item);
  238. }
  239. }
  240. return res;
  241. }
  242. public void clear() {
  243. dates.clear();
  244. }
  245. }
  246. }