/*!
 *  Returns the rectangle for the cursor including the predictive text area.
 *  HbAbstractEditPrivate::ensurePositionVisible() uses the same algorithm.
 */
QRectF NmEditorTextEdit::rectForCursorPosition() const
{
    NM_FUNCTION;
    
    int cursorPos = cursorPosition();
    QRectF rect = rectForPosition(cursorPos);
    QTextDocument *doc = document();
    if (doc) {
        rect.adjust(0, -doc->documentMargin(), 0, doc->documentMargin());
        const QTextBlock block = doc->findBlock(cursorPos);
        QTextLayout *blockLayout = block.layout();
        if (block.isValid() && blockLayout) {
            if (blockLayout->preeditAreaText().length()) {
                // Adjust cursor rect so that predictive text will be also visible
                rect.adjust(0, 0, boundingRect().width() / 2, 0);
            }
        }
    }

    return rect;
}
Example #2
0
QSize CustomLabel::sizeHint() const
{
#ifdef DEBUG_CUSTOMLABEL
    QSize sh = QLabel::sizeHint();
    //sh.setWidth(sh.width() + 1);
    //sh.setHeight(sh.height() + 4);
    qDebug() << "for text:" << text();
    qDebug() << "  size hint:" << sh;

    QTextDocument *doc = textDocument();
    sh = doc->documentLayout()->documentSize().toSize();
    qDebug() << "  doc size:" << sh;

    sh += QSize(doc->documentMargin(), doc->documentMargin());
    qDebug() << "  doc size with margin:" << sh;

    return sh;
#else
    return QLabel::sizeHint();
#endif
}
Example #3
0
void TextDocumentLayout::layoutBlock(const QTextBlock &block)
{
    QTextDocument *doc = document();
    qreal margin = doc->documentMargin();
    qreal blockMaximumWidth = 0;

    qreal height = 0;
    QTextLayout *tl = block.layout();
    QTextOption option = doc->defaultTextOption();
    tl->setTextOption(option);

    int extraMargin = 0;
    if (option.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) {
        QFontMetrics fm(block.charFormat().font());
        extraMargin += fm.width(QChar(0x21B5));
    }
    tl->beginLayout();
    qreal availableWidth = d->width;
    if (availableWidth <= 0) {
        availableWidth = qreal(INT_MAX); // similar to text edit with pageSize.width == 0
    }
    availableWidth -= 2*margin + extraMargin;
    qreal indentMargin = 0;
    while (1) {
        QTextLine line = tl->createLine();
        if (!line.isValid())
            break;
        line.setLeadingIncluded(true);
        line.setLineWidth(availableWidth - indentMargin);
        line.setPosition(QPointF(margin + indentMargin, height));
        if(!height) //enter only in the first iteration
        {
            indentMargin = indentWidth(block);
        }
        height += line.height();
        blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
    }
    tl->endLayout();

    int previousLineCount = doc->lineCount();
    const_cast<QTextBlock&>(block).setLineCount(block.isVisible() ? tl->lineCount() : 0);
    int lineCount = doc->lineCount();

    bool emitDocumentSizeChanged = previousLineCount != lineCount;
    if (blockMaximumWidth > d->maximumWidth) {
        // new longest line
        d->maximumWidth = blockMaximumWidth;
        d->maximumWidthBlockNumber = block.blockNumber();
        emitDocumentSizeChanged = true;
    } else if (block.blockNumber() == d->maximumWidthBlockNumber && blockMaximumWidth < d->maximumWidth) {
        // longest line shrinking
        QTextBlock b = doc->firstBlock();
        d->maximumWidth = 0;
        QTextBlock maximumBlock;
        while (b.isValid()) {
            qreal blockMaximumWidth = blockWidth(b);
            if (blockMaximumWidth > d->maximumWidth) {
                d->maximumWidth = blockMaximumWidth;
                maximumBlock = b;
            }
            b = b.next();
        }
        if (maximumBlock.isValid()) {
            d->maximumWidthBlockNumber = maximumBlock.blockNumber();
            emitDocumentSizeChanged = true;
        }
    }
    if (emitDocumentSizeChanged)// && !d->blockDocumentSizeChanged)
        emit documentSizeChanged(documentSize());

    emit updateBlock(block);
}
Example #4
0
/*! \reimp
 */
void TextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, int charsAdded)
{
    QTextDocument *doc = document();
    int newBlockCount = doc->blockCount();

    QTextBlock changeStartBlock = doc->findBlock(from);
    QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsAdded - 1));

    if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) {
        QTextBlock block = changeStartBlock;
        if (block.isValid()  && block.layout()->lineCount()) {
            QRectF oldBr = blockBoundingRect(block);
            layoutBlock(block);
            QRectF newBr = blockBoundingRect(block);
            if (newBr.height() == oldBr.height()) {
                if (!d->blockUpdate)
                    emit updateBlock(block);
                return;
            }
        }
    } else {
        QTextBlock block = changeStartBlock;
        do {
            block.clearLayout();
            if (block == changeEndBlock)
                break;
            block = block.next();
        } while(block.isValid());
    }

    if (newBlockCount != d->blockCount) {

        int changeEnd = changeEndBlock.blockNumber();
        int blockDiff = newBlockCount - d->blockCount;
        int oldChangeEnd = changeEnd - blockDiff;

        if (d->maximumWidthBlockNumber > oldChangeEnd)
            d->maximumWidthBlockNumber += blockDiff;

        d->blockCount = newBlockCount;
        if (d->blockCount == 1)
            d->maximumWidth = blockWidth(doc->firstBlock());

        if (!d->blockDocumentSizeChanged)
            emit documentSizeChanged(documentSize());

        if (blockDiff == 1 && changeEnd == newBlockCount -1 ) {
            if (!d->blockUpdate)
            {
                QTextBlock b = changeStartBlock;
                for(;;) {
                    emit updateBlock(b);
                    if (b == changeEndBlock)
                        break;
                    b = b.next();
                }
            }
            return;
        }
    }
    if (!d->blockUpdate)
        emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
}
Example #5
0
void AATextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    if (hasFocus()){
        QGraphicsTextItem::paint(painter, option, widget);
        return;
    }

    painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    QPainterPath path;
    QString s = toPlainText();
    QTextDocument *doc = document();
    qreal margin = doc->documentMargin();
    QStringList lines = s.split("\n", QString::SkipEmptyParts);

    QFont f = font();
    f.setStyleHint(QFont::AnyStyle, QFont::PreferAntialias);
    QFontMetrics fm(f);
    QFont f_bold = f;
    f_bold.setBold(true);
    QFontMetrics fm_bold(f_bold);

    int line = 0;
    for (int i = 0; i < lines.length(); i++){
        QString thisline = lines[i];
        QStringList s1 = thisline.split(']', QString::SkipEmptyParts);
        QStringList s_non_bold, s_bold;
        foreach(QString s, s1){
            if (!s.contains('[')){
                s_non_bold << s;
                s_bold << QString();
            }
            else if (!s.startsWith('[')){
                QStringList s2 = s.split('[', QString::SkipEmptyParts);
                s_non_bold << s2.first();
                s_bold << s2.last();
            }
            else {
                s = s.mid(1);
                s_non_bold << QString();
                s_bold << s;
            }
        }

        int width = 0;
        for (int j = 0; j < s_non_bold.length(); j++){
            QString non_bold = s_non_bold[j];
            for (int k = 0; k < non_bold.length(); k++){
                QChar c = non_bold[k];
                QString str = c;
                int width_c = fm.width(str);
                if (width + width_c > doc->size().width()){
                    ++line;
                    width = 0;
                }
                path.addText(margin + width, fm.height() * (line + 1), f, str);
                width += width_c;
            }
            QString bold = s_bold[j];
            for (int k = 0; k < bold.length(); k++){
                QChar c = bold[k];
                QString str = c;
                int width_c = fm_bold.width(str);
                if (width + width_c > doc->size().width()){
                    ++line;
                    width = 0;
                }
                path.addText(margin + width, fm.height() * (line + 1), f_bold, str); //use fm.height not fm_bold.height, for sometimes the bold characters are not as high as the non-bold ones
                width += width_c;
            }
        }
        ++line;
    }
    painter->fillPath(path, defaultTextColor());
}