Coverage for src/robotide/action/shortcut.py: 90%
94 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
1# Copyright 2008-2015 Nokia Networks
2# Copyright 2016- Robot Framework Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
16from functools import total_ordering 1ac
18import wx 1ac
20from ..context import IS_MAC 1ac
22CMD_CHAR = u'\u2318' 1ac
23SHIFT_CHAR = u'\u21E7' 1ac
24OPTION_CHAR = u'\u2325' 1ac
25CTRL_CHAR = u'\u2303' 1ac
26SPACE_CHAR = u'\u2423' 1ac
27LEFT_CHAR = u'\u2190' 1ac
28RIGHT_CHAR = u'\u2192' 1ac
29DEL_CHAR = u'\u2326' 1ac
30ENTER_CHAR = u'\u2324' 1ac
31RETURN_CHAR = u'\u21A9' 1ac
32ESC_CHAR = u'\u238B' 1ac
33UP_CHAR = u'\u2191' 1ac
34DOWN_CHAR = u'\u2193' 1ac
36_REPLACE = { 1ac
37 'Cmd': CMD_CHAR,
38 'Shift': SHIFT_CHAR,
39 'Alt': OPTION_CHAR,
40 'Ctrl': CTRL_CHAR,
41 'Space': SPACE_CHAR,
42 'Left': LEFT_CHAR,
43 'Right': RIGHT_CHAR,
44 'Delete': DEL_CHAR,
45 'Enter': ENTER_CHAR,
46 'Return': RETURN_CHAR,
47 'Escape': ESC_CHAR,
48 '-': '',
49 'Up': UP_CHAR,
50 'Down': DOWN_CHAR
51}
54def localize_shortcuts(string): 1ac
55 if IS_MAC: 55 ↛ 58line 55 didn't jump to line 58 because the condition on line 55 was always true1ac
56 string = string.replace('CtrlCmd', 'Cmd') 1ac
57 else:
58 string = string.replace('CtrlCmd', 'Ctrl')
59 return _replace_mac_chars(string) 1ac
62def _replace_mac_chars(string): 1ac
63 if not IS_MAC or not string: 1akjfdeihgcmlb
64 return string 1akjmlb
65 for key, value in _REPLACE.items(): 1akjfdeihgclb
66 string = string.replace(key, value) 1akjfdeihgclb
67 return string 1akjfdeihgclb
70@total_ordering 1ac
71class Shortcut(object): 1ac
73 def __init__(self, shortcut): 1ac
74 self.value = self._normalize(shortcut) 1akjfdeihgmlb
75 self.printable = self._get_printable(self.value) 1akjfdeihgmlb
77 def _get_printable(self, value): 1ac
78 return self._replace_chars_in_mac(value) 1akjfdeihgmlb
80 def _replace_chars_in_mac(self, shortcut): 1ac
81 return _replace_mac_chars(shortcut) 1akjfdeihgmlb
83 def __nonzero__(self): 1ac
84 return bool(self.value)
86 def _normalize(self, shortcut): 1ac
87 if not shortcut: 1akjfdeihgmlb
88 return None 1akjmlb
89 order = ['Shift', 'Ctrl', 'Cmd', 'Alt'] 1akjfdeihglb
90 keys = [self._normalize_key(key) for key in self._split(shortcut)] 1akjfdeihglb
91 try: # DEBUG only in python3 ?? 1akjfdeihglb
92 keys.index('') 1akjfdeihglb
93 keys.pop()
94 return None
95 except ValueError: 1akjfdeihglb
96 pass 1akjfdeihglb
97 keys.sort(key=lambda t: t in order and order.index(t) or 42) 1akjfdeihglb
98 return '-'.join(keys) 1akjfdeihglb
100 def _split(self, shortcut): 1ac
101 try: 1akjfdeihglb
102 m_str=shortcut.replace('+', '-').split('-') 1akjfdeihglb
103 # print("DEBUG: Shortcut %s" % m_str)
104 return m_str 1akjfdeihglb
105 except AttributeError: # DEBUG On python 3 there are NoneType 1ab
106 pass 1ab
107 return '' 1ab
109 def _normalize_key(self, key): 1ac
110 key = key.title() 1akjfdeihglb
111 key = self._handle_ctrlcmd(key) 1akjfdeihglb
112 return {'Del': 'Delete', 'Ins': 'Insert', 1akjfdeihglb
113 'Enter': 'Return', 'Esc':'Escape'}.get(key, key)
115 def _handle_ctrlcmd(self, key): 1ac
116 if key != 'Ctrlcmd': 1akjfdeihglb
117 return key 1akjfdeihglb
118 if IS_MAC: 118 ↛ 120line 118 didn't jump to line 120 because the condition on line 118 was always true1ajdb
119 return 'Cmd' 1ajdb
120 return 'Ctrl'
122 def parse(self): 1ac
123 keys = self._split(self.value) 1afdeihgb
124 if keys: 1afdeihgb
125 # print("DEBUG: parser %s" % keys)
126 if len(keys) == 1: 1afdeihgb
127 flags = wx.ACCEL_NORMAL 1aeihb
128 else:
129 flags = sum(self._get_wx_key_constant('ACCEL', key) 1afdgb
130 for key in keys[:-1])
131 return flags, self._get_key(keys[-1]) 1afdeihgb
133 def _get_wx_key_constant(self, prefix, name): 1ac
134 attr = '%s_%s' % (prefix, name.upper().replace(' ', '')) 1afdehgb
135 try: 1afdehgb
136 return getattr(wx, attr) 1afdehgb
137 except AttributeError: 1e
138 raise ValueError('Invalid shortcut key: %s' % name) 1e
140 def _get_key(self, key): 1ac
141 if len(key) == 1: 1afdeihgb
142 return ord(key.upper()) 1afdigb
143 return self._get_wx_key_constant('WXK', self._normalize_key(key)) 1afehgb
145 def __eq__(self, other): 1ac
146 return self.name.lower() == other.name.lower()
148 def __hash__(self): 1ac
149 return hash(repr(self))
151 def __lt__(self, other): 1ac
152 return self.name.lower() < other.name.lower()
154 def __repr__(self): 1ac
155 return self.printable