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

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import wx
  5. from wx.combo import ComboCtrl, ComboPopup
  6. from gui.textutil import default_font, CopyFont
  7. from util import do, Storage
  8. from gui.buddylist.renderers import get_buddy_icon
  9. from gui.skin.skinobjects import SkinColor
  10. from gui import skin
  11. from logging import getLogger
  12. log = getLogger('roomlist')
  13.  
  14. class TextControl(wx.TextCtrl):
  15.     
  16.     def __init__(self, parent, value = None, empty_text = None):
  17.         wx.TextCtrl.__init__(self, parent)
  18.         self.EmptyText = empty_text
  19.         if not value:
  20.             pass
  21.         self.Value = ''
  22.         self.defaultcolor = self.GetForegroundColour()
  23.         self.emptycolor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)
  24.         self.BBind(KILL_FOCUS = self.OnLoseFocus, SET_FOCUS = self.OnSetFocus)
  25.  
  26.     
  27.     def OnLoseFocus(self, e):
  28.         e.Skip()
  29.         if self.EmptyText and self.Value == '':
  30.             self.SetForegroundColour(self.emptycolor)
  31.             self.Value = self.EmptyText
  32.         
  33.  
  34.     
  35.     def OnSetFocus(self, e):
  36.         e.Skip()
  37.         if self.EmptyText and self.ForegroundColour == self.emptycolor:
  38.             self.SetForegroundColour(self.defaultcolor)
  39.             self.Value = ''
  40.         
  41.  
  42.  
  43.  
  44. class SkinVListBox(wx.VListBox):
  45.     
  46.     def __init__(self, *a, **k):
  47.         wx.VListBox.__init__(self, *a, **k)
  48.         syscol = wx.SystemSettings.GetColour
  49.         self.colors = Storage(textfg = Storage(selected = syscol(wx.SYS_COLOUR_HIGHLIGHTTEXT), normal = syscol(wx.SYS_COLOUR_WINDOWTEXT)))
  50.         self.bg = Storage(selected = SkinColor(syscol(wx.SYS_COLOUR_HIGHLIGHT)), normal = SkinColor(syscol(wx.SYS_COLOUR_LISTBOX)))
  51.         self.fonts = Storage(text = default_font())
  52.         self.BBind(LEFT_DOWN = self._OnLeftDown)
  53.  
  54.     
  55.     def GetSelections(self):
  56.         (item, cookie) = self.GetFirstSelected()
  57.         yield item
  58.         while item != -1:
  59.             (item, cookie) = self.GetNextSelected(cookie)
  60.             yield item
  61.  
  62.     
  63.     def IsSelected(self, n):
  64.         if self.HasMultipleSelection():
  65.             return n in self.GetSelections()
  66.         else:
  67.             return self.Selection == n
  68.  
  69.     
  70.     def OnDrawItem(self, dc, rect, n):
  71.         selected = self.IsSelected(n)
  72.         textfg = None(getattr, self.colors.textfg if selected else 'normal')
  73.         dc.SetTextForeground(textfg)
  74.         dc.SetFont(self.fonts.text)
  75.         self._draw(dc, rect, n, selected)
  76.  
  77.     
  78.     def OnDrawBackground(self, dc, rect, n):
  79.         selected = self.IsSelected(n)
  80.         bg = None(getattr, self.bg if selected else 'normal')
  81.         bg.draw(dc, rect, n)
  82.         
  83.         try:
  84.             self._drawbg(dc, rect, n, selected)
  85.         except AttributeError:
  86.             pass
  87.  
  88.  
  89.     
  90.     def OnMeasureItem(self, n):
  91.         
  92.         try:
  93.             measure = self._measure
  94.         except AttributeError:
  95.             return 20
  96.  
  97.         return measure(n)
  98.  
  99.     
  100.     def _OnLeftDown(self, e):
  101.         e.Skip()
  102.         i = self.HitTest((e.GetX(), e.GetY()))
  103.         if i == -1:
  104.             self.SetSelection(-1)
  105.         
  106.  
  107.  
  108.  
  109. class ContactListCtrl(SkinVListBox):
  110.     
  111.     def __init__(self, parent):
  112.         SkinVListBox.__init__(self, parent, style = wx.LB_MULTIPLE)
  113.  
  114.     
  115.     def SetContacts(self, contacts):
  116.         self.contacts = contacts
  117.         self.pending_contacts = []
  118.         
  119.         update = lambda *a: self.update_count()
  120.         self.contacts.add_observer(update)
  121.         (None,)((self.Bind, wx.EVT_WINDOW_DESTROY), (lambda e: self.contacts.remove_observer(update)))
  122.         self.update_count()
  123.  
  124.     
  125.     def update_count(self, keep_pending = False):
  126.         if not keep_pending:
  127.             del self.pending_contacts[:]
  128.         
  129.         self.SetItemCount(len(self.contacts) + len(self.pending_contacts))
  130.         self.RefreshAll()
  131.  
  132.     Contacts = property(None, SetContacts)
  133.     
  134.     def AddPendingContact(self, contact):
  135.         self.pending_contacts += [
  136.             contact]
  137.         self.update_count(keep_pending = True)
  138.  
  139.     
  140.     def _draw(self, dc, rect, n, selected):
  141.         (iconsize, padding) = (16, 3)
  142.         
  143.         try:
  144.             contact = self.contacts[n]
  145.             icon = get_buddy_icon(contact, iconsize, False)
  146.         except IndexError:
  147.             contact = self.pending_contacts[n - len(self.contacts)]
  148.             icon = skin.get('miscicons.smallspinner')
  149.  
  150.         alias = contact.alias
  151.         name = contact.name
  152.         contact_str = None if alias == name else u'%s (%s)' % (alias, name)
  153.         rect.Subtract(left = padding)
  154.         dc.DrawBitmap(icon, rect.X, rect.Y + (rect.Height / 2 - icon.Size.height / 2))
  155.         rect.Subtract(left = iconsize + padding)
  156.         dc.DrawTruncatedText(contact_str, rect, wx.ALIGN_CENTER_VERTICAL)
  157.  
  158.     
  159.     def _measure(self, n):
  160.         return 22
  161.  
  162.     
  163.     def OnGetItemImage(self, item):
  164.         return item
  165.  
  166.  
  167. from gui.uberwidgets.UberCombo import UberCombo
  168. from gui.uberwidgets.simplemenu import SimpleMenuItem
  169.  
  170. def item_for_contact(contact):
  171.     alias = contact.alias
  172.     name = contact.name
  173.     icon = skin.get('statusicons.' + contact.status_orb)
  174.     if alias == name:
  175.         smi = SimpleMenuItem([
  176.             icon,
  177.             name])
  178.     else:
  179.         smi = SimpleMenuItem([
  180.             icon,
  181.             '%s (%s)' % (alias, name)])
  182.     smi.buddy = contact
  183.     return smi
  184.  
  185.  
  186. class ContactCombo(UberCombo):
  187.     
  188.     def __init__(self, parent, skinkey = 'ComboBox', contacts = None, inviteCallback = None, listctrl = None):
  189.         UberCombo.__init__(self, parent, typeable = True, skinkey = skinkey, editmethod = self.ShowMenu, selectioncallback = self.on_selection, maxmenuheight = 10, empty_text = _('Invite Buddy'))
  190.         self.TextField.Bind(wx.EVT_CHAR, self.on_char)
  191.         self.TextField.Bind(wx.EVT_TEXT, self.on_text)
  192.         self.contacts = None if contacts is not None else { }
  193.         self.inviteCallback = inviteCallback
  194.         self.contact_list = listctrl
  195.         trace = trace
  196.         import util
  197.         SimpleMenu = SimpleMenu
  198.         import gui.uberwidgets.simplemenu
  199.         self.DropDownButton.Bind(wx.EVT_BUTTON, self.ShowMenu)
  200.  
  201.     
  202.     def buddy_sort(self, c):
  203.         return (-int(c.online), c.name)
  204.  
  205.     
  206.     def on_char(self, e):
  207.         k = e.GetKeyCode()
  208.         m = self.menu
  209.         if k == wx.WXK_DOWN:
  210.             m.Selection = (m.Selection + 1) % m.Count
  211.         elif k == wx.WXK_UP:
  212.             if m.Selection == -1:
  213.                 m.Selection = m.Count - 1
  214.             else:
  215.                 m.Selection = (m.Selection - 1) % m.Count
  216.         elif k == wx.WXK_RETURN:
  217.             if m.IsShown() and m.Selection >= 0:
  218.                 item = m.GetItem(m.Selection)
  219.                 m.Hide()
  220.                 self.on_selection(item)
  221.             else:
  222.                 self.on_selection(self.TextField.Value)
  223.                 m.Hide()
  224.                 self.GrandParent.SetFocus()
  225.         elif k == wx.WXK_ESCAPE:
  226.             self.TextField.Value = ''
  227.             m.Hide()
  228.         else:
  229.             e.Skip()
  230.  
  231.     
  232.     def on_text(self, e):
  233.         val = self.TextField.Value
  234.         e.Skip()
  235.         m = self.menu
  236.         m.RemoveAll()
  237.         items = []
  238.         for contact in sorted(self.contacts.itervalues(), key = self.buddy_sort):
  239.             n = contact.name.lower()
  240.             a = contact.alias.lower()
  241.             v = val.lower()
  242.             if contact not in self.contact_list.contacts:
  243.                 if n.startswith(v) or a.startswith(v):
  244.                     items.append(item_for_contact(contact))
  245.                     continue
  246.         
  247.         for item in items:
  248.             m.AppendItem(item, calcSize = False)
  249.         
  250.         if m.Count:
  251.             m.spine.CalcSize()
  252.             m.Selection = -1
  253.             m.Refresh()
  254.         else:
  255.             m.Selection = -1
  256.             m.Hide()
  257.  
  258.     
  259.     def on_selection(self, item):
  260.         print 'on_selection', item
  261.         if isinstance(item, basestring):
  262.             p = self.Parent
  263.             while not hasattr(p, 'protocol') and p is not None:
  264.                 p = p.Parent
  265.             buddy = p.protocol.get_buddy(item)
  266.         else:
  267.             buddy = item.buddy
  268.         if buddy:
  269.             if wx.YES == wx.MessageBox(_('Do you want to invite %s to a chat?') % buddy.name, _('Chat Invite'), wx.YES | wx.NO):
  270.                 cb = self.inviteCallback
  271.                 if cb is None:
  272.                     
  273.                     cb = lambda *a, **k: log.warning('inviteCallback(%r, %r)', a, k)
  274.                 
  275.                 if cb(buddy):
  276.                     self.SetValue('')
  277.                     self.contact_list.AddPendingContact(buddy)
  278.                 
  279.             
  280.         
  281.  
  282.     
  283.     def ShowMenu(self, *e):
  284.         m = self.menu
  285.         m.RemoveAll()
  286.         for contact in sorted(self.contacts.itervalues(), key = self.buddy_sort):
  287.             if contact not in self.contact_list.contacts:
  288.                 m.AppendItem(item_for_contact(contact))
  289.                 continue
  290.         
  291.         self.OpenMenu()
  292.  
  293.  
  294.  
  295. class RoomListPanel(wx.Panel):
  296.     
  297.     def __init__(self, parent, buddies = None, inviteCallback = None):
  298.         wx.Panel.__init__(self, parent)
  299.         self._obs_link = None
  300.         self.roomlist = None
  301.         self.list = ContactListCtrl(self)
  302.         self.combo = ContactCombo(self, skinkey = skin.get('RoomListComboSkin'), contacts = buddies, inviteCallback = inviteCallback, listctrl = self.list)
  303.         s = self.Sizer = wx.BoxSizer(wx.VERTICAL)
  304.         s.Add(self.combo, 0, wx.EXPAND | wx.ALL)
  305.         s.Add(self.list, 1, wx.EXPAND | wx.ALL)
  306.         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  307.         self.Bind(wx.EVT_ERASE_BACKGROUND, (lambda e: pass))
  308.  
  309.     contact_attrs = ('status', 'alias')
  310.     
  311.     def UpdateSkin(self):
  312.         self.combo.SetSkinKey(skin.get('RoomListComboSkin'))
  313.  
  314.     
  315.     def SetRoomList(self, obslist):
  316.         obs_args = (self.on_list_changed, self.on_contact_changed) + self.contact_attrs
  317.         if self.roomlist is not None:
  318.             if self._obs_link is not None:
  319.                 self._obs_link.disconnect()
  320.                 self._obs_link = None
  321.             
  322.         
  323.         self.roomlist = obslist
  324.         if self.roomlist is not None:
  325.             self._obs_link = self.roomlist.add_list_observer(*obs_args)
  326.         
  327.         self.list.Contacts = obslist
  328.  
  329.     RoomList = property((lambda self: self.roomlist), SetRoomList, (lambda self: self.SetRoomList(None)), "Sets or gets this panel's roomlist.")
  330.     
  331.     def on_list_changed(self, src, attr, old, new):
  332.         pass
  333.  
  334.     
  335.     def on_contact_changed(self, contact, attr, old, new):
  336.         pass
  337.  
  338.  
  339. if __name__ == '__main__':
  340.     
  341.     _ = lambda s: s
  342.     from tests.testapp import testapp
  343.     a = testapp('../../../')
  344.     f = wx.Frame(None, -1, 'roomlist')
  345.     from tests.mock.mockbuddy import MockBuddy
  346.     from common import caps
  347.     from util.observe import ObservableList
  348.     AIM = ('aim', [
  349.         caps.BLOCKABLE,
  350.         caps.EMAIL,
  351.         caps.FILES,
  352.         caps.IM,
  353.         caps.PICTURES,
  354.         caps.SMS])
  355.     MSN = ('msn', [
  356.         caps.BLOCKABLE,
  357.         caps.EMAIL,
  358.         caps.FILES,
  359.         caps.IM])
  360.     JBR = ('jabber', [
  361.         caps.EMAIL,
  362.         caps.FILES,
  363.         caps.IM])
  364.     YHO = ('yahoo', [
  365.         caps.BLOCKABLE,
  366.         caps.EMAIL,
  367.         caps.FILES,
  368.         caps.IM,
  369.         caps.SMS])
  370.     contacts = ObservableList([
  371.         MockBuddy('Aaron', 'away', *JBR),
  372.         MockBuddy('Chris', 'available', *JBR),
  373.         MockBuddy('Jeff', 'offline', *AIM),
  374.         MockBuddy('Kevin', 'away', *YHO),
  375.         MockBuddy('Mike', 'available', *MSN),
  376.         MockBuddy('Steve', 'offline', *AIM)])
  377.     buddies = dict((lambda .0: for c in .0:
  378. (c.name, c))(contacts))
  379.     rl = RoomListPanel(f, buddies)
  380.     rl.RoomList = contacts
  381.     f.SetSize((200, 400))
  382.     f.Show()
  383.     a.MainLoop()
  384.  
  385.