]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/wxPython/tests/pytree.py
wxPython 2.1b1:
[wxWidgets.git] / utils / wxPython / tests / pytree.py
diff --git a/utils/wxPython/tests/pytree.py b/utils/wxPython/tests/pytree.py
new file mode 100644 (file)
index 0000000..10deb18
--- /dev/null
@@ -0,0 +1,203 @@
+"""
+Hello, and welcome to this test of the wxTreeItemData class.
+
+The wxTreeItemData class can be used to associate a python object with
+a wxTreeCtrl item. In this sample, its use is demonstrated via a tree
+control that shows the contents of a python namespace according to the
+standard dir() command. Every item in the tree has its label taken
+from the dir() output, and 'behind it' a reference to the python
+object is stored in a wxTreeItemData object.
+
+As you may have guessed by now, this sample automatically displays
+'__doc__' strings if the selected python object happens to have
+one. Please expand the pyTree object to learn more about the
+implementation.
+
+Version 1.0, April 4 1999.
+Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)
+
+P.S. Check out the string module. It's imported in this sample not
+because it's used, but because it's so beautifully documented...
+"""
+
+from wxPython import wx
+import string # Don't use it, but it's fun expanding :-)
+
+#----------------------------------------------------------------------
+
+def _getindent(line):
+    """Returns the indentation level of the given line."""
+    indent = 0
+    for c in line:
+        if c == ' ': indent = indent + 1
+        elif c == '\t': indent = indent + 8
+        else: break
+    return indent
+
+def _sourcefinder(func):
+    """Given a func_code object, this function tries to find and return
+    the python source code of the function."""
+    try:
+        f = open(func.co_filename,"r")
+    except:
+        return "(could not open file %s)" % (func.co_filename,)
+
+    for i in range(func.co_firstlineno):
+        line = f.readline()
+    ind = _getindent(line)
+    msg = ""
+    while line:
+        msg = msg + line
+        line = f.readline()
+        # the following should be <= ind, but then we get
+        # confused by multiline docstrings. Using == works most of
+        # the time... but not always!
+        if _getindent(line) == ind: break
+    return msg
+
+#----------------------------------------------------------------------
+
+class pyTree(wx.wxTreeCtrl):
+    """
+    This wxTreeCtrl derivative displays a tree view of a Python namespace.
+    Anything from which the dir() command returns a non-empty list is a branch
+    in this tree.
+    """
+
+    def __init__(self, parent, id, root):
+        """
+        Initialize function; because we insert branches into the tree
+        as needed, we use the ITEM_EXPANDING event handler. The
+        ITEM_COLLAPSED handler removes the stuff afterwards. The
+        SEL_CHANGED handler attempts to display interesting
+        information about the selected object.
+        """
+        wx.wxTreeCtrl.__init__(self, parent, id)
+        self.root = self.AddRoot(str(root), -1, -1, wx.wxTreeItemData(root))
+        if dir(root):
+            self.SetItemHasChildren(self.root, wx.TRUE)
+        wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
+        wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
+        wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
+        self.output = None
+
+
+    def SetOutput(self, output):
+        """
+        Set output function (accepts single string). Used to display string
+        representation of the selected object by OnSelChanged.
+        """
+        self.output = output
+
+
+    def OnItemExpanding(self,event):
+        """
+        The real workhorse of this class. First we retrieve the object
+        (parent) belonging to the branch that is to be expanded. This
+        is done by calling GetPyData(parent), which is a short-cut for
+        GetPyItemData(parent).Get().
+
+        Then we get the dir() list of that object. For each item in
+        this list, a tree item is created with associated
+        wxTreeItemData referencing the child object. We get this
+        object using child = getattr(parent, item).
+
+        Finally, we check wether the child returns a non-empty dir()
+        list. If so, it is labeled as 'having children', so that it
+        may be expanded. When it actually is expanded, this function
+        will again figure out what the offspring is.
+        """
+        item = event.GetItem()
+        obj = self.GetPyData( item )
+        lst = dir(obj)
+        for key in lst:
+            new_obj = getattr(obj,key)
+            new_item = self.AppendItem( item, key, -1, -1,
+                                        wx.wxTreeItemData(new_obj) )
+            if dir(new_obj):
+                self.SetItemHasChildren(new_item, wx.TRUE)
+
+    def OnItemCollapsed(self, event):
+        """
+        We need to remove all children here, otherwise we'll see all
+        that old rubbish again after the next expansion.
+        """
+        item = event.GetItem()
+        self.DeleteChildren(item)
+
+    def OnSelChanged(self, event):
+        """
+        If an output function is defined, we try to print some
+        informative, interesting and thought-provoking stuff to it.
+        If it has a __doc__ string, we print it. If it's a function or
+        unbound class method, we attempt to find the python source.
+        """
+        if not self.output:
+            return
+        obj = self.GetPyData( event.GetItem() )
+        msg = str(obj)
+        if hasattr(obj, '__doc__'):
+            msg = msg+"\n\nDocumentation string:\n\n%s" % ( getattr(obj, '__doc__'),)
+        # Is it a function?
+        func = None
+        if hasattr(obj, "func_code"): # normal function
+            func = getattr(obj, "func_code")
+        elif hasattr(obj, "im_func"): # unbound class method
+            func = getattr(getattr(obj, "im_func"), "func_code")
+        if func: # if we found one, let's try to print the source
+            msg = msg+"\n\nFunction source:\n\n" + _sourcefinder(func)
+
+        apply(self.output, (msg,))
+
+#----------------------------------------------------------------------
+
+overview = __doc__
+
+def runTest(frame, nb, log):
+    split = wx.wxSplitterWindow(nb, -1)
+    tree = pyTree(split, -1, __main__)
+    text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
+                         wx.wxDefaultSize, wx.wxTE_MULTILINE)
+    split.SplitVertically(tree, text, 200)
+    tree.SetOutput(text.SetValue)
+    tree.SelectItem(tree.root)
+    text.SetBackgroundColour(wxNamedColour("LIGHT BLUE"))
+    tree.SetBackgroundColour(wxNamedColour("LIGHT BLUE"))
+
+    return split
+
+
+
+#----------------------------------------------------------------------
+if __name__ == '__main__':
+
+    class MyFrame(wx.wxFrame):
+        """Very standard Frame class. Nothing special here!"""
+
+        def __init__(self):
+            """Make a splitter window; left a tree, right a textctrl. Wow."""
+            import __main__
+            wx.wxFrame.__init__(self, wx.NULL, -1, "PyTreeItemData Test",
+                                wx.wxDefaultPosition, wx.wxSize(800,500))
+            split = wx.wxSplitterWindow(self, -1)
+            tree = pyTree(split, -1, __main__)
+            text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
+                                 wx.wxDefaultSize, wx.wxTE_MULTILINE)
+            split.SplitVertically(tree, text, 200)
+            tree.SetOutput(text.SetValue)
+            tree.SelectItem(tree.root)
+
+    class MyApp(wx.wxApp):
+        """This class is even less interesting than MyFrame."""
+
+        def OnInit(self):
+            """OnInit. Boring, boring, boring!"""
+            frame = MyFrame()
+            frame.Show(wx.TRUE)
+            self.SetTopWindow(frame)
+            return wx.TRUE
+
+    app = MyApp(0)
+    app.MainLoop()
+
+