home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / gui / pref / pg_accounts.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  40.2 KB  |  1,065 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. import logging
  5. from traceback import print_exc
  6. from util.introspect import memoize
  7. log = logging.getLogger('pg_accounts2')
  8. import wx
  9. from gui.uberwidgets.PrefPanel import PrefPanel
  10. from gui.pref.prefcontrols import HSizer, VSizer, mark_pref, SText
  11. from wx import EXPAND
  12. import protocols
  13. from gui.textutil import default_font
  14. from gui.accountslist import AccountRow
  15. from gui.accountslist import AccountList
  16. from util.primitives.funcs import find
  17. from operator import attrgetter
  18. import hooks
  19. from contacts.sort_model import ChoiceModel
  20. from pg_contact_list import yield_choices, release_choices
  21. from common import pref, profile
  22. from peak.util.addons import AddOn
  23. import common
  24. from peak.events import trellis
  25. import util.observe as observe
  26. from util.lego.lattice.blocks import IValueListener
  27. from util.lego.lattice.frame import ObservableAttrBindable
  28.  
  29. class IServiceProviderGUIMetaData(protocols.Interface):
  30.     provider_id = unicode()
  31.     icon = property()
  32.     name = unicode()
  33.     popularity = int()
  34.     service_components = list()
  35.  
  36.  
  37. class IServiceProviderInstanceGUIMetaData(protocols.Interface):
  38.     account_name = unicode()
  39.  
  40.  
  41. class IServiceComponentGUIMetaData(protocols.Interface):
  42.     icon = property()
  43.     service_name = unicode()
  44.     type = str()
  45.     component_id = str()
  46.  
  47. from plugin_manager.plugin_registry import ServiceProviderPlugin, ServiceComponentPlugin
  48. import services.service_provider as sp
  49.  
  50. class ServiceProviderPluginGUIMetaData(protocols.Adapter):
  51.     protocols.advise(asAdapterForTypes = [
  52.         ServiceProviderPlugin], instancesProvide = [
  53.         IServiceProviderGUIMetaData])
  54.     
  55.     def provider_id(self):
  56.         return self.subject.provider_id
  57.  
  58.     provider_id = property(provider_id)
  59.     
  60.     def icon(self):
  61.         skin = skin
  62.         import gui
  63.         return skin.get('serviceprovidericons.%s' % self.subject.provider_id)
  64.  
  65.     icon = property(icon)
  66.     
  67.     def provider_name(self):
  68.         return self.subject.name
  69.  
  70.     provider_name = property(provider_name)
  71.     
  72.     def popularity(self):
  73.         return getattr(getattr(getattr(self.subject, 'info', None), 'provider_info', None), 'popularity', 0)
  74.  
  75.     popularity = property(popularity)
  76.     
  77.     def service_components(self):
  78.         return sp.get_meta_components_for_provider(self.subject.provider_id)
  79.  
  80.     service_components = property(service_components)
  81.  
  82.  
  83. class ServiceComponentPluginGUIMetaData(protocols.Adapter):
  84.     protocols.advise(asAdapterForTypes = [
  85.         ServiceComponentPlugin], instancesProvide = [
  86.         IServiceComponentGUIMetaData])
  87.     
  88.     def icon(self):
  89.         skin = skin
  90.         import gui
  91.         return skin.get('serviceicons.%s' % self.subject.shortname)
  92.  
  93.     icon = property(icon)
  94.     
  95.     def service_name(self):
  96.         if not self.subject.info.get('service_name'):
  97.             pass
  98.         return self.subject.info.get('name')
  99.  
  100.     service_name = property(service_name)
  101.     
  102.     def component_id(self):
  103.         return self.subject.shortname
  104.  
  105.     component_id = property(component_id)
  106.     
  107.     def type(self):
  108.         return self.subject.component_type
  109.  
  110.     type = property(type)
  111.  
  112.  
  113. class StringServiceComponentGUIData(object):
  114.     protocols.advise(asAdapterForTypes = [
  115.         basestring], instancesProvide = [
  116.         IServiceComponentGUIMetaData])
  117.     
  118.     def __init__(self, subject):
  119.         self.subject = subject
  120.  
  121.     
  122.     def service_name(self):
  123.         protocolmeta = protocolmeta
  124.         import common
  125.         p = protocolmeta.protocols.get(self.subject)
  126.         if p:
  127.             if not p.get('service_name'):
  128.                 pass
  129.             name = p.get('name')
  130.         else:
  131.             name = self.subject.capitalize()
  132.         return name
  133.         if p:
  134.             return p.name
  135.         return self.subject.capitalize()
  136.  
  137.     service_name = property(service_name)
  138.     
  139.     def icon(self):
  140.         skin = skin
  141.         import gui
  142.         return skin.get('serviceicons.%s' % self.subject, skin.get('serviceprovidericons.%s' % self.subject, None))
  143.  
  144.     icon = property(icon)
  145.     
  146.     def type(self):
  147.         protocolmeta = protocolmeta
  148.         import common
  149.         p = protocolmeta.protocols.get(self.subject)
  150.         if p:
  151.             return p.get('component_type', p.get('type'))
  152.         return 'unknown'
  153.  
  154.     type = property(type)
  155.     
  156.     def component_id(self):
  157.         return self.subject
  158.  
  159.     component_id = property(component_id)
  160.  
  161.  
  162. def get_meta_for_provider(provider_instance):
  163.     return IServiceProviderGUIMetaData(sp.get_meta_service_provider(provider_instance.provider_id))
  164.  
  165. protocols.declareAdapterForType(IServiceProviderGUIMetaData, get_meta_for_provider, sp.ServiceProvider)
  166.  
  167. class IPaintable(protocols.Interface):
  168.     
  169.     def on_paint(e):
  170.         pass
  171.  
  172.  
  173.  
  174. class wxPaintingMixin(object):
  175.     
  176.     def __init__(self, *a, **k):
  177.         
  178.         try:
  179.             IPaintable(self)
  180.         except protocols.AdaptationFailure:
  181.             raise 
  182.  
  183.         super(wxPaintingMixin, self).__init__(*a, **k)
  184.         self.Bind(wx.EVT_PAINT, self.on_paint)
  185.  
  186.  
  187.  
  188. class IDrawable(protocols.Interface):
  189.     
  190.     def draw(dc):
  191.         pass
  192.  
  193.  
  194.  
  195. class IDrawingContext(protocols.Interface):
  196.     
  197.     def DrawText(text, x, y):
  198.         pass
  199.  
  200.     
  201.     def DrawBitmap(bmp, x, y):
  202.         pass
  203.  
  204.     
  205.     def DrawRoundedRectangleRect(rect, radius):
  206.         pass
  207.  
  208.  
  209.  
  210. def wxPaintEventDrawingContextAdapter(event):
  211.     if event.EventType == wx.EVT_PAINT:
  212.         return wx.AutoBufferedPaintDC(event.GetEventObject())
  213.  
  214. protocols.declareImplementation(wx.DC, instancesProvide = [
  215.     IDrawingContext])
  216. protocols.declareAdapterForType(IDrawingContext, wxPaintEventDrawingContextAdapter, wx.Event)
  217.  
  218. class IRectagleFactory(protocols.Interface):
  219.     
  220.     def get_rect(x, y, w, h):
  221.         pass
  222.  
  223.  
  224.  
  225. class wxRectangleFactory(protocols.Adapter):
  226.     protocols.advise(instancesProvide = [
  227.         IRectagleFactory], asAdapterForTypes = [
  228.         wx.DC])
  229.     
  230.     def get_rect(x, y, w, h):
  231.         return wx.Rect(x, y, w, h)
  232.  
  233.     get_rect = staticmethod(get_rect)
  234.  
  235.  
  236. class ServiceProviderGUIMetaIconUser(object):
  237.     icon_cache = { }
  238.     
  239.     def get_icon(self, meta, size):
  240.         meta = IServiceProviderGUIMetaData(meta)
  241.         
  242.         try:
  243.             ret = self.icon_cache[(meta.provider_id, size)]
  244.         except KeyError:
  245.             ret = self.icon_cache[(meta.provider_id, size)] = meta.icon.PIL.Resized(size).WXB
  246.  
  247.         return ret
  248.  
  249.  
  250.  
  251. class ServiceComponentGUIMetaIconUser(object):
  252.     icon_cache = { }
  253.     
  254.     def get_icon(self, meta, size):
  255.         meta = IServiceComponentGUIMetaData(meta)
  256.         
  257.         try:
  258.             ret = self.icon_cache[(meta.component_id, size)]
  259.         except KeyError:
  260.             ret = self.icon_cache[(meta.component_id, size)] = meta.icon.PIL.Resized(size).WXB
  261.  
  262.         return ret
  263.  
  264.  
  265.  
  266. class ServiceMetaProviderPanel(wxPaintingMixin, wx.Panel, ServiceProviderGUIMetaIconUser):
  267.     protocols.advise(instancesProvide = [
  268.         IPaintable,
  269.         IDrawable])
  270.     
  271.     def __init__(self, service_providers, height, spacing, *a, **k):
  272.         self.service_providers = [ s[0] for s in sorted((lambda .0: for sp in .0:
  273. (sp, IServiceProviderGUIMetaData(sp)))(service_providers), key = (lambda o: o[1].popularity), reverse = True) ]
  274.         self.height = height
  275.         self.spacing = spacing
  276.         super(ServiceMetaProviderPanel, self).__init__(*a, **k)
  277.         self.MinSize = ((len(service_providers) - 1) * (height + spacing) + height, height + spacing)
  278.         self.w = None
  279.         self.Bind(wx.EVT_MOTION, self.on_mouseover, self)
  280.         self.Bind(wx.EVT_LEFT_UP, self.on_mouseclick, self)
  281.         self.Bind(wx.EVT_ENTER_WINDOW, self.on_mousein, self)
  282.         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  283.         self.Bind(wx.EVT_LEAVE_WINDOW, self.on_mouseout, self)
  284.         self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.on_capture_lost, self)
  285.         self.sx = None
  286.         self.sy = None
  287.  
  288.     
  289.     def draw(self, obj):
  290.         dc = IDrawingContext(obj)
  291.         dc.Clear()
  292.         size = self.height
  293.         offset = self.height + self.spacing
  294.         dc.SetPen(wx.TRANSPARENT_PEN)
  295.         dc.DrawRectangle(0, 0, self.Size.width, self.Size.height)
  296.         for i, s in enumerate(self.service_providers):
  297.             dc.DrawBitmap(self.get_icon(s, size), i * offset, 0)
  298.         
  299.  
  300.     on_paint = draw
  301.     
  302.     def service_provider_from_evt(self, e):
  303.         if e.GetEventObject() is not self:
  304.             return None
  305.         if not self.HasCapture():
  306.             return None
  307.         lx = e.X
  308.         r = self.ClientRect
  309.         if not wx.Rect(r.y, r.x, r.width + 1, r.height + 1).Contains(e.Position):
  310.             return None
  311.         offset = self.height + self.spacing
  312.         pos = lx / float(offset)
  313.         posi = int(pos)
  314.         posr = pos - posi
  315.  
  316.     
  317.     def on_mouseover(self, e):
  318.         e.Skip()
  319.         if e.GetEventObject() is not self:
  320.             return None
  321.         if not self.HasCapture():
  322.             return None
  323.         lx = e.X
  324.         r = self.ClientRect
  325.         if not wx.Rect(r.y, r.x, r.width + 1, r.height + 1).Contains(e.Position):
  326.             return self.on_mouseout(e)
  327.         offset = self.height + self.spacing
  328.         pos = lx / float(offset)
  329.         posi = int(pos)
  330.         posr = pos - posi
  331.  
  332.     
  333.     def on_mouseclick(self, e):
  334.         e.Skip()
  335.         sp = self.service_provider_from_evt(e)
  336.         if sp is None:
  337.             return None
  338.         diag = hooks.first('digsby.services.create', parent = self.Top, sp_info = sp, impl = 'digsby_service_editor')
  339.         diag.CenterOnParent()
  340.         return_code = diag.ShowModal()
  341.         if return_code != wx.ID_SAVE:
  342.             log.info('Account creation cancelled. Return code = %r', return_code)
  343.             return None
  344.         info = diag.extract()
  345.         sp = hooks.first('digsby.service_provider', impl = diag.sp_info.provider_id, **info)
  346.         log.info('Created %r', sp)
  347.         components = []
  348.         types_ = sp.get_component_types()
  349.         for type_ in types_:
  350.             comp = sp.get_component(type_)
  351.             components.append((comp, type_[:2]))
  352.             log.info('\thas component %r: %r', type_, comp)
  353.         
  354.         import services.service_provider as sp
  355.         
  356.         try:
  357.             container = _[1]
  358.             profile.account_manager.add_multi(components)
  359.             for comp, type_ in components:
  360.                 
  361.                 try:
  362.                     if hasattr(comp, 'enable'):
  363.                         comp.enable()
  364.                     else:
  365.                         comp.enabled = True
  366.                 except Exception:
  367.                     sp.ServiceProviderContainer(profile()).rebuilding().__exit__
  368.                     sp.ServiceProviderContainer(profile()).rebuilding().__exit__
  369.                     sp.ServiceProviderContainer(profile()).rebuilding()
  370.                     print_exc()
  371.                 except:
  372.                     None if 'im' in types_ else sp is None
  373.  
  374.                 
  375.                 try:
  376.                     on_create = getattr(comp, 'onCreate', None)
  377.                     if on_create is not None:
  378.                         on_create()
  379.                 except Exception:
  380.                     None if 'im' in types_ else sp is None
  381.                     None if 'im' in types_ else sp is None
  382.                     print_exc()
  383.                 except:
  384.                     None if 'im' in types_ else sp is None
  385.  
  386.                 if type_ == 'em':
  387.                     hooks.notify('digsby.email.new_account', parent = self.Top, protocol = comp.protocol, **info)
  388.                     continue
  389.                 None if 'im' in types_ else sp is None
  390.             
  391.             container.rebuild()
  392.         finally:
  393.             pass
  394.  
  395.  
  396.     
  397.     def on_mousein(self, e):
  398.         if e.GetEventObject() is not self:
  399.             return None
  400.         self.CaptureMouse()
  401.  
  402.     
  403.     def on_mouseout(self, e):
  404.         if self.w is not None:
  405.             self.w.Hide()
  406.         
  407.         while self.HasCapture():
  408.             self.ReleaseMouse()
  409.         self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
  410.  
  411.     
  412.     def on_capture_lost(self, e):
  413.         pass
  414.  
  415.  
  416.  
  417. class BubbleWindow(wx.Frame):
  418.     
  419.     def __init__(self, internal_size, parent = None, *a, **k):
  420.         if not parent or wx.FRAME_FLOAT_ON_PARENT:
  421.             pass
  422.         style = wx.FRAME_SHAPED | wx.BORDER_NONE | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP
  423.         ret = super(BubbleWindow, self).__init__(parent, style = style, *a, **k)
  424.         self.Bind(wx.EVT_PAINT, self.on_paint)
  425.         self.internal_size = internal_size
  426.         self.point = (10, 0)
  427.         return ret
  428.  
  429.     
  430.     def draw_content(self, dc):
  431.         pass
  432.  
  433.     
  434.     def poly(self):
  435.         xborder = 0
  436.         yborder = 0
  437.         (startx, starty) = (0, 10)
  438.         (px, py) = self.point
  439.         endx = 2 * xborder + self.internal_size[0] + startx
  440.         endy = 2 * yborder + self.internal_size[1] + starty
  441.         return ((px, py), (px + 1, py), (px + 11, starty), (endx, starty), (endx, endy), (startx, endy), (startx, starty), (px, starty), (px, py))
  442.  
  443.     poly = property(poly)
  444.     
  445.     def show_point_to(self, point):
  446.         (x, y) = point
  447.         xborder = 0
  448.         yborder = 0
  449.         (startx, starty) = (0, 10)
  450.         (px, py) = self.point
  451.         endx = 2 * xborder + self.internal_size[0] + startx
  452.         endy = 2 * yborder + self.internal_size[1] + starty
  453.         self.Frozen().__enter__()
  454.         
  455.         try:
  456.             self.Position = (x - px, y - py)
  457.             self.Size = (endx + 1, endy + 1)
  458.             self.SetShape(get_polyregion(self.poly, endx, endy))
  459.             self.ShowNoActivate(True)
  460.         finally:
  461.             pass
  462.  
  463.  
  464.     
  465.     def on_paint(self, e):
  466.         dc = wx.AutoBufferedPaintDC(self)
  467.         o = wx.Color(254, 214, 76)
  468.         y = wx.Color(255, 251, 184)
  469.         dc.SetPen(wx.Pen(o))
  470.         dc.SetBrush(wx.Brush(y))
  471.         dc.DrawPolygon(self.poly)
  472.         self.draw_content(dc)
  473.  
  474.  
  475.  
  476. class ServiceProviderBubble(BubbleWindow, ServiceComponentGUIMetaIconUser):
  477.     
  478.     def __init__(self, service_provider, font_adjust = 0, *a, **k):
  479.         self.service_provider = IServiceProviderGUIMetaData(service_provider)
  480.         super(ServiceProviderBubble, self).__init__((0, 0), *a, **k)
  481.         self.Font = default_font()
  482.         self.font_adjust = font_adjust
  483.         self._service_provider = None
  484.         self.recalcsize()
  485.  
  486.     
  487.     def recalcsize(self):
  488.         if self.service_provider is self._service_provider:
  489.             return None
  490.         ftitle = self.Font
  491.         ftitle.PointSize = int((ftitle.PointSize + self.font_adjust) * 4 / 3)
  492.         fbase = self.Font
  493.         fbase.PointSize += self.font_adjust
  494.         h = 0
  495.         h += ftitle.LineHeight + 2
  496.         h += ftitle.Descent * 2
  497.         lh = round(fbase.LineHeight / 4 + 0.25) * 4 + 2
  498.         h += lh * len(self.service_provider.service_components) - 2
  499.         dc = wx.ClientDC(self)
  500.         dc.Font = ftitle
  501.         w = dc.GetTextExtent(self.service_provider.provider_name)[0]
  502.         self.offset = dc.GetTextExtent(' ')[0]
  503.         dc.Font = fbase
  504.         w2 = []([ dc.GetTextExtent(' ' + IServiceComponentGUIMetaData(s).service_name)[0] for s in self.service_provider.service_components ] + [
  505.             0])
  506.         w2 += lh
  507.         w2 += self.offset
  508.         w = max(w, w2)
  509.         w += ftitle.Descent * 4
  510.         h += 2
  511.         self.internal_size = (int(w), int(h))
  512.         self._service_provider = self.service_provider
  513.  
  514.     
  515.     def draw_content(self, dc):
  516.         ftitle = self.Font
  517.         ftitle.PointSize = int((ftitle.PointSize + self.font_adjust) * 4 / 3)
  518.         fbase = self.Font
  519.         fbase.PointSize += self.font_adjust
  520.         dc.Font = ftitle
  521.         x = ftitle.Descent * 2
  522.         y = 10 + ftitle.Descent * 1
  523.         dc.DrawText(self.service_provider.provider_name, x, y)
  524.         y += ftitle.LineHeight + 2
  525.         lh = int(round(fbase.LineHeight / 4 + 0.25)) * 4 + 2
  526.         dc.Font = fbase
  527.         x += self.offset
  528.         for s in sorted((lambda .0: for sc in .0:
  529. IServiceComponentGUIMetaData(sc))(self.service_provider.service_components), key = attrgetter('type'), cmp = component_sort):
  530.             dc.DrawBitmap(self.get_icon(s, lh - 2), x, y)
  531.             dc.DrawText(' ' + s.service_name, x + lh, y)
  532.             y += lh
  533.         
  534.  
  535.     
  536.     def show_point_to(self, point):
  537.         self.recalcsize()
  538.         return super(ServiceProviderBubble, self).show_point_to(point)
  539.  
  540.  
  541.  
  542. def get_polyregion(points, w, h, border = 1):
  543.     i = wx.EmptyImage(w + border, h + border)
  544.     b = i.WXB
  545.     m = wx.MemoryDC(b)
  546.     m.Clear()
  547.     m.SetBrush(wx.Brush(wx.Color(0, 0, 0)))
  548.     m.SetPen(wx.Pen(wx.Color(0, 0, 0)))
  549.     m.DrawRectangle(0, 0, w + border, h + border)
  550.     m.SetBrush(wx.Brush(wx.Color(255, 255, 255)))
  551.     m.SetPen(wx.Pen(wx.Color(255, 255, 255)))
  552.     m.DrawPolygon(points)
  553.     m.SelectObject(wx.NullBitmap)
  554.     del m
  555.     b.SetMaskColour(wx.Color(0, 0, 0))
  556.     return wx.RegionFromBitmap(b)
  557.  
  558. get_polyregion = memoize(get_polyregion)
  559.  
  560. class IServiceProviderInstance(protocols.Interface):
  561.     icon = property()
  562.  
  563.  
  564. def grayify(i, grayshade):
  565.     return int(round((i + grayshade) / 2))
  566.  
  567.  
  568. def grayify3(tuple_, grayshade):
  569.     return (tuple,)((lambda .0: for i in .0:
  570. grayify(i, grayshade))(tuple_))
  571.  
  572.  
  573. class CheckModel(trellis.Component):
  574.     value = trellis.attr(False)
  575.     enabled = trellis.attr(True)
  576.  
  577.  
  578. class ListenerSync(trellis.Component):
  579.     listener = trellis.attr()
  580.     model = trellis.attr()
  581.  
  582.  
  583. class ModelListenerSync(ListenerSync):
  584.     
  585.     def value(self):
  586.         self.model.value = self.listener.value
  587.  
  588.     value = trellis.maintain(value)
  589.  
  590.  
  591. class ListenerModelSync(ListenerSync):
  592.     
  593.     def keep_value(self):
  594.         self.listener.value = self.model.value
  595.  
  596.     keep_value = trellis.maintain(keep_value)
  597.  
  598.  
  599. class ViewListenerModelSync(ListenerModelSync):
  600.     view = trellis.attr()
  601.  
  602.  
  603. class CheckModelSync(ViewListenerModelSync):
  604.     
  605.     def update(self):
  606.         
  607.         try:
  608.             self.view.Frozen().__enter__()
  609.             
  610.             try:
  611.                 self.view.Enabled = self.model.enabled
  612.                 self.view.Value = self.model.value
  613.             finally:
  614.                 pass
  615.  
  616.         except Exception:
  617.             if not wx.IsDestroyed(self.view):
  618.                 raise 
  619.             wx.IsDestroyed(self.view)
  620.  
  621.  
  622.     update = trellis.perform(update)
  623.  
  624.  
  625. class CheckSync(object):
  626.     
  627.     def __init__(self, model, view):
  628.         listener = IValueListener(view)
  629.         self.model_to_view = CheckModelSync(model = model, view = view, listener = listener)
  630.         self.view_to_model = ModelListenerSync(model = model, listener = listener)
  631.  
  632.  
  633.  
  634. class AccountModelSync(ViewListenerModelSync):
  635.     
  636.     def update(self):
  637.         has_enabled = hasattr(self.view, 'enabled')
  638.         if has_enabled and self.view.enabled != self.model.value:
  639.             val = self.model.value
  640.             if val and hasattr(self.view, 'enable'):
  641.                 self.view.enable()
  642.             elif not val and hasattr(self.view, 'disable'):
  643.                 self.view.disable()
  644.             else:
  645.                 self.view.setnotify('enabled', val)
  646.                 wx.CallAfter(self.view.update_info)
  647.         
  648.  
  649.     update = trellis.perform(update)
  650.  
  651.  
  652. class AccountEnabledSync(object):
  653.     
  654.     def __init__(self, model, view):
  655.         listener = IValueListener(ObservableAttrBindable(view, 'enabled'))
  656.         self.acct_to_model = ModelListenerSync(model = model, listener = listener)
  657.         self.model_to_acct = AccountModelSync(model = model, view = view, listener = listener)
  658.  
  659.  
  660.  
  661. class EnabledAccountSync(object):
  662.     
  663.     def __init__(self, model, view):
  664.         listener = IValueListener(ObservableAttrBindable(view, 'enabled'))
  665.         self.model_to_acct = AccountModelSync(model = model, view = view, listener = listener)
  666.         self.acct_to_model = ModelListenerSync(model = model, listener = listener)
  667.  
  668.  
  669.  
  670. class AccountEnabledCheckSync(object):
  671.     
  672.     def __init__(self, account, check):
  673.         model = CheckModel()
  674.         self.acct_model = AccountEnabledSync(model = model, view = account)
  675.         self.view_model = CheckSync(model = model, view = check)
  676.  
  677.  
  678.  
  679. class NoAccountEnabledCheckSync(trellis.Component):
  680.     created_account = trellis.attr(False)
  681.     
  682.     def __init__(self, provider, component, check):
  683.         super(NoAccountEnabledCheckSync, self).__init__()
  684.         self.model = CheckModel()
  685.         self.provider = provider
  686.         self.component = component
  687.         self.view_model = CheckSync(model = self.model, view = check)
  688.  
  689.     
  690.     def update(self):
  691.         if not self.model.value:
  692.             return None
  693.         if self.created_account:
  694.             return None
  695.         self.created_account = True
  696.         acct = self.provider.get_component(self.component.type)
  697.         profile.account_manager.add(acct, self.component.type[:2], ignore_on_rebuild = True)
  698.         self.acct_to_model = EnabledAccountSync(model = self.model, view = acct)
  699.  
  700.     update = trellis.maintain(update)
  701.  
  702.  
  703. class ServiceProviderRow(AccountRow, ServiceProviderGUIMetaIconUser):
  704.     row_height = 50
  705.     
  706.     def __init__(self, parent, data, *a, **k):
  707.         self.data = data
  708.         self._base_color_tuple = (128, 128, 128)
  709.         self._name_color_tuple = (0, 0, 0)
  710.         ret = super(ServiceProviderRow, self).__init__(parent = parent, data = data, *a, **k)
  711.         self.Font = default_font()
  712.         return ret
  713.  
  714.     
  715.     def image(self):
  716.         
  717.         try:
  718.             ret = self.get_icon(self.data, 40)
  719.         except AttributeError:
  720.             ret = super(ServiceProviderRow, self).image
  721.  
  722.         return ret
  723.  
  724.     image = property(image)
  725.     
  726.     def draw_text(self, dc, x, sz):
  727.         pass
  728.  
  729.     
  730.     def _paint(self, e):
  731.         dc = super(ServiceProviderRow, self)._paint(e)
  732.         f = self.Font
  733.         f.PointSize += 3
  734.         dc.Font = f
  735.         name = IServiceProviderInstanceGUIMetaData(self.data).account_name
  736.         (x, y) = self._place_text.Position
  737.         y += f.Descent
  738.         for color, string in ():
  739.             color_obj = getattr(self, '_active_%s_color' % color, None)
  740.             dc.SetTextForeground(wx.Color(*color_obj))
  741.             dc.DrawText(string, x, y)
  742.             x += dc.GetTextExtent(string)[0]
  743.  
  744.     
  745.     def ConstructMore(self):
  746.         self.checks = []
  747.         self.hiddens = []
  748.         import gui.lattice as gui
  749.         for s in sorted((lambda .0: for sc in .0:
  750. IServiceComponentGUIMetaData(sc))(IServiceProviderGUIMetaData(self.data).service_components), key = attrgetter('type'), cmp = component_sort):
  751.             c = wx.CheckBox(self, -1, s.service_name)
  752.             for a in self.data.accounts.values():
  753.                 if a.protocol == s.component_id:
  754.                     c.controller = AccountEnabledCheckSync(account = a, check = c)
  755.                     break
  756.                     continue
  757.             else:
  758.                 c.controller = NoAccountEnabledCheckSync(provider = self.data, component = s, check = c)
  759.             if s.type == 'im':
  760.                 text = wx.StaticText(self, label = _('(auto login)'))
  761.                 f = c.Font
  762.                 text.Font = f
  763.                 text.ForegroundColour = wx.Color(*self._base_color_tuple)
  764.                 text.Hide()
  765.                 self.hiddens.append(text)
  766.                 c = (c, text)
  767.             
  768.             self.checks.append(c)
  769.         
  770.         edit = self.edit = wx.HyperlinkCtrl(self, -1, _('Edit'), '#')
  771.         edit.Hide()
  772.         edit.Bind((wx.EVT_HYPERLINK,), (lambda e: self.on_edit()))
  773.         remove = self.remove = wx.HyperlinkCtrl(self, -1, _('Remove'), '#')
  774.         remove.Hide()
  775.         remove.Bind((wx.EVT_HYPERLINK,), (lambda e: self.on_delete()))
  776.         self.hiddens.append(edit)
  777.         self.hiddens.append(remove)
  778.         edit.HoverColour = edit.VisitedColour = edit.ForegroundColour
  779.         remove.HoverColour = remove.VisitedColour = remove.ForegroundColour
  780.         self._reset_text_name()
  781.  
  782.     
  783.     def on_edit(self):
  784.         super(ServiceProviderRow, self).on_edit()
  785.         self.on_data_changed(self)
  786.  
  787.     
  788.     def on_delete(self):
  789.         super(ServiceProviderRow, self).on_delete()
  790.         super(ServiceProviderRow, self).on_data_changed(self)
  791.  
  792.     
  793.     def _reset_text_name(self):
  794.         dc = wx.ClientDC(self)
  795.         f = self.Font
  796.         f.PointSize += 3
  797.         dc.Font = f
  798.         txt = IServiceProviderInstanceGUIMetaData(self.data).account_name
  799.         (w, h) = dc.GetTextExtent(txt)
  800.         self.text_name = (w, h)
  801.  
  802.     
  803.     def CalcColors(self, *a, **k):
  804.         if self.IsHovered():
  805.             self._active_base_color = self._base_color_tuple
  806.             self._active_name_color = self._name_color_tuple
  807.         else:
  808.             self._active_base_color = grayify3(self._base_color_tuple, 128)
  809.             self._active_name_color = grayify3(self._name_color_tuple, 128)
  810.         return super(ServiceProviderRow, self).CalcColors(*a, **k)
  811.  
  812.     
  813.     def LayoutMore(self, sizer):
  814.         check_sizer = VSizer()
  815.         check_sizer.AddStretchSpacer(3)
  816.         for check in self.checks:
  817.             if isinstance(check, tuple):
  818.                 (check, text) = check
  819.                 h = HSizer()
  820.                 h.Add(check)
  821.                 h.Add(text)
  822.                 check_sizer.Add(h)
  823.             else:
  824.                 check_sizer.Add(check)
  825.             check_sizer.AddStretchSpacer()
  826.         
  827.         check_sizer.AddStretchSpacer(2)
  828.         sizer.Add(check_sizer, 1, wx.LEFT | wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, self.padding.x * 2)
  829.         right_sizer = VSizer()
  830.         self._place_text = right_sizer.Add(self.text_name, 3, wx.ALIGN_RIGHT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, self.padding.y)
  831.         link_sizer = HSizer()
  832.         link_sizer.Add(self.edit, 0, wx.LEFT, self.padding.x)
  833.         link_sizer.Add(self.remove, 0, wx.LEFT, self.padding.x)
  834.         right_sizer.AddStretchSpacer()
  835.         right_sizer.Add(link_sizer, 3, wx.ALIGN_RIGHT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, self.padding.y)
  836.         sizer.Add(right_sizer, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 0)
  837.  
  838.     
  839.     def on_data_changed(self, src = None, *a):
  840.         super(ServiceProviderRow, self).on_data_changed(src, *a)
  841.         self._reset_text_name()
  842.         self.layout()
  843.         self.Layout()
  844.         self.Refresh()
  845.  
  846.  
  847. sorted_component_types = [
  848.     'social',
  849.     'email',
  850.     'im']
  851.  
  852. def component_sort(a, b):
  853.     return find(sorted_component_types, b) - find(sorted_component_types, a)
  854.  
  855.  
  856. class ServiceProviderGUIMetaDataAdapter(protocols.Adapter):
  857.     protocols.advise(asAdapterForTypes = [
  858.         sp.ServiceProvider], instancesProvide = [
  859.         IServiceProviderInstanceGUIMetaData])
  860.     
  861.     def account_name(self):
  862.         name = None
  863.         
  864.         try:
  865.             name = getattr(self.subject, 'display_name', None)
  866.         except Exception:
  867.             print_exc()
  868.             if name is None:
  869.                 name = self.subject.name
  870.             
  871.         except:
  872.             name is None
  873.  
  874.         return name
  875.  
  876.     account_name = property(account_name)
  877.  
  878.  
  879. class ProviderList(AccountList):
  880.     
  881.     def __init__(self, *a, **k):
  882.         super(ProviderList, self).__init__(*a, **k)
  883.         self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.OnHoveredChanged)
  884.  
  885.     
  886.     def OnHoveredChanged(self, e):
  887.         row = self.GetRow(e.Int)
  888.  
  889.     
  890.     def on_edit(self, rowdata):
  891.         diag = hooks.first('digsby.services.edit', parent = self.Top, sp = rowdata, impl = 'digsby_service_editor')
  892.         return_code = diag.ShowModal()
  893.         if return_code != wx.ID_SAVE:
  894.             return None
  895.         info = diag.RetrieveData()
  896.         log.info('Modifying %r', rowdata)
  897.         rowdata.update_info(info)
  898.         rowdata.update_components(info)
  899.  
  900.     
  901.     def OnDelete(self, data):
  902.         msgbox = hooks.first('digsby.services.delete.build_dialog', impls = (data.provider_id, 'default'), parent = self.Top, SP = data)
  903.         
  904.         try:
  905.             if msgbox.ShowModal() == wx.ID_YES:
  906.                 for type_ in data.get_component_types():
  907.                     comp = data.get_component(type_, create = False)
  908.                     if comp is None:
  909.                         continue
  910.                     
  911.                     profile.account_manager.remove(comp)
  912.                 
  913.         finally:
  914.             msgbox.Destroy()
  915.  
  916.  
  917.     
  918.     def get_wheel_lines(self, rotation, e):
  919.         val = (rotation / float(e.GetWheelDelta())) * e.LinesPerAction
  920.         return val / 2.5
  921.  
  922.     
  923.     def rotation_for_lines(self, lines, e):
  924.         return (float(e.GetWheelDelta()) / e.LinesPerAction) * lines * 2.5
  925.  
  926.  
  927.  
  928. def panel(panel, sizer, addgroup, exithooks):
  929.     service_providers = ServiceMetaProviderPanel(sp.get_meta_service_providers(), 40, 3, panel)
  930.     two = PrefPanel(panel, service_providers, _('Add Accounts'))
  931.     import services
  932.     container = services.service_provider.ServiceProviderContainer(profile())
  933.     if not container.get_ordered():
  934.         pass
  935.     provider_accts = observe.ObservableList([])
  936.     
  937.     def on_change(*a, **k):
  938.         if not provider_accts.isflagged('being_set'):
  939.             order = []
  940.             for provider in provider_accts:
  941.                 for type_ in ('im', 'email', 'social'):
  942.                     if type_ in provider.accounts:
  943.                         order.append(provider.accounts[type_].id)
  944.                         continue
  945.                 
  946.             
  947.             container.set_order(order)
  948.         
  949.  
  950.     
  951.     def order_set(*a, **k):
  952.         
  953.         def do_set():
  954.             new = container.get_ordered()
  955.  
  956.         do_set = (None, wx.CallAfter)(do_set)
  957.  
  958.     container.on_order_changed += order_set
  959.     
  960.     def unregister(*a, **k):
  961.         if order_set in container.on_order_changed:
  962.             container.on_order_changed -= order_set
  963.         
  964.  
  965.     exithooks += unregister
  966.     accts = ProviderList(panel, provider_accts, row_control = (lambda : ServiceProviderRow(use_checkbox = False, *a, **k)), edit_buttons = None)
  967.     provider_accts.add_observer(on_change, obj = accts)
  968.     three = PrefPanel(panel, accts, _('My Accounts'))
  969.     sizer.Add(two, 0, EXPAND)
  970.     sizer.Add(three, 1, EXPAND | wx.TOP, 3)
  971.     four = PrefPanel(panel, choices_sizer(panel, exithooks), _('Account Options'))
  972.     sizer.Add(four, 0, EXPAND | wx.TOP, 3)
  973.     return panel
  974.  
  975.  
  976. def set_loc_values(model, prefname):
  977.     val = pref(prefname)
  978.     
  979.     try:
  980.         model.selection = [ v[0] for v in model.values ].index(val)
  981.     except ValueError:
  982.         pass
  983.  
  984.  
  985.  
  986. class PrefChoiceWatcher(trellis.Component):
  987.     
  988.     def __init__(self, model, prefname):
  989.         trellis.Component.__init__(self)
  990.         self.model = model
  991.         self.prefname = prefname
  992.  
  993.     
  994.     def output_pref(self):
  995.         mark_pref(self.prefname, self.model.values[self.model.selection][0])
  996.  
  997.     output_pref = trellis.perform(output_pref)
  998.  
  999.  
  1000. class AccountLocationModels(AddOn):
  1001.     did_setup = False
  1002.     
  1003.     def __init__(self, subject):
  1004.         self.profile = subject
  1005.         super(AccountLocationModels, self).__init__(subject)
  1006.  
  1007.     
  1008.     def setup(self):
  1009.         if self.did_setup:
  1010.             return None
  1011.         self.did_setup = True
  1012.         account_options = [
  1013.             ('panel', _('buddy list')),
  1014.             ('systray', _('icon tray')),
  1015.             ('both', _('buddy list and icon tray'))]
  1016.         email_pref = 'buddylist.show_email_as'
  1017.         social_pref = 'buddylist.show_social_as'
  1018.         set_loc_values(email, email_pref)
  1019.         set_loc_values(social, social_pref)
  1020.         self.profile.prefs.add_observer(self.on_email_changed, email_pref)
  1021.         self.profile.prefs.add_observer(self.on_social_changed, social_pref)
  1022.         self.email_watcher = PrefChoiceWatcher(self.email, email_pref)
  1023.         self.social_watcher = PrefChoiceWatcher(self.social, social_pref)
  1024.  
  1025.     
  1026.     def location_models(self):
  1027.         return [
  1028.             self.email,
  1029.             self.social]
  1030.  
  1031.     location_models = property(location_models)
  1032.     
  1033.     def on_email_changed(self, src, attr, old, new):
  1034.         import wx
  1035.         wx.CallAfter(set_loc_values, self.email, 'buddylist.show_email_as')
  1036.  
  1037.     
  1038.     def on_social_changed(self, src, attr, old, new):
  1039.         import wx
  1040.         wx.CallAfter(set_loc_values, self.social, 'buddylist.show_social_as')
  1041.  
  1042.  
  1043.  
  1044. def choices_sizer(panel, exithooks):
  1045.     p = wx.Panel(panel)
  1046.     sz = p.Sizer = VSizer()
  1047.     model_addon = AccountLocationModels(common.profile())
  1048.     model_addon.setup()
  1049.     location_models = model_addon.location_models
  1050.     import gui.lattice as gui
  1051.     choices = list(yield_choices(location_models, p))
  1052.     (exithooks.append,)((lambda : release_choices(choices)))
  1053.     labels = [
  1054.         _('Show email accounts in:'),
  1055.         _('Show social networks in:')]
  1056.     to_add = [ [
  1057.         (SText(p, label), 0, wx.ALIGN_CENTER_VERTICAL),
  1058.         (choice, 1, 0)] for label, choice in zip(labels, choices) ]
  1059.     s = wx.FlexGridSizer(len(location_models), 2, 7, 7)
  1060.     s.AddMany(sum(to_add, []))
  1061.     s.AddGrowableCol(1, 1)
  1062.     sz.Add(s, 0, EXPAND)
  1063.     return p
  1064.  
  1065.