QGIS API Documentation 3.28.14-Firenze (exported)
Loading...
Searching...
No Matches
qgscodeeditorpython.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscodeeditorpython.cpp - A Python editor based on QScintilla
3 --------------------------------------
4 Date : 06-Oct-2013
5 Copyright : (C) 2013 by Salvatore Larosa
6 Email : lrssvtml (at) gmail (dot) com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsapplication.h"
17#include "qgscodeeditorpython.h"
18#include "qgslogger.h"
19#include "qgssymbollayerutils.h"
20#include "qgssettings.h"
21#include "qgis.h"
22
23#include <QWidget>
24#include <QString>
25#include <QFont>
26#include <QUrl>
27#include <QFileInfo>
28#include <QMessageBox>
29#include <QTextStream>
30#include <Qsci/qscilexerpython.h>
31#include <QDesktopServices>
32
33QgsCodeEditorPython::QgsCodeEditorPython( QWidget *parent, const QList<QString> &filenames )
34 : QgsCodeEditor( parent,
35 QString(),
36 false,
37 false,
38 QgsCodeEditor::Flag::CodeFolding )
39 , mAPISFilesList( filenames )
40{
41 if ( !parent )
42 {
43 setTitle( tr( "Python Editor" ) );
44 }
45
46 setCaretWidth( 2 );
47
49}
50
52{
53 // current line
54 setEdgeMode( QsciScintilla::EdgeLine );
55 setEdgeColumn( 80 );
57
58 setWhitespaceVisibility( QsciScintilla::WsVisibleAfterIndent );
59
60 QFont font = lexerFont();
62
63 QsciLexerPython *pyLexer = new QgsQsciLexerPython( this );
64
65 pyLexer->setIndentationWarning( QsciLexerPython::Inconsistent );
66 pyLexer->setFoldComments( true );
67 pyLexer->setFoldQuotes( true );
68
69 pyLexer->setDefaultFont( font );
70 pyLexer->setDefaultColor( defaultColor );
72 pyLexer->setFont( font, -1 );
73
74 font.setItalic( true );
75 pyLexer->setFont( font, QsciLexerPython::Comment );
76 pyLexer->setFont( font, QsciLexerPython::CommentBlock );
77
78 font.setItalic( false );
79 font.setBold( true );
80 pyLexer->setFont( font, QsciLexerPython::SingleQuotedString );
81 pyLexer->setFont( font, QsciLexerPython::DoubleQuotedString );
82
83 pyLexer->setColor( defaultColor, QsciLexerPython::Default );
84 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Class ), QsciLexerPython::ClassName );
85 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Method ), QsciLexerPython::FunctionMethodName );
86 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Number ), QsciLexerPython::Number );
87 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Operator ), QsciLexerPython::Operator );
88 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Identifier ), QsciLexerPython::Identifier );
89 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Comment ), QsciLexerPython::Comment );
90 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::CommentBlock ), QsciLexerPython::CommentBlock );
91 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Keyword ), QsciLexerPython::Keyword );
92 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Decoration ), QsciLexerPython::Decorator );
93 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::SingleQuote ), QsciLexerPython::SingleQuotedString );
94 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::DoubleQuote ), QsciLexerPython::DoubleQuotedString );
95 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::TripleSingleQuote ), QsciLexerPython::TripleSingleQuotedString );
96 pyLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::TripleDoubleQuote ), QsciLexerPython::TripleDoubleQuotedString );
97
98 QsciAPIs *apis = new QsciAPIs( pyLexer );
99
100 const QgsSettings settings;
101
102 if ( mAPISFilesList.isEmpty() )
103 {
104 if ( settings.value( QStringLiteral( "pythonConsole/preloadAPI" ), true ).toBool() )
105 {
106 mPapFile = QgsApplication::pkgDataPath() + QStringLiteral( "/python/qsci_apis/pyqgis.pap" );
107 apis->loadPrepared( mPapFile );
108 }
109 else if ( settings.value( QStringLiteral( "pythonConsole/usePreparedAPIFile" ), false ).toBool() )
110 {
111 apis->loadPrepared( settings.value( QStringLiteral( "pythonConsole/preparedAPIFile" ) ).toString() );
112 }
113 else
114 {
115 const QStringList apiPaths = settings.value( QStringLiteral( "pythonConsole/userAPI" ) ).toStringList();
116 for ( const QString &path : apiPaths )
117 {
118 if ( !QFileInfo::exists( path ) )
119 {
120 QgsDebugMsg( QStringLiteral( "The apis file %1 was not found" ).arg( path ) );
121 }
122 else
123 {
124 apis->load( path );
125 }
126 }
127 apis->prepare();
128 pyLexer->setAPIs( apis );
129 }
130 }
131 else if ( mAPISFilesList.length() == 1 && mAPISFilesList[0].right( 3 ) == QLatin1String( "pap" ) )
132 {
133 if ( !QFileInfo::exists( mAPISFilesList[0] ) )
134 {
135 QgsDebugMsg( QStringLiteral( "The apis file %1 not found" ).arg( mAPISFilesList.at( 0 ) ) );
136 return;
137 }
138 mPapFile = mAPISFilesList[0];
139 apis->loadPrepared( mPapFile );
140 }
141 else
142 {
143 for ( const QString &path : mAPISFilesList )
144 {
145 if ( !QFileInfo::exists( path ) )
146 {
147 QgsDebugMsg( QStringLiteral( "The apis file %1 was not found" ).arg( path ) );
148 }
149 else
150 {
151 apis->load( path );
152 }
153 }
154 apis->prepare();
155 pyLexer->setAPIs( apis );
156 }
157 setLexer( pyLexer );
158
159 const int threshold = settings.value( QStringLiteral( "pythonConsole/autoCompThreshold" ), 2 ).toInt();
160 setAutoCompletionThreshold( threshold );
161 if ( !settings.value( "pythonConsole/autoCompleteEnabled", true ).toBool() )
162 {
163 setAutoCompletionSource( AcsNone );
164 }
165 else
166 {
167 const QString autoCompleteSource = settings.value( QStringLiteral( "pythonConsole/autoCompleteSource" ), QStringLiteral( "fromAPI" ) ).toString();
168 if ( autoCompleteSource == QLatin1String( "fromDoc" ) )
169 setAutoCompletionSource( AcsDocument );
170 else if ( autoCompleteSource == QLatin1String( "fromDocAPI" ) )
171 setAutoCompletionSource( AcsAll );
172 else
173 setAutoCompletionSource( AcsAPIs );
174 }
175
176 setLineNumbersVisible( true );
177 setIndentationsUseTabs( false );
178 setIndentationGuides( true );
179
181}
182
184{
185 switch ( autoCompletionSource() )
186 {
187 case AcsDocument:
188 autoCompleteFromDocument();
189 break;
190
191 case AcsAPIs:
192 autoCompleteFromAPIs();
193 break;
194
195 case AcsAll:
196 autoCompleteFromAll();
197 break;
198
199 case AcsNone:
200 break;
201 }
202}
203
204void QgsCodeEditorPython::loadAPIs( const QList<QString> &filenames )
205{
206 mAPISFilesList = filenames;
207 //QgsDebugMsg( QStringLiteral( "The apis files: %1" ).arg( mAPISFilesList[0] ) );
209}
210
211bool QgsCodeEditorPython::loadScript( const QString &script )
212{
213 QgsDebugMsgLevel( QStringLiteral( "The script file: %1" ).arg( script ), 2 );
214 QFile file( script );
215 if ( !file.open( QIODevice::ReadOnly ) )
216 {
217 return false;
218 }
219
220 QTextStream in( &file );
221#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
222 in.setCodec( "UTF-8" );
223#endif
224
225 setText( in.readAll().trimmed() );
226 file.close();
227
229 return true;
230}
231
233{
234 if ( !hasSelectedText() )
235 return;
236
237 QString text = selectedText();
238 text = text.replace( QLatin1String( ">>> " ), QString() ).replace( QLatin1String( "... " ), QString() ).trimmed(); // removing prompts
239 const QString version = QString( Qgis::version() ).split( '.' ).mid( 0, 2 ).join( '.' );
240 QDesktopServices::openUrl( QUrl( QStringLiteral( "https://qgis.org/pyqgis/%1/search.html?q=%2" ).arg( version, text ) ) );
241}
242
244//
245// QgsQsciLexerPython
246//
247QgsQsciLexerPython::QgsQsciLexerPython( QObject *parent )
248 : QsciLexerPython( parent )
249{
250
251}
252
253const char *QgsQsciLexerPython::keywords( int set ) const
254{
255 if ( set == 1 )
256 {
257 return "True False and as assert break class continue def del elif else except exec "
258 "finally for from global if import in is lambda None not or pass "
259 "print raise return try while with yield";
260 }
261
262 return QsciLexerPython::keywords( set );
263}
static QString version()
Version string.
Definition qgis.cpp:277
static QString pkgDataPath()
Returns the common root path of all application data directories.
@ TripleSingleQuote
Triple single quote color.
@ CommentBlock
Comment block color.
@ DoubleQuote
Double quote color.
@ SingleQuote
Single quote color.
@ TripleDoubleQuote
Triple double quote color.
void autoComplete()
Triggers the autocompletion popup.
void searchSelectedTextInPyQGISDocs()
Searches the selected text in the official PyQGIS online documentation.
void loadAPIs(const QList< QString > &filenames)
Load APIs from one or more files.
void initializeLexer() override
Called when the dialect specific code lexer needs to be initialized (or reinitialized).
bool loadScript(const QString &script)
Load a script file.
QgsCodeEditorPython(QWidget *parent=nullptr, const QList< QString > &filenames=QList< QString >())
Construct a new Python editor.
A text editor based on QScintilla2.
void runPostLexerConfigurationTasks()
Performs tasks which must be run after a lexer has been set for the widget.
void setTitle(const QString &title)
Set the widget title.
Flag
Flags controlling behavior of code editor.
void setLineNumbersVisible(bool visible)
Sets whether line numbers should be visible in the editor.
QFont lexerFont() const
Returns the font to use in the lexer.
QColor lexerColor(QgsCodeEditorColorScheme::ColorRole role) const
Returns the color to use in the lexer for the specified role.
static QColor defaultColor(QgsCodeEditorColorScheme::ColorRole role, const QString &theme=QString())
Returns the default color for the specified role.
This class is a composition of two QSettings instances:
Definition qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
#define QgsDebugMsg(str)
Definition qgslogger.h:38