Editor: Add replacement helper to document layout

More inline with the other text block user data members and cleaner on
the client side. Additionally add some & for const arguments and remove
test function call.

Change-Id: I19e646aa204eedf447c02a2f76b89c3430280169
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
David Schulz
2023-02-01 14:21:51 +01:00
parent 8cb654a3ee
commit 6908130c83
5 changed files with 52 additions and 57 deletions

View File

@@ -373,7 +373,7 @@ QAction *TextDocument::createDiffAgainstCurrentFileAction(
return diffAction; return diffAction;
} }
void TextDocument::insertSuggestion(const QString text, const QTextBlock &block) void TextDocument::insertSuggestion(const QString &text, const QTextBlock &block)
{ {
TextDocumentLayout::userData(block)->setReplacement(block.text() + text); TextDocumentLayout::userData(block)->setReplacement(block.text() + text);
TextDocumentLayout::updateReplacmentFormats(block, fontSettings()); TextDocumentLayout::updateReplacmentFormats(block, fontSettings());

View File

@@ -144,7 +144,7 @@ public:
static QAction *createDiffAgainstCurrentFileAction(QObject *parent, static QAction *createDiffAgainstCurrentFileAction(QObject *parent,
const std::function<Utils::FilePath()> &filePath); const std::function<Utils::FilePath()> &filePath);
void insertSuggestion(const QString text, const QTextBlock &block); void insertSuggestion(const QString &text, const QTextBlock &block);
#ifdef WITH_TESTS #ifdef WITH_TESTS
void setSilentReload(); void setSilentReload();

View File

@@ -345,7 +345,7 @@ void TextBlockUserData::setCodeFormatterData(CodeFormatterData *data)
m_codeFormatterData = data; m_codeFormatterData = data;
} }
void TextBlockUserData::setReplacement(const QString replacement) void TextBlockUserData::setReplacement(const QString &replacement)
{ {
m_replacement.reset(new QTextDocument(replacement)); m_replacement.reset(new QTextDocument(replacement));
m_replacement->setDocumentLayout(new TextDocumentLayout(m_replacement.get())); m_replacement->setDocumentLayout(new TextDocumentLayout(m_replacement.get()));
@@ -528,30 +528,32 @@ QByteArray TextDocumentLayout::expectedRawStringSuffix(const QTextBlock &block)
void TextDocumentLayout::updateReplacmentFormats(const QTextBlock &block, void TextDocumentLayout::updateReplacmentFormats(const QTextBlock &block,
const FontSettings &fontSettings) const FontSettings &fontSettings)
{ {
if (TextBlockUserData *userData = textUserData(block)) { if (QTextDocument *replacement = replacementDocument(block)) {
if (QTextDocument *replacement = userData->replacement()) { const QTextCharFormat replacementFormat = fontSettings.toTextCharFormat(
const QTextCharFormat replacementFormat = fontSettings.toTextCharFormat( TextStyles{C_TEXT, {C_DISABLED_CODE}});
TextStyles{C_TEXT, {C_DISABLED_CODE}}); QTextCursor cursor(replacement);
QTextCursor cursor(replacement); cursor.select(QTextCursor::Document);
cursor.select(QTextCursor::Document); cursor.setCharFormat(fontSettings.toTextCharFormat(C_TEXT));
cursor.setCharFormat(fontSettings.toTextCharFormat(C_TEXT)); cursor.setPosition(block.length() - 1);
cursor.setPosition(block.length() - 1); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); cursor.setCharFormat(replacementFormat);
cursor.setCharFormat(replacementFormat); replacement->firstBlock().layout()->setFormats(block.layout()->formats());
replacement->firstBlock().layout()->setFormats(block.layout()->formats());
}
} }
} }
QString TextDocumentLayout::replacement(const QTextBlock &block) QString TextDocumentLayout::replacement(const QTextBlock &block)
{ {
if (TextBlockUserData *userData = textUserData(block)) { if (QTextDocument *replacement = replacementDocument(block))
if (QTextDocument *replacement = userData->replacement()) return replacement->toPlainText().mid(block.length() - 1);
return replacement->toPlainText().mid(block.length() - 1);
}
return {}; return {};
} }
QTextDocument *TextDocumentLayout::replacementDocument(const QTextBlock &block)
{
TextBlockUserData *userData = textUserData(block);
return userData ? userData->replacement() : nullptr;
}
void TextDocumentLayout::requestExtraAreaUpdate() void TextDocumentLayout::requestExtraAreaUpdate()
{ {
emit updateExtraArea(); emit updateExtraArea();
@@ -682,10 +684,8 @@ static QRectF replacementBoundingRect(const QTextDocument *replacement)
QRectF TextDocumentLayout::blockBoundingRect(const QTextBlock &block) const QRectF TextDocumentLayout::blockBoundingRect(const QTextBlock &block) const
{ {
if (TextBlockUserData *userData = textUserData(block)) { if (QTextDocument *replacement = replacementDocument(block))
if (auto replacement = userData->replacement()) return replacementBoundingRect(replacement);
return replacementBoundingRect(replacement);
}
QRectF boundingRect = QPlainTextDocumentLayout::blockBoundingRect(block); QRectF boundingRect = QPlainTextDocumentLayout::blockBoundingRect(block);

View File

@@ -126,7 +126,7 @@ public:
QByteArray expectedRawStringSuffix() { return m_expectedRawStringSuffix; } QByteArray expectedRawStringSuffix() { return m_expectedRawStringSuffix; }
void setExpectedRawStringSuffix(const QByteArray &suffix) { m_expectedRawStringSuffix = suffix; } void setExpectedRawStringSuffix(const QByteArray &suffix) { m_expectedRawStringSuffix = suffix; }
void setReplacement(const QString replacement); void setReplacement(const QString &replacement);
void clearReplacement() { m_replacement.reset(); } void clearReplacement() { m_replacement.reset(); }
QTextDocument *replacement() const { return m_replacement.get(); } QTextDocument *replacement() const { return m_replacement.get(); }
@@ -179,6 +179,7 @@ public:
static QByteArray expectedRawStringSuffix(const QTextBlock &block); static QByteArray expectedRawStringSuffix(const QTextBlock &block);
static void updateReplacmentFormats(const QTextBlock &block, const FontSettings &fontSettings); static void updateReplacmentFormats(const QTextBlock &block, const FontSettings &fontSettings);
static QString replacement(const QTextBlock &block); static QString replacement(const QTextBlock &block);
static QTextDocument *replacementDocument(const QTextBlock &block);
class TEXTEDITOR_EXPORT FoldValidator class TEXTEDITOR_EXPORT FoldValidator
{ {

View File

@@ -1853,13 +1853,13 @@ TextEditorWidget *TextEditorWidget::fromEditor(const IEditor *editor)
void TextEditorWidgetPrivate::editorContentsChange(int position, int charsRemoved, int charsAdded) void TextEditorWidgetPrivate::editorContentsChange(int position, int charsRemoved, int charsAdded)
{ {
if (m_suggestionBlock.isValid()) { if (m_suggestionBlock.isValid()) {
if (TextBlockUserData *data = TextDocumentLayout::textUserData(m_suggestionBlock)) { if (QTextDocument *replacementDocument = TextDocumentLayout::replacementDocument(
if (auto replacementDocument = data->replacement()) { m_suggestionBlock)) {
if (replacementDocument->firstBlock().text().startsWith(m_suggestionBlock.text())) if (replacementDocument->firstBlock().text().startsWith(m_suggestionBlock.text()))
TextDocumentLayout::updateReplacmentFormats(m_suggestionBlock, m_document->fontSettings()); TextDocumentLayout::updateReplacmentFormats(m_suggestionBlock,
else m_document->fontSettings());
clearCurrentSuggestion(); else
} clearCurrentSuggestion();
} }
} }
@@ -2994,8 +2994,6 @@ void TextEditorWidgetPrivate::universalHelper()
{ {
// Test function for development. Place your new fangled experiment here to // Test function for development. Place your new fangled experiment here to
// give it proper scrutiny before pushing it onto others. // give it proper scrutiny before pushing it onto others.
insertSuggestion("Teste\nWeste\nBeste", q->textCursor().block());
} }
void TextEditorWidget::doSetTextCursor(const QTextCursor &cursor, bool keepMultiSelection) void TextEditorWidget::doSetTextCursor(const QTextCursor &cursor, bool keepMultiSelection)
@@ -4449,18 +4447,16 @@ void TextEditorWidgetPrivate::paintAdditionalVisualWhitespaces(PaintEventData &d
} }
if (!nextBlockIsValid) { // paint EOF symbol if (!nextBlockIsValid) { // paint EOF symbol
if (m_suggestionBlock.isValid() && data.block == m_suggestionBlock) { if (m_suggestionBlock.isValid() && data.block == m_suggestionBlock) {
if (TextBlockUserData *userData = TextDocumentLayout::textUserData( if (QTextDocument *replacement = TextDocumentLayout::replacementDocument(
m_suggestionBlock)) { m_suggestionBlock)) {
if (QTextDocument *replacement = userData->replacement()) { const QTextBlock lastReplacementBlock = replacement->lastBlock();
const QTextBlock lastReplacementBlock = replacement->lastBlock(); for (QTextBlock block = replacement->firstBlock();
for (QTextBlock block = replacement->firstBlock(); block != lastReplacementBlock && block.isValid();
block != lastReplacementBlock && block.isValid(); block = block.next()) {
block = block.next()) { top += replacement->documentLayout()->blockBoundingRect(block).height();
top += replacement->documentLayout()->blockBoundingRect(block).height();
}
layout = lastReplacementBlock.layout();
lineCount = layout->lineCount();
} }
layout = lastReplacementBlock.layout();
lineCount = layout->lineCount();
} }
} }
QTextLine line = layout->lineAt(lineCount - 1); QTextLine line = layout->lineAt(lineCount - 1);
@@ -4468,10 +4464,10 @@ void TextEditorWidgetPrivate::paintAdditionalVisualWhitespaces(PaintEventData &d
int h = 4; int h = 4;
lineRect.adjust(0, 0, -1, -1); lineRect.adjust(0, 0, -1, -1);
QPainterPath path; QPainterPath path;
QPointF pos(lineRect.topRight() + QPointF(h+4, line.ascent())); QPointF pos(lineRect.topRight() + QPointF(h + 4, line.ascent()));
path.moveTo(pos); path.moveTo(pos);
path.lineTo(pos + QPointF(-h, -h)); path.lineTo(pos + QPointF(-h, -h));
path.lineTo(pos + QPointF(0, -2*h)); path.lineTo(pos + QPointF(0, -2 * h));
path.lineTo(pos + QPointF(h, -h)); path.lineTo(pos + QPointF(h, -h));
path.closeSubpath(); path.closeSubpath();
painter.setBrush(painter.pen().color()); painter.setBrush(painter.pen().color());
@@ -4937,19 +4933,17 @@ void TextEditorWidget::paintBlock(QPainter *painter,
const QVector<QTextLayout::FormatRange> &selections, const QVector<QTextLayout::FormatRange> &selections,
const QRect &clipRect) const const QRect &clipRect) const
{ {
if (TextBlockUserData *userData = TextDocumentLayout::textUserData(block)) { if (QTextDocument *replacement = TextDocumentLayout::replacementDocument(block)) {
if (QTextDocument *replacement = userData->replacement()) { QTextBlock replacementBlock = replacement->firstBlock();
QTextBlock replacementBlock = replacement->firstBlock(); QPointF replacementOffset = offset;
QPointF replacementOffset = offset; replacementOffset.rx() += document()->documentMargin();
replacementOffset.rx() += document()->documentMargin(); while (replacementBlock.isValid()) {
while (replacementBlock.isValid()) { replacementBlock.layout()->draw(painter, replacementOffset, selections, clipRect);
replacementBlock.layout()->draw(painter, replacementOffset, selections, clipRect); replacementOffset.ry()
replacementOffset.ry() += replacement->documentLayout()->blockBoundingRect(replacementBlock).height();
+= replacement->documentLayout()->blockBoundingRect(replacementBlock).height(); replacementBlock = replacementBlock.next();
replacementBlock = replacementBlock.next();
}
return;
} }
return;
} }
block.layout()->draw(painter, offset, selections, clipRect); block.layout()->draw(painter, offset, selections, clipRect);