mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
* Trophy: Save dialog state and add show type settings * SaveDataManager: Save Dialog State * SaveDataList: Minor Optimization * Qt: Save icon size on mouseevent resizes it's a bit slower than using the slider because it saves every single resize. But better than not saving at all for now * SaveData: Optimize saving to settings a bit No Saving needed there * Qt: get rid of all-uppercase enums and namespaces * Qt/Linux: adjust remaining DX12 tooltip * Qt: prevent dockwidget contextmenu
184 lines
5.2 KiB
C++
184 lines
5.2 KiB
C++
#include "syntax_highlighter.h"
|
|
|
|
syntax_highlighter::syntax_highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
|
{
|
|
}
|
|
|
|
void syntax_highlighter::AddSimpleRule(SimpleRule rule)
|
|
{
|
|
rule.expressions.erase(std::remove_if(rule.expressions.begin(), rule.expressions.end(), [&](const auto &e){
|
|
return IsInvalidExpression(e) || e.captureCount() > 1;
|
|
}), rule.expressions.end());
|
|
|
|
if (rule.expressions.isEmpty())
|
|
{
|
|
return;
|
|
}
|
|
m_rules.append(rule);
|
|
}
|
|
|
|
void syntax_highlighter::AddSimpleRule(const QStringList& expressions, const QColor& color)
|
|
{
|
|
QTextCharFormat format;
|
|
format.setForeground(color);
|
|
QVector<QRegularExpression> regexs;
|
|
for (const auto& expr : expressions)
|
|
{
|
|
regexs.append(QRegularExpression(expr));
|
|
}
|
|
AddSimpleRule(SimpleRule(regexs, format));
|
|
}
|
|
|
|
void syntax_highlighter::AddWordRule(const QStringList& words, const QColor& color)
|
|
{
|
|
QTextCharFormat format;
|
|
format.setForeground(color);
|
|
QVector<QRegularExpression> regexs;
|
|
for (const auto& word : words)
|
|
{
|
|
regexs.append(QRegularExpression("\\b" + word + "\\b"));
|
|
}
|
|
AddSimpleRule(SimpleRule(regexs, format));
|
|
}
|
|
|
|
void syntax_highlighter::AddMultiRule(const MultiRule& rule)
|
|
{
|
|
if (IsInvalidExpression(rule.expression) || rule.formats.length() <= rule.expression.captureCount())
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_multi_rules.append(rule);
|
|
}
|
|
void syntax_highlighter::AddMultiRule(const QString& expression, const QVector<QColor>& colors)
|
|
{
|
|
QVector<QTextCharFormat> formats;
|
|
for (const auto& color : colors)
|
|
{
|
|
QTextCharFormat format;
|
|
format.setForeground(color);
|
|
formats.append(format);
|
|
}
|
|
AddMultiRule(MultiRule(QRegularExpression(expression), formats));
|
|
}
|
|
|
|
void syntax_highlighter::AddCommentRule(const CommentRule& rule)
|
|
{
|
|
if (IsInvalidExpression(rule.start_expression) || (rule.multi_line && IsInvalidExpression(rule.end_expression)))
|
|
{
|
|
return;
|
|
}
|
|
m_comment_rules.append(rule);
|
|
}
|
|
|
|
void syntax_highlighter::AddCommentRule(const QString& start, const QColor& color, bool multi_line, const QString& end)
|
|
{
|
|
QTextCharFormat format;
|
|
format.setForeground(color);
|
|
AddCommentRule(CommentRule(QRegularExpression(start), QRegularExpression(end), format, multi_line));
|
|
}
|
|
|
|
void syntax_highlighter::highlightBlock(const QString &text)
|
|
{
|
|
m_current_block = text;
|
|
|
|
for (const auto& rule : m_multi_rules)
|
|
{
|
|
// Search for all the matching strings
|
|
QRegularExpressionMatchIterator iter = rule.expression.globalMatch(m_current_block);
|
|
|
|
// Iterate through the matching strings
|
|
while (iter.hasNext())
|
|
{
|
|
// Apply formats to their respective found groups
|
|
QRegularExpressionMatch match = iter.next();
|
|
|
|
for (int i = 0; i <= match.lastCapturedIndex(); i++)
|
|
{
|
|
setFormat(match.capturedStart(i), match.capturedLength(i), rule.formats[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const auto& rule : m_rules)
|
|
{
|
|
for (const auto& expression : rule.expressions)
|
|
{
|
|
// Search for all the matching strings
|
|
QRegularExpressionMatchIterator iter = expression.globalMatch(m_current_block);
|
|
bool contains_group = expression.captureCount() > 0;
|
|
|
|
// Iterate through the matching strings
|
|
while (iter.hasNext())
|
|
{
|
|
// Apply format to the matching string
|
|
QRegularExpressionMatch match = iter.next();
|
|
if (contains_group)
|
|
{
|
|
setFormat(match.capturedStart(1), match.capturedLength(1), rule.format);
|
|
}
|
|
else
|
|
{
|
|
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const auto& rule : m_comment_rules)
|
|
{
|
|
int comment_start = 0; // Current comment's start position in the text block
|
|
int comment_end = 0; // Current comment's end position in the text block
|
|
int comment_length = 0; // Current comment length
|
|
|
|
// We assume we end outside a comment until we know better
|
|
setCurrentBlockState(block_state::ended_outside_comment);
|
|
|
|
// Search for the first comment in this block if we start outside or don't want to search for multiline comments
|
|
if (!rule.multi_line || previousBlockState() != block_state::ended_inside_comment)
|
|
{
|
|
comment_start = m_current_block.indexOf(rule.start_expression);
|
|
}
|
|
|
|
// Set format for the rest of this block/line
|
|
if (!rule.multi_line)
|
|
{
|
|
comment_length = m_current_block.length() - comment_start;
|
|
setFormat(comment_start, comment_length, rule.format);
|
|
break;
|
|
}
|
|
|
|
// Format all comments in this block (if they exist)
|
|
while (comment_start >= 0)
|
|
{
|
|
// Search for end of comment in the remaining text
|
|
QRegularExpressionMatch match = rule.end_expression.match(m_current_block, comment_start);
|
|
comment_end = match.capturedStart();
|
|
match.captured(1);
|
|
|
|
if (comment_end == -1)
|
|
{
|
|
// We end inside a comment and want to format the entire remaining text
|
|
setCurrentBlockState(block_state::ended_inside_comment);
|
|
comment_length = m_current_block.length() - comment_start;
|
|
}
|
|
else
|
|
{
|
|
// We found the end of the comment so we need to go another round
|
|
comment_length = comment_end - comment_start + match.capturedLength();
|
|
}
|
|
|
|
// Set format for this text segment
|
|
setFormat(comment_start, comment_length, rule.format);
|
|
|
|
// Search for the next comment
|
|
comment_start = m_current_block.indexOf(rule.start_expression, comment_start + comment_length);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool syntax_highlighter::IsInvalidExpression(const QRegularExpression& expression)
|
|
{
|
|
return !expression.isValid() || expression.pattern().isEmpty();
|
|
}
|