Update to 0.9 of TreeMixin.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@45065 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -104,9 +104,9 @@ class DemoTreeMixin(treemixin.VirtualTree, treemixin.DragAndDrop,
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def OnDrop(self, dropTarget, dragItem):
|
def OnDrop(self, dropTarget, dragItem):
|
||||||
dropIndex = self.ItemIndex(dropTarget)
|
dropIndex = self.GetIndoxOfItem(dropTarget)
|
||||||
dropText = self.model.GetText(dropIndex)
|
dropText = self.model.GetText(dropIndex)
|
||||||
dragIndex = self.ItemIndex(dragItem)
|
dragIndex = self.GetIndexOfItem(dragItem)
|
||||||
dragText = self.model.GetText(dragIndex)
|
dragText = self.model.GetText(dragIndex)
|
||||||
self.log.write('drop %s %s on %s %s'%(dragText, dragIndex,
|
self.log.write('drop %s %s on %s %s'%(dragText, dragIndex,
|
||||||
dropText, dropIndex))
|
dropText, dropIndex))
|
||||||
@@ -168,7 +168,7 @@ class VirtualCustomTreeCtrl(DemoTreeMixin,
|
|||||||
|
|
||||||
def OnItemChecked(self, event):
|
def OnItemChecked(self, event):
|
||||||
item = event.GetItem()
|
item = event.GetItem()
|
||||||
itemIndex = self.ItemIndex(item)
|
itemIndex = self.GetIndexOfItem(item)
|
||||||
if self.GetItemType(item) == 2:
|
if self.GetItemType(item) == 2:
|
||||||
# It's a radio item; reset other items on the same level
|
# It's a radio item; reset other items on the same level
|
||||||
for nr in range(self.GetChildrenCount(self.GetItemParent(item))):
|
for nr in range(self.GetChildrenCount(self.GetItemParent(item))):
|
||||||
@@ -201,7 +201,7 @@ class TreeNotebook(wx.Notebook):
|
|||||||
def GetIndicesOfSelectedItems(self):
|
def GetIndicesOfSelectedItems(self):
|
||||||
tree = self.trees[self.GetSelection()]
|
tree = self.trees[self.GetSelection()]
|
||||||
if tree.GetSelections():
|
if tree.GetSelections():
|
||||||
return [tree.ItemIndex(item) for item in tree.GetSelections()]
|
return [tree.GetIndexOfItem(item) for item in tree.GetSelections()]
|
||||||
else:
|
else:
|
||||||
return [()]
|
return [()]
|
||||||
|
|
||||||
|
@@ -1,10 +1,21 @@
|
|||||||
Recent Changes for wxPython
|
Recent Changes for wxPython
|
||||||
=====================================================================
|
=====================================================================
|
||||||
|
|
||||||
2.8.3.0
|
2.8.3.1
|
||||||
-------
|
-------
|
||||||
*
|
*
|
||||||
|
|
||||||
|
wxGTK: Make wx.NO_BORDER style work with wx.RadioBox (patch 1525406)
|
||||||
|
|
||||||
|
Update to 0.9 of TreeMixin.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2.8.3.0
|
||||||
|
-------
|
||||||
|
* 22-March-2007
|
||||||
|
|
||||||
Added wx.ToolBar.SetToolNormalBitmap and SetToolDisabledBitmap
|
Added wx.ToolBar.SetToolNormalBitmap and SetToolDisabledBitmap
|
||||||
methods. (Keep in mind however that the disabled bitmap is currently
|
methods. (Keep in mind however that the disabled bitmap is currently
|
||||||
generated on the fly by most native toolbar widgets, so this
|
generated on the fly by most native toolbar widgets, so this
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import wx, wx.gizmos, wx.lib.customtreectrl, unittest, treemixin
|
import wx, wx.gizmos, wx.lib.customtreectrl, unittest
|
||||||
|
from wx.lib.mixins import treemixin
|
||||||
|
|
||||||
|
|
||||||
# VirtualTree tests
|
# VirtualTree tests
|
||||||
@@ -51,13 +52,9 @@ class TreeCtrl(object):
|
|||||||
self.checked[index] = checked
|
self.checked[index] = checked
|
||||||
|
|
||||||
|
|
||||||
class VirtualTreeCtrlWithTreeIndices(TreeCtrl, treemixin.VirtualTree,
|
class VirtualTreeCtrl(TreeCtrl, treemixin.VirtualTree,
|
||||||
wx.lib.customtreectrl.CustomTreeCtrl):
|
wx.lib.customtreectrl.CustomTreeCtrl):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
kwargs['tupleIndex'] = True
|
|
||||||
super(VirtualTreeCtrlWithTreeIndices, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def OnGetItemText(self, indices):
|
def OnGetItemText(self, indices):
|
||||||
return 'item %s'%'.'.join([str(index) for index in indices])
|
return 'item %s'%'.'.join([str(index) for index in indices])
|
||||||
|
|
||||||
@@ -69,27 +66,11 @@ class VirtualTreeCtrlWithTreeIndices(TreeCtrl, treemixin.VirtualTree,
|
|||||||
self.children[index] = childrenCount
|
self.children[index] = childrenCount
|
||||||
|
|
||||||
|
|
||||||
class VirtualTreeCtrlWithListIndices(TreeCtrl, treemixin.VirtualTree,
|
|
||||||
wx.lib.customtreectrl.CustomTreeCtrl):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
class VirtualTreeCtrlTest_NoRootItems(unittest.TestCase):
|
||||||
kwargs['tupleIndex'] = False
|
|
||||||
super(VirtualTreeCtrlWithListIndices, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def OnGetItemText(self, index):
|
|
||||||
return 'item %d'%index
|
|
||||||
|
|
||||||
def OnGetChildrenIndices(self, index=None):
|
|
||||||
return self.children.get(index, [])
|
|
||||||
|
|
||||||
def PrepareChildrenIndices(self, index, indices):
|
|
||||||
self.children[index] = indices
|
|
||||||
|
|
||||||
|
|
||||||
class VirtualTreeCtrlTestWithTreeIndices_NoRootItems(unittest.TestCase):
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.frame = wx.Frame(None)
|
self.frame = wx.Frame(None)
|
||||||
self.tree = VirtualTreeCtrlWithTreeIndices(self.frame)
|
self.tree = VirtualTreeCtrl(self.frame)
|
||||||
self.tree.RefreshItems()
|
self.tree.RefreshItems()
|
||||||
|
|
||||||
def testNoRootItems(self):
|
def testNoRootItems(self):
|
||||||
@@ -115,39 +96,11 @@ class VirtualTreeCtrlTestWithTreeIndices_NoRootItems(unittest.TestCase):
|
|||||||
self.assertEqual(3, self.tree.GetCount())
|
self.assertEqual(3, self.tree.GetCount())
|
||||||
|
|
||||||
|
|
||||||
class VirtualTreeCtrlWithListIndicesTest_NoRootItems(unittest.TestCase):
|
|
||||||
|
class VirtualTreeCtrlTest_OneRoot(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.frame = wx.Frame(None)
|
self.frame = wx.Frame(None)
|
||||||
self.tree = VirtualTreeCtrlWithListIndices(self.frame)
|
self.tree = VirtualTreeCtrl(self.frame)
|
||||||
self.tree.RefreshItems()
|
|
||||||
|
|
||||||
def testNoRootItems(self):
|
|
||||||
self.assertEqual(0, self.tree.GetCount())
|
|
||||||
|
|
||||||
def testAddTwoRootItems(self):
|
|
||||||
self.tree.PrepareChildrenIndices(None, [0,1])
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
self.assertEqual(2, self.tree.GetCount())
|
|
||||||
|
|
||||||
def testAddOneRootItemAndOneChild(self):
|
|
||||||
self.tree.PrepareChildrenIndices(None, [0])
|
|
||||||
self.tree.PrepareChildrenIndices(0, [1])
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
self.tree.ExpandAll()
|
|
||||||
self.assertEqual(2, self.tree.GetCount())
|
|
||||||
|
|
||||||
def testAddOneRootItemAndTwoChildren(self):
|
|
||||||
self.tree.PrepareChildrenIndices(None, [0])
|
|
||||||
self.tree.PrepareChildrenIndices(0, [1,2])
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
self.tree.ExpandAll()
|
|
||||||
self.assertEqual(3, self.tree.GetCount())
|
|
||||||
|
|
||||||
|
|
||||||
class VirtualTreeCtrlTestWithTreeIndices_OneRoot(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.frame = wx.Frame(None)
|
|
||||||
self.tree = VirtualTreeCtrlWithTreeIndices(self.frame)
|
|
||||||
self.tree.PrepareChildrenCount((), 1)
|
self.tree.PrepareChildrenCount((), 1)
|
||||||
self.tree.RefreshItems()
|
self.tree.RefreshItems()
|
||||||
|
|
||||||
@@ -202,65 +155,19 @@ class VirtualTreeCtrlTestWithTreeIndices_OneRoot(unittest.TestCase):
|
|||||||
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
||||||
self.failUnless(self.tree.IsItemChecked(item))
|
self.failUnless(self.tree.IsItemChecked(item))
|
||||||
|
|
||||||
|
def testChangeTypeAndAddChildren(self):
|
||||||
class VirtualTreeCtrlWithListIndicesTest_OneRoot(unittest.TestCase):
|
self.tree.PrepareType((0,), 1)
|
||||||
def setUp(self):
|
self.tree.PrepareChildrenCount((0,), 1)
|
||||||
self.frame = wx.Frame(None)
|
|
||||||
self.tree = VirtualTreeCtrlWithListIndices(self.frame)
|
|
||||||
self.tree.PrepareChildrenIndices(None, [0])
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
|
|
||||||
def testOneRoot(self):
|
|
||||||
self.assertEqual(1, self.tree.GetCount())
|
|
||||||
|
|
||||||
def testDeleteRootItem(self):
|
|
||||||
self.tree.PrepareChildrenIndices(None, [])
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
self.assertEqual(0, self.tree.GetCount())
|
|
||||||
|
|
||||||
def testAddOneChild(self):
|
|
||||||
self.tree.PrepareChildrenIndices(0, [1])
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
self.tree.ExpandAll()
|
|
||||||
self.assertEqual(2, self.tree.GetCount())
|
|
||||||
|
|
||||||
def testAddTwoChildren(self):
|
|
||||||
self.tree.PrepareChildrenIndices(0, [1,2])
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
self.tree.ExpandAll()
|
|
||||||
self.assertEqual(3, self.tree.GetCount())
|
|
||||||
|
|
||||||
def testChangeFont(self):
|
|
||||||
self.tree.PrepareItemFont(0, wx.SMALL_FONT)
|
|
||||||
self.tree.RefreshItems()
|
self.tree.RefreshItems()
|
||||||
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
||||||
self.assertEqual(wx.SMALL_FONT, self.tree.GetItemFont(item))
|
self.failUnless(self.tree.ItemHasChildren(item))
|
||||||
|
|
||||||
def testChangeColour(self):
|
def testRefreshItem(self):
|
||||||
self.tree.PrepareItemColour(0, wx.RED)
|
self.tree.PrepareItemColour((0,), wx.RED)
|
||||||
self.tree.RefreshItems()
|
self.tree.RefreshItem((0,))
|
||||||
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
||||||
self.assertEqual(wx.RED, self.tree.GetItemTextColour(item))
|
self.assertEqual(wx.RED, self.tree.GetItemTextColour(item))
|
||||||
|
|
||||||
def testChangeBackgroundColour(self):
|
|
||||||
self.tree.PrepareItemBackgroundColour(0, wx.RED)
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
|
||||||
self.assertEqual(wx.RED, self.tree.GetItemBackgroundColour(item))
|
|
||||||
|
|
||||||
def testChangeImage(self):
|
|
||||||
self.tree.PrepareImage(0, 0)
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
|
||||||
self.assertEqual(0, self.tree.GetItemImage(item))
|
|
||||||
|
|
||||||
def testChangeType(self):
|
|
||||||
self.tree.PrepareType(0, 2)
|
|
||||||
self.tree.PrepareChecked(0, True)
|
|
||||||
self.tree.RefreshItems()
|
|
||||||
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
|
|
||||||
self.failUnless(self.tree.IsItemChecked(item))
|
|
||||||
|
|
||||||
|
|
||||||
# TreeAPIHarmonizer tests
|
# TreeAPIHarmonizer tests
|
||||||
|
|
||||||
@@ -272,6 +179,7 @@ class TreeAPIHarmonizerTestCase(unittest.TestCase):
|
|||||||
class HarmonizedTreeCtrl(treemixin.TreeAPIHarmonizer, self.TreeClass):
|
class HarmonizedTreeCtrl(treemixin.TreeAPIHarmonizer, self.TreeClass):
|
||||||
pass
|
pass
|
||||||
self.tree = HarmonizedTreeCtrl(self.frame, style=self.style)
|
self.tree = HarmonizedTreeCtrl(self.frame, style=self.style)
|
||||||
|
self.eventsReceived = []
|
||||||
self.populateTree()
|
self.populateTree()
|
||||||
|
|
||||||
def populateTree(self):
|
def populateTree(self):
|
||||||
@@ -279,6 +187,9 @@ class TreeAPIHarmonizerTestCase(unittest.TestCase):
|
|||||||
self.item = self.tree.AppendItem(self.root, 'Item')
|
self.item = self.tree.AppendItem(self.root, 'Item')
|
||||||
self.items = [self.root, self.item]
|
self.items = [self.root, self.item]
|
||||||
|
|
||||||
|
def onEvent(self, event):
|
||||||
|
self.eventsReceived.append(event)
|
||||||
|
|
||||||
|
|
||||||
class TreeAPIHarmonizerCommonTests(object):
|
class TreeAPIHarmonizerCommonTests(object):
|
||||||
''' Tests that should succeed for all tree controls and all styles. '''
|
''' Tests that should succeed for all tree controls and all styles. '''
|
||||||
@@ -318,6 +229,14 @@ class TreeAPIHarmonizerCommonTests(object):
|
|||||||
self.assertEqual(-1,
|
self.assertEqual(-1,
|
||||||
self.tree.GetItemImage(self.item, wx.TreeItemIcon_Selected, 1))
|
self.tree.GetItemImage(self.item, wx.TreeItemIcon_Selected, 1))
|
||||||
|
|
||||||
|
def testExpandAll(self):
|
||||||
|
self.tree.ExpandAll()
|
||||||
|
|
||||||
|
def testExpandAllChildren(self):
|
||||||
|
self.tree.AppendItem(self.item, 'child')
|
||||||
|
self.tree.ExpandAllChildren(self.item)
|
||||||
|
self.failUnless(self.tree.IsExpanded(self.item))
|
||||||
|
|
||||||
|
|
||||||
class TreeAPIHarmonizerNoTreeListCtrlCommonTests(object):
|
class TreeAPIHarmonizerNoTreeListCtrlCommonTests(object):
|
||||||
''' Tests that should succeed for all tree controls, except the
|
''' Tests that should succeed for all tree controls, except the
|
||||||
@@ -378,7 +297,6 @@ class TreeAPIHarmonizerMultipleSelectionTests(object):
|
|||||||
self.assertEqual([self.item, item2], self.tree.GetSelections())
|
self.assertEqual([self.item, item2], self.tree.GetSelections())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TreeAPIHarmonizerVisibleRootTests(object):
|
class TreeAPIHarmonizerVisibleRootTests(object):
|
||||||
''' Tests that should succeed for all tree controls when the root item
|
''' Tests that should succeed for all tree controls when the root item
|
||||||
is not hidden. '''
|
is not hidden. '''
|
||||||
@@ -405,7 +323,6 @@ class TreeAPIHarmonizerHiddenRootTests(object):
|
|||||||
self.assertEqual([], self.tree.GetSelections())
|
self.assertEqual([], self.tree.GetSelections())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TreeAPIHarmonizerWithTreeCtrlTestCase(TreeAPIHarmonizerTestCase):
|
class TreeAPIHarmonizerWithTreeCtrlTestCase(TreeAPIHarmonizerTestCase):
|
||||||
TreeClass = wx.TreeCtrl
|
TreeClass = wx.TreeCtrl
|
||||||
|
|
||||||
@@ -564,63 +481,64 @@ class TreeHelperTestCase(unittest.TestCase):
|
|||||||
self.child = self.tree.AppendItem(self.item, 'Child')
|
self.child = self.tree.AppendItem(self.item, 'Child')
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperVisibleRootTests(object):
|
class TreeHelperCommonTests(object):
|
||||||
def testIntegerIndexRootItem(self):
|
def testGetItemChildren_EmptyTree(self):
|
||||||
self.assertEqual(0, self.tree.ItemIndex(self.root, tupleIndex=False))
|
self.tree.DeleteAllItems()
|
||||||
|
self.assertEqual([], self.tree.GetItemChildren())
|
||||||
|
|
||||||
def testIntegerIndexRegularItem(self):
|
def testGetItemChildren_NoParent(self):
|
||||||
self.assertEqual(1, self.tree.ItemIndex(self.item, tupleIndex=False))
|
self.assertEqual([self.item], self.tree.GetItemChildren())
|
||||||
|
|
||||||
def testIntegerIndexChild(self):
|
def testGetItemChildren_RootItem(self):
|
||||||
self.assertEqual(2, self.tree.ItemIndex(self.child, tupleIndex=False))
|
self.assertEqual([self.item], self.tree.GetItemChildren(self.root))
|
||||||
|
|
||||||
def testTupleIndexRootItem(self):
|
def testGetItemChildren_RegularItem(self):
|
||||||
self.assertEqual((), self.tree.ItemIndex(self.root))
|
self.assertEqual([self.child], self.tree.GetItemChildren(self.item))
|
||||||
|
|
||||||
def testTupleIndexRegularItem(self):
|
def testGetItemChildren_ItemWithoutChildren(self):
|
||||||
self.assertEqual((0,), self.tree.ItemIndex(self.item))
|
self.assertEqual([], self.tree.GetItemChildren(self.child))
|
||||||
|
|
||||||
def testTupleIndexChild(self):
|
def testGetItemChildren_NoParent_Recursively(self):
|
||||||
self.assertEqual((0,0), self.tree.ItemIndex(self.child))
|
self.assertEqual([self.item, self.child],
|
||||||
|
self.tree.GetItemChildren(recursively=True))
|
||||||
|
|
||||||
|
def testGetItemChildren_RootItem_Recursively(self):
|
||||||
|
self.assertEqual([self.item, self.child],
|
||||||
|
self.tree.GetItemChildren(self.root, True))
|
||||||
|
|
||||||
|
def testGetItemChildren_RegularItem_Recursively(self):
|
||||||
|
self.assertEqual([self.child],
|
||||||
|
self.tree.GetItemChildren(self.item, True))
|
||||||
|
|
||||||
|
def testGetItemChildren_ItemWithoutChildren_Recursively(self):
|
||||||
|
self.assertEqual([], self.tree.GetItemChildren(self.child, True))
|
||||||
|
|
||||||
|
def testGetItemByIndex_RootItem(self):
|
||||||
|
self.assertEqual(self.root, self.tree.GetItemByIndex(()))
|
||||||
|
|
||||||
|
def testGetItemByIndex_RegularItem(self):
|
||||||
|
self.assertEqual(self.item, self.tree.GetItemByIndex((0,)))
|
||||||
|
|
||||||
|
def testGetItemByIndex_Child(self):
|
||||||
|
self.assertEqual(self.child, self.tree.GetItemByIndex((0,0)))
|
||||||
|
|
||||||
|
def testGetIndexOfItemRootItem(self):
|
||||||
|
self.assertEqual((), self.tree.GetIndexOfItem(self.root))
|
||||||
|
|
||||||
|
def testGetIndexOfItemRegularItem(self):
|
||||||
|
self.assertEqual((0,), self.tree.GetIndexOfItem(self.item))
|
||||||
|
|
||||||
|
def testGetIndexOfItemChild(self):
|
||||||
|
self.assertEqual((0,0), self.tree.GetIndexOfItem(self.child))
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperHiddenRootTests(object):
|
class TreeHelperWithTreeCtrlTestCase(TreeHelperCommonTests,
|
||||||
style = wx.TR_HIDE_ROOT
|
TreeHelperTestCase):
|
||||||
|
|
||||||
def testIntegerIndexRootItem(self):
|
|
||||||
self.assertEqual(None, self.tree.ItemIndex(self.root, tupleIndex=False))
|
|
||||||
|
|
||||||
def testIntegerIndexRegularItem(self):
|
|
||||||
self.assertEqual(0, self.tree.ItemIndex(self.item, tupleIndex=False))
|
|
||||||
|
|
||||||
def testIntegerIndexChild(self):
|
|
||||||
self.assertEqual(1, self.tree.ItemIndex(self.child, tupleIndex=False))
|
|
||||||
|
|
||||||
def testTupleIndexRootItem(self):
|
|
||||||
self.assertEqual((), self.tree.ItemIndex(self.root))
|
|
||||||
|
|
||||||
def testTupleIndexRegularItem(self):
|
|
||||||
self.assertEqual((0,), self.tree.ItemIndex(self.item))
|
|
||||||
|
|
||||||
def testTupleIndexChild(self):
|
|
||||||
self.assertEqual((0,0), self.tree.ItemIndex(self.child))
|
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithTreeCtrlTestCase(TreeHelperTestCase):
|
|
||||||
TreeClass = wx.TreeCtrl
|
TreeClass = wx.TreeCtrl
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithTreeCtrl_VisibleRoot(TreeHelperVisibleRootTests,
|
class TreeHelperWithTreeListCtrlTestCase(TreeHelperCommonTests,
|
||||||
TreeHelperWithTreeCtrlTestCase):
|
TreeHelperTestCase):
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithTreeCtrl_HiddenRoot(TreeHelperHiddenRootTests,
|
|
||||||
TreeHelperWithTreeCtrlTestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithTreeListCtrlTestCase(TreeHelperTestCase):
|
|
||||||
TreeClass = wx.gizmos.TreeListCtrl
|
TreeClass = wx.gizmos.TreeListCtrl
|
||||||
|
|
||||||
def populateTree(self):
|
def populateTree(self):
|
||||||
@@ -628,29 +546,11 @@ class TreeHelperWithTreeListCtrlTestCase(TreeHelperTestCase):
|
|||||||
super(TreeHelperWithTreeListCtrlTestCase, self).populateTree()
|
super(TreeHelperWithTreeListCtrlTestCase, self).populateTree()
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithTreeListCtrl_VisibleRoot(TreeHelperVisibleRootTests,
|
class TreeHelperWithCustomTreeCtrlTestCase(TreeHelperCommonTests,
|
||||||
TreeHelperWithTreeListCtrlTestCase):
|
TreeHelperTestCase):
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithTreeListCtrl_HiddenRoot(TreeHelperHiddenRootTests,
|
|
||||||
TreeHelperWithTreeListCtrlTestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class TreeHelperWithCustomTreeCtrlTestCase(TreeHelperTestCase):
|
|
||||||
TreeClass = wx.lib.customtreectrl.CustomTreeCtrl
|
TreeClass = wx.lib.customtreectrl.CustomTreeCtrl
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithCustomTreeCtrl_VisibleRoot(TreeHelperVisibleRootTests,
|
|
||||||
TreeHelperWithCustomTreeCtrlTestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TreeHelperWithCustomTreeCtrl_HiddenRoot(TreeHelperHiddenRootTests,
|
|
||||||
TreeHelperWithCustomTreeCtrlTestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# ExpansionState tests
|
# ExpansionState tests
|
||||||
|
|
||||||
class ExpansionStateTreeCtrl(treemixin.ExpansionState, wx.TreeCtrl):
|
class ExpansionStateTreeCtrl(treemixin.ExpansionState, wx.TreeCtrl):
|
||||||
@@ -769,6 +669,58 @@ class SetExpansionStateTestCase(unittest.TestCase):
|
|||||||
self.failUnless(self.tree.IsExpanded(grandChild))
|
self.failUnless(self.tree.IsExpanded(grandChild))
|
||||||
|
|
||||||
|
|
||||||
|
# Tests of the tree controls without any mixin, to document behaviour that
|
||||||
|
# already works, and works the same, for all tree control widgets
|
||||||
|
|
||||||
|
class VanillaTreeTestCase(unittest.TestCase):
|
||||||
|
style = wx.TR_DEFAULT_STYLE
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.frame = wx.Frame(None)
|
||||||
|
self.tree = self.TreeClass(self.frame, style=self.style)
|
||||||
|
self.eventsReceived = []
|
||||||
|
self.populateTree()
|
||||||
|
|
||||||
|
def populateTree(self):
|
||||||
|
self.root = self.tree.AddRoot('Root')
|
||||||
|
self.item = self.tree.AppendItem(self.root, 'Item')
|
||||||
|
self.items = [self.root, self.item]
|
||||||
|
|
||||||
|
def onEvent(self, event):
|
||||||
|
self.eventsReceived.append(event)
|
||||||
|
|
||||||
|
|
||||||
|
class VanillaTreeCommonTests(object):
|
||||||
|
''' Tests that should succeed for all tree controls and all styles. '''
|
||||||
|
|
||||||
|
def testSetItemHasChildren(self):
|
||||||
|
self.tree.SetItemHasChildren(self.item, True)
|
||||||
|
self.failUnless(self.tree.ItemHasChildren(self.item))
|
||||||
|
|
||||||
|
def testExpandItemWithPlus(self):
|
||||||
|
self.tree.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.onEvent)
|
||||||
|
self.tree.SetItemHasChildren(self.item, True)
|
||||||
|
self.tree.Expand(self.item)
|
||||||
|
self.assertEqual(1, len(self.eventsReceived))
|
||||||
|
|
||||||
|
|
||||||
|
class VanillaTreeCtrlTestCase(VanillaTreeCommonTests, VanillaTreeTestCase):
|
||||||
|
TreeClass = wx.TreeCtrl
|
||||||
|
|
||||||
|
|
||||||
|
class VanillaTreeListCtrlTestCase(VanillaTreeCommonTests, VanillaTreeTestCase):
|
||||||
|
TreeClass = wx.gizmos.TreeListCtrl
|
||||||
|
|
||||||
|
def populateTree(self):
|
||||||
|
self.tree.AddColumn('Column 0')
|
||||||
|
super(VanillaTreeListCtrlTestCase, self).populateTree()
|
||||||
|
|
||||||
|
|
||||||
|
class VanillaCustomTreeCtrlTestCase(VanillaTreeCommonTests,
|
||||||
|
VanillaTreeTestCase):
|
||||||
|
TreeClass = wx.lib.customtreectrl.CustomTreeCtrl
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = wx.App(False)
|
app = wx.App(False)
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@@ -25,8 +25,8 @@ The VirtualTree and DragAndDrop mixins force the wx.TR_HIDE_ROOT style.
|
|||||||
|
|
||||||
Author: Frank Niessink <frank@niessink.com>
|
Author: Frank Niessink <frank@niessink.com>
|
||||||
License: wxWidgets license
|
License: wxWidgets license
|
||||||
Version: 0.8
|
Version: 0.9
|
||||||
Date: 13 March 2007
|
Date: 18 March 2007
|
||||||
|
|
||||||
ExpansionState is based on code and ideas from Karsten Hilbert.
|
ExpansionState is based on code and ideas from Karsten Hilbert.
|
||||||
Andrea Gavana provided help with the CustomTreeCtrl integration.
|
Andrea Gavana provided help with the CustomTreeCtrl integration.
|
||||||
@@ -179,7 +179,16 @@ class TreeAPIHarmonizer(object):
|
|||||||
|
|
||||||
def ExpandAll(self, item=None):
|
def ExpandAll(self, item=None):
|
||||||
# TreeListCtrl wants an item as argument. That's an inconsistency with
|
# TreeListCtrl wants an item as argument. That's an inconsistency with
|
||||||
# the TreeCtrl API.
|
# the TreeCtrl API. Also, TreeCtrl doesn't allow invoking ExpandAll
|
||||||
|
# on a tree with hidden root node, so prevent that.
|
||||||
|
if self.HasFlag(wx.TR_HIDE_ROOT):
|
||||||
|
rootItem = self.GetRootItem()
|
||||||
|
if rootItem:
|
||||||
|
child, cookie = self.GetFirstChild(rootItem)
|
||||||
|
while child:
|
||||||
|
self.ExpandAllChildren(child)
|
||||||
|
child, cookie = self.GetNextChild(rootItem, cookie)
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
super(TreeAPIHarmonizer, self).ExpandAll()
|
super(TreeAPIHarmonizer, self).ExpandAll()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
@@ -187,13 +196,28 @@ class TreeAPIHarmonizer(object):
|
|||||||
item = self.GetRootItem()
|
item = self.GetRootItem()
|
||||||
super(TreeAPIHarmonizer, self).ExpandAll(item)
|
super(TreeAPIHarmonizer, self).ExpandAll(item)
|
||||||
|
|
||||||
|
def ExpandAllChildren(self, item):
|
||||||
|
# TreeListCtrl and CustomTreeCtrl don't have ExpandallChildren
|
||||||
|
try:
|
||||||
|
super(TreeAPIHarmonizer, self).ExpandAllChildren(item)
|
||||||
|
except AttributeError:
|
||||||
|
self.Expand(item)
|
||||||
|
child, cookie = self.GetFirstChild(item)
|
||||||
|
while child:
|
||||||
|
self.ExpandAllChildren(child)
|
||||||
|
child, cookie = self.GetNextChild(item, cookie)
|
||||||
|
|
||||||
|
|
||||||
class TreeHelper(object):
|
class TreeHelper(object):
|
||||||
''' This class provides methods that are not part of the API of any
|
''' This class provides methods that are not part of the API of any
|
||||||
tree control, but are convenient to have available. '''
|
tree control, but are convenient to have available. '''
|
||||||
|
|
||||||
def GetItemChildren(self, item, recursively=False):
|
def GetItemChildren(self, item=None, recursively=False):
|
||||||
''' Return the children of item as a list. '''
|
''' Return the children of item as a list. '''
|
||||||
|
if not item:
|
||||||
|
item = self.GetRootItem()
|
||||||
|
if not item:
|
||||||
|
return []
|
||||||
children = []
|
children = []
|
||||||
child, cookie = self.GetFirstChild(item)
|
child, cookie = self.GetFirstChild(item)
|
||||||
while child:
|
while child:
|
||||||
@@ -203,29 +227,23 @@ class TreeHelper(object):
|
|||||||
child, cookie = self.GetNextChild(item, cookie)
|
child, cookie = self.GetNextChild(item, cookie)
|
||||||
return children
|
return children
|
||||||
|
|
||||||
def ItemIndex(self, item, tupleIndex=True):
|
def GetIndexOfItem(self, item):
|
||||||
''' Return the index of item. If tupleIndex is True, return a
|
''' Return the index of item. '''
|
||||||
an tuple-based index else return an integer-based index for item. '''
|
|
||||||
if tupleIndex:
|
|
||||||
parent = self.GetItemParent(item)
|
parent = self.GetItemParent(item)
|
||||||
if parent:
|
if parent:
|
||||||
parentIndices = self.ItemIndex(parent)
|
parentIndices = self.GetIndexOfItem(parent)
|
||||||
ownIndex = self.GetItemChildren(parent).index(item)
|
ownIndex = self.GetItemChildren(parent).index(item)
|
||||||
return parentIndices + (ownIndex,)
|
return parentIndices + (ownIndex,)
|
||||||
else:
|
else:
|
||||||
return ()
|
return ()
|
||||||
else:
|
|
||||||
rootItem = self.GetRootItem()
|
def GetItemByIndex(self, index):
|
||||||
if self.HasFlag(wx.TR_HIDE_ROOT):
|
''' Return the item specified by index. '''
|
||||||
if item == rootItem:
|
item = self.GetRootItem()
|
||||||
return None
|
for i in index:
|
||||||
countRoot = 0
|
children = self.GetItemChildren(item)
|
||||||
else:
|
item = children[i]
|
||||||
if item == rootItem:
|
return item
|
||||||
return 0
|
|
||||||
countRoot = 1
|
|
||||||
return self.GetItemChildren(rootItem,
|
|
||||||
recursively=True).index(item) + countRoot
|
|
||||||
|
|
||||||
|
|
||||||
class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
||||||
@@ -241,73 +259,44 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
|||||||
VirtualTree uses several callbacks (such as OnGetItemText) to
|
VirtualTree uses several callbacks (such as OnGetItemText) to
|
||||||
retrieve information needed to construct the tree and render the
|
retrieve information needed to construct the tree and render the
|
||||||
items. To specify what item the callback needs information about,
|
items. To specify what item the callback needs information about,
|
||||||
the callback passes an item index. VirtualTree supports two types of
|
the callback passes an item index. Whereas for list controls a simple
|
||||||
indices: a tuple-based index (the default) and an integer based index.
|
integer index can be used, for tree controls indicating a specific
|
||||||
See below for a more detailed explanation of the two index types.
|
item is a little bit more complicated. See below for a more detailed
|
||||||
|
explanation of the how index works.
|
||||||
|
|
||||||
Note that VirtualTree forces the wx.TR_HIDE_ROOT style.
|
Note that VirtualTree forces the wx.TR_HIDE_ROOT style.
|
||||||
|
|
||||||
In your subclass you *must* override OnGetItemText and either
|
In your subclass you *must* override OnGetItemText and
|
||||||
OnGetChildrenCount if you use the tuple-based index or
|
OnGetChildrenCount. These two methods are the minimum needed to
|
||||||
OnGetChildrenIndices if you use the integer-based index. These
|
construct the tree and render the item labels. If you want to add
|
||||||
methods are the minimum needed to construct the tree and render
|
images, change fonts our colours, etc., you need to override the
|
||||||
the item labels. If you want to add images, change fonts our colours,
|
appropriate OnGetXXX method as well.
|
||||||
etc., you need to override the appropriate OnGetXXX method as well.
|
|
||||||
|
|
||||||
About the index types: VirtualTree supports two types of indices that
|
About indices: your callbacks are passed a tuple of integers that
|
||||||
are passed to the several callbacks to retrieve information about
|
identifies the item the VirtualTree wants information about. An
|
||||||
items in the tree. The default index type is tuple-based, the second
|
empty tuple, i.e. (), represents the hidden root item. A tuple with
|
||||||
type is integer-based.
|
one integer, e.g. (3,), represents a visible root item, in this case
|
||||||
|
the fourth one. A tuple with two integers, e.g. (3,0), represents a
|
||||||
If you use tuple-based indices, your callbacks are passed a tuple of
|
child of a visible root item, in this case the first child of the
|
||||||
integers that identifies the item the VirtualTree wants information
|
fourth root item.
|
||||||
about. An empty tuple, i.e. (), represents the hidden root item.
|
|
||||||
A tuple with one integer, e.g. (3,), represents a visible root item,
|
|
||||||
in this case the fourth one. A tuple with two integers, e.g. (3,0),
|
|
||||||
represents a child of a visible root item, in this case the first
|
|
||||||
child of the fourth root item. The tuple-based index is best suited
|
|
||||||
if your underlying data structure is organized as a tree and allows
|
|
||||||
for easy navigation to the right object in your tree data structure.
|
|
||||||
|
|
||||||
If you use integer-based indices, your callbacks are passed a simple
|
|
||||||
integer (or None) that identifies the item the VirtualTree wants
|
|
||||||
information about. None represents the hidden root item. Zero (0)
|
|
||||||
represents the first visible root item. If the first visible root
|
|
||||||
item has children 1 represents the first child of the first visible
|
|
||||||
root item. If that child has children 2 represents the first grand
|
|
||||||
child of the first visible root item. If the first child has no
|
|
||||||
children, 2 would represent the second child of the first visible
|
|
||||||
root item, etc. Basically, the integer is the row number of the item
|
|
||||||
(when the tree is completely expanded). Integer-based indices are
|
|
||||||
more convenient when your underlying data structure is organized as
|
|
||||||
a list that is in the same order as the tree items in the tree need
|
|
||||||
to be.
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._tupleIndex = kwargs.pop('tupleIndex', True)
|
|
||||||
kwargs['style'] = kwargs.get('style', wx.TR_DEFAULT_STYLE) | \
|
kwargs['style'] = kwargs.get('style', wx.TR_DEFAULT_STYLE) | \
|
||||||
wx.TR_HIDE_ROOT
|
wx.TR_HIDE_ROOT
|
||||||
super(VirtualTree, self).__init__(*args, **kwargs)
|
super(VirtualTree, self).__init__(*args, **kwargs)
|
||||||
self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnItemExpanding)
|
self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnItemExpanding)
|
||||||
self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed)
|
self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed)
|
||||||
|
|
||||||
def OnGetChildrenCount(self, tupleIndex):
|
def OnGetChildrenCount(self, index):
|
||||||
''' This function must be overloaded in the derived class, if
|
''' This function *must* be overloaded in the derived class.
|
||||||
you use the tuple-based indices. It should return the number
|
It should return the number of child items of the item with the
|
||||||
of child items of the item with the provided tupleIndex. If
|
provided index. If index == () it should return the number of
|
||||||
tupleIndex == () it should return the number of root items. '''
|
root items. '''
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def OnGetChildrenIndices(self, integerIndex=None):
|
|
||||||
''' This function must be overloaded in the derived class, if
|
|
||||||
you want to use the integer-based index. The overridden method
|
|
||||||
should return a list containing the (integer) indices of the
|
|
||||||
children of the specified item. '''
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def OnGetItemText(self, index, column=0):
|
def OnGetItemText(self, index, column=0):
|
||||||
''' This function must be overloaded in the derived class. It
|
''' This function *must* be overloaded in the derived class. It
|
||||||
should return the string containing the text of the specified
|
should return the string containing the text of the specified
|
||||||
item. '''
|
item. '''
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@@ -361,11 +350,17 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
|||||||
rootItem = self.AddRoot('Hidden root')
|
rootItem = self.AddRoot('Hidden root')
|
||||||
self.RefreshChildrenRecursively(rootItem)
|
self.RefreshChildrenRecursively(rootItem)
|
||||||
|
|
||||||
|
def RefreshItem(self, index):
|
||||||
|
''' Redraws the item with the specified index. '''
|
||||||
|
item = self.GetItemByIndex(index)
|
||||||
|
hasChildren = bool(self.OnGetChildrenCount(index))
|
||||||
|
self.DoRefreshItem(item, index, hasChildren)
|
||||||
|
|
||||||
def RefreshChildrenRecursively(self, item, itemIndex=None):
|
def RefreshChildrenRecursively(self, item, itemIndex=None):
|
||||||
''' Refresh the children of item, reusing as much of the
|
''' Refresh the children of item, reusing as much of the
|
||||||
existing items in the tree as possible. '''
|
existing items in the tree as possible. '''
|
||||||
if itemIndex is None:
|
if itemIndex is None:
|
||||||
itemIndex = self.ItemIndex(item, tupleIndex=self._tupleIndex)
|
itemIndex = self.GetIndexOfItem(item)
|
||||||
reusableChildren = self.GetItemChildren(item)
|
reusableChildren = self.GetItemChildren(item)
|
||||||
for childIndex in self.ChildIndices(itemIndex):
|
for childIndex in self.ChildIndices(itemIndex):
|
||||||
if reusableChildren:
|
if reusableChildren:
|
||||||
@@ -378,8 +373,8 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
|||||||
|
|
||||||
def RefreshItemRecursively(self, item, itemIndex):
|
def RefreshItemRecursively(self, item, itemIndex):
|
||||||
''' Refresh the item and its children recursively. '''
|
''' Refresh the item and its children recursively. '''
|
||||||
hasChildren = bool(self.ChildIndices(itemIndex))
|
hasChildren = bool(self.OnGetChildrenCount(itemIndex))
|
||||||
self.RefreshItem(item, itemIndex, hasChildren)
|
item = self.DoRefreshItem(item, itemIndex, hasChildren)
|
||||||
# We need to refresh the children when the item is expanded and
|
# We need to refresh the children when the item is expanded and
|
||||||
# when the item has no children, because in the latter case we
|
# when the item has no children, because in the latter case we
|
||||||
# might have to delete old children from the tree:
|
# might have to delete old children from the tree:
|
||||||
@@ -387,7 +382,7 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
|||||||
self.RefreshChildrenRecursively(item, itemIndex)
|
self.RefreshChildrenRecursively(item, itemIndex)
|
||||||
self.SetItemHasChildren(item, hasChildren)
|
self.SetItemHasChildren(item, hasChildren)
|
||||||
|
|
||||||
def RefreshItem(self, item, index, hasChildren):
|
def DoRefreshItem(self, item, index, hasChildren):
|
||||||
''' Refresh one item. '''
|
''' Refresh one item. '''
|
||||||
item = self.RefreshItemType(item, index)
|
item = self.RefreshItemType(item, index)
|
||||||
self.RefreshItemText(item, index)
|
self.RefreshItemText(item, index)
|
||||||
@@ -397,6 +392,7 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
|||||||
self.RefreshBackgroundColour(item, index)
|
self.RefreshBackgroundColour(item, index)
|
||||||
self.RefreshItemImage(item, index, hasChildren)
|
self.RefreshItemImage(item, index, hasChildren)
|
||||||
self.RefreshCheckedState(item, index)
|
self.RefreshCheckedState(item, index)
|
||||||
|
return item
|
||||||
|
|
||||||
def RefreshItemText(self, item, index):
|
def RefreshItemText(self, item, index):
|
||||||
self.__refreshAttribute(item, index, 'ItemText')
|
self.__refreshAttribute(item, index, 'ItemText')
|
||||||
@@ -441,12 +437,9 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper):
|
|||||||
self.__refreshAttribute(item, index, 'ItemChecked')
|
self.__refreshAttribute(item, index, 'ItemChecked')
|
||||||
|
|
||||||
def ChildIndices(self, itemIndex):
|
def ChildIndices(self, itemIndex):
|
||||||
if self._tupleIndex:
|
|
||||||
childrenCount = self.OnGetChildrenCount(itemIndex)
|
childrenCount = self.OnGetChildrenCount(itemIndex)
|
||||||
return [itemIndex + (childNumber,) for childNumber \
|
return [itemIndex + (childNumber,) for childNumber \
|
||||||
in range(childrenCount)]
|
in range(childrenCount)]
|
||||||
else:
|
|
||||||
return self.OnGetChildrenIndices(itemIndex)
|
|
||||||
|
|
||||||
def OnItemExpanding(self, event):
|
def OnItemExpanding(self, event):
|
||||||
self.RefreshChildrenRecursively(event.GetItem())
|
self.RefreshChildrenRecursively(event.GetItem())
|
||||||
@@ -601,7 +594,7 @@ class ExpansionState(TreeAPIHarmonizer, TreeHelper):
|
|||||||
(if you know that labels are unique and don't change), or return
|
(if you know that labels are unique and don't change), or return
|
||||||
something that represents the underlying domain object, e.g.
|
something that represents the underlying domain object, e.g.
|
||||||
a database key. '''
|
a database key. '''
|
||||||
return self.ItemIndex(item)
|
return self.GetIndexOfItem(item)
|
||||||
|
|
||||||
def GetExpansionState(self):
|
def GetExpansionState(self):
|
||||||
''' GetExpansionState() -> list of expanded items. Expanded items
|
''' GetExpansionState() -> list of expanded items. Expanded items
|
||||||
|
Reference in New Issue
Block a user