001/*
002 * Copyright (c) 2006-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2015-08-24 22:44:14 +0000 (Mon, 24 Aug 2015) $' 
007 * '$Revision: 33630 $'
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.event.KeyEvent;
033
034import javax.swing.JMenu;
035
036import org.kepler.gui.state.StateChangeListener;
037
038import diva.gui.GUIUtilities;
039import ptolemy.actor.gui.Effigy;
040import ptolemy.actor.gui.PtolemyEffigy;
041import ptolemy.actor.gui.Tableau;
042import ptolemy.actor.gui.TableauFactory;
043import ptolemy.actor.lib.hoc.Case;
044import ptolemy.kernel.CompositeEntity;
045import ptolemy.kernel.Port;
046import ptolemy.kernel.util.IllegalActionException;
047import ptolemy.kernel.util.NameDuplicationException;
048import ptolemy.kernel.util.NamedObj;
049import ptolemy.moml.LibraryAttribute;
050
051//////////////////////////////////////////////////////////////////////////
052//// CaseGraphTableau
053
054/** An editor tableau for case constructs in Ptolemy II.
055
056 <p>This class is a copy of ptolemy.vergil.modal.CaseGraphTableau,
057 but uses org.kepler.gui.frame.CaseGraphFrame</p>
058
059(see http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3708)
060 @author Daniel Crawl, based on ptolemy.vergil.modal.CaseGraphTableau by Edward A. Lee
061 @version $Id: CaseGraphTableau.java 33630 2015-08-24 22:44:14Z crawl $
062 @since Ptolemy II 7.1
063 @Pt.ProposedRating Yellow (eal)
064 @Pt.AcceptedRating Red (johnr)
065 */
066public class CaseGraphTableau extends MultiCompositeTableau implements StateChangeListener {
067    /** Create a new case editor tableau with the specified container
068     *  and name.
069     *  @param container The container.
070     *  @param name The name.
071     *  @exception IllegalActionException If the model associated with
072     *   the container effigy is not an instance of Case.
073     *  @exception NameDuplicationException If the container already
074     *   contains an object with the specified name.
075     */
076    public CaseGraphTableau(PtolemyEffigy container, String name)
077            throws IllegalActionException, NameDuplicationException {
078        this(container, name, null);
079    }
080
081    /** Create a new case editor tableau with the specified container,
082     *  name, and default library.
083     *  @param container The container.
084     *  @param name The name.
085     *  @param defaultLibrary The default library, or null to not specify one.
086     *  @exception IllegalActionException If the model associated with
087     *   the container effigy is not an instance of Case.
088     *  @exception NameDuplicationException If the container already
089     *   contains an object with the specified name.
090     */
091    public CaseGraphTableau(PtolemyEffigy container, String name,
092            LibraryAttribute defaultLibrary) throws IllegalActionException,
093            NameDuplicationException {
094        super(container, name);
095    }
096
097    ///////////////////////////////////////////////////////////////////
098    ////                         public methods                    ////
099
100
101    /** This method is called when the Case actor is selected or unselected in the
102     *  frame. If selected, add the Case menu to the menubar, otherwise remove it.
103     */
104    @Override
105    public void _multiCompositeSelected(boolean isSelected) {
106
107        super._multiCompositeSelected(isSelected);
108        
109        // create the Case menu if necessary
110        if(_caseMenu == null) {
111            
112            _caseMenu = new JMenu("Case");
113            _caseMenu.setMnemonic(KeyEvent.VK_C);
114            
115            _addCaseAction = new AddCaseAction();
116            _removeCaseAction = new RemoveRefinementAction("case", "cases");
117
118            // TODO: addHotKey() calls seem unnecessary?
119            
120            //GUIUtilities.addHotKey(_getRightComponent(), _addCaseAction);
121            GUIUtilities.addMenuItem(_caseMenu, _addCaseAction);
122            
123            //GUIUtilities.addHotKey(_getRightComponent(), _removeCaseAction);
124            GUIUtilities.addMenuItem(_caseMenu, _removeCaseAction);
125        }
126        
127        if(isSelected) {
128            _frame.addMenu(_caseMenu);
129        } else {
130            _frame.removeMenu(_caseMenu);
131        }
132    }
133
134    /** Configure the frame for the opened Case actor. */
135    @Override
136    protected void _configureFrame(TabbedKeplerGraphFrame frame, CompositeEntity model) {
137        super._configureFrame(frame, model);
138        _case = (Case) model;
139    }
140
141    /** A menu to add and remove cases. */
142    private JMenu _caseMenu;
143    
144    /** The action to add a case. */
145    private AddCaseAction _addCaseAction;
146
147    /** The Case actor displayed by this frame. */
148    private Case _case;
149    
150    /** The action to remove a refinement. */
151    private RemoveRefinementAction _removeCaseAction;
152
153    
154    ///////////////////////////////////////////////////////////////////
155    ////                     public inner classes                  ////
156
157    /** Class implementing the Add Case menu command. */
158    public class AddCaseAction extends AddRefinementAction {
159
160        /** Create a case action with label "Add Case". */
161        public AddCaseAction() {
162            super("Add Case", "case",
163                "Pattern that the control input must match");
164        }
165                
166        /** Returns true if port should be mirrored. */
167        @Override
168        public boolean mirrorPort(Port port) {
169            // do not mirror the control port
170            if(port == _case.control.getPort()) {
171                return false;
172            }
173            return true;
174        }
175    }
176    
177    /** A factory that creates graph editing tableaux for Ptolemy models.
178     */
179    public static class Factory extends TableauFactory {
180        /** Create an factory with the given name and container.
181         *  @param container The container.
182         *  @param name The name of the entity.
183         *  @exception IllegalActionException If the container is incompatible
184         *   with this attribute.
185         *  @exception NameDuplicationException If the name coincides with
186         *   an attribute already in the container.
187         */
188        public Factory(NamedObj container, String name)
189                throws IllegalActionException, NameDuplicationException {
190            super(container, name);
191        }
192
193        /** Create an instance of CaseGraphTableau for the specified effigy,
194         *  if it is an effigy for an instance of Case.
195         *  @param effigy The effigy for a Case.
196         *  @return A new CaseGraphTableau, if the effigy is a PtolemyEffigy
197         *   that references a Case, or null otherwise.
198         *  @exception Exception If an exception occurs when creating the
199         *   tableau.
200         */
201        @Override
202        public Tableau createTableau(Effigy effigy) throws Exception {
203            if (!(effigy instanceof PtolemyEffigy)) {
204                return null;
205            }
206
207            NamedObj model = ((PtolemyEffigy) effigy).getModel();
208
209            if (model instanceof Case) {
210                // Check to see whether this factory contains a
211                // default library.
212                LibraryAttribute library = (LibraryAttribute) getAttribute(
213                        "_library", LibraryAttribute.class);
214
215                CaseGraphTableau tableau = new CaseGraphTableau(
216                        (PtolemyEffigy) effigy, effigy.uniqueName("tableau"),
217                        library);
218                return tableau;
219            } else {
220                return null;
221            }
222        }
223    }
224}