Thu, 20 Apr 2017 20:09:53 +0200
Started implementing the standalone shell window.
QScintilla/Shell.py | file | annotate | diff | comparison | revisions | |
QScintilla/ShellWindow.py | file | annotate | diff | comparison | revisions | |
eric6.e4p | file | annotate | diff | comparison | revisions | |
eric6_shell.py | file | annotate | diff | comparison | revisions |
--- a/QScintilla/Shell.py Wed Apr 19 19:02:34 2017 +0200 +++ b/QScintilla/Shell.py Thu Apr 20 20:09:53 2017 +0200 @@ -47,7 +47,7 @@ """ super(ShellAssembly, self).__init__(parent) - self.__shell = Shell(dbs, vm, self) + self.__shell = Shell(dbs, vm, False, self) from UI.SearchWidget import SearchWidget self.__searchWidget = SearchWidget(self.__shell, self, horizontal) @@ -95,13 +95,15 @@ """ searchStringFound = pyqtSignal(bool) - def __init__(self, dbs, vm, parent=None): + def __init__(self, dbs, vm, windowedVariant, parent=None): """ Constructor @param dbs reference to the debug server object @param vm reference to the viewmanager object @param parent parent widget (QWidget) + @param windowedVariant flag indicating the shell window variant + (boolean) """ super(Shell, self).__init__(parent) self.setUtf8(True) @@ -109,47 +111,74 @@ self.vm = vm self.__mainWindow = parent self.__lastSearch = () + self.__windowed = windowedVariant self.linesepRegExp = r"\r\n|\n|\r" + # TODO: change this for Shell Window self.passive = Preferences.getDebugger("PassiveDbgEnabled") if self.passive: self.setWindowTitle(self.tr('Shell - Passive')) else: self.setWindowTitle(self.tr('Shell')) - self.setWhatsThis(self.tr( - """<b>The Shell Window</b>""" - """<p>This is simply an interpreter running in a window. The""" - """ interpreter is the one that is used to run the program""" - """ being debugged. This means that you can execute any command""" - """ while the program being debugged is running.</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>""" - """<p>The shell has some special commands. 'reset' kills the""" - """ shell and starts a new one. 'clear' clears the display of""" - """ the shell window. 'start' is used to switch the shell""" - """ language and must be followed by a supported language.""" - """ Supported languages are listed by the 'languages' command.""" - """ These commands (except 'languages') are available through""" - """ the context menu as well.</p>""" - """<p>Pressing the Tab key after some text has been entered will""" - """ show a list of possible commandline completions. The""" - """ relevant entry may be selected from this list. If only one""" - """ entry is available, this will inserted automatically.</p>""" - """<p>In passive debugging mode the shell is only available""" - """ after the program to be debugged has connected to the IDE""" - """ until it has finished. This is indicated by a different""" - """ prompt and by an indication in the window caption.</p>""" - )) + if self.__windowed: + self.setWhatsThis(self.tr( + """<b>The Shell Window</b>""" + """<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>""" + """<p>The shell has some special commands. 'reset' kills the""" + """ shell and starts a new one. 'clear' clears the display""" + """ of the shell window. 'start' is used to switch the shell""" + """ language and must be followed by a supported language.""" + """ Supported languages are listed by the 'languages'""" + """ command. These commands (except 'languages') are""" + """ available through the context menu as well.</p>""" + """<p>Pressing the Tab key after some text has been entered""" + """ will show a list of possible completions. The relevant""" + """ entry may be selected from this list. If only one entry""" + """ is available, this will be inserted automatically.</p>""" + )) + else: + self.setWhatsThis(self.tr( + """<b>The Shell Window</b>""" + """<p>This is simply an interpreter running in a window. The""" + """ interpreter is the one that is used to run the program""" + """ being debugged. This means that you can execute any""" + """ command while the program being debugged is running.</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>""" + """<p>The shell has some special commands. 'reset' kills the""" + """ shell and starts a new one. 'clear' clears the display""" + """ of the shell window. 'start' is used to switch the shell""" + """ language and must be followed by a supported language.""" + """ Supported languages are listed by the 'languages'""" + """ command. These commands (except 'languages') are""" + """ available through the context menu as well.</p>""" + """<p>Pressing the Tab key after some text has been entered""" + """ will show a list of possible completions. The relevant""" + """ entry may be selected from this list. If only one entry""" + """ is available, this will be inserted automatically.</p>""" + """<p>In passive debugging mode the shell is only available""" + """ after the program to be debugged has connected to the""" + """ IDE until it has finished. This is indicated by a""" + """ different prompt and by an indication in the window""" + """ caption.</p>""" + )) self.userListActivated.connect(self.__completionListSelected) self.linesChanged.connect(self.__resizeLinenoMargin) - self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") + if self.__windowed: + self.__showStdOutErr = True + else: + self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") if self.__showStdOutErr: dbs.clientProcessStdout.connect(self.__writeStdOut) dbs.clientProcessStderr.connect(self.__writeStdErr) @@ -232,8 +261,9 @@ self.tr('Reset and Clear'), self.__resetAndClear) self.menu.addSeparator() self.menu.addMenu(self.lmenu) - self.menu.addSeparator() - self.menu.addAction(self.tr("Configure..."), self.__configure) + if not self.__windowed: + self.menu.addSeparator() + self.menu.addAction(self.tr("Configure..."), self.__configure) self.__bindLexer() self.__setTextDisplay() @@ -696,7 +726,8 @@ """ self .__clientError() - if Preferences.getDebugger("ShowExceptionInShell"): + if not self.__windowed and \ + Preferences.getDebugger("ShowExceptionInShell"): if exceptionType: if stackTrace: self.__write( @@ -729,7 +760,8 @@ """ self .__clientError() - if Preferences.getDebugger("ShowExceptionInShell"): + if not self.__windowed and \ + Preferences.getDebugger("ShowExceptionInShell"): if message is None: self.__write(self.tr("Unspecified syntax error.\n")) else: @@ -1436,6 +1468,10 @@ return else: cmd = '' + elif cmd in ["quit", "quit()"] and self.__windowed: + # call main window quit() + self.vm.quit() + return self.dbs.remoteStatement(cmd) while self.inCommandExecution:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QScintilla/ShellWindow.py Thu Apr 20 20:09:53 2017 +0200 @@ -0,0 +1,998 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a stand alone shell window. +""" + +from __future__ import unicode_literals + +from PyQt5.QtCore import QCoreApplication, QPoint, QSize, QSignalMapper +from PyQt5.QtGui import QKeySequence +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QAction, \ + QWhatsThis +from PyQt5.Qsci import QsciScintilla + +from E5Gui.E5MainWindow import E5MainWindow +from E5Gui.E5Action import E5Action, createActionGroup +from E5Gui.E5Application import e5App +from E5Gui.E5ZoomWidget import E5ZoomWidget +from E5Gui import E5MessageBox + +import UI.PixmapCache +import Preferences + +from Globals import isMacPlatform + +from .Shell import Shell +from .APIsManager import APIsManager + +from Debugger.DebugServer import DebugServer +from UI.SearchWidget import SearchWidget + + +class ShellWindow(E5MainWindow): + """ + Class implementing a stand alone shell window. + """ + def __init__(self, parent=None, name=None): + """ + Constructor + + @param parent reference to the parent widget + @type QWidget + @param name object name of the window + @type str + """ + super(ShellWindow, self).__init__(parent) + if name is not None: + self.setObjectName(name) + self.setWindowIcon(UI.PixmapCache.getIcon("shell.png")) + + self.setStyle(Preferences.getUI("Style"), + Preferences.getUI("StyleSheet")) + + # initialize the APIs manager + self.__apisManager = APIsManager(parent=self) + + # initialize the debug server and shell widgets + self.__debugServer = DebugServer() + self.__shell = Shell(self.__debugServer, self, True, self) + self.__searchWidget = SearchWidget(self.__shell, self) + + centralWidget = QWidget() + layout = QVBoxLayout() + layout.setContentsMargins(1, 1, 1, 1) + layout.addWidget(self.__shell) + layout.addWidget(self.__searchWidget) + centralWidget.setLayout(layout) + self.setCentralWidget(centralWidget) + self.__searchWidget.hide() + + + self.__searchWidget.searchNext.connect(self.__shell.searchNext) + self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev) + self.__shell.searchStringFound.connect( + self.__searchWidget.searchStringFound) + + self.__shell.zoomValueChanged.connect(self.__zoomValueChanged) + + self.__createActions() +## self.__createMenus() +## self.__createToolBars() + self.__createStatusBar() + + self.__readSettings() + + # now start the debug client + self.__debugServer.startClient(False) + + # set the keyboard input interval + interval = Preferences.getUI("KeyboardInputInterval") + if interval > 0: + QApplication.setKeyboardInputInterval(interval) + + def closeEvent(self, event): + """ + Protected method to handle the close event. + + @param event close event (QCloseEvent) + """ + self.__writeSettings() + self.__debugServer.shutdownServer() + self.__shell.closeShell() + + event.accept() + + ################################################################## + ## Below are API handling methods + ################################################################## + + def getAPIsManager(self): + """ + Public method to get a reference to the APIs manager. + + @return the APIs manager object (eric6.QScintilla.APIsManager) + """ + return self.__apisManager + + ################################################################## + ## Below are action related methods + ################################################################## + + def __readShortcut(self, act, category): + """ + Private function to read a single keyboard shortcut from the settings. + + @param act reference to the action object (E5Action) + @param category category the action belongs to (string) + """ + if act.objectName(): + accel = Preferences.Prefs.settings.value( + "Shortcuts/{0}/{1}/Accel".format(category, act.objectName())) + if accel is not None: + act.setShortcut(QKeySequence(accel)) + accel = Preferences.Prefs.settings.value( + "Shortcuts/{0}/{1}/AltAccel".format( + category, act.objectName())) + if accel is not None: + act.setAlternateShortcut(QKeySequence(accel), removeEmpty=True) + + def __createActions(self): + """ + Private method to create the actions. + """ + self.fileActions = [] + self.editActions = [] + self.searchActions = [] + self.viewActions = [] + self.helpActions = [] + + self.viewActGrp = createActionGroup(self) + + self.__createFileActions() + self.__createEditActions() + self.__createSearchActions() + self.__createHelpActions() + + # read the keyboard shortcuts and make them identical to the main + # eric6 shortcuts + for act in self.helpActions: + self.__readShortcut(act, "General") + for act in self.editActions: + self.__readShortcut(act, "Edit") + for act in self.fileActions: + self.__readShortcut(act, "View") + for act in self.searchActions: + self.__readShortcut(act, "Search") + + def __createFileActions(self): + """ + Private method defining the user interface actions for the file + commands. + """ + self.exitAct = E5Action( + self.tr('Quit'), + UI.PixmapCache.getIcon("exit.png"), + self.tr('&Quit'), + QKeySequence(self.tr("Ctrl+Q", "File|Quit")), + 0, self, 'quit') + self.exitAct.setStatusTip(self.tr('Quit the IDE')) + self.exitAct.setWhatsThis(self.tr( + """<b>Quit the Shell</b>""" + """<p>This quits the Shell window.</p>""" + )) + self.exitAct.triggered.connect(self.quit) + self.exitAct.setMenuRole(QAction.QuitRole) + self.fileActions.append(self.exitAct) +## +## self.newWindowAct = E5Action( +## self.tr('New Window'), +## UI.PixmapCache.getIcon("newWindow.png"), +## self.tr('New &Window'), +## QKeySequence(self.tr("Ctrl+Shift+N", "File|New Window")), +## 0, self, 'new_window') +## self.newWindowAct.setStatusTip(self.tr( +## 'Open a new eric6 instance')) +## self.newWindowAct.setWhatsThis(self.tr( +## """<b>New Window</b>""" +## """<p>This opens a new instance of the eric6 IDE.</p>""" +## )) +## self.newWindowAct.triggered.connect(self.__newWindow) +## self.fileActions.append(self.newWindowAct) + + def __createEditActions(self): + """ + Private method defining the user interface actions for the edit + commands. + """ + self.editActGrp = createActionGroup(self) + self.copyActGrp = createActionGroup(self.editActGrp) + + self.cutAct = E5Action( + QCoreApplication.translate('ViewManager', 'Cut'), + UI.PixmapCache.getIcon("editCut.png"), + QCoreApplication.translate('ViewManager', 'Cu&t'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+X", "Edit|Cut")), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Shift+Del", "Edit|Cut")), + self.copyActGrp, 'vm_edit_cut') + self.cutAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Cut the selection')) + self.cutAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Cut</b>""" + """<p>Cut the selected text of the current editor to the""" + """ clipboard.</p>""" + )) + self.cutAct.triggered.connect(self.__shell.cut) + self.editActions.append(self.cutAct) + + self.copyAct = E5Action( + QCoreApplication.translate('ViewManager', 'Copy'), + UI.PixmapCache.getIcon("editCopy.png"), + QCoreApplication.translate('ViewManager', '&Copy'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+C", "Edit|Copy")), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+Ins", "Edit|Copy")), + self.copyActGrp, 'vm_edit_copy') + self.copyAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Copy the selection')) + self.copyAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Copy</b>""" + """<p>Copy the selected text of the current editor to the""" + """ clipboard.</p>""" + )) + self.copyAct.triggered.connect(self.__shell.copy) + self.editActions.append(self.copyAct) + + self.pasteAct = E5Action( + QCoreApplication.translate('ViewManager', 'Paste'), + UI.PixmapCache.getIcon("editPaste.png"), + QCoreApplication.translate('ViewManager', '&Paste'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+V", "Edit|Paste")), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Shift+Ins", "Edit|Paste")), + self.copyActGrp, 'vm_edit_paste') + self.pasteAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Paste the last cut/copied text')) + self.pasteAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Paste</b>""" + """<p>Paste the last cut/copied text from the clipboard to""" + """ the current editor.</p>""" + )) + self.pasteAct.triggered.connect(self.__shell.paste) + self.editActions.append(self.pasteAct) + + self.deleteAct = E5Action( + QCoreApplication.translate('ViewManager', 'Clear'), + UI.PixmapCache.getIcon("editDelete.png"), + QCoreApplication.translate('ViewManager', 'Clear'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Alt+Shift+C", "Edit|Clear")), + 0, + self.copyActGrp, 'vm_edit_clear') + self.deleteAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Clear all text')) + self.deleteAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Clear</b>""" + """<p>Delete all text of the current editor.</p>""" + )) + self.deleteAct.triggered.connect(self.__shell.clear) + self.editActions.append(self.deleteAct) + + self.cutAct.setEnabled(False) + self.copyAct.setEnabled(False) + self.__shell.copyAvailable.connect(self.cutAct.setEnabled) + self.__shell.copyAvailable.connect(self.copyAct.setEnabled) + + #################################################################### + ## Below follow the actions for QScintilla standard commands. + #################################################################### + + self.esm = QSignalMapper(self) + self.esm.mapped[int].connect(self.__shell.editorCommand) + + self.editorActGrp = createActionGroup(self) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Delete current line'), + QCoreApplication.translate('ViewManager', 'Delete current line'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', 'Ctrl+Shift+L')), + 0, + self.editorActGrp, 'vm_edit_delete_current_line') + self.esm.setMapping(act, QsciScintilla.SCI_LINEDELETE) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Indent one level'), + QCoreApplication.translate('ViewManager', 'Indent one level'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Tab')), 0, + self.editorActGrp, 'vm_edit_indent_one_level') + self.esm.setMapping(act, QsciScintilla.SCI_TAB) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Insert new line'), + QCoreApplication.translate('ViewManager', 'Insert new line'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Return')), + QKeySequence(QCoreApplication.translate('ViewManager', 'Enter')), + self.editorActGrp, 'vm_edit_insert_line') + self.esm.setMapping(act, QsciScintilla.SCI_NEWLINE) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', + 'Delete previous character'), + QCoreApplication.translate('ViewManager', + 'Delete previous character'), + QKeySequence(QCoreApplication.translate('ViewManager', + 'Backspace')), + 0, self.editorActGrp, 'vm_edit_delete_previous_char') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+H'))) + else: + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Shift+Backspace'))) + self.esm.setMapping(act, QsciScintilla.SCI_DELETEBACK) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', + 'Delete current character'), + QCoreApplication.translate('ViewManager', + 'Delete current character'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Del')), + 0, self.editorActGrp, 'vm_edit_delete_current_char') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+D'))) + self.esm.setMapping(act, QsciScintilla.SCI_CLEAR) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Delete word to left'), + QCoreApplication.translate('ViewManager', 'Delete word to left'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', 'Ctrl+Backspace')), + 0, + self.editorActGrp, 'vm_edit_delete_word_left') + self.esm.setMapping(act, QsciScintilla.SCI_DELWORDLEFT) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Delete word to right'), + QCoreApplication.translate('ViewManager', 'Delete word to right'), + QKeySequence(QCoreApplication.translate('ViewManager', + 'Ctrl+Del')), + 0, self.editorActGrp, 'vm_edit_delete_word_right') + self.esm.setMapping(act, QsciScintilla.SCI_DELWORDRIGHT) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Delete line to left'), + QCoreApplication.translate('ViewManager', 'Delete line to left'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', 'Ctrl+Shift+Backspace')), + 0, + self.editorActGrp, 'vm_edit_delete_line_left') + self.esm.setMapping(act, QsciScintilla.SCI_DELLINELEFT) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Delete line to right'), + QCoreApplication.translate('ViewManager', 'Delete line to right'), + 0, 0, + self.editorActGrp, 'vm_edit_delete_line_right') + if isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+K'))) + else: + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Del'))) + self.esm.setMapping(act, QsciScintilla.SCI_DELLINERIGHT) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', + 'Move left one character'), + QCoreApplication.translate('ViewManager', + 'Move left one character'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Left')), 0, + self.editorActGrp, 'vm_edit_move_left_char') + self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFT) + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+B'))) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', + 'Move right one character'), + QCoreApplication.translate('ViewManager', + 'Move right one character'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Right')), + 0, self.editorActGrp, 'vm_edit_move_right_char') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+F'))) + self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHT) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Move left one word'), + QCoreApplication.translate('ViewManager', 'Move left one word'), + 0, 0, + self.editorActGrp, 'vm_edit_move_left_word') + if isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Alt+Left'))) + else: + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Ctrl+Left'))) + self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFT) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Move right one word'), + QCoreApplication.translate('ViewManager', 'Move right one word'), + 0, 0, + self.editorActGrp, 'vm_edit_move_right_word') + if not isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Ctrl+Right'))) + self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHT) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', + 'Move to first visible character in document line'), + QCoreApplication.translate( + 'ViewManager', + 'Move to first visible character in document line'), + 0, 0, + self.editorActGrp, 'vm_edit_move_first_visible_char') + if not isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Home'))) + self.esm.setMapping(act, QsciScintilla.SCI_VCHOME) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', 'Move to end of document line'), + QCoreApplication.translate( + 'ViewManager', 'Move to end of document line'), + 0, 0, + self.editorActGrp, 'vm_edit_move_end_line') + if isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+E'))) + else: + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'End'))) + self.esm.setMapping(act, QsciScintilla.SCI_LINEEND) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Move up one line'), + QCoreApplication.translate('ViewManager', 'Move up one line'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Up')), 0, + self.editorActGrp, 'vm_edit_move_up_line') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+P'))) + self.esm.setMapping(act, QsciScintilla.SCI_LINEUP) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Move down one line'), + QCoreApplication.translate('ViewManager', 'Move down one line'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Down')), 0, + self.editorActGrp, 'vm_edit_move_down_line') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+N'))) + self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWN) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Move up one page'), + QCoreApplication.translate('ViewManager', 'Move up one page'), + QKeySequence(QCoreApplication.translate('ViewManager', 'PgUp')), 0, + self.editorActGrp, 'vm_edit_move_up_page') + self.esm.setMapping(act, QsciScintilla.SCI_PAGEUP) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Move down one page'), + QCoreApplication.translate('ViewManager', 'Move down one page'), + QKeySequence(QCoreApplication.translate('ViewManager', 'PgDown')), + 0, self.editorActGrp, 'vm_edit_move_down_page') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+V'))) + self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWN) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate('ViewManager', 'Escape'), + QCoreApplication.translate('ViewManager', 'Escape'), + QKeySequence(QCoreApplication.translate('ViewManager', 'Esc')), 0, + self.editorActGrp, 'vm_edit_escape') + self.esm.setMapping(act, QsciScintilla.SCI_CANCEL) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', 'Extend selection left one character'), + QCoreApplication.translate( + 'ViewManager', 'Extend selection left one character'), + QKeySequence(QCoreApplication.translate('ViewManager', + 'Shift+Left')), + 0, self.editorActGrp, 'vm_edit_extend_selection_left_char') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+Shift+B'))) + self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFTEXTEND) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', 'Extend selection right one character'), + QCoreApplication.translate( + 'ViewManager', 'Extend selection right one character'), + QKeySequence(QCoreApplication.translate('ViewManager', + 'Shift+Right')), + 0, self.editorActGrp, 'vm_edit_extend_selection_right_char') + if isMacPlatform(): + act.setAlternateShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+Shift+F'))) + self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHTEXTEND) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', 'Extend selection left one word'), + QCoreApplication.translate( + 'ViewManager', 'Extend selection left one word'), + 0, 0, + self.editorActGrp, 'vm_edit_extend_selection_left_word') + if isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Alt+Shift+Left'))) + else: + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Left'))) + self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTEXTEND) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', 'Extend selection right one word'), + QCoreApplication.translate( + 'ViewManager', 'Extend selection right one word'), + 0, 0, + self.editorActGrp, 'vm_edit_extend_selection_right_word') + if isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Alt+Shift+Right'))) + else: + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Right'))) + self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTEXTEND) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', + 'Extend selection to first visible character in document' + ' line'), + QCoreApplication.translate( + 'ViewManager', + 'Extend selection to first visible character in document' + ' line'), + 0, 0, + self.editorActGrp, 'vm_edit_extend_selection_first_visible_char') + if not isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Shift+Home'))) + self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEEXTEND) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + act = E5Action( + QCoreApplication.translate( + 'ViewManager', 'Extend selection to end of document line'), + QCoreApplication.translate( + 'ViewManager', 'Extend selection to end of document line'), + 0, 0, + self.editorActGrp, 'vm_edit_extend_selection_end_line') + if isMacPlatform(): + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Meta+Shift+E'))) + else: + act.setShortcut(QKeySequence( + QCoreApplication.translate('ViewManager', 'Shift+End'))) + self.esm.setMapping(act, QsciScintilla.SCI_LINEENDEXTEND) + act.triggered.connect(self.esm.map) + self.editActions.append(act) + + def __createSearchActions(self): + """ + Private method defining the user interface actions for the search + commands. + """ + self.searchActGrp = createActionGroup(self) + + self.searchAct = E5Action( + QCoreApplication.translate('ViewManager', 'Search'), + UI.PixmapCache.getIcon("find.png"), + QCoreApplication.translate('ViewManager', '&Search...'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+F", "Search|Search")), + 0, + self.searchActGrp, 'vm_search') + self.searchAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Search for a text')) + self.searchAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Search</b>""" + """<p>Search for some text in the current editor. A""" + """ dialog is shown to enter the searchtext and options""" + """ for the search.</p>""" + )) + self.searchAct.triggered.connect(self.__showFind) + self.searchActions.append(self.searchAct) + + self.searchNextAct = E5Action( + QCoreApplication.translate( + 'ViewManager', 'Search next'), + UI.PixmapCache.getIcon("findNext.png"), + QCoreApplication.translate('ViewManager', 'Search &next'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "F3", "Search|Search next")), + 0, + self.searchActGrp, 'vm_search_next') + self.searchNextAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Search next occurrence of text')) + self.searchNextAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Search next</b>""" + """<p>Search the next occurrence of some text in the current""" + """ editor. The previously entered searchtext and options are""" + """ reused.</p>""" + )) + self.searchNextAct.triggered.connect( + self.__searchWidget.on_findNextButton_clicked) + self.searchActions.append(self.searchNextAct) + + self.searchPrevAct = E5Action( + QCoreApplication.translate('ViewManager', 'Search previous'), + UI.PixmapCache.getIcon("findPrev.png"), + QCoreApplication.translate('ViewManager', 'Search &previous'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Shift+F3", "Search|Search previous")), + 0, + self.searchActGrp, 'vm_search_previous') + self.searchPrevAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Search previous occurrence of text')) + self.searchPrevAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Search previous</b>""" + """<p>Search the previous occurrence of some text in the current""" + """ editor. The previously entered searchtext and options are""" + """ reused.</p>""" + )) + self.searchPrevAct.triggered.connect( + self.__searchWidget.on_findPrevButton_clicked) + self.searchActions.append(self.searchPrevAct) + + def __createViewActions(self): + """ + Private method defining the user interface actions for the view + commands. + """ + self.viewActGrp = createActionGroup(self) + self.viewFoldActGrp = createActionGroup(self) + + self.zoomInAct = E5Action( + QCoreApplication.translate('ViewManager', 'Zoom in'), + UI.PixmapCache.getIcon("zoomIn.png"), + QCoreApplication.translate('ViewManager', 'Zoom &in'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl++", "View|Zoom in")), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Zoom In", "View|Zoom in")), + self.viewActGrp, 'vm_view_zoom_in') + self.zoomInAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Zoom in on the text')) + self.zoomInAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Zoom in</b>""" + """<p>Zoom in on the text. This makes the text bigger.</p>""" + )) + self.zoomInAct.triggered.connect(self.__zoomIn) + self.viewActions.append(self.zoomInAct) + + self.zoomOutAct = E5Action( + QCoreApplication.translate('ViewManager', 'Zoom out'), + UI.PixmapCache.getIcon("zoomOut.png"), + QCoreApplication.translate('ViewManager', 'Zoom &out'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+-", "View|Zoom out")), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Zoom Out", "View|Zoom out")), + self.viewActGrp, 'vm_view_zoom_out') + self.zoomOutAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Zoom out on the text')) + self.zoomOutAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Zoom out</b>""" + """<p>Zoom out on the text. This makes the text smaller.</p>""" + )) + self.zoomOutAct.triggered.connect(self.__zoomOut) + self.viewActions.append(self.zoomOutAct) + + self.zoomResetAct = E5Action( + QCoreApplication.translate('ViewManager', 'Zoom reset'), + UI.PixmapCache.getIcon("zoomReset.png"), + QCoreApplication.translate('ViewManager', 'Zoom &reset'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+0", "View|Zoom reset")), + 0, + self.viewActGrp, 'vm_view_zoom_reset') + self.zoomResetAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Reset the zoom of the text')) + self.zoomResetAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Zoom reset</b>""" + """<p>Reset the zoom of the text. """ + """This sets the zoom factor to 100%.</p>""" + )) + self.zoomResetAct.triggered.connect(self.__zoomReset) + self.viewActions.append(self.zoomResetAct) + + self.zoomToAct = E5Action( + QCoreApplication.translate('ViewManager', 'Zoom'), + UI.PixmapCache.getIcon("zoomTo.png"), + QCoreApplication.translate('ViewManager', '&Zoom'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+#", "View|Zoom")), + 0, + self.viewActGrp, 'vm_view_zoom') + self.zoomToAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Zoom the text')) + self.zoomToAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Zoom</b>""" + """<p>Zoom the text. This opens a dialog where the""" + """ desired size can be entered.</p>""" + )) + self.zoomToAct.triggered.connect(self.__zoom) + self.viewActions.append(self.zoomToAct) + + def __createHelpActions(self): + """ + Private method to create the Help actions. + """ + self.aboutAct = E5Action( + self.tr('About'), + self.tr('&About'), + 0, 0, self, 'about_eric') + self.aboutAct.setStatusTip(self.tr( + 'Display information about this software')) + self.aboutAct.setWhatsThis(self.tr( + """<b>About</b>""" + """<p>Display some information about this software.</p>""")) + self.aboutAct.triggered.connect(self.__about) + self.helpActions.append(self.aboutAct) + + self.aboutQtAct = E5Action( + self.tr('About Qt'), + self.tr('About &Qt'), + 0, 0, self, 'about_qt') + self.aboutQtAct.setStatusTip( + self.tr('Display information about the Qt toolkit')) + self.aboutQtAct.setWhatsThis(self.tr( + """<b>About Qt</b>""" + """<p>Display some information about the Qt toolkit.</p>""" + )) + self.aboutQtAct.triggered.connect(self.__aboutQt) + self.helpActions.append(self.aboutQtAct) + + self.whatsThisAct = E5Action( + self.tr('What\'s This?'), + UI.PixmapCache.getIcon("whatsThis.png"), + self.tr('&What\'s This?'), + QKeySequence(self.tr("Shift+F1", "Help|What's This?'")), + 0, self, 'help_help_whats_this') + self.whatsThisAct.setStatusTip(self.tr('Context sensitive help')) + self.whatsThisAct.setWhatsThis(self.tr( + """<b>Display context sensitive help</b>""" + """<p>In What's This? mode, the mouse cursor shows an arrow""" + """ with a question mark, and you can click on the interface""" + """ elements to get a short description of what they do and""" + """ how to use them. In dialogs, this feature can be""" + """ accessed using the context help button in the titlebar.""" + """</p>""" + )) + self.whatsThisAct.triggered.connect(self.__whatsThis) + self.helpActions.append(self.whatsThisAct) + + def __showFind(self): + """ + Public method to display the search widget. + """ + self.__searchWidget.showFind("") + + def activeWindow(self): + """ + Public method to get a reference to the active shell. + """ + return self.__shell + + def __readSettings(self): + """ + Private method to read the settings remembered last time. + """ + settings = Preferences.Prefs.settings + pos = settings.value("ShellWindow/Position", QPoint(0, 0)) + size = settings.value("ShellWindow/Size", QSize(800, 600)) + self.resize(size) + self.move(pos) + + def __writeSettings(self): + """ + Private method to write the settings for reuse. + """ + settings = Preferences.Prefs.settings + settings.setValue("ShellWindow/Position", self.pos()) + settings.setValue("ShellWindow/Size", self.size()) + + def quit(self): + """ + Public method to quit the application. + """ + e5App().closeAllWindows() + + ################################################################## + ## Below are the action methods for the view menu + ################################################################## + + def __zoomIn(self): + """ + Private method to handle the zoom in action. + """ + self.__shell.zoomIn() + self.__sbZoom.setValue(self.__shell.getZoom()) + + def __zoomOut(self): + """ + Private method to handle the zoom out action. + """ + self.__shell.zoomOut() + self.__sbZoom.setValue(self.__shell.getZoom()) + + def __zoomReset(self): + """ + Private method to reset the zoom factor. + """ + self.__shell.zoomTo(0) + self.__sbZoom.setValue(self.__shell.getZoom()) + + def __zoom(self): + """ + Private method to handle the zoom action. + """ + from QScintilla.ZoomDialog import ZoomDialog + dlg = ZoomDialog(self.__shell.getZoom(), self, None, True) + if dlg.exec_() == QDialog.Accepted: + value = dlg.getZoomSize() + self.__zoomTo(value) + + def __zoomTo(self, value): + """ + Private slot to zoom to a given value. + + @param value zoom value to be set (integer) + """ + self.__shell.zoomTo(value) + self.__sbZoom.setValue(self.__shell.getZoom()) + + def __zoomValueChanged(self, value): + """ + Private slot to handle changes of the zoom value. + + @param value new zoom value (integer) + """ + self.__sbZoom.setValue(value) + + ################################################################## + ## Below are the action methods for the help menu + ################################################################## + + def __about(self): + """ + Private slot to show a little About message. + """ + # TODO: change this text + E5MessageBox.about( + self, + self.tr("About eric6 Mini Editor"), + self.tr( + "The eric6 Mini Editor is an editor component" + " based on QScintilla. It may be used for simple" + " editing tasks, that don't need the power of" + " a full blown editor.")) + + def __aboutQt(self): + """ + Private slot to handle the About Qt dialog. + """ + E5MessageBox.aboutQt(self, "eric6 Shell windindow") + + def __whatsThis(self): + """ + Private slot called in to enter Whats This mode. + """ + QWhatsThis.enterWhatsThisMode() + + ################################################################## + ## Below are the status bar handling methods + ################################################################## + + def __createStatusBar(self): + """ + Private slot to set up the status bar. + """ + self.__statusBar = self.statusBar() + self.__statusBar.setSizeGripEnabled(True) + + self.__sbZoom = E5ZoomWidget( + UI.PixmapCache.getPixmap("zoomOut.png"), + UI.PixmapCache.getPixmap("zoomIn.png"), + UI.PixmapCache.getPixmap("zoomReset.png"), + self.__statusBar) + self.__statusBar.addPermanentWidget(self.__sbZoom) + self.__sbZoom.setWhatsThis(self.tr( + """<p>This part of the status bar allows zooming the shell.</p>""" + )) + + self.__sbZoom.valueChanged.connect(self.__zoomTo) + self.__sbZoom.setValue(0)
--- a/eric6.e4p Wed Apr 19 19:02:34 2017 +0200 +++ b/eric6.e4p Thu Apr 20 20:09:53 2017 +0200 @@ -896,6 +896,7 @@ <Source>QScintilla/SearchReplaceWidget.py</Source> <Source>QScintilla/Shell.py</Source> <Source>QScintilla/ShellHistoryDialog.py</Source> + <Source>QScintilla/ShellWindow.py</Source> <Source>QScintilla/SortOptionsDialog.py</Source> <Source>QScintilla/SpellChecker.py</Source> <Source>QScintilla/SpellCheckingDialog.py</Source> @@ -1483,6 +1484,7 @@ <Source>eric6_qregularexpression.pyw</Source> <Source>eric6_re.py</Source> <Source>eric6_re.pyw</Source> + <Source>eric6_shell.py</Source> <Source>eric6_snap.py</Source> <Source>eric6_snap.pyw</Source> <Source>eric6_sqlbrowser.py</Source> @@ -1958,14 +1960,14 @@ <Interfaces/> <Others> <Other>.hgignore</Other> - <Other>APIs/Python/zope-2.10.7.api</Other> - <Other>APIs/Python/zope-2.11.2.api</Other> - <Other>APIs/Python/zope-3.3.1.api</Other> <Other>APIs/Python3/PyQt4.bas</Other> <Other>APIs/Python3/PyQt5.bas</Other> <Other>APIs/Python3/QScintilla2.bas</Other> <Other>APIs/Python3/eric6.api</Other> <Other>APIs/Python3/eric6.bas</Other> + <Other>APIs/Python/zope-2.10.7.api</Other> + <Other>APIs/Python/zope-2.11.2.api</Other> + <Other>APIs/Python/zope-3.3.1.api</Other> <Other>APIs/QSS/qss.api</Other> <Other>APIs/Ruby/Ruby-1.8.7.api</Other> <Other>APIs/Ruby/Ruby-1.8.7.bas</Other>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6_shell.py Thu Apr 20 20:09:53 2017 +0200 @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Eric6 Shell. + +This is the main Python script that performs the necessary initialization +of the ShellWindow module and starts the Qt event loop. +""" + +from __future__ import unicode_literals + +import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ + +try: # Only for Py2 + import Globals.compatibility_fixes # __IGNORE_WARNING__ +except (ImportError): + pass + +import sys +import os + +for arg in sys.argv[:]: + if arg.startswith("--config="): + import Globals + configDir = arg.replace("--config=", "") + Globals.setConfigDir(configDir) + sys.argv.remove(arg) + elif arg.startswith("--settings="): + from PyQt5.QtCore import QSettings + settingsDir = os.path.expanduser(arg.replace("--settings=", "")) + if not os.path.isdir(settingsDir): + os.makedirs(settingsDir) + QSettings.setPath(QSettings.IniFormat, QSettings.UserScope, + settingsDir) + sys.argv.remove(arg) + +### make ThirdParty package available as a packages repository +##sys.path.insert(2, os.path.join(os.path.dirname(__file__), +## "ThirdParty", "Pygments")) + +from Globals import AppInfo + +from Toolbox import Startup + + +def createMainWidget(argv): + """ + Function to create the main widget. + + @param argv list of commandline parameters (list of strings) + @return reference to the main widget (QWidget) + """ + from QScintilla.ShellWindow import ShellWindow + + return ShellWindow() + + +def main(): + """ + Main entry point into the application. + """ + options = [ + ("--config=configDir", + "use the given directory as the one containing the config files"), + ("--settings=settingsDir", + "use the given directory to store the settings files"), + ] + appinfo = AppInfo.makeAppInfo(sys.argv, + "Eric6 Shell", + "", + "Stand alone version of the eric6" + " interpreter shell", + options) + res = Startup.simpleAppStartup(sys.argv, + appinfo, + createMainWidget) + sys.exit(res) + +if __name__ == '__main__': + main()