001/* An action for editing parameters.
002
003 Copyright (c) 1999-2016 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.vergil.toolbox;
029
030import java.awt.Frame;
031import java.awt.Toolkit;
032import java.awt.event.ActionEvent;
033import java.awt.event.KeyEvent;
034import java.util.List;
035
036import javax.swing.KeyStroke;
037
038import diva.gui.GUIUtilities;
039import ptolemy.actor.gui.EditParametersDialog;
040import ptolemy.actor.gui.Editable;
041import ptolemy.kernel.util.NamedObj;
042import ptolemy.util.MessageHandler;
043
044///////////////////////////////////////////////////////////////////
045//// ConfigureAction
046
047/**
048 An action that will configure parameters on the current object.
049 If that object contains an attribute that is an instance of EditorFactory,
050 then that instance is used to create the dialog (or whatever) to configure
051 the object.  Otherwise, an instance of EditParametersDialog is created.
052
053 @author Edward A. Lee
054 @version $Id$
055 @since Ptolemy II 2.1
056 @Pt.ProposedRating Red (eal)
057 @Pt.AcceptedRating Red (johnr)
058 @see ptolemy.actor.gui.EditParametersDialog
059 */
060@SuppressWarnings("serial")
061public class ConfigureAction extends FigureAction {
062    /** Construct a new configure action.
063     *  @param description A description.
064     */
065    public ConfigureAction(String description) {
066        super(description);
067
068        // FIXME: For some inexplicable reason, the following works
069        // for LookInsideAction to define a hotkey for look inside,
070        // but it doesn't work here.
071
072        // Call getMenuShortcutKeyMask() instead of Event.CTRL_MASK
073        // and avoid problems with shortcut keys on the Macintosh.  See
074        // http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3094
075        putValue(GUIUtilities.ACCELERATOR_KEY,
076                KeyStroke.getKeyStroke(KeyEvent.VK_E,
077                        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
078    }
079
080    ///////////////////////////////////////////////////////////////////
081    ////                         public methods                    ////
082
083    /** Open a dialog to edit the target.
084     *  @param e The event.
085     */
086    @Override
087    public void actionPerformed(ActionEvent e) {
088        try {
089            // Determine which entity was selected for the look inside action.
090            super.actionPerformed(e);
091
092            NamedObj target = getTarget();
093
094            if (target == null) {
095                return;
096            }
097
098            // Create a dialog for configuring the object.
099            // First, identify the top parent frame.
100            Frame parent = getFrame();
101            _openDialog(parent, target, e);
102        } catch (Throwable throwable) {
103            // Giotto code generator on giotto/demo/Hierarchy/Hierarchy.xml
104            // was throwing an exception here that was not being displayed
105            // in the UI.
106            MessageHandler.error("Failed to open a dialog to edit the target.",
107                    throwable);
108        }
109    }
110
111    /** Open an edit parameters dialog.  This is a modal dialog, so
112     *  this method returns only after the dialog has been dismissed.
113     *  @param parent A frame to serve as a parent for the dialog, or
114     *  null if there is none.
115     *  @param target The object whose parameters are to be edited.
116     */
117    public void openDialog(Frame parent, NamedObj target) {
118        _openDialog(parent, target, null);
119    }
120
121    ///////////////////////////////////////////////////////////////////
122    ////                         protected methods                 ////
123
124    /** Open an edit parameters dialog.  This is a modal dialog, so
125     *  this method returns only after the dialog has been dismissed.
126     *  @param parent A frame to serve as a parent for the dialog, or
127     *  null if there is none.
128     *  @param target The object whose parameters are to be edited.
129     *  @param event The action event that triggered this, or null if
130     *   none.
131     */
132    protected void _openDialog(Frame parent, NamedObj target,
133            ActionEvent event) {
134        List<Editable> attributeList = target.attributeList(Editable.class);
135        boolean altKeyPressed = false;
136        if (event != null) {
137            altKeyPressed = (event.getModifiers() & ActionEvent.ALT_MASK) != 0;
138        }
139
140        //Use the EditorFactory if the alt key is not pressed and the
141        // action command is not "Configure".
142        if (attributeList.size() > 0 && !altKeyPressed && (event == null
143                || !event.getActionCommand().equals("Configure"))) {
144
145            // Use the last editor factory if there is more than one.
146            Editable factory = attributeList.get(attributeList.size() - 1);
147            factory.createEditor(target, parent);
148        } else {
149            new EditParametersDialog(parent, target);
150        }
151    }
152}