aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schulz <[email protected]>2025-09-10 14:19:32 +0200
committerDavid Schulz <[email protected]>2025-09-11 10:43:23 +0000
commit1e7f76cb5fd036da4fb5fdb7659bcac93a4834fb (patch)
treec909a621003d2c7d9deb43553fbb1dc7667f5189
parent1dc94f1aac8f2e48e231cb4612083986f77ad9f7 (diff)
Utils: improve page up/down in plain text edit
Just increasing the scrollbar by page step and moving the cursor to the closest previous vertical offset is way cleaner than the previous aproach. Fixes: QTCREATORBUG-33447 Change-Id: I8c6fcfabd263d11ac088f93d34967c2a0682e61b Reviewed-by: Christian Stenger <[email protected]>
-rw-r--r--src/libs/utils/plaintextedit/plaintextedit.cpp107
1 files changed, 19 insertions, 88 deletions
diff --git a/src/libs/utils/plaintextedit/plaintextedit.cpp b/src/libs/utils/plaintextedit/plaintextedit.cpp
index 8cb3a2642f2..48a53ab3c3a 100644
--- a/src/libs/utils/plaintextedit/plaintextedit.cpp
+++ b/src/libs/utils/plaintextedit/plaintextedit.cpp
@@ -1051,8 +1051,6 @@ void PlainTextEditPrivate::repaintContents(const QRectF &contentsRect)
void PlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode, bool moveCursor)
{
-
-
QTextCursor cursor = control->textCursor();
if (moveCursor) {
ensureCursorVisible();
@@ -1060,100 +1058,33 @@ void PlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor
pageUpDownLastCursorY = control->cursorRect(cursor).top() - verticalOffset();
}
- qreal lastY = pageUpDownLastCursorY;
+ int scrollBarValue = vbar()->value();
+ const bool atStart = scrollBarValue == 0;
+ const bool atEnd = scrollBarValue == vbar()->maximum();
- if (op == QTextCursor::Down) {
- QRectF visible = QRectF(viewport()->rect()).translated(-q->contentOffset());
- QTextBlock firstVisibleBlock = q->firstVisibleBlock();
- QTextBlock block = firstVisibleBlock;
- QRectF br = q->blockBoundingRect(block);
- qreal h = 0;
- int atEnd = false;
- while (h + br.height() <= visible.bottom()) {
- if (!block.next().isValid()) {
- atEnd = true;
- lastY = visible.bottom(); // set cursor to last line
- break;
- }
- h += br.height();
- block = block.next();
- br = q->blockBoundingRect(block);
- }
+ if (op == QTextCursor::Down && !atEnd)
+ scrollBarValue += vbar()->pageStep();
+ else if (op == QTextCursor::Up && !atStart)
+ scrollBarValue -= vbar()->pageStep();
- if (!atEnd) {
- int line = 0;
- qreal diff = visible.bottom() - h;
- int lineCount = editorLayout->blockLayout(block)->lineCount();
- while (line < lineCount - 1) {
- if (editorLayout->blockLayout(block)->lineAt(line).naturalTextRect().bottom() > diff) {
- // the first line that did not completely fit the screen
- break;
- }
- ++line;
- }
- setTopBlock(block.blockNumber(), line);
- }
+ vbar()->setValue(scrollBarValue);
- if (moveCursor) {
- // move using movePosition to keep the cursor's x
- lastY += verticalOffset();
- bool moved = false;
- do {
- moved = cursor.movePosition(op, moveMode);
- } while (moved && control->cursorRect(cursor).top() < lastY);
- }
-
- } else if (op == QTextCursor::Up) {
-
- QRectF visible = QRectF(viewport()->rect()).translated(-q->contentOffset());
- visible.translate(0, -visible.height()); // previous page
- QTextBlock block = q->firstVisibleBlock();
- qreal h = 0;
- while (h >= visible.top()) {
- if (!block.previous().isValid()) {
- if (control->topBlock == 0 && topLine == 0) {
- lastY = 0; // set cursor to first line
- }
- break;
- }
- block = block.previous();
- QRectF br = q->blockBoundingRect(block);
- h -= br.height();
- }
-
- int line = 0;
- if (block.isValid()) {
- qreal diff = visible.top() - h;
- int lineCount = editorLayout->blockLayout(block)->lineCount();
- while (line < lineCount) {
- if (editorLayout->blockLayout(block)->lineAt(line).naturalTextRect().top() >= diff)
+ if (moveCursor) {
+ while (cursor.movePosition(op, moveMode)) {
+ if (op == QTextCursor::Down) {
+ if (atEnd)
+ continue;
+ if (control->cursorRect(cursor).top() >= pageUpDownLastCursorY)
+ break;
+ } else if (op == QTextCursor::Up) {
+ if (atStart)
+ continue;
+ if (control->cursorRect(cursor).top() <= pageUpDownLastCursorY)
break;
- ++line;
- }
- if (line == lineCount) {
- if (block.next().isValid() && block.next() != q->firstVisibleBlock()) {
- block = block.next();
- line = 0;
- } else {
- --line;
- }
}
}
- setTopBlock(block.blockNumber(), line);
- if (moveCursor) {
- cursor.setVisualNavigation(true);
- // move using movePosition to keep the cursor's x
- lastY += verticalOffset();
- bool moved = false;
- do {
- moved = cursor.movePosition(op, moveMode);
- } while (moved && control->cursorRect(cursor).top() > lastY);
- }
- }
-
- if (moveCursor) {
control->setTextCursor(cursor, moveMode == QTextCursor::KeepAnchor);
pageUpDownLastCursorYIsValid = true;
}