/** * OrbisGIS is a java GIS application dedicated to research in GIScience. * OrbisGIS is developed by the GIS group of the DECIDE team of the * Lab-STICC CNRS laboratory, see <http://www.lab-sticc.fr/>. * * The GIS group of the DECIDE team is located at : * * Laboratoire Lab-STICC – CNRS UMR 6285 * Equipe DECIDE * UNIVERSITÉ DE BRETAGNE-SUD * Institut Universitaire de Technologie de Vannes * 8, Rue Montaigne - BP 561 56017 Vannes Cedex * * OrbisGIS is distributed under GPL 3 license. * * Copyright (C) 2007-2014 CNRS (IRSTV FR CNRS 2488) * Copyright (C) 2015-2017 CNRS (Lab-STICC UMR CNRS 6285) * * This file is part of OrbisGIS. * * OrbisGIS is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * OrbisGIS is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * OrbisGIS. If not, see <http://www.gnu.org/licenses/>. * * For more information, please consult: <http://www.orbisgis.org/> * or contact directly: * info_at_ orbisgis.org */ package org.orbisgis.docking.impl.internals.actions; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.Action; import bibliothek.gui.dock.common.action.CAction; import bibliothek.gui.dock.common.action.CDropDownButton; import bibliothek.gui.dock.common.action.CMenu; import bibliothek.gui.dock.common.action.CRadioButton; import bibliothek.gui.dock.common.action.CRadioGroup; import bibliothek.gui.dock.common.action.CSeparator; import org.orbisgis.sif.components.actions.ActionCommands; import org.orbisgis.sif.components.actions.ActionTools; import java.util.Map.Entry; /** * Manage DockingFrames CActions, converted from Swing Actions. */ public class ToolBarActions { // Root actions private List<CAction> customActions = new ArrayList<CAction>(); /** * * @return The CAction created during the execution of convertToolBarToActions */ public List<CAction> getCustomActions() { return customActions; } /** * Docking Frames doesn't provide the "Container" interface, * this method help to add item into multiple CAction container * @param container * @param item */ private boolean addSubItem(CAction container,CAction item) { if(container instanceof CDropDownButton) { ((CDropDownButton)container).add(item); }else if(container instanceof CMenu) { ((CMenu)container).add(item); }else{ return false; } return true; } private Action getAction(CAction action) { if(action instanceof CActionHolder) { return ((CActionHolder)action).getAction(); } else { return null; } } /** * Find the most appropriate action insertion index. * This is sorting by insertion. But it doesn't guaranty to solve complex order issues. * @param actionList CAction containers * @param newAction Action to insert * @return Advised insertion id [0-actionList.getSize()] */ private int getInsertionPosition(List<CAction> actionList, Action newAction) { if(ActionTools.isFirstInsertion(newAction)) { return 0; } for(int i=0;i<actionList.size();i++) { Action compAction = getAction(actionList.get(i)); if(compAction!=null) { int position = ActionCommands.getInsertionPosition(i, newAction, compAction); if(position!=-1) { return position; } } } return actionList.size(); } /** * Get the logical group of action (two different logical group are separated with separation bar) * @param action Common Action * @return Empty string if none, else logicial action group. */ private String getActionLogicalGroup(CAction action) { if(action instanceof CActionHolder) { return ActionTools.getLogicalGroup(((CActionHolder)action).getAction()); } else { return ""; } } /** * Convert swing Action to DockingFrame buttons. * @param actions Actions to convert */ public void setActions(List<Action> actions) { customActions.clear(); // Action containers Map<String,CAction> menuActions = new HashMap<String, CAction>(); // Radio groups Map<String,CRadioGroup> actionGroup = new HashMap<String, CRadioGroup>(); // At the time of writing there is no way to retrieve CAction container items // Then an intermediate list must be create in order to sort sub items. Map<String,ArrayList<CAction>> tempCActionContainer = new HashMap<String, ArrayList<CAction>>(); // Create menu item container for(Action action : actions) { if(ActionTools.isMenu(action)) { String parentId = ActionTools.getParentMenuId(action); if(parentId.isEmpty()) { menuActions.put(ActionTools.getMenuId(action), new CDropDownButtonExt(action)); } else { menuActions.put(ActionTools.getMenuId(action), new CMenuExt(action)); } } } // Create menu item and put in containers for(Action action : actions) { // Retrieve Parent CAction String parentId = ActionTools.getParentMenuId(action); // Create menu item CAction cAction=null; if(ActionTools.isMenu(action)) { cAction = menuActions.get(ActionTools.getMenuId(action)); } else { String toggleGroup = ActionTools.getToggleGroup(action); if(toggleGroup.isEmpty()) { //Standard button, // if it has no parent, the button is not created if it has no icons if(!parentId.isEmpty() || ActionTools.getIcon(action)!=null) { cAction = new CButtonExt(action); } } else { CRadioButton cRadioButton = new CToggleButton(action); // Get CRadioGroup CRadioGroup radioGroup = actionGroup.get(toggleGroup); if(radioGroup==null) { radioGroup = new CRadioGroup(); actionGroup.put(toggleGroup,radioGroup); } radioGroup.add(cRadioButton); cAction = cRadioButton; } } if(cAction!=null) { // Insert the created CAction in a temporary container ArrayList<CAction> actionList = tempCActionContainer.get(parentId); if(actionList==null) { actionList = new ArrayList<CAction>(); tempCActionContainer.put(parentId,actionList); } int insertPosition = getInsertionPosition(actionList, action); String currentAG = ActionTools.getLogicalGroup(action); if(insertPosition>0) { CAction beforeA = actionList.get(insertPosition-1); String beforeAG = getActionLogicalGroup(beforeA); if(!beforeAG.equals(currentAG) && !(beforeA instanceof CSeparator)) { actionList.add(insertPosition,CSeparator.SEPARATOR); insertPosition++; } } if(insertPosition<actionList.size()) { CAction afterA = actionList.get(insertPosition); String afterAG = getActionLogicalGroup(afterA); if(!afterAG.equals(currentAG) && !(afterA instanceof CSeparator)) { actionList.add(insertPosition,CSeparator.SEPARATOR); } } actionList.add(insertPosition,cAction); } } // Insert CAction in each containers for(Entry<String,ArrayList<CAction>> entry : tempCActionContainer.entrySet()) { // Retrieve Parent CAction CAction parentAction=null; if(!entry.getKey().isEmpty()) { parentAction = menuActions.get(entry.getKey()); } for(CAction cAction :entry.getValue()) { // Put CAction in root or action container. if(parentAction!=null) { // Sub CAction addSubItem(parentAction,cAction); } else { // Root items customActions.add(cAction); } } } } }