001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.layer;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007import java.awt.event.KeyEvent;
008import java.lang.ref.WeakReference;
009import java.util.List;
010
011import javax.swing.AbstractAction;
012
013import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
014import org.openstreetmap.josm.tools.MultikeyActionsHandler;
015import org.openstreetmap.josm.tools.MultikeyShortcutAction;
016import org.openstreetmap.josm.tools.Shortcut;
017
018public final class JumpToMarkerActions {
019
020    public interface JumpToMarkerLayer {
021        void jumpToNextMarker();
022        void jumpToPreviousMarker();
023    }
024    
025    private JumpToMarkerActions() {
026        // Hide default constructor for utils classes
027    }
028
029    private static JumpToNextMarker jumpToNextMarkerAction;
030    private static JumpToPreviousMarker jumpToPreviousMarkerAction;
031
032    public static void initialize() {
033        jumpToNextMarkerAction = new JumpToNextMarker(null);
034        jumpToPreviousMarkerAction = new JumpToPreviousMarker(null);
035        MultikeyActionsHandler.getInstance().addAction(jumpToNextMarkerAction);
036        MultikeyActionsHandler.getInstance().addAction(jumpToPreviousMarkerAction);
037    }
038
039    public static void unregisterActions() {
040        MultikeyActionsHandler.getInstance().removeAction(jumpToNextMarkerAction);
041        MultikeyActionsHandler.getInstance().removeAction(jumpToPreviousMarkerAction);
042    }
043
044    private static abstract class JumpToMarker extends AbstractAction implements MultikeyShortcutAction {
045
046        private final Layer layer;
047        private final Shortcut multikeyShortcut;
048        private WeakReference<Layer> lastLayer;
049        
050        public JumpToMarker(JumpToMarkerLayer layer, Shortcut shortcut) {
051            this.layer = (Layer) layer;
052            this.multikeyShortcut = shortcut;
053            this.multikeyShortcut.setAccelerator(this);
054        }
055        
056        protected final void setLastLayer(Layer l) {
057            lastLayer = new WeakReference<Layer>(l);
058        }
059
060        @Override
061        public Shortcut getMultikeyShortcut() {
062            return multikeyShortcut;
063        }
064
065        @Override
066        public void actionPerformed(ActionEvent e) {
067            execute(layer);
068        }
069
070        @Override
071        public void executeMultikeyAction(int index, boolean repeat) {
072            Layer l = LayerListDialog.getLayerForIndex(index);
073            if (l != null) {
074                if (l instanceof JumpToMarkerLayer) {
075                    execute(l);
076                }
077            } else if (repeat && lastLayer != null) {
078                l = lastLayer.get();
079                if (LayerListDialog.isLayerValid(l)) {
080                    execute(l);
081                }
082            }
083        }
084
085        protected abstract void execute(Layer l);
086
087        @Override
088        public List<MultikeyInfo> getMultikeyCombinations() {
089            return LayerListDialog.getLayerInfoByClass(JumpToMarkerLayer.class);
090        }
091        
092        @Override
093        public MultikeyInfo getLastMultikeyAction() {
094            if (lastLayer != null)
095                return LayerListDialog.getLayerInfo(lastLayer.get());
096            else
097                return null;
098        }
099    }
100
101    public static final class JumpToNextMarker extends JumpToMarker {
102
103        public JumpToNextMarker(JumpToMarkerLayer layer) {
104            super(layer, Shortcut.registerShortcut("core_multikey:nextMarker", tr("Multikey: {0}", tr("Next marker")),
105                    KeyEvent.VK_J, Shortcut.ALT_CTRL));
106            putValue(SHORT_DESCRIPTION, tr("Jump to next marker"));
107            putValue(NAME, tr("Jump to next marker"));
108        }
109
110        @Override
111        protected void execute(Layer l) {
112            ((JumpToMarkerLayer)l).jumpToNextMarker();
113            setLastLayer(l);
114        }
115    }
116
117    public static final class JumpToPreviousMarker extends JumpToMarker {
118
119        public JumpToPreviousMarker(JumpToMarkerLayer layer) {
120            super(layer, Shortcut.registerShortcut("core_multikey:previousMarker", tr("Multikey: {0}", tr("Previous marker")),
121                    KeyEvent.VK_P, Shortcut.ALT_CTRL));
122            putValue(SHORT_DESCRIPTION, tr("Jump to previous marker"));
123            putValue(NAME, tr("Jump to previous marker"));
124        }
125
126        @Override
127        protected void execute(Layer l) {
128            ((JumpToMarkerLayer) l).jumpToPreviousMarker();
129            setLastLayer(l);
130        }
131    }
132}