Tue, 12 Jan 2010 18:36:05 +0000
Renamed e5App to e5App.
# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2010 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing a simple terminal based on QScintilla. """ import sys import os import re from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.Qsci import QsciScintilla from E4Gui.E4Application import e5App from . import Lexers from .QsciScintillaCompat import QsciScintillaCompat, QSCINTILLA_VERSION import Preferences import Utilities import UI.PixmapCache from .ShellHistoryDialog import ShellHistoryDialog class Terminal(QsciScintillaCompat): """ Class implementing a simple terminal based on QScintilla. A user can enter commands that are executed by a shell process. """ def __init__(self, vm, parent = None): """ Constructor @param vm reference to the viewmanager object @param parent parent widget (QWidget) """ QsciScintillaCompat.__init__(self, parent) self.setUtf8(True) self.vm = vm self.linesepRegExp = r"\r\n|\n|\r" self.setWindowTitle(self.trUtf8('Terminal')) self.setWhatsThis(self.trUtf8( """<b>The Terminal Window</b>""" """<p>This is a very simple terminal like window, that runs a shell""" """ process in the background.</p>""" """<p>The process can be stopped and started via the context menu. Some""" """ Ctrl command may be sent as well. However, the shell may ignore""" """ them.</p>""" """<p>You can use the cursor keys while entering commands. There is also a""" """ history of commands that can be recalled using the up and down cursor""" """ keys. Pressing the up or down key after some text has been entered will""" """ start an incremental search.</p>""" )) self.ansi_re = re.compile("\033\[\??[\d;]*\w") # Initialise instance variables. self.prline = 0 self.prcol = 0 self.inDragDrop = False self.lexer_ = None # Initialize history self.maxHistoryEntries = Preferences.getTerminal("MaxHistoryEntries") self.history = [] self.histidx = -1 # clear QScintilla defined keyboard commands # we do our own handling through the view manager self.clearAlternateKeys() self.clearKeys() self.__actionsAdded = False # Create the history context menu self.hmenu = QMenu(self.trUtf8('History')) self.hmenu.addAction(self.trUtf8('Select entry'), self.__selectHistory) self.hmenu.addAction(self.trUtf8('Show'), self.__showHistory) self.hmenu.addAction(self.trUtf8('Clear'), self.__clearHistory) # Create a little context menu to send Ctrl-C, Ctrl-D or Ctrl-Z self.csm = QSignalMapper(self) self.connect(self.csm, SIGNAL('mapped(int)'), self.__sendCtrl) self.cmenu = QMenu(self.trUtf8('Ctrl Commands')) act = self.cmenu.addAction(self.trUtf8('Ctrl-C')) self.csm.setMapping(act, 3) self.connect(act, SIGNAL('triggered()'), self.csm, SLOT('map()')) act = self.cmenu.addAction(self.trUtf8('Ctrl-D')) self.csm.setMapping(act, 4) self.connect(act, SIGNAL('triggered()'), self.csm, SLOT('map()')) act = self.cmenu.addAction(self.trUtf8('Ctrl-Z')) self.csm.setMapping(act, 26) self.connect(act, SIGNAL('triggered()'), self.csm, SLOT('map()')) # Create a little context menu self.menu = QMenu(self) self.menu.addAction(self.trUtf8('Cut'), self.cut) self.menu.addAction(self.trUtf8('Copy'), self.copy) self.menu.addAction(self.trUtf8('Paste'), self.paste) self.menu.addMenu(self.hmenu) self.menu.addSeparator() self.menu.addAction(self.trUtf8('Clear'), self.clear) self.__startAct = self.menu.addAction(self.trUtf8("Start"), self.__startShell) self.__stopAct = self.menu.addAction(self.trUtf8("Stop"), self.__stopShell) self.__resetAct = self.menu.addAction(self.trUtf8('Reset'), self.__reset) self.menu.addSeparator() self.__ctrlAct = self.menu.addMenu(self.cmenu) self.menu.addSeparator() self.menu.addAction(self.trUtf8("Configure..."), self.__configure) self.__bindLexer() self.__setTextDisplay() self.__setMargin0() self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.incrementalSearchString = "" self.incrementalSearchActive = False self.supportedEditorCommands = { QsciScintilla.SCI_LINEDELETE : self.__clearCurrentLine, QsciScintilla.SCI_NEWLINE : self.__QScintillaNewline, QsciScintilla.SCI_DELETEBACK : self.__QScintillaDeleteBack, QsciScintilla.SCI_CLEAR : self.__QScintillaDelete, QsciScintilla.SCI_DELWORDLEFT : self.__QScintillaDeleteWordLeft, QsciScintilla.SCI_DELWORDRIGHT : self.__QScintillaDeleteWordRight, QsciScintilla.SCI_DELLINELEFT : self.__QScintillaDeleteLineLeft, QsciScintilla.SCI_DELLINERIGHT : self.__QScintillaDeleteLineRight, QsciScintilla.SCI_CHARLEFT : self.__QScintillaCharLeft, QsciScintilla.SCI_CHARRIGHT : self.__QScintillaCharRight, QsciScintilla.SCI_WORDLEFT : self.__QScintillaWordLeft, QsciScintilla.SCI_WORDRIGHT : self.__QScintillaWordRight, QsciScintilla.SCI_VCHOME : self.__QScintillaVCHome, QsciScintilla.SCI_LINEEND : self.__QScintillaLineEnd, QsciScintilla.SCI_LINEUP : self.__QScintillaLineUp, QsciScintilla.SCI_LINEDOWN : self.__QScintillaLineDown, QsciScintilla.SCI_CHARLEFTEXTEND : self.__QScintillaCharLeftExtend, QsciScintilla.SCI_CHARRIGHTEXTEND : self.extendSelectionRight, QsciScintilla.SCI_WORDLEFTEXTEND : self.__QScintillaWordLeftExtend, QsciScintilla.SCI_WORDRIGHTEXTEND : self.extendSelectionWordRight, QsciScintilla.SCI_VCHOMEEXTEND : self.__QScintillaVCHomeExtend, QsciScintilla.SCI_LINEENDEXTEND : self.extendSelectionToEOL, } self.__ioEncoding = Preferences.getSystem("IOEncoding") self.__process = QProcess() self.__process.setProcessChannelMode(QProcess.MergedChannels) self.__process.setReadChannel(QProcess.StandardOutput) self.connect(self.__process, SIGNAL("readyReadStandardOutput()"), self.__readOutput) self.connect(self.__process, SIGNAL("started()"), self.__started) self.connect(self.__process, SIGNAL("finished(int)"), self.__finished) self.__ctrl = {} for ascii_number, letter in enumerate("abcdefghijklmnopqrstuvwxyz"): self.__ctrl[letter] = chr(ascii_number + 1) self.__lastPos = (0, 0) self.__startShell() def __readOutput(self): """ Private method to process the output of the shell. """ output = str(self.__process.readAllStandardOutput(), self.__ioEncoding, 'replace') self.__write(self.ansi_re.sub("", output)) self.__lastPos = self.__getEndPos() def __started(self): """ Private method called, when the shell process has started. """ if not Utilities.isWindowsPlatform(): QTimer.singleShot(250, self.clear) self.__startAct.setEnabled(False) self.__stopAct.setEnabled(True) self.__resetAct.setEnabled(True) self.__ctrlAct.setEnabled(True) def __finished(self): """ Private method called, when the shell process has finished. """ QsciScintilla.clear(self) self.__startAct.setEnabled(True) self.__stopAct.setEnabled(False) self.__resetAct.setEnabled(False) self.__ctrlAct.setEnabled(False) def __send(self, data): """ Private method to send data to the shell process. @param data data to be sent to the shell process (string) """ pdata = QByteArray() pdata.append(data) self.__process.write(pdata) def __sendCtrl(self, cmd): """ Private slot to send a control command to the shell process. @param the control command to be sent (integer) """ self.__send(chr(cmd)) def closeTerminal(self): """ Public method to shutdown the terminal. """ self.__stopShell() self.saveHistory() def __bindLexer(self): """ Private slot to set the lexer. """ if Utilities.isWindowsPlatform(): self.language = "Batch" else: self.language = "Bash" if Preferences.getTerminal("SyntaxHighlightingEnabled"): self.lexer_ = Lexers.getLexer(self.language, self) else: self.lexer_ = None if self.lexer_ is None: self.setLexer(None) font = Preferences.getTerminal("MonospacedFont") self.monospacedStyles(font) return # get the font for style 0 and set it as the default font key = 'Scintilla/%s/style0/font' % self.lexer_.language() fdesc = Preferences.Prefs.settings.value(key) if fdesc is not None: font = QFont(fdesc[0], int(fdesc[1])) self.lexer_.setDefaultFont(font) self.setLexer(self.lexer_) self.lexer_.readSettings(Preferences.Prefs.settings, "Scintilla") def __setMargin0(self): """ Private method to configure margin 0. """ # set the settings for all margins self.setMarginsFont(Preferences.getTerminal("MarginsFont")) self.setMarginsForegroundColor(Preferences.getEditorColour("MarginsForeground")) self.setMarginsBackgroundColor(Preferences.getEditorColour("MarginsBackground")) # set margin 0 settings linenoMargin = Preferences.getTerminal("LinenoMargin") self.setMarginLineNumbers(0, linenoMargin) if linenoMargin: self.setMarginWidth(0, ' ' + '8' * Preferences.getTerminal("LinenoWidth")) else: self.setMarginWidth(0, 0) # disable margins 1 and 2 self.setMarginWidth(1, 0) self.setMarginWidth(2, 0) def __setTextDisplay(self): """ Private method to configure the text display. """ self.setTabWidth(Preferences.getEditor("TabWidth")) if Preferences.getEditor("ShowWhitespace"): self.setWhitespaceVisibility(QsciScintilla.WsVisible) else: self.setWhitespaceVisibility(QsciScintilla.WsInvisible) self.setEolVisibility(Preferences.getEditor("ShowEOL")) if Preferences.getEditor("BraceHighlighting"): self.setBraceMatching(QsciScintilla.SloppyBraceMatch) else: self.setBraceMatching(QsciScintilla.NoBraceMatch) self.setMatchedBraceForegroundColor( Preferences.getEditorColour("MatchingBrace")) self.setMatchedBraceBackgroundColor( Preferences.getEditorColour("MatchingBraceBack")) self.setUnmatchedBraceForegroundColor( Preferences.getEditorColour("NonmatchingBrace")) self.setUnmatchedBraceBackgroundColor( Preferences.getEditorColour("NonmatchingBraceBack")) if Preferences.getEditor("CustomSelectionColours"): self.setSelectionBackgroundColor(\ Preferences.getEditorColour("SelectionBackground")) else: self.setSelectionBackgroundColor(\ QApplication.palette().color(QPalette.Highlight)) if Preferences.getEditor("ColourizeSelText"): self.resetSelectionForegroundColor() elif Preferences.getEditor("CustomSelectionColours"): self.setSelectionForegroundColor(\ Preferences.getEditorColour("SelectionForeground")) else: self.setSelectionForegroundColor(\ QApplication.palette().color(QPalette.HighlightedText)) self.setSelectionToEol(Preferences.getEditor("ExtendSelectionToEol")) self.setCaretForegroundColor( Preferences.getEditorColour("CaretForeground")) self.setCaretLineBackgroundColor( Preferences.getEditorColour("CaretLineBackground")) self.setCaretLineVisible(Preferences.getEditor("CaretLineVisible")) self.caretWidth = Preferences.getEditor("CaretWidth") self.setCaretWidth(self.caretWidth) self.setWrapMode(QsciScintilla.WrapNone) self.useMonospaced = Preferences.getTerminal("UseMonospacedFont") self.__setMonospaced(self.useMonospaced) def __setMonospaced(self, on): """ Private method to set/reset a monospaced font. @param on flag to indicate usage of a monospace font (boolean) """ if on: f = Preferences.getTerminal("MonospacedFont") self.monospacedStyles(f) else: if not self.lexer_: self.clearStyles() self.__setMargin0() self.setFont(Preferences.getTerminal("MonospacedFont")) self.useMonospaced = on def loadHistory(self): """ Public method to load the history. """ hl = Preferences.Prefs.settings.value("Terminal/History") if hl is not None: self.history = hl[-self.maxHistoryEntries:] else: self.history = [] def reloadHistory(self): """ Public method to reload the history. """ self.loadHistory(self.clientType) self.history = self.historyLists[self.clientType] self.histidx = -1 def saveHistory(self): """ Public method to save the history. """ Preferences.Prefs.settings.setValue("Terminal/History", self.history) def getHistory(self): """ Public method to get the history. @return reference to the history list (list of strings) """ return self.history def __clearHistory(self): """ Private slot to clear the current history. """ self.history.clear() def __selectHistory(self): """ Private slot to select a history entry to execute. """ cmd, ok = QInputDialog.getItem(\ self, self.trUtf8("Select History"), self.trUtf8("Select the history entry to execute (most recent shown last)."), self.history, 0, False) if ok: self.__insertHistory(cmd) def __showHistory(self): """ Private slot to show the shell history dialog. """ dlg = ShellHistoryDialog(self.history, self.vm, self) if dlg.exec_() == QDialog.Accepted: self.history = dlg.getHistory() self.histidx = -1 def __getEndPos(self): """ Private method to return the line and column of the last character. @return tuple of two values (int, int) giving the line and column """ line = self.lines() - 1 return (line, self.lineLength(line)) def __write(self, s): """ Private method to display some text. @param s text to be displayed (string) """ line, col = self.__getEndPos() self.setCursorPosition(line, col) self.insert(s) self.prline, self.prcol = self.getCursorPosition() self.ensureCursorVisible() self.ensureLineVisible(self.prline) def __clearCurrentLine(self): """ Private method to clear the line containing the cursor. """ line, col = self.getCursorPosition() if self.text(line).startswith(sys.ps1): col = len(sys.ps1) elif self.text(line).startswith(sys.ps2): col = len(sys.ps2) else: col = 0 self.setCursorPosition(line, col) self.deleteLineRight() def __insertText(self, s): """ Private method to insert some text at the current cursor position. @param s text to be inserted (string) """ line, col = self.getCursorPosition() self.insertAt(s, line, col) self.setCursorPosition(line, col + len(s)) def __insertTextAtEnd(self, s): """ Private method to insert some text at the end of the command line. @param s text to be inserted (string) """ line, col = self.__getEndPos() self.setCursorPosition(line, col) self.insert(s) self.prline, self.prcol = self.getCursorPosition() def mousePressEvent(self, event): """ Protected method to handle the mouse press event. @param event the mouse press event (QMouseEvent) """ self.setFocus() QsciScintillaCompat.mousePressEvent(self, event) def editorCommand(self, cmd): """ Public method to perform an editor command. @param cmd the scintilla command to be performed """ try: self.supportedEditorCommands[cmd]() except TypeError: self.supportedEditorCommands[cmd](cmd) except KeyError: pass def __isCursorOnLastLine(self): """ Private method to check, if the cursor is on the last line. """ cline, ccol = self.getCursorPosition() return cline == self.lines() - 1 def keyPressEvent(self, ev): """ Re-implemented to handle the user input a key at a time. @param ev key event (QKeyEvent) """ txt = ev.text() key = ev.key() # See it is text to insert. if len(txt) and txt >= " ": if not self.__isCursorOnLastLine(): line, col = self.__getEndPos() self.setCursorPosition(line, col) self.prline, self.prcol = self.getCursorPosition() QsciScintillaCompat.keyPressEvent(self, ev) self.incrementalSearchActive = True else: ev.ignore() def __QScintillaLeftDeleteCommand(self, method): """ Private method to handle a QScintilla delete command working to the left. @param method shell method to execute """ if self.__isCursorOnLastLine(): line, col = self.getCursorPosition() if col > self.__lastPos[1]: method() def __QScintillaDeleteBack(self): """ Private method to handle the Backspace key. """ self.__QScintillaLeftDeleteCommand(self.deleteBack) def __QScintillaDeleteWordLeft(self): """ Private method to handle the Delete Word Left command. """ self.__QScintillaLeftDeleteCommand(self.deleteWordLeft) def __QScintillaDelete(self): """ Private method to handle the delete command. """ if self.__isCursorOnLastLine(): if self.hasSelectedText(): lineFrom, indexFrom, lineTo, indexTo = self.getSelection() if indexFrom >= self.__lastPos[1]: self.delete() self.setSelection(lineTo, indexTo, lineTo, indexTo) else: self.delete() def __QScintillaDeleteLineLeft(self): """ Private method to handle the Delete Line Left command. """ if self.__isCursorOnLastLine(): if self.isListActive(): self.cancelList() line, col = self.getCursorPosition() prompt = self.text(line)[:self.__lastPos[1]] self.deleteLineLeft() self.insertAt(prompt, line, 0) self.setCursorPosition(line, len(prompt)) def __QScintillaNewline(self, cmd): """ Private method to handle the Return key. @param cmd QScintilla command """ if self.__isCursorOnLastLine(): self.incrementalSearchString = "" self.incrementalSearchActive = False line, col = self.__getEndPos() self.setCursorPosition(line, col) self.setSelection(*(self.__lastPos + self.getCursorPosition())) buf = self.selectedText() self.setCursorPosition(line, col) # select nothin self.insert('\n') self.__executeCommand(buf) def __QScintillaLeftCommand(self, method, allLinesAllowed = False): """ Private method to handle a QScintilla command working to the left. @param method shell method to execute """ if self.__isCursorOnLastLine() or allLinesAllowed: line, col = self.getCursorPosition() if col > self.__lastPos[1]: method() def __QScintillaCharLeft(self): """ Private method to handle the Cursor Left command. """ self.__QScintillaLeftCommand(self.moveCursorLeft) def __QScintillaWordLeft(self): """ Private method to handle the Cursor Word Left command. """ self.__QScintillaLeftCommand(self.moveCursorWordLeft) def __QScintillaRightCommand(self, method): """ Private method to handle a QScintilla command working to the right. @param method shell method to execute """ if self.__isCursorOnLastLine(): method() def __QScintillaCharRight(self): """ Private method to handle the Cursor Right command. """ self.__QScintillaRightCommand(self.moveCursorRight) def __QScintillaWordRight(self): """ Private method to handle the Cursor Word Right command. """ self.__QScintillaRightCommand(self.moveCursorWordRight) def __QScintillaDeleteWordRight(self): """ Private method to handle the Delete Word Right command. """ self.__QScintillaRightCommand(self.deleteWordRight) def __QScintillaDeleteLineRight(self): """ Private method to handle the Delete Line Right command. """ self.__QScintillaRightCommand(self.deleteLineRight) def __QScintillaVCHome(self, cmd): """ Private method to handle the Home key. @param cmd QScintilla command """ self.setCursorPosition(*self.__lastPos) def __QScintillaLineEnd(self, cmd): """ Private method to handle the End key. @param cmd QScintilla command """ self.moveCursorToEOL() def __QScintillaLineUp(self, cmd): """ Private method to handle the Up key. @param cmd QScintilla command """ line, col = self.__getEndPos() buf = self.text(line)[self.__lastPos[1]:] if buf and self.incrementalSearchActive: if self.incrementalSearchString: idx = self.__rsearchHistory(self.incrementalSearchString, self.histidx) if idx >= 0: self.histidx = idx self.__useHistory() else: idx = self.__rsearchHistory(buf) if idx >= 0: self.histidx = idx self.incrementalSearchString = buf self.__useHistory() else: if self.histidx < 0: self.histidx = len(self.history) if self.histidx > 0: self.histidx = self.histidx - 1 self.__useHistory() def __QScintillaLineDown(self, cmd): """ Private method to handle the Down key. @param cmd QScintilla command """ line, col = self.__getEndPos() buf = self.text(line)[self.__lastPos[1]:] if buf and self.incrementalSearchActive: if self.incrementalSearchString: idx = self.__searchHistory(self.incrementalSearchString, self.histidx) if idx >= 0: self.histidx = idx self.__useHistory() else: idx = self.__searchHistory(buf) if idx >= 0: self.histidx = idx self.incrementalSearchString = buf self.__useHistory() else: if self.histidx >= 0 and self.histidx < len(self.history): self.histidx += 1 self.__useHistory() def __QScintillaCharLeftExtend(self): """ Private method to handle the Extend Selection Left command. """ self.__QScintillaLeftCommand(self.extendSelectionLeft, True) def __QScintillaWordLeftExtend(self): """ Private method to handle the Extend Selection Left one word command. """ self.__QScintillaLeftCommand(self.extendSelectionWordLeft, True) def __QScintillaVCHomeExtend(self): """ Private method to handle the Extend Selection to start of line command. """ col = self.__lastPos[1] self.extendSelectionToBOL() while col > 0: self.extendSelectionRight() col -= 1 def __executeCommand(self, cmd): """ Private slot to execute a command. @param cmd command to be executed by debug client (string) """ if not cmd: cmd = '' if len(self.history) == 0 or self.history[-1] != cmd: if len(self.history) == self.maxHistoryEntries: del self.history[0] self.history.append(cmd) self.histidx = -1 if cmd.lower() in ["clear", "cls"]: self.clear() return else: if not cmd.endswith("\n"): cmd = "%s\n" % cmd self.__send(cmd) def __useHistory(self): """ Private method to display a command from the history. """ if self.histidx < len(self.history): cmd = self.history[self.histidx] else: cmd = "" self.incrementalSearchString = "" self.incrementalSearchActive = False self.__insertHistory(cmd) def __insertHistory(self, cmd): """ Private method to insert a command selected from the history. @param cmd history entry to be inserted (string) """ self.setCursorPosition(self.prline, self.prcol) self.setSelection(self.prline, self.prcol,\ self.prline, self.lineLength(self.prline)) self.removeSelectedText() self.__insertText(cmd) def __searchHistory(self, txt, startIdx = -1): """ Private method used to search the history. @param txt text to match at the beginning (string) @param startIdx index to start search from (integer) @return index of found entry (integer) """ if startIdx == -1: idx = 0 else: idx = startIdx + 1 while idx < len(self.history) and \ not self.history[idx].startswith(txt): idx += 1 return idx def __rsearchHistory(self, txt, startIdx = -1): """ Private method used to reverse search the history. @param txt text to match at the beginning (string) @param startIdx index to start search from (integer) @return index of found entry (integer) """ if startIdx == -1: idx = len(self.history) - 1 else: idx = startIdx - 1 while idx >= 0 and \ not self.history[idx].startswith(txt): idx -= 1 return idx def contextMenuEvent(self,ev): """ Reimplemented to show our own context menu. @param ev context menu event (QContextMenuEvent) """ self.menu.popup(ev.globalPos()) ev.accept() def clear(self): """ Public slot to clear the display. """ QsciScintillaCompat.clear(self) self.__send("\n") def __reset(self): """ Private slot to handle the 'reset' context menu entry. """ self.__stopShell() self.__startShell() def __startShell(self): """ Private slot to start the shell process. """ args = [] if Utilities.isWindowsPlatform(): args.append("/Q") self.__process.start("cmd.exe", args) else: shell = Preferences.getTerminal("Shell") if not shell: shell = os.environ.get('SHELL') if shell is None: self.__insertText(self.trUtf8("No shell has been configured.")) return if Preferences.getTerminal("ShellInteractive"): args.append("-i") self.__process.start(shell, args) def __stopShell(self): """ Private slot to stop the shell process. """ self.__process.kill() res = self.__process.waitForFinished(3000) def handlePreferencesChanged(self): """ Public slot to handle the preferencesChanged signal. """ # rebind the lexer self.__bindLexer() self.recolor() # set margin 0 configuration self.__setTextDisplay() self.__setMargin0() # do the history related stuff self.maxHistoryEntries = Preferences.getTerminal("MaxHistoryEntries") self.history = self.history[-self.maxHistoryEntries:] # do the I/O encoding self.__ioEncoding = Preferences.getSystem("IOEncoding") def focusInEvent(self, event): """ Public method called when the shell receives focus. @param event the event object (QFocusEvent) """ if not self.__actionsAdded: self.addActions(self.vm.editorActGrp.actions()) self.addActions(self.vm.copyActGrp.actions()) self.addActions(self.vm.viewActGrp.actions()) try: self.vm.editActGrp.setEnabled(False) self.vm.editorActGrp.setEnabled(True) self.vm.copyActGrp.setEnabled(True) self.vm.viewActGrp.setEnabled(True) except AttributeError: pass self.setCaretWidth(self.caretWidth) QsciScintillaCompat.focusInEvent(self, event) def focusOutEvent(self, event): """ Public method called when the shell loses focus. @param event the event object (QFocusEvent) """ try: self.vm.editorActGrp.setEnabled(False) except AttributeError: pass self.setCaretWidth(0) QsciScintillaCompat.focusOutEvent(self, event) def insert(self, txt): """ Public slot to insert text at the current cursor position. The cursor is advanced to the end of the inserted text. @param txt text to be inserted (string) """ l = len(txt) line, col = self.getCursorPosition() self.insertAt(txt, line, col) if re.search(self.linesepRegExp, txt) is not None: line += 1 self.setCursorPosition(line, col + l) def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("terminalPage")