Skip to content

Commit 308a963

Browse files
authored
Merge 1346837 into f90caa9
2 parents f90caa9 + 1346837 commit 308a963

3 files changed

Lines changed: 147 additions & 17 deletions

File tree

source/JABHandler.py

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,33 @@ class AccessibleTableCellInfo(Structure):
226226
]
227227

228228
MAX_KEY_BINDINGS=50
229-
ACCESSIBLE_SHIFT_KEYSTROKE=1
230-
ACCESSIBLE_CONTROL_KEYSTROKE=2
231-
ACCESSIBLE_META_KEYSTROKE=4
232-
ACCESSIBLE_ALT_KEYSTROKE=8
233-
ACCESSIBLE_ALT_GRAPH_KEYSTROKE=16
234-
ACCESSIBLE_BUTTON1_KEYSTROKE=32
235-
ACCESSIBLE_BUTTON2_KEYSTROKE=64
236-
ACCESSIBLE_BUTTON3_KEYSTROKE=128
229+
ACCESSIBLE_SHIFT_KEYSTROKE = 1
230+
ACCESSIBLE_CONTROL_KEYSTROKE = 2
231+
ACCESSIBLE_META_KEYSTROKE = 4
232+
ACCESSIBLE_ALT_KEYSTROKE = 8
233+
ACCESSIBLE_ALT_GRAPH_KEYSTROKE = 16
234+
ACCESSIBLE_BUTTON1_KEYSTROKE = 32
235+
ACCESSIBLE_BUTTON2_KEYSTROKE = 64
236+
ACCESSIBLE_BUTTON3_KEYSTROKE = 128
237+
ACCESSIBLE_FKEY_KEYSTROKE = 256 # F key pressed, character contains 1-24
238+
ACCESSIBLE_CONTROLCODE_KEYSTROKE = 512 # Control code key pressed, character contains control code.
239+
240+
# The supported control code keys are:
241+
ACCESSIBLE_VK_BACK_SPACE = 8
242+
ACCESSIBLE_VK_DELETE = 127
243+
ACCESSIBLE_VK_DOWN = 40
244+
ACCESSIBLE_VK_END = 35
245+
ACCESSIBLE_VK_HOME = 36
246+
ACCESSIBLE_VK_INSERT = 155
247+
ACCESSIBLE_VK_KP_DOWN = 225
248+
ACCESSIBLE_VK_KP_LEFT = 226
249+
ACCESSIBLE_VK_KP_RIGHT = 227
250+
ACCESSIBLE_VK_KP_UP = 224
251+
ACCESSIBLE_VK_LEFT = 37
252+
ACCESSIBLE_VK_PAGE_DOWN = 34
253+
ACCESSIBLE_VK_PAGE_UP = 33
254+
ACCESSIBLE_VK_RIGHT = 39
255+
ACCESSIBLE_VK_UP = 38
237256

238257
class AccessibleKeyBindingInfo(Structure):
239258
_fields_=[
@@ -827,3 +846,46 @@ def terminate():
827846
bridgeDll=None
828847
windll.kernel32.FreeLibrary(h)
829848
isRunning=False
849+
850+
851+
JABKeyControlCodesToLabels = {
852+
ACCESSIBLE_VK_UP: "uparrow",
853+
ACCESSIBLE_VK_DOWN: "downarrow",
854+
ACCESSIBLE_VK_LEFT: "leftarrow",
855+
ACCESSIBLE_VK_RIGHT: "rightarrow",
856+
ACCESSIBLE_VK_KP_UP: "numpad8",
857+
ACCESSIBLE_VK_KP_DOWN: "numpad2",
858+
ACCESSIBLE_VK_KP_LEFT: "numpad4",
859+
ACCESSIBLE_VK_KP_RIGHT: "numpad6",
860+
ACCESSIBLE_VK_BACK_SPACE: "backspace",
861+
ACCESSIBLE_VK_INSERT: "insert",
862+
ACCESSIBLE_VK_DELETE: "delete",
863+
ACCESSIBLE_VK_HOME: "home",
864+
ACCESSIBLE_VK_END: "end",
865+
ACCESSIBLE_VK_PAGE_UP: "pageup",
866+
ACCESSIBLE_VK_PAGE_DOWN: "pagedown"
867+
}
868+
869+
# Do not include ACCESSIBLE_FKEY_KEYSTROKE and ACCESSIBLE_CONTROLCODE_KEYSTROKE
870+
# as these are not really modifiers
871+
JABKeyModifiersToLabels = {
872+
ACCESSIBLE_BUTTON3_KEYSTROKE: "button3",
873+
ACCESSIBLE_BUTTON2_KEYSTROKE: "button2",
874+
ACCESSIBLE_BUTTON1_KEYSTROKE: "button1",
875+
ACCESSIBLE_ALT_GRAPH_KEYSTROKE: "altgraph",
876+
ACCESSIBLE_ALT_KEYSTROKE: "alt",
877+
ACCESSIBLE_META_KEYSTROKE: "meta",
878+
ACCESSIBLE_CONTROL_KEYSTROKE: "control",
879+
ACCESSIBLE_SHIFT_KEYSTROKE: "shift"
880+
}
881+
882+
883+
def _getKeyLabels(modifiers, character):
884+
keys = [v for m, v in JABKeyModifiersToLabels.items() if modifiers & m]
885+
if modifiers & ACCESSIBLE_FKEY_KEYSTROKE:
886+
keys.append("F{}".format(ord(character)))
887+
elif modifiers & ACCESSIBLE_CONTROLCODE_KEYSTROKE:
888+
keys.append(JABKeyControlCodesToLabels.get(ord(character), character))
889+
else:
890+
keys.append(character)
891+
return keys

source/NVDAObjects/JAB/__init__.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from .. import InvalidNVDAObject
1919
from locationHelper import RectLTWH
2020

21+
2122
JABRolesToNVDARoles={
2223
"alert":controlTypes.Role.DIALOG,
2324
"column header":controlTypes.Role.TABLECOLUMNHEADER,
@@ -95,6 +96,8 @@
9596
"editable":controlTypes.State.EDITABLE,
9697
}
9798

99+
100+
98101
re_simpleXmlTag=re.compile(r"\<[^>]+\>")
99102

100103

@@ -270,16 +273,13 @@ def _get_keyboardShortcut(self):
270273
# We don't support these modifiers
271274
if binding.modifiers&(JABHandler.ACCESSIBLE_META_KEYSTROKE|JABHandler.ACCESSIBLE_ALT_GRAPH_KEYSTROKE|JABHandler.ACCESSIBLE_BUTTON1_KEYSTROKE|JABHandler.ACCESSIBLE_BUTTON2_KEYSTROKE|JABHandler.ACCESSIBLE_BUTTON3_KEYSTROKE):
272275
continue
273-
keyList=[]
276+
modifiers = binding.modifiers
274277
# We assume alt if there are no modifiers at all and its not a menu item as this is clearly a nmonic
275-
if (binding.modifiers&JABHandler.ACCESSIBLE_ALT_KEYSTROKE) or (not binding.modifiers and self.role!=controlTypes.Role.MENUITEM):
276-
keyList.append(keyLabels.localizedKeyLabels['alt'])
277-
if binding.modifiers&JABHandler.ACCESSIBLE_CONTROL_KEYSTROKE:
278-
keyList.append(keyLabels.localizedKeyLabels['control'])
279-
if binding.modifiers&JABHandler.ACCESSIBLE_SHIFT_KEYSTROKE:
280-
keyList.append(keyLabels.localizedKeyLabels['shift'])
281-
keyList.append(binding.character)
282-
shortcutsList.append("+".join(keyList))
278+
if not modifiers and self.role != controlTypes.Role.MENUITEM:
279+
modifiers |= JABHandler.ACCESSIBLE_ALT_KEYSTROKE
280+
keyList = [keyLabels.localizedKeyLabels.get(l, l)
281+
for l in JABHandler._getKeyLabels(modifiers, binding.character)]
282+
shortcutsList.append("+".join(keyList))
283283
return ", ".join(shortcutsList)
284284

285285
def _get_name(self):

tests/unit/test_javaAccessBridge.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import unittest
99
from NVDAObjects import JAB
10+
import JABHandler
1011

1112

1213
class TestJavaAccessBridge(unittest.TestCase):
@@ -26,3 +27,70 @@ def test_htmlStringHasTagsRemoved(self):
2627
htmlStr = "<html><body><p>Some <b>bold</b> text.</p></body></html>"
2728
expected = " Some bold text. "
2829
self.assertEqual(expected, JAB._processHtml(htmlStr))
30+
31+
32+
MODIFIER_COMBINATIONS = [
33+
{},
34+
{JABHandler.ACCESSIBLE_ALT_KEYSTROKE: "alt"},
35+
{JABHandler.ACCESSIBLE_SHIFT_KEYSTROKE: "shift"},
36+
{JABHandler.ACCESSIBLE_CONTROL_KEYSTROKE: "control"},
37+
{JABHandler.ACCESSIBLE_CONTROL_KEYSTROKE: "control", JABHandler.ACCESSIBLE_SHIFT_KEYSTROKE: "shift"},
38+
{JABHandler.ACCESSIBLE_ALT_KEYSTROKE: "alt",
39+
JABHandler.ACCESSIBLE_CONTROL_KEYSTROKE: "control",
40+
JABHandler.ACCESSIBLE_SHIFT_KEYSTROKE: "shift"},
41+
{JABHandler.ACCESSIBLE_ALT_KEYSTROKE: "alt", JABHandler.ACCESSIBLE_SHIFT_KEYSTROKE: "shift"},
42+
{JABHandler.ACCESSIBLE_ALT_KEYSTROKE: "alt", JABHandler.ACCESSIBLE_CONTROL_KEYSTROKE: "control"},
43+
{JABHandler.ACCESSIBLE_ALT_GRAPH_KEYSTROKE: "altgraph"},
44+
{JABHandler.ACCESSIBLE_META_KEYSTROKE: "meta"},
45+
{JABHandler.ACCESSIBLE_BUTTON1_KEYSTROKE: "button1"},
46+
{JABHandler.ACCESSIBLE_BUTTON2_KEYSTROKE: "button2"},
47+
{JABHandler.ACCESSIBLE_BUTTON3_KEYSTROKE: "button3"},
48+
{JABHandler.ACCESSIBLE_BUTTON3_KEYSTROKE: "button3",
49+
JABHandler.ACCESSIBLE_BUTTON2_KEYSTROKE: "button2",
50+
JABHandler.ACCESSIBLE_BUTTON1_KEYSTROKE: "button1",
51+
JABHandler.ACCESSIBLE_ALT_GRAPH_KEYSTROKE: "altgraph",
52+
JABHandler.ACCESSIBLE_ALT_KEYSTROKE: "alt",
53+
JABHandler.ACCESSIBLE_META_KEYSTROKE: "meta",
54+
JABHandler.ACCESSIBLE_CONTROL_KEYSTROKE: "control",
55+
JABHandler.ACCESSIBLE_SHIFT_KEYSTROKE: "shift"}
56+
]
57+
BASIC_SHORTCUT_KEYS = [chr(x) for x in range(ord('A'), ord('Z') + 1)]
58+
FKEY_SHORTCUTS = [chr(x) for x in range(1, 25)]
59+
60+
61+
class TestJavaAccessBridgeShortcutKeys(unittest.TestCase):
62+
def testBasicShortcut(self):
63+
for c in BASIC_SHORTCUT_KEYS:
64+
for modifierCombination in MODIFIER_COMBINATIONS:
65+
modifiers = 0
66+
modLabels = []
67+
for m, l in modifierCombination.items():
68+
modifiers |= m
69+
modLabels.append(l)
70+
with self.subTest(character=c, modifiers=modifiers, modLabels=modLabels):
71+
expected = modLabels + [c]
72+
self.assertListEqual(expected, JABHandler._getKeyLabels(modifiers, c))
73+
74+
def testFKeyShortcut(self):
75+
for c in FKEY_SHORTCUTS:
76+
for modifierCombination in MODIFIER_COMBINATIONS:
77+
modifiers = JABHandler.ACCESSIBLE_FKEY_KEYSTROKE
78+
modLabels = []
79+
for m, l in modifierCombination.items():
80+
modifiers |= m
81+
modLabels.append(l)
82+
with self.subTest(fkey=ord(c), modifiers=modifiers, modLabels=modLabels):
83+
expected = modLabels + ["F{}".format(ord(c))]
84+
self.assertListEqual(expected, JABHandler._getKeyLabels(modifiers, c))
85+
86+
def testControlCodeShortcut(self):
87+
for c, v in JABHandler.JABKeyControlCodesToLabels.items():
88+
for modifierCombination in MODIFIER_COMBINATIONS:
89+
modifiers = JABHandler.ACCESSIBLE_CONTROLCODE_KEYSTROKE
90+
modLabels = []
91+
for m, l in modifierCombination.items():
92+
modifiers |= m
93+
modLabels.append(l)
94+
with self.subTest(controlCode=c, label=v, modifiers=modifiers, modLabels=modLabels):
95+
expected = modLabels + [v]
96+
self.assertListEqual(expected, JABHandler._getKeyLabels(modifiers, chr(c)))

0 commit comments

Comments
 (0)