Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python console interactive help #58962

Merged
merged 12 commits into from
Nov 13, 2024
Merged
1 change: 1 addition & 0 deletions images/images.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,7 @@
<file>themes/default/propertyicons/notes.svg</file>
<file>themes/default/stacked-diagram.svg</file>
<file>themes/default/mIconStac.svg</file>
<file>themes/default/mIconQt.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Expand Down
1 change: 1 addition & 0 deletions images/themes/default/mIconQt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions python/PyQt6/core/auto_additions/qgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -10883,6 +10883,36 @@
"""
# --
Qgis.ColorModel.baseClass = Qgis
# monkey patching scoped based enum
Qgis.DocumentationApi.PyQgis.__doc__ = "PyQgis API documentation"
Qgis.DocumentationApi.PyQgisSearch.__doc__ = "Search in PyQgis API documentation"
Qgis.DocumentationApi.CppQgis.__doc__ = "C++ QGIS API documentation"
Qgis.DocumentationApi.Qt.__doc__ = "Qt API documentation"
Qgis.DocumentationApi.__doc__ = """Documentation API

.. versionadded:: 3.42

* ``PyQgis``: PyQgis API documentation
* ``PyQgisSearch``: Search in PyQgis API documentation
* ``CppQgis``: C++ QGIS API documentation
* ``Qt``: Qt API documentation

"""
# --
Qgis.DocumentationApi.baseClass = Qgis
# monkey patching scoped based enum
Qgis.DocumentationBrowser.DeveloperToolsPanel.__doc__ = "Embedded webview in the DevTools panel"
Qgis.DocumentationBrowser.SystemWebBrowser.__doc__ = "Default system web browser"
Qgis.DocumentationBrowser.__doc__ = """Documentation API browser

.. versionadded:: 3.42

* ``DeveloperToolsPanel``: Embedded webview in the DevTools panel
* ``SystemWebBrowser``: Default system web browser

"""
# --
Qgis.DocumentationBrowser.baseClass = Qgis
try:
Qgis.__attribute_docs__ = {'QGIS_DEV_VERSION': 'The development version', 'DEFAULT_SEARCH_RADIUS_MM': 'Identify search radius in mm', 'DEFAULT_MAPTOPIXEL_THRESHOLD': 'Default threshold between map coordinates and device coordinates for map2pixel simplification', 'DEFAULT_HIGHLIGHT_COLOR': 'Default highlight color. The transparency is expected to only be applied to polygon\nfill. Lines and outlines are rendered opaque.', 'DEFAULT_HIGHLIGHT_BUFFER_MM': 'Default highlight buffer in mm.', 'DEFAULT_HIGHLIGHT_MIN_WIDTH_MM': 'Default highlight line/stroke minimum width in mm.', 'SCALE_PRECISION': 'Fudge factor used to compare two scales. The code is often going from scale to scale\ndenominator. So it looses precision and, when a limit is inclusive, can lead to errors.\nTo avoid that, use this factor instead of using <= or >=.\n\n.. deprecated:: 3.40\n\n No longer used by QGIS and will be removed in QGIS 4.0.', 'DEFAULT_Z_COORDINATE': 'Default Z coordinate value.\nThis value have to be assigned to the Z coordinate for the vertex.', 'DEFAULT_M_COORDINATE': 'Default M coordinate value.\nThis value have to be assigned to the M coordinate for the vertex.\n\n.. versionadded:: 3.20', 'UI_SCALE_FACTOR': 'UI scaling factor. This should be applied to all widget sizes obtained from font metrics,\nto account for differences in the default font sizes across different platforms.', 'DEFAULT_SNAP_TOLERANCE': 'Default snapping distance tolerance.', 'DEFAULT_SNAP_UNITS': 'Default snapping distance units.'}
Qgis.version = staticmethod(Qgis.version)
Expand Down
14 changes: 14 additions & 0 deletions python/PyQt6/core/auto_generated/qgis.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -3173,6 +3173,20 @@ The development version
Cmyk,
};

enum class DocumentationApi /BaseType=IntEnum/
{
PyQgis,
PyQgisSearch,
CppQgis,
Qt,
};

enum class DocumentationBrowser /BaseType=IntEnum/
{
DeveloperToolsPanel,
SystemWebBrowser,
};

static const double DEFAULT_SEARCH_RADIUS_MM;

static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
Expand Down
3 changes: 2 additions & 1 deletion python/PyQt6/gui/auto_additions/qgscodeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,14 @@
QgsCodeEditor.Flags.baseClass = QgsCodeEditor
Flags = QgsCodeEditor # dirty hack since SIP seems to introduce the flags in module
try:
QgsCodeEditor.__attribute_docs__ = {'SEARCH_RESULT_INDICATOR': 'Indicator index for search results', 'sessionHistoryCleared': 'Emitted when the history of commands run in the current session is cleared.\n\n.. versionadded:: 3.30\n', 'persistentHistoryCleared': 'Emitted when the persistent history of commands run in the editor is cleared.\n\n.. versionadded:: 3.30\n'}
QgsCodeEditor.__attribute_docs__ = {'SEARCH_RESULT_INDICATOR': 'Indicator index for search results', 'sessionHistoryCleared': 'Emitted when the history of commands run in the current session is cleared.\n\n.. versionadded:: 3.30\n', 'persistentHistoryCleared': 'Emitted when the persistent history of commands run in the editor is cleared.\n\n.. versionadded:: 3.30\n', 'helpRequested': 'Emitted when documentation was requested for the specified ``word``.\n\n.. versionadded:: 3.42\n'}
QgsCodeEditor.languageToString = staticmethod(QgsCodeEditor.languageToString)
QgsCodeEditor.defaultColor = staticmethod(QgsCodeEditor.defaultColor)
QgsCodeEditor.color = staticmethod(QgsCodeEditor.color)
QgsCodeEditor.setColor = staticmethod(QgsCodeEditor.setColor)
QgsCodeEditor.getMonospaceFont = staticmethod(QgsCodeEditor.getMonospaceFont)
QgsCodeEditor.isFixedPitch = staticmethod(QgsCodeEditor.isFixedPitch)
QgsCodeEditor.__signal_arguments__ = {'helpRequested': ['word: str']}
QgsCodeEditor.__group__ = ['codeeditors']
except NameError:
pass
Expand Down
1 change: 1 addition & 0 deletions python/PyQt6/gui/auto_additions/qgsgui.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ def _force_int(v): return int(v.value) if isinstance(v, Enum) else v
QgsGui.higFlags = staticmethod(QgsGui.higFlags)
QgsGui.sampleColor = staticmethod(QgsGui.sampleColor)
QgsGui.findScreenAt = staticmethod(QgsGui.findScreenAt)
QgsGui.hasWebEngine = staticmethod(QgsGui.hasWebEngine)
except NameError:
pass
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,14 @@ Emitted when the persistent history of commands run in the editor is cleared.
.. versionadded:: 3.30
%End


void helpRequested( const QString &word );
%Docstring
Emitted when documentation was requested for the specified ``word``.

.. versionadded:: 3.42
%End

protected:

static bool isFixedPitch( const QFont &font );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ Updates the editor capabilities.
Searches the selected text in the official PyQGIS online documentation.

.. versionadded:: 3.16
%End

virtual void showApiDocumentation( const QString &item );
%Docstring
Displays the given text in the official APIs (PyQGIS, C++ QGIS or Qt) documentation.

.. versionadded:: 3.42
%End

virtual void toggleComment();
Expand Down
12 changes: 12 additions & 0 deletions python/PyQt6/gui/auto_generated/qgisinterface.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,18 @@ Unregister a previously registered tool factory from the development/debugging t
.. seealso:: :py:func:`registerDevToolWidgetFactory`

.. versionadded:: 3.14
%End

virtual void showApiDocumentation( Qgis::DocumentationApi api = Qgis::DocumentationApi::PyQgis, Qgis::DocumentationBrowser browser = Qgis::DocumentationBrowser::DeveloperToolsPanel, const QString &object = QString(), const QString &module = QString() ) = 0;
%Docstring
Show a page of the API documentation

:param api: Which API to display
:param browser: Web browser used to display the API documentation
:param object: object to show in the documentation
:param module: used only if api = :py:class:`Qgis`.DocumentationApi.PyQgis

.. versionadded:: 3.42
%End

virtual void registerApplicationExitBlocker( QgsApplicationExitBlockerInterface *blocker ) = 0;
Expand Down
7 changes: 7 additions & 0 deletions python/PyQt6/gui/auto_generated/qgsgui.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@ Returns the screen at the given global ``point`` (pixel).



static bool hasWebEngine();
%Docstring
Checks whether QWebEngineView is available to display HTML content.

.. versionadded:: 3.42
%End


signals:

Expand Down
19 changes: 12 additions & 7 deletions python/console/console_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ def __init__(self,
self.modificationChanged.connect(self.editor_tab.modified)
self.modificationAttempted.connect(self.fileReadOnly)

def showApiDocumentation(self, text):
self.console_widget.shell.showApiDocumentation(text)

def set_code_editor_widget(self, widget: QgsCodeEditorWidget):
self.code_editor_widget = widget
self.code_editor_widget.loadedExternalChanges.connect(
Expand Down Expand Up @@ -154,11 +157,15 @@ def contextMenuEvent(self, e):
runSelected.setShortcut('Ctrl+E') # spellok
menu.addAction(runSelected) # spellok

pyQGISHelpAction = QAction(QgsApplication.getThemeIcon("console/iconHelpConsole.svg"),
QCoreApplication.translate("PythonConsole", "Search Selection in PyQGIS Documentation"),
menu)
pyQGISHelpAction.triggered.connect(self.searchSelectedTextInPyQGISDocs)
menu.addAction(pyQGISHelpAction)
word = self.selectedText() or self.wordAtPoint(e.pos())
if word:
context_help_action = QAction(
QgsApplication.getThemeIcon("mActionHelpContents.svg"),
QCoreApplication.translate("PythonConsole", "Context Help"),
menu)
context_help_action.triggered.connect(partial(self.console_widget.shell.showApiDocumentation, word, force_search=True))
context_help_action.setShortcut('F1')
menu.addAction(context_help_action)

start_action = QAction(QgsApplication.getThemeIcon("mActionStart.svg"),
QCoreApplication.translate("PythonConsole", "Run Script"),
Expand Down Expand Up @@ -246,7 +253,6 @@ def contextMenuEvent(self, e):
self.console_widget.openSettings)
syntaxCheckAction.setEnabled(False)
pasteAction.setEnabled(False)
pyQGISHelpAction.setEnabled(False)
cutAction.setEnabled(False)
runSelected.setEnabled(False) # spellok
copyAction.setEnabled(False)
Expand All @@ -258,7 +264,6 @@ def contextMenuEvent(self, e):
runSelected.setEnabled(True) # spellok
copyAction.setEnabled(True)
cutAction.setEnabled(True)
pyQGISHelpAction.setEnabled(True)
if not self.text() == '':
selectAllAction.setEnabled(True)
syntaxCheckAction.setEnabled(True)
Expand Down
32 changes: 13 additions & 19 deletions python/console/console_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from __future__ import annotations

import sys
from functools import partial
from typing import TYPE_CHECKING

from qgis.PyQt import sip
Expand Down Expand Up @@ -239,11 +240,15 @@ def contextMenuEvent(self, e):
clearAction.triggered.connect(self.clearConsole)
menu.addAction(clearAction)

pyQGISHelpAction = QAction(QgsApplication.getThemeIcon("console/iconHelpConsole.svg"),
QCoreApplication.translate("PythonConsole", "Search Selection in PyQGIS Documentation"),
menu)
pyQGISHelpAction.triggered.connect(self.searchSelectedTextInPyQGISDocs)
menu.addAction(pyQGISHelpAction)
word = self.selectedText() or self.wordAtPoint(e.pos())
if word:
context_help_action = QAction(
QgsApplication.getThemeIcon("mActionHelpContents.svg"),
QCoreApplication.translate("PythonConsole", "Context Help"),
menu)
context_help_action.triggered.connect(partial(self.shell_editor.showApiDocumentation, word, force_search=True))
context_help_action.setShortcut('F1')
menu.addAction(context_help_action)

menu.addSeparator()
copyAction = QAction(
Expand Down Expand Up @@ -271,13 +276,11 @@ def contextMenuEvent(self, e):
runAction.setEnabled(False)
clearAction.setEnabled(False)
copyAction.setEnabled(False)
pyQGISHelpAction.setEnabled(False)
selectAllAction.setEnabled(False)
showEditorAction.setEnabled(True)
if self.hasSelectedText():
runAction.setEnabled(True)
copyAction.setEnabled(True)
pyQGISHelpAction.setEnabled(True)
if not self.text(3) == '':
selectAllAction.setEnabled(True)
clearAction.setEnabled(True)
Expand Down Expand Up @@ -311,17 +314,8 @@ def enteredSelected(self):
self.shell_editor.insertFromDropPaste(cmd)
self.shell_editor.entered()

def keyPressEvent(self, e):
# empty text indicates possible shortcut key sequence so stay in output
txt = e.text()
if len(txt) and txt >= " ":
self.shell_editor.append(txt)
self.shell_editor.moveCursorToEnd()
self.shell_editor.setFocus()
e.ignore()
else:
# possible shortcut key sequence, accept it
e.accept()

def widgetMessageBar(self, text: str):
self.infoBar.pushMessage(text, Qgis.MessageLevel.Info)

def showApiDocumentation(self, text):
self.shell_editor.showApiDocumentation(text)
Loading
Loading