PyXR

c:\projects\bitpim\src \ t9editor.py



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