/**
* 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.
* <hr>
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* This file has been modified by the OpenOLAT community. Changes are licensed
* under the Apache 2.0 license as the original file.
*/
package org.olat.portfolio.ui.artefacts.view;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
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.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.CloseableCalloutWindowController;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.portfolio.manager.EPFrontendManager;
import org.olat.portfolio.model.artefacts.AbstractArtefact;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Description:<br>
* TODO:
* - maybe optimize new creation of artefacts controllers by watching which are yet existing and not
* dropping/creating them again
*
* <P>
* Initial Date: 08.07.2010 <br>
*
* @author Roman Haag, roman.haag@frentix.com, frentix GmbH
*/
public class EPMultipleArtefactPreviewController extends BasicController implements EPMultiArtefactsController {
private VelocityContainer vC;
private Link artAttribBtn;
private List<Controller> artefactCtrls;
@Autowired
private EPFrontendManager ePFMgr;
private EPArtefactAttributeSettingController artAttribCtlr;
private Map<String, Boolean> artAttribConfig;
private boolean artefactChooseMode;
private static final int artefactsPerPage = 4;
private List<AbstractArtefact> artefactsFullList;
private CloseableCalloutWindowController artAttribCalloutCtr;
public EPMultipleArtefactPreviewController(UserRequest ureq, WindowControl wControl, List<AbstractArtefact> artefacts) {
this(ureq, wControl, artefacts, false);
}
public EPMultipleArtefactPreviewController(UserRequest ureq, WindowControl wControl, List<AbstractArtefact> artefacts, boolean artefactChooseMode) {
super(ureq, wControl);
this.artefactChooseMode = artefactChooseMode;
vC = createVelocityContainer("multiArtefact");
if (!artefactChooseMode) {
artAttribBtn = LinkFactory.createCustomLink("detail.options", "detail.options", "", Link.BUTTON + Link.NONTRANSLATED, vC, this);
artAttribBtn.setTooltip(translate("detail.options"));
artAttribBtn.setTitle(translate("detail.options"));
artAttribBtn.setIconLeftCSS("o_icon o_icon_customize");
}
setNewArtefactsList(ureq, artefacts);
putInitialPanel(vC);
}
public EPMultipleArtefactPreviewController(UserRequest ureq, WindowControl wControl) {
this(ureq, wControl, null);
}
public void setNewArtefactsList(UserRequest ureq, List<AbstractArtefact> artefacts) {
this.artefactsFullList = artefacts;
if (artefacts != null) {
preparePaging(ureq, 1);
}
}
private void preparePaging(UserRequest ureq, int actualPage){
int nrOfArtefacts = artefactsFullList.size();
vC.contextPut("artefactAmnt", Integer.toString(nrOfArtefacts));
if (nrOfArtefacts > artefactsPerPage){
int divRest = (nrOfArtefacts % artefactsPerPage);
int nrOfPages = (nrOfArtefacts / artefactsPerPage) + (divRest > 0 ? 1 : 0);
ArrayList<Link> pageLinkList = new ArrayList<Link>();
for (int i = 1; i < nrOfPages + 1; i++) {
Link pageLink = LinkFactory.createCustomLink("pageLink" + i, "pageLink" + i, String.valueOf(i), Link.LINK + Link.NONTRANSLATED, vC, this);
pageLink.setUserObject(i);
if (actualPage == i) pageLink.setEnabled(false);
pageLinkList.add(pageLink);
}
int fromIndex = (actualPage-1) * artefactsPerPage;
int toIndex = actualPage * artefactsPerPage;
if (toIndex > nrOfArtefacts) toIndex = nrOfArtefacts;
List<AbstractArtefact> artefactsToShow = artefactsFullList.subList(fromIndex, toIndex);
vC.contextPut("pageLinkList", pageLinkList);
initOrUpdateArtefactControllers(ureq, artefactsToShow);
} else {
// no paging needed
vC.contextRemove("pageLinkList");
initOrUpdateArtefactControllers(ureq, artefactsFullList);
}
}
/**
* @param ureq
* @param wControl
* @param artefacts
*/
private void initOrUpdateArtefactControllers(UserRequest ureq, List<AbstractArtefact> artefacts) {
vC.contextPut("artefacts", artefacts);
if (artefactCtrls != null) disposeArtefactControllers();
artefactCtrls = new ArrayList<Controller>();
ArrayList<Component> artefactCtrlComps = new ArrayList<Component>();
int i = 1;
getArtefactAttributeDisplayConfig(ureq.getIdentity());
if (artefacts != null) {
for (AbstractArtefact abstractArtefact : artefacts) {
Controller artCtrl = new EPArtefactViewController(ureq, getWindowControl(), abstractArtefact, artAttribConfig, artefactChooseMode, false, true);
artefactCtrls.add(artCtrl);
Component artefactCtrlComponent = artCtrl.getInitialComponent();
listenTo(artCtrl);
artefactCtrlComps.add(artefactCtrlComponent);
vC.put("artCtrl" + i, artefactCtrlComponent);
i++;
}
}
vC.contextPut("artefactCtrlComps", artefactCtrlComps);
}
// dispose all artefact controllers
private void disposeArtefactControllers() {
if (artefactCtrls != null){
for (Controller artefactCtrl : artefactCtrls) {
removeAsListenerAndDispose(artefactCtrl);
artefactCtrl = null;
}
artefactCtrls = null;
}
}
/**
* @see org.olat.core.gui.control.DefaultController#doDispose()
*/
@Override
protected void doDispose() {
disposeArtefactControllers();
}
/**
* @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
* org.olat.core.gui.components.Component,
* org.olat.core.gui.control.Event)
*/
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if (source == artAttribBtn) {
if (artAttribCalloutCtr == null){
popupArtAttribBox(ureq);
} else {
// close on second click
closeArtAttribBox();
}
} else if (source instanceof Link) {
Link link = (Link) source;
int pageNum = (Integer) link.getUserObject();
preparePaging(ureq, pageNum);
}
}
/**
* @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
* org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
*/
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
super.event(ureq, source, event);
if (source == artAttribCtlr) {
if (event.equals(Event.DONE_EVENT)) {
closeArtAttribBox();
// set new display config for each artefact controller
vC.setDirty(true);
}
} else if (source instanceof EPArtefactViewController) {
if (event.getCommand().equals(EPArtefactDeletedEvent.ARTEFACT_DELETED)) {
// an artefact has been deleted, so refresh
EPArtefactDeletedEvent epDelEv = (EPArtefactDeletedEvent) event;
// only refresh whats needed, dont load all artefacts!
artefactsFullList.remove(epDelEv.getArtefact());
setNewArtefactsList(ureq, artefactsFullList);
fireEvent(ureq, event); // pass to EPArtefactPoolRunCtrl
}
}
if (event instanceof EPArtefactChoosenEvent) {
// an artefact was choosen, pass through the event until top
fireEvent(ureq, event);
}
if (source == artAttribCalloutCtr && event == CloseableCalloutWindowController.CLOSE_WINDOW_EVENT) {
removeAsListenerAndDispose(artAttribCalloutCtr);
artAttribCalloutCtr = null;
}
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
if(entries == null || entries.isEmpty()) return;
OLATResourceable ores = entries.get(0).getOLATResourceable();
if("AbstractArtefact".equals(ores.getResourceableTypeName())) {
Long resId = ores.getResourceableId();
int index = 0;
for(AbstractArtefact artefact: artefactsFullList) {
if(artefact.getKey().equals(resId) || artefact.getResourceableId().equals(resId)) {
int rest = (index % artefactsPerPage);
int page = (index - rest) / artefactsPerPage;
preparePaging(ureq, page + 1);
break;
}
index++;
}
}
}
private Map<String, Boolean> getArtefactAttributeDisplayConfig(Identity ident) {
if (artAttribConfig == null) {
artAttribConfig = ePFMgr.getArtefactAttributeConfig(ident);
}
return artAttribConfig;
}
/**
* @param ureq
*/
private void popupArtAttribBox(UserRequest ureq) {
String title = translate("display.option.title");
if (artAttribCtlr == null) {
artAttribCtlr = new EPArtefactAttributeSettingController(ureq, getWindowControl(),
getArtefactAttributeDisplayConfig(ureq.getIdentity()));
listenTo(artAttribCtlr);
}
removeAsListenerAndDispose(artAttribCalloutCtr);
artAttribCalloutCtr = new CloseableCalloutWindowController(ureq, getWindowControl(), artAttribCtlr.getInitialComponent(), artAttribBtn, title, true, null);
listenTo(artAttribCalloutCtr);
artAttribCalloutCtr.activate();
}
private void closeArtAttribBox() {
if (artAttribCalloutCtr!= null){
artAttribCalloutCtr.deactivate();
removeAsListenerAndDispose(artAttribCalloutCtr);
artAttribCalloutCtr = null;
}
}
}