diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/QScintilla/EditorAssembly.py --- a/src/eric7/QScintilla/EditorAssembly.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/QScintilla/EditorAssembly.py Wed Jul 13 14:55:47 2022 +0200 @@ -24,11 +24,11 @@ Class implementing the editor assembly widget containing the navigation combos and the editor widget. """ - def __init__(self, dbs, fn="", vm=None, filetype="", editor=None, - tv=None): + + def __init__(self, dbs, fn="", vm=None, filetype="", editor=None, tv=None): """ Constructor - + @param dbs reference to the debug server object @type DebugServer @param fn name of the file to be opened. If it is None, @@ -44,17 +44,17 @@ @type TaskViewer """ super().__init__() - + self.__layout = QGridLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.__layout.setSpacing(1) - + from .EditorButtonsWidget import EditorButtonsWidget 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() @@ -62,38 +62,41 @@ self.__membersCombo = QComboBox() self.__membersCombo.setDuplicatesEnabled(True) self.__sourceOutline = EditorOutlineView( - self.__editor, populate=self.__showOutline) + self.__editor, populate=self.__showOutline + ) self.__sourceOutline.setMaximumWidth( - Preferences.getEditor("SourceOutlineWidth")) - + Preferences.getEditor("SourceOutlineWidth") + ) + self.__layout.addWidget(self.__buttonsWidget, 1, 0, -1, 1) self.__layout.addWidget(self.__globalsCombo, 0, 1) self.__layout.addWidget(self.__membersCombo, 0, 2) self.__layout.addWidget(self.__editor, 1, 1, 1, 2) self.__layout.addWidget(self.__sourceOutline, 0, 3, -1, -1) - + self.setFocusProxy(self.__editor) - + self.__module = None - + self.__shutdownTimerCalled = False self.__parseTimer = QTimer(self) self.__parseTimer.setSingleShot(True) self.__parseTimer.setInterval(5 * 1000) self.__editor.textChanged.connect(self.__resetParseTimer) self.__editor.refreshed.connect(self.__resetParseTimer) - + self.__selectedGlobal = "" self.__selectedMember = "" self.__globalsBoundaries = {} self.__membersBoundaries = {} - + self.__activateOutline(self.__showOutline) self.__activateCombos(not self.__showOutline) - + ericApp().getObject("UserInterface").preferencesChanged.connect( - self.__preferencesChanged) - + self.__preferencesChanged + ) + def shutdownTimer(self): """ Public method to stop and disconnect the timer. @@ -103,16 +106,16 @@ self.__editor.textChanged.disconnect(self.__resetParseTimer) self.__editor.refreshed.disconnect(self.__resetParseTimer) self.__shutdownTimerCalled = True - + def getEditor(self): """ Public method to get the reference to the editor widget. - + @return reference to the editor widget @rtype Editor """ return self.__editor - + def __preferencesChanged(self): """ Private slot handling a change of preferences. @@ -122,53 +125,49 @@ 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.__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: with contextlib.suppress(TypeError): - self.__globalsCombo.activated[int].disconnect( - self.__globalsActivated) - self.__membersCombo.activated[int].disconnect( - self.__membersActivated) + self.__globalsCombo.activated[int].disconnect(self.__globalsActivated) + self.__membersCombo.activated[int].disconnect(self.__membersActivated) self.__editor.cursorLineChanged.disconnect( - self.__editorCursorLineChanged) + self.__editorCursorLineChanged + ) self.__parseTimer.timeout.disconnect(self.__parseEditor) - + 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 @type int @param moveCursor flag indicating to move the editor cursor @@ -180,10 +179,9 @@ if moveCursor: txt = self.__editor.text(lineno - 1).rstrip() pos = len(txt.replace(txt.strip(), "")) - self.__editor.gotoLine( - lineno, pos if pos == 0 else pos + 1, True) + self.__editor.gotoLine(lineno, pos if pos == 0 else pos + 1, True) self.__editor.setFocus() - + # step 2: populate the members combo, if the entry is a class self.__membersCombo.clear() self.__membersBoundaries = {} @@ -201,22 +199,20 @@ if cl.isPrivate(): icon = UI.PixmapCache.getIcon("class_private") elif cl.isProtected(): - icon = UI.PixmapCache.getIcon( - "class_protected") + icon = UI.PixmapCache.getIcon("class_protected") else: icon = UI.PixmapCache.getIcon("class") items.append((icon, cl.name, cl.lineno, cl.endlineno)) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__membersCombo.addItem(itm[0], itm[1], itm[2]) memberIndex += 1 - self.__membersBoundaries[(itm[2], itm[3])] = ( - memberIndex - ) + self.__membersBoundaries[(itm[2], itm[3])] = memberIndex else: return - + # step 2.1: add class methods from Utilities.ModuleParser import Function + items = [] for meth in entry.methods.values(): if meth.modifier == Function.Static: @@ -229,28 +225,25 @@ icon = UI.PixmapCache.getIcon("method_protected") else: icon = UI.PixmapCache.getIcon("method") - items.append( - (icon, meth.name, meth.lineno, meth.endlineno) - ) + items.append((icon, meth.name, meth.lineno, meth.endlineno)) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__membersCombo.addItem(itm[0], itm[1], itm[2]) memberIndex += 1 self.__membersBoundaries[(itm[2], itm[3])] = memberIndex - + # step 2.2: add class instance attributes items = [] for attr in entry.attributes.values(): if attr.isPrivate(): icon = UI.PixmapCache.getIcon("attribute_private") elif attr.isProtected(): - icon = UI.PixmapCache.getIcon( - "attribute_protected") + icon = UI.PixmapCache.getIcon("attribute_protected") else: icon = UI.PixmapCache.getIcon("attribute") items.append((icon, attr.name, attr.lineno)) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__membersCombo.addItem(itm[0], itm[1], itm[2]) - + # step 2.3: add class attributes items = [] icon = UI.PixmapCache.getIcon("attribute_class") @@ -258,11 +251,11 @@ items.append((icon, globalVar.name, globalVar.lineno)) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__membersCombo.addItem(itm[0], itm[1], itm[2]) - + def __membersActivated(self, index, moveCursor=True): """ Private method to jump to the line of the selected members entry. - + @param index index of the selected entry @type int @param moveCursor flag indicating to move the editor cursor @@ -272,24 +265,25 @@ if lineno is not None and moveCursor: txt = self.__editor.text(lineno - 1).rstrip() pos = len(txt.replace(txt.strip(), "")) - self.__editor.gotoLine(lineno, pos if pos == 0 else pos + 1, - firstVisible=True, expand=True) + self.__editor.gotoLine( + lineno, pos if pos == 0 else pos + 1, firstVisible=True, expand=True + ) self.__editor.setFocus() - + def __resetParseTimer(self): """ Private slot to reset the parse timer. """ self.__parseTimer.stop() self.__parseTimer.start() - + def __parseEditor(self): """ Private method to parse the editor source and repopulate the globals combo. """ from Utilities.ModuleParser import Module, getTypeFromTypeName - + self.__module = None sourceType = getTypeFromTypeName(self.__editor.determineFileType()) if sourceType != -1: @@ -300,31 +294,35 @@ fn = "" self.__module = Module("", fn, sourceType) self.__module.scan(src) - + # remember the current selections self.__selectedGlobal = self.__globalsCombo.currentText() self.__selectedMember = self.__membersCombo.currentText() - + self.__globalsCombo.clear() self.__membersCombo.clear() self.__globalsBoundaries = {} self.__membersBoundaries = {} - + self.__globalsCombo.addItem("") index = 0 - + # step 1: add modules items = [] for module in self.__module.modules.values(): items.append( - (UI.PixmapCache.getIcon("module"), module.name, - module.lineno, module.endlineno) + ( + UI.PixmapCache.getIcon("module"), + module.name, + module.lineno, + module.endlineno, + ) ) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__globalsCombo.addItem(itm[0], itm[1], itm[2]) index += 1 self.__globalsBoundaries[(itm[2], itm[3])] = index - + # step 2: add classes items = [] for cl in self.__module.classes.values(): @@ -334,14 +332,12 @@ icon = UI.PixmapCache.getIcon("class_protected") else: icon = UI.PixmapCache.getIcon("class") - items.append( - (icon, cl.name, cl.lineno, cl.endlineno) - ) + items.append((icon, cl.name, cl.lineno, cl.endlineno)) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__globalsCombo.addItem(itm[0], itm[1], itm[2]) index += 1 self.__globalsBoundaries[(itm[2], itm[3])] = index - + # step 3: add functions items = [] for func in self.__module.functions.values(): @@ -351,30 +347,25 @@ icon = UI.PixmapCache.getIcon("method_protected") else: icon = UI.PixmapCache.getIcon("method") - items.append( - (icon, func.name, func.lineno, func.endlineno) - ) + items.append((icon, func.name, func.lineno, func.endlineno)) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__globalsCombo.addItem(itm[0], itm[1], itm[2]) index += 1 self.__globalsBoundaries[(itm[2], itm[3])] = index - + # step 4: add attributes items = [] for globalValue in self.__module.globals.values(): if globalValue.isPrivate(): icon = UI.PixmapCache.getIcon("attribute_private") elif globalValue.isProtected(): - icon = UI.PixmapCache.getIcon( - "attribute_protected") + icon = UI.PixmapCache.getIcon("attribute_protected") else: icon = UI.PixmapCache.getIcon("attribute") - items.append( - (icon, globalValue.name, globalValue.lineno) - ) + items.append((icon, globalValue.name, globalValue.lineno)) for itm in sorted(items, key=lambda x: (x[1], x[2])): self.__globalsCombo.addItem(itm[0], itm[1], itm[2]) - + # reset the currently selected entries without moving the # text cursor index = self.__globalsCombo.findText(self.__selectedGlobal) @@ -390,78 +381,77 @@ self.__membersCombo.clear() self.__globalsBoundaries = {} self.__membersBoundaries = {} - + def __editorCursorLineChanged(self, lineno): """ Private slot handling a line change of the cursor of the editor. - + @param lineno line number of the cursor @type int """ - lineno += 1 # cursor position is zero based, code info one based - + lineno += 1 # cursor position is zero based, code info one based + # step 1: search in the globals indexFound = 0 for (lower, upper), index in self.__globalsBoundaries.items(): if upper == -1: - upper = 1000000 # it is the last line + upper = 1000000 # it is the last line if lower <= lineno <= upper: indexFound = index break self.__globalsCombo.setCurrentIndex(indexFound) self.__globalsActivated(indexFound, moveCursor=False) - + # step 2: search in members indexFound = 0 for (lower, upper), index in self.__membersBoundaries.items(): if upper == -1: - upper = 1000000 # it is the last line + upper = 1000000 # it is the last line if lower <= lineno <= upper: indexFound = index 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.__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() - + with contextlib.suppress(TypeError): - self.__parseTimer.timeout.disconnect( - self.__sourceOutline.repopulate) + self.__parseTimer.timeout.disconnect(self.__sourceOutline.repopulate) self.__editor.languageChanged.disconnect(self.__editorChanged) self.__editor.editorRenamed.disconnect(self.__editorChanged) - + def __editorChanged(self): """ Private slot handling changes of the editor language or file name. """ supported = self.__sourceOutline.isSupportedLanguage( - self.__editor.getLanguage()) - + self.__editor.getLanguage() + ) + self.__sourceOutline.setVisible(supported) + # # eflag: noqa = Y113