/python/helper/PinYinSetup/SetupUI.py

http://scim-python.googlecode.com/ · Python · 300 lines · 232 code · 41 blank · 27 comment · 34 complexity · bb8efdf571f3deae3ad607c9a78b47e3 MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. # vim: set noet ts=4:
  3. #
  4. # scim-python
  5. #
  6. # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
  7. #
  8. #
  9. # This library is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU Lesser General Public
  11. # License as published by the Free Software Foundation; either
  12. # version 2 of the License, or (at your option) any later version.
  13. #
  14. # This library is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU Lesser General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Lesser General Public
  20. # License along with this program; if not, write to the
  21. # Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  22. # Boston, MA 02111-1307 USA
  23. #
  24. # $Id: $
  25. #
  26. import os.path as path
  27. import scim
  28. import gobject
  29. import gtk
  30. import gtk.gdk as gdk
  31. import gtk.glade as glade
  32. import sys
  33. from gettext import dgettext
  34. _ = lambda a : dgettext ("scim-python", a)
  35. try:
  36. from PYDict import *
  37. except:
  38. pathname = path.dirname (__file__)
  39. pathname = path.abspath(pathname)
  40. pathname = path.join (pathname, "../../engine/PinYin")
  41. pathname = path.abspath(pathname)
  42. sys.path.append(pathname)
  43. from PYDict import *
  44. RGB_COLOR = lambda c : ((c.red & 0xff00) << 8) + (c.green & 0xff00) + ((c.blue & 0xff00) >> 8)
  45. GDK_COLOR = lambda c : gdk.Color (((c >> 16) & 0xff) * 256, ((c >> 8) & 0xff) * 256, (c & 0xff) * 256)
  46. RGB = lambda r, g, b : ((r & 0xff) << 16) + ((g & 0xff) << 8) + (b & 0xff)
  47. class SetupUI ():
  48. def __init__ (self, helper_info):
  49. self._helper_info = helper_info
  50. self._helper_agent = scim.HelperAgent ()
  51. self._need_reload_config = False
  52. self._options = {
  53. "SupportGBK" : [True, self._checkbutton_op],
  54. "ShuangPin" : [False, self._checkbutton_op],
  55. "AutoCorrect" : [True, self._checkbutton_op],
  56. #FuzzyPinYin Hacking by YW
  57. "FuzzyPinYin" : [False, self._checkbutton_op],#0
  58. "FuzzyS_Sh" : [False, self._checkbutton_op],#1
  59. "FuzzyC_Ch" : [False, self._checkbutton_op],#2
  60. "FuzzyZ_Zh" : [False, self._checkbutton_op],#3
  61. "FuzzyL_N" : [False, self._checkbutton_op],#4
  62. "FuzzyIn_Ing" : [False, self._checkbutton_op],#5
  63. "FuzzyEn_Eng" : [False, self._checkbutton_op],#6
  64. "FuzzyAn_Ang" : [False, self._checkbutton_op],#7
  65. "SpellCheck" : [True, self._checkbutton_op],
  66. "UVToTemp" : [True, self._checkbutton_op],
  67. "ShiftSelectCandidates" :
  68. [True, self._checkbutton_op],
  69. "CommaPageDownUp" : [True, self._checkbutton_op],
  70. "EqualPageDownUp" : [True, self._checkbutton_op],
  71. "AutoCommit" : [False, self._checkbutton_op],
  72. "PhraseColor" : [RGB (0, 0, 0), self._colorbutton_op],
  73. "NewPhraseColor" : [RGB (0xef, 0, 0), self._colorbutton_op],
  74. "UserPhraseColor" : [RGB (0, 0, 0xbf), self._colorbutton_op],
  75. "SpecialPhraseColor" :
  76. [RGB (0, 0xbf, 0), self._colorbutton_op],
  77. "EnglishPhraseColor" : [RGB (0, 0xbf, 0), self._colorbutton_op],
  78. "ErrorEnglishPhraseColor" :
  79. [RGB (0xef, 0, 0), self._colorbutton_op],
  80. "PageSize" : [5, self._combobox_op, range (1, 10)],
  81. "ShuangPinSchema" : ["MSPY", self._combobox_op, SHUANGPIN_SCHEMAS.keys ()],
  82. }
  83. def run (self, uuid, config, display):
  84. self._config = config
  85. self._uuid = uuid
  86. self._display = display
  87. self._init_agent ()
  88. self._init_ui ()
  89. self._load_config ()
  90. gtk.main ()
  91. if self._need_reload_config:
  92. self._config.flush ()
  93. self._helper_agent.reload_config ()
  94. self._helper_agent.close_connection ()
  95. def _combobox_op (self, name, opt, info):
  96. widget = self._xml.get_widget (name)
  97. if widget == None:
  98. print >> sys.stderr, "Can not find widget %s" % name
  99. return False
  100. if opt == "read":
  101. info[0] = self._read (name, info[0])
  102. widget.set_active (info[2].index (info[0]))
  103. return True
  104. if opt == "write":
  105. info[0] = info[2][widget.get_active ()]
  106. self._write (name, info[0])
  107. return True
  108. if opt == "check":
  109. return info[0] != info[2][widget.get_active ()]
  110. if opt == "init":
  111. model = gtk.ListStore (str)
  112. for v in info[2]:
  113. model.append ([_(str (v))])
  114. widget.set_model (model)
  115. return False
  116. def _colorbutton_op (self, name, opt, info):
  117. widget = self._xml.get_widget (name)
  118. if widget == None:
  119. print >> sys.stderr, "Can not find widget %s" % name
  120. return False
  121. if opt == "read":
  122. info[0] = self._read (name, info[0])
  123. widget.set_color (GDK_COLOR (info[0]))
  124. return True
  125. if opt == "write":
  126. info[0] = RGB_COLOR (widget.get_color ())
  127. self._write (name, info[0])
  128. return True
  129. if opt == "check":
  130. return info[0] != RGB_COLOR (widget.get_color ())
  131. return False
  132. def _checkbutton_op (self, name, opt, info):
  133. widget = self._xml.get_widget (name)
  134. if widget == None:
  135. print >> sys.stderr, "Can not find widget %s" % name
  136. return False
  137. if opt == "read":
  138. info[0] = self._read (name, info[0])
  139. widget.set_active (info[0])
  140. return True
  141. if opt == "write":
  142. info[0] = widget.get_active ()
  143. self._write (name, info[0])
  144. return True
  145. if opt == "check":
  146. return info[0] != widget.get_active ()
  147. return False
  148. def _read (self, name, v):
  149. return self._config.read ("/IMEngine/Python/PinYin/" + name, v)
  150. def _write (self, name, v):
  151. return self._config.write ("/IMEngine/Python/PinYin/" + name, v)
  152. def _init_ui (self):
  153. glade.textdomain("scim-python")
  154. glade_file = path.join (path.dirname (__file__), "SetupUI.glade")
  155. self._xml = glade.XML (glade_file)
  156. self._window = self._xml.get_widget ("window_main")
  157. for name, info in self._options.items ():
  158. info[1] (name, "init", info)
  159. info[1] (name, "read", info)
  160. self._xml.signal_autoconnect (self)
  161. self._window.show_all ()
  162. def _init_agent (self):
  163. fd = self._helper_agent.open_connection (self._helper_info, self._display)
  164. if fd >= 0:
  165. condition = gobject.IO_IN | gobject.IO_ERR | gobject.IO_HUP
  166. gobject.io_add_watch (fd, condition, self.on_agent_event)
  167. def _load_config (self):
  168. for name, info in self._options.items ():
  169. info[1] (name, "read", info)
  170. def _save_config (self):
  171. self._need_reload_config = True
  172. for name, info in self._options.items ():
  173. info[1] (name, "write", info)
  174. def _query_changed (self):
  175. for name, info in self._options.items ():
  176. if info[1] (name, "check", info):
  177. return True
  178. return False
  179. def _quit (self, need_confirm ):
  180. if need_confirm == False:
  181. gtk.main_quit ()
  182. return True
  183. else:
  184. dlg = gtk.MessageDialog (self._window, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION,
  185. gtk.BUTTONS_YES_NO, _("Are you sure to close Python PinYin Setup without save configure?"))
  186. id = dlg.run ()
  187. dlg.destroy ()
  188. if id == gtk.RESPONSE_YES:
  189. gtk.main_quit ()
  190. return True
  191. return False
  192. def _optimize_user_db (self):
  193. import sqlite3
  194. dlg = gtk.MessageDialog (self._window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO,
  195. gtk.BUTTONS_OK, _("The user phrases database will be reorganized! Please don't use python PinYin now."))
  196. dlg.run ()
  197. dlg.destroy ()
  198. try:
  199. db = sqlite3.connect (path.expanduser ("~/.scim/scim-python/pinyin/user.db"))
  200. sqlstring = """
  201. BEGIN TRANSACTION;
  202. CREATE TABLE tmp AS SELECT * FROM py_phrase;
  203. DELETE FROM py_phrase;
  204. INSERT INTO py_phrase SELECT * FROM tmp ORDER BY ylen, y0, y1, y2, y3, yx, phrase;
  205. DROP TABLE tmp;
  206. COMMIT;
  207. """
  208. db.executescript (sqlstring)
  209. db.executescript ("VACUUM;")
  210. except:
  211. import traceback
  212. traceback.print_exc ()
  213. dlg.destroy ()
  214. dlg = gtk.MessageDialog (self._window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO,
  215. gtk.BUTTONS_OK, _("Reorganizing is over!"))
  216. dlg.run ()
  217. dlg.destroy ()
  218. # events handlers
  219. def on_window_main_delete_event (self, widget, event):
  220. result = self._quit (True)
  221. return True
  222. def on_button_ok_clicked (self, button):
  223. changed = self._query_changed ()
  224. if changed:
  225. self._save_config ()
  226. self._quit (False)
  227. def on_button_apply_clicked (self, button):
  228. self._save_config ()
  229. def on_button_cancel_clicked (self, button):
  230. changed = self._query_changed ()
  231. self._quit (changed)
  232. def on_button_optimize_db_clicked (self, button):
  233. self._optimize_user_db ()
  234. def on_value_changed (self, widget, data = None):
  235. if self._query_changed ():
  236. self._xml.get_widget ("button_apply").set_sensitive (True)
  237. else:
  238. self._xml.get_widget ("button_apply").set_sensitive (False)
  239. def on_agent_event (self, fd, condition):
  240. if condition == gobject.IO_IN:
  241. while self._helper_agent.has_pending_event ():
  242. self._helper_agent.filter_event ()
  243. return True
  244. elif condition == gobject.IO_ERR or condition == gobject.IO_HUP:
  245. gtk.main_quit ()
  246. return False
  247. return False
  248. if __name__ == "__main__":
  249. class CC:
  250. def __init__ (self):
  251. pass
  252. def read (self, name, v):
  253. return v
  254. def write (self, name, v):
  255. pass
  256. def flush (self):
  257. pass
  258. helper_info = ("eebeecd7-cb22-48f4-8ced-70e42dad1a79", "", "", "", 1)
  259. SetupUI (helper_info). run ("eebeecd7-cb22-48f4-8ced-70e42dad1a79", CC (), ":0.0")