AGW Logo

svn SVN Revision 68021 For customtreectrl

This file contains the SVN revision history for customtreectrl, at revision 68021.

Available information include commit date, the name of the committer, the file size, the SVN log messages and a diff from the previous version (if available).


file_info File Information

  • Commit Date: 30-Mar-2010 04:15:46 UTC
  • Committer: AG
  • File Size: 263572 byte(s)

svn_log Log Messages

The following log message was entered by the committer:

  • Fixed bug #13269 for CustomTreeCtrl and HyperTreeList (thanks to Frank Niessink);
  • Fixed bug #13268 for AuiToolBar;
  • Fixed bug #13107 on AuiNotebook.

svn_diff Diff To Previous Version (67457)

Version SVN diff:

--- wxPython/3rdParty/AGW/agw/customtreectrl.py     2011/04/13 18:03:05     67457
+++ wxPython/3rdParty/AGW/agw/customtreectrl.py     2011/06/22 19:56:23     68021
@@ -3,7 +3,7 @@
# Inspired By And Heavily Based On wxGenericTreeCtrl.
#
# Andrea Gavana, @ 17 May 2006
-# Latest Revision: 23 Jan 2011, 10.00 GMT
+# Latest Revision: 21 Jun 2011, 22.00 GMT
#
#
# TODO List
@@ -74,6 +74,7 @@
* Whatever non-toplevel widget can be attached next to an item;
* Possibility to horizontally align the widgets attached to tree items on the
same tree level.
+* Possibility to align the widgets attached to tree items to the rightmost edge of CustomTreeCtrl;
* Default selection style, gradient (horizontal/vertical) selection style and Windows
Vista selection style;
* Customized drag and drop images built on the fly;
@@ -99,12 +100,13 @@
- ``TR_AUTO_CHECK_PARENT``: automatically checks/unchecks the item parent;
- ``TR_AUTO_TOGGLE_CHILD``: automatically toggles the item children.

-And a style you can use to force the horizontal alignment of all the widgets
+And two styles you can use to force the horizontal alignment of all the widgets
attached to the tree items:

- ``TR_ALIGN_WINDOWS``: aligns horizontally the windows belonging to the item on the
same tree level.
-
+- ``TR_ALIGN_WINDOWS_RIGHT``: aligns to the rightmost position the windows belonging
+  to the item on the same tree level.

All the methods available in `wx.TreeCtrl` are also available in CustomTreeCtrl.

@@ -166,6 +168,7 @@
``TR_AUTO_TOGGLE_CHILD``            0x8000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT``           0x10000 Only meaningful foe checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_ALIGN_WINDOWS``               0x20000 Flag used to align windows (in items with windows) at the same horizontal position.
+``TR_ALIGN_WINDOWS_RIGHT``         0x40000 Flag used to align windows (in items with windows) to the rightmost edge of `CustomTreeCtrl`.
============================== =========== ==================================================


@@ -209,14 +212,14 @@

CustomTreeCtrl is distributed under the wxPython license.

-Latest Revision: Andrea Gavana @ 23 Jan 2011, 10.00 GMT
+Latest Revision: Andrea Gavana @ 21 Jun 2011, 22.00 GMT

-Version 2.3
+Version 2.4

"""

# Version Info
-__version__ = "2.3"
+__version__ = "2.4"

import wx
from wx.lib.expando import ExpandoTextCtrl
@@ -300,6 +303,8 @@
""" its parent item is checked/unchecked as well. """
TR_ALIGN_WINDOWS = 0x20000                                     # to align windows horizontally for items at the same level
""" Flag used to align windows (in items with windows) at the same horizontal position. """
+TR_ALIGN_WINDOWS_RIGHT = 0x40000                               # to align windows to the rightmost edge of CustomTreeCtrl
+""" Flag used to align windows (in items with windows) to the rightmost edge of `CustomTreeCtrl`."""

TR_DEFAULT_STYLE = wx.TR_DEFAULT_STYLE                         # default style for the tree control
""" The set of flags that are closest to the defaults for the native control for a""" \
@@ -999,10 +1004,10 @@


# -----------------------------------------------------------------------------
-# Auxiliary Classes: TreeRenameTimer
+# Auxiliary Classes: TreeEditTimer
# -----------------------------------------------------------------------------

-class TreeRenameTimer(wx.Timer):
+class TreeEditTimer(wx.Timer):
""" Timer used for enabling in-place edit."""

def __init__(self, owner):
@@ -1020,7 +1025,7 @@
def Notify(self):
""" The timer has expired. """

-        self._owner.OnRenameTimer()
+        self._owner.OnEditTimer()


# -----------------------------------------------------------------------------
@@ -1130,10 +1135,10 @@
# needs to be notified that the user decided
# not to change the tree item label, and that
# the edit has been cancelled
-            self._owner.OnRenameCancelled(self._itemEdited)
+            self._owner.OnCancelEdit(self._itemEdited)
return True

-        if not self._owner.OnRenameAccept(self._itemEdited, value):
+        if not self._owner.OnAcceptEdit(self._itemEdited, value):
# vetoed by the user
return False

@@ -1149,7 +1154,7 @@
if not self._finished:
self._finished = True
self._owner.SetFocusIgnoringChildren()
-            self._owner.ResetTextControl()
+            self._owner.ResetEditControl()


def OnChar(self, event):
@@ -1221,7 +1226,7 @@
# focus problems:

if not self.AcceptChanges():
-                self._owner.OnRenameCancelled(self._itemEdited)
+                self._owner.OnCancelEdit(self._itemEdited)

# We must let the native text control handle focus, too, otherwise
# it could have problems with the cursor (e.g., in wxGTK).
@@ -1231,7 +1236,7 @@
def StopEditing(self):
"""Suddenly stops the editing."""

-        self._owner.OnRenameCancelled(self._itemEdited)
+        self._owner.OnCancelEdit(self._itemEdited)
self.Finish()


@@ -2282,6 +2287,7 @@
``TR_AUTO_TOGGLE_CHILD``            0x8000 Only meaningful foe checkbox-type items: when a parent item is checked/unchecked its children are toggled accordingly.
``TR_AUTO_CHECK_PARENT``           0x10000 Only meaningful foe checkbox-type items: when a child item is checked/unchecked its parent item is checked/unchecked as well.
``TR_ALIGN_WINDOWS``               0x20000 Flag used to align windows (in items with windows) at the same horizontal position.
+         ``TR_ALIGN_WINDOWS_RIGHT``         0x40000 Flag used to align windows (in items with windows) to the rightmost edge of `CustomTreeCtrl`.
============================== =========== ==================================================

:param `validator`: window validator;
@@ -2322,9 +2328,9 @@
self._dragImage = None
self._underMouse = None

-        # TextCtrl initial settings for editable items
-        self._textCtrl = None
-        self._renameTimer = None
+        # EditCtrl initial settings for editable items
+        self._editCtrl = None
+        self._editTimer = None

# This one allows us to handle Freeze() and Thaw() calls
self._freezeCount = 0
@@ -2477,10 +2483,10 @@

# Here there may be something I miss... do I have to destroy
# something else?
-        if self._renameTimer and self._renameTimer.IsRunning():
-            self._renameTimer.Stop()
-            del self._renameTimer
-            self._renameTimer = None
+        if self._editTimer and self._editTimer.IsRunning():
+            self._editTimer.Stop()
+            del self._editTimer
+            self._editTimer = None

if self._findTimer and self._findTimer.IsRunning():
self._findTimer.Stop()
@@ -3063,7 +3069,7 @@

:see: The L{__init__} method for the `agwStyle` parameter description.
"""
-
+
# Do not try to expand the root node if it hasn't been created yet
if self._anchor and not self.HasAGWFlag(TR_HIDE_ROOT) and agwStyle & TR_HIDE_ROOT:

@@ -4110,12 +4116,12 @@
return lastGoodItem


-    def ResetTextControl(self):
-        """ Called by L{TreeTextCtrl} when it marks itself for deletion. """
+    def ResetEditControl(self):
+        """ Called by L{EditCtrl} when it marks itself for deletion. """

-        if self._textCtrl is not None:
-            self._textCtrl.Destroy()
-            self._textCtrl = None
+        if self._editCtrl is not None:
+            self._editCtrl.Destroy()
+            self._editCtrl = None

self.CalculatePositions()
self.Refresh()
@@ -4442,8 +4448,8 @@
:param `item`: an instance of L{GenericTreeItem}.
"""

-        if self._textCtrl != None and item != self._textCtrl.item() and self.IsDescendantOf(item, self._textCtrl.item()):
-            self._textCtrl.StopEditing()
+        if self._editCtrl != None and item != self._editCtrl.item() and self.IsDescendantOf(item, self._editCtrl.item()):
+            self._editCtrl.StopEditing()

if item != self._key_current and self.IsDescendantOf(item, self._key_current):
self._key_current = None
@@ -4479,9 +4485,9 @@

self._dirty = True     # do this first so stuff below doesn't cause flicker

-        if self._textCtrl != None and self.IsDescendantOf(item, self._textCtrl.item()):
+        if self._editCtrl != None and self.IsDescendantOf(item, self._editCtrl.item()):
# can't delete the item being edited, cancel editing it first
-            self._textCtrl.StopEditing()
+            self._editCtrl.StopEditing()

parent = item.GetParent()

@@ -5859,8 +5865,14 @@
if item.GetHeight() > item.GetWindowSize()[1]:
ya += (item.GetHeight() - item.GetWindowSize()[1])/2

-            if align and level in self.absoluteWindows:
-                wndx = self.absoluteWindows[level] + item.GetX() + 2
+            if align == 1:
+                # Horizontal alignment of windows
+                if level in self.absoluteWindows:
+                    wndx = self.absoluteWindows[level] + item.GetX() + 2
+
+            elif align == 2:
+                # Rightmost alignment of windows
+                wndx = self.GetClientSize().x - item.GetWindowSize().x - 2

if not wnd.IsShown():
wnd.Show()
@@ -5880,8 +5892,16 @@
:param `dc`: an instance of `wx.DC`;
:param `level`: the item level in the tree hierarchy;
:param `y`: the current vertical position in the `wx.PyScrolledWindow`;
-        :param `align`: ``True`` if we want to align windows (in items with windows)
-         at the same horizontal position.
+        :param `align`: an integer specifying the alignment type:
+
+         =============== =========================================
+         `align` Value   Description
+         =============== =========================================
+                0        No horizontal alignment of windows (in items with windows).
+                1        Windows (in items with windows) are aligned at the same horizontal position.
+                2        Windows (in items with windows) are aligned at the rightmost edge of L{CustomTreeCtrl}.
+         =============== =========================================
+
"""

x = level*self._indent
@@ -6113,7 +6133,13 @@
dc.SetFont(self._normalFont)
dc.SetPen(self._dottedPen)

-        align = self.HasAGWFlag(TR_ALIGN_WINDOWS)
+        align = 0
+
+        if self.HasAGWFlag(TR_ALIGN_WINDOWS):
+            align = 1
+        elif self.HasAGWFlag(TR_ALIGN_WINDOWS_RIGHT):
+            align = 2
+
y = 2
self.PaintLevel(self._anchor, dc, 0, y, align)

@@ -6125,7 +6151,11 @@
:param `event`: a `wx.SizeEvent` event to be processed.
"""

-        self.RefreshSelected()
+        if self.HasAGWFlag(TR_ALIGN_WINDOWS_RIGHT) and self._itemWithWindow:
+            self.RefreshItemWithWindows()
+        else:
+            self.RefreshSelected()
+
event.Skip()


@@ -6608,11 +6638,11 @@
else:
wx.YieldIfNeeded()

-        if self._textCtrl != None and item != self._textCtrl.item():
-            self._textCtrl.StopEditing()
+        if self._editCtrl != None and item != self._editCtrl.item():
+            self._editCtrl.StopEditing()

-        self._textCtrl = TreeTextCtrl(self, item=item)
-        self._textCtrl.SetFocus()
+        self._editCtrl = TreeTextCtrl(self, item=item)
+        self._editCtrl.SetFocus()


def GetEditControl(self):
@@ -6622,12 +6652,12 @@
simultaneously).
"""

-        return self._textCtrl
+        return self._editCtrl


-    def OnRenameAccept(self, item, value):
+    def OnAcceptEdit(self, item, value):
"""
-        Called by L{TreeTextCtrl}, to accept the changes and to send the
+        Called by L{EditCtrl}, to accept the changes and to send the
``EVT_TREE_END_LABEL_EDIT`` event.

:param `item`: an instance of L{GenericTreeItem};
@@ -6643,9 +6673,9 @@
return not self.GetEventHandler().ProcessEvent(le) or le.IsAllowed()


-    def OnRenameCancelled(self, item):
+    def OnCancelEdit(self, item):
"""
-        Called by L{TreeTextCtrl}, to cancel the changes and to send the
+        Called by L{EditCtrl}, to cancel the changes and to send the
``EVT_TREE_END_LABEL_EDIT`` event.

:param `item`: an instance of L{GenericTreeItem}.
@@ -6661,8 +6691,8 @@
self.GetEventHandler().ProcessEvent(le)


-    def OnRenameTimer(self):
-        """ The timer for renaming has expired. Start editing. """
+    def OnEditTimer(self):
+        """ The timer for editing has expired. Start editing. """

self.Edit(self._current)

@@ -6686,7 +6716,7 @@
underMouseChanged = underMouse != self._underMouse

if underMouse and (flags & TREE_HITTEST_ONITEM) and not event.LeftIsDown() and \
-           not self._isDragging and (not self._renameTimer or not self._renameTimer.IsRunning()):
+           not self._isDragging and (not self._editTimer or not self._editTimer.IsRunning()):
underMouse = underMouse
else:
underMouse = None
@@ -6701,8 +6731,8 @@
# Determines what item we are hovering over and need a tooltip for
hoverItem = thisItem

-        # We do not want a tooltip if we are dragging, or if the rename timer is running
-        if underMouseChanged and not self._isDragging and (not self._renameTimer or not self._renameTimer.IsRunning()):
+        # We do not want a tooltip if we are dragging, or if the edit timer is running
+        if underMouseChanged and not self._isDragging and (not self._editTimer or not self._editTimer.IsRunning()):

if hoverItem is not None:
# Ask the tree control what tooltip (if any) should be shown
@@ -6867,14 +6897,14 @@
self._dragCount = 0

if item == None:
-                if self._textCtrl != None and item != self._textCtrl.item():
-                    self._textCtrl.StopEditing()
+                if self._editCtrl != None and item != self._editCtrl.item():
+                    self._editCtrl.StopEditing()
return  # we hit the blank area

if event.RightDown():

-                if self._textCtrl != None and item != self._textCtrl.item():
-                    self._textCtrl.StopEditing()
+                if self._editCtrl != None and item != self._editCtrl.item():
+                    self._editCtrl.StopEditing()

self._hasFocus = True
self.SetFocusIgnoringChildren()
@@ -6915,17 +6945,17 @@

if item == self._current and (flags & TREE_HITTEST_ONITEMLABEL) and self.HasAGWFlag(TR_EDIT_LABELS):

-                        if self._renameTimer:
+                        if self._editTimer:

-                            if self._renameTimer.IsRunning():
+                            if self._editTimer.IsRunning():

-                                self._renameTimer.Stop()
+                                self._editTimer.Stop()

else:

-                            self._renameTimer = TreeRenameTimer(self)
+                            self._editTimer = TreeEditTimer(self)

-                        self._renameTimer.Start(_DELAY, True)
+                        self._editTimer.Start(_DELAY, True)

self._lastOnSame = False

@@ -6933,12 +6963,12 @@
else: # !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick()

if not item or not item.IsEnabled():
-                    if self._textCtrl != None and item != self._textCtrl.item():
-                        self._textCtrl.StopEditing()
+                    if self._editCtrl != None and item != self._editCtrl.item():
+                        self._editCtrl.StopEditing()
return

-                if self._textCtrl != None and item != self._textCtrl.item():
-                    self._textCtrl.StopEditing()
+                if self._editCtrl != None and item != self._editCtrl.item():
+                    self._editCtrl.StopEditing()

self._hasFocus = True
self.SetFocusIgnoringChildren()
@@ -7001,8 +7031,8 @@
if event.LeftDClick():

# double clicking should not start editing the item label
-                    if self._renameTimer:
-                        self._renameTimer.Stop()
+                    if self._editTimer:
+                        self._editTimer.Stop()

self._lastOnSame = False

@@ -7059,15 +7089,23 @@
#        event.Skip()


-    def CalculateSize(self, item, dc, level=-1, align=False):
+    def CalculateSize(self, item, dc, level=-1, align=0):
"""
Calculates overall position and size of an item.

:param `item`: an instance of L{GenericTreeItem};
:param `dc`: an instance of `wx.DC`;
:param `level`: the item level in the tree hierarchy;
-        :param `align`: ``True`` if we want to align windows (in items with windows)
-         at the same horizontal position.
+        :param `align`: an integer specifying the alignment type:
+
+         =============== =========================================
+         `align` Value   Description
+         =============== =========================================
+                0        No horizontal alignment of windows (in items with windows).
+                1        Windows (in items with windows) are aligned at the same horizontal position.
+                2        Windows (in items with windows) are aligned at the rightmost edge of L{CustomTreeCtrl}.
+         =============== =========================================
+
"""

attr = item.GetAttributes()
@@ -7124,19 +7162,19 @@
totalHeight = max(total_h, item.GetWindowSize()[1])

if level >= 0 and wnd:
-            if not align:
+            if align == 0:
if level in self.absoluteWindows:
self.absoluteWindows[level] = max(self.absoluteWindows[level], image_w+text_w+wcheck+2)
else:
self.absoluteWindows[level] = image_w+text_w+wcheck+2
-            else:
+            elif align == 1:
self.absoluteWindows[level] = max(self.absoluteWindows[level], image_w+text_w+wcheck+2)

item.SetWidth(totalWidth)
item.SetHeight(totalHeight)


-    def CalculateLevel(self, item, dc, level, y, align=False):
+    def CalculateLevel(self, item, dc, level, y, align=0):
"""
Calculates the level of an item inside the tree hierarchy.

@@ -7144,8 +7182,16 @@
:param `dc`: an instance of `wx.DC`;
:param `level`: the item level in the tree hierarchy;
:param `y`: the current vertical position inside the `wx.PyScrolledWindow`;
-        :param `align`: ``True`` if we want to align windows (in items with windows)
-         at the same horizontal position.
+        :param `align`: an integer specifying the alignment type:
+
+         =============== =========================================
+         `align` Value   Description
+         =============== =========================================
+                0        No horizontal alignment of windows (in items with windows).
+                1        Windows (in items with windows) are aligned at the same horizontal position.
+                2        Windows (in items with windows) are aligned at the rightmost edge of L{CustomTreeCtrl}.
+         =============== =========================================
+
"""

x = level*self._indent
@@ -7202,9 +7248,10 @@
y = 2
y = self.CalculateLevel(self._anchor, dc, 0, y) # start recursion

-        if self.HasAGWFlag(TR_ALIGN_WINDOWS):
+        if self.HasAGWFlag(TR_ALIGN_WINDOWS) or self.HasAGWFlag(TR_ALIGN_WINDOWS_RIGHT):
+            align = (self.HasAGWFlag(TR_ALIGN_WINDOWS) and [1] or [2])[0]
y = 2
-            y = self.CalculateLevel(self._anchor, dc, 0, y, align=True) # start recursion
+            y = self.CalculateLevel(self._anchor, dc, 0, y, align) # start recursion


def RefreshSubtree(self, item):
@@ -7280,6 +7327,33 @@
self.RefreshSelectedUnder(child)


+    def RefreshItemWithWindows(self, item=None):
+        """
+        Refreshes the items with which a window is associated.
+
+        :param `item`: an instance of L{GenericTreeItem}. If `item` is ``None``, then the
+         recursive refresh starts from the root node.
+
+        :note: This method is called only if the style ``TR_ALIGN_WINDOWS_RIGHT`` is used.
+        """
+
+        if self._freezeCount:
+            return
+
+        if item is None:
+            if self._anchor:
+                self.RefreshItemWithWindows(self._anchor)
+                return
+
+        wnd = item.GetWindow()
+        if wnd and wnd.IsShown():
+            self.RefreshLine(item)
+
+        children = item.GetChildren()
+        for child in children:
+            self.RefreshItemWithWindows(child)
+
+
def Freeze(self):
"""
Freeze L{CustomTreeCtrl}.
Tree