Ticket #1622: thepatch-withwhitespace.diff

File thepatch-withwhitespace.diff, 154.0 KB (added by Henry Loenwind, 18 years ago)

This is the same patch but WITH whitespace changes. Gives nicer results...

  • src/org/openstreetmap/josm/actions/PreferencesAction.java

     
    1414import org.openstreetmap.josm.Main;
    1515import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
    1616import org.openstreetmap.josm.tools.GBC;
     17import org.openstreetmap.josm.tools.ShortCut;
    1718
    1819/**
    1920 * Open the Preferences dialog.
     
    2627         * Create the preference action with "&Preferences" as label.
    2728         */
    2829        public PreferencesAction() {
    29                 super(tr("Preferences ..."), "preference", tr("Open a preferences page for global settings."), KeyEvent.VK_F12, 0, true);
     30                super(tr("Preferences ..."), "preference", tr("Open a preferences page for global settings."),
     31                ShortCut.registerShortCut("system:preferences", tr("Preferences"), KeyEvent.VK_F12, ShortCut.GROUP_DIRECT), true);
    3032        }
    3133
    3234        /**
  • src/org/openstreetmap/josm/actions/OpenAction.java

     
    2424import org.openstreetmap.josm.io.NmeaReader;
    2525import org.openstreetmap.josm.io.OsmReader;
    2626import org.xml.sax.SAXException;
     27import org.openstreetmap.josm.tools.ShortCut;
    2728
    2829/**
    2930 * Open a file chooser dialog and select an file to import. Then call the gpx-import
    3031 * driver. Finally open an internal frame into the main window with the gpx data shown.
    31  * 
     32 *
    3233 * @author imi
    3334 */
    3435public class OpenAction extends DiskAccessAction {
    35        
     36
    3637        /**
    3738         * Create an open action. The name is "Open a file".
    3839         */
    3940        public OpenAction() {
    40                 super(tr("Open ..."), "open", tr("Open a file."), KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK);
     41                super(tr("Open ..."), "open", tr("Open a file."),
     42                ShortCut.registerShortCut("system:open", tr("File: Open..."), KeyEvent.VK_O, ShortCut.GROUP_MENU));
    4143        }
    4244
    4345        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/AlignInCircleAction.java

     
    1919import org.openstreetmap.josm.data.osm.Node;
    2020import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2121import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.tools.ShortCut;
    2223
    2324/**
    2425 * Aligns all selected nodes within a circle. (Useful for roundabouts)
     
    2829public final class AlignInCircleAction extends JosmAction {
    2930
    3031        public AlignInCircleAction() {
    31                 super(tr("Align Nodes in Circle"), "aligncircle", tr("Move the selected nodes into a circle."), KeyEvent.VK_O, 0, true);
     32                super(tr("Align Nodes in Circle"), "aligncircle", tr("Move the selected nodes into a circle."),
     33                ShortCut.registerShortCut("tools:aligncircle", tr("Tool: Align in circle"), KeyEvent.VK_O, ShortCut.GROUP_EDIT), true);
    3234        }
    3335
    3436        public void actionPerformed(ActionEvent e) {
     
    3941                        if (osm instanceof Node)
    4042                                nodes.add((Node)osm);
    4143
    42                 // special case if no single nodes are selected and exactly one way is: 
     44                // special case if no single nodes are selected and exactly one way is:
    4345                // then use the way's nodes
    4446                if ((nodes.size() == 0) && (sel.size() == 1))
    4547                        for (OsmPrimitive osm : sel)
     
    6668                // Node "avn" now is central to all selected nodes.
    6769
    6870                // Now calculate the average distance to each node from the
    69                 // centre.  This method is ok as long as distances are short 
     71                // centre.  This method is ok as long as distances are short
    7072                // relative to the distance from the N or S poles.
    7173                double distances[] = new double[nodes.size()];
    7274                double avdist = 0, latd, lond;
  • src/org/openstreetmap/josm/actions/MoveAction.java

     
    1616import org.openstreetmap.josm.data.osm.Node;
    1717import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1818import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
     19import org.openstreetmap.josm.tools.ShortCut;
    1920
    2021/**
    2122 * Moves the selection
    22  * 
     23 *
    2324 * @author Frederik Ramm
    2425 */
    2526public class MoveAction extends JosmAction {
    2627
    2728        public enum Direction { UP, LEFT, RIGHT, DOWN }
    2829        private Direction myDirection;
    29        
     30
     31        // any better idea?
     32        private static Object calltosupermustbefirststatementinconstructor(Direction dir, boolean text) {
     33                ShortCut sc;
     34                String directiontext;
     35                if        (dir == Direction.UP)   {
     36                        directiontext = tr("up");
     37                        sc = ShortCut.registerShortCut("core:moveup",    tr("Move objects {0}", directiontext), KeyEvent.VK_UP,    ShortCut.GROUPS_ALT1+ShortCut.GROUP_DIRECT);
     38                } else if (dir == Direction.DOWN)  {
     39                        directiontext = tr("down");
     40                        sc = ShortCut.registerShortCut("core:movedown",  tr("Move objects {0}", directiontext), KeyEvent.VK_DOWN,  ShortCut.GROUPS_ALT1+ShortCut.GROUP_DIRECT);
     41                } else if (dir == Direction.LEFT)  {
     42                        directiontext = tr("left");
     43                        sc = ShortCut.registerShortCut("core:moveleft",  tr("Move objects {0}", directiontext), KeyEvent.VK_LEFT,  ShortCut.GROUPS_ALT1+ShortCut.GROUP_DIRECT);
     44                } else { //dir == Direction.RIGHT) {
     45                        directiontext = tr("right");
     46                        sc = ShortCut.registerShortCut("core:moveright", tr("Move objects {0}", directiontext), KeyEvent.VK_RIGHT, ShortCut.GROUPS_ALT1+ShortCut.GROUP_DIRECT);
     47                }
     48                if (text) {
     49                        return directiontext;
     50                } else {
     51                        return sc;
     52                }
     53        }
     54
    3055        public MoveAction(Direction dir) {
    31                 super(tr("Move"), null, tr("Moves Objects"),
    32                 (dir == Direction.UP) ? KeyEvent.VK_UP :
    33                 (dir == Direction.DOWN) ? KeyEvent.VK_DOWN :
    34                 (dir == Direction.LEFT) ? KeyEvent.VK_LEFT :
    35                 KeyEvent.VK_RIGHT, 0, true);
     56                super(tr("Move {0}", calltosupermustbefirststatementinconstructor(dir, true)), null,
     57                      tr("Moves Objects {0}", calltosupermustbefirststatementinconstructor(dir, true)),
     58                      (ShortCut)calltosupermustbefirststatementinconstructor(dir, false), true);
    3659                myDirection = dir;
    3760        }
    3861
    3962        public void actionPerformed(ActionEvent event) {
    40                
     63
    4164                // find out how many "real" units the objects have to be moved in order to
    4265                // achive an 1-pixel movement
    43                
     66
    4467                EastNorth en1 = Main.map.mapView.getEastNorth(100, 100);
    4568                EastNorth en2 = Main.map.mapView.getEastNorth(101, 101);
    46                
     69
    4770                double distx = en2.east() - en1.east();
    4871                double disty = en2.north() - en1.north();
    49                
     72
    5073                switch (myDirection) {
    51                 case UP: 
     74                case UP:
    5275                        distx = 0;
    5376                        disty = -disty;
    5477                        break;
     
    6184                default:
    6285                        disty = 0;
    6386                }
    64                
     87
    6588                Collection<OsmPrimitive> selection = Main.ds.getSelected();
    6689                Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);
    67                
     90
    6891                Command c = !Main.main.undoRedo.commands.isEmpty()
    6992                ? Main.main.undoRedo.commands.getLast() : null;
    7093
  • src/org/openstreetmap/josm/actions/JosmAction.java

     
    11// License: GPL. Copyright 2007 by Immanuel Scholz and others
    22package org.openstreetmap.josm.actions;
    33
     4import java.awt.event.InputEvent;
    45
    56import javax.swing.AbstractAction;
    67import javax.swing.JComponent;
     
    1011import org.openstreetmap.josm.data.osm.DataSet;
    1112import org.openstreetmap.josm.tools.Destroyable;
    1213import org.openstreetmap.josm.tools.ImageProvider;
    13 import org.openstreetmap.josm.tools.ShortCutLabel;
     14import org.openstreetmap.josm.tools.ShortCut;
    1415
    1516/**
    1617 * Base class helper for all Actions in JOSM. Just to make the life easier.
    17  * 
     18 *
    1819 * destroy() from interface Destroyable is called e.g. for MapModes, when the last layer has
    1920 * been removed and so the mapframe will be destroyed. For other JosmActions, destroy() may never
    2021 * be called (currently).
    21  * 
     22 *
    2223 * @author imi
    2324 */
    2425abstract public class JosmAction extends AbstractAction implements Destroyable {
    2526
     27        @Deprecated
    2628        public KeyStroke shortCut;
     29        protected ShortCut sc;
    2730
     31        public ShortCut getShortCut() {
     32                if (sc == null) {
     33                        sc = ShortCut.registerShortCut("core:none", "No Shortcut", 0, ShortCut.GROUP_NONE);
     34                        sc.setAutomatic(); // as this shortcut is shared by all action that don't want to have a shortcut,
     35                                           // we shouldn't allow the user to change it...
     36                }
     37                return sc;
     38        }
     39
     40        @Deprecated
    2841        public JosmAction(String name, String iconName, String tooltip, int shortCut, int modifier, boolean register) {
    2942                super(name, iconName == null ? null : ImageProvider.get(iconName));
    3043                setHelpId();
    31                 String scl = ShortCutLabel.name(shortCut, modifier);
    32                 putValue(SHORT_DESCRIPTION, "<html>"+tooltip+" <font size='-2'>"+scl+"</font>"+(scl.equals("")?"":"&nbsp;")+"</html>");
    3344                if (shortCut != 0) {
    34                         this.shortCut = KeyStroke.getKeyStroke(shortCut, modifier);
    35                         Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(this.shortCut, name);
     45                        int group = ShortCut.GROUP_LAYER; //GROUP_NONE;
     46                        if (((modifier & InputEvent.CTRL_MASK) != 0) || ((modifier & InputEvent.CTRL_DOWN_MASK) != 0)) {
     47                                group = ShortCut.GROUP_MENU;
     48                        } else if (modifier == 0) {
     49                                group = ShortCut.GROUP_EDIT;
     50                        }
     51                        sc = ShortCut.registerShortCut("auto:"+name, name, shortCut, group);
     52                        this.shortCut = sc.getKeyStroke();
     53                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), name);
    3654                        Main.contentPane.getActionMap().put(name, this);
    3755                }
    38         putValue("toolbar", iconName);
    39         if (register)
    40                 Main.toolbar.register(this);
     56                putValue(SHORT_DESCRIPTION, Main.platform.makeTooltip(tooltip, sc));
     57                putValue("toolbar", iconName);
     58    if (register)
     59        Main.toolbar.register(this);
    4160        }
    4261
     62        /**
     63         * The new super for all actions.
     64         *
     65         * Use this super constructor to setup your action. It takes 5 parameters:
     66         *
     67         * name - the action's text as displayed on the menu (if it is added to a menu)
     68         * iconName - the filename of the icon to use
     69         * tooltip - a longer description of the action that will be displayed in the tooltip. Please note
     70         *           that html is not supported for menu action on some platforms
     71         * shortCut - a ready-created shortcut object or null if you don't want a shortcut. But you always
     72         *            do want a shortcut, remember you can alway register it with group=none, so you
     73         *            won't be assigned a shurtcut unless the user configures one. If you pass null here,
     74         *            the user CANNOT configure a shortcut for your action.
     75         * register - register this action for the toolbar preferences?
     76         */
     77        public JosmAction(String name, String iconName, String tooltip, ShortCut shortCut, boolean register) {
     78                super(name, iconName == null ? null : ImageProvider.get(iconName));
     79                setHelpId();
     80                sc = shortCut;
     81                if (sc != null) {
     82                        this.shortCut = sc.getKeyStroke();
     83                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), name);
     84                        Main.contentPane.getActionMap().put(name, this);
     85                }
     86                putValue(SHORT_DESCRIPTION, Main.platform.makeTooltip(tooltip, sc));
     87                putValue("toolbar", iconName);
     88    if (register)
     89        Main.toolbar.register(this);
     90        }
     91
    4392        public void destroy() {
    4493                if (shortCut != null) {
    45                         Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).remove(shortCut);
    46                         Main.contentPane.getActionMap().remove(shortCut);
     94                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).remove(sc.getKeyStroke());
     95                        Main.contentPane.getActionMap().remove(sc.getKeyStroke());
    4796                }
    4897        }
    49        
     98
    5099        public JosmAction() {
    51100                setHelpId();
    52101        }
     
    57106        public void pasteBufferChanged(DataSet newPasteBuffer) {
    58107                return;
    59108        }
    60        
     109
    61110        /**
    62111         * needs to be overridden to be useful
    63112         */
    64113        public void addListener(JosmAction a) {
    65114                return;
    66115        }
    67        
     116
    68117        private void setHelpId() {
    69118                String helpId = "Action/"+getClass().getName().substring(getClass().getName().lastIndexOf('.')+1);
    70119                if (helpId.endsWith("Action"))
  • src/org/openstreetmap/josm/actions/SelectAllAction.java

     
    77import java.awt.event.KeyEvent;
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112public class SelectAllAction extends JosmAction {
    1213
    1314        public SelectAllAction() {
    14                 super(tr("Select All"),"selectall", tr("Select all undeleted objects in the data layer. This selects incomplete objects too."), KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK, true);
    15     }
     15                super(tr("Select All"),"selectall", tr("Select all undeleted objects in the data layer. This selects incomplete objects too."),
     16                ShortCut.registerShortCut("system:selectall", tr("Edit: Select all"), KeyEvent.VK_A, ShortCut.GROUP_MENU), true);
     17        }
    1618
    1719        public void actionPerformed(ActionEvent e) {
    1820                Main.ds.setSelected(Main.ds.allNonDeletedPhysicalPrimitives());
  • src/org/openstreetmap/josm/actions/ExitAction.java

     
    77import java.awt.event.KeyEvent;
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112/**
    1213 * Exit the application. May ask for permission first (if something has changed).
    13  * 
     14 *
    1415 * @author imi
    1516 */
    1617public class ExitAction extends JosmAction {
     
    1819         * Construct the action with "Exit" as label
    1920         */
    2021        public ExitAction() {
    21                 super(tr("Exit"), "exit", tr("Exit the application."), KeyEvent.VK_Q, KeyEvent.CTRL_DOWN_MASK, true);
     22                super(tr("Exit"), "exit", tr("Exit the application."),
     23                ShortCut.registerShortCut("system:menuexit", tr("Quit JOSM"), KeyEvent.VK_Q, ShortCut.GROUP_MENU), true);
    2224        }
    2325
    2426        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/CopyAction.java

     
    2323import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2424import org.openstreetmap.josm.data.osm.Way;
    2525import org.openstreetmap.josm.data.osm.visitor.Visitor;
     26import org.openstreetmap.josm.tools.ShortCut;
    2627
    2728public final class CopyAction extends JosmAction implements SelectionChangedListener {
    2829
    2930        private LinkedList<JosmAction> listeners;
    30        
     31
    3132        public CopyAction() {
    3233                super(tr("Copy"), "copy",
    3334                                tr("Copy selected objects to paste buffer."),
    34                                 KeyEvent.VK_C, KeyEvent.CTRL_MASK, true);
     35                                ShortCut.registerShortCut("system:copy", tr("Edit: Copy"), KeyEvent.VK_C, ShortCut.GROUP_MENU), true);
    3536                setEnabled(false);
    3637                DataSet.selListeners.add(this);
    3738                listeners = new LinkedList<JosmAction>();
     
    4041        @Override public void addListener(JosmAction a) {
    4142                listeners.add(a);
    4243        }
    43        
     44
    4445        public void actionPerformed(ActionEvent e) {
    4546                Collection<OsmPrimitive> sel = Main.ds.getSelected();
    46                 if (sel.isEmpty()) { 
     47                if (sel.isEmpty()) {
    4748                        JOptionPane.showMessageDialog(Main.parent,
    48                                         tr("Please select something to copy."));       
     49                                        tr("Please select something to copy."));
    4950                        return;
    5051                }
    5152
     
    5455                final HashMap<OsmPrimitive,OsmPrimitive> map = new HashMap<OsmPrimitive,OsmPrimitive>();
    5556                /* temporarily maps old nodes to new so we can do a true deep copy */
    5657
    57                 /* scan the selected objects, mapping them to copies; when copying a way or relation, 
     58                /* scan the selected objects, mapping them to copies; when copying a way or relation,
    5859                 * the copy references the copies of their child objects */
    5960                new Visitor(){
    6061                        public void visit(Node n) {
    61                                 /* check if already in pasteBuffer - e.g. two ways are selected which share a node; 
    62                                  * or a way and a node in that way is selected, we'll see it twice, once via the 
     62                                /* check if already in pasteBuffer - e.g. two ways are selected which share a node;
     63                                 * or a way and a node in that way is selected, we'll see it twice, once via the
    6364                                 * way and once directly; and so on. */
    6465                                if (map.containsKey(n)) { return; }
    6566                                Node nnew = new Node(n);
     
    106107
    107108                Main.pasteBuffer = pasteBuffer;
    108109                Main.main.menu.paste.setEnabled(true); /* now we have a paste buffer we can make paste available */
    109                
     110
    110111                for(JosmAction a : listeners) {
    111112                        a.pasteBufferChanged(Main.pasteBuffer);
    112113                }
  • src/org/openstreetmap/josm/actions/UnselectAllAction.java

     
    99import javax.swing.JComponent;
    1010
    1111import org.openstreetmap.josm.Main;
     12import org.openstreetmap.josm.tools.ShortCut;
    1213
    1314public class UnselectAllAction extends JosmAction {
    1415
    1516        public UnselectAllAction() {
    1617                super(tr("Unselect All"), "unselectall", tr("Unselect all objects."),
    17                         KeyEvent.VK_U, 0, true);
     18                ShortCut.registerShortCut("edit:unselectall", tr("Edit: Unselect all"), KeyEvent.VK_U, ShortCut.GROUP_EDIT), true);
     19                // this is not really GROUP_EDIT, but users really would complain if the yhad to reconfigure because we put
     20                // the correct group in
    1821
    1922                // Add extra shortcut C-S-a
    2023                Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    21                         KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK
    22                                 | KeyEvent.SHIFT_DOWN_MASK), tr("Unselect All"));
     24                ShortCut.registerShortCut("edit:unselectall2", tr("Edit: Unselect all (2)"), KeyEvent.VK_A, ShortCut.GROUP_MENU).getKeyStroke(),
     25                tr("Unselect All"));
    2326
    2427                // Add extra shortcut ESCAPE
    2528                /*
     
    2831                 * for now this is a reasonable approximation.
    2932                 */
    3033                Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    31                         KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
    32                         tr("Unselect All"));
     34                ShortCut.registerShortCut("edit:unselectall3", tr("Edit: Unselect all (3)"), KeyEvent.VK_ESCAPE, ShortCut.GROUP_DIRECT).getKeyStroke(),
     35                tr("Unselect All"));
    3336        }
    3437
    3538        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/ZoomInAction.java

     
    77import java.awt.event.KeyEvent;
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112public final class ZoomInAction extends JosmAction {
    1213
    1314        public ZoomInAction() {
    1415                super(tr("Zoom in"), "dialogs/zoomin", tr("Zoom in"),
    15                         KeyEvent.VK_PLUS, 0, true);
     16                ShortCut.registerShortCut("view:zoomin", tr("View: Zoom in"), KeyEvent.VK_PLUS, ShortCut.GROUP_DIRECT), true);
    1617                setEnabled(true);
    1718        }
    1819
  • src/org/openstreetmap/josm/actions/SplitWayAction.java

     
    3232import org.openstreetmap.josm.data.osm.Way;
    3333import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
    3434import org.openstreetmap.josm.data.osm.visitor.Visitor;
     35import org.openstreetmap.josm.tools.ShortCut;
    3536
    3637/**
    3738 * Splits a way into multiple ways (all identical except for their node list).
    38  * 
     39 *
    3940 * Ways are just split at the selected nodes.  The nodes remain in their
    4041 * original order.  Selected nodes at the end of a way are ignored.
    4142 */
     
    4950         * Create a new SplitWayAction.
    5051         */
    5152        public SplitWayAction() {
    52                 super(tr("Split Way"), "splitway", tr("Split a way at the selected node."), KeyEvent.VK_P, 0, true);
     53                super(tr("Split Way"), "splitway", tr("Split a way at the selected node."),
     54                ShortCut.registerShortCut("tools:splitway", tr("Tool: Split way"), KeyEvent.VK_P, ShortCut.GROUP_EDIT), true);
    5355                DataSet.selListeners.add(this);
    5456        }
    5557
    5658        /**
    5759         * Called when the action is executed.
    58          * 
     60         *
    5961         * This method performs an expensive check whether the selection clearly defines one
    6062         * of the split actions outlined above, and if yes, calls the splitWay method.
    6163         */
     
    8486                                // enties are not considered
    8587                        }
    8688                };
    87                
     89
    8890                for (OsmPrimitive p : selection)
    8991                        p.visit(splitVisitor);
    9092
     
    110112                                }
    111113                        }
    112114                        if (wayOccurenceCounter.isEmpty()) {
    113                                 JOptionPane.showMessageDialog(Main.parent, 
     115                                JOptionPane.showMessageDialog(Main.parent,
    114116                                                trn("The selected node is no inner part of any way.",
    115117                                                                "The selected nodes are no inner part of any way.", selectedNodes.size()));
    116118                                return;
     
    139141                                nds.remove(n);
    140142                        }
    141143                        if (!nds.isEmpty()) {
    142                                 JOptionPane.showMessageDialog(Main.parent, 
     144                                JOptionPane.showMessageDialog(Main.parent,
    143145                                                trn("The selected way does not contain the selected node.",
    144146                                                                "The selected way does not contain all the selected nodes.", selectedNodes.size()));
    145147                                return;
     
    150152                splitWay();
    151153        }
    152154
    153         /** 
     155        /**
    154156         * Checks if the selection consists of something we can work with.
    155157         * Checks only if the number and type of items selected looks good;
    156          * does not check whether the selected items are really a valid 
     158         * does not check whether the selected items are really a valid
    157159         * input for splitting (this would be too expensive to be carried
    158160         * out from the selectionChanged listener).
    159          */     
     161         */
    160162        private boolean checkSelection(Collection<? extends OsmPrimitive> selection) {
    161163                boolean way = false;
    162164                boolean node = false;
     
    229231                // build a list of commands, and also a new selection list
    230232                Collection<Command> commandList = new ArrayList<Command>(wayChunks.size());
    231233                Collection<Way> newSelection = new ArrayList<Way>(wayChunks.size());
    232                
     234
    233235                Iterator<List<Node>> chunkIt = wayChunks.iterator();
    234                
     236
    235237                // First, change the original way
    236238                Way changedWay = new Way(selectedWay);
    237239                changedWay.nodes.clear();
  • src/org/openstreetmap/josm/actions/ZoomOutAction.java

     
    77import java.awt.event.KeyEvent;
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112public final class ZoomOutAction extends JosmAction {
    1213
    1314        public ZoomOutAction() {
    1415                super(tr("Zoom out"), "dialogs/zoomout", tr("Zoom out"),
    15                         KeyEvent.VK_MINUS, 0, true);
     16                ShortCut.registerShortCut("view:zoomout", tr("View: Zoom out"), KeyEvent.VK_MINUS, ShortCut.GROUP_DIRECT), true);
    1617                setEnabled(true);
    1718        }
    1819
  • src/org/openstreetmap/josm/actions/SaveAsAction.java

     
    88import java.io.File;
    99
    1010import org.openstreetmap.josm.gui.layer.Layer;
     11import org.openstreetmap.josm.tools.ShortCut;
    1112
    1213/**
    1314 * Export the data.
    14  * 
     15 *
    1516 * @author imi
    1617 */
    1718public class SaveAsAction extends SaveActionBase {
    18    
     19
    1920        /**
    2021         * Construct the action with "Save" as label.
    2122         * @param layer Save this layer.
    2223         */
    2324        public SaveAsAction(Layer layer) {
    24                 super(tr("Save as ..."), "save_as", tr("Save the current data to a new file."), KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK, layer);
     25                super(tr("Save as ..."), "save_as", tr("Save the current data to a new file."),
     26                ShortCut.registerShortCut("system:saveas", tr("File: Save as..."), KeyEvent.VK_S, ShortCut.GROUP_MENU), layer);
    2527        }
    26        
     28
    2729        @Override protected File getFile(Layer layer) {
    2830                return openFileDialog(layer);
    2931        }
  • src/org/openstreetmap/josm/actions/audio/AudioBackAction.java

     
    1010import org.openstreetmap.josm.actions.JosmAction;
    1111import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
    1212import org.openstreetmap.josm.tools.AudioPlayer;
     13import org.openstreetmap.josm.tools.ShortCut;
    1314
    1415public class AudioBackAction extends JosmAction {
    1516
    1617        private double amount; // note, normally negative, i.e. jump backwards in time
    17        
     18
    1819        public AudioBackAction() {
    19                 super(tr("Back"), "audio-back", tr("Jump back."), KeyEvent.VK_F6, 0, true);
     20                super(tr("Back"), "audio-back", tr("Jump back."),
     21                ShortCut.registerShortCut("audio:back", tr("Audio: Back"), KeyEvent.VK_F6, ShortCut.GROUP_DIRECT), true);
    2022                try {
    2123                        amount = - Double.parseDouble(Main.pref.get("audio.forwardbackamount","10.0"));
    2224                } catch (NumberFormatException e) {
  • src/org/openstreetmap/josm/actions/audio/AudioFwdAction.java

     
    1010import org.openstreetmap.josm.actions.JosmAction;
    1111import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
    1212import org.openstreetmap.josm.tools.AudioPlayer;
     13import org.openstreetmap.josm.tools.ShortCut;
    1314
    1415public class AudioFwdAction extends JosmAction {
    1516
    1617        private double amount;
    17        
     18
    1819        public AudioFwdAction() {
    19                 super(tr("Forward"), "audio-fwd", tr("Jump forward"), KeyEvent.VK_F7, 0, true);
     20                super(tr("Forward"), "audio-fwd", tr("Jump forward"),
     21                ShortCut.registerShortCut("audio:forward", tr("Audio: Forward"), KeyEvent.VK_F7, ShortCut.GROUP_DIRECT), true);
    2022                try {
    2123                        amount = Double.parseDouble(Main.pref.get("audio.forwardbackamount","10.0"));
    2224                } catch (NumberFormatException e) {
  • src/org/openstreetmap/josm/actions/audio/AudioFastSlowAction.java

     
    66import org.openstreetmap.josm.Main;
    77import org.openstreetmap.josm.actions.JosmAction;
    88import org.openstreetmap.josm.tools.AudioPlayer;
     9import org.openstreetmap.josm.tools.ShortCut;
    910
    1011abstract public class AudioFastSlowAction extends JosmAction {
    1112
    1213        private double multiplier;
    13        
     14
     15        public AudioFastSlowAction(String name, String iconName, String tooltip, ShortCut shortcut, boolean fast) {
     16                super(name, iconName, tooltip, shortcut, true);
     17                try {
     18                        multiplier = Double.parseDouble(Main.pref.get("audio.fastfwdmultiplier","1.3"));
     19                } catch (NumberFormatException e) {
     20                        multiplier = 1.3;
     21                }
     22                if (! fast)
     23                        multiplier = 1.0 / multiplier;
     24        }
     25
     26        @Deprecated
    1427        public AudioFastSlowAction(String name, String iconName, String tooltip, int shortcut, int modifier, boolean fast) {
    1528                super(name, iconName, tooltip, shortcut, modifier, true);
    1629                try {
     
    1831                } catch (NumberFormatException e) {
    1932                        multiplier = 1.3;
    2033                }
    21                 if (! fast) 
     34                if (! fast)
    2235                        multiplier = 1.0 / multiplier;
    2336        }
    2437
    2538        public void actionPerformed(ActionEvent e) {
    2639                double speed = AudioPlayer.speed();
    27                 if (speed * multiplier <= 0.1) 
     40                if (speed * multiplier <= 0.1)
    2841                        return;
    2942                try {
    3043                        if (AudioPlayer.playing() || AudioPlayer.paused())
  • src/org/openstreetmap/josm/actions/audio/AudioPlayPauseAction.java

     
    1010import org.openstreetmap.josm.actions.JosmAction;
    1111import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
    1212import org.openstreetmap.josm.tools.AudioPlayer;
     13import org.openstreetmap.josm.tools.ShortCut;
    1314
    1415public class AudioPlayPauseAction extends JosmAction {
    1516
    1617        public AudioPlayPauseAction() {
    17                 super(tr("Play/pause"), "audio-playpause", tr("Play/pause audio."), KeyEvent.VK_PERIOD, 0, true);
     18                super(tr("Play/pause"), "audio-playpause", tr("Play/pause audio."),
     19                ShortCut.registerShortCut("audio:pause", tr("Audio: Play/Pause"), KeyEvent.VK_PERIOD, ShortCut.GROUP_DIRECT), true);
    1820        }
    1921
    2022        public void actionPerformed(ActionEvent e) {
     
    3436                } catch (Exception ex) {
    3537                        AudioPlayer.audioMalfunction(ex);
    3638                }
    37         }       
     39        }
    3840}
  • src/org/openstreetmap/josm/actions/audio/AudioFasterAction.java

     
    22package org.openstreetmap.josm.actions.audio;
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
     5import org.openstreetmap.josm.tools.ShortCut;
    56
    67import java.awt.event.KeyEvent;
    78
    89public class AudioFasterAction extends AudioFastSlowAction {
    9        
     10
    1011        public AudioFasterAction() {
    11                 super(tr("Faster"), "audio-faster", tr("Faster Forward"), KeyEvent.VK_F9, 0, true);
     12                super(tr("Faster"), "audio-faster", tr("Faster Forward"),
     13                ShortCut.registerShortCut("audio:faster", tr("Audio: Faster"), KeyEvent.VK_F9, ShortCut.GROUP_DIRECT), true);
    1214        }
    1315}
  • src/org/openstreetmap/josm/actions/audio/AudioSlowerAction.java

     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.awt.event.KeyEvent;
     7import org.openstreetmap.josm.tools.ShortCut;
    78
    89public class AudioSlowerAction extends AudioFastSlowAction {
    9        
     10
    1011        public AudioSlowerAction() {
    11                 super(tr("Slower"), "audio-slower", tr("Slower Forward"), KeyEvent.VK_F9, KeyEvent.SHIFT_MASK, false);
     12                super(tr("Slower"), "audio-slower", tr("Slower Forward"),
     13                ShortCut.registerShortCut("audio:slower", tr("Audio: Slower"), KeyEvent.VK_F9, ShortCut.GROUP_DIRECT), true);
    1214        }
    1315}
  • src/org/openstreetmap/josm/actions/audio/AudioPrevAction.java

     
    88
    99import org.openstreetmap.josm.actions.JosmAction;
    1010import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
     11import org.openstreetmap.josm.tools.ShortCut;
    1112
    1213public class AudioPrevAction extends JosmAction {
    1314
    1415        public AudioPrevAction() {
    15                 super(tr("Previous Marker"), "audio-prev", tr("Play previous marker."), KeyEvent.VK_F5, 0, true);
     16                super(tr("Previous Marker"), "audio-prev", tr("Play previous marker."),
     17                ShortCut.registerShortCut("audio:prev", tr("Audio: Previous"), KeyEvent.VK_F5, ShortCut.GROUP_DIRECT), true);
    1618        }
    1719
    1820        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/audio/AudioNextAction.java

     
    88
    99import org.openstreetmap.josm.actions.JosmAction;
    1010import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
     11import org.openstreetmap.josm.tools.ShortCut;
    1112
    1213public class AudioNextAction extends JosmAction {
    1314
    1415        public AudioNextAction() {
    15                 super(tr("Next Marker"), "audio-next", tr("Play next marker."), KeyEvent.VK_F8, 0, true);
     16                super(tr("Next Marker"), "audio-next", tr("Play next marker."),
     17                ShortCut.registerShortCut("audio:next", tr("Audio: Next"), KeyEvent.VK_F8, ShortCut.GROUP_DIRECT), true);
    1618        }
    1719
    1820        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/JoinNodeWayAction.java

     
    2222import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2323import org.openstreetmap.josm.data.osm.Way;
    2424import org.openstreetmap.josm.data.osm.WaySegment;
     25import org.openstreetmap.josm.tools.ShortCut;
    2526
    2627public class JoinNodeWayAction extends JosmAction {
    2728        public JoinNodeWayAction() {
    28             super(tr("Join node to way"), "joinnodeway",
    29                         tr("Join a node into the nearest way segments"), KeyEvent.VK_J, 0, true);
     29            super(tr("Join node to way"), "joinnodeway", tr("Join a node into the nearest way segments"),
     30                        ShortCut.registerShortCut("tools:joinnodeway", tr("Tool: Join node to way"), KeyEvent.VK_J, ShortCut.GROUP_EDIT), true);
    3031        }
    3132
    3233        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/search/SearchAction.java

     
    2121import org.openstreetmap.josm.actions.JosmAction;
    2222import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2323import org.openstreetmap.josm.tools.GBC;
     24import org.openstreetmap.josm.tools.ShortCut;
    2425
    2526public class SearchAction extends JosmAction {
    2627
     
    3536    private static SearchSetting lastSearch = null;
    3637
    3738    public SearchAction() {
    38         super(tr("Search ..."), "dialogs/search", tr("Search for objects."), KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK,
    39                 true);
     39        super(tr("Search ..."), "dialogs/search", tr("Search for objects."),
     40        ShortCut.registerShortCut("system:find", tr("Search..."), KeyEvent.VK_F, ShortCut.GROUP_HOTKEY), true);
    4041    }
    4142
    4243    public void actionPerformed(ActionEvent e) {
     
    104105    }
    105106
    106107    /**
    107      * Adds the search specified by the settings in <code>s</code> to the 
     108     * Adds the search specified by the settings in <code>s</code> to the
    108109     * search history and performs the search.
    109      * 
     110     *
    110111     * @param s
    111112     */
    112113    public static void searchWithHistory(SearchSetting s) {
  • src/org/openstreetmap/josm/actions/AlignInLineAction.java

     
    1717import org.openstreetmap.josm.data.osm.Node;
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1919import org.openstreetmap.josm.data.osm.Way;
     20import org.openstreetmap.josm.tools.ShortCut;
    2021
    2122/**
    2223 * Aligns all selected nodes into a straight line (useful for
    2324 * roads that should be straight, but have side roads and
    2425 * therefore need multiple nodes)
    25  * 
     26 *
    2627 * @author Matthew Newton
    2728 */
    2829public final class AlignInLineAction extends JosmAction {
    2930
    3031        public AlignInLineAction() {
    31                 super(tr("Align Nodes in Line"), "alignline", tr("Move the selected nodes onto a line."), KeyEvent.VK_L, 0, true);
     32                super(tr("Align Nodes in Line"), "alignline", tr("Move the selected nodes onto a line."),
     33                ShortCut.registerShortCut("tools:alignline", tr("Tool: Align in line"), KeyEvent.VK_L, ShortCut.GROUP_EDIT), true);
    3234        }
    3335
    3436        /**
     
    4547                                nodes.add((Node)osm);
    4648                                itnodes.add((Node)osm);
    4749                        }
    48                 // special case if no single nodes are selected and exactly one way is: 
     50                // special case if no single nodes are selected and exactly one way is:
    4951                // then use the way's nodes
    5052                if ((nodes.size() == 0) && (sel.size() == 1))
    5153                        for (OsmPrimitive osm : sel)
  • src/org/openstreetmap/josm/actions/ReverseWayAction.java

     
    2424import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2525import org.openstreetmap.josm.data.osm.Way;
    2626import org.openstreetmap.josm.data.osm.visitor.Visitor;
     27import org.openstreetmap.josm.tools.ShortCut;
    2728
    2829public final class ReverseWayAction extends JosmAction {
    2930
    3031        public ReverseWayAction() {
    31                 super(tr("Reverse ways"), "wayflip",
    32                         tr("Reverse the direction of all selected ways."),
    33                         KeyEvent.VK_R, 0, true);
     32                super(tr("Reverse ways"), "wayflip", tr("Reverse the direction of all selected ways."),
     33                ShortCut.registerShortCut("tools:reverse", tr("Tool: Reverse way"), KeyEvent.VK_R, ShortCut.GROUP_EDIT), true);
    3434        }
    3535
    3636        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/UnGlueAction.java

     
    2525import org.openstreetmap.josm.data.osm.Relation;
    2626import org.openstreetmap.josm.data.osm.RelationMember;
    2727import org.openstreetmap.josm.data.osm.Way;
     28import org.openstreetmap.josm.tools.ShortCut;
    2829
    2930/**
    3031 * Dupe a node that is used my multiple ways, so each way has its own node.
     
    4344         * Create a new SplitWayAction.
    4445         */
    4546        public UnGlueAction() {
    46                 super(tr("UnGlue Ways"), "unglueways", tr("Duplicate the selected node so each way using it has its own copy."), KeyEvent.VK_G, 0, true);
     47                super(tr("UnGlue Ways"), "unglueways", tr("Duplicate the selected node so each way using it has its own copy."),
     48                ShortCut.registerShortCut("tools:unglue", tr("Tool: Unglue"), KeyEvent.VK_G, ShortCut.GROUP_EDIT), true);
    4749                DataSet.selListeners.add(this);
    4850        }
    4951
     
    8486         * out from the selectionChanged listener).
    8587         */
    8688        private boolean checkSelection(Collection<? extends OsmPrimitive> selection) {
    87                
     89
    8890                int size = selection.size();
    8991                if (size < 1 || size > 2)
    9092                        return false;
    91                
     93
    9294                selectedNode = null;
    9395                selectedWay = null;
    94                
     96
    9597                for (OsmPrimitive p : selection) {
    9698                        if (p instanceof Node) {
    9799                                selectedNode = (Node) p;
     
    99101                                        return size == 1 || selectedWay.nodes.contains(selectedNode);
    100102                        } else if (p instanceof Way) {
    101103                                selectedWay = (Way) p;
    102                                 if (size == 2 && selectedNode != null) 
     104                                if (size == 2 && selectedNode != null)
    103105                                        return selectedWay.nodes.contains(selectedNode);
    104106                        }
    105107                }
    106                
     108
    107109                return false;
    108110        }
    109111
     
    132134
    133135                return firstway;
    134136        }
    135        
     137
    136138        /**
    137139         * see above
    138140         */
     
    142144                List<Node> newNodes = new LinkedList<Node>();
    143145
    144146                if (selectedWay == null) {
    145                        
     147
    146148                        boolean firstway = true;
    147149                        // modify all ways containing the nodes
    148150                        for (Way w : Main.ds.ways) {
    149151                                if (w.deleted || w.incomplete || w.nodes.size() < 1) continue;
    150152                                if (!w.nodes.contains(selectedNode)) continue;
    151        
     153
    152154                                firstway = modifyWay(firstway, w, cmds, newNodes);
    153155                        }
    154156                } else {
  • src/org/openstreetmap/josm/actions/GpxExportAction.java

     
    3333import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    3434import org.openstreetmap.josm.io.GpxWriter;
    3535import org.openstreetmap.josm.tools.GBC;
     36import org.openstreetmap.josm.tools.ShortCut;
    3637
    3738/**
    3839 * Exports data to gpx.
     
    4445        private final Layer layer;
    4546
    4647        public GpxExportAction(Layer layer) {
    47                 super(tr("Export to GPX ..."), "exportgpx", tr("Export the data to GPX file."), KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK);
     48                super(tr("Export to GPX ..."), "exportgpx", tr("Export the data to GPX file."),
     49                ShortCut.registerShortCut("file:exportgpx", tr("Export to GPX"), KeyEvent.VK_E, ShortCut.GROUP_MENU));
    4850                this.layer = layer;
    4951        }
    5052
     
    7072                        fn += ".gpx";
    7173                        file = new File(fn);
    7274                }
    73                
     75
    7476                // open the dialog asking for options
    7577                JPanel p = new JPanel(new GridBagLayout());
    7678
     
    7981                desc.setWrapStyleWord(true);
    8082                desc.setLineWrap(true);
    8183                p.add(new JScrollPane(desc), GBC.eop().fill(GBC.BOTH));
    82                
     84
    8385                JCheckBox author = new JCheckBox(tr("Add author information"), Main.pref.getBoolean("lastAddAuthor", true));
    8486                author.setSelected(true);
    8587                p.add(author, GBC.eol());
     
    104106                JLabel warning = new JLabel("<html><font size='-2'>&nbsp;</html");
    105107                p.add(warning, GBC.eol().fill(GBC.HORIZONTAL).insets(15,0,0,0));
    106108                addDependencies(author, authorName, email, copyright, predefined, copyrightYear, nameLabel, emailLabel, copyrightLabel, copyrightYearLabel, warning);
    107                
     109
    108110                p.add(new JLabel(tr("Keywords")), GBC.eol());
    109111                JTextField keywords = new JTextField();
    110112                p.add(keywords, GBC.eop().fill(GBC.HORIZONTAL));
     
    112114                int answer = JOptionPane.showConfirmDialog(Main.parent, p, tr("Export options"), JOptionPane.OK_CANCEL_OPTION);
    113115                if (answer != JOptionPane.OK_OPTION)
    114116                        return;
    115                
     117
    116118                Main.pref.put("lastAddAuthor", author.isSelected());
    117119                if (authorName.getText().length() != 0)
    118120                        Main.pref.put("lastAuthorName", authorName.getText());
     
    135137                } catch (IOException x) {
    136138                        x.printStackTrace();
    137139                        JOptionPane.showMessageDialog(Main.parent, tr("Error while exporting {0}", fn)+":\n"+x.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE);
    138                 }               
     140                }
    139141        }
    140        
     142
    141143        /**
    142144         * Add all those listeners to handle the enable state of the fields.
    143          * @param copyrightYearLabel 
    144          * @param copyrightLabel 
    145          * @param emailLabel 
    146          * @param nameLabel 
    147          * @param warning 
     145         * @param copyrightYearLabel
     146         * @param copyrightLabel
     147         * @param emailLabel
     148         * @param nameLabel
     149         * @param warning
    148150         */
    149151        private static void addDependencies(
    150                         final JCheckBox author, 
     152                        final JCheckBox author,
    151153                        final JTextField authorName,
    152154                        final JTextField email,
    153155                        final JTextField copyright,
     
    158160                        final JLabel copyrightLabel,
    159161                        final JLabel copyrightYearLabel,
    160162                        final JLabel warning) {
    161                
     163
    162164                ActionListener authorActionListener = new ActionListener(){
    163165                        public void actionPerformed(ActionEvent e) {
    164166                                boolean b = author.isSelected();
     
    182184                                        }
    183185                                };
    184186                authorName.addKeyListener(authorNameListener);
    185                
     187
    186188                predefined.addActionListener(new ActionListener(){
    187189                        public void actionPerformed(ActionEvent e) {
    188190                                JList l = new JList(new String[]{"Creative Commons By-SA", "public domain", "GNU Lesser Public License (LGPL)", "BSD License (MIT/X11)"});
  • src/org/openstreetmap/josm/actions/DeleteAction.java

     
    77import java.awt.event.KeyEvent;
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112public final class DeleteAction extends JosmAction {
    1213
    1314        public DeleteAction() {
    1415                super(tr("Delete"), "dialogs/delete", tr("Delete selected objects."),
    15                         KeyEvent.VK_DELETE, 0, true);
     16                ShortCut.registerShortCut("system:delete", tr("Edit: Delete"), KeyEvent.VK_DELETE, ShortCut.GROUP_DIRECT), true);
    1617                setEnabled(true);
    1718        }
    1819
  • src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java

     
    1515import org.openstreetmap.josm.data.osm.WaySegment;
    1616import org.openstreetmap.josm.gui.MapFrame;
    1717import org.openstreetmap.josm.tools.ImageProvider;
     18import org.openstreetmap.josm.tools.ShortCut;
    1819
    1920/**
    2021 * An action that enables the user to delete nodes and other objects.
    2122 *
    22  * The user can click on an object, which gets deleted if possible. When Ctrl is 
    23  * pressed when releasing the button, the objects and all its references are 
     23 * The user can click on an object, which gets deleted if possible. When Ctrl is
     24 * pressed when releasing the button, the objects and all its references are
    2425 * deleted. The exact definition of "all its references" are in
    2526 * {@link #deleteWithReferences deleteWithReferences}.
    2627 *
     
    2930 *
    3031 * If the user enters the mapmode and any object is selected, all selected
    3132 * objects that can be deleted will.
    32  * 
     33 *
    3334 * @author imi
    3435 */
    3536public class DeleteAction extends MapMode {
     
    4041         */
    4142        public DeleteAction(MapFrame mapFrame) {
    4243                super(tr("Delete Mode"),
    43                                 "delete", 
    44                                 tr("Delete nodes or ways."), 
    45                                 KeyEvent.VK_D,
    46                                 mapFrame, 
     44                                "delete",
     45                                tr("Delete nodes or ways."),
     46                                ShortCut.registerShortCut("mapmode:delete", tr("Delete mode"), KeyEvent.VK_D, ShortCut.GROUP_EDIT),
     47                                mapFrame,
    4748                                ImageProvider.getCursor("normal", "delete"));
    4849        }
    4950
     
    5758                Main.map.mapView.removeMouseListener(this);
    5859        }
    5960
    60        
     61
    6162        @Override public void actionPerformed(ActionEvent e) {
    6263                super.actionPerformed(e);
    6364                if(!Main.map.mapView.isDrawableLayer())
     
    9697                boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    9798                boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    9899                boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
    99                
     100
    100101                OsmPrimitive sel = Main.map.mapView.getNearestNode(e.getPoint());
    101102                Command c = null;
    102103                if (sel == null) {
    103104                        WaySegment ws = Main.map.mapView.getNearestWaySegment(e.getPoint());
    104105                        if (ws != null) {
    105106                                if (shift) {
    106                                         c = DeleteCommand.deleteWaySegment(ws); 
     107                                        c = DeleteCommand.deleteWaySegment(ws);
    107108                                } else if (ctrl) {
    108109                                        c = DeleteCommand.deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way));
    109110                                } else {
     
    121122
    122123                Main.map.mapView.repaint();
    123124        }
    124        
     125
    125126        @Override public String getModeHelpText() {
    126127                return tr("Click to delete. Shift: delete way segment. Alt: don't delete unused nodes when deleting a way. Ctrl: delete referring objects.");
    127128        }
  • src/org/openstreetmap/josm/actions/mapmode/MapMode.java

     
    1111import org.openstreetmap.josm.actions.JosmAction;
    1212import org.openstreetmap.josm.gui.MapFrame;
    1313import org.openstreetmap.josm.tools.ImageProvider;
     14import org.openstreetmap.josm.tools.ShortCut;
    1415
    1516/**
    1617 * A class implementing MapMode is able to be selected as an mode for map editing.
    1718 * As example scrolling the map is a MapMode, connecting Nodes to new Ways
    1819 * is another.
    19  * 
     20 *
    2021 * MapModes should register/deregister all necessary listeners on the map's view
    21  * control. 
     22 * control.
    2223 */
    2324abstract public class MapMode extends JosmAction implements MouseListener, MouseMotionListener {
    2425        private final Cursor cursor;
     
    2728        /**
    2829         * Constructor for mapmodes without an menu
    2930         */
     31        public MapMode(String name, String iconName, String tooltip, ShortCut shortCut, MapFrame mapFrame, Cursor cursor) {
     32                super(name, "mapmode/"+iconName, tooltip, shortCut, false);
     33                this.cursor = cursor;
     34                putValue("active", false);
     35        }
     36
     37        /**
     38         * Constructor for mapmodes without an menu
     39         */
     40         @Deprecated
    3041        public MapMode(String name, String iconName, String tooltip, int keystroke, MapFrame mapFrame, Cursor cursor) {
    3142                super(name, "mapmode/"+iconName, tooltip, keystroke, 0, false);
    3243                this.cursor = cursor;
     
    5869                Main.map.statusLine.setHelpText(getModeHelpText());
    5970                Main.map.statusLine.repaint();
    6071        }
    61        
     72
    6273        public String getModeHelpText() {
    6374                return "";
    6475        }
  • src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java

     
    1212import org.openstreetmap.josm.gui.SelectionManager;
    1313import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
    1414import org.openstreetmap.josm.tools.ImageProvider;
     15import org.openstreetmap.josm.tools.ShortCut;
    1516
    1617/**
    17  * Enable the zoom mode within the MapFrame. 
    18  * 
    19  * Holding down the left mouse button select a rectangle with the same aspect 
     18 * Enable the zoom mode within the MapFrame.
     19 *
     20 * Holding down the left mouse button select a rectangle with the same aspect
    2021 * ratio than the current map view.
    2122 * Holding down left and right let the user move the former selected rectangle.
    2223 * Releasing the left button zoom to the selection.
    23  * 
    24  * Rectangle selections with either height or width smaller than 3 pixels 
     24 *
     25 * Rectangle selections with either height or width smaller than 3 pixels
    2526 * are ignored.
    26  * 
     27 *
    2728 * @author imi
    2829 */
    2930public class ZoomAction extends MapMode implements SelectionEnded {
     
    4445         * @param mapFrame The MapFrame, whose zoom mode should be enabled.
    4546         */
    4647        public ZoomAction(MapFrame mapFrame) {
    47                 super(tr("Zoom"), "zoom", tr("Zoom and move map"), KeyEvent.VK_Z, mapFrame, ImageProvider.getCursor("normal", "zoom"));
     48                super(tr("Zoom"), "zoom", tr("Zoom and move map"),
     49                ShortCut.registerShortCut("mapmode:zoom", tr("Zoom mode"), KeyEvent.VK_Z, ShortCut.GROUP_EDIT),
     50                mapFrame, ImageProvider.getCursor("normal", "zoom"));
    4851                mv = mapFrame.mapView;
    4952                selectionManager = new SelectionManager(this, true, mv);
    5053        }
     
    6972                super.exitMode();
    7073                selectionManager.unregister(mv);
    7174        }
    72        
     75
    7376        @Override public String getModeHelpText() {
    7477                return tr("Zoom by dragging or Ctrl+. or Ctrl+,; move with Ctrl+up,left,down,right; move zoom with right button");
    7578        }
  • src/org/openstreetmap/josm/actions/mapmode/PlayHeadDragMode.java

     
    1111import org.openstreetmap.josm.Main;
    1212import org.openstreetmap.josm.data.coor.EastNorth;
    1313import org.openstreetmap.josm.gui.layer.markerlayer.PlayHeadMarker;
     14import org.openstreetmap.josm.tools.ShortCut;
    1415
    1516/**
    1617 * Singleton marker class to track position of audio.
    17  * 
     18 *
    1819 * @author david.earl
    1920 *
    2021 */
     
    2425        private Point mousePos = null;
    2526        private Point mouseStart = null;
    2627        private PlayHeadMarker playHeadMarker = null;
    27        
     28
    2829        public PlayHeadDragMode(PlayHeadMarker m) {
    29                 super("play head drag", "playheaddrag", "play head trag", 0, Main.map, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
     30                super("play head drag", "playheaddrag", "play head drag", null,
     31                Main.map, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
    3032                playHeadMarker = m;
    3133        }
    32        
     34
    3335        @Override public void enterMode() {
    3436                super.enterMode();
    3537                Main.map.mapView.addMouseListener(this);
     
    7375                } else {
    7476                        playHeadMarker.synchronize(en);
    7577                }
    76                 mousePos = null;       
     78                mousePos = null;
    7779                dragging = false;
    7880
    7981        /*
  • src/org/openstreetmap/josm/actions/mapmode/DrawAction.java

     
    5151import org.openstreetmap.josm.gui.layer.MapViewPaintable;
    5252import org.openstreetmap.josm.tools.ImageProvider;
    5353import org.openstreetmap.josm.tools.Pair;
     54import org.openstreetmap.josm.tools.ShortCut;
    5455
    5556/**
    5657 *
    57  */ 
     58 */
    5859public class DrawAction extends MapMode implements MapViewPaintable, SelectionChangedListener, AWTEventListener {
    59                
     60
    6061        private static Node lastUsedNode = null;
    6162        private double PHI=Math.toRadians(90);
    6263
     
    6768        private boolean drawHelperLine;
    6869        private Point mousePos;
    6970        private Color selectedColor;
    70        
     71
    7172        private Node currentBaseNode;
    7273        private EastNorth currentMouseEastNorth;
    73        
     74
    7475        public DrawAction(MapFrame mapFrame) {
    7576                super(tr("Draw"), "node/autonode", tr("Draw nodes"),
    76                         KeyEvent.VK_A, mapFrame, getCursor());
     77                                ShortCut.registerShortCut("mapmode:draw", tr("Draw mode"), KeyEvent.VK_A, ShortCut.GROUP_EDIT),
     78                                mapFrame, getCursor());
    7779
    7880                // Add extra shortcut N
    7981                Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    80                         KeyStroke.getKeyStroke(KeyEvent.VK_N, 0), tr("Draw"));
    81                
     82                        ShortCut.registerShortCut("mapmode:draw2", tr("Draw mode (2)"), KeyEvent.VK_N, ShortCut.GROUP_EDIT).getKeyStroke(), tr("Draw"));
     83
    8284                //putValue("help", "Action/AddNode/Autnode");
    8385                selectedColor = Main.pref.getColor(marktr("selected"), Color.YELLOW);
    84                
     86
    8587                drawHelperLine = Main.pref.getBoolean("draw.helper-line", true);
    8688        }
    8789
     
    117119                } catch (SecurityException ex) {
    118120                }
    119121        }
    120        
     122
    121123        /**
    122124         * redraw to (possibly) get rid of helper line if selection changes.
    123125         */
     
    143145         * If user clicked with the left button, add a node at the current mouse
    144146         * position.
    145147         *
    146          * If in nodeway mode, insert the node into the way. 
     148         * If in nodeway mode, insert the node into the way.
    147149         */
    148150        @Override public void mouseClicked(MouseEvent e) {
    149151
     
    159161                alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
    160162                shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    161163                mousePos = e.getPoint();
    162                
     164
    163165                Collection<OsmPrimitive> selection = Main.ds.getSelected();
    164166                Collection<Command> cmds = new LinkedList<Command>();
    165167
     
    167169                        replacedWays = new ArrayList<Way>();
    168170                boolean newNode = false;
    169171                Node n = null;
    170                
     172
    171173                if (!ctrl) {
    172174                        n = Main.map.mapView.getNearestNode(mousePos);
    173175                }
    174                
     176
    175177                if (n != null) {
    176178                        // user clicked on node
    177179                        if (shift || selection.isEmpty()) {
     
    181183                                Main.ds.setSelected(n);
    182184                                return;
    183185                        }
    184                        
     186
    185187                } else {
    186188                        // no node found in clicked area
    187189                        n = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
     
    231233                                adjustNode(segSet, n);
    232234                        }
    233235                }
    234                
     236
    235237                // This part decides whether or not a "segment" (i.e. a connection) is made to an
    236238                // existing node.
    237                
     239
    238240                // For a connection to be made, the user must either have a node selected (connection
    239241                // is made to that node), or he must have a way selected *and* one of the endpoints
    240242                // of that way must be the last used node (connection is made to last used node), or
    241243                // he must have a way and a node selected (connection is made to the selected node).
    242                
     244
    243245                boolean extendedWay = false;
    244246
    245247                if (!shift && selection.size() > 0 && selection.size() < 3) {
    246                        
     248
    247249                        Node selectedNode = null;
    248250                        Way selectedWay = null;
    249                        
     251
    250252                        for (OsmPrimitive p : selection) {
    251253                                if (p instanceof Node) {
    252254                                        if (selectedNode != null) return;
     
    256258                                        selectedWay = (Way) p;
    257259                                }
    258260                        }
    259                        
     261
    260262                        // the node from which we make a connection
    261263                        Node n0 = null;
    262                        
     264
    263265                        if (selectedNode == null) {
    264266                                if (selectedWay == null) return;
    265267                                if (lastUsedNode == selectedWay.nodes.get(0) || lastUsedNode == selectedWay.nodes.get(selectedWay.nodes.size()-1)) {
     
    270272                        } else {
    271273                                if (selectedNode == selectedWay.nodes.get(0) || selectedNode == selectedWay.nodes.get(selectedWay.nodes.size()-1)) {
    272274                                        n0 = selectedNode;
    273                                 }                       
     275                                }
    274276                        }
    275                        
     277
    276278                        if (n0 == null || n0 == n) {
    277279                                return; // Don't create zero length way segments.
    278280                        }
    279281
    280                         // Ok we know now that we'll insert a line segment, but will it connect to an 
     282                        // Ok we know now that we'll insert a line segment, but will it connect to an
    281283                        // existing way or make a new way of its own? The "alt" modifier means that the
    282284                        // user wants a new way.
    283                        
     285
    284286                        Way way = alt ? null : (selectedWay != null) ? selectedWay : getWayForNode(n0);
    285287                        if (way == null) {
    286288                                way = new Way();
     
    327329                }
    328330
    329331                Command c = new SequenceCommand(title, cmds);
    330        
     332
    331333                Main.main.undoRedo.add(c);
    332334                lastUsedNode = n;
    333335                computeHelperLine();
    334336                Main.map.mapView.repaint();
    335337        }
    336        
     338
    337339        @Override public void mouseMoved(MouseEvent e) {
    338340                if(!Main.map.mapView.isDrawableLayer())
    339341                        return;
     
    341343                // we copy ctrl/alt/shift from the event just in case our global
    342344                // AWTEvent didn't make it through the security manager. Unclear
    343345                // if that can ever happen but better be safe.
    344                
     346
    345347                ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    346348                alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
    347349                shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    348350                mousePos = e.getPoint();
    349                
     351
    350352                computeHelperLine();
    351353        }
    352        
     354
    353355        /**
    354356         * This method prepares data required for painting the "helper line" from
    355357         * the last used position to the mouse cursor. It duplicates some code from
     
    362364                        currentBaseNode = null;
    363365                        return;
    364366                }
    365                
     367
    366368                double distance = -1;
    367369                double angle = -1;
    368370
     
    380382                if (!ctrl && mousePos != null) {
    381383                        currentMouseNode = Main.map.mapView.getNearestNode(mousePos);
    382384                }
    383                
     385
    384386                if (currentMouseNode != null) {
    385387                        // user clicked on node
    386388                        if (selection.isEmpty()) return;
     
    390392                        // no node found in clicked area
    391393                        currentMouseEastNorth = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
    392394                }
    393                
     395
    394396                for (OsmPrimitive p : selection) {
    395397                        if (p instanceof Node) {
    396398                                if (selectedNode != null) return;
     
    400402                                selectedWay = (Way) p;
    401403                        }
    402404                }
    403                
     405
    404406                // the node from which we make a connection
    405407                currentBaseNode = null;
    406408                Node previousNode = null;
    407                
     409
    408410                if (selectedNode == null) {
    409411                        if (selectedWay == null) return;
    410412                        if (lastUsedNode == selectedWay.nodes.get(0) || lastUsedNode == selectedWay.nodes.get(selectedWay.nodes.size()-1)) {
     
    418420                } else {
    419421                        if (selectedNode == selectedWay.nodes.get(0) || selectedNode == selectedWay.nodes.get(selectedWay.nodes.size()-1)) {
    420422                                currentBaseNode = selectedNode;
    421                         }                       
     423                        }
    422424                }
    423                
     425
    424426                if (currentBaseNode == null || currentBaseNode == currentMouseNode) {
    425427                        return; // Don't create zero length way segments.
    426428                }
     
    442444
    443445                Main.map.mapView.repaint();
    444446        }
    445        
     447
    446448        /**
    447449         * Repaint on mouse exit so that the helper line goes away.
    448450         */
     
    452454                mousePos = e.getPoint();
    453455                Main.map.mapView.repaint();
    454456        }
    455        
     457
    456458        /**
    457          * @return If the node is the end of exactly one way, return this. 
     459         * @return If the node is the end of exactly one way, return this.
    458460         *      <code>null</code> otherwise.
    459461         */
    460462        public static Way getWayForNode(Node n) {
     
    490492        /**
    491493         * Adjusts the position of a node to lie on a segment (or a segment
    492494         * intersection).
    493          * 
     495         *
    494496         * If one or more than two segments are passed, the node is adjusted
    495497         * to lie on the first segment that is passed.
    496          * 
     498         *
    497499         * If two segments are passed, the node is adjusted to be at their
    498500         * intersection.
    499          * 
     501         *
    500502         * No action is taken if no segments are passed.
    501          * 
     503         *
    502504         * @param segs the segments to use as a reference when adjusting
    503505         * @param n the node to adjust
    504506         */
    505507        private static void adjustNode(Collection<Pair<Node,Node>> segs, Node n) {
    506                
     508
    507509                switch (segs.size()) {
    508510                case 0:
    509511                        return;
    510512                case 2:
    511513                        // algorithm used here is a bit clumsy, anyone's welcome to replace
    512514                        // it by something else. All it does it compute the intersection between
    513                         // the two segments and adjust the node position. The code doesnt 
     515                        // the two segments and adjust the node position. The code doesnt
    514516                        Iterator<Pair<Node,Node>> i = segs.iterator();
    515517                        Pair<Node,Node> seg = i.next();
    516518                        EastNorth A = seg.a.eastNorth;
     
    527529                                        det(C.east(), C.north(), D.east(), D.north()), C.north() - D.north())/
    528530                                        det(A.east() - B.east(), A.north() - B.north(), C.east() - D.east(), C.north() - D.north())
    529531                        );
    530                        
     532
    531533                        // only adjust to intersection if within 10 pixel of mouse click; otherwise
    532534                        // fall through to default action.
    533535                        // (for semi-parallel lines, intersection might be miles away!)
     
    535537                                n.eastNorth = intersection;
    536538                                return;
    537539                        }
    538                
     540
    539541                default:
    540542                        EastNorth P = n.eastNorth;
    541543                        seg = segs.iterator().next();
     
    550552                                B.north() + q * (A.north() - B.north()));
    551553                }
    552554        }
    553        
     555
    554556        // helper for adjustNode
    555557        static double det(double a, double b, double c, double d)
    556558        {
    557559                return a * d - b * c;
    558560        }
    559        
     561
    560562        public void paint(Graphics g, MapView mv) {
    561563
    562564                // don't draw line if disabled in prefs
    563565                if (!drawHelperLine) return;
    564                
     566
    565567                // sanity checks
    566568                if (Main.map.mapView == null) return;
    567569                if (mousePos == null) return;
    568                
     570
    569571                // if shift key is held ("no auto-connect"), don't draw a line
    570572                if (shift) return;
    571                
     573
    572574                // don't draw line if we don't know where from or where to
    573575                if (currentBaseNode == null) return;
    574576                if (currentMouseEastNorth == null) return;
    575                
     577
    576578                // don't draw line if mouse is outside window
    577579                if (!Main.map.mapView.getBounds().contains(mousePos)) return;
    578                
     580
    579581                Graphics2D g2 = (Graphics2D) g;
    580582                g2.setColor(selectedColor);
    581583                g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
     
    584586                Point p2=mv.getPoint(currentMouseEastNorth);
    585587
    586588                double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
    587                
     589
    588590                b.moveTo(p1.x,p1.y); b.lineTo(p2.x, p2.y);
    589                
     591
    590592                // if alt key is held ("start new way"), draw a little perpendicular line
    591593                if (alt) {
    592594                        b.moveTo((int)(p1.x + 8*Math.cos(t+PHI)), (int)(p1.y + 8*Math.sin(t+PHI)));
    593595                        b.lineTo((int)(p1.x + 8*Math.cos(t-PHI)), (int)(p1.y + 8*Math.sin(t-PHI)));
    594596                }
    595                
     597
    596598                g2.draw(b);
    597                 g2.setStroke(new BasicStroke(1));       
     599                g2.setStroke(new BasicStroke(1));
    598600
    599601        }
    600        
     602
    601603        @Override public String getModeHelpText() {
    602604                String rv;
    603                
     605
    604606                if (currentBaseNode != null && !shift) {
    605607                        if (mouseOnExistingNode) {
    606608                                if (alt && /* FIXME: way exists */true)
    607609                                    rv = tr("Click to create a new way to the existing node.");
    608                                 else   
     610                                else
    609611                                        rv =tr("Click to make a connection to the existing node.");
    610612                        } else {
    611613                                if (alt && /* FIXME: way exists */true)
    612614                                    rv = tr("Click to insert a node and create a new way.");
    613                                 else   
     615                                else
    614616                                        rv = tr("Click to insert a new node and make a connection.");
    615617                        }
    616618                }
  • src/org/openstreetmap/josm/actions/mapmode/SelectAction.java

     
    3535import org.openstreetmap.josm.gui.SelectionManager;
    3636import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
    3737import org.openstreetmap.josm.tools.ImageProvider;
     38import org.openstreetmap.josm.tools.ShortCut;
     39
    3840/**
    3941 * Move is an action that can move all kind of OsmPrimitives (except keys for now).
    4042 *
     
    4244 * If an unselected object is under the mouse when dragging, it becomes selected
    4345 * and will be moved.
    4446 * If no object is under the mouse, move all selected objects (if any)
    45  * 
     47 *
    4648 * @author imi
    4749 */
    4850public class SelectAction extends MapMode implements SelectionEnded {
     
    6466         */
    6567        private Point mousePos;
    6668        private SelectionManager selectionManager;
    67        
     69
    6870        /**
    6971         * The time which needs to pass between click and release before something
    7072         * counts as a move, in milliseconds
     
    8385         */
    8486        public SelectAction(MapFrame mapFrame) {
    8587                super(tr("Select"), "move/move", tr("Select, move and rotate objects"),
    86                         KeyEvent.VK_S, mapFrame,
     88                        ShortCut.registerShortCut("mapmode:select", tr("Select mode"), KeyEvent.VK_S, ShortCut.GROUP_EDIT),
     89                        mapFrame,
    8790                        getCursor("normal", "selection", Cursor.DEFAULT_CURSOR));
    8891                putValue("help", "Action/Move/Move");
    89                 selectionManager = new SelectionManager(this, false, mapFrame.mapView);         
     92                selectionManager = new SelectionManager(this, false, mapFrame.mapView);
    9093                try { initialMoveDelay = Integer.parseInt(Main.pref.get("edit.initial-move-delay","200")); } catch (NumberFormatException x) {}
    9194                try { initialMoveThreshold = Integer.parseInt(Main.pref.get("edit.initial-move-threshold","5")); } catch (NumberFormatException x) {}
    92                
     95
    9396        }
    9497
    9598        private static Cursor getCursor(String name, String mod, int def) {
     
    113116                        oldCursor = null;
    114117                }
    115118        }
    116        
     119
    117120        @Override public void enterMode() {
    118121                super.enterMode();
    119122                Main.map.mapView.addMouseListener(this);
     
    152155                        mousePos = e.getPoint();
    153156                        return;
    154157                }
    155                
     158
    156159                if (!initialMoveThresholdExceeded) {
    157160                        int dxp = mousePos.x - e.getX();
    158161                        int dyp = mousePos.y - e.getY();
     
    160163                        if (dp < initialMoveThreshold) return;
    161164                        initialMoveThresholdExceeded = true;
    162165                }
    163                
     166
    164167                EastNorth mouseEN = Main.map.mapView.getEastNorth(e.getX(), e.getY());
    165168                EastNorth mouseStartEN = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
    166169                double dx = mouseEN.east() - mouseStartEN.east();
     
    183186                } else {
    184187                        Collection<OsmPrimitive> selection = Main.ds.getSelected();
    185188                        Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);
    186                
     189
    187190                        // when rotating, having only one node makes no sense - quit silently
    188                         if (mode == Mode.rotate && affectedNodes.size() < 2) 
     191                        if (mode == Mode.rotate && affectedNodes.size() < 2)
    189192                                return;
    190193
    191194                        Command c = !Main.main.undoRedo.commands.isEmpty()
     
    231234                OsmPrimitive osm = c.getNearestNode(p);
    232235                virtualWay = null;
    233236                virtualNode = null;
    234                
     237
    235238                if (osm == null)
    236239                {
    237240                        WaySegment nearestWaySeg = c.getNearestWaySegment(p);
     
    256259                                }
    257260                        }
    258261                }
    259                 if (osm == null) 
     262                if (osm == null)
    260263                        return Collections.emptySet();
    261264                return Collections.singleton(osm);
    262265        }
     
    264267        /**
    265268         * Look, whether any object is selected. If not, select the nearest node.
    266269         * If there are no nodes in the dataset, do nothing.
    267          * 
     270         *
    268271         * If the user did not press the left mouse button, do nothing.
    269          * 
    270          * Also remember the starting position of the movement and change the mouse 
     272         *
     273         * Also remember the starting position of the movement and change the mouse
    271274         * cursor to movement.
    272275         */
    273276        @Override public void mousePressed(MouseEvent e) {
     
    277280                boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    278281                // boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
    279282                boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    280                
     283
    281284                mouseDownTime = System.currentTimeMillis();
    282285                didMove = false;
    283286                initialMoveThresholdExceeded = false;
     
    376379                Main.ds.setSelected(curSel);
    377380                Main.map.mapView.repaint();
    378381        }
    379        
     382
    380383        @Override public String getModeHelpText() {
    381384                if (mode == Mode.select) {
    382385                        return tr("Release the mouse button to select the objects in the rectangle.");
  • src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java

     
    2929import org.openstreetmap.josm.gui.MapView;
    3030import org.openstreetmap.josm.gui.layer.MapViewPaintable;
    3131import org.openstreetmap.josm.tools.ImageProvider;
     32import org.openstreetmap.josm.tools.ShortCut;
     33
    3234/**
    3335 * Makes a rectangle from a line, or modifies a rectangle.
    34  * 
     36 *
    3537 * This class currently contains some "sleeping" code copied from DrawAction (move and rotate)
    3638 * which can eventually be removed, but it may also get activated here and removed in DrawAction.
    3739 */
     
    4648        double xoff;
    4749        double yoff;
    4850        double distance;
    49        
     51
    5052        /**
    5153         * The old cursor before the user pressed the mouse button.
    5254         */
    5355        private Cursor oldCursor;
    5456        /**
    55          * The current position of the mouse 
     57         * The current position of the mouse
    5658         */
    5759        private Point mousePos;
    58         /** 
     60        /**
    5961         * The position of the mouse cursor when the drag action was initiated.
    6062         */
    6163        private Point initialMousePos;
     
    7173         */
    7274        public ExtrudeAction(MapFrame mapFrame) {
    7375                super(tr("Extrude"), "extrude/extrude", tr("Create areas"),
    74                         KeyEvent.VK_X, mapFrame,
     76                                ShortCut.registerShortCut("mapmode:extrude", tr("Extrude mode"), KeyEvent.VK_X, ShortCut.GROUP_EDIT),
     77                        mapFrame,
    7578                        getCursor("normal", "selection", Cursor.DEFAULT_CURSOR));
    7679                putValue("help", "Action/Extrude/Extrude");
    7780                initialMoveDelay = Main.pref.getInteger("edit.initial-move-delay",200);
     
    99102                        oldCursor = null;
    100103                }
    101104        }
    102        
     105
    103106        @Override public void enterMode() {
    104107                super.enterMode();
    105108                Main.map.mapView.addMouseListener(this);
     
    121124         */
    122125        @Override public void mouseDragged(MouseEvent e) {
    123126                if (mode == Mode.select) return;
    124                
     127
    125128                // do not count anything as a move if it lasts less than 100 milliseconds.
    126129                if ((mode == Mode.EXTRUDE) && (System.currentTimeMillis() - mouseDownTime < initialMoveDelay)) return;
    127130
     
    136139                        mousePos = e.getPoint();
    137140                        return;
    138141                }
    139                
     142
    140143                Main.map.mapView.repaint();
    141144                mousePos = e.getPoint();
    142145
     
    146149                if (selectedSegment != null) {
    147150                        Node n1 = selectedSegment.way.nodes.get(selectedSegment.lowerIndex);
    148151                        Node n2 = selectedSegment.way.nodes.get(selectedSegment.lowerIndex+1);
    149                        
     152
    150153                        EastNorth en1 = n1.eastNorth;
    151154                        EastNorth en2 = n2.eastNorth;
    152155                        if (en1.east() < en2.east()) { en2 = en1; en1 = n2.eastNorth; }
    153156                        EastNorth en3 = mv.getEastNorth(mousePos.x, mousePos.y);
    154                        
     157
    155158                        double u = ((en3.east()-en1.east())*(en2.east()-en1.east()) + (en3.north()-en1.north())*(en2.north()-en1.north()))/en2.distanceSq(en1);
    156159                        // the point on the segment from which the distance to mouse pos is shortest
    157160                        EastNorth base = new EastNorth(en1.east()+u*(en2.east()-en1.east()), en1.north()+u*(en2.north()-en1.north()));
    158                        
     161
    159162                        // the distance, in projection units, between the base point and the mouse cursor
    160163                        double len = base.distance(en3);
    161                        
     164
    162165                        // find out the distance, in metres, between the base point and the mouse cursor
    163166                        distance = Main.proj.eastNorth2latlon(base).greatCircleDistance(Main.proj.eastNorth2latlon(en3));
    164167                        Main.map.statusLine.setDist(distance);
    165168                        updateStatusLine();
    166                        
     169
    167170                        // compute the angle at which the segment is drawn
    168171                        // and use it to compute the x and y offsets for the
    169                         // corner points. 
     172                        // corner points.
    170173                        double sin_alpha = (en2.north()-en1.north())/en2.distance(en1);
    171                        
     174
    172175                        // this is a kludge because sometimes extrusion just goes the wrong direction
    173176                        if ((en3.east()>base.east()) ^ (sin_alpha < 0)) len=-len;
    174177                        xoff = sin_alpha * len;
    175178                        yoff = Math.sqrt(1-sin_alpha*sin_alpha) * len;
    176                        
     179
    177180                        Graphics2D g2 = (Graphics2D) g;
    178181                        g2.setColor(selectedColor);
    179182                        g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
     
    182185                        Point p2=mv.getPoint(en2);
    183186                        Point p3=mv.getPoint(en1.add(-xoff, -yoff));
    184187                        Point p4=mv.getPoint(en2.add(-xoff, -yoff));
    185                        
     188
    186189                        b.moveTo(p1.x,p1.y); b.lineTo(p3.x, p3.y);
    187190                        b.lineTo(p4.x, p4.y); b.lineTo(p2.x, p2.y);
    188191                        b.lineTo(p1.x,p1.y);
    189192                        g2.draw(b);
    190                         g2.setStroke(new BasicStroke(1));       
     193                        g2.setStroke(new BasicStroke(1));
    191194                }
    192195        }
    193        
     196
    194197        /**
    195198         */
    196199        @Override public void mousePressed(MouseEvent e) {
     
    200203                // boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    201204                // boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
    202205                // boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    203                
     206
    204207                mouseDownTime = System.currentTimeMillis();
    205                
     208
    206209                selectedSegment =
    207210                        Main.map.mapView.getNearestWaySegment(e.getPoint());
    208211
     
    241244                        Command c = new SequenceCommand(tr("Extrude Way"), cmds);
    242245                        Main.main.undoRedo.add(c);
    243246                }
    244                
     247
    245248                Main.map.mapView.removeTemporaryLayer(this);
    246249                mode = null;
    247250                updateStatusLine();
    248                 Main.map.mapView.repaint();     
     251                Main.map.mapView.repaint();
    249252        }
    250253
    251254        @Override public String getModeHelpText() {
  • src/org/openstreetmap/josm/actions/UndoAction.java

     
    88import java.awt.event.KeyEvent;
    99
    1010import org.openstreetmap.josm.Main;
     11import org.openstreetmap.josm.tools.ShortCut;
    1112
    12 
    1313/**
    1414 * Undoes the last command.
    15  * 
     15 *
    1616 * @author imi
    1717 */
    1818public class UndoAction extends JosmAction {
     
    2121         * Construct the action with "Undo" as label.
    2222         */
    2323        public UndoAction() {
    24                 super(tr("Undo"), "undo", tr("Undo the last action."), KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK, true);
     24                super(tr("Undo"), "undo", tr("Undo the last action."),
     25                ShortCut.registerShortCut("system:undo", tr("Edit: Undo"), KeyEvent.VK_Z, ShortCut.GROUP_MENU), true);
    2526                setEnabled(false);
    2627        }
    2728
  • src/org/openstreetmap/josm/actions/AlignInRectangleAction.java

     
    1919import org.openstreetmap.josm.data.osm.Node;
    2020import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2121import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.tools.ShortCut;
    2223
    2324/**
    24  * Aligns all selected nodes within a rectangle. 
    25  * 
     25 * Aligns all selected nodes within a rectangle.
     26 *
    2627 * There are many ways this could be done, for example:
    2728 * - find smallest rectangle to contain all points (rectangular hull) OR
    2829 * - find largest rectangle to fit inside OR
    2930 * - find both and compute the average
    30  * 
     31 *
    3132 * Also, it would be possible to let the user specify more input, e.g.
    3233 * two nodes that should remain where they are.
    33  * 
     34 *
    3435 * This method uses the following algorithm:
    3536 * 1. compute "heading" of all four edges
    3637 * 2. select the edge that is oriented closest to the average of all headings
     
    3940public final class AlignInRectangleAction extends JosmAction {
    4041
    4142        public AlignInRectangleAction() {
    42                 super(tr("Align Nodes in Rectangle"), "alignrect", tr("Move the selected nodes into a rectangle."), KeyEvent.VK_Q, 0, true);
     43                super(tr("Align Nodes in Rectangle"), "alignrect", tr("Move the selected nodes into a rectangle."),
     44                ShortCut.registerShortCut("tools:alignrect", tr("Tool: Align in rectangle"), KeyEvent.VK_Q, ShortCut.GROUP_EDIT), true);
    4345        }
    4446
    4547        public void actionPerformed(ActionEvent e) {
    4648                Collection<OsmPrimitive> sel = Main.ds.getSelected();
    4749                Way myWay = null;
    48                 if (sel.size() == 1) 
     50                if (sel.size() == 1)
    4951                        for (OsmPrimitive osm : sel)
    5052                                if (osm instanceof Way)
    5153                                        myWay = (Way) osm;
    52                
     54
    5355                if ((myWay == null) || (myWay.nodes.size() != 5) || (!myWay.nodes.get(0).equals(myWay.nodes.get(4)))) {
    5456                        JOptionPane.showMessageDialog(Main.parent, tr("Please select one circular way of exactly four nodes."));
    5557                        return;
     
    6668                        avg_angle += angle[i];
    6769                }
    6870                avg_angle /= 4;
    69                
     71
    7072                // select edge that is closest to average, and use it as the base for the following
    71                 double best_dist = 0; 
     73                double best_dist = 0;
    7274                int base = 0;
    7375                for (int i=0; i<4; i++)
    7476                {
     
    8587                EastNorth end = en[(base+1)%4]; // second node of base segment
    8688                EastNorth next = en[(base+2)%4]; // node following the second node of the base seg
    8789                EastNorth prev= en[(base+3)%4];  // node before the first node of the base seg
    88                
     90
    8991                // find a parallel to the base segment
    9092                double base_slope = (end.north() - begin.north()) / (end.east() - begin.east());
    9193                // base intercept of parallels that go through "next" and "prev" points
     
    101103                // same for "prev"
    102104                u = ((prev.east()-begin.east())*(end.east()-begin.east()) + (prev.north()-begin.north())*(end.north()-begin.north()))/end.distanceSq(begin);
    103105                EastNorth begin2 = new EastNorth(begin.east()+u*(end.east()-begin.east()), begin.north()+u*(end.north()-begin.north()));
    104                
    105                 // new "begin" and "end" points are halfway between their old position and 
     106
     107                // new "begin" and "end" points are halfway between their old position and
    106108                // the base points found above
    107109                end = new EastNorth((end2.east()+end.east())/2, (end2.north()+end.north())/2);
    108110                begin = new EastNorth((begin2.east()+begin.east())/2, (begin2.north()+begin.north())/2);
    109                
     111
    110112                double other_slope = -1 / base_slope;
    111113                double next_b = end.north() - other_slope * end.east();
    112114                double prev_b = begin.north() - other_slope * begin.east();
    113                
     115
    114116                double x = (opposite_b-next_b)/(other_slope-base_slope);
    115117                double y = opposite_b + base_slope * x;
    116118                next = new EastNorth(x, y);
    117                
     119
    118120                x = (opposite_b-prev_b)/(other_slope-base_slope);
    119121                y = opposite_b + base_slope * x;
    120122                prev = new EastNorth(x, y);
    121                
     123
    122124                Collection<Command> cmds = new LinkedList<Command>();
    123125                for (int i=0; i<4; i++) {
    124126                        Node n = myWay.nodes.get(i);
  • src/org/openstreetmap/josm/actions/DownloadAction.java

     
    1616import org.openstreetmap.josm.gui.download.DownloadDialog;
    1717import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    1818import org.openstreetmap.josm.tools.GBC;
     19import org.openstreetmap.josm.tools.ShortCut;
    1920
    2021/**
    2122 * Action that opens a connection to the osm server and downloads map data.
     
    2627 * @author imi
    2728 */
    2829public class DownloadAction extends JosmAction {
    29        
     30
    3031        public DownloadDialog dialog;
    31        
     32
    3233        public DownloadAction() {
    33                 super(tr("Download from OSM ..."), "download", tr("Download map data from the OSM server."), KeyEvent.VK_D, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK, true);
     34                super(tr("Download from OSM ..."), "download", tr("Download map data from the OSM server."),
     35                ShortCut.registerShortCut("file:download", tr("File: Download"), KeyEvent.VK_D, ShortCut.GROUPS_ALT1+ShortCut.GROUP_HOTKEY), true);
    3436        }
    3537
    3638        public void actionPerformed(ActionEvent e) {
    3739                dialog = new DownloadDialog();
    38                
     40
    3941                JPanel downPanel = new JPanel(new GridBagLayout());
    4042                downPanel.add(dialog, GBC.eol().fill(GBC.BOTH));
    4143
  • src/org/openstreetmap/josm/actions/DuplicateAction.java

     
    1212import org.openstreetmap.josm.data.SelectionChangedListener;
    1313import org.openstreetmap.josm.data.osm.DataSet;
    1414import org.openstreetmap.josm.data.osm.OsmPrimitive;
     15import org.openstreetmap.josm.tools.ShortCut;
    1516
    1617public final class DuplicateAction extends JosmAction implements SelectionChangedListener {
    1718
    1819    public DuplicateAction() {
    1920        super(tr("Duplicate"), "duplicate",
    2021                        tr("Duplicate selection by copy and immediate paste."),
    21                         KeyEvent.VK_D, KeyEvent.CTRL_MASK, true);
     22                        ShortCut.registerShortCut("system:duplicate", tr("Edit: Duplicate selection"), KeyEvent.VK_D, ShortCut.GROUP_MENU), true);
    2223        setEnabled(false);
    23                 DataSet.selListeners.add(this);
     24                        DataSet.selListeners.add(this);
    2425    }
    2526
    2627        public void actionPerformed(ActionEvent e) {
    2728                Main.main.menu.copy.actionPerformed(e);
    2829                Main.main.menu.paste.actionPerformed(e);
    2930    }
    30        
     31
    3132        public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
    3233                setEnabled(! newSelection.isEmpty());
    3334        }
  • src/org/openstreetmap/josm/actions/AboutAction.java

     
    3333import org.openstreetmap.josm.tools.GBC;
    3434import org.openstreetmap.josm.tools.ImageProvider;
    3535import org.openstreetmap.josm.tools.UrlLabel;
     36import org.openstreetmap.josm.tools.ShortCut;
    3637
    3738/**
    3839 * Nice about screen. I guess every application need one these days.. *sigh*
    39  * 
    40  * The REVISION resource is read and if present, it shows the revision 
     40 *
     41 * The REVISION resource is read and if present, it shows the revision
    4142 * information of the jar-file.
    42  * 
     43 *
    4344 * @author imi
    4445 */
    4546public class AboutAction extends JosmAction {
     
    6465        static public String getVersion() {
    6566                return version;
    6667        }
    67        
     68
    6869        public AboutAction() {
    69                 super(tr("About"), "about",tr("Display the about screen."), KeyEvent.VK_F1, KeyEvent.SHIFT_DOWN_MASK, true);
     70                super(tr("About"), "about", tr("Display the about screen."), ShortCut.registerShortCut("system:about", tr("About..."), KeyEvent.VK_F1, ShortCut.GROUP_DIRECT), true);
    7071        }
    7172
    7273        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/PasteAction.java

     
    2323import org.openstreetmap.josm.data.osm.RelationMember;
    2424import org.openstreetmap.josm.data.osm.Way;
    2525import org.openstreetmap.josm.data.coor.EastNorth;
     26import org.openstreetmap.josm.tools.ShortCut;
    2627
    2728public final class PasteAction extends JosmAction {
    2829
    2930    public PasteAction() {
    30         super(tr("Paste"), "paste",
    31                         tr("Paste contents of paste buffer."),
    32                         KeyEvent.VK_V, KeyEvent.CTRL_MASK, true);
    33                 setEnabled(false);
     31        super(tr("Paste"), "paste", tr("Paste contents of paste buffer."),
     32                        ShortCut.registerShortCut("system:paste", tr("Edit: Paste"), KeyEvent.VK_V, ShortCut.GROUP_MENU), true);
     33                        setEnabled(false);
    3434    }
    3535
    3636        public void actionPerformed(ActionEvent e) {
    3737                DataSet pasteBuffer = Main.pasteBuffer;
    3838
    39                 /* Find the middle of the pasteBuffer area */ 
     39                /* Find the middle of the pasteBuffer area */
    4040                double maxEast = -1E100, minEast = 1E100, maxNorth = -1E100, minNorth = 1E100;
    4141                for (Node n : pasteBuffer.nodes) {
    4242                        double east = n.eastNorth.east();
    4343                        double north = n.eastNorth.north();
    44                         if (east > maxEast) { maxEast = east; } 
    45                         if (east < minEast) { minEast = east; } 
    46                         if (north > maxNorth) { maxNorth = north; } 
    47                         if (north < minNorth) { minNorth = north; } 
     44                        if (east > maxEast) { maxEast = east; }
     45                        if (east < minEast) { minEast = east; }
     46                        if (north > maxNorth) { maxNorth = north; }
     47                        if (north < minNorth) { minNorth = north; }
    4848                }
    4949
    5050                EastNorth mPosition;
     
    5656
    5757                double offsetEast  = mPosition.east() - (maxEast + minEast)/2.0;
    5858                double offsetNorth = mPosition.north() - (maxNorth + minNorth)/2.0;
    59                
    60                 HashMap<OsmPrimitive,OsmPrimitive> map = new HashMap<OsmPrimitive,OsmPrimitive>(); 
     59
     60                HashMap<OsmPrimitive,OsmPrimitive> map = new HashMap<OsmPrimitive,OsmPrimitive>();
    6161                  /* temporarily maps old nodes to new so we can do a true deep copy */
    62                
     62
    6363                /* do the deep copy of the paste buffer contents, leaving the pasteBuffer unchanged */
    6464                for (Node n : pasteBuffer.nodes) {
    6565                        Node nnew = new Node(n);
     
    9595                        rnew.members.addAll(members);
    9696                        map.put(r, rnew);
    9797                }
    98                
     98
    9999                /* Now execute the commands to add the dupicated contents of the paste buffer to the map */
    100100                Collection<OsmPrimitive> osms = map.values();
    101101                Collection<Command> clist = new LinkedList<Command>();
  • src/org/openstreetmap/josm/actions/DiskAccessAction.java

     
    99import javax.swing.JOptionPane;
    1010
    1111import org.openstreetmap.josm.Main;
     12import org.openstreetmap.josm.tools.ShortCut;
    1213
    1314/**
    1415 * Helper class for all actions that access the disk
    1516 */
    1617abstract public class DiskAccessAction extends JosmAction {
    1718
     19        public DiskAccessAction(String name, String iconName, String tooltip, ShortCut shortCut) {
     20                super(name, iconName, tooltip, shortCut, true);
     21        }
     22
     23        @Deprecated
    1824        public DiskAccessAction(String name, String iconName, String tooltip, int shortCut, int modifiers) {
    1925                super(name, iconName, tooltip, shortCut, modifiers, true);
    2026        }
    21        
     27
    2228        protected static JFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title) {
    2329                String curDir = Main.pref.get("lastDirectory");
    2430                if (curDir.equals(""))
     
    3137                for (int i = 0; i < ExtensionFileFilter.filters.length; ++i)
    3238                        fc.addChoosableFileFilter(ExtensionFileFilter.filters[i]);
    3339                fc.setAcceptAllFileFilterUsed(true);
    34        
     40
    3541                int answer = open ? fc.showOpenDialog(Main.parent) : fc.showSaveDialog(Main.parent);
    3642                if (answer != JFileChooser.APPROVE_OPTION)
    3743                        return null;
    38                
     44
    3945                if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir))
    4046                        Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
    4147
    4248                if (!open) {
    4349                        File file = fc.getSelectedFile();
    44                         if (file == null || (file.exists() && JOptionPane.YES_OPTION != 
     50                        if (file == null || (file.exists() && JOptionPane.YES_OPTION !=
    4551                                        JOptionPane.showConfirmDialog(Main.parent, tr("File exists. Overwrite?"), tr("Overwrite"), JOptionPane.YES_NO_OPTION)))
    4652                                return null;
    4753                }
    48                
     54
    4955                return fc;
    5056        }
    5157}
  • src/org/openstreetmap/josm/actions/HistoryInfoAction.java

     
    1313import org.openstreetmap.josm.data.osm.Way;
    1414import org.openstreetmap.josm.data.osm.visitor.Visitor;
    1515import org.openstreetmap.josm.tools.OpenBrowser;
     16import org.openstreetmap.josm.tools.ShortCut;
    1617
    1718public class HistoryInfoAction extends JosmAction {
    1819
    1920        public HistoryInfoAction() {
    20                 super(tr("OSM History Information"), "about",tr("Display history information about OSM ways or nodes."), KeyEvent.VK_H, KeyEvent.SHIFT_DOWN_MASK, true);
     21                super(tr("OSM History Information"), "about",tr("Display history information about OSM ways or nodes."),
     22                ShortCut.registerShortCut("core:history", tr("Display history"), KeyEvent.VK_H, ShortCut.GROUP_HOTKEY), true);
    2123        }
    2224
    2325        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/AutoScaleAction.java

     
    1414import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1515import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    1616import org.openstreetmap.josm.gui.layer.Layer;
     17import org.openstreetmap.josm.tools.ShortCut;
    1718
    1819/**
    1920 * Toggles the autoScale feature of the mapView
     
    4546
    4647    public AutoScaleAction(String mode) {
    4748        super(tr("Zoom to {0}", tr(mode)), "dialogs/autoscale/" + mode, tr("Zoom the view to {0}.", tr(mode)),
    48                 AutoScaleAction.getModeShortcut(mode), 0, true);
     49                                ShortCut.registerShortCut("view:zoom"+mode, tr("View: Zoom to {0}", tr(mode)), getModeShortcut(mode), ShortCut.GROUP_EDIT), true);
    4950        String modeHelp = Character.toUpperCase(mode.charAt(0)) + mode.substring(1);
    5051        putValue("help", "Action/AutoScale/" + modeHelp);
    5152        this.mode = mode;
     
    7879            }
    7980            for (OsmPrimitive osm : sel)
    8081                osm.visit(v);
    81             // increase bbox by 0.001 degrees on each side. this is required 
    82             // especially if the bbox contains one single node, but helpful 
     82            // increase bbox by 0.001 degrees on each side. this is required
     83            // especially if the bbox contains one single node, but helpful
    8384            // in most other cases as well.
    8485            v.enlargeBoundingBox();
    8586        }
  • src/org/openstreetmap/josm/actions/UploadAction.java

     
    2323import org.openstreetmap.josm.io.OsmServerWriter;
    2424import org.openstreetmap.josm.tools.GBC;
    2525import org.xml.sax.SAXException;
     26import org.openstreetmap.josm.tools.ShortCut;
    2627
    2728/**
    2829 * Action that opens a connection to the osm server and uploads all changes.
     
    3334 * @author imi
    3435 */
    3536public class UploadAction extends JosmAction {
    36        
     37
    3738        /** Upload Hook */
    3839        public interface UploadHook {
    3940                /**
     
    4546                 */
    4647                public boolean checkUpload(Collection<OsmPrimitive> add, Collection<OsmPrimitive> update, Collection<OsmPrimitive> delete);
    4748        }
    48        
     49
    4950        /**
    5051         * The list of upload hooks. These hooks will be called one after the other
    5152         * when the user wants to upload data. Plugins can insert their own hooks here
    5253         * if they want to be able to veto an upload.
    53          * 
     54         *
    5455         * Be default, the standard upload dialog is the only element in the list.
    5556         * Plugins should normally insert their code before that, so that the upload
    5657         * dialog is the last thing shown before upload really starts; on occasion
     
    5960        public final LinkedList<UploadHook> uploadHooks = new LinkedList<UploadHook>();
    6061
    6162        public UploadAction() {
    62                 super(tr("Upload to OSM ..."), "upload", tr("Upload all changes to the OSM server."), KeyEvent.VK_U, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK, true);
     63                super(tr("Upload to OSM ..."), "upload", tr("Upload all changes to the OSM server."),
     64                ShortCut.registerShortCut("file:upload", tr("File: Upload"), KeyEvent.VK_U, ShortCut.GROUPS_ALT1+ShortCut.GROUP_HOTKEY), true);
    6365
    6466                /**
    6567                 * Displays a screen where the actions that would be taken are displayed and
     
    128130                        else if (osm.deleted && osm.id != 0)
    129131                                delete.addFirst(osm);
    130132                }
    131                
     133
    132134                if (add.isEmpty() && update.isEmpty() && delete.isEmpty()) {
    133135                        JOptionPane.showMessageDialog(Main.parent,tr("No changes to upload."));
    134136                        return;
     
    139141                for(UploadHook hook : uploadHooks)
    140142                        if(!hook.checkUpload(add, update, delete))
    141143                                return;
    142                
     144
    143145                final OsmServerWriter server = new OsmServerWriter();
    144146                final Collection<OsmPrimitive> all = new LinkedList<OsmPrimitive>();
    145147                all.addAll(add);
  • src/org/openstreetmap/josm/actions/CreateCircleAction.java

     
    1919import org.openstreetmap.josm.data.osm.Node;
    2020import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2121import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.tools.ShortCut;
    2223
    2324/**
    2425 * Create a new circle from three selected nodes--or a way with 3 nodes. (Useful for roundabouts)
     26 *
    2527 * Note: If a way is selected, it is changed. If nodes are selected a new way is created.
    2628 *       So if you've got a way with 3 nodes it makes a difference between running this on the way or the nodes!
     29 *
    2730 * BTW: Someone might want to implement projection corrections for this...
    2831 *
    2932 * @author Henry Loenwind, based on much copy&Paste from other Actions.
     
    3134public final class CreateCircleAction extends JosmAction {
    3235
    3336        public CreateCircleAction() {
    34                 super(tr("Create Circle"), "createcircle", tr("Create a circle from three selected nodes."), KeyEvent.VK_O, KeyEvent.CTRL_MASK, true);
     37                super(tr("Create Circle"), "createcircle", tr("Create a circle from three selected nodes."),
     38                ShortCut.registerShortCut("tools:createcircle", tr("Tool: Create circle"), KeyEvent.VK_O, ShortCut.GROUP_EDIT), true);
    3539        }
    3640
    3741        private double calcang(double xc, double yc, double x, double y) {
  • src/org/openstreetmap/josm/actions/MergeNodesAction.java

     
    3939import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
    4040import org.openstreetmap.josm.tools.GBC;
    4141import org.openstreetmap.josm.tools.Pair;
     42import org.openstreetmap.josm.tools.ShortCut;
    4243
    4344
    4445/**
    4546 * Merge two or more nodes into one node.
    4647 * (based on Combine ways)
    47  * 
     48 *
    4849 * @author Matthew Newton
    4950 *
    5051 */
    5152public class MergeNodesAction extends JosmAction implements SelectionChangedListener {
    5253
    5354        public MergeNodesAction() {
    54                 super(tr("Merge Nodes"), "mergenodes", tr("Merge nodes into one."), KeyEvent.VK_M, 0, true);
     55                super(tr("Merge Nodes"), "mergenodes", tr("Merge nodes into the oldest one."),
     56                ShortCut.registerShortCut("tools:mergenodes", tr("Tool: Merge nodes"), KeyEvent.VK_M, ShortCut.GROUP_EDIT), true);
    5557                DataSet.selListeners.add(this);
    5658        }
    5759
  • src/org/openstreetmap/josm/actions/SaveActionBase.java

     
    2121import org.openstreetmap.josm.gui.layer.GpxLayer;
    2222import org.openstreetmap.josm.io.OsmWriter;
    2323import org.openstreetmap.josm.io.GpxWriter;
     24import org.openstreetmap.josm.tools.ShortCut;
    2425
    2526public abstract class SaveActionBase extends DiskAccessAction {
    2627
    2728        private Layer layer;
    2829
     30        public SaveActionBase(String name, String iconName, String tooltip, ShortCut shortCut, Layer layer) {
     31                super(name, iconName, tooltip, shortCut);
     32                this.layer = layer;
     33        }
     34
     35        @Deprecated
    2936        public SaveActionBase(String name, String iconName, String tooltip, int shortCut, int modifiers, Layer layer) {
    3037                super(name, iconName, tooltip, shortCut, modifiers);
    3138                this.layer = layer;
     
    7885                        return false;
    7986                }
    8087                if (!Main.map.conflictDialog.conflicts.isEmpty()) {
    81                         int answer = JOptionPane.showConfirmDialog(Main.parent, 
     88                        int answer = JOptionPane.showConfirmDialog(Main.parent,
    8289                                        tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"),tr("Conflicts"), JOptionPane.YES_NO_OPTION);
    8390                        if (answer != JOptionPane.YES_OPTION)
    8491                                return false;
     
    215222
    216223        /**
    217224         * Check the data set if it would be empty on save. It is empty, if it contains
    218          * no objects (after all objects that are created and deleted without being 
     225         * no objects (after all objects that are created and deleted without being
    219226         * transfered to the server have been removed).
    220          * 
     227         *
    221228         * @return <code>true</code>, if a save result in an empty data set.
    222229         */
    223230        private boolean isDataSetEmpty(OsmDataLayer layer) {
  • src/org/openstreetmap/josm/actions/RedoAction.java

     
    88import java.awt.event.KeyEvent;
    99
    1010import org.openstreetmap.josm.Main;
     11import org.openstreetmap.josm.tools.ShortCut;
    1112
    12 
    1313/**
    1414 * Redoes the last command.
    15  * 
     15 *
    1616 * @author imi
    1717 */
    1818public class RedoAction extends JosmAction {
     
    2121         * Construct the action with "Redo" as label.
    2222         */
    2323        public RedoAction() {
    24                 super(tr("Redo"), "redo", tr("Redo the last undone action."), KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK, true);
     24                super(tr("Redo"), "redo", tr("Redo the last undone action."),
     25                ShortCut.registerShortCut("system:redo", tr("Edit: Redo"), KeyEvent.VK_Y, ShortCut.GROUP_MENU), true);
    2526                setEnabled(false);
    2627        }
    2728
  • src/org/openstreetmap/josm/actions/NewAction.java

     
    1010import org.openstreetmap.josm.Main;
    1111import org.openstreetmap.josm.data.osm.DataSet;
    1212import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     13import org.openstreetmap.josm.tools.ShortCut;
    1314
    1415public class NewAction extends JosmAction {
    1516
    1617        public NewAction() {
    17                 super(tr("New"), "new", tr("Create a new map."), KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK, true);
     18                super(tr("New"), "new", tr("Create a new map."),
     19                ShortCut.registerShortCut("system:new", tr("File: New"), KeyEvent.VK_N, ShortCut.GROUP_MENU), true);
    1820        }
    1921
    2022        public void actionPerformed(ActionEvent e) {
  • src/org/openstreetmap/josm/actions/PasteTagsAction.java

     
    1919import org.openstreetmap.josm.data.SelectionChangedListener;
    2020import org.openstreetmap.josm.data.osm.DataSet;
    2121import org.openstreetmap.josm.data.osm.OsmPrimitive;
     22import org.openstreetmap.josm.tools.ShortCut;
    2223
    2324public final class PasteTagsAction extends JosmAction implements SelectionChangedListener {
    2425
    2526        public PasteTagsAction(JosmAction copyAction) {
    2627                super(tr("Paste Tags"), "pastetags",
    2728                        tr("Apply tags of contents of paste buffer to all selected items."),
    28                         KeyEvent.VK_V, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
     29                        ShortCut.registerShortCut("system:pastestyle", tr("Edit: Paste tags"), KeyEvent.VK_V, ShortCut.GROUP_MENU), true);
    2930                DataSet.selListeners.add(this);
    3031                copyAction.addListener(this);
    3132                setEnabled(false);
  • src/org/openstreetmap/josm/actions/CombineWayAction.java

     
    3939import org.openstreetmap.josm.data.osm.Way;
    4040import org.openstreetmap.josm.tools.GBC;
    4141import org.openstreetmap.josm.tools.Pair;
     42import org.openstreetmap.josm.tools.ShortCut;
    4243
    4344/**
    4445 * Combines multiple ways into one.
    45  * 
     46 *
    4647 * @author Imi
    4748 */
    4849public class CombineWayAction extends JosmAction implements SelectionChangedListener {
    4950
    5051        public CombineWayAction() {
    51                 super(tr("Combine Way"), "combineway", tr("Combine several ways into one."), KeyEvent.VK_C, 0, true);
     52                super(tr("Combine Way"), "combineway", tr("Combine several ways into one."),
     53                ShortCut.registerShortCut("tools:combineway", tr("Tool: Combine ways"), KeyEvent.VK_C, ShortCut.GROUP_EDIT), true);
    5254                DataSet.selListeners.add(this);
    5355        }
    5456
  • src/org/openstreetmap/josm/actions/SaveAction.java

     
    1010import org.openstreetmap.josm.gui.layer.Layer;
    1111import org.openstreetmap.josm.gui.layer.GpxLayer;
    1212import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     13import org.openstreetmap.josm.tools.ShortCut;
    1314
    1415/**
    1516 * Export the data as an OSM xml file.
    16  * 
     17 *
    1718 * @author imi
    1819 */
    1920public class SaveAction extends SaveActionBase {
    20    
     21
    2122        /**
    2223         * Construct the action with "Save" as label.
    2324         * @param layer Save this layer.
    2425         */
    2526        public SaveAction(Layer layer) {
    26                 super(tr("Save"), "save", tr("Save the current data."), KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK, layer);
     27                super(tr("Save"), "save", tr("Save the current data."),
     28                ShortCut.registerShortCut("system:save", tr("File: Save"), KeyEvent.VK_S, ShortCut.GROUP_MENU), layer);
    2729        }
    28        
     30
    2931        @Override public File getFile(Layer layer) {
    3032                if (layer instanceof OsmDataLayer) {
    3133                        File f = ((OsmDataLayer)layer).associatedFile;
  • src/org/openstreetmap/josm/tools/OpenBrowser.java

     
    1111
    1212/**
    1313 * Helper to open platform web browser on different platforms
     14 *
     15 * This now delegates the real work to a platform specific class.
     16 *
    1417 * @author Imi
    1518 */
    1619public class OpenBrowser {
     
    2932                        }
    3033                }
    3134
    32                 String os = System.getProperty("os.name");
    33                 if (os == null)
    34                         return "unknown operating system";
    3535                try {
    36                         if (os != null && os.startsWith("Windows"))
    37                                 windows(url);
    38                         else if (os.equals("Linux") || os.equals("Solaris") || os.equals("SunOS") || os.equals("AIX") || os.equals("FreeBSD"))
    39                                 linux(url);
    40                         else if (os.equals("Mac OS") || os.equals("Mac OS X"))
    41                                 mac(url);
    42                         else
    43                                 return "unknown operating system";
     36                        Main.platform.openUrl(url);
    4437                } catch (IOException e) {
    4538                        return e.getMessage();
    4639                }
    4740                return null;
    4841        }
    4942
    50         private static void windows(String url) throws IOException {
    51                 Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
    52         }
    53 
    54         private static void linux(String url) {
    55                 String[] programs = {"gnome-open", "kfmclient openURL", "firefox"};
    56                 for (String program : programs) {
    57                         try {
    58                                 Runtime.getRuntime().exec(program+" "+url);
    59                                 return;
    60                         } catch (IOException e) {
    61             }
    62                 }
    63         }
    64 
    65         private static void mac(String url) throws IOException {
    66                 Runtime.getRuntime().exec("open " + url);
    67         }
    6843}
  • src/org/openstreetmap/josm/tools/ShortCutLabel.java

     
    55
    66import java.awt.event.KeyEvent;
    77
    8 
     8@Deprecated
    99public class ShortCutLabel {
     10        @Deprecated
    1011        public static String name(int shortCut, int modifiers) {
    1112                if (shortCut == 0 && modifiers == 0)
    1213                        return "";
  • src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java

     
    4242import org.openstreetmap.josm.gui.NavigatableComponent;
    4343import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    4444import org.openstreetmap.josm.gui.SideButton;
     45import org.openstreetmap.josm.tools.ShortCut;
    4546
    4647public final class ConflictDialog extends ToggleDialog {
    4748
     
    5051        private final JList displaylist = new JList(model);
    5152
    5253        public ConflictDialog() {
    53                 super(tr("Conflict"), "conflict", tr("Merging conflicts."), KeyEvent.VK_C, 100);
     54                super(tr("Conflict"), "conflict", tr("Merging conflicts."),
     55                ShortCut.registerShortCut("subwindow:conflict", tr("Toggle conflict window"), KeyEvent.VK_C, ShortCut.GROUP_LAYER), 100);
    5456                displaylist.setCellRenderer(new OsmPrimitivRenderer());
    5557                displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    5658                displaylist.addMouseListener(new MouseAdapter(){
  • src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java

     
    3737import org.openstreetmap.josm.gui.SideButton;
    3838import org.openstreetmap.josm.tools.GBC;
    3939import org.openstreetmap.josm.tools.ImageProvider;
     40import org.openstreetmap.josm.tools.ShortCut;
    4041
    4142/**
    4243 * History dialog works like follows:
     
    8687        private JLabel notLoaded = new JLabel("<html><i>"+tr("Click Reload to refresh list")+"</i></html>");
    8788
    8889        public HistoryDialog() {
    89                 super(tr("History"), "history", tr("Display the history of all selected items."), KeyEvent.VK_H, 150);
     90                super(tr("History"), "history", tr("Display the history of all selected items."),
     91                ShortCut.registerShortCut("subwindow:history", tr("Toggle history window"), KeyEvent.VK_H, ShortCut.GROUP_LAYER), 150);
    9092                historyPane.setVisible(false);
    9193                notLoaded.setVisible(true);
    9294                notLoaded.setHorizontalAlignment(JLabel.CENTER);
  • src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java

     
    4040import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    4141import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    4242import org.openstreetmap.josm.gui.SideButton;
     43import org.openstreetmap.josm.tools.ShortCut;
    4344
    4445/**
    4546 * A small tool dialog for displaying the current selection. The selection manager
     
    6970    private JMenuItem zoomToElement;
    7071
    7172    /**
    72      * If the selection changed event is triggered with newSelection equals 
    73      * this element, the newSelection will not be added to the selection history 
     73     * If the selection changed event is triggered with newSelection equals
     74     * this element, the newSelection will not be added to the selection history
    7475     */
    7576    private Collection<? extends OsmPrimitive> historyIgnoreSelection = null;
    7677
    7778    public SelectionListDialog() {
    78         super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."), KeyEvent.VK_T, 150);
     79        super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."),
     80        ShortCut.registerShortCut("subwindow:selection", tr("Toggle selection window"), KeyEvent.VK_T, ShortCut.GROUP_LAYER), 150);
    7981
    8082        selectionHistory = new LinkedList<Collection<? extends OsmPrimitive>>();
    8183        popupMenu = new JPopupMenu();
     
    190192    }
    191193
    192194    /**
    193      * Zooms to the element(s) selected in {@link #displaylist} 
     195     * Zooms to the element(s) selected in {@link #displaylist}
    194196     */
    195197    public void zoomToSelectedElement() {
    196198        BoundingXYVisitor box = new BoundingXYVisitor();
     
    247249        if (selectionHistory != null && newSelection.size() > 0 && !newSelection.equals(historyIgnoreSelection)) {
    248250            historyIgnoreSelection = null;
    249251            try {
    250                 // Check if the newSelection has already been added to the history 
     252                // Check if the newSelection has already been added to the history
    251253                Collection<? extends OsmPrimitive> first = selectionHistory.getFirst();
    252254                if (first.equals(newSelection))
    253255                    return;
     
    272274
    273275    /**
    274276     * A specialized {@link JMenuItem} for presenting one entry of the selection history
    275      *   
     277     *
    276278     * @author Jan Peter Stotz
    277279     */
    278280    protected class SelectionMenuItem extends JMenuItem implements ActionListener {
     
    302304
    303305    /**
    304306     * A specialized {@link JMenuItem} for presenting one entry of the search history
    305      *   
     307     *
    306308     * @author Jan Peter Stotz
    307309     */
    308310    protected class SearchMenuItem extends JMenuItem implements ActionListener {
  • src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java

     
    2626import org.openstreetmap.josm.actions.HelpAction.Helpful;
    2727import org.openstreetmap.josm.tools.GBC;
    2828import org.openstreetmap.josm.tools.ImageProvider;
     29import org.openstreetmap.josm.tools.ShortCut;
    2930
    3031/**
    3132 * This class is a toggle dialog that can be turned on and off. It is attached
     
    3940                public final String prefname;
    4041                public AbstractButton button;
    4142
    42                 private ToggleDialogAction(String name, String iconName, String tooltip, int shortCut, int modifier, String prefname) {
    43                         super(name, iconName, tooltip, shortCut, modifier, false);
     43                private ToggleDialogAction(String name, String iconName, String tooltip, ShortCut shortCut, String prefname) {
     44                        super(name, iconName, tooltip, shortCut, false);
    4445                        this.prefname = prefname;
    4546                }
    4647
     
    6162        public JPanel parent;
    6263        private final JPanel titleBar = new JPanel(new GridBagLayout());
    6364
     65        @Deprecated
    6466        public ToggleDialog(final String name, String iconName, String tooltip, int shortCut, int preferredHeight) {
    6567                super(new BorderLayout());
    6668                this.prefName = iconName;
     69                ToggleDialogInit(name, iconName, tooltip, ShortCut.registerShortCut("auto:"+name, tooltip, shortCut, ShortCut.GROUP_LAYER), preferredHeight);
     70        }
     71
     72        public ToggleDialog(final String name, String iconName, String tooltip, ShortCut shortCut, int preferredHeight) {
     73                super(new BorderLayout());
     74                this.prefName = iconName;
     75                ToggleDialogInit(name, iconName, tooltip, shortCut, preferredHeight);
     76        }
     77
     78        private void ToggleDialogInit(final String name, String iconName, String tooltip, ShortCut shortCut, int preferredHeight) {
    6779                setPreferredSize(new Dimension(330,preferredHeight));
    68                 action = new ToggleDialogAction(name, "dialogs/"+iconName, tooltip, shortCut, KeyEvent.ALT_MASK, iconName);
     80                action = new ToggleDialogAction(name, "dialogs/"+iconName, tooltip, shortCut, iconName);
    6981                String helpId = "Dialog/"+getClass().getName().substring(getClass().getName().lastIndexOf('.')+1);
    7082                action.putValue("help", helpId.substring(0, helpId.length()-6));
    7183                setLayout(new BorderLayout());
  • src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java

     
    1919import org.openstreetmap.josm.command.Command;
    2020import org.openstreetmap.josm.gui.MapFrame;
    2121import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
     22import org.openstreetmap.josm.tools.ShortCut;
    2223
    2324public class CommandStackDialog extends ToggleDialog implements CommandQueueListener {
    2425
     
    2627    private JTree tree = new JTree(treeModel);
    2728
    2829        public CommandStackDialog(final MapFrame mapFrame) {
    29                 super(tr("Command Stack"), "commandstack", tr("Open a list of all commands (undo buffer)."), KeyEvent.VK_O, 100);
     30                super(tr("Command Stack"), "commandstack", tr("Open a list of all commands (undo buffer)."),
     31                ShortCut.registerShortCut("subwindow:commandstack", tr("Toggle command stack"), KeyEvent.VK_O, ShortCut.GROUP_LAYER), 100);
    3032                Main.main.undoRedo.listenerCommands.add(this);
    31                        
     33
    3234                tree.setRootVisible(false);
    3335                tree.setShowsRootHandles(true);
    3436                tree.expandRow(0);
  • src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

     
    3939import org.openstreetmap.josm.tools.DontShowAgainInfo;
    4040import org.openstreetmap.josm.tools.ImageProvider;
    4141import org.openstreetmap.josm.tools.ImageProvider.OverlayPosition;
     42import org.openstreetmap.josm.tools.ShortCut;
    4243
    4344/**
    4445 * A component that manages the list of all layers and react to selection changes
     
    157158         * Create an layerlist and attach it to the given mapView.
    158159         */
    159160        public LayerListDialog(MapFrame mapFrame) {
    160                 super(tr("Layers"), "layerlist", tr("Open a list of all loaded layers."), KeyEvent.VK_L, 100);
     161                super(tr("Layers"), "layerlist", tr("Open a list of all loaded layers."),
     162                ShortCut.registerShortCut("subwindow:layers", tr("Toggle layer window"), KeyEvent.VK_L, ShortCut.GROUP_LAYER), 100);
    161163                instance = new JList(model);
    162164                listScrollPane = new JScrollPane(instance);
    163165                add(listScrollPane, BorderLayout.CENTER);
  • src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java

     
    3131import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    3232import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
    3333import org.openstreetmap.josm.tools.GBC;
     34import org.openstreetmap.josm.tools.ShortCut;
    3435
    3536/**
    3637 * A dialog showing all known relations, with buttons to add, edit, and
    37  * delete them. 
    38  * 
     38 * delete them.
     39 *
    3940 * We don't have such dialogs for nodes, segments, and ways, becaus those
    4041 * objects are visible on the map and can be selected there. Relations are not.
    4142 *
     
    5455        private JList displaylist = new JList(list);
    5556
    5657        public RelationListDialog() {
    57                 super(tr("Relations"), "relationlist", tr("Open a list of all relations."), KeyEvent.VK_R, 150);
     58                super(tr("Relations"), "relationlist", tr("Open a list of all relations."),
     59                ShortCut.registerShortCut("subwindow:relations", tr("Toggle relations window"), KeyEvent.VK_R, ShortCut.GROUP_LAYER), 150);
    5860                displaylist.setCellRenderer(new OsmPrimitivRenderer());
    5961                displaylist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    6062                displaylist.addMouseListener(new MouseAdapter(){
     
    7072                add(new JScrollPane(displaylist), BorderLayout.CENTER);
    7173
    7274                JPanel buttonPanel = new JPanel(new GridLayout(1,4));
    73                
     75
    7476                buttonPanel.add(new SideButton(marktr("New"), "addrelation", "Selection", tr("Create a new relation"), new ActionListener() {
    7577                        public void actionPerformed(ActionEvent e) {
    7678                                // call relation editor with null argument to create new relation
    7779                                new RelationEditor(null).setVisible(true);
    7880                        }
    7981                }), GBC.std());
    80                
     82
    8183                buttonPanel.add(new SideButton(marktr("Select"), "select", "Selection", tr("Select this relation"), new ActionListener() {
    8284                        public void actionPerformed(ActionEvent e) {
    8385                                // replace selection with the relation from the list
    8486                                Main.ds.setSelected((Relation)displaylist.getSelectedValue());
    8587                        }
    8688                }), GBC.std());
    87                
     89
    8890                buttonPanel.add(new SideButton(marktr("Edit"), "edit", "Selection", tr( "Open an editor for the selected relation"), new ActionListener() {
    8991                        public void actionPerformed(ActionEvent e) {
    9092                                Relation toEdit = (Relation) displaylist.getSelectedValue();
    9193                                if (toEdit != null)
    92                                         new RelationEditor(toEdit).setVisible(true);                           
     94                                        new RelationEditor(toEdit).setVisible(true);
    9395                        }
    9496                }), GBC.std());
    95                
     97
    9698                buttonPanel.add(new SideButton(marktr("Delete"), "delete", "Selection", tr("Delete the selected relation"), new ActionListener() {
    9799                        public void actionPerformed(ActionEvent e) {
    98100                                Relation toDelete = (Relation) displaylist.getSelectedValue();
     
    110112                super.setVisible(b);
    111113                if (b) updateList();
    112114        }
    113        
     115
    114116        public void updateList() {
    115117                list.setSize(Main.ds.relations.size());
    116118                int i = 0;
     
    120122                }
    121123                list.setSize(i);
    122124        }
    123        
     125
    124126        public void activeLayerChange(Layer a, Layer b) {
    125127                if ((a == null || a instanceof OsmDataLayer) && b instanceof OsmDataLayer) {
    126128                        if (a != null) ((OsmDataLayer)a).listenerDataChanged.remove(this);
     
    129131                        repaint();
    130132                }
    131133        }
    132        
     134
    133135        public void layerRemoved(Layer a) {
    134136                if (a instanceof OsmDataLayer) {
    135137                        ((OsmDataLayer)a).listenerDataChanged.remove(this);
     
    139141                if (a instanceof OsmDataLayer) {
    140142                        ((OsmDataLayer)a).listenerDataChanged.add(this);
    141143                }
    142         }       
     144        }
    143145        public void dataChanged(OsmDataLayer l) {
    144146                updateList();
    145147                repaint();
    146148        }
    147        
     149
    148150        /**
    149151         * Returns the currently selected relation, or null.
    150          * 
     152         *
    151153         * @return the currently selected relation, or null
    152154         */
    153155        public Relation getCurrentRelation() {
     
    156158
    157159        /**
    158160         * Adds a selection listener to the relation list.
    159          * 
     161         *
    160162         * @param listener the listener to add
    161163         */
    162164        public void addListSelectionListener(ListSelectionListener listener) {
     
    165167
    166168        /**
    167169         * Removes a selection listener from the relation list.
    168          * 
     170         *
    169171         * @param listener the listener to remove
    170172         */
    171173        public void removeListSelectionListener(ListSelectionListener listener) {
  • src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java

     
    2020import org.openstreetmap.josm.data.osm.DataSet;
    2121import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2222import org.openstreetmap.josm.data.osm.User;
     23import org.openstreetmap.josm.tools.ShortCut;
    2324
    2425/**
    25  * Displays a dialog with all users who have last edited something in the 
     26 * Displays a dialog with all users who have last edited something in the
    2627 * selection area, along with the number of objects.
    27  * 
     28 *
    2829 * @author Frederik Ramm <frederik@remote.org>
    2930 */
    3031public class UserListDialog extends ToggleDialog implements SelectionChangedListener {
     
    4445        private JTable userTable = new JTable(data);
    4546
    4647    private static User anonymousUser = User.get("(anonymous users)");
    47                        
     48
    4849        public UserListDialog() {
    49                 super(tr("Authors"), "userlist", tr("Open a list of people working on the selected objects."), KeyEvent.VK_A, 150);
    50                
     50                super(tr("Authors"), "userlist", tr("Open a list of people working on the selected objects."),
     51                ShortCut.registerShortCut("subwindow:authors", tr("Toggle authors window"), KeyEvent.VK_A, ShortCut.GROUP_LAYER), 150);
     52
    5153                data.setColumnIdentifiers(new String[]{tr("Author"),tr("# Objects"),"%"});
    5254                userTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    5355                add(new JScrollPane(userTable), BorderLayout.CENTER);
    5456                selectionChanged(Main.ds.getSelected());
    55                
     57
    5658                DataSet.selListeners.add(this);
    5759        }
    5860
     
    6971        public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
    7072                if (!isVisible())
    7173                        return;
    72                
     74
    7375                class UserCount {
    7476                        User user;
    7577                        int count;
    7678                        UserCount(User user, int count) { this.user=user; this.count=count; }
    7779                }
    78                
     80
    7981                if (data == null)
    8082                        return; // selection changed may be received in base class constructor before init
    81                
     83
    8284                data.setRowCount(0);
    83                
     85
    8486                HashMap<User,UserCount> counters = new HashMap<User,UserCount>();
    8587                int all = 0;
    8688                for (OsmPrimitive p : newSelection) {
    8789            User u = p.user;
    8890            if (u == null) u = anonymousUser;
    8991            UserCount uc = counters.get(u);
    90             if (uc == null) 
     92            if (uc == null)
    9193                counters.put(u, uc = new UserCount(u, 0));
    9294            uc.count++;
    9395            all++;
     
    9597                UserCount[] ucArr = new UserCount[counters.size()];
    9698                counters.values().toArray(ucArr);
    9799                Arrays.sort(ucArr, new Comparator<UserCount>() {
    98                         public int compare(UserCount a, UserCount b) { 
     100                        public int compare(UserCount a, UserCount b) {
    99101                                return (a.count<b.count) ? 1 : (a.count>b.count) ? -1 : 0;
    100102                        }
    101103                });
    102                
     104
    103105                for (UserCount uc : ucArr) {
    104106                        data.addRow(new Object[] { uc.user.name, uc.count, uc.count * 100 / all });
    105107                }
  • src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java

     
    6363import org.openstreetmap.josm.gui.tagging.TaggingPreset;
    6464import org.openstreetmap.josm.tools.AutoCompleteComboBox;
    6565import org.openstreetmap.josm.tools.GBC;
     66import org.openstreetmap.josm.tools.ShortCut;
    6667
    6768/**
    6869 * This dialog displays the properties of the current selected primitives.
     
    8788         * Used to display relation names in the membership table
    8889         */
    8990        private NameVisitor nameVisitor = new NameVisitor();
    90        
     91
    9192        /**
    9293         * Watches for double clicks and from editing or new property, depending on the
    9394         * location, the click was.
     
    133134                        return;
    134135                }
    135136                String msg = "<html>"+trn("This will change up to {0} object.", "This will change up to {0} objects.", sel.size(), sel.size())+"<br><br>("+tr("An empty value deletes the key.", key)+")</html>";
    136                
     137
    137138                JPanel panel = new JPanel(new BorderLayout());
    138139                panel.add(new JLabel(msg), BorderLayout.NORTH);
    139140
     
    158159                            if (c instanceof JLabel) {
    159160                                String str = null;
    160161                                        str=(String) value;
    161                                         if (valueCount.containsKey(objKey)){ 
     162                                        if (valueCount.containsKey(objKey)){
    162163                                                Map<String, Integer> m=valueCount.get(objKey);
    163164                                                if (m.containsKey(str)) {
    164165                                                        str+="("+m.get(str)+")";
     
    268269        /**
    269270         * This simply fires up an relation editor for the relation shown; everything else
    270271         * is the editor's business.
    271          * 
     272         *
    272273         * @param row
    273274         */
    274         void membershipEdit(int row) { 
    275                 final RelationEditor editor = new RelationEditor((Relation)membershipData.getValueAt(row, 0), 
     275        void membershipEdit(int row) {
     276                final RelationEditor editor = new RelationEditor((Relation)membershipData.getValueAt(row, 0),
    276277                                (Collection<RelationMember>) membershipData.getValueAt(row, 1) );
    277278                editor.setVisible(true);
    278279        }
     
    295296                final AutoCompleteComboBox keys = new AutoCompleteComboBox();
    296297                keys.setPossibleItems(allData.keySet());
    297298                keys.setEditable(true);
    298                
     299
    299300                p.add(keys, BorderLayout.CENTER);
    300301
    301302                JPanel p2 = new JPanel(new BorderLayout());
     
    402403                        return String.class;
    403404                }
    404405        };
    405        
     406
    406407        /**
    407408         * The properties list.
    408409         */
     
    416417         * Create a new PropertiesDialog
    417418         */
    418419        public PropertiesDialog(MapFrame mapFrame) {
    419                 super(tr("Properties/Memberships"), "propertiesdialog", tr("Properties for selected objects."), KeyEvent.VK_P, 150);
     420                super(tr("Properties/Memberships"), "propertiesdialog", tr("Properties for selected objects."),
     421                ShortCut.registerShortCut("subwindow:properies", tr("Toggle properties window"), KeyEvent.VK_P, ShortCut.GROUP_LAYER), 150);
    420422
    421423                // ---------------------------------------
    422                 // This drop-down is really deprecated but we offer people a chance to 
    423                 // activate it if they really want. Presets should be used from the 
     424                // This drop-down is really deprecated but we offer people a chance to
     425                // activate it if they really want. Presets should be used from the
    424426                // menu.
    425                 if (TaggingPresetPreference.taggingPresets.size() > 0 && 
     427                if (TaggingPresetPreference.taggingPresets.size() > 0 &&
    426428                                Main.pref.getBoolean("taggingpreset.in-properties-dialog", false)) {
    427429                        Vector<ActionListener> allPresets = new Vector<ActionListener>();
    428430                        for (final TaggingPreset p : TaggingPresetPreference.taggingPresets)
     
    447449                taggingPresets.setRenderer(new TaggingCellRenderer());
    448450
    449451                // setting up the properties table
    450                
     452
    451453                propertyData.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
    452454                propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    453        
     455
    454456                propertyTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer(){
    455457                        @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    456458                                Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
     
    475477                                return c;
    476478                        }
    477479                });
    478                
     480
    479481                // setting up the membership table
    480                
     482
    481483                membershipData.setColumnIdentifiers(new String[]{tr("Member Of"),tr("Role")});
    482484                membershipTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    483                
     485
    484486                membershipTable.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
    485487                        @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    486488                                Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
     
    491493                                return c;
    492494                        }
    493495                });
    494                
     496
    495497                membershipTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
    496498                        @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    497499                                Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
    498500                                if (c instanceof JLabel) {
    499501                                        Collection<RelationMember> col = (Collection<RelationMember>) value;
    500                                        
     502
    501503                                        String text = null;
    502504                                        for (RelationMember r : col) {
    503505                                                if (text == null) {
     
    508510                                                        break;
    509511                                                }
    510512                                        }
    511                                        
     513
    512514                                        ((JLabel)c).setText(text);
    513515                                }
    514516                                return c;
    515517                        }
    516518                });
    517                
     519
    518520                // combine both tables and wrap them in a scrollPane
    519521                JPanel bothTables = new JPanel();
    520522                bothTables.setLayout(new GridBagLayout());
     
    522524                bothTables.add(propertyTable, GBC.eol().fill(GBC.BOTH));
    523525                bothTables.add(membershipTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
    524526                bothTables.add(membershipTable, GBC.eol().fill(GBC.BOTH));
    525                
     527
    526528                DblClickWatch dblClickWatch = new DblClickWatch();
    527529                propertyTable.addMouseListener(dblClickWatch);
    528530                membershipTable.addMouseListener(dblClickWatch);
     
    564566                                                        Main.main.undoRedo.add(new ChangeCommand(cur, rel));
    565567                                                        selectionChanged(sel); // update whole table
    566568                                                }
    567                                                
     569
    568570                                        }
    569571                                }
    570572                                else
     
    586588                                }
    587589                        }
    588590                };
    589                
     591
    590592                buttonPanel.add(new SideButton(marktr("Add"),"add","Properties",tr("Add a new key/value pair to all objects"), KeyEvent.VK_A, buttonAction));
    591593                buttonPanel.add(new SideButton(marktr("Edit"),"edit","Properties",tr("Edit the value of the selected key for all objects"), KeyEvent.VK_E, buttonAction));
    592594                buttonPanel.add(new SideButton(marktr("Delete"),"delete","Properties",tr("Delete the selected key in all objects"), KeyEvent.VK_D, buttonAction));
     
    610612                        propertyTable.getCellEditor().cancelCellEditing();
    611613
    612614                // re-load property data
    613                
     615
    614616                propertyData.setRowCount(0);
    615617
    616618                Map<String, Integer> keyCount = new HashMap<String, Integer>();
     
    638640                        }
    639641                        propertyData.addRow(new Object[]{e.getKey(), e.getValue()});
    640642                }
    641                
     643
    642644                // re-load membership data
    643645                // this is rather expensive since we have to walk through all members of all existing relationships.
    644646                // could use back references here for speed if necessary.
    645                
     647
    646648                membershipData.setRowCount(0);
    647                
     649
    648650                TreeMap<Relation, Collection<RelationMember>> roles = new TreeMap<Relation, Collection<RelationMember>>();
    649651                for (Relation r : Main.ds.relations) {
    650652                        if (!r.deleted && !r.incomplete) {
     
    660662                                }
    661663                        }
    662664                }
    663                
     665
    664666                for (Entry<Relation, Collection<RelationMember>> e : roles.entrySet()) {
    665667                        membershipData.addRow(new Object[]{e.getKey(), e.getValue()});
    666668                }
    667                
     669
    668670                membershipTable.getTableHeader().setVisible(membershipData.getRowCount() > 0);
    669671        }
    670672}
  • src/org/openstreetmap/josm/gui/MainApplication.java

     
    3030 */
    3131public class MainApplication extends Main {
    3232        /**
     33         * Allow subclassing (see JOSM.java)
     34         */
     35        public MainApplication() {}
     36
     37        /**
    3338         * Construct an main frame, ready sized and operating. Does not
    3439         * display the frame.
    3540         */
     
    6570
    6671                Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
    6772
     73                // initialize the plaform hook, and
     74                Main.determinePlatformHook();
     75                // call the really early hook before we anything else
     76                Main.platform.preStartupHook();
     77
    6878                // construct argument table
    6979                List<String> argList = Arrays.asList(argArray);
    7080                final Map<String, Collection<String>> args = new HashMap<String, Collection<String>>();
     
    137147                                tr("Activating the updated plugins failed. Check if JOSM has the permission to overwrite the existing ones."),
    138148                                tr("Plugins"), JOptionPane.ERROR_MESSAGE);
    139149                }
    140                
     150
    141151                // load the early plugins
    142152                splash.setStatus(tr("Loading early plugins"));
    143153                Main.loadPlugins(true, language);
    144154
    145155                if (argList.contains("--help") || argList.contains("-?") || argList.contains("-h")) {
     156                        // TODO: put in a platformHook for system that have no console by default
    146157                        System.out.println(tr("Java OpenStreetMap Editor")+"\n\n"+
    147158                                        tr("usage")+":\n"+
    148159                                        "\tjava -jar josm.jar <option> <option> <option>...\n\n"+
     
    191202                        }
    192203                });
    193204        }
     205
    194206}
  • src/org/openstreetmap/josm/gui/MapView.java

     
    2525
    2626import org.openstreetmap.josm.Main;
    2727import org.openstreetmap.josm.actions.AutoScaleAction;
     28import org.openstreetmap.josm.actions.JosmAction;
    2829import org.openstreetmap.josm.actions.MoveAction;
    2930import org.openstreetmap.josm.data.Bounds;
    3031import org.openstreetmap.josm.data.SelectionChangedListener;
     
    8283         * The layer from the layers list that is currently active.
    8384         */
    8485        private Layer activeLayer;
    85        
     86
    8687        /**
    8788         * The last event performed by mouse.
    8889         */
    8990        public MouseEvent lastMEvent;
    9091
    9192        private LinkedList<MapViewPaintable> temporaryLayers = new LinkedList<MapViewPaintable>();
    92        
     93
    9394        private BufferedImage offscreenBuffer;
    94        
     95
    9596        /**
    9697         * The listener of the active layer changes.
    9798         * @deprecated Use Layer.listener instead.
     
    106107                                new AutoScaleAction("data").actionPerformed(null);
    107108
    108109                                new MapMover(MapView.this, Main.contentPane);
    109                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, java.awt.event.InputEvent.SHIFT_MASK), "UP");
    110                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, java.awt.event.InputEvent.SHIFT_MASK), "DOWN");
    111                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, java.awt.event.InputEvent.SHIFT_MASK), "LEFT");
    112                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, java.awt.event.InputEvent.SHIFT_MASK), "RIGHT");
     110                                JosmAction mv;
     111                                mv = new MoveAction(MoveAction.Direction.UP);
     112                                if (mv.getShortCut() != null) {
     113                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "UP");
     114                                        Main.contentPane.getActionMap().put("UP", mv);
     115                                }
     116                                mv = new MoveAction(MoveAction.Direction.DOWN);
     117                                if (mv.getShortCut() != null) {
     118                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "DOWN");
     119                                        Main.contentPane.getActionMap().put("DOWN", mv);
     120                                }
     121                                mv = new MoveAction(MoveAction.Direction.LEFT);
     122                                if (mv.getShortCut() != null) {
     123                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "LEFT");
     124                                        Main.contentPane.getActionMap().put("LEFT", mv);
     125                                }
     126                                mv = new MoveAction(MoveAction.Direction.RIGHT);
     127                                if (mv.getShortCut() != null) {
     128                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "RIGHT");
     129                                        Main.contentPane.getActionMap().put("RIGHT", mv);
     130                                }
    113131
    114                                 Main.contentPane.getActionMap().put("UP", new MoveAction(MoveAction.Direction.UP));
    115                                 Main.contentPane.getActionMap().put("DOWN", new MoveAction(MoveAction.Direction.DOWN));
    116                                 Main.contentPane.getActionMap().put("LEFT", new MoveAction(MoveAction.Direction.LEFT));
    117                                 Main.contentPane.getActionMap().put("RIGHT", new MoveAction(MoveAction.Direction.RIGHT));
    118                                
    119 
    120132                                MapSlider zoomSlider = new MapSlider(MapView.this);
    121133                                add(zoomSlider);
    122134                                zoomSlider.setBounds(3, 0, 114, 30);
     
    275287                for (MapViewPaintable mvp : temporaryLayers) {
    276288                        mvp.paint(tempG, this);
    277289                }
    278                
     290
    279291                // draw world borders
    280292                tempG.setColor(Color.WHITE);
    281293                Bounds b = new Bounds();
     
    287299                int y2 = Math.max(min.y, max.y);
    288300                if (x1 > 0 || y1 > 0 || x2 < getWidth() || y2 < getHeight())
    289301                        tempG.drawRect(x1, y1, x2-x1+1, y2-y1+1);
    290                
     302
    291303                if (playHeadMarker != null)
    292304                        playHeadMarker.paint(tempG, this);
    293305
     
    403415                if (oldScale != scale)
    404416                        firePropertyChange("scale", oldScale, scale);
    405417        }
    406        
     418
    407419        public boolean addTemporaryLayer(MapViewPaintable mvp) {
    408420                if (temporaryLayers.contains(mvp)) return false;
    409421                return temporaryLayers.add(mvp);
    410422        }
    411        
     423
    412424        public boolean removeTemporaryLayer(MapViewPaintable mvp) {
    413425                return temporaryLayers.remove(mvp);
    414426        }
  • src/org/openstreetmap/josm/gui/MainMenu.java

     
    1212import javax.swing.JMenuBar;
    1313import javax.swing.JMenuItem;
    1414import javax.swing.KeyStroke;
     15import java.awt.event.KeyEvent;
    1516
    1617import org.openstreetmap.josm.Main;
    1718import org.openstreetmap.josm.actions.AboutAction;
     
    5859import org.openstreetmap.josm.actions.audio.AudioSlowerAction;
    5960import org.openstreetmap.josm.actions.search.SearchAction;
    6061import org.openstreetmap.josm.data.DataSetChecker;
     62import org.openstreetmap.josm.tools.ShortCut;
    6163
    6264/**
    6365 * This is the JOSM main menu bar. It is overwritten to initialize itself and provide
     
    7880        public final DownloadAction download = new DownloadAction();
    7981        public final JosmAction upload = new UploadAction();
    8082        public final JosmAction exit = new ExitAction();
    81    
     83
    8284        /* Edit menu */
    8385        public final UndoAction undo = new UndoAction();
    8486        public final RedoAction redo = new RedoAction();
    8587        public final JosmAction copy = new CopyAction();
    8688        public final JosmAction paste = new PasteAction();
    8789        public final JosmAction delete = new DeleteAction();
    88         public final JosmAction pasteTags = new PasteTagsAction(copy); 
    89         public final JosmAction duplicate = new DuplicateAction(); 
     90        public final JosmAction pasteTags = new PasteTagsAction(copy);
     91        public final JosmAction duplicate = new DuplicateAction();
    9092        public final JosmAction selectAll = new SelectAllAction();
    9193        public final JosmAction unselectAll = new UnselectAllAction();
    9294    /* crashes when loading data, if using JosmAction for search */
    9395        public final JosmAction search = new SearchAction();
    9496        public final JosmAction preferences = new PreferencesAction();
    95        
     97
    9698        /* View menu */
    97    
     99
    98100        /* Tools menu */
    99101        public final JosmAction splitWay = new SplitWayAction();
    100102        public final JosmAction combineWay = new CombineWayAction();
     
    120122        public final HelpAction help = new HelpAction();
    121123        public final JosmAction about = new AboutAction();
    122124        public final HistoryInfoAction historyinfo = new HistoryInfoAction();
    123        
     125
    124126        public final JMenu fileMenu = new JMenu(tr("File"));
    125127        public final JMenu editMenu = new JMenu(tr("Edit"));
    126128        public final JMenu viewMenu = new JMenu(tr("View"));
     
    128130        public final JMenu audioMenu = new JMenu(tr("Audio"));
    129131        public final JMenu presetsMenu = new JMenu(tr("Presets"));
    130132        public final JMenu helpMenu = new JMenu(tr("Help"));
    131        
    132133
     134        /**
     135         * Add a JosmAction to a menu.
     136         *
     137         * This method handles all the shortcut handling.
     138         * It also makes sure that actions that are handled by the
     139         * OS are not duplicated on the menu.
     140         */
     141        public static void add(JMenu menu, JosmAction action) {
     142                if (!action.getShortCut().getAutomatic()) {
     143                        JMenuItem menuitem = menu.add(action);
     144                        KeyStroke ks = action.getShortCut().getKeyStroke();
     145                        if (ks != null) {
     146                                menuitem.setAccelerator(ks);
     147                        }
     148                }
     149        }
     150
     151        /**
     152         * Add a menu to the main menu.
     153         *
     154         * This method handles all the shortcut handling.
     155         */
     156        public void add(JMenu menu, int mnemonicKey, String shortName) {
     157                ShortCut.registerShortCut("menu:"+shortName, shortName+" menu", mnemonicKey, ShortCut.GROUP_MNEMONIC).setMnemonic(menu);
     158                add(menu);
     159        }
     160
    133161        public MainMenu() {
    134         JMenuItem current;
    135        
    136                 fileMenu.setMnemonic('F');
    137                 current = fileMenu.add(newAction);
    138                 current.setAccelerator(newAction.shortCut);
    139                 current = fileMenu.add(open);
    140                 current.setAccelerator(open.shortCut);
     162                JMenuItem current;
     163
     164                add(fileMenu, newAction);
     165                add(fileMenu, open);
    141166                fileMenu.addSeparator();
    142                 current = fileMenu.add(save);
    143                 current.setAccelerator(save.shortCut);
    144                 current = fileMenu.add(saveAs);
    145                 current.setAccelerator(saveAs.shortCut);
    146                 current = fileMenu.add(gpxExport);
    147                 current.setAccelerator(gpxExport.shortCut);
     167                add(fileMenu, save);
     168                add(fileMenu, saveAs);
     169                add(fileMenu, gpxExport);
    148170                fileMenu.addSeparator();
    149                 current = fileMenu.add(download);
    150                 current.setAccelerator(download.shortCut);
    151                 current = fileMenu.add(upload);
    152                 current.setAccelerator(upload.shortCut);
    153                 fileMenu.addSeparator();
    154                 current = fileMenu.add(exit);
    155                 current.setAccelerator(exit.shortCut);
    156                 add(fileMenu);
     171                add(fileMenu, download);
     172                add(fileMenu, upload);
     173                add(fileMenu, exit);
     174                add(fileMenu, KeyEvent.VK_F, "file");
    157175
    158                 editMenu.setMnemonic('E');
    159                 current = editMenu.add(undo);
    160                 current.setAccelerator(undo.shortCut);
    161                 current = editMenu.add(redo);
    162                 current.setAccelerator(redo.shortCut);
     176                add(editMenu, undo);
     177                add(editMenu, redo);
    163178                editMenu.addSeparator();
    164                 current = editMenu.add(copy);
    165                 current.setAccelerator(copy.shortCut);
    166                 current = editMenu.add(delete);
    167                 current.setAccelerator(delete.shortCut);
    168                 current = editMenu.add(paste);
    169                 current.setAccelerator(paste.shortCut);
    170                 current = editMenu.add(pasteTags);
    171                 current.setAccelerator(pasteTags.shortCut);
    172                 current = editMenu.add(duplicate);
    173                 current.setAccelerator(duplicate.shortCut);
     179                add(editMenu, copy);
     180                add(editMenu, delete);
     181                add(editMenu, paste);
     182                add(editMenu, pasteTags);
     183                add(editMenu, duplicate);
    174184                editMenu.addSeparator();
    175                 current = editMenu.add(selectAll);
    176                 current.setAccelerator(selectAll.shortCut);
    177                 current = editMenu.add(unselectAll);
    178                 current.setAccelerator(unselectAll.shortCut);
     185                add(editMenu, selectAll);
     186                add(editMenu, unselectAll);
    179187                editMenu.addSeparator();
    180                 current = editMenu.add(search);
    181                 current.setAccelerator(search.shortCut);
     188                add(editMenu, search);
    182189                editMenu.addSeparator();
    183                 current = editMenu.add(preferences);
    184                 current.setAccelerator(preferences.shortCut);
    185                 add(editMenu);
    186                
    187                 viewMenu.setMnemonic('V');
    188         for (String mode : AutoScaleAction.modes) {
    189             JosmAction autoScaleAction = new AutoScaleAction(mode);
    190                         current = viewMenu.add(autoScaleAction);
    191                     current.setAccelerator(autoScaleAction.shortCut);
    192         }
    193         viewMenu.addSeparator();
    194         JosmAction a = new ZoomOutAction();
    195                 viewMenu.add(a).setAccelerator(a.shortCut);
    196                 a = new ZoomInAction();
    197                 viewMenu.add(a).setAccelerator(a.shortCut);
     190                add(editMenu, preferences);
     191                add(editMenu, KeyEvent.VK_E, "edit");
    198192
     193                for (String mode : AutoScaleAction.modes) {
     194                        JosmAction autoScaleAction = new AutoScaleAction(mode);
     195                        add(viewMenu, autoScaleAction);
     196                }
    199197                viewMenu.addSeparator();
    200 
     198                add(viewMenu, new ZoomOutAction());
     199                add(viewMenu, new ZoomInAction());
     200                viewMenu.addSeparator();
    201201                // TODO move code to an "action" like the others?
    202         final JCheckBoxMenuItem wireframe = new JCheckBoxMenuItem(tr("Wireframe view"));
     202                final JCheckBoxMenuItem wireframe = new JCheckBoxMenuItem(tr("Wireframe view"));
    203203                wireframe.setSelected(Main.pref.getBoolean("draw.wireframe", false));
    204         wireframe.setAccelerator(KeyStroke.getKeyStroke("ctrl W"));
    205         wireframe.addActionListener(new ActionListener() {
    206                 public void actionPerformed(ActionEvent ev) {
    207                         Main.pref.put("draw.wireframe", wireframe.isSelected());
    208                         if (Main.map != null) {
     204                wireframe.setAccelerator(ShortCut.registerShortCut("menu:view:wireframe", "Toggle Wireframe view", KeyEvent.VK_W, ShortCut.GROUP_MENU).getKeyStroke());
     205                wireframe.addActionListener(new ActionListener() {
     206                        public void actionPerformed(ActionEvent ev) {
     207                                Main.pref.put("draw.wireframe", wireframe.isSelected());
     208                                if (Main.map != null) {
    209209                                        Main.map.mapView.repaint();
    210210                                }
    211                 }
    212         });
    213         viewMenu.add(wireframe);
    214        
    215                 add(viewMenu);
     211                        }
     212                });
     213                viewMenu.add(wireframe);
     214                add(viewMenu, KeyEvent.VK_V, "view");
    216215
    217                 toolsMenu.setMnemonic('T');
    218                 current = toolsMenu.add(splitWay);
    219                 current.setAccelerator(splitWay.shortCut);
    220                 current = toolsMenu.add(combineWay);
    221                 current.setAccelerator(combineWay.shortCut);
     216                add(toolsMenu, splitWay);
     217                add(toolsMenu, combineWay);
    222218                toolsMenu.addSeparator();
    223                 current = toolsMenu.add(reverseWay);
    224                 current.setAccelerator(reverseWay.shortCut);
     219                add(toolsMenu, reverseWay);
    225220                toolsMenu.addSeparator();
    226                 current = toolsMenu.add(alignInCircle);
    227                 current.setAccelerator(alignInCircle.shortCut);
    228                 current = toolsMenu.add(alignInLine);
    229                 current.setAccelerator(alignInLine.shortCut);
    230                 current = toolsMenu.add(alignInRect);
    231                 current.setAccelerator(alignInRect.shortCut);
     221                add(toolsMenu, alignInCircle);
     222                add(toolsMenu, alignInLine);
     223                add(toolsMenu, alignInRect);
    232224                toolsMenu.addSeparator();
    233                 current = toolsMenu.add(createCircle);
    234                 current.setAccelerator(createCircle.shortCut);
     225                add(toolsMenu, createCircle);
    235226                toolsMenu.addSeparator();
    236                 current = toolsMenu.add(mergeNodes);
    237                 current.setAccelerator(mergeNodes.shortCut);
    238                 current = toolsMenu.add(joinNodeWay);
    239                 current.setAccelerator(joinNodeWay.shortCut);
    240                 current = toolsMenu.add(unglueNodes);
    241                 current.setAccelerator(unglueNodes.shortCut);
    242                 add(toolsMenu);
     227                add(toolsMenu, mergeNodes);
     228                add(toolsMenu, joinNodeWay);
     229                add(toolsMenu, unglueNodes);
     230                add(toolsMenu, KeyEvent.VK_T, "tools");
    243231
    244232                if (! Main.pref.getBoolean("audio.menuinvisible")) {
    245                         audioMenu.setMnemonic('A');
    246                         current = audioMenu.add(audioPlayPause);
    247                         current.setAccelerator(audioPlayPause.shortCut);
    248                         current = audioMenu.add(audioNext);
    249                         current.setAccelerator(audioNext.shortCut);
    250                         current = audioMenu.add(audioPrev);
    251                         current.setAccelerator(audioPrev.shortCut);
    252                         current = audioMenu.add(audioFwd);
    253                         current.setAccelerator(audioFwd.shortCut);
    254                         current = audioMenu.add(audioBack);
    255                         current.setAccelerator(audioBack.shortCut);
    256                         current = audioMenu.add(audioSlower);
    257                         current.setAccelerator(audioSlower.shortCut);
    258                         current = audioMenu.add(audioFaster);
    259                         current.setAccelerator(audioFaster.shortCut);
    260                         add(audioMenu);
     233                        add(audioMenu, audioPlayPause);
     234                        add(audioMenu, audioNext);
     235                        add(audioMenu, audioPrev);
     236                        add(audioMenu, audioFwd);
     237                        add(audioMenu, audioBack);
     238                        add(audioMenu, audioSlower);
     239                        add(audioMenu, audioFaster);
     240                        add(audioMenu, KeyEvent.VK_A, "audio");
    261241                }
    262242
    263                 add(presetsMenu);
    264                 presetsMenu.setMnemonic('P');
    265                
    266                 helpMenu.setMnemonic('H');
     243                add(presetsMenu, KeyEvent.VK_P, "presets");
     244
    267245                JMenuItem check = new JMenuItem("DEBUG: Check Dataset");
    268246                check.addActionListener(new ActionListener(){
    269247                        public void actionPerformed(ActionEvent e) {
    270248                                DataSetChecker.check();
    271             }
     249                        }
    272250                });
    273                 current = helpMenu.add(check);
    274                 current = helpMenu.add(help);
    275                 //current.setAccelerator(help.shortCut);
    276                 current = helpMenu.add(about);
    277                 current.setAccelerator(about.shortCut);
    278                 current = helpMenu.add(historyinfo);
    279                 current.setAccelerator(historyinfo.shortCut);
    280                 add(helpMenu);
     251                helpMenu.add(check);
     252                current = helpMenu.add(help); // why is help not a JosmAction?
     253                current.setAccelerator(ShortCut.registerShortCut("system:help", tr("Help"), KeyEvent.VK_F1, ShortCut.GROUP_DIRECT).getKeyStroke());
     254                add(helpMenu, about);
     255                add(helpMenu, historyinfo);
     256                add(helpMenu, KeyEvent.VK_H, "help");
    281257    }
    282258}
  • src/org/openstreetmap/josm/gui/preferences/LafPreference.java

     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.awt.Component;
     7import java.lang.reflect.*;
    78
    89import javax.swing.DefaultListCellRenderer;
    910import javax.swing.JComboBox;
     
    2526
    2627        public void addGui(PreferenceDialog gui) {
    2728                lafCombo = new JComboBox(UIManager.getInstalledLookAndFeels());
    28                
     29
     30                // let's try to load additional LookAndFeels and put them into the list
     31                try {
     32                        Class Cquaqua = Class.forName("ch.randelshofer.quaqua.QuaquaLookAndFeel");
     33                        Object Oquaqua = Cquaqua.getConstructor((Class[])null).newInstance((Object[])null);
     34                        // no exception? Then Go!
     35                        lafCombo.addItem(
     36                                new UIManager.LookAndFeelInfo(((javax.swing.LookAndFeel)Oquaqua).getName(), "ch.randelshofer.quaqua.QuaquaLookAndFeel")
     37                        );
     38                } catch (Exception ex) {
     39                        // just ignore, Quaqua may not even be installed...
     40                        //System.out.println("Failed to load Quaqua: " + ex);
     41                }
     42
    2943                String laf = Main.pref.get("laf");
    3044                for (int i = 0; i < lafCombo.getItemCount(); ++i) {
    3145                        if (((LookAndFeelInfo)lafCombo.getItemAt(i)).getClassName().equals(laf)) {
  • src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java

     
    4040        public final JPanel connection = createPreferenceTab("connection", I18n.tr("Connection Settings"), I18n.tr("Connection Settings for the OSM server."));
    4141        public final JPanel map = createPreferenceTab("map", I18n.tr("Map Settings"), I18n.tr("Settings for the map projection and data interpretation."));
    4242        public final JPanel audio = createPreferenceTab("audio", I18n.tr("Audio Settings"), I18n.tr("Settings for the audio player and audio markers."));
    43        
     43
    4444        /**
    4545         * Construct a JPanel for the preference settings. Layout is GridBagLayout
    4646         * and a centered title label and the description are added.
     
    110110                settings.add(new PluginPreference());
    111111                settings.add(Main.toolbar);
    112112                settings.add(new AudioPreference());
    113                
     113                settings.add(new ShortcutPreference());
     114
    114115                for (PluginProxy plugin : Main.plugins) {
    115116                        PreferenceSetting p = plugin.getPreferenceSetting();
    116117                        if (p != null)
  • src/org/openstreetmap/josm/gui/MapMover.java

     
    1515import javax.swing.JComponent;
    1616import javax.swing.JPanel;
    1717import javax.swing.KeyStroke;
     18import org.openstreetmap.josm.tools.ShortCut;
     19import static org.openstreetmap.josm.tools.I18n.tr;
    1820
    1921import org.openstreetmap.josm.data.coor.EastNorth;
    2022
     
    7779                nc.addMouseListener(this);
    7880                nc.addMouseMotionListener(this);
    7981                nc.addMouseWheelListener(this);
    80                
    81                 String[] n = {",",".","up","right","down","left"};
    82                 int[] k = {KeyEvent.VK_COMMA, KeyEvent.VK_PERIOD, KeyEvent.VK_UP, KeyEvent.VK_RIGHT, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT};
    8382
    8483                if (contentPane != null) {
    85                         for (int i = 0; i < n.length; ++i) {
    86                                 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(k[i], KeyEvent.CTRL_DOWN_MASK), "MapMover.Zoomer."+n[i]);
    87                                 contentPane.getActionMap().put("MapMover.Zoomer."+n[i], new ZoomerAction(n[i]));
    88                         }
     84                        contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     85                                ShortCut.registerShortCut("system:movefocusright", tr("Map: Move right"), KeyEvent.VK_RIGHT, ShortCut.GROUP_HOTKEY).getKeyStroke(),
     86                                "MapMover.Zoomer.right");
     87                        contentPane.getActionMap().put("MapMover.Zoomer.right", new ZoomerAction("right"));
     88
     89                        contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     90                                ShortCut.registerShortCut("system:movefocusleft", tr("Map: Move left"), KeyEvent.VK_LEFT, ShortCut.GROUP_HOTKEY).getKeyStroke(),
     91                                "MapMover.Zoomer.left");
     92                        contentPane.getActionMap().put("MapMover.Zoomer.left", new ZoomerAction("left"));
     93
     94                        contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     95                                ShortCut.registerShortCut("system:movefocusup", tr("Map: Move up"), KeyEvent.VK_UP, ShortCut.GROUP_HOTKEY).getKeyStroke(),
     96                                "MapMover.Zoomer.up");
     97                        contentPane.getActionMap().put("MapMover.Zoomer.up", new ZoomerAction("up"));
     98
     99                        contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     100                                ShortCut.registerShortCut("system:movefocusdown", tr("Map: Move down"), KeyEvent.VK_DOWN, ShortCut.GROUP_HOTKEY).getKeyStroke(),
     101                                "MapMover.Zoomer.down");
     102                        contentPane.getActionMap().put("MapMover.Zoomer.down", new ZoomerAction("down"));
     103
     104                        contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     105                                ShortCut.registerShortCut("view:zoominalternate", tr("Map: Zoom in"), KeyEvent.VK_COMMA, ShortCut.GROUP_HOTKEY).getKeyStroke(),
     106                                "MapMover.Zoomer.in");
     107                        contentPane.getActionMap().put("MapMover.Zoomer.in", new ZoomerAction(","));
     108
     109                        contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     110                                ShortCut.registerShortCut("view:zoomoutalternate", tr("Map: Zoom out"), KeyEvent.VK_PERIOD, ShortCut.GROUP_HOTKEY).getKeyStroke(),
     111                                "MapMover.Zoomer.out");
     112                        contentPane.getActionMap().put("MapMover.Zoomer.out", new ZoomerAction("."));
    89113                }
    90114        }
    91115
     
    168192                double newHalfHeight = h*zoomfactor - h/2;
    169193                double centerx = e.getX() - (e.getX()-w/2)*newHalfWidth*2/w;
    170194                double centery = e.getY() - (e.getY()-h/2)*newHalfHeight*2/h;
    171                 EastNorth newCenter = nc.getEastNorth((int)centerx, (int)centery); 
     195                EastNorth newCenter = nc.getEastNorth((int)centerx, (int)centery);
    172196
    173197                nc.zoomTo(newCenter, nc.getScale()*zoom);
    174198        }
  • src/org/openstreetmap/josm/gui/MainApplet.java

     
    2828import org.openstreetmap.josm.actions.JosmAction;
    2929import org.openstreetmap.josm.data.ServerSidePreferences;
    3030import org.openstreetmap.josm.tools.GBC;
     31import org.openstreetmap.josm.tools.ShortCut;
    3132
    3233public class MainApplet extends JApplet {
    3334
    3435        public static final class UploadPreferencesAction extends JosmAction {
    3536                public UploadPreferencesAction() {
    36                         super(tr("Upload Preferences"), "upload-preferences", tr("Upload the current preferences to the server"), KeyEvent.VK_U, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK, true);
     37                        super(tr("Upload Preferences"), "upload-preferences", tr("Upload the current preferences to the server"),
     38                        ShortCut.registerShortCut("applet:uploadprefs", tr("Upload preferences"), KeyEvent.VK_U, ShortCut.GROUP_HOTKEY), true);
    3739        }
    3840            public void actionPerformed(ActionEvent e) {
    3941                ((ServerSidePreferences)Main.pref).upload();
     
    99101                Main.preConstructorInit(args);
    100102                Main.parent = this;
    101103                new MainCaller().postConstructorProcessCmdLine(args);
    102                
     104
    103105                MainMenu m = Main.main.menu; // shortcut
    104106
    105107                // remove offending stuff from JOSM (that would break the SecurityManager)
  • src/org/openstreetmap/josm/Main.java

     
    5858import org.openstreetmap.josm.plugins.PluginInformation;
    5959import org.openstreetmap.josm.plugins.PluginProxy;
    6060import org.openstreetmap.josm.tools.ImageProvider;
     61import org.openstreetmap.josm.tools.PlatformHook;
     62import org.openstreetmap.josm.tools.PlatformHookUnixoid;
     63import org.openstreetmap.josm.tools.PlatformHookWindows;
     64import org.openstreetmap.josm.tools.PlatformHookOsx;
     65import org.openstreetmap.josm.tools.ShortCut;
    6166
    6267abstract public class Main {
    6368        /**
     
    132137        }
    133138
    134139        /**
     140         * Platform specific code goes in here.
     141         * Plugins may replace it, however, some hooks will be called before any plugins have been loeaded.
     142         * So if you need to hook into those early ones, split your class and send the one with the early hooks
     143         * to the JOSM team for inclusion.
     144         */
     145        public static PlatformHook platform;
     146
     147        /**
    135148         * Set or clear (if passed <code>null</code>) the map.
    136149         */
    137150        public final void setMapFrame(final MapFrame map) {
     
    177190                        setMapFrame(null);
    178191        }
    179192
    180 
    181193        public Main() {
    182194                main = this;
     195//              platform = determinePlatformHook();
     196                platform.startupHook();
    183197                contentPane.add(panel, BorderLayout.CENTER);
    184198                panel.add(new GettingStarted(), BorderLayout.CENTER);
    185199                menu = new MainMenu();
    186200
    187201                undoRedo.listenerCommands.add(redoUndoListener);
    188                
     202
    189203                // creating toolbar
    190204                contentPane.add(toolbar.control, BorderLayout.NORTH);
    191205
    192                 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "Help");
     206                contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ShortCut.registerShortCut("system:help", tr("Help"), KeyEvent.VK_F1, ShortCut.GROUP_DIRECT).getKeyStroke(), "Help");
    193207                contentPane.getActionMap().put("Help", menu.help);
    194208
    195209                TaggingPresetPreference.initialize();
     
    234248                        if(!lang.equals("en"))
    235249                                plugins.add("lang-"+lang);
    236250                }
    237                
     251
    238252                if (plugins.isEmpty())
    239253                        return;
    240254                SortedMap<Integer, Collection<PluginInformation>> p = new TreeMap<Integer, Collection<PluginInformation>>();
     
    249263                        } else {
    250264                                if (early)
    251265                                        System.out.println("Plugin not found: "+pluginName); // do not translate
    252                                 else   
     266                                else
    253267                                        JOptionPane.showMessageDialog(Main.parent, tr("Plugin not found: {0}.", pluginName));
    254268                        }
    255269                }
    256                
     270
    257271                // iterate all plugins and collect all libraries of all plugins:
    258272                List<URL> allPluginLibraries = new ArrayList<URL>();
    259273                for (Collection<PluginInformation> c : p.values())
     
    289303                                        if (remove) {
    290304                                                plugins.remove(info.name);
    291305                                                String plist = null;
    292                                                 for (String pn : plugins) { 
     306                                                for (String pn : plugins) {
    293307                                                        if (plist==null) plist=""; else plist=plist+",";
    294308                                                        plist=plist+pn;
    295309                                                }
     
    414428        }
    415429
    416430        public static boolean breakBecauseUnsavedChanges() {
     431                ShortCut.savePrefs();
    417432                if (map != null) {
    418433                        boolean modified = false;
    419434                        boolean uploadedModified = false;
     
    470485
    471486                main.menu.open.openFile(new File(s));
    472487        }
     488
     489        protected static void determinePlatformHook() {
     490                String os = System.getProperty("os.name");
     491                if (os == null) {
     492                        System.err.println("Your operating system has no name, so I'm guessing its some kind of *nix.");
     493                        platform = new PlatformHookUnixoid();
     494                } else if (os.toLowerCase().startsWith("windows")) {
     495                        platform = new PlatformHookWindows();
     496                } else if (os.equals("Linux") || os.equals("Solaris") || os.equals("SunOS") || os.equals("AIX") || os.equals("FreeBSD")) {
     497                        platform = new PlatformHookUnixoid();
     498                } else if (os.toLowerCase().startsWith("mac os x")) {
     499                        platform = new PlatformHookOsx();
     500                } else {
     501                        System.err.println("I don't know your operating system '"+os+"', so I'm guessing its some kind of *nix.");
     502                        platform = new PlatformHookUnixoid();
     503                }
     504        }
     505
    473506}
  • build.xml

     
    3636                <delete file="dist/josm-custom.jar"/>
    3737                <jar destfile="dist/josm-custom.jar" basedir="build">
    3838                        <manifest>
    39                                 <attribute name="Main-class" value="org.openstreetmap.josm.gui.MainApplication" />
     39                                <attribute name="Main-class" value="JOSM" />
    4040                        </manifest>
    4141                </jar>
    4242        </target>