-
import dbus
ATTR_TYPE_DECORATION = 1
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)
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
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, \
@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
@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
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, \
# 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
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, \
@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
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
@signal ()
def LookupTablePageUp (self):
pass
-
+
@signal ()
def LookupTablePageDown (self):
pass
-
+
@signal ()
def LookupTableCursorUp (self):
pass
-
+
@signal ()
def LookupTableCursorDown (self):
pass
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
--- /dev/null
+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 ()