Exemple #1
0
// 遍历文本块
void MainWindow::showTextBlock()
{
    QTextDocument *document = ui->textEdit->document();
    // 获取文档的第一个文本块
    QTextBlock block = document->firstBlock();
    for(int i=0; i<document->blockCount(); i++){
        qDebug() << tr("文本块%1,文本块首行行号为:%2,长度为:%3,内容为:")
                    .arg(i).arg(block.firstLineNumber()).arg(block.length())
                 << block.text();
        // 获取下一个文本块
        block = block.next();
    }
}
QPoint Editor::keyPopPoint(QTextCursor cursor)
{
    int ht = fontMetrics().height();
    int wd = fontMetrics().width(QLatin1Char('9'));
    int col = cursor.columnNumber();
    int row = cursor.blockNumber()+2; // show just below line

    QTextBlock block = firstVisibleBlock();
    int top = block.firstLineNumber();

    QPoint pt = QPoint(lineNumberAreaWidth()+col*wd,(row-top)*ht);
    return pt;
}
void CodeFoldingPanel::paintEvent(QPaintEvent *e)
{
    QTextDocument *doc = editorWidget()->document();
    TextDocumentLayout *documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout());
    if(!documentLayout)
        return;

    QPalette pal = areaWidget()->palette();
    pal.setCurrentColorGroup(QPalette::Active);
    QPainter painter(this);
    const QFontMetrics fm(areaWidget()->font());

    const int collapseColumnWidth = d->m_codeFoldingVisible ? foldBoxWidth(fm): 0;
    const int extraAreaWidth = d->m_extraArea->width() - collapseColumnWidth;

    painter.fillRect(e->rect(), pal.color(QPalette::Background));

    QTextBlock block = editorWidget()->firstVisibleBlock();
    int blockNumber = block.blockNumber();
    qreal top = editorWidget()->blockBoundingGeometry(block).translated(editorWidget()->contentOffset()).top();
    qreal bottom = top;

    while (block.isValid() && top <= e->rect().bottom()) {

        top = bottom;
        const qreal height = editorWidget()->blockBoundingRect(block).height();
        bottom = top + height;
        QTextBlock nextBlock = block.next();

        QTextBlock nextVisibleBlock = nextBlock;
        int nextVisibleBlockNumber = blockNumber + 1;

        if (!nextVisibleBlock.isVisible()) {
            // invisible blocks do have zero line count
            nextVisibleBlock = doc->findBlockByLineNumber(nextVisibleBlock.firstLineNumber());
            nextVisibleBlockNumber = nextVisibleBlock.blockNumber();
        }

        if (bottom < e->rect().top()) {
            block = nextVisibleBlock;
            blockNumber = nextVisibleBlockNumber;
            continue;
        }

        painter.setPen(pal.color(QPalette::Dark));

        painter.save();
        painter.setRenderHint(QPainter::Antialiasing, false);

        int extraAreaHighlightFoldBlockNumber = -1;
        int extraAreaHighlightFoldEndBlockNumber = -1;
        bool endIsVisible = false;
        if (!d->m_highlightBlocksInfo.isEmpty()) {
            extraAreaHighlightFoldBlockNumber =  d->m_highlightBlocksInfo.open.last();
            extraAreaHighlightFoldEndBlockNumber =  d->m_highlightBlocksInfo.close.first();
            endIsVisible = doc->findBlockByNumber(extraAreaHighlightFoldEndBlockNumber).isVisible();

//                    QTextBlock before = doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber-1);
//                    if (TextBlockUserData::hasCollapseAfter(before)) {
//                        extraAreaHighlightCollapseBlockNumber--;
//                    }
        }

        TextBlockUserData *nextBlockUserData = TextDocumentLayout::testUserData(nextBlock);

        bool drawBox = nextBlockUserData
                       && TextDocumentLayout::foldingIndent(block) < nextBlockUserData->foldingIndent();



        bool active = blockNumber == extraAreaHighlightFoldBlockNumber;

        bool drawStart = active;
        bool drawEnd = blockNumber == extraAreaHighlightFoldEndBlockNumber || (drawStart && !endIsVisible);
        bool hovered = blockNumber >= extraAreaHighlightFoldBlockNumber
                       && blockNumber <= extraAreaHighlightFoldEndBlockNumber;

        int boxWidth = foldBoxWidth(fm);
        if (hovered) {
            int itop = qRound(top);
            int ibottom = qRound(bottom);
            QRect box = QRect(extraAreaWidth + 1, itop, boxWidth - 2, ibottom - itop);
            drawRectBox(&painter, box, drawStart, drawEnd, pal);
        }

        if (drawBox) {
            bool expanded = nextBlock.isVisible();
            int size = boxWidth/4;
            QRect box(extraAreaWidth + size, top + size,
                      2 * (size) + 1, 2 * (size) + 1);
            d->drawFoldingMarker(&painter, pal, box, expanded, active, hovered);
        }


        painter.restore();

        block = nextVisibleBlock;
        blockNumber = nextVisibleBlockNumber;
    }
}