Uploaded image for project: 'Qt Creator'
  1. Qt Creator
  2. QTCREATORBUG-23224

Qt Creator multiselection

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P4: Low
    • None
    • Qt Creator 4.9.2, Qt Creator 4.10.2
    • Editors
    • None
    • All

    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.

       

      .

      Attachments

        1. multilinebug.gif
          multilinebug.gif
          282 kB
        2. multilinebug2.gif
          multilinebug2.gif
          712 kB
        3. multilinebug3.gif
          multilinebug3.gif
          85 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            davschul David Schulz
            namezero Langonda Agag
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes