Qt: honor control characters in ScriptingTextBuffer::print

This commit is contained in:
Adam Higerd 2024-11-19 10:41:34 -06:00 committed by Vicki Pfau
parent 1eb130a28b
commit 938ee55d42
2 changed files with 67 additions and 16 deletions

View File

@ -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);
}
}

View File

@ -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*);