def ready(self): # See comments in __call__. if not self.insertedLines: pl = self.logrunner.getLine(self.lineno - 1) # previous line return (not pl or pl.status == "done" or (pl.status == "running" and pl.runLevel < logutils.run_level())) for line in self.insertedLines: if not (line.status == "done" or line.status == "running" and line.runLevel < logutils.run_level()): return False return True
def ready(self): # See comments in __call__. if not self.insertedLines: pl = self.logrunner.getLine(self.lineno-1) # previous line return (not pl or pl.status == "done" or (pl.status == "running" and pl.runLevel < logutils.run_level())) for line in self.insertedLines: if not (line.status == "done" or line.status == "running" and line.runLevel < logutils.run_level()): return False return True
def ready(self): # Overrides PerformLine.ready() return logutils.run_level() <= self.ppl.runlevel
def __init__(self, logrunner, srcline, lineno, line): GUILogLineRunner.__init__(self, logrunner, srcline, lineno) self.line = line self.runlevel = logutils.run_level()
def __call__(self): # Execute our line of the gui log, *if* the previous line has # completed. Figuring out if the previous line has completed # is non-trivial, because the previous line may have emitted a # gtk signal that caused a modal dialog box to open, in which # case its "emit" call won't return until the box has closed! # *This* line contains the commands that operate the dialog # box, and must be issued even though the previous command # hasn't returned. If the previous line hasn't returned it # must have called Dialog.run or started up a new gtk main # loop, so by keeping track of gtk.main_level() and the number # of open dialogs, we can tell when it's time to execute our # line. (This is why we must redefine the Dialog class.) if self.logrunner.aborted: # The previous line raised an exception, so don't run this # line, even though it's already been installed as an idle # callback. self.status = "aborted" return False # Run this line, but only if there are no postponed lines # ready to go, and if this line is also ready. if not self.run_postponed() and self.ready(): assert self.status in ("repeating", "installed") # Add the idle callback for the next line *before* # executing our line, because we might not return # until after the next line is done! This is why we # need a separate idle callback for each line. if self.status != "repeating" and self.nextLine() is not None: self.nextLine().start() if _threaded: gtk.gdk.threads_enter() try: if self.status == "installed": self.status = "running" self.report() self.runLevel = logutils.run_level() # self.playback performs some suitable action and # returns True if the idle callback should be # repeated, and False if it shouldn't. It can also # reinstall the callback, and should set self.status # to "done" if the task is finished. try: result = self.playback() if self.nextLine() is None: self.logrunner.stop() return result except logutils.GtkLoggerTopFailure: # It's possible that the previous log line tried # to open a window, but the window hasn't actually # appeared yet. In that case, our line will have # failed with a GtkLoggerTopFailure exception. We # just want to keep trying (within reason) until # the window appears. Using checkpoints to wait # until the window is mapped makes this problem # less frequent, but doesn't make it go away # entirely. self.status = "repeating" self.ntries += 1 if self.ntries == maxtries: if logutils.debugLevel() >= 1: print >> sys.stderr, \ "Failed to find top-level widget after", \ self.ntries, "attempts." raise # Keep trying. By reinstalling ourself in the # idle callback table and returning False # (meaning, "don't repeat this callback") we move # to the back of the queue. This allows the # widget we are waiting for to appear, we hope. gobject.timeout_add(retrydelay, self, priority=gobject.PRIORITY_LOW) return False except logutils.exceptions(), exc: # Any type of exception other than GtkLoggerTopFailure # is fatal. self.status = "aborted" self.logrunner.abort() if self.logrunner.exceptHook: if not self.logrunner.exceptHook(exc, self.srcline): raise exc finally: gtk.gdk.flush() if _threaded: gtk.gdk.threads_leave() # We're still waiting for the previous line to execute. We put # ourself at the back of the execution queue (by reinstalling # and returning False) so that the previous line will run # first. if logutils.debugLevel() >= 4: print >> sys.stderr, "Reinstalling", self.srcline gobject.timeout_add(retrydelay, self, priority=gobject.PRIORITY_LOW) return False