1 import copy
2 import string
3 from Tkinter import *
4 import tkMessageBox
5 import Pmw
6 from teamwork.agent.RecursiveAgent import RecursiveAgent
7 from teamwork.agent.GoalBased import GoalBasedAgent
8 from teamwork.agent.stereotypes import Stereotyper
9 from teamwork.widgets.MultiWin import InnerWindow
10 from PropertyPane import PropertyFrame
11 from StatePane import StateFrame
12 from GoalPane import GoalFrame
13 from BeliefPane import BeliefFrame
14 from MentalModelPane import MentalModelFrame
15 from PolicyPane import PolicyFrame
16 from ActionPane import ActionFrame
17 from ActionEditor import ActionEditor
18 from MessagePane import MessageFrame
19 from ObservationPane import ObservationFrame
20 from RelationshipPane import RelationFrame
21 from teamwork.widgets.images import getPILImage
22
24 """Widget for displaying an agent
25
26 The following panes have separate widgets:
27 - L{General<PropertyFrame>}
28 - L{State<StateFrame>}
29 - L{Actions<ActionFrame>}
30 - L{Goals<GoalFrame>}
31 - L{Observations<ObservationFrame>}
32 - L{Beliefs<BeliefFrame>}
33 - L{Mental Models<MentalModelFrame>}
34 - L{Policy<PolicyFrame>}
35 - L{Messages<MessageFrame>}
36 - L{Relationships<RelationshipPane>}
37 """
38
39 agtHeight = 700
40 agtWidth = 750
41
43
44 self.paneSpecs = \
45 {'General': {'type': 'General','widget': PropertyFrame,
46 'image':getPILImage('icons/home.png')},
47 'State': {'type': 'State','widget': StateFrame,'tag':'S',
48 'image': getPILImage('icons/globe-green.png')},
49 'Actions': {'type': 'Actions','widget': ActionFrame,'tag':'A',
50 'image': getPILImage('icons/hammer-screwdriver.png')},
51 'Goals': {'type': 'Goals','widget': GoalFrame,'tag':'R',
52 'image': getPILImage('icons/trophy.png')},
53 'Observations': {'type': 'Observations','widget': ObservationFrame,
54 'image': getPILImage('icons/binocular.png')},
55 'Beliefs': {'type': 'Beliefs','widget': BeliefFrame,
56 'image':getPILImage('icons/users.png')},
57 'Policy': {'type': 'Policy','widget': PolicyFrame,'tag':'P',
58 'image': getPILImage('icons/traffic-light.png')},
59 'Messages': {'type': 'Messages','widget': MessageFrame,
60 'image':getPILImage('icons/balloon.png')},
61 'Relationships': {'type': 'Relationships','widget': RelationFrame,
62 'image':getPILImage('icons/chain.png')},
63 'Mental Models': {'type': 'Mental Models',
64 'widget': MentalModelFrame},
65 }
66 optiondefs = (
67 ('entity', None, Pmw.INITOPT),
68 ('society',{},Pmw.INITOPT),
69 ('x', 0, Pmw.INITOPT),
70 ('y', 0, Pmw.INITOPT),
71 ('balloon',None, Pmw.INITOPT),
72 ('actCmd',lambda x,y:{},Pmw.INITOPT),
73 ('msgCmd',lambda v,w,x,y,z: {},Pmw.INITOPT),
74 ('policyCmd',None,Pmw.INITOPT),
75 ('hypoCmd',None,Pmw.INITOPT),
76 ('stepCmd',None,Pmw.INITOPT),
77 ('valueCmd',None,Pmw.INITOPT),
78 ('abstract',None,Pmw.INITOPT),
79 ('expert',0,self.setExpert),
80 ('beta',False,Pmw.INITOPT),
81 ('destroycommand',None,Pmw.INITOPT),
82
83 ('window',True,Pmw.INITOPT),
84 )
85 self.defineoptions(kw,optiondefs)
86 Pmw.MegaArchetype.__init__(self,frame)
87
88 self.panes = [self.paneSpecs['General'],
89 self.paneSpecs['State']]
90 if self['abstract'] or len(self['entity'].actions.getOptions()) > 0:
91 self.panes.append(self.paneSpecs['Actions'])
92 if isinstance(self['entity'],GoalBasedAgent):
93 self.panes.append(self.paneSpecs['Goals'])
94 self.panes.append(self.paneSpecs['Observations'])
95 if not self['abstract'] and not self['entity'].parent:
96 self.panes.append(self.paneSpecs['Beliefs'])
97 if not self['abstract'] and len(self['entity'].actions.getOptions()) > 0:
98 self.panes.append(self.paneSpecs['Policy'])
99 if not self['abstract']:
100 self.panes.append(self.paneSpecs['Messages'])
101 self.panes.append(self.paneSpecs['Relationships'])
102
103 self.policywidgets = {}
104 self.bstatewidgets = {}
105 if self['window']:
106 self.win = InnerWindow(parent = frame, title = self['entity'].name,
107 height = self.agtHeight, width = self.agtWidth,
108 x = self['x'], y = self['y'],
109 destroycommand=self['destroycommand'])
110 container = self.win.component('frame')
111 else:
112 self.win = None
113 container = frame
114
115 notebook = self.createcomponent('notebook',(), None, Pmw.NoteBook,
116 (container,),raisecommand=self.selectPage,
117 )
118 notebook.pack(fill='both',expand='yes')
119 for entry in self.panes:
120 self.create_pane(self['entity'], notebook, entry)
121 self.selectPage(self.panes[0]['type'])
122 self.initialiseoptions()
123
125 if not entity:
126 entity = self['entity']
127 for component in self.components():
128 if self.componentgroup(component) == 'Pane':
129 self.component(component).configure(expert=self['expert'])
130 if not self['abstract'] and len(entity.actions.getOptions()) > 0:
131
132
133 self.setExpertPane(entity,'Policy','Messages')
134 if isinstance(entity,Stereotyper) and \
135 len(entity.getEntities()) > 0 and self['beta']:
136
137
138 self.setExpertPane(entity,'Mental Models','Policy')
139
141 notebook = self.component('notebook')
142 if self['expert']:
143 spec = self.paneSpecs[pane]
144 try:
145 tag = spec['tag']
146 except KeyError:
147 tag = spec['type']
148 if not tag in notebook.pagenames():
149 page = notebook.insert(tag,before=before)
150 self.create_pane(entity,notebook,spec,page)
151 elif pane in notebook.pagenames():
152 if entity.parent:
153 self.destroycomponent('%s %s' % \
154 (entity.ancestry(),pane))
155 else:
156 self.destroycomponent(pane)
157 notebook.delete(pane)
158
160 """Display's the hypothetical result of the entity's policy"""
161 if entity.parent:
162 widget = self.component('%s Actions' % (entity.ancestry()))
163 else:
164 widget = self.component('Actions')
165 options = widget.getActions()
166 if len(options) == 0:
167 tkMessageBox.showerror('Agent Action Error','The agent has no allowable actions! Please go to the Action pane and select at least one possible choice.')
168 else:
169 self['hypoCmd'](entity,options)
170
172 """Performs the policy-selected action of the given entity"""
173 widget = self.component('Actions')
174 options = widget.getActions()
175 if len(options) == 0:
176 tkMessageBox.showerror('Agent Action Error','The agent has no allowable actions! Please go to the Action pane and select at least one possible choices.')
177 else:
178 self['stepCmd'](self['entity'],options)
179
181 """Performs the policy-selected action of the given entity"""
182 self['valueCmd'](entity)
183
185 result = self['actCmd']({self['entity'].name:action})
186
187 - def create_pane(self, entity, notebook, pane, page=None):
188 if entity.parent:
189 label = '%s %s' % (entity.ancestry(),pane['type'])
190 else:
191 label = pane['type']
192 if pane.has_key('tag'):
193 tab = pane['tag']
194 else:
195 tab = pane['type']
196
197 if page is None:
198 try:
199 page = notebook.add(tab,tab_text='',tab_image=pane['image'])
200 except KeyError:
201 page = notebook.add(tab)
202 if self['balloon']:
203 self['balloon'].bind(self.component('notebook').tab(tab),pane['type'])
204
205 try:
206 frame = self.component(label)
207 except KeyError:
208 frame = self.createcomponent(label,(),'Pane',pane['widget'],(page,),
209 balloon=self['balloon'],
210 entity=entity,
211 society=self['society'],
212 expert=self['expert'],
213 generic=self['abstract'])
214
215 if isinstance(frame,Pmw.ScrolledFrame):
216 frame.configure(horizflex='expand')
217 if pane['type'] == 'General':
218 frame.configure(step=self.stepEntity,policy=self.applyPolicy,
219 valueCmd=self['valueCmd'])
220 elif pane['type'] == 'State':
221 for feature in entity.getStateFeatures():
222 cmd = lambda widget=frame,f=feature:widget.set(f)
223 if entity.parent:
224 self.bstatewidgets[entity.ancestry()+' '+feature] = cmd
225 elif pane['type'] == 'Actions':
226 if not self['abstract']:
227
228 frame.configure(command=self.actEntity)
229 elif pane['type'] == 'Goals':
230 if not self['abstract']:
231 frame.configure(society=None)
232 frame.recreate_goals()
233 elif pane['type'] == 'Policy':
234 if entity.parent:
235 widget = self.component('%s Actions' % (entity.ancestry()))
236 else:
237 widget = self.component('Actions')
238 frame.configure(actions=widget,command=self['policyCmd'])
239 elif pane['type'] == 'Beliefs':
240 frame.configure(window=self.__class__)
241 elif pane['type'] == 'Messages':
242 frame.configure(send=self['msgCmd'])
243 frame.pack(expand='yes',fill='both')
244
253
255 try:
256 frame = self.component('Mental Models')
257 except KeyError:
258 frame = None
259 if frame:
260 frame.recreate_mental()
261
263 self.component('State').update()
264 for key in self.bstatewidgets.keys():
265 apply(self.bstatewidgets[key],())
266
267 - def selectPage(self,page):
268 palette = Pmw.Color.getdefaultpalette(self.interior())
269 widget = self.component('notebook')
270 for name in filter(lambda n:widget.componentgroup(n) == 'Page',
271 widget.components()):
272 if name == page:
273 widget.tab(name).configure(fg=palette['selectForeground'],
274 bg=palette['selectBackground'])
275 else:
276 widget.tab(name).configure(fg=palette['activeForeground'],
277 bg=palette['activeBackground'])
278 if page == 'Actions' and self['abstract']:
279 self.component('Actions_type_entry').focus_set()
280 elif page == 'State' and self['abstract']:
281 self.component('State_new_entry').focus_set()
282 elif page == 'General':
283 try:
284 self.component('General_description_text').focus_set()
285 except KeyError:
286
287 pass
288
289
290
291
292 - def selectBeliefPage(self,page):
293 if page == 'Policy' and len(self.activeBelief.policy.attributes) > 0:
294 widget = self.component('%s Policy' % \
295 (self.activeBelief.ancestry()))
296 widget.displayPolicy()
297
299 """Sets the state of all of the agent editing widgets
300 - NORMAL: enables all of the widgets
301 - DISABLED: disables all of the widgets
302 """
303 for pane in self.panes:
304 if pane['type'] == 'General':
305 try:
306 widget = self.component('%s Run Box' % (self['entity'].ancestry()))
307 widget.configure(Button_state=state)
308 except KeyError:
309 pass
310
311 elif pane['type'] in ['State','Actions','Goals']:
312 try:
313 widget = self.component(pane['type'])
314 widget.setState(state)
315 except KeyError:
316 pass
317 elif pane['type'] == 'Mental Models':
318 if len(self['entity'].getEntities()) > 0:
319 try:
320 widget = self.component('%s Lock Models' % \
321 (self['entity'].ancestry()))
322 except KeyError:
323 continue
324 widget.configure(state=state)
325 for other in self['entity'].getEntityBeliefs():
326 widget = self.component('%s Mental Models' % \
327 (other.ancestry()))
328 if state == DISABLED:
329 widget.disable()
330 elif self['entity'].modelChange:
331 widget.enable()
332
334 """
335 @param old: the current name of the entity
336 @param new: the new name of the entity
337 @type old,new: str
338 """
339 if self.win and self['entity'].name == new:
340 self.win.configure(title=new)
341 self.component('Relationships').renameEntity(old,new)
342 if self.component('Actions_object').get() == old:
343 self.component('Actions_object').selectitem(0)
344 self.update()
345