|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the editor outline model. |
|
8 """ |
|
9 |
|
10 import os |
|
11 |
|
12 from PyQt5.QtCore import QCoreApplication, QModelIndex |
|
13 |
|
14 from UI.BrowserModel import ( |
|
15 BrowserModel, BrowserItem, BrowserClassItem, BrowserCodingItem, |
|
16 BrowserGlobalsItem, BrowserImportsItem, BrowserImportItem |
|
17 ) |
|
18 |
|
19 |
|
20 class EditorOutlineModel(BrowserModel): |
|
21 """ |
|
22 Class implementing the editor outline model. |
|
23 """ |
|
24 SupportedLanguages = ( |
|
25 "IDL", "JavaScript", "Protocol", "Python3", "MicroPython", "Ruby", |
|
26 ) |
|
27 |
|
28 def __init__(self, editor): |
|
29 """ |
|
30 Constructor |
|
31 |
|
32 @param editor reference to the editor containing the source text |
|
33 @type Editor |
|
34 """ |
|
35 super(EditorOutlineModel, self).__init__(nopopulate=True) |
|
36 |
|
37 self.__editor = editor |
|
38 |
|
39 self.__filename = self.__editor.getFileName() |
|
40 self.__module = os.path.basename(self.__filename) |
|
41 |
|
42 self.__populated = False |
|
43 |
|
44 rootData = QCoreApplication.translate("EditorOutlineModel", "Name") |
|
45 self.rootItem = BrowserItem(None, rootData) |
|
46 |
|
47 self.__populateModel() |
|
48 |
|
49 def __populateModel(self, repopulate=False): |
|
50 """ |
|
51 Private slot to populate the model. |
|
52 |
|
53 @param repopulate flag indicating a repopulation |
|
54 @type bool |
|
55 """ |
|
56 language = self.__editor.getLanguage() |
|
57 if language in EditorOutlineModel.SupportedLanguages: |
|
58 if language in ("Python3", "MicroPython"): |
|
59 from Utilities.ClassBrowsers import pyclbr |
|
60 dictionary = pyclbr.scan(self.__editor.text(), self.__filename, |
|
61 self.__module) |
|
62 pyclbr._modules.clear() |
|
63 |
|
64 keys = list(dictionary.keys()) |
|
65 if len(keys) > 0: |
|
66 parentItem = self.rootItem |
|
67 |
|
68 if repopulate: |
|
69 self.beginInsertRows( |
|
70 QModelIndex(), |
|
71 0, len(keys) - 1) |
|
72 |
|
73 for key in keys: |
|
74 if key.startswith("@@"): |
|
75 # special treatment done later |
|
76 continue |
|
77 cl = dictionary[key] |
|
78 try: |
|
79 if cl.module == self.__module: |
|
80 node = BrowserClassItem( |
|
81 parentItem, cl, self.__filename) |
|
82 self._addItem(node, parentItem) |
|
83 except AttributeError: |
|
84 pass |
|
85 if "@@Coding@@" in keys: |
|
86 node = BrowserCodingItem( |
|
87 parentItem, |
|
88 QCoreApplication.translate( |
|
89 "EditorOutlineModel", "Coding: {0}") |
|
90 .format(dictionary["@@Coding@@"].coding)) |
|
91 self._addItem(node, parentItem) |
|
92 if "@@Globals@@" in keys: |
|
93 node = BrowserGlobalsItem( |
|
94 parentItem, |
|
95 dictionary["@@Globals@@"].globals, |
|
96 QCoreApplication.translate( |
|
97 "EditorOutlineModel", "Globals")) |
|
98 self._addItem(node, parentItem) |
|
99 if "@@Import@@" in keys or "@@ImportFrom@@" in keys: |
|
100 node = BrowserImportsItem( |
|
101 parentItem, |
|
102 QCoreApplication.translate( |
|
103 "EditorOutlineModel", "Imports")) |
|
104 self._addItem(node, parentItem) |
|
105 if "@@Import@@" in keys: |
|
106 for importedModule in ( |
|
107 dictionary["@@Import@@"].getImports().values() |
|
108 ): |
|
109 m_node = BrowserImportItem( |
|
110 node, |
|
111 importedModule.importedModuleName, |
|
112 importedModule.file, |
|
113 importedModule.linenos) |
|
114 self._addItem(m_node, node) |
|
115 for importedName, linenos in ( |
|
116 importedModule.importedNames.items() |
|
117 ): |
|
118 mn_node = BrowserImportItem( |
|
119 m_node, |
|
120 importedName, |
|
121 importedModule.file, |
|
122 linenos, |
|
123 isModule=False) |
|
124 self._addItem(mn_node, m_node) |
|
125 if repopulate: |
|
126 self.endInsertRows() |
|
127 |
|
128 self.__populated = True |
|
129 else: |
|
130 self.clear() |
|
131 self.__populated = False |
|
132 |
|
133 def isPopulated(self): |
|
134 """ |
|
135 Public method to check, if the model is populated. |
|
136 |
|
137 @return flag indicating a populated model |
|
138 @rtype bool |
|
139 """ |
|
140 return self.__populated |
|
141 |
|
142 def repopulate(self): |
|
143 """ |
|
144 Public slot to repopulate the model. |
|
145 """ |
|
146 self.clear() |
|
147 self.__populateModel(repopulate=True) |