135 lines
4.5 KiB
C++
135 lines
4.5 KiB
C++
|
|
#include "jsonhighlighter.h"
|
|||
|
|
#include <QDebug>
|
|||
|
|
|
|||
|
|
JsonHighlighter::JsonHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent), m_document(nullptr) {
|
|||
|
|
// 关键字的颜色规则
|
|||
|
|
addRule(QRegExp("\"[^\"]*\""), Qt::darkGreen); // 字符串
|
|||
|
|
addRule(QRegExp("\\b(true|false|null)\\b"), Qt::darkBlue); // 字面量
|
|||
|
|
addRule(QRegExp("[{}\\[\\]]"), Qt::darkMagenta); // 括号
|
|||
|
|
addRule(QRegExp(":"), Qt::darkRed); // 冒号
|
|||
|
|
// 初始化错误格式
|
|||
|
|
m_errorFormat.setUnderlineColor(Qt::red);
|
|||
|
|
m_errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
|
|||
|
|
m_errorFormat.setForeground(Qt::red); // 可选:文字颜色
|
|||
|
|
}
|
|||
|
|
void JsonHighlighter::addRule(const QRegExp &pattern, const QColor &color) {
|
|||
|
|
HighlightRule rule;
|
|||
|
|
rule.pattern = pattern;
|
|||
|
|
rule.format.setForeground(color);
|
|||
|
|
rule.format.setFontWeight(QFont::Bold);
|
|||
|
|
rules.append(rule);
|
|||
|
|
}
|
|||
|
|
void JsonHighlighter::highlightBlock(const QString &text) {
|
|||
|
|
for (const auto &rule : rules) {
|
|||
|
|
QRegExp expression(rule.pattern);
|
|||
|
|
int index = expression.indexIn(text);
|
|||
|
|
while (index >= 0) {
|
|||
|
|
int length = expression.matchedLength();
|
|||
|
|
setFormat(index, length, rule.format);
|
|||
|
|
index = expression.indexIn(text, index + length);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 步骤 2: 检测语法错误
|
|||
|
|
// detectJsonErrors(text);
|
|||
|
|
}
|
|||
|
|
// 检测错误并标记
|
|||
|
|
void JsonHighlighter::detectJsonErrors(const QString& text) {
|
|||
|
|
QStack<QChar> stack;
|
|||
|
|
int pos = 0;
|
|||
|
|
while (pos < text.length()) {
|
|||
|
|
QChar ch = text.at(pos);
|
|||
|
|
|
|||
|
|
if (ch == '\"') {
|
|||
|
|
if (stack.isEmpty() || stack.top() != '\"') {
|
|||
|
|
// 开始一个新的字符串
|
|||
|
|
stack.push('\"');
|
|||
|
|
} else {
|
|||
|
|
// 闭合字符串
|
|||
|
|
stack.pop();
|
|||
|
|
}
|
|||
|
|
pos++;
|
|||
|
|
} else if (ch == '\\') {
|
|||
|
|
// 跳过转义字符后的字符
|
|||
|
|
pos += 2;
|
|||
|
|
} else if (!stack.isEmpty() && stack.top() == '\"') {
|
|||
|
|
// 在字符串内部,忽略其他字符
|
|||
|
|
pos++;
|
|||
|
|
} else if (ch == '{' || ch == '[') {
|
|||
|
|
stack.push(ch);
|
|||
|
|
pos++;
|
|||
|
|
} else if (ch == '}' || ch == ']') {
|
|||
|
|
if (!stack.isEmpty()) {
|
|||
|
|
QChar top = stack.top();
|
|||
|
|
if ((top == '{' && ch == '}') || (top == '[' && ch == ']')) {
|
|||
|
|
stack.pop();
|
|||
|
|
} else {
|
|||
|
|
// 不匹配的括号,标记错误
|
|||
|
|
setFormat(pos, 1, m_errorFormat);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 没有对应的开始括号,标记错误
|
|||
|
|
setFormat(pos, 1, m_errorFormat);
|
|||
|
|
}
|
|||
|
|
pos++;
|
|||
|
|
} else {
|
|||
|
|
pos++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查未闭合的引号、括号和大括号
|
|||
|
|
while (!stack.isEmpty()) {
|
|||
|
|
QChar top = stack.top();
|
|||
|
|
if (top == '\"') {
|
|||
|
|
// 未闭合的字符串,标记错误
|
|||
|
|
int start = text.lastIndexOf('\"', pos - 1);
|
|||
|
|
if (start != -1) {
|
|||
|
|
setFormat(start, text.length() - start, m_errorFormat);
|
|||
|
|
}
|
|||
|
|
} else if (top == '{' || top == '[') {
|
|||
|
|
// 未闭合的括号或大括号,标记错误
|
|||
|
|
int start = text.lastIndexOf(top, pos - 1);
|
|||
|
|
if (start != -1) {
|
|||
|
|
setFormat(start, 1, m_errorFormat);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
stack.pop();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
QQuickTextDocument* JsonHighlighter::document() const {
|
|||
|
|
return m_document;
|
|||
|
|
}
|
|||
|
|
void JsonHighlighter::setDocument(QQuickTextDocument* doc) {
|
|||
|
|
if (m_document != doc) {
|
|||
|
|
m_document = doc;
|
|||
|
|
if (doc) {
|
|||
|
|
QSyntaxHighlighter::setDocument(doc->textDocument());
|
|||
|
|
} else {
|
|||
|
|
QSyntaxHighlighter::setDocument(nullptr);
|
|||
|
|
}
|
|||
|
|
emit documentChanged();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QString JsonProcessor::formatJson(const QString &rawJson) {
|
|||
|
|
QJsonDocument doc = QJsonDocument::fromJson(rawJson.toUtf8());
|
|||
|
|
if (doc.isNull()) return "";
|
|||
|
|
return QString::fromUtf8(doc.toJson(QJsonDocument::Indented));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QVariantMap JsonProcessor::validateJson(const QString &json) {
|
|||
|
|
QJsonParseError error;
|
|||
|
|
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8(), &error);
|
|||
|
|
QVariantMap result;
|
|||
|
|
|
|||
|
|
if (error.error != QJsonParseError::NoError) {
|
|||
|
|
result["hasError"] = true;
|
|||
|
|
result["errorOffset"] = error.offset; // 错误位置
|
|||
|
|
result["errorMessage"] = error.errorString(); // 错误描述
|
|||
|
|
} else {
|
|||
|
|
result["hasError"] = false;
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|