--- a/src/eric7/QScintilla/EditorOutlineModel.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/QScintilla/EditorOutlineModel.py Wed Jul 13 14:55:47 2022 +0200 @@ -13,9 +13,15 @@ from PyQt6.QtCore import QCoreApplication, QModelIndex from UI.BrowserModel import ( - BrowserModel, BrowserItem, BrowserClassItem, BrowserCodingItem, - BrowserGlobalsItem, BrowserImportsItem, BrowserImportItem, - BrowserClassAttributesItem, BrowserMethodItem + BrowserModel, + BrowserItem, + BrowserClassItem, + BrowserCodingItem, + BrowserGlobalsItem, + BrowserImportsItem, + BrowserImportItem, + BrowserClassAttributesItem, + BrowserMethodItem, ) import Preferences @@ -25,83 +31,98 @@ """ Class implementing the editor outline model. """ + SupportedLanguages = ( - "IDL", "JavaScript", "Protocol", "Python3", "MicroPython", "Cython", + "IDL", + "JavaScript", + "Protocol", + "Python3", + "MicroPython", + "Cython", "Ruby", ) - + def __init__(self, editor, populate=True): """ Constructor - + @param editor reference to the editor containing the source text @type Editor @param populate flag indicating to populate the outline @type bool """ super().__init__(nopopulate=True) - + self.__editor = editor - + self.__populated = False - + rootData = QCoreApplication.translate("EditorOutlineModel", "Name") self.rootItem = BrowserItem(None, rootData) - + if populate: self.__populateModel() - + def __populateModel(self, repopulate=False): """ Private slot to populate the model. - + @param repopulate flag indicating a repopulation @type bool """ self.__filename = self.__editor.getFileName() self.__module = os.path.basename(self.__filename) - + language = self.__editor.getLanguage() if language in EditorOutlineModel.SupportedLanguages: if language == "IDL": from Utilities.ClassBrowsers import idlclbr + dictionary = idlclbr.scan( - self.__editor.text(), self.__filename, self.__module) + self.__editor.text(), self.__filename, self.__module + ) idlclbr._modules.clear() elif language == "Protocol": from Utilities.ClassBrowsers import protoclbr + dictionary = protoclbr.scan( - self.__editor.text(), self.__filename, self.__module) + self.__editor.text(), self.__filename, self.__module + ) protoclbr._modules.clear() elif language == "Ruby": from Utilities.ClassBrowsers import rbclbr + dictionary = rbclbr.scan( - self.__editor.text(), self.__filename, self.__module) + self.__editor.text(), self.__filename, self.__module + ) rbclbr._modules.clear() elif language == "JavaScript": from Utilities.ClassBrowsers import jsclbr + dictionary = jsclbr.scan( - self.__editor.text(), self.__filename, self.__module) + self.__editor.text(), self.__filename, self.__module + ) jsclbr._modules.clear() elif language in ("Python3", "MicroPython", "Cython"): from Utilities.ClassBrowsers import pyclbr + dictionary = pyclbr.scan( - self.__editor.text(), self.__filename, self.__module) + self.__editor.text(), self.__filename, self.__module + ) pyclbr._modules.clear() - + keys = list(dictionary.keys()) if len(keys) > 0: parentItem = self.rootItem - + if repopulate: last = len(keys) - 1 - if ( - "@@Coding@@" in keys and - not Preferences.getEditor("SourceOutlineShowCoding") + if "@@Coding@@" in keys and not Preferences.getEditor( + "SourceOutlineShowCoding" ): last -= 1 self.beginInsertRows(QModelIndex(), 0, last) - + for key in keys: if key.startswith("@@"): # special treatment done later @@ -109,32 +130,31 @@ cl = dictionary[key] with contextlib.suppress(AttributeError): if cl.module == self.__module: - node = BrowserClassItem( - parentItem, cl, self.__filename) + node = BrowserClassItem(parentItem, cl, self.__filename) self._addItem(node, parentItem) - if ( - "@@Coding@@" in keys and - Preferences.getEditor("SourceOutlineShowCoding") + if "@@Coding@@" in keys and Preferences.getEditor( + "SourceOutlineShowCoding" ): node = BrowserCodingItem( parentItem, QCoreApplication.translate( - "EditorOutlineModel", "Coding: {0}") - .format(dictionary["@@Coding@@"].coding), - dictionary["@@Coding@@"].linenumber) + "EditorOutlineModel", "Coding: {0}" + ).format(dictionary["@@Coding@@"].coding), + dictionary["@@Coding@@"].linenumber, + ) self._addItem(node, parentItem) if "@@Globals@@" in keys: node = BrowserGlobalsItem( parentItem, dictionary["@@Globals@@"].globals, - QCoreApplication.translate( - "EditorOutlineModel", "Globals")) + QCoreApplication.translate("EditorOutlineModel", "Globals"), + ) self._addItem(node, parentItem) if "@@Import@@" in keys or "@@ImportFrom@@" in keys: node = BrowserImportsItem( parentItem, - QCoreApplication.translate( - "EditorOutlineModel", "Imports")) + QCoreApplication.translate("EditorOutlineModel", "Imports"), + ) self._addItem(node, parentItem) if "@@Import@@" in keys: for importedModule in ( @@ -144,74 +164,78 @@ node, importedModule.importedModuleName, importedModule.file, - importedModule.linenos) + importedModule.linenos, + ) self._addItem(m_node, node) - for importedName, linenos in ( - importedModule.importedNames.items() - ): + for ( + importedName, + linenos, + ) in importedModule.importedNames.items(): mn_node = BrowserImportItem( m_node, importedName, importedModule.file, linenos, - isModule=False) + isModule=False, + ) self._addItem(mn_node, m_node) if repopulate: self.endInsertRows() - + self.__populated = True else: self.clear() self.__populated = False - + def isPopulated(self): """ Public method to check, if the model is populated. - + @return flag indicating a populated model @rtype bool """ return self.__populated - + def repopulate(self): """ Public slot to repopulate the model. """ self.clear() self.__populateModel(repopulate=True) - + def editor(self): """ Public method to retrieve a reference to the editor. - + @return reference to the editor @rtype Editor """ return self.__editor - + def fileName(self): """ Public method to retrieve the file name of the editor. - + @return file name of the editor @rtype str """ return self.__filename - + def itemIndexByLine(self, lineno): """ Public method to find an item's index given a line number. - + @param lineno one based line number of the item @type int @return index of the item found @rtype QModelIndex """ + def findItem(lineno, parent): """ Function to iteratively search for an item containing the given line. - + @param lineno one based line number of the item @type int @param parent reference to the parent item @@ -232,7 +256,7 @@ elif isinstance(child, (BrowserClassItem, BrowserMethodItem)): start, end = child.boundaries() if end == -1: - end = 1000000 # assume end of file + end = 1000000 # assume end of file if start <= lineno <= end: itm = findItem(lineno, child) if itm is not None: @@ -242,36 +266,32 @@ elif hasattr(child, "linenos"): if lineno in child.linenos(): return child - elif ( - hasattr(child, "lineno") and - lineno == child.lineno() - ): + elif hasattr(child, "lineno") and lineno == child.lineno(): return child else: return None - + if self.__populated: for rootChild in self.rootItem.children(): itm = None if isinstance(rootChild, BrowserClassItem): start, end = rootChild.boundaries() if end == -1: - end = 1000000 # assume end of file + end = 1000000 # assume end of file if start <= lineno <= end: itm = findItem(lineno, rootChild) if itm is None: itm = rootChild - elif isinstance(rootChild, - (BrowserImportsItem, BrowserGlobalsItem)): + elif isinstance(rootChild, (BrowserImportsItem, BrowserGlobalsItem)): itm = findItem(lineno, rootChild) elif ( - isinstance(rootChild, BrowserCodingItem) and - lineno == rootChild.lineno() + isinstance(rootChild, BrowserCodingItem) + and lineno == rootChild.lineno() ): itm = rootChild if itm is not None: return self.createIndex(itm.row(), 0, itm) else: return QModelIndex() - + return QModelIndex()