fix call/tool pretty-print: use C++ prettyJson() with QJsonDocument
The onVisibleChanged approach failed because block.blockContent could not resolve through the Loader scope. Now using direct binding: - call blocks: text bound to chatModel.prettyJson(block.blockContent) - tool blocks: detect JSON/diff, format accordingly - prettyJson() uses QJsonDocument for proper indentation + KSyntaxHighlighting - Only evaluated when visible (lazy)
This commit is contained in:
parent
ee3a0a1e76
commit
c39e0f2723
|
|
@ -8,6 +8,8 @@
|
|||
#include <QTextDocument>
|
||||
#include <QGuiApplication>
|
||||
#include <QClipboard>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
#include <QPalette>
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
54
gui/main.qml
54
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(/>/g, '>').replace(/\n/g, '<br>')
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Reference in New Issue