eric6/QScintilla/EditorOutlineModel.py

changeset 7690
a59680062837
parent 7686
379d402162ca
child 7697
c981a807aab1
--- a/eric6/QScintilla/EditorOutlineModel.py	Fri Sep 04 18:48:52 2020 +0200
+++ b/eric6/QScintilla/EditorOutlineModel.py	Fri Sep 04 18:50:43 2020 +0200
@@ -13,7 +13,8 @@
 
 from UI.BrowserModel import (
     BrowserModel, BrowserItem, BrowserClassItem, BrowserCodingItem,
-    BrowserGlobalsItem, BrowserImportsItem, BrowserImportItem
+    BrowserGlobalsItem, BrowserImportsItem, BrowserImportItem,
+    BrowserClassAttributesItem, BrowserMethodItem
 )
 
 
@@ -25,12 +26,14 @@
         "IDL", "JavaScript", "Protocol", "Python3", "MicroPython", "Ruby",
     )
     
-    def __init__(self, editor):
+    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(EditorOutlineModel, self).__init__(nopopulate=True)
         
@@ -41,7 +44,8 @@
         rootData = QCoreApplication.translate("EditorOutlineModel", "Name")
         self.rootItem = BrowserItem(None, rootData)
         
-        self.__populateModel()
+        if populate:
+            self.__populateModel()
     
     def __populateModel(self, repopulate=False):
         """
@@ -55,10 +59,30 @@
         
         language = self.__editor.getLanguage()
         if language in EditorOutlineModel.SupportedLanguages:
-            if language in ("Python3", "MicroPython"):
+            if language == "IDL":
+                from Utilities.ClassBrowsers import idlclbr
+                dictionary = idlclbr.scan(
+                    self.__editor.text(), self.__filename, self.__module)
+                idlclbr._modules.clear()
+            elif language == "ProtoBuf":
+                from Utilities.ClassBrowsers import protoclbr
+                dictionary = protoclbr.scan(
+                    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)
+                rbclbr._modules.clear()
+            elif language == "JavaScript":
+                from Utilities.ClassBrowsers import jsclbr
+                dictionary = jsclbr.scan(
+                    self.__editor.text(), self.__filename, self.__module)
+                jsclbr._modules.clear()
+            elif language in ("Python3", "MicroPython"):
                 from Utilities.ClassBrowsers import pyclbr
-                dictionary = pyclbr.scan(self.__editor.text(), self.__filename,
-                                         self.__module)
+                dictionary = pyclbr.scan(
+                    self.__editor.text(), self.__filename, self.__module)
                 pyclbr._modules.clear()
             
             keys = list(dictionary.keys())
@@ -87,7 +111,8 @@
                         parentItem,
                         QCoreApplication.translate(
                             "EditorOutlineModel", "Coding: {0}")
-                        .format(dictionary["@@Coding@@"].coding))
+                        .format(dictionary["@@Coding@@"].coding),
+                        dictionary["@@Coding@@"].linenumber)
                     self._addItem(node, parentItem)
                 if "@@Globals@@" in keys:
                     node = BrowserGlobalsItem(
@@ -163,3 +188,79 @@
         @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
+            @type BrowserItem
+            @return found item or None
+            @rtype BrowserItem
+            """
+            if not parent.isPopulated():
+                if parent.isLazyPopulated():
+                    self.populateItem(parent)
+                else:
+                    return None
+            for child in parent.children():
+                if isinstance(child, BrowserClassAttributesItem):
+                    itm = findItem(lineno, child)
+                    if itm is not None:
+                        return itm
+                elif isinstance(child, (BrowserClassItem, BrowserMethodItem)):
+                    start, end = child.boundaries()
+                    if end == -1:
+                        end = 1000000   # assume end of file
+                    if start <= lineno <= end:
+                        itm = findItem(lineno, child)
+                        if itm is not None:
+                            return itm
+                        else:
+                            return child
+                elif hasattr(child, "linenos"):
+                    if lineno in child.linenos():
+                        return child
+                elif hasattr(child, "lineno"):
+                    if 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
+                    if start <= lineno <= end:
+                        itm = findItem(lineno, rootChild)
+                        if itm is None:
+                            itm = rootChild
+                elif isinstance(rootChild,
+                                (BrowserImportsItem, BrowserGlobalsItem)):
+                    itm = findItem(lineno, rootChild)
+                elif (
+                    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()

eric ide

mercurial