From 33177686fdba19622becf3f1cd8f13693c93911b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 30 Sep 2022 11:37:50 +0200 Subject: [PATCH] TextEditor: do not replace nbsp with normal spaces This fixes saving documents and copy texts that contain non breaking spaces. Task-number: QTCREATORBUG-17875 Change-Id: Ie0b0e68cf7d67e768ff99c9acae1937aafc78ce7 Reviewed-by: Eike Ziller --- .../diffeditor/sidebysidediffeditorwidget.cpp | 2 +- src/plugins/texteditor/textdocument.cpp | 29 +++++++++++++++++-- src/plugins/texteditor/textdocument.h | 1 + src/plugins/texteditor/texteditor.cpp | 28 ++---------------- src/plugins/texteditor/texteditor.h | 1 - 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp index 4403f2285c3..952eea642f9 100644 --- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp +++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp @@ -259,7 +259,7 @@ QString SideDiffEditorWidget::plainTextFromSelection(const QTextCursor &cursor) block = block.next(); } - return convertToPlainText(text); + return TextDocument::convertToPlainText(text); } SideBySideDiffOutput SideDiffData::diffOutput(QFutureInterface &fi, int progressMin, diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index 71da641ecef..6b221c310fa 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -274,9 +274,34 @@ TextDocument *TextDocument::textDocumentForFilePath(const Utils::FilePath &fileP return qobject_cast(DocumentModel::documentForFilePath(filePath)); } +QString TextDocument::convertToPlainText(const QString &rawText) +{ + // This is basically a copy of QTextDocument::toPlainText but since toRawText returns a + // text containing formating characters and toPlainText replaces non breaking spaces, we + // provide our own plain text conversion to be able to save and copy document content + // containing non breaking spaces. + + QString txt = rawText; + QChar *uc = txt.data(); + QChar *e = uc + txt.size(); + + for (; uc != e; ++uc) { + switch (uc->unicode()) { + case 0xfdd0: // QTextBeginningOfFrame + case 0xfdd1: // QTextEndOfFrame + case QChar::ParagraphSeparator: + case QChar::LineSeparator: + *uc = QLatin1Char('\n'); + break; + default:; + } + } + return txt; +} + QString TextDocument::plainText() const { - return document()->toPlainText(); + return convertToPlainText(d->m_document.toRawText()); } QString TextDocument::textAt(int pos, int length) const @@ -638,7 +663,7 @@ bool TextDocument::save(QString *errorString, const FilePath &filePath, bool aut } } - const bool ok = write(savePath, saveFormat, d->m_document.toPlainText(), errorString); + const bool ok = write(savePath, saveFormat, plainText(), errorString); // restore text cursor and scroll bar positions if (autoSave && undos < d->m_document.availableUndoSteps()) { diff --git a/src/plugins/texteditor/textdocument.h b/src/plugins/texteditor/textdocument.h index fbddd843848..4a73cc124a5 100644 --- a/src/plugins/texteditor/textdocument.h +++ b/src/plugins/texteditor/textdocument.h @@ -53,6 +53,7 @@ public: static QMap openedTextDocumentEncodings(); static TextDocument *currentTextDocument(); static TextDocument *textDocumentForFilePath(const Utils::FilePath &filePath); + static QString convertToPlainText(const QString &rawText); virtual QString plainText() const; virtual QString textAt(int pos, int length) const; diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index c75eb28bb41..1b4c0be2b34 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -1097,36 +1097,12 @@ QString TextEditorWidget::plainTextFromSelection(const QTextCursor &cursor) cons { // Copy the selected text as plain text QString text = cursor.selectedText(); - return convertToPlainText(text); + return TextDocument::convertToPlainText(text); } QString TextEditorWidget::plainTextFromSelection(const Utils::MultiTextCursor &cursor) const { - return convertToPlainText(cursor.selectedText()); -} - -QString TextEditorWidget::convertToPlainText(const QString &txt) -{ - QString ret = txt; - QChar *uc = ret.data(); - QChar *e = uc + ret.size(); - - for (; uc != e; ++uc) { - switch (uc->unicode()) { - case 0xfdd0: // QTextBeginningOfFrame - case 0xfdd1: // QTextEndOfFrame - case QChar::ParagraphSeparator: - case QChar::LineSeparator: - *uc = QLatin1Char('\n'); - break; - case QChar::Nbsp: - *uc = QLatin1Char(' '); - break; - default: - ; - } - } - return ret; + return TextDocument::convertToPlainText(cursor.selectedText()); } static const char kTextBlockMimeType[] = "application/vnd.qtcreator.blocktext"; diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index ae7f2f82cce..75ccb493578 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -522,7 +522,6 @@ protected: virtual QString plainTextFromSelection(const QTextCursor &cursor) const; virtual QString plainTextFromSelection(const Utils::MultiTextCursor &cursor) const; - static QString convertToPlainText(const QString &txt); virtual QString lineNumber(int blockNumber) const; virtual int lineNumberDigits() const;