|
| 1 | +#include "QQueryHighlighter.h" |
| 2 | + |
| 3 | +QQueryHighlighter::QQueryHighlighter(QTextDocument* parent) : QSyntaxHighlighter(parent) { |
| 4 | + HighlightingRule rule; |
| 5 | + |
| 6 | + m_keywordFormat.setForeground(Qt::darkMagenta); |
| 7 | + m_keywordFormat.setFontWeight(QFont::Bold); |
| 8 | + const QString keywordPatterns[] = { |
| 9 | + QStringLiteral("\\b(?i)ADD(?-i)\\b"), |
| 10 | + QStringLiteral("\\b(?i)ADD CONSTRAINT(?-i)\\b"), |
| 11 | + QStringLiteral("\\b(?i)ALL(?-i)\\b"), |
| 12 | + QStringLiteral("\\b(?i)ALTER(?-i)\\b"), |
| 13 | + QStringLiteral("\\b(?i)ALTER COLUMN(?-i)\\b"), |
| 14 | + QStringLiteral("\\b(?i)ALTER TABLE(?-i)\\b"), |
| 15 | + QStringLiteral("\\b(?i)AND(?-i)\\b"), |
| 16 | + QStringLiteral("\\b(?i)ANY(?-i)\\b"), |
| 17 | + QStringLiteral("\\b(?i)AS(?-i)\\b"), |
| 18 | + QStringLiteral("\\b(?i)ASC(?-i)\\b"), |
| 19 | + QStringLiteral("\\b(?i)AVG(?-i)\\b"), |
| 20 | + QStringLiteral("\\b(?i)BACKUP DATABASE(?-i)\\b"), |
| 21 | + QStringLiteral("\\b(?i)BETWEEN(?-i)\\b"), |
| 22 | + QStringLiteral("\\b(?i)CASE(?-i)\\b"), |
| 23 | + QStringLiteral("\\b(?i)CHECK(?-i)\\b"), |
| 24 | + QStringLiteral("\\b(?i)COLUMN(?-i)\\b"), |
| 25 | + QStringLiteral("\\b(?i)CONSTRAINT(?-i)\\b"), |
| 26 | + QStringLiteral("\\b(?i)COUNT(?-i)\\b"), |
| 27 | + QStringLiteral("\\b(?i)CREATE(?-i)\\b"), |
| 28 | + QStringLiteral("\\b(?i)CREATE DATABASE(?-i)\\b"), |
| 29 | + QStringLiteral("\\b(?i)CREATE INDEX(?-i)\\b"), |
| 30 | + QStringLiteral("\\b(?i)CREATE OR REPLACE VIEW(?-i)\\b"), |
| 31 | + QStringLiteral("\\b(?i)CREATE TABLE(?-i)\\b"), |
| 32 | + QStringLiteral("\\b(?i)CREATE PROCEDURE(?-i)\\b"), |
| 33 | + QStringLiteral("\\b(?i)CREATE UNIQUE INDEX(?-i)\\b"), |
| 34 | + QStringLiteral("\\b(?i)CREATE VIEW(?-i)\\b"), |
| 35 | + QStringLiteral("\\b(?i)DATABASE(?-i)\\b"), |
| 36 | + QStringLiteral("\\b(?i)DEFAULT(?-i)\\b"), |
| 37 | + QStringLiteral("\\b(?i)DELETE(?-i)\\b"), |
| 38 | + QStringLiteral("\\b(?i)DESC(?-i)\\b"), |
| 39 | + QStringLiteral("\\b(?i)DISTINCT(?-i)\\b"), |
| 40 | + QStringLiteral("\\b(?i)DROP(?-i)\\b"), |
| 41 | + QStringLiteral("\\b(?i)DROP COLUMN(?-i)\\b"), |
| 42 | + QStringLiteral("\\b(?i)DROP CONSTRAINT(?-i)\\b"), |
| 43 | + QStringLiteral("\\b(?i)DROP DATABASE(?-i)\\b"), |
| 44 | + QStringLiteral("\\b(?i)DROP DEFAULT(?-i)\\b"), |
| 45 | + QStringLiteral("\\b(?i)DROP INDEX(?-i)\\b"), |
| 46 | + QStringLiteral("\\b(?i)DROP TABLE(?-i)\\b"), |
| 47 | + QStringLiteral("\\b(?i)DROP VIEW(?-i)\\b"), |
| 48 | + QStringLiteral("\\b(?i)EXEC(?-i)\\b"), |
| 49 | + QStringLiteral("\\b(?i)EXISTS(?-i)\\b"), |
| 50 | + QStringLiteral("\\b(?i)FOREIGN KEY(?-i)\\b"), |
| 51 | + QStringLiteral("\\b(?i)FROM(?-i)\\b"), |
| 52 | + QStringLiteral("\\b(?i)FULL OUTER JOIN(?-i)\\b"), |
| 53 | + QStringLiteral("\\b(?i)GROUP BY(?-i)\\b"), |
| 54 | + QStringLiteral("\\b(?i)HAVING(?-i)\\b"), |
| 55 | + QStringLiteral("\\b(?i)IN(?-i)\\b"), |
| 56 | + QStringLiteral("\\b(?i)INDEX(?-i)\\b"), |
| 57 | + QStringLiteral("\\b(?i)INNER JOIN(?-i)\\b"), |
| 58 | + QStringLiteral("\\b(?i)INSERT INTO(?-i)\\b"), |
| 59 | + QStringLiteral("\\b(?i)INSERT INTO SELECT(?-i)\\b"), |
| 60 | + QStringLiteral("\\b(?i)IS NULL(?-i)\\b"), |
| 61 | + QStringLiteral("\\b(?i)IS NOT NULL(?-i)\\b"), |
| 62 | + QStringLiteral("\\b(?i)JOIN(?-i)\\b"), |
| 63 | + QStringLiteral("\\b(?i)LEFT JOIN(?-i)\\b"), |
| 64 | + QStringLiteral("\\b(?i)LIKE(?-i)\\b"), |
| 65 | + QStringLiteral("\\b(?i)MAX(?-i)\\b"), |
| 66 | + QStringLiteral("\\b(?i)MIN(?-i)\\b"), |
| 67 | + QStringLiteral("\\b(?i)NOT(?-i)\\b"), |
| 68 | + QStringLiteral("\\b(?i)NOT NULL(?-i)\\b"), |
| 69 | + QStringLiteral("\\b(?i)OR(?-i)\\b"), |
| 70 | + QStringLiteral("\\b(?i)ORDER BY(?-i)\\b"), |
| 71 | + QStringLiteral("\\b(?i)OUTER JOIN(?-i)\\b"), |
| 72 | + QStringLiteral("\\b(?i)PRIMARY KEY(?-i)\\b"), |
| 73 | + QStringLiteral("\\b(?i)PROCEDURE(?-i)\\b"), |
| 74 | + QStringLiteral("\\b(?i)RIGHT JOIN(?-i)\\b"), |
| 75 | + QStringLiteral("\\b(?i)ROWNUM(?-i)\\b"), |
| 76 | + QStringLiteral("\\b(?i)SELECT(?-i)\\b"), |
| 77 | + QStringLiteral("\\b(?i)SELECT DISTINCT(?-i)\\b"), |
| 78 | + QStringLiteral("\\b(?i)SELECT INTO(?-i)\\b"), |
| 79 | + QStringLiteral("\\b(?i)SELECT TOP(?-i)\\b"), |
| 80 | + QStringLiteral("\\b(?i)SET(?-i)\\b"), |
| 81 | + QStringLiteral("\\b(?i)SUM(?-i)\\b"), |
| 82 | + QStringLiteral("\\b(?i)TABLE(?-i)\\b"), |
| 83 | + QStringLiteral("\\b(?i)TOP(?-i)\\b"), |
| 84 | + QStringLiteral("\\b(?i)TRUNCATE TABLE(?-i)\\b"), |
| 85 | + QStringLiteral("\\b(?i)UNION(?-i)\\b"), |
| 86 | + QStringLiteral("\\b(?i)UNION ALL(?-i)\\b"), |
| 87 | + QStringLiteral("\\b(?i)UNIQUE(?-i)\\b"), |
| 88 | + QStringLiteral("\\b(?i)UPDATE(?-i)\\b"), |
| 89 | + QStringLiteral("\\b(?i)VALUES(?-i)\\b"), |
| 90 | + QStringLiteral("\\b(?i)VIEW(?-i)\\b"), |
| 91 | + QStringLiteral("\\b(?i)WHERE(?-i)\\b") |
| 92 | + }; |
| 93 | + |
| 94 | + for (auto pattern : keywordPatterns) { |
| 95 | + rule.pattern = QRegularExpression(pattern); |
| 96 | + rule.format = m_keywordFormat; |
| 97 | + m_highlightingRules.append(rule); |
| 98 | + } |
| 99 | + |
| 100 | + |
| 101 | + m_singleLineCommentFormat.setForeground(QColor(255, 0, 0, 127)); |
| 102 | + rule.pattern = QRegularExpression(QStringLiteral("--[^\n]*")); |
| 103 | + rule.format = m_singleLineCommentFormat; |
| 104 | + m_highlightingRules.append(rule); |
| 105 | + |
| 106 | + m_sLiteralFormat.setForeground(Qt::gray); |
| 107 | + m_sLiteralFormat.setFontWeight(QFont::Bold); |
| 108 | + m_sLiteralDelimiterExpression = QRegularExpression(QStringLiteral("'")); |
| 109 | + |
| 110 | + m_dLiteralFormat.setForeground(Qt::darkRed); |
| 111 | + m_dLiteralFormat.setFontWeight(QFont::Bold); |
| 112 | + rule.pattern = QRegularExpression(QStringLiteral("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)")); |
| 113 | + rule.format = m_dLiteralFormat; |
| 114 | + m_highlightingRules.append(rule); |
| 115 | + |
| 116 | + m_multiLineCommentFormat.setForeground(QColor(255, 0, 0, 127)); |
| 117 | + m_commentStartExpression = QRegularExpression(QStringLiteral("/\\*")); |
| 118 | + m_commentEndExpression = QRegularExpression(QStringLiteral("\\*/")); |
| 119 | +} |
| 120 | + |
| 121 | +void QQueryHighlighter::highlightBlock(const QString& text) { |
| 122 | + for (const HighlightingRule& rule : std::as_const(m_highlightingRules)) { |
| 123 | + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); |
| 124 | + while (matchIterator.hasNext()) { |
| 125 | + QRegularExpressionMatch match = matchIterator.next(); |
| 126 | + setFormat(match.capturedStart(), match.capturedLength(), rule.format); |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | + setCurrentBlockState(0); |
| 131 | + qsizetype startIndex = -1; |
| 132 | + qsizetype commentIndex = previousBlockState() != 1 ? text.indexOf(m_commentStartExpression) : 0; |
| 133 | + qsizetype literalIndex = previousBlockState() != 2 ? text.indexOf(m_sLiteralDelimiterExpression) : 0; |
| 134 | + if (commentIndex >= 0 && literalIndex >= 0) |
| 135 | + startIndex = std::min(commentIndex, literalIndex); |
| 136 | + else if (commentIndex >= 0) |
| 137 | + startIndex = commentIndex; |
| 138 | + else if (literalIndex >= 0) |
| 139 | + startIndex = literalIndex; |
| 140 | + |
| 141 | + while (startIndex >= 0) { |
| 142 | + qsizetype blockLength = 0; |
| 143 | + int blockState; |
| 144 | + QTextCharFormat fmt; |
| 145 | + if (startIndex == commentIndex) { |
| 146 | + blockState = 1; |
| 147 | + fmt = m_multiLineCommentFormat; |
| 148 | + } |
| 149 | + else { |
| 150 | + blockState = 2; |
| 151 | + fmt = m_sLiteralFormat; |
| 152 | + } |
| 153 | + |
| 154 | + QRegularExpressionMatch match = startIndex == literalIndex ? m_sLiteralDelimiterExpression.match(text, startIndex + 1) : m_commentEndExpression.match(text, startIndex + 2) ; |
| 155 | + qsizetype endIndex = match.capturedStart(); |
| 156 | + if (endIndex == -1) { |
| 157 | + setCurrentBlockState(blockState); |
| 158 | + blockLength = text.length() - startIndex; |
| 159 | + } |
| 160 | + else blockLength = endIndex - startIndex + match.capturedLength(); |
| 161 | + |
| 162 | + setFormat(startIndex, blockLength, fmt); |
| 163 | + |
| 164 | + commentIndex = text.indexOf(m_commentStartExpression, startIndex + blockLength); |
| 165 | + literalIndex = text.indexOf(m_sLiteralDelimiterExpression, startIndex + blockLength); |
| 166 | + startIndex = -1; |
| 167 | + if (commentIndex >= 0 && literalIndex >= 0) |
| 168 | + startIndex = std::min(commentIndex, literalIndex); |
| 169 | + else if (commentIndex >= 0) |
| 170 | + startIndex = commentIndex; |
| 171 | + else if (literalIndex >= 0) |
| 172 | + startIndex = literalIndex; |
| 173 | + } |
| 174 | +} |
0 commit comments