diff --git a/gui/chatblockmodel.cpp b/gui/chatblockmodel.cpp index e69c633..f71dd4a 100644 --- a/gui/chatblockmodel.cpp +++ b/gui/chatblockmodel.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include static KSyntaxHighlighting::Repository *s_repo = nullptr; @@ -368,6 +370,20 @@ QString ChatBlockModel::highlightedHtml(const QString &code, const QString &lang return html; } +QString ChatBlockModel::prettyJson(const QString &text) const +{ + // Try to parse and pretty-print JSON, then syntax highlight + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(text.toUtf8(), &err); + QString formatted; + if (err.error == QJsonParseError::NoError) { + formatted = QString::fromUtf8(doc.toJson(QJsonDocument::Indented)); + } else { + formatted = text; + } + return highlightedHtml(formatted, QStringLiteral("JSON")); +} + void ChatBlockModel::copyToClipboard(const QString &text) const { QGuiApplication::clipboard()->setText(text); diff --git a/gui/chatblockmodel.h b/gui/chatblockmodel.h index bea9821..5bbb823 100644 --- a/gui/chatblockmodel.h +++ b/gui/chatblockmodel.h @@ -60,6 +60,7 @@ public: void setRawText(const QString &text); Q_INVOKABLE QString highlightedHtml(const QString &code, const QString &language) const; + Q_INVOKABLE QString prettyJson(const QString &text) const; Q_INVOKABLE void copyToClipboard(const QString &text) const; Q_INVOKABLE bool loadEarlier(); // returns true if more blocks were loaded diff --git a/gui/main.qml b/gui/main.qml index 9e72f1a..690e628 100644 --- a/gui/main.qml +++ b/gui/main.qml @@ -622,27 +622,14 @@ ApplicationWindow { Text { id: callText Layout.fillWidth: true - text: block.blockContent - textFormat: Text.PlainText + text: visible ? chatModel.prettyJson(block.blockContent) : "" + textFormat: Text.RichText wrapMode: Text.Wrap font.family: "monospace" font.pixelSize: Qt.application.font.pixelSize * 0.85 opacity: 0.7 visible: false color: palette.text - - onVisibleChanged: { - if (visible && textFormat === Text.PlainText) { - try { - let obj = JSON.parse(block.blockContent) - let pretty = JSON.stringify(obj, null, 2) - text = chatModel.highlightedHtml(pretty, "json") - } catch(e) { - text = chatModel.highlightedHtml(block.blockContent, "json") - } - textFormat = Text.RichText - } - } } } } @@ -664,8 +651,17 @@ ApplicationWindow { Text { id: toolText Layout.fillWidth: true - text: block.blockContent - textFormat: Text.PlainText + text: { + if (!visible) return "" + let content = block.blockContent + let trimmed = content.trimStart() + if (trimmed.startsWith("{") || trimmed.startsWith("[")) + return chatModel.prettyJson(content) + if (trimmed.startsWith("---") || trimmed.startsWith("diff ")) + return chatModel.highlightedHtml(content, "diff") + return content.replace(/&/g, '&').replace(//g, '>').replace(/\n/g, '
') + } + textFormat: Text.RichText wrapMode: Text.Wrap font.family: "monospace" font.pixelSize: Qt.application.font.pixelSize * 0.85 @@ -674,30 +670,6 @@ ApplicationWindow { color: palette.text maximumLineCount: 80 elide: Text.ElideRight - - onVisibleChanged: { - if (visible && textFormat === Text.PlainText) { - let content = block.blockContent - let trimmed = content.trimStart() - let lang = "" - if (trimmed.startsWith("{") || trimmed.startsWith("[")) lang = "json" - else if (trimmed.startsWith("---") || trimmed.startsWith("diff ")) lang = "diff" - - if (lang === "json") { - try { - let obj = JSON.parse(content) - let pretty = JSON.stringify(obj, null, 2) - text = chatModel.highlightedHtml(pretty, "json") - } catch(e) { - text = chatModel.highlightedHtml(content, "json") - } - textFormat = Text.RichText - } else if (lang) { - text = chatModel.highlightedHtml(content, lang) - textFormat = Text.RichText - } - } - } } } }