text: """Base frame with menu."""
  
  __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
  
  import wx
  import os
  from .version import VERSION
  from . import editwindow
  from . import dispatcher
  
  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_EMPTYBUFFER = wx.NewIdRef()
  ID_ABOUT = wx.ID_ABOUT
  ID_HELP = wx.NewIdRef()
  ID_AUTOCOMP = wx.NewIdRef()
  ID_AUTOCOMP_SHOW = wx.NewIdRef()
  ID_AUTOCOMP_MAGIC = wx.NewIdRef()
  ID_AUTOCOMP_SINGLE = wx.NewIdRef()
  ID_AUTOCOMP_DOUBLE = wx.NewIdRef()
  ID_CALLTIPS = wx.NewIdRef()
  ID_CALLTIPS_SHOW = wx.NewIdRef()
  ID_CALLTIPS_INSERT = wx.NewIdRef()
  ID_COPY_PLUS = wx.NewIdRef()
  ID_NAMESPACE = wx.NewIdRef()
  ID_PASTE_PLUS = wx.NewIdRef()
  ID_WRAP = wx.NewIdRef()
  ID_TOGGLE_MAXIMIZE = wx.NewIdRef()
  ID_SHOW_LINENUMBERS = wx.NewIdRef()
  ID_ENABLESHELLMODE = wx.NewIdRef()
  ID_ENABLEAUTOSYMPY = wx.NewIdRef()
  ID_AUTO_SAVESETTINGS = wx.NewIdRef()
  ID_SAVEACOPY = wx.NewIdRef()
  ID_SAVEHISTORY = wx.NewIdRef()
  ID_SAVEHISTORYNOW = wx.NewIdRef()
  ID_CLEARHISTORY = wx.NewIdRef()
  ID_SAVESETTINGS = wx.NewIdRef()
  ID_DELSETTINGSFILE = wx.NewIdRef()
  ID_EDITSTARTUPSCRIPT = wx.NewIdRef()
  ID_EXECSTARTUPSCRIPT = wx.NewIdRef()
  ID_SHOWPYSLICESTUTORIAL = wx.NewIdRef()
  ID_STARTUP = wx.NewIdRef()
  ID_SETTINGS = wx.NewIdRef()
  ID_FIND = wx.ID_FIND
  ID_FINDNEXT = wx.NewIdRef()
  ID_FINDPREVIOUS = wx.NewIdRef()
  ID_SHOWTOOLS = wx.NewIdRef()
  ID_HIDEFOLDINGMARGIN = wx.NewIdRef()
  
  
  
  class Frame(wx.Frame):
      """Frame with standard menu items."""
  
  
      def __init__(self, parent=None, id=-1, title='Editor',
                   pos=wx.DefaultPosition, size=wx.DefaultSize,
                   style=wx.DEFAULT_FRAME_STYLE,shellName='PyCrust'):
          """Create a Frame instance."""
          wx.Frame.__init__(self, parent, id, title, pos, size, style)
          self.CreateStatusBar()
          self.SetStatusText('Frame')
          self.shellName=shellName
          from . import images
          self.SetIcon(images.getPyIcon(shellName=shellName))
          self.__createMenus()
  
          self.iconized = False
          self.findDlg = None
          self.findData = wx.FindReplaceData()
          self.findData.SetFlags(wx.FR_DOWN)
  
          self.Bind(wx.EVT_CLOSE, self.OnClose)
          self.Bind(wx.EVT_ICONIZE, self.OnIconize)
  
  
      def OnIconize(self, event):
          """Event handler for Iconize."""
          self.iconized = event.Iconized()
  
  
      def OnClose(self, event):
          """Event handler for closing."""
          self.Destroy()
  
  
      def __createMenus(self):
          # File Menu
          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 \tCtrl+Shift+S',
                   'Save file with new name')
          if self.shellName in ['PySlices','SymPySlices']:
              m.Append(ID_SAVEACOPY, 'Save A Cop&y',
                   'Save a copy of the file without changing the current file')
          m.AppendSeparator()
          m.Append(ID_PRINT, '&Print... \tCtrl+P',
                   'Print file')
          m.AppendSeparator()
          m.Append(ID_NAMESPACE, '&Update Namespace \tCtrl+Shift+N',
                   'Update namespace for autocompletion and calltips')
          m.AppendSeparator()
          m.Append(ID_EXIT, 'E&xit\tCtrl+Q', 'Exit Program')
  
          # Edit
          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 \tCtrl+Shift+C',
                   'Copy the selection - retaining prompts')
          m.Append(ID_PASTE, '&Paste \tCtrl+V', 'Paste from clipboard')
          m.Append(ID_PASTE_PLUS, 'Past&e Plus \tCtrl+Shift+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.AppendSeparator()
          m.Append(ID_EMPTYBUFFER, 'E&mpty Buffer...',
                   'Delete all the contents of the edit buffer')
          m.Append(ID_FIND, '&Find Text... \tCtrl+F',
                   'Search for text in the edit buffer')
          m.Append(ID_FINDNEXT, 'Find &Next \tCtrl+G',
                   'Find next instance of the search text')
          m.Append(ID_FINDPREVIOUS, 'Find Pre&vious \tCtrl+Shift+G',
                   'Find previous instance of the search text')
  
          # View
          m = self.viewMenu = wx.Menu()
          m.Append(ID_WRAP, '&Wrap Lines\tCtrl+Shift+W',
                   'Wrap lines at right edge', wx.ITEM_CHECK)
          m.Append(ID_SHOW_LINENUMBERS, '&Show Line Numbers\tCtrl+Shift+L',
                   'Show Line Numbers', wx.ITEM_CHECK)
          m.Append(ID_TOGGLE_MAXIMIZE, '&Toggle Maximize\tF11',
                   'Maximize/Restore Application')
          if hasattr(self, 'ToggleTools'):
              m.Append(ID_SHOWTOOLS,
                       'Show &Tools\tF4',
                       'Show the filling and other tools', wx.ITEM_CHECK)
          if self.shellName==['PySlices','SymPySlices']:
              m.Append(ID_HIDEFOLDINGMARGIN,
                                  '&Hide Folding Margin',
                                  'Hide Folding Margin', wx.ITEM_CHECK)
  
          # Options
          m = self.autocompMenu = wx.Menu()
          m.Append(ID_AUTOCOMP_SHOW, 'Show &Auto Completion\tCtrl+Shift+A',
                   'Show auto completion list', wx.ITEM_CHECK)
          m.Append(ID_AUTOCOMP_MAGIC, 'Include &Magic Attributes\tCtrl+Shift+M',
                   'Include attributes visible to __getattr__ and __setattr__',
                   wx.ITEM_CHECK)
          m.Append(ID_AUTOCOMP_SINGLE, 'Include Single &Underscores\tCtrl+Shift+U',
                   'Include attibutes prefixed by a single underscore', wx.ITEM_CHECK)
          m.Append(ID_AUTOCOMP_DOUBLE, 'Include &Double Underscores\tCtrl+Shift+D',
                   'Include attibutes prefixed by a double underscore', wx.ITEM_CHECK)
          m = self.calltipsMenu = wx.Menu()
          m.Append(ID_CALLTIPS_SHOW, 'Show Call &Tips\tCtrl+Shift+T',
                   'Show call tips with argument signature and docstring', wx.ITEM_CHECK)
          m.Append(ID_CALLTIPS_INSERT, '&Insert Call Tips\tCtrl+Shift+I',
                   '&Insert Call Tips', wx.ITEM_CHECK)
  
          m = self.optionsMenu = wx.Menu()
          m.Append(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu,
                       'Auto Completion Options')
          m.Append(ID_CALLTIPS, '&Call Tips', self.calltipsMenu,
                       'Call Tip Options')
  
          m.AppendSeparator()
  
          self.historyMenu = wx.Menu()
          self.historyMenu.Append(ID_SAVEHISTORY, '&Autosave History',
                   'Automatically save history on close', wx.ITEM_CHECK)
          self.historyMenu.Append(ID_SAVEHISTORYNOW, '&Save History Now',
                   'Save history')
          self.historyMenu.Append(ID_CLEARHISTORY, '&Clear History ',
                   'Clear history')
          m.Append(-1, "&History", self.historyMenu, "History Options")
  
          self.startupMenu = wx.Menu()
          self.startupMenu.Append(ID_EXECSTARTUPSCRIPT,
                                  'E&xecute Startup Script',
                                  'Execute Startup Script', wx.ITEM_CHECK)
          self.startupMenu.Append(ID_EDITSTARTUPSCRIPT,
                                  '&Edit Startup Script...',
                                  'Edit Startup Script')
          if self.shellName in ['PySlices','SymPySlices']:
              self.startupMenu.Append(ID_SHOWPYSLICESTUTORIAL,
                                  '&Show PySlices Tutorial',
                                  'Show PySlices Tutorial', wx.ITEM_CHECK)
          m.Append(ID_STARTUP, '&Startup', self.startupMenu, 'Startup Options')
  
          self.settingsMenu = wx.Menu()
          if self.shellName in ['PySlices','SymPySlices']:
              self.settingsMenu.Append(ID_ENABLESHELLMODE,
                                  '&Enable Shell Mode',
                                  'Enable Shell Mode', wx.ITEM_CHECK)
          if self.shellName == 'SymPySlices':
              self.settingsMenu.Append(ID_ENABLEAUTOSYMPY,
                                  '&Enable "Auto-Sympy" Conversions for Undefined Variables',
                                  'Enable "Auto-Sympy" Conversions', wx.ITEM_CHECK)
          self.settingsMenu.Append(ID_AUTO_SAVESETTINGS,
                                   '&Auto Save Settings',
                                   'Automatically save settings on close', wx.ITEM_CHECK)
          self.settingsMenu.Append(ID_SAVESETTINGS,
                                   '&Save Settings',
                                   'Save settings now')
          self.settingsMenu.Append(ID_DELSETTINGSFILE,
                                   '&Revert to default',
                                   'Revert to the default settings')
          m.Append(ID_SETTINGS, '&Settings', self.settingsMenu, 'Settings Options')
  
          m = self.helpMenu = wx.Menu()
          m.Append(ID_HELP, '&Help\tF1', 'Help!')
          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.viewMenu, '&View')
          b.Append(self.optionsMenu, '&Options')
          b.Append(self.helpMenu, '&Help')
          self.SetMenuBar(b)
  
          self.Bind(wx.EVT_MENU, self.OnFileNew, id=ID_NEW)
          self.Bind(wx.EVT_MENU, self.OnFileOpen, id=ID_OPEN)
          self.Bind(wx.EVT_MENU, self.OnFileRevert, id=ID_REVERT)
          self.Bind(wx.EVT_MENU, self.OnFileClose, id=ID_CLOSE)
          self.Bind(wx.EVT_MENU, self.OnFileSave, id=ID_SAVE)
          self.Bind(wx.EVT_MENU, self.OnFileSaveAs, id=ID_SAVEAS)
          self.Bind(wx.EVT_MENU, self.OnFileSaveACopy, id=ID_SAVEACOPY)
          self.Bind(wx.EVT_MENU, self.OnFileUpdateNamespace, id=ID_NAMESPACE)
          self.Bind(wx.EVT_MENU, self.OnFilePrint, id=ID_PRINT)
          self.Bind(wx.EVT_MENU, self.OnExit, id=ID_EXIT)
          self.Bind(wx.EVT_MENU, self.OnUndo, id=ID_UNDO)
          self.Bind(wx.EVT_MENU, self.OnRedo, id=ID_REDO)
          self.Bind(wx.EVT_MENU, self.OnCut, id=ID_CUT)
          self.Bind(wx.EVT_MENU, self.OnCopy, id=ID_COPY)
          self.Bind(wx.EVT_MENU, self.OnCopyPlus, id=ID_COPY_PLUS)
          self.Bind(wx.EVT_MENU, self.OnPaste, id=ID_PASTE)
          self.Bind(wx.EVT_MENU, self.OnPastePlus, id=ID_PASTE_PLUS)
          self.Bind(wx.EVT_MENU, self.OnClear, id=ID_CLEAR)
          self.Bind(wx.EVT_MENU, self.OnSelectAll, id=ID_SELECTALL)
          self.Bind(wx.EVT_MENU, self.OnEmptyBuffer, id=ID_EMPTYBUFFER)
          self.Bind(wx.EVT_MENU, self.OnAbout, id=ID_ABOUT)
          self.Bind(wx.EVT_MENU, self.OnHelp, id=ID_HELP)
          self.Bind(wx.EVT_MENU, self.OnAutoCompleteShow, id=ID_AUTOCOMP_SHOW)
          self.Bind(wx.EVT_MENU, self.OnAutoCompleteMagic, id=ID_AUTOCOMP_MAGIC)
          self.Bind(wx.EVT_MENU, self.OnAutoCompleteSingle, id=ID_AUTOCOMP_SINGLE)
          self.Bind(wx.EVT_MENU, self.OnAutoCompleteDouble, id=ID_AUTOCOMP_DOUBLE)
          self.Bind(wx.EVT_MENU, self.OnCallTipsShow, id=ID_CALLTIPS_SHOW)
          self.Bind(wx.EVT_MENU, self.OnCallTipsInsert, id=ID_CALLTIPS_INSERT)
          self.Bind(wx.EVT_MENU, self.OnWrap, id=ID_WRAP)
          self.Bind(wx.EVT_MENU, self.OnToggleMaximize, id=ID_TOGGLE_MAXIMIZE)
          self.Bind(wx.EVT_MENU, self.OnShowLineNumbers, id=ID_SHOW_LINENUMBERS)
          self.Bind(wx.EVT_MENU, self.OnEnableShellMode, id=ID_ENABLESHELLMODE)
          self.Bind(wx.EVT_MENU, self.OnEnableAutoSympy, id=ID_ENABLEAUTOSYMPY)
          self.Bind(wx.EVT_MENU, self.OnAutoSaveSettings, id=ID_AUTO_SAVESETTINGS)
          self.Bind(wx.EVT_MENU, self.OnSaveHistory, id=ID_SAVEHISTORY)
          self.Bind(wx.EVT_MENU, self.OnSaveHistoryNow, id=ID_SAVEHISTORYNOW)
          self.Bind(wx.EVT_MENU, self.OnClearHistory, id=ID_CLEARHISTORY)
          self.Bind(wx.EVT_MENU, self.OnSaveSettings, id=ID_SAVESETTINGS)
          self.Bind(wx.EVT_MENU, self.OnDelSettingsFile, id=ID_DELSETTINGSFILE)
          self.Bind(wx.EVT_MENU, self.OnEditStartupScript, id=ID_EDITSTARTUPSCRIPT)
          self.Bind(wx.EVT_MENU, self.OnExecStartupScript, id=ID_EXECSTARTUPSCRIPT)
          self.Bind(wx.EVT_MENU, self.OnShowPySlicesTutorial, id=ID_SHOWPYSLICESTUTORIAL)
          self.Bind(wx.EVT_MENU, self.OnFindText, id=ID_FIND)
          self.Bind(wx.EVT_MENU, self.OnFindNext, id=ID_FINDNEXT)
          self.Bind(wx.EVT_MENU, self.OnFindPrevious, id=ID_FINDPREVIOUS)
          self.Bind(wx.EVT_MENU, self.OnToggleTools, id=ID_SHOWTOOLS)
          self.Bind(wx.EVT_MENU, self.OnHideFoldingMargin, id=ID_HIDEFOLDINGMARGIN)
  
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_NEW)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_OPEN)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_REVERT)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CLOSE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVEAS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_NAMESPACE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_PRINT)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_UNDO)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_REDO)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CUT)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_COPY)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_COPY_PLUS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_PASTE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_PASTE_PLUS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CLEAR)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SELECTALL)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_EMPTYBUFFER)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_SHOW)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_MAGIC)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_SINGLE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTOCOMP_DOUBLE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CALLTIPS_SHOW)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CALLTIPS_INSERT)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_WRAP)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SHOW_LINENUMBERS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_ENABLESHELLMODE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_ENABLEAUTOSYMPY)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_AUTO_SAVESETTINGS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVESETTINGS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_DELSETTINGSFILE)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_EXECSTARTUPSCRIPT)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SHOWPYSLICESTUTORIAL)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVEHISTORY)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SAVEHISTORYNOW)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_CLEARHISTORY)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_EDITSTARTUPSCRIPT)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_FIND)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_FINDNEXT)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_FINDPREVIOUS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_SHOWTOOLS)
          self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateMenu, id=ID_HIDEFOLDINGMARGIN)
  
          self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
          self.Bind(wx.EVT_FIND, self.OnFindNext)
          self.Bind(wx.EVT_FIND_NEXT, self.OnFindNext)
          self.Bind(wx.EVT_FIND_CLOSE, self.OnFindClose)
  
  
  
      def OnShowLineNumbers(self, event):
          win = wx.Window.FindFocus()
          if hasattr(win, 'lineNumbers'):
              win.lineNumbers = event.IsChecked()
              win.setDisplayLineNumbers(win.lineNumbers)
  
      def OnToggleMaximize(self, event):
          self.Maximize(not self.IsMaximized())
  
      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 OnFileSaveACopy(self, event):
          self.bufferSaveACopy()
  
      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 OnEmptyBuffer(self, event):
          win = wx.Window.FindFocus()
          d = wx.MessageDialog(self,
                               "Are you sure you want to clear the edit buffer,\n"
                               "deleting all the text?",
                               "Empty Buffer", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
          answer = d.ShowModal()
          d.Destroy()
          if (answer == wx.ID_OK):
              win.ClearAll()
              if hasattr(win,'prompt'):
                  win.prompt()
  
      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 OnHelp(self, event):
          """Display a Help window."""
          title = 'Help'
          text = "Type 'shell.help()' in the shell window."
          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 OnCallTipsInsert(self, event):
          win = wx.Window.FindFocus()
          win.callTipInsert = event.IsChecked()
  
      def OnWrap(self, event):
          win = wx.Window.FindFocus()
          win.SetWrapMode(event.IsChecked())
          wx.CallLater(1, self.shell.EnsureCaretVisible)
  
      def OnSaveHistory(self, event):
          self.autoSaveHistory = event.IsChecked()
  
      def OnSaveHistoryNow(self, event):
          self.SaveHistory()
  
      def OnClearHistory(self, event):
          self.shell.clearHistory()
  
      def OnEnableShellMode(self, event):
          self.enableShellMode = event.IsChecked()
  
      def OnEnableAutoSympy(self, event):
          self.enableAutoSympy = event.IsChecked()
  
      def OnHideFoldingMargin(self, event):
          self.hideFoldingMargin = event.IsChecked()
  
      def OnAutoSaveSettings(self, event):
          self.autoSaveSettings = event.IsChecked()
  
      def OnSaveSettings(self, event):
          self.DoSaveSettings()
  
      def OnDelSettingsFile(self, event):
          if self.config is not None:
              d = wx.MessageDialog(
                  self, "Do you want to revert to the default settings?\n" +
                  "A restart is needed for the change to take effect",
                  "Warning", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
              answer = d.ShowModal()
              d.Destroy()
              if (answer == wx.ID_OK):
                  self.config.DeleteAll()
                  self.LoadSettings()
  
  
      def OnEditStartupScript(self, event):
          if hasattr(self, 'EditStartupScript'):
              self.EditStartupScript()
  
      def OnExecStartupScript(self, event):
          self.execStartupScript = event.IsChecked()
          self.SaveSettings(force=True)
  
      def OnShowPySlicesTutorial(self,event):
          self.showPySlicesTutorial = event.IsChecked()
          self.SaveSettings(force=True)
  
      def OnFindText(self, event):
          if self.findDlg is not None:
              return
          win = wx.Window.FindFocus()
          if self.shellName == 'PyCrust':
              self.findDlg = wx.FindReplaceDialog(win, self.findData,
                                                 "Find",wx.FR_NOWHOLEWORD)
          else:
              self.findDlg = wx.FindReplaceDialog(win, self.findData,
                  "Find & Replace", wx.FR_NOWHOLEWORD|wx.FR_REPLACEDIALOG)
          self.findDlg.Show()
  
      def OnFindNext(self, event,backward=False):
          if backward and (self.findData.GetFlags() & wx.FR_DOWN):
              self.findData.SetFlags( self.findData.GetFlags() ^ wx.FR_DOWN )
          elif not backward and not (self.findData.GetFlags() & wx.FR_DOWN):
              self.findData.SetFlags( self.findData.GetFlags() ^ wx.FR_DOWN )
  
          if not self.findData.GetFindString():
              self.OnFindText(event)
              return
          if isinstance(event, wx.FindDialogEvent):
              win = self.findDlg.GetParent()
          else:
              win = wx.Window.FindFocus()
          win.DoFindNext(self.findData, self.findDlg)
          if self.findDlg is not None:
              self.OnFindClose(None)
  
      def OnFindPrevious(self, event):
          self.OnFindNext(event,backward=True)
  
      def OnFindClose(self, event):
          self.findDlg.Destroy()
          self.findDlg = None
  
      def OnToggleTools(self, event):
          self.ToggleTools()
  
  
      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_SAVEACOPY:
                  event.Enable(hasattr(self, 'bufferSaveACopy')
                               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_EMPTYBUFFER:
                  event.Enable(hasattr(win, 'ClearAll') and not win.GetReadOnly())
              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_CALLTIPS_INSERT:
                  event.Check(win.callTipInsert)
              elif id == ID_WRAP:
                  event.Check(win.GetWrapMode())
  
              elif id == ID_SHOW_LINENUMBERS:
                  event.Check(win.lineNumbers)
              elif id == ID_ENABLESHELLMODE:
                  event.Check(self.enableShellMode)
                  event.Enable(self.config is not None)
              elif id == ID_ENABLEAUTOSYMPY:
                  event.Check(self.enableAutoSympy)
                  event.Enable(self.config is not None)
              elif id == ID_AUTO_SAVESETTINGS:
                  event.Check(self.autoSaveSettings)
                  event.Enable(self.config is not None)
              elif id == ID_SAVESETTINGS:
                  event.Enable(self.config is not None and
                               hasattr(self, 'DoSaveSettings'))
              elif id == ID_DELSETTINGSFILE:
                  event.Enable(self.config is not None)
  
              elif id == ID_EXECSTARTUPSCRIPT:
                  event.Check(self.execStartupScript)
                  event.Enable(self.config is not None)
  
              elif id == ID_SHOWPYSLICESTUTORIAL:
                  event.Check(self.showPySlicesTutorial)
                  event.Enable(self.config is not None)
  
              elif id == ID_SAVEHISTORY:
                  event.Check(self.autoSaveHistory)
                  event.Enable(self.dataDir is not None)
              elif id == ID_SAVEHISTORYNOW:
                  event.Enable(self.dataDir is not None and
                               hasattr(self, 'SaveHistory'))
              elif id == ID_CLEARHISTORY:
                  event.Enable(self.dataDir is not None)
  
              elif id == ID_EDITSTARTUPSCRIPT:
                  event.Enable(hasattr(self, 'EditStartupScript'))
                  event.Enable(self.dataDir is not None)
  
              elif id == ID_FIND:
                  event.Enable(hasattr(win, 'DoFindNext'))
              elif id == ID_FINDNEXT:
                  event.Enable(hasattr(win, 'DoFindNext'))
              elif id == ID_FINDPREVIOUS:
                  event.Enable(hasattr(win, 'DoFindNext'))
  
              elif id == ID_SHOWTOOLS:
                  event.Check(self.ToolsShown())
  
              elif id == ID_HIDEFOLDINGMARGIN:
                  event.Check(self.hideFoldingMargin)
                  event.Enable(self.config is not None)
  
              else:
                  event.Enable(False)
          except AttributeError:
              # This menu option is not supported in the current context.
              event.Enable(False)
  
  
      def OnActivate(self, event):
          """
          Event Handler for losing the focus of the Frame. Should close
          Autocomplete listbox, if shown.
          """
          if not event.GetActive():
              # If autocomplete active, cancel it.  Otherwise, the
              # autocomplete list will stay visible on top of the
              # z-order after switching to another application
              win = wx.Window.FindFocus()
              if hasattr(win, 'AutoCompActive') and win.AutoCompActive():
                  win.AutoCompCancel()
          event.Skip()
  
  
  
      def LoadSettings(self, config):
          """Called by derived classes to load settings specific to the Frame"""
          pos  = wx.Point(config.ReadInt('Window/PosX', -1),
                          config.ReadInt('Window/PosY', -1))
  
          size = wx.Size(config.ReadInt('Window/Width', -1),
                         config.ReadInt('Window/Height', -1))
  
          self.SetSize(size)
          self.Move(pos)
  
  
      def SaveSettings(self, config):
          """Called by derived classes to save Frame settings to a wx.Config object"""
  
          # TODO: track position/size so we can save it even if the
          # frame is maximized or iconized.
          if not self.iconized and not self.IsMaximized():
              w, h = self.GetSize()
              config.WriteInt('Window/Width', w)
              config.WriteInt('Window/Height', h)
  
              px, py = self.GetPosition()
              config.WriteInt('Window/PosX', px)
              config.WriteInt('Window/PosY', py)
  
  
  
  
  class ShellFrameMixin:
      """
      A mix-in class for frames that will have a Shell or a Crust window
      and that want to add history, startupScript and other common
      functionality.
      """
      def __init__(self, config, dataDir):
          self.config = config
          self.dataDir = dataDir
          self.startupScript = os.environ.get('PYTHONSTARTUP')
          if not self.startupScript and self.dataDir:
              self.startupScript = os.path.join(self.dataDir, 'startup')
  
          self.autoSaveSettings = False
          self.autoSaveHistory = False
  
          # We need this one before we have a chance to load the settings...
          self.execStartupScript = True
          self.showPySlicesTutorial = True
          self.enableShellMode = False
          self.enableAutoSympy = True
          self.hideFoldingMargin = False
          if self.config:
              self.execStartupScript = \
                   self.config.ReadBool('Options/ExecStartupScript', True)
              self.showPySlicesTutorial = \
                   self.config.ReadBool('Options/ShowPySlicesTutorial', True)
              self.enableShellMode = \
                   self.config.ReadBool('Options/EnableShellMode', False)
              self.enableAutoSympy = \
                   self.config.ReadBool('Options/EnableAutoSympy', True)
              self.hideFoldingMargin = \
                   self.config.ReadBool('Options/HideFoldingMargin', True)
  
      def OnHelp(self, event):
          """Display a Help window."""
          import  wx.lib.dialogs
          title = 'Help on key bindings'
  
          text = wx.py.shell.HELP_TEXT
  
          dlg = wx.lib.dialogs.ScrolledMessageDialog(self, text, title,
                                                     size = ((700, 540)))
          fnt = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
          dlg.GetChildren()[0].SetFont(fnt)
          dlg.GetChildren()[0].SetInsertionPoint(0)
          dlg.ShowModal()
          dlg.Destroy()
  
  
      def LoadSettings(self):
          if self.config is not None:
              self.autoSaveSettings = \
                   self.config.ReadBool('Options/AutoSaveSettings', False)
              self.execStartupScript = \
                   self.config.ReadBool('Options/ExecStartupScript', True)
              self.autoSaveHistory = \
                   self.config.ReadBool('Options/AutoSaveHistory', False)
  
              self.showPySlicesTutorial = \
                   self.config.ReadBool('Options/ShowPySlicesTutorial', True)
              self.enableShellMode = \
                   self.config.ReadBool('Options/EnableShellMode', False)
              self.enableAutoSympy = \
                   self.config.ReadBool('Options/EnableAutoSympy', True)
              self.hideFoldingMargin = \
                   self.config.ReadBool('Options/HideFoldingMargin', True)
  
              self.LoadHistory()
  
  
      def SaveSettings(self, force=False):
          if self.config is not None:
              # always save these
              self.config.WriteBool('Options/AutoSaveSettings',
                                    self.autoSaveSettings)
  
              if self.autoSaveSettings or force:
                  self.config.WriteBool('Options/AutoSaveHistory',
                                        self.autoSaveHistory)
                  self.config.WriteBool('Options/ExecStartupScript',
                                        self.execStartupScript)
                  self.config.WriteBool('Options/ShowPySlicesTutorial',
                                        self.showPySlicesTutorial)
                  self.config.WriteBool('Options/EnableShellMode',
                                        self.enableShellMode)
                  self.config.WriteBool('Options/EnableAutoSympy',
                                        self.enableAutoSympy)
                  self.config.WriteBool('Options/HideFoldingMargin',
                                        self.hideFoldingMargin)
              if self.autoSaveHistory:
                  self.SaveHistory()
  
  
  
      def SaveHistory(self):
          if self.dataDir:
              try:
                  name = os.path.join(self.dataDir, 'history')
                  f = open(name, 'wb')
                  hist = []
                  enc = 'utf-8'
                  for h in self.shell.history:
                      h = h.encode(enc)
                      hist.append(h)
                  hist = b'\x00\n'.join(hist)
                  f.write(hist)
                  f.close()
              except:
                  d = wx.MessageDialog(self, "Error saving history file.",
                                       "Error", wx.ICON_EXCLAMATION|wx.OK)
                  d.ShowModal()
                  d.Destroy()
                  raise
  
      def LoadHistory(self):
          if self.dataDir:
              name = os.path.join(self.dataDir, 'history')
              if os.path.exists(name):
                  try:
                      f = open(name, 'rb')
                      hist = f.read()
                      f.close()
                      enc = 'utf-8'
                      hist = [h.decode(enc) for h in hist.split(b'\x00\n')]
                      self.shell.history = hist
                      dispatcher.send(signal="Shell.loadHistory",
                                      history=self.shell.history)
                  except:
                      import traceback
                      traceback.print_exc()
  
                      d = wx.MessageDialog(self, "Error loading history file.",
                                           "Error", wx.ICON_EXCLAMATION|wx.OK)
                      d.ShowModal()
                      d.Destroy()
  
  
      def bufferHasChanged(self):
          # the shell buffers can always be saved
          return True
  
      def bufferSave(self):
          import time
          appname = wx.GetApp().GetAppName()
          default = appname + '-' + time.strftime("%Y%m%d-%H%M.py")
          fileName = wx.FileSelector("Save File As", "Saving",
                                    default_filename=default,
                                    default_extension="py",
                                    wildcard="*.py",
                                    flags = wx.SAVE | wx.OVERWRITE_PROMPT)
          if not fileName:
              return
  
          text = self.shell.GetText()
  
  ## This isn't working currently...
  ##         d = wx.MessageDialog(self,u'Save source code only?\n' + \
  ##              'Answering yes will only save lines starting with >>> and ...',
  ##            u'Question', wx.YES_NO | wx.ICON_QUESTION)
  ##         yes_no = d.ShowModal()
  ##         if yes_no == wx.ID_YES:
  ##             m = re.findall('^[>\.]{3,3} (.*)\r', text, re.MULTILINE | re.LOCALE)
  ##             text = '\n'.join(m)
  ##         d.Destroy()
  
          try:
              f = open(fileName, "w")
              f.write(text)
              f.close()
          except:
              d = wx.MessageDialog(self, u'Error saving session',u'Error',
                                   wx.OK | wx.ICON_ERROR)
              d.ShowModal()
              d.Destroy()
  
  
      def EditStartupScript(self):
          if os.path.exists(self.startupScript):
              text = open(self.startupScript, 'U').read()
          else:
              text = ''
  
          dlg = EditStartupScriptDialog(self, self.startupScript, text)
          if dlg.ShowModal() == wx.ID_OK:
              text = dlg.GetText()
              try:
                  f = open(self.startupScript, 'w')
                  f.write(text)
                  f.close()
              except:
                  d = wx.MessageDialog(self, "Error saving startup file.",
                                       "Error", wx.ICON_EXCLAMATION|wx.OK)
                  d.ShowModal()
                  d.Destroy()
  
  
  
  class EditStartupScriptDialog(wx.Dialog):
      def __init__(self, parent, fileName, text):
          wx.Dialog.__init__(self, parent, size=(425,350),
                             title="Edit Startup Script",
                             style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
  
          pst = wx.StaticText(self, -1, "Path:")
          ptx = wx.TextCtrl(self, -1, fileName, style=wx.TE_READONLY)
          self.editor = editwindow.EditWindow(self)
          self.editor.SetText(text)
          wx.CallAfter(self.editor.SetFocus)
  
          ok = wx.Button(self, wx.ID_OK)
          cancel = wx.Button(self, wx.ID_CANCEL)
  
          mainSizer = wx.BoxSizer(wx.VERTICAL)
  
          pthSizer = wx.BoxSizer(wx.HORIZONTAL)
          pthSizer.Add(pst, flag=wx.ALIGN_CENTER_VERTICAL)
          pthSizer.Add((5,5))
          pthSizer.Add(ptx, 1)
          mainSizer.Add(pthSizer, 0, wx.EXPAND|wx.ALL, 10)
  
          mainSizer.Add(self.editor, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 10)
  
          btnSizer = wx.BoxSizer(wx.HORIZONTAL)
          btnSizer.Add((5,5), 1)
          btnSizer.Add(ok)
          btnSizer.Add((5,5), 1)
          btnSizer.Add(cancel)
          btnSizer.Add((5,5), 1)
          mainSizer.Add(btnSizer, 0, wx.EXPAND|wx.ALL, 10)
  
          self.SetSizer(mainSizer)
          self.Layout()
  
  
      def GetText(self):
          return self.editor.GetText()
  