]> git.saurik.com Git - wxWidgets.git/commitdiff
A couple little fixes for wxSTC
authorRobin Dunn <robin@alldunn.com>
Tue, 4 Sep 2001 23:44:17 +0000 (23:44 +0000)
committerRobin Dunn <robin@alldunn.com>
Tue, 4 Sep 2001 23:44:17 +0000 (23:44 +0000)
Updated to 0.6 of PyCrust

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11560 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

19 files changed:
wxPython/CHANGES.txt
wxPython/contrib/stc/stc_.cpp
wxPython/contrib/stc/stc_.py
wxPython/demo/Main.py
wxPython/demo/PyCrustWithFilling.py [new file with mode: 0644]
wxPython/demo/wxStyledTextCtrl_1.py
wxPython/setup.py
wxPython/src/__version__.py
wxPython/wxPython/lib/PyCrust/PyCrust.ico
wxPython/wxPython/lib/PyCrust/PyCrust.py
wxPython/wxPython/lib/PyCrust/PyFilling.py [new file with mode: 0644]
wxPython/wxPython/lib/PyCrust/PyShell.py [new file with mode: 0644]
wxPython/wxPython/lib/PyCrust/README.txt
wxPython/wxPython/lib/PyCrust/crust.py [new file with mode: 0644]
wxPython/wxPython/lib/PyCrust/filling.py [new file with mode: 0644]
wxPython/wxPython/lib/PyCrust/interpreter.py
wxPython/wxPython/lib/PyCrust/introspect.py
wxPython/wxPython/lib/PyCrust/shell.py
wxPython/wxPython/lib/PyCrust/version.py

index a6f0a558ff31fbaaef453e6a9734cf09875b6b5f..43ef79bba6663e2f0cb633aa8c37acea4d8b30fa 100644 (file)
@@ -9,7 +9,8 @@ EVT_DETAILED_HELP_RANGE, EVT_CONTEXT_MENU, wxHelpEvent,
 wxContextMenuEvent, wxContextHelp, wxContextHelpButton, wxTipWindow,
 and a demo to show them in action.
 
-Deprecated PyShell and PyShellWindow, added a snapshot of PyCrust.
+Deprecated PyShell and PyShellWindow, added a snapshot of PyCrust (see
+http://sourceforge.net/projects/pycrust/. )
 
 Added the new virtual list capabilities to wxListCtrl.
 
@@ -40,6 +41,8 @@ Added wxGenBitmapTextButton, TablePrint, etc. contribs from Lorne White.
 Added wxNativeFontInfo and wxFontMapper.
 
 
+
+
 2.3.1
 -----
 Added EVT_GRID_EDITOR_CREATED and wxGridEditorCreatedEvent so the user
index ebd8dec5b5222c3c71c11f7fb2306c3497258bdf..1ad28148806dfdbe41ea565009a599f09cc0c0db 100644 (file)
@@ -988,7 +988,7 @@ static PyObject *_wrap_wxStyledTextCtrl_GetCurLine(PyObject *self, PyObject *arg
     PyObject * _resultobj;
     wxString * _result;
     wxStyledTextCtrl * _arg0;
-    int * _arg1 = (int *) NULL;
+    int * _arg1;
     int  temp;
     PyObject * _argo0 = 0;
     char *_kwnames[] = { "self", NULL };
@@ -7532,8 +7532,8 @@ static PyObject *_wrap_wxStyledTextCtrl_GetModEventMask(PyObject *self, PyObject
     return _resultobj;
 }
 
-#define wxStyledTextCtrl_SetFocus(_swigobj,_swigarg0)  (_swigobj->SetFocus(_swigarg0))
-static PyObject *_wrap_wxStyledTextCtrl_SetFocus(PyObject *self, PyObject *args, PyObject *kwargs) {
+#define wxStyledTextCtrl_SetSTCFocus(_swigobj,_swigarg0)  (_swigobj->SetSTCFocus(_swigarg0))
+static PyObject *_wrap_wxStyledTextCtrl_SetSTCFocus(PyObject *self, PyObject *args, PyObject *kwargs) {
     PyObject * _resultobj;
     wxStyledTextCtrl * _arg0;
     bool  _arg1;
@@ -7542,19 +7542,19 @@ static PyObject *_wrap_wxStyledTextCtrl_SetFocus(PyObject *self, PyObject *args,
     char *_kwnames[] = { "self","focus", NULL };
 
     self = self;
-    if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxStyledTextCtrl_SetFocus",_kwnames,&_argo0,&tempbool1)) 
+    if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxStyledTextCtrl_SetSTCFocus",_kwnames,&_argo0,&tempbool1)) 
         return NULL;
     if (_argo0) {
         if (_argo0 == Py_None) { _arg0 = NULL; }
         else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxStyledTextCtrl_p")) {
-            PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_SetFocus. Expected _wxStyledTextCtrl_p.");
+            PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_SetSTCFocus. Expected _wxStyledTextCtrl_p.");
         return NULL;
         }
     }
     _arg1 = (bool ) tempbool1;
 {
     wxPy_BEGIN_ALLOW_THREADS;
-        wxStyledTextCtrl_SetFocus(_arg0,_arg1);
+        wxStyledTextCtrl_SetSTCFocus(_arg0,_arg1);
 
     wxPy_END_ALLOW_THREADS;
 }    Py_INCREF(Py_None);
@@ -7562,8 +7562,8 @@ static PyObject *_wrap_wxStyledTextCtrl_SetFocus(PyObject *self, PyObject *args,
     return _resultobj;
 }
 
-#define wxStyledTextCtrl_GetFocus(_swigobj)  (_swigobj->GetFocus())
-static PyObject *_wrap_wxStyledTextCtrl_GetFocus(PyObject *self, PyObject *args, PyObject *kwargs) {
+#define wxStyledTextCtrl_GetSTCFocus(_swigobj)  (_swigobj->GetSTCFocus())
+static PyObject *_wrap_wxStyledTextCtrl_GetSTCFocus(PyObject *self, PyObject *args, PyObject *kwargs) {
     PyObject * _resultobj;
     bool  _result;
     wxStyledTextCtrl * _arg0;
@@ -7571,18 +7571,18 @@ static PyObject *_wrap_wxStyledTextCtrl_GetFocus(PyObject *self, PyObject *args,
     char *_kwnames[] = { "self", NULL };
 
     self = self;
-    if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:wxStyledTextCtrl_GetFocus",_kwnames,&_argo0)) 
+    if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:wxStyledTextCtrl_GetSTCFocus",_kwnames,&_argo0)) 
         return NULL;
     if (_argo0) {
         if (_argo0 == Py_None) { _arg0 = NULL; }
         else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxStyledTextCtrl_p")) {
-            PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_GetFocus. Expected _wxStyledTextCtrl_p.");
+            PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_GetSTCFocus. Expected _wxStyledTextCtrl_p.");
         return NULL;
         }
     }
 {
     wxPy_BEGIN_ALLOW_THREADS;
-        _result = (bool )wxStyledTextCtrl_GetFocus(_arg0);
+        _result = (bool )wxStyledTextCtrl_GetSTCFocus(_arg0);
 
     wxPy_END_ALLOW_THREADS;
 }    _resultobj = Py_BuildValue("i",_result);
@@ -9869,8 +9869,8 @@ static PyMethodDef stc_cMethods[] = {
         { "wxStyledTextCtrl_SetMouseDownCaptures", (PyCFunction) _wrap_wxStyledTextCtrl_SetMouseDownCaptures, METH_VARARGS | METH_KEYWORDS },
         { "wxStyledTextCtrl_GetStatus", (PyCFunction) _wrap_wxStyledTextCtrl_GetStatus, METH_VARARGS | METH_KEYWORDS },
         { "wxStyledTextCtrl_SetStatus", (PyCFunction) _wrap_wxStyledTextCtrl_SetStatus, METH_VARARGS | METH_KEYWORDS },
-        { "wxStyledTextCtrl_GetFocus", (PyCFunction) _wrap_wxStyledTextCtrl_GetFocus, METH_VARARGS | METH_KEYWORDS },
-        { "wxStyledTextCtrl_SetFocus", (PyCFunction) _wrap_wxStyledTextCtrl_SetFocus, METH_VARARGS | METH_KEYWORDS },
+        { "wxStyledTextCtrl_GetSTCFocus", (PyCFunction) _wrap_wxStyledTextCtrl_GetSTCFocus, METH_VARARGS | METH_KEYWORDS },
+        { "wxStyledTextCtrl_SetSTCFocus", (PyCFunction) _wrap_wxStyledTextCtrl_SetSTCFocus, METH_VARARGS | METH_KEYWORDS },
         { "wxStyledTextCtrl_GetModEventMask", (PyCFunction) _wrap_wxStyledTextCtrl_GetModEventMask, METH_VARARGS | METH_KEYWORDS },
         { "wxStyledTextCtrl_ReleaseDocument", (PyCFunction) _wrap_wxStyledTextCtrl_ReleaseDocument, METH_VARARGS | METH_KEYWORDS },
         { "wxStyledTextCtrl_AddRefDocument", (PyCFunction) _wrap_wxStyledTextCtrl_AddRefDocument, METH_VARARGS | METH_KEYWORDS },
@@ -10150,12 +10150,14 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
     { "_wxChar","_char",0},
     { "_wxCommandEvent","_wxStyledTextEvent",SwigwxStyledTextEventTowxCommandEvent},
     { "_char","_wxChar",0},
+    { "_struct_wxNativeFontInfo","_wxNativeFontInfo",0},
     { "_EBool","_wxCoord",0},
     { "_EBool","_wxPrintQuality",0},
     { "_EBool","_signed_int",0},
     { "_EBool","_int",0},
     { "_EBool","_wxWindowID",0},
     { "_unsigned_long","_long",0},
+    { "_wxNativeFontInfo","_struct_wxNativeFontInfo",0},
     { "_signed_int","_wxCoord",0},
     { "_signed_int","_wxPrintQuality",0},
     { "_signed_int","_EBool",0},
index 079b8cc4fd97f3ef6d503c55b6540152ed04bb8f..83863a5c3bf1e85f29476a5cbe48dafa09f92f4e 100644 (file)
@@ -822,11 +822,11 @@ class wxStyledTextCtrlPtr(wxControlPtr):
     def GetModEventMask(self, *_args, **_kwargs):
         val = apply(stc_c.wxStyledTextCtrl_GetModEventMask,(self,) + _args, _kwargs)
         return val
-    def SetFocus(self, *_args, **_kwargs):
-        val = apply(stc_c.wxStyledTextCtrl_SetFocus,(self,) + _args, _kwargs)
+    def SetSTCFocus(self, *_args, **_kwargs):
+        val = apply(stc_c.wxStyledTextCtrl_SetSTCFocus,(self,) + _args, _kwargs)
         return val
-    def GetFocus(self, *_args, **_kwargs):
-        val = apply(stc_c.wxStyledTextCtrl_GetFocus,(self,) + _args, _kwargs)
+    def GetSTCFocus(self, *_args, **_kwargs):
+        val = apply(stc_c.wxStyledTextCtrl_GetSTCFocus,(self,) + _args, _kwargs)
         return val
     def SetStatus(self, *_args, **_kwargs):
         val = apply(stc_c.wxStyledTextCtrl_SetStatus,(self,) + _args, _kwargs)
index 74318bcd627877aafd88a6bf4d3f92e3b711302f..5eebb3513788902b349d5d24fe2e4120aff4273e 100644 (file)
@@ -24,6 +24,7 @@ import images
 _treeList = [
     ('New since last release', ['ContextHelp',
                                 'PyCrust',
+                                'PyCrustWithFilling',
                                 'VirtualListCtrl',
                                 'wxListCtrl',
                                 'TablePrint',
diff --git a/wxPython/demo/PyCrustWithFilling.py b/wxPython/demo/PyCrustWithFilling.py
new file mode 100644 (file)
index 0000000..78a200a
--- /dev/null
@@ -0,0 +1,20 @@
+
+from wxPython.wx import *
+from wxPython.lib.PyCrust import shell, version, filling
+
+
+#----------------------------------------------------------------------
+
+intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % version.VERSION
+
+def runTest(frame, nb, log):
+    win = wxSplitterWindow(nb, -1, size=(640, 480))
+    shellWin = shell.Shell(win, -1, introText=intro)
+    fillingWin = filling.Filling(win, -1, size=(640, 480),
+                                 ingredients=shellWin.interp.locals)
+    win.SplitHorizontally(shellWin, fillingWin)
+    return win
+
+#----------------------------------------------------------------------
+
+overview = filling.__doc__
index cf589e92f337f2eae5a1a61c9ea37e8025c53b98..76aba88b50cb9b6e72eca5ed589f533feaaee95f 100644 (file)
@@ -175,6 +175,8 @@ def runTest(frame, nb, log):
         print "GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104))
         print
         print "GetCurLine(): ", repr(ed.GetCurLine())
+        ed.GotoPos(5)
+        print "GetCurLine(): ", repr(ed.GetCurLine())
         print
         print "GetLine(1): ", repr(ed.GetLine(1))
         print
index ee2b3d47f9ef0f676754f1a8629e5abcee08941d..d9a0bb2e232d2f0808f25957942b4e67f8d8c673 100755 (executable)
@@ -13,7 +13,7 @@ from my_distutils import run_swig, contrib_copy_tree
 # flags and values that affect this script
 #----------------------------------------------------------------------
 
-VERSION          = "2.3.2b1"
+VERSION          = "2.3.2b2"
 DESCRIPTION      = "Cross platform GUI toolkit for Python"
 AUTHOR           = "Robin Dunn"
 AUTHOR_EMAIL     = "Robin Dunn <robin@alldunn.com>"
index eea883684f5736d1e139a2cf6f14d8f932fff6ee..f50900a0017bc0d658f9cd8bb729622b4ae9dfc9 100644 (file)
@@ -1 +1 @@
-ver = '2.3.2b1'
+ver = '2.3.2b2'
index bb29c8edd7e66d24e5acde41c632ebb805b87891..2075eec3978f1651c5dad964e71cab2e074089b1 100644 (file)
Binary files a/wxPython/wxPython/lib/PyCrust/PyCrust.ico and b/wxPython/wxPython/lib/PyCrust/PyCrust.ico differ
index 84edad7ca06ff1b3b9ae848600af62c6c735d570..d2281ce306115af88470c670f7c02523c75b2fd3 100644 (file)
@@ -1,6 +1,5 @@
 #!/usr/bin/env python
-"""PyCrust is a python shell application.
-"""
+"""PyCrust is a python shell and namespace browser application."""
 
 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
 __cvsid__ = "$Id$"
@@ -8,209 +7,32 @@ __date__ = "July 1, 2001"
 __version__ = "$Revision$"[11:-2]
 
 from wxPython.wx import *
+from crust import CrustFrame
 
-from version import VERSION
-from shell import Shell
-
-ID_AUTOCOMP = NewId()
-ID_AUTOCOMP_SHOW = NewId()
-ID_AUTOCOMP_INCLUDE_MAGIC = NewId()
-ID_AUTOCOMP_INCLUDE_SINGLE = NewId()
-ID_AUTOCOMP_INCLUDE_DOUBLE = NewId()
-ID_CALLTIPS = NewId()
-ID_CALLTIPS_SHOW = NewId()
-
-
-class Frame(wxFrame):
-    """Main window for the PyCrust application."""
-    def __init__(self, parent, id, title):
-        """Create the main frame object for the application."""
-        wxFrame.__init__(self, parent, id, title)
-        intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
-        self.CreateStatusBar()
-        self.SetStatusText(intro)
-        self.icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO)
-        self.SetIcon(self.icon)
-        self.createMenus()
-        # Create the shell, which will create a default interpreter.
-        locals = {'__app__': 'PyCrust Application'}
-        self.shell = Shell(parent=self, id=-1, introText=intro, locals=locals)
-        # Override the shell so that status messages go to the status bar.
-        self.shell.setStatusText = self.SetStatusText
-
-    def createMenus(self):
-        m = self.fileMenu = wxMenu()
-        m.AppendSeparator()
-        m.Append(wxID_EXIT, 'E&xit', 'Exit PyCrust')
-
-        m = self.editMenu = wxMenu()
-        m.Append(wxID_UNDO, '&Undo \tCtrl+Z', 'Undo the last action')
-        m.Append(wxID_REDO, '&Redo \tCtrl+Y', 'Redo the last undone action')
-        m.AppendSeparator()
-        m.Append(wxID_CUT, 'Cu&t \tCtrl+X', 'Cut the selection')
-        m.Append(wxID_COPY, '&Copy \tCtrl+C', 'Copy the selection')
-        m.Append(wxID_PASTE, '&Paste \tCtrl+V', 'Paste')
-        m.AppendSeparator()
-        m.Append(wxID_CLEAR, 'Cle&ar \tDel', 'Delete the selection')
-        m.Append(wxID_SELECTALL, 'Select A&ll \tCtrl+A', 'Select all text')
-
-        m = self.autocompMenu = wxMenu()
-        m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \
-                 'Show auto completion during dot syntax', checkable=1)
-        m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \
-                 'Include attributes visible to __getattr__ and __setattr__', checkable=1)
-        m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \
-                 'Include attibutes prefixed by a single underscore', checkable=1)
-        m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \
-                 'Include attibutes prefixed by a double underscore', checkable=1)
-
-        m = self.calltipsMenu = wxMenu()
-        m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \
-                 'Show call tips with argument specifications', checkable=1)
-
-        m = self.optionsMenu = wxMenu()
-        m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \
-                     'Auto Completion Options')
-        m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu, \
-                     'Call Tip Options')
-
-        m = self.helpMenu = wxMenu()
-        m.AppendSeparator()
-        m.Append(wxID_ABOUT, '&About...', 'About PyCrust')
-
-        b = self.menuBar = wxMenuBar()
-        b.Append(self.fileMenu, '&File')
-        b.Append(self.editMenu, '&Edit')
-        b.Append(self.optionsMenu, '&Options')
-        b.Append(self.helpMenu, '&Help')
-        self.SetMenuBar(b)
-
-        EVT_MENU(self, wxID_EXIT, self.OnExit)
-        EVT_MENU(self, wxID_UNDO, self.OnUndo)
-        EVT_MENU(self, wxID_REDO, self.OnRedo)
-        EVT_MENU(self, wxID_CUT, self.OnCut)
-        EVT_MENU(self, wxID_COPY, self.OnCopy)
-        EVT_MENU(self, wxID_PASTE, self.OnPaste)
-        EVT_MENU(self, wxID_CLEAR, self.OnClear)
-        EVT_MENU(self, wxID_SELECTALL, self.OnSelectAll)
-        EVT_MENU(self, wxID_ABOUT, self.OnAbout)
-        EVT_MENU(self, ID_AUTOCOMP_SHOW, self.OnAutoCompleteShow)
-        EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnAutoCompleteIncludeMagic)
-        EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnAutoCompleteIncludeSingle)
-        EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnAutoCompleteIncludeDouble)
-        EVT_MENU(self, ID_CALLTIPS_SHOW, self.OnCallTipsShow)
-
-        EVT_UPDATE_UI(self, wxID_UNDO, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, wxID_REDO, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, wxID_CUT, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, wxID_COPY, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, wxID_PASTE, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, wxID_CLEAR, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu)
-        EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu)
-
-    def OnExit(self, event):
-        self.Close(true)
-
-    def OnUndo(self, event):
-        self.shell.Undo()
-
-    def OnRedo(self, event):
-        self.shell.Redo()
-
-    def OnCut(self, event):
-        self.shell.Cut()
-
-    def OnCopy(self, event):
-        self.shell.Copy()
-
-    def OnPaste(self, event):
-        self.shell.Paste()
-
-    def OnClear(self, event):
-        self.shell.Clear()
-
-    def OnSelectAll(self, event):
-        self.shell.SelectAll()
-
-    def OnAbout(self, event):
-        """Display an About PyCrust window."""
-        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' % self.shell.interp.revision
-        dialog = wxMessageDialog(self, text, title, wxOK | wxICON_INFORMATION)
-        dialog.ShowModal()
-        dialog.Destroy()
-
-    def OnAutoCompleteShow(self, event):
-        self.shell.autoComplete = event.IsChecked()
-
-    def OnAutoCompleteIncludeMagic(self, event):
-        self.shell.autoCompleteIncludeMagic = event.IsChecked()
-
-    def OnAutoCompleteIncludeSingle(self, event):
-        self.shell.autoCompleteIncludeSingle = event.IsChecked()
-
-    def OnAutoCompleteIncludeDouble(self, event):
-        self.shell.autoCompleteIncludeDouble = event.IsChecked()
-
-    def OnCallTipsShow(self, event):
-        self.shell.autoCallTip = event.IsChecked()
-
-    def OnUpdateMenu(self, event):
-        """Update menu items based on current status."""
-        id = event.GetId()
-        if id == wxID_UNDO:
-            event.Enable(self.shell.CanUndo())
-        elif id == wxID_REDO:
-            event.Enable(self.shell.CanRedo())
-        elif id == wxID_CUT:
-            event.Enable(self.shell.CanCut())
-        elif id == wxID_COPY:
-            event.Enable(self.shell.CanCopy())
-        elif id == wxID_PASTE:
-            event.Enable(self.shell.CanPaste())
-        elif id == wxID_CLEAR:
-            event.Enable(self.shell.CanCut())
-        elif id == ID_AUTOCOMP_SHOW:
-            event.Check(self.shell.autoComplete)
-        elif id == ID_AUTOCOMP_INCLUDE_MAGIC:
-            event.Check(self.shell.autoCompleteIncludeMagic)
-        elif id == ID_AUTOCOMP_INCLUDE_SINGLE:
-            event.Check(self.shell.autoCompleteIncludeSingle)
-        elif id == ID_AUTOCOMP_INCLUDE_DOUBLE:
-            event.Check(self.shell.autoCompleteIncludeDouble)
-        elif id == ID_CALLTIPS_SHOW:
-            event.Check(self.shell.autoCallTip)
-            
 
 class App(wxApp):
+    """PyCrust standalone application."""
+    
     def OnInit(self):
-        parent = None
-        id = -1
-        title = 'PyCrust'
-        self.frame = Frame(parent, id, title)
-        self.frame.Show(true)
-        self.SetTopWindow(self.frame)
+        locals = {'__app__': 'PyCrust Standalone Application'}
+        self.crustFrame = CrustFrame(locals=locals)
+        self.crustFrame.Show(true)
+        # Set focus to the shell editor.
+        self.crustFrame.crust.shell.SetFocus()
+        self.SetTopWindow(self.crustFrame)
+        # Add the application object to the sys module's namespace.
+        # This allows a shell user to do:
+        # >>> import sys
+        # >>> sys.application.whatever
+        import sys
+        sys.application = self
         return true
 
 
 def main():
-    import sys
     application = App(0)
-    # Add the application object to the sys module's namespace.
-    # This allows a shell user to do:
-    # >>> import sys
-    # >>> sys.application.whatever
-    sys.application = application
     application.MainLoop()
 
 if __name__ == '__main__':
     main()
+
diff --git a/wxPython/wxPython/lib/PyCrust/PyFilling.py b/wxPython/wxPython/lib/PyCrust/PyFilling.py
new file mode 100644 (file)
index 0000000..bb2c72b
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+"""PyFilling is a python namespace inspection application."""
+
+__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
+__cvsid__ = "$Id$"
+__date__ = "August 21, 2001"
+__version__ = "$Revision$"[11:-2]
+
+# We use this object to get more introspection when run standalone.
+application = 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
+
+
+def main():
+    """Create and run the application."""
+    global application
+    application = filling.App(0)
+    root = application.fillingFrame.filling.fillingTree.root
+    application.fillingFrame.filling.fillingTree.Expand(root)
+    application.MainLoop()
+
+
+if __name__ == '__main__':
+    main()
+
diff --git a/wxPython/wxPython/lib/PyCrust/PyShell.py b/wxPython/wxPython/lib/PyCrust/PyShell.py
new file mode 100644 (file)
index 0000000..0fea2d5
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+"""PyShell is a python shell application."""
+
+__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
+__cvsid__ = "$Id$"
+__date__ = "July 1, 2001"
+__version__ = "$Revision$"[11:-2]
+
+from wxPython.wx import *
+from shell import ShellFrame
+
+
+class App(wxApp):
+    """PyShell standalone application."""
+    
+    def OnInit(self):
+        locals = {'__app__': 'PyShell Standalone Application'}
+        self.shellFrame = ShellFrame(locals=locals)
+        self.shellFrame.Show(true)
+        self.SetTopWindow(self.shellFrame)
+        # Add the application object to the sys module's namespace.
+        # This allows a shell user to do:
+        # >>> import sys
+        # >>> sys.application.whatever
+        import sys
+        sys.application = self
+        return true
+
+
+def main():
+    application = App(0)
+    application.MainLoop()
+
+if __name__ == '__main__':
+    main()
+
index 73ad07bc2b2e21c143fd5dc57bc19aee2b4ef298..df1431c41ec0f0bfafc4765d1b8e847af38a5628 100644 (file)
@@ -4,40 +4,63 @@ Half-baked by Patrick K. O'Brien (pobrien@orbtech.com)
 
 What is PyCrust?
 ----------------
+PyCrust is an interactive Python environment written in Python.
+PyCrust components can run standalone or be integrated into other
+development environments and/or other Python applications.
 
-PyCrust is is an interactive Python Shell written in Python.
-PyCrust can be run standalone or integrated into other development
-environments or other Python applications.
+PyCrust comes with an interactive Python shell (PyShell), an 
+interactive namespace/object tree control (PyFilling) and an 
+integrated, split-window combination of the two (PyCrust).
 
 
-Where can I get the latest files and join the mailing lists?
-------------------------------------------------------------
+What is PyCrust good for?
+-------------------------
+Have you ever tried to bake a pie without one? Well, you
+shouldn't build a Python program without a PyCrust either.
+
 
-Latest PyCrust releases:
+Where can I get the latest release of PyCrust?
+------------------------------------------------------------
+The latest PyCrust releases are available at:
 http://sourceforge.net/project/showfiles.php?group_id=31263
 
-PyCrust home page:
-http://pycrust.sourceforge.net/
 
-SourceForge summary page:
+What else do I need to use PyCrust?
+-----------------------------------
+PyCrust requires Python 2.1 or later, and wxPython 2.3.1 or later.
+PyCrust uses wxPython and the Scintilla wrapper (wxStyledTextCtrl).
+Python is available at http://www.python.org/.
+wxPython is available at http://www.wxpython.org/.
+
+
+Where is the PyCrust project hosted?
+------------------------------------
+At SourceForge, of course. The SourceForge summary page:
 http://sourceforge.net/projects/pycrust/
 
-PyCrust Mailing lists:
+
+Does PyCrust have a mailing list full of wonderful people?
+----------------------------------------------------------
+As a matter of fact, we do. Join the PyCrust mailing lists at:
 http://sourceforge.net/mail/?group_id=31263
 
 
-What else do I need to use PyCrust?
------------------------------------
+I found a bug in PyCrust, what do I do with it?
+-----------------------------------------------
+You can send it to me at pobrien@orbtech.com, or, preferably,
+submit a bug report on our bug tracker at SourceForge:
+http://sourceforge.net/tracker/?group_id=31263
 
-PyCrust requires Python 2.1 or later, and wxPython 2.3.1 or later.
-PyCrust uses wxPython and the Scintilla wrapper class (wxStyledTextCtrl).
-Python is available at http://www.python.org/.
-wxPython is available at http://www.wxpython.org/.
+
+I want a new feature added to PyCrust. Will you do it?
+------------------------------------------------------
+Flattery and money will get you anything. Short of that, you
+can try posting a request on our feature tracker at SourceForge:
+http://sourceforge.net/tracker/?group_id=31263
 
 
 What is the CVS information for this README file?
 -------------------------------------------------
-
 $Date$
 $Revision$
 $Id$
diff --git a/wxPython/wxPython/lib/PyCrust/crust.py b/wxPython/wxPython/lib/PyCrust/crust.py
new file mode 100644 (file)
index 0000000..d45941a
--- /dev/null
@@ -0,0 +1,67 @@
+"""PyCrust Crust combines the shell and filling into one control."""
+
+__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
+__cvsid__ = "$Id$"
+__date__ = "July 1, 2001"
+__version__ = "$Revision$"[11:-2]
+
+from wxPython.wx import *
+from shell import Shell
+from filling import Filling
+from version import VERSION
+
+
+class Crust(wxSplitterWindow):
+    """PyCrust Crust based on wxSplitterWindow."""
+    
+    name = 'PyCrust Crust'
+    revision = __version__
+    
+    def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
+                 size=wxDefaultSize, style=wxSP_3D, name='Crust Window', \
+                 ingredients=None, rootLabel=None, intro='', locals=None, \
+                 InterpClass=None, *args, **kwds):
+        """Create a PyCrust Crust instance."""
+        wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
+        self.shell = Shell(parent=self, introText=intro, \
+                           locals=locals, InterpClass=InterpClass, \
+                           *args, **kwds)
+        self.filling = Filling(parent=self, \
+                               ingredients=self.shell.interp.locals, \
+                               rootLabel=rootLabel)
+        """Add 'filling' to the interpreter's locals."""
+        self.shell.interp.locals['filling'] = self.filling
+        self.SplitHorizontally(self.shell, self.filling, 300)
+        # Set focus to the shell editor. Doesn't always work as intended.
+        self.shell.SetFocus()
+
+
+class CrustFrame(wxFrame):
+    """Frame containing all the PyCrust components."""
+    
+    name = 'PyCrust Frame'
+    revision = __version__
+    
+    def __init__(self, parent=None, id=-1, title='PyCrust', \
+                 ingredients=None, rootLabel=None, locals=None, \
+                 InterpClass=None, *args, **kwds):
+        """Create a PyCrust CrustFrame instance."""
+        wxFrame.__init__(self, parent, id, title)
+        intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
+        self.CreateStatusBar()
+        self.SetStatusText(intro)
+        if wxPlatform == '__WXMSW__':
+            icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO)
+            self.SetIcon(icon)
+        self.crust = Crust(parent=self, intro=intro, \
+                           ingredients=ingredients, \
+                           rootLabel=rootLabel, locals=locals, \
+                           InterpClass=InterpClass, *args, **kwds)
+        # Override the filling so that status messages go to the status bar.
+        self.crust.filling.fillingTree.setStatusText = self.SetStatusText
+        # Override the shell so that status messages go to the status bar.
+        self.crust.shell.setStatusText = self.SetStatusText
+        # Set focus to the shell editor. Doesn't always work as intended.
+        self.crust.shell.SetFocus()
+
+
diff --git a/wxPython/wxPython/lib/PyCrust/filling.py b/wxPython/wxPython/lib/PyCrust/filling.py
new file mode 100644 (file)
index 0000000..ef3292e
--- /dev/null
@@ -0,0 +1,292 @@
+"""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$"
+__date__ = "August 21, 2001"
+__version__ = "$Revision$"[11:-2]
+
+from wxPython.wx import *
+from wxPython.stc import *
+from version import VERSION
+import inspect
+import introspect
+import keyword
+import sys
+import types
+
+
+class FillingTree(wxTreeCtrl):
+    """PyCrust FillingTree based on wxTreeCtrl."""
+    
+    name = 'PyCrust Filling Tree'
+    revision = __version__
+
+    def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
+                 size=wxDefaultSize, style=wxTR_HAS_BUTTONS, \
+                 ingredients=None, rootLabel=None):
+        """Create a PyCrust FillingTree instance."""
+        wxTreeCtrl.__init__(self, parent, id, pos, size)
+        if not ingredients:
+            import __main__
+            ingredients = __main__
+        if not rootLabel: rootLabel = 'Ingredients'
+        rootdata = wxTreeItemData(ingredients)
+        self.root = self.AddRoot(rootLabel, -1, -1, rootdata)
+        self.SetItemHasChildren(self.root, self.hasChildren(self.root))
+        EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
+        EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
+        EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
+
+    def hasChildren(self, object):
+        """Return true if object has children."""
+        if self.getChildren(object):
+            return true
+        else:
+            return false
+
+    def getChildren(self, object):
+        """Return a dictionary with the attributes or contents of object."""
+        dict = {}
+        objtype = type(object)
+        if objtype is types.DictType:
+            dict = object
+        elif objtype in (types.InstanceType, types.ModuleType):
+            for key in introspect.getAttributeNames(object):
+                # 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:
+                    dict[key] = getattr(object, key)
+                except:
+                    pass
+        return dict
+
+    def OnItemExpanding(self, event):
+        selection = event.GetItem()
+        if self.IsExpanded(selection):
+            return
+        object = self.GetPyData(selection)
+        children = self.getChildren(object)
+        if not children:
+            return
+        list = children.keys()
+        list.sort()
+        for item in list:
+            itemtext = str(item)
+            # Show string dictionary items with single quotes, except for
+            # the first level of items, which represent the local namespace.
+            if type(object) is types.DictType \
+            and type(item) is types.StringType \
+            and selection != self.root:
+                itemtext = repr(item)
+            child = self.AppendItem(selection, itemtext, -1, -1, \
+                                    wxTreeItemData(children[item]))
+            self.SetItemHasChildren(child, self.hasChildren(children[item]))
+
+    def OnItemCollapsed(self, event):
+        """Remove all children from the item."""
+        item = event.GetItem()
+        self.DeleteChildren(item)
+
+    def OnSelChanged(self, event):
+        item = event.GetItem()
+        if item == self.root:
+            self.setText('')
+            return
+        object = self.GetPyData(item)
+        text = ''
+        text += self.getFullName(item)
+        text += '\n\nType: ' + str(type(object))[7:-2]
+        value = str(object)
+        if type(object) is types.StringType:
+            value = repr(value)
+        text += '\n\nValue: ' + value
+        if type(object) is types.InstanceType:
+            try:
+                text += '\n\nClass Definition:\n\n' + \
+                        inspect.getsource(object.__class__)
+            except:
+                try:
+                    text += '\n\n"""' + inspect.getdoc(object).strip() + '"""'
+                except:
+                    pass
+        else:
+            try:
+                text += '\n\nSource Code:\n\n' + \
+                        inspect.getsource(object)
+            except:
+                try:
+                    text += '\n\n"""' + inspect.getdoc(object).strip() + '"""'
+                except:
+                    pass
+        self.setText(text)
+
+    def getFullName(self, item, partial=''):
+        """Return a syntactically proper name for item."""
+        parent = self.GetItemParent(item)
+        parentobject = self.GetPyData(parent)
+        name = self.GetItemText(item)
+        # Apply dictionary syntax to dictionary items, except the root
+        # and first level children.
+        if item != self.root and parent != self.root \
+        and type(parentobject) is types.DictType:
+            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.
+        if item != self.root and parent != self.root:
+            name = self.getFullName(parent, partial=name)
+        return name
+
+    def setText(self, text):
+        """Display information about the current selection."""
+
+        # This method will most 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 most likely be replaced by the enclosing app
+        # to do something more interesting, like write to a status bar.
+        print text
+
+
+if wxPlatform == '__WXMSW__':
+    faces = { 'times'  : 'Times New Roman',
+              'mono'   : 'Courier New',
+              'helv'   : 'Lucida Console',
+              'lucida' : 'Lucida Console',
+              'other'  : 'Comic Sans MS',
+              'size'   : 8,
+              'lnsize' : 7,
+              'backcol': '#FFFFFF',
+            }
+else:  # GTK
+    faces = { 'times'  : 'Times',
+              'mono'   : 'Courier',
+              'helv'   : 'Helvetica',
+              'other'  : 'new century schoolbook',
+              'size'   : 12,
+              'lnsize' : 10,
+              'backcol': '#FFFFFF',
+            }
+
+
+class FillingText(wxStyledTextCtrl):
+    """PyCrust FillingText based on wxStyledTextCtrl."""
+    
+    name = 'PyCrust Filling Text'
+    revision = __version__
+
+    def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
+                 size=wxDefaultSize, style=wxCLIP_CHILDREN):
+        """Create a PyCrust FillingText instance."""
+        wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
+        # Configure various defaults and user preferences.
+        self.config()
+
+    def config(self):
+        """Configure shell based on user preferences."""
+        self.SetMarginWidth(1, 0)
+        
+        self.SetLexer(wxSTC_LEX_PYTHON)
+        self.SetKeyWords(0, ' '.join(keyword.kwlist))
+
+        self.setStyles(faces)
+        self.SetViewWhiteSpace(0)
+        self.SetTabWidth(4)
+        self.SetUseTabs(0)
+
+    def setStyles(self, faces):
+        """Configure font size, typeface and color for lexer."""
+        
+        # Default style
+        self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
+
+        self.StyleClearAll()
+
+        # Built in styles
+        self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
+        self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
+        self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88")
+        self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88")
+
+        # Python styles
+        self.StyleSetSpec(wxSTC_P_DEFAULT, "face:%(mono)s" % faces)
+        self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces)
+        self.StyleSetSpec(wxSTC_P_NUMBER, "")
+        self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces)
+        self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces)
+        self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold")
+        self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000")
+        self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8")
+        self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold")
+        self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold")
+        self.StyleSetSpec(wxSTC_P_OPERATOR, "")
+        self.StyleSetSpec(wxSTC_P_IDENTIFIER, "")
+        self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F")
+        self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
+
+
+class Filling(wxSplitterWindow):
+    """PyCrust Filling based on wxSplitterWindow."""
+    
+    name = 'PyCrust Filling'
+    revision = __version__
+    
+    def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
+                 size=wxDefaultSize, style=wxSP_3D, name='Filling Window', \
+                 ingredients=None, rootLabel=None):
+        """Create a PyCrust Filling instance."""
+        wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
+        self.fillingTree = FillingTree(parent=self, ingredients=ingredients, \
+                                       rootLabel=rootLabel)
+        self.fillingText = FillingText(parent=self)
+        self.SplitVertically(self.fillingTree, self.fillingText, 200)
+        # Override the filling so that descriptions go to fillingText.
+        self.fillingTree.setText = self.fillingText.SetText
+        # Select the root item.
+        self.fillingTree.SelectItem(self.fillingTree.root)
+
+
+class FillingFrame(wxFrame):
+    """Frame containing the PyCrust filling, or namespace tree component."""
+    
+    name = 'PyCrust Filling Frame'
+    revision = __version__
+    
+    def __init__(self, parent=None, id=-1, title='PyFilling', \
+                 pos=wxDefaultPosition, size=wxDefaultSize, \
+                 style=wxDEFAULT_FRAME_STYLE, ingredients=None, \
+                 rootLabel=None):
+        """Create a PyCrust FillingFrame instance."""
+        wxFrame.__init__(self, parent, id, title, pos, size, style)
+        intro = 'Welcome To PyFilling - The Tastiest Namespace Inspector'
+        self.CreateStatusBar()
+        self.SetStatusText(intro)
+        if wxPlatform == '__WXMSW__':
+            icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO)
+            self.SetIcon(icon)
+        self.filling = Filling(parent=self, ingredients=ingredients, \
+                               rootLabel=rootLabel)
+        # Override the filling so that status messages go to the status bar.
+        self.filling.fillingTree.setStatusText = self.SetStatusText
+
+
+class App(wxApp):
+    """PyFilling standalone application."""
+    
+    def OnInit(self):
+        self.fillingFrame = FillingFrame()
+        self.fillingFrame.Show(true)
+        self.SetTopWindow(self.fillingFrame)
+        return true
+
+
index 5f12c01f3403be4ee30cb73a038dbc23ae703c88..48e9056464e0a044dc97f11f7ca77ad55d5d881d 100644 (file)
@@ -1,5 +1,4 @@
-"""PyCrust Interpreter executes Python commands.
-"""
+"""PyCrust Interpreter executes Python commands."""
 
 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
 __cvsid__ = "$Id$"
@@ -8,15 +7,16 @@ __version__ = "$Revision$"[11:-2]
 
 import os
 import sys
-
 from code import InteractiveInterpreter
 import introspect
 
 
 class Interpreter(InteractiveInterpreter):
     """PyCrust Interpreter based on code.InteractiveInterpreter."""
+    
     revision = __version__
-    def __init__(self, locals=None, rawin=None,
+    
+    def __init__(self, locals=None, rawin=None, \
                  stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
         """Create an interactive interpreter object."""
         InteractiveInterpreter.__init__(self, locals=locals)
@@ -28,8 +28,8 @@ class Interpreter(InteractiveInterpreter):
             __builtin__.raw_input = rawin
             del __builtin__
         copyright = 'Type "copyright", "credits" or "license" for more information.'
-        self.introText = 'Python %s on %s\n%s' % \
-                         (sys.version, sys.platform, copyright)
+        self.introText = 'Python %s on %s%s%s' % \
+                         (sys.version, sys.platform, os.linesep, copyright)
         try:
             sys.ps1
         except AttributeError:
@@ -81,3 +81,15 @@ class Interpreter(InteractiveInterpreter):
         The call tip information will be based on the locals namespace."""
         return introspect.getCallTip(command, self.locals, *args, **kwds)
 
+
+class InterpreterAlaCarte(Interpreter):
+    """PyCrustAlaCarte Demo Interpreter."""
+    
+    def __init__(self, locals, rawin, stdin, stdout, stderr, \
+                 ps1='main prompt', ps2='continuation prompt'):
+        """Create an interactive interpreter object."""
+        Interpreter.__init__(self, locals=locals, rawin=rawin, \
+                             stdin=stdin, stdout=stdout, stderr=stderr)
+        sys.ps1 = ps1
+        sys.ps2 = ps2
+
index 8cf6ae85051e69d96b68bd9f9e90392786cb8579..4f3abd1477ea638bb201981d8390b6fcfea2b817 100644 (file)
@@ -19,27 +19,28 @@ def getAutoCompleteList(command='', locals=None, includeMagic=1, \
     root = getRoot(command, terminator='.')
     try:
         object = eval(root, locals)
-        attributes = getAttributeNames(object)
-        if includeMagic:
-            try: attributes += object._getAttributeNames()
-            except: pass
-        if not includeSingle:
-            attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes)
-        if not includeDouble:
-            attributes = filter(lambda item: item[:2]!='__', attributes)
+        attributes = getAttributeNames(object, includeMagic, \
+                                       includeSingle, includeDouble)
         return attributes
     except:
         return []
     
-def getAttributeNames(object):
+def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1):
     """Return list of unique attributes, including inherited, for an object."""
     attributes = []
     dict = {}
-    # Remove duplicates from the attribute list.
+    if includeMagic:
+        try: attributes += object._getAttributeNames()
+        except: pass
+    # Get all attribute names, removing duplicates from the attribute list.
     for item in getAllAttributeNames(object):
         dict[item] = None
     attributes += dict.keys()
     attributes.sort()
+    if not includeSingle:
+        attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes)
+    if not includeDouble:
+        attributes = filter(lambda item: item[:2]!='__', attributes)
     return attributes
 
 def getAllAttributeNames(object):
@@ -137,7 +138,9 @@ def getRoot(command, terminator=None):
         pieces = command.split(terminator)
         if len(pieces) > 1:
             command = terminator.join(pieces[:-1])
-    if command in ("''", '""', '""""""', '[]', '()', '{}'):
+    if len(command) == 0:
+        root = ''
+    elif command in ("''", '""', '""""""', '[]', '()', '{}'):
         # Let empty type delimiter pairs go through.
         root = command
     else:
index 0c71206bd24af8624e1a1123d3549d7e024e81e9..e14e6c6d4e47b9d3a90bd8a6b134f0ea46f40dc3 100644 (file)
@@ -1,7 +1,7 @@
-"""PyCrust Shell is the gui text control in which a user interacts and types
-in commands to be sent to the interpreter. This particular shell is based on
-wxPython's wxStyledTextCtrl.
-"""
+"""The PyCrust Shell is an interactive text control in which a user types in
+commands to be sent to the interpreter. This particular shell is based on
+wxPython's wxStyledTextCtrl. The latest files are always available at the
+SourceForge project page at http://sourceforge.net/projects/pycrust/."""
 
 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
 __cvsid__ = "$Id$"
@@ -10,13 +10,12 @@ __version__ = "$Revision$"[11:-2]
 
 from wxPython.wx import *
 from wxPython.stc import *
-
 import keyword
 import os
 import sys
-
 from version import VERSION
 
+
 if wxPlatform == '__WXMSW__':
     faces = { 'times'  : 'Times New Roman',
               'mono'   : 'Courier New',
@@ -32,79 +31,85 @@ else:  # GTK
               'mono'   : 'Courier',
               'helv'   : 'Helvetica',
               'other'  : 'new century schoolbook',
-              'size'   : 9,
-              'lnsize' : 8,
+              'size'   : 12,
+              'lnsize' : 10,
               'backcol': '#FFFFFF',
             }
 
 
 class Shell(wxStyledTextCtrl):
     """PyCrust Shell based on wxStyledTextCtrl."""
+    
     name = 'PyCrust Shell'
     revision = __version__
-    def __init__(self, parent, id, introText='', locals=None, interp=None):
-        """Create a PyCrust Shell object."""
-        wxStyledTextCtrl.__init__(self, parent, id, style=wxCLIP_CHILDREN)
-        self.introText = introText
+    
+    def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
+                 size=wxDefaultSize, style=wxCLIP_CHILDREN, introText='', \
+                 locals=None, InterpClass=None, *args, **kwds):
+        """Create a PyCrust Shell instance."""
+        wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
+        # Import a default interpreter class if one isn't provided.
+        if InterpClass == None:
+            from interpreter import Interpreter
+        else:
+            Interpreter = InterpClass
+        # Create default locals so we have something interesting.
+        shellLocals = {'__name__': 'PyShell', 
+                       '__doc__': 'PyShell, The PyCrust Python Shell.',
+                       '__version__': VERSION,
+                      }
+        # Add the dictionary that was passed in.
+        if locals:
+            shellLocals.update(locals)
+        from pseudo import PseudoFileIn, PseudoFileOut, PseudoFileErr
+        self.interp = Interpreter(locals=shellLocals, \
+                                  rawin=self.readRaw, \
+                                  stdin=PseudoFileIn(self.readIn), \
+                                  stdout=PseudoFileOut(self.writeOut), \
+                                  stderr=PseudoFileErr(self.writeErr), \
+                                  *args, **kwds)
         # Keep track of the most recent prompt starting and ending positions.
         self.promptPos = [0, 0]
         # Keep track of multi-line commands.
         self.more = 0
+        # Create the command history.  Commands are added into the front of
+        # the list (ie. at index 0) as they are entered.  self.historyPos is
+        # the current position in the history; it gets incremented as you
+        # retrieve the previous command, decremented as you retrieve the next,
+        # and reset when you hit Enter. self.historyPos == -1 means you're on
+        # the current command, not in the history. self.tempCommand is
+        # storage space for whatever was on the last line when you first hit
+        # "Retrieve-Previous", so that the final "Retrieve-Next" will restore
+        # whatever was originally there.  self.lastCommandRecalled remembers
+        # the index of the last command to be recalled from the history, so
+        # you can repeat a group of commands by going up-up-up-enter to find
+        # the first one in the group then down-enter-down-enter to recall each
+        # subsequent command.  Also useful for multiline commands, in lieu of
+        # a proper implementation of those.
+        self.history = []
+        self.historyPos = -1
+        self.tempCommand = ''
+        self.lastCommandRecalled = -1
         # Assign handlers for keyboard events.
         EVT_KEY_DOWN(self, self.OnKeyDown)
         EVT_CHAR(self, self.OnChar)
-        # Create a default interpreter if one isn't provided.
-        if interp == None:
-            from interpreter import Interpreter
-            from pseudo import PseudoFileIn, PseudoFileOut, PseudoFileErr
-            self.stdin = PseudoFileIn(self.readIn)
-            self.stdout = PseudoFileOut(self.writeOut)
-            self.stderr = PseudoFileErr(self.writeErr)
-            # Override the default locals so we have something interesting.
-            self.locals = {'__name__': 'PyCrust', 
-                           '__doc__': 'PyCrust, The Python Shell.',
-                           '__version__': VERSION,
-                          }
-            # Add the dictionary that was passed in.
-            if locals:
-                self.locals.update(locals)
-            self.interp = Interpreter(locals=self.locals, 
-                                      rawin=self.readRaw,
-                                      stdin=self.stdin, 
-                                      stdout=self.stdout, 
-                                      stderr=self.stderr)
-        else:
-            self.interp = interp
-
         # Configure various defaults and user preferences.
         self.config()
-
-        try:
-            self.showIntro(self.introText)
-        except:
-            pass
-
-        try:
-            self.setBuiltinKeywords()
-        except:
-            pass
-        
-        try:
-            self.setLocalShell()
-        except:
-            pass
-        
+        # Display the introductory banner information.
+        try: self.showIntro(introText)
+        except: pass
+        # Assign some pseudo keywords to the interpreter's namespace.
+        try: self.setBuiltinKeywords()
+        except: pass
+        # Add 'shell' to the interpreter's local namespace.
+        try: self.setLocalShell()
+        except: pass
         # Do this last so the user has complete control over their
         # environment. They can override anything they want.
-        try:
-            self.execStartupScript(self.interp.startupScript)
-        except:
-            pass
+        try: self.execStartupScript(self.interp.startupScript)
+        except: pass
             
     def destroy(self):
-        del self.stdin
-        del self.stdout
-        del self.stderr
         del self.interp
         
     def config(self):
@@ -133,7 +138,7 @@ class Shell(wxStyledTextCtrl):
     def showIntro(self, text=''):
         """Display introductory text in the shell."""
         if text:
-            if text[-1] != '\n': text += '\n'
+            if not text.endswith(os.linesep): text += os.linesep
             self.write(text)
         try:
             self.write(self.interp.introText)
@@ -148,10 +153,15 @@ class Shell(wxStyledTextCtrl):
         In this case what we want is to call our self.quit() method.
         The user can type "close", "exit" or "quit" without the final parens.
         """
+## POB: This is having some weird side-effects so I'm taking it out.
+##        import __builtin__
+##        from pseudo import PseudoKeyword
+##        __builtin__.close = __builtin__.exit = __builtin__.quit = \
+##            PseudoKeyword(self.quit)
         import __builtin__
         from pseudo import PseudoKeyword
         __builtin__.close = __builtin__.exit = __builtin__.quit = \
-            PseudoKeyword(self.quit)
+            'Click on the close button to leave the application.'
 
     def quit(self):
         """Quit the application."""
@@ -211,14 +221,86 @@ class Shell(wxStyledTextCtrl):
         """Key down event handler.
         
         The main goal here is to not allow modifications to previous 
-        lines of text.
-        """
+        lines of text."""
         key = event.KeyCode()
         currpos = self.GetCurrentPos()
         stoppos = self.promptPos[1]
         # If the auto-complete window is up let it do its thing.
         if self.AutoCompActive():
             event.Skip()
+        # Control+UpArrow steps up through the history.
+        elif key == WXK_UP and event.ControlDown() \
+        and self.historyPos < len(self.history) - 1:
+            # Move to the end of the buffer.
+            endpos = self.GetTextLength()
+            self.SetCurrentPos(endpos)
+            # The first Control+Up stores the current command;
+            # Control+Down brings it back.
+            if self.historyPos == -1:
+                self.tempCommand = self.getCommand()
+            # Now replace the current line with the next one from the history.
+            self.historyPos = self.historyPos + 1
+            self.SetSelection(stoppos, endpos)
+            self.ReplaceSelection(self.history[self.historyPos])
+        # Control+DownArrow steps down through the history.
+        elif key == WXK_DOWN and event.ControlDown():
+            # Move to the end of the buffer.
+            endpos = self.GetTextLength()
+            self.SetCurrentPos(endpos)
+            # Are we at the bottom end of the history?
+            if self.historyPos == -1:
+                # Do we have a lastCommandRecalled stored?
+                if self.lastCommandRecalled >= 0:
+                    # Replace the current line with the command after the
+                    # last-recalled command (you'd think there should be a +1
+                    # here but there isn't because the history was shuffled up
+                    # by 1 after the previous command was recalled).
+                    self.SetSelection(stoppos, endpos)
+                    self.ReplaceSelection(self.history[self.lastCommandRecalled])
+                    # We've now warped into middle of the history.
+                    self.historyPos = self.lastCommandRecalled
+                    self.lastCommandRecalled = -1
+            else:
+                # Fetch either the previous line from the history, or the saved
+                # command if we're back at the start.
+                self.historyPos = self.historyPos - 1
+                if self.historyPos == -1:
+                    newText = self.tempCommand
+                else:
+                    newText = self.history[self.historyPos]
+                # Replace the current line with the new text.
+                self.SetSelection(stoppos, endpos)
+                self.ReplaceSelection(newText)
+        # F8 on the last line does a search up the history for the text in
+        # front of the cursor.
+        elif key == WXK_F8 and self.GetCurrentLine() == self.GetLineCount()-1:
+            tempCommand = self.getCommand()
+            # The first F8 saves the current command, just like Control+Up.
+            if self.historyPos == -1:
+                self.tempCommand = tempCommand
+            # The text up to the cursor is what we search for.
+            searchText = tempCommand
+            numCharsAfterCursor = self.GetTextLength() - self.GetCurrentPos()
+            if numCharsAfterCursor > 0:
+                searchText = searchText[:-numCharsAfterCursor]
+            # Search upwards from the current history position and loop back
+            # to the beginning if we don't find anything.
+            for i in range(self.historyPos+1, len(self.history)) + \
+                     range(self.historyPos):
+                command = self.history[i]
+                if command[:len(searchText)] == searchText:
+                    # Replace the current line with the one we've found.
+                    endpos = self.GetTextLength()
+                    self.SetSelection(stoppos, endpos)
+                    self.ReplaceSelection(command)
+                    # Put the cursor back at the end of the search text.
+                    pos = self.GetTextLength() - len(command) + len(searchText)
+                    self.SetCurrentPos(pos)
+                    self.SetAnchor(pos)
+                    # We've now warped into middle of the history.
+                    self.historyPos = i
+                    self.lastCommandRecalled = -1
+                    break
         # Return is used to submit a command to the interpreter.
         elif key == WXK_RETURN:
             if self.CallTipActive: self.CallTipCancel()
@@ -252,8 +334,7 @@ class Shell(wxStyledTextCtrl):
         """Keypress event handler.
         
         The main goal here is to not allow modifications to previous 
-        lines of text.
-        """
+        lines of text."""
         key = event.KeyCode()
         currpos = self.GetCurrentPos()
         stoppos = self.promptPos[1]
@@ -296,14 +377,24 @@ class Shell(wxStyledTextCtrl):
         # Grab information about the current line.
         thepos = self.GetCurrentPos()
         theline = self.GetCurrentLine()
-        thetext = self.GetCurLine()[0]
-        command = self.getCommand(thetext)
+        command = self.getCommand()
         # Go to the very bottom of the text.
         endpos = self.GetTextLength()
         self.SetCurrentPos(endpos)
         endline = self.GetCurrentLine()
         # If they hit RETURN on the last line, execute the command.
         if theline == endline:
+            # Store the last-recalled command; see the main comment for
+            # self.lastCommandRecalled.
+            if command != '':
+                self.lastCommandRecalled = self.historyPos
+            # Reset the history position.
+            self.historyPos = -1
+            # Insert this command into the history, unless it's a blank line
+            # or the same as the last command.
+            if command != '' \
+            and (len(self.history) == 0 or command != self.history[0]):
+                self.history.insert(0, command)
             self.push(command)
         # Otherwise, replace the last line with the new line.
         else:
@@ -319,15 +410,19 @@ class Shell(wxStyledTextCtrl):
                 self.SetCurrentPos(thepos)
                 self.SetAnchor(thepos)
 
-    def getCommand(self, text):
+    def getCommand(self, text=None):
         """Extract a command from text which may include a shell prompt.
         
-        The command may not necessarily be valid Python syntax.
-        """
-        
+        The command may not necessarily be valid Python syntax."""
+        if not text:
+            text = self.GetCurLine()[0]
+## This is a hack due to a bug in the wxPython 2.3.2 beta. The following
+## two lines of code should go away once the bug has been fixed and the
+## line above should be restored.
+##            self.write(' ')
+##            text = self.GetCurLine()[0][:-1]
         # XXX Need to extract real prompts here. Need to keep track of the
-        # prompt every time a command is issued. Do this in the interpreter
-        # with a line number, prompt, command dictionary. For the history, perhaps.
+        # prompt every time a command is issued.
         ps1 = str(sys.ps1)
         ps1size = len(ps1)
         ps2 = str(sys.ps2)
@@ -344,7 +439,7 @@ class Shell(wxStyledTextCtrl):
     
     def push(self, command):
         """Send command to the interpreter for execution."""
-        self.write('\n')
+        self.write(os.linesep)
         self.more = self.interp.push(command)
         self.prompt()
         # Keep the undo feature from undoing previous responses. The only
@@ -353,22 +448,30 @@ class Shell(wxStyledTextCtrl):
         self.EmptyUndoBuffer()
 
     def write(self, text):
-        """Display text in the shell."""
+        """Display text in the shell.
+
+        Replace line endings with OS-specific endings."""
+        lines = text.split('\r\n')
+        for l in range(len(lines)):
+            chunks = lines[l].split('\r')
+            for c in range(len(chunks)):
+                chunks[c] = os.linesep.join(chunks[c].split('\n'))
+            lines[l] = os.linesep.join(chunks)
+        text = os.linesep.join(lines)
         self.AddText(text)
         self.EnsureCaretVisible()
         #self.ScrollToColumn(0)
-    
+
     def prompt(self):
         """Display appropriate prompt for the context, either ps1 or ps2.
         
-        If this is a continuation line, autoindent as necessary.
-        """
+        If this is a continuation line, autoindent as necessary."""
         if self.more:
             prompt = str(sys.ps2)
         else:
             prompt = str(sys.ps1)
         pos = self.GetCurLine()[1]
-        if pos > 0: self.write('\n')
+        if pos > 0: self.write(os.linesep)
         self.promptPos[0] = self.GetCurrentPos()
         self.write(prompt)
         self.promptPos[1] = self.GetCurrentPos()
@@ -377,7 +480,7 @@ class Shell(wxStyledTextCtrl):
             self.write('\t')  # Temporary hack indentation.
         self.EnsureCaretVisible()
         self.ScrollToColumn(0)
-    
+
     def readIn(self):
         """Replacement for stdin."""
         prompt = 'Please enter your response:'
@@ -386,7 +489,7 @@ class Shell(wxStyledTextCtrl):
         try:
             if dialog.ShowModal() == wxID_OK:
                 text = dialog.GetValue()
-                self.write(text + '\n')
+                self.write(text + os.linesep)
                 return text
         finally:
             dialog.Destroy()
@@ -476,3 +579,205 @@ class Shell(wxStyledTextCtrl):
         """Return true if text is selected and can be copied."""
         return self.GetSelectionStart() != self.GetSelectionEnd()
 
+
+wxID_SELECTALL = NewId()  # This *should* be defined by wxPython.
+ID_AUTOCOMP = NewId()
+ID_AUTOCOMP_SHOW = NewId()
+ID_AUTOCOMP_INCLUDE_MAGIC = NewId()
+ID_AUTOCOMP_INCLUDE_SINGLE = NewId()
+ID_AUTOCOMP_INCLUDE_DOUBLE = NewId()
+ID_CALLTIPS = NewId()
+ID_CALLTIPS_SHOW = NewId()
+
+
+class ShellFrame(wxFrame):
+    """Frame containing the PyCrust shell component."""
+    
+    name = 'PyCrust Shell Frame'
+    revision = __version__
+    
+    def __init__(self, parent=None, id=-1, title='PyShell', \
+                 pos=wxDefaultPosition, size=wxDefaultSize, \
+                 style=wxDEFAULT_FRAME_STYLE, locals=None, \
+                 InterpClass=None, *args, **kwds):
+        """Create a PyCrust ShellFrame instance."""
+        wxFrame.__init__(self, parent, id, title, pos, size, style)
+        intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
+        self.CreateStatusBar()
+        self.SetStatusText(intro)
+        if wxPlatform == '__WXMSW__':
+            icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO)
+            self.SetIcon(icon)
+        self.createMenus()
+        self.shell = Shell(parent=self, id=-1, introText=intro, \
+                           locals=locals, InterpClass=InterpClass, \
+                           *args, **kwds)
+        # Override the shell so that status messages go to the status bar.
+        self.shell.setStatusText = self.SetStatusText
+
+    def createMenus(self):
+        m = self.fileMenu = wxMenu()
+        m.AppendSeparator()
+        m.Append(wxID_EXIT, 'E&xit', 'Exit PyCrust')
+
+        m = self.editMenu = wxMenu()
+        m.Append(wxID_UNDO, '&Undo \tCtrl+Z', 'Undo the last action')
+        m.Append(wxID_REDO, '&Redo \tCtrl+Y', 'Redo the last undone action')
+        m.AppendSeparator()
+        m.Append(wxID_CUT, 'Cu&t \tCtrl+X', 'Cut the selection')
+        m.Append(wxID_COPY, '&Copy \tCtrl+C', 'Copy the selection')
+        m.Append(wxID_PASTE, '&Paste \tCtrl+V', 'Paste')
+        m.AppendSeparator()
+        m.Append(wxID_CLEAR, 'Cle&ar \tDel', 'Delete the selection')
+        m.Append(wxID_SELECTALL, 'Select A&ll \tCtrl+A', 'Select all text')
+
+        m = self.autocompMenu = wxMenu()
+        m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \
+                 'Show auto completion during dot syntax', \
+                 checkable=1)
+        m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \
+                 'Include attributes visible to __getattr__ and __setattr__', \
+                 checkable=1)
+        m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \
+                 'Include attibutes prefixed by a single underscore', \
+                 checkable=1)
+        m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \
+                 'Include attibutes prefixed by a double underscore', \
+                 checkable=1)
+
+        m = self.calltipsMenu = wxMenu()
+        m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \
+                 'Show call tips with argument specifications', checkable=1)
+
+        m = self.optionsMenu = wxMenu()
+        m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \
+                     'Auto Completion Options')
+        m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu, \
+                     'Call Tip Options')
+
+        m = self.helpMenu = wxMenu()
+        m.AppendSeparator()
+        m.Append(wxID_ABOUT, '&About...', 'About PyCrust')
+
+        b = self.menuBar = wxMenuBar()
+        b.Append(self.fileMenu, '&File')
+        b.Append(self.editMenu, '&Edit')
+        b.Append(self.optionsMenu, '&Options')
+        b.Append(self.helpMenu, '&Help')
+        self.SetMenuBar(b)
+
+        EVT_MENU(self, wxID_EXIT, self.OnExit)
+        EVT_MENU(self, wxID_UNDO, self.OnUndo)
+        EVT_MENU(self, wxID_REDO, self.OnRedo)
+        EVT_MENU(self, wxID_CUT, self.OnCut)
+        EVT_MENU(self, wxID_COPY, self.OnCopy)
+        EVT_MENU(self, wxID_PASTE, self.OnPaste)
+        EVT_MENU(self, wxID_CLEAR, self.OnClear)
+        EVT_MENU(self, wxID_SELECTALL, self.OnSelectAll)
+        EVT_MENU(self, wxID_ABOUT, self.OnAbout)
+        EVT_MENU(self, ID_AUTOCOMP_SHOW, \
+                 self.OnAutoCompleteShow)
+        EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC, \
+                 self.OnAutoCompleteIncludeMagic)
+        EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE, \
+                 self.OnAutoCompleteIncludeSingle)
+        EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE, \
+                 self.OnAutoCompleteIncludeDouble)
+        EVT_MENU(self, ID_CALLTIPS_SHOW, \
+                 self.OnCallTipsShow)
+
+        EVT_UPDATE_UI(self, wxID_UNDO, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, wxID_REDO, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, wxID_CUT, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, wxID_COPY, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, wxID_PASTE, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, wxID_CLEAR, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu)
+        EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu)
+
+    def OnExit(self, event):
+        self.Close(true)
+
+    def OnUndo(self, event):
+        self.shell.Undo()
+
+    def OnRedo(self, event):
+        self.shell.Redo()
+
+    def OnCut(self, event):
+        self.shell.Cut()
+
+    def OnCopy(self, event):
+        self.shell.Copy()
+
+    def OnPaste(self, event):
+        self.shell.Paste()
+
+    def OnClear(self, event):
+        self.shell.Clear()
+
+    def OnSelectAll(self, event):
+        self.shell.SelectAll()
+
+    def OnAbout(self, event):
+        """Display an About PyCrust window."""
+        import sys
+        title = 'About PyCrust'
+        text = 'PyCrust %s\n\n' % VERSION + \
+               'Yet another Python shell, only flakier.\n\n' + \
+               'Half-baked by Patrick K. O\'Brien,\n' + \
+               'the other half is still in the oven.\n\n' + \
+               'Shell Revision: %s\n' % self.shell.revision + \
+               'Interpreter Revision: %s\n\n' % self.shell.interp.revision + \
+               'Python Version: %s\n' % sys.version.split()[0] + \
+               'wxPython Version: %s\n' % wx.__version__ + \
+               'Platform: %s\n' % sys.platform
+        dialog = wxMessageDialog(self, text, title, wxOK | wxICON_INFORMATION)
+        dialog.ShowModal()
+        dialog.Destroy()
+
+    def OnAutoCompleteShow(self, event):
+        self.shell.autoComplete = event.IsChecked()
+
+    def OnAutoCompleteIncludeMagic(self, event):
+        self.shell.autoCompleteIncludeMagic = event.IsChecked()
+
+    def OnAutoCompleteIncludeSingle(self, event):
+        self.shell.autoCompleteIncludeSingle = event.IsChecked()
+
+    def OnAutoCompleteIncludeDouble(self, event):
+        self.shell.autoCompleteIncludeDouble = event.IsChecked()
+
+    def OnCallTipsShow(self, event):
+        self.shell.autoCallTip = event.IsChecked()
+
+    def OnUpdateMenu(self, event):
+        """Update menu items based on current status."""
+        id = event.GetId()
+        if id == wxID_UNDO:
+            event.Enable(self.shell.CanUndo())
+        elif id == wxID_REDO:
+            event.Enable(self.shell.CanRedo())
+        elif id == wxID_CUT:
+            event.Enable(self.shell.CanCut())
+        elif id == wxID_COPY:
+            event.Enable(self.shell.CanCopy())
+        elif id == wxID_PASTE:
+            event.Enable(self.shell.CanPaste())
+        elif id == wxID_CLEAR:
+            event.Enable(self.shell.CanCut())
+        elif id == ID_AUTOCOMP_SHOW:
+            event.Check(self.shell.autoComplete)
+        elif id == ID_AUTOCOMP_INCLUDE_MAGIC:
+            event.Check(self.shell.autoCompleteIncludeMagic)
+        elif id == ID_AUTOCOMP_INCLUDE_SINGLE:
+            event.Check(self.shell.autoCompleteIncludeSingle)
+        elif id == ID_AUTOCOMP_INCLUDE_DOUBLE:
+            event.Check(self.shell.autoCompleteIncludeDouble)
+        elif id == ID_CALLTIPS_SHOW:
+            event.Check(self.shell.autoCallTip)
+            
+
index 0c48e4021de287125b0f689230c3a7ec3981fe73..5fc855db6dc8a8c9cfd85154b4ec4ebdbb4de847 100644 (file)
@@ -1,5 +1,5 @@
 """Provides an object representing the current "version" or "release" of
-PyCrust as a whole. Individual classes, such as the shell, editor and
+PyCrust 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>"
@@ -7,4 +7,4 @@ __cvsid__ = "$Id$"
 __date__ = "July 1, 2001"
 __version__ = "$Revision$"[11:-2]
 
-VERSION = '0.5.2'
+VERSION = '0.6'