Updated PyCrust
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@18266 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -4,20 +4,21 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from wxPython.wx import *
|
||||
from wxPython import wx
|
||||
from crust import CrustFrame
|
||||
|
||||
True, False = 1, 0
|
||||
|
||||
class App(wxApp):
|
||||
|
||||
class App(wx.wxApp):
|
||||
"""PyCrust standalone application."""
|
||||
|
||||
def OnInit(self):
|
||||
wxInitAllImageHandlers()
|
||||
wx.wxInitAllImageHandlers()
|
||||
locals = {'__app__': 'PyCrust Standalone Application'}
|
||||
self.crustFrame = CrustFrame(locals=locals)
|
||||
self.crustFrame.SetSize((750, 525))
|
||||
self.crustFrame.Show(true)
|
||||
self.crustFrame.crust.shell.SetFocus()
|
||||
self.crustFrame.Show(True)
|
||||
self.SetTopWindow(self.crustFrame)
|
||||
# Add the application object to the sys module's namespace.
|
||||
# This allows a shell user to do:
|
||||
@@ -25,11 +26,11 @@ class App(wxApp):
|
||||
# >>> sys.application.whatever
|
||||
import sys
|
||||
sys.application = self
|
||||
return true
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
application = App(1)
|
||||
application = App(0)
|
||||
application.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@@ -4,32 +4,34 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from wxPython.wx import *
|
||||
from wxPython import wx
|
||||
from shell import ShellFrame
|
||||
|
||||
True, False = 1, 0
|
||||
|
||||
class App(wxApp):
|
||||
|
||||
class App(wx.wxApp):
|
||||
"""PyShell standalone application."""
|
||||
|
||||
def OnInit(self):
|
||||
wxInitAllImageHandlers()
|
||||
wx.wxInitAllImageHandlers()
|
||||
locals = {'__app__': 'PyShell Standalone Application'}
|
||||
self.shellFrame = ShellFrame(locals=locals)
|
||||
self.shellFrame.SetSize((750, 525))
|
||||
self.shellFrame.Show(true)
|
||||
self.shellFrame.shell.SetFocus()
|
||||
self.shellFrame.Show(True)
|
||||
self.SetTopWindow(self.shellFrame)
|
||||
self.shellFrame.shell.SetFocus()
|
||||
# Add the application object to the sys module's namespace.
|
||||
# This allows a shell user to do:
|
||||
# >>> import sys
|
||||
# >>> sys.application.whatever
|
||||
import sys
|
||||
sys.application = self
|
||||
return true
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
application = App(1)
|
||||
application = App(0)
|
||||
application.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@@ -4,31 +4,32 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from wxPython.wx import *
|
||||
from shell import Shell
|
||||
from wxPython import wx
|
||||
from filling import Filling
|
||||
from version import VERSION
|
||||
import os
|
||||
from shell import Shell
|
||||
from shellmenu import ShellMenu
|
||||
from version import VERSION
|
||||
|
||||
|
||||
class Crust(wxSplitterWindow):
|
||||
class Crust(wx.wxSplitterWindow):
|
||||
"""PyCrust Crust based on wxSplitterWindow."""
|
||||
|
||||
name = 'PyCrust Crust'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||
size=wxDefaultSize, style=wxSP_3D, name='Crust Window', \
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=1, \
|
||||
intro='', locals=None, \
|
||||
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
|
||||
size=wx.wxDefaultSize, style=wx.wxSP_3D, name='Crust Window',
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=1,
|
||||
intro='', locals=None,
|
||||
InterpClass=None, *args, **kwds):
|
||||
"""Create a PyCrust Crust instance."""
|
||||
wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
|
||||
self.shell = Shell(parent=self, introText=intro, \
|
||||
locals=locals, InterpClass=InterpClass, \
|
||||
wx.wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
|
||||
self.shell = Shell(parent=self, introText=intro,
|
||||
locals=locals, InterpClass=InterpClass,
|
||||
*args, **kwds)
|
||||
self.filling = Filling(parent=self, \
|
||||
rootObject=self.shell.interp.locals, \
|
||||
self.filling = Filling(parent=self,
|
||||
rootObject=self.shell.interp.locals,
|
||||
rootLabel=rootLabel, rootIsNamespace=1)
|
||||
"""Add 'filling' to the interpreter's locals."""
|
||||
self.shell.interp.locals['filling'] = self.filling
|
||||
@@ -36,33 +37,30 @@ class Crust(wxSplitterWindow):
|
||||
self.SetMinimumPaneSize(1)
|
||||
|
||||
|
||||
# Temporary hack to share menus between PyCrust and PyShell.
|
||||
from shell import ShellMenu
|
||||
|
||||
class CrustFrame(wxFrame, ShellMenu):
|
||||
class CrustFrame(wx.wxFrame, ShellMenu):
|
||||
"""Frame containing all the PyCrust components."""
|
||||
|
||||
name = 'PyCrust Frame'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyCrust', \
|
||||
pos=wxDefaultPosition, size=wxDefaultSize, \
|
||||
style=wxDEFAULT_FRAME_STYLE, \
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=1, \
|
||||
def __init__(self, parent=None, id=-1, title='PyCrust',
|
||||
pos=wx.wxDefaultPosition, size=wx.wxDefaultSize,
|
||||
style=wx.wxDEFAULT_FRAME_STYLE,
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=1,
|
||||
locals=None, InterpClass=None, *args, **kwds):
|
||||
"""Create a PyCrust CrustFrame instance."""
|
||||
wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||
wx.wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||
intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
|
||||
intro += '\nSponsored by Orbtech - Your source for Python programming expertise.'
|
||||
self.CreateStatusBar()
|
||||
self.SetStatusText(intro.replace('\n', ', '))
|
||||
import images
|
||||
self.SetIcon(images.getPyCrustIcon())
|
||||
self.crust = Crust(parent=self, intro=intro, \
|
||||
rootObject=rootObject, \
|
||||
rootLabel=rootLabel, \
|
||||
rootIsNamespace=rootIsNamespace, \
|
||||
locals=locals, \
|
||||
self.crust = Crust(parent=self, intro=intro,
|
||||
rootObject=rootObject,
|
||||
rootLabel=rootLabel,
|
||||
rootIsNamespace=rootIsNamespace,
|
||||
locals=locals,
|
||||
InterpClass=InterpClass, *args, **kwds)
|
||||
# Override the filling so that status messages go to the status bar.
|
||||
self.crust.filling.fillingTree.setStatusText = self.SetStatusText
|
||||
@@ -75,7 +73,7 @@ class CrustFrame(wxFrame, ShellMenu):
|
||||
# Temporary hack to share menus between PyCrust and PyShell.
|
||||
self.shell = self.crust.shell
|
||||
self.createMenus()
|
||||
EVT_CLOSE(self, self.OnCloseWindow)
|
||||
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||
|
||||
def OnCloseWindow(self, event):
|
||||
self.crust.shell.destroy()
|
||||
|
@@ -5,8 +5,8 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from wxPython.wx import *
|
||||
from wxPython.stc import *
|
||||
from wxPython import wx
|
||||
from wxPython import stc
|
||||
from version import VERSION
|
||||
import inspect
|
||||
import introspect
|
||||
@@ -14,6 +14,8 @@ import keyword
|
||||
import sys
|
||||
import types
|
||||
|
||||
True, False = 1, 0
|
||||
|
||||
COMMONTYPES = [getattr(types, t) for t in dir(types) \
|
||||
if not t.startswith('_') \
|
||||
and t not in ('ClassType', 'InstanceType', 'ModuleType')]
|
||||
@@ -23,40 +25,40 @@ except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
class FillingTree(wxTreeCtrl):
|
||||
class FillingTree(wx.wxTreeCtrl):
|
||||
"""PyCrust FillingTree based on wxTreeCtrl."""
|
||||
|
||||
name = 'PyCrust Filling Tree'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||
size=wxDefaultSize, style=wxTR_HAS_BUTTONS, \
|
||||
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
|
||||
size=wx.wxDefaultSize, style=wx.wxTR_HAS_BUTTONS,
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=0):
|
||||
"""Create a PyCrust FillingTree instance."""
|
||||
wxTreeCtrl.__init__(self, parent, id, pos, size)
|
||||
wx.wxTreeCtrl.__init__(self, parent, id, pos, size)
|
||||
self.rootIsNamespace = rootIsNamespace
|
||||
if not rootObject:
|
||||
import __main__
|
||||
rootObject = __main__
|
||||
self.rootIsNamespace = 1
|
||||
if not rootLabel: rootLabel = 'Ingredients'
|
||||
rootData = wxTreeItemData(rootObject)
|
||||
rootData = wx.wxTreeItemData(rootObject)
|
||||
self.root = self.AddRoot(rootLabel, -1, -1, rootData)
|
||||
self.SetItemHasChildren(self.root, self.hasChildren(self.root))
|
||||
EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
|
||||
EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
|
||||
EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
|
||||
wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
|
||||
wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
|
||||
wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
|
||||
|
||||
def hasChildren(self, o):
|
||||
"""Return true if object has children."""
|
||||
if self.getChildren(o):
|
||||
return true
|
||||
return True
|
||||
else:
|
||||
return false
|
||||
return False
|
||||
|
||||
def getChildren(self, o):
|
||||
"""Return a dictionary with the attributes or contents of object."""
|
||||
busy = wxBusyCursor()
|
||||
busy = wx.wxBusyCursor()
|
||||
otype = type(o)
|
||||
if (otype is types.DictType) \
|
||||
or str(otype)[17:23] == 'BTrees' and hasattr(o, 'keys'):
|
||||
@@ -78,7 +80,7 @@ class FillingTree(wxTreeCtrl):
|
||||
return d
|
||||
|
||||
def OnItemExpanding(self, event):
|
||||
busy = wxBusyCursor()
|
||||
busy = wx.wxBusyCursor()
|
||||
selection = event.GetItem()
|
||||
if self.IsExpanded(selection):
|
||||
return
|
||||
@@ -100,18 +102,18 @@ class FillingTree(wxTreeCtrl):
|
||||
and (selection != self.root \
|
||||
or (selection == self.root and not self.rootIsNamespace)):
|
||||
itemtext = repr(item)
|
||||
child = self.AppendItem(selection, itemtext, -1, -1, \
|
||||
wxTreeItemData(children[item]))
|
||||
child = self.AppendItem(selection, itemtext, -1, -1,
|
||||
wx.wxTreeItemData(children[item]))
|
||||
self.SetItemHasChildren(child, self.hasChildren(children[item]))
|
||||
|
||||
def OnItemCollapsed(self, event):
|
||||
"""Remove all children from the item."""
|
||||
busy = wxBusyCursor()
|
||||
busy = wx.wxBusyCursor()
|
||||
item = event.GetItem()
|
||||
self.DeleteChildren(item)
|
||||
|
||||
def OnSelChanged(self, event):
|
||||
busy = wxBusyCursor()
|
||||
busy = wx.wxBusyCursor()
|
||||
item = event.GetItem()
|
||||
if item == self.root:
|
||||
self.setText('')
|
||||
@@ -189,7 +191,7 @@ class FillingTree(wxTreeCtrl):
|
||||
print text
|
||||
|
||||
|
||||
if wxPlatform == '__WXMSW__':
|
||||
if wx.wxPlatform == '__WXMSW__':
|
||||
faces = { 'times' : 'Times New Roman',
|
||||
'mono' : 'Courier New',
|
||||
'helv' : 'Lucida Console',
|
||||
@@ -201,8 +203,8 @@ if wxPlatform == '__WXMSW__':
|
||||
}
|
||||
# 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.
|
||||
if ((wxMAJOR_VERSION, wxMINOR_VERSION) == (2, 3) and wxRELEASE_NUMBER < 2) \
|
||||
or (wxMAJOR_VERSION <= 2 and wxMINOR_VERSION <= 2):
|
||||
if ((wx.wxMAJOR_VERSION, wx.wxMINOR_VERSION) == (2, 3) and wx.wxRELEASE_NUMBER < 2) \
|
||||
or (wx.wxMAJOR_VERSION <= 2 and wx.wxMINOR_VERSION <= 2):
|
||||
faces['size'] -= 2
|
||||
faces['lnsize'] -= 2
|
||||
else: # GTK
|
||||
@@ -216,16 +218,16 @@ else: # GTK
|
||||
}
|
||||
|
||||
|
||||
class FillingText(wxStyledTextCtrl):
|
||||
class FillingText(stc.wxStyledTextCtrl):
|
||||
"""PyCrust FillingText based on wxStyledTextCtrl."""
|
||||
|
||||
name = 'PyCrust Filling Text'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||
size=wxDefaultSize, style=wxCLIP_CHILDREN):
|
||||
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
|
||||
size=wx.wxDefaultSize, style=wx.wxCLIP_CHILDREN):
|
||||
"""Create a PyCrust FillingText instance."""
|
||||
wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
|
||||
stc.wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
|
||||
# Configure various defaults and user preferences.
|
||||
self.config()
|
||||
|
||||
@@ -233,7 +235,7 @@ class FillingText(wxStyledTextCtrl):
|
||||
"""Configure shell based on user preferences."""
|
||||
self.SetMarginWidth(1, 0)
|
||||
|
||||
self.SetLexer(wxSTC_LEX_PYTHON)
|
||||
self.SetLexer(stc.wxSTC_LEX_PYTHON)
|
||||
self.SetKeyWords(0, ' '.join(keyword.kwlist))
|
||||
|
||||
self.setStyles(faces)
|
||||
@@ -250,51 +252,51 @@ class FillingText(wxStyledTextCtrl):
|
||||
"""Configure font size, typeface and color for lexer."""
|
||||
|
||||
# Default style
|
||||
self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
|
||||
|
||||
self.StyleClearAll()
|
||||
|
||||
# Built in styles
|
||||
self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
|
||||
self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88")
|
||||
self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88")
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88")
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88")
|
||||
|
||||
# Python styles
|
||||
self.StyleSetSpec(wxSTC_P_DEFAULT, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_NUMBER, "")
|
||||
self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold")
|
||||
self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000")
|
||||
self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8")
|
||||
self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold")
|
||||
self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold")
|
||||
self.StyleSetSpec(wxSTC_P_OPERATOR, "")
|
||||
self.StyleSetSpec(wxSTC_P_IDENTIFIER, "")
|
||||
self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F")
|
||||
self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_DEFAULT, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_NUMBER, "")
|
||||
self.StyleSetSpec(stc.wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_WORD, "fore:#00007F,bold")
|
||||
self.StyleSetSpec(stc.wxSTC_P_TRIPLE, "fore:#7F0000")
|
||||
self.StyleSetSpec(stc.wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8")
|
||||
self.StyleSetSpec(stc.wxSTC_P_CLASSNAME, "fore:#0000FF,bold")
|
||||
self.StyleSetSpec(stc.wxSTC_P_DEFNAME, "fore:#007F7F,bold")
|
||||
self.StyleSetSpec(stc.wxSTC_P_OPERATOR, "")
|
||||
self.StyleSetSpec(stc.wxSTC_P_IDENTIFIER, "")
|
||||
self.StyleSetSpec(stc.wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F")
|
||||
self.StyleSetSpec(stc.wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
|
||||
|
||||
def SetText(self, *args, **kwds):
|
||||
self.SetReadOnly(0)
|
||||
wxStyledTextCtrl.SetText(self, *args, **kwds)
|
||||
stc.wxStyledTextCtrl.SetText(self, *args, **kwds)
|
||||
self.SetReadOnly(1)
|
||||
|
||||
|
||||
class Filling(wxSplitterWindow):
|
||||
class Filling(wx.wxSplitterWindow):
|
||||
"""PyCrust Filling based on wxSplitterWindow."""
|
||||
|
||||
name = 'PyCrust Filling'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||
size=wxDefaultSize, style=wxSP_3D, name='Filling Window', \
|
||||
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
|
||||
size=wx.wxDefaultSize, style=wx.wxSP_3D, name='Filling Window',
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=0):
|
||||
"""Create a PyCrust Filling instance."""
|
||||
wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
|
||||
self.fillingTree = FillingTree(parent=self, rootObject=rootObject, \
|
||||
rootLabel=rootLabel, \
|
||||
wx.wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
|
||||
self.fillingTree = FillingTree(parent=self, rootObject=rootObject,
|
||||
rootLabel=rootLabel,
|
||||
rootIsNamespace=rootIsNamespace)
|
||||
self.fillingText = FillingText(parent=self)
|
||||
self.SplitVertically(self.fillingTree, self.fillingText, 200)
|
||||
@@ -305,41 +307,41 @@ class Filling(wxSplitterWindow):
|
||||
self.fillingTree.SelectItem(self.fillingTree.root)
|
||||
|
||||
|
||||
class FillingFrame(wxFrame):
|
||||
class FillingFrame(wx.wxFrame):
|
||||
"""Frame containing the PyCrust filling, or namespace tree component."""
|
||||
|
||||
name = 'PyCrust Filling Frame'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyFilling', \
|
||||
pos=wxDefaultPosition, size=wxDefaultSize, \
|
||||
style=wxDEFAULT_FRAME_STYLE, rootObject=None, \
|
||||
def __init__(self, parent=None, id=-1, title='PyFilling',
|
||||
pos=wx.wxDefaultPosition, size=wx.wxDefaultSize,
|
||||
style=wx.wxDEFAULT_FRAME_STYLE, rootObject=None,
|
||||
rootLabel=None, rootIsNamespace=0):
|
||||
"""Create a PyCrust FillingFrame instance."""
|
||||
wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||
wx.wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||
intro = 'Welcome To PyFilling - The Tastiest Namespace Inspector'
|
||||
self.CreateStatusBar()
|
||||
self.SetStatusText(intro)
|
||||
if wxPlatform == '__WXMSW__':
|
||||
if wx.wxPlatform == '__WXMSW__':
|
||||
import os
|
||||
filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico')
|
||||
icon = wxIcon(filename, wxBITMAP_TYPE_ICO)
|
||||
icon = wx.wxIcon(filename, wx.wxBITMAP_TYPE_ICO)
|
||||
self.SetIcon(icon)
|
||||
self.filling = Filling(parent=self, rootObject=rootObject, \
|
||||
rootLabel=rootLabel, \
|
||||
self.filling = Filling(parent=self, rootObject=rootObject,
|
||||
rootLabel=rootLabel,
|
||||
rootIsNamespace=rootIsNamespace)
|
||||
# Override the filling so that status messages go to the status bar.
|
||||
self.filling.fillingTree.setStatusText = self.SetStatusText
|
||||
|
||||
|
||||
class App(wxApp):
|
||||
class App(wx.wxApp):
|
||||
"""PyFilling standalone application."""
|
||||
|
||||
def OnInit(self):
|
||||
self.fillingFrame = FillingFrame()
|
||||
self.fillingFrame.Show(true)
|
||||
self.fillingFrame.Show(True)
|
||||
self.SetTopWindow(self.fillingFrame)
|
||||
return true
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
@@ -15,7 +15,7 @@ class Interpreter(InteractiveInterpreter):
|
||||
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, locals=None, rawin=None, \
|
||||
def __init__(self, locals=None, rawin=None,
|
||||
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
|
||||
"""Create an interactive interpreter object."""
|
||||
InteractiveInterpreter.__init__(self, locals=locals)
|
||||
@@ -27,7 +27,7 @@ class Interpreter(InteractiveInterpreter):
|
||||
__builtin__.raw_input = rawin
|
||||
del __builtin__
|
||||
copyright = \
|
||||
'Type "copyright", "credits" or "license" for more information.'
|
||||
'Type "help", "copyright", "credits" or "license" for more information.'
|
||||
self.introText = 'Python %s on %s%s%s' % \
|
||||
(sys.version, sys.platform, os.linesep, copyright)
|
||||
try:
|
||||
@@ -98,10 +98,10 @@ class Interpreter(InteractiveInterpreter):
|
||||
class InterpreterAlaCarte(Interpreter):
|
||||
"""PyCrustAlaCarte Demo Interpreter."""
|
||||
|
||||
def __init__(self, locals, rawin, stdin, stdout, stderr, \
|
||||
def __init__(self, locals, rawin, stdin, stdout, stderr,
|
||||
ps1='main prompt', ps2='continuation prompt'):
|
||||
"""Create an interactive interpreter object."""
|
||||
Interpreter.__init__(self, locals=locals, rawin=rawin, \
|
||||
Interpreter.__init__(self, locals=locals, rawin=rawin,
|
||||
stdin=stdin, stdout=stdout, stderr=stderr)
|
||||
sys.ps1 = ps1
|
||||
sys.ps2 = ps2
|
||||
|
@@ -5,11 +5,15 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from __future__ import nested_scopes
|
||||
|
||||
import cStringIO
|
||||
import inspect
|
||||
import string
|
||||
import tokenize
|
||||
import types
|
||||
|
||||
def getAutoCompleteList(command='', locals=None, includeMagic=1, \
|
||||
def getAutoCompleteList(command='', locals=None, includeMagic=1,
|
||||
includeSingle=1, includeDouble=1):
|
||||
"""Return list of auto-completion options for command.
|
||||
|
||||
@@ -25,7 +29,7 @@ def getAutoCompleteList(command='', locals=None, includeMagic=1, \
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
attributes = getAttributeNames(object, includeMagic, \
|
||||
attributes = getAttributeNames(object, includeMagic,
|
||||
includeSingle, includeDouble)
|
||||
return attributes
|
||||
|
||||
@@ -36,8 +40,8 @@ def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1):
|
||||
if not hasattrAlwaysReturnsTrue(object):
|
||||
# Add some attributes that don't always get picked up.
|
||||
# If they don't apply, they'll get filtered out at the end.
|
||||
attributes += ['__bases__', '__class__', '__dict__', '__name__', \
|
||||
'func_closure', 'func_code', 'func_defaults', \
|
||||
attributes += ['__bases__', '__class__', '__dict__', '__name__',
|
||||
'func_closure', 'func_code', 'func_defaults',
|
||||
'func_dict', 'func_doc', 'func_globals', 'func_name']
|
||||
if includeMagic:
|
||||
try: attributes += object._getAttributeNames()
|
||||
@@ -182,37 +186,83 @@ def getRoot(command, terminator=None):
|
||||
Return only the root portion that can be eval()'d without side effects.
|
||||
The command would normally terminate with a "(" or ".". The terminator
|
||||
and anything after the terminator will be dropped."""
|
||||
root = ''
|
||||
validChars = "._" + string.uppercase + string.lowercase + string.digits
|
||||
emptyTypes = ("''", '""', '""""""', "''''''", '[]', '()', '{}')
|
||||
validSeparators = string.whitespace + ',+-*/=%<>&|^~:([{'
|
||||
# Drop the final terminator and anything that follows.
|
||||
command = rtrimTerminus(command, terminator)
|
||||
if len(command) == 0:
|
||||
root = ''
|
||||
elif command in emptyTypes and terminator in ('.', '', None):
|
||||
# Let empty type delimiter pairs go through.
|
||||
root = command
|
||||
else:
|
||||
# Go backward through the command until we hit an "invalid" character.
|
||||
i = len(command)
|
||||
while i and command[i-1] in validChars:
|
||||
i -= 1
|
||||
# Default to everything from the "invalid" character to the end.
|
||||
root = command[i:]
|
||||
# Override certain exceptions.
|
||||
if i > 0 and command[i-1] in ("'", '"'):
|
||||
# Detect situations where we are in the middle of a string.
|
||||
# This code catches the simplest case, but needs to catch others.
|
||||
root = ''
|
||||
elif ((2 <= i < len(command) and command[i] == '.') \
|
||||
or (2 <= i <= len(command) and terminator in ('.', '', None))) \
|
||||
and command[i-2:i] in emptyTypes:
|
||||
# Allow empty types to get through.
|
||||
# Don't confuse an empty tupple with an argumentless callable.
|
||||
if i == 2 or (i >= 3 and command[i-3] in validSeparators):
|
||||
root = command[i-2:]
|
||||
return root
|
||||
command = command.rstrip()
|
||||
tokens = getTokens(command)
|
||||
tokens.reverse()
|
||||
line = ''
|
||||
start = None
|
||||
prefix = ''
|
||||
laststring = '.'
|
||||
emptyTypes = ('[]', '()', '{}')
|
||||
for token in tokens:
|
||||
tokentype = token[0]
|
||||
tokenstring = token[1]
|
||||
line = token[4]
|
||||
if tokentype is tokenize.ENDMARKER:
|
||||
continue
|
||||
if tokentype in (tokenize.NAME, tokenize.STRING, tokenize.NUMBER) \
|
||||
and laststring != '.':
|
||||
# We've reached something that's not part of the root.
|
||||
if prefix and line[token[3][1]] != ' ':
|
||||
# If it doesn't have a space after it, remove the prefix.
|
||||
prefix = ''
|
||||
break
|
||||
if tokentype in (tokenize.NAME, tokenize.STRING, tokenize.NUMBER) \
|
||||
or (tokentype is tokenize.OP and tokenstring == '.'):
|
||||
if prefix:
|
||||
# The prefix isn't valid because it comes after a dot.
|
||||
prefix = ''
|
||||
break
|
||||
else:
|
||||
# start represents the last known good point in the line.
|
||||
start = token[2][1]
|
||||
elif tokenstring in ('[({])}'):
|
||||
# Remember, we're working backwords.
|
||||
# So prefix += tokenstring would be wrong.
|
||||
if prefix in emptyTypes and tokenstring in ('[({'):
|
||||
# We've already got an empty type identified so now we are in
|
||||
# a nested situation and we can break out with what we've got.
|
||||
break
|
||||
else:
|
||||
prefix = tokenstring + prefix
|
||||
else:
|
||||
# We've reached something that's not part of the root.
|
||||
break
|
||||
laststring = tokenstring
|
||||
if start is None:
|
||||
start = len(line)
|
||||
root = line[start:]
|
||||
if prefix in emptyTypes:
|
||||
# Empty types are safe to be eval()'d and introspected.
|
||||
root = prefix + root
|
||||
return root
|
||||
|
||||
def getTokens(command):
|
||||
"""Return list of token tuples for command."""
|
||||
command = str(command) # In case the command is unicode, which won't work.
|
||||
f = cStringIO.StringIO(command)
|
||||
# tokens is a list of token tuples, each looking like:
|
||||
# (type, string, (srow, scol), (erow, ecol), line)
|
||||
tokens = []
|
||||
# Can't use list comprehension:
|
||||
# tokens = [token for token in tokenize.generate_tokens(f.readline)]
|
||||
# because of need to append as much as possible before TokenError.
|
||||
try:
|
||||
## This code wasn't backward compatible with Python 2.1.3.
|
||||
##
|
||||
## for token in tokenize.generate_tokens(f.readline):
|
||||
## tokens.append(token)
|
||||
|
||||
# This works with Python 2.1.3 (with nested_scopes).
|
||||
def eater(*args):
|
||||
tokens.append(args)
|
||||
tokenize.tokenize_loop(f.readline, eater)
|
||||
except tokenize.TokenError:
|
||||
# This is due to a premature EOF, which we expect since
|
||||
# we are feeding in fragments of Python code.
|
||||
pass
|
||||
return tokens
|
||||
|
||||
def rtrimTerminus(command, terminator=None):
|
||||
"""Return command minus the final terminator and anything that follows."""
|
||||
|
@@ -64,11 +64,13 @@ class PseudoFile:
|
||||
|
||||
class PseudoFileIn(PseudoFile):
|
||||
|
||||
def __init__(self, readline):
|
||||
def __init__(self, readline, readlines=None):
|
||||
if callable(readline):
|
||||
self.readline = readline
|
||||
else:
|
||||
raise ValueError, 'readline must be callable'
|
||||
if callable(readlines):
|
||||
self.readlines = readlines
|
||||
|
||||
def isatty(self):
|
||||
return 1
|
||||
|
@@ -8,21 +8,26 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from wxPython.wx import *
|
||||
from wxPython.stc import *
|
||||
from wxPython import wx
|
||||
from wxPython import stc
|
||||
import keyword
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from pseudo import PseudoFileIn
|
||||
from pseudo import PseudoFileOut
|
||||
from pseudo import PseudoFileErr
|
||||
from shellmenu import ShellMenu
|
||||
from version import VERSION
|
||||
|
||||
True, False = 1, 0
|
||||
|
||||
sys.ps3 = '<-- ' # Input prompt.
|
||||
|
||||
NAVKEYS = (WXK_END, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, WXK_PRIOR, WXK_NEXT)
|
||||
NAVKEYS = (wx.WXK_END, wx.WXK_LEFT, wx.WXK_RIGHT,
|
||||
wx.WXK_UP, wx.WXK_DOWN, wx.WXK_PRIOR, wx.WXK_NEXT)
|
||||
|
||||
if wxPlatform == '__WXMSW__':
|
||||
if wx.wxPlatform == '__WXMSW__':
|
||||
faces = { 'times' : 'Times New Roman',
|
||||
'mono' : 'Courier New',
|
||||
'helv' : 'Lucida Console',
|
||||
@@ -32,11 +37,6 @@ if wxPlatform == '__WXMSW__':
|
||||
'lnsize' : 9,
|
||||
'backcol': '#FFFFFF',
|
||||
}
|
||||
# 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.
|
||||
if (wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER) < (2, 3, 2):
|
||||
faces['size'] -= 2
|
||||
faces['lnsize'] -= 2
|
||||
else: # GTK
|
||||
faces = { 'times' : 'Times',
|
||||
'mono' : 'Courier',
|
||||
@@ -48,10 +48,42 @@ else: # GTK
|
||||
}
|
||||
|
||||
|
||||
class ShellFrame(wx.wxFrame, ShellMenu):
|
||||
"""Frame containing the PyCrust shell component."""
|
||||
|
||||
name = 'PyCrust Shell Frame'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyShell',
|
||||
pos=wx.wxDefaultPosition, size=wx.wxDefaultSize,
|
||||
style=wx.wxDEFAULT_FRAME_STYLE, locals=None,
|
||||
InterpClass=None, *args, **kwds):
|
||||
"""Create a PyCrust ShellFrame instance."""
|
||||
wx.wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||
intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
|
||||
intro += '\nSponsored by Orbtech - Your source for Python programming expertise.'
|
||||
self.CreateStatusBar()
|
||||
self.SetStatusText(intro.replace('\n', ', '))
|
||||
filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico')
|
||||
icon = wx.wxIcon(filename, wx.wxBITMAP_TYPE_ICO)
|
||||
self.SetIcon(icon)
|
||||
self.shell = Shell(parent=self, id=-1, introText=intro,
|
||||
locals=locals, InterpClass=InterpClass,
|
||||
*args, **kwds)
|
||||
# Override the shell so that status messages go to the status bar.
|
||||
self.shell.setStatusText = self.SetStatusText
|
||||
self.createMenus()
|
||||
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||
|
||||
def OnCloseWindow(self, event):
|
||||
self.shell.destroy()
|
||||
self.Destroy()
|
||||
|
||||
|
||||
class ShellFacade:
|
||||
"""Simplified interface to all shell-related functionality.
|
||||
|
||||
This is a semi-transparent facade, in that all attributes of other are
|
||||
This is a semi-transparent facade, in that all attributes of other are
|
||||
still accessible, even though only some are visible to the user."""
|
||||
|
||||
name = 'PyCrust Shell Interface'
|
||||
@@ -59,19 +91,21 @@ class ShellFacade:
|
||||
|
||||
def __init__(self, other):
|
||||
"""Create a ShellFacade instance."""
|
||||
methods = ['ask',
|
||||
'clear',
|
||||
'pause',
|
||||
'prompt',
|
||||
'quit',
|
||||
'redirectStderr',
|
||||
'redirectStdin',
|
||||
'redirectStdout',
|
||||
'run',
|
||||
'runfile',
|
||||
'wrap',
|
||||
'zoom',
|
||||
]
|
||||
methods = [
|
||||
'about',
|
||||
'ask',
|
||||
'clear',
|
||||
'pause',
|
||||
'prompt',
|
||||
'quit',
|
||||
'redirectStderr',
|
||||
'redirectStdin',
|
||||
'redirectStdout',
|
||||
'run',
|
||||
'runfile',
|
||||
'wrap',
|
||||
'zoom',
|
||||
]
|
||||
for method in methods:
|
||||
self.__dict__[method] = getattr(other, method)
|
||||
d = self.__dict__
|
||||
@@ -129,17 +163,17 @@ F8 Command-completion of History item.
|
||||
return list
|
||||
|
||||
|
||||
class Shell(wxStyledTextCtrl):
|
||||
class Shell(stc.wxStyledTextCtrl):
|
||||
"""PyCrust Shell based on wxStyledTextCtrl."""
|
||||
|
||||
name = 'PyCrust Shell'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||
size=wxDefaultSize, style=wxCLIP_CHILDREN, introText='', \
|
||||
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
|
||||
size=wx.wxDefaultSize, style=wx.wxCLIP_CHILDREN, introText='',
|
||||
locals=None, InterpClass=None, *args, **kwds):
|
||||
"""Create a PyCrust Shell instance."""
|
||||
wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
|
||||
stc.wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
|
||||
# Grab these so they can be restored by self.redirect* methods.
|
||||
self.stdin = sys.stdin
|
||||
self.stdout = sys.stdout
|
||||
@@ -160,15 +194,15 @@ class Shell(wxStyledTextCtrl):
|
||||
if locals:
|
||||
shellLocals.update(locals)
|
||||
# Create a replacement for stdin.
|
||||
self.reader = PseudoFileIn(self.readline)
|
||||
self.reader = PseudoFileIn(self.readline, self.readlines)
|
||||
self.reader.input = ''
|
||||
self.reader.isreading = 0
|
||||
# Set up the interpreter.
|
||||
self.interp = Interpreter(locals=shellLocals, \
|
||||
rawin=self.raw_input, \
|
||||
stdin=self.reader, \
|
||||
stdout=PseudoFileOut(self.writeOut), \
|
||||
stderr=PseudoFileErr(self.writeErr), \
|
||||
self.interp = Interpreter(locals=shellLocals,
|
||||
rawin=self.raw_input,
|
||||
stdin=self.reader,
|
||||
stdout=PseudoFileOut(self.writeOut),
|
||||
stderr=PseudoFileErr(self.writeErr),
|
||||
*args, **kwds)
|
||||
# Find out for which keycodes the interpreter will autocomplete.
|
||||
self.autoCompleteKeys = self.interp.getAutoCompleteKeys()
|
||||
@@ -186,10 +220,13 @@ class Shell(wxStyledTextCtrl):
|
||||
self.history = []
|
||||
self.historyIndex = -1
|
||||
# Assign handlers for keyboard events.
|
||||
EVT_KEY_DOWN(self, self.OnKeyDown)
|
||||
EVT_CHAR(self, self.OnChar)
|
||||
wx.EVT_KEY_DOWN(self, self.OnKeyDown)
|
||||
wx.EVT_CHAR(self, self.OnChar)
|
||||
# Assign handlers for wxSTC events.
|
||||
EVT_STC_UPDATEUI(self, id, self.OnUpdateUI)
|
||||
stc.EVT_STC_UPDATEUI(self, id, self.OnUpdateUI)
|
||||
# Assign handler for idle time.
|
||||
self.waiting = False
|
||||
wx.EVT_IDLE(self, self.OnIdle)
|
||||
# Configure various defaults and user preferences.
|
||||
self.config()
|
||||
# Display the introductory banner information.
|
||||
@@ -212,10 +249,10 @@ class Shell(wxStyledTextCtrl):
|
||||
|
||||
def config(self):
|
||||
"""Configure shell based on user preferences."""
|
||||
self.SetMarginType(1, wxSTC_MARGIN_NUMBER)
|
||||
self.SetMarginType(1, stc.wxSTC_MARGIN_NUMBER)
|
||||
self.SetMarginWidth(1, 40)
|
||||
|
||||
self.SetLexer(wxSTC_LEX_PYTHON)
|
||||
self.SetLexer(stc.wxSTC_LEX_PYTHON)
|
||||
self.SetKeyWords(0, ' '.join(keyword.kwlist))
|
||||
|
||||
self.setStyles(faces)
|
||||
@@ -231,10 +268,10 @@ class Shell(wxStyledTextCtrl):
|
||||
self.AutoCompSetIgnoreCase(self.autoCompleteCaseInsensitive)
|
||||
# Do we want to automatically pop up command argument help?
|
||||
self.autoCallTip = 1
|
||||
self.CallTipSetBackground(wxColour(255, 255, 232))
|
||||
self.CallTipSetBackground(wx.wxColour(255, 255, 232))
|
||||
self.wrap()
|
||||
try:
|
||||
self.SetEndAtLastLine(false)
|
||||
self.SetEndAtLastLine(False)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
@@ -247,7 +284,7 @@ class Shell(wxStyledTextCtrl):
|
||||
self.write(self.interp.introText)
|
||||
except AttributeError:
|
||||
pass
|
||||
wxCallAfter(self.ScrollToLine, 0)
|
||||
wx.wxCallAfter(self.ScrollToLine, 0)
|
||||
|
||||
def setBuiltinKeywords(self):
|
||||
"""Create pseudo keywords as part of builtins.
|
||||
@@ -286,33 +323,50 @@ class Shell(wxStyledTextCtrl):
|
||||
"""Configure font size, typeface and color for lexer."""
|
||||
|
||||
# Default style
|
||||
self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d,back:%(backcol)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d,back:%(backcol)s" % faces)
|
||||
|
||||
self.StyleClearAll()
|
||||
|
||||
# Built in styles
|
||||
self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
|
||||
self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88")
|
||||
self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88")
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88")
|
||||
self.StyleSetSpec(stc.wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88")
|
||||
|
||||
# Python styles
|
||||
self.StyleSetSpec(wxSTC_P_DEFAULT, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_NUMBER, "")
|
||||
self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold")
|
||||
self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000")
|
||||
self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8")
|
||||
self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold")
|
||||
self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold")
|
||||
self.StyleSetSpec(wxSTC_P_OPERATOR, "")
|
||||
self.StyleSetSpec(wxSTC_P_IDENTIFIER, "")
|
||||
self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F")
|
||||
self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_DEFAULT, "face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_NUMBER, "")
|
||||
self.StyleSetSpec(stc.wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.wxSTC_P_WORD, "fore:#00007F,bold")
|
||||
self.StyleSetSpec(stc.wxSTC_P_TRIPLE, "fore:#7F0000")
|
||||
self.StyleSetSpec(stc.wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8")
|
||||
self.StyleSetSpec(stc.wxSTC_P_CLASSNAME, "fore:#0000FF,bold")
|
||||
self.StyleSetSpec(stc.wxSTC_P_DEFNAME, "fore:#007F7F,bold")
|
||||
self.StyleSetSpec(stc.wxSTC_P_OPERATOR, "")
|
||||
self.StyleSetSpec(stc.wxSTC_P_IDENTIFIER, "")
|
||||
self.StyleSetSpec(stc.wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F")
|
||||
self.StyleSetSpec(stc.wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
|
||||
|
||||
def OnUpdateUI(self, evt):
|
||||
def about(self):
|
||||
"""Display information about PyCrust."""
|
||||
text = """
|
||||
PyCrust Version: %s
|
||||
Shell Revision: %s
|
||||
Interpreter Revision: %s
|
||||
Python Version: %s
|
||||
wxPython Version: %s
|
||||
Platform: %s""" % (VERSION, self.revision, self.interp.revision,
|
||||
sys.version.split()[0], wx.__version__, sys.platform)
|
||||
self.write(text.strip())
|
||||
|
||||
def OnIdle(self, event):
|
||||
"""Free the CPU to do other things."""
|
||||
if self.waiting:
|
||||
time.sleep(0.1)
|
||||
|
||||
def OnUpdateUI(self, event):
|
||||
"""Check for matching braces."""
|
||||
braceAtCaret = -1
|
||||
braceOpposite = -1
|
||||
@@ -328,7 +382,7 @@ class Shell(wxStyledTextCtrl):
|
||||
|
||||
# Check before.
|
||||
if charBefore and chr(charBefore) in '[]{}()' \
|
||||
and styleBefore == wxSTC_P_OPERATOR:
|
||||
and styleBefore == stc.wxSTC_P_OPERATOR:
|
||||
braceAtCaret = caretPos - 1
|
||||
|
||||
# Check after.
|
||||
@@ -340,7 +394,7 @@ class Shell(wxStyledTextCtrl):
|
||||
#***
|
||||
styleAfter = self.GetStyleAt(caretPos)
|
||||
if charAfter and chr(charAfter) in '[]{}()' \
|
||||
and styleAfter == wxSTC_P_OPERATOR:
|
||||
and styleAfter == stc.wxSTC_P_OPERATOR:
|
||||
braceAtCaret = caretPos
|
||||
|
||||
if braceAtCaret >= 0:
|
||||
@@ -353,7 +407,7 @@ class Shell(wxStyledTextCtrl):
|
||||
|
||||
def OnChar(self, event):
|
||||
"""Keypress event handler.
|
||||
|
||||
|
||||
Only receives an event if OnKeyDown calls event.Skip() for
|
||||
the corresponding event."""
|
||||
|
||||
@@ -364,7 +418,7 @@ class Shell(wxStyledTextCtrl):
|
||||
currpos = self.GetCurrentPos()
|
||||
stoppos = self.promptPosEnd
|
||||
# Return (Enter) needs to be ignored in this handler.
|
||||
if key == WXK_RETURN:
|
||||
if key == wx.WXK_RETURN:
|
||||
pass
|
||||
elif key in self.autoCompleteKeys:
|
||||
# Usually the dot (period) key activates auto completion.
|
||||
@@ -399,12 +453,12 @@ class Shell(wxStyledTextCtrl):
|
||||
endpos = self.GetTextLength()
|
||||
selecting = self.GetSelectionStart() != self.GetSelectionEnd()
|
||||
# Return (Enter) is used to submit a command to the interpreter.
|
||||
if not controlDown and key == WXK_RETURN:
|
||||
if not controlDown and key == wx.WXK_RETURN:
|
||||
if self.AutoCompActive(): self.AutoCompCancel()
|
||||
if self.CallTipActive(): self.CallTipCancel()
|
||||
self.processLine()
|
||||
# Ctrl+Return (Cntrl+Enter) is used to insert a line break.
|
||||
elif controlDown and key == WXK_RETURN:
|
||||
elif controlDown and key == wx.WXK_RETURN:
|
||||
if self.AutoCompActive(): self.AutoCompCancel()
|
||||
if self.CallTipActive(): self.CallTipCancel()
|
||||
if currpos == endpos:
|
||||
@@ -418,25 +472,25 @@ class Shell(wxStyledTextCtrl):
|
||||
elif controlDown and altDown:
|
||||
event.Skip()
|
||||
# Clear the current, unexecuted command.
|
||||
elif key == WXK_ESCAPE:
|
||||
elif key == wx.WXK_ESCAPE:
|
||||
if self.CallTipActive():
|
||||
event.Skip()
|
||||
else:
|
||||
self.clearCommand()
|
||||
# Cut to the clipboard.
|
||||
elif (controlDown and key in (ord('X'), ord('x'))) \
|
||||
or (shiftDown and key == WXK_DELETE):
|
||||
or (shiftDown and key == wx.WXK_DELETE):
|
||||
self.Cut()
|
||||
# Copy to the clipboard.
|
||||
elif controlDown and not shiftDown \
|
||||
and key in (ord('C'), ord('c'), WXK_INSERT):
|
||||
and key in (ord('C'), ord('c'), wx.WXK_INSERT):
|
||||
self.Copy()
|
||||
# Copy to the clipboard, including prompts.
|
||||
elif controlDown and shiftDown \
|
||||
and key in (ord('C'), ord('c'), WXK_INSERT):
|
||||
and key in (ord('C'), ord('c'), wx.WXK_INSERT):
|
||||
self.CopyWithPrompts()
|
||||
# Home needs to be aware of the prompt.
|
||||
elif key == WXK_HOME:
|
||||
elif key == wx.WXK_HOME:
|
||||
home = self.promptPosEnd
|
||||
if currpos > home:
|
||||
self.SetCurrentPos(home)
|
||||
@@ -455,41 +509,41 @@ class Shell(wxStyledTextCtrl):
|
||||
# Paste from the clipboard.
|
||||
elif (controlDown and not shiftDown \
|
||||
and key in (ord('V'), ord('v'))) \
|
||||
or (shiftDown and not controlDown and key == WXK_INSERT):
|
||||
or (shiftDown and not controlDown and key == wx.WXK_INSERT):
|
||||
self.Paste()
|
||||
# Paste from the clipboard, run commands.
|
||||
elif controlDown and shiftDown \
|
||||
and key in (ord('V'), ord('v')):
|
||||
self.PasteAndRun()
|
||||
# Replace with the previous command from the history buffer.
|
||||
elif (controlDown and key == WXK_UP) \
|
||||
elif (controlDown and key == wx.WXK_UP) \
|
||||
or (altDown and key in (ord('P'), ord('p'))):
|
||||
self.OnHistoryReplace(step=+1)
|
||||
# Replace with the next command from the history buffer.
|
||||
elif (controlDown and key == WXK_DOWN) \
|
||||
elif (controlDown and key == wx.WXK_DOWN) \
|
||||
or (altDown and key in (ord('N'), ord('n'))):
|
||||
self.OnHistoryReplace(step=-1)
|
||||
# Insert the previous command from the history buffer.
|
||||
elif (shiftDown and key == WXK_UP) and self.CanEdit():
|
||||
elif (shiftDown and key == wx.WXK_UP) and self.CanEdit():
|
||||
self.OnHistoryInsert(step=+1)
|
||||
# Insert the next command from the history buffer.
|
||||
elif (shiftDown and key == WXK_DOWN) and self.CanEdit():
|
||||
elif (shiftDown and key == wx.WXK_DOWN) and self.CanEdit():
|
||||
self.OnHistoryInsert(step=-1)
|
||||
# Search up the history for the text in front of the cursor.
|
||||
elif key == WXK_F8:
|
||||
elif key == wx.WXK_F8:
|
||||
self.OnHistorySearch()
|
||||
# Don't backspace over the latest non-continuation prompt.
|
||||
elif key == WXK_BACK:
|
||||
elif key == wx.WXK_BACK:
|
||||
if selecting and self.CanEdit():
|
||||
event.Skip()
|
||||
elif currpos > self.promptPosEnd:
|
||||
event.Skip()
|
||||
# Only allow these keys after the latest prompt.
|
||||
elif key in (WXK_TAB, WXK_DELETE):
|
||||
elif key in (wx.WXK_TAB, wx.WXK_DELETE):
|
||||
if self.CanEdit():
|
||||
event.Skip()
|
||||
# Don't toggle between insert mode and overwrite mode.
|
||||
elif key == WXK_INSERT:
|
||||
elif key == wx.WXK_INSERT:
|
||||
pass
|
||||
# Don't allow line deletion.
|
||||
elif controlDown and key in (ord('L'), ord('l')):
|
||||
@@ -590,7 +644,7 @@ class Shell(wxStyledTextCtrl):
|
||||
# The user hit ENTER and we need to decide what to do. They could be
|
||||
# sitting on any line in the shell.
|
||||
|
||||
thepos = self.GetCurrentPos()
|
||||
thepos = self.GetCurrentPos()
|
||||
startpos = self.promptPosEnd
|
||||
endpos = self.GetTextLength()
|
||||
# If they hit RETURN inside the current command, execute the command.
|
||||
@@ -685,12 +739,14 @@ class Shell(wxStyledTextCtrl):
|
||||
elif text[:ps2size] == ps2:
|
||||
text = text[ps2size:]
|
||||
return text
|
||||
|
||||
|
||||
def push(self, command):
|
||||
"""Send command to the interpreter for execution."""
|
||||
self.write(os.linesep)
|
||||
busy = wxBusyCursor()
|
||||
busy = wx.wxBusyCursor()
|
||||
self.waiting = True
|
||||
self.more = self.interp.push(command)
|
||||
self.waiting = False
|
||||
del busy
|
||||
if not self.more:
|
||||
self.addHistory(command.rstrip())
|
||||
@@ -765,13 +821,34 @@ class Shell(wxStyledTextCtrl):
|
||||
self.prompt()
|
||||
try:
|
||||
while not reader.input:
|
||||
wxYield()
|
||||
time.sleep(0.1) # Free up the CPU.
|
||||
wx.wxYield()
|
||||
input = reader.input
|
||||
finally:
|
||||
reader.input = ''
|
||||
reader.isreading = 0
|
||||
return input
|
||||
|
||||
def readlines(self):
|
||||
"""Replacement for stdin.readlines()."""
|
||||
lines = []
|
||||
input = ''
|
||||
reader = self.reader
|
||||
reader.isreading = 1
|
||||
try:
|
||||
while lines[-1:] != ['\n']:
|
||||
self.prompt()
|
||||
while not reader.input:
|
||||
time.sleep(0.1) # Free up the CPU.
|
||||
wx.wxYield()
|
||||
input = reader.input
|
||||
lines.append(input)
|
||||
reader.input = ''
|
||||
finally:
|
||||
reader.input = ''
|
||||
reader.isreading = 0
|
||||
return lines
|
||||
|
||||
def raw_input(self, prompt=''):
|
||||
"""Return string based on user input."""
|
||||
if prompt:
|
||||
@@ -780,10 +857,10 @@ class Shell(wxStyledTextCtrl):
|
||||
|
||||
def ask(self, prompt='Please enter your response:'):
|
||||
"""Get response from the user using a dialog box."""
|
||||
dialog = wxTextEntryDialog(None, prompt, \
|
||||
'Input Dialog (Raw)', '')
|
||||
dialog = wx.wxTextEntryDialog(None, prompt,
|
||||
'Input Dialog (Raw)', '')
|
||||
try:
|
||||
if dialog.ShowModal() == wxID_OK:
|
||||
if dialog.ShowModal() == wx.wxID_OK:
|
||||
text = dialog.GetValue()
|
||||
return text
|
||||
finally:
|
||||
@@ -803,11 +880,11 @@ class Shell(wxStyledTextCtrl):
|
||||
>>> shell.run('print "this"')
|
||||
>>> print "this"
|
||||
this
|
||||
>>>
|
||||
>>>
|
||||
"""
|
||||
# Go to the very bottom of the text.
|
||||
endpos = self.GetTextLength()
|
||||
self.SetCurrentPos(endpos)
|
||||
self.SetCurrentPos(endpos)
|
||||
command = command.rstrip()
|
||||
if prompt: self.prompt()
|
||||
if verbose: self.write(command)
|
||||
@@ -828,9 +905,9 @@ class Shell(wxStyledTextCtrl):
|
||||
|
||||
def autoCompleteShow(self, command):
|
||||
"""Display auto-completion popup list."""
|
||||
list = self.interp.getAutoCompleteList(command,
|
||||
includeMagic=self.autoCompleteIncludeMagic,
|
||||
includeSingle=self.autoCompleteIncludeSingle,
|
||||
list = self.interp.getAutoCompleteList(command,
|
||||
includeMagic=self.autoCompleteIncludeMagic,
|
||||
includeSingle=self.autoCompleteIncludeSingle,
|
||||
includeDouble=self.autoCompleteIncludeDouble)
|
||||
if list:
|
||||
options = ' '.join(list)
|
||||
@@ -898,7 +975,7 @@ class Shell(wxStyledTextCtrl):
|
||||
|
||||
def CanPaste(self):
|
||||
"""Return true if a paste should succeed."""
|
||||
if self.CanEdit() and wxStyledTextCtrl.CanPaste(self):
|
||||
if self.CanEdit() and stc.wxStyledTextCtrl.CanPaste(self):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
@@ -929,26 +1006,28 @@ class Shell(wxStyledTextCtrl):
|
||||
command = command.replace(os.linesep + sys.ps2, os.linesep)
|
||||
command = command.replace(os.linesep + sys.ps1, os.linesep)
|
||||
command = self.lstripPrompt(text=command)
|
||||
data = wxTextDataObject(command)
|
||||
if wxTheClipboard.Open():
|
||||
wxTheClipboard.SetData(data)
|
||||
wxTheClipboard.Close()
|
||||
data = wx.wxTextDataObject(command)
|
||||
if wx.wxTheClipboard.Open():
|
||||
wx.wxTheClipboard.UsePrimarySelection(False)
|
||||
wx.wxTheClipboard.SetData(data)
|
||||
wx.wxTheClipboard.Close()
|
||||
|
||||
def CopyWithPrompts(self):
|
||||
"""Copy selection, including prompts, and place it on the clipboard."""
|
||||
if self.CanCopy():
|
||||
command = self.GetSelectedText()
|
||||
data = wxTextDataObject(command)
|
||||
if wxTheClipboard.Open():
|
||||
wxTheClipboard.SetData(data)
|
||||
wxTheClipboard.Close()
|
||||
data = wx.wxTextDataObject(command)
|
||||
if wx.wxTheClipboard.Open():
|
||||
wx.wxTheClipboard.UsePrimarySelection(False)
|
||||
wx.wxTheClipboard.SetData(data)
|
||||
wx.wxTheClipboard.Close()
|
||||
|
||||
def Paste(self):
|
||||
"""Replace selection with clipboard contents."""
|
||||
if self.CanPaste() and wxTheClipboard.Open():
|
||||
if wxTheClipboard.IsSupported(wxDataFormat(wxDF_TEXT)):
|
||||
data = wxTextDataObject()
|
||||
if wxTheClipboard.GetData(data):
|
||||
if self.CanPaste() and wx.wxTheClipboard.Open():
|
||||
if wx.wxTheClipboard.IsSupported(wx.wxDataFormat(wx.wxDF_TEXT)):
|
||||
data = wx.wxTextDataObject()
|
||||
if wx.wxTheClipboard.GetData(data):
|
||||
self.ReplaceSelection('')
|
||||
command = data.GetText()
|
||||
command = command.rstrip()
|
||||
@@ -958,14 +1037,14 @@ class Shell(wxStyledTextCtrl):
|
||||
command = command.replace(os.linesep, '\n')
|
||||
command = command.replace('\n', os.linesep + sys.ps2)
|
||||
self.write(command)
|
||||
wxTheClipboard.Close()
|
||||
wx.wxTheClipboard.Close()
|
||||
|
||||
def PasteAndRun(self):
|
||||
"""Replace selection with clipboard contents, run commands."""
|
||||
if wxTheClipboard.Open():
|
||||
if wxTheClipboard.IsSupported(wxDataFormat(wxDF_TEXT)):
|
||||
data = wxTextDataObject()
|
||||
if wxTheClipboard.GetData(data):
|
||||
if wx.wxTheClipboard.Open():
|
||||
if wx.wxTheClipboard.IsSupported(wx.wxDataFormat(wx.wxDF_TEXT)):
|
||||
data = wx.wxTextDataObject()
|
||||
if wx.wxTheClipboard.GetData(data):
|
||||
endpos = self.GetTextLength()
|
||||
self.SetCurrentPos(endpos)
|
||||
startpos = self.promptPosEnd
|
||||
@@ -994,11 +1073,11 @@ class Shell(wxStyledTextCtrl):
|
||||
command += '\n'
|
||||
command += line
|
||||
commands.append(command)
|
||||
for command in commands:
|
||||
for command in commands:
|
||||
command = command.replace('\n', os.linesep + sys.ps2)
|
||||
self.write(command)
|
||||
self.processLine()
|
||||
wxTheClipboard.Close()
|
||||
wx.wxTheClipboard.Close()
|
||||
|
||||
def wrap(self, wrap=1):
|
||||
"""Sets whether text is word wrapped."""
|
||||
@@ -1009,214 +1088,8 @@ class Shell(wxStyledTextCtrl):
|
||||
|
||||
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.
|
||||
ID_AUTOCOMP = NewId()
|
||||
ID_AUTOCOMP_SHOW = NewId()
|
||||
ID_AUTOCOMP_INCLUDE_MAGIC = NewId()
|
||||
ID_AUTOCOMP_INCLUDE_SINGLE = NewId()
|
||||
ID_AUTOCOMP_INCLUDE_DOUBLE = NewId()
|
||||
ID_CALLTIPS = NewId()
|
||||
ID_CALLTIPS_SHOW = NewId()
|
||||
|
||||
|
||||
class ShellMenu:
|
||||
"""Mixin class to add standard menu items."""
|
||||
|
||||
def createMenus(self):
|
||||
m = self.fileMenu = wxMenu()
|
||||
m.AppendSeparator()
|
||||
m.Append(wxID_EXIT, 'E&xit', 'Exit PyCrust')
|
||||
|
||||
m = self.editMenu = wxMenu()
|
||||
m.Append(wxID_UNDO, '&Undo \tCtrl+Z', 'Undo the last action')
|
||||
m.Append(wxID_REDO, '&Redo \tCtrl+Y', 'Redo the last undone action')
|
||||
m.AppendSeparator()
|
||||
m.Append(wxID_CUT, 'Cu&t \tCtrl+X', 'Cut the selection')
|
||||
m.Append(wxID_COPY, '&Copy \tCtrl+C', 'Copy the selection')
|
||||
m.Append(wxID_PASTE, '&Paste \tCtrl+V', 'Paste')
|
||||
m.AppendSeparator()
|
||||
m.Append(wxID_CLEAR, 'Cle&ar', 'Delete the selection')
|
||||
m.Append(wxID_SELECTALL, 'Select A&ll', 'Select all text')
|
||||
|
||||
m = self.autocompMenu = wxMenu()
|
||||
m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \
|
||||
'Show auto completion during dot syntax', 1)
|
||||
m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \
|
||||
'Include attributes visible to __getattr__ and __setattr__', 1)
|
||||
m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \
|
||||
'Include attibutes prefixed by a single underscore', 1)
|
||||
m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \
|
||||
'Include attibutes prefixed by a double underscore', 1)
|
||||
|
||||
m = self.calltipsMenu = wxMenu()
|
||||
m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \
|
||||
'Show call tips with argument specifications', 1)
|
||||
|
||||
m = self.optionsMenu = wxMenu()
|
||||
m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \
|
||||
'Auto Completion Options')
|
||||
m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu, \
|
||||
'Call Tip Options')
|
||||
|
||||
m = self.helpMenu = wxMenu()
|
||||
m.AppendSeparator()
|
||||
m.Append(wxID_ABOUT, '&About...', 'About PyCrust')
|
||||
|
||||
b = self.menuBar = wxMenuBar()
|
||||
b.Append(self.fileMenu, '&File')
|
||||
b.Append(self.editMenu, '&Edit')
|
||||
b.Append(self.optionsMenu, '&Options')
|
||||
b.Append(self.helpMenu, '&Help')
|
||||
self.SetMenuBar(b)
|
||||
|
||||
EVT_MENU(self, wxID_EXIT, self.OnExit)
|
||||
EVT_MENU(self, wxID_UNDO, self.OnUndo)
|
||||
EVT_MENU(self, wxID_REDO, self.OnRedo)
|
||||
EVT_MENU(self, wxID_CUT, self.OnCut)
|
||||
EVT_MENU(self, wxID_COPY, self.OnCopy)
|
||||
EVT_MENU(self, wxID_PASTE, self.OnPaste)
|
||||
EVT_MENU(self, wxID_CLEAR, self.OnClear)
|
||||
EVT_MENU(self, wxID_SELECTALL, self.OnSelectAll)
|
||||
EVT_MENU(self, wxID_ABOUT, self.OnAbout)
|
||||
EVT_MENU(self, ID_AUTOCOMP_SHOW, \
|
||||
self.OnAutoCompleteShow)
|
||||
EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC, \
|
||||
self.OnAutoCompleteIncludeMagic)
|
||||
EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE, \
|
||||
self.OnAutoCompleteIncludeSingle)
|
||||
EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE, \
|
||||
self.OnAutoCompleteIncludeDouble)
|
||||
EVT_MENU(self, ID_CALLTIPS_SHOW, \
|
||||
self.OnCallTipsShow)
|
||||
|
||||
EVT_UPDATE_UI(self, wxID_UNDO, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, wxID_REDO, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, wxID_CUT, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, wxID_COPY, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, wxID_PASTE, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, wxID_CLEAR, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu)
|
||||
EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu)
|
||||
|
||||
def OnExit(self, event):
|
||||
self.Close(true)
|
||||
|
||||
def OnUndo(self, event):
|
||||
self.shell.Undo()
|
||||
|
||||
def OnRedo(self, event):
|
||||
self.shell.Redo()
|
||||
|
||||
def OnCut(self, event):
|
||||
self.shell.Cut()
|
||||
|
||||
def OnCopy(self, event):
|
||||
self.shell.Copy()
|
||||
|
||||
def OnPaste(self, event):
|
||||
self.shell.Paste()
|
||||
|
||||
def OnClear(self, event):
|
||||
self.shell.Clear()
|
||||
|
||||
def OnSelectAll(self, event):
|
||||
self.shell.SelectAll()
|
||||
|
||||
def OnAbout(self, event):
|
||||
"""Display an About PyCrust window."""
|
||||
import sys
|
||||
title = 'About PyCrust'
|
||||
text = 'PyCrust %s\n\n' % VERSION + \
|
||||
'Yet another Python shell, only flakier.\n\n' + \
|
||||
'Half-baked by Patrick K. O\'Brien,\n' + \
|
||||
'the other half is still in the oven.\n\n' + \
|
||||
'Shell Revision: %s\n' % self.shell.revision + \
|
||||
'Interpreter Revision: %s\n\n' % self.shell.interp.revision + \
|
||||
'Python Version: %s\n' % sys.version.split()[0] + \
|
||||
'wxPython Version: %s\n' % wx.__version__ + \
|
||||
'Platform: %s\n' % sys.platform
|
||||
dialog = wxMessageDialog(self, text, title, wxOK | wxICON_INFORMATION)
|
||||
dialog.ShowModal()
|
||||
dialog.Destroy()
|
||||
|
||||
def OnAutoCompleteShow(self, event):
|
||||
self.shell.autoComplete = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteIncludeMagic(self, event):
|
||||
self.shell.autoCompleteIncludeMagic = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteIncludeSingle(self, event):
|
||||
self.shell.autoCompleteIncludeSingle = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteIncludeDouble(self, event):
|
||||
self.shell.autoCompleteIncludeDouble = event.IsChecked()
|
||||
|
||||
def OnCallTipsShow(self, event):
|
||||
self.shell.autoCallTip = event.IsChecked()
|
||||
|
||||
def OnUpdateMenu(self, event):
|
||||
"""Update menu items based on current status."""
|
||||
id = event.GetId()
|
||||
if id == wxID_UNDO:
|
||||
event.Enable(self.shell.CanUndo())
|
||||
elif id == wxID_REDO:
|
||||
event.Enable(self.shell.CanRedo())
|
||||
elif id == wxID_CUT:
|
||||
event.Enable(self.shell.CanCut())
|
||||
elif id == wxID_COPY:
|
||||
event.Enable(self.shell.CanCopy())
|
||||
elif id == wxID_PASTE:
|
||||
event.Enable(self.shell.CanPaste())
|
||||
elif id == wxID_CLEAR:
|
||||
event.Enable(self.shell.CanCut())
|
||||
elif id == ID_AUTOCOMP_SHOW:
|
||||
event.Check(self.shell.autoComplete)
|
||||
elif id == ID_AUTOCOMP_INCLUDE_MAGIC:
|
||||
event.Check(self.shell.autoCompleteIncludeMagic)
|
||||
elif id == ID_AUTOCOMP_INCLUDE_SINGLE:
|
||||
event.Check(self.shell.autoCompleteIncludeSingle)
|
||||
elif id == ID_AUTOCOMP_INCLUDE_DOUBLE:
|
||||
event.Check(self.shell.autoCompleteIncludeDouble)
|
||||
elif id == ID_CALLTIPS_SHOW:
|
||||
event.Check(self.shell.autoCallTip)
|
||||
|
||||
|
||||
class ShellFrame(wxFrame, ShellMenu):
|
||||
"""Frame containing the PyCrust shell component."""
|
||||
|
||||
name = 'PyCrust Shell Frame'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyShell', \
|
||||
pos=wxDefaultPosition, size=wxDefaultSize, \
|
||||
style=wxDEFAULT_FRAME_STYLE, locals=None, \
|
||||
InterpClass=None, *args, **kwds):
|
||||
"""Create a PyCrust ShellFrame instance."""
|
||||
wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||
intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
|
||||
intro += '\nSponsored by Orbtech - Your source for Python programming expertise.'
|
||||
self.CreateStatusBar()
|
||||
self.SetStatusText(intro.replace('\n', ', '))
|
||||
import images
|
||||
self.SetIcon(images.getPyCrustIcon())
|
||||
self.shell = Shell(parent=self, id=-1, introText=intro, \
|
||||
locals=locals, InterpClass=InterpClass, \
|
||||
*args, **kwds)
|
||||
# Override the shell so that status messages go to the status bar.
|
||||
self.shell.setStatusText = self.SetStatusText
|
||||
self.createMenus()
|
||||
EVT_CLOSE(self, self.OnCloseWindow)
|
||||
|
||||
def OnCloseWindow(self, event):
|
||||
self.shell.destroy()
|
||||
self.Destroy()
|
||||
|
||||
|
213
wxPython/wxPython/lib/PyCrust/shellmenu.py
Normal file
213
wxPython/wxPython/lib/PyCrust/shellmenu.py
Normal file
@@ -0,0 +1,213 @@
|
||||
"""Shell menu mixin shared by shell and crust."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from wxPython import wx
|
||||
import sys
|
||||
from version import VERSION
|
||||
|
||||
|
||||
True, False = 1, 0
|
||||
|
||||
ID_AUTOCOMP = wx.NewId()
|
||||
ID_AUTOCOMP_SHOW = wx.NewId()
|
||||
ID_AUTOCOMP_INCLUDE_MAGIC = wx.NewId()
|
||||
ID_AUTOCOMP_INCLUDE_SINGLE = wx.NewId()
|
||||
ID_AUTOCOMP_INCLUDE_DOUBLE = wx.NewId()
|
||||
ID_CALLTIPS = wx.NewId()
|
||||
ID_CALLTIPS_SHOW = wx.NewId()
|
||||
ID_COPY_PLUS = wx.NewId()
|
||||
ID_PASTE_PLUS = wx.NewId()
|
||||
ID_WRAP = wx.NewId()
|
||||
|
||||
|
||||
class ShellMenu:
|
||||
"""Mixin class to add standard menu items."""
|
||||
|
||||
def createMenus(self):
|
||||
m = self.fileMenu = wx.wxMenu()
|
||||
m.AppendSeparator()
|
||||
m.Append(wx.wxID_EXIT, 'E&xit', 'Exit PyCrust')
|
||||
|
||||
m = self.editMenu = wx.wxMenu()
|
||||
m.Append(wx.wxID_UNDO, '&Undo \tCtrl+Z', 'Undo the last action')
|
||||
m.Append(wx.wxID_REDO, '&Redo \tCtrl+Y', 'Redo the last undone action')
|
||||
m.AppendSeparator()
|
||||
m.Append(wx.wxID_CUT, 'Cu&t \tCtrl+X', 'Cut the selection')
|
||||
m.Append(wx.wxID_COPY, '&Copy \tCtrl+C', 'Copy the selection - removing prompts')
|
||||
m.Append(ID_COPY_PLUS, 'Cop&y Plus \tCtrl+Shift+C', 'Copy the selection - retaining prompts')
|
||||
m.Append(wx.wxID_PASTE, '&Paste \tCtrl+V', 'Paste')
|
||||
m.Append(ID_PASTE_PLUS, 'Past&e Plus \tCtrl+Shift+V', 'Paste and run commands')
|
||||
m.AppendSeparator()
|
||||
m.Append(wx.wxID_CLEAR, 'Cle&ar', 'Delete the selection')
|
||||
m.Append(wx.wxID_SELECTALL, 'Select A&ll \tCtrl+A', 'Select all text')
|
||||
|
||||
m = self.autocompMenu = wx.wxMenu()
|
||||
m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion',
|
||||
'Show auto completion during dot syntax', 1)
|
||||
m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes',
|
||||
'Include attributes visible to __getattr__ and __setattr__', 1)
|
||||
m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores',
|
||||
'Include attibutes prefixed by a single underscore', 1)
|
||||
m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores',
|
||||
'Include attibutes prefixed by a double underscore', 1)
|
||||
|
||||
m = self.calltipsMenu = wx.wxMenu()
|
||||
m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips',
|
||||
'Show call tips with argument specifications', 1)
|
||||
|
||||
m = self.optionsMenu = wx.wxMenu()
|
||||
m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu,
|
||||
'Auto Completion Options')
|
||||
m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu,
|
||||
'Call Tip Options')
|
||||
m.Append(ID_WRAP, '&Wrap Lines',
|
||||
'Wrap lines at right edge', 1)
|
||||
|
||||
m = self.helpMenu = wx.wxMenu()
|
||||
m.AppendSeparator()
|
||||
m.Append(wx.wxID_ABOUT, '&About...', 'About PyCrust')
|
||||
|
||||
b = self.menuBar = wx.wxMenuBar()
|
||||
b.Append(self.fileMenu, '&File')
|
||||
b.Append(self.editMenu, '&Edit')
|
||||
b.Append(self.optionsMenu, '&Options')
|
||||
b.Append(self.helpMenu, '&Help')
|
||||
self.SetMenuBar(b)
|
||||
|
||||
wx.EVT_MENU(self, wx.wxID_EXIT, self.OnExit)
|
||||
wx.EVT_MENU(self, wx.wxID_UNDO, self.OnUndo)
|
||||
wx.EVT_MENU(self, wx.wxID_REDO, self.OnRedo)
|
||||
wx.EVT_MENU(self, wx.wxID_CUT, self.OnCut)
|
||||
wx.EVT_MENU(self, wx.wxID_COPY, self.OnCopy)
|
||||
wx.EVT_MENU(self, ID_COPY_PLUS, self.OnCopyPlus)
|
||||
wx.EVT_MENU(self, wx.wxID_PASTE, self.OnPaste)
|
||||
wx.EVT_MENU(self, ID_PASTE_PLUS, self.OnPastePlus)
|
||||
wx.EVT_MENU(self, wx.wxID_CLEAR, self.OnClear)
|
||||
wx.EVT_MENU(self, wx.wxID_SELECTALL, self.OnSelectAll)
|
||||
wx.EVT_MENU(self, wx.wxID_ABOUT, self.OnAbout)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_SHOW,
|
||||
self.OnAutoCompleteShow)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC,
|
||||
self.OnAutoCompleteIncludeMagic)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE,
|
||||
self.OnAutoCompleteIncludeSingle)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE,
|
||||
self.OnAutoCompleteIncludeDouble)
|
||||
wx.EVT_MENU(self, ID_CALLTIPS_SHOW,
|
||||
self.OnCallTipsShow)
|
||||
wx.EVT_MENU(self, ID_WRAP, self.OnWrap)
|
||||
|
||||
wx.EVT_UPDATE_UI(self, wx.wxID_UNDO, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, wx.wxID_REDO, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, wx.wxID_CUT, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, wx.wxID_COPY, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_COPY_PLUS, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, wx.wxID_PASTE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_PASTE_PLUS, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, wx.wxID_CLEAR, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_WRAP, self.OnUpdateMenu)
|
||||
|
||||
def OnExit(self, event):
|
||||
self.Close(True)
|
||||
|
||||
def OnUndo(self, event):
|
||||
self.shell.Undo()
|
||||
|
||||
def OnRedo(self, event):
|
||||
self.shell.Redo()
|
||||
|
||||
def OnCut(self, event):
|
||||
self.shell.Cut()
|
||||
|
||||
def OnCopy(self, event):
|
||||
self.shell.Copy()
|
||||
|
||||
def OnCopyPlus(self, event):
|
||||
self.shell.CopyWithPrompts()
|
||||
|
||||
def OnPaste(self, event):
|
||||
self.shell.Paste()
|
||||
|
||||
def OnPastePlus(self, event):
|
||||
self.shell.PasteAndRun()
|
||||
|
||||
def OnClear(self, event):
|
||||
self.shell.Clear()
|
||||
|
||||
def OnSelectAll(self, event):
|
||||
self.shell.SelectAll()
|
||||
|
||||
def OnAbout(self, event):
|
||||
"""Display an About PyCrust window."""
|
||||
title = 'About PyCrust'
|
||||
text = 'PyCrust %s\n\n' % VERSION + \
|
||||
'Yet another Python shell, only flakier.\n\n' + \
|
||||
'Half-baked by Patrick K. O\'Brien,\n' + \
|
||||
'the other half is still in the oven.\n\n' + \
|
||||
'Shell Revision: %s\n' % self.shell.revision + \
|
||||
'Interpreter Revision: %s\n\n' % self.shell.interp.revision + \
|
||||
'Python Version: %s\n' % sys.version.split()[0] + \
|
||||
'wxPython Version: %s\n' % wx.__version__ + \
|
||||
'Platform: %s\n' % sys.platform
|
||||
dialog = wx.wxMessageDialog(self, text, title, wx.wxOK | wx.wxICON_INFORMATION)
|
||||
dialog.ShowModal()
|
||||
dialog.Destroy()
|
||||
|
||||
def OnAutoCompleteShow(self, event):
|
||||
self.shell.autoComplete = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteIncludeMagic(self, event):
|
||||
self.shell.autoCompleteIncludeMagic = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteIncludeSingle(self, event):
|
||||
self.shell.autoCompleteIncludeSingle = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteIncludeDouble(self, event):
|
||||
self.shell.autoCompleteIncludeDouble = event.IsChecked()
|
||||
|
||||
def OnCallTipsShow(self, event):
|
||||
self.shell.autoCallTip = event.IsChecked()
|
||||
|
||||
def OnWrap(self, event):
|
||||
self.shell.SetWrapMode(event.IsChecked())
|
||||
|
||||
def OnUpdateMenu(self, event):
|
||||
"""Update menu items based on current status."""
|
||||
id = event.GetId()
|
||||
if id == wx.wxID_UNDO:
|
||||
event.Enable(self.shell.CanUndo())
|
||||
elif id == wx.wxID_REDO:
|
||||
event.Enable(self.shell.CanRedo())
|
||||
elif id == wx.wxID_CUT:
|
||||
event.Enable(self.shell.CanCut())
|
||||
elif id == wx.wxID_COPY:
|
||||
event.Enable(self.shell.CanCopy())
|
||||
elif id == ID_COPY_PLUS:
|
||||
event.Enable(self.shell.CanCopy())
|
||||
elif id == wx.wxID_PASTE:
|
||||
event.Enable(self.shell.CanPaste())
|
||||
elif id == ID_PASTE_PLUS:
|
||||
event.Enable(self.shell.CanPaste())
|
||||
elif id == wx.wxID_CLEAR:
|
||||
event.Enable(self.shell.CanCut())
|
||||
elif id == ID_AUTOCOMP_SHOW:
|
||||
event.Check(self.shell.autoComplete)
|
||||
elif id == ID_AUTOCOMP_INCLUDE_MAGIC:
|
||||
event.Check(self.shell.autoCompleteIncludeMagic)
|
||||
elif id == ID_AUTOCOMP_INCLUDE_SINGLE:
|
||||
event.Check(self.shell.autoCompleteIncludeSingle)
|
||||
elif id == ID_AUTOCOMP_INCLUDE_DOUBLE:
|
||||
event.Check(self.shell.autoCompleteIncludeDouble)
|
||||
elif id == ID_CALLTIPS_SHOW:
|
||||
event.Check(self.shell.autoCallTip)
|
||||
elif id == ID_WRAP:
|
||||
event.Check(self.shell.GetWrapMode())
|
||||
|
@@ -6,5 +6,5 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
VERSION = '0.7.2'
|
||||
VERSION = '0.8'
|
||||
|
||||
|
Reference in New Issue
Block a user