X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c8f129d0675af4f473f92b90aeb187c90e4053c9..27ee942feb598fc96f790d62bb8aac6d8c97cce5:/wxPython/wx/lib/customtreectrl.py diff --git a/wxPython/wx/lib/customtreectrl.py b/wxPython/wx/lib/customtreectrl.py index 1616f48adb..817fa01b54 100644 --- a/wxPython/wx/lib/customtreectrl.py +++ b/wxPython/wx/lib/customtreectrl.py @@ -3,7 +3,7 @@ # Inspired By And Heavily Based On wxGenericTreeCtrl. # # Andrea Gavana, @ 17 May 2006 -# Latest Revision: 26 May 2006, 22.30 CET +# Latest Revision: 16 Apr 2007, 11.00 CET # # # TODO List @@ -95,8 +95,9 @@ Base Functionalities CustomTreeCtrl supports all the wx.TreeCtrl styles, except: - TR_EXTENDED: supports for this style is on the todo list (Am I sure of this?). -Plus it has 2 more styles to handle checkbox-type items: +Plus it has 3 more styles to handle checkbox-type items: - TR_AUTO_CHECK_CHILD : automatically checks/unchecks the item children; + - TR_AUTO_CHECK_PARENT : automatically checks/unchecks the item parent; - TR_AUTO_TOGGLE_CHILD: automatically toggles the item children. All the methods available in wx.TreeCtrl are also available in CustomTreeCtrl. @@ -133,8 +134,8 @@ CustomTreeCtrl has been tested on the following platforms: * Mac OS (Thanks to John Jackson). -Latest Revision: Andrea Gavana @ 26 May 2006, 22.30 CET -Version 0.8 +Latest Revision: Andrea Gavana @ 16 Apr 2007, 11.00 CET +Version 1.0 """ @@ -190,8 +191,9 @@ TR_HIDE_ROOT = wx.TR_HIDE_ROOT # don't display r TR_FULL_ROW_HIGHLIGHT = wx.TR_FULL_ROW_HIGHLIGHT # highlight full horz space -TR_AUTO_CHECK_CHILD = 0x4000 # only meaningful for checkboxes -TR_AUTO_TOGGLE_CHILD = 0x8000 # only meaningful for checkboxes +TR_AUTO_CHECK_CHILD = 0x04000 # only meaningful for checkboxes +TR_AUTO_TOGGLE_CHILD = 0x08000 # only meaningful for checkboxes +TR_AUTO_CHECK_PARENT = 0x10000 # only meaningful for checkboxes TR_DEFAULT_STYLE = wx.TR_DEFAULT_STYLE # default style for the tree control @@ -492,9 +494,9 @@ class DragImage(wx.DragImage): text = item.GetText() font = item.Attr().GetFont() colour = item.Attr().GetTextColour() - if colour is None: + if not colour: colour = wx.BLACK - if font is None: + if not font: font = treeCtrl._normalFont backcolour = treeCtrl.GetBackgroundColour() @@ -922,7 +924,7 @@ class TreeTextCtrl(wx.TextCtrl): else: - raise "\n ERROR: You Must Create An Image List To Use Images!" + raise Exception("\n ERROR: You Must Create An Image List To Use Images!") checkimage = item.GetCurrentCheckedImage() @@ -942,16 +944,12 @@ class TreeTextCtrl(wx.TextCtrl): x += image_w + wcheck w -= image_w + 4 + wcheck - if wx.Platform == "__WXMAC__": - bs = self.DoGetBestSize() - # edit control height - if h > bs.y - 8: - diff = h - ( bs.y - 8 ) - h -= diff - y += diff / 2 - wx.TextCtrl.__init__(self, self._owner, wx.ID_ANY, self._startValue, wx.Point(x - 4, y), wx.Size(w + 15, h)) + if wx.Platform == "__WXMAC__": + self.SetFont(owner.GetFont()) + bs = self.GetBestSize() + self.SetSize((-1, bs.height)) self.Bind(wx.EVT_CHAR, self.OnChar) self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) @@ -1166,28 +1164,7 @@ class GenericTreeItem: self._wnd = wnd # are we holding a window? if wnd: - if wnd.GetSizer(): # the window is a complex one hold by a sizer - size = wnd.GetBestSize() - else: # simple window, without sizers - size = wnd.GetSize() - - # We have to bind the wx.EVT_SET_FOCUS for the associated window - # No other solution to handle the focus changing from an item in - # CustomTreeCtrl and the window associated to an item - # Do better strategies exist? - self._wnd.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) - - self._height = size.GetHeight() + 2 - self._width = size.GetWidth() - self._windowsize = size - - # We don't show the window if the item is collapsed - if self._isCollapsed: - self._wnd.Show(False) - - # The window is enabled only if the item is enabled - self._wnd.Enable(self._enabled) - self._windowenabled = self._enabled + self.SetWindow(wnd) def IsOk(self): @@ -1312,6 +1289,29 @@ class GenericTreeItem: self._wnd = wnd + if wnd.GetSizer(): # the window is a complex one hold by a sizer + size = wnd.GetBestSize() + else: # simple window, without sizers + size = wnd.GetSize() + + # We have to bind the wx.EVT_SET_FOCUS for the associated window + # No other solution to handle the focus changing from an item in + # CustomTreeCtrl and the window associated to an item + # Do better strategies exist? + self._wnd.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + + self._height = size.GetHeight() + 2 + self._width = size.GetWidth() + self._windowsize = size + + # We don't show the window if the item is collapsed + if self._isCollapsed: + self._wnd.Show(False) + + # The window is enabled only if the item is enabled + self._wnd.Enable(self._enabled) + self._windowenabled = self._enabled + def GetWindow(self): """Returns the window associated to the item.""" @@ -1319,11 +1319,19 @@ class GenericTreeItem: return self._wnd + def DeleteWindow(self): + """Deletes the window associated to the item (if any).""" + + if self._wnd: + self._wnd.Destroy() + self._wnd = None + + def GetWindowEnabled(self): """Returns whether the associated window is enabled or not.""" if not self._wnd: - raise "\nERROR: This Item Has No Window Associated" + raise Exception("\nERROR: This Item Has No Window Associated") return self._windowenabled @@ -1332,7 +1340,7 @@ class GenericTreeItem: """Sets whether the associated window is enabled or not.""" if not self._wnd: - raise "\nERROR: This Item Has No Window Associated" + raise Exception("\nERROR: This Item Has No Window Associated") self._windowenabled = enable self._wnd.Enable(enable) @@ -1735,10 +1743,10 @@ def EventFlagsToSelType(style, shiftDown=False, ctrlDown=False): # This Is The Main Class. # ----------------------------------------------------------------------------- -class CustomTreeCtrl(wx.ScrolledWindow): +class CustomTreeCtrl(wx.PyScrolledWindow): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=0, ctstyle=TR_DEFAULT_STYLE, validator=wx.DefaultValidator, + style=TR_DEFAULT_STYLE, ctstyle=0, validator=wx.DefaultValidator, name="CustomTreeCtrl"): """ Default class constructor. @@ -1751,9 +1759,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): size: window size. If the default size (-1, -1) is specified then the window is sized appropriately. - style: the underlying wx.ScrolledWindow style + style: the underlying wx.ScrolledWindow style + CustomTreeCtrl window style. This can be one of: - ctstyle: CustomTreeCtrl window style. This can be one of: TR_NO_BUTTONS TR_HAS_BUTTONS # draw collapsed/expanded btns TR_NO_LINES # don't draw lines at all @@ -1768,12 +1775,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): TR_HIDE_ROOT # don't display root node TR_FULL_ROW_HIGHLIGHT # highlight full horizontal space TR_AUTO_CHECK_CHILD # only meaningful for checkboxes + TR_AUTO_CHECK_PARENT # only meaningful for checkboxes TR_AUTO_TOGGLE_CHILD # only meaningful for checkboxes + ctstyle: kept for backward compatibility. + validator: window validator. name: window name. """ + + style = style | ctstyle self._current = self._key_current = self._anchor = self._select_me = None self._hasFocus = False @@ -1791,7 +1803,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): btnshadow = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) self._hilightUnfocusedBrush = wx.Brush(btnshadow) r, g, b = btnshadow.Red(), btnshadow.Green(), btnshadow.Blue() - backcolour = ((r >> 1) - 20, (g >> 1) - 20, (b >> 1) - 20) + backcolour = (max((r >> 1) - 20, 0), + max((g >> 1) - 20, 0), + max((b >> 1) - 20, 0)) backcolour = wx.Colour(backcolour[0], backcolour[1], backcolour[2]) self._hilightUnfocusedBrush2 = wx.Brush(backcolour) @@ -1872,16 +1886,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._itemWithWindow = [] if wx.Platform == "__WXMAC__": + style &= ~TR_LINES_AT_ROOT + style |= TR_NO_LINES platform, major, minor = wx.GetOsVersion() - - ctstyle &= ~TR_LINES_AT_ROOT - ctstyle |= TR_NO_LINES - if major < 10: - ctstyle |= TR_ROW_LINES + style |= TR_ROW_LINES - self._windowStyle = ctstyle + self._windowStyle = style # Create the default check image list self.SetImageListCheck(13, 13) @@ -1894,7 +1906,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._drawingfunction = wx.RendererNative.Get().DrawTreeItemButton # Create our container... at last! - wx.ScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) + wx.PyScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) # If the tree display has no buttons, but does have # connecting lines, we can use a narrower layout. @@ -1922,15 +1934,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) self.Bind(EVT_TREE_ITEM_GETTOOLTIP, self.OnGetToolTip) - self.Bind(wx.EVT_IDLE, self.OnInternalIdle) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) # Sets the focus to ourselves: this is useful if you have items # with associated widgets. self.SetFocus() - return True + def AcceptsFocus(self): + # overridden base class method, allows this ctrl to + # participate in the tab-order, etc. It's overridable because + # of deriving this class from wx.PyScrolledWindow... + return True + def OnDestroy(self, event): """Handles the wx.EVT_WINDOW_DESTROY event.""" @@ -1992,7 +2008,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Toggles the item selection.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") self.SelectItem(item, not self.IsSelected(item)) @@ -2022,7 +2038,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Enables/disables an item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if item.IsEnabled() == enable: return @@ -2049,11 +2065,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.RefreshLine(item) - def IsEnabled(self, item): + def IsItemEnabled(self, item): """Returns whether an item is enabled or disabled.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.IsEnabled() @@ -2075,7 +2091,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether an item is checked or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.IsChecked() @@ -2105,7 +2121,6 @@ class CustomTreeCtrl(wx.ScrolledWindow): return False item.Check(checked) - dc = wx.ClientDC(self) self.RefreshLine(item) self.EnableChildren(item, checked) e = TreeEvent(wxEVT_TREE_ITEM_CHECKED, self.GetId()) @@ -2123,7 +2138,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") # Should we raise an error here?!? if item.GetType() == 0: @@ -2157,6 +2172,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._windowStyle & TR_AUTO_CHECK_CHILD: ischeck = self.IsItemChecked(item) self.AutoCheckChild(item, ischeck) + if self._windowStyle & TR_AUTO_CHECK_PARENT: + ischeck = self.IsItemChecked(item) + self.AutoCheckParent(item, ischeck) elif self._windowStyle & TR_AUTO_TOGGLE_CHILD: self.AutoToggleChild(item) @@ -2170,7 +2188,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Transverses the tree and toggles the items. Meaningful only for check items.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") child, cookie = self.GetFirstChild(item) @@ -2190,7 +2208,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Transverses the tree and checks/unchecks the items. Meaningful only for check items.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") (child, cookie) = self.GetFirstChild(item) @@ -2205,11 +2223,33 @@ class CustomTreeCtrl(wx.ScrolledWindow): (child, cookie) = self.GetNextChild(item, cookie) + def AutoCheckParent(self, item, checked): + """Traverses up the tree and checks/unchecks parent items. + Meaningful only for check items.""" + + if not item: + raise Exception("\nERROR: Invalid Tree Item. ") + + parent = item.GetParent() + if not parent or parent.GetType() != 1: + return + + (child, cookie) = self.GetFirstChild(parent) + while child: + if child.GetType() == 1 and child.IsEnabled(): + if checked != child.IsChecked(): + return + (child, cookie) = self.GetNextChild(parent, cookie) + + self.CheckItem2(parent, checked, torefresh=True) + self.AutoCheckParent(parent, checked) + + def CheckChilds(self, item, checked=True): """Programatically check/uncheck item children. Does not generate EVT_TREE_CHECK* events.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if checked == None: self.AutoToggleChild(item) @@ -2245,7 +2285,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Starts editing an item label.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") self.Edit(item) @@ -2280,7 +2320,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether an item has children or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return len(item.GetChildren()) > 0 @@ -2289,7 +2329,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the item children count.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.GetChildrenCount(recursively) @@ -2338,16 +2378,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns the item text.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.GetText() - def GetItemImage(self, item, which): + def GetItemImage(self, item, which=TreeItemIcon_Normal): """Returns the item image.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.GetImage(which) @@ -2356,7 +2396,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns the data associated to an item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.GetData() @@ -2367,7 +2407,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns the item text colour.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.Attr().GetTextColour() @@ -2376,7 +2416,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns the item background colour.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.Attr().GetBackgroundColour() @@ -2385,7 +2425,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns the item font.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.Attr().GetFont() @@ -2394,7 +2434,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether an item is hypertext or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.IsHyperText() @@ -2403,7 +2443,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the item text.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") dc = wx.ClientDC(self) item.SetText(text) @@ -2415,7 +2455,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the item image, depending on the item state.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") item.SetImage(image, which) @@ -2428,7 +2468,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the data associated to an item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") item.SetData(data) @@ -2439,7 +2479,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Forces the appearance of the button next to the item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") item.SetHasPlus(has) self.RefreshLine(item) @@ -2449,7 +2489,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the item font bold/unbold.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") # avoid redrawing the tree if no real change if item.IsBold() != bold: @@ -2461,7 +2501,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the item font italic/non-italic.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if item.IsItalic() != italic: itemFont = self.GetItemFont(item) @@ -2483,7 +2523,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if highlight: bg = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) @@ -2498,7 +2538,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the item text colour.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if self.GetItemTextColour(item) == col: return @@ -2511,7 +2551,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the item background colour.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") item.Attr().SetBackgroundColour(col) self.RefreshLine(item) @@ -2521,7 +2561,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets whether the item is hypertext or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") item.SetHyperText(hyper) self.RefreshLine(item) @@ -2531,7 +2571,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets the item font.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if self.GetItemFont(item) == font: return @@ -2596,7 +2636,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Sets whether an hypertext item was visited.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") item.SetVisited(visited) self.RefreshLine(item) @@ -2606,7 +2646,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether an hypertext item was visited.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.GetVisited() @@ -2778,7 +2818,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns the window associated to the item (if any).""" if not item: - raise "\nERROR: Invalid Item" + raise Exception("\nERROR: Invalid Item") return item.GetWindow() @@ -2787,7 +2827,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether the window associated to the item is enabled.""" if not item: - raise "\nERROR: Invalid Item" + raise Exception("\nERROR: Invalid Item") return item.GetWindowEnabled() @@ -2796,7 +2836,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Enables/disables the window associated to the item.""" if not item: - raise "\nERROR: Invalid Item" + raise Exception("\nERROR: Invalid Item") item.SetWindowEnabled(enable) @@ -2810,7 +2850,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if not item: - raise "\nERROR: Invalid Item" + raise Exception("\nERROR: Invalid Item") return item.GetType() @@ -2822,7 +2862,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether the item is visible or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") # An item is only visible if it's not a descendant of a collapsed item parent = item.GetParent() @@ -2855,7 +2895,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether the item has children or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") # consider that the item does have children if it has the "+" button: it # might not have them (if it had never been expanded yet) but then it @@ -2869,7 +2909,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether the item is expanded or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.IsExpanded() @@ -2878,7 +2918,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether the item is selected or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.IsSelected() @@ -2887,7 +2927,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether the item font is bold or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.IsBold() @@ -2896,7 +2936,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns whether the item font is italic or not.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.IsItalic() @@ -2909,7 +2949,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the item parent.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") return item.GetParent() @@ -2918,7 +2958,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the item first child.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") cookie = 0 return self.GetNextChild(item, cookie) @@ -2931,7 +2971,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") children = item.GetChildren() @@ -2952,7 +2992,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the item last child.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") children = item.GetChildren() return (len(children) == 0 and [None] or [children[-1]])[0] @@ -2962,7 +3002,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the next sibling of an item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") i = item parent = i.GetParent() @@ -2983,7 +3023,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the previous sibling of an item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") i = item parent = i.GetParent() @@ -3003,7 +3043,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the next item. Only for internal use right now.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") i = item @@ -3041,7 +3081,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Returns the next visible item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") id = item @@ -3056,9 +3096,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): def GetPrevVisible(self, item): if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") - raise "\nERROR: Not Implemented" + raise Exception("\nERROR: Not Implemented") return None @@ -3116,13 +3156,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Actually inserts an item in the tree.""" if wnd is not None and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if text.find("\n") >= 0 and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if ct_type < 0 or ct_type > 2: - raise "\nERROR: Item Type Should Be 0 (Normal), 1 (CheckBox) or 2 (RadioButton). " + raise Exception("\nERROR: Item Type Should Be 0 (Normal), 1 (CheckBox) or 2 (RadioButton). ") parent = parentId @@ -3148,16 +3188,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Adds a root to the CustomTreeCtrl. Only one root must exist.""" if self._anchor: - raise "\nERROR: Tree Can Have Only One Root" + raise Exception("\nERROR: Tree Can Have Only One Root") if wnd is not None and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if text.find("\n") >= 0 and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if ct_type < 0 or ct_type > 2: - raise "\nERROR: Item Type Should Be 0 (Normal), 1 (CheckBox) or 2 (RadioButton). " + raise Exception("\nERROR: Item Type Should Be 0 (Normal), 1 (CheckBox) or 2 (RadioButton). ") self._dirty = True # do this first so stuff below doesn't cause flicker @@ -3187,10 +3227,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Appends an item as a first child of parent.""" if wnd is not None and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if text.find("\n") >= 0 and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") return self.DoInsertItem(parent, 0, text, ct_type, wnd, image, selImage, data) @@ -3199,10 +3239,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Auxiliary function to cope with the C++ hideous multifunction.""" if wnd is not None and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if text.find("\n") >= 0 and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") parent = parentId @@ -3216,7 +3256,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): try: index = parent.GetChildren().index(idPrevious) except: - raise "ERROR: Previous Item In CustomTreeCtrl.InsertItem() Is Not A Sibling" + raise Exception("ERROR: Previous Item In CustomTreeCtrl.InsertItem() Is Not A Sibling") return self.DoInsertItem(parentId, index+1, text, ct_type, wnd, image, selImage, data) @@ -3225,10 +3265,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Auxiliary function to cope with the C++ hideous multifunction.""" if wnd is not None and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if text.find("\n") >= 0 and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") parent = parentId @@ -3243,10 +3283,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Inserts an item after the given previous.""" if wnd is not None and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if text.find("\n") >= 0 and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if type(input) == type(1): return self.InsertItemByIndex(parentId, input, text, ct_type, wnd, image, selImage, data) @@ -3258,10 +3298,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Appends an item as a last child of its parent.""" if wnd is not None and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert Controls You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") if text.find("\n") >= 0 and not (self._windowStyle & TR_HAS_VARIABLE_ROW_HEIGHT): - raise "\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT" + raise Exception("\nERROR: In Order To Append/Insert A MultiLine Text You Have To Use The Style TR_HAS_VARIABLE_ROW_HEIGHT") parent = parentId @@ -3278,7 +3318,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): event = TreeEvent(wxEVT_TREE_DELETE_ITEM, self.GetId()) event._item = item event.SetEventObject(self) - self.ProcessEvent(event) + self.GetEventHandler().ProcessEvent(event) def IsDescendantOf(self, parent, item): @@ -3319,7 +3359,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Delete item children.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") self._dirty = True # do this first so stuff below doesn't cause flicker @@ -3331,7 +3371,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Delete an item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") self._dirty = True # do this first so stuff below doesn't cause flicker @@ -3408,10 +3448,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if self.HasFlag(TR_HIDE_ROOT) and item == self.GetRootItem(): - raise "\nERROR: Can't Expand An Hidden Root. " + raise Exception("\nERROR: Can't Expand An Hidden Root. ") if not item.HasPlus(): return @@ -3423,7 +3463,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): event._item = item event.SetEventObject(self) - if self.ProcessEvent(event) and not event.IsAllowed(): + if self.GetEventHandler().ProcessEvent(event) and not event.IsAllowed(): # cancelled by program return @@ -3437,16 +3477,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.HideWindows() event.SetEventType(wxEVT_TREE_ITEM_EXPANDED) - self.ProcessEvent(event) + self.GetEventHandler().ProcessEvent(event) - def ExpandAll(self, item): - """Expands all the items.""" + def ExpandAllChildren(self, item): + """Expands all the items children of the input item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") - if not self.HasFlag(TR_HIDE_ROOT) or item != GetRootItem(): + if not self.HasFlag(TR_HIDE_ROOT) or item != self.GetRootItem(): self.Expand(item) if not self.IsExpanded(item): return @@ -3454,10 +3494,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): child, cookie = self.GetFirstChild(item) while child: - self.ExpandAll(child) + self.ExpandAllChildren(child) child, cookie = self.GetNextChild(item, cookie) + def ExpandAll(self): + """Expands all CustomTreeCtrl items.""" + + if self._anchor: + self.ExpandAllChildren(self._anchor) + + def Collapse(self, item): """ Collapse an item, sending a EVT_TREE_ITEM_COLLAPSING and @@ -3465,10 +3512,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") if self.HasFlag(TR_HIDE_ROOT) and item == self.GetRootItem(): - raise "\nERROR: Can't Collapse An Hidden Root. " + raise Exception("\nERROR: Can't Collapse An Hidden Root. ") if not item.IsExpanded(): return @@ -3476,7 +3523,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): event = TreeEvent(wxEVT_TREE_ITEM_COLLAPSING, self.GetId()) event._item = item event.SetEventObject(self) - if self.ProcessEvent(event) and not event.IsAllowed(): + if self.GetEventHandler().ProcessEvent(event) and not event.IsAllowed(): # cancelled by program return @@ -3490,7 +3537,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.HideWindows() event.SetEventType(wxEVT_TREE_ITEM_COLLAPSED) - self.ProcessEvent(event) + self.GetEventHandler().ProcessEvent(event) def CollapseAndReset(self, item): @@ -3551,7 +3598,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): # the tree might not have the root item at all if rootItem: self.UnselectAllChildren(rootItem) - + + self.Unselect() # Recursive function ! # To stop we must have crt_item item.GetWindowSize()[1]: + ya += (item.GetHeight() - item.GetWindowSize()[1])/2 + if not wnd.IsShown(): wnd.Show() if wnd.GetPosition() != (wndx, ya): @@ -4390,7 +4468,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): # draw line down to last child origY += self.GetLineHeight(children[0])>>1 oldY += self.GetLineHeight(children[n-1])>>1 + oldPen = dc.GetPen() + dc.SetPen(self._dottedPen) dc.DrawLine(3, origY, 3, oldY) + dc.SetPen(oldPen) return y @@ -4676,11 +4757,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): keyCode = event.GetKeyCode() if keyCode in [ord("+"), wx.WXK_ADD]: # "+" - if self._current.HasPlus() and not self.IsExpanded(self._current) and self.IsEnabled(self._current): + if self._current.HasPlus() and not self.IsExpanded(self._current) and self.IsItemEnabled(self._current): self.Expand(self._current) elif keyCode in [ord("*"), wx.WXK_MULTIPLY]: # "*" - if not self.IsExpanded(self._current) and self.IsEnabled(self._current): + if not self.IsExpanded(self._current) and self.IsItemEnabled(self._current): # expand all self.ExpandAll(self._current) @@ -4700,7 +4781,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): elif keyCode in [wx.WXK_RETURN, wx.WXK_SPACE]: - if not self.IsEnabled(self._current): + if not self.IsItemEnabled(self._current): event.Skip() return @@ -4733,7 +4814,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if prev: current = self._key_current # TODO: Huh? If we get here, we'd better be the first child of our parent. How else could it be? - if current == self.GetFirstChild(prev)[0] and self.IsEnabled(prev): + if current == self.GetFirstChild(prev)[0] and self.IsItemEnabled(prev): # otherwise we return to where we came from self.DoSelectItem(prev, unselect_others, extended_select) self._key_current = prev @@ -4749,13 +4830,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): current = prev # Try to get the previous siblings and see if they are active - while prev and not self.IsEnabled(prev): + while prev and not self.IsItemEnabled(prev): prev = self.GetPrevSibling(prev) if not prev: # No previous siblings active: go to the parent and up prev = self.GetItemParent(current) - while prev and not self.IsEnabled(prev): + while prev and not self.IsItemEnabled(prev): prev = self.GetItemParent(prev) if prev: @@ -4773,7 +4854,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self.IsExpanded(self._current): self.Collapse(self._current) else: - if prev and self.IsEnabled(prev): + if prev and self.IsItemEnabled(prev): self.DoSelectItem(prev, unselect_others, extended_select) elif keyCode == wx.WXK_RIGHT: @@ -4781,7 +4862,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # also expand the item if it wasn't expanded yet if self.IsExpanded(self._current) and self.HasChildren(self._current): child, cookie = self.GetFirstChild(self._key_current) - if self.IsEnabled(child): + if self.IsItemEnabled(child): self.DoSelectItem(child, unselect_others, extended_select) self._key_current = child else: @@ -4807,11 +4888,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): current = self.GetItemParent(current) if current: next = self.GetNextSibling(current) - if not self.IsEnabled(next): + if not next or not self.IsItemEnabled(next): next = None else: - while next and not self.IsEnabled(next): + while next and not self.IsItemEnabled(next): next = self.GetNext(next) if next: @@ -4836,7 +4917,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): last = lastChild - if last and self.IsEnabled(last): + if last and self.IsItemEnabled(last): self.DoSelectItem(last, unselect_others, extended_select) @@ -4853,7 +4934,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if not prev: return - if self.IsEnabled(prev): + if self.IsItemEnabled(prev): self.DoSelectItem(prev, unselect_others, extended_select) else: @@ -4870,7 +4951,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # no such item return - if self.IsEnabled(id): + if self.IsItemEnabled(id): self.SelectItem(id) self._findPrefix += ch @@ -4902,7 +4983,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): while 1: child = sibling(item) - if (child and self.IsEnabled(child)) or not child: + if (child and self.IsItemEnabled(child)) or not child: break item = child @@ -4910,10 +4991,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): # Tha's not a radiobutton... but some of its children can be # inactive child, cookie = self.GetFirstChild(item) - while child and not self.IsEnabled(child): + while child and not self.IsItemEnabled(child): child, cookie = self.GetNextChild(item, cookie) - if child and self.IsEnabled(child): + if child and self.IsItemEnabled(child): return child return None @@ -4967,7 +5048,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): flags = TREE_HITTEST_NOWHERE return None, flags - if not self.IsEnabled(hit): + if not self.IsItemEnabled(hit): return None, flags return hit, flags @@ -4977,7 +5058,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Gets the bounding rectangle of the item.""" if not item: - raise "\nERROR: Invalid Tree Item. " + raise Exception("\nERROR: Invalid Tree Item. ") i = item @@ -5082,7 +5163,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): underMouse = thisItem underMouseChanged = underMouse != self._underMouse - if underMouse and (flags & TREE_HITTEST_ONITEMBUTTON) and not event.LeftIsDown() and \ + if underMouse and (flags & TREE_HITTEST_ONITEM) and not event.LeftIsDown() and \ not self._isDragging and (not self._renameTimer or not self._renameTimer.IsRunning()): underMouse = underMouse else: @@ -5405,7 +5486,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.Toggle(item) - def OnInternalIdle(self, event): + def OnInternalIdle(self): """Performs operations in idle time (essentially drawing).""" # Check if we need to select the root item @@ -5486,6 +5567,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.SetHeight(total_h) else: item.SetWidth(item.GetWindowSize()[0]+image_w+text_w+wcheck+2) + item.SetHeight(max(total_h, item.GetWindowSize()[1])) def CalculateLevel(self, item, dc, level, y): @@ -5615,7 +5697,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """Thaw CustomTreeCtrl.""" if self._freezeCount == 0: - raise "\nERROR: Thawing Unfrozen Tree Control?" + raise Exception("\nERROR: Thawing Unfrozen Tree Control?") self._freezeCount = self._freezeCount - 1 @@ -5683,4 +5765,6 @@ class CustomTreeCtrl(wx.ScrolledWindow): attr.font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) return attr + GetClassDefaultAttributes = classmethod(GetClassDefaultAttributes) +