Kaydet (Commit) 7d5e4217 authored tarafından Guido van Rossum's avatar Guido van Rossum

Rewritten somewhat again, distinguished between internal and external

methods (internal ones start with '_'), asynchronous transfers are now
killed synchronously (i.e. after t.kill(), t.busy() is false immediately).
üst 9755b26f
...@@ -18,6 +18,7 @@ ulprog = regex.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n') ...@@ -18,6 +18,7 @@ ulprog = regex.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
# Basic Man Page class -- does not disable editing # Basic Man Page class -- does not disable editing
class EditableManPage(ScrolledText): class EditableManPage(ScrolledText):
# Initialize instance
def __init__(self, master=None, cnf={}): def __init__(self, master=None, cnf={}):
# Initialize base class # Initialize base class
ScrolledText.__init__(self, master, cnf) ScrolledText.__init__(self, master, cnf)
...@@ -27,37 +28,77 @@ class EditableManPage(ScrolledText): ...@@ -27,37 +28,77 @@ class EditableManPage(ScrolledText):
self.tag_config('!', {'font': ITALICFONT}) self.tag_config('!', {'font': ITALICFONT})
self.tag_config('_', {'underline': 1}) self.tag_config('_', {'underline': 1})
def parsefile(self, fp): # Set state to idle
if hasattr(self, 'buffer'): self.fp = None
raise RuntimeError, 'Still busy parsing!' self.lineno = 0
# Test whether we are busy parsing a file
def busy(self):
return self.fp != None
# Ensure we're not busy
def kill(self):
if self.busy():
self._endparser()
# Parse a file, in the background
def asyncparsefile(self, fp):
self._startparser(fp)
self.tk.createfilehandler(fp, tkinter.READABLE,
self._filehandler)
parsefile = asyncparsefile # Alias
# I/O handler used by background parsing
def _filehandler(self, fp, mask):
nextline = self.fp.readline()
if not nextline:
self._endparser()
return
self._parseline(nextline)
# Parse a file, now (cannot be aborted)
def syncparsefile(self, fp):
from select import select from select import select
def avail(fp=fp, tout=0.0, select=select): def avail(fp=fp, tout=0.0, select=select):
return select([fp], [], [], tout)[0] return select([fp], [], [], tout)[0]
height = self.getint(self['height']) height = self.getint(self['height'])
self.startparser() self._startparser(fp)
while 1: while 1:
if self.lineno < height or \
self.lineno%10 == 0 or not avail():
self.update()
nextline = fp.readline() nextline = fp.readline()
if not nextline: if not nextline:
break break
self.parseline(nextline) self._parseline(nextline)
self.endparser() self._endparser()
self.update()
# Initialize parsing from a particular file -- must not be busy
def startparser(self): def _startparser(self, fp):
if self.busy():
raise RuntimeError, 'startparser: still busy'
fp.fileno() # Test for file-ness
self.fp = fp
self.lineno = 0 self.lineno = 0
self.ok = 0 self.ok = 0
self.empty = 0 self.empty = 0
self.buffer = None self.buffer = None
self.delete('1.0', 'end')
def endparser(self): # End parsing -- must be busy, need not be at EOF
def _endparser(self):
if not self.busy():
raise RuntimeError, 'endparser: not busy'
if self.buffer: if self.buffer:
self.parseline('') self._parseline('')
try:
self.tk.deletefilehandler(self.fp)
except TclError, msg:
pass
self.fp.close()
self.fp = None
del self.ok, self.empty, self.buffer del self.ok, self.empty, self.buffer
def parseline(self, nextline): # Parse a single line
def _parseline(self, nextline):
if not self.buffer: if not self.buffer:
# Save this line -- we need one line read-ahead # Save this line -- we need one line read-ahead
self.buffer = nextline self.buffer = nextline
...@@ -90,12 +131,12 @@ class EditableManPage(ScrolledText): ...@@ -90,12 +131,12 @@ class EditableManPage(ScrolledText):
if self.empty: if self.empty:
# One or more previous lines were empty # One or more previous lines were empty
# -- insert one blank line in the text # -- insert one blank line in the text
self.insert_prop('\n') self._insert_prop('\n')
self.lineno = self.lineno + 1 self.lineno = self.lineno + 1
self.empty = 0 self.empty = 0
if not propline: if not propline:
# No properties # No properties
self.insert_prop(textline) self._insert_prop(textline)
self.lineno = self.lineno + 1 self.lineno = self.lineno + 1
return return
# Search for properties # Search for properties
...@@ -104,25 +145,26 @@ class EditableManPage(ScrolledText): ...@@ -104,25 +145,26 @@ class EditableManPage(ScrolledText):
for i in range(min(len(propline), len(textline))): for i in range(min(len(propline), len(textline))):
if propline[i] != p: if propline[i] != p:
if j < i: if j < i:
self.insert_prop(textline[j:i], p) self._insert_prop(textline[j:i], p)
j = i j = i
p = propline[i] p = propline[i]
self.insert_prop(textline[j:]) self._insert_prop(textline[j:])
self.lineno = self.lineno + 1 self.lineno = self.lineno + 1
def insert_prop(self, str, prop = ' '): # Insert a string at the end, with at most one property (tag)
def _insert_prop(self, str, prop = ' '):
here = self.index('end') here = self.index('end')
self.insert('end', str[0]) self.insert('end', str)
tags = self.tag_names(here) tags = self.tag_names(here)
for tag in tags: for tag in tags:
self.tag_remove(tag, here) self.tag_remove(tag, here, 'end')
if prop != ' ': if prop != ' ':
self.tag_add(prop, here) self.tag_add(prop, here, 'end')
self.insert('end', str[1:])
# Readonly Man Page class -- disables editing, otherwise the same # Readonly Man Page class -- disables editing, otherwise the same
class ReadonlyManPage(EditableManPage): class ReadonlyManPage(EditableManPage):
# Initialize instance
def __init__(self, master=None, cnf={}): def __init__(self, master=None, cnf={}):
# Initialize base class # Initialize base class
EditableManPage.__init__(self, master, cnf) EditableManPage.__init__(self, master, cnf)
...@@ -136,6 +178,7 @@ class ReadonlyManPage(EditableManPage): ...@@ -136,6 +178,7 @@ class ReadonlyManPage(EditableManPage):
self.bind('<Control-d>', self.modify_cb) self.bind('<Control-d>', self.modify_cb)
self.bind('<Control-v>', self.modify_cb) self.bind('<Control-v>', self.modify_cb)
# You could override this to ring the bell, etc.
def modify_cb(self, e): def modify_cb(self, e):
pass pass
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment