def removeRulebook(self, rulebook): if isinstance(rulebook, Rulebook): # if rule in editor window is in this rulebook, clear the editor window if self.filename is not None: dir, rule = os.path.split(self.filename) if rulebook.containsRule(rule): if self.rule.textIsDirty: # First give user a chance to save rule msg = "Closing this rulebook will also close the\ncurrently open rule. Save rule first?" dlg = CougaarMessageDialog(self, "close", msg) disposition = dlg.getUserInput() if disposition == wxID_CANCEL: return elif disposition == wxID_YES: self.save_rule() self.clearRule() for rule in rulebook.each_rule(): item = self.lb.FindString(rule) if item >= 0: self.lb.Delete(item) self.ruleBooks.remove(rulebook) removeRulebook = False self.frame.updateCloseRulebookMenuItem(removeRulebook) else: # must be a rulebook name (String) aRulebook = self.getRulebook(rulebook) if aRulebook is not None: self.removeRulebook(aRulebook)
def OnOpenRuleBook(self, event): dlg = wxDirDialog(self, "Choose a RuleBook:", "", style=wxDD_DEFAULT_STYLE | wxDD_NEW_DIR_BUTTON) if dlg.ShowModal() == wxID_OK: ruleBookPath = dlg.GetPath() # check if this rulebook already open for rulebook in self.ruleBooks: if ruleBookPath == rulebook.getPath(): dlg.Destroy() self.log.WriteText("Ignored attempt to open an already opened Rulebook (%s)\n" % rulebook.getName()) return # Must not be already open, so continue ruleBook = Rulebook(ruleBookPath) # Next, if there are no [.rul | .rule] files in the dir, show user a dialog and return. if ruleBook.isEmpty(): emptyRulebookDialog = CougaarMessageDialog(self, "info", "The selected rulebook is empty.") emptyRulebookDialog.display() dlg.Destroy() return # Wasn't empty, so continue self.ruleBooks.append(ruleBook) for rule in ruleBook.each_rule(): self.lb.Append(rule) self.ruleIndex[rule] = ruleBook # links rules to their containing rulebook addRulebook = True self.frame.updateCloseRulebookMenuItem(addRulebook) dlg.Destroy()
def Run(self): #self.log.WriteText( "Thread starting...") print "Thread starting..." soc = None while self.keepGoing: print "transforming>>>" try: soc = self.engine.transform() except Exception, args: print "ERROR transforming the Society" traceback.print_exc() # prints to stderr # We're not sending the following msg to the log file because logging from a thread may be # causing a deadlock (see wxPython bug 496697). #~ wxLogError("Transformation failed.\n") # print to log self.log.WriteText("Transformation failed.\n") self.log.WriteText("%s\n" % str(args)) # format traceback and send to log #~ stackTrace = traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) #~ traceStr = '' #~ for line in stackTrace: #~ traceStr = traceStr + line #~ wxLogError(traceStr) # log the exception and the traceback # Notify user in a dialog box msg = 'ERROR transforming the Society.\nTransformation failed.' errorDialog = CougaarMessageDialog(self._parent, "error", msg) errorDialog.display() evt = UpdateSocietyEvent(soc) wxPostEvent(self._parent, evt) self.keepGoing = False # ?
def OnDeleteRule(self, event): ruleIdToDelete = self.lb.GetSelection() if ruleIdToDelete < 0: self.log.WriteText("Unable to delete rule: no rule selected\n") return ruleNameToDelete = self.lb.GetString(ruleIdToDelete) rulebook = self.ruleIndex[ruleNameToDelete] # get this rule's associated rulebook msg = """Are you sure you want to delete this rule? Doing so will permanently delete it from disk.""" dlg = CougaarMessageDialog(self, "delete", msg) response = dlg.getUserInput() if response == wxID_YES: self.lb.Delete(ruleIdToDelete) # remove it from the list box os.remove(os.path.join(rulebook.getPath(), ruleNameToDelete)) # delete from disk self.clearRule() # clear the rule text self.frame.enableRuleMenuItems(False) rulebook.removeRule(ruleNameToDelete) if rulebook.size() == 0: self.removeRulebook(rulebook)
def OnApplyRules(self, event): self.tempSociety = self.frame.society.clone() # save a copy in case we must restore numRules = self.lb.GetCount() if numRules > 0: checkedRules = [] # will hold a string path/filename for ea rule checked ruleFilename = None for item in range(numRules): if self.lb.IsChecked(item): ruleFilename = self.lb.GetString(item) wx.LogMessage("Applying rule " + str(item) + ": " + ruleFilename + "\n") if self.lb.IsSelected(item) and self.rule.textIsDirty == True: msg = ( "The rule you are applying has been changed. If you wish " + "to apply the changed version, you must first save the rule. " + "Would you like to save the rule now?" ) dlg = wx.MessageDialog( self, msg, style=wx.CAPTION | wx.YES_NO | wx.NO_DEFAULT | wx.THICK_FRAME | wx.ICON_EXCLAMATION, ) val = dlg.ShowModal() if val == wx.ID_YES: self.SaveRule() rulebook = self.ruleIndex[ruleFilename] # get this rule's associated rulebook checkedRules.append(os.path.join(rulebook.getPath(), ruleFilename)) msg = "" if len(checkedRules) > 0: self.frame.ruleApplied = True # All rules are now python rules # Create one SocietyTransformServer instance and pass it a list of rules to execute self.transformServer = SocietyTransformServer(self.frame.society, checkedRules, self, self.log) self.transformServer.Start() # ~ self.StartAnimation() self.log.WriteText("Transformation complete.\n") self.undoTransformButton.Enable(True) msg = "Transformation complete.\n" + msg doneDialog = CougaarMessageDialog(self, "info", msg) doneDialog.display()
def OnApplyRules(self, event): self.tempSociety = self.frame.society.clone() # save a copy in case we must restore numRules = self.lb.GetCount() if numRules > 0: checkedRules = [] # will hold a string path/filename for ea rule checked ruleFilename = None for item in range(numRules): if self.lb.IsChecked(item): ruleFilename = self.lb.GetString(item) wxLogMessage("Applying rule " + str(item) + ": " + ruleFilename + "\n") if self.lb.Selected(item) and self.rule.textIsDirty == True: msg = ( "The rule you are applying has been changed. If you wish " + "to apply the changed version, you must first save the rule. " + "Would you like to save the rule now?" ) dlg = wxMessageDialog( self, msg, style=wxCAPTION | wxYES_NO | wxNO_DEFAULT | wxTHICK_FRAME | wxICON_EXCLAMATION ) val = dlg.ShowModal() if val == wxID_YES: self.SaveRule() rulebook = self.ruleIndex[ruleFilename] # get this rule's associated rulebook checkedRules.append(os.path.join(rulebook.getPath(), ruleFilename)) if len(checkedRules) > 0: self.frame.ruleApplied = True if ruleFilename.endswith("rule"): # just sample the last rule checked # They're Ruby rules rubyArgs = "ruby ruleEngine/acme_scripting/src/lib/cougaar/py_society_builder.rb " rubyArgs = rubyArgs + " ".join(checkedRules) self.log.WriteText(rubyArgs) self.log.WriteText("Transformation in progress...please wait\n") # Call a Ruby program that receives the society (in Ruby code) as a string from Python, # creates a Ruby society object, transforms that society per rules passed as args, # then outputs it back to Python as a string of xml-formatted text input, output = os.popen2(rubyArgs) input.write(self.frame.society.to_ruby()) # sends society as Ruby code to Ruby input.close() xmlSocietyList = output.readlines() # transformed society as a list of XML strings from Ruby output.close() # Check if Ruby threw an exception during transformation # also catch any runy warnings... potentialWarnings = [] errOrWarn = 0 msg = "" while xmlSocietyList[0].lower().find("<?xml version='1.0'?>") == -1: potentialWarnings.append(xmlSocietyList[0]) xmlSocietyList.remove(xmlSocietyList[0]) errOrWarn = 1 if potentialWarnings: msg = join(potentialWarnings, "\n") if xmlSocietyList[0].lower().find("error") >= 0: self.log.WriteText("Transformation failed.\n") msg += "ERROR parsing XML document.\nSociety creation/transformation failed." errOrWarn += 2 if errOrWarn > 2: wxLogError(msg) errorDialog = CougaarMessageDialog(self.frame, "error", msg) errorDialog.display() return else: # codeObj = "".join(codeObjList) # for use when output from Ruby program is Python code # exec codeObj # for use when output from Ruby program is Python code xmlSociety = "".join( xmlSocietyList ) # join list elements into a single string; for use when output from Ruby program is XML # Now parse the xml string and create the new, transformed society self.frame.server = SocietyFactoryServer(None, self, self.log, xmlSociety) self.frame.server.Start() # NOTE: The animation doesn't work while the Ruby process is executing. I presume it's # because the animation is a thread of the Python process, and while the Ruby process # is executing, the Python process is blocked waiting for output from Ruby. I'm guessing that # as long as the Python process is blocked, all its threads are also blocked. However, I've # noticed that once the Ruby process completes, many, many gizmo events arrive all at once. # So it may be that the animation thread continues to run, but its events are not handled till # after the Ruby process completes. else: # They're Python rules, so... # Create one SocietyTransformServer instance and pass it a list of rules to execute self.transformServer = SocietyTransformServer(self.frame.society, checkedRules, self, self.log) self.transformServer.Start() # ~ self.StartAnimation() self.log.WriteText("Transformation complete.\n") self.undoTransformButton.Enable(True) msg = "Transformation complete.\n" + msg doneDialog = CougaarMessageDialog(self, "info", msg) doneDialog.display()
def closeSociety(self, societyId): societyToClose = None currentViewer = None saveAgents = True if societyId != "agentSociety": if societyId == "mappedSociety": societyToClose = self.mappedSociety currentViewer = self.laydownViewer elif societyId == "society": societyToClose = self.society currentViewer = self.societyViewer saveAgents = False if societyToClose.isDirty: # First give user a chance to save the society dlg = CougaarMessageDialog(self, "confirm") disposition = dlg.getUserInput() if disposition == wxID_CANCEL: return if disposition == wxID_YES: self.saveSociety(societyId) # Now delete the tree display currentViewer.DeleteAllItems() # Finally, delete the society object in memory if societyToClose is not None: # shouldn't ever be None...but it sometimes is! societyToClose.close(saveAgents) societyToClose = None if societyId == "mappedSociety": self.mappedSociety = None self.mappedSocietyOpen = 0 self.societyHnaFile = None self.enableHnaSaveMenuItems(false) if not self.agentSocietyOpen: self.editMenu.Enable(AWB.SORT, false) elif societyId == "society": self.society = None self.societyOpen = 0 self.societyFile = None self.ruleEditor.societyName.SetValue("") self.nameServer = None self.enableSocietySaveMenuItems(false) if not self.mappedSocietyOpen: self.editMenu.Enable(AWB.SORT, false) elif societyId == "controller": print "Controller File" else: # societyId == "agentSociety" if self.agentViewer is not None: self.agentViewer.DeleteAllItems() # delete the tree if self.agentSociety is not None: # shouldn't ever be None...but it sometimes is! # Delete the society object in memory self.agentSociety.close() self.agentSociety = None self.agentSocietyOpen = 0 self.agentSocietyFile = None if len(self.undoBuffer) > 0: self.undoBuffer.pop() # empty it out self.mainmenu.Enable(AWB.UNDO, false) self.enableAgentSocietySaveMenuItems(false) if not self.mappedSocietyOpen: self.editMenu.Enable(AWB.SORT, false)
def displayDupeMessage(self, entityType, dupeName): msg = "Duplicate " + entityType + " found: " + dupeName dlg = CougaarMessageDialog(self, "error", msg) dlg.display()