From 87805e2558089e68cd198987123355f1da9f3ca9 Mon Sep 17 00:00:00 2001 From: Huang Peng Date: Mon, 19 May 2008 18:19:39 +0800 Subject: [PATCH] Add lookuptabel.py and add {to,from}_dbus_value to Attribute and AttrList classes. --- ibus/attribute.py | 46 +++++++++++++---- ibus/interface.py | 45 +++++++++------- ibus/lookuptable.py | 122 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 29 deletions(-) create mode 100644 ibus/lookuptable.py diff --git a/ibus/attribute.py b/ibus/attribute.py index 437bc2ae..35a78bcf 100644 --- a/ibus/attribute.py +++ b/ibus/attribute.py @@ -1,4 +1,3 @@ - import dbus ATTR_TYPE_DECORATION = 1 @@ -13,16 +12,30 @@ ATTR_DECORATION_REVERSE = 4 class Attribute: def __init__ (self, type, value, start_index, end_index): self._type = type + self._value = value self._start_index = start_index self._end_index = end_index - self._value = value - def get_values (self): - return [dbus.UInt32 (self._type), - dbus.UInt32 (self._value), - dbus.UInt32 (self._start_index), - dbus.UInt32 (self._end_index)] + def to_dbus_value (self): + values = (dbus.UInt32 (self._type), + dbus.UInt32 (self._value), + dbus.UInt32 (self._start_index), + dbus.UInt32 (self._end_index)) + return dbus.Struct (values) + + def from_dbus_value (self, value): + if not isinstance (value, dbus.Struct): + raise dbus.Exception ("Attribute must be dbus.Struct (uuuu)") + if len (value) != 4 or not all (map (lambda x: isinstance (x, dbus.UInt32), value)): + raise dbus.Exception ("Attribute must be dbus.Struct (uuuu)") + + self._type = value[0] + self._value = value[1] + self._start_index = value[2] + self._end_index = value[3] + + class AttributeDecoration (Attribute): def __init__(self, value, start_index, end_index): Attribute.__init__ (self, ATTR_TYPE_DECORATION, value, start_index, end_index) @@ -52,7 +65,20 @@ class AttrList: assert isinstance (attr, Attribute) self._attrs.append (attr) - def get_array (self): - get_values = lambda attr: attr.get_values () - return map (get_values, self._attrs) + def to_dbus_value (self): + array = dbus.Array () + for attr in self._attrs: + array.append (attr.to_dbus_value ()) + return array + + def from_dbus_value (self, value): + attrs = [] + if not isinstance (value, dbus.Array): + raise IBusException ("AttrList must from dbus.Array (iiii)") + + for v in value: + attr = Attribute (0, 0, 0, 0) + attr.from_dbus_value (v) + attrs.append (attr) + self._attrs = attrs diff --git a/ibus/interface.py b/ibus/interface.py index 65f34736..ad30385e 100644 --- a/ibus/interface.py +++ b/ibus/interface.py @@ -11,7 +11,7 @@ class IIBus (dbus.service.Object): dbus.service.method (dbus_interface = IBUS_IFACE, \ connection_keyword = "dbusconn", \ **args) - + # define async method decorator. async_method = lambda **args: \ dbus.service.method (dbus_interface = IBUS_IFACE, \ @@ -21,10 +21,10 @@ class IIBus (dbus.service.Object): @method (out_signature = "s") def GetIBusAddress (self, dbusconn): pass - + @method (in_signature = "s") def RegisterClient (self, client_name, dbusconn): pass - + @method () def UnregisterClient (self, dbusconn): pass @@ -33,13 +33,16 @@ class IIBus (dbus.service.Object): @method (in_signature = "ao") def UnregisterFactories (self, object_paths, dbusconn): pass - + + @method (in_signature = "ob") + def RegisterPanel (self, object_path, replace, dbusconn): pass + @async_method (in_signature = "ubu", out_signature = "b") def ProcessKeyEvent (self, keyval, is_press, state, dbusconn, reply_cb, error_cb): pass - + @method (in_signature = "iiii") def SetCursorLocation (self, x, y, w, h, dbusconn): pass - + @method () def FocusIn (self, dbusconn): pass @@ -57,7 +60,7 @@ class IEngineFactory (dbus.service.Object): method = lambda **args: \ dbus.service.method (dbus_interface = IBUS_ENGINE_FACTORY_IFACE, \ **args) - + # define async method decorator. async_method = lambda **args: \ dbus.service.method (dbus_interface = IBUS_ENGINE_FACTORY_IFACE, \ @@ -70,7 +73,7 @@ class IEngineFactory (dbus.service.Object): # Factory should allocate all resources in this method @method () def Initialize (self): pass - + # Factory should free all allocated resources in this method @method () def Uninitialize (self): pass @@ -85,12 +88,12 @@ class IEngine (dbus.service.Object): method = lambda **args: \ dbus.service.method (dbus_interface = IBUS_ENGINE_IFACE, \ **args) - + # define signal decorator. signal = lambda **args: \ dbus.service.signal (dbus_interface = IBUS_ENGINE_IFACE, \ **args) - + # define async method decorator. async_method = lambda **args: \ dbus.service.method (dbus_interface = IBUS_ENGINE_IFACE, \ @@ -100,19 +103,19 @@ class IEngine (dbus.service.Object): @method (in_signature = "ubu", out_signature = "b") def ProcessKeyEvent (self, keyval, is_press, state): pass - + @method (in_signature = "iiii") def SetCursorLocation (self, x, y, w, h): pass @method () def FocusIn (self): pass - + @method () def FocusOut (self): pass @method () def Reset (self): pass - + @method (in_signature = "b") def SetEnable (self, enable): pass @@ -126,6 +129,7 @@ class IEngine (dbus.service.Object): def PreeditChanged (self, text, attrs, cursor_pos): pass + # below signals are optional. The engine could create and maintain panel by self. @signal (signature = "a(saai)i") def LookupTableChanged (self, lookup_table, cursor_pos): pass @@ -133,15 +137,15 @@ class IEngine (dbus.service.Object): @signal () def LookupTablePageUp (self): pass - + @signal () def LookupTablePageDown (self): pass - + @signal () def LookupTableCursorUp (self): pass - + @signal () def LookupTableCursorDown (self): pass @@ -151,18 +155,21 @@ class IPanel (dbus.service.Object): method = lambda **args: \ dbus.service.method (dbus_interface = IBUS_PANEL_IFACE, \ **args) - + # define signal decorator. signal = lambda **args: \ dbus.service.signal (dbus_interface = IBUS_PANEL_IFACE, \ **args) - + # define async method decorator. async_method = lambda **args: \ dbus.service.method (dbus_interface = IBUS_PANE_IFACE, \ async_callbacks = ("reply_cb", "error_cb"), \ **args) - + + @method () + def Destroy (self): pass + @signal () def PageUp (self): pass diff --git a/ibus/lookuptable.py b/ibus/lookuptable.py new file mode 100644 index 00000000..36180ce4 --- /dev/null +++ b/ibus/lookuptable.py @@ -0,0 +1,122 @@ +import dbus +from attribute import * +from exception import * + +class Candidates (list): + + def clear (self): + del self[:] + + def to_dbus_value (self): + value = dbus.Array () + for text, attrs in self: + value.append (dbus.Struct ((dbus.String (text), attrs.to_dbus_value ()))) + return value + + def from_dbus_value (self, value): + candidates = [] + if not isinstance (value, dbus.Array): + raise dbus.Exception ("Candidates must from dbus.Array (a(sa(...))") + for candidate in value: + if not isinstance (candidate, dbus.Struct): + raise IBusException ("Candidates must from dbus.Array (a(sa(...)))") + if len (candidate) != 2 or \ + not isinstance (candidate[0], dbus.String): + raise IBusException ("Candidates must from dbus.Array (a(sa(...)))") + text = candidate[0] + attrs = AttrList () + attrs.from_dbus_value (candidate[1]) + + candidates.append ((text, attrs)) + self.clear () + self[:] = candidates + + +class LookupTable: + def __init__ (self, page_size = 5): + self._page_size = page_size + self._cursor_visible = False + self._cursor_pos = 0 + self._candidates = Candidates () + + def set_page_size (self, page_size): + self._page_size = page_size + + def get_page_size (self): + return self._page_size + + def show_cursor (self, show = True): + self._cursor_visible = show + + def is_cursor_visible (self): + return self._cursor_visible + + def get_current_page_start (self): + return (self._cursor_pos / self._page_size) * self._page_size + + def set_cursor_pos (self, pos): + self._current_pos = pos + + def get_cursor_pos (self): + return self._current_pos + + def get_cursor_pos_in_current_page (self): + return self._current_pos % self._page_size + + def page_up (self): + pass + + def page_down (self): + pass + + def cursor_up (self): + pass + + def cursor_down (self): + pass + + def clear (self): + self._candidates.clear () + + def append_candidate (self, candidate, attrs = None): + if attrs == None: + attrs = AttrList () + self._candidates.append ((candidate, attrs)) + + def get_candidate (self, index): + return self._candidates[index] + + def to_dbus_struct (self): + value = (dbus.UInt32 (self._page_size), + dbus.UInt32 (self._cursor_pos), + dbus.Boolean (self._cursor_visible), + self._candidates.to_dbus_value ()) + return dbus.Struct (value) + + def from_dbus_struct (self, value): + if not isinstance (value, dbus.Struct): + raise dbus.Exception ("LookupTable must from dbus.Struct (uuba(...))") + + if len (value) != 4 or \ + not isinstance (value[0], dbus.UInt32) or \ + not isinstance (value[1], dbus.UInt32) or \ + not isinstance (value[2], dbus.Boolean): + raise dbus.Exception ("LookupTable must from dbus.Struct (uuba(...))") + + self._candidates.from_dbus_value (value[3]) + self._page_size = value[0] + self._cursor_pos = value[1] + self._cursor_visible = value[2] + + +def test (): + t = LookupTable () + attrs = AttrList () + attrs.append (AttributeBackground (RGB (233, 0,1), 0, 3)) + t.append_candidate ("Hello", attrs) + value = t.to_dbus_struct () + print value + t.from_dbus_struct (value) + +if __name__ == "__main__": + test () -- 2.34.1