Patch from FN that fixes bug in RefreshItem on an item that has no

corresponding node in the tree yet (because its parent isn't expanded
yet) triggered an exception.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45503 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2007-04-16 18:59:00 +00:00
parent 3a41827a6d
commit 7d36c6a8eb
3 changed files with 38 additions and 50 deletions

View File

@@ -1,10 +1,6 @@
import wx, wx.lib.customtreectrl, wx.gizmos import wx, wx.lib.customtreectrl, wx.gizmos
try: import treemixin
import treemixin
except ImportError:
from wx.lib.mixins import treemixin
overview = treemixin.__doc__
class TreeModel(object): class TreeModel(object):
''' TreeModel holds the domain objects that are shown in the different ''' TreeModel holds the domain objects that are shown in the different
@@ -153,8 +149,8 @@ class VirtualCustomTreeCtrl(DemoTreeMixin,
wx.lib.customtreectrl.CustomTreeCtrl): wx.lib.customtreectrl.CustomTreeCtrl):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.checked = {} self.checked = {}
kwargs['ctstyle'] = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | \ kwargs['style'] = wx.TR_HIDE_ROOT | \
wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT
super(VirtualCustomTreeCtrl, self).__init__(*args, **kwargs) super(VirtualCustomTreeCtrl, self).__init__(*args, **kwargs)
self.Bind(wx.lib.customtreectrl.EVT_TREE_ITEM_CHECKED, self.Bind(wx.lib.customtreectrl.EVT_TREE_ITEM_CHECKED,
self.OnItemChecked) self.OnItemChecked)

View File

@@ -1,8 +1,4 @@
import wx, wx.gizmos, wx.lib.customtreectrl, unittest import wx, wx.gizmos, wx.lib.customtreectrl, unittest, treemixin
try:
import treemixin
except ImportError:
from wx.lib.mixins import treemixin
# VirtualTree tests # VirtualTree tests
@@ -171,6 +167,14 @@ class VirtualTreeCtrlTest_OneRoot(unittest.TestCase):
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 testRefreshItemThatHasNoCorrespondingNodeInTheTree(self):
# The item to refresh might be in a collapsed branch of the tree
# and not present yet.
self.tree.PrepareChildrenCount((0,), 1)
self.tree.RefreshItem((0,0))
item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem())
self.failIf(self.tree.ItemHasChildren(item))
# TreeAPIHarmonizer tests # TreeAPIHarmonizer tests
@@ -240,6 +244,10 @@ class TreeAPIHarmonizerCommonTests(object):
self.tree.ExpandAllChildren(self.item) self.tree.ExpandAllChildren(self.item)
self.failUnless(self.tree.IsExpanded(self.item)) self.failUnless(self.tree.IsExpanded(self.item))
def testGetFirstVisibleItem(self):
self.tree.DeleteAllItems()
self.failIf(self.tree.GetFirstVisibleItem())
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
@@ -707,6 +715,7 @@ class VanillaTreeCommonTests(object):
self.assertEqual(1, len(self.eventsReceived)) self.assertEqual(1, len(self.eventsReceived))
class VanillaTreeCtrlTestCase(VanillaTreeCommonTests, VanillaTreeTestCase): class VanillaTreeCtrlTestCase(VanillaTreeCommonTests, VanillaTreeTestCase):
TreeClass = wx.TreeCtrl TreeClass = wx.TreeCtrl
@@ -724,31 +733,9 @@ class VanillaCustomTreeCtrlTestCase(VanillaTreeCommonTests,
TreeClass = wx.lib.customtreectrl.CustomTreeCtrl TreeClass = wx.lib.customtreectrl.CustomTreeCtrl
# Tests of the tree controls without any mixin, to document behaviour class VanillaTreeItemIdTestCase(unittest.TestCase):
# that is either different between tree control widgets or undesired def testTreeItemIdIsFalseDefault(self):
# behaviour. self.failIf(wx.TreeItemId())
class TreeCtrlTestCase(unittest.TestCase):
def setUp(self):
self.frame = wx.Frame(None)
self.tree = wx.TreeCtrl(self.frame, style=wx.TR_HIDE_ROOT)
def testSelectHiddenRootItem(self):
root = self.tree.AddRoot('Hidden root')
self.tree.SelectItem(root)
self.assertEqual(root, self.tree.GetSelection())
class CustomTreeCtrlTestCase(unittest.TestCase):
def setUp(self):
self.frame = wx.Frame(None)
self.tree = wx.lib.customtreectrl.CustomTreeCtrl(self.frame,
style=wx.TR_HIDE_ROOT)
def testSelectHiddenRootItem(self):
root = self.tree.AddRoot('Hidden root')
self.tree.SelectItem(root)
self.assertEqual(root, self.tree.GetSelection())
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -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.9.1 Version: 1.0
Date: 26 March 2007 Date: 15 April 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.
@@ -40,14 +40,6 @@ class TreeAPIHarmonizer(object):
''' This class attempts to hide the differences in API between the ''' This class attempts to hide the differences in API between the
different tree controls that are part of wxPython. ''' different tree controls that are part of wxPython. '''
def __init__(self, *args, **kwargs):
# CustomTreeCtrl uses a different keyword for the window style
# argument ('ctstyle'). To hide this, we replace the 'style' keyword
# by 'ctstyle' if we're mixed in with CustomTreeCtrl.
if isinstance(self, wx.lib.customtreectrl.CustomTreeCtrl):
kwargs['ctstyle'] = kwargs.pop('style', wx.TR_DEFAULT_STYLE)
super(TreeAPIHarmonizer, self).__init__(*args, **kwargs)
def __callSuper(self, methodName, default, *args, **kwargs): def __callSuper(self, methodName, default, *args, **kwargs):
# If our super class has a method called methodName, call it, # If our super class has a method called methodName, call it,
# otherwise return the default value. # otherwise return the default value.
@@ -148,13 +140,21 @@ class TreeAPIHarmonizer(object):
else: else:
selections = [] selections = []
# If the root item is hidden, it should never be selected, # If the root item is hidden, it should never be selected,
# unfortunately, CustomTreeCtrl and TreeCtrl allow it to be selected. # unfortunately, CustomTreeCtrl allows it to be selected.
if self.HasFlag(wx.TR_HIDE_ROOT): if self.HasFlag(wx.TR_HIDE_ROOT):
rootItem = self.GetRootItem() rootItem = self.GetRootItem()
if rootItem and rootItem in selections: if rootItem and rootItem in selections:
selections.remove(rootItem) selections.remove(rootItem)
return selections return selections
def GetFirstVisibleItem(self):
# TreeListCtrl raises an exception or even crashes when invoking
# GetFirstVisibleItem on an empty tree.
if self.GetRootItem():
return super(TreeAPIHarmonizer, self).GetFirstVisibleItem()
else:
return wx.TreeItemId()
def SelectItem(self, item, *args, **kwargs): def SelectItem(self, item, *args, **kwargs):
# Prevent the hidden root from being selected, otherwise TreeCtrl # Prevent the hidden root from being selected, otherwise TreeCtrl
# crashes # crashes
@@ -197,7 +197,7 @@ class TreeAPIHarmonizer(object):
super(TreeAPIHarmonizer, self).ExpandAll(item) super(TreeAPIHarmonizer, self).ExpandAll(item)
def ExpandAllChildren(self, item): def ExpandAllChildren(self, item):
# TreeListCtrl doesn't have ExpandallChildren # TreeListCtrl and CustomTreeCtrl don't have ExpandallChildren
try: try:
super(TreeAPIHarmonizer, self).ExpandAllChildren(item) super(TreeAPIHarmonizer, self).ExpandAllChildren(item)
except AttributeError: except AttributeError:
@@ -352,7 +352,12 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper):
def RefreshItem(self, index): def RefreshItem(self, index):
''' Redraws the item with the specified index. ''' ''' Redraws the item with the specified index. '''
item = self.GetItemByIndex(index) try:
item = self.GetItemByIndex(index)
except IndexError:
# There's no corresponding item for index, because its parent
# has not been expanded yet.
return
hasChildren = bool(self.OnGetChildrenCount(index)) hasChildren = bool(self.OnGetChildrenCount(index))
self.DoRefreshItem(item, index, hasChildren) self.DoRefreshItem(item, index, hasChildren)