eric6/QScintilla/EditorOutlineModel.py

Wed, 02 Sep 2020 18:13:12 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 02 Sep 2020 18:13:12 +0200
changeset 7685
0b6e8c0d6403
child 7686
379d402162ca
permissions
-rw-r--r--

Started implementing the editor outline widget.

# -*- 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