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 023 void jumpToPreviousMarker(); 024 } 025 026 private JumpToMarkerActions() { 027 // Hide default constructor for utils classes 028 } 029 030 private static volatile JumpToNextMarker jumpToNextMarkerAction; 031 private static volatile JumpToPreviousMarker jumpToPreviousMarkerAction; 032 033 public static void initialize() { 034 jumpToNextMarkerAction = new JumpToNextMarker(null); 035 jumpToPreviousMarkerAction = new JumpToPreviousMarker(null); 036 MultikeyActionsHandler.getInstance().addAction(jumpToNextMarkerAction); 037 MultikeyActionsHandler.getInstance().addAction(jumpToPreviousMarkerAction); 038 } 039 040 public static void unregisterActions() { 041 MultikeyActionsHandler.getInstance().removeAction(jumpToNextMarkerAction); 042 MultikeyActionsHandler.getInstance().removeAction(jumpToPreviousMarkerAction); 043 } 044 045 private abstract static class JumpToMarker extends AbstractAction implements MultikeyShortcutAction { 046 047 private final transient Layer layer; 048 private final transient Shortcut multikeyShortcut; 049 private transient WeakReference<Layer> lastLayer; 050 051 JumpToMarker(JumpToMarkerLayer layer, Shortcut shortcut) { 052 this.layer = (Layer) layer; 053 this.multikeyShortcut = shortcut; 054 this.multikeyShortcut.setAccelerator(this); 055 } 056 057 protected final void setLastLayer(Layer l) { 058 lastLayer = new WeakReference<>(l); 059 } 060 061 @Override 062 public Shortcut getMultikeyShortcut() { 063 return multikeyShortcut; 064 } 065 066 @Override 067 public void actionPerformed(ActionEvent e) { 068 execute(layer); 069 } 070 071 @Override 072 public void executeMultikeyAction(int index, boolean repeat) { 073 Layer l = LayerListDialog.getLayerForIndex(index); 074 if (l != null) { 075 if (l instanceof JumpToMarkerLayer) { 076 execute(l); 077 } 078 } else if (repeat && lastLayer != null) { 079 l = lastLayer.get(); 080 if (LayerListDialog.isLayerValid(l)) { 081 execute(l); 082 } 083 } 084 } 085 086 protected abstract void execute(Layer l); 087 088 @Override 089 public List<MultikeyInfo> getMultikeyCombinations() { 090 return LayerListDialog.getLayerInfoByClass(JumpToMarkerLayer.class); 091 } 092 093 @Override 094 public MultikeyInfo getLastMultikeyAction() { 095 if (lastLayer != null) 096 return LayerListDialog.getLayerInfo(lastLayer.get()); 097 else 098 return null; 099 } 100 } 101 102 public static final class JumpToNextMarker extends JumpToMarker { 103 104 public JumpToNextMarker(JumpToMarkerLayer layer) { 105 super(layer, Shortcut.registerShortcut("core_multikey:nextMarker", tr("Multikey: {0}", tr("Next marker")), 106 KeyEvent.VK_J, Shortcut.ALT_CTRL)); 107 putValue(SHORT_DESCRIPTION, tr("Jump to next marker")); 108 putValue(NAME, tr("Jump to next marker")); 109 } 110 111 @Override 112 protected void execute(Layer l) { 113 ((JumpToMarkerLayer) l).jumpToNextMarker(); 114 setLastLayer(l); 115 } 116 } 117 118 public static final class JumpToPreviousMarker extends JumpToMarker { 119 120 public JumpToPreviousMarker(JumpToMarkerLayer layer) { 121 super(layer, Shortcut.registerShortcut("core_multikey:previousMarker", tr("Multikey: {0}", tr("Previous marker")), 122 KeyEvent.VK_P, Shortcut.ALT_CTRL)); 123 putValue(SHORT_DESCRIPTION, tr("Jump to previous marker")); 124 putValue(NAME, tr("Jump to previous marker")); 125 } 126 127 @Override 128 protected void execute(Layer l) { 129 ((JumpToMarkerLayer) l).jumpToPreviousMarker(); 130 setLastLayer(l); 131 } 132 } 133}