001/*
002 * Copyright (c) 2004-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;
031
032import java.awt.event.ActionEvent;
033import java.awt.event.KeyEvent;
034import java.util.Map;
035
036import javax.swing.Action;
037import javax.swing.ImageIcon;
038import javax.swing.JCheckBoxMenuItem;
039import javax.swing.KeyStroke;
040
041import org.apache.commons.logging.Log;
042import org.apache.commons.logging.LogFactory;
043
044import diva.gui.GUIUtilities;
045import ptolemy.actor.gui.TableauFrame;
046import ptolemy.vergil.toolbox.FigureAction;
047
048/**
049 * This class provides an action to turn on or off animating a workflow
050 * during execution. When animation is turned on, a checkbox appears
051 * next to the text in the menu item.
052 * 
053 *@author Matthew Brooke
054 *@since 27 January 2006
055 */
056public class RunWithFeedbackChkBoxAction extends FigureAction implements InitializableAction {
057
058        // //////////////////////////////////////////////////////////////////////////////
059        // Note that these are defaults - Instantiating code will
060        // probably override these in a localizable manner
061
062        private final String DISPLAY_NAME = "Run with Feedback";
063        private final String TOOLTIP = "Show feedback when running workflow";
064        private final ImageIcon LARGE_ICON = null;
065        private final Integer MNEMONIC_KEY = new Integer(KeyEvent.VK_F);
066        private final KeyStroke ACCELERATOR_KEY = null;
067        // = KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().
068        // getMenuShortcutKeyMask());
069        // //////////////////////////////////////////////////////////////////////////////
070
071        // old PTII display names used for actionCommand
072        // text, for backward compatibility
073        private final String FEEDBACK_ON_PTII_DISPLAY_NAME = "Animate Execution";
074        private final String FEEDBACK_OFF_PTII_DISPLAY_NAME = "Stop Animating";
075
076        // NOTE - Keys in PTIIMenuActionsMap are all UPPERCASE
077        private final String FEEDBACK_ON_PTIIMENUPATH = ("Debug->" + FEEDBACK_ON_PTII_DISPLAY_NAME)
078                        .toUpperCase();
079
080        // NOTE - Keys in PTIIMenuActionsMap are all UPPERCASE
081        private final String FEEDBACK_OFF_PTIIMENUPATH = ("Debug->" + FEEDBACK_OFF_PTII_DISPLAY_NAME)
082                        .toUpperCase();
083
084        private JCheckBoxMenuItem jcbMenuItem;
085        private Action feedbackOnAction;
086        private Action feedbackOffAction;
087
088        /**
089         * Constructor
090         * 
091         * @param parent
092         *            the "frame" (derived from ptolemy.gui.Top) where the menu is
093         *            being added.
094         */
095        public RunWithFeedbackChkBoxAction(TableauFrame parent) {
096                super("");
097                if (parent == null) {
098                        IllegalArgumentException iae = new IllegalArgumentException(
099                                        "RunWithFeedbackChkBoxAction constructor received NULL argument for TableauFrame");
100                        iae.fillInStackTrace();
101                        throw iae;
102                }
103                this.putValue(Action.NAME, DISPLAY_NAME);
104                this.putValue(GUIUtilities.LARGE_ICON, LARGE_ICON);
105                this.putValue(GUIUtilities.MNEMONIC_KEY, MNEMONIC_KEY);
106                this.putValue("tooltip", TOOLTIP);
107                this.putValue(GUIUtilities.ACCELERATOR_KEY, ACCELERATOR_KEY);
108        }
109        
110        public boolean initialize(Map<String, Action> menuActionsMap) {
111            
112            // set the menu type to a checkbox so that MenuMapper will use
113            // a JCheckBoxMenuItem for our menu item.
114                this.putValue(MenuMapper.MENUITEM_TYPE,
115                                MenuMapper.CHECKBOX_MENUITEM_TYPE);
116
117                feedbackOnAction = (Action) menuActionsMap.get(FEEDBACK_ON_PTIIMENUPATH);
118                feedbackOffAction = (Action) menuActionsMap.get(FEEDBACK_OFF_PTIIMENUPATH);
119
120                /* This method gets called when MenuMapper is constructing the menu bar.
121                 * The actions Debug->Animate Execution and Debug->Stop Animating may not be
122                 * present for the type of window that is being constructed, e.g.,
123                 * a documentation window, so do not check if they are null.
124                 */
125                /*
126                if (feedbackOnAction == null || feedbackOffAction == null) {
127                        IllegalArgumentException iae = new IllegalArgumentException(
128                                        "RunWithFeedbackChkBoxAction constructor could not get actions for "
129                                                        + FEEDBACK_ON_PTIIMENUPATH + " or "
130                                                        + FEEDBACK_OFF_PTIIMENUPATH);
131                        iae.fillInStackTrace();
132                        throw iae;
133                }
134                */
135                
136                // Both actions need to be present in order to use this action
137                if(feedbackOnAction == null || feedbackOffAction == null) {
138                    return false;
139                }
140                return true;
141                
142        }
143
144        /**
145         * Invoked when an action occurs.
146         * 
147         *@param e
148         *            ActionEvent
149         */
150        public void actionPerformed(ActionEvent e) {
151
152            /* Our menu item was executed, so make sure the corresponding Ptolemy
153             * actions were found.
154             */
155                if (feedbackOnAction == null || feedbackOffAction == null) {
156                        if (isDebugging) {
157                                log
158                                                .debug("RunWithFeedbackChkBoxAction.actionPerformed() - null Action(s):"
159                                                                + "\n feedbackOnAction = "
160                                                                + feedbackOnAction
161                                                                + "\n feedbackOffAction = " + feedbackOffAction);
162                        }
163                        return;
164                }
165
166                // get the menu item so that we can see if animation is currently turned on
167                if (jcbMenuItem == null) {
168                        jcbMenuItem = (JCheckBoxMenuItem) this
169                                        .getValue(MenuMapper.NEW_JMENUITEM_KEY);
170                }
171                
172                if (jcbMenuItem != null) {
173
174                        boolean isChecked = jcbMenuItem.getState();
175
176                        if (isChecked) {
177                            
178                            log.debug("FEEDBACK_ON");
179
180                                // NOTE - PTII uses ActionCommands for some listeners;
181                                // need to set this to PTII display name so it works...
182                                jcbMenuItem.setActionCommand(FEEDBACK_ON_PTII_DISPLAY_NAME);
183
184                                feedbackOnAction.actionPerformed(e);
185                        } else {
186                                log.debug("FEEDBACK_OFF");
187
188                                // NOTE - PTII uses ActionCommands for some listeners;
189                                // need to set this to PTII display name so it works...
190                                jcbMenuItem.setActionCommand(FEEDBACK_OFF_PTII_DISPLAY_NAME);
191
192                                feedbackOffAction.actionPerformed(e);
193                        }
194                }
195        }
196
197        private static final Log log = LogFactory.getLog(
198                        RunWithFeedbackChkBoxAction.class.getName());
199
200        private static final boolean isDebugging = log.isDebugEnabled();
201
202}