Module sms_tab
[hide private]
[frames] | no frames]

Source Code for Module sms_tab

  1  ### BITPIM 
  2  ### 
  3  ### Copyright (C) 2005 Joe Pham <djpham@netzero.net> 
  4  ### 
  5  ### This program is free software; you can redistribute it and/or modify 
  6  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  7  ### 
  8  ### $Id: sms_tab.py 4784 2010-01-15 01:44:50Z djpham $ 
  9   
 10  """ 
 11  Code to handle the SMS Tab of the BitPim main display. 
 12  The read flag is not required for outbox and saved message, delivery 
 13  status is not needed for saved and inbox message, from is not required for 
 14  save and outbox, to is not required for inbox etc. 
 15   
 16  """ 
 17  # standard modules 
 18  from __future__ import with_statement 
 19   
 20  import copy 
 21   
 22  # wx modules 
 23  import wx 
 24  import wx.gizmos as gizmos 
 25  import wx.lib.scrolledpanel as scrolled 
 26   
 27  # BitPim modules 
 28  import common 
 29  import database 
 30  import guiwidgets 
 31  import helpids 
 32  import phonebookentryeditor as pb_editor 
 33  import phonenumber 
 34  import pubsub 
 35  import sms 
 36  import today 
 37  import guihelper 
 38  import guiwidgets 
 39  import widgets 
 40  import xyaptu 
 41   
 42  #------------------------------------------------------------------------------- 
43 -class StaticText(wx.StaticText):
44 - def __init__(self, parent, _=None):
45 super(StaticText, self).__init__(parent, -1)
46 - def SetValue(self, v):
47 if v.find('subject') and (v.find('\n')>-1): 48 v=v.split('\n')[0] 49 if len(v)==10 and v.isdigit(): 50 v='(%03d)-%03d-%04d'%(int(v[:3]),int(v[3:6]),int(v[6:10])) 51 elif len(v)==11 and v.isdigit() and v[0]=='1': 52 v='1-(%03d)-%03d-%04d'%(int(v[1:4]),int(v[4:7]),int(v[7:11])) 53 self.SetLabel(v)
54 55 #-------------------------------------------------------------------------------
56 -class TimeStamp(wx.StaticText):
57 - def __init__(self, parent, _=None):
58 super(TimeStamp, self).__init__(parent, -1)
59 - def SetValue(self, v):
60 if v: 61 self.SetLabel('%04d-%02d-%02d %02d:%02d:%02d'%( 62 int(v[:4]), int(v[4:6]), int(v[6:8]), 63 int(v[9:11]), int(v[11:13]), int(v[13:]))) 64 else: 65 self.SetLabel('')
66 67 #-------------------------------------------------------------------------------
68 -class DeliveryStatus(wx.StaticText):
69 - def __init__(self, parent, _=None):
70 super(DeliveryStatus, self).__init__(parent, -1)
71 - def SetValue(self, v):
72 self.SetLabel('\n'.join(v))
73 74 #-------------------------------------------------------------------------------
75 -class SMSInfo(pb_editor.DirtyUIBase):
76 _dict_key_index=0 77 _label_index=1 78 _class_index=2 79 _get_index=3 80 _set_index=4 81 _w_index=5 82 _flg_index=6 83 _not_used_fields={ 84 ## sms.SMSEntry.Folder_Inbox: ('delivery_status', '_to'), 85 ## sms.SMSEntry.Folder_Sent: ('read', '_from'), 86 ## sms.SMSEntry.Folder_Saved: ('delivery_status',) } 87 sms.SMSEntry.Folder_Inbox: ('delivery_status',), 88 sms.SMSEntry.Folder_Sent: ('read',), 89 sms.SMSEntry.Folder_Saved: ('delivery_status',) }
90 - def __init__(self, parent, _=None):
91 super(SMSInfo, self).__init__(parent) 92 self._fields=[ 93 ['_from', 'From:', StaticText, None, None, None, 0], 94 ['_to', 'To:', StaticText, None, None, None, 0], 95 ['callback', 'Callback #:', StaticText, None, None, None, 0], 96 ['subject', 'Subject:', StaticText, None, None, None, 0], 97 ['datetime', 'Date:', TimeStamp, None, None, None, 0], 98 ['priority_str', 'Priority:', StaticText, None, None, None, 0], 99 ['read', 'Read?:', wx.CheckBox, None, None, None, 0], 100 ['locked', 'Locked:', wx.CheckBox, None, None, None, 0], 101 ['delivery_status', 'Delivery Status:', DeliveryStatus, None, None, 102 None, wx.EXPAND], 103 ] 104 gs=wx.FlexGridSizer(-1, 2, 5, 5) 105 gs.AddGrowableCol(1) 106 for n in self._fields: 107 gs.Add(wx.StaticText(self, -1, n[self._label_index], 108 style=wx.ALIGN_LEFT),0, wx.EXPAND|wx.BOTTOM, 0) 109 w=n[self._class_index](self, -1) 110 gs.Add(w, 0, n[self._flg_index]|wx.BOTTOM, 0) 111 n[self._w_index]=w 112 # all done 113 self.SetSizer(gs) 114 self.SetAutoLayout(True) 115 gs.Fit(self) 116 self._gs=gs
117
118 - def OnMakeDirty(self, evt):
119 self.OnDirtyUI(evt)
120
121 - def Set(self, data):
122 self.ignore_dirty=True 123 if data is None: 124 for n in self._fields: 125 if n[self._class_index]==StaticText or n[self._class_index]==DeliveryStatus or \ 126 n[self._class_index]==TimeStamp: 127 w=n[self._w_index] 128 w.SetValue('') 129 if n[self._class_index]==wx.CheckBox: 130 f=n[self._w_index] 131 f.SetValue(False) 132 else: 133 _bad_fields=self._not_used_fields.get(data.folder, ()) 134 for i,n in enumerate(self._fields): 135 w=n[self._w_index] 136 if n[self._dict_key_index] in _bad_fields: 137 self._gs.Show(i*2, False) 138 self._gs.Show(i*2+1, False) 139 else: 140 self._gs.Show(i*2, True) 141 self._gs.Show(i*2+1, True) 142 w.SetValue(getattr(data, n[self._dict_key_index])) 143 self._gs.Layout() 144 self.ignore_dirty=self.dirty=False
145
146 - def Clear(self):
147 self.Set(None)
148 149 #-------------------------------------------------------------------------------
150 -class SMSWidget(wx.Panel, widgets.BitPimWidget):
151 _data_key='sms' 152 _canned_data_key='canned_msg' 153 msg_type_list=(sms.SMSEntry.Folder_Saved, sms.SMSEntry.Folder_Sent, sms.SMSEntry.Folder_Inbox, 'All')
154 - def __init__(self, mainwindow, parent):
155 super(SMSWidget, self).__init__(parent, -1) 156 self._main_window=mainwindow 157 #self._data=self._canned_data={} 158 self._data={} 159 self._parent=parent 160 self.sms_tree_nodes={} 161 # main box sizer 162 vbs=wx.BoxSizer(wx.VERTICAL) 163 # data date adjuster 164 hbs=wx.BoxSizer(wx.HORIZONTAL) 165 self.read_only=False 166 self.historical_date=None 167 static_bs=wx.StaticBoxSizer(wx.StaticBox(self, -1, 'Historical Data Status:'), 168 wx.VERTICAL) 169 self.historical_data_label=wx.StaticText(self, -1, 'Current Data') 170 static_bs.Add(self.historical_data_label, 1, wx.EXPAND|wx.ALL, 5) 171 hbs.Add(static_bs, 1, wx.EXPAND|wx.ALL, 5) 172 vbs.Add(hbs, 0, wx.EXPAND|wx.ALL, 5) 173 static_bs1=wx.StaticBoxSizer(wx.StaticBox(self, -1, 'Canned Messages:'), 174 wx.HORIZONTAL) 175 self.canned_list=gizmos.EditableListBox(self, -1, 'User Defined Canned Messages:') 176 static_bs1.Add(self.canned_list, 1, wx.EXPAND|wx.ALL, 5) 177 vbs1=wx.BoxSizer(wx.VERTICAL) 178 vbs1.Add(wx.StaticText(self, -1, ' Built-in Canned Messages:'), 0, wx.ALL, 0) 179 self.builtin_canned_list=wx.ListBox(self, -1) 180 vbs1.Add(self.builtin_canned_list, 1, wx.EXPAND|wx.ALL, 5) 181 static_bs1.Add(vbs1, 1, wx.EXPAND|wx.ALL, 5) 182 vbs.Add(static_bs1, 1, wx.EXPAND|wx.ALL, 5) 183 self.save_btn=wx.Button(self, wx.ID_SAVE) 184 vbs.Add(self.save_btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5) 185 self.list_widget=SMSList(self._main_window, self._parent, self) 186 wx.EVT_BUTTON(self, self.save_btn.GetId(), self.OnSaveCannedMsg) 187 # all done 188 self.SetSizer(vbs) 189 self.SetAutoLayout(True) 190 vbs.Fit(self)
191
192 - def OnInit(self):
193 for stat in self.msg_type_list: 194 self.sms_tree_nodes[stat]=self.AddSubPage(self.list_widget, stat, self._tree.message)
195
196 - def GetRightClickMenuItems(self, node):
197 result=[] 198 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EXPORT_SMS, "Export SMS ...", "Export the SMS")) 199 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_DATAHISTORICAL, "Historical Data ...", "Display Historical Data")) 200 return result
201
202 - def _populate(self):
203 self.list_widget.populate() 204 # populate the canned data 205 self.canned_list.SetStrings( 206 self._canned_data.user_list) 207 self.builtin_canned_list.Set(self._canned_data.builtin_list)
208
209 - def OnSaveCannedMsg(self, _):
210 if self.read_only: 211 wx.MessageBox('You are viewing historical data which cannot be changed or saved', 212 'Cannot Save SMS Data', 213 style=wx.OK|wx.ICON_ERROR) 214 return 215 self._canned_data.user_list=self.canned_list.GetStrings() 216 self._save_to_db(canned_msg_dict=self._canned_data)
217
218 - def GetDeleteInfo(self):
219 return guihelper.ART_DEL_SMS, "Delete SMS"
220
221 - def GetAddInfo(self):
222 return guihelper.ART_ADD_SMS, "Add SMS"
223
224 - def getdata(self,dict,want=None):
225 dict[self._data_key]=copy.deepcopy(self._data, {}) 226 dict[self._canned_data_key]=self._canned_data.get().get( 227 self._canned_data_key, {})
228
229 - def get_selected_data(self):
230 # return a dict of selected items 231 res={} 232 for sel_idx in self.list_widget._item_list.GetSelections().values(): 233 k=self.list_widget._item_list.GetItemData(sel_idx) 234 if k: 235 res[k]=self._data[k] 236 return res
237
238 - def get_data(self):
239 return self._data
240
241 - def get_keys(self):
242 """Return the list of keys as being displayed""" 243 return self.list_widget.GetAllKeys()
244 - def get_selected_keys(self):
245 """Return the list of keys of selected items being displayed""" 246 return self.list_widget.GetSelectedKeys()
247
248 - def populate(self, dict, force=False):
249 if self.read_only and not force: 250 return 251 if not self.read_only: 252 self._canned_data=sms.CannedMsgEntry() 253 self._canned_data.set({ self._canned_data_key: dict.get(self._canned_data_key, [])}) 254 self._data=dict.get(self._data_key, {}) 255 self._populate()
256
257 - def _save_to_db(self, sms_dict=None, canned_msg_dict=None):
258 if self.read_only: 259 return 260 if sms_dict is not None: 261 db_rr={} 262 for k, e in sms_dict.items(): 263 db_rr[k]=sms.SMSDataObject(e) 264 database.ensurerecordtype(db_rr, sms.smsobjectfactory) 265 self._main_window.database.savemajordict(self._data_key, db_rr) 266 if canned_msg_dict is not None: 267 db_rr={} 268 db_rr[self._canned_data_key]=sms.CannedMsgDataObject( 269 canned_msg_dict) 270 database.ensurerecordtype(db_rr, sms.cannedmsgobjectfactory) 271 self._main_window.database.savemajordict(self._canned_data_key, 272 db_rr)
273 - def populatefs(self, dict):
274 if self.read_only: 275 wx.MessageBox('You are viewing historical data which cannot be changed or saved', 276 'Cannot Save SMS Data', 277 style=wx.OK|wx.ICON_ERROR) 278 return 279 canned_msg=sms.CannedMsgEntry() 280 canned_msg.set({ self._canned_data_key: dict.get(self._canned_data_key, [])}) 281 self._save_to_db(sms_dict=dict.get(self._data_key, []), 282 canned_msg_dict=canned_msg) 283 return dict
284
285 - def getfromfs(self, result, timestamp=None):
286 # read data from the database 287 sms_dict=self._main_window.database.\ 288 getmajordictvalues(self._data_key, sms.smsobjectfactory, 289 at_time=timestamp) 290 r={} 291 for k,e in sms_dict.items(): 292 ce=sms.SMSEntry() 293 ce.set_db_dict(e) 294 r[ce.id]=ce 295 result.update({ self._data_key: r }) 296 # read the canned messages 297 canned_msg_dict=self._main_window.database.\ 298 getmajordictvalues(self._canned_data_key, 299 sms.cannedmsgobjectfactory) 300 for k,e in canned_msg_dict.items(): 301 ce=sms.CannedMsgEntry() 302 ce.set_db_dict(e) 303 result.update(ce.get()) 304 return result
305
306 - def merge(self, dict):
307 # merge this data with our data 308 # the merge criteria is simple: reject if msg_id's are same 309 if self.read_only: 310 wx.MessageBox('You are viewing historical data which cannot be changed or saved', 311 'Cannot Save SMS Data', 312 style=wx.OK|wx.ICON_ERROR) 313 return 314 existing_id=[e.msg_id for k,e in self._data.items()] 315 d=dict.get(self._data_key, {}) 316 for k,e in d.items(): 317 if e.msg_id not in existing_id: 318 self._data[e.id]=e 319 # save the canned data 320 self._canned_data=sms.CannedMsgEntry() 321 self._canned_data.set({ self._canned_data_key: dict.get(self._canned_data_key, []) } ) 322 # populate the display and save the data 323 self._populate() 324 self._save_to_db(sms_dict=self._data, 325 canned_msg_dict=self._canned_data)
326
327 - def HasHistoricalData(self):
328 return True
329
330 - def OnHistoricalData(self):
331 """Display current or historical data""" 332 if self.read_only: 333 current_choice=guiwidgets.HistoricalDataDialog.Historical_Data 334 else: 335 current_choice=guiwidgets.HistoricalDataDialog.Current_Data 336 with guihelper.WXDialogWrapper(guiwidgets.HistoricalDataDialog(self, 337 current_choice=current_choice, 338 historical_date=self.historical_date, 339 historical_events=\ 340 self._main_window.database.getchangescount(self._data_key)), 341 True) as (dlg, retcode): 342 if retcode==wx.ID_OK: 343 with guihelper.MWBusyWrapper(self._main_window): 344 current_choice, self.historical_date=dlg.GetValue() 345 r={} 346 if current_choice==guiwidgets.HistoricalDataDialog.Current_Data: 347 self.read_only=False 348 msg_str='Current Data' 349 self.getfromfs(r) 350 else: 351 self.read_only=True 352 msg_str='Historical Data as of %s'%\ 353 str(wx.DateTimeFromTimeT(self.historical_date)) 354 self.getfromfs(r, self.historical_date) 355 self.populate(r, True) 356 self.historical_data_label.SetLabel(msg_str) 357 self.list_widget.historical_data_label.SetLabel(msg_str)
358
359 - def OnPrintDialog(self, mainwindow, config):
360 with guihelper.WXDialogWrapper(guiwidgets.SMSPrintDialog(self, mainwindow, config), 361 True): 362 pass
363 - def CanPrint(self):
364 return True
365 366 #-------------------------------------------------------------------------------
367 -class SMSList(wx.Panel, widgets.BitPimWidget):
368 _by_type=0 369 _by_date=1 370 _by_number=2 371 _me_name='<Me>'
372 - def __init__(self, mainwindow, parent, stats):
373 super(SMSList, self).__init__(parent, -1) 374 self._main_window=mainwindow 375 self._stats=stats 376 self.nodes={} 377 self.nodes_keys={} 378 self._display_filter="All" 379 self._name_map={} 380 self._data_map={} 381 382 # main box sizer 383 vbs=wx.BoxSizer(wx.VERTICAL) 384 # data date adjuster 385 hbs=wx.BoxSizer(wx.HORIZONTAL) 386 static_bs=wx.StaticBoxSizer(wx.StaticBox(self, -1, 'Historical Data Status:'), 387 wx.VERTICAL) 388 self.historical_data_label=wx.StaticText(self, -1, 'Current Data') 389 static_bs.Add(self.historical_data_label, 1, wx.EXPAND|wx.ALL, 5) 390 hbs.Add(static_bs, 1, wx.EXPAND|wx.ALL, 5) 391 vbs.Add(hbs, 0, wx.EXPAND|wx.ALL, 5) 392 # main list 393 hbmessage=wx.BoxSizer(wx.HORIZONTAL) 394 column_info=[] 395 column_info.append(("From", 105, False)) 396 column_info.append(("To", 120, False)) 397 column_info.append(("Date", 180, False)) 398 self._item_list=guiwidgets.BitPimListCtrl(self, column_info) 399 self._item_list.ResetView(self.nodes, self.nodes_keys) 400 vbs0=wx.BoxSizer(wx.VERTICAL) 401 vbs0.Add(self._item_list, 1, wx.EXPAND|wx.ALL, 5) 402 vbs0.Add(wx.StaticText(self, -1, ' Note: Click column headings to sort data'), 0, wx.ALIGN_CENTRE|wx.BOTTOM, 10) 403 hbmessage.Add(vbs0, 1, wx.EXPAND|wx.ALL, 5) 404 vbs1=wx.BoxSizer(wx.VERTICAL) 405 self._item_info=SMSInfo(self) 406 vbs1.Add(self._item_info, 0, wx.EXPAND|wx.ALL, 5) 407 self._item_text=pb_editor.MemoEditor(self, -1) 408 vbs1.Add(self._item_text, 1, wx.EXPAND|wx.ALL, 5) 409 hbmessage.Add(vbs1, 0, wx.EXPAND|wx.ALL, 5) 410 hbmessage.SetItemMinSize(1, (350, 20)) 411 vbs.Add(hbmessage, 1, wx.EXPAND|wx.ALL, 5) 412 wx.EVT_LIST_ITEM_SELECTED(self, self._item_list.GetId(), self._OnSelChanged) 413 pubsub.subscribe(self._OnPBLookup, pubsub.RESPONSE_PB_LOOKUP) 414 # register for Today selection 415 self.today_data=None 416 today.bind_notification_event(self.OnTodaySelection, 417 today.Today_Group_IncomingSMS) 418 # all done 419 self.SetSizer(vbs) 420 self.SetAutoLayout(True) 421 vbs.Fit(self)
422
423 - def CanCopy(self):
424 return self._item_text.CanCopy()
425 - def OnCopy(self, _):
426 self._item_text.Copy()
427
428 - def OnSelected(self, node):
429 for stat in self._stats.msg_type_list: 430 if self._stats.sms_tree_nodes[stat]==node: 431 if self._display_filter!=stat: 432 self._display_filter=stat 433 # for some reason GetTopItem return 0 (instead of -1) 434 # when the list is empty 435 if self._item_list.GetItemCount(): 436 item=self._item_list.GetTopItem() 437 # deselect all the items when changing view 438 while item!=-1: 439 self._item_list.Select(item, 0) 440 item=self._item_list.GetNextItem(item) 441 self._item_info.Clear() 442 self._item_text.Set(None) 443 self.populate() 444 self._on_today_selection() 445 return
446
447 - def GetRightClickMenuItems(self, node):
448 result=[] 449 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EDITSELECTALL, "Select All", "Select All Items")) 450 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EDITDELETEENTRY, "Delete Selected", "Delete Selected Items")) 451 result.append((widgets.BitPimWidget.MENU_SPACER, 0, "", "")) 452 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EXPORT_SMS, "Export SMS ...", "Export the SMS")) 453 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_DATAHISTORICAL, "Historical Data ...", "Display Historical Data")) 454 return result
455
456 - def CanSelectAll(self):
457 if self._item_list.GetItemCount(): 458 return True 459 return False
460
461 - def _OnPBLookup(self, msg):
462 d=msg.data 463 k=d.get('item', None) 464 name=d.get('name', None) 465 if k is None: 466 return 467 self._name_map[k]=name
468
469 - def publish_today_data(self):
470 keys=[(x.datetime,k) for k,x in self._stats._data.items()] 471 keys.sort() 472 keys.reverse() 473 today_event=today.TodaySMSEvent() 474 for _,k in keys: 475 if self._stats._data[k].folder==sms.SMSEntry.Folder_Inbox: 476 today_event.append(self._stats._data[k].text, 477 { 'id': k } ) 478 today_event.broadcast()
479
480 - def OnTodaySelection(self, evt):
481 inbox_node=self._stats.sms_tree_nodes[sms.SMSEntry.Folder_Inbox] 482 self.today_data=evt.data 483 self.ActivateSelf(inbox_node)
484
485 - def _on_today_selection(self):
486 if self.today_data and self._item_list.GetItemCount(): 487 item=self._item_list.GetTopItem() 488 while item>=0: 489 if self.today_data['id']==self._item_list.GetItemData(item): 490 self._item_list.Select(item, 1) 491 self._item_list.EnsureVisible(item) 492 else: 493 self._item_list.Select(item, 0) 494 item=self._item_list.GetNextItem(item) 495 self.today_data=None
496
497 - def OnSelectAll(self, _):
498 item=self._item_list.GetTopItem() 499 while item!=-1: 500 self._item_list.Select(item) 501 item=self._item_list.GetNextItem(item)
502
503 - def _number2name(self, numstr):
504 # Lookup name from number string 505 _s=self._name_map.get(numstr, None) 506 if _s is None: 507 return phonenumber.format(numstr) 508 return _s
509
510 - def _OnSelChanged(self, evt):
511 # an item was clicked on/selected 512 item=evt.GetIndex() 513 k=self._item_list.GetItemData(item) 514 # populate the detailed info of the item keyed k 515 if k is None: 516 # clear out all the subfields 517 self._item_info.Clear() 518 self._item_text.Set(None) 519 return 520 entry=self._stats._data.get(k, None) 521 if entry is None: 522 return 523 # set the general detail 524 e=copy.deepcopy(entry) 525 # lookup names if available 526 e._from=self._me_name if e.folder in (e.Folder_Sent, e.Folder_Saved) else \ 527 self._number2name(e._from) 528 e._to=self._me_name if e.folder==e.Folder_Inbox else self._number2name(e._to) 529 e.callback=self._number2name(e.callback) 530 self._item_info.Set(e) 531 self._item_text.Set({'memo': e.text})
532
533 - def HasHistoricalData(self):
534 return self._stats.HasHistoricalData()
535
536 - def OnHistoricalData(self):
537 return self._stats.OnHistoricalData()
538
539 - def populate(self):
540 self.nodes={} 541 self.nodes_keys={} 542 index=0 543 for k,e in self._stats._data.items(): 544 if len(e._from) and not self._name_map.has_key(e._from): 545 pubsub.publish(pubsub.REQUEST_PB_LOOKUP, 546 { 'item': e._from } ) 547 if len(e._to) and not self._name_map.has_key(e._to): 548 pubsub.publish(pubsub.REQUEST_PB_LOOKUP, 549 { 'item': e._to } ) 550 if len(e.callback) and not self._name_map.has_key(e.callback): 551 pubsub.publish(pubsub.REQUEST_PB_LOOKUP, 552 { 'item': e.callback } ) 553 if self._display_filter=='All' or e.folder==self._display_filter: 554 _from=self._me_name if e.folder in (e.Folder_Sent, e.Folder_Saved) \ 555 else self._number2name(e._from) 556 _to=self._me_name if e.folder==e.Folder_Inbox \ 557 else self._number2name(e._to) 558 self.nodes[index]=(_from, _to, e.get_date_time_str()) 559 self.nodes_keys[index]=k 560 self._data_map[k]=index 561 index+=1 562 self._item_list.ResetView(self.nodes, self.nodes_keys) 563 self.publish_today_data()
564
565 - def CanDelete(self):
566 if self._stats.read_only: 567 return False 568 sels_idx=self._item_list.GetFirstSelected() 569 if sels_idx==-1: 570 return False 571 return True
572
573 - def GetDeleteInfo(self):
574 return guihelper.ART_DEL_SMS, "Delete Message"
575
576 - def OnDelete(self, _):
577 if self._stats.read_only: 578 return 579 sels_idx=self._item_list.GetSelections() 580 if len(sels_idx): 581 # delete them from the data list 582 for i,item in sels_idx.items(): 583 del self._stats._data[self._item_list.GetItemData(item)] 584 self._item_list.Select(item, 0) 585 self.populate() 586 self._stats._save_to_db(self._stats._data)
587 - def GetHelpID(self):
588 return helpids.ID_TAB_SMS
589 - def OnPrintDialog(self, mainwindow, config):
590 self._stats.OnPrintDialog(mainwindow, config)
591 - def CanPrint(self):
592 return True
593 - def GetAllKeys(self):
594 return [ self._item_list.GetItemData(x) \ 595 for x in range(self._item_list.GetItemCount()) ]
596 - def GetSelectedKeys(self):
597 _sel_items=self._item_list.GetSelections() 598 _keys=_sel_items.keys() 599 _keys.sort() 600 return [ self._item_list.GetItemData(_sel_items[x]) \ 601 for x in _keys ]
602