Changeset 1023 in josm for trunk/src/org/openstreetmap/josm


Ignore:
Timestamp:
2008-10-05T17:06:27+02:00 (16 years ago)
Author:
stoecker
Message:

close bug #1622. Keyboard shortcuts and specific OS handling

Location:
trunk/src/org/openstreetmap/josm
Files:
7 added
72 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/Main.java

    r966 r1023  
    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 {
     
    131136                System.out.println(msg);
    132137        }
     138
     139        /**
     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;
    133146
    134147        /**
     
    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);
     
    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
     
    235249                                plugins.add("lang-"+lang);
    236250                }
    237                
     251
    238252                if (plugins.isEmpty())
    239253                        return;
     
    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>();
     
    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;
     
    415429
    416430        public static boolean breakBecauseUnsavedChanges() {
     431                ShortCut.savePrefs();
    417432                if (map != null) {
    418433                        boolean modified = false;
     
    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}
  • trunk/src/org/openstreetmap/josm/actions/AboutAction.java

    r655 r1023  
    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 */
     
    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
  • trunk/src/org/openstreetmap/josm/actions/AlignInCircleAction.java

    r749 r1023  
    2020import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2121import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.tools.ShortCut;
    2223
    2324/**
     
    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
     
    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))
     
    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()];
  • trunk/src/org/openstreetmap/josm/actions/AlignInLineAction.java

    r627 r1023  
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1919import org.openstreetmap.josm.data.osm.Way;
     20import org.openstreetmap.josm.tools.ShortCut;
    2021
    2122/**
     
    2324 * roads that should be straight, but have side roads and
    2425 * therefore need multiple nodes)
    25  * 
     26 *
    2627 * @author Matthew Newton
    2728 */
     
    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
     
    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))
  • trunk/src/org/openstreetmap/josm/actions/AlignInRectangleAction.java

    r999 r1023  
    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
     
    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
     
    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."));
     
    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++)
     
    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());
     
    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++) {
  • trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java

    r948 r1023  
    1515import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    1616import org.openstreetmap.josm.gui.layer.Layer;
     17import org.openstreetmap.josm.tools.ShortCut;
    1718
    1819/**
     
    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);
     
    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();
  • trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java

    r734 r1023  
    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 */
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/CopyAction.java

    r627 r1023  
    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);
     
    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                }
     
    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; }
     
    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);
  • trunk/src/org/openstreetmap/josm/actions/CreateCircleAction.java

    r999 r1023  
    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 *
     
    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
  • trunk/src/org/openstreetmap/josm/actions/DeleteAction.java

    r770 r1023  
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112public final class DeleteAction extends JosmAction {
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/DiskAccessAction.java

    r693 r1023  
    1010
    1111import org.openstreetmap.josm.Main;
     12import org.openstreetmap.josm.tools.ShortCut;
    1213
    1314/**
     
    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");
     
    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());
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/DownloadAction.java

    r859 r1023  
    1717import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    1818import org.openstreetmap.josm.tools.GBC;
     19import org.openstreetmap.josm.tools.ShortCut;
    1920
    2021/**
     
    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));
  • trunk/src/org/openstreetmap/josm/actions/DuplicateAction.java

    r655 r1023  
    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 {
     
    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
     
    2829                Main.main.menu.paste.actionPerformed(e);
    2930    }
    30        
     31
    3132        public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
    3233                setEnabled(! newSelection.isEmpty());
  • trunk/src/org/openstreetmap/josm/actions/ExitAction.java

    r655 r1023  
    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 */
     
    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
  • trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java

    r872 r1023  
    3434import org.openstreetmap.josm.io.GpxWriter;
    3535import org.openstreetmap.josm.tools.GBC;
     36import org.openstreetmap.josm.tools.ShortCut;
    3637
    3738/**
     
    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        }
     
    7173                        file = new File(fn);
    7274                }
    73                
     75
    7476                // open the dialog asking for options
    7577                JPanel p = new JPanel(new GridBagLayout());
     
    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);
     
    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();
     
    113115                if (answer != JOptionPane.OK_OPTION)
    114116                        return;
    115                
     117
    116118                Main.pref.put("lastAddAuthor", author.isSelected());
    117119                if (authorName.getText().length() != 0)
     
    136138                        x.printStackTrace();
    137139                        JOptionPane.showMessageDialog(Main.parent, tr("Error while exporting {0}", fn)+":\n"+x.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE);
    138                 }               
    139         }
    140        
     140                }
     141        }
     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,
     
    159161                        final JLabel copyrightYearLabel,
    160162                        final JLabel warning) {
    161                
     163
    162164                ActionListener authorActionListener = new ActionListener(){
    163165                        public void actionPerformed(ActionEvent e) {
     
    183185                                };
    184186                authorName.addKeyListener(authorNameListener);
    185                
     187
    186188                predefined.addActionListener(new ActionListener(){
    187189                        public void actionPerformed(ActionEvent e) {
  • trunk/src/org/openstreetmap/josm/actions/HistoryInfoAction.java

    r999 r1023  
    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
  • trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java

    r627 r1023  
    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
  • trunk/src/org/openstreetmap/josm/actions/JosmAction.java

    r627 r1023  
    22package org.openstreetmap.josm.actions;
    33
     4import java.awt.event.InputEvent;
    45
    56import javax.swing.AbstractAction;
     
    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);
     60        }
     61
     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);
    4190        }
    4291
    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();
     
    58107                return;
    59108        }
    60        
     109
    61110        /**
    62111         * needs to be overridden to be useful
     
    65114                return;
    66115        }
    67        
     116
    68117        private void setHelpId() {
    69118                String helpId = "Action/"+getClass().getName().substring(getClass().getName().lastIndexOf('.')+1);
  • trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java

    r734 r1023  
    4040import org.openstreetmap.josm.tools.GBC;
    4141import org.openstreetmap.josm.tools.Pair;
     42import org.openstreetmap.josm.tools.ShortCut;
    4243
    4344
     
    4546 * Merge two or more nodes into one node.
    4647 * (based on Combine ways)
    47  * 
     48 *
    4849 * @author Matthew Newton
    4950 *
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/MoveAction.java

    r627 r1023  
    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 */
     
    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;
     
    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;
  • trunk/src/org/openstreetmap/josm/actions/NewAction.java

    r627 r1023  
    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
  • trunk/src/org/openstreetmap/josm/actions/OpenAction.java

    r737 r1023  
    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
  • trunk/src/org/openstreetmap/josm/actions/PasteAction.java

    r999 r1023  
    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
     
    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
     
    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) {
     
    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();
  • trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java

    r750 r1023  
    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 {
     
    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);
  • trunk/src/org/openstreetmap/josm/actions/PreferencesAction.java

    r1021 r1023  
    1515import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
    1616import org.openstreetmap.josm.tools.GBC;
     17import org.openstreetmap.josm.tools.ShortCut;
    1718
    1819/**
     
    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
  • trunk/src/org/openstreetmap/josm/actions/RedoAction.java

    r655 r1023  
    99
    1010import org.openstreetmap.josm.Main;
    11 
     11import org.openstreetmap.josm.tools.ShortCut;
    1212
    1313/**
    1414 * Redoes the last command.
    15  * 
     15 *
    1616 * @author imi
    1717 */
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java

    r1001 r1023  
    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
  • trunk/src/org/openstreetmap/josm/actions/SaveAction.java

    r693 r1023  
    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.
     
    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) {
  • trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java

    r872 r1023  
    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 {
     
    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);
     
    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)
     
    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         */
  • trunk/src/org/openstreetmap/josm/actions/SaveAsAction.java

    r693 r1023  
    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.
     
    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);
  • trunk/src/org/openstreetmap/josm/actions/SelectAllAction.java

    r753 r1023  
    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) {
  • trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java

    r926 r1023  
    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.
     
    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        }
     
    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.
     
    8587                        }
    8688                };
    87                
     89
    8890                for (OsmPrimitive p : selection)
    8991                        p.visit(splitVisitor);
     
    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()));
     
    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()));
     
    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;
     
    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);
  • trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java

    r1009 r1023  
    2626import org.openstreetmap.josm.data.osm.RelationMember;
    2727import org.openstreetmap.josm.data.osm.Way;
     28import org.openstreetmap.josm.tools.ShortCut;
    2829
    2930/**
     
    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        }
     
    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) {
     
    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        }
     
    133135                return firstway;
    134136        }
    135        
     137
    136138        /**
    137139         * see above
     
    143145
    144146                if (selectedWay == null) {
    145                        
     147
    146148                        boolean firstway = true;
    147149                        // modify all ways containing the nodes
     
    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                        }
  • trunk/src/org/openstreetmap/josm/actions/UndoAction.java

    r627 r1023  
    99
    1010import org.openstreetmap.josm.Main;
    11 
     11import org.openstreetmap.josm.tools.ShortCut;
    1212
    1313/**
    1414 * Undoes the last command.
    15  * 
     15 *
    1616 * @author imi
    1717 */
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/UnselectAllAction.java

    r768 r1023  
    1010
    1111import org.openstreetmap.josm.Main;
     12import org.openstreetmap.josm.tools.ShortCut;
    1213
    1314public class UnselectAllAction extends JosmAction {
     
    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
     
    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
  • trunk/src/org/openstreetmap/josm/actions/UploadAction.java

    r655 r1023  
    2424import org.openstreetmap.josm.tools.GBC;
    2525import org.xml.sax.SAXException;
     26import org.openstreetmap.josm.tools.ShortCut;
    2627
    2728/**
     
    3435 */
    3536public class UploadAction extends JosmAction {
    36        
     37
    3738        /** Upload Hook */
    3839        public interface UploadHook {
     
    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
     
    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                /**
     
    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."));
     
    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>();
  • trunk/src/org/openstreetmap/josm/actions/ZoomInAction.java

    r877 r1023  
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112public final class ZoomInAction extends JosmAction {
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/ZoomOutAction.java

    r877 r1023  
    88
    99import org.openstreetmap.josm.Main;
     10import org.openstreetmap.josm.tools.ShortCut;
    1011
    1112public final class ZoomOutAction extends JosmAction {
     
    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        }
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioBackAction.java

    r627 r1023  
    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"));
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioFastSlowAction.java

    r627 r1023  
    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);
     
    1932                        multiplier = 1.3;
    2033                }
    21                 if (! fast) 
     34                if (! fast)
    2235                        multiplier = 1.0 / multiplier;
    2336        }
     
    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 {
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioFasterAction.java

    r627 r1023  
    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}
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioFwdAction.java

    r627 r1023  
    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"));
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioNextAction.java

    r627 r1023  
    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
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioPlayPauseAction.java

    r627 r1023  
    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
     
    3537                        AudioPlayer.audioMalfunction(ex);
    3638                }
    37         }       
     39        }
    3840}
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioPrevAction.java

    r627 r1023  
    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
  • trunk/src/org/openstreetmap/josm/actions/audio/AudioSlowerAction.java

    r627 r1023  
    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}
  • trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java

    r988 r1023  
    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}.
     
    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 */
     
    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        }
     
    5859        }
    5960
    60        
     61
    6162        @Override public void actionPerformed(ActionEvent e) {
    6263                super.actionPerformed(e);
     
    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;
     
    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));
     
    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.");
  • trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java

    r999 r1023  
    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);
     
    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        }
     
    118120                }
    119121        }
    120        
     122
    121123        /**
    122124         * redraw to (possibly) get rid of helper line if selection changes.
     
    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) {
     
    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>();
     
    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
     
    182184                                return;
    183185                        }
    184                        
     186
    185187                } else {
    186188                        // no node found in clicked area
     
    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) {
     
    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;
     
    271273                                if (selectedNode == selectedWay.nodes.get(0) || selectedNode == selectedWay.nodes.get(selectedWay.nodes.size()-1)) {
    272274                                        n0 = selectedNode;
    273                                 }                       
    274                         }
    275                        
     275                                }
     276                        }
     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) {
     
    328330
    329331                Command c = new SequenceCommand(title, cmds);
    330        
     332
    331333                Main.main.undoRedo.add(c);
    332334                lastUsedNode = n;
     
    334336                Main.map.mapView.repaint();
    335337        }
    336        
     338
    337339        @Override public void mouseMoved(MouseEvent e) {
    338340                if(!Main.map.mapView.isDrawableLayer())
     
    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
     
    363365                        return;
    364366                }
    365                
     367
    366368                double distance = -1;
    367369                double angle = -1;
     
    381383                        currentMouseNode = Main.map.mapView.getNearestNode(mousePos);
    382384                }
    383                
     385
    384386                if (currentMouseNode != null) {
    385387                        // user clicked on node
     
    391393                        currentMouseEastNorth = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
    392394                }
    393                
     395
    394396                for (OsmPrimitive p : selection) {
    395397                        if (p instanceof Node) {
     
    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;
     
    419421                        if (selectedNode == selectedWay.nodes.get(0) || selectedNode == selectedWay.nodes.get(selectedWay.nodes.size()-1)) {
    420422                                currentBaseNode = selectedNode;
    421                         }                       
    422                 }
    423                
     423                        }
     424                }
     425
    424426                if (currentBaseNode == null || currentBaseNode == currentMouseNode) {
    425427                        return; // Don't create zero length way segments.
     
    443445                Main.map.mapView.repaint();
    444446        }
    445        
     447
    446448        /**
    447449         * Repaint on mouse exit so that the helper line goes away.
     
    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         */
     
    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:
     
    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();
     
    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.
     
    536538                                return;
    537539                        }
    538                
     540
    539541                default:
    540542                        EastNorth P = n.eastNorth;
     
    551553                }
    552554        }
    553        
     555
    554556        // helper for adjustNode
    555557        static double det(double a, double b, double c, double d)
     
    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);
     
    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) {
     
    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));       
    598 
    599         }
    600        
     599                g2.setStroke(new BasicStroke(1));
     600
     601        }
     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                        }
  • trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java

    r999 r1023  
    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.
     
    4749        double yoff;
    4850        double distance;
    49        
     51
    5052        /**
    5153         * The old cursor before the user pressed the mouse button.
     
    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         */
     
    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");
     
    100103                }
    101104        }
    102        
     105
    103106        @Override public void enterMode() {
    104107                super.enterMode();
     
    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;
     
    137140                        return;
    138141                }
    139                
     142
    140143                Main.map.mapView.repaint();
    141144                mousePos = e.getPoint();
     
    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);
     
    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));       
    191                 }
    192         }
    193        
     193                        g2.setStroke(new BasicStroke(1));
     194                }
     195        }
     196
    194197        /**
    195198         */
     
    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());
     
    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
  • trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java

    r627 r1023  
    1212import org.openstreetmap.josm.gui.MapFrame;
    1313import org.openstreetmap.josm.tools.ImageProvider;
     14import org.openstreetmap.josm.tools.ShortCut;
    1415
    1516/**
     
    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 {
     
    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);
     
    5970                Main.map.statusLine.repaint();
    6071        }
    61        
     72
    6273        public String getModeHelpText() {
    6374                return "";
  • trunk/src/org/openstreetmap/josm/actions/mapmode/PlayHeadDragMode.java

    r627 r1023  
    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 *
     
    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();
     
    7476                        playHeadMarker.synchronize(en);
    7577                }
    76                 mousePos = null;       
     78                mousePos = null;
    7779                dragging = false;
    7880
  • trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java

    r982 r1023  
    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).
     
    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 */
     
    6567        private Point mousePos;
    6668        private SelectionManager selectionManager;
    67        
     69
    6870        /**
    6971         * The time which needs to pass between click and release before something
     
    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
     
    114117                }
    115118        }
    116        
     119
    117120        @Override public void enterMode() {
    118121                super.enterMode();
     
    153156                        return;
    154157                }
    155                
     158
    156159                if (!initialMoveThresholdExceeded) {
    157160                        int dxp = mousePos.x - e.getX();
     
    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);
     
    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
     
    232235                virtualWay = null;
    233236                virtualNode = null;
    234                
     237
    235238                if (osm == null)
    236239                {
     
    257260                        }
    258261                }
    259                 if (osm == null) 
     262                if (osm == null)
    260263                        return Collections.emptySet();
    261264                return Collections.singleton(osm);
     
    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         */
     
    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;
     
    377380                Main.map.mapView.repaint();
    378381        }
    379        
     382
    380383        @Override public String getModeHelpText() {
    381384                if (mode == Mode.select) {
  • trunk/src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java

    r983 r1023  
    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 */
     
    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);
     
    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");
  • trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java

    r967 r1023  
    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 {
     
    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
     
    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     */
  • trunk/src/org/openstreetmap/josm/gui/MainApplet.java

    r627 r1023  
    2929import org.openstreetmap.josm.data.ServerSidePreferences;
    3030import org.openstreetmap.josm.tools.GBC;
     31import org.openstreetmap.josm.tools.ShortCut;
    3132
    3233public class MainApplet extends JApplet {
     
    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) {
     
    100102                Main.parent = this;
    101103                new MainCaller().postConstructorProcessCmdLine(args);
    102                
     104
    103105                MainMenu m = Main.main.menu; // shortcut
    104106
  • trunk/src/org/openstreetmap/josm/gui/MainApplication.java

    r999 r1023  
    3030 */
    3131public class MainApplication extends Main {
     32        /**
     33         * Allow subclassing (see JOSM.java)
     34         */
     35        public MainApplication() {}
     36
    3237        /**
    3338         * Construct an main frame, ready sized and operating. Does not
     
    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);
     
    138148                                tr("Plugins"), JOptionPane.ERROR_MESSAGE);
    139149                }
    140                
     150
    141151                // load the early plugins
    142152                splash.setStatus(tr("Loading early plugins"));
     
    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"+
     
    192203                });
    193204        }
     205
    194206}
  • trunk/src/org/openstreetmap/josm/gui/MainMenu.java

    r996 r1023  
    1313import javax.swing.JMenuItem;
    1414import javax.swing.KeyStroke;
     15import java.awt.event.KeyEvent;
    1516
    1617import org.openstreetmap.josm.Main;
     
    5960import org.openstreetmap.josm.actions.search.SearchAction;
    6061import org.openstreetmap.josm.data.DataSetChecker;
     62import org.openstreetmap.josm.tools.ShortCut;
    6163
    6264/**
     
    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();
     
    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();
     
    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();
     
    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"));
     
    129131        public final JMenu presetsMenu = new JMenu(tr("Presets"));
    130132        public final JMenu helpMenu = new JMenu(tr("Help"));
    131        
     133
     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        }
    132160
    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);
    157 
    158                 editMenu.setMnemonic('E');
    159                 current = editMenu.add(undo);
    160                 current.setAccelerator(undo.shortCut);
    161                 current = editMenu.add(redo);
    162                 current.setAccelerator(redo.shortCut);
    163                 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);
    174                 editMenu.addSeparator();
    175                 current = editMenu.add(selectAll);
    176                 current.setAccelerator(selectAll.shortCut);
    177                 current = editMenu.add(unselectAll);
    178                 current.setAccelerator(unselectAll.shortCut);
    179                 editMenu.addSeparator();
    180                 current = editMenu.add(search);
    181                 current.setAccelerator(search.shortCut);
    182                 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);
    198 
     171                add(fileMenu, download);
     172                add(fileMenu, upload);
     173                add(fileMenu, exit);
     174                add(fileMenu, KeyEvent.VK_F, "file");
     175
     176                add(editMenu, undo);
     177                add(editMenu, redo);
     178                editMenu.addSeparator();
     179                add(editMenu, copy);
     180                add(editMenu, delete);
     181                add(editMenu, paste);
     182                add(editMenu, pasteTags);
     183                add(editMenu, duplicate);
     184                editMenu.addSeparator();
     185                add(editMenu, selectAll);
     186                add(editMenu, unselectAll);
     187                editMenu.addSeparator();
     188                add(editMenu, search);
     189                editMenu.addSeparator();
     190                add(editMenu, preferences);
     191                add(editMenu, KeyEvent.VK_E, "edit");
     192
     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);
    216 
    217                 toolsMenu.setMnemonic('T');
    218                 current = toolsMenu.add(splitWay);
    219                 current.setAccelerator(splitWay.shortCut);
    220                 current = toolsMenu.add(combineWay);
    221                 current.setAccelerator(combineWay.shortCut);
    222                 toolsMenu.addSeparator();
    223                 current = toolsMenu.add(reverseWay);
    224                 current.setAccelerator(reverseWay.shortCut);
    225                 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);
    232                 toolsMenu.addSeparator();
    233                 current = toolsMenu.add(createCircle);
    234                 current.setAccelerator(createCircle.shortCut);
    235                 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);
     211                        }
     212                });
     213                viewMenu.add(wireframe);
     214                add(viewMenu, KeyEvent.VK_V, "view");
     215
     216                add(toolsMenu, splitWay);
     217                add(toolsMenu, combineWay);
     218                toolsMenu.addSeparator();
     219                add(toolsMenu, reverseWay);
     220                toolsMenu.addSeparator();
     221                add(toolsMenu, alignInCircle);
     222                add(toolsMenu, alignInLine);
     223                add(toolsMenu, alignInRect);
     224                toolsMenu.addSeparator();
     225                add(toolsMenu, createCircle);
     226                toolsMenu.addSeparator();
     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}
  • trunk/src/org/openstreetmap/josm/gui/MapMover.java

    r627 r1023  
    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;
     
    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        }
     
    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);
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r1022 r1023  
    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;
     
    8485         */
    8586        private Layer activeLayer;
    86        
     87
    8788        /**
    8889         * The last event performed by mouse.
     
    9192
    9293        private LinkedList<MapViewPaintable> temporaryLayers = new LinkedList<MapViewPaintable>();
    93        
     94
    9495        private BufferedImage offscreenBuffer;
    95        
     96
    9697        /**
    9798         * The listener of the active layer changes.
     
    109110
    110111                                new MapMover(MapView.this, Main.contentPane);
    111                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, java.awt.event.InputEvent.SHIFT_MASK), "UP");
    112                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, java.awt.event.InputEvent.SHIFT_MASK), "DOWN");
    113                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, java.awt.event.InputEvent.SHIFT_MASK), "LEFT");
    114                                 Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, java.awt.event.InputEvent.SHIFT_MASK), "RIGHT");
    115 
    116                                 Main.contentPane.getActionMap().put("UP", new MoveAction(MoveAction.Direction.UP));
    117                                 Main.contentPane.getActionMap().put("DOWN", new MoveAction(MoveAction.Direction.DOWN));
    118                                 Main.contentPane.getActionMap().put("LEFT", new MoveAction(MoveAction.Direction.LEFT));
    119                                 Main.contentPane.getActionMap().put("RIGHT", new MoveAction(MoveAction.Direction.RIGHT));
    120                                
     112                                JosmAction mv;
     113                                mv = new MoveAction(MoveAction.Direction.UP);
     114                                if (mv.getShortCut() != null) {
     115                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "UP");
     116                                        Main.contentPane.getActionMap().put("UP", mv);
     117                                }
     118                                mv = new MoveAction(MoveAction.Direction.DOWN);
     119                                if (mv.getShortCut() != null) {
     120                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "DOWN");
     121                                        Main.contentPane.getActionMap().put("DOWN", mv);
     122                                }
     123                                mv = new MoveAction(MoveAction.Direction.LEFT);
     124                                if (mv.getShortCut() != null) {
     125                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "LEFT");
     126                                        Main.contentPane.getActionMap().put("LEFT", mv);
     127                                }
     128                                mv = new MoveAction(MoveAction.Direction.RIGHT);
     129                                if (mv.getShortCut() != null) {
     130                                        Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(mv.getShortCut().getKeyStroke(), "RIGHT");
     131                                        Main.contentPane.getActionMap().put("RIGHT", mv);
     132                                }
    121133
    122134                                MapSlider zoomSlider = new MapSlider(MapView.this);
     
    278290                        mvp.paint(tempG, this);
    279291                }
    280                
     292
    281293                // draw world borders
    282294                tempG.setColor(Color.WHITE);
     
    290302                if (x1 > 0 || y1 > 0 || x2 < getWidth() || y2 < getHeight())
    291303                        tempG.drawRect(x1, y1, x2-x1+1, y2-y1+1);
    292                
     304
    293305                if (playHeadMarker != null)
    294306                        playHeadMarker.paint(tempG, this);
     
    435447                return false;
    436448        }
    437        
     449
    438450        public boolean addTemporaryLayer(MapViewPaintable mvp) {
    439451                if (temporaryLayers.contains(mvp)) return false;
    440452                return temporaryLayers.add(mvp);
    441453        }
    442        
     454
    443455        public boolean removeTemporaryLayer(MapViewPaintable mvp) {
    444456                return temporaryLayers.remove(mvp);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java

    r627 r1023  
    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 {
     
    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);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java

    r999 r1023  
    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 {
     
    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);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java

    r758 r1023  
    3838import org.openstreetmap.josm.tools.GBC;
    3939import org.openstreetmap.josm.tools.ImageProvider;
     40import org.openstreetmap.josm.tools.ShortCut;
    4041
    4142/**
     
    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);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

    r867 r1023  
    4040import org.openstreetmap.josm.tools.ImageProvider;
    4141import org.openstreetmap.josm.tools.ImageProvider.OverlayPosition;
     42import org.openstreetmap.josm.tools.ShortCut;
    4243
    4344/**
     
    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);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java

    r810 r1023  
    6464import org.openstreetmap.josm.tools.AutoCompleteComboBox;
    6565import org.openstreetmap.josm.tools.GBC;
     66import org.openstreetmap.josm.tools.ShortCut;
    6667
    6768/**
     
    8889         */
    8990        private NameVisitor nameVisitor = new NameVisitor();
    90        
     91
    9192        /**
    9293         * Watches for double clicks and from editing or new property, depending on the
     
    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);
     
    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)) {
     
    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);
     
    296297                keys.setPossibleItems(allData.keySet());
    297298                keys.setEditable(true);
    298                
     299
    299300                p.add(keys, BorderLayout.CENTER);
    300301
     
    403404                }
    404405        };
    405        
     406
    406407        /**
    407408         * The properties list.
     
    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>();
     
    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) {
     
    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) {
     
    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) {
     
    498500                                if (c instanceof JLabel) {
    499501                                        Collection<RelationMember> col = (Collection<RelationMember>) value;
    500                                        
     502
    501503                                        String text = null;
    502504                                        for (RelationMember r : col) {
     
    509511                                                }
    510512                                        }
    511                                        
     513
    512514                                        ((JLabel)c).setText(text);
    513515                                }
     
    515517                        }
    516518                });
    517                
     519
    518520                // combine both tables and wrap them in a scrollPane
    519521                JPanel bothTables = new JPanel();
     
    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);
     
    565567                                                        selectionChanged(sel); // update whole table
    566568                                                }
    567                                                
     569
    568570                                        }
    569571                                }
     
    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));
     
    611613
    612614                // re-load property data
    613                
     615
    614616                propertyData.setRowCount(0);
    615617
     
    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) {
     
    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        }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java

    r999 r1023  
    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.
     
    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);
     
    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) {
     
    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) {
     
    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) {
     
    111113                if (b) updateList();
    112114        }
    113        
     115
    114116        public void updateList() {
    115117                list.setSize(Main.ds.relations.size());
     
    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) {
     
    130132                }
    131133        }
    132        
     134
    133135        public void layerRemoved(Layer a) {
    134136                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         */
     
    157159        /**
    158160         * Adds a selection listener to the relation list.
    159          * 
     161         *
    160162         * @param listener the listener to add
    161163         */
     
    166168        /**
    167169         * Removes a selection listener from the relation list.
    168          * 
     170         *
    169171         * @param listener the listener to remove
    170172         */
  • trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java

    r967 r1023  
    4141import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    4242import org.openstreetmap.josm.gui.SideButton;
     43import org.openstreetmap.josm.tools.ShortCut;
    4344
    4445/**
     
    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>>();
     
    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() {
     
    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))
     
    273275    /**
    274276     * A specialized {@link JMenuItem} for presenting one entry of the selection history
    275      *   
     277     *
    276278     * @author Jan Peter Stotz
    277279     */
     
    303305    /**
    304306     * A specialized {@link JMenuItem} for presenting one entry of the search history
    305      *   
     307     *
    306308     * @author Jan Peter Stotz
    307309     */
  • trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java

    r627 r1023  
    2727import org.openstreetmap.josm.tools.GBC;
    2828import org.openstreetmap.josm.tools.ImageProvider;
     29import org.openstreetmap.josm.tools.ShortCut;
    2930
    3031/**
     
    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                }
     
    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));
  • trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java

    r627 r1023  
    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 */
     
    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        }
     
    7072                if (!isVisible())
    7173                        return;
    72                
     74
    7375                class UserCount {
    7476                        User user;
     
    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;
     
    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++;
     
    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 });
  • trunk/src/org/openstreetmap/josm/gui/preferences/LafPreference.java

    r627 r1023  
    55
    66import java.awt.Component;
     7import java.lang.reflect.*;
    78
    89import javax.swing.DefaultListCellRenderer;
     
    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) {
  • trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java

    r938 r1023  
    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
     
    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();
  • trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java

    r627 r1023  
    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 */
     
    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();
     
    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}
  • trunk/src/org/openstreetmap/josm/tools/ShortCutLabel.java

    r627 r1023  
    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)
Note: See TracChangeset for help on using the changeset viewer.