--- a/QScintilla/Shell.py Wed May 02 19:10:17 2012 +0200 +++ b/QScintilla/Shell.py Fri May 04 20:06:17 2012 +0200 @@ -10,9 +10,9 @@ import sys import re -from PyQt4.QtCore import QFileInfo, Qt, QEvent +from PyQt4.QtCore import pyqtSignal, QFileInfo, Qt, QEvent from PyQt4.QtGui import QDialog, QInputDialog, QApplication, QClipboard, QMenu, \ - QPalette, QFont + QPalette, QFont, QWidget, QHBoxLayout, QVBoxLayout, QShortcut from PyQt4.Qsci import QsciScintilla from E5Gui.E5Application import e5App @@ -22,20 +22,74 @@ from .QsciScintillaCompat import QsciScintillaCompat import Preferences + import UI.PixmapCache +from UI.SearchWidget import SearchWidget from Debugger.DebugClientCapabilities import HasCompleter from .ShellHistoryDialog import ShellHistoryDialog +class ShellAssembly(QWidget): + """ + Class implementing the containing widget for the shell. + """ + def __init__(self, dbs, vm, horizontal=True, parent=None): + """ + Constructor + + @param dbs reference to the debug server object + @param vm reference to the viewmanager object + @param horizontal flag indicating a horizontal layout (boolean) + @param parent parent widget (QWidget) + """ + super().__init__(parent) + + self.__shell = Shell(dbs, vm, self) + self.__searchWidget = SearchWidget(self.__shell, self, horizontal) + self.__searchWidget.hide() + + if horizontal: + self.__layout = QHBoxLayout(self) + else: + self.__layout = QVBoxLayout(self) + self.__layout.setContentsMargins(1, 1, 1, 1) + self.__layout.addWidget(self.__shell) + self.__layout.addWidget(self.__searchWidget) + + self.__searchWidget.searchNext.connect(self.__shell.searchNext) + self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev) + self.__shell.searchStringFound.connect(self.__searchWidget.searchStringFound) + + def showFind(self, txt=""): + """ + Public method to display the search widget. + + @param txt text to be shown in the combo (string) + """ + self.__searchWidget.showFind(txt) + + def shell(self): + """ + Public method to get a reference to the terminal widget. + + @return reference to the terminal widget (Terminal) + """ + return self.__shell + + class Shell(QsciScintillaCompat): """ Class implementing a graphical Python shell. A user can enter commands that are executed in the remote Python interpreter. + + @signal searchStringFound(found) emitted to indicate the search result (boolean) """ + searchStringFound = pyqtSignal(bool) + def __init__(self, dbs, vm, parent=None): """ Constructor @@ -48,6 +102,8 @@ self.setUtf8(True) self.vm = vm + self.__mainWindow = parent + self.__lastSearch = () self.linesepRegExp = r"\r\n|\n|\r" @@ -160,6 +216,8 @@ self.menu.addAction(self.trUtf8('Paste'), self.paste) self.menu.addMenu(self.hmenu) self.menu.addSeparator() + self.menu.addAction(self.trUtf8('Find'), self.__find) + self.menu.addSeparator() self.menu.addAction(self.trUtf8('Clear'), self.clear) self.menu.addAction(self.trUtf8('Reset'), self.__reset) self.menu.addAction(self.trUtf8('Reset and Clear'), @@ -1458,6 +1516,12 @@ self.addActions(self.vm.editorActGrp.actions()) self.addActions(self.vm.copyActGrp.actions()) self.addActions(self.vm.viewActGrp.actions()) + self.__searchShortcut = QShortcut(self.vm.searchAct.shortcut(), self, + self.__find, self.__find) + self.__searchNextShortcut = QShortcut(self.vm.searchNextAct.shortcut(), self, + self.__searchNext, self.__searchNext) + self.__searchPrevShortcut = QShortcut(self.vm.searchPrevAct.shortcut(), self, + self.__searchPrev, self.__searchPrev) try: self.vm.editActGrp.setEnabled(False) @@ -1467,6 +1531,9 @@ self.vm.searchActGrp.setEnabled(False) except AttributeError: pass + self.__searchShortcut.setEnabled(True) + self.__searchNextShortcut.setEnabled(True) + self.__searchPrevShortcut.setEnabled(True) self.setCaretWidth(self.caretWidth) self.setCursorFlashTime(QApplication.cursorFlashTime()) @@ -1482,6 +1549,9 @@ self.vm.editorActGrp.setEnabled(False) except AttributeError: pass + self.__searchShortcut.setEnabled(False) + self.__searchNextShortcut.setEnabled(False) + self.__searchPrevShortcut.setEnabled(False) self.setCaretWidth(0) super().focusOutEvent(event) @@ -1505,3 +1575,57 @@ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("shellPage") + + def __find(self): + """ + Private slot to show the find widget. + """ + txt = self.selectedText() + self.__mainWindow.showFind(txt) + + def __searchNext(self): + """ + Private method to search for the next occurrence. + """ + if self.__lastSearch: + self.searchNext(*self.__lastSearch) + + def searchNext(self, txt, caseSensitive, wholeWord): + """ + Public method to search the next occurrence of the given text. + + @param txt text to search for (string) + @param caseSensitive flag indicating to perform a case sensitive + search (boolean) + @param wholeWord flag indicating to search for whole words + only (boolean) + """ + self.__lastSearch = (txt, caseSensitive, wholeWord) + ok = self.findFirst(txt, False, caseSensitive, wholeWord, False, forward=True) + self.searchStringFound.emit(ok) + + def __searchPrev(self): + """ + Private method to search for the next occurrence. + """ + if self.__lastSearch: + self.searchPrev(*self.__lastSearch) + + def searchPrev(self, txt, caseSensitive, wholeWord): + """ + Public method to search the previous occurrence of the given text. + + @param txt text to search for (string) + @param caseSensitive flag indicating to perform a case sensitive + search (boolean) + @param wholeWord flag indicating to search for whole words + only (boolean) + """ + self.__lastSearch = (txt, caseSensitive, wholeWord) + if self.hasSelectedText(): + line, index = self.getSelection()[:2] + else: + line, index = -1, -1 + ok = self.findFirst(txt, False, caseSensitive, wholeWord, False, forward=False, + line=line, index=index) + self.searchStringFound.emit(ok)