[z3-checkins] r14459 - in z3/zopejam/trunk/src/zopejam: .
icons/palette/16x16
hathawsh at codespeak.net
hathawsh at codespeak.net
Sun Jul 10 01:01:19 CEST 2005
Author: hathawsh
Date: Sun Jul 10 01:01:14 2005
New Revision: 14459
Added:
z3/zopejam/trunk/src/zopejam/icons/palette/16x16/sort_down.png (contents, props changed)
z3/zopejam/trunk/src/zopejam/icons/palette/16x16/sort_up.png (contents, props changed)
Modified:
z3/zopejam/trunk/src/zopejam/columns.py
z3/zopejam/trunk/src/zopejam/main.py
Log:
Sortable directives list
Modified: z3/zopejam/trunk/src/zopejam/columns.py
==============================================================================
--- z3/zopejam/trunk/src/zopejam/columns.py (original)
+++ z3/zopejam/trunk/src/zopejam/columns.py Sun Jul 10 01:01:14 2005
@@ -16,6 +16,7 @@
class Column:
label = ''
default_width = 100
+ indent = False
def setProject(self, project):
self.project = project
@@ -23,6 +24,9 @@
def getText(self, d):
return ''
+ def getSortKey(self, d):
+ return self.getText(d)
+
def resolve(self, d, name):
"""Tries to resolve a package name,
@@ -44,6 +48,7 @@
class SourceFile(Column):
label = 'Source File'
default_width = 350
+ indent = True
def getText(self, d):
cfg = d.element.config_file
@@ -57,10 +62,11 @@
text = '"%s"' % self.project.shortenPath(cfg.filename)
else:
text = '"%s"' % cfg.filename
- if d.element.depth:
- return ' ' * (d.element.depth) + text
- else:
- return text
+ return text
+
+ def getSortKey(self, d):
+ cfg = d.element.config_file
+ return (cfg.package_name, cfg.filename)
class DirectiveType(Column):
@@ -75,6 +81,12 @@
ns = ns[len(nzo_prefix):]
return '%s:%s' % (ns, localname)
+ def getSortKey(self, d):
+ ns, localname = d.element.name
+ if interfaces.IGenericNamespaceDirective.providedBy(d):
+ ns = '*'
+ return (ns, localname)
+
class NameOrId(Column):
label = 'Name / Id'
@@ -82,22 +94,23 @@
def getText(self, d):
data = d.element.data
- if interfaces.IIncludeDirective.providedBy(d):
- fn = data.get('files') or data.get('file') or 'configure.zcml'
- package = data.get('package') or '.'
- if package:
- abs_package, error = self.resolve(d, package)
- if error:
- abs_package = '??? %s' % package
- if abs_package:
- if fn == 'configure.zcml':
- label = abs_package
- else:
- label = '%s "%s"' % (abs_package, fn)
- else:
- label = '"%s"' % fn
- return label
-
+
+## if interfaces.IIncludeDirective.providedBy(d):
+## fn = data.get('files') or data.get('file') or 'configure.zcml'
+## package = data.get('package') or '.'
+## if package:
+## abs_package, error = self.resolve(d, package)
+## if error:
+## abs_package = '??? %s' % package
+## if abs_package:
+## if fn == 'configure.zcml':
+## label = abs_package
+## else:
+## label = '%s "%s"' % (abs_package, fn)
+## else:
+## label = '"%s"' % fn
+## return label
+
res = data.get('name')
if res is None:
res = data.get('id', '')
@@ -106,9 +119,9 @@
class FactoryClassOrObject(Column):
label = 'Factory / Class / Object'
- default_width = 210
+ default_width = 150
- def getText(self, d):
+ def getText(self, d, mark_inherited=True):
# Search for an object in the directive or any parent
src = d.element
while src is not None:
@@ -122,12 +135,15 @@
src = src.parent
if name:
text, error = self.resolve(d, name)
- if src is not d.element:
+ if mark_inherited and src is not d.element:
# inherited
text = '^ ' + text
return text
return ''
+ def getSortKey(self, d):
+ return self.getText(d, mark_inherited=False)
+
class File(Column):
label = 'File'
Added: z3/zopejam/trunk/src/zopejam/icons/palette/16x16/sort_down.png
==============================================================================
Binary file. No diff available.
Added: z3/zopejam/trunk/src/zopejam/icons/palette/16x16/sort_up.png
==============================================================================
Binary file. No diff available.
Modified: z3/zopejam/trunk/src/zopejam/main.py
==============================================================================
--- z3/zopejam/trunk/src/zopejam/main.py (original)
+++ z3/zopejam/trunk/src/zopejam/main.py Sun Jul 10 01:01:14 2005
@@ -13,6 +13,7 @@
import sys
import wx
from wx import xrc
+from wx.lib.mixins import listctrl
from zcmledit.project import Project
from zopejam import columns
@@ -231,7 +232,7 @@
menubar = self.frame.GetMenuBar()
addmenu = menubar.GetMenu(2)
for item in addmenu.GetMenuItems():
- addmenu.Destroy(item)
+ addmenu.DestroyItem(item)
if self.project is None:
return
@@ -399,21 +400,40 @@
return p
-class DirectiveList(wx.ListCtrl):
+class DirectiveList(wx.ListCtrl, listctrl.ListCtrlAutoWidthMixin,
+ listctrl.ColumnSorterMixin):
def __init__(self, gui, parent, id):
wx.ListCtrl.__init__(
self, parent, id, style=wx.LC_REPORT | wx.LC_VIRTUAL)
self.gui = gui
self.elements = []
+ self.indexes = [] # list of element indexes (shuffled by sorting)
+ self.focus = -1 # element index or -1
self.filter = Filter(gui, xrc.XRCCTRL(self.gui.frame, 'filter_panel'))
self.columns = columns.create_default_columns()
+ self.SetImageList(self.gui.small_palette_images, wx.IMAGE_LIST_SMALL)
+
+ listctrl.ListCtrlAutoWidthMixin.__init__(self)
+ self.initColumnSorter(len(self.columns))
for i, c in enumerate(self.columns):
self.InsertColumn(i, c.label, width=c.default_width)
+ self.SortListItems(0, 1)
+
+ self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.onFocusItem)
+
+ def onFocusItem(self, event):
+ item = event.GetIndex()
+ if item < 0:
+ self.focus = -1
+ else:
+ self.focus = self.indexes[item]
+
def populate(self):
+ self.itemDataMap = {}
for c in self.columns:
c.setProject(self.gui.project)
@@ -423,19 +443,106 @@
self.elements = []
files = []
+ # Order the elements by filename. The original order is not
+ # used directly for display order, but when two elements have
+ # the same sort key, sorting will fall back to the original
+ # order.
for cfg in self.gui.project.files.values():
- # sort by source file
files.append(((cfg.package_name or '', cfg.filename), cfg))
files.sort()
for sort_key, cfg in files:
if cfg.root is not None:
self.elements.extend(cfg.root.flattened())
self.SetItemCount(len(self.elements))
+ self._doResize()
+ try:
+ self.SortItems()
+ except:
+ self.SetItemCount(0)
+ raise
+ self.Refresh()
+
+ def OnGetItemText(self, item, col):
+ index = self.indexes[item]
+ d = self.elements[index].directive
+ col_obj = self.columns[col]
+ text = col_obj.getText(d)
+ if col == self._col and col_obj.indent and d.element.depth:
+ # indent when sorting on an indentable column
+ return ' ' * (d.element.depth) + text
+ else:
+ return text
+
+ def GetListCtrl(self):
+ return self
+
+ def GetSortImages(self):
+ return (self.gui.small_palette_images['sort_up'],
+ self.gui.small_palette_images['sort_down'])
+
+ def SortItems(self, sorter=None):
+ """A SortItem implementation that works with virtual lists.
+
+ The sorter is not used.
+
+ Based on code by Egor Zindy
+ http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/426407
+ """
+ # _col and _colSortFlag are defined in ColumnSorterMixin.
+ # col is the column which was clicked on and
+ # sf, the sort flag, is False for descending (Z->A)
+ # and True for ascending (A->Z).
+
+ col = self._col
+ sf = self._colSortFlag[col]
+
+ # create pairs [(element_sort_key, element_index)]
+ items = []
+ col_obj = self.columns[col]
+ for i, e in enumerate(self.elements):
+ sort_key = col_obj.getSortKey(e.directive)
+ items.append((sort_key, i))
+
+ # sort the pairs by value (first element), then by original
+ # order (second element). Multiple same values are okay,
+ # because the keys are unique.
+ items.sort()
+
+ # get the element index for each sorted item
+ k = [key for value, key in items]
- def OnGetItemText(self, item, column):
- d = self.elements[item].directive
- c = self.columns[column]
- return c.getText(d)
+ # False is descending (starting from last)
+ if sf == False:
+ k.reverse()
+
+ # store the element indexes as self.indexes.
+ self.indexes = k
+
+ # restore the focus to the element that had focus
+ if self.focus >= 0:
+ i = self.indexes.index(self.focus)
+ self.EnsureVisible(i)
+ # XXX need a way to change which item is focused (focus is
+ # independent of selection)
+
+ # redraw the list
+ self.Refresh()
+
+ def initColumnSorter(self, numColumns):
+ self._colSortFlag = [True] * numColumns
+ self._col = -1
+ self.Bind(wx.EVT_LIST_COL_CLICK, self.__OnColClick, self)
+
+ def __OnColClick(self, evt):
+ oldCol = self._col
+ self._col = col = evt.GetColumn()
+ # Toggle forward/reverse when clicking a column more than once,
+ # but not when switching columns
+ if col == oldCol:
+ self._colSortFlag[col] = not self._colSortFlag[col]
+ self.GetListCtrl().SortItems(self.GetColumnSorter())
+ self._ColumnSorterMixin__updateImages(oldCol)
+ evt.Skip()
class Filter:
More information about the z3-checkins
mailing list