This is an automated email from the ASF dual-hosted git repository.

ebakke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git

commit f5c239ad21708fa614d045c36b2a429a8538e0ea
Author: Eirik Bakke <[email protected]>
AuthorDate: Thu Sep 22 22:55:13 2022 -0400

    Centralize presentation string generation for keyboard shortcuts in a new 
method Actions.keyStrokeToString, and make some improvements.
    
    Details:
    * Move the logic in o.n.editor.Utilities.keyStrokeToString to a new public 
method org.openide.awt.Actions.keyStrokeToString, and delegate to the latter. 
This avoids duplication of logic, and makes the logic available from modules 
that do not depend on the editor infrastructure.
    * Use InputEvent.getModifiersExText instead of the deprecated 
KeyEvent.getKeyModifiersText.
    * On MacOS, use proper modifier key symbols in the canonical order, without 
a plus sign between them.
    * Use NetBeans' preferred 'NumPad-' prefix instead of 'KP_' for e.g. 
'KP_LEFT'.
---
 .../src/org/netbeans/editor/Utilities.java         | 42 ++--------
 platform/openide.awt/apichanges.xml                | 17 ++++
 .../openide.awt/src/org/openide/awt/Actions.java   | 98 +++++++++++++++++++---
 .../src/org/openide/awt/Bundle.properties          |  3 +
 4 files changed, 112 insertions(+), 48 deletions(-)

diff --git a/ide/editor.lib/src/org/netbeans/editor/Utilities.java 
b/ide/editor.lib/src/org/netbeans/editor/Utilities.java
index ddb3af35ba..e5fa316eb6 100644
--- a/ide/editor.lib/src/org/netbeans/editor/Utilities.java
+++ b/ide/editor.lib/src/org/netbeans/editor/Utilities.java
@@ -83,6 +83,7 @@ import org.netbeans.modules.editor.lib.BeforeSaveTasks;
 import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
 import org.netbeans.modules.editor.lib2.view.DocumentView;
 import org.netbeans.modules.editor.lib2.view.EditorView;
+import org.openide.awt.Actions;
 import org.openide.util.Exceptions;
 import org.openide.util.Mutex;
 import org.openide.util.NbBundle;
@@ -1292,47 +1293,14 @@ public class Utilities {
 
     /**
      * Creates nice textual representation of KeyStroke.
-     * Modifiers and an actual key label are concated by plus signs
+     * Modifiers and an actual key label are concated per the 
platform-specific convention
      * @param stroke the KeyStroke to get description of
      * @return String describing the KeyStroke
      */
     public static String keyStrokeToString( KeyStroke stroke ) {
-        String modifText = KeyEvent.getKeyModifiersText( stroke.getModifiers() 
);
-        String keyText = (stroke.getKeyCode() == KeyEvent.VK_UNDEFINED) ? 
-            String.valueOf(stroke.getKeyChar()) : 
getKeyText(stroke.getKeyCode());
-        if( modifText.length() > 0 ) return modifText + '+' + keyText;
-        else return keyText;
-    }
-    
-    /** @return slight modification of what KeyEvent.getKeyText() returns.
-     *  The numpad Left, Right, Down, Up get extra result.
-     */
-    private static String getKeyText(int keyCode) {
-        String ret = KeyEvent.getKeyText(keyCode);
-        if (ret != null) {
-            switch (keyCode) {
-                case KeyEvent.VK_KP_DOWN:
-                    ret = prefixNumpad(ret, KeyEvent.VK_DOWN);
-                    break;
-                case KeyEvent.VK_KP_LEFT:
-                    ret = prefixNumpad(ret, KeyEvent.VK_LEFT);
-                    break;
-                case KeyEvent.VK_KP_RIGHT:
-                    ret = prefixNumpad(ret, KeyEvent.VK_RIGHT);
-                    break;
-                case KeyEvent.VK_KP_UP:
-                    ret = prefixNumpad(ret, KeyEvent.VK_UP);
-                    break;
-            }
-        }
-        return ret;
-    }
-    
-    private static String prefixNumpad(String key, int testKeyCode) {
-        if (key.equals(KeyEvent.getKeyText(testKeyCode))) {
-            key = 
NbBundle.getBundle(BaseKit.class).getString("key-prefix-numpad") + key;
-        }
-        return key;
+        /* The related logic has now been moved into org.openide.awt.Actions, 
so that it can be used
+        by modules that do not depend on the editor infrastructure. */
+        return Actions.keyStrokeToString(stroke);
     }
 
     private static void checkOffsetValid(Document doc, int offset) throws 
BadLocationException {
diff --git a/platform/openide.awt/apichanges.xml 
b/platform/openide.awt/apichanges.xml
index 3413a01ae5..656ddf2f87 100644
--- a/platform/openide.awt/apichanges.xml
+++ b/platform/openide.awt/apichanges.xml
@@ -26,6 +26,23 @@
 <apidef name="awt">AWT API</apidef>
 </apidefs>
 <changes>
+    <change id="add-actions-keyStrokeToString">
+        <api name="awt"/>
+        <summary>Add Actions.keyStrokeToString utility method.</summary>
+        <version major="7" minor="88"/>
+        <date day="25" month="3" year="2023"/>
+        <author login="ebakke"/>
+        <compatibility binary="compatible" semantic="compatible" 
source="compatible" addition="yes" deprecation="no" deletion="no"/>
+        <description>
+            <p>The Actions.keyStrokeToString method has been added as a public 
API, to avoid
+               duplication of the same logic in the editor.lib module. This 
method has identical
+               semantics to the existing 
org.netbeans.editor.Utilities.Actions.keyStrokeToString
+               method (which now delegates to the new 
Actions.keyStrokeToString), but is available
+               without depending on the editor infrastructure.
+            </p>
+        </description>
+        <class name="Actions" package="org.openide.awt"/>
+    </change>
     <change id="configureDefaultRenderingHints">
         <api name="awt"/>
         <summary>Added 
GraphicsUtils.configureDefaultRenderingHints(Graphics).</summary>
diff --git a/platform/openide.awt/src/org/openide/awt/Actions.java 
b/platform/openide.awt/src/org/openide/awt/Actions.java
index 310d2caae8..5b7c70e8da 100644
--- a/platform/openide.awt/src/org/openide/awt/Actions.java
+++ b/platform/openide.awt/src/org/openide/awt/Actions.java
@@ -24,6 +24,7 @@ import java.awt.Dimension;
 import java.awt.EventQueue;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
@@ -128,25 +129,100 @@ public class Actions {
             return null;
         }
 
-        KeyStroke accelerator = (KeyStroke) 
action.getValue(Action.ACCELERATOR_KEY);
+        KeyStroke stroke = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY);
 
-        if (accelerator == null) {
+        if (stroke == null) {
             return null;
         }
 
-        int modifiers = accelerator.getModifiers();
-        String acceleratorText = ""; // NOI18N
+        return keyStrokeToString(stroke);
+    }
 
-        if (modifiers > 0) {
-            acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
-            acceleratorText += "+"; // NOI18N
-        } else if (accelerator.getKeyCode() == KeyEvent.VK_UNDEFINED) {
-            return ""; // NOI18N
+    // Based on 
com.formdev.flatlaf.FlatMenuItemRenderer.getMacOSModifiersExText
+    private static String getMacOSModifiersExText(int modifiersEx) {
+        /* Use the proper MacOS convention, which uses single-character 
modifier symbols, in the
+        order below, without "+" or space separators. */
+        StringBuilder buf = new StringBuilder();
+        if ((modifiersEx & InputEvent.CTRL_DOWN_MASK) != 0) {
+            buf.append('\u2303'); // MacOS "control key" symbol.
+        }
+        if ((modifiersEx & (InputEvent.ALT_DOWN_MASK | 
InputEvent.ALT_GRAPH_DOWN_MASK)) != 0) {
+            buf.append('\u2325'); // MacOS "option key" symbol.
+        }
+        if ((modifiersEx & InputEvent.SHIFT_DOWN_MASK) != 0) {
+            buf.append('\u21E7'); // MacOS "shift key" symbol.
         }
+        if ((modifiersEx & InputEvent.META_DOWN_MASK) != 0) {
+            buf.append('\u2318'); // MacOS "command key" symbol.
+        }
+        return buf.toString();
+    }
 
-        acceleratorText += KeyEvent.getKeyText(accelerator.getKeyCode());
+    /**
+     * Creates nice textual representation of KeyStroke.
+     * Modifiers and an actual key label are concated per the 
platform-specific convention
+     * @param stroke the KeyStroke to get description of
+     * @return String describing the KeyStroke
+     */
+    public static String keyStrokeToString( KeyStroke stroke ) {
+        boolean macOS = Utilities.isMac();
+        String modifText = macOS
+                ? getMacOSModifiersExText(stroke.getModifiers())
+                : InputEvent.getModifiersExText(stroke.getModifiers());
+        String keyText = (stroke.getKeyCode() == KeyEvent.VK_UNDEFINED) ?
+            String.valueOf(stroke.getKeyChar()) : 
getKeyText(stroke.getKeyCode());
+        if (!modifText.isEmpty()) {
+            if (macOS) {
+                return modifText + keyText;
+            } else {
+                return modifText + '+' + keyText;
+            }
+        } else {
+            return keyText;
+        }
+    }
 
-        return acceleratorText;
+    /** @return slight modification of what KeyEvent.getKeyText() returns.
+     *  The numpad Left, Right, Down, Up get extra result.
+     */
+    private static String getKeyText(int keyCode) {
+        String ret = KeyEvent.getKeyText(keyCode);
+        if (ret != null) {
+            switch (keyCode) {
+                case KeyEvent.VK_KP_DOWN:
+                    ret = prefixNumpad(ret, KeyEvent.VK_DOWN);
+                    break;
+                case KeyEvent.VK_KP_LEFT:
+                    ret = prefixNumpad(ret, KeyEvent.VK_LEFT);
+                    break;
+                case KeyEvent.VK_KP_RIGHT:
+                    ret = prefixNumpad(ret, KeyEvent.VK_RIGHT);
+                    break;
+                case KeyEvent.VK_KP_UP:
+                    ret = prefixNumpad(ret, KeyEvent.VK_UP);
+                    break;
+            }
+        }
+        return ret;
+    }
+
+    private static String prefixNumpad(String key, int nonNumpadCode) {
+        final String REPLACABLE_PREFIX = "KP_";
+        final String usePrefix = NbBundle.getMessage(Actions.class, 
"key-prefix-numpad");
+        final String nonNumpadName = KeyEvent.getKeyText(nonNumpadCode);
+        if (key.equals(nonNumpadName)) {
+            /* AWT's name for the key does not distinguish the numpad vs. 
non-numpad version of the
+            key; add our "Numpad-" prefix. */
+            return usePrefix + key;
+        } else if (key.startsWith(REPLACABLE_PREFIX)) {
+            /* AWT's name for the numpad key uses the somewhat confusing "KP_" 
prefix (e.g.
+            "KP_LEFT"); use our own preferred prefix instead (e.g. 
"Numpad-LEFT"). */
+            return usePrefix + key.substring(REPLACABLE_PREFIX.length());
+        } else {
+            /* AWT is using some other convention to disambiguate the numpad 
vs. non-numpad version
+            of the key. Use AWT's name in this case. */
+            return key;
+        }
     }
 
     /** Attaches menu item to an action.
diff --git a/platform/openide.awt/src/org/openide/awt/Bundle.properties 
b/platform/openide.awt/src/org/openide/awt/Bundle.properties
index 301d991a31..4b85d99e5a 100644
--- a/platform/openide.awt/src/org/openide/awt/Bundle.properties
+++ b/platform/openide.awt/src/org/openide/awt/Bundle.properties
@@ -62,6 +62,9 @@ ACSD_SplittedPanel_EmptySplitter=N/A
 # {1} = shortcut
 FMT_ButtonHint={0} ({1})
 
+# Used by Actions.keyStrokeToString
+key-prefix-numpad=NumPad-
+
 # SwingBrowserImpl
 ACS_SwingBrowserImpl_SwingBrowser=N/A
 #Title while loading


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to