/
console_base.py
155 lines (132 loc) · 7.5 KB
/
console_base.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# -*- coding:utf-8 -*-
"""
/***************************************************************************
Python Console for QGIS
-------------------
begin : 2020-06-04
copyright : (C) 2020 by Richard Duivenvoorde
email : Richard Duivenvoorde (at) duif (dot) net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
Some portions of code were taken from https://code.google.com/p/pydee/
"""
from qgis.PyQt.QtCore import Qt, QUrl
from qgis.PyQt.QtGui import QColor, QFontDatabase, QDesktopServices
from qgis.PyQt.Qsci import QsciLexerPython, QsciAPIs
from qgis.core import QgsApplication, Qgis
from qgis.gui import QgsCodeEditorPython, QgsCodeEditor
import os
import re
class QgsPythonConsoleBase(QgsCodeEditorPython):
MARKER_NUM = 6
HANDY_COMMANDS = ['_pyqgis', '_api', '_cookbook']
def __init__(self, parent=None):
super().__init__(parent)
# Enable non-ascii chars
self.setUtf8(True)
# Set the default font
font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
self.setFont(font)
# Margin 0 is used for line numbers (editor and output)
self.setMarginWidth(0, "00000")
# Margin 1 is used for the '>>>' prompt (console input)
self.setMarginWidth(1, "0")
self.setMarginType(1, 5) # TextMarginRightJustified=5
# Margin 2 is used for the 'folding' (editor)
self.setMarginWidth(2, "0")
self.setCaretLineVisible(True)
self.setCaretWidth(2)
self.iconRun = QgsApplication.getThemeIcon("console/mIconRunConsole.svg")
self.iconRunScript = QgsApplication.getThemeIcon("mActionStart.svg")
self.iconUndo = QgsApplication.getThemeIcon("mActionUndo.svg")
self.iconRedo = QgsApplication.getThemeIcon("mActionRedo.svg")
self.iconCodePad = QgsApplication.getThemeIcon("console/iconCodepadConsole.svg")
self.iconCommentEditor = QgsApplication.getThemeIcon("console/iconCommentEditorConsole.svg")
self.iconUncommentEditor = QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.svg")
self.iconSettings = QgsApplication.getThemeIcon("console/iconSettingsConsole.svg")
self.iconFind = QgsApplication.getThemeIcon("console/iconSearchEditorConsole.svg")
self.iconSyntaxCk = QgsApplication.getThemeIcon("console/iconSyntaxErrorConsole.svg")
self.iconObjInsp = QgsApplication.getThemeIcon("console/iconClassBrowserConsole.svg")
self.iconCut = QgsApplication.getThemeIcon("mActionEditCut.svg")
self.iconCopy = QgsApplication.getThemeIcon("mActionEditCopy.svg")
self.iconPaste = QgsApplication.getThemeIcon("mActionEditPaste.svg")
self.iconClear = QgsApplication.getThemeIcon("console/iconClearConsole.svg")
self.iconHideTool = QgsApplication.getThemeIcon("console/iconHideToolConsole.svg")
self.iconShowEditor = QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg")
self.iconPyQGISHelp = QgsApplication.getThemeIcon("console/iconHelpConsole.svg")
def setLexers(self):
self.lexer = QsciLexerPython()
self.lexer.setIndentationWarning(QsciLexerPython.Inconsistent)
self.lexer.setFoldComments(True)
self.lexer.setFoldQuotes(True)
font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
# output and console
loadFont = self.settings.value("pythonConsole/fontfamilytext")
if loadFont:
font.setFamily(loadFont)
fontSize = self.settings.value("pythonConsole/fontsize", type=int)
if fontSize:
font.setPointSize(fontSize)
self.lexer.setDefaultFont(font)
self.lexer.setDefaultColor(self.color(QgsCodeEditor.ColorRole.Default))
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.Comment), 1)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.Number), 2)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.Keyword), 5)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.Class), 8)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.Method), 9)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.Decoration), 15)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.CommentBlock), 12)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.SingleQuote), 4)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.DoubleQuote), 3)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.TripleSingleQuote), 6)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.TripleDoubleQuote), 7)
self.lexer.setColor(self.color(QgsCodeEditor.ColorRole.Default), 13)
self.lexer.setColor(QColor(Qt.red), 14)
self.lexer.setFont(font, 1)
self.lexer.setFont(font, 2)
self.lexer.setFont(font, 3)
self.lexer.setFont(font, 4)
self.lexer.setFont(font, QsciLexerPython.UnclosedString)
# ? only for editor and console ?
paperColor = self.color(QgsCodeEditor.ColorRole.Background)
for style in range(0, 33):
self.lexer.setPaper(paperColor, style)
self.api = QsciAPIs(self.lexer)
checkBoxAPI = self.settings.value("pythonConsole/preloadAPI", True, type=bool)
checkBoxPreparedAPI = self.settings.value("pythonConsole/usePreparedAPIFile", False, type=bool)
if checkBoxAPI:
pap = os.path.join(QgsApplication.pkgDataPath(), "python", "qsci_apis", "pyqgis.pap")
self.api.loadPrepared(pap)
elif checkBoxPreparedAPI:
self.api.loadPrepared(self.settings.value("pythonConsole/preparedAPIFile"))
else:
apiPath = self.settings.value("pythonConsole/userAPI", [])
for i in range(0, len(apiPath)):
self.api.load(apiPath[i])
self.api.prepare()
self.lexer.setAPIs(self.api)
self.setLexer(self.lexer)
def searchPyQGIS(self):
if self.hasSelectedText():
text = self.selectedText()
text = text.replace('>>> ', '').replace('... ', '').strip() # removing prompts
version = '.'.join(Qgis.QGIS_VERSION.split('.')[0:2])
QDesktopServices.openUrl(QUrl('https://qgis.org/pyqgis/' + version + '/search.html?q=' + text))
def handyCommands(self, hcmd):
version = 'master' if 'master' in Qgis.QGIS_VERSION.lower() else re.findall(r'^\d.[0-9]*', Qgis.QGIS_VERSION)[0]
if hcmd == '_pyqgis':
QDesktopServices.openUrl(QUrl("https://qgis.org/pyqgis/{}".format(version)))
elif hcmd == '_api':
QDesktopServices.openUrl(QUrl("https://qgis.org/api/{}".format('' if version == 'master' else version)))
elif hcmd == '_cookbook':
QDesktopServices.openUrl(QUrl("https://docs.qgis.org/{}/en/docs/pyqgis_developer_cookbook/".format(
'testing' if version == 'master' else version)))
if __name__ == "__main__":
pass