Import ibus-anthy projiect.
authorHuang Peng <shawn.p.huang@gmail.com>
Sun, 29 Jun 2008 23:57:04 +0000 (07:57 +0800)
committerHuang Peng <shawn.p.huang@gmail.com>
Sun, 29 Jun 2008 23:57:04 +0000 (07:57 +0800)
16 files changed:
.gitignore
Makefile.am
configure.ac
engine/Makefile.am
engine/anthy.i [new file with mode: 0644]
engine/engine.py
engine/factory.py
engine/ibus-engine-anthy.in [new file with mode: 0644]
engine/ibus-engine-enchant.in [deleted file]
engine/main.py
engine/tables.py [new file with mode: 0644]
engine/test.py [new file with mode: 0644]
ibus-anthy.spec.in [moved from ibus-tmpl.spec.in with 76% similarity]
icons/Makefile.am
icons/ibus-anthy.png [new file with mode: 0644]
icons/ibus-enchant.svg [deleted file]

index da3b6ba..c10eb8b 100644 (file)
@@ -32,5 +32,5 @@ ltmain.sh
 missing
 stamp-h1
 py-compile
-ibus-tmpl*.tar.*
-ibus-tmpl.spec
+ibus-anthy*.tar.*
+ibus-anthy.spec
index 647e6a2..1b0538a 100644 (file)
@@ -1,6 +1,6 @@
 # vim:set noet ts=4:
 #
-# ibus-tmpl - The Input Bus template project
+# ibus-anthy - The Anthy engine for IBus
 #
 # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 #
@@ -29,7 +29,7 @@ ACLOCAL_AMFLAGS = -I m4
 
 EXTRA_DIST = \
        autogen.sh \
-       ibus-tmpl.spec.in \
+       ibus-anthy.spec.in \
        $(NULL)
 
 noinst_DIST = \
@@ -40,7 +40,7 @@ DISTCLEANFILES = \
        po/stamp-it \
        $(NULL)
 
-rpm: dist ibus-tmpl.spec
+rpm: dist ibus-anthy.spec
        rpmbuild -bb                                            \
                        --define "_sourcedir `pwd`" \
                        --define "_builddir `pwd`"      \
index 177c005..a5419fe 100644 (file)
@@ -1,6 +1,6 @@
 # vim:set noet ts=4:
 #
-# ibus-tmpl - The Input Bus template project
+# ibus-anthy - The Anthy engine for IBus
 #
 # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 #
@@ -29,7 +29,7 @@ m4_define(ibus_maybe_datestamp,
 m4_define([ibus_version],
        ibus_major_version.ibus_minor_version.ibus_micro_version[]ibus_maybe_datestamp)
 
-AC_INIT([ibus-tmpl], [ibus_version], [http://code.google.com/p/ibus/issues/entry],[ibus-tmpl])
+AC_INIT([ibus-anthy], [ibus_version], [http://code.google.com/p/ibus/issues/entry],[ibus-anthy])
 AM_INIT_AUTOMAKE([1.10])
 AC_GNU_SOURCE
 
@@ -49,11 +49,38 @@ AC_ISC_POSIX
 AC_HEADER_STDC
 AM_PROG_LIBTOOL
 
-#check python
+# check anthy
+PKG_CHECK_MODULES(ANTHY, [
+       anthy
+])
+
+
+# check swig
+AC_PATH_PROG(SWIG, swig)
+if test x"$SWIG" == x""; then
+        AC_MSG_ERROR([can not find swig])
+fi
+AC_SUBST(SWIG)
+
+# check env
+AC_PATH_PROG(ENV, env)
+AC_SUBST(ENV)
+
+# check python
 AM_PATH_PYTHON([2.5])
+PYTHON_CONFIG=`type -p python$PYTHON_VERSION-config`
+if test "$PYTHON_CONFIG" != ""; then
+    PYTHON_CFLAGS=`$PYTHON_CONFIG --includes`
+    PYTHON_LIBS=`$PYTHON_CONFIG --libs`
+else
+    PYTHON_CFLAGS=`$PYTHON $srcdir/python-config.py --includes`
+    PYTHON_LIBS=`$PYTHON $srcdir/python-config.py --libs`
+fi
+AC_SUBST(PYTHON_CFLAGS)
+AC_SUBST(PYTHON_LIBS)
 
 # define GETTEXT_* variables
-GETTEXT_PACKAGE=ibus-tmpl
+GETTEXT_PACKAGE=ibus-anthy
 AC_SUBST(GETTEXT_PACKAGE)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the read-only architecture-independent data directory.])
 
@@ -64,9 +91,9 @@ AM_GNU_GETTEXT_VERSION(0.16.1)
 # OUTPUT files
 AC_CONFIG_FILES([ po/Makefile.in
 Makefile
-ibus-tmpl.spec
+ibus-anthy.spec
 engine/Makefile
-engine/ibus-engine-enchant
+engine/ibus-engine-anthy
 icons/Makefile
 m4/Makefile
 ])
index 8b58e86..67c4a5a 100644 (file)
@@ -1,6 +1,6 @@
 # vim:set noet ts=4:
 #
-# ibus-tmpl - The Input Bus template project
+# ibus-anthy - The Anthy engine for IBus
 #
 # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 #
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-engine_enchant_PYTHON = \
+engine_anthy_PYTHON = \
        engine.py \
        factory.py \
        main.py \
+       tables.py \
+       test.py \
        $(NULL)
 
-engine_enchantdir = $(datadir)/ibus/engine/enchant
+engine_anthydir = $(datadir)/ibus/engine/anthy
 
-libexec_SCRIPTS = ibus-engine-enchant
+anthy_DATA = \
+       anthy.py \
+       $(NULL)
 
-CLEANFILES = \
-       *.pyc \
+anthy_LTLIBRARIES = _anthy.la
+
+anthydir = @pyexecdir@
+
+_anthy_la_SOURCES = \
        $(NULL)
 
-EXTRA_DIST = \
-       ibus-engine-enchant.in \
+nodist__anthy_la_SOURCES = \
+       anthy_wrap.c \
+       $(NULL)
+
+_anthy_la_CFLAGS = \
+       @ANTHY_CFLAGS@ \
+       @PYTHON_CFLAGS@ \
+       $(NULL)
+
+_anthy_la_LDFLAGS = \
+       @ANTHY_LIBS@ \
+       -rpath $(anthydir) \
+       -avoid-version \
+       -module \
        $(NULL)
 
+libexec_SCRIPTS = ibus-engine-anthy
+
+anthy.py anthy_wrap.c: anthy.i
+       $(SWIG) -python -I/usr/include -o anthy_wrap.c $(srcdir)/anthy.i
+
 test:
-       $(ENV) PYTHONPATH=$(top_srcdir) $(PYTHON) $(srcdir)/main.py
+       $(ENV) PYTHONPATH=$(builddir)/.libs $(PYTHON) $(srcdir)/main.py
+
+EXTRA_DIST = \
+       anthy.i \
+       ibus-engine-anthy.in \
+       $(NULL)
+
+CLEANFILES = \
+       anthy.py \
+       anthy_wrap.* \
+       *.pyc \
+       $(MULL)
 
+DISTCLEANFILES = \
+       $(MULL)
diff --git a/engine/anthy.i b/engine/anthy.i
new file mode 100644 (file)
index 0000000..c48481c
--- /dev/null
@@ -0,0 +1,115 @@
+/* vim:set et ts=4: */
+/*
+ * ibus-anthy - The Anthy engine for IBus
+ *
+ * Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+%module anthy
+%{
+ /* Put header files here or function declarations like below */
+#include <anthy/anthy.h>
+%}
+
+%init %{
+    anthy_init ();
+%}
+
+/* anthy_context_t */
+%include anthy/anthy.h
+struct anthy_context {};
+%extend anthy_context {
+    anthy_context () {
+        return anthy_create_context ();
+    }
+
+    void reset () {
+        anthy_reset_context (self);
+    }
+
+    int set_string (char *str) {
+        return anthy_set_string (self, str);
+    }
+
+    void resize_segment (int a1, int a2) {
+        anthy_resize_segment (self, a1, a2);
+    }
+
+    int get_stat (struct anthy_conv_stat *a1) {
+        return anthy_get_stat (self, a1);
+    }
+
+    int get_segment_stat (int a1, struct anthy_segment_stat *a2) {
+        return anthy_get_segment_stat (self, a1, a2);
+    }
+
+    char *get_segment (int a1, int a2) {
+        int len;
+        static char temp[512];
+
+        len = anthy_get_segment (self, a1, a2, temp, sizeof (temp));
+        if (len >= 0)
+            return temp;
+        else
+            return NULL;
+    }
+
+    int commit_segment (int a1, int a2) {
+        return anthy_commit_segment (self, a1, a2);
+    }
+
+    int set_prediction_string (const char *a1) {
+        return anthy_set_prediction_string (self, a1);
+    }
+
+    int get_prediction_stat (struct anthy_prediction_stat *a1) {
+        return anthy_get_prediction_stat (self, a1);
+    }
+
+    char *get_prediction (int a1) {
+        int len;
+        static char temp[512];
+
+        len = anthy_get_prediction (self, a1, temp, sizeof (temp));
+
+        if (len >= 0)
+            return temp;
+        else
+            return NULL;
+    }
+
+    int commit_prediction (int a1) {
+        return anthy_commit_prediction(self, a1);
+    }
+
+    void _print () {
+        anthy_print_context (self);
+    }
+
+    int _set_encoding (int encoding) {
+        return anthy_context_set_encoding (self, encoding);
+    }
+
+    int set_reconversion_mode (int mode) {
+        return anthy_set_reconversion_mode (self, mode);
+    }
+
+    ~anthy_context () {
+        anthy_release_context (self);
+    }
+};
+
index 7ef6934..df8fc9c 100644 (file)
@@ -1,6 +1,7 @@
 # vim:set noet ts=4:
+# -*- coding: utf-8 -*-
 #
-# ibus-tmpl - The Input Bus template project
+# ibus-anthy - The Anthy engine for IBus
 #
 # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 #
@@ -23,123 +24,460 @@ import gtk
 import pango
 import dbus
 import ibus
-import enchant
+import anthy
+from tables import *
 from ibus import keysyms
-from ibus import modifier
 from ibus import interface
+MODE_HIRAGANA, \
+MODE_KATAKANA, \
+MODE_HALF_WIDTH_KATAKANA, \
+MODE_LATIN, \
+MODE_WIDE_LATIN = range (0, 5)
+
+_ = lambda a: a
 
 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""
+
+               # create anthy context
+               self._context = anthy.anthy_context ()
+               self._context._set_encoding (anthy.ANTHY_UTF8_ENCODING)
+
+               # init state
+               self._input_mode = MODE_HIRAGANA
+               self._prop_dict = {}
+
                self._lookup_table = ibus.LookupTable ()
-               self._prop_list = ibus.PropList ()
-               self._prop_list.append (ibus.Property ("test", icon = "ibus-locale"))
+               self._prop_list = self._init_props ()
 
-       def _process_key_event (self, keyval, is_press, state):
-               # ignore key release events
-               if not is_press:
-                       return False
+               # use reset to init values
+               self._reset ()
 
-               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)
+       def _init_props (self):
+               props = ibus.PropList ()
+
+               # init input mode properties
+               mode_prop = ibus.Property (name = "InputMode",
+                                                       type = ibus.PROP_TYPE_MENU,
+                                                       label = "あ",
+                                                       tooltip = "Switch input mode")
+               self._prop_dict["InputMode"] = mode_prop
+
+               mode_props = ibus.PropList ()
+               mode_props.append (ibus.Property (name = "InputMode.Hiragana",
+                                                                               type = ibus.PROP_TYPE_RADIO,
+                                                                               label = "Hiragana"))
+               mode_props.append (ibus.Property (name = "InputMode.Katakana",
+                                                                               type = ibus.PROP_TYPE_RADIO,
+                                                                               label = "Katakana"))
+               mode_props.append (ibus.Property (name = "InputMode.HalfWidthKatakana",
+                                                                               type = ibus.PROP_TYPE_RADIO,
+                                                                               label = "Half width katakana"))
+               mode_props.append (ibus.Property (name = "InputMode.Latin",
+                                                                               type = ibus.PROP_TYPE_RADIO,
+                                                                               label = "Latin"))
+               mode_props.append (ibus.Property (name = "InputMode.WideLatin",
+                                                                               type = ibus.PROP_TYPE_RADIO,
+                                                                               label = "Wide Latin"))
+
+               mode_props[self._input_mode].set_state (ibus.PROP_STATE_CHECKED)
+
+               for prop in mode_props:
+                       self._prop_dict[prop.get_name ()] = prop
+
+               mode_prop.set_sub_props (mode_props)
+               props.append (mode_prop)
+
+
+               # init test property
+               test_prop = ibus.Property (name = "TestProp",
+                                                       type = ibus.PROP_TYPE_TOGGLE,
+                                                       label = "あ",
+                                                       tooltip = "test property")
+               self._prop_dict["TestProp"] = test_prop
+               props.append (test_prop)
+
+
+               return props
+
+       # reset values of engine
+       def _reset (self):
+               self._input_chars = u""
+               self._convert_chars = u""
+               self._cursor_pos = 0
+               self._need_update = False
+               self._convert_begined = False
+               self._segments = []
+               self._lookup_table.clean ()
+               self._lookup_table_visible = False
+
+       # begine convert
+       def _begin_convert (self):
+               if self._convert_begined:
+                       return
+               self._convert_begined = True
+
+               self._context.set_string (self._input_chars.encode ("utf-8"))
+               conv_stat = anthy.anthy_conv_stat ()
+               self._context.get_stat (conv_stat)
+
+               for i in xrange (0, conv_stat.nr_segment):
+                       buf = self._context.get_segment (i, 0)
+                       text = unicode (buf, "utf-8")
+                       self._segments.append ((0, text))
+
+               self._cursor_pos = 0
+               self._fill_lookup_table ()
+               self._lookup_table_visible = False
+
+       def _fill_lookup_table (self):
+               # get segment stat
+               seg_stat = anthy.anthy_segment_stat ()
+               self._context.get_segment_stat (self._cursor_pos, seg_stat)
+
+               # fill lookup_table
+               self._lookup_table.clean ()
+               for i in xrange (0, seg_stat.nr_candidate):
+                       buf = self._context.get_segment (self._cursor_pos, i)
+                       candidate = unicode (buf, "utf-8")
+                       self._lookup_table.append_candidate (candidate)
 
-               return False
 
        def _invalidate (self):
-               if self._is_invalidate:
+               if self._need_update:
                        return
-               self._is_invalidate = True
+               self._need_update = True
                gobject.idle_add (self._update, priority = gobject.PRIORITY_LOW)
 
+       def _page_up (self):
+               # only process cursor down in convert mode
+               if not self._convert_begined:
+                       return False
+
+               if not self._lookup_table.page_up ():
+                       return False
+
+               candidate = self._lookup_table.get_current_candidate ()[0]
+               index = self._lookup_table.get_cursor_pos ()
+               self._segments[self._cursor_pos] = index, candidate
+               self._invalidate ()
+               return True
+
+       def _page_down (self):
+               # only process cursor down in convert mode
+               if not self._convert_begined:
+                       return False
+
+               if not self._lookup_table.page_down ():
+                       return False
+
+               candidate = self._lookup_table.get_current_candidate ()[0]
+               index = self._lookup_table.get_cursor_pos ()
+               self._segments[self._cursor_pos] = index, candidate
+               self._invalidate ()
+               return True
+
        def _cursor_up (self):
-               if self._lookup_table.cursor_up ():
-                       self._update_lookup_table ()
-                       return True
-               return False
+               # only process cursor down in convert mode
+               if not self._convert_begined:
+                       return False
+
+               if not self._lookup_table.cursor_up ():
+                       return False
+
+               candidate = self._lookup_table.get_current_candidate ()[0]
+               index = self._lookup_table.get_cursor_pos ()
+               self._segments[self._cursor_pos] = index, candidate
+               self._invalidate ()
+               return True
 
        def _cursor_down (self):
-               if self._lookup_table.cursor_down ():
-                       self._update_lookup_table ()
-                       return True
-               return False
+               # only process cursor down in convert mode
+               if not self._convert_begined:
+                       return False
+
+               if not self._lookup_table.cursor_down ():
+                       return False
+
+               candidate = self._lookup_table.get_current_candidate ()[0]
+               index = self._lookup_table.get_cursor_pos ()
+               self._segments[self._cursor_pos] = index, candidate
+               self._invalidate ()
+               return True
 
        def _commit_string (self, text):
+               self._reset ()
                self.CommitString (text)
-               self._preedit_string = u""
-               self._update ()
+               self._invalidate ()
+
+       def _update_input_chars (self):
+               begin, end  = max (self._cursor_pos - 4, 0), self._cursor_pos
+
+               for i in range (begin, end):
+                       text = self._input_chars[i:end]
+                       romja = romaji_typing_rule.get (text, None)
+                       if romja != None:
+                               self._input_chars = u"".join ((self._input_chars[:i], romja, self._input_chars[end:]))
+                               self._cursor_pos -= len(text)
+                               self._cursor_pos += len(romja)
 
-       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)
+               attrs.append (ibus.AttributeUnderline (pango.UNDERLINE_SINGLE, 0, len (self._input_chars.encode ("utf-8"))))
+
+               self.UpdatePreedit (dbus.String (self._input_chars),
+                               attrs.to_dbus_value (),
+                               dbus.Int32 (self._cursor_pos),
+                               len (self._input_chars) > 0)
+               self.UpdateAuxString (u"", ibus.AttrList ().to_dbus_value (), False)
+               self.UpdateLookupTable (self._lookup_table.to_dbus_value (), self._lookup_table_visible)
+
+       def _update_convert_chars (self):
+               self._convert_chars = u""
+               pos = 0
+               i = 0
+               for seg_index, text in self._segments:
+                       self._convert_chars += text
+                       if i <= self._cursor_pos:
+                               pos += len (text)
+                       i += 1
 
+               attrs = ibus.AttrList ()
+               attrs.append (ibus.AttributeUnderline (pango.UNDERLINE_SINGLE, 0, len (self._convert_chars)))
+               attrs.append (ibus.AttributeBackground (ibus.RGB (200, 200, 240),
+                               pos - len (self._segments[self._cursor_pos][1]),
+                               pos))
+               self.UpdatePreedit (dbus.String (self._convert_chars),
+                               attrs.to_dbus_value (),
+                               dbus.Int32 (pos),
+                               True)
+               aux_string = u"( %d / %d )" % (self._lookup_table.get_cursor_pos () + 1, self._lookup_table.get_number_of_candidates())
+               self.UpdateAuxString (aux_string, ibus.AttrList ().to_dbus_value (), self._lookup_table_visible)
+               self.UpdateLookupTable (self._lookup_table.to_dbus_value (), self._lookup_table_visible)
+
+       def _update (self):
+               self._need_update = False
+               if self._convert_begined == False:
+                       self._update_input_chars ()
+               else:
+                       self._update_convert_chars ()
+
+       def _on_key_return (self):
+               if not self._input_chars:
+                       return False
+               if self._convert_begined == False:
+                       self._commit_string (self._input_chars)
+               else:
+                       i = 0
+                       for seg_index, text in self._segments:
+                               self._context.commit_segment (i, seg_index)
+                       self._commit_string (self._convert_chars)
+               return True
+
+       def _on_key_escape (self):
+               if not self._input_chars:
+                       return False
+               self._reset ()
+               self._invalidate ()
+               return True
+
+       def _on_key_back_space (self):
+               if not self._input_chars:
+                       return False
+
+               if self._convert_begined:
+                       self._convert_begined = False
+                       self._cursor_pos = len (self._input_chars)
+                       self._lookup_table.clean ()
+                       self._lookup_table_visible = False
+               elif self._cursor_pos > 0:
+                       self._input_chars = self._input_chars[:self._cursor_pos - 1] + self._input_chars [self._cursor_pos:]
+                       self._cursor_pos -= 1
+
+               self._invalidate ()
+               return True
+
+       def _on_key_delete (self):
+               if not self._input_chars:
+                       return False
+
+               if self._convert_begined:
+                       self._convert_begined = False
+                       self._cursor_pos = len (self._input_chars)
+                       self._lookup_table.clean ()
+                       self._lookup_table_visible = False
+               elif self._cursor_pos < len (self._input_chars):
+                       self._input_chars = self._input_chars[:self._cursor_pos] + self._input_chars [self._cursor_pos + 1:]
+
+               self._invalidate ()
+               return True
+
+       def _on_key_space (self):
+               if not self._input_chars:
+                       return False
+               if self._convert_begined == False:
+                       self._begin_convert ()
+                       self._invalidate ()
+               else:
+                       self._lookup_table_visible = True
+                       self._cursor_down ()
+               return True
+
+       def _on_key_up (self):
+               if not self._input_chars:
+                       return False
+               self._lookup_table_visible = True
+               self._cursor_up ()
+               return True
+
+       def _on_key_down (self):
+               if not self._input_chars:
+                       return False
+               self._lookup_table_visible = True
+               self._cursor_down ()
+               return True
+
+       def _on_key_page_up (self):
+               if not self._input_chars:
+                       return False
+               if self._lookup_table_visible == True:
+                       self._page_up ()
+               return True
+
+       def _on_key_page_down (self):
+               if not self._input_chars:
+                       return False
+               if self._lookup_table_visible == True:
+                       self._page_down ()
+               return True
+
+       def _on_key_left (self):
+               if not self._input_chars:
+                       return False
+               if self._cursor_pos == 0:
+                       return True
+               self._cursor_pos -= 1
+               self._lookup_table_visible = False
+               self._fill_lookup_table ()
+               self._invalidate ()
+               return True
+
+       def _on_key_right (self):
+               if not self._input_chars:
+                       return False
+
+               if self._convert_begined:
+                       max_pos = len (self._segments) - 1
+               else:
+                       max_pos = len (self._input_chars)
+               if self._cursor_pos == max_pos:
+                       return True
+               self._cursor_pos += 1
+               self._lookup_table_visible = False
+               self._fill_lookup_table ()
+               self._invalidate ()
+
+               return True
+
+       def _on_key_number (self, index):
+               if not self._input_chars:
+                       return False
+
+               if self._convert_begined and self._lookup_table_visible:
+                       candidates = self._lookup_table.get_canidates_in_current_page ()
+                       if self._lookup_table.set_cursor_pos_in_current_page (index):
+                               index = self._lookup_table.get_cursor_pos ()
+                               candidate = self._lookup_table.get_current_candidate ()[0]
+                               self._segments[self._cursor_pos] = index, candidate
+                               self._lookup_table_visible = False
+                               self._on_key_right ()
+                               self._invalidate ()
+               return True
+
+
+       def _on_key_common (self, keyval):
+               if self._convert_begined:
+                       i = 0
+                       for seg_index, text in self._segments:
+                               self._context.commit_segment (i, seg_index)
+                       self._commit_string (self._convert_chars)
+               self._input_chars += unichr (keyval)
+               self._cursor_pos += 1
+               self._invalidate ()
+               return True
+
+       def _process_key_event (self, keyval, is_press, state):
+               # ignore key release events
+               if not is_press:
+                       return False
+
+               if keyval == keysyms.Return:
+                       return self._on_key_return ()
+               elif keyval == keysyms.Escape:
+                       return self._on_key_escape ()
+               elif keyval == keysyms.BackSpace:
+                       return self._on_key_back_space ()
+               elif keyval == keysyms.Delete or keyval == keysyms.KP_Delete:
+                       return self._on_key_delete ()
+               elif keyval == keysyms.space:
+                       return self._on_key_space ()
+               elif keyval >= keysyms._1 and keyval <= keysyms._9:
+                       index = keyval - keysyms._1
+                       return self._on_key_number (index)
+               elif keyval == keysyms.Page_Up or keyval == keysyms.KP_Page_Up:
+                       return self._on_key_page_up ()
+               elif keyval == keysyms.Page_Down or keyval == keysyms.KP_Page_Down:
+                       return self._on_key_page_down ()
+               elif keyval == keysyms.Up:
+                       return self._on_key_up ()
+               elif keyval == keysyms.Down:
+                       return self._on_key_down ()
+               elif keyval == keysyms.Left:
+                       return self._on_key_left ()
+               elif keyval == keysyms.Right:
+                       return self._on_key_right ()
+               elif keyval in xrange (keysyms.a, keysyms.z + 1) or \
+                       keyval in xrange (keysyms.A, keysyms.Z + 1):
+                       return self._on_key_common (keyval)
+               else:
+                       return True
+
+               return False
+
+       def _property_activate (self, prop_name, state):
+               prop = self._prop_dict[prop_name]
+               prop.set_state (state)
+
+               if state == ibus.PROP_STATE_CHECKED:
+                       if prop_name == "InputMode.Hiragana":
+                               prop = self._prop_dict["InputMode"]
+                               prop.set_label (_("あ"))
+                               self._input_mode = MODE_HIRAGANA
+                               self._update_property (prop)
+                       elif prop_name == "InputMode.Katakana":
+                               prop = self._prop_dict["InputMode"]
+                               prop.set_label (_("ア"))
+                               self._input_mode = MODE_KATAKANA
+                               self._update_property (prop)
+                       elif prop_name == "InputMode.HalfWidthKatakana":
+                               prop = self._prop_dict["InputMode"]
+                               prop.set_label (_("ア"))
+                               self._input_mode = MODE_HALF_WIDTH_KATAKANA
+                               self._update_property (prop)
+                       elif prop_name == "InputMode.Latin":
+                               prop = self._prop_dict["InputMode"]
+                               self._input_mode = MODE_LATIN
+                               prop.set_label (_("A"))
+                               self._update_property (prop)
+                       elif prop_name == "InputMode.WideLatin":
+                               prop = self._prop_dict["InputMode"]
+                               prop.set_label (_("A"))
+                               self._input_mode = MODE_WIDE_LATIN
+                               self._update_property (prop)
+
+       def _update_property (self, prop):
+               self.UpdateProperty (prop.to_dbus_value ())
 
        # methods for dbus rpc
        def ProcessKeyEvent (self, keyval, is_press, state):
@@ -163,10 +501,10 @@ class Engine (interface.IEngine):
                print "Reset"
 
        def PageUp (self):
-               print "PageUp"
+               self._page_up ()
 
        def PageDown (self):
-               print "PageDown"
+               self._page_down ()
 
        def CursorUp (self):
                self._cursor_up ()
@@ -179,12 +517,9 @@ class Engine (interface.IEngine):
                if self._enable:
                        self.RegisterProperties (self._prop_list.to_dbus_value ())
 
-       def PropertyActivate (self, prop_name):
-               print "PropertyActivate (%s)" % prop_name
+       def PropertyActivate (self, prop_name, prop_state):
+               self._property_activate (prop_name, prop_state)
 
        def Destroy (self):
                print "Destroy"
 
-class DemoEngine (Engine):
-       pass
-
index f76598d..3380416 100644 (file)
@@ -1,6 +1,7 @@
 # vim:set noet ts=4:
+# -*- coding: utf-8 -*-
 #
-# ibus-tmpl - The Input Bus template project
+# ibus-anthy - The Anthy engine for IBus
 #
 # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 #
 from ibus import interface
 import engine
 
-FACTORY_PATH = "/com/redhat/IBus/engines/Demo/Factory"
-ENGINE_PATH = "/com/redhat/IBus/engines/Demo/Engine/%d"
+FACTORY_PATH = "/com/redhat/IBus/engines/Anthy/Factory"
+ENGINE_PATH = "/com/redhat/IBus/engines/Anthy/Engine/%d"
 
 class DemoEngineFactory (interface.IEngineFactory):
-       NAME = "Enchant"
-       LANG = "en"
-       ICON = "ibus-enchant"
+       NAME = "Anthy"
+       LANG = "ja"
+       ICON = "ibus-anthy"
        AUTHORS = "Huang Peng <shawn.p.huang@gmail.com>"
        CREDITS = "GPLv2"
 
@@ -48,6 +49,6 @@ class DemoEngineFactory (interface.IEngineFactory):
        def CreateEngine (self):
                engine_path = ENGINE_PATH % self._max_engine_id
                self._max_engine_id += 1
-               return engine.DemoEngine (self._dbusconn, engine_path)
+               return engine.Engine (self._dbusconn, engine_path)
 
 
diff --git a/engine/ibus-engine-anthy.in b/engine/ibus-engine-anthy.in
new file mode 100644 (file)
index 0000000..8e1b2ca
--- /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/anthy/main.py $@
+
diff --git a/engine/ibus-engine-enchant.in b/engine/ibus-engine-enchant.in
deleted file mode 100644 (file)
index df64cfc..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-# vim:set noet ts=4:
-#
-# ibus-tmpl - The Input Bus template project
-#
-# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-python @prefix@/share/ibus/engine/enchant/main.py $@
-
index 019dcdb..6aaa1e1 100644 (file)
@@ -1,6 +1,7 @@
 # vim:set noet ts=4:
+# -*- coding: utf-8 -*-
 #
-# ibus-tmpl - The Input Bus template project
+# ibus-anthy - The Anthy engine for IBus
 #
 # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 #
diff --git a/engine/tables.py b/engine/tables.py
new file mode 100644 (file)
index 0000000..0a36cb1
--- /dev/null
@@ -0,0 +1,350 @@
+# vim:set noet ts=4:
+# -*- coding: utf-8 -*-
+#
+# ibus-anthy - The Anthy engine for IBus
+#
+# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# string, result, cont
+romaji_typing_rule = {
+    u"-" : u"ー",
+    u"a" : u"あ",
+    u"i" : u"い",
+    u"u" : u"う",
+    u"e" : u"え",
+    u"o" : u"お",
+    u"xa" : u"ぁ",
+    u"xi" : u"ぃ",
+    u"xu" : u"ぅ",
+    u"xe" : u"ぇ",
+    u"xo" : u"ぉ",
+    u"la" : u"ぁ",
+    u"li" : u"ぃ",
+    u"lu" : u"ぅ",
+    u"le" : u"ぇ",
+    u"lo" : u"ぉ",
+    u"wi" : u"うぃ",
+    u"we" : u"うぇ",
+    u"wha" : u"うぁ",
+    u"whi" : u"うぃ",
+    u"whe" : u"うぇ",
+    u"who" : u"うぉ",
+    u"va" : u"ヴぁ",
+    u"vi" : u"ヴぃ",
+    u"vu" : u"ヴ",
+    u"ve" : u"ヴぇ",
+    u"vo" : u"ヴぉ",
+    u"ka" : u"か",
+    u"ki" : u"き",
+    u"ku" : u"く",
+    u"ke" : u"け",
+    u"ko" : u"こ",
+    u"ga" : u"が",
+    u"gi" : u"ぎ",
+    u"gu" : u"ぐ",
+    u"ge" : u"げ",
+    u"go" : u"ご",
+    u"kya" : u"きゃ",
+    u"kyi" : u"きぃ",
+    u"kyu" : u"きゅ",
+    u"kye" : u"きぇ",
+    u"kyo" : u"きょ",
+    u"gya" : u"ぎゃ",
+    u"gyi" : u"ぎぃ",
+    u"gyu" : u"ぎゅ",
+    u"gye" : u"ぎぇ",
+    u"gyo" : u"ぎょ",
+    u"sa" : u"さ",
+    u"si" : u"し",
+    u"su" : u"す",
+    u"se" : u"せ",
+    u"so" : u"そ",
+    u"za" : u"ざ",
+    u"zi" : u"じ",
+    u"zu" : u"ず",
+    u"ze" : u"ぜ",
+    u"zo" : u"ぞ",
+    u"sya" : u"しゃ",
+    u"syi" : u"しぃ",
+    u"syu" : u"しゅ",
+    u"sye" : u"しぇ",
+    u"syo" : u"しょ",
+    u"sha" : u"しゃ",
+    u"shi" : u"し",
+    u"shu" : u"しゅ",
+    u"she" : u"しぇ",
+    u"sho" : u"しょ",
+    u"zya" : u"じゃ",
+    u"zyi" : u"じぃ",
+    u"zyu" : u"じゅ",
+    u"zye" : u"じぇ",
+    u"zyo" : u"じょ",
+    u"ja" : u"じゃ",
+    u"jya" : u"じゃ",
+    u"ji" : u"じ",
+    u"jyi" : u"じぃ",
+    u"ju" : u"じゅ",
+    u"jyu" : u"じゅ",
+    u"je" : u"じぇ",
+    u"jye" : u"じぇ",
+    u"jo" : u"じょ",
+    u"jyo" : u"じょ",
+    u"ta" : u"た",
+    u"ti" : u"ち",
+    u"tu" : u"つ",
+    u"tsu" : u"つ",
+    u"te" : u"て",
+    u"to" : u"と",
+    u"da" : u"だ",
+    u"di" : u"ぢ",
+    u"du" : u"づ",
+    u"de" : u"で",
+    u"do" : u"ど",
+    u"xtu" : u"っ",
+    u"xtsu" : u"っ",
+    u"ltu" : u"っ",
+    u"ltsu" : u"っ",
+    u"tya" : u"ちゃ",
+    u"tyi" : u"ちぃ",
+    u"tyu" : u"ちゅ",
+    u"tye" : u"ちぇ",
+    u"tyo" : u"ちょ",
+    u"cha" : u"ちゃ",
+    u"chi" : u"ち",
+    u"chu" : u"ちゅ",
+    u"che" : u"ちぇ",
+    u"cho" : u"ちょ",
+    u"dya" : u"ぢゃ",
+    u"dyi" : u"ぢぃ",
+    u"dyu" : u"ぢゅ",
+    u"dye" : u"ぢぇ",
+    u"dyo" : u"ぢょ",
+    u"tha" : u"てゃ",
+    u"thi" : u"てぃ",
+    u"thu" : u"てゅ",
+    u"the" : u"てぇ",
+    u"tho" : u"てょ",
+    u"dha" : u"でゃ",
+    u"dhi" : u"でぃ",
+    u"dhu" : u"でゅ",
+    u"dhe" : u"でぇ",
+    u"dho" : u"でょ",
+    u"na" : u"な",
+    u"ni" : u"に",
+    u"nu" : u"ぬ",
+    u"ne" : u"ね",
+    u"no" : u"の",
+    u"nya" : u"にゃ",
+    u"nyi" : u"にぃ",
+    u"nyu" : u"にゅ",
+    u"nye" : u"にぇ",
+    u"nyo" : u"にょ",
+    u"ha" : u"は",
+    u"hi" : u"ひ",
+    u"hu" : u"ふ",
+    u"fu" : u"ふ",
+    u"he" : u"へ",
+    u"ho" : u"ほ",
+    u"ba" : u"ば",
+    u"bi" : u"び",
+    u"bu" : u"ぶ",
+    u"be" : u"べ",
+    u"bo" : u"ぼ",
+    u"pa" : u"ぱ",
+    u"pi" : u"ぴ",
+    u"pu" : u"ぷ",
+    u"pe" : u"ぺ",
+    u"po" : u"ぽ",
+    u"hya" : u"ひゃ",
+    u"hyi" : u"ひぃ",
+    u"hyu" : u"ひゅ",
+    u"hye" : u"ひぇ",
+    u"hyo" : u"ひょ",
+    u"bya" : u"びゃ",
+    u"byi" : u"びぃ",
+    u"byu" : u"びゅ",
+    u"bye" : u"びぇ",
+    u"byo" : u"びょ",
+    u"pya" : u"ぴゃ",
+    u"pyi" : u"ぴぃ",
+    u"pyu" : u"ぴゅ",
+    u"pye" : u"ぴぇ",
+    u"pyo" : u"ぴょ",
+    u"fa" : u"ふぁ",
+    u"fi" : u"ふぃ",
+    u"fu" : u"ふ",
+    u"fe" : u"ふぇ",
+    u"fo" : u"ふぉ",
+    u"ma" : u"ま",
+    u"mi" : u"み",
+    u"mu" : u"む",
+    u"me" : u"め",
+    u"mo" : u"も",
+    u"mya" : u"みゃ",
+    u"myi" : u"みぃ",
+    u"myu" : u"みゅ",
+    u"mye" : u"みぇ",
+    u"myo" : u"みょ",
+    u"lya" : u"ゃ",
+    u"xya" : u"ゃ",
+    u"ya" : u"や",
+    u"lyu" : u"ゅ",
+    u"xyu" : u"ゅ",
+    u"yu" : u"ゆ",
+    u"lyo" : u"ょ",
+    u"xyo" : u"ょ",
+    u"yo" : u"よ",
+    u"ra" : u"ら",
+    u"ri" : u"り",
+    u"ru" : u"る",
+    u"re" : u"れ",
+    u"ro" : u"ろ",
+    u"rya" : u"りゃ",
+    u"ryi" : u"りぃ",
+    u"ryu" : u"りゅ",
+    u"rye" : u"りぇ",
+    u"ryo" : u"りょ",
+    u"xwa" : u"ゎ",
+    u"wa" : u"わ",
+    u"wo" : u"を",
+# u"n'" : u"ん",
+    u"nn" : u"ん",
+    u"wyi" : u"ゐ",
+    u"wye" : u"ゑ",
+}
+
+#hiragana, katakana, half_katakana
+hiragana_katakana_table = { 
+    u"あ" : (u"ア", u"ア"),
+    u"い" : (u"イ", u"イ"),
+    u"う" : (u"ウ", u"ウ"),
+    u"え" : (u"エ", u"エ"),
+    u"お" : (u"オ", u"オ"),
+    u"か" : (u"カ", u"カ"),
+    u"き" : (u"キ", u"キ"),
+    u"く" : (u"ク", u"ク"),
+    u"け" : (u"ケ", u"ケ"),
+    u"こ" : (u"コ", u"コ"),
+    u"が" : (u"ガ", u"ガ"),
+    u"ぎ" : (u"ギ", u"ギ"),
+    u"ぐ" : (u"グ", u"グ"),
+    u"げ" : (u"ゲ", u"ゲ"),
+    u"ご" : (u"ゴ", u"ゴ"),
+    u"さ" : (u"サ", u"サ"),
+    u"し" : (u"シ", u"シ"),
+    u"す" : (u"ス", u"ス"),
+    u"せ" : (u"セ", u"セ"),
+    u"そ" : (u"ソ", u"ソ"),
+    u"ざ" : (u"ザ", u"ザ"),
+    u"じ" : (u"ジ", u"ジ"),
+    u"ず" : (u"ズ", u"ズ"),
+    u"ぜ" : (u"ゼ", u"ゼ"),
+    u"ぞ" : (u"ゾ", u"ゾ"),
+    u"た" : (u"タ", u"タ"),
+    u"ち" : (u"チ", u"チ"),
+    u"つ" : (u"ツ", u"ツ"),
+    u"て" : (u"テ", u"テ"),
+    u"と" : (u"ト", u"ト"),
+    u"だ" : (u"ダ", u"ダ"),
+    u"ぢ" : (u"ヂ", u"ヂ"),
+    u"づ" : (u"ヅ", u"ヅ"),
+    u"で" : (u"デ", u"デ"),
+    u"ど" : (u"ド", u"ド"),
+    u"な" : (u"ナ", u"ナ"),
+    u"に" : (u"ニ", u"ニ"),
+    u"ぬ" : (u"ヌ", u"ヌ"),
+    u"ね" : (u"ネ", u"ネ"),
+    u"の" : (u"ノ", u"ノ"),
+    u"は" : (u"ハ", u"ハ"),
+    u"ひ" : (u"ヒ", u"ヒ"),
+    u"ふ" : (u"フ", u"フ"),
+    u"へ" : (u"ヘ", u"ヘ"),
+    u"ほ" : (u"ホ", u"ホ"),
+    u"ば" : (u"バ", u"バ"),
+    u"び" : (u"ビ", u"ビ"),
+    u"ぶ" : (u"ブ", u"ブ"),
+    u"べ" : (u"ベ", u"ベ"),
+    u"ぼ" : (u"ボ", u"ボ"),
+    u"ぱ" : (u"パ", u"パ"),
+    u"ぴ" : (u"ピ", u"ピ"),
+    u"ぷ" : (u"プ", u"プ"),
+    u"ぺ" : (u"ペ", u"ペ"),
+    u"ぽ" : (u"ポ", u"ポ"),
+    u"ま" : (u"マ", u"マ"),
+    u"み" : (u"ミ", u"ミ"),
+    u"む" : (u"ム", u"ム"),
+    u"め" : (u"メ", u"メ"),
+    u"も" : (u"モ", u"モ"),
+    u"や" : (u"ヤ", u"ヤ"),
+    u"ゆ" : (u"ユ", u"ユ"),
+    u"よ" : (u"ヨ", u"ヨ"),
+    u"ら" : (u"ラ", u"ラ"),
+    u"り" : (u"リ", u"リ"),
+    u"る" : (u"ル", u"ル"),
+    u"れ" : (u"レ", u"レ"),
+    u"ろ" : (u"ロ", u"ロ"),
+    u"わ" : (u"ワ", u"ワ"),
+    u"を" : (u"ヲ", u"ヲ"),
+    u"ん" : (u"ン", u"ン"),
+    u"ぁ" : (u"ァ", u"ァ"),
+    u"ぃ" : (u"ィ", u"ィ"),
+    u"ぅ" : (u"ゥ", u"ゥ"),
+    u"ぇ" : (u"ェ", u"ェ"),
+    u"ぉ" : (u"ォ", u"ォ"),
+    u"っ" : (u"ッ", u"ッ"),
+    u"ゃ" : (u"ャ", u"ャ"),
+    u"ゅ" : (u"ュ", u"ュ"),
+    u"ょ" : (u"ョ", u"ョ"),
+    u"ヵ" : (u"ヵ", u"カ"),
+    u"ヶ" : (u"ヶ", u"ケ"),
+    u"ゎ" : (u"ヮ", u"ワ"),
+    u"ゐ" : (u"ヰ", u"ィ"),
+    u"ゑ" : (u"ヱ", u"ェ"),
+    u"ヴ" : (u"ヴ", u"ヴ"),
+    u"ー" : (u"ー", u"ー"),
+    u"、" : (u"、", u"、"),
+    u"。" : (u"。", u"。"),
+    u"!" : (u"!", u"!"),
+    u"”" : (u"”", u"\""),
+    u"#" : (u"#", u"#"),
+    u"$" : (u"$", u"$"),
+    u"%" : (u"%", u"%"),
+    u"&" : (u"&", u"&"),
+    u"’" : (u"’", u"'"),
+    u"(" : (u"(", u""),
+    u")" : (u")", u")"),
+    u"〜" : (u"〜", u"~"),
+    u"=" : (u"=", u"="),
+    u"^" : (u"^", u"u"),
+    u"\" : (u"\", u"\\"),
+    u"|" : (u"|", u"|"),
+    u"‘" : (u"‘", u"`"),
+    u"@" : (u"@", u"@"),
+    u"{" : (u"{", u""),
+    u"「" : (u"「", u"「"),
+    u"+" : (u"+", u"+"),
+    u";" : (u";", u";"),
+    u"*" : (u"*", u"*"),
+    u":" : (u":", u" : u"),
+    u"}" : (u"}", u")"),
+    u"」" : (u"」", u"」"),
+    u"<" : (u"<", u"<"),
+    u">" : (u">", u">"),
+    u"?" : (u"?", u"?"),
+    u"/" : (u"/", u"/"),
+    u"_" : (u"_", u"_"),
+}
diff --git a/engine/test.py b/engine/test.py
new file mode 100644 (file)
index 0000000..cd67997
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import anthy
+import sys
+
+ctx = anthy.anthy_context ()
+ctx._set_encoding (2)
+if len(sys.argv) >= 2:
+    ctx.set_string (sys.argv[1])
+else:
+    ctx.set_string ("かまぁく")
+conv_stat = anthy.anthy_conv_stat ()
+seg_stat = anthy.anthy_segment_stat ()
+ctx.get_stat (conv_stat)
+for i in range (0, conv_stat.nr_segment):
+    ctx.get_segment_stat (i, seg_stat)
+    buf = "          "
+    i = ctx.get_segment (i, 0, buf, 10)
+    print buf[:i]
+# anthy.anthy_release_context (ctx)
+ctx = None
similarity index 76%
rename from ibus-tmpl.spec.in
rename to ibus-anthy.spec.in
index 52728bd..2b5c27b 100644 (file)
@@ -1,10 +1,10 @@
 %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
 %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
 %define mod_path ibus-@PACKAGE_VERSION_MAJOR@.@PACKAGE_VERSION_MINOR@
-Name:       ibus-tmpl
+Name:       ibus-anthy
 Version:    @PACKAGE_VERSION@
 Release:    1%{?dist}
-Summary:    IBus template project
+Summary:    The Anthy engine for IBus input platform.
 License:    GPLv2+
 Group:      System Environment/Libraries
 URL:        http://code.google.com/p/ibus/
@@ -15,7 +15,7 @@ BuildRequires: gettext-devel, libtool, python-devel, pygtk2-devel, perl(XML::Par
 Requires:   pygtk2
 
 %description
-IBus template project
+The Anthy engine for IBus input platform.
 
 %prep
 %setup -q
@@ -28,6 +28,7 @@ make %{?_smp_mflags}
 %install
 rm -rf $RPM_BUILD_ROOT
 make DESTDIR=${RPM_BUILD_ROOT} install
+rm -f $RPM_BUILD_ROOT%{python_sitearch}/_anthy.la
 
 # %find_lang %{name}
 
@@ -39,11 +40,12 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %doc AUTHORS COPYING README
 # %dir %{python_sitearch}/ibus
-# %{python_sitearch}/ibus/*
-%dir %{_datadir}/ibus/engine/enchant
-%{_datadir}/ibus/engine/enchant/*
-%{_libexecdir}/ibus-engine-enchant
-%{_datadir}/ibus/icons/ibus-enchant.svg
+%{python_sitearch}/anthy.py*
+%{python_sitearch}/_anthy.so
+%dir %{_datadir}/ibus/engine/anthy
+%{_datadir}/ibus/engine/anthy/*
+%{_libexecdir}/ibus-engine-anthy
+%{_datadir}/ibus/icons/ibus-anthy.png
 
 %changelog
 * Wed Jun 25 2008 Huang Peng <shawn.p.huang@gmail.com> - 0.1.0-1
index 2bd3790..b406579 100644 (file)
@@ -1,6 +1,6 @@
 # vim:set noet ts=4:
 #
-# ibus - The Input Bus
+# ibus - The Anthy engine for IBus
 #
 # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 #
 # Boston, MA  02111-1307  USA
 
 icons_DATA = \
-       ibus-enchant.svg \
+       ibus-anthy.png \
        $(NULL)
 
 iconsdir = $(datadir)/ibus/icons
 
 EXTRA_DIST = \
-       ibus-enchant.svg \
+       ibus-anthy.png \
        $(NULL)
diff --git a/icons/ibus-anthy.png b/icons/ibus-anthy.png
new file mode 100644 (file)
index 0000000..8d90188
Binary files /dev/null and b/icons/ibus-anthy.png differ
diff --git a/icons/ibus-enchant.svg b/icons/ibus-enchant.svg
deleted file mode 100644 (file)
index 3f9061d..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="48"
-   height="48"
-   id="svg14"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   sodipodi:docbase="/home/silvestre/Desktop/Neu/scalable/categories"
-   sodipodi:docname="ibus-enchant.svg"
-   version="1.0"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs3">
-    <linearGradient
-       id="linearGradient3186">
-      <stop
-         id="stop3188"
-         offset="0"
-         style="stop-color:#ff0000;stop-opacity:1;" />
-      <stop
-         id="stop3190"
-         offset="1"
-         style="stop-color:#fb4b12;stop-opacity:0.77840906;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3174">
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0"
-         id="stop3176" />
-      <stop
-         style="stop-color:#000000;stop-opacity:0;"
-         offset="1"
-         id="stop3178" />
-    </linearGradient>
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 24 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="48 : 24 : 1"
-       inkscape:persp3d-origin="24 : 16 : 1"
-       id="perspective23" />
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient6647">
-      <stop
-         style="stop-color:white;stop-opacity:1;"
-         offset="0"
-         id="stop6649" />
-      <stop
-         style="stop-color:white;stop-opacity:0.45064378"
-         offset="1"
-         id="stop6651" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4234">
-      <stop
-         id="stop4236"
-         offset="0"
-         style="stop-color:#c1e3ff;stop-opacity:1;" />
-      <stop
-         id="stop4238"
-         offset="1"
-         style="stop-color:#56ace5;stop-opacity:1;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2049"
-       inkscape:collect="always">
-      <stop
-         id="stop2051"
-         offset="0"
-         style="stop-color:white;stop-opacity:0.527897" />
-      <stop
-         id="stop2053"
-         offset="1"
-         style="stop-color:#ffffff;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2049"
-       id="linearGradient4018"
-       gradientUnits="userSpaceOnUse"
-       x1="72.151817"
-       y1="38.213421"
-       x2="72.151817"
-       y2="77.304459"
-       gradientTransform="matrix(0.473102,0,0,0.486551,-14.45093,-13.94975)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4234"
-       id="linearGradient4021"
-       gradientUnits="userSpaceOnUse"
-       x1="34.812870"
-       y1="16.950554"
-       x2="34.812870"
-       y2="50.460960"
-       gradientTransform="matrix(0.604677,0,0,0.611141,-2.223758,-2.866561)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6647"
-       id="linearGradient6653"
-       x1="38.311138"
-       y1="29.974993"
-       x2="26.017185"
-       y2="26.680838"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.308298,0,0,1.26823,-17.41594,-13.94055)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3186"
-       id="linearGradient3184"
-       x1="20.957657"
-       y1="35.310341"
-       x2="36.531876"
-       y2="35.310341"
-       gradientUnits="userSpaceOnUse" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1"
-     inkscape:cx="-150.5"
-     inkscape:cy="24"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="1024"
-     inkscape:window-height="693"
-     inkscape:window-x="0"
-     inkscape:window-y="26"
-     inkscape:showpageshadow="false"
-     width="48px"
-     height="48px"
-     showgrid="false"
-     showborder="false"
-     showguides="true"
-     inkscape:guide-bbox="true" />
-  <metadata
-     id="metadata4">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <path
-       style="color:black;fill:#2f82b8;fill-opacity:1;fill-rule:evenodd;stroke:#005188;stroke-width:1.02248347;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
-       d="M 26.652146,1.5112415 L 21.796107,7.0524995 L 18.086565,4.7695813 L 19.368084,5.7766783 L 15.819439,2.9965264 L 10.870014,6.1384784 L 11.561064,14.612225 L 4.5011298,16.459311 L 3.5112434,22.057698 L 9.5999726,26.703976 L 5.154827,33.444889 L 8.8715662,38.395843 L 8.9028381,38.371929 L 12.868462,40.89036 L 17.16419,39.214654 L 18.845126,43.384881 L 18.906372,43.368051 L 22.860699,45.879399 L 29.715189,46.488746 L 32.217915,38.510096 L 39.29653,40.43335 L 42.583698,35.082512 L 38.810927,27.808419 L 44.488758,22.53375 L 42.975915,16.173679 L 38.974191,13.636434 L 38.979021,13.679161 L 35.803916,13.203108 L 35.841272,6.5764474 L 31.825697,4.0960486 L 31.825697,4.0819295 L 26.652146,1.5112415 z M 26.017126,18.820536 C 26.1304,18.820536 26.223034,18.888863 26.334637,18.896705 C 27.083758,20.018222 27.604678,21.381061 27.604678,22.914592 C 27.604676,26.544153 25.091551,29.484129 22.001554,29.484129 C 21.881961,29.484129 21.783135,29.416636 21.665368,29.407958 C 20.912902,28.290367 20.395324,26.942643 20.395324,25.409112 C 20.395326,21.779551 22.927124,18.820536 26.017126,18.820536 z "
-       id="path2041"
-       sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccsscsc" />
-    <path
-       style="color:black;fill:url(#linearGradient4021);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.86331141;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
-       d="M 26.537485,2 L 21.471285,7.7153745 L 15.978957,3.444977 L 11.165279,6.4772487 L 11.843929,14.655197 L 4.9627365,16.437806 L 4,21.829224 L 9.9184569,26.313311 L 5.6003402,32.825753 L 9.2145447,37.603879 L 15.906347,35.012666 L 18.936598,42.418762 L 25.622096,43 L 28.052609,35.299866 L 34.933802,37.155986 L 38.137658,31.991933 L 34.476106,24.971762 L 40,19.88122 L 38.532224,13.743164 L 31.540553,12.695652 L 31.572117,4.4809497 L 26.537485,2 z M 22.00789,16.297625 C 25.97073,16.297625 28.009709,19.153348 28.009709,22.656208 C 28.009708,26.159069 25.016154,29.478806 22.00789,29.478806 C 18.99963,29.478804 16.547128,26.159069 16.547128,22.656208 C 16.54713,19.153347 18.99963,16.297625 22.00789,16.297625 z "
-       id="path2043"
-       sodipodi:nodetypes="cccccccccccccccccccccccssss" />
-    <path
-       id="path1317"
-       d="M 26.531416,2 L 21.460369,7.8234072 L 15.975359,3.4748561 L 11.155646,6.5614153 L 11.835728,14.878396 L 4.9609866,16.702961 L 4,22.176659 L 4.6061603,22.648005 C 8.1497976,20.481689 12.845752,19.050606 18.074743,18.588345 C 19.070627,17.348013 20.453902,16.550914 22.007392,16.550914 C 24.120113,16.550914 25.633247,17.413895 26.634908,18.725189 C 30.895551,19.290607 34.700407,20.557527 37.767556,22.298298 L 40,20.200046 L 38.52156,13.950907 L 31.528542,12.886578 L 31.572894,4.5239825 L 26.531416,2 z "
-       style="color:black;fill:url(#linearGradient4018);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.86331141;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
-    <path
-       style="color:black;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6653);stroke-width:0.96760041;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
-       d="M 26.401951,3.4838006 L 21.536258,9.0779654 L 15.695213,4.8708453 L 11.522975,7.3498089 L 12.523715,15.307816 L 5.2069064,17.450691 L 4.4838012,21.870413 L 10.520787,26.606458 L 5.9446345,32.965733 L 9.2725396,37.444359 L 15.62388,34.741164 L 18.823489,41.958265 L 25.391328,42.5162 L 27.779067,35.124781 L 34.539151,36.906487 L 37.686624,31.949474 L 34.089512,25.21076 L 39.51619,20.324311 L 38.185589,14.756151 L 31.316967,13.750636 L 31.347975,5.7573491 L 26.401951,3.4838006 z M 21.840731,16.884393 C 25.733827,16.884393 27.736921,19.625623 27.736921,22.988044 C 27.73692,26.350463 24.79605,29.537105 21.840731,29.537105 C 18.885413,29.537103 16.476076,26.350463 16.476076,22.988044 C 16.476077,19.625622 18.885413,16.884393 21.840731,16.884393 z "
-       id="path5772"
-       sodipodi:nodetypes="cccccccccccccccccccccccssss" />
-    <text
-       xml:space="preserve"
-       style="font-size:24px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient3184);fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Sans;-inkscape-font-specification:Sans Bold Italic"
-       x="20.453751"
-       y="44.058388"
-       id="text2396"
-       sodipodi:linespacing="100%"><tspan
-         sodipodi:role="line"
-         x="20.453751"
-         y="44.058388"
-         id="tspan2400"
-         style="fill-opacity:1.0;fill:url(#linearGradient3184)">E</tspan></text>
-  </g>
-</svg>