QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgscodeeditorhtml.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscodeeditorhtml.cpp - A HTML editor based on QScintilla
3 --------------------------------------
4 Date : 20-Jul-2014
5 Copyright : (C) 2014 by Nathan Woodrow
6 Email : woodrow.nathan (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 "qgscodeeditorhtml.h"
17
18#include "qgsprocessingutils.h"
19#include "qgspythonrunner.h"
20
21#include <QFont>
22#include <QString>
23#include <QWidget>
24#include <Qsci/qscilexerhtml.h>
25
26#include "moc_qgscodeeditorhtml.cpp"
27
29 : QgsCodeEditor( parent, QString(), false, false, QgsCodeEditor::Flag::CodeFolding )
30{
31 if ( !parent )
32 {
33 setTitle( tr( "HTML Editor" ) );
34 }
36
39 {
40 // we could potentially check for beautifulsoup4 import here and reflect the capability accordingly.
41 // (current approach is to to always indicate this capability and raise a user-friendly warning
42 // when attempting to reformat if the libraries can't be imported)
44 }
45}
46
51
56
58{
59 QFont font = lexerFont();
61
62 QsciLexerHTML *lexer = new QsciLexerHTML( this );
63 lexer->setDefaultFont( font );
64 lexer->setDefaultColor( defaultColor );
66 lexer->setFont( font, -1 );
67
68 font.setItalic( true );
69 lexer->setFont( font, QsciLexerHTML::HTMLComment );
70 lexer->setFont( font, QsciLexerHTML::JavaScriptComment );
71 lexer->setFont( font, QsciLexerHTML::JavaScriptCommentLine );
72
73 lexer->setColor( defaultColor, QsciLexerHTML::Default );
74 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Tag ), QsciLexerHTML::Tag );
75 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::UnknownTag ), QsciLexerHTML::UnknownTag );
76 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Method ), QsciLexerHTML::Attribute );
77 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Method ), QsciLexerHTML::UnknownAttribute );
78 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Class ), QsciLexerHTML::Entity );
79 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Number ), QsciLexerHTML::HTMLNumber );
80 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Comment ), QsciLexerHTML::HTMLComment );
81 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Comment ), QsciLexerHTML::JavaScriptComment );
82 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::CommentLine ), QsciLexerHTML::JavaScriptCommentLine );
83 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Number ), QsciLexerHTML::JavaScriptNumber );
84 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Keyword ), QsciLexerHTML::JavaScriptKeyword );
85 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::DoubleQuote ), QsciLexerHTML::JavaScriptDoubleQuotedString );
86 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::SingleQuote ), QsciLexerHTML::JavaScriptSingleQuotedString );
87 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::SingleQuote ), QsciLexerHTML::HTMLSingleQuotedString );
88 lexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::DoubleQuote ), QsciLexerHTML::HTMLDoubleQuotedString );
89
90 setLexer( lexer );
92}
93
94QString QgsCodeEditorHTML::reformatCodeString( const QString &string )
95{
97 {
98 return string;
99 }
100 QString newText = string;
101
102 const QString definePrettify = QStringLiteral(
103 "def __qgis_prettify(text):\n"
104 " try:\n"
105 " from bs4 import BeautifulSoup\n"
106 " return BeautifulSoup(text, 'html.parser').prettify()\n"
107 " except ImportError:\n"
108 " try:\n"
109 " import re\n"
110 " from lxml import etree, html\n"
111 " text = re.sub('>\\\\s+<', '><', text)\n"
112 " text = re.sub('\\n\\\\s*', '', text)\n"
113 " document_root = html.fromstring(text)\n"
114 " return etree.tostring(document_root, encoding='utf-8', pretty_print=True).decode('utf-8')\n"
115 " except ImportError:\n"
116 " return '_ImportError'\n"
117 );
118
119
120 if ( !QgsPythonRunner::run( definePrettify ) )
121 {
122 QgsDebugError( QStringLiteral( "Error running script: %1" ).arg( definePrettify ) );
123 return string;
124 }
125
126 const QString script = QStringLiteral( "__qgis_prettify(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( newText ) );
127 QString result;
128 if ( QgsPythonRunner::eval( script, result ) )
129 {
130 if ( result == QLatin1String( "_ImportError" ) )
131 {
132 showMessage( tr( "Reformat Code" ), tr( "HTML reformatting requires bs4 or lxml python modules to be installed" ), Qgis::MessageLevel::Warning );
133 }
134 else
135 {
136 newText = result;
137 }
138 }
139 else
140 {
141 QgsDebugError( QStringLiteral( "Error running script: %1" ).arg( script ) );
142 return newText;
143 }
144
145 return newText;
146}
147
149{
150 if ( isReadOnly() )
151 {
152 return;
153 }
154
155 const QString commentStart( "<!--" );
156 const QString commentEnd( "-->" );
157
158 int startLine, startPos, endLine, endPos;
159 if ( hasSelectedText() )
160 {
161 getSelection( &startLine, &startPos, &endLine, &endPos );
162 }
163 else
164 {
165 getCursorPosition( &startLine, &startPos );
166 endLine = startLine;
167 endPos = startPos;
168 }
169
170
171 // Compute first and last non-blank lines
172 while ( text( startLine ).trimmed().isEmpty() )
173 {
174 startLine++;
175 if ( startLine > endLine )
176 {
177 // Only blank lines selected
178 return;
179 }
180 }
181 while ( text( endLine ).trimmed().isEmpty() )
182 {
183 endLine--;
184 }
185
186 // Remove leading spaces from the start line
187 QString startLineTrimmed = text( startLine );
188 startLineTrimmed.remove( QRegularExpression( "^\\s+" ) );
189 // Remove trailing spaces from the end line
190 QString endLineTrimmed = text( endLine );
191 endLineTrimmed.remove( QRegularExpression( "\\s+$" ) );
192
193 const bool commented = startLineTrimmed.startsWith( commentStart ) && endLineTrimmed.endsWith( commentEnd );
194
195 // Special case, selected text is <!--> or <!--->
196 if ( commented && startLine == endLine && text( endLine ).trimmed().size() < commentStart.size() + commentEnd.size() )
197 {
198 return;
199 }
200
201 beginUndoAction();
202
203 // Selection is commented: uncomment it
204 if ( commented )
205 {
206 int c1, c2;
207
208 // Remove trailing comment tag ( --> )
209 c2 = endLineTrimmed.size();
210 if ( endLineTrimmed.endsWith( QStringLiteral( " " ) + commentEnd ) )
211 {
212 c1 = c2 - commentEnd.size() - 1;
213 }
214 else
215 {
216 c1 = c2 - commentEnd.size();
217 }
218
219 setSelection( endLine, c1, endLine, c2 );
220 removeSelectedText();
221
222 // Remove leading comment tag ( <!-- )
223 c1 = indentation( startLine );
224 if ( startLineTrimmed.startsWith( commentStart + QStringLiteral( " " ) ) )
225 {
226 c2 = c1 + commentStart.size() + 1;
227 }
228 else
229 {
230 c2 = c1 + commentStart.size();
231 }
232
233 setSelection( startLine, c1, startLine, c2 );
234 removeSelectedText();
235 }
236 // Selection is not commented: comment it
237 else
238 {
239 insertAt( QStringLiteral( " " ) + commentEnd, endLine, endLineTrimmed.size() );
240 insertAt( commentStart + QStringLiteral( " " ), startLine, indentation( startLine ) );
241 }
242
243 endUndoAction();
244
245 // Restore selection
246 setSelection( startLine, startPos, endLine, endPos );
247}
@ Warning
Warning message.
Definition qgis.h:158
@ Reformat
Language supports automatic code reformatting.
Definition qgis.h:4502
@ ToggleComment
Language supports comment toggling.
Definition qgis.h:4504
ScriptLanguage
Scripting languages.
Definition qgis.h:4478
QFlags< ScriptLanguageCapability > ScriptLanguageCapabilities
Script language capabilities.
Definition qgis.h:4513
Qgis::ScriptLanguage language() const override
Returns the associated scripting language.
Qgis::ScriptLanguageCapabilities languageCapabilities() const override
Returns the associated scripting language capabilities.
void initializeLexer() override
Called when the dialect specific code lexer needs to be initialized (or reinitialized).
QString reformatCodeString(const QString &string) override
Applies code reformatting to a string and returns the result.
QgsCodeEditorHTML(QWidget *parent=nullptr)
Constructor for QgsCodeEditorHTML.
void toggleComment() override
Toggle comment for the selected text.
void runPostLexerConfigurationTasks()
Performs tasks which must be run after a lexer has been set for the widget.
virtual void showMessage(const QString &title, const QString &message, Qgis::MessageLevel level)
Shows a user facing message (eg a warning message).
void setTitle(const QString &title)
Set the widget title.
QgsCodeEditor(QWidget *parent=nullptr, const QString &title=QString(), bool folding=false, bool margin=false, QgsCodeEditor::Flags flags=QgsCodeEditor::Flags(), QgsCodeEditor::Mode mode=QgsCodeEditor::Mode::ScriptEditor)
Construct a new code editor.
Flag
Flags controlling behavior of code 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.
static QString stringToPythonLiteral(const QString &string)
Converts a string to a Python string literal.
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a Python statement.
static bool eval(const QString &command, QString &result)
Eval a Python statement.
static bool isValid()
Returns true if the runner has an instance (and thus is able to run commands).
#define QgsDebugError(str)
Definition qgslogger.h:57