Updated PyCrust code from Patrick
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16755 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -8,6 +8,7 @@ from wxPython.wx import *
|
|||||||
from shell import Shell
|
from shell import Shell
|
||||||
from filling import Filling
|
from filling import Filling
|
||||||
from version import VERSION
|
from version import VERSION
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
class Crust(wxSplitterWindow):
|
class Crust(wxSplitterWindow):
|
||||||
@@ -55,12 +56,9 @@ class CrustFrame(wxFrame, ShellMenu):
|
|||||||
intro += '\nSponsored by Orbtech - Your source for Python programming expertise.'
|
intro += '\nSponsored by Orbtech - Your source for Python programming expertise.'
|
||||||
self.CreateStatusBar()
|
self.CreateStatusBar()
|
||||||
self.SetStatusText(intro.replace('\n', ', '))
|
self.SetStatusText(intro.replace('\n', ', '))
|
||||||
|
|
||||||
import os
|
|
||||||
filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico')
|
filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico')
|
||||||
icon = wxIcon(filename, wxBITMAP_TYPE_ICO)
|
icon = wxIcon(filename, wxBITMAP_TYPE_ICO)
|
||||||
self.SetIcon(icon)
|
self.SetIcon(icon)
|
||||||
|
|
||||||
self.crust = Crust(parent=self, intro=intro, \
|
self.crust = Crust(parent=self, intro=intro, \
|
||||||
rootObject=rootObject, \
|
rootObject=rootObject, \
|
||||||
rootLabel=rootLabel, \
|
rootLabel=rootLabel, \
|
||||||
@@ -78,6 +76,10 @@ class CrustFrame(wxFrame, ShellMenu):
|
|||||||
# Temporary hack to share menus between PyCrust and PyShell.
|
# Temporary hack to share menus between PyCrust and PyShell.
|
||||||
self.shell = self.crust.shell
|
self.shell = self.crust.shell
|
||||||
self.createMenus()
|
self.createMenus()
|
||||||
|
EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.crust.shell.destroy()
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
|
||||||
|
@@ -14,6 +14,14 @@ import keyword
|
|||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
|
||||||
|
COMMONTYPES = [getattr(types, t) for t in dir(types) \
|
||||||
|
if not t.startswith('_') \
|
||||||
|
and t not in ('ClassType', 'InstanceType', 'ModuleType')]
|
||||||
|
try:
|
||||||
|
COMMONTYPES.append(type(''.__repr__)) # Method-wrapper in version 2.2.x.
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FillingTree(wxTreeCtrl):
|
class FillingTree(wxTreeCtrl):
|
||||||
"""PyCrust FillingTree based on wxTreeCtrl."""
|
"""PyCrust FillingTree based on wxTreeCtrl."""
|
||||||
@@ -39,40 +47,43 @@ class FillingTree(wxTreeCtrl):
|
|||||||
EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
|
EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
|
||||||
EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
|
EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
|
||||||
|
|
||||||
def hasChildren(self, object):
|
def hasChildren(self, o):
|
||||||
"""Return true if object has children."""
|
"""Return true if object has children."""
|
||||||
if self.getChildren(object):
|
if self.getChildren(o):
|
||||||
return true
|
return true
|
||||||
else:
|
else:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
def getChildren(self, object):
|
def getChildren(self, o):
|
||||||
"""Return a dictionary with the attributes or contents of object."""
|
"""Return a dictionary with the attributes or contents of object."""
|
||||||
dict = {}
|
busy = wxBusyCursor()
|
||||||
objtype = type(object)
|
otype = type(o)
|
||||||
if (objtype is types.DictType) \
|
if (otype is types.DictType) \
|
||||||
or str(objtype)[17:23] == 'BTrees' and hasattr(object, 'keys'):
|
or str(otype)[17:23] == 'BTrees' and hasattr(o, 'keys'):
|
||||||
dict = object
|
return o
|
||||||
elif (objtype in (types.ClassType, \
|
d = {}
|
||||||
types.InstanceType, \
|
if otype is types.ListType:
|
||||||
types.ModuleType)) \
|
for n in range(len(o)):
|
||||||
or str(objtype)[1:10] == 'extension':
|
key = '[' + str(n) + ']'
|
||||||
for key in introspect.getAttributeNames(object):
|
d[key] = o[n]
|
||||||
|
if otype not in COMMONTYPES:
|
||||||
|
for key in introspect.getAttributeNames(o):
|
||||||
# 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
|
||||||
# nested in a try block.
|
# nested in a try block.
|
||||||
try:
|
try:
|
||||||
dict[key] = getattr(object, key)
|
d[key] = getattr(o, key)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return dict
|
return d
|
||||||
|
|
||||||
def OnItemExpanding(self, event):
|
def OnItemExpanding(self, event):
|
||||||
|
busy = wxBusyCursor()
|
||||||
selection = event.GetItem()
|
selection = event.GetItem()
|
||||||
if self.IsExpanded(selection):
|
if self.IsExpanded(selection):
|
||||||
return
|
return
|
||||||
object = self.GetPyData(selection)
|
o = self.GetPyData(selection)
|
||||||
children = self.getChildren(object)
|
children = self.getChildren(o)
|
||||||
if not children:
|
if not children:
|
||||||
return
|
return
|
||||||
list = children.keys()
|
list = children.keys()
|
||||||
@@ -84,7 +95,7 @@ class FillingTree(wxTreeCtrl):
|
|||||||
itemtext = str(item)
|
itemtext = str(item)
|
||||||
# Show string dictionary items with single quotes, except for
|
# Show string dictionary items with single quotes, except for
|
||||||
# the first level of items, if they represent a namespace.
|
# the first level of items, if they represent a namespace.
|
||||||
if type(object) is types.DictType \
|
if type(o) is types.DictType \
|
||||||
and type(item) is types.StringType \
|
and type(item) is types.StringType \
|
||||||
and (selection != self.root \
|
and (selection != self.root \
|
||||||
or (selection == self.root and not self.rootIsNamespace)):
|
or (selection == self.root and not self.rootIsNamespace)):
|
||||||
@@ -95,42 +106,44 @@ class FillingTree(wxTreeCtrl):
|
|||||||
|
|
||||||
def OnItemCollapsed(self, event):
|
def OnItemCollapsed(self, event):
|
||||||
"""Remove all children from the item."""
|
"""Remove all children from the item."""
|
||||||
|
busy = wxBusyCursor()
|
||||||
item = event.GetItem()
|
item = event.GetItem()
|
||||||
self.DeleteChildren(item)
|
self.DeleteChildren(item)
|
||||||
|
|
||||||
def OnSelChanged(self, event):
|
def OnSelChanged(self, event):
|
||||||
|
busy = wxBusyCursor()
|
||||||
item = event.GetItem()
|
item = event.GetItem()
|
||||||
if item == self.root:
|
if item == self.root:
|
||||||
self.setText('')
|
self.setText('')
|
||||||
return
|
return
|
||||||
object = self.GetPyData(item)
|
o = self.GetPyData(item)
|
||||||
otype = type(object)
|
otype = type(o)
|
||||||
text = ''
|
text = ''
|
||||||
text += self.getFullName(item)
|
text += self.getFullName(item)
|
||||||
text += '\n\nType: ' + str(otype)
|
text += '\n\nType: ' + str(otype)
|
||||||
try:
|
try:
|
||||||
value = str(object)
|
value = str(o)
|
||||||
except:
|
except:
|
||||||
value = ''
|
value = ''
|
||||||
if otype is types.StringType or otype is types.UnicodeType:
|
if otype is types.StringType or otype is types.UnicodeType:
|
||||||
value = repr(object)
|
value = repr(o)
|
||||||
text += '\n\nValue: ' + value
|
text += '\n\nValue: ' + value
|
||||||
if otype is types.InstanceType:
|
if otype is types.InstanceType:
|
||||||
try:
|
try:
|
||||||
text += '\n\nClass Definition:\n\n' + \
|
text += '\n\nClass Definition:\n\n' + \
|
||||||
inspect.getsource(object.__class__)
|
inspect.getsource(o.__class__)
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
text += '\n\n"""' + inspect.getdoc(object).strip() + '"""'
|
text += '\n\n"""' + inspect.getdoc(o).strip() + '"""'
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
text += '\n\nSource Code:\n\n' + \
|
text += '\n\nSource Code:\n\n' + \
|
||||||
inspect.getsource(object)
|
inspect.getsource(o)
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
text += '\n\n"""' + inspect.getdoc(object).strip() + '"""'
|
text += '\n\n"""' + inspect.getdoc(o).strip() + '"""'
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.setText(text)
|
self.setText(text)
|
||||||
@@ -138,13 +151,13 @@ class FillingTree(wxTreeCtrl):
|
|||||||
def getFullName(self, item, partial=''):
|
def getFullName(self, item, partial=''):
|
||||||
"""Return a syntactically proper name for item."""
|
"""Return a syntactically proper name for item."""
|
||||||
parent = self.GetItemParent(item)
|
parent = self.GetItemParent(item)
|
||||||
parentobject = self.GetPyData(parent)
|
parento = self.GetPyData(parent)
|
||||||
name = self.GetItemText(item)
|
name = self.GetItemText(item)
|
||||||
# Apply dictionary syntax to dictionary items, except the root
|
# Apply dictionary syntax to dictionary items, except the root
|
||||||
# and first level children of a namepace.
|
# and first level children of a namepace.
|
||||||
if (type(parentobject) is types.DictType \
|
if (type(parento) is types.DictType \
|
||||||
or str(type(parentobject))[17:23] == 'BTrees' \
|
or str(type(parento))[17:23] == 'BTrees' \
|
||||||
and hasattr(parentobject, 'keys')) \
|
and hasattr(parento, 'keys')) \
|
||||||
and ((item != self.root and parent != self.root) \
|
and ((item != self.root and parent != self.root) \
|
||||||
or (parent == self.root and not self.rootIsNamespace)):
|
or (parent == self.root and not self.rootIsNamespace)):
|
||||||
name = '[' + name + ']'
|
name = '[' + name + ']'
|
||||||
@@ -228,6 +241,10 @@ class FillingText(wxStyledTextCtrl):
|
|||||||
self.SetTabWidth(4)
|
self.SetTabWidth(4)
|
||||||
self.SetUseTabs(0)
|
self.SetUseTabs(0)
|
||||||
self.SetReadOnly(1)
|
self.SetReadOnly(1)
|
||||||
|
try:
|
||||||
|
self.SetWrapMode(1)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def setStyles(self, faces):
|
def setStyles(self, faces):
|
||||||
"""Configure font size, typeface and color for lexer."""
|
"""Configure font size, typeface and color for lexer."""
|
||||||
|
@@ -78,6 +78,10 @@ class Interpreter(InteractiveInterpreter):
|
|||||||
sys.stderr = stderr
|
sys.stderr = stderr
|
||||||
return more
|
return more
|
||||||
|
|
||||||
|
def getAutoCompleteKeys(self):
|
||||||
|
"""Return list of auto-completion keycodes."""
|
||||||
|
return [ord('.')]
|
||||||
|
|
||||||
def getAutoCompleteList(self, command='', *args, **kwds):
|
def getAutoCompleteList(self, command='', *args, **kwds):
|
||||||
"""Return list of auto-completion options for a command.
|
"""Return list of auto-completion options for a command.
|
||||||
|
|
||||||
|
@@ -19,6 +19,8 @@ from pseudo import PseudoFileErr
|
|||||||
from version import VERSION
|
from version import VERSION
|
||||||
|
|
||||||
|
|
||||||
|
NAVKEYS = (WXK_END, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, WXK_PRIOR, WXK_NEXT)
|
||||||
|
|
||||||
if wxPlatform == '__WXMSW__':
|
if wxPlatform == '__WXMSW__':
|
||||||
faces = { 'times' : 'Times New Roman',
|
faces = { 'times' : 'Times New Roman',
|
||||||
'mono' : 'Courier New',
|
'mono' : 'Courier New',
|
||||||
@@ -66,6 +68,8 @@ class ShellFacade:
|
|||||||
'redirectStdout',
|
'redirectStdout',
|
||||||
'run',
|
'run',
|
||||||
'runfile',
|
'runfile',
|
||||||
|
'wrap',
|
||||||
|
'zoom',
|
||||||
]
|
]
|
||||||
for method in methods:
|
for method in methods:
|
||||||
self.__dict__[method] = getattr(other, method)
|
self.__dict__[method] = getattr(other, method)
|
||||||
@@ -160,6 +164,8 @@ class Shell(wxStyledTextCtrl):
|
|||||||
stdout=PseudoFileOut(self.writeOut), \
|
stdout=PseudoFileOut(self.writeOut), \
|
||||||
stderr=PseudoFileErr(self.writeErr), \
|
stderr=PseudoFileErr(self.writeErr), \
|
||||||
*args, **kwds)
|
*args, **kwds)
|
||||||
|
# Find out for which keycodes the interpreter will autocomplete.
|
||||||
|
self.autoCompleteKeys = self.interp.getAutoCompleteKeys()
|
||||||
# Keep track of the last non-continuation prompt positions.
|
# Keep track of the last non-continuation prompt positions.
|
||||||
self.promptPosStart = 0
|
self.promptPosStart = 0
|
||||||
self.promptPosEnd = 0
|
self.promptPosEnd = 0
|
||||||
@@ -219,6 +225,7 @@ class Shell(wxStyledTextCtrl):
|
|||||||
# Do we want to automatically pop up command argument help?
|
# Do we want to automatically pop up command argument help?
|
||||||
self.autoCallTip = 1
|
self.autoCallTip = 1
|
||||||
self.CallTipSetBackground(wxColour(255, 255, 232))
|
self.CallTipSetBackground(wxColour(255, 255, 232))
|
||||||
|
self.wrap()
|
||||||
|
|
||||||
def showIntro(self, text=''):
|
def showIntro(self, text=''):
|
||||||
"""Display introductory text in the shell."""
|
"""Display introductory text in the shell."""
|
||||||
@@ -301,6 +308,10 @@ class Shell(wxStyledTextCtrl):
|
|||||||
caretPos = self.GetCurrentPos()
|
caretPos = self.GetCurrentPos()
|
||||||
if caretPos > 0:
|
if caretPos > 0:
|
||||||
charBefore = self.GetCharAt(caretPos - 1)
|
charBefore = self.GetCharAt(caretPos - 1)
|
||||||
|
#*** Patch to fix bug in wxSTC for wxPython < 2.3.3.
|
||||||
|
if charBefore < 0:
|
||||||
|
charBefore = 32 # Mimic a space.
|
||||||
|
#***
|
||||||
styleBefore = self.GetStyleAt(caretPos - 1)
|
styleBefore = self.GetStyleAt(caretPos - 1)
|
||||||
|
|
||||||
# Check before.
|
# Check before.
|
||||||
@@ -311,6 +322,10 @@ class Shell(wxStyledTextCtrl):
|
|||||||
# Check after.
|
# Check after.
|
||||||
if braceAtCaret < 0:
|
if braceAtCaret < 0:
|
||||||
charAfter = self.GetCharAt(caretPos)
|
charAfter = self.GetCharAt(caretPos)
|
||||||
|
#*** Patch to fix bug in wxSTC for wxPython < 2.3.3.
|
||||||
|
if charAfter < 0:
|
||||||
|
charAfter = 32 # Mimic a space.
|
||||||
|
#***
|
||||||
styleAfter = self.GetStyleAt(caretPos)
|
styleAfter = self.GetStyleAt(caretPos)
|
||||||
if charAfter and chr(charAfter) in '[]{}()' \
|
if charAfter and chr(charAfter) in '[]{}()' \
|
||||||
and styleAfter == wxSTC_P_OPERATOR:
|
and styleAfter == wxSTC_P_OPERATOR:
|
||||||
@@ -325,20 +340,20 @@ class Shell(wxStyledTextCtrl):
|
|||||||
self.BraceHighlight(braceAtCaret, braceOpposite)
|
self.BraceHighlight(braceAtCaret, braceOpposite)
|
||||||
|
|
||||||
def OnChar(self, event):
|
def OnChar(self, event):
|
||||||
"""Keypress event handler.
|
"""Keypress event handler."""
|
||||||
|
|
||||||
Prevents modification of previously submitted commands/responses."""
|
# Prevent modification of previously submitted commands/responses.
|
||||||
if not self.CanEdit():
|
if not self.CanEdit():
|
||||||
return
|
return
|
||||||
key = event.KeyCode()
|
key = event.KeyCode()
|
||||||
currpos = self.GetCurrentPos()
|
currpos = self.GetCurrentPos()
|
||||||
stoppos = self.promptPosEnd
|
stoppos = self.promptPosEnd
|
||||||
if key == ord('.'):
|
if key in self.autoCompleteKeys:
|
||||||
# The dot or period key activates auto completion.
|
# Usually the dot (period) key activates auto completion.
|
||||||
# Get the command between the prompt and the cursor.
|
# Get the command between the prompt and the cursor.
|
||||||
# Add a dot to the end of the command.
|
# Add the autocomplete character to the end of the command.
|
||||||
command = self.GetTextRange(stoppos, currpos) + '.'
|
command = self.GetTextRange(stoppos, currpos) + chr(key)
|
||||||
self.write('.')
|
self.write(chr(key))
|
||||||
if self.autoComplete: self.autoCompleteShow(command)
|
if self.autoComplete: self.autoCompleteShow(command)
|
||||||
elif key == ord('('):
|
elif key == ord('('):
|
||||||
# The left paren activates a call tip and cancels
|
# The left paren activates a call tip and cancels
|
||||||
@@ -355,9 +370,9 @@ class Shell(wxStyledTextCtrl):
|
|||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def OnKeyDown(self, event):
|
def OnKeyDown(self, event):
|
||||||
"""Key down event handler.
|
"""Key down event handler."""
|
||||||
|
|
||||||
Prevents modification of previously submitted commands/responses."""
|
# Prevent modification of previously submitted commands/responses.
|
||||||
key = event.KeyCode()
|
key = event.KeyCode()
|
||||||
controlDown = event.ControlDown()
|
controlDown = event.ControlDown()
|
||||||
altDown = event.AltDown()
|
altDown = event.AltDown()
|
||||||
@@ -401,6 +416,25 @@ class Shell(wxStyledTextCtrl):
|
|||||||
elif controlDown and shiftDown \
|
elif controlDown and shiftDown \
|
||||||
and key in (ord('C'), ord('c'), WXK_INSERT):
|
and key in (ord('C'), ord('c'), WXK_INSERT):
|
||||||
self.CopyWithPrompts()
|
self.CopyWithPrompts()
|
||||||
|
# Home needs to be aware of the prompt.
|
||||||
|
elif key == WXK_HOME:
|
||||||
|
home = self.promptPosEnd
|
||||||
|
if currpos > home:
|
||||||
|
selecting = self.GetSelectionStart() != self.GetSelectionEnd()
|
||||||
|
self.SetCurrentPos(home)
|
||||||
|
if not selecting and not shiftDown:
|
||||||
|
self.SetAnchor(home)
|
||||||
|
self.EnsureCaretVisible()
|
||||||
|
else:
|
||||||
|
event.Skip()
|
||||||
|
#
|
||||||
|
# The following handlers modify text, so we need to see if there
|
||||||
|
# is a selection that includes text prior to the prompt.
|
||||||
|
#
|
||||||
|
# Don't modify a selection with text prior to the prompt.
|
||||||
|
elif self.GetSelectionStart() != self.GetSelectionEnd()\
|
||||||
|
and key not in NAVKEYS and not self.CanEdit():
|
||||||
|
pass
|
||||||
# Paste from the clipboard.
|
# Paste from the clipboard.
|
||||||
elif (controlDown and not shiftDown \
|
elif (controlDown and not shiftDown \
|
||||||
and key in (ord('V'), ord('v'))) \
|
and key in (ord('V'), ord('v'))) \
|
||||||
@@ -419,34 +453,20 @@ class Shell(wxStyledTextCtrl):
|
|||||||
or (altDown and key in (ord('N'), ord('n'))):
|
or (altDown and key in (ord('N'), ord('n'))):
|
||||||
self.OnHistoryReplace(step=-1)
|
self.OnHistoryReplace(step=-1)
|
||||||
# Insert the previous command from the history buffer.
|
# Insert the previous command from the history buffer.
|
||||||
elif (shiftDown and key == WXK_UP):
|
elif (shiftDown and key == WXK_UP) and self.CanEdit():
|
||||||
self.OnHistoryInsert(step=+1)
|
self.OnHistoryInsert(step=+1)
|
||||||
# Insert the next command from the history buffer.
|
# Insert the next command from the history buffer.
|
||||||
elif (shiftDown and key == WXK_DOWN):
|
elif (shiftDown and key == WXK_DOWN) and self.CanEdit():
|
||||||
self.OnHistoryInsert(step=-1)
|
self.OnHistoryInsert(step=-1)
|
||||||
# Search up the history for the text in front of the cursor.
|
# Search up the history for the text in front of the cursor.
|
||||||
elif key == WXK_F8:
|
elif key == WXK_F8:
|
||||||
self.OnHistorySearch()
|
self.OnHistorySearch()
|
||||||
# Home needs to be aware of the prompt.
|
|
||||||
elif key == WXK_HOME:
|
|
||||||
home = self.promptPosEnd
|
|
||||||
if currpos >= home:
|
|
||||||
if event.ShiftDown():
|
|
||||||
# Select text from current position to end of prompt.
|
|
||||||
self.SetSelection(self.GetCurrentPos(), home)
|
|
||||||
else:
|
|
||||||
self.SetCurrentPos(home)
|
|
||||||
self.SetAnchor(home)
|
|
||||||
self.EnsureCaretVisible()
|
|
||||||
else:
|
|
||||||
event.Skip()
|
|
||||||
# Basic navigation keys should work anywhere.
|
|
||||||
elif key in (WXK_END, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, \
|
|
||||||
WXK_PRIOR, WXK_NEXT):
|
|
||||||
event.Skip()
|
|
||||||
# Don't backspace over the latest non-continuation prompt.
|
# Don't backspace over the latest non-continuation prompt.
|
||||||
elif key == WXK_BACK:
|
elif key == WXK_BACK:
|
||||||
if currpos > self.promptPosEnd:
|
if self.GetSelectionStart() != self.GetSelectionEnd()\
|
||||||
|
and self.CanEdit():
|
||||||
|
event.Skip()
|
||||||
|
elif 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):
|
||||||
@@ -461,6 +481,9 @@ class Shell(wxStyledTextCtrl):
|
|||||||
# Don't allow line transposition.
|
# Don't allow line transposition.
|
||||||
elif controlDown and key in (ord('T'), ord('t')):
|
elif controlDown and key in (ord('T'), ord('t')):
|
||||||
pass
|
pass
|
||||||
|
# Basic navigation keys should work anywhere.
|
||||||
|
elif key in NAVKEYS:
|
||||||
|
event.Skip()
|
||||||
# Protect the readonly portion of the shell.
|
# Protect the readonly portion of the shell.
|
||||||
elif not self.CanEdit():
|
elif not self.CanEdit():
|
||||||
pass
|
pass
|
||||||
@@ -641,6 +664,7 @@ class Shell(wxStyledTextCtrl):
|
|||||||
|
|
||||||
def push(self, command):
|
def push(self, command):
|
||||||
"""Send command to the interpreter for execution."""
|
"""Send command to the interpreter for execution."""
|
||||||
|
busy = wxBusyCursor()
|
||||||
self.write(os.linesep)
|
self.write(os.linesep)
|
||||||
self.more = self.interp.push(command)
|
self.more = self.interp.push(command)
|
||||||
if not self.more:
|
if not self.more:
|
||||||
@@ -844,6 +868,13 @@ class Shell(wxStyledTextCtrl):
|
|||||||
|
|
||||||
def CanEdit(self):
|
def CanEdit(self):
|
||||||
"""Return true if editing should succeed."""
|
"""Return true if editing should succeed."""
|
||||||
|
if self.GetSelectionStart() != self.GetSelectionEnd():
|
||||||
|
if self.GetSelectionStart() >= self.promptPosEnd \
|
||||||
|
and self.GetSelectionEnd() >= self.promptPosEnd:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
return self.GetCurrentPos() >= self.promptPosEnd
|
return self.GetCurrentPos() >= self.promptPosEnd
|
||||||
|
|
||||||
def Cut(self):
|
def Cut(self):
|
||||||
@@ -932,6 +963,20 @@ class Shell(wxStyledTextCtrl):
|
|||||||
self.processLine()
|
self.processLine()
|
||||||
wxTheClipboard.Close()
|
wxTheClipboard.Close()
|
||||||
|
|
||||||
|
def wrap(self, wrap=1):
|
||||||
|
"""Sets whether text is word wrapped."""
|
||||||
|
try:
|
||||||
|
self.SetWrapMode(wrap)
|
||||||
|
except AttributeError:
|
||||||
|
return 'Wrapping is not available in this version of PyCrust.'
|
||||||
|
|
||||||
|
def zoom(self, points=0):
|
||||||
|
"""Set the zoom level.
|
||||||
|
|
||||||
|
This number of points is added to the size of all fonts.
|
||||||
|
It may be positive to magnify or negative to reduce."""
|
||||||
|
self.SetZoom(points)
|
||||||
|
|
||||||
|
|
||||||
wxID_SELECTALL = NewId() # This *should* be defined by wxPython.
|
wxID_SELECTALL = NewId() # This *should* be defined by wxPython.
|
||||||
ID_AUTOCOMP = NewId()
|
ID_AUTOCOMP = NewId()
|
||||||
@@ -1124,19 +1169,18 @@ class ShellFrame(wxFrame, ShellMenu):
|
|||||||
intro += '\nSponsored by Orbtech - Your source for Python programming expertise.'
|
intro += '\nSponsored by Orbtech - Your source for Python programming expertise.'
|
||||||
self.CreateStatusBar()
|
self.CreateStatusBar()
|
||||||
self.SetStatusText(intro.replace('\n', ', '))
|
self.SetStatusText(intro.replace('\n', ', '))
|
||||||
|
|
||||||
import os
|
|
||||||
filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico')
|
filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico')
|
||||||
icon = wxIcon(filename, wxBITMAP_TYPE_ICO)
|
icon = wxIcon(filename, wxBITMAP_TYPE_ICO)
|
||||||
self.SetIcon(icon)
|
self.SetIcon(icon)
|
||||||
|
|
||||||
self.shell = Shell(parent=self, id=-1, introText=intro, \
|
self.shell = Shell(parent=self, id=-1, introText=intro, \
|
||||||
locals=locals, InterpClass=InterpClass, \
|
locals=locals, InterpClass=InterpClass, \
|
||||||
*args, **kwds)
|
*args, **kwds)
|
||||||
# Override the shell so that status messages go to the status bar.
|
# Override the shell so that status messages go to the status bar.
|
||||||
self.shell.setStatusText = self.SetStatusText
|
self.shell.setStatusText = self.SetStatusText
|
||||||
self.createMenus()
|
self.createMenus()
|
||||||
|
EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.shell.destroy()
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user