New PyCrust source from Patrick's CVS

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14078 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2002-02-09 00:41:10 +00:00
parent 769a9cb2b8
commit 167a4bb9fd
3 changed files with 86 additions and 43 deletions

View File

@@ -52,9 +52,9 @@ class FillingTree(wxTreeCtrl):
objtype = type(object) objtype = type(object)
if objtype is types.DictType: if objtype is types.DictType:
dict = object dict = object
elif (objtype in (types.ClassType, types.InstanceType, \ elif (objtype in (types.ClassType, \
types.ModuleType)) \ types.InstanceType, \
or hasattr(object, '__class__'): types.ModuleType)):
for key in introspect.getAttributeNames(object): for key in introspect.getAttributeNames(object):
# Believe it or not, some attributes can disappear, such as # Believe it or not, some attributes can disappear, such as
# the exc_traceback attribute of the sys module. So this is # the exc_traceback attribute of the sys module. So this is
@@ -74,7 +74,7 @@ class FillingTree(wxTreeCtrl):
if not children: if not children:
return return
list = children.keys() list = children.keys()
list.sort() list.sort(lambda x, y: cmp(x.lower(), y.lower()))
for item in list: for item in list:
itemtext = str(item) itemtext = str(item)
# Show string dictionary items with single quotes, except for # Show string dictionary items with single quotes, except for

View File

@@ -7,6 +7,7 @@ __version__ = "$Revision$"[11:-2]
import inspect import inspect
import string import string
import types
def getAutoCompleteList(command='', locals=None, includeMagic=1, \ def getAutoCompleteList(command='', locals=None, includeMagic=1, \
includeSingle=1, includeDouble=1): includeSingle=1, includeDouble=1):
@@ -35,11 +36,13 @@ def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1):
for item in getAllAttributeNames(object): for item in getAllAttributeNames(object):
dict[item] = None dict[item] = None
attributes += dict.keys() attributes += dict.keys()
attributes.sort(lambda x, y: cmp(x.lower(), y.lower())) attributes.sort(lambda x, y: cmp(x.upper(), y.upper()))
if not includeSingle: if not includeSingle:
attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes) attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes)
if not includeDouble: if not includeDouble:
attributes = filter(lambda item: item[:2]!='__', attributes) attributes = filter(lambda item: item[:2]!='__', attributes)
# Make sure we haven't picked up any bogus attributes somehow.
attributes = [attribute for attribute in attributes if hasattr(object, attribute)]
return attributes return attributes
def getAllAttributeNames(object): def getAllAttributeNames(object):
@@ -47,12 +50,22 @@ def getAllAttributeNames(object):
Recursively walk through a class and all base classes. Recursively walk through a class and all base classes.
""" """
# !!!
# !!! Do Not use hasattr() as a test anywhere in this function,
# !!! because it is unreliable with remote objects - xmlrpc, soap, etc.
# !!!
attributes = [] attributes = []
# Wake up sleepy objects - a hack for ZODB objects in "ghost" state. # Wake up sleepy objects - a hack for ZODB objects in "ghost" state.
wakeupcall = dir(object) wakeupcall = dir(object)
del wakeupcall del wakeupcall
# Get attributes available through the normal convention. # Get attributes available through the normal convention.
attributes += dir(object) attributes += dir(object)
try:
keys = object.__dict__.keys()
except:
pass
else:
attributes += keys
# For a class instance, get the attributes for the class. # For a class instance, get the attributes for the class.
if hasattr(object, '__class__'): if hasattr(object, '__class__'):
# Break a circular reference. This happens with extension classes. # Break a circular reference. This happens with extension classes.
@@ -61,9 +74,18 @@ def getAllAttributeNames(object):
else: else:
attributes += getAllAttributeNames(object.__class__) attributes += getAllAttributeNames(object.__class__)
# Also get attributes from any and all parent classes. # Also get attributes from any and all parent classes.
if hasattr(object, '__bases__'): try:
for base in object.__bases__: bases = object.__bases__
attributes += getAllAttributeNames(base) except:
pass
else:
if isinstance(bases, type(())):
for base in bases:
if type(base) is types.TypeType:
# Break a circular reference. Happens in Python 2.2.
pass
else:
attributes += getAllAttributeNames(base)
return attributes return attributes
def getCallTip(command='', locals=None): def getCallTip(command='', locals=None):

View File

@@ -31,8 +31,7 @@ if wxPlatform == '__WXMSW__':
} }
# Versions of wxPython prior to 2.3.2 had a sizing bug on Win platform. # Versions of wxPython prior to 2.3.2 had a sizing bug on Win platform.
# The font was 2 points too large. So we need to reduce the font size. # The font was 2 points too large. So we need to reduce the font size.
if ((wxMAJOR_VERSION, wxMINOR_VERSION) == (2, 3) and wxRELEASE_NUMBER < 2) \ if (wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER) < (2, 3, 2):
or (wxMAJOR_VERSION <= 2 and wxMINOR_VERSION <= 2):
faces['size'] -= 2 faces['size'] -= 2
faces['lnsize'] -= 2 faces['lnsize'] -= 2
else: # GTK else: # GTK
@@ -72,8 +71,28 @@ class ShellFacade:
self.__dict__[method] = getattr(other, method) self.__dict__[method] = getattr(other, method)
d = self.__dict__ d = self.__dict__
d['other'] = other d['other'] = other
d['help'] = 'There is no help available, yet.' d['helpText'] = \
"""
* Key bindings:
Home Go to the beginning of the command or line.
Shift+Home Select to the beginning of the command or line.
Shift+End Select to the end of the line.
End Go to the end of the line.
Ctrl+C Copy selected text, removing prompts.
Ctrl+Shift+C Copy selected text, retaining prompts.
Ctrl+X Cut selected text.
Ctrl+V Paste from clipboard.
Ctrl+Up Arrow Retrieve Previous History item.
Alt+P Retrieve Previous History item.
Ctrl+Down Arrow Retrieve Next History item.
Alt+N Retrieve Next History item.
F8 Command-completion of History item.
(Type a few characters of a previous command and then press F8.)
"""
def help(self):
"""Display some useful information about how to use the shell."""
self.write(self.helpText)
def __getattr__(self, name): def __getattr__(self, name):
if hasattr(self.other, name): if hasattr(self.other, name):
@@ -138,10 +157,9 @@ class Shell(wxStyledTextCtrl):
stdout=PseudoFileOut(self.writeOut), \ stdout=PseudoFileOut(self.writeOut), \
stderr=PseudoFileErr(self.writeErr), \ stderr=PseudoFileErr(self.writeErr), \
*args, **kwds) *args, **kwds)
# Keep track of the most recent prompt starting and ending positions. # Keep track of the last non-continuation prompt positions.
self.promptPos = [0, 0] self.promptPosStart = 0
# Keep track of the most recent non-continuation prompt. self.promptPosEnd = 0
self.prompt1Pos = [0, 0]
# Keep track of multi-line commands. # Keep track of multi-line commands.
self.more = 0 self.more = 0
# Create the command history. Commands are added into the front of # Create the command history. Commands are added into the front of
@@ -253,7 +271,7 @@ class Shell(wxStyledTextCtrl):
"""Configure font size, typeface and color for lexer.""" """Configure font size, typeface and color for lexer."""
# Default style # Default style
self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d,back:%(backcol)s" % faces)
self.StyleClearAll() self.StyleClearAll()
@@ -287,7 +305,7 @@ class Shell(wxStyledTextCtrl):
return return
key = event.KeyCode() key = event.KeyCode()
currpos = self.GetCurrentPos() currpos = self.GetCurrentPos()
stoppos = self.promptPos[1] stoppos = self.promptPosEnd
if key == ord('.'): if key == ord('.'):
# The dot or period key activates auto completion. # The dot or period key activates auto completion.
# Get the command between the prompt and the cursor. # Get the command between the prompt and the cursor.
@@ -317,7 +335,6 @@ class Shell(wxStyledTextCtrl):
altDown = event.AltDown() altDown = event.AltDown()
shiftDown = event.ShiftDown() shiftDown = event.ShiftDown()
currpos = self.GetCurrentPos() currpos = self.GetCurrentPos()
stoppos = self.promptPos[1]
# Return is used to submit a command to the interpreter. # Return is used to submit a command to the interpreter.
if key == WXK_RETURN: if key == WXK_RETURN:
if self.AutoCompActive(): self.AutoCompCancel() if self.AutoCompActive(): self.AutoCompCancel()
@@ -330,16 +347,20 @@ class Shell(wxStyledTextCtrl):
elif controlDown and altDown: elif controlDown and altDown:
event.Skip() event.Skip()
# Cut to the clipboard. # Cut to the clipboard.
elif controlDown and key in (ord('X'), ord('x')): elif (controlDown and key in (ord('X'), ord('x'))) \
or (shiftDown and key == WXK_DELETE):
self.Cut() self.Cut()
# Copy to the clipboard. # Copy to the clipboard.
elif controlDown and not shiftDown and key in (ord('C'), ord('c')): elif controlDown and not shiftDown \
and key in (ord('C'), ord('c'), WXK_INSERT):
self.Copy() self.Copy()
# Copy to the clipboard, including prompts. # Copy to the clipboard, including prompts.
elif controlDown and shiftDown and key in (ord('C'), ord('c')): elif controlDown and shiftDown \
and key in (ord('C'), ord('c'), WXK_INSERT):
self.CopyWithPrompts() self.CopyWithPrompts()
# Paste from the clipboard. # Paste from the clipboard.
elif controlDown and key in (ord('V'), ord('v')): elif (controlDown and key in (ord('V'), ord('v'), WXK_INSERT)) \
or (shiftDown and key == WXK_INSERT):
self.Paste() self.Paste()
# Retrieve the previous command from the history buffer. # Retrieve the previous command from the history buffer.
elif (controlDown and key == WXK_UP) \ elif (controlDown and key == WXK_UP) \
@@ -354,22 +375,23 @@ class Shell(wxStyledTextCtrl):
self.OnHistorySearch() self.OnHistorySearch()
# Home needs to be aware of the prompt. # Home needs to be aware of the prompt.
elif key == WXK_HOME: elif key == WXK_HOME:
if currpos >= stoppos: home = self.promptPosEnd
if currpos >= home:
if event.ShiftDown(): if event.ShiftDown():
# Select text from current position to end of prompt. # Select text from current position to end of prompt.
self.SetSelection(self.GetCurrentPos(), stoppos) self.SetSelection(self.GetCurrentPos(), home)
else: else:
self.SetCurrentPos(stoppos) self.SetCurrentPos(home)
self.SetAnchor(stoppos) self.SetAnchor(home)
else: else:
event.Skip() event.Skip()
# Basic navigation keys should work anywhere. # Basic navigation keys should work anywhere.
elif key in (WXK_END, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, \ elif key in (WXK_END, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, \
WXK_PRIOR, WXK_NEXT): WXK_PRIOR, WXK_NEXT):
event.Skip() event.Skip()
# Don't backspace over the latest prompt. # Don't backspace over the latest non-continuation prompt.
elif key == WXK_BACK: elif key == WXK_BACK:
if currpos > self.prompt1Pos[1]: if currpos > self.promptPosEnd:
event.Skip() event.Skip()
# Only allow these keys after the latest prompt. # Only allow these keys after the latest prompt.
elif key in (WXK_TAB, WXK_DELETE): elif key in (WXK_TAB, WXK_DELETE):
@@ -459,23 +481,23 @@ class Shell(wxStyledTextCtrl):
if thepos == endpos: if thepos == endpos:
self.interp.more = 0 self.interp.more = 0
if self.getCommand(): if self.getCommand():
command = self.GetTextRange(self.prompt1Pos[1], endpos) command = self.GetTextRange(self.promptPosEnd, endpos)
else: else:
# This is a hack, now that we allow editing of previous # This is a hack, now that we allow editing of previous
# lines, which throws off our promptPos values. # lines, which throws off our promptPos values.
newend = endpos - len(self.getCommand(rstrip=0)) newend = endpos - len(self.getCommand(rstrip=0))
command = self.GetTextRange(self.prompt1Pos[1], newend) command = self.GetTextRange(self.promptPosEnd, newend)
command = command.replace(os.linesep + sys.ps2, '\n') command = command.replace(os.linesep + sys.ps2, '\n')
self.push(command) self.push(command)
# Or replace the current command with the other command. # Or replace the current command with the other command.
elif thepos < self.prompt1Pos[0]: elif thepos < self.promptPosStart:
theline = self.GetCurrentLine() theline = self.GetCurrentLine()
command = self.getCommand(rstrip=0) command = self.getCommand(rstrip=0)
# If the new line contains a command (even an invalid one). # If the new line contains a command (even an invalid one).
if command: if command:
command = self.getMultilineCommand() command = self.getMultilineCommand()
self.SetCurrentPos(endpos) self.SetCurrentPos(endpos)
startpos = self.prompt1Pos[1] startpos = self.promptPosEnd
self.SetSelection(startpos, endpos) self.SetSelection(startpos, endpos)
self.ReplaceSelection('') self.ReplaceSelection('')
self.write(command) self.write(command)
@@ -485,7 +507,7 @@ class Shell(wxStyledTextCtrl):
self.SetCurrentPos(thepos) self.SetCurrentPos(thepos)
self.SetAnchor(thepos) self.SetAnchor(thepos)
# Or add a new line to the current single or multi-line command. # Or add a new line to the current single or multi-line command.
elif thepos > self.prompt1Pos[1]: elif thepos > self.promptPosEnd:
self.write(os.linesep) self.write(os.linesep)
self.more = 1 self.more = 1
self.prompt() self.prompt()
@@ -601,12 +623,11 @@ class Shell(wxStyledTextCtrl):
prompt = str(sys.ps1) prompt = str(sys.ps1)
pos = self.GetCurLine()[1] pos = self.GetCurLine()[1]
if pos > 0: self.write(os.linesep) if pos > 0: self.write(os.linesep)
self.promptPos[0] = self.GetCurrentPos()
if not self.more: self.prompt1Pos[0] = self.GetCurrentPos()
self.write(prompt)
self.promptPos[1] = self.GetCurrentPos()
if not self.more: if not self.more:
self.prompt1Pos[1] = self.GetCurrentPos() self.promptPosStart = self.GetCurrentPos()
self.write(prompt)
if not self.more:
self.promptPosEnd = self.GetCurrentPos()
# Keep the undo feature from undoing previous responses. # Keep the undo feature from undoing previous responses.
self.EmptyUndoBuffer() self.EmptyUndoBuffer()
# XXX Add some autoindent magic here if more. # XXX Add some autoindent magic here if more.
@@ -732,8 +753,8 @@ class Shell(wxStyledTextCtrl):
def CanCut(self): def CanCut(self):
"""Return true if text is selected and can be cut.""" """Return true if text is selected and can be cut."""
if self.GetSelectionStart() != self.GetSelectionEnd() \ if self.GetSelectionStart() != self.GetSelectionEnd() \
and self.GetSelectionStart() >= self.prompt1Pos[1] \ and self.GetSelectionStart() >= self.promptPosEnd \
and self.GetSelectionEnd() >= self.prompt1Pos[1]: and self.GetSelectionEnd() >= self.promptPosEnd:
return 1 return 1
else: else:
return 0 return 0
@@ -751,7 +772,7 @@ class Shell(wxStyledTextCtrl):
def CanEdit(self): def CanEdit(self):
"""Return true if editing should succeed.""" """Return true if editing should succeed."""
return self.GetCurrentPos() >= self.prompt1Pos[1] return self.GetCurrentPos() >= self.promptPosEnd
def Cut(self): def Cut(self):
"""Remove selection and place it on the clipboard.""" """Remove selection and place it on the clipboard."""