diff --git a/wx/lib/agw/__init__.py b/wx/lib/agw/__init__.py index 6b44006f..a1df03bd 100644 --- a/wx/lib/agw/__init__.py +++ b/wx/lib/agw/__init__.py @@ -120,7 +120,7 @@ andrea.gavana@maerskoil.com AGW version: 0.9.7 -Last updated: 16 July 2012, 18.00 GMT +Last updated: 27 August 2012, 21.00 GMT """ diff --git a/wx/lib/agw/customtreectrl.py b/wx/lib/agw/customtreectrl.py index 17bba8de..42c4ad01 100644 --- a/wx/lib/agw/customtreectrl.py +++ b/wx/lib/agw/customtreectrl.py @@ -3,7 +3,7 @@ # Inspired By And Heavily Based On wxGenericTreeCtrl. # # Andrea Gavana, @ 17 May 2006 -# Latest Revision: 16 Jul 2012, 15.00 GMT +# Latest Revision: 27 Aug 2012, 21.00 GMT # # # TODO List @@ -58,7 +58,7 @@ to the standard :class:`TreeCtrl` behaviour this class supports: * Added support for 3-state value checkbox items; * RadioButton-type items: since I elected to put radiobuttons in :class:`CustomTreeCtrl`, I needed some way to handle them, that made sense. So, I used the following approach: - + - All peer-nodes that are radiobuttons will be mutually exclusive. In other words, only one of a set of radiobuttons that share a common parent can be checked at once. If a radiobutton node becomes checked, then all of its peer radiobuttons @@ -125,7 +125,7 @@ attached to the tree items: - ``TR_ALIGN_WINDOWS_RIGHT``: aligns to the rightmost position the windows belonging to the item on the same tree level. -And two styles related to long items (with a lot of text in them), which can be +And two styles related to long items (with a lot of text in them), which can be ellipsized and/or highlighted with a tooltip: - ``TR_ELLIPSIZE_LONG_ITEMS``: ellipsizes long items when the horizontal space for @@ -148,13 +148,13 @@ Usage example:: def __init__(self, parent): - wx.Frame.__init__(self, parent, -1, "CustomTreeCtrl Demo") + wx.Frame.__init__(self, parent, -1, "CustomTreeCtrl Demo") # Create a CustomTreeCtrl instance custom_tree = CT.CustomTreeCtrl(self, agwStyle=wx.TR_DEFAULT_STYLE) - + # Add a root node to it - root = custom_tree.AddRoot("The Root Item") + root = custom_tree.AddRoot("The Root Item") # Create an image list to add icons next to an item il = wx.ImageList(16, 16) @@ -163,7 +163,7 @@ Usage example:: fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16, 16))) custom_tree.SetImageList(il) - + custom_tree.SetItemImage(root, fldridx, wx.TreeItemIcon_Normal) custom_tree.SetItemImage(root, fldropenidx, wx.TreeItemIcon_Expanded) @@ -195,7 +195,7 @@ Usage example:: app.MainLoop() - + Events ====== @@ -297,16 +297,16 @@ Event Name Description License And Version =================== -:class:`CustomTreeCtrl` is distributed under the wxPython license. +:class:`CustomTreeCtrl` is distributed under the wxPython license. -Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT +Latest Revision: Andrea Gavana @ 27 Aug 2012, 21.00 GMT -Version 2.7 +Version 2.6 """ # Version Info -__version__ = "2.7" +__version__ = "2.6" import wx from wx.lib.expando import ExpandoTextCtrl @@ -459,7 +459,7 @@ _rgbNoFocusInner = wx.Colour(245, 245, 245) # Flags for wx.RendererNative _CONTROL_EXPANDED = 8 _CONTROL_CURRENT = 16 - + # ---------------------------------------------------------------------------- # CustomTreeCtrl events and binding for handling them @@ -551,7 +551,7 @@ def MakeDisabledBitmap(original): :return: An instance of :class:`Bitmap`, containing a disabled-looking representation of the original item image. """ - + img = original.ConvertToImage() return wx.Bitmap(img.ConvertToGreyscale()) @@ -568,7 +568,7 @@ def DrawTreeItemButton(win, dc, rect, flags): :note: This is a simple replacement of :meth:`RendererNative.DrawTreeItemButton`. - :note: This method is never used in wxPython versions newer than 2.6.2.1. + :note: This method is never used in wxPython versions newer than 2.6.2.1. """ # white background @@ -587,7 +587,7 @@ def DrawTreeItemButton(win, dc, rect, flags): xMiddle + halfWidth + 1, yMiddle) if not flags & _CONTROL_EXPANDED: - + # turn "-" into "+" halfHeight = rect.height//2 - 2 dc.DrawLine(xMiddle, yMiddle - halfHeight, @@ -605,7 +605,7 @@ def EventFlagsToSelType(style, shiftDown=False, ctrlDown=False): :param bool `ctrlDown`: ``True`` if the ``Ctrl`` key is pressed, ``False`` otherwise; :return: A 3-elements tuple, with the following elements: - + - `is_multiple`: ``True`` if :class:`CustomTreeCtrl` has the ``TR_MULTIPLE`` flag set, ``False`` otherwise; - `extended_select`: ``True`` if the ``Shift`` key is pressend and if :class:`CustomTreeCtrl` has the ``TR_MULTIPLE`` flag set, ``False`` otherwise; @@ -635,30 +635,30 @@ def ChopText(dc, text, max_size): .. versionadded:: 0.9.3 """ - + # first check if the text fits with no problems x, y, dummy = dc.GetFullMultiLineTextExtent(text) - + if x <= max_size: return text textLen = len(text) last_good_length = 0 - + for i in range(textLen, -1, -1): s = text[0:i] s += "..." x, y = dc.GetTextExtent(s) last_good_length = i - + if x < max_size: break - ret = text[0:last_good_length] + "..." + ret = text[0:last_good_length] + "..." return ret - + #--------------------------------------------------------------------------- # DragImage Implementation # This Class Handles The Creation Of A Custom Image In Case Of Item Drag @@ -679,7 +679,7 @@ class DragImage(wx.DragImage): :param `treeCtrl`: the parent :class:`CustomTreeCtrl`; :param `item`: one of the tree control item (an instance of :class:`GenericTreeItem`). """ - + text = item.GetText() font = item.Attr().GetFont() colour = item.Attr().GetTextColour() @@ -687,7 +687,7 @@ class DragImage(wx.DragImage): colour = wx.BLACK if not font: font = treeCtrl._normalFont - + backcolour = treeCtrl.GetBackgroundColour() r, g, b = int(backcolour.Red()), int(backcolour.Green()), int(backcolour.Blue()) backcolour = ((r >> 1) + 20, (g >> 1) + 20, (b >> 1) + 20) @@ -697,7 +697,7 @@ class DragImage(wx.DragImage): tempdc = wx.ClientDC(treeCtrl) tempdc.SetFont(font) width, height, dummy = tempdc.GetFullMultiLineTextExtent(text + "M") - + image = item.GetCurrentImage() image_w, image_h = 0, 0 @@ -708,13 +708,13 @@ class DragImage(wx.DragImage): yimagepos = 0 xcheckpos = 0 ycheckpos = 0 - - if image != _NO_IMAGE: + + if image != _NO_IMAGE: if treeCtrl._imageListNormal: image_w, image_h = treeCtrl._imageListNormal.GetSize(image) image_w += 4 itemimage = treeCtrl._imageListNormal.GetBitmap(image) - + checkimage = item.GetCurrentCheckedImage() if checkimage is not None: @@ -725,7 +725,7 @@ class DragImage(wx.DragImage): total_h = max(hcheck, height) total_h = max(image_h, total_h) - + if image_w: ximagepos = wcheck yimagepos = ((total_h > image_h) and [(total_h-image_h)//2] or [0])[0] @@ -735,13 +735,13 @@ class DragImage(wx.DragImage): ycheckpos = ((total_h > image_h) and [(total_h-image_h)//2] or [0])[0] + 2 extraH = ((total_h > height) and [(total_h - height)//2] or [0])[0] - + xtextpos = wcheck + image_w ytextpos = extraH total_h = max(image_h, hcheck) total_h = max(total_h, height) - + if total_h < 30: total_h += 2 # at least 2 pixels else: @@ -765,7 +765,7 @@ class DragImage(wx.DragImage): self._textwidth = width self._textheight = height self._extraH = extraH - + self._bitmap = self.CreateBitmap() wx.DragImage.__init__(self, self._bitmap) @@ -803,7 +803,7 @@ class DragImage(wx.DragImage): memory.DrawLabel(self._text, textrect) memory.SelectObject(wx.NullBitmap) - + # Gtk and Windows unfortunatly don't do so well with transparent # drawing so this hack corrects the image to have a transparent # background. @@ -819,9 +819,9 @@ class DragImage(wx.DragImage): if pix == self._backgroundColour: timg.SetAlpha(x, y, 0) bitmap = timg.ConvertToBitmap() - return bitmap + return bitmap + - # ---------------------------------------------------------------------------- # TreeItemAttr: a structure containing the visual attributes of an item # ---------------------------------------------------------------------------- @@ -832,19 +832,21 @@ class TreeItemAttr(object): :note: This class is inspired by the wxWidgets generic implementation of :class:`TreeItemAttr`. """ - - def __init__(self, colText=wx.NullColour, colBack=wx.NullColour, font=wx.NullFont): + + def __init__(self, colText=wx.NullColour, colBack=wx.NullColour, colBorder=wx.NullColour,font=wx.NullFont): """ Default class constructor. For internal use: do not call it in your code! :param `colText`: the text colour, an instance of :class:`Colour`; :param `colBack`: the tree item background colour, an instance of :class:`Colour`; + :param `colBorder`: the tree item border colour, an instance of :class:`Colour`; :param `font`: the tree item font, an instance of :class:`Font`. """ - + self._colText = colText self._colBack = colBack + self._colBorder = colBorder self._font = font # setters @@ -854,7 +856,7 @@ class TreeItemAttr(object): :param `colText`: an instance of :class:`Colour`. """ - + self._colText = colText @@ -864,20 +866,32 @@ class TreeItemAttr(object): :param `colBack`: an instance of :class:`Colour`. """ - + self._colBack = colBack - + + def SetBorderColour(self, colBorder): + """ + Sets the item border colour attribute. + + :param `colBack`: an instance of :class:`Colour`. + + .. versionadded:: 0.9.6 + """ + + self._colBorder = colBorder + + def SetFont(self, font): """ Sets the item font attribute. :param `font`: an instance of :class:`Font`. """ - + self._font = font - + # accessors def HasTextColour(self): """ @@ -885,7 +899,7 @@ class TreeItemAttr(object): :return: ``True`` if the text colour attribute has been set, ``False`` otherwise. """ - + return self._colText != wx.NullColour @@ -895,10 +909,22 @@ class TreeItemAttr(object): :return: ``True`` if the background colour attribute has been set, ``False`` otherwise. """ - + return self._colBack != wx.NullColour + def HasBorderColour(self): + """ + Returns whether the attribute has border colour. + + :return: ``True`` if the border colour attribute has been set, ``False`` otherwise. + + .. versionadded:: 0.9.6 + """ + + return self._colBorder != wx.NullColour + + def HasFont(self): """ Returns whether the attribute has font. @@ -916,10 +942,10 @@ class TreeItemAttr(object): :return: An instance of :class:`Colour`. """ - + return self._colText - + def GetBackgroundColour(self): """ Returns the attribute background colour. @@ -929,7 +955,19 @@ class TreeItemAttr(object): return self._colBack - + + def GetBorderColour(self): + """ + Returns the attribute border colour. + + :return: An instance of :class:`Colour`. + + .. versionadded:: 0.9.6 + """ + + return self._colBorder + + def GetFont(self): """ Returns the attribute font. @@ -944,16 +982,16 @@ class TreeItemAttr(object): # CommandTreeEvent Is A Special Subclassing Of wx.CommandEvent # # NB: Note That Not All The Accessors Make Sense For All The Events, See The -# Event Description Below. +# Event Description Below. # ---------------------------------------------------------------------------- class CommandTreeEvent(wx.CommandEvent): """ :class:`CommandTreeEvent` is a special subclassing of :class:`CommandEvent`. - :note: Not all the accessors make sense for all the events, see the event description for every method in this class. + :note: Not all the accessors make sense for all the events, see the event description for every method in this class. """ - + def __init__(self, evtType, evtId, item=None, evtKey=None, point=None, label=None, **kwargs): """ @@ -973,7 +1011,7 @@ class CommandTreeEvent(wx.CommandEvent): self._evtKey = evtKey self._pointDrag = point self._label = label - + def GetItem(self): """ @@ -982,16 +1020,16 @@ class CommandTreeEvent(wx.CommandEvent): :return: An instance of :class:`GenericTreeItem`. """ - + return self._item - + def SetItem(self, item): """ Sets the item on which the operation was performed or the newly selected item for ``EVT_TREE_SEL_CHANGED`` and ``EVT_TREE_SEL_CHANGING`` events. - :param `item`: an instance of :class:`GenericTreeItem`. + :param `item`: an instance of :class:`GenericTreeItem`. """ self._item = item @@ -1006,16 +1044,16 @@ class CommandTreeEvent(wx.CommandEvent): """ return self._itemOld - + def SetOldItem(self, item): """ Returns the previously selected item for ``EVT_TREE_SEL_CHANGED`` and ``EVT_TREE_SEL_CHANGING`` events. - :param `item`: an instance of :class:`GenericTreeItem`. + :param `item`: an instance of :class:`GenericTreeItem`. """ - + self._itemOld = item @@ -1030,16 +1068,16 @@ class CommandTreeEvent(wx.CommandEvent): return self._pointDrag - + def SetPoint(self, pt): """ Sets the point where the mouse was when the drag operation started (for ``EVT_TREE_BEGIN_DRAG`` and ``EVT_TREE_BEGIN_RDRAG`` events only) or the click position. - :param `pt`: an instance of :class:`Point`. + :param `pt`: an instance of :class:`Point`. """ - + self._pointDrag = pt @@ -1049,7 +1087,7 @@ class CommandTreeEvent(wx.CommandEvent): :return: An instance of :class:`KeyEvent`. """ - + return self._evtKey @@ -1059,17 +1097,17 @@ class CommandTreeEvent(wx.CommandEvent): non-ASCII events return values such as ``wx.WXK_LEFT`` for the left cursor key. This method is for ``EVT_TREE_KEY_DOWN`` events only. - + :return: An integer representing the virtual key code. :note: In Unicode build, the returned value is meaningful only if the user entered a character that can be represented in current locale's default charset. You can - obtain the corresponding Unicode character using `GetUnicodeKey`. + obtain the corresponding Unicode character using `GetUnicodeKey`. """ return self._evtKey.GetKeyCode() - + def SetKeyEvent(self, event): """ Sets the keyboard data (for ``EVT_TREE_KEY_DOWN`` event only). @@ -1078,7 +1116,7 @@ class CommandTreeEvent(wx.CommandEvent): """ self._evtKey = event - + def GetLabel(self): """ @@ -1090,13 +1128,13 @@ class CommandTreeEvent(wx.CommandEvent): return self._label - + def SetLabel(self, label): """ Sets the item text (for ``EVT_TREE_BEGIN_LABEL_EDIT`` and ``EVT_TREE_END_LABEL_EDIT`` events only). - :param string `label`: a string containing the new item text. + :param string `label`: a string containing the new item text. """ self._label = label @@ -1118,7 +1156,7 @@ class CommandTreeEvent(wx.CommandEvent): Sets the edit cancel flag (for ``EVT_TREE_BEGIN_LABEL_EDIT`` and ``EVT_TREE_END_LABEL_EDIT`` events only). - :param bool `editCancelled`: ``True`` to cancel the editing, ``False`` otherwise. + :param bool `editCancelled`: ``True`` to cancel the editing, ``False`` otherwise. """ self._editCancelled = editCancelled @@ -1133,7 +1171,7 @@ class CommandTreeEvent(wx.CommandEvent): self._label = toolTip - + def GetToolTip(self): """ Returns the tooltip for the item (for ``EVT_TREE_ITEM_GETTOOLTIP`` events). @@ -1142,7 +1180,7 @@ class CommandTreeEvent(wx.CommandEvent): """ return self._label - + # ---------------------------------------------------------------------------- # TreeEvent is a special class for all events associated with tree controls @@ -1154,7 +1192,7 @@ class CommandTreeEvent(wx.CommandEvent): class TreeEvent(CommandTreeEvent): """ :class:`CommandTreeEvent` is a special class for all events associated with tree controls. - + :note: Not all accessors make sense for all events, see the event descriptions below. """ def __init__(self, evtType, evtId, item=None, evtKey=None, point=None, @@ -1181,7 +1219,7 @@ class TreeEvent(CommandTreeEvent): :return: An instance of :class:`NotifyEvent`. """ - + return self.notify @@ -1215,8 +1253,8 @@ class TreeEvent(CommandTreeEvent): """ self.notify.Allow() - - + + # ----------------------------------------------------------------------------- # Auxiliary Classes: TreeEditTimer # ----------------------------------------------------------------------------- @@ -1231,9 +1269,9 @@ class TreeEditTimer(wx.Timer): :param `owner`: the :class:`Timer` owner (an instance of :class:`CustomTreeCtrl`). """ - + wx.Timer.__init__(self) - self._owner = owner + self._owner = owner def Notify(self): @@ -1270,7 +1308,7 @@ class TreeTextCtrl(ExpandoTextCtrl): :raise: `Exception` when the item has an associated image but the parent :class:`CustomTreeCtrl` does not have a :class:`ImageList` assigned. """ - + self._owner = owner self._itemEdited = item self._startValue = item.GetText() @@ -1294,13 +1332,13 @@ class TreeTextCtrl(ExpandoTextCtrl): image = item.GetCurrentImage() if image != _NO_IMAGE: - + if self._owner._imageListNormal: image_w, image_h = self._owner._imageListNormal.GetSize(image) image_w += 4 - + else: - + raise Exception("\n ERROR: You Must Create An Image List To Use Images!") checkimage = item.GetCurrentCheckedImage() @@ -1316,7 +1354,7 @@ class TreeTextCtrl(ExpandoTextCtrl): dc = wx.ClientDC(self._owner) h = max(h, dc.GetTextExtent("Aq")[1]) h = h + 2 - + # FIXME: what are all these hardcoded 4, 8 and 11s really? x += image_w + wcheck w -= image_w + 4 + wcheck @@ -1328,7 +1366,7 @@ class TreeTextCtrl(ExpandoTextCtrl): else: expandoStyle |= wx.SUNKEN_BORDER xSize, ySize = w + 25, h+2 - + ExpandoTextCtrl.__init__(self, self._owner, wx.ID_ANY, self._startValue, wx.Point(x - 4, y), wx.Size(xSize, ySize), expandoStyle) @@ -1337,11 +1375,11 @@ class TreeTextCtrl(ExpandoTextCtrl): 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) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) - + def AcceptChanges(self): """ @@ -1368,18 +1406,18 @@ class TreeTextCtrl(ExpandoTextCtrl): # accepted, do rename the item self._owner.SetItemText(self._itemEdited, value) - + return True def Finish(self): """ Finish editing. """ - if not self._finished: + if not self._finished: self._finished = True self._owner.SetFocusIgnoringChildren() self._owner.ResetEditControl() - + def OnChar(self, event): """ @@ -1407,7 +1445,7 @@ class TreeTextCtrl(ExpandoTextCtrl): else: event.Skip() - + def OnKeyUp(self, event): """ @@ -1430,7 +1468,7 @@ class TreeTextCtrl(ExpandoTextCtrl): sx = parentSize.x - myPos.x if mySize.x > sx: sx = mySize.x - + self.SetSize((sx, -1)) self._currentValue = self.GetValue() @@ -1443,15 +1481,15 @@ class TreeTextCtrl(ExpandoTextCtrl): :param `event`: a :class:`FocusEvent` event to be processed. """ - + if not self._finished and not self._aboutToFinish: - + # We must finish regardless of success, otherwise we'll get # focus problems: - + if not self.AcceptChanges(): 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). event.Skip() @@ -1462,8 +1500,8 @@ class TreeTextCtrl(ExpandoTextCtrl): self._owner.OnCancelEdit(self._itemEdited) self.Finish() - - + + def item(self): """ Returns the item currently edited. @@ -1471,7 +1509,7 @@ class TreeTextCtrl(ExpandoTextCtrl): :return: An instance of :class:`GenericTreeItem`. """ - return self._itemEdited + return self._itemEdited # ----------------------------------------------------------------------------- @@ -1491,7 +1529,7 @@ class TreeFindTimer(wx.Timer): Default class constructor. For internal use: do not call it in your code! - :param `owner`: the :class:`Timer` owner (an instance of :class:`CustomTreeCtrl`). + :param `owner`: the :class:`Timer` owner (an instance of :class:`CustomTreeCtrl`). """ wx.Timer.__init__(self) @@ -1515,7 +1553,7 @@ class GenericTreeItem(object): This class holds all the information and methods for every single item in :class:`CustomTreeCtrl`. This is a generic implementation of :class:`TreeItem`. """ - + def __init__(self, parent, text="", ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False): """ Default class constructor. @@ -1542,11 +1580,11 @@ class GenericTreeItem(object): use for the item in selected state; if `image` > -1 and `selImage` is -1, the same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; - :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. + :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. :note: Regarding radiobutton-type items (with `ct_type` = 2), the following approach is used: - + - All peer-nodes that are radiobuttons will be mutually exclusive. In other words, only one of a set of radiobuttons that share a common parent can be checked at once. If a radiobutton node becomes checked, then all of its peer radiobuttons @@ -1557,7 +1595,7 @@ class GenericTreeItem(object): :note: Separator items should not have children, labels, data or an associated window. Other issues/features associated to separator items: - + - You can change the color of individual separators by using :meth:`CustomTreeCtrl.SetItemTextColour() `, or you can use :meth:`CustomTreeCtrl.SetSeparatorColour() ` to change the color of all separators. The default separator colour is that returned by `SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)`; @@ -1567,7 +1605,7 @@ class GenericTreeItem(object): - Separators cannot be edited via the ``EVT_TREE_BEGIN_LABEL_EDIT`` event. """ - + # since there can be very many of these, we save size by chosing # the smallest representation for the elements and by ordering # the members to avoid padding. @@ -1579,7 +1617,7 @@ class GenericTreeItem(object): self._attr = None # attributes??? - self._separator = separator + self._separator = separator # tree ctrl images for the normal, selected, expanded and # expanded+selected states @@ -1618,7 +1656,7 @@ class GenericTreeItem(object): self._checkedimages[TreeItemIcon_Undetermined] = 2 self._checkedimages[TreeItemIcon_Flagged] = 3 self._checkedimages[TreeItemIcon_NotFlagged] = 4 - + if parent: if parent.GetType() == 2 and not parent.IsChecked(): # if the node parent is a radio not enabled, we are disabled @@ -1628,7 +1666,7 @@ class GenericTreeItem(object): if wnd: self.SetWindow(wnd) - + def IsOk(self): """ @@ -1637,9 +1675,9 @@ class GenericTreeItem(object): :note: This method always returns ``True``, it has been added for backward compatibility with the wxWidgets C++ implementation. """ - + return True - + def IsSeparator(self): """ @@ -1649,7 +1687,7 @@ class GenericTreeItem(object): """ return self._separator - + def GetChildren(self): """ @@ -1659,7 +1697,7 @@ class GenericTreeItem(object): this item's children. """ - return self._children + return self._children def GetText(self): @@ -1669,7 +1707,7 @@ class GenericTreeItem(object): :return: A string containing the item text. """ - return self._text + return self._text def GetImage(self, which=TreeItemIcon_Normal): @@ -1684,14 +1722,14 @@ class GenericTreeItem(object): ``TreeItemIcon_Normal`` To get the normal item image ``TreeItemIcon_Selected`` To get the selected item image (i.e. the image which is shown when the item is currently selected) ``TreeItemIcon_Expanded`` To get the expanded image (this only makes sense for items which have children - then this image is shown when the item is expanded and the normal image is shown when it is collapsed) - ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) + ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) ================================= ======================== :return: An integer index that can be used to retrieve the item image inside a :class:`ImageList`. """ - - return self._images[which] + + return self._images[which] def GetCheckedImage(self, which=TreeItemIcon_Checked): @@ -1729,7 +1767,7 @@ class GenericTreeItem(object): """ return self._leftimage - + def GetData(self): """ @@ -1738,8 +1776,8 @@ class GenericTreeItem(object): :return: A Python object representing the item data, or ``None`` if no data has been assigned to this item. """ - - return self._data + + return self._data def SetImage(self, image, which): @@ -1748,7 +1786,7 @@ class GenericTreeItem(object): :param integer `image`: an index within the normal image list specifying the image to use; :param integer `which`: the image kind. - + :see: :meth:`~GenericTreeItem.GetImage` for a description of the `which` parameter. """ @@ -1766,7 +1804,7 @@ class GenericTreeItem(object): self._leftimage = image - + def SetData(self, data): """ Sets the data associated to this item. @@ -1774,7 +1812,7 @@ class GenericTreeItem(object): :param object `data`: can be any Python object. """ - self._data = data + self._data = data def SetHasPlus(self, has=True): @@ -1784,7 +1822,7 @@ class GenericTreeItem(object): :param bool `has`: ``True`` to set the 'plus' button on the item, ``False`` otherwise. """ - self._hasPlus = has + self._hasPlus = has def SetBold(self, bold): @@ -1794,7 +1832,7 @@ class GenericTreeItem(object): :parameter bool `bold`: ``True`` to have a bold font item, ``False`` otherwise. """ - self._isBold = bold + self._isBold = bold def SetItalic(self, italic): @@ -1805,18 +1843,18 @@ class GenericTreeItem(object): """ self._isItalic = italic - + def GetX(self): """ Returns the `x` position on an item, in logical coordinates. """ - return self._x + return self._x def GetY(self): """ Returns the `y` position on an item, in logical coordinates. """ - return self._y + return self._y def SetX(self, x): @@ -1826,7 +1864,7 @@ class GenericTreeItem(object): :param integer `x`: an integer specifying the x position of the item. """ - self._x = x + self._x = x def SetY(self, y): @@ -1836,19 +1874,19 @@ class GenericTreeItem(object): :param integer `y`: an integer specifying the y position of the item. """ - self._y = y + self._y = y def GetHeight(self): """ Returns the height of the item, in pixels. """ - return self._height + return self._height def GetWidth(self): """ Returns the width of the item, in pixels. """ - return self._width + return self._width def SetHeight(self, h): @@ -1860,7 +1898,7 @@ class GenericTreeItem(object): self._height = h - + def SetWidth(self, w): """ Sets the item's width. @@ -1868,7 +1906,7 @@ class GenericTreeItem(object): :param integer `w`: an integer specifying the item's width, in pixels. """ - self._width = w + self._width = w def SetWindow(self, wnd): @@ -1896,16 +1934,16 @@ class GenericTreeItem(object): # 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 + # The window is enabled only if the item is enabled self._wnd.Enable(self._enabled) self._windowenabled = self._enabled @@ -1917,7 +1955,7 @@ class GenericTreeItem(object): :return: An instance of any :class:`Window` derived class, excluding top-level windows. """ - return self._wnd + return self._wnd def DeleteWindow(self): @@ -1926,7 +1964,7 @@ class GenericTreeItem(object): if self._wnd: self._wnd.Destroy() self._wnd = None - + def GetWindowEnabled(self): """ @@ -1961,15 +1999,15 @@ class GenericTreeItem(object): def GetWindowSize(self): """ Returns the associated window size. """ - - return self._windowsize + + return self._windowsize def OnSetFocus(self, event): """ Handles the ``wx.EVT_SET_FOCUS`` event for the window associated with the item. - :param `event`: a :class:`FocusEvent` event to be processed. + :param `event`: a :class:`FocusEvent` event to be processed. """ treectrl = self._wnd.GetParent() @@ -1981,7 +2019,7 @@ class GenericTreeItem(object): treectrl._hasFocus = False else: treectrl._hasFocus = True - + event.Skip() @@ -1989,11 +2027,11 @@ class GenericTreeItem(object): """ Returns the item type. - :see: :meth:`~GenericTreeItem.SetType` and :meth:`~GenericTreeItem.__init__` for a description of valid item types. + :see: :meth:`~GenericTreeItem.SetType` and :meth:`~GenericTreeItem.__init__` for a description of valid item types. """ return self._type - + def SetType(self, ct_type): """ @@ -2011,7 +2049,7 @@ class GenericTreeItem(object): :note: Regarding radiobutton-type items (with `ct_type` = 2), the following approach is used: - + - All peer-nodes that are radiobuttons will be mutually exclusive. In other words, only one of a set of radiobuttons that share a common parent can be checked at once. If a radiobutton node becomes checked, then all of its peer radiobuttons @@ -2029,7 +2067,7 @@ class GenericTreeItem(object): :param bool `hyper`: ``True`` to set hypertext behaviour, ``False`` otherwise. """ - + self._hypertext = hyper @@ -2046,24 +2084,24 @@ class GenericTreeItem(object): def GetVisited(self): """ Returns whether an hypertext item was visited or not. """ - return self._visited + return self._visited def IsHyperText(self): """ Returns whether the item is hypetext or not. """ return self._hypertext - + def GetParent(self): """ Gets the item parent (another instance of :class:`GenericTreeItem` or ``None`` for root items. - :return: An instance of :class:`GenericTreeItem` or ``None`` for root items. + :return: An instance of :class:`GenericTreeItem` or ``None`` for root items. """ - return self._parent + return self._parent def Insert(self, child, index): @@ -2073,30 +2111,30 @@ class GenericTreeItem(object): :param `child`: an instance of :class:`GenericTreeItem`; :param integer `index`: the index at which we should insert the new child. """ - - self._children.insert(index, child) + + self._children.insert(index, child) def Expand(self): """ Expands the item. """ - self._isCollapsed = False - + self._isCollapsed = False + def Collapse(self): """ Collapses the item. """ self._isCollapsed = True - + def SetHilight(self, set=True): """ Sets the item focus/unfocus. - :param bool `set`: ``True`` to set the focus to the item, ``False`` otherwise. + :param bool `set`: ``True`` to set the focus to the item, ``False`` otherwise. """ - self._hasHilight = set + self._hasHilight = set def HasChildren(self): @@ -2116,7 +2154,7 @@ class GenericTreeItem(object): :return: ``True`` if the item is selected, ``False`` otherwise. """ - return self._hasHilight != 0 + return self._hasHilight != 0 def IsExpanded(self): @@ -2126,7 +2164,7 @@ class GenericTreeItem(object): :return: ``True`` if the item is expanded, ``False`` if it is collapsed. """ - return not self._isCollapsed + return not self._isCollapsed def GetValue(self): @@ -2138,8 +2176,8 @@ class GenericTreeItem(object): if self.Is3State(): return self.Get3StateValue() - - return self._checked + + return self._checked def Get3StateValue(self): @@ -2148,7 +2186,7 @@ class GenericTreeItem(object): :return: ``wx.CHK_UNCHECKED`` when the checkbox is unchecked, ``wx.CHK_CHECKED`` when it is checked and ``wx.CHK_UNDETERMINED`` when it's in the undetermined - state. + state. :raise: `Exception` when the item is not a 3-state checkbox item. @@ -2161,7 +2199,7 @@ class GenericTreeItem(object): if not self.Is3State(): raise Exception("Get3StateValue can only be used with 3-state checkbox items.") - return self._checked + return self._checked def Is3State(self): @@ -2175,7 +2213,7 @@ class GenericTreeItem(object): """ return self._is3State - + def Set3StateValue(self, state): """ @@ -2215,7 +2253,7 @@ class GenericTreeItem(object): self._is3State = allow return True - + def IsChecked(self): """ @@ -2232,12 +2270,12 @@ class GenericTreeItem(object): """ Checks/unchecks an item. - :param bool `checked`: ``True`` to check an item, ``False`` to uncheck it. + :param bool `checked`: ``True`` to check an item, ``False`` to uncheck it. :note: This is meaningful only for checkbox-like and radiobutton-like items. """ - - self._checked = checked + + self._checked = checked def HasPlus(self): @@ -2247,7 +2285,7 @@ class GenericTreeItem(object): :return: ``True`` if the item has a 'plus' mark, ``False`` otherwise. """ - return self._hasPlus or self.HasChildren() + return self._hasPlus or self.HasChildren() def IsBold(self): @@ -2257,7 +2295,7 @@ class GenericTreeItem(object): :return: ``True`` if the item has bold text, ``False`` otherwise. """ - return self._isBold != 0 + return self._isBold != 0 def IsItalic(self): @@ -2267,7 +2305,7 @@ class GenericTreeItem(object): :return: ``True`` if the item has italic text, ``False`` otherwise. """ - return self._isItalic != 0 + return self._isItalic != 0 def Enable(self, enable=True): @@ -2288,7 +2326,7 @@ class GenericTreeItem(object): """ return self._enabled - + def GetAttributes(self): """ @@ -2297,7 +2335,7 @@ class GenericTreeItem(object): :return: An instance of :class:`TreeItemAttr`. """ - return self._attr + return self._attr def Attr(self): @@ -2306,36 +2344,36 @@ class GenericTreeItem(object): :return: An instance of :class:`TreeItemAttr`. """ - + if not self._attr: - + self._attr = TreeItemAttr() self._ownsAttr = True - + return self._attr - + def SetAttributes(self, attr): """ Sets the item attributes (font, colours, etc...). :param `attr`: an instance of :class:`TreeItemAttr`. """ - + if self._ownsAttr: del self._attr - + self._attr = attr self._ownsAttr = False - + def AssignAttributes(self, attr): """ Assigns the item attributes (font, colours, etc...) for this item. :param `attr`: an instance of :class:`TreeItemAttr`. """ - + self.SetAttributes(attr) self._ownsAttr = True @@ -2352,7 +2390,7 @@ class GenericTreeItem(object): tree.SendDeleteEvent(child) child.DeleteChildren(tree) - + if child == tree._select_me: tree._select_me = None @@ -2364,9 +2402,9 @@ class GenericTreeItem(object): if child in tree._itemWithWindow: tree._itemWithWindow.remove(child) - + del child - + self._children = [] @@ -2376,7 +2414,7 @@ class GenericTreeItem(object): :param string `text`: the new item label. - :raise: `Exception` if the item is a separator. + :raise: `Exception` if the item is a separator. """ if self.IsSeparator(): @@ -2394,7 +2432,7 @@ class GenericTreeItem(object): """ count = len(self._children) - + if not recursively: return count @@ -2402,7 +2440,7 @@ class GenericTreeItem(object): for n in range(count): total += self._children[n].GetChildrenCount() - + return total @@ -2424,15 +2462,15 @@ class GenericTreeItem(object): y = bottomY width = self._x + self._width - + if x < width: x = width if self.IsExpanded(): for child in self._children: x, y = child.GetSize(x, y, theButton) - - return x, y + + return x, y def HitTest(self, point, theCtrl, flags=0, level=0): @@ -2443,18 +2481,18 @@ class GenericTreeItem(object): :param `theCtrl`: the main :class:`CustomTreeCtrl` tree; :param integer `flags`: a bitlist of hit locations; :param integer `level`: the item's level inside the tree hierarchy. - + :see: :meth:`CustomTreeCtrl.HitTest() ` method for the flags explanation. """ - + # for a hidden root node, don't evaluate it, but do evaluate children if not (level == 0 and theCtrl.HasAGWFlag(TR_HIDE_ROOT)): - + # evaluate the item h = theCtrl.GetLineHeight(self) - + if point.y > self._y and point.y < self._y + h: - + y_mid = self._y + h//2 if point.y < y_mid: @@ -2513,13 +2551,13 @@ class GenericTreeItem(object): flags |= TREE_HITTEST_ONITEM else: flags |= TREE_HITTEST_ONITEMRIGHT - + return self, flags - + # if children are expanded, fall through to evaluate them if self._isCollapsed: return None, 0 - + # evaluate children for child in self._children: res, flags = child.HitTest(point, theCtrl, flags, level + 1) @@ -2538,24 +2576,24 @@ class GenericTreeItem(object): """ image = _NO_IMAGE - + if self.IsExpanded(): - + if self.IsSelected(): - + image = self._images[TreeItemIcon_SelectedExpanded] if image == _NO_IMAGE: - + # we usually fall back to the normal item, but try just the # expanded one (and not selected) first in this case image = self._images[TreeItemIcon_Expanded] - + else: # not expanded - + if self.IsSelected(): image = self._images[TreeItemIcon_Selected] - + # maybe it doesn't have the specific image we want, # try the default one instead if image == _NO_IMAGE: @@ -2576,13 +2614,13 @@ class GenericTreeItem(object): return None checked = self.IsChecked() - + if checked > 0: if self._type == 1: # Checkbox if checked == wx.CHK_CHECKED: return self._checkedimages[TreeItemIcon_Checked] else: - return self._checkedimages[TreeItemIcon_Undetermined] + return self._checkedimages[TreeItemIcon_Undetermined] else: # Radiobutton return self._checkedimages[TreeItemIcon_Flagged] else: @@ -2590,7 +2628,7 @@ class GenericTreeItem(object): return self._checkedimages[TreeItemIcon_NotChecked] else: # Radiobutton return self._checkedimages[TreeItemIcon_NotFlagged] - + # ----------------------------------------------------------------------------- # CustomTreeCtrl Main Implementation. @@ -2609,7 +2647,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): name="CustomTreeCtrl"): """ Default class constructor. - + :param Window `parent`: parent window. Must not be ``None``; :param integer `id`: window identifier. A value of -1 indicates a default value; :param `pos`: the control position. A value of (-1, -1) indicates a default position, @@ -2621,7 +2659,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param integer `style`: the underlying :class:`ScrolledWindow` style; :param integer `agwStyle`: the AGW-specific window style for :class:`CustomTreeCtrl`. It can be a combination of the following bits: - + ============================== =========== ================================================== Window Styles Hex Value Description ============================== =========== ================================================== @@ -2651,7 +2689,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param Validator `validator`: window validator; :param string `name`: window name. """ - + self._current = self._key_current = self._anchor = self._select_me = None self._hasFocus = False self._dirty = False @@ -2686,11 +2724,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._dragImage = None self._underMouse = None - # EditCtrl initial settings for editable items + # EditCtrl initial settings for editable items self._editCtrl = None self._editTimer = None - # This one allows us to handle Freeze() and Thaw() calls + # This one allows us to handle Freeze() and Thaw() calls self._freezeCount = 0 self._findPrefix = "" @@ -2720,17 +2758,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._hypertextvisitedcolour = wx.Colour(200, 47, 200) self._isonhyperlink = False - # Default CustomTreeCtrl background colour. + # Default CustomTreeCtrl background colour. self._backgroundColour = wx.WHITE - + # Background image settings self._backgroundImage = None self._imageStretchStyle = _StyleTile - # Disabled items colour + # Disabled items colour self._disabledColour = wx.Colour(180, 180, 180) - # Gradient selection colours + # Gradient selection colours self._firstcolour = colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT) self._secondcolour = wx.WHITE self._usegradients = False @@ -2754,15 +2792,15 @@ class CustomTreeCtrl(wx.ScrolledWindow): # Pen Used To Draw The Border Around Selected Items self._borderPen = wx.BLACK_PEN self._cursor = wx.Cursor(wx.CURSOR_ARROW) - + # For Appended Windows self._hasWindows = False self._itemWithWindow = [] - + if wx.Platform == "__WXMAC__": agwStyle &= ~TR_LINES_AT_ROOT agwStyle |= TR_NO_LINES - + platform, major, minor = wx.GetOsVersion() if major < 10: agwStyle |= TR_ROW_LINES @@ -2777,12 +2815,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): # Set the separator pen default colour self._separatorPen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)) - # Create our container... at last! + # Create our container... at last! wx.ScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) self._agwStyle = agwStyle - - # Create the default check image list + + # Create the default check image list self.SetImageListCheck(16, 16) # If the tree display has no buttons, but does have @@ -2791,13 +2829,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): if not self.HasButtons() and not self.HasAGWFlag(TR_NO_LINES): self._indent= 10 self._spacing = 10 - + self.SetValidator(validator) attr = self.GetDefaultAttributes() self.SetOwnForegroundColour(attr.colFg) self.SetOwnBackgroundColour(attr.colBg) - + if not self._hasFont: self.SetOwnFont(attr.font) @@ -2833,13 +2871,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): # participate in the tab-order, etc. It's overridable because # of deriving this class from wx.ScrolledWindow... return True - + def OnDestroy(self, event): """ Handles the ``wx.EVT_WINDOW_DESTROY`` event for :class:`CustomTreeCtrl`. - :param `event`: a :class:`WindowDestroyEvent` event to be processed. + :param `event`: a :class:`WindowDestroyEvent` event to be processed. """ # Here there may be something I miss... do I have to destroy @@ -2859,14 +2897,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): def GetControlBmp(self, checkbox=True, checked=False, enabled=True, x=16, y=16): """ Returns a native looking checkbox or radio button bitmap. - + :param bool `checkbox`: ``True`` to get a checkbox image, ``False`` for a radiobutton one; :param bool `checked`: ``True`` if the control is marked, ``False`` if it is not; :param bool `enabled`: ``True`` if the control is enabled, ``False`` if it is not; :param integer `x`: the width of the bitmap; :param integer `y`: the height of the bitmap. - :return: An instance of :class:`Bitmap`, representing a native looking checkbox or radiobutton. + :return: An instance of :class:`Bitmap`, representing a native looking checkbox or radiobutton. """ bmp = wx.Bitmap(x, y) @@ -2874,7 +2912,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): mask = wx.Colour(0xfe, 0xfe, 0xfe) mdc.SetBackground(wx.Brush(mask)) mdc.Clear() - + render = wx.RendererNative.Get() if checked == wx.CHK_CHECKED: @@ -2908,11 +2946,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): return 0 count = self._anchor.GetChildrenCount() - + if not self.HasAGWFlag(TR_HIDE_ROOT): # take the root itself into account count = count + 1 - + return count @@ -2921,7 +2959,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): return self._indent - + def GetSpacing(self): """ Returns the spacing between the start and the text, in pixels. """ @@ -2939,7 +2977,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): Returns the current selection. :return: An instance of :class:`GenericTreeItem`. - + :note: This method is valid only with the style ``TR_SINGLE`` set. Use @@ -2955,7 +2993,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. """ - + self.SelectItem(item, not self.IsSelected(item)) @@ -2966,7 +3004,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`; :param bool `enable`: ``True`` to enable the children, ``False`` to disable them. - :note: This method is used internally. + :note: This method is used internally. """ torefresh = False @@ -2977,7 +3015,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # We hit a radiobutton item not checked, we don't want to # enable the children return - + child, cookie = self.GetFirstChild(item) while child: self.EnableItem(child, enable, torefresh=torefresh) @@ -3005,17 +3043,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.Enable(enable) wnd = item.GetWindow() - # Handles the eventual window associated to the item + # Handles the eventual window associated to the item if wnd: wndenable = item.GetWindowEnabled() wnd.Enable(enable) - + if torefresh: # We have to refresh the item line dc = wx.ClientDC(self) self.CalculateSize(item, dc) self.RefreshLine(item) - + def IsItemEnabled(self, item): """ @@ -3024,7 +3062,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. """ - return item.IsEnabled() + return item.IsEnabled() def SetDisabledColour(self, colour): @@ -3033,7 +3071,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `colour`: a valid :class:`Colour` instance. """ - + self._disabledColour = colour self._dirty = True @@ -3045,8 +3083,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`Colour`. """ - return self._disabledColour - + return self._disabledColour + def IsItemChecked(self, item): """ @@ -3055,7 +3093,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. :return: ``True`` if the item is in a 'checked' state, ``False`` otherwise. - + :note: This method is meaningful only for checkbox-like and radiobutton-like items. """ @@ -3070,7 +3108,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: ``wx.CHK_UNCHECKED`` when the checkbox is unchecked, ``wx.CHK_CHECKED`` when it is checked and ``wx.CHK_UNDETERMINED`` when it's in the undetermined - state. + state. :note: This method raises an exception when the function is used with a 2-state checkbox item. @@ -3094,7 +3132,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ return item.Is3State() - + def SetItem3StateValue(self, item, state): """ @@ -3127,7 +3165,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ return item.Set3State(allow) - + def CheckItem2(self, item, checked=True, torefresh=False): """ @@ -3140,14 +3178,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): if item.GetType() == 0: return - + item.Check(checked) if torefresh: dc = wx.ClientDC(self) self.CalculateSize(item, dc) self.RefreshLine(item) - + def UnCheckRadioParent(self, item, checked=False): """ @@ -3160,7 +3198,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): e = TreeEvent(wxEVT_TREE_ITEM_CHECKING, self.GetId()) e.SetItem(item) e.SetEventObject(self) - + if self.GetEventHandler().ProcessEvent(e): return False @@ -3172,8 +3210,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): e.SetEventObject(self) self.GetEventHandler().ProcessEvent(e) - return True - + return True + def CheckItem(self, item, checked=True): """ @@ -3187,7 +3225,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): ``wx.CHK_UNDETERMINED`` when it's in the undetermined state. """ - # Should we raise an error here?!? + # Should we raise an error here?!? if item.GetType() == 0: return @@ -3200,21 +3238,21 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.CheckSameLevel(item, False) return - + # Radiobuttons are done, let's handle checkbuttons... e = TreeEvent(wxEVT_TREE_ITEM_CHECKING, self.GetId()) e.SetItem(item) e.SetEventObject(self) - + if self.GetEventHandler().ProcessEvent(e): # Blocked by user - return + return if item.Is3State(): item.Set3StateValue(checked) else: item.Check(checked) - + dc = wx.ClientDC(self) self.RefreshLine(item) @@ -3241,14 +3279,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: This method is meaningful only for checkbox-like and radiobutton-like items. """ - + child, cookie = self.GetFirstChild(item) torefresh = False if item.IsExpanded(): torefresh = True - # Recurse on tree + # Recurse on tree while child: if child.GetType() == 1 and child.IsEnabled(): self.CheckItem2(child, not child.IsChecked(), torefresh=torefresh) @@ -3264,14 +3302,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param bool `checked`: ``True`` to check an item, ``False`` to uncheck it. :note: This method is meaningful only for checkbox-like and radiobutton-like items. - """ + """ (child, cookie) = self.GetFirstChild(item) torefresh = False if item.IsExpanded(): torefresh = True - + while child: if child.GetType() == 1 and child.IsEnabled(): self.CheckItem2(child, checked, torefresh=torefresh) @@ -3316,7 +3354,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: This method does not generate ``EVT_TREE_ITEM_CHECKING`` and ``EVT_TREE_ITEM_CHECKED`` events. """ - + if checked == None: self.AutoToggleChild(item) else: @@ -3342,7 +3380,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): torefresh = False if parent.IsExpanded(): torefresh = True - + (child, cookie) = self.GetFirstChild(parent) while child: if child.GetType() == 2 and child != item: @@ -3358,23 +3396,23 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. """ - + self.Edit(item) - + def ShouldInheritColours(self): """ Return ``True`` from here to allow the colours of this window to be changed by `InheritAttributes`, returning ``False`` forbids inheriting them from the parent window. - + The base class version returns ``False``, but this method is overridden in :class:`Control` where it returns ``True``. :class:`CustomTreeCtrl` does not inherit colours from anyone. """ - return False + return False def SetIndent(self, indent): @@ -3394,7 +3432,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param integer `spacing`: an integer representing the spacing between items in the tree. """ - + self._spacing = spacing self._dirty = True @@ -3430,26 +3468,26 @@ class CustomTreeCtrl(wx.ScrolledWindow): :see: The :meth:`~CustomTreeCtrl.__init__` method for the `flag` parameter description. """ - return self._agwStyle & flag - + return self._agwStyle & flag + def SetAGWWindowStyleFlag(self, agwStyle): """ Sets the :class:`CustomTreeCtrl` window style. :param integer `agwStyle`: the new :class:`CustomTreeCtrl` window style. - + :see: The :meth:`~CustomTreeCtrl.__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: - + # if we will hide the root, make sure children are visible self._anchor.SetHasPlus() self._anchor.Expand() self.CalculatePositions() - + # right now, just sets the styles. Eventually, we may # want to update the inherited styles, but right now # none of the parents has updatable styles @@ -3471,7 +3509,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ return self._agwStyle - + def HasButtons(self): """ @@ -3496,7 +3534,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ return item.GetText() - + def GetItemSize(self, item): """ @@ -3506,26 +3544,26 @@ class CustomTreeCtrl(wx.ScrolledWindow): .. versionadded:: 0.9.3 """ - + w, h = self.GetClientSize() xa, ya = self.CalcScrolledPosition((0, item.GetY())) - + wcheck = image_w = 0 - + if item.GetType() != 0: wcheck, dummy = self._imageListCheck.GetSize(item.GetType()) wcheck += 4 image = item.GetCurrentImage() - - if image != _NO_IMAGE: - if self._imageListNormal: + + if image != _NO_IMAGE: + if self._imageListNormal: image_w, dummy = self._imageListNormal.GetSize(image) image_w += 4 maxsize = w - (wcheck + image_w + item.GetX()) + xa return maxsize - + def GetItemImage(self, item, which=TreeItemIcon_Normal): """ @@ -3540,11 +3578,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): ``TreeItemIcon_Normal`` To get the normal item image ``TreeItemIcon_Selected`` To get the selected item image (i.e. the image which is shown when the item is currently selected) ``TreeItemIcon_Expanded`` To get the expanded image (this only makes sense for items which have children - then this image is shown when the item is expanded and the normal image is shown when it is collapsed) - ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) + ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) ================================= ======================== :return: An integer index that can be used to retrieve the item image inside - a :class:`ImageList`. + a :class:`ImageList`. """ return item.GetImage(which) @@ -3639,12 +3677,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`; :param string `text`: the new item label. - :raise: `Exception` if the input `item` is a separator. + :raise: `Exception` if the input `item` is a separator. """ if item.IsSeparator(): raise Exception("Separator items can not have text") - + dc = wx.ClientDC(self) item.SetText(text) self.CalculateSize(item, dc) @@ -3660,7 +3698,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): use for the item in the state specified by the `which` parameter; :param integer `which`: the item state. - :see: :meth:`~CustomTreeCtrl.GetItemImage` for an explanation of the `which` parameter. + :see: :meth:`~CustomTreeCtrl.GetItemImage` for an explanation of the `which` parameter. """ item.SetImage(image, which) @@ -3699,7 +3737,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): SetItemPyData = SetPyData SetItemData = SetPyData - + def SetItemHasChildren(self, item, has=True): """ @@ -3708,7 +3746,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`; :param bool `has`: ``True`` to have a button next to an item, ``False`` otherwise. """ - + item.SetHasPlus(has) self.RefreshLine(item) @@ -3725,7 +3763,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if item.IsBold() != bold: item.SetBold(bold) self._dirty = True - + def SetItemItalic(self, item, italic=True): """ @@ -3768,7 +3806,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.Attr().SetTextColour(colour) self.RefreshLine(item) - + def SetItemBackgroundColour(self, item, colour): """ @@ -3792,7 +3830,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.SetHyperText(hyper) self.RefreshLine(item) - + def SetItemFont(self, item, font): """ @@ -3804,7 +3842,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.Attr().SetFont(font) self._dirty = True - + def SetFont(self, font): """ @@ -3812,12 +3850,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `font`: a valid :class:`Font` instance. - :note: Overridden from :class:`ScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ wx.ScrolledWindow.SetFont(self, font) - self._normalFont = font + self._normalFont = font family = self._normalFont.GetFamily() if family == wx.FONTFAMILY_UNKNOWN: @@ -3847,7 +3885,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: This method is meaningful only for hypertext-like items. """ - return self._hypertextfont + return self._hypertextfont def SetHyperTextFont(self, font): @@ -3861,7 +3899,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._hypertextfont = font self._dirty = True - + def SetHyperTextNewColour(self, colour): """ @@ -3938,7 +3976,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: This method is meaningful only for hypertext-like items. """ - return item.GetVisited() + return item.GetVisited() def SetHilightFocusColour(self, colour): @@ -3946,21 +3984,21 @@ class CustomTreeCtrl(wx.ScrolledWindow): Sets the colour used to highlight focused selected items. :param `colour`: a valid :class:`Colour` instance. - + :note: This is applied only if gradient and Windows Vista selection styles are disabled. """ self._hilightBrush = wx.Brush(colour) self.RefreshSelected() - + def SetHilightNonFocusColour(self, colour): """ Sets the colour used to highlight unfocused selected items. :param `colour`: a valid :class:`Colour` instance. - + :note: This is applied only if gradient and Windows Vista selection styles are disabled. """ @@ -3974,13 +4012,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): Returns the colour used to highlight focused selected items. :return: An instance of :class:`Colour`. - + :note: This is used only if gradient and Windows Vista selection styles are disabled. """ return self._hilightBrush.GetColour() - + def GetHilightNonFocusColour(self): """ @@ -3991,10 +4029,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: This is used only if gradient and Windows Vista selection styles are disabled. """ - + return self._hilightUnfocusedBrush.GetColour() - + def SetFirstGradientColour(self, colour=None): """ Sets the first gradient colour for gradient-style selections. @@ -4002,14 +4040,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `colour`: if not ``None``, a valid :class:`Colour` instance. Otherwise, the colour is taken from the system value ``wx.SYS_COLOUR_HIGHLIGHT``. """ - + if colour is None: colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT) self._firstcolour = colour if self._usegradients: self.RefreshSelected() - + def SetSecondGradientColour(self, colour=None): """ @@ -4040,7 +4078,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`Colour`. """ - + return self._firstcolour @@ -4050,7 +4088,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`Colour`. """ - + return self._secondcolour @@ -4068,7 +4106,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._usegradients = enable self._vistaselection = False self.RefreshSelected() - + def SetGradientStyle(self, vertical=0): """ @@ -4117,7 +4155,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): Sets the pen used to draw the selected item border. :param `pen`: an instance of :class:`Pen`. - + :note: The border pen is not used if the Windows Vista selection style is applied. """ @@ -4166,26 +4204,26 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: At present, the background image can only be used in "tile" mode. - .. todo:: Support background images also in stretch and centered modes. + .. todo:: Support background images also in stretch and centered modes. """ self._backgroundImage = image self.Refresh() - + def GetBackgroundImage(self): """ Returns the :class:`CustomTreeCtrl` background image (if any). :return: An instance of :class:`Bitmap` if a background image is present, ``None`` otherwise. - + :note: At present, the background image can only be used in "tile" mode. - .. todo:: Support background images also in stretch and centered modes. + .. todo:: Support background images also in stretch and centered modes. """ - return self._backgroundImage - + return self._backgroundImage + def SetSeparatorColour(self, colour): """ @@ -4216,7 +4254,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ return item.IsSeparator() - + def GetItemWindow(self, item): """ @@ -4224,7 +4262,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. - :return: An instance of :class:`Window` if the item has an associated window, ``None`` otherwise. + :return: An instance of :class:`Window` if the item has an associated window, ``None`` otherwise. """ return item.GetWindow() @@ -4252,12 +4290,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.DeleteItemWindow(item) else: self.DeleteItemWindow(item) - + item.SetWindow(wnd) self.CalculatePositions() self.Refresh() self.AdjustMyScrollbars() - + def DeleteItemWindow(self, item): """ @@ -4272,7 +4310,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.DeleteWindow() if item in self._itemWithWindow: self._itemWithWindow.remove(item) - + def GetItemWindowEnabled(self, item): """ @@ -4306,8 +4344,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. :return: An integer representing the item type. - - :see: :meth:`~CustomTreeCtrl.SetItemType` for a description of valid item types. + + :see: :meth:`~CustomTreeCtrl.SetItemType` for a description of valid item types. """ return item.GetType() @@ -4330,7 +4368,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: Regarding radiobutton-type items (with `ct_type` = 2), the following approach is used: - + - All peer-nodes that are radiobuttons will be mutually exclusive. In other words, only one of a set of radiobuttons that share a common parent can be checked at once. If a radiobutton node becomes checked, then all of its peer radiobuttons @@ -4353,7 +4391,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ Returns whether the item is visible or not (i.e., its hierarchy is expanded enough to show the item). - + :param `item`: an instance of :class:`GenericTreeItem`. :return: ``True`` if the item is visible, ``False`` if it is hidden. @@ -4363,17 +4401,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): parent = item.GetParent() while parent: - + if not parent.IsExpanded(): return False - + parent = parent.GetParent() - + startX, startY = self.GetViewStart() clientSize = self.GetClientSize() rect = self.GetBoundingRect(item) - + if not rect: return False if rect.GetWidth() == 0 or rect.GetHeight() == 0: @@ -4461,7 +4499,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. - :return: An instance of :class:`GenericTreeItem` or ``None`` for root items. + :return: An instance of :class:`GenericTreeItem` or ``None`` for root items. """ return item.GetParent() @@ -4506,14 +4544,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): # overflow "void *" if cookie < len(children): - + return children[cookie], cookie+1 - + else: - + # there are no more of them return None, cookie - + def GetLastChild(self, item): """ @@ -4543,15 +4581,15 @@ class CustomTreeCtrl(wx.ScrolledWindow): i = item parent = i.GetParent() - + if parent == None: - + # root item doesn't have any siblings return None - + siblings = parent.GetChildren() index = siblings.index(i) - + n = index + 1 return (n == len(siblings) and [None] or [siblings[n]])[0] @@ -4570,12 +4608,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): i = item parent = i.GetParent() - + if parent == None: - + # root item doesn't have any siblings return None - + siblings = parent.GetChildren() index = siblings.index(i) @@ -4605,7 +4643,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): while p and not toFind: toFind = self.GetNextSibling(p) p = self.GetItemParent(p) - + return toFind @@ -4615,7 +4653,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. - :return: An instance of :class:`GenericTreeItem` + :return: An instance of :class:`GenericTreeItem` """ # Look for a previous sibling of this item @@ -4637,7 +4675,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): Returns the next expanded item after the input one. :param `item`: an instance of :class:`TreeListItem`. - """ + """ nextSibling = self.GetNextSibling(item) if nextSibling: @@ -4645,7 +4683,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): return nextSibling return self.GetNextExpanded(prevSibling) - + return None @@ -4654,7 +4692,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): Returns the previous expanded item before the input one. :param `item`: an instance of :class:`TreeListItem`. - """ + """ prevSibling = self.GetPrevSibling(item) if prevSibling: @@ -4662,9 +4700,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): return prevSibling return self.GetPrevExpanded(prevSibling) - + return None - + def GetFirstVisibleItem(self): """ @@ -4702,7 +4740,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): id = self.GetNext(id) if id and self.IsVisible(id): return id - + return None @@ -4715,14 +4753,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`GenericTreeItem` or ``None`` if there are no previous visible items. """ - + # find a previous sibling or parent which is visible lastGoodItem = self.GetPrevSibling(item) if not lastGoodItem or not self.IsVisible(lastGoodItem): parent = self.GetItemParent(item) rootHidden = self.HasAGWFlag(TR_HIDE_ROOT) rootItem = self.GetRootItem() - + while parent and not (rootHidden and parent == rootItem): if self.IsVisible(parent): lastGoodItem = parent @@ -4731,18 +4769,18 @@ class CustomTreeCtrl(wx.ScrolledWindow): if not lastGoodItem: return None - - # test if found item has visible children, if so and if the found item is not the + + # test if found item has visible children, if so and if the found item is not the # parent of the current item traverse the found item to the last visible child if not self.HasChildren(lastGoodItem) or not self.IsExpanded(lastGoodItem) or \ (self.GetItemParent(item) == lastGoodItem): return lastGoodItem - + lastChild = self.GetLastChild(lastGoodItem) while lastChild and self.IsVisible(lastChild): lastGoodItem = lastChild lastChild = self.GetLastChild(lastGoodItem) - + return lastGoodItem @@ -4765,7 +4803,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param integer `idParent`: an instance of :class:`GenericTreeItem`; :param string `prefixOrig`: a string containing the item text prefix. - :return: An instance of :class:`GenericTreeItem` or ``None`` if no item has been found. + :return: An instance of :class:`GenericTreeItem` or ``None`` if no item has been found. """ # match is case insensitive as this is more convenient to the user: having @@ -4781,28 +4819,28 @@ class CustomTreeCtrl(wx.ScrolledWindow): if len(prefix) == 1: id = self.GetNext(id) - + # look for the item starting with the given prefix after it while id and not self.GetItemText(id).lower().startswith(prefix): - + id = self.GetNext(id) - + # if we haven't found anything... if not id: - + # ... wrap to the beginning id = self.GetRootItem() if self.HasAGWFlag(TR_HIDE_ROOT): # can't select virtual root id = self.GetNext(id) - if idParent == self.GetRootItem(): - # no tree item selected and idParent is not reachable - return id - + if idParent == self.GetRootItem(): + # no tree item selected and idParent is not reachable + return id + # and try all the items (stop when we get to the one we started from) while id != idParent and not self.GetItemText(id).lower().startswith(prefix): id = self.GetNext(id) - + return id @@ -4828,7 +4866,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): use for the item in selected state; if `image` > -1 and `selImage` is -1, the same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; - :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. + :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. :return: An instance of :class:`GenericTreeItem` upon successful insertion. @@ -4843,7 +4881,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): - The item is a separator but it has text or an associated window. - :note: Separator items should not have children, text labels or an associated window. + :note: Separator items should not have children, text labels or an associated window. """ if wnd is not None and not self.HasAGWFlag(TR_HAS_VARIABLE_ROW_HEIGHT): @@ -4860,21 +4898,21 @@ class CustomTreeCtrl(wx.ScrolledWindow): raise Exception("Separator items can not have associated windows") if text.strip(): raise Exception("Separator items can not text labels") - + parent = parentId - + if not parent: # should we give a warning here? return self.AddRoot(text, ct_type, wnd, image, selImage, data) - + self._dirty = True # do this first so stuff below doesn't cause flicker item = GenericTreeItem(parent, text, ct_type, wnd, image, selImage, data, separator) - + if wnd is not None: self._hasWindows = True self._itemWithWindow.append(item) - + parent.Insert(item, previous) return item @@ -4910,7 +4948,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): .. warning:: Only one root is allowed to exist in any given instance of :class:`CustomTreeCtrl`. - + """ if self._anchor: @@ -4928,24 +4966,24 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._dirty = True # do this first so stuff below doesn't cause flicker self._anchor = GenericTreeItem(None, text, ct_type, wnd, image, selImage, data) - + if wnd is not None: self._hasWindows = True - self._itemWithWindow.append(self._anchor) - + self._itemWithWindow.append(self._anchor) + if self.HasAGWFlag(TR_HIDE_ROOT): - + # if root is hidden, make sure we can navigate # into children self._anchor.SetHasPlus() self._anchor.Expand() self.CalculatePositions() - + if not self.HasAGWFlag(TR_MULTIPLE): - + self._current = self._key_current = self._anchor self._current.SetHilight(True) - + return self._anchor @@ -4970,7 +5008,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`GenericTreeItem` upon successful insertion. - :see: :meth:`~CustomTreeCtrl.DoInsertItem` for possible exceptions generated by this method. + :see: :meth:`~CustomTreeCtrl.DoInsertItem` for possible exceptions generated by this method. """ return self.DoInsertItem(parent, 0, text, ct_type, wnd, image, selImage, data, separator) @@ -4996,20 +5034,20 @@ class CustomTreeCtrl(wx.ScrolledWindow): same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. - + :return: An instance of :class:`GenericTreeItem` upon successful insertion. - :raise: `Exception` if the previous item is not a sibling. + :raise: `Exception` if the previous item is not a sibling. :see: :meth:`~CustomTreeCtrl.DoInsertItem` for other possible exceptions generated by this method. """ - + parent = parentId - + if not parent: # should we give a warning here? return self.AddRoot(text, ct_type, wnd, image, selImage, data) - + index = -1 if idPrevious: @@ -5040,18 +5078,18 @@ class CustomTreeCtrl(wx.ScrolledWindow): same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. - + :return: An instance of :class:`GenericTreeItem` upon successful insertion. :see: :meth:`~CustomTreeCtrl.DoInsertItem` for possible exceptions generated by this method. """ - + parent = parentId - + if not parent: # should we give a warning here? return self.AddRoot(text, ct_type, wnd, image, selImage, data) - + return self.DoInsertItem(parentId, idPrevious, text, ct_type, wnd, image, selImage, data, separator) @@ -5071,7 +5109,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): return self.InsertItemByIndex(parentId, input, text, ct_type, wnd, image, selImage, data, separator) else: return self.InsertItemByItem(parentId, input, text, ct_type, wnd, image, selImage, data, separator) - + def AppendItem(self, parentId, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None): """ @@ -5095,13 +5133,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): :see: :meth:`~CustomTreeCtrl.DoInsertItem` for possible exceptions generated by this method. """ - + parent = parentId - + if not parent: # should we give a warning here? return self.AddRoot(text, ct_type, wnd, image, selImage, data) - + return self.DoInsertItem(parent, len(parent.GetChildren()), text, ct_type, wnd, image, selImage, data) @@ -5134,7 +5172,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ return self.InsertItem(parentId, input, "", separator=True) - + def PrependSeparator(self, parent): """ @@ -5145,7 +5183,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`GenericTreeItem` upon successful insertion. - :see: :meth:`~CustomTreeCtrl.DoInsertItem` for possible exceptions generated by this method. + :see: :meth:`~CustomTreeCtrl.DoInsertItem` for possible exceptions generated by this method. """ return self.PrependItem(parent, 0, separator=True) @@ -5172,18 +5210,18 @@ class CustomTreeCtrl(wx.ScrolledWindow): parent of `item`; :param `item`: another instance of :class:`GenericTreeItem`. - :return: ``True`` if `item` is a descendant of `parent`, ``False`` otherwise. + :return: ``True`` if `item` is a descendant of `parent`, ``False`` otherwise. """ while item: - + if item == parent: - + # item is a descendant of parent return True - + item = item.GetParent() - + return False @@ -5197,13 +5235,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): 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 - + if self.IsDescendantOf(item, self._select_me): self._select_me = item - + if item != self._current and self.IsDescendantOf(item, self._current): self._current.SetHilight(False) self._current = None @@ -5229,7 +5267,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. - :note: This method sends the ``EVT_TREE_DELETE_ITEM`` event. + :note: This method sends the ``EVT_TREE_DELETE_ITEM`` event. """ self._dirty = True # do this first so stuff below doesn't cause flicker @@ -5237,26 +5275,26 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._editCtrl != None and self.IsDescendantOf(item, self._editCtrl.item()): # can't delete the item being edited, cancel editing it first self._editCtrl.StopEditing() - + parent = item.GetParent() # don't keep stale pointers around! if self.IsDescendantOf(item, self._key_current): - + # Don't silently change the selection: # do it properly in idle time, so event # handlers get called. # self._key_current = parent self._key_current = None - + # self._select_me records whether we need to select # a different item, in idle time. if self._select_me and self.IsDescendantOf(item, self._select_me): self._select_me = parent - + if self.IsDescendantOf(item, self._current): - + # Don't silently change the selection: # do it properly in idle time, so event # handlers get called. @@ -5264,17 +5302,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): # self._current = parent self._current = None self._select_me = parent - + # remove the item from the tree if parent: - + parent.GetChildren().remove(item) # remove by value - + else: # deleting the root - + # nothing will be left in the tree self._anchor = None - + # and delete all of its children and the item itself now item.DeleteChildren(self) self.SendDeleteEvent(item) @@ -5289,7 +5327,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): wnd.Destroy() item._wnd = None self._itemWithWindow.remove(item) - + del item @@ -5298,19 +5336,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._anchor: self.Delete(self._anchor) - + def Expand(self, item): """ Expands an item, sending a ``EVT_TREE_ITEM_EXPANDING`` and ``EVT_TREE_ITEM_EXPANDED`` events. - :param `item`: an instance of :class:`GenericTreeItem`. + :param `item`: an instance of :class:`GenericTreeItem`. :raise: `Exception` if you try to expand a hidden root (i.e., when the ``TR_HIDE_ROOT`` style is set for :class:`CustomTreeCtrl`). """ - + if self.HasAGWFlag(TR_HIDE_ROOT) and item == self.GetRootItem(): raise Exception("\nERROR: Can't Expand An Hidden Root. ") @@ -5328,9 +5366,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self.GetEventHandler().ProcessEvent(event) and not event.IsAllowed(): # cancelled by program return - + item.Expand() - + if not self._sendEvent: # We are in ExpandAll/ExpandAllChildren return @@ -5341,7 +5379,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._hasWindows: # We hide the associated window here, we may show it after self.HideWindows() - + event.SetEventType(wxEVT_TREE_ITEM_EXPANDED) self.GetEventHandler().ProcessEvent(event) @@ -5357,21 +5395,21 @@ class CustomTreeCtrl(wx.ScrolledWindow): control would be too slow then. """ - self._sendEvent = False + self._sendEvent = False if not self.HasAGWFlag(TR_HIDE_ROOT) or item != self.GetRootItem(): self.Expand(item) if not self.IsExpanded(item): self._sendEvent = True return - + child, cookie = self.GetFirstChild(item) - + while child: self.ExpandAllChildren(child) child, cookie = self.GetNextChild(item, cookie) self._sendEvent = True - + def ExpandAll(self): """ @@ -5387,7 +5425,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._sendEvent = True self._dirty = True - + def Collapse(self, item): """ @@ -5399,7 +5437,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :raise: `Exception` if you try to collapse a hidden root (i.e., when the ``TR_HIDE_ROOT`` style is set for :class:`CustomTreeCtrl`). """ - + if self.HasAGWFlag(TR_HIDE_ROOT) and item == self.GetRootItem(): raise Exception("\nERROR: Can't Collapse An Hidden Root. ") @@ -5412,7 +5450,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self.GetEventHandler().ProcessEvent(event) and not event.IsAllowed(): # cancelled by program return - + self.ChildrenClosing(item) item.Collapse() @@ -5422,8 +5460,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._hasWindows: self.HideWindows() - self.AdjustMyScrollbars() - + self.AdjustMyScrollbars() + event.SetEventType(wxEVT_TREE_ITEM_COLLAPSED) self.GetEventHandler().ProcessEvent(event) @@ -5454,13 +5492,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): def HideWindows(self): """ Hides the windows associated to the items. Used internally. """ - + for child in self._itemWithWindow: if not self.IsVisible(child): wnd = child.GetWindow() if wnd: wnd.Hide() - + def Unselect(self): """ Unselects the current selection. """ @@ -5483,7 +5521,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if item.IsSelected(): item.SetHilight(False) self.RefreshLine(item) - + if item.HasChildren(): for child in item.GetChildren(): self.UnselectAllChildren(child) @@ -5498,19 +5536,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): :raise: `Exception` if used without the ``TR_EXTENDED`` or ``TR_MULTIPLE`` style set. :note: This method can be used only if :class:`CustomTreeCtrl` has the ``TR_MULTIPLE`` or ``TR_EXTENDED`` - style set. + style set. """ if not self.HasAGWFlag(TR_MULTIPLE) and not self.HasAGWFlag(TR_EXTENDED): raise Exception("SelectAllChildren can be used only with multiple selection enabled.") - + if not item.IsSelected(): item.SetHilight(True) self.RefreshLine(item) - + if item.HasChildren(): for child in item.GetChildren(): - self.SelectAllChildren(child) + self.SelectAllChildren(child) def UnselectAll(self): @@ -5522,7 +5560,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if rootItem: self.UnselectAllChildren(rootItem) - self.Unselect() + self.Unselect() def SelectAll(self): @@ -5537,14 +5575,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): if not self.HasAGWFlag(TR_MULTIPLE) and not self.HasAGWFlag(TR_EXTENDED): raise Exception("SelectAll can be used only with multiple selection enabled.") - + rootItem = self.GetRootItem() # the tree might not have the root item at all if rootItem: self.SelectAllChildren(rootItem) - + # Recursive function ! # To stop we must have crt_item start_y+client_h: - + # going up x, y = self._anchor.GetSize(x, y, self) y += _PIXELS_PER_UNIT + 2 # one more scrollbar unit + 2 pixels @@ -5863,7 +5901,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): def OnCompareItems(self, item1, item2): """ Returns whether 2 items have the same text. - + Override this function in the derived class to change the sort order of the items in the :class:`CustomTreeCtrl`. The function should return a negative, zero or positive value if the first item is less than, equal to or greater than the second one. @@ -5873,7 +5911,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: The return value is negative if `item1` < `item2`, zero if `item1` == `item2` and strictly positive if `item1` < `item2`. - + :note: The base class version compares items alphabetically. """ @@ -5883,21 +5921,21 @@ class CustomTreeCtrl(wx.ScrolledWindow): def SortChildren(self, item): """ Sorts the children of the given item using the :meth:`~CustomTreeCtrl.OnCompareItems` method of - :class:`CustomTreeCtrl`. + :class:`CustomTreeCtrl`. :param `item`: an instance of :class:`GenericTreeItem`. - + :note: You should override the :meth:`~CustomTreeCtrl.OnCompareItems` method in your derived class to change the sort order (the default is ascending case-sensitive alphabetical order). """ children = item.GetChildren() - + if len(children) > 1: self._dirty = True children = wx2to3.sort(children, self.OnCompareItems) item._children = children - + def GetImageList(self): """ @@ -5938,7 +5976,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`ImageList`. """ - return self._imageListCheck + return self._imageListCheck def GetLeftImageList(self): @@ -5957,64 +5995,64 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ Calculates the height of a line. """ dc = wx.ClientDC(self) - self._lineHeight = dc.GetCharHeight() + self._lineHeight = dc.GetCharHeight() if self._imageListNormal: - + # Calculate a self._lineHeight value from the normal Image sizes. # May be toggle off. Then CustomTreeCtrl will spread when # necessary (which might look ugly). n = self._imageListNormal.GetImageCount() for i in range(n): - + width, height = self._imageListNormal.GetSize(i) if height > self._lineHeight: self._lineHeight = height - + if self._imageListButtons: - + # Calculate a self._lineHeight value from the Button image sizes. # May be toggle off. Then CustomTreeCtrl will spread when # necessary (which might look ugly). n = self._imageListButtons.GetImageCount() for i in range(n): - + width, height = self._imageListButtons.GetSize(i) if height > self._lineHeight: self._lineHeight = height if self._imageListCheck: - + # Calculate a self._lineHeight value from the check/radio image sizes. # May be toggle off. Then CustomTreeCtrl will spread when # necessary (which might look ugly). n = self._imageListCheck.GetImageCount() for i in range(n): - + width, height = self._imageListCheck.GetSize(i) if height > self._lineHeight: self._lineHeight = height if self._imageListLeft: - + # Calculate a self._lineHeight value from the leftmost image sizes. # May be toggle off. Then CustomTreeCtrl will spread when # necessary (which might look ugly). n = self._imageListLeft.GetImageCount() for i in range(n): - + width, height = self._imageListLeft.GetSize(i) if height > self._lineHeight: self._lineHeight = height - + if self._lineHeight < 30: self._lineHeight += 2 # at least 2 pixels else: @@ -6030,11 +6068,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._ownsImageListNormal: del self._imageListNormal - + self._imageListNormal = imageList self._ownsImageListNormal = False self._dirty = True - + # Don't do any drawing if we're setting the list to NULL, # since we may be in the process of deleting the tree control. if imageList: @@ -6062,7 +6100,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._imageListLeft = imageList self._ownsImageListLeft = False self._dirty = True - + # Don't do any drawing if we're setting the list to NULL, # since we may be in the process of deleting the tree control. if imageList: @@ -6076,7 +6114,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): bmp = imageList.GetBitmap(ii) newbmp = MakeDisabledBitmap(bmp) self._grayedImageListLeft.Add(newbmp) - + def SetStateImageList(self, imageList): """ @@ -6085,7 +6123,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `imageList`: an instance of :class:`ImageList`. """ - + if self._ownsImageListState: del self._imageListState @@ -6103,7 +6141,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._ownsImageListButtons: del self._imageListButtons - + self._imageListButtons = imageList self._ownsImageListButtons = False self._dirty = True @@ -6123,7 +6161,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._grayedCheckList = wx.ImageList(sizex, sizey, True, 0) if imglist is None: - + self._imageListCheck = wx.ImageList(sizex, sizey) # Get the Checkboxes @@ -6179,7 +6217,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._imageListCheck = imglist for ii in range(self._imageListCheck.GetImageCount()): - + bmp = self._imageListCheck.GetBitmap(ii) newbmp = MakeDisabledBitmap(bmp) self._grayedCheckList.Add(newbmp) @@ -6244,18 +6282,18 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ Internal method used to adjust the :class:`ScrolledWindow` scrollbars. """ if self._anchor: - + x, y = self._anchor.GetSize(0, 0, self) y += _PIXELS_PER_UNIT + 2 # one more scrollbar unit + 2 pixels x += _PIXELS_PER_UNIT + 2 # one more scrollbar unit + 2 pixels x_pos = self.GetScrollPos(wx.HORIZONTAL) y_pos = self.GetScrollPos(wx.VERTICAL) self.SetScrollbars(_PIXELS_PER_UNIT, _PIXELS_PER_UNIT, x//_PIXELS_PER_UNIT, y//_PIXELS_PER_UNIT, x_pos, y_pos) - + else: - + self.SetScrollbars(0, 0, 0, 0) - + def GetLineHeight(self, item): """ @@ -6263,7 +6301,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. - :return: the item height, in pixels. + :return: the item height, in pixels. """ if self.GetAGWWindowStyleFlag() & TR_HAS_VARIABLE_ROW_HEIGHT: @@ -6304,15 +6342,15 @@ class CustomTreeCtrl(wx.ScrolledWindow): bstep = float((b2 - b1)) / flrect rf, gf, bf = 0, 0, 0 - + for y in range(rect.y, rect.y + rect.height): - currCol = (r1 + rf, g1 + gf, b1 + bf) + currCol = (r1 + rf, g1 + gf, b1 + bf) dc.SetBrush(wx.Brush(currCol, wx.BRUSHSTYLE_SOLID)) dc.DrawRectangle(rect.x, y, rect.width, 1) rf = rf + rstep gf = gf + gstep bf = bf + bstep - + dc.SetPen(oldpen) dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangle(rect) @@ -6365,7 +6403,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangle(rect) dc.SetBrush(oldbrush) - + def DrawVistaRectangle(self, dc, rect, hasfocus): """ @@ -6378,14 +6416,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if hasfocus: - + outer = _rgbSelectOuter inner = _rgbSelectInner top = _rgbSelectTop bottom = _rgbSelectBottom else: - + outer = _rgbNoFocusOuter inner = _rgbNoFocusInner top = _rgbNoFocusTop @@ -6397,7 +6435,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): bdrRect = wx.Rect(*rect.Get()) filRect = wx.Rect(*rect.Get()) filRect.Deflate(1,1) - + r1, g1, b1 = int(top.Red()), int(top.Green()), int(top.Blue()) r2, g2, b2 = int(bottom.Red()), int(bottom.Green()), int(bottom.Blue()) @@ -6411,7 +6449,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): rf, gf, bf = 0, 0, 0 dc.SetPen(wx.TRANSPARENT_PEN) - + for y in range(filRect.y, filRect.y + filRect.height): currCol = (r1 + rf, g1 + gf, b1 + bf) dc.SetBrush(wx.Brush(currCol, wx.BRUSHSTYLE_SOLID)) @@ -6419,7 +6457,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): rf = rf + rstep gf = gf + gstep bf = bf + bstep - + dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.SetPen(wx.Pen(outer)) dc.DrawRoundedRectangle(bdrRect, 3) @@ -6450,7 +6488,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ attr = item.GetAttributes() - + if attr and attr.HasFont(): dc.SetFont(attr.GetFont()) else: @@ -6464,29 +6502,29 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.SetTextForeground(self.GetHyperTextVisitedColour()) else: dc.SetTextForeground(self.GetHyperTextNewColour()) - + text_w, text_h, dummy = dc.GetFullMultiLineTextExtent(item.GetText()) w, h = self.GetClientSize() - + image = item.GetCurrentImage() checkimage = item.GetCurrentCheckedImage() leftimage = _NO_IMAGE separator = item.IsSeparator() - + if self._imageListLeft: leftimage = item.GetLeftImage() - + image_w, image_h = 0, 0 if image != _NO_IMAGE: - + if self._imageListNormal: - + image_w, image_h = self._imageListNormal.GetSize(image) image_w += 4 - + else: - + image = _NO_IMAGE if item.GetType() != 0: @@ -6497,19 +6535,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): if leftimage != _NO_IMAGE: l_image_w, l_image_h = self._imageListLeft.GetSize(leftimage) - + total_h = self.GetLineHeight(item) drawItemBackground = False - + if item.IsSelected(): - + # under mac selections are only a rectangle in case they don't have the focus if wx.Platform == "__WXMAC__": if not self._hasFocus: - dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.SetPen(wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT), 1, wx.SOLID)) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.SetPen(wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT), 1, wx.SOLID)) else: - dc.SetBrush(self._hilightBrush) + dc.SetBrush(self._hilightBrush) else: dc.SetBrush((self._hasFocus and [self._hilightBrush] or [self._hilightUnfocusedBrush])[0]) drawItemBackground = True @@ -6519,17 +6557,21 @@ class CustomTreeCtrl(wx.ScrolledWindow): colBg = attr.GetBackgroundColour() else: colBg = self._backgroundColour - + dc.SetBrush(wx.Brush(colBg, wx.BRUSHSTYLE_SOLID)) - dc.SetPen(wx.TRANSPARENT_PEN) - + if attr and attr.HasBorderColour(): + colBorder = attr.GetBorderColour() + dc.SetPen(wx.Pen(colBorder, 1)) + else: + dc.SetPen(wx.TRANSPARENT_PEN) + offset = (self.HasAGWFlag(TR_ROW_LINES) and [1] or [0])[0] - + if self.HasAGWFlag(TR_FULL_ROW_HIGHLIGHT): x = 0 itemrect = wx.Rect(x, item.GetY()+offset, w, total_h-offset) - + if item.IsSelected(): if self._usegradients: if self._gradientstyle == 0: # Horizontal @@ -6542,7 +6584,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if wx.Platform in ["__WXGTK2__", "__WXMAC__"]: flags = wx.CONTROL_SELECTED if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED - wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) + wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) else: dc.DrawRectangle(itemrect) else: @@ -6553,11 +6595,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.GetWidth()-minusicon, total_h-offset) dc.DrawRectangle(itemrect) - + else: if item.IsSelected(): - + # If it's selected, and there's an image, then we should # take care to leave the area under the image painted in the # background colour. @@ -6571,7 +6613,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): item_width = w else: item_width = item.GetWidth() - image_w - wcheck + 2 - wndx - + itemrect = wx.Rect(item.GetX() + wcheck + image_w - 2, item.GetY()+offset, item_width, @@ -6588,10 +6630,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): if wx.Platform in ["__WXGTK2__", "__WXMAC__"]: flags = wx.CONTROL_SELECTED if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED - wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) + wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) else: dc.DrawRectangle(itemrect) - + # On GTK+ 2, drawing a 'normal' background is wrong for themes that # don't allow backgrounds to be customized. Not drawing the background, # except for custom item backgrounds, works for both kinds of theme. @@ -6602,13 +6644,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): if separator: item_width = w else: - item_width = item.GetWidth()-minusicon, - + item_width = item.GetWidth()-minusicon + itemrect = wx.Rect(item.GetX()+minusicon, item.GetY()+offset, item_width, total_h-offset) - + if self._usegradients and self._hasFocus: if self._gradientstyle == 0: # Horizontal self.DrawHorizontalGradient(dc, itemrect, self._hasFocus) @@ -6616,9 +6658,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.DrawVerticalGradient(dc, itemrect, self._hasFocus) else: dc.DrawRectangle(itemrect) - + if image != _NO_IMAGE: - + dc.SetClippingRegion(item.GetX(), item.GetY(), wcheck+image_w-2, total_h) if item.IsEnabled(): imglist = self._imageListNormal @@ -6629,7 +6671,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): item.GetX() + wcheck, item.GetY() + ((total_h > image_h) and [(total_h-image_h)//2] or [0])[0], wx.IMAGELIST_DRAW_TRANSPARENT) - + dc.DestroyClippingRegion() if wcheck: @@ -6637,7 +6679,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): imglist = self._imageListCheck else: imglist = self._grayedCheckList - + imglist.Draw(checkimage, dc, item.GetX(), item.GetY() + ((total_h > hcheck) and [(total_h-hcheck)//2] or [0])[0], @@ -6664,7 +6706,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): xa, ya = self.CalcScrolledPosition((0, item.GetY())) maxsize = w - (wcheck + image_w + item.GetX()) + xa itemText = ChopText(dc, itemText, maxsize) - + if not item.IsEnabled(): foreground = dc.GetTextForeground() dc.SetTextForeground(self._disabledColour) @@ -6687,11 +6729,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): # Horizontal alignment of windows if level in self.absoluteWindows: wndx = self.absoluteWindows[level] + item.GetX() + 2 + xa - + elif align == 2: # Rightmost alignment of windows wndx = w - item.GetWindowSize().x - 2 + xa - + if not wnd.IsShown(): wnd.Show() if wnd.GetPosition() != (wndx, ya): @@ -6707,14 +6749,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): separatorPen = self._separatorPen else: separatorPen = wx.GREY_PEN - + dc.SetPen(separatorPen) dc.DrawLine(item.GetX()+2, item.GetY()+total_h//2, w, item.GetY()+total_h//2) dc.SetPen(oldPen) - + # restore normal font dc.SetFont(self._normalFont) - + # Now y stands for the top of the item, whereas it used to stand for middle ! def PaintLevel(self, item, dc, level, y, align): @@ -6742,20 +6784,20 @@ class CustomTreeCtrl(wx.ScrolledWindow): left_image_list = 0 if self._imageListLeft: left_image_list += self._imageListLeft.GetBitmap(0).GetWidth() - + x += left_image_list - + if not self.HasAGWFlag(TR_HIDE_ROOT): - + x += self._indent - + elif level == 0: - + # always expand hidden root origY = y children = item.GetChildren() count = len(children) - + if count > 0: n = 0 while n < count: @@ -6764,7 +6806,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): n = n + 1 if not self.HasAGWFlag(TR_NO_LINES) and self.HasAGWFlag(TR_LINES_AT_ROOT) and count > 0: - + # draw line down to last child origY += self.GetLineHeight(children[0])>>1 oldY += self.GetLineHeight(children[n-1])>>1 @@ -6772,9 +6814,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.SetPen(self._dottedPen) dc.DrawLine(3, origY, 3, oldY) dc.SetPen(oldPen) - + return y - + item.SetX(x+self._spacing) item.SetY(y) @@ -6813,7 +6855,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): colText = attr.GetTextColour() else: colText = self.GetForegroundColour() - + # prepare to draw dc.SetTextForeground(colText) dc.SetPen(pen) @@ -6823,20 +6865,20 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.PaintItem(item, dc, level, align) if self.HasAGWFlag(TR_ROW_LINES): - + # if the background colour is white, choose a # contrasting colour for the lines medium_grey = wx.Pen(wx.Colour(200, 200, 200)) dc.SetPen(((self.GetBackgroundColour() == wx.WHITE) and [medium_grey] or [wx.WHITE_PEN])[0]) dc.DrawLine(0, y_top, 10000, y_top) dc.DrawLine(0, y, 10000, y) - + # restore DC objects dc.SetBrush(wx.WHITE_BRUSH) dc.SetTextForeground(wx.BLACK) if not self.HasAGWFlag(TR_NO_LINES): - + # draw the horizontal line here dc.SetPen(self._dottedPen) x_start = x @@ -6845,13 +6887,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): elif self.HasAGWFlag(TR_LINES_AT_ROOT): x_start = 3 dc.DrawLine(x_start, y_mid, x + self._spacing, y_mid) - dc.SetPen(oldpen) + dc.SetPen(oldpen) # should the item show a button? if item.HasPlus() and self.HasButtons(): - + if self._imageListButtons: - + # draw the image button here image_h = 0 image_w = 0 @@ -6867,16 +6909,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._imageListButtons.Draw(image, dc, xx, yy, wx.IMAGELIST_DRAW_TRANSPARENT) dc.DestroyClippingRegion() - + else: # no custom buttons if self.HasAGWFlag(TR_TWIST_BUTTONS): # We draw something like the Mac twist buttons - + dc.SetPen(wx.BLACK_PEN) dc.SetBrush(self._hilightBrush) button = [wx.Point(), wx.Point(), wx.Point()] - + if item.IsExpanded(): button[0].x = x - 5 button[0].y = y_mid - 3 @@ -6891,12 +6933,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): button[1].y = y_mid + 5 button[2].x = button[0].x + 5 button[2].y = y_mid - + dc.DrawPolygon(button) else: # These are the standard wx.TreeCtrl buttons as wx.RendererNative knows - + wImage = 11 hImage = 11 @@ -6908,14 +6950,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): flag |= _CONTROL_CURRENT self._drawingfunction(self, dc, wx.Rect(x - wImage//2, y_mid - hImage//2, wImage, hImage), flag) - + if item.IsExpanded(): - + children = item.GetChildren() count = len(children) - + if count > 0: - + n = 0 level = level + 1 @@ -6923,9 +6965,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): oldY = y y = self.PaintLevel(children[n], dc, level, y, align) n = n + 1 - + if not self.HasAGWFlag(TR_NO_LINES) and count > 0: - + # draw line down to last child oldY += self.GetLineHeight(children[n-1])>>1 if self.HasButtons(): @@ -6947,7 +6989,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if y_mid < oldY: dc.SetPen(self._dottedPen) dc.DrawLine(x, y_mid, x, oldY) - + return y @@ -6972,12 +7014,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.SetPen(self._dottedPen) 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) @@ -6993,14 +7035,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.Refresh() event.Skip() return - + if self.HasAGWFlag(TR_ALIGN_WINDOWS_RIGHT) and self._itemWithWindow: self.RefreshItemWithWindows() else: self.RefreshSelected() - + event.Skip() - + def OnEraseBackground(self, event): """ @@ -7012,7 +7054,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # Can we actually do something here (or in OnPaint()) To Handle # background images that are stretchable or always centered? # I tried but I get enormous flickering... - + if not self._backgroundImage: event.Skip() return @@ -7034,7 +7076,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `dc`: an instance of :class:`DC`. - .. todo:: Support background images also in stretch and centered modes. + .. todo:: Support background images also in stretch and centered modes. """ sz = self.GetClientSize() @@ -7050,8 +7092,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.DrawBitmap(self._backgroundImage, x, y, True) y = y + h - x = x + w - + x = x + w + def OnSetFocus(self, event): """ @@ -7088,15 +7130,15 @@ class CustomTreeCtrl(wx.ScrolledWindow): te = TreeEvent(wxEVT_TREE_KEY_DOWN, self.GetId()) te._evtKey = event te.SetEventObject(self) - + if self.GetEventHandler().ProcessEvent(te): # intercepted by the user code return if self._current is None or self._key_current is None: - + self._current = self._key_current = self.GetFirstVisibleItem() - + # how should the selection work for this event? is_multiple, extended_select, unselect_others = EventFlagsToSelType(self.GetAGWWindowStyleFlag(), event.ShiftDown(), event.CmdDown()) @@ -7112,13 +7154,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): # home : go to root # end : go to last item without opening parents # alnum : start or continue searching for the item with this prefix - + keyCode = event.GetKeyCode() if keyCode in [ord("+"), wx.WXK_ADD]: # "+" 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.IsItemEnabled(self._current): # expand all @@ -7127,7 +7169,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): elif keyCode in [ord("-"), wx.WXK_SUBTRACT]: # "-" if self.IsExpanded(self._current): self.Collapse(self._current) - + elif keyCode == wx.WXK_MENU: # Use the item's bounding rectangle to determine position for the event itemRect = self.GetBoundingRect(self._current, True) @@ -7137,13 +7179,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): event._pointDrag = wx.Point(itemRect.GetX(), itemRect.GetY() + itemRect.GetHeight()//2) event.SetEventObject(self) self.GetEventHandler().ProcessEvent(event) - + elif keyCode in [wx.WXK_RETURN, wx.WXK_SPACE, wx.WXK_NUMPAD_ENTER]: if not self.IsItemEnabled(self._current): event.Skip() return - + if not event.HasModifiers(): event = TreeEvent(wxEVT_TREE_ITEM_ACTIVATED, self.GetId()) event._item = self._current @@ -7156,12 +7198,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): checked = (checked+1)%3 else: checked = not self.IsItemChecked(self._current) - + self.CheckItem(self._current, checked) if self.IsItemHyperText(self._current): self.HandleHyperLink(self._current) - + # in any case, also generate the normal key event for this key, # even if we generated the ACTIVATED event above: this is what # wxMSW does and it makes sense because you might not want to @@ -7177,7 +7219,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): prev = self.GetItemParent(self._key_current) if prev == self.GetRootItem() and self.HasAGWFlag(TR_HIDE_ROOT): return - + 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? @@ -7185,17 +7227,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): # otherwise we return to where we came from self.DoSelectItem(prev, unselect_others, extended_select, from_key=True) self._key_current = prev - + else: current = self._key_current - + # We are going to another parent node while self.IsExpanded(prev) and self.HasChildren(prev): child = self.GetLastChild(prev) if child: prev = child current = prev - + # Try to get the previous siblings and see if they are active while prev and not self.IsItemEnabled(prev): prev = self.GetPrevSibling(prev) @@ -7205,16 +7247,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): prev = self.GetItemParent(current) while prev and not self.IsItemEnabled(prev): prev = self.GetItemParent(prev) - + if prev: self.DoSelectItem(prev, unselect_others, extended_select, from_key=True) self._key_current = prev # left arrow goes to the parent elif keyCode == wx.WXK_LEFT: - + prev = self.GetItemParent(self._current) - if prev == self.GetRootItem() and self.HasAGWFlag(TR_HIDE_ROOT): + if prev == self.GetRootItem() and self.HasAGWFlag(TR_HIDE_ROOT): # don't go to root if it is hidden prev = self.GetPrevSibling(self._current) @@ -7223,7 +7265,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): else: if prev and self.IsItemEnabled(prev): self.DoSelectItem(prev, unselect_others, extended_select, from_key=True) - + elif keyCode == wx.WXK_RIGHT: # this works the same as the down arrow except that we # also expand the item if it wasn't expanded yet @@ -7240,15 +7282,15 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self.IsExpanded(self._key_current) and self.HasChildren(self._key_current): child = self.GetNextActiveItem(self._key_current) - + if child: self.DoSelectItem(child, unselect_others, extended_select, from_key=True) - self._key_current = child - + self._key_current = child + else: - + next = self.GetNextSibling(self._key_current) - + if not next: current = self._key_current while current and not next: @@ -7261,19 +7303,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): else: while next and not self.IsItemEnabled(next): next = self.GetNext(next) - + if next: self.DoSelectItem(next, unselect_others, extended_select, from_key=True) self._key_current = next - + # selects the last visible tree item elif keyCode == wx.WXK_END: - + last = self.GetRootItem() while last and self.IsExpanded(last): - + lastChild = self.GetLastChild(last) # it may happen if the item was expanded but then all of @@ -7283,16 +7325,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): break last = lastChild - + if last and self.IsItemEnabled(last): - + self.DoSelectItem(last, unselect_others, extended_select, from_key=True) - + # selects the root item elif keyCode == wx.WXK_HOME: - + prev = self.GetRootItem() - + if not prev: return @@ -7303,22 +7345,22 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self.IsItemEnabled(prev): self.DoSelectItem(prev, unselect_others, extended_select, from_key=True) - + else: - + if not event.HasModifiers() and ((keyCode >= ord('0') and keyCode <= ord('9')) or \ (keyCode >= ord('a') and keyCode <= ord('z')) or \ (keyCode >= ord('A') and keyCode <= ord('Z'))): - + # find the next item starting with the given prefix ch = chr(keyCode) id = self.FindItem(self._current, self._findPrefix + ch) - + if not id: # no such item return - if self.IsItemEnabled(id): + if self.IsItemEnabled(id): self.SelectItem(id) self._findPrefix += ch @@ -7327,11 +7369,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): # to use this prefix for a new item search if not self._findTimer: self._findTimer = TreeFindTimer(self) - + self._findTimer.Start(_DELAY, wx.TIMER_ONE_SHOT) - + else: - + event.Skip() @@ -7346,16 +7388,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: An instance of :class:`GenericTreeItem` if an active item has been found or ``None`` if none has been found. """ - + if down: sibling = self.GetNextSibling else: sibling = self.GetPrevSibling - + if self.GetItemType(item) == 2 and not self.IsItemChecked(item): # Is an unchecked radiobutton... all its children are inactive # try to get the next/previous sibling - found = 0 + found = 0 while 1: child = sibling(item) @@ -7369,12 +7411,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): child, cookie = self.GetFirstChild(item) while child and not self.IsItemEnabled(child): child, cookie = self.GetNextChild(item, cookie) - + if child and self.IsItemEnabled(child): return child - + return None - + def HitTest(self, point, flags=0): """ @@ -7408,10 +7450,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): :note: both the item (if any, ``None`` otherwise) and the `flags` are always returned as a tuple. """ - + w, h = self.GetSize() flags = 0 - + if point.x < 0: flags |= TREE_HITTEST_TOLEFT if point.x > w: @@ -7423,15 +7465,15 @@ class CustomTreeCtrl(wx.ScrolledWindow): if flags: return None, flags - + if self._anchor == None: flags = TREE_HITTEST_NOWHERE return None, flags - point = self.CalcUnscrolledPosition(*point) + point = self.CalcUnscrolledPosition(*point) hit, flags = self._anchor.HitTest(point, self, flags, 0) - if hit == None: + if hit == None: flags = TREE_HITTEST_NOWHERE return None, flags @@ -7450,12 +7492,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): be returned, otherwise the item's image is also taken into account. :return: An instance of :class:`Rect`. - + :note: The rectangle coordinates are logical, not physical ones. So, for example, the `x` coordinate may be negative if the tree has a horizontal scrollbar and its position is not ``0``. """ - + i = item startX, startY = self.GetViewStart() @@ -7476,19 +7518,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`. - .. warning:: Separator-type items can not be edited. + .. warning:: Separator-type items can not be edited. """ if item.IsSeparator(): return - + te = TreeEvent(wxEVT_TREE_BEGIN_LABEL_EDIT, self.GetId()) te._item = item te.SetEventObject(self) if self.GetEventHandler().ProcessEvent(te) and not te.IsAllowed(): # vetoed by user return - + # We have to call this here because the label in # question might just have been added and no screen # update taken place. @@ -7504,14 +7546,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._editCtrl = TreeTextCtrl(self, item=item) self._editCtrl.SetFocus() - + def GetEditControl(self): """ Returns a pointer to the edit :class:`TreeTextCtrl` if the item is being edited or ``None`` otherwise (it is assumed that no more than one item may be edited - simultaneously). + simultaneously). """ - + return self._editCtrl @@ -7523,7 +7565,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`GenericTreeItem`; :param string `value`: the new value of the item label. - :return: ``True`` if the editing has not been vetoed, ``False`` otherwise. + :return: ``True`` if the editing has not been vetoed, ``False`` otherwise. """ le = TreeEvent(wxEVT_TREE_END_LABEL_EDIT, self.GetId()) @@ -7533,14 +7575,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): le._editCancelled = False return not self.GetEventHandler().ProcessEvent(le) or le.IsAllowed() - + def OnCancelEdit(self, item): """ Called by :class:`TreeTextCtrl`, to cancel the changes and to send the ``EVT_TREE_END_LABEL_EDIT`` event. - :param `item`: an instance of :class:`GenericTreeItem`. + :param `item`: an instance of :class:`GenericTreeItem`. """ # let owner know that the edit was cancelled @@ -7555,7 +7597,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): def OnEditTimer(self): """ The timer for editing has expired. Start editing. """ - + self.Edit(self._current) @@ -7587,7 +7629,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._underMouse: # unhighlight old item self._underMouse = None - + self._underMouse = underMouse # Determines what item we are hovering over and need a tooltip for @@ -7595,7 +7637,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # 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 hevent = TreeEvent(wxEVT_TREE_ITEM_GETTOOLTIP, self.GetId()) @@ -7604,7 +7646,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self.GetEventHandler().ProcessEvent(hevent) and hevent.IsAllowed(): self.SetToolTip(hevent._label) - + elif self.HasAGWFlag(TR_TOOLTIP_ON_LONG_ITEMS): tip = self.GetToolTipText() @@ -7612,19 +7654,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): if hoverItem.IsSeparator(): if tip: self.SetToolTip('') - else: + else: maxsize = self.GetItemSize(hoverItem) itemText = hoverItem.GetText() dc = wx.ClientDC(self) - + if dc.GetFullMultiLineTextExtent(itemText)[0] > maxsize: if tip != itemText: self.SetToolTip(itemText) else: if tip: self.SetToolTip('') - + if hoverItem.IsHyperText() and (flags & TREE_HITTEST_ONITEMLABEL) and hoverItem.IsEnabled(): self.SetCursor(wx.Cursor(wx.CURSOR_HAND)) self._isonhyperlink = True @@ -7632,22 +7674,22 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._isonhyperlink: self.SetCursor(wx.Cursor(wx.CURSOR_ARROW)) self._isonhyperlink = False - + # we process left mouse up event (enables in-place edit), right down # (pass to the user code), left dbl click (activate item) and # dragging/moving events for items drag-and-drop if not (event.LeftDown() or event.LeftUp() or event.RightDown() or event.LeftDClick() or \ event.Dragging() or ((event.Moving() or event.RightUp()) and self._isDragging)): - + event.Skip() return - + flags = 0 item, flags = self._anchor.HitTest(pt, self, flags, 0) if event.Dragging() and not self._isDragging and ((flags & TREE_HITTEST_ONITEMICON) or (flags & TREE_HITTEST_ONITEMLABEL)): - + if self._dragCount == 0: self._dragStart = pt @@ -7657,7 +7699,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._dragCount != 3: # wait until user drags a bit further... return - + command = (event.RightIsDown() and [wxEVT_TREE_BEGIN_RDRAG] or [wxEVT_TREE_BEGIN_DRAG])[0] nevent = TreeEvent(command, self.GetId()) @@ -7671,7 +7713,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): nevent.Veto() if self.GetEventHandler().ProcessEvent(nevent) and nevent.IsAllowed(): - + # we're going to drag this item self._isDragging = True @@ -7684,7 +7726,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._oldSelection = self.GetSelection() if self._oldSelection: - + self._oldSelection.SetHilight(False) self.RefreshLine(self._oldSelection) else: @@ -7697,12 +7739,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._dragImage: del self._dragImage - # Create the custom draw image from the icons and the text of the item + # Create the custom draw image from the icons and the text of the item self._dragImage = DragImage(self, self._current) self._dragImage.BeginDrag(wx.Point(0,0), self) self._dragImage.Show() self._dragImage.Move(self.CalcScrolledPosition(*pt)) - + elif event.Dragging() and self._isDragging: self._dragImage.Move(self.CalcScrolledPosition(*pt)) @@ -7711,7 +7753,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._oldItem = item if item != self._dropTarget: - + # unhighlight the previous drop target if self._dropTarget: self._dropTarget.SetHilight(False) @@ -7736,13 +7778,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._dropTarget: self._dropTarget.SetHilight(False) - + if self._oldSelection: - + self._oldSelection.SetHilight(True) self.RefreshLine(self._oldSelection) self._oldSelection = None - + # generate the drag end event event = TreeEvent(wxEVT_TREE_END_DRAG, self.GetId()) event._item = item @@ -7753,7 +7795,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._isDragging = False self._dropTarget = None - + self.SetCursor(self._oldCursor) if wx.Platform in ["__WXMSW__", "__WXMAC__"]: @@ -7761,7 +7803,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): else: # Probably this is not enough on GTK. Try a Refresh() if it does not work. wx.SafeYield() - + else: # If we got to this point, we are not dragging or moving the mouse. @@ -7773,7 +7815,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._hasFocus = True self.SetFocusIgnoringChildren() event.Skip() - + # here we process only the messages which happen on tree items self._dragCount = 0 @@ -7784,17 +7826,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): return # we hit the blank area if event.RightDown(): - + if self._editCtrl != None and item != self._editCtrl.item(): self._editCtrl.StopEditing() self._hasFocus = True self.SetFocusIgnoringChildren() - + # If the item is already selected, do not update the selection. # Multi-selections should not be cleared if a selected item is clicked. if not self.IsSelected(item): - + self.DoSelectItem(item, True, False) nevent = TreeEvent(wxEVT_TREE_ITEM_RIGHT_CLICK, self.GetId()) @@ -7810,38 +7852,38 @@ class CustomTreeCtrl(wx.ScrolledWindow): nevent2._pointDrag = self.CalcScrolledPosition(*pt) nevent2.SetEventObject(self) self.GetEventHandler().ProcessEvent(nevent2) - + elif event.LeftUp(): - + # this facilitates multiple-item drag-and-drop if self.HasAGWFlag(TR_MULTIPLE): - + selections = self.GetSelections() if len(selections) > 1 and not event.CmdDown() and not event.ShiftDown(): - + self.DoSelectItem(item, True, False) - + if self._lastOnSame: - + if item == self._current and (flags & TREE_HITTEST_ONITEMLABEL) and self.HasAGWFlag(TR_EDIT_LABELS): - + if self._editTimer: - + if self._editTimer.IsRunning(): - + self._editTimer.Stop() - + else: - + self._editTimer = TreeEditTimer(self) - + self._editTimer.Start(_DELAY, True) - + self._lastOnSame = False - - + + else: # !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick() if not item or not item.IsEnabled(): @@ -7854,23 +7896,23 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._hasFocus = True self.SetFocusIgnoringChildren() - + if event.LeftDown(): - + self._lastOnSame = item == self._current - + if flags & TREE_HITTEST_ONITEMBUTTON: - + # only toggle the item for a single click, double click on # the button doesn't do anything (it toggles the item twice) if event.LeftDown(): - + self.Toggle(item) - + # don't select the item if the button was clicked return - if item.GetType() > 0 and (flags & TREE_HITTEST_ONITEMCHECKICON): + if item.GetType() > 0 and (flags & TREE_HITTEST_ONITEMCHECKICON) and (flags & TREE_HITTEST_ONITEMLABEL == 0): if event.LeftDown(): if flags & TREE_HITTEST_ONITEM and self.HasAGWFlag(TR_FULL_ROW_HIGHLIGHT): @@ -7881,10 +7923,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): checked = (checked+1)%3 else: checked = not self.IsItemChecked(item) - + self.CheckItem(item, checked) - - return + + return # clear the previously selected items, if the # user clicked outside of the present selection. @@ -7897,7 +7939,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # how should the selection work for this event? if item.IsHyperText(): self.SetItemVisited(item, True) - + is_multiple, extended_select, unselect_others = EventFlagsToSelType(self.GetAGWWindowStyleFlag(), event.ShiftDown(), event.CmdDown()) @@ -7907,11 +7949,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): # Handle hyperlink items... which are a bit odd sometimes elif self.IsSelected(item) and item.IsHyperText(): self.HandleHyperLink(item) - + # For some reason, Windows isn't recognizing a left double-click, # so we need to simulate it here. Allow 200 milliseconds for now. if event.LeftDClick(): - + # double clicking should not start editing the item label if self._editTimer: self._editTimer.Stop() @@ -7924,13 +7966,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): nevent._pointDrag = self.CalcScrolledPosition(*pt) nevent.SetEventObject(self) if not self.GetEventHandler().ProcessEvent(nevent): - + # if the user code didn't process the activate event, # handle it ourselves by toggling the item when it is # double clicked ## if item.HasPlus(): self.Toggle(item) - + def OnInternalIdle(self): """ @@ -7948,12 +7990,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): # Delaying it means that we can invoke event handlers # as required, when a first item is selected. if not self.HasAGWFlag(TR_MULTIPLE) and not self.GetSelection(): - + if self._select_me: self.SelectItem(self._select_me) elif self.GetRootItem(): self.SelectItem(self.GetRootItem()) - + # after all changes have been done to the tree control, # we actually redraw the tree when everything is over @@ -7968,7 +8010,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.Refresh() self.AdjustMyScrollbars() -# event.Skip() +# event.Skip() def CalculateSize(self, item, dc, level=-1, align=0): @@ -8012,9 +8054,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): image = item.GetCurrentImage() if image != _NO_IMAGE: - + if self._imageListNormal: - + image_w, image_h = self._imageListNormal.GetSize(image) image_w += 4 @@ -8025,7 +8067,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): wcheck, hcheck = self._imageListCheck.GetSize(checkimage) wcheck += 4 else: - wcheck = 0 + wcheck = 0 if total_h < 30: total_h += 2 # at least 2 pixels @@ -8055,7 +8097,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if item.IsSeparator(): totalWidth = self.GetClientSize()[0] totalHeight = total_h - + item.SetWidth(totalWidth) item.SetHeight(totalHeight) @@ -8082,13 +8124,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ x = level*self._indent - + if not self.HasAGWFlag(TR_HIDE_ROOT): - + x += self._indent - + elif level == 0: - + # a hidden root is not evaluated, but its # children are always calculated children = item.GetChildren() @@ -8096,9 +8138,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): level = level + 1 for n in range(count): y = self.CalculateLevel(children[n], dc, level, y, align) # recurse - + return y - + self.CalculateSize(item, dc, level, align) # set its position @@ -8115,9 +8157,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): level = level + 1 for n in range(count): y = self.CalculateLevel(children[n], dc, level, y, align) # recurse - + return y - + def CalculatePositions(self): """ Calculates all the positions of the visible items. """ @@ -8126,7 +8168,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): return self.absoluteWindows = {} - + dc = wx.ClientDC(self) self.PrepareDC(dc) @@ -8134,7 +8176,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.SetPen(self._dottedPen) y = 2 y = self.CalculateLevel(self._anchor, dc, 0, y) # start recursion - + 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 @@ -8144,7 +8186,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): def RefreshSubtree(self, item): """ Refreshes a damaged subtree of an item. - + :param `item`: an instance of :class:`GenericTreeItem`. """ @@ -8212,7 +8254,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): children = item.GetChildren() for child in children: self.RefreshSelectedUnder(child) - + def RefreshItemWithWindows(self, item=None): """ @@ -8220,7 +8262,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :param `item`: an instance of :class:`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. """ @@ -8232,7 +8274,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.RefreshItemWithWindows(self._anchor) return - wnd = item.GetWindow() + wnd = item.GetWindow() if wnd and wnd.IsShown(): self.RefreshLine(item) @@ -8266,17 +8308,17 @@ class CustomTreeCtrl(wx.ScrolledWindow): Reenables window updating after a previous call to :meth:`~Freeze`. To really thaw the control, it must be called exactly the same number of times as :meth:`~Freeze`. - :raise: `Exception` if :meth:`~Thaw` has been called without an un-matching :meth:`~Freeze`. + :raise: `Exception` if :meth:`~Thaw` has been called without an un-matching :meth:`~Freeze`. """ if self._freezeCount == 0: raise Exception("\nERROR: Thawing Unfrozen Tree Control?") self._freezeCount = self._freezeCount - 1 - + if not self._freezeCount: self.Refresh() - + # ---------------------------------------------------------------------------- # changing colours: we need to refresh the tree control @@ -8291,7 +8333,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: ``False`` if the underlying :class:`ScrolledWindow` does not accept the new colour, ``True`` otherwise. - + :note: The background colour is usually painted by the default :class:`EraseEvent` event handler function under Windows and automatically under GTK. @@ -8299,7 +8341,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): you may wish to call :meth:`Window.ClearBackground` or :meth:`Window.Refresh` after calling this function. - :note: Overridden from :class:`ScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ if not wx.ScrolledWindow.SetBackgroundColour(self, colour): @@ -8323,7 +8365,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): :return: ``False`` if the underlying :class:`ScrolledWindow` does not accept the new colour, ``True`` otherwise. - :note: Overridden from :class:`ScrolledWindow`. + :note: Overridden from :class:`ScrolledWindow`. """ if not wx.ScrolledWindow.SetForegroundColour(self, colour): @@ -8336,13 +8378,13 @@ class CustomTreeCtrl(wx.ScrolledWindow): return True - + def OnGetToolTip(self, event): """ Process the tooltip event, to speed up event processing. Does not actually get a tooltip. - :param `event`: a :class:`CommandTreeEvent` event to be processed. + :param `event`: a :class:`CommandTreeEvent` event to be processed. """ event.Veto() @@ -8355,30 +8397,30 @@ class CustomTreeCtrl(wx.ScrolledWindow): as it would have after a call to `Fit()`. :return: An instance of :class:`Size`. - + :note: Overridden from :class:`ScrolledWindow`. """ - + # something is better than nothing... # 100x80 is what the MSW version will get from the default # wxControl::DoGetBestSize return wx.Size(100, 80) - + def GetMaxWidth(self, respect_expansion_state=True): """ Returns the maximum width of the :class:`CustomTreeCtrl`. - + :param bool `respect_expansion_state`: if ``True``, only the expanded items (and their children) will be measured. Otherwise all the items are expanded and their width measured. - :return: the maximum width of :class:`CustomTreeCtrl`, in pixels. + :return: the maximum width of :class:`CustomTreeCtrl`, in pixels. """ self.Freeze() - + root = self.GetRootItem() rect = self.GetBoundingRect(root, True) @@ -8386,7 +8428,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # rect occupies 4 pixels approximatively maxwidth = rect.x + rect.width + 4 lastheight = rect.y + rect.height - + if not self.IsExpanded(root): if respect_expansion_state: return maxwidth @@ -8397,9 +8439,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): maxwidth, lastheight = self.RecurseOnChildren(root, maxwidth, respect_expansion_state) self.Thaw() - + return maxwidth - + def RecurseOnChildren(self, item, maxwidth, respect_expansion_state): """ @@ -8412,29 +8454,29 @@ class CustomTreeCtrl(wx.ScrolledWindow): children) will be measured. Otherwise all the items are expanded and their width measured. - :return: A tuple containing the maximum width and item height, in pixels. + :return: A tuple containing the maximum width and item height, in pixels. """ - + child, cookie = self.GetFirstChild(item) lastheight = 0 while child: rect = self.GetBoundingRect(child, True) - + # It looks like the space between the "+" and the node # rect occupies 4 pixels approximatively maxwidth = max(maxwidth, rect.x + rect.width + 4) lastheight = rect.y + rect.height - + if self.IsExpanded(child) or not respect_expansion_state: maxwidth, lastheight = self.RecurseOnChildren(child, maxwidth, respect_expansion_state) - + child, cookie = self.GetNextChild(item, cookie) return maxwidth, lastheight - + def GetClassDefaultAttributes(self): """ Returns the default font and colours which are used by the control. This is @@ -8449,14 +8491,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): returned by, say, :meth:`ListCtrl.GetClassDefaultAttributes` (). :return: An instance of :class:`VisualAttributes`. - + :note: The :class:`VisualAttributes` structure has at least the fields `font`, `colFg` and `colBg`. All of them may be invalid if it was not possible to determine the default control appearance or, especially for the background colour, if the field doesn't make sense as is the case for `colBg` for the controls with themed background. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ attr = wx.VisualAttributes() @@ -8477,14 +8519,14 @@ if __name__ == '__main__': def __init__(self, parent): - wx.Frame.__init__(self, parent, -1, "CustomTreeCtrl Demo") + wx.Frame.__init__(self, parent, -1, "CustomTreeCtrl Demo") # Create a CustomTreeCtrl instance custom_tree = CustomTreeCtrl(self, agwStyle=wx.TR_DEFAULT_STYLE) custom_tree.SetBackgroundColour(wx.WHITE) - + # Add a root node to it - root = custom_tree.AddRoot("The Root Item") + root = custom_tree.AddRoot("The Root Item") # Create an image list to add icons next to an item il = wx.ImageList(16, 16) @@ -8493,7 +8535,7 @@ if __name__ == '__main__': fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16, 16))) custom_tree.SetImageList(il) - + custom_tree.SetItemImage(root, fldridx, wx.TreeItemIcon_Normal) custom_tree.SetItemImage(root, fldropenidx, wx.TreeItemIcon_Expanded) @@ -8523,4 +8565,3 @@ if __name__ == '__main__': frame.Show() app.MainLoop() - \ No newline at end of file diff --git a/wx/lib/agw/floatspin.py b/wx/lib/agw/floatspin.py index c2233568..6ad78592 100644 --- a/wx/lib/agw/floatspin.py +++ b/wx/lib/agw/floatspin.py @@ -3,7 +3,7 @@ # Python Code By: # # Andrea Gavana, @ 16 Nov 2005 -# Latest Revision: 16 Jul 2012, 15.00 GMT +# Latest Revision: 06 Aug 2012, 21.00 GMT # # # TODO List/Caveats @@ -57,17 +57,17 @@ Usage example:: class MyFrame(wx.Frame): def __init__(self, parent): - + wx.Frame.__init__(self, parent, -1, "FloatSpin Demo") panel = wx.Panel(self) - + floatspin = FS.FloatSpin(panel, -1, pos=(50, 50), min_val=0, max_val=1, increment=0.01, value=0.1, agwStyle=FS.FS_LEFT) floatspin.SetFormat("%f") floatspin.SetDigits(2) - + # our normal wxApp-derived class, as usual app = wx.App(0) @@ -136,7 +136,7 @@ License And Version :class:`FloatSpin` control is distributed under the wxPython license. -Latest revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT +Latest revision: Andrea Gavana @ 06 Aug 2012, 21.00 GMT Version 1.0 @@ -248,7 +248,7 @@ class FloatTextCtrl(wx.TextCtrl): A class which holds a :class:`TextCtrl`, one of the two building blocks of :class:`FloatSpin`. """ - + def __init__(self, parent, id=wx.ID_ANY, value="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TE_NOHIDESEL | wx.TE_PROCESS_ENTER, validator=wx.DefaultValidator, @@ -267,7 +267,7 @@ class FloatTextCtrl(wx.TextCtrl): :param `style`: the window style; :param `validator`: the window validator; :param `name`: the window name. - + """ wx.TextCtrl.__init__(self, parent, id, value, pos, size, style, validator, name) @@ -385,7 +385,7 @@ class FloatSpin(wx.Control): self._spinctrl_bestsize = wx.Size(-999, -999) # start Philip Semanchuk addition - # The textbox & spin button are drawn slightly differently + # The textbox & spin button are drawn slightly differently # depending on the platform. The difference is most pronounced # under OS X. if "__WXMAC__" in wx.PlatformInfo: @@ -407,15 +407,6 @@ class FloatSpin(wx.Control): # end Philip Semanchuk addition self.SetLabel(name) - # start Philip Semanchuk change - # Set the background color to match that of the parent. wxMac supports - # transparency, and that gives the best results on that platform. - # Other platforms ignore wx.ALPHA_TRANSPARENT. - colour = parent.GetBackgroundColour() - colour.Set(colour.Red(), colour.Green(), colour.Blue(), - wx.ALPHA_TRANSPARENT) - self.SetBackgroundColour(colour) - # end Philip Semanchuk change self.SetForegroundColour(parent.GetForegroundColour()) width = size[0] @@ -453,14 +444,14 @@ class FloatSpin(wx.Control): txtstyle) # start Philip Semanchuk addition - # Setting the textctrl's size in the ctor also sets its min size. - # But the textctrl is entirely controlled by the parent floatspin + # Setting the textctrl's size in the ctor also sets its min size. + # But the textctrl is entirely controlled by the parent floatspin # control and should accept whatever size its parent dictates, so # here we tell it to forget its min size. self._textctrl.SetMinSize(wx.DefaultSize) - # Setting the spin buttons's size in the ctor also sets its min size. + # Setting the spin buttons's size in the ctor also sets its min size. # Under OS X that results in a rendering artifact because spin buttons - # are a little shorter than textboxes. + # are a little shorter than textboxes. # Setting the min size to the default allows OS X to draw the spin # button correctly. However, Windows and KDE take the call to # SetMinSize() as a cue to size the spin button taller than the @@ -495,7 +486,7 @@ class FloatSpin(wx.Control): self.Bind(wx.EVT_SPIN_UP, self.OnSpinUp) self.Bind(wx.EVT_SPIN_DOWN, self.OnSpinDown) self._spinbutton.Bind(wx.EVT_LEFT_DOWN, self.OnSpinMouseDown) - + self._textctrl.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter) self._textctrl.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self._spinbutton.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) @@ -533,7 +524,7 @@ class FloatSpin(wx.Control): Gets the size which best suits the window: for a control, it would be the minimal size which doesn't truncate the control, for a panel - the same size as it would have after a call to `Fit()`. - + :note: Overridden from :class:`Control`. """ @@ -757,21 +748,21 @@ class FloatSpin(wx.Control): """ # start Philip Semanchuk addition event_width = event.GetSize().width - + self._textctrl.SetPosition((self._text_left, self._text_top)) - + text_width, text_height = self._textctrl.GetSize() - + spin_width, _ = self._spinbutton.GetSize() - + text_width = event_width - (spin_width + self._gap + self._text_left) self._textctrl.SetSize(wx.Size(text_width, text_height)) - - # The spin button is always snug against the right edge of the + + # The spin button is always snug against the right edge of the # control. self._spinbutton.SetPosition((event_width - spin_width, self._spin_top)) - + event.Skip() # end Philip Semanchuk addition @@ -803,7 +794,7 @@ class FloatSpin(wx.Control): Sets the :class:`FloatSpin` value. :param `value`: the new value. - """ + """ if not self._textctrl or not self.InRange(value): return @@ -880,7 +871,7 @@ class FloatSpin(wx.Control): or no range:: SetRange(min_val=None, max_val=None) - + """ self.SetRangeDontClampValue(min_val, max_val) @@ -896,7 +887,7 @@ class FloatSpin(wx.Control): been specified. :param `var`: the value to be clamped. - + :return: A clamped copy of `var`. """ @@ -908,7 +899,7 @@ class FloatSpin(wx.Control): if (self._max != None): if (var > self._max): var = self._max - + return var @@ -967,14 +958,14 @@ class FloatSpin(wx.Control): ====== ================================= Format Description - ====== ================================= + ====== ================================= 'e' Floating point exponential format (lowercase) 'E' Floating point exponential format (uppercase) 'f' Floating point decimal format 'F' Floating point decimal format 'g' Floating point format. Uses lowercase exponential format if exponent is less than -4 or not less than precision, decimal format otherwise 'G' Floating point format. Uses uppercase exponential format if exponent is less than -4 or not less than precision, decimal format otherwise - ====== ================================= + ====== ================================= """ @@ -1035,7 +1026,7 @@ class FloatSpin(wx.Control): Force the value to always be divisible by the increment. Initially ``False``. :param `forceticks`: ``True`` to force the snap to ticks option, ``False`` otherwise. - + :note: This uses the default value as the basis, you will get strange results for very large differences between the current value and default value when the increment is very small. @@ -1256,7 +1247,7 @@ class FixedPoint(object): Note that if the precision of a FixedPoint is reduced via :meth:`FixedPoint.set_precision() `, information may be lost to rounding. - Example:: + Example:: >>> x = FixedPoint("5.55") # precision defaults to 2 >>> print x @@ -1328,7 +1319,7 @@ class FixedPoint(object): :param `value`: the initial value; :param `precision`: must be an int >= 0, and defaults to ``DEFAULT_PRECISION``. """ - + self.n = self.p = 0 self.set_precision(precision) p = self.p @@ -1454,7 +1445,7 @@ class FixedPoint(object): def __str__(self): - + n, p = self.n, self.p i, f = divmod(abs(n), _tento(p)) if p: @@ -1474,14 +1465,14 @@ class FixedPoint(object): def copy(self): """ Create a copy of the current :class:`FixedPoint`. """ - + return _mkFP(self.n, self.p) __copy__ = __deepcopy__ = copy def __cmp__(self, other): - + if (other == None): return 1 xn, yn, p = _norm(self, other) @@ -1593,12 +1584,12 @@ class FixedPoint(object): Returns fractional portion as a :class:`FixedPoint`. :note: In :class:`FixedPoint`, - + this equality holds true:: - + x = x.frac() + long(x) - + """ return self - long(self) @@ -1732,17 +1723,17 @@ if __name__ == '__main__': class MyFrame(wx.Frame): def __init__(self, parent): - + wx.Frame.__init__(self, parent, -1, "FloatSpin Demo") panel = wx.Panel(self) - + floatspin = FloatSpin(panel, -1, pos=(50, 50), min_val=0, max_val=1, increment=0.01, value=0.1, agwStyle=FS_LEFT) floatspin.SetFormat("%f") floatspin.SetDigits(2) - + # our normal wxApp-derived class, as usual app = wx.App(0) @@ -1753,4 +1744,3 @@ if __name__ == '__main__': app.MainLoop() - \ No newline at end of file diff --git a/wx/lib/agw/hypertreelist.py b/wx/lib/agw/hypertreelist.py index 198a514b..c7411a73 100644 --- a/wx/lib/agw/hypertreelist.py +++ b/wx/lib/agw/hypertreelist.py @@ -3,7 +3,7 @@ # Inspired By And Heavily Based On wx.adv.TreeListCtrl. # # Andrea Gavana, @ 08 May 2006 -# Latest Revision: 16 Jul 2012, 15.00 GMT +# Latest Revision: 25 Aug 2012, 10.00 GMT # # # TODO List @@ -62,7 +62,7 @@ In addition to the standard :class:`adv.TreeListCtrl` behaviour this class suppo * Added support for 3-state value checkbox items; * RadioButton-type items: since I elected to put radiobuttons in :class:`~lib.agw.customtreectrl.CustomTreeCtrl`, I needed some way to handle them, that made sense. So, I used the following approach: - + - All peer-nodes that are radiobuttons will be mutually exclusive. In other words, only one of a set of radiobuttons that share a common parent can be checked at once. If a radiobutton node becomes checked, then all of its peer radiobuttons @@ -107,7 +107,7 @@ And a style useful to hide the TreeListCtrl header: - ``TR_NO_HEADER``: hides the :class:`HyperTreeList` header. -And a style related to long items (with a lot of text in them), which can be +And a style related to long items (with a lot of text in them), which can be ellipsized: - ``TR_ELLIPSIZE_LONG_ITEMS``: ellipsizes long items when the horizontal space for @@ -128,18 +128,18 @@ Usage example:: class MyFrame(wx.Frame): def __init__(self, parent): - + wx.Frame.__init__(self, parent, -1, "HyperTreeList Demo") tree_list = HTL.HyperTreeList(self) - + tree_list.AddColumn("First column") root = tree_list.AddRoot("Root", ct_type=1) parent = tree_list.AppendItem(root, "First child", ct_type=1) child = tree_list.AppendItem(parent, "First Grandchild", ct_type=1) - + tree_list.AppendItem(root, "Second child", ct_type=1) @@ -152,7 +152,7 @@ Usage example:: frame.Show() app.MainLoop() - + Events @@ -262,7 +262,7 @@ License And Version :class:`HyperTreeList` is distributed under the wxPython license. -Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT +Latest Revision: Andrea Gavana @ 25 Aug 2012, 10.00 GMT Version 1.4 @@ -379,8 +379,8 @@ def IsBufferingSupported(): return True - return False - + return False + class TreeListColumnInfo(object): """ @@ -420,9 +420,9 @@ class TreeListColumnInfo(object): self._colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT) else: self._colour = colour - + else: - + self._text = input._text self._width = input._width self._flag = input._flag @@ -432,15 +432,15 @@ class TreeListColumnInfo(object): self._edit = input._edit self._colour = input._colour self._font = input._font - + # get/set def GetText(self): """ Returns the column header label. """ - + return self._text - + def SetText(self, text): """ Sets the column header label. @@ -455,7 +455,7 @@ class TreeListColumnInfo(object): def GetWidth(self): """ Returns the column header width in pixels. """ - return self._width + return self._width def SetWidth(self, width): @@ -474,7 +474,7 @@ class TreeListColumnInfo(object): return self._flag - + def SetAlignment(self, flag): """ Sets the column text alignment. @@ -484,7 +484,7 @@ class TreeListColumnInfo(object): """ self._flag = flag - return self + return self def GetColour(self): @@ -502,12 +502,12 @@ class TreeListColumnInfo(object): self._colour = colour return self - + def GetImage(self): """ Returns the column image index. """ - return self._image + return self._image def SetImage(self, image): @@ -519,14 +519,14 @@ class TreeListColumnInfo(object): """ self._image = image - return self + return self def GetSelectedImage(self): """ Returns the column image index in the selected state. """ return self._selected_image - + def SetSelectedImage(self, image): """ @@ -539,23 +539,23 @@ class TreeListColumnInfo(object): self._selected_image = image return self - + def IsEditable(self): """ Returns ``True`` if the column is editable, ``False`` otherwise. """ return self._edit - + def SetEditable(self, edit): """ Sets the column as editable or non-editable. :param `edit`: ``True`` if the column should be editable, ``False`` otherwise. """ - + self._edit = edit - return self + return self def IsShown(self): @@ -563,7 +563,7 @@ class TreeListColumnInfo(object): return self._shown - + def SetShown(self, shown): """ Sets the column as shown or hidden. @@ -573,7 +573,7 @@ class TreeListColumnInfo(object): """ self._shown = shown - return self + return self def SetFont(self, font): @@ -590,7 +590,7 @@ class TreeListColumnInfo(object): def GetFont(self): """ Returns the column text font. """ - return self._font + return self._font #----------------------------------------------------------------------------- @@ -599,7 +599,7 @@ class TreeListColumnInfo(object): class TreeListHeaderWindow(wx.Window): """ A window which holds the header of :class:`HyperTreeList`. """ - + def __init__(self, parent, id=wx.ID_ANY, owner=None, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, name="wxtreelistctrlcolumntitles"): """ @@ -617,7 +617,7 @@ class TreeListHeaderWindow(wx.Window): """ wx.Window.__init__(self, parent, id, pos, size, style, name=name) - + self._owner = owner self._currentCursor = wx.Cursor(wx.CURSOR_DEFAULT) self._resizeCursor = wx.Cursor(wx.CURSOR_SIZEWE) @@ -627,7 +627,7 @@ class TreeListHeaderWindow(wx.Window): self._hotTrackCol = -1 self._columns = [] self._headerCustomRenderer = None - + self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) @@ -651,7 +651,7 @@ class TreeListHeaderWindow(wx.Window): def GetWidth(self): """ Returns the total width of all columns. """ - return self._total_col_width + return self._total_col_width # column manipulation @@ -671,7 +671,7 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column] @@ -684,10 +684,10 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].GetText() - + def SetColumnText(self, column, text): """ Sets the column text label. @@ -698,9 +698,9 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].SetText(text) - + def GetColumnAlignment(self, column): """ @@ -711,9 +711,9 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].GetAlignment() - + def SetColumnAlignment(self, column, flag): """ @@ -728,9 +728,9 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].SetAlignment(flag) - + def GetColumnWidth(self, column): """ @@ -741,9 +741,9 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].GetWidth() - + def GetColumnColour(self, column): """ @@ -754,7 +754,7 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].GetColour() @@ -768,7 +768,7 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].SetColour(colour) @@ -781,9 +781,9 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + return self._columns[column].IsEditable() - + def IsColumnShown(self, column): """ @@ -796,7 +796,7 @@ class TreeListHeaderWindow(wx.Window): raise Exception("Invalid column") return self._columns[column].IsShown() - + # shift the DC origin to match the position of the main window horz # scrollbar: this allows us to always use logical coords @@ -805,9 +805,9 @@ class TreeListHeaderWindow(wx.Window): Shifts the :class:`DC` origin to match the position of the main window horizontal scrollbar: this allows us to always use logical coordinates. - :param `dc`: an instance of :class:`DC`. + :param `dc`: an instance of :class:`DC`. """ - + xpix, dummy = self._owner.GetScrollPixelsPerUnit() x, dummy = self._owner.GetViewStart() @@ -821,12 +821,12 @@ class TreeListHeaderWindow(wx.Window): :param `event`: a :class:`PaintEvent` event to be processed. """ - + if self._buffered: dc = wx.BufferedPaintDC(self) else: dc = wx.PaintDC(self) - + self.AdjustDC(dc) x = 0 @@ -837,12 +837,12 @@ class TreeListHeaderWindow(wx.Window): dc.SetBackgroundMode(wx.TRANSPARENT) numColumns = self.GetColumnCount() - + for i in range(numColumns): if x >= w: break - + if not self.IsColumnShown(i): continue # do next column if not shown @@ -859,7 +859,7 @@ class TreeListHeaderWindow(wx.Window): if i == self._hotTrackCol: flags |= wx.CONTROL_CURRENT - + params.m_labelText = column.GetText() params.m_labelAlignment = column.GetAlignment() @@ -874,7 +874,7 @@ class TreeListHeaderWindow(wx.Window): else: wx.RendererNative.Get().DrawHeaderButton(self, dc, rect, flags, wx.HDR_SORT_ICON_NONE, params) - + # Fill up any unused space to the right of the columns if x < w: rect = wx.Rect(x, 0, w-x, h) @@ -882,11 +882,11 @@ class TreeListHeaderWindow(wx.Window): self._headerCustomRenderer.DrawHeaderButton(dc, rect) else: wx.RendererNative.Get().DrawHeaderButton(self, dc, rect) - + def DrawCurrent(self): """ Draws the column resize line on a :class:`ScreenDC`. """ - + x1, y1 = self._currentX, 0 x1, y1 = self.ClientToScreen((x1, y1)) x2 = self._currentX-1 @@ -905,8 +905,8 @@ class TreeListHeaderWindow(wx.Window): self.AdjustDC(dc) dc.DrawLine (x1, y1, x2, y2) dc.SetLogicalFunction(wx.COPY) - - + + def SetCustomRenderer(self, renderer=None): """ Associate a custom renderer with the header - all columns will use it @@ -928,21 +928,21 @@ class TreeListHeaderWindow(wx.Window): :return: The column that corresponds to the logical input `x` coordinate, or ``wx.NOT_FOUND`` if there is no column at the `x` position. """ - + colLeft = 0 numColumns = self.GetColumnCount() for col in range(numColumns): - + if not self.IsColumnShown(col): - continue + continue column = self.GetColumn(col) if x < (colLeft + column.GetWidth()): return col - + colLeft += column.GetWidth() - + return wx.NOT_FOUND @@ -955,13 +955,13 @@ class TreeListHeaderWindow(wx.Window): if col >= self.GetColumnCount(): return - + x = idx = width = 0 while idx <= col: - + if not self.IsColumnShown(idx): idx += 1 - continue + continue column = self.GetColumn(idx) x += width @@ -971,7 +971,7 @@ class TreeListHeaderWindow(wx.Window): x, dummy = self._owner.CalcScrolledPosition(x, 0) self.RefreshRect(wx.Rect(x, 0, width, self.GetSize().GetHeight())) - + def OnMouse(self, event): """ Handles the ``wx.EVT_MOUSE_EVENTS`` event for :class:`TreeListHeaderWindow`. @@ -984,10 +984,10 @@ class TreeListHeaderWindow(wx.Window): y = event.GetY() if event.Moving(): - + col = self.XToCol(x) if col != self._hotTrackCol: - + # Refresh the col header so it will be painted with hot tracking # (if supported by the native renderer.) self.RefreshColLabel(col) @@ -997,13 +997,13 @@ class TreeListHeaderWindow(wx.Window): self.RefreshColLabel(self._hotTrackCol) self._hotTrackCol = col - + if event.Leaving() and self._hotTrackCol >= 0: - + # Leaving the window so clear any hot tracking indicator that may be present self.RefreshColLabel(self._hotTrackCol) self._hotTrackCol = -1 - + if self._isDragging: self.SendListEvent(wx.wxEVT_COMMAND_LIST_COL_DRAGGING, event.GetPosition()) @@ -1032,7 +1032,7 @@ class TreeListHeaderWindow(wx.Window): # draw in the new location if self._currentX < w: self.DrawCurrent() - + else: # not dragging self._minX = 0 @@ -1055,13 +1055,13 @@ class TreeListHeaderWindow(wx.Window): # near the column border hit_border = True break - + if x < xpos: # inside the column break - + self._minX = xpos - + if event.LeftDown() or event.RightUp(): if hit_border and event.LeftDown(): self._isDragging = True @@ -1072,23 +1072,23 @@ class TreeListHeaderWindow(wx.Window): else: # click on a column evt = (event.LeftDown() and [wx.wxEVT_COMMAND_LIST_COL_CLICK] or [wx.wxEVT_COMMAND_LIST_COL_RIGHT_CLICK])[0] self.SendListEvent(evt, event.GetPosition()) - + elif event.LeftDClick() and hit_border: self.SetColumnWidth(self._column, self._owner.GetBestColumnWidth(self._column)) self.Refresh() elif event.Moving(): - + if hit_border: setCursor = self._currentCursor == wx.STANDARD_CURSOR self._currentCursor = self._resizeCursor else: setCursor = self._currentCursor != wx.STANDARD_CURSOR self._currentCursor = wx.STANDARD_CURSOR - + if setCursor: self.SetCursor(self._currentCursor) - + def OnSetFocus(self, event): """ @@ -1107,7 +1107,7 @@ class TreeListHeaderWindow(wx.Window): :param `evtType`: the event type; :param `pos`: an instance of :class:`Point`. """ - + parent = self.GetParent() le = wx.ListEvent(evtType, parent.GetId()) le.SetEventObject(parent) @@ -1128,7 +1128,7 @@ class TreeListHeaderWindow(wx.Window): :param `colInfo`: an instance of :class:`TreeListColumnInfo`. """ - + self._columns.append(colInfo) self._total_col_width += colInfo.GetWidth() self._owner.AdjustMyScrollbars() @@ -1163,7 +1163,7 @@ class TreeListHeaderWindow(wx.Window): :param `column`: an integer specifying the column index; :param `width`: the new width for the column, in pixels. """ - + if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") @@ -1185,7 +1185,7 @@ class TreeListHeaderWindow(wx.Window): if before < 0 or before >= self.GetColumnCount(): raise Exception("Invalid column") - + self._columns.insert(before, colInfo) self._total_col_width += colInfo.GetWidth() self._owner.AdjustMyScrollbars() @@ -1193,7 +1193,7 @@ class TreeListHeaderWindow(wx.Window): def InsertColumn(self, before, text, width=_DEFAULT_COL_WIDTH, - flag=wx.ALIGN_LEFT, image=-1, shown=True, colour=None, + flag=wx.ALIGN_LEFT, image=-1, shown=True, colour=None, edit=False): """ Inserts a column to the :class:`TreeListHeaderWindow` at the position specified @@ -1209,10 +1209,10 @@ class TreeListHeaderWindow(wx.Window): :param `shown`: ``True`` to show the column, ``False`` to hide it; :param `colour`: a valid :class:`Colour`, representing the text foreground colour for the column; - :param `edit`: ``True`` to set the column as editable, ``False`` otherwise. + :param `edit`: ``True`` to set the column as editable, ``False`` otherwise. """ - - colInfo = TreeListColumnInfo(text, width, flag, image, shown, colour, + + colInfo = TreeListColumnInfo(text, width, flag, image, shown, colour, edit) self.InsertColumnInfo(before, colInfo) @@ -1226,7 +1226,7 @@ class TreeListHeaderWindow(wx.Window): if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + self._total_col_width -= self._columns[column].GetWidth() self._columns.pop(column) self._owner.AdjustMyScrollbars() @@ -1238,21 +1238,21 @@ class TreeListHeaderWindow(wx.Window): Sets a column using an instance of :class:`TreeListColumnInfo`. :param `column`: an integer specifying the column index; - :param `info`: an instance of :class:`TreeListColumnInfo`. + :param `info`: an instance of :class:`TreeListColumnInfo`. """ - + if column < 0 or column >= self.GetColumnCount(): raise Exception("Invalid column") - + w = self._columns[column].GetWidth() self._columns[column] = info - + if w != info.GetWidth(): self._total_col_width += info.GetWidth() - w self._owner.AdjustMyScrollbars() - + self._owner._dirty = True - + # --------------------------------------------------------------------------- # TreeListItem @@ -1262,9 +1262,9 @@ class TreeListItem(GenericTreeItem): This class holds all the information and methods for every single item in :class:`HyperTreeList`. - :note: Subclassed from :class:`GenericTreeItem`. + :note: Subclassed from :class:`GenericTreeItem`. """ - + def __init__(self, mainWin, parent, text=[], ct_type=0, wnd=None, image=-1, selImage=-1, data=None): """ Default class constructor. @@ -1295,13 +1295,13 @@ class TreeListItem(GenericTreeItem): :note: Regarding radiobutton-type items (with `ct_type` = 2), the following approach is used: - + - All peer-nodes that are radiobuttons will be mutually exclusive. In other words, only one of a set of radiobuttons that share a common parent can be checked at once. If a radiobutton node becomes checked, then all of its peer radiobuttons must be unchecked. - If a radiobutton node becomes unchecked, then all of its child nodes will become - inactive. + inactive. """ self._col_images = [] @@ -1309,12 +1309,12 @@ class TreeListItem(GenericTreeItem): # We don't know the height here yet. self._text_x = 0 - - GenericTreeItem.__init__(self, parent, text, ct_type, wnd, image, selImage, data) - + + GenericTreeItem.__init__(self, parent, text, ct_type, wnd, image, selImage, data) + self._wnd = [None] # are we holding a window? self._hidden = False - + if wnd: self.SetWindow(wnd) @@ -1333,8 +1333,8 @@ class TreeListItem(GenericTreeItem): """ self._hidden = hide - - + + def DeleteChildren(self, tree): """ Deletes the item children. @@ -1347,7 +1347,7 @@ class TreeListItem(GenericTreeItem): tree.SendDeleteEvent(child) child.DeleteChildren(tree) - + if child == tree._selectItem: tree._selectItem = None @@ -1356,14 +1356,14 @@ class TreeListItem(GenericTreeItem): if wnd: wnd.Hide() wnd.Destroy() - + child._wnd = [] if child in tree._itemWithWindow: tree._itemWithWindow.remove(child) - + del child - + self._children = [] @@ -1376,7 +1376,7 @@ class TreeListItem(GenericTreeItem): :param `flags`: a bitlist of hit locations; :param `column`: an integer specifying the column index; :param `level`: the item's level inside the tree hierarchy. - + :see: :meth:`TreeListMainWindow.HitTest() ` method for the flags explanation. """ @@ -1394,7 +1394,7 @@ class TreeListItem(GenericTreeItem): # evaluate if y-pos is okay h = theCtrl.GetLineHeight(self) - + if point.y >= self._y and point.y <= self._y + h: maincol = theCtrl.GetMainColumn() @@ -1405,7 +1405,7 @@ class TreeListItem(GenericTreeItem): flags |= wx.TREE_HITTEST_ONITEMUPPERPART else: flags |= wx.TREE_HITTEST_ONITEMLOWERPART - + # check for button hit if self.HasPlus() and theCtrl.HasButtons(): bntX = self._x - theCtrl._btnWidth2 @@ -1426,32 +1426,32 @@ class TreeListItem(GenericTreeItem): chkX = self._text_x - imageWidth - numberOfMargins*_MARGIN - theCtrl._checkWidth chkY = y_mid - theCtrl._checkHeight2 if ((point.x >= chkX) and (point.x <= (chkX + theCtrl._checkWidth)) and - (point.y >= chkY) and (point.y <= (chkY + theCtrl._checkHeight))): + (point.y >= chkY) and (point.y <= (chkY + theCtrl._checkHeight))): flags |= TREE_HITTEST_ONITEMCHECKICON return self, flags, maincol - + # check for image hit if self.GetCurrentImage() != _NO_IMAGE: - imgX = self._text_x - theCtrl._imgWidth - _MARGIN + imgX = self._text_x - theCtrl._imgWidth - _MARGIN imgY = y_mid - theCtrl._imgHeight2 if ((point.x >= imgX) and (point.x <= (imgX + theCtrl._imgWidth)) and (point.y >= imgY) and (point.y <= (imgY + theCtrl._imgHeight))): flags |= wx.TREE_HITTEST_ONITEMICON column = maincol return self, flags, column - + # check for label hit if ((point.x >= self._text_x) and (point.x <= (self._text_x + self._width))): flags |= wx.TREE_HITTEST_ONITEMLABEL column = maincol return self, flags, column - + # check for indent hit after button and image hit if point.x < self._x: flags |= wx.TREE_HITTEST_ONITEMINDENT column = -1 # considered not belonging to main column return self, flags, column - + # check for right of label end = 0 for i in range(maincol): @@ -1460,7 +1460,7 @@ class TreeListItem(GenericTreeItem): flags |= wx.TREE_HITTEST_ONITEMRIGHT column = -1 # considered not belonging to main column return self, flags, column - + # else check for each column except main x = 0 for j in range(theCtrl.GetColumnCount()): @@ -1471,22 +1471,22 @@ class TreeListItem(GenericTreeItem): flags |= wx.TREE_HITTEST_ONITEMCOLUMN column = j return self, flags, column - + x += w - + # no special flag or column found return self, flags, column # if children not expanded, return no item if not self.IsExpanded(): return None, flags, wx.NOT_FOUND - + # in any case evaluate children for child in self._children: hit, flags, column = child.HitTest(point, theCtrl, flags, column, level+1) if hit: return hit, flags, column - + # not found return None, flags, wx.NOT_FOUND @@ -1500,15 +1500,15 @@ class TreeListItem(GenericTreeItem): """ column = (column is not None and [column] or [self._owner.GetMainColumn()])[0] - + if len(self._text) > 0: if self._owner.IsVirtual(): return self._owner.GetItemText(self._data, column) else: return self._text[column] - + return "" - + def GetImage(self, which=wx.TreeItemIcon_Normal, column=None): """ @@ -1522,7 +1522,7 @@ class TreeListItem(GenericTreeItem): ``TreeItemIcon_Normal`` To get the normal item image ``TreeItemIcon_Selected`` To get the selected item image (i.e. the image which is shown when the item is currently selected) ``TreeItemIcon_Expanded`` To get the expanded image (this only makes sense for items which have children - then this image is shown when the item is expanded and the normal image is shown when it is collapsed) - ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) + ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) ================================= ======================== :param `column`: if not ``None``, an integer specifying the column index. @@ -1533,7 +1533,7 @@ class TreeListItem(GenericTreeItem): if column == self._owner.GetMainColumn(): return self._images[which] - + if column < len(self._col_images): return self._col_images[column] @@ -1545,17 +1545,17 @@ class TreeListItem(GenericTreeItem): Returns the current item image. :param `column`: if not ``None``, an integer specifying the column index. - If it is ``None``, the main column index is used. + If it is ``None``, the main column index is used. """ column = (column is not None and [column] or [self._owner.GetMainColumn()])[0] if column != self._owner.GetMainColumn(): return self.GetImage(column=column) - + image = GenericTreeItem.GetCurrentImage(self) return image - + def SetText(self, column, text): """ @@ -1567,13 +1567,13 @@ class TreeListItem(GenericTreeItem): """ column = (column is not None and [column] or [self._owner.GetMainColumn()])[0] - + if column < len(self._text): self._text[column] = text elif column < self._owner.GetColumnCount(): self._text.extend([""] * (column - len(self._text) + 1)) self._text[column] = text - + def SetImage(self, column, image, which): """ @@ -1588,7 +1588,7 @@ class TreeListItem(GenericTreeItem): """ column = (column is not None and [column] or [self._owner.GetMainColumn()])[0] - + if column == self._owner.GetMainColumn(): self._images[which] = image elif column < len(self._col_images): @@ -1596,14 +1596,14 @@ class TreeListItem(GenericTreeItem): elif column < self._owner.GetColumnCount(): self._col_images.extend([_NO_IMAGE] * (column - len(self._col_images) + 1)) self._col_images[column] = image - - + + def GetTextX(self): """ Returns the `x` position of the item text. """ return self._text_x - + def SetTextX(self, text_x): """ Sets the `x` position of the item text. @@ -1611,7 +1611,7 @@ class TreeListItem(GenericTreeItem): :param `text_x`: the `x` position of the item text. """ - self._text_x = text_x + self._text_x = text_x def SetWindow(self, wnd, column=None): @@ -1636,20 +1636,20 @@ class TreeListItem(GenericTreeItem): if self not in self._owner._itemWithWindow: self._owner._itemWithWindow.append(self) - + # 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 # HyperTreeList and the window associated to an item # Do better strategies exist? wnd.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) - + # We don't show the window if the item is collapsed if self._isCollapsed: wnd.Show(False) - # The window is enabled only if the item is enabled + # The window is enabled only if the item is enabled wnd.Enable(self._enabled) - + def OnSetFocus(self, event): """ @@ -1667,24 +1667,24 @@ class TreeListItem(GenericTreeItem): treectrl._hasFocus = False else: treectrl._hasFocus = True - + event.Skip() - + def GetWindow(self, column=None): """ Returns the window associated to the item. :param `column`: if not ``None``, an integer specifying the column index. - If it is ``None``, the main column index is used. + If it is ``None``, the main column index is used. """ column = (column is not None and [column] or [self._owner.GetMainColumn()])[0] - + if column >= len(self._wnd): return None - return self._wnd[column] + return self._wnd[column] def DeleteWindow(self, column=None): @@ -1699,11 +1699,11 @@ class TreeListItem(GenericTreeItem): if column >= len(self._wnd): return - + if self._wnd[column]: self._wnd[column].Destroy() self._wnd[column] = None - + def GetWindowEnabled(self, column=None): """ @@ -1747,11 +1747,11 @@ class TreeListItem(GenericTreeItem): """ column = (column is not None and [column] or [self._owner.GetMainColumn()])[0] - + if not self._wnd[column]: raise Exception("\nERROR: This Item Has No Window Associated At Column %s"%column) - - return self._wnd[column].GetSize() + + return self._wnd[column].GetSize() #----------------------------------------------------------------------------- @@ -1789,9 +1789,9 @@ class EditCtrl(object): self._startValue = value self._itemEdited = item self._finished = False - + column = (column is not None and [column] or [self._owner.GetMainColumn()])[0] - + self._column = column w = self._itemEdited.GetWidth() @@ -1806,28 +1806,28 @@ class EditCtrl(object): if column > 0: x = 0 - + for i in range(column): if not self._owner.GetParent()._header_win.IsColumnShown(i): continue # do next column if not shown - + col = self._owner.GetParent()._header_win.GetColumn(i) wCol = col.GetWidth() x += wCol - + x, y = self._owner.CalcScrolledPosition(x+2, item.GetY()) image_w = image_h = wcheck = hcheck = 0 image = item.GetCurrentImage(column) if image != _NO_IMAGE: - + if self._owner._imageListNormal: image_w, image_h = self._owner._imageListNormal.GetSize(image) image_w += 2*_MARGIN - + else: - + raise Exception("\n ERROR: You Must Create An Image List To Use Images!") if column > 0: @@ -1841,16 +1841,16 @@ class EditCtrl(object): dc = wx.ClientDC(self._owner) h = max(h, dc.GetTextExtent("Aq")[1]) h = h + 2 - + # FIXME: what are all these hardcoded 4, 8 and 11s really? x += image_w + wcheck w -= image_w + 2*_MARGIN + wcheck super(EditCtrl, self).__init__(parent, id, value, wx.Point(x,y), - wx.Size(w+15, h), - style=style|wx.SIMPLE_BORDER, + wx.Size(w+15, h), + style=style|wx.SIMPLE_BORDER, name=name, **kwargs) - + if wx.Platform == "__WXMAC__": self.SetFont(owner.GetFont()) bs = self.GetBestSize() @@ -1865,8 +1865,8 @@ class EditCtrl(object): return self._itemEdited - def column(self): - """Returns the column currently edited.""" + def column(self): + """Returns the column currently edited.""" return self._column @@ -1882,7 +1882,7 @@ class EditCtrl(object): """Finish editing.""" if not self._finished: - + self._finished = True self._owner.SetFocusIgnoringChildren() self._owner.ResetEditControl() @@ -1922,7 +1922,7 @@ class EditTextCtrl(EditCtrl, wx.TextCtrl): """ Text control used for in-place edit. """ - + def __init__(self, parent, id=wx.ID_ANY, item=None, column=None, owner=None, value="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name="edittextctrl", **kwargs): @@ -1946,9 +1946,9 @@ class EditTextCtrl(EditCtrl, wx.TextCtrl): :param `name`: the window name. """ - super(EditTextCtrl, self).__init__(parent, id, item, column, owner, - value, pos, size, style, validator, - name, **kwargs) + super(EditTextCtrl, self).__init__(parent, id, item, column, owner, + value, pos, size, style, validator, + name, **kwargs) self.SelectAll() self.Bind(wx.EVT_CHAR, self.OnChar) @@ -1975,7 +1975,7 @@ class EditTextCtrl(EditCtrl, wx.TextCtrl): else: event.Skip() - + def OnKeyUp(self, event): """ @@ -1990,19 +1990,19 @@ class EditTextCtrl(EditCtrl, wx.TextCtrl): parentSize = self._owner.GetSize() myPos = self.GetPosition() mySize = self.GetSize() - + sx, sy = self.GetTextExtent(self.GetValue() + "M") if myPos.x + sx > parentSize.x: sx = parentSize.x - myPos.x if mySize.x > sx: sx = mySize.x - + self.SetSize((sx, -1)) event.Skip() - - - + + + # --------------------------------------------------------------------------- # TreeListMainWindow implementation # --------------------------------------------------------------------------- @@ -2019,7 +2019,7 @@ class TreeListMainWindow(CustomTreeCtrl): name="wxtreelistmainwindow"): """ Default class constructor. - + :param `parent`: parent window. Must not be ``None``; :param `id`: window identifier. A value of -1 indicates a default value; :param `pos`: the control position. A value of (-1, -1) indicates a default position, @@ -2029,7 +2029,7 @@ class TreeListMainWindow(CustomTreeCtrl): :param `style`: the underlying :class:`PyScrolledWindow` style; :param `agwStyle`: the AGW-specific :class:`TreeListMainWindow` window style. This can be a combination of the following bits: - + ============================== =========== ================================================== Window Styles Hex Value Description ============================== =========== ================================================== @@ -2061,9 +2061,9 @@ class TreeListMainWindow(CustomTreeCtrl): """ self._buffered = False - + CustomTreeCtrl.__init__(self, parent, id, pos, size, style, agwStyle, validator, name) - + self._shiftItem = None self._editItem = None self._selectItem = None @@ -2088,7 +2088,7 @@ class TreeListMainWindow(CustomTreeCtrl): self._dragTimer = wx.Timer(self) self._findTimer = wx.Timer(self) - + self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) self.Bind(wx.EVT_SCROLLWIN, self.OnScroll) @@ -2117,7 +2117,7 @@ class TreeListMainWindow(CustomTreeCtrl): def IsVirtual(self): """ Returns ``True`` if :class:`TreeListMainWindow` has the ``TR_VIRTUAL`` flag set. """ - + return self.HasAGWFlag(TR_VIRTUAL) @@ -2140,10 +2140,10 @@ class TreeListMainWindow(CustomTreeCtrl): ``TreeItemIcon_Normal`` To get the normal item image ``TreeItemIcon_Selected`` To get the selected item image (i.e. the image which is shown when the item is currently selected) ``TreeItemIcon_Expanded`` To get the expanded image (this only makes sense for items which have children - then this image is shown when the item is expanded and the normal image is shown when it is collapsed) - ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) + ``TreeItemIcon_SelectedExpanded`` To get the selected expanded image (which is shown when an expanded item is currently selected) ================================= ======================== """ - + column = (column is not None and [column] or [self._main_column])[0] if column < 0: @@ -2164,12 +2164,12 @@ class TreeListMainWindow(CustomTreeCtrl): :see: :meth:`~TreeListMainWindow.GetItemImage` for a list of valid item states. """ - + column = (column is not None and [column] or [self._main_column])[0] if column < 0: return - + item.SetImage(column, image, which) dc = wx.ClientDC(self) self.CalculateSize(item, dc) @@ -2196,7 +2196,7 @@ class TreeListMainWindow(CustomTreeCtrl): :param `column`: if not ``None``, an integer specifying the column index. If it is ``None``, the main column index is used. """ - + return item.GetWindow(column) @@ -2217,11 +2217,11 @@ class TreeListMainWindow(CustomTreeCtrl): # Reparent the window to ourselves if window.GetParent() != self: window.Reparent(self) - + item.SetWindow(window, column) if window: self._hasWindows = True - + def SetItemWindowEnabled(self, item, enable=True, column=None): """ @@ -2251,17 +2251,17 @@ class TreeListMainWindow(CustomTreeCtrl): parent = item.GetParent() while parent: - + if not parent.IsExpanded(): return False - + parent = parent.GetParent() - + startX, startY = self.GetViewStart() clientSize = self.GetClientSize() rect = self.GetBoundingRect(item) - + if not rect: return False if rect.GetWidth() == 0 or rect.GetHeight() == 0: @@ -2288,9 +2288,9 @@ class TreeListMainWindow(CustomTreeCtrl): children = item.GetChildren() - if cookie >= 0: + if cookie >= 0: return children[cookie], cookie-1 - else: + else: # there are no more of them return None, cookie @@ -2306,7 +2306,7 @@ class TreeListMainWindow(CustomTreeCtrl): Returns the next expanded item after the input one. :param `item`: an instance of :class:`TreeListItem`. - """ + """ return CustomTreeCtrl.GetNextExpanded(self, item) @@ -2316,7 +2316,7 @@ class TreeListMainWindow(CustomTreeCtrl): Returns the previous expanded item before the input one. :param `item`: an instance of :class:`TreeListItem`. - """ + """ return CustomTreeCtrl.GetPrevExpanded(self, item) @@ -2332,14 +2332,14 @@ class TreeListMainWindow(CustomTreeCtrl): Returns the previous visible item before the input one. :param `item`: an instance of :class:`TreeListItem`. - """ + """ i = self.GetPrev(item) while i: if self.IsItemVisible(i): return i i = self.GetPrev(i) - + return None @@ -2365,23 +2365,23 @@ class TreeListMainWindow(CustomTreeCtrl): same image is used for both selected and unselected items; :param `data`: associate the given Python object `data` with the item. """ - + self._dirty = True # do this first so stuff below doesn't cause flicker arr = [""]*self.GetColumnCount() arr[self._main_column] = text - + if not parent: # should we give a warning here? return self.AddRoot(text, ct_type, wnd, image, selImage, data) - + self._dirty = True # do this first so stuff below doesn't cause flicker item = TreeListItem(self, parent, arr, ct_type, wnd, image, selImage, data) - + if wnd is not None: self._hasWindows = True self._itemWithWindow.append(item) - + parent.Insert(item, previous) return item @@ -2405,8 +2405,8 @@ class TreeListMainWindow(CustomTreeCtrl): .. warning:: Only one root is allowed to exist in any given instance of :class:`TreeListMainWindow`. - - """ + + """ if self._anchor: raise Exception("\nERROR: Tree Can Have Only One Root") @@ -2424,22 +2424,22 @@ class TreeListMainWindow(CustomTreeCtrl): arr = [""]*self.GetColumnCount() arr[self._main_column] = text self._anchor = TreeListItem(self, None, arr, ct_type, wnd, image, selImage, data) - + if wnd is not None: self._hasWindows = True - self._itemWithWindow.append(self._anchor) - + self._itemWithWindow.append(self._anchor) + if self.HasAGWFlag(wx.TR_HIDE_ROOT): # if root is hidden, make sure we can navigate # into children self._anchor.SetHasPlus() self._anchor.Expand() self.CalculatePositions() - + if not self.HasAGWFlag(wx.TR_MULTIPLE): self._current = self._key_current = self._selectItem = self._anchor self._current.SetHilight(True) - + return self._anchor @@ -2452,7 +2452,7 @@ class TreeListMainWindow(CustomTreeCtrl): if not item: raise Exception("\nERROR: Invalid Tree Item. ") - + self._dirty = True # do this first so stuff below doesn't cause flicker if self._editCtrl != None and self.IsDescendantOf(item, self._editCtrl.item()): @@ -2462,18 +2462,18 @@ class TreeListMainWindow(CustomTreeCtrl): # don't stay with invalid self._shiftItem or we will crash in the next call to OnChar() changeKeyCurrent = False itemKey = self._shiftItem - + while itemKey: if itemKey == item: # self._shiftItem is a descendant of the item being deleted changeKeyCurrent = True break - + itemKey = itemKey.GetParent() - + parent = item.GetParent() if parent: parent.GetChildren().remove(item) # remove by value - + if changeKeyCurrent: self._shiftItem = parent @@ -2487,10 +2487,10 @@ class TreeListMainWindow(CustomTreeCtrl): if wnd: wnd.Hide() wnd.Destroy() - + item._wnd = [] self._itemWithWindow.remove(item) - + item.DeleteChildren(self) del item @@ -2508,12 +2508,12 @@ class TreeListMainWindow(CustomTreeCtrl): if self.IsDescendantOf(item, self._selectItem): self._selectItem = item - + if item != self._current and self.IsDescendantOf(item, self._current): self._current.SetHilight(False) self._current = None - + def DeleteRoot(self): """ Removes the tree root item (and subsequently all the items in @@ -2535,18 +2535,18 @@ class TreeListMainWindow(CustomTreeCtrl): """ Delete all items in the :class:`TreeListMainWindow`. """ self.DeleteRoot() - + def HideWindows(self): """ Hides the windows associated to the items. Used internally. """ - + for child in self._itemWithWindow: if not self.IsItemVisible(child): for column in range(self.GetColumnCount()): wnd = child.GetWindow(column) if wnd and wnd.IsShown(): wnd.Hide() - + def EnableItem(self, item, enable=True, torefresh=True): """ @@ -2556,7 +2556,7 @@ class TreeListMainWindow(CustomTreeCtrl): :param `enable`: ``True`` to enable the item, ``False`` otherwise; :param `torefresh`: whether to redraw the item or not. """ - + if item.IsEnabled() == enable: return @@ -2568,10 +2568,10 @@ class TreeListMainWindow(CustomTreeCtrl): for column in range(self.GetColumnCount()): wnd = item.GetWindow(column) - # Handles the eventual window associated to the item + # Handles the eventual window associated to the item if wnd: wnd.Enable(enable) - + if torefresh: # We have to refresh the item line dc = wx.ClientDC(self) @@ -2587,14 +2587,14 @@ class TreeListMainWindow(CustomTreeCtrl): """ return item.IsEnabled() - + def GetCurrentItem(self): """ Returns the current item. """ return self._current - + def GetColumnCount(self): """ Returns the total number of columns. """ @@ -2609,7 +2609,7 @@ class TreeListMainWindow(CustomTreeCtrl): :param `column`: if not ``None``, an integer specifying the column index. If it is ``None``, the main column index is used. """ - + if column >= 0 and column < self.GetColumnCount(): self._main_column = column @@ -2619,9 +2619,9 @@ class TreeListMainWindow(CustomTreeCtrl): Returns the :class:`HyperTreeList` main column (i.e. the position of the underlying :class:`~lib.agw.customtreectrl.CustomTreeCtrl`. """ - + return self._main_column - + def ScrollTo(self, item): """ @@ -2649,13 +2649,13 @@ class TreeListMainWindow(CustomTreeCtrl): # going down, item should appear at top self.SetScrollbars(xUnit, yUnit, (xUnit and [x//xUnit] or [0])[0], (yUnit and [y//yUnit] or [0])[0], x_pos, (yUnit and [item._y//yUnit] or [0])[0]) - + elif item._y+self.GetLineHeight(item) > start_y+client_h: # going up, item should appear at bottom item._y += yUnit + 2 self.SetScrollbars(xUnit, yUnit, (xUnit and [x//xUnit] or [0])[0], (yUnit and [y//yUnit] or [0])[0], x_pos, (yUnit and [(item._y+self.GetLineHeight(item)-client_h)//yUnit] or [0])[0]) - + def SetDragItem(self, item): """ @@ -2697,7 +2697,7 @@ class TreeListMainWindow(CustomTreeCtrl): self.SetScrollbars(xUnit, yUnit, x//xUnit, y//yUnit, x_pos, y_pos) else: self.SetScrollbars(0, 0, 0, 0) - + def PaintItem(self, item, dc): """ @@ -2716,7 +2716,7 @@ class TreeListMainWindow(CustomTreeCtrl): :param `alignment`: the alignment for the text label, one of ``wx.ALIGN_LEFT``, ``wx.ALIGN_RIGHT``, ``wx.ALIGN_CENTER``. """ - + txt = text.splitlines() if alignment != wx.ALIGN_LEFT and len(txt): yorigin = textrect.Y @@ -2729,9 +2729,9 @@ class TreeListMainWindow(CustomTreeCtrl): yorigin += h return dc.DrawLabel(text, textrect) - + attr = item.GetAttributes() - + if attr and attr.HasFont(): dc.SetFont(attr.GetFont()) elif item.IsBold(): @@ -2744,7 +2744,7 @@ class TreeListMainWindow(CustomTreeCtrl): dc.SetTextForeground(self.GetHyperTextNewColour()) colText = wx.Colour(*dc.GetTextForeground()) - + if item.IsSelected(): if (wx.Platform == "__WXMAC__" and self._hasFocus): colTextHilight = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) @@ -2755,10 +2755,10 @@ class TreeListMainWindow(CustomTreeCtrl): attr = item.GetAttributes() if attr and attr.HasTextColour(): colText = attr.GetTextColour() - + if self._vistaselection: colText = colTextHilight = wx.BLACK - + total_w = self._owner.GetHeaderWindow().GetWidth() total_h = self.GetLineHeight(item) off_h = (self.HasAGWFlag(TR_ROW_LINES) and [1] or [0])[0] @@ -2774,14 +2774,18 @@ class TreeListMainWindow(CustomTreeCtrl): drawItemBackground = True else: colBg = self._backgroundColour - + dc.SetBrush(wx.Brush(colBg)) - dc.SetPen(wx.TRANSPARENT_PEN) + if attr and attr.HasBorderColour(): + colBorder = attr.GetBorderColour() + dc.SetPen(wx.Pen(colBorder, 1)) + else: + dc.SetPen(wx.TRANSPARENT_PEN) if self.HasAGWFlag(wx.TR_FULL_ROW_HIGHLIGHT): itemrect = wx.Rect(0, item.GetY() + off_h, total_w-1, total_h - off_h) - + if item == self._dragItem: dc.SetBrush(self._hilightBrush) if wx.Platform == "__WXMAC__": @@ -2797,7 +2801,7 @@ class TreeListMainWindow(CustomTreeCtrl): wndx, wndy = item.GetWindowSize(self._main_column) itemrect = wx.Rect(0, item.GetY() + off_h, total_w-1, total_h - off_h) - + if self._usegradients: if self._gradientstyle == 0: # Horizontal self.DrawHorizontalGradient(dc, itemrect, self._hasFocus) @@ -2809,12 +2813,12 @@ class TreeListMainWindow(CustomTreeCtrl): if wx.Platform in ["__WXGTK2__", "__WXMAC__"]: flags = wx.CONTROL_SELECTED if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED - wx.RendererNative.Get().DrawItemSelectionRect(self._owner, dc, itemrect, flags) + wx.RendererNative.Get().DrawItemSelectionRect(self._owner, dc, itemrect, flags) else: dc.SetBrush((self._hasFocus and [self._hilightBrush] or [self._hilightUnfocusedBrush])[0]) dc.SetPen((self._hasFocus and [self._borderPen] or [wx.TRANSPARENT_PEN])[0]) dc.DrawRectangle(itemrect) - + dc.SetTextForeground(colTextHilight) # On GTK+ 2, drawing a 'normal' background is wrong for themes that @@ -2826,18 +2830,18 @@ class TreeListMainWindow(CustomTreeCtrl): dc.SetBrush(wx.Brush(colBg)) dc.DrawRectangle(itemrect) dc.SetTextForeground(colText) - + else: dc.SetTextForeground(colText) else: - + dc.SetTextForeground(colText) text_extraH = (total_h > text_h and [(total_h - text_h)//2] or [0])[0] img_extraH = (total_h > self._imgHeight and [(total_h-self._imgHeight)//2] or [0])[0] x_colstart = 0 - + for i in range(self.GetColumnCount()): if not self._owner.GetHeaderWindow().IsColumnShown(i): continue @@ -2854,20 +2858,20 @@ class TreeListMainWindow(CustomTreeCtrl): x += (self._btnWidth-self._btnWidth2) + _LINEATROOT else: x -= self._indent//2 - + if self._imageListNormal: image = item.GetCurrentImage(i) - + if item.GetType() != 0 and self._imageListCheck: checkimage = item.GetCurrentCheckedImage() wcheck, hcheck = self._imageListCheck.GetSize(item.GetType()) else: wcheck, hcheck = 0, 0 - + else: x = x_colstart + _MARGIN image = item.GetImage(column=i) - + if image != _NO_IMAGE: image_w = self._imgWidth + _MARGIN @@ -2887,9 +2891,9 @@ class TreeListMainWindow(CustomTreeCtrl): else: if image_w == 0 and wcheck: x += 2*_MARGIN - + text_x = x + image_w + wcheck + 1 - + if i == self.GetMainColumn(): item.SetTextX(text_x) @@ -2902,7 +2906,7 @@ class TreeListMainWindow(CustomTreeCtrl): dc.SetPen((item == self._dragItem and [wx.BLACK_PEN] or [wx.TRANSPARENT_PEN])[0]) dc.SetTextForeground(colTextHilight) - + elif item.IsSelected(): itemrect = wx.Rect(text_x-2, item.GetY() + off_h, text_w+2*_MARGIN, total_h - off_h) @@ -2918,7 +2922,7 @@ class TreeListMainWindow(CustomTreeCtrl): if wx.Platform in ["__WXGTK2__", "__WXMAC__"]: flags = wx.CONTROL_SELECTED if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED - wx.RendererNative.Get().DrawItemSelectionRect(self._owner, dc, itemrect, flags) + wx.RendererNative.Get().DrawItemSelectionRect(self._owner, dc, itemrect, flags) else: dc.DrawRectangle(itemrect) @@ -2926,7 +2930,7 @@ class TreeListMainWindow(CustomTreeCtrl): elif item == self._current: dc.SetPen((self._hasFocus and [wx.BLACK_PEN] or [wx.TRANSPARENT_PEN])[0]) - + # On GTK+ 2, drawing a 'normal' background is wrong for themes that # don't allow backgrounds to be customized. Not drawing the background, # except for custom item backgrounds, works for both kinds of theme. @@ -2938,15 +2942,15 @@ class TreeListMainWindow(CustomTreeCtrl): else: dc.SetTextForeground(colText) - + else: dc.SetTextForeground(colText) - + if self.HasAGWFlag(TR_COLUMN_LINES): # vertical lines between columns pen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DLIGHT), 1, wx.SOLID) dc.SetPen((self.GetBackgroundColour() == wx.WHITE and [pen] or [wx.WHITE_PEN])[0]) dc.DrawLine(x_colstart+col_w-1, item.GetY(), x_colstart+col_w-1, item.GetY()+total_h) - + dc.SetBackgroundMode(wx.TRANSPARENT) if image != _NO_IMAGE: @@ -2958,7 +2962,7 @@ class TreeListMainWindow(CustomTreeCtrl): imglist = self._imageListNormal else: imglist = self._grayedImageList - + imglist.Draw(image, dc, x, y, wx.IMAGELIST_DRAW_TRANSPARENT) if wcheck: @@ -2971,14 +2975,14 @@ class TreeListMainWindow(CustomTreeCtrl): btnWidth = self._btnWidth else: btnWidth = -self._btnWidth - + imglist.Draw(checkimage, dc, item.GetX() + btnWidth + _MARGIN, item.GetY() + ((total_h > hcheck) and [(total_h-hcheck)//2] or [0])[0]+1, wx.IMAGELIST_DRAW_TRANSPARENT) text_w, text_h, dummy = dc.GetFullMultiLineTextExtent(text) - text_extraH = (total_h > text_h and [(total_h - text_h)//2] or [0])[0] + text_extraH = (total_h > text_h and [(total_h - text_h)//2] or [0])[0] text_y = item.GetY() + text_extraH textrect = wx.Rect(text_x, text_y, text_w, text_h) @@ -2989,7 +2993,7 @@ class TreeListMainWindow(CustomTreeCtrl): maxsize = col_w - (wcheck + image_w + _MARGIN) text = ChopText(dc, text, maxsize) - + if not item.IsEnabled(): foreground = dc.GetTextForeground() dc.SetTextForeground(self._disabledColour) @@ -3000,7 +3004,7 @@ class TreeListMainWindow(CustomTreeCtrl): dc.SetTextForeground(wx.WHITE) _paintText(text, textrect, alignment) - wnd = item.GetWindow(i) + wnd = item.GetWindow(i) if wnd: if text_w == 0: wndx = text_x @@ -3010,15 +3014,15 @@ class TreeListMainWindow(CustomTreeCtrl): wndx += xa if item.GetHeight() > item.GetWindowSize(i)[1]: ya += (item.GetHeight() - item.GetWindowSize(i)[1])//2 - + if not wnd.IsShown(): wnd.Show() if wnd.GetPosition() != (wndx, ya): - wnd.SetPosition((wndx, ya)) - + wnd.SetPosition((wndx, ya)) + x_colstart += col_w dc.DestroyClippingRegion() - + # restore normal font dc.SetFont(self._normalFont) @@ -3037,31 +3041,31 @@ class TreeListMainWindow(CustomTreeCtrl): if item.IsHidden(): return y, x_maincol - + # Handle hide root (only level 0) if self.HasAGWFlag(wx.TR_HIDE_ROOT) and level == 0: for child in item.GetChildren(): y, x_maincol = self.PaintLevel(child, dc, 1, y, x_maincol) - + # end after expanding root return y, x_maincol - + # calculate position of vertical lines x = x_maincol + _MARGIN # start of column if self.HasAGWFlag(wx.TR_LINES_AT_ROOT): x += _LINEATROOT # space for lines at root - + if self.HasButtons(): x += (self._btnWidth-self._btnWidth2) # half button space else: x += (self._indent-self._indent//2) - + if self.HasAGWFlag(wx.TR_HIDE_ROOT): x += self._indent*(level-1) # indent but not level 1 else: x += self._indent*level # indent according to level - + # set position of vertical line item.SetX(x) item.SetY(y) @@ -3086,7 +3090,7 @@ class TreeListMainWindow(CustomTreeCtrl): dc.SetPen((self.GetBackgroundColour() == wx.WHITE and [pen] or [wx.WHITE_PEN])[0]) dc.DrawLine(0, y_top, total_width, y_top) dc.DrawLine(0, y_top+h, total_width, y_top+h) - + # draw item self.PaintItem(item, dc) @@ -3114,9 +3118,9 @@ class TreeListMainWindow(CustomTreeCtrl): dc.DrawLine(x2, y_mid, x3 + _LINEATROOT, y_mid) else: dc.DrawLine(x2, y_mid, x - self._indent//2, y_mid) - + if item.HasPlus() and self.HasButtons(): # should the item show a button? - + if self._imageListButtons: # draw the image button here @@ -3151,7 +3155,7 @@ class TreeListMainWindow(CustomTreeCtrl): button[1].y = y_mid + (self._btnHeight2+1) button[2].x = button[0].x + (self._btnWidth2+1) button[2].y = y_mid - + dc.SetClippingRegion(x_maincol + _MARGIN, y_top, clip_width, h) dc.DrawPolygon(button) dc.DestroyClippingRegion() @@ -3160,7 +3164,7 @@ class TreeListMainWindow(CustomTreeCtrl): rect = wx.Rect(x-self._btnWidth2, y_mid-self._btnHeight2, self._btnWidth, self._btnHeight) flag = (item.IsExpanded() and [wx.CONTROL_EXPANDED] or [0])[0] - wx.RendererNative.GetDefault().DrawTreeItemButton(self, dc, rect, flag) + wx.RendererNative.GetDefault().DrawTreeItemButton(self, dc, rect, flag) # restore DC objects dc.SetBrush(wx.WHITE_BRUSH) @@ -3174,7 +3178,7 @@ class TreeListMainWindow(CustomTreeCtrl): oldY = y_mid + self._imgHeight2 else: oldY = y_mid + h//2 - + for child in item.GetChildren(): y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol) @@ -3184,7 +3188,7 @@ class TreeListMainWindow(CustomTreeCtrl): Y1 = child.GetY() + child.GetHeight()//2 dc.DrawLine(x, oldY, x, Y1) - return y, x_maincol + return y, x_maincol # ---------------------------------------------------------------------------- @@ -3236,14 +3240,14 @@ class TreeListMainWindow(CustomTreeCtrl): elif self.HasButtons(): self._btnWidth = _BTNWIDTH self._btnHeight = _BTNHEIGHT - + self._btnWidth2 = self._btnWidth//2 self._btnHeight2 = self._btnHeight//2 # calculate image size if self._imageListNormal: self._imgWidth, self._imgHeight = self._imageListNormal.GetSize(0) - + self._imgWidth2 = self._imgWidth//2 self._imgHeight2 = self._imgHeight//2 @@ -3252,13 +3256,13 @@ class TreeListMainWindow(CustomTreeCtrl): self._checkWidth2 = self._checkWidth//2 self._checkHeight2 = self._checkHeight//2 - + # calculate indent size if self._imageListButtons: self._indent = max(_MININDENT, self._btnWidth + _MARGIN) elif self.HasButtons(): self._indent = max(_MININDENT, self._btnWidth + _LINEATROOT) - + # set default values dc.SetFont(self._normalFont) dc.SetPen(self._dottedPen) @@ -3269,7 +3273,7 @@ class TreeListMainWindow(CustomTreeCtrl): if not self._owner.GetHeaderWindow().IsColumnShown(i): continue x_maincol += self._owner.GetHeaderWindow().GetColumnWidth(i) - + y, x_maincol = self.PaintLevel(self._anchor, dc, 0, 0, x_maincol) @@ -3332,7 +3336,7 @@ class TreeListMainWindow(CustomTreeCtrl): flags = wx.TREE_HITTEST_NOWHERE column = -1 return None, flags, column - + return hit, flags, column @@ -3342,14 +3346,14 @@ class TreeListMainWindow(CustomTreeCtrl): :param `item`: an instance of :class:`TreeListItem`; :param `column`: if not ``None``, an integer specifying the column index. - If it is ``None``, the main column index is used. + If it is ``None``, the main column index is used. """ if not item: return column = (column is not None and [column] or [self._main_column])[0] - + if column < 0 or column >= self.GetColumnCount(): return @@ -3368,13 +3372,13 @@ class TreeListMainWindow(CustomTreeCtrl): # ensure that the position of the item it calculated in any case if self._dirty: self.CalculatePositions() - + if self._editCtrl != None and (item != self._editCtrl.item() or column != self._editCtrl.column()): self._editCtrl.StopEditing() - - self._editCtrl = self._owner.CreateEditCtrl(item, column) + + self._editCtrl = self._owner.CreateEditCtrl(item, column) self._editCtrl.SetFocus() - + def OnEditTimer(self): """ The timer for editing has expired. Start editing. """ @@ -3387,7 +3391,7 @@ class TreeListMainWindow(CustomTreeCtrl): Called by :class:`EditTextCtrl`, to accept the changes and to send the ``EVT_TREE_END_LABEL_EDIT`` event. - :param `value`: the new value of the item label. + :param `value`: the new value of the item label. """ # TODO if the validator fails this causes a crash @@ -3404,7 +3408,7 @@ class TreeListMainWindow(CustomTreeCtrl): if self._curColumn == -1: self._curColumn = 0 - + self.SetItemText(self._editItem, wx2to3.text_type(value), self._curColumn) @@ -3423,7 +3427,7 @@ class TreeListMainWindow(CustomTreeCtrl): self._owner.GetEventHandler().ProcessEvent(le) - + def OnMouse(self, event): """ Handles the ``wx.EVT_MOUSE_EVENTS`` event for :class:`TreeListMainWindow`. @@ -3442,7 +3446,7 @@ class TreeListMainWindow(CustomTreeCtrl): event.GetWheelRotation() != 0 or event.Moving()): self._owner.GetEventHandler().ProcessEvent(event) return - + # set focus if window clicked if event.LeftDown() or event.RightDown(): @@ -3468,7 +3472,7 @@ class TreeListMainWindow(CustomTreeCtrl): if self._underMouse: # unhighlight old item self._underMouse = None - + self._underMouse = underMouse # Determines what item we are hovering over and need a tooltip for @@ -3481,7 +3485,7 @@ class TreeListMainWindow(CustomTreeCtrl): # 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 hevent = TreeEvent(wx.wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, self.GetId()) @@ -3498,13 +3502,13 @@ class TreeListMainWindow(CustomTreeCtrl): if self._isonhyperlink: self.SetCursor(wx.Cursor(wx.CURSOR_ARROW)) self._isonhyperlink = False - + # we only process dragging here if event.Dragging(): - + if self._isDragging: if not self._dragImage: - # Create the custom draw image from the icons and the text of the item + # Create the custom draw image from the icons and the text of the item self._dragImage = DragImage(self, self._current or item) self._dragImage.BeginDrag(wx.Point(0,0), self) self._dragImage.Show() @@ -3516,7 +3520,7 @@ class TreeListMainWindow(CustomTreeCtrl): self._oldSelection = self._current if item != self._dropTarget: - + # unhighlight the previous drop target if self._dropTarget: self._dropTarget.SetHilight(False) @@ -3533,7 +3537,7 @@ class TreeListMainWindow(CustomTreeCtrl): # Here I am trying to avoid ugly repainting problems... hope it works self.RefreshLine(self._oldItem) self._countDrag = 0 - + return # nothing to do, already done if item == None: @@ -3542,7 +3546,7 @@ class TreeListMainWindow(CustomTreeCtrl): # determine drag start if self._dragCount == 0: self._dragTimer.Start(_DRAG_TIMER_TICKS, wx.TIMER_ONE_SHOT) - + self._dragCount += 1 if self._dragCount < 3: return # minimum drag 3 pixel @@ -3559,9 +3563,9 @@ class TreeListMainWindow(CustomTreeCtrl): nevent.SetItem(self._current) # the dragged item nevent.SetPoint(p) nevent.Veto() # dragging must be explicit allowed! - + if self.GetEventHandler().ProcessEvent(nevent) and nevent.IsAllowed(): - + # we're going to drag this item self._isDragging = True self.CaptureMouse() @@ -3570,7 +3574,7 @@ class TreeListMainWindow(CustomTreeCtrl): # in a single selection control, hide the selection temporarily if not (self._agwStyle & wx.TR_MULTIPLE): if self._oldSelection: - + self._oldSelection.SetHilight(False) self.RefreshLine(self._oldSelection) else: @@ -3595,14 +3599,14 @@ class TreeListMainWindow(CustomTreeCtrl): nevent.SetItem(item) # the item the drag is started nevent.SetPoint(p) self._owner.GetEventHandler().ProcessEvent(nevent) - + if self._dragImage: self._dragImage.EndDrag() if self._dropTarget: self._dropTarget.SetHilight(False) self.RefreshLine(self._dropTarget) - + if self._oldSelection: self._oldSelection.SetHilight(True) self.RefreshLine(self._oldSelection) @@ -3612,7 +3616,7 @@ class TreeListMainWindow(CustomTreeCtrl): self._dropTarget = None if self._dragImage: self._dragImage = None - + self.Refresh() elif self._dragCount > 0: # just in case dragging is initiated @@ -3624,14 +3628,14 @@ class TreeListMainWindow(CustomTreeCtrl): if (item == None or not self.IsItemEnabled(item)) and not event.GetWheelRotation(): self._owner.GetEventHandler().ProcessEvent(event) return - + # remember item at shift down if event.ShiftDown(): if not self._shiftItem: self._shiftItem = self._current else: self._shiftItem = None - + if event.RightUp(): self.SetFocus() @@ -3649,9 +3653,9 @@ class TreeListMainWindow(CustomTreeCtrl): self._owner.GetHeaderWindow().IsColumnEditable(self._curColumn) and \ flags & (wx.TREE_HITTEST_ONITEMLABEL | wx.TREE_HITTEST_ONITEMCOLUMN): self._editTimer.Start(_EDIT_TIMER_TICKS, wx.TIMER_ONE_SHOT) - + self._lastOnSame = False - + if (((flags & wx.TREE_HITTEST_ONITEMBUTTON) or (flags & wx.TREE_HITTEST_ONITEMICON)) and \ self.HasButtons() and item.HasPlus()): @@ -3661,8 +3665,8 @@ class TreeListMainWindow(CustomTreeCtrl): self.Toggle(item) # don't select the item if the button was clicked - return - + return + # determine the selection if not done by left down if not self._left_down_selection: unselect_others = not ((event.ShiftDown() or event.CmdDown()) and self.HasAGWFlag(wx.TR_MULTIPLE)) @@ -3671,16 +3675,16 @@ class TreeListMainWindow(CustomTreeCtrl): self._current = self._key_current = item # make the new item the current item else: self._left_down_selection = False - + elif event.LeftDown() or event.RightDown() or event.LeftDClick(): if column >= 0: self._curColumn = column - + if event.LeftDown() or event.RightDown(): self.SetFocus() self._lastOnSame = item == self._current - + if (((flags & wx.TREE_HITTEST_ONITEMBUTTON) or (flags & wx.TREE_HITTEST_ONITEMICON)) and \ self.HasButtons() and item.HasPlus()): @@ -3702,7 +3706,7 @@ class TreeListMainWindow(CustomTreeCtrl): self.CheckItem(item, checked) return - + # determine the selection if the current item is not selected if not item.IsSelected(): unselect_others = not ((event.ShiftDown() or event.CmdDown()) and self.HasAGWFlag(wx.TR_MULTIPLE)) @@ -3710,7 +3714,7 @@ class TreeListMainWindow(CustomTreeCtrl): self.EnsureVisible(item) self._current = self._key_current = item # make the new item the current item self._left_down_selection = True - + # For some reason, Windows isn't recognizing a left double-click, # so we need to simulate it here. Allow 200 milliseconds for now. if event.LeftDClick(): @@ -3732,12 +3736,12 @@ class TreeListMainWindow(CustomTreeCtrl): # double clicked if item.HasPlus(): self.Toggle(item) - + else: # any other event skip just in case event.Skip() - + def OnScroll(self, event): """ Handles the ``wx.EVT_SCROLLWIN`` event for :class:`TreeListMainWindow`. @@ -3748,13 +3752,13 @@ class TreeListMainWindow(CustomTreeCtrl): def _updateHeaderWindow(header): header.Refresh() header.Update() - + # Update the header window after this scroll event has fully finished # processing, and the scoll action is complete. if event.GetOrientation() == wx.HORIZONTAL: wx.CallAfter(_updateHeaderWindow, self._owner.GetHeaderWindow()) event.Skip() - + def CalculateSize(self, item, dc): """ @@ -3777,7 +3781,7 @@ class TreeListMainWindow(CustomTreeCtrl): for column in range(self.GetColumnCount()): w, h, dummy = dc.GetFullMultiLineTextExtent(item.GetText(column)) text_w, text_h = max(w, text_w), max(h, text_h) - + wnd = item.GetWindow(column) if wnd: wnd_h = max(wnd_h, item.GetWindowSize(column)[1]) @@ -3794,9 +3798,9 @@ class TreeListMainWindow(CustomTreeCtrl): image = item.GetCurrentImage() if image != _NO_IMAGE: - + if self._imageListNormal: - + image_w, image_h = self._imageListNormal.GetSize(image) image_w += 2*_MARGIN @@ -3820,7 +3824,7 @@ class TreeListMainWindow(CustomTreeCtrl): item.SetWidth(image_w+text_w+wcheck+2+wnd_w) item.SetHeight(max(total_h, wnd_h+2)) - + def CalculateLevel(self, item, dc, level, y, x_colstart): """ Calculates the level of an item inside the tree hierarchy. @@ -3840,12 +3844,12 @@ class TreeListMainWindow(CustomTreeCtrl): x += (self._btnWidth-self._btnWidth2) # half button space else: x += (self._indent-self._indent//2) - + if self.HasAGWFlag(wx.TR_HIDE_ROOT): x += self._indent * (level-1) # indent but not level 1 else: x += self._indent * level # indent according to level - + # a hidden root is not evaluated, but its children are always if self.HasAGWFlag(wx.TR_HIDE_ROOT) and (level == 0): # a hidden root is not evaluated, but its @@ -3855,7 +3859,7 @@ class TreeListMainWindow(CustomTreeCtrl): level = level + 1 for n in range(count): y = self.CalculateLevel(children[n], dc, level, y, x_colstart) # recurse - + return y self.CalculateSize(item, dc) @@ -3874,13 +3878,13 @@ class TreeListMainWindow(CustomTreeCtrl): level = level + 1 for n in range(count): y = self.CalculateLevel(children[n], dc, level, y, x_colstart) # recurse - + return y - + def CalculatePositions(self): """ Recalculates all the items positions. """ - + if not self._anchor: return @@ -3895,7 +3899,7 @@ class TreeListMainWindow(CustomTreeCtrl): if not self._owner.GetHeaderWindow().IsColumnShown(i): continue x_colstart += self._owner.GetHeaderWindow().GetColumnWidth(i) - + self.CalculateLevel(self._anchor, dc, 0, y, x_colstart) # start recursion @@ -3928,7 +3932,7 @@ class TreeListMainWindow(CustomTreeCtrl): return self._owner.OnGetItemText(item, column) else: return item.GetText(column) - + def GetItemWidth(self, item, column): """ @@ -3937,7 +3941,7 @@ class TreeListMainWindow(CustomTreeCtrl): :param `item`: an instance of :class:`TreeListItem`; :param `column`: an integer specifying the column index. """ - + if not item: return 0 @@ -3953,7 +3957,7 @@ class TreeListMainWindow(CustomTreeCtrl): else: font = self._normalFont - dc = wx.ClientDC(self) + dc = wx.ClientDC(self) dc.SetFont(font) w, h, dummy = dc.GetFullMultiLineTextExtent(item.GetText(column)) w += 2*_MARGIN @@ -3976,7 +3980,7 @@ class TreeListMainWindow(CustomTreeCtrl): while (parent and (not self.HasAGWFlag(wx.TR_HIDE_ROOT) or (parent != root))): level += 1 parent = parent.GetParent() - + if level: width += level*self.GetIndent() @@ -4032,7 +4036,7 @@ class TreeListMainWindow(CustomTreeCtrl): # next sibling item, cookie = self.GetNextChild(parent, cookie) - + return max(10, width) # Prevent zero column width @@ -4046,7 +4050,7 @@ class TreeListMainWindow(CustomTreeCtrl): item.Hide(hide) self.Refresh() - + #---------------------------------------------------------------------------- # TreeListCtrl - the multicolumn tree control @@ -4087,13 +4091,13 @@ class HyperTreeList(wx.Control): almost the same base functionalities plus some more enhancements. This class does not rely on the native control, as it is a full owner-drawn tree-list control. """ - + def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, agwStyle=wx.TR_DEFAULT_STYLE, validator=wx.DefaultValidator, name="HyperTreeList"): """ Default class constructor. - + :param `parent`: parent window. Must not be ``None``; :param `id`: window identifier. A value of -1 indicates a default value; :param `pos`: the control position. A value of (-1, -1) indicates a default position, @@ -4103,7 +4107,7 @@ class HyperTreeList(wx.Control): :param `style`: the underlying :class:`PyScrolledWindow` style; :param `agwStyle`: the AGW-specific :class:`HyperTreeList` window style. This can be a combination of the following bits: - + ============================== =========== ================================================== Window Styles Hex Value Description ============================== =========== ================================================== @@ -4141,25 +4145,25 @@ class HyperTreeList(wx.Control): self._main_win = None self._headerHeight = 0 self._attr_set = False - + main_style = style & ~(wx.SIMPLE_BORDER|wx.SUNKEN_BORDER|wx.DOUBLE_BORDER| wx.RAISED_BORDER|wx.STATIC_BORDER) self._agwStyle = agwStyle - + self._main_win = TreeListMainWindow(self, -1, wx.Point(0, 0), size, main_style, agwStyle, validator) self._main_win._buffered = False self._header_win = TreeListHeaderWindow(self, -1, self._main_win, wx.Point(0, 0), wx.DefaultSize, wx.TAB_TRAVERSAL) self._header_win._buffered = False - + self.CalculateAndSetHeaderHeight() self.Bind(wx.EVT_SIZE, self.OnSize) self.SetBuffered(IsBufferingSupported()) self._main_win.SetAGWWindowStyleFlag(agwStyle) - + def SetBuffered(self, buffered): """ @@ -4183,25 +4187,25 @@ class HyperTreeList(wx.Control): if h != self._headerHeight: self._headerHeight = h self.DoHeaderLayout() - + def DoHeaderLayout(self): """ Layouts the header control. """ w, h = self.GetClientSize() has_header = self._agwStyle & TR_NO_HEADER == 0 - + if self._header_win and has_header: self._header_win.SetSize(0, 0, w, self._headerHeight) self._header_win.Refresh() else: self._header_win.SetSize(0, 0, 0, 0) - + if self._main_win and has_header: self._main_win.SetSize(0, self._headerHeight + 1, w, h - self._headerHeight - 1) else: self._main_win.SetSize(0, 0, w, h) - + def OnSize(self, event): """ @@ -4219,12 +4223,12 @@ class HyperTreeList(wx.Control): :param `font`: a valid :class:`Font` object. """ - + if self._header_win: self._header_win.SetFont(font) self.CalculateAndSetHeaderHeight() self._header_win.Refresh() - + if self._main_win: return self._main_win.SetFont(font) else: @@ -4240,13 +4244,13 @@ class HyperTreeList(wx.Control): if not self._header_win: return - + for column in range(self.GetColumnCount()): self._header_win.SetColumn(column, self.GetColumn(column).SetFont(font)) self._header_win.Refresh() - + def SetHeaderCustomRenderer(self, renderer=None): """ Associate a custom renderer with the header - all columns will use it @@ -4257,7 +4261,7 @@ class HyperTreeList(wx.Control): """ self._header_win.SetCustomRenderer(renderer) - + def SetAGWWindowStyleFlag(self, agwStyle): """ @@ -4291,12 +4295,12 @@ class HyperTreeList(wx.Control): ``TR_ELLIPSIZE_LONG_ITEMS`` 0x80000 Flag used to ellipsize long items when the horizontal space for :class:`~lib.agw.customtreectrl.CustomTreeCtrl` is low. ``TR_VIRTUAL`` 0x100000 :class:`HyperTreeList` will have virtual behaviour. ============================== =========== ================================================== - + :note: Please note that some styles cannot be changed after the window creation and that `Refresh()` might need to be be called after changing the others for the change to take place immediately. """ - + if self._main_win: self._main_win.SetAGWWindowStyleFlag(agwStyle) @@ -4304,7 +4308,7 @@ class HyperTreeList(wx.Control): self._agwStyle = agwStyle if abs(agwStyle - tmp) & TR_NO_HEADER: self.DoHeaderLayout() - + def GetAGWWindowStyleFlag(self): """ @@ -4316,7 +4320,7 @@ class HyperTreeList(wx.Control): agwStyle = self._agwStyle if self._main_win: agwStyle |= self._main_win.GetAGWWindowStyleFlag() - + return agwStyle @@ -4353,7 +4357,7 @@ class HyperTreeList(wx.Control): if not self._main_win: return False - + return self._main_win.SetBackgroundColour(colour) @@ -4364,12 +4368,12 @@ class HyperTreeList(wx.Control): :param `colour`: the colour to be used as the foreground colour, pass :class:`NullColour` to reset to the default colour. - :note: Overridden from :class:`Control`. + :note: Overridden from :class:`Control`. """ if not self._main_win: return False - + return self._main_win.SetForegroundColour(colour) @@ -4382,17 +4386,17 @@ class HyperTreeList(wx.Control): """ if width == wx.LIST_AUTOSIZE_USEHEADER: - + font = self._header_win.GetFont() dc = wx.ClientDC(self._header_win) width, dummy, dummy = dc.GetFullMultiLineTextExtent(self._header_win.GetColumnText(column)) # Search TreeListHeaderWindow.OnPaint to understand this: width += 2*_EXTRA_WIDTH + _MARGIN - + elif width == wx.LIST_AUTOSIZE: - + width = self._main_win.GetBestColumnWidth(column) - + self._header_win.SetColumnWidth(column, width) self._header_win.Refresh() @@ -4406,7 +4410,7 @@ class HyperTreeList(wx.Control): return self._header_win.GetColumnWidth(column) - + def SetColumnText(self, column, text): """ Sets the column text label. @@ -4448,7 +4452,7 @@ class HyperTreeList(wx.Control): self._header_win.AddColumn(text, width, flag, image, shown, colour, edit) self.DoHeaderLayout() - + def AddColumnInfo(self, colInfo): """ @@ -4475,7 +4479,7 @@ class HyperTreeList(wx.Control): def InsertColumn(self, before, text, width=_DEFAULT_COL_WIDTH, - flag=wx.ALIGN_LEFT, image=-1, shown=True, colour=None, + flag=wx.ALIGN_LEFT, image=-1, shown=True, colour=None, edit=False): """ Inserts a column to the :class:`HyperTreeList` at the position specified @@ -4491,7 +4495,7 @@ class HyperTreeList(wx.Control): :param `shown`: ``True`` to show the column, ``False`` to hide it; :param `colour`: a valid :class:`Colour`, representing the text foreground colour for the column; - :param `edit`: ``True`` to set the column as editable, ``False`` otherwise. + :param `edit`: ``True`` to set the column as editable, ``False`` otherwise. """ self._header_win.InsertColumn(before, text, width, flag, image, @@ -4515,12 +4519,12 @@ class HyperTreeList(wx.Control): Sets a column using an instance of :class:`TreeListColumnInfo`. :param `column`: an integer specifying the column index; - :param `info`: an instance of :class:`TreeListColumnInfo`. + :param `info`: an instance of :class:`TreeListColumnInfo`. """ self._header_win.SetColumn(column, colInfo) self._header_win.Refresh() - + def GetColumn(self, column): """ @@ -4528,7 +4532,7 @@ class HyperTreeList(wx.Control): :param `column`: an integer specifying the column index. """ - + return self._header_win.GetColumn(column) @@ -4539,7 +4543,7 @@ class HyperTreeList(wx.Control): :param `column`: an integer specifying the column index. :param `image`: an index within the normal image list assigned to :class:`HyperTreeList` specifying the image to use for the column. - """ + """ self._header_win.SetColumn(column, self.GetColumn(column).SetImage(image)) self._header_win.Refresh() @@ -4577,7 +4581,7 @@ class HyperTreeList(wx.Control): if self._main_win.GetMainColumn() == column: shown = True # Main column cannot be hidden - + self.SetColumn(column, self.GetColumn(column).SetShown(shown)) @@ -4620,7 +4624,7 @@ class HyperTreeList(wx.Control): :param `column`: an integer specifying the column index. """ - + return self._header_win.GetColumn(column).GetAlignment() @@ -4644,7 +4648,7 @@ class HyperTreeList(wx.Control): """ return self._header_win.GetColumn(column).GetColour() - + def SetColumnFont(self, column, font): """ @@ -4671,7 +4675,7 @@ class HyperTreeList(wx.Control): def Refresh(self, erase=True, rect=None): """ Causes this window, and all of its children recursively (except under wxGTK1 - where this is not implemented), to be repainted. + where this is not implemented), to be repainted. :param `erase`: If ``True``, the background will be erased; :param `rect`: If not ``None``, only the given rectangle will be treated as damaged. @@ -4680,7 +4684,7 @@ class HyperTreeList(wx.Control): event loop iteration, if you need to update the window immediately you should use `Update` instead. - :note: Overridden from :class:`Control`. + :note: Overridden from :class:`Control`. """ self._main_win.Refresh(erase, rect) @@ -4689,19 +4693,19 @@ class HyperTreeList(wx.Control): def SetFocus(self): """ This sets the window to receive keyboard input. """ - - self._main_win.SetFocus() + + self._main_win.SetFocus() def GetHeaderWindow(self): """ Returns the header window, an instance of :class:`TreeListHeaderWindow`. """ - + return self._header_win - + def GetMainWindow(self): """ Returns the main window, an instance of :class:`TreeListMainWindow`. """ - + return self._main_win @@ -4711,7 +4715,7 @@ class HyperTreeList(wx.Control): minimal size which doesn't truncate the control, for a panel - the same size as it would have after a call to `Fit()`. - :note: Overridden from :class:`Control`. + :note: Overridden from :class:`Control`. """ # something is better than nothing... @@ -4727,13 +4731,13 @@ class HyperTreeList(wx.Control): :param `item`: an instance of :class:`TreeListItem`; :param `column`: an integer specifying the column index. """ - + return "" def SortChildren(self, item): """ - Sorts the children of the given item using :meth:`~HyperTreeList.OnCompareItems` method of :class:`HyperTreeList`. + Sorts the children of the given item using :meth:`~HyperTreeList.OnCompareItems` method of :class:`HyperTreeList`. You should override that method to change the sort order (the default is ascending case-sensitive alphabetical order). @@ -4743,14 +4747,14 @@ class HyperTreeList(wx.Control): if not self._attr_set: setattr(self._main_win, "OnCompareItems", self.OnCompareItems) self._attr_set = True - + self._main_win.SortChildren(item) - + def OnCompareItems(self, item1, item2): """ Returns whether 2 items have the same text. - + Override this function in the derived class to change the sort order of the items in the :class:`HyperTreeList`. The function should return a negative, zero or positive value if the first item is less than, equal to or greater than the second one. @@ -4771,10 +4775,10 @@ class HyperTreeList(wx.Control): """ Create an edit control for editing a label of an item. By default, this returns a text control. - + Override this function in the derived class to return a different type of control. - + :param `item`: an instance of :class:`TreeListItem`; :param `column`: an integer specifying the column index. """ @@ -4783,37 +4787,37 @@ class HyperTreeList(wx.Control): self.GetMainWindow(), item.GetText(column), style=self.GetTextCtrlStyle(column)) - + def GetTextCtrlStyle(self, column): """ Return the style to use for the text control that is used to edit - labels of items. - + labels of items. + Override this function in the derived class to support a different style, e.g. ``wx.TE_MULTILINE``. - + :param `column`: an integer specifying the column index. """ - + return self.GetTextCtrlAlignmentStyle(column) | wx.TE_PROCESS_ENTER - + def GetTextCtrlAlignmentStyle(self, column): """ Return the alignment style to use for the text control that is used - to edit labels of items. The alignment style is derived from the + to edit labels of items. The alignment style is derived from the column alignment. - + :param `column`: an integer specifying the column index. """ header_win = self.GetHeaderWindow() alignment = header_win.GetColumnAlignment(column) - return {wx.ALIGN_LEFT: wx.TE_LEFT, - wx.ALIGN_RIGHT: wx.TE_RIGHT, + return {wx.ALIGN_LEFT: wx.TE_LEFT, + wx.ALIGN_RIGHT: wx.TE_RIGHT, wx.ALIGN_CENTER: wx.TE_CENTER}[alignment] - + def GetClassDefaultAttributes(self): """ Returns the default font and colours which are used by the control. This is @@ -4849,7 +4853,7 @@ def create_delegator_for(method): :param `method`: one method inside the :class:`TreeListMainWindow` local scope. """ - + def delegate(self, *args, **kwargs): return getattr(self._main_win, method)(*args, **kwargs) return delegate @@ -4857,7 +4861,7 @@ def create_delegator_for(method): # Create methods that delegate to self._main_win. This approach allows for # overriding these methods in possible subclasses of HyperTreeList for method in _methods: - setattr(HyperTreeList, method, create_delegator_for(method)) + setattr(HyperTreeList, method, create_delegator_for(method)) if __name__ == '__main__': @@ -4867,18 +4871,18 @@ if __name__ == '__main__': class MyFrame(wx.Frame): def __init__(self, parent): - + wx.Frame.__init__(self, parent, -1, "HyperTreeList Demo") tree_list = HyperTreeList(self) - + tree_list.AddColumn("First column") root = tree_list.AddRoot("Root", ct_type=1) parent = tree_list.AppendItem(root, "First child", ct_type=1) child = tree_list.AppendItem(parent, "First Grandchild", ct_type=1) - + tree_list.AppendItem(root, "Second child", ct_type=1) @@ -4892,4 +4896,3 @@ if __name__ == '__main__': app.MainLoop() - \ No newline at end of file diff --git a/wx/lib/agw/supertooltip.py b/wx/lib/agw/supertooltip.py index 5e8c0bc2..4e749e83 100644 --- a/wx/lib/agw/supertooltip.py +++ b/wx/lib/agw/supertooltip.py @@ -2,7 +2,7 @@ # SUPERTOOLTIP wxPython IMPLEMENTATION # # Andrea Gavana, @ 07 October 2008 -# Latest Revision: 20 Mar 2012, 21.00 GMT +# Latest Revision: 25 Aug 2012, 10.00 GMT # # # TODO List @@ -11,7 +11,10 @@ # in the header and footer; # 2) Check whether it's possible to use rounded corners and # shadows on the Mac -# +# 3) Split OnPaint() into smaller pieces to improve readability and +# ability to redefine behaviour in subclasses +# 4) Extend text formatting capabilities +# 5) Make better use of links (right now it's difficult to click them without hiding tooltip) # # For all kind of problems, requests of enhancements and bug reports, please # write to me at: @@ -64,12 +67,12 @@ Usage example:: class MyFrame(wx.Frame): def __init__(self, parent): - + wx.Frame.__init__(self, parent, -1, "SuperToolTip Demo") panel = wx.Panel(self) button = wx.Button(panel, -1, "I am the SuperToolTip target", pos=(100, 50)) - + tip = STT.SuperToolTip("A nice tooltip message") tip.SetHeader("Hello World") @@ -77,10 +80,10 @@ Usage example:: tip.SetDrawHeaderLine(True) tip.ApplyStyle("Office 2007 Blue") - + tip.SetDropShadow(True) - - + + # our normal wxApp-derived class, as usual app = wx.App(0) @@ -117,7 +120,7 @@ License And Version :class:`SuperToolTip` is distributed under the wxPython license. -Latest Revision: Andrea Gavana @ 20 Mar 2012, 21.00 GMT +Latest Revision: Andrea Gavana @ 25 Aug 2012, 10.00 GMT Version 0.5 @@ -135,7 +138,7 @@ _libimported = None if wx.Platform == "__WXMSW__": osVersion = wx.GetOsVersion() # Shadows behind menus are supported only in XP - if osVersion[1] == 5 and osVersion[2] == 1: + if osVersion[1] > 5 or (osVersion[1] == 5 and osVersion[2] >= 1): try: # Try Mark Hammond's win32all extensions import win32api @@ -256,7 +259,7 @@ class ToolTipWindowBase(object): self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) self.Bind(wx.EVT_MOTION, self.OnMouseMotion) self.Bind(wx.EVT_TIMER, self.AlphaCycle) - self.Bind(wx.EVT_KILL_FOCUS, self.OnDestroy) + parent.Bind(wx.EVT_KILL_FOCUS, self.OnDestroy) self.Bind(wx.EVT_LEFT_DOWN, self.OnDestroy) self.Bind(wx.EVT_LEFT_DCLICK, self.OnDestroy) @@ -265,14 +268,20 @@ class ToolTipWindowBase(object): """ Handles the ``wx.EVT_PAINT`` event for :class:`SuperToolTip`. - :param `event`: a :class:`PaintEvent` event to be processed. + If the `event` parameter is ``None``, calculates best size and returns it. + + :param `event`: a :class:`PaintEvent` event to be processed or ``None``. """ - # Go with double buffering... - dc = wx.BufferedPaintDC(self) + maxWidth = 0 + if event is None: + dc = wx.ClientDC(self) + else: + # Go with double buffering... + dc = wx.BufferedPaintDC(self) frameRect = self.GetClientRect() - x, y, width, height = frameRect + x, y, width, _height = frameRect # Store the rects for the hyperlink lines self._hyperlinkRect, self._hyperlinkWeb = [], [] classParent = self._classParent @@ -294,8 +303,8 @@ class ToolTipWindowBase(object): headerFont, messageFont, footerFont, hyperlinkFont = classParent.GetHeaderFont(), classParent.GetMessageFont(), \ classParent.GetFooterFont(), classParent.GetHyperlinkFont() - xPos, yPos = self._spacing, 0 - bmpXPos = bmpYPos = 0 + yPos = 0 + bmpXPos = 0 bmpHeight = textHeight = bmpWidth = 0 if headerBmp and headerBmp.IsOk(): @@ -307,7 +316,7 @@ class ToolTipWindowBase(object): # We got the header text dc.SetFont(headerFont) textWidth, textHeight = dc.GetTextExtent(header) - + maxWidth = max(bmpWidth, maxWidth) # Calculate the header height height = max(textHeight, bmpHeight) if header: @@ -321,7 +330,7 @@ class ToolTipWindowBase(object): # Draw the separator line after the header dc.SetPen(wx.GREY_PEN) dc.DrawLine(self._spacing, yPos+self._spacing, width-self._spacing, yPos+self._spacing) - + maxWidth = max(bmpXPos + bmpWidth + self._spacing, maxWidth) # Get the big body image (if any) embeddedImage = classParent.GetBodyImage() bmpWidth = bmpHeight = -1 @@ -330,13 +339,12 @@ class ToolTipWindowBase(object): # A bunch of calculations to draw the main body message messageHeight = 0 - textSpacing = (bmpWidth > 0 and [3*self._spacing] or [2*self._spacing])[0] lines = classParent.GetMessage().split("\n") yText = yPos normalText = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUTEXT) hyperLinkText = wx.BLUE - - for indx, line in enumerate(lines): + messagePos = self._getTextExtent(dc, lines[0] if lines else "")[1] // 2 + self._spacing + for line in lines: # Loop over all the lines in the message isLink = False dc.SetTextForeground(normalText) @@ -353,23 +361,16 @@ class ToolTipWindowBase(object): # Is a normal line dc.SetFont(messageFont) - textWidth, textHeight = dc.GetTextExtent(line) - if textHeight == 0: - textWidth, textHeight = dc.GetTextExtent("a") + textWidth, textHeight = self._getTextExtent(dc, line) messageHeight += textHeight - xText = (bmpWidth > 0 and [bmpWidth+2*self._spacing] or [self._spacing])[0] + xText = (bmpWidth + 2 * self._spacing) if bmpWidth > 0 else self._spacing yText += textHeight/2+self._spacing - + maxWidth = max(xText + textWidth + self._spacing, maxWidth) dc.DrawText(line, xText, yText) if isLink: - # Store the hyperlink rectangle and link - self._hyperlinkRect.append(wx.Rect(xText, yText, textWidth, textHeight)) - self._hyperlinkWeb.append(hl) - - if indx == 0: - messagePos = yText + self._storeHyperLinkInfo(xText, yText, textWidth, textHeight, hl) toAdd = 0 if bmpHeight > textHeight: @@ -385,7 +386,7 @@ class ToolTipWindowBase(object): footer, footerBmp = classParent.GetFooter(), classParent.GetFooterBitmap() bmpHeight = bmpWidth = textHeight = textWidth = 0 - bmpXPos = bmpYPos = 0 + bmpXPos = 0 if footerBmp and footerBmp.IsOk(): # Got the footer bitmap @@ -401,16 +402,37 @@ class ToolTipWindowBase(object): if drawFooter: # Draw the separator line before the footer dc.SetPen(wx.GREY_PEN) - dc.DrawLine(self._spacing, yPos-self._spacing/2+toAdd, width-self._spacing, yPos-self._spacing/2+toAdd) - + dc.DrawLine(self._spacing, yPos-self._spacing/2+toAdd, + width-self._spacing, yPos-self._spacing/2+toAdd) # Draw the footer and footer bitmap (if any) dc.SetTextForeground(normalText) height = max(textHeight, bmpHeight) yPos += toAdd if footer: - dc.DrawText(footer, bmpXPos+bmpWidth+self._spacing, yPos + (height-textHeight+self._spacing)/2) + toAdd = (height - textHeight + self._spacing) // 2 + dc.DrawText(footer, bmpXPos + bmpWidth + self._spacing, yPos + toAdd) + maxWidth = max(bmpXPos + bmpWidth + self._spacing, maxWidth) if footerBmp and footerBmp.IsOk(): - dc.DrawBitmap(footerBmp, bmpXPos, yPos + (height-bmpHeight+self._spacing)/2, True) + toAdd = (height - bmpHeight + self._spacing) / 2 + dc.DrawBitmap(footerBmp, bmpXPos, yPos + toAdd, True) + maxWidth = max(footerBmp.GetSize().GetWidth() + bmpXPos, maxWidth) + + maxHeight = yPos + toAdd + if event is None: + return maxWidth, maxHeight + + + @staticmethod + def _getTextExtent(dc, line): + textWidth, textHeight = dc.GetTextExtent(line) + if textHeight == 0: + _, textHeight = dc.GetTextExtent("a") + return textWidth, textHeight + + def _storeHyperLinkInfo(self, hTextPos, vTextPos, textWidth, textHeight, linkTarget): + # Store the hyperlink rectangle and link + self._hyperlinkRect.append(wx.Rect(hTextPos, vTextPos, textWidth, textHeight)) + self._hyperlinkWeb.append(linkTarget) def OnEraseBackground(self, event): @@ -469,7 +491,8 @@ class ToolTipWindowBase(object): if not isinstance(event, wx.MouseEvent): # We haven't clicked a link - self.Destroy() + if self: # Check if window still exists, Destroy might have been called manually (more than once) + self.Destroy() return x, y = event.GetPosition() @@ -644,91 +667,10 @@ class ToolTipWindowBase(object): def CalculateBestSize(self): """ Calculates the :class:`SuperToolTip` window best size. """ - # See the OnPaint method for explanations... - maxWidth = maxHeight = 0 - dc = wx.ClientDC(self) - - classParent = self._classParent - header, headerBmp = classParent.GetHeader(), classParent.GetHeaderBitmap() - - textHeight, bmpHeight = 0, 0 - headerFont, messageFont, footerFont, hyperlinkFont = classParent.GetHeaderFont(), classParent.GetMessageFont(), \ - classParent.GetFooterFont(), classParent.GetHyperlinkFont() - if header: - dc.SetFont(headerFont) - textWidth, textHeight = dc.GetTextExtent(header) - maxWidth = max(maxWidth, textWidth + 2*self._spacing) - maxHeight += self._spacing/2 - if headerBmp and headerBmp.IsOk(): - maxWidth += headerBmp.GetWidth() + 2*self._spacing - bmpHeight = headerBmp.GetHeight() - if not header: - maxHeight += self._spacing/2 - - maxHeight += max(textHeight, bmpHeight) - if textHeight or bmpHeight: - maxHeight += self._spacing/2 - - # See the OnPaint method for explanations... - bmpWidth = bmpHeight = -1 - embeddedImage = classParent.GetBodyImage() - if embeddedImage and embeddedImage.IsOk(): - bmpWidth, bmpHeight = embeddedImage.GetWidth(), embeddedImage.GetHeight() - - messageHeight = 0 - textSpacing = (bmpWidth and [3*self._spacing] or [2*self._spacing])[0] - lines = classParent.GetMessage().split("\n") - - for line in lines: - if line.startswith(""): # is a bold line - font = MakeBold(messageFont) - dc.SetFont(font) - line = line[4:] - elif line.startswith(""): # is a link - dc.SetFont(hyperlinkFont) - line, hl = ExtractLink(line) - else: - dc.SetFont(messageFont) - - textWidth, textHeight = dc.GetTextExtent(line) - if textHeight == 0: - textWidth, textHeight = dc.GetTextExtent("a") - - maxWidth = max(maxWidth, textWidth + textSpacing + bmpWidth) - messageHeight += textHeight - - # See the OnPaint method for explanations... - messageHeight = max(messageHeight, bmpHeight) - maxHeight += messageHeight - toAdd = 0 - if bmpHeight > textHeight: - maxHeight += 2*self._spacing - toAdd = self._spacing - else: - maxHeight += 2*self._spacing - - footer, footerBmp = classParent.GetFooter(), classParent.GetFooterBitmap() - textHeight, bmpHeight = 0, 0 - - # See the OnPaint method for explanations... - if footer: - dc.SetFont(footerFont) - textWidth, textHeight = dc.GetTextExtent(footer) - maxWidth = max(maxWidth, textWidth + 2*self._spacing) - maxHeight += self._spacing/2 - - if footerBmp and footerBmp.IsOk(): - bmpWidth, bmpHeight = footerBmp.GetWidth(), footerBmp.GetHeight() - maxWidth = max(maxWidth, textWidth + 3*self._spacing + bmpWidth) - if not footer: - maxHeight += self._spacing/2 - - if textHeight or bmpHeight: - maxHeight += self._spacing/2 + max(textHeight, bmpHeight) - - maxHeight += toAdd + maxWidth, maxHeight = self.OnPaint(None) self.SetSize((maxWidth, maxHeight)) + def CalculateBestPosition(self,widget): screen = wx.ClientDisplayRect()[2:] left,top = widget.ClientToScreenXY(0,0) @@ -903,11 +845,14 @@ class SuperToolTip(object): # The running app doesn't want tooltips... return + if not self._widget.GetTopLevelParent().IsActive(): + self._startTimer.Stop() + return + if self._startTimer.IsRunning(): # We are already running event.Skip() return - self._startTimer.Start(self._startDelayTime*1000) event.Skip() @@ -919,15 +864,6 @@ class SuperToolTip(object): :param `event`: a :class:`MouseEvent` event to be processed. """ - pos = wx.GetMousePosition() - realPos = self._widget.ScreenToClient(pos) - rect = self._widget.GetClientRect() - - if rect.Contains(realPos): - # We get fake leave events... - event.Skip() - return - if self._superToolTip: if self.GetUseFade(): # Fade out... @@ -1006,6 +942,24 @@ class SuperToolTip(object): self._endTimer.Start(self._endDelayTime*1000) + def DoHideNow(self): + """ + Dismiss the :class:`SuperToolTip` window immediately. + + .. versionadded:: 0.9.6 + """ + + if self._superToolTip: + if self.GetUseFade(): + # Fade out... + self._superToolTip.StartAlpha(False) + else: + self._superToolTip.Destroy() + + self._startTimer.Stop() + self._endTimer.Stop() + + def Show(self, show=True): """ Shows or hides the window. @@ -1014,7 +968,7 @@ class SuperToolTip(object): top, although this is not needed if :meth:`~SuperToolTip.Show` is called immediately after the frame creation. :param bool `show`: ``True`` to show the :class:`SuperToolTip` window, ``False`` to hide it. - + :return: ``True`` if the window has been shown or hidden or ``False`` if nothing was done because it already was in the requested state. @@ -1027,9 +981,15 @@ class SuperToolTip(object): .. versionadded:: 0.9.5 """ - - self.DoShowNow() - + + if show and self._superToolTip is None: + self.DoShowNow() + return True + elif not show and self._superToolTip is not None: + self.DoHideNow() + return True + return False + def Update(self): """ @@ -1458,7 +1418,16 @@ class SuperToolTip(object): wx.GetApp().__superToolTip = enable if not enable and self._superToolTip: - self._superToolTip.Destroy() - self._superToolTip = None + self.DoHideNow() del self._superToolTip + self._superToolTip = None + + def IsEnabled(self): + """ + Returns ``True`` when :class:`SuperToolTip` is globally enabled, ``False`` otherwise. + + .. versionadded:: 0.9.6 + """ + + return wx.GetApp().__superToolTip diff --git a/wx/lib/agw/ultimatelistctrl.py b/wx/lib/agw/ultimatelistctrl.py index 8fa14ec7..b8a9c90b 100644 --- a/wx/lib/agw/ultimatelistctrl.py +++ b/wx/lib/agw/ultimatelistctrl.py @@ -3,7 +3,7 @@ # Inspired by and heavily based on the wxWidgets C++ generic version of wxListCtrl. # # Andrea Gavana, @ 08 May 2009 -# Latest Revision: 04 Jul 2012, 18.00 GMT +# Latest Revision: 09 Aug 2012, 21.00 GMT # # # TODO List @@ -84,35 +84,35 @@ Usage Usage example:: import sys - - import wx + + import wx import wx.lib.agw.ultimatelistctrl as ULC - class MyFrame(wx.Frame): + class MyFrame(wx.Frame): def __init__(self): - + wx.Frame.__init__(self, parent, -1, "UltimateListCtrl Demo") - list = ULC.UltimateListCtrl(self, wx.ID_ANY, agwStyle=wx.LC_REPORT|wx.LC_VRULES|wx.LC_HRULES|wx.LC_SINGLE_SEL) + list = ULC.UltimateListCtrl(self, wx.ID_ANY, agwStyle=wx.LC_REPORT|wx.LC_VRULES|wx.LC_HRULES|wx.LC_SINGLE_SEL) - list.InsertColumn(0, "Column 1") - list.InsertColumn(1, "Column 2") + list.InsertColumn(0, "Column 1") + list.InsertColumn(1, "Column 2") - index = list.InsertStringItem(sys.maxint, "Item 1") - list.SetStringItem(index, 1, "Sub-item 1") + index = list.InsertStringItem(sys.maxint, "Item 1") + list.SetStringItem(index, 1, "Sub-item 1") - index = list.InsertStringItem(sys.maxint, "Item 2") - list.SetStringItem(index, 1, "Sub-item 2") + index = list.InsertStringItem(sys.maxint, "Item 2") + list.SetStringItem(index, 1, "Sub-item 2") - choice = wx.Choice(list, -1, choices=["one", "two"]) - index = list.InsertStringItem(sys.maxint, "A widget") + choice = wx.Choice(list, -1, choices=["one", "two"]) + index = list.InsertStringItem(sys.maxint, "A widget") - list.SetItemWindow(index, 1, choice, expand=True) + list.SetItemWindow(index, 1, choice, expand=True) - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(list, 1, wx.EXPAND) - self.SetSizer(sizer) + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(list, 1, wx.EXPAND) + self.SetSizer(sizer) # our normal wxApp-derived class, as usual @@ -225,7 +225,7 @@ License And Version UltimateListCtrl is distributed under the wxPython license. -Latest Revision: Andrea Gavana @ 04 Jul 2012, 18.00 GMT +Latest Revision: Andrea Gavana @ 09 Aug 2012, 21.00 GMT Version 0.8 @@ -288,7 +288,7 @@ ULC_TRACK_SELECT = 0x10000000 # Enables hot-track selection in a list c # is automatically selected when the cursor remains over the item for a certain period # of time. The delay is retrieved on Windows using the win32api call # win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERTIME), and is defaulted to 400ms - # on other platforms. This style applies to all styles of UltimateListCtrl. + # on other platforms. This style applies to all styles of UltimateListCtrl. ULC_HEADER_IN_ALL_VIEWS = 0x20000000 # Show column headers in all view modes ULC_NO_FULL_ROW_SELECT = 0x40000000 # When an item is selected, the only the item in the first column is highlighted ULC_FOOTER = 0x80000000 # Show a footer too (only when header is present) @@ -574,7 +574,7 @@ def to_list(input): return [input] else: raise Exception("Invalid parameter passed to `to_list`: only integers and list are accepted.") - + def CheckVariableRowHeight(listCtrl, text): """ @@ -616,7 +616,7 @@ def MakeDisabledBitmap(original): :param `original`: an instance of :class:`Bitmap` to be greyed-out. """ - + img = original.ConvertToImage() return wx.BitmapFromImage(img.ConvertToGreyscale()) @@ -675,7 +675,7 @@ class PyImageList(object): the style ``IL_VARIABLE_SIZE`` then each image can have any size (in terms of width and height). """ - + def __init__(self, width, height, mask=True, initialCount=1, style=IL_VARIABLE_SIZE): """ Default class constructor. @@ -696,7 +696,7 @@ class PyImageList(object): ``IL_VARIABLE_SIZE`` 1 Each image can have any size (in terms of width and height) ==================== ===== ================================= - """ + """ self._width = width self._height = height @@ -705,7 +705,7 @@ class PyImageList(object): self._style = style self._images = [] - + def GetImageCount(self): """ Returns the number of images in the list. """ @@ -728,7 +728,7 @@ class PyImageList(object): """ index = len(self._images) - + # Mimic behavior of Windows ImageList_Add that automatically breaks up the added # bitmap into sub-images of the correct size @@ -736,18 +736,18 @@ class PyImageList(object): if self._width > 0 and bitmap.GetWidth() > self._width and \ bitmap.GetHeight() >= self._height: - + numImages = bitmap.GetWidth()/self._width for subIndex in xrange(numImages): rect = wx.Rect(self._width * subIndex, 0, self._width, self._height) tmpBmp = bitmap.GetSubBitmap(rect) self._images.append(tmpBmp) - + else: - + self._images.append(bitmap) else: - + self._images.append(bitmap) if self._width == 0 and self._height == 0: @@ -790,7 +790,7 @@ class PyImageList(object): img = bitmap.ConvertToImage() img.SetMaskColour(maskColour.Red(), maskColour.Green(), maskColour.Blue()) - + return self.Add(wx.BitmapFromImage(img)) @@ -804,7 +804,7 @@ class PyImageList(object): if index >= len(self._images): return wx.NullBitmap - + return self._images[index] @@ -818,9 +818,9 @@ class PyImageList(object): if index >= len(self._images): return wx.NullIcon - + return wx.IconFromBitmap(self._images[index]) - + def Replace(self, index, bitmap): """ @@ -830,10 +830,10 @@ class PyImageList(object): :param `bitmap`: the new bitmap to add to the image list, an instance of :class:`Bitmap`. """ - + if index >= len(self._images): raise Exception("Wrong index in image list") - + self._images[index] = bitmap return True @@ -878,9 +878,9 @@ class PyImageList(object): :param `index`: the zero-based index of the image. - :return: a tuple of `(width, height)` properties of the chosen bitmap. + :return: a tuple of `(width, height)` properties of the chosen bitmap. """ - + if index >= len(self._images): raise Exception("Wrong index in image list") @@ -909,11 +909,11 @@ class PyImageList(object): :param `solidBackground`: currently unused. """ - + if index >= len(self._images): raise Exception("Wrong index in image list") - bmp = self._images[index] + bmp = self._images[index] dc.DrawBitmap(bmp, x, y, (flags & wx.IMAGELIST_DRAW_TRANSPARENT) > 0) return True @@ -955,7 +955,7 @@ class SelectionStore(object): # return the total number of selected items def GetSelectedCount(self): """ Return the total number of selected items. """ - + return (self._defaultState and [self._count - len(self._itemsSel)] or [len(self._itemsSel)])[0] @@ -990,17 +990,17 @@ class SelectionStore(object): isSel = index < len(self._itemsSel) and self._itemsSel[index] == item if select != self._defaultState: - + if item not in self._itemsSel: bisect.insort_right(self._itemsSel, item) return True - + else: # reset to default state - + if item in self._itemsSel: self._itemsSel.remove(item) return True - + return False @@ -1011,25 +1011,25 @@ class SelectionStore(object): :param `itemFrom`: the first index of the selection range; :param `itemTo`: the last index of the selection range; :param `select`: ``True`` to select the items, ``False`` otherwise. - + :return: ``True`` and fill the `itemsChanged` array with the indices of items which have changed state if "few" of them did, otherwise return ``False`` (meaning that too many items changed state to bother counting them individually). """ - + # 100 is hardcoded but it shouldn't matter much: the important thing is # that we don't refresh everything when really few (e.g. 1 or 2) items # change state MANY_ITEMS = 100 # many items (> half) changed state - itemsChanged = [] + itemsChanged = [] # are we going to have more [un]selected items than the other ones? if itemTo - itemFrom > self._count/2: if select != self._defaultState: - + # the default state now becomes the same as 'select' self._defaultState = select @@ -1044,13 +1044,13 @@ class SelectionStore(object): for item in xrange(itemFrom): if item not in selOld: self._itemsSel.append(item) - + for item in xrange(itemTo + 1, self._count): if item not in selOld: self._itemsSel.append(item) else: # select == self._defaultState - + # get the inclusive range of items between itemFrom and itemTo count = len(self._itemsSel) start = bisect.bisect_right(self._itemsSel, itemFrom) @@ -1061,27 +1061,27 @@ class SelectionStore(object): if start == count or self._itemsSel[start] < itemFrom: start += 1 - + if end == count or self._itemsSel[end] > itemTo: end -= 1 if start <= end: - + # delete all of them (from end to avoid changing indices) for i in xrange(end, start-1, -1): if itemsChanged: if len(itemsChanged) > MANY_ITEMS: # stop counting (see comment below) itemsChanged = [] - else: + else: itemsChanged.append(self._itemsSel[i]) - + self._itemsSel.pop(i) else: self._itemsSel = [] else: # "few" items change state - + if itemsChanged: itemsChanged = [] @@ -1114,13 +1114,13 @@ class SelectionStore(object): self._itemsSel.pop(i) count -= 1 - + # and adjust the index of all which follow it while i < count: - i += 1 + i += 1 self._itemsSel[i] -= 1 - + def SetItemCount(self, count): """ @@ -1135,7 +1135,7 @@ class SelectionStore(object): for i in xrange(len(self._itemsSel), 0, -1): if self._itemsSel[i - 1] >= count: self._itemsSel.pop(i - 1) - + # remember the new number of items self._count = count @@ -1149,7 +1149,7 @@ class UltimateListItemAttr(object): Represents the attributes (colour, font, ...) of a :class:`UltimateListCtrl` :class:`UltimateListItem`. """ - + def __init__(self, colText=wx.NullColour, colBack=wx.NullColour, font=wx.NullFont, enabled=True, footerColText=wx.NullColour, footerColBack=wx.NullColour, footerFont=wx.NullFont): @@ -1164,7 +1164,7 @@ class UltimateListItemAttr(object): :param `footerColBack`: for footer items, the item background colour; :param `footerFont`: for footer items, the item font. """ - + self._colText = colText self._colBack = colBack self._font = font @@ -1182,7 +1182,7 @@ class UltimateListItemAttr(object): :param `colText`: an instance of :class:`Colour`. """ - + self._colText = colText @@ -1213,7 +1213,7 @@ class UltimateListItemAttr(object): :param `enable`: ``True`` to enable the item, ``False`` to disable it. """ - self._enabled = enable + self._enabled = enable def SetFooterTextColour(self, colText): @@ -1249,7 +1249,7 @@ class UltimateListItemAttr(object): # accessors def HasTextColour(self): """ Returns ``True`` if the currently set text colour is valid. """ - + return self._colText.Ok() @@ -1332,7 +1332,7 @@ class UltimateListItemAttr(object): def IsEnabled(self): """ Returns ``True`` if the item is enabled. """ - return self._enabled + return self._enabled # ---------------------------------------------------------------------------- # UltimateListItem: the item or column info, used to exchange data with UltimateListCtrl @@ -1340,14 +1340,14 @@ class UltimateListItemAttr(object): class UltimateListItem(wx.Object): """ This class stores information about a :class:`UltimateListCtrl` item or column. """ - + def __init__(self, item=None): """ Default class constructor. :param `item`: if not ``None``, another instance of :class:`UltimateListItem`. """ - + if not item: self.Init() self._attr = None @@ -1392,7 +1392,7 @@ class UltimateListItem(wx.Object): # resetting def Clear(self): """ Resets the item state to the default. """ - + self.Init() self._text = "" self.ClearAttributes() @@ -1400,7 +1400,7 @@ class UltimateListItem(wx.Object): def ClearAttributes(self): """ Deletes the item attributes if they have been stored. """ - + if self._attr: del self._attr self._attr = None @@ -1440,9 +1440,9 @@ class UltimateListItem(wx.Object): ``ULC_MASK_FOOTER_CHECK`` 0x800000 :meth:`~UltimateListItem.IsFooterChecked` is valid ``ULC_MASK_FOOTER_KIND`` 0x1000000 :meth:`~UltimateListItem.GetFooterKind` is valid ============================ ========= ============================== - + """ - + self._mask = mask @@ -1452,7 +1452,7 @@ class UltimateListItem(wx.Object): :param `id`: the zero-based item position. """ - + self._itemId = id @@ -1461,10 +1461,10 @@ class UltimateListItem(wx.Object): Sets the zero-based column. :param `col`: the zero-based column. - + :note: This method is neaningful only in report mode. """ - + self._col = col @@ -1473,7 +1473,7 @@ class UltimateListItem(wx.Object): Sets the item state flags. :param `state`: any combination of the following bits: - + ============================ ========= ============================== State Bits Hex Value Description ============================ ========= ============================== @@ -1493,7 +1493,7 @@ class UltimateListItem(wx.Object): :see: :meth:`~UltimateListItem.SetStateMask` """ - + self._mask |= ULC_MASK_STATE self._state = state self._stateMask |= state @@ -1505,10 +1505,10 @@ class UltimateListItem(wx.Object): to be set. :param `stateMask`: the state bitmask. - + :see: :meth:`~UltimateListItem.SetState` for a list of valid state bits. """ - + self._stateMask = stateMask @@ -1518,11 +1518,11 @@ class UltimateListItem(wx.Object): :param `text`: the text label for the item. """ - + self._mask |= ULC_MASK_TEXT self._text = text - - + + def SetToolTip(self, text): """ Sets the tooltip text for the item. @@ -1541,11 +1541,11 @@ class UltimateListItem(wx.Object): :param `image`: a Python list with the zero-based indexes of the images associated with the item into the image list. """ - + self._mask |= ULC_MASK_IMAGE if image is None: image = [] - + self._image = to_list(image) @@ -1554,11 +1554,11 @@ class UltimateListItem(wx.Object): Sets client data for the item. :param `data`: the client data associated to the item. - + :note: Please note that client data is associated with the item and not with subitems. """ - + self._mask |= ULC_MASK_DATA self._data = data @@ -1568,14 +1568,14 @@ class UltimateListItem(wx.Object): Sets data for the item, which can be any Python object. :param `data`: any Python object associated to the item. - + :note: Please note that Python data is associated with the item and not with subitems. """ self._mask |= ULC_MASK_PYDATA self._pyData = pyData - + def SetWidth(self, width): """ @@ -1585,7 +1585,7 @@ class UltimateListItem(wx.Object): :note: This method is meaningful only for column headers in report mode. """ - + self._mask |= ULC_MASK_WIDTH self._width = width @@ -1606,7 +1606,7 @@ class UltimateListItem(wx.Object): ============================ ========= ============================== """ - + self._mask |= ULC_MASK_FORMAT self._format = align @@ -1617,7 +1617,7 @@ class UltimateListItem(wx.Object): :param `colText`: a valid :class:`Colour` object. """ - + self.Attributes().SetTextColour(colText) @@ -1678,7 +1678,7 @@ class UltimateListItem(wx.Object): :param `enable`: ``True`` to enable the item, ``False`` to disable it. """ - self.Attributes().Enable(enable) + self.Attributes().Enable(enable) # accessors def GetMask(self): @@ -1687,13 +1687,13 @@ class UltimateListItem(wx.Object): :see: :meth:`~UltimateListItem.SetMask` for a list of valid bit masks. """ - + return self._mask def GetId(self): """ Returns the zero-based item position. """ - + return self._itemId @@ -1719,7 +1719,7 @@ class UltimateListItem(wx.Object): :see: :meth:`~UltimateListItem.SetState` for a list of valid item states. """ - + return self._state & self._stateMask @@ -1728,7 +1728,7 @@ class UltimateListItem(wx.Object): return self._text - + def GetToolTip(self): """ Returns the label/header tooltip. """ @@ -1740,7 +1740,7 @@ class UltimateListItem(wx.Object): Returns a Python list with the zero-based indexes of the images associated with the item into the image list. """ - + return self._image @@ -1751,7 +1751,7 @@ class UltimateListItem(wx.Object): :note: Please note that client data is associated with the item and not with subitems. """ - + return self._data @@ -1764,7 +1764,7 @@ class UltimateListItem(wx.Object): """ return self._pyData - + def GetWidth(self): """ @@ -1782,7 +1782,7 @@ class UltimateListItem(wx.Object): :see: :meth:`~UltimateListItem.SetAlign` for a list of valid alignment bits. """ - + return self._format @@ -1820,21 +1820,21 @@ class UltimateListItem(wx.Object): """ Returns ``True`` if the item is enabled. """ return (self.HasAttributes() and [self._attr.IsEnabled()] or [True])[0] - + # creates self._attr if we don't have it yet def Attributes(self): """ Returns the associated attributes if they exist, or create a new :class:`UltimateListItemAttr` structure and associate it with this item. """ - + if not self._attr: self._attr = UltimateListItemAttr() return self._attr - def SetKind(self, kind): + def SetKind(self, kind): """ Sets the item kind. @@ -1852,7 +1852,7 @@ class UltimateListItem(wx.Object): self._mask |= ULC_MASK_KIND self._kind = kind - + def GetKind(self): """ @@ -1862,7 +1862,7 @@ class UltimateListItem(wx.Object): """ return self._kind - + def IsChecked(self): """ Returns whether the item is checked or not. """ @@ -1875,7 +1875,7 @@ class UltimateListItem(wx.Object): Checks/unchecks an item. :param `checked`: ``True`` to check an item, ``False`` to uncheck it. - + :note: This method is meaningful only for check and radio items. """ @@ -1887,7 +1887,7 @@ class UltimateListItem(wx.Object): """ Returns ``True`` if the item is shown, or ``False`` if it is hidden. """ return self._isColumnShown - + def SetShown(self, shown=True): """ @@ -1899,14 +1899,14 @@ class UltimateListItem(wx.Object): self._mask |= ULC_MASK_SHOWN self._isColumnShown = shown - + def SetHyperText(self, hyper=True): """ Sets whether the item is hypertext or not. :param `hyper`: ``True`` to set hypertext behaviour, ``False`` otherwise. """ - + self._mask |= ULC_MASK_HYPERTEXT self._hypertext = hyper @@ -1925,7 +1925,7 @@ class UltimateListItem(wx.Object): def GetVisited(self): """ Returns whether an hypertext item was visited or not. """ - return self._visited + return self._visited def IsHyperText(self): @@ -1948,7 +1948,7 @@ class UltimateListItem(wx.Object): listCtrl = wnd.GetParent() mainWin = listCtrl._mainWin - + wnd.Reparent(mainWin) if wnd.GetSizer(): # the window is a complex one hold by a sizer @@ -1960,10 +1960,10 @@ class UltimateListItem(wx.Object): # No other solution to handle the focus changing from an item in # UltimateListCtrl and the window associated to an item # Do better strategies exist? - self._wnd.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self._wnd.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self._windowsize = size - - # The window is enabled only if the item is enabled + + # The window is enabled only if the item is enabled self._wnd.Enable(self._enabled) self._windowenabled = self._enabled self._expandWin = expand @@ -1975,24 +1975,24 @@ class UltimateListItem(wx.Object): # are shown at the top left corner of ULC mainWin.HideWindows() mainWin.Refresh() - + def GetWindow(self): """ Returns the window associated to the item. """ - return self._wnd + return self._wnd def DeleteWindow(self): """ Deletes the window associated to the item (if any). """ if self._wnd: - listCtrl = self._wnd.GetParent() + listCtrl = self._wnd.GetParent() if self in listCtrl._itemWithWindow: - listCtrl._itemWithWindow.remove(self) + listCtrl._itemWithWindow.remove(self) self._wnd.Destroy() self._wnd = None - + def GetWindowEnabled(self): """ Returns whether the associated window is enabled or not. """ @@ -2019,8 +2019,8 @@ class UltimateListItem(wx.Object): def GetWindowSize(self): """ Returns the associated window size. """ - - return self._windowsize + + return self._windowsize def SetCustomRenderer(self, renderer): @@ -2030,7 +2030,7 @@ class UltimateListItem(wx.Object): :param `renderer`: a class able to correctly render the item. :note: the renderer class **must** implement the methods `DrawSubItem`, - `GetLineHeight` and `GetSubItemWidth`. + `GetLineHeight` and `GetSubItemWidth`. """ self._mask |= ULC_MASK_RENDERER @@ -2041,7 +2041,7 @@ class UltimateListItem(wx.Object): """ Returns the custom renderer associated with this item (if any). """ return self._customRenderer - + def SetOverFlow(self, over=True): """ @@ -2049,10 +2049,10 @@ class UltimateListItem(wx.Object): An item/subitem may overwrite neighboring items/subitems if its text would not normally fit in the space allotted to it. - - :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. + + :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. """ - + self._mask |= ULC_MASK_OVERFLOW self._overFlow = over @@ -2066,8 +2066,8 @@ class UltimateListItem(wx.Object): """ return self._overFlow - - + + def Init(self): """ Initializes an empty :class:`UltimateListItem`. """ @@ -2110,7 +2110,7 @@ class UltimateListItem(wx.Object): self._expandWin = False - def SetFooterKind(self, kind): + def SetFooterKind(self, kind): """ Sets the footer item kind. @@ -2119,7 +2119,7 @@ class UltimateListItem(wx.Object): self._mask |= ULC_MASK_FOOTER_KIND self._footerKind = kind - + def GetFooterKind(self): """ @@ -2129,7 +2129,7 @@ class UltimateListItem(wx.Object): """ return self._footerKind - + def IsFooterChecked(self): """ Returns whether the footer item is checked or not. """ @@ -2142,7 +2142,7 @@ class UltimateListItem(wx.Object): Checks/unchecks a footer item. :param `checked`: ``True`` to check an item, ``False`` to uncheck it. - + :note: This method is meaningful only for check and radio footer items. """ @@ -2243,7 +2243,7 @@ class UltimateListItem(wx.Object): """ return self._footerFormat - + def OnSetFocus(self, event): """ @@ -2263,7 +2263,7 @@ class UltimateListItem(wx.Object): listCtrl._hasFocus = True listCtrl.SetFocus() - + event.Skip() # ---------------------------------------------------------------------------- @@ -2275,7 +2275,7 @@ class CommandListEvent(wx.PyCommandEvent): A list event holds information about events associated with :class:`UltimateListCtrl` objects. """ - + def __init__(self, commandTypeOrEvent=None, winid=0): """ Default class constructor. @@ -2330,19 +2330,19 @@ class CommandListEvent(wx.PyCommandEvent): being dragged, for the column click events it may be -1 if the user clicked in the list control header outside any column. """ - + return self.m_col def GetPoint(self): """ Returns the position of the mouse pointer if the event is a drag event. """ - + return self.m_pointDrag def GetLabel(self): """ Returns the (new) item label for ``EVT_LIST_END_LABEL_EDIT`` event. """ - + return self.m_item._text @@ -2456,10 +2456,10 @@ class UltimateListEvent(CommandListEvent): else: self.notify = wx.NotifyEvent(commandTypeOrEvent.GetEventType(), commandTypeOrEvent.GetId()) - + def GetNotifyEvent(self): """ Returns the actual :class:`NotifyEvent`. """ - + return self.notify @@ -2494,7 +2494,7 @@ class UltimateListEvent(CommandListEvent): self.notify.Allow() - + # ============================================================================ # private classes # ============================================================================ @@ -2567,7 +2567,7 @@ class UltimateListItemData(object): Sets client data for the item. :param `data`: the client data associated to the item. - + :note: Please note that client data is associated with the item and not with subitems. """ @@ -2577,7 +2577,7 @@ class UltimateListItemData(object): def HasText(self): """ Returns ``True`` if the item text is not the empty string. """ - + return self._text != "" @@ -2585,8 +2585,8 @@ class UltimateListItemData(object): """ Returns the item text. """ return self._text - - + + def GetToolTip(self): """ Returns the item tooltip. """ @@ -2597,7 +2597,7 @@ class UltimateListItemData(object): """ Returns the currently set background colour. """ return self._backColour - + def GetColour(self): """ Returns the currently set text colour. """ @@ -2643,7 +2643,7 @@ class UltimateListItemData(object): self._hasColour = False del self._colour return - + self._hasColour = True self._colour = colour @@ -2659,7 +2659,7 @@ class UltimateListItemData(object): self._hasFont = False del self._font return - + self._hasFont = True self._font = font @@ -2675,10 +2675,10 @@ class UltimateListItemData(object): self._hasBackColour = False del self._backColour return - + self._hasBackColour = True self._backColour = colour - + # we can't use empty string for measuring the string width/height, so # always return something @@ -2687,7 +2687,7 @@ class UltimateListItemData(object): Returns the item text or a simple string if the item text is the empty string. """ - + s = self.GetText() if not s.strip(): s = 'H' @@ -2706,11 +2706,11 @@ class UltimateListItemData(object): def HasImage(self): """ Returns ``True`` if the item has at least one image associated with it. """ - + return len(self._image) > 0 - def SetKind(self, kind): + def SetKind(self, kind): """ Sets the item kind. @@ -2727,7 +2727,7 @@ class UltimateListItemData(object): """ self._kind = kind - + def GetKind(self): """ @@ -2737,7 +2737,7 @@ class UltimateListItemData(object): """ return self._kind - + def IsChecked(self): """ Returns whether the item is checked or not. """ @@ -2750,12 +2750,12 @@ class UltimateListItemData(object): Checks/unchecks an item. :param `checked`: ``True`` to check an item, ``False`` to uncheck it. - + :note: This method is meaningful only for check and radio items. """ self._checked = checked - + def SetHyperText(self, hyper=True): """ @@ -2763,7 +2763,7 @@ class UltimateListItemData(object): :param `hyper`: ``True`` to set hypertext behaviour, ``False`` otherwise. """ - + self._hypertext = hyper @@ -2780,7 +2780,7 @@ class UltimateListItemData(object): def GetVisited(self): """Returns whether an hypertext item was visited or not.""" - return self._visited + return self._visited def IsHyperText(self): @@ -2811,8 +2811,8 @@ class UltimateListItemData(object): # UltimateListCtrl and the window associated to an item # Do better strategies exist? self._windowsize = size - - # The window is enabled only if the item is enabled + + # The window is enabled only if the item is enabled self._wnd.Enable(self._enabled) self._windowenabled = self._enabled self._expandWin = expand @@ -2821,7 +2821,7 @@ class UltimateListItemData(object): def GetWindow(self): """ Returns the window associated to the item. """ - return self._wnd + return self._wnd def DeleteWindow(self): @@ -2830,7 +2830,7 @@ class UltimateListItemData(object): if self._wnd: self._wnd.Destroy() self._wnd = None - + def GetWindowEnabled(self): """ Returns whether the associated window is enabled or not. """ @@ -2857,10 +2857,10 @@ class UltimateListItemData(object): def GetWindowSize(self): """ Returns the associated window size. """ - - return self._windowsize - + return self._windowsize + + def SetAttr(self, attr): """ Sets the item attributes. @@ -2902,7 +2902,7 @@ class UltimateListItemData(object): :param `renderer`: a class able to correctly render the item. :note: the renderer class **must** implement the methods `DrawSubItem`, - `GetLineHeight` and `GetSubItemWidth`. + `GetLineHeight` and `GetSubItemWidth`. """ self._mask |= ULC_MASK_RENDERER @@ -2913,7 +2913,7 @@ class UltimateListItemData(object): """ Returns the custom renderer associated with this item (if any). """ return self._customRenderer - + def SetOverFlow(self, over=True): """ @@ -2921,8 +2921,8 @@ class UltimateListItemData(object): An item/subitem may overwrite neighboring items/subitems if its text would not normally fit in the space allotted to it. - - :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. + + :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. """ self._mask |= ULC_MASK_OVERFLOW @@ -2938,7 +2938,7 @@ class UltimateListItemData(object): """ return self._overFlow - + def Init(self): """ Initializes the item data structure. """ @@ -2954,14 +2954,14 @@ class UltimateListItemData(object): self._hasBackColour = False self._text = "" self._tooltip = "" - + # kind = 0: normal item # kind = 1: checkbox-type item self._kind = 0 self._checked = False self._enabled = True - + # custom attributes or None self._attr = None @@ -2987,7 +2987,7 @@ class UltimateListItemData(object): if info._mask & ULC_MASK_TEXT: CheckVariableRowHeight(self._owner, info._text) self.SetText(info._text) - + if info._mask & ULC_MASK_TOOLTIP: self.SetToolTip(info._tooltip) @@ -2999,7 +2999,7 @@ class UltimateListItemData(object): if info._mask & ULC_MASK_ENABLE: self._enabled = info._enabled - + if info._mask & ULC_MASK_IMAGE: self._image = info._image[:] @@ -3008,11 +3008,11 @@ class UltimateListItemData(object): if info._mask & ULC_MASK_PYDATA: self._pyData = info._pyData - + if info._mask & ULC_MASK_HYPERTEXT: self._hypertext = info._hypertext self._visited = info._visited - + if info._mask & ULC_MASK_FONTCOLOUR: self.SetColour(info.GetTextColour()) @@ -3036,7 +3036,7 @@ class UltimateListItemData(object): if info._mask & ULC_MASK_OVERFLOW: self._overFlow = info._overFlow - + if info.HasAttributes(): if self._attr: @@ -3093,7 +3093,7 @@ class UltimateListItemData(object): def GetX(self): """ Returns the item `x` position. """ - + return self._rect.x @@ -3186,8 +3186,8 @@ class UltimateListItemData(object): :param `enable`: ``True`` to enable the item, ``False`` to disable it. """ - self._enabled = enable - + self._enabled = enable + #----------------------------------------------------------------------------- # UltimateListHeaderData (internal) @@ -3202,7 +3202,7 @@ class UltimateListHeaderData(object): def __init__(self, item=None): """ Default class constructor. - + :param `item`: another instance of :class:`UltimateListHeaderData`. """ @@ -3222,8 +3222,8 @@ class UltimateListHeaderData(object): """ Returns the header/footer item text. """ return self._text - - + + def GetToolTip(self): """ Returns the header/footer item tooltip. """ @@ -3238,8 +3238,8 @@ class UltimateListHeaderData(object): """ self._text = text - - + + def SetToolTip(self, tip): """ Sets the header/footer item tooltip. @@ -3249,12 +3249,12 @@ class UltimateListHeaderData(object): self._tip = tip - + def GetFont(self): """ Returns the header/footer item font. """ - + return self._font - + def Init(self): """ Initializes the header/footer item. """ @@ -3281,7 +3281,7 @@ class UltimateListHeaderData(object): self._footerKind = 0 self._footerChecked = False self._footerFont = wx.NullFont - + def SetItem(self, item): """ @@ -3294,7 +3294,7 @@ class UltimateListHeaderData(object): if self._mask & ULC_MASK_TEXT: self._text = item._text - + if self._mask & ULC_MASK_TOOLTIP: self._tooltip = item._tooltip @@ -3321,7 +3321,7 @@ class UltimateListHeaderData(object): if self._mask & ULC_MASK_FOOTER_FONT: self._footerFont = item._footerFont - + if self._mask & ULC_MASK_FOOTER_KIND: self._footerKind = item._footerKind self._footerChecked = item._footerChecked @@ -3343,7 +3343,7 @@ class UltimateListHeaderData(object): if self._mask & ULC_MASK_SHOWN: self._isColumnShown = item._isColumnShown - + if self._mask & ULC_MASK_RENDERER: self._customRenderer = item._customRenderer @@ -3353,7 +3353,7 @@ class UltimateListHeaderData(object): Sets the item state flags. :param `state`: any combination of the following bits: - + ============================ ========= ============================== State Bits Hex Value Description ============================ ========= ============================== @@ -3417,7 +3417,7 @@ class UltimateListHeaderData(object): :param `format`: the header item format. """ - + self._format = format @@ -3429,7 +3429,7 @@ class UltimateListHeaderData(object): """ self._footerFormat = format - + def HasImage(self): """ @@ -3447,7 +3447,7 @@ class UltimateListHeaderData(object): """ return len(self._footerImage) > 0 - + def IsHit(self, x, y): """ @@ -3502,7 +3502,7 @@ class UltimateListHeaderData(object): return self._state - + def GetImage(self): """ Returns a Python list with the zero-based indexes of the images associated @@ -3519,11 +3519,11 @@ class UltimateListHeaderData(object): """ return self._footerImage - + def GetWidth(self): """ Returns the header/footer item width, in pixels. """ - + return self._width @@ -3547,7 +3547,7 @@ class UltimateListHeaderData(object): """ self._font = font - + def SetFooterFont(self, font): """ @@ -3559,7 +3559,7 @@ class UltimateListHeaderData(object): self._footerFont = font - def SetKind(self, kind): + def SetKind(self, kind): """ Sets the header item kind. @@ -3576,9 +3576,9 @@ class UltimateListHeaderData(object): """ self._kind = kind - - def SetFooterKind(self, kind): + + def SetFooterKind(self, kind): """ Sets the footer item kind. @@ -3598,7 +3598,7 @@ class UltimateListHeaderData(object): """ return self._kind - + def GetFooterKind(self): """ @@ -3621,7 +3621,7 @@ class UltimateListHeaderData(object): Checks/unchecks a header item. :param `checked`: ``True`` to check an item, ``False`` to uncheck it. - + :note: This method is meaningful only for check and radio header items. """ @@ -3639,13 +3639,13 @@ class UltimateListHeaderData(object): Checks/unchecks a footer item. :param `checked`: ``True`` to check an item, ``False`` to uncheck it. - + :note: This method is meaningful only for check and radio footer items. """ self._footerChecked = check - + def SetCustomRenderer(self, renderer): """ Associate a custom renderer to this item. @@ -3653,7 +3653,7 @@ class UltimateListHeaderData(object): :param `renderer`: a class able to correctly render the item. :note: the renderer class **must** implement the methods `DrawHeaderButton` - and `GetForegroundColor`. + and `GetForegroundColor`. """ self._mask |= ULC_MASK_RENDERER @@ -3664,7 +3664,7 @@ class UltimateListHeaderData(object): """ Returns the custom renderer associated with this item (if any). """ return self._customRenderer - + #----------------------------------------------------------------------------- # GeometryInfo (internal) @@ -3763,7 +3763,7 @@ class UltimateListLineData(object): del self._gi self._gi = None - + else: self._gi = GeometryInfo() @@ -3814,13 +3814,13 @@ class UltimateListLineData(object): :param `x`: the new line `x` position. """ - self._x = x + self._x = x def GetY(self): """ Returns the line `y` position. """ - return self._y + return self._y def SetY(self, y): @@ -3836,9 +3836,9 @@ class UltimateListLineData(object): def ResetDimensions(self): """ Resets the line dimensions (client rectangle). """ - self._height = self._width = self._x = self._y = -1 + self._height = self._width = self._x = self._y = -1 + - def HasImage(self, col=0): """ Returns ``True`` if the first item in the line has at least one image @@ -3881,11 +3881,11 @@ class UltimateListLineData(object): """ return self._owner.GetListCtrl().HasAGWFlag(mode) - + def InReportView(self): """ Returns ``True`` if the parent :class:`UltimateListCtrl` is in report view. """ - + return self._owner.HasAGWFlag(ULC_REPORT) @@ -3952,7 +3952,7 @@ class UltimateListLineData(object): self._gi._rectHighlight.width = self._gi._rectIcon.width self._gi._rectHighlight.height = self._gi._rectIcon.height - + elif mode == ULC_LIST: s = item.GetTextForMeasuring() @@ -3987,10 +3987,10 @@ class UltimateListLineData(object): self._gi._rectCheck.height = h self._gi._rectAll.width += 4 + w - + if h > self._gi._rectAll.height: self._gi._rectAll.height = h - + self._gi._rectHighlight.width = self._gi._rectAll.width self._gi._rectHighlight.height = self._gi._rectAll.height @@ -4029,7 +4029,7 @@ class UltimateListLineData(object): self._gi._rectLabel.x = self._gi._rectAll.x + 2 else: self._gi._rectLabel.x = self._gi._rectAll.x + 2 + (spacing/2) - (self._gi._rectLabel.width/2) - + self._gi._rectLabel.y = self._gi._rectAll.y + self._gi._rectAll.height + 2 - self._gi._rectLabel.height self._gi._rectHighlight.x = self._gi._rectLabel.x - 2 self._gi._rectHighlight.y = self._gi._rectLabel.y - 2 @@ -4045,13 +4045,13 @@ class UltimateListLineData(object): self._gi._rectAll.y = y wcheck = hcheck = 0 - + if item.GetKind() in [1, 2]: wcheck, hcheck = self._owner.GetCheckboxImageSize() wcheck += 2 self._gi._rectCheck.x = self._gi._rectAll.x + 2 self._gi._rectCheck.y = self._gi._rectAll.y + 2 - + self._gi._rectHighlight.x = self._gi._rectAll.x self._gi._rectHighlight.y = self._gi._rectAll.y self._gi._rectLabel.y = self._gi._rectAll.y + 2 @@ -4114,7 +4114,7 @@ class UltimateListLineData(object): :param `index`: the index of the item. """ - + item = self._items[index] return item.GetText() @@ -4137,7 +4137,7 @@ class UltimateListLineData(object): :param `index`: the index of the item. """ - + item = self._items[index] return item.GetToolTip() @@ -4186,7 +4186,7 @@ class UltimateListLineData(object): :param `index`: the index of the item; :param `checked`: ``True`` to check an item, ``False`` to uncheck it. - + :note: This method is meaningful only for check and radio items. """ @@ -4198,7 +4198,7 @@ class UltimateListLineData(object): """ Sets the item kind. - :param `index`: the index of the item; + :param `index`: the index of the item; :param `kind`: may be one of the following integers: =============== ========================== @@ -4213,7 +4213,7 @@ class UltimateListLineData(object): item = self._items[index] item.SetKind(kind) - + def GetKind(self, index=0): """ @@ -4256,7 +4256,7 @@ class UltimateListLineData(object): Returns an instance of :class:`UltimateListItemAttr` associated with the first item in the line. """ - + item = self._items[0] return item.GetAttr() @@ -4280,7 +4280,7 @@ class UltimateListLineData(object): :param `attr`: an instance of :class:`UltimateListItemAttr`; :param `highlighted`: ``True`` if the item is highlighted, ``False`` otherwise. """ - + listctrl = self._owner.GetParent() # fg colour @@ -4417,7 +4417,7 @@ class UltimateListLineData(object): r.width -= 1 r.height -= 1 dc.DrawRoundedRectangleRect(r, 4) - + def HideItemWindow(self, item): """ @@ -4429,7 +4429,7 @@ class UltimateListLineData(object): wnd = item.GetWindow() if wnd and wnd.IsShown(): wnd.Hide() - + def DrawInReportMode(self, dc, line, rect, rectHL, highlighted, current, enabled, oldPN, oldBR): """ @@ -4446,7 +4446,7 @@ class UltimateListLineData(object): :param `oldPN`: an instance of :class:`Pen`, to save and restore at the end of the drawing; :param `oldBR`: an instance of :class:`Brush`, to save and restore at the end of - the drawing. + the drawing. """ attr = self.GetAttr() @@ -4456,12 +4456,12 @@ class UltimateListLineData(object): hasFocus = self._owner._hasFocus borderOnly = self._owner.HasAGWFlag(ULC_BORDER_SELECT) nofullRow = self._owner.HasAGWFlag(ULC_NO_FULL_ROW_SELECT) - + drawn = False dc.SetBrush(wx.TRANSPARENT_BRUSH) if nofullRow: - + x = rect.x + HEADER_OFFSET_X y = rect.y height = rect.height @@ -4478,14 +4478,14 @@ class UltimateListLineData(object): else: - paintRect = wx.Rect(*rectHL) - + paintRect = wx.Rect(*rectHL) + if self.SetAttributes(dc, attr, highlighted) and enabled: - + drawn = True - + if not borderOnly: - + if useGradient: if gradientStyle == 0: # horizontal gradient @@ -4503,13 +4503,13 @@ class UltimateListLineData(object): flags |= wx.CONTROL_FOCUSED if current: flags |= wx.CONTROL_CURRENT - - wx.RendererNative.Get().DrawItemSelectionRect(self._owner, dc, paintRect, flags) + + wx.RendererNative.Get().DrawItemSelectionRect(self._owner, dc, paintRect, flags) else: dc.DrawRectangleRect(paintRect) else: - + if borderOnly: dc.SetBrush(wx.WHITE_BRUSH) @@ -4523,11 +4523,11 @@ class UltimateListLineData(object): boldFont.SetWeight(wx.BOLD) for col, item in enumerate(self._items): - + if not self._owner.IsColumnShown(col): self.HideItemWindow(item) continue - + width = self._owner.GetColumnWidth(col) xOld = x x += width @@ -4538,25 +4538,25 @@ class UltimateListLineData(object): continue overflow = item.GetOverFlow() and item.HasText() - + if item.GetKind() in [1, 2]: - + # We got a checkbox-type item ix, iy = self._owner.GetCheckboxImageSize() checked = item.IsChecked() self._owner.DrawCheckbox(dc, xOld, y + (height-iy+1)/2, item.GetKind(), checked, enabled) xOld += ix width -= ix - + if item.HasImage(): images = item.GetImage() - + for img in images: - + ix, iy = self._owner.GetImageSize([img]) self._owner.DrawImage(img, dc, xOld, y + (height-iy)/2, enabled) - + xOld += ix width -= ix @@ -4578,7 +4578,7 @@ class UltimateListLineData(object): itemRect = wx.Rect(xOld-2*HEADER_OFFSET_X, rect.y, rectHL.width-xSize-HEADER_OFFSET_X, rect.height) dc.SetClippingRect(itemRect) - + if item.HasBackgroundColour(): dc.SetBrush(wx.Brush(item.GetBackgroundColour())) dc.SetPen(wx.Pen(item.GetBackgroundColour())) @@ -4589,7 +4589,7 @@ class UltimateListLineData(object): if item.HasText(): coloured = item.HasColour() - + c = dc.GetTextForeground() oldTF = wx.Colour(c.Red(),c.Green(),c.Blue()) oldFT = dc.GetFont() @@ -4614,7 +4614,7 @@ class UltimateListLineData(object): if font: dc.SetFont(item.GetFont()) - itemRect = wx.Rect(itemRect.x+MARGIN_BETWEEN_TEXT_AND_ICON, itemRect.y, itemRect.width-8, itemRect.height) + itemRect = wx.Rect(itemRect.x+MARGIN_BETWEEN_TEXT_AND_ICON, itemRect.y, itemRect.width-8, itemRect.height) self.DrawTextFormatted(dc, item.GetText(), line, col, itemRect, overflow) if coloured: @@ -4628,14 +4628,14 @@ class UltimateListLineData(object): if wnd: if not wnd.IsShown(): wnd.Show() - + if item._expandWin: wRect = wx.Rect(*itemRect) wRect.x += xa + 2 wRect.width = width - 8 wRect.y = ya + 2 wRect.height -= 4 - if wnd.GetRect() != wRect: + if wnd.GetRect() != wRect: wnd.SetRect(wRect) else: if wnd.GetPosition() != (wndx, ya): @@ -4659,7 +4659,7 @@ class UltimateListLineData(object): rect.height -= 1 dc.DrawRoundedRectangleRect(rect, 3) dc.SetPen(oldPN) - + def DrawTextFormatted(self, dc, text, row, col, itemRect, overflow): """ @@ -4692,17 +4692,17 @@ class UltimateListLineData(object): textAlign = wx.ALIGN_LEFT if w <= width: - + if tuples in shortItems: shortItems.remove(tuples) dc.DrawLabel(text, itemRect, textAlign|wx.ALIGN_CENTER_VERTICAL) - + else: # otherwise, truncate and add an ellipsis if possible if tuples not in shortItems: shortItems.append(tuples) - + # determine the base width ellipsis = "..." base_w, h = dc.GetTextExtent(ellipsis) @@ -4713,7 +4713,7 @@ class UltimateListLineData(object): theText = "" for text in newText: - + lenText = len(text) drawntext = text w, dummy = dc.GetTextExtent(text) @@ -4727,7 +4727,7 @@ class UltimateListLineData(object): drawntext = drawntext[0:-1] lenText -= 1 w -= w_c - + # if still not enough space, remove ellipsis characters while len(ellipsis) > 0 and w + base_w > width: ellipsis = ellipsis[0:-1] @@ -4736,7 +4736,7 @@ class UltimateListLineData(object): theText += drawntext + ellipsis + "\n" theText = theText.rstrip() - # now draw the text + # now draw the text dc.DrawLabel(theText, itemRect, textAlign|wx.ALIGN_CENTER_VERTICAL) @@ -4772,15 +4772,15 @@ class UltimateListLineData(object): bstep = float((b2 - b1)) / flrect rf, gf, bf = 0, 0, 0 - + for y in xrange(rect.y, rect.y + rect.height): - currCol = (r1 + rf, g1 + gf, b1 + bf) + currCol = (r1 + rf, g1 + gf, b1 + bf) dc.SetBrush(wx.Brush(currCol, wx.SOLID)) dc.DrawRectangle(rect.x, y, rect.width, 1) rf = rf + rstep gf = gf + gstep bf = bf + bstep - + dc.SetPen(oldpen) dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangleRect(rect) @@ -4833,7 +4833,7 @@ class UltimateListLineData(object): dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangleRect(rect) dc.SetBrush(oldbrush) - + def DrawVistaRectangle(self, dc, rect, hasfocus): """ @@ -4846,14 +4846,14 @@ class UltimateListLineData(object): """ if hasfocus: - + outer = _rgbSelectOuter inner = _rgbSelectInner top = _rgbSelectTop bottom = _rgbSelectBottom else: - + outer = _rgbNoFocusOuter inner = _rgbNoFocusInner top = _rgbNoFocusTop @@ -4865,7 +4865,7 @@ class UltimateListLineData(object): bdrRect = wx.Rect(*rect.Get()) filRect = wx.Rect(*rect.Get()) filRect.Deflate(1,1) - + r1, g1, b1 = int(top.Red()), int(top.Green()), int(top.Blue()) r2, g2, b2 = int(bottom.Red()), int(bottom.Green()), int(bottom.Blue()) @@ -4879,7 +4879,7 @@ class UltimateListLineData(object): rf, gf, bf = 0, 0, 0 dc.SetPen(wx.TRANSPARENT_PEN) - + for y in xrange(filRect.y, filRect.y + filRect.height): currCol = (r1 + rf, g1 + gf, b1 + bf) dc.SetBrush(wx.Brush(currCol, wx.SOLID)) @@ -4887,7 +4887,7 @@ class UltimateListLineData(object): rf = rf + rstep gf = gf + gstep bf = bf + bstep - + dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.SetPen(wx.Pen(outer)) dc.DrawRoundedRectangleRect(bdrRect, 3) @@ -4898,7 +4898,7 @@ class UltimateListLineData(object): dc.SetPen(oldpen) dc.SetBrush(oldbrush) - + def Highlight(self, on): """ Sets the current line as highlighted or not highlighted. @@ -4938,7 +4938,7 @@ class UltimateListHeaderWindow(wx.PyControl): name="UltimateListCtrlcolumntitles", isFooter=False): """ Default class constructor. - + :param `parent`: parent window. Must not be ``None``; :param `id`: window identifier. A value of -1 indicates a default value; :param `owner`: an instance of :class:`UltimateListCtrl`; @@ -4952,7 +4952,7 @@ class UltimateListHeaderWindow(wx.PyControl): :param `isFooter`: ``True`` if the :class:`UltimateListHeaderWindow` is in a footer position, ``False`` otherwise. """ - + wx.PyControl.__init__(self, win, id, pos, size, style|wx.NO_BORDER, validator, name) self._isFooter = isFooter @@ -4962,10 +4962,10 @@ class UltimateListHeaderWindow(wx.PyControl): self._isDragging = False self._headerHeight = None self._footerHeight = None - + # Custom renderer for every column self._headerCustomRenderer = None - + # column being resized or -1 self._column = -1 @@ -5017,12 +5017,12 @@ class UltimateListHeaderWindow(wx.PyControl): :param `renderer`: a class able to correctly render header buttons :note: the renderer class **must** implement the methods `DrawHeaderButton` - and `GetForegroundColor`. + and `GetForegroundColor`. """ if not self._owner.HasAGWFlag(ULC_REPORT): raise Exception("Custom renderers can be used on with style = ULC_REPORT") - + self._headerCustomRenderer = renderer @@ -5041,7 +5041,7 @@ class UltimateListHeaderWindow(wx.PyControl): if self._footerHeight is not None: self.GetParent()._footerHeight = self._footerHeight return wx.Size(200, self._footerHeight) - + w, h, d, dummy = self.GetFullTextExtent("Hg") maxH = self.GetTextHeight() nativeH = wx.RendererNative.Get().GetHeaderButtonHeight(self.GetParent()) @@ -5054,7 +5054,7 @@ class UltimateListHeaderWindow(wx.PyControl): maxH = max(h, nativeH) maxH += d self.GetParent()._footerHeight = maxH - + return wx.Size(200, maxH) @@ -5062,7 +5062,7 @@ class UltimateListHeaderWindow(wx.PyControl): """ Returns the :class:`UltimateListHeaderWindow` height, in pixels. """ return self.DoGetBestSize() - + def IsColumnShown(self, column): """ @@ -5076,7 +5076,7 @@ class UltimateListHeaderWindow(wx.PyControl): return self._owner.IsColumnShown(column) - + # shift the DC origin to match the position of the main window horz # scrollbar: this allows us to always use logical coords def AdjustDC(self, dc): @@ -5084,7 +5084,7 @@ class UltimateListHeaderWindow(wx.PyControl): Shifts the :class:`DC` origin to match the position of the main window horizontal scrollbar: this allows us to always use logical coordinates. - :param `dc`: an instance of :class:`DC`. + :param `dc`: an instance of :class:`DC`. """ xpix, dummy = self._owner.GetScrollPixelsPerUnit() @@ -5101,7 +5101,7 @@ class UltimateListHeaderWindow(wx.PyControl): numColumns = self._owner.GetColumnCount() dc = wx.ClientDC(self) for i in xrange(numColumns): - + if not self.IsColumnShown(i): continue @@ -5110,13 +5110,13 @@ class UltimateListHeaderWindow(wx.PyControl): dc.SetFont(item.GetFont()) else: dc.SetFont(self.GetFont()) - + wLabel, hLabel, dummy = dc.GetMultiLineTextExtent(item.GetText()) maxH = max(maxH, hLabel) return maxH - - + + def OnPaint(self, event): """ Handles the ``wx.EVT_PAINT`` event for :class:`UltimateListHeaderWindow`. @@ -5131,7 +5131,7 @@ class UltimateListHeaderWindow(wx.PyControl): dc.SetBrush(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))) dc.SetPen(wx.TRANSPARENT_PEN) dc.DrawRectangle(0, -1, w, h+2) - + self.AdjustDC(dc) dc.SetBackgroundMode(wx.TRANSPARENT) @@ -5147,7 +5147,7 @@ class UltimateListHeaderWindow(wx.PyControl): isFooter = self._isFooter for i in xrange(numColumns): - + # Reset anything in the dc that a custom renderer might have changed dc.SetTextForeground(self.GetForegroundColour()) @@ -5156,7 +5156,7 @@ class UltimateListHeaderWindow(wx.PyControl): if not self.IsColumnShown(i): continue # do next column if not shown - + item = self._owner.GetColumn(i) wCol = item._width @@ -5175,7 +5175,7 @@ class UltimateListHeaderWindow(wx.PyControl): if "__WXMAC__" in wx.PlatformInfo: if not virtual and item._mask & ULC_MASK_STATE and item._state & ULC_STATE_SELECTED: flags |= wx.CONTROL_SELECTED - + if i == 0: flags |= wx.CONTROL_SPECIAL # mark as first column @@ -5185,20 +5185,20 @@ class UltimateListHeaderWindow(wx.PyControl): else: if self._enter: flags |= wx.CONTROL_CURRENT - + # the width of the rect to draw: make it smaller to fit entirely # inside the column rect header_rect = wx.Rect(x-1, HEADER_OFFSET_Y-1, cw-1, ch) if self._headerCustomRenderer != None: self._headerCustomRenderer.DrawHeaderButton(dc, header_rect, flags) - + # The custom renderer will specify the color to draw the header text and buttons dc.SetTextForeground(self._headerCustomRenderer.GetForegroundColour()) - - elif item._mask & ULC_MASK_RENDERER: + + elif item._mask & ULC_MASK_RENDERER: item.GetCustomRenderer().DrawHeaderButton(dc, header_rect, flags) - + # The custom renderer will specify the color to draw the header text and buttons dc.SetTextForeground(item.GetCustomRenderer().GetForegroundColour()) else: @@ -5220,7 +5220,7 @@ class UltimateListHeaderWindow(wx.PyControl): wcheck = hcheck = 0 kind = (isFooter and [item.GetFooterKind()] or [item.GetKind()])[0] checked = (isFooter and [item.IsFooterChecked()] or [item.IsChecked()])[0] - + if kind in [1, 2]: # We got a checkbox-type item ix, iy = self._owner.GetCheckboxImageSize() @@ -5250,7 +5250,7 @@ class UltimateListHeaderWindow(wx.PyControl): imageList = None # ignore alignment if there is not enough space anyhow - align = (isFooter and [item.GetFooterAlign()] or [item.GetAlign()])[0] + align = (isFooter and [item.GetFooterAlign()] or [item.GetAlign()])[0] align = (wLabel < cw and [align] or [ULC_FORMAT_LEFT])[0] if align == ULC_FORMAT_LEFT: @@ -5277,7 +5277,7 @@ class UltimateListHeaderWindow(wx.PyControl): # boundary dc.SetClippingRegion(x, HEADER_OFFSET_Y, cw, h - 4) self.DrawTextFormatted(dc, text, wx.Rect(xAligned+EXTRA_WIDTH, HEADER_OFFSET_Y, cw-EXTRA_WIDTH, h-4)) - + x += wCol dc.DestroyClippingRegion() @@ -5308,11 +5308,11 @@ class UltimateListHeaderWindow(wx.PyControl): width = rect.width if w <= width: - + dc.DrawLabel(text, rect, wx.ALIGN_CENTER_VERTICAL) else: - + # determine the base width ellipsis = "..." base_w, h = dc.GetTextExtent(ellipsis) @@ -5323,7 +5323,7 @@ class UltimateListHeaderWindow(wx.PyControl): theText = "" for text in newText: - + lenText = len(text) drawntext = text w, dummy = dc.GetTextExtent(text) @@ -5337,7 +5337,7 @@ class UltimateListHeaderWindow(wx.PyControl): drawntext = drawntext[0:-1] lenText -= 1 w -= w_c - + # if still not enough space, remove ellipsis characters while len(ellipsis) > 0 and w + base_w > width: ellipsis = ellipsis[0:-1] @@ -5347,7 +5347,7 @@ class UltimateListHeaderWindow(wx.PyControl): theText = theText.rstrip() dc.DrawLabel(theText, rect, wx.ALIGN_CENTER_VERTICAL) - + def OnInternalIdle(self): """ @@ -5364,12 +5364,12 @@ class UltimateListHeaderWindow(wx.PyControl): if self._isFooter: return - + if self._sendSetColumnWidth: self._owner.SetColumnWidth(self._colToSend, self._widthToSend) self._sendSetColumnWidth = False - + def DrawCurrent(self): """ Force the redrawing of the column window. """ @@ -5389,7 +5389,7 @@ class UltimateListHeaderWindow(wx.PyControl): x, dummy = self._owner.CalcUnscrolledPosition(event.GetX(), 0) y = event.GetY() - columnX, columnY = x, y + columnX, columnY = x, y if self._isDragging: @@ -5399,7 +5399,7 @@ class UltimateListHeaderWindow(wx.PyControl): # there w, dummy = self.GetClientSize() - w, dummy = self._owner.CalcUnscrolledPosition(w, 0) + w, dummy = self._owner.CalcUnscrolledPosition(w, 0) w -= 6 # erase the line if it was drawn @@ -5442,7 +5442,7 @@ class UltimateListHeaderWindow(wx.PyControl): if not self.IsColumnShown(col): continue - + xpos += self._owner.GetColumnWidth(col) self._column = col @@ -5465,17 +5465,17 @@ class UltimateListHeaderWindow(wx.PyControl): self._column = -1 if tipCol >= 0: - # First check to see if we have a tooltip to display + # First check to see if we have a tooltip to display colItem = self._owner.GetColumn(col) if colItem.GetToolTip() != "": self.SetToolTipString(colItem.GetToolTip()) else: self.SetToolTipString("") - + if event.LeftUp(): self._leftDown = False self.Refresh() - + if event.LeftDown() or event.RightUp(): if hit_border and event.LeftDown(): @@ -5496,12 +5496,12 @@ class UltimateListHeaderWindow(wx.PyControl): # record the selected state of the columns if event.LeftDown(): - + for i in xrange(self._owner.GetColumnCount()): if not self.IsColumnShown(col): continue - + colItem = self._owner.GetColumn(i) state = colItem.GetState() @@ -5524,7 +5524,7 @@ class UltimateListHeaderWindow(wx.PyControl): else: self.SendListEvent((event.LeftDown() and [wxEVT_COMMAND_LIST_FOOTER_CLICK] or \ [wxEVT_COMMAND_LIST_FOOTER_RIGHT_CLICK])[0], event.GetPosition()) - + self._leftDown = True self._currentColumn = self._column @@ -5557,12 +5557,12 @@ class UltimateListHeaderWindow(wx.PyControl): self._leftDown = leftDown - self.Refresh() + self.Refresh() - elif event.ButtonDClick(): + elif event.ButtonDClick(): self.HandleColumnCheck(self._column, event.GetPosition()) - + def HandleColumnCheck(self, column, pos): """ @@ -5571,10 +5571,10 @@ class UltimateListHeaderWindow(wx.PyControl): :param `column`: the column index; :param `pos`: the mouse position. """ - + if column < 0 or column >= self._owner.GetColumnCount(): return False - + colItem = self._owner.GetColumn(column) # Let's see if it is a checkbox-type item @@ -5583,7 +5583,7 @@ class UltimateListHeaderWindow(wx.PyControl): return False x = HEADER_OFFSET_X - + for i in xrange(self._owner.GetColumnCount()): if not self.IsColumnShown(i): @@ -5595,11 +5595,11 @@ class UltimateListHeaderWindow(wx.PyControl): x += self._owner.GetColumnWidth(i) parent = self.GetParent() - + w, h = self.GetClientSize() ix, iy = self._owner.GetCheckboxImageSize() rect = wx.Rect(theX + HEADER_OFFSET_X, HEADER_OFFSET_Y + (h - 4 - iy)/2, ix, iy) - + if rect.Contains(pos): # User clicked on the checkbox evt = (self._isFooter and [wxEVT_COMMAND_LIST_FOOTER_CHECKING] or [wxEVT_COMMAND_LIST_COL_CHECKING])[0] @@ -5607,11 +5607,11 @@ class UltimateListHeaderWindow(wx.PyControl): # No veto for the item checking if self._isFooter: isChecked = colItem.IsFooterChecked() - colItem.CheckFooter(not isChecked) + colItem.CheckFooter(not isChecked) else: isChecked = colItem.IsChecked() colItem.Check(not isChecked) - + self._owner.SetColumn(column, colItem) evt = (self._isFooter and [wxEVT_COMMAND_LIST_FOOTER_CHECKED] or [wxEVT_COMMAND_LIST_COL_CHECKED])[0] self.SendListEvent(evt, pos) @@ -5619,7 +5619,7 @@ class UltimateListHeaderWindow(wx.PyControl): if self._isFooter: return True - + if parent.HasAGWFlag(ULC_AUTO_CHECK_CHILD): self._owner.AutoCheckChild(isChecked, self._column) elif parent.HasAGWFlag(ULC_AUTO_TOGGLE_CHILD): @@ -5660,7 +5660,7 @@ class UltimateListHeaderWindow(wx.PyControl): self._enter = False self._leftDown = False - + self._currentColumn = -1 self.Refresh() @@ -5675,20 +5675,20 @@ class UltimateListHeaderWindow(wx.PyControl): :return: The column index if any column client rectangle contains the mouse position, ``wx.NOT_FOUND`` otherwise. """ - + xOld = 0 - + for i in xrange(self._owner.GetColumnCount()): if not self.IsColumnShown(i): continue - + xOld += self._owner.GetColumnWidth(i) if x <= xOld: return i - return -1 - - + return -1 + + def OnSetFocus(self, event): """ Handles the ``wx.EVT_SET_FOCUS`` event for :class:`UltimateListHeaderWindow`. @@ -5744,16 +5744,16 @@ class UltimateListRenameTimer(wx.Timer): :param `owner`: an instance of :class:`UltimateListCtrl`. """ - + wx.Timer.__init__(self) - self._owner = owner + self._owner = owner def Notify(self): """ The timer has expired. """ self._owner.OnRenameTimer() - + #----------------------------------------------------------------------------- # UltimateListTextCtrl (internal) @@ -5782,7 +5782,7 @@ class UltimateListTextCtrl(ExpandoTextCtrl): self._startValue = owner.GetItemText(itemEdit) self._currentValue = self._startValue - + self._itemEdited = itemEdit self._owner = owner @@ -5798,7 +5798,7 @@ class UltimateListTextCtrl(ExpandoTextCtrl): expandoStyle |= wx.SIMPLE_BORDER else: expandoStyle |= wx.SUNKEN_BORDER - + ExpandoTextCtrl.__init__(self, owner, -1, self._startValue, wx.Point(rectLabel.x, rectLabel.y), wx.Size(xSize, ySize), expandoStyle) @@ -5827,11 +5827,11 @@ class UltimateListTextCtrl(ExpandoTextCtrl): # accepted, do rename the item self._owner.SetItemText(self._itemEdited, value) - + if value.count("\n") != self._startValue.count("\n"): self._owner.ResetLineDimensions() self._owner.Refresh() - + return True @@ -5845,7 +5845,7 @@ class UltimateListTextCtrl(ExpandoTextCtrl): self._owner.ResetTextControl() except wx.PyDeadObjectError: return - + def OnChar(self, event): """ @@ -5873,7 +5873,7 @@ class UltimateListTextCtrl(ExpandoTextCtrl): else: event.Skip() - + def OnKeyUp(self, event): """ @@ -5896,7 +5896,7 @@ class UltimateListTextCtrl(ExpandoTextCtrl): sx = parentSize.x - myPos.x if mySize.x > sx: sx = mySize.x - + self.SetSize((sx, -1)) self._currentValue = self.GetValue() @@ -5909,15 +5909,15 @@ class UltimateListTextCtrl(ExpandoTextCtrl): :param `event`: a :class:`FocusEvent` event to be processed. """ - + if not self._finished and not self._aboutToFinish: - + # We must finish regardless of success, otherwise we'll get # focus problems: - + if not self.AcceptChanges(): self._owner.OnRenameCancelled(self._itemEdited) - + # We must let the native text control handle focus, too, otherwise # it could have problems with the cursor (e.g., in wxGTK). event.Skip() @@ -5939,12 +5939,12 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ This is the main widget implementation of :class:`UltimateListCtrl`. """ - + def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, agwStyle=0, name="listctrlmainwindow"): """ Default class constructor. - + :param `parent`: parent window. Must not be ``None``; :param `id`: window identifier. A value of -1 indicates a default value; :param `pos`: the control position. A value of (-1, -1) indicates a default position, @@ -5995,7 +5995,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `name`: the window name. """ - + wx.PyScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) # the list of column objects @@ -6010,11 +6010,11 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # the number of lines per page self._linesPerPage = 0 - + # Automatically resized column - this column expands to fill the width of the window self._resizeColumn = -1 self._resizeColMinWidth = None - + # this flag is set when something which should result in the window # redrawing happens (i.e. an item was added or deleted, or its appearance # changed) and OnPaint() doesn't redraw the window while it is set which @@ -6026,7 +6026,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.Init() self._highlightBrush = wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT), wx.SOLID) - + btnshadow = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) self._highlightUnfocusedBrush = wx.Brush(btnshadow, wx.SOLID) r, g, b = btnshadow.Red(), btnshadow.Green(), btnshadow.Blue() @@ -6035,12 +6035,12 @@ class UltimateListMainWindow(wx.PyScrolledWindow): max((b >> 1) - 20, 0)) backcolour = wx.Colour(backcolour[0], backcolour[1], backcolour[2]) self._highlightUnfocusedBrush2 = wx.Brush(backcolour) - + self.SetScrollbars(0, 0, 0, 0, 0, 0) attr = wx.ListCtrl.GetClassDefaultAttributes() self.SetOwnForegroundColour(attr.colFg) - self.SetOwnBackgroundColour(attr.colBg) + self.SetOwnBackgroundColour(attr.colBg) self.SetOwnFont(attr.font) self.Bind(wx.EVT_PAINT, self.OnPaint) @@ -6049,16 +6049,16 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.Bind(wx.EVT_CHILD_FOCUS, self.OnChildFocus) self.Bind(wx.EVT_CHAR, self.OnChar) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) - self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) + self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) self.Bind(wx.EVT_SCROLLWIN, self.OnScroll) self.Bind(wx.EVT_TIMER, self.OnHoverTimer, self._hoverTimer) - + def Init(self): """ Initializes the :class:`UltimateListMainWindow` widget. """ - + self._dirty = True self._countVirt = 0 self._lineFrom = None @@ -6068,7 +6068,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._headerWidth = 0 self._lineHeight = 0 self._userLineHeight = None - + self._small_image_list = None self._normal_image_list = None @@ -6098,10 +6098,10 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._backgroundImage = None self._imageStretchStyle = _StyleTile - # Disabled items colour + # Disabled items colour self._disabledColour = wx.Colour(180, 180, 180) - # Gradient selection colours + # Gradient selection colours self._firstcolour = colour= wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) self._secondcolour = wx.WHITE self._usegradients = False @@ -6110,9 +6110,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # Vista Selection Styles self._vistaselection = False - self.SetImageListCheck(16, 16) - - # Disabled items colour + self.SetImageListCheck(16, 16) + + # Disabled items colour self._disabledColour = wx.Colour(180, 180, 180) # Hyperlinks things @@ -6153,7 +6153,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def GetMainWindowOfCompositeControl(self): """ Returns the :class:`UltimateListMainWindow` parent. """ - + return self.GetParent() @@ -6165,7 +6165,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ return wx.Size(100, 80) - + def HasAGWFlag(self, flag): """ @@ -6207,24 +6207,24 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ Returns ``True`` if the window is in tile mode (partially implemented). - .. todo:: Fully implement tile view for :class:`UltimateListCtrl`. + .. todo:: Fully implement tile view for :class:`UltimateListCtrl`. """ - return self.HasAGWFlag(ULC_TILE) + return self.HasAGWFlag(ULC_TILE) # return True if we are in single selection mode, False if multi sel def IsSingleSel(self): """ Returns ``True`` if we are in single selection mode, ``False`` if multi selection. """ - + return self.HasAGWFlag(ULC_SINGLE_SEL) def HasFocus(self): """ Returns ``True`` if the window has focus. """ - + return self._hasFocus - + # do we have a header window? def HasHeader(self): """ Returns ``True`` if the header window is shown. """ @@ -6254,7 +6254,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `line`: an instance of :class:`UltimateListLineData`. """ - + self.HighlightLine(line, not self.IsHighlighted(line)) self.RefreshLine(line) @@ -6272,8 +6272,8 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._userLineHeight = height return - raise Exception("SetUserLineHeight can only be used with styles ULC_REPORT and ULC_USER_ROW_HEIGHT set.") - + raise Exception("SetUserLineHeight can only be used with styles ULC_REPORT and ULC_USER_ROW_HEIGHT set.") + def GetUserLineHeight(self): """ @@ -6286,7 +6286,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.HasAGWFlag(ULC_REPORT) and self.HasAGWFlag(ULC_USER_ROW_HEIGHT): return self._userLineHeight - raise Exception("GetUserLineHeight can only be used with styles ULC_REPORT and ULC_USER_ROW_HEIGHT set.") + raise Exception("GetUserLineHeight can only be used with styles ULC_REPORT and ULC_USER_ROW_HEIGHT set.") # get the size of the total line rect @@ -6296,7 +6296,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `line`: an instance of :class:`UltimateListLineData`. """ - + return self.GetLineRect(line).GetSize() @@ -6372,9 +6372,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `font`: a valid :class:`Font` object. - :note: Overridden from :class:`PyScrolledWindow`. + :note: Overridden from :class:`PyScrolledWindow`. """ - + if not wx.PyScrolledWindow.SetFont(self, font): return False @@ -6396,7 +6396,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): for l in xrange(self.GetItemCount()): line = self.GetLine(l) line.ResetDimensions() - + # these are for UltimateListLineData usage only # get the backpointer to the list ctrl def GetListCtrl(self): @@ -6408,7 +6408,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # get the brush to use for the item highlighting def GetHighlightBrush(self): """ Returns the brush to use for the item highlighting. """ - + return (self._hasFocus and [self._highlightBrush] or [self._highlightUnfocusedBrush])[0] @@ -6441,7 +6441,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.IsShownOnScreen() and reset: self.ResetLineDimensions() - + # Called on EVT_SIZE to resize the _resizeColumn to fill the width of the window def ResizeColumns(self): """ @@ -6453,14 +6453,14 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if not self: # Avoid PyDeadObjectErrors on Mac return - + if self._resizeColumn == -1: return - - + + numCols = self.GetColumnCount() if numCols == 0: return # Nothing to resize. - + resizeCol = self._resizeColumn if self._resizeColMinWidth == None: @@ -6546,7 +6546,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :note: This method is used only if the :class:`UltimateListCtrl` has the ``ULC_VIRTUAL`` style set. """ - + if self.IsEmpty(): raise Exception("invalid line index") @@ -6582,9 +6582,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.HasAGWFlag(ULC_REPORT) and self.HasAGWFlag(ULC_USER_ROW_HEIGHT): if self._userLineHeight is not None: return self._userLineHeight - + if item is None or not self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): - + if not self._lineHeight: dc = wx.ClientDC(self) dc.SetFont(self.GetFont()) @@ -6598,7 +6598,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._lineHeight = y + LINE_SPACING return self._lineHeight - + else: line = self.GetLine(item) @@ -6607,9 +6607,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): return LH dc = wx.ClientDC(self) - + allTextY = 0 - + for col, items in enumerate(line._items): if items.GetCustomRenderer(): @@ -6648,12 +6648,12 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.IsVirtual(): return LINE_SPACING + line*self.GetLineHeight() - + lineItem = self.GetLine(line) lineY = lineItem.GetY() if lineY != -1: return lineY - + lineY = 0 for l in xrange(line): lineY += self.GetLineHeight(l) @@ -6679,7 +6679,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def GetLineLabelRect(self, line, col=0): """ Returns the line client rectangle for the item text only. - Note this is the full column width unless an image or + Note this is the full column width unless an image or checkbox exists. It is not the width of the text itself :param `line`: an instance of :class:`UltimateListLineData`. @@ -6690,10 +6690,10 @@ class UltimateListMainWindow(wx.PyScrolledWindow): image_x = 0 image_width = 0 - + for c in range(col): image_x += self.GetColumnWidth(c) - + item = self.GetLine(line) if item.HasImage(col): ix, iy = self.GetImageSize(item.GetImage(col)) @@ -6703,10 +6703,10 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if item.GetKind(col) in [1, 2]: image_x += self.GetCheckboxImageSize()[0] image_width += self.GetCheckboxImageSize()[0] - + rect = wx.Rect(image_x + HEADER_OFFSET_X, self.GetLineY(line), self.GetColumnWidth(col) - image_width, self.GetLineHeight(line)) return rect - + def GetLineIconRect(self, line): """ @@ -6723,7 +6723,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): image_x = HEADER_OFFSET_X if ld.GetKind() in [1, 2]: image_x += self.GetCheckboxImageSize()[0] - + rect = wx.Rect(image_x, self.GetLineY(line), *self.GetImageSize(ld.GetImage())) return rect @@ -6737,13 +6737,13 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if not self.InReportView(): return self.GetLine(line)._gi._rectCheck - + ld = self.GetLine(line) LH = self.GetLineHeight(line) wcheck, hcheck = self.GetCheckboxImageSize() rect = wx.Rect(HEADER_OFFSET_X, self.GetLineY(line) + LH/2 - hcheck/2, wcheck, hcheck) return rect - + def GetLineHighlightRect(self, line): """ @@ -6781,7 +6781,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): ``ULC_HITTEST_TORIGHT`` 0x800 To the right of the client area ``ULC_HITTEST_ONITEMCHECK`` 0x1000 On the item checkbox (if any) =============================== ========= ================================ - + """ ld = self.GetLine(line) @@ -6790,12 +6790,12 @@ class UltimateListMainWindow(wx.PyScrolledWindow): lineY = self.GetLineY(line) xstart = HEADER_OFFSET_X - + for col, item in enumerate(ld._items): if not self.IsColumnShown(col): continue - + width = self.GetColumnWidth(col) xOld = xstart xstart += width @@ -6807,7 +6807,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if rect.Contains((x, y)): newItem = self.GetParent().GetItem(line, col) return newItem, ULC_HITTEST_ONITEMLABEL - + if item.GetKind() in [1, 2]: # We got a checkbox-type item ix, iy = self.GetCheckboxImageSize() @@ -6816,19 +6816,19 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if rect.Contains((x, y)): newItem = self.GetParent().GetItem(line, col) return newItem, ULC_HITTEST_ONITEMCHECK - + if item.IsHyperText(): start, end = self.GetItemTextSize(item) rect = wx.Rect(xOld+start, lineY, end, self.GetLineHeight(line)) if rect.Contains((x, y)): newItem = self.GetParent().GetItem(line, col) return newItem, ULC_HITTEST_ONITEMLABEL - + xOld += ix - + if ld.HasImage() and self.GetLineIconRect(line).Contains((x, y)): return self.GetParent().GetItem(line), ULC_HITTEST_ONITEMICON - + # VS: Testing for "ld.HasText() || InReportView()" instead of # "ld.HasText()" is needed to make empty lines in report view # possible @@ -6841,7 +6841,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): return self.GetParent().GetItem(line), ULC_HITTEST_ONITEMCHECK rect = self.GetLineLabelRect(line) - + if rect.Contains((x, y)): return self.GetParent().GetItem(line), ULC_HITTEST_ONITEMLABEL @@ -7038,7 +7038,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def HideWindows(self): """ Hides the windows associated to the items. Used internally. """ - + for child in self._itemWithWindow: wnd = child.GetWindow() if wnd: @@ -7055,22 +7055,22 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # Note: a wxPaintDC must be constructed even if no drawing is # done (a Windows requirement). dc = wx.BufferedPaintDC(self) - + dc.SetBackgroundMode(wx.TRANSPARENT) - + self.PrepareDC(dc) dc.SetBackground(wx.Brush(self.GetBackgroundColour())) dc.SetPen(wx.TRANSPARENT_PEN) dc.Clear() - + self.TileBackground(dc) self.PaintWaterMark(dc) if self.IsEmpty(): # nothing to draw or not the moment to draw it return - + if self._dirty: # delay the repainting until we calculate all the items positions self.RecalculatePositions(False) @@ -7079,10 +7079,10 @@ class UltimateListMainWindow(wx.PyScrolledWindow): dev_x, dev_y = self.CalcScrolledPosition(0, 0) dc.SetFont(self.GetFont()) - + if self.InReportView(): visibleFrom, visibleTo = self.GetVisibleLinesRange() - + # mrcs: draw additional items if visibleFrom > 0: visibleFrom -= 1 @@ -7149,13 +7149,13 @@ class UltimateListMainWindow(wx.PyScrolledWindow): dc.SetPen(pen) dc.SetBrush(wx.TRANSPARENT_BRUSH) for col in xrange(self.GetColumnCount()): - + if not self.IsColumnShown(col): continue colWidth = self.GetColumnWidth(col) x += colWidth - + x_pos = x - dev_x if col < self.GetColumnCount()-1: x_pos -= 2 @@ -7178,18 +7178,18 @@ class UltimateListMainWindow(wx.PyScrolledWindow): dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangleRect(self.GetLineHighlightRect(self._current)) - + def OnEraseBackground(self, event): """ Handles the ``wx.EVT_ERASE_BACKGROUND`` event for :class:`UltimateListMainWindow`. :param `event`: a :class:`EraseEvent` event to be processed. - :note: This method is intentionally empty to reduce flicker. + :note: This method is intentionally empty to reduce flicker. """ pass - + def TileBackground(self, dc): """ @@ -7238,7 +7238,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): return width, height = self.CalcUnscrolledPosition(*self.GetClientSize()) - + bitmapW = self._waterMark.GetWidth() bitmapH = self._waterMark.GetHeight() @@ -7246,8 +7246,8 @@ class UltimateListMainWindow(wx.PyScrolledWindow): y = height - bitmapH - 5 dc.DrawBitmap(self._waterMark, x, y, True) - - + + def HighlightAll(self, on=True): """ Highlights/unhighlights all the lines in :class:`UltimateListCtrl`. @@ -7281,7 +7281,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): This method is intentionally empty to prevent the default handler in :class:`PyScrolledWindow` from needlessly scrolling the window when the edit control is dismissed. - + """ # Do nothing here. This prevents the default handler in wx.PyScrolledWindow @@ -7289,7 +7289,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # dismissed. See ticket #9563. pass - + def SendNotify(self, line, command, point=wx.DefaultPosition): """ @@ -7333,7 +7333,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): Changes the current line to the specified one. :param `current`: an integer specifying the index of the current line. - """ + """ self._current = current @@ -7341,7 +7341,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # "slow click" timer expires as the click happened on another item if self._renameTimer.IsRunning(): self._renameTimer.Stop() - + self.SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED) @@ -7397,7 +7397,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): ``EVT_LIST_END_LABEL_EDIT`` event. :param `itemEdit`: an instance of :class:`UltimateListItem`; - :param `value`: the new value of the item label. + :param `value`: the new value of the item label. """ le = UltimateListEvent(wxEVT_COMMAND_LIST_END_LABEL_EDIT, self.GetParent().GetId()) @@ -7408,7 +7408,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): le.m_item = data.GetItem(0, le.m_item) le.m_item._text = value - + return not self.GetParent().GetEventHandler().ProcessEvent(le) or le.IsAllowed() @@ -7510,17 +7510,17 @@ class UltimateListMainWindow(wx.PyScrolledWindow): break theItem = None - + if not self.IsVirtual(): theItem = CreateListItem(current, 0) theItem = self.GetItem(theItem) - + if event.GetEventType() == wx.wxEVT_MOTION and not event.Dragging(): if current >= 0 and current < count and self.HasAGWFlag(ULC_TRACK_SELECT) and not self._hoverTimer.IsRunning(): self._hoverItem = current self._hoverTimer.Start(HOVER_TIME, wx.TIMER_ONE_SHOT) - + if newItem and newItem.IsHyperText() and (hitResult & ULC_HITTEST_ONITEMLABEL) and theItem and theItem.IsEnabled(): self.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) self._isonhyperlink = True @@ -7541,11 +7541,11 @@ class UltimateListMainWindow(wx.PyScrolledWindow): line = self.GetLine(r) tt = line.GetToolTip(c) if tt and not tt == "": - if self.GetToolTip() and self.GetToolTip().GetTip() != tt: + if self.GetToolTip() and self.GetToolTip().GetTip() != tt: self.SetToolTipString(tt) elif (r,c) in self._shortItems: # if the text didn't fit in the column text = newItem.GetText() - if self.GetToolTip() and self.GetToolTip().GetTip() != text: + if self.GetToolTip() and self.GetToolTip().GetTip() != text: self.SetToolTipString(text) else: self.SetToolTipString("") @@ -7554,18 +7554,18 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.HasAGWFlag(ULC_HOT_TRACKING): if hitResult: - if self._oldHotCurrent != current: + if self._oldHotCurrent != current: if self._oldHotCurrent is not None: self.RefreshLine(self._oldHotCurrent) self._newHotCurrent = current self.RefreshLine(self._newHotCurrent) self._oldHotCurrent = current - + event.Skip() return if event.Dragging(): - + if not self._isDragging: if self._lineLastClicked == -1 or not hitResult or not theItem or not theItem.IsEnabled(): @@ -7597,11 +7597,11 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # dragging self._oldCursor = self._cursor self.SetCursor(self._dragCursor) - + else: if current != self._dropTarget: - + self.SetCursor(self._dragCursor) # unhighlight the previous drop target if self._dropTarget is not None: @@ -7617,15 +7617,15 @@ class UltimateListMainWindow(wx.PyScrolledWindow): else: if self._dragItem == current: - self.SetCursor(wx.StockCursor(wx.CURSOR_NO_ENTRY)) + self.SetCursor(wx.StockCursor(wx.CURSOR_NO_ENTRY)) if self.HasAGWFlag(ULC_REPORT) and self._dragItem != current: self.DrawDnDArrow() return - + else: - + self._dragCount = 0 if theItem and not theItem.IsEnabled(): @@ -7651,7 +7651,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if event.ButtonDClick(): if self._renameTimer.IsRunning(): self._renameTimer.Stop() - + self._lastOnSame = False if current == self._lineLastClicked: @@ -7689,10 +7689,10 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._lineSelectSingleOnUp = -1 elif event.RightUp(): - + if self.DragFinish(event): return - + else: # This is necessary, because after a DnD operation in @@ -7733,7 +7733,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.HighlightAll(False) self.ChangeCurrent(current) self.ReverseHighlight(self._current) - + else: # multi sel & current is highlighted & no mod keys self._lineSelectSingleOnUp = current self.ChangeCurrent(current) # change focus @@ -7754,28 +7754,28 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if not self.IsHighlighted(lineFrom): shift = 1 - + for i in xrange(lineFrom+1, lineTo+1): if self.IsHighlighted(i): self.HighlightLine(i, False) self.RefreshLine(i) lineTo -= 1 - + self.HighlightLines(lineFrom, lineTo+shift) else: # !ctrl, !shift # test in the enclosing if should make it impossible raise Exception("how did we get here?") - + if newItem: if event.LeftDown(): - if newItem.GetKind() in [1, 2] and (hitResult & ULC_HITTEST_ONITEMCHECK): + if newItem.GetKind() in [1, 2] and (hitResult & ULC_HITTEST_ONITEMCHECK): self.CheckItem(newItem, not self.IsItemChecked(newItem)) if newItem.IsHyperText(): self.SetItemVisited(newItem, True) self.HandleHyperLink(newItem) - + if self._current != oldCurrent: self.RefreshLine(oldCurrent) @@ -7788,11 +7788,11 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def DrawDnDArrow(self): """ Draws a drag and drop visual representation of an arrow. """ - + dc = wx.ClientDC(self) lineY = self.GetLineY(self._dropTarget) width = self.GetTotalWidth() - + dc.SetPen(wx.Pen(wx.BLACK, 2)) x, y = self.CalcScrolledPosition(HEADER_OFFSET_X, lineY+2*HEADER_OFFSET_Y) @@ -7800,9 +7800,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): tri2 = [wx.Point(x+width-1, y-2), wx.Point(x+width-1, y+4), wx.Point(x+width-4, y+1)] dc.DrawPolygon(tri1) dc.DrawPolygon(tri2) - + dc.DrawLine(x, y+1, width, y+1) - + def DragFinish(self, event): """ @@ -7813,7 +7813,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if not self._isDragging: return False - + self._isDragging = False self._dragCount = 0 self._dragItem = None @@ -7827,13 +7827,13 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.GetParent().GetEventHandler().ProcessEvent(le) return True - + def HandleHyperLink(self, item): """ Handles the hyperlink items, sending the ``EVT_LIST_ITEM_HYPERLINK`` event. - :param `item`: an instance of :class:`UltimateListItem`. + :param `item`: an instance of :class:`UltimateListItem`. """ if self.IsItemHyperText(item): @@ -7853,11 +7853,11 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if item and item._itemId == self._hoverItem: if not self.IsHighlighted(self._hoverItem): - + dontNotify = self.HasAGWFlag(ULC_STICKY_HIGHLIGHT) and self.HasAGWFlag(ULC_STICKY_NOSELEVENT) if not dontNotify: self.SendNotify(self._hoverItem, wxEVT_COMMAND_LIST_ITEM_SELECTED) - + self.HighlightAll(False) self.ChangeCurrent(self._hoverItem) self.ReverseHighlight(self._current) @@ -7875,7 +7875,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if item >= self.GetItemCount(): item = self.GetItemCount() - 1 - + rect = self.GetLineRect(item) client_w, client_h = self.GetClientSize() hLine = self.GetLineHeight(item) @@ -7889,7 +7889,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # recalculate it self.ResetVisibleLinesRange() - if not self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): + if not self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): if rect.y < view_y: self.Scroll(-1, rect.y/hLine) @@ -7905,7 +7905,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # too but couldn't duplicate it there. Perhaps the order of events # is different... --Robin self.ResetVisibleLinesRange() - + else: view_y = SCROLL_UNIT_Y*self.GetScrollPos(wx.VERTICAL) @@ -7916,13 +7916,13 @@ class UltimateListMainWindow(wx.PyScrolledWindow): start_y -= SCROLL_UNIT_Y self.Scroll(-1, start_y/SCROLL_UNIT_Y) - + if start_y + height > view_y + client_h: while start_y + height < view_y + client_h: start_y += SCROLL_UNIT_Y self.Scroll(-1, (start_y+height-client_h+SCROLL_UNIT_Y)/SCROLL_UNIT_Y) - + else: # !report @@ -7939,7 +7939,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): sy = (rect.y + rect.height - client_h + hLine)/hLine self.Scroll(sx, sy) - + # ---------------------------------------------------------------------------- # keyboard handling @@ -7956,7 +7956,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): count = self.GetItemCount() initialItem = item - + while 1: if item >= count or item < 0: return initialItem @@ -7965,7 +7965,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): listItem = self.GetItem(listItem, 0) if listItem.IsEnabled(): return item - + item = (down and [item+1] or [item-1])[0] @@ -7979,7 +7979,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): oldCurrent = self._current newCurrent = self.GetNextActiveItem(newCurrent, newCurrent > oldCurrent) - + # in single selection we just ignore Shift as we can't select several # items anyhow if event.ShiftDown() and not self.IsSingleSel(): @@ -8053,7 +8053,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): for attr in attributes: setattr(newEvent, attr, getattr(oldEvent, attr)) - + def OnKeyDown(self, event): """ @@ -8067,14 +8067,14 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # we propagate the key event upwards ke = wx.KeyEvent(event.GetEventType()) self.SetEventAttrs(event, ke) - + ke.SetEventObject(parent) if parent.GetEventHandler().ProcessEvent(ke): event.Skip() return event.Skip() - + def OnKeyUp(self, event): """ @@ -8094,7 +8094,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): return event.Skip() - + def OnChar(self, event): """ @@ -8109,7 +8109,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): event.Skip() return - # we send a list_key event up + # we send a list_key event up if self.HasCurrent(): le = UltimateListEvent(wxEVT_COMMAND_LIST_KEY_DOWN, self.GetParent().GetId()) le.m_itemIndex = self._current @@ -8128,7 +8128,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): ke.SetEventObject(parent) if parent.GetEventHandler().ProcessEvent(ke): return - + if event.GetKeyCode() == wx.WXK_TAB: nevent = wx.NavigationKeyEvent() nevent.SetWindowChange(event.ControlDown()) @@ -8144,7 +8144,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): return keyCode = event.GetKeyCode() - + if keyCode == wx.WXK_UP: if self._current > 0: self.OnArrowChar(self._current - 1, event) @@ -8170,7 +8170,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): elif keyCode == wx.WXK_PRIOR: steps = (self.InReportView() and [self._linesPerPage - 1] or [self._current % self._linesPerPage])[0] index = self._current - steps - + if index < 0: index = 0 @@ -8182,7 +8182,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): steps = (self.InReportView() and [self._linesPerPage - 1] or [self._linesPerPage - (self._current % self._linesPerPage) - 1])[0] index = self._current + steps count = self.GetItemCount() - + if index >= count: index = count - 1 @@ -8203,7 +8203,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): index = self._current + self._linesPerPage count = self.GetItemCount() - + if index >= count: index = count - 1 @@ -8329,14 +8329,14 @@ class UltimateListMainWindow(wx.PyScrolledWindow): index = (checked and [2] or [3])[0] imgList.Draw(index, dc, x, y, wx.IMAGELIST_DRAW_TRANSPARENT) - + def GetCheckboxImageSize(self): """ Returns the checkbox/radiobutton image size. """ bmp = self._image_list_check.GetBitmap(0) return bmp.GetWidth(), bmp.GetHeight() - + def GetImageSize(self, index): """ @@ -8413,7 +8413,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): imageList = PyImageList(16, 16) imageList.Add(someBitmap) self.SetImageList(imageList, wx.IMAGE_LIST_SMALL) - + """ self._dirty = True @@ -8451,7 +8451,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): newbmp = MakeDisabledBitmap(bmp) self._small_grayed_image_list.Add(newbmp) - self._lineHeight = 0 # ensure that the line height will be recalc'd + self._lineHeight = 0 # ensure that the line height will be recalc'd self.ResetLineDimensions() @@ -8468,7 +8468,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._grayed_check_list = wx.ImageList(sizex, sizey, True, 0) if imglist is None: - + self._image_list_check = wx.ImageList(sizex, sizey) # Get the Checkboxes @@ -8513,7 +8513,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._image_list_check = imglist for ii in xrange(self._image_list_check.GetImageCount()): - + bmp = self._image_list_check.GetBitmap(ii) newbmp = MakeDisabledBitmap(bmp) self._grayed_check_list.Add(newbmp) @@ -8527,13 +8527,13 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def GetControlBmp(self, checkbox=True, checked=False, enabled=True, x=16, y=16): """ Returns a native looking checkbox or radio button bitmap. - + :param `checkbox`: ``True`` to get a checkbox image, ``False`` for a radiobutton one; :param `checked`: ``True`` if the control is marked, ``False`` if it is not; :param `enabled`: ``True`` if the control is enabled, ``False`` if it is not; :param `x`: the width of the bitmap, in pixels; - :param `y`: the height of the bitmap, in pixels. + :param `y`: the height of the bitmap, in pixels. """ bmp = wx.EmptyBitmap(x, y) @@ -8572,7 +8572,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ self._dirty = True - + if isSmall: self._small_spacing = spacing else: @@ -8624,17 +8624,17 @@ class UltimateListMainWindow(wx.PyScrolledWindow): Sets the column width. :param `width`: can be a width in pixels or ``wx.LIST_AUTOSIZE`` (-1) or - ``wx.LIST_AUTOSIZE_USEHEADER`` (-2) or ``ULC_AUTOSIZE_FILL`` (-3). + ``wx.LIST_AUTOSIZE_USEHEADER`` (-2) or ``ULC_AUTOSIZE_FILL`` (-3). ``wx.LIST_AUTOSIZE`` will resize the column to the length of its longest item. ``wx.LIST_AUTOSIZE_USEHEADER`` will resize the column to the - length of the header (Win32) or 80 pixels (other platforms). + length of the header (Win32) or 80 pixels (other platforms). ``ULC_AUTOSIZE_FILL`` will resize the column fill the remaining width of the window. :note: In small or normal icon view, col must be -1, and the column width is set for all columns. """ - + if col < 0: raise Exception("invalid column index") @@ -8644,7 +8644,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._dirty = True headerWin = self.GetListCtrl()._headerWin footerWin = self.GetListCtrl()._footerWin - + if headerWin: headerWin._dirty = True @@ -8655,12 +8655,12 @@ class UltimateListMainWindow(wx.PyScrolledWindow): count = self.GetItemCount() if width == ULC_AUTOSIZE_FILL: - + width = self.GetColumnWidth(col) if width == 0: width = WIDTH_COL_DEFAULT self._resizeColumn = col - + elif width == ULC_AUTOSIZE_USEHEADER: width = self.GetTextLength(column.GetText()) @@ -8669,7 +8669,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if column.GetKind() in [1, 2]: ix, iy = self._owner.GetCheckboxImageSize() width += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE - + # check for column header's image availability images = column.GetImage() for img in images: @@ -8700,7 +8700,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): itemWidth = self.GetItemWidthWithImage(item) if itemWidth > maxW and not item._overFlow: maxW = itemWidth - + self._aColWidths[col]._bNeedsUpdate = False self._aColWidths[col]._nMaxWidth = maxW @@ -8727,12 +8727,12 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if not self.IsColumnShown(col): continue - + self._headerWidth += self.GetColumnWidth(col) if self.HasAGWFlag(ULC_FOOTER): self._footerWidth = self._headerWidth - + return self._headerWidth @@ -8744,11 +8744,11 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ item = UltimateListItem() - column = self._columns[col] + column = self._columns[col] item = column.GetItem(item) return item - + def GetColumnWidth(self, col): """ @@ -8768,7 +8768,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): for column in self._columns: width += column.GetWidth() - return width + return width # ---------------------------------------------------------------------------- # item state @@ -8782,7 +8782,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ id = item._itemId - + if id < 0 or id >= self.GetItemCount(): raise Exception("invalid item index in SetItem") @@ -8811,14 +8811,14 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.InReportView(): rectItem = self.GetItemRect(id) self.RefreshRect(rectItem) - + def SetItemStateAll(self, state, stateMask): """ Sets the item state flags for all the items. :param `state`: any combination of the following bits: - + ============================ ========= ============================== State Bits Hex Value Description ============================ ========= ============================== @@ -8835,7 +8835,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): ============================ ========= ============================== :param `stateMask`: the bitmask for the state flag. - + :note: The valid state flags are influenced by the value of the state mask. """ @@ -8857,7 +8857,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): count = self.GetItemCount() for i in xrange(count): self.SetItemState(i, ULC_STATE_SELECTED, ULC_STATE_SELECTED) - + else: # clear for non virtual (somewhat optimized by using GetNextItem()) @@ -8884,9 +8884,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `litem`: the index of the item; if defaulted to -1, the state flag will be set for all the items; - :param `state`: the item state flag; + :param `state`: the item state flag; :param `stateMask`: the bitmask for the state flag. - + :see: :meth:`~UltimateListMainWindow.SetItemStateAll` for a list of valid state flags. """ @@ -8972,7 +8972,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `item`: the index of the item; :param `stateMask`: the bitmask for the state flag. - + :see: :meth:`~UltimateListMainWindow.SetItemStateAll` for a list of valid state flags. """ @@ -9005,7 +9005,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): line = self.GetLine(item._itemId) item = line.GetItem(col, item) - + # Get item state if user wants it if item._mask & ULC_MASK_STATE: item._state = self.GetItemState(item._itemId, ULC_STATE_SELECTED | ULC_STATE_FOCUSED) @@ -9022,32 +9022,32 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `checked`: ``True`` to check an item, ``False`` to uncheck it; :param `sendEvent`: ``True`` to send a {UltimateListEvent}, ``False`` otherwise. - :note: This method is meaningful only for checkbox-like and radiobutton-like items. + :note: This method is meaningful only for checkbox-like and radiobutton-like items. """ - # Should we raise an error here?!? + # Should we raise an error here?!? if item.GetKind() == 0 or not item.IsEnabled(): return if sendEvent: - + parent = self.GetParent() le = UltimateListEvent(wxEVT_COMMAND_LIST_ITEM_CHECKING, parent.GetId()) le.m_itemIndex = item._itemId le.m_item = item le.SetEventObject(parent) - + if parent.GetEventHandler().ProcessEvent(le): # Blocked by user - return - + return + item.Check(checked) self.SetItem(item) self.RefreshLine(item._itemId) if not sendEvent: return - + le = UltimateListEvent(wxEVT_COMMAND_LIST_ITEM_CHECKED, parent.GetId()) le.m_itemIndex = item._itemId le.m_item = item @@ -9063,13 +9063,13 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `column`: the column to which the items belongs to. :note: This method is meaningful only for checkbox-like and radiobutton-like items. - """ + """ for indx in xrange(self.GetItemCount()): item = CreateListItem(indx, column) newItem = self.GetItem(item, column) self.CheckItem(newItem, not isChecked, False) - + def AutoToggleChild(self, column): """ @@ -9078,7 +9078,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `column`: the column to which the items belongs to. :note: This method is meaningful only for checkbox-like and radiobutton-like items. - """ + """ for indx in xrange(self.GetItemCount()): item = CreateListItem(indx, column) @@ -9086,7 +9086,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if newItem.GetKind() != 1: continue - + self.CheckItem(newItem, not item.IsChecked(), False) @@ -9127,15 +9127,15 @@ class UltimateListMainWindow(wx.PyScrolledWindow): item.Enable(enable) wnd = item.GetWindow() - # Handles the eventual window associated to the item + # Handles the eventual window associated to the item if wnd: wnd.Enable(enable) - + self.SetItem(item) return True - - + + def GetItemKind(self, item): """ Returns the item kind. @@ -9147,7 +9147,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): item = self.GetItem(item, item._col) return item.GetKind() - + def SetItemKind(self, item, kind): """ @@ -9171,7 +9171,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.SetItem(item) return True - + def IsItemHyperText(self, item): """ @@ -9179,7 +9179,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `item`: an instance of :class:`UltimateListItem`. """ - + item = self.GetItem(item, item._col) return item.IsHyperText() @@ -9197,12 +9197,12 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.SetItem(item) return True - + def GetHyperTextFont(self): """Returns the font used to render an hypertext item.""" - return self._hypertextfont + return self._hypertextfont def SetHyperTextFont(self, font): @@ -9214,7 +9214,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._hypertextfont = font self._dirty = True - + def SetHyperTextNewColour(self, colour): """ @@ -9301,7 +9301,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if not self.InReportView() or not self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): raise Exception("Widgets are only allowed in report mode and with the ULC_HAS_VARIABLE_ROW_HEIGHT style.") - + item = self.GetItem(item, item._col) if wnd is not None: @@ -9317,7 +9317,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.SetItem(item) self.RecalculatePositions() self.Refresh() - + def DeleteItemWindow(self, item): """ @@ -9335,7 +9335,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.SetItem(item) self.RecalculatePositions() - + def GetItemWindowEnabled(self, item): """ @@ -9362,7 +9362,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.SetItem(item) self.Refresh() - + def SetColumnCustomRenderer(self, col=0, renderer=None): """ Associate a custom renderer to this column's header @@ -9371,7 +9371,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `renderer`: a class able to correctly render the input item. :note: the renderer class **must** implement the methods `DrawHeaderButton` - and `GetForegroundColor`. + and `GetForegroundColor`. """ self._columns[col].SetCustomRenderer(renderer) @@ -9391,7 +9391,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ Returns the custom renderer used to draw the input item (if any). - :param `item`: an instance of :class:`UltimateListItem`. + :param `item`: an instance of :class:`UltimateListItem`. """ item = self.GetItem(item, item._col) @@ -9406,7 +9406,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `renderer`: a class able to correctly render the item. :note: the renderer class **must** implement the methods `DrawSubItem`, - `GetLineHeight` and `GetSubItemWidth`. + `GetLineHeight` and `GetSubItemWidth`. """ item = self.GetItem(item, item._col) @@ -9436,9 +9436,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): An item/subitem may overwrite neighboring items/subitems if its text would not normally fit in the space allotted to it. - + :param `item`: an instance of :class:`UltimateListItem`; - :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. + :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. """ item = self.GetItem(item, item._col) @@ -9453,7 +9453,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def GetItemCount(self): """ Returns the number of items in the :class:`UltimateListCtrl`. """ - + return (self.IsVirtual() and [self._countVirt] or [len(self._lines)])[0] @@ -9464,9 +9464,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): the main program should be ready to handle calls to various item callbacks (such as :meth:`UltimateListCtrl.OnGetItemText() `) for all items in the range from 0 to `count`. - :param `count`: the total number of items in :class:`UltimateListCtrl`. + :param `count`: the total number of items in :class:`UltimateListCtrl`. """ - + self._selStore.SetItemCount(count) self._countVirt = count @@ -9511,14 +9511,14 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :note: This function only works in the icon and small icon views, not in list or report views. """ - + if self.HasAGWFlag(ULC_LIST): raise Exception("UltimateListCtrl.GetViewRect() not implemented for list view") # we need to find the longest/tallest label xMax = yMax = 0 count = self.GetItemCount() - + if count: for i in xrange(count): # we need logical, not physical, coordinates here, so use @@ -9554,9 +9554,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `subItem`: the column in which the item lives. If set equal to the special value ``ULC_GETSUBITEMRECT_WHOLEITEM`` the return value is the same as for :meth:`~UltimateListMainWindow.GetItemRect`. - + :note: This method is only meaningful when the :class:`UltimateListCtrl` is in the - report mode. + report mode. """ if not self.InReportView() and subItem == ULC_GETSUBITEMRECT_WHOLEITEM: @@ -9568,7 +9568,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # ensure that we're laid out, otherwise we could return nonsense if self._dirty: self.RecalculatePositions(True) - + rect = self.GetLineRect(item) # Adjust rect to specified column @@ -9584,7 +9584,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): rect.x, rect.y = self.CalcScrolledPosition(rect.x, rect.y) return rect - + def GetItemRect(self, item): """ Returns the rectangle representing the item's size and position, in physical @@ -9592,9 +9592,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `item`: the row in which the item lives. """ - + return self.GetSubItemRect(item, ULC_GETSUBITEMRECT_WHOLEITEM) - + def GetItemPosition(self, item): """ @@ -9602,7 +9602,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `item`: the row in which the item lives. """ - + rect = self.GetItemRect(item) return wx.Point(rect.x, rect.y) @@ -9649,7 +9649,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.InReportView(): self.ResetVisibleLinesRange() - + if not self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): # all lines have the same height and we scroll one line per step @@ -9682,7 +9682,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): decrement = 0 if entireHeight > self.GetClientSize()[1]: decrement = SCROLL_UNIT_X - + self.SetScrollbars(SCROLL_UNIT_X, SCROLL_UNIT_Y, (self.GetHeaderWidth()-decrement)/SCROLL_UNIT_X, (entireHeight + SCROLL_UNIT_Y - 1)/SCROLL_UNIT_Y, @@ -9702,7 +9702,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # to arrange them in top to bottom, left to right (don't ask me why # not the other way round...) order if self.HasAGWFlag(ULC_ALIGN_LEFT | ULC_ALIGN_TOP): - + x = EXTRA_BORDER_X y = EXTRA_BORDER_Y widthMax = 0 @@ -9853,9 +9853,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): ``ULC_NEXT_LEFT`` 0x3 Searches for an item to the left of the specified item ``ULC_NEXT_RIGHT`` 0x4 Searches for an item to the right of the specified item =================== ========= ================================= - + :param `state`: any combination of the following bits: - + ============================ ========= ============================== State Bits Hex Value Description ============================ ========= ============================== @@ -9876,20 +9876,20 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :note: This function may be used to find all selected items in the control like this:: - + item = -1 - + while 1: item = listctrl.GetNextItem(item, ULC_NEXT_ALL, ULC_STATE_SELECTED) - + if item == -1: break - + # This item is selected - do whatever is needed with it wx.LogMessage("Item %ld is selected."%item) - + """ ret = item @@ -9899,7 +9899,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # and this is intentional to allow writing a simple loop to iterate over # all selected items ret += 1 - + if ret == maxI: # this is not an error because the index was ok initially, just no # such item @@ -9928,7 +9928,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): Deletes the specified item. :param `lindex`: the index of the item to delete. - + :note: This function sends the ``EVT_LIST_DELETE_ITEM`` event for the item being deleted. """ @@ -9952,7 +9952,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # we're deleting contain the Max Column Width line = self.GetLine(lindex) item = UltimateListItem() - + for i in xrange(len(self._columns)): itemData = line._items[i] item = itemData.GetItem(item) @@ -9968,7 +9968,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._current = -1 self.SendNotify(lindex, wxEVT_COMMAND_LIST_DELETE_ITEM) - + if self.IsVirtual(): self._countVirt -= 1 self._selStore.OnItemDelete(lindex) @@ -9977,7 +9977,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._lines.pop(lindex) # we need to refresh the (vert) scrollbar as the number of items changed - self._dirty = True + self._dirty = True self._lineHeight = 0 self.ResetLineDimensions(True) self.RecalculatePositions() @@ -9988,7 +9988,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ Deletes the specified column. - :param `col`: the index of the column to delete. + :param `col`: the index of the column to delete. """ self._columns.pop(col) @@ -10002,14 +10002,14 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.InReportView(): # we only cache max widths when in Report View self._aColWidths.pop(col) - + # invalidate it as it has to be recalculated self._headerWidth = 0 def DoDeleteAllItems(self): """ Actually performs the deletion of all the items. """ - + if self.IsEmpty(): # nothing to do - in particular, don't send the event return @@ -10050,20 +10050,20 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :note: This function does not send the ``EVT_LIST_DELETE_ITEM`` event because deleting many items from the control would be too slow then (unlike :meth:`~UltimateListMainWindow.DeleteItem`). """ - + self.DoDeleteAllItems() self.RecalculatePositions() def DeleteEverything(self): """ Deletes all items in the :class:`UltimateListCtrl`, resetting column widths to zero. """ - + self.DeleteAllItems() count = len(self._columns) for n in xrange(count): self.DeleteColumn(0) - + self.RecalculatePositions() self.GetListCtrl().Refresh() @@ -10100,9 +10100,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `partial`: if ``True`` then this method will look for items which begin with `string`. - :note: The string comparison is case insensitive. + :note: The string comparison is case insensitive. """ - + if start < 0: start = 0 @@ -10131,17 +10131,17 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if `start` is -1; :param `data`: the data to look for matches. """ - + if start < 0: start = 0 count = self.GetItemCount() - + for i in xrange(start, count): line = self.GetLine(i) item = UltimateListItem() item = line.GetItem(0, item) - + if item._data == data: return i @@ -10152,17 +10152,17 @@ class UltimateListMainWindow(wx.PyScrolledWindow): """ Find an item nearest this position. - :param `pt`: an instance of :class:`Point`. + :param `pt`: an instance of :class:`Point`. """ - + topItem, dummy = self.GetVisibleLinesRange() p = self.GetItemPosition(self.GetItemCount()-1) - + if p.y == 0: return topItem id = int(math.floor(pt.y*float(self.GetItemCount()-topItem-1)/p.y+topItem)) - + if id >= 0 and id < self.GetItemCount(): return id @@ -10176,9 +10176,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `x`: the mouse `x` position; :param `y`: the mouse `y` position. - :see: :meth:`~UltimateListMainWindow.HitTestLine` for a list of return flags. + :see: :meth:`~UltimateListMainWindow.HitTestLine` for a list of return flags. """ - + x, y = self.CalcUnscrolledPosition(x, y) count = self.GetItemCount() @@ -10194,7 +10194,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): newItem, flags = self.HitTestLine(current, x, y) if flags: return current, flags - + else: # TODO: optimize it too! this is less simple than for report view but # enumerating all items is still not a way to do it!! @@ -10216,7 +10216,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `item`: an instance of :class:`UltimateListItem`. """ - + if self.IsVirtual(): raise Exception("can't be used with virtual control") @@ -10225,7 +10225,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): raise Exception("invalid item index") CheckVariableRowHeight(self, item._text) - + if item._itemId > count: item._itemId = count @@ -10239,7 +10239,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): pWidthInfo = self._aColWidths[item.GetColumn()] width = self.GetItemWidthWithImage(item) item.SetWidth(width) - + if width > pWidthInfo._nMaxWidth: pWidthInfo._nMaxWidth = width @@ -10267,7 +10267,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `item`: an instance of :class:`UltimateListItem`. :return: the index at which the column has been inserted. - + :note: This method is meaningful only if :class:`UltimateListCtrl` has the ``ULC_REPORT`` or the ``ULC_TILE`` styles set. """ @@ -10283,7 +10283,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): colWidthInfo = ColWidthInfo() insert = (col >= 0) and (col < len(self._columns)) - + if insert: self._columns.insert(col, column) self._aColWidths.insert(col, colWidthInfo) @@ -10328,7 +10328,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): font = item.GetFont() else: font = self.GetFont() - + dc.SetFont(font) if item.GetKind() in [1, 2]: @@ -10363,7 +10363,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): font = item.GetFont() else: font = self.GetFont() - + dc.SetFont(font) if item.GetKind() in [1, 2]: @@ -10388,7 +10388,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def OnCompareItems(self, line1, line2): """ Returns whether 2 lines have the same index. - + Override this function in the derived class to change the sort order of the items in the :class:`UltimateListCtrl`. The function should return a negative, zero or positive value if the first line is less than, equal to or greater than the second one. @@ -10403,7 +10403,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): item1 = line1.GetItem(0, item) item = UltimateListItem() item2 = line2.GetItem(0, item) - + data1 = item1._data data2 = item2._data @@ -10422,7 +10422,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def OnCompareItems(self, line1, line2): DoSomething(line1, line2) - # function code + # function code It is called each time when the two items must be compared and should return 0 @@ -10445,7 +10445,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.__func = func self._lines.sort(self.OnCompareItems) - + if self.IsShownOnScreen(): self._dirty = True self._lineHeight = 0 @@ -10470,7 +10470,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): # update our idea of which lines are shown when we redraw the window the # next time self.ResetVisibleLinesRange() - + if self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): wx.CallAfter(self.RecalculatePositions, True) @@ -10480,19 +10480,19 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self.HasHeader(): lc._headerWin.Refresh() lc._headerWin.Update() - + if self.HasFooter(): lc._footerWin.Refresh() lc._footerWin.Update() - - + + def GetCountPerPage(self): """ Returns the number of items that can fit vertically in the visible area of the :class:`UltimateListCtrl` (list or report view) or the total number of items in the list control (icon or small icon view). """ - + if not self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): if not self._linesPerPage: self._linesPerPage = self.GetClientSize().y/self.GetLineHeight() @@ -10501,7 +10501,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): visibleFrom, visibleTo = self.GetVisibleLinesRange() self._linesPerPage = visibleTo - visibleFrom + 1 - + return self._linesPerPage @@ -10517,9 +10517,9 @@ class UltimateListMainWindow(wx.PyScrolledWindow): raise Exception("this is for report mode only") if self._lineFrom == -1: - + count = self.GetItemCount() - + if count: if self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): @@ -10535,10 +10535,10 @@ class UltimateListMainWindow(wx.PyScrolledWindow): if self._lineFrom < 0: self._lineFrom = 0 - - self._lineTo = self._lineFrom + + self._lineTo = self._lineFrom clientWidth, clientHeight = self.GetClientSize() - + for i in xrange(self._lineFrom, count): rc = self.GetLineY(i) + self.GetLineHeight(i) if rc > view_y + clientHeight - 5: @@ -10546,7 +10546,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._lineTo += 1 else: - + # No variable row height self._lineFrom = self.GetScrollPos(wx.VERTICAL) @@ -10586,14 +10586,14 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `colour`: if not ``None``, a valid :class:`Colour` instance. Otherwise, the colour is taken from the system value ``wx.SYS_COLOUR_HIGHLIGHT``. """ - + if colour is None: colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) self._firstcolour = colour if self._usegradients: self.RefreshSelected() - + def SetSecondGradientColour(self, colour=None): """ @@ -10620,13 +10620,13 @@ class UltimateListMainWindow(wx.PyScrolledWindow): def GetFirstGradientColour(self): """ Returns the first gradient colour for gradient-style selections. """ - + return self._firstcolour def GetSecondGradientColour(self): """ Returns the second gradient colour for gradient-style selections. """ - + return self._secondcolour @@ -10644,7 +10644,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._usegradients = enable self._vistaselection = False self.RefreshSelected() - + def SetGradientStyle(self, vertical=0): """ @@ -10701,7 +10701,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self._backgroundImage = image self.Refresh() - + def GetBackgroundImage(self): """ @@ -10709,7 +10709,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :note: At present, the background image can only be used in "tile" mode. - .. todo:: Support background images also in stretch and centered modes. + .. todo:: Support background images also in stretch and centered modes. """ return self._backgroundImage @@ -10722,23 +10722,23 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `watermark`: if not ``None``, an instance of :class:`Bitmap`. - .. todo:: Better support for this is needed. - """ + .. todo:: Better support for this is needed. + """ self._waterMark = watermark self.Refresh() - + def GetWaterMark(self): """ Returns the :class:`UltimateListCtrl` watermark image (if any), displayed in the bottom right part of the window. - .. todo:: Better support for this is needed. + .. todo:: Better support for this is needed. """ return self._waterMark - + def SetDisabledTextColour(self, colour): """ @@ -10746,8 +10746,8 @@ class UltimateListMainWindow(wx.PyScrolledWindow): :param `colour`: an instance of :class:`Colour`. """ - - # Disabled items colour + + # Disabled items colour self._disabledColour = colour self.Refresh() @@ -10790,7 +10790,7 @@ class UltimateListMainWindow(wx.PyScrolledWindow): self.ResetVisibleLinesRange() return True - + # ------------------------------------------------------------------------------------- # UltimateListCtrl # ------------------------------------------------------------------------------------- @@ -10806,7 +10806,7 @@ class UltimateListCtrl(wx.PyControl): style=0, agwStyle=0, validator=wx.DefaultValidator, name="UltimateListCtrl"): """ Default class constructor. - + :param `parent`: parent window. Must not be ``None``; :param `id`: window identifier. A value of -1 indicates a default value; :param `pos`: the control position. A value of (-1, -1) indicates a default position, @@ -10855,7 +10855,7 @@ class UltimateListCtrl(wx.PyControl): ``ULC_USER_ROW_HEIGHT`` 0x100000000 Allows to set a custom row height (one value for all the items, only in report mode). =============================== =========== ==================================================================================================== - :param `validator`: the window validator; + :param `validator`: the window validator; :param `name`: the window name. """ @@ -10877,13 +10877,13 @@ class UltimateListCtrl(wx.PyControl): if agwStyle & ULC_USER_ROW_HEIGHT and (agwStyle & ULC_REPORT) == 0: raise Exception("Style ULC_USER_ROW_HEIGHT can be used only with ULC_REPORT") - + wx.PyControl.__init__(self, parent, id, pos, size, style|wx.CLIP_CHILDREN, validator, name) self._mainWin = None self._headerWin = None self._footerWin = None - + self._headerHeight = wx.RendererNative.Get().GetHeaderButtonHeight(self) self._footerHeight = self._headerHeight @@ -10897,7 +10897,7 @@ class UltimateListCtrl(wx.PyControl): self._agwStyle = agwStyle if style & wx.SUNKEN_BORDER: style -= wx.SUNKEN_BORDER - + self._mainWin = UltimateListMainWindow(self, wx.ID_ANY, wx.Point(0, 0), wx.DefaultSize, style, agwStyle) sizer = wx.BoxSizer(wx.VERTICAL) @@ -10906,20 +10906,20 @@ class UltimateListCtrl(wx.PyControl): self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) - + self.CreateOrDestroyHeaderWindowAsNeeded() self.CreateOrDestroyFooterWindowAsNeeded() self.SetInitialSize(size) wx.CallAfter(self.Layout) - + def CreateOrDestroyHeaderWindowAsNeeded(self): """ Creates or destroys the header window depending on the window style flags. """ needs_header = self.HasHeader() has_header = self._headerWin is not None - + if needs_header == has_header: return @@ -10950,14 +10950,14 @@ class UltimateListCtrl(wx.PyControl): self.GetSizer().Detach(self._headerWin) self._headerWin.Destroy() self._headerWin = None - + def CreateOrDestroyFooterWindowAsNeeded(self): """ Creates or destroys the footer window depending on the window style flags. """ needs_footer = self.HasFooter() has_footer = self._footerWin is not None - + if needs_footer == has_footer: return @@ -10994,7 +10994,7 @@ class UltimateListCtrl(wx.PyControl): """ Returns ``True`` if :class:`UltimateListCtrl` has a header window. """ return self._mainWin.HasHeader() - + def HasFooter(self): """ Returns ``True`` if :class:`UltimateListCtrl` has a footer window. """ @@ -11050,7 +11050,7 @@ class UltimateListCtrl(wx.PyControl): ``ULC_NO_FULL_ROW_SELECT`` 0x40000000 When an item is selected, the only the item in the first column is highlighted. ``ULC_FOOTER`` 0x80000000 Show a footer too (only when header is present). =============================== =========== ==================================================================================================== - + :param `add`: ``True`` to add the window style, ``False`` to remove it. :note: The style ``ULC_VIRTUAL`` can not be set/unset after construction. @@ -11058,7 +11058,7 @@ class UltimateListCtrl(wx.PyControl): if style & ULC_VIRTUAL: raise Exception("ULC_VIRTUAL can't be [un]set") - + flag = self.GetAGWWindowStyleFlag() if add: @@ -11087,13 +11087,13 @@ class UltimateListCtrl(wx.PyControl): def GetAGWWindowStyleFlag(self): """ Returns the :class:`UltimateListCtrl` AGW-specific style flag. - + :see: :meth:`~UltimateListCtrl.SetAGWWindowStyleFlag` for a list of possible style flags. """ - + return self._agwStyle - - + + def SetAGWWindowStyleFlag(self, style): """ Sets the :class:`UltimateListCtrl` AGW-specific style flag. @@ -11138,11 +11138,11 @@ class UltimateListCtrl(wx.PyControl): ``ULC_FOOTER`` 0x80000000 Show a footer too (only when header is present). ``ULC_USER_ROW_HEIGHT`` 0x100000000 Allows to set a custom row height (one value for all the items, only in report mode). =============================== =========== ==================================================================================================== - """ + """ if style & ULC_HAS_VARIABLE_ROW_HEIGHT and not self.HasAGWFlag(ULC_REPORT): raise Exception("ULC_HAS_VARIABLE_ROW_HEIGHT style can be used only in report mode") - + wasInReportView = self.HasAGWFlag(ULC_REPORT) self._agwStyle = style @@ -11158,7 +11158,7 @@ class UltimateListCtrl(wx.PyControl): self.CreateOrDestroyHeaderWindowAsNeeded() self.CreateOrDestroyFooterWindowAsNeeded() self.GetSizer().Layout() - + if style & ULC_HAS_VARIABLE_ROW_HEIGHT: self._mainWin.ResetLineDimensions() self._mainWin.ResetVisibleLinesRange() @@ -11172,11 +11172,11 @@ class UltimateListCtrl(wx.PyControl): :param `flag`: the window style to check. - :see: :meth:`~UltimateListCtrl.SetAGWWindowStyleFlag` for a list of valid window styles. + :see: :meth:`~UltimateListCtrl.SetAGWWindowStyleFlag` for a list of valid window styles. """ - + return self._agwStyle & flag - + def SetUserLineHeight(self, height): """ @@ -11189,7 +11189,7 @@ class UltimateListCtrl(wx.PyControl): if self._mainWin: self._mainWin.SetUserLineHeight(height) - + def GetUserLineHeight(self): """ @@ -11240,10 +11240,10 @@ class UltimateListCtrl(wx.PyControl): Sets the column width. :param `width`: can be a width in pixels or ``wx.LIST_AUTOSIZE`` (-1) or - ``wx.LIST_AUTOSIZE_USEHEADER`` (-2) or ``LIST_AUTOSIZE_FILL`` (-3). + ``wx.LIST_AUTOSIZE_USEHEADER`` (-2) or ``LIST_AUTOSIZE_FILL`` (-3). ``wx.LIST_AUTOSIZE`` will resize the column to the length of its longest item. ``wx.LIST_AUTOSIZE_USEHEADER`` will resize the column to the - length of the header (Win32) or 80 pixels (other platforms). + length of the header (Win32) or 80 pixels (other platforms). ``LIST_AUTOSIZE_FILL`` will resize the column fill the remaining width of the window. @@ -11307,9 +11307,9 @@ class UltimateListCtrl(wx.PyControl): 1 A checkbox-like item 2 A radiobutton-type item =============== ========================== - + """ - + info = UltimateListItem() info._text = label info._mask = ULC_MASK_TEXT @@ -11317,8 +11317,8 @@ class UltimateListCtrl(wx.PyControl): if it_kind: info._mask |= ULC_MASK_KIND info._kind = it_kind - - info._itemId = index + + info._itemId = index info._col = col for ids in to_list(imageIds): @@ -11338,7 +11338,7 @@ class UltimateListCtrl(wx.PyControl): :param `item`: the index of the item; :param `stateMask`: the bitmask for the state flag. - + :see: :meth:`~UltimateListCtrl.SetItemState` for a list of valid state flags. """ @@ -11352,7 +11352,7 @@ class UltimateListCtrl(wx.PyControl): :param `item`: the index of the item; if defaulted to -1, the state flag will be set for all the items; :param `state`: any combination of the following bits: - + ============================ ========= ============================== State Bits Hex Value Description ============================ ========= ============================== @@ -11369,7 +11369,7 @@ class UltimateListCtrl(wx.PyControl): ============================ ========= ============================== :param `stateMask`: the bitmask for the state flag. - + """ self._mainWin.SetItemState(item, state, stateMask) @@ -11386,7 +11386,7 @@ class UltimateListCtrl(wx.PyControl): for the first column; :param `selImage`: not used at present. """ - + return self.SetItemColumnImage(item, 0, image) @@ -11398,7 +11398,7 @@ class UltimateListCtrl(wx.PyControl): :param `item`: an integer specifying the item index; :param `column`: the column to which the item belongs to; :param `image`: a Python list of indexes into the image list associated - with the :class:`UltimateListCtrl`. + with the :class:`UltimateListCtrl`. """ info = UltimateListItem() @@ -11407,7 +11407,7 @@ class UltimateListCtrl(wx.PyControl): info._itemId = item info._col = column self._mainWin.SetItem(info) - + return True @@ -11472,7 +11472,7 @@ class UltimateListCtrl(wx.PyControl): Returns the data for the item, which can be any Python object. :param `item`: an integer specifying the item index. - + :note: Please note that Python data is associated with the item and not with subitems. """ @@ -11490,7 +11490,7 @@ class UltimateListCtrl(wx.PyControl): :param `item`: an integer specifying the item index; :param `pyData`: any Python object. - + :note: Please note that Python data is associated with the item and not with subitems. """ @@ -11501,7 +11501,7 @@ class UltimateListCtrl(wx.PyControl): info._pyData = pyData self._mainWin.SetItem(info) return True - + SetPyData = SetItemPyData GetPyData = GetItemPyData @@ -11542,9 +11542,9 @@ class UltimateListCtrl(wx.PyControl): value ``ULC_GETSUBITEMRECT_WHOLEITEM`` the return value is the same as for :meth:`~UltimateListCtrl.GetItemRect`; :param `code`: one of ``ULC_RECT_BOUNDS``, ``ULC_RECT_ICON``, ``ULC_RECT_LABEL``. - + :note: This method is only meaningful when the :class:`UltimateListCtrl` is in the - report mode. + report mode. """ rect = self._mainWin.GetSubItemRect(item, subItem) @@ -11571,7 +11571,7 @@ class UltimateListCtrl(wx.PyControl): :param `item`: the row in which the item lives; :param `pos`: the item position. - :note: This method is currently unimplemented and does nothing. + :note: This method is currently unimplemented and does nothing. """ return False @@ -11619,9 +11619,10 @@ class UltimateListCtrl(wx.PyControl): :param `item`: the index of the item; :param `col`: a valid :class:`Colour` object. """ - + info = UltimateListItem() info._itemId = item + info = self._mainWin.GetItem(info) info.SetTextColour(col) self._mainWin.SetItem(info) @@ -11636,7 +11637,7 @@ class UltimateListCtrl(wx.PyControl): info = UltimateListItem() info._itemId = item info = self._mainWin.GetItem(info) - + return info.GetTextColour() @@ -11650,6 +11651,7 @@ class UltimateListCtrl(wx.PyControl): info = UltimateListItem() info._itemId = item + info = self._mainWin.GetItem(info) info.SetBackgroundColour(col) self._mainWin.SetItem(info) @@ -11677,6 +11679,7 @@ class UltimateListCtrl(wx.PyControl): info = UltimateListItem() info._itemId = item + info = self._mainWin.GetItem(info) info.SetFont(f) info.SetBackgroundColour(self.GetItemBackgroundColour(item)) self._mainWin.SetItem(info) @@ -11742,9 +11745,9 @@ class UltimateListCtrl(wx.PyControl): ``ULC_NEXT_LEFT`` 0x3 Searches for an item to the left of the specified item ``ULC_NEXT_RIGHT`` 0x4 Searches for an item to the right of the specified item =================== ========= ================================= - + :param `state`: any combination of the following bits: - + ============================ ========= ============================== State Bits Hex Value Description ============================ ========= ============================== @@ -11765,15 +11768,15 @@ class UltimateListCtrl(wx.PyControl): :note: This function may be used to find all selected items in the control like this:: - + item = -1 - + while 1: item = listctrl.GetNextItem(item, ULC_NEXT_ALL, ULC_STATE_SELECTED) - + if item == -1: break - + # This item is selected - do whatever is needed with it wx.LogMessage("Item %ld is selected."%item) @@ -11830,7 +11833,7 @@ class UltimateListCtrl(wx.PyControl): imageList = PyImageList(16, 16) imageList.Add(someBitmap) self.SetImageList(imageList, wx.IMAGE_LIST_SMALL) - + """ if which == wx.IMAGE_LIST_NORMAL: @@ -11865,7 +11868,7 @@ class UltimateListCtrl(wx.PyControl): imageList = PyImageList(16, 16) imageList.Add(someBitmap) self.SetImageList(imageList, wx.IMAGE_LIST_SMALL) - + """ self.SetImageList(imageList, which) @@ -11896,7 +11899,7 @@ class UltimateListCtrl(wx.PyControl): Deletes the specified item. :param `item`: the index of the item to delete. - + :note: This function sends the ``EVT_LIST_DELETE_ITEM`` event for the item being deleted. """ @@ -11937,7 +11940,7 @@ class UltimateListCtrl(wx.PyControl): """ Deletes the specified column. - :param `col`: the index of the column to delete. + :param `col`: the index of the column to delete. """ self._mainWin.DeleteColumn(col) @@ -11975,7 +11978,7 @@ class UltimateListCtrl(wx.PyControl): :param `partial`: if ``True`` then this method will look for items which begin with `string`. - :note: The string comparison is case insensitive. + :note: The string comparison is case insensitive. """ return self._mainWin.FindItem(start, str, partial) @@ -11997,7 +12000,7 @@ class UltimateListCtrl(wx.PyControl): """ Find an item nearest this position. - :param `pt`: an instance of :class:`Point`. + :param `pt`: an instance of :class:`Point`. """ return self._mainWin.FindItemAtPos(pt) @@ -12010,7 +12013,7 @@ class UltimateListCtrl(wx.PyControl): :param `pointOrTuple`: an instance of :class:`Point` or a tuple representing the mouse `x`, `y` position. - :see: :meth:`UltimateListMainWindow.HitTestLine() ` for a list of return flags. + :see: :meth:`UltimateListMainWindow.HitTestLine() ` for a list of return flags. """ if isinstance(pointOrTuple, wx.Point): @@ -12073,10 +12076,10 @@ class UltimateListCtrl(wx.PyControl): if it_kind: info._mask |= ULC_MASK_KIND info._kind = it_kind - + info._image = to_list(imageIds) info._itemId = index - + return self.InsertItem(info) @@ -12101,7 +12104,7 @@ class UltimateListCtrl(wx.PyControl): if it_kind: info._mask |= ULC_MASK_KIND info._kind = it_kind - + info._itemId = index return self.InsertItem(info) @@ -12146,20 +12149,20 @@ class UltimateListCtrl(wx.PyControl): ============================ ========= ============================== :param `width`: can be a width in pixels or ``wx.LIST_AUTOSIZE`` (-1) or - ``wx.LIST_AUTOSIZE_USEHEADER`` (-2) or ``LIST_AUTOSIZE_FILL`` (-3). + ``wx.LIST_AUTOSIZE_USEHEADER`` (-2) or ``LIST_AUTOSIZE_FILL`` (-3). ``wx.LIST_AUTOSIZE`` will resize the column to the length of its longest item. ``wx.LIST_AUTOSIZE_USEHEADER`` will resize the column to the - length of the header (Win32) or 80 pixels (other platforms). + length of the header (Win32) or 80 pixels (other platforms). ``LIST_AUTOSIZE_FILL`` will resize the column fill the remaining width of the window. :return: the index at which the column has been inserted. """ - + item = UltimateListItem() item._mask = ULC_MASK_TEXT | ULC_MASK_FORMAT | ULC_MASK_FONT item._text = heading - + if width >= -2: item._mask |= ULC_MASK_WIDTH item._width = width @@ -12196,7 +12199,7 @@ class UltimateListCtrl(wx.PyControl): self._mainWin.SetColumn(column, col) self.Update() - + def ScrollList(self, dx, dy): """ Scrolls the :class:`UltimateListCtrl`. @@ -12224,7 +12227,7 @@ class UltimateListCtrl(wx.PyControl): def OnCompareItems(self, line1, line2): DoSomething(line1, line2) - # function code + # function code It is called each time when the two items must be compared and should return 0 @@ -12237,10 +12240,10 @@ class UltimateListCtrl(wx.PyControl): self._mainWin.SortItems(func) wx.CallAfter(self.Refresh) - + return True - - + + # ---------------------------------------------------------------------------- # event handlers # ---------------------------------------------------------------------------- @@ -12251,13 +12254,13 @@ class UltimateListCtrl(wx.PyControl): :param `event`: a :class:`SizeEvent` event to be processed. """ - + if not self.IsShownOnScreen(): - # We don't have the proper column sizes until we are visible so + # We don't have the proper column sizes until we are visible so # use CallAfter to resize the columns on the first display if self._mainWin: wx.CallAfter(self._mainWin.ResizeColumns) - + if not self._mainWin: return @@ -12269,7 +12272,7 @@ class UltimateListCtrl(wx.PyControl): # calling SetScrollbar() further down. self.DoLayout() - + def OnSetFocus(self, event): """ @@ -12321,7 +12324,7 @@ class UltimateListCtrl(wx.PyControl): you may wish to call :meth:`Window.ClearBackground` or :meth:`Window.Refresh` after calling this function. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ if self._mainWin: @@ -12338,7 +12341,7 @@ class UltimateListCtrl(wx.PyControl): :param `colour`: the colour to be used as the foreground colour, pass :class:`NullColour` to reset to the default colour. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ if not wx.PyControl.SetForegroundColour(self, colour): @@ -12360,7 +12363,7 @@ class UltimateListCtrl(wx.PyControl): :param `font`: a valid :class:`Font` instance. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ if not wx.PyControl.SetFont(self, font): @@ -12397,7 +12400,7 @@ class UltimateListCtrl(wx.PyControl): colour, if the field doesn't make sense as is the case for `colBg` for the controls with themed background. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ attr = wx.VisualAttributes() @@ -12424,7 +12427,7 @@ class UltimateListCtrl(wx.PyControl): :param `dropTarget`: an instance of :class:`DropTarget`. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ self._mainWin.SetDropTarget(dropTarget) @@ -12442,7 +12445,7 @@ class UltimateListCtrl(wx.PyControl): def SetCursor(self, cursor): """ - Sets the window's cursor. + Sets the window's cursor. :param `cursor`: specifies the cursor that the window should normally display. The `cursor` may be :class:`NullCursor` in which case the window cursor will be @@ -12462,7 +12465,7 @@ class UltimateListCtrl(wx.PyControl): :note: Overridden from :class:`PyControl`. """ - + return (self._mainWin and [self._mainWin.GetBackgroundColour()] or [wx.NullColour])[0] @@ -12501,7 +12504,7 @@ class UltimateListCtrl(wx.PyControl): `x`, `y` coordinates for this point. :return: the coordinates relative to the screen. - + :note: Overridden from :class:`PyControl`. """ @@ -12512,11 +12515,11 @@ class UltimateListCtrl(wx.PyControl): """ Converts to screen coordinates from coordinates relative to this window. - :param `x`: an integer specifying the `x` client coordinate; + :param `x`: an integer specifying the `x` client coordinate; :param `y`: an integer specifying the `y` client coordinate. :return: the coordinates relative to the screen. - + :note: Overridden from :class:`PyControl`. """ @@ -12531,7 +12534,7 @@ class UltimateListCtrl(wx.PyControl): `x`, `y` coordinates for this point. :return: the coordinates relative to this window. - + :note: Overridden from :class:`PyControl`. """ @@ -12542,11 +12545,11 @@ class UltimateListCtrl(wx.PyControl): """ Converts from screen to client window coordinates. - :param `x`: an integer specifying the `x` screen coordinate; + :param `x`: an integer specifying the `x` screen coordinate; :param `y`: an integer specifying the `y` screen coordinate. :return: the coordinates relative to this window. - + :note: Overridden from :class:`PyControl`. """ @@ -12592,8 +12595,8 @@ class UltimateListCtrl(wx.PyControl): # this is a pure virtual function, in fact - which is not really pure # because the controls which are not virtual don't need to implement it raise Exception("UltimateListCtrl.OnGetItemText not supposed to be called") - - + + def OnGetItemTextColour(self, item, col): """ This function **must** be overloaded in the derived class for a control with @@ -12622,7 +12625,7 @@ class UltimateListCtrl(wx.PyControl): # this is a pure virtual function, in fact - which is not really pure # because the controls which are not virtual don't need to implement it raise Exception("UltimateListCtrl.OnGetItemToolTip not supposed to be called") - + def OnGetItemImage(self, item): """ @@ -12708,7 +12711,7 @@ class UltimateListCtrl(wx.PyControl): ``ULC_VIRTUAL`` and ``ULC_REPORT`` style. It should return whether a checkbox-like item or a radiobutton-like item in the column header is checked or unchecked. - + :param `item`: an integer specifying the item index. :note: The base class version always returns an empty Python list. @@ -12717,7 +12720,7 @@ class UltimateListCtrl(wx.PyControl): if column == 0: return self.OnGetItemCheck(item) - return [] + return [] def OnGetItemKind(self, item): @@ -12753,7 +12756,7 @@ class UltimateListCtrl(wx.PyControl): return self.OnGetItemKind(item) return 0 - + def SetItemCount(self, count): """ @@ -12792,7 +12795,7 @@ class UltimateListCtrl(wx.PyControl): :param `itemFrom`: the first index of the refresh range; :param `itemTo`: the last index of the refresh range. """ - + self._mainWin.RefreshLines(itemFrom, itemTo) @@ -12807,7 +12810,7 @@ class UltimateListCtrl(wx.PyControl): def Refresh(self, eraseBackground=True, rect=None): """ Causes this window, and all of its children recursively (except under wxGTK1 - where this is not implemented), to be repainted. + where this is not implemented), to be repainted. :param `eraseBackground`: If ``True``, the background will be erased; :param `rect`: If not ``None``, only the given rectangle will be treated as damaged. @@ -12816,7 +12819,7 @@ class UltimateListCtrl(wx.PyControl): event loop iteration, if you need to update the window immediately you should use :meth:`~UltimateListCtrl.Update` instead. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ if not rect: @@ -12861,9 +12864,9 @@ class UltimateListCtrl(wx.PyControl): happens if nothing has been invalidated (i.e. marked as requiring a redraw). Use :meth:`~UltimateListCtrl.Refresh` first if you want to immediately redraw the window unconditionally. - :note: Overridden from :class:`PyControl`. + :note: Overridden from :class:`PyControl`. """ - + self._mainWin.ResetVisibleLinesRange(True) wx.PyControl.Update(self) @@ -12901,7 +12904,7 @@ class UltimateListCtrl(wx.PyControl): else: state = 0 - + self.SetItemState(idx, state, ULC_STATE_SELECTED) @@ -12918,13 +12921,13 @@ class UltimateListCtrl(wx.PyControl): def GetFocusedItem(self): """ Returns the currently focused item or -1 if none is focused. """ - + return self.GetNextItem(-1, ULC_NEXT_ALL, ULC_STATE_FOCUSED) def GetFirstSelected(self): """ Return first selected item, or -1 when none is selected. """ - + return self.GetNextSelected(-1) @@ -12944,7 +12947,7 @@ class UltimateListCtrl(wx.PyControl): :param `idx`: the index of the item to check for selection. """ - + return (self.GetItemState(idx, ULC_STATE_SELECTED) & ULC_STATE_SELECTED) != 0 @@ -12968,7 +12971,7 @@ class UltimateListCtrl(wx.PyControl): :param `col`: the column index to which the input item belongs to. """ - item = CreateListItem(itemOrId, col) + item = CreateListItem(itemOrId, col) return self._mainWin.IsItemEnabled(item) @@ -12981,7 +12984,7 @@ class UltimateListCtrl(wx.PyControl): :see: :meth:`~UltimateListCtrl.SetItemKind` for a list of valid item kinds. """ - + item = CreateListItem(itemOrId, col) return self._mainWin.GetItemKind(item) @@ -13006,7 +13009,7 @@ class UltimateListCtrl(wx.PyControl): item = CreateListItem(itemOrId, col) return self._mainWin.SetItemKind(item, kind) - + def EnableItem(self, itemOrId, col=0, enable=True): """ @@ -13019,7 +13022,7 @@ class UltimateListCtrl(wx.PyControl): item = CreateListItem(itemOrId, col) return self._mainWin.EnableItem(item, enable) - + def IsItemHyperText(self, itemOrId, col=0): """ @@ -13028,7 +13031,7 @@ class UltimateListCtrl(wx.PyControl): :param `itemOrId`: an instance of :class:`UltimateListItem` or the item index; :param `col`: the column index to which the input item belongs to. """ - + item = CreateListItem(itemOrId, col) return self._mainWin.IsItemHyperText(item) @@ -13041,7 +13044,7 @@ class UltimateListCtrl(wx.PyControl): :param `col`: the column index to which the input item belongs to; :param `hyper`: ``True`` to have an item with hypertext behaviour, ``False`` otherwise. """ - + item = CreateListItem(itemOrId, col) return self._mainWin.SetItemHyperText(item, hyper) @@ -13052,11 +13055,11 @@ class UltimateListCtrl(wx.PyControl): :param `col`: the column index; :param `tip`: the tooltip text """ - + item = self.GetColumn(col) item.SetToolTip(tip) self.SetColumn(col, item) - + def SetColumnImage(self, col, image): """ @@ -13066,7 +13069,7 @@ class UltimateListCtrl(wx.PyControl): :param `image`: a Python list containing the image indexes for the images associated to this column item. """ - + item = self.GetColumn(col) # preserve all other attributes too @@ -13081,7 +13084,7 @@ class UltimateListCtrl(wx.PyControl): ULC_MASK_FONT | ULC_MASK_BACKCOLOUR | ULC_MASK_KIND | - ULC_MASK_CHECK + ULC_MASK_CHECK ) item.SetImage(image) self.SetColumn(col, item) @@ -13093,7 +13096,7 @@ class UltimateListCtrl(wx.PyControl): :param `col`: the column index; """ - + self.SetColumnImage(col, -1) @@ -13103,7 +13106,7 @@ class UltimateListCtrl(wx.PyControl): :param `entry`: should be a sequence with an item for each column. """ - + if entry: if wx.USE_UNICODE: cvtfunc = unicode @@ -13113,7 +13116,7 @@ class UltimateListCtrl(wx.PyControl): self.InsertStringItem(pos, cvtfunc(entry[0])) for i in range(1, len(entry)): self.SetStringItem(pos, i, cvtfunc(entry[i])) - + return pos @@ -13124,9 +13127,9 @@ class UltimateListCtrl(wx.PyControl): :param `colour`: if not ``None``, a valid :class:`Colour` instance. Otherwise, the colour is taken from the system value ``wx.SYS_COLOUR_HIGHLIGHT``. """ - + self._mainWin.SetFirstGradientColour(colour) - + def SetSecondGradientColour(self, colour=None): """ @@ -13142,13 +13145,13 @@ class UltimateListCtrl(wx.PyControl): def GetFirstGradientColour(self): """ Returns the first gradient colour for gradient-style selections. """ - + return self._mainWin.GetFirstGradientColour() def GetSecondGradientColour(self): """ Returns the second gradient colour for gradient-style selections. """ - + return self._mainWin.GetSecondGradientColour() @@ -13164,7 +13167,7 @@ class UltimateListCtrl(wx.PyControl): """ self._mainWin.EnableSelectionGradient(enable) - + def SetGradientStyle(self, vertical=0): """ @@ -13214,7 +13217,7 @@ class UltimateListCtrl(wx.PyControl): """ self._mainWin.SetBackgroundImage(image) - + def GetBackgroundImage(self): """ @@ -13222,7 +13225,7 @@ class UltimateListCtrl(wx.PyControl): :note: At present, the background image can only be used in "tile" mode. - .. todo:: Support background images also in stretch and centered modes. + .. todo:: Support background images also in stretch and centered modes. """ return self._mainWin.GetBackgroundImage() @@ -13235,18 +13238,18 @@ class UltimateListCtrl(wx.PyControl): :param `watermark`: if not ``None``, an instance of :class:`Bitmap`. - .. todo:: Better support for this is needed. - """ + .. todo:: Better support for this is needed. + """ self._mainWin.SetWaterMark(watermark) - + def GetWaterMark(self): """ Returns the :class:`UltimateListCtrl` watermark image (if any), displayed in the bottom right part of the window. - .. todo:: Better support for this is needed. + .. todo:: Better support for this is needed. """ return self._mainWin.GetWaterMark() @@ -13282,7 +13285,7 @@ class UltimateListCtrl(wx.PyControl): """ self._mainWin.SetHyperTextFont(font) - + def SetHyperTextNewColour(self, colour): """ @@ -13292,7 +13295,7 @@ class UltimateListCtrl(wx.PyControl): """ self._mainWin.SetHyperTextNewColour(colour) - + def GetHyperTextNewColour(self): """ Returns the colour used to render a non-visited hypertext item. """ @@ -13308,7 +13311,7 @@ class UltimateListCtrl(wx.PyControl): """ self._mainWin.SetHyperTextVisitedColour(colour) - + def GetHyperTextVisitedColour(self): """ Returns the colour used to render a visited hypertext item. """ @@ -13327,7 +13330,7 @@ class UltimateListCtrl(wx.PyControl): item = CreateListItem(itemOrId, col) return self._mainWin.SetItemVisited(item, visited) - + def GetItemVisited(self, itemOrId, col=0): """ @@ -13361,12 +13364,12 @@ class UltimateListCtrl(wx.PyControl): :param `col`: the column index to which the input item belongs to; :param `wnd`: a non-toplevel window to be displayed next to the item; :param `expand`: ``True`` to expand the column where the item/subitem lives, - so that the window will be fully visible. + so that the window will be fully visible. """ item = CreateListItem(itemOrId, col) return self._mainWin.SetItemWindow(item, wnd, expand) - + def DeleteItemWindow(self, itemOrId, col=0): """ @@ -13378,7 +13381,7 @@ class UltimateListCtrl(wx.PyControl): item = CreateListItem(itemOrId, col) return self._mainWin.DeleteItemWindow(item) - + def GetItemWindowEnabled(self, itemOrId, col=0): """ @@ -13424,15 +13427,15 @@ class UltimateListCtrl(wx.PyControl): :param `renderer`: a class able to correctly render header buttons :note: the renderer class **must** implement the methods `DrawHeaderButton` - and `GetForegroundColor`. + and `GetForegroundColor`. """ if not self.HasAGWFlag(ULC_REPORT): raise Exception("Custom renderers can be used on with style = ULC_REPORT") - + self._headerWin.SetCustomRenderer(renderer) - + def SetFooterCustomRenderer(self, renderer=None): """ Associate a custom renderer with the footer - all columns will use it. @@ -13440,12 +13443,12 @@ class UltimateListCtrl(wx.PyControl): :param `renderer`: a class able to correctly render header buttons :note: the renderer class **must** implement the methods `DrawHeaderButton` - and `GetForegroundColor`. + and `GetForegroundColor`. """ if not self.HasAGWFlag(ULC_REPORT) or not self.HasAGWFlag(ULC_FOOTER): raise Exception("Custom renderers can only be used on with style = ULC_REPORT | ULC_FOOTER") - + self._footerWin.SetCustomRenderer(renderer) @@ -13457,12 +13460,12 @@ class UltimateListCtrl(wx.PyControl): :param `renderer`: a class able to correctly render the input item. :note: the renderer class **must** implement the methods `DrawHeaderButton` - and `GetForegroundColor`. + and `GetForegroundColor`. """ if not self.HasAGWFlag(ULC_REPORT): raise Exception("Custom renderers can be used on with style = ULC_REPORT") - + return self._mainWin.SetCustomRenderer(col, renderer) @@ -13475,12 +13478,12 @@ class UltimateListCtrl(wx.PyControl): :param `renderer`: a class able to correctly render the input item. :note: the renderer class **must** implement the methods `DrawSubItem`, - `GetLineHeight` and `GetSubItemWidth`. + `GetLineHeight` and `GetSubItemWidth`. """ if not self.HasAGWFlag(ULC_REPORT) or not self.HasAGWFlag(ULC_HAS_VARIABLE_ROW_HEIGHT): raise Exception("Custom renderers can be used on with style = ULC_REPORT | ULC_HAS_VARIABLE_ROW_HEIGHT") - + item = CreateListItem(itemOrId, col) return self._mainWin.SetItemCustomRenderer(item, renderer) @@ -13491,10 +13494,10 @@ class UltimateListCtrl(wx.PyControl): An item/subitem may overwrite neighboring items/subitems if its text would not normally fit in the space allotted to it. - + :param `itemOrId`: an instance of :class:`UltimateListItem` or the item index; :param `col`: the column index to which the input item belongs to; - :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. + :param `over`: ``True`` to set the item in a overflow state, ``False`` otherwise. """ if not self.HasAGWFlag(ULC_REPORT) or self._mainWin.IsVirtual(): @@ -13502,7 +13505,7 @@ class UltimateListCtrl(wx.PyControl): item = CreateListItem(itemOrId, col) return self._mainWin.SetItemOverFlow(item, over) - + def GetItemOverFlow(self, itemOrId, col=0): """ @@ -13536,7 +13539,7 @@ class UltimateListCtrl(wx.PyControl): return self._mainWin.GetScrollPos() return 0 - + def SetScrollPos(self, orientation, pos, refresh=True): """ @@ -13552,7 +13555,7 @@ class UltimateListCtrl(wx.PyControl): if self._mainWin: self._mainWin.SetScrollPos(orientation, pos, refresh) - + def GetScrollThumb(self): """ @@ -13595,7 +13598,7 @@ class UltimateListCtrl(wx.PyControl): if height is not None and height < 1: raise Exception("Invalid height passed to SetHeaderHeight: %s"%repr(height)) - + self._headerWin._headerHeight = height self.DoLayout() @@ -13607,7 +13610,7 @@ class UltimateListCtrl(wx.PyControl): return -1 return self._headerWin.GetWindowHeight() - + def SetFooterHeight(self, height): """ @@ -13624,7 +13627,7 @@ class UltimateListCtrl(wx.PyControl): if height is not None and height < 1: raise Exception("Invalid height passed to SetFooterHeight: %s"%repr(height)) - + self._footerWin._footerHeight = height self.DoLayout() @@ -13645,7 +13648,7 @@ class UltimateListCtrl(wx.PyControl): """ self.Layout() - + self._mainWin.ResizeColumns() self._mainWin.ResetVisibleLinesRange(True) self._mainWin.RecalculatePositions() @@ -13653,7 +13656,7 @@ class UltimateListCtrl(wx.PyControl): if self._headerWin: self._headerWin.Refresh() - + if self._footerWin: self._footerWin.Refresh()