Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 96 additions & 22 deletions gui/codeeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,29 @@ Highlighter::Highlighter(QTextDocument *parent,
foreach (const QString &pattern, keywordPatterns) {
rule.pattern = QRegularExpression("\\b" + pattern + "\\b");
rule.format = mKeywordFormat;
rule.ruleRole = RuleRole::Keyword;
mHighlightingRules.append(rule);
}

mClassFormat.setForeground(mWidgetStyle->classColor);
mClassFormat.setFontWeight(mWidgetStyle->classWeight);
rule.pattern = QRegularExpression("\\bQ[A-Za-z]+\\b");
rule.format = mClassFormat;
rule.ruleRole = RuleRole::Class;
mHighlightingRules.append(rule);

mQuotationFormat.setForeground(mWidgetStyle->quoteColor);
mQuotationFormat.setFontWeight(mWidgetStyle->quoteWeight);
rule.pattern = QRegularExpression("\".*\"");
rule.format = mQuotationFormat;
rule.ruleRole = RuleRole::Quote;
mHighlightingRules.append(rule);

mSingleLineCommentFormat.setForeground(mWidgetStyle->commentColor);
mSingleLineCommentFormat.setFontWeight(mWidgetStyle->commentWeight);
rule.pattern = QRegularExpression("//[^\n]*");
rule.format = mSingleLineCommentFormat;
rule.ruleRole = RuleRole::Comment;
mHighlightingRules.append(rule);

mHighlightingRulesWithSymbols = mHighlightingRules;
Expand All @@ -97,10 +101,35 @@ void Highlighter::setSymbols(const QStringList &symbols)
HighlightingRule rule;
rule.pattern = QRegularExpression("\\b" + sym + "\\b");
rule.format = mSymbolFormat;
rule.ruleRole = RuleRole::Symbol;
mHighlightingRulesWithSymbols.append(rule);
}
}

void Highlighter::setStyle( const CodeEditorStyle &newStyle )
{
mKeywordFormat.setForeground( newStyle.keywordColor );
mKeywordFormat.setFontWeight( newStyle.keywordWeight );
mClassFormat.setForeground( newStyle.classColor );
mClassFormat.setFontWeight( newStyle.classWeight );
mSingleLineCommentFormat.setForeground( newStyle.commentColor );
mSingleLineCommentFormat.setFontWeight( newStyle.commentWeight );
mMultiLineCommentFormat.setForeground( newStyle.commentColor );
mMultiLineCommentFormat.setFontWeight( newStyle.commentWeight );
mQuotationFormat.setForeground( newStyle.quoteColor );
mQuotationFormat.setFontWeight( newStyle.quoteWeight );
mSymbolFormat.setForeground( newStyle.symbolFGColor );
mSymbolFormat.setBackground( newStyle.symbolBGColor );
mSymbolFormat.setFontWeight( newStyle.symbolWeight );
for( HighlightingRule& rule : mHighlightingRules ) {
applyFormat( rule );
}

for( HighlightingRule& rule : mHighlightingRulesWithSymbols ) {
applyFormat( rule );
}
}

void Highlighter::highlightBlock(const QString &text)
{
foreach (const HighlightingRule &rule, mHighlightingRulesWithSymbols) {
Expand Down Expand Up @@ -133,41 +162,56 @@ void Highlighter::highlightBlock(const QString &text)
}
}


CodeEditor::CodeEditor(QWidget *parent,
CodeEditorStyle *widgetStyle /*= nullptr*/) :
QPlainTextEdit(parent)
void Highlighter::applyFormat( HighlightingRule &rule )
{
if (widgetStyle) mWidgetStyle = widgetStyle;
else mWidgetStyle = new CodeEditorStyle(defaultStyle);
switch( rule.ruleRole )
{
case RuleRole::Keyword:
rule.format = mKeywordFormat;
break;
case RuleRole::Class:
rule.format = mClassFormat;
break;
case RuleRole::Comment:
rule.format = mSingleLineCommentFormat;
break;
case RuleRole::Quote:
rule.format = mQuotationFormat;
break;
case RuleRole::Symbol:
rule.format = mSymbolFormat;
break;
}
}

CodeEditor::CodeEditor(QWidget *parent) :
QPlainTextEdit(parent),
mWidgetStyle( new CodeEditorStyle( defaultStyleLight ))
{
mLineNumberArea = new LineNumberArea(this);
mHighlighter = new Highlighter(this->document(), mWidgetStyle);
mHighlighter = new Highlighter( document(), mWidgetStyle );
mErrorPosition = -1;

QFont font( "Monospace" );
font.setStyleHint( QFont::TypeWriter );
setFont( font );

// set widget coloring by overriding widget style sheet
QString bgcolor = QString("background:rgb(%1,%2,%3);")
.arg(mWidgetStyle->widgetBGColor.red())
.arg(mWidgetStyle->widgetBGColor.green())
.arg(mWidgetStyle->widgetBGColor.blue());
QString fgcolor = QString("color:rgb(%1,%2,%3);")
.arg(mWidgetStyle->widgetFGColor.red())
.arg(mWidgetStyle->widgetFGColor.green())
.arg(mWidgetStyle->widgetFGColor.blue());
QString style = QString("%1 %2")
.arg(bgcolor)
.arg(fgcolor);
setObjectName("CodeEditor");
setStyleSheet(style);

setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
setStyleSheet( generateStyleString() );

connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));

updateLineNumberAreaWidth(0);
}

CodeEditor::~CodeEditor()
{
// NOTE: not a Qt Object - delete manually
delete mWidgetStyle;
}

static int getPos(const QString &fileData, int lineNumber)
{
if (lineNumber <= 1)
Expand All @@ -182,6 +226,16 @@ static int getPos(const QString &fileData, int lineNumber)
return fileData.size();
}

void CodeEditor::setStyle(const CodeEditorStyle& newStyle)
{
*mWidgetStyle = newStyle;
// apply new styling
setStyleSheet( generateStyleString() );
mHighlighter->setStyle( newStyle );
mHighlighter->rehighlight();
highlightErrorLine();
}

void CodeEditor::setError(const QString &code, int errorLine, const QStringList &symbols)
{
mHighlighter->setSymbols(symbols);
Expand Down Expand Up @@ -242,7 +296,11 @@ void CodeEditor::highlightErrorLine()
selection.format.setBackground(mWidgetStyle->highlightBGColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = QTextCursor(document());
selection.cursor.setPosition(mErrorPosition);
if( mErrorPosition >= 0 ) {
selection.cursor.setPosition(mErrorPosition);
} else {
selection.cursor.setPosition(0);
}
selection.cursor.clearSelection();
extraSelections.append(selection);

Expand Down Expand Up @@ -273,3 +331,19 @@ void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
++blockNumber;
}
}

QString CodeEditor::generateStyleString()
{
QString bgcolor = QString("background:rgb(%1,%2,%3);")
.arg(mWidgetStyle->widgetBGColor.red())
.arg(mWidgetStyle->widgetBGColor.green())
.arg(mWidgetStyle->widgetBGColor.blue());
QString fgcolor = QString("color:rgb(%1,%2,%3);")
.arg(mWidgetStyle->widgetFGColor.red())
.arg(mWidgetStyle->widgetFGColor.green())
.arg(mWidgetStyle->widgetFGColor.blue());
QString style = QString("%1 %2")
.arg(bgcolor)
.arg(fgcolor);
return style;
}
21 changes: 19 additions & 2 deletions gui/codeeditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,27 @@ class Highlighter : public QSyntaxHighlighter {

void setSymbols(const QStringList &symbols);

void setStyle( const CodeEditorStyle &newStyle );

protected:
void highlightBlock(const QString &text) override;

private:
enum RuleRole {
Keyword = 1,
Class = 2,
Comment = 3,
Quote = 4,
Symbol = 5
};
struct HighlightingRule {
QRegularExpression pattern;
QTextCharFormat format;
RuleRole ruleRole;
};

void applyFormat( HighlightingRule &rule );

QVector<HighlightingRule> mHighlightingRules;
QVector<HighlightingRule> mHighlightingRulesWithSymbols;

Expand All @@ -52,13 +65,14 @@ class CodeEditor : public QPlainTextEdit {
Q_OBJECT

public:
explicit CodeEditor(QWidget *parent,
CodeEditorStyle *widgetStyle = nullptr);
explicit CodeEditor(QWidget *parent);
CodeEditor(const CodeEditor &) = delete;
CodeEditor &operator=(const CodeEditor &) = delete;
~CodeEditor();

void lineNumberAreaPaintEvent(QPaintEvent *event);
int lineNumberAreaWidth();
void setStyle(const CodeEditorStyle& newStyle);

/**
* Set source code to show, goto error line and highlight that line.
Expand All @@ -76,6 +90,9 @@ private slots:
void highlightErrorLine();
void updateLineNumberArea(const QRect &, int);

private:
QString generateStyleString();

private:
QWidget *mLineNumberArea;
Highlighter *mHighlighter;
Expand Down
Loading