WIP.
authorHuang Peng <shawn.p.huang@gmail.com>
Thu, 29 May 2008 09:22:46 +0000 (17:22 +0800)
committerHuang Peng <shawn.p.huang@gmail.com>
Thu, 29 May 2008 09:22:46 +0000 (17:22 +0800)
15 files changed:
engine/demo/engine.py
gtk2/gikimclient.c
ibus/attribute.py
ibus/gtk.py
ibus/interface/iengine.py
ibus/interface/ipanel.py
ibusdaemon/bus.py
ibusdaemon/client.py
ibusdaemon/engine.py
ibusdaemon/panel.py
panel/Makefile
panel/candidatepanel.py
panel/candidatewindow.py
panel/main.py
panel/panel.py

index 0631f84..e7205f6 100644 (file)
@@ -1,6 +1,9 @@
 #!/usr/bin/env python
 import gobject
 import gtk
+import pango
+import dbus
+import ibus
 from ibus import keysyms
 from ibus import interface
 
@@ -8,16 +11,40 @@ class Engine (interface.IEngine):
        def __init__ (self, dbusconn, object_path):
                interface.IEngine.__init__ (self, dbusconn, object_path)
                self._dbusconn = dbusconn
+               self._preedit_string = ""
 
        # methods for dbus rpc
        def ProcessKeyEvent (self, keyval, is_press, state):
+               # ignore key release events
                if not is_press:
                        return False
-               if keyval < 128 and (state & keysyms.CONTROL_MASK | keysyms.MOD1_MASK | keysyms.SHIFT_MASK) == 0:
-                       self.CommitString (chr(keyval))
-                       print "commit %s" % chr(keyval)
-                       return True
-               return False
+
+               if self._preedit_string:
+                       if keyval == keysyms.Return:
+                               self.CommitString (self._preedit_string)
+                               self._preedit_string = ""
+                               self._update_preedit ()
+                               return True
+                       elif keyval == keysyms.BackSpace:
+                               self._preedit_string = self._preedit_string[:-1]
+                               self._update_preedit ()
+                               return True
+
+               # ignore hotkeys or key > 128
+               if keyval >= 128 or (state & (keysyms.CONTROL_MASK | keysyms.MOD1_MASK)) != 0:
+                       return False
+
+               self._preedit_string += chr (keyval)
+               self._update_preedit ()
+
+               return True
+
+       def _update_preedit (self):
+               preedit_len = len (self._preedit_string)
+               attrs = ibus.AttrList ()
+               attrs.append (ibus.AttributeUnderline (pango.UNDERLINE_SINGLE, 0, preedit_len))
+               self.PreeditChanged (self._preedit_string, attrs.to_dbus_value (), dbus.Int32 (preedit_len))
+               self.AuxStringChanged (self._preedit_string, attrs.to_dbus_value ())
 
        def FocusIn (self):
                print "FocusIn"
index 6639930..9836d37 100644 (file)
@@ -493,7 +493,7 @@ _gik_signal_preedit_changed_handler (DBusConnection *connection, DBusMessage *me
     }
     dbus_message_iter_recurse (&iter, &sub_iter);
     if (dbus_message_iter_get_arg_type (&sub_iter) != DBUS_TYPE_ARRAY ||
-        dbus_message_iter_get_element_type (&sub_iter) != DBUS_TYPE_UINT32 ) {
+        dbus_message_iter_get_element_type (&sub_iter) != DBUS_TYPE_INT32 ) {
         g_warning ("The secode argument of PreeditChanged signal must be a Struct Array");
         return;
     }
@@ -513,8 +513,8 @@ _gik_signal_preedit_changed_handler (DBusConnection *connection, DBusMessage *me
         }
 
         switch (values[0]) {
-        case 1: /* Decoration */
-            attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
+        case 1: /* Underline */
+            attr = pango_attr_underline_new (values[1]);
             attr->start_index = values[2];
             attr->end_index = values[3];
             pango_attr_list_insert (attrs, attr);
@@ -552,7 +552,7 @@ _gik_signal_preedit_changed_handler (DBusConnection *connection, DBusMessage *me
 
     type = dbus_message_iter_get_arg_type (&iter);
     if (type != DBUS_TYPE_INT32) {
-        g_warning ("The third argument of PreeditChanged signal must be an Int32");
+        g_warning ("The third argument of PreeditChanged signal must be an Int32 %c", type);
         pango_attr_list_unref (attrs);
         return;
     }
index f63e67e..89e75b3 100644 (file)
@@ -12,17 +12,17 @@ class Attribute:
                self._end_index = 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)]
+               values = [dbus.Int32 (self._type),
+                               dbus.Int32 (self._value),
+                               dbus.Int32 (self._start_index),
+                               dbus.Int32 (self._end_index)]
                return dbus.Array (values)
 
        def from_dbus_value (self, value):
                if not isinstance (value, dbus.Array):
                        raise dbus.Exception ("Attribute must be dbus.Array (uuuu)")
 
-               if len (value) != 4 or not all (map (lambda x: isinstance (x, dbus.UInt32), value)):
+               if len (value) != 4 or not all (map (lambda x: isinstance (x, dbus.Int32), value)):
                        raise dbus.Exception ("Attribute must be dbus.Array (uuuu)")
 
                self._type = value[0]
index 95168ed..b9e5fa7 100644 (file)
@@ -4,23 +4,24 @@ import ibus
 class PangoAttrList (pango.AttrList):
        def __init__ (self, attrs):
                pango.AttrList.__init__ (self)
+               if attrs == None:
+                       return
                for attr in attrs:
                        pango_attr = None
-                       if attr._type == ATTR_TYPE_FOREGROUND:
+                       if attr._type == ibus.ATTR_TYPE_FOREGROUND:
                                r = (attr._value & 0x00ff0000) >> 8
                                g = (attr._value & 0x0000ff00)
                                b = (attr._value & 0x000000ff) << 8
                                pango_attr = pango.AttrForeground (r, g, b, 
                                        attr._start_index, attr._end_index)
-                       elif attr._type == ATTR_TYPE_BACKGROUND:
+                       elif attr._type == ibus.ATTR_TYPE_BACKGROUND:
                                r = (attr._value & 0x00ff0000) >> 8
                                g = (attr._value & 0x0000ff00)
                                b = (attr._value & 0x000000ff) << 8
                                pango_attr = pango.AttrBackground (r, g, b, 
                                        attr._start_index, attr._end_index)
-                       elif attr._type == ATTR_TYPE_UNDERLINE:
-                               pango_attr = pango.AttrUnderline (
-                                                                               attr._value,
+                       elif attr._type == ibus.ATTR_TYPE_UNDERLINE:
+                               pango_attr = pango.AttrUnderline (attr._value,
                                                                                attr._start_index, attr._end_index)
                        if pango_attr != None:
                                self.insert (pango_attr)
index 17a0d54..f443f3e 100644 (file)
@@ -50,7 +50,7 @@ class IEngine (dbus.service.Object):
        @signal (signature="ubu")
        def ForwardKeyEvent (self, keyval, is_press, state): pass
 
-       @signal (signature="svu")
+       @signal (signature="saaii")
        def PreeditChanged (self, text, attrs, cursor_pos): pass
 
        # below signals are optional. The engine could create and maintain panel by self.
index bb3fbbb..91b9da4 100644 (file)
@@ -18,6 +18,9 @@ class IPanel (dbus.service.Object):
                dbus.service.method (dbus_interface = IBUS_PANE_IFACE, \
                                                         async_callbacks = ("reply_cb", "error_cb"), \
                                                         **args)
+       @method (in_signature="iiii")
+       def SetCursorLocation (self, x, y, w, h): pass
+
        @method (in_signature="svu")
        def SetPreeditString (self, text, attrs, cursor_pos): pass
 
index c404b60..470e603 100644 (file)
@@ -103,6 +103,7 @@ class IBus (ibus.Object):
        def set_cursor_location (self, x, y, w, h, dbusconn):
                client = self._lookup_client (dbusconn)
                client.set_cursor_location (x, y, w, h)
+               self._panel.set_cursor_location (x, y, w, h)
 
        def _filter_hotkeys (self, client, keyval, is_press, state):
                if is_press and keyval == keysyms.space \
@@ -131,22 +132,22 @@ class IBus (ibus.Object):
        def _aux_string_changed_cb (self, client, text, attrs):
                assert self._focused_client == client
 
-               self._pabel.set_aux_string (text, attrs)
+               self._panel.set_aux_string (text, attrs)
 
        def _update_lookup_table_cb (self, client, lookup_table):
                assert self._focused_client == client
 
-               self._pabel.update_lookup_table (lookup_table)
+               self._panel.update_lookup_table (lookup_table)
 
        def _show_lookup_table_cb (self, client, lookup_table):
                assert self._focused_client == client
 
-               self._pabel.show_candidate_window ()
+               self._panel.show_candidate_window ()
 
        def _hide_lookup_table_cb (self, client, lookup_table):
                assert self._focused_client == client
 
-               self._pabel.hide_candidate_window ()
+               self._panel.hide_candidate_window ()
 
        ##########################################################
        # methods for im engines
index 297957a..908be9c 100644 (file)
@@ -6,7 +6,7 @@ class Client (ibus.Object):
                "preedit-changed" : (
                        gobject.SIGNAL_RUN_FIRST,
                        gobject.TYPE_NONE,
-                       (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_UINT)),
+                       (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_INT)),
                "aux-string-changed" : (
                        gobject.SIGNAL_RUN_FIRST,
                        gobject.TYPE_NONE,
@@ -134,7 +134,7 @@ class Client (ibus.Object):
                self.commit_string (text)
 
        def _preedit_changed_cb (self, engine, text, attrs, cursor_pos):
-               self.preedit_changed (self, text, attrs, cursor_pos)
+               self.preedit_changed (text, attrs, cursor_pos)
 
        def _aux_string_changed_cb (self, engine, text, attrs):
                self._aux_string = text
index 13a1bc1..b12b28c 100644 (file)
@@ -15,7 +15,7 @@ class Engine (ibus.Object):
                "preedit-changed" : (
                        gobject.SIGNAL_RUN_FIRST,
                        gobject.TYPE_NONE,
-                       (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_UINT)),
+                       (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_INT)),
                "aux-string-changed" : (
                        gobject.SIGNAL_RUN_FIRST,
                        gobject.TYPE_NONE,
@@ -56,22 +56,21 @@ class Engine (ibus.Object):
                        self.emit ("forward-key-event", args[0], bool (arg[1]), arg[2])
                        return True
                elif message.is_signal (ibus.IBUS_ENGINE_IFACE, "PreeditChanged"):
+                       args = message.get_args_list ()
                        self.emit ("preedit-changed", args[0], args[1], args[2])
                        return True
                elif message.is_signal (ibus.IBUS_ENGINE_IFACE, "AuxStringChanged"):
+                       args = message.get_args_list ()
                        self.emit ("aux-string-changed", args[0], args[1])
                        return True
                elif message.is_signal (ibus.IBUS_ENGINE_IFACE, "UpdateLookupTable"):
                        args = message.get_args_list ()
-                       lookup_table = ibus.lookup_table_from_dbus_value (args[0])
-                       self.emit ("update-lookup-table", lookup_table)
+                       self.emit ("update-lookup-table", args[0])
                        return True
                elif message.is_signal (ibus.IBUS_ENGINE_IFACE, "ShowLookupTable"):
-                       args = message.get_args_list ()
                        self.emit ("show-lookup-table")
                        return True
                elif message.is_signal (ibus.IBUS_ENGINE_IFACE, "HideLookupTable"):
-                       args = message.get_args_list ()
                        self.emit ("hide-lookup-table")
                        return True
                else:
@@ -90,7 +89,7 @@ class Engine (ibus.Object):
                self._engine.ProcessKeyEvent (keyval, is_press, state, 
                                                                        reply_handler = reply_cb,
                                                                        error_handler = error_cb)
-       
+
        def set_cursor_location (self, x, y, w, h):
                self._engine.SetCursorLocation (x, y, w, h)
 
index 83b85e2..8c41f7f 100644 (file)
@@ -13,6 +13,9 @@ class Panel (ibus.Object):
                self._ibusconn.connect ("destroy", self._ibusconn_destroy_cb)
                self._ibusconn.connect ("dbus-signal", self._dbus_signal_cb)
 
+       def set_cursor_location (self, x, y, w, h):
+               self._panel.SetCursorLocation (x, y, w, h)
+
        def set_preedit_string (self, text, attrs, cursor_pos):
                self._panel.SetPreeditString (text, attrs, cursor_pos)
 
index 34018e2..03c50ce 100644 (file)
@@ -1,5 +1,7 @@
 PYTHON = env PYTHONPATH=../ python
 
+all: test-panel
+
 test-candidatewindow:
        $(PYTHON) ./candidatewindow.py
 
index 55b159e..c66c455 100644 (file)
@@ -3,6 +3,7 @@ import gtk
 import gtk.gdk as gdk
 import gobject
 import pango
+from ibus.gtk import PangoAttrList
 
 class HSeparator (gtk.HBox):
        def __init__ (self):
@@ -196,6 +197,7 @@ class CandidatePanel (gtk.VBox):
                self._preedit_label.hide ()
 
        def set_aux_string (self, text, attrs):
+               attrs = PangoAttrList (attrs)
                self._aux_string = text
                self._aux_label.set_text (text)
                if attrs == None:
@@ -203,7 +205,8 @@ class CandidatePanel (gtk.VBox):
                self._aux_attrs = attrs
                self._aux_label.set_attributes (attrs)
 
-       def set_preedit_string (self, text, attrs):
+       def set_preedit_string (self, text, attrs, cursor_pos):
+               attrs = PangoAttrList (attrs)
                self._preedit_string = text
                self._preedit_label.set_text (text)
                if attrs == None:
@@ -214,6 +217,8 @@ class CandidatePanel (gtk.VBox):
        def set_lookup_table (self, lookup_table):
                self._lookup_table = lookup_table
                candidates = self._lookup_table.get_canidates_in_current_page ()
+               candidates = map (lambda x: (x[0], PangoAttrList (x[1])), candidates)
+               self._candidate_area.set_candidates (candidates)
 
        def set_orientation (self, orientation):
                if self._orientation == orientation:
index 6642406..f54f81c 100644 (file)
@@ -17,9 +17,10 @@ class CandidateWindow (gtk.Window):
                self._candidate_panel.connect ("size-request", self._size_request_cb)
                self.add (self._candidate_panel)
                self.move (100, 100)
+               self.show_all ()
 
-       def set_preedit_string (self, text, attrs):
-               self._candidate_panel.set_preedit_string (text, attrs)
+       def set_preedit_string (self, text, attrs, cursor_pos):
+               self._candidate_panel.set_preedit_string (text, attrs, cursor_pos)
 
        def show_preedit_string (self, text, attrs):
                self._candidate_panel.show_preedit_string ()
@@ -31,7 +32,7 @@ class CandidateWindow (gtk.Window):
                self._candidate_panel.set_aux_string (text, attrs)
 
        def set_lookup_table (self, lookup_table):
-               self._candidate_pabel.set_lookup_table (lookup_table)
+               self._candidate_panel.set_lookup_table (lookup_table)
 
        def _size_request_cb (self, widget, size):
                self.resize (1, 1)
index 7a70965..6913215 100644 (file)
@@ -26,7 +26,7 @@ class PanelApplication:
 
 def main ():
        # gtk.settings_get_default ().props.gtk_theme_name = "/home/phuang/.themes/aud-Default/gtk-2.0/gtkrc"
-       gtk.rc_parse ("./themes/default/gtkrc")
+       gtk.rc_parse ("./themes/default/gtkrc")
        PanelApplication ().run ()
 
 if __name__ == "__main__":
index 1c4a67c..b0b4251 100644 (file)
@@ -2,80 +2,98 @@
 import gtk
 import gtk.gdk as gdk
 import gobject
+import ibus
 from ibus import interface
-from image import Image
-from handle import Handle
-
-class PanelBar (gtk.Toolbar):
-       def __init__ (self):
-               gtk.Toolbar.__init__ (self)
-               self.set_property ("icon-size", gtk.ICON_SIZE_MENU)
-               # self.set_orientation (gtk.ORIENTATION_VERTICAL)
-               self._create_items ()
+from languagebar import LanguageBarWindow
+from candidatewindow import CandidateWindow
+
+class Panel (gobject.GObject):
+       def __init__ (self, proxy):
+               gobject.GObject.__init__ (self)
+               self._proxy = proxy
+               self._language_bar = LanguageBarWindow ()
+               self._candidate_panel = CandidateWindow ()
+
+       def set_cursor_location (self, x, y, w, h):
+               self._candidate_panel.move (x + w, y + h)
        
-       def insert (self, toolitem, pos):
-               gtk.Toolbar.insert (self, toolitem, pos)
-               self.check_resize ()
-
-       def _add_items (self):
-               btn = gtk.ToolButton (gtk.STOCK_NEW)
-               btn.connect ("clicked", lambda x: self._add_items ())
-               self.insert (btn, -1)
-               self.insert (gtk.ToolButton (gtk.STOCK_APPLY), -1)
-               self.insert (gtk.SeparatorToolItem (), -1)
-               self.show_all ()
-               
-       def _create_items (self):
-               handle = Handle ()
-               item = gtk.ToolItem ()
-               item.add (handle)
-               self.insert (item, -1)
-
-               self._add_items ()
-               
-       def do_realize (self):
-               gtk.Toolbar.do_realize (self)
-               self.check_resize ()
+       def set_preedit_string (self, text, attrs, cursor_pos):
+               self._candidate_panel.set_preedit_string (text, attrs, cursor_pos)
+
+       def show_preedit_string (self):
+               self._candidate_panel.show_preedit_string ()
+
+       def hide_preedit_string (self):
+               self._candidate_panel.hide_preedit_string ()
+
+       def set_aux_string (self, text, attrs):
+               self._candidate_panel.set_aux_string (text, attrs)
+
+       def show_aux_string (self):
+               self._candidate_panel.show_aux_string ()
+
+       def hide_aux_string (self):
+               self._candidate_panel.hide_aux_string ()
        
-       def do_check_resize (self):
-               width = 0
-               for item in self:
-                       w, h = item.size_request ()
-                       width += w
-               self.set_size_request (width + 2, -1)
-               
-gobject.type_register (PanelBar, "IBusToolbar")
-
-class PanelWindow (gtk.Window):
-       def __init__ (self):
-               gtk.Window.__init__ (self, gtk.WINDOW_POPUP)
-               self._panel_bar = PanelBar ()
-               self._panel_bar.connect ("size-request", self._size_request_cb)
-               self.add (self._panel_bar)
-               self.show_all ()
-
-       def _size_request_cb (self, widget, size):
-               self.resize (size.width, size.height)
-
-       def do_size_allocate (self, allocation):
-               gtk.Window.do_size_allocate (self, allocation)
-               root = gdk.get_default_root_window ()
-               workarea = root.property_get ("_NET_WORKAREA")[2]
-               x, y = workarea[2] - allocation.width - 40, workarea[1] + workarea[3] - allocation.height
-               self.move (x, y)
-               
-       def do_destroy (self):
-               gtk.main_quit ()
-               gtk.Window.do_destroy (self)
-
-gobject.type_register (PanelWindow, "IBusPanelWindow")
+       def update_lookup_table (self, lookup_table):
+               self._candidate_panel.set_lookup_table (lookup_table)
+
+       def show_candidate_window (self):
+               self._candidate_panel.show ()
+
+       def hide_candidate_window (self):
+               self._candidate_panel.hide ()
+
+       def show_language_bar (self):
+               selk._language_bar.show ()
+
+       def hide_language_bar (self):
+               selk._language_bar.hide ()
 
 class PanelProxy (interface.IPanel):
        def __init__ (self, dbusconn, object_path):
                interface.IPanel.__init__ (self, dbusconn, object_path)
                self._dbusconn = dbusconn
-               self._panel = PanelWindow ()
+               self._panel = Panel (self)
+
+       def SetCursorLocation (self, x, y, w, h):
+               self._panel.set_cursor_location (x, y, w, h)
+       
+       def SetPreeditString (self, text, attrs, cursor_pos):
+               attrs = ibus.attr_list_from_dbus_value (attrs)
+               self._panel.set_preedit_string (text, atrrs, cursor_pos)
+
+       def ShowPreeditString (self):
+               self._panel.show_preedit_string ()
+
+       def HidePreeditString (self):
+               self._panel.hide_preedit_string ()
+
+       def SetAuxString (self, text, attrs):
+               attrs = ibus.attr_list_from_dbus_value (attrs)
+               self._panel.set_aux_string (text, attrs)
+
+       def ShowAuxString (self):
+               self._panel.show_aux_string ()
+
+       def HideAuxString (self):
+               self._panel.hide_aux_string ()
+
+       def UpdateLookupTable (self, lookup_table):
+               self._panel.update_lookup_table ()
+
+       def ShowCandidateWindow (self):
+               self._panel.show_candidate_window ()
+
+       def HideCandidateWindow (self):
+               self._panel.hide_candidate_window ()
+
+       def ShowLanguageBar (self):
+               self._panel.show_language_bar ()
+
+       def HideLanguageBar (self):
+               self._panel.hide_language_bar ()
 
        def Destroy (self):
-               self._panel.destroy ()
+               self._pabel.destroy ()