Changeset 7539 in josm for trunk


Ignore:
Timestamp:
2014-09-15T19:42:31+02:00 (10 years ago)
Author:
Don-vip
Message:

fix #5957, fix #10458, see #10455: fix various focus/shortcuts issues:

  • proper use of "Command" modifier on OS X instead of "Ctrl"
  • fix related focus issue on OS X in layer list dialog (copy/paste between layers not working)
  • fix non-working commands after a layer selection: Ctrl-A, Tab, Ctrl-Down/Up/Left/Right, F8
  • fix impossibility to use 'A', 'S' or 'X' keys in relation filter or when renaming layer
Location:
trunk/src/org/openstreetmap/josm
Files:
9 edited

Legend:

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

    r7005 r7539  
    2424
    2525import javax.swing.AbstractAction;
    26 import javax.swing.Action;
    2726import javax.swing.DefaultCellEditor;
    2827import javax.swing.DefaultListSelectionModel;
     
    6261import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    6362import org.openstreetmap.josm.gui.util.GuiHelper;
     63import org.openstreetmap.josm.gui.widgets.DisableShortcutsOnFocusGainedTextField;
    6464import org.openstreetmap.josm.gui.widgets.JosmTextField;
    6565import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
     
    7676 * change the ordering of the layers, to hide/show layers, to activate layers,
    7777 * and to delete layers.
    78  *
     78 * @since 17
    7979 */
    8080public class LayerListDialog extends ToggleDialog {
     
    127127        public void actionPerformed(ActionEvent e) {
    128128            final Layer l = model.getLayer(model.getRowCount() - layerIndex - 1);
    129             if(l != null) {
     129            if (l != null) {
    130130                l.toggleVisible();
    131131            }
     
    135135    private final Shortcut[] visibilityToggleShortcuts = new Shortcut[10];
    136136    private final ToggleLayerIndexVisibility[] visibilityToggleActions = new ToggleLayerIndexVisibility[10];
     137
    137138    /**
    138139     * registers (shortcut to toggle right hand side toggle dialogs)+(number keys) shortcuts
     
    153154
    154155    /**
    155      * Create an layer list and attach it to the given mapView.
     156     * Creates a layer list and attach it to the given mapView.
    156157     */
    157158    protected LayerListDialog(MapFrame mapFrame) {
     
    189190        layerList.getColumnModel().getColumn(1).setResizable(false);
    190191        layerList.getColumnModel().getColumn(2).setCellRenderer(new LayerNameCellRenderer());
    191         layerList.getColumnModel().getColumn(2).setCellEditor(new LayerNameCellEditor(new JosmTextField()));
     192        layerList.getColumnModel().getColumn(2).setCellEditor(new LayerNameCellEditor(new DisableShortcutsOnFocusGainedTextField()));
     193        // Disable some default JTable shortcuts to use JOSM ones (see #5678, #10458)
    192194        for (KeyStroke ks : new KeyStroke[] {
    193                 KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK),
    194                 KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK),
    195                 KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.SHIFT_MASK),
    196                 KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_MASK),
    197                 KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.SHIFT_MASK),
    198                 KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.SHIFT_MASK),
     195                KeyStroke.getKeyStroke(KeyEvent.VK_A, GuiHelper.getMenuShortcutKeyMaskEx()),
     196                KeyStroke.getKeyStroke(KeyEvent.VK_C, GuiHelper.getMenuShortcutKeyMaskEx()),
     197                KeyStroke.getKeyStroke(KeyEvent.VK_V, GuiHelper.getMenuShortcutKeyMaskEx()),
     198                KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.SHIFT_DOWN_MASK),
     199                KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_DOWN_MASK),
     200                KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.SHIFT_DOWN_MASK),
     201                KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.SHIFT_DOWN_MASK),
     202                KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_DOWN_MASK),
     203                KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_DOWN_MASK),
     204                KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.CTRL_DOWN_MASK),
     205                KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.CTRL_DOWN_MASK),
    199206                KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0),
    200207                KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0),
     208                KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0),
     209                KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0),
    201210        })
    202211        {
     
    246255        adaptTo(showHideLayerAction, selectionModel);
    247256
    248         //-- layer opacity action
     257        // -- layer opacity action
    249258        LayerOpacityAction layerOpacityAction = new LayerOpacityAction();
    250259        adaptTo(layerOpacityAction, selectionModel);
     
    261270        adaptTo(duplicateLayerAction, selectionModel);
    262271
    263         //-- delete layer action
     272        // -- delete layer action
    264273        DeleteLayerAction deleteLayerAction = new DeleteLayerAction();
    265274        layerList.getActionMap().put("deleteLayer", deleteLayerAction);
     
    309318    }
    310319
     320    /**
     321     * Returns the layer list model.
     322     * @return the layer list model
     323     */
    311324    public LayerListModel getModel() {
    312325        return model;
     
    372385     */
    373386    public final class DeleteLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction {
     387
    374388        /**
    375389         * Creates a {@link DeleteLayerAction} which will delete the currently
    376390         * selected layers in the layer dialog.
    377          *
    378391         */
    379392        public DeleteLayerAction() {
     
    423436    }
    424437
     438    /**
     439     * Action which will toggle the visibility of the currently selected layers.
     440     */
    425441    public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction, MultikeyShortcutAction {
    426442
     
    431447         * Creates a {@link ShowHideLayerAction} which will toggle the visibility of
    432448         * the currently selected layers
    433          *
    434          */
    435         public ShowHideLayerAction(boolean init) {
     449         */
     450        public ShowHideLayerAction() {
    436451            putValue(NAME, tr("Show/hide"));
    437452            putValue(SMALL_ICON, ImageProvider.get("dialogs", "showhide"));
     
    441456                    tr("Show/hide layer")), KeyEvent.VK_S, Shortcut.SHIFT);
    442457            multikeyShortcut.setAccelerator(this);
    443             if (init) {
    444                 updateEnabledState();
    445             }
    446         }
    447 
    448         /**
    449          * Constructs a new {@code ShowHideLayerAction}.
    450          */
    451         public ShowHideLayerAction() {
    452             this(true);
     458            updateEnabledState();
    453459        }
    454460
     
    517523    }
    518524
     525    /**
     526     * Action which allows to change the opacity of one or more layers.
     527     */
    519528    public final class LayerOpacityAction extends AbstractAction implements IEnabledStateUpdating, LayerAction {
    520529        private Layer layer;
     
    523532
    524533        /**
    525          * Creates a {@link LayerOpacityAction} which allows to chenge the
     534         * Creates a {@link LayerOpacityAction} which allows to change the
    526535         * opacity of one or more layers.
    527536         *
     
    632641        private Shortcut multikeyShortcut;
    633642
     643        /**
     644         * Constructs a new {@code ActivateLayerAction}.
     645         * @param layer the layer
     646         */
    634647        public ActivateLayerAction(Layer layer) {
    635648            this();
     
    670683
    671684        private void execute(Layer layer) {
    672             // model is  going to be updated via LayerChangeListener
    673             // and PropertyChangeEvents
     685            // model is  going to be updated via LayerChangeListener and PropertyChangeEvents
    674686            Main.map.mapView.setActiveLayer(layer);
    675687            layer.setVisible(true);
     
    704716            updateEnabledState();
    705717        }
     718
    706719        @Override
    707720        public void layerAdded(Layer newLayer) {
    708721            updateEnabledState();
    709722        }
     723
    710724        @Override
    711725        public void layerRemoved(Layer oldLayer) {
     
    738752        private  Layer layer;
    739753
     754        /**
     755         * Constructs a new {@code MergeAction}.
     756         * @param layer the layer
     757         * @throws IllegalArgumentException if {@code layer} is null
     758         */
    740759        public MergeAction(Layer layer) throws IllegalArgumentException {
    741760            this();
     
    806825     */
    807826    public final class DuplicateAction extends AbstractAction implements IEnabledStateUpdating {
    808         private  Layer layer;
    809 
     827        private Layer layer;
     828
     829        /**
     830         * Constructs a new {@code DuplicateAction}.
     831         * @param layer the layer
     832         * @throws IllegalArgumentException if {@code layer} is null
     833         */
    810834        public DuplicateAction(Layer layer) throws IllegalArgumentException {
    811835            this();
     
    891915
    892916    private static class LayerVisibleCheckBox extends JCheckBox {
    893         private final ImageIcon icon_eye;
    894         private final ImageIcon icon_eye_translucent;
     917        private final ImageIcon iconEye;
     918        private final ImageIcon iconEyeTranslucent;
    895919        private boolean isTranslucent;
    896920        public LayerVisibleCheckBox() {
    897921            setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
    898             icon_eye = ImageProvider.get("dialogs/layerlist", "eye");
    899             icon_eye_translucent = ImageProvider.get("dialogs/layerlist", "eye-translucent");
     922            iconEye = ImageProvider.get("dialogs/layerlist", "eye");
     923            iconEyeTranslucent = ImageProvider.get("dialogs/layerlist", "eye-translucent");
    900924            setIcon(ImageProvider.get("dialogs/layerlist", "eye-off"));
    901925            setPressedIcon(ImageProvider.get("dialogs/layerlist", "eye-pressed"));
    902             setSelectedIcon(icon_eye);
     926            setSelectedIcon(iconEye);
    903927            isTranslucent = false;
    904928        }
     
    907931            if (this.isTranslucent == isTranslucent) return;
    908932            if (isTranslucent) {
    909                 setSelectedIcon(icon_eye_translucent);
     933                setSelectedIcon(iconEyeTranslucent);
    910934            } else {
    911                 setSelectedIcon(icon_eye);
     935                setSelectedIcon(iconEye);
    912936            }
    913937            this.isTranslucent = isTranslucent;
     
    923947
    924948    private static class ActiveLayerCellRenderer implements TableCellRenderer {
    925         JCheckBox cb;
     949        final JCheckBox cb;
    926950        public ActiveLayerCellRenderer() {
    927951            cb = new ActiveLayerCheckBox();
     
    938962
    939963    private static class LayerVisibleCellRenderer implements TableCellRenderer {
    940         LayerVisibleCheckBox cb;
     964        final LayerVisibleCheckBox cb;
    941965        public LayerVisibleCellRenderer() {
    942966            this.cb = new LayerVisibleCheckBox();
     
    953977
    954978    private static class LayerVisibleCellEditor extends DefaultCellEditor {
    955         LayerVisibleCheckBox cb;
     979        final LayerVisibleCheckBox cb;
    956980        public LayerVisibleCellEditor(LayerVisibleCheckBox cb) {
    957981            super(cb);
     
    10141038
    10151039    private static class LayerNameCellEditor extends DefaultCellEditor {
    1016         public LayerNameCellEditor(JosmTextField tf) {
     1040        public LayerNameCellEditor(DisableShortcutsOnFocusGainedTextField tf) {
    10171041            super(tf);
    10181042        }
     
    10271051
    10281052    class PopupMenuHandler extends PopupMenuLauncher {
    1029         @Override public void showMenu(MouseEvent evt) {
     1053        @Override
     1054        public void showMenu(MouseEvent evt) {
    10301055            Layer layer = getModel().getLayer(layerList.getSelectedRow());
    10311056            menu = new LayerListPopup(getModel().getSelectedLayers(), layer);
     
    10791104
    10801105    /**
    1081      * Observer interface to be implemented by views using {@link LayerListModel}
    1082      *
     1106     * Observer interface to be implemented by views using {@link LayerListModel}.
    10831107     */
    10841108    public interface LayerListModelListener {
     1109
     1110        /**
     1111         * Fired when a layer is made visible.
     1112         * @param index the layer index
     1113         * @param layer the layer
     1114         */
    10851115        public void makeVisible(int index, Layer layer);
     1116
     1117
     1118        /**
     1119         * Fired when something has changed in the layer list model.
     1120         */
    10861121        public void refresh();
    10871122    }
     
    11611196
    11621197        /**
    1163          * Populates the model with the current layers managed by
    1164          * {@link MapView}.
    1165          *
     1198         * Populates the model with the current layers managed by {@link MapView}.
    11661199         */
    11671200        public void populate() {
    11681201            for (Layer layer: getLayers()) {
    11691202                // make sure the model is registered exactly once
    1170                 //
    11711203                layer.removePropertyChangeListener(this);
    11721204                layer.addPropertyChangeListener(this);
     
    11761208
    11771209        /**
    1178          * Marks <code>layer</code> as selected layer. Ignored, if
    1179          * layer is null.
     1210         * Marks <code>layer</code> as selected layer. Ignored, if layer is null.
    11801211         *
    11811212         * @param layer the layer.
     
    11921223
    11931224        /**
    1194          * Replies the list of currently selected layers. Never null, but may
    1195          * be empty.
    1196          *
    1197          * @return the list of currently selected layers. Never null, but may
    1198          * be empty.
     1225         * Replies the list of currently selected layers. Never null, but may be empty.
     1226         *
     1227         * @return the list of currently selected layers. Never null, but may be empty.
    11991228         */
    12001229        public List<Layer> getSelectedLayers() {
     
    14121441            final Layer activeLayer = getActiveLayer();
    14131442            if (activeLayer != null) {
    1414                 // there's an active layer - select it and make it
    1415                 // visible
     1443                // there's an active layer - select it and make it visible
    14161444                int idx = getLayers().indexOf(activeLayer);
    14171445                selectionModel.setSelectionInterval(idx, idx);
    14181446                ensureSelectedIsVisible();
    14191447            } else {
    1420                 // no active layer - select the first one and make
    1421                 // it visible
     1448                // no active layer - select the first one and make it visible
    14221449                selectionModel.setSelectionInterval(0, 0);
    14231450                ensureSelectedIsVisible();
     
    15571584
    15581585    /**
    1559      * Creates a {@link ShowHideLayerAction} for <code>layer</code> in the
     1586     * Creates a {@link ShowHideLayerAction} in the
    15601587     * context of this {@link LayerListDialog}.
    15611588     *
     
    15631590     */
    15641591    public ShowHideLayerAction createShowHideLayerAction() {
    1565         ShowHideLayerAction act = new ShowHideLayerAction(true);
    1566         act.putValue(Action.NAME, tr("Show/Hide"));
    1567         return act;
    1568     }
    1569 
    1570     /**
    1571      * Creates a {@link DeleteLayerAction} for <code>layer</code> in the
     1592        return new ShowHideLayerAction();
     1593    }
     1594
     1595    /**
     1596     * Creates a {@link DeleteLayerAction} in the
    15721597     * context of this {@link LayerListDialog}.
    15731598     *
     
    15751600     */
    15761601    public DeleteLayerAction createDeleteLayerAction() {
    1577         // the delete layer action doesn't depend on the current layer
    15781602        return new DeleteLayerAction();
    15791603    }
     
    16011625    }
    16021626
     1627    /**
     1628     * Returns the layer at given index, or {@code null}.
     1629     * @param index the index
     1630     * @return the layer at given index, or {@code null} if index out of range
     1631     */
    16031632    public static Layer getLayerForIndex(int index) {
    16041633
     
    16141643    }
    16151644
    1616     // This is not Class<? extends Layer> on purpose, to allow asking for layers implementing some interface
     1645    /**
     1646     * Returns a list of info on all layers of a given class.
     1647     * @param layerClass The layer class. This is not {@code Class<? extends Layer>} on purpose,
     1648     *                   to allow asking for layers implementing some interface
     1649     * @return list of info on all layers assignable from {@code layerClass}
     1650     */
    16171651    public static List<MultikeyInfo> getLayerInfoByClass(Class<?> layerClass) {
    16181652
     
    16351669    }
    16361670
     1671    /**
     1672     * Determines if a layer is valid (contained in layer list).
     1673     * @param l the layer
     1674     * @return {@code true} if layer {@code l} is contained in current layer list
     1675     */
    16371676    public static boolean isLayerValid(Layer l) {
    1638         if (l == null)
     1677
     1678        if (l == null || !Main.isDisplayingMapView())
    16391679            return false;
    16401680
    1641         if (!Main.isDisplayingMapView())
    1642             return false;
    1643 
    16441681        return Main.map.mapView.getAllLayersAsList().contains(l);
    16451682    }
    16461683
     1684    /**
     1685     * Returns info about layer.
     1686     * @param l the layer
     1687     * @return info about layer {@code l}
     1688     */
    16471689    public static MultikeyInfo getLayerInfo(Layer l) {
    16481690
    1649         if (l == null)
    1650             return null;
    1651 
    1652         if (!Main.isDisplayingMapView())
     1691        if (l == null || !Main.isDisplayingMapView())
    16531692            return null;
    16541693
  • trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java

    r7029 r7539  
    117117    HighlightHelper highlightHelper = new HighlightHelper();
    118118    private boolean highlightEnabled = Main.pref.getBoolean("draw.target-highlight", true);
     119
    119120    /**
    120121     * Constructs <code>RelationListDialog</code>
     
    197198    }
    198199
    199     @Override public void showNotify() {
     200    @Override
     201    public void showNotify() {
    200202        MapView.addLayerChangeListener(newAction);
    201203        newAction.updateEnabledState();
     
    205207    }
    206208
    207     @Override public void hideNotify() {
     209    @Override
     210    public void hideNotify() {
    208211        MapView.removeLayerChangeListener(newAction);
    209212        DatasetEventManager.getInstance().removeDatasetListener(this);
     
    323326        }
    324327
    325         @Override public void mouseClicked(MouseEvent e) {
     328        @Override
     329        public void mouseClicked(MouseEvent e) {
    326330            if (!Main.main.hasEditLayer()) return;
    327331            if (isDoubleClick(e)) {
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java

    r7158 r7539  
    8080
    8181/**
    82  * Class that helps PropertiesDialog add and edit tag values
     82 * Class that helps PropertiesDialog add and edit tag values.
     83 * @since 5633
    8384 */
    8485class TagEditHelper {
     
    139140
    140141    /**
    141     * Edit the value in the tags table row
     142    * Edit the value in the tags table row.
    142143    * @param row The row of the table from which the value is edited.
    143144    * @param focusOnKey Determines if the initial focus should be set on key instead of value
     
    187188
    188189    /**
    189      * Load recently used tags from preferences if needed
     190     * Load recently used tags from preferences if needed.
    190191     */
    191192    public void loadTagsIfNeeded() {
     
    204205
    205206    /**
    206      * Store recently used tags in preferences if needed
     207     * Store recently used tags in preferences if needed.
    207208     */
    208209    public void saveTagsIfNeeded() {
     
    258259        ListCellRenderer<AutoCompletionListItem> cellRenderer = new ListCellRenderer<AutoCompletionListItem>() {
    259260            final DefaultListCellRenderer def = new DefaultListCellRenderer();
    260                 @Override
    261                 public Component getListCellRendererComponent(JList<? extends AutoCompletionListItem> list,
    262                         AutoCompletionListItem value, int index, boolean isSelected,  boolean cellHasFocus){
    263                     Component c = def.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    264                     if (c instanceof JLabel) {
    265                         String str = value.getValue();
    266                         if (valueCount.containsKey(objKey)) {
    267                             Map<String, Integer> m = valueCount.get(objKey);
    268                             if (m.containsKey(str)) {
    269                                 str = tr("{0} ({1})", str, m.get(str));
    270                                 c.setFont(c.getFont().deriveFont(Font.ITALIC + Font.BOLD));
    271                             }
     261            @Override
     262            public Component getListCellRendererComponent(JList<? extends AutoCompletionListItem> list,
     263                    AutoCompletionListItem value, int index, boolean isSelected,  boolean cellHasFocus){
     264                Component c = def.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     265                if (c instanceof JLabel) {
     266                    String str = value.getValue();
     267                    if (valueCount.containsKey(objKey)) {
     268                        Map<String, Integer> m = valueCount.get(objKey);
     269                        if (m.containsKey(str)) {
     270                            str = tr("{0} ({1})", str, m.get(str));
     271                            c.setFont(c.getFont().deriveFont(Font.ITALIC + Font.BOLD));
    272272                        }
    273                         ((JLabel) c).setText(str);
    274                     }
    275                     return c;
    276                 }
    277             };
     273                    }
     274                    ((JLabel) c).setText(str);
     275                }
     276                return c;
     277            }
     278        };
    278279
    279280        private EditTagDialog(String key, int row, Map<String, Integer> map, final boolean initialFocusOnKey) {
     
    463464
    464465        private void selectACComboBoxSavingUnixBuffer(AutoCompletingComboBox cb) {
    465             // select compbobox with saving unix system selection (middle mouse paste)
     466            // select combobox with saving unix system selection (middle mouse paste)
    466467            Clipboard sysSel = Toolkit.getDefaultToolkit().getSystemSelection();
    467468            if(sysSel != null) {
     
    493494        protected FocusAdapter addFocusAdapter(final AutoCompletionManager autocomplete, final Comparator<AutoCompletionListItem> comparator) {
    494495           // get the combo box' editor component
    495            JTextComponent editor = (JTextComponent)values.getEditor()
    496                    .getEditorComponent();
     496           JTextComponent editor = (JTextComponent)values.getEditor().getEditorComponent();
    497497           // Refresh the values model when focus is gained
    498498           FocusAdapter focus = new FocusAdapter() {
    499                @Override public void focusGained(FocusEvent e) {
     499               @Override
     500               public void focusGained(FocusEvent e) {
    500501                   String key = keys.getEditor().getItem().toString();
    501502
     
    665666                    public void actionPerformed(ActionEvent e) {
    666667                        keys.setSelectedItem(t.getKey());
    667                         // Update list of values (fix #7951)
    668                         // fix #8298 - update list of values before setting value (?)
     668                        // fix #7951, #8298 - update list of values before setting value (?)
    669669                        focus.focusGained(null);
    670670                        values.setSelectedItem(t.getValue());
  • trunk/src/org/openstreetmap/josm/gui/util/AdvancedKeyPressDetector.java

    r7533 r7539  
    3838    private final ArrayList<ModifierListener> modifierListeners = new ArrayList<>();
    3939    private int previousModifiers;
     40
     41    private boolean enabled = true;
    4042
    4143    /**
     
    8486            public void actionPerformed(ActionEvent e) {
    8587                timer.stop();
    86                 if (set.remove(releaseEvent.getKeyCode())) {
     88                if (set.remove(releaseEvent.getKeyCode()) && enabled) {
    8789                    synchronized (AdvancedKeyPressDetector.this) {
    8890                        for (KeyPressReleaseListener q: keyListeners) {
     
    121123            if (timer.isRunning()) {
    122124                timer.stop();
    123             } else if (set.add((e.getKeyCode()))) {
     125            } else if (set.add((e.getKeyCode())) && enabled) {
    124126                synchronized (this) {
    125127                    for (KeyPressReleaseListener q: keyListeners) {
     
    131133            if (timer.isRunning()) {
    132134                timer.stop();
    133                 if (set.remove(e.getKeyCode())) {
     135                if (set.remove(e.getKeyCode()) && enabled) {
    134136                    synchronized (this) {
    135137                        for (KeyPressReleaseListener q: keyListeners) {
     
    178180        return set.contains(keyCode);
    179181    }
     182
     183    /**
     184     * Sets the enabled state of the key detector. We need to disable it when text fields that disable
     185     * shortcuts gain focus.
     186     * @param enabled if {@code true}, enables this key detector. If {@code false}, disables it
     187     * @since 7539
     188     */
     189    public final void setEnabled(boolean enabled) {
     190        this.enabled = enabled;
     191    }
    180192}
  • trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java

    r7312 r7539  
    1919import java.awt.event.HierarchyEvent;
    2020import java.awt.event.HierarchyListener;
     21import java.awt.event.KeyEvent;
    2122import java.awt.image.FilteredImageSource;
    2223import java.lang.reflect.InvocationTargetException;
     
    330331        return new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    331332    }
     333
     334    /**
     335     * Returns extended modifier key used as the appropriate accelerator key for menu shortcuts.
     336     * It is advised everywhere to use {@link Toolkit#getMenuShortcutKeyMask()} to get the cross-platform modifier, but:
     337     * <ul>
     338     * <li>it returns KeyEvent.CTRL_MASK instead of KeyEvent.CTRL_DOWN_MASK. We used the extended
     339     *    modifier for years, and Oracle recommends to use it instead, so it's best to keep it</li>
     340     * <li>the method throws a HeadlessException ! So we would need to handle it for unit tests anyway</li>
     341     * </ul>
     342     * @return extended modifier key used as the appropriate accelerator key for menu shortcuts
     343     * @since 7539
     344     */
     345    public static int getMenuShortcutKeyMaskEx() {
     346        return Main.isPlatformOsx() ? KeyEvent.META_DOWN_MASK : KeyEvent.CTRL_DOWN_MASK;
     347    }
    332348}
  • trunk/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java

    r7005 r7539  
    113113        disableMenuActions();
    114114        unregisterActionShortcuts();
     115        Main.map.keyDetector.setEnabled(false);
    115116    }
    116117
    117118    @Override
    118119    public void focusLost(FocusEvent e) {
     120        Main.map.keyDetector.setEnabled(true);
    119121        restoreActionShortcuts();
    120122        restoreMenuActions();
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/AddTagsDialog.java

    r7521 r7539  
    1818import java.util.Map;
    1919import java.util.Set;
     20
    2021import javax.swing.AbstractAction;
    2122import javax.swing.JCheckBox;
    22 
    2323import javax.swing.JPanel;
    2424import javax.swing.JTable;
     
    6969            this.num = num;
    7070        }
     71        @Override
    7172        public String toString() {
    7273            return tr("<delete from {0} objects>", num);
     
    329330
    330331    /**
    331      * Ask user and add the tags he confirm
     332     * Ask user and add the tags he confirm.
    332333     * @param keyValue is a table or {{tag1,val1},{tag2,val2},...}
    333334     * @param sender is a string for skipping confirmations. Use epmty string for always confirmed adding.
     335     * @param primitives OSM objects that will be modified
     336     * @since 7521
    334337     */
    335338    public static void addTags(String[][] keyValue, String sender, Collection<? extends OsmPrimitive> primitives) {
  • trunk/src/org/openstreetmap/josm/tools/InputMapUtils.java

    r7509 r7539  
    1313
    1414/**
    15  * Tools to work with Swing InputMap
    16  *
     15 * Tools to work with Swing InputMap.
     16 * @since 5200
    1717 */
    1818public final class InputMapUtils {
     
    6262
    6363    /**
    64      * Enable activating button on Enter (which is replaced with spacebar for certain Look-And-Feels)
     64     * Enable activating button on Enter (which is replaced with spacebar for certain Look-And-Feels).
     65     * @param b Button
    6566     */
    6667    public static void enableEnter(JButton b) {
    6768         b.setFocusable(true);
    6869         b.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
    69          b.getActionMap().put("enter",b.getAction());
     70         b.getActionMap().put("enter", b.getAction());
    7071    }
    7172
     73    /**
     74     * Add an action activated with Enter key on a component.
     75     * @param c The Swing component
     76     * @param a action activated with Enter key
     77     */
    7278    public static void addEnterAction(JComponent c, Action a) {
    7379         c.getActionMap().put("enter", a);
     
    7581    }
    7682
     83    /**
     84     * Add an action activated with Spacebar key on a component.
     85     * @param c The Swing component
     86     * @param a action activated with Spacebar key
     87     */
    7788    public static void addSpacebarAction(JComponent c, Action a) {
    7889         c.getActionMap().put("spacebar", a);
  • trunk/src/org/openstreetmap/josm/tools/Shortcut.java

    r7012 r7539  
    1919
    2020import org.openstreetmap.josm.Main;
     21import org.openstreetmap.josm.gui.util.GuiHelper;
    2122
    2223/**
     
    2728 *       finally manages loading and saving shortcuts to/from the preferences.
    2829 *
    29  * Action authors: You only need the {@link #registerShortcut} factory. Ignore everything
    30  *                 else.
     30 * Action authors: You only need the {@link #registerShortcut} factory. Ignore everything else.
    3131 *
    3232 * All: Use only public methods that are also marked to be used. The others are
    3333 *      public so the shortcut preferences can use them.
    34  *
     34 * @since 1084
    3535 */
    3636public final class Shortcut {
     
    262262    }
    263263
     264    /** None group: used with KeyEvent.CHAR_UNDEFINED if no shortcut is defined */
    264265    public static final int NONE = 5000;
    265266    public static final int MNEMONIC = 5001;
     267    /** Reserved group: for system shortcuts only */
    266268    public static final int RESERVED = 5002;
     269    /** Direct group: no modifier */
    267270    public static final int DIRECT = 5003;
     271    /** Alt group */
    268272    public static final int ALT = 5004;
     273    /** Shift group */
    269274    public static final int SHIFT = 5005;
     275    /** Command group. Matches CTRL modifier on Windows/Linux but META modifier on OS X */
    270276    public static final int CTRL = 5006;
     277    /** Alt-Shift group */
    271278    public static final int ALT_SHIFT = 5007;
     279    /** Alt-Command group. Matches ALT-CTRL modifier on Windows/Linux but ALT-META modifier on OS X */
    272280    public static final int ALT_CTRL = 5008;
     281    /** Command-Shift group. Matches CTRL-SHIFT modifier on Windows/Linux but META-SHIFT modifier on OS X */
    273282    public static final int CTRL_SHIFT = 5009;
     283    /** Alt-Command-Shift group. Matches ALT-CTRL-SHIFT modifier on Windows/Linux but ALT-META-SHIFT modifier on OS X */
    274284    public static final int ALT_CTRL_SHIFT = 5010;
    275285
     
    285295        if (initdone) return;
    286296        initdone = true;
     297        int commandDownMask = GuiHelper.getMenuShortcutKeyMaskEx();
    287298        groups.put(NONE, -1);
    288299        groups.put(MNEMONIC, KeyEvent.ALT_DOWN_MASK);
     
    290301        groups.put(ALT, KeyEvent.ALT_DOWN_MASK);
    291302        groups.put(SHIFT, KeyEvent.SHIFT_DOWN_MASK);
    292         groups.put(CTRL, KeyEvent.CTRL_DOWN_MASK);
     303        groups.put(CTRL, commandDownMask);
    293304        groups.put(ALT_SHIFT, KeyEvent.ALT_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK);
    294         groups.put(ALT_CTRL, KeyEvent.ALT_DOWN_MASK|KeyEvent.CTRL_DOWN_MASK);
    295         groups.put(CTRL_SHIFT, KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK);
    296         groups.put(ALT_CTRL_SHIFT, KeyEvent.ALT_DOWN_MASK|KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK);
     305        groups.put(ALT_CTRL, KeyEvent.ALT_DOWN_MASK|commandDownMask);
     306        groups.put(CTRL_SHIFT, commandDownMask|KeyEvent.SHIFT_DOWN_MASK);
     307        groups.put(ALT_CTRL_SHIFT, KeyEvent.ALT_DOWN_MASK|commandDownMask|KeyEvent.SHIFT_DOWN_MASK);
    297308
    298309        // (1) System reserved shortcuts
Note: See TracChangeset for help on using the changeset viewer.