From: Huang Peng Date: Sun, 29 Jun 2008 08:10:36 +0000 (+0800) Subject: Add a template engine - enchant. X-Git-Tag: 0.1.0.20080810~35 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1e9f9787283d449fe7446a9fa19924c964980180;p=platform%2Fupstream%2Fibus-hangul.git Add a template engine - enchant. --- diff --git a/Makefile.am b/Makefile.am index 670d3f7..bfee6a2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,6 +19,7 @@ # Free Software Foundation, Inc., 59 Temple Place, Suite 330, # Boston, MA 02111-1307 USA SUBDIRS = \ + engine \ m4 \ po \ $(NULL) diff --git a/configure.ac b/configure.ac index 970ce27..357a974 100644 --- a/configure.ac +++ b/configure.ac @@ -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 index 0000000..83ef4fd --- /dev/null +++ b/engine/Makefile.am @@ -0,0 +1,42 @@ +# vim:set noet ts=4: +# +# ibus - The Input Bus +# +# Copyright (c) 2007-2008 Huang Peng +# +# 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 index 0000000..700d89a --- /dev/null +++ b/engine/engine.py @@ -0,0 +1,191 @@ +# vim:set noet ts=4: +# +# ibus - The Input Bus +# +# Copyright (c) 2007-2008 Huang Peng +# +# 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 index 0000000..ddca013 --- /dev/null +++ b/engine/factory.py @@ -0,0 +1,54 @@ +# vim:set noet ts=4: +# +# ibus - The Input Bus +# +# Copyright (c) 2007-2008 Huang Peng +# +# 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 " + 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 index 0000000..251160e --- /dev/null +++ b/engine/ibus-engine-enchant.in @@ -0,0 +1,23 @@ +#!/bin/sh +# +# ibus - The Input Bus +# +# Copyright (c) 2007-2008 Huang Peng +# +# 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 index 0000000..be84968 --- /dev/null +++ b/engine/main.py @@ -0,0 +1,84 @@ +# vim:set noet ts=4: +# +# ibus - The Input Bus +# +# Copyright (c) 2007-2008 Huang Peng +# +# 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 () diff --git a/ibus-tmpl.spec.in b/ibus-tmpl.spec.in index 846b617..3786489 100644 --- a/ibus-tmpl.spec.in +++ b/ibus-tmpl.spec.in @@ -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 - 0.1.0-1