1 /* vim:set et ts=4 sts=4:
3 * ibus-pinyin - The Chinese PinYin engine for IBus
5 * Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "PYPConfig.h"
25 #include "PYLibPinyin.h"
29 const gchar * const CONFIG_CORRECT_PINYIN = "CorrectPinyin";
30 const gchar * const CONFIG_FUZZY_PINYIN = "FuzzyPinyin";
31 const gchar * const CONFIG_ORIENTATION = "LookupTableOrientation";
32 const gchar * const CONFIG_PAGE_SIZE = "LookupTablePageSize";
33 const gchar * const CONFIG_SHIFT_SELECT_CANDIDATE = "ShiftSelectCandidate";
34 const gchar * const CONFIG_MINUS_EQUAL_PAGE = "MinusEqualPage";
35 const gchar * const CONFIG_COMMA_PERIOD_PAGE = "CommaPeriodPage";
36 const gchar * const CONFIG_AUTO_COMMIT = "AutoCommit";
37 const gchar * const CONFIG_DOUBLE_PINYIN = "DoublePinyin";
38 const gchar * const CONFIG_DOUBLE_PINYIN_SCHEMA = "DoublePinyinSchema";
39 const gchar * const CONFIG_DOUBLE_PINYIN_SHOW_RAW = "DoublePinyinShowRaw";
40 const gchar * const CONFIG_INIT_CHINESE = "InitChinese";
41 const gchar * const CONFIG_INIT_FULL = "InitFull";
42 const gchar * const CONFIG_INIT_FULL_PUNCT = "InitFullPunct";
43 const gchar * const CONFIG_INIT_SIMP_CHINESE = "InitSimplifiedChinese";
44 const gchar * const CONFIG_SPECIAL_PHRASES = "SpecialPhrases";
45 const gchar * const CONFIG_BOPOMOFO_KEYBOARD_MAPPING = "BopomofoKeyboardMapping";
46 const gchar * const CONFIG_SELECT_KEYS = "SelectKeys";
47 const gchar * const CONFIG_GUIDE_KEY = "GuideKey";
48 const gchar * const CONFIG_AUXILIARY_SELECT_KEY_F = "AuxiliarySelectKey_F";
49 const gchar * const CONFIG_AUXILIARY_SELECT_KEY_KP = "AuxiliarySelectKey_KP";
50 const gchar * const CONFIG_ENTER_KEY = "EnterKey";
52 const guint PINYIN_DEFAULT_OPTION =
58 std::unique_ptr<LibPinyinPinyinConfig> LibPinyinPinyinConfig::m_instance;
59 std::unique_ptr<LibPinyinBopomofoConfig> LibPinyinBopomofoConfig::m_instance;
61 LibPinyinConfig::LibPinyinConfig (Bus & bus, const std::string & name)
65 g_signal_connect (get<IBusConfig> (),
67 G_CALLBACK (valueChangedCallback),
71 LibPinyinConfig::~LibPinyinConfig (void)
76 LibPinyinConfig::initDefaultValues (void)
78 m_option = PINYIN_DEFAULT_OPTION;
79 m_option_mask = PINYIN_INCOMPLETE | CHEWING_INCOMPLETE | PINYIN_CORRECT_ALL;
81 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
83 m_shift_select_candidate = FALSE;
84 m_minus_equal_page = TRUE;
85 m_comma_period_page = TRUE;
86 m_auto_commit = FALSE;
88 m_double_pinyin = FALSE;
89 m_double_pinyin_schema = 0;
90 m_double_pinyin_show_raw = FALSE;
92 m_init_chinese = TRUE;
94 m_init_full_punct = TRUE;
95 m_init_simp_chinese = TRUE;
96 m_special_phrases = TRUE;
100 const gchar * const name;
103 { "IncompletePinyin", PINYIN_INCOMPLETE|CHEWING_INCOMPLETE},
105 { "FuzzyPinyin_C_CH", PINYIN_AMB_C_CH },
106 { "FuzzyPinyin_Z_ZH", PINYIN_AMB_Z_ZH },
107 { "FuzzyPinyin_S_SH", PINYIN_AMB_S_SH },
108 { "FuzzyPinyin_L_N", PINYIN_AMB_L_N },
109 { "FuzzyPinyin_F_H", PINYIN_AMB_F_H },
110 { "FuzzyPinyin_L_R", PINYIN_AMB_L_R },
111 { "FuzzyPinyin_G_K", PINYIN_AMB_G_K },
112 { "FuzzyPinyin_AN_ANG", PINYIN_AMB_AN_ANG },
113 { "FuzzyPinyin_EN_ENG", PINYIN_AMB_EN_ENG },
114 { "FuzzyPinyin_IN_ING", PINYIN_AMB_IN_ING },
118 LibPinyinConfig::readDefaultValues (void)
120 #if defined(HAVE_IBUS_CONFIG_GET_VALUES)
121 /* read all values together */
122 initDefaultValues ();
124 ibus_config_get_values (get<IBusConfig> (), m_section.c_str ());
125 g_return_if_fail (values != NULL);
130 g_variant_iter_init (&iter, values);
131 while (g_variant_iter_next (&iter, "{sv}", &name, &value)) {
132 valueChanged (m_section, name, value);
134 g_variant_unref (value);
136 g_variant_unref (values);
139 m_orientation = read (CONFIG_ORIENTATION, 0);
140 if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
141 m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
142 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
143 g_warn_if_reached ();
145 m_page_size = read (CONFIG_PAGE_SIZE, 5);
146 if (m_page_size > 10) {
148 g_warn_if_reached ();
152 if (read (CONFIG_FUZZY_PINYIN, false))
153 m_option_mask |= PINYIN_AMB_ALL;
155 m_option_mask &= ~PINYIN_AMB_ALL;
158 for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
159 if (read (options[i].name,
160 (options[i].option & PINYIN_DEFAULT_OPTION) != 0)) {
161 m_option |= options[i].option;
164 m_option &= ~options[i].option;
172 normalizeGVariant (GVariant *value, bool defval)
174 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_BOOLEAN)
176 return g_variant_get_boolean (value);
180 normalizeGVariant (GVariant *value, gint defval)
182 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_INT32)
184 return g_variant_get_int32 (value);
187 static inline std::string
188 normalizeGVariant (GVariant *value, const std::string &defval)
190 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_STRING)
192 return g_variant_get_string (value, NULL);
196 LibPinyinConfig::valueChanged (const std::string §ion,
197 const std::string &name,
200 if (m_section != section)
203 /* lookup table page size */
204 if (CONFIG_ORIENTATION == name) {
205 m_orientation = normalizeGVariant (value, IBUS_ORIENTATION_HORIZONTAL);
206 if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
207 m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
208 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
209 g_warn_if_reached ();
212 else if (CONFIG_PAGE_SIZE == name) {
213 m_page_size = normalizeGVariant (value, 5);
214 if (m_page_size > 10) {
216 g_warn_if_reached ();
220 else if (CONFIG_FUZZY_PINYIN == name) {
221 if (normalizeGVariant (value, false))
222 m_option_mask |= PINYIN_AMB_ALL;
224 m_option_mask &= ~PINYIN_AMB_ALL;
227 for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
228 if (G_LIKELY (options[i].name != name))
230 if (normalizeGVariant (value,
231 (options[i].option & PINYIN_DEFAULT_OPTION) != 0))
232 m_option |= options[i].option;
234 m_option &= ~options[i].option;
243 LibPinyinConfig::valueChangedCallback (IBusConfig *config,
244 const gchar *section,
247 LibPinyinConfig *self)
249 self->valueChanged (section, name, value);
250 if (self->m_section != section)
252 #ifdef IBUS_BUILD_LIBPINYIN
253 if (self->m_section == "engine/Pinyin")
254 LibPinyinBackEnd::instance ().setPinyinOptions (self);
255 if (self->m_section == "engine/Bopomofo")
256 LibPinyinBackEnd::instance ().setChewingOptions (self);
260 static const struct {
261 const gchar * const name;
263 } pinyin_options [] = {
265 { "CorrectPinyin_GN_NG", PINYIN_CORRECT_GN_NG },
266 { "CorrectPinyin_GN_NG", PINYIN_CORRECT_GN_NG },
267 { "CorrectPinyin_MG_NG", PINYIN_CORRECT_MG_NG },
268 { "CorrectPinyin_IOU_IU", PINYIN_CORRECT_IOU_IU },
269 { "CorrectPinyin_UEI_UI", PINYIN_CORRECT_UEI_UI },
270 { "CorrectPinyin_UEN_UN", PINYIN_CORRECT_UEN_UN },
271 { "CorrectPinyin_UE_VE", PINYIN_CORRECT_UE_VE },
272 { "CorrectPinyin_V_U", PINYIN_CORRECT_V_U },
273 { "CorrectPinyin_VE_UE", PINYIN_CORRECT_V_U },
274 { "CorrectPinyin_ON_ONG", PINYIN_CORRECT_ON_ONG },
277 LibPinyinPinyinConfig::LibPinyinPinyinConfig (Bus & bus)
278 : LibPinyinConfig (bus, "Pinyin")
283 LibPinyinPinyinConfig::init (Bus & bus)
285 if (m_instance.get () == NULL) {
286 m_instance.reset (new LibPinyinPinyinConfig (bus));
287 m_instance->readDefaultValues ();
292 LibPinyinPinyinConfig::readDefaultValues (void)
294 LibPinyinConfig::readDefaultValues ();
295 #if !defined(HAVE_IBUS_CONFIG_GET_VALUES)
297 m_double_pinyin = read (CONFIG_DOUBLE_PINYIN, false);
298 m_double_pinyin_schema = read (CONFIG_DOUBLE_PINYIN_SCHEMA, 0);
299 if (m_double_pinyin_schema > DOUBLE_PINYIN_LAST) {
300 m_double_pinyin_schema = 0;
301 g_warn_if_reached ();
303 m_double_pinyin_show_raw = read (CONFIG_DOUBLE_PINYIN_SHOW_RAW, false);
306 m_init_chinese = read (CONFIG_INIT_CHINESE, true);
307 m_init_full = read (CONFIG_INIT_FULL, false);
308 m_init_full_punct = read (CONFIG_INIT_FULL_PUNCT, true);
309 m_init_simp_chinese = read (CONFIG_INIT_SIMP_CHINESE, true);
311 m_special_phrases = read (CONFIG_SPECIAL_PHRASES, true);
314 m_shift_select_candidate = read (CONFIG_SHIFT_SELECT_CANDIDATE, false);
315 m_minus_equal_page = read (CONFIG_MINUS_EQUAL_PAGE, true);
316 m_comma_period_page = read (CONFIG_COMMA_PERIOD_PAGE, true);
317 m_auto_commit = read (CONFIG_AUTO_COMMIT, false);
320 if (read (CONFIG_CORRECT_PINYIN, true))
321 m_option_mask |= PINYIN_CORRECT_ALL;
323 m_option_mask &= ~PINYIN_CORRECT_ALL;
326 for (guint i = 0; i < G_N_ELEMENTS (pinyin_options); i++) {
327 if (read (pinyin_options[i].name,
328 (pinyin_options[i].option & PINYIN_DEFAULT_OPTION) != 0))
329 m_option |= pinyin_options[i].option;
331 m_option &= ~pinyin_options[i].option;
337 LibPinyinPinyinConfig::valueChanged (const std::string §ion,
338 const std::string &name,
341 if (m_section != section)
344 if (LibPinyinConfig::valueChanged (section, name, value))
348 if (CONFIG_DOUBLE_PINYIN == name)
349 m_double_pinyin = normalizeGVariant (value, false);
350 else if (CONFIG_DOUBLE_PINYIN_SCHEMA == name) {
351 m_double_pinyin_schema = normalizeGVariant (value, 0);
353 if (m_double_pinyin_schema > DOUBLE_PINYIN_LAST) {
354 m_double_pinyin_schema = 0;
355 g_warn_if_reached ();
359 else if (CONFIG_DOUBLE_PINYIN_SHOW_RAW == name)
360 m_double_pinyin_show_raw = normalizeGVariant (value, false);
362 else if (CONFIG_INIT_CHINESE == name)
363 m_init_chinese = normalizeGVariant (value, true);
364 else if (CONFIG_INIT_FULL == name)
365 m_init_full = normalizeGVariant (value, true);
366 else if (CONFIG_INIT_FULL_PUNCT == name)
367 m_init_full_punct = normalizeGVariant (value, true);
368 else if (CONFIG_INIT_SIMP_CHINESE == name)
369 m_init_simp_chinese = normalizeGVariant (value, true);
370 else if (CONFIG_SPECIAL_PHRASES == name)
371 m_special_phrases = normalizeGVariant (value, true);
373 else if (CONFIG_SHIFT_SELECT_CANDIDATE == name)
374 m_shift_select_candidate = normalizeGVariant (value, false);
375 else if (CONFIG_MINUS_EQUAL_PAGE == name)
376 m_minus_equal_page = normalizeGVariant (value, true);
377 else if (CONFIG_COMMA_PERIOD_PAGE == name)
378 m_comma_period_page = normalizeGVariant (value, true);
379 else if (CONFIG_AUTO_COMMIT == name)
380 m_auto_commit = normalizeGVariant (value, false);
382 else if (CONFIG_CORRECT_PINYIN == name) {
383 if (normalizeGVariant (value, true))
384 m_option_mask |= PINYIN_CORRECT_ALL;
386 m_option_mask &= ~PINYIN_CORRECT_ALL;
389 for (guint i = 0; i < G_N_ELEMENTS (pinyin_options); i++) {
390 if (G_LIKELY (pinyin_options[i].name != name))
392 if (normalizeGVariant (value,
393 (pinyin_options[i].option & PINYIN_DEFAULT_OPTION) != 0))
394 m_option |= pinyin_options[i].option;
396 m_option &= ~pinyin_options[i].option;
404 LibPinyinBopomofoConfig::LibPinyinBopomofoConfig (Bus & bus)
405 : LibPinyinConfig (bus, "Bopomofo")
410 LibPinyinBopomofoConfig::init (Bus & bus)
412 if (m_instance.get () == NULL) {
413 m_instance.reset (new LibPinyinBopomofoConfig (bus));
414 m_instance->readDefaultValues ();
419 LibPinyinBopomofoConfig::readDefaultValues (void)
421 LibPinyinConfig::readDefaultValues ();
422 #if !defined(HAVE_IBUS_CONFIG_GET_VALUES)
424 m_init_chinese = read (CONFIG_INIT_CHINESE, true);
425 m_init_full = read (CONFIG_INIT_FULL, false);
426 m_init_full_punct = read (CONFIG_INIT_FULL_PUNCT, true);
427 m_init_simp_chinese = read (CONFIG_INIT_SIMP_CHINESE, false);
429 m_special_phrases = read (CONFIG_SPECIAL_PHRASES, false);
431 m_bopomofo_keyboard_mapping = read (CONFIG_BOPOMOFO_KEYBOARD_MAPPING, 0);
433 m_select_keys = read (CONFIG_SELECT_KEYS, 0);
434 if (m_select_keys >= 9) m_select_keys = 0;
435 m_guide_key = read (CONFIG_GUIDE_KEY, true);
436 m_auxiliary_select_key_f = read (CONFIG_AUXILIARY_SELECT_KEY_F, true);
437 m_auxiliary_select_key_kp = read (CONFIG_AUXILIARY_SELECT_KEY_KP, true);
438 m_enter_key = read (CONFIG_ENTER_KEY, true);
443 LibPinyinBopomofoConfig::valueChanged (const std::string §ion,
444 const std::string &name,
447 if (m_section != section)
450 if (LibPinyinConfig::valueChanged (section, name, value))
454 if (CONFIG_INIT_CHINESE == name)
455 m_init_chinese = normalizeGVariant (value, true);
456 else if (CONFIG_INIT_FULL == name)
457 m_init_full = normalizeGVariant (value, true);
458 else if (CONFIG_INIT_FULL_PUNCT == name)
459 m_init_full_punct = normalizeGVariant (value, true);
460 else if (CONFIG_INIT_SIMP_CHINESE == name)
461 m_init_simp_chinese = normalizeGVariant (value, false);
462 else if (CONFIG_SPECIAL_PHRASES == name)
463 m_special_phrases = normalizeGVariant (value, false);
464 else if (CONFIG_BOPOMOFO_KEYBOARD_MAPPING == name)
465 m_bopomofo_keyboard_mapping = normalizeGVariant (value, 0);
466 else if (CONFIG_SELECT_KEYS == name) {
467 m_select_keys = normalizeGVariant (value, 0);
468 if (m_select_keys >= 9) m_select_keys = 0;
470 else if (CONFIG_GUIDE_KEY == name)
471 m_guide_key = normalizeGVariant (value, true);
472 else if (CONFIG_AUXILIARY_SELECT_KEY_F == name)
473 m_auxiliary_select_key_f = normalizeGVariant (value, true);
474 else if (CONFIG_AUXILIARY_SELECT_KEY_KP == name)
475 m_auxiliary_select_key_kp = normalizeGVariant (value, true);
476 else if (CONFIG_ENTER_KEY == name)
477 m_enter_key = normalizeGVariant (value, true);