mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2024-10-01 01:06:10 -04:00
qml: fix hang in ChatView by processing text explicitly (#2543)
Fixes #2519 Signed-off-by: Adam Treat <treat.adam@gmail.com> Signed-off-by: Jared Van Bortel <jared@nomic.ai> Co-authored-by: Jared Van Bortel <jared@nomic.ai>
This commit is contained in:
parent
64359e68e6
commit
c11e0f4a98
@ -188,11 +188,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Q_INVOKABLE void forceUpdate(int index)
|
||||
{
|
||||
emit dataChanged(createIndex(index, 0), createIndex(index, 0), {ValueRole});
|
||||
}
|
||||
|
||||
Q_INVOKABLE void updateValue(int index, const QString &value)
|
||||
{
|
||||
if (index < 0 || index >= m_chatItems.size()) return;
|
||||
@ -201,6 +196,7 @@ public:
|
||||
if (item.value != value) {
|
||||
item.value = value;
|
||||
emit dataChanged(createIndex(index, 0), createIndex(index, 0), {ValueRole});
|
||||
emit valueChanged(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,6 +464,7 @@ public:
|
||||
|
||||
Q_SIGNALS:
|
||||
void countChanged();
|
||||
void valueChanged(int index, const QString &value);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -771,9 +771,8 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
|
||||
// chat class to populate the clipboard.
|
||||
ChatViewTextProcessor::ChatViewTextProcessor(QObject *parent)
|
||||
: QObject{parent}
|
||||
, m_textDocument(nullptr)
|
||||
, m_quickTextDocument(nullptr)
|
||||
, m_syntaxHighlighter(new SyntaxHighlighter(this))
|
||||
, m_isProcessingText(false)
|
||||
, m_shouldProcessText(true)
|
||||
, m_fontPixelSize(QGuiApplication::font().pointSizeF())
|
||||
{
|
||||
@ -781,17 +780,19 @@ ChatViewTextProcessor::ChatViewTextProcessor(QObject *parent)
|
||||
|
||||
QQuickTextDocument* ChatViewTextProcessor::textDocument() const
|
||||
{
|
||||
return m_textDocument;
|
||||
return m_quickTextDocument;
|
||||
}
|
||||
|
||||
void ChatViewTextProcessor::setTextDocument(QQuickTextDocument* textDocument)
|
||||
void ChatViewTextProcessor::setTextDocument(QQuickTextDocument* quickTextDocument)
|
||||
{
|
||||
if (m_textDocument)
|
||||
disconnect(m_textDocument->textDocument(), &QTextDocument::contentsChanged, this, &ChatViewTextProcessor::handleTextChanged);
|
||||
m_quickTextDocument = quickTextDocument;
|
||||
m_syntaxHighlighter->setDocument(m_quickTextDocument->textDocument());
|
||||
handleTextChanged();
|
||||
}
|
||||
|
||||
m_textDocument = textDocument;
|
||||
m_syntaxHighlighter->setDocument(m_textDocument->textDocument());
|
||||
connect(m_textDocument->textDocument(), &QTextDocument::contentsChanged, this, &ChatViewTextProcessor::handleTextChanged);
|
||||
void ChatViewTextProcessor::setValue(const QString &value)
|
||||
{
|
||||
m_quickTextDocument->textDocument()->setPlainText(value);
|
||||
handleTextChanged();
|
||||
}
|
||||
|
||||
@ -881,14 +882,12 @@ void traverseDocument(QTextDocument *doc, QTextFrame *frame)
|
||||
|
||||
void ChatViewTextProcessor::handleTextChanged()
|
||||
{
|
||||
if (!m_textDocument || m_isProcessingText || !m_shouldProcessText)
|
||||
if (!m_quickTextDocument || !m_shouldProcessText)
|
||||
return;
|
||||
|
||||
m_isProcessingText = true;
|
||||
|
||||
// Force full layout of the text document to work around a bug in Qt
|
||||
// TODO(jared): report the Qt bug and link to the report here
|
||||
QTextDocument* doc = m_textDocument->textDocument();
|
||||
QTextDocument* doc = m_quickTextDocument->textDocument();
|
||||
(void)doc->documentLayout()->documentSize();
|
||||
|
||||
handleCodeBlocks();
|
||||
@ -899,12 +898,11 @@ void ChatViewTextProcessor::handleTextChanged()
|
||||
QTextCursor cursor(doc);
|
||||
QString invisibleCharacter = QString(QChar(0xFEFF));
|
||||
cursor.insertText(invisibleCharacter, QTextCharFormat());
|
||||
m_isProcessingText = false;
|
||||
}
|
||||
|
||||
void ChatViewTextProcessor::handleCodeBlocks()
|
||||
{
|
||||
QTextDocument* doc = m_textDocument->textDocument();
|
||||
QTextDocument* doc = m_quickTextDocument->textDocument();
|
||||
QTextCursor cursor(doc);
|
||||
|
||||
QTextCharFormat textFormat;
|
||||
@ -1081,7 +1079,7 @@ void replaceAndInsertMarkdown(int startIndex, int endIndex, QTextDocument *doc)
|
||||
|
||||
void ChatViewTextProcessor::handleMarkdown()
|
||||
{
|
||||
QTextDocument* doc = m_textDocument->textDocument();
|
||||
QTextDocument* doc = m_quickTextDocument->textDocument();
|
||||
QTextCursor cursor(doc);
|
||||
|
||||
QVector<QPair<int, int>> codeBlockPositions;
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
QQuickTextDocument* textDocument() const;
|
||||
void setTextDocument(QQuickTextDocument* textDocument);
|
||||
|
||||
Q_INVOKABLE void setValue(const QString &value);
|
||||
Q_INVOKABLE bool tryCopyAtPosition(int position) const;
|
||||
|
||||
bool shouldProcessText() const;
|
||||
@ -119,12 +120,11 @@ private Q_SLOTS:
|
||||
void handleMarkdown();
|
||||
|
||||
private:
|
||||
QQuickTextDocument *m_textDocument;
|
||||
QQuickTextDocument *m_quickTextDocument;
|
||||
SyntaxHighlighter *m_syntaxHighlighter;
|
||||
QVector<ContextLink> m_links;
|
||||
QVector<CodeCopy> m_copies;
|
||||
bool m_shouldProcessText = false;
|
||||
bool m_isProcessingText = false;
|
||||
qreal m_fontPixelSize;
|
||||
};
|
||||
|
||||
|
@ -879,7 +879,6 @@ Rectangle {
|
||||
Layout.fillWidth: true
|
||||
TextArea {
|
||||
id: myTextArea
|
||||
text: value
|
||||
Layout.fillWidth: true
|
||||
padding: 0
|
||||
color: {
|
||||
@ -953,7 +952,7 @@ Rectangle {
|
||||
height: enabled ? implicitHeight : 0
|
||||
onTriggered: {
|
||||
textProcessor.shouldProcessText = !textProcessor.shouldProcessText;
|
||||
myTextArea.text = value
|
||||
textProcessor.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -974,11 +973,16 @@ Rectangle {
|
||||
textProcessor.codeColors.headerColor = theme.codeHeaderColor
|
||||
textProcessor.codeColors.backgroundColor = theme.codeBackgroundColor
|
||||
textProcessor.textDocument = textDocument
|
||||
chatModel.forceUpdate(index); // called to trigger a reprocessing of the text
|
||||
textProcessor.setValue(value);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
resetChatViewTextProcessor();
|
||||
chatModel.valueChanged.connect(function(i, value) {
|
||||
if (index === i)
|
||||
textProcessor.setValue(value);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
@ -272,7 +272,7 @@ Rectangle {
|
||||
color: theme.conversationBackground
|
||||
width: subscribeLink.width
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
MyFancyLink {
|
||||
id: subscribeLink
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
Loading…
Reference in New Issue
Block a user