/** * 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. * <p> */ package org.olat.core.gui.components.tabbedpane; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.ComponentRenderer; import org.olat.core.gui.components.Container; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.translator.Translator; 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.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; /** * enclosing_type Description: <br> * * @author Felix Jost */ public class TabbedPane extends Container implements Activateable2 { private static final OLog log = Tracing.createLoggerFor(TabbedPane.class); private static final ComponentRenderer RENDERER = new TabbedPaneRenderer(); /** * Comment for <code>PARAM_PANE_ID</code> */ protected static final String PARAM_PANE_ID = "taid"; private int selectedPane = -1; private final List<TabPane> tabPanes = new ArrayList<>(5); private Translator compTrans; /** * @param name */ public TabbedPane(String name, Locale locale) { super(name); compTrans = Util.createPackageTranslator(this.getClass(), locale); setDomReplacementWrapperRequired(false);// we provide our own DOM replacement ID } /** * @see org.olat.core.gui.components.Component#dispatchRequest(org.olat.core.gui.UserRequest) */ @Override protected void doDispatchRequest(UserRequest ureq) { // the taid indicates which tab the user clicked String s_taid = ureq.getParameter(PARAM_PANE_ID); try { int newTaid = Integer.parseInt(s_taid); dispatchRequest(ureq, newTaid); } catch (NumberFormatException e) { log.warn("Not a number: " + s_taid); } } /** * @param ureq * @param newTaid */ private void dispatchRequest(UserRequest ureq, int newTaid) { if (isEnabled(newTaid) && newTaid >= 0 && newTaid < getTabCount()) { Component oldSelComp = getTabAt(selectedPane); setSelectedPane(newTaid); Component newSelComp = getTabAt(selectedPane); fireEvent(ureq, new TabbedPaneChangedEvent(oldSelComp, newSelComp)); } } /** * Sets the selectedPane. * * @param selectedPane The selectedPane to set */ public void setSelectedPane(int newSelectedPane) { // get old selected component and remove it from render tree Component oldSelComp = getTabAt(selectedPane); remove(oldSelComp); // activate new selectedPane = newSelectedPane; Component newSelComp = getTabAt(newSelectedPane); super.put("atp", newSelComp); //setDirty(true); not needed since: line above marks this container automatically dirty } public OLATResourceable getTabResource() { return OresHelper.createOLATResourceableInstance("tab", new Long(selectedPane)); } public void addToHistory(UserRequest ureq, WindowControl wControl) { OLATResourceable ores = getTabResource(); BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, null, wControl, true); } /** * @param displayName * @param component * @return */ public int addTab(String displayName, Component component) { tabPanes.add(new TabPane(displayName, component)); if (selectedPane == -1) { selectedPane = 0; // if no pane has been selected, select the first one super.put("atp", component); } return tabPanes.size() - 1; } public int addTab(String displayName, Controller controller) { TabPane tab = new TabPane(displayName, controller); tabPanes.add(tab); if (selectedPane == -1) { selectedPane = 0; // if no pane has been selected, select the first one super.put("atp", tab.getComponent()); } return tabPanes.size() - 1; } public boolean containsTab(Component component) { boolean found = false; for(int i=tabPanes.size(); i-->0; ) { if(tabPanes.get(i).getComponent() == component) { found = true; } } return found; } public int indexOfTab(Component component) { for(int i=tabPanes.size(); i-->0; ) { if(tabPanes.get(i).getComponent() == component) { return i; } } return -1; } public boolean containsTab(String displayName) { boolean found = false; for(int i=tabPanes.size(); i-->0; ) { if(displayName.equals(tabPanes.get(i).getDisplayName())) { found = true; } } return found; } public int indexOfTab(String displayName) { for(int i=tabPanes.size(); i-->0; ) { if(displayName.equals(tabPanes.get(i).getComponent())) { return i; } } return -1; } public void replaceTab(int pos, Controller controller) { tabPanes.get(pos).setController(controller); if(pos == selectedPane) { super.put("atp", controller.getInitialComponent()); } } public void replaceTab(int pos, Component component) { tabPanes.get(pos).setComponent(component); if(pos == selectedPane) { super.put("atp", component); } } public void removeTab(Component component) { int index = indexOfTab(component); if(index >= 0 && index < tabPanes.size()) { tabPanes.remove(index); if(selectedPane == index) { setSelectedPane(0); } setDirty(true); } } public void removeAll() { if (selectedPane != -1) { Component oldSelComp = getTabAt(selectedPane); remove(oldSelComp); } tabPanes.clear(); selectedPane = -1; setDirty(true); } /** * @param position * @return */ protected Component getTabAt(int position) { return tabPanes.get(position).getComponent(); } /** * @param position * @return */ protected String getDisplayNameAt(int position) { return tabPanes.get(position).getDisplayName(); } /** * @return */ protected int getTabCount() { return (tabPanes == null ? 0 : tabPanes.size()); } /** * Returns the selectedPane. * * @return int */ public int getSelectedPane() { return selectedPane; } /** * Return the selected controller only if you used * the addTab with a controller as parameter! * * @return */ public Controller getSelectedController() { int index = getSelectedPane(); if(index >= 0 && index < this.tabPanes.size()) { return tabPanes.get(index).getController(); } return null; } /** * @deprecated * @param displayName */ public void setSelectedPane(String displayName) { if (displayName == null) return; int pos = indexOfTab(displayName); if (pos > -1) { setSelectedPane(pos); } } /** * @see org.olat.core.gui.components.Component#getExtendedDebugInfo() */ @Override public String getExtendedDebugInfo() { return "selectedPane:" + selectedPane; } /** * @param pane * @param enabled */ public void setEnabled(int pane, boolean enabled) { boolean wasEnabled = isEnabled(pane); if (wasEnabled != enabled) { setDirty(true); } tabPanes.get(pane).setEnabled(enabled); setDirty(true); } /** * @param pane * @return */ protected boolean isEnabled(int pane) { return tabPanes.get(pane).isEnabled(); } @Override public ComponentRenderer getHTMLRendererSingleton() { return RENDERER; } protected Translator getCompTrans() { return compTrans; } @Override public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { if(entries == null || entries.isEmpty()) return; OLATResourceable ores = entries.get(0).getOLATResourceable(); if("tab".equals(ores.getResourceableTypeName())) { int pos = ores.getResourceableId().intValue(); if(pos != selectedPane && pos >= 0 && pos < getTabCount()) { dispatchRequest(ureq, pos); } } } private static class TabPane { private boolean enabled = true; private final String displayName; private Component component; private Controller controller; public TabPane(String displayName, Component component) { this.displayName = displayName; this.component = component; this.enabled = true; } public TabPane(String displayName, Controller controller) { this.displayName = displayName; this.controller = controller; this.component = controller.getInitialComponent(); this.enabled = true; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public String getDisplayName() { return displayName; } public Controller getController() { return controller; } public void setController(Controller controller) { if(controller == null) { controller = null; component = null; } else { this.controller = controller; this.component = controller.getInitialComponent(); } } public Component getComponent() { return component; } public void setComponent(Component component) { this.component = component; } } }