# XXX TO DO:
# - popup menu
# - support partial or total redisplay
# - more doc strings
# - tooltips

# object browser

# XXX TO DO:
# - for classes/modules, add "open source" to object browser

from TreeWidget import TreeItem, TreeNode, ScrolledCanvas

from repr import Repr

myrepr = Repr()
myrepr.maxstring = 100
myrepr.maxother = 100

class ObjectTreeItem(TreeItem):
    def __init__(self, labeltext, object, setfunction=None):
        self.labeltext = labeltext
        self.object = object
        self.setfunction = setfunction
    def GetLabelText(self):
        return self.labeltext
    def GetText(self):
        return myrepr.repr(self.object)
    def GetIconName(self):
        if not self.IsExpandable():
            return "python"
    def IsEditable(self):
        return self.setfunction is not None
    def SetText(self, text):
        try:
            value = eval(text)
            self.setfunction(value)
        except:
            pass
        else:
            self.object = value
    def IsExpandable(self):
        return not not dir(self.object)
    def GetSubList(self):
        keys = dir(self.object)
        sublist = []
        for key in keys:
            try:
                value = getattr(self.object, key)
            except AttributeError:
                continue
            item = make_objecttreeitem(
                str(key) + " =",
                value,
                lambda value, key=key, object=self.object:
                    setattr(object, key, value))
            sublist.append(item)
        return sublist

class InstanceTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return 1
    def GetSubList(self):
        sublist = ObjectTreeItem.GetSubList(self)
        sublist.insert(0,
            make_objecttreeitem("__class__ =", self.object.__class__))
        return sublist

class ClassTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return 1
    def GetSubList(self):
        sublist = ObjectTreeItem.GetSubList(self)
        if len(self.object.__bases__) == 1:
            item = make_objecttreeitem("__bases__[0] =",
                self.object.__bases__[0])
        else:
            item = make_objecttreeitem("__bases__ =", self.object.__bases__)
        sublist.insert(0, item)
        return sublist

class AtomicObjectTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return 0

class SequenceTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return len(self.object) > 0
    def keys(self):
        return range(len(self.object))
    def GetSubList(self):
        sublist = []
        for key in self.keys():
            try:
                value = self.object[key]
            except KeyError:
                continue
            def setfunction(value, key=key, object=self.object):
                object[key] = value
            item = make_objecttreeitem(`key` + ":", value, setfunction)
            sublist.append(item)
        return sublist

class DictTreeItem(SequenceTreeItem):
    def keys(self):
        keys = self.object.keys()
        try:
            keys.sort()
        except:
            pass
        return keys

from types import *

dispatch = {
    IntType: AtomicObjectTreeItem,
    LongType: AtomicObjectTreeItem,
    FloatType: AtomicObjectTreeItem,
    StringType: AtomicObjectTreeItem,
    TupleType: SequenceTreeItem,
    ListType: SequenceTreeItem,
    DictType: DictTreeItem,
    InstanceType: InstanceTreeItem,
    ClassType: ClassTreeItem,
}

def make_objecttreeitem(labeltext, object, setfunction=None):
    t = type(object)
    if dispatch.has_key(t):
        c = dispatch[t]
    else:
        c = ObjectTreeItem
    return c(labeltext, object, setfunction)

# Test script

def _test():
    import sys
    from Tkinter import Tk
    root = Tk()
    root.configure(bd=0, bg="yellow")
    root.focus_set()
    sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
    sc.frame.pack(expand=1, fill="both")
    item = make_objecttreeitem("sys", sys)
    node = TreeNode(sc.canvas, None, item)
    node.update()
    root.mainloop()

if __name__ == '__main__':
    _test()
