Translation update done using Pootle.
[wammu.git] / Wammu / SMSExport.py
blob03b55f5f02017c26cf37c8bbff4d0c9f0ca867d2
1 # -*- coding: UTF-8 -*-
2 # vim: expandtab sw=4 ts=4 sts=4:
3 '''
4 Wammu - Phone manager
5 SMS export code.
6 '''
7 __author__ = 'Michal Čihař'
8 __email__ = 'michal@cihar.com'
9 __license__ = '''
10 Copyright © 2003 - 2010 Michal Čihař
12 This program is free software; you can redistribute it and/or modify it
13 under the terms of the GNU General Public License version 2 as published by
14 the Free Software Foundation.
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 more details.
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 '''
26 import os
27 import imaplib
28 import wx
29 import Wammu.MailWriter
30 import Wammu.IMAP
31 import re
33 MAILBOX_RE = re.compile(r'\((?P<flags>(\s*\\\w*)*)\)\s+(?P<delim>[^ ]*)\s+(?P<name>.*)')
34 POSSIBLY_QUOTED_RE = re.compile(r'"?([^"]*)"?')
36 def SMSToMailbox(parent, messages, contacts):
37 count = len(messages)
38 wildcard = _('Mailboxes') + ' (*.mbox)|*.mbox|' + _('All files') + ' (*.*)|*.*;*'
39 exts = ['mbox']
40 exts.append(None)
41 dlg = wx.FileDialog(parent, _('Select mailbox file...'), os.getcwd(), "", wildcard, wx.SAVE | wx.OVERWRITE_PROMPT | wx.CHANGE_DIR)
43 if dlg.ShowModal() != wx.ID_OK:
44 return
46 path = dlg.GetPath()
47 ext = exts[dlg.GetFilterIndex()]
48 # Add automatic extension if we know one and file does not
49 # have any
50 if (os.path.splitext(path)[1] == '' and
51 ext is not None):
52 path += '.' + ext
54 parent.ShowProgress(_('Saving messages to mailbox'))
55 try:
56 f = file(path, 'w')
57 for i in range(count):
58 if not parent.progress.Update(i * 100 / count):
59 del parent.progress
60 parent.SetStatusText(_('Export terminated'))
61 return
63 sms = messages[i]
64 filename, data, unused_msgid = Wammu.MailWriter.SMSToMail(parent.cfg, sms, contacts, True)
65 f.write(data)
66 f.write('\n')
67 f.write('\n')
69 f.close()
70 except IOError:
71 del parent.progress
72 wx.MessageDialog(parent,
73 _('Creating of file %s failed, bailing out.') % path,
74 _('Can not create file!'),
75 wx.OK | wx.ICON_ERROR).ShowModal()
76 del parent.progress
77 parent.SetStatusText(_('Export terminated'))
78 return
80 parent.progress.Update(100)
81 del parent.progress
82 parent.SetStatusText(_('%(count)d messages exported to "%(path)s" (%(type)s)') % {'count':count, 'path':path, 'type': _('mailbox')})
84 def SMSToMaildir(parent, messages, contacts):
85 count = len(messages)
86 dlg = wx.DirDialog(parent, _('Select maildir directory where to save files'), os.getcwd(),
87 style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
89 if dlg.ShowModal() != wx.ID_OK:
90 return
92 path = dlg.GetPath()
93 outpath = path
95 if not os.path.isdir(os.path.join(outpath, 'new')):
96 res = wx.MessageDialog(parent,
97 _('Selected folder does not contain new subfolder and thus probably is not valid maildir.\n\nDo you want to create new subfolder and export to it?'),
98 _('Folder doesn\'t look like maildir!'),
99 wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_WARNING).ShowModal()
101 if res == wx.ID_CANCEL:
102 return
104 if res == wx.ID_YES:
105 outpath = os.path.join(outpath, 'new')
106 try:
107 os.mkdir(outpath)
108 except OSError:
109 wx.MessageDialog(parent,
110 _('Creating of folder failed, bailing out.'),
111 _('Can not create folder!'),
112 wx.OK | wx.ICON_ERROR).ShowModal()
113 return
114 else:
115 outpath = os.path.join(outpath, 'new')
117 parent.ShowProgress(_('Saving messages to maildir'))
118 for i in range(count):
119 if not parent.progress.Update(i * 100 / count):
120 del parent.progress
121 parent.SetStatusText(_('Export terminated'))
122 return
124 sms = messages[i]
125 filename, data, unused_msgid = Wammu.MailWriter.SMSToMail(parent.cfg, sms, contacts)
127 outfile = os.path.join(outpath, filename)
128 if os.path.exists(outfile):
129 res = wx.MessageDialog(parent,
130 _('Output file already exists, this usually means that this message was already saved there.\n\nDo you wish to overwrite file %s?') % outfile,
131 _('File already exists!'),
132 wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_WARNING).ShowModal()
134 if res == wx.ID_CANCEL:
135 del parent.progress
136 parent.SetStatusText(_('Export terminated'))
137 return
139 if res == wx.ID_NO:
140 continue
141 try:
142 f = file(outfile, 'w')
143 f.write(data)
144 f.close()
145 except IOError:
146 wx.MessageDialog(parent,
147 _('Creating of file %s failed, bailing out.') % outfile,
148 _('Can not create file!'),
149 wx.OK | wx.ICON_ERROR).ShowModal()
150 del parent.progress
151 parent.SetStatusText(_('Export terminated'))
152 return
154 parent.progress.Update(100)
155 del parent.progress
157 parent.SetStatusText(_('%(count)d messages exported to "%(path)s" (%(type)s)') % {'count':count, 'path':path, 'type': _('maildir')})
159 def ParseIMAPFolder(item):
161 Parses folder reply from IMAP.
163 match = MAILBOX_RE.match(item)
165 if not match:
166 return (None, None)
168 delim = POSSIBLY_QUOTED_RE.match(match.group('delim')).group(1)
169 path = POSSIBLY_QUOTED_RE.match(match.group('name')).group(1)
170 flags = match.group('flags')
171 return (path, flags)
173 def SMSToIMAP(parent, messages, contacts):
174 imapConfig = IMAPConfigHelper(parent.cfg)
176 while True:
177 value = IMAPSettingsDialog(parent, imapConfig).ShowModal()
178 if value == wx.ID_CANCEL:
179 return
181 busy = wx.BusyInfo(_('Connecting to IMAP server...'))
183 if imapConfig.useSSL:
184 m = imaplib.IMAP4_SSL(imapConfig.server, int(imapConfig.port))
185 else:
186 m = imaplib.IMAP4(imapConfig.server, int(imapConfig.port))
188 try:
189 res = m.login(imapConfig.login, imapConfig.password)
190 except:
191 res = ['FAIL']
192 del busy
193 if res[0] == 'OK':
194 break
195 else:
196 if wx.MessageDialog(parent,
197 _('Can not login, you probably entered invalid login information. Do you want to retry?'),
198 _('Login failed!'),
199 wx.YES_NO | wx.YES_DEFAULT | wx.ICON_ERROR).ShowModal() == wx.ID_NO:
200 return
202 busy = wx.BusyInfo(_('Listing folders on IMAP server...'))
203 try:
204 res, list = m.list()
205 except:
206 res = 'FAIL'
207 del busy
208 if res != 'OK':
209 wx.MessageDialog(parent,
210 _('Can not list folders on server, bailing out.'),
211 _('Listing failed!'),
212 wx.OK | wx.ICON_ERROR).ShowModal()
213 parent.SetStatusText(_('Export terminated'))
214 return
216 folders = []
217 for item in list:
218 path, flags = ParseIMAPFolder(item)
220 if path is None:
221 continue
223 if flags.find('\\Noselect') != -1:
224 continue
226 try:
227 folders.append(unicode(path, 'imap4-utf-7'))
228 except UnicodeDecodeError:
229 # Ignore folders which can not be properly converted
230 pass
232 folders.sort()
234 lastFolder = parent.cfg.Read('/IMAP/LastUsedFolder')
235 folderIndex = 0
236 if lastFolder != '':
237 try:
238 folderIndex = folders.index(lastFolder)
239 except:
240 pass
242 dlg = wx.SingleChoiceDialog(parent,
243 _('Please select folder on server %s where messages will be stored') % imapConfig.server,
244 _('Select folder'),
245 folders, wx.CHOICEDLG_STYLE | wx.RESIZE_BORDER)
246 if folderIndex > 0:
247 dlg.SetSelection(folderIndex)
248 if dlg.ShowModal() == wx.ID_CANCEL:
249 try:
250 m.logout()
251 except:
252 pass
253 return
254 path = '%s@%s/%s' % (imapConfig.login, imapConfig.server, folders[dlg.GetSelection()])
255 folder = folders[dlg.GetSelection()].encode('imap4-utf-7')
257 parent.cfg.Write('/IMAP/LastUsedFolder', folders[dlg.GetSelection()])
259 busy = wx.BusyInfo(_('Selecting folder on IMAP server...'))
260 try:
261 res = m.select(folder)
262 except:
263 res = ['FAIL']
264 del busy
265 if res[0] != 'OK':
266 wx.MessageDialog(parent,
267 _('Can not select folder %s on server, bailing out.') % folder,
268 _('Selecting failed!'),
269 wx.OK | wx.ICON_ERROR).ShowModal()
270 parent.SetStatusText(_('Export terminated'))
271 return
273 def msgFilter(sms):
274 return \
275 (imapConfig.backupRead and sms['SMS'][0]['State'] == 'Read') \
276 or (imapConfig.backupSent and sms['SMS'][0]['State'] == 'Sent') \
277 or (imapConfig.backupUnread and sms['SMS'][0]['State'] == 'UnRead') \
278 or (imapConfig.backupUnsent and sms['SMS'][0]['State'] == 'UnSent')
280 messages = filter(msgFilter, messages)
281 count = len(messages)
283 parent.ShowProgress(_('Saving messages to IMAP'))
285 new_messages_num = 0
286 count = len(messages)
287 for i in range(count):
288 if not parent.progress.Update(i * 100 / count):
289 del parent.progress
290 parent.SetStatusText(_('Export terminated'))
291 return
293 sms = messages[i]
295 filename, data, msgid = Wammu.MailWriter.SMSToMail(parent.cfg, sms, contacts)
297 if imapConfig.newMessages == True:
298 res, msgnums = m.search(None, 'HEADER', '"Message-ID" "' + msgid + '"')
299 if len(msgnums[0].split()) != 0:
300 continue
302 new_messages_num += 1
304 try:
305 res = m.append(folder, '$SMS', None, data)
306 except:
307 res = ['FAIL']
308 if res[0] != 'OK':
309 wx.MessageDialog(parent,
310 _('Can not save message to folder %s on server, bailing out.') % folder,
311 _('Saving failed!'),
312 wx.OK | wx.ICON_ERROR).ShowModal()
313 parent.progress.Update(100)
314 del parent.progress
315 parent.SetStatusText(_('Export terminated'))
316 return
318 parent.progress.Update(100)
319 del parent.progress
321 try:
322 m.logout()
323 except:
324 pass
326 if imapConfig.newMessages == False:
327 parent.SetStatusText(_('%(count)d messages exported to "%(path)s" (%(type)s)') % {'count':count, 'path':path, 'type': _('IMAP server')})
328 else:
329 parent.SetStatusText(_('%(new)d new of %(count)d messages exported to "%(path)s" (%(type)s)') % {'new':new_messages_num, 'count':count, 'path':path, 'type': _('IMAP server')})
331 def SMSExport(parent, messages, contacts):
332 # Select where to export
333 dlg = wx.SingleChoiceDialog(parent, _('Where do you want to export emails created from your messages?'), _('Select export type'),
334 [_('Mailbox file'), _('Maildir folder'), _('IMAP account')], wx.CHOICEDLG_STYLE | wx.RESIZE_BORDER)
335 if dlg.ShowModal() != wx.ID_OK:
336 return
338 idx = dlg.GetSelection()
339 del dlg
341 # Mailbox
342 if idx == 0:
343 SMSToMailbox(parent, messages, contacts)
344 # Maildir
345 elif idx == 1:
346 SMSToMaildir(parent, messages, contacts)
347 # IMAP
348 elif idx == 2:
349 SMSToIMAP(parent, messages, contacts)
350 else:
351 raise Exception('Not implemented export functionality!')
353 def bool2yn(value):
354 if value:
355 return 'yes'
356 else:
357 return 'no'
359 def yn2bool(value):
360 return value == 'yes'
362 class IMAPConfigHelper:
364 A small helper to read and write the Wammu config
366 def __init__(self, WammuConfig):
367 self.wcfg = WammuConfig
368 self.load()
370 def load(self):
372 # Textfields
373 self.fromAddress = self.wcfg.Read('/MessageExport/From')
374 self.server = self.wcfg.Read('/IMAP/Server')
375 self.port = self.wcfg.Read('/IMAP/Port')
376 self.login = self.wcfg.Read('/IMAP/Login')
377 self.password = self.wcfg.Read('/IMAP/Password')
379 # Checkboxes
380 self.rememberPassword = yn2bool(self.wcfg.Read('/IMAP/RememberPassword'))
381 self.useSSL = yn2bool(self.wcfg.Read('/IMAP/UseSSL'))
382 self.newMessages = yn2bool(self.wcfg.Read('/IMAP/OnlyNewMessages'))
384 # States
385 self.backupRead = yn2bool(self.wcfg.Read('/IMAP/BackupStateRead'))
386 self.backupSent = yn2bool(self.wcfg.Read('/IMAP/BackupStateSent'))
387 self.backupUnread = yn2bool(self.wcfg.Read('/IMAP/BackupStateUnread'))
388 self.backupUnsent = yn2bool(self.wcfg.Read('/IMAP/BackupStateUnsent'))
390 if self.port == '':
391 if self.useSSL:
392 self.port = '993'
393 else:
394 self.port = '143'
396 def write(self):
398 # Textfields
399 self.wcfg.Write('/MessageExport/From', self.fromAddress)
400 self.wcfg.Write('/IMAP/Server', self.server)
401 self.wcfg.Write('/IMAP/Port', self.port)
402 self.wcfg.Write('/IMAP/Login', self.login)
403 if self.rememberPassword:
404 self.wcfg.Write('/IMAP/Password', self.password)
405 else:
406 self.wcfg.Write('/IMAP/Password', '')
408 # Checkboxes
409 self.wcfg.Write('/IMAP/RememberPassword', bool2yn(self.rememberPassword))
410 self.wcfg.Write('/IMAP/UseSSL', bool2yn(self.useSSL))
411 self.wcfg.Write('/IMAP/OnlyNewMessages', bool2yn(self.newMessages))
413 # States
414 self.wcfg.Write('/IMAP/BackupStateRead', bool2yn(self.backupRead))
415 self.wcfg.Write('/IMAP/BackupStateSent', bool2yn(self.backupSent))
416 self.wcfg.Write('/IMAP/BackupStateUnread', bool2yn(self.backupUnread))
417 self.wcfg.Write('/IMAP/BackupStateUnsent', bool2yn(self.backupUnsent))
420 class IMAPSettingsDialog(wx.Dialog):
421 def __init__(self, parent, imapConfig):
422 wx.Dialog.__init__(self, parent, -1, _("IMAP Settings"), style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
423 self.cfg = imapConfig
424 self.connectionFrameSizer_staticbox = wx.StaticBox(self, -1, _("Connection Details"))
425 self.preferenciesFrameSizer_staticbox = wx.StaticBox(self, -1, _("Preferences"))
426 self.stateFrameSizer_staticbox = wx.StaticBox(self, -1, _("Message State Selection"))
427 self.fromAddressLabel = wx.StaticText(self, -1, _("From Address"))
428 self.fromAddressTextCtrl = wx.TextCtrl(self, -1, "")
429 self.serverLabel = wx.StaticText(self, -1, _("Server"))
430 self.serverTextCtrl = wx.TextCtrl(self, -1, "")
431 self.portLabel = wx.StaticText(self, -1, _("Port"))
432 self.portTextCtrl = wx.TextCtrl(self, -1, "")
433 self.loginLabel = wx.StaticText(self, -1, _("Login"))
434 self.loginTextCtrl = wx.TextCtrl(self, -1, "")
435 self.passwordLabel = wx.StaticText(self, -1, _("Password"))
436 self.passwordTextCtrl = wx.TextCtrl(self, -1, "", style=wx.TE_PASSWORD)
437 self.rememberCheckBox = wx.CheckBox(self, -1, _("Remember password (insecure)"))
438 self.useSSLCheckBox = wx.CheckBox(self, -1, _("Use SSL"))
439 self.newMessagesCheckBox = wx.CheckBox(self, -1, _("Only back-up new messages"))
440 self.readCheckBox = wx.CheckBox(self, -1, _("Read"))
441 self.sentCheckBox = wx.CheckBox(self, -1, _("Sent"))
442 self.unreadCheckBox = wx.CheckBox(self, -1, _("Unread"))
443 self.unsentCheckBox = wx.CheckBox(self, -1, _("Unsent"))
444 self.applyButton = wx.Button(self, wx.ID_APPLY, "")
445 self.cancelButton = wx.Button(self, wx.ID_CANCEL, "")
446 self.okButton = wx.Button(self, wx.ID_OK, "")
448 self.__read_config()
449 self.__do_layout()
451 self.Bind(wx.EVT_CHECKBOX, self.OnToggleSSL, self.useSSLCheckBox)
452 self.Bind(wx.EVT_BUTTON, self.OnOkClick, self.okButton)
453 self.Bind(wx.EVT_BUTTON, self.OnApplyClick, self.applyButton)
455 def __read_config(self):
456 self.fromAddressTextCtrl.SetValue(self.cfg.fromAddress)
457 self.serverTextCtrl.SetValue(self.cfg.server)
458 self.portTextCtrl.SetValue(self.cfg.port)
459 self.loginTextCtrl.SetValue(self.cfg.login)
460 self.passwordTextCtrl.SetValue(self.cfg.password)
462 self.rememberCheckBox.SetValue(self.cfg.rememberPassword)
463 self.useSSLCheckBox.SetValue(self.cfg.useSSL)
464 self.newMessagesCheckBox.SetValue(self.cfg.newMessages)
466 self.readCheckBox.SetValue(self.cfg.backupRead)
467 self.sentCheckBox.SetValue(self.cfg.backupSent)
468 self.unreadCheckBox.SetValue(self.cfg.backupUnread)
469 self.unsentCheckBox.SetValue(self.cfg.backupUnsent)
471 def __copy_config(self):
472 self.cfg.fromAddress = self.fromAddressTextCtrl.GetValue()
473 self.cfg.server = self.serverTextCtrl.GetValue()
474 self.cfg.port = self.portTextCtrl.GetValue()
475 self.cfg.login = self.loginTextCtrl.GetValue()
476 self.cfg.password = self.passwordTextCtrl.GetValue()
478 self.cfg.rememberPassword = self.rememberCheckBox.GetValue()
479 self.cfg.useSSL = self.useSSLCheckBox.GetValue()
480 self.cfg.newMessages = self.useSSLCheckBox.GetValue()
482 self.cfg.backupRead = self.readCheckBox.GetValue()
483 self.cfg.backupSent = self.sentCheckBox.GetValue()
484 self.cfg.backupUnread = self.unreadCheckBox.GetValue()
485 self.cfg.backupUnsent = self.unsentCheckBox.GetValue()
487 def __do_layout(self):
488 mainSizer = wx.BoxSizer(wx.VERTICAL)
489 buttonRowSizer = wx.BoxSizer(wx.HORIZONTAL)
490 stateFrameSizer = wx.StaticBoxSizer(self.stateFrameSizer_staticbox, wx.HORIZONTAL)
491 preferenciesFrameSizer = wx.StaticBoxSizer(self.preferenciesFrameSizer_staticbox, wx.HORIZONTAL)
492 preferenciesGridSizer = wx.FlexGridSizer(3, 2, 2, 2)
493 connectionFrameSizer = wx.StaticBoxSizer(self.connectionFrameSizer_staticbox, wx.HORIZONTAL)
494 connectionGridSizer = wx.FlexGridSizer(5, 2, 2, 10)
495 connectionGridSizer.Add(self.fromAddressLabel, 0, wx.ALIGN_CENTER_VERTICAL, 0)
496 connectionGridSizer.Add(self.fromAddressTextCtrl, 0, wx.EXPAND, 0)
497 connectionGridSizer.Add(self.serverLabel, 0, wx.ALIGN_CENTER_VERTICAL, 0)
498 connectionGridSizer.Add(self.serverTextCtrl, 0, wx.EXPAND, 0)
499 connectionGridSizer.Add(self.portLabel, 0, wx.ALIGN_CENTER_VERTICAL, 0)
500 connectionGridSizer.Add(self.portTextCtrl, 0, wx.EXPAND, 0)
501 connectionGridSizer.Add(self.loginLabel, 0, wx.ALIGN_CENTER_VERTICAL, 0)
502 connectionGridSizer.Add(self.loginTextCtrl, 0, wx.EXPAND, 0)
503 connectionGridSizer.Add(self.passwordLabel, 0, wx.ALIGN_CENTER_VERTICAL, 0)
504 connectionGridSizer.Add(self.passwordTextCtrl, 0, wx.EXPAND, 0)
505 connectionGridSizer.AddGrowableCol(1)
506 connectionFrameSizer.Add(connectionGridSizer, 1, wx.EXPAND, 0)
507 mainSizer.Add(connectionFrameSizer, 0, wx.ALL|wx.EXPAND, 2)
508 preferenciesGridSizer.Add((90, 20), 0, 0, 0)
509 preferenciesGridSizer.Add(self.rememberCheckBox, 0, 0, 0)
510 preferenciesGridSizer.Add((20, 20), 0, 0, 0)
511 preferenciesGridSizer.Add(self.useSSLCheckBox, 0, 0, 0)
512 preferenciesGridSizer.Add((20, 20), 0, 0, 0)
513 preferenciesGridSizer.Add(self.newMessagesCheckBox, 0, 0, 0)
514 preferenciesGridSizer.AddGrowableCol(1)
515 preferenciesFrameSizer.Add(preferenciesGridSizer, 1, wx.EXPAND, 0)
516 mainSizer.Add(preferenciesFrameSizer, 0, wx.ALL|wx.EXPAND, 2)
517 stateFrameSizer.Add(self.readCheckBox, 1, wx.EXPAND, 0)
518 stateFrameSizer.Add(self.sentCheckBox, 1, wx.EXPAND, 0)
519 stateFrameSizer.Add(self.unreadCheckBox, 1, wx.EXPAND, 0)
520 stateFrameSizer.Add(self.unsentCheckBox, 1, wx.EXPAND, 0)
521 mainSizer.Add(stateFrameSizer, 0, wx.ALL|wx.EXPAND, 2)
522 buttonRowSizer.Add((20, 20), 1, wx.EXPAND, 0)
523 buttonRowSizer.Add(self.applyButton, 0, wx.ALIGN_BOTTOM, 0)
524 buttonRowSizer.Add(self.cancelButton, 0, wx.ALIGN_BOTTOM, 0)
525 buttonRowSizer.Add(self.okButton, 0, wx.ALIGN_BOTTOM, 0)
526 mainSizer.Add(buttonRowSizer, 1, wx.ALL|wx.EXPAND, 2)
527 self.SetSizer(mainSizer)
528 mainSizer.Fit(self)
529 self.Layout()
531 def OnToggleSSL(self, event):
532 if self.useSSLCheckBox.GetValue():
533 if self.portTextCtrl.GetValue() == '143':
534 self.portTextCtrl.SetValue('993')
535 else:
536 if self.portTextCtrl.GetValue() == '993':
537 self.portTextCtrl.SetValue('143')
540 def OnApplyClick(self, event):
541 self.__copy_config()
542 self.cfg.write()
544 def OnOkClick(self, event):
545 # check for all required fields
546 counter = 0
547 error = ''
548 if self.fromAddressTextCtrl.GetValue() == "":
549 counter += 1
550 error += _('%d. From Address invalid\n') % counter
551 if self.serverTextCtrl.GetValue() == "":
552 counter += 1
553 error += _('%d. Server incomplete\n') % counter
554 if self.portTextCtrl.GetValue() == "" or re.search('\D', self.portTextCtrl.GetValue()) :
555 counter += 1
556 error += _('%d. Port invalid\n') % counter
557 if self.loginTextCtrl.GetValue() == "":
558 counter += 1
559 error += _('%d. Login incomplete\n') % counter
560 if self.passwordTextCtrl.GetValue() == "":
561 counter += 1
562 error += _('%d. Password incomplete\n') % counter
563 if not self.readCheckBox.GetValue() and \
564 not self.sentCheckBox.GetValue() and \
565 not self.unreadCheckBox.GetValue() and \
566 not self.unsentCheckBox.GetValue():
567 counter += 1
568 error += _('%d. No messages to back-up selected. Please tick at least one of the states.') % counter
570 if counter != 0:
571 wx.MessageDialog(self,
572 error,
573 _('Incomplete'),
574 wx.OK | wx.ICON_ERROR).ShowModal()
575 else:
576 self.__copy_config()
577 event.Skip()
579 # end of class IMAPSettingsDialog