--- a/eric6/QScintilla/EditorAssembly.py Fri Sep 04 18:48:52 2020 +0200 +++ b/eric6/QScintilla/EditorAssembly.py Fri Sep 04 18:50:43 2020 +0200 @@ -12,7 +12,10 @@ from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QWidget, QGridLayout, QComboBox +from E5Gui.E5Application import e5App + import UI.PixmapCache +import Preferences class EditorAssembly(QWidget): @@ -26,13 +29,18 @@ Constructor @param dbs reference to the debug server object - @param fn name of the file to be opened (string). If it is None, - a new (empty) editor is opened + @type DebugServer + @param fn name of the file to be opened. If it is None, + a new (empty) editor is opened. + @type str @param vm reference to the view manager object - (ViewManager.ViewManager) - @param filetype type of the source file (string) + @type ViewManager.ViewManager + @param filetype type of the source file + @type str @param editor reference to an Editor object, if this is a cloned view + @type Editor @param tv reference to the task viewer object + @type TaskViewer """ super(EditorAssembly, self).__init__() @@ -44,13 +52,16 @@ from .Editor import Editor from .EditorOutline import EditorOutlineView + self.__showOutline = Preferences.getEditor("ShowSourceOutline") + self.__editor = Editor(dbs, fn, vm, filetype, editor, tv) self.__buttonsWidget = EditorButtonsWidget(self.__editor, self) self.__globalsCombo = QComboBox() self.__membersCombo = QComboBox() - self.__sourceOutline = EditorOutlineView(self.__editor) - # TODO: make this configurable - self.__sourceOutline.setMaximumWidth(200) + self.__sourceOutline = EditorOutlineView( + self.__editor, populate=self.__showOutline) + self.__sourceOutline.setMaximumWidth( + Preferences.getEditor("SourceOutlineWidth")) self.__layout.addWidget(self.__buttonsWidget, 1, 0, -1, 1) self.__layout.addWidget(self.__globalsCombo, 0, 1) @@ -58,25 +69,14 @@ self.__layout.addWidget(self.__editor, 1, 1, 1, 2) self.__layout.addWidget(self.__sourceOutline, 0, 3, -1, -1) - if not self.__sourceOutline.isSupportedLanguage( - self.__editor.getLanguage() - ): - self.__sourceOutline.hide() - self.setFocusProxy(self.__editor) self.__module = None - self.__globalsCombo.activated[int].connect(self.__globalsActivated) - self.__membersCombo.activated[int].connect(self.__membersActivated) - self.__editor.cursorLineChanged.connect(self.__editorCursorLineChanged) - self.__shutdownTimerCalled = False self.__parseTimer = QTimer(self) self.__parseTimer.setSingleShot(True) self.__parseTimer.setInterval(5 * 1000) - self.__parseTimer.timeout.connect(self.__parseEditor) - self.__parseTimer.timeout.connect(self.__sourceOutline.repopulate) self.__editor.textChanged.connect(self.__resetParseTimer) self.__editor.refreshed.connect(self.__resetParseTimer) @@ -85,7 +85,11 @@ self.__globalsBoundaries = {} self.__membersBoundaries = {} - QTimer.singleShot(0, self.__parseEditor) + self.__activateOutline(self.__showOutline) + self.__activateCombos(not self.__showOutline) + + e5App().getObject("UserInterface").preferencesChanged.connect( + self.__preferencesChanged) def shutdownTimer(self): """ @@ -93,7 +97,6 @@ """ self.__parseTimer.stop() if not self.__shutdownTimerCalled: - self.__parseTimer.timeout.disconnect(self.__parseEditor) self.__editor.textChanged.disconnect(self.__resetParseTimer) self.__editor.refreshed.disconnect(self.__resetParseTimer) self.__shutdownTimerCalled = True @@ -102,18 +105,74 @@ """ Public method to get the reference to the editor widget. - @return reference to the editor widget (Editor) + @return reference to the editor widget + @rtype Editor """ return self.__editor + def __preferencesChanged(self): + """ + Private slot handling a change of preferences. + """ + showOutline = Preferences.getEditor("ShowSourceOutline") + if showOutline != self.__showOutline: + self.__showOutline = showOutline + self.__activateOutline(self.__showOutline) + self.__activateCombos(not self.__showOutline) + + ####################################################################### + ## Methods dealing with the navigation combos below + ####################################################################### + + def __activateCombos(self, activate): + """ + Private slot to activate the navigation combo boxes. + + @param activate flag indicating to activate the combo boxes + @type bool + """ + self.__globalsCombo.setVisible(activate) + self.__membersCombo.setVisible(activate) + if activate: + self.__globalsCombo.activated[int].connect( + self.__globalsActivated) + self.__membersCombo.activated[int].connect( + self.__membersActivated) + self.__editor.cursorLineChanged.connect( + self.__editorCursorLineChanged) + self.__parseTimer.timeout.connect(self.__parseEditor) + + self.__parseEditor() + + line, _ = self.__editor.getCursorPosition() + self.__editorCursorLineChanged(line) + else: + try: + self.__globalsCombo.activated[int].disconnect( + self.__globalsActivated) + self.__membersCombo.activated[int].disconnect( + self.__membersActivated) + self.__editor.cursorLineChanged.disconnect( + self.__editorCursorLineChanged) + self.__parseTimer.timeout.disconnect(self.__parseEditor) + except TypeError: + # signals were not connected + pass + + self.__globalsCombo.clear() + self.__membersCombo.clear() + self.__globalsBoundaries = {} + self.__membersBoundaries = {} + def __globalsActivated(self, index, moveCursor=True): """ Private method to jump to the line of the selected global entry and to populate the members combo box. - @param index index of the selected entry (integer) - @keyparam moveCursor flag indicating to move the editor cursor - (boolean) + @param index index of the selected entry + @type int + @param moveCursor flag indicating to move the editor cursor + @type bool """ # step 1: go to the line of the selected entry lineno = self.__globalsCombo.itemData(index) @@ -206,9 +265,10 @@ """ Private method to jump to the line of the selected members entry. - @param index index of the selected entry (integer) - @keyparam moveCursor flag indicating to move the editor cursor - (boolean) + @param index index of the selected entry + @type int + @param moveCursor flag indicating to move the editor cursor + @type bool """ lineno = self.__membersCombo.itemData(index) if lineno is not None and moveCursor: @@ -333,7 +393,8 @@ """ Private slot handling a line change of the cursor of the editor. - @param lineno line number of the cursor (integer) + @param lineno line number of the cursor + @type int """ lineno += 1 # cursor position is zero based, code info one based @@ -358,3 +419,47 @@ break self.__membersCombo.setCurrentIndex(indexFound) self.__membersActivated(indexFound, moveCursor=False) + + ####################################################################### + ## Methods dealing with the source outline below + ####################################################################### + + def __activateOutline(self, activate): + """ + Private slot to activate the source outline view. + + @param activate flag indicating to activate the source outline view + @type bool + """ + self.__sourceOutline.setActive(activate) + + if activate: + self.__sourceOutline.setVisible( + self.__sourceOutline.isSupportedLanguage( + self.__editor.getLanguage() + ) + ) + + self.__parseTimer.timeout.connect(self.__sourceOutline.repopulate) + self.__editor.languageChanged.connect(self.__editorChanged) + self.__editor.editorRenamed.connect(self.__editorChanged) + else: + self.__sourceOutline.hide() + + try: + self.__parseTimer.timeout.disconnect( + self.__sourceOutline.repopulate) + self.__editor.languageChanged.disconnect(self.__editorChanged) + self.__editor.editorRenamed.disconnect(self.__editorChanged) + except TypeError: + # signals were not connected + pass + + def __editorChanged(self): + """ + Private slot handling changes of the editor language or file name. + """ + supported = self.__sourceOutline.isSupportedLanguage( + self.__editor.getLanguage()) + + self.__sourceOutline.setVisible(supported)