├── NEWS ├── ChangeLog ├── po ├── LINGUAS ├── POTFILES.skip ├── POTFILES.in ├── Makevars └── ja.po ├── src ├── ibus-1.0.deps ├── ibus-kkc.deps ├── ibus-engine-kkc.gresource.xml ├── ibus-setup-kkc.desktop.in.in ├── ibus-setup-kkc.gresource.xml ├── config.vapi ├── kkc.xml.in.in ├── ibus-kkc-dictionaries.pot ├── ibus-kkc-dictionaries.json ├── shortcut-dialog.ui ├── dictionary-dialog.ui ├── preferences.vala ├── dictionary.vala ├── Makefile.am ├── engine.vala └── setup.vala ├── AUTHORS ├── .dir-locals.el ├── autogen.sh ├── ibus-kkc.spec.in ├── m4 └── Makefile.am ├── icons ├── Makefile.am └── ibus-kkc.svg ├── README ├── Makefile.am ├── configure.ac ├── git.mk └── COPYING /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | ja 2 | 3 | -------------------------------------------------------------------------------- /src/ibus-1.0.deps: -------------------------------------------------------------------------------- 1 | gio-2.0 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Daiki Ueno 2 | -------------------------------------------------------------------------------- /src/ibus-kkc.deps: -------------------------------------------------------------------------------- 1 | gee-0.8 2 | kkc-1.0 3 | ibus-1.0 4 | -------------------------------------------------------------------------------- /po/POTFILES.skip: -------------------------------------------------------------------------------- 1 | src/ibus-setup-kkc.desktop.in 2 | src/engine.c 3 | src/setup.c 4 | src/kkc.xml.in 5 | -------------------------------------------------------------------------------- /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((c-mode . ((indent-tabs-mode . nil))) 2 | (vala-mode . ((indent-tabs-mode . nil))) 3 | (js-mode . ((indent-tabs-mode . nil)))) 4 | -------------------------------------------------------------------------------- /src/ibus-engine-kkc.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ibus-kkc-dictionaries.json 5 | 6 | 7 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | src/engine.vala 2 | src/setup.vala 3 | [type: gettext/glade]src/setup-dialog.ui 4 | [type: gettext/glade]src/dictionary-dialog.ui 5 | [type: gettext/glade]src/shortcut-dialog.ui 6 | src/ibus-kkc-dictionaries.pot 7 | src/ibus-setup-kkc.desktop.in.in 8 | src/kkc.xml.in.in 9 | -------------------------------------------------------------------------------- /src/ibus-setup-kkc.desktop.in.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | _Name=Kana Kanji Conversion Preferences 3 | _Comment=Customize Kana Kanji Conversion input-method 4 | Exec=@libexecdir@/ibus-setup-kkc 5 | Icon=@pkgdatadir@/icons/ibus-kkc.svg 6 | NoDisplay=true 7 | Type=Application 8 | StartupNotify=true 9 | -------------------------------------------------------------------------------- /src/ibus-setup-kkc.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ibus-kkc-dictionaries.json 5 | setup-dialog.ui 6 | dictionary-dialog.ui 7 | shortcut-dialog.ui 8 | ../icons/ibus-kkc.svg 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/config.vapi: -------------------------------------------------------------------------------- 1 | [CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")] 2 | namespace Config 3 | { 4 | public const string GETTEXT_PACKAGE; 5 | public const string PACKAGE_DATADIR; 6 | public const string PACKAGE_NAME; 7 | public const string PACKAGE_VERSION; 8 | public const string LOCALEDIR; 9 | public const string LIBEXECDIR; 10 | public const string SETUPDIR; 11 | public const string DATADIR; 12 | public const string SKKDICDIR; 13 | public const string VERSION; 14 | } 15 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run this to generate all the initial makefiles, etc. 3 | 4 | srcdir=`dirname $0` 5 | test -z "$srcdir" && srcdir=. 6 | 7 | PKG_NAME="ibus-kkc" 8 | 9 | (test -f $srcdir/configure.ac \ 10 | && test -f $srcdir/README ) || { 11 | echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" 12 | echo " top-level $PKG_NAME directory" 13 | exit 1 14 | } 15 | 16 | which gnome-autogen.sh || { 17 | echo "You need to install gnome-common from the GNOME CVS" 18 | exit 1 19 | } 20 | 21 | ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4" 22 | REQUIRED_AUTOMAKE_VERSION=1.10 23 | REQUIRED_AUTOCONF_VERSION=2.60 24 | 25 | . gnome-autogen.sh 26 | -------------------------------------------------------------------------------- /src/kkc.xml.in.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.freedesktop.IBus.KKC 5 | KKC Component 6 | @libexecdir@/ibus-engine-kkc --ibus 7 | @VERSION@ 8 | Daiki Ueno <ueno@gnu.org> 9 | GPL 10 | https://bitbucket.org/libkkc/libkkc/ 11 | ibus-kkc 12 | 13 | 14 | 15 | 16 | kkc 17 | ja 18 | GPL 19 | Daiki Ueno <ueno@gnu.org> 20 | @pkgdatadir@/icons/ibus-kkc.svg 21 | jp 22 | <_longname>Kana Kanji 23 | <_description>Kana Kanji Input Method 24 | 77 25 | 26 | ibus-kkc 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ibus-kkc.spec.in: -------------------------------------------------------------------------------- 1 | Name: @PACKAGE_NAME@ 2 | Version: @PACKAGE_VERSION@ 3 | Release: 1%{?dist} 4 | Summary: Japanese KKC input method for ibus 5 | 6 | Group: System Environment/Libraries 7 | License: GPLv2+ 8 | URL: http://gitorious.org/libkkc/ibus-kkc 9 | Source0: %{name}-%{version}.tar.gz 10 | 11 | BuildRequires: intltool 12 | BuildRequires: libkkc-devel 13 | BuildRequires: ibus-devel 14 | BuildRequires: gtk3-devel 15 | Requires: ibus 16 | 17 | %description 18 | A Japanese KKC Input Method Engine for ibus. 19 | 20 | 21 | %prep 22 | %setup -q 23 | 24 | 25 | %build 26 | %configure 27 | make %{?_smp_mflags} 28 | 29 | 30 | %install 31 | make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" 32 | 33 | %find_lang %{name} 34 | 35 | 36 | %files -f %{name}.lang 37 | %doc AUTHORS COPYING README 38 | %{_datadir}/ibus-kkc 39 | %{_libexecdir}/ibus-*-kkc 40 | %{_datadir}/ibus/component/kkc.xml 41 | 42 | 43 | %changelog 44 | * @DATE_DISPLAY@ Daiki Ueno - @PACKAGE_VERSION@-1 45 | - initial release 46 | -------------------------------------------------------------------------------- /m4/Makefile.am: -------------------------------------------------------------------------------- 1 | # ibus-kkc - The Japanese Kana Kanji engine for IBus 2 | # 3 | # Copyright (C) 2012-2013 Daiki Ueno 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2, or (at your option) 8 | # any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | GITIGNOREFILES = \ 21 | intltool.m4 \ 22 | libtool.m4 \ 23 | ltoptions.m4 \ 24 | ltsugar.m4 \ 25 | ltversion.m4 \ 26 | lt~obsolete.m4 \ 27 | $(NULL) 28 | 29 | -include $(top_srcdir)/git.mk 30 | -------------------------------------------------------------------------------- /icons/Makefile.am: -------------------------------------------------------------------------------- 1 | # vim:set noet ts=4: 2 | # 3 | # ibus-kkc - The KKC engine for IBus 4 | # 5 | # Copyright (c) 2007-2008 Huang Peng 6 | # Copyright (C) 2009-2013 Daiki Ueno 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Lesser General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public 19 | # License along with this library; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | dist_icons_DATA = ibus-kkc.svg 24 | iconsdir = $(pkgdatadir)/icons 25 | 26 | -include $(top_srcdir)/git.mk 27 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ibus-kkc -- a Japanese Kana Kanji input engine for IBus 2 | ======================================================= 3 | 4 | ibus-kkc makes the Kana Kanji conversion library (libkkc[0]) usable 5 | through IBus. 6 | 7 | 8 | Custom dictionaries 9 | ------------------- 10 | 11 | ibus-kkc will look for a "dictionaries.json" file in a path consisting 12 | of the user's config directory concatenated with the package name (the 13 | default template for this file is at src/ibus-kkc-dictionaries.json[1]). By 14 | default the file will be searched in "$HOME/.config/ibus-kkc/". 15 | 16 | The "dictionaries.json" file is in JSON format and contains a list of 17 | JSON objects describing dictionaries that can be downloaded from here[2] 18 | (this site is in Japanese). All custom dictionary files mentioned in 19 | "dictionaries.json" will be searched in "/usr/local/share/skk/". 20 | 21 | The assumed default encoding of the dictionaries is "EUC-JP". If your 22 | dictionary uses a different encoding you can add an "encoding" field 23 | to the JSON object describing your dictionary. The value of that field 24 | should be the name of the encoding used in your custom dictionary file. 25 | 26 | [0] https://github.com/ueno/libkkc 27 | [1] https://github.com/ueno/ibus-kkc/blob/master/src/ibus-kkc-dictionaries.json 28 | [2] http://openlab.ring.gr.jp/skk/wiki/wiki.cgi?page=SKK%BC%AD%BD%F1 29 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # ibus-kkc - The Japanese Kana Kanji engine for IBus 2 | # 3 | # Copyright (C) 2012-2014 Daiki Ueno 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2, or (at your option) 8 | # any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | SUBDIRS = \ 21 | src \ 22 | icons \ 23 | m4 \ 24 | po \ 25 | $(NULL) 26 | 27 | # As of now (May 2013) IBus 1.4 is still widely used. For the tarball 28 | # distribution, generate C code which uses 1.4 API only. 29 | DISTCHECK_CONFIGURE_FLAGS = --with-ibus=1.4 30 | 31 | ACLOCAL_AMFLAGS = -I m4 32 | 33 | EXTRA_DIST = \ 34 | autogen.sh \ 35 | ibus-kkc.spec.in \ 36 | $(NULL) 37 | 38 | GITIGNOREFILES = \ 39 | INSTALL \ 40 | aclocal.m4 \ 41 | compile \ 42 | config.guess \ 43 | config.h.in \ 44 | config.sub \ 45 | depcomp \ 46 | install-sh \ 47 | ltmain.sh \ 48 | missing \ 49 | mkinstalldirs \ 50 | $(NULL) 51 | 52 | DISTCLEANFILES = \ 53 | po/stamp-it \ 54 | $(NULL) 55 | 56 | dist-hook: 57 | if test -d .git ; then \ 58 | git log --name-status --date=iso > $(distdir)/ChangeLog ; \ 59 | fi 60 | 61 | -include $(top_srcdir)/git.mk 62 | -------------------------------------------------------------------------------- /src/ibus-kkc-dictionaries.pot: -------------------------------------------------------------------------------- 1 | msgid "Standard (large)" 2 | msgstr "" 3 | 4 | msgid "Standard dictionary (SKK, large size)" 5 | msgstr "" 6 | 7 | msgid "Standard (medium)" 8 | msgstr "" 9 | 10 | msgid "Standard dictionary (SKK, medium size)" 11 | msgstr "" 12 | 13 | msgid "Standard (small)" 14 | msgstr "" 15 | 16 | msgid "Standard dictionary (SKK, small size)" 17 | msgstr "" 18 | 19 | msgid "ZIP code" 20 | msgstr "" 21 | 22 | msgid "Alternative dictionary for zipcodes" 23 | msgstr "" 24 | 25 | msgid "Station names" 26 | msgstr "" 27 | 28 | msgid "Alternative dictionary for station names" 29 | msgstr "" 30 | 31 | msgid "Okinawa dialect" 32 | msgstr "" 33 | 34 | msgid "Alternative dictionary for Okinawa dialect" 35 | msgstr "" 36 | 37 | msgid "Biographical" 38 | msgstr "" 39 | 40 | msgid "Alternative dictionary for biographical names" 41 | msgstr "" 42 | 43 | msgid "Geographical" 44 | msgstr "" 45 | 46 | msgid "Alternative dictionary for geographical names" 47 | msgstr "" 48 | 49 | msgid "Association and abbreviation" 50 | msgstr "" 51 | 52 | msgid "Alternative dictionary for association and abbreviation" 53 | msgstr "" 54 | 55 | msgid "Itaiji" 56 | msgstr "" 57 | 58 | msgid "Alternative dictionary for Itaiji" 59 | msgstr "" 60 | 61 | msgid "Proper nouns" 62 | msgstr "" 63 | 64 | msgid "Alternative dictionary for proper nouns" 65 | msgstr "" 66 | 67 | msgid "pubdic" 68 | msgstr "" 69 | 70 | msgid "Alternative dictionary based on pubdic" 71 | msgstr "" 72 | 73 | msgid "Biographical (fullname)" 74 | msgstr "" 75 | 76 | msgid "Alternative dictionary for biographical names (fullname)" 77 | msgstr "" 78 | 79 | msgid "Geographical (China and Taiwan)" 80 | msgstr "" 81 | 82 | msgid "Alternative dictionary for geographical names in China and Taiwan" 83 | msgstr "" 84 | 85 | msgid "Law terms" 86 | msgstr "" 87 | 88 | msgid "Alternative dictionary for law terms" 89 | msgstr "" 90 | -------------------------------------------------------------------------------- /po/Makevars: -------------------------------------------------------------------------------- 1 | # Makefile variables for PO directory in any package using GNU gettext. 2 | 3 | # Usually the message domain is the same as the package name. 4 | DOMAIN = $(PACKAGE) 5 | 6 | # These two variables depend on the location of this directory. 7 | subdir = po 8 | top_builddir = .. 9 | 10 | # These options get passed to xgettext. 11 | XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ 12 | 13 | # This is the copyright holder that gets inserted into the header of the 14 | # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding 15 | # package. (Note that the msgstr strings, extracted from the package's 16 | # sources, belong to the copyright holder of the package.) Translators are 17 | # expected to transfer the copyright for their translations to this person 18 | # or entity, or to disclaim their copyright. The empty string stands for 19 | # the public domain; in this case the translators are expected to disclaim 20 | # their copyright. 21 | COPYRIGHT_HOLDER = Daiki Ueno 22 | 23 | # This is the email address or URL to which the translators shall report 24 | # bugs in the untranslated strings: 25 | # - Strings which are not entire sentences, see the maintainer guidelines 26 | # in the GNU gettext documentation, section 'Preparing Strings'. 27 | # - Strings which use unclear terms or require additional context to be 28 | # understood. 29 | # - Strings which make invalid assumptions about notation of date, time or 30 | # money. 31 | # - Pluralisation problems. 32 | # - Incorrect English spelling. 33 | # - Incorrect formatting. 34 | # It can be your email address, or a mailing list address where translators 35 | # can write to without being subscribed, or the URL of a web page through 36 | # which the translators can contact you. 37 | MSGID_BUGS_ADDRESS = $(PACKAGE_BUGREPORT) 38 | 39 | # This is the list of locale categories, beyond LC_MESSAGES, for which the 40 | # message catalogs shall be used. It is usually empty. 41 | EXTRA_LOCALE_CATEGORIES = 42 | -------------------------------------------------------------------------------- /src/ibus-kkc-dictionaries.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "large", 4 | "filename": "SKK-JISYO.L", 5 | "name": "Standard (large)", 6 | "description": "Standard dictionary (SKK, large size)", 7 | "default_enabled": true 8 | }, 9 | { 10 | "id": "medium", 11 | "filename": "SKK-JISYO.M", 12 | "name": "Standard (medium)", 13 | "description": "Standard dictionary (SKK, medium size)", 14 | "default_enabled": false 15 | }, 16 | { 17 | "id": "small", 18 | "filename": "SKK-JISYO.S", 19 | "name": "Standard (small)", 20 | "description": "Standard dictionary (SKK, small size)", 21 | "default_enabled": false 22 | }, 23 | { 24 | "id": "zipcode", 25 | "filename": "SKK-JISYO.zipcode", 26 | "name": "ZIP code", 27 | "description": "Alternative dictionary for zipcodes", 28 | "default_enabled": true 29 | }, 30 | { 31 | "id": "station", 32 | "filename": "SKK-JISYO.station", 33 | "name": "Station names", 34 | "description": "Alternative dictionary for station names", 35 | "default_enabled": true 36 | }, 37 | { 38 | "id": "okinawa", 39 | "filename": "SKK-JISYO.okinawa", 40 | "name": "Okinawa dialect", 41 | "description": "Alternative dictionary for Okinawa dialect", 42 | "default_enabled": false 43 | }, 44 | { 45 | "id": "jinmei", 46 | "filename": "SKK-JISYO.jinmei", 47 | "name": "Biographical", 48 | "description": "Alternative dictionary for biographical names", 49 | "default_enabled": true 50 | }, 51 | { 52 | "id": "geo", 53 | "filename": "SKK-JISYO.geo", 54 | "name": "Geographical", 55 | "description": "Alternative dictionary for geographical names", 56 | "default_enabled": true 57 | }, 58 | { 59 | "id": "assoc", 60 | "filename": "SKK-JISYO.assoc", 61 | "name": "Association and abbreviation", 62 | "description": "Alternative dictionary for association and abbreviation", 63 | "default_enabled": false 64 | }, 65 | { 66 | "id": "itaiji", 67 | "filename": "SKK-JISYO.itaiji", 68 | "name": "Itaiji", 69 | "description": "Alternative dictionary for Itaiji", 70 | "default_enabled": false 71 | }, 72 | { 73 | "id": "propernoun", 74 | "filename": "SKK-JISYO.propernoun", 75 | "name": "Proper nouns", 76 | "description": "Alternative dictionary for proper nouns", 77 | "default_enabled": false 78 | }, 79 | { 80 | "id": "pubdic+", 81 | "filename": "SKK-JISYO.pubdic+", 82 | "name": "pubdic", 83 | "description": "Alternative dictionary based on pubdic", 84 | "default_enabled": false 85 | }, 86 | { 87 | "id": "fullname", 88 | "filename": "SKK-JISYO.fullname", 89 | "name": "Biographical (fullname)", 90 | "description": "Alternative dictionary for biographical names (fullname)", 91 | "default_enabled": false 92 | }, 93 | { 94 | "id": "china_taiwan", 95 | "filename": "SKK-JISYO.china_taiwan", 96 | "name": "Geographical (China and Taiwan)", 97 | "description": "Alternative dictionary for geographical names in China and Taiwan", 98 | "default_enabled": false 99 | }, 100 | { 101 | "id": "law", 102 | "filename": "SKK-JISYO.law", 103 | "name": "Law terms", 104 | "description": "Alternative dictionary for law terms", 105 | "default_enabled": false 106 | } 107 | ] 108 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # vim:set et ts=4: 2 | # 3 | # ibus-kkc - The Japanese Kana Kanji engine for IBus 4 | # 5 | # Copyright (c) 2007-2008 Huang Peng 6 | # Copyright (C) 2009-2014 Daiki Ueno 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2, or (at your option) 11 | # any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 | # 02110-1301, USA. 22 | 23 | # if not 1, append datestamp to the version number. 24 | m4_define([package_name], [ibus-kkc]) 25 | m4_define([ibus_released], [1]) 26 | m4_define([ibus_major_version], [1]) 27 | m4_define([ibus_minor_version], [5]) 28 | m4_define([ibus_micro_version], [22]) 29 | m4_define(ibus_maybe_datestamp, 30 | m4_esyscmd([if test x]ibus_released[ != x1; then date +.%Y%m%d | tr -d '\n\r'; fi])) 31 | 32 | m4_define([ibus_version], 33 | ibus_major_version.ibus_minor_version.ibus_micro_version[]ibus_maybe_datestamp) 34 | 35 | AC_INIT([package_name], [ibus_version], [https://bitbucket.org/libkkc/libkkc/issues], [package_name]) 36 | AM_INIT_AUTOMAKE([silent-rules]) 37 | AC_GNU_SOURCE 38 | 39 | AC_CONFIG_HEADERS([config.h]) 40 | AC_CONFIG_MACRO_DIR([m4]) 41 | 42 | # define PACKAGE_VERSION_* variables 43 | AM_SANITY_CHECK 44 | AM_MAINTAINER_MODE 45 | AM_DISABLE_STATIC 46 | AC_PROG_CC 47 | AC_PROG_CXX 48 | AM_PROG_CC_C_O 49 | AC_ISC_POSIX 50 | AC_HEADER_STDC 51 | IT_PROG_INTLTOOL([0.35.0]) 52 | AM_PROG_LIBTOOL 53 | 54 | # For dislpay Date 55 | m4_define(ibus_maybe_datedisplay, 56 | m4_esyscmd([if test x]ibus_released[ != x1; then date '+%a %b %d %Y' | tr -d '\n\r'; fi])) 57 | m4_define([ibus_datedisplay], ibus_maybe_datedisplay) 58 | DATE_DISPLAY="ibus_datedisplay" 59 | AC_SUBST(DATE_DISPLAY) 60 | 61 | # check ibus 62 | AC_ARG_WITH([ibus], 63 | [AS_HELP_STRING([--with-ibus], 64 | [IBus version to compile with @<:@default=auto@:>@])], 65 | [], 66 | [with_ibus=auto]) 67 | 68 | PKG_CHECK_MODULES(IBUS, [ibus-1.0 >= 1.5], , 69 | AC_MSG_ERROR([can't find ibus 1.5])) 70 | 71 | # check skkdic 72 | AC_ARG_WITH([skkdic], 73 | [AS_HELP_STRING([--with-skkdic], 74 | [location of skkdic @<:@default=DATAROOTDIR/skk@:>@])], 75 | [], 76 | [with_skkdic='${datarootdir}/skk']) 77 | AC_SUBST([skkdicdir], [$with_skkdic]) 78 | 79 | # check libkkc 80 | PKG_CHECK_MODULES(LIBKKC, [kkc-1.0 >= 0.3.4], , 81 | AC_MSG_ERROR([can't find libkkc])) 82 | 83 | # check gtk+ 84 | PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 3.10], , 85 | AC_MSG_ERROR([can't find gtk+-3.0])) 86 | 87 | # check vala 88 | AM_PROG_VALAC([0.10.0]) 89 | 90 | AC_PATH_PROG(VALAC, valac, valac) 91 | AC_SUBST(VALAC) 92 | AC_SUBST(VALAFLAGS) 93 | 94 | # define GETTEXT_* variables 95 | GETTEXT_PACKAGE=ibus-kkc 96 | AC_SUBST(GETTEXT_PACKAGE) 97 | AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the read-only architecture-independent data directory.]) 98 | 99 | # check glib-compile-resources 100 | GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0` 101 | AC_SUBST(GLIB_COMPILE_RESOURCES) 102 | 103 | # OUTPUT files 104 | AC_CONFIG_FILES([ po/Makefile.in 105 | Makefile 106 | ibus-kkc.spec 107 | src/Makefile 108 | icons/Makefile 109 | m4/Makefile 110 | ]) 111 | 112 | AC_OUTPUT 113 | -------------------------------------------------------------------------------- /src/shortcut-dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 106 | 107 | -------------------------------------------------------------------------------- /src/dictionary-dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/preferences.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daiki Ueno 3 | * Copyright (C) 2011-2014 Red Hat, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | * 02110-1301, USA. 19 | */ 20 | using Gee; 21 | 22 | public class Preferences : Object { 23 | IBus.Config config; 24 | DictionaryRegistry registry; 25 | 26 | Map _default = new HashMap (); 27 | Map current = new HashMap (); 28 | 29 | public void load () { 30 | Variant? values = config.get_values ("engine/kkc"); 31 | if (values != null) { 32 | var iter = values.iterator (); 33 | Variant? entry = null; 34 | while ((entry = iter.next_value ()) != null) { 35 | string name; 36 | Variant value; 37 | entry.get ("{sv}", out name, out value); 38 | current.set (name, value); 39 | } 40 | } 41 | } 42 | 43 | public DictionaryMetadata[] list_available_dictionaries () { 44 | return registry.list_available (); 45 | } 46 | 47 | public DictionaryMetadata get_dictionary_metadata (string id) { 48 | return registry.get_metadata (id); 49 | } 50 | 51 | public new Variant? @get (string name) { 52 | Variant? value = current.get (name); 53 | if (value != null) { 54 | return value; 55 | } 56 | return _default.get (name); 57 | } 58 | 59 | public new void @set (string name, Variant value) { 60 | Variant? _value = current.get (name); 61 | if (_value == null || !_value.equal (value)) { 62 | _value = _default.get (name); 63 | if (_value == null || !_value.equal (value)) { 64 | current.set (name, value); 65 | config.set_value ("engine/kkc", name, value); 66 | } else { 67 | current.unset (name); 68 | config.unset ("engine/kkc", name); 69 | } 70 | } 71 | } 72 | 73 | public Preferences (IBus.Config config) { 74 | registry = new DictionaryRegistry (); 75 | 76 | _default.set ( 77 | "user_dictionary", 78 | new Variant.string ( 79 | Path.build_filename ( 80 | Environment.get_user_config_dir (), 81 | Config.PACKAGE_NAME, 82 | "dictionary"))); 83 | 84 | ArrayList dictionaries = new ArrayList (); 85 | foreach (var metadata in list_available_dictionaries ()) { 86 | if (metadata.default_enabled) { 87 | dictionaries.add (metadata.id); 88 | } 89 | } 90 | _default.set ("system_dictionaries", 91 | new Variant.strv (dictionaries.to_array ())); 92 | _default.set ("punctuation_style", 93 | new Variant.int32 ((int32) Kkc.PunctuationStyle.JA_JA)); 94 | _default.set ("auto_correct", 95 | new Variant.boolean (true)); 96 | _default.set ("page_size", 97 | new Variant.int32 (10)); 98 | _default.set ("pagination_start", 99 | new Variant.int32 (0)); 100 | _default.set ("show_annotation", 101 | new Variant.boolean (false)); 102 | _default.set ("initial_input_mode", 103 | new Variant.int32 (Kkc.InputMode.HIRAGANA)); 104 | _default.set ("egg_like_newline", 105 | new Variant.boolean (false)); 106 | _default.set ("typing_rule", 107 | new Variant.string ("default")); 108 | _default.set ("use_custom_keymap", 109 | new Variant.boolean (false)); 110 | _default.set ("keymap", 111 | new Variant.string ("jp")); 112 | 113 | this.config = config; 114 | load (); 115 | config.value_changed.connect (value_changed_cb); 116 | } 117 | 118 | public signal void value_changed (string name, Variant value); 119 | 120 | void value_changed_cb (IBus.Config config, 121 | string section, 122 | string name, 123 | Variant value) 124 | { 125 | if (section == "engine/kkc") { 126 | if (value == null || 127 | // An empty tuple means that the value was unset. 128 | value.equal (new Variant.tuple (new Variant[0]))) { 129 | current.unset (name); 130 | } else { 131 | current.set (name, value); 132 | } 133 | value_changed (name, value); 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/dictionary.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daiki Ueno 3 | * Copyright (C) 2011-2014 Red Hat, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | * 02110-1301, USA. 19 | */ 20 | using Gee; 21 | 22 | public class DictionaryMetadata : Object { 23 | public string id { get; construct set; } 24 | public string filename { get; construct set; } 25 | public string name { get; construct set; } 26 | public string description { get; construct set; } 27 | 28 | public string encoding { get; construct set; default = "EUC-JP"; } 29 | public bool default_enabled { get; construct set; default = false; } 30 | 31 | public DictionaryMetadata.from_json_object (Json.Object object) { 32 | var id = object.get_string_member ("id"); 33 | var filename = object.get_string_member ("filename"); 34 | var name = object.get_string_member ("name"); 35 | var description = object.get_string_member ("description"); 36 | 37 | var default_enabled = false; 38 | if (object.has_member ("default_enabled")) 39 | default_enabled = object.get_boolean_member ("default_enabled"); 40 | 41 | var encoding = "EUC-JP"; 42 | if (object.has_member ("encoding")) { 43 | encoding = object.get_string_member ("encoding"); 44 | } 45 | 46 | Object (id: id, 47 | filename: Path.build_filename (Config.SKKDICDIR, filename), 48 | name: name, 49 | description: description, 50 | default_enabled: default_enabled, 51 | encoding: encoding); 52 | } 53 | } 54 | 55 | public class DictionaryRegistry : Object { 56 | Map available_metadata = 57 | new HashMap (); 58 | Gee.List available = new ArrayList (); 59 | 60 | void load_metadata_from_stream (InputStream stream) { 61 | var parser = new Json.Parser (); 62 | try { 63 | parser.load_from_stream (stream); 64 | } catch (GLib.Error e) { 65 | error ("failed to parse JSON: %s", e.message); 66 | } 67 | 68 | var root = parser.get_root (); 69 | 70 | if (root.get_node_type () != Json.NodeType.ARRAY) { 71 | error ("malformed format of dictionaries list: toplevel"); 72 | } 73 | var array = root.get_array (); 74 | 75 | for (var i = 0; i < array.get_length (); i++) { 76 | var node = array.get_element (i); 77 | 78 | if (node.get_node_type () != Json.NodeType.OBJECT) { 79 | warning ("malformed format of dictionaries list: child object"); 80 | continue; 81 | } 82 | 83 | var object = node.get_object (); 84 | var metadata = new DictionaryMetadata.from_json_object (object); 85 | 86 | if (FileUtils.test (metadata.filename, FileTest.EXISTS)) { 87 | available_metadata.set (metadata.id, metadata); 88 | available.add (metadata.id); 89 | } 90 | } 91 | } 92 | 93 | public DictionaryMetadata[] list_available () { 94 | var result = new ArrayList (); 95 | foreach (var id in available) { 96 | result.add (get_metadata (id)); 97 | } 98 | return result.to_array (); 99 | } 100 | 101 | public DictionaryMetadata? get_metadata (string id) { 102 | return available_metadata.get (id); 103 | } 104 | 105 | public DictionaryRegistry () { 106 | try { 107 | var stream = resources_open_stream ( 108 | "/org/freedesktop/ibus/engine/kkc/dictionaries.json", 109 | ResourceLookupFlags.NONE); 110 | load_metadata_from_stream (stream); 111 | } catch (GLib.Error e) { 112 | error ("can't load dictionaries list from resource: %s", e.message); 113 | } 114 | 115 | var file = File.new_for_path (Path.build_filename ( 116 | Environment.get_user_config_dir (), 117 | Config.PACKAGE_NAME, 118 | "dictionaries.json")); 119 | if (file.query_exists ()) { 120 | try { 121 | var stream = file.read (); 122 | load_metadata_from_stream (stream); 123 | } catch (GLib.Error e) { 124 | warning ("%s exists, but cannot read: %s", 125 | file.get_path (), 126 | e.message); 127 | } 128 | } else { 129 | warning ("Dictionary file at %s could not be found. We will run without any custom dictionaries.", 130 | file.get_path ()); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # ibus-kkc - The Japanese Kana Kanji engine for IBus 2 | # 3 | # Copyright (C) 2012-2013 Daiki Ueno 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2, or (at your option) 8 | # any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | # 02110-1301, USA. 19 | 20 | libexec_PROGRAMS = ibus-engine-kkc ibus-setup-kkc 21 | noinst_LTLIBRARIES = libutil.la 22 | 23 | libutil_la_VALAFLAGS = \ 24 | -H libutil.h --vapi ibus-kkc.vapi \ 25 | --vapidir=. \ 26 | --pkg config \ 27 | --pkg gee-0.8 \ 28 | --pkg kkc-1.0 \ 29 | --pkg ibus-1.0 \ 30 | --library ibus-kkc \ 31 | $(VALAFLAGS) 32 | libutil_la_SOURCES = \ 33 | preferences.vala \ 34 | dictionary.vala \ 35 | $(NULL) 36 | libutil_la_CFLAGS = \ 37 | $(COMMON_CFLAGS) 38 | libutil_la_LIBADD = \ 39 | $(COMMON_LIBS) 40 | 41 | BUILT_SOURCES = \ 42 | ibus-kkc.vapi \ 43 | ibus-engine-kkc-resources.c \ 44 | ibus-setup-kkc-resources.c \ 45 | $(NULL) 46 | 47 | # force include config.h before gi18n.h. 48 | AM_CPPFLAGS = -include $(CONFIG_HEADER) 49 | 50 | COMMON_CFLAGS = \ 51 | $(IBUS_CFLAGS) \ 52 | $(LIBKKC_CFLAGS) \ 53 | -DPACKAGE_DATADIR=\"$(pkgdatadir)\" \ 54 | -DLOCALEDIR=\"$(datadir)/locale\" \ 55 | -DSETUPDIR=\"$(setupdir)\" \ 56 | -DLIBEXECDIR=\"$(libexecdir)\" \ 57 | -DDATADIR=\"$(datadir)\" \ 58 | -DSKKDICDIR=\"$(skkdicdir)\" 59 | 60 | COMMON_LIBS = \ 61 | $(IBUS_LIBS) \ 62 | $(LIBKKC_LIBS) 63 | 64 | ibus_engine_kkc_VALAFLAGS = \ 65 | --vapidir=. \ 66 | --pkg config \ 67 | --pkg ibus-kkc \ 68 | --pkg gtk+-3.0 \ 69 | $(VALAFLAGS) 70 | 71 | ibus_engine_kkc_CFLAGS = \ 72 | $(COMMON_CFLAGS) \ 73 | $(GTK_CFLAGS) 74 | 75 | ibus_engine_kkc_LDADD = \ 76 | $(COMMON_LIBS) \ 77 | $(GTK_LIBS) \ 78 | libutil.la 79 | 80 | ibus_engine_kkc_SOURCES = \ 81 | engine.vala \ 82 | ibus-engine-kkc-resources.c \ 83 | $(NULL) 84 | 85 | ibus_setup_kkc_VALAFLAGS = \ 86 | --target-glib=2.38 \ 87 | --gresources ibus-setup-kkc.gresource.xml \ 88 | --vapidir=. \ 89 | --pkg config \ 90 | --pkg ibus-kkc \ 91 | --pkg gtk+-3.0 \ 92 | $(VALAFLAGS) 93 | 94 | ibus_setup_kkc_CFLAGS = \ 95 | $(COMMON_CFLAGS) \ 96 | $(GTK_CFLAGS) 97 | 98 | ibus_setup_kkc_LDADD = \ 99 | $(COMMON_LIBS) \ 100 | $(GTK_LIBS) \ 101 | libutil.la 102 | 103 | ibus_setup_kkc_SOURCES = \ 104 | setup.vala \ 105 | ibus-setup-kkc-resources.c \ 106 | $(NULL) 107 | 108 | ibus-engine-kkc-resources.c: ibus-engine-kkc.gresource.xml ibus-kkc-dictionaries.json 109 | $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) ibus-engine-kkc.gresource.xml \ 110 | --target=$@ --c-name ibus_kkc --generate-source 111 | 112 | ibus-setup-kkc-resources.c: ibus-setup-kkc.gresource.xml setup-dialog.ui dictionary-dialog.ui shortcut-dialog.ui ibus-kkc-dictionaries.json $(top_srcdir)/icons/ibus-kkc.svg 113 | $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) ibus-setup-kkc.gresource.xml \ 114 | --target=$@ --c-name ibus_kkc --generate-source 115 | 116 | edit = sed \ 117 | -e 's|@VERSION[@]|$(VERSION)|g' \ 118 | -e 's|@libexecdir[@]|$(libexecdir)|g' \ 119 | -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \ 120 | -e 's|@top_srcdir[@]|$(top_srcdir)|g' \ 121 | -e 's|@srcdir[@]|$(srcdir)|g' 122 | 123 | desktop_in_in_files = ibus-setup-kkc.desktop.in.in 124 | desktop_in_files = $(desktop_in_in_files:.in.in=.in) 125 | 126 | $(desktop_in_files): %.desktop.in: %.desktop.in.in Makefile 127 | $(AM_V_GEN) $(edit) $< > $@.tmp && mv $@.tmp $@ 128 | 129 | desktopdir=$(datadir)/applications 130 | desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) 131 | 132 | @INTLTOOL_DESKTOP_RULE@ 133 | 134 | component_DATA = kkc.xml 135 | componentdir = $(datadir)/ibus/component 136 | 137 | kkc.xml.in: kkc.xml.in.in 138 | $(AM_V_GEN) $(edit) $< > $@.tmp && mv $@.tmp $@ 139 | 140 | @INTLTOOL_XML_NOMERGE_RULE@ 141 | 142 | GITIGNOREFILES = \ 143 | $(libutil_la_SOURCES:.vala=.c) \ 144 | $(ibus_engine_kkc_SOURCES:.vala=.c) \ 145 | $(ibus_setup_kkc_SOURCES:.vala=.c) \ 146 | libutil_la_vala.stamp \ 147 | ibus_engine_kkc_vala.stamp \ 148 | ibus_setup_kkc_vala.stamp \ 149 | libutil.h \ 150 | $(NULL) 151 | 152 | CLEANFILES = \ 153 | ibus-engine-kkc-resources.c \ 154 | ibus-setup-kkc-resources.c \ 155 | $(desktop_DATA) \ 156 | $(desktop_in_files) \ 157 | kkc.xml.in \ 158 | kkc.xml \ 159 | $(NULL) 160 | 161 | EXTRA_DIST = \ 162 | config.vapi \ 163 | ibus-kkc.vapi \ 164 | ibus-kkc.deps \ 165 | ibus-1.0.vapi \ 166 | ibus-1.0.deps \ 167 | ibus-kkc-dictionaries.json \ 168 | ibus-kkc-dictionaries.pot \ 169 | $(desktop_in_in_files) \ 170 | kkc.xml.in.in \ 171 | ibus-engine-kkc.gresource.xml \ 172 | ibus-setup-kkc.gresource.xml \ 173 | setup-dialog.ui \ 174 | dictionary-dialog.ui \ 175 | shortcut-dialog.ui \ 176 | $(NULL) 177 | 178 | MAINTAINERCLEANFILES = \ 179 | ibus-kkc.vapi \ 180 | $(NULL) 181 | 182 | -include $(top_srcdir)/git.mk 183 | -------------------------------------------------------------------------------- /git.mk: -------------------------------------------------------------------------------- 1 | # git.mk 2 | # 3 | # Copyright 2009, Red Hat, Inc. 4 | # Copyright 2010,2011 Behdad Esfahbod 5 | # Written by Behdad Esfahbod 6 | # 7 | # Copying and distribution of this file, with or without modification, 8 | # is permitted in any medium without royalty provided the copyright 9 | # notice and this notice are preserved. 10 | # 11 | # The latest version of this file can be downloaded from: 12 | # https://raw.github.com/behdad/git.mk/master/git.mk 13 | # Bugs, etc, should be reported upstream at: 14 | # https://github.com/behdad/git.mk 15 | # 16 | # To use in your project, import this file in your git repo's toplevel, 17 | # then do "make -f git.mk". This modifies all Makefile.am files in 18 | # your project to -include git.mk. Remember to add that line to new 19 | # Makefile.am files you create in your project, or just rerun the 20 | # "make -f git.mk". 21 | # 22 | # This enables automatic .gitignore generation. If you need to ignore 23 | # more files, add them to the GITIGNOREFILES variable in your Makefile.am. 24 | # But think twice before doing that. If a file has to be in .gitignore, 25 | # chances are very high that it's a generated file and should be in one 26 | # of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES. 27 | # 28 | # The only case that you need to manually add a file to GITIGNOREFILES is 29 | # when remove files in one of mostlyclean-local, clean-local, distclean-local, 30 | # or maintainer-clean-local make targets. 31 | # 32 | # Note that for files like editor backup, etc, there are better places to 33 | # ignore them. See "man gitignore". 34 | # 35 | # If "make maintainer-clean" removes the files but they are not recognized 36 | # by this script (that is, if "git status" shows untracked files still), send 37 | # me the output of "git status" as well as your Makefile.am and Makefile for 38 | # the directories involved and I'll diagnose. 39 | # 40 | # For a list of toplevel files that should be in MAINTAINERCLEANFILES, see 41 | # Makefile.am.sample in the git.mk git repo. 42 | # 43 | # Don't EXTRA_DIST this file. It is supposed to only live in git clones, 44 | # not tarballs. It serves no useful purpose in tarballs and clutters the 45 | # build dir. 46 | # 47 | # This file knows how to handle autoconf, automake, libtool, gtk-doc, 48 | # gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu. 49 | # 50 | # This makefile provides the following targets: 51 | # 52 | # - all: "make all" will build all gitignore files. 53 | # - gitignore: makes all gitignore files in the current dir and subdirs. 54 | # - .gitignore: make gitignore file for the current dir. 55 | # - gitignore-recurse: makes all gitignore files in the subdirs. 56 | # 57 | # KNOWN ISSUES: 58 | # 59 | # - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the 60 | # submodule doesn't find us. If you have configure.{in,ac} files in 61 | # subdirs, add a proxy git.mk file in those dirs that simply does: 62 | # "include $(top_srcdir)/../git.mk". Add more ..'s to your taste. 63 | # And add those files to git. See vte/gnome-pty-helper/git.mk for 64 | # example. 65 | # 66 | 67 | git-all: git-mk-install 68 | 69 | git-mk-install: 70 | @echo Installing git makefile 71 | @any_failed=; \ 72 | find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \ 73 | if grep 'include .*/git.mk' $$x >/dev/null; then \ 74 | echo $$x already includes git.mk; \ 75 | else \ 76 | failed=; \ 77 | echo "Updating $$x"; \ 78 | { cat $$x; \ 79 | echo ''; \ 80 | echo '-include $$(top_srcdir)/git.mk'; \ 81 | } > $$x.tmp || failed=1; \ 82 | if test x$$failed = x; then \ 83 | mv $$x.tmp $$x || failed=1; \ 84 | fi; \ 85 | if test x$$failed = x; then : else \ 86 | echo Failed updating $$x; >&2 \ 87 | any_failed=1; \ 88 | fi; \ 89 | fi; done; test -z "$$any_failed" 90 | 91 | .PHONY: git-all git-mk-install 92 | 93 | 94 | ### .gitignore generation 95 | 96 | $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk 97 | $(AM_V_GEN) \ 98 | { \ 99 | if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ 100 | for x in \ 101 | $(DOC_MODULE)-decl-list.txt \ 102 | $(DOC_MODULE)-decl.txt \ 103 | tmpl/$(DOC_MODULE)-unused.sgml \ 104 | "tmpl/*.bak" \ 105 | xml html \ 106 | ; do echo /$$x; done; \ 107 | fi; \ 108 | if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ 109 | for lc in $(DOC_LINGUAS); do \ 110 | for x in \ 111 | $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ 112 | $(DOC_PAGES) \ 113 | $(DOC_INCLUDES) \ 114 | ; do echo /$$lc/$$x; done; \ 115 | done; \ 116 | for x in \ 117 | $(_DOC_OMF_ALL) \ 118 | $(_DOC_DSK_ALL) \ 119 | $(_DOC_HTML_ALL) \ 120 | $(_DOC_MOFILES) \ 121 | $(DOC_H_FILE) \ 122 | "*/.xml2po.mo" \ 123 | "*/*.omf.out" \ 124 | ; do echo /$$x; done; \ 125 | fi; \ 126 | if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ 127 | for lc in $(HELP_LINGUAS); do \ 128 | for x in \ 129 | $(HELP_FILES) \ 130 | "$$lc.stamp" \ 131 | "$$lc.mo" \ 132 | ; do echo /$$lc/$$x; done; \ 133 | done; \ 134 | fi; \ 135 | if test "x$(gsettings_SCHEMAS)" = x; then :; else \ 136 | for x in \ 137 | $(gsettings_SCHEMAS:.xml=.valid) \ 138 | $(gsettings__enum_file) \ 139 | ; do echo /$$x; done; \ 140 | fi; \ 141 | if test -f $(srcdir)/po/Makefile.in.in; then \ 142 | for x in \ 143 | po/Makefile.in.in \ 144 | po/Makefile.in \ 145 | po/Makefile \ 146 | po/POTFILES \ 147 | po/stamp-it \ 148 | po/.intltool-merge-cache \ 149 | "po/*.gmo" \ 150 | "po/*.mo" \ 151 | po/$(GETTEXT_PACKAGE).pot \ 152 | intltool-extract.in \ 153 | intltool-merge.in \ 154 | intltool-update.in \ 155 | ; do echo /$$x; done; \ 156 | fi; \ 157 | if test -f $(srcdir)/configure; then \ 158 | for x in \ 159 | autom4te.cache \ 160 | configure \ 161 | config.h \ 162 | stamp-h1 \ 163 | libtool \ 164 | config.lt \ 165 | ; do echo /$$x; done; \ 166 | fi; \ 167 | if test "x$(DEJATOOL)" = x; then :; else \ 168 | for x in \ 169 | $(DEJATOOL) \ 170 | ; do echo /$$x.sum; echo /$$x.log; done; \ 171 | echo /site.exp; \ 172 | fi; \ 173 | for x in \ 174 | .gitignore \ 175 | $(GITIGNOREFILES) \ 176 | $(CLEANFILES) \ 177 | $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ 178 | $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ 179 | $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ 180 | so_locations \ 181 | .libs _libs \ 182 | $(MOSTLYCLEANFILES) \ 183 | "*.$(OBJEXT)" \ 184 | "*.lo" \ 185 | $(DISTCLEANFILES) \ 186 | $(am__CONFIG_DISTCLEAN_FILES) \ 187 | $(CONFIG_CLEAN_FILES) \ 188 | TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ 189 | "*.tab.c" \ 190 | $(MAINTAINERCLEANFILES) \ 191 | $(BUILT_SOURCES) \ 192 | $(DEPDIR) \ 193 | Makefile \ 194 | Makefile.in \ 195 | "*.orig" \ 196 | "*.rej" \ 197 | "*.bak" \ 198 | "*~" \ 199 | ".*.sw[nop]" \ 200 | ".dirstamp" \ 201 | ; do echo /$$x; done; \ 202 | } | \ 203 | sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ 204 | sed 's@/[.]/@/@g' | \ 205 | LC_ALL=C sort | uniq > $@.tmp && \ 206 | mv $@.tmp $@; 207 | 208 | all: $(srcdir)/.gitignore gitignore-recurse-maybe 209 | gitignore: $(srcdir)/.gitignore gitignore-recurse 210 | 211 | gitignore-recurse-maybe: 212 | @for subdir in $(DIST_SUBDIRS); do \ 213 | case " $(SUBDIRS) " in \ 214 | *" $$subdir "*) :;; \ 215 | *) test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) .gitignore gitignore-recurse-maybe || echo "Skipping $$subdir");; \ 216 | esac; \ 217 | done 218 | gitignore-recurse: 219 | @for subdir in $(DIST_SUBDIRS); do \ 220 | test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) .gitignore gitignore-recurse || echo "Skipping $$subdir"); \ 221 | done 222 | 223 | maintainer-clean: gitignore-clean 224 | gitignore-clean: 225 | -rm -f $(srcdir)/.gitignore 226 | 227 | .PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe 228 | -------------------------------------------------------------------------------- /po/ja.po: -------------------------------------------------------------------------------- 1 | # Japanese translations for ibus-kkc package 2 | # ibus-kkc パッケージに対する英訳. 3 | # Copyright (C) 2009-2010 Daiki Ueno 4 | # This file is distributed under the same license as the ibus-kkc package. 5 | # Daiki Ueno , 2009. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: ibus-kkc 1.2.0.20091108\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2013-12-20 17:33+0900\n" 12 | "PO-Revision-Date: 2014-06-02 17:28+0900\n" 13 | "Last-Translator: Daiki Ueno \n" 14 | "Language-Team: Japanese\n" 15 | "Language: ja\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=1; plural=0;\n" 20 | 21 | #: ../src/engine.vala:70 ../src/ibus-kkc-preferences.ui.in.h:33 22 | msgid "Hiragana" 23 | msgstr "ひらがな" 24 | 25 | #: ../src/engine.vala:76 ../src/ibus-kkc-preferences.ui.in.h:36 26 | msgid "Katakana" 27 | msgstr "カタカナ" 28 | 29 | #: ../src/engine.vala:82 ../src/ibus-kkc-preferences.ui.in.h:37 30 | msgid "Halfwidth Katakana" 31 | msgstr "半角カタカナ" 32 | 33 | #: ../src/engine.vala:88 ../src/ibus-kkc-preferences.ui.in.h:34 34 | msgid "Latin" 35 | msgstr "英数" 36 | 37 | #: ../src/engine.vala:94 ../src/ibus-kkc-preferences.ui.in.h:38 38 | msgid "Wide Latin" 39 | msgstr "全角英数" 40 | 41 | #: ../src/engine.vala:100 42 | msgid "Direct Input" 43 | msgstr "直接入力" 44 | 45 | #: ../src/engine.vala:109 46 | msgid "Switch input mode" 47 | msgstr "入力モードを変更" 48 | 49 | #: ../src/engine.vala:120 50 | msgid "Setup" 51 | msgstr "設定" 52 | 53 | #: ../src/engine.vala:122 54 | msgid "Configure KKC" 55 | msgstr "KKC を設定" 56 | 57 | #: ../src/engine.vala:301 58 | #, c-format 59 | msgid "Input Mode (%s)" 60 | msgstr "入力モード (%s)" 61 | 62 | #: ../src/engine.vala:622 63 | msgid "Component is executed by IBus" 64 | msgstr "IBus からコンポーネントを起動" 65 | 66 | #: ../src/engine.vala:681 ../src/kkc.xml.in.in.h:1 67 | msgid "Kana Kanji" 68 | msgstr "かな漢字" 69 | 70 | #: ../src/setup.vala:352 71 | #, c-format 72 | msgid "Shortcut '%s' is already assigned to '%s'" 73 | msgstr "ショートカット '%s' は既に '%s' に割り当てられています" 74 | 75 | #: ../src/ibus-kkc-preferences.ui.in.h:1 76 | #: ../src/ibus-setup-kkc.desktop.in.in.h:1 77 | msgid "Kana Kanji Conversion Preferences" 78 | msgstr "かな漢字変換の設定" 79 | 80 | #: ../src/ibus-kkc-preferences.ui.in.h:2 81 | msgid "Typing _rule:" 82 | msgstr "タイピング方式(_R):" 83 | 84 | #: ../src/ibus-kkc-preferences.ui.in.h:3 85 | msgid "_Initial input mode:" 86 | msgstr "初期入力モード(_I):" 87 | 88 | #: ../src/ibus-kkc-preferences.ui.in.h:4 89 | msgid "_Punctuation style:" 90 | msgstr "句読点の形式(_P):" 91 | 92 | #: ../src/ibus-kkc-preferences.ui.in.h:5 93 | msgid "Auto correct input sequence" 94 | msgstr "入力列を自動的に修正する" 95 | 96 | #: ../src/ibus-kkc-preferences.ui.in.h:6 97 | msgid "Cancel invalid roma-ji sequence instead of inserting it" 98 | msgstr "ローマ字として無効な入力列を、挿入せずにキャンセル" 99 | 100 | #: ../src/ibus-kkc-preferences.ui.in.h:7 101 | msgid "Use custom keymap" 102 | msgstr "独自のキーマップを使う" 103 | 104 | #: ../src/ibus-kkc-preferences.ui.in.h:8 105 | msgid "Use different keyboard layout than the system settings" 106 | msgstr "システムの設定とは異なるキーボードレイアウトを利用" 107 | 108 | #: ../src/ibus-kkc-preferences.ui.in.h:9 109 | msgid "Typing" 110 | msgstr "タイピング" 111 | 112 | #: ../src/ibus-kkc-preferences.ui.in.h:10 113 | msgid "Maximum number of candidates which will be displayed on a single page" 114 | msgstr "1ページに表示する候補の最大数" 115 | 116 | #: ../src/ibus-kkc-preferences.ui.in.h:11 117 | msgid "Candidate _window page size:" 118 | msgstr "候補ウィンドウの項目数(_W):" 119 | 120 | #: ../src/ibus-kkc-preferences.ui.in.h:12 121 | msgid "Threshold to display candidate window" 122 | msgstr "候補ウィンドウを表示するまでの変換回数" 123 | 124 | #: ../src/ibus-kkc-preferences.ui.in.h:13 125 | msgid "Candidate window pa_gination start:" 126 | msgstr "候補ウィンドウの表示開始位置(_G):" 127 | 128 | #: ../src/ibus-kkc-preferences.ui.in.h:14 129 | msgid "Show annotation" 130 | msgstr "候補の注釈を表示する" 131 | 132 | #: ../src/ibus-kkc-preferences.ui.in.h:15 133 | msgid "Display annotation of word on the candidate window" 134 | msgstr "単語の注釈を候補ウィンドウに表示" 135 | 136 | #: ../src/ibus-kkc-preferences.ui.in.h:16 137 | msgid "Candidate window" 138 | msgstr "候補ウィンドウ" 139 | 140 | #: ../src/ibus-kkc-preferences.ui.in.h:17 141 | msgid "Behavior" 142 | msgstr "動作" 143 | 144 | #: ../src/ibus-kkc-preferences.ui.in.h:18 145 | msgid "Add Shortcut" 146 | msgstr "ショートカットを追加" 147 | 148 | #: ../src/ibus-kkc-preferences.ui.in.h:19 149 | msgid "Remove Shortcut" 150 | msgstr "ショートカットを削除" 151 | 152 | #: ../src/ibus-kkc-preferences.ui.in.h:20 153 | msgid "" 154 | "To edit a shortcut, click the row and hold down the new keys or press " 155 | "Backspace to clear." 156 | msgstr "" 157 | "ショートカットを編集するには、対応する行をクリックし、新しいキーの組み合わせ" 158 | "を押すか、[BS]キーで取り消してください。" 159 | 160 | #: ../src/ibus-kkc-preferences.ui.in.h:21 161 | msgid "Shortcuts" 162 | msgstr "ショートカット" 163 | 164 | #: ../src/ibus-kkc-preferences.ui.in.h:22 165 | msgid "Add.." 166 | msgstr "追加" 167 | 168 | #: ../src/ibus-kkc-preferences.ui.in.h:23 169 | msgid "Remove" 170 | msgstr "削除" 171 | 172 | #: ../src/ibus-kkc-preferences.ui.in.h:24 173 | msgid "Up" 174 | msgstr "上へ" 175 | 176 | #: ../src/ibus-kkc-preferences.ui.in.h:25 177 | msgid "Down" 178 | msgstr "下へ" 179 | 180 | #: ../src/ibus-kkc-preferences.ui.in.h:26 181 | msgid "Dictionaries" 182 | msgstr "辞書" 183 | 184 | #: ../src/ibus-kkc-preferences.ui.in.h:27 185 | msgid "Kana Kanji Conversion" 186 | msgstr "かな漢字変換" 187 | 188 | #: ../src/ibus-kkc-preferences.ui.in.h:28 189 | msgid "Kana Kanji Conversion input-method" 190 | msgstr "かな漢字変換入力メソッド" 191 | 192 | #: ../src/ibus-kkc-preferences.ui.in.h:29 193 | msgid "About" 194 | msgstr "情報" 195 | 196 | #: ../src/ibus-kkc-preferences.ui.in.h:30 197 | msgid "Add dictionary" 198 | msgstr "辞書を追加" 199 | 200 | #: ../src/ibus-kkc-preferences.ui.in.h:31 201 | msgid "System" 202 | msgstr "システム" 203 | 204 | #: ../src/ibus-kkc-preferences.ui.in.h:32 205 | msgid "User" 206 | msgstr "ユーザ" 207 | 208 | #: ../src/ibus-kkc-preferences.ui.in.h:35 209 | msgid "Direct input" 210 | msgstr "直接入力" 211 | 212 | #: ../src/ibus-kkc-preferences.ui.in.h:39 213 | msgid "Japanese" 214 | msgstr "日本語" 215 | 216 | #: ../src/ibus-kkc-preferences.ui.in.h:40 217 | msgid "English (US)" 218 | msgstr "英語 (US)" 219 | 220 | #: ../src/ibus-kkc-preferences.ui.in.h:41 221 | msgid "Add shortcut" 222 | msgstr "ショートカットを追加" 223 | 224 | #: ../src/ibus-kkc-preferences.ui.in.h:42 225 | msgid "Command:" 226 | msgstr "コマンド:" 227 | 228 | #: ../src/ibus-kkc-dictionaries.json.in:5 229 | msgid "Standard (large)" 230 | msgstr "標準 (サイズ大)" 231 | 232 | #: ../src/ibus-kkc-dictionaries.json.in:6 233 | msgid "Standard dictionary (SKK, large size)" 234 | msgstr "標準辞書 (SKK, サイズ大)" 235 | 236 | #: ../src/ibus-kkc-dictionaries.json.in:12 237 | msgid "Standard (medium)" 238 | msgstr "標準 (サイズ中)" 239 | 240 | #: ../src/ibus-kkc-dictionaries.json.in:13 241 | msgid "Standard dictionary (SKK, medium size)" 242 | msgstr "標準辞書 (SKK, サイズ中)" 243 | 244 | #: ../src/ibus-kkc-dictionaries.json.in:19 245 | msgid "Standard (small)" 246 | msgstr "標準 (サイズ小)" 247 | 248 | #: ../src/ibus-kkc-dictionaries.json.in:20 249 | msgid "Standard dictionary (SKK, small size)" 250 | msgstr "標準辞書 (SKK, サイズ小)" 251 | 252 | #: ../src/ibus-kkc-dictionaries.json.in:26 253 | msgid "ZIP code" 254 | msgstr "郵便番号" 255 | 256 | #: ../src/ibus-kkc-dictionaries.json.in:27 257 | msgid "Alternative dictionary for zipcodes" 258 | msgstr "補助辞書 (郵便番号)" 259 | 260 | #: ../src/ibus-kkc-dictionaries.json.in:33 261 | msgid "Station names" 262 | msgstr "駅名" 263 | 264 | #: ../src/ibus-kkc-dictionaries.json.in:34 265 | msgid "Alternative dictionary for station names" 266 | msgstr "補助辞書 (駅名)" 267 | 268 | #: ../src/ibus-kkc-dictionaries.json.in:40 269 | msgid "Okinawa dialect" 270 | msgstr "沖縄方言" 271 | 272 | #: ../src/ibus-kkc-dictionaries.json.in:41 273 | msgid "Alternative dictionary for Okinawa dialect" 274 | msgstr "補助辞書 (沖縄方言)" 275 | 276 | #: ../src/ibus-kkc-dictionaries.json.in:47 277 | msgid "Biographical" 278 | msgstr "人名" 279 | 280 | #: ../src/ibus-kkc-dictionaries.json.in:48 281 | msgid "Alternative dictionary for biographical names" 282 | msgstr "補助辞書 (人名)" 283 | 284 | #: ../src/ibus-kkc-dictionaries.json.in:54 285 | msgid "Geographical" 286 | msgstr "地名" 287 | 288 | #: ../src/ibus-kkc-dictionaries.json.in:55 289 | msgid "Alternative dictionary for geographical names" 290 | msgstr "補助辞書 (地名)" 291 | 292 | #: ../src/ibus-kkc-dictionaries.json.in:61 293 | msgid "Association and abbreviation" 294 | msgstr "連想と略語" 295 | 296 | #: ../src/ibus-kkc-dictionaries.json.in:62 297 | msgid "Alternative dictionary for association and abbreviation" 298 | msgstr "補助辞書 (連想と略語)" 299 | 300 | #: ../src/ibus-kkc-dictionaries.json.in:68 301 | msgid "Itaiji" 302 | msgstr "異体字" 303 | 304 | #: ../src/ibus-kkc-dictionaries.json.in:69 305 | msgid "Alternative dictionary for Itaiji" 306 | msgstr "補助辞書 (異体字)" 307 | 308 | #: ../src/ibus-kkc-dictionaries.json.in:75 309 | msgid "Proper nouns" 310 | msgstr "固有名詞" 311 | 312 | #: ../src/ibus-kkc-dictionaries.json.in:76 313 | msgid "Alternative dictionary for proper nouns" 314 | msgstr "補助辞書 (固有名詞)" 315 | 316 | #: ../src/ibus-kkc-dictionaries.json.in:82 317 | msgid "pubdic" 318 | msgstr "pubdic" 319 | 320 | #: ../src/ibus-kkc-dictionaries.json.in:83 321 | msgid "Alternative dictionary based on pubdic" 322 | msgstr "補助辞書 (pubdic)" 323 | 324 | #: ../src/ibus-kkc-dictionaries.json.in:89 325 | msgid "Biographical (fullname)" 326 | msgstr "人名 (フルネーム)" 327 | 328 | #: ../src/ibus-kkc-dictionaries.json.in:90 329 | msgid "Alternative dictionary for biographical names (fullname)" 330 | msgstr "補助辞書 (人名, フルネーム)" 331 | 332 | #: ../src/ibus-kkc-dictionaries.json.in:96 333 | msgid "Geographical (China and Taiwan)" 334 | msgstr "地名 (中国と台湾)" 335 | 336 | #: ../src/ibus-kkc-dictionaries.json.in:97 337 | msgid "Alternative dictionary for geographical names in China and Taiwan" 338 | msgstr "補助辞書 (中国と台湾の地名)" 339 | 340 | #: ../src/ibus-kkc-dictionaries.json.in:103 341 | msgid "Law terms" 342 | msgstr "法律用語" 343 | 344 | #: ../src/ibus-kkc-dictionaries.json.in:104 345 | msgid "Alternative dictionary for law terms" 346 | msgstr "補助辞書 (法律用語)" 347 | 348 | #: ../src/ibus-setup-kkc.desktop.in.in.h:2 349 | msgid "Customize Kana Kanji Conversion input-method" 350 | msgstr "かな漢字入力メソッドをカスタマイズ" 351 | 352 | #: ../src/kkc.xml.in.in.h:2 353 | msgid "Kana Kanji Input Method" 354 | msgstr "かな漢字入力方式" 355 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /src/engine.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daiki Ueno 3 | * Copyright (C) 2011-2014 Red Hat, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | * 02110-1301, USA. 19 | */ 20 | using Gee; 21 | 22 | class KkcEngine : IBus.Engine { 23 | // Preferences are shared among KkcEngine instances. 24 | static Preferences preferences; 25 | 26 | // Dictionaries are shared among KkcEngine instances and 27 | // maintained in the per-class signal handler in main(). 28 | static ArrayList dictionaries; 29 | 30 | // Language model is shared among KkcEngine instances and 31 | // maintained in the per-class signal handler in main(). 32 | static Kkc.LanguageModel language_model; 33 | 34 | Kkc.Context context; 35 | IBus.LookupTable lookup_table; 36 | bool lookup_table_visible; 37 | 38 | bool use_custom_keymap; 39 | bool show_annotation; 40 | 41 | IBus.Keymap keymap; 42 | IBus.Property input_mode_prop; 43 | IBus.PropList prop_list; 44 | bool properties_registered = false; 45 | 46 | Map input_mode_props = 47 | new HashMap (); 48 | Map input_mode_symbols = 49 | new HashMap (); 50 | Map name_input_modes = 51 | new HashMap (); 52 | 53 | Gtk.Clipboard clipboard; 54 | 55 | construct { 56 | // Prepare lookup table 57 | lookup_table = new IBus.LookupTable (LOOKUP_TABLE_LABELS.length, 58 | 0, true, true); 59 | for (var i = 0; i < LOOKUP_TABLE_LABELS.length; i++) { 60 | var text = new IBus.Text.from_string (LOOKUP_TABLE_LABELS[i]); 61 | lookup_table.set_label (i, text); 62 | } 63 | 64 | // Prepare the properties on the lang bar 65 | prop_list = new IBus.PropList (); 66 | var props = new IBus.PropList (); 67 | IBus.Property prop; 68 | 69 | prop = register_input_mode_property (Kkc.InputMode.HIRAGANA, 70 | "InputMode.Hiragana", 71 | _("Hiragana"), 72 | "あ"); 73 | props.append (prop); 74 | 75 | prop = register_input_mode_property (Kkc.InputMode.KATAKANA, 76 | "InputMode.Katakana", 77 | _("Katakana"), 78 | "ア"); 79 | props.append (prop); 80 | 81 | prop = register_input_mode_property (Kkc.InputMode.HANKAKU_KATAKANA, 82 | "InputMode.HankakuKatakana", 83 | _("Halfwidth Katakana"), 84 | "_ア"); 85 | props.append (prop); 86 | 87 | prop = register_input_mode_property (Kkc.InputMode.LATIN, 88 | "InputMode.Latin", 89 | _("Latin"), 90 | "_A"); 91 | props.append (prop); 92 | 93 | prop = register_input_mode_property (Kkc.InputMode.WIDE_LATIN, 94 | "InputMode.WideLatin", 95 | _("Wide Latin"), 96 | "A"); 97 | props.append (prop); 98 | 99 | prop = register_input_mode_property (Kkc.InputMode.DIRECT, 100 | "InputMode.Direct", 101 | _("Direct Input"), 102 | "_A"); 103 | props.append (prop); 104 | 105 | prop = new IBus.Property ( 106 | "InputMode", 107 | IBus.PropType.MENU, 108 | new IBus.Text.from_string ("あ"), 109 | null, 110 | new IBus.Text.from_string (_("Switch input mode")), 111 | true, 112 | true, 113 | IBus.PropState.UNCHECKED, 114 | props); 115 | prop_list.append (prop); 116 | input_mode_prop = prop; 117 | 118 | prop = new IBus.Property ( 119 | "setup", 120 | IBus.PropType.NORMAL, 121 | new IBus.Text.from_string (_("Preferences")), 122 | "gtk-preferences", 123 | new IBus.Text.from_string (_("Configure Kana Kanji Conversion")), 124 | true, 125 | true, 126 | IBus.PropState.UNCHECKED, 127 | null); 128 | prop_list.append (prop); 129 | 130 | // Initialize the context of libkkc. 131 | context = new Kkc.Context (language_model); 132 | 133 | foreach (var dictionary in dictionaries) { 134 | context.dictionaries.add (dictionary); 135 | } 136 | 137 | apply_preferences (); 138 | preferences.value_changed.connect ((name, value) => { 139 | apply_preferences (); 140 | if (name == "dictionaries") { 141 | // KkcEngine.dictionaries should be updated separately 142 | context.dictionaries.clear (); 143 | foreach (var dictionary in KkcEngine.dictionaries) { 144 | context.dictionaries.add (dictionary); 145 | } 146 | } 147 | }); 148 | 149 | context.notify["input"].connect (() => { 150 | update_preedit (); 151 | }); 152 | context.notify["input-mode"].connect ((s, p) => { 153 | update_input_mode (); 154 | }); 155 | context.candidates.populated.connect (() => { 156 | populate_lookup_table (); 157 | }); 158 | context.candidates.notify["cursor-pos"].connect (() => { 159 | set_lookup_table_cursor_pos (); 160 | }); 161 | context.candidates.selected.connect (() => { 162 | if (lookup_table_visible) { 163 | hide_lookup_table (); 164 | hide_auxiliary_text (); 165 | lookup_table_visible = false; 166 | } 167 | }); 168 | 169 | // Initialize clipboard 170 | clipboard = Gtk.Clipboard.get (Gdk.SELECTION_PRIMARY); 171 | context.request_selection_text.connect ((e) => { 172 | clipboard.request_text ( 173 | (Gtk.ClipboardTextReceivedFunc) set_selection_text); 174 | }); 175 | 176 | update_candidates (); 177 | update_input_mode (); 178 | } 179 | 180 | [CCode (instance_pos = 2.1)] 181 | void set_selection_text (Gtk.Clipboard clipboard, string? text) { 182 | context.set_selection_text (text); 183 | } 184 | 185 | void populate_lookup_table () { 186 | lookup_table.clear (); 187 | for (int i = (int) context.candidates.page_start; 188 | i < context.candidates.size; 189 | i++) { 190 | var text = new IBus.Text.from_string ( 191 | context.candidates[i].output); 192 | lookup_table.append_candidate (text); 193 | } 194 | } 195 | 196 | void set_lookup_table_cursor_pos () { 197 | var empty_text = new IBus.Text.from_static_string (""); 198 | var cursor_pos = context.candidates.cursor_pos; 199 | if (context.candidates.page_visible) { 200 | lookup_table.set_cursor_pos (cursor_pos - 201 | context.candidates.page_start); 202 | update_lookup_table_fast (lookup_table, true); 203 | var candidate = context.candidates.get (); 204 | if (show_annotation 205 | && candidate.annotation != null 206 | // SKK-JISYO.* has annotations marked as "?" for 207 | // development purposes. 208 | && candidate.annotation != "?") { 209 | var text = new IBus.Text.from_string ( 210 | candidate.annotation); 211 | update_auxiliary_text (text, true); 212 | } else { 213 | update_auxiliary_text (empty_text, false); 214 | } 215 | lookup_table_visible = true; 216 | } else if (lookup_table_visible) { 217 | hide_lookup_table (); 218 | hide_auxiliary_text (); 219 | lookup_table_visible = false; 220 | } 221 | } 222 | 223 | void update_preedit () { 224 | IBus.Text text; 225 | uint cursor_pos; 226 | if (context.segments.cursor_pos >= 0) { 227 | text = new IBus.Text.from_string (context.segments.get_output ()); 228 | int index = 0; 229 | int offset = 0; 230 | for (; index < context.segments.cursor_pos; index++) { 231 | offset += context.segments[index].output.char_count (); 232 | } 233 | text.append_attribute ( 234 | IBus.AttrType.BACKGROUND, 235 | 0x00c8c8f0, 236 | offset, 237 | offset + context.segments[index].output.char_count ()); 238 | text.append_attribute ( 239 | IBus.AttrType.FOREGROUND, 240 | 0x00000000, 241 | offset, 242 | offset + context.segments[index].output.char_count ()); 243 | cursor_pos = offset; 244 | } else { 245 | text = new IBus.Text.from_string (context.input); 246 | if (text.get_length () > 0 && 247 | context.input_cursor_pos >= 0) { 248 | text.append_attribute ( 249 | IBus.AttrType.BACKGROUND, 250 | 0x00000000, 251 | context.input_cursor_pos, 252 | context.input_cursor_pos + (int) context.input_cursor_width); 253 | text.append_attribute ( 254 | IBus.AttrType.FOREGROUND, 255 | (uint) 0xffffffff, 256 | context.input_cursor_pos, 257 | context.input_cursor_pos + (int) context.input_cursor_width); 258 | cursor_pos = context.input_cursor_pos; 259 | } else 260 | cursor_pos = text.get_length (); 261 | } 262 | if (text.get_length () > 0) { 263 | text.append_attribute ( 264 | IBus.AttrType.UNDERLINE, 265 | IBus.AttrUnderline.SINGLE, 266 | 0, 267 | (int) text.get_length ()); 268 | } 269 | 270 | if (context.has_output ()) { 271 | var output = context.poll_output (); 272 | var ctext = new IBus.Text.from_string (output); 273 | commit_text (ctext); 274 | } 275 | 276 | update_preedit_text (text, 277 | cursor_pos, 278 | text.get_length () > 0); 279 | } 280 | 281 | void update_candidates () { 282 | populate_lookup_table (); 283 | set_lookup_table_cursor_pos (); 284 | } 285 | 286 | void update_input_mode () { 287 | bool changed; 288 | 289 | // Update the menu item 290 | var iter = input_mode_props.map_iterator (); 291 | while (iter.next ()) { 292 | var input_mode = iter.get_key (); 293 | var prop = iter.get_value (); 294 | 295 | changed = false; 296 | if (input_mode == context.input_mode) { 297 | if (prop.get_state () == IBus.PropState.UNCHECKED) { 298 | prop.set_state (IBus.PropState.CHECKED); 299 | changed = true; 300 | } 301 | } else { 302 | if (prop.get_state () == IBus.PropState.CHECKED) { 303 | prop.set_state (IBus.PropState.UNCHECKED); 304 | changed = true; 305 | } 306 | } 307 | if (changed && properties_registered) 308 | update_property (prop); 309 | } 310 | 311 | // Update the menu 312 | changed = false; 313 | var symbol = new IBus.Text.from_string ( 314 | input_mode_symbols.get (context.input_mode)); 315 | var label = new IBus.Text.from_string ( 316 | _("Input Mode (%s)").printf (symbol.text)); 317 | if (input_mode_prop.get_symbol () != symbol) { 318 | input_mode_prop.set_symbol (symbol); 319 | changed = true; 320 | } 321 | if (input_mode_prop.get_label () != label) { 322 | input_mode_prop.set_label (label); 323 | changed = true; 324 | } 325 | if (changed && properties_registered) 326 | update_property (input_mode_prop); 327 | } 328 | 329 | static void reload_dictionaries () { 330 | KkcEngine.dictionaries.clear (); 331 | Variant? variant; 332 | 333 | variant = preferences.get ("user_dictionary"); 334 | if (variant != null) { 335 | try { 336 | KkcEngine.dictionaries.add (new Kkc.UserDictionary ( 337 | variant.get_string ())); 338 | } catch (Error e) { 339 | warning ("can't load user dictionary %s: %s", 340 | variant.get_string (), 341 | e.message); 342 | } 343 | } 344 | 345 | variant = preferences.get ("system_dictionaries"); 346 | assert (variant != null); 347 | string[] strv = variant.dup_strv (); 348 | foreach (var id in strv) { 349 | var metadata = preferences.get_dictionary_metadata (id); 350 | try { 351 | KkcEngine.dictionaries.add ( 352 | new Kkc.SystemSegmentDictionary (metadata.filename, 353 | metadata.encoding)); 354 | } catch (Error e) { 355 | warning ("can't load system dictionary %s: %s", 356 | metadata.filename, 357 | e.message); 358 | } 359 | } 360 | } 361 | 362 | void apply_preferences () { 363 | Variant? variant; 364 | 365 | variant = preferences.get ("punctuation_style"); 366 | assert (variant != null); 367 | context.punctuation_style = (Kkc.PunctuationStyle) variant.get_int32 (); 368 | 369 | variant = preferences.get ("auto_correct"); 370 | assert (variant != null); 371 | context.auto_correct = variant.get_boolean (); 372 | 373 | variant = preferences.get ("page_size"); 374 | assert (variant != null); 375 | context.candidates.page_size = (uint) variant.get_int32 (); 376 | lookup_table.set_page_size (variant.get_int32 ()); 377 | 378 | variant = preferences.get ("pagination_start"); 379 | assert (variant != null); 380 | context.candidates.page_start = (uint) variant.get_int32 (); 381 | 382 | variant = preferences.get ("initial_input_mode"); 383 | assert (variant != null); 384 | context.input_mode = (Kkc.InputMode) variant.get_int32 (); 385 | 386 | variant = preferences.get ("show_annotation"); 387 | assert (variant != null); 388 | show_annotation = variant.get_boolean (); 389 | 390 | variant = preferences.get ("typing_rule"); 391 | assert (variant != null); 392 | 393 | var parent_metadata = Kkc.RuleMetadata.find (variant.get_string ()); 394 | assert (parent_metadata != null); 395 | 396 | var base_dir = Path.build_filename ( 397 | Environment.get_user_config_dir (), 398 | "ibus-kkc", "rules"); 399 | 400 | try { 401 | context.typing_rule = new Kkc.UserRule (parent_metadata, 402 | base_dir, 403 | "ibus-kkc"); 404 | } catch (Error e) { 405 | warning ("can't load typing rule %s: %s", 406 | variant.get_string (), e.message); 407 | } 408 | 409 | variant = preferences.get ("use_custom_keymap"); 410 | assert (variant != null); 411 | use_custom_keymap = variant.get_boolean (); 412 | 413 | variant = preferences.get ("keymap"); 414 | assert (variant != null); 415 | keymap = IBus.Keymap.get (variant.get_string ()); 416 | } 417 | 418 | IBus.Property register_input_mode_property (Kkc.InputMode mode, 419 | string name, 420 | string label, 421 | string symbol) 422 | { 423 | var prop = new IBus.Property (name, 424 | IBus.PropType.RADIO, 425 | new IBus.Text.from_string (label), 426 | null, 427 | null, 428 | true, 429 | true, 430 | IBus.PropState.UNCHECKED, 431 | null); 432 | input_mode_props.set (mode, prop); 433 | input_mode_symbols.set (mode, symbol); 434 | name_input_modes.set (name, mode); 435 | return prop; 436 | } 437 | 438 | const string[] LOOKUP_TABLE_LABELS = { 439 | "1", "2", "3", "4", "5", "6", "7", "8", 440 | "9", "0", "a", "b", "c", "d", "e", "f" 441 | }; 442 | 443 | bool process_lookup_table_key_event (uint keyval, 444 | uint keycode, 445 | uint state) 446 | { 447 | var page_size = lookup_table.get_page_size (); 448 | if (state == 0 && 449 | ((unichar) keyval).to_string () in LOOKUP_TABLE_LABELS) { 450 | string label = ((unichar) keyval).tolower ().to_string (); 451 | for (var index = 0; 452 | index < int.min ((int)page_size, LOOKUP_TABLE_LABELS.length); 453 | index++) { 454 | if (LOOKUP_TABLE_LABELS[index] == label) { 455 | return context.candidates.select_at (index); 456 | } 457 | } 458 | return false; 459 | } 460 | 461 | if (state == 0) { 462 | bool retval = false; 463 | switch (keyval) { 464 | case IBus.Page_Up: 465 | case IBus.KP_Page_Up: 466 | retval = context.candidates.page_up (); 467 | break; 468 | case IBus.Page_Down: 469 | case IBus.KP_Page_Down: 470 | retval = context.candidates.page_down (); 471 | break; 472 | case IBus.Up: 473 | retval = context.candidates.cursor_up (); 474 | break; 475 | case IBus.Down: 476 | retval = context.candidates.cursor_down (); 477 | break; 478 | default: 479 | return false; 480 | } 481 | 482 | if (retval) { 483 | set_lookup_table_cursor_pos (); 484 | update_preedit (); 485 | } 486 | return true; 487 | } 488 | 489 | return false; 490 | } 491 | 492 | public override bool process_key_event (uint keyval, 493 | uint keycode, 494 | uint state) 495 | { 496 | uint _keyval = keyval; 497 | 498 | if (use_custom_keymap) 499 | _keyval = keymap.lookup_keysym ((uint16) keycode, (uint32) state); 500 | 501 | // Filter out unnecessary modifier bits 502 | // FIXME: should resolve virtual modifiers 503 | uint _state = state & (IBus.ModifierType.SHIFT_MASK | 504 | IBus.ModifierType.CONTROL_MASK | 505 | IBus.ModifierType.MOD1_MASK | 506 | IBus.ModifierType.MOD5_MASK | 507 | IBus.ModifierType.RELEASE_MASK); 508 | if (context.candidates.page_visible && 509 | process_lookup_table_key_event (_keyval, keycode, _state)) { 510 | return true; 511 | } 512 | 513 | var key = new Kkc.KeyEvent.from_x_event (_keyval, 514 | keycode, 515 | (Kkc.ModifierType) _state); 516 | 517 | var retval = context.process_key_event (key); 518 | 519 | // Hack for the direct input mode: if the keyval is translated 520 | // in the custom keymap and the new keyval is printable, send 521 | // it as a text event. 522 | if (!retval && use_custom_keymap && 523 | _keyval != keyval && 524 | 0x20 <= _keyval && _keyval <= 0x7F && 525 | (state & IBus.ModifierType.RELEASE_MASK) == 0) { 526 | var builder = new StringBuilder (); 527 | builder.append_c ((char) _keyval); 528 | var text = new IBus.Text.from_string (builder.str); 529 | commit_text (text); 530 | return true; 531 | } 532 | 533 | return retval; 534 | } 535 | 536 | uint save_dictionaries_timeout_id = 0; 537 | 538 | public override void enable () { 539 | context.reset (); 540 | 541 | save_dictionaries_timeout_id = Timeout.add_seconds_full ( 542 | Priority.LOW, 543 | 300, 544 | () => { 545 | context.dictionaries.save (); 546 | return true; 547 | }); 548 | 549 | base.enable (); 550 | } 551 | 552 | public override void disable () { 553 | focus_out (); 554 | 555 | if (save_dictionaries_timeout_id > 0) { 556 | Source.remove (save_dictionaries_timeout_id); 557 | save_dictionaries_timeout_id = 0; 558 | } 559 | context.dictionaries.save (); 560 | 561 | base.disable (); 562 | } 563 | 564 | public override void reset () { 565 | context.reset (); 566 | var empty_text = new IBus.Text.from_static_string (""); 567 | update_preedit_text (empty_text, 568 | 0, 569 | false); 570 | base.reset (); 571 | } 572 | 573 | public override void focus_in () { 574 | update_input_mode (); 575 | register_properties (prop_list); 576 | properties_registered = true; 577 | base.focus_in (); 578 | } 579 | 580 | public override void focus_out () { 581 | context.reset (); 582 | hide_preedit_text (); 583 | hide_lookup_table (); 584 | properties_registered = false; 585 | base.focus_out (); 586 | } 587 | 588 | public override void property_activate (string prop_name, 589 | uint prop_state) 590 | { 591 | if (prop_name == "setup") { 592 | var filename = Path.build_filename (Config.LIBEXECDIR, 593 | "ibus-setup-kkc"); 594 | try { 595 | Process.spawn_command_line_async (filename); 596 | } catch (GLib.SpawnError e) { 597 | warning ("can't spawn %s: %s", filename, e.message); 598 | } 599 | } 600 | else if (prop_name.has_prefix ("InputMode.") && 601 | prop_state == IBus.PropState.CHECKED) { 602 | context.input_mode = name_input_modes.get (prop_name); 603 | } 604 | } 605 | 606 | public override void candidate_clicked (uint index, uint button, uint state) { 607 | context.candidates.select_at (index); 608 | } 609 | 610 | public override void cursor_up () { 611 | context.candidates.cursor_up (); 612 | } 613 | 614 | public override void cursor_down () { 615 | context.candidates.cursor_down (); 616 | } 617 | 618 | public override void page_up () { 619 | context.candidates.page_up (); 620 | } 621 | 622 | public override void page_down () { 623 | context.candidates.page_down (); 624 | } 625 | 626 | static bool ibus; 627 | 628 | const OptionEntry[] options = { 629 | {"ibus", 'i', 0, OptionArg.NONE, ref ibus, 630 | N_("Component is executed by IBus"), null }, 631 | { null } 632 | }; 633 | 634 | public static int main (string[] args) { 635 | IBus.init (); 636 | Kkc.init (); 637 | Gtk.init (ref args); 638 | 639 | Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR); 640 | Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8"); 641 | Intl.textdomain (Config.GETTEXT_PACKAGE); 642 | 643 | var context = new OptionContext ("- ibus kkc"); 644 | context.add_main_entries (options, "ibus-kkc"); 645 | try { 646 | context.parse (ref args); 647 | } catch (OptionError e) { 648 | stderr.printf ("%s\n", e.message); 649 | return 1; 650 | } 651 | 652 | var bus = new IBus.Bus (); 653 | if (!bus.is_connected ()) { 654 | stderr.printf ("cannot connect to ibus-daemon!\n"); 655 | return 1; 656 | } 657 | 658 | bus.disconnected.connect (() => { IBus.quit (); }); 659 | 660 | var config = bus.get_config (); 661 | if (config == null) { 662 | stderr.printf ("ibus-config component is not running!\n"); 663 | return 1; 664 | } 665 | 666 | try { 667 | KkcEngine.language_model = Kkc.LanguageModel.load ("sorted3"); 668 | } catch (Error e) { 669 | stderr.printf ("can't load language model: %s\n", e.message); 670 | return 1; 671 | } 672 | 673 | KkcEngine.preferences = new Preferences (config); 674 | KkcEngine.dictionaries = new ArrayList (); 675 | KkcEngine.reload_dictionaries (); 676 | KkcEngine.preferences.value_changed.connect ((name, value) => { 677 | if (name == "dictionaries") { 678 | KkcEngine.reload_dictionaries (); 679 | } 680 | }); 681 | 682 | var factory = new IBus.Factory (bus.get_connection()); 683 | factory.add_engine ("kkc", typeof(KkcEngine)); 684 | if (ibus) { 685 | bus.request_name ("org.freedesktop.IBus.KKC", 0); 686 | } else { 687 | var component = new IBus.Component ( 688 | "org.freedesktop.IBus.KKC", 689 | N_("Kana Kanji"), Config.PACKAGE_VERSION, "GPL", 690 | "Daiki Ueno ", 691 | "https://github.com/ueno/ibus-kkc", 692 | "", 693 | "ibus-kkc"); 694 | var engine = new IBus.EngineDesc ( 695 | "kkc", 696 | "Kana Kanji", 697 | "Kana Kanji Input Method", 698 | "ja", 699 | "GPL", 700 | "Daiki Ueno ", 701 | "%s/icons/ibus-kkc.svg".printf (Config.PACKAGE_DATADIR), 702 | "us"); 703 | component.add_engine (engine); 704 | bus.register_component (component); 705 | } 706 | IBus.main (); 707 | return 0; 708 | } 709 | } 710 | -------------------------------------------------------------------------------- /src/setup.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daiki Ueno 3 | * Copyright (C) 2011-2014 Red Hat, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | * 02110-1301, USA. 19 | */ 20 | using Gee; 21 | 22 | class DictionaryCellRenderer : Gtk.CellRendererText { 23 | private DictionaryMetadata _metadata; 24 | public DictionaryMetadata metadata { 25 | get { 26 | return _metadata; 27 | } 28 | set { 29 | _metadata = value; 30 | text = dgettext (null, _metadata.name); 31 | } 32 | } 33 | } 34 | 35 | [GtkTemplate (ui = "/org/freedesktop/ibus/engine/kkc/dictionary-dialog.ui")] 36 | class DictionaryDialog : Gtk.Dialog { 37 | [GtkChild] 38 | private unowned Gtk.TreeView available_dictionaries_treeview; 39 | 40 | Preferences preferences; 41 | 42 | public DictionaryDialog (Preferences preferences) { 43 | this.preferences = preferences; 44 | 45 | Gtk.ListStore model; 46 | Gtk.CellRenderer renderer; 47 | Gtk.TreeViewColumn column; 48 | 49 | model = new Gtk.ListStore (2, 50 | typeof (DictionaryMetadata), 51 | typeof (string)); 52 | available_dictionaries_treeview.set_model (model); 53 | 54 | renderer = new DictionaryCellRenderer (); 55 | column = new Gtk.TreeViewColumn.with_attributes ("dict", renderer, 56 | "metadata", 0); 57 | available_dictionaries_treeview.append_column (column); 58 | populate_available_dictionaries_treeview (); 59 | } 60 | 61 | void populate_available_dictionaries_treeview () { 62 | Variant? variant = preferences.get ("system_dictionaries"); 63 | assert (variant != null); 64 | string[] strv = variant.dup_strv (); 65 | Set enabled = new Gee.HashSet (); 66 | foreach (var str in strv) { 67 | enabled.add (str); 68 | } 69 | 70 | var model = (Gtk.ListStore) available_dictionaries_treeview.get_model (); 71 | model.clear (); 72 | var available_dictionaries = preferences.list_available_dictionaries (); 73 | foreach (var metadata in available_dictionaries) { 74 | if (!enabled.contains (metadata.id)) { 75 | Gtk.TreeIter iter; 76 | model.append (out iter); 77 | model.set (iter, 78 | 0, metadata, 79 | 1, dgettext (null, metadata.description)); 80 | } 81 | } 82 | } 83 | 84 | public DictionaryMetadata[] get_dictionaries () { 85 | DictionaryMetadata[] dictionaries = {}; 86 | var selection = available_dictionaries_treeview.get_selection (); 87 | Gtk.TreeModel available_model; 88 | var rows = selection.get_selected_rows (out available_model); 89 | foreach (var row in rows) { 90 | Gtk.TreeIter available_iter; 91 | if (available_model.get_iter (out available_iter, row)) { 92 | DictionaryMetadata metadata; 93 | available_model.get (available_iter, 0, out metadata, -1); 94 | dictionaries += metadata; 95 | } 96 | } 97 | return dictionaries; 98 | } 99 | } 100 | 101 | [GtkTemplate (ui = "/org/freedesktop/ibus/engine/kkc/shortcut-dialog.ui")] 102 | class ShortcutDialog : Gtk.Dialog { 103 | [GtkChild] 104 | private unowned Gtk.ComboBox shortcut_command_combobox; 105 | 106 | public ShortcutDialog () { 107 | Gtk.ListStore model; 108 | Gtk.CellRenderer renderer; 109 | 110 | model = new Gtk.ListStore (2, typeof (string), typeof (string)); 111 | model.set_sort_column_id (1, Gtk.SortType.ASCENDING); 112 | shortcut_command_combobox.set_model (model); 113 | var commands = Kkc.Keymap.commands (); 114 | foreach (var command in commands) { 115 | Gtk.TreeIter iter; 116 | model.append (out iter); 117 | model.set (iter, 118 | 0, command, 119 | 1, Kkc.Keymap.get_command_label (command)); 120 | } 121 | shortcut_command_combobox.set_active (0); 122 | 123 | renderer = new Gtk.CellRendererText (); 124 | shortcut_command_combobox.pack_start (renderer, false); 125 | shortcut_command_combobox.set_attributes (renderer, "text", 1); 126 | } 127 | 128 | string combobox_get_active_string (Gtk.ComboBox combo, int column) { 129 | string text; 130 | Gtk.TreeIter iter; 131 | if (combo.get_active_iter (out iter)) { 132 | var model = (Gtk.ListStore) combo.get_model (); 133 | model.get (iter, column, out text, -1); 134 | } else { 135 | assert_not_reached (); 136 | } 137 | return text; 138 | } 139 | 140 | public string get_command () { 141 | return combobox_get_active_string (shortcut_command_combobox, 0); 142 | } 143 | } 144 | 145 | [GtkTemplate (ui = "/org/freedesktop/ibus/engine/kkc/setup-dialog.ui")] 146 | class SetupDialog : Gtk.Dialog { 147 | [GtkChild] 148 | private unowned Gtk.TreeView dictionaries_treeview; 149 | [GtkChild] 150 | private unowned Gtk.ComboBox punctuation_style_combobox; 151 | [GtkChild] 152 | private unowned Gtk.CheckButton auto_correct_checkbutton; 153 | [GtkChild] 154 | private unowned Gtk.CheckButton use_custom_keymap_checkbutton; 155 | [GtkChild] 156 | private unowned Gtk.ComboBox keymap_combobox; 157 | [GtkChild] 158 | private unowned Gtk.SpinButton page_size_spinbutton; 159 | [GtkChild] 160 | private unowned Gtk.SpinButton pagination_start_spinbutton; 161 | [GtkChild] 162 | private unowned Gtk.CheckButton show_annotation_checkbutton; 163 | [GtkChild] 164 | private unowned Gtk.ComboBox initial_input_mode_combobox; 165 | [GtkChild] 166 | private unowned Gtk.ComboBox typing_rule_combobox; 167 | [GtkChild] 168 | private unowned Gtk.TreeView input_mode_treeview; 169 | [GtkChild] 170 | private unowned Gtk.ToolButton add_dict_toolbutton; 171 | [GtkChild] 172 | private unowned Gtk.ToolButton remove_dict_toolbutton; 173 | [GtkChild] 174 | private unowned Gtk.ToolButton up_dict_toolbutton; 175 | [GtkChild] 176 | private unowned Gtk.ToolButton down_dict_toolbutton; 177 | [GtkChild] 178 | private unowned Gtk.TreeView shortcut_treeview; 179 | [GtkChild] 180 | private unowned Gtk.ToolButton add_shortcut_toolbutton; 181 | [GtkChild] 182 | private unowned Gtk.ToolButton remove_shortcut_toolbutton; 183 | [GtkChild] 184 | private unowned Gtk.Label version_label; 185 | 186 | Preferences preferences; 187 | 188 | Kkc.UserRule shortcut_rule; 189 | Kkc.InputMode shortcut_input_mode; 190 | 191 | public SetupDialog (Preferences preferences) { 192 | this.preferences = preferences; 193 | 194 | version_label.use_markup = true; 195 | version_label.label = "%s".printf (Config.VERSION); 196 | 197 | page_size_spinbutton.set_range (7.0, 16.0); 198 | page_size_spinbutton.set_increments (1.0, 1.0); 199 | 200 | pagination_start_spinbutton.set_range (0.0, 7.0); 201 | pagination_start_spinbutton.set_increments (1.0, 1.0); 202 | 203 | Gtk.ListStore model; 204 | Gtk.CellRenderer renderer; 205 | Gtk.TreeViewColumn column; 206 | 207 | model = new Gtk.ListStore (2, 208 | typeof (DictionaryMetadata), 209 | typeof (string)); 210 | dictionaries_treeview.set_model (model); 211 | 212 | renderer = new DictionaryCellRenderer (); 213 | column = new Gtk.TreeViewColumn.with_attributes ("dict", renderer, 214 | "metadata", 0); 215 | dictionaries_treeview.append_column (column); 216 | 217 | renderer = new Gtk.CellRendererText (); 218 | punctuation_style_combobox.pack_start (renderer, false); 219 | punctuation_style_combobox.set_attributes (renderer, "text", 0); 220 | 221 | renderer = new Gtk.CellRendererText (); 222 | initial_input_mode_combobox.pack_start (renderer, false); 223 | initial_input_mode_combobox.set_attributes (renderer, "text", 0); 224 | 225 | renderer = new Gtk.CellRendererText (); 226 | column = new Gtk.TreeViewColumn.with_attributes ("Mode", 227 | renderer, 228 | "text", 0); 229 | input_mode_treeview.append_column (column); 230 | var input_mode_selection = input_mode_treeview.get_selection (); 231 | input_mode_selection.changed.connect (() => { 232 | Gtk.TreeIter iter; 233 | Gtk.TreeModel _model; 234 | if (input_mode_selection.get_selected (out _model, out iter)) { 235 | int input_mode; 236 | _model.get (iter, 1, out input_mode, -1); 237 | populate_shortcut_treeview ((Kkc.InputMode) input_mode); 238 | } 239 | }); 240 | 241 | model = new Gtk.ListStore (3, 242 | typeof (string), 243 | typeof (Kkc.KeyEvent), 244 | typeof (string)); 245 | model.set_sort_column_id (0, Gtk.SortType.ASCENDING); 246 | shortcut_treeview.set_model (model); 247 | renderer = new Gtk.CellRendererText (); 248 | column = new Gtk.TreeViewColumn.with_attributes ("Command", 249 | renderer, 250 | "text", 2); 251 | shortcut_treeview.append_column (column); 252 | 253 | var accel_renderer = new KeyEventCellRenderer (); 254 | accel_renderer.set ("editable", true, 255 | "accel-mode", Gtk.CellRendererAccelMode.OTHER, 256 | null); 257 | column = new Gtk.TreeViewColumn.with_attributes ("Shortcut", 258 | accel_renderer, 259 | "event", 1); 260 | shortcut_treeview.append_column (column); 261 | 262 | accel_renderer.accel_edited.connect (accel_edited); 263 | accel_renderer.accel_cleared.connect (accel_cleared); 264 | 265 | var shortcut_selection = shortcut_treeview.get_selection (); 266 | shortcut_selection.changed.connect (() => { 267 | int count = shortcut_selection.count_selected_rows (); 268 | if (count > 0) { 269 | remove_shortcut_toolbutton.sensitive = true; 270 | } else if (count == 0) { 271 | remove_shortcut_toolbutton.sensitive = false; 272 | } 273 | }); 274 | 275 | add_shortcut_toolbutton.clicked.connect (add_shortcut); 276 | remove_shortcut_toolbutton.clicked.connect (remove_shortcut); 277 | 278 | model = new Gtk.ListStore (2, typeof (string), typeof (string)); 279 | model.set_sort_column_id (1, Gtk.SortType.ASCENDING); 280 | typing_rule_combobox.set_model (model); 281 | 282 | var rules = Kkc.Rule.list (); 283 | foreach (var rule in rules) { 284 | if (rule.priority > 70) { 285 | Gtk.TreeIter iter; 286 | model.append (out iter); 287 | model.set (iter, 0, rule.name, 1, rule.label); 288 | } 289 | } 290 | 291 | renderer = new Gtk.CellRendererText (); 292 | typing_rule_combobox.pack_start (renderer, false); 293 | typing_rule_combobox.set_attributes (renderer, "text", 1); 294 | 295 | renderer = new Gtk.CellRendererText (); 296 | keymap_combobox.pack_start (renderer, false); 297 | keymap_combobox.set_attributes (renderer, "text", 1); 298 | 299 | use_custom_keymap_checkbutton.toggled.connect (() => { 300 | keymap_combobox.sensitive = 301 | use_custom_keymap_checkbutton.get_active (); 302 | }); 303 | 304 | load (); 305 | 306 | add_dict_toolbutton.clicked.connect (add_dict); 307 | remove_dict_toolbutton.clicked.connect (remove_dict); 308 | up_dict_toolbutton.clicked.connect (up_dict); 309 | down_dict_toolbutton.clicked.connect (down_dict); 310 | 311 | var dictionaries_selection = dictionaries_treeview.get_selection (); 312 | dictionaries_selection.changed.connect (() => { 313 | int count = dictionaries_selection.count_selected_rows (); 314 | if (count > 0) { 315 | remove_dict_toolbutton.sensitive = true; 316 | 317 | Gtk.TreeModel _model; 318 | Gtk.TreeIter iter; 319 | if (dictionaries_selection.get_selected (out _model, 320 | out iter)) { 321 | Gtk.TreeIter prev = iter; 322 | up_dict_toolbutton.sensitive = 323 | _model.iter_previous (ref prev); 324 | 325 | Gtk.TreeIter next = iter; 326 | down_dict_toolbutton.sensitive = 327 | _model.iter_next (ref next); 328 | } 329 | } else if (count == 0) { 330 | remove_dict_toolbutton.sensitive = false; 331 | up_dict_toolbutton.sensitive = false; 332 | down_dict_toolbutton.sensitive = false; 333 | } 334 | }); 335 | } 336 | 337 | void accel_edited (string path_string, 338 | uint keyval, 339 | Gdk.ModifierType modifiers, 340 | uint keycode) 341 | { 342 | Gtk.TreeIter iter; 343 | var model = (Gtk.ListStore) shortcut_treeview.get_model (); 344 | if (model.get_iter_from_string (out iter, path_string)) { 345 | Kkc.KeyEvent new_event = new Kkc.KeyEvent.from_x_event ( 346 | keyval, 347 | keycode, 348 | (Kkc.ModifierType) modifiers); 349 | var keymap = shortcut_rule.get_keymap (shortcut_input_mode); 350 | var old_command = keymap.lookup_key (new_event); 351 | if (old_command != null) { 352 | string new_command; 353 | model.get (iter, 354 | 0, out new_command, 355 | -1); 356 | if (old_command != new_command) { 357 | var error_dialog = new Gtk.MessageDialog ( 358 | this, 359 | Gtk.DialogFlags.MODAL, 360 | Gtk.MessageType.ERROR, 361 | Gtk.ButtonsType.CLOSE, 362 | _("Shortcut '%s' is already assigned to '%s'"), 363 | new_event.to_string (), 364 | old_command); 365 | error_dialog.run (); 366 | error_dialog.destroy (); 367 | } 368 | } else { 369 | string new_command; 370 | Kkc.KeyEvent *old_event; 371 | model.get (iter, 372 | 0, out new_command, 373 | 1, out old_event, 374 | -1); 375 | if (old_event != null) 376 | keymap.set (old_event, null); 377 | keymap.set (new_event, new_command); 378 | try { 379 | shortcut_rule.write (shortcut_input_mode); 380 | } catch (Error e) { 381 | warning ("can't write shortcut: %s", e.message); 382 | } 383 | model.set (iter, 1, new_event, -1); 384 | 385 | // Notify engine that the typing rule has been modified. 386 | typing_rule_combobox.changed (); 387 | } 388 | } 389 | } 390 | 391 | void accel_cleared (string path_string) { 392 | Gtk.TreeIter iter; 393 | var model = (Gtk.ListStore) shortcut_treeview.get_model (); 394 | if (model.get_iter_from_string (out iter, path_string)) { 395 | Kkc.KeyEvent *old_event; 396 | model.get (iter, 1, out old_event, -1); 397 | var keymap = shortcut_rule.get_keymap (shortcut_input_mode); 398 | if (old_event != null) 399 | keymap.set (old_event, null); 400 | try { 401 | shortcut_rule.write (shortcut_input_mode); 402 | } catch (Error e) { 403 | warning ("can't write shortcut: %s", e.message); 404 | } 405 | #if VALA_0_36 406 | model.remove (ref iter); 407 | #else 408 | model.remove (iter); 409 | #endif 410 | } 411 | } 412 | 413 | void add_shortcut () { 414 | var shortcut_dialog = new ShortcutDialog (); 415 | shortcut_dialog.set_transient_for (this); 416 | if (shortcut_dialog.run () == Gtk.ResponseType.OK) { 417 | var command = shortcut_dialog.get_command (); 418 | Gtk.TreeIter iter; 419 | var model = (Gtk.ListStore) shortcut_treeview.get_model (); 420 | model.append (out iter); 421 | model.set (iter, 422 | 0, command, 423 | 1, null, 424 | 2, Kkc.Keymap.get_command_label (command), 425 | -1); 426 | } 427 | shortcut_dialog.hide (); 428 | } 429 | 430 | void remove_shortcut () { 431 | var selection = shortcut_treeview.get_selection (); 432 | Gtk.TreeModel model; 433 | var rows = selection.get_selected_rows (out model); 434 | var keymap = shortcut_rule.get_keymap (shortcut_input_mode); 435 | foreach (var row in rows) { 436 | Gtk.TreeIter iter; 437 | if (model.get_iter (out iter, row)) { 438 | Kkc.KeyEvent *old_event; 439 | model.get (iter, 1, out old_event, -1); 440 | if (old_event != null) { 441 | if (old_event->modifiers == 0 && 442 | old_event->keyval in IGNORED_KEYVALS) 443 | continue; 444 | keymap.set (old_event, null); 445 | } 446 | #if VALA_0_36 447 | ((Gtk.ListStore)model).remove (ref iter); 448 | #else 449 | ((Gtk.ListStore)model).remove (iter); 450 | #endif 451 | } 452 | } 453 | try { 454 | shortcut_rule.write (shortcut_input_mode); 455 | } catch (Error e) { 456 | warning ("can't write shortcut: %s", e.message); 457 | } 458 | } 459 | 460 | void populate_dictionaries_treeview () { 461 | Variant? variant = preferences.get ("system_dictionaries"); 462 | assert (variant != null); 463 | string[] strv = variant.dup_strv (); 464 | var model = (Gtk.ListStore) dictionaries_treeview.get_model (); 465 | foreach (var id in strv) { 466 | var metadata = preferences.get_dictionary_metadata (id); 467 | if (metadata != null) { 468 | Gtk.TreeIter iter; 469 | model.append (out iter); 470 | model.set (iter, 471 | 0, metadata, 472 | 1, dgettext (null, metadata.description)); 473 | } 474 | } 475 | } 476 | 477 | void populate_shortcut_treeview (Kkc.InputMode input_mode) { 478 | Variant? variant = preferences.get ("typing_rule"); 479 | assert (variant != null); 480 | 481 | var parent_metadata = Kkc.RuleMetadata.find (variant.get_string ()); 482 | assert (parent_metadata != null); 483 | 484 | var base_dir = Path.build_filename ( 485 | Environment.get_user_config_dir (), 486 | "ibus-kkc", "rules"); 487 | 488 | Kkc.UserRule rule; 489 | try { 490 | rule = new Kkc.UserRule (parent_metadata, base_dir, "ibus-kkc"); 491 | } catch (Error e) { 492 | error ("can't load typing rule %s: %s", 493 | variant.get_string (), e.message); 494 | } 495 | 496 | var model = (Gtk.ListStore) shortcut_treeview.get_model (); 497 | model.clear (); 498 | var entries = rule.get_keymap (input_mode).entries (); 499 | foreach (var entry in entries) { 500 | if (entry.command != null) { 501 | Gtk.TreeIter iter; 502 | model.append (out iter); 503 | model.set (iter, 504 | 0, entry.command, 505 | 1, entry.key, 506 | 2, Kkc.Keymap.get_command_label (entry.command)); 507 | } 508 | } 509 | shortcut_input_mode = input_mode; 510 | shortcut_rule = rule; 511 | } 512 | 513 | void add_dict () { 514 | var dictionary_dialog = new DictionaryDialog (preferences); 515 | dictionary_dialog.set_transient_for (this); 516 | if (dictionary_dialog.run () == Gtk.ResponseType.OK) { 517 | var dictionaries = dictionary_dialog.get_dictionaries (); 518 | var model = (Gtk.ListStore) dictionaries_treeview.get_model (); 519 | foreach (var dictionary in dictionaries) { 520 | Gtk.TreeIter iter; 521 | model.append (out iter); 522 | model.set (iter, 0, dictionary); 523 | } 524 | save_dictionaries ("system_dictionaries"); 525 | } 526 | dictionary_dialog.hide (); 527 | } 528 | 529 | void remove_dict () { 530 | var selection = dictionaries_treeview.get_selection (); 531 | Gtk.TreeModel model; 532 | var rows = selection.get_selected_rows (out model); 533 | foreach (var row in rows) { 534 | Gtk.TreeIter iter; 535 | if (model.get_iter (out iter, row)) { 536 | #if VALA_0_36 537 | ((Gtk.ListStore)model).remove (ref iter); 538 | #else 539 | ((Gtk.ListStore)model).remove (iter); 540 | #endif 541 | } 542 | } 543 | save_dictionaries ("system_dictionaries"); 544 | } 545 | 546 | void up_dict () { 547 | var selection = dictionaries_treeview.get_selection (); 548 | Gtk.TreeModel model; 549 | Gtk.TreeIter iter; 550 | if (selection.get_selected (out model, out iter)) { 551 | Gtk.TreeIter prev = iter; 552 | if (model.iter_previous (ref prev)) { 553 | ((Gtk.ListStore)model).swap (iter, prev); 554 | } 555 | } 556 | save_dictionaries ("system_dictionaries"); 557 | } 558 | 559 | void down_dict () { 560 | var selection = dictionaries_treeview.get_selection (); 561 | Gtk.TreeModel model; 562 | Gtk.TreeIter iter; 563 | if (selection.get_selected (out model, out iter)) { 564 | Gtk.TreeIter next = iter; 565 | if (model.iter_next (ref next)) { 566 | ((Gtk.ListStore)model).swap (iter, next); 567 | } 568 | } 569 | save_dictionaries ("system_dictionaries"); 570 | } 571 | 572 | void load_spinbutton (string name, 573 | Gtk.SpinButton spin) { 574 | Variant? variant = preferences.get (name); 575 | assert (variant != null); 576 | spin.value = (double) variant.get_int32 (); 577 | spin.value_changed.connect (() => { 578 | preferences.set (name, (int) spin.value); 579 | }); 580 | } 581 | 582 | void load_togglebutton (string name, 583 | Gtk.ToggleButton toggle) { 584 | Variant? variant = preferences.get (name); 585 | assert (variant != null); 586 | toggle.active = variant.get_boolean (); 587 | toggle.toggled.connect (() => { 588 | preferences.set (name, 589 | toggle.active); 590 | }); 591 | } 592 | 593 | void load_combobox (string name, 594 | Gtk.ComboBox combo, 595 | int column) { 596 | Variant? variant = preferences.get (name); 597 | assert (variant != null); 598 | Gtk.TreeIter iter; 599 | var model = combo.get_model (); 600 | if (model.get_iter_first (out iter)) { 601 | var index = variant.get_int32 (); 602 | int _index; 603 | do { 604 | model.get (iter, column, out _index, -1); 605 | if (index == _index) { 606 | combo.set_active_iter (iter); 607 | break; 608 | } 609 | } while (model.iter_next (ref iter)); 610 | } 611 | 612 | combo.changed.connect (() => { 613 | save_combobox (name, combo, column); 614 | }); 615 | } 616 | 617 | void load_combobox_string (string name, 618 | Gtk.ComboBox combo, 619 | int column) { 620 | Variant? variant = preferences.get (name); 621 | assert (variant != null); 622 | Gtk.TreeIter iter; 623 | var model = combo.get_model (); 624 | if (model.get_iter_first (out iter)) { 625 | string str = variant.get_string (); 626 | do { 627 | string _str; 628 | model.get (iter, column, out _str, -1); 629 | if (str == _str) { 630 | combo.set_active_iter (iter); 631 | break; 632 | } 633 | } while (model.iter_next (ref iter)); 634 | } 635 | 636 | combo.changed.connect (() => { 637 | save_combobox_string (name, combo, column); 638 | }); 639 | } 640 | 641 | void select_shortcut_section (Kkc.InputMode input_mode) { 642 | Gtk.TreeIter iter; 643 | var model = input_mode_treeview.get_model (); 644 | if (model.get_iter_first (out iter)) { 645 | do { 646 | int _input_mode; 647 | model.get (iter, 1, out _input_mode, -1); 648 | if (_input_mode == input_mode) { 649 | var selection = input_mode_treeview.get_selection (); 650 | selection.select_iter (iter); 651 | break; 652 | } 653 | } while (model.iter_next (ref iter)); 654 | } 655 | } 656 | 657 | void load () { 658 | load_combobox_string ("typing_rule", typing_rule_combobox, 0); 659 | load_combobox ("initial_input_mode", initial_input_mode_combobox, 1); 660 | load_combobox ("punctuation_style", punctuation_style_combobox, 1); 661 | load_togglebutton ("auto_correct", auto_correct_checkbutton); 662 | load_togglebutton ("use_custom_keymap", use_custom_keymap_checkbutton); 663 | load_combobox_string ("keymap", keymap_combobox, 0); 664 | 665 | load_spinbutton ("page_size", page_size_spinbutton); 666 | load_spinbutton ("pagination_start", pagination_start_spinbutton); 667 | load_togglebutton ("show_annotation", show_annotation_checkbutton); 668 | 669 | populate_dictionaries_treeview (); 670 | select_shortcut_section (Kkc.InputMode.HIRAGANA); 671 | } 672 | 673 | void save_dictionaries (string name) { 674 | var model = dictionaries_treeview.get_model (); 675 | Gtk.TreeIter iter; 676 | if (model.get_iter_first (out iter)) { 677 | ArrayList dictionaries = new ArrayList (); 678 | do { 679 | DictionaryMetadata metadata; 680 | model.get (iter, 0, out metadata, -1); 681 | dictionaries.add (metadata.id); 682 | } while (model.iter_next (ref iter)); 683 | preferences.set (name, dictionaries.to_array ()); 684 | } 685 | } 686 | 687 | void save_combobox (string name, 688 | Gtk.ComboBox combo, 689 | int column) 690 | { 691 | Gtk.TreeIter iter; 692 | if (combo.get_active_iter (out iter)) { 693 | int index; 694 | var model = combo.get_model (); 695 | model.get (iter, column, out index, -1); 696 | preferences.set (name, index); 697 | } 698 | } 699 | 700 | void save_combobox_string (string name, 701 | Gtk.ComboBox combo, 702 | int column) 703 | { 704 | Gtk.TreeIter iter; 705 | if (combo.get_active_iter (out iter)) { 706 | string str; 707 | var model = combo.get_model (); 708 | model.get (iter, column, out str, -1); 709 | preferences.set (name, str); 710 | } 711 | } 712 | 713 | const uint[] IGNORED_KEYVALS = { 714 | Kkc.Keysyms.BackSpace, 715 | Kkc.Keysyms.Escape 716 | }; 717 | 718 | class KeyEventCellRenderer : Gtk.CellRendererAccel { 719 | private Kkc.KeyEvent _event; 720 | public Kkc.KeyEvent event { 721 | get { 722 | return _event; 723 | } 724 | set { 725 | accel_mode = Gtk.CellRendererAccelMode.OTHER; 726 | _event = value; 727 | if (_event == null) { 728 | accel_key = 0; 729 | accel_mods = 0; 730 | keycode = 0; 731 | } else { 732 | accel_key = _event.keyval; 733 | accel_mods = (Gdk.ModifierType) _event.modifiers; 734 | keycode = _event.keycode; 735 | } 736 | if (accel_mods == 0 && accel_key in IGNORED_KEYVALS) 737 | editable = false; 738 | else 739 | editable = true; 740 | } 741 | } 742 | } 743 | 744 | public static int main (string[] args) { 745 | IBus.init (); 746 | Kkc.init (); 747 | Gtk.init (ref args); 748 | 749 | Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR); 750 | Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8"); 751 | Intl.textdomain (Config.GETTEXT_PACKAGE); 752 | 753 | var bus = new IBus.Bus (); 754 | if (!bus.is_connected ()) { 755 | stderr.printf ("cannot connect to ibus-daemon!\n"); 756 | return 1; 757 | } 758 | 759 | var config = bus.get_config (); 760 | if (config == null) { 761 | stderr.printf ("ibus-config component is not running!\n"); 762 | return 1; 763 | } 764 | 765 | var setup_dialog = new SetupDialog (new Preferences (config)); 766 | 767 | setup_dialog.run (); 768 | return 0; 769 | } 770 | } 771 | -------------------------------------------------------------------------------- /icons/ibus-kkc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 26 | 30 | 34 | 35 | 37 | 41 | 45 | 46 | 53 | 62 | 71 | 80 | 89 | 98 | 107 | 116 | 126 | 135 | 145 | 152 | 161 | 170 | 179 | 186 | 188 | 192 | 196 | 197 | 206 | 208 | 212 | 216 | 217 | 226 | 228 | 232 | 236 | 237 | 246 | 248 | 252 | 256 | 257 | 266 | 268 | 272 | 276 | 277 | 286 | 288 | 292 | 296 | 297 | 306 | 308 | 312 | 316 | 317 | 326 | 333 | 342 | 344 | 348 | 352 | 353 | 362 | 364 | 368 | 372 | 373 | 382 | 384 | 388 | 392 | 393 | 402 | 404 | 408 | 412 | 413 | 422 | 424 | 428 | 432 | 433 | 442 | 444 | 448 | 452 | 453 | 462 | 464 | 468 | 472 | 473 | 482 | 491 | 500 | 507 | 514 | 524 | 531 | 541 | 548 | 555 | 562 | 572 | 574 | 578 | 582 | 583 | 593 | 595 | 599 | 603 | 604 | 614 | 624 | 631 | 638 | 647 | 650 | 654 | 658 | 659 | 668 | 677 | 684 | 693 | 700 | 707 | 716 | 719 | 723 | 727 | 728 | 737 | 747 | 754 | 764 | 774 | 784 | 791 | 801 | 811 | 821 | 830 | 837 | 846 | 855 | 864 | 873 | 882 | 891 | 898 | 908 | 918 | 928 | 938 | 948 | 958 | 967 | 968 | 987 | 989 | 990 | 992 | image/svg+xml 993 | 995 | 996 | 997 | 998 | 999 | 1003 | 1007 | 1014 | 1026 | 1027 | 1031 | 1032 | --------------------------------------------------------------------------------