1 # vim:set et ts=4 sts=4:
2 # -*- coding: utf-8 -*-
4 # ibus-libpinyin - Intelligent Pinyin engine based on libpinyin for IBus
6 # Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
7 # Copyright (c) 2010 BYVoid <byvoid1@gmail.com>
8 # Copyright (c) 2011-2012 Peng Wu <alexepico@gmail.com>
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2, or (at your option)
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 from gi.repository import GLib
31 from gi.repository import Gtk
32 from gi.repository import IBus
33 from xdg import BaseDirectory
36 from dicttreeview import DictionaryTreeView
38 locale.setlocale(locale.LC_ALL, "")
39 localedir = os.getenv("IBUS_LOCALEDIR")
40 gettext.install('ibus-libpinyin', localedir)
42 class PreferencesDialog:
43 def __init__(self, engine):
44 self.__bus = IBus.Bus()
45 self.__config = self.__bus.get_config()
46 self.__builder = Gtk.Builder()
47 self.__builder.set_translation_domain("ibus-libpinyin")
48 self.__builder.add_from_file("ibus-libpinyin-preferences.ui")
49 self.__dialog = self.__builder.get_object("dialog")
52 if engine == "pinyin":
53 self.__config_namespace = "engine/Pinyin"
54 self.__values = dict(self.__config.get_values(self.__config_namespace))
58 self.__init_dictionary()
59 self.__init_user_data()
61 elif engine == "bopomofo":
62 self.__config_namespace = "engine/Bopomofo"
63 self.__values = dict(self.__config.get_values(self.__config_namespace))
65 self.__init_bopomofo()
67 self.__init_dictionary()
68 #self.__init_user_data()
70 self.__convert_fuzzy_pinyin_to_bopomofo()
73 print("Error: Unknown Engine")
76 self.__pages.set_current_page(0)
78 def __init_pages(self):
79 self.__pages = self.__builder.get_object("pages")
80 self.__page_general = self.__builder.get_object("pageGeneral")
81 self.__page_pinyin_mode = self.__builder.get_object("pagePinyinMode")
82 self.__page_bopomofo_mode = self.__builder.get_object("pageBopomofoMode")
83 self.__page_fuzzy = self.__builder.get_object("pageFuzzy")
84 self.__page_dictionary = self.__builder.get_object("pageDictionary")
85 self.__page_user_data = self.__builder.get_object("pageUserData")
86 self.__page_about = self.__builder.get_object("pageAbout")
88 self.__page_general.hide()
89 self.__page_pinyin_mode.hide()
90 self.__page_bopomofo_mode.hide()
91 self.__page_fuzzy.hide()
92 self.__page_dictionary.hide()
93 self.__page_user_data.hide()
94 self.__page_about.hide()
96 def __init_general(self):
98 self.__page_general.show()
101 self.__init_chinese = self.__builder.get_object("InitChinese")
102 self.__init_english = self.__builder.get_object("InitEnglish")
103 self.__init_full = self.__builder.get_object("InitFull")
104 self.__init_half = self.__builder.get_object("InitHalf")
105 self.__init_full_punct = self.__builder.get_object("InitFullPunct")
106 self.__init_half_punct = self.__builder.get_object("InitHalfPunct")
107 self.__init_simp = self.__builder.get_object("InitSimplifiedChinese")
108 self.__init_trad = self.__builder.get_object("InitTraditionalChinese")
111 self.__lookup_table_page_size = self.__builder.get_object("LookupTablePageSize")
112 self.__lookup_table_orientation = self.__builder.get_object("LookupTableOrientation")
114 self.__shift_switch = self.__builder.get_object("ShiftSwitch")
115 self.__ctrl_switch = self.__builder.get_object("CtrlSwitch")
117 self.__dynamic_adjust = self.__builder.get_object("DynamicAdjust")
120 self.__init_chinese.set_active(self.__get_value("InitChinese", True))
121 self.__init_full.set_active(self.__get_value("InitFull", False))
122 self.__init_full_punct.set_active(self.__get_value("InitFullPunct", True))
123 self.__init_simp.set_active(self.__get_value("InitSimplifiedChinese", True))
125 self.__lookup_table_orientation.set_active(self.__get_value("LookupTableOrientation", 0))
126 self.__lookup_table_page_size.set_value(self.__get_value("LookupTablePageSize", 5))
128 self.__shift_switch.set_active(not self.__get_value("CtrlSwitch", False))
130 self.__dynamic_adjust.set_active(self.__get_value("DynamicAdjust", True))
132 self.__init_chinese.connect("toggled", self.__toggled_cb, "InitChinese")
133 self.__init_full.connect("toggled", self.__toggled_cb, "InitFull")
134 self.__init_full_punct.connect("toggled", self.__toggled_cb, "InitFullPunct")
135 self.__init_simp.connect("toggled", self.__toggled_cb, "InitSimplifiedChinese")
136 self.__ctrl_switch.connect("toggled", self.__toggled_cb, "CtrlSwitch")
137 self.__dynamic_adjust.connect("toggled", self.__toggled_cb, "DynamicAdjust")
139 def __lookup_table_page_size_changed_cb(adjustment):
140 self.__set_value("LookupTablePageSize", int(adjustment.get_value()))
142 def __lookup_table_orientation_changed_cb(widget):
143 self.__set_value("LookupTableOrientation", widget.get_active())
145 self.__lookup_table_orientation.connect("changed", __lookup_table_orientation_changed_cb)
146 self.__lookup_table_page_size.connect("value-changed", __lookup_table_page_size_changed_cb)
148 def __init_pinyin(self):
150 self.__page_pinyin_mode.show()
153 self.__full_pinyin = self.__builder.get_object("FullPinyin")
154 self.__incomplete_pinyin = self.__builder.get_object("IncompletePinyin")
155 self.__double_pinyin = self.__builder.get_object("DoublePinyin")
156 self.__double_pinyin_schema = self.__builder.get_object("DoublePinyinSchema")
157 # self.__double_pinyin_schema_label = self.__builder.get_object("labelDoublePinyinSchema")
158 self.__double_pinyin_show_raw = self.__builder.get_object("DoublePinyinShowRaw")
159 self.__double_pinyin_show_raw.hide ()
162 self.__incomplete_pinyin.set_active(self.__get_value("IncompletePinyin", True))
163 self.__full_pinyin.set_active(not self.__get_value("DoublePinyin", False))
164 self.__double_pinyin_schema.set_active(self.__get_value("DoublePinyinSchema", 0))
165 if self.__full_pinyin.get_active():
166 # self.__incomplete_pinyin.set_sensitive(True)
167 self.__double_pinyin_schema.set_sensitive(False)
168 # self.__double_pinyin_schema_label.set_sensitive(False)
169 self.__double_pinyin_show_raw.set_sensitive(False)
171 # self.__incomplete_pinyin.set_sensitive(False)
172 self.__double_pinyin_schema.set_sensitive(True)
173 # self.__double_pinyin_schema_label.set_sensitive(True)
174 self.__double_pinyin_show_raw.set_sensitive(True)
176 def __double_pinyin_toggled_cb(widget):
177 val = widget.get_active()
178 self.__set_value("DoublePinyin", val)
179 self.__double_pinyin_schema.set_sensitive(val)
180 # self.__double_pinyin_schema_label.set_sensitive(val)
181 self.__double_pinyin_show_raw.set_sensitive(val)
183 def __double_pinyin_schema_changed_cb(widget):
184 self.__set_value("DoublePinyinSchema", widget.get_active())
187 self.__double_pinyin.connect("toggled", __double_pinyin_toggled_cb)
188 self.__incomplete_pinyin.connect("toggled", self.__toggled_cb, "IncompletePinyin")
189 self.__double_pinyin_schema.connect("changed", __double_pinyin_schema_changed_cb)
190 self.__double_pinyin_show_raw.connect("toggled", self.__toggled_cb, "DoublePinyinShowRaw")
192 self.__init_input_custom()
193 self.__init_correct_pinyin()
195 def __init_bopomofo(self):
197 self.__page_bopomofo_mode.show()
200 self.__incomplete_bopomofo = self.__builder.get_object("IncompleteBopomofo")
201 self.__bopomofo_keyboard_mapping = self.__builder.get_object("BopomofoKeyboardMapping")
204 self.__select_keys = self.__builder.get_object("SelectKeys")
205 self.__guide_key = self.__builder.get_object("GuideKey")
206 self.__auxiliary_select_key_f = self.__builder.get_object("AuxiliarySelectKey_F")
207 self.__auxiliary_select_key_kp = self.__builder.get_object("AuxiliarySelectKey_KP")
210 self.__enter_key = self.__builder.get_object("CommitFirstCandidate")
213 self.__bopomofo_keyboard_mapping.set_active(self.__get_value("BopomofoKeyboardMapping", 0))
214 self.__incomplete_bopomofo.set_active(self.__get_value("IncompletePinyin", False))
215 self.__select_keys.set_active(self.__get_value("SelectKeys", 0))
216 self.__guide_key.set_active(self.__get_value("GuideKey", 1))
217 self.__auxiliary_select_key_f.set_active(self.__get_value("AuxiliarySelectKey_F", 1))
218 self.__auxiliary_select_key_kp.set_active(self.__get_value("AuxiliarySelectKey_KP", 1))
219 self.__enter_key.set_active(self.__get_value("EnterKey", True))
222 def __bopomofo_keyboard_mapping_changed_cb(widget):
223 self.__set_value("BopomofoKeyboardMapping", widget.get_active())
224 def __select_keys_changed_cb(widget):
225 self.__set_value("SelectKeys", widget.get_active())
227 self.__bopomofo_keyboard_mapping.connect("changed", __bopomofo_keyboard_mapping_changed_cb)
228 self.__incomplete_bopomofo.connect("toggled", self.__toggled_cb, "IncompletePinyin")
229 self.__select_keys.connect("changed", __select_keys_changed_cb)
230 self.__guide_key.connect("toggled", self.__toggled_cb, "GuideKey")
231 self.__auxiliary_select_key_f.connect("toggled", self.__toggled_cb, "AuxiliarySelectKey_F")
232 self.__auxiliary_select_key_kp.connect("toggled", self.__toggled_cb, "AuxiliarySelectKey_KP")
233 self.__enter_key.connect("toggled", self.__toggled_cb, "EnterKey")
235 def __init_input_custom(self):
237 self.__shift_select_candidate = self.__builder.get_object("ShiftSelectCandidate")
238 self.__minus_equal_page = self.__builder.get_object("MinusEqualPage")
239 self.__comma_period_page = self.__builder.get_object("CommaPeriodPage")
240 self.__auto_commit = self.__builder.get_object("AutoCommit")
243 self.__shift_select_candidate.set_active(self.__get_value("ShiftSelectCandidate", False))
244 self.__minus_equal_page.set_active(self.__get_value("MinusEqualPage", True))
245 self.__comma_period_page.set_active(self.__get_value("CommaPeriodPage", True))
246 self.__auto_commit.set_active(self.__get_value("AutoCommit", False))
249 self.__shift_select_candidate.connect("toggled", self.__toggled_cb, "ShiftSelectCandidate")
250 self.__minus_equal_page.connect("toggled", self.__toggled_cb, "MinusEqualPage")
251 self.__comma_period_page.connect("toggled", self.__toggled_cb, "CommaPeriodPage")
252 self.__auto_commit.connect("toggled", self.__toggled_cb, "AutoCommit")
254 def __init_correct_pinyin(self):
256 self.__correct_pinyin = self.__builder.get_object("CorrectPinyin")
257 self.__correct_pinyin_widgets = [
258 ("CorrectPinyin_GN_NG", True),
259 ("CorrectPinyin_MG_NG", True),
260 ("CorrectPinyin_IOU_IU", True),
261 ("CorrectPinyin_UEI_UI", True),
262 ("CorrectPinyin_UEN_UN", True),
263 ("CorrectPinyin_UE_VE", True),
264 ("CorrectPinyin_V_U", True),
265 ("CorrectPinyin_ON_ONG", True),
268 def __correct_pinyin_toggled_cb(widget):
269 val = widget.get_active()
270 map(lambda w: self.__builder.get_object(w[0]).set_sensitive(val),
271 self.__correct_pinyin_widgets)
272 self.__correct_pinyin.connect("toggled", __correct_pinyin_toggled_cb)
275 self.__correct_pinyin.set_active(self.__get_value("CorrectPinyin", True))
276 for name, defval in self.__correct_pinyin_widgets:
277 widget = self.__builder.get_object(name)
278 widget.set_active(self.__get_value(name, defval))
280 self.__correct_pinyin.connect("toggled", self.__toggled_cb, "CorrectPinyin")
281 for name, defval in self.__correct_pinyin_widgets:
282 widget = self.__builder.get_object(name)
283 widget.connect("toggled", self.__toggled_cb, name)
285 def __init_fuzzy(self):
287 self.__page_fuzzy.show()
290 self.__fuzzy_pinyin = self.__builder.get_object("FuzzyPinyin")
291 self.__fuzzy_pinyin_widgets = [
292 ("FuzzyPinyin_C_CH", True),
293 ("FuzzyPinyin_Z_ZH", True),
294 ("FuzzyPinyin_S_SH", True),
295 ("FuzzyPinyin_L_N", True),
296 ("FuzzyPinyin_F_H", True),
297 ("FuzzyPinyin_L_R", False),
298 ("FuzzyPinyin_G_K", False),
299 ("FuzzyPinyin_AN_ANG", True),
300 ("FuzzyPinyin_EN_ENG", True),
301 ("FuzzyPinyin_IN_ING", True),
304 def __fuzzy_pinyin_toggled_cb(widget):
305 val = widget.get_active()
306 map(lambda w: self.__builder.get_object(w[0]).set_sensitive(val),
307 self.__fuzzy_pinyin_widgets)
308 self.__fuzzy_pinyin.connect("toggled", __fuzzy_pinyin_toggled_cb)
311 self.__fuzzy_pinyin.set_active(self.__get_value("FuzzyPinyin", False))
312 for name, defval in self.__fuzzy_pinyin_widgets:
313 widget = self.__builder.get_object(name)
314 widget.set_active(self.__get_value(name, defval))
316 self.__fuzzy_pinyin.connect("toggled", self.__toggled_cb, "FuzzyPinyin")
317 for name, defval in self.__fuzzy_pinyin_widgets:
318 widget = self.__builder.get_object(name)
319 widget.connect("toggled", self.__toggled_cb, name)
321 def __convert_fuzzy_pinyin_to_bopomofo(self):
323 ("FuzzyPinyin_C_CH", "ㄘ <=> ㄔ"),
324 ("FuzzyPinyin_Z_ZH", "ㄗ <=> ㄓ"),
325 ("FuzzyPinyin_S_SH", "ㄙ <=> ㄕ"),
326 ("FuzzyPinyin_L_N", "ㄌ <=> ㄋ"),
327 ("FuzzyPinyin_F_H", "ㄈ <=> ㄏ"),
328 ("FuzzyPinyin_L_R", "ㄌ <=> ㄖ"),
329 ("FuzzyPinyin_G_K", "ㄍ <=> ㄎ"),
330 ("FuzzyPinyin_AN_ANG", "ㄢ <=> ㄤ"),
331 ("FuzzyPinyin_EN_ENG", "ㄣ <=> ㄥ"),
332 ("FuzzyPinyin_IN_ING", "ㄧㄣ <=> ㄧㄥ"),
335 for name, label in options:
336 self.__builder.get_object(name).set_label(label)
339 def __init_dictionary(self):
341 self.__page_dictionary.show()
343 # dictionary tree view
344 self.__dict_treeview = self.__builder.get_object("Dictionaries")
345 self.__dict_treeview.show()
346 self.__dict_treeview.set_dictionaries(self.__get_value("Dictionaries", "2"))
348 def __notified_dicts_cb(self, param, dialog):
349 dialog.__set_value("Dictionaries", self.get_dictionaries())
351 # connect notify signal
352 self.__dict_treeview.connect("notify::dictionaries", __notified_dicts_cb, self)
354 def __init_user_data(self):
356 self.__page_user_data.show()
358 self.__frame_lua_script = self.__builder.get_object("frameLuaScript")
359 path = os.path.join(config.get_data_dir(), 'user.lua')
360 if not os.access(path, os.R_OK):
361 self.__frame_lua_script.hide()
363 self.__edit_lua = self.__builder.get_object("EditLua")
364 self.__edit_lua.connect("clicked", self.__edit_lua_cb)
366 self.__import_dictionary = self.__builder.get_object("ImportDictionary")
367 self.__import_dictionary.connect("clicked", self.__import_dictionary_cb)
369 self.__clear_user_data = self.__builder.get_object("ClearUserData")
370 self.__clear_user_data.connect("clicked", self.__clear_user_data_cb, "user")
371 self.__clear_all_data = self.__builder.get_object("ClearAllData")
372 self.__clear_all_data.connect("clicked", self.__clear_user_data_cb, "all")
374 def __edit_lua_cb(self, widget):
376 path = os.path.join(BaseDirectory.xdg_config_home, "ibus", "libpinyin")
377 os.path.exists(path) or os.makedirs(path)
378 path = os.path.join(path, "user.lua")
379 if not os.path.exists(path):
380 src = os.path.join(config.get_data_dir(), "user.lua")
381 shutil.copyfile(src, path)
382 os.system("xdg-open %s" % path)
384 def __import_dictionary_cb(self, widget):
385 dialog = Gtk.FileChooserDialog \
386 (_("Please choose a file"), None,
387 Gtk.FileChooserAction.OPEN,
388 (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
389 Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
391 filter_text = Gtk.FileFilter()
392 filter_text.set_name("Text files")
393 filter_text.add_mime_type("text/plain")
394 dialog.add_filter(filter_text)
396 response = dialog.run()
397 if response == Gtk.ResponseType.OK:
398 self.__set_value("ImportDictionary", dialog.get_filename())
402 def __clear_user_data_cb(self, widget, name):
403 self.__set_value("ClearUserData", name)
405 def __init_about(self):
407 self.__page_about.show()
409 self.__name_version = self.__builder.get_object("NameVersion")
410 self.__name_version.set_markup(_("<big><b>Intelligent Pinyin %s</b></big>") % config.get_version())
412 def __changed_cb(self, widget, name):
413 self.__set_value(name, widget.get_active())
415 def __toggled_cb(self, widget, name):
416 self.__set_value(name, widget.get_active ())
418 def __get_value(self, name, defval):
419 if name in self.__values:
420 var = self.__values[name]
421 if isinstance(defval, type(var)):
423 self.__set_value(name, defval)
426 def __set_value(self, name, val):
428 if isinstance(val, bool):
429 var = GLib.Variant.new_boolean(val)
430 elif isinstance(val, int):
431 var = GLib.Variant.new_int32(val)
432 elif isinstance(val, str):
433 var = GLib.Variant.new_string(val)
435 print >> sys.stderr, "val(%s) is not in support type." % repr(val)
438 self.__values[name] = val
439 self.__config.set_value(self.__config_namespace, name, var)
442 return self.__dialog.run()
446 if len(sys.argv) == 2:
448 if name not in ("pinyin", "bopomofo"):
450 PreferencesDialog(name).run()
453 if __name__ == "__main__":