001/*
002 * Copyright (c) 2012 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2012-08-30 18:51:48 +0000 (Thu, 30 Aug 2012) $' 
007 * '$Revision: 30577 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029package org.kepler.gui;
030
031import java.util.HashMap;
032import java.util.Map;
033
034import javax.swing.tree.DefaultMutableTreeNode;
035import javax.swing.tree.TreeNode;
036
037import ptolemy.kernel.CompositeEntity;
038import ptolemy.kernel.util.NamedObj;
039
040/** A tree model that can display a subset of a workflow. Use addToSubset()
041 *  to select which NamedObjs are in the tree, and then call showSubset()
042 *  to activate.
043 * 
044 *  @author Daniel Crawl
045 *  @version $Id: SubsetWorkflowOutlineTreeModel.java 30577 2012-08-30 18:51:48Z crawl $
046 */
047public class SubsetWorkflowOutlineTreeModel extends WorkflowOutlineTreeModel {
048
049    /** Create a new SubsetWorkflowOutlineTreeModel with the specified root. */
050    public SubsetWorkflowOutlineTreeModel(CompositeEntity root) {
051        super(root);
052    }
053
054    /** Add an object to the subset tree. NOTE: the subset tree is
055     *  not activated until showSubset() is called.
056     */
057    public void addToSubset(NamedObj namedObj) {
058
059        DefaultMutableTreeNode node = new DefaultMutableTreeNode(namedObj);
060        _nodeMap.put(namedObj, node);
061        
062        NamedObj parentNamedObj = namedObj.getContainer();
063        while(parentNamedObj != null) {
064            
065            // see if container is already in tree
066            boolean parentInTree = true;
067            DefaultMutableTreeNode parentNode = _nodeMap.get(parentNamedObj);
068            if(parentNode == null) {
069                parentNode = new DefaultMutableTreeNode(parentNamedObj);
070                _nodeMap.put(parentNamedObj, parentNode);
071                parentInTree = false;
072            }
073            
074            // set parent/child relationships
075            parentNode.insert(node, parentNode.getChildCount());
076            //System.out.println(parentNamedObj.getFullName() + " --> " + namedObj.getFullName());
077            
078            if(parentInTree) {
079                break;
080            }
081            parentNamedObj = parentNamedObj.getContainer();
082            node = parentNode;
083        }
084    }
085
086    /** Get the child of the given parent at the given index. If the child does
087     *  not exist, then return null.
088     */
089    @Override
090    public Object getChild(Object parent, int index) {
091        
092        if(!_showSubset) {
093            return super.getChild(parent, index);
094        }
095        
096        TreeNode node = _nodeMap.get(parent);
097        if(node == null) {
098            return null;
099        }
100        //System.out.println(((NamedObj) parent).getFullName() + " child " + index + " is " +
101                //((DefaultMutableTreeNode) node.getChildAt(index)).getUserObject());
102        return ((DefaultMutableTreeNode) node.getChildAt(index)).getUserObject();
103    }
104
105    /** Returns the number of children of the given parent. */ 
106    @Override
107    public int getChildCount(Object parent) {
108        
109        if(!_showSubset) {
110            return super.getChildCount(parent);     
111        }
112        
113        TreeNode node = _nodeMap.get(parent);
114        if(node == null) {
115            return 0;
116        }
117        //System.out.println("child count " + ((NamedObj) parent).getFullName() + " is " + node.getChildCount());
118        return node.getChildCount();
119    }
120    
121    /** Return the index of the given child within the given parent. If the
122     *  parent is not contained in the child, return -1.
123     */
124    @Override
125    public int getIndexOfChild(Object parent, Object child) {
126        
127        if(!_showSubset) {
128            super.getIndexOfChild(parent, child);
129        }
130        
131        TreeNode parentNode = _nodeMap.get(parent);
132        TreeNode childNode = _nodeMap.get(child);
133        if(parentNode == null || childNode == null) {
134            return -1;
135        }
136        return parentNode.getIndex(childNode);
137    }
138
139    /** Returns true if the object is a leaf node. */
140    @Override
141    public boolean isLeaf(Object object) {
142
143        if(!_showSubset) {
144            return super.isLeaf(object);
145        }
146        
147        TreeNode node = _nodeMap.get(object);
148        if(node == null) {
149            return true;
150        }
151        return node.isLeaf();
152    }
153
154    /** Show everything in the tree. */
155    public void showAll() {
156        _nodeMap.clear();
157        _showSubset = false;
158    }
159    
160    /** Show only the nodes containing objects that were called with addToSubset().
161     *  Do not call this method until everything to be displayed has been added
162     *  with addToSubset().
163     */
164    public void showSubset() {
165        _showSubset = true;
166    }    
167    
168    /** A mapping from user object (NamedObj) to a tree node. */
169    private Map<Object,DefaultMutableTreeNode> _nodeMap = new HashMap<Object,DefaultMutableTreeNode>();
170    
171    /** If true, show the subset tree. */
172    private boolean _showSubset = false;
173}