diff options
Diffstat (limited to 'lib/python2.7/site-packages/wx-3.0-msw/wx/py/crust.py')
-rw-r--r-- | lib/python2.7/site-packages/wx-3.0-msw/wx/py/crust.py | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/wx-3.0-msw/wx/py/crust.py b/lib/python2.7/site-packages/wx-3.0-msw/wx/py/crust.py new file mode 100644 index 0000000..aed30a1 --- /dev/null +++ b/lib/python2.7/site-packages/wx-3.0-msw/wx/py/crust.py @@ -0,0 +1,379 @@ +"""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 re +import sys + +import dispatcher +import editwindow +from filling import Filling +import frame +from shell import Shell +from version import VERSION + + +class Crust(wx.SplitterWindow): + """Crust based on SplitterWindow.""" + + name = 'Crust' + revision = __revision__ + sashoffset = 300 + + def __init__(self, parent, id=-1, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.SP_3D|wx.SP_LIVE_UPDATE, + name='Crust Window', rootObject=None, rootLabel=None, + rootIsNamespace=True, intro='', locals=None, + InterpClass=None, + startupScript=None, execStartupScript=True, + *args, **kwds): + """Create Crust instance.""" + wx.SplitterWindow.__init__(self, parent, id, pos, size, style, name) + + # Turn off the tab-traversal style that is automatically + # turned on by wx.SplitterWindow. We do this because on + # Windows the event for Ctrl-Enter is stolen and used as a + # navigation key, but the Shell window uses it to insert lines. + style = self.GetWindowStyle() + self.SetWindowStyle(style & ~wx.TAB_TRAVERSAL) + + self.shell = Shell(parent=self, introText=intro, + locals=locals, InterpClass=InterpClass, + startupScript=startupScript, + execStartupScript=execStartupScript, + *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.display.nbTab = self.notebook.GetPageCount()-1 + + 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='History') + + self.dispatcherlisting = DispatcherListing(parent=self.notebook) + self.notebook.AddPage(page=self.dispatcherlisting, text='Dispatcher') + + + # Initialize in an unsplit mode, and check later after loading + # settings if we should split or not. + self.shell.Hide() + self.notebook.Hide() + self.Initialize(self.shell) + self._shouldsplit = True + wx.CallAfter(self._CheckShouldSplit) + self.SetMinimumPaneSize(100) + + self.Bind(wx.EVT_SIZE, self.SplitterOnSize) + self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnChanged) + self.Bind(wx.EVT_SPLITTER_DCLICK, self.OnSashDClick) + + def _CheckShouldSplit(self): + if self._shouldsplit: + self.SplitHorizontally(self.shell, self.notebook, -self.sashoffset) + self.lastsashpos = self.GetSashPosition() + else: + self.lastsashpos = -1 + self.issplit = self.IsSplit() + + def ToggleTools(self): + """Toggle the display of the filling and other tools""" + if self.issplit: + self.Unsplit() + else: + self.SplitHorizontally(self.shell, self.notebook, -self.sashoffset) + self.lastsashpos = self.GetSashPosition() + self.issplit = self.IsSplit() + + def ToolsShown(self): + return self.issplit + + def OnChanged(self, event): + """update sash offset from the bottom of the window""" + self.sashoffset = self.GetSize().height - event.GetSashPosition() + self.lastsashpos = event.GetSashPosition() + event.Skip() + + def OnSashDClick(self, event): + self.Unsplit() + self.issplit = False + + # Make the splitter expand the top window when resized + def SplitterOnSize(self, event): + splitter = event.GetEventObject() + sz = splitter.GetSize() + splitter.SetSashPosition(sz.height - self.sashoffset, True) + event.Skip() + + + def LoadSettings(self, config): + self.shell.LoadSettings(config) + self.filling.LoadSettings(config) + + pos = config.ReadInt('Sash/CrustPos', 400) + wx.CallAfter(self.SetSashPosition, pos) + def _updateSashPosValue(): + sz = self.GetSize() + self.sashoffset = sz.height - self.GetSashPosition() + wx.CallAfter(_updateSashPosValue) + zoom = config.ReadInt('View/Zoom/Display', -99) + if zoom != -99: + self.display.SetZoom(zoom) + self.issplit = config.ReadInt('Sash/IsSplit', True) + if not self.issplit: + self._shouldsplit = False + + def SaveSettings(self, config): + self.shell.SaveSettings(config) + self.filling.SaveSettings(config) + + if self.lastsashpos != -1: + config.WriteInt('Sash/CrustPos', self.lastsashpos) + config.WriteInt('Sash/IsSplit', self.issplit) + config.WriteInt('View/Zoom/Display', self.display.GetZoom()) + +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() + if self.GetParent().GetSelection() != self.nbTab: + focus = wx.Window.FindFocus() + self.GetParent().SetSelection(self.nbTab) + wx.CallAfter(focus.SetFocus) + + +# TODO: Switch this to a editwindow.EditWindow +class Calltip(wx.TextCtrl): + """Text control containing the most recent shell calltip.""" + + def __init__(self, parent=None, id=-1,ShellClassName='Shell'): + style = (wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2) + wx.TextCtrl.__init__(self, parent, id, style=style) + self.SetBackgroundColour(wx.Colour(255, 255, 208)) + self.ShellClassName=ShellClassName + dispatcher.connect(receiver=self.display, signal=self.ShellClassName+'.calltip') + + df = self.GetFont() + font = wx.Font(df.GetPointSize(), wx.TELETYPE, wx.NORMAL, wx.NORMAL) + self.SetFont(font) + + def display(self, calltip): + """Receiver for """+self.ShellClassName+""".calltip signal.""" + ## self.SetValue(calltip) # Caused refresh problem on Windows. + self.Clear() + self.AppendText(calltip) + self.SetInsertionPoint(0) + + +# TODO: Switch this to a editwindow.EditWindow +class SessionListing(wx.TextCtrl): + """Text control containing all commands for session.""" + + def __init__(self, parent=None, id=-1,ShellClassName='Shell'): + style = (wx.TE_MULTILINE | wx.TE_READONLY | + wx.TE_RICH2 | wx.TE_DONTWRAP) + wx.TextCtrl.__init__(self, parent, id, style=style) + dispatcher.connect(receiver=self.addHistory, + signal=ShellClassName+".addHistory") + dispatcher.connect(receiver=self.clearHistory, + signal=ShellClassName+".clearHistory") + dispatcher.connect(receiver=self.loadHistory, + signal=ShellClassName+".loadHistory") + + df = self.GetFont() + font = wx.Font(df.GetPointSize(), wx.TELETYPE, wx.NORMAL, wx.NORMAL) + self.SetFont(font) + + def loadHistory(self, history): + # preload the existing history, if any + hist = history[:] + hist.reverse() + self.SetValue('\n'.join(hist) + '\n') + self.SetInsertionPointEnd() + + def addHistory(self, command): + if command: + self.SetInsertionPointEnd() + self.AppendText(command + '\n') + + def clearHistory(self): + self.SetValue("") + + +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, id, style=style) + dispatcher.connect(receiver=self.spy) + + df = self.GetFont() + font = wx.Font(df.GetPointSize(), wx.TELETYPE, wx.NORMAL, wx.NORMAL) + self.SetFont(font) + + 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.ShellFrameMixin): + """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, + config=None, dataDir=None, + *args, **kwds): + """Create CrustFrame instance.""" + frame.Frame.__init__(self, parent, id, title, pos, size, style, + shellName='PyCrust') + frame.ShellFrameMixin.__init__(self, config, dataDir) + + if size == wx.DefaultSize: + self.SetSize((800, 600)) + + intro = 'PyCrust %s - The Flakiest Python Shell' % VERSION + + self.SetStatusText(intro.replace('\n', ', ')) + self.crust = Crust(parent=self, intro=intro, + rootObject=rootObject, + rootLabel=rootLabel, + rootIsNamespace=rootIsNamespace, + locals=locals, + InterpClass=InterpClass, + startupScript=self.startupScript, + execStartupScript=self.execStartupScript, + *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 + + self.shell.SetFocus() + self.LoadSettings() + + + def OnClose(self, event): + """Event handler for closing.""" + self.SaveSettings() + 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 + \ + 'Platform: %s\n' % sys.platform + \ + 'Python Version: %s\n' % sys.version.split()[0] + \ + 'wxPython Version: %s\n' % wx.VERSION_STRING + \ + ('\t(%s)\n' % ", ".join(wx.PlatformInfo[1:])) + dialog = wx.MessageDialog(self, text, title, + wx.OK | wx.ICON_INFORMATION) + dialog.ShowModal() + dialog.Destroy() + + + def ToggleTools(self): + """Toggle the display of the filling and other tools""" + return self.crust.ToggleTools() + + def ToolsShown(self): + return self.crust.ToolsShown() + + def OnHelp(self, event): + """Show a help dialog.""" + frame.ShellFrameMixin.OnHelp(self, event) + + def LoadSettings(self): + if self.config is not None: + frame.ShellFrameMixin.LoadSettings(self) + frame.Frame.LoadSettings(self, self.config) + self.crust.LoadSettings(self.config) + + + def SaveSettings(self, force=False): + if self.config is not None: + frame.ShellFrameMixin.SaveSettings(self,force) + if self.autoSaveSettings or force: + frame.Frame.SaveSettings(self, self.config) + self.crust.SaveSettings(self.config) + + + def DoSaveSettings(self): + if self.config is not None: + self.SaveSettings(force=True) + self.config.Flush() + |