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);
70 setPinyinOptions (&LibPinyinPinyinConfig::instance ());
71 return pinyin_alloc_instance (m_pinyin_context);
75 LibPinyinBackEnd::freePinyinInstance (pinyin_instance_t *instance)
77 pinyin_free_instance (instance);
81 LibPinyinBackEnd::allocChewingInstance ()
83 if (NULL == m_chewing_context) {
84 gchar * userdir = g_build_filename (g_get_home_dir(), ".cache",
85 "ibus", "libbopomofo", NULL);
86 int retval = g_mkdir_with_parents (userdir, 0700);
88 g_free(userdir); userdir = NULL;
90 m_chewing_context = pinyin_init ("/usr/share/libpinyin/data", NULL);
94 setChewingOptions (&LibPinyinBopomofoConfig::instance ());
95 return pinyin_alloc_instance (m_chewing_context);
99 LibPinyinBackEnd::freeChewingInstance (pinyin_instance_t *instance)
101 pinyin_free_instance (instance);
105 LibPinyinBackEnd::init (void) {
106 g_assert (NULL == m_instance.get ());
107 LibPinyinBackEnd * backend = new LibPinyinBackEnd;
108 m_instance.reset (backend);
112 LibPinyinBackEnd::finalize (void) {
116 /* Here are the double pinyin keyboard scheme mapping table. */
118 gint double_pinyin_keyboard;
119 DoublePinyinScheme scheme;
120 } double_pinyin_options [] = {
121 {0, DOUBLE_PINYIN_MS},
122 {1, DOUBLE_PINYIN_ZRM},
123 {2, DOUBLE_PINYIN_ABC},
124 {3, DOUBLE_PINYIN_ZIGUANG},
125 {4, DOUBLE_PINYIN_PYJJ},
126 {5, DOUBLE_PINYIN_XHE}
130 LibPinyinBackEnd::setPinyinOptions (Config *config)
132 if (NULL == m_pinyin_context)
135 const gint map = config->doublePinyinSchema ();
136 for (guint i = 0; i < G_N_ELEMENTS (double_pinyin_options); i++) {
137 if (map == double_pinyin_options[i].double_pinyin_keyboard) {
138 /* set double pinyin scheme. */
139 DoublePinyinScheme scheme = double_pinyin_options[i].scheme;
140 pinyin_set_double_pinyin_scheme (m_pinyin_context, scheme);
144 pinyin_option_t options = config->option() | USE_RESPLIT_TABLE;
145 pinyin_set_options (m_pinyin_context, options);
149 /* Here are the chewing keyboard scheme mapping table. */
150 static const struct {
151 gint bopomofo_keyboard;
152 ChewingScheme scheme;
153 } chewing_options [] = {
154 {0, CHEWING_STANDARD},
155 {1, CHEWING_GINYIEH},
162 LibPinyinBackEnd::setChewingOptions (Config *config)
164 if (NULL == m_chewing_context)
167 const gint map = config->bopomofoKeyboardMapping ();
168 for (guint i = 0; i < G_N_ELEMENTS (chewing_options); i++) {
169 if (map == chewing_options[i].bopomofo_keyboard) {
170 /* TODO: set chewing scheme. */
171 ChewingScheme scheme = chewing_options[i].scheme;
172 pinyin_set_chewing_scheme (m_chewing_context, scheme);
176 pinyin_option_t options = config->option() | USE_TONE;
177 pinyin_set_options(m_chewing_context, options);
182 LibPinyinBackEnd::modified (void)
184 /* Restart the timer */
185 g_timer_start (m_timer);
187 if (m_timeout_id != 0)
190 m_timeout_id = g_timeout_add_seconds (LIBPINYIN_SAVE_TIMEOUT,
191 LibPinyinBackEnd::timeoutCallback,
192 static_cast<gpointer> (this));
196 LibPinyinBackEnd::timeoutCallback (gpointer data)
198 LibPinyinBackEnd *self = static_cast<LibPinyinBackEnd *> (data);
200 /* Get the elapsed time since last modification of database. */
201 guint elapsed = (guint)g_timer_elapsed (self->m_timer, NULL);
203 if (elapsed >= LIBPINYIN_SAVE_TIMEOUT &&
204 self->saveUserDB ()) {
205 self->m_timeout_id = 0;
213 LibPinyinBackEnd::saveUserDB (void)
215 if (m_pinyin_context)
216 pinyin_save (m_pinyin_context);
217 if (m_chewing_context)
218 pinyin_save (m_chewing_context);