Ticket #21443: 21443.patch
File 21443.patch, 13.3 KB (added by , 3 years ago) |
---|
-
new file src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedComponent.java
diff --git a/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedComponent.java b/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedComponent.java new file mode 100644 index 0000000000..a792c63749
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.widgets; 3 4 import java.awt.Component; 5 import java.awt.event.FocusEvent; 6 import java.awt.event.FocusListener; 7 import java.awt.event.InputEvent; 8 import java.awt.event.KeyEvent; 9 import java.util.List; 10 import java.util.Set; 11 12 import javax.swing.Action; 13 import javax.swing.JMenu; 14 import javax.swing.JMenuItem; 15 import javax.swing.KeyStroke; 16 17 import org.openstreetmap.josm.actions.JosmAction; 18 import org.openstreetmap.josm.gui.MainApplication; 19 import org.openstreetmap.josm.tools.Pair; 20 import org.openstreetmap.josm.tools.Shortcut; 21 import org.openstreetmap.josm.tools.annotations.PrivateMethod; 22 23 /** 24 * An interface for components with code that can be used for disabling shortcuts while they hold focus. 25 * 26 * Warning: On migration to Java 9+, all methods marked 27 * @author Taylor Smock 28 * @since xxx (code extracted for {@link DisableShortcutsOnFocusGainedTextField} 29 */ 30 public interface DisableShortcutsOnFocusGainedComponent extends FocusListener { 31 32 @Override 33 default void focusGained(FocusEvent e) { 34 disableMenuActions(); 35 unregisterActionShortcuts(); 36 } 37 38 @Override 39 default void focusLost(FocusEvent e) { 40 restoreActionShortcuts(); 41 restoreMenuActions(); 42 } 43 44 /** 45 * Get the unregistered action shortcuts. 46 * This should not be used outside the {@link DisableShortcutsOnFocusGainedComponent} interface. 47 * @return The list of unregistered action shortcuts (modifiable) 48 */ 49 List<Pair<Action, Shortcut>> getUnregisteredActionShortcuts(); 50 51 /** 52 * Get the disabled menu action list 53 * This should not be used outside the {@link DisableShortcutsOnFocusGainedComponent} interface. 54 * @return The list of disabled menu actions (modifiable) 55 */ 56 Set<JosmAction> getDisabledMenuActions(); 57 58 /** 59 * Disables all relevant menu actions. 60 * @see #hasToBeDisabled 61 */ 62 @PrivateMethod("Was protected") 63 default void disableMenuActions() { 64 getDisabledMenuActions().clear(); 65 for (int i = 0; i < MainApplication.getMenu().getMenuCount(); i++) { 66 JMenu menu = MainApplication.getMenu().getMenu(i); 67 if (menu != null) { 68 for (int j = 0; j < menu.getItemCount(); j++) { 69 JMenuItem item = menu.getItem(j); 70 if (item != null) { 71 Action action = item.getAction(); 72 if (action instanceof JosmAction && action.isEnabled()) { 73 Shortcut shortcut = ((JosmAction) action).getShortcut(); 74 if (shortcut != null) { 75 KeyStroke ks = shortcut.getKeyStroke(); 76 if (hasToBeDisabled(ks)) { 77 action.setEnabled(false); 78 getDisabledMenuActions().add((JosmAction) action); 79 } 80 } 81 } 82 } 83 } 84 } 85 } 86 } 87 88 /** 89 * Unregisters all relevant action shortcuts. 90 * @see #hasToBeDisabled 91 */ 92 @PrivateMethod("Was protected") 93 default void unregisterActionShortcuts() { 94 getUnregisteredActionShortcuts().clear(); 95 // Unregister all actions with Shift modifier or without modifiers to avoid them to be triggered by typing in this text field 96 for (Shortcut shortcut : Shortcut.listAll()) { 97 KeyStroke ks = shortcut.getKeyStroke(); 98 if (hasToBeDisabled(ks)) { 99 Action action = MainApplication.getRegisteredActionShortcut(shortcut); 100 if (action != null) { 101 MainApplication.unregisterActionShortcut(action, shortcut); 102 getUnregisteredActionShortcuts().add(new Pair<>(action, shortcut)); 103 } 104 } 105 } 106 } 107 108 /** 109 * Returns true if the given shortcut has Shift modifier or no modifier and is not an actions key. 110 * @param ks key stroke 111 * @return {@code true} if the given shortcut has to be disabled 112 * @see KeyEvent#isActionKey() 113 */ 114 @PrivateMethod("Was protected") 115 default boolean hasToBeDisabled(KeyStroke ks) { 116 if (this instanceof Component) { 117 return ks != null && (ks.getModifiers() == 0 || isOnlyShift(ks.getModifiers())) && !new KeyEvent((Component) this, 118 KeyEvent.KEY_PRESSED, 0, ks.getModifiers(), ks.getKeyCode(), ks.getKeyChar()).isActionKey(); 119 } 120 throw new UnsupportedOperationException(this.getClass().getSimpleName() + " is not an instanceof Component"); 121 } 122 123 /** 124 * Check if the modifiers is only shift 125 * @param modifiers The modifiers to check 126 * @return {@code true} if the only modifier is {@link InputEvent#SHIFT_DOWN_MASK} 127 */ 128 @PrivateMethod("Was private") 129 static boolean isOnlyShift(int modifiers) { 130 return (modifiers & InputEvent.SHIFT_DOWN_MASK) != 0 131 && (modifiers & InputEvent.CTRL_DOWN_MASK) == 0 132 && (modifiers & InputEvent.ALT_DOWN_MASK) == 0 133 && (modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) == 0 134 && (modifiers & InputEvent.META_DOWN_MASK) == 0; 135 } 136 137 /** 138 * Restore all actions previously disabled 139 */ 140 @PrivateMethod("Was protected") 141 default void restoreMenuActions() { 142 for (JosmAction a : getDisabledMenuActions()) { 143 a.setEnabled(true); 144 } 145 getDisabledMenuActions().clear(); 146 } 147 148 /** 149 * Restore all action shortcuts previously unregistered 150 */ 151 @PrivateMethod("Was protected") 152 default void restoreActionShortcuts() { 153 for (Pair<Action, Shortcut> p : getUnregisteredActionShortcuts()) { 154 MainApplication.registerActionShortcut(p.a, p.b); 155 } 156 getUnregisteredActionShortcuts().clear(); 157 } 158 } -
src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java
diff --git a/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java b/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java index 13e8e687f8..b035615d2c 100644
a b 2 2 package org.openstreetmap.josm.gui.widgets; 3 3 4 4 import java.awt.event.FocusEvent; 5 import java.awt.event.InputEvent;6 import java.awt.event.KeyEvent;7 5 import java.util.ArrayList; 8 6 import java.util.HashSet; 9 7 import java.util.List; 10 8 import java.util.Set; 11 9 12 10 import javax.swing.Action; 13 import javax.swing.JMenu;14 import javax.swing.JMenuItem;15 import javax.swing.KeyStroke;16 11 import javax.swing.text.Document; 17 12 18 13 import org.openstreetmap.josm.actions.JosmAction; 19 import org.openstreetmap.josm.gui.MainApplication;20 14 import org.openstreetmap.josm.tools.Pair; 21 15 import org.openstreetmap.josm.tools.Shortcut; 22 16 … … import org.openstreetmap.josm.tools.Shortcut; 26 20 * This allows to include text fields in toggle dialogs (needed for relation filter). 27 21 * @since 5696 28 22 */ 29 public class DisableShortcutsOnFocusGainedTextField extends JosmTextField {23 public class DisableShortcutsOnFocusGainedTextField extends JosmTextField implements DisableShortcutsOnFocusGainedComponent { 30 24 31 25 /** 32 26 * Constructs a new <code>TextField</code>. A default model is created, … … public class DisableShortcutsOnFocusGainedTextField extends JosmTextField { 97 91 @Override 98 92 public void focusGained(FocusEvent e) { 99 93 super.focusGained(e); 100 disableMenuActions(); 101 unregisterActionShortcuts(); 94 DisableShortcutsOnFocusGainedComponent.super.focusGained(e); 102 95 } 103 96 104 97 @Override 105 98 public void focusLost(FocusEvent e) { 106 99 super.focusLost(e); 107 restoreActionShortcuts(); 108 restoreMenuActions(); 100 DisableShortcutsOnFocusGainedComponent.super.focusLost(e); 109 101 } 110 102 111 /** 112 * Disables all relevant menu actions. 113 * @see #hasToBeDisabled 114 */ 115 protected void disableMenuActions() { 116 disabledMenuActions.clear(); 117 for (int i = 0; i < MainApplication.getMenu().getMenuCount(); i++) { 118 JMenu menu = MainApplication.getMenu().getMenu(i); 119 if (menu != null) { 120 for (int j = 0; j < menu.getItemCount(); j++) { 121 JMenuItem item = menu.getItem(j); 122 if (item != null) { 123 Action action = item.getAction(); 124 if (action instanceof JosmAction && action.isEnabled()) { 125 Shortcut shortcut = ((JosmAction) action).getShortcut(); 126 if (shortcut != null) { 127 KeyStroke ks = shortcut.getKeyStroke(); 128 if (hasToBeDisabled(ks)) { 129 action.setEnabled(false); 130 disabledMenuActions.add((JosmAction) action); 131 } 132 } 133 } 134 } 135 } 136 } 137 } 138 } 139 140 /** 141 * Unregisters all relevant action shortcuts. 142 * @see #hasToBeDisabled 143 */ 144 protected void unregisterActionShortcuts() { 145 unregisteredActionShortcuts.clear(); 146 // Unregister all actions with Shift modifier or without modifiers to avoid them to be triggered by typing in this text field 147 for (Shortcut shortcut : Shortcut.listAll()) { 148 KeyStroke ks = shortcut.getKeyStroke(); 149 if (hasToBeDisabled(ks)) { 150 Action action = MainApplication.getRegisteredActionShortcut(shortcut); 151 if (action != null) { 152 MainApplication.unregisterActionShortcut(action, shortcut); 153 unregisteredActionShortcuts.add(new Pair<>(action, shortcut)); 154 } 155 } 156 } 157 } 158 159 /** 160 * Returns true if the given shortcut has Shift modifier or no modifier and is not an actions key. 161 * @param ks key stroke 162 * @return {@code true} if the given shortcut has to be disabled 163 * @see KeyEvent#isActionKey() 164 */ 165 protected boolean hasToBeDisabled(KeyStroke ks) { 166 return ks != null && (ks.getModifiers() == 0 || isOnlyShift(ks.getModifiers())) && !new KeyEvent( 167 this, KeyEvent.KEY_PRESSED, 0, ks.getModifiers(), ks.getKeyCode(), ks.getKeyChar()).isActionKey(); 168 } 169 170 private static boolean isOnlyShift(int modifiers) { 171 return (modifiers & InputEvent.SHIFT_DOWN_MASK) != 0 172 && (modifiers & InputEvent.CTRL_DOWN_MASK) == 0 173 && (modifiers & InputEvent.ALT_DOWN_MASK) == 0 174 && (modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) == 0 175 && (modifiers & InputEvent.META_DOWN_MASK) == 0; 103 @Override 104 public List<Pair<Action, Shortcut>> getUnregisteredActionShortcuts() { 105 return this.unregisteredActionShortcuts; 176 106 } 177 107 178 /** 179 * Restore all actions previously disabled 180 */ 181 protected void restoreMenuActions() { 182 for (JosmAction a : disabledMenuActions) { 183 a.setEnabled(true); 184 } 185 disabledMenuActions.clear(); 108 @Override 109 public Set<JosmAction> getDisabledMenuActions() { 110 return this.disabledMenuActions; 186 111 } 187 112 188 /**189 * Restore all action shortcuts previously unregistered190 */191 protected void restoreActionShortcuts() {192 for (Pair<Action, Shortcut> p : unregisteredActionShortcuts) {193 MainApplication.registerActionShortcut(p.a, p.b);194 }195 unregisteredActionShortcuts.clear();196 }197 113 } -
new file src/org/openstreetmap/josm/tools/annotations/PrivateMethod.java
diff --git a/src/org/openstreetmap/josm/tools/annotations/PrivateMethod.java b/src/org/openstreetmap/josm/tools/annotations/PrivateMethod.java new file mode 100644 index 0000000000..7e7e4554ba
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.tools.annotations; 3 4 /** 5 * This annotation marks methods that will become private when JOSM migrates the codebase to JOSM 9+. 6 * This is typically used in interfaces. 7 * @author Taylor Smock 8 * @since xxx 9 */ 10 public @interface PrivateMethod { 11 /** 12 * The reason why this method will become private 13 * @return The reason 14 */ 15 String value() default ""; 16 } -
new file src/org/openstreetmap/josm/tools/annotations/package-info.java
diff --git a/src/org/openstreetmap/josm/tools/annotations/package-info.java b/src/org/openstreetmap/josm/tools/annotations/package-info.java new file mode 100644 index 0000000000..eeb988cf11
- + 1 // License: GPL. For details, see LICENSE file. 2 3 /** 4 * Provides the annotations to mark items for future changes 5 */ 6 package org.openstreetmap.josm.tools.annotations;