Add format code action in Python Console Editor

This commit is contained in:
Yoann Quenach de Quivillic 2023-03-12 10:25:00 +01:00 committed by Nyall Dawson
parent 6e551db4c9
commit ef6de1ff2c
4 changed files with 84 additions and 0 deletions

View File

@ -165,6 +165,7 @@
<file>themes/default/console/iconNewTabEditorConsole.svg</file>
<file>themes/default/console/iconRestoreTabsConsole.svg</file>
<file>themes/default/console/iconFileTabsMenuConsole.svg</file>
<file>themes/default/console/iconFormatCode.svg</file>
<file>themes/default/console/iconShowEditorConsole.svg</file>
<file>themes/default/console/iconCommentEditorConsole.svg</file>
<file>themes/default/console/iconUncommentEditorConsole.svg</file>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 353.176 353.176" style="enable-background:new 0 0 353.176 353.176;" xml:space="preserve" sodipodi:docname="wizard.svg" inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata id="metadata57"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs id="defs55"/><sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1920" inkscape:window-height="1017" id="namedview53" showgrid="false" inkscape:zoom="0.94500874" inkscape:cx="2.7621272" inkscape:cy="243.91811" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="g16"/>
<g id="g20">
<g id="g18">
<g id="g16">
<path d="m 281.90157,77.256044 c 2.12,0.11 4.193,-0.644 5.747,-2.09 l 37.094,-37.094 c 2.597,-3.462 1.895,-8.375 -1.567,-10.971 -2.786,-2.09 -6.618,-2.09 -9.404,0 l -37.094,37.094 c -2.987,3.047 -2.987,7.924 0,10.971 1.392,1.366 3.273,2.118 5.224,2.09 z" id="path6" inkscape:connector-curvature="0"/>
<path d="m 346.42112,112.327 h -43.29114 c -3.58626,0 -6.49388,3.509 -6.49388,7.837 0,4.328 2.90762,7.837 6.49388,7.837 h 43.29114 c 3.58626,0 6.49388,-3.509 6.49388,-7.837 -8.3e-4,-4.329 -2.90762,-7.837 -6.49388,-7.837 z" id="path8" inkscape:connector-curvature="0" style="stroke-width:0.91028452"/>
<path d="m 330.03253,197.08272 -37.094,-37.094 c -3.22,-2.529 -7.751,-2.529 -10.971,0 -3.052,3.224 -3.052,8.27 0,11.494 l 37.094,36.571 c 1.303,1.559 3.196,2.505 5.224,2.612 2.183,-0.086 4.246,-1.024 5.747,-2.612 3.03,-2.672 3.32,-7.294 0.648,-10.324 -0.202,-0.228 -0.418,-0.445 -0.648,-0.647 z" id="path10" inkscape:connector-curvature="0"/>
<path d="m 181.41809,73.049661 c 3.315,2.813 8.179,2.813 11.494,0 2.529,-3.22 2.529,-7.751 0,-10.971 l -37.094,-37.094 c -3.463,-2.597 -8.375,-1.895 -10.971,1.567 -2.09,2.786 -2.09,6.618 0,9.404 z" id="path12" inkscape:connector-curvature="0"/>
<path d="m 232.751,63.685235 c 4.328,0 7.837,-3.290313 7.837,-7.348585 V 7.3485849 C 240.588,3.2903132 237.079,0 232.751,0 c -4.328,0 -7.837,3.2903132 -7.837,7.3485849 V 56.337588 c 0,4.058271 3.509,7.347647 7.837,7.347647 z" id="path14" inkscape:connector-curvature="0" style="stroke-width:0.96833789"/>
<g id="g4588"><g id="g4597" transform="rotate(42.726697,172.50888,321.10701)" inkscape:transform-center-x="64.888571" inkscape:transform-center-y="38.220033"><g id="g4592" transform="translate(-1.1928715,11.1853)"><rect y="91.802742" x="52.909565" height="71.957001" width="57.14233" id="rect4567" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:9.60000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke" ry="1.0581913"/><rect ry="0" y="182.88254" x="62.070442" height="227.99924" width="36.957619" id="rect4567-9" style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:9.60000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"/></g></g></g></g>
</g>
</g>
<g id="g22">
</g>
<g id="g24">
</g>
<g id="g26">
</g>
<g id="g28">
</g>
<g id="g30">
</g>
<g id="g32">
</g>
<g id="g34">
</g>
<g id="g36">
</g>
<g id="g38">
</g>
<g id="g40">
</g>
<g id="g42">
</g>
<g id="g44">
</g>
<g id="g46">
</g>
<g id="g48">
</g>
<g id="g50">
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -289,6 +289,18 @@ class PythonConsoleWidget(QWidget):
self.toggleCommentEditorButton.setToolTip(toggleText + " <b>Ctrl+:</b>")
self.toggleCommentEditorButton.setText(toggleText)
# Action Format code
formatCodeText = QCoreApplication.translate("PythonConsole", "Format Code")
self.formatCodeEditorButton = QAction(self)
self.formatCodeEditorButton.setCheckable(False)
self.formatCodeEditorButton.setEnabled(True)
self.formatCodeEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconFormatCode.svg"))
self.formatCodeEditorButton.setMenuRole(QAction.PreferencesRole)
self.formatCodeEditorButton.setIconVisibleInMenu(True)
self.formatCodeEditorButton.setToolTip(formatCodeText + " <b>Ctrl+Alt+F</b>")
self.formatCodeEditorButton.setShortcut("Ctrl+Alt+F")
self.formatCodeEditorButton.setText(formatCodeText)
# Action for Object browser
objList = QCoreApplication.translate("PythonConsole", "Object Inspector…")
self.objectListButton = QAction(self)
@ -417,6 +429,7 @@ class PythonConsoleWidget(QWidget):
self.toolBarEditor.addAction(self.findTextButton)
self.toolBarEditor.addSeparator()
self.toolBarEditor.addAction(self.toggleCommentEditorButton)
self.toolBarEditor.addAction(self.formatCodeEditorButton)
self.toolBarEditor.addSeparator()
self.toolBarEditor.addAction(self.objectListButton)
@ -510,6 +523,7 @@ class PythonConsoleWidget(QWidget):
self.findTextButton.triggered.connect(self._toggleFind)
self.objectListButton.toggled.connect(self.toggleObjectListWidget)
self.toggleCommentEditorButton.triggered.connect(self.toggleComment)
self.formatCodeEditorButton.triggered.connect(self.formatCode)
self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
self.cutEditorButton.triggered.connect(self.cutEditor)
self.copyEditorButton.triggered.connect(self.copyEditor)
@ -641,6 +655,9 @@ class PythonConsoleWidget(QWidget):
def toggleComment(self):
self.tabEditorWidget.currentWidget().toggleComment()
def formatCode(self):
self.tabEditorWidget.currentWidget().newEditor.formatCode()
def openScriptFileExtEditor(self):
tabWidget = self.tabEditorWidget.currentWidget()
path = tabWidget.path

View File

@ -30,6 +30,8 @@ from functools import partial
from operator import itemgetter
from pathlib import Path
import autopep8
from qgis.core import Qgis, QgsApplication, QgsBlockingNetworkRequest, QgsFileUtils, QgsSettings
from qgis.gui import QgsCodeEditorPython, QgsMessageBar
from qgis.PyQt.Qsci import QsciScintilla
@ -229,6 +231,23 @@ class Editor(QgsCodeEditorPython):
def findPrevious(self):
self.findText(False)
def formatCode(self):
new_text = autopep8.fix_code(self.text())
if new_text == self.text():
return
# Try to preserve the cursor position and scroll position
old_pos = self.getCursorPosition()
old_scroll_value = self.verticalScrollBar().value()
self.beginUndoAction()
self.selectAll()
self.removeSelectedText()
self.insert(new_text)
self.setCursorPosition(*old_pos)
self.verticalScrollBar().setValue(old_scroll_value)
self.endUndoAction()
def objectListEditor(self):
listObj = self.pythonconsole.listClassMethod
if listObj.isVisible():