9 """ |
9 """ |
10 |
10 |
11 from PyQt6.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QTimer |
11 from PyQt6.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QTimer |
12 from PyQt6.QtGui import QCursor |
12 from PyQt6.QtGui import QCursor |
13 from PyQt6.QtWidgets import ( |
13 from PyQt6.QtWidgets import ( |
14 QWidget, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QSizePolicy, |
14 QWidget, |
15 QLineEdit, QTextBrowser, QToolTip |
15 QVBoxLayout, |
|
16 QHBoxLayout, |
|
17 QLabel, |
|
18 QComboBox, |
|
19 QSizePolicy, |
|
20 QLineEdit, |
|
21 QTextBrowser, |
|
22 QToolTip, |
16 ) |
23 ) |
17 |
24 |
18 from EricWidgets.EricTextEditSearchWidget import ( |
25 from EricWidgets.EricTextEditSearchWidget import ( |
19 EricTextEditSearchWidget, EricTextEditType |
26 EricTextEditSearchWidget, |
|
27 EricTextEditType, |
20 ) |
28 ) |
21 from EricWidgets.EricApplication import ericApp |
29 from EricWidgets.EricApplication import ericApp |
22 |
30 |
23 import Preferences |
31 import Preferences |
24 |
32 |
25 from .CodeDocumentationViewerTemplate import ( |
33 from .CodeDocumentationViewerTemplate import ( |
26 prepareDocumentationViewerHtmlDocument, |
34 prepareDocumentationViewerHtmlDocument, |
27 prepareDocumentationViewerHtmlDocWarningDocument, |
35 prepareDocumentationViewerHtmlDocWarningDocument, |
28 prepareDocumentationViewerHtmlWarningDocument |
36 prepareDocumentationViewerHtmlWarningDocument, |
29 ) |
37 ) |
30 |
38 |
31 |
39 |
32 class DocumentationViewerWidget(QWidget): |
40 class DocumentationViewerWidget(QWidget): |
33 """ |
41 """ |
34 Class implementing a rich text documentation viewer. |
42 Class implementing a rich text documentation viewer. |
35 """ |
43 """ |
|
44 |
36 EmpytDocument_Light = ( |
45 EmpytDocument_Light = ( |
37 '''<!DOCTYPE html>\n''' |
46 """<!DOCTYPE html>\n""" |
38 '''<html lang="EN">\n''' |
47 """<html lang="EN">\n""" |
39 '''<head>\n''' |
48 """<head>\n""" |
40 '''<style type="text/css">\n''' |
49 """<style type="text/css">\n""" |
41 '''html {background-color: #ffffff;}\n''' |
50 """html {background-color: #ffffff;}\n""" |
42 '''body {background-color: #ffffff;\n''' |
51 """body {background-color: #ffffff;\n""" |
43 ''' color: #000000;\n''' |
52 """ color: #000000;\n""" |
44 ''' margin: 0px 10px 10px 10px;\n''' |
53 """ margin: 0px 10px 10px 10px;\n""" |
45 '''}\n''' |
54 """}\n""" |
46 '''</style''' |
55 """</style""" |
47 '''</head>\n''' |
56 """</head>\n""" |
48 '''<body>\n''' |
57 """<body>\n""" |
49 '''</body>\n''' |
58 """</body>\n""" |
50 '''</html>''' |
59 """</html>""" |
51 ) |
60 ) |
52 EmpytDocument_Dark = ( |
61 EmpytDocument_Dark = ( |
53 '''<!DOCTYPE html>\n''' |
62 """<!DOCTYPE html>\n""" |
54 '''<html lang="EN">\n''' |
63 """<html lang="EN">\n""" |
55 '''<head>\n''' |
64 """<head>\n""" |
56 '''<style type="text/css">\n''' |
65 """<style type="text/css">\n""" |
57 '''html {background-color: #262626;}\n''' |
66 """html {background-color: #262626;}\n""" |
58 '''body {background-color: #262626;\n''' |
67 """body {background-color: #262626;\n""" |
59 ''' color: #ffffff;\n''' |
68 """ color: #ffffff;\n""" |
60 ''' margin: 0px 10px 10px 10px;\n''' |
69 """ margin: 0px 10px 10px 10px;\n""" |
61 '''}\n''' |
70 """}\n""" |
62 '''</style''' |
71 """</style""" |
63 '''</head>\n''' |
72 """</head>\n""" |
64 '''<body>\n''' |
73 """<body>\n""" |
65 '''</body>\n''' |
74 """</body>\n""" |
66 '''</html>''' |
75 """</html>""" |
67 ) |
76 ) |
68 |
77 |
69 def __init__(self, parent=None): |
78 def __init__(self, parent=None): |
70 """ |
79 """ |
71 Constructor |
80 Constructor |
72 |
81 |
73 @param parent reference to the parent widget |
82 @param parent reference to the parent widget |
74 @type QWidget |
83 @type QWidget |
75 """ |
84 """ |
76 super().__init__(parent) |
85 super().__init__(parent) |
77 self.setObjectName("DocumentationViewerWidget") |
86 self.setObjectName("DocumentationViewerWidget") |
78 |
87 |
79 self.__verticalLayout = QVBoxLayout(self) |
88 self.__verticalLayout = QVBoxLayout(self) |
80 self.__verticalLayout.setObjectName("verticalLayout") |
89 self.__verticalLayout.setObjectName("verticalLayout") |
81 self.__verticalLayout.setContentsMargins(0, 0, 0, 0) |
90 self.__verticalLayout.setContentsMargins(0, 0, 0, 0) |
82 |
91 |
83 try: |
92 try: |
84 from PyQt6.QtWebEngineCore import QWebEngineSettings |
93 from PyQt6.QtWebEngineCore import QWebEngineSettings |
85 from PyQt6.QtWebEngineWidgets import QWebEngineView |
94 from PyQt6.QtWebEngineWidgets import QWebEngineView |
|
95 |
86 self.__contents = QWebEngineView(self) |
96 self.__contents = QWebEngineView(self) |
87 self.__contents.page().linkHovered.connect(self.__showLink) |
97 self.__contents.page().linkHovered.connect(self.__showLink) |
88 self.__contents.settings().setAttribute( |
98 self.__contents.settings().setAttribute( |
89 QWebEngineSettings.WebAttribute.FocusOnNavigationEnabled, |
99 QWebEngineSettings.WebAttribute.FocusOnNavigationEnabled, False |
90 False) |
100 ) |
91 self.__viewerType = EricTextEditType.QWEBENGINEVIEW |
101 self.__viewerType = EricTextEditType.QWEBENGINEVIEW |
92 except ImportError: |
102 except ImportError: |
93 self.__contents = QTextBrowser(self) |
103 self.__contents = QTextBrowser(self) |
94 self.__contents.setOpenExternalLinks(True) |
104 self.__contents.setOpenExternalLinks(True) |
95 self.__viewerType = EricTextEditType.QTEXTBROWSER |
105 self.__viewerType = EricTextEditType.QTEXTBROWSER |
96 |
106 |
97 sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, |
107 sizePolicy = QSizePolicy( |
98 QSizePolicy.Policy.Expanding) |
108 QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding |
|
109 ) |
99 sizePolicy.setHorizontalStretch(0) |
110 sizePolicy.setHorizontalStretch(0) |
100 sizePolicy.setVerticalStretch(0) |
111 sizePolicy.setVerticalStretch(0) |
101 sizePolicy.setHeightForWidth( |
112 sizePolicy.setHeightForWidth(self.__contents.sizePolicy().hasHeightForWidth()) |
102 self.__contents.sizePolicy().hasHeightForWidth()) |
|
103 self.__contents.setSizePolicy(sizePolicy) |
113 self.__contents.setSizePolicy(sizePolicy) |
104 self.__contents.setContextMenuPolicy( |
114 self.__contents.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) |
105 Qt.ContextMenuPolicy.NoContextMenu) |
|
106 if self.__viewerType != EricTextEditType.QTEXTBROWSER: |
115 if self.__viewerType != EricTextEditType.QTEXTBROWSER: |
107 self.__contents.setUrl(QUrl("about:blank")) |
116 self.__contents.setUrl(QUrl("about:blank")) |
108 self.__verticalLayout.addWidget(self.__contents) |
117 self.__verticalLayout.addWidget(self.__contents) |
109 |
118 |
110 self.__searchWidget = EricTextEditSearchWidget(self, False) |
119 self.__searchWidget = EricTextEditSearchWidget(self, False) |
111 self.__searchWidget.setFocusPolicy(Qt.FocusPolicy.WheelFocus) |
120 self.__searchWidget.setFocusPolicy(Qt.FocusPolicy.WheelFocus) |
112 self.__searchWidget.setObjectName("searchWidget") |
121 self.__searchWidget.setObjectName("searchWidget") |
113 self.__verticalLayout.addWidget(self.__searchWidget) |
122 self.__verticalLayout.addWidget(self.__searchWidget) |
114 |
123 |
115 self.__searchWidget.attachTextEdit( |
124 self.__searchWidget.attachTextEdit(self.__contents, editType=self.__viewerType) |
116 self.__contents, editType=self.__viewerType) |
125 |
117 |
|
118 @pyqtSlot(str) |
126 @pyqtSlot(str) |
119 def __showLink(self, urlStr): |
127 def __showLink(self, urlStr): |
120 """ |
128 """ |
121 Private slot to show the hovered link in a tooltip. |
129 Private slot to show the hovered link in a tooltip. |
122 |
130 |
123 @param urlStr hovered URL |
131 @param urlStr hovered URL |
124 @type str |
132 @type str |
125 """ |
133 """ |
126 QToolTip.showText(QCursor.pos(), urlStr, self.__contents) |
134 QToolTip.showText(QCursor.pos(), urlStr, self.__contents) |
127 |
135 |
128 def setHtml(self, html): |
136 def setHtml(self, html): |
129 """ |
137 """ |
130 Public method to set the HTML text of the widget. |
138 Public method to set the HTML text of the widget. |
131 |
139 |
132 @param html HTML text to be shown |
140 @param html HTML text to be shown |
133 @type str |
141 @type str |
134 """ |
142 """ |
135 self.__contents.setEnabled(False) |
143 self.__contents.setEnabled(False) |
136 self.__contents.setHtml(html) |
144 self.__contents.setHtml(html) |
137 self.__contents.setEnabled(True) |
145 self.__contents.setEnabled(True) |
138 |
146 |
139 def clear(self): |
147 def clear(self): |
140 """ |
148 """ |
141 Public method to clear the shown contents. |
149 Public method to clear the shown contents. |
142 """ |
150 """ |
143 if self.__viewerType == EricTextEditType.QTEXTBROWSER: |
151 if self.__viewerType == EricTextEditType.QTEXTBROWSER: |
146 if ericApp().usesDarkPalette(): |
154 if ericApp().usesDarkPalette(): |
147 self.__contents.setHtml(self.EmpytDocument_Dark) |
155 self.__contents.setHtml(self.EmpytDocument_Dark) |
148 else: |
156 else: |
149 self.__contents.setHtml(self.EmpytDocument_Light) |
157 self.__contents.setHtml(self.EmpytDocument_Light) |
150 |
158 |
151 |
159 |
152 class CodeDocumentationViewer(QWidget): |
160 class CodeDocumentationViewer(QWidget): |
153 """ |
161 """ |
154 Class implementing a widget to show some source code information provided |
162 Class implementing a widget to show some source code information provided |
155 by plug-ins. |
163 by plug-ins. |
156 |
164 |
157 @signal providerAdded() emitted to indicate the availability of a new |
165 @signal providerAdded() emitted to indicate the availability of a new |
158 provider |
166 provider |
159 @signal providerRemoved() emitted to indicate the removal of a provider |
167 @signal providerRemoved() emitted to indicate the removal of a provider |
160 """ |
168 """ |
|
169 |
161 providerAdded = pyqtSignal() |
170 providerAdded = pyqtSignal() |
162 providerRemoved = pyqtSignal() |
171 providerRemoved = pyqtSignal() |
163 |
172 |
164 def __init__(self, parent=None): |
173 def __init__(self, parent=None): |
165 """ |
174 """ |
166 Constructor |
175 Constructor |
167 |
176 |
168 @param parent reference to the parent widget |
177 @param parent reference to the parent widget |
169 @type QWidget |
178 @type QWidget |
170 """ |
179 """ |
171 super().__init__(parent) |
180 super().__init__(parent) |
172 self.__setupUi() |
181 self.__setupUi() |
173 |
182 |
174 self.__ui = parent |
183 self.__ui = parent |
175 |
184 |
176 self.__providers = {} |
185 self.__providers = {} |
177 self.__selectedProvider = "" |
186 self.__selectedProvider = "" |
178 self.__disabledProvider = "disabled" |
187 self.__disabledProvider = "disabled" |
179 |
188 |
180 self.__shuttingDown = False |
189 self.__shuttingDown = False |
181 self.__startingUp = True |
190 self.__startingUp = True |
182 |
191 |
183 self.__lastDocumentation = None |
192 self.__lastDocumentation = None |
184 self.__requestingEditor = None |
193 self.__requestingEditor = None |
185 |
194 |
186 self.__unregisterTimer = QTimer(self) |
195 self.__unregisterTimer = QTimer(self) |
187 self.__unregisterTimer.setInterval(30000) # 30 seconds |
196 self.__unregisterTimer.setInterval(30000) # 30 seconds |
188 self.__unregisterTimer.setSingleShot(True) |
197 self.__unregisterTimer.setSingleShot(True) |
189 self.__unregisterTimer.timeout.connect(self.__unregisterTimerTimeout) |
198 self.__unregisterTimer.timeout.connect(self.__unregisterTimerTimeout) |
190 self.__mostRecentlyUnregisteredProvider = None |
199 self.__mostRecentlyUnregisteredProvider = None |
191 |
200 |
192 def __setupUi(self): |
201 def __setupUi(self): |
193 """ |
202 """ |
194 Private method to generate the UI layout. |
203 Private method to generate the UI layout. |
195 """ |
204 """ |
196 self.setObjectName("CodeDocumentationViewer") |
205 self.setObjectName("CodeDocumentationViewer") |
197 |
206 |
198 self.verticalLayout = QVBoxLayout(self) |
207 self.verticalLayout = QVBoxLayout(self) |
199 self.verticalLayout.setObjectName("verticalLayout") |
208 self.verticalLayout.setObjectName("verticalLayout") |
200 self.verticalLayout.setContentsMargins(3, 3, 3, 3) |
209 self.verticalLayout.setContentsMargins(3, 3, 3, 3) |
201 |
210 |
202 # top row 1 of widgets |
211 # top row 1 of widgets |
203 self.horizontalLayout1 = QHBoxLayout() |
212 self.horizontalLayout1 = QHBoxLayout() |
204 self.horizontalLayout1.setObjectName("horizontalLayout1") |
213 self.horizontalLayout1.setObjectName("horizontalLayout1") |
205 |
214 |
206 self.label = QLabel(self) |
215 self.label = QLabel(self) |
207 self.label.setObjectName("label") |
216 self.label.setObjectName("label") |
208 self.label.setText(self.tr("Code Info Provider:")) |
217 self.label.setText(self.tr("Code Info Provider:")) |
209 self.label.setAlignment(Qt.AlignmentFlag.AlignRight | |
218 self.label.setAlignment( |
210 Qt.AlignmentFlag.AlignVCenter) |
219 Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter |
|
220 ) |
211 self.horizontalLayout1.addWidget(self.label) |
221 self.horizontalLayout1.addWidget(self.label) |
212 |
222 |
213 self.providerComboBox = QComboBox(self) |
223 self.providerComboBox = QComboBox(self) |
214 sizePolicy = QSizePolicy( |
224 sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed) |
215 QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed) |
|
216 sizePolicy.setHorizontalStretch(0) |
225 sizePolicy.setHorizontalStretch(0) |
217 sizePolicy.setVerticalStretch(0) |
226 sizePolicy.setVerticalStretch(0) |
218 sizePolicy.setHeightForWidth( |
227 sizePolicy.setHeightForWidth( |
219 self.providerComboBox.sizePolicy().hasHeightForWidth()) |
228 self.providerComboBox.sizePolicy().hasHeightForWidth() |
|
229 ) |
220 self.providerComboBox.setSizePolicy(sizePolicy) |
230 self.providerComboBox.setSizePolicy(sizePolicy) |
221 self.providerComboBox.setSizeAdjustPolicy( |
231 self.providerComboBox.setSizeAdjustPolicy( |
222 QComboBox.SizeAdjustPolicy.AdjustToContents) |
232 QComboBox.SizeAdjustPolicy.AdjustToContents |
|
233 ) |
223 self.providerComboBox.setObjectName("providerComboBox") |
234 self.providerComboBox.setObjectName("providerComboBox") |
224 self.providerComboBox.setToolTip( |
235 self.providerComboBox.setToolTip(self.tr("Select the code info provider")) |
225 self.tr("Select the code info provider")) |
|
226 self.providerComboBox.addItem(self.tr("<disabled>"), "disabled") |
236 self.providerComboBox.addItem(self.tr("<disabled>"), "disabled") |
227 self.horizontalLayout1.addWidget(self.providerComboBox) |
237 self.horizontalLayout1.addWidget(self.providerComboBox) |
228 |
238 |
229 # top row 2 of widgets |
239 # top row 2 of widgets |
230 self.objectLineEdit = QLineEdit(self) |
240 self.objectLineEdit = QLineEdit(self) |
231 self.objectLineEdit.setReadOnly(True) |
241 self.objectLineEdit.setReadOnly(True) |
232 self.objectLineEdit.setObjectName("objectLineEdit") |
242 self.objectLineEdit.setObjectName("objectLineEdit") |
233 |
243 |
234 self.verticalLayout.addLayout(self.horizontalLayout1) |
244 self.verticalLayout.addLayout(self.horizontalLayout1) |
235 self.verticalLayout.addWidget(self.objectLineEdit) |
245 self.verticalLayout.addWidget(self.objectLineEdit) |
236 |
246 |
237 # Rich Text (Web) Documentation Viewer |
247 # Rich Text (Web) Documentation Viewer |
238 self.__viewerWidget = DocumentationViewerWidget(self) |
248 self.__viewerWidget = DocumentationViewerWidget(self) |
239 self.__viewerWidget.setObjectName("__viewerWidget") |
249 self.__viewerWidget.setObjectName("__viewerWidget") |
240 self.verticalLayout.addWidget(self.__viewerWidget) |
250 self.verticalLayout.addWidget(self.__viewerWidget) |
241 |
251 |
242 self.providerComboBox.currentIndexChanged[int].connect( |
252 self.providerComboBox.currentIndexChanged[int].connect( |
243 self.on_providerComboBox_currentIndexChanged) |
253 self.on_providerComboBox_currentIndexChanged |
244 |
254 ) |
|
255 |
245 def finalizeSetup(self): |
256 def finalizeSetup(self): |
246 """ |
257 """ |
247 Public method to finalize the setup of the documentation viewer. |
258 Public method to finalize the setup of the documentation viewer. |
248 """ |
259 """ |
249 self.__startingUp = False |
260 self.__startingUp = False |
274 @type function(language) |
284 @type function(language) |
275 @exception KeyError raised if a provider with the given name was |
285 @exception KeyError raised if a provider with the given name was |
276 already registered |
286 already registered |
277 """ |
287 """ |
278 if providerName in self.__providers: |
288 if providerName in self.__providers: |
279 raise KeyError( |
289 raise KeyError("Provider '{0}' already registered.".format(providerName)) |
280 "Provider '{0}' already registered.".format(providerName)) |
290 |
281 |
|
282 self.__providers[providerName] = (provider, supported) |
291 self.__providers[providerName] = (provider, supported) |
283 self.providerComboBox.addItem(providerDisplay, providerName) |
292 self.providerComboBox.addItem(providerDisplay, providerName) |
284 |
293 |
285 self.providerAdded.emit() |
294 self.providerAdded.emit() |
286 |
295 |
287 if ( |
296 if ( |
288 self.__unregisterTimer.isActive() and |
297 self.__unregisterTimer.isActive() |
289 providerName == self.__mostRecentlyUnregisteredProvider |
298 and providerName == self.__mostRecentlyUnregisteredProvider |
290 ): |
299 ): |
291 # this is assumed to be a plug-in reload |
300 # this is assumed to be a plug-in reload |
292 self.__unregisterTimer.stop() |
301 self.__unregisterTimer.stop() |
293 self.__mostRecentlyUnregisteredProvider = None |
302 self.__mostRecentlyUnregisteredProvider = None |
294 self.__selectProvider(providerName) |
303 self.__selectProvider(providerName) |
295 |
304 |
296 def unregisterProvider(self, providerName): |
305 def unregisterProvider(self, providerName): |
297 """ |
306 """ |
298 Public method register a source docu provider. |
307 Public method register a source docu provider. |
299 |
308 |
300 @param providerName name of the provider (must be unique) |
309 @param providerName name of the provider (must be unique) |
301 @type str |
310 @type str |
302 """ |
311 """ |
303 if providerName in self.__providers: |
312 if providerName in self.__providers: |
304 if providerName == self.__selectedProvider: |
313 if providerName == self.__selectedProvider: |
305 self.providerComboBox.setCurrentIndex(0) |
314 self.providerComboBox.setCurrentIndex(0) |
306 |
315 |
307 # in case this is just a temporary unregistration (< 30s) |
316 # in case this is just a temporary unregistration (< 30s) |
308 # e.g. when the plug-in is re-installed or updated |
317 # e.g. when the plug-in is re-installed or updated |
309 self.__mostRecentlyUnregisteredProvider = providerName |
318 self.__mostRecentlyUnregisteredProvider = providerName |
310 self.__unregisterTimer.start() |
319 self.__unregisterTimer.start() |
311 |
320 |
312 del self.__providers[providerName] |
321 del self.__providers[providerName] |
313 index = self.providerComboBox.findData(providerName) |
322 index = self.providerComboBox.findData(providerName) |
314 self.providerComboBox.removeItem(index) |
323 self.providerComboBox.removeItem(index) |
315 |
324 |
316 self.providerRemoved.emit() |
325 self.providerRemoved.emit() |
317 |
326 |
318 @pyqtSlot() |
327 @pyqtSlot() |
319 def __unregisterTimerTimeout(self): |
328 def __unregisterTimerTimeout(self): |
320 """ |
329 """ |
321 Private slot handling the timeout signal of the unregister timer. |
330 Private slot handling the timeout signal of the unregister timer. |
322 """ |
331 """ |
323 self.__mostRecentlyUnregisteredProvider = None |
332 self.__mostRecentlyUnregisteredProvider = None |
324 |
333 |
325 def isSupportedLanguage(self, language): |
334 def isSupportedLanguage(self, language): |
326 """ |
335 """ |
327 Public method to check, if the given language is supported by the |
336 Public method to check, if the given language is supported by the |
328 selected provider. |
337 selected provider. |
329 |
338 |
330 @param language editor programming language to check |
339 @param language editor programming language to check |
331 @type str |
340 @type str |
332 @return flag indicating the support status |
341 @return flag indicating the support status |
333 @rtype bool |
342 @rtype bool |
334 """ |
343 """ |
335 supported = False |
344 supported = False |
336 |
345 |
337 if self.__selectedProvider != self.__disabledProvider: |
346 if self.__selectedProvider != self.__disabledProvider: |
338 supported = self.__providers[self.__selectedProvider][1](language) |
347 supported = self.__providers[self.__selectedProvider][1](language) |
339 |
348 |
340 return supported |
349 return supported |
341 |
350 |
342 def getProviders(self): |
351 def getProviders(self): |
343 """ |
352 """ |
344 Public method to get a list of providers and their visible strings. |
353 Public method to get a list of providers and their visible strings. |
345 |
354 |
346 @return list containing the providers and their visible strings |
355 @return list containing the providers and their visible strings |
347 @rtype list of tuple of (str,str) |
356 @rtype list of tuple of (str,str) |
348 """ |
357 """ |
349 providers = [] |
358 providers = [] |
350 for index in range(1, self.providerComboBox.count()): |
359 for index in range(1, self.providerComboBox.count()): |
351 provider = self.providerComboBox.itemData(index) |
360 provider = self.providerComboBox.itemData(index) |
352 text = self.providerComboBox.itemText(index) |
361 text = self.providerComboBox.itemText(index) |
353 providers.append((provider, text)) |
362 providers.append((provider, text)) |
354 |
363 |
355 return providers |
364 return providers |
356 |
365 |
357 def showInfo(self, editor): |
366 def showInfo(self, editor): |
358 """ |
367 """ |
359 Public method to request code documentation data from a provider. |
368 Public method to request code documentation data from a provider. |
360 |
369 |
361 @param editor reference to the editor to request code docu for |
370 @param editor reference to the editor to request code docu for |
362 @type Editor |
371 @type Editor |
363 """ |
372 """ |
364 line, index = editor.getCursorPosition() |
373 line, index = editor.getCursorPosition() |
365 word = editor.getWord(line, index) |
374 word = editor.getWord(line, index) |
366 if not word: |
375 if not word: |
367 # try again one index before |
376 # try again one index before |
368 word = editor.getWord(line, index - 1) |
377 word = editor.getWord(line, index - 1) |
369 self.objectLineEdit.setText(word) |
378 self.objectLineEdit.setText(word) |
370 |
379 |
371 if self.__selectedProvider != self.__disabledProvider: |
380 if self.__selectedProvider != self.__disabledProvider: |
372 self.__viewerWidget.clear() |
381 self.__viewerWidget.clear() |
373 self.__providers[self.__selectedProvider][0](editor) |
382 self.__providers[self.__selectedProvider][0](editor) |
374 |
383 |
375 def documentationReady(self, documentationInfo, isWarning=False, |
384 def documentationReady( |
376 isDocWarning=False): |
385 self, documentationInfo, isWarning=False, isDocWarning=False |
|
386 ): |
377 """ |
387 """ |
378 Public method to provide the documentation info to the viewer. |
388 Public method to provide the documentation info to the viewer. |
379 |
389 |
380 If documentationInfo is a dictionary, it should contain these |
390 If documentationInfo is a dictionary, it should contain these |
381 (optional) keys and data: |
391 (optional) keys and data: |
382 |
392 |
383 name: the name of the inspected object |
393 name: the name of the inspected object |
384 argspec: its arguments specification |
394 argspec: its arguments specification |
385 note: A phrase describing the type of object (function or method) and |
395 note: A phrase describing the type of object (function or method) and |
386 the module it belongs to. |
396 the module it belongs to. |
387 docstring: its documentation string |
397 docstring: its documentation string |
388 typ: its type information |
398 typ: its type information |
389 |
399 |
390 @param documentationInfo dictionary containing the source docu data |
400 @param documentationInfo dictionary containing the source docu data |
391 @type dict or str |
401 @type dict or str |
392 @param isWarning flag indicating a warning page |
402 @param isWarning flag indicating a warning page |
393 @type bool |
403 @type bool |
394 @param isDocWarning flag indicating a documentation warning page |
404 @param isDocWarning flag indicating a documentation warning page |
395 @type bool |
405 @type bool |
396 """ |
406 """ |
397 self.__ui.activateCodeDocumentationViewer(switchFocus=False) |
407 self.__ui.activateCodeDocumentationViewer(switchFocus=False) |
398 |
408 |
399 if not isWarning and not isDocWarning: |
409 if not isWarning and not isDocWarning: |
400 self.__lastDocumentation = documentationInfo |
410 self.__lastDocumentation = documentationInfo |
401 |
411 |
402 if not documentationInfo: |
412 if not documentationInfo: |
403 if self.__selectedProvider == self.__disabledProvider: |
413 if self.__selectedProvider == self.__disabledProvider: |
404 self.__showDisabledMessage() |
414 self.__showDisabledMessage() |
405 else: |
415 else: |
406 self.documentationReady(self.tr("No documentation available"), |
416 self.documentationReady( |
407 isDocWarning=True) |
417 self.tr("No documentation available"), isDocWarning=True |
|
418 ) |
408 else: |
419 else: |
409 if isWarning: |
420 if isWarning: |
410 html = prepareDocumentationViewerHtmlWarningDocument( |
421 html = prepareDocumentationViewerHtmlWarningDocument(documentationInfo) |
411 documentationInfo) |
|
412 elif isDocWarning: |
422 elif isDocWarning: |
413 html = prepareDocumentationViewerHtmlDocWarningDocument( |
423 html = prepareDocumentationViewerHtmlDocWarningDocument( |
414 documentationInfo) |
424 documentationInfo |
|
425 ) |
415 elif isinstance(documentationInfo, dict): |
426 elif isinstance(documentationInfo, dict): |
416 html = prepareDocumentationViewerHtmlDocument( |
427 html = prepareDocumentationViewerHtmlDocument(documentationInfo) |
417 documentationInfo) |
|
418 else: |
428 else: |
419 html = documentationInfo |
429 html = documentationInfo |
420 self.__viewerWidget.setHtml(html) |
430 self.__viewerWidget.setHtml(html) |
421 |
431 |
422 def __showDisabledMessage(self): |
432 def __showDisabledMessage(self): |
423 """ |
433 """ |
424 Private method to show a message giving the reason for being disabled. |
434 Private method to show a message giving the reason for being disabled. |
425 """ |
435 """ |
426 if len(self.__providers) == 0: |
436 if len(self.__providers) == 0: |
427 self.documentationReady( |
437 self.documentationReady( |
428 self.tr("No source code documentation provider has been" |
438 self.tr( |
429 " registered. This function has been disabled."), |
439 "No source code documentation provider has been" |
430 isWarning=True) |
440 " registered. This function has been disabled." |
|
441 ), |
|
442 isWarning=True, |
|
443 ) |
431 else: |
444 else: |
432 self.documentationReady( |
445 self.documentationReady( |
433 self.tr("This function has been disabled."), |
446 self.tr("This function has been disabled."), isWarning=True |
434 isWarning=True) |
447 ) |
435 |
448 |
436 @pyqtSlot(int) |
449 @pyqtSlot(int) |
437 def on_providerComboBox_currentIndexChanged(self, index): |
450 def on_providerComboBox_currentIndexChanged(self, index): |
438 """ |
451 """ |
439 Private slot to handle the selection of a provider. |
452 Private slot to handle the selection of a provider. |
440 |
453 |
441 @param index index of the selected provider |
454 @param index index of the selected provider |
442 @type int |
455 @type int |
443 """ |
456 """ |
444 if not self.__shuttingDown and not self.__startingUp: |
457 if not self.__shuttingDown and not self.__startingUp: |
445 self.__viewerWidget.clear() |
458 self.__viewerWidget.clear() |
446 self.objectLineEdit.clear() |
459 self.objectLineEdit.clear() |
447 |
460 |
448 provider = self.providerComboBox.itemData(index) |
461 provider = self.providerComboBox.itemData(index) |
449 if provider == self.__disabledProvider: |
462 if provider == self.__disabledProvider: |
450 self.__showDisabledMessage() |
463 self.__showDisabledMessage() |
451 else: |
464 else: |
452 self.__lastDocumentation = None |
465 self.__lastDocumentation = None |
453 |
466 |
454 Preferences.setDocuViewer("Provider", provider) |
467 Preferences.setDocuViewer("Provider", provider) |
455 self.__selectedProvider = provider |
468 self.__selectedProvider = provider |
456 |
469 |
457 def shutdown(self): |
470 def shutdown(self): |
458 """ |
471 """ |
459 Public method to perform shutdown actions. |
472 Public method to perform shutdown actions. |
460 """ |
473 """ |
461 self.__shuttingDown = True |
474 self.__shuttingDown = True |
462 Preferences.setDocuViewer("Provider", self.__selectedProvider) |
475 Preferences.setDocuViewer("Provider", self.__selectedProvider) |
463 |
476 |
464 def preferencesChanged(self): |
477 def preferencesChanged(self): |
465 """ |
478 """ |
466 Public slot to handle a change of preferences. |
479 Public slot to handle a change of preferences. |
467 """ |
480 """ |
468 provider = Preferences.getDocuViewer("Provider") |
481 provider = Preferences.getDocuViewer("Provider") |
469 self.__selectProvider(provider) |
482 self.__selectProvider(provider) |
470 |
483 |
471 def __selectProvider(self, provider): |
484 def __selectProvider(self, provider): |
472 """ |
485 """ |
473 Private method to select a provider programmatically. |
486 Private method to select a provider programmatically. |
474 |
487 |
475 @param provider name of the provider to be selected |
488 @param provider name of the provider to be selected |
476 @type str |
489 @type str |
477 """ |
490 """ |
478 if provider != self.__selectedProvider: |
491 if provider != self.__selectedProvider: |
479 index = self.providerComboBox.findData(provider) |
492 index = self.providerComboBox.findData(provider) |