1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.custom.schedule;
21
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.util.Calendar;
25 import java.util.Date;
26 import java.util.Iterator;
27 import java.util.TreeSet;
28
29 import javax.faces.component.UIComponent;
30 import javax.faces.context.FacesContext;
31 import javax.faces.context.ResponseWriter;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.myfaces.custom.schedule.model.ScheduleDay;
36 import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
37 import org.apache.myfaces.custom.schedule.util.ScheduleUtil;
38 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
39 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
40 import org.apache.myfaces.shared_tomahawk.renderkit.html.util.FormInfo;
41
42
43
44
45
46
47
48
49
50
51
52 public abstract class AbstractCompactScheduleRenderer extends
53 AbstractScheduleRenderer implements Serializable
54 {
55 private static final Log log = LogFactory.getLog(AbstractCompactScheduleRenderer.class);
56
57
58
59
60
61
62
63
64 public void encodeChildren(FacesContext context, UIComponent component)
65 throws IOException
66 {
67
68 }
69
70
71
72
73
74 public void encodeEnd(FacesContext context, UIComponent component)
75 throws IOException
76 {
77
78 }
79
80
81
82
83 protected abstract int getDefaultRowHeight();
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 protected void writeDayCell(FacesContext context, ResponseWriter writer,
115 HtmlSchedule schedule, ScheduleDay day, float cellWidth,
116 int dayOfWeek, int dayOfMonth, boolean isWeekend,
117 boolean isCurrentMonth, int rowspan) throws IOException
118 {
119 final String clientId = schedule.getClientId(context);
120 final FormInfo parentFormInfo = RendererUtils.findNestingForm(schedule, context);
121 final String formId = parentFormInfo == null ? null : parentFormInfo.getFormName();
122 final String dayHeaderId = clientId + "_header_" + ScheduleUtil.getDateId(day.getDate(), schedule.getModel().getTimeZone());
123 final String dayBodyId = clientId + "_body_" + ScheduleUtil.getDateId(day.getDate(), schedule.getModel().getTimeZone());
124 writer.startElement(HTML.TD_ELEM, schedule);
125
126 writer.writeAttribute("rowspan", String.valueOf(rowspan), null);
127
128 boolean isToday = ScheduleUtil.isSameDay(day.getDate(), new Date(), schedule.getModel().getTimeZone());
129
130 String dayClass = getStyleClass(schedule, isCurrentMonth ? "day" : "inactive-day") +
131 " " + getStyleClass(schedule, isWeekend ? "weekend" : "workday") + " " + (isToday ? getStyleClass(schedule, "today") : "");
132
133 writer.writeAttribute(HTML.CLASS_ATTR, dayClass, null);
134
135
136 StringBuffer styleBuffer = new StringBuffer();
137
138 int rowHeight = getRowHeight(schedule);
139 String myRowHeight = "height: ";
140 String myContentHeight = "height: ";
141
142 if (rowHeight > 0)
143 {
144 if (isWeekend && schedule.isSplitWeekend())
145 {
146 myRowHeight += (rowHeight / 2) + "px;";
147 myContentHeight += ((rowHeight / 2) - 19) + "px;";
148 }
149 else
150 {
151 myRowHeight += (rowHeight + (schedule.isSplitWeekend() ? 1 : 0)) + "px;";
152 myContentHeight += ((rowHeight + (schedule.isSplitWeekend() ? 1 : 0)) - 18) + "px;";
153 }
154 }
155 else
156 {
157 myRowHeight += "100%;";
158 myContentHeight += "100%;";
159 }
160
161 styleBuffer.append(myRowHeight);
162 styleBuffer.append("width: " + cellWidth + "%;");
163 styleBuffer.append("vertical-align: top;");
164
165 writer.writeAttribute(HTML.STYLE_ATTR, styleBuffer.toString(), null);
166
167 writer.startElement(HTML.DIV_ELEM, schedule);
168
169 writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule, "day"),
170 null);
171
172
173 writer.startElement(HTML.DIV_ELEM, schedule);
174 writer.writeAttribute(HTML.CLASS_ATTR,
175 getStyleClass(schedule, "header"), null);
176 writer.writeAttribute(HTML.STYLE_ATTR,
177 "height: 18px; overflow: hidden", null);
178
179 writer.startElement(HTML.ANCHOR_ELEM, schedule);
180 writer.writeAttribute(HTML.ID_ATTR, dayHeaderId, null);
181 writer.writeAttribute(HTML.HREF_ATTR, "#", null);
182
183
184
185 if (!schedule.isReadonly() && schedule.isSubmitOnClick()) {
186 writer.writeAttribute(
187 HTML.ONCLICK_ATTR,
188 "fireScheduleDateClicked(this, event, '"
189 + formId + "', '"
190 + clientId
191 + "');",
192 null);
193 }
194
195 writer.writeText(getDateString(context, schedule, day.getDate()), null);
196
197 writer.endElement(HTML.ANCHOR_ELEM);
198 writer.endElement(HTML.DIV_ELEM);
199
200
201 writer.startElement(HTML.DIV_ELEM, schedule);
202
203 writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule,
204 "content"), null);
205
206
207 writer.writeAttribute(HTML.STYLE_ATTR, myContentHeight + " overflow: auto; vertical-align: top;", null);
208
209
210
211 writer.startElement(HTML.DIV_ELEM, schedule);
212 writer
213 .writeAttribute(
214 HTML.STYLE_ATTR,
215 "height: 100%; vertical-align: top;",
216 null);
217
218 writer.writeAttribute(HTML.ID_ATTR, dayBodyId, null);
219
220
221
222 if (!schedule.isReadonly() && schedule.isSubmitOnClick()) {
223 writer.writeAttribute(
224 HTML.ONCLICK_ATTR,
225 "fireScheduleTimeClicked(this, event, '"
226 + formId + "', '"
227 + clientId
228 + "');",
229 null);
230 }
231
232 writeEntries(context, schedule, day, writer);
233
234 writer.endElement(HTML.DIV_ELEM);
235 writer.endElement(HTML.DIV_ELEM);
236 writer.endElement(HTML.DIV_ELEM);
237 writer.endElement(HTML.TD_ELEM);
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257 protected void writeEntries(FacesContext context, HtmlSchedule schedule,
258 ScheduleDay day, ResponseWriter writer) throws IOException
259 {
260 final String clientId = schedule.getClientId(context);
261 final FormInfo parentFormInfo = RendererUtils.findNestingForm(schedule, context);
262 final String formId = parentFormInfo == null ? null : parentFormInfo.getFormName();
263 final TreeSet entrySet = new TreeSet(comparator);
264
265 for (Iterator entryIterator = day.iterator(); entryIterator.hasNext();)
266 {
267 ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
268 entrySet.add(entry);
269 }
270
271 if (entrySet.size() > 0)
272 {
273 writer.startElement(HTML.TABLE_ELEM, schedule);
274 writer.writeAttribute(HTML.CELLPADDING_ATTR, "0", null);
275 writer.writeAttribute(HTML.CELLSPACING_ATTR, "0", null);
276 writer.writeAttribute(HTML.STYLE_ATTR, "width: 100%;", null);
277
278 for (Iterator entryIterator = entrySet.iterator(); entryIterator
279 .hasNext();)
280 {
281 ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
282 writer.startElement(HTML.TR_ELEM, schedule);
283 writer.startElement(HTML.TD_ELEM, schedule);
284
285 if (isSelected(schedule, entry))
286 {
287 writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule,
288 "selected"), null);
289 }
290
291
292 StringBuffer entryStyle = new StringBuffer();
293 entryStyle.append("width: 100%;");
294 String entryColor = getEntryRenderer(schedule).getColor(context, schedule, entry, isSelected(schedule, entry));
295 if (isSelected(schedule, entry) && entryColor != null) {
296 entryStyle.append(" background-color: ");
297 entryStyle.append(entryColor);
298 entryStyle.append(";");
299 entryStyle.append(" border-color: ");
300 entryStyle.append(entryColor);
301 entryStyle.append(";");
302 }
303
304 writer.writeAttribute(HTML.STYLE_ATTR, entryStyle.toString(), null);
305
306
307 if (schedule.isTooltip())
308 {
309 getEntryRenderer(schedule).renderToolTip(context, writer,
310 schedule, entry, isSelected(schedule, entry));
311 }
312
313 if (!isSelected(schedule, entry) && !schedule.isReadonly())
314 {
315 writer.startElement(HTML.ANCHOR_ELEM, schedule);
316 writer.writeAttribute(HTML.HREF_ATTR, "#", null);
317
318 writer.writeAttribute(
319 HTML.ONCLICK_ATTR,
320 "fireEntrySelected('"
321 + formId + "', '"
322 + clientId + "', '"
323 + entry.getId()
324 + "');",
325 null);
326 }
327
328
329 getEntryRenderer(schedule).renderContent(context, writer, schedule,
330 day, entry, true, isSelected(schedule, entry));
331
332 if (!isSelected(schedule, entry) && !schedule.isReadonly())
333 {
334 writer.endElement(HTML.ANCHOR_ELEM);
335 }
336
337 writer.endElement(HTML.TD_ELEM);
338 writer.endElement(HTML.TR_ELEM);
339 }
340 writer.endElement(HTML.TABLE_ELEM);
341 }
342 }
343
344 protected boolean isSelected(HtmlSchedule schedule, ScheduleEntry entry)
345 {
346 ScheduleEntry selectedEntry = schedule.getModel().getSelectedEntry();
347
348 if (selectedEntry == null)
349 {
350 return false;
351 }
352
353 return selectedEntry.getId().equals(entry.getId());
354 }
355
356
357
358
359
360 protected Date determineLastClickedDate(HtmlSchedule schedule, String dateId, String yPos) {
361
362 String day = dateId.substring(dateId.lastIndexOf("_") + 1);
363 Date date = ScheduleUtil.getDateFromId(day, schedule.getModel().getTimeZone());
364
365 Calendar cal = getCalendarInstance(schedule, date != null ? date : new Date());
366 cal.set(Calendar.HOUR_OF_DAY, schedule.getVisibleStartHour());
367 cal.set(Calendar.MINUTE, 0);
368 cal.set(Calendar.SECOND, 0);
369 cal.set(Calendar.MILLISECOND, 0);
370 log.debug("last clicked datetime: " + cal.getTime());
371 return cal.getTime();
372 }
373
374 }
375