def __init__(self, prefs=None, display=None): self.root = Tk(className='Grail', screenName=display) self.root.withdraw() resources = os.path.join(script_dir, "data", "Grail.ad") if os.path.isfile(resources): self.root.option_readfile(resources, "startupFile") BaseApplication.BaseApplication.__init__(self, prefs) # The stylesheet must be initted before any Viewers, so it # registers its' prefs callbacks first, hence reloads before the # viewers reconfigure w.r.t. the new styles. self.stylesheet = Stylesheet.Stylesheet(self.prefs) self.load_images = 1 # Overridden by cmd line or pref. # socket management sockets = self.prefs.GetInt('sockets', 'number') self.sq = SocketQueue(sockets) self.prefs.AddGroupCallback('sockets', lambda self=self: \ self.sq.change_max( self.prefs.GetInt('sockets', 'number'))) # initialize on_exit_methods before global_history self.on_exit_methods = [] self.global_history = GlobalHistory.GlobalHistory(self) self.login_cache = {} self.rexec_cache = {} self.url_cache = CacheManager(self) self.image_cache = ImageCache(self.url_cache) self.auth = AuthenticationManager(self) self.root.report_callback_exception = self.report_callback_exception if sys.stdin.isatty(): # only useful if stdin might generate KeyboardInterrupt self.keep_alive() self.browsers = [] self.iostatuspanel = None self.in_exception_dialog = None from ancillary import Greek for k, v in Greek.entitydefs.items(): Application.dingbatimages[k] = (v, '_sym') self.root.bind_class("Text", "<Alt-Left>", self.dummy_event) self.root.bind_class("Text", "<Alt-Right>", self.dummy_event)
def __init__(self, prefs=None, display=None): self.root = Tk(className='Grail', screenName=display) self.root.withdraw() resources = os.path.join(script_dir, "data", "Grail.ad") if os.path.isfile(resources): self.root.option_readfile(resources, "startupFile") BaseApplication.BaseApplication.__init__(self, prefs) # The stylesheet must be initted before any Viewers, so it # registers its' prefs callbacks first, hence reloads before the # viewers reconfigure w.r.t. the new styles. self.stylesheet = Stylesheet.Stylesheet(self.prefs) self.load_images = 1 # Overridden by cmd line or pref. # socket management sockets = self.prefs.GetInt('sockets', 'number') self.sq = SocketQueue(sockets) self.prefs.AddGroupCallback('sockets', lambda self=self: \ self.sq.change_max( self.prefs.GetInt('sockets', 'number'))) # initialize on_exit_methods before global_history self.on_exit_methods = [] self.global_history = GlobalHistory.GlobalHistory(self) self.login_cache = {} self.rexec_cache = {} self.url_cache = CacheManager(self) self.image_cache = ImageCache(self.url_cache) self.auth = AuthenticationManager(self) self.root.report_callback_exception = self.report_callback_exception if sys.stdin.isatty(): # only useful if stdin might generate KeyboardInterrupt self.keep_alive() self.browsers = [] self.iostatuspanel = None self.in_exception_dialog = None import Greek for k, v in Greek.entitydefs.items(): Application.dingbatimages[k] = (v, '_sym') self.root.bind_class("Text", "<Alt-Left>", self.dummy_event) self.root.bind_class("Text", "<Alt-Right>", self.dummy_event)
class Application(BaseApplication.BaseApplication): """The application class represents a group of browser windows.""" def __init__(self, prefs=None, display=None): self.root = Tk(className='Grail', screenName=display) self.root.withdraw() resources = os.path.join(script_dir, "data", "Grail.ad") if os.path.isfile(resources): self.root.option_readfile(resources, "startupFile") BaseApplication.BaseApplication.__init__(self, prefs) # The stylesheet must be initted before any Viewers, so it # registers its' prefs callbacks first, hence reloads before the # viewers reconfigure w.r.t. the new styles. self.stylesheet = Stylesheet.Stylesheet(self.prefs) self.load_images = 1 # Overridden by cmd line or pref. # socket management sockets = self.prefs.GetInt('sockets', 'number') self.sq = SocketQueue(sockets) self.prefs.AddGroupCallback('sockets', lambda self=self: \ self.sq.change_max( self.prefs.GetInt('sockets', 'number'))) # initialize on_exit_methods before global_history self.on_exit_methods = [] self.global_history = GlobalHistory.GlobalHistory(self) self.login_cache = {} self.rexec_cache = {} self.url_cache = CacheManager(self) self.image_cache = ImageCache(self.url_cache) self.auth = AuthenticationManager(self) self.root.report_callback_exception = self.report_callback_exception if sys.stdin.isatty(): # only useful if stdin might generate KeyboardInterrupt self.keep_alive() self.browsers = [] self.iostatuspanel = None self.in_exception_dialog = None from ancillary import Greek for k, v in Greek.entitydefs.items(): Application.dingbatimages[k] = (v, '_sym') self.root.bind_class("Text", "<Alt-Left>", self.dummy_event) self.root.bind_class("Text", "<Alt-Right>", self.dummy_event) def dummy_event(self, event): pass def register_on_exit(self, method): self.on_exit_methods.append(method) def unregister_on_exit(self, method): try: self.on_exit_methods.remove(method) except ValueError: pass def exit_notification(self): for m in self.on_exit_methods[:]: try: m() except: pass def add_browser(self, browser): self.browsers.append(browser) def del_browser(self, browser): try: self.browsers.remove(browser) except ValueError: pass def quit(self): self.root.quit() def open_io_status_panel(self): if not self.iostatuspanel: from ancillary import IOStatusPanel self.iostatuspanel = IOStatusPanel.IOStatusPanel(self) else: self.iostatuspanel.reopen() def maybe_quit(self): if not (self.embedded or self.browsers): self.quit() def go(self): try: try: if ilu_tk: ilu_tk.RunMainLoop() else: self.root.mainloop() except KeyboardInterrupt: pass finally: self.exit_notification() def keep_alive(self): # Exercise the Python interpreter regularly so keyboard # interrupts get through self.root.tk.createtimerhandler(KEEPALIVE_TIMER, self.keep_alive) def get_cached_image(self, url): return self.image_cache.get_image(url) def set_cached_image(self, url, image, owner=None): self.image_cache.set_image(url, image, owner) def open_url(self, url, method, params, reload=0, data=None): api = self.url_cache.open(url, method, params, reload, data=data) api._url_ = url return api def open_url_simple(self, url): api = self.open_url(url, 'GET', {}) errcode, errmsg, meta = api.getmeta() if errcode != 200: raise IOError(('url open error', errcode, errmsg, meta)) return URLReadWrapper(api, meta) def get_cache_keys(self): """For applets.""" return self.url_cache.items.keys() def decode_pipeline(self, fp, content_encoding, error=1): if self.decode_prog.has_key(content_encoding): prog = self.decode_prog[content_encoding] if not prog: return fp tfn = tempfile.mktemp() ok = 0 try: temp = open(tfn, 'w') BUFSIZE = 8192 while 1: buf = fp.read(BUFSIZE) if not buf: break temp.write(buf) temp.close() ok = 1 finally: if not ok: try: os.unlink(tfn) except os.error: pass pipeline = '%s <%s; rm -f %s' % (prog, tfn, tfn) # XXX What if prog fails? return os.popen(pipeline, 'r') if error: self.error_dialog( IOError, "Can't decode content-encoding: %s" % content_encoding) return None decode_prog = { 'gzip': 'gzip -d', 'x-gzip': 'gzip -d', 'compress': 'compress -d', 'x-compress': 'compress -d', } def exception_dialog(self, message="", root=None): exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback self.exc_dialog(message, exc, val, tb, root) def report_callback_exception(self, exc, val, tb, root=None): self.exc_dialog("in a callback function", exc, val, tb, root) def exc_dialog(self, message, exc, val, tb, root=None): if self.in_exception_dialog: print() print("*** Recursive exception", message) import traceback traceback.print_exception(exc, val, tb) return self.in_exception_dialog = 1 def f(s=self, m=message, e=exc, v=val, t=tb, root=root): s._exc_dialog(m, e, v, t, root) if TkVersion >= 4.1: self.root.after_idle(f) else: self.root.after(0, f) def _exc_dialog(self, message, exc, val, tb, root=None): # XXX This needn't be a modal dialog -- # XXX should SafeDialog be changed to support callbacks? from utils import SafeDialog msg = "An exception occurred " + str(message) + " :\n" msg = msg + str(exc) + " : " + str(val) dlg = SafeDialog.Dialog( root or self.root, text=msg, title="Python Exception: " + str(exc), bitmap='error', default=0, strings=("OK", "Show traceback"), ) self.in_exception_dialog = 0 if dlg.num == 1: self.traceback_dialog(exc, val, tb) def traceback_dialog(self, exc, val, tb): # XXX This could actually just create a new Browser window... from utils import TbDialog TbDialog.TracebackDialog(self.root, exc, val, tb) def error_dialog(self, exc, msg, root=None): # Display an error dialog. # Return when the user clicks OK # XXX This needn't be a modal dialog from utils import SafeDialog if type(msg) in (List, Tuple): s = '' for item in msg: s = s + ':\n' + str(item) msg = s[2:] else: msg = str(msg) SafeDialog.Dialog( root or self.root, text=msg, title="Error: " + str(exc), bitmap='error', default=0, strings=('OK', ), ) dingbatimages = { 'ldots': ('...', None), # math stuff 'sp': (' ', None), 'hairsp': ('\240', None), 'thinsp': ('\240', None), 'emdash': ('--', None), 'endash': ('-', None), 'mdash': ('--', None), 'ndash': ('-', None), 'ensp': (' ', None) } def clear_dingbat(self, entname): if self.dingbatimages.has_key(entname): del self.dingbatimages[entname] def set_dingbat(self, entname, entity): self.dingbatimages[entname] = entity def load_dingbat(self, entname): if self.dingbatimages.has_key(entname): return self.dingbatimages[entname] gifname = grailutil.which(entname + '.gif', self.iconpath) if gifname: img = PhotoImage(file=gifname, master=self.root) self.dingbatimages[entname] = img return img self.dingbatimages[entname] = None return None
class Application(BaseApplication.BaseApplication): """The application class represents a group of browser windows.""" def __init__(self, prefs=None, display=None): self.root = Tk(className='Grail', screenName=display) self.root.withdraw() resources = os.path.join(script_dir, "data", "Grail.ad") if os.path.isfile(resources): self.root.option_readfile(resources, "startupFile") BaseApplication.BaseApplication.__init__(self, prefs) # The stylesheet must be initted before any Viewers, so it # registers its' prefs callbacks first, hence reloads before the # viewers reconfigure w.r.t. the new styles. self.stylesheet = Stylesheet.Stylesheet(self.prefs) self.load_images = 1 # Overridden by cmd line or pref. # socket management sockets = self.prefs.GetInt('sockets', 'number') self.sq = SocketQueue(sockets) self.prefs.AddGroupCallback('sockets', lambda self=self: \ self.sq.change_max( self.prefs.GetInt('sockets', 'number'))) # initialize on_exit_methods before global_history self.on_exit_methods = [] self.global_history = GlobalHistory.GlobalHistory(self) self.login_cache = {} self.rexec_cache = {} self.url_cache = CacheManager(self) self.image_cache = ImageCache(self.url_cache) self.auth = AuthenticationManager(self) self.root.report_callback_exception = self.report_callback_exception if sys.stdin.isatty(): # only useful if stdin might generate KeyboardInterrupt self.keep_alive() self.browsers = [] self.iostatuspanel = None self.in_exception_dialog = None import Greek for k, v in Greek.entitydefs.items(): Application.dingbatimages[k] = (v, '_sym') self.root.bind_class("Text", "<Alt-Left>", self.dummy_event) self.root.bind_class("Text", "<Alt-Right>", self.dummy_event) def dummy_event(self, event): pass def register_on_exit(self, method): self.on_exit_methods.append(method) def unregister_on_exit(self, method): try: self.on_exit_methods.remove(method) except ValueError: pass def exit_notification(self): for m in self.on_exit_methods[:]: try: m() except: pass def add_browser(self, browser): self.browsers.append(browser) def del_browser(self, browser): try: self.browsers.remove(browser) except ValueError: pass def quit(self): self.root.quit() def open_io_status_panel(self): if not self.iostatuspanel: import IOStatusPanel self.iostatuspanel = IOStatusPanel.IOStatusPanel(self) else: self.iostatuspanel.reopen() def maybe_quit(self): if not (self.embedded or self.browsers): self.quit() def go(self): try: try: if ilu_tk: ilu_tk.RunMainLoop() else: self.root.mainloop() except KeyboardInterrupt: pass finally: self.exit_notification() def keep_alive(self): # Exercise the Python interpreter regularly so keyboard # interrupts get through self.root.tk.createtimerhandler(KEEPALIVE_TIMER, self.keep_alive) def get_cached_image(self, url): return self.image_cache.get_image(url) def set_cached_image(self, url, image, owner=None): self.image_cache.set_image(url, image, owner) def open_url(self, url, method, params, reload=0, data=None): api = self.url_cache.open(url, method, params, reload, data=data) api._url_ = url return api def open_url_simple(self, url): api = self.open_url(url, 'GET', {}) errcode, errmsg, meta = api.getmeta() if errcode != 200: raise IOError, ('url open error', errcode, errmsg, meta) return URLReadWrapper(api, meta) def get_cache_keys(self): """For applets.""" return self.url_cache.items.keys() def decode_pipeline(self, fp, content_encoding, error=1): if self.decode_prog.has_key(content_encoding): prog = self.decode_prog[content_encoding] if not prog: return fp tfn = tempfile.mktemp() ok = 0 try: temp = open(tfn, 'w') BUFSIZE = 8192 while 1: buf = fp.read(BUFSIZE) if not buf: break temp.write(buf) temp.close() ok = 1 finally: if not ok: try: os.unlink(tfn) except os.error: pass pipeline = '%s <%s; rm -f %s' % (prog, tfn, tfn) # XXX What if prog fails? return os.popen(pipeline, 'r') if error: self.error_dialog(IOError, "Can't decode content-encoding: %s" % content_encoding) return None decode_prog = { 'gzip': 'gzip -d', 'x-gzip': 'gzip -d', 'compress': 'compress -d', 'x-compress': 'compress -d', } def exception_dialog(self, message="", root=None): exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback self.exc_dialog(message, exc, val, tb, root) def report_callback_exception(self, exc, val, tb, root=None): self.exc_dialog("in a callback function", exc, val, tb, root) def exc_dialog(self, message, exc, val, tb, root=None): if self.in_exception_dialog: print print "*** Recursive exception", message import traceback traceback.print_exception(exc, val, tb) return self.in_exception_dialog = 1 def f(s=self, m=message, e=exc, v=val, t=tb, root=root): s._exc_dialog(m, e, v, t, root) if TkVersion >= 4.1: self.root.after_idle(f) else: self.root.after(0, f) def _exc_dialog(self, message, exc, val, tb, root=None): # XXX This needn't be a modal dialog -- # XXX should SafeDialog be changed to support callbacks? import SafeDialog msg = "An exception occurred " + str(message) + " :\n" msg = msg + str(exc) + " : " + str(val) dlg = SafeDialog.Dialog(root or self.root, text=msg, title="Python Exception: " + str(exc), bitmap='error', default=0, strings=("OK", "Show traceback"), ) self.in_exception_dialog = 0 if dlg.num == 1: self.traceback_dialog(exc, val, tb) def traceback_dialog(self, exc, val, tb): # XXX This could actually just create a new Browser window... import TbDialog TbDialog.TracebackDialog(self.root, exc, val, tb) def error_dialog(self, exc, msg, root=None): # Display an error dialog. # Return when the user clicks OK # XXX This needn't be a modal dialog import SafeDialog if type(msg) in (ListType, TupleType): s = '' for item in msg: s = s + ':\n' + str(item) msg = s[2:] else: msg = str(msg) SafeDialog.Dialog(root or self.root, text=msg, title="Error: " + str(exc), bitmap='error', default=0, strings=('OK',), ) dingbatimages = {'ldots': ('...', None), # math stuff 'sp': (' ', None), 'hairsp': ('\240', None), 'thinsp': ('\240', None), 'emdash': ('--', None), 'endash': ('-', None), 'mdash': ('--', None), 'ndash': ('-', None), 'ensp': (' ', None) } def clear_dingbat(self, entname): if self.dingbatimages.has_key(entname): del self.dingbatimages[entname] def set_dingbat(self, entname, entity): self.dingbatimages[entname] = entity def load_dingbat(self, entname): if self.dingbatimages.has_key(entname): return self.dingbatimages[entname] gifname = grailutil.which(entname + '.gif', self.iconpath) if gifname: img = PhotoImage(file=gifname, master=self.root) self.dingbatimages[entname] = img return img self.dingbatimages[entname] = None return None