wxPython Merge #2 of 2.4 branch --> HEAD (branch tag: wxPy_2_4_merge_2)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21593 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2003-07-02 23:13:10 +00:00
parent e234d4c9b7
commit 1fded56b37
535 changed files with 48899 additions and 20067 deletions

View File

@@ -1,3 +0,0 @@
*.pyc
*.BAK
*.$$$

View File

@@ -1,512 +0,0 @@
=============
CHANGES.txt
=============
-----------------------------------------
Changes made to each release of PyCrust
-----------------------------------------
0.9 (2/27/2003 to 3/20/2003)
============================
Added fontIncrease, fontDecrease, fontDefault signals, receivers and
keybindings:
Ctrl+] Increase font size.
Ctrl+[ Decrease font size.
Ctrl+= Default font size.
Continued enhancement of the decorator capability to provide better
documentation and docstrings for wxPython classes and functions.
Introduced new tabbed interface:
* Namespace
* Calltip
* Session
* Dispatcher
* wxPython Docs
* wxSTC Docs
Filling.tree now expands tuples as well as lists. (It should have done
this all along, I just never noticed this omission before.)
Added this True/False test to all modules:
try:
True
except NameError:
True = 1==1
False = 1==0
Added wxd directory with decoration classes.
0.8.2 (1/5/2003 to 2/26/2003)
=============================
Wrapped sys.ps1, sys.ps2, and sys.ps3 in str(). (Thanks, Kieran
Holland.)
Fixed minor things found by PyChecker.
Changed locals to use __main__.__dict__ and added code to clean up the
namespace, making it as close to the regular Python environment as
possible. This solves the problem of pickling and unpickling instances
of classes defined in the shell.
Made shell.PasteAndRun() a little more forgiving when it finds a ps2
prompt line with no trailing space, such when you copy code from a web
page.
Improved autocomplete behavior by adding these to shell:
self.AutoCompSetAutoHide(False)
self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`')
Added decor directory, decorator.py, stcDecor.py, and
stcConstants.py. These all serve the purpose of adding docstrings to
existing wxPython classes, in particular the wxStyledTextControl.
Added wrap.py, a command line utility for running a wxPython app with
additional runtime-tools loaded, such as PyCrust (the only tool at
this point).
Flushed the clipboard Cut/Copy operations so that selections will
exist in the clipboard even after PyCrust has been closed.
Improved the suppression of docstrings for simple data types appearing
in the namespace viewer.
Better handling of autocompletion with numeric types; no
autocompletion when typing a dot after an integer. If the
autocompletion is desired, type a space before the dot:
func = 3 .
More Filling!!! The namespace tree is now dynamically updated.
0.8.1 (12/20/2002 to 12/25/2002)
================================
Improved keyboard handling with Autocomplete active. You can now use
Enter as well as Tab to select an item from the list.
Disabled autocomplete for lists of 2000 items or more. The current
implementation of wxSTC can't handle lists this big.
Changed filling to always display docstrings for objects. This is
useful for objects whose docstrings have been decorated, rather than
coming directly from the source code. (Hmmm. Sounds like someone is
doing some decorating. I wonder where that would be helpful? ;-)
Fixed handling of icon. Added images.py file.
0.8 (10/29/2002 to 12/16/2002)
==============================
Added "help" to startup banner info.
Made all wx and stc imports explicit. No more import *.
Replaced use of wx's true and false with Python's True and False.
Changed introspect.getRoot() to use tokenize module. This does a
slightly better job than the previous parsing routine and the code is
clearer.
Improved handling of whitespace and empty types during introspection.
Fixed cut/copy clipboard problem under Linux. (Robin Dunn rocks!!!)
Added shell.about() which works like this:
>>> shell.about()
PyCrust Version: 0.8
Shell Revision: 1.80
Interpreter Revision: 1.15
Python Version: 2.2.2
wxPython Version: 2.3.3.1
Platform: linux2
Added copy plus and paste plus to shell menu.
Moved shell menu from shell.py to shellmenu.py.
Added sys.stdin.readlines() support.
Added time.sleep() in readline() and OnIdle() event handler to free up
the CPU.
0.7.2 (2/22/2002 to 8/27/2002)
==============================
Tweaked getAttributeNames() to pick up a few more attributes:
'__bases__', '__class__', '__dict__', '__name__', 'func_closure',
'func_code', 'func_defaults', 'func_dict', 'func_doc',
'func_globals', 'func_name'
Added a tests directory and unit tests.
Improved support for empty types in the shell: [], () and {} as far as
when call tips and autocompletion are available.
Added support for the other triple string - ''''''.
Refactored introspect.py to improve testability.
Improved call tips for unbound methods by leaving the "self"
parameter, since unbound methods require an instance be passed.
Fixed call tip bug where a tip was displayed when a "(" was typed
after an object that wasn't callable.
Fixed getAllAttributeNames when str(object) fails.
Added brace highlighting. (Thank you, Kevin Altis.)
Fixed problem displaying unicode objects in PyFilling.
Changed how filling.py checks for expandable objects. Lists are now
expandable objects.
Made the key handling more robust when there is an active text
selection that includes text prior to the last primary prompt. Thanks
to Raul Cota for pointing this out.
Fixed wxSTC problem with brace highlighting and non-us keyboards.
(Thank you for the patch, Jean-Michel Fauth.)
Added busy = wxBusyCursor() to key point in shell and filling.
Added OnCloseWindow handler to ShellFrame and CrustFrame.
Default to SetWrapMode(1) for shell and namespace viewer.
Added shell.wrap() and shell.zoom().
Added Raul Cota autoCompleteKeys hooks.
Cleaned up various little key handling bugs.
Changed input methods to get values from shell, rather than dialog
boxes. Renamed readIn to readline and readRaw to raw_input.
0.7.1 (12/12/2001 to 2/21/2002)
===============================
Fixed OnChar() issues effecting European keyboards, as reported by
Jean-Michel Fauth.
Fixed introspect.py issue with xmlrpc objects reported by Kevin Altis.
Fixed some introspect/PyFilling issues with regard to Python 2.2.
Fixed font background color as reported by Keith J. Farmer. (Thanks)
Fixed problem with call tips and autocompletion inside multiline
commands as report by Kevin Altis.
Improved OnKeyDown handling of cut/copy/paste operations based on
feedback from Syver Enstad. (Thanks)
Added a shell.help() method to display some help info.
Changed sort of items in the namespace viewer to case insensitive.
Changed attributes.sort(lambda x, y: cmp(x.upper(), y.upper())) in
advance of an upcoming fix to an autocompletion matching bug in wxSTC.
Improved support for ZODB by allowing namespace drilldown into BTrees.
Added shell.PasteAndRun() to support pasting multiple commands into
the shell from the clipboard. Ctrl+Shift+V or v.
Enter now always processes a command (or copies down a previous one.)
To insert a line break, press Ctrl+Enter.
Escape key clears the current, unexecuted command.
History retrieval changed to replace current command. Added new keys
to insert from history - Shift+Up and Shift+Down.
Better call tips on objects with __call__ methods.
Improved call tip positioning calculation.
0.7 (10/15/2001 to 12/11/2001)
==============================
Changed how command history retrieval functions work. Added Alt-P,
Alt-N as keybindings for Retrieve-Previous, Retrieve-Next.
Added full support for mult-line commands, similar to IDLE.
Changed introspect.getAttributeNames() to do a case insensitive sort.
Changed Cut/Copy/Paste to deal with prompts intelligently. Cut and
Copy remove all prompts. Paste can handle prompted or not-prompted
text.
Added CopyWithPrompts() method attached to Ctrl-Shift-C for those
times when you really do want all the prompts left intact.
Improved handling of the shell's read-only zone.
Changed CrustFrame.__init__ parameter spec to include all parameters
allowed by a wxFrame.
Changed FillingText to be read-only.
Renamed PyCrust.py to PyCrustApp.py to eliminate package/module name
conflicts that kept you from doing "from PyCrust import shell" inside
files located in the PyCrust directory.
Renamed PyFilling.py to PyFillingApp.py and PyShell.py to
PyShellApp.py to maintain consistency.
Removed the __date__ property from all modules.
Fixed bug in introspect.getCallTip(), reported by Kevin Altis.
0.6.1 (9/19/2001 to 10/12/2001)
===============================
Changed Shell.run() to always position to the end of existing text, as
suggested by Raul Cota.
Changed introspect.getAllAttributeNames() to break circular references
in object.__class__, which occurs in Zope/ZODB extension classes.
Changed filling.FillingTree.getChildren() to introspect extension
classes.
Fixed minor bugs in introspect.getCallTip() that were interfering with
call tips for Zope/ZODB extension class methods.
In preparation for wxPython 2.3.2, added code to fix a font sizing
problem. Versions of wxPython prior to 2.3.2 had a sizing bug on Win
platform where the font was 2 points larger than what was specified.
Added a hack to introspect.getAllAttributeNames() to "wake up" ZODB
objects that are asleep - in a "ghost" state. Otherwise it returns
incomplete info.
0.6 (8/21/2001 to 9/12/2001)
============================
Added PyFilling.py and filling.py.
PyShell.py and PyFilling.py can now be run standalone, as well as
PyCrust.py.
Added crust.py and moved some code from PyCrust.py to it.
Added command history retrieval features submitted by Richie Hindle.
Changed shell.write() to replace line endings with OS-specific
endings. Changed shell.py and interpreter.py to use os.linesep in
strings having hardcoded line endings.
Added shell.redirectStdin(), shell.redirectStdout() and
shell.redirectStderr() to allow the surrounding app to toggle requests
that the specified sys.std* be redirected to the shell. These can also
be run from within the shell itself, of course.
The shell now adds the current working directory "." to the search
path:
sys.path.insert(0, os.curdir)
Added support for distutils installations.
0.5.4 (8/17/2001 to 8/20/2001)
==============================
Changed default font size under *nix to:
'size' : 12,
'lnsize' : 10,
Changed Shell to expect a parameter referencing an Interpreter class,
rather than an intepreter instance, to facilitate subclassing of
Interpreter, which effectively broke when the Editor class was
eliminated.
Fixed PyCrustAlaCarte.py, which had been broken by previous changes.
Created InterpreterAlaCarte class as an example for use in the demo.
Split PyCrust.py into PyCrust.py and PyShell.py in anticipation of
PyFilling.
0.5.3 (8/16/2001)
=================
Added patch to PyCrust.py to fix wxPython bug:
wxID_SELECTALL = NewId() # This *should* be defined by wxPython.
0.5.2 (8/14/2001 to 8/15/2001)
==============================
Shortened module names by dropping "PyCrust" as a prefix.
Changed version to VERSION in version module.
Added Options menu to PyCrust application.
Eliminated the Editor class (and editor module) by merging with Shell.
This means that Shell "is a" wxStyledTextCtrl rather than "has a".
There just wasn't enough non-gui code to justify the separation. Plus,
Shell will be much easier for gui toolkits/designers to deal with now.
0.5.1 (8/10/2001 to 8/14/2001)
==============================
Added introspect module.
Moved some functionality from PyCrustInterp to introspect.
Changed introspect.getRoot() to no longer remove whitespace from the
command. This was a remnant of a previous approach that, when left as
part of the current approach, turned out to be a really bad thing.
Changed introspect.getRoot() to allow commands of '', "", """""", [],
(), and {} to pass through. This allows you to type them, followed by
a dot, and get autocomplete options on them.
Changed introspect.getRoot() to identify some situations where strings
shouldn't be considered roots. For example:
>>> import PyCrust # To illustrate the potential problem.
>>> len('PyCrust.py')
Typing the dot at the end of "PyCrust" in the second line above should
NOT result in an autocompletion list because "PyCrust" is part of a
string in this context, not a reference to the PyCrust module
object. Similar reasoning applies to call tips. For example:
>>> len('dir(')
Typing the left paren at the end of "dir" should NOT result in a call
tip.
Both features now behave properly in the examples given. However,
there is still the case where whitespace precedes the potential root
and that is NOT handled properly. For example:
>>> len('this is a dir(')
and
>>> len('This is PyCrust.py')
More code needs to be written to handle more complex situations.
Added locals=None parameter to Shell.__init__().
Added support for magic attribute retrieval. Users can change this
with:
>>> shell.editor.autoCompleteIncludeMagic = 0
Added the ability to set filters on auto completion to exclude
attributes prefixed with a single or double underscore. Users can
exclude one or the other or both with:
>>> shell.editor.autoCompleteExcludeSingle = 1
>>> shell.editor.autoCompleteExcludeDouble = 1
0.5 (8/8/2001)
==============
Mostly just a final version change before creating a release.
0.4 (8/4/2001 to 8/7/2001)
==========================
Changed version/revision handling.
Fixed bugs.
0.3 (8/2/2001 to 8/3/2001)
==========================
Removed lots of cruft.
Added lots of docstrings.
Imported to CVS repository at SourceForge.
Added call tips.
0.2 (7/30/2001 to 8/2/2001)
===========================
Renamed several files.
Added command autocompletion.
Added menus to PyCrust.py: File, Edit and Help
Added sample applications: PyCrustAlaCarte.py, PyCrustAlaMode.py, and
PyCrustMinimus.py.
0.1 (7/1/2001 to 7/19/2001)
===========================
Added basic syntax coloring much like Boa.
Added read-only logging much like IDLE.
Can retrieve a previous command by putting the cursor back on that
line and hitting enter.
Stdin and raw_input operate properly so you can now do help() and
license() without hanging.
Redefined "quit", "exit", and "close" to display a better-than-nothing
response.
Home key honors the prompt.
Created SourceForge account, but nothing was posted.
In the beginning, there was pie... (7/1/2001)
=============================================
Blame it all on IDLE, Boa and PythonWin. I was using all three, got
frustrated with their dissimilarities, and began to let everyone know
how I felt. At the same time, Scintilla looked like an interesting
tool to build a shell around. And while I didn't receive much in the
way of positive feedback, let alone encouragement, I just couldn't let
go of the idea of a Scintilla-based Python shell. Then the PythonCard
project got to the point where they were talking about including a
shell in their development environment. That was all the incentive I
needed. PyCrust had to happen...
CVS Information
===============
$Date$
$Revision$
$Id$

View File

@@ -1,70 +1,6 @@
"""PyCrustApp is a python shell and namespace browser application."""
from wxPython.py.PyCrust import *
# The next two lines, and the other code below that makes use of
# ``__main__`` and ``original``, serve the purpose of cleaning up the
# main namespace to look as much as possible like the regular Python
# shell environment.
import __main__
original = __main__.__dict__.keys()
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
from wxPython import wx
try:
True
except NameError:
True = 1==1
False = 1==0
class App(wx.wxApp):
"""PyCrust standalone application."""
def OnInit(self):
from wxPython import wx
wx.wxInitAllImageHandlers()
locals = __main__.__dict__
from crust import CrustFrame
self.frame = CrustFrame(locals=locals)
self.frame.SetSize((800, 600))
self.frame.Show()
self.SetTopWindow(self.frame)
# Add the application object to the sys module's namespace.
# This allows a shell user to do:
# >>> import sys
# >>> sys.app.whatever
import sys
sys.app = self
return 1
'''
The main() function needs to handle being imported, such as with the
pycrust script that wxPython installs:
#!/usr/bin/env python
from wxPython.lib.PyCrust.PyCrustApp import main
main()
'''
def main():
import __main__
md = __main__.__dict__
keepers = original
keepers.append('App')
for key in md.keys():
if key not in keepers:
del md[key]
app = App(0)
if md.has_key('App') and md['App'] is App:
del md['App']
if md.has_key('__main__') and md['__main__'] is __main__:
del md['__main__']
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -1,44 +1,5 @@
"""PyFillingApp is a python namespace inspection application."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
# We use this object to get more introspection when run standalone.
app = None
import filling
# These are imported just to have something interesting to inspect.
import crust
import interpreter
import introspect
import pseudo
import shell
import sys
from wxPython import wx
try:
True
except NameError:
True = 1==1
False = 1==0
class App(filling.App):
def OnInit(self):
filling.App.OnInit(self)
self.root = self.fillingFrame.filling.tree.root
return True
def main():
"""Create and run the application."""
global app
app = App(0)
app.fillingFrame.filling.tree.Expand(app.root)
app.MainLoop()
from wxPython.py.PyFilling import *
if __name__ == '__main__':

View File

@@ -1,71 +1,6 @@
"""PyShellApp is a python shell application."""
from wxPython.py.PyShell import *
# The next two lines, and the other code below that makes use of
# ``__main__`` and ``original``, serve the purpose of cleaning up the
# main namespace to look as much as possible like the regular Python
# shell environment.
import __main__
original = __main__.__dict__.keys()
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
from wxPython import wx
try:
True
except NameError:
True = 1==1
False = 1==0
class App(wx.wxApp):
"""PyShell standalone application."""
def OnInit(self):
from wxPython import wx
wx.wxInitAllImageHandlers()
locals = __main__.__dict__
from shell import ShellFrame
self.frame = ShellFrame(locals=locals)
self.frame.SetSize((750, 525))
self.frame.Show()
self.SetTopWindow(self.frame)
self.frame.shell.SetFocus()
# Add the application object to the sys module's namespace.
# This allows a shell user to do:
# >>> import sys
# >>> sys.app.whatever
import sys
sys.app = self
return 1
'''
The main() function needs to handle being imported, such as with the
pycrust script that wxPython installs:
#!/usr/bin/env python
from wxPython.lib.PyCrust.PyCrustApp import main
main()
'''
def main():
import __main__
md = __main__.__dict__
keepers = original
keepers.append('App')
for key in md.keys():
if key not in keepers:
del md[key]
app = App(0)
if md.has_key('App') and md['App'] is App:
del md['App']
if md.has_key('__main__') and md['__main__'] is __main__:
del md['__main__']
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -1 +1,5 @@
# Orbtech python package.
# Change this to an ImportError after the next release
import warnings
warnings.warn("PyCrust has been renamed to Py. Use 'from wx import py'", stacklevel=2)

View File

@@ -1,169 +1,2 @@
"""PyCrust Crust combines the shell and filling into one control."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
from wxPython import wx
from filling import Filling
import os
from shell import Shell
from shellmenu import ShellMenu
from version import VERSION
try:
True
except NameError:
True = 1==1
False = 1==0
class Crust(wx.wxSplitterWindow):
"""PyCrust Crust based on wxSplitterWindow."""
name = 'PyCrust Crust'
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
size=wx.wxDefaultSize, style=wx.wxSP_3D,
name='Crust Window', rootObject=None, rootLabel=None,
rootIsNamespace=True, intro='', locals=None,
InterpClass=None, *args, **kwds):
"""Create a PyCrust Crust instance."""
wx.wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
self.shell = Shell(parent=self, introText=intro,
locals=locals, InterpClass=InterpClass,
*args, **kwds)
if rootObject is None:
rootObject = self.shell.interp.locals
self.notebook = wx.wxNotebook(parent=self, id=-1)
self.shell.interp.locals['notebook'] = self.notebook
self.filling = Filling(parent=self.notebook,
rootObject=rootObject,
rootLabel=rootLabel,
rootIsNamespace=rootIsNamespace)
# Add 'filling' to the interpreter's locals.
self.shell.interp.locals['filling'] = self.filling
self.notebook.AddPage(page=self.filling, text='Namespace', select=True)
self.calltip = Calltip(parent=self.notebook)
self.notebook.AddPage(page=self.calltip, text='Calltip')
self.sessionlisting = SessionListing(parent=self.notebook)
self.notebook.AddPage(page=self.sessionlisting, text='Session')
self.dispatcherlisting = DispatcherListing(parent=self.notebook)
self.notebook.AddPage(page=self.dispatcherlisting, text='Dispatcher')
from wxd import wx_
self.wxdocs = Filling(parent=self.notebook,
rootObject=wx_,
rootLabel='wx',
rootIsNamespace=False,
static=True)
self.notebook.AddPage(page=self.wxdocs, text='wxPython Docs')
from wxd import stc_
self.stcdocs = Filling(parent=self.notebook,
rootObject=stc_.StyledTextCtrl,
rootLabel='StyledTextCtrl',
rootIsNamespace=False,
static=True)
self.notebook.AddPage(page=self.stcdocs, text='StyledTextCtrl Docs')
self.SplitHorizontally(self.shell, self.notebook, 300)
self.SetMinimumPaneSize(1)
class Calltip(wx.wxTextCtrl):
"""Text control containing the most recent shell calltip."""
def __init__(self, parent=None, id=-1):
import dispatcher
style = wx.wxTE_MULTILINE | wx.wxTE_READONLY | wx.wxTE_RICH2
wx.wxTextCtrl.__init__(self, parent=parent, id=id, style=style)
self.SetBackgroundColour(wx.wxColour(255, 255, 232))
dispatcher.connect(receiver=self.display, signal='Shell.calltip')
def display(self, calltip):
"""Receiver for Shell.calltip signal."""
self.SetValue(calltip)
class SessionListing(wx.wxTextCtrl):
"""Text control containing all commands for session."""
def __init__(self, parent=None, id=-1):
import dispatcher
style = wx.wxTE_MULTILINE | wx.wxTE_READONLY | \
wx.wxTE_RICH2 | wx.wxTE_DONTWRAP
wx.wxTextCtrl.__init__(self, parent=parent, id=id, style=style)
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
def push(self, command, more):
"""Receiver for Interpreter.push signal."""
if command and not more:
self.SetInsertionPointEnd()
start, end = self.GetSelection()
if start != end:
self.SetSelection(0, 0)
self.AppendText(command + '\n')
class DispatcherListing(wx.wxTextCtrl):
"""Text control containing all dispatches for session."""
def __init__(self, parent=None, id=-1):
import dispatcher
style = wx.wxTE_MULTILINE | wx.wxTE_READONLY | \
wx.wxTE_RICH2 | wx.wxTE_DONTWRAP
wx.wxTextCtrl.__init__(self, parent=parent, id=id, style=style)
dispatcher.connect(receiver=self.spy)
def spy(self, signal, sender):
"""Receiver for Any signal from Any sender."""
text = '%r from %s' % (signal, sender)
self.SetInsertionPointEnd()
start, end = self.GetSelection()
if start != end:
self.SetSelection(0, 0)
self.AppendText(text + '\n')
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=wx.wxDefaultPosition, size=wx.wxDefaultSize,
style=wx.wxDEFAULT_FRAME_STYLE,
rootObject=None, rootLabel=None, rootIsNamespace=True,
locals=None, InterpClass=None, *args, **kwds):
"""Create a PyCrust CrustFrame instance."""
wx.wxFrame.__init__(self, parent, id, title, pos, size, style)
intro = 'PyCrust %s - The Flakiest Python Shell' % VERSION
intro += '\nSponsored by Orbtech - '
intro += '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,
InterpClass=InterpClass, *args, **kwds)
# Override the filling so that status messages go to the status bar.
self.crust.filling.tree.setStatusText = self.SetStatusText
# Override the shell so that status messages go to the status bar.
self.crust.shell.setStatusText = self.SetStatusText
# Fix a problem with the sash shrinking to nothing.
self.crust.filling.SetSashPosition(200)
self.shell = self.crust.shell
self.createMenus()
wx.EVT_CLOSE(self, self.OnCloseWindow)
# Set focus to the shell editor.
self.crust.shell.SetFocus()
def OnCloseWindow(self, event):
self.crust.shell.destroy()
self.Destroy()
from wxPython.py.crust import *

View File

@@ -1,436 +1,3 @@
"""PyCrust Filling is the gui tree control through which a user can
navigate the local namespace or any object."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
from wxPython.py.filling import *
from wxPython import wx
from wxPython import stc
from version import VERSION
import dispatcher
import inspect
import introspect
import keyword
import sys
import types
try:
True
except NameError:
True = 1==1
False = 1==0
COMMONTYPES = [getattr(types, t) for t in dir(types) \
if not t.startswith('_') \
and t not in ('ClassType', 'InstanceType', 'ModuleType')]
DOCTYPES = ('BuiltinFunctionType', 'BuiltinMethodType', 'ClassType',
'FunctionType', 'GeneratorType', 'InstanceType',
'LambdaType', 'MethodType', 'ModuleType',
'UnboundMethodType', 'method-wrapper')
SIMPLETYPES = [getattr(types, t) for t in dir(types) \
if not t.startswith('_') and t not in DOCTYPES]
try:
COMMONTYPES.append(type(''.__repr__)) # Method-wrapper in version 2.2.x.
except AttributeError:
pass
class FillingTree(wx.wxTreeCtrl):
"""PyCrust FillingTree based on wxTreeCtrl."""
name = 'PyCrust Filling Tree'
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
size=wx.wxDefaultSize, style=wx.wxTR_DEFAULT_STYLE,
rootObject=None, rootLabel=None, rootIsNamespace=0,
static=False):
"""Create a PyCrust FillingTree instance."""
wx.wxTreeCtrl.__init__(self, parent, id, pos, size, style)
self.rootIsNamespace = rootIsNamespace
import __main__
if rootObject is None:
rootObject = __main__.__dict__
self.rootIsNamespace = 1
if rootObject is __main__.__dict__ and rootLabel is None:
rootLabel = 'locals()'
if not rootLabel:
rootLabel = 'Ingredients'
rootData = wx.wxTreeItemData(rootObject)
self.item = self.root = self.AddRoot(rootLabel, -1, -1, rootData)
self.SetItemHasChildren(self.root, self.hasChildren(rootObject))
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)
wx.EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated)
if not static:
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
def push(self, command, more):
"""Receiver for Interpreter.push signal."""
self.display()
def OnItemExpanding(self, event):
"""Add children to the item."""
busy = wx.wxBusyCursor()
item = event.GetItem()
if self.IsExpanded(item):
return
self.addChildren(item)
# self.SelectItem(item)
def OnItemCollapsed(self, event):
"""Remove all children from the item."""
busy = wx.wxBusyCursor()
item = event.GetItem()
# self.CollapseAndReset(item)
# self.DeleteChildren(item)
# self.SelectItem(item)
def OnSelChanged(self, event):
"""Display information about the item."""
busy = wx.wxBusyCursor()
self.item = event.GetItem()
self.display()
def OnItemActivated(self, event):
"""Launch a DirFrame."""
item = event.GetItem()
text = self.getFullName(item)
obj = self.GetPyData(item)
frame = FillingFrame(parent=self, size=(600, 100), rootObject=obj,
rootLabel=text, rootIsNamespace=False)
frame.Show()
def hasChildren(self, obj):
"""Return true if object has children."""
if self.getChildren(obj):
return True
else:
return False
def getChildren(self, obj):
"""Return dictionary with attributes or contents of object."""
busy = wx.wxBusyCursor()
otype = type(obj)
if otype is types.DictType \
or str(otype)[17:23] == 'BTrees' and hasattr(obj, 'keys'):
return obj
d = {}
if otype is types.ListType or otype is types.TupleType:
for n in range(len(obj)):
key = '[' + str(n) + ']'
d[key] = obj[n]
if otype not in COMMONTYPES:
for key in introspect.getAttributeNames(obj):
# Believe it or not, some attributes can disappear,
# such as the exc_traceback attribute of the sys
# module. So this is nested in a try block.
try:
d[key] = getattr(obj, key)
except:
pass
return d
def addChildren(self, item):
self.DeleteChildren(item)
obj = self.GetPyData(item)
children = self.getChildren(obj)
if not children:
return
keys = children.keys()
keys.sort(lambda x, y: cmp(x.lower(), y.lower()))
for key in keys:
itemtext = str(key)
# Show string dictionary items with single quotes, except
# for the first level of items, if they represent a
# namespace.
if type(obj) is types.DictType \
and type(key) is types.StringType \
and (item != self.root \
or (item == self.root and not self.rootIsNamespace)):
itemtext = repr(key)
child = children[key]
data = wx.wxTreeItemData(child)
branch = self.AppendItem(parent=item, text=itemtext, data=data)
self.SetItemHasChildren(branch, self.hasChildren(child))
def display(self):
item = self.item
if self.IsExpanded(item):
self.addChildren(item)
self.setText('')
obj = self.GetPyData(item)
if obj is None: # Windows bug fix.
return
self.SetItemHasChildren(item, self.hasChildren(obj))
otype = type(obj)
text = ''
text += self.getFullName(item)
text += '\n\nType: ' + str(otype)
try:
value = str(obj)
except:
value = ''
if otype is types.StringType or otype is types.UnicodeType:
value = repr(obj)
text += '\n\nValue: ' + value
if otype not in SIMPLETYPES:
try:
text += '\n\nDocstring:\n\n"""' + \
inspect.getdoc(obj).strip() + '"""'
except:
pass
if otype is types.InstanceType:
try:
text += '\n\nClass Definition:\n\n' + \
inspect.getsource(obj.__class__)
except:
pass
else:
try:
text += '\n\nSource Code:\n\n' + \
inspect.getsource(obj)
except:
pass
self.setText(text)
def getFullName(self, item, partial=''):
"""Return a syntactically proper name for item."""
name = self.GetItemText(item)
parent = None
obj = None
if item != self.root:
parent = self.GetItemParent(item)
obj = self.GetPyData(parent)
# Apply dictionary syntax to dictionary items, except the root
# and first level children of a namepace.
if (type(obj) is types.DictType \
or str(type(obj))[17:23] == 'BTrees' \
and hasattr(obj, 'keys')) \
and ((item != self.root and parent != self.root) \
or (parent == self.root and not self.rootIsNamespace)):
name = '[' + name + ']'
# Apply dot syntax to multipart names.
if partial:
if partial[0] == '[':
name += partial
else:
name += '.' + partial
# Repeat for everything but the root item
# and first level children of a namespace.
if (item != self.root and parent != self.root) \
or (parent == self.root and not self.rootIsNamespace):
name = self.getFullName(parent, partial=name)
return name
def setText(self, text):
"""Display information about the current selection."""
# This method will likely be replaced by the enclosing app to
# do something more interesting, like write to a text control.
print text
def setStatusText(self, text):
"""Display status information."""
# This method will likely be replaced by the enclosing app to
# do something more interesting, like write to a status bar.
print text
if wx.wxPlatform == '__WXMSW__':
faces = { 'times' : 'Times New Roman',
'mono' : 'Courier New',
'helv' : 'Lucida Console',
'lucida' : 'Lucida Console',
'other' : 'Comic Sans MS',
'size' : 10,
'lnsize' : 9,
'backcol': '#FFFFFF',
}
else: # GTK
faces = { 'times' : 'Times',
'mono' : 'Courier',
'helv' : 'Helvetica',
'other' : 'new century schoolbook',
'size' : 12,
'lnsize' : 10,
'backcol': '#FFFFFF',
}
class FillingText(stc.wxStyledTextCtrl):
"""PyCrust FillingText based on wxStyledTextCtrl."""
name = 'PyCrust Filling Text'
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition,
size=wx.wxDefaultSize, style=wx.wxCLIP_CHILDREN,
static=False):
"""Create a PyCrust FillingText instance."""
stc.wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
# Configure various defaults and user preferences.
self.config()
dispatcher.connect(receiver=self.fontsizer, signal='FontIncrease')
dispatcher.connect(receiver=self.fontsizer, signal='FontDecrease')
dispatcher.connect(receiver=self.fontsizer, signal='FontDefault')
if not static:
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
def push(self, command, more):
"""Receiver for Interpreter.push signal."""
self.Refresh()
def fontsizer(self, signal):
"""Receiver for Font* signals."""
size = self.GetZoom()
if signal == 'FontIncrease':
size += 1
elif signal == 'FontDecrease':
size -= 1
elif signal == 'FontDefault':
size = 0
self.SetZoom(size)
def config(self):
"""Configure shell based on user preferences."""
self.SetMarginWidth(1, 0)
self.SetLexer(stc.wxSTC_LEX_PYTHON)
self.SetKeyWords(0, ' '.join(keyword.kwlist))
self.setStyles(faces)
self.SetViewWhiteSpace(0)
self.SetTabWidth(4)
self.SetUseTabs(0)
self.SetReadOnly(1)
try:
self.SetWrapMode(1)
except AttributeError:
pass
def setStyles(self, faces):
"""Configure font size, typeface and color for lexer."""
# Default style
self.StyleSetSpec(stc.wxSTC_STYLE_DEFAULT,
"face:%(mono)s,size:%(size)d" % faces)
self.StyleClearAll()
# Built in styles
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(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)
stc.wxStyledTextCtrl.SetText(self, *args, **kwds)
self.SetReadOnly(1)
class Filling(wx.wxSplitterWindow):
"""PyCrust Filling based on wxSplitterWindow."""
name = 'PyCrust Filling'
revision = __revision__
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, static=False):
"""Create a PyCrust Filling instance."""
wx.wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
self.tree = FillingTree(parent=self, rootObject=rootObject,
rootLabel=rootLabel,
rootIsNamespace=rootIsNamespace,
static=static)
self.text = FillingText(parent=self, static=static)
self.SplitVertically(self.tree, self.text, 200)
self.SetMinimumPaneSize(1)
# Override the filling so that descriptions go to FillingText.
self.tree.setText = self.text.SetText
# Display the root item.
## self.tree.SelectItem(self.tree.root)
self.tree.display()
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=wx.wxDefaultPosition, size=wx.wxDefaultSize,
style=wx.wxDEFAULT_FRAME_STYLE, rootObject=None,
rootLabel=None, rootIsNamespace=0, static=False):
"""Create a PyCrust FillingFrame instance."""
wx.wxFrame.__init__(self, parent, id, title, pos, size, style)
intro = 'PyFilling - The Tastiest Namespace Inspector'
self.CreateStatusBar()
self.SetStatusText(intro)
import images
self.SetIcon(images.getPyCrustIcon())
self.filling = Filling(parent=self, rootObject=rootObject,
rootLabel=rootLabel,
rootIsNamespace=rootIsNamespace,
static=static)
# Override so that status messages go to the status bar.
self.filling.tree.setStatusText = self.SetStatusText
class App(wx.wxApp):
"""PyFilling standalone application."""
def OnInit(self):
wx.wxInitAllImageHandlers()
self.fillingFrame = FillingFrame()
self.fillingFrame.Show(True)
self.SetTopWindow(self.fillingFrame)
return True

File diff suppressed because it is too large Load Diff

View File

@@ -1,226 +0,0 @@
"""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
try:
True
except NameError:
True = 1==1
False = 1==0
ID_AUTOCOMP = wx.wxNewId()
ID_AUTOCOMP_SHOW = wx.wxNewId()
ID_AUTOCOMP_INCLUDE_MAGIC = wx.wxNewId()
ID_AUTOCOMP_INCLUDE_SINGLE = wx.wxNewId()
ID_AUTOCOMP_INCLUDE_DOUBLE = wx.wxNewId()
ID_CALLTIPS = wx.wxNewId()
ID_CALLTIPS_SHOW = wx.wxNewId()
ID_COPY_PLUS = wx.wxNewId()
ID_PASTE_PLUS = wx.wxNewId()
ID_WRAP = wx.wxNewId()
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())

View File

@@ -1,54 +1,5 @@
"""Wrap is a command line utility that runs a wxPython program with
additional runtime-tools, such as PyCrust."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import os
import sys
from wxPython import wx
from crust import CrustFrame as Frame
try:
True
except NameError:
True = 1==1
False = 1==0
def wrap(app):
wx.wxInitAllImageHandlers()
frame = Frame()
frame.SetSize((750, 525))
frame.Show(True)
frame.shell.interp.locals['app'] = app
app.MainLoop()
def main(argv):
if len(argv) < 2:
print "Please specify a module name."
raise SystemExit
name = argv[1]
if name[-3:] == '.py':
name = name[:-3]
module = __import__(name)
# Find the App class.
App = None
d = module.__dict__
for item in d.keys():
try:
if issubclass(d[item], wx.wxApp):
App = d[item]
except (NameError, TypeError):
pass
if App is None:
print "No App class found."
raise SystemExit
app = App()
wrap(app)
from wxPython.py.PyWrap import *
if __name__ == '__main__':

View File

@@ -1,488 +0,0 @@
"""Decorator classes for documentation and shell scripting.
"""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
# These are not the real wxPython classes. These are Python versions
# for documentation purposes. They are also used to apply docstrings
# to the real wxPython classes, which are SWIG-generated wrappers for
# C-language classes.
from Base import Object
import Parameters as wx
class Sizer(Object):
""""""
def Add(self):
""""""
pass
def AddMany(self):
""""""
pass
def AddSizer(self):
""""""
pass
def AddSpacer(self):
""""""
pass
def AddWindow(self):
""""""
pass
def Clear(self):
""""""
pass
def DeleteWindows(self):
""""""
pass
def Destroy(self):
""""""
pass
def Fit(self):
""""""
pass
def FitInside(self):
""""""
pass
def GetChildren(self):
""""""
pass
def GetMinSize(self):
""""""
pass
def GetMinSizeTuple(self):
""""""
pass
def GetPosition(self):
""""""
pass
def GetPositionTuple(self):
""""""
pass
def GetSize(self):
""""""
pass
def GetSizeTuple(self):
""""""
pass
def Hide(self):
""""""
pass
def HideSizer(self):
""""""
pass
def HideWindow(self):
""""""
pass
def Insert(self):
""""""
pass
def InsertSizer(self):
""""""
pass
def InsertSpacer(self):
""""""
pass
def InsertWindow(self):
""""""
pass
def IsShown(self):
""""""
pass
def IsShownSizer(self):
""""""
pass
def IsShownWindow(self):
""""""
pass
def Layout(self):
""""""
pass
def Prepend(self):
""""""
pass
def PrependSizer(self):
""""""
pass
def PrependSpacer(self):
""""""
pass
def PrependWindow(self):
""""""
pass
def Remove(self):
""""""
pass
def RemovePos(self):
""""""
pass
def RemoveSizer(self):
""""""
pass
def RemoveWindow(self):
""""""
pass
def SetDimension(self):
""""""
pass
def SetItemMinSize(self):
""""""
pass
def SetItemMinSizePos(self):
""""""
pass
def SetItemMinSizeSizer(self):
""""""
pass
def SetItemMinSizeWindow(self):
""""""
pass
def SetMinSize(self):
""""""
pass
def SetSizeHints(self):
""""""
pass
def SetVirtualSizeHints(self):
""""""
pass
def Show(self):
""""""
pass
def ShowItems(self):
""""""
pass
def ShowSizer(self):
""""""
pass
def ShowWindow(self):
""""""
pass
def __init__(self):
""""""
pass
def _setOORInfo(self):
""""""
pass
class SizerItem(Object):
""""""
def CalcMin(self):
""""""
pass
def DeleteWindows(self):
""""""
pass
def GetBorder(self):
""""""
pass
def GetFlag(self):
""""""
pass
def GetOption(self):
""""""
pass
def GetPosition(self):
""""""
pass
def GetRatio(self):
""""""
pass
def GetSize(self):
""""""
pass
def GetSizer(self):
""""""
pass
def GetUserData(self):
""""""
pass
def GetWindow(self):
""""""
pass
def IsShown(self):
""""""
pass
def IsSizer(self):
""""""
pass
def IsSpacer(self):
""""""
pass
def IsWindow(self):
""""""
pass
def SetBorder(self):
""""""
pass
def SetDimension(self):
""""""
pass
def SetFlag(self):
""""""
pass
def SetInitSize(self):
""""""
pass
def SetOption(self):
""""""
pass
def SetRatio(self):
""""""
pass
def SetRatioSize(self):
""""""
pass
def SetRatioWH(self):
""""""
pass
def SetSizer(self):
""""""
pass
def SetWindow(self):
""""""
pass
def Show(self):
""""""
pass
def __init__(self):
""""""
pass
class BoxSizer(Sizer):
""""""
def CalcMin(self):
""""""
pass
def GetOrientation(self):
""""""
pass
def RecalcSizes(self):
""""""
pass
def SetOrientation(self):
""""""
pass
def __init__(self):
""""""
pass
class GridSizer(Sizer):
""""""
def CalcMin(self):
""""""
pass
def GetCols(self):
""""""
pass
def GetHGap(self):
""""""
pass
def GetRows(self):
""""""
pass
def GetVGap(self):
""""""
pass
def RecalcSizes(self):
""""""
pass
def SetCols(self):
""""""
pass
def SetHGap(self):
""""""
pass
def SetRows(self):
""""""
pass
def SetVGap(self):
""""""
pass
def __init__(self):
""""""
pass
class FlexGridSizer(GridSizer):
""""""
def AddGrowableCol(self):
""""""
pass
def AddGrowableRow(self):
""""""
pass
def CalcMin(self):
""""""
pass
def RecalcSizes(self):
""""""
pass
def RemoveGrowableCol(self):
""""""
pass
def RemoveGrowableRow(self):
""""""
pass
def __init__(self):
""""""
pass
class NotebookSizer(Sizer):
""""""
def CalcMin(self):
""""""
pass
def GetNotebook(self):
""""""
pass
def RecalcSizes(self):
""""""
pass
def __init__(self):
""""""
pass
class PySizer(Sizer):
""""""
def __init__(self):
""""""
pass
def _setCallbackInfo(self):
""""""
pass
class StaticBoxSizer(BoxSizer):
""""""
def CalcMin(self):
""""""
pass
def GetStaticBox(self):
""""""
pass
def RecalcSizes(self):
""""""
pass
def __init__(self):
""""""
pass

View File

@@ -0,0 +1,201 @@
#----------------------------------------------------------------------
# Name: wxPython.lib.analogclock
# Purpose: A simple analog clock window
#
# Author: several folks on wxPython-users
#
# Created: 16-April-2003
# RCS-ID: $Id$
# Copyright: (c) 2003 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
import math, sys, string, time
from wxPython.wx import *
class AnalogClockWindow(wxWindow):
"""A simple analog clock window"""
TICKS_NONE = 0
TICKS_SQUARE = 1
TICKS_CIRCLE = 2
def __init__(self, parent, ID=-1, pos=wxDefaultPosition, size=wxDefaultSize,
style=0, name="clock"):
# Initialize the wxWindow...
wxWindow.__init__(self, parent, ID, pos, size, style, name)
# Initialize the default clock settings...
self.minuteMarks = 60
self.hourMarks = 12
self.tickMarksBrushC = self.GetForegroundColour()
self.tickMarksPenC = self.GetForegroundColour()
self.tickMarkStyle = self.TICKS_SQUARE
# Make an initial bitmap for the face, it will be updated and
# painted at the first EVT_SIZE event.
W, H = size
self.faceBitmap = wxEmptyBitmap(max(W,1), max(H,1))
# Initialize the timer that drives the update of the clock
# face. Update every half second to ensure that there is at
# least one true update during each realtime second.
self.timer = wxTimer(self)
self.timer.Start(500)
# Set event handlers...
EVT_PAINT(self, self.OnPaint)
EVT_ERASE_BACKGROUND(self, lambda x: None)
EVT_SIZE(self, self.OnSize)
EVT_TIMER(self, -1, self.OnTimerExpire)
EVT_WINDOW_DESTROY(self, self.OnQuit)
def SetTickMarkStyle(self, style):
"""
Set the style of the marks around the edge of the clock.
Options are TICKS_NONE, TICKS_SQUARE, and TICKS_CIRCLE
"""
self.tickMarkStyle = style
def SetTickMarkColours(self, brushC, penC="BLACK"):
"""
Set the brush colour and optionally the pen colour of
the marks around the edge of the clock.
"""
self.tickMarksBrushC = brushC
self.tickMarksPenC = penC
SetTickMarkColour = SetTickMarkColours
def SetHandsColour(self, c):
"""An alias for SetForegroundColour"""
self.SetForegroundColour(c) # the hands just use the foreground colour
# Using the current settings, render the points and line endings for the
# circle inside the specified device context. In this case, the DC is
# a memory based device context that will be blitted to the actual
# display DC inside the OnPaint() event handler.
def OnSize(self, event):
# The faceBitmap init is done here, to make sure the buffer is always
# the same size as the Window
size = self.GetClientSize()
self.faceBitmap = wxEmptyBitmap(size.width, size.height)
self.DrawFace()
def OnPaint(self, event):
self.DrawHands(wxPaintDC(self))
def OnQuit(self, event):
self.timer.Stop()
del self.timer
def OnTimerExpire(self, event):
self.DrawHands(wxClientDC(self))
def DrawHands(self, drawDC):
# Start by drawing the face bitmap
drawDC.DrawBitmap(self.faceBitmap,0,0)
currentTime = time.localtime(time.time())
hour, minutes, seconds = currentTime[3:6]
W,H = self.faceBitmap.GetWidth(), self.faceBitmap.GetHeight()
centerX = W / 2
centerY = H / 2
radius = min(centerX, centerY)
hour += minutes / 60.0 # added so the hour hand moves continuously
x, y = self.point(hour, 12, (radius * .65))
hourX, hourY = (x + centerX), (centerY - y)
x, y = self.point(minutes, 60, (radius * .85))
minutesX, minutesY = (x + centerX), (centerY - y)
x, y = self.point(seconds, 60, (radius * .85))
secondsX, secondsY = (x + centerX), (centerY - y)
# Draw the hour hand...
drawDC.SetPen(wxPen(self.GetForegroundColour(), 5, wxSOLID))
drawDC.DrawLine(centerX, centerY, hourX, hourY)
# Draw the minutes hand...
drawDC.SetPen(wxPen(self.GetForegroundColour(), 3, wxSOLID))
drawDC.DrawLine(centerX, centerY, minutesX, minutesY)
# Draw the seconds hand...
drawDC.SetPen(wxPen(self.GetForegroundColour(), 1, wxSOLID))
drawDC.DrawLine(centerX, centerY, secondsX, secondsY)
# Draw the specified set of line marks inside the clock face for the
# hours or minutes...
def DrawFace(self):
backgroundBrush = wxBrush(self.GetBackgroundColour(), wxSOLID)
drawDC = wxMemoryDC()
drawDC.SelectObject(self.faceBitmap)
drawDC.SetBackground(backgroundBrush)
drawDC.Clear()
W,H = self.faceBitmap.GetWidth(), self.faceBitmap.GetHeight()
centerX = W / 2
centerY = H / 2
# Draw the marks for hours and minutes...
self.DrawTimeMarks(drawDC, self.minuteMarks, centerX, centerY, 4)
self.DrawTimeMarks(drawDC, self.hourMarks, centerX, centerY, 9)
def DrawTimeMarks(self, drawDC, markCount, centerX, centerY, markSize):
for i in range(markCount):
x, y = self.point(i + 1, markCount, min(centerX,centerY) - 16)
scaledX = x + centerX - markSize/2
scaledY = centerY - y - markSize/2
drawDC.SetBrush(wxBrush(self.tickMarksBrushC, wxSOLID))
drawDC.SetPen(wxPen(self.tickMarksPenC, 1, wxSOLID))
if self.tickMarkStyle != self.TICKS_NONE:
if self.tickMarkStyle == self.TICKS_CIRCLE:
drawDC.DrawEllipse(scaledX - 2, scaledY, markSize, markSize)
else:
drawDC.DrawRectangle(scaledX - 3, scaledY, markSize, markSize)
def point(self, tick, range, radius):
angle = tick * (360.0 / range)
radiansPerDegree = math.pi / 180
pointX = int(round(radius * math.sin(angle * radiansPerDegree)))
pointY = int(round(radius * math.cos(angle * radiansPerDegree)))
return wxPoint(pointX, pointY)
if __name__ == "__main__":
class App(wxApp):
def OnInit(self):
frame = wxFrame(None, -1, "AnalogClockWindow Test", size=(375,375))
clock = AnalogClockWindow(frame)
clock.SetTickMarkColours("RED")
clock.SetHandsColour("WHITE")
clock.SetBackgroundColour("BLUE")
frame.Centre(wxBOTH)
frame.Show(True)
self.SetTopWindow(frame)
return true
theApp = App(0)
theApp.MainLoop()

View File

@@ -716,12 +716,12 @@ class CalenDlg(wxDialog):
monthlist = GetMonthList()
# select the month
mID = NewId()
mID = wxNewId()
self.date = wxComboBox(self, mID, Month[start_month], wxPoint(20, 20), wxSize(90, -1), monthlist, wxCB_DROPDOWN)
EVT_COMBOBOX(self, mID, self.EvtComboBox)
# alternate spin button to control the month
mID = NewId()
mID = wxNewId()
h = self.date.GetSize().height
self.m_spin = wxSpinButton(self, mID, wxPoint(130, 20), wxSize(h*2, h), wxSP_VERTICAL)
self.m_spin.SetRange(1, 12)
@@ -730,7 +730,7 @@ class CalenDlg(wxDialog):
EVT_SPIN(self, mID, self.OnMonthSpin)
# spin button to control the year
mID = NewId()
mID = wxNewId()
self.dtext = wxTextCtrl(self, -1, str(start_year), wxPoint(160, 20), wxSize(60, -1))
h = self.dtext.GetSize().height
@@ -746,11 +746,11 @@ class CalenDlg(wxDialog):
y_pos = 280
but_size = wxSize(60, 25)
mID = NewId()
mID = wxNewId()
wxButton(self, mID, ' Ok ', wxPoint(x_pos, y_pos), but_size)
EVT_BUTTON(self, mID, self.OnOk)
mID = NewId()
mID = wxNewId()
wxButton(self, mID, ' Close ', wxPoint(x_pos + 120, y_pos), but_size)
EVT_BUTTON(self, mID, self.OnCancel)

View File

@@ -33,15 +33,16 @@ class wxScrolledMessageDialog(wx.wxDialog):
class wxMultipleChoiceDialog(wx.wxDialog):
def __init__(self, parent, msg, title, lst, pos = wx.wxDefaultPosition, size = (200,200)):
wx.wxDialog.__init__(self, parent, -1, title, pos, size)
def __init__(self, parent, msg, title, lst, pos = wx.wxDefaultPosition,
size = (200,200), style = wx.wxDEFAULT_DIALOG_STYLE):
wx.wxDialog.__init__(self, parent, -1, title, pos, size, style)
x, y = pos
if x == -1 and y == -1:
self.CenterOnScreen(wx.wxBOTH)
dc = wx.wxClientDC(self)
height = 0
for line in msg.splitlines():
height = height + dc.GetTextExtent(msg)[1] + 4
height = height + dc.GetTextExtent(line)[1] + 2
stat = wx.wxStaticText(self, -1, msg)
self.lbox = wx.wxListBox(self, 100, wx.wxDefaultPosition,
wx.wxDefaultSize, lst, wx.wxLB_MULTIPLE)

View File

@@ -8,7 +8,7 @@
#
# Created: 12-December-2002
# RCS-ID: $Id$
# Copyright: (c) 2002 by Robb Shecter <robb@acm.org>
# Copyright: (c) 2003 by db-X Corporation
# Licence: wxWindows license
#---------------------------------------------------------------------------
@@ -32,7 +32,6 @@ programmer to declare or track control ids or parent containers:
This module is Python 2.1+ compatible.
Author: Robb Shecter
"""
from wxPython import wx
import pubsub
@@ -176,7 +175,7 @@ class EventManager:
Return a dictionary with data about my state.
"""
stats = {}
stats['Adapters: Message'] = reduce(lambda x,y: x+y, map(len, self.messageAdapterDict.values()))
stats['Adapters: Message'] = reduce(lambda x,y: x+y, [0] + map(len, self.messageAdapterDict.values()))
stats['Adapters: Event'] = len(self.eventAdapterDict)
stats['Topics: Total'] = len(self.__getTopics())
stats['Topics: Dead'] = len(self.GetDeadTopics())
@@ -193,7 +192,7 @@ class EventManager:
is a problem.
"""
for topic in self.GetDeadTopics():
self.DeregisterTopic(topic)
self.__deregisterTopic(topic)
def GetDeadTopics(self):

View File

@@ -133,6 +133,7 @@ class ImageDialog(wxDialog):
size = wxSize(80, 25)
self.set_dir = os.getcwd()
self.set_file = None
if set_dir != None:
if os.path.exists(set_dir): # set to working directory if nothing set

View File

@@ -130,12 +130,12 @@ class _MyStatusBar(wxStatusBar):
self.SetStatusText("",0)
ID = NewId()
ID = wxNewId()
self.button1 = wxButton(self,ID,"Dismiss",
style=wxTAB_TRAVERSAL)
EVT_BUTTON(self,ID,self.OnButton1)
ID = NewId()
ID = wxNewId()
if not useopenbutton:
self.button2 = wxButton(self,ID,"Close File",
style=wxTAB_TRAVERSAL)

View File

@@ -338,17 +338,18 @@ class wxIntCtrl(wxTextCtrl):
wxIntCtrl(
parent, id = -1,
value = 0,
pos = wxDefaultPosition,
size = wxDefaultSize,
style = 0,
validator = wxDefaultValidator,
name = "integer",
min = None,
max = None,
limited = False,
allow_none = False,
allow_long = False,
default_color = wxBLACK,
oob_color = wxRED,
pos = wxDefaultPosition,
size = wxDefaultSize,
style = 0,
name = "integer")
oob_color = wxRED )
value
If no initial value is set, the default will be zero, or
@@ -390,14 +391,22 @@ class wxIntCtrl(wxTextCtrl):
oob_color
Color value used for out-of-bounds values of the control
when the bounds are set but the control is not limited.
validator
Normally None, wxIntCtrl uses its own validator to do value
validation and input control. However, a validator derived
from wxIntValidator can be supplied to override the data
transfer methods for the wxIntValidator class.
"""
def __init__ (
self, parent, id=-1,
pos = wxDefaultPosition, size = wxDefaultSize,
style = 0, validator = wxDefaultValidator,
name = "integer",
value = 0, min=None, max=None,
limited = 0, allow_none = 0, allow_long = 0,
default_color = wxBLACK, oob_color = wxRED,
pos = wxDefaultPosition, size = wxDefaultSize,
style = 0, name = "integer",
):
# Establish attrs required for any operation on value:
@@ -408,10 +417,14 @@ class wxIntCtrl(wxTextCtrl):
self.__oob_color = wxRED
self.__allow_none = 0
self.__allow_long = 0
self.__oldvalue = None
if validator == wxDefaultValidator:
validator = wxIntValidator()
wxTextCtrl.__init__(
self, parent, id, self._toGUI(0),
pos, size, style, wxIntValidator(), name )
pos, size, style, validator, name )
# The following lets us set out our "integer update" events:
EVT_TEXT( self, self.GetId(), self.OnText )
@@ -424,20 +437,28 @@ class wxIntCtrl(wxTextCtrl):
self.SetNoneAllowed(allow_none)
self.SetLongAllowed(allow_long)
self.SetValue(value)
self.__oldvalue = 0
def OnText( self, event ):
"""
Handles an event indicating that the text control's value
has changed, and issue EVT_INT event.
NOTE: using wxTextCtrl.SetValue() to change the control's
contents from within a EVT_CHAR handler can cause double
text events. So we check for actual changes to the text
before passing the events on.
"""
try:
self.GetEventHandler().ProcessEvent(
wxIntUpdatedEvent( self.GetId(), self.GetValue(), self ) )
except ValueError:
return
# let normal processing of the text continue
event.Skip()
value = self.GetValue()
if value != self.__oldvalue:
try:
self.GetEventHandler().ProcessEvent(
wxIntUpdatedEvent( self.GetId(), self.GetValue(), self ) )
except ValueError:
return
# let normal processing of the text continue
event.Skip()
self.__oldvalue = value # record for next event
def GetValue(self):
@@ -719,6 +740,13 @@ class wxIntCtrl(wxTextCtrl):
"""
Conversion function used in getting the value of the control.
"""
# One or more of the underlying text control implementations
# issue an intermediate EVT_TEXT when replacing the control's
# value, where the intermediate value is an empty string.
# So, to ensure consistency and to prevent spurious ValueErrors,
# we make the following test, and react accordingly:
#
if value == '':
if not self.IsNoneAllowed():
return 0
@@ -811,7 +839,7 @@ if __name__ == '__main__':
style = wxDEFAULT_DIALOG_STYLE ):
wxDialog.__init__(self, parent, id, title, pos, size, style)
self.int_ctrl = wxIntCtrl(self, NewId(), size=(55,20))
self.int_ctrl = wxIntCtrl(self, wxNewId(), size=(55,20))
self.OK = wxButton( self, wxID_OK, "OK")
self.Cancel = wxButton( self, wxID_CANCEL, "Cancel")

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,21 @@
#---------------------------------------------------------------------------
# Name: wxPython.lib.mixins.rubberband
# Purpose: A mixin class for doing "RubberBand"-ing on a window.
#
# Author: Robb Shecter and members of wxPython-users
#
# Created: 11-September-2002
# RCS-ID: $Id$
# Copyright: (c) 2002 by db-X Corporation
# Licence: wxWindows license
#---------------------------------------------------------------------------
"""
A mixin class for doing "RubberBand"-ing on a window.
by "Robb Shecter" <rs@onsitetech.com>
$Id$
"""
from wxPython.wx import *
import Image
#
# Some miscellaneous mathematical and geometrical functions

View File

@@ -140,7 +140,7 @@ class PopButton(wxPyControl):
# Tried to use wxPopupWindow but the control misbehaves on MSW
class wxPopupDialog(wxDialog):
def __init__(self,parent,content = None):
wxDialog.__init__(self,parent,-1,'', style = wxSTAY_ON_TOP)
wxDialog.__init__(self,parent,-1,'', style = wxBORDER_SIMPLE|wxSTAY_ON_TOP)
self.ctrl = parent
self.win = wxWindow(self,-1,pos = wxPoint(0,0),style = 0)
@@ -197,6 +197,12 @@ class wxPopupControl(wxPyControl):
EVT_SIZE(self,self.OnSize)
EVT_BUTTON(self.bCtrl,self.bCtrl.GetId(),self.OnButton)
# embedded control should get focus on TAB keypress
EVT_SET_FOCUS(self,self.OnFocus)
def OnFocus(self,evt):
self.textCtrl.SetFocus()
evt.Skip()
def OnSize(self,evt):
w,h = self.GetClientSizeTuple()

View File

@@ -6,7 +6,7 @@
#
# Created: 12-December-2002
# RCS-ID: $Id$
# Copyright: (c) 2002 by Robb Shecter <robb@acm.org>
# Copyright: (c) 2002 by db-X Corporation
# Licence: wxWindows license
#---------------------------------------------------------------------------
"""

View File

@@ -28,6 +28,9 @@ Hope this can help someone, as much as this list helps me.
Josu Oyanguren
Ubera Servicios Inform<72>ticos.
P.S. This only works well on wxMSW.
"""
from wxPython.wx import *
@@ -51,6 +54,12 @@ class wxRightTextCtrl(wxTextCtrl):
y = (dcheight - textheight) / 2
x = dcwidth - textwidth - 2
if self.IsEnabled():
fclr = self.GetForegroundColour()
else:
fclr = wxSystemSettings_GetColour(wxSYS_COLOUR_GRAYTEXT)
dc.SetTextForeground(fclr)
dc.SetClippingRegion(0, 0, dcwidth, dcheight)
dc.DrawText(text, x, y)

View File

@@ -27,8 +27,10 @@ as a proper class (and the demo is now converted to just use it.)
pos=pos, size=size,
style=style, name=name)
EVT_CHILD_FOCUS(self, self.OnChildFocus)
def SetupScrolling(self, scroll_x=True, scroll_y=True, rate_x=1, rate_y=1):
def SetupScrolling(self, scroll_x=True, scroll_y=True, rate_x=20, rate_y=20):
"""
This function sets up the event handling necessary to handle
scrolling properly. It should be called within the __init__
@@ -42,10 +44,18 @@ as a proper class (and the demo is now converted to just use it.)
if not scroll_x: rate_x = 0
if not scroll_y: rate_y = 0
self.SetScrollRate(rate_x, rate_y)
# Round up the virtual size to be a multiple of the scroll rate
sizer = self.GetSizer()
if sizer:
w, h = sizer.GetMinSize()
if rate_x:
w += rate_x - (w % rate_x)
if rate_y:
h += rate_y - (h % rate_y)
self.SetVirtualSize( (w, h) )
self.SetVirtualSizeHints( w, h )
self.GetSizer().SetVirtualSizeHints(self)
EVT_CHILD_FOCUS(self, self.OnChildFocus)
self.SetScrollRate(rate_x, rate_y)
wxCallAfter(self.Scroll, 0, 0) # scroll back to top after initial events

View File

@@ -26,7 +26,8 @@ class wxGenStaticText(wxPyControl):
pos = wxDefaultPosition, size = wxDefaultSize,
style = 0,
name = "genstattext"):
wxPyControl.__init__(self, parent, ID, pos, size, style, wxDefaultValidator, name)
wxPyControl.__init__(self, parent, ID, pos, size, style|wxNO_BORDER,
wxDefaultValidator, name)
wxPyControl.SetLabel(self, label) # don't check wxST_NO_AUTORESIZE yet
self.SetPosition(pos)
@@ -35,10 +36,10 @@ class wxGenStaticText(wxPyControl):
font = wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT)
wxPyControl.SetFont(self, font) # same here
clr = parent.GetBackgroundColour()
if not clr.Ok():
clr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE)
self.SetBackgroundColour(clr)
self.defBackClr = parent.GetBackgroundColour()
if not self.defBackClr.Ok():
self.defBackClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_3DFACE)
self.SetBackgroundColour(self.defBackClr)
clr = parent.GetForegroundColour()
if not clr.Ok():
@@ -105,7 +106,14 @@ class wxGenStaticText(wxPyControl):
width, height = self.GetClientSize()
if not width or not height:
return
dc.SetBackground(wxBrush(self.GetBackgroundColour(), wxSOLID))
clr = self.GetBackgroundColour()
backBrush = wxBrush(clr, wxSOLID)
if wxPlatform == "__WXMAC__" and clr == self.defBackClr:
# if colour still the default the use the striped background on Mac
backBrush.SetMacTheme(1) # 1 == kThemeBrushDialogBackgroundActive
dc.SetBackground(backBrush)
dc.SetTextForeground(self.GetForegroundColour())
dc.Clear()
dc.SetFont(self.GetFont())

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,594 @@
0.9.2 (5/3/2003 to //2003)
-----------------------------
Changed to the new prefix-less "wx" package::
import wx
instead of::
from wxPython import wx
Fixed typo in ``PyWrap.py``::
if __name__ == '__main__':
main(sys.argv)
should have been::
if __name__ == '__main__':
main()
Added pretty-print Display tab to Crust, based on suggestion from
Jason Whitlark.
Improved ``Can*`` checks in ``EditWindow``, since STC is too lenient,
particularly when it is set to read-only but returns True for
CanPaste() (seems like an STC bug to me)::
def CanCopy(self):
"""Return True if text is selected and can be copied."""
return self.GetSelectionStart() != self.GetSelectionEnd()
def CanCut(self):
"""Return True if text is selected and can be cut."""
return self.CanCopy() and self.CanEdit()
def CanEdit(self):
"""Return True if editing should succeed."""
return not self.GetReadOnly()
def CanPaste(self):
"""Return True if pasting should succeed."""
return stc.StyledTextCtrl.CanPaste(self) and self.CanEdit()
0.9.1 (3/21/2003 to 5/2/2003)
-----------------------------
PyCrust is dead! Long live Py!
* Renamed ``PyCrust`` package to ``py``.
* Moved code to wxPython's CVS repository.
Fixed bug in ``introspect.py`` on introspecting objects occurring
immediately after a secondary prompt, like this::
>>> l = [1, 2, 3]
>>> for n in range(3):
... l. <-- failed to popup autocomplete list
Added documentation files:
* PyManual.txt
* wxPythonManual.txt
* wxPythonPackage.txt
* wxPythonExamples.txt
Added PyAlaMode and PyAlaCarte code editors.
Major refactoring to support ``editor`` and ``shell`` from the same
base.
Renamed program files:
* ``PyCrustApp.py`` to ``PyCrust.py``
* ``PyFillingApp.py`` to ``PyFilling.py``
* ``PyShellApp.py`` to ``PyShell.py``
* ``wrap.py`` to ``PyWrap.py``
Removed disabling of autocomplete for lists of 2000 items or more.
The current implementation of wxSTC can now handle lists this big.
Improved handling of ``sys.path`` to mimic the standard Python shell.
0.9 (2/27/2003 to 3/20/2003)
----------------------------
Added fontIncrease, fontDecrease, fontDefault signals, receivers and
keybindings::
Ctrl+] Increase font size.
Ctrl+[ Decrease font size.
Ctrl+= Default font size.
Continued enhancement of the decorator capability to provide better
documentation and docstrings for wxPython classes and functions.
Introduced new tabbed interface:
* Namespace
* Calltip
* Session
* Dispatcher
* wxPython Docs
* wxSTC Docs
``Filling.tree`` now expands tuples as well as lists. (It should have
done this all along, I just never noticed this omission before.)
Added this True/False test to all modules::
try:
True
except NameError:
True = 1==1
False = 1==0
Added ``wxd`` directory with decoration classes.
0.8.2 (1/5/2003 to 2/26/2003)
-----------------------------
Wrapped ``sys.ps1``, ``sys.ps2``, and ``sys.ps3`` in ``str()``.
(Thanks, Kieran Holland.)
Fixed minor things found by PyChecker.
Changed locals to use ``__main__.__dict__`` and added code to clean up
the namespace, making it as close to the regular Python environment as
possible. This solves the problem of pickling and unpickling
instances of classes defined in the shell.
Made ``shell.PasteAndRun()`` a little more forgiving when it finds a
ps2 prompt line with no trailing space, such when you copy code from a
web page.
Improved autocomplete behavior by adding these to shell::
self.AutoCompSetAutoHide(False)
self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`')
Added ``decor`` directory, ``decorator.py``, ``stcDecor.py``, and
``stcConstants.py``. These all serve the purpose of adding docstrings
to existing wxPython classes, in particular the ``wxStyledTextCtrl``.
Added ``wrap.py``, a command line utility for running a wxPython app
with additional runtime-tools loaded, such as PyCrust (the only tool
at this point).
Flushed the clipboard Cut/Copy operations so that selections will
exist in the clipboard even after PyCrust has been closed.
Improved the suppression of docstrings for simple data types appearing
in the namespace viewer.
Better handling of autocompletion with numeric types; no
autocompletion when typing a dot after an integer. If the
autocompletion is desired, type a space before the dot::
func = 3 .
More Filling!!! The namespace tree is now dynamically updated.
0.8.1 (12/20/2002 to 12/25/2002)
--------------------------------
Improved keyboard handling with Autocomplete active. You can now use
Enter as well as Tab to select an item from the list.
Disabled autocomplete for lists of 2000 items or more. The current
implementation of wxSTC can't handle lists this big.
Changed ``filling`` to always display docstrings for objects. This is
useful for objects whose docstrings have been decorated, rather than
coming directly from the source code. (Hmmm. Sounds like someone is
doing some decorating. I wonder where that would be helpful? <wink>)
Fixed handling of icon. Added ``images.py`` file.
0.8 (10/29/2002 to 12/16/2002)
------------------------------
Added "help" to startup banner info.
Made all ``wx`` and ``stc`` imports explicit. No more ``import *``.
Replaced use of the ``wx`` module's ``true`` and ``false`` with
Python's ``True`` and ``False``.
Changed ``introspect.getRoot()`` to use ``tokenize`` module. This
does a slightly better job than the previous parsing routine and the
code is clearer.
Improved handling of whitespace and empty types during introspection.
Fixed cut/copy clipboard problem under Linux. (Robin Dunn rocks!!!)
Added shell.about() which works like this::
>>> shell.about()
PyCrust Version: 0.8
Shell Revision: 1.80
Interpreter Revision: 1.15
Python Version: 2.2.2
wxPython Version: 2.3.3.1
Platform: linux2
Added copy plus and paste plus to shell menu.
Moved shell menu from ``shell.py`` to ``shellmenu.py``.
Added ``sys.stdin.readlines()`` support.
Added ``time.sleep()`` in ``readline()`` and ``OnIdle()`` event
handler to free up the CPU.
0.7.2 (2/22/2002 to 8/27/2002)
------------------------------
Tweaked ``getAttributeNames()`` to pick up a few more attributes::
'__bases__', '__class__', '__dict__', '__name__', 'func_closure',
'func_code', 'func_defaults', 'func_dict', 'func_doc',
'func_globals', 'func_name'
Added a tests directory and unit tests.
Improved support for empty types in the shell: ``[]``, ``()`` and
``{}`` as far as when call tips and autocompletion are available.
Added support for the other triple string - ``''''''``.
Refactored ``introspect.py`` to improve testability.
Improved call tips for unbound methods by leaving the "self"
parameter, since unbound methods require an instance be passed.
Fixed call tip bug where a tip was displayed when a "(" was typed
after an object that wasn't callable.
Fixed ``getAllAttributeNames`` when ``str(object)`` fails.
Added brace highlighting. (Thank you, Kevin Altis.)
Fixed problem displaying unicode objects in ``PyFilling``.
Changed how ``filling.py`` checks for expandable objects. Lists are
now expandable objects.
Made the key handling more robust when there is an active text
selection that includes text prior to the last primary prompt. Thanks
to Raul Cota for pointing this out.
Fixed wxSTC problem with brace highlighting and non-us keyboards.
(Thank you for the patch, Jean-Michel Fauth.)
Added ``busy = wxBusyCursor()`` to key points in ``shell`` and
``filling``.
Added ``OnCloseWindow`` handler to ``ShellFrame`` and ``CrustFrame``.
Default to ``SetWrapMode(1)`` for shell and namespace viewer.
Added ``shell.wrap()`` and ``shell.zoom()``.
Added autoCompleteKeys hooks for Raul Cota.
Cleaned up various little key handling bugs.
Changed input methods to get values from shell, rather than dialog
boxes. Renamed ``readIn`` to ``readline`` and ``readRaw`` to
``raw_input``.
0.7.1 (12/12/2001 to 2/21/2002)
-------------------------------
Fixed ``OnChar()`` issues effecting European keyboards, as reported by
Jean-Michel Fauth.
Fixed ``introspect.py`` issue with xmlrpc objects reported by Kevin
Altis.
Fixed some introspect/PyFilling issues with regard to Python 2.2.
Fixed font background color as reported by Keith J. Farmer. (Thanks)
Fixed problem with call tips and autocompletion inside multiline
commands as report by Kevin Altis.
Improved ``OnKeyDown`` handling of cut/copy/paste operations based on
feedback from Syver Enstad. (Thanks)
Added a ``shell.help()`` method to display some help info.
Changed sort of items in the namespace viewer to case insensitive.
Changed ``attributes.sort(lambda x, y: cmp(x.upper(), y.upper()))`` in
advance of an upcoming fix to an autocompletion matching bug in wxSTC.
Improved support for ZODB by allowing namespace drilldown into BTrees.
Added ``shell.PasteAndRun()`` to support pasting multiple commands into
the shell from the clipboard. Ctrl+Shift+V or v.
Enter now always processes a command (or copies down a previous one.)
To insert a line break, press Ctrl+Enter.
Escape key clears the current, unexecuted command.
History retrieval changed to replace current command. Added new keys
to insert from history - Shift+Up and Shift+Down.
Better call tips on objects with ``__call__`` methods.
Improved call tip positioning calculation.
0.7 (10/15/2001 to 12/11/2001)
------------------------------
Changed how command history retrieval functions work. Added Alt-P,
Alt-N as keybindings for Retrieve-Previous, Retrieve-Next.
Added full support for multi-line commands, similar to IDLE.
Changed ``introspect.getAttributeNames()`` to do a case insensitive
sort.
Changed Cut/Copy/Paste to deal with prompts intelligently. Cut and
Copy remove all prompts. Paste can handle prompted or not-prompted
text.
Added ``CopyWithPrompts()`` method attached to Ctrl-Shift-C for those
times when you really do want all the prompts left intact.
Improved handling of the shell's read-only zone.
Changed ``CrustFrame.__init__`` parameter spec to include all
parameters allowed by a ``wxFrame``.
Changed ``FillingText`` to be read-only.
Renamed ``PyCrust.py`` to ``PyCrustApp.py`` to eliminate
package/module name conflicts that kept you from doing ``from PyCrust
import shell`` inside files located in the ``PyCrust`` directory.
Renamed ``PyFilling.py`` to ``PyFillingApp.py`` and ``PyShell.py`` to
``PyShellApp.py`` to maintain consistency.
Removed the ``__date__`` property from all modules.
Fixed bug in ``introspect.getCallTip()``, reported by Kevin Altis.
0.6.1 (9/19/2001 to 10/12/2001)
-------------------------------
Changed ``Shell.run()`` to always position to the end of existing
text, as suggested by Raul Cota.
Changed ``introspect.getAllAttributeNames()`` to break circular
references in ``object.__class__``, which occurs in Zope/ZODB
extension classes.
Changed ``filling.FillingTree.getChildren()`` to introspect extension
classes.
Fixed minor bugs in ``introspect.getCallTip()`` that were interfering
with call tips for Zope/ZODB extension class methods.
In preparation for wxPython 2.3.2, added code to fix a font sizing
problem. Versions of wxPython prior to 2.3.2 had a sizing bug on Win
platform where the font was 2 points larger than what was specified.
Added a hack to ``introspect.getAllAttributeNames()`` to "wake up"
ZODB objects that are asleep - in a "ghost" state. Otherwise it
returns incomplete info.
0.6 (8/21/2001 to 9/12/2001)
----------------------------
Added ``PyFilling.py`` and ``filling.py``.
``PyShell.py`` and ``PyFilling.py`` can now be run standalone, as well
as ``PyCrust.py``.
Added ``crust.py`` and moved some code from ``PyCrust.py`` to it.
Added command history retrieval features submitted by Richie Hindle.
Changed ``shell.write()`` to replace line endings with OS-specific
endings. Changed ``shell.py`` and ``interpreter.py`` to use
``os.linesep`` in strings having hardcoded line endings.
Added ``shell.redirectStdin()``, ``shell.redirectStdout()`` and
``shell.redirectStderr()`` to allow the surrounding app to toggle
requests that the specified ``sys.std*`` be redirected to the shell.
These can also be run from within the shell itself, of course.
The shell now adds the current working directory "." to the search
path::
sys.path.insert(0, os.curdir)
Added support for distutils installations.
0.5.4 (8/17/2001 to 8/20/2001)
------------------------------
Changed default font size under Linux to::
'size' : 12,
'lnsize' : 10,
Changed ``Shell`` to expect a parameter referencing an Interpreter
class, rather than an intepreter instance, to facilitate subclassing
of Interpreter, which effectively broke when the Editor class was
eliminated.
Fixed ``PyCrustAlaCarte.py``, which had been broken by previous
changes.
Created ``InterpreterAlaCarte`` class as an example for use in the
demo.
Split ``PyCrust.py`` into ``PyCrust.py`` and ``PyShell.py`` in
anticipation of ``PyFilling.py``.
0.5.3 (8/16/2001)
-----------------
Added patch to ``PyCrust.py`` to fix wxPython bug::
wxID_SELECTALL = NewId() # This *should* be defined by wxPython.
0.5.2 (8/14/2001 to 8/15/2001)
------------------------------
Shortened module names by dropping "PyCrust" as a prefix.
Changed ``version`` to ``VERSION`` in ``version`` module.
Added Options menu to PyCrust application.
Eliminated the Editor class (and editor module) by merging with Shell.
This means that Shell "is a" wxStyledTextCtrl rather than "has a".
There just wasn't enough non-gui code to justify the separation.
Plus, Shell will be much easier for gui toolkits/designers to deal
with now.
0.5.1 (8/10/2001 to 8/14/2001)
------------------------------
Added ``introspect`` module.
Moved some functionality from ``PyCrustInterp`` to ``introspect``.
Changed ``introspect.getRoot()`` to no longer remove whitespace from
the command. This was a remnant of a previous approach that, when
left as part of the current approach, turned out to be a really bad
thing.
Changed ``introspect.getRoot()`` to allow commands of ``''``, ``""``,
``""""""``, ``[]``, ``()``, and ``{}`` to pass through. This allows
you to type them, followed by a dot, and get autocomplete options on
them.
Changed ``introspect.getRoot()`` to identify some situations where
strings shouldn't be considered roots. For example::
>>> import PyCrust # To illustrate the potential problem.
>>> len('PyCrust.py')
Typing the dot at the end of "PyCrust" in the second line above should
NOT result in an autocompletion list because "PyCrust" is part of a
string in this context, not a reference to the PyCrust module object.
Similar reasoning applies to call tips. For example::
>>> len('dir(')
Typing the left paren at the end of "dir" should NOT result in a call
tip.
Both features now behave properly in the examples given. However,
there is still the case where whitespace precedes the potential root
and that is NOT handled properly. For example::
>>> len('this is a dir(')
and::
>>> len('This is PyCrust.py')
More code needs to be written to handle more complex situations.
Added ``locals=None`` parameter to ``Shell.__init__()``.
Added support for magic attribute retrieval. Users can change this
with::
>>> shell.editor.autoCompleteIncludeMagic = 0
Added the ability to set filters on auto completion to exclude
attributes prefixed with a single or double underscore. Users can
exclude one or the other or both with::
>>> shell.editor.autoCompleteExcludeSingle = 1
>>> shell.editor.autoCompleteExcludeDouble = 1
0.5 (8/8/2001)
--------------
Mostly just a final version change before creating a release.
0.4 (8/4/2001 to 8/7/2001)
--------------------------
Changed version/revision handling.
Fixed bugs.
0.3 (8/2/2001 to 8/3/2001)
--------------------------
Removed lots of cruft.
Added lots of docstrings.
Imported to CVS repository at SourceForge.
Added call tips.
0.2 (7/30/2001 to 8/2/2001)
---------------------------
Renamed several files.
Added command autocompletion.
Added menus to PyCrust.py: File, Edit and Help.
Added sample applications: ``PyCrustAlaCarte.py``,
``PyCrustAlaMode.py``, and ``PyCrustMinimus.py``.
0.1 (7/1/2001 to 7/19/2001)
---------------------------
Added basic syntax coloring much like Boa.
Added read-only logging much like IDLE.
Can retrieve a previous command by putting the cursor back on that
line and hitting enter.
Stdin and raw_input operate properly so you can now do ``help()`` and
``license()`` without hanging.
Redefined "quit", "exit", and "close" to display a better-than-nothing
response.
Home key honors the prompt.
Created SourceForge account, but nothing was posted.
In the beginning, there was pie... (7/1/2001)
---------------------------------------------
Blame it all on IDLE, Boa and PythonWin. I was using all three, got
frustrated with their dissimilarities, and began to let everyone know
how I felt. At the same time, Scintilla looked like an interesting
tool to build a shell around. And while I didn't receive much in the
way of positive feedback, let alone encouragement, I just couldn't let
go of the idea of a Scintilla-based Python shell. Then the PythonCard
project got to the point where they were talking about including a
shell in their development environment. That was all the incentive I
needed. PyCrust had to happen...

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,43 @@
"""PyAlaCarte is a simple programmer's editor."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
import os
import sys
import editor
try:
True
except NameError:
True = 1==1
False = 1==0
class App(wx.App):
"""PyAlaCarte standalone application."""
def __init__(self, filename=None):
self.filename = filename
wx.App.__init__(self, redirect=False)
def OnInit(self):
wx.InitAllImageHandlers()
self.frame = editor.EditorFrame(filename=self.filename)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main(filename=None):
if not filename and len(sys.argv) > 1:
filename = sys.argv[1]
if filename:
filename = os.path.realpath(filename)
app = App(filename)
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,43 @@
"""PyAlaMode is a programmer's editor."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
import os
import sys
import editor
try:
True
except NameError:
True = 1==1
False = 1==0
class App(wx.App):
"""PyAlaMode standalone application."""
def __init__(self, filename=None):
self.filename = filename
wx.App.__init__(self, redirect=False)
def OnInit(self):
wx.InitAllImageHandlers()
self.frame = editor.EditorNotebookFrame(filename=self.filename)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main(filename=None):
if not filename and len(sys.argv) > 1:
filename = sys.argv[1]
if filename:
filename = os.path.realpath(filename)
app = App(filename)
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,42 @@
"""PyAlaModeTest is a programmer's editor."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
import os
import sys
import editor
try:
True
except NameError:
True = 1==1
False = 1==0
class App(wx.App):
"""PyAlaModeTest standalone application."""
def __init__(self, filename=None):
self.filename = filename
wx.App.__init__(self, redirect=False)
def OnInit(self):
wx.InitAllImageHandlers()
self.frame = editor.EditorShellNotebookFrame(filename=self.filename)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main(filename=None):
app = App(filename)
app.MainLoop()
if __name__ == '__main__':
filename = None
if len(sys.argv) > 1:
filename = os.path.realpath(sys.argv[1])
main(filename)

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

78
wxPython/wxPython/py/PyCrust.py Executable file
View File

@@ -0,0 +1,78 @@
"""PyCrust is a python shell and namespace browser application."""
# The next two lines, and the other code below that makes use of
# ``__main__`` and ``original``, serve the purpose of cleaning up the
# main namespace to look as much as possible like the regular Python
# shell environment.
import __main__
original = __main__.__dict__.keys()
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
try:
True
except NameError:
True = 1==1
False = 1==0
class App(wx.App):
"""PyCrust standalone application."""
def OnInit(self):
import wx
wx.InitAllImageHandlers()
locals = __main__.__dict__
from crust import CrustFrame
self.frame = CrustFrame(locals=locals)
self.frame.SetSize((800, 600))
self.frame.Show()
self.SetTopWindow(self.frame)
return True
'''
The main() function needs to handle being imported, such as with the
pycrust script that wxPython installs:
#!/usr/bin/env python
from wx.py.PyCrust import main
main()
'''
def main():
"""The main function for the PyCrust program."""
# Cleanup the main namespace, leaving the App class.
import __main__
md = __main__.__dict__
keepers = original
keepers.append('App')
for key in md.keys():
if key not in keepers:
del md[key]
# Create an application instance.
app = App(0)
# Mimic the contents of the standard Python shell's sys.path.
import sys
if sys.path[0]:
sys.path[0] = ''
# Add the application object to the sys module's namespace.
# This allows a shell user to do:
# >>> import sys
# >>> sys.app.whatever
sys.app = app
del sys
# Cleanup the main namespace some more.
if md.has_key('App') and md['App'] is App:
del md['App']
if md.has_key('__main__') and md['__main__'] is __main__:
del md['__main__']
# Start the wxPython event loop.
app.MainLoop()
if __name__ == '__main__':
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,43 @@
"""PyFilling is a python namespace inspection application."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
# We use this object to get more introspection when run standalone.
app = None
import filling
# These are imported just to have something interesting to inspect.
import crust
import interpreter
import introspect
import pseudo
import shell
import sys
import wx
try:
True
except NameError:
True = 1==1
False = 1==0
class App(filling.App):
def OnInit(self):
filling.App.OnInit(self)
self.root = self.fillingFrame.filling.tree.root
return True
def main():
"""Create and run the application."""
global app
app = App(0)
app.fillingFrame.filling.tree.Expand(app.root)
app.MainLoop()
if __name__ == '__main__':
main()

79
wxPython/wxPython/py/PyShell.py Executable file
View File

@@ -0,0 +1,79 @@
"""PyShell is a python shell application."""
# The next two lines, and the other code below that makes use of
# ``__main__`` and ``original``, serve the purpose of cleaning up the
# main namespace to look as much as possible like the regular Python
# shell environment.
import __main__
original = __main__.__dict__.keys()
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
try:
True
except NameError:
True = 1==1
False = 1==0
class App(wx.App):
"""PyShell standalone application."""
def OnInit(self):
import wx
wx.InitAllImageHandlers()
locals = __main__.__dict__
from shell import ShellFrame
self.frame = ShellFrame(locals=locals)
self.frame.SetSize((750, 525))
self.frame.Show()
self.SetTopWindow(self.frame)
self.frame.shell.SetFocus()
return True
'''
The main() function needs to handle being imported, such as with the
pyshell script that wxPython installs:
#!/usr/bin/env python
from wx.py.PyShell import main
main()
'''
def main():
"""The main function for the PyShell program."""
# Cleanup the main namespace, leaving the App class.
import __main__
md = __main__.__dict__
keepers = original
keepers.append('App')
for key in md.keys():
if key not in keepers:
del md[key]
# Create an application instance.
app = App(0)
# Cleanup the main namespace some more.
if md.has_key('App') and md['App'] is App:
del md['App']
if md.has_key('__main__') and md['__main__'] is __main__:
del md['__main__']
# Mimic the contents of the standard Python shell's sys.path.
import sys
if sys.path[0]:
sys.path[0] = ''
# Add the application object to the sys module's namespace.
# This allows a shell user to do:
# >>> import sys
# >>> sys.app.whatever
sys.app = app
del sys
# Start the wxPython event loop.
app.MainLoop()
if __name__ == '__main__':
main()

56
wxPython/wxPython/py/PyWrap.py Executable file
View File

@@ -0,0 +1,56 @@
"""PyWrap is a command line utility that runs a wxPython program with
additional runtime-tools, such as PyCrust."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import os
import sys
import wx
from crust import CrustFrame as Frame
try:
True
except NameError:
True = 1==1
False = 1==0
def wrap(app):
wx.InitAllImageHandlers()
frame = Frame()
frame.SetSize((750, 525))
frame.Show(True)
frame.shell.interp.locals['app'] = app
app.MainLoop()
def main(modulename=None):
sys.path.insert(0, os.curdir)
if not modulename:
if len(sys.argv) < 2:
print "Please specify a module name."
raise SystemExit
modulename = sys.argv[1]
if modulename.endswith('.py'):
modulename = modulename[:-3]
module = __import__(modulename)
# Find the App class.
App = None
d = module.__dict__
for item in d.keys():
try:
if issubclass(d[item], wx.App):
App = d[item]
except (NameError, TypeError):
pass
if App is None:
print "No App class found."
raise SystemExit
app = App()
wrap(app)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,20 @@
"""The py package, formerly the PyCrust package."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import buffer
import crust
import dispatcher
import document
import editor
import editwindow
import filling
import frame
import images
import interpreter
import introspect
import pseudo
import shell
import version

View File

@@ -0,0 +1,144 @@
"""Buffer class."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
from interpreter import Interpreter
import imp
import os
import sys
import document
try:
True
except NameError:
True = 1==1
False = 1==0
class Buffer:
"""Buffer class."""
id = 0
def __init__(self, filename=None):
"""Create a Buffer instance."""
Buffer.id += 1
self.id = Buffer.id
self.interp = Interpreter(locals={})
self.name = ''
self.editors = {}
self.editor = None
self.modules = sys.modules.keys()
self.syspath = sys.path[:]
while True:
try:
self.syspath.remove('')
except ValueError:
break
while True:
try:
self.syspath.remove('.')
except ValueError:
break
self.open(filename)
def addEditor(self, editor):
"""Add an editor."""
self.editor = editor
self.editors[editor.id] = editor
def hasChanged(self):
"""Return True if text in editor has changed since last save."""
if self.editor:
return self.editor.hasChanged()
else:
return False
def new(self, filepath):
"""New empty buffer."""
if not filepath:
return
if os.path.exists(filepath):
self.confirmed = self.overwriteConfirm(filepath)
else:
self.confirmed = True
def open(self, filename):
"""Open file into buffer."""
self.doc = document.Document(filename)
self.name = self.doc.filename or ('Untitled:' + str(self.id))
self.modulename = self.doc.filebase
# XXX This should really make sure filedir is first item in syspath.
# XXX Or maybe this should be moved to the update namespace method.
if self.doc.filedir and self.doc.filedir not in self.syspath:
# To create the proper context for updateNamespace.
self.syspath.insert(0, self.doc.filedir)
if self.doc.filepath and os.path.exists(self.doc.filepath):
self.confirmed = True
if self.editor:
text = self.doc.read()
self.editor._setBuffer(buffer=self, text=text)
def overwriteConfirm(filepath):
"""Confirm overwriting an existing file."""
return False
def save(self):
"""Save buffer."""
filepath = self.doc.filepath
if not filepath:
return # XXX Get filename
if not os.path.exists(filepath):
self.confirmed = True
if not self.confirmed:
self.confirmed = self.overwriteConfirm(filepath)
if self.confirmed:
self.doc.write(self.editor.getText())
if self.editor:
self.editor.setSavePoint()
def saveAs(self, filename):
"""Save buffer."""
self.doc = document.Document(filename)
self.name = self.doc.filename
self.modulename = self.doc.filebase
self.save()
def updateNamespace(self):
"""Update the namespace for autocompletion and calltips.
Return True if updated, False if there was an error."""
if not self.interp or not hasattr(self.editor, 'getText'):
return False
syspath = sys.path
sys.path = self.syspath
text = self.editor.getText()
text = text.replace('\r\n', '\n')
text = text.replace('\r', '\n')
name = self.modulename or self.name
module = imp.new_module(name)
newspace = module.__dict__.copy()
try:
try:
code = compile(text, name, 'exec')
except:
raise
# return False
try:
exec code in newspace
except:
raise
# return False
else:
# No problems, so update the namespace.
self.interp.locals.clear()
self.interp.locals.update(newspace)
return True
finally:
sys.path = syspath
for m in sys.modules.keys():
if m not in self.modules:
del sys.modules[m]

View File

@@ -0,0 +1,221 @@
"""Crust combines the shell and filling into one control."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
import os
import pprint
import sys
import dispatcher
import editwindow
from filling import Filling
import frame
from shell import Shell
from version import VERSION
try:
True
except NameError:
True = 1==1
False = 1==0
class Crust(wx.SplitterWindow):
"""Crust based on SplitterWindow."""
name = 'Crust'
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.SP_3D,
name='Crust Window', rootObject=None, rootLabel=None,
rootIsNamespace=True, intro='', locals=None,
InterpClass=None, *args, **kwds):
"""Create Crust instance."""
wx.SplitterWindow.__init__(self, parent, id, pos, size, style, name)
self.shell = Shell(parent=self, introText=intro,
locals=locals, InterpClass=InterpClass,
*args, **kwds)
self.editor = self.shell
if rootObject is None:
rootObject = self.shell.interp.locals
self.notebook = wx.Notebook(parent=self, id=-1)
self.shell.interp.locals['notebook'] = self.notebook
self.filling = Filling(parent=self.notebook,
rootObject=rootObject,
rootLabel=rootLabel,
rootIsNamespace=rootIsNamespace)
# Add 'filling' to the interpreter's locals.
self.shell.interp.locals['filling'] = self.filling
self.notebook.AddPage(page=self.filling, text='Namespace', select=True)
self.display = Display(parent=self.notebook)
self.notebook.AddPage(page=self.display, text='Display')
# Add 'pp' (pretty print) to the interpreter's locals.
self.shell.interp.locals['pp'] = self.display.setItem
self.calltip = Calltip(parent=self.notebook)
self.notebook.AddPage(page=self.calltip, text='Calltip')
self.sessionlisting = SessionListing(parent=self.notebook)
self.notebook.AddPage(page=self.sessionlisting, text='Session')
self.dispatcherlisting = DispatcherListing(parent=self.notebook)
self.notebook.AddPage(page=self.dispatcherlisting, text='Dispatcher')
from wxd import wx_
self.wxdocs = Filling(parent=self.notebook,
rootObject=wx_,
rootLabel='wx',
rootIsNamespace=False,
static=True)
self.notebook.AddPage(page=self.wxdocs, text='wxPython Docs')
from wxd import stc_
self.stcdocs = Filling(parent=self.notebook,
rootObject=stc_.StyledTextCtrl,
rootLabel='StyledTextCtrl',
rootIsNamespace=False,
static=True)
self.notebook.AddPage(page=self.stcdocs, text='StyledTextCtrl Docs')
self.SplitHorizontally(self.shell, self.notebook, 300)
self.SetMinimumPaneSize(1)
class Display(editwindow.EditWindow):
"""STC used to display an object using Pretty Print."""
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER,
static=False):
"""Create Display instance."""
editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
# Configure various defaults and user preferences.
self.SetReadOnly(True)
self.SetWrapMode(False)
if not static:
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
def push(self, command, more):
"""Receiver for Interpreter.push signal."""
self.Refresh()
def Refresh(self):
if not hasattr(self, "item"):
return
self.SetReadOnly(False)
text = pprint.pformat(self.item)
self.SetText(text)
self.SetReadOnly(True)
def setItem(self, item):
"""Set item to pretty print in the notebook Display tab."""
self.item = item
self.Refresh()
class Calltip(wx.TextCtrl):
"""Text control containing the most recent shell calltip."""
def __init__(self, parent=None, id=-1):
style = wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2
wx.TextCtrl.__init__(self, parent=parent, id=id, style=style)
self.SetBackgroundColour(wx.Colour(255, 255, 232))
dispatcher.connect(receiver=self.display, signal='Shell.calltip')
def display(self, calltip):
"""Receiver for Shell.calltip signal."""
self.SetValue(calltip)
class SessionListing(wx.TextCtrl):
"""Text control containing all commands for session."""
def __init__(self, parent=None, id=-1):
style = wx.TE_MULTILINE | wx.TE_READONLY | \
wx.TE_RICH2 | wx.TE_DONTWRAP
wx.TextCtrl.__init__(self, parent=parent, id=id, style=style)
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
def push(self, command, more):
"""Receiver for Interpreter.push signal."""
if command and not more:
self.SetInsertionPointEnd()
start, end = self.GetSelection()
if start != end:
self.SetSelection(0, 0)
self.AppendText(command + '\n')
class DispatcherListing(wx.TextCtrl):
"""Text control containing all dispatches for session."""
def __init__(self, parent=None, id=-1):
style = wx.TE_MULTILINE | wx.TE_READONLY | \
wx.TE_RICH2 | wx.TE_DONTWRAP
wx.TextCtrl.__init__(self, parent=parent, id=id, style=style)
dispatcher.connect(receiver=self.spy)
def spy(self, signal, sender):
"""Receiver for Any signal from Any sender."""
text = '%r from %s' % (signal, sender)
self.SetInsertionPointEnd()
start, end = self.GetSelection()
if start != end:
self.SetSelection(0, 0)
self.AppendText(text + '\n')
class CrustFrame(frame.Frame):
"""Frame containing all the PyCrust components."""
name = 'CrustFrame'
revision = __revision__
def __init__(self, parent=None, id=-1, title='PyCrust',
pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.DEFAULT_FRAME_STYLE,
rootObject=None, rootLabel=None, rootIsNamespace=True,
locals=None, InterpClass=None, *args, **kwds):
"""Create CrustFrame instance."""
frame.Frame.__init__(self, parent, id, title, pos, size, style)
intro = 'PyCrust %s - The Flakiest Python Shell' % VERSION
intro += '\nSponsored by Orbtech - '
intro += 'Your source for Python programming expertise.'
self.SetStatusText(intro.replace('\n', ', '))
self.crust = Crust(parent=self, intro=intro,
rootObject=rootObject,
rootLabel=rootLabel,
rootIsNamespace=rootIsNamespace,
locals=locals,
InterpClass=InterpClass, *args, **kwds)
self.shell = self.crust.shell
# Override the filling so that status messages go to the status bar.
self.crust.filling.tree.setStatusText = self.SetStatusText
# Override the shell so that status messages go to the status bar.
self.shell.setStatusText = self.SetStatusText
# Fix a problem with the sash shrinking to nothing.
self.crust.filling.SetSashPosition(200)
# Set focus to the shell editor.
self.shell.SetFocus()
def OnClose(self, event):
"""Event handler for closing."""
self.crust.shell.destroy()
self.Destroy()
def OnAbout(self, event):
"""Display an About 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_STRING + \
'Platform: %s\n' % sys.platform
dialog = wx.MessageDialog(self, text, title,
wx.OK | wx.ICON_INFORMATION)
dialog.ShowModal()
dialog.Destroy()

View File

@@ -0,0 +1,49 @@
"""Document class."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import os
try:
True
except NameError:
True = 1==1
False = 1==0
class Document:
"""Document class."""
def __init__(self, filename=None):
"""Create a Document instance."""
self.filename = filename
self.filepath = None
self.filedir = None
self.filebase = None
self.fileext = None
if self.filename:
self.filepath = os.path.realpath(self.filename)
self.filedir, self.filename = os.path.split(self.filepath)
self.filebase, self.fileext = os.path.splitext(self.filename)
def read(self):
"""Return contents of file."""
if self.filepath and os.path.exists(self.filepath):
f = file(self.filepath, 'rb')
try:
return f.read()
finally:
f.close()
else:
return ''
def write(self, text):
"""Write text to file."""
try:
f = file(self.filepath, 'wb')
f.write(text)
finally:
if f:
f.close()

View File

@@ -0,0 +1,839 @@
"""PyAlaCarte and PyAlaMode editors."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
from buffer import Buffer
import crust
import dispatcher
import editwindow
import frame
from shell import Shell
import version
try:
True
except NameError:
True = 1==1
False = 1==0
class EditorFrame(frame.Frame):
"""Frame containing one editor."""
def __init__(self, parent=None, id=-1, title='PyAlaCarte',
pos=wx.DefaultPosition, size=(800, 600),
style=wx.DEFAULT_FRAME_STYLE, filename=None):
"""Create EditorFrame instance."""
frame.Frame.__init__(self, parent, id, title, pos, size, style)
self.buffers = {}
self.buffer = None # Current buffer.
self.editor = None
self._defaultText = title + ' - the tastiest Python editor.'
self._statusText = self._defaultText
self.SetStatusText(self._statusText)
wx.EVT_IDLE(self, self.OnIdle)
self._setup()
if filename:
self.bufferCreate(filename)
def _setup(self):
"""Setup prior to first buffer creation.
Useful for subclasses."""
pass
def setEditor(self, editor):
self.editor = editor
self.buffer = self.editor.buffer
self.buffers[self.buffer.id] = self.buffer
def OnAbout(self, event):
"""Display an About window."""
title = 'About PyAlaCarte'
text = 'Another fine, flaky program.'
dialog = wx.MessageDialog(self, text, title,
wx.OK | wx.ICON_INFORMATION)
dialog.ShowModal()
dialog.Destroy()
def OnClose(self, event):
"""Event handler for closing."""
for buffer in self.buffers.values():
self.buffer = buffer
if buffer.hasChanged():
cancel = self.bufferSuggestSave()
if cancel and event.CanVeto():
event.Veto()
return
self.Destroy()
def OnIdle(self, event):
"""Event handler for idle time."""
self._updateStatus()
if hasattr(self, 'notebook'):
self._updateTabText()
self._updateTitle()
event.Skip()
def _updateStatus(self):
"""Show current status information."""
if self.editor and hasattr(self.editor, 'getStatus'):
status = self.editor.getStatus()
text = 'File: %s | Line: %d | Column: %d' % status
else:
text = self._defaultText
if text != self._statusText:
self.SetStatusText(text)
self._statusText = text
def _updateTabText(self):
"""Show current buffer information on notebook tab."""
## suffix = ' **'
## notebook = self.notebook
## selection = notebook.GetSelection()
## if selection == -1:
## return
## text = notebook.GetPageText(selection)
## window = notebook.GetPage(selection)
## if window.editor and window.editor.buffer.hasChanged():
## if text.endswith(suffix):
## pass
## else:
## notebook.SetPageText(selection, text + suffix)
## else:
## if text.endswith(suffix):
## notebook.SetPageText(selection, text[:len(suffix)])
def _updateTitle(self):
"""Show current title information."""
title = self.GetTitle()
if self.bufferHasChanged():
if title.startswith('* '):
pass
else:
self.SetTitle('* ' + title)
else:
if title.startswith('* '):
self.SetTitle(title[2:])
def hasBuffer(self):
"""Return True if there is a current buffer."""
if self.buffer:
return True
else:
return False
def bufferClose(self):
"""Close buffer."""
if self.bufferHasChanged():
cancel = self.bufferSuggestSave()
if cancel:
return cancel
self.bufferDestroy()
cancel = False
return cancel
def bufferCreate(self, filename=None):
"""Create new buffer."""
self.bufferDestroy()
buffer = Buffer()
self.panel = panel = wx.Panel(parent=self, id=-1)
editor = Editor(parent=panel)
panel.editor = editor
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(editor.window, 1, wx.EXPAND)
panel.SetSizer(sizer)
panel.SetAutoLayout(True)
sizer.Layout()
buffer.addEditor(editor)
buffer.open(filename)
self.setEditor(editor)
self.editor.setFocus()
def bufferDestroy(self):
"""Destroy the current buffer."""
if self.buffer:
for editor in self.buffer.editors.values():
editor.destroy()
self.editor = None
del self.buffers[self.buffer.id]
self.buffer = None
self.panel.Destroy()
def bufferHasChanged(self):
"""Return True if buffer has changed since last save."""
if self.buffer:
return self.buffer.hasChanged()
else:
return False
def bufferNew(self):
"""Create new buffer."""
if self.bufferHasChanged():
cancel = self.bufferSuggestSave()
if cancel:
return cancel
self.bufferCreate()
cancel = False
return cancel
def bufferOpen(self):
"""Open file in buffer."""
if self.bufferHasChanged():
cancel = self.bufferSuggestSave()
if cancel:
return cancel
filedir = ''
if self.buffer and self.buffer.doc.filedir:
filedir = self.buffer.doc.filedir
result = openSingle(directory=filedir)
if result.path:
self.bufferCreate(result.path)
cancel = False
return cancel
## def bufferPrint(self):
## """Print buffer."""
## pass
## def bufferRevert(self):
## """Revert buffer to version of file on disk."""
## pass
def bufferSave(self):
"""Save buffer to its file."""
if self.buffer.doc.filepath:
self.buffer.save()
cancel = False
else:
cancel = self.bufferSaveAs()
return cancel
def bufferSaveAs(self):
"""Save buffer to a new filename."""
if self.bufferHasChanged() and self.buffer.doc.filepath:
cancel = self.bufferSuggestSave()
if cancel:
return cancel
filedir = ''
if self.buffer and self.buffer.doc.filedir:
filedir = self.buffer.doc.filedir
result = saveSingle(directory=filedir)
if result.path:
self.buffer.saveAs(result.path)
cancel = False
else:
cancel = True
return cancel
def bufferSuggestSave(self):
"""Suggest saving changes. Return True if user selected Cancel."""
result = messageDialog(parent=None,
message='%s has changed.\n'
'Would you like to save it first'
'?' % self.buffer.name,
title='Save current file?')
if result.positive:
cancel = self.bufferSave()
else:
cancel = result.text == 'Cancel'
return cancel
def updateNamespace(self):
"""Update the buffer namespace for autocompletion and calltips."""
if self.buffer.updateNamespace():
self.SetStatusText('Namespace updated')
else:
self.SetStatusText('Error executing, unable to update namespace')
class EditorNotebookFrame(EditorFrame):
"""Frame containing one or more editors in a notebook."""
def __init__(self, parent=None, id=-1, title='PyAlaMode',
pos=wx.DefaultPosition, size=(800, 600),
style=wx.DEFAULT_FRAME_STYLE, filename=None):
"""Create EditorNotebookFrame instance."""
self.notebook = None
EditorFrame.__init__(self, parent, id, title, pos,
size, style, filename)
if self.notebook:
dispatcher.connect(receiver=self._editorChange,
signal='EditorChange', sender=self.notebook)
def _setup(self):
"""Setup prior to first buffer creation.
Called automatically by base class during init."""
self.notebook = EditorNotebook(parent=self)
intro = 'Py %s' % version.VERSION
import imp
module = imp.new_module('__main__')
import __builtin__
module.__dict__['__builtins__'] = __builtin__
namespace = module.__dict__.copy()
self.crust = crust.Crust(parent=self.notebook, intro=intro, locals=namespace)
self.shell = self.crust.shell
# Override the filling so that status messages go to the status bar.
self.crust.filling.tree.setStatusText = self.SetStatusText
# Override the shell so that status messages go to the status bar.
self.shell.setStatusText = self.SetStatusText
# Fix a problem with the sash shrinking to nothing.
self.crust.filling.SetSashPosition(200)
self.notebook.AddPage(page=self.crust, text='*Shell*', select=True)
self.setEditor(self.crust.editor)
self.crust.editor.SetFocus()
def _editorChange(self, editor):
"""Editor change signal receiver."""
self.setEditor(editor)
def OnAbout(self, event):
"""Display an About window."""
title = 'About PyAlaMode'
text = 'Another fine, flaky program.'
dialog = wx.MessageDialog(self, text, title,
wx.OK | wx.ICON_INFORMATION)
dialog.ShowModal()
dialog.Destroy()
def _updateTitle(self):
"""Show current title information."""
pass
## title = self.GetTitle()
## if self.bufferHasChanged():
## if title.startswith('* '):
## pass
## else:
## self.SetTitle('* ' + title)
## else:
## if title.startswith('* '):
## self.SetTitle(title[2:])
def bufferCreate(self, filename=None):
"""Create new buffer."""
buffer = Buffer()
panel = wx.Panel(parent=self.notebook, id=-1)
editor = Editor(parent=panel)
panel.editor = editor
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(editor.window, 1, wx.EXPAND)
panel.SetSizer(sizer)
panel.SetAutoLayout(True)
sizer.Layout()
buffer.addEditor(editor)
buffer.open(filename)
self.setEditor(editor)
self.notebook.AddPage(page=panel, text=self.buffer.name, select=True)
self.editor.setFocus()
def bufferDestroy(self):
"""Destroy the current buffer."""
selection = self.notebook.GetSelection()
## print "Destroy Selection:", selection
if selection > 0: # Don't destroy the PyCrust tab.
if self.buffer:
del self.buffers[self.buffer.id]
self.buffer = None # Do this before DeletePage().
self.notebook.DeletePage(selection)
def bufferNew(self):
"""Create new buffer."""
self.bufferCreate()
cancel = False
return cancel
def bufferOpen(self):
"""Open file in buffer."""
filedir = ''
if self.buffer and self.buffer.doc.filedir:
filedir = self.buffer.doc.filedir
result = openMultiple(directory=filedir)
for path in result.paths:
self.bufferCreate(path)
cancel = False
return cancel
class EditorNotebook(wx.Notebook):
"""A notebook containing a page for each editor."""
def __init__(self, parent):
"""Create EditorNotebook instance."""
wx.Notebook.__init__(self, parent, id=-1)
wx.EVT_NOTEBOOK_PAGE_CHANGING(self, self.GetId(),
self.OnPageChanging)
wx.EVT_NOTEBOOK_PAGE_CHANGED(self, self.GetId(),
self.OnPageChanged)
wx.EVT_IDLE(self, self.OnIdle)
def OnIdle(self, event):
"""Event handler for idle time."""
self._updateTabText()
event.Skip()
def _updateTabText(self):
"""Show current buffer display name on all but first tab."""
size = 3
changed = ' **'
unchanged = ' --'
selection = self.GetSelection()
if selection < 1:
return
text = self.GetPageText(selection)
window = self.GetPage(selection)
if not window.editor:
return
if text.endswith(changed) or text.endswith(unchanged):
name = text[:-size]
else:
name = text
if name != window.editor.buffer.name:
text = window.editor.buffer.name
if window.editor.buffer.hasChanged():
if text.endswith(changed):
text = None
elif text.endswith(unchanged):
text = text[:-size] + changed
else:
text += changed
else:
if text.endswith(changed):
text = text[:-size] + unchanged
elif text.endswith(unchanged):
text = None
else:
text += unchanged
if text is not None:
self.SetPageText(selection, text)
self.Refresh() # Needed on Win98.
def OnPageChanging(self, event):
"""Page changing event handler."""
event.Skip()
def OnPageChanged(self, event):
"""Page changed event handler."""
new = event.GetSelection()
window = self.GetPage(new)
dispatcher.send(signal='EditorChange', sender=self,
editor=window.editor)
window.SetFocus()
event.Skip()
class EditorShellNotebookFrame(EditorNotebookFrame):
"""Frame containing a notebook containing EditorShellNotebooks."""
def __init__(self, parent=None, id=-1, title='PyAlaModeTest',
pos=wx.DefaultPosition, size=(600, 400),
style=wx.DEFAULT_FRAME_STYLE,
filename=None, singlefile=False):
"""Create EditorShellNotebookFrame instance."""
self._singlefile = singlefile
EditorNotebookFrame.__init__(self, parent, id, title, pos,
size, style, filename)
def _setup(self):
"""Setup prior to first buffer creation.
Called automatically by base class during init."""
if not self._singlefile:
self.notebook = EditorNotebook(parent=self)
def OnAbout(self, event):
"""Display an About window."""
title = 'About PyAlaModePlus'
text = 'Another fine, flaky program.'
dialog = wx.MessageDialog(self, text, title,
wx.OK | wx.ICON_INFORMATION)
dialog.ShowModal()
dialog.Destroy()
def bufferCreate(self, filename=None):
"""Create new buffer."""
if self._singlefile:
self.bufferDestroy()
notebook = EditorShellNotebook(parent=self,
filename=filename)
self.notebook = notebook
else:
notebook = EditorShellNotebook(parent=self.notebook,
filename=filename)
self.setEditor(notebook.editor)
if not self._singlefile:
self.notebook.AddPage(page=notebook, text=self.buffer.name,
select=True)
self.editor.setFocus()
def bufferDestroy(self):
"""Destroy the current buffer."""
if self.buffer:
self.editor = None
del self.buffers[self.buffer.id]
self.buffer = None # Do this before DeletePage().
if self._singlefile:
self.notebook.Destroy()
self.notebook = None
else:
selection = self.notebook.GetSelection()
## print "Destroy Selection:", selection
self.notebook.DeletePage(selection)
def bufferNew(self):
"""Create new buffer."""
if self._singlefile and self.bufferHasChanged():
cancel = self.bufferSuggestSave()
if cancel:
return cancel
self.bufferCreate()
cancel = False
return cancel
def bufferOpen(self):
"""Open file in buffer."""
if self._singlefile and self.bufferHasChanged():
cancel = self.bufferSuggestSave()
if cancel:
return cancel
filedir = ''
if self.buffer and self.buffer.doc.filedir:
filedir = self.buffer.doc.filedir
if self._singlefile:
result = openSingle(directory=filedir)
if result.path:
self.bufferCreate(result.path)
else:
result = openMultiple(directory=filedir)
for path in result.paths:
self.bufferCreate(path)
cancel = False
return cancel
class EditorShellNotebook(wx.Notebook):
"""A notebook containing an editor page and a shell page."""
def __init__(self, parent, filename=None):
"""Create EditorShellNotebook instance."""
wx.Notebook.__init__(self, parent, id=-1)
usePanels = True
if usePanels:
editorparent = editorpanel = wx.Panel(self, -1)
shellparent = shellpanel = wx.Panel(self, -1)
else:
editorparent = self
shellparent = self
self.buffer = Buffer()
self.editor = Editor(parent=editorparent)
self.buffer.addEditor(self.editor)
self.buffer.open(filename)
self.shell = Shell(parent=shellparent, locals=self.buffer.interp.locals,
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)
self.buffer.interp.locals.clear()
if usePanels:
self.AddPage(page=editorpanel, text='Editor', select=True)
self.AddPage(page=shellpanel, text='Shell')
# Setup sizers
editorsizer = wx.BoxSizer(wx.VERTICAL)
editorsizer.Add(self.editor.window, 1, wx.EXPAND)
editorpanel.SetSizer(editorsizer)
editorpanel.SetAutoLayout(True)
shellsizer = wx.BoxSizer(wx.VERTICAL)
shellsizer.Add(self.shell, 1, wx.EXPAND)
shellpanel.SetSizer(shellsizer)
shellpanel.SetAutoLayout(True)
else:
self.AddPage(page=self.editor.window, text='Editor', select=True)
self.AddPage(page=self.shell, text='Shell')
self.editor.setFocus()
wx.EVT_NOTEBOOK_PAGE_CHANGED(self, self.GetId(), self.OnPageChanged)
def OnPageChanged(self, event):
"""Page changed event handler."""
selection = event.GetSelection()
if selection == 0:
self.editor.setFocus()
else:
self.shell.SetFocus()
event.Skip()
def SetFocus(self):
wx.Notebook.SetFocus(self)
selection = self.GetSelection()
if selection == 0:
self.editor.setFocus()
else:
self.shell.SetFocus()
class Editor:
"""Editor having an EditWindow."""
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
"""Create Editor instance."""
self.window = EditWindow(self, parent, id, pos, size, style)
self.id = self.window.GetId()
self.buffer = None
# Assign handlers for keyboard events.
wx.EVT_CHAR(self.window, self.OnChar)
wx.EVT_KEY_DOWN(self.window, self.OnKeyDown)
def _setBuffer(self, buffer, text):
"""Set the editor to a buffer. Private callback called by buffer."""
self.buffer = buffer
self.autoCompleteKeys = buffer.interp.getAutoCompleteKeys()
self.clearAll()
self.setText(text)
self.emptyUndoBuffer()
self.setSavePoint()
def destroy(self):
"""Destroy all editor objects."""
self.window.Destroy()
def clearAll(self):
self.window.ClearAll()
def emptyUndoBuffer(self):
self.window.EmptyUndoBuffer()
def getStatus(self):
"""Return (filepath, line, column) status tuple."""
pos = self.window.GetCurrentPos()
line = self.window.LineFromPosition(pos) + 1
col = self.window.GetColumn(pos)
if self.buffer:
name = self.buffer.doc.filepath or self.buffer.name
else:
name = ''
status = (name, line, col)
return status
def getText(self):
"""Return contents of editor."""
return self.window.GetText()
def hasChanged(self):
"""Return True if contents have changed."""
return self.window.GetModify()
def setFocus(self):
"""Set the input focus to the editor window."""
self.window.SetFocus()
def setSavePoint(self):
self.window.SetSavePoint()
def setText(self, text):
"""Set contents of editor."""
self.window.SetText(text)
def OnChar(self, event):
"""Keypress event handler.
Only receives an event if OnKeyDown calls event.Skip() for the
corresponding event."""
key = event.KeyCode()
if key in self.autoCompleteKeys:
# Usually the dot (period) key activates auto completion.
if self.window.AutoCompActive():
self.window.AutoCompCancel()
self.window.ReplaceSelection('')
self.window.AddText(chr(key))
text, pos = self.window.GetCurLine()
text = text[:pos]
if self.window.autoComplete:
self.autoCompleteShow(text)
elif key == ord('('):
# The left paren activates a call tip and cancels an
# active auto completion.
if self.window.AutoCompActive():
self.window.AutoCompCancel()
self.window.ReplaceSelection('')
self.window.AddText('(')
text, pos = self.window.GetCurLine()
text = text[:pos]
self.autoCallTipShow(text)
else:
# Allow the normal event handling to take place.
event.Skip()
def OnKeyDown(self, event):
"""Key down event handler."""
key = event.KeyCode()
# If the auto-complete window is up let it do its thing.
if self.window.AutoCompActive():
event.Skip()
return
controlDown = event.ControlDown()
altDown = event.AltDown()
shiftDown = event.ShiftDown()
# Let Ctrl-Alt-* get handled normally.
if controlDown and altDown:
event.Skip()
# Increase font size.
elif controlDown and key in (ord(']'),):
dispatcher.send(signal='FontIncrease')
# Decrease font size.
elif controlDown and key in (ord('['),):
dispatcher.send(signal='FontDecrease')
# Default font size.
elif controlDown and key in (ord('='),):
dispatcher.send(signal='FontDefault')
else:
event.Skip()
def autoCompleteShow(self, command):
"""Display auto-completion popup list."""
list = self.buffer.interp.getAutoCompleteList(command,
includeMagic=self.window.autoCompleteIncludeMagic,
includeSingle=self.window.autoCompleteIncludeSingle,
includeDouble=self.window.autoCompleteIncludeDouble)
if list:
options = ' '.join(list)
offset = 0
self.window.AutoCompShow(offset, options)
def autoCallTipShow(self, command):
"""Display argument spec and docstring in a popup window."""
if self.window.CallTipActive():
self.window.CallTipCancel()
(name, argspec, tip) = self.buffer.interp.getCallTip(command)
if tip:
dispatcher.send(signal='Shell.calltip', sender=self, calltip=tip)
if not self.window.autoCallTip:
return
if argspec:
startpos = self.window.GetCurrentPos()
self.window.AddText(argspec + ')')
endpos = self.window.GetCurrentPos()
self.window.SetSelection(endpos, startpos)
if tip:
curpos = self.window.GetCurrentPos()
size = len(name)
tippos = curpos - (size + 1)
fallback = curpos - self.window.GetColumn(curpos)
# In case there isn't enough room, only go back to the
# fallback.
tippos = max(tippos, fallback)
self.window.CallTipShow(tippos, tip)
self.window.CallTipSetHighlight(0, size)
class EditWindow(editwindow.EditWindow):
"""EditWindow based on StyledTextCtrl."""
def __init__(self, editor, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
"""Create EditWindow instance."""
editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
self.editor = editor
class DialogResults:
"""DialogResults class."""
def __init__(self, returned):
"""Create wrapper for results returned by dialog."""
self.returned = returned
self.positive = returned in (wx.ID_OK, wx.ID_YES)
self.text = self._asString()
def __repr__(self):
return str(self.__dict__)
def _asString(self):
returned = self.returned
if returned == wx.ID_OK:
return "Ok"
elif returned == wx.ID_CANCEL:
return "Cancel"
elif returned == wx.ID_YES:
return "Yes"
elif returned == wx.ID_NO:
return "No"
def fileDialog(parent=None, title='Open', directory='', filename='',
wildcard='All Files (*.*)|*.*',
style=wx.OPEN | wx.MULTIPLE):
"""File dialog wrapper function."""
dialog = wx.FileDialog(parent, title, directory, filename,
wildcard, style)
result = DialogResults(dialog.ShowModal())
if result.positive:
result.paths = dialog.GetPaths()
else:
result.paths = []
dialog.Destroy()
return result
def openSingle(parent=None, title='Open', directory='', filename='',
wildcard='All Files (*.*)|*.*', style=wx.OPEN):
"""File dialog wrapper function."""
dialog = wx.FileDialog(parent, title, directory, filename,
wildcard, style)
result = DialogResults(dialog.ShowModal())
if result.positive:
result.path = dialog.GetPath()
else:
result.path = None
dialog.Destroy()
return result
def openMultiple(parent=None, title='Open', directory='', filename='',
wildcard='All Files (*.*)|*.*',
style=wx.OPEN | wx.MULTIPLE):
"""File dialog wrapper function."""
return fileDialog(parent, title, directory, filename, wildcard, style)
def saveSingle(parent=None, title='Save', directory='', filename='',
wildcard='All Files (*.*)|*.*',
style=wx.SAVE | wx.HIDE_READONLY | wx.OVERWRITE_PROMPT):
"""File dialog wrapper function."""
dialog = wx.FileDialog(parent, title, directory, filename,
wildcard, style)
result = DialogResults(dialog.ShowModal())
if result.positive:
result.path = dialog.GetPath()
else:
result.path = None
dialog.Destroy()
return result
def directory(parent=None, message='Choose a directory', path='', style=0,
pos=wx.DefaultPosition, size=wx.DefaultSize):
"""Dir dialog wrapper function."""
dialog = wx.DirDialog(parent, message, path, style, pos, size)
result = DialogResults(dialog.ShowModal())
if result.positive:
result.path = dialog.GetPath()
else:
result.path = None
dialog.Destroy()
return result
def messageDialog(parent=None, message='', title='Message box',
style=wx.YES_NO | wx.CANCEL | wx.CENTRE | wx.ICON_QUESTION,
pos=wx.DefaultPosition):
"""Message dialog wrapper function."""
dialog = wx.MessageDialog(parent, message, title, style, pos)
result = DialogResults(dialog.ShowModal())
dialog.Destroy()
return result

View File

@@ -0,0 +1,199 @@
"""EditWindow class."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
from wx import stc
import keyword
import os
import sys
import time
import dispatcher
from version import VERSION
try:
True
except NameError:
True = 1==1
False = 1==0
if wx.Platform == '__WXMSW__':
FACES = { 'times' : 'Times New Roman',
'mono' : 'Courier New',
'helv' : 'Lucida Console',
'lucida' : 'Lucida Console',
'other' : 'Comic Sans MS',
'size' : 10,
'lnsize' : 9,
'backcol': '#FFFFFF',
}
else: # GTK
FACES = { 'times' : 'Times',
'mono' : 'Courier',
'helv' : 'Helvetica',
'other' : 'new century schoolbook',
'size' : 12,
'lnsize' : 10,
'backcol': '#FFFFFF',
}
class EditWindow(stc.StyledTextCtrl):
"""EditWindow based on StyledTextCtrl."""
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
"""Create EditWindow instance."""
stc.StyledTextCtrl.__init__(self, parent, id, pos, size, style)
self.__config()
stc.EVT_STC_UPDATEUI(self, id, self.OnUpdateUI)
dispatcher.connect(receiver=self._fontsizer, signal='FontIncrease')
dispatcher.connect(receiver=self._fontsizer, signal='FontDecrease')
dispatcher.connect(receiver=self._fontsizer, signal='FontDefault')
def _fontsizer(self, signal):
"""Receiver for Font* signals."""
size = self.GetZoom()
if signal == 'FontIncrease':
size += 1
elif signal == 'FontDecrease':
size -= 1
elif signal == 'FontDefault':
size = 0
self.SetZoom(size)
def __config(self):
"""Configure shell based on user preferences."""
self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
self.SetMarginWidth(1, 40)
self.SetLexer(stc.STC_LEX_PYTHON)
self.SetKeyWords(0, ' '.join(keyword.kwlist))
self.setStyles(FACES)
self.SetViewWhiteSpace(False)
self.SetTabWidth(4)
self.SetUseTabs(False)
# Do we want to automatically pop up command completion options?
self.autoComplete = True
self.autoCompleteIncludeMagic = True
self.autoCompleteIncludeSingle = True
self.autoCompleteIncludeDouble = True
self.autoCompleteCaseInsensitive = True
self.AutoCompSetIgnoreCase(self.autoCompleteCaseInsensitive)
self.AutoCompSetAutoHide(False)
self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`')
# Do we want to automatically pop up command argument help?
self.autoCallTip = True
self.CallTipSetBackground(wx.Colour(255, 255, 232))
self.SetWrapMode(False)
try:
self.SetEndAtLastLine(False)
except AttributeError:
pass
def setStyles(self, faces):
"""Configure font size, typeface and color for lexer."""
# Default style
self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
"face:%(mono)s,size:%(size)d,back:%(backcol)s" % \
faces)
self.StyleClearAll()
# Built in styles
self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,
"back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR,
"face:%(mono)s" % faces)
self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
"fore:#0000FF,back:#FFFF88")
self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
"fore:#FF0000,back:#FFFF88")
# Python styles
self.StyleSetSpec(stc.STC_P_DEFAULT,
"face:%(mono)s" % faces)
self.StyleSetSpec(stc.STC_P_COMMENTLINE,
"fore:#007F00,face:%(mono)s" % faces)
self.StyleSetSpec(stc.STC_P_NUMBER,
"")
self.StyleSetSpec(stc.STC_P_STRING,
"fore:#7F007F,face:%(mono)s" % faces)
self.StyleSetSpec(stc.STC_P_CHARACTER,
"fore:#7F007F,face:%(mono)s" % faces)
self.StyleSetSpec(stc.STC_P_WORD,
"fore:#00007F,bold")
self.StyleSetSpec(stc.STC_P_TRIPLE,
"fore:#7F0000")
self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
"fore:#000033,back:#FFFFE8")
self.StyleSetSpec(stc.STC_P_CLASSNAME,
"fore:#0000FF,bold")
self.StyleSetSpec(stc.STC_P_DEFNAME,
"fore:#007F7F,bold")
self.StyleSetSpec(stc.STC_P_OPERATOR,
"")
self.StyleSetSpec(stc.STC_P_IDENTIFIER,
"")
self.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
"fore:#7F7F7F")
self.StyleSetSpec(stc.STC_P_STRINGEOL,
"fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
def OnUpdateUI(self, event):
"""Check for matching braces."""
# If the auto-complete window is up let it do its thing.
if self.AutoCompActive() or self.CallTipActive():
return
braceAtCaret = -1
braceOpposite = -1
charBefore = None
caretPos = self.GetCurrentPos()
if caretPos > 0:
charBefore = self.GetCharAt(caretPos - 1)
styleBefore = self.GetStyleAt(caretPos - 1)
# Check before.
if charBefore and chr(charBefore) in '[]{}()' \
and styleBefore == stc.STC_P_OPERATOR:
braceAtCaret = caretPos - 1
# Check after.
if braceAtCaret < 0:
charAfter = self.GetCharAt(caretPos)
styleAfter = self.GetStyleAt(caretPos)
if charAfter and chr(charAfter) in '[]{}()' \
and styleAfter == stc.STC_P_OPERATOR:
braceAtCaret = caretPos
if braceAtCaret >= 0:
braceOpposite = self.BraceMatch(braceAtCaret)
if braceAtCaret != -1 and braceOpposite == -1:
self.BraceBadLight(braceAtCaret)
else:
self.BraceHighlight(braceAtCaret, braceOpposite)
def CanCopy(self):
"""Return True if text is selected and can be copied."""
return self.GetSelectionStart() != self.GetSelectionEnd()
def CanCut(self):
"""Return True if text is selected and can be cut."""
return self.CanCopy() and self.CanEdit()
def CanEdit(self):
"""Return True if editing should succeed."""
return not self.GetReadOnly()
def CanPaste(self):
"""Return True if pasting should succeed."""
return stc.StyledTextCtrl.CanPaste(self) and self.CanEdit()

View File

@@ -0,0 +1,337 @@
"""Filling is the gui tree control through which a user can navigate
the local namespace or any object."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
import dispatcher
import editwindow
import inspect
import introspect
import keyword
import sys
import types
from version import VERSION
try:
True
except NameError:
True = 1==1
False = 1==0
COMMONTYPES = [getattr(types, t) for t in dir(types) \
if not t.startswith('_') \
and t not in ('ClassType', 'InstanceType', 'ModuleType')]
DOCTYPES = ('BuiltinFunctionType', 'BuiltinMethodType', 'ClassType',
'FunctionType', 'GeneratorType', 'InstanceType',
'LambdaType', 'MethodType', 'ModuleType',
'UnboundMethodType', 'method-wrapper')
SIMPLETYPES = [getattr(types, t) for t in dir(types) \
if not t.startswith('_') and t not in DOCTYPES]
del t
try:
COMMONTYPES.append(type(''.__repr__)) # Method-wrapper in version 2.2.x.
except AttributeError:
pass
class FillingTree(wx.TreeCtrl):
"""FillingTree based on TreeCtrl."""
name = 'Filling Tree'
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.TR_DEFAULT_STYLE,
rootObject=None, rootLabel=None, rootIsNamespace=False,
static=False):
"""Create FillingTree instance."""
wx.TreeCtrl.__init__(self, parent, id, pos, size, style)
self.rootIsNamespace = rootIsNamespace
import __main__
if rootObject is None:
rootObject = __main__.__dict__
self.rootIsNamespace = True
if rootObject is __main__.__dict__ and rootLabel is None:
rootLabel = 'locals()'
if not rootLabel:
rootLabel = 'Ingredients'
rootData = wx.TreeItemData(rootObject)
self.item = self.root = self.AddRoot(rootLabel, -1, -1, rootData)
self.SetItemHasChildren(self.root, self.objHasChildren(rootObject))
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)
wx.EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated)
if not static:
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
def push(self, command, more):
"""Receiver for Interpreter.push signal."""
self.display()
def OnItemExpanding(self, event):
"""Add children to the item."""
busy = wx.BusyCursor()
item = event.GetItem()
if self.IsExpanded(item):
return
self.addChildren(item)
# self.SelectItem(item)
def OnItemCollapsed(self, event):
"""Remove all children from the item."""
busy = wx.BusyCursor()
item = event.GetItem()
# self.CollapseAndReset(item)
# self.DeleteChildren(item)
# self.SelectItem(item)
def OnSelChanged(self, event):
"""Display information about the item."""
busy = wx.BusyCursor()
self.item = event.GetItem()
self.display()
def OnItemActivated(self, event):
"""Launch a DirFrame."""
item = event.GetItem()
text = self.getFullName(item)
obj = self.GetPyData(item)
frame = FillingFrame(parent=self, size=(600, 100), rootObject=obj,
rootLabel=text, rootIsNamespace=False)
frame.Show()
def objHasChildren(self, obj):
"""Return true if object has children."""
if self.objGetChildren(obj):
return True
else:
return False
def objGetChildren(self, obj):
"""Return dictionary with attributes or contents of object."""
busy = wx.BusyCursor()
otype = type(obj)
if otype is types.DictType \
or str(otype)[17:23] == 'BTrees' and hasattr(obj, 'keys'):
return obj
d = {}
if otype is types.ListType or otype is types.TupleType:
for n in range(len(obj)):
key = '[' + str(n) + ']'
d[key] = obj[n]
if otype not in COMMONTYPES:
for key in introspect.getAttributeNames(obj):
# Believe it or not, some attributes can disappear,
# such as the exc_traceback attribute of the sys
# module. So this is nested in a try block.
try:
d[key] = getattr(obj, key)
except:
pass
return d
def addChildren(self, item):
self.DeleteChildren(item)
obj = self.GetPyData(item)
children = self.objGetChildren(obj)
if not children:
return
keys = children.keys()
keys.sort(lambda x, y: cmp(str(x).lower(), str(y).lower()))
for key in keys:
itemtext = str(key)
# Show string dictionary items with single quotes, except
# for the first level of items, if they represent a
# namespace.
if type(obj) is types.DictType \
and type(key) is types.StringType \
and (item != self.root \
or (item == self.root and not self.rootIsNamespace)):
itemtext = repr(key)
child = children[key]
data = wx.TreeItemData(child)
branch = self.AppendItem(parent=item, text=itemtext, data=data)
self.SetItemHasChildren(branch, self.objHasChildren(child))
def display(self):
item = self.item
if self.IsExpanded(item):
self.addChildren(item)
self.setText('')
obj = self.GetPyData(item)
if wx.Platform == '__WXMSW__':
if obj is None: # Windows bug fix.
return
self.SetItemHasChildren(item, self.objHasChildren(obj))
otype = type(obj)
text = ''
text += self.getFullName(item)
text += '\n\nType: ' + str(otype)
try:
value = str(obj)
except:
value = ''
if otype is types.StringType or otype is types.UnicodeType:
value = repr(obj)
text += '\n\nValue: ' + value
if otype not in SIMPLETYPES:
try:
text += '\n\nDocstring:\n\n"""' + \
inspect.getdoc(obj).strip() + '"""'
except:
pass
if otype is types.InstanceType:
try:
text += '\n\nClass Definition:\n\n' + \
inspect.getsource(obj.__class__)
except:
pass
else:
try:
text += '\n\nSource Code:\n\n' + \
inspect.getsource(obj)
except:
pass
self.setText(text)
def getFullName(self, item, partial=''):
"""Return a syntactically proper name for item."""
name = self.GetItemText(item)
parent = None
obj = None
if item != self.root:
parent = self.GetItemParent(item)
obj = self.GetPyData(parent)
# Apply dictionary syntax to dictionary items, except the root
# and first level children of a namepace.
if (type(obj) is types.DictType \
or str(type(obj))[17:23] == 'BTrees' \
and hasattr(obj, 'keys')) \
and ((item != self.root and parent != self.root) \
or (parent == self.root and not self.rootIsNamespace)):
name = '[' + name + ']'
# Apply dot syntax to multipart names.
if partial:
if partial[0] == '[':
name += partial
else:
name += '.' + partial
# Repeat for everything but the root item
# and first level children of a namespace.
if (item != self.root and parent != self.root) \
or (parent == self.root and not self.rootIsNamespace):
name = self.getFullName(parent, partial=name)
return name
def setText(self, text):
"""Display information about the current selection."""
# This method will likely be replaced by the enclosing app to
# do something more interesting, like write to a text control.
print text
def setStatusText(self, text):
"""Display status information."""
# This method will likely be replaced by the enclosing app to
# do something more interesting, like write to a status bar.
print text
class FillingText(editwindow.EditWindow):
"""FillingText based on StyledTextCtrl."""
name = 'Filling Text'
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.CLIP_CHILDREN,
static=False):
"""Create FillingText instance."""
editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
# Configure various defaults and user preferences.
self.SetReadOnly(True)
self.SetWrapMode(True)
self.SetMarginWidth(1, 0)
if not static:
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
def push(self, command, more):
"""Receiver for Interpreter.push signal."""
self.Refresh()
def SetText(self, *args, **kwds):
self.SetReadOnly(False)
editwindow.EditWindow.SetText(self, *args, **kwds)
self.SetReadOnly(True)
class Filling(wx.SplitterWindow):
"""Filling based on wxSplitterWindow."""
name = 'Filling'
revision = __revision__
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.SP_3D,
name='Filling Window', rootObject=None,
rootLabel=None, rootIsNamespace=False, static=False):
"""Create a Filling instance."""
wx.SplitterWindow.__init__(self, parent, id, pos, size, style, name)
self.tree = FillingTree(parent=self, rootObject=rootObject,
rootLabel=rootLabel,
rootIsNamespace=rootIsNamespace,
static=static)
self.text = FillingText(parent=self, static=static)
self.SplitVertically(self.tree, self.text, 130)
self.SetMinimumPaneSize(1)
# Override the filling so that descriptions go to FillingText.
self.tree.setText = self.text.SetText
# Display the root item.
## self.tree.SelectItem(self.tree.root)
self.tree.display()
class FillingFrame(wx.Frame):
"""Frame containing the namespace tree component."""
name = 'Filling Frame'
revision = __revision__
def __init__(self, parent=None, id=-1, title='PyFilling',
pos=wx.DefaultPosition, size=(600, 400),
style=wx.DEFAULT_FRAME_STYLE, rootObject=None,
rootLabel=None, rootIsNamespace=False, static=False):
"""Create FillingFrame instance."""
wx.Frame.__init__(self, parent, id, title, pos, size, style)
intro = 'PyFilling - The Tastiest Namespace Inspector'
self.CreateStatusBar()
self.SetStatusText(intro)
import images
self.SetIcon(images.getPyIcon())
self.filling = Filling(parent=self, rootObject=rootObject,
rootLabel=rootLabel,
rootIsNamespace=rootIsNamespace,
static=static)
# Override so that status messages go to the status bar.
self.filling.tree.setStatusText = self.SetStatusText
class App(wx.App):
"""PyFilling standalone application."""
def OnInit(self):
wx.InitAllImageHandlers()
self.fillingFrame = FillingFrame()
self.fillingFrame.Show(True)
self.SetTopWindow(self.fillingFrame)
return True

View File

@@ -0,0 +1,348 @@
"""Base frame with menu."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
from version import VERSION
try:
True
except NameError:
True = 1==1
False = 1==0
ID_NEW = wx.ID_NEW
ID_OPEN = wx.ID_OPEN
ID_REVERT = wx.ID_REVERT
ID_CLOSE = wx.ID_CLOSE
ID_SAVE = wx.ID_SAVE
ID_SAVEAS = wx.ID_SAVEAS
ID_PRINT = wx.ID_PRINT
ID_EXIT = wx.ID_EXIT
ID_UNDO = wx.ID_UNDO
ID_REDO = wx.ID_REDO
ID_CUT = wx.ID_CUT
ID_COPY = wx.ID_COPY
ID_PASTE = wx.ID_PASTE
ID_CLEAR = wx.ID_CLEAR
ID_SELECTALL = wx.ID_SELECTALL
ID_ABOUT = wx.ID_ABOUT
ID_AUTOCOMP = wx.NewId()
ID_AUTOCOMP_SHOW = wx.NewId()
ID_AUTOCOMP_MAGIC = wx.NewId()
ID_AUTOCOMP_SINGLE = wx.NewId()
ID_AUTOCOMP_DOUBLE = wx.NewId()
ID_CALLTIPS = wx.NewId()
ID_CALLTIPS_SHOW = wx.NewId()
ID_COPY_PLUS = wx.NewId()
ID_NAMESPACE = wx.NewId()
ID_PASTE_PLUS = wx.NewId()
ID_WRAP = wx.NewId()
class Frame(wx.Frame):
"""Frame with standard menu items."""
revision = __revision__
def __init__(self, parent=None, id=-1, title='Editor',
pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.DEFAULT_FRAME_STYLE):
"""Create a Frame instance."""
wx.Frame.__init__(self, parent, id, title, pos, size, style)
self.CreateStatusBar()
self.SetStatusText('Frame')
import images
self.SetIcon(images.getPyIcon())
self.__createMenus()
wx.EVT_CLOSE(self, self.OnClose)
def OnClose(self, event):
"""Event handler for closing."""
self.Destroy()
def __createMenus(self):
m = self.fileMenu = wx.Menu()
m.Append(ID_NEW, '&New \tCtrl+N',
'New file')
m.Append(ID_OPEN, '&Open... \tCtrl+O',
'Open file')
m.AppendSeparator()
m.Append(ID_REVERT, '&Revert \tCtrl+R',
'Revert to last saved version')
m.Append(ID_CLOSE, '&Close \tCtrl+W',
'Close file')
m.AppendSeparator()
m.Append(ID_SAVE, '&Save... \tCtrl+S',
'Save file')
m.Append(ID_SAVEAS, 'Save &As \tShift+Ctrl+S',
'Save file with new name')
m.AppendSeparator()
m.Append(ID_PRINT, '&Print... \tCtrl+P',
'Print file')
m.AppendSeparator()
m.Append(ID_NAMESPACE, '&Update Namespace \tShift+Ctrl+N',
'Update namespace for autocompletion and calltips')
m.AppendSeparator()
m.Append(ID_EXIT, 'E&xit', 'Exit Program')
m = self.editMenu = wx.Menu()
m.Append(ID_UNDO, '&Undo \tCtrl+Z',
'Undo the last action')
m.Append(ID_REDO, '&Redo \tCtrl+Y',
'Redo the last undone action')
m.AppendSeparator()
m.Append(ID_CUT, 'Cu&t \tCtrl+X',
'Cut the selection')
m.Append(ID_COPY, '&Copy \tCtrl+C',
'Copy the selection')
m.Append(ID_COPY_PLUS, 'Cop&y Plus \tShift+Ctrl+C',
'Copy the selection - retaining prompts')
m.Append(ID_PASTE, '&Paste \tCtrl+V', 'Paste from clipboard')
m.Append(ID_PASTE_PLUS, 'Past&e Plus \tShift+Ctrl+V',
'Paste and run commands')
m.AppendSeparator()
m.Append(ID_CLEAR, 'Cle&ar',
'Delete the selection')
m.Append(ID_SELECTALL, 'Select A&ll \tCtrl+A',
'Select all text')
m = self.autocompMenu = wx.Menu()
m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion',
'Show auto completion list', 1)
m.Append(ID_AUTOCOMP_MAGIC, 'Include Magic Attributes',
'Include attributes visible to __getattr__ and __setattr__',
1)
m.Append(ID_AUTOCOMP_SINGLE, 'Include Single Underscores',
'Include attibutes prefixed by a single underscore', 1)
m.Append(ID_AUTOCOMP_DOUBLE, 'Include Double Underscores',
'Include attibutes prefixed by a double underscore', 1)
m = self.calltipsMenu = wx.Menu()
m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips',
'Show call tips with argument signature and docstring', 1)
m = self.optionsMenu = wx.Menu()
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.Menu()
m.AppendSeparator()
m.Append(ID_ABOUT, '&About...', 'About this program')
b = self.menuBar = wx.MenuBar()
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, ID_NEW, self.OnFileNew)
wx.EVT_MENU(self, ID_OPEN, self.OnFileOpen)
wx.EVT_MENU(self, ID_REVERT, self.OnFileRevert)
wx.EVT_MENU(self, ID_CLOSE, self.OnFileClose)
wx.EVT_MENU(self, ID_SAVE, self.OnFileSave)
wx.EVT_MENU(self, ID_SAVEAS, self.OnFileSaveAs)
wx.EVT_MENU(self, ID_NAMESPACE, self.OnFileUpdateNamespace)
wx.EVT_MENU(self, ID_PRINT, self.OnFilePrint)
wx.EVT_MENU(self, ID_EXIT, self.OnExit)
wx.EVT_MENU(self, ID_UNDO, self.OnUndo)
wx.EVT_MENU(self, ID_REDO, self.OnRedo)
wx.EVT_MENU(self, ID_CUT, self.OnCut)
wx.EVT_MENU(self, ID_COPY, self.OnCopy)
wx.EVT_MENU(self, ID_COPY_PLUS, self.OnCopyPlus)
wx.EVT_MENU(self, ID_PASTE, self.OnPaste)
wx.EVT_MENU(self, ID_PASTE_PLUS, self.OnPastePlus)
wx.EVT_MENU(self, ID_CLEAR, self.OnClear)
wx.EVT_MENU(self, ID_SELECTALL, self.OnSelectAll)
wx.EVT_MENU(self, ID_ABOUT, self.OnAbout)
wx.EVT_MENU(self, ID_AUTOCOMP_SHOW, self.OnAutoCompleteShow)
wx.EVT_MENU(self, ID_AUTOCOMP_MAGIC, self.OnAutoCompleteMagic)
wx.EVT_MENU(self, ID_AUTOCOMP_SINGLE, self.OnAutoCompleteSingle)
wx.EVT_MENU(self, ID_AUTOCOMP_DOUBLE, self.OnAutoCompleteDouble)
wx.EVT_MENU(self, ID_CALLTIPS_SHOW, self.OnCallTipsShow)
wx.EVT_MENU(self, ID_WRAP, self.OnWrap)
wx.EVT_UPDATE_UI(self, ID_NEW, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_OPEN, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_REVERT, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_CLOSE, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_SAVE, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_SAVEAS, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_NAMESPACE, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_PRINT, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_UNDO, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_REDO, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_CUT, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_COPY, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_COPY_PLUS, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_PASTE, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_PASTE_PLUS, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_CLEAR, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_SELECTALL, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_MAGIC, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_SINGLE, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_DOUBLE, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu)
wx.EVT_UPDATE_UI(self, ID_WRAP, self.OnUpdateMenu)
def OnFileNew(self, event):
self.bufferNew()
def OnFileOpen(self, event):
self.bufferOpen()
def OnFileRevert(self, event):
self.bufferRevert()
def OnFileClose(self, event):
self.bufferClose()
def OnFileSave(self, event):
self.bufferSave()
def OnFileSaveAs(self, event):
self.bufferSaveAs()
def OnFileUpdateNamespace(self, event):
self.updateNamespace()
def OnFilePrint(self, event):
self.bufferPrint()
def OnExit(self, event):
self.Close(False)
def OnUndo(self, event):
win = wx.Window_FindFocus()
win.Undo()
def OnRedo(self, event):
win = wx.Window_FindFocus()
win.Redo()
def OnCut(self, event):
win = wx.Window_FindFocus()
win.Cut()
def OnCopy(self, event):
win = wx.Window_FindFocus()
win.Copy()
def OnCopyPlus(self, event):
win = wx.Window_FindFocus()
win.CopyWithPrompts()
def OnPaste(self, event):
win = wx.Window_FindFocus()
win.Paste()
def OnPastePlus(self, event):
win = wx.Window_FindFocus()
win.PasteAndRun()
def OnClear(self, event):
win = wx.Window_FindFocus()
win.Clear()
def OnSelectAll(self, event):
win = wx.Window_FindFocus()
win.SelectAll()
def OnAbout(self, event):
"""Display an About window."""
title = 'About'
text = 'Your message here.'
dialog = wx.MessageDialog(self, text, title,
wx.OK | wx.ICON_INFORMATION)
dialog.ShowModal()
dialog.Destroy()
def OnAutoCompleteShow(self, event):
win = wx.Window_FindFocus()
win.autoComplete = event.IsChecked()
def OnAutoCompleteMagic(self, event):
win = wx.Window_FindFocus()
win.autoCompleteIncludeMagic = event.IsChecked()
def OnAutoCompleteSingle(self, event):
win = wx.Window_FindFocus()
win.autoCompleteIncludeSingle = event.IsChecked()
def OnAutoCompleteDouble(self, event):
win = wx.Window_FindFocus()
win.autoCompleteIncludeDouble = event.IsChecked()
def OnCallTipsShow(self, event):
win = wx.Window_FindFocus()
win.autoCallTip = event.IsChecked()
def OnWrap(self, event):
win = wx.Window_FindFocus()
win.SetWrapMode(event.IsChecked())
def OnUpdateMenu(self, event):
"""Update menu items based on current status and context."""
win = wx.Window_FindFocus()
id = event.GetId()
event.Enable(True)
try:
if id == ID_NEW:
event.Enable(hasattr(self, 'bufferNew'))
elif id == ID_OPEN:
event.Enable(hasattr(self, 'bufferOpen'))
elif id == ID_REVERT:
event.Enable(hasattr(self, 'bufferRevert') and self.hasBuffer())
elif id == ID_CLOSE:
event.Enable(hasattr(self, 'bufferClose') and self.hasBuffer())
elif id == ID_SAVE:
event.Enable(hasattr(self, 'bufferSave') and self.bufferHasChanged())
elif id == ID_SAVEAS:
event.Enable(hasattr(self, 'bufferSaveAs') and self.hasBuffer())
elif id == ID_NAMESPACE:
event.Enable(hasattr(self, 'updateNamespace') and self.hasBuffer())
elif id == ID_PRINT:
event.Enable(hasattr(self, 'bufferPrint') and self.hasBuffer())
elif id == ID_UNDO:
event.Enable(win.CanUndo())
elif id == ID_REDO:
event.Enable(win.CanRedo())
elif id == ID_CUT:
event.Enable(win.CanCut())
elif id == ID_COPY:
event.Enable(win.CanCopy())
elif id == ID_COPY_PLUS:
event.Enable(win.CanCopy() and hasattr(win, 'CopyWithPrompts'))
elif id == ID_PASTE:
event.Enable(win.CanPaste())
elif id == ID_PASTE_PLUS:
event.Enable(win.CanPaste() and hasattr(win, 'PasteAndRun'))
elif id == ID_CLEAR:
event.Enable(win.CanCut())
elif id == ID_SELECTALL:
event.Enable(hasattr(win, 'SelectAll'))
elif id == ID_AUTOCOMP_SHOW:
event.Check(win.autoComplete)
elif id == ID_AUTOCOMP_MAGIC:
event.Check(win.autoCompleteIncludeMagic)
elif id == ID_AUTOCOMP_SINGLE:
event.Check(win.autoCompleteIncludeSingle)
elif id == ID_AUTOCOMP_DOUBLE:
event.Check(win.autoCompleteIncludeDouble)
elif id == ID_CALLTIPS_SHOW:
event.Check(win.autoCallTip)
elif id == ID_WRAP:
event.Check(win.GetWrapMode())
else:
event.Enable(False)
except AttributeError:
# This menu option is not supported in the current context.
event.Enable(False)

View File

@@ -1,12 +1,26 @@
#----------------------------------------------------------------------
# This file was generated by ../scripts/img2py
#
from wxPython.wx import wxImageFromStream, wxBitmapFromImage
from wxPython.wx import wxEmptyIcon
"""Support for icons."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
import cStringIO
def getPyCrustData():
def getPyIcon():
icon = wx.EmptyIcon()
icon.CopyFromBitmap(getPyBitmap())
return icon
def getPyBitmap():
return wx.BitmapFromImage(getPyImage())
def getPyImage():
stream = cStringIO.StringIO(getPyData())
return wx.ImageFromStream(stream)
def getPyData():
return \
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\
@@ -56,16 +70,3 @@ N\xba\xb3\xab\x87\xfb\x8f\x97\xd8\xd9\xd5\x03\xc0\xfd\xc7K\xec\xd8\xd6\xdd\
\x8f\xdb\xbel\x8e\xa1S\xc7\xda\xc6\xe6\xee\xccs\xe9\xdcYnV\x95\xd8\xf2?&q+\
\x9c\x1b1\xf3\xbf\xcd3{\xfdJ\xdb\xf8\xde\xfd\x19.\\\xad\x08\x80\xbf\x01\xd1\
\x86\xfa\x8b\xc7\xc0\xc8\xb7\x00\x00\x00\x00IEND\xaeB`\x82'
def getPyCrustBitmap():
return wxBitmapFromImage(getPyCrustImage())
def getPyCrustImage():
stream = cStringIO.StringIO(getPyCrustData())
return wxImageFromStream(stream)
def getPyCrustIcon():
icon = wxEmptyIcon()
icon.CopyFromBitmap(getPyCrustBitmap())
return icon

View File

@@ -1,4 +1,4 @@
"""PyCrust Interpreter executes Python commands."""
"""Interpreter executes Python commands."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
@@ -18,7 +18,7 @@ except NameError:
class Interpreter(InteractiveInterpreter):
"""PyCrust Interpreter based on code.InteractiveInterpreter."""
"""Interpreter based on code.InteractiveInterpreter."""
revision = __revision__
@@ -112,7 +112,7 @@ class Interpreter(InteractiveInterpreter):
class InterpreterAlaCarte(Interpreter):
"""PyCrustAlaCarte Demo Interpreter."""
"""Demo Interpreter."""
def __init__(self, locals, rawin, stdin, stdout, stderr,
ps1='main prompt', ps2='continuation prompt'):

View File

@@ -9,6 +9,7 @@ from __future__ import nested_scopes
import cStringIO
import inspect
import sys
import tokenize
import types
@@ -173,7 +174,10 @@ def getCallTip(command='', locals=None):
tip1 = name + argspec
doc = ''
if callable(object):
doc = inspect.getdoc(object)
try:
doc = inspect.getdoc(object)
except:
pass
if doc:
# tip2 is the first separated line of the docstring, like:
# "Return call tip text for a command."
@@ -200,6 +204,10 @@ def getRoot(command, terminator=None):
effects. The command would normally terminate with a '(' or
'.'. The terminator and anything after the terminator will be
dropped."""
command = command.split('\n')[-1]
if command.startswith(sys.ps2):
command = command[len(sys.ps2):]
command = command.lstrip()
command = rtrimTerminus(command, terminator)
tokens = getTokens(command)
if not tokens:
@@ -207,13 +215,17 @@ def getRoot(command, terminator=None):
if tokens[-1][0] is tokenize.ENDMARKER:
# Remove the end marker.
del tokens[-1]
if not tokens:
return ''
if terminator == '.' and \
(tokens[-1][1] <> '.' or tokens[-1][0] is not tokenize.OP):
# Trap decimals in numbers, versus the dot operator.
return ''
else:
# Strip off the terminator.
command = command[:-1]
if terminator and command.endswith(terminator):
size = 0 - len(terminator)
command = command[:size]
command = command.rstrip()
tokens = getTokens(command)
tokens.reverse()
@@ -293,7 +305,7 @@ def getTokens(command):
return tokens
def rtrimTerminus(command, terminator=None):
"""Return command minus anything that fillows the final terminator."""
"""Return command minus anything that follows the final terminator."""
if terminator:
pieces = command.split(terminator)
if len(pieces) > 1:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import unittest
# Import from this module's parent directory.
import os
import sys
sys.path.insert(0, os.pardir)
import interpreter
del sys.path[0]
del sys
del os
"""
These unittest methods are preferred:
-------------------------------------
self.assert_(expr, msg=None)
self.assertEqual(first, second, msg=None)
self.assertRaises(excClass, callableObj, *args, **kwargs)
self.fail(msg=None)
self.failIf(expr, msg=None)
"""
class ModuleTestCase(unittest.TestCase):
def test_module(self):
module = interpreter
self.assert_(module.__author__)
self.assert_(module.__cvsid__)
self.assert_(module.__revision__)
self.assert_(module.Interpreter)
self.assert_(module.Interpreter.push)
self.assert_(module.Interpreter.runsource)
self.assert_(module.Interpreter.getAutoCompleteList)
self.assert_(module.Interpreter.getCallTip)
self.assert_(module.InterpreterAlaCarte)
class InterpreterTestCase(unittest.TestCase):
def setUp(self):
self.output = ''
self.i = interpreter.Interpreter(stdout=self)
def write(self, text):
"""Capture output from self.i.push()."""
self.output += text
def tearDown(self):
self.output = ''
self.i = None
del self.i
def test_more(self):
self.assertEqual(self.i.push('dir()'), 0)
self.assertEqual(self.i.push('for n in range(3):'), 1)
def test_push(self):
values = (
('dir', '<built-in function dir>'),
('dir()', "['__builtins__', '__doc__', '__name__']"),
('2 + 2', '4'),
('d = {}', ''),
('d', '{}'),
('del d', ''),
('len([4,5,6])', '3'),
)
for input, output in values:
if output: output += '\n'
self.i.push(input)
self.assertEqual(self.output, output)
self.output = ''
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,862 @@
#!/usr/bin/env python
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import unittest
# Import from this module's parent directory.
import os
import sys
sys.path.insert(0, os.pardir)
import introspect
del sys.path[0]
del sys
del os
"""
These unittest methods are preferred:
-------------------------------------
self.assert_(expr, msg=None)
self.assertEqual(first, second, msg=None)
self.assertRaises(excClass, callableObj, *args, **kwargs)
self.fail(msg=None)
self.failIf(expr, msg=None)
"""
class ModuleTestCase(unittest.TestCase):
def test_module(self):
module = introspect
self.assert_(module.__author__)
self.assert_(module.__cvsid__)
self.assert_(module.__revision__)
self.assert_(module.getAllAttributeNames)
self.assert_(module.getAttributeNames)
self.assert_(module.getAutoCompleteList)
self.assert_(module.getBaseObject)
self.assert_(module.getCallTip)
self.assert_(module.getConstructor)
self.assert_(module.getRoot)
self.assert_(module.rtrimTerminus)
class RtrimTerminusTestCase(unittest.TestCase):
def test_rtrimTerminus(self):
values = (
('', '', ''),
('', None, ''),
('', '.', ''),
('', '(', ''),
('.', '', '.'),
('.', None, '.'),
('.', '.', '.'),
('.', '(', '.'),
('(', '', '('),
('(', None, '('),
('(', '.', '('),
('(', '(', '('),
('spam', '', 'spam'),
('spam', None, 'spam'),
('spam', '.', 'spam'),
('spam', '(', 'spam'),
('spam.', '', 'spam.'),
('spam.', None, 'spam.'),
('spam.', '.', 'spam.'),
('spam.', '(', 'spam.'),
('spam(', '', 'spam('),
('spam(', None, 'spam('),
('spam(', '.', 'spam('),
('spam(', '(', 'spam('),
('spam.eggs', '.', 'spam.'),
('spam.eggs.', '.', 'spam.eggs.'),
('spam.eggs(', '(', 'spam.eggs('),
('spam.eggs.', '(', 'spam.eggs.'),
('spam.eggs(', '.', 'spam.'),
('x = spam.', '.', 'x = spam.'),
('x = spam.eggs', '.', 'x = spam.'),
('x = spam.eggs.', '.', 'x = spam.eggs.'),
('x = spam.eggs(', '(', 'x = spam.eggs('),
)
for input, terminator, output in values:
result = introspect.rtrimTerminus(input, terminator)
self.assertEqual(result, output,
':in: %r :t: %r :out: %r :result: %r' %
(input, terminator, output, result))
class GetRootTestCase(unittest.TestCase):
def _checkRoot(self, input, terminator, output):
root = introspect.getRoot(command=input, terminator=terminator)
self.assertEqual(root, output,
':in: %r :t: %r :out: %r :root: %r' %
(input, terminator, output, root))
def test_getRoot(self):
values = (
('', '', ''),
('', None, ''),
('', '.', ''),
('', '(', ''),
('.', '', '.'),
('.', None, '.'),
('.', '.', ''),
('.', '(', '.'),
('(', '', ''),
('(', None, ''),
('(', '.', ''),
('(', '(', ''),
('spam', '', 'spam'),
('spam', None, 'spam'),
('spam', '.', ''),
('spam', '(', 'spam'),
('spam.', '', 'spam.'),
('spam.', None, 'spam.'),
('spam.', '.', 'spam'),
('spam.', '(', 'spam.'),
('spam(', '', ''),
('spam(', None, ''),
('spam(', '.', ''),
('spam(', '(', 'spam'),
('spam.eggs', '.', 'spam'),
('spam.eggs.', '.', 'spam.eggs'),
('spam.eggs(', '(', 'spam.eggs'),
('spam.eggs.', '(', 'spam.eggs.'),
('spam.eggs(', '.', 'spam'),
('x = spam.', '.', 'spam'),
('x = spam.eggs', '.', 'spam'),
('x = spam.eggs.', '.', 'spam.eggs'),
('x = spam.eggs(', '(', 'spam.eggs'),
('for n in range(3):\n d.', '.', 'd'),
('for n in range(3):\n... d.', '.', 'd'),
)
for input, terminator, output in values:
self._checkRoot(input, terminator, output)
def test_getRoot_Advanced(self):
values = (
('spam_', '', 'spam_'),
('spam_', None, 'spam_'),
('spam_', '.', ''),
('spam_', '(', 'spam_'),
('_spam', '', '_spam'),
('_spam', None, '_spam'),
('_spam', '.', ''),
('_spam', '(', '_spam'),
('spam_eggs', '', 'spam_eggs'),
('spam_eggs', None, 'spam_eggs'),
('spam_eggs', '.', ''),
('spam_eggs', '(', 'spam_eggs'),
('spam123', '', 'spam123'),
('spam123', None, 'spam123'),
('spam123', '.', ''),
('spam123', '(', 'spam123'),
('spam_123', '', 'spam_123'),
('spam_123', None, 'spam_123'),
('spam_123', '.', ''),
('spam_123', '(', 'spam_123'),
)
for input, terminator, output in values:
self._checkRoot(input, terminator, output)
## The original intent was to detect when we were inside a string.
## That has proven to be very difficult, for little benefit.
## The fact that autocomplete or calltips might be triggered inside
## a string is not a big deal. Sometimes it is even helpful.
## def test_getRoot_InsideStrings(self):
## values = (
## ('x = ".', '.', ''),
## ("x = '.", '.', ''),
## ('x = """.', '.', ''),
## ("x = '''.", '.', ''),
##
## ('x = "(', '(', ''),
## ("x = '(", '(', ''),
## ('x = """(', '(', ''),
## ("x = '''(", '(', ''),
##
## ('x = "spam', '.', ''),
## ('x = "spam.', '.', ''),
## ("x = 'spam.", '.', ''),
## ('x = """spam.', '.', ''),
## ("x = '''spam.", '.', ''),
##
## ('x = "spam', '(', ''),
## ('x = "spam(', '(', ''),
## ("x = 'spam(", '(', ''),
## ('x = """spam(', '(', ''),
## ("x = '''spam(", '(', ''),
##
## ('x = "spam.eggs.', '.', ''),
## ("x = 'spam.eggs.", '.', ''),
## ('x = """spam.eggs.', '.', ''),
## ("x = '''spam.eggs.", '.', ''),
##
## ('x = "spam.eggs(', '(', ''),
## ("x = 'spam.eggs(", '(', ''),
## ('x = """spam.eggs(', '(', ''),
## ("x = '''spam.eggs(", '(', ''),
## )
## for input, terminator, output in values:
## self._checkRoot(input, terminator, output)
def test_getRoot_EmptyTypes(self):
values = (
("''.", '.', "''"),
('"".', '.', '""'),
('"""""".', '.', '""""""'),
("''''''.", '.', "''''''"),
('[].', '.', '[]'),
('().', '.', '()'),
('{}.', '.', '{}'),
('[](', '(', '[]'),
('()(', '(', '()'),
('{}(', '(', '{}'),
("x = ''.", '.', "''"),
('x = "".', '.', '""'),
('x = """""".', '.', '""""""'),
("x = ''''''.", '.', "''''''"),
('x = [].', '.', '[]'),
('x = ().', '.', '()'),
('x = {}.', '.', '{}'),
('x = [](', '(', '[]'),
('x = ()(', '(', '()'),
('x = {}(', '(', '{}'),
('print [].', '.', '[]'),
('print ().', '.', '()'),
('print {}.', '.', '{}'),
('print [](', '(', '[]'),
('print ()(', '(', '()'),
('print {}(', '(', '{}'),
("''.attr.", '.', "''.attr"),
('"".attr.', '.', '"".attr'),
('"""""".attr.', '.', '"""""".attr'),
("''''''.attr.", '.', "''''''.attr"),
('[].attr.', '.', '[].attr'),
('().attr.', '.', '().attr'),
('{}.attr.', '.', '{}.attr'),
('[].attr(', '(', '[].attr'),
('().attr(', '(', '().attr'),
('{}.attr(', '(', '{}.attr'),
('spam().', '.', ''),
('spam_().', '.', ''),
('spam5().', '.', ''),
('spam[]().', '.', ''),
('spam()[].', '.', ''),
('spam[]{}.', '.', ''),
("spam(''.", '.', "''"),
('spam("".', '.', '""'),
('spam("""""".', '.', '""""""'),
("spam(''''''.", '.', "''''''"),
('spam([].', '.', '[]'),
('spam(().', '.', '()'),
('spam({}.', '.', '{}'),
('spam[[].', '.', '[]'),
('spam[().', '.', '()'),
('spam[{}.', '.', '{}'),
('x = {[].', '.', '[]'),
('x = {().', '.', '()'),
('x = {{}.', '.', '{}'),
('spam,[].', '.', '[]'),
('spam+[].', '.', '[]'),
('spam-[].', '.', '[]'),
('spam*[].', '.', '[]'),
('spam/[].', '.', '[]'),
('spam=[].', '.', '[]'),
('spam%[].', '.', '[]'),
('spam<[].', '.', '[]'),
('spam>[].', '.', '[]'),
('spam&[].', '.', '[]'),
('spam|[].', '.', '[]'),
('spam^[].', '.', '[]'),
('spam~[].', '.', '[]'),
('spam:[].', '.', '[]'),
('spam,().', '.', '()'),
('spam+().', '.', '()'),
('spam-().', '.', '()'),
('spam*().', '.', '()'),
('spam/().', '.', '()'),
('spam=().', '.', '()'),
('spam%().', '.', '()'),
('spam<().', '.', '()'),
('spam>().', '.', '()'),
('spam&().', '.', '()'),
('spam|().', '.', '()'),
('spam^().', '.', '()'),
('spam~().', '.', '()'),
('spam:().', '.', '()'),
('spam,{}.', '.', '{}'),
('spam+{}.', '.', '{}'),
('spam-{}.', '.', '{}'),
('spam*{}.', '.', '{}'),
('spam/{}.', '.', '{}'),
('spam={}.', '.', '{}'),
('spam%{}.', '.', '{}'),
('spam<{}.', '.', '{}'),
('spam>{}.', '.', '{}'),
('spam&{}.', '.', '{}'),
('spam|{}.', '.', '{}'),
('spam^{}.', '.', '{}'),
('spam~{}.', '.', '{}'),
('spam:{}.', '.', '{}'),
)
for input, terminator, output in values:
self._checkRoot(input, terminator, output)
# Support for GetBaseObjectTestCase and GetAttributeNamesTestCase.
class Foo:
def __init__(self):
pass
def __del__(self):
pass
def _private(self):
pass
class Bar:
pass
class Spam:
def __call__(self):
pass
def foo(self):
pass
def bar(spam):
# It shouldn't matter what we call "self".
pass
def eggs(self):
pass
def ham(eggs):
pass
class GetBaseObjectTestCase(unittest.TestCase):
def test_getBaseObject(self):
spam = Spam()
eggs = Spam.eggs
listappend = [].append
spamda = lambda: None
values = (
('spam', 'spam', 0),
(123, 123, 0),
(12.3, 12.3, 0),
([], [], 0),
((), (), 0),
({}, {}, 0),
# Builtin function.
(len, len, 0),
# Builtin method.
(listappend, listappend, 0),
# User function.
(ham, ham, 0),
# Byte-compiled code.
(ham.func_code, ham.func_code, 0),
# Lambda.
(spamda, spamda, 0),
# Class with init.
(Foo, Foo.__init__.im_func, 1),
# Class with no init.
(Bar, Bar, 0),
# Bound method.
(spam.foo, spam.foo.im_func, 1),
# Bound method with self named something else (spam).
(spam.bar, spam.bar.im_func, 1),
# Unbound method. (Do not drop the self argument.)
(eggs, eggs.im_func, 0),
# Callable instance.
(spam, spam.__call__.im_func, 1),
)
for object, baseObject, dropSelf in values:
result = introspect.getBaseObject(object)
self.assertEqual(result, (baseObject, dropSelf))
class GetAttributeTestCase(unittest.TestCase):
"""Base class for other test case classes."""
def setUp(self):
self.values = (
'__abs__',
'__add__',
'__and__',
'__base__',
'__bases__',
'__basicsize__',
'__builtins__',
'__call__',
'__class__',
'__cmp__',
'__coerce__',
'__contains__',
'__del__',
'__delattr__',
'__delitem__',
'__delslice__',
'__dict__',
'__dictoffset__',
'__div__',
'__divmod__',
'__doc__',
'__eq__',
'__file__',
'__flags__',
'__float__',
'__floordiv__',
'__ge__',
'__get__',
'__getattr__',
'__getattribute__',
'__getitem__',
'__getslice__',
'__gt__',
'__hash__',
'__hex__',
'__iadd__',
'__imul__',
'__init__',
'__int__',
'__invert__',
'__itemsize__',
'__iter__',
'__le__',
'__len__',
'__long__',
'__lshift__',
'__lt__',
'__mod__',
'__module__',
'__mro__',
'__mul__',
'__name__',
'__ne__',
'__neg__',
'__new__',
'__nonzero__',
'__oct__',
'__or__',
'__path__',
'__pos__',
'__pow__',
'__radd__',
'__rand__',
'__rdiv__',
'__rdivmod__',
'__reduce__',
'__repr__',
'__rfloordiv__',
'__rlshift__',
'__rmod__',
'__rmul__',
'__ror__',
'__rpow__',
'__rrshift__',
'__rshift__',
'__rsub__',
'__rtruediv__',
'__rxor__',
'__self__',
'__setattr__',
'__setitem__',
'__setslice__',
'__str__',
'__sub__',
'__subclasses__',
'__truediv__',
'__warningregistry__',
'__weakrefoffset__',
'__xor__',
'append',
'capitalize',
'center',
'clear',
'close',
'closed',
'co_argcount',
'co_cellvars',
'co_code',
'co_consts',
'co_filename',
'co_firstlineno',
'co_flags',
'co_freevars',
'co_lnotab',
'co_name',
'co_names',
'co_nlocals',
'co_stacksize',
'co_varnames',
'conjugate',
'copy',
'count',
'decode',
'encode',
'endswith',
'expandtabs',
'extend',
'fileno',
'find',
'flush',
'func_closure',
'func_code',
'func_defaults',
'func_dict',
'func_doc',
'func_globals',
'func_name',
'get',
'has_key',
'im_class',
'im_func',
'im_self',
'imag',
'index',
'insert',
'isalnum',
'isalpha',
'isatty',
'isdigit',
'islower',
'isspace',
'istitle',
'isupper',
'items',
'iteritems',
'iterkeys',
'itervalues',
'join',
'keys',
'ljust',
'lower',
'lstrip',
'mode',
'mro',
'name',
'pop',
'popitem',
'real',
'read',
'readinto',
'readline',
'readlines',
'remove',
'replace',
'reverse',
'rfind',
'rindex',
'rjust',
'rstrip',
'seek',
'setdefault',
'softspace',
'sort',
'split',
'splitlines',
'start',
'startswith',
'step',
'stop',
'strip',
'swapcase',
'tell',
'title',
'tolist',
'translate',
'truncate',
'update',
'upper',
'values',
'write',
'writelines',
'xreadlines',
)
# Since getAllAttributeNames() calls str(object),
# we need to test for a broken __str__ method.
class BrokenStr:
def __str__(self):
raise Exception
brokenStr = BrokenStr()
class GetAttributeNamesTestCase(GetAttributeTestCase):
def setUp(self):
GetAttributeTestCase.setUp(self)
import PyCrust
spam = Spam()
self.f = open('test_introspect.py')
self.items = (
None,
int(123),
long(123),
float(123),
complex(123),
"",
unicode(""),
[],
(),
xrange(0),
{},
# Builtin function.
len,
# Builtin method.
[].append,
# User function.
ham,
# Byte-compiled code.
ham.func_code,
# Lambda.
lambda: None,
# Class with no init.
Bar,
# Instance with no init.
Bar(),
# Class with init and del.
Foo,
# Instance with init and del.
Foo(),
# Bound method.
spam.foo,
# Unbound method.
Spam.eggs,
# Callable instance.
spam,
# Module.
introspect,
# Package.
PyCrust,
# Buffer.
buffer(''),
# File.
self.f,
# Slice.
slice(0),
# Ellipsis.
Ellipsis,
# BrokenStr class.
BrokenStr,
# BrokenStr instance.
brokenStr,
)
def tearDown(self):
self.items = None
self.f.close()
def test_getAttributeNames(self):
for item in self.items:
self._checkAttributeNames(item)
if __builtins__.has_key('object'):
self._checkAttributeNames(object)
def test_getAttributeNames_NoSingle(self):
for item in self.items:
result = introspect.getAttributeNames(item, includeSingle=0)
attributes = [attribute for attribute in result \
if attribute[0] != '_' or attribute[:2] == '__']
self.assertEqual(result, attributes,
':item: %r' % (item,))
def test_getAttributeNames_NoDouble(self):
for item in self.items:
result = introspect.getAttributeNames(item, includeDouble=0)
attributes = [attribute for attribute in result \
if attribute[:2] != '__']
self.assertEqual(result, attributes,
':item: %r' % (item,))
def test_getAttributeNames_NoSingleOrDouble(self):
for item in self.items:
result = introspect.getAttributeNames(item, includeSingle=0,
includeDouble=0)
attributes = [attribute for attribute in result \
if attribute[0] != '_']
self.assertEqual(result, attributes,
':item: %r' % (item,))
def _checkAttributeNames(self, item):
result = introspect.getAttributeNames(item)
attributes = [attribute for attribute in self.values \
if hasattr(item, attribute)]
for attribute in attributes:
self.assert_(attribute in result,
':item: %r :attribute: %r' % (item, attribute))
class GetAutoCompleteListTestCase(GetAttributeTestCase):
def setUp(self):
GetAttributeTestCase.setUp(self)
self.items = (
'None.',
'123 .',
'"".',
'[].',
'().',
'{}.',
# Builtin function.
'len.',
# Builtin method.
'[].append.',
)
def test_getAutoCompleteList(self):
for item in self.items:
result = introspect.getAutoCompleteList(item)
object = eval(item[:-1])
attributes = [attribute for attribute in self.values \
if hasattr(object, attribute)]
for attribute in attributes:
self.assert_(attribute in result,
':item: %r :attribute: %r' % (item, attribute))
def test_getAutoCompleteList_NoSingle(self):
for item in self.items:
result = introspect.getAutoCompleteList(item, includeSingle=0)
attributes = [attribute for attribute in result \
if attribute[0] != '_' or attribute[:2] == '__']
self.assertEqual(result, attributes,
':item: %r' % (item,))
def test_getAutoCompleteList_NoDouble(self):
for item in self.items:
result = introspect.getAutoCompleteList(item, includeDouble=0)
attributes = [attribute for attribute in result \
if attribute[:2] != '__']
self.assertEqual(result, attributes,
':item: %r' % (item,))
def test_getAutoCompleteList_NoSingleOrDouble(self):
for item in self.items:
result = introspect.getAutoCompleteList(item, includeSingle=0,
includeDouble=0)
attributes = [attribute for attribute in result \
if attribute[0] != '_']
self.assertEqual(result, attributes,
':item: %r' % (item,))
# Support for GetConstructorTestCase.
class A1:
def __init__(self, a):
self.a = a
class B1(A1):
def __init__(self, b):
self.b = b
class C1(A1):
pass
class D1(C1, B1):
pass
if __builtins__.has_key('object'):
class A2(object):
def __init__(self, a):
self.a = a
class B2(A2):
def __init__(self, b):
self.b = b
class C2(A2):
pass
class D2(C2, B2):
pass
class N:
pass
class O:
def __init__(self, a, b=2, *args, **kwargs):
pass
class P(O):
pass
class Q(P):
def __init__(self, c, d=4):
pass
class GetConstructorTestCase(unittest.TestCase):
def test_getConstructor(self):
args = ('self', 'a', 'b', 'args', 'kwargs')
varnames = introspect.getConstructor(O).func_code.co_varnames
self.assertEqual(varnames, args)
varnames = introspect.getConstructor(P).func_code.co_varnames
self.assertEqual(varnames, args)
args = ('self', 'c', 'd')
varnames = introspect.getConstructor(Q).func_code.co_varnames
self.assertEqual(varnames, args)
def test_getConstructor_None(self):
values = (N, 1, 'spam', {}, [], (), dir)
for value in values:
self.assertEqual(introspect.getConstructor(N), None)
def test_getConstructor_MultipleInheritance(self):
# Test old style inheritance rules.
args = ('self', 'a')
varnames = introspect.getConstructor(D1).func_code.co_varnames
self.assertEqual(varnames, args)
if __builtins__.has_key('object'):
# Test new style inheritance rules as well.
args = ('self', 'b')
varnames = introspect.getConstructor(D2).func_code.co_varnames
self.assertEqual(varnames, args)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,81 @@
#!/usr/bin/env python
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import unittest
# Import from this module's parent directory.
import os
import sys
sys.path.insert(0, os.pardir)
import pseudo
del sys.path[0]
del sys
del os
"""
These unittest methods are preferred:
-------------------------------------
self.assert_(expr, msg=None)
self.assertEqual(first, second, msg=None)
self.assertRaises(excClass, callableObj, *args, **kwargs)
self.fail(msg=None)
self.failIf(expr, msg=None)
"""
class ModuleTestCase(unittest.TestCase):
def test_module(self):
module = pseudo
self.assert_(module.__author__)
self.assert_(module.__cvsid__)
self.assert_(module.__revision__)
self.assert_(module.PseudoFile)
self.assert_(module.PseudoFileErr)
self.assert_(module.PseudoFileIn)
self.assert_(module.PseudoFileOut)
self.assert_(module.PseudoKeyword)
class PseudoTestCase(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
class PseudoFileTestCase(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
class PseudoFileOutTestCase(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def _write(self):
pass
def test_PseudoFileOut_goodInit(self):
self.assert_(pseudo.PseudoFileOut(write=self._write))
def test_PseudoFileOut_badInit(self):
self.assertRaises(ValueError, pseudo.PseudoFileOut, write='bad')
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env python
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import unittest
import types
# Import from this module's parent directory.
import os
import sys
sys.path.insert(0, os.pardir)
import version
del sys.path[0]
del sys
del os
"""
These unittest methods are preferred:
-------------------------------------
self.assert_(expr, msg=None)
self.assertEqual(first, second, msg=None)
self.assertRaises(excClass, callableObj, *args, **kwargs)
self.fail(msg=None)
self.failIf(expr, msg=None)
"""
class ModuleTestCase(unittest.TestCase):
def test_module(self):
module = version
self.assert_(module.__author__)
self.assert_(module.__cvsid__)
self.assert_(module.__revision__)
self.assert_(module.VERSION)
class VersionTestCase(unittest.TestCase):
def test_VERSION(self):
self.assert_(type(version.VERSION) is types.StringType)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import unittest
import glob
import os
def suite():
"""Return a test suite containing all test cases in all test modules.
Searches the current directory for any modules matching test_*.py."""
suite = unittest.TestSuite()
for filename in glob.glob('test_*.py'):
module = __import__(os.path.splitext(filename)[0])
suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(module))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='suite')

View File

@@ -1,11 +1,9 @@
"""Provides an object representing the current 'version' or 'release'
of PyCrust as a whole. Individual classes, such as the shell, filling
and interpreter, each have a revision property based on the CVS
Revision."""
of Py as a whole. Individual classes, such as the shell, filling and
interpreter, each have a revision property based on the CVS Revision."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
VERSION = '0.9'
VERSION = '0.9.2'

View File

@@ -503,6 +503,19 @@ class GenericDirCtrl(Control):
pass
class DirFilterListCtrl(Choice):
""""""
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0):
""""""
pass
def FillFilterList(filter, defaultFilter):
""""""
pass
class ListBox(ControlWithItems):
""""""
@@ -1126,11 +1139,11 @@ class Notebook(Control):
""""""
pass
def AddPage(self, pPage, strText, bSelect=False, imageId=-1):
def AddPage(self, page, text, select=False, imageId=-1):
""""""
pass
def AdvanceSelection(self, bForward=True):
def AdvanceSelection(self, forward=True):
""""""
pass
@@ -1147,7 +1160,7 @@ class Notebook(Control):
""""""
pass
def DeletePage(self, nPage):
def DeletePage(self, page):
""""""
pass
@@ -1155,7 +1168,7 @@ class Notebook(Control):
""""""
pass
def GetPage(self, nPage):
def GetPage(self, page):
""""""
pass
@@ -1163,11 +1176,11 @@ class Notebook(Control):
""""""
pass
def GetPageImage(self, nPage):
def GetPageImage(self, page):
""""""
pass
def GetPageText(self, nPage):
def GetPageText(self, page):
""""""
pass
@@ -1179,11 +1192,11 @@ class Notebook(Control):
""""""
pass
def InsertPage(self, nPage, pPage, strText, bSelect=False, imageId=-1):
def InsertPage(self, index, page, text, select=False, imageId=-1):
""""""
pass
def RemovePage(self, nPage):
def RemovePage(self, page):
""""""
pass
@@ -1199,7 +1212,7 @@ class Notebook(Control):
""""""
pass
def SetPageImage(self, nPage, nImage):
def SetPageImage(self, page, image):
""""""
pass
@@ -1207,11 +1220,11 @@ class Notebook(Control):
""""""
pass
def SetPageText(self, nPage, strText):
def SetPageText(self, page, text):
""""""
pass
def SetSelection(self, nPage):
def SetSelection(self, page):
""""""
pass

View File

@@ -788,7 +788,14 @@ def EVT_WINDOW_CREATE(win, func):
""""""
pass
def EVT_WINDOW_CREATE_ID(win, id, func):
""""""
pass
def EVT_WINDOW_DESTROY(win, func):
""""""
pass
def EVT_WINDOW_DESTROY_ID(win, id, func):
""""""
pass

View File

@@ -37,9 +37,9 @@ class Frame(TopLevelWindow):
name=wx.PyFrameNameStr):
"""Create a Frame instance.
parent - The window parent. This may be NULL. If it is
non-NULL, the frame will always be displayed on top of the
parent window on Windows.
parent - The window parent. This may be None. If it is not
None, the frame will always be displayed on top of the parent
window on Windows.
id - The window identifier. It may take a value of -1 to
indicate a default value.
@@ -93,8 +93,8 @@ class Frame(TopLevelWindow):
By default, the status bar is an instance of wx.StatusBar."""
pass
def CreateToolBar(self, style=wx.NO_BORDER|wx.TB_HORIZONTAL, id=-1,
name=wx.PyToolBarNameStr):
def CreateToolBar(self, style=wx.NO_BORDER | wx.TB_HORIZONTAL,
id=-1, name=wx.PyToolBarNameStr):
"""Create a toolbar at the top or left of frame.
style - The toolbar style. See wxToolBar for a list of valid
@@ -141,8 +141,7 @@ class Frame(TopLevelWindow):
pass
def GetStatusBarPane(self):
"""Return status bar pane used to display menu and toolbar
help."""
"""Return status bar pane used to display menu/toolbar help."""
pass
def GetToolBar(self):
@@ -237,22 +236,102 @@ class Frame(TopLevelWindow):
class LayoutAlgorithm(Object):
""""""
"""LayoutAlgorithm implements layout of subwindows in MDI or SDI
frames. It sends a wx.CalculateLayoutEvent event to children of
the frame, asking them for information about their size. For MDI
parent frames, the algorithm allocates the remaining space to the
MDI client window (which contains the MDI child frames). For SDI
(normal) frames, a 'main' window is specified as taking up the
remaining space.
Because the event system is used, this technique can be applied to
any windows, which are not necessarily 'aware' of the layout
classes. However, you may wish to use wx.SashLayoutWindow for
your subwindows since this class provides handlers for the
required events, and accessors to specify the desired size of the
window. The sash behaviour in the base class can be used,
optionally, to make the windows user-resizable.
LayoutAlgorithm is typically used in IDE (integrated development
environment) applications, where there are several resizable
windows in addition to the MDI client window, or other primary
editing window. Resizable windows might include toolbars, a
project window, and a window for displaying error and warning
messages.
When a window receives an OnCalculateLayout event, it should call
SetRect in the given event object, to be the old supplied
rectangle minus whatever space the window takes up. It should
also set its own size accordingly.
SashLayoutWindow.OnCalculateLayout generates an OnQueryLayoutInfo
event which it sends to itself to determine the orientation,
alignment and size of the window, which it gets from internal
member variables set by the application.
The algorithm works by starting off with a rectangle equal to the
whole frame client area. It iterates through the frame children,
generating OnCalculateLayout events which subtract the window size
and return the remaining rectangle for the next window to process.
It is assumed (by SashLayoutWindow.OnCalculateLayout) that a
window stretches the full dimension of the frame client, according
to the orientation it specifies. For example, a horizontal window
will stretch the full width of the remaining portion of the frame
client area. In the other orientation, the window will be fixed
to whatever size was specified by OnQueryLayoutInfo. An alignment
setting will make the window 'stick' to the left, top, right or
bottom of the remaining client area. This scheme implies that
order of window creation is important. Say you wish to have an
extra toolbar at the top of the frame, a project window to the
left of the MDI client window, and an output window above the
status bar. You should therefore create the windows in this
order: toolbar, output window, project window. This ensures that
the toolbar and output window take up space at the top and bottom,
and then the remaining height in-between is used for the project
window.
LayoutAlgorithm is quite independent of the way in which
OnCalculateLayout chooses to interpret a window's size and
alignment. Therefore you could implement a different window class
with a new OnCalculateLayout event handler, that has a more
sophisticated way of laying out the windows. It might allow
specification of whether stretching occurs in the specified
orientation, for example, rather than always assuming
stretching. (This could, and probably should, be added to the
existing implementation).
The algorithm object does not respond to events, but itself
generates the following events in order to calculate window sizes:
EVT_QUERY_LAYOUT_INFO(func), EVT_CALCULATE_LAYOUT(func)."""
def __init__(self):
""""""
"""Create a LayoutAlgorithm instance."""
pass
def LayoutFrame(self):
""""""
def LayoutFrame(self, frame, mainWindow=wx.NULL):
"""Lay out the children of a normal frame.
mainWindow is set to occupy the remaining space. This
function simply calls LayoutWindow()."""
pass
def LayoutMDIFrame(self):
""""""
def LayoutMDIFrame(self, frame, rect=wx.NULL):
"""Lay out the children of an MDI parent frame.
If rect is non-NULL, the given rectangle will be used as a
starting point instead of the frame's client area.
The MDI client window is set to occupy the remaining space."""
pass
def LayoutWindow(self):
""""""
def LayoutWindow(self, parent, mainWindow=wx.NULL):
"""Lay out the children of a normal frame or other window.
mainWindow is set to occupy the remaining space. If this is
not specified, then the last window that responds to a
calculate layout event in query mode will get the remaining
space (that is, a non-query OnCalculateLayout event will not
be sent to this window and the window will be set to the
remaining size)."""
pass

View File

@@ -36,6 +36,7 @@ _params = (
'DefaultValidator',
'EmptyString',
'EVT_NULL',
'HORIZONTAL',
'HSCROLL',
'NO_BORDER',
'NULL',

View File

@@ -0,0 +1,605 @@
"""Decorator classes for documentation and shell scripting.
Sizer is the abstract base class used for laying out subwindows in a
window. You cannot use Sizer directly; instead, you will have to use
one of the sizer classes derived from it. Currently there are
BoxSizer, StaticBoxSizer, NotebookSizer, GridSizer, and FlexGridSizer.
The layout algorithm used by sizers in wxPython is closely related to
layout in other GUI toolkits, such as Java's AWT, the GTK toolkit or
the Qt toolkit. It is based upon the idea of the individual
subwindows reporting their minimal required size and their ability to
get stretched if the size of the parent window has changed. This will
most often mean, that the programmer does not set the original size of
a dialog in the beginning, rather the dialog will assigned a sizer and
this sizer will be queried about the recommended size. The sizer in
turn will query its children, which can be normal windows, empty space
or other sizers, so that a hierarchy of sizers can be constructed.
Note that wxSizer does not derive from wxWindow and thus do not
interfere with tab ordering and requires very little resources
compared to a real window on screen.
What makes sizers so well fitted for use in wxPython is the fact that
every control reports its own minimal size and the algorithm can
handle differences in font sizes or different window (dialog item)
sizes on different platforms without problems. If e.g. the standard
font as well as the overall design of Motif widgets requires more
space than on Windows, the initial dialog size will automatically be
bigger on Motif than on Windows.
If you wish to create a sizer class in wxPython you should derive the
class from PySizer in order to get Python-aware capabilities for the
various virtual methods.
"""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
# These are not the real wxPython classes. These are Python versions
# for documentation purposes. They are also used to apply docstrings
# to the real wxPython classes, which are SWIG-generated wrappers for
# C-language classes.
from Base import Object
import Parameters as wx
try:
True
except NameError:
True = 1==1
False = 1==0
class Sizer(Object):
"""Sizer is the abstract base class used for laying out subwindows
in a window. You shouldn't use Sizer directly; instead, you should
use one of the sizer classes derived from it.
If you wish to create a sizer class in wxPython you should derive
the class from PySizer in order to get Python-aware capabilities
for the various virtual methods.
Placing a child sizer in a sizer allows you to create hierarchies
of sizers (typically a vertical box as the top sizer and several
horizontal boxes on the level beneath).
When you place a window in a sizer the window's initial size
(either set explicitly by the user or calculated internally when
using wxDefaultSize) is interpreted as the minimal and in many
cases also the initial size. This is particularly useful in
connection with SetSizeHints.
Adding spacers to sizers gives more flexibility in the design of
dialogs. Imagine for example a horizontal box with two buttons at
the bottom of a dialog: you might want to insert a space between
the two buttons and make that space stretchable using the
proportion flag and the result will be that the left button will
be aligned with the left side of the dialog and the right button
with the right side - the space in between will shrink and grow
with the dialog.
Several methods (Add, Insert, Prepend) take the following
parameters:
proportion - Used only by BoxSizer to indicate if a child of a
sizer can change its size in the main orientation of the BoxSizer,
where 0 stands for not changeable and a value of more than zero is
interpreted relative to the value of other children of the same
BoxSizer. For example, you might have a horizontal BoxSizer with
three children, two of which are supposed to change their size
with the sizer. Then the two stretchable windows would each get a
value of 1 to make them grow and shrink equally with the sizer's
horizontal dimension.
flag - This parameter can be used to set a number of flags which
can be combined using the binary OR operator |. Two main
behaviours are defined using these flags. One is the border
around a window: the border parameter determines the border width
whereas the flags given here determine where the border may be
(wx.TOP, wx.BOTTOM, wx.LEFT, wx.RIGHT or wx.ALL). The other flags
determine the child window's behaviour if the size of the sizer
changes. However this is not - in contrast to the proportion flag
- in the main orientation, but in the respectively other
orientation. So if you created a BoxSizer with the wx.VERTICAL
option, these flags will be relevant if the sizer changes its
horizontal size. A child may get resized to completely fill out
the new size (using either wx.GROW or wx.EXPAND), it may get
proportionally resized (wx.SHAPED), it may get centered
(wx.ALIGN_CENTER or wx.ALIGN_CENTRE) or it may get aligned to
either side (wx.ALIGN_LEFT and wx.ALIGN_TOP are set to 0 and thus
represent the default, wx.ALIGN_RIGHT and wx.ALIGN_BOTTOM have
their obvious meaning). With proportional resize, a child may
also be centered in the main orientation using
wx.ALIGN_CENTER_VERTICAL (same as wx.ALIGN_CENTRE_VERTICAL) and
wx.ALIGN_CENTER_HORIZONTAL (same as wx.ALIGN_CENTRE_HORIZONTAL)
flags. Finally, you can also specify wx.ADJUST_MINSIZE flag to
make the minimal size of the control dynamically adjust to the
value returned by its GetAdjustedBestSize() method - this allows,
for example, for correct relayouting of a static text control even
if its text is changed during run-time.
border - Determines the border width, if the flag parameter is set
to any border. A border is not a visible element, but rather a
margin of empty space surrounding the item.
userData - Allows an extra object to be attached to the sizer
item, for use in derived classes when sizing information is more
complex than the option and flag parameters will allow."""
def __init__(self):
"""Must be defined by subclasses."""
pass
def Add(self, item, proportion=0, flag=0, border=0,
userData=wx.NULL):
"""Add item to sizer.
item - window, sizer, or spacer. Spacer is specified with a
(width, height) tuple or wx.Size representing the spacer size.
Call Layout() to update the layout on-screen after adding."""
pass
def Clear(self, delete_windows=False):
"""Remove all items from this sizer.
If delete_windows is True, destroy any window items."""
pass
def DeleteWindows(self):
"""Destroy windows associated with this sizer."""
pass
def Destroy(self):
"""Destroy the sizer."""
pass
def Fit(self, window):
"""Resize window to match sizer's minimal size; return size.
This is commonly done in the constructor of the window itself."""
pass
def FitInside(self, window):
"""Resize window virtual size to match sizer's minimal size.
This will not alter the on screen size of the window, but may
cause the addition/removal/alteration of scrollbars required
to view the virtual area in windows which manage it."""
pass
def GetChildren(self):
"""Return list of SizerItem instances."""
pass
def GetMinSize(self):
"""Return the minimal size of the sizer.
This is either the combined minimal size of all the children
and their borders or the minimal size set by SetMinSize,
whichever is larger."""
pass
def GetMinSizeTuple(self):
"""Return the minimal size of the sizer as a tuple.
This is either the combined minimal size of all the children
and their borders or the minimal size set by SetMinSize,
whichever is larger."""
pass
def GetPosition(self):
"""Return the current position of the sizer."""
pass
def GetPositionTuple(self):
"""Return the current position of the sizer as a tuple."""
pass
def GetSize(self):
"""Return the current size of the sizer."""
pass
def GetSizeTuple(self):
"""Return the current size of the sizer as a tuple."""
pass
def Hide(self, item):
"""Hide item (sizer or window). To make a sizer item
disappear on-screen, use Hide() followed by Layout()."""
pass
def Insert(self, before, item, proportion=0, flag=0, border=0,
userData=wx.NULL):
"""Same as Add, but inserts item into list of items (windows,
subsizers or spacers) owned by this sizer.
Call Layout() to update the layout on-screen after inserting."""
pass
def IsShown(self, item):
"""Return True if item (sizer or window) is shown."""
pass
def Layout(self):
"""Force layout of children anew.
Use after adding or removing a child (window, other sizer, or
spacer) from the sizer while keeping the current dimension."""
pass
def Prepend(self, item, proportion=0, flag=0, border=0,
userData=wx.NULL):
"""Same as Add, but prepends item to beginning of list of
items (windows, subsizers or spacers) owned by this sizer.
Call Layout() to update the layout on-screen after prepending."""
pass
def Remove(self, item):
"""Remove item from the sizer.
item - sizer, window, or index of item in the sizer, typically
0 for the first item.
Does not cause any layout or resizing to take place, and does
not delete the child itself. Call Layout() to update the
layout on-screen after removing child.
Return True if child found and removed, False otherwise."""
pass
def SetDimension(self, x, y, width, height):
"""Force sizer to take the given dimension and thus force
items owned by sizer to resize themselves according to the
rules defined by the parameter in the Add and Prepend methods."""
pass
def SetItemMinSize(self, item, width, height):
"""Set minimal size of item.
item - sizer, window, or index of item in the sizer, typically
0 for the first item.
The item will be found recursively in the sizer's descendants.
Enables application to set size of item after initialization."""
pass
def SetMinSize(self, size):
"""Set minimal size.
Normally, sizer will calculate minimal size based on how much
space its children need. After calling this method,
GetMinSize will return the minimal size as requested by its
children or the minimal size set here, whichever is larger."""
pass
def SetSizeHints(self, window):
"""Set (and Fit) minimal size of window to match sizer's
minimal size. Commonly called in the window's init."""
pass
def SetVirtualSizeHints(self, window):
"""Set minimal size of window virtual area to match sizer's
minimal size. For windows with managed scrollbars this will
set them appropriately."""
pass
def Show(self, item, show=True):
"""Show or hide item (sizer or window). To make item
disappear or reappear on-screen, use Show() followed by
Layout()."""
pass
def ShowItems(self, show):
"""Recursively call Show() on all sizer items."""
pass
class PySizer(Sizer):
"""If you wish to create a custom sizer class you should derive
the class from PySizer in order to get Python-aware capabilities
for the various virtual methods."""
def __init__(self):
"""Create a PySizer instance. Override in subclass."""
pass
class BoxSizer(Sizer):
"""A box sizer is used to lay out a rather simple geometry,
typically a row or column or several hierarchies of either."""
def __init__(self, orient=wx.HORIZONTAL):
"""Create BoxSizer instance.
orient is either wx.VERTICAL or wx.HORIZONTAL"""
pass
def CalcMin(self):
"""Calculate minimum size. Do not call directly."""
pass
def GetOrientation(self):
"""Return orientation: wx.VERTICAL or wx.HORIZONTAL."""
pass
def RecalcSizes(self):
"""Recalculate sizes, then set the size of its children
(calling SetSize if child is a window). Do not call directly."""
pass
def SetOrientation(self, orient):
"""Set orientation to either wx.VERTICAL or wx.HORIZONTAL."""
pass
class StaticBoxSizer(BoxSizer):
"""Like BoxSizer, but adds a static box around the sizer. Note
that the static box has to be created separately."""
def __init__(self, box, orient=wx.HORIZONTAL):
"""Create StaticBoxSizer instance.
box - instance of wx.StaticBox
orient - either wx.VERTICAL or wx.HORIZONTAL"""
pass
def CalcMin(self):
"""Calculate minimum size. Do not call directly."""
pass
def GetStaticBox(self):
"""Return the static box associated with the sizer."""
pass
def RecalcSizes(self):
"""Recalculate sizes, then set the size of its children
(calling SetSize if child is a window). Do not call directly."""
pass
class GridSizer(Sizer):
"""A grid sizer lays out its children in a two-dimensional table
where all cells have the same size: the width of each cell is the
width of the widest child, the height of each cell is the height
of the tallest child. See also the FlexGridSizer."""
def __init__(self, rows=1, cols=0, vgap=0, hgap=0):
"""Create a GridSizer instance.
rows and cols - the number of rows and columns in the grid; if
either is zero, it will be calculated as the number of
children in the sizer, allowing the sizer grow dynamically.
vgap and hgap - extra space between all cells, in pixels."""
pass
def CalcMin(self):
"""Calculate minimum size. Do not call directly."""
pass
def GetCols(self):
"""Return the number of columns in the grid."""
pass
def GetHGap(self):
"""Return the horizontal gap (in pixels) between cells."""
pass
def GetRows(self):
"""Return the number of rows in the grid."""
pass
def GetVGap(self):
"""Return the vertical gap (in pixels) between cells."""
pass
def RecalcSizes(self):
"""Recalculate sizes, then set the size of its children
(calling SetSize if child is a window). Do not call directly."""
pass
def SetCols(self, cols):
"""Set the number of columns in the grid."""
pass
def SetHGap(self, gap):
"""Set the horizontal gap (in pixels) between cells."""
pass
def SetRows(self, rows):
"""Sets the number of rows in the grid."""
pass
def SetVGap(self, gap):
"""Set the vertical gap (in pixels) between cells."""
pass
class FlexGridSizer(GridSizer):
"""A flex grid sizer lays out its children in a two-dimensional
table where all cells in one row have the same height and all
cells in one column have the same width, but all cells are not
necessarily the same height and width, as in the GridSizer."""
def __init__(self, rows=1, cols=0, vgap=0, hgap=0):
"""Create a GridSizer instance.
rows and cols - the number of rows and columns in the grid; if
either is zero, it will be calculated as the number of
children in the sizer, allowing the sizer grow dynamically.
vgap and hgap - extra space between all cells, in pixels."""
pass
def AddGrowableCol(self, idx):
"""Specify that column idx (starting from zero) should expand
if there is extra space available to the sizer."""
pass
def AddGrowableRow(self, idx):
"""Specify that row idx (starting from zero) should expand if
there is extra space available to the sizer."""
pass
def CalcMin(self):
"""Calculate minimum size. Do not call directly."""
pass
def RecalcSizes(self):
"""Recalculate sizes, then set the size of its children
(calling SetSize if child is a window). Do not call directly."""
pass
def RemoveGrowableCol(self, idx):
"""Specify that column idx is no longer growable."""
pass
def RemoveGrowableRow(self, idx):
"""Specify that row idx is no longer growable."""
pass
class NotebookSizer(Sizer):
"""NotebookSizer works with a notebook to determine the size of
the biggest page and report an adjusted minimal size to a more
toplevel sizer. Do not add children to a NotebookSizer."""
def __init__(self, nb):
"""Create a NotebookSizer instance for notebook."""
pass
def CalcMin(self):
"""Calculate minimum size. Do not call directly."""
pass
def GetNotebook(self):
"""Return the notebook associated with the sizer."""
pass
def RecalcSizes(self):
"""Recalculate size. Do not call directly."""
pass
class SizerItem(Object):
"""SizerItem class. Wrapper for items managed by a sizer."""
def __init__(self, this):
"""Create a SizerItem instance. You don't normally create one
directly."""
pass
def CalcMin(self):
"""Calculate minimum size. Do not call directly."""
pass
def DeleteWindows(self):
"""Recursively destroy windows associated with this SizerItem."""
pass
def GetBorder(self):
"""Return border width."""
pass
def GetFlag(self):
"""Return flag value."""
pass
def GetOption(self):
"""Return option value."""
pass
def GetPosition(self):
"""Return wx.Point instance representing position relative to
the client area."""
pass
def GetRatio(self):
"""Return a floating point aspect ratio (width/height). If
wx.SHAPED flag is used item will maintain ratio when resized."""
pass
def GetSize(self):
"""Return wx.Size instance with size."""
pass
def GetSizer(self):
"""If IsSizer() return the sizer; otherwise return None."""
pass
def GetUserData(self):
"""Return a wx.PyUserData object."""
pass
def GetWindow(self):
"""If IsWindow() return the window; otherwise return None."""
pass
def IsShown(self):
"""Return True if item is shown."""
pass
def IsSizer(self):
"""Return True if SizerItem represents a sizer."""
pass
def IsSpacer(self):
"""Return True if SizerItem represents a spacer."""
pass
def IsWindow(self):
"""Return True if SizerItem represents a window."""
pass
def SetBorder(self, border):
"""Set border width for item."""
pass
def SetDimension(self, pos, size):
"""Set position and size for item."""
pass
def SetFlag(self, flag):
"""Set flag for item."""
pass
def SetInitSize(self, x, y):
"""Set initial size of item."""
pass
def SetOption(self, option):
"""Set option for item."""
pass
def SetRatio(self, ratio):
"""Set a floating point aspect ratio (width/height). If
wx.SHAPED flag is used item will maintain ratio when resized."""
pass
def SetRatioSize(self, size):
"""Set a floating point aspect ratio (width/height). If
wx.SHAPED flag is used item will maintain ratio when resized."""
pass
def SetRatioWH(self, width, height):
"""Set a floating point aspect ratio (width/height). If
wx.SHAPED flag is used item will maintain ratio when resized."""
pass
def SetSizer(self, sizer):
"""Set sizer associated with SizerItem."""
pass
def SetWindow(self, window):
"""Set window associated with SizerItem."""
pass
def Show(self, show):
"""Is show is True, show item, otherwise hide item."""
pass

View File

@@ -18,7 +18,10 @@ import Parameters as wx
class TreeCtrl(Control):
""""""
"""A tree control presents information as a hierarchy, with items
that may be expanded to show further items. Items in a tree
control are referenced by wx.TreeItemId handles, which may be
tested for validity by calling TreeItemId.IsOk()."""
def AddRoot(self):
""""""
@@ -354,49 +357,47 @@ class TreeItemAttr:
class TreeItemData(Object):
""""""
"""TreeItemData is some (arbitrary) user class associated with
some item. The main advantage of having this class is that
TreeItemData objects are destroyed automatically by the tree and
the memory and any other resources associated with a tree item
will be automatically freed when it is deleted."""
def __init__(self, obj=wx.NULL):
"""Associate any Python object with tree item using
wxTreeItemData as container."""
pass
def GetData(self):
""""""
"""Return the Python object."""
pass
def GetId(self):
""""""
"""Return the item associated with this node."""
pass
def SetData(self):
""""""
def SetData(self, obj):
"""Associate Python object with tree item."""
pass
def SetId(self):
""""""
pass
def __init__(self):
""""""
def SetId(self, id):
"""Set the item associated with this node."""
pass
class TreeItemId:
""""""
"""Item in a TreeCtrl."""
## You wouldn't create these directly.
## def __init__(self):
## """"""
## pass
def IsOk(self):
""""""
"""Return True if item is valid."""
pass
def Ok(self):
""""""
"""Synonym for IsOk."""
pass
def __cmp__(self):
""""""
pass
def __del__(self):
""""""
pass
def __init__(self):
""""""
pass

Some files were not shown because too many files have changed in this diff Show More