home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- from __future__ import with_statement
- from __future__ import division
- KEEP_STATS = False
- app = None
- import wx
- from wx import WXK_LEFT, WXK_RIGHT, WXK_DOWN, WXK_UP, Rect
- from util import Delegate
- from logging import getLogger
- log = getLogger('treelist')
- info = log.info
- from gui.textutil import GetFontHeight, default_font
- from contextlib import contextmanager
-
- expanded_id = lambda obj: u'_'.join([
- type(obj).__name__,
- obj.name])
-
- idfunc = lambda obj: obj.__hash__()
-
- def hasChildren(obj):
-
- try:
- iter(obj)
- except:
- return False
-
- return True
-
-
- class ListMixin(object):
-
- def __init__(self, listAttrName):
- self._listAttrName = listAttrName
-
-
- def __len__(self):
- return len(self.__dict__[self._listAttrName])
-
-
- def __iter__(self):
- return self.__dict__[self._listAttrName].__iter__()
-
-
- def __getitem__(self, n):
- return self.__dict__[self._listAttrName][n]
-
-
-
- class TreeListModel(ListMixin):
-
- def __init__(self, root = None, collapsed = None):
- if not root:
- pass
- self.root = []
- self.collapsed = None if collapsed is not None else set()
- self.flattened_list = []
- self.listeners = []
- self.depths = { }
- self.filters = []
- self.donotexpand = []
- self._expandable_cache = { }
- self.update_list()
- self.expansion_state_changed = Delegate()
- ListMixin.__init__(self, 'flattened_list')
-
-
- def _expandable(self, eltype):
-
- try:
- return self._expandable_cache[eltype]
- except KeyError:
- for i in self.donotexpand:
- if issubclass(eltype, i):
- return self._expandable_cache.setdefault(eltype, False)
- continue
-
- return self._expandable_cache.setdefault(eltype, True)
-
-
-
- def expandable(self, el):
- return self._expandable(el.__class__)
-
-
- def flatten(self, root, collapsed, depths, depth = 0, filters = [], expanded_id = expanded_id):
- lst = [
- root]
- if hasChildren(root):
- for el in root:
- depths[idfunc(el)] = (depth, root)
- if expanded_id(el) not in collapsed and self.expandable(el):
- lst.extend(self.flatten(el, collapsed, depths, depth + 1, filters, expanded_id = expanded_id))
- continue
- lst.append(el)
-
-
- return lst
-
-
- def __repr__(self):
- return '<TreeListModel %r>' % self.flattened_list
-
-
- def expand(self, obj):
- i = expanded_id(obj)
- self.collapsed.discard(i)
- self.expansion_state_changed()
- self.update_list()
-
-
- def collapse(self, obj):
- self.collapsed.add(expanded_id(obj))
- self.expansion_state_changed()
- self.update_list()
-
-
- def toggle_expand(self, obj):
- if obj.__class__ not in self.donotexpand:
- if expanded_id(obj) not in self.collapsed:
- self.collapse(obj)
- elif hasChildren(obj):
- self.expand(obj)
-
-
-
-
- def is_expanded(self, n):
- return expanded_id(self.flattened_list[n]) not in self.collapsed
-
-
- def parent_of(self, child):
- return self.depths[idfunc(child)][1]
-
-
- def index_of(self, child):
-
- try:
- return None if idfunc(child) in self.indices else -1
- except:
- return -1
-
-
-
- def set_root(self, root):
- self.depths = { }
- self.root = root
- self.update_list()
-
-
- def update_list(self):
- self.flattened_list = self.flatten(self.root, self.collapsed, self.depths, filters = self.filters)[1:]
- self.indices = dict((lambda .0: for c, item in .0:
- (idfunc(item), c))(enumerate(self.flattened_list)))
- for l in self.listeners:
- l.list_changed()
-
-
-
- def remove_child(self, child):
- parent = self.depths[idfunc(child)][1]
- parent.remove(child)
- self.update_list()
-
-
- if KEEP_STATS:
- from time import clock
-
- from cgui import SkinVList as TreeListBase
-
- class TreeList(TreeListBase):
- if KEEP_STATS:
- stats = { }
-
-
- def __init__(self, parent, model, id = -1, style = wx.NO_BORDER | wx.FULL_REPAINT_ON_RESIZE, enable_hover = True):
- self.renderers = { }
- self.renderers_cache = { }
- self.context_menu_handlers = { }
- TreeListBase.__init__(self, parent, id, style)
- self.model = model
- model.listeners.append(self)
- measure = self.OnMeasureItem
- []([ measure(n) for n in xrange(len(self.model)) ])
- Bind = self.Bind
- Bind(wx.EVT_LISTBOX_DCLICK, self.on_doubleclick)
- Bind(wx.EVT_RIGHT_DOWN, self.on_right_down)
- Bind(wx.EVT_KEY_DOWN, self.on_key_down)
- self.hoveridx = -1
- self.indent = 10
-
-
- def on_leave_window(self, e):
- self.Hover = -1
- e.Skip(True)
-
-
- def on_motion(self, e):
- self.Hover = self.HitTest(e.Position)
- e.Skip(True)
-
-
- def toggle_expand(self, obj):
- i = self.GetSelection()
- model = self.model
- selected = self.model[i]
- do_select = False
- if i != -1:
-
- try:
- parent = self.GetParent(model[i])
- except KeyError:
- pass
-
- p = model.index_of(parent)
- if parent is obj and model.is_expanded(p):
- self.SetSelection(p)
- else:
- do_select = True
-
- self.model.toggle_expand(obj)
- if do_select:
- self.SetSelection(model.index_of(selected), keepVisible = False)
-
-
-
- def GetItemRect(self, item, include_children = True):
- if not include_children:
- return TreeListBase.GetItemRect(self, self.model.index_of(item))
-
- model = self.model
- modellen = len(self.model)
- measure = self.OnMeasureItem
- i = model.index_of(item)
- rect = Rect(0, self.GetItemY(i), self.ClientRect.width, measure(i))
- if include_children:
- i += 1
- while i < modellen and self.GetParent(model[i]) is item:
- rect.height += measure(i)
- i += 1
- continue
- rect
-
- return rect
-
-
- def get_hover(self):
- return self.hoveridx
-
-
- def set_hover(self, i):
- old = self.hoveridx
- self.hoveridx = i
- if i != old:
- if old != -1:
- self.RefreshLine(old)
-
- if i != -1:
- self.RefreshLine(i)
-
-
-
- Hover = property(get_hover, set_hover)
-
- def GetSelectedItem(self):
- i = self.GetSelection()
- if i != -1:
- return self.model[i]
-
-
- SelectedItem = property(GetSelectedItem)
-
- def __getitem__(self, i):
- return self.model[i]
-
-
- def GetParent(self, obj):
- return self.model.parent_of(obj)
-
-
- def save_selection(self):
- i = self.GetSelection()
- elem = None
- model = self.model
- if i != -1:
-
- try:
- elem = model[i]
- except IndexError:
- elem = None
- except:
- None<EXCEPTION MATCH>IndexError
-
-
- None<EXCEPTION MATCH>IndexError
-
- try:
- yield None
- finally:
- if elem is not None:
- TreeList.SetSelection(self, model.index_of(elem), False)
-
-
-
- save_selection = contextmanager(save_selection)
-
- def set_root(self, root):
- self.save_selection().__enter__()
-
- try:
- self.renderers_cache = { }
- self.model.set_root(root)
- finally:
- pass
-
-
-
- def on_key_down(self, e):
- i = self.GetSelection()
- model = self.model
- keycode = e.KeyCode
- modifiers = e.Modifiers
-
- try:
- obj = self.model[i]
- except IndexError:
- obj = None
-
- if keycode == WXK_LEFT:
- if modifiers == wx.MOD_SHIFT:
- self.collapse_all()
- elif obj is not None and modifiers == wx.MOD_NONE:
- if model.expandable(obj) and model.is_expanded(i):
- self.toggle_expand(obj)
- else:
- self.select_parent(obj)
-
- elif keycode == WXK_RIGHT:
- if modifiers == wx.MOD_SHIFT:
- self.expand_all()
- elif obj is not None and modifiers == wx.MOD_NONE:
- if model.expandable(obj):
- if not model.is_expanded(i):
- self.toggle_expand(obj)
- elif i + 1 < self.GetItemCount() and self.GetParent(model[i + 1]) is obj:
- self.SetSelection(self.GetSelection() + 1)
-
-
-
- elif keycode == WXK_UP:
- sel = self.GetSelection() - 1
- if sel >= 0:
- self.SetSelection(sel)
-
- return e.Skip(False)
- elif keycode == WXK_DOWN:
- sel = self.GetSelection() + 1
- if sel < self.GetItemCount():
- self.SetSelection(sel)
-
- return e.Skip(False)
- elif keycode == wx.WXK_PAGEUP:
- self.PageUp()
- self.SetSelection(self.GetFirstVisibleLine())
- elif keycode == wx.WXK_PAGEDOWN:
- self.PageDown()
- self.SetSelection(self.GetFirstVisibleLine())
-
- e.Skip(True)
-
-
- def select_parent(self, obj):
- parent = self.GetParent(obj)
- if parent is not None:
- i = self.model.index_of(parent)
- if i != -1:
- self.SetSelection(i)
-
-
-
-
- def renderer_for(self, obj):
-
- try:
- k = obj._renderer
- except AttributeError:
-
- try:
- k = obj.__class__.__name__
- except AttributeError:
- k = None
- except:
- None<EXCEPTION MATCH>AttributeError
-
-
- None<EXCEPTION MATCH>AttributeError
-
- return self.renderers.get(k, None)
-
-
- def renderer_for_index(self, n):
-
- try:
- renderer = self.renderers_cache[n]
- except KeyError:
- renderer = self.renderers_cache[n] = self.renderer_for(self.model[n])
-
- return renderer
-
- if KEEP_STATS:
-
- def print_stats(cls):
- avgs = [ (float(total) / float(n), r) for n, total in cls.stats.iteritems() ]
- print 'avg time renderer'
- print '--------------------------'
- for avg, r in sorted(avgs, reverse = True):
- print '%.8f' % avg, r
-
-
- print_stats = classmethod(print_stats)
- else:
-
- def print_stats(cls):
- print 'set treelist.KEEP_STATS = True to keep renderer timings'
-
- print_stats = classmethod(print_stats)
-
- hit_test_ex = lambda self, pt, h = TreeListBase.HitTestEx: h(self, *pt)
- collapsedTri = [
- (0, 0),
- (7, 3),
- (0, 7)]
- expandedTri = [
- (0, 0),
- (7, 0),
- (3, 3)]
-
- def hit_test_parent(self, mouse_pos):
- model = self.model
- (i, unused_percent) = self.hit_test_ex(mouse_pos)
- if i == -1:
- return (-1, None)
-
- parent = model.parent_of(model[i])
- j = model.index_of(parent)
- if j != -1:
- rect = self.GetItemRect(parent)
- i = j
- else:
- rect = self.GetItemRect(model[i])
- percent = (mouse_pos.y - rect.y) / rect.height
- return (i, percent)
-
-
- def default_draw(self, dc, rect, n):
- if self.IsSelected(n):
- fg = wx.SYS_COLOUR_HIGHLIGHTTEXT
- else:
- fg = wx.SYS_COLOUR_WINDOWTEXT
- dc.SetTextForeground(wx.SystemSettings_GetColour(fg))
- font = default_font()
- dc.SetFont(font)
- if self.model.is_expanded(n):
- tri = self.expandedTri
- else:
- tri = self.collapsedTri
- dc.SetPen(wx.BLACK_PEN)
- dc.SetBrush(wx.BLACK_BRUSH)
- obj = self.model[n]
- xoffset = self.indent * self.model.depths[idfunc(obj)][0]
- yy = rect.y + rect.height / 2 - 3
- if hasattr(obj, 'expandable'):
- if obj.expandable():
- []([ (x + rect.x + xoffset, y + yy) for x, y in tri ])
-
- elif hasChildren(obj):
- []([ (x + rect.x + xoffset, y + yy) for x, y in tri ])
-
- icon = getattr(obj, 'icon', None)
- x = rect.x + 20 + xoffset
- if icon:
- dc.DrawBitmap(icon, rect.x + 20, rect.y + (rect.Height / 2 - icon.GetHeight() / 2))
- x += icon.GetWidth() + 10
-
- dc.DrawText(unicode(obj), x, rect.y + (rect.Height / 2 - GetFontHeight(font, dc) / 2))
-
-
- def OnMeasureItem(self, n):
- renderer = self.renderer_for_index(n)
- if renderer:
- return renderer.item_height(self.model[n])
- else:
- return getattr(self.model[n], 'ItemHeight', 20)
-
-
- def OnDrawBackground(self, dc, rect, n, selected = None):
- obj = self.model[n]
- selected = None if selected is None else selected
- renderer = self.renderer_for_index(n)
-
- try:
- drawbg = renderer.draw_background
- except AttributeError:
-
- try:
- return obj.OnDrawBackground(dc, rect, n, selected)
- except AttributeError:
- return TreeListBase.OnDrawBackground(self, dc, rect, n)
- except:
- None<EXCEPTION MATCH>AttributeError
-
-
- None<EXCEPTION MATCH>AttributeError
-
- drawbg(obj, dc, rect, n, selected, self.Hover == n)
-
-
- def OnDrawItem(self, dc, rect, n):
- model = self.model
- obj = model[n]
- selected = self.IsSelected(n)
-
- try:
- depthVal = model.depths[idfunc(obj)][0]
- except KeyError:
- log.warning('KeyError in TreeList.OnDrawItem: %r', obj)
- return 1
-
- draw_args = dict(dc = dc, rect = rect, depth = depthVal, obj = obj, index = n, expanded = model.is_expanded(n), selected = selected, hover = self.Hover == n)
- renderer = self.renderer_for_index(n)
- if renderer:
- if KEEP_STATS:
- start = clock()
- renderer.Draw(**draw_args)
- diff = clock() - start
- (n, tot) = self.stats.get(k, (0, 0))
- self.stats[k] = (n + 1, tot + diff)
- else:
- renderer.Draw(**draw_args)
- else:
- self.default_draw(dc, rect, n)
-
-
- def list_changed(self):
- measure = self.OnMeasureItem
- []([ measure(n) for n in xrange(len(self.model)) ])
-
-
- def on_doubleclick(self, e):
- if e:
- e.Skip(True)
-
- i = self.GetSelection()
- if i != -1:
- self.toggle_expand(self.model[i])
-
-
-
- def on_right_down(self, e):
- i = self.HitTest((e.GetX(), e.GetY()))
- self.SetSelection(i)
- e.Skip(True)
-
-
-