--- a/eric6/QScintilla/EditorOutline.py Fri Sep 04 18:48:52 2020 +0200 +++ b/eric6/QScintilla/EditorOutline.py Fri Sep 04 18:50:43 2020 +0200 @@ -7,7 +7,7 @@ Module implementing an outline widget for source code navigation of the editor. """ -from PyQt5.QtCore import Qt, QCoreApplication, QItemSelectionModel +from PyQt5.QtCore import pyqtSlot, Qt, QCoreApplication from PyQt5.QtWidgets import QTreeView, QAbstractItemView, QMenu, QApplication from UI.BrowserSortFilterProxyModel import BrowserSortFilterProxyModel @@ -19,27 +19,27 @@ from .EditorOutlineModel import EditorOutlineModel -# TODO: handle editor signal 'cursorLineChanged' -# TODO: handle editor signal 'languageChanged' -# TODO: handle editor signal 'refreshed' -# TODO: handle editor signal 'editorRenamed' class EditorOutlineView(QTreeView): """ Class implementing an outline widget for source code navigation of the editor. """ - def __init__(self, editor, parent=None): + WidthIncrement = 50 + + 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 + @type bool @param parent reference to the parent widget @type QWidget """ super(EditorOutlineView, self).__init__(parent) - self.__model = EditorOutlineModel(editor) + self.__model = EditorOutlineModel(editor, populate=populate) self.__sortModel = BrowserSortFilterProxyModel() self.__sortModel.setSourceModel(self.__model) self.setModel(self.__sortModel) @@ -70,6 +70,36 @@ 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 + """ + if active and not self.__signalsConnected: + editor = self.__model.editor() + editor.refreshed.connect(self.repopulate) + 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() def __resizeColumns(self): """ @@ -124,6 +154,7 @@ if name in self.__expandedNames: self.setExpanded(childIndex, True) childIndex = self.indexBelow(childIndex) + self.__resizeColumns() self.__expandedNames = [] self.__currentItemName = "" @@ -205,6 +236,15 @@ QCoreApplication.translate( 'EditorOutlineView', 'Copy Path to Clipboard'), self.__copyToClipboard) + self.__menu.addSeparator() + self.__menu.addAction( + QCoreApplication.translate( + 'EditorOutlineView', 'Increment Width'), + self.__incWidth) + self.__menu.addAction( + QCoreApplication.translate( + 'EditorOutlineView', 'Decrement Width'), + self.__decWidth) # create the attribute/import menu self.__gotoMenu = QMenu( @@ -224,6 +264,15 @@ QCoreApplication.translate( 'EditorOutlineView', 'Copy Path to Clipboard'), self.__copyToClipboard) + self.__attributeMenu.addSeparator() + self.__attributeMenu.addAction( + QCoreApplication.translate( + 'EditorOutlineView', 'Increment Width'), + self.__incWidth) + self.__attributeMenu.addAction( + QCoreApplication.translate( + 'EditorOutlineView', 'Decrement Width'), + self.__decWidth) # create the background menu self.__backMenu = QMenu(self) @@ -235,6 +284,15 @@ QCoreApplication.translate( 'EditorOutlineView', 'Copy Path to Clipboard'), self.__copyToClipboard) + self.__backMenu.addSeparator() + self.__backMenu.addAction( + QCoreApplication.translate( + 'EditorOutlineView', 'Increment Width'), + self.__incWidth) + self.__backMenu.addAction( + QCoreApplication.translate( + 'EditorOutlineView', 'Decrement Width'), + self.__decWidth) def __contextMenuRequested(self, coord): """ @@ -243,15 +301,11 @@ @param coord position of the mouse pointer @type QPoint """ + index = self.indexAt(coord) coord = self.mapToGlobal(coord) - index = self.indexAt(coord) if index.isValid(): self.setCurrentIndex(index) - flags = QItemSelectionModel.SelectionFlags( - QItemSelectionModel.ClearAndSelect | - QItemSelectionModel.Rows) - self.selectionModel().select(index, flags) itm = self.model().item(index) if isinstance( @@ -312,3 +366,55 @@ if fn: cb = QApplication.clipboard() cb.setText(fn) + + def __incWidth(self): + """ + Private method to increment the width of the outline. + """ + self.setMaximumWidth( + self.maximumWidth() + EditorOutlineView.WidthIncrement) + self.updateGeometry() + + def __decWidth(self): + """ + Private method to decrement the width of the outline. + """ + self.setMaximumWidth( + self.maximumWidth() - EditorOutlineView.WidthIncrement) + self.updateGeometry() + + ####################################################################### + ## Methods handling editor signals below + ####################################################################### + + @pyqtSlot() + def __editorLanguageChanged(self): + """ + Private slot handling a change of the associated editors source code + language. + """ + self.__model.repopulate() + self.__resizeColumns() + + @pyqtSlot() + def __editorRenamed(self): + """ + Private slot handling a renaming of the associated editor. + """ + 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 + """ + sindex = self.__model.itemIndexByLine(lineno + 1) + if sindex.isValid(): + index = self.model().mapFromSource(sindex) + if index.isValid(): + self.setCurrentIndex(index) + self.scrollTo(index)