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 <eike.ziller@qt.io>
This commit is contained in:
David Schulz
2022-09-30 11:37:50 +02:00
parent 78ef2e2b52
commit 33177686fd
5 changed files with 31 additions and 30 deletions

View File

@@ -259,7 +259,7 @@ QString SideDiffEditorWidget::plainTextFromSelection(const QTextCursor &cursor)
block = block.next(); block = block.next();
} }
return convertToPlainText(text); return TextDocument::convertToPlainText(text);
} }
SideBySideDiffOutput SideDiffData::diffOutput(QFutureInterface<void> &fi, int progressMin, SideBySideDiffOutput SideDiffData::diffOutput(QFutureInterface<void> &fi, int progressMin,

View File

@@ -274,9 +274,34 @@ TextDocument *TextDocument::textDocumentForFilePath(const Utils::FilePath &fileP
return qobject_cast<TextDocument *>(DocumentModel::documentForFilePath(filePath)); return qobject_cast<TextDocument *>(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 QString TextDocument::plainText() const
{ {
return document()->toPlainText(); return convertToPlainText(d->m_document.toRawText());
} }
QString TextDocument::textAt(int pos, int length) const 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 // restore text cursor and scroll bar positions
if (autoSave && undos < d->m_document.availableUndoSteps()) { if (autoSave && undos < d->m_document.availableUndoSteps()) {

View File

@@ -53,6 +53,7 @@ public:
static QMap<Utils::FilePath, QTextCodec *> openedTextDocumentEncodings(); static QMap<Utils::FilePath, QTextCodec *> openedTextDocumentEncodings();
static TextDocument *currentTextDocument(); static TextDocument *currentTextDocument();
static TextDocument *textDocumentForFilePath(const Utils::FilePath &filePath); static TextDocument *textDocumentForFilePath(const Utils::FilePath &filePath);
static QString convertToPlainText(const QString &rawText);
virtual QString plainText() const; virtual QString plainText() const;
virtual QString textAt(int pos, int length) const; virtual QString textAt(int pos, int length) const;

View File

@@ -1097,36 +1097,12 @@ QString TextEditorWidget::plainTextFromSelection(const QTextCursor &cursor) cons
{ {
// Copy the selected text as plain text // Copy the selected text as plain text
QString text = cursor.selectedText(); QString text = cursor.selectedText();
return convertToPlainText(text); return TextDocument::convertToPlainText(text);
} }
QString TextEditorWidget::plainTextFromSelection(const Utils::MultiTextCursor &cursor) const QString TextEditorWidget::plainTextFromSelection(const Utils::MultiTextCursor &cursor) const
{ {
return convertToPlainText(cursor.selectedText()); return TextDocument::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;
} }
static const char kTextBlockMimeType[] = "application/vnd.qtcreator.blocktext"; static const char kTextBlockMimeType[] = "application/vnd.qtcreator.blocktext";

View File

@@ -522,7 +522,6 @@ protected:
virtual QString plainTextFromSelection(const QTextCursor &cursor) const; virtual QString plainTextFromSelection(const QTextCursor &cursor) const;
virtual QString plainTextFromSelection(const Utils::MultiTextCursor &cursor) const; virtual QString plainTextFromSelection(const Utils::MultiTextCursor &cursor) const;
static QString convertToPlainText(const QString &txt);
virtual QString lineNumber(int blockNumber) const; virtual QString lineNumber(int blockNumber) const;
virtual int lineNumberDigits() const; virtual int lineNumberDigits() const;