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.
28 const gchar * const CONFIG_CORRECT_PINYIN = "CorrectPinyin";
29 const gchar * const CONFIG_FUZZY_PINYIN = "FuzzyPinyin";
30 const gchar * const CONFIG_ORIENTATION = "LookupTableOrientation";
31 const gchar * const CONFIG_PAGE_SIZE = "LookupTablePageSize";
32 const gchar * const CONFIG_SHIFT_SELECT_CANDIDATE = "ShiftSelectCandidate";
33 const gchar * const CONFIG_MINUS_EQUAL_PAGE = "MinusEqualPage";
34 const gchar * const CONFIG_COMMA_PERIOD_PAGE = "CommaPeriodPage";
35 const gchar * const CONFIG_AUTO_COMMIT = "AutoCommit";
36 const gchar * const CONFIG_DOUBLE_PINYIN = "DoublePinyin";
37 const gchar * const CONFIG_DOUBLE_PINYIN_SCHEMA = "DoublePinyinSchema";
38 const gchar * const CONFIG_DOUBLE_PINYIN_SHOW_RAW = "DoublePinyinShowRaw";
39 const gchar * const CONFIG_INIT_CHINESE = "InitChinese";
40 const gchar * const CONFIG_INIT_FULL = "InitFull";
41 const gchar * const CONFIG_INIT_FULL_PUNCT = "InitFullPunct";
42 const gchar * const CONFIG_INIT_SIMP_CHINESE = "InitSimplifiedChinese";
43 const gchar * const CONFIG_SPECIAL_PHRASES = "SpecialPhrases";
44 const gchar * const CONFIG_BOPOMOFO_KEYBOARD_MAPPING = "BopomofoKeyboardMapping";
45 const gchar * const CONFIG_SELECT_KEYS = "SelectKeys";
46 const gchar * const CONFIG_GUIDE_KEY = "GuideKey";
47 const gchar * const CONFIG_AUXILIARY_SELECT_KEY_F = "AuxiliarySelectKey_F";
48 const gchar * const CONFIG_AUXILIARY_SELECT_KEY_KP = "AuxiliarySelectKey_KP";
49 const gchar * const CONFIG_ENTER_KEY = "EnterKey";
51 const guint PINYIN_DEFAULT_OPTION =
52 PINYIN_INCOMPLETE_PINYIN |
54 // PINYIN_FUZZY_CH_C |
56 // PINYIN_FUZZY_ZH_Z |
58 // PINYIN_FUZZY_SH_S |
73 // PINYIN_FUZZY_IAN_IANG |
74 // PINYIN_FUZZY_IANG_IAN |
75 // PINYIN_FUZZY_UAN_UANG |
76 // PINYIN_FUZZY_UANG_UAN |
80 Config::Config (Bus & bus, const std::string & name)
81 : Object (ibus_bus_get_config (bus)),
82 m_section ("engine/" + name)
85 g_signal_connect (get<IBusConfig> (),
87 G_CALLBACK (valueChangedCallback),
91 Config::~Config (void)
96 Config::initDefaultValues (void)
98 m_option = PINYIN_DEFAULT_OPTION;
99 m_option_mask = PINYIN_INCOMPLETE_PINYIN | PINYIN_CORRECT_ALL;
101 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
103 m_shift_select_candidate = FALSE;
104 m_minus_equal_page = TRUE;
105 m_comma_period_page = TRUE;
106 m_auto_commit = FALSE;
108 m_double_pinyin = FALSE;
109 m_double_pinyin_schema = 0;
110 m_double_pinyin_show_raw = FALSE;
112 m_init_chinese = TRUE;
114 m_init_full_punct = TRUE;
115 m_init_simp_chinese = TRUE;
116 m_special_phrases = TRUE;
119 static const struct {
120 const gchar * const name;
123 { "IncompletePinyin", PINYIN_INCOMPLETE_PINYIN},
125 { "FuzzyPinyin_C_CH", PINYIN_FUZZY_C_CH },
126 { "FuzzyPinyin_CH_C", PINYIN_FUZZY_CH_C },
127 { "FuzzyPinyin_Z_ZH", PINYIN_FUZZY_Z_ZH },
128 { "FuzzyPinyin_ZH_Z", PINYIN_FUZZY_ZH_Z },
129 { "FuzzyPinyin_S_SH", PINYIN_FUZZY_S_SH },
130 { "FuzzyPinyin_SH_S", PINYIN_FUZZY_SH_S },
131 { "FuzzyPinyin_L_N", PINYIN_FUZZY_L_N },
132 { "FuzzyPinyin_N_L", PINYIN_FUZZY_N_L },
133 { "FuzzyPinyin_F_H", PINYIN_FUZZY_F_H },
134 { "FuzzyPinyin_H_F", PINYIN_FUZZY_H_F },
135 { "FuzzyPinyin_L_R", PINYIN_FUZZY_L_R },
136 { "FuzzyPinyin_R_L", PINYIN_FUZZY_R_L },
137 { "FuzzyPinyin_K_G", PINYIN_FUZZY_K_G },
138 { "FuzzyPinyin_G_K", PINYIN_FUZZY_G_K },
139 { "FuzzyPinyin_AN_ANG", PINYIN_FUZZY_AN_ANG },
140 { "FuzzyPinyin_ANG_AN", PINYIN_FUZZY_ANG_AN },
141 { "FuzzyPinyin_EN_ENG", PINYIN_FUZZY_EN_ENG },
142 { "FuzzyPinyin_ENG_EN", PINYIN_FUZZY_ENG_EN },
143 { "FuzzyPinyin_IN_ING", PINYIN_FUZZY_IN_ING },
144 { "FuzzyPinyin_ING_IN", PINYIN_FUZZY_ING_IN },
146 { "FuzzyPinyin_IAN_IANG", PINYIN_FUZZY_IAN_IANG },
147 { "FuzzyPinyin_IANG_IAN", PINYIN_FUZZY_IANG_IAN },
148 { "FuzzyPinyin_UAN_UANG", PINYIN_FUZZY_UAN_UANG },
149 { "FuzzyPinyin_UANG_UAN", PINYIN_FUZZY_UANG_UAN },
154 Config::readDefaultValues (void)
156 #if defined(HAVE_IBUS_CONFIG_GET_VALUES)
157 /* read all values together */
158 initDefaultValues ();
160 ibus_config_get_values (get<IBusConfig> (), m_section.c_str ());
161 g_return_if_fail (values != NULL);
166 g_variant_iter_init (&iter, values);
167 while (g_variant_iter_next (&iter, "{sv}", &name, &value)) {
168 valueChanged (m_section, name, value);
170 g_variant_unref (value);
172 g_variant_unref (values);
175 m_orientation = read (CONFIG_ORIENTATION, 0);
176 if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
177 m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
178 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
179 g_warn_if_reached ();
181 m_page_size = read (CONFIG_PAGE_SIZE, 5);
182 if (m_page_size > 10) {
184 g_warn_if_reached ();
188 if (read (CONFIG_FUZZY_PINYIN, false))
189 m_option_mask |= PINYIN_FUZZY_ALL;
191 m_option_mask &= ~PINYIN_FUZZY_ALL;
194 for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
195 if (read (options[i].name,
196 (options[i].option & PINYIN_DEFAULT_OPTION) != 0)) {
197 m_option |= options[i].option;
200 m_option &= ~options[i].option;
207 Config::read (const gchar * name,
210 GVariant *value = NULL;
211 if ((value = ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name)) != NULL) {
212 if (g_variant_classify (value) == G_VARIANT_CLASS_BOOLEAN)
213 return g_variant_get_boolean (value);
216 // write default value to config
217 value = g_variant_new ("b", defval);
218 ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, value);
224 Config::read (const gchar * name,
227 GVariant *value = NULL;
228 if ((value = ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name)) != NULL) {
229 if (g_variant_classify (value) == G_VARIANT_CLASS_INT32)
230 return g_variant_get_int32 (value);
233 // write default value to config
234 value = g_variant_new ("i", defval);
235 ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, value);
241 Config::read (const gchar * name,
242 const gchar * defval)
244 GVariant *value = NULL;
245 if ((value = ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name)) != NULL) {
246 if (g_variant_classify (value) == G_VARIANT_CLASS_STRING)
247 return g_variant_get_string (value, NULL);
250 // write default value to config
251 value = g_variant_new ("s", defval);
252 ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, value);
258 normalizeGVariant (GVariant *value, bool defval)
260 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_BOOLEAN)
262 return g_variant_get_boolean (value);
266 normalizeGVariant (GVariant *value, gint defval)
268 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_INT32)
270 return g_variant_get_int32 (value);
273 static inline std::string
274 normalizeGVariant (GVariant *value, const std::string &defval)
276 if (value == NULL || g_variant_classify (value) != G_VARIANT_CLASS_STRING)
278 return g_variant_get_string (value, NULL);
282 Config::valueChanged (const std::string §ion,
283 const std::string &name,
286 if (m_section != section)
289 /* lookup table page size */
290 if (CONFIG_ORIENTATION == name) {
291 m_orientation = normalizeGVariant (value, IBUS_ORIENTATION_HORIZONTAL);
292 if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
293 m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
294 m_orientation = IBUS_ORIENTATION_HORIZONTAL;
295 g_warn_if_reached ();
298 else if (CONFIG_PAGE_SIZE == name) {
299 m_page_size = normalizeGVariant (value, 5);
300 if (m_page_size > 10) {
302 g_warn_if_reached ();
306 else if (CONFIG_FUZZY_PINYIN == name) {
307 if (normalizeGVariant (value, false))
308 m_option_mask |= PINYIN_FUZZY_ALL;
310 m_option_mask &= ~PINYIN_FUZZY_ALL;
313 for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
314 if (G_LIKELY (options[i].name != name))
316 if (normalizeGVariant (value,
317 (options[i].option & PINYIN_DEFAULT_OPTION) != 0))
318 m_option |= options[i].option;
320 m_option &= ~options[i].option;
329 Config::valueChangedCallback (IBusConfig *config,
330 const gchar *section,
335 self->valueChanged (section, name, value);