diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/QScintilla/EditorOutline.py --- a/src/eric7/QScintilla/EditorOutline.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/QScintilla/EditorOutline.py Wed Jul 13 14:55:47 2022 +0200 @@ -10,14 +10,14 @@ import contextlib from PyQt6.QtCore import pyqtSlot, Qt, QCoreApplication, QModelIndex, QPoint -from PyQt6.QtWidgets import ( - QTreeView, QAbstractItemView, QMenu, QApplication, QDialog -) +from PyQt6.QtWidgets import QTreeView, QAbstractItemView, QMenu, QApplication, QDialog from UI.BrowserSortFilterProxyModel import BrowserSortFilterProxyModel from UI.BrowserModel import ( - BrowserImportsItem, BrowserGlobalsItem, BrowserClassAttributeItem, - BrowserImportItem + BrowserImportsItem, + BrowserGlobalsItem, + BrowserClassAttributeItem, + BrowserImportItem, ) from .EditorOutlineModel import EditorOutlineModel @@ -30,10 +30,11 @@ Class implementing an outline widget for source code navigation of the editor. """ + def __init__(self, editor, populate=True, parent=None): """ Constructor - + @param editor reference to the editor widget @type Editor @param populate flag indicating to populate the outline @@ -42,45 +43,44 @@ @type QWidget """ super().__init__(parent) - + self.__model = EditorOutlineModel(editor, populate=populate) self.__sortModel = BrowserSortFilterProxyModel() self.__sortModel.setSourceModel(self.__model) self.setModel(self.__sortModel) - + self.setRootIsDecorated(True) self.setAlternatingRowColors(True) - + header = self.header() header.setSortIndicator(0, Qt.SortOrder.AscendingOrder) header.setSortIndicatorShown(True) header.setSectionsClickable(True) self.setHeaderHidden(True) - + self.setSortingEnabled(True) - + self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) - self.setSelectionBehavior( - QAbstractItemView.SelectionBehavior.SelectRows) - + self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) + self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.customContextMenuRequested.connect(self.__contextMenuRequested) self.__createPopupMenus() - + self.activated.connect(self.__gotoItem) self.expanded.connect(self.__resizeColumns) self.collapsed.connect(self.__resizeColumns) - + self.__resizeColumns() - + self.__expandedNames = [] self.__currentItemName = "" self.__signalsConnected = False - + def setActive(self, active): """ Public method to activate or deactivate the outline view. - + @param active flag indicating the requested action @type bool """ @@ -90,38 +90,38 @@ editor.languageChanged.connect(self.__editorLanguageChanged) editor.editorRenamed.connect(self.__editorRenamed) editor.cursorLineChanged.connect(self.__editorCursorLineChanged) - + self.__model.repopulate() self.__resizeColumns() - + line, _ = editor.getCursorPosition() self.__editorCursorLineChanged(line) - + elif not active and self.__signalsConnected: editor = self.__model.editor() editor.refreshed.disconnect(self.repopulate) editor.languageChanged.disconnect(self.__editorLanguageChanged) editor.editorRenamed.disconnect(self.__editorRenamed) editor.cursorLineChanged.disconnect(self.__editorCursorLineChanged) - + self.__model.clear() - + @pyqtSlot() def __resizeColumns(self): """ Private slot to resize the view when items get expanded or collapsed. """ self.resizeColumnToContents(0) - + def isPopulated(self): """ Public method to check, if the model is populated. - + @return flag indicating a populated model @rtype bool """ return self.__model.isPopulated() - + @pyqtSlot() def repopulate(self): """ @@ -131,7 +131,7 @@ self.__prepareRepopulate() self.__model.repopulate() self.__completeRepopulate() - + @pyqtSlot() def __prepareRepopulate(self): """ @@ -140,16 +140,15 @@ itm = self.__currentItem() if itm is not None: self.__currentItemName = itm.data(0) - + self.__expandedNames = [] - + childIndex = self.model().index(0, 0) while childIndex.isValid(): if self.isExpanded(childIndex): - self.__expandedNames.append( - self.model().item(childIndex).data(0)) + self.__expandedNames.append(self.model().item(childIndex).data(0)) childIndex = self.indexBelow(childIndex) - + @pyqtSlot() def __completeRepopulate(self): """ @@ -158,32 +157,32 @@ childIndex = self.model().index(0, 0) while childIndex.isValid(): name = self.model().item(childIndex).data(0) - if (self.__currentItemName and self.__currentItemName == name): + if self.__currentItemName and self.__currentItemName == name: self.setCurrentIndex(childIndex) if name in self.__expandedNames: self.setExpanded(childIndex, True) childIndex = self.indexBelow(childIndex) self.__resizeColumns() - + self.__expandedNames = [] self.__currentItemName = "" - + def isSupportedLanguage(self, language): """ Public method to check, if outlining a given language is supported. - + @param language source language to be checked @type str @return flag indicating support @rtype bool """ return language in EditorOutlineModel.SupportedLanguages - + @pyqtSlot(QModelIndex) def __gotoItem(self, index): """ Private slot to set the editor cursor. - + @param index index of the item to set the cursor for @type QModelIndex """ @@ -193,14 +192,14 @@ with contextlib.suppress(AttributeError): lineno = itm.lineno() self.__model.editor().gotoLine(lineno) - + def mouseDoubleClickEvent(self, mouseEvent): """ Protected method of QAbstractItemView. - + Reimplemented to disable expanding/collapsing of items when double-clicking. Instead the double-clicked entry is opened. - + @param mouseEvent the mouse event (QMouseEvent) """ index = self.indexAt(mouseEvent.position().toPoint()) @@ -210,21 +209,21 @@ self.setExpanded(index, not self.isExpanded(index)) else: self.__gotoItem(index) - + def __currentItem(self): """ Private method to get a reference to the current item. - + @return reference to the current item @rtype BrowserItem """ itm = self.model().item(self.currentIndex()) return itm - + ####################################################################### ## Context menu methods below ####################################################################### - + def __createPopupMenus(self): """ Private method to generate the various popup menus. @@ -232,149 +231,146 @@ # create the popup menu for general use self.__menu = QMenu(self) self.__menu.addAction( - QCoreApplication.translate('EditorOutlineView', 'Goto'), - self.__goto) + QCoreApplication.translate("EditorOutlineView", "Goto"), self.__goto + ) self.__menu.addSeparator() self.__menu.addAction( - QCoreApplication.translate('EditorOutlineView', 'Refresh'), - self.repopulate) + QCoreApplication.translate("EditorOutlineView", "Refresh"), self.repopulate + ) self.__menu.addSeparator() self.__menu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Copy Path to Clipboard'), - self.__copyToClipboard) + QCoreApplication.translate("EditorOutlineView", "Copy Path to Clipboard"), + self.__copyToClipboard, + ) self.__menu.addSeparator() self.__menu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Expand All'), - lambda: self.expandToDepth(-1)) + QCoreApplication.translate("EditorOutlineView", "Expand All"), + lambda: self.expandToDepth(-1), + ) self.__menu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Collapse All'), - self.collapseAll) + QCoreApplication.translate("EditorOutlineView", "Collapse All"), + self.collapseAll, + ) self.__menu.addSeparator() self.__menu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Increment Width'), - self.__incWidth) + QCoreApplication.translate("EditorOutlineView", "Increment Width"), + self.__incWidth, + ) self.__decWidthAct = self.__menu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Decrement Width'), - self.__decWidth) + QCoreApplication.translate("EditorOutlineView", "Decrement Width"), + self.__decWidth, + ) self.__menu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Set to Default Width'), - self.__defaultWidth) + QCoreApplication.translate("EditorOutlineView", "Set to Default Width"), + self.__defaultWidth, + ) self.__menu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Change Default Width'), - self.__changeDefaultWidth) - + QCoreApplication.translate("EditorOutlineView", "Change Default Width"), + self.__changeDefaultWidth, + ) + # create the attribute/import menu self.__gotoMenu = QMenu( - QCoreApplication.translate('EditorOutlineView', "Goto"), - self) + QCoreApplication.translate("EditorOutlineView", "Goto"), self + ) self.__gotoMenu.aboutToShow.connect(self.__showGotoMenu) self.__gotoMenu.triggered.connect(self.__gotoAttribute) - + self.__attributeMenu = QMenu(self) self.__attributeMenu.addMenu(self.__gotoMenu) self.__attributeMenu.addSeparator() self.__attributeMenu.addAction( - QCoreApplication.translate('EditorOutlineView', 'Refresh'), - self.repopulate) + QCoreApplication.translate("EditorOutlineView", "Refresh"), self.repopulate + ) self.__attributeMenu.addSeparator() self.__attributeMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Copy Path to Clipboard'), - self.__copyToClipboard) + QCoreApplication.translate("EditorOutlineView", "Copy Path to Clipboard"), + self.__copyToClipboard, + ) self.__attributeMenu.addSeparator() self.__attributeMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Expand All'), - lambda: self.expandToDepth(-1)) + QCoreApplication.translate("EditorOutlineView", "Expand All"), + lambda: self.expandToDepth(-1), + ) self.__attributeMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Collapse All'), - self.collapseAll) + QCoreApplication.translate("EditorOutlineView", "Collapse All"), + self.collapseAll, + ) self.__attributeMenu.addSeparator() self.__attributeMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Increment Width'), - self.__incWidth) + QCoreApplication.translate("EditorOutlineView", "Increment Width"), + self.__incWidth, + ) self.__attributeDecWidthAct = self.__attributeMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Decrement Width'), - self.__decWidth) + QCoreApplication.translate("EditorOutlineView", "Decrement Width"), + self.__decWidth, + ) self.__attributeMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Set to Default Width'), - self.__defaultWidth) + QCoreApplication.translate("EditorOutlineView", "Set to Default Width"), + self.__defaultWidth, + ) self.__attributeMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Change Default Width'), - self.__changeDefaultWidth) - + QCoreApplication.translate("EditorOutlineView", "Change Default Width"), + self.__changeDefaultWidth, + ) + # create the background menu self.__backMenu = QMenu(self) self.__backMenu.addAction( - QCoreApplication.translate('EditorOutlineView', 'Refresh'), - self.repopulate) + QCoreApplication.translate("EditorOutlineView", "Refresh"), self.repopulate + ) self.__backMenu.addSeparator() self.__backMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Copy Path to Clipboard'), - self.__copyToClipboard) + QCoreApplication.translate("EditorOutlineView", "Copy Path to Clipboard"), + self.__copyToClipboard, + ) self.__backMenu.addSeparator() self.__backMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Expand All'), - lambda: self.expandToDepth(-1)) + QCoreApplication.translate("EditorOutlineView", "Expand All"), + lambda: self.expandToDepth(-1), + ) self.__backMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Collapse All'), - self.collapseAll) + QCoreApplication.translate("EditorOutlineView", "Collapse All"), + self.collapseAll, + ) self.__backMenu.addSeparator() self.__backMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Increment Width'), - self.__incWidth) + QCoreApplication.translate("EditorOutlineView", "Increment Width"), + self.__incWidth, + ) self.__backDecWidthAct = self.__backMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Decrement Width'), - self.__decWidth) + QCoreApplication.translate("EditorOutlineView", "Decrement Width"), + self.__decWidth, + ) self.__backMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Set to Default Width'), - self.__defaultWidth) + QCoreApplication.translate("EditorOutlineView", "Set to Default Width"), + self.__defaultWidth, + ) self.__backMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', 'Change Default Width'), - self.__changeDefaultWidth) - + QCoreApplication.translate("EditorOutlineView", "Change Default Width"), + self.__changeDefaultWidth, + ) + @pyqtSlot(QPoint) def __contextMenuRequested(self, coord): """ Private slot to show the context menu. - + @param coord position of the mouse pointer @type QPoint """ index = self.indexAt(coord) coord = self.mapToGlobal(coord) - - decWidthEnable = ( - self.maximumWidth() != - 2 * Preferences.getEditor("SourceOutlineStepSize") + + decWidthEnable = self.maximumWidth() != 2 * Preferences.getEditor( + "SourceOutlineStepSize" ) - + if index.isValid(): self.setCurrentIndex(index) - + itm = self.model().item(index) - if isinstance( - itm, (BrowserClassAttributeItem, BrowserImportItem) - ): + if isinstance(itm, (BrowserClassAttributeItem, BrowserImportItem)): self.__attributeDecWidthAct.setEnabled(decWidthEnable) self.__attributeMenu.popup(coord) else: @@ -383,14 +379,14 @@ else: self.__backDecWidthAct.setEnabled(decWidthEnable) self.__backMenu.popup(coord) - + @pyqtSlot() def __showGotoMenu(self): """ Private slot to prepare the goto submenu of the attribute menu. """ self.__gotoMenu.clear() - + itm = self.model().item(self.currentIndex()) try: linenos = itm.linenos() @@ -399,56 +395,57 @@ linenos = [itm.lineno()] except AttributeError: return - + for lineno in sorted(linenos): act = self.__gotoMenu.addAction( - QCoreApplication.translate( - 'EditorOutlineView', "Line {0}").format(lineno)) + QCoreApplication.translate("EditorOutlineView", "Line {0}").format( + lineno + ) + ) act.setData(lineno) - + ####################################################################### ## Context menu handlers below ####################################################################### - + @pyqtSlot() def __gotoAttribute(self, act): """ Private slot to handle the selection of the goto menu. - + @param act reference to the action (EricAction) """ lineno = act.data() self.__model.editor().gotoLine(lineno) - + @pyqtSlot() def __goto(self): """ Private slot to move the editor cursor to the line of the context item. """ self.__gotoItem(self.currentIndex()) - + @pyqtSlot() def __copyToClipboard(self): """ Private slot to copy the file name of the editor to the clipboard. """ fn = self.__model.fileName() - + if fn: cb = QApplication.clipboard() cb.setText(fn) - + @pyqtSlot() def __incWidth(self): """ Private slot to increment the width of the outline. """ self.setMaximumWidth( - self.maximumWidth() + - Preferences.getEditor("SourceOutlineStepSize") + self.maximumWidth() + Preferences.getEditor("SourceOutlineStepSize") ) self.updateGeometry() - + @pyqtSlot() def __decWidth(self): """ @@ -456,10 +453,10 @@ """ stepSize = Preferences.getEditor("SourceOutlineStepSize") newWidth = self.maximumWidth() - stepSize - + self.setMaximumWidth(max(newWidth, 2 * stepSize)) self.updateGeometry() - + @pyqtSlot() def __defaultWidth(self): """ @@ -467,7 +464,7 @@ """ self.setMaximumWidth(Preferences.getEditor("SourceOutlineWidth")) self.updateGeometry() - + @pyqtSlot() def __changeDefaultWidth(self): """ @@ -475,25 +472,25 @@ size presetting the width with the current value. """ from .EditorOutlineSizesDialog import EditorOutlineSizesDialog - + stepSize = Preferences.getEditor("SourceOutlineStepSize") defaultWidth = Preferences.getEditor("SourceOutlineWidth") currentWidth = self.maximumWidth() - + dlg = EditorOutlineSizesDialog(currentWidth, defaultWidth, stepSize) if dlg.exec() == QDialog.DialogCode.Accepted: newDefaultWidth, stepSize = dlg.getSizes() - + Preferences.setEditor("SourceOutlineWidth", newDefaultWidth) Preferences.setEditor("SourceOutlineStepSize", stepSize) - + if newDefaultWidth != currentWidth: self.__defaultWidth() - + ####################################################################### ## Methods handling editor signals below ####################################################################### - + @pyqtSlot() def __editorLanguageChanged(self): """ @@ -502,7 +499,7 @@ """ self.__model.repopulate() self.__resizeColumns() - + @pyqtSlot() def __editorRenamed(self): """ @@ -510,12 +507,12 @@ """ self.__model.repopulate() self.__resizeColumns() - + @pyqtSlot(int) def __editorCursorLineChanged(self, lineno): """ Private method to highlight a node given its line number. - + @param lineno zero based line number of the item @type int """