1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import libxyz
18
19 from libxyz.core.plugins import Namespace
20 from libxyz.core.utils import ustring
21 from libxyz.core.utils import is_func
22 from libxyz.core.utils import typer
23
24 from libxyz.ui import Shortcut
25
26 from libxyz.exceptions import PluginError
27 from libxyz.exceptions import KeyManagerError
30 """
31 Key bindings management class
32 """
33
34 CONTEXT_DEFAULT = u"DEFAULT"
35 CONTEXT_SELF = u"@"
36
38 self.xyz = xyz
39 self.keys = libxyz.ui.Keys()
40
41 self._loaded_methods = {}
42 self._bind_data = {}
43 self._prefixes = []
44
45
46
47 - def process(self, pressed, context=None):
48 """
49 Process pressed keys
50
51 @return: Tuple (method, arguments)
52 """
53
54 context = context or self.CONTEXT_DEFAULT
55 _p = Shortcut(raw=pressed)
56
57
58 if _p in self._prefixes:
59 _aux = self.xyz.input.get()
60 _p = Shortcut(raw=pressed + _aux)
61
62 _method = None
63
64
65 try:
66 _method = self._bind_data[context][_p]
67 except KeyError:
68
69 pass
70
71 return _method
72
73
74
86
87
88
89 @typer(None, Shortcut)
91 """
92 Check if provided shortcut is a prefix
93 """
94
95 return shortcut in self._prefixes
96
97
98
99 - def load(self, method):
100 """
101 Load method
102 """
103
104 _p = Namespace(method)
105
106
107 if _p.full in self._loaded_methods:
108 return
109
110
111 if _p.method == _p.ALL:
112 self._loaded_methods[_p.full] = _p.ALL
113
114 elif _p.method is None:
115 self.xyz.pm.load(_p)
116 else:
117 self._loaded_methods[_p.full] = self.xyz.pm.from_load(_p.pfull,
118 _p.method)
119
120
121
122 - def bind(self, method, shortcut, context=None):
123 """
124 Bind a shortcut to a method.
125 A method can be either a string, in that case it should denote the
126 plugin method or it can be a function or it can be a tuple with two
127 elements: first - function to bind and the second - string description
128
129 @return: True on success, False otherwise, also raises exception
130 if method was not loaded
131 """
132
133 if isinstance(method, basestring):
134 _p = Namespace(method)
135 _mobj = None
136
137 if context == self.CONTEXT_SELF:
138 context = _p.pfull
139
140
141 if _p.full not in self._loaded_methods:
142 if "%s:%s" % (_p.pfull, _p.ALL) not in self._loaded_methods:
143 raise KeyManagerError(_(u"Method %s not loaded") % _p)
144
145
146 try:
147 _mobj = self.xyz.pm.from_load(_p.pfull, _p.method)
148 except PluginError, e:
149 raise KeyManagerError(_(u"Load error: %s") % e)
150 else:
151 _mobj = self._loaded_methods[_p.full]
152
153 if _mobj is None:
154
155 self.xyz.pm.wait_for(_p, self._bind_wait_cb, _p.method,
156 shortcut, context)
157
158 elif is_func(method):
159 _mobj = method
160 _mobj.ns = _(u"<Internal function object>")
161 elif isinstance(method, tuple) and len(method) == 2:
162 _mobj = method[0]
163 _mobj.ns = method[1]
164 else:
165 raise KeyManagerError(_(u"Invalid method type: %s. "\
166 u"Must be string or function") %
167 type(method))
168
169 self._bind(_mobj, shortcut, context)
170
171
172
174 if method not in plugin_obj.public:
175 xyzlog.error(_(u"Unable to bind method %s. "\
176 u"Plugin %s doesn't export it.") %
177 (method, plugin_obj.ns.pfull))
178 return
179
180 self._bind(plugin_obj.public[method], shortcut, context, force=False)
181
182
183
184 - def _bind(self, mobj, shortcut, context=None, force=True):
196
197
198
200 """
201 Return keybindings data
202 """
203
204 return self._bind_data
205
206
207
208 @typer(None, Shortcut, basestring)
210 """
211 Find a method that a provided shortcut is bound to
212 """
213
214 return self._bind_data[context or self.CONTEXT_DEFAULT].get(sc, None)
215