Changeset 4595 in josm


Ignore:
Timestamp:
2011-11-15T20:09:57+01:00 (9 years ago)
Author:
jttt
Message:

Multikey keyboard shorcuts - shorcuts like Ctrl+Alt+S,n will toggle n-th layer visibility, added shorcuts also for Jump to next/previous marker. Shorcuts for other actions can be easily added.

Location:
trunk/src/org/openstreetmap/josm
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

    r4456 r4595  
    1616import java.beans.PropertyChangeEvent;
    1717import java.beans.PropertyChangeListener;
     18import java.lang.ref.WeakReference;
    1819import java.util.ArrayList;
    1920import java.util.Arrays;
     
    6465import org.openstreetmap.josm.tools.CheckParameterUtil;
    6566import org.openstreetmap.josm.tools.ImageProvider;
     67import org.openstreetmap.josm.tools.MultikeyActionsHandler;
     68import org.openstreetmap.josm.tools.MultikeyShortcutAction;
     69import org.openstreetmap.josm.tools.MultikeyShortcutAction.MultikeyInfo;
    6670import org.openstreetmap.josm.tools.Shortcut;
    6771
     
    8589            throw new IllegalStateException("Dialog was already created");
    8690        instance = new LayerListDialog(mapFrame);
     91
     92        MultikeyActionsHandler.getInstance().addAction(instance.new ShowHideLayerAction(false));
    8793    }
    8894
     
    113119    ActivateLayerAction activateLayerAction;
    114120
     121    //TODO This duplicates ShowHide actions functionality
    115122    /** stores which layer index to toggle and executes the ShowHide action if the layer is present */
    116123    private final class ToggleLayerIndexVisibility extends AbstractAction {
     
    123130            final Layer l = model.getLayer(model.getRowCount() - layerIndex);
    124131            if(l != null) {
    125                 new ShowHideLayerAction(l).actionPerformed(e);
     132                l.toggleVisible();
    126133            }
    127134        }
     
    258265
    259266        createLayout(layerList, true, Arrays.asList(new SideButton[] {
    260             new SideButton(moveUpAction),
    261             new SideButton(moveDownAction),
    262             new SideButton(activateLayerAction),
    263             new SideButton(showHideLayerAction),
    264             opacityButton,
    265             new SideButton(mergeLayerAction),
    266             new SideButton(duplicateLayerAction),
    267             new SideButton(deleteLayerAction, false)
     267                new SideButton(moveUpAction),
     268                new SideButton(moveDownAction),
     269                new SideButton(activateLayerAction),
     270                new SideButton(showHideLayerAction),
     271                opacityButton,
     272                new SideButton(mergeLayerAction),
     273                new SideButton(duplicateLayerAction),
     274                new SideButton(deleteLayerAction, false)
    268275        }));
    269276
     
    420427    }
    421428
    422     public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction {
    423         private  Layer layer;
    424 
    425         /**
    426          * Creates a {@see ShowHideLayerAction} which toggle the visibility of
    427          * a specific layer.
    428          *
    429          * @param layer  the layer. Must not be null.
    430          * @exception IllegalArgumentException thrown, if layer is null
    431          */
    432         public ShowHideLayerAction(Layer layer) throws IllegalArgumentException {
    433             this();
    434             putValue(NAME, tr("Show/Hide"));
    435             CheckParameterUtil.ensureParameterNotNull(layer, "layer");
    436             this.layer = layer;
    437             updateEnabledState();
    438         }
     429    public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction, MultikeyShortcutAction {
     430
     431        private WeakReference<Layer> lastLayer;
    439432
    440433        /**
     
    443436         *
    444437         */
    445         public ShowHideLayerAction() {
     438        public ShowHideLayerAction(boolean init) {
    446439            putValue(SMALL_ICON, ImageProvider.get("dialogs", "showhide"));
    447440            putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the selected layer."));
    448441            putValue("help", HelpUtil.ht("/Dialog/LayerList#ShowHideLayer"));
    449             updateEnabledState();
     442            putValue(ACCELERATOR_KEY, Shortcut.registerShortcut("core_multikey:showHideLayer", "", 'S', Shortcut.GROUP_DIRECT, KeyEvent.ALT_DOWN_MASK + KeyEvent.CTRL_DOWN_MASK).getKeyStroke());
     443            if (init) {
     444                updateEnabledState();
     445            }
     446        }
     447
     448        public ShowHideLayerAction() {
     449            this(true);
    450450        }
    451451
    452452        @Override
    453453        public void actionPerformed(ActionEvent e) {
    454             if (layer != null) {
    455                 layer.toggleVisible();
    456             } else {
    457                 for(Layer l : model.getSelectedLayers()) {
     454            for(Layer l : model.getSelectedLayers()) {
     455                l.toggleVisible();
     456            }
     457        }
     458
     459        @Override
     460        public void executeMultikeyAction(int index) {
     461            Layer l = LayerListDialog.getLayerForIndex(index);
     462            if (l != null) {
     463                l.toggleVisible();
     464                lastLayer = new WeakReference<Layer>(l);
     465            }
     466        }
     467
     468        @Override
     469        public void repeateLastMultikeyAction() {
     470            if (lastLayer != null) {
     471                Layer l = lastLayer.get();
     472                if (LayerListDialog.isLayerValid(l)) {
    458473                    l.toggleVisible();
    459474                }
     
    463478        @Override
    464479        public void updateEnabledState() {
    465             if (layer == null) {
    466                 setEnabled(! getModel().getSelectedLayers().isEmpty());
    467             } else {
    468                 setEnabled(true);
    469             }
     480            setEnabled(!model.getSelectedLayers().isEmpty());
    470481        }
    471482
     
    488499        public int hashCode() {
    489500            return getClass().hashCode();
     501        }
     502
     503        @Override
     504        public List<MultikeyInfo> getMultikeyCombinations() {
     505            return LayerListDialog.getLayerInfoByClass(Layer.class);
     506        }
     507
     508        @Override
     509        public MultikeyInfo getLastMultikeyAction() {
     510            if (lastLayer != null)
     511                return LayerListDialog.getLayerInfo(lastLayer.get());
     512            return null;
    490513        }
    491514    }
     
    905928                    }
    906929                }
    907                 if(c == null)
     930                if(c == null) {
    908931                    c = Main.pref.getUIColor(isSelected ? "Table.selectionForeground" : "Table.foreground");
     932                }
    909933                label.setForeground(c);
    910934            }
     
    14591483     */
    14601484    public ShowHideLayerAction createShowHideLayerAction() {
    1461         ShowHideLayerAction act = new ShowHideLayerAction();
     1485        ShowHideLayerAction act = new ShowHideLayerAction(true);
    14621486        act.putValue(Action.NAME, tr("Show/Hide"));
    14631487        return act;
     
    14971521        return new MergeAction(layer);
    14981522    }
     1523
     1524    public static Layer getLayerForIndex(int index) {
     1525
     1526        if (!Main.isDisplayingMapView())
     1527            return null;
     1528
     1529        List<Layer> layers = Main.map.mapView.getAllLayersAsList();
     1530
     1531        if (index < layers.size())
     1532            return layers.get(index);
     1533        else
     1534            return null;
     1535    }
     1536
     1537    public static List<MultikeyInfo> getLayerInfoByClass(Class<? extends Layer> layerClass) {
     1538
     1539        List<MultikeyInfo> result = new ArrayList<MultikeyShortcutAction.MultikeyInfo>();
     1540
     1541        if (!Main.isDisplayingMapView())
     1542            return result;
     1543
     1544        List<Layer> layers = Main.map.mapView.getAllLayersAsList();
     1545
     1546        int index = 0;
     1547        for (Layer l: layers) {
     1548            if (layerClass.isAssignableFrom(l.getClass())) {
     1549                result.add(new MultikeyInfo(index, l.getName()));
     1550            }
     1551            index++;
     1552        }
     1553
     1554        return result;
     1555    }
     1556
     1557    public static boolean isLayerValid(Layer l) {
     1558        if (l == null)
     1559            return false;
     1560
     1561        if (!Main.isDisplayingMapView())
     1562            return false;
     1563
     1564        return Main.map.mapView.getAllLayersAsList().indexOf(l) >= 0;
     1565    }
     1566
     1567    public static MultikeyInfo getLayerInfo(Layer l) {
     1568
     1569        if (l == null)
     1570            return null;
     1571
     1572        if (!Main.isDisplayingMapView())
     1573            return null;
     1574
     1575        int index = Main.map.mapView.getAllLayersAsList().indexOf(l);
     1576        if (index < 0)
     1577            return null;
     1578
     1579        return new MultikeyInfo(index, l.getName());
     1580    }
    14991581}
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r4282 r4595  
    1212import java.awt.Point;
    1313import java.awt.event.ActionEvent;
     14import java.awt.event.KeyEvent;
    1415import java.awt.event.MouseAdapter;
    1516import java.awt.event.MouseEvent;
    1617import java.io.File;
     18import java.lang.ref.WeakReference;
    1719import java.net.URL;
    1820import java.util.ArrayList;
     
    4244import org.openstreetmap.josm.tools.AudioPlayer;
    4345import org.openstreetmap.josm.tools.ImageProvider;
     46import org.openstreetmap.josm.tools.MultikeyActionsHandler;
     47import org.openstreetmap.josm.tools.MultikeyShortcutAction;
     48import org.openstreetmap.josm.tools.Shortcut;
    4449
    4550/**
     
    5964     * A list of markers.
    6065     */
    61     public final Collection<Marker> data;
     66    public final List<Marker> data;
    6267    private boolean mousePressed = false;
    6368    public GpxLayer fromLayer = null;
    64 
    65     @SuppressWarnings("unchecked")
     69    private Marker currentMarker;
     70
    6671    public MarkerLayer(GpxData indata, String name, File associatedFile, GpxLayer fromLayer) {
    6772
     
    125130    }
    126131
     132    static {
     133        MultikeyActionsHandler.getInstance().addAction(new JumpToNextMarker(null));
     134        MultikeyActionsHandler.getInstance().addAction(new JumpToPreviousMarker(null));
     135    }
     136
     137
    127138    /**
    128139     * Return a static icon.
     
    200211            components.add (new MoveAudio());
    201212        }
     213        components.add(new JumpToNextMarker(this));
     214        components.add(new JumpToPreviousMarker(this));
    202215        components.add(new RenameLayerAction(getAssociatedFile(), this));
    203216        components.add(SeparatorLayerAction.INSTANCE);
     
    292305        data.addAll(newData);
    293306        return ret;
     307    }
     308
     309    public void jumpToNextMarker() {
     310        if (currentMarker == null) {
     311            currentMarker = data.get(0);
     312        } else {
     313            boolean foundCurrent = false;
     314            for (Marker m: data) {
     315                if (foundCurrent) {
     316                    currentMarker = m;
     317                    break;
     318                } else if (currentMarker == m) {
     319                    foundCurrent = true;
     320                }
     321            }
     322        }
     323        Main.map.mapView.zoomTo(currentMarker.getEastNorth());
     324    }
     325
     326    public void jumpToPreviousMarker() {
     327        if (currentMarker == null) {
     328            currentMarker = data.get(data.size() - 1);
     329        } else {
     330            boolean foundCurrent = false;
     331            for (int i=data.size() - 1; i>=0; i--) {
     332                Marker m = data.get(i);
     333                if (foundCurrent) {
     334                    currentMarker = m;
     335                    break;
     336                } else if (currentMarker == m) {
     337                    foundCurrent = true;
     338                }
     339            }
     340        }
     341        Main.map.mapView.zoomTo(currentMarker.getEastNorth());
    294342    }
    295343
     
    393441    }
    394442
     443    public static final class JumpToNextMarker extends AbstractAction implements MultikeyShortcutAction {
     444
     445        private final MarkerLayer layer;
     446        private WeakReference<MarkerLayer> lastLayer;
     447
     448        public JumpToNextMarker(MarkerLayer layer) {
     449            putValue(ACCELERATOR_KEY, Shortcut.registerShortcut("core_multikey:nextMarker", "", 'J', Shortcut.GROUP_DIRECT, KeyEvent.ALT_DOWN_MASK + KeyEvent.CTRL_DOWN_MASK).getKeyStroke());
     450            putValue(SHORT_DESCRIPTION, tr("Jump to next marker"));
     451            putValue(NAME, tr("Jump to next marker"));
     452
     453            this.layer = layer;
     454        }
     455
     456        @Override
     457        public void actionPerformed(ActionEvent e) {
     458            execute(layer);
     459        }
     460
     461        @Override
     462        public void executeMultikeyAction(int index) {
     463            Layer l = LayerListDialog.getLayerForIndex(index);
     464            if (l != null && l instanceof MarkerLayer) {
     465                execute((MarkerLayer) l);
     466            }
     467        }
     468
     469        @Override
     470        public void repeateLastMultikeyAction() {
     471            if (lastLayer != null) {
     472                MarkerLayer l = lastLayer.get();
     473                if (LayerListDialog.isLayerValid(l)) {
     474                    execute(l);
     475                }
     476            }
     477        }
     478
     479        private void execute(MarkerLayer l) {
     480            l.jumpToNextMarker();
     481            lastLayer = new WeakReference<MarkerLayer>(l);
     482        }
     483
     484        @Override
     485        public List<MultikeyInfo> getMultikeyCombinations() {
     486            return LayerListDialog.getLayerInfoByClass(MarkerLayer.class);
     487        }
     488
     489        @Override
     490        public MultikeyInfo getLastMultikeyAction() {
     491            if (lastLayer != null)
     492                return LayerListDialog.getLayerInfo(lastLayer.get());
     493            else
     494                return null;
     495        }
     496
     497    }
     498
     499    public static final class JumpToPreviousMarker extends AbstractAction implements MultikeyShortcutAction {
     500
     501        private WeakReference<MarkerLayer> lastLayer;
     502        private final MarkerLayer layer;
     503
     504        public JumpToPreviousMarker(MarkerLayer layer) {
     505            this.layer = layer;
     506
     507            putValue(ACCELERATOR_KEY, Shortcut.registerShortcut("core_multikey:previousMarker", "", 'P', Shortcut.GROUP_DIRECT, KeyEvent.ALT_DOWN_MASK + KeyEvent.CTRL_DOWN_MASK).getKeyStroke());
     508            putValue(SHORT_DESCRIPTION, tr("Jump to previous marker"));
     509            putValue(NAME, tr("Jump to previous marker"));
     510        }
     511
     512        @Override
     513        public void actionPerformed(ActionEvent e) {
     514            execute(layer);
     515        }
     516
     517        @Override
     518        public void executeMultikeyAction(int index) {
     519            Layer l = LayerListDialog.getLayerForIndex(index);
     520            if (l != null && l instanceof MarkerLayer) {
     521                execute((MarkerLayer) l);
     522            }
     523        }
     524
     525        @Override
     526        public void repeateLastMultikeyAction() {
     527            if (lastLayer != null) {
     528                MarkerLayer l = lastLayer.get();
     529                if (LayerListDialog.isLayerValid(l)) {
     530                    execute(l);
     531                }
     532            }
     533        }
     534
     535        private void execute(MarkerLayer l) {
     536            l.jumpToPreviousMarker();
     537            lastLayer = new WeakReference<MarkerLayer>(l);
     538        }
     539
     540        @Override
     541        public List<MultikeyInfo> getMultikeyCombinations() {
     542            return LayerListDialog.getLayerInfoByClass(MarkerLayer.class);
     543        }
     544
     545        @Override
     546        public MultikeyInfo getLastMultikeyAction() {
     547            if (lastLayer != null)
     548                return LayerListDialog.getLayerInfo(lastLayer.get());
     549            else
     550                return null;
     551        }
     552
     553    }
     554
    395555    private class SynchronizeAudio extends AbstractAction {
    396556
     
    455615        }
    456616    }
     617
    457618}
  • trunk/src/org/openstreetmap/josm/tools/Shortcut.java

    r4418 r4595  
    22package org.openstreetmap.josm.tools;
    33
    4 import java.awt.Menu;
    54import static org.openstreetmap.josm.tools.I18n.tr;
    65
     
    209208    }
    210209
     210    @Override
     211    public String toString() {
     212        return getKeyText();
     213    }
     214
    211215    ///////////////////////////////
    212216    // everything's static below //
     
    504508                                :
    505509                                    tr("Using the shortcut ''{0}'' instead.\n\n", potentialShortcut.getKeyText())
    506                         )+
    507                         tr("(Hint: You can edit the shortcuts in the preferences.)"),
    508                         tr("Error"),
    509                         JOptionPane.ERROR_MESSAGE
    510         );
     510                                )+
     511                                tr("(Hint: You can edit the shortcuts in the preferences.)"),
     512                                tr("Error"),
     513                                JOptionPane.ERROR_MESSAGE
     514                );
    511515    }
    512516
Note: See TracChangeset for help on using the changeset viewer.