1 import threading
2 from Tkinter import *
3 import Pmw
4 from teamwork.widgets.images import getImage
5
7 """A dialog for editing the ordering of a sequence"""
9 optiondefs = (
10 ('serial',False,Pmw.INITOPT),
11 )
12 self.defineoptions(kw, optiondefs)
13 Pmw.Dialog.__init__(self,parent)
14 if self['serial']:
15 self.createcomponent('editor',(),None,OldTurnEditor,(self.interior(),),
16 vertflex='expand',horizflex='expand')
17 else:
18 self.createcomponent('editor',(),None,TurnEditor,(self.interior(),),
19 vertflex='expand',horizflex='expand')
20 self.component('editor').pack(side='top',fill='both',expand='yes')
21 self.initialiseoptions()
22
25 self.lock = threading.Lock()
26 optiondefs = (
27 ('order',[],self.setOrder),
28 ('elements',[],self.setOrder),
29 ('editable',True,self.setOrder),
30 )
31 self.defineoptions(kw, optiondefs)
32 self.variables = {}
33 Pmw.ScrolledFrame.__init__(self,parent)
34 self.interior().grid_columnconfigure(1,weight=1)
35 self.createcomponent('serial',(),None,Pmw.OptionMenu,(self.interior(),),
36 items=('serial','parallel','mixed'),
37 command=self.serialize).grid(row=0,column=0,
38 sticky='w')
39 Button(self.interior(),text='Preview',command=self.setOrder,
40 justify='center').grid(row=0,column=1,sticky='w')
41
43 """Redraws the control elements based on the new order"""
44 for name in self.components():
45 if self.componentgroup(name) == 'active':
46 if not name[:-7] in self['elements']:
47 self.destroycomponent(name)
48 elif self.componentgroup(name) == 'scale':
49 if not name[:-6] in self['elements']:
50 self.destroycomponent(name)
51 if isinstance(self['order'][0],str):
52
53 self.component('serial').setvalue('serial')
54 elif len(self['order']) == 1:
55
56 self.component('serial').setvalue('parallel')
57 else:
58
59 self.component('serial').setvalue('mixed')
60 inactive = self['elements'][:]
61
62 leftover = {}
63 leftover.update(self.variables)
64
65 row = 2
66 for pos in range(len(self['order'])):
67 names = self['order'][pos]
68 if isinstance(names,str):
69
70 names = [names]
71 for name in names:
72 self.drawControl(name,row,pos,True)
73 row += 1
74 inactive.remove(name)
75 if leftover.has_key(name):
76 del leftover[name]
77
78 for name in inactive:
79 self.drawControl(name,row,len(self['order']),False)
80 row += 1
81 if leftover.has_key(name):
82 del leftover[name]
83
84 for name in leftover.keys():
85 del self.variables[name]
86
88 """Draws the control for an individual agent's position in order
89 @param name: the name of the agent
90 @type name: str
91 @param row: the position of the agent's widget
92 @type row: int
93 @param pos: the turn of the agent in the execution order
94 @type pos: int
95 @param active: if C{True}, the agent gets a turn
96 @type active: bool
97 """
98 try:
99 widget = self.component('%s-active' % (name))
100 except KeyError:
101 self.variables[name] = StringVar()
102 widget = self.createcomponent('%s-active' % (name),(),'active',
103 Checkbutton,(self.interior(),),
104 text=name,variable=self.variables[name],
105 command=lambda n=name,s=self:s.toggle(n))
106 widget.grid(row=row,column=0,sticky='w')
107
108 if self.lock.acquire(0):
109 if active:
110 widget.select()
111 else:
112 widget.deselect()
113 self.lock.release()
114
115 try:
116 widget = self.component('%s-scale' % (name))
117 except KeyError:
118 widget = self.createcomponent('%s-scale' % (name),(),'scale',
119 Scale,(self.interior(),),
120 command=lambda v,n=name,s=self:
121 s.update(n,v),
122 orient='horizontal',from_=1,
123 to=len(self['elements']))
124
125 if self.lock.acquire(0):
126 widget.set(pos+1)
127 self.lock.release()
128 widget.grid(row=row,column=1,sticky='ew')
129
131 """Slider callback
132 """
133 if self.lock.acquire(0):
134 new = int(new)
135 serial = self.component('serial').getvalue()
136 active = int(self.variables[name].get())
137 if serial == 'serial':
138 if active and new > len(self['order']):
139
140 self['order'].append(name)
141 if len(self['order']) != new:
142
143 self.component('%s-scale' % (name)).set(len(self['order']))
144 elif active and self['order'][new-1] != name:
145
146 old = self['order'].index(name)+1
147 other = self['order'][new-1]
148 self['order'][old-1] = other
149 self['order'][new-1] = name
150 self.component('%s-scale' % (other)).set(old)
151 elif serial == 'mixed':
152 for names in self['order']:
153 try:
154 names.remove(name)
155 break
156 except ValueError:
157 pass
158 if int(self.variables[name].get()):
159
160 self['order'][new-1].append(name)
161 self.lock.release()
162
164 """Activation checkbutton callback
165 """
166 widget = self.component('%s-scale' % (name))
167 position = int(widget.get())
168 serial = self.component('serial').getvalue()
169 active = int(self.variables[name].get())
170 if active:
171
172 widget.configure(state='normal')
173 self.update(name,position)
174 elif serial == 'serial':
175
176 widget.set(len(self['order']))
177 assert self['order'][position-1] == name
178 del self['order'][position-1]
179 widget.configure(state='disabled')
180 else:
181
182 self['order'][position-1].remove(name)
183
185 if serial == 'serial':
186 if isinstance(self['order'][0],list):
187
188 new = []
189 for index in range(len(self['order'])):
190 names = self['order'][0]
191 del self['order'][0]
192 for name in names:
193 if int(self.variables[name].get()):
194 self['order'].append(name)
195 self.setOrder()
196 elif serial == 'parallel':
197 if isinstance(self['order'][0],str):
198 self['order'][0] = self['order'][:]
199 else:
200 self['order'][0] += sum(self['order'][1:],[])
201 del self['order'][1:]
202 self.setOrder()
203 else:
204 if isinstance(self['order'],str):
205
206 for index in range(len(self['order'])):
207 self['order'][index] = [self['order'][index]]
208
211 optiondefs = (
212 ('order',[],self.setOrder),
213 ('elements',[],self.setElements),
214 ('editable',True,self.setEditable),
215 )
216 self.defineoptions(kw, optiondefs)
217 Pmw.ScrolledFrame.__init__(self,parent)
218 self.up = PhotoImage(file=getImage('up.gif'))
219 self.down = PhotoImage(file=getImage('down.gif'))
220 self.createcomponent('active',(),None,Pmw.Group,(self.interior(),),
221 tag_text='Active')
222 self.component('active').interior().grid_columnconfigure(1,weight=1)
223 self.createcomponent('inactive',(),None,Pmw.Group,(self.interior(),),
224 tag_text='Inactive').pack(side='top',fill='both',
225 expand='yes')
226 self.component('inactive').interior().grid_columnconfigure(1,weight=1)
227 self.initialiseoptions()
228
230 """Redraws the control elements based on the new order"""
231
232 for name in self.components():
233 if self.componentgroup(name) == 'active':
234 self.destroycomponent(name)
235 frame = self.component('active')
236
237 for index in range(len(self['order'])):
238 self.drawControl(index,self['order'][index],True)
239 if len(self['order']) > 0:
240 frame.pack(side='top',fill='both',expand='yes',
241 before=self.component('inactive'))
242
244 """Redraws the control elements for the inactive elements"""
245
246 for name in self.components():
247 if self.componentgroup(name) == 'inactive':
248 self.destroycomponent(name)
249 frame = self.component('inactive')
250 index = len(self['order'])
251 for element in self['elements']:
252 if not element in self['order']:
253 self.drawControl(index,element,False)
254 index += 1
255
257 """Draws a new text box with up/down arrows
258 @param index: the row in which to create this widget
259 @type index: int
260 @param label: the text label for this element
261 @type label: str
262 @param active: C{True} iff this element is currently active
263 @type active: bool
264 """
265 if active:
266 group = 'active'
267 offset = 0
268 else:
269 group = 'inactive'
270 offset = len(self['order'])
271 w = self.createcomponent('up%d' % (index),(),group,Button,
272 (self.component(group).interior(),),
273 image=self.up,
274 command=lambda i=index:\
275 self.moveUp(i),
276 )
277 if index == 0 and active:
278 w.configure(state='disabled')
279 w.grid(row=index-offset,column=0)
280 w = self.createcomponent('name%d' % (index),(),group,Label,
281 (self.component(group).interior(),),
282 text=label,bd=1,relief='raised',
283 )
284 w.grid(row=index-offset,column=1,sticky='ewns')
285 w = self.createcomponent('down%d' % (index),(),group,Button,
286 (self.component(group).interior(),),
287 image=self.down,
288 command=lambda i=index:\
289 self.moveDown(i),
290 )
291 if index == len(self['elements']) - 1 and not active:
292 w.configure(state='disabled')
293 w.grid(row=index-offset,column=2)
294
296 """En/disables the order modification buttons, as appropriate"""
297 if self['editable']:
298 state = 'normal'
299 else:
300 state = 'disabled'
301 for index in range(len(self['order'])):
302 if index > 0:
303 w = self.component('up%d' % (index))
304 w.configure(state=state)
305 if index < len(self['elements'])-1:
306 w = self.component('down%d' % (index))
307 w.configure(state=state)
308
310 """Moves the identified element up in the order"""
311 if index < len(self['order']):
312 old = self['order'][index-1]
313 new = self['order'][index]
314 self.component('name%d' % (index)).configure(text=old)
315 self.component('name%d' % (index-1)).configure(text=new)
316 self['order'][index] = old
317 self['order'][index-1] = new
318 elif index > len(self['order']):
319 old = self.component('name%d' % (index-1)).cget('text')
320 new = self.component('name%d' % (index)).cget('text')
321 self.component('name%d' % (index)).configure(text=old)
322 self.component('name%d' % (index-1)).configure(text=new)
323 else:
324
325 name = self.component('name%d' % (index)).cget('text')
326 self['order'].append(name)
327 self.setElements()
328 self.drawControl(index,name,True)
329
331 """Moves the identified element down in the order"""
332 if index < len(self['order']) - 1:
333 old = self['order'][index+1]
334 new = self['order'][index]
335 self.component('name%d' % (index)).configure(text=old)
336 self.component('name%d' % (index+1)).configure(text=new)
337 self['order'][index] = old
338 self['order'][index+1] = new
339 elif index >= len(self['order']):
340 old = self.component('name%d' % (index+1)).cget('text')
341 new = self.component('name%d' % (index)).cget('text')
342 self.component('name%d' % (index)).configure(text=old)
343 self.component('name%d' % (index+1)).configure(text=new)
344 else:
345
346 name = self.component('name%d' % (index)).cget('text')
347 self['order'].pop()
348 for label in ['up','name','down']:
349 self.destroycomponent('%s%d' % (label,index))
350 self.setElements()
351
353 Pmw.Dialog.deactivate(self,result)
354
355 for name in self.components():
356 if self.componentgroup(name) in ['active','inactive']:
357 self.destroycomponent(name)
358