Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Store QTextBlock user data without deleting it after undo of TextEdit Qml
Qt 6.12 LTS is out! See what's new in the release blog

Store QTextBlock user data without deleting it after undo of TextEdit Qml

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 357 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SheepS Offline
    SheepS Offline
    Sheep
    wrote on last edited by
    #1

    Am tryng to implement folding and folding of QtextBlocks in qml without tracking them in the undo and redo..
    I tried using QTextBlock::setVisible but when i set it to false..the app crashes, even when i add QTextDocument::markContentsDirty.

    I tried using QTextBlock::setUserData with the QTextBlockUserData object, and it works!, but if the user undoes, the object is deleted leading to loss of data since the block text is stored in the object. And Qt documentation warns us not to do any internal manipulations of the QQuickTextDocument object returned by the TextEdit::textDocument or else will crash!

    void DocumentHandler::toggleBlock(int blockPosition) {
      if (textDocument()) {
        auto textBlock = textDocument()->findBlockByNumber(blockPosition);
        if (textBlock.isValid()) {
    
          // this is nullptr whenever the the text block is undone!!
          auto userBlockData =
              dynamic_cast<GwTextBlockData *>(textBlock.userData());
    
           if (!userBlockData) {
            // hence forcing this object to be recreated the second time....this is ugly!
            userBlockData = new GwTextBlockData;
            textBlock.setUserData(userBlockData);
          } 
    
          if (userBlockData->isVisible()) {
            foldBlock(textBlock);
          } else {
            unFoldBlock(textBlock);
          }
    
          emit updateBlockHightligterPosition();
        }
      }
    }
    
    void DocumentHandler::foldBlock(QTextBlock &textBlock) {
    
      auto userBlockData = dynamic_cast<GwTextBlockData *>(textBlock.userData());
      if (!userBlockData) {
        qDebug() << "Failed to get block data ..";
        return;
      }
    
      // store block text before folding
      userBlockData->setBlockText(textBlock.text());
    
      QTextCursor blockCursor(textBlock);
    
      // select first line of the block
    
      int currentCursorPosition = blockCursor.position();
    
      blockCursor.select(QTextCursor::BlockUnderCursor);
    
      auto blocKtext = textBlock.text();
      auto firstLine =
          blocKtext.mid(0, 50); // this is the text that will remain visible to the
                                // user when th block is folded
    
      auto remaining = blocKtext.remove(firstLine); // this is the rest of the block
                                                    // text to be hidden
    
      int start = currentCursorPosition + firstLine.length();
      int end = currentCursorPosition + textBlock.text().length();
    
      blockCursor.setPosition(start, QTextCursor::MoveAnchor);
      blockCursor.setPosition(end, QTextCursor::KeepAnchor);
    
      // prevent registering this operation to the undo and redo stack
      blockCursor.joinPreviousEditBlock();
      // remove the remaining text to give an illusion of folding;
      blockCursor.removeSelectedText();
      blockCursor.endEditBlock();
    
      // store the block state in the text block object
      userBlockData->setFirstLineText(firstLine);
      userBlockData->setRemainingText(remaining);
      userBlockData->setIsVisible(false);
    }
    
    
    void DocumentHandler::unFoldBlock(QTextBlock &textBlock) {
    
      QTextCursor blockCursor(textBlock);
    
      auto userBlockData = dynamic_cast<GwTextBlockData *>(textBlock.userData());
    
      if (!userBlockData) {
        qDebug() << "Failed to get block data ..";
        return;
      }
    
      // prevent registering this operation to the undo and redo stack
      blockCursor.joinPreviousEditBlock();
      // revealing block
      blockCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor);
    
      // insert the remaining text to give an illusion of unfolding
      blockCursor.insertText(userBlockData->getRemainingText());
      blockCursor.endEditBlock();
    
      userBlockData->setIsVisible(true);
      textBlock.setUserData(userBlockData);
    } 
    

    any suggestion of recommendatins are welcome

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt
    • Unsolved