def threadexited(thread):
if thread.getExitCause() == 'EXCEPTION':
+ if isinstance(thread.getExitException(), SystemExit):
+ # Bring a SystemExit into the main thread.
+ # Do not send it back to UI layer right now.
+ # Maybe later send it to ui.terminate?
+ raise SystemExit
ui.threadException(thread) # Expected to terminate
sys.exit(100) # Just in case...
os._exit(100)
ui.threadExited(thread)
threadutil.initexitnotify()
-t = ExitNotifyThread(target=sync_with_timer, name='sync_with_timer')
+t = ExitNotifyThread(target=sync_with_timer,
+ name='Sync Runner')
t.setDaemon(1)
t.start()
try:
raise
except:
ui.mainException() # Also expected to terminate.
-
-
-
return self.password
class TextOKDialog:
- def __init__(self, title, message):
- self.top = Tk()
+ def __init__(self, title, message, blocking = 1, master = None):
+ if not master:
+ self.top = Tk()
+ else:
+ self.top = Toplevel(master)
self.top.title(title)
self.text = ScrolledText(self.top, font = "Courier 10")
self.text.pack()
self.button = Button(self.top, text = "OK", command=self.ok)
self.button.pack()
- self.top.wait_window(self.button)
+ if blocking:
+ self.top.wait_window(self.button)
def ok(self):
self.top.destroy()
def getthreadextraframe(self):
if self.threadextraframe:
return self.threadextraframe
- self.threadextraframe = Frame()
+ self.threadextraframe = Frame(self)
self.threadextraframe.pack(fill = 'x')
+ return self.threadextraframe
def setaccount(self, account):
self.account = account
name = "Tk idle vacuum")
t.setDaemon(1)
t.start()
- print "TkUI mainloop started."
def runmainloop(s):
s.top.mainloop()
def threadExited(s, thread):
threadid = thread.threadid
- print "Thread %d exited" % threadid
s.tflock.acquire()
if threadid in s.threadframes:
- print "Removing thread %d" % threadid
tf = s.threadframes[threadid]
tf.setthread(None)
tf.setaccount("Unknown")
print msg
s.top.destroy()
+ s.top = None
TextOKDialog("Thread Exception", msg)
s.terminate(100)
print msg
s.top.destroy()
+ s.top = None
TextOKDialog("Main Program Exception", msg)
+ def init_banner(s):
+ s._msg(version.productname + " " + version.versionstr + ", " +\
+ version.copyright)
+ tf = s.gettf().getthreadextraframe()
+
+ def showlicense():
+ TextOKDialog(version.productname + " License",
+ version.bigcopyright + "\n" +
+ version.homepage + "\n\n" + version.license,
+ blocking = 0, master = tf)
+ b = Button(tf, text = "About", command = showlicense)
+ b.pack(side = LEFT)
+
+ b = Button(tf, text = "Exit", command = s.terminate)
+ b.pack(side = RIGHT)
+
def deletingmessages(s, uidlist, destlist):
ds = s.folderlist(destlist)
s._msg("Deleting %d messages in %s" % (len(uidlist), ds))
+ def _sleep_cancel(s, args = None):
+ s.sleeping_abort = 1
+
+ def sleep(s, sleepsecs):
+ s.sleeping_abort = 0
+ tf = s.gettf().getthreadextraframe()
+
+ sleepbut = Button(tf, text = 'Sync immediately',
+ command = s._sleep_cancel)
+ sleepbut.pack()
+ UIBase.sleep(s, sleepsecs)
+
+ def sleeping(s, sleepsecs, remainingsecs):
+ if remainingsecs:
+ s._msg("Next sync in %d:%02d" % (remainingsecs / 60,
+ remainingsecs % 60))
+ else:
+ s._msg("Wait done; synchronizing now.")
+ s.gettf().destroythreadextraframe()
+ time.sleep(sleepsecs)
+ return s.sleeping_abort
+
################################################## Copied from TTY
def syncingmessages(s, sr, sf, dr, df):
author = "John Goerzen"
author_email = "jgoerzen@complete.org"
description = "Disconnected Universal IMAP Mail Synchronization/Reader Support"
+bigcopyright = "%(productname)s %(versionstr)s, %(copyright)s <%(author_email)s>" % locals()
-banner = """%(productname)s %(versionstr)s, %(copyright)s <%(author_email)s>
+banner = bigcopyright + """
This software comes with ABSOLUTELY NO WARRANTY; see the file
COPYING for details. This is free software, and you are welcome
-to distribute it under the conditions laid out in COPYING.""" % locals()
+to distribute it under the conditions laid out in COPYING."""
homepage = "http://www.quux.org/devel/offlineimap"
homegopher = "gopher://quux.org/1/devel/offlineimap"