Ignore:
Timestamp:
2015-02-02T23:56:07+01:00 (9 years ago)
Author:
Don-vip
Message:

fix #11046 - add Redo action, bound to Ctrl-Y in JosmTextField. Don't bind undo/redo actions in headless mode to avoid exception in unit tests

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java

    r8000 r8002  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.GraphicsEnvironment;
    67import java.awt.Toolkit;
    78import java.awt.event.ActionEvent;
     
    2021import javax.swing.text.DefaultEditorKit;
    2122import javax.swing.text.JTextComponent;
     23import javax.swing.undo.CannotRedoException;
    2224import javax.swing.undo.CannotUndoException;
    2325import javax.swing.undo.UndoManager;
     
    3032 * <ul>
    3133 * <li>Undo</li>
     34 * <li>Redo</li>
    3235 * <li>Cut</li>
    3336 * <li>Copy</li>
     
    4346
    4447    protected JTextComponent component = null;
    45     protected UndoAction undoAction = null;
     48    protected final UndoAction undoAction = new UndoAction();
     49    protected final RedoAction redoAction = new RedoAction();
     50    protected final UndoManager undo = new UndoManager();
     51
     52    protected final UndoableEditListener undoEditListener = new UndoableEditListener() {
     53        @Override
     54        public void undoableEditHappened(UndoableEditEvent e) {
     55            undo.addEdit(e.getEdit());
     56            undoAction.updateUndoState();
     57            redoAction.updateRedoState();
     58        }
     59    };
    4660
    4761    protected final PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
    48         @Override public void propertyChange(PropertyChangeEvent evt) {
     62        @Override
     63        public void propertyChange(PropertyChangeEvent evt) {
    4964            if (EDITABLE.equals(evt.getPropertyName())) {
    5065                removeAll();
     
    7186            this.component = component;
    7287            if (component.isEditable()) {
    73                 undoAction = new UndoAction();
    74                 component.getDocument().addUndoableEditListener(undoAction);
    75                 component.getInputMap().put(
    76                         KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), undoAction);
     88                component.getDocument().addUndoableEditListener(undoEditListener);
     89                if (!GraphicsEnvironment.isHeadless()) {
     90                    component.getInputMap().put(
     91                            KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), undoAction);
     92                    component.getInputMap().put(
     93                            KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), redoAction);
     94                }
    7795            }
    7896            addMenuEntries();
     
    85103        if (component.isEditable()) {
    86104            add(new JMenuItem(undoAction));
     105            add(new JMenuItem(redoAction));
    87106            addSeparator();
    88107            addMenuEntry(component, tr("Cut"), DefaultEditorKit.cutAction, null);
     
    106125            component.removePropertyChangeListener(EDITABLE, propertyChangeListener);
    107126            removeAll();
    108             if (undoAction != null) {
    109                 component.getDocument().removeUndoableEditListener(undoAction);
    110                 undoAction = null;
    111             }
    112             this.component = null;
     127            component.getDocument().removeUndoableEditListener(undoEditListener);
     128            component = null;
    113129        }
    114130        return this;
     
    164180    }
    165181
    166     protected static class UndoAction extends AbstractAction implements UndoableEditListener {
    167 
    168         private final UndoManager undoManager = new UndoManager();
     182    protected class UndoAction extends AbstractAction {
    169183
    170184        /**
     
    177191
    178192        @Override
    179         public void undoableEditHappened(UndoableEditEvent e) {
    180             undoManager.addEdit(e.getEdit());
    181             setEnabled(undoManager.canUndo());
    182         }
    183 
    184         @Override
    185193        public void actionPerformed(ActionEvent e) {
    186194            try {
    187                 undoManager.undo();
     195                undo.undo();
    188196            } catch (CannotUndoException ex) {
    189197                if (Main.isTraceEnabled()) {
     
    191199                }
    192200            } finally {
    193                 setEnabled(undoManager.canUndo());
     201                updateUndoState();
     202                redoAction.updateRedoState();
     203            }
     204        }
     205
     206        public void updateUndoState() {
     207            if (undo.canUndo()) {
     208                setEnabled(true);
     209                putValue(Action.NAME, undo.getUndoPresentationName());
     210            } else {
     211                setEnabled(false);
     212                putValue(Action.NAME, tr("Undo"));
     213            }
     214        }
     215    }
     216
     217    protected class RedoAction extends AbstractAction {
     218
     219        /**
     220         * Constructs a new {@code RedoAction}.
     221         */
     222        public RedoAction() {
     223            super(tr("Redo"));
     224            setEnabled(false);
     225        }
     226
     227        @Override
     228        public void actionPerformed(ActionEvent e) {
     229            try {
     230                undo.redo();
     231            } catch (CannotRedoException ex) {
     232                if (Main.isTraceEnabled()) {
     233                    Main.trace(ex.getMessage());
     234                }
     235            } finally {
     236                updateRedoState();
     237                undoAction.updateUndoState();
     238            }
     239        }
     240
     241        public void updateRedoState() {
     242            if (undo.canRedo()) {
     243                setEnabled(true);
     244                putValue(Action.NAME, undo.getRedoPresentationName());
     245            } else {
     246                setEnabled(false);
     247                putValue(Action.NAME, tr("Redo"));
    194248            }
    195249        }
Note: See TracChangeset for help on using the changeset viewer.