Add a template engine - enchant.
authorHuang Peng <shawn.p.huang@gmail.com>
Sun, 29 Jun 2008 08:10:36 +0000 (16:10 +0800)
committerHuang Peng <shawn.p.huang@gmail.com>
Sun, 29 Jun 2008 08:10:36 +0000 (16:10 +0800)
Makefile.am
configure.ac
engine/Makefile.am [new file with mode: 0644]
engine/engine.py [new file with mode: 0644]
engine/factory.py [new file with mode: 0644]
engine/ibus-engine-enchant.in [new file with mode: 0644]
engine/main.py [new file with mode: 0644]
ibus-tmpl.spec.in

index 670d3f7..bfee6a2 100644 (file)
@@ -19,6 +19,7 @@
 # Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 # Boston, MA  02111-1307  USA
 SUBDIRS = \
+       engine \
        m4 \
        po \
        $(NULL)
index 970ce27..357a974 100644 (file)
@@ -50,6 +50,9 @@ AC_ISC_POSIX
 AC_HEADER_STDC
 AM_PROG_LIBTOOL
 
+#check python
+AM_PATH_PYTHON([2.5])
+
 # define GETTEXT_* variables
 GETTEXT_PACKAGE=ibus-tmpl
 AC_SUBST(GETTEXT_PACKAGE)
@@ -63,6 +66,8 @@ AM_GNU_GETTEXT_VERSION(0.16.1)
 AC_CONFIG_FILES([ po/Makefile.in
 Makefile
 ibus-tmpl.spec
+engine/Makefile
+engine/ibus-engine-enchant
 m4/Makefile
 ])
 
diff --git a/engine/Makefile.am b/engine/Makefile.am
new file mode 100644 (file)
index 0000000..83ef4fd
--- /dev/null
@@ -0,0 +1,42 @@
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA  02111-1307  USA
+
+engine_enchant_PYTHON = \
+       engine.py \
+       factory.py \
+       main.py \
+       $(NULL)
+
+engine_enchantdir = $(datadir)/ibus/engine/enchant
+
+libexec_SCRIPTS = ibus-engine-enchant
+
+CLEANFILES = \
+       *.pyc \
+       $(NULL)
+
+EXTRA_DIST = \
+       ibus-engine-enchant.in \
+       $(NULL)
+
+test:
+       $(ENV) PYTHONPATH=$(top_srcdir) $(PYTHON) $(srcdir)/main.py
+
diff --git a/engine/engine.py b/engine/engine.py
new file mode 100644 (file)
index 0000000..700d89a
--- /dev/null
@@ -0,0 +1,191 @@
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA  02111-1307  USA
+
+import gobject
+import gtk
+import pango
+import dbus
+import ibus
+import enchant
+from ibus import keysyms
+from ibus import modifier
+from ibus import interface
+
+class Engine (interface.IEngine):
+       _dict = enchant.Dict ()
+       def __init__ (self, dbusconn, object_path):
+               interface.IEngine.__init__ (self, dbusconn, object_path)
+               self._dbusconn = dbusconn
+               self._is_invalidate = False
+               self._preedit_string = u""
+               self._lookup_table = ibus.LookupTable ()
+               self._prop_list = ibus.PropList ()
+               self._prop_list.append (ibus.Property ("test", icon = "ibus-locale"))
+
+       def _process_key_event (self, keyval, is_press, state):
+               # ignore key release events
+               if not is_press:
+                       return False
+
+               if self._preedit_string:
+                       if keyval == keysyms.Return:
+                               self._commit_string (self._preedit_string)
+                               return True
+                       elif keyval == keysyms.Escape:
+                               self._preedit_string = u""
+                               self._update ()
+                               return True
+                       elif keyval == keysyms.BackSpace:
+                               self._preedit_string = self._preedit_string[:-1]
+                               self._invalidate ()
+                               return True
+                       elif keyval == keysyms.space:
+                               if self._lookup_table.get_number_of_candidates () > 0:
+                                       self._commit_string (self._lookup_table.get_current_candidate ()[0])
+                               else:
+                                       self._commit_string (self._preedit_string)
+                               return False
+                       elif keyval >= keysyms._1 and keyval <= keysyms._9:
+                               index = keyval - keysyms._1
+                               candidates = self._lookup_table.get_canidates_in_current_page ()
+                               if index >= len (candidates):
+                                       return False
+                               candidate = candidates[index][0]
+                               self._commit_string (candidate)
+                               return True
+                       elif keyval == keysyms.Page_Up or keyval == keysyms.KP_Page_Up:
+                               if self._lookup_table.page_up ():
+                                       self._update_lookup_table ()
+                               return True
+                       elif keyval == keysyms.Up:
+                               self._cursor_up ()
+                               return True
+                       elif keyval == keysyms.Down:
+                               self._cursor_down ()
+                               return True
+                       elif keyval == keysyms.Left or keyval == keysyms.Right:
+                               return True
+                       elif keyval == keysyms.Page_Down or keyval == keysyms.KP_Page_Down:
+                               if self._lookup_table.page_down ():
+                                       self._update_lookup_table ()
+                               return True
+               if keyval in xrange (keysyms.a, keysyms.z + 1) or \
+                       keyval in xrange (keysyms.A, keysyms.Z + 1):
+                       if state & (modifier.CONTROL_MASK | modifier.ALT_MASK) == 0:
+                               self._preedit_string += unichr (keyval)
+                               self._invalidate ()
+                               return True
+               else:
+                       if keyval < 128 and self._preedit_string:
+                               self._commit_string (self._preedit_string)
+
+               return False
+
+       def _invalidate (self):
+               if self._is_invalidate:
+                       return
+               self._is_invalidate = True
+               gobject.idle_add (self._update, priority = gobject.PRIORITY_LOW)
+
+       def _cursor_up (self):
+               if self._lookup_table.cursor_up ():
+                       self._update_lookup_table ()
+                       return True
+               return False
+
+       def _cursor_down (self):
+               if self._lookup_table.cursor_down ():
+                       self._update_lookup_table ()
+                       return True
+               return False
+
+       def _commit_string (self, text):
+               self.CommitString (text)
+               self._preedit_string = u""
+               self._update ()
+
+       def _update (self):
+               preedit_len = len (self._preedit_string)
+               attrs = ibus.AttrList ()
+               self._lookup_table.clean ()
+               if preedit_len > 0:
+                       if not self._dict.check (self._preedit_string):
+                               attrs.append (ibus.AttributeForeground (0xff0000, 0, preedit_len))
+                               for text in self._dict.suggest (self._preedit_string):
+                                       self._lookup_table.append_candidate (text)
+               self.UpdateAuxString (self._preedit_string, attrs.to_dbus_value (), preedit_len > 0)
+               attrs.append (ibus.AttributeUnderline (pango.UNDERLINE_SINGLE, 0, preedit_len))
+               self.UpdatePreedit (self._preedit_string, attrs.to_dbus_value (), dbus.Int32 (preedit_len), preedit_len > 0)
+               self._update_lookup_table ()
+               self._is_invalidate = False
+
+       def _update_lookup_table (self):
+               show = self._lookup_table.get_number_of_candidates () > 0
+               self.UpdateLookupTable (self._lookup_table.to_dbus_value (), show)
+
+
+       # methods for dbus rpc
+       def ProcessKeyEvent (self, keyval, is_press, state):
+               try:
+                       return self._process_key_event (keyval, is_press, state)
+               except Exception, e:
+                       print e
+               return False
+
+       def FocusIn (self):
+               self.RegisterProperties (self._prop_list.to_dbus_value ())
+               print "FocusIn"
+
+       def FocusOut (self):
+               print "FocusOut"
+
+       def SetCursorLocation (self, x, y, w, h):
+               pass
+
+       def Reset (self):
+               print "Reset"
+
+       def PageUp (self):
+               print "PageUp"
+
+       def PageDown (self):
+               print "PageDown"
+
+       def CursorUp (self):
+               self._cursor_up ()
+
+       def CursorDown (self):
+               self._cursor_down ()
+
+       def SetEnable (self, enable):
+               self._enable = enable
+               if self._enable:
+                       self.RegisterProperties (self._prop_list.to_dbus_value ())
+
+       def PropertyActivate (self, prop_name):
+               print "PropertyActivate (%s)" % prop_name
+
+       def Destroy (self):
+               print "Destroy"
+
+class DemoEngine (Engine):
+       pass
+
diff --git a/engine/factory.py b/engine/factory.py
new file mode 100644 (file)
index 0000000..ddca013
--- /dev/null
@@ -0,0 +1,54 @@
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA  02111-1307  USA
+
+from ibus import interface
+import engine
+
+FACTORY_PATH = "/com/redhat/IBus/engines/Demo/Factory"
+ENGINE_PATH = "/com/redhat/IBus/engines/Demo/Engine/%d"
+
+class DemoEngineFactory (interface.IEngineFactory):
+       NAME = "Enchant"
+       LANG = "en"
+       ICON = ""
+       AUTHORS = "Huang Peng <shawn.p.huang@gmail.com>"
+       CREDITS = "GPLv2"
+
+       def __init__ (self, dbusconn):
+               interface.IEngineFactory.__init__ (self, dbusconn, object_path = FACTORY_PATH)
+               self._dbusconn = dbusconn
+               self._max_engine_id = 1
+       
+       def GetInfo (self):
+               return [
+                       self.NAME,
+                       self.LANG,
+                       self.ICON,
+                       self.AUTHORS,
+                       self.CREDITS
+                       ]
+
+       def CreateEngine (self):
+               engine_path = ENGINE_PATH % self._max_engine_id
+               self._max_engine_id += 1
+               return engine.DemoEngine (self._dbusconn, engine_path)
+
+
diff --git a/engine/ibus-engine-enchant.in b/engine/ibus-engine-enchant.in
new file mode 100644 (file)
index 0000000..251160e
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA  02111-1307  USA
+
+python @prefix@/share/ibus/engine/enchant/main.py $@
+
diff --git a/engine/main.py b/engine/main.py
new file mode 100644 (file)
index 0000000..be84968
--- /dev/null
@@ -0,0 +1,84 @@
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA  02111-1307  USA
+
+import os
+import sys
+import getopt
+import dbus
+import dbus.connection
+import dbus.mainloop.glib
+import ibus
+import factory
+import gtk
+
+class IMApp:
+       def __init__ (self):
+               self._dbusconn = dbus.connection.Connection (ibus.IBUS_ADDR)
+               self._dbusconn.add_signal_receiver (self._disconnected_cb, 
+                                                       "Disconnected", 
+                                                       dbus_interface = dbus.LOCAL_IFACE)
+               self._engine = factory.DemoEngineFactory (self._dbusconn)
+               self._ibus = self._dbusconn.get_object (ibus.IBUS_NAME, ibus.IBUS_PATH)
+               self._ibus.RegisterFactories ([factory.FACTORY_PATH], **ibus.DEFAULT_ASYNC_HANDLERS)
+
+       def run (self):
+               gtk.main ()
+
+       def _disconnected_cb (self):
+               print "disconnected"
+               gtk.main_quit ()
+
+
+def launch_engine ():
+       dbus.mainloop.glib.DBusGMainLoop (set_as_default=True)
+       IMApp ().run ()
+
+def print_help (out, v = 0):
+       print >> out, "-h, --help             show this message."
+       print >> out, "-d, --daemonize        daemonize ibus"
+       sys.exit (v)
+
+def main ():
+       daemonize = False
+       shortopt = "hd"
+       longopt = ["help", "daemonize"]
+       try:
+               opts, args = getopt.getopt (sys.argv[1:], shortopt, longopt)
+       except getopt.GetoptError, err:
+               print_help (sys.stderr, 1)
+
+       for o, a in opts:
+               if o in ("-h", "--help"):
+                       print_help (sys.stdout)
+               elif o in ("-d", "--daemonize"):
+                       daemonize = True
+               else:
+                       print >> sys.stderr, "Unknown argument: %s" % o
+                       print_help (sys.stderr, 1)
+
+       if daemonize:
+               if os.fork ():
+                       sys.exit ()
+
+       launch_engine ()
+
+if __name__ == "__main__":
+       main ()
index 846b617..3786489 100644 (file)
@@ -40,17 +40,10 @@ rm -rf $RPM_BUILD_ROOT
 %doc AUTHORS COPYING README
 # %dir %{python_sitearch}/ibus
 # %{python_sitearch}/ibus/*
-# %dir %{_datadir}/ibus/
-# %dir %{_datadir}/ibus/daemon/
-# %dir %{_datadir}/ibus/panel/
-# %dir %{_datadir}/ibus/engine/
-# %dir %{_datadir}/ibus/icons/
-# %{_datadir}/ibus/daemon/*
-# %{_datadir}/ibus/panel/*
-# %{_datadir}/ibus/engine/*
+%dir %{_datadir}/ibus/engine/enchant
+%{_datadir}/ibus/engine/enchant/*
+%{_libexecdir}/ibus-engine-enchant
 # %{_datadir}/ibus/icons/*
-# %{_libexecdir}/ibus-daemon
-# %{_libexecdir}/ibus-panel
 
 %changelog
 * Wed Jun 25 2008 Huang Peng <shawn.p.huang@gmail.com> - 0.1.0-1