From 464a9ad9ab67e4894aec1c9a3fccb252e9ceadda Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 23 Nov 2017 14:17:48 +0100 Subject: [PATCH] Editor: Fix block for offset calculation Take block bounding rects into account, when calculating the row count or the center visible line. Change-Id: If933828867df25920eeb56359e9a42a8b95d9c6d Reviewed-by: Christian Stenger --- src/plugins/texteditor/texteditor.cpp | 52 +++++++++++++++++++++------ src/plugins/texteditor/texteditor.h | 9 ++--- src/plugins/vcsbase/vcsbaseeditor.cpp | 8 ++--- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index cb4bfd12c15..8aa3dc847f6 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -4692,8 +4692,8 @@ QTextBlock TextEditorWidgetPrivate::nextVisibleBlock(const QTextBlock &block) co void TextEditorWidgetPrivate::cleanupAnnotationCache() { - const int firstVisibleBlock = q->firstVisibleLine(); - const int lastVisibleBlock = q->lastVisibleLine(); + const int firstVisibleBlock = q->firstVisibleBlockNumber(); + const int lastVisibleBlock = q->lastVisibleBlockNumber(); auto lineIsVisble = [&](int blockNumber){ auto behindFirstVisibleBlock = [&](){ return firstVisibleBlock >= 0 && blockNumber >= firstVisibleBlock; @@ -8107,8 +8107,26 @@ int TextEditorWidget::columnCount() const int TextEditorWidget::rowCount() const { - QFontMetricsF fm(font()); - return viewport()->rect().height() / fm.lineSpacing(); + int height = viewport()->rect().height(); + int lineCount = 0; + QTextBlock block = firstVisibleBlock(); + while (block.isValid()) { + height -= blockBoundingRect(block).height(); + if (height < 0) { + const int blockLineCount = block.layout()->lineCount(); + for (int i = 0; i < blockLineCount; ++i) { + ++lineCount; + const QTextLine line = block.layout()->lineAt(i); + height += line.rect().height(); + if (height >= 0) + break; + } + return lineCount; + } + lineCount += block.layout()->lineCount(); + block = block.next(); + } + return lineCount; } /** @@ -8254,6 +8272,18 @@ QTextBlock TextEditorWidget::blockForVisibleRow(int row) const } +QTextBlock TextEditorWidget::blockForVerticalOffset(int offset) const +{ + QTextBlock block = firstVisibleBlock(); + while (block.isValid()) { + offset -= blockBoundingRect(block).height(); + if (offset < 0) + return block; + block = block.next(); + } + return block; +} + void TextEditorWidget::invokeAssist(AssistKind kind, IAssistProvider *provider) { if (kind == QuickFix && d->m_snippetOverlay->isVisible()) { @@ -8373,28 +8403,28 @@ void TextEditorWidget::configureGenericHighlighter() updateEditorInfoBar(this); } -int TextEditorWidget::lineForVisibleRow(int row) const +int TextEditorWidget::blockNumberForVisibleRow(int row) const { QTextBlock block = blockForVisibleRow(row); return block.isValid() ? block.blockNumber() : -1; } -int TextEditorWidget::firstVisibleLine() const +int TextEditorWidget::firstVisibleBlockNumber() const { - return lineForVisibleRow(0); + return blockNumberForVisibleRow(0); } -int TextEditorWidget::lastVisibleLine() const +int TextEditorWidget::lastVisibleBlockNumber() const { - QTextBlock block = blockForVisibleRow(rowCount() - 1); + QTextBlock block = blockForVerticalOffset(viewport()->height() - 1); if (!block.isValid()) block.previous(); return block.isValid() ? block.blockNumber() : -1; } -int TextEditorWidget::centerVisibleLine() const +int TextEditorWidget::centerVisibleBlockNumber() const { - QTextBlock block = blockForVisibleRow(rowCount() / 2); + QTextBlock block = blockForVerticalOffset(viewport()->height() / 2); if (!block.isValid()) block.previous(); return block.isValid() ? block.blockNumber() : -1; diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 2e2d31e9371..d15db70c7f1 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -453,14 +453,14 @@ public: * * Any invalid row will return -1 as line number. */ - int lineForVisibleRow(int row) const; + int blockNumberForVisibleRow(int row) const; /*! Returns the first visible line of the document. */ - int firstVisibleLine() const; + int firstVisibleBlockNumber() const; /*! Returns the last visible line of the document. */ - int lastVisibleLine() const; + int lastVisibleBlockNumber() const; /*! Returns the line visible closest to the vertical center of the editor. */ - int centerVisibleLine() const; + int centerVisibleBlockNumber() const; Core::HighlightScrollBarController *highlightScrollBarController() const; @@ -472,6 +472,7 @@ signals: protected: QTextBlock blockForVisibleRow(int row) const; + QTextBlock blockForVerticalOffset(int offset) const; bool event(QEvent *e) override; void inputMethodEvent(QInputMethodEvent *e) override; void keyPressEvent(QKeyEvent *e) override; diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index c39686e6021..679d7e6aa5b 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -1303,14 +1303,14 @@ int VcsBaseEditor::lineNumberOfCurrentEditor(const QString ¤tFile) const BaseTextEditor *eda = qobject_cast(ed); if (!eda) return -1; - const int cursorLine = eda->currentLine(); + const int cursorLine = eda->textCursor().blockNumber(); auto const edw = qobject_cast(ed->widget()); if (edw) { - const int firstLine = edw->firstVisibleLine(); - const int lastLine = edw->lastVisibleLine(); + const int firstLine = edw->firstVisibleBlockNumber(); + const int lastLine = edw->lastVisibleBlockNumber(); if (firstLine <= cursorLine && cursorLine < lastLine) return cursorLine; - return edw->centerVisibleLine(); + return edw->centerVisibleBlockNumber(); } return cursorLine; }