001/* 002 * Copyright (c) 1998-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2012-08-30 21:33:16 +0000 (Thu, 30 Aug 2012) $' 007 * '$Revision: 30578 $' 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 */ 029 030package org.kepler.gui; 031 032import java.awt.BorderLayout; 033import java.awt.Dimension; 034import java.awt.event.ActionEvent; 035import java.awt.event.ActionListener; 036import java.awt.event.MouseListener; 037 038import javax.swing.JCheckBox; 039import javax.swing.JPanel; 040import javax.swing.JScrollPane; 041import javax.swing.ScrollPaneConstants; 042import javax.swing.SwingUtilities; 043 044import org.apache.commons.logging.Log; 045import org.apache.commons.logging.LogFactory; 046import org.kepler.gui.popups.OutlinePopupListener; 047import org.kepler.util.StaticResources; 048 049import ptolemy.kernel.CompositeEntity; 050import ptolemy.kernel.util.NamedObj; 051import ptolemy.moml.MoMLChangeRequest; 052 053public class WorkflowOutlinePanel extends JPanel { 054 private static final Log log = LogFactory 055 .getLog(WorkflowOutlinePanel.class.getName()); 056 private static final boolean isDebugging = log.isDebugEnabled(); 057 058 private SubsetWorkflowOutlineTreeModel wotm; 059 060 private JCheckBox togglePorts; 061 private JCheckBox toggleRelations; 062 private JCheckBox toggleAttributes; 063 064 private boolean includeAttributeCheckBox = false; 065 private boolean includePortsCheckBox = false; 066 private boolean includeRelationsCheckBox = false; 067 private MouseListener _mouseListener; 068 069 private AnnotatedPTree _ptree; 070 071 private String _searchTerm; 072 073 public WorkflowOutlinePanel(CompositeEntity entity, 074 boolean includeAttributeCheckBox, boolean includePortsCheckBox, 075 boolean includeRelationsCheckBox) { 076 077 this.includeAttributeCheckBox = includeAttributeCheckBox; 078 this.includePortsCheckBox = includePortsCheckBox; 079 this.includeRelationsCheckBox = includeRelationsCheckBox; 080 081 initialize(entity); 082 } 083 084 /* 085 * (non-Javadoc) 086 * 087 * @see org.kepler.gui.TabPane#initializeTab() 088 */ 089 public void initialize(CompositeEntity entity) { 090 if (isDebugging) log.debug("initialize()"); 091 this.setLayout(new BorderLayout()); 092 this.setBackground(TabManager.BGCOLOR); 093 094 wotm = new SubsetWorkflowOutlineTreeModel(entity); 095 096 refreshOutlineTree(); 097 } 098 099 public void refreshOutlineTree() { 100 if (isDebugging) { 101 log.debug("refreshOutlineTree()"); 102 } 103 104 this.removeAll(); 105 106 _ptree = new AnnotatedPTree(wotm, this); 107 108 _mouseListener = new OutlinePopupListener(_ptree); 109 _ptree.setMouseListener(_mouseListener); 110 111 _ptree.setRootVisible(false); 112 _ptree.initAnotatedPTree(); 113 JScrollPane jSP = new JScrollPane(_ptree, 114 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 115 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 116 jSP.setPreferredSize(new Dimension(200, 200)); 117 118 this.add(jSP, BorderLayout.CENTER); 119 120 setControls(); 121 122 this.repaint(); 123 this.validate(); 124 125 // if panel was showing the results of a search, redo the search 126 if(_searchTerm != null && !_searchTerm.isEmpty()) { 127 search(_searchTerm); 128 } 129 } 130 131 /** Display the subset of the workflow for entities containing the given term. 132 * To display everything set the term to the empty string. 133 */ 134 public void search(String searchTerm) { 135 136 // reset the display 137 wotm.showAll(); 138 139 // do the search if search term is not empty 140 if(!searchTerm.isEmpty()) { 141 Object root = wotm.getRoot(); 142 _searchTree(root, searchTerm); 143 // show only the matches 144 wotm.showSubset(); 145 146 } 147 148 // issue an empty change request to repaint the tree 149 MoMLChangeRequest change = 150 new MoMLChangeRequest(wotm.getRoot(), (NamedObj) wotm.getRoot(), "<group></group>"); 151 change.setPersistent(false); 152 ((NamedObj) wotm.getRoot()).requestChange(change); 153 154 // if the search term was not empty, expand the tree to show 155 // the matching nodes 156 if(!searchTerm.isEmpty()) { 157 // do this in the swing thread so that it occurs after the tree is repainted 158 SwingUtilities.invokeLater(new Runnable() { 159 public void run() { 160 LibrarySearchResultPane.expandAll(_ptree); 161 } 162 }); 163 } 164 165 _searchTerm = searchTerm; 166 167 } 168 169 /** Recursively check if a node and its children contain the search term. */ 170 private void _searchTree(Object node, String searchTerm) { 171 172 NamedObj namedObj = (NamedObj)node; 173 //System.out.println("searching " + namedObj.getFullName()); 174 // see if the name contains the search term; ignore case 175 if(namedObj.getName().toLowerCase().contains(searchTerm.toLowerCase())) { 176 //System.out.println(namedObj); 177 wotm.addToSubset(namedObj); 178 } 179 180 if(!wotm.isLeaf(node)) { 181 for(int i = 0; i < wotm.getChildCount(node); i++) { 182 _searchTree(wotm.getChild(node, i), searchTerm); 183 } 184 } 185 } 186 187 private void setControls() { 188 189 JPanel controlPanel = new JPanel(new BorderLayout()); 190 191 if (includePortsCheckBox) { 192 togglePorts = new JCheckBox(StaticResources.getDisplayString( 193 "outline.showPorts", "Show Ports")); 194 togglePorts.setSelected(wotm.includePorts); 195 togglePorts.addActionListener(new ToggleListener()); 196 togglePorts.setBackground(TabManager.BGCOLOR); 197 controlPanel.add(togglePorts, BorderLayout.NORTH); 198 } 199 200 if (includeAttributeCheckBox) { 201 toggleAttributes = new JCheckBox(StaticResources.getDisplayString( 202 "outline.showAttributes", "Show Attributes")); 203 toggleAttributes.setSelected(wotm.includeAttributes); 204 toggleAttributes.addActionListener(new ToggleListener()); 205 toggleAttributes.setBackground(TabManager.BGCOLOR); 206 controlPanel.add(toggleAttributes, BorderLayout.CENTER); 207 208 } 209 210 if (includeRelationsCheckBox) { 211 toggleRelations = new JCheckBox(StaticResources.getDisplayString( 212 "outline.showRelations", "Show Relations")); 213 toggleRelations.setSelected(wotm.includeRelations); 214 toggleRelations.addActionListener(new ToggleListener()); 215 toggleRelations.setBackground(TabManager.BGCOLOR); 216 controlPanel.add(toggleRelations, BorderLayout.SOUTH); 217 } 218 219 controlPanel.setBackground(TabManager.BGCOLOR); 220 this.add(controlPanel,BorderLayout.SOUTH); 221 } 222 223 224 private class ToggleListener implements ActionListener { 225 226 public void actionPerformed(ActionEvent e) { 227 if (isDebugging) log.debug("actionPerformed("+e+")"); 228 if (e.getSource() == togglePorts) { 229 if (isDebugging) log.debug("togglePorts"); 230 if (togglePorts.isSelected()) { 231 wotm.includePorts = true; 232 } else { 233 wotm.includePorts = false; 234 } 235 } else if (e.getSource() == toggleAttributes) { 236 if (isDebugging) log.debug("toggleAttributes"); 237 if (toggleAttributes.isSelected()) { 238 wotm.includeAttributes = true; 239 } else { 240 wotm.includeAttributes = false; 241 } 242 } else if (e.getSource() == toggleRelations) { 243 if (isDebugging) log.debug("toggleRelations"); 244 if (toggleRelations.isSelected()) { 245 wotm.includeRelations = true; 246 } else { 247 wotm.includeRelations = false; 248 } 249 } 250 refreshOutlineTree(); 251 } 252 } 253 254}