/** * <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.repository.ui.list; import java.util.List; 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.MainPanel; import org.olat.core.gui.components.segmentedview.SegmentViewComponent; import org.olat.core.gui.components.segmentedview.SegmentViewEvent; import org.olat.core.gui.components.segmentedview.SegmentViewFactory; import org.olat.core.gui.components.stack.BreadcrumbedStackedPanel; 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.dtabs.Activateable2; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.Util; import org.olat.core.util.event.EventBus; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.resource.OresHelper; import org.olat.repository.CatalogEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryModule; import org.olat.repository.RepositoryService; import org.olat.repository.controllers.EntryChangedEvent; import org.olat.repository.controllers.EntryChangedEvent.Change; import org.olat.repository.manager.CatalogManager; import org.olat.repository.model.SearchMyRepositoryEntryViewParams; import org.olat.repository.ui.catalog.CatalogNodeController; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; /** * * Initial date: 28.01.2014<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class OverviewRepositoryListController extends BasicController implements Activateable2, GenericEventListener { private final VelocityContainer mainVC; private final SegmentViewComponent segmentView; private final Link myCourseLink; private Link favoriteLink, catalogLink, searchCourseLink, closedCourseLink; private Controller currentCtrl; private RepositoryEntryListController markedCtrl; private BreadcrumbedStackedPanel markedStackPanel; private RepositoryEntryListController myCoursesCtrl; private BreadcrumbedStackedPanel myCoursesStackPanel; private CatalogNodeController catalogCtrl; private BreadcrumbedStackedPanel catalogStackPanel; private RepositoryEntryListController searchCoursesCtrl; private RepositoryEntryListController closedCoursesCtrl; private BreadcrumbedStackedPanel searchCoursesStackPanel; private final boolean isGuestOnly; private boolean favoritDirty, myDirty; private final EventBus eventBus; @Autowired private CatalogManager catalogManager; @Autowired private RepositoryModule repositoryModule; public OverviewRepositoryListController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); setTranslator(Util.createPackageTranslator(RepositoryManager.class, getLocale(), getTranslator())); isGuestOnly = ureq.getUserSession().getRoles().isGuestOnly(); MainPanel mainPanel = new MainPanel("myCoursesMainPanel"); mainPanel.setDomReplaceable(false); mainVC = createVelocityContainer("overview"); mainPanel.setContent(mainVC); segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this); segmentView.setReselect(true); if(!isGuestOnly) { favoriteLink = LinkFactory.createLink("search.mark", mainVC, this); favoriteLink.setElementCssClass("o_sel_mycourses_fav"); segmentView.addSegment(favoriteLink, false); } myCourseLink = LinkFactory.createLink("search.mycourses.student", mainVC, this); myCourseLink.setElementCssClass("o_sel_mycourses_my"); segmentView.addSegment(myCourseLink, false); closedCourseLink = LinkFactory.createLink("search.courses.closed", mainVC, this); closedCourseLink.setElementCssClass("o_sel_mycourses_closed"); segmentView.addSegment(closedCourseLink, false); if(repositoryModule.isCatalogEnabled() && repositoryModule.isCatalogBrowsingEnabled()) { catalogLink = LinkFactory.createLink("search.catalog", mainVC, this); catalogLink.setElementCssClass("o_sel_mycourses_catlog"); segmentView.addSegment(catalogLink, false); } if(repositoryModule.isMyCoursesSearchEnabled()) { searchCourseLink = LinkFactory.createLink("search.courses.student", mainVC, this); searchCourseLink.setElementCssClass("o_sel_mycourses_search"); segmentView.addSegment(searchCourseLink, false); } eventBus = ureq.getUserSession().getSingleUserEventCenter(); eventBus.registerFor(this, getIdentity(), RepositoryService.REPOSITORY_EVENT_ORES); putInitialPanel(mainPanel); } @Override public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { if(entries == null || entries.isEmpty()) { if(currentCtrl == null) { if(isGuestOnly) { doOpenMyCourses(ureq); segmentView.select(myCourseLink); } else { boolean markEmpty = doOpenMark(ureq).isEmpty(); if(markEmpty) { doOpenMyCourses(ureq); segmentView.select(myCourseLink); } else { segmentView.select(favoriteLink); } } } if(favoritDirty && markedCtrl != null) { markedCtrl.reloadRows(); } if(myDirty && myCoursesCtrl != null) { myCoursesCtrl.reloadRows(); } addToHistory(ureq, this); } else { ContextEntry entry = entries.get(0); String segment = entry.getOLATResourceable().getResourceableTypeName(); List<ContextEntry> subEntries = entries.subList(1, entries.size()); if("Favorits".equalsIgnoreCase(segment)) { if(isGuestOnly) { doOpenMyCourses(ureq).activate(ureq, subEntries, entry.getTransientState()); segmentView.select(myCourseLink); } else { doOpenMark(ureq).activate(ureq, subEntries, entry.getTransientState()); segmentView.select(favoriteLink); } } else if("My".equalsIgnoreCase(segment)) { doOpenMyCourses(ureq).activate(ureq, subEntries, entry.getTransientState()); segmentView.select(myCourseLink); } else if(("Catalog".equalsIgnoreCase(segment) || "CatalogEntry".equalsIgnoreCase(segment)) && catalogLink != null) { CatalogNodeController ctrl = doOpenCatalog(ureq); if(ctrl != null) { ctrl.activate(ureq, entries, entry.getTransientState()); segmentView.select(catalogLink); } } else if("Search".equalsIgnoreCase(segment) && searchCourseLink != null) { doOpenSearchCourses(ureq).activate(ureq, subEntries, entry.getTransientState()); segmentView.select(searchCourseLink); } else if("Closed".equalsIgnoreCase(segment) && closedCourseLink != null) { doOpenClosedCourses(ureq).activate(ureq, subEntries, entry.getTransientState()); segmentView.select(closedCourseLink); } else { //default if the others fail doOpenMyCourses(ureq).activate(ureq, subEntries, entry.getTransientState()); segmentView.select(myCourseLink); } } } @Override protected void doDispose() { eventBus.deregisterFor(this, RepositoryService.REPOSITORY_EVENT_ORES); } @Override public void event(Event event) { if(EntryChangedEvent.CHANGE_CMD.equals(event.getCommand()) && event instanceof EntryChangedEvent) { EntryChangedEvent ece = (EntryChangedEvent)event; if(ece.getChange() == Change.addBookmark || ece.getChange() == Change.removeBookmark || ece.getChange() == Change.added || ece.getChange() == Change.deleted) { if(markedCtrl != null && !markedCtrl.getName().equals(ece.getSource())) { favoritDirty = true; } if(myCoursesCtrl != null && !myCoursesCtrl.getName().equals(ece.getSource())) { myDirty = true; } } } } @Override protected void event(UserRequest ureq, Component source, Event event) { if(source == segmentView) { if(event instanceof SegmentViewEvent) { cleanUp(); SegmentViewEvent sve = (SegmentViewEvent)event; String segmentCName = sve.getComponentName(); Component clickedLink = mainVC.getComponent(segmentCName); if (clickedLink == favoriteLink) { doOpenMark(ureq); } else if (clickedLink == myCourseLink) { doOpenMyCourses(ureq); } else if (clickedLink == catalogLink) { doOpenCatalog(ureq); } else if(clickedLink == searchCourseLink) { doOpenSearchCourses(ureq); } else if(clickedLink == closedCourseLink) { doOpenClosedCourses(ureq); } } } } private void cleanUp() { removeAsListenerAndDispose(catalogCtrl); removeAsListenerAndDispose(markedCtrl); removeAsListenerAndDispose(myCoursesCtrl); removeAsListenerAndDispose(searchCoursesCtrl); catalogCtrl = null; markedCtrl = null; myCoursesCtrl = null; searchCoursesCtrl = null; } private RepositoryEntryListController doOpenMark(UserRequest ureq) { cleanUp(); SearchMyRepositoryEntryViewParams searchParams = new SearchMyRepositoryEntryViewParams(getIdentity(), ureq.getUserSession().getRoles()); searchParams.setMarked(Boolean.TRUE); OLATResourceable ores = OresHelper.createOLATResourceableInstance("Favorits", 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); markedStackPanel = new BreadcrumbedStackedPanel("mrkstack", getTranslator(), this); markedCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, "marked", markedStackPanel); markedStackPanel.pushController(translate("search.mark"), markedCtrl); listenTo(markedCtrl); currentCtrl = markedCtrl; favoritDirty = false; addToHistory(ureq, markedCtrl); mainVC.put("segmentCmp", markedStackPanel); return markedCtrl; } private RepositoryEntryListController doOpenMyCourses(UserRequest ureq) { cleanUp(); SearchMyRepositoryEntryViewParams searchParams = new SearchMyRepositoryEntryViewParams(getIdentity(), ureq.getUserSession().getRoles()); searchParams.setMembershipMandatory(true); searchParams.setClosed(Boolean.FALSE); OLATResourceable ores = OresHelper.createOLATResourceableInstance("My", 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); myCoursesStackPanel = new BreadcrumbedStackedPanel("mystack", getTranslator(), this); myCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, "my", myCoursesStackPanel); myCoursesStackPanel.pushController(translate("search.mycourses.student"), myCoursesCtrl); listenTo(myCoursesCtrl); currentCtrl = myCoursesCtrl; myDirty = false; addToHistory(ureq, myCoursesCtrl); mainVC.put("segmentCmp", myCoursesStackPanel); return myCoursesCtrl; } private CatalogNodeController doOpenCatalog(UserRequest ureq) { if(!repositoryModule.isCatalogEnabled() || !repositoryModule.isCatalogBrowsingEnabled()) { return null; } cleanUp(); List<CatalogEntry> entries = catalogManager.getRootCatalogEntries(); CatalogEntry rootEntry = null; if(entries.size() > 0) { rootEntry = entries.get(0); } OLATResourceable ores = OresHelper.createOLATResourceableInstance("Catalog", 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); catalogStackPanel = new BreadcrumbedStackedPanel("catstack", getTranslator(), this); catalogCtrl = new CatalogNodeController(ureq, bwControl, getWindowControl(), rootEntry, catalogStackPanel, false); catalogStackPanel.pushController(translate("search.catalog"), catalogCtrl); listenTo(catalogCtrl); currentCtrl = catalogCtrl; addToHistory(ureq, catalogCtrl); mainVC.put("segmentCmp", catalogStackPanel); return catalogCtrl; } private RepositoryEntryListController doOpenSearchCourses(UserRequest ureq) { cleanUp(); SearchMyRepositoryEntryViewParams searchParams = new SearchMyRepositoryEntryViewParams(getIdentity(), ureq.getUserSession().getRoles()); searchParams.setMembershipMandatory(false); OLATResourceable ores = OresHelper.createOLATResourceableInstance("Search", 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); searchCoursesStackPanel = new BreadcrumbedStackedPanel("search", getTranslator(), this); searchCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, false, true, "my-search", searchCoursesStackPanel); searchCoursesStackPanel.pushController(translate("search.mycourses.student"), searchCoursesCtrl); listenTo(searchCoursesCtrl); currentCtrl = searchCoursesCtrl; addToHistory(ureq, searchCoursesCtrl); mainVC.put("segmentCmp", searchCoursesStackPanel); return searchCoursesCtrl; } private RepositoryEntryListController doOpenClosedCourses(UserRequest ureq) { cleanUp(); SearchMyRepositoryEntryViewParams searchParams = new SearchMyRepositoryEntryViewParams(getIdentity(), ureq.getUserSession().getRoles()); searchParams.setMembershipMandatory(true); searchParams.setClosed(Boolean.TRUE); OLATResourceable ores = OresHelper.createOLATResourceableInstance("Closed", 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); myCoursesStackPanel = new BreadcrumbedStackedPanel("mystack", getTranslator(), this); closedCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, "closed", myCoursesStackPanel); myCoursesStackPanel.pushController(translate("search.mycourses.student"), closedCoursesCtrl); listenTo(closedCoursesCtrl); currentCtrl = closedCoursesCtrl; myDirty = false; addToHistory(ureq, closedCoursesCtrl); mainVC.put("segmentCmp", myCoursesStackPanel); return closedCoursesCtrl; } }