home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 October / maximum-cd-2011-10.iso / DiscContents / digsby_setup.exe / lib / gui / treelist.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-06-22  |  15.9 KB  |  555 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. from __future__ import division
  6. app = None
  7. import wx
  8. from wx import WXK_LEFT, WXK_RIGHT, WXK_DOWN, WXK_UP, Rect
  9. from util.primitives.funcs import Delegate
  10. from logging import getLogger
  11. log = getLogger('treelist')
  12. info = log.info
  13. from gui.textutil import GetFontHeight, default_font
  14. from contextlib import contextmanager
  15.  
  16. expanded_id = lambda obj: u'_'.join([
  17. type(obj).__name__,
  18. obj.name])
  19.  
  20. idfunc = lambda obj: obj.__hash__()
  21.  
  22. def hasChildren(obj):
  23.     
  24.     try:
  25.         iter(obj)
  26.     except:
  27.         return False
  28.  
  29.     return True
  30.  
  31.  
  32. class ListMixin(object):
  33.     
  34.     def __init__(self, listAttrName):
  35.         self._listAttrName = listAttrName
  36.  
  37.     
  38.     def __len__(self):
  39.         return len(self.__dict__[self._listAttrName])
  40.  
  41.     
  42.     def __iter__(self):
  43.         return self.__dict__[self._listAttrName].__iter__()
  44.  
  45.     
  46.     def __getitem__(self, n):
  47.         return self.__dict__[self._listAttrName][n]
  48.  
  49.  
  50.  
  51. class TreeListModel(ListMixin):
  52.     
  53.     def __init__(self, root = None, collapsed = None):
  54.         if not root:
  55.             pass
  56.         self.root = []
  57.         self.collapsed = None if collapsed is not None else set()
  58.         self.flattened_list = []
  59.         self.listeners = []
  60.         self.depths = { }
  61.         self.filters = []
  62.         self.donotexpand = []
  63.         self._expandable_cache = { }
  64.         self.update_list()
  65.         self.expansion_state_changed = Delegate()
  66.         ListMixin.__init__(self, 'flattened_list')
  67.  
  68.     
  69.     def _expandable(self, eltype):
  70.         
  71.         try:
  72.             return self._expandable_cache[eltype]
  73.         except KeyError:
  74.             for i in self.donotexpand:
  75.                 if issubclass(eltype, i):
  76.                     return self._expandable_cache.setdefault(eltype, False)
  77.             
  78.             return self._expandable_cache.setdefault(eltype, True)
  79.             issubclass(eltype, i)
  80.  
  81.  
  82.     
  83.     def expandable(self, el):
  84.         return self._expandable(el.__class__)
  85.  
  86.     
  87.     def flatten(self, root, collapsed, depths, depth = 0, filters = [], expanded_id = expanded_id):
  88.         lst = [
  89.             root]
  90.         if hasChildren(root):
  91.             for el in root:
  92.                 depths[idfunc(el)] = (depth, root)
  93.                 if expanded_id(el) not in collapsed and self.expandable(el):
  94.                     lst.extend(self.flatten(el, collapsed, depths, depth + 1, filters, expanded_id = expanded_id))
  95.                     continue
  96.                 lst.append(el)
  97.             
  98.         
  99.         return lst
  100.  
  101.     
  102.     def __repr__(self):
  103.         return '<TreeListModel %r>' % self.flattened_list
  104.  
  105.     
  106.     def expand(self, obj):
  107.         i = expanded_id(obj)
  108.         self.collapsed.discard(i)
  109.         self.expansion_state_changed()
  110.         self.update_list()
  111.  
  112.     
  113.     def collapse(self, obj):
  114.         self.collapsed.add(expanded_id(obj))
  115.         self.expansion_state_changed()
  116.         self.update_list()
  117.  
  118.     
  119.     def toggle_expand(self, obj):
  120.         if obj.__class__ not in self.donotexpand:
  121.             if expanded_id(obj) not in self.collapsed:
  122.                 self.collapse(obj)
  123.             elif hasChildren(obj):
  124.                 self.expand(obj)
  125.             
  126.         
  127.  
  128.     
  129.     def is_expanded(self, n):
  130.         return expanded_id(self.flattened_list[n]) not in self.collapsed
  131.  
  132.     
  133.     def parent_of(self, child):
  134.         return self.depths[idfunc(child)][1]
  135.  
  136.     
  137.     def index_of(self, child):
  138.         
  139.         try:
  140.             if idfunc(child) in self.indices:
  141.                 return self.indices[idfunc(child)]
  142.             return -1
  143.         except:
  144.             return -1
  145.  
  146.  
  147.     
  148.     def set_root(self, root):
  149.         self.depths = { }
  150.         self.root = root
  151.         self.update_list()
  152.  
  153.     
  154.     def update_list(self):
  155.         self.flattened_list = self.flatten(self.root, self.collapsed, self.depths, filters = self.filters)[1:]
  156.         self.indices = dict((lambda .0: for c, item in .0:
  157. (idfunc(item), c))(enumerate(self.flattened_list)))
  158.         for l in self.listeners:
  159.             l.list_changed()
  160.         
  161.  
  162.     
  163.     def remove_child(self, child):
  164.         parent = self.depths[idfunc(child)][1]
  165.         parent.remove(child)
  166.         self.update_list()
  167.  
  168.  
  169. from cgui import SkinVList as TreeListBase
  170.  
  171. class TreeList(TreeListBase):
  172.     
  173.     def __init__(self, parent, model, id = -1, style = wx.NO_BORDER | wx.FULL_REPAINT_ON_RESIZE | wx.HSCROLL | wx.VSCROLL, enable_hover = True, keyhandler = None):
  174.         self.renderers = { }
  175.         self.renderers_cache = { }
  176.         self.context_menu_handlers = { }
  177.         TreeListBase.__init__(self, parent, id, style)
  178.         self.model = model
  179.         model.listeners.append(self)
  180.         measure = self.OnMeasureItem
  181.         []([ measure(n) for n in xrange(len(self.model)) ])
  182.         Bind = self.Bind
  183.         Bind(wx.EVT_LISTBOX_DCLICK, self.on_doubleclick)
  184.         Bind(wx.EVT_RIGHT_DOWN, self.on_right_down)
  185.         Bind(wx.EVT_KEY_DOWN, self.on_key_down)
  186.         self.hoveridx = -1
  187.         if enable_hover:
  188.             Bind(wx.EVT_MOTION, self.on_motion)
  189.             Bind(wx.EVT_LEAVE_WINDOW, self.on_leave_window)
  190.         
  191.         self.indent = 10
  192.  
  193.     
  194.     def on_leave_window(self, e):
  195.         self.Hover = -1
  196.         e.Skip(True)
  197.  
  198.     
  199.     def on_motion(self, e):
  200.         self.Hover = self.HitTest(e.Position)
  201.         e.Skip(True)
  202.  
  203.     
  204.     def toggle_expand(self, obj):
  205.         i = self.GetSelection()
  206.         model = self.model
  207.         selected = self.model[i]
  208.         do_select = False
  209.         if i != -1:
  210.             
  211.             try:
  212.                 parent = self.GetParent(model[i])
  213.             except KeyError:
  214.                 pass
  215.  
  216.             p = model.index_of(parent)
  217.             if parent is obj and model.is_expanded(p):
  218.                 self.SetSelection(p)
  219.             else:
  220.                 do_select = True
  221.         
  222.         self.model.toggle_expand(obj)
  223.         if do_select:
  224.             self.SetSelection(model.index_of(selected), keepVisible = False)
  225.         
  226.  
  227.     
  228.     def GetItemRect(self, item, include_children = True):
  229.         if not include_children:
  230.             return TreeListBase.GetItemRect(self, self.model.index_of(item))
  231.         model = self.model
  232.         modellen = len(self.model)
  233.         measure = self.OnMeasureItem
  234.         i = model.index_of(item)
  235.         rect = Rect(0, self.GetItemY(i), self.ClientRect.width, measure(i))
  236.         if include_children:
  237.             i += 1
  238.             while i < modellen and self.GetParent(model[i]) is item:
  239.                 rect.height += measure(i)
  240.                 i += 1
  241.                 continue
  242.                 rect
  243.         
  244.         return rect
  245.  
  246.     
  247.     def get_hover(self):
  248.         return self.hoveridx
  249.  
  250.     
  251.     def set_hover(self, i):
  252.         old = self.hoveridx
  253.         self.hoveridx = i
  254.         if i != old:
  255.             if old != -1:
  256.                 self.RefreshLine(old)
  257.             
  258.             if i != -1:
  259.                 self.RefreshLine(i)
  260.             
  261.         
  262.  
  263.     Hover = property(get_hover, set_hover)
  264.     
  265.     def GetSelectedItem(self):
  266.         i = self.GetSelection()
  267.         if i != -1:
  268.             
  269.             try:
  270.                 return self.model[i]
  271.             except IndexError:
  272.                 pass
  273.             except:
  274.                 None<EXCEPTION MATCH>IndexError
  275.             
  276.  
  277.         None<EXCEPTION MATCH>IndexError
  278.  
  279.     SelectedItem = property(GetSelectedItem)
  280.     
  281.     def __getitem__(self, i):
  282.         return self.model[i]
  283.  
  284.     
  285.     def GetParent(self, obj):
  286.         return self.model.parent_of(obj)
  287.  
  288.     
  289.     def save_selection(self):
  290.         i = self.GetSelection()
  291.         elem = None
  292.         model = self.model
  293.         if i != -1:
  294.             
  295.             try:
  296.                 elem = model[i]
  297.             except IndexError:
  298.                 elem = None
  299.             except:
  300.                 None<EXCEPTION MATCH>IndexError
  301.             
  302.  
  303.         None<EXCEPTION MATCH>IndexError
  304.         
  305.         try:
  306.             yield None
  307.         finally:
  308.             if elem is None:
  309.                 sel = -1
  310.             else:
  311.                 sel = model.index_of(elem)
  312.             if sel == -1:
  313.                 if hasattr(self, 'fallback_selection'):
  314.                     sel = self.fallback_selection
  315.                     del self.fallback_selection
  316.                 
  317.             
  318.             TreeList.SetSelection(self, sel, False)
  319.  
  320.  
  321.     save_selection = contextmanager(save_selection)
  322.     
  323.     def set_root(self, root):
  324.         self.save_selection().__enter__()
  325.         
  326.         try:
  327.             self.renderers_cache = { }
  328.             self.model.set_root(root)
  329.         finally:
  330.             pass
  331.  
  332.  
  333.     
  334.     def on_key_down(self, e):
  335.         i = self.GetSelection()
  336.         model = self.model
  337.         keycode = e.KeyCode
  338.         modifiers = e.Modifiers
  339.         
  340.         try:
  341.             obj = self.model[i]
  342.         except IndexError:
  343.             obj = None
  344.  
  345.         if keycode == WXK_LEFT:
  346.             if modifiers == wx.MOD_SHIFT:
  347.                 self.collapse_all()
  348.             elif obj is not None and modifiers == wx.MOD_NONE:
  349.                 if model.expandable(obj) and model.is_expanded(i):
  350.                     self.toggle_expand(obj)
  351.                 else:
  352.                     self.select_parent(obj)
  353.             
  354.         elif keycode == WXK_RIGHT:
  355.             if modifiers == wx.MOD_SHIFT:
  356.                 self.expand_all()
  357.             elif obj is not None and modifiers == wx.MOD_NONE:
  358.                 if model.expandable(obj):
  359.                     if not model.is_expanded(i):
  360.                         self.toggle_expand(obj)
  361.                     elif i + 1 < self.GetItemCount() and self.GetParent(model[i + 1]) is obj:
  362.                         self.SetSelection(self.GetSelection() + 1)
  363.                     
  364.                 
  365.             
  366.         elif keycode == WXK_UP:
  367.             sel = self.GetSelection() - 1
  368.             if sel >= 0:
  369.                 self.SetSelection(sel)
  370.             
  371.         elif keycode == WXK_DOWN:
  372.             sel = self.GetSelection() + 1
  373.             if sel < self.GetItemCount():
  374.                 self.SetSelection(sel)
  375.             
  376.         elif keycode == wx.WXK_PAGEUP:
  377.             self.PageUp()
  378.             self.SetSelection(self.GetFirstVisibleLine())
  379.         elif keycode == wx.WXK_PAGEDOWN:
  380.             self.PageDown()
  381.             self.SetSelection(self.GetFirstVisibleLine())
  382.         else:
  383.             e.Skip(True)
  384.  
  385.     
  386.     def select_parent(self, obj):
  387.         parent = self.GetParent(obj)
  388.         if parent is not None:
  389.             i = self.model.index_of(parent)
  390.             if i != -1:
  391.                 self.SetSelection(i)
  392.             
  393.         
  394.  
  395.     
  396.     def renderer_for(self, obj):
  397.         
  398.         try:
  399.             k = obj._renderer
  400.         except AttributeError:
  401.             
  402.             try:
  403.                 k = obj.__class__.__name__
  404.             except AttributeError:
  405.                 k = None
  406.             except:
  407.                 None<EXCEPTION MATCH>AttributeError
  408.             
  409.  
  410.             None<EXCEPTION MATCH>AttributeError
  411.  
  412.         return self.renderers.get(k, None)
  413.  
  414.     
  415.     def renderer_for_index(self, n):
  416.         
  417.         try:
  418.             renderer = self.renderers_cache[n]
  419.         except KeyError:
  420.             renderer = self.renderers_cache[n] = self.renderer_for(self.model[n])
  421.  
  422.         return renderer
  423.  
  424.     
  425.     hit_test_ex = lambda self, pt, h = TreeListBase.HitTestEx: h(self, *pt)
  426.     collapsedTri = [
  427.         (0, 0),
  428.         (7, 3),
  429.         (0, 7)]
  430.     expandedTri = [
  431.         (0, 0),
  432.         (7, 0),
  433.         (3, 3)]
  434.     
  435.     def hit_test_parent(self, mouse_pos):
  436.         model = self.model
  437.         (i, unused_percent) = self.hit_test_ex(mouse_pos)
  438.         if i == -1:
  439.             return (-1, None)
  440.         parent = model.parent_of(model[i])
  441.         j = model.index_of(parent)
  442.         if j != -1:
  443.             rect = self.GetItemRect(parent)
  444.             i = j
  445.         else:
  446.             rect = self.GetItemRect(model[i])
  447.         percent = (mouse_pos.y - rect.y) / rect.height
  448.         return (i, percent)
  449.  
  450.     
  451.     def default_draw(self, dc, rect, n):
  452.         if self.IsSelected(n):
  453.             fg = wx.SYS_COLOUR_HIGHLIGHTTEXT
  454.         else:
  455.             fg = wx.SYS_COLOUR_WINDOWTEXT
  456.         dc.SetTextForeground(wx.SystemSettings_GetColour(fg))
  457.         font = default_font()
  458.         dc.SetFont(font)
  459.         if self.model.is_expanded(n):
  460.             tri = self.expandedTri
  461.         else:
  462.             tri = self.collapsedTri
  463.         dc.SetPen(wx.BLACK_PEN)
  464.         dc.SetBrush(wx.BLACK_BRUSH)
  465.         obj = self.model[n]
  466.         xoffset = self.indent * self.model.depths[idfunc(obj)][0]
  467.         yy = rect.y + rect.height / 2 - 3
  468.         if hasattr(obj, 'expandable'):
  469.             if obj.expandable():
  470.                 []([ (x + rect.x + xoffset, y + yy) for x, y in tri ])
  471.             
  472.         elif hasChildren(obj):
  473.             []([ (x + rect.x + xoffset, y + yy) for x, y in tri ])
  474.         
  475.         icon = getattr(obj, 'icon', None)
  476.         x = rect.x + 20 + xoffset
  477.         if icon:
  478.             dc.DrawBitmap(icon, rect.x + 20, rect.y + (rect.Height / 2 - icon.GetHeight() / 2))
  479.             x += icon.GetWidth() + 10
  480.         
  481.         dc.DrawText(unicode(obj), x, rect.y + (rect.Height / 2 - GetFontHeight(font, dc) / 2))
  482.  
  483.     
  484.     def OnMeasureItem(self, n):
  485.         renderer = self.renderer_for_index(n)
  486.         if renderer:
  487.             return renderer.item_height(self.model[n])
  488.         return getattr(self.model[n], 'ItemHeight', 20)
  489.  
  490.     
  491.     def OnDrawBackground(self, dc, rect, n, selected = None):
  492.         obj = self.model[n]
  493.         selected = None if selected is None else selected
  494.         renderer = self.renderer_for_index(n)
  495.         
  496.         try:
  497.             drawbg = renderer.draw_background
  498.         except AttributeError:
  499.             
  500.             try:
  501.                 return obj.OnDrawBackground(dc, rect, n, selected)
  502.             except AttributeError:
  503.                 return TreeListBase.OnDrawBackground(self, dc, rect, n)
  504.             
  505.  
  506.             None<EXCEPTION MATCH>AttributeError
  507.  
  508.         drawbg(obj, dc, rect, n, selected, self.Hover == n)
  509.  
  510.     
  511.     def OnDrawItem(self, dc, rect, n):
  512.         model = self.model
  513.         obj = model[n]
  514.         selected = self.IsSelected(n)
  515.         
  516.         try:
  517.             depthVal = model.depths[idfunc(obj)][0]
  518.         except KeyError:
  519.             log.warning('KeyError in TreeList.OnDrawItem: %r', obj)
  520.             return 1
  521.  
  522.         draw_args = dict(dc = dc, rect = rect, depth = depthVal, obj = obj, index = n, expanded = model.is_expanded(n), selected = selected, hover = self.Hover == n)
  523.         renderer = self.renderer_for_index(n)
  524.         if renderer:
  525.             renderer.Draw(**draw_args)
  526.         else:
  527.             self.default_draw(dc, rect, n)
  528.  
  529.     
  530.     def list_changed(self):
  531.         measure = self.OnMeasureItem
  532.         []([ measure(n) for n in xrange(len(self.model)) ])
  533.  
  534.     
  535.     def SetSelection(self, i, keepVisible = True):
  536.         TreeListBase.SetSelection(self, i, keepVisible)
  537.  
  538.     
  539.     def on_doubleclick(self, e):
  540.         if e:
  541.             e.Skip(True)
  542.         
  543.         i = self.GetSelection()
  544.         if i != -1:
  545.             self.toggle_expand(self.model[i])
  546.         
  547.  
  548.     
  549.     def on_right_down(self, e):
  550.         i = self.HitTest((e.GetX(), e.GetY()))
  551.         self.SetSelection(i)
  552.         e.Skip(True)
  553.  
  554.  
  555.