1 /* vim:set et ts=4 sts=4:
3 * ibus-libpinyin - Intelligent Pinyin engine based on libpinyin for IBus
5 * Copyright (c) 2011 Peng Wu <alexepico@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "PYLibPinyin.h"
24 #include "PYPConfig.h"
26 #define LIBPINYIN_SAVE_TIMEOUT (5 * 60)
30 std::unique_ptr<LibPinyinBackEnd> LibPinyinBackEnd::m_instance;
32 static LibPinyinBackEnd libpinyin_backend;
34 LibPinyinBackEnd::LibPinyinBackEnd () {
36 m_timer = g_timer_new();
37 m_pinyin_context = NULL;
38 m_chewing_context = NULL;
41 LibPinyinBackEnd::~LibPinyinBackEnd () {
42 g_timer_destroy (m_timer);
43 if (m_timeout_id != 0) {
45 g_source_remove (m_timeout_id);
49 pinyin_fini(m_pinyin_context);
50 m_pinyin_context = NULL;
51 if (m_chewing_context)
52 pinyin_fini(m_chewing_context);
53 m_chewing_context = NULL;
57 LibPinyinBackEnd::allocPinyinInstance ()
59 if (NULL == m_pinyin_context) {
60 gchar * userdir = g_build_filename (g_get_home_dir(), ".cache",
61 "ibus", "libpinyin", NULL);
62 int retval = g_mkdir_with_parents (userdir, 0700);
64 g_free(userdir); userdir = NULL;
66 m_pinyin_context = pinyin_init ("/usr/share/libpinyin/data", userdir);
67 pinyin_load_phrase_library(m_pinyin_context, 2);
71 setPinyinOptions (&LibPinyinPinyinConfig::instance ());
72 return pinyin_alloc_instance (m_pinyin_context);
76 LibPinyinBackEnd::freePinyinInstance (pinyin_instance_t *instance)
78 pinyin_free_instance (instance);
82 LibPinyinBackEnd::allocChewingInstance ()
84 if (NULL == m_chewing_context) {
85 gchar * userdir = g_build_filename (g_get_home_dir(), ".cache",
86 "ibus", "libbopomofo", NULL);
87 int retval = g_mkdir_with_parents (userdir, 0700);
89 g_free(userdir); userdir = NULL;
91 m_chewing_context = pinyin_init ("/usr/share/libpinyin/data", userdir);
92 pinyin_load_phrase_library(m_chewing_context, 2);
96 setChewingOptions (&LibPinyinBopomofoConfig::instance ());
97 return pinyin_alloc_instance (m_chewing_context);
101 LibPinyinBackEnd::freeChewingInstance (pinyin_instance_t *instance)
103 pinyin_free_instance (instance);
107 LibPinyinBackEnd::init (void) {
108 g_assert (NULL == m_instance.get ());
109 LibPinyinBackEnd * backend = new LibPinyinBackEnd;
110 m_instance.reset (backend);
114 LibPinyinBackEnd::finalize (void) {
118 /* Here are the double pinyin keyboard scheme mapping table. */
120 gint double_pinyin_keyboard;
121 DoublePinyinScheme scheme;
122 } double_pinyin_options [] = {
123 {0, DOUBLE_PINYIN_MS},
124 {1, DOUBLE_PINYIN_ZRM},
125 {2, DOUBLE_PINYIN_ABC},
126 {3, DOUBLE_PINYIN_ZIGUANG},
127 {4, DOUBLE_PINYIN_PYJJ},
128 {5, DOUBLE_PINYIN_XHE}
132 LibPinyinBackEnd::setPinyinOptions (Config *config)
134 if (NULL == m_pinyin_context)
137 const gint map = config->doublePinyinSchema ();
138 for (guint i = 0; i < G_N_ELEMENTS (double_pinyin_options); i++) {
139 if (map == double_pinyin_options[i].double_pinyin_keyboard) {
140 /* set double pinyin scheme. */
141 DoublePinyinScheme scheme = double_pinyin_options[i].scheme;
142 pinyin_set_double_pinyin_scheme (m_pinyin_context, scheme);
146 pinyin_option_t options = config->option() | USE_RESPLIT_TABLE;
147 pinyin_set_options (m_pinyin_context, options);
151 /* Here are the chewing keyboard scheme mapping table. */
152 static const struct {
153 gint bopomofo_keyboard;
154 ChewingScheme scheme;
155 } chewing_options [] = {
156 {0, CHEWING_STANDARD},
157 {1, CHEWING_GINYIEH},
164 LibPinyinBackEnd::setChewingOptions (Config *config)
166 if (NULL == m_chewing_context)
169 const gint map = config->bopomofoKeyboardMapping ();
170 for (guint i = 0; i < G_N_ELEMENTS (chewing_options); i++) {
171 if (map == chewing_options[i].bopomofo_keyboard) {
172 /* TODO: set chewing scheme. */
173 ChewingScheme scheme = chewing_options[i].scheme;
174 pinyin_set_chewing_scheme (m_chewing_context, scheme);
178 pinyin_option_t options = config->option() | USE_TONE;
179 pinyin_set_options(m_chewing_context, options);
184 LibPinyinBackEnd::modified (void)
186 /* Restart the timer */
187 g_timer_start (m_timer);
189 if (m_timeout_id != 0)
192 m_timeout_id = g_timeout_add_seconds (LIBPINYIN_SAVE_TIMEOUT,
193 LibPinyinBackEnd::timeoutCallback,
194 static_cast<gpointer> (this));
198 LibPinyinBackEnd::timeoutCallback (gpointer data)
200 LibPinyinBackEnd *self = static_cast<LibPinyinBackEnd *> (data);
202 /* Get the elapsed time since last modification of database. */
203 guint elapsed = (guint)g_timer_elapsed (self->m_timer, NULL);
205 if (elapsed >= LIBPINYIN_SAVE_TIMEOUT &&
206 self->saveUserDB ()) {
207 self->m_timeout_id = 0;
215 LibPinyinBackEnd::saveUserDB (void)
217 if (m_pinyin_context)
218 pinyin_save (m_pinyin_context);
219 if (m_chewing_context)
220 pinyin_save (m_chewing_context);