Package teamwork :: Package widgets :: Module TreeEditor
[hide private]
[frames] | no frames]

Source Code for Module teamwork.widgets.TreeEditor

  1  from teamwork.math.KeyedMatrix import * 
  2  from teamwork.math.KeyedTree import * 
  3   
  4  from Tkinter import * 
  5  import tkMessageBox 
  6  import Pmw 
  7   
  8  from teamwork.widgets.TreeWidget import * 
  9   
10 -class TreeEditor(Pmw.PanedWidget):
11 """Widget for editing a KeyedTree object""" 12
13 - def __init__(self,parent,**kw):
14 optiondefs = ( 15 # The initial dynamics tree to show/edit 16 ('tree', None, self.setTree), 17 # Width of the pane containing the tree browser 18 ('treeWidth', 300, Pmw.INITOPT), 19 # Width of the pane containing editing widgets 20 ('editorWidth', 150, Pmw.INITOPT), 21 # Flag indicating the level of detail used in display 22 ('expert', False, Pmw.INITOPT), 23 # Font for Tree 24 ('font', ('Helvetica', 10,'bold'), Pmw.INITOPT), 25 ) 26 self.defineoptions(kw, optiondefs) 27 Pmw.PanedWidget.__init__(self,parent) 28 # Set overall widget size 29 self.configure(hull_width=self['treeWidth']+self['editorWidth']) 30 # Pane for viewing decision tree 31 self.add('treePane',size=self['treeWidth'],min=self['treeWidth']) 32 Label(self.pane('treePane'),text='Tree:').grid(row=0,column=0,sticky='wn') 33 widget = self.createcomponent('tree',(),None,EasyTree, 34 (self.pane('treePane'),), 35 font=self['font'], 36 icon=None,openicon=None, 37 root_label="no change", 38 root_action = self.select, 39 ## usehullsize=1, 40 action=None) 41 42 # Vertical scrollbar 43 sb=Scrollbar(widget.master,orient='vertical') 44 sb.grid(row=1,column=1,sticky='ns') 45 widget.configure(yscrollcommand=sb.set) 46 sb.configure(command=widget.yview) 47 # Horizontal scrollbar 48 sb=Scrollbar(widget.master,orient='horizontal') 49 sb.grid(row=2,column=0,sticky='ew') 50 widget.configure(xscrollcommand=sb.set) 51 sb.configure(command=widget.xview) 52 53 widget.grid(row=1,column=0,sticky='esnw') 54 widget.master.grid_rowconfigure(1, weight=1) 55 widget.master.grid_columnconfigure(0, weight=1) 56 # Pane for editing widgets 57 self.add('editorPane',size=self['editorWidth'], 58 max=self['editorWidth'],min=self['editorWidth']) 59 Label(self.pane('editorPane'),text='Edit:', 60 anchor='nw').pack(side='top',fill='x') 61 # Action buttons 62 frame = self.createcomponent('box',(),None,Pmw.ButtonBox, 63 (self.pane('editorPane'),), 64 orient='vertical') 65 frame.add('apply',command=self.apply, 66 text='Apply',state='disabled') 67 frame.add('add',command=self.addBranch, 68 text='Add branch',state='disabled') 69 frame.add('delete',command=self.deleteNode, 70 text='Delete node',state='disabled') 71 frame.pack(side='bottom',fill='x') 72 # Store individual tree nodes 73 self.nodes = {} 74 self.initialiseoptions()
75
76 - def setTree(self,tree=None,node=None,prefix=''):
77 """Callback for setting the tree to display and edit""" 78 self.component('tree').inhibitDraw = 1 79 if tree is None: 80 tree = self['tree'] 81 if tree is None: 82 # Draw emptiness 83 self.component('tree').easyRoot.deleteChildren() 84 return 85 if not node: 86 # Start at top of tree 87 node = self.component('tree').easyRoot 88 # Remove any previous tree display 89 node.deleteChildren() 90 self.component('tree').root.action = self.select 91 # node = node.addChild(self.component('tree'),isLeaf=True) 92 node['action'] = self.select 93 if not isinstance(tree,self['tree'].__class__): 94 name = self.displayLeaf(tree) 95 node['label'] = prefix+name 96 elif tree.isLeaf(): 97 # Simply display value 98 name = self.displayLeaf(tree.getValue()) 99 node['label'] = prefix+name 100 else: 101 # Display branchpoint first 102 name = self.displayPlane(tree.split) 103 node['label'] = prefix+name 104 # Display children 105 if tree.isProbabilistic(): 106 elements = tree.split.domain() 107 elements.sort() 108 node['isLeaf']=False 109 subnode = node.addChild(self.component('tree'),isLeaf=True) 110 subnode['action'] = self.select 111 self.setTree(elements[0],subnode,'then ') 112 if len(elements) == 2: 113 # Probabilistic branch 114 subnode = node.addChild(self.component('tree'),isLeaf=True) 115 subnode['action'] = self.select 116 self.setTree(elements[1],subnode,'else ') 117 elif len(elements) > 2: 118 raise NotImplementedError,'Unable to distributions with more than 2 branches' 119 else: 120 node['isLeaf']=False 121 fTree,tTree = tree.getValue() 122 # Then branch 123 subnode = node.addChild(self.component('tree'),isLeaf=True) 124 subnode['action'] = self.select 125 self.setTree(tTree,subnode,'then ') 126 # Else branch 127 subnode = node.addChild(self.component('tree'),isLeaf=True) 128 subnode['action']=self.select 129 self.setTree(fTree,subnode,'else ') 130 self.component('tree').inhibitDraw = 0 131 self.nodes[id(node)] = tree 132 self.component('tree').root.expand() 133 node.refresh(self.component('tree'))
134
135 - def displayLeaf(self,value):
136 return str(value)
137
138 - def displayPlane(self,planes):
139 return str(planes)
140
141 - def select(self,selection=None,event=None):
142 tree = self.selectedTree() 143 if not tree: 144 self.component('box_apply').configure(state='disabled') 145 self.component('box_add').configure(state='disabled') 146 self.component('box_delete').configure(state='disabled') 147 else: 148 if tree.isLeaf(): 149 self.component('box_add').configure(state='normal') 150 self.component('box_delete').configure(state='normal') 151 else: 152 self.component('box_add').configure(state='normal') 153 self.component('box_delete').configure(state='normal') 154 self.component('box_apply').configure(state='normal') 155 if tree.isLeaf(): 156 self.selectLeaf() 157 else: 158 self.selectBranch()
159
160 - def setLeaf(self,leafType):
161 pass
162
163 - def setBranch(self,rowType):
164 pass
165
166 - def selectLeaf(self):
167 pass
168
169 - def selectBranch(self):
170 pass
171
172 - def apply(self):
173 pass
174
175 - def selection(self,tree=None):
176 """ 177 @return: the selected C{Node} object (C{None} if none selected)""" 178 if not tree: 179 tree = self.component('tree') 180 return tree.selected_node()
181
182 - def selectedTree(self):
183 """ 184 @return: selected C{KeyedTree} object (C{None} if none selected)""" 185 node = self.selection() 186 if node: 187 try: 188 return self.nodes[id(node)] 189 except KeyError: 190 # Hopefully, because we've selected the top (label) node 191 return None 192 else: 193 return None
194
195 - def addBranch(self):
196 pass
197
198 - def deleteNode(self):
199 pass
200
201 - def findParent(self,node,tree=None):
202 """Returns the parent of the given node (None if none)""" 203 if not tree: 204 tree = self.component('tree') 205 for child in tree.child: 206 if child is node: 207 return tree 208 else: 209 value = self.findParent(node,child) 210 if value: 211 return value 212 else: 213 return None
214 215 if __name__ == '__main__': 216 from teamwork.examples.PSYOP.oil import * 217 218 tree = oilEconomic()['tree'] 219 print tree.simpleText() 220 root = Tk() 221 editor = TreeEditor(root,tree=tree, 222 features=['militaryPower','economicPower', 223 'oilInfrastructure','politicalPower'], 224 roles=['self','actor','object','location'], 225 orient=HORIZONTAL) 226 editor.pack(fill=BOTH) 227 root.mainloop() 228