--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/QScintilla/EditorOutlineModel.py Wed Sep 02 18:13:12 2020 +0200 @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the editor outline model. +""" + +import os + +from PyQt5.QtCore import QCoreApplication, QModelIndex + +from UI.BrowserModel import ( + BrowserModel, BrowserItem, BrowserClassItem, BrowserCodingItem, + BrowserGlobalsItem, BrowserImportsItem, BrowserImportItem +) + + +class EditorOutlineModel(BrowserModel): + """ + Class implementing the editor outline model. + """ + SupportedLanguages = ( + "IDL", "JavaScript", "Protocol", "Python3", "MicroPython", "Ruby", + ) + + def __init__(self, editor): + """ + Constructor + + @param editor reference to the editor containing the source text + @type Editor + """ + super(EditorOutlineModel, self).__init__(nopopulate=True) + + self.__editor = editor + + self.__filename = self.__editor.getFileName() + self.__module = os.path.basename(self.__filename) + + self.__populated = False + + rootData = QCoreApplication.translate("EditorOutlineModel", "Name") + self.rootItem = BrowserItem(None, rootData) + + self.__populateModel() + + def __populateModel(self, repopulate=False): + """ + Private slot to populate the model. + + @param repopulate flag indicating a repopulation + @type bool + """ + language = self.__editor.getLanguage() + if language in EditorOutlineModel.SupportedLanguages: + if language in ("Python3", "MicroPython"): + from Utilities.ClassBrowsers import pyclbr + dictionary = pyclbr.scan(self.__editor.text(), self.__filename, + self.__module) + pyclbr._modules.clear() + + keys = list(dictionary.keys()) + if len(keys) > 0: + parentItem = self.rootItem + + if repopulate: + self.beginInsertRows( + QModelIndex(), + 0, len(keys) - 1) + + for key in keys: + if key.startswith("@@"): + # special treatment done later + continue + cl = dictionary[key] + try: + if cl.module == self.__module: + node = BrowserClassItem( + parentItem, cl, self.__filename) + self._addItem(node, parentItem) + except AttributeError: + pass + if "@@Coding@@" in keys: + node = BrowserCodingItem( + parentItem, + QCoreApplication.translate( + "EditorOutlineModel", "Coding: {0}") + .format(dictionary["@@Coding@@"].coding)) + self._addItem(node, parentItem) + if "@@Globals@@" in keys: + node = BrowserGlobalsItem( + parentItem, + dictionary["@@Globals@@"].globals, + QCoreApplication.translate( + "EditorOutlineModel", "Globals")) + self._addItem(node, parentItem) + if "@@Import@@" in keys or "@@ImportFrom@@" in keys: + node = BrowserImportsItem( + parentItem, + QCoreApplication.translate( + "EditorOutlineModel", "Imports")) + self._addItem(node, parentItem) + if "@@Import@@" in keys: + for importedModule in ( + dictionary["@@Import@@"].getImports().values() + ): + m_node = BrowserImportItem( + node, + importedModule.importedModuleName, + importedModule.file, + importedModule.linenos) + self._addItem(m_node, node) + for importedName, linenos in ( + importedModule.importedNames.items() + ): + mn_node = BrowserImportItem( + m_node, + importedName, + importedModule.file, + linenos, + 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)