Esempio n. 1
0
int ShaderEdit::searchPreviousMatch( QTextBlock block, int start, QString close, QString open )
{
	int skipNext = 0;
	--start;
	TextBlockData *data = (TextBlockData*)block.userData();
	
	do {
		if ( data ) {
			for ( int i = start; i >= 0; --i ) {
				ParenthesisInfo pi = data->parenthesis[i];
				QString s = pi.character;
				if ( s == open ) {
					if ( skipNext > 0 )
						--skipNext;
					else
						return block.position() + pi.position;
				}
				else if ( s == close )
					++skipNext;
			}
		}
		block = block.previous();
		data = (TextBlockData*)block.userData();
		if ( data )
			start = data->parenthesis.count() - 1;
	} while ( block.isValid() );
	
	return -1;
}
Esempio n. 2
0
static int findOpeningMatch(const QTextDocument *doc, int cursorPosition) {
  QTextBlock block = doc->findBlock(cursorPosition);
  TextBlockData *blockData =
    reinterpret_cast<TextBlockData *>(block.userData());

  if (!blockData->bracketPositions.isEmpty()) {
    int depth = 1;

    while (block.isValid()) {
      blockData = reinterpret_cast<TextBlockData *>(block.userData());

      if (blockData && !blockData->bracketPositions.isEmpty()) {
        for (int c = blockData->bracketPositions.count() - 1; c >= 0; --c) {
          int absPos = block.position() + blockData->bracketPositions.at(c);

          if (absPos >= cursorPosition - 1) continue;
          if (doc->characterAt(absPos) == '}') depth++;
          else depth--;
          if (depth == 0) return absPos;
        }
      }
      block = block.previous();
    }
  }
  return -1;
}
Esempio n. 3
0
void TestDocumentLayout::testCenteredItems()
{
    initForNewTest("ListItem\nListItem\nListItem");

    KoListStyle listStyle;
    KoListLevelProperties llp;
    llp.setStyle(KoListStyle::DecimalItem);
    listStyle.setLevelProperties(llp);

    QTextBlock block = m_doc->begin(); // normal block
    QVERIFY(block.isValid());
    listStyle.applyStyle(block);
    block = block.next(); // centered block
    QVERIFY(block.isValid());
    listStyle.applyStyle(block);
    QTextBlockFormat fmt;
    fmt.setAlignment(Qt::AlignHCenter);
    QTextCursor cursor(block);
    cursor.mergeBlockFormat(fmt);
    block = block.next(); // centered RTL text.
    listStyle.applyStyle(block);
    cursor = QTextCursor(block);
    fmt.setProperty(KoParagraphStyle::TextProgressionDirection, KoText::RightLeftTopBottom);
    cursor.mergeBlockFormat(fmt);

    m_layout->layout();

    block = m_doc->begin();
    QTextLayout *layout = block.layout();
    QTextLine line1 = layout->lineAt(0);
    KoTextBlockData *data1 = dynamic_cast<KoTextBlockData *>(block.userData());
    QVERIFY(line1.isValid());
    QVERIFY(line1.width() < 200); // the counter takes some space.

    block = block.next();
    layout = block.layout();
    QTextLine line2 = layout->lineAt(0);
    KoTextBlockData *data2 = dynamic_cast<KoTextBlockData *>(block.userData());
    QVERIFY(line2.isValid());
    QVERIFY(line2.width() < 200); // the counter takes some space.
    QCOMPARE(line1.width(), line2.width());

    const qreal width1 = line1.naturalTextWidth() + data1->counterWidth() + data1->counterSpacing();
    const qreal width2 = line2.naturalTextWidth() + data2->counterWidth() + data2->counterSpacing();
    QCOMPARE(width1, width2);
    QVERIFY(data1->counterPosition().x() < data2->counterPosition().x());
    const qreal padding = (200 - width2) / 2;
    QVERIFY(padding > 0);// not really a layout test, but the rest will be bogus otherwise.
    QCOMPARE(data2->counterPosition().x(), padding); // close to the centered text.

    // right to left parag places the counter on the right. Its centered, so not the far right.
    block = block.next();
    layout = block.layout();
    QTextLine line = layout->lineAt(0);
    KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData());
    QCOMPARE(data->counterPosition().x(), 200 - padding - data->counterWidth());
}
Esempio n. 4
0
void Document::dictionaryChanged()
{
	for (QTextBlock i = m_text->document()->begin(); i != m_text->document()->end(); i = i.next()) {
		if (i.userData()) {
			static_cast<BlockStats*>(i.userData())->checkSpelling(i.text(), m_dictionary);
		}
	}
	m_highlighter->rehighlight();
}
Esempio n. 5
0
void TestDocumentLayout::testListParagraphIndent()
{
    // test that the list item is drawn indented on an indented paragraph.
    initForNewTest("Foo\nBar\n");

    KoParagraphStyle h1;
    m_styleManager->add(&h1);
    KoParagraphStyle h2;
    m_styleManager->add(&h2);
    h2.setTextIndent(10);

    KoListStyle listStyle;
    h1.setListStyle(&listStyle);
    KoListStyle listStyle2;
    h2.setListStyle(&listStyle2);

    QTextBlock block = m_doc->begin();
    h1.applyStyle(block);
    block = block.next();
    h2.applyStyle(block);

    m_layout->layout();

    // still at h2 parag!
    KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData());
    QVERIFY(data);
    QCOMPARE(data->counterPosition(), QPointF(10, 14.4));
}
Esempio n. 6
0
    TokenIterator& operator --()
    {
        if(idx > 0)
        {
            --idx;
            return *this;
        }
        else if( idx < 0 )
        {
            return *this;
        }

        idx = -1;
        while( (blk = blk.previous()).isValid() )
        {
            data = static_cast<TextBlockData*>(blk.userData());

            if(data)
                idx = data->tokens.size() - 1;

            if (idx < 0)
                continue;

            // we have a valid idx
            break;
        }

        return *this;
    }
Esempio n. 7
0
    // Return an iterator for the token at 'pos' or 'pos-1'.
    // If there is no such token, the returned iterator is invalid.
    static TokenIterator around( const QTextBlock & block, int positionInBlock )
    {
        TokenIterator it;
        it.blk = block;
        it.idx = -1;

        if(!block.isValid())
            return it;

        it.data = static_cast<TextBlockData*>(block.userData());

        if (!it.data)
            return it;

        int n = it.data->tokens.size();
        for( int i = 0; i < n; ++i )
        {
            Token const & token = it.data->tokens[i];
            if(token.positionInBlock > positionInBlock) {
                return it;
            }
            else if(token.positionInBlock == positionInBlock - 1 || token.positionInBlock == positionInBlock)
            {
                it.idx = i;
                break;
            }
        }

        return it;
    }
Esempio n. 8
0
void TestDocumentLayout::testRightToLeftList()
{
    initForNewTest("a\nb\nc");
    KoParagraphStyle h1;
    h1.setTextProgressionDirection(KoText::RightLeftTopBottom);
    m_styleManager->add(&h1);
    KoListStyle listStyle;
    KoListLevelProperties llp = listStyle.levelProperties(1);
    llp.setStyle(KoListStyle::DecimalItem);
    listStyle.setLevelProperties(llp);
    h1.setListStyle(&listStyle);

    QTextBlock block = m_doc->begin();
    h1.applyStyle(block);
    block = block.next();
    h1.applyStyle(block);
    block = block.next();
    h1.applyStyle(block);
    block = block.next();

    m_layout->layout();

    block = m_doc->begin();
    while (block.isValid()) {
        KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData());
        QVERIFY(data);
        QVERIFY(data->counterWidth() > 2);
        QVERIFY(data->counterPosition().x() > 100);
        QTextLine line = block.layout()->lineAt(0);
        QVERIFY(line.isValid());
        QCOMPARE(line.x(), (qreal)0);
        QCOMPARE(line.width() + data->counterWidth() + data->counterSpacing(), (qreal)200);
        block = block.next();
    }
}
Esempio n. 9
0
void TestDocumentLayout::testLetterSynchronization()
{
    // make numbering be  'y, z, aa, bb, cc'
    initForNewTest("a\nb\na\nb\nc");

    KoParagraphStyle h1;
    m_styleManager->add(&h1);
    KoListStyle listStyle;
    KoListLevelProperties llp;
    llp.setStyle(KoListStyle::AlphaLowerItem);
    llp.setLetterSynchronization(true);
    llp.setStartValue(25);
    listStyle.setLevelProperties(llp);
    h1.setListStyle(&listStyle);

    QTextBlock block = m_doc->begin();
    while (block.isValid()) {
        h1.applyStyle(block);
        block = block.next();
    }

    m_layout->layout();

    static const char *const values[] = { "y", "z", "aa", "bb", "cc" };
    block = m_doc->begin();
    int i = 0;
    while (block.isValid()) {
        KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData());
        QVERIFY(data);
        // qDebug() << "-> " << data->counterText() << endl;
        QCOMPARE(data->counterText(), QString(values[i++]));

        block = block.next();
    }
}
Esempio n. 10
0
int ShaderEdit::searchNextMatch( QTextBlock block, int start, QString open, QString close )
{
	int skipNext = 0;
	int i = start + 1;
	
	do {
		TextBlockData *data = (TextBlockData*)block.userData();
		if ( data ) {
			for ( ; i < data->parenthesis.count(); ++i ) {
				ParenthesisInfo pi = data->parenthesis[i];
				QString s = pi.character;
				if ( s == close ) {
					if ( skipNext > 0 )
						--skipNext;
					else
						return block.position() + pi.position;
				}
				else if ( s == open )
					++skipNext;
			}
		}
		block = block.next();
		i = 0;
	} while ( block.isValid() );
	
	return -1;
}
Esempio n. 11
0
void VPreviewManager::clearBlockObsoletePreviewInfo(long long p_timeStamp,
                                                    PreviewSource p_source)
{
    OrderedIntSet affectedBlocks;
    QVector<int> obsoleteBlocks;
    const QSet<int> &blocks = m_highlighter->getPossiblePreviewBlocks();
    for (auto i : blocks) {
        QTextBlock block = m_document->findBlockByNumber(i);
        if (!block.isValid()) {
            obsoleteBlocks.append(i);
            continue;
        }

        VTextBlockData *blockData = dynamic_cast<VTextBlockData *>(block.userData());
        if (!blockData) {
            continue;
        }

        if (blockData->clearObsoletePreview(p_timeStamp, p_source)) {
            affectedBlocks.insert(i, QMapDummyValue());
        }

        if (blockData->getPreviews().isEmpty()) {
            obsoleteBlocks.append(i);
        }
    }

    m_highlighter->clearPossiblePreviewBlocks(obsoleteBlocks);

    m_editor->relayout(affectedBlocks);
}
Esempio n. 12
0
void KPrAttributeHeight::updateCache(KPrAnimationCache *cache, KPrShapeAnimation *shapeAnimation, qreal value)
{
    qreal tx = 0.0, ty = 0.0;
    KoShape * shape = shapeAnimation->shape();
    KoTextBlockData * textBlockData = shapeAnimation->textBlockData();
    QTransform transform;
    if (textBlockData) {
        if (KoTextShapeData *textShapeData = dynamic_cast<KoTextShapeData*>(shape->userData())) {
            QTextDocument *textDocument = textShapeData->document();
            for (int i = 0; i < textDocument->blockCount(); i++) {
                QTextBlock textBlock = textDocument->findBlockByNumber(i);
                if (textBlock.userData() == textBlockData) {
                    QTextLayout *layout = textBlock.layout();
                    value = value * cache->pageSize().height() / layout->boundingRect().height();
                    tx = layout->minimumWidth() * cache->zoom() / 2;
                    ty = layout->boundingRect().height() * cache->zoom() / 2;
                }
            }
        }
    }
    else {
        value = value * cache->pageSize().height() / shape->size().height();
        tx = shape->size().width() * cache->zoom() / 2;
        ty = shape->size().height() * cache->zoom() / 2;
    }
    transform.translate(tx, ty).scale(1, value).translate(-tx, -ty);
    cache->update(shape, shapeAnimation->textBlockData(), "transform", transform);
}
Esempio n. 13
0
void KPrAttributeHeight::initCache(KPrAnimationCache *animationCache, int step, KPrShapeAnimation * shapeAnimation, qreal startValue, qreal endValue)
{
    qreal v1 = 0.0, v2 = 0.0, tx = 0.0, ty = 0.0;
    KoShape * shape = shapeAnimation->shape();
    KoTextBlockData * textBlockData = shapeAnimation->textBlockData();

    if (textBlockData) {
        if (KoTextShapeData *textShapeData = dynamic_cast<KoTextShapeData*>(shape->userData())) {
            QTextDocument *textDocument = textShapeData->document();
            for (int i = 0; i < textDocument->blockCount(); i++) {
                QTextBlock textBlock = textDocument->findBlockByNumber(i);
                if (textBlock.userData() == textBlockData) {
                    QTextLayout *layout = textBlock.layout();
                    v1 = startValue * animationCache->pageSize().height() / layout->boundingRect().height();
                    v2 = endValue * animationCache->pageSize().height() / layout->boundingRect().height();
                    tx = layout->minimumWidth() * animationCache->zoom() / 2;
                    ty = layout->boundingRect().height() * animationCache->zoom() / 2;
                }
            }
        }
    }
    else {
        v1 = startValue * animationCache->pageSize().height() / shape->size().height();
        v2 = endValue * animationCache->pageSize().height() / shape->size().height();
        tx = shape->size().width() * animationCache->zoom() / 2;
        ty = shape->size().height() * animationCache->zoom() / 2;
    }
    animationCache->init(step, shape, textBlockData, "transform", QTransform().translate(tx, ty).scale(1, v1).translate(-tx, -ty));
    animationCache->init(step + 1, shape, textBlockData, "transform", QTransform().translate(tx, ty).scale(1, v2).translate(-tx, -ty));
}
Esempio n. 14
0
bool CodeEditor::matchRightParenthesis(QTextBlock currentBlock, int i, int numRightParentheses)
{
    TextBlockData *data = static_cast<TextBlockData *>(currentBlock.userData());
    QVector<ParenthesisInfo *> parentheses = data->parentheses();

    int docPos = currentBlock.position();
    for (; i > -1 && parentheses.size() > 0; --i)
    {
        ParenthesisInfo *info = parentheses.at(i);
        if (info->character == ')')
        {
            ++numRightParentheses;
            continue;
        }
        if (info->character == '(' && numRightParentheses == 0)
        {
            createParenthesisSelection(docPos + info->position);
            return true;
        }
        else
        {
            --numRightParentheses;
        }
    }

    currentBlock = currentBlock.previous();
    if (currentBlock.isValid())
        return matchRightParenthesis(currentBlock, 0, numRightParentheses);

    return false;
}
Esempio n. 15
0
void TestDocumentLayout::testInvalidateLists()
{
    initForNewTest("Base\nListItem1\nListItem2");

    //KoParagraphStyle style;
    KoListStyle listStyle;
    KoListLevelProperties llp;
    llp.setStyle(KoListStyle::DecimalItem);
    listStyle.setLevelProperties(llp);
    //style.setListStyle(&listStyle);

    QTextBlock block = m_doc->begin().next();
    QVERIFY(block.isValid());
    listStyle.applyStyle(block);
    block = block.next();
    QVERIFY(block.isValid());
    listStyle.applyStyle(block);

    m_layout->layout();

    // check the list items were done (semi) properly
    block = m_doc->begin().next();
    QVERIFY(block.textList());
    KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData());
    QVERIFY(data);
    QVERIFY(data->hasCounterData());

    QTextCursor cursor(m_doc);
    cursor.setPosition(10); // list item1
    cursor.insertText("x");
    QCOMPARE(data->hasCounterData(), true); // nothing changed

    cursor.setPosition(22); // list item2
    cursor.insertText("x");
    QCOMPARE(data->hasCounterData(), true); // nothing changed
    cursor.deleteChar();
    QCOMPARE(data->hasCounterData(), true); // nothing changed

    cursor.setPosition(25); // end of doc
    cursor.insertBlock();
    block = cursor.block();
    QVERIFY(block.textList());
    QVERIFY(block.userData() == 0);

    QCOMPARE(data->hasCounterData(), false); // inserting a new block on this list made the list be invalidated
}
Esempio n. 16
0
void Editor::clearAllBookmarks()
{
  int line = 1;
  for ( QTextBlock block = m_textEdit->document()->begin(); block.isValid(); block = block.next(), line++ ) {
    BlockUserData *blockUserData = ( BlockUserData* ) block.userData();
    if ( blockUserData && blockUserData->bookmark )
      toggleBookmark ( line );
  }
}
Esempio n. 17
0
// static
bool ListItemsHelper::needsRecalc(QTextList *textList)
{
    Q_ASSERT(textList);
    QTextBlock tb = textList->item(0);
    KoTextBlockData *data = dynamic_cast<KoTextBlockData*>(tb.userData());
    if (data == 0)
        return true;
    return !data->hasCounterData();
}
Esempio n. 18
0
QString TextDocument::tooltip(const QPoint& point) const
{
    const int pos = documentLayout()->hitTest(point, Qt::FuzzyHit);
    const QTextBlock block = findBlock(pos);
    TextBlockMessageData* blockData = static_cast<TextBlockMessageData*>(block.userData());
    if (blockData)
        return formatEvents(blockData->data.getEvents());
    return QString();
}
Esempio n. 19
0
 // Constructs an iterator for the first token at the given block.
 // If there's no token in the block, the new iterator is invalid.
 TokenIterator( const QTextBlock & block ):
     blk(block),
     idx(-1)
 {
     if (block.isValid()) {
         data = static_cast<TextBlockData*>(block.userData());
         if (data && !data->tokens.empty())
             idx = 0;
     }
 }
Esempio n. 20
0
QTextBlock TextBlockUserData::testCollapse(const QTextBlock& block)
{
    QTextBlock info = block;
    if (block.userData() && static_cast<TextBlockUserData*>(block.userData())->collapseMode() == CollapseAfter)
        ;
    else if (block.next().userData()
             && static_cast<TextBlockUserData*>(block.next().userData())->collapseMode()
             == TextBlockUserData::CollapseThis)
        info = block.next();
    else
        return QTextBlock();
    int pos = static_cast<TextBlockUserData*>(info.userData())->collapseAtPos();
    if (pos < 0)
        return QTextBlock();
    QTextCursor cursor(info);
    cursor.setPosition(cursor.position() + pos);
    matchCursorForward(&cursor);
    return cursor.block();
}
void DocumentMarker::removeMark(TextEditor::ITextMark *mark)
{
    QTextBlock block = document->findBlockByNumber(mark->lineNumber() - 1);
    if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) {
        if (!data->removeMark(mark))
            qDebug() << "Could not find mark" << mark << "on line" << mark->lineNumber();
    }

    removeMarkFromMarksCache(mark);
    mark->setMarkableInterface(0);
}
Esempio n. 22
0
BaseTextDocument::~BaseTextDocument()
{
    QTextBlock block = m_document->begin();
    while (block.isValid()) {
        if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData()))
            data->documentClosing();
        block = block.next();
    }
    delete m_document;
    m_document = 0;
}
Esempio n. 23
0
QList<int> Editor::bookmarksList()
{
  QList<int> list;
  int line = 1;
  for ( QTextBlock block = m_textEdit->document()->begin(); block.isValid(); block = block.next(), line++ ) {
    BlockUserData *blockUserData = ( BlockUserData* ) block.userData();
    if ( blockUserData && blockUserData->bookmark )
      list << line;
  }
  return list;
}
Esempio n. 24
0
void Highlighter::contentsChange(int pos, int add, int rem)
{
    // Invalidate the cache where the text has changed
    const QTextBlock &lastBlock = document()->findBlock(pos + add - rem);
    QTextBlock block = document()->findBlock(pos);
    do {
        LanguageCache* cache=dynamic_cast<LanguageCache*>(block.userData());
        if (cache) cache->invalidate(pos-block.position());
        block = block.next();
    } while (block.isValid() && block < lastBlock);
}
Esempio n. 25
0
void ShaderEdit::cursorPositionChanged()
{
	QList<QTextEdit::ExtraSelection> selections;

	int curPos = editor->textCursor().positionInBlock();
	QTextBlock currentBlock = editor->textCursor().block();
	TextBlockData *data = (TextBlockData*)currentBlock.userData();
	if ( !data ) {
		editor->setExtraSelections( selections );
		return;
	}

	int searchPos = curPos;
	int matchPos = -1;
	for ( int i = 0; i < data->parenthesis.count(); ++i ) {
		ParenthesisInfo pi = data->parenthesis[i];
		if ( pi.position == curPos || pi.position == curPos - 1 ) {
			searchPos = currentBlock.position() + pi.position;
			QString s = pi.character;
			if ( s == "(" )
				matchPos = searchNextMatch( currentBlock, i, s, ")" );
			else if ( s == "{" )
				matchPos = searchNextMatch( currentBlock, i, s, "}" );
			else if ( s == "[" )
				matchPos = searchNextMatch( currentBlock, i, s, "]" );
			else if ( s == ")" )
				matchPos = searchPreviousMatch( currentBlock, i, s, "(" );
			else if ( s == "}" )
				matchPos = searchPreviousMatch( currentBlock, i, s, "{" );
			else if ( s == "]" )
				matchPos = searchPreviousMatch( currentBlock, i, s, "[" );
			break;
		}
	}

	if ( matchPos > -1 ) {
		QTextEdit::ExtraSelection selection;
		selection.format.setBackground( Qt::yellow );
		QTextCursor cursor = editor->textCursor();
		cursor.setPosition( searchPos );
		cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor );
		selection.cursor = cursor;
		selections.append( selection );
		
		cursor.setPosition( matchPos );
		cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor );
		selection.cursor = cursor;
		selections.append( selection );
	}
	
	editor->setExtraSelections( selections );
}
Esempio n. 26
0
int ScCodeEditor::indentationLevel(const QTextCursor & cursor)
{
    QTextDocument *doc = QPlainTextEdit::document();
    int startBlockNum = doc->findBlock(cursor.selectionStart()).blockNumber();

    QStack<int> stack;
    int level = 0;
    int blockNum = 0;
    QTextBlock block = QPlainTextEdit::document()->begin();
    while (block.isValid()) {
        if (level > 0) {
            stack.push(level);
            level = 0;
        }

        TextBlockData *data = static_cast<TextBlockData*>(block.userData());
        if (data) {
            int count = data->tokens.size();
            for (int idx = 0; idx < count; ++idx) {
                const Token & token = data->tokens[idx];
                switch (token.type) {
                case Token::OpeningBracket:
                    if (token.character != '(' || stack.size() || token.positionInBlock)
                        level += 1;
                    break;

                case Token::ClosingBracket:
                    if (level)
                        level -= 1;
                    else if(!stack.isEmpty()) {
                        stack.top() -= 1;
                        if (stack.top() <= 0)
                            stack.pop();
                    }
                    break;

                default:
                    ;
                }
            }
        }

        if (blockNum == startBlockNum)
            return stack.size();

        block = block.next();
        ++blockNum;
    }

    return -1;
}
Esempio n. 27
0
void KTextDocumentLayout::documentChanged(int position, int charsRemoved, int charsAdded)
{
    Q_UNUSED(charsRemoved);
    if (shapes().count() == 0) // nothing to do.
        return;

/*
    switch (document()->documentLayout()->property("KoTextRelayoutForPage").toInt()) {
    case KTextShapeData::NormalState:
        kDebug() << "KoTextRelayoutForPage in NormalState"; break;
    case KTextShapeData::LayoutCopyShape:
        kDebug() << "KoTextRelayoutForPage in LayoutCopyShape"; break;
    case KTextShapeData::LayoutOrig:
        kDebug() << "KoTextRelayoutForPage in LayoutOrig, skipping relayout"; break;
    }
*/
    if (document()->documentLayout()->property("KoTextRelayoutForPage").toInt() == KTextShapeData::LayoutOrig) {
        // don't refresh if we relayout after a relayout-for-page
        return;
    }

    int from = position;
    const int to = from + charsAdded;
    while (from < to) { // find blocks that have been added
        QTextBlock block = document()->findBlock(from);
        if (! block.isValid())
            break;
        if (from == block.position() && block.textList()) {
            KTextBlockData *data = dynamic_cast<KTextBlockData*>(block.userData());
            if (data)
                data->setCounterWidth(-1); // invalidate whole list.
        }

        from = block.position() + block.length();
    }

    foreach (KShape *shape, shapes()) {
        KTextShapeData *data = qobject_cast<KTextShapeData*>(shape->userData());
        Q_ASSERT(data);
        if (data && data->position() <= position && data->endPosition() >= position) {
            // found our (first) shape to re-layout
            data->foul();
            m_state->interrupted = true;
            scheduleLayout();
            return;
        }
    }
Esempio n. 28
0
void TestDocumentLayout::testBasicList()
{
    initForNewTest("Base\nListItem\nListItem2: The quick brown fox jums over the lazy dog.\nNormal\nNormal");

    KoParagraphStyle style;
    QTextBlock block = m_doc->begin();
    style.applyStyle(block);
    block = block.next();
    QVERIFY(block.isValid());

    KoListStyle listStyle;
    KoListLevelProperties level1;
    level1.setStyle(KoListStyle::Bullet);
    listStyle.setLevelProperties(level1);
    style.setListStyle(&listStyle);
    style.applyStyle(block); // make this a listStyle
    QVERIFY(block.textList());
    QCOMPARE(block.textList()->format().intProperty(QTextListFormat::ListStyle), (int) KoListStyle::Bullet);
    block = block.next();
    QVERIFY(block.isValid());
    style.applyStyle(block); // make this a listStyle

    m_layout->layout();
    QTextLayout *blockLayout = m_block.layout();

    QCOMPARE(blockLayout->lineAt(0).x(), 0.0);
    block = m_doc->begin().next();
    QVERIFY(block.isValid());
    blockLayout = block.layout(); // parag 2
    KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData());
    QVERIFY(data);
    qreal counterSpacing = data->counterSpacing();
    QVERIFY(counterSpacing > 0.);
    // 12 is hardcoded to be the width of a discitem (taken from the default font):
    QCOMPARE(blockLayout->lineAt(0).x(), 12.0 + counterSpacing);
    block = block.next();
    QVERIFY(block.isValid());
    blockLayout = block.layout(); // parag 3
    QCOMPARE(blockLayout->lineAt(0).x(), 12.0 + counterSpacing);
    QVERIFY(blockLayout->lineCount() > 1);
    QCOMPARE(blockLayout->lineAt(1).x(), 12.0 + counterSpacing); // make sure not only the first line is indented
    block = block.next();
    QVERIFY(block.isValid());
    blockLayout = block.layout(); // parag 4
    QCOMPARE(blockLayout->lineAt(0).x(), 0.0);
}
Esempio n. 29
0
 // Constructs an iterator for the token that starts at, or contains the given position.
 // If there is no such token, the new iterator is invalid.
 TokenIterator( const QTextBlock & block, int positionInBlock ):
     blk(block)
 {
     if (block.isValid()) {
         data = static_cast<TextBlockData*>(block.userData());
         idx = data ? data->tokens.size() : 0;
         while (idx--)
         {
             const Token & token = data->tokens[idx];
             if (token.positionInBlock > positionInBlock)
                 continue;
             else if (token.positionInBlock == positionInBlock || token.positionInBlock + token.length > positionInBlock)
                 break;
         }
     }
     else
         idx = -1;
 }
Esempio n. 30
0
void TestDocumentLayout::testAutoRestartList()
{
    initForNewTest("Humans\nGandhi\nEinstein\nInventions\nCar\nToilet\nLaboratory\n");

    KoParagraphStyle h1;
    m_styleManager->add(&h1);
    KoParagraphStyle h2;
    m_styleManager->add(&h2);

    KoListStyle listStyle;
    KoListLevelProperties llp = listStyle.levelProperties(1);
    llp.setStyle(KoListStyle::DecimalItem);
    llp.setStartValue(1);
    llp.setListItemSuffix(".");
    listStyle.setLevelProperties(llp);
    h1.setListStyle(&listStyle);

    KoListStyle listStyle2;
    KoListLevelProperties llp2 = listStyle2.levelProperties(2);
    llp2.setStyle(KoListStyle::DecimalItem);
    llp2.setStartValue(1);
    llp2.setDisplayLevel(2);
    llp2.setListItemSuffix(".");
    listStyle2.setLevelProperties(llp2);
    h2.setListStyle(&listStyle2);

    QTextBlock block = m_doc->begin();
    h1.applyStyle(block);
    block = block.next(); h2.applyStyle(block);
    block = block.next(); h2.applyStyle(block);
    block = block.next(); h1.applyStyle(block); // inventions
    block = block.next(); h2.applyStyle(block);
    QTextBlock car = block;
    block = block.next(); h2.applyStyle(block);
    block = block.next(); h2.applyStyle(block);

    m_layout->layout();

    KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(car.userData());
    QVERIFY(data);
    // qDebug() << data->counterText();
    QCOMPARE(data->counterText(), QString("2.1."));
}