QGIS API Documentation 3.28.14-Firenze (exported)
Loading...
Searching...
No Matches
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#if QSCINTILLA_VERSION < 0x020d03
109 installEventFilter( this );
110#endif
111}
112
113// Workaround a bug in QScintilla 2.8.X
114void QgsCodeEditor::focusOutEvent( QFocusEvent *event )
115{
116#if QSCINTILLA_VERSION >= 0x020800 && QSCINTILLA_VERSION < 0x020900
117 if ( event->reason() != Qt::ActiveWindowFocusReason )
118 {
119 /* There's a bug in all QScintilla 2.8.X, where
120 a focus out event that is not due to ActiveWindowFocusReason doesn't
121 lead to the bliking caret being disabled. The hack consists in making
122 QsciScintilla::focusOutEvent believe that the event is a ActiveWindowFocusReason
123 The bug was fixed in 2.9 per:
124 2015-04-14 Phil Thompson <phil@riverbankcomputing.com>
125
126 * qt/qsciscintillabase.cpp:
127 Fixed a problem notifying when focus is lost to another application
128 widget.
129 [41734678234e]
130 */
131 QFocusEvent newFocusEvent( QEvent::FocusOut, Qt::ActiveWindowFocusReason );
132 QsciScintilla::focusOutEvent( &newFocusEvent );
133 }
134 else
135#endif
136 {
137 QsciScintilla::focusOutEvent( event );
138 }
139}
140
141// This workaround a likely bug in QScintilla. The ESC key should not be consumned
142// by the main entry, so that the default behavior (Dialog closing) can trigger,
143// but only is the auto-completion suggestion list isn't displayed
144void QgsCodeEditor::keyPressEvent( QKeyEvent *event )
145{
146 if ( event->key() == Qt::Key_Escape && !isListActive() )
147 {
148 // Shortcut QScintilla and redirect the event to the QWidget handler
149 QWidget::keyPressEvent( event ); // clazy:exclude=skipped-base-method
150 }
151 else
152 {
153 QsciScintilla::keyPressEvent( event );
154 }
155}
156
157bool QgsCodeEditor::eventFilter( QObject *watched, QEvent *event )
158{
159#if QSCINTILLA_VERSION < 0x020d03
160 if ( watched == this && event->type() == QEvent::InputMethod )
161 {
162 // swallow input method events, which cause loss of selected text.
163 // See https://sourceforge.net/p/scintilla/bugs/1913/ , which was ported to QScintilla
164 // in version 2.13.3
165 return true;
166 }
167#endif
168
169 return QsciScintilla::eventFilter( watched, event );
170}
171
176
178{
179 if ( mUseDefaultSettings )
180 return color( role );
181
182 if ( !mOverrideColors )
183 {
184 return defaultColor( role, mColorScheme );
185 }
186 else
187 {
188 const QColor color = mCustomColors.value( role );
189 return !color.isValid() ? defaultColor( role ) : color;
190 }
191}
192
194{
195 if ( mUseDefaultSettings )
196 return getMonospaceFont();
197
198 QFont font = QFontDatabase::systemFont( QFontDatabase::FixedFont );
199
200 const QgsSettings settings;
201 if ( !mFontFamily.isEmpty() )
202 font.setFamily( mFontFamily );
203
204#ifdef Q_OS_MAC
205 if ( mFontSize > 0 )
206 font.setPointSize( mFontSize );
207 else
208 {
209 // The font size gotten from getMonospaceFont() is too small on Mac
210 font.setPointSize( QLabel().font().pointSize() );
211 }
212#else
213 if ( mFontSize > 0 )
214 font.setPointSize( mFontSize );
215 else
216 {
217 const int fontSize = settings.value( QStringLiteral( "qgis/stylesheet/fontPointSize" ), 10 ).toInt();
218 font.setPointSize( fontSize );
219 }
220#endif
221 font.setBold( false );
222
223 return font;
224}
225
227{
228 updateFolding();
229
232
233 SendScintilla( SCI_MARKERSETFORE, SC_MARKNUM_FOLDEROPEN, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconHalo ) );
234 SendScintilla( SCI_MARKERSETBACK, SC_MARKNUM_FOLDEROPEN, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconForeground ) );
235 SendScintilla( SCI_MARKERSETFORE, SC_MARKNUM_FOLDER, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconHalo ) );
236 SendScintilla( SCI_MARKERSETBACK, SC_MARKNUM_FOLDER, lexerColor( QgsCodeEditorColorScheme::ColorRole::FoldIconForeground ) );
237 SendScintilla( SCI_STYLESETFORE, STYLE_INDENTGUIDE, lexerColor( QgsCodeEditorColorScheme::ColorRole::IndentationGuide ) );
238 SendScintilla( SCI_STYLESETBACK, STYLE_INDENTGUIDE, lexerColor( QgsCodeEditorColorScheme::ColorRole::IndentationGuide ) );
239}
240
241void QgsCodeEditor::setSciWidget()
242{
243 const QFont font = lexerFont();
244 setFont( font );
245
246 setUtf8( true );
247 setCaretLineVisible( true );
248 setCaretLineBackgroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::CaretLine ) );
249 setCaretForegroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Cursor ) );
252
253 setBraceMatching( QsciScintilla::SloppyBraceMatch );
256
257 setLineNumbersVisible( false );
258
259 // temporarily disable folding, will be enabled later if required by updateFolding()
260 setFolding( QsciScintilla::NoFoldStyle );
261 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), 0 );
262
263 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 0 );
264
267 setIndentationGuidesForegroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::MarginForeground ) );
268 setIndentationGuidesBackgroundColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::MarginBackground ) );
269 // whether margin will be shown
270 updateFolding();
271 const QColor foldColor = lexerColor( QgsCodeEditorColorScheme::ColorRole::Fold );
272 setFoldMarginColors( foldColor, foldColor );
273 // indentation
274 setAutoIndent( true );
275 setIndentationWidth( 4 );
276 setTabIndents( true );
277 setBackspaceUnindents( true );
278 setTabWidth( 4 );
279 // autocomplete
280 setAutoCompletionThreshold( 2 );
281 setAutoCompletionSource( QsciScintilla::AcsAPIs );
282
283 markerDefine( QgsApplication::getThemePixmap( "console/iconSyntaxErrorConsoleParams.svg", lexerColor( QgsCodeEditorColorScheme::ColorRole::Error ),
285}
286
287void QgsCodeEditor::setTitle( const QString &title )
288{
289 setWindowTitle( title );
290}
291
293{
294 mMargin = margin;
295 if ( margin )
296 {
297 QFont marginFont = lexerFont();
298 marginFont.setPointSize( 10 );
299 setMarginLineNumbers( 0, true );
300 setMarginsFont( marginFont );
301 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), QStringLiteral( "00000" ) );
304 }
305 else
306 {
307 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), 0 );
308 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 0 );
309 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), 0 );
310 }
311}
312
314{
315 if ( visible )
316 {
317 QFont marginFont = lexerFont();
318 marginFont.setPointSize( 10 );
319 setMarginLineNumbers( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), true );
320 setMarginsFont( marginFont );
321 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), QStringLiteral( "00000" ) );
324 }
325 else
326 {
327 setMarginLineNumbers( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), false );
328 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ), 0 );
329 }
330}
331
333{
334 return marginLineNumbers( static_cast< int >( QgsCodeEditor::MarginRole::LineNumbers ) );
335}
336
338{
339 if ( folding )
340 {
342 }
343 else
344 {
345 mFlags &= ~( static_cast< int >( QgsCodeEditor::Flag::CodeFolding ) );
346 }
347 updateFolding();
348}
349
354
355void QgsCodeEditor::updateFolding()
356{
358 {
359 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), "0" );
362 setFolding( QsciScintilla::PlainFoldStyle );
363 }
364 else
365 {
366 setFolding( QsciScintilla::NoFoldStyle );
367 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::FoldingControls ), 0 );
368 }
369}
370
371void QgsCodeEditor::insertText( const QString &text )
372{
373 // Insert the text or replace selected text
374 if ( hasSelectedText() )
375 {
376 replaceSelectedText( text );
377 }
378 else
379 {
380 int line, index;
381 getCursorPosition( &line, &index );
382 insertAt( text, line, index );
383 setCursorPosition( line, index + text.length() );
384 }
385}
386
388{
389 if ( theme.isEmpty() && QgsApplication::themeName() == QLatin1String( "default" ) )
390 {
391 // if using default theme, take certain colors from the palette
392 const QPalette pal = qApp->palette();
393
394 switch ( role )
395 {
397 return pal.color( QPalette::Highlight );
399 return pal.color( QPalette::HighlightedText );
400 default:
401 break;
402 }
403 }
404 else if ( theme.isEmpty() )
405 {
406 // non default theme (e.g. Blend of Gray). Take colors from theme ini file...
407 const QSettings ini( QgsApplication::uiThemes().value( QgsApplication::themeName() ) + "/qscintilla.ini", QSettings::IniFormat );
408
409 static const QMap< QgsCodeEditorColorScheme::ColorRole, QString > sColorRoleToIniKey
410 {
411 {QgsCodeEditorColorScheme::ColorRole::Default, QStringLiteral( "python/defaultFontColor" ) },
412 {QgsCodeEditorColorScheme::ColorRole::Keyword, QStringLiteral( "python/keywordFontColor" ) },
413 {QgsCodeEditorColorScheme::ColorRole::Class, QStringLiteral( "python/classFontColor" ) },
414 {QgsCodeEditorColorScheme::ColorRole::Method, QStringLiteral( "python/methodFontColor" ) },
415 {QgsCodeEditorColorScheme::ColorRole::Decoration, QStringLiteral( "python/decoratorFontColor" ) },
416 {QgsCodeEditorColorScheme::ColorRole::Number, QStringLiteral( "python/numberFontColor" ) },
417 {QgsCodeEditorColorScheme::ColorRole::Comment, QStringLiteral( "python/commentFontColor" ) },
418 {QgsCodeEditorColorScheme::ColorRole::CommentLine, QStringLiteral( "sql/commentLineFontColor" ) },
419 {QgsCodeEditorColorScheme::ColorRole::CommentBlock, QStringLiteral( "python/commentBlockFontColor" ) },
420 {QgsCodeEditorColorScheme::ColorRole::Background, QStringLiteral( "python/paperBackgroundColor" ) },
421 {QgsCodeEditorColorScheme::ColorRole::Cursor, QStringLiteral( "cursorColor" ) },
422 {QgsCodeEditorColorScheme::ColorRole::CaretLine, QStringLiteral( "caretLineColor" ) },
423 {QgsCodeEditorColorScheme::ColorRole::Operator, QStringLiteral( "sql/operatorFontColor" ) },
424 {QgsCodeEditorColorScheme::ColorRole::QuotedOperator, QStringLiteral( "sql/QuotedOperatorFontColor" ) },
425 {QgsCodeEditorColorScheme::ColorRole::Identifier, QStringLiteral( "sql/identifierFontColor" ) },
426 {QgsCodeEditorColorScheme::ColorRole::QuotedIdentifier, QStringLiteral( "sql/QuotedIdentifierFontColor" ) },
427 {QgsCodeEditorColorScheme::ColorRole::Tag, QStringLiteral( "html/tagFontColor" ) },
428 {QgsCodeEditorColorScheme::ColorRole::UnknownTag, QStringLiteral( "html/unknownTagFontColor" ) },
429 {QgsCodeEditorColorScheme::ColorRole::SingleQuote, QStringLiteral( "sql/singleQuoteFontColor" ) },
430 {QgsCodeEditorColorScheme::ColorRole::DoubleQuote, QStringLiteral( "sql/doubleQuoteFontColor" ) },
431 {QgsCodeEditorColorScheme::ColorRole::TripleSingleQuote, QStringLiteral( "python/tripleSingleQuoteFontColor" ) },
432 {QgsCodeEditorColorScheme::ColorRole::TripleDoubleQuote, QStringLiteral( "python/tripleDoubleQuoteFontColor" ) },
433 {QgsCodeEditorColorScheme::ColorRole::MarginBackground, QStringLiteral( "marginBackgroundColor" ) },
434 {QgsCodeEditorColorScheme::ColorRole::MarginForeground, QStringLiteral( "marginForegroundColor" ) },
435 {QgsCodeEditorColorScheme::ColorRole::SelectionBackground, QStringLiteral( "selectionBackgroundColor" ) },
436 {QgsCodeEditorColorScheme::ColorRole::SelectionForeground, QStringLiteral( "selectionForegroundColor" ) },
437 {QgsCodeEditorColorScheme::ColorRole::MatchedBraceBackground, QStringLiteral( "matchedBraceBackground" ) },
438 {QgsCodeEditorColorScheme::ColorRole::MatchedBraceForeground, QStringLiteral( "matchedBraceColor" ) },
439 {QgsCodeEditorColorScheme::ColorRole::Edge, QStringLiteral( "edgeColor" ) },
440 {QgsCodeEditorColorScheme::ColorRole::Fold, QStringLiteral( "foldColor" ) },
441 {QgsCodeEditorColorScheme::ColorRole::Error, QStringLiteral( "stderrFontColor" ) },
442 {QgsCodeEditorColorScheme::ColorRole::ErrorBackground, QStringLiteral( "stderrBackground" ) },
443 {QgsCodeEditorColorScheme::ColorRole::FoldIconForeground, QStringLiteral( "foldIconForeground" ) },
444 {QgsCodeEditorColorScheme::ColorRole::FoldIconHalo, QStringLiteral( "foldIconHalo" ) },
445 {QgsCodeEditorColorScheme::ColorRole::IndentationGuide, QStringLiteral( "indentationGuide" ) },
446 };
447
448 const QgsCodeEditorColorScheme defaultScheme = QgsGui::codeEditorColorSchemeRegistry()->scheme( QStringLiteral( "default" ) );
449 return QgsSymbolLayerUtils::decodeColor( ini.value( sColorRoleToIniKey.value( role ), defaultScheme.color( role ).name() ).toString() );
450 }
451
452 const QgsCodeEditorColorScheme scheme = QgsGui::codeEditorColorSchemeRegistry()->scheme( theme.isEmpty() ? QStringLiteral( "default" ) : theme );
453 return scheme.color( role );
454}
455
457{
458 const QgsSettings settings;
459 if ( !settings.value( QStringLiteral( "codeEditor/overrideColors" ), false, QgsSettings::Gui ).toBool() )
460 {
461 const QString theme = settings.value( QStringLiteral( "codeEditor/colorScheme" ), QString(), QgsSettings::Gui ).toString();
462 return defaultColor( role, theme );
463 }
464 else
465 {
466 const QString color = settings.value( QStringLiteral( "codeEditor/%1" ).arg( sColorRoleToSettingsKey.value( role ) ), QString(), QgsSettings::Gui ).toString();
467 return color.isEmpty() ? defaultColor( role ) : QgsSymbolLayerUtils::decodeColor( color );
468 }
469}
470
472{
473 QgsSettings settings;
474 if ( color.isValid() )
475 {
476 settings.setValue( QStringLiteral( "codeEditor/%1" ).arg( sColorRoleToSettingsKey.value( role ) ), color.name(), QgsSettings::Gui );
477 }
478 else
479 {
480 settings.remove( QStringLiteral( "codeEditor/%1" ).arg( sColorRoleToSettingsKey.value( role ) ), QgsSettings::Gui );
481 }
482}
483
484// Settings for font and fontsize
485bool QgsCodeEditor::isFixedPitch( const QFont &font )
486{
487 return font.fixedPitch();
488}
489
491{
492 QFont font = QFontDatabase::systemFont( QFontDatabase::FixedFont );
493
494 const QgsSettings settings;
495 if ( !settings.value( QStringLiteral( "codeEditor/fontfamily" ), QString(), QgsSettings::Gui ).toString().isEmpty() )
496 font.setFamily( settings.value( QStringLiteral( "codeEditor/fontfamily" ), QString(), QgsSettings::Gui ).toString() );
497
498 const int fontSize = settings.value( QStringLiteral( "codeEditor/fontsize" ), 0, QgsSettings::Gui ).toInt();
499
500#ifdef Q_OS_MAC
501 if ( fontSize > 0 )
502 font.setPointSize( fontSize );
503 else
504 {
505 // The font size gotten from getMonospaceFont() is too small on Mac
506 font.setPointSize( QLabel().font().pointSize() );
507 }
508#else
509 if ( fontSize > 0 )
510 font.setPointSize( fontSize );
511 else
512 {
513 const int fontSize = settings.value( QStringLiteral( "qgis/stylesheet/fontPointSize" ), 10 ).toInt();
514 font.setPointSize( fontSize );
515 }
516#endif
517 font.setBold( false );
518
519 return font;
520}
521
522void QgsCodeEditor::setCustomAppearance( const QString &scheme, const QMap<QgsCodeEditorColorScheme::ColorRole, QColor> &customColors, const QString &fontFamily, int fontSize )
523{
524 mUseDefaultSettings = false;
525 mOverrideColors = !customColors.isEmpty();
526 mColorScheme = scheme;
527 mCustomColors = customColors;
528 mFontFamily = fontFamily;
529 mFontSize = fontSize;
530
531 setSciWidget();
533}
534
535void QgsCodeEditor::addWarning( const int lineNumber, const QString &warning )
536{
537 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), "000" );
538 markerAdd( lineNumber, MARKER_NUMBER );
539 QFont font = lexerFont();
540 font.setItalic( true );
541 const QsciStyle styleAnn = QsciStyle( -1, QStringLiteral( "Annotation" ),
544 font,
545 true );
546 annotate( lineNumber, warning, styleAnn );
547 mWarningLines.push_back( lineNumber );
548}
549
551{
552 for ( const int line : mWarningLines )
553 {
554 markerDelete( line );
555 clearAnnotations( line );
556 }
557 setMarginWidth( static_cast< int >( QgsCodeEditor::MarginRole::ErrorIndicators ), 0 );
558 mWarningLines.clear();
559}
560
562{
563 int line = 0;
564 int index = 0;
565 getCursorPosition( &line, &index );
566 return line == lines() - 1;
567}
568
570{
571 setCursorPosition( 0, 0 );
572 ensureCursorVisible();
573 ensureLineVisible( 0 );
574}
575
577{
578 const int endLine = lines() - 1;
579 const int endLineLength = lineLength( endLine );
580 setCursorPosition( endLine, endLineLength );
581 ensureCursorVisible();
582 ensureLineVisible( endLine );
583}
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.
bool eventFilter(QObject *watched, QEvent *event) override
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)