From e773f79b191e77649b07f527a08405863a1cb117 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Fri, 24 Feb 2006 01:21:26 +0000 Subject: [PATCH] Allow clearing the history, and saving the history on demand Let the session tab show all of the history Fix case-sensitive searches to actually allow case-insensitive Make wx.WXK_NUMPAD_ENTER equivalent to wx.WXK_RETURN git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37696 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/wx/py/crust.py | 36 +++++++++++++++----- wxPython/wx/py/editwindow.py | 6 ++-- wxPython/wx/py/frame.py | 66 +++++++++++++++++++++++++----------- wxPython/wx/py/shell.py | 19 +++++++---- 4 files changed, 90 insertions(+), 37 deletions(-) diff --git a/wxPython/wx/py/crust.py b/wxPython/wx/py/crust.py index 371638f604..4dea629362 100644 --- a/wxPython/wx/py/crust.py +++ b/wxPython/wx/py/crust.py @@ -63,7 +63,7 @@ class Crust(wx.SplitterWindow): self.notebook.AddPage(page=self.calltip, text='Calltip') self.sessionlisting = SessionListing(parent=self.notebook) - self.notebook.AddPage(page=self.sessionlisting, text='Session') + self.notebook.AddPage(page=self.sessionlisting, text='History') self.dispatcherlisting = DispatcherListing(parent=self.notebook) self.notebook.AddPage(page=self.dispatcherlisting, text='Dispatcher') @@ -162,6 +162,10 @@ class Calltip(wx.TextCtrl): self.SetBackgroundColour(wx.Colour(255, 255, 208)) dispatcher.connect(receiver=self.display, signal='Shell.calltip') + df = self.GetFont() + font = wx.Font(df.GetPointSize(), wx.TELETYPE, wx.NORMAL, wx.NORMAL) + self.SetFont(font) + def display(self, calltip): """Receiver for Shell.calltip signal.""" ## self.SetValue(calltip) # Caused refresh problem on Windows. @@ -177,17 +181,29 @@ class SessionListing(wx.TextCtrl): 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.push, signal='Interpreter.push') + dispatcher.connect(receiver=self.addHistory, signal="Shell.addHistory") + dispatcher.connect(receiver=self.clearHistory, signal="Shell.clearHistory") + dispatcher.connect(receiver=self.loadHistory, signal="Shell.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 push(self, command, more): - """Receiver for Interpreter.push signal.""" - if command and not more: + def addHistory(self, command): + if command: self.SetInsertionPointEnd() - start, end = self.GetSelection() - if start != end: - self.SetSelection(0, 0) self.AppendText(command + '\n') + def clearHistory(self): + self.SetValue("") + class DispatcherListing(wx.TextCtrl): """Text control containing all dispatches for session.""" @@ -198,6 +214,10 @@ class DispatcherListing(wx.TextCtrl): 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) diff --git a/wxPython/wx/py/editwindow.py b/wxPython/wx/py/editwindow.py index 808e1785f3..26c419c696 100644 --- a/wxPython/wx/py/editwindow.py +++ b/wxPython/wx/py/editwindow.py @@ -251,13 +251,13 @@ class EditWindow(stc.StyledTextCtrl): def DoFindNext(self, findData, findDlg=None): backward = not (findData.GetFlags() & wx.FR_DOWN) - matchcase = findData.GetFlags() & wx.FR_MATCHCASE + matchcase = (findData.GetFlags() & wx.FR_MATCHCASE) != 0 end = self.GetLastPosition() textstring = self.GetRange(0, end) findstring = findData.GetFindString() if not matchcase: - textstring.lower() - findstring.lower() + textstring = textstring.lower() + findstring = findstring.lower() if backward: start = self.GetSelection()[0] loc = textstring.rfind(findstring, 0, start) diff --git a/wxPython/wx/py/frame.py b/wxPython/wx/py/frame.py index fcdb14c85e..9c05c4787d 100644 --- a/wxPython/wx/py/frame.py +++ b/wxPython/wx/py/frame.py @@ -8,6 +8,7 @@ import wx import os from version import VERSION import editwindow +import dispatcher ID_NEW = wx.ID_NEW ID_OPEN = wx.ID_OPEN @@ -44,6 +45,8 @@ ID_USEAA = wx.NewId() ID_SHOW_LINENUMBERS = wx.NewId() ID_AUTO_SAVESETTINGS = wx.NewId() ID_SAVEHISTORY = wx.NewId() +ID_SAVEHISTORYNOW = wx.NewId() +ID_CLEARHISTORY = wx.NewId() ID_SAVESETTINGS = wx.NewId() ID_DELSETTINGSFILE = wx.NewId() ID_EDITSTARTUPSCRIPT = wx.NewId() @@ -138,9 +141,9 @@ class Frame(wx.Frame): m.Append(ID_SELECTALL, 'Select A&ll \tCtrl+A', 'Select all text') m.AppendSeparator() - m.Append(ID_EMPTYBUFFER, 'E&mpty Buffer', + m.Append(ID_EMPTYBUFFER, 'E&mpty Buffer...', 'Delete all the contents of the edit buffer') - m.Append(ID_FIND, '&Find Text \tCtrl+F', + m.Append(ID_FIND, '&Find Text... \tCtrl+F', 'Search for text in the edit buffer') m.Append(ID_FINDNEXT, 'Find &Next \tF3', 'Find next/previous instance of the search text') @@ -180,14 +183,22 @@ class Frame(wx.Frame): 'Use anti-aliased fonts', wx.ITEM_CHECK) m.AppendSeparator() - m.Append(ID_SAVEHISTORY, '&Save History', + + 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.AppendMenu(-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...', 'Edit Startup Script') m.AppendMenu(ID_STARTUP, '&Startup', self.startupMenu, 'Startup Options') @@ -249,6 +260,8 @@ class Frame(wx.Frame): self.Bind(wx.EVT_MENU, self.OnShowLineNumbers, id=ID_SHOW_LINENUMBERS) 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) @@ -288,6 +301,8 @@ class Frame(wx.Frame): 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_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) @@ -436,7 +451,13 @@ class Frame(wx.Frame): win.SetUseAntiAliasing(event.IsChecked()) def OnSaveHistory(self, event): - self.saveHistory = event.IsChecked() + self.autoSaveHistory = event.IsChecked() + + def OnSaveHistoryNow(self, event): + self.SaveHistory() + + def OnClearHistory(self, event): + self.shell.clearHistory() def OnAutoSaveSettings(self, event): self.autoSaveSettings = event.IsChecked() @@ -474,6 +495,9 @@ class Frame(wx.Frame): self.findDlg.Show() def OnFindNext(self, event): + if not self.findData.GetFindString(): + self.OnFindText(event) + return if isinstance(event, wx.FindDialogEvent): win = self.findDlg.GetParent() else: @@ -567,8 +591,14 @@ class Frame(wx.Frame): event.Enable(self.config is not None) elif id == ID_SAVEHISTORY: - event.Check(self.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) @@ -576,9 +606,8 @@ class Frame(wx.Frame): elif id == ID_FIND: event.Enable(hasattr(win, 'DoFindNext')) elif id == ID_FINDNEXT: - event.Enable(hasattr(win, 'DoFindNext') and - self.findData.GetFindString() != '') - + event.Enable(hasattr(win, 'DoFindNext')) + else: event.Enable(False) except AttributeError: @@ -645,7 +674,7 @@ class ShellFrameMixin: self.startupScript = os.path.join(self.dataDir, 'startup') self.autoSaveSettings = False - self.saveHistory = False + self.autoSaveHistory = False # We need this one before we have a chance to load the settings... self.execStartupScript = True @@ -672,7 +701,7 @@ class ShellFrameMixin: if self.config is not None: self.autoSaveSettings = self.config.ReadBool('Options/AutoSaveSettings', False) self.execStartupScript = self.config.ReadBool('Options/ExecStartupScript', True) - self.saveHistory = self.config.ReadBool('Options/SaveHistory', False) + self.autoSaveHistory = self.config.ReadBool('Options/AutoSaveHistory', False) self.LoadHistory() @@ -681,8 +710,9 @@ class ShellFrameMixin: # always save this one self.config.WriteBool('Options/AutoSaveSettings', self.autoSaveSettings) if self.autoSaveSettings: - self.config.WriteBool('Options/SaveHistory', self.saveHistory) + self.config.WriteBool('Options/AutoSaveHistory', self.autoSaveHistory) self.config.WriteBool('Options/ExecStartupScript', self.execStartupScript) + if self.autoSaveHistory: self.SaveHistory() @@ -690,20 +720,17 @@ class ShellFrameMixin: def SaveHistory(self): if self.dataDir: try: - # always open the file so that when we are not - # saving the history, the old file is emptied. name = os.path.join(self.dataDir, 'history') f = file(name, 'w') - if self.saveHistory: - hist = '\n'.join(self.shell.history) - f.write(hist) + hist = '\x00\n'.join(self.shell.history) + f.write(hist) f.close() except: d = wx.MessageDialog(self, "Error saving history file.", "Error", wx.ICON_EXCLAMATION) d.ShowModal() d.Destroy() - + raise def LoadHistory(self): if self.dataDir: @@ -713,7 +740,8 @@ class ShellFrameMixin: f = file(name, 'U') hist = f.read() f.close() - self.shell.history = hist.split('\n') + self.shell.history = hist.split('\x00\n') + dispatcher.send(signal="Shell.loadHistory", history=self.shell.history) except: d = wx.MessageDialog(self, "Error loading history file.", "Error", wx.ICON_EXCLAMATION) diff --git a/wxPython/wx/py/shell.py b/wxPython/wx/py/shell.py index de8c88c90c..dbd4c268dd 100644 --- a/wxPython/wx/py/shell.py +++ b/wxPython/wx/py/shell.py @@ -147,10 +147,9 @@ Ctrl+[ Decrease font size. Ctrl+= Default font size. Ctrl-Space Show Auto Completion. Ctrl-Alt-Space Show Call Tip. -Alt+Shift+C Clear Screen. Shift+Enter Complete Text from History. -Ctrl+F Search (backwards) TODO: regexp-wholeWords-... -Ctrl+G Search next +Ctrl+F Search +F3 Search next Ctrl+H "hide" lines containing selection / "unhide" F12 on/off "free-edit" mode """ @@ -321,6 +320,11 @@ class Shell(editwindow.EditWindow): wx.CallAfter(self.ScrollToLine, 0) + def clearHistory(self): + self.history = [] + self.historyIndex = -1 + dispatcher.send(signal="Shell.clearHistory") + def destroy(self): del self.interp @@ -416,7 +420,7 @@ Platform: %s""" % \ currpos = self.GetCurrentPos() stoppos = self.promptPosEnd # Return (Enter) needs to be ignored in this handler. - if key == wx.WXK_RETURN: + if key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: pass elif key in self.autoCompleteKeys: # Usually the dot (period) key activates auto completion. @@ -512,17 +516,17 @@ Platform: %s""" % \ # Return (Enter) is used to submit a command to the # interpreter. - if (not controlDown and not shiftDown and not altDown) and key == wx.WXK_RETURN: + if (not controlDown and not shiftDown and not altDown) and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: if self.CallTipActive(): self.CallTipCancel() self.processLine() # Complete Text (from already typed words) - elif shiftDown and key == wx.WXK_RETURN: + elif shiftDown and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: self.OnShowCompHistory() # Ctrl+Return (Ctrl+Enter) is used to insert a line break. - elif controlDown and key == wx.WXK_RETURN: + elif controlDown and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: if self.CallTipActive(): self.CallTipCancel() if currpos == endpos: @@ -918,6 +922,7 @@ Platform: %s""" % \ if command != '' \ and (len(self.history) == 0 or command != self.history[0]): self.history.insert(0, command) + dispatcher.send(signal="Shell.addHistory", command=command) def write(self, text): """Display text in the shell. -- 2.45.2