1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2017 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Module implementing a stand alone shell window.
8"""
9
10import sys
11import os
12
13from PyQt5.QtCore import (
14    Qt, QCoreApplication, QPoint, QSize, QSignalMapper, QProcess
15)
16from PyQt5.QtGui import QKeySequence
17from PyQt5.QtWidgets import (
18    QWidget, QVBoxLayout, QApplication, QAction, QWhatsThis, QDialog
19)
20from PyQt5.Qsci import QsciScintilla
21
22from E5Gui.E5MainWindow import E5MainWindow
23from E5Gui.E5Action import E5Action, createActionGroup
24from E5Gui.E5Application import e5App
25from E5Gui.E5ZoomWidget import E5ZoomWidget
26from E5Gui import E5MessageBox
27
28import UI.Config
29import UI.PixmapCache
30import Preferences
31
32from Globals import isMacPlatform
33
34from .Shell import Shell
35from .APIsManager import APIsManager
36
37from Debugger.DebugServer import DebugServer
38from UI.SearchWidget import SearchWidget
39from VirtualEnv.VirtualenvManager import VirtualenvManager
40
41from eric6config import getConfig
42
43
44class ShellWindow(E5MainWindow):
45    """
46    Class implementing a stand alone shell window.
47    """
48    def __init__(self, originalPathString, parent=None, name=None):
49        """
50        Constructor
51
52        @param originalPathString original PATH environment variable
53        @type str
54        @param parent reference to the parent widget
55        @type QWidget
56        @param name object name of the window
57        @type str
58        """
59        super().__init__(parent)
60        if name is not None:
61            self.setObjectName(name)
62        self.setWindowIcon(UI.PixmapCache.getIcon("shell"))
63        self.setWindowTitle(self.tr("eric Shell"))
64
65        self.setStyle(Preferences.getUI("Style"),
66                      Preferences.getUI("StyleSheet"))
67
68        self.__lastDebuggerId = ""
69
70        # initialize the APIs manager
71        self.__apisManager = APIsManager(parent=self)
72
73        # initialize the debug server and shell widgets
74        self.__debugServer = DebugServer(originalPathString,
75                                         preventPassiveDebugging=True,
76                                         parent=self)
77        self.__debugServer.clientDebuggerId.connect(self.__clientDebuggerId)
78
79        self.__shell = Shell(self.__debugServer, self, None, True, self)
80        self.__shell.registerDebuggerIdMethod(self.getDebuggerId)
81
82        self.__searchWidget = SearchWidget(self.__shell, self, showLine=True)
83
84        centralWidget = QWidget()
85        layout = QVBoxLayout()
86        layout.setContentsMargins(1, 1, 1, 1)
87        layout.addWidget(self.__shell)
88        layout.addWidget(self.__searchWidget)
89        centralWidget.setLayout(layout)
90        self.setCentralWidget(centralWidget)
91        self.__searchWidget.hide()
92
93        self.__searchWidget.searchNext.connect(self.__shell.searchNext)
94        self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev)
95        self.__shell.searchStringFound.connect(
96            self.__searchWidget.searchStringFound)
97
98        self.__shell.zoomValueChanged.connect(self.__zoomValueChanged)
99
100        self.__createActions()
101        self.__createMenus()
102        self.__createToolBars()
103        self.__createStatusBar()
104
105        self.__readSettings()
106
107        self.__shell.historyStyleChanged.connect(self.__historyStyleChanged)
108
109        # Generate the virtual environment manager and register it
110        self.virtualenvManager = VirtualenvManager(self)
111        e5App().registerObject("VirtualEnvManager", self.virtualenvManager)
112
113        self.__shell.virtualEnvironmentChanged.connect(
114            self.__virtualEnvironmentChanged)
115
116        # now start the debug client with the most recently used virtual
117        # environment
118        self.__debugServer.startClient(
119            False, venvName=Preferences.getShell("LastVirtualEnvironment")
120        )
121
122        # set the keyboard input interval
123        interval = Preferences.getUI("KeyboardInputInterval")
124        if interval > 0:
125            QApplication.setKeyboardInputInterval(interval)
126
127    def closeEvent(self, event):
128        """
129        Protected method to handle the close event.
130
131        @param event close event
132        @type QCloseEvent
133        """
134        self.__writeSettings()
135        self.__debugServer.shutdownServer()
136        self.__shell.closeShell()
137        Preferences.syncPreferences()
138
139        event.accept()
140
141    def __clientDebuggerId(self, debuggerId):
142        """
143        Private slot to receive the ID of a newly connected debugger backend.
144
145        @param debuggerId ID of a newly connected debugger backend
146        @type str
147        """
148        self.__lastDebuggerId = debuggerId
149
150    def getDebuggerId(self):
151        """
152        Public method to get the most recently registered debugger ID.
153
154        @return debugger ID
155        @rtype str
156        """
157        return self.__lastDebuggerId
158
159    ##################################################################
160    ## Below are API handling methods
161    ##################################################################
162
163    def getAPIsManager(self):
164        """
165        Public method to get a reference to the APIs manager.
166
167        @return the APIs manager object (eric6.QScintilla.APIsManager)
168        """
169        return self.__apisManager
170
171    ##################################################################
172    ## Below are action related methods
173    ##################################################################
174
175    def __readShortcut(self, act, category):
176        """
177        Private function to read a single keyboard shortcut from the settings.
178
179        @param act reference to the action object
180        @type E5Action
181        @param category category the action belongs to
182        @type str
183        """
184        if act.objectName():
185            accel = Preferences.Prefs.settings.value(
186                "Shortcuts/{0}/{1}/Accel".format(category, act.objectName()))
187            if accel is not None:
188                act.setShortcut(QKeySequence(accel))
189            accel = Preferences.Prefs.settings.value(
190                "Shortcuts/{0}/{1}/AltAccel".format(
191                    category, act.objectName()))
192            if accel is not None:
193                act.setAlternateShortcut(QKeySequence(accel), removeEmpty=True)
194
195    def __createActions(self):
196        """
197        Private method to create the actions.
198        """
199        self.fileActions = []
200        self.editActions = []
201        self.searchActions = []
202        self.viewActions = []
203        self.helpActions = []
204
205        self.viewActGrp = createActionGroup(self)
206
207        self.__createFileActions()
208        self.__createEditActions()
209        self.__createSearchActions()
210        self.__createViewActions()
211        self.__createHelpActions()
212        self.__createHistoryActions()
213
214        # read the keyboard shortcuts and make them identical to the main
215        # eric shortcuts
216        for act in self.helpActions:
217            self.__readShortcut(act, "General")
218        for act in self.editActions:
219            self.__readShortcut(act, "Edit")
220        for act in self.fileActions:
221            self.__readShortcut(act, "View")
222        for act in self.searchActions:
223            self.__readShortcut(act, "Search")
224
225    def __createFileActions(self):
226        """
227        Private method defining the user interface actions for the file
228        commands.
229        """
230        self.exitAct = E5Action(
231            self.tr('Quit'),
232            UI.PixmapCache.getIcon("exit"),
233            self.tr('&Quit'),
234            QKeySequence(self.tr("Ctrl+Q", "File|Quit")),
235            0, self, 'quit')
236        self.exitAct.setStatusTip(self.tr('Quit the Shell'))
237        self.exitAct.setWhatsThis(self.tr(
238            """<b>Quit the Shell</b>"""
239            """<p>This quits the Shell window.</p>"""
240        ))
241        self.exitAct.triggered.connect(self.quit)
242        self.exitAct.setMenuRole(QAction.MenuRole.QuitRole)
243        self.fileActions.append(self.exitAct)
244
245        self.newWindowAct = E5Action(
246            self.tr('New Window'),
247            UI.PixmapCache.getIcon("newWindow"),
248            self.tr('New &Window'),
249            QKeySequence(self.tr("Ctrl+Shift+N", "File|New Window")),
250            0, self, 'new_window')
251        self.newWindowAct.setStatusTip(self.tr(
252            'Open a new Shell window'))
253        self.newWindowAct.setWhatsThis(self.tr(
254            """<b>New Window</b>"""
255            """<p>This opens a new instance of the Shell window.</p>"""
256        ))
257        self.newWindowAct.triggered.connect(self.__newWindow)
258        self.fileActions.append(self.newWindowAct)
259
260        self.restartAct = E5Action(
261            self.tr('Restart'),
262            UI.PixmapCache.getIcon("restart"),
263            self.tr('Restart'),
264            0, 0, self, 'shell_restart')
265        self.restartAct.setStatusTip(self.tr(
266            'Restart the shell'))
267        self.restartAct.setWhatsThis(self.tr(
268            """<b>Restart</b>"""
269            """<p>Restart the shell for the currently selected"""
270            """ environment.</p>"""
271        ))
272        self.restartAct.triggered.connect(self.__shell.doRestart)
273        self.fileActions.append(self.restartAct)
274
275        self.clearRestartAct = E5Action(
276            self.tr('Restart and Clear'),
277            UI.PixmapCache.getIcon("restartDelete"),
278            self.tr('Restart and Clear'),
279            Qt.Key.Key_F4, 0, self, 'shell_clear_restart')
280        self.clearRestartAct.setStatusTip(self.tr(
281            'Clear the window and restart the shell'))
282        self.clearRestartAct.setWhatsThis(self.tr(
283            """<b>Restart and Clear</b>"""
284            """<p>Clear the shell window and restart the shell for the"""
285            """ currently selected environment.</p>"""
286        ))
287        self.clearRestartAct.triggered.connect(self.__shell.doClearRestart)
288        self.fileActions.append(self.clearRestartAct)
289
290    def __createEditActions(self):
291        """
292        Private method defining the user interface actions for the edit
293        commands.
294        """
295        self.editActGrp = createActionGroup(self)
296        self.copyActGrp = createActionGroup(self.editActGrp)
297
298        self.cutAct = E5Action(
299            QCoreApplication.translate('ViewManager', 'Cut'),
300            UI.PixmapCache.getIcon("editCut"),
301            QCoreApplication.translate('ViewManager', 'Cu&t'),
302            QKeySequence(QCoreApplication.translate(
303                'ViewManager', "Ctrl+X", "Edit|Cut")),
304            QKeySequence(QCoreApplication.translate(
305                'ViewManager', "Shift+Del", "Edit|Cut")),
306            self.copyActGrp, 'vm_edit_cut')
307        self.cutAct.setStatusTip(QCoreApplication.translate(
308            'ViewManager', 'Cut the selection'))
309        self.cutAct.setWhatsThis(self.tr(
310            """<b>Cut</b>"""
311            """<p>Cut the selected text to the clipboard.</p>"""
312        ))
313        self.cutAct.triggered.connect(self.__shell.cut)
314        self.editActions.append(self.cutAct)
315
316        self.copyAct = E5Action(
317            QCoreApplication.translate('ViewManager', 'Copy'),
318            UI.PixmapCache.getIcon("editCopy"),
319            QCoreApplication.translate('ViewManager', '&Copy'),
320            QKeySequence(QCoreApplication.translate(
321                'ViewManager', "Ctrl+C", "Edit|Copy")),
322            QKeySequence(QCoreApplication.translate(
323                'ViewManager', "Ctrl+Ins", "Edit|Copy")),
324            self.copyActGrp, 'vm_edit_copy')
325        self.copyAct.setStatusTip(QCoreApplication.translate(
326            'ViewManager', 'Copy the selection'))
327        self.copyAct.setWhatsThis(self.tr(
328            """<b>Copy</b>"""
329            """<p>Copy the selected text to the clipboard.</p>"""
330        ))
331        self.copyAct.triggered.connect(self.__shell.copy)
332        self.editActions.append(self.copyAct)
333
334        self.pasteAct = E5Action(
335            QCoreApplication.translate('ViewManager', 'Paste'),
336            UI.PixmapCache.getIcon("editPaste"),
337            QCoreApplication.translate('ViewManager', '&Paste'),
338            QKeySequence(QCoreApplication.translate(
339                'ViewManager', "Ctrl+V", "Edit|Paste")),
340            QKeySequence(QCoreApplication.translate(
341                'ViewManager', "Shift+Ins", "Edit|Paste")),
342            self.copyActGrp, 'vm_edit_paste')
343        self.pasteAct.setStatusTip(QCoreApplication.translate(
344            'ViewManager', 'Paste the last cut/copied text'))
345        self.pasteAct.setWhatsThis(self.tr(
346            """<b>Paste</b>"""
347            """<p>Paste the last cut/copied text from the clipboard.</p>"""
348        ))
349        self.pasteAct.triggered.connect(self.__shell.paste)
350        self.editActions.append(self.pasteAct)
351
352        self.clearAct = E5Action(
353            QCoreApplication.translate('ViewManager', 'Clear'),
354            UI.PixmapCache.getIcon("editDelete"),
355            QCoreApplication.translate('ViewManager', 'Clear'),
356            QKeySequence(QCoreApplication.translate(
357                'ViewManager', "Alt+Shift+C", "Edit|Clear")),
358            0,
359            self.copyActGrp, 'vm_edit_clear')
360        self.clearAct.setStatusTip(QCoreApplication.translate(
361            'ViewManager', 'Clear all text'))
362        self.clearAct.setWhatsThis(self.tr(
363            """<b>Clear</b>"""
364            """<p>Delete all text.</p>"""
365        ))
366        self.clearAct.triggered.connect(self.__shell.clear)
367        self.editActions.append(self.clearAct)
368
369        self.cutAct.setEnabled(False)
370        self.copyAct.setEnabled(False)
371        self.__shell.copyAvailable.connect(self.cutAct.setEnabled)
372        self.__shell.copyAvailable.connect(self.copyAct.setEnabled)
373
374        ####################################################################
375        ## Below follow the actions for QScintilla standard commands.
376        ####################################################################
377
378        self.esm = QSignalMapper(self)
379        try:
380            self.esm.mappedInt.connect(self.__shell.editorCommand)
381        except AttributeError:
382            # pre Qt 5.15
383            self.esm.mapped[int].connect(self.__shell.editorCommand)
384
385        self.editorActGrp = createActionGroup(self)
386
387        act = E5Action(
388            QCoreApplication.translate('ViewManager', 'Delete current line'),
389            QCoreApplication.translate('ViewManager', 'Delete current line'),
390            QKeySequence(QCoreApplication.translate(
391                'ViewManager', 'Ctrl+Shift+L')),
392            0,
393            self.editorActGrp, 'vm_edit_delete_current_line')
394        self.esm.setMapping(act, QsciScintilla.SCI_LINEDELETE)
395        act.triggered.connect(self.esm.map)
396        self.editActions.append(act)
397
398        act = E5Action(
399            QCoreApplication.translate('ViewManager', 'Indent one level'),
400            QCoreApplication.translate('ViewManager', 'Indent one level'),
401            QKeySequence(QCoreApplication.translate('ViewManager', 'Tab')), 0,
402            self.editorActGrp, 'vm_edit_indent_one_level')
403        self.esm.setMapping(act, QsciScintilla.SCI_TAB)
404        act.triggered.connect(self.esm.map)
405        self.editActions.append(act)
406
407        act = E5Action(
408            QCoreApplication.translate('ViewManager', 'Insert new line'),
409            QCoreApplication.translate('ViewManager', 'Insert new line'),
410            QKeySequence(QCoreApplication.translate('ViewManager', 'Return')),
411            QKeySequence(QCoreApplication.translate('ViewManager', 'Enter')),
412            self.editorActGrp, 'vm_edit_insert_line')
413        self.esm.setMapping(act, QsciScintilla.SCI_NEWLINE)
414        act.triggered.connect(self.esm.map)
415        self.editActions.append(act)
416
417        act = E5Action(
418            QCoreApplication.translate('ViewManager',
419                                       'Delete previous character'),
420            QCoreApplication.translate('ViewManager',
421                                       'Delete previous character'),
422            QKeySequence(QCoreApplication.translate('ViewManager',
423                                                    'Backspace')),
424            0, self.editorActGrp, 'vm_edit_delete_previous_char')
425        if isMacPlatform():
426            act.setAlternateShortcut(QKeySequence(
427                QCoreApplication.translate('ViewManager', 'Meta+H')))
428        else:
429            act.setAlternateShortcut(QKeySequence(
430                QCoreApplication.translate('ViewManager', 'Shift+Backspace')))
431        self.esm.setMapping(act, QsciScintilla.SCI_DELETEBACK)
432        act.triggered.connect(self.esm.map)
433        self.editActions.append(act)
434
435        act = E5Action(
436            QCoreApplication.translate('ViewManager',
437                                       'Delete current character'),
438            QCoreApplication.translate('ViewManager',
439                                       'Delete current character'),
440            QKeySequence(QCoreApplication.translate('ViewManager', 'Del')),
441            0, self.editorActGrp, 'vm_edit_delete_current_char')
442        if isMacPlatform():
443            act.setAlternateShortcut(QKeySequence(
444                QCoreApplication.translate('ViewManager', 'Meta+D')))
445        self.esm.setMapping(act, QsciScintilla.SCI_CLEAR)
446        act.triggered.connect(self.esm.map)
447        self.editActions.append(act)
448
449        act = E5Action(
450            QCoreApplication.translate('ViewManager', 'Delete word to left'),
451            QCoreApplication.translate('ViewManager', 'Delete word to left'),
452            QKeySequence(QCoreApplication.translate(
453                'ViewManager', 'Ctrl+Backspace')),
454            0,
455            self.editorActGrp, 'vm_edit_delete_word_left')
456        self.esm.setMapping(act, QsciScintilla.SCI_DELWORDLEFT)
457        act.triggered.connect(self.esm.map)
458        self.editActions.append(act)
459
460        act = E5Action(
461            QCoreApplication.translate('ViewManager', 'Delete word to right'),
462            QCoreApplication.translate('ViewManager', 'Delete word to right'),
463            QKeySequence(QCoreApplication.translate('ViewManager',
464                                                    'Ctrl+Del')),
465            0, self.editorActGrp, 'vm_edit_delete_word_right')
466        self.esm.setMapping(act, QsciScintilla.SCI_DELWORDRIGHT)
467        act.triggered.connect(self.esm.map)
468        self.editActions.append(act)
469
470        act = E5Action(
471            QCoreApplication.translate('ViewManager', 'Delete line to left'),
472            QCoreApplication.translate('ViewManager', 'Delete line to left'),
473            QKeySequence(QCoreApplication.translate(
474                'ViewManager', 'Ctrl+Shift+Backspace')),
475            0,
476            self.editorActGrp, 'vm_edit_delete_line_left')
477        self.esm.setMapping(act, QsciScintilla.SCI_DELLINELEFT)
478        act.triggered.connect(self.esm.map)
479        self.editActions.append(act)
480
481        act = E5Action(
482            QCoreApplication.translate('ViewManager', 'Delete line to right'),
483            QCoreApplication.translate('ViewManager', 'Delete line to right'),
484            0, 0,
485            self.editorActGrp, 'vm_edit_delete_line_right')
486        if isMacPlatform():
487            act.setShortcut(QKeySequence(
488                QCoreApplication.translate('ViewManager', 'Meta+K')))
489        else:
490            act.setShortcut(QKeySequence(
491                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Del')))
492        self.esm.setMapping(act, QsciScintilla.SCI_DELLINERIGHT)
493        act.triggered.connect(self.esm.map)
494        self.editActions.append(act)
495
496        act = E5Action(
497            QCoreApplication.translate('ViewManager',
498                                       'Move left one character'),
499            QCoreApplication.translate('ViewManager',
500                                       'Move left one character'),
501            QKeySequence(QCoreApplication.translate('ViewManager', 'Left')), 0,
502            self.editorActGrp, 'vm_edit_move_left_char')
503        self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFT)
504        if isMacPlatform():
505            act.setAlternateShortcut(QKeySequence(
506                QCoreApplication.translate('ViewManager', 'Meta+B')))
507        act.triggered.connect(self.esm.map)
508        self.editActions.append(act)
509
510        act = E5Action(
511            QCoreApplication.translate('ViewManager',
512                                       'Move right one character'),
513            QCoreApplication.translate('ViewManager',
514                                       'Move right one character'),
515            QKeySequence(QCoreApplication.translate('ViewManager', 'Right')),
516            0, self.editorActGrp, 'vm_edit_move_right_char')
517        if isMacPlatform():
518            act.setAlternateShortcut(QKeySequence(
519                QCoreApplication.translate('ViewManager', 'Meta+F')))
520        self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHT)
521        act.triggered.connect(self.esm.map)
522        self.editActions.append(act)
523
524        act = E5Action(
525            QCoreApplication.translate('ViewManager', 'Move left one word'),
526            QCoreApplication.translate('ViewManager', 'Move left one word'),
527            0, 0,
528            self.editorActGrp, 'vm_edit_move_left_word')
529        if isMacPlatform():
530            act.setShortcut(QKeySequence(
531                QCoreApplication.translate('ViewManager', 'Alt+Left')))
532        else:
533            act.setShortcut(QKeySequence(
534                QCoreApplication.translate('ViewManager', 'Ctrl+Left')))
535        self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFT)
536        act.triggered.connect(self.esm.map)
537        self.editActions.append(act)
538
539        act = E5Action(
540            QCoreApplication.translate('ViewManager', 'Move right one word'),
541            QCoreApplication.translate('ViewManager', 'Move right one word'),
542            0, 0,
543            self.editorActGrp, 'vm_edit_move_right_word')
544        if not isMacPlatform():
545            act.setShortcut(QKeySequence(
546                QCoreApplication.translate('ViewManager', 'Ctrl+Right')))
547        self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHT)
548        act.triggered.connect(self.esm.map)
549        self.editActions.append(act)
550
551        act = E5Action(
552            QCoreApplication.translate(
553                'ViewManager',
554                'Move to first visible character in document line'),
555            QCoreApplication.translate(
556                'ViewManager',
557                'Move to first visible character in document line'),
558            0, 0,
559            self.editorActGrp, 'vm_edit_move_first_visible_char')
560        if not isMacPlatform():
561            act.setShortcut(QKeySequence(
562                QCoreApplication.translate('ViewManager', 'Home')))
563        self.esm.setMapping(act, QsciScintilla.SCI_VCHOME)
564        act.triggered.connect(self.esm.map)
565        self.editActions.append(act)
566
567        act = E5Action(
568            QCoreApplication.translate(
569                'ViewManager', 'Move to end of document line'),
570            QCoreApplication.translate(
571                'ViewManager', 'Move to end of document line'),
572            0, 0,
573            self.editorActGrp, 'vm_edit_move_end_line')
574        if isMacPlatform():
575            act.setShortcut(QKeySequence(
576                QCoreApplication.translate('ViewManager', 'Meta+E')))
577        else:
578            act.setShortcut(QKeySequence(
579                QCoreApplication.translate('ViewManager', 'End')))
580        self.esm.setMapping(act, QsciScintilla.SCI_LINEEND)
581        act.triggered.connect(self.esm.map)
582        self.editActions.append(act)
583
584        act = E5Action(
585            QCoreApplication.translate('ViewManager', 'Move up one line'),
586            QCoreApplication.translate('ViewManager', 'Move up one line'),
587            QKeySequence(QCoreApplication.translate('ViewManager', 'Up')), 0,
588            self.editorActGrp, 'vm_edit_move_up_line')
589        if isMacPlatform():
590            act.setAlternateShortcut(QKeySequence(
591                QCoreApplication.translate('ViewManager', 'Meta+P')))
592        self.esm.setMapping(act, QsciScintilla.SCI_LINEUP)
593        act.triggered.connect(self.esm.map)
594        self.editActions.append(act)
595
596        act = E5Action(
597            QCoreApplication.translate('ViewManager', 'Move down one line'),
598            QCoreApplication.translate('ViewManager', 'Move down one line'),
599            QKeySequence(QCoreApplication.translate('ViewManager', 'Down')), 0,
600            self.editorActGrp, 'vm_edit_move_down_line')
601        if isMacPlatform():
602            act.setAlternateShortcut(QKeySequence(
603                QCoreApplication.translate('ViewManager', 'Meta+N')))
604        self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWN)
605        act.triggered.connect(self.esm.map)
606        self.editActions.append(act)
607
608        act = E5Action(
609            self.tr('Move forward one history entry'),
610            self.tr('Move forward one history entry'),
611            QKeySequence(QCoreApplication.translate('ViewManager',
612                                                    'Ctrl+Down')),
613            0, self.editorActGrp, 'vm_edit_scroll_down_line')
614        self.esm.setMapping(act, QsciScintilla.SCI_LINESCROLLDOWN)
615        act.triggered.connect(self.esm.map)
616        self.editActions.append(act)
617
618        act = E5Action(
619            self.tr('Move back one history entry'),
620            self.tr('Move back one history entry'),
621            QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+Up')),
622            0, self.editorActGrp, 'vm_edit_scroll_up_line')
623        self.esm.setMapping(act, QsciScintilla.SCI_LINESCROLLUP)
624        act.triggered.connect(self.esm.map)
625        self.editActions.append(act)
626
627        act = E5Action(
628            QCoreApplication.translate('ViewManager', 'Move up one page'),
629            QCoreApplication.translate('ViewManager', 'Move up one page'),
630            QKeySequence(QCoreApplication.translate('ViewManager', 'PgUp')), 0,
631            self.editorActGrp, 'vm_edit_move_up_page')
632        self.esm.setMapping(act, QsciScintilla.SCI_PAGEUP)
633        act.triggered.connect(self.esm.map)
634        self.editActions.append(act)
635
636        act = E5Action(
637            QCoreApplication.translate('ViewManager', 'Move down one page'),
638            QCoreApplication.translate('ViewManager', 'Move down one page'),
639            QKeySequence(QCoreApplication.translate('ViewManager', 'PgDown')),
640            0, self.editorActGrp, 'vm_edit_move_down_page')
641        if isMacPlatform():
642            act.setAlternateShortcut(QKeySequence(
643                QCoreApplication.translate('ViewManager', 'Meta+V')))
644        self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWN)
645        act.triggered.connect(self.esm.map)
646        self.editActions.append(act)
647
648        act = E5Action(
649            QCoreApplication.translate('ViewManager', 'Escape'),
650            QCoreApplication.translate('ViewManager', 'Escape'),
651            QKeySequence(QCoreApplication.translate('ViewManager', 'Esc')), 0,
652            self.editorActGrp, 'vm_edit_escape')
653        self.esm.setMapping(act, QsciScintilla.SCI_CANCEL)
654        act.triggered.connect(self.esm.map)
655        self.editActions.append(act)
656
657        act = E5Action(
658            QCoreApplication.translate(
659                'ViewManager', 'Extend selection left one character'),
660            QCoreApplication.translate(
661                'ViewManager', 'Extend selection left one character'),
662            QKeySequence(QCoreApplication.translate('ViewManager',
663                                                    'Shift+Left')),
664            0, self.editorActGrp, 'vm_edit_extend_selection_left_char')
665        if isMacPlatform():
666            act.setAlternateShortcut(QKeySequence(
667                QCoreApplication.translate('ViewManager', 'Meta+Shift+B')))
668        self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFTEXTEND)
669        act.triggered.connect(self.esm.map)
670        self.editActions.append(act)
671
672        act = E5Action(
673            QCoreApplication.translate(
674                'ViewManager', 'Extend selection right one character'),
675            QCoreApplication.translate(
676                'ViewManager', 'Extend selection right one character'),
677            QKeySequence(QCoreApplication.translate('ViewManager',
678                                                    'Shift+Right')),
679            0, self.editorActGrp, 'vm_edit_extend_selection_right_char')
680        if isMacPlatform():
681            act.setAlternateShortcut(QKeySequence(
682                QCoreApplication.translate('ViewManager', 'Meta+Shift+F')))
683        self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHTEXTEND)
684        act.triggered.connect(self.esm.map)
685        self.editActions.append(act)
686
687        act = E5Action(
688            QCoreApplication.translate(
689                'ViewManager', 'Extend selection left one word'),
690            QCoreApplication.translate(
691                'ViewManager', 'Extend selection left one word'),
692            0, 0,
693            self.editorActGrp, 'vm_edit_extend_selection_left_word')
694        if isMacPlatform():
695            act.setShortcut(QKeySequence(
696                QCoreApplication.translate('ViewManager', 'Alt+Shift+Left')))
697        else:
698            act.setShortcut(QKeySequence(
699                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Left')))
700        self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTEXTEND)
701        act.triggered.connect(self.esm.map)
702        self.editActions.append(act)
703
704        act = E5Action(
705            QCoreApplication.translate(
706                'ViewManager', 'Extend selection right one word'),
707            QCoreApplication.translate(
708                'ViewManager', 'Extend selection right one word'),
709            0, 0,
710            self.editorActGrp, 'vm_edit_extend_selection_right_word')
711        if isMacPlatform():
712            act.setShortcut(QKeySequence(
713                QCoreApplication.translate('ViewManager', 'Alt+Shift+Right')))
714        else:
715            act.setShortcut(QKeySequence(
716                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Right')))
717        self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTEXTEND)
718        act.triggered.connect(self.esm.map)
719        self.editActions.append(act)
720
721        act = E5Action(
722            QCoreApplication.translate(
723                'ViewManager',
724                'Extend selection to first visible character in document'
725                ' line'),
726            QCoreApplication.translate(
727                'ViewManager',
728                'Extend selection to first visible character in document'
729                ' line'),
730            0, 0,
731            self.editorActGrp, 'vm_edit_extend_selection_first_visible_char')
732        if not isMacPlatform():
733            act.setShortcut(QKeySequence(
734                QCoreApplication.translate('ViewManager', 'Shift+Home')))
735        self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEEXTEND)
736        act.triggered.connect(self.esm.map)
737        self.editActions.append(act)
738
739        act = E5Action(
740            QCoreApplication.translate(
741                'ViewManager', 'Extend selection to end of document line'),
742            QCoreApplication.translate(
743                'ViewManager', 'Extend selection to end of document line'),
744            0, 0,
745            self.editorActGrp, 'vm_edit_extend_selection_end_line')
746        if isMacPlatform():
747            act.setShortcut(QKeySequence(
748                QCoreApplication.translate('ViewManager', 'Meta+Shift+E')))
749        else:
750            act.setShortcut(QKeySequence(
751                QCoreApplication.translate('ViewManager', 'Shift+End')))
752        self.esm.setMapping(act, QsciScintilla.SCI_LINEENDEXTEND)
753        act.triggered.connect(self.esm.map)
754        self.editActions.append(act)
755
756    def __createSearchActions(self):
757        """
758        Private method defining the user interface actions for the search
759        commands.
760        """
761        self.searchActGrp = createActionGroup(self)
762
763        self.searchAct = E5Action(
764            QCoreApplication.translate('ViewManager', 'Search'),
765            UI.PixmapCache.getIcon("find"),
766            QCoreApplication.translate('ViewManager', '&Search...'),
767            QKeySequence(QCoreApplication.translate(
768                'ViewManager', "Ctrl+F", "Search|Search")),
769            0,
770            self, 'vm_search')
771        self.searchAct.setStatusTip(QCoreApplication.translate(
772            'ViewManager', 'Search for a text'))
773        self.searchAct.setWhatsThis(QCoreApplication.translate(
774            'ViewManager',
775            """<b>Search</b>"""
776            """<p>Search for some text in the shell window. A"""
777            """ dialog is shown to enter the search text and options"""
778            """ for the search.</p>"""
779        ))
780        self.searchAct.triggered.connect(self.__showFind)
781        self.searchActions.append(self.searchAct)
782
783        self.searchNextAct = E5Action(
784            QCoreApplication.translate(
785                'ViewManager', 'Search next'),
786            UI.PixmapCache.getIcon("findNext"),
787            QCoreApplication.translate('ViewManager', 'Search &next'),
788            QKeySequence(QCoreApplication.translate(
789                'ViewManager', "F3", "Search|Search next")),
790            0,
791            self, 'vm_search_next')
792        self.searchNextAct.setStatusTip(QCoreApplication.translate(
793            'ViewManager', 'Search next occurrence of text'))
794        self.searchNextAct.setWhatsThis(QCoreApplication.translate(
795            'ViewManager',
796            """<b>Search next</b>"""
797            """<p>Search the next occurrence of some text in the shell"""
798            """ window. The previously entered search text and options are"""
799            """ reused.</p>"""
800        ))
801        self.searchNextAct.triggered.connect(
802            self.__searchWidget.on_findNextButton_clicked)
803        self.searchActions.append(self.searchNextAct)
804
805        self.searchPrevAct = E5Action(
806            QCoreApplication.translate('ViewManager', 'Search previous'),
807            UI.PixmapCache.getIcon("findPrev"),
808            QCoreApplication.translate('ViewManager', 'Search &previous'),
809            QKeySequence(QCoreApplication.translate(
810                'ViewManager', "Shift+F3", "Search|Search previous")),
811            0,
812            self, 'vm_search_previous')
813        self.searchPrevAct.setStatusTip(QCoreApplication.translate(
814            'ViewManager', 'Search previous occurrence of text'))
815        self.searchPrevAct.setWhatsThis(QCoreApplication.translate(
816            'ViewManager',
817            """<b>Search previous</b>"""
818            """<p>Search the previous occurrence of some text in the shell"""
819            """ window. The previously entered search text and options are"""
820            """ reused.</p>"""
821        ))
822        self.searchPrevAct.triggered.connect(
823            self.__searchWidget.on_findPrevButton_clicked)
824        self.searchActions.append(self.searchPrevAct)
825
826    def __createViewActions(self):
827        """
828        Private method defining the user interface actions for the view
829        commands.
830        """
831        self.viewActGrp = createActionGroup(self)
832
833        self.zoomInAct = E5Action(
834            QCoreApplication.translate('ViewManager', 'Zoom in'),
835            UI.PixmapCache.getIcon("zoomIn"),
836            QCoreApplication.translate('ViewManager', 'Zoom &in'),
837            QKeySequence(QCoreApplication.translate(
838                'ViewManager', "Ctrl++", "View|Zoom in")),
839            QKeySequence(QCoreApplication.translate(
840                'ViewManager', "Zoom In", "View|Zoom in")),
841            self.viewActGrp, 'vm_view_zoom_in')
842        self.zoomInAct.setStatusTip(QCoreApplication.translate(
843            'ViewManager', 'Zoom in on the text'))
844        self.zoomInAct.setWhatsThis(QCoreApplication.translate(
845            'ViewManager',
846            """<b>Zoom in</b>"""
847            """<p>Zoom in on the text. This makes the text bigger.</p>"""
848        ))
849        self.zoomInAct.triggered.connect(self.__zoomIn)
850        self.viewActions.append(self.zoomInAct)
851
852        self.zoomOutAct = E5Action(
853            QCoreApplication.translate('ViewManager', 'Zoom out'),
854            UI.PixmapCache.getIcon("zoomOut"),
855            QCoreApplication.translate('ViewManager', 'Zoom &out'),
856            QKeySequence(QCoreApplication.translate(
857                'ViewManager', "Ctrl+-", "View|Zoom out")),
858            QKeySequence(QCoreApplication.translate(
859                'ViewManager', "Zoom Out", "View|Zoom out")),
860            self.viewActGrp, 'vm_view_zoom_out')
861        self.zoomOutAct.setStatusTip(QCoreApplication.translate(
862            'ViewManager', 'Zoom out on the text'))
863        self.zoomOutAct.setWhatsThis(QCoreApplication.translate(
864            'ViewManager',
865            """<b>Zoom out</b>"""
866            """<p>Zoom out on the text. This makes the text smaller.</p>"""
867        ))
868        self.zoomOutAct.triggered.connect(self.__zoomOut)
869        self.viewActions.append(self.zoomOutAct)
870
871        self.zoomResetAct = E5Action(
872            QCoreApplication.translate('ViewManager', 'Zoom reset'),
873            UI.PixmapCache.getIcon("zoomReset"),
874            QCoreApplication.translate('ViewManager', 'Zoom &reset'),
875            QKeySequence(QCoreApplication.translate(
876                'ViewManager', "Ctrl+0", "View|Zoom reset")),
877            0,
878            self.viewActGrp, 'vm_view_zoom_reset')
879        self.zoomResetAct.setStatusTip(QCoreApplication.translate(
880            'ViewManager', 'Reset the zoom of the text'))
881        self.zoomResetAct.setWhatsThis(QCoreApplication.translate(
882            'ViewManager',
883            """<b>Zoom reset</b>"""
884            """<p>Reset the zoom of the text. """
885            """This sets the zoom factor to 100%.</p>"""
886        ))
887        self.zoomResetAct.triggered.connect(self.__zoomReset)
888        self.viewActions.append(self.zoomResetAct)
889
890        self.zoomToAct = E5Action(
891            QCoreApplication.translate('ViewManager', 'Zoom'),
892            UI.PixmapCache.getIcon("zoomTo"),
893            QCoreApplication.translate('ViewManager', '&Zoom'),
894            QKeySequence(QCoreApplication.translate(
895                'ViewManager', "Ctrl+#", "View|Zoom")),
896            0,
897            self.viewActGrp, 'vm_view_zoom')
898        self.zoomToAct.setStatusTip(QCoreApplication.translate(
899            'ViewManager', 'Zoom the text'))
900        self.zoomToAct.setWhatsThis(QCoreApplication.translate(
901            'ViewManager',
902            """<b>Zoom</b>"""
903            """<p>Zoom the text. This opens a dialog where the"""
904            """ desired size can be entered.</p>"""
905        ))
906        self.zoomToAct.triggered.connect(self.__zoom)
907        self.viewActions.append(self.zoomToAct)
908
909    def __createHistoryActions(self):
910        """
911        Private method defining the user interface actions for the history
912        commands.
913        """
914        self.showHistoryAct = E5Action(
915            self.tr('Show History'),
916            UI.PixmapCache.getIcon("history"),
917            self.tr('&Show History...'),
918            0, 0,
919            self, 'shell_show_history')
920        self.showHistoryAct.setStatusTip(self.tr(
921            "Show the shell history in a dialog"))
922        self.showHistoryAct.triggered.connect(self.__shell.showHistory)
923
924        self.clearHistoryAct = E5Action(
925            self.tr('Clear History'),
926            UI.PixmapCache.getIcon("historyClear"),
927            self.tr('&Clear History...'),
928            0, 0,
929            self, 'shell_clear_history')
930        self.clearHistoryAct.setStatusTip(self.tr(
931            "Clear the shell history"))
932        self.clearHistoryAct.triggered.connect(self.__shell.clearHistory)
933
934        self.selectHistoryAct = E5Action(
935            self.tr('Select History Entry'),
936            self.tr('Select History &Entry'),
937            0, 0,
938            self, 'shell_select_history')
939        self.selectHistoryAct.setStatusTip(self.tr(
940            "Select an entry of the shell history"))
941        self.selectHistoryAct.triggered.connect(self.__shell.selectHistory)
942
943    def __createHelpActions(self):
944        """
945        Private method to create the Help actions.
946        """
947        self.aboutAct = E5Action(
948            self.tr('About'),
949            self.tr('&About'),
950            0, 0, self, 'about_eric')
951        self.aboutAct.setStatusTip(self.tr(
952            'Display information about this software'))
953        self.aboutAct.setWhatsThis(self.tr(
954            """<b>About</b>"""
955            """<p>Display some information about this software.</p>"""))
956        self.aboutAct.triggered.connect(self.__about)
957        self.helpActions.append(self.aboutAct)
958
959        self.aboutQtAct = E5Action(
960            self.tr('About Qt'),
961            self.tr('About &Qt'),
962            0, 0, self, 'about_qt')
963        self.aboutQtAct.setStatusTip(
964            self.tr('Display information about the Qt toolkit'))
965        self.aboutQtAct.setWhatsThis(self.tr(
966            """<b>About Qt</b>"""
967            """<p>Display some information about the Qt toolkit.</p>"""
968        ))
969        self.aboutQtAct.triggered.connect(self.__aboutQt)
970        self.helpActions.append(self.aboutQtAct)
971
972        self.whatsThisAct = E5Action(
973            self.tr('What\'s This?'),
974            UI.PixmapCache.getIcon("whatsThis"),
975            self.tr('&What\'s This?'),
976            QKeySequence(self.tr("Shift+F1", "Help|What's This?'")),
977            0, self, 'help_help_whats_this')
978        self.whatsThisAct.setStatusTip(self.tr('Context sensitive help'))
979        self.whatsThisAct.setWhatsThis(self.tr(
980            """<b>Display context sensitive help</b>"""
981            """<p>In What's This? mode, the mouse cursor shows an arrow"""
982            """ with a question mark, and you can click on the interface"""
983            """ elements to get a short description of what they do and"""
984            """ how to use them. In dialogs, this feature can be"""
985            """ accessed using the context help button in the titlebar."""
986            """</p>"""
987        ))
988        self.whatsThisAct.triggered.connect(self.__whatsThis)
989        self.helpActions.append(self.whatsThisAct)
990
991    def __showFind(self):
992        """
993        Private method to display the search widget.
994        """
995        txt = self.__shell.selectedText()
996        self.showFind(txt)
997
998    def showFind(self, txt=""):
999        """
1000        Public method to display the search widget.
1001
1002        @param txt text to be shown in the combo
1003        @type str
1004        """
1005        self.__searchWidget.showFind(txt)
1006
1007    def activeWindow(self):
1008        """
1009        Public method to get a reference to the active shell.
1010
1011        @return reference to the shell widget
1012        @rtype Shell
1013        """
1014        return self.__shell
1015
1016    def __readSettings(self):
1017        """
1018        Private method to read the settings remembered last time.
1019        """
1020        settings = Preferences.Prefs.settings
1021        pos = settings.value("ShellWindow/Position", QPoint(0, 0))
1022        size = settings.value("ShellWindow/Size", QSize(800, 600))
1023        self.resize(size)
1024        self.move(pos)
1025
1026    def __writeSettings(self):
1027        """
1028        Private method to write the settings for reuse.
1029        """
1030        settings = Preferences.Prefs.settings
1031        settings.setValue("ShellWindow/Position", self.pos())
1032        settings.setValue("ShellWindow/Size", self.size())
1033
1034    def quit(self):
1035        """
1036        Public method to quit the application.
1037        """
1038        e5App().closeAllWindows()
1039
1040    def __newWindow(self):
1041        """
1042        Private slot to start a new instance of eric.
1043        """
1044        program = sys.executable
1045        eric6 = os.path.join(getConfig("ericDir"), "eric6_shell.py")
1046        args = [eric6]
1047        QProcess.startDetached(program, args)
1048
1049    def __virtualEnvironmentChanged(self, venvName):
1050        """
1051        Private slot handling a change of the shell's virtual environment.
1052
1053        @param venvName name of the virtual environment of the shell
1054        @type str
1055        """
1056        if venvName:
1057            self.setWindowTitle(self.tr("eric Shell [{0}]").format(venvName))
1058        else:
1059            self.setWindowTitle(self.tr("eric Shell"))
1060
1061    ##################################################################
1062    ## Below are the action methods for the view menu
1063    ##################################################################
1064
1065    def __zoomIn(self):
1066        """
1067        Private method to handle the zoom in action.
1068        """
1069        self.__shell.zoomIn()
1070        self.__sbZoom.setValue(self.__shell.getZoom())
1071
1072    def __zoomOut(self):
1073        """
1074        Private method to handle the zoom out action.
1075        """
1076        self.__shell.zoomOut()
1077        self.__sbZoom.setValue(self.__shell.getZoom())
1078
1079    def __zoomReset(self):
1080        """
1081        Private method to reset the zoom factor.
1082        """
1083        self.__shell.zoomTo(0)
1084        self.__sbZoom.setValue(self.__shell.getZoom())
1085
1086    def __zoom(self):
1087        """
1088        Private method to handle the zoom action.
1089        """
1090        from QScintilla.ZoomDialog import ZoomDialog
1091        dlg = ZoomDialog(self.__shell.getZoom(), self, None, True)
1092        if dlg.exec() == QDialog.DialogCode.Accepted:
1093            value = dlg.getZoomSize()
1094            self.__zoomTo(value)
1095
1096    def __zoomTo(self, value):
1097        """
1098        Private slot to zoom to a given value.
1099
1100        @param value zoom value to be set
1101        @type int
1102        """
1103        self.__shell.zoomTo(value)
1104        self.__sbZoom.setValue(self.__shell.getZoom())
1105
1106    def __zoomValueChanged(self, value):
1107        """
1108        Private slot to handle changes of the zoom value.
1109
1110        @param value new zoom value
1111        @type int
1112        """
1113        self.__sbZoom.setValue(value)
1114
1115    ##################################################################
1116    ## Below are the action methods for the help menu
1117    ##################################################################
1118
1119    def __about(self):
1120        """
1121        Private slot to show a little About message.
1122        """
1123        E5MessageBox.about(
1124            self,
1125            self.tr("About eric Shell Window"),
1126            self.tr(
1127                "The eric Shell is a standalone shell window."
1128                " It uses the same backend as the debugger of"
1129                " the full IDE, but is executed independently."))
1130
1131    def __aboutQt(self):
1132        """
1133        Private slot to handle the About Qt dialog.
1134        """
1135        E5MessageBox.aboutQt(self, "eric Shell Window")
1136
1137    def __whatsThis(self):
1138        """
1139        Private slot called in to enter Whats This mode.
1140        """
1141        QWhatsThis.enterWhatsThisMode()
1142
1143    ##################################################################
1144    ## Below are the main menu handling methods
1145    ##################################################################
1146
1147    def __createMenus(self):
1148        """
1149        Private method to create the menus of the menu bar.
1150        """
1151        self.__fileMenu = self.menuBar().addMenu(self.tr("&File"))
1152        self.__fileMenu.setTearOffEnabled(True)
1153        self.__fileMenu.addAction(self.newWindowAct)
1154        self.__fileMenu.addSeparator()
1155        self.__fileMenu.addAction(self.restartAct)
1156        self.__fileMenu.addAction(self.clearRestartAct)
1157        self.__fileMenu.addSeparator()
1158        self.__fileMenu.addAction(self.exitAct)
1159
1160        self.__editMenu = self.menuBar().addMenu(self.tr("&Edit"))
1161        self.__editMenu.setTearOffEnabled(True)
1162        self.__editMenu.addAction(self.cutAct)
1163        self.__editMenu.addAction(self.copyAct)
1164        self.__editMenu.addAction(self.pasteAct)
1165        self.__editMenu.addAction(self.clearAct)
1166        self.__editMenu.addSeparator()
1167        self.__editMenu.addAction(self.searchAct)
1168        self.__editMenu.addAction(self.searchNextAct)
1169        self.__editMenu.addAction(self.searchPrevAct)
1170
1171        self.__viewMenu = self.menuBar().addMenu(self.tr("&View"))
1172        self.__viewMenu.setTearOffEnabled(True)
1173        self.__viewMenu.addAction(self.zoomInAct)
1174        self.__viewMenu.addAction(self.zoomOutAct)
1175        self.__viewMenu.addAction(self.zoomResetAct)
1176        self.__viewMenu.addAction(self.zoomToAct)
1177
1178        self.__historyMenu = self.menuBar().addMenu(self.tr("Histor&y"))
1179        self.__historyMenu.setTearOffEnabled(True)
1180        self.__historyMenu.addAction(self.selectHistoryAct)
1181        self.__historyMenu.addAction(self.showHistoryAct)
1182        self.__historyMenu.addAction(self.clearHistoryAct)
1183        self.__historyMenu.setEnabled(self.__shell.isHistoryEnabled())
1184
1185        self.__startMenu = self.menuBar().addMenu(self.tr("&Start"))
1186        self.__startMenu.aboutToShow.connect(self.__showStartMenu)
1187        self.__startMenu.triggered.connect(self.__startShell)
1188
1189        self.menuBar().addSeparator()
1190
1191        self.__helpMenu = self.menuBar().addMenu(self.tr("&Help"))
1192        self.__helpMenu.setTearOffEnabled(True)
1193        self.__helpMenu.addAction(self.aboutAct)
1194        self.__helpMenu.addAction(self.aboutQtAct)
1195        self.__helpMenu.addSeparator()
1196        self.__helpMenu.addAction(self.whatsThisAct)
1197
1198    def __showStartMenu(self):
1199        """
1200        Private slot to prepare the language menu.
1201        """
1202        self.__startMenu.clear()
1203        for venvName in sorted(self.virtualenvManager.getVirtualenvNames()):
1204            self.__startMenu.addAction(venvName)
1205
1206    def __startShell(self, action):
1207        """
1208        Private slot to start a shell according to the action triggered.
1209
1210        @param action menu action that was triggered (QAction)
1211        """
1212        venvName = action.text()
1213        self.__debugServer.startClient(False, venvName=venvName)
1214        self.__debugServer.remoteBanner()
1215
1216    ##################################################################
1217    ## Below are the toolbar handling methods
1218    ##################################################################
1219
1220    def __createToolBars(self):
1221        """
1222        Private method to create the various toolbars.
1223        """
1224        filetb = self.addToolBar(self.tr("File"))
1225        filetb.setIconSize(UI.Config.ToolBarIconSize)
1226        filetb.addAction(self.newWindowAct)
1227        filetb.addSeparator()
1228        filetb.addAction(self.restartAct)
1229        filetb.addAction(self.clearRestartAct)
1230        filetb.addSeparator()
1231        filetb.addAction(self.exitAct)
1232
1233        edittb = self.addToolBar(self.tr("Edit"))
1234        edittb.setIconSize(UI.Config.ToolBarIconSize)
1235        edittb.addAction(self.cutAct)
1236        edittb.addAction(self.copyAct)
1237        edittb.addAction(self.pasteAct)
1238        edittb.addAction(self.clearAct)
1239
1240        findtb = self.addToolBar(self.tr("Find"))
1241        findtb.setIconSize(UI.Config.ToolBarIconSize)
1242        findtb.addAction(self.searchAct)
1243        findtb.addAction(self.searchNextAct)
1244        findtb.addAction(self.searchPrevAct)
1245
1246        viewtb = self.addToolBar(self.tr("View"))
1247        viewtb.setIconSize(UI.Config.ToolBarIconSize)
1248        viewtb.addAction(self.zoomInAct)
1249        viewtb.addAction(self.zoomOutAct)
1250        viewtb.addAction(self.zoomResetAct)
1251        viewtb.addAction(self.zoomToAct)
1252
1253        self.__historyToolbar = self.addToolBar(self.tr("History"))
1254        self.__historyToolbar.setIconSize(UI.Config.ToolBarIconSize)
1255        self.__historyToolbar.addAction(self.showHistoryAct)
1256        self.__historyToolbar.addAction(self.clearHistoryAct)
1257        self.__historyToolbar.setEnabled(self.__shell.isHistoryEnabled())
1258
1259        helptb = self.addToolBar(self.tr("Help"))
1260        helptb.setIconSize(UI.Config.ToolBarIconSize)
1261        helptb.addAction(self.whatsThisAct)
1262
1263    ##################################################################
1264    ## Below are the status bar handling methods
1265    ##################################################################
1266
1267    def __createStatusBar(self):
1268        """
1269        Private slot to set up the status bar.
1270        """
1271        self.__statusBar = self.statusBar()
1272        self.__statusBar.setSizeGripEnabled(True)
1273
1274        self.__sbZoom = E5ZoomWidget(
1275            UI.PixmapCache.getPixmap("zoomOut"),
1276            UI.PixmapCache.getPixmap("zoomIn"),
1277            UI.PixmapCache.getPixmap("zoomReset"),
1278            self.__statusBar)
1279        self.__statusBar.addPermanentWidget(self.__sbZoom)
1280        self.__sbZoom.setWhatsThis(self.tr(
1281            """<p>This part of the status bar allows zooming the  shell.</p>"""
1282        ))
1283
1284        self.__sbZoom.valueChanged.connect(self.__zoomTo)
1285        self.__sbZoom.setValue(0)
1286
1287    def __historyStyleChanged(self, historyStyle):
1288        """
1289        Private slot to handle a change of the shell history style.
1290
1291        @param historyStyle style to be used for the history
1292        @type ShellHistoryStyle
1293        """
1294        enabled = self.__shell.isHistoryEnabled()
1295        self.__historyMenu.setEnabled(enabled)
1296        self.__historyToolbar.setEnabled(enabled)
1297