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

Source Code for Module teamwork.widgets.PsychGUI.ScenarioWizard

  1  import copy 
  2  import os.path 
  3  import Pmw 
  4  from Queue import Queue,Empty 
  5  import string 
  6  from threading import * 
  7  from time import strftime,localtime,sleep 
  8  from Tkinter import * 
  9  from tkFileDialog import askopenfilename 
 10   
 11  from teamwork.agent.lightweight import PWLAgent 
 12  from teamwork.agent.Entities import PsychEntity 
 13  from teamwork.agent.AgentClasses import getEntityClassList 
 14  from teamwork.multiagent.pwlSimulation import PWLSimulation 
 15  from teamwork.policy.policyTable import PolicyTable 
 16  from teamwork.widgets.WizardShell import WizardShell 
 17  from teamwork.widgets.ProgressBar import ProgressBar 
 18  from teamwork.widgets.images import getImageDirectory,getImage 
 19  from objectives import ObjectivesDialog 
 20   
21 -class ScenarioWizard(WizardShell):
22 """Setup wizard dialog widget""" 23 frameWidth = 700 24 frameHeight = 600 25 defaultImage = getImage('nobody.gif') 26
27 - def __init__(self, shell, parent=None, **kw):
28 optiondefs = ( 29 ('doActions',False,Pmw.INITOPT), 30 ('doObjectives',False,Pmw.INITOPT), 31 ('society',{},Pmw.INITOPT), 32 ('leavesOnly',False,Pmw.INITOPT), 33 ('balloon',None,Pmw.INITOPT), 34 ('expert',False,Pmw.INITOPT), 35 ('command',None,Pmw.INITOPT), 36 ('agentClass',PsychEntity,None), 37 ('scenario',None,Pmw.INITOPT), 38 ('beta',False,Pmw.INITOPT), 39 ) 40 self.defineoptions(kw, optiondefs) 41 self.scenario = None 42 if len(self['society']) == 1: 43 # If there's only one thing, then we'd better show it 44 self.leaves = self['society'].keys() 45 elif self['leavesOnly']: 46 # Show only leaf classes 47 self.leaves = self['society'].leaves() 48 else: 49 # Show any non-root classes 50 leaves = filter(lambda e:len(e.getParents())>0, 51 self['society'].members()) 52 self.leaves = map(lambda e:e.name,leaves) 53 self.leaves.sort(lambda x,y:cmp(x.lower(),y.lower())) 54 self.entities = {} 55 self.selected = {} 56 self.panes = len(self.leaves) + 2 # population, All done! 57 if self['doObjectives']: 58 self.panes += 1 59 try: 60 self.nobody = PhotoImage(file=self.defaultImage) 61 except: 62 self.nobody = None 63 self.toImport = False 64 self.thread = None 65 WizardShell.__init__(self,parent)
66
67 - def createButtons(self):
68 self.cancel = self.buttonAdd('Cancel', command=self.done, state=1) 69 self.nextB = self.buttonAdd('Next', command=self.next, state=1) 70 self.nextB.configure(default=ACTIVE) 71 self.prevB = self.buttonAdd('Prev', command=self.prev, state=0)
72
73 - def createInterface(self):
74 WizardShell.createInterface(self) 75 self.createButtons() 76 self.createMain()
77
78 - def createMain(self):
79 self.createPopulation(0) 80 for index in range(len(self.leaves)): 81 self.createClassPane(1+index,self.leaves[index]) 82 self.createFinish(len(self.leaves)+1)
83
84 - def createPopulation(self,pane):
85 frame = Pmw.ScrolledFrame(self.pInterior(pane),) 86 87 self.counters = {} 88 for leaf in self.leaves: 89 self.counters[leaf] = self.__createCounter(frame.interior(), 90 leaf,0,leaf) 91 Pmw.alignlabels(self.counters.values()) 92 frame.grid(row=0,column=0,sticky='ewns') 93 self.pInterior(pane).rowconfigure(0,weight=1) 94 if self['scenario']: 95 widget = Button(self.pInterior(pane),command=self.editScenario, 96 text='Import Current Scenario and Edit') 97 if self['balloon']: 98 self['balloon'].bind(widget,'Use the current scenario\'s settings for the initial settings in this wizard.') 99 widget.grid(row=1,column=0,sticky='ew') 100 widget = Button(self.pInterior(pane),command=self.useScenario, 101 text='Import Current Scenario and Finish') 102 if self['balloon']: 103 self['balloon'].bind(widget,'Use the current scenario\'s settings without any changes.') 104 widget.grid(row=2,column=0,sticky='ew')
105
106 - def createFinish(self,pane):
107 # Create progress message and bar 108 group = Pmw.Group(self.pInterior(pane),tag_text='Progress') 109 group.grid(row=0,column=1,sticky='ewns') 110 self.pInterior(pane).rowconfigure(0,weight=1) 111 msg = 'All done! Click "Finish" to instantiate scenario.' 112 self.createcomponent('FinishLabel',(),None, 113 Label,(group.interior(),), 114 text=msg).pack(side=TOP,fill=BOTH,expand=YES) 115 self.progressBar = ProgressBar(master=group.interior(), 116 labelText='Progress:', 117 value=0,width=300, 118 background=None, 119 labelColor="black", 120 fillColor="darkgray", 121 ) 122 self.progressBar.frame.pack_forget() 123 # Set up option for compiling dynamics and policies 124 self.compileFlag = IntVar() 125 self.compileFlag.set(1) 126 self.distillFlag = IntVar() 127 self.distillFlag.set(0) 128 self.level = StringVar() 129 group = Pmw.Group(self.pInterior(pane),tag_text='Options') 130 self.createcomponent('Distill',(),None, 131 Checkbutton,(group.interior(),), 132 text='Create lightweight agents', 133 variable=self.distillFlag, 134 ) 135 self.createcomponent('Compile Dynamics',(),None, 136 Checkbutton,(group.interior(),), 137 text='Compile dynamics', 138 variable=self.compileFlag, 139 ) 140 self.createcomponent('Compile Policies',(),None, 141 Pmw.OptionMenu,(group.interior(),), 142 labelpos='w', 143 label_text='Compile policies for:', 144 menubutton_textvariable=self.level, 145 ) 146 if self['beta']: 147 self.component('Distill').pack(side=TOP,fill=BOTH,expand=YES) 148 if self['expert']: 149 self.component('Compile Dynamics').pack(side=TOP,fill=BOTH, 150 expand=YES) 151 if self['beta']: 152 self.component('Compile Policies').pack(side=TOP,fill=BOTH, 153 expand=YES) 154 if self['expert']: 155 group.grid(row=1,column=1,sticky='ewns') 156 self.pInterior(pane).rowconfigure(1,weight=1) 157 self.pInterior(pane).columnconfigure(1,weight=1)
158
159 - def editScenario(self):
160 """Shorthand for L{importScenario} with C{finish=False}""" 161 self.importScenario(finish=False)
162
163 - def useScenario(self):
164 """Shorthand for L{importScenario} with C{finish=True}""" 165 self.importScenario(finish=True)
166
167 - def importScenario(self,finish=False):
168 """Fills out everything using what's present in the current scenario 169 @param finish: if C{True}, then jump directly to end without editing any of the current scenario's settings 170 @type finish: bool 171 """ 172 self.toImport = True 173 for leaf in self.leaves: 174 # Reset counters to 0 (gotta be an easier way) 175 while int(self.counters[leaf].get()) > 0: 176 self.counters[leaf].decrement() 177 # Erase any entities already stored 178 try: 179 self.entities[leaf].clear() 180 except KeyError: 181 pass 182 for entity in self['scenario'].members(): 183 # Find out which leaves this entity is in 184 leaves = [] 185 for leaf in self.leaves: 186 if entity.instanceof(leaf): 187 leaves.append(leaf) 188 # Find out the most specific class 189 for leaf in leaves[:]: 190 for className in self['society'][leaf].getParents(): 191 try: 192 leaves.remove(className) 193 except ValueError: 194 pass 195 # There should be only one such bottom-level class 196 assert len(leaves) == 1 197 leaf = leaves[0] 198 # Increment the counter for this entity class 199 self.counters[leaf].increment() 200 # Create a new entity 201 new = self['society'].instantiate(leaf,entity.name, 202 self['agentClass']) 203 # Copy relationships 204 for relation,others in entity.relationships.items(): 205 new.relationships[relation] = others[:] 206 try: 207 self.entities[leaf][entity.name] = new 208 except KeyError: 209 self.entities[leaf] = {entity.name:new} 210 if finish: 211 self.next(self.panes - 1) 212 self.finish()
213
214 - def setPopulation(self):
215 """Extract the number of each entity type selected from pane 0 of the wizard""" 216 self.population = {} 217 for leaf in self.leaves: 218 # Look at the counter of each entity type 219 counter = self.counters[leaf] 220 count = int(counter.get()) 221 self.population[leaf] = count 222 try: 223 while len(self.entities[leaf]) > count: 224 # Too many entities...start deleting 225 key = self.entities[leaf].keys()[-1] 226 del self.entities[leaf][key] 227 except KeyError: 228 # Haven't created any of these entities...start from 229 # scratch 230 self.entities[leaf] = {} 231 while len(self.entities[leaf]) < count: 232 # Not enough entities...start making new ones 233 if count > 1: 234 name = '%s %d' % (leaf,len(self.entities[leaf])+1) 235 else: 236 name = '%s' % (leaf) 237 newEntity = self['society'].instantiate(leaf,name, 238 self['agentClass']) 239 self.entities[leaf][name] = newEntity 240 for leaf in self.leaves: 241 # Set the selection box options for this pane 242 box = self.component('%sEntitySelect' % (leaf)) 243 nameList = self.entities[leaf].keys() 244 nameList.sort() 245 box.setitems(nameList) 246 # Create properties (doesn't work if we haven't set the 247 # population first 248 book = self.component('%sNotebook' % (leaf)) 249 if not self.selected.has_key(leaf): 250 try: 251 self.selectEntity(nameList[0],leaf,None) 252 except IndexError: 253 # No entities of this type 254 pass 255 self.createProps(book,leaf) 256 ## book.pack(fill=BOTH,expand=YES) 257 if self['doObjectives']: 258 # Build objectives dialog if not done already 259 objPaneName = 'ObjectivesPane' 260 try: 261 obj = self.component(objPaneName) 262 except KeyError: 263 eList = map(lambda e:e.values(),self.entities.values()) 264 pane = len(self.leaves)+2 265 obj = self.createcomponent(objPaneName, (),None, 266 ObjectivesDialog, 267 (self.pInterior(pane),), 268 psyopFlag = 0, 269 entities=reduce(lambda x,y:x+y, 270 eList,[])) 271 obj.pack(side=TOP,fill=X,expand=YES) 272 # Update compile option menu 273 count = 0 274 for leaf in self.leaves: 275 if self.population[leaf] > 0: 276 depth = self['society'][leaf].depth 277 if depth > count: 278 count = depth 279 self.levels = ['All agents'] 280 self.levels += map(lambda n:'Agents at belief depth %d and below'\ 281 % (n+1),range(count)) 282 self.levels.append('No agents') 283 self.component('Compile Policies').setitems(self.levels) 284 self.component('Compile Policies').invoke(Pmw.END)
285
286 - def createClassPane(self,pane,className):
287 """Create the pane for the specified index and class""" 288 # Class label 289 self.createcomponent('%sLabel' % (className), (), None, 290 Label, 291 (self.pInterior(pane),), 292 borderwidth=3,relief=RIDGE, 293 font=('helvetica',18,'bold'), 294 text=className).grid(row=0,column=0, 295 sticky='ew') 296 cmd = lambda label,s=self,c=className:s.selectEntity(label,c) 297 # Entity selection menu 298 msg = 'Select which instance of %s you wish to customize:' \ 299 % (className) 300 Label(self.pInterior(pane),text=msg).grid(row=1,column=0,sticky='ew') 301 self.createcomponent('%sEntitySelect' % (className), (), None, 302 Pmw.OptionMenu, 303 (self.pInterior(pane),), 304 labelpos=W,label_text='Entity:', 305 command=cmd).grid(row=2,column=0,sticky='ew') 306 # Encapsulate all of the entity-specific options 307 book = self.createcomponent('%sNotebook' % (className), (), None, 308 Pmw.NoteBook,(self.pInterior(pane),)) 309 # Allow user to change the name of selected entity 310 book.add('Name') 311 widget = self.createcomponent('%sName' % (className), (), None, 312 Pmw.EntryField,(book.page(0),), 313 validate={'validator': 314 self.validateName}, 315 modifiedcommand=self.updateName, 316 labelpos='nw', 317 label_text='Entity name:', 318 ) 319 widget.grid(row=0,column=0,sticky='EW',ipadx=5) 320 # Allow user to select image 321 widget = self.createcomponent('%sImage' % (className), (),None, 322 Button,(book.page(0),), 323 command=lambda s=self,c=className:\ 324 s.selectImage(c), 325 width=100,height=100) 326 widget.grid(row=0,column=1) 327 # Allow user to enter description 328 widget = self.createcomponent('%sDescription' % (className), 329 (), None, Pmw.ScrolledText, 330 (book.page(0),), 331 text_height=5,text_width=40, 332 text_wrap='word', 333 labelpos='nw', 334 label_text='Entity description:', 335 ) 336 widget.grid(row=1,column=0,columnspan=2,sticky='NESW',padx=5) 337 book.page(0).rowconfigure(1,weight=1) 338 book.page(0).columnconfigure(0,weight=1) 339 book.grid(row=3,column=0,sticky='ewns') 340 self.pInterior(pane).rowconfigure(3,weight=1) 341 self.pInterior(pane).columnconfigure(0,weight=1)
342
343 - def selectImage(self,className):
344 """Pops up a dialog to allow user to select image for an entity""" 345 filename = askopenfilename(parent=self.root, 346 initialdir = getImageDirectory()) 347 if filename: 348 try: 349 image = PhotoImage(file=filename) 350 except: 351 image = None 352 if image: 353 widget = self.component('%sImage' % (className)) 354 widget.configure(image=image) 355 entity = self.selected[className] 356 entity.attributes['image'] = image 357 entity.attributes['imageName'] = filename
358
359 - def createProps(self,parent,className):
360 """Creates all the background tabs for specializing an entity""" 361 try: 362 entity = self.entities[className].values()[0] 363 except IndexError: 364 # No entities of this class 365 return 366 generic = self['society'][className] 367 page = 1 368 if self['doActions']: 369 # Add action selection pane 370 if len(generic.actions.getOptions()) > 0: 371 try: 372 parent.add('Actions') 373 menuLabel = '%sActions' % (className) 374 except ValueError: 375 # Page already exists 376 menuLabel = None 377 if menuLabel: 378 menu = self.createcomponent(menuLabel,(),None, 379 Pmw.RadioSelect, 380 (parent.page(page),), 381 buttontype='checkbutton', 382 orient='vertical', 383 ) 384 options = generic.actions.getOptions() 385 options.sort(lambda x,y:cmp(str(x),str(y))) 386 map(lambda n:menu.add(str(n)),options) 387 menu.pack(side='top',fill='both',expand='yes') 388 page += 1 389 # Add relationship fillers 390 relationships = {} 391 for cls in entity.classes: 392 relationships.update(self['society'][cls].relationships) 393 for relation,objClasses in relationships.items(): 394 try: 395 newPage = parent.add(relation) 396 except ValueError: 397 # Page already exists 398 continue 399 menuLabel = '%s%sRelation' % (className,relation) 400 try: 401 menu = self.component(menuLabel) 402 except KeyError: 403 # Haven't created this menu yet...do so now 404 cmd = lambda selected,value,s=self,c=className,r=relation:\ 405 s.updateFiller(c,r,selected,value) 406 frame = Pmw.ScrolledFrame(parent.page(page)) 407 menu = self.createcomponent(menuLabel, (), 408 None, Pmw.RadioSelect, 409 (frame.interior(),), 410 buttontype='checkbutton', 411 command=cmd, 412 orient='vertical') 413 frame.pack(side='top',fill='both',expand='yes') 414 menu.pack(side='top',fill='both',expand='yes') 415 page += 1 416 self.updateRelationships(entity,className)
417
418 - def updateRelationships(self,entity,className):
419 # Add relationship fillers 420 relationships = {} 421 for cls in entity.classes: 422 relationships.update(self['society'][cls].relationships) 423 for relation,objClasses in relationships.items(): 424 # Add all the appropriate entities to the menu 425 objList = [] 426 for classSet in self.entities.values(): 427 for other in classSet.values(): 428 for objClass in objClasses: 429 if other.instanceof(objClass): 430 objList.append(other) 431 menuLabel = '%s%sRelation' % (className,relation) 432 menu = self.component(menuLabel) 433 # Add relevant object entities 434 nameList = map(lambda e:e.name,objList) 435 nameList.sort() 436 # Delete any extraneous buttons 437 toDelete = filter(lambda n:menu.componentgroup(n) == 'Button' \ 438 and not n in nameList,menu.components()) 439 for name in toDelete: 440 # RadioSelect doesn't provide individual deletion! 441 # The following is adapted from source of deletall() 442 menu.destroycomponent(name) 443 menu._buttonList.remove(name) 444 try: 445 menu.selection.remove(name) 446 except ValueError: 447 # Wasn't selected 448 pass 449 for index in range(len(nameList)): 450 name = nameList[index] 451 try: 452 widget = menu.component(name) 453 except KeyError: 454 widget = menu.add(name) 455 widget.grid(row=index) 456 if not entity.relationships.has_key(relation): 457 entity.relationships[relation] = [] 458 others = entity.relationships[relation][:] 459 menu.setvalue(others)
460
461 - def validateName(self,name,**kw):
462 """Validator for name entry field. 463 Ensures that names are not zero length and that all names are 464 unique.""" 465 if self.pCurrent == 0: 466 return Pmw.OK 467 elif len(name) > 0: 468 className = self.leaves[self.pCurrent-1] 469 entity = self.selected[className].name 470 for className in self.leaves: 471 for other in self.entities[className].keys(): 472 if other != entity and name == other: 473 return Pmw.PARTIAL 474 else: 475 return Pmw.OK 476 else: 477 return Pmw.PARTIAL
478
479 - def updateName(self):
480 if self.pCurrent > 0: 481 className = self.leaves[self.pCurrent-1] 482 entity = self.selected[className] 483 self.rename(className,entity.name, 484 self.component('%sName' % (className)).getvalue())
485
486 - def rename(self,className,old,new):
487 entity = self.entities[className][old] 488 entity.setName(new) 489 # Update all refs to this entity's name 490 del self.entities[className][old] 491 self.entities[className][entity.name] = entity 492 # Update any relationships 493 for otherClass in self.leaves: 494 for other in self.entities[otherClass].values(): 495 for relation,objList in other.relationships.items(): 496 try: 497 index = objList.index(old) 498 objList[index] = entity.name 499 except ValueError: 500 pass 501 # Update name in entity selector 502 menu = self.component('%sEntitySelect' % (className)) 503 menu.setitems(self.entities[className].keys(),new) 504 # Update relationship refs in other panes 505 for otherClass in self.leaves: 506 try: 507 other = self.selected[otherClass] 508 except KeyError: 509 continue 510 self.updateRelationships(other,otherClass)
511
512 - def updateFiller(self,className,relation,other,value):
513 """Updates the relationships of the given entity in response to the click of a single button""" 514 entity = self.selected[className] 515 if not entity.relationships.has_key(relation): 516 entity.relationships[relation] = [] 517 if value: 518 assert other not in entity.relationships[relation] 519 entity.relationships[relation].append(other) 520 else: 521 entity.relationships[relation].remove(other)
522
523 - def selectEntity(self,label,className,saveOld=1):
524 """Change the view when a new entity is selected for viewing/editing""" 525 oldName = '' 526 if saveOld: 527 # Save the description 528 entity = self.selected[className] 529 oldName = entity.name 530 widget = self.component('%sDescription' % (className)) 531 entity.description = widget.get() 532 if label != oldName: 533 # Set the widget to display properties for new entity 534 self.selected[className] = self.entities[className][label] 535 entity = self.selected[className] 536 widget = self.component('%sName' % (className)) 537 widget.setvalue(entity.name) 538 widget = self.component('%sDescription' % (className)) 539 widget.settext(entity.description) 540 # Set image 541 widget = self.component('%sImage' % (className)) 542 try: 543 widget.configure(image=entity.attributes['image']) 544 except KeyError: 545 widget.configure(image=self.nobody) 546 # Set relationship values 547 if self.pCurrent > 0: 548 self.updateRelationships(entity,className)
549
550 - def getRelationMenus(self,className):
551 """Returns a dictionary of the available relationship menus""" 552 result = {} 553 try: 554 entity = self.selected[className] 555 except KeyError: 556 return result 557 relationships = {} 558 for cls in entity.classes: 559 relationships.update(self['society'][cls].relationships) 560 for relation in relationships.keys(): 561 if relation[0] == '_': 562 label = relation[1:] 563 else: 564 label = relation 565 try: 566 menu = self.component('%s%sRelation' % (className,label)) 567 except KeyError: 568 # No menu for this relationship, and that's OK 569 continue 570 result[relation] = menu 571 return result
572
573 - def saveProps(self):
574 """Applies any changes made to the currently selected entity""" 575 className = self.leaves[self.pCurrent-1] 576 entity = self.selected[className] 577 self.selectEntity(entity.name,className)
578
579 - def next(self,new=None):
580 """Moves the wizard forward to the next applicable pane""" 581 if self.pCurrent == 0: 582 self.setPopulation() 583 elif self.isClassPane(): 584 # Save results before moving on 585 self.saveProps() 586 done = None 587 cpane = self.pCurrent 588 while not done: 589 if new is None: 590 self.pCurrent = self.pCurrent + 1 591 else: 592 self.pCurrent = new 593 self.prevB['state'] = NORMAL 594 if self.pCurrent == self.panes - 1: 595 self.nextB['text'] = 'Finish' 596 self.nextB['command'] = self.finish 597 if self.isClassPane(): 598 className = self.leaves[self.pCurrent-1] 599 self.component('%sName_entry' % (className)).focus_set() 600 done = self.legalPane() 601 self.pFrame[cpane].forget() 602 self.pFrame[self.pCurrent].pack(fill=BOTH, expand=YES)
603
604 - def prev(self):
605 """Moves the wizard backward to the next applicable pane""" 606 if self.isClassPane(): 607 # Save results before moving on 608 self.saveProps() 609 done = None 610 cpane = self.pCurrent 611 while not done: 612 self.pCurrent = self.pCurrent - 1 613 if self.pCurrent <= 0: 614 self.pCurrent = 0 615 self.prevB['state'] = DISABLED 616 if cpane == self.panes - 1: 617 self.nextB['text'] = 'Next' 618 self.nextB['command'] = self.next 619 done = self.legalPane() 620 self.pFrame[cpane].forget() 621 self.pFrame[self.pCurrent].pack(fill=BOTH, expand=YES)
622
623 - def isClassPane(self,pane=-1):
624 """ 625 @return: True iff the pane (defaults to current) is an entity pane""" 626 if pane < 0: 627 pane = self.pCurrent 628 if pane == 0: 629 return False 630 elif pane > len(self.leaves): 631 return False 632 else: 633 return True
634
635 - def legalPane(self,pane=-1):
636 """Returns true iff the pane (defaults to current) is legal, 637 given the current population breakdown""" 638 if pane < 0: 639 pane = self.pCurrent 640 if self.isClassPane(pane): 641 return len(self.entities[self.leaves[pane-1]]) > 0 642 else: 643 return 1
644
645 - def validateCount(self,count,className):
646 result = Pmw.integervalidator(count) 647 if result == Pmw.OK: 648 count = int(count) 649 if count < 0: 650 return Pmw.ERROR 651 total = 0 652 for other in self.leaves: 653 if other == className: 654 total += count 655 else: 656 try: 657 counter = self.component('Counter%s' % (other)) 658 total += int(counter.getvalue()) 659 except KeyError: 660 pass 661 if total < 1: 662 self.nextB['state'] = DISABLED 663 return Pmw.OK 664 ## return Pmw.PARTIAL 665 else: 666 self.nextB['state'] = NORMAL 667 return Pmw.OK 668 else: 669 return result
670
671 - def __createCounter( self, master, labelText, initialValue, 672 className ):
673 """Creates a counter widget for changing the population""" 674 validator = lambda value,s=self,n=className:s.validateCount(value,n) 675 ## validator = { 'validator':'integer', 676 ## 'min':0, 'max':9 } 677 counter = self.createcomponent('Counter%s' % labelText, (), None, 678 Pmw.Counter,(master,), 679 padx=8, pady=0, 680 labelpos = W, 681 label_text = labelText, 682 entry_width = 3, #Screws Layout 683 entryfield_validate = validator, 684 entryfield_value = initialValue ) 685 # Identify source of this model 686 if className and self['balloon']: 687 str = '' 688 try: 689 source = self['society'][className]['source'] 690 except KeyError: 691 source = None 692 if source: 693 str += 'Created by ' + source['who'] + '\n' 694 str += strftime('%x %X',localtime(source['when'])) 695 try: 696 sourceList = self['society'][className]['validated'] 697 except KeyError: 698 sourceList = [] 699 for source in sourceList: 700 str += '\nValidated by ' + source['who'] + '\n' 701 str += strftime('%x %X',localtime(source['when'])) 702 if len(str) > 0: 703 self['balloon'].bind(counter,str) 704 705 counter.pack( side=TOP, padx=8) 706 return counter
707
708 - def finish(self):
709 self.component('FinishLabel').configure(text='Initializing...') 710 self.prevB['state'] = DISABLED 711 self.nextB['state'] = DISABLED 712 self.cancel['state'] = DISABLED 713 self.component('Compile Dynamics').configure(state='disabled') 714 self.component('Compile Policies').configure(menubutton_state='disabled') 715 self.progressBar.frame.pack(side=TOP) 716 self.progress = Queue() 717 if self['command']: 718 args = {'level': self.levels.index(self.level.get())} 719 eList = map(lambda e:e.values(),self.entities.values()) 720 args['entities'] = reduce(lambda x,y:x+y,eList,[]) 721 if self.distillFlag.get(): 722 args['distill'] = True 723 else: 724 args['distill'] = False 725 if self.compileFlag.get(): 726 args['compile'] = True 727 else: 728 args['compile'] = False 729 self.thread = Thread(target=self.__finish,kwargs=args) 730 self.thread.start() 731 result = True 732 while result is not None: 733 try: 734 result = self.progress.get_nowait() 735 except Empty: 736 result = True 737 if isinstance(result,tuple): 738 msg,inc = result 739 widget = self.component('FinishLabel') 740 widget.configure(text=msg) 741 self.updateProgress(inc) 742 self.mainloop(10) 743 self.update() 744 self.done()
745
746 - def __finish(self,entities,compile,distill,level):
747 self.scenario = self['command'](entities,progress=self.progress, 748 compileDynamics=compile, 749 compilePolicies=level, 750 distill=distill)
751
752 - def progress(self,msg,inc=1):
753 if len(msg) == 0: 754 msg = 'Done.' 755 inc = self.progressBar.max 756 widget = self.component('FinishLabel') 757 widget.configure(text=msg) 758 self.updateProgress(inc)
759
760 - def updateProgress(self,inc):
761 new = self.progressBar.value + inc 762 self.progressBar.updateProgress(new)
763
764 - def done(self):
765 self.quit() 766 self.root.destroy()
767