--- a/src/eric7/Plugins/ViewManagerPlugins/Listspace/Listspace.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Plugins/ViewManagerPlugins/Listspace/Listspace.py Wed Jul 13 14:55:47 2022 +0200 @@ -11,8 +11,13 @@ from PyQt6.QtCore import pyqtSignal, pyqtSlot, QEvent, Qt from PyQt6.QtWidgets import ( - QStackedWidget, QSplitter, QListWidget, QListWidgetItem, QSizePolicy, - QMenu, QApplication + QStackedWidget, + QSplitter, + QListWidget, + QListWidgetItem, + QSizePolicy, + QMenu, + QApplication, ) from EricWidgets.EricApplication import ericApp @@ -31,21 +36,22 @@ """ Class implementing a custimized StackedWidget. """ + def __init__(self, parent): """ Constructor - + @param parent parent widget @type QWidget """ super().__init__(parent) - + self.editors = [] - + def addWidget(self, assembly): """ Public method to add a new widget. - + @param assembly editor assembly object to be added @type QScintilla.EditorAssembly.EditorAssembly """ @@ -53,11 +59,11 @@ super().addWidget(assembly) if editor not in self.editors: self.editors.append(editor) - + def removeWidget(self, widget): """ Public method to remove a widget. - + @param widget widget to be removed @type QWidget """ @@ -65,11 +71,11 @@ self.editors.remove(widget) widget = widget.parent() super().removeWidget(widget) - + def currentWidget(self): """ Public method to get a reference to the current editor. - + @return reference to the current editor @rtype Editor """ @@ -77,11 +83,11 @@ if widget is not None: widget = widget.getEditor() return widget - + def setCurrentWidget(self, widget): """ Public method to set the current widget. - + @param widget widget to be made current @type QWidget """ @@ -91,18 +97,18 @@ self.editors.insert(0, widget) widget = widget.parent() super().setCurrentWidget(widget) - + def setCurrentIndex(self, index): """ Public method to set the current widget by its index. - + @param index index of widget to be made current @type int """ widget = self.widget(index) if widget is not None: self.setCurrentWidget(widget) - + def nextTab(self): """ Public slot used to show the next tab. @@ -110,7 +116,7 @@ ind = self.currentIndex() + 1 if ind == self.count(): ind = 0 - + self.setCurrentIndex(ind) self.currentWidget().setFocus() @@ -121,14 +127,14 @@ ind = self.currentIndex() - 1 if ind == -1: ind = self.count() - 1 - + self.setCurrentIndex(ind) self.currentWidget().setFocus() def hasEditor(self, editor): """ Public method to check for an editor. - + @param editor editor object to check for @type Editor @return flag indicating, whether the editor to be checked belongs @@ -136,12 +142,12 @@ @rtype bool """ return editor in self.editors - + def firstEditor(self): """ Public method to retrieve the first editor in the list of managed editors. - + @return first editor in list @rtype QScintilla.Editor.Editor """ @@ -151,7 +157,7 @@ class Listspace(ViewManager): """ Class implementing the listspace viewmanager class. - + @signal changeCaption(str) emitted if a change of the caption is necessary @signal editorChanged(str) emitted when the current editor has changed @signal editorChangedEd(Editor) emitted when the current editor has changed @@ -187,6 +193,7 @@ @signal editorLineChangedEd(Editor,int) emitted to signal a change of an editor's current line (line is given one based) """ + changeCaption = pyqtSignal(str) editorChanged = pyqtSignal(str) editorChangedEd = pyqtSignal(Editor) @@ -210,30 +217,29 @@ editorTextChanged = pyqtSignal(Editor) editorLineChanged = pyqtSignal(str, int) editorLineChangedEd = pyqtSignal(Editor, int) - + def __init__(self, parent): """ Constructor - + @param parent parent widget @type QWidget """ self.stacks = [] - + self.__splitter = QSplitter(parent) ViewManager.__init__(self) self.__splitter.setChildrenCollapsible(False) - + self.viewlist = QListWidget(self) policy = self.viewlist.sizePolicy() policy.setHorizontalPolicy(QSizePolicy.Policy.Ignored) self.viewlist.setSizePolicy(policy) self.__splitter.addWidget(self.viewlist) - self.viewlist.setContextMenuPolicy( - Qt.ContextMenuPolicy.CustomContextMenu) + self.viewlist.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.viewlist.currentRowChanged.connect(self.__showSelectedView) self.viewlist.customContextMenuRequested.connect(self.__showMenu) - + self.stackArea = QSplitter(self) self.stackArea.setChildrenCollapsible(False) self.__splitter.addWidget(self.stackArea) @@ -244,15 +250,14 @@ self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) - self.__splitter.setSizes( - [int(self.width() * 0.2), int(self.width() * 0.8)]) + self.__splitter.setSizes([int(self.width() * 0.2), int(self.width() * 0.8)]) # 20% for viewlist, 80% for the editors self.__inRemoveView = False - + self.__initMenu() self.contextMenuEditor = None self.contextMenuIndex = -1 - + def __initMenu(self): """ Private method to initialize the viewlist context menu. @@ -260,64 +265,78 @@ self.__startMenu = QMenu(self.tr("Start"), self) self.__startMenu.addAction( UI.PixmapCache.getIcon("runScript"), - self.tr('Run Script...'), - self.__contextMenuRunScript) + self.tr("Run Script..."), + self.__contextMenuRunScript, + ) self.__startMenu.addAction( UI.PixmapCache.getIcon("debugScript"), - self.tr('Debug Script...'), - self.__contextMenuDebugScript) + self.tr("Debug Script..."), + self.__contextMenuDebugScript, + ) self.__startMenu.addAction( UI.PixmapCache.getIcon("profileScript"), - self.tr('Profile Script...'), - self.__contextMenuProfileScript) + self.tr("Profile Script..."), + self.__contextMenuProfileScript, + ) self.__startMenu.addAction( UI.PixmapCache.getIcon("coverageScript"), - self.tr('Coverage run of Script...'), - self.__contextMenuCoverageScript) - + self.tr("Coverage run of Script..."), + self.__contextMenuCoverageScript, + ) + self.__menu = QMenu(self) self.__menu.addAction( UI.PixmapCache.getIcon("tabClose"), - self.tr('Close'), self.__contextMenuClose) + self.tr("Close"), + self.__contextMenuClose, + ) self.closeOthersMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("tabCloseOther"), self.tr("Close Others"), - self.__contextMenuCloseOthers) - self.__menu.addAction( - self.tr('Close All'), self.__contextMenuCloseAll) + self.__contextMenuCloseOthers, + ) + self.__menu.addAction(self.tr("Close All"), self.__contextMenuCloseAll) self.__menu.addSeparator() self.saveMenuAct = self.__menu.addAction( - UI.PixmapCache.getIcon("fileSave"), - self.tr('Save'), self.__contextMenuSave) + UI.PixmapCache.getIcon("fileSave"), self.tr("Save"), self.__contextMenuSave + ) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAs"), - self.tr('Save As...'), self.__contextMenuSaveAs) + self.tr("Save As..."), + self.__contextMenuSaveAs, + ) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAll"), - self.tr('Save All'), self.__contextMenuSaveAll) + self.tr("Save All"), + self.__contextMenuSaveAll, + ) self.__menu.addSeparator() self.openRejectionsMenuAct = self.__menu.addAction( - self.tr("Open 'rejection' file"), - self.__contextMenuOpenRejections) + self.tr("Open 'rejection' file"), self.__contextMenuOpenRejections + ) self.__menu.addSeparator() self.__startAct = self.__menu.addMenu(self.__startMenu) self.__menu.addSeparator() self.__menu.addAction( UI.PixmapCache.getIcon("printPreview"), - self.tr("Print Preview"), self.__contextMenuPrintPreviewFile) + self.tr("Print Preview"), + self.__contextMenuPrintPreviewFile, + ) self.__menu.addAction( UI.PixmapCache.getIcon("print"), - self.tr('Print'), self.__contextMenuPrintFile) + self.tr("Print"), + self.__contextMenuPrintFile, + ) self.__menu.addSeparator() self.copyPathAct = self.__menu.addAction( - self.tr("Copy Path to Clipboard"), - self.__contextMenuCopyPathToClipboard) - + self.tr("Copy Path to Clipboard"), self.__contextMenuCopyPathToClipboard + ) + def __showMenu(self, point): """ Private slot to handle the customContextMenuRequested signal of the viewlist. - + @param point position to open the menu at @type QPoint """ @@ -328,78 +347,74 @@ self.contextMenuEditor = self.editors[row] self.contextMenuIndex = row if self.contextMenuEditor: - self.saveMenuAct.setEnabled( - self.contextMenuEditor.isModified()) + self.saveMenuAct.setEnabled(self.contextMenuEditor.isModified()) fileName = self.contextMenuEditor.getFileName() self.copyPathAct.setEnabled(bool(fileName)) if fileName: rej = "{0}.rej".format(fileName) - self.openRejectionsMenuAct.setEnabled( - os.path.exists(rej)) - + self.openRejectionsMenuAct.setEnabled(os.path.exists(rej)) + ext = os.path.splitext(fileName)[1] self.__startAct.setEnabled( - ext in Preferences.getDebugger( - "Python3Extensions").split() + ext in Preferences.getDebugger("Python3Extensions").split() ) else: self.openRejectionsMenuAct.setEnabled(False) self.__startAct.setEnabled(False) - - self.closeOthersMenuAct.setEnabled( - self.viewlist.count() > 1) - + + self.closeOthersMenuAct.setEnabled(self.viewlist.count() > 1) + self.__menu.popup(self.viewlist.mapToGlobal(point)) - + def mainWidget(self): """ Public method to return a reference to the main Widget of a specific view manager subclass. - + @return reference to the main widget @rtype QWidget """ return self.__splitter - + def canCascade(self): """ Public method to signal if cascading of managed windows is available. - + @return flag indicating cascading of windows is available @rtype bool """ return False - + def canTile(self): """ Public method to signal if tiling of managed windows is available. - + @return flag indicating tiling of windows is available @rtype bool """ return False - + def canSplit(self): """ public method to signal if splitting of the view is available. - + @return flag indicating splitting of the view is available @rtype bool """ return True - + def tile(self): """ Public method to tile the managed windows. """ pass - + def cascade(self): """ Public method to cascade the managed windows. """ pass - + def _removeAllViews(self): """ Protected method to remove all views (i.e. windows). @@ -411,11 +426,11 @@ stack.removeWidget(win) break win.closeIt() - + def _removeView(self, win): """ Protected method to remove a view (i.e. window). - + @param win editor window to be removed @type Editor """ @@ -439,7 +454,7 @@ return stack.setCurrentWidget(stack.firstEditor()) self._showView(self.editors[ind].parent()) - + aw = self.activeWindow() fn = aw and aw.getFileName() or None if fn: @@ -449,11 +464,11 @@ else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) - + def _addView(self, win, fn=None, noName="", addNext=False, indexes=None): """ Protected method to add a view (i.e. window). - + @param win editor assembly to be added @type EditorAssembly @param fn filename of this editor @@ -492,8 +507,9 @@ self.currentStack.setCurrentWidget(win) editor.captionChanged.connect(self.__captionChange) editor.cursorLineChanged.connect( - lambda lineno: self.__cursorLineChanged(lineno, editor)) - + lambda lineno: self.__cursorLineChanged(lineno, editor) + ) + index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() @@ -504,13 +520,13 @@ else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) - + def __captionChange(self, cap, editor): """ Private method to handle caption change signals from the editor. - + Updates the listwidget text to reflect the new caption information. - + @param cap Caption for the editor @type str @param editor Editor to update the caption for @@ -519,11 +535,11 @@ fn = editor.getFileName() if fn: self.setEditorName(editor, fn) - + def __cursorLineChanged(self, lineno, editor): """ Private slot to handle a change of the current editor's cursor line. - + @param lineno line number of the editor's cursor (zero based) @type int @param editor reference to the editor @@ -534,11 +550,11 @@ if fn: self.editorLineChanged.emit(fn, lineno + 1) self.editorLineChangedEd.emit(editor, lineno + 1) - + def _showView(self, win, fn=None): """ Protected method to show a view (i.e. window). - + @param win editor assembly to be shown @type EditorAssembly @param fn filename of this editor @@ -561,47 +577,47 @@ else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) - + def __showSelectedView(self, row): """ Private slot called to show a view selected in the list. - + @param row row number of the item clicked on @type int """ if row != -1: self._showView(self.editors[row].parent()) self._checkActions(self.editors[row]) - + def activeWindow(self): """ Public method to return the active (i.e. current) window. - + @return reference to the active editor @rtype EditorAssembly """ return self.currentStack.currentWidget() - + def showWindowMenu(self, windowMenu): """ Public method to set up the viewmanager part of the Window menu. - + @param windowMenu reference to the window menu @type QMenu """ pass - + def _initWindowActions(self): """ Protected method to define the user interface actions for window handling. """ pass - + def setEditorName(self, editor, newName): """ Public method to change the displayed name of the editor. - + @param editor editor window to be changed @type Editor @param newName new name to be shown @@ -619,11 +635,11 @@ itm.setToolTip(newName) self.viewlist.setCurrentRow(currentRow) self.changeCaption.emit(newName) - + def _modificationStatusChanged(self, m, editor): """ Protected slot to handle the modificationStatusChanged signal. - + @param m flag indicating the modification status @type bool @param editor editor window changed @@ -645,11 +661,11 @@ item.setIcon(UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) self._checkActions(editor) - + def _syntaxErrorToggled(self, editor): """ Protected slot to handle the syntaxerrorToggled signal. - + @param editor editor that sent the signal @type Editor """ @@ -668,9 +684,9 @@ if item: item.setIcon(UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) - + ViewManager._syntaxErrorToggled(self, editor) - + def addSplit(self): """ Public method used to split the current view. @@ -684,21 +700,20 @@ stack.installEventFilter(self) size = ( self.stackArea.width() - if self.stackArea.orientation() == Qt.Orientation.Horizontal else - self.stackArea.height() + if self.stackArea.orientation() == Qt.Orientation.Horizontal + else self.stackArea.height() ) - self.stackArea.setSizes( - [int(size / len(self.stacks))] * len(self.stacks)) + self.stackArea.setSizes([int(size / len(self.stacks))] * len(self.stacks)) self.splitRemoveAct.setEnabled(True) self.nextSplitAct.setEnabled(True) self.prevSplitAct.setEnabled(True) - + @pyqtSlot() def removeSplit(self, index=-1): """ Public method used to remove the current split view or a split view by index. - + @param index index of the split to be removed (-1 means to delete the current split) @type int @@ -732,22 +747,22 @@ self.nextSplitAct.setEnabled(False) self.prevSplitAct.setEnabled(False) return True - + return False - + def splitCount(self): """ Public method to get the number of splitted views. - + @return number of splitted views @rtype int """ return len(self.stacks) - + def setSplitCount(self, count): """ Public method to set the number of split views. - + @param count number of split views @type int """ @@ -758,25 +773,25 @@ while self.splitCount() > count: # use an arbitrarily large index to remove the last one self.removeSplit(index=100) - + def getSplitOrientation(self): """ Public method to get the orientation of the split view. - + @return orientation of the split @rtype Qt.Orientation.Horizontal or Qt.Orientation.Vertical """ return self.stackArea.orientation() - + def setSplitOrientation(self, orientation): """ Public method used to set the orientation of the split view. - + @param orientation orientation of the split @type Qt.Orientation.Horizontal or Qt.Orientation.Vertical """ self.stackArea.setOrientation(orientation) - + def nextSplit(self): """ Public slot used to move to the next split. @@ -786,18 +801,18 @@ ind = self.stacks.index(self.currentStack) + 1 if ind == len(self.stacks): ind = 0 - + self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() - + cw = self.currentStack.currentWidget() if cw: index = self.editors.index(cw) self.viewlist.setCurrentRow(index) - + def prevSplit(self): """ Public slot used to move to the previous split. @@ -807,37 +822,36 @@ ind = self.stacks.index(self.currentStack) - 1 if ind == -1: ind = len(self.stacks) - 1 - + self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() - + cw = self.currentStack.currentWidget() if cw: index = self.editors.index(cw) self.viewlist.setCurrentRow(index) - + def __contextMenuClose(self): """ Private method to close the selected editor. """ if self.contextMenuEditor: self.closeEditorWindow(self.contextMenuEditor) - + def __contextMenuCloseOthers(self): """ Private method to close the other editors. """ index = self.contextMenuIndex - for i in ( - list(range(self.viewlist.count() - 1, index, -1)) + - list(range(index - 1, -1, -1)) + for i in list(range(self.viewlist.count() - 1, index, -1)) + list( + range(index - 1, -1, -1) ): editor = self.editors[i] self.closeEditorWindow(editor) - + def __contextMenuCloseAll(self): """ Private method to close all editors. @@ -845,27 +859,27 @@ savedEditors = self.editors[:] for editor in savedEditors: self.closeEditorWindow(editor) - + def __contextMenuSave(self): """ Private method to save the selected editor. """ if self.contextMenuEditor: self.saveEditorEd(self.contextMenuEditor) - + def __contextMenuSaveAs(self): """ Private method to save the selected editor to a new file. """ if self.contextMenuEditor: self.saveAsEditorEd(self.contextMenuEditor) - + def __contextMenuSaveAll(self): """ Private method to save all editors. """ self.saveEditorsList(self.editors) - + def __contextMenuOpenRejections(self): """ Private slot to open a rejections file associated with the selected @@ -877,21 +891,21 @@ rej = "{0}.rej".format(fileName) if os.path.exists(rej): self.openSourceFile(rej) - + def __contextMenuPrintFile(self): """ Private method to print the selected editor. """ if self.contextMenuEditor: self.printEditor(self.contextMenuEditor) - + def __contextMenuPrintPreviewFile(self): """ Private method to show a print preview of the selected editor. """ if self.contextMenuEditor: self.printPreviewEditor(self.contextMenuEditor) - + def __contextMenuCopyPathToClipboard(self): """ Private method to copy the file name of the selected editor to the @@ -902,7 +916,7 @@ if fn: cb = QApplication.clipboard() cb.setText(fn) - + def __contextMenuRunScript(self): """ Private method to run the editor script. @@ -911,7 +925,7 @@ fn = self.contextMenuEditor.getFileName() if fn: ericApp().getObject("DebugUI").doRun(False, script=fn) - + def __contextMenuDebugScript(self): """ Private method to debug the editor script. @@ -920,7 +934,7 @@ fn = self.contextMenuEditor.getFileName() if fn: ericApp().getObject("DebugUI").doDebug(False, script=fn) - + def __contextMenuProfileScript(self): """ Private method to profile the editor script. @@ -929,7 +943,7 @@ fn = self.contextMenuEditor.getFileName() if fn: ericApp().getObject("DebugUI").doProfile(False, script=fn) - + def __contextMenuCoverageScript(self): """ Private method to run a coverage test of the editor script. @@ -938,21 +952,21 @@ fn = self.contextMenuEditor.getFileName() if fn: ericApp().getObject("DebugUI").doCoverage(False, script=fn) - + def __currentChanged(self, index): """ Private slot to handle the currentChanged signal. - + @param index index of the current editor @type int """ if index == -1 or not self.editors: return - + editor = self.activeWindow() if editor is None: return - + self._checkActions(editor) editor.setFocus() fn = editor.getFileName() @@ -960,19 +974,18 @@ self.changeCaption.emit(fn) if not self.__inRemoveView: self.editorChanged.emit(fn) - self.editorLineChanged.emit( - fn, editor.getCursorPosition()[0] + 1) + self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) - + cindex = self.editors.index(editor) self.viewlist.setCurrentRow(cindex) - + def eventFilter(self, watched, event): """ Public method called to filter the event queue. - + @param watched the QObject being watched @type QObject @param event the event that occurred @@ -981,8 +994,8 @@ @rtype bool """ if ( - event.type() == QEvent.Type.MouseButtonPress and - event.button() != Qt.MouseButton.RightButton + event.type() == QEvent.Type.MouseButtonPress + and event.button() != Qt.MouseButton.RightButton ): switched = True if isinstance(watched, QStackedWidget): @@ -998,7 +1011,7 @@ if currentWidget: index = self.editors.index(currentWidget) self.viewlist.setCurrentRow(index) - + aw = self.activeWindow() if aw is not None: self._checkActions(aw) @@ -1008,21 +1021,20 @@ self.changeCaption.emit(fn) if switched: self.editorChanged.emit(fn) - self.editorLineChanged.emit( - fn, aw.getCursorPosition()[0] + 1) + self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) - + return False - + def getOpenEditorsForSession(self): """ Public method to get a lists of all open editors. - + The returned list contains one list per split view. If the view manager cannot split the view, only one list of editors is returned. - + @return list of list of editor references @rtype list of list of Editor """