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 "DoublePinyinTable.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";
51
boost::scoped_ptr<PinyinConfig> PinyinConfig::m_instance;
52
boost::scoped_ptr<BopomofoConfig> BopomofoConfig::m_instance;
54
Config::Config (Bus & bus, const std::string & name)
55
: Object (ibus_bus_get_config (bus)),
56
m_section ("engine/" + name)
58
m_option = PINYIN_INCOMPLETE_PINYIN | PINYIN_CORRECT_ALL;
59
m_option_mask = PINYIN_INCOMPLETE_PINYIN | PINYIN_CORRECT_ALL;
61
m_orientation = IBUS_ORIENTATION_HORIZONTAL;
63
m_shift_select_candidate = FALSE;
64
m_minus_equal_page = TRUE;
65
m_comma_period_page = TRUE;
66
m_auto_commit = FALSE;
68
m_double_pinyin = FALSE;
69
m_double_pinyin_schema = 0;
70
m_double_pinyin_show_raw = FALSE;
72
m_init_chinese = TRUE;
74
m_init_full_punct = TRUE;
75
m_init_simp_chinese = TRUE;
76
m_special_phrases = TRUE;
78
g_signal_connect (get<IBusConfig> (),
80
G_CALLBACK (valueChangedCallback),
84
Config::~Config (void)
89
const gchar * const name;
93
{ "IncompletePinyin", PINYIN_INCOMPLETE_PINYIN, TRUE },
95
{ "FuzzyPinyin_C_CH", PINYIN_FUZZY_C_CH, FALSE },
96
{ "FuzzyPinyin_CH_C", PINYIN_FUZZY_CH_C, FALSE },
97
{ "FuzzyPinyin_Z_ZH", PINYIN_FUZZY_Z_ZH, FALSE },
98
{ "FuzzyPinyin_ZH_Z", PINYIN_FUZZY_ZH_Z, FALSE },
99
{ "FuzzyPinyin_S_SH", PINYIN_FUZZY_S_SH, FALSE },
100
{ "FuzzyPinyin_SH_S", PINYIN_FUZZY_SH_S, FALSE },
101
{ "FuzzyPinyin_L_N", PINYIN_FUZZY_L_N, FALSE },
102
{ "FuzzyPinyin_N_L", PINYIN_FUZZY_N_L, FALSE },
103
{ "FuzzyPinyin_F_H", PINYIN_FUZZY_F_H, FALSE },
104
{ "FuzzyPinyin_H_F", PINYIN_FUZZY_H_F, FALSE },
105
{ "FuzzyPinyin_L_R", PINYIN_FUZZY_L_R, FALSE },
106
{ "FuzzyPinyin_R_L", PINYIN_FUZZY_R_L, FALSE },
107
{ "FuzzyPinyin_K_G", PINYIN_FUZZY_K_G, FALSE },
108
{ "FuzzyPinyin_G_K", PINYIN_FUZZY_G_K, FALSE },
109
{ "FuzzyPinyin_AN_ANG", PINYIN_FUZZY_AN_ANG, FALSE },
110
{ "FuzzyPinyin_ANG_AN", PINYIN_FUZZY_ANG_AN, FALSE },
111
{ "FuzzyPinyin_EN_ENG", PINYIN_FUZZY_EN_ENG, FALSE },
112
{ "FuzzyPinyin_ENG_EN", PINYIN_FUZZY_ENG_EN, FALSE },
113
{ "FuzzyPinyin_IN_ING", PINYIN_FUZZY_IN_ING, FALSE },
114
{ "FuzzyPinyin_ING_IN", PINYIN_FUZZY_ING_IN, FALSE },
115
{ "FuzzyPinyin_IAN_IANG", PINYIN_FUZZY_IAN_IANG, FALSE },
116
{ "FuzzyPinyin_IANG_IAN", PINYIN_FUZZY_IANG_IAN, FALSE },
117
{ "FuzzyPinyin_UAN_UANG", PINYIN_FUZZY_UAN_UANG, FALSE },
118
{ "FuzzyPinyin_UANG_UAN", PINYIN_FUZZY_UANG_UAN, FALSE },
122
Config::readDefaultValues (void)
125
m_orientation = read (CONFIG_ORIENTATION, 0);
126
if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
127
m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
128
m_orientation = IBUS_ORIENTATION_HORIZONTAL;
129
g_warn_if_reached ();
131
m_page_size = read (CONFIG_PAGE_SIZE, 5);
132
if (m_page_size > 10) {
134
g_warn_if_reached ();
138
if (read (CONFIG_FUZZY_PINYIN, false))
139
m_option_mask |= PINYIN_FUZZY_ALL;
141
m_option_mask &= ~PINYIN_FUZZY_ALL;
144
for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
145
if (read (options[i].name, options[i].defval))
146
m_option |= options[i].option;
148
m_option &= ~options[i].option;
153
Config::read (const gchar * name,
157
if (ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name, &value)) {
158
if (G_VALUE_TYPE (&value) == G_TYPE_BOOLEAN)
159
return g_value_get_boolean (&value);
162
// write default value to config
163
g_value_init (&value, G_TYPE_BOOLEAN);
164
g_value_set_boolean (&value, defval);
165
ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, &value);
171
Config::read (const gchar * name,
175
if (ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name, &value)) {
176
if (G_VALUE_TYPE (&value) == G_TYPE_INT)
177
return g_value_get_int (&value);
180
// write default value to config
181
g_value_init (&value, G_TYPE_INT);
182
g_value_set_int (&value, defval);
183
ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, &value);
189
Config::read (const gchar * name,
190
const gchar * defval)
193
if (ibus_config_get_value (get<IBusConfig> (), m_section.c_str (), name, &value)) {
194
if (G_VALUE_TYPE (&value) == G_TYPE_STRING)
195
return g_value_get_string (&value);
198
// write default value to config
199
g_value_init (&value, G_TYPE_STRING);
200
g_value_set_static_string (&value, defval);
201
ibus_config_set_value (get<IBusConfig> (), m_section.c_str (), name, &value);
207
normalizeGValue (const GValue *value, bool defval)
209
if (value == NULL || G_VALUE_TYPE (value) != G_TYPE_BOOLEAN)
211
return g_value_get_boolean (value);
215
normalizeGValue (const GValue *value, gint defval)
217
if (value == NULL || G_VALUE_TYPE (value) != G_TYPE_INT)
219
return g_value_get_int (value);
222
static inline const gchar *
223
normalizeGValue (const GValue *value, const gchar * defval)
225
if (value == NULL || G_VALUE_TYPE (value) != G_TYPE_STRING)
227
return g_value_get_string (value);
231
Config::valueChanged (const std::string & section,
232
const std::string & name,
235
if (m_section != section)
238
/* lookup table page size */
239
if (CONFIG_ORIENTATION == name) {
240
m_orientation = normalizeGValue (value, 0);
241
if (m_orientation != IBUS_ORIENTATION_VERTICAL &&
242
m_orientation != IBUS_ORIENTATION_HORIZONTAL) {
243
m_orientation = IBUS_ORIENTATION_HORIZONTAL;
244
g_warn_if_reached ();
247
else if (CONFIG_PAGE_SIZE == name) {
248
m_page_size = normalizeGValue (value, 5);
249
if (m_page_size > 10) {
251
g_warn_if_reached ();
255
else if (CONFIG_FUZZY_PINYIN == name) {
256
if (normalizeGValue (value, TRUE))
257
m_option_mask |= PINYIN_FUZZY_ALL;
259
m_option_mask &= ~PINYIN_FUZZY_ALL;
262
for (guint i = 0; i < G_N_ELEMENTS (options); i++) {
263
if (G_LIKELY (options[i].name != name))
265
if (normalizeGValue (value, options[i].defval))
266
m_option |= options[i].option;
268
m_option &= ~options[i].option;
278
Config::valueChangedCallback (IBusConfig *config,
279
const gchar *section,
284
self->valueChanged (section, name, value);
289
static const struct {
290
const gchar * const name;
293
} pinyin_options [] = {
295
{ "CorrectPinyin_GN_NG", PINYIN_CORRECT_GN_TO_NG, TRUE },
296
{ "CorrectPinyin_GN_NG", PINYIN_CORRECT_GN_TO_NG, TRUE },
297
{ "CorrectPinyin_MG_NG", PINYIN_CORRECT_MG_TO_NG, TRUE },
298
{ "CorrectPinyin_IOU_IU", PINYIN_CORRECT_IOU_TO_IU, TRUE },
299
{ "CorrectPinyin_UEI_UI", PINYIN_CORRECT_UEI_TO_UI, TRUE },
300
{ "CorrectPinyin_UEN_UN", PINYIN_CORRECT_UEN_TO_UN, TRUE },
301
{ "CorrectPinyin_UE_VE", PINYIN_CORRECT_UE_TO_VE, TRUE },
302
{ "CorrectPinyin_V_U", PINYIN_CORRECT_V_TO_U, TRUE },
303
{ "CorrectPinyin_VE_UE", PINYIN_CORRECT_V_TO_U, TRUE },
306
PinyinConfig::PinyinConfig (Bus & bus)
307
: Config (bus, "Pinyin")
312
PinyinConfig::init (Bus & bus)
314
if (m_instance == NULL) {
315
m_instance.reset (new PinyinConfig (bus));
316
m_instance->readDefaultValues ();
321
PinyinConfig::readDefaultValues (void)
323
Config::readDefaultValues ();
325
m_double_pinyin = read (CONFIG_DOUBLE_PINYIN, false);
326
m_double_pinyin_schema = read (CONFIG_DOUBLE_PINYIN_SCHEMA, 0);
327
if (m_double_pinyin_schema > DOUBLE_PINYIN_LAST) {
328
m_double_pinyin_schema = 0;
329
g_warn_if_reached ();
331
m_double_pinyin_show_raw = read (CONFIG_DOUBLE_PINYIN_SHOW_RAW, false);
334
m_init_chinese = read (CONFIG_INIT_CHINESE, true);
335
m_init_full = read (CONFIG_INIT_FULL, false);
336
m_init_full_punct = read (CONFIG_INIT_FULL_PUNCT, true);
337
m_init_simp_chinese = read (CONFIG_INIT_SIMP_CHINESE, true);
339
m_special_phrases = read (CONFIG_SPECIAL_PHRASES, true);
342
m_shift_select_candidate = read (CONFIG_SHIFT_SELECT_CANDIDATE, false);
343
m_minus_equal_page = read (CONFIG_MINUS_EQUAL_PAGE, true);
344
m_comma_period_page = read (CONFIG_COMMA_PERIOD_PAGE, true);
345
m_auto_commit = read (CONFIG_AUTO_COMMIT, false);
348
if (read (CONFIG_CORRECT_PINYIN, true))
349
m_option_mask |= PINYIN_CORRECT_ALL;
351
m_option_mask &= ~PINYIN_CORRECT_ALL;
354
for (guint i = 0; i < G_N_ELEMENTS (pinyin_options); i++) {
355
if (read (pinyin_options[i].name, pinyin_options[i].defval))
356
m_option |= pinyin_options[i].option;
358
m_option &= ~pinyin_options[i].option;
364
PinyinConfig::valueChanged (const std::string & section,
365
const std::string & name,
368
if (m_section != section)
371
if (Config::valueChanged (section, name, value))
375
if (CONFIG_DOUBLE_PINYIN == name)
376
m_double_pinyin = normalizeGValue (value, false);
377
else if (CONFIG_DOUBLE_PINYIN_SCHEMA == name) {
378
m_double_pinyin_schema = normalizeGValue (value, 0);
379
if (m_double_pinyin_schema > DOUBLE_PINYIN_LAST) {
380
m_double_pinyin_schema = 0;
381
g_warn_if_reached ();
384
else if (CONFIG_DOUBLE_PINYIN_SHOW_RAW == name)
385
m_double_pinyin_show_raw = normalizeGValue (value, false);
387
else if (CONFIG_INIT_CHINESE == name)
388
m_init_chinese = normalizeGValue (value, true);
389
else if (CONFIG_INIT_FULL == name)
390
m_init_full = normalizeGValue (value, true);
391
else if (CONFIG_INIT_FULL_PUNCT == name)
392
m_init_full_punct = normalizeGValue (value, true);
393
else if (CONFIG_INIT_SIMP_CHINESE == name)
394
m_init_simp_chinese = normalizeGValue (value, true);
395
else if (CONFIG_SPECIAL_PHRASES == name)
396
m_special_phrases = normalizeGValue (value, true);
398
else if (CONFIG_SHIFT_SELECT_CANDIDATE == name)
399
m_shift_select_candidate = normalizeGValue (value, false);
400
else if (CONFIG_MINUS_EQUAL_PAGE == name)
401
m_minus_equal_page = normalizeGValue (value, true);
402
else if (CONFIG_COMMA_PERIOD_PAGE == name)
403
m_comma_period_page = normalizeGValue (value, true);
404
else if (CONFIG_AUTO_COMMIT == name)
405
m_auto_commit = normalizeGValue (value, false);
407
else if (CONFIG_CORRECT_PINYIN == name) {
408
if (normalizeGValue (value, TRUE))
409
m_option_mask |= PINYIN_CORRECT_ALL;
411
m_option_mask &= ~PINYIN_CORRECT_ALL;
414
for (guint i = 0; i < G_N_ELEMENTS (pinyin_options); i++) {
415
if (G_LIKELY (pinyin_options[i].name != name))
417
if (normalizeGValue (value, pinyin_options[i].defval))
418
m_option |= pinyin_options[i].option;
420
m_option &= ~pinyin_options[i].option;
429
BopomofoConfig::BopomofoConfig (Bus & bus)
430
: Config (bus, "Bopomofo")
435
BopomofoConfig::init (Bus & bus)
437
if (m_instance == NULL) {
438
m_instance.reset (new BopomofoConfig (bus));
439
m_instance->readDefaultValues ();
444
BopomofoConfig::readDefaultValues (void)
446
Config::readDefaultValues ();
449
m_init_chinese = read (CONFIG_INIT_CHINESE, true);
450
m_init_full = read (CONFIG_INIT_FULL, false);
451
m_init_full_punct = read (CONFIG_INIT_FULL_PUNCT, true);
452
m_init_simp_chinese = read (CONFIG_INIT_SIMP_CHINESE, false);
454
m_special_phrases = read (CONFIG_SPECIAL_PHRASES, false);
456
m_bopomofo_keyboard_mapping = read (CONFIG_BOPOMOFO_KEYBOARD_MAPPING, 0);
458
m_select_keys = read (CONFIG_SELECT_KEYS, 0);
459
if (m_select_keys >= 9) m_select_keys = 0;
460
m_guide_key = read (CONFIG_GUIDE_KEY, true);
461
m_auxiliary_select_key_f = read (CONFIG_AUXILIARY_SELECT_KEY_F, true);
462
m_auxiliary_select_key_kp = read (CONFIG_AUXILIARY_SELECT_KEY_KP, true);
466
BopomofoConfig::valueChanged (const std::string & section,
467
const std::string & name,
470
if (m_section != section)
473
if (Config::valueChanged (section, name, value))
477
if (CONFIG_INIT_CHINESE == name)
478
m_init_chinese = normalizeGValue (value, true);
479
else if (CONFIG_INIT_FULL == name)
480
m_init_full = normalizeGValue (value, true);
481
else if (CONFIG_INIT_FULL_PUNCT == name)
482
m_init_full_punct = normalizeGValue (value, true);
483
else if (CONFIG_INIT_SIMP_CHINESE == name)
484
m_init_simp_chinese = normalizeGValue (value, false);
485
else if (CONFIG_SPECIAL_PHRASES == name)
486
m_special_phrases = normalizeGValue (value, false);
487
else if (CONFIG_BOPOMOFO_KEYBOARD_MAPPING == name)
488
m_bopomofo_keyboard_mapping = normalizeGValue (value, 0);
489
else if (CONFIG_SELECT_KEYS == name) {
490
m_select_keys = normalizeGValue (value, 0);
491
if (m_select_keys >= 9) m_select_keys = 0;
493
else if (CONFIG_GUIDE_KEY == name)
494
m_guide_key = normalizeGValue (value, true);
495
else if (CONFIG_AUXILIARY_SELECT_KEY_F == name)
496
m_auxiliary_select_key_f = normalizeGValue (value, true);
497
else if (CONFIG_AUXILIARY_SELECT_KEY_KP == name)
498
m_auxiliary_select_key_kp = normalizeGValue (value, true);