001/* 002 * Copyright (c) 2012 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2015-02-09 18:04:51 +0000 (Mon, 09 Feb 2015) $' 007 * '$Revision: 33224 $' 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.frame; 031 032import java.awt.Color; 033 034import org.kepler.gui.ModelToFrameManager; 035import org.kepler.gui.TabbedLookInsideAction; 036 037import ptolemy.actor.CompositeActor; 038import ptolemy.actor.gui.Effigy; 039import ptolemy.actor.gui.PtolemyEffigy; 040import ptolemy.actor.gui.Tableau; 041import ptolemy.actor.gui.TableauFactory; 042import ptolemy.kernel.CompositeEntity; 043import ptolemy.kernel.util.IllegalActionException; 044import ptolemy.kernel.util.InternalErrorException; 045import ptolemy.kernel.util.NameDuplicationException; 046import ptolemy.kernel.util.NamedObj; 047import ptolemy.moml.LibraryAttribute; 048 049/** An editor tableau for multiple composite actors. 050 * 051 @author Daniel Crawl 052 @version $Id: TabbedKeplerGraphTableau.java 33224 2015-02-09 18:04:51Z crawl $ 053 */ 054public class TabbedKeplerGraphTableau extends KeplerGraphTableau { 055 /** Create a new TabbedKeplerGraphTableau with the specified 056 * container and name. 057 * @param container The container. 058 * @param name The name. 059 * @exception IllegalActionException If the model associated with 060 * the container effigy is not an instance of CompositeEntity. 061 * @exception NameDuplicationException If the container already 062 * contains an object with the specified name. 063 */ 064 public TabbedKeplerGraphTableau(PtolemyEffigy container, String name) 065 throws IllegalActionException, NameDuplicationException { 066 this(container, name, null); 067 } 068 069 /** Create a new TabbedKeplerGraphTableau with the specified 070 * container, name, and default library. 071 * @param container The container. 072 * @param name The name. 073 * @param defaultLibrary The default library, or null to not specify one. 074 * @exception IllegalActionException If the model associated with 075 * the container effigy is not an instance of CompositeEntity. 076 * @exception NameDuplicationException If the container already 077 * contains an object with the specified name. 078 */ 079 public TabbedKeplerGraphTableau(PtolemyEffigy container, String name, 080 LibraryAttribute defaultLibrary) throws IllegalActionException, 081 NameDuplicationException { 082 super(container, name); 083 } 084 085 /////////////////////////////////////////////////////////////////// 086 //// public methods //// 087 088 /** Create the graph frame that displays the model associated with 089 * this tableau. This method creates a MultiCompositeGraphFrame. 090 * @param model The Ptolemy II model to display in the graph frame. 091 */ 092 public void createGraphFrame(CompositeEntity model) { 093 createGraphFrame(model, null); 094 } 095 096 /** Create the graph frame that displays the model associated with 097 * this tableau together with the specified library. 098 * @param model The Ptolemy II model to display in the graph frame. 099 * @param defaultLibrary The default library, or null to not specify 100 * one. 101 */ 102 @Override 103 public void createGraphFrame(CompositeEntity model, 104 LibraryAttribute defaultLibrary) 105 { 106 TabbedKeplerGraphFrame frame = null; 107 NamedObj container = model.getContainer(); 108 109 // if model is top-level or the action for opening in new tab is not 110 // running, then open in a new frame 111 if(container == null || !TabbedLookInsideAction.actionIsRunning()) { 112 frame = new TabbedKeplerGraphFrame((CompositeActor) model, this, 113 defaultLibrary); 114 _createdNewFrame = true; 115 } else { 116 frame = _addCompositeToExistingFrame(model, defaultLibrary); 117 _createdNewFrame = false; 118 } 119 120 _configureFrame(frame, model); 121 122 } 123 124 /** Override the parent class so that if the new container is null and we did 125 * not create a new frame, then set the frame to null so that it is not 126 * disposed of by the parent class. 127 */ 128 @Override 129 public void setContainer(CompositeEntity container) 130 throws IllegalActionException, NameDuplicationException { 131 132 if(container == null && !_createdNewFrame) { 133 setFrame(null); 134 } 135 super.setContainer(container); 136 } 137 138 /** Make this tableau visible by calling setVisible(true), and 139 * raising or deiconifying its window. 140 * If no frame has been set, then do nothing. 141 */ 142 @Override 143 public void show() { 144 145 // make the tableau visible 146 super.show(); 147 148 // set the selected tab to the model for this tableau. 149 // if the model is not one of the tabs, then setSelectedTab() does nothing. 150 final PtolemyEffigy effigy = (PtolemyEffigy)getContainer(); 151 final NamedObj model = effigy.getModel(); 152 final TabbedKeplerGraphFrame frame = 153 (TabbedKeplerGraphFrame) ModelToFrameManager.getInstance().getFrame(model); 154 frame.setSelectedTab(model); 155 } 156 157 protected TabbedKeplerGraphFrame _addCompositeToExistingFrame(CompositeEntity model, 158 LibraryAttribute defaultLibrary) { 159 160 TabbedKeplerGraphFrame frame = null; 161 NamedObj container = model.getContainer(); 162 163 // get the frame for the container. if the container does not have a frame, 164 // e.g., we're opening a sub-workflow whose parent was not opened, then go 165 // up the hierarchy to find the frame. 166 while(frame == null && container != null) { 167 frame = (TabbedKeplerGraphFrame) ModelToFrameManager.getInstance().getFrame(container); 168 if(frame == null) { 169 container = container.getContainer(); 170 } 171 } 172 if(frame == null) { 173 throw new InternalErrorException("Unable to find frame for " + model.getFullName()); 174 } 175 frame.addComposite(model, this, defaultLibrary); 176 return frame; 177 } 178 179 /** Configure the frame for the opened model. */ 180 protected void _configureFrame(TabbedKeplerGraphFrame frame, CompositeEntity model) { 181 182 NamedObj container = model.getContainer(); 183 184 // setFrame() sets the title to be the name of the model. if the model 185 // is a tab in an existing frame, set the name back to the top level model 186 String oldTitle = null; 187 if(container != null) { 188 oldTitle = frame.getTitle(); 189 } 190 191 try { 192 setFrame(frame); 193 } catch (IllegalActionException e) { 194 throw new InternalErrorException(e); 195 } 196 197 if(container != null) { 198 frame.setTitle(oldTitle); 199 } 200 201 frame.setBackground(BACKGROUND_COLOR); 202 203 } 204 205 /////////////////////////////////////////////////////////////////// 206 //// private variables //// 207 208 /** Background color. */ 209 private final static Color BACKGROUND_COLOR = new Color(0xe5e5e5); 210 211 /** If true, a new frame was created in createGraphFrame(). */ 212 protected boolean _createdNewFrame; 213 214 // ///////////////////////////////////////////////////////////////// 215 // // public inner classes //// 216 217 /** 218 * A factory that creates graph editing tableaux for Ptolemy models. 219 */ 220 public static class Factory extends TableauFactory { 221 /** 222 * Create an factory with the given name and container. 223 * 224 * @param container 225 * The container. 226 * @param name 227 * The name. 228 * @exception IllegalActionException 229 * If the container is incompatible with this attribute. 230 * @exception NameDuplicationException 231 * If the name coincides with an attribute already in the 232 * container. 233 */ 234 public Factory(NamedObj container, String name) 235 throws IllegalActionException, NameDuplicationException { 236 super(container, name); 237 } 238 239 /** 240 * Create a tableau in the default workspace with no name for the given 241 * Effigy. The tableau will created with a new unique name in the given 242 * model effigy. If this factory cannot create a tableau for the given 243 * effigy (perhaps because the effigy is not of the appropriate 244 * subclass) then return null. It is the responsibility of callers of 245 * this method to check the return value and call show(). 246 * 247 * @param effigy 248 * The model effigy. 249 * @return A new KeplerGraphTableau, if the effigy is a PtolemyEffigy, 250 * or null otherwise. 251 * @exception Exception 252 * If an exception occurs when creating the tableau. 253 */ 254 @Override 255 public Tableau createTableau(Effigy effigy) throws Exception { 256 if (effigy instanceof PtolemyEffigy) { 257 // First see whether the effigy already contains a graphTableau. 258 TabbedKeplerGraphTableau tableau = (TabbedKeplerGraphTableau) effigy 259 .getEntity("graphTableau"); 260 261 if (tableau == null) { 262 // Check to see whether this factory contains a 263 // default library. 264 LibraryAttribute library = (LibraryAttribute) getAttribute( 265 "_library", LibraryAttribute.class); 266 tableau = new TabbedKeplerGraphTableau((PtolemyEffigy) effigy, 267 "graphTableau", library); 268 } 269 270 // Don't call show() here, it is called for us in 271 // TableauFrame.ViewMenuListener.actionPerformed() 272 return tableau; 273 } else { 274 return null; 275 } 276 } 277 } 278}