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

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import util.primitives.strings as strings
  5. DEFAULT_NOICON_OPACITY = 0.4
  6. import wx
  7. from wx import ALIGN_LEFT, ALIGN_CENTER_VERTICAL, Font, Rect, ALIGN_BOTTOM, FONTFAMILY_DEFAULT, FONTSTYLE_ITALIC, FONTSTYLE_NORMAL, FONTWEIGHT_BOLD, FONTWEIGHT_NORMAL, SystemSettings_GetColour, Point, ALIGN_RIGHT, ALIGN_CENTER
  8. lmiddle = ALIGN_LEFT | ALIGN_CENTER_VERTICAL
  9. LBOTTOM = ALIGN_LEFT | ALIGN_BOTTOM
  10. RBOTTOM = ALIGN_RIGHT | ALIGN_BOTTOM
  11. from gui.toolbox import get_wxColor
  12. from gui.textutil import default_font, TruncateText
  13. from util import isiterable, do, Storage as S, try_this, nicetimecount, memoize
  14. from util.lrucache import lru_cache
  15. from contacts import MetaContact
  16. from time import time
  17. from logging import getLogger
  18. log = getLogger('renderers')
  19. info = log.info
  20. from common import pref, prefprop
  21. from gui import skin
  22. from gui.skin.skinobjects import SkinColor, Margins
  23.  
  24. syscol = lambda s: SkinColor(SystemSettings_GetColour(s))
  25. from wx import Rect
  26. from PIL import Image
  27. from os.path import join
  28. from traceback import print_exc
  29. import sys
  30. replace_newlines = lru_cache(100)(strings.replace_newlines)
  31.  
  32. def get_contact_status(contact):
  33.     msg = contact.stripped_msg
  34.     return None if msg is not None and contact.online else ''
  35.  
  36. _cached_noicon = None
  37. from gui.toolbox.imagefx import pil_setalpha
  38.  
  39. def _load_noicon():
  40.     
  41.     try:
  42.         return skin.get('BuddiesPanel.BuddyIcons.NoIcon').PIL
  43.     except:
  44.         return Image.open(skin.resourcedir() / 'AppDefaults' / 'contact.png')
  45.  
  46.  
  47.  
  48. def get_no_icon(with_transparency = False):
  49.     global _cached_noicon
  50.     
  51.     try:
  52.         return _cached_noicon[int(with_transparency)]
  53.     except TypeError:
  54.         pass
  55.  
  56.     img = _load_noicon()
  57.     imgnoalpha = img.copy()
  58.     
  59.     try:
  60.         alpha = skin.get('BuddiesPanel.BuddyIcons.NoIconAlpha', '75%').strip().rstrip('%')
  61.         alpha_opacity = float(alpha) / 100
  62.     except:
  63.         alpha_opacity = DEFAULT_NOICON_OPACITY
  64.  
  65.     pil_setalpha(img, alpha_opacity)
  66.     _cached_noicon = (imgnoalpha, img)
  67.     return _cached_noicon[int(with_transparency)]
  68.  
  69.  
  70. def print_bicon_exc(buddykey):
  71.     print_exc()
  72.  
  73. if not getattr(sys, 'DEV', False) or True:
  74.     print_bicon_exc = memoize(print_bicon_exc)
  75.  
  76.  
  77. def _geticon(buddy):
  78.     
  79.     try:
  80.         icon = buddy.icon
  81.     except Exception:
  82.         print_bicon_exc(buddy.info_key)
  83.         return None
  84.  
  85.     
  86.     try:
  87.         if icon is not None:
  88.             
  89.             try:
  90.                 extrema = icon._extrema
  91.             except AttributeError:
  92.                 extrema = icon._extrema = icon.getextrema()
  93.  
  94.             if extrema != (0, 0) and not all((lambda .0: for e in .0:
  95. e == (0, 0))(extrema)):
  96.                 return icon
  97.             
  98.     except Exception:
  99.         e = None
  100.         
  101.         try:
  102.             print_bicon_exc(buddy.info_key)
  103.         except Exception:
  104.             pass
  105.         except:
  106.             None<EXCEPTION MATCH>Exception
  107.         
  108.  
  109.         None<EXCEPTION MATCH>Exception
  110.  
  111.  
  112.  
  113. def get_buddy_icon_path(buddy):
  114.     icon = _geticon(buddy)
  115.     if icon is None:
  116.         return skin.get('BuddiesPanel.BuddyIcons.NoIcon').path
  117.     else:
  118.         return buddy.icon_path
  119.  
  120.  
  121. def get_buddy_icon(buddy, size = None, round_size = 1, grey_offline = True, with_transparency = False):
  122.     icon = _geticon(buddy)
  123.     isno = icon is None
  124.     icon = None if isno else icon
  125.     icon = None if size else icon
  126.     if isno or not round_size:
  127.         i = None if grey_offline and not (buddy.online) else icon.WXB
  128.     else:
  129.         i = icon.Rounded(round_size).WXB
  130.         i = None if grey_offline and not (buddy.online) else i
  131.     return i
  132.  
  133.  
  134. def get_idle_string(contact):
  135.     idle = getattr(contact, 'idle', None)
  136.     if idle in (True, False, None):
  137.         return ''
  138.     elif isinstance(idle, (int, long)):
  139.         diff = int(time() - idle)
  140.         if diff != 0:
  141.             return _get_idle_string_from_seconds(diff)
  142.         else:
  143.             return ''
  144.     else:
  145.         return ''
  146.  
  147.  
  148. def _get_idle_string_from_seconds(secs):
  149.     (mins, secs) = divmod(secs, 60)
  150.     (hours, mins) = divmod(mins, 60)
  151.     (days, hours) = divmod(hours, 24)
  152.     timeStr = ''
  153.     if days:
  154.         return '(%dd)' % int(days)
  155.     
  156.     if hours > 0:
  157.         timeStr += '%d' % int(hours) + ':'
  158.         timeStr += '%02d' % int(mins)
  159.     else:
  160.         mins = int(mins)
  161.         if mins < 10:
  162.             timeStr += '%dm' % mins
  163.         else:
  164.             timeStr += '%02dm' % mins
  165.     return None if timeStr else ''
  166.  
  167. _get_idle_string_from_seconds = lru_cache(100)(_get_idle_string_from_seconds)
  168.  
  169. def get_prefs():
  170.     
  171.     try:
  172.         profile = profile
  173.         import common
  174.         return profile.prefs
  175.     except ImportError:
  176.         ObservableDict = ObservableDict
  177.         import util.observe
  178.         return ObservableDict()
  179.  
  180.  
  181.  
  182. def safefont(name, size, bold = False):
  183.     weight = None if bold else FONTWEIGHT_NORMAL
  184.     
  185.     try:
  186.         return Font(size, FONTFAMILY_DEFAULT, FONTSTYLE_NORMAL, weight, False, name)
  187.     except:
  188.         print_exc()
  189.         font = default_font()
  190.         font.SetPointSize(size)
  191.         font.SetWeight(weight)
  192.         return font
  193.  
  194.  
  195.  
  196. class Renderer(object):
  197.     
  198.     def __init__(self, parent):
  199.         self.parent = parent
  200.         self.prefs = get_prefs()
  201.         self.skin = S(fontcolors = S())
  202.  
  203.     
  204.     def UpdateSkin(self):
  205.         s = self.skin
  206.         g = skin.get
  207.         s.bg = g('BuddiesPanel.Backgrounds.Buddy', (lambda : syscol(wx.SYS_COLOUR_LISTBOX)))
  208.         s.selectedbg = g('BuddiesPanel.Backgrounds.BuddySelected', (lambda : syscol(wx.SYS_COLOUR_HIGHLIGHT)))
  209.         s.hoverbg = g('BuddiesPanel.Backgrounds.BuddyHover', (lambda : syscol(wx.SYS_COLOUR_LISTBOX)))
  210.  
  211.     
  212.     def getpref(self, prefname, default = None):
  213.         return pref('buddylist.layout.%s' % prefname, default)
  214.  
  215.     
  216.     def attrlink(self, attr):
  217.         return self.prefs.link(('buddylist.layout.%s' % attr,), (lambda val: (self.calcsizes(), self.parent.list_changed())), False, obj = self)
  218.  
  219.     
  220.     def draw_background(self, obj, dc, rect, n, selected, hover):
  221.         s = self.skin
  222.         if selected and s.selectedbg:
  223.             s.selectedbg.Draw(dc, rect, n)
  224.         elif hover and s.hoverbg:
  225.             s.hoverbg.Draw(dc, rect, n)
  226.         elif s.bg:
  227.             s.bg.Draw(dc, rect, n)
  228.         
  229.  
  230.  
  231.  
  232. class GroupCellRenderer(Renderer):
  233.     
  234.     def __init__(self, parent):
  235.         Renderer.__init__(self, parent)
  236.         layout_attrs = '\n        name_font_face\n        name_font_size\n        padding\n        '.strip().split()
  237.         (do,)((lambda .0: for attr in .0:
  238. self.attrlink(attr))(layout_attrs))
  239.         self.UpdateSkin()
  240.  
  241.     
  242.     def UpdateSkin(self):
  243.         Renderer.UpdateSkin(self)
  244.         s = self.skin
  245.         s.margins = skin.get('BuddiesPanel.GroupMargins')
  246.         s.padding = skin.get('BuddiesPanel.GroupPadding', (lambda : Point(4, 4)))
  247.         
  248.         g = lambda k, default = sentinel: skin.get('BuddiesPanel.GroupIcons.' + k, default)
  249.         s.expanded = g('Expanded', (lambda : pass))
  250.         s.expandedhover = g(('ExpandedHover',), (lambda : s.expanded))
  251.         s.expandedselected = g(('ExpandedSelected',), (lambda : s.expanded))
  252.         s.collapsed = g('Collapsed', (lambda : pass))
  253.         s.collapsedhover = g('CollapsedHover', s.collapsed)
  254.         s.collapsedselected = g('CollapsedSelected', s.collapsed)
  255.         
  256.         g = lambda k, default: skin.get('BuddiesPanel.Backgrounds.' + k, default)
  257.         s.bg = g(('Group',), (lambda : g('Buddy')))
  258.         s.hoverbg = g(('GroupHover',), (lambda : g('BuddyHover')))
  259.         s.selectedbg = g(('GroupSelected',), (lambda : g('BuddySelected')))
  260.         f = s.fontcolors
  261.         
  262.         g = lambda k, default: skin.get('BuddiesPanel.FontColors.' + k, default)
  263.         f.group = g(('Group',), (lambda : g('Buddy', (lambda : syscol(wx.SYS_COLOUR_WINDOWTEXT)))
  264. ))
  265.         f.grouphover = g(('GroupHover',), (lambda : g('BuddyHover', (lambda : syscol(wx.SYS_COLOUR_WINDOWTEXT)))
  266. ))
  267.         f.groupselected = g(('GroupSelected',), (lambda : g('BuddySelected', (lambda : syscol(wx.SYS_COLOUR_HIGHLIGHTTEXT)))
  268. ))
  269.         self.calcsizes()
  270.  
  271.     
  272.     def item_height(self, obj):
  273.         return int(self.group_height)
  274.  
  275.     
  276.     def calcsizes(self):
  277.         p = self.getpref
  278.         margins = self.skin.margins
  279.         padding = self.skin.padding
  280.         self.mainfont = safefont(p('name_font_face', None), (try_this,)((lambda : int(p('name_font_size'))), 10))
  281.         self.mainfont_height = self.mainfont.LineHeight
  282.         self.group_height = int(self.mainfont_height) + margins.top + margins.bottom + padding.y * 2
  283.         self.depth_indent = p('indent', 5)
  284.  
  285.     font_face = prefprop('buddylist.layout.name_font_face', None)
  286.     font_size = prefprop('buddylist.layout.name_font_size', None)
  287.     group_indent = prefprop('buddylist.layout.indent', 0)
  288.     
  289.     def Draw(self, dc, rect, selected, obj, depth, expanded, index, hover):
  290.         s = self.skin
  291.         rect = rect.AddMargins(wx.Rect(*s.margins)).AddMargins(wx.Rect(0, s.padding.y, 0, s.padding.y))
  292.         fontface = self.font_face
  293.         font = safefont(fontface, (try_this,)((lambda : int(self.font_size)), 10), bold = True)
  294.         dc.SetFont(font)
  295.         rect = rect.Subtract(left = self.group_indent * depth)
  296.         if isiterable(obj):
  297.             triangle = self.get_expander(selected, expanded, hover)
  298.             if triangle is not None:
  299.                 dc.DrawBitmap(triangle, rect.x, rect.VCenter(triangle), True)
  300.                 rect = rect.Subtract(left = triangle.Width + s.padding.x)
  301.             
  302.         
  303.         if selected:
  304.             fg = s.fontcolors.groupselected
  305.         elif hover:
  306.             fg = s.fontcolors.grouphover
  307.         else:
  308.             fg = s.fontcolors.group
  309.         dc.SetTextForeground(fg)
  310.         dc.DrawTruncatedText(obj.display_string, rect, alignment = lmiddle)
  311.  
  312.     
  313.     def get_expander(self, selected, expanded, hover):
  314.         iconname = None if expanded else 'collapsed'
  315.         if selected:
  316.             iconname += 'selected'
  317.         elif hover:
  318.             iconname += 'hover'
  319.         
  320.         return getattr(self.skin, iconname, None)
  321.  
  322.  
  323.  
  324. class ContactCellRenderer(Renderer):
  325.     
  326.     def __init__(self, parent):
  327.         Renderer.__init__(self, parent)
  328.         self._lastcalc = None
  329.         self.layout_attrs = '\n        name_font_face\n        name_font_size\n        show_extra\n        extra_info\n        extra_font_face\n        extra_font_size\n        extra_padding\n        show_buddy_icon\n        buddy_icon_pos\n        badge_max_size\n        badge_min_size\n        show_status_icon\n        status_icon_pos\n        status_icon_size\n        show_service_icon\n        service_icon_pos\n        badge_ratio\n        buddy_icon_size\n        service_icon_size\n        side_icon_size\n        padding\n        indent\n        grey_offline\n        '.strip().split()
  330.         (do,)((lambda .0: for attr in .0:
  331. self.attrlink(attr))(self.layout_attrs))
  332.         self.UpdateSkin()
  333.  
  334.     
  335.     def UpdateSkin(self):
  336.         Renderer.UpdateSkin(self)
  337.         self.drawseqs = { }
  338.         self._lastcalc = []
  339.         s = self.skin
  340.         g = skin.get
  341.         self.statusicons = g('statusicons')
  342.         s.margins = g('BuddiesPanel.BuddyMargins')
  343.         s.icon_frame = g('BuddiesPanel.BuddyIcons.Frame', None)
  344.         s.icon_frame_size = Margins(g('BuddiesPanel.BuddyIcons.FrameSize', (0, 0, 0, 0)))
  345.         s.round_corners = (try_this,)((lambda : int(g('BuddiesPanel.BuddyIcons.Rounded', 1))), 1)
  346.         f = s.fontcolors
  347.         
  348.         g = lambda k, default: skin.get('BuddiesPanel.FontColors.' + k, default)
  349.         f.buddy = g('Buddy', (lambda : syscol(wx.SYS_COLOUR_WINDOWTEXT)))
  350.         f.buddyoffline = g('BuddyOffline', (lambda : syscol(wx.SYS_COLOUR_GRAYTEXT)))
  351.         f.buddyselected = g('BuddySelected', (lambda : syscol(wx.SYS_COLOUR_HIGHLIGHTTEXT)))
  352.         f.buddyhover = g(('BuddyHover',), (lambda : f.buddy))
  353.         f.status = g(('Status',), (lambda : f.buddy))
  354.         f.statushover = g(('StatusHover',), (lambda : f.buddyhover))
  355.         f.statusselected = g(('StatusSelected',), (lambda : f.buddyselected))
  356.         f.idletime = g('IdleTime', (lambda : syscol(wx.SYS_COLOUR_GRAYTEXT)))
  357.         f.idletimehover = g('IdleTimeHover', (lambda : syscol(wx.SYS_COLOUR_GRAYTEXT)))
  358.         f.idletimeselected = g('IdleTimeSelected', (lambda : syscol(wx.SYS_COLOUR_HIGHLIGHTTEXT)))
  359.         self.icons = [
  360.             'service_icon',
  361.             'status_icon',
  362.             'buddy_icon']
  363.         self.calcsizes()
  364.  
  365.     
  366.     def calcsizes(self):
  367.         p = self.getpref
  368.         s = self.skin
  369.         padding = p('padding', 4)
  370.         (None, do)((lambda .0: for k in .0:
  371. setattr(self, k.replace('.', '_'), p(k)))(self.layout_attrs))
  372.         sz = int(p('name_font_size', 10))
  373.         self.mainfont = safefont(p('name_font_face', None), sz)
  374.         self.mainfont.Style = FONTSTYLE_NORMAL
  375.         self.mainfont_height = mainfont_height = self.mainfont.LineHeight
  376.         self.extrafont = safefont(p('extra_font_face', None), int(p('extra_font_size', 10)))
  377.         self.extrafont_height = extrafont_height = self.extrafont.LineHeight
  378.         self.depth_indent = p('indent', 5)
  379.         icon_size = p('buddy_icon_size', 0)
  380.         if s.icon_frame_size:
  381.             icon_size += s.icon_frame_size.top + s.icon_frame_size.bottom
  382.         
  383.         show_icon = p('show_buddy_icon', False)
  384.         extraheight = None if p('show_extra', True) and p('extra_info', 'status') in ('status', 'both') else 0
  385.         margins = self.skin.margins
  386.         self.cell_height = None + padding * 2(max if show_icon else 0, mainfont_height + extraheight) + margins.top + margins.bottom
  387.         if self.cell_height < mainfont_height * 1.2:
  388.             self.cell_height = mainfont_height * 1.2
  389.         
  390.         self.drawseqs.clear()
  391.         self._serviceiconcache = { }
  392.         self._lastcalc = None
  393.         return self.cell_height
  394.  
  395.     
  396.     def calcdraw(self, w, h, Rect = Rect):
  397.         if self._lastcalc == (w, h):
  398.             return self._lastseq
  399.         
  400.         s = self.skin
  401.         rect = Rect(0, 0, w, h).AddMargins(wx.Rect(*s.margins))
  402.         icons = (sorted,)((lambda .0: for icon in .0:
  403. (icon, getattr(self, icon + '_pos')))(self.icons), key = (lambda o: {
  404. 'f': -1,
  405. 'b': 1 }.get(o[1][0], 0)))
  406.         seq = []
  407.         last = Rect()
  408.         badge_size = min(self.badge_max_size, max(self.badge_min_size, int(self.buddy_icon_size * self.badge_ratio)))
  409.         frame_size = s.icon_frame_size
  410.         padding = self.padding
  411.         hpadding = 4
  412.         for icon, pos in icons:
  413.             if getattr(self, 'show_' + icon):
  414.                 pos = pos.lower()
  415.                 size = getattr(self, icon + '_size')
  416.                 left = pos.endswith('left')
  417.                 iconpos = Point(-size * int(not left), 0)
  418.                 if icon == 'buddy_icon':
  419.                     iconw = size + frame_size.left + frame_size.right
  420.                     frameRect = Rect(0, 0, iconw, size + frame_size.top + frame_size.bottom)
  421.                     frameRect.x = rect.Pos(wx.Point(-(frameRect.width) * int(not left), 0))[0]
  422.                     frameRect.y = rect.VCenterH(frameRect.height)
  423.                     last = Rect(frameRect.x + frame_size.left, frameRect.y + frame_size.top, size, size)
  424.                     seq += [
  425.                         (getattr(self, 'get_buddy_icon'), last, 0)]
  426.                     seq += [
  427.                         (getattr(self, 'get_frame_icon'), frameRect, 0)]
  428.                     iconw + hpadding[{ } if left else 'right'] = { }
  429.                     rect = None(**rect.Subtract)
  430.                     bitmap = getattr(self, 'get_' + icon)
  431.                 elif not pos.startswith('b'):
  432.                     r = Rect(rect.Pos(iconpos)[0], rect.VCenterH(size), size, size)
  433.                     size + hpadding[{ } if left else 'right'] = { }
  434.                     rect = None(**rect.Subtract)
  435.                     last = r
  436.                     alignment = ALIGN_CENTER
  437.                     bitmap = getattr(self, 'get_' + icon)
  438.                 else:
  439.                     bp = badge_size
  440.                     alignment = None if left else RBOTTOM
  441.                     badgepos = None(last.Pos(wx.Point if left else -bp, -bp))
  442.                     r = Rect(badgepos[0], badgepos[1], badge_size, badge_size)
  443.                     
  444.                     bitmap = lambda obj, icon = (None, icon): getattr(self, 'get_' + icon)(obj).ResizedSmaller(badge_size)
  445.                 seq.append((bitmap, r, alignment))
  446.                 continue
  447.         
  448.         self.inforect = rect
  449.         self._lastcalc = (w, h)
  450.         self._lastseq = seq
  451.         return seq
  452.  
  453.     
  454.     def Draw(self, dc, rect, selected, obj, depth, expanded, index, hover, Rect = Rect):
  455.         DrawBitmap = dc.DrawBitmap
  456.         DrawTruncatedText = dc.DrawTruncatedText
  457.         idle_string = get_idle_string(obj)
  458.         extrafont = self.extrafont
  459.         extra_info = None if self.show_extra else None
  460.         msg = get_contact_status(obj)
  461.         padding = self.padding
  462.         extra_padding = self.extra_padding
  463.         contact_name = obj.alias
  464.         mainfont_height = self.mainfont_height
  465.         for method, r, align in self.calcdraw(rect.width, rect.height):
  466.             
  467.             try:
  468.                 b = method(obj)
  469.             except:
  470.                 print_exc()
  471.                 continue
  472.  
  473.             if b:
  474.                 b.Draw(dc, Rect(rect.x + r.x, rect.y + r.y, r.width, r.height), align)
  475.                 continue
  476.         
  477.         rect = rect.AddMargins(wx.Rect(*self.skin.margins))
  478.         rect.x = self.inforect.x
  479.         rect.width = self.inforect.width
  480.         if msg and extra_info in ('status', 'both'):
  481.             th = self.mainfont.LineHeight + extra_padding + self.extrafont_height
  482.             rect = Rect(rect.x, rect.VCenterH(th), rect.width, rect.height)
  483.             namerect = Rect(rect.x, rect.y + 1, rect.Width, self.mainfont.LineHeight)
  484.             inforect = Rect(rect.x, rect.y + self.mainfont.LineHeight + extra_padding, rect.Width, self.extrafont_height)
  485.             DrawTruncatedText(self.get_contact_info(obj, dc, selected, expanded, hover), inforect, alignment = lmiddle)
  486.         else:
  487.             namerect = rect
  488.         hpadding = 4
  489.         if idle_string and extra_info in ('idle', 'both'):
  490.             (namew, nameh, namedescent, __) = dc.GetFullTextExtent(contact_name, self.mainfont)
  491.             (w, h, desc, __) = dc.GetFullTextExtent(idle_string, extrafont)
  492.             iy = 3
  493.             diff = namew + w + hpadding - namerect.width
  494.             if diff > 0:
  495.                 x = namerect.Pos((-w, 0))[0]
  496.                 y = namerect.Y
  497.                 r = Rect(x, y, w, namerect.Height)
  498.                 namerect = namerect.Subtract(right = w + hpadding)
  499.             else:
  500.                 r = Rect(namerect.X + namew + hpadding, namerect.Y, w, namerect.Height)
  501.             self.set_idle_time_dc(obj, dc, selected, expanded, hover)
  502.             dc.DrawLabel(idle_string, r, ALIGN_LEFT | ALIGN_CENTER_VERTICAL)
  503.         
  504.         self.set_contact_name_dc(obj, dc, selected, expanded, hover)
  505.         DrawTruncatedText(contact_name, namerect, alignment = lmiddle)
  506.  
  507.     
  508.     def get_buddy_icon(self, contact, *a):
  509.         return get_buddy_icon(contact, self.buddy_icon_size, self.skin.round_corners, self.grey_offline, with_transparency = True)
  510.  
  511.     
  512.     def get_frame_icon(self, contact, *a):
  513.         return self.skin.icon_frame
  514.  
  515.     
  516.     def get_service_icon(self, contact, *a):
  517.         icon = contact.serviceicon
  518.         if max(icon.Width, icon.Height) > self.service_icon_size:
  519.             icon = icon.Resized(self.service_icon_size)
  520.         
  521.         if self.grey_offline and not (contact.online):
  522.             icon = icon.Greyed
  523.         
  524.         return icon
  525.  
  526.     
  527.     def get_status_icon(self, contact, *a):
  528.         icon = skin.get('statusicons.' + contact.status_orb)
  529.         if max(icon.Width, icon.Height) > self.status_icon_size:
  530.             return icon.Resized(self.status_icon_size)
  531.         else:
  532.             return icon
  533.  
  534.     
  535.     def set_contact_name_dc(self, contact, dc, selected, expanded, hover):
  536.         fontcolors = self.skin.fontcolors
  537.         online = contact.online
  538.         if selected:
  539.             fg = fontcolors.buddyselected
  540.         elif hover:
  541.             fg = fontcolors.buddyhover
  542.         elif not online:
  543.             fg = fontcolors.buddyoffline
  544.         else:
  545.             fg = fontcolors.buddy
  546.         dc.TextForeground = fg
  547.         mainfont = self.mainfont
  548.         None(mainfont.SetStyle if online else FONTSTYLE_ITALIC)
  549.         None(mainfont.SetWeight if getattr(contact, 'entering', False) else FONTWEIGHT_NORMAL)
  550.         dc.SetFont(mainfont)
  551.  
  552.     
  553.     def set_idle_time_dc(self, contact, dc, selected, expanded, hover):
  554.         fontcolors = self.skin.fontcolors
  555.         if selected:
  556.             fg = fontcolors.idletimeselected
  557.         elif hover:
  558.             fg = fontcolors.idletimehover
  559.         else:
  560.             fg = fontcolors.idletime
  561.         dc.TextForeground = fg
  562.         dc.Font = self.extrafont
  563.  
  564.     
  565.     def get_contact_info(self, contact, dc, selected, expanded, hover):
  566.         fontcolors = self.skin.fontcolors
  567.         if selected:
  568.             fg = fontcolors.statusselected
  569.         elif hover:
  570.             fg = fontcolors.statushover
  571.         else:
  572.             fg = fontcolors.status
  573.         dc.TextForeground = fg
  574.         dc.SetFont(self.extrafont)
  575.         return get_contact_status(contact)
  576.  
  577.     
  578.     def item_height(self, obj):
  579.         return int(self.cell_height)
  580.  
  581.  
  582.  
  583. class MetaContactCellRenderer(ContactCellRenderer):
  584.     
  585.     def __init__(self, parent):
  586.         ContactCellRenderer.__init__(self, parent)
  587.  
  588.  
  589.