From 7d36c6a8eb8b1a7d3f62087efa80d9075c5c5e5c Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 16 Apr 2007 18:59:00 +0000 Subject: [PATCH] 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 --- wxPython/demo/TreeMixin.py | 10 ++---- wxPython/tests/TreeMixinTest.py | 47 +++++++++++------------------ wxPython/wx/lib/mixins/treemixin.py | 31 +++++++++++-------- 3 files changed, 38 insertions(+), 50 deletions(-) diff --git a/wxPython/demo/TreeMixin.py b/wxPython/demo/TreeMixin.py index 8a3245571b..7c31599a3f 100644 --- a/wxPython/demo/TreeMixin.py +++ b/wxPython/demo/TreeMixin.py @@ -1,10 +1,6 @@ import wx, wx.lib.customtreectrl, wx.gizmos -try: - import treemixin -except ImportError: - from wx.lib.mixins import treemixin +import treemixin -overview = treemixin.__doc__ class TreeModel(object): ''' TreeModel holds the domain objects that are shown in the different @@ -153,8 +149,8 @@ class VirtualCustomTreeCtrl(DemoTreeMixin, wx.lib.customtreectrl.CustomTreeCtrl): def __init__(self, *args, **kwargs): self.checked = {} - kwargs['ctstyle'] = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | \ - wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT + kwargs['style'] = wx.TR_HIDE_ROOT | \ + wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT super(VirtualCustomTreeCtrl, self).__init__(*args, **kwargs) self.Bind(wx.lib.customtreectrl.EVT_TREE_ITEM_CHECKED, self.OnItemChecked) diff --git a/wxPython/tests/TreeMixinTest.py b/wxPython/tests/TreeMixinTest.py index 55a740ae67..1153f0243f 100644 --- a/wxPython/tests/TreeMixinTest.py +++ b/wxPython/tests/TreeMixinTest.py @@ -1,8 +1,4 @@ -import wx, wx.gizmos, wx.lib.customtreectrl, unittest -try: - import treemixin -except ImportError: - from wx.lib.mixins import treemixin +import wx, wx.gizmos, wx.lib.customtreectrl, unittest, treemixin # VirtualTree tests @@ -171,6 +167,14 @@ class VirtualTreeCtrlTest_OneRoot(unittest.TestCase): item, cookie = self.tree.GetFirstChild(self.tree.GetRootItem()) 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 @@ -240,6 +244,10 @@ class TreeAPIHarmonizerCommonTests(object): self.tree.ExpandAllChildren(self.item) self.failUnless(self.tree.IsExpanded(self.item)) + def testGetFirstVisibleItem(self): + self.tree.DeleteAllItems() + self.failIf(self.tree.GetFirstVisibleItem()) + class TreeAPIHarmonizerNoTreeListCtrlCommonTests(object): ''' Tests that should succeed for all tree controls, except the @@ -707,6 +715,7 @@ class VanillaTreeCommonTests(object): self.assertEqual(1, len(self.eventsReceived)) + class VanillaTreeCtrlTestCase(VanillaTreeCommonTests, VanillaTreeTestCase): TreeClass = wx.TreeCtrl @@ -724,31 +733,9 @@ class VanillaCustomTreeCtrlTestCase(VanillaTreeCommonTests, TreeClass = wx.lib.customtreectrl.CustomTreeCtrl -# Tests of the tree controls without any mixin, to document behaviour -# that is either different between tree control widgets or undesired -# behaviour. - -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()) +class VanillaTreeItemIdTestCase(unittest.TestCase): + def testTreeItemIdIsFalseDefault(self): + self.failIf(wx.TreeItemId()) if __name__ == '__main__': diff --git a/wxPython/wx/lib/mixins/treemixin.py b/wxPython/wx/lib/mixins/treemixin.py index f3a840708f..41ad9fb8c6 100644 --- a/wxPython/wx/lib/mixins/treemixin.py +++ b/wxPython/wx/lib/mixins/treemixin.py @@ -25,8 +25,8 @@ The VirtualTree and DragAndDrop mixins force the wx.TR_HIDE_ROOT style. Author: Frank Niessink License: wxWidgets license -Version: 0.9.1 -Date: 26 March 2007 +Version: 1.0 +Date: 15 April 2007 ExpansionState is based on code and ideas from Karsten Hilbert. 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 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): # If our super class has a method called methodName, call it, # otherwise return the default value. @@ -148,13 +140,21 @@ class TreeAPIHarmonizer(object): else: selections = [] # 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): rootItem = self.GetRootItem() if rootItem and rootItem in selections: selections.remove(rootItem) 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): # Prevent the hidden root from being selected, otherwise TreeCtrl # crashes @@ -197,7 +197,7 @@ class TreeAPIHarmonizer(object): super(TreeAPIHarmonizer, self).ExpandAll(item) def ExpandAllChildren(self, item): - # TreeListCtrl doesn't have ExpandallChildren + # TreeListCtrl and CustomTreeCtrl don't have ExpandallChildren try: super(TreeAPIHarmonizer, self).ExpandAllChildren(item) except AttributeError: @@ -352,7 +352,12 @@ class VirtualTree(TreeAPIHarmonizer, TreeHelper): def RefreshItem(self, 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)) self.DoRefreshItem(item, index, hasChildren) -- 2.50.0