/** * 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.view.toc.actions.cui.legend; import javax.swing.JTree; import javax.swing.event.TreeModelEvent; import javax.swing.tree.TreePath; import org.orbisgis.sif.components.resourceTree.AbstractTreeModel; import org.orbisgis.view.toc.wrapper.RuleWrapper; import org.orbisgis.view.toc.wrapper.StyleWrapper; /** * This tree model is used in the legend edition panel. Its depth is only 2 : * <ul> * <li>Level 0 (root) : the Style we are editing.</li> * <li>Level 1 : the Rules</li> * <li>Level 2 : the Legends</li> * </ul> * @author Alexis Guéganno */ public class LegendTreeModel extends AbstractTreeModel { private StyleWrapper root; public LegendTreeModel(JTree tree, StyleWrapper r){ super(tree); root = r; } public void refresh(){ //This is way too violent : it would be faster to create a //dedicated event for each change ! fireEvent(); } @Override public Object getRoot() { return root; } @Override public Object getChild(Object parent, int index) { if(parent instanceof StyleWrapper){ return getChild((StyleWrapper) parent, index); } else if(parent instanceof RuleWrapper){ return getChild((RuleWrapper)parent, index); } return null; } @Override public int getChildCount(Object parent) { if(parent instanceof StyleWrapper){ return ((StyleWrapper)parent).getSize(); } else if(parent instanceof RuleWrapper){ return ((RuleWrapper) parent).getSize(); } else { return -1; } } @Override public boolean isLeaf(Object node) { return node instanceof ILegendPanel; } @Override public void valueForPathChanged(TreePath path, Object newValue) { } @Override public int getIndexOfChild(Object parent, Object child) { if(parent instanceof StyleWrapper && child instanceof RuleWrapper){ return getIndexOfChild((StyleWrapper) parent, (RuleWrapper) child); } else if(parent instanceof RuleWrapper && child instanceof ILegendPanel){ return getIndexOfChild((RuleWrapper) parent, (ILegendPanel) child); } else { return -1; } } /** * Add {@code newElt} in {@code parent}. * @param parent * @param newElt * The object to be inserted. If {@code parent} is a {@code * StyleWrapper}, must be a {@code RuleWrapper}. If {@code parent} * is a {@code RuleWrapper}, must be a {@code Legend}. * @param current * The object after which we will inser newElt, if possible. As it * will be searched for in parent, it must be of the same type as * newElt. */ public void addElement(Object parent, Object newElt, Object current){ if(parent instanceof RuleWrapper && newElt instanceof ILegendPanel){ if(current instanceof ILegendPanel){ addElement((RuleWrapper) parent, (ILegendPanel) newElt, (ILegendPanel) current); } else { addElement((RuleWrapper) parent, (ILegendPanel) newElt, null); } } else if(parent instanceof StyleWrapper && newElt instanceof RuleWrapper){ if(current instanceof RuleWrapper){ addElement((RuleWrapper) newElt, (RuleWrapper) current); } else { addElement((RuleWrapper) newElt, null); } } } /** * Remove {@code oldElt} from {@code parent}. * @param parent * @param oldElt * The object to be removed. If {@code parent} is a {@code * StyleWrapper}, must be a {@code RuleWrapper}. If {@code parent} * is a {@code RuleWrapper}, must be a {@code Legend}. */ public void removeElement(Object parent, Object oldElt){ if(parent instanceof RuleWrapper && oldElt instanceof ILegendPanel){ removeElement((RuleWrapper) parent, (ILegendPanel) oldElt); } else if(parent instanceof StyleWrapper && oldElt instanceof RuleWrapper){ removeElement((RuleWrapper) oldElt); } } private void removeElement(RuleWrapper rw, ILegendPanel old){ int pos = rw.indexOf(old); if(pos >=0){ rw.remove(old); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root, rw}, new int[]{pos}, new Object[]{old}); fireNodeRemoved(tme); } } private void removeElement(RuleWrapper rw){ int pos = root.indexOf(rw); if(pos >=0){ root.remove(rw); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root}, new int[]{pos}, new Object[]{rw}); fireNodeRemoved(tme); } } /** * Move {@code elt} down in {@code parent}. If {@code elt} is a legend, * it is moved in the underlying RuleWrapper. If it is a RuleWrapper, it * is moved in the underlying StyleWrapper. * @param parent * @param elt * The element we want to move down. If {@code parent} is a {@code * StyleWrapper}, must be a {@code RuleWrapper}. If {@code parent} * is a {@code RuleWrapper}, must be a {@code Legend}. */ public void moveElementDown(Object parent, Object elt){ if(parent instanceof RuleWrapper && elt instanceof ILegendPanel){ moveElementDown((RuleWrapper) parent, (ILegendPanel) elt); } else if(parent instanceof StyleWrapper && elt instanceof RuleWrapper){ moveElementDown((RuleWrapper) elt); } } /** * Move {@code elt} up in {@code parent}. If {@code elt} is a legend, * it is moved in the underlying RuleWrapper. If it is a RuleWrapper, it * is moved in the underlying StyleWrapper. * @param parent * @param elt * The element we want to move up. If {@code parent} is a {@code * StyleWrapper}, must be a {@code RuleWrapper}. If {@code parent} * is a {@code RuleWrapper}, must be a {@code Legend}. */ public void moveElementUp(Object parent, Object elt){ if(parent instanceof RuleWrapper && elt instanceof ILegendPanel){ moveElementUp((RuleWrapper) parent, (ILegendPanel) elt); } else if(parent instanceof StyleWrapper && elt instanceof RuleWrapper){ moveElementUp((RuleWrapper) elt); } } /** * Checks that there is at least one {@code Legend} under this {@code * TreeModel}. * @return */ public boolean hasLegend(){ return root.hasLegend(); } private void addElement(RuleWrapper newElt, RuleWrapper current){ int pos; if(current == null){ pos = root.getSize(); } else { pos = root.indexOf(current)+1; pos = pos == -1 ? root.getSize() : pos; } root.addRuleWrapper(pos, newElt); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root}, new int[]{pos}, new Object[]{newElt}); fireNodeInserted(tme); } private void addElement(RuleWrapper parent, ILegendPanel newElt, ILegendPanel current){ int pos; if(current == null){ pos = parent.getSize(); } else { pos = parent.indexOf(current)+1; pos = pos == -1 ? parent.getSize() : pos; } parent.addLegend(pos, newElt); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root,parent}, new int[]{pos}, new Object[]{newElt}); fireNodeInserted(tme); } /** * Manage element moves for legend nodes * @param rw * @param l */ private void moveElementDown(RuleWrapper rw, ILegendPanel l){ int i = rw.indexOf(l); rw.moveLegendDown(i); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root,rw}); fireStructureChanged(tme); } /** * Manage element moves for RuleWrapper nodes. * @param rw */ private void moveElementDown(RuleWrapper rw){ int i = getIndexOfChild(root, rw); root.moveRuleWrapperDown(i); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root}); fireStructureChanged(tme); } private void moveElementUp(RuleWrapper rw, ILegendPanel l){ int i = rw.indexOf(l); rw.moveLegendUp(i); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root,rw}); fireStructureChanged(tme); } private void moveElementUp(RuleWrapper rw) { int i = getIndexOfChild(root, rw); root.moveRuleWrapperUp(i); TreeModelEvent tme = new TreeModelEvent( this, new Object[]{root}); fireStructureChanged(tme); } private RuleWrapper getChild(StyleWrapper s, int i){ if(i>=0 && i < s.getSize()){ return s.getRuleWrapper(i); } return null; } private ILegendPanel getChild(RuleWrapper r, int i){ if(i>=0 && i<r.getSize()){ return r.getLegend(i); } return null; } private int getIndexOfChild(StyleWrapper sw, RuleWrapper rw){ return sw.indexOf(rw); } private int getIndexOfChild(RuleWrapper rw, ILegendPanel leg){ return rw.indexOf(leg); } }