diff --git a/Source/Core/DolphinQt/Config/GameConfigEdit.cpp b/Source/Core/DolphinQt/Config/GameConfigEdit.cpp index d114704f6a..8c93f84263 100644 --- a/Source/Core/DolphinQt/Config/GameConfigEdit.cpp +++ b/Source/Core/DolphinQt/Config/GameConfigEdit.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp b/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp index 4473fde5a9..13d74cc9b2 100644 --- a/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp +++ b/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp @@ -5,6 +5,10 @@ #include #include +#include +#include +#include +#include #include "DolphinQt/Settings.h" @@ -16,7 +20,7 @@ struct HighlightingRule GameConfigHighlighter::~GameConfigHighlighter() = default; -GameConfigHighlighter::GameConfigHighlighter(QTextDocument* parent) : QSyntaxHighlighter(parent) +GameConfigHighlighter::GameConfigHighlighter(QTextDocument* parent) : QObject(parent) { const bool is_dark_theme = Settings::Instance().IsThemeDark(); @@ -65,17 +69,42 @@ GameConfigHighlighter::GameConfigHighlighter(QTextDocument* parent) : QSyntaxHig HighlightingRule{QRegularExpression(QStringLiteral("^\\$.*")), comment_format}); m_rules.emplace_back( HighlightingRule{QRegularExpression(QStringLiteral("^\\*.*")), comment_format}); + + // Highlight block on change. + // We're manually highlighting blocks because QSyntaxHighlighter + // hangs with large (>2MB) files for some reason. + connect(parent, &QTextDocument::contentsChange, this, + [this, parent](const int pos, int /* removed */, const int added) { + QTextBlock block = parent->findBlock(pos); + const auto pos_end = pos + added; + while (block.isValid() && block.position() <= pos_end) + { + HighlightBlock(block); + block = block.next(); + } + }); + + // Highlight all blocks right now. + for (QTextBlock block = parent->begin(); block.isValid(); block = block.next()) + HighlightBlock(block); } -void GameConfigHighlighter::highlightBlock(const QString& text) +void GameConfigHighlighter::HighlightBlock(const QTextBlock& block) { + QList format_ranges; + for (const auto& rule : m_rules) { - auto it = rule.pattern.globalMatch(text); + auto it = rule.pattern.globalMatch(block.text()); while (it.hasNext()) { - auto match = it.next(); - setFormat(match.capturedStart(), match.capturedLength(), rule.format); + const auto match = it.next(); + format_ranges.emplace_back(QTextLayout::FormatRange{.start = int(match.capturedStart()), + .length = int(match.capturedLength()), + .format = rule.format}); } } + + block.layout()->clearFormats(); + block.layout()->setFormats(format_ranges); } diff --git a/Source/Core/DolphinQt/Config/GameConfigHighlighter.h b/Source/Core/DolphinQt/Config/GameConfigHighlighter.h index b01febed42..b2c26f48cb 100644 --- a/Source/Core/DolphinQt/Config/GameConfigHighlighter.h +++ b/Source/Core/DolphinQt/Config/GameConfigHighlighter.h @@ -5,23 +5,23 @@ #include -#include -#include -#include +#include struct HighlightingRule; -class GameConfigHighlighter : public QSyntaxHighlighter +class QTextBlock; +class QTextDocument; + +class GameConfigHighlighter : public QObject { Q_OBJECT public: - explicit GameConfigHighlighter(QTextDocument* parent = nullptr); + explicit GameConfigHighlighter(QTextDocument* parent); ~GameConfigHighlighter() override; -protected: - void highlightBlock(const QString& text) override; - private: + void HighlightBlock(const QTextBlock& block); + std::vector m_rules; };