eric6/QScintilla/EditorOutlineModel.py

changeset 7685
0b6e8c0d6403
child 7686
379d402162ca
diff -r 2fca14bea889 -r 0b6e8c0d6403 eric6/QScintilla/EditorOutlineModel.py
--- /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)

eric ide

mercurial