Details
-
Bug
-
Resolution: Unresolved
-
P4: Low
-
None
-
Qt Creator 4.9.2, Qt Creator 4.10.2
-
None
Description
When multiselecting lines with the mouse using Alt+mouse drag, the text above the selection gets rendered white on white (at first I thought it doesn't get rendered, but watch the first highlighted line in the GIF).
That is because the highlighted cursor text is white in color, and as explained below the editor is tricked into using the first block as anchor/position in this case)
Hence also, when the text document doesn't fit the page, the cursor jumps to the first line (see second GIF).
While the rendering is a problem, the root cause appears to be in the function
QTextCursor TextBlockSelection::cursor(QTextDocument *document, bool fullSelection) const in texteditor.cpp(7999).
Here, it is not checked whether anchorTextBlock and positionTextBlock are valid.
If theses are forced to be within range (by settings to lastBlock()), the problem disappears:
QTextCursor TextBlockSelection::cursor(QTextDocument *document, bool fullSelection) const { if (!document) return QTextCursor(); int selectionAnchorColumn; int selectionPositionColumn; // Ensure blocks within range const int validAnchorBlock = std::min(anchorBlock, document->blockCount()-1); const int validPositionBlock = std::min(positionBlock, document->blockCount()-1); if(validAnchorBlock == validPositionBlock || !fullSelection) { selectionAnchorColumn = anchorColumn; selectionPositionColumn = positionColumn; } else if(validAnchorBlock == firstBlockNumber()) { selectionAnchorColumn = firstVisualColumn(); selectionPositionColumn = lastVisualColumn(); } else { selectionAnchorColumn = lastVisualColumn(); selectionPositionColumn = firstVisualColumn(); } QTextCursor cursor(document); QTextBlock anchorTextBlock = document->findBlockByNumber(validAnchorBlock); const int anchorPosition = anchorTextBlock.position() + m_TabSettings->positionAtColumn(anchorTextBlock.text(), selectionAnchorColumn); QTextBlock positionTextBlock = document->findBlockByNumber(validPositionBlock); const int cursorPosition = positionTextBlock.position() + m_TabSettings->positionAtColumn(positionTextBlock.text(), selectionPositionColumn); cursor.setPosition(anchorPosition); cursor.setPosition(cursorPosition, QTextCursor::KeepAnchor); return cursor; }
In additon, the function TectBlockSelection::fromPosition() should take the document and verify that the blocks are within range.
If this isn't done, there is a corner case where the issue happens if only the last line is selected. This is visible only when the document doesn't end on a newline. See third GIF.
void TextBlockSelection::fromPostition(int positionBlock, int positionColumn, int anchorBlock, int anchorColumn, QTextDocument *document) { this->positionBlock = std::min(positionBlock, document->blockCount()-1); this->positionColumn = positionColumn; this->anchorBlock = std::min(anchorBlock, document->blockCount()-1); this->anchorColumn = anchorColumn; }
Note that in theory this fix should make the previous code obsolete, but just in case, we can verify there too instead of getting the invalid block by block number.
.