1 from Tkinter import *
2 import Pmw
3 import tkMessageBox
4 from teamwork.widgets.DynamicsEditor import *
5 from teamwork.math.ProbabilityTree import identityTree
6 from teamwork.dynamics.pwlDynamics import PWLDynamics
7
9 """Dialog to display and edit the dynamics of a state feature"""
10
12 optiondefs = (
13 ('dynamics', {}, None),
14 ('key', None, None),
15 ('feature', None, Pmw.INITOPT),
16 ('action', None, Pmw.INITOPT),
17 ('expert', 0, Pmw.INITOPT),
18 ('selector', 'listbox',Pmw.INITOPT),
19 ('society', {}, None),
20 ('newLabel', 'New...', Pmw.INITOPT),
21 )
22 self.defineoptions(kw,optiondefs)
23 Pmw.Dialog.__init__(self,parent)
24 self.options = {}
25 if self['action']:
26 for feature,dynamics in self['dynamics'].items():
27 for agent,tree in dynamics.items():
28 if tree:
29 label = '%s of %s' % (feature,agent)
30 self.options[label] = {'feature':feature,
31 'agent':agent}
32 else:
33 for action,dynamics in self['dynamics'].items():
34 if dynamics:
35 self.options[str(action)] = action
36 options = self.options.keys()
37 options.sort(lambda x,y:cmp(str(x).lower(),str(y).lower()))
38
39 tree = self.createcomponent('editor',(),None,
40 DynamicsEditor,
41 (self.component('dialogchildsite'),),
42 menus_key=self['key'],
43 menus_feature=self['feature'],
44 expert=self['expert'],
45 orient='horizontal',
46 society=self['society'],
47 )
48 orientation = 'left'
49 itemList = options[:]
50 if self['selector'] == 'pulldown':
51
52 button = self.createcomponent('Selector',(),None,
53 Pmw.OptionMenu,
54 (self.component('dialogchildsite'),),
55 items=itemList,
56 command=self.selectTree)
57 if len(options) > 0:
58 button.invoke(options[0])
59 button.pack(side='top',fill='y')
60 elif self['selector'] == 'listbox':
61
62 pane = tree.insert('select pane',min=200)
63 button = self.createcomponent('Selector',(),None,
64 Pmw.ScrolledListBox,(pane,),
65 items=itemList,
66 labelpos='nw',
67 selectioncommand=self.selectTree,
68 listbox_selectmode='single',
69 )
70 if self['action']:
71 button.configure(label_text='State:')
72 else:
73 button.configure(label_text='Action:')
74 button.pack(side='top',fill='both',expand='yes')
75 if self['society']:
76 box = self.createcomponent('select buttons',(),None,
77 Pmw.ButtonBox,(pane,),
78 )
79 box.add(self['newLabel'],command=self.newDynamics)
80 box.add('Delete',command=self.delDynamics,state='disabled')
81 box.pack(side='top',fill='x')
82 if len(options) > 0:
83 button.setvalue(str(options[0]))
84 self.selectTree()
85 else:
86 raise UserWarning,'Unknown selector type: %s' % (self['selector'])
87
88 tree.configure(hull_width=800)
89 tree.pack(side=orientation,fill='both',expand='yes')
90 self.initialiseoptions()
91
93 options = {}
94 if self['action']:
95
96 if self['society']:
97 for agent in self['society'].members():
98 for feature in agent.getStateFeatures():
99 options['%s of %s' % (feature,agent.name)] = \
100 {'feature':feature,'agent':agent.name}
101 label = 'State Feature'
102 else:
103
104 label = 'Action Type'
105 if self['society']:
106 for agent in self['society'].members():
107 for action in sum(agent.actions.getOptions(),[]):
108 if not self['dynamics'].has_key(action['type']):
109 options[action['type']] = action['type']
110 if not self['dynamics'].has_key(None):
111 options['(none)'] = None
112 if len(options) == 0:
113
114 tkMessageBox.showerror('No Missing Dynamics','All possible dynamics are already included')
115 return
116 items = options.keys()
117 items.sort(lambda x,y:cmp(x.lower(),y.lower()))
118 dialog = Pmw.SelectionDialog(self.component('dialogchildsite'),
119 title=label,
120 scrolledlist_items=items,
121 scrolledlist_listbox_width=50,
122 buttons=('OK','Cancel'),
123 defaultbutton='OK')
124 if dialog.activate() == 'OK':
125 try:
126 option = dialog.component('scrolledlist').getcurselection()[0]
127 except IndexError:
128 tkMessageBox.showerror('No Selection','You did not select anything for new dynamics')
129 return
130 if self['feature']:
131 if self['dynamics'].has_key(options[option]):
132 msg = 'Dynamics for %s already exist' % (option)
133 tkMessageBox.showerror('Duplicate Action',msg)
134 return
135 elif self['key']:
136 args = {'tree':identityTree(self['key'])}
137 self['dynamics'][options[option]] = PWLDynamics(args)
138 else:
139 args = {'tree':identityTree(self['feature'])}
140 self['dynamics'][options[option]] = PWLDynamics(args)
141 else:
142 feature = options[option]['feature']
143 agent = options[option]['agent']
144 if self['dynamics'].has_key(feature) and \
145 self['dynamics'][feature].has_key(agent):
146 msg = 'Dynamics for %s already exist' % (option)
147 tkMessageBox.showerror('Duplicate Feature',msg)
148 return
149 else:
150 args = {'tree':identityTree(options[option]['feature'])}
151 try:
152 self['dynamics'][feature][agent] = PWLDynamics(args)
153 except KeyError:
154 self['dynamics'][feature] = {agent: PWLDynamics(args)}
155 self.options[option] = options[option]
156 self.refreshItems(option)
157 option = self.options[option]
158 self.selectTree(option)
159
161 if option == '':
162 widget = self.component('Selector')
163 try:
164 option = self.options[widget.getcurselection()[0]]
165 except KeyError:
166 raise UserWarning,'Unknown selection: %s' % \
167 widget.getcurselection()[0]
168 except IndexError:
169
170 pass
171 if option != '':
172 widget = self.component('editor')
173 if self['action']:
174 if self['society']:
175 widget.component('menus').configure(feature=option['feature'])
176 dynamics = self['dynamics'][option['feature']][option['agent']]
177 else:
178 dynamics = self['dynamics'][option]
179 tree = dynamics.getTree()
180 widget.configure(tree=tree)
181 widget.component('tree').root.invoke()
182 if self['society']:
183 self.component('select buttons').component('Delete').configure(state='normal')
184
186 widget = self.component('Selector')
187 label = widget.getcurselection()[0]
188 try:
189 option = self.options[label]
190 except KeyError:
191 raise UserWarning,'Unknown selection: %s' % (label)
192 title = 'Confirm delete'
193 msg = 'Delete these dynamics permanently?'
194 if tkMessageBox.askokcancel(title=title,message=msg):
195 del self.options[label]
196 if self['action']:
197 del self['dynamics'][option['feature']][option['agent']]
198 else:
199 del self['dynamics'][option]
200 self.refreshItems()
201 self.component('editor').configure(tree=None)
202
204 """Redraw the items in the selection pane (on the left)
205 """
206 widget = self.component('Selector')
207 itemList = self.options.keys()
208 itemList.sort(lambda x,y:cmp(x.lower(),y.lower()))
209 if self['selector'] == 'pulldown':
210 widget.setitems(itemList)
211 else:
212 widget.setlist(itemList)
213 if selection is None:
214 if self['society']:
215 self.component('select buttons').component('Delete').configure(state='disabled')
216 else:
217 widget.setvalue(selection)
218