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.
25 #include "PYDoublePinyinTable.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 =
53 PINYIN_INCOMPLETE_PINYIN |
55 // PINYIN_FUZZY_CH_C |
57 // PINYIN_FUZZY_ZH_Z |
59 // PINYIN_FUZZY_SH_S |
74 // PINYIN_FUZZY_IAN_IANG |
75 // PINYIN_FUZZY_IANG_IAN |
76 // PINYIN_FUZZY_UAN_UANG |
77 // PINYIN_FUZZY_UANG_UAN |
80 std::unique_ptr<PinyinConfig> PinyinConfig::m_instance;
81 std::unique_ptr<BopomofoConfig> BopomofoConfig::m_instance;
83 Config::Config (Bus & bus, const std::string & name)
84 : Object (ibus_bus_get_config (bus)),
85 m_section ("engine/" + name)
88 g_signal_connect (get<IBusConfig> (),
90 G_CALLBACK (valueChangedCallback),
94 Config::~Config (void)
99 Config::initDefaultValues (void)
101 m_option = PINYIN_DEFAULT_OPTION;
102 m_option_mask = PINYIN_INCOMPLETE_PINYIN | PINYIN_CORRECT_ALL;
104 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
106 m_shift_select_candidate = FALSE;
107 m_minus_equal_page = TRUE;
108 m_comma_period_page = TRUE;
109 m_auto_commit = FALSE;
111 m_double_pinyin = FALSE;
112 m_double_pinyin_schema = 0;
113 m_double_pinyin_show_raw = FALSE;
115 m_init_chinese = TRUE;
117 m_init_full_punct = TRUE;
118 m_init_simp_chinese = TRUE;
119 m_special_phrases = TRUE;
122 static const struct {
123 const gchar * const name;
126 { "IncompletePinyin", PINYIN_INCOMPLETE_PINYIN},
128 { "FuzzyPinyin_C_CH", PINYIN_FUZZY_C_CH },
129 { "FuzzyPinyin_CH_C", PINYIN_FUZZY_CH_C },
130 { "FuzzyPinyin_Z_ZH", PINYIN_FUZZY_Z_ZH },
131 { "FuzzyPinyin_ZH_Z", PINYIN_FUZZY_ZH_Z },
132 { "FuzzyPinyin_S_SH", PINYIN_FUZZY_S_SH },
133 { "FuzzyPinyin_SH_S", PINYIN_FUZZY_SH_S },
134 { "FuzzyPinyin_L_N", PINYIN_FUZZY_L_N },
135 { "FuzzyPinyin_N_L", PINYIN_FUZZY_N_L },
136 { "FuzzyPinyin_F_H", PINYIN_FUZZY_F_H },
137 { "FuzzyPinyin_H_F", PINYIN_FUZZY_H_F },
138 { "FuzzyPinyin_L_R", PINYIN_FUZZY_L_R },
139 { "FuzzyPinyin_R_L", PINYIN_FUZZY_R_L },
140 { "FuzzyPinyin_K_G", PINYIN_FUZZY_K_G },
141 { "FuzzyPinyin_G_K", PINYIN_FUZZY_G_K },
142 { "FuzzyPinyin_AN_ANG", PINYIN_FUZZY_AN_ANG },
143 { "FuzzyPinyin_ANG_AN", PINYIN_FUZZY_ANG_AN },
144 { "FuzzyPinyin_EN_ENG", PINYIN_FUZZY_EN_ENG },
145 { "FuzzyPinyin_ENG_EN", PINYIN_FUZZY_ENG_EN },
146 { "FuzzyPinyin_IN_ING", PINYIN_FUZZY_IN_ING },
147 { "FuzzyPinyin_ING_IN", PINYIN_FUZZY_ING_IN },
149 { "FuzzyPinyin_IAN_IANG", PINYIN_FUZZY_IAN_IANG },
150 { "FuzzyPinyin_IANG_IAN", PINYIN_FUZZY_IANG_IAN },
151 { "FuzzyPinyin_UAN_UANG", PINYIN_FUZZY_UAN_UANG },
152 { "FuzzyPinyin_UANG_UAN", PINYIN_FUZZY_UANG_UAN },
157 Config::readDefaultValues (void)
159 #if defined(HAVE_IBUS_CONFIG_GET_VALUES)
160 /* read all values together */
161 initDefaultValues ();
163 ibus_config_get_values (get<IBusConfig> (), m_section.c_str ());
164 g_return_if_fail (values != NULL);
169 g_variant_iter_init (&iter, values);
170 while (g_variant_iter_next (&iter, "{sv}", &name, &value)) {
171 valueChanged (m_section, name, value);
173 g_variant_unref (value);
175 g_variant_unref (values);
178 m_orientation = read (CONFIG_ORIENTATION, 0);
179 if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
180 m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
181 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
182 g_warn_if_reached ();
184 m_page_size = read (CONFIG_PAGE_SIZE, 5);
185 if (m_page_size > 10) {
187 g_warn_if_reached ();
191 if (read (CONFIG_FUZZY_PINYIN, false))
192 m_option_mask |= PINYIN_FUZZY_ALL;
194 m_option_mask &= ~PINYIN_FUZZY_ALL;
197 for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
198 if (read (options[i].name,
199 (options[i].option & PINYIN_DEFAULT_OPTION) != 0)) {
200 m_option |= options[i].option;
203 m_option &= ~options[i].option;
210 Config::read (const gchar * name,
213 GVariant *value = NULL;
214 if ((value = ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name)) != NULL) {
215 if (g_variant_classify (value) == G_VARIANT_CLASS_BOOLEAN)
216 return g_variant_get_boolean (value);
219 // write default value to config
220 value = g_variant_new ("b", defval);
221 ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, value);
227 Config::read (const gchar * name,
230 GVariant *value = NULL;
231 if ((value = ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name)) != NULL) {
232 if (g_variant_classify (value) == G_VARIANT_CLASS_INT32)
233 return g_variant_get_int32 (value);
236 // write default value to config
237 value = g_variant_new ("i", defval);
238 ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, value);
244 Config::read (const gchar * name,
245 const gchar * defval)
247 GVariant *value = NULL;
248 if ((value = ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name)) != NULL) {
249 if (g_variant_classify (value) == G_VARIANT_CLASS_STRING)
250 return g_variant_get_string (value, NULL);
253 // write default value to config
254 value = g_variant_new ("s", defval);
255 ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, value);
261 normalizeGVariant (GVariant *value, bool defval)
263 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_BOOLEAN)
265 return g_variant_get_boolean (value);
269 normalizeGVariant (GVariant *value, gint defval)
271 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_INT32)
273 return g_variant_get_int32 (value);
276 static inline std::string
277 normalizeGVariant (GVariant *value, const std::string &defval)
279 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_STRING)
281 return g_variant_get_string (value, NULL);
285 Config::valueChanged (const std::string §ion,
286 const std::string &name,
289 if (m_section != section)
292 /* lookup table page size */
293 if (CONFIG_ORIENTATION == name) {
294 m_orientation = normalizeGVariant (value, IBUS_ORIENTATION_HORIZONTAL);
295 if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
296 m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
297 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
298 g_warn_if_reached ();
301 else if (CONFIG_PAGE_SIZE == name) {
302 m_page_size = normalizeGVariant (value, 5);
303 if (m_page_size > 10) {
305 g_warn_if_reached ();
309 else if (CONFIG_FUZZY_PINYIN == name) {
310 if (normalizeGVariant (value, false))
311 m_option_mask |= PINYIN_FUZZY_ALL;
313 m_option_mask &= ~PINYIN_FUZZY_ALL;
316 for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
317 if (G_LIKELY (options[i].name != name))
319 if (normalizeGVariant (value,
320 (options[i].option & PINYIN_DEFAULT_OPTION) != 0))
321 m_option |= options[i].option;
323 m_option &= ~options[i].option;
332 Config::valueChangedCallback (IBusConfig *config,
333 const gchar *section,
338 self->valueChanged (section, name, value);