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 <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2017-11-23 14:17:48 +01:00
parent c67902ec4e
commit 464a9ad9ab
3 changed files with 50 additions and 19 deletions

View File

@@ -4692,8 +4692,8 @@ QTextBlock TextEditorWidgetPrivate::nextVisibleBlock(const QTextBlock &block) co
void TextEditorWidgetPrivate::cleanupAnnotationCache() void TextEditorWidgetPrivate::cleanupAnnotationCache()
{ {
const int firstVisibleBlock = q->firstVisibleLine(); const int firstVisibleBlock = q->firstVisibleBlockNumber();
const int lastVisibleBlock = q->lastVisibleLine(); const int lastVisibleBlock = q->lastVisibleBlockNumber();
auto lineIsVisble = [&](int blockNumber){ auto lineIsVisble = [&](int blockNumber){
auto behindFirstVisibleBlock = [&](){ auto behindFirstVisibleBlock = [&](){
return firstVisibleBlock >= 0 && blockNumber >= firstVisibleBlock; return firstVisibleBlock >= 0 && blockNumber >= firstVisibleBlock;
@@ -8107,8 +8107,26 @@ int TextEditorWidget::columnCount() const
int TextEditorWidget::rowCount() const int TextEditorWidget::rowCount() const
{ {
QFontMetricsF fm(font()); int height = viewport()->rect().height();
return viewport()->rect().height() / fm.lineSpacing(); 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) void TextEditorWidget::invokeAssist(AssistKind kind, IAssistProvider *provider)
{ {
if (kind == QuickFix && d->m_snippetOverlay->isVisible()) { if (kind == QuickFix && d->m_snippetOverlay->isVisible()) {
@@ -8373,28 +8403,28 @@ void TextEditorWidget::configureGenericHighlighter()
updateEditorInfoBar(this); updateEditorInfoBar(this);
} }
int TextEditorWidget::lineForVisibleRow(int row) const int TextEditorWidget::blockNumberForVisibleRow(int row) const
{ {
QTextBlock block = blockForVisibleRow(row); QTextBlock block = blockForVisibleRow(row);
return block.isValid() ? block.blockNumber() : -1; 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()) if (!block.isValid())
block.previous(); block.previous();
return block.isValid() ? block.blockNumber() : -1; 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()) if (!block.isValid())
block.previous(); block.previous();
return block.isValid() ? block.blockNumber() : -1; return block.isValid() ? block.blockNumber() : -1;

View File

@@ -453,14 +453,14 @@ public:
* *
* Any invalid row will return -1 as line number. * 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. */ /*! Returns the first visible line of the document. */
int firstVisibleLine() const; int firstVisibleBlockNumber() const;
/*! Returns the last visible line of the document. */ /*! 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. */ /*! Returns the line visible closest to the vertical center of the editor. */
int centerVisibleLine() const; int centerVisibleBlockNumber() const;
Core::HighlightScrollBarController *highlightScrollBarController() const; Core::HighlightScrollBarController *highlightScrollBarController() const;
@@ -472,6 +472,7 @@ signals:
protected: protected:
QTextBlock blockForVisibleRow(int row) const; QTextBlock blockForVisibleRow(int row) const;
QTextBlock blockForVerticalOffset(int offset) const;
bool event(QEvent *e) override; bool event(QEvent *e) override;
void inputMethodEvent(QInputMethodEvent *e) override; void inputMethodEvent(QInputMethodEvent *e) override;
void keyPressEvent(QKeyEvent *e) override; void keyPressEvent(QKeyEvent *e) override;

View File

@@ -1303,14 +1303,14 @@ int VcsBaseEditor::lineNumberOfCurrentEditor(const QString &currentFile)
const BaseTextEditor *eda = qobject_cast<const BaseTextEditor *>(ed); const BaseTextEditor *eda = qobject_cast<const BaseTextEditor *>(ed);
if (!eda) if (!eda)
return -1; return -1;
const int cursorLine = eda->currentLine(); const int cursorLine = eda->textCursor().blockNumber();
auto const edw = qobject_cast<const TextEditorWidget *>(ed->widget()); auto const edw = qobject_cast<const TextEditorWidget *>(ed->widget());
if (edw) { if (edw) {
const int firstLine = edw->firstVisibleLine(); const int firstLine = edw->firstVisibleBlockNumber();
const int lastLine = edw->lastVisibleLine(); const int lastLine = edw->lastVisibleBlockNumber();
if (firstLine <= cursorLine && cursorLine < lastLine) if (firstLine <= cursorLine && cursorLine < lastLine)
return cursorLine; return cursorLine;
return edw->centerVisibleLine(); return edw->centerVisibleBlockNumber();
} }
return cursorLine; return cursorLine;
} }