Package org.olat.commons.calendar.ui

Source Code of org.olat.commons.calendar.ui.WeeklyCalendarController

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <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>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <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 org.olat.commons.calendar.CalendarManager;
import org.olat.commons.calendar.CalendarManagerFactory;
import org.olat.commons.calendar.CalendarUtils;
import org.olat.commons.calendar.GotoDateEvent;
import org.olat.commons.calendar.ImportCalendarManager;
import org.olat.commons.calendar.model.Kalendar;
import org.olat.commons.calendar.model.KalendarComparator;
import org.olat.commons.calendar.model.KalendarEvent;
import org.olat.commons.calendar.ui.components.KalendarRenderWrapper;
import org.olat.commons.calendar.ui.components.WeeklyCalendarComponent;
import org.olat.commons.calendar.ui.events.KalendarGUIAddEvent;
import org.olat.commons.calendar.ui.events.KalendarGUIEditEvent;
import org.olat.commons.calendar.ui.events.KalendarModifiedEvent;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.components.panel.Panel;
import org.olat.core.gui.components.util.ComponentUtil;
import org.olat.core.gui.components.velocity.VelocityContainer;
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.controller.BasicController;
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.gui.translator.PackageTranslator;
import org.olat.core.gui.translator.Translator;
import org.olat.core.util.CodeHelper;
import org.olat.core.util.Util;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.event.GenericEventListener;
import org.olat.core.util.notifications.ContextualSubscriptionController;
import org.olat.core.util.notifications.NotificationsManager;
import org.olat.core.util.notifications.SubscriptionContext;
import org.olat.core.util.resource.OresHelper;

import de.bps.olat.util.notifications.SubscriptionProvider;
import de.bps.olat.util.notifications.SubscriptionProviderImpl;

public class WeeklyCalendarController extends BasicController implements CalendarController, GenericEventListener {

  private static final String PACKAGE = CalendarManager.class.getPackage().getName();
  private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(CalendarManager.class);

  private static final String CMD_PREVIOUS_WEEK = "pw";
  private static final String CMD_NEXT_WEEK = "nw";

  public static final String CALLER_HOME = "home";
  public static final String CALLER_PROFILE = "profile";
  public static final String CALLER_COLLAB = "collab";
  public static final String CALLER_COURSE = "course";
 
  private Panel mainPanel;
  private VelocityContainer vcMain;
  private Translator translator;
  private List<KalendarRenderWrapper> calendarWrappers;
  private List<KalendarRenderWrapper> importedCalendarWrappers;
  private WeeklyCalendarComponent weeklyCalendar;
  private KalendarConfigurationController calendarConfig;
  private ImportedCalendarConfigurationController importedCalendarConfig;
  private KalendarEntryDetailsController editController;
  private SearchAllCalendarsController searchController;
  private CalendarSubscription calendarSubscription;
  private Controller subscriptionController;
  private String caller;
  private boolean dirty = false;
  private Link thisWeekLink;
  private Link searchLink;
  private Link subscribeButton;
  private Link unsubscribeButton;

  private CloseableModalController cmc;
  private GotoDateCalendarsForm gotoDateForm;
  private SubscriptionContext subsContext;
  private ContextualSubscriptionController csc;
 
  /**
   * three options:
   * 1. edit sequence
   * 2. delete single date
   * 3. delete whole sequence
   */
  private DialogBoxController dbcSequence;
  private DialogBoxController deleteSingleYesNoController, deleteSequenceYesNoController;
  private String modifiedCalendarId;
  private boolean modifiedCalenderDirty = false;
/**
   * Display week view of calendar. Add the calendars to be displayed via
   * addKalendarWrapper(KalendarRenderWrapper kalendarWrapper) method.
   *
   * @param ureq
   * @param wControl
   */
  public WeeklyCalendarController(UserRequest ureq, WindowControl wControl, List<KalendarRenderWrapper> calendarWrappers, String caller) {
    this(ureq, wControl, calendarWrappers, new ArrayList<KalendarRenderWrapper>(), caller, null);
  }

  public WeeklyCalendarController(UserRequest ureq, WindowControl wControl, List<KalendarRenderWrapper> calendarWrappers, List<KalendarRenderWrapper> importedCalendarWrappers, String caller) {
    this(ureq, wControl, calendarWrappers, importedCalendarWrappers, caller, null);
  }

 
  public WeeklyCalendarController(UserRequest ureq, WindowControl wControl, List<KalendarRenderWrapper> calendarWrappers, String caller, CalendarSubscription calendarSubscription) {
    this(ureq, wControl, calendarWrappers, new ArrayList<KalendarRenderWrapper>(), caller, calendarSubscription);
  }
 
  /**
   * Display week view of calendar. Add the calendars to be displayed via
   * addKalendarWrapper(KalendarRenderWrapper kalendarWrapper) method.
   *
   * @param ureq
   * @param wControl
   * @param calendarSubscription Provide a CalendarSubscription component or null if no subscription available.
   */
  public WeeklyCalendarController(UserRequest ureq, WindowControl wControl, List<KalendarRenderWrapper> calendarWrappers, List<KalendarRenderWrapper> importedCalendarWrappers, String caller, CalendarSubscription calendarSubscription) {
    super(ureq,wControl);
    this.calendarWrappers = calendarWrappers;
    this.importedCalendarWrappers = importedCalendarWrappers;
    this.calendarSubscription = calendarSubscription;
    this.caller = caller;

    // translator
    translator = new PackageTranslator(PACKAGE, ureq.getLocale());

    // main panel
    mainPanel = new Panel("mainPanel");
   
    // main velocity controller
    vcMain = new VelocityContainer("calMain", VELOCITY_ROOT + "/indexWeekly.html", translator, this);
    thisWeekLink = LinkFactory.createLink("cal.thisweek", vcMain, this);
    gotoDateForm = new GotoDateCalendarsForm(ureq, wControl, translator);
    this.listenTo(gotoDateForm);
    vcMain.put("cal.gotodate", gotoDateForm.getInitialComponent());
    searchLink = LinkFactory.createLink("cal.search.button", vcMain, this);
    subscribeButton = LinkFactory.createButtonXSmall("cal.subscribe", vcMain, this);
    unsubscribeButton = LinkFactory.createButtonXSmall("cal.unsubscribe", vcMain, this);
   
    vcMain.contextPut("caller", caller);
    mainPanel.setContent(vcMain);
   
    Collections.sort(calendarWrappers, KalendarComparator.getInstance());
    Collections.sort(importedCalendarWrappers, KalendarComparator.getInstance());
   
    List<KalendarRenderWrapper> allCalendarWrappers = new ArrayList<KalendarRenderWrapper>(calendarWrappers);
    allCalendarWrappers.addAll(importedCalendarWrappers);
    weeklyCalendar = new WeeklyCalendarComponent("weeklyCalendar", allCalendarWrappers, 7, getTranslator());
    weeklyCalendar.addListener(this);

    // subscription, see OLAT-3861
    SubscriptionProvider provider = new SubscriptionProviderImpl(caller, calendarWrappers.get(0));
    subsContext = provider.getSubscriptionContext();
    // if sc is null, then no subscription is desired
    if (subsContext != null) {
      csc = provider.getContextualSubscriptionController(ureq, getWindowControl());
      vcMain.put("calsubscription", csc.getInitialComponent());
    }

    ComponentUtil.registerForValidateEvents(vcMain, this);

    vcMain.put("calendar", weeklyCalendar);

    // calendarConfiguration component
    calendarConfig = new KalendarConfigurationController(calendarWrappers, ureq, getWindowControl(), false, true);
    calendarConfig.addControllerListener(this);
    vcMain.put("calendarConfig", calendarConfig.getInitialComponent());
    importedCalendarConfig = new ImportedCalendarConfigurationController(importedCalendarWrappers, ureq, getWindowControl(), false);
    importedCalendarConfig.addControllerListener(this);
    vcMain.put("importedCalendarConfig", importedCalendarConfig.getInitialComponent());

    // calendar subscription
    if (calendarSubscription == null) {
      vcMain.contextPut("hasSubscription", Boolean.FALSE);
    } else {
      vcMain.contextPut("hasSubscription", Boolean.TRUE);
      vcMain.contextPut("isSubscribed", new Boolean(calendarSubscription.isSubscribed()));
    }

    this.putInitialPanel(mainPanel);
   
    CoordinatorManager.getCoordinator().getEventBus().registerFor(this, ureq.getIdentity(), OresHelper.lookupType(CalendarManager.class));
  }
 
  public void setEnableRemoveFromPersonalCalendar(boolean enable) {
    calendarConfig.setEnableRemoveFromPersonalCalendar(enable);
  }

  public void setFocus(Date date) {
    Calendar focus = CalendarUtils.createCalendarInstance(getLocale());
    focus.setTime(date);
    weeklyCalendar.setFocus(focus.get(Calendar.YEAR), focus.get(Calendar.WEEK_OF_YEAR));
  }
 
  @Override
  public void setFocusOnEvent(String eventId) {
    if  (eventId.length() > 0) {
      for(KalendarRenderWrapper wrapper:calendarWrappers) {
        KalendarEvent event = wrapper.getKalendar().getEvent(eventId);
        if(event != null) {
          setFocus(event.getBegin());
          break;
        }
      }
    }
  }

  public void setCalendars(List calendars) {
    setCalendars(calendars, new ArrayList());
  }

  public void setCalendars(List calendars, List importedCalendars) {
    this.calendarWrappers = calendars;
    Collections.sort(calendarWrappers, KalendarComparator.getInstance());
    weeklyCalendar.setKalendars(calendarWrappers);
    calendarConfig.setCalendars(calendarWrappers);

    this.importedCalendarWrappers = importedCalendars;
    Collections.sort(calendarWrappers, KalendarComparator.getInstance());
    Collections.sort(importedCalendarWrappers, KalendarComparator.getInstance());
   
    ArrayList allCalendarWrappers = new ArrayList(calendarWrappers);
    allCalendarWrappers.addAll(importedCalendarWrappers);
    weeklyCalendar.setKalendars(allCalendarWrappers);
   
    calendarConfig.setCalendars(calendarWrappers);
    importedCalendarConfig.setCalendars(importedCalendarWrappers);
  }
 
  public void setDirty() {
    dirty = true;
  }
 
  public void event(UserRequest ureq, Component source, Event event) {
    if (event == ComponentUtil.VALIDATE_EVENT && dirty) {
      dirty = false;
      fireEvent(ureq, new KalendarModifiedEvent());
    } else if (event == ComponentUtil.VALIDATE_EVENT && weeklyCalendar.isDirty() && modifiedCalenderDirty  ) {
      KalendarRenderWrapper kalendarRenderWrapper = weeklyCalendar.getKalendarRenderWrapper(modifiedCalendarId);
      kalendarRenderWrapper.reloadKalendar()
    }else if (source == vcMain) {
      if (event.getCommand().equals(CMD_PREVIOUS_WEEK)) {
        weeklyCalendar.previousWeek();
      } else if (event.getCommand().equals(CMD_NEXT_WEEK)) {
        weeklyCalendar.nextWeek();
      }
    } else if (source == thisWeekLink){
      Calendar cal = CalendarUtils.createCalendarInstance(ureq.getLocale());
      weeklyCalendar.setFocus(cal.get(Calendar.YEAR), cal.get(Calendar.WEEK_OF_YEAR));
    } else if (source == searchLink) {
      if (searchController != null) searchController.dispose();
      ArrayList allCalendarWrappers = new ArrayList(calendarWrappers);
      allCalendarWrappers.addAll(importedCalendarWrappers);
      searchController = new SearchAllCalendarsController(ureq, getWindowControl(), translator, allCalendarWrappers);
      searchController.addControllerListener(this);
      if (cmc != null) cmc.dispose();
      cmc = new CloseableModalController(getWindowControl(), translator.translate("close"), searchController.getInitialComponent());
      cmc.activate();
    } else if (source == subscribeButton || source == unsubscribeButton) {
      if (subscriptionController != null) subscriptionController.dispose();
      if(calendarSubscription.isSubscribed() == (source == unsubscribeButton)) {
        subscriptionController = calendarSubscription.triggerSubscribeAction();
      }
      if (subscriptionController != null) {
        // activate subscription controller
        subscriptionController.addControllerListener(this);
        mainPanel.setContent(subscriptionController.getInitialComponent());
      } else {
        vcMain.contextPut("isSubscribed", new Boolean(calendarSubscription.isSubscribed()));
        CoordinatorManager.getCoordinator().getEventBus().fireEventToListenersOf(new KalendarModifiedEvent(), OresHelper.lookupType(CalendarManager.class));
      }
    } else if (source == weeklyCalendar) {
      if (event instanceof KalendarGUIEditEvent) {
        KalendarGUIEditEvent guiEvent = (KalendarGUIEditEvent) event;
        KalendarEvent kalendarEvent = guiEvent.getKalendarEvent();
        if (kalendarEvent == null) {
          // event already deleted
          getWindowControl().setError(translator.translate("cal.error.eventDeleted"));
          return;
        }
        String recurrence = kalendarEvent.getRecurrenceRule();
        boolean isImported = false;
        KalendarRenderWrapper kalendarRenderWrapper = guiEvent.getKalendarRenderWrapper();
        if (kalendarRenderWrapper!=null) {
          isImported = kalendarRenderWrapper.isImported();
        }
        if( !isImported && recurrence != null && !recurrence.equals("") ) {
          List<String> btnLabels = new ArrayList<String>();
          btnLabels.add(translator.translate("cal.edit.dialog.sequence"));
          btnLabels.add(translator.translate("cal.edit.dialog.delete.single"));
          btnLabels.add(translator.translate("cal.edit.dialog.delete.sequence"));
          if (dbcSequence != null) dbcSequence.dispose();
          dbcSequence = DialogBoxUIFactory.createGenericDialog(ureq, getWindowControl(), translator.translate("cal.edit.dialog.title"), translator.translate("cal.edit.dialog.text"), btnLabels);
          dbcSequence.addControllerListener(this);
          dbcSequence.setUserObject(guiEvent);
          dbcSequence.activate();
          return;
        }
        KalendarRenderWrapper kalendarWrapper = guiEvent.getKalendarRenderWrapper();
        pushEditEventController(ureq, kalendarEvent, kalendarWrapper);
      } else if (event instanceof KalendarGUIAddEvent) {
        pushAddEventController((KalendarGUIAddEvent)event, ureq);
      }
    }
  }

  public void event(UserRequest ureq, Controller source, Event event) {
    Kalendar affectedCal = null;
    if (dirty) {
      dirty = false;
      fireEvent(ureq, new KalendarModifiedEvent());
    }
    if (source == editController) {
      affectedCal = editController.getKalendarEvent().getCalendar();
      cmc.deactivate();
      weeklyCalendar.setDirty(true);
    } else if(source == cmc && event == CloseableModalController.CLOSE_MODAL_EVENT){
      //DO NOT DEACTIVATE AS ALREADY CLOSED BY CloseableModalController INTERNALLY
      weeklyCalendar.setDirty(true);
    } else if (source == calendarConfig || source == importedCalendarConfig) {
      if (event instanceof KalendarGUIAddEvent) {
        pushAddEventController((KalendarGUIAddEvent)event, ureq);
      } else if (event == Event.CHANGED_EVENT) {
        importedCalendarWrappers = ImportCalendarManager.getImportedCalendarsForIdentity(ureq);
        importedCalendarConfig.setCalendars(importedCalendarWrappers);
        this.setCalendars(calendarWrappers, importedCalendarWrappers);
        weeklyCalendar.setDirty(true);
        vcMain.setDirty(true);
      }
    } else if (source == searchController) {
      if (event instanceof GotoDateEvent) {
        Date gotoDate = ((GotoDateEvent)event).getGotoDate();
        weeklyCalendar.setDate(gotoDate);
      }
      cmc.deactivate();
    } else if (source == subscriptionController) {
      // nothing to do here
      mainPanel.setContent(vcMain);
      vcMain.contextPut("isSubscribed", new Boolean(calendarSubscription.isSubscribed()));
    } else if (source == gotoDateForm) {
      weeklyCalendar.setDate(gotoDateForm.getGotoDate());
    } else if (source == dbcSequence) {
      if(event != Event.CANCELLED_EVENT) {
        int pos = DialogBoxUIFactory.getButtonPos(event);
        KalendarGUIEditEvent guiEvent = (KalendarGUIEditEvent)dbcSequence.getUserObject();
        KalendarRenderWrapper kalendarWrapper = guiEvent.getKalendarRenderWrapper();
        KalendarEvent kalendarEvent = guiEvent.getKalendarEvent();
        if(pos == 0) { // edit the sequence
          // load the parent event of this sequence
          KalendarEvent parentEvent = kalendarWrapper.getKalendar().getEvent(kalendarEvent.getID());
          pushEditEventController(ureq, parentEvent, kalendarWrapper);
        } else if(pos == 1) { // delete a single event of the sequence
          deleteSingleYesNoController = activateYesNoDialog(ureq, null, translator.translate("cal.delete.dialogtext"), deleteSingleYesNoController);
          deleteSingleYesNoController.setUserObject(kalendarEvent);
        } else if(pos == 2) { // delete the whole sequence
          deleteSequenceYesNoController = activateYesNoDialog(ureq, null, translator.translate("cal.delete.dialogtext.sequence"), deleteSequenceYesNoController);
          deleteSequenceYesNoController.setUserObject(kalendarEvent);
        }
      }
      dbcSequence.dispose();
    } else if (source == deleteSingleYesNoController) {
      if (DialogBoxUIFactory.isYesEvent(event)) {
        KalendarEvent kalendarEvent = (KalendarEvent)deleteSingleYesNoController.getUserObject();
        affectedCal = kalendarEvent.getCalendar();
        KalendarEvent kEvent = affectedCal.getEvent(kalendarEvent.getID());
        kEvent.addRecurrenceExc(kalendarEvent.getBegin());
        CalendarManagerFactory.getInstance().getCalendarManager().updateEventFrom(affectedCal, kEvent);
        deleteSingleYesNoController.dispose();
        weeklyCalendar.setDirty(true);
        vcMain.setDirty(true);
      }
    } else if (source == deleteSequenceYesNoController) {
      if (DialogBoxUIFactory.isYesEvent(event)) {
        KalendarEvent kalendarEvent = (KalendarEvent)deleteSequenceYesNoController.getUserObject();
        affectedCal = kalendarEvent.getCalendar();
        CalendarManagerFactory.getInstance().getCalendarManager().removeEventFrom(affectedCal, kalendarEvent);
        deleteSequenceYesNoController.dispose();
        weeklyCalendar.setDirty(true);
        vcMain.setDirty(true);
      }
    }
    if (weeklyCalendar.isDirty()) {
      if (subsContext != null) {
        // group or course calendar -> prepared subscription context is the right one
        NotificationsManager.getInstance().markPublisherNews(subsContext, ureq.getIdentity());
      } else if(this.caller.equals(CALLER_HOME) && affectedCal != null) {
        // one can add/edit/remove dates of group and course calendars from the home calendar view -> choose right subscription context
        KalendarRenderWrapper calWrapper = null;
        for( Object calWrapperObj : calendarWrappers) {
          calWrapper = (KalendarRenderWrapper) calWrapperObj;
          if(affectedCal == calWrapper.getKalendar()) break;
        }
        if(calWrapper != null) {
          SubscriptionProvider provider = new SubscriptionProviderImpl(calWrapper);
          SubscriptionContext tmpSubsContext = provider.getSubscriptionContext();
          NotificationsManager.getInstance().markPublisherNews(tmpSubsContext, ureq.getIdentity());
        }
      }
    }
  }

  /**
   * @param ureq
   * @param kalendarEvent
   * @param kalendarWrapper
   */
  private void pushEditEventController(UserRequest ureq, KalendarEvent kalendarEvent, KalendarRenderWrapper kalendarWrapper) {
    if (editController != null) editController.dispose();
    editController = new KalendarEntryDetailsController(ureq, kalendarEvent, kalendarWrapper,  calendarWrappers, false, caller, getWindowControl());
    editController.addControllerListener(this);
    if (cmc != null) cmc.dispose();
    cmc = new CloseableModalController(getWindowControl(), translator.translate("close"), editController.getInitialComponent());
    cmc.addControllerListener(this);
    cmc.activate();
  }

  private void pushAddEventController(KalendarGUIAddEvent addEvent, UserRequest ureq) {
    KalendarRenderWrapper calendarWrapper = weeklyCalendar.getKalendarRenderWrapper(addEvent.getCalendarID());
    // create new KalendarEvent
    KalendarEvent newEvent = new KalendarEvent(CodeHelper.getGlobalForeverUniqueID(), "", addEvent.getStartDate(), (1000 * 60 * 60 * 1));
    if (calendarWrapper.getKalendar().getType().equals(CalendarManager.TYPE_COURSE) ||
        calendarWrapper.getKalendar().getType().equals(CalendarManager.TYPE_GROUP))
      newEvent.setClassification(KalendarEvent.CLASS_PUBLIC);
    if (editController != null) editController.dispose();
    ArrayList allCalendarWrappers = new ArrayList(calendarWrappers);
    allCalendarWrappers.addAll(importedCalendarWrappers);
    editController = new KalendarEntryDetailsController(ureq, newEvent,
        calendarWrapper, allCalendarWrappers, true, caller, getWindowControl());
    editController.addControllerListener(this);
    if (cmc != null) cmc.dispose();
    cmc = new CloseableModalController(getWindowControl(), translator.translate("close"), editController.getInitialComponent());
    cmc.addControllerListener(this);
    cmc.activate();
  }
 
  protected void doDispose() {
    CoordinatorManager.getCoordinator().getEventBus().deregisterFor(this, OresHelper.lookupType(CalendarManager.class));
    if (editController != null) {
      editController.dispose();
      editController = null;
    }
    if (calendarConfig != null) {
      calendarConfig.dispose();
      calendarConfig = null;
    }
    if (searchController != null) {
      searchController.dispose();
      searchController = null;
    }
    if (cmc != null) {
      cmc.dispose();
      cmc = null;
    }
    if (subscriptionController != null) {
      subscriptionController.dispose();
      subscriptionController = null;
    }
   
  }
 
  public void event(Event event) {
    if (event instanceof KalendarModifiedEvent) {
      KalendarModifiedEvent kalendarModifiedEvent = (KalendarModifiedEvent)event;
      if (kalendarModifiedEvent.getType()!=null
          && kalendarModifiedEvent.getCalendarId()!=null
          && weeklyCalendar.getKalendarRenderWrapper(kalendarModifiedEvent.getCalendarId())!=null
          && kalendarModifiedEvent.getType().equals(weeklyCalendar.getKalendarRenderWrapper(kalendarModifiedEvent.getCalendarId()).getKalendar().getType())         
          && kalendarModifiedEvent.getCalendarId().equals(weeklyCalendar.getKalendarRenderWrapper(kalendarModifiedEvent.getCalendarId()).getKalendar().getCalendarID())) {
        // the event is for my calendar => reload it       
       
        //keeping a reference to the dirty calendar as reloading here raises an nested do in sync error. Using the component validation event to reload
        modifiedCalendarId  = kalendarModifiedEvent.getCalendarId();
        modifiedCalenderDirty = true;
        weeklyCalendar.setDirty(true);
      }
    }
  }

}
TOP

Related Classes of org.olat.commons.calendar.ui.WeeklyCalendarController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.