/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.commons.calendar.ui; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.olat.commons.calendar.CalendarManager; import org.olat.commons.calendar.CalendarUtils; import org.olat.commons.calendar.model.KalendarEvent; import org.olat.commons.calendar.ui.components.KalendarEventDateComparator; import org.olat.commons.calendar.ui.components.KalendarEventRenderWrapper; import org.olat.commons.calendar.ui.components.KalendarRenderWrapper; import org.olat.core.CoreSpringFactory; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.StringMediaResource; import org.olat.core.gui.translator.Translator; import org.olat.core.util.Formatter; import org.olat.core.util.StringHelper; /** * * Initial date: 17.05.2013<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class CalendarPrintMapper implements Mapper { private final String themeBaseUri; private final Translator translator; private Date from, to; private List<KalendarRenderWrapper> calendarWrappers; private final CalendarManager calendarManager; public CalendarPrintMapper(String themeBaseUri, Translator translator) { this.themeBaseUri = themeBaseUri; this.translator = translator; calendarManager = CoreSpringFactory.getImpl(CalendarManager.class); } public Date getFrom() { return from; } public void setFrom(Date from) { this.from = from; } public Date getTo() { return to; } public void setTo(Date to) { this.to = to; } public List<KalendarRenderWrapper> getCalendarWrappers() { return calendarWrappers; } public void setCalendarWrappers(List<KalendarRenderWrapper> calendarWrappers) { this.calendarWrappers = calendarWrappers; } @Override public MediaResource handle(String relPath, HttpServletRequest request) { StringBuilder sb = new StringBuilder(); sb.append("<html><head><title>") .append("Calendar") .append("</title>") .append("<meta http-equiv='Content-type' content='text/html; charset=utf-8' />") .append("<link href='").append(themeBaseUri).append("theme.css' rel='stylesheet' type='text/css' />\n") .append("<!--[if IE 9]><link id='o_theme_css_ie' href='").append(themeBaseUri).append("theme_ie_completions.css' rel='stylesheet' type='text/css' /><![endif]-->\n") .append("</head><body class='o_cal_print' onload='window.focus();window.print()'>"); //collect all events List<KalendarEventRenderWrapper> sortedEventsWithin = new ArrayList<>(); collectEvents(sortedEventsWithin, calendarWrappers); Collections.sort(sortedEventsWithin, KalendarEventDateComparator.getInstance()); //list of events renderEvents(sb, sortedEventsWithin, from, to); //list of calendars renderCalendars(sb) ; sb.append("</body></html>"); StringMediaResource smr = new StringMediaResource(); smr.setContentType("text/html"); smr.setEncoding("UTF-8"); smr.setData(sb.toString()); return smr; } private void collectEvents(List<KalendarEventRenderWrapper> eventList, List<KalendarRenderWrapper> wrappers) { for (KalendarRenderWrapper calendarWrapper:wrappers) { if (calendarWrapper.isVisible()) { List<KalendarEvent> events = calendarManager.getEvents(calendarWrapper.getKalendar(), from, to, true); for (KalendarEvent event : events) { //private filter??? eventList.add(new KalendarEventRenderWrapper(event, calendarWrapper)); } } } } /* <div class="o_cal_wv_print"> <ul class="o_cal_wv_list"> <li> <span class="o_cal_date">Monday, May 13, 2013</span> <ul class="o_cal_events"> <li class="o_cal_event"> <div class="o_cal_time"><span>4:00 AM - 9:00 AM</span></div> <div class="o_cal_subject o_cal_blue"><p>Test</p></div> </li> </ul> </li> <li> <span class="o_cal_date">Tuesday, May 14, 2013</span> <ul class="o_cal_events"> <li class="o_cal_event"> <div class="o_cal_time"><span>2:00 PM - 3:00 PM</span></div> <div class="o_cal_subject o_cal_blue"><p>Test 3</p></div> </li> </ul> </li> </ul> <div class="clearfix"> </div> </div> */ private void renderEvents(StringBuilder sb, List<KalendarEventRenderWrapper> eventList, Date dateFrom , Date dateTo) { sb.append("<div class='o_cal_wv_print'><fieldset>") .append("<legend>").append(translator.translate("cal.print.title")) .append("<span>") .append(StringHelper.formatLocaleDateFull(dateFrom, translator.getLocale())) .append(" - ").append(StringHelper.formatLocaleDateFull(dateTo, translator.getLocale())) .append("</span></legend>") .append("<ul class='o_cal_wv_list'>"); Collections.sort(eventList, new KalendarEventDateComparator()); Date currentDate = null; List<KalendarEventRenderWrapper> eventByDayList = new ArrayList<KalendarEventRenderWrapper>(); for(KalendarEventRenderWrapper event:eventList) { Date begin = event.getEvent().getBegin(); Date normalizedBegin = CalendarUtils.removeTime(begin); //same day? if(currentDate == null || currentDate.before(normalizedBegin)) { renderDay(sb, currentDate, eventByDayList); eventByDayList.clear(); currentDate = normalizedBegin; } eventByDayList.add(event); } renderDay(sb, currentDate, eventByDayList); sb.append("</ul></fieldset><div class='clearfix'> </div></div>"); } private void renderDay(StringBuilder sb, Date date, List<KalendarEventRenderWrapper> eventList) { if(eventList.isEmpty()) return; Date dayStart = date; Calendar cal = Calendar.getInstance(); cal.setTime(dayStart); cal.add(Calendar.DAY_OF_YEAR, 1); Date dayEnd = cal.getTime(); sb.append("<li><span class='o_cal_date'>") .append(StringHelper.formatLocaleDateFull(dayStart, translator.getLocale())) .append("</span><ul class='o_cal_events'>"); for(KalendarEventRenderWrapper event:eventList) { renderEvent(sb, event, dayStart, dayEnd); } sb.append("</ul></li>"); } private void renderEvent(StringBuilder sb, KalendarEventRenderWrapper eventWrapper, Date dayStart, Date dayEnd) { KalendarEvent event = eventWrapper.getEvent(); // check if event is private and user allowed to see it if (event.getClassification() == KalendarEvent.CLASS_PRIVATE && !eventWrapper.getKalendarRenderWrapper().isPrivateEventsVisible()) { return; } // Show all PUBLIC and FREEBUSY events String escapedSubject = Formatter.escWithBR(event.getSubject()).toString(); escapedSubject = escapedSubject.replace('\r', ' '); sb.append("<li class=\"o_cal_event\">\n"); sb.append("<div class=\"o_cal_class " + eventWrapper.getCssClass() + "\"> </div>\n"); // time sb.append("<div class=\"o_cal_time\"><span>\n"); if (event.isAllDayEvent()) { sb.append(translator.translate("cal.form.allday")); } else { // set start and end times for events spanning more than one day Date begin = event.getBegin(); Date end = event.getEnd(); if (begin.before(dayStart)) { begin = dayStart; } if (end == null || end.after(dayEnd)) { end = dayEnd; } sb.append(StringHelper.formatLocaleTime(begin, translator.getLocale())); sb.append(" - "); sb.append(StringHelper.formatLocaleTime(end, translator.getLocale())); } sb.append("</span></div>\n"); // Show calendar data only when user allowed to see private data, or the event is // public or the calendar is imported (because the free/busy flag is not standard // and should not be applied to imported calendars) if (eventWrapper.getKalendarRenderWrapper().isPrivateEventsVisible() || event.getClassification() == KalendarEvent.CLASS_PUBLIC || eventWrapper.getKalendarRenderWrapper().isImported()) { // event name (subject) // firefox doesn't break lines with only <br />, we need <p> sb.append("<div class=\"o_cal_subject\"><p>"); sb.append(escapedSubject.replace("<br />", "</p><p>")); sb.append("</p></div>\n"); // location if (StringHelper.containsNonWhitespace(event.getLocation())) { sb.append("<div class=\"o_cal_location\"><span>\n<strong>"); sb.append(translator.translate("cal.form.location") + "</strong>: "); sb.append(StringHelper.escapeHtml(event.getLocation())); sb.append("</span></div>\n"); } // description if (StringHelper.containsNonWhitespace(event.getDescription())) { sb.append("<div class=\"o_cal_description\"><span>\n<strong>"); sb.append(translator.translate("cal.form.description") + "</strong>: "); sb.append(StringHelper.escapeHtml(event.getDescription())); sb.append("</span></div>\n"); } } else { // for free-busy events where user has not the right to see the private stuff // show only a message sb.append("<div class=\"o_cal_freebusy\"><p>"); sb.append(translator.translate("cal.form.subject.hidden")); sb.append("</p></div>\n"); } sb.append("</li>\n"); } /* <div id="o_cal_config"> <fieldset> <legend>List of calendars</legend> <div class="o_cal_config_row"> <div class="o_cal_config_calendar o_cal_blue"> kanu </div> </div> </fieldset> </div> */ private void renderCalendars(StringBuilder sb) { sb.append("<div id='o_cal_config'>") .append("<fieldset><legend>").append(translator.translate("cal.list")).append("</legend>"); renderCalendar(sb, calendarWrappers, false); sb.append("</fieldset>"); //list of imported calendars sb.append("<fieldset><legend>").append(translator.translate("cal.import.list")).append("</legend>"); renderCalendar(sb, calendarWrappers, true); sb.append("</fieldset>") .append("</div>"); } private void renderCalendar(StringBuilder sb, List<KalendarRenderWrapper> calendarWrapperList, boolean imported) { for(KalendarRenderWrapper calendarWrapper:calendarWrapperList) { if(calendarWrapper.isImported() == imported) { sb.append("<div class='o_cal_config_row'><div class='o_cal_config_calendar'>") .append("<div class='o_cal_class " + calendarWrapper.getCssClass() + "'> </div>\n") .append(StringHelper.escapeHtml(calendarWrapper.getDisplayName())) .append("</div></div>"); } } } }