/** * <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.portfolio.ui.artefacts.view; import java.util.ArrayList; import java.util.BitSet; import java.util.List; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.EscapeMode; import org.olat.core.gui.components.table.ColumnDescriptor; import org.olat.core.gui.components.table.CustomRenderColumnDescriptor; import org.olat.core.gui.components.table.DefaultColumnDescriptor; import org.olat.core.gui.components.table.StaticColumnDescriptor; import org.olat.core.gui.components.table.TableController; import org.olat.core.gui.components.table.TableEvent; import org.olat.core.gui.components.table.TableGuiConfiguration; import org.olat.core.gui.components.table.TableMultiSelectEvent; 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.Translator; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.core.util.StringHelper; import org.olat.portfolio.EPArtefactHandler; import org.olat.portfolio.EPSecurityCallback; import org.olat.portfolio.EPUIFactory; import org.olat.portfolio.PortfolioModule; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; import org.olat.portfolio.model.structel.PortfolioStructure; import org.olat.portfolio.model.structel.PortfolioStructureMap; import org.olat.portfolio.model.structel.StructureStatusEnum; import org.olat.portfolio.ui.artefacts.collect.EPCollectStepForm04; import org.olat.portfolio.ui.artefacts.edit.EPReflexionWrapperController; import org.olat.portfolio.ui.filter.PortfolioFilterController; import org.olat.portfolio.ui.structel.EPStructureChangeEvent; /** * Description:<br> * Controller to hold a table representation of artefacts * - used with a struct (inside a map) it allows to unlink artefact * - in chooseMode there is column to add artefact to struct * * <P> * Initial Date: 20.08.2010 <br> * @author Roman Haag, roman.haag@frentix.com, http://www.frentix.com */ public class EPMultipleArtefactsAsTableController extends BasicController implements EPMultiArtefactsController { private static final String CMD_CHOOSE = "choose"; private static final String CMD_UNLINK = "unlink"; private static final String CMD_REFLEXION = "refl"; private static final String CMD_DELETEARTEFACT = "delartf"; private static final String CMD_TITLE = "title"; private static final String CMD_MOVE = "move"; private VelocityContainer vC; private TableController artefactListTblCtrl; private CloseableModalController artefactBox; private PortfolioStructure struct; private EPFrontendManager ePFMgr; private boolean mapClosed = false; private boolean multiSelect = false; private boolean artefactChooseMode; private EPSecurityCallback secCallback; private PortfolioModule portfolioModule; private DialogBoxController deleteDialogController; private EPCollectStepForm04 moveTreeCtrl; private CloseableModalController moveTreeBox; public EPMultipleArtefactsAsTableController(UserRequest ureq, WindowControl wControl, List<AbstractArtefact> artefacts, PortfolioStructure struct, boolean artefactChooseMode, boolean multiSelect, EPSecurityCallback secCallback) { super(ureq, wControl); this.multiSelect = multiSelect; this.secCallback = secCallback; this.artefactChooseMode = artefactChooseMode; vC = createVelocityContainer("multiArtefactTable"); this.struct = struct; if(struct != null && struct.getRoot() instanceof PortfolioStructureMap) { mapClosed = StructureStatusEnum.CLOSED.equals(((PortfolioStructureMap)struct.getRoot()).getStatus()); } else { mapClosed = false; } portfolioModule = (PortfolioModule)CoreSpringFactory.getBean("portfolioModule"); ePFMgr = (EPFrontendManager) CoreSpringFactory.getBean("epFrontendManager"); if (artefacts!=null){ initOrUpdateTable(ureq, artefacts); } putInitialPanel(vC); } private void initOrUpdateTable(UserRequest ureq, List<AbstractArtefact> artefacts) { ArtefactTableDataModel artefactListModel = new ArtefactTableDataModel(artefacts); artefactListModel.setLocale(getLocale()); TableGuiConfiguration tableGuiConfiguration = new TableGuiConfiguration(); tableGuiConfiguration.setTableEmptyMessage(getTranslator().translate("table.empty")); tableGuiConfiguration.setPageingEnabled(true); tableGuiConfiguration.setDownloadOffered(struct == null); // offer download only when in artefact pool (no struct given) tableGuiConfiguration.setResultsPerPage(10); tableGuiConfiguration.setPreferencesOffered(true, "artefacts.as.table.prefs"); artefactListTblCtrl = new TableController(tableGuiConfiguration, ureq, getWindowControl(), getTranslator()); if(multiSelect) { artefactListTblCtrl.setMultiSelect(true); artefactListTblCtrl.addMultiSelectAction("select", "select"); } listenTo(artefactListTblCtrl); String details = artefactChooseMode ? null : CMD_TITLE; DefaultColumnDescriptor descr = new DefaultColumnDescriptor("artefact.title", 0, details, getLocale()); artefactListTblCtrl.addColumnDescriptor(descr); descr = new DefaultColumnDescriptor("artefact.description", 1, null, getLocale()); descr.setEscapeHtml(EscapeMode.antisamy); artefactListTblCtrl.addColumnDescriptor(true, descr); descr = new DefaultColumnDescriptor("artefact.date", 2, null, getLocale()); artefactListTblCtrl.addColumnDescriptor(true, descr); descr = new DefaultColumnDescriptor("artefact.author", 3, null, getLocale()); artefactListTblCtrl.addColumnDescriptor(false, descr); descr = new DefaultColumnDescriptor("artefact.tags", 4, null, getLocale()); artefactListTblCtrl.addColumnDescriptor(false, descr); descr = new CustomRenderColumnDescriptor("table.header.type", 5, null, ureq.getLocale(), ColumnDescriptor.ALIGNMENT_CENTER, new ArtefactTypeImageCellRenderer(getLocale())){ /** * @see org.olat.core.gui.components.table.DefaultColumnDescriptor#compareTo(int, int) */ @Override public int compareTo(int rowa, int rowb) { Object a = table.getTableDataModel().getValueAt(rowa,dataColumn); Object b = table.getTableDataModel().getValueAt(rowb,dataColumn); String typeA = getArtefactTranslatedTypeName((AbstractArtefact)a); String typeB = getArtefactTranslatedTypeName((AbstractArtefact)b); return typeA.compareTo(typeB); } }; artefactListTblCtrl.addColumnDescriptor(false, descr); StaticColumnDescriptor staticDescr; if(!artefactChooseMode) { if(mapClosed || !secCallback.canEditReflexion()) { // change link-description in row, when map is closed or viewed by another person staticDescr = new StaticColumnDescriptor(CMD_REFLEXION, "table.header.reflexion", translate("table.header.view")); } else { staticDescr = new StaticColumnDescriptor(CMD_REFLEXION, "table.header.reflexion", translate("table.row.reflexion")); } artefactListTblCtrl.addColumnDescriptor(true, staticDescr); } if(struct == null){ staticDescr = new StaticColumnDescriptor(CMD_DELETEARTEFACT, "delete.artefact", translate("delete.artefact")); artefactListTblCtrl.addColumnDescriptor(true,staticDescr); } if (artefactChooseMode) { staticDescr = new StaticColumnDescriptor(CMD_CHOOSE, "table.header.choose", translate("choose.artefact")); artefactListTblCtrl.addColumnDescriptor(true, staticDescr); } if(struct!=null && secCallback.canRemoveArtefactFromStruct()){ staticDescr = new StaticColumnDescriptor(CMD_UNLINK, "table.header.unlink", translate("remove.from.map")); artefactListTblCtrl.addColumnDescriptor(true, staticDescr); } if(struct!=null && secCallback.canRemoveArtefactFromStruct() && secCallback.canAddArtefact()){ staticDescr = new StaticColumnDescriptor(CMD_MOVE, "table.header.move", translate("artefact.options.move")); artefactListTblCtrl.addColumnDescriptor(true, staticDescr); } artefactListTblCtrl.setTableDataModel(artefactListModel); if (vC.getComponent("artefactTable")!=null) vC.remove(artefactListTblCtrl.getInitialComponent()); vC.put("artefactTable", artefactListTblCtrl.getInitialComponent()); } // translate the type of artefact needed for sorting by type String getArtefactTranslatedTypeName(AbstractArtefact artefact){ EPArtefactHandler<?> artHandler = portfolioModule.getArtefactHandler(artefact.getResourceableTypeName()); Translator handlerTrans = artHandler.getHandlerTranslator(getTranslator()); String handlerClass = PortfolioFilterController.HANDLER_PREFIX + artHandler.getClass().getSimpleName() + PortfolioFilterController.HANDLER_TITLE_SUFFIX; String artType = handlerTrans.translate(handlerClass); return artType; } /** * @see org.olat.core.gui.control.DefaultController#doDispose() */ @Override protected void doDispose() { //nothing to dispose } /** * @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) { // } @Override protected void event(UserRequest ureq, Controller source, Event event) { if(source == artefactListTblCtrl) { if(event instanceof TableEvent) { TableEvent te = (TableEvent)event; AbstractArtefact artefact = (AbstractArtefact)artefactListTblCtrl.getTableDataModel().getObject(te.getRowId()); String action = te.getActionId(); if(CMD_TITLE.equals(action)) { popupArtefact(artefact, ureq); } else if (CMD_REFLEXION.equals(action)){ EPReflexionWrapperController reflexionCtrl = new EPReflexionWrapperController(ureq, getWindowControl(), secCallback, artefact, struct); listenTo(reflexionCtrl); } else if (CMD_CHOOSE.equals(action)){ fireEvent(ureq, new EPArtefactChoosenEvent(artefact)); } else if (CMD_UNLINK.equals(action)){ struct = ePFMgr.reloadPortfolioStructure(struct); ePFMgr.removeArtefactFromStructure(artefact, struct); artefactListTblCtrl.modelChanged(); fireEvent(ureq, new EPStructureChangeEvent(EPStructureChangeEvent.ADDED, struct)); } else if (CMD_MOVE.equals(action)){ showMoveTree(ureq, artefact); } else if (CMD_DELETEARTEFACT.equals(action)) { String text = translate("delete.artefact.text", StringHelper.escapeHtml(artefact.getTitle())); deleteDialogController = activateYesNoDialog(ureq, translate("delete.artefact"), text, deleteDialogController); deleteDialogController.setUserObject(artefact); } } else if(event instanceof TableMultiSelectEvent) { TableMultiSelectEvent tmse = (TableMultiSelectEvent)event; BitSet objectMarkers = tmse.getSelection(); List<AbstractArtefact> selectedArtefacts = new ArrayList<>(objectMarkers.size()); for(int i=objectMarkers.nextSetBit(0); i >= 0; i=objectMarkers.nextSetBit(i+1)) { AbstractArtefact entry = (AbstractArtefact)artefactListTblCtrl.getTableDataModel().getObject(i); selectedArtefacts.add(entry); } fireEvent(ureq, new EPArtefactListChoosenEvent(selectedArtefacts)); } } else if (source == moveTreeCtrl && event.getCommand().equals(EPStructureChangeEvent.CHANGED)){ EPStructureChangeEvent epsEv = (EPStructureChangeEvent) event; PortfolioStructure newStruct = epsEv.getPortfolioStructure(); showInfo("artefact.moved", newStruct.getTitle()); fireEvent(ureq, event); moveTreeBox.deactivate(); } else if(source == deleteDialogController){ if (DialogBoxUIFactory.isYesEvent(event)) { AbstractArtefact artefact2delete = (AbstractArtefact)deleteDialogController.getUserObject(); ePFMgr.deleteArtefact(artefact2delete); ArtefactTableDataModel model = (ArtefactTableDataModel) artefactListTblCtrl.getTableDataModel(); model.getObjects().remove(artefact2delete); artefactListTblCtrl.modelChanged(); fireEvent(ureq, new EPStructureChangeEvent(EPStructureChangeEvent.REMOVED, struct)); } removeAsListenerAndDispose(deleteDialogController); deleteDialogController = null; } super.event(ureq, source, event); } @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(); ArtefactTableDataModel model = (ArtefactTableDataModel) artefactListTblCtrl.getTableDataModel(); for(int i=0; i< model.getRowCount(); i++) { AbstractArtefact artefact = model.getObject(i); if(artefact.getKey().equals(resId)) { int artefactsPerPage = artefactListTblCtrl.getPageSize(); int rest = (i % artefactsPerPage); int page = (i - rest) / artefactsPerPage; artefactListTblCtrl.setPage(new Integer(page + 1)); break; } } } } private void showMoveTree(UserRequest ureq, AbstractArtefact artefact){ moveTreeCtrl = new EPCollectStepForm04(ureq, getWindowControl(), artefact, struct); listenTo(moveTreeCtrl); String title = translate("artefact.move.title"); moveTreeBox = new CloseableModalController(getWindowControl(), title, moveTreeCtrl.getInitialComponent()); listenTo(moveTreeBox); //moveTreeBox.setInitialWindowSize(450, 300); moveTreeBox.activate(); } protected void popupArtefact(AbstractArtefact artefact, UserRequest ureq) { String title = translate("view.artefact.header"); artefactBox = EPUIFactory.getAndActivatePopupArtefactController(artefact, ureq, getWindowControl(), title); listenTo(artefactBox); } @Override public void setNewArtefactsList(UserRequest ureq, List<AbstractArtefact> artefacts) { initOrUpdateTable(ureq, artefacts); } }