001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas/
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see https://www.gnu.org/licenses/.
027 */
028
029package edu.wisc.ssec.mcidasv.jython;
030
031import java.awt.event.ActionEvent;
032import java.awt.event.KeyEvent;
033import java.util.Map;
034import java.util.concurrent.ConcurrentHashMap;
035
036import javax.swing.Action;
037import javax.swing.JTextPane;
038import javax.swing.text.DefaultEditorKit;
039import javax.swing.text.Keymap;
040import javax.swing.text.TextAction;
041
042import edu.wisc.ssec.mcidasv.jython.Console.Actions;
043
044// TODO(jon): there has to be a less repetitive way...
045public abstract class ConsoleAction extends TextAction {
046    protected static final Map<JTextPane, Console> mapping = new ConcurrentHashMap<>();
047    protected Console console;
048
049    protected ConsoleAction(final Console console, final Actions type) {
050        super(type.getId());
051        this.console = console;
052
053        JTextPane textPane = console.getTextPane();
054        Keymap keyMap = textPane.getKeymap();
055        keyMap.addActionForKeyStroke(type.getKeyStroke(), this);
056        mapping.put(textPane, console);
057    }
058
059    /**
060     * Attempts to return the console where the {@code ActionEvent} originated.
061     * 
062     * <p>Note: {@code TextAction}s are <i>weird</i>. The only 
063     * somewhat-accurate way to determine where the action occurred is to check
064     * {@link ActionEvent#getSource()}. Since that will be a {@code JTextPane},
065     * you have to keep an updated mapping of {@code JTextPane}s to {@code Console}s.
066     * 
067     * @param e The action whose source {@code Console} you want.
068     * 
069     * @return Either the actual source {@code Console}, or the {@code Console}
070     * provided to the constructor.
071     * 
072     * @see TextAction
073     */
074    protected Console getSourceConsole(final ActionEvent e) {
075        if (console.getTextPane() != e.getSource()) {
076            Console other = mapping.get((JTextPane)e.getSource());
077            if (other != null) {
078                return other;
079            }
080        }
081        return console;
082    }
083
084    public abstract void actionPerformed(final ActionEvent e);
085}
086
087class PasteAction extends ConsoleAction {
088    public PasteAction(final Console console, final Actions type) {
089        super(console, type);
090    }
091    
092    public void actionPerformed(final ActionEvent e) {
093        getSourceConsole(e).handlePaste();
094    }
095}
096
097class EnterAction extends ConsoleAction {
098    private static final long serialVersionUID = 6866731355386212866L;
099
100    public EnterAction(final Console console, final Actions type) {
101        super(console, type);
102    }
103
104    public void actionPerformed(final ActionEvent e) {
105        getSourceConsole(e).handleEnter();
106    }
107}
108
109class DeleteAction extends ConsoleAction {
110    private static final long serialVersionUID = 4084595316508126660L;
111
112    public DeleteAction(final Console console, final Actions type) {
113        super(console, type);
114    }
115
116    public void actionPerformed(final ActionEvent e) {
117        getSourceConsole(e).handleDelete();
118    }
119}
120
121class HomeAction extends ConsoleAction {
122    private static final long serialVersionUID = 8416339385843554054L;
123
124    public HomeAction(final Console console, final Actions type) {
125        super(console, type);
126    }
127
128    public void actionPerformed(final ActionEvent e) {
129        getSourceConsole(e).handleHome();
130    }
131}
132
133class EndAction extends ConsoleAction {
134    private static final long serialVersionUID = 5990936637916440399L;
135
136    public EndAction(final Console console, final Actions type) {
137        super(console, type);
138    }
139
140    public void actionPerformed(final ActionEvent e) {
141        getSourceConsole(e).handleEnd();
142    }
143}
144
145class TabAction extends ConsoleAction {
146    private static final long serialVersionUID = 2303773619117479801L;
147
148    public TabAction(final Console console, final Actions type) {
149        super(console, type);
150    }
151    public void actionPerformed(final ActionEvent e) {
152        getSourceConsole(e).handleTab();
153    }
154}
155
156class UpAction extends ConsoleAction {
157    private static final long serialVersionUID = 6710943250074726107L;
158    private Action defaultAction;
159    
160    public UpAction(final Console console, final Actions type) {
161        super(console, type);
162        defaultAction = console.getTextPane().getActionMap().get(DefaultEditorKit.upAction);
163    }
164
165    public void actionPerformed(final ActionEvent e) {
166        defaultAction.actionPerformed(e);
167    }
168}
169
170class DownAction extends ConsoleAction {
171    private static final long serialVersionUID = 5700659549452276829L;
172    private Action defaultAction;
173
174    public DownAction(final Console console, final Actions type) {
175        super(console, type);
176        defaultAction = console.getTextPane().getActionMap().get(DefaultEditorKit.downAction);
177    }
178
179    public void actionPerformed(final ActionEvent e) {
180        defaultAction.actionPerformed(e);
181    }
182}