Changeset 4595 in josm


Ignore:
Timestamp:
Nov 15, 2011 8:09:57 PM (19 months 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.