25 #include <QCryptographicHash>
27 #include <QFontMetrics>
28 #include <QKeySequence>
29 #include <QLatin1Char>
32 #include <QPaintEvent>
35 #include <QRegularExpressionMatchIterator>
38 #include <QTextCursor>
40 #include <QTextFormat>
47 QSyntaxHighlighter(parent),
48 mWidgetStyle(widgetStyle)
54 QStringList keywordPatterns;
56 keywordPatterns <<
"alignas"
112 <<
"reinterpret_cast"
138 for (
const QString &pattern : keywordPatterns) {
139 rule.
pattern = QRegularExpression(
"\\b" + pattern +
"\\b");
147 rule.
pattern = QRegularExpression(
"\\bQ[A-Za-z]+\\b");
156 rule.
pattern = QRegularExpression(
"\".*?(?<!\\\\)\"");
163 rule.
pattern = QRegularExpression(
"//[^\n]*");
186 for (
const QString &sym : symbols) {
188 rule.
pattern = QRegularExpression(
"\\b" + sym +
"\\b");
222 QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
223 while (matchIterator.hasNext()) {
224 QRegularExpressionMatch
match = matchIterator.next();
225 setFormat(
match.capturedStart(),
match.capturedLength(), rule.format);
229 setCurrentBlockState(0);
232 if (previousBlockState() != 1)
235 while (startIndex >= 0) {
237 const int endIndex =
match.capturedStart();
238 int commentLength = 0;
239 if (endIndex == -1) {
240 setCurrentBlockState(1);
241 commentLength = text.length() - startIndex;
243 commentLength = endIndex - startIndex
244 +
match.capturedLength();
254 case RuleRole::Keyword:
257 case RuleRole::Class:
260 case RuleRole::Comment:
263 case RuleRole::Quote:
266 case RuleRole::Symbol:
273 QPlainTextEdit(parent),
280 QFont font(
"Monospace");
281 font.setStyleHint(QFont::TypeWriter);
286 setObjectName(
"CodeEditor");
289 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
290 auto *copyText =
new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_C),
this);
291 auto *allText =
new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_A),
this);
293 const auto *copyText =
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_C),
this);
294 const auto *allText =
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_A),
this);
299 connect(copyText, SIGNAL(activated()),
this, SLOT(copy()));
300 connect(allText, SIGNAL(activated()),
this, SLOT(selectAll()));
311 static int getPos(
const QString &fileData,
int lineNumber)
315 for (
int pos = 0, line = 1; pos < fileData.size(); ++pos) {
316 if (fileData[pos] !=
'\n')
319 if (line >= lineNumber)
322 return fileData.size();
342 QTextCursor tc = textCursor();
355 QTextCursor tc = textCursor();
366 int max = qMax(1, blockCount());
372 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
373 const int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char(
'9')) * digits;
375 const int space = 3 + fontMetrics().width(QLatin1Char(
'9')) * digits;
392 if (rect.contains(viewport()->rect()))
398 QPlainTextEdit::resizeEvent(event);
399 QRect cr = contentsRect();
405 QList<QTextEdit::ExtraSelection> extraSelections;
407 QTextEdit::ExtraSelection selection;
410 selection.format.setProperty(QTextFormat::FullWidthSelection,
true);
411 selection.cursor = QTextCursor(document());
415 selection.cursor.setPosition(0);
417 selection.cursor.clearSelection();
418 extraSelections.append(selection);
420 setExtraSelections(extraSelections);
428 QTextBlock block = firstVisibleBlock();
429 int blockNumber = block.blockNumber();
430 int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
431 int bottom = top + (int) blockBoundingRect(block).height();
433 while (block.isValid() && top <=
event->rect().bottom()) {
434 if (block.isVisible() && bottom >=
event->rect().top()) {
435 QString number = QString::number(blockNumber + 1);
437 painter.drawText(0, top,
mLineNumberArea->width(), fontMetrics().height(),
438 Qt::AlignRight, number);
441 block = block.next();
443 bottom = top + (int) blockBoundingRect(block).height();
450 QString bgcolor = QString(
"background:rgb(%1,%2,%3);")
454 QString fgcolor = QString(
"color:rgb(%1,%2,%3);")
458 QString
style = QString(
"%1 %2")
static bool match(const Token *tok, const std::string &rhs)
QFont::Weight classWeight
QFont::Weight commentWeight
QFont::Weight quoteWeight
QFont::Weight symbolWeight
QFont::Weight keywordWeight
void updateLineNumberAreaWidth(int newBlockCount)
Highlighter * mHighlighter
void lineNumberAreaPaintEvent(const QPaintEvent *event)
void updateLineNumberArea(const QRect &, int)
QWidget * mLineNumberArea
void setStyle(const CodeEditorStyle &newStyle)
void resizeEvent(QResizeEvent *event) override
void highlightErrorLine()
CodeEditorStyle * mWidgetStyle
QString generateStyleString()
void setError(const QString &code, int errorLine, const QStringList &symbols)
Set source code to show, goto error line and highlight that line.
CodeEditor(QWidget *parent)
int lineNumberAreaWidth()
QRegularExpression mCommentStartExpression
QTextCharFormat mKeywordFormat
QTextCharFormat mSingleLineCommentFormat
QTextCharFormat mClassFormat
void applyFormat(HighlightingRule &rule)
Highlighter(QTextDocument *parent, CodeEditorStyle *widgetStyle)
QVector< HighlightingRule > mHighlightingRules
QRegularExpression mCommentEndExpression
void highlightBlock(const QString &text) override
QTextCharFormat mQuotationFormat
CodeEditorStyle * mWidgetStyle
void setStyle(const CodeEditorStyle &newStyle)
void setSymbols(const QStringList &symbols)
QTextCharFormat mMultiLineCommentFormat
QTextCharFormat mSymbolFormat
QVector< HighlightingRule > mHighlightingRulesWithSymbols
static int getPos(const QString &fileData, int lineNumber)
static const CodeEditorStyle defaultStyleLight(Qt::black, QColor(240, 240, 240), QColor(255, 220, 220), Qt::black, QColor(240, 240, 240), Qt::darkBlue, QFont::Bold, Qt::darkMagenta, QFont::Bold, Qt::darkGreen, QFont::Normal, Qt::gray, QFont::Normal, Qt::red, QColor(220, 220, 255), QFont::Normal)
QRegularExpression pattern