Sun, 15 Oct 2017 19:40:26 +0200
Continued implementing a viewer for source code documentation extracted by providers to be implemented by plug-ins (like rope and jedi).
--- a/Preferences/__init__.py Sun Oct 15 17:21:51 2017 +0200 +++ b/Preferences/__init__.py Sun Oct 15 19:40:26 2017 +0200 @@ -428,7 +428,7 @@ "CallTipsScintillaOnFail": False, # show QScintilla calltips, if plug-in fails - "ShowInfoOnOpenBracket": True, + "ShowInfoOnOpenParenthesis": True, # TODO: add to editor configuration page "AutoCheckSyntax": True, @@ -1463,6 +1463,13 @@ "HeaderColor": QColor(237, 237, 190), "BadWhitespaceColor": QColor(255, 0, 0, 192), } + + # defaults for Code Documentation Viewer + docuViewerDefaults = { + "ShowInfoAsMarkdown": False, + "Provider": "disabled", + } + # TODO: add to new configuration page to editor section def readToolGroups(prefClass=Prefs): @@ -3532,7 +3539,7 @@ @param key the key of the value to get @param prefClass preferences class used as the storage area - @return the requested editor colour + @return the requested diff colour """ col = prefClass.settings.value("Diff/" + key) if col is not None: @@ -3560,6 +3567,35 @@ prefClass.settings.setValue("Diff/" + key, val) +def getDocuViewer(key, prefClass=Prefs): + """ + Module function to retrieve the Code Documentation Viewer related settings. + + @param key the key of the value to get + @param prefClass preferences class used as the storage area + @return the requested editor colour + """ + if key in ["ShowInfoAsMarkdown"]: + return toBool(prefClass.settings.value( + "CodeDocumentationViewer/" + key, + prefClass.docuViewerDefaults[key])) + else: + return prefClass.settings.value( + "CodeDocumentationViewer/" + key, + prefClass.docuViewerDefaults[key]) + + +def setDocuViewer(key, value, prefClass=Prefs): + """ + Module function to store the Code Documentation Viewer related settings. + + @param key the key of the setting to be set + @param value the value to be set + @param prefClass preferences class used as the storage area + """ + prefClass.settings.setValue("CodeDocumentationViewer/" + key, value) + + def getGeometry(key, prefClass=Prefs): """ Module function to retrieve the display geometry.
--- a/QScintilla/Editor.py Sun Oct 15 17:21:51 2017 +0200 +++ b/QScintilla/Editor.py Sun Oct 15 19:40:26 2017 +0200 @@ -4553,6 +4553,7 @@ ## auto-completion hook interfaces ################################################################# + # TODO: document this hook in chapter 6.2 of plug-in document def addCompletionListHook(self, key, func, async=False): """ Public method to set an auto-completion list provider. @@ -4591,6 +4592,7 @@ else: self.__completionListHookFunctions[key] = func + # TODO: document this hook in chapter 6.2 of plug-in document def removeCompletionListHook(self, key): """ Public method to remove a previously registered completion list @@ -4611,6 +4613,7 @@ self.setAutoCompletionThreshold( Preferences.getEditor("AutoCompletionThreshold")) + # TODO: document this hook in chapter 6.2 of plug-in document def getCompletionListHook(self, key): """ Public method to get the registered completion list provider. @@ -4683,6 +4686,7 @@ self, context) self.completionsListReady(completions, self.__acText) + # TODO: document this hook in chapter 6.2 of plug-in document def completionsListReady(self, completions, acText): """ Public method to show the completions determined by a completions @@ -4780,6 +4784,70 @@ bool(self.__completionListHookFunctions) or bool(self.__completionListAsyncHookFunctions)) + ################################################################# + ## call-tip hook interfaces + ################################################################# + + # TODO: document this hook in chapter 6.2 of plug-in document + def addCallTipHook(self, key, func): + """ + Public method to set a calltip provider. + + @param key name of the provider + @type str + @param func function providing calltips. func + should be a function taking a reference to the editor, + a position into the text and the amount of commas to the + left of the cursor. It should return the possible + calltips as a list of strings. + @type function(editor, int, int) -> list of str + """ + if key in self.__ctHookFunctions: + # it was already registered + E5MessageBox.warning( + self, + self.tr("Call-Tips Provider"), + self.tr("""The call-tips provider '{0}' was already""" + """ registered. Ignoring duplicate request.""") + .format(key)) + return + + self.__ctHookFunctions[key] = func + + # TODO: document this hook in chapter 6.2 of plug-in document + def removeCallTipHook(self, key): + """ + Public method to remove a previously registered calltip provider. + + @param key name of the provider + @type str + """ + if key in self.__ctHookFunctions: + del self.__ctHookFunctions[key] + + # TODO: document this hook in chapter 6.2 of plug-in document + def getCallTipHook(self, key): + """ + Public method to get the registered calltip provider. + + @param key name of the provider + @type str + @return function providing calltips + @rtype function or None + """ + if key in self.__ctHookFunctions: + return self.__ctHookFunctions[key] + else: + return None + + def canProvideCallTipps(self): + """ + Public method to test the calltips availability. + + @return flag indicating the availability of calltips (boolean) + """ + return (self.acAPI or + bool(self.__ctHookFunctions)) def callTip(self): """ Public method to show calltips. @@ -4909,67 +4977,6 @@ ct = ct - ctshift return ct - ################################################################# - ## call-tip hook interfaces - ################################################################# - - def addCallTipHook(self, key, func): - """ - Public method to set a calltip provider. - - @param key name of the provider - @type str - @param func function providing calltips. func - should be a function taking a reference to the editor, - a position into the text and the amount of commas to the - left of the cursor. It should return the possible - calltips as a list of strings. - @type function(editor, int, int) -> list of str - """ - if key in self.__ctHookFunctions: - # it was already registered - E5MessageBox.warning( - self, - self.tr("Call-Tips Provider"), - self.tr("""The call-tips provider '{0}' was already""" - """ registered. Ignoring duplicate request.""") - .format(key)) - return - - self.__ctHookFunctions[key] = func - - def removeCallTipHook(self, key): - """ - Public method to remove a previously registered calltip provider. - - @param key name of the provider - @type str - """ - if key in self.__ctHookFunctions: - del self.__ctHookFunctions[key] - - def getCallTipHook(self, key): - """ - Public method to get the registered calltip provider. - - @param key name of the provider - @type str - @return function providing calltips - @rtype function or None - """ - if key in self.__ctHookFunctions: - return self.__ctHookFunctions[key] - else: - return None - - def canProvideCallTipps(self): - """ - Public method to test the calltips availability. - - @return flag indicating the availability of calltips (boolean) - """ - return (self.acAPI or - bool(self.__ctHookFunctions)) ################################################################# ## Methods needed by the code documentation viewer @@ -4985,7 +4992,7 @@ @param charNumber value of the character entered (integer) """ char = chr(charNumber) - if char == "(" and Preferences.getEditor("ShowInfoOnOpenBracket"): + if char == "(" and Preferences.getEditor("ShowInfoOnOpenParenthesis"): self.vm.showEditorInfo(self) #################################################################
--- a/UI/CodeDocumentationViewer.py Sun Oct 15 17:21:51 2017 +0200 +++ b/UI/CodeDocumentationViewer.py Sun Oct 15 19:40:26 2017 +0200 @@ -35,6 +35,8 @@ super(CodeDocumentationViewer, self).__init__(parent) self.setupUi(self) + self.searchWidget.attachTextEdit(self.contents) + self.__ui = parent self.__providers = {} @@ -44,26 +46,34 @@ self.__shuttingDown = False self.__startingUp = True + self.__lastDocumentation = None + + self.__showMarkdown = Preferences.getDocuViewer("ShowInfoAsMarkdown") + self.__noDocumentationString = self.tr("No documentation available") self.__disabledString = self.tr( "No source code documentation provider has been registered or" " this function has been disabled.") self.providerComboBox.addItem(self.tr("<disabled>"), "disabled") + + font = Preferences.getEditorOtherFonts("MonospacedFont") + self.contents.setFontFamily(font.family()) + self.contents.setFontPointSize(font.pointSize()) def finalizeSetup(self): """ Public method to finalize the setup of the documentation viewer. """ self.__startingUp = False - provider = Preferences.Prefs.settings.value( - "CodeDocumentationViewer/Provider", "disabled") + provider = Preferences.getDocuViewer("Provider") if provider in self.__providers: index = self.providerComboBox.findData(provider) else: index = 0 self.providerComboBox.setCurrentIndex(index) + # TODO: document this hook in the plug-in document def registerProvider(self, providerName, providerDisplay, provider): """ Public method register a source docu provider. @@ -84,6 +94,7 @@ self.__providers[providerName] = provider self.providerComboBox.addItem(providerDisplay, providerName) + # TODO: document this hook in the plug-in document def unregisterProvider(self, providerName): """ Public method register a source docu provider. @@ -106,10 +117,18 @@ @param editor reference to the editor to request code docu for @type Editor """ + line, index = editor.getCursorPosition() + word = editor.getWord(line, index) + if not word: + # try again one index before + word = editor.getWord(line, index - 1) + self.objectLineEdit.setText(word) + if self.__selectedProvider != self.__disabledProvider: self.contents.clear() self.__providers[self.__selectedProvider](editor) + # TODO: document this hook in the plug-in document def documentationReady(self, documentationInfo): """ Public method to provide the documentation info to the viewer. @@ -128,27 +147,42 @@ """ self.__ui.activateCodeDocumentationViewer(switchFocus=False) + self.__lastDocumentation = documentationInfo + if not documentationInfo: fullText = self.__noDocumentationString elif isinstance(documentationInfo, str): fullText = documentationInfo elif isinstance(documentationInfo, dict): + # format the text with markdown syntax name = documentationInfo["name"] if name: - title = "".join(["=" * len(name), "\n", name, "\n", + title = "".join([name, "\n", "=" * len(name), "\n\n"]) else: title = "" if documentationInfo["argspec"]: - definition = self.tr("Definition: {0}{1}\n").format( - name, documentationInfo["argspec"]) + if self.__showMarkdown: + definition = self.tr("**Definition**: {0}{1}\n", + "string with markdown syntax").format( + name, documentationInfo["argspec"]) + else: + definition = self.tr("Definition: {0}{1}\n", + "string as plain text").format( + name, documentationInfo["argspec"]) else: definition = '' if documentationInfo["note"]: - note = self.tr("Info: {0}\n\n----\n\n").format( - documentationInfo["note"]) + if self.__showMarkdown: + note = self.tr("**Info**: _{0}_\n\n----\n\n", + "string with markdown syntax").format( + documentationInfo["note"]) + else: + note = self.tr("Info: {0}\n\n----\n\n", + "string as plain text").format( + documentationInfo["note"]) else: note = "" @@ -170,8 +204,7 @@ if provider == self.__disabledProvider: self.documentationReady(self.__disabledString) elif provider in self.__providers: - Preferences.Prefs.settings.setValue( - "CodeDocumentationViewer/Provider", provider) + Preferences.setDocuViewer("Provider", provider) self.__selectedProvider = provider def shutdown(self): @@ -179,5 +212,24 @@ Public method to perform shutdown actions. """ self.__shuttingDown = True - Preferences.Prefs.settings.setValue( - "CodeDocumentationViewer/Provider", self.__selectedProvider) + Preferences.setDocuViewer("Provider", self.__selectedProvider) + + def preferencesChanged(self): + """ + Public slot to handle a change of preferences. + """ + showMarkdown = Preferences.getDocuViewer("ShowInfoAsMarkdown") + if showMarkdown != self.__showMarkdown: + self.__showMarkdown = showMarkdown + self.documentationReady(self.__lastDocumentation) + + provider = Preferences.getDocuViewer("Provider") + if provider != self.__selectedProvider: + index = self.providerComboBox.findData(provider) + if index < 0: + index = 0 + self.providerComboBox.setCurrentIndex(index) + + font = Preferences.getEditorOtherFonts("MonospacedFont") + self.contents.setFontFamily(font.family()) + self.contents.setFontPointSize(font.pointSize())
--- a/UI/Previewers/PreviewerHTML.py Sun Oct 15 17:21:51 2017 +0200 +++ b/UI/Previewers/PreviewerHTML.py Sun Oct 15 19:40:26 2017 +0200 @@ -682,7 +682,8 @@ try: import mdx_mathjax # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ except ImportError: - #mathjax doesn't require import statement if installed as extension + # mathjax doesn't require import statement if installed + # as extension pass if convertNewLineToBreak:
--- a/UI/UserInterface.py Sun Oct 15 17:21:51 2017 +0200 +++ b/UI/UserInterface.py Sun Oct 15 19:40:26 2017 +0200 @@ -455,6 +455,8 @@ self.preferencesChanged.connect(self.cooperation.preferencesChanged) self.preferencesChanged.connect( self.backgroundService.preferencesOrProjectChanged) + self.preferencesChanged.connect( + self.codeDocumentationViewer.preferencesChanged) self.viewmanager.editorSaved.connect(self.project.repopulateItem) self.viewmanager.lastEditorClosed.connect(self.__lastEditorClosed)
--- a/ViewManager/ViewManager.py Sun Oct 15 17:21:51 2017 +0200 +++ b/ViewManager/ViewManager.py Sun Oct 15 19:40:26 2017 +0200 @@ -84,7 +84,6 @@ super(QuickSearchLineEdit, self).focusInEvent(evt) # pass it on -# TODO: add an action to show code info for the object under the cursor (Ctrl-Alt-I) class ViewManager(QWidget): """ Base class inherited by all specific viewmanager classes. @@ -1379,6 +1378,24 @@ self.calltipsAct.triggered.connect(self.__editShowCallTips) self.editActions.append(self.calltipsAct) + self.codeInfoAct = E5Action( + QCoreApplication.translate('ViewManager', 'Code Info'), + UI.PixmapCache.getIcon("codeDocuViewer.png"), + QCoreApplication.translate('ViewManager', 'Code Info'), + QKeySequence(QCoreApplication.translate( + 'ViewManager', "Ctrl+Alt+I", "Edit|Code Info")), + 0, + self.editActGrp, 'vm_edit_codeinfo') + self.codeInfoAct.setStatusTip(QCoreApplication.translate( + 'ViewManager', 'Show Code Info')) + self.codeInfoAct.setWhatsThis(QCoreApplication.translate( + 'ViewManager', + """<b>Code Info</b>""" + """<p>Show code information based on the cursor position.</p>""" + )) + self.codeInfoAct.triggered.connect(self.__editShowCodeInfo) + self.editActions.append(self.codeInfoAct) + self.sortAct = E5Action( QCoreApplication.translate('ViewManager', 'Sort'), QCoreApplication.translate('ViewManager', 'Sort'), @@ -5434,6 +5451,12 @@ """ self.activeWindow().callTip() + def __editShowCodeInfo(self): + """ + Private method to handle the code info action. + """ + self.showEditorInfo(self.activeWindow()) + ################################################################## ## Below are the action and utility methods for the search menu ################################################################## @@ -6790,7 +6813,6 @@ @param editor editor to show information text for @type Editor """ - # TODO: implement CodeDocumentationViewer self.ui.documentationViewer().showInfo(editor) ##################################################################