comparison frontends/wix/main_window.py @ 70:8f2ed279784b

i18n - gettext support added in frontends - first draft of frontends french translation
author Goffi <goffi@goffi.org>
date Fri, 05 Mar 2010 20:33:10 +1100
parents 9b842086d915
children f271fff3a713
comparison
equal deleted inserted replaced
69:86f1f7f6d332 70:8f2ed279784b
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """ 20 """
21 21
22 22
23 from quick_frontend.quick_chat_list import QuickChatList
24 from quick_frontend.quick_app import QuickApp
25 from quick_frontend.quick_contact_list import QuickContactList
26 from quick_frontend.quick_contact_management import QuickContactManagement
23 import wx 27 import wx
24 from chat import Chat 28 from chat import Chat
25 from param import Param 29 from param import Param
26 from form import Form 30 from form import Form
27 from gateways import GatewaysManager 31 from gateways import GatewaysManager
30 import gobject 34 import gobject
31 import os.path 35 import os.path
32 import pdb 36 import pdb
33 from tools.jid import JID 37 from tools.jid import JID
34 from logging import debug, info, error 38 from logging import debug, info, error
35 from quick_frontend.quick_chat_list import QuickChatList
36 from quick_frontend.quick_contact_list import QuickContactList
37 from quick_frontend.quick_app import QuickApp
38 from quick_frontend.quick_contact_management import QuickContactManagement
39 from cgi import escape 39 from cgi import escape
40 import sys 40 import sys
41 41
42 IMAGE_DIR = sys.path[0]+'/images' 42 IMAGE_DIR = sys.path[0]+'/images'
43 43
50 idADD_CONTACT,\ 50 idADD_CONTACT,\
51 idREMOVE_CONTACT,\ 51 idREMOVE_CONTACT,\
52 idSHOW_PROFILE,\ 52 idSHOW_PROFILE,\
53 idFIND_GATEWAYS = range(8) 53 idFIND_GATEWAYS = range(8)
54 const_DEFAULT_GROUP = "Unclassed" 54 const_DEFAULT_GROUP = "Unclassed"
55 const_STATUS = [("", "Online", None), 55 const_STATUS = [("", _("Online"), None),
56 ("chat", "Free for chat", "green"), 56 ("chat", _("Free for chat"), "green"),
57 ("away", "AFK", "brown"), 57 ("away", _("AFK"), "brown"),
58 ("dnd", "DND", "red"), 58 ("dnd", _("DND"), "red"),
59 ("xa", "Away", "red")] 59 ("xa", _("Away"), "red")]
60 60
61 class ChatList(QuickChatList): 61 class ChatList(QuickChatList):
62 """This class manage the list of chat windows""" 62 """This class manage the list of chat windows"""
63 63
64 def __init__(self, host): 64 def __init__(self, host):
88 self.GetClientData(i) == entity: 88 self.GetClientData(i) == entity:
89 result.append(i) 89 result.append(i)
90 return result 90 return result
91 91
92 def replace(self, jid): 92 def replace(self, jid):
93 debug("update %s" % jid) 93 debug(_("update %s") % jid)
94 if not self.__find_idx(jid): 94 if not self.__find_idx(jid):
95 self.add(jid) 95 self.add(jid)
96 else: 96 else:
97 for i in self.__find_idx(jid): 97 for i in self.__find_idx(jid):
98 self.SetString(i, self.__presentItem(jid)) 98 self.SetString(i, self.__presentItem(jid))
153 """Clear all the contact list""" 153 """Clear all the contact list"""
154 self.Clear() 154 self.Clear()
155 155
156 def add(self, jid): 156 def add(self, jid):
157 """add a contact to the list""" 157 """add a contact to the list"""
158 debug ("adding %s",jid) 158 debug (_("adding %s"),jid)
159 groups = self.CM.getAttr(jid, 'groups') 159 groups = self.CM.getAttr(jid, 'groups')
160 if not groups: 160 if not groups:
161 idx = self.Append(self.__presentItem(jid), jid) 161 idx = self.Append(self.__presentItem(jid), jid)
162 else: 162 else:
163 for group in groups: 163 for group in groups:
172 172
173 173
174 174
175 def remove(self, jid): 175 def remove(self, jid):
176 """remove a contact from the list""" 176 """remove a contact from the list"""
177 debug ("removing %s",jid) 177 debug (_("removing %s"),jid)
178 list_idx = self.__find_idx(jid) 178 list_idx = self.__find_idx(jid)
179 list_idx.reverse() #we me make some deletions, we have to reverse the order 179 list_idx.reverse() #we me make some deletions, we have to reverse the order
180 for i in list_idx: 180 for i in list_idx:
181 self.Delete(i) 181 self.Delete(i)
182 182
252 self.tools.Disable() 252 self.tools.Disable()
253 253
254 #tray icon 254 #tray icon
255 ticon = wx.Icon(IMAGE_DIR+'/crystal/tray_icon.xpm', wx.BITMAP_TYPE_XPM) 255 ticon = wx.Icon(IMAGE_DIR+'/crystal/tray_icon.xpm', wx.BITMAP_TYPE_XPM)
256 self.tray_icon = wx.TaskBarIcon() 256 self.tray_icon = wx.TaskBarIcon()
257 self.tray_icon.SetIcon(ticon, "Wix jabber client") 257 self.tray_icon.SetIcon(ticon, _("Wix jabber client"))
258 wx.EVT_TASKBAR_LEFT_UP(self.tray_icon, self.onTrayClick) 258 wx.EVT_TASKBAR_LEFT_UP(self.tray_icon, self.onTrayClick)
259 259
260 260
261 #events 261 #events
262 self.Bind(wx.EVT_CLOSE, self.onClose, self) 262 self.Bind(wx.EVT_CLOSE, self.onClose, self)
281 super(MainWindow, self).plug_profile(profile_key) 281 super(MainWindow, self).plug_profile(profile_key)
282 if not self.bridge.isConnected(profile_key): 282 if not self.bridge.isConnected(profile_key):
283 self.bridge.connect(profile_key) 283 self.bridge.connect(profile_key)
284 284
285 def createMenus(self): 285 def createMenus(self):
286 info("Creating menus") 286 info(_("Creating menus"))
287 connectMenu = wx.Menu() 287 connectMenu = wx.Menu()
288 connectMenu.Append(idCONNECT, "&Connect CTRL-c"," Connect to the server") 288 connectMenu.Append(idCONNECT, _("&Connect CTRL-c"),_(" Connect to the server"))
289 connectMenu.Append(idDISCONNECT, "&Disconnect CTRL-d"," Disconnect from the server") 289 connectMenu.Append(idDISCONNECT, _("&Disconnect CTRL-d"),_(" Disconnect from the server"))
290 connectMenu.Append(idPARAM,"&Parameters"," Configure the program") 290 connectMenu.Append(idPARAM,_("&Parameters"),_(" Configure the program"))
291 connectMenu.AppendSeparator() 291 connectMenu.AppendSeparator()
292 connectMenu.Append(idEXIT,"E&xit"," Terminate the program") 292 connectMenu.Append(idEXIT,_("E&xit"),_(" Terminate the program"))
293 contactMenu = wx.Menu() 293 contactMenu = wx.Menu()
294 contactMenu.Append(idADD_CONTACT, "&Add contact"," Add a contact to your list") 294 contactMenu.Append(idADD_CONTACT, _("&Add contact"),_(" Add a contact to your list"))
295 contactMenu.Append(idREMOVE_CONTACT, "&Remove contact"," Remove the selected contact from your list") 295 contactMenu.Append(idREMOVE_CONTACT, _("&Remove contact"),_(" Remove the selected contact from your list"))
296 contactMenu.AppendSeparator() 296 contactMenu.AppendSeparator()
297 contactMenu.Append(idSHOW_PROFILE, "&Show profile", " Show contact's profile") 297 contactMenu.Append(idSHOW_PROFILE, _("&Show profile"), _(" Show contact's profile"))
298 communicationMenu = wx.Menu() 298 communicationMenu = wx.Menu()
299 communicationMenu.Append(idFIND_GATEWAYS, "&Find Gateways"," Find gateways to legacy IM") 299 communicationMenu.Append(idFIND_GATEWAYS, _("&Find Gateways"),_(" Find gateways to legacy IM"))
300 self.menuBar = wx.MenuBar() 300 self.menuBar = wx.MenuBar()
301 self.menuBar.Append(connectMenu,"&General") 301 self.menuBar.Append(connectMenu,_("&General"))
302 self.menuBar.Append(contactMenu,"&Contacts") 302 self.menuBar.Append(contactMenu,_("&Contacts"))
303 self.menuBar.Append(communicationMenu,"&Communication") 303 self.menuBar.Append(communicationMenu,_("&Communication"))
304 self.SetMenuBar(self.menuBar) 304 self.SetMenuBar(self.menuBar)
305 305
306 #events 306 #events
307 wx.EVT_MENU(self, idCONNECT, self.onConnectRequest) 307 wx.EVT_MENU(self, idCONNECT, self.onConnectRequest)
308 wx.EVT_MENU(self, idDISCONNECT, self.onDisconnectRequest) 308 wx.EVT_MENU(self, idDISCONNECT, self.onDisconnectRequest)
337 flags = wx.OK | wx.ICON_ERROR 337 flags = wx.OK | wx.ICON_ERROR
338 elif type == 'yes/no': 338 elif type == 'yes/no':
339 flags = wx.YES_NO | wx.ICON_QUESTION 339 flags = wx.YES_NO | wx.ICON_QUESTION
340 else: 340 else:
341 flags = wx.OK | wx.ICON_INFORMATION 341 flags = wx.OK | wx.ICON_INFORMATION
342 error('unmanaged dialog type: %s', type) 342 error(_('unmanaged dialog type: %s'), type)
343 dlg = wx.MessageDialog(self, message, title, flags) 343 dlg = wx.MessageDialog(self, message, title, flags)
344 answer = dlg.ShowModal() 344 answer = dlg.ShowModal()
345 dlg.Destroy() 345 dlg.Destroy()
346 return True if (answer == wx.ID_YES or answer == wx.ID_OK) else False 346 return True if (answer == wx.ID_YES or answer == wx.ID_OK) else False
347 347
355 self.tools.Disable() 355 self.tools.Disable()
356 return 356 return
357 357
358 def askConfirmation(self, type, id, data): 358 def askConfirmation(self, type, id, data):
359 #TODO: refactor this in QuickApp 359 #TODO: refactor this in QuickApp
360 debug ("Confirmation asked") 360 debug (_("Confirmation asked"))
361 answer_data={} 361 answer_data={}
362 if type == "FILE_TRANSFERT": 362 if type == "FILE_TRANSFERT":
363 debug ("File transfert confirmation asked") 363 debug (_("File transfert confirmation asked"))
364 dlg = wx.MessageDialog(self, "The contact %s wants to send you the file %s\nDo you accept ?" % (data["from"], data["filename"]), 364 dlg = wx.MessageDialog(self, _("The contact %(jid)s wants to send you the file %(filename)s\nDo you accept ?") % {'jid':data["from"], 'filename':data["filename"]},
365 'File Request', 365 _('File Request'),
366 wx.YES_NO | wx.ICON_QUESTION 366 wx.YES_NO | wx.ICON_QUESTION
367 ) 367 )
368 answer=dlg.ShowModal() 368 answer=dlg.ShowModal()
369 if answer==wx.ID_YES: 369 if answer==wx.ID_YES:
370 filename = wx.FileSelector("Where do you want to save the file ?", flags = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) 370 filename = wx.FileSelector(_("Where do you want to save the file ?"), flags = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
371 if filename: 371 if filename:
372 answer_data["dest_path"] = filename 372 answer_data["dest_path"] = filename
373 self.bridge.confirmationAnswer(id, True, answer_data) 373 self.bridge.confirmationAnswer(id, True, answer_data)
374 self.waitProgress(id, "File Transfer", "Copying %s" % os.path.basename(filename)) 374 self.waitProgress(id, _("File Transfer"), _("Copying %s") % os.path.basename(filename))
375 else: 375 else:
376 answer = wx.ID_NO 376 answer = wx.ID_NO
377 if answer==wx.ID_NO: 377 if answer==wx.ID_NO:
378 self.bridge.confirmationAnswer(id, False, answer_data) 378 self.bridge.confirmationAnswer(id, False, answer_data)
379 379
380 dlg.Destroy() 380 dlg.Destroy()
381 381
382 elif type == "YES/NO": 382 elif type == "YES/NO":
383 debug ("Yes/No confirmation asked") 383 debug (_("Yes/No confirmation asked"))
384 dlg = wx.MessageDialog(self, data["message"], 384 dlg = wx.MessageDialog(self, data["message"],
385 'Confirmation', 385 _('Confirmation'),
386 wx.YES_NO | wx.ICON_QUESTION 386 wx.YES_NO | wx.ICON_QUESTION
387 ) 387 )
388 answer=dlg.ShowModal() 388 answer=dlg.ShowModal()
389 if answer==wx.ID_YES: 389 if answer==wx.ID_YES:
390 self.bridge.confirmationAnswer(id, True, {}) 390 self.bridge.confirmationAnswer(id, True, {})
392 self.bridge.confirmationAnswer(id, False, {}) 392 self.bridge.confirmationAnswer(id, False, {})
393 393
394 dlg.Destroy() 394 dlg.Destroy()
395 395
396 def actionResult(self, type, id, data): 396 def actionResult(self, type, id, data):
397 debug ("actionResult: type = [%s] id = [%s] data = [%s]" % (type, id, data)) 397 debug (_("actionResult: type = [%(type)s] id = [%(id)s] data = [%(data)s]") % {'type':type, 'id':id, 'data':data})
398 if not id in self.current_action_ids: 398 if not id in self.current_action_ids:
399 debug ('unknown id, ignoring') 399 debug (_('unknown id, ignoring'))
400 return 400 return
401 if type == "SUPPRESS": 401 if type == "SUPPRESS":
402 self.current_action_ids.remove(id) 402 self.current_action_ids.remove(id)
403 elif type == "SUCCESS": 403 elif type == "SUCCESS":
404 self.current_action_ids.remove(id) 404 self.current_action_ids.remove(id)
405 dlg = wx.MessageDialog(self, data["message"], 405 dlg = wx.MessageDialog(self, data["message"],
406 'Success', 406 _('Success'),
407 wx.OK | wx.ICON_INFORMATION 407 wx.OK | wx.ICON_INFORMATION
408 ) 408 )
409 dlg.ShowModal() 409 dlg.ShowModal()
410 dlg.Destroy() 410 dlg.Destroy()
411 elif type == "ERROR": 411 elif type == "ERROR":
412 self.current_action_ids.remove(id) 412 self.current_action_ids.remove(id)
413 dlg = wx.MessageDialog(self, data["message"], 413 dlg = wx.MessageDialog(self, data["message"],
414 'Error', 414 _('Error'),
415 wx.OK | wx.ICON_ERROR 415 wx.OK | wx.ICON_ERROR
416 ) 416 )
417 dlg.ShowModal() 417 dlg.ShowModal()
418 dlg.Destroy() 418 dlg.Destroy()
419 elif type == "FORM": 419 elif type == "FORM":
420 self.current_action_ids.remove(id) 420 self.current_action_ids.remove(id)
421 debug ("Form received") 421 debug (_("Form received"))
422 form=Form(self, title='Registration', target = data['target'], type = data['type'], xml_data = data['xml']) 422 form=Form(self, title=_('Registration'), target = data['target'], type = data['type'], xml_data = data['xml'])
423 elif type == "RESULT": 423 elif type == "RESULT":
424 self.current_action_ids.remove(id) 424 self.current_action_ids.remove(id)
425 if self.current_action_ids_cb.has_key(id): 425 if self.current_action_ids_cb.has_key(id):
426 callback = self.current_action_ids_cb[id] 426 callback = self.current_action_ids_cb[id]
427 del self.current_action_ids_cb[id] 427 del self.current_action_ids_cb[id]
431 if self.current_action_ids_cb.has_key(id): 431 if self.current_action_ids_cb.has_key(id):
432 callback = self.current_action_ids_cb[id] 432 callback = self.current_action_ids_cb[id]
433 del self.current_action_ids_cb[id] 433 del self.current_action_ids_cb[id]
434 callback(data) 434 callback(data)
435 else: 435 else:
436 error ("FIXME FIXME FIXME: type [%s] not implemented" % type) 436 error (_("FIXME FIXME FIXME: type [%s] not implemented") % type)
437 raise NotImplementedError 437 raise NotImplementedError
438 438
439 439
440 440
441 def progressCB(self, id, title, message): 441 def progressCB(self, id, title, message):
463 463
464 464
465 ### events ### 465 ### events ###
466 466
467 def onContactActivated(self, jid): 467 def onContactActivated(self, jid):
468 debug ("onContactActivated: %s", jid) 468 debug (_("onContactActivated: %s"), jid)
469 if self.chat_wins[jid.short].IsShown(): 469 if self.chat_wins[jid.short].IsShown():
470 self.chat_wins[jid.short].Hide() 470 self.chat_wins[jid.short].Hide()
471 else: 471 else:
472 self.chat_wins[jid.short].Show() 472 self.chat_wins[jid.short].Show()
473 473
481 show = filter(lambda x:x[1] == self.statusBox.GetValue(), const_STATUS)[0][0] 481 show = filter(lambda x:x[1] == self.statusBox.GetValue(), const_STATUS)[0][0]
482 status = self.statusTxt.GetValue() 482 status = self.statusTxt.GetValue()
483 self.bridge.setPresence(show=show, statuses={'default':status}) #FIXME: manage multilingual statuses 483 self.bridge.setPresence(show=show, statuses={'default':status}) #FIXME: manage multilingual statuses
484 484
485 def onStatusChange(self, e): 485 def onStatusChange(self, e):
486 debug("Status change request") 486 debug(_("Status change request"))
487 self.__updateStatus() 487 self.__updateStatus()
488 488
489 def onParam(self, e): 489 def onParam(self, e):
490 debug("Param request") 490 debug(_("Param request"))
491 param=Param(self) 491 param=Param(self)
492 492
493 def onExit(self, e): 493 def onExit(self, e):
494 self.Close() 494 self.Close()
495 495
496 def onAddContact(self, e): 496 def onAddContact(self, e):
497 debug("Add contact request") 497 debug(_("Add contact request"))
498 dlg = wx.TextEntryDialog( 498 dlg = wx.TextEntryDialog(
499 self, 'Please enter new contact JID', 499 self, _('Please enter new contact JID'),
500 'Adding a contact', 'name@server.tld') 500 _('Adding a contact'), _('name@server.tld'))
501 501
502 if dlg.ShowModal() == wx.ID_OK: 502 if dlg.ShowModal() == wx.ID_OK:
503 jid=JID(dlg.GetValue()) 503 jid=JID(dlg.GetValue())
504 if jid.is_valid(): 504 if jid.is_valid():
505 self.bridge.addContact(jid.short) 505 self.bridge.addContact(jid.short)
506 else: 506 else:
507 error ("'%s' is an invalid JID !", jid) 507 error (_("'%s' is an invalid JID !"), jid)
508 #TODO: notice the user 508 #TODO: notice the user
509 509
510 dlg.Destroy() 510 dlg.Destroy()
511 511
512 def onRemoveContact(self, e): 512 def onRemoveContact(self, e):
513 debug("Remove contact request") 513 debug(_("Remove contact request"))
514 target = self.contactList.getSelection() 514 target = self.contactList.getSelection()
515 if not target: 515 if not target:
516 dlg = wx.MessageDialog(self, "You haven't selected any contact !", 516 dlg = wx.MessageDialog(self, _("You haven't selected any contact !"),
517 'Error', 517 _('Error'),
518 wx.OK | wx.ICON_ERROR 518 wx.OK | wx.ICON_ERROR
519 ) 519 )
520 dlg.ShowModal() 520 dlg.ShowModal()
521 dlg.Destroy() 521 dlg.Destroy()
522 return 522 return
523 523
524 dlg = wx.MessageDialog(self, "Are you sure you want to delete %s from your roster list ?" % target.short, 524 dlg = wx.MessageDialog(self, _("Are you sure you want to delete %s from your roster list ?") % target.short,
525 'Contact suppression', 525 _('Contact suppression'),
526 wx.YES_NO | wx.ICON_QUESTION 526 wx.YES_NO | wx.ICON_QUESTION
527 ) 527 )
528 528
529 if dlg.ShowModal() == wx.ID_YES: 529 if dlg.ShowModal() == wx.ID_YES:
530 info("Unsubscribing %s presence", target.short) 530 info(_("Unsubscribing %s presence"), target.short)
531 self.bridge.delContact(target.short) 531 self.bridge.delContact(target.short)
532 532
533 dlg.Destroy() 533 dlg.Destroy()
534 534
535 def onShowProfile(self, e): 535 def onShowProfile(self, e):
536 debug("Show contact's profile request") 536 debug(_("Show contact's profile request"))
537 target = self.contactList.getSelection() 537 target = self.contactList.getSelection()
538 if not target: 538 if not target:
539 dlg = wx.MessageDialog(self, "You haven't selected any contact !", 539 dlg = wx.MessageDialog(self, _("You haven't selected any contact !"),
540 'Error', 540 _('Error'),
541 wx.OK | wx.ICON_ERROR 541 wx.OK | wx.ICON_ERROR
542 ) 542 )
543 dlg.ShowModal() 543 dlg.ShowModal()
544 dlg.Destroy() 544 dlg.Destroy()
545 return 545 return
547 self.current_action_ids.add(id) 547 self.current_action_ids.add(id)
548 self.current_action_ids_cb[id] = self.onProfileReceived 548 self.current_action_ids_cb[id] = self.onProfileReceived
549 549
550 def onProfileReceived(self, data): 550 def onProfileReceived(self, data):
551 """Called when a profile is received""" 551 """Called when a profile is received"""
552 debug ('Profile received: [%s]' % data) 552 debug (_('Profile received: [%s]') % data)
553 profile=Profile(self, data) 553 profile=Profile(self, data)
554 554
555 555
556 def onFindGateways(self, e): 556 def onFindGateways(self, e):
557 debug("Find Gateways request") 557 debug(_("Find Gateways request"))
558 id = self.bridge.findGateways(self.profiles[self.profile]['whoami'].domain) 558 id = self.bridge.findGateways(self.profiles[self.profile]['whoami'].domain)
559 self.current_action_ids.add(id) 559 self.current_action_ids.add(id)
560 self.current_action_ids_cb[id] = self.onGatewaysFound 560 self.current_action_ids_cb[id] = self.onGatewaysFound
561 561
562 def onGatewaysFound(self, data): 562 def onGatewaysFound(self, data):
564 target = data['__private__']['target'] 564 target = data['__private__']['target']
565 del data['__private__'] 565 del data['__private__']
566 gatewayManager = GatewaysManager(self, data, server=target) 566 gatewayManager = GatewaysManager(self, data, server=target)
567 567
568 def onClose(self, e): 568 def onClose(self, e):
569 info("Exiting...") 569 info(_("Exiting..."))
570 e.Skip() 570 e.Skip()
571 571
572 def onTrayClick(self, e): 572 def onTrayClick(self, e):
573 debug("Tray Click") 573 debug(_("Tray Click"))
574 if self.IsShown(): 574 if self.IsShown():
575 self.Hide() 575 self.Hide()
576 else: 576 else:
577 self.Show() 577 self.Show()
578 self.Raise() 578 self.Raise()