0001 ### BITPIM 0002 ### 0003 ### Copyright (C) 2006 Joe Pham <djpham@bitpim.org> 0004 ### 0005 ### This program is free software; you can redistribute it and/or modify 0006 ### it under the terms of the BitPim license as detailed in the LICENSE file. 0007 ### 0008 ### $Id: t9editor.py 4379 2007-08-28 03:06:58Z djpham $ 0009 """ 0010 Code to handle T9 Editor 0011 0012 The format of the T9 Words data is standardized. It is a list of dict that 0013 has the following standard fields: 0014 0015 "words": an ordered list of dicts, each dict has the following fields: 0016 "word": string value of the actual T9 Word. 0017 0018 To implement T9 Editor feature for your phone, do the following: 0019 0020 1. Add 2 entries into Profile._supportedsyncs: 0021 ... 0022 ('t9_udb', 'read', 'OVERWRITE'), 0023 ('t9_udb', 'write', 'OVERWRITE'), 0024 0025 2. Implement the following 2 methods in your Phone class: 0026 def gett9db(self, result) 0027 def savet9db(self, result, _merge) 0028 0029 The result dict should contain: 0030 result[t9editor.dict_key]=<instance of t9editor.T9WordsList()> 0031 0032 See module phones.com_lgxv8500 for an example implementation. 0033 0034 """ 0035 0036 # wx Modules 0037 from __future__ import with_statement 0038 import wx 0039 import wx.gizmos as gizmos 0040 0041 # BitPim modules 0042 import database 0043 import guihelper 0044 import helpids 0045 import widgets 0046 0047 # module constants-------------------------------------------------------------- 0048 dict_key='T9 Data' 0049 0050 #------------------------------------------------------------------------------- 0051 class T9WordsDataObject(database.basedataobject): 0052 _knownproperties=[] 0053 _knownlistproperties=database.basedataobject._knownlistproperties.copy() 0054 _knownlistproperties.update( { 'words': ['word'] }) 0055 def __init__(self, data=None): 0056 if data and isinstance(data, dict): 0057 self.update(data) 0058 t9wordsdataobjectfactory=database.dataobjectfactory(T9WordsDataObject) 0059 0060 #------------------------------------------------------------------------------- 0061 class T9WordsList(object): 0062 _t9_dict={'0': '0', '1': '1', 0063 'a': '2', 'b': '2', 'c': '2', '2': '2', 0064 'd': '3', 'e': '3', 'f': '3', '3': '3', 0065 'g': '4', 'h': '4', 'i': '4', '4': '4', 0066 'j': '5', 'k': '5', 'l': '5', '5': '5', 0067 'm': '6', 'n': '6', 'o': '6', '6': '6', 0068 'p': '7', 'q': '7', 'r': '7', 's': '7', '7': '7', 0069 't': '8', 'u': '8', 'v': '8', '8': '8', 0070 'w': '9', 'x': '9', 'y': '9', 'z': '9', '9': '9', 0071 } 0072 def __init__(self): 0073 self._data={} 0074 0075 def get(self): 0076 return copy.deepcopy(self._data, {}) 0077 def set(self, d): 0078 self._data={} 0079 self._data.update(d) 0080 0081 def _set_or_del(self, key, v, v_list=[]): 0082 if v is None or v in v_list: 0083 if self._data.has_key(key): 0084 del self._data[key] 0085 else: 0086 self._data[key]=v 0087 0088 def _get_keys(self): 0089 # return a list of available keys in this list 0090 _keys=[x for x,y in self._data.items() if y] 0091 _keys.sort() 0092 return _keys 0093 keys=property(fget=_get_keys) 0094 0095 def _keyof(self, word): 0096 # return the T9 key of this word 0097 return ''.join([self._t9_dict.get(x.lower(), '1') for x in word]) 0098 0099 def get_words(self, key=None): 0100 # return a list of words of group 'key', 0101 # if key is None, return the whole list 0102 _res=[] 0103 if key is None: 0104 _keys=self.keys 0105 _keys.sort() 0106 for _k in _keys: 0107 _res+=self.get_words(_k) 0108 else: 0109 return self._data.get(key, []) 0110 0111 def del_word(self, word): 0112 # delete the specified word from the list 0113 _key=self._keyof(word) 0114 if self._data.has_key(_key): 0115 for _idx,_word in enumerate(self._data[_key]): 0116 if _word==word: 0117 del self._data[_key][_idx] 0118 if not self._data[_key]: 0119 # empty list 0120 del self._data[_key] 0121 return 0122 0123 def append_word(self, word): 0124 # Append this word to our existing list 0125 self._data.setdefault(self._keyof(word), []).append(word) 0126 0127 def set_words(self, words, key=None): 0128 # set the list of words for group 'key' 0129 # if key is None, set the whole database 0130 if key is None: 0131 # set the whole list 0132 self._data={} 0133 for _word in words: 0134 self.append_word(_word) 0135 else: 0136 _l=[] 0137 for _word in words: 0138 if self._keyof(_word)==key: 0139 _l.append(_word) 0140 self._data[key]=_l 0141 0142 def clear(self): 0143 self._data={} 0144 0145 def save(self, db): 0146 # save the current list to the database db 0147 global dict_key 0148 _rec=[] 0149 for _,_list in self._data.items(): 0150 _rec+=[ { 'word': x } for x in _list ] 0151 _dict={ dict_key: { 'words': _rec } } 0152 database.ensurerecordtype(_dict, t9wordsdataobjectfactory) 0153 db.savemajordict(dict_key, _dict) 0154 def load(self, db): 0155 # load from database db into the current list 0156 global dict_key 0157 _dict=db.getmajordictvalues(dict_key, t9wordsdataobjectfactory) 0158 self.clear() 0159 for _word in _dict.get(dict_key, {}).get('words', []): 0160 if _word.get('word', None): 0161 self.append_word(_word['word']) 0162 0163 #------------------------------------------------------------------------------- 0164 class T9EditorWidget(wx.Panel, widgets.BitPimWidget): 0165 help_id=helpids.ID_TAB_T9EDITOR 0166 def __init__(self, mainwindow, parent): 0167 super(T9EditorWidget, self).__init__(parent, -1) 0168 self._mw=mainwindow 0169 self._t9list=T9WordsList() 0170 self.ignoredirty=False 0171 self.dirty=False 0172 # main box sizer 0173 vbs=wx.BoxSizer(wx.VERTICAL) 0174 # horizontal sizer for the main contents 0175 hbs=wx.BoxSizer(wx.HORIZONTAL) 0176 _svbs=wx.StaticBoxSizer(wx.StaticBox(self, -1, 'T9 Keys'), 0177 wx.VERTICAL) 0178 self._keys_lb=wx.ListBox(self, -1, 0179 style=wx.LB_SINGLE|wx.LB_HSCROLL|wx.LB_NEEDED_SB) 0180 wx.EVT_LISTBOX(self, self._keys_lb.GetId(), self._OnSelectKey) 0181 _svbs.Add(self._keys_lb, 1, wx.EXPAND|wx.ALL, 5) 0182 hbs.Add(_svbs, 1, wx.EXPAND|wx.ALL, 5) 0183 self._words_w=gizmos.EditableListBox(self, -1, 'T9 Words:', style=0) 0184 self._words_lb=self._words_w.GetListCtrl() 0185 wx.EVT_BUTTON(self._words_w, self._words_w.GetUpButton().GetId(), 0186 self._OnUpDown) 0187 wx.EVT_BUTTON(self._words_w, self._words_w.GetDownButton().GetId(), 0188 self._OnUpDown) 0189 hbs.Add(self._words_w, 3, wx.EXPAND|wx.ALL, 5) 0190 vbs.Add(hbs, 1, wx.EXPAND|wx.ALL, 5) 0191 vbs.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5) 0192 hbs=wx.BoxSizer(wx.HORIZONTAL) 0193 self._save_btn=wx.Button(self, wx.ID_SAVE) 0194 hbs.Add(self._save_btn, 0, 0195 wx.ALIGN_CENTRE|wx.ALL, 5) 0196 hbs.Add(wx.Button(self, wx.ID_HELP), 0, 0197 wx.ALIGN_CENTRE|wx.ALL, 5) 0198 self._revert_btn=wx.Button(self, wx.ID_REVERT_TO_SAVED) 0199 hbs.Add(self._revert_btn, 0, 0200 wx.ALIGN_CENTRE|wx.ALL, 5) 0201 wx.EVT_BUTTON(self, wx.ID_SAVE, self._OnSave) 0202 wx.EVT_BUTTON(self, wx.ID_REVERT_TO_SAVED, self._OnRevert) 0203 wx.EVT_BUTTON(self, wx.ID_HELP, 0204 lambda _: wx.GetApp().displayhelpid(self.help_id)) 0205 vbs.Add(hbs, 0, wx.ALIGN_CENTRE|wx.ALL, 5) 0206 self.SetSizer(vbs) 0207 self.SetAutoLayout(True) 0208 vbs.Fit(self) 0209 # populate data 0210 self._populate() 0211 # turn on dirty flag 0212 self.setdirty(False) 0213 0214 def setdirty(self, val): 0215 if self.ignoredirty: 0216 return 0217 self.dirty=val 0218 self._save_btn.Enable(self.dirty) 0219 self._revert_btn.Enable(self.dirty) 0220 0221 def _populate_each(self): 0222 # populate the word list based on the selected key 0223 _sel=self._keys_lb.GetStringSelection() 0224 self._words_lb.DeleteAllItems() 0225 if _sel: 0226 self._words_w.SetStrings(self._t9list.get_words(_sel)) 0227 def _populate(self): 0228 # clear both lists 0229 self._keys_lb.Clear() 0230 self._words_lb.DeleteAllItems() 0231 # populate the keys list 0232 for _key in self._t9list.keys: 0233 self._keys_lb.Append(_key) 0234 def populate(self, dict): 0235 global dict_key 0236 self._t9list=dict.get(dict_key, T9WordsList()) 0237 self._populate() 0238 def populatefs(self, dict): 0239 global dict_key 0240 self._t9list=dict.get(dict_key, T9WordsList()) 0241 self._t9list.save(self._mw.database) 0242 self._populate() 0243 return dict 0244 def getfromfs(self, result): 0245 self._t9list.load(self._mw.database) 0246 global dict_key 0247 result[dict_key]=self._t9list 0248 return result 0249 # called from various widget update callbacks 0250 def _re_order(self): 0251 # update the order of the list 0252 self._t9list.set_words(self._words_w.GetStrings(), 0253 self._keys_lb.GetStringSelection()) 0254 def _OnUpDown(self, evt): 0255 wx.CallAfter(self._re_order) 0256 self.OnMakeDirty() 0257 evt.Skip() 0258 def OnMakeDirty(self, _=None): 0259 """A public function you can call that will set the dirty flag""" 0260 if self.dirty or self.ignoredirty: 0261 # already dirty, no need to make it worse 0262 return 0263 self.setdirty(True) 0264 def OnDirty(self, _): 0265 self.setdirty(True) 0266 0267 def _OnSave(self, _): 0268 self._t9list.save(self._mw.database) 0269 self.setdirty(False) 0270 def _OnRevert(self, _): 0271 self._t9list.load(self._mw.database) 0272 self._populate() 0273 self.setdirty(False) 0274 def _OnSelectKey(self, _): 0275 self._populate_each() 0276 def CanAdd(self): 0277 return True 0278 def OnAdd(self, _): 0279 with guihelper.WXDialogWrapper(wx.TextEntryDialog(self, 'Enter a new word:', 0280 'T9 User Word'), 0281 True) as (_dlg, _retcode): 0282 if _retcode==wx.ID_OK: 0283 if _dlg.GetValue(): 0284 self.OnMakeDirty() 0285 self._t9list.append_word(_dlg.GetValue()) 0286 self._populate() 0287 0288 def CanDelete(self): 0289 return self._words_lb.GetSelectedItemCount() 0290 def OnDelete(self, _): 0291 _idx=self._words_lb.GetNextItem(-1, state=wx.LIST_STATE_SELECTED) 0292 if _idx==-1: 0293 return 0294 self._t9list.del_word(self._words_w.GetStrings()[_idx]) 0295 self._words_lb.DeleteItem(_idx) 0296 # Check if this key is empty, if it is, delete it from the keys LB 0297 if self._words_lb.GetItemCount()<2: 0298 # this key is empty, delete it as well 0299 _idx=self._keys_lb.GetSelection() 0300 if _idx!=wx.NOT_FOUND: 0301 self._keys_lb.Delete(_idx) 0302 self.OnMakeDirty() 0303 wx.CallAfter(self._re_order) 0304 def getdata(self, result): 0305 global dict_key 0306 result[dict_key]=self._t9list 0307 return result 0308
Generated by PyXR 0.9.4