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

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. 

15 

16from functools import total_ordering 1ac

17 

18import wx 1ac

19 

20from ..context import IS_MAC 1ac

21 

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

35 

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} 

52 

53 

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

60 

61 

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

68 

69 

70@total_ordering 1ac

71class Shortcut(object): 1ac

72 

73 def __init__(self, shortcut): 1ac

74 self.value = self._normalize(shortcut) 1akjfdeihgmlb

75 self.printable = self._get_printable(self.value) 1akjfdeihgmlb

76 

77 def _get_printable(self, value): 1ac

78 return self._replace_chars_in_mac(value) 1akjfdeihgmlb

79 

80 def _replace_chars_in_mac(self, shortcut): 1ac

81 return _replace_mac_chars(shortcut) 1akjfdeihgmlb

82 

83 def __nonzero__(self): 1ac

84 return bool(self.value) 

85 

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

99 

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

108 

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) 

114 

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' 

121 

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

132 

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

139 

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

144 

145 def __eq__(self, other): 1ac

146 return self.name.lower() == other.name.lower() 

147 

148 def __hash__(self): 1ac

149 return hash(repr(self)) 

150 

151 def __lt__(self, other): 1ac

152 return self.name.lower() < other.name.lower() 

153 

154 def __repr__(self): 1ac

155 return self.printable