/** * <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.List; import org.apache.commons.lang.RandomStringUtils; import org.olat.commons.calendar.CalendarManager; import org.olat.commons.calendar.manager.ImportCalendarManager; import org.olat.commons.calendar.model.Kalendar; import org.olat.commons.calendar.ui.CalendarPersonalConfigurationDataModel.ConfigCols; import org.olat.commons.calendar.ui.components.KalendarRenderWrapper; import org.olat.commons.calendar.ui.events.CalendarGUIEvent; import org.olat.commons.calendar.ui.events.CalendarGUIImportEvent; import org.olat.commons.calendar.ui.events.CalendarGUIRemoveEvent; import org.olat.commons.calendar.ui.events.CalendarGUISettingEvent; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.springframework.beans.factory.annotation.Autowired; /** * Manage your calendars. * * Initial date: 26.08.2015<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class CalendarPersonalConfigurationController extends FormBasicController { private FlexiTableElement tableEl; private CalendarPersonalConfigurationDataModel model; private FormLink importTypeFileButton; private FormLink importTypeUrlButton; private CloseableModalController cmc; private CalendarURLController feedUrlCtrl; private DialogBoxController confirmRemoveTokenDialog; private CalendarToolsController calendarToolsCtrl; private CloseableCalloutWindowController calloutCtrl; private DialogBoxController confirmDeleteCalendarDialog; private ImportCalendarFileController calendarFileUploadCtrl; private ImportCalendarByUrlController calendarUrlImportCtrl; private InjectCalendarFileController injectCalendarFileCtrl; private SynchronizedCalendarUrlController synchronizedCalendarUrlCtrl; private CalendarColorChooserController colorChooserCtrl; private int counter; private final boolean allowImport; private List<KalendarRenderWrapper> calendars; @Autowired private CalendarManager calendarManager; @Autowired private ImportCalendarManager importCalendarManager; public CalendarPersonalConfigurationController(UserRequest ureq, WindowControl wControl, List<KalendarRenderWrapper> calendars, boolean allowImport) { super(ureq, wControl, "configuration"); this.calendars = calendars; this.allowImport = allowImport; setTranslator(Util.createPackageTranslator(CalendarManager.class, getLocale(), getTranslator())); initForm(ureq); } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { if(allowImport) { importTypeFileButton = uifactory.addFormLink("cal.import.type.file", formLayout, Link.BUTTON); importTypeFileButton.setIconLeftCSS("o_icon o_icon_import"); importTypeUrlButton = uifactory.addFormLink("cal.synchronize.type.url", formLayout, Link.BUTTON); importTypeUrlButton.setIconLeftCSS("o_icon o_icon_calendar_sync"); } //add the table FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ConfigCols.type.i18nKey(), ConfigCols.type.ordinal(), true, ConfigCols.type.name(), new CalendarTypeClassRenderer())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ConfigCols.cssClass.i18nKey(), ConfigCols.cssClass.ordinal(), true, ConfigCols.cssClass.name())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ConfigCols.name.i18nKey(), ConfigCols.name.ordinal(), true, ConfigCols.name.name())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ConfigCols.visible.i18nKey(), ConfigCols.visible.ordinal(), true, ConfigCols.visible.name())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ConfigCols.aggregated.i18nKey(), ConfigCols.aggregated.ordinal(), true, ConfigCols.aggregated.name())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ConfigCols.feed.i18nKey(), ConfigCols.feed.ordinal())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ConfigCols.tools.i18nKey(), ConfigCols.tools.ordinal())); model = new CalendarPersonalConfigurationDataModel(columnsModel); List<CalendarPersonalConfigurationRow> rows = new ArrayList<>(calendars.size()); for(KalendarRenderWrapper calendar:calendars) { CalendarPersonalConfigurationRow row = new CalendarPersonalConfigurationRow(calendar); initLinks(row); rows.add(row); } model.setObjects(rows); tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout); tableEl.setMultiSelect(false); tableEl.setPageSize(50); tableEl.setCustomizeColumns(false); tableEl.setNumOfRowsEnabled(false); } private void initLinks(CalendarPersonalConfigurationRow row) { FormLink colorLink = uifactory.addFormLink("col_" + (++counter), "color", "", null, null, Link.NONTRANSLATED); colorLink.setIconLeftCSS("o_cal_config_color ".concat(row.getCssClass())); colorLink.setUserObject(row); row.setColorLink(colorLink); FormLink visibleLink = uifactory.addFormLink("vis_" + (++counter), "visible", "", null, null, Link.NONTRANSLATED); enableDisableIcons(visibleLink, row.isVisible()); visibleLink.setUserObject(row); row.setVisibleLink(visibleLink); FormLink aggregatedLink = uifactory.addFormLink("agg_" + (++counter), "aggregated", "", null, null, Link.NONTRANSLATED); enableDisableIcons(aggregatedLink, row.isAggregated()); aggregatedLink.setUserObject(row); row.setAggregatedLink(aggregatedLink); FormLink feedLink = uifactory.addFormLink("fee_" + (++counter), "feed", "", null, null, Link.NONTRANSLATED); feedLink.setIconLeftCSS("o_icon o_icon-lg o_icon_rss"); feedLink.setUserObject(row); row.setFeedLink(feedLink); FormLink toolsLink = uifactory.addFormLink("tools_" + (++counter), "tools", "", null, null, Link.NONTRANSLATED); toolsLink.setIconLeftCSS("o_icon o_icon-lg o_icon_actions"); toolsLink.setUserObject(row); row.setToolsLink(toolsLink); } private void enableDisableIcons(FormLink link, boolean enabled) { link.setIconLeftCSS(enabled ? "o_icon o_icon_calendar_enabled" : "o_icon o_icon_calendar_disabled"); } @Override protected void doDispose() { // } @Override protected void event(UserRequest ureq, Controller source, Event event) { if(calloutCtrl == source || cmc == source) { cleanUp(); } else if (source == confirmRemoveTokenDialog ) { if (DialogBoxUIFactory.isOkEvent(event)) { doDeleteToken((CalendarPersonalConfigurationRow)confirmRemoveTokenDialog.getUserObject()); showInfo("cal.icalfeed.remove.info"); fireEvent(ureq, Event.CHANGED_EVENT); } } else if (source == confirmDeleteCalendarDialog ) { if (DialogBoxUIFactory.isOkEvent(event)) { doDeleteCalendar(ureq, (CalendarPersonalConfigurationRow)confirmDeleteCalendarDialog.getUserObject()); showInfo("cal.import.remove.info"); fireEvent(ureq, Event.CHANGED_EVENT); } } else if(calendarFileUploadCtrl == source) { KalendarRenderWrapper calendar = calendarFileUploadCtrl.getImportedCalendar(); cmc.deactivate(); cleanUp(); if(event == Event.DONE_EVENT) { doImportCalendar(calendar); fireEvent(ureq, new CalendarGUIImportEvent(calendar)); } } else if(calendarUrlImportCtrl == source) { KalendarRenderWrapper calendar = calendarUrlImportCtrl.getImportedCalendar(); cmc.deactivate(); cleanUp(); if(event == Event.DONE_EVENT) { doImportCalendar(calendar); fireEvent(ureq, new CalendarGUIImportEvent(calendar)); } } else if(calendarToolsCtrl == source) { CalendarPersonalConfigurationRow row = calendarToolsCtrl.getRow(); calloutCtrl.deactivate(); cleanUp(); if(CalendarGUIEvent.IMPORT_BY_FILE.equals(event.getCommand())) { doOpenInjectCalendarFile(ureq, row); } else if(CalendarGUIEvent.IMPORT_SYNCHRONIZED_URL.equals(event.getCommand())) { doOpenSynchronizedCalendarUrl(ureq, row); } else if(CalendarGUIEvent.DELETE_TOKEN.equals(event.getCommand())) { doConfirmDeleteToken(ureq, row); } else if(CalendarGUIEvent.DELETE_CALENDAR.equals(event.getCommand())) { doConfirmDeleteCalendar(ureq, row); } } else if(injectCalendarFileCtrl == source || synchronizedCalendarUrlCtrl == source) { cmc.deactivate(); cleanUp(); } else if(colorChooserCtrl == source) { if(event == Event.DONE_EVENT) { doSetColor(ureq, colorChooserCtrl.getRow(), colorChooserCtrl.getChoosenColor()); } calloutCtrl.deactivate(); cleanUp(); } super.event(ureq, source, event); } private void cleanUp() { removeAsListenerAndDispose(calendarFileUploadCtrl); removeAsListenerAndDispose(calendarUrlImportCtrl); removeAsListenerAndDispose(calendarToolsCtrl); removeAsListenerAndDispose(colorChooserCtrl); removeAsListenerAndDispose(calloutCtrl); removeAsListenerAndDispose(feedUrlCtrl); removeAsListenerAndDispose(cmc); calendarFileUploadCtrl = null; calendarUrlImportCtrl = null; calendarToolsCtrl = null; colorChooserCtrl = null; calloutCtrl = null; feedUrlCtrl = null; cmc = null; } @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source instanceof FormLink) { if(importTypeFileButton == source) { doOpenImportCalendarFile(ureq); } else if(importTypeUrlButton == source) { doOpenImportCalendarUrl(ureq); } else { FormLink link = (FormLink)source; String cmd = link.getCmd(); if("visible".equals(cmd)) { doToogleVisibility(ureq, (CalendarPersonalConfigurationRow)link.getUserObject()); } else if("aggregated".equals(cmd)) { doToogleAggregated(ureq, (CalendarPersonalConfigurationRow)link.getUserObject()); } else if("feed".equals(cmd)) { doShowFeedURL(ureq, link, (CalendarPersonalConfigurationRow)link.getUserObject()); } else if("tools".equals(cmd)) { doTools(ureq, link, (CalendarPersonalConfigurationRow)link.getUserObject()); } else if("color".equals(cmd)) { doChooseColor(ureq, link, (CalendarPersonalConfigurationRow)link.getUserObject()); } } } super.formInnerEvent(ureq, source, event); } @Override protected void formOK(UserRequest ureq) { // } @Override protected void propagateDirtinessToContainer(FormItem fiSrc, FormEvent event) { // } private void doToogleVisibility(UserRequest ureq, CalendarPersonalConfigurationRow row) { KalendarRenderWrapper calendarWrapper = row.getWrapper(); calendarWrapper.setVisible(!calendarWrapper.isVisible()); calendarManager.saveCalendarConfigForIdentity(calendarWrapper, getIdentity()); enableDisableIcons(row.getVisibleLink(), calendarWrapper.isVisible()); fireEvent(ureq, new CalendarGUISettingEvent(calendarWrapper)); } private void doToogleAggregated(UserRequest ureq, CalendarPersonalConfigurationRow row) { KalendarRenderWrapper calendarWrapper = row.getWrapper(); calendarWrapper.setInAggregatedFeed(!calendarWrapper.isInAggregatedFeed()); calendarManager.saveCalendarConfigForIdentity(calendarWrapper, getIdentity()); enableDisableIcons(row.getAggregatedLink(), calendarWrapper.isInAggregatedFeed()); fireEvent(ureq, Event.CHANGED_EVENT); } private void doShowFeedURL(UserRequest ureq, FormLink link, CalendarPersonalConfigurationRow row) { removeAsListenerAndDispose(feedUrlCtrl); removeAsListenerAndDispose(calloutCtrl); KalendarRenderWrapper calendarWrapper = row.getWrapper(); if(!StringHelper.containsNonWhitespace(row.getToken())) { calendarWrapper.setToken(RandomStringUtils.randomAlphanumeric(6)); calendarManager.saveCalendarConfigForIdentity(calendarWrapper, getIdentity()); } String calFeedLink = row.getFeedUrl(getIdentity()); feedUrlCtrl = new CalendarURLController(ureq, getWindowControl(), calFeedLink); listenTo(feedUrlCtrl); calloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(), feedUrlCtrl.getInitialComponent(), link.getFormDispatchId(), "", true, ""); listenTo(calloutCtrl); calloutCtrl.activate(); } private void doConfirmDeleteToken(UserRequest ureq, CalendarPersonalConfigurationRow row) { String title = translate("cal.icalfeed.remove.title"); String msg = translate("cal.icalfeed.remove.confirmation_message"); confirmRemoveTokenDialog = activateOkCancelDialog(ureq, title, msg, confirmRemoveTokenDialog); confirmRemoveTokenDialog.setUserObject(row); } private void doDeleteToken(CalendarPersonalConfigurationRow row) { KalendarRenderWrapper calendarWrapper = row.getWrapper(); calendarWrapper.setToken(null); calendarManager.saveCalendarConfigForIdentity(calendarWrapper, getIdentity()); tableEl.reloadData(); } private void doTools(UserRequest ureq, FormLink link, CalendarPersonalConfigurationRow row) { removeAsListenerAndDispose(cmc); removeAsListenerAndDispose(calendarToolsCtrl); calendarToolsCtrl = new CalendarToolsController(ureq, getWindowControl(), row); listenTo(calendarToolsCtrl); calloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(), calendarToolsCtrl.getInitialComponent(), link.getFormDispatchId(), "", true, ""); listenTo(calloutCtrl); calloutCtrl.activate(); } private void doConfirmDeleteCalendar(UserRequest ureq, CalendarPersonalConfigurationRow row) { String title = translate("cal.import.remove.title"); String msg = translate("cal.import.remove.confirmation_message"); confirmDeleteCalendarDialog = activateOkCancelDialog(ureq, title, msg, confirmDeleteCalendarDialog); confirmDeleteCalendarDialog.setUserObject(row); } private void doDeleteCalendar(UserRequest ureq, CalendarPersonalConfigurationRow row) { if(!row.isImported()) return; Kalendar calendar = row.getWrapper().getKalendar(); importCalendarManager.deleteCalendar(getIdentity(), calendar); List<CalendarPersonalConfigurationRow> currentRows = model.getObjects(); currentRows.remove(row); model.setObjects(currentRows); tableEl.reloadData(); fireEvent(ureq, new CalendarGUIRemoveEvent(row.getWrapper())); } private void doOpenImportCalendarFile(UserRequest ureq) { calendarFileUploadCtrl = new ImportCalendarFileController(ureq, getWindowControl()); listenTo(calendarFileUploadCtrl); String title = translate("cal.import.type.file"); cmc = new CloseableModalController(getWindowControl(), translate("close"), calendarFileUploadCtrl.getInitialComponent(), true, title); cmc.activate(); listenTo(cmc); } private void doOpenImportCalendarUrl(UserRequest ureq) { calendarUrlImportCtrl = new ImportCalendarByUrlController(ureq, getWindowControl()); listenTo(calendarUrlImportCtrl); String title = translate("cal.synchronize.type.url"); cmc = new CloseableModalController(getWindowControl(), translate("close"), calendarUrlImportCtrl.getInitialComponent(), true, title); cmc.activate(); listenTo(cmc); } private void doImportCalendar(KalendarRenderWrapper wrapper) { CalendarPersonalConfigurationRow row = new CalendarPersonalConfigurationRow(wrapper); initLinks(row); List<CalendarPersonalConfigurationRow> rows = model.getObjects(); rows.add(row); model.setObjects(rows); tableEl.reloadData(); } private void doOpenInjectCalendarFile(UserRequest ureq, CalendarPersonalConfigurationRow row) { injectCalendarFileCtrl = new InjectCalendarFileController(ureq, getWindowControl(), row); listenTo(injectCalendarFileCtrl); String title = translate("cal.import.type.file"); cmc = new CloseableModalController(getWindowControl(), translate("close"), injectCalendarFileCtrl.getInitialComponent(), true, title); cmc.activate(); listenTo(cmc); } private void doOpenSynchronizedCalendarUrl(UserRequest ureq, CalendarPersonalConfigurationRow row) { synchronizedCalendarUrlCtrl = new SynchronizedCalendarUrlController(ureq, getWindowControl(), row); listenTo(synchronizedCalendarUrlCtrl); String title = translate("cal.synchronize.type.url"); cmc = new CloseableModalController(getWindowControl(), translate("close"), synchronizedCalendarUrlCtrl.getInitialComponent(), true, title); cmc.activate(); listenTo(cmc); } private void doChooseColor(UserRequest ureq, FormLink link, CalendarPersonalConfigurationRow row) { removeAsListenerAndDispose(calloutCtrl); removeAsListenerAndDispose(colorChooserCtrl); colorChooserCtrl = new CalendarColorChooserController(ureq, getWindowControl(), row); listenTo(colorChooserCtrl); calloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(), colorChooserCtrl.getInitialComponent(), link.getFormDispatchId(), "", true, ""); listenTo(calloutCtrl); calloutCtrl.activate(); } private void doSetColor(UserRequest ureq, CalendarPersonalConfigurationRow row, String cssColor) { KalendarRenderWrapper calendarWrapper = row.getWrapper(); calendarWrapper.setCssClass(cssColor); calendarManager.saveCalendarConfigForIdentity(calendarWrapper, getIdentity()); row.getColorLink().setIconLeftCSS("o_cal_config_color ".concat(row.getCssClass())); fireEvent(ureq, new CalendarGUISettingEvent(calendarWrapper)); } }