home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / gui / imwin / imwin_ctrl.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  17.2 KB  |  494 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. import wx
  6. from wx import EVT_BUTTON, MessageBox, PyTimer
  7. from operator import attrgetter
  8. from traceback import print_exc
  9. from logging import getLogger
  10. log = getLogger('imwinctrl')
  11. info = log.info
  12. info_s = getattr(log, 'info_s', log.info)
  13. from util import Storage as traceguard
  14. from common import profile, prefprop
  15. from common.message import Message
  16. from gui.infobox.htmlgeneration import GetInfo
  17. from gui.imwin.imwin_tofrom import IMControl, EmailControl, SMSControl
  18. from gui.toolbox import check_destroyed, calllimit
  19. from common.sms import SMS_MAX_LENGTH
  20.  
  21. class ImWinCtrl(object):
  22.     
  23.     def __init__(self):
  24.         self.IMControl = IMControl(self.capsbar, self.To, self.From)
  25.         self.IMControl.OnSelection += self.FocusTextCtrl
  26.         (self.IMControl.OnSwitchContact,) += (lambda c: self.set_conversation(c.protocol.convo_for(c)))
  27.         self.EmailControl = EmailControl(self.To, self.From)
  28.         (self.EmailControl.OnLoseFocus,) += (lambda : self._emailpanel.subject_input.SetFocus())
  29.         self.SMSControl = SMSControl(self.To, self.From)
  30.         self.SMSControl.OnLoseFocus += self.FocusTextCtrl
  31.         self.controllers = {
  32.             'im': self.IMControl,
  33.             'email': self.EmailControl,
  34.             'sms': self.SMSControl }
  35.         self.mode = None
  36.         self.convo = None
  37.         self.typing = None
  38.         self.typing_status = None
  39.         self.typing_timer = None
  40.         self.GetButton('im').Bind((EVT_BUTTON,), (lambda e: self.set_mode('im', toggle_tofrom = True)))
  41.         for mode in ('email', 'sms', 'info'):
  42.             self.GetButton(mode).Bind(EVT_BUTTON, (lambda e, mode = (mode,): self.set_mode(mode)))
  43.         
  44.         self.GetButton('video').Bind((EVT_BUTTON,), (lambda e: self.on_video()))
  45.  
  46.     send_typing = prefprop('privacy.send_typing_notifications', True)
  47.     typed_delay = prefprop('messaging.typed_delay', 5)
  48.     
  49.     def message(self, messageobj, convo = None, mode = 'im', meta = None):
  50.         info('%r', self)
  51.         info_s('  messageobj: %r', messageobj)
  52.         info('       convo: %r', convo)
  53.         info('        mode: %r', mode)
  54.         info('        meta: %r', meta)
  55.         if messageobj is None:
  56.             self.set_conversation(convo)
  57.             self.set_mode(mode)
  58.             self.IMControl.SetConvo(convo)
  59.         elif (messageobj.get('sms', False) or convo.buddy.sms) and not profile.blist.on_buddylist(convo.buddy):
  60.             if self.convo is None:
  61.                 self.set_conversation(convo)
  62.             
  63.             if self.mode != 'sms':
  64.                 self.set_mode('sms')
  65.             
  66.             self.show_message(messageobj)
  67.         else:
  68.             convo = messageobj.conversation
  69.             if self.mode is None:
  70.                 self.set_mode(mode)
  71.             
  72.             self.show_message(messageobj)
  73.             self.set_conversation(convo)
  74.             self.IMControl.SetConvo(convo)
  75.  
  76.     
  77.     def set_mode(self, mode, toggle_tofrom = False):
  78.         self.Frozen().__enter__()
  79.         
  80.         try:
  81.             oldmode = getattr(self, 'mode', None)
  82.             self.on_mode_change(oldmode, mode, toggle_tofrom)
  83.             self.show_controls(mode)
  84.             self.on_mode_changed(mode)
  85.         finally:
  86.             pass
  87.  
  88.  
  89.     Mode = property(attrgetter('mode'), set_mode)
  90.     
  91.     def on_mode_change(self, oldmode, mode, toggle_tofrom = False):
  92.         if oldmode != mode and mode in ('email', 'sms'):
  93.             self.ShowToFrom(True)
  94.         elif mode == 'info':
  95.             self.ShowToFrom(False)
  96.         
  97.         if mode == 'sms' and oldmode != 'sms':
  98.             (wx.CallAfter,)((lambda : self.input_area.tc.SetMaxLength(SMS_MAX_LENGTH)))
  99.         elif oldmode == 'sms' and mode != 'sms':
  100.             (wx.CallAfter,)((lambda : self.input_area.tc.SetMaxLength(0)))
  101.         
  102.         for m in ('im', 'email', 'sms'):
  103.             if mode == m and oldmode != m:
  104.                 wx.CallAfter(self.controllers[mode].Apply)
  105.                 break
  106.                 continue
  107.         
  108.         if mode == 'im':
  109.             if oldmode != 'im':
  110.                 self.ShowToFrom(self.IMControl.HasChoices)
  111.             elif toggle_tofrom:
  112.                 self.ShowToFrom(not (self.capsbar.ToFromShown))
  113.             
  114.         
  115.         if oldmode is not None:
  116.             self.GetButton(oldmode).Active(False)
  117.         
  118.         self.GetButton(mode).Active(True)
  119.  
  120.     
  121.     def on_mode_changed(self, mode):
  122.         if mode in ('im', 'sms'):
  123.             self.on_message_area_shown()
  124.             if self.IsActive():
  125.                 self.FocusTextCtrl()
  126.             
  127.         elif mode == 'info':
  128.             self.set_profile_html(self.Buddy)
  129.             self.profile_html.SetFocus()
  130.         elif mode == 'email':
  131.             self._emailpanel.subject_input.SetFocus()
  132.         
  133.  
  134.     
  135.     def on_send_message(self):
  136.         getattr(self, 'on_send_message_' + self.mode, (lambda a: pass))()
  137.  
  138.     
  139.     def on_send_message_im(self, message = None):
  140.         val = None if message is not None else self.input_area.Value
  141.         if not val:
  142.             return None
  143.         
  144.         self.history.commit(val)
  145.         if self.set_conversation_from_combos():
  146.             self.convo.send_message(val, format = self.input_area.Format)
  147.             self.ClearAndFocus()
  148.         
  149.  
  150.     
  151.     def on_send_email(self, *a):
  152.         to = self.EmailControl.ToEmail
  153.         frm = self.EmailControl.FromAccount
  154.         if to is None:
  155.             return wx.MessageBox(_('Please add an email address for this buddy by clicking the "To:" box.'), _('Compose email to %s') % self.Buddy.name)
  156.         
  157.         epanel = self._emailpanel
  158.         
  159.         def success(*a):
  160.             log.info('Email send success')
  161.             profile.blist.add_tofrom('email', to, frm)
  162.             epanel.Clear()
  163.             epanel.SetStatusMessage(_('Message Sent'))
  164.             epanel.send_button.Enable(True)
  165.             epanel.openin.Enable(True)
  166.  
  167.         
  168.         def error(*a):
  169.             log.info('Email send error')
  170.             epanel.SetStatusMessage(_('Failed to Send Email'))
  171.             epanel.send_button.Enable(True)
  172.             epanel.openin.Enable(True)
  173.  
  174.         epanel.SetStatusMessage(_('Sending...'))
  175.         epanel.send_button.Enable(False)
  176.         epanel.openin.Enable(False)
  177.         frm.OnClickSend(to = to, subject = self._emailpanel.subject_input.Value, body = self._emailpanel.email_input_area.Value, success = success, error = error)
  178.  
  179.     
  180.     def on_send_message_sms(self):
  181.         if not self.input_area.Value:
  182.             return None
  183.         
  184.         to = self.SMSControl.ToSMS
  185.         frm = self.SMSControl.FromAccount
  186.         if to is None:
  187.             MessageBox(_('Please add an SMS number first.'), _('Send SMS Message'))
  188.         elif frm is None:
  189.             MessageBox(_('You are not signed in to any accounts which can send SMS messages.'), _('Send SMS Message'))
  190.         else:
  191.             message = self.input_area.Value
  192.             
  193.             def on_success():
  194.                 self.show_message(Message(buddy = frm.self_buddy, message = message[:SMS_MAX_LENGTH], conversation = self.convo, type = 'outgoing'))
  195.                 self.ClearAndFocus()
  196.  
  197.             
  198.             def on_error(errstr = None):
  199.                 if errstr is not None:
  200.                     more = _('\nThe error message received was:\n\t%s') % errstr
  201.                 else:
  202.                     more = ''
  203.                 MessageBox(_('There was an error in sending your SMS message.') + more, _('Send SMS Message Error'), style = wx.ICON_ERROR)
  204.  
  205.             if len(message) > SMS_MAX_LENGTH:
  206.                 if wx.NO == wx.MessageBox(_('Only the first %d characters of your message can be sent over SMS:\n\n"%s"\n\nDo you want to send this message now?') % (SMS_MAX_LENGTH, message), _('Send SMS - Character Limit'), style = wx.YES_NO):
  207.                     return None
  208.                 
  209.             
  210.             frm.send_sms(to, message[:SMS_MAX_LENGTH], success = on_success, error = on_error)
  211.  
  212.     
  213.     def on_edit_email(self):
  214.         to = self.EmailControl.ToEmail
  215.         frm = self.EmailControl.FromAccount
  216.         if to is not None and frm is not None:
  217.             frm.OnComposeEmail(to = to, subject = self._emailpanel.subject_input.Value, body = self._emailpanel.email_input_area.Value)
  218.         
  219.  
  220.     
  221.     def set_conversation_from_combos(self):
  222.         to = self.IMControl.Buddy
  223.         frm = self.IMControl.Account
  224.         if frm is None:
  225.             return False
  226.         
  227.         convo = self.convo
  228.         if convo.protocol is not frm or convo.buddy is not to:
  229.             self.set_conversation(frm.convo_for(to))
  230.         
  231.         return True
  232.  
  233.     
  234.     def on_close(self):
  235.         if getattr(self, '_closed', False):
  236.             log.warning('FIXME: imwin_ctrl.on_close was called more than once!!!')
  237.             return None
  238.         
  239.         self._closed = True
  240.         del self.capsbar.buddy_callback
  241.         del self.capsbar
  242.         plugin_hub = plugin_hub
  243.         import plugin_manager
  244.         plugin_hub.act('digsby.im.conversation.close.async', self.convo)
  245.         self.unlink_observers()
  246.         if self.convo is not None:
  247.             self.unwatch_conversation(self.convo)
  248.             
  249.             try:
  250.                 self.convo.exit()
  251.             except Exception:
  252.                 print_exc()
  253.             except:
  254.                 None<EXCEPTION MATCH>Exception
  255.             
  256.  
  257.         None<EXCEPTION MATCH>Exception
  258.  
  259.     
  260.     def current_buddy_items(self):
  261.         items = [ buddy_menu_item(contact) for contact in self.contacts ]
  262.         i = self.contacts.index(self.Buddy)
  263.         return (items, items[i])
  264.  
  265.     
  266.     def Conversation(self):
  267.         return self.convo
  268.  
  269.     Conversation = property(Conversation)
  270.     
  271.     def Buddy(self):
  272.         return self.IMControl.Buddy
  273.  
  274.     Buddy = property(Buddy)
  275.     
  276.     def SMS(self):
  277.         return self.SMSControl.get_contact_sms()
  278.  
  279.     SMS = property(SMS)
  280.     
  281.     def set_conversation(self, convo, meta = None):
  282.         if convo is self.convo:
  283.             return None
  284.         
  285.         shouldShowToFrom = False
  286.         if self.convo is not None:
  287.             self.unwatch_conversation(self.convo)
  288.             self.convo.exit()
  289.             shouldShowToFrom = True
  290.         
  291.         self.convo = convo
  292.         self.watch_conversation(convo)
  293.         contact = None if meta is not None else convo.buddy
  294.         self.capsbar.ApplyCaps(convo.buddy)
  295.         self.IMControl.SetConvo(convo, meta)
  296.         if shouldShowToFrom:
  297.             self.ShowToFrom(shouldShowToFrom)
  298.         
  299.         self.EmailControl.SetContact(contact)
  300.         self.SMSControl.SetContact(contact)
  301.         self.update_icon()
  302.         self.update_title()
  303.         self.choose_message_formatting()
  304.  
  305.     
  306.     def watch_conversation(self, convo):
  307.         plugin_hub = plugin_hub
  308.         import plugin_manager
  309.         plugin_hub.act('digsby.im.conversation.open.async', convo)
  310.         convo.typing_status.add_observer(self.typing_status_changed)
  311.         buddy = convo.buddy
  312.         buddy.add_observer(self.buddy_status_changed, 'status')
  313.         buddy.add_observer(self.buddy_info_changed)
  314.  
  315.     
  316.     def unwatch_conversation(self, convo = None):
  317.         if convo is None:
  318.             convo = self.convo
  319.         
  320.         if convo is not None:
  321.             buddy = convo.buddy
  322.             convo.typing_status.remove_observer(self.typing_status_changed)
  323.             buddy.remove_observer(self.buddy_status_changed, 'status')
  324.             buddy.remove_observer(self.buddy_info_changed)
  325.         
  326.  
  327.     
  328.     def show_status(self, update, ondone = None):
  329.         
  330.         try:
  331.             
  332.             self._statustimer.notify = lambda u = (None, update): self.show_message(u, ondone)
  333.         except AttributeError:
  334.             self._statustimer = None((lambda u = (wx.PyTimer, update): self.show_message(u, ondone)))
  335.  
  336.         if not self._statustimer.IsRunning():
  337.             self._statustimer.Start(250, True)
  338.         
  339.  
  340.     
  341.     def buddy_info_changed(self, *a):
  342.         if self.mode == 'info':
  343.             self.set_profile_html(self.Buddy)
  344.         
  345.  
  346.     buddy_info_changed = calllimit(1)(buddy_info_changed)
  347.     
  348.     def buddy_status_changed(self, *a):
  349.         wx.CallAfter(self._buddy_status_changed)
  350.  
  351.     
  352.     def _buddy_status_changed(self):
  353.         if check_destroyed(self):
  354.             return None
  355.         
  356.         self.capsbar.ApplyCaps(self.Buddy)
  357.         if self.icontype == 'status':
  358.             self.update_icon()
  359.         
  360.  
  361.     
  362.     def typing_status_changed(self, *a):
  363.         self.typing = self.convo.typing_status.get(self.convo.buddy, None)
  364.         self.update_title()
  365.         self.update_icon()
  366.  
  367.     
  368.     def choose_message_formatting(self):
  369.         plain = False
  370.         conv = self.convo
  371.         
  372.         try:
  373.             plain = conv.message_formatting == 'plaintext'
  374.         except AttributeError:
  375.             
  376.             try:
  377.                 plain = conv.protocol.message_formatting == 'plaintext'
  378.             except AttributeError:
  379.                 pass
  380.             except:
  381.                 None<EXCEPTION MATCH>AttributeError
  382.             
  383.  
  384.             None<EXCEPTION MATCH>AttributeError
  385.  
  386.         self.plainttext = plain
  387.  
  388.     
  389.     def show_message(self, messageobj, ondone = None):
  390.         c = messageobj.conversation
  391.         b = messageobj.buddy
  392.         t = messageobj.type
  393.         buddyid = None if b is not None else None
  394.         if buddyid is None:
  395.             next = False
  396.         else:
  397.             next = getattr(self, 'last_buddy', None) == buddyid
  398.         self.last_buddy = buddyid
  399.         self.message_area.format_message(t, messageobj, next = next)
  400.         if ondone is not None:
  401.             pass
  402.         
  403.  
  404.     
  405.     def set_profile_html(self, buddy):
  406.         profilewindow = self.profile_html
  407.         
  408.         try:
  409.             html = GetInfo(self.Buddy, showprofile = True, showhide = False)
  410.         except Exception:
  411.             print_exc()
  412.             html = buddy.name
  413.  
  414.         self.Frozen().__enter__()
  415.         
  416.         try:
  417.             profilewindow.SetPage(html)
  418.         finally:
  419.             pass
  420.  
  421.  
  422.     
  423.     def on_text_changed(self, e):
  424.         e.Skip()
  425.         oldConvo = self.convo
  426.         if not (self.send_typing) and self.Mode != 'im' or not self.set_conversation_from_combos():
  427.             return None
  428.         
  429.         if oldConvo is not None and oldConvo is not self.convo:
  430.             traceguard.__enter__()
  431.             
  432.             try:
  433.                 oldConvo.send_typing_status(None)
  434.             finally:
  435.                 pass
  436.  
  437.         
  438.         txt = self.input_area.Value
  439.         if len(txt) == 0:
  440.             self.convo.send_typing_status(None)
  441.             if self.typing_timer:
  442.                 self.typing_timer.Stop()
  443.                 self.typing_timer = None
  444.             
  445.             self.typing_status = None
  446.         elif self.typing_status != 'typing':
  447.             self.typing_status = 'typing'
  448.             self.convo.send_typing_status(self.typing_status)
  449.         
  450.         self.cancel_timer()
  451.         self.typing_timer = PyTimer(self.send_typed)
  452.         self.typing_timer.Start(self.typed_delay * 1000, True)
  453.  
  454.     
  455.     def send_typed(self, *e):
  456.         self.typing_status = 'typed'
  457.         self.convo.send_typing_status(self.typing_status)
  458.  
  459.     
  460.     def cancel_timer(self):
  461.         if self.typing_timer:
  462.             self.typing_timer.Stop()
  463.             self.typing_timer = None
  464.         
  465.  
  466.     
  467.     def on_message_area_shown(self):
  468.         if hasattr(self, 'message_area') and not (self.message_area.inited):
  469.             if hasattr(self, 'convo'):
  470.                 self.init_message_area(self.convo.name, self.convo.buddy)
  471.             else:
  472.                 self.init_message_area('', None)
  473.             self.input_area.tc.Bind(wx.EVT_TEXT, self.on_text_changed)
  474.             ImWinDropTarget = ImWinDropTarget
  475.             import gui.imwin.imwindnd
  476.             self.SetDropTarget(ImWinDropTarget(self))
  477.         
  478.  
  479.     
  480.     def on_video(self):
  481.         buddy = self.Buddy
  482.         VideoChatWindow = VideoChatWindow
  483.         import gui.video.webvideo
  484.         if VideoChatWindow.RaiseExisting():
  485.             self.convo.system_message(_('You can only have one audio/video call at a time.'))
  486.             log.info('video window already up')
  487.         else:
  488.             log.info('requesting video chat')
  489.             VideoChat = VideoChat
  490.             import digsby.videochat
  491.             VideoChat(buddy)
  492.  
  493.  
  494.