aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tktree.py
blob: 8fbe46243ab752c440473adfb56ae3891129a234 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

"""
What I want it to look like:

+- One
| \- Two
| |- Three
| |- Four
| +- Five
| | \- Six
| |- Seven
+- Eight
| \- Nine
"""

import os
from Tkinter import *

class Node:
    def __init__(self):
        """
        Do whatever you want here.
        """
        self.item=None
    def getName(self):
        """
        Return the name of this node in the tree.
        """
        pass
    def isExpandable(self):
        """
        Return true if this node is expandable.
        """
        return len(self.getSubNodes())>0
    def getSubNodes(self):
        """
        Return the sub nodes of this node.
        """
        return []
    def gotDoubleClick(self):
        """
        Called when we are double clicked.
        """
        pass
    def updateMe(self):
        """
        Call me when something about me changes, so that my representation
        changes.
        """
        if self.item:
            self.item.update()

class FileNode(Node):
    def __init__(self,name):
        Node.__init__(self)
        self.name=name
    def getName(self):
        return os.path.basename(self.name)
    def isExpandable(self):
        return os.path.isdir(self.name)
    def getSubNodes(self):
        names=map(lambda x,n=self.name:os.path.join(n,x),os.listdir(self.name))
        return map(FileNode,names)

class TreeItem:
    def __init__(self,widget,parent,node):
        self.widget=widget
        self.node=node
        node.item=self
        if self.node.isExpandable():
            self.expand=0
        else:
            self.expand=None
        self.parent=parent
        if parent:
            self.level=self.parent.level+1
        else:
            self.level=0
        self.first=0 # gets set in Tree.expand()
        self.subitems=[]
    def __del__(self):
        del self.node
        del self.widget
    def __repr__(self):
        return "<Item for Node %s at level %s>"%(self.node.getName(),self.level)
    def render(self):
        """
        Override in a subclass.
        """
        raise NotImplementedError
    def update(self):
        self.widget.update(self)

class ListboxTreeItem(TreeItem):
    def render(self):
        start=self.level*"|    "
        if self.expand==None and not self.first:
            start=start+"|"
        elif self.expand==0:
            start=start+"L"
        elif self.expand==1:
            start=start+"+"
        else:
            start=start+"\\"
        r=[start+"- "+self.node.getName()]
        if self.expand:
            for i in self.subitems:
                r.extend(i.render())
        return r

class ListboxTree:
    def __init__(self,parent=None,**options):
        self.box=apply(Listbox,[parent],options)
        self.box.bind("<Double-1>",self.flip)
        self.roots=[]
        self.items=[]
    def pack(self,*args,**kw):
        """
        for packing.
        """
        apply(self.box.pack,args,kw)
    def grid(self,*args,**kw):
        """
        for gridding.
        """
        apply(self.box.grid,args,kw)
    def yview(self,*args,**kw):
        """
        for scrolling.
        """
        apply(self.box.yview,args,kw)
    def addRoot(self,node):
        r=ListboxTreeItem(self,None,node)
        self.roots.append(r)
        self.items.append(r)
        self.box.insert(END,r.render()[0])
        return r
    def curselection(self):
        c=self.box.curselection()
        if not c: return
        return self.items[int(c[0])]
    def flip(self,*foo):
        if not self.box.curselection(): return
        item=self.items[int(self.box.curselection()[0])]
        if item.expand==None: return
        if not item.expand:
            self.expand(item)
        else:
            self.close(item)
        item.node.gotDoubleClick()
    def expand(self,item):
        if item.expand or item.expand==None: return
        item.expand=1
        item.subitems=map(lambda x,i=item,s=self:ListboxTreeItem(s,i,x),item.node.getSubNodes())
        if item.subitems:
            item.subitems[0].first=1
        i=self.items.index(item)
        self.items,after=self.items[:i+1],self.items[i+1:]
        self.items=self.items+item.subitems+after
        c=self.items.index(item)
        self.box.delete(c)
        r=item.render()
        for i in r:
            self.box.insert(c,i)
            c=c+1
    def close(self,item):
        if not item.expand: return
        item.expand=0
        length=len(item.subitems)
        for i in item.subitems:
            self.close(i)
        c=self.items.index(item)
        del self.items[c+1:c+1+length]
        for i in range(length+1):
            self.box.delete(c)
        self.box.insert(c,item.render()[0])
    def remove(self,item):
        if item.expand:
            self.close(item)
        c=self.items.index(item)
        del self.items[c]
        if item.parent:
            item.parent.subitems.remove(item)
        self.box.delete(c)
    def update(self,item):
        if item.expand==None:
            c=self.items.index(item)
            self.box.delete(c)
            self.box.insert(c,item.render()[0])
        elif item.expand:
            self.close(item)
            self.expand(item)

if __name__=="__main__":
    tk=Tk()
    s=Scrollbar()
    t=ListboxTree(tk,yscrollcommand=s.set)
    t.pack(side=LEFT,fill=BOTH)
    s.config(command=t.yview)
    s.pack(side=RIGHT,fill=Y)
    t.addRoot(FileNode("C:/"))
    #mainloop()