QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgscodeeditor.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscodeeditor.cpp - A base code editor for QGIS and plugins. Provides
3 a base editor using QScintilla for editors
4 --------------------------------------
5 Date : 06-Oct-2013
6 Copyright : (C) 2013 by Salvatore Larosa
7 Email : lrssvtml (at) gmail (dot) com
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include "qgsapplication.h"
18#include "qgscodeeditor.h"
19#include "qgssettings.h"
20#include "qgssymbollayerutils.h"
21#include "qgsgui.h"
23
24#include <QLabel>
25#include <QWidget>
26#include <QFont>
27#include <QFontDatabase>
28#include <QDebug>
29#include <QFocusEvent>
30#include <Qsci/qscistyle.h>
31
32QMap< QgsCodeEditorColorScheme::ColorRole, QString > QgsCodeEditor::sColorRoleToSettingsKey
33{
34 {QgsCodeEditorColorScheme::ColorRole::Default, QStringLiteral( "defaultFontColor" ) },
35 {QgsCodeEditorColorScheme::ColorRole::Keyword, QStringLiteral( "keywordFontColor" ) },
36 {QgsCodeEditorColorScheme::ColorRole::Class, QStringLiteral( "classFontColor" ) },
37 {QgsCodeEditorColorScheme::ColorRole::Method, QStringLiteral( "methodFontColor" ) },
38 {QgsCodeEditorColorScheme::ColorRole::Decoration, QStringLiteral( "decoratorFontColor" ) },
39 {QgsCodeEditorColorScheme::ColorRole::Number, QStringLiteral( "numberFontColor" ) },
40 {QgsCodeEditorColorScheme::ColorRole::Comment, QStringLiteral( "commentFontColor" ) },
41 {QgsCodeEditorColorScheme::ColorRole::CommentLine, QStringLiteral( "commentLineFontColor" ) },
42 {QgsCodeEditorColorScheme::ColorRole::CommentBlock, QStringLiteral( "commentBlockFontColor" ) },
43 {QgsCodeEditorColorScheme::ColorRole::Background, QStringLiteral( "paperBackgroundColor" ) },
44 {QgsCodeEditorColorScheme::ColorRole::Cursor, QStringLiteral( "cursorColor" ) },
45 {QgsCodeEditorColorScheme::ColorRole::CaretLine, QStringLiteral( "caretLineColor" ) },
46 {QgsCodeEditorColorScheme::ColorRole::Operator, QStringLiteral( "operatorFontColor" ) },
47 {QgsCodeEditorColorScheme::ColorRole::QuotedOperator, QStringLiteral( "quotedOperatorFontColor" ) },
48 {QgsCodeEditorColorScheme::ColorRole::Identifier, QStringLiteral( "identifierFontColor" ) },
49 {QgsCodeEditorColorScheme::ColorRole::QuotedIdentifier, QStringLiteral( "quotedIdentifierFontColor" ) },
50 {QgsCodeEditorColorScheme::ColorRole::Tag, QStringLiteral( "tagFontColor" ) },
51 {QgsCodeEditorColorScheme::ColorRole::UnknownTag, QStringLiteral( "unknownTagFontColor" ) },
52 {QgsCodeEditorColorScheme::ColorRole::SingleQuote, QStringLiteral( "singleQuoteFontColor" ) },
53 {QgsCodeEditorColorScheme::ColorRole::DoubleQuote, QStringLiteral( "doubleQuoteFontColor" ) },
54 {QgsCodeEditorColorScheme::ColorRole::TripleSingleQuote, QStringLiteral( "tripleSingleQuoteFontColor" ) },
55 {QgsCodeEditorColorScheme::ColorRole::TripleDoubleQuote, QStringLiteral( "tripleDoubleQuoteFontColor" ) },
56 {QgsCodeEditorColorScheme::ColorRole::MarginBackground, QStringLiteral( "marginBackgroundColor" ) },
57 {QgsCodeEditorColorScheme::ColorRole::MarginForeground, QStringLiteral( "marginForegroundColor" ) },
58 {QgsCodeEditorColorScheme::ColorRole::SelectionBackground, QStringLiteral( "selectionBackgroundColor" ) },
59 {QgsCodeEditorColorScheme::ColorRole::SelectionForeground, QStringLiteral( "selectionForegroundColor" ) },
60 {QgsCodeEditorColorScheme::ColorRole::MatchedBraceBackground, QStringLiteral( "matchedBraceBackground" ) },
61 {QgsCodeEditorColorScheme::ColorRole::MatchedBraceForeground, QStringLiteral( "matchedBraceColor" ) },
62 {QgsCodeEditorColorScheme::ColorRole::Edge, QStringLiteral( "edgeColor" ) },
63 {QgsCodeEditorColorScheme::ColorRole::Fold, QStringLiteral( "foldColor" ) },
64 {QgsCodeEditorColorScheme::ColorRole::Error, QStringLiteral( "stderrFontColor" ) },
65 {QgsCodeEditorColorScheme::ColorRole::ErrorBackground, QStringLiteral( "stderrBackgroundColor" ) },
66 {QgsCodeEditorColorScheme::ColorRole::FoldIconForeground, QStringLiteral( "foldIconForeground" ) },
67 {QgsCodeEditorColorScheme::ColorRole::FoldIconHalo, QStringLiteral( "foldIconHalo" ) },
68 {QgsCodeEditorColorScheme::ColorRole::IndentationGuide, QStringLiteral( "indentationGuide" ) },
69};
70
71
72QgsCodeEditor::QgsCodeEditor( QWidget *parent, const QString &title, bool folding, bool margin, QgsCodeEditor::Flags flags )
73 : QsciScintilla( parent )
74 , mWidgetTitle( title )
75 , mMargin( margin )
76 , mFlags( flags )
77{
78 if ( !parent && mWidgetTitle.isEmpty() )
79 {
80 setWindowTitle( QStringLiteral( "Text Editor" ) );
81 }
82 else
83 {
84 setWindowTitle( mWidgetTitle );
85 }
86
87 if ( folding )
89
90 setSciWidget();
91 setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
92
93 SendScintilla( SCI_SETADDITIONALSELECTIONTYPING, 1 );
94 SendScintilla( SCI_SETMULTIPASTE, 1 );
95 SendScintilla( SCI_SETVIRTUALSPACEOPTIONS, SCVS_RECTANGULARSELECTION );
96
97 SendScintilla( SCI_SETMARGINTYPEN, static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), SC_MARGIN_SYMBOL );
98 SendScintilla( SCI_SETMARGINMASKN, static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 1 << MARKER_NUMBER );
99 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 0 );
100 setAnnotationDisplay( QsciScintilla::AnnotationBoxed );
101
102 connect( QgsGui::instance(), &QgsGui::optionsChanged, this, [ = ]
103 {
104 setSciWidget();
106 } );
107}
108
109// Workaround a bug in QScintilla 2.8.X
110void QgsCodeEditor::focusOutEvent( QFocusEvent *event )
111{
112#if QSCINTILLA_VERSION >= 0x020800 && QSCINTILLA_VERSION < 0x020900
113 if ( event->reason() != Qt::ActiveWindowFocusReason )
114 {
115 /* There's a bug in all QScintilla 2.8.X, where
116 a focus out event that is not due to ActiveWindowFocusReason doesn't
117 lead to the bliking caret being disabled. The hack consists in making
118 QsciScintilla::focusOutEvent believe that the event is a ActiveWindowFocusReason
119 The bug was fixed in 2.9 per:
120 2015-04-14 Phil Thompson <[email protected]>
121
122 * qt/qsciscintillabase.cpp:
123 Fixed a problem notifying when focus is lost to another application
124 widget.
125 [41734678234e]
126 */
127 QFocusEvent newFocusEvent( QEvent::FocusOut, Qt::ActiveWindowFocusReason );
128 QsciScintilla::focusOutEvent( &newFocusEvent );
129 }
130 else
131#endif
132 {
133 QsciScintilla::focusOutEvent( event );
134 }
135}
136
137// This workaround a likely bug in QScintilla. The ESC key should not be consumned
138// by the main entry, so that the default behavior (Dialog closing) can trigger,
139// but only is the auto-completion suggestion list isn't displayed
140void QgsCodeEditor::keyPressEvent( QKeyEvent *event )
141{
142 if ( event->key() == Qt::Key_Escape && !isListActive() )
143 {
144 // Shortcut QScintilla and redirect the event to the QWidget handler
145 QWidget::keyPressEvent( event ); // clazy:exclude=skipped-base-method
146 }
147 else
148 {
149 QsciScintilla::keyPressEvent( event );
150 }
151}
152
154{
155
156}
157
159{
160 if ( mUseDefaultSettings )
161 return color( role );
162
163 if ( !mOverrideColors )
164 {
165 return defaultColor( role, mColorScheme );
166 }
167 else
168 {
169 const QColor color = mCustomColors.value( role );
170 return !color.isValid() ? defaultColor( role ) : color;
171 }
172}
173
175{
176 if ( mUseDefaultSettings )
177 return getMonospaceFont();
178
179 QFont font = QFontDatabase::systemFont( QFontDatabase::FixedFont );
180
181 const QgsSettings settings;
182 if ( !mFontFamily.isEmpty() )
183 font.setFamily( mFontFamily );
184
185#ifdef Q_OS_MAC
186 if ( mFontSize > 0 )
187 font.setPointSize( mFontSize );
188 else
189 {
190 // The font size gotten from getMonospaceFont() is too small on Mac
191 font.setPointSize( QLabel().font().pointSize() );
192 }
193#else
194 if ( mFontSize > 0 )
195 font.setPointSize( mFontSize );
196 else
197 {
198 const int fontSize = settings.value( QStringLiteral( "qgis/stylesheet/fontPointSize" ), 10 ).toInt();
199 font.setPointSize( fontSize );
200 }
201#endif
202 font.setBold( false );
203
204 return font;
205}
206
208{
209 updateFolding();
210
213
214 SendScintilla( SCI_MARKERSETFORE, SC_MARKNUM_FOLDEROPEN, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconHalo ) );
215 SendScintilla( SCI_MARKERSETBACK, SC_MARKNUM_FOLDEROPEN, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconForeground ) );
216 SendScintilla( SCI_MARKERSETFORE, SC_MARKNUM_FOLDER, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconHalo ) );
217 SendScintilla( SCI_MARKERSETBACK, SC_MARKNUM_FOLDER, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconForeground ) );
218 SendScintilla( SCI_STYLESETFORE, STYLE_INDENTGUIDE, lexerColor( QgsCodeEditorColorScheme::ColorRole::IndentationGuide ) );
219 SendScintilla( SCI_STYLESETBACK, STYLE_INDENTGUIDE, lexerColor( QgsCodeEditorColorScheme::ColorRole::IndentationGuide ) );
220}
221
222void QgsCodeEditor::setSciWidget()
223{
224 const QFont font = lexerFont();
225 setFont( font );
226
227 setUtf8( true );
228 setCaretLineVisible( true );
229 setCaretLineBackgroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::CaretLine ) );
230 setCaretForegroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Cursor ) );
233
234 setBraceMatching( QsciScintilla::SloppyBraceMatch );
237
238 setLineNumbersVisible( false );
239
240 // temporarily disable folding, will be enabled later if required by updateFolding()
241 setFolding( QsciScintilla::NoFoldStyle );
242 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), 0 );
243
244 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 0 );
245
248 setIndentationGuidesForegroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::MarginForeground ) );
249 setIndentationGuidesBackgroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::MarginBackground ) );
250 // whether margin will be shown
251 updateFolding();
252 const QColor foldColor = lexerColor( QgsCodeEditorColorScheme::ColorRole::Fold );
253 setFoldMarginColors( foldColor, foldColor );
254 // indentation
255 setAutoIndent( true );
256 setIndentationWidth( 4 );
257 setTabIndents( true );
258 setBackspaceUnindents( true );
259 setTabWidth( 4 );
260 // autocomplete
261 setAutoCompletionThreshold( 2 );
262 setAutoCompletionSource( QsciScintilla::AcsAPIs );
263
264 markerDefine( QgsApplication::getThemePixmap( "console/iconSyntaxErrorConsoleParams.svg", lexerColor( QgsCodeEditorColorScheme::ColorRole::Error ),
266}
267
268void QgsCodeEditor::setTitle( const QString &title )
269{
270 setWindowTitle( title );
271}
272
274{
275 mMargin = margin;
276 if ( margin )
277 {
278 QFont marginFont = lexerFont();
279 marginFont.setPointSize( 10 );
280 setMarginLineNumbers( 0, true );
281 setMarginsFont( marginFont );
282 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), QStringLiteral( "00000" ) );
285 }
286 else
287 {
288 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), 0 );
289 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 0 );
290 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), 0 );
291 }
292}
293
295{
296 if ( visible )
297 {
298 QFont marginFont = lexerFont();
299 marginFont.setPointSize( 10 );
300 setMarginLineNumbers( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), true );
301 setMarginsFont( marginFont );
302 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), QStringLiteral( "00000" ) );
305 }
306 else
307 {
308 setMarginLineNumbers( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), false );
309 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), 0 );
310 }
311}
312
314{
315 return marginLineNumbers( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ) );
316}
317
319{
320 if ( folding )
321 {
323 }
324 else
325 {
326 mFlags &= ~( static_cast< int >( QgsCodeEditor::Flag::CodeFolding ) );
327 }
328 updateFolding();
329}
330
332{
333 return mFlags & QgsCodeEditor::Flag::CodeFolding;
334}
335
336void QgsCodeEditor::updateFolding()
337{
339 {
340 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), "0" );
343 setFolding( QsciScintilla::PlainFoldStyle );
344 }
345 else
346 {
347 setFolding( QsciScintilla::NoFoldStyle );
348 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), 0 );
349 }
350}
351
352void QgsCodeEditor::insertText( const QString &text )
353{
354 // Insert the text or replace selected text
355 if ( hasSelectedText() )
356 {
357 replaceSelectedText( text );
358 }
359 else
360 {
361 int line, index;
362 getCursorPosition( &line, &index );
363 insertAt( text, line, index );
364 setCursorPosition( line, index + text.length() );
365 }
366}
367
369{
370 if ( theme.isEmpty() && QgsApplication::themeName() == QLatin1String( "default" ) )
371 {
372 // if using default theme, take certain colors from the palette
373 const QPalette pal = qApp->palette();
374
375 switch ( role )
376 {
378 return pal.color( QPalette::Highlight );
380 return pal.color( QPalette::HighlightedText );
381 default:
382 break;
383 }
384 }
385 else if ( theme.isEmpty() )
386 {
387 // non default theme (e.g. Blend of Gray). Take colors from theme ini file...
388 const QSettings ini( QgsApplication::uiThemes().value( QgsApplication::themeName() ) + "/qscintilla.ini", QSettings::IniFormat );
389
390 static const QMap< QgsCodeEditorColorScheme::ColorRole, QString > sColorRoleToIniKey
391 {
392 {QgsCodeEditorColorScheme::ColorRole::Default, QStringLiteral( "python/defaultFontColor" ) },
393 {QgsCodeEditorColorScheme::ColorRole::Keyword, QStringLiteral( "python/keywordFontColor" ) },
394 {QgsCodeEditorColorScheme::ColorRole::Class, QStringLiteral( "python/classFontColor" ) },
395 {QgsCodeEditorColorScheme::ColorRole::Method, QStringLiteral( "python/methodFontColor" ) },
396 {QgsCodeEditorColorScheme::ColorRole::Decoration, QStringLiteral( "python/decoratorFontColor" ) },
397 {QgsCodeEditorColorScheme::ColorRole::Number, QStringLiteral( "python/numberFontColor" ) },
398 {QgsCodeEditorColorScheme::ColorRole::Comment, QStringLiteral( "python/commentFontColor" ) },
399 {QgsCodeEditorColorScheme::ColorRole::CommentLine, QStringLiteral( "sql/commentLineFontColor" ) },
400 {QgsCodeEditorColorScheme::ColorRole::CommentBlock, QStringLiteral( "python/commentBlockFontColor" ) },
401 {QgsCodeEditorColorScheme::ColorRole::Background, QStringLiteral( "python/paperBackgroundColor" ) },
402 {QgsCodeEditorColorScheme::ColorRole::Cursor, QStringLiteral( "cursorColor" ) },
403 {QgsCodeEditorColorScheme::ColorRole::CaretLine, QStringLiteral( "caretLineColor" ) },
404 {QgsCodeEditorColorScheme::ColorRole::Operator, QStringLiteral( "sql/operatorFontColor" ) },
405 {QgsCodeEditorColorScheme::ColorRole::QuotedOperator, QStringLiteral( "sql/QuotedOperatorFontColor" ) },
406 {QgsCodeEditorColorScheme::ColorRole::Identifier, QStringLiteral( "sql/identifierFontColor" ) },
407 {QgsCodeEditorColorScheme::ColorRole::QuotedIdentifier, QStringLiteral( "sql/QuotedIdentifierFontColor" ) },
408 {QgsCodeEditorColorScheme::ColorRole::Tag, QStringLiteral( "html/tagFontColor" ) },
409 {QgsCodeEditorColorScheme::ColorRole::UnknownTag, QStringLiteral( "html/unknownTagFontColor" ) },
410 {QgsCodeEditorColorScheme::ColorRole::SingleQuote, QStringLiteral( "sql/singleQuoteFontColor" ) },
411 {QgsCodeEditorColorScheme::ColorRole::DoubleQuote, QStringLiteral( "sql/doubleQuoteFontColor" ) },
412 {QgsCodeEditorColorScheme::ColorRole::TripleSingleQuote, QStringLiteral( "python/tripleSingleQuoteFontColor" ) },
413 {QgsCodeEditorColorScheme::ColorRole::TripleDoubleQuote, QStringLiteral( "python/tripleDoubleQuoteFontColor" ) },
414 {QgsCodeEditorColorScheme::ColorRole::MarginBackground, QStringLiteral( "marginBackgroundColor" ) },
415 {QgsCodeEditorColorScheme::ColorRole::MarginForeground, QStringLiteral( "marginForegroundColor" ) },
416 {QgsCodeEditorColorScheme::ColorRole::SelectionBackground, QStringLiteral( "selectionBackgroundColor" ) },
417 {QgsCodeEditorColorScheme::ColorRole::SelectionForeground, QStringLiteral( "selectionForegroundColor" ) },
418 {QgsCodeEditorColorScheme::ColorRole::MatchedBraceBackground, QStringLiteral( "matchedBraceBackground" ) },
419 {QgsCodeEditorColorScheme::ColorRole::MatchedBraceForeground, QStringLiteral( "matchedBraceColor" ) },
420 {QgsCodeEditorColorScheme::ColorRole::Edge, QStringLiteral( "edgeColor" ) },
421 {QgsCodeEditorColorScheme::ColorRole::Fold, QStringLiteral( "foldColor" ) },
422 {QgsCodeEditorColorScheme::ColorRole::Error, QStringLiteral( "stderrFontColor" ) },
423 {QgsCodeEditorColorScheme::ColorRole::ErrorBackground, QStringLiteral( "stderrBackground" ) },
424 {QgsCodeEditorColorScheme::ColorRole::FoldIconForeground, QStringLiteral( "foldIconForeground" ) },
425 {QgsCodeEditorColorScheme::ColorRole::FoldIconHalo, QStringLiteral( "foldIconHalo" ) },
426 {QgsCodeEditorColorScheme::ColorRole::IndentationGuide, QStringLiteral( "indentationGuide" ) },
427 };
428
429 const QgsCodeEditorColorScheme defaultScheme = QgsGui::codeEditorColorSchemeRegistry()->scheme( QStringLiteral( "default" ) );
430 return QgsSymbolLayerUtils::decodeColor( ini.value( sColorRoleToIniKey.value( role ), defaultScheme.color( role ).name() ).toString() );
431 }
432
433 const QgsCodeEditorColorScheme scheme = QgsGui::codeEditorColorSchemeRegistry()->scheme( theme.isEmpty() ? QStringLiteral( "default" ) : theme );
434 return scheme.color( role );
435}
436
438{
439 const QgsSettings settings;
440 if ( !settings.value( QStringLiteral( "codeEditor/overrideColors" ), false, QgsSettings::Gui ).toBool() )
441 {
442 const QString theme = settings.value( QStringLiteral( "codeEditor/colorScheme" ), QString(), QgsSettings::Gui ).toString();
443 return defaultColor( role, theme );
444 }
445 else
446 {
447 const QString color = settings.value( QStringLiteral( "codeEditor/%1" ).arg( sColorRoleToSettingsKey.value( role ) ), QString(), QgsSettings::Gui ).toString();
448 return color.isEmpty() ? defaultColor( role ) : QgsSymbolLayerUtils::decodeColor( color );
449 }
450}
451
453{
454 QgsSettings settings;
455 if ( color.isValid() )
456 {
457 settings.setValue( QStringLiteral( "codeEditor/%1" ).arg( sColorRoleToSettingsKey.value( role ) ), color.name(), QgsSettings::Gui );
458 }
459 else
460 {
461 settings.remove( QStringLiteral( "codeEditor/%1" ).arg( sColorRoleToSettingsKey.value( role ) ), QgsSettings::Gui );
462 }
463}
464
465// Settings for font and fontsize
466bool QgsCodeEditor::isFixedPitch( const QFont &font )
467{
468 return font.fixedPitch();
469}
470
472{
473 QFont font = QFontDatabase::systemFont( QFontDatabase::FixedFont );
474
475 const QgsSettings settings;
476 if ( !settings.value( QStringLiteral( "codeEditor/fontfamily" ), QString(), QgsSettings::Gui ).toString().isEmpty() )
477 font.setFamily( settings.value( QStringLiteral( "codeEditor/fontfamily" ), QString(), QgsSettings::Gui ).toString() );
478
479 const int fontSize = settings.value( QStringLiteral( "codeEditor/fontsize" ), 0, QgsSettings::Gui ).toInt();
480
481#ifdef Q_OS_MAC
482 if ( fontSize > 0 )
483 font.setPointSize( fontSize );
484 else
485 {
486 // The font size gotten from getMonospaceFont() is too small on Mac
487 font.setPointSize( QLabel().font().pointSize() );
488 }
489#else
490 if ( fontSize > 0 )
491 font.setPointSize( fontSize );
492 else
493 {
494 const int fontSize = settings.value( QStringLiteral( "qgis/stylesheet/fontPointSize" ), 10 ).toInt();
495 font.setPointSize( fontSize );
496 }
497#endif
498 font.setBold( false );
499
500 return font;
501}
502
503void QgsCodeEditor::setCustomAppearance( const QString &scheme, const QMap<QgsCodeEditorColorScheme::ColorRole, QColor> &customColors, const QString &fontFamily, int fontSize )
504{
505 mUseDefaultSettings = false;
506 mOverrideColors = !customColors.isEmpty();
507 mColorScheme = scheme;
508 mCustomColors = customColors;
509 mFontFamily = fontFamily;
510 mFontSize = fontSize;
511
512 setSciWidget();
514}
515
516void QgsCodeEditor::addWarning( const int lineNumber, const QString &warning )
517{
518 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), "000" );
519 markerAdd( lineNumber, MARKER_NUMBER );
520 QFont font = lexerFont();
521 font.setItalic( true );
522 const QsciStyle styleAnn = QsciStyle( -1, QStringLiteral( "Annotation" ),
525 font,
526 true );
527 annotate( lineNumber, warning, styleAnn );
528 mWarningLines.push_back( lineNumber );
529}
530
532{
533 for ( const int line : mWarningLines )
534 {
535 markerDelete( line );
536 clearAnnotations( line );
537 }
538 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 0 );
539 mWarningLines.clear();
540}
541
543{
544 int line = 0;
545 int index = 0;
546 getCursorPosition( &line, &index );
547 return line == lines() - 1;
548}
549
551{
552 setCursorPosition( 0, 0 );
553 ensureCursorVisible();
554 ensureLineVisible( 0 );
555}
556
558{
559 const int endLine = lines() - 1;
560 const int endLineLength = lineLength( endLine );
561 setCursorPosition( endLine, endLineLength );
562 ensureCursorVisible();
563 ensureLineVisible( endLine );
564}
static QPixmap getThemePixmap(const QString &name, const QColor &foreColor=QColor(), const QColor &backColor=QColor(), int size=16)
Helper to get a theme icon as a pixmap.
static QHash< QString, QString > uiThemes()
All themes found in ~/.qgis3/themes folder.
static QString themeName()
Set the active theme to the specified theme.
QgsCodeEditorColorScheme scheme(const QString &id) const
Returns the color scheme with matching id.
Defines a color scheme for use in QgsCodeEditor widgets.
@ TripleSingleQuote
Triple single quote color.
@ CommentBlock
Comment block color.
@ QuotedOperator
Quoted operator color.
@ DoubleQuote
Double quote color.
@ QuotedIdentifier
Quoted identifier color.
@ SelectionForeground
Selection foreground color.
@ CommentLine
Line comment color.
@ FoldIconForeground
Fold icon foreground color.
@ MarginForeground
Margin foreground color.
@ ErrorBackground
Error background color.
@ MatchedBraceBackground
Matched brace background color.
@ IndentationGuide
Indentation guide line.
@ SingleQuote
Single quote color.
@ MarginBackground
Margin background color.
@ SelectionBackground
Selection background color.
@ MatchedBraceForeground
Matched brace foreground color.
@ TripleDoubleQuote
Triple double quote color.
@ FoldIconHalo
Fold icon halo color.
QColor color(ColorRole role) const
Returns the color to use in the editor for the specified role.
void setCustomAppearance(const QString &scheme=QString(), const QMap< QgsCodeEditorColorScheme::ColorRole, QColor > &customColors=QMap< QgsCodeEditorColorScheme::ColorRole, QColor >(), const QString &fontFamily=QString(), int fontSize=0)
Sets a custom appearance for the widget, disconnecting it from using the standard appearance taken fr...
static void setColor(QgsCodeEditorColorScheme::ColorRole role, const QColor &color)
Sets the color to use in the editor for the specified role.
void keyPressEvent(QKeyEvent *event) override
virtual void moveCursorToStart()
Moves the cursor to the start of the document and scrolls to ensure it is visible.
void setFoldingVisible(bool folding)
Set whether the folding controls are visible in the editor.
@ FoldingControls
Folding controls.
@ ErrorIndicators
Error indicators.
@ LineNumbers
Line numbers.
void runPostLexerConfigurationTasks()
Performs tasks which must be run after a lexer has been set for the widget.
virtual void initializeLexer()
Called when the dialect specific code lexer needs to be initialized (or reinitialized).
void setTitle(const QString &title)
Set the widget title.
void clearWarnings()
Clears all warning messages from the editor.
static QFont getMonospaceFont()
Returns the monospaced font to use for code editors.
void focusOutEvent(QFocusEvent *event) override
@ CodeFolding
Indicates that code folding should be enabled for the editor.
bool isCursorOnLastLine() const
Returns true if the cursor is on the last line of the document.
bool isFixedPitch(const QFont &font)
QgsCodeEditor(QWidget *parent=nullptr, const QString &title=QString(), bool folding=false, bool margin=false, QgsCodeEditor::Flags flags=QgsCodeEditor::Flags())
Flags controlling behavior of code editor.
void insertText(const QString &text)
Insert text at cursor position, or replace any selected text if user has made a selection.
virtual void moveCursorToEnd()
Moves the cursor to the end of the document and scrolls to ensure it is visible.
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.
bool lineNumbersVisible() const
Returns whether line numbers are visible in the editor.
QColor lexerColor(QgsCodeEditorColorScheme::ColorRole role) const
Returns the color to use in the lexer for the specified role.
bool foldingVisible()
Returns true if the folding controls are visible in the editor.
Q_DECL_DEPRECATED void setMarginVisible(bool margin)
Set margin visible state.
static QColor defaultColor(QgsCodeEditorColorScheme::ColorRole role, const QString &theme=QString())
Returns the default color for the specified role.
void addWarning(int lineNumber, const QString &warning)
Adds a warning message and indicator to the specified a lineNumber.
static QColor color(QgsCodeEditorColorScheme::ColorRole role)
Returns the color to use in the editor for the specified role.
void optionsChanged()
This signal is emitted whenever the application options have been changed.
static QgsGui * instance()
Returns a pointer to the singleton instance.
Definition: qgsgui.cpp:67
static QgsCodeEditorColorSchemeRegistry * codeEditorColorSchemeRegistry()
Returns the global code editor color scheme registry, used for registering the color schemes for QgsC...
Definition: qgsgui.cpp:148
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.
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QColor decodeColor(const QString &str)