From 938ee55d42445d57fcdb501af43bb190be27f4b9 Mon Sep 17 00:00:00 2001 From: Adam Higerd Date: Tue, 19 Nov 2024 10:41:34 -0600 Subject: [PATCH] Qt: honor control characters in ScriptingTextBuffer::print --- .../qt/scripting/ScriptingTextBuffer.cpp | 76 +++++++++++++++---- .../qt/scripting/ScriptingTextBuffer.h | 7 ++ 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/platform/qt/scripting/ScriptingTextBuffer.cpp b/src/platform/qt/scripting/ScriptingTextBuffer.cpp index da05bd2b9..c209adcd5 100644 --- a/src/platform/qt/scripting/ScriptingTextBuffer.cpp +++ b/src/platform/qt/scripting/ScriptingTextBuffer.cpp @@ -49,26 +49,70 @@ void ScriptingTextBuffer::setBufferName(const QString& name) { emit bufferNameChanged(name); } +void ScriptingTextBuffer::lineBreak() { + bool nextBlockExists = m_shim.cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, 1); + if (!nextBlockExists) { + m_shim.cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor, 1); + m_shim.cursor.insertBlock(); + } +} + +void ScriptingTextBuffer::carriageReturn() { + m_shim.cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor, 1); +} + +void ScriptingTextBuffer::tab() { + QTextCursor& cursor = m_shim.cursor; + int column = cursor.positionInBlock(); + int move = tabStop - (column % tabStop) + 1; + if (column + move >= m_dims.width()) { + lineBreak(); + } else if (column + move <= cursor.block().length()) { + cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, move - 1); + } else { + move = column + move - cursor.block().length(); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::MoveAnchor, 1); + cursor.insertText(QString(move, ' ')); + } +} + +void ScriptingTextBuffer::insertString(const QString& text) { + QTextCursor& cursor = m_shim.cursor; + if (cursor.positionInBlock() >= m_dims.width()) { + lineBreak(); + } + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, text.length()); + cursor.insertText(text); +} + void ScriptingTextBuffer::print(const QString& text) { QMutexLocker locker(&m_mutex); - for (QString split : text.split('\n')) { - while (m_shim.cursor.positionInBlock() + split.length() > m_dims.width()) { - int cut = m_dims.width() - m_shim.cursor.positionInBlock(); - if (!m_shim.cursor.atBlockEnd()) { - m_shim.cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - } - m_shim.cursor.insertText(split.left(cut)); - if (m_shim.cursor.atEnd()) { - m_shim.cursor.insertBlock(); - } else { - m_shim.cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, 1); - } - split = split.mid(cut); + + QTextCursor& cursor = m_shim.cursor; + QString toInsert; + + for (const QChar& ch : text) { + int column = cursor.positionInBlock(); + if (ch == '\t' || ch == '\n' || ch == '\r' || column + toInsert.length() >= m_dims.width()) { + insertString(toInsert); + toInsert.clear(); } - if (!m_shim.cursor.atBlockEnd()) { - m_shim.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, split.length()); + switch (ch.unicode()) { + case '\t': + tab(); + break; + case '\n': + lineBreak(); + break; + case '\r': + carriageReturn(); + break; + default: + toInsert += ch; } - m_shim.cursor.insertText(split); + } + if (!toInsert.isEmpty()) { + insertString(toInsert); } } diff --git a/src/platform/qt/scripting/ScriptingTextBuffer.h b/src/platform/qt/scripting/ScriptingTextBuffer.h index b4a9c5b83..717a5d284 100644 --- a/src/platform/qt/scripting/ScriptingTextBuffer.h +++ b/src/platform/qt/scripting/ScriptingTextBuffer.h @@ -36,6 +36,8 @@ signals: void bufferNameChanged(const QString&); private: + enum { tabStop = 4 }; + struct ScriptingBufferShim : public mScriptTextBuffer { ScriptingTextBuffer* p; QTextCursor cursor; @@ -44,6 +46,11 @@ private: QMutex m_mutex; QString m_name; + void lineBreak(); + void carriageReturn(); + void tab(); + void insertString(const QString& text); + static void init(struct mScriptTextBuffer*, const char* name); static void deinit(struct mScriptTextBuffer*);