# 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 True

    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 True

    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("%r:" % (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()

