void ParagraphSettingsDialog::slotApply() { if (!m_styleChanged) { return; } KoParagraphStyle chosenStyle; m_paragraphGeneral->save(&chosenStyle); QTextCharFormat cformat; QTextBlockFormat format; chosenStyle.KoCharacterStyle::applyStyle(cformat); chosenStyle.applyStyle(format); KoListLevelProperties llp; if (chosenStyle.listStyle()) { llp = chosenStyle.listStyle()->levelProperties(chosenStyle.listStyle()->listLevels().first()); } else { llp.setStyle(KoListStyle::None); } m_editor->applyDirectFormatting(cformat, format, llp); m_styleChanged = false; }
QString KoTextWriter::saveParagraphStyle(const QTextBlockFormat &blockFormat, const QTextCharFormat &charFormat, KoStyleManager * styleManager, KoShapeSavingContext &context) { KoParagraphStyle *defaultParagraphStyle = styleManager->defaultParagraphStyle(); KoParagraphStyle *originalParagraphStyle = styleManager->paragraphStyle(blockFormat.intProperty(KoParagraphStyle::StyleId)); if (!originalParagraphStyle) originalParagraphStyle = defaultParagraphStyle; QString generatedName; QString displayName = originalParagraphStyle->name(); QString internalName = QString(QUrl::toPercentEncoding(displayName, "", " ")).replace('%', '_'); // we'll convert the blockFormat to a KoParagraphStyle to check for local changes. KoParagraphStyle paragStyle(blockFormat, charFormat); if (paragStyle == (*originalParagraphStyle)) { // This is the real, unmodified character style. // TODO zachmann: this could use the name of the saved style without saving it again // therefore we would need to store that information in the saving context if (originalParagraphStyle != defaultParagraphStyle) { KoGenStyle style(KoGenStyle::ParagraphStyle, "paragraph"); originalParagraphStyle->saveOdf(style, context); generatedName = context.mainStyles().insert(style, internalName, KoGenStyles::DontAddNumberToName); } } else { // There are manual changes... We'll have to store them then KoGenStyle style(KoGenStyle::ParagraphAutoStyle, "paragraph", internalName); if (context.isSet(KoShapeSavingContext::AutoStyleInStyleXml)) style.setAutoStyleInStylesDotXml(true); if (originalParagraphStyle) { paragStyle.removeDuplicates(*originalParagraphStyle); paragStyle.setParentStyle(originalParagraphStyle); } paragStyle.saveOdf(style, context); generatedName = context.mainStyles().insert(style, "P"); } return generatedName; }
void ParagraphGeneral::save(KoParagraphStyle *style) { KoParagraphStyle *savingStyle; if (style == 0) { if (m_style == 0) return; else savingStyle = m_style; } else savingStyle = style; m_paragraphIndentSpacing->save(savingStyle); m_paragraphLayout->save(savingStyle); m_paragraphBulletsNumbers->save(savingStyle); m_paragraphDecorations->save(savingStyle); savingStyle->setNextStyle(widget.nextStyle->itemData(widget.nextStyle->currentIndex()).toInt()); emit styleAltered(savingStyle); /* int parentStyleId = widget.inheritStyle->itemData(widget.inheritStyle->currentIndex()).toInt(); if (parentStyleId == 0) m_style->setParentStyle(0); else { foreach(KoParagraphStyle *style, m_paragraphStyles) { if (style->styleId() == parentStyleId) { m_style->setParentStyle(style); break; } } } */ }
void StylesWidget::setCurrentFormat(const QTextBlockFormat &format) { if (format == m_currentBlockFormat) return; m_currentBlockFormat = format; int id = m_currentBlockFormat.intProperty(KoParagraphStyle::StyleId); // bool unchanged = true; KoParagraphStyle *usedStyle = 0; if (m_styleManager) usedStyle = m_styleManager->paragraphStyle(id); if (usedStyle) { foreach(int property, m_currentBlockFormat.properties().keys()) { if (property == QTextFormat::ObjectIndex) continue; if (property == KoParagraphStyle::ListStyleId) continue; if (m_currentBlockFormat.property(property) != usedStyle->value(property)) { // unchanged = false; break; } } } m_blockSignals = true; // m_stylesModel->setCurrentParagraphStyle(id, unchanged); m_blockSignals = false; widget.stylesView->setCurrentIndex(m_stylesModel->indexOf(*usedStyle)); }
QImage KoStyleThumbnailer::thumbnail(KoCharacterStyle *characterStyle, KoParagraphStyle *paragraphStyle, QSize size, bool recreateThumbnail, KoStyleThumbnailerFlags flags) { if ((flags & UseStyleNameText) && (!characterStyle || characterStyle->name().isNull())) { return QImage(); } else if ((! (flags & UseStyleNameText)) && d->thumbnailText.isEmpty()) { return QImage(); } else if (characterStyle == 0) { return QImage(); } if (!size.isValid() || size.isNull()) { size = d->defaultSize; } QString imageKey = "c_" + QString::number(reinterpret_cast<unsigned long>(characterStyle)) + "_" + "p_" + QString::number(reinterpret_cast<unsigned long>(paragraphStyle)) + "_" + QString::number(size.width()) + "_" + QString::number(size.height()); if (!recreateThumbnail && d->thumbnailCache.object(imageKey)) { return QImage(*(d->thumbnailCache.object(imageKey))); } QImage *im = new QImage(size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); im->fill(QColor(Qt::transparent).rgba()); QTextCursor cursor(d->thumbnailHelperDocument); QTextCharFormat format; // Default to black as text color, to match what KoTextLayoutArea::paint(...) // does, setting solid black if no brush is set. Otherwise the UI text color // would be used, which might be too bright with dark UI color schemes format.setForeground(QColor(Qt::black)); KoCharacterStyle *characterStyleClone = characterStyle->clone(); characterStyleClone->applyStyle(format); cursor.select(QTextCursor::Document); cursor.setBlockFormat(QTextBlockFormat()); cursor.setBlockCharFormat(QTextCharFormat()); cursor.setCharFormat(QTextCharFormat()); if (paragraphStyle) { KoParagraphStyle *paragraphStyleClone = paragraphStyle->clone(); // paragraphStyleClone->KoCharacterStyle::applyStyle(format); QTextBlock block = cursor.block(); paragraphStyleClone->applyStyle(block, true); delete paragraphStyleClone; paragraphStyleClone = 0; } if (flags & UseStyleNameText) { cursor.insertText(characterStyleClone->name(), format); } else { cursor.insertText(d->thumbnailText, format); } layoutThumbnail(size, im, flags); d->thumbnailCache.insert(imageKey, im); delete characterStyleClone; return QImage(*im); }
int KoBibliographyInfo::styleNameToStyleId(KoTextSharedLoadingData *sharedLoadingData, const QString &styleName) { KoParagraphStyle * style = sharedLoadingData->paragraphStyle(styleName, true); if (style) { return style->styleId(); } return 0; }
void ChangeFollower::processUpdates(const QList<int> &changedStyles) { KoStyleManager *sm = m_styleManager.data(); if (!sm) { // since the stylemanager would be the one calling this method, I doubt this // will ever happen. But better safe than sorry.. deleteLater(); return; } // optimization strategy; store the formatid of the formats we checked into // a qset for 'hits' and 'ignores' and avoid the copying of the format // (fragment.charFormat() / block.blockFormat()) when the formatId is // already checked previosly QTextCursor cursor(m_document); QTextBlock block = cursor.block(); while (block.isValid()) { QTextBlockFormat bf = block.blockFormat(); int id = bf.intProperty(KoParagraphStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { cursor.setPosition(block.position()); KoParagraphStyle *style = sm->paragraphStyle(id); Q_ASSERT(style); style->applyStyle(bf); cursor.setBlockFormat(bf); } QTextCharFormat cf = block.charFormat(); id = cf.intProperty(KoCharacterStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { KoCharacterStyle *style = sm->characterStyle(id); Q_ASSERT(style); style->applyStyle(block); } QTextBlock::iterator iter = block.begin(); while (! iter.atEnd()) { QTextFragment fragment = iter.fragment(); cf = fragment.charFormat(); id = cf.intProperty(KoCharacterStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { // create selection cursor.setPosition(fragment.position()); cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor); KoCharacterStyle *style = sm->characterStyle(id); Q_ASSERT(style); style->applyStyle(cf); cursor.mergeCharFormat(cf); } iter++; } block = block.next(); } }
void NewStyleWidget::createButtonPressed() { if (widget.character->isChecked()) { KoCharacterStyle *style = new KoCharacterStyle(); style->setName(widget.name->text()); emit newCharacterStyle(style); } else { KoParagraphStyle *style = new KoParagraphStyle(); style->setName(widget.name->text()); emit newParagraphStyle(style); } }
QImage KoStyleThumbnailer::thumbnail(KoParagraphStyle *style, QSize size, bool recreateThumbnail, KoStyleThumbnailerFlags flags) { if ((flags & UseStyleNameText) && (!style || style->name().isNull())) { return QImage(); } else if ((! (flags & UseStyleNameText)) && d->thumbnailText.isEmpty()) { return QImage(); } if (!size.isValid() || size.isNull()) { size = d->defaultSize; } QString imageKey = "p_" + QString::number(reinterpret_cast<unsigned long>(style)) + "_" + QString::number(size.width()) + "_" + QString::number(size.height()); if (!recreateThumbnail && d->thumbnailCache.object(imageKey)) { return QImage(*(d->thumbnailCache.object(imageKey))); } QImage *im = new QImage(size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); im->fill(QColor(Qt::transparent).rgba()); KoParagraphStyle *clone = style->clone(); //TODO: make the following real options //we ignore these properties when the thumbnail would not be sufficient to preview properly the whole paragraph with margins. clone->setMargin(QTextLength(QTextLength::FixedLength, 0)); clone->setPadding(0); // QTextCursor cursor(d->thumbnailHelperDocument); cursor.select(QTextCursor::Document); cursor.setBlockFormat(QTextBlockFormat()); cursor.setBlockCharFormat(QTextCharFormat()); cursor.setCharFormat(QTextCharFormat()); QTextBlock block = cursor.block(); clone->applyStyle(block, true); QTextCharFormat format; // Default to black as text color, to match what KoTextLayoutArea::paint(...) // does, setting solid black if no brush is set. Otherwise the UI text color // would be used, which might be too bright with dark UI color schemes format.setForeground(QColor(Qt::black)); clone->KoCharacterStyle::applyStyle(format); if (flags & UseStyleNameText) { cursor.insertText(clone->name(), format); } else { cursor.insertText(d->thumbnailText, format); } layoutThumbnail(size, im, flags); d->thumbnailCache.insert(imageKey, im); delete clone; return QImage(*im); }
void TestBorder::testBorder() { KoParagraphStyle style; style.setLeftBorderWidth(4.0); style.setLeftBorderSpacing(2.0); style.setLeftInnerBorderWidth(1.0); style.setTopBorderWidth(6.0); style.setTopBorderSpacing(7.0); style.setTopInnerBorderWidth(8.0); QTextBlockFormat format; style.applyStyle(format); KoTextBlockBorderData data(QRectF(10, 10, 100, 100)); data.setEdge(KoTextBlockBorderData::Left, format, KoParagraphStyle::LeftBorderStyle, KoParagraphStyle::LeftBorderWidth, KoParagraphStyle::LeftBorderColor, KoParagraphStyle::LeftBorderSpacing, KoParagraphStyle::LeftInnerBorderWidth); data.setEdge(KoTextBlockBorderData::Top, format, KoParagraphStyle::TopBorderStyle, KoParagraphStyle::TopBorderWidth, KoParagraphStyle::TopBorderColor, KoParagraphStyle::TopBorderSpacing, KoParagraphStyle::TopInnerBorderWidth); //QCOMPARE(QRectF(10, 10, 100, 80), data.rect()); QCOMPARE(7., data.inset(KoTextBlockBorderData::Left)); QCOMPARE(0., data.inset(KoTextBlockBorderData::Right)); QCOMPARE(21., data.inset(KoTextBlockBorderData::Top)); QCOMPARE(0., data.inset(KoTextBlockBorderData::Bottom)); }
void TestStyleManager::testAddAppliedParagraphStyle() { // Create style, apply it, then add it to the manager. KoParagraphStyle paragraphStyle; QTextBlock block = m_doc->begin(); paragraphStyle.applyStyle(block); m_styleManager->beginEdit(); m_styleManager->add(¶graphStyle); m_styleManager->endEdit(); // Check that style is marked as used. QVERIFY(m_styleManager->usedParagraphStyles().contains(paragraphStyle.styleId())); }
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); }
void ValidParentStylesProxyModel::createMapping() { if (!m_styleManager || !m_sourceModel) { return; } m_sourceToProxy.clear(); m_proxyToSource.clear(); for(int i = 0; i < m_sourceModel->rowCount(QModelIndex()); ++i) { QModelIndex index = m_sourceModel->index(i, 0, QModelIndex()); int id = (int)index.internalId(); KoParagraphStyle *paragraphStyle = m_styleManager->paragraphStyle(id); if (paragraphStyle) { bool ok = true; KoParagraphStyle *testStyle = paragraphStyle; while (testStyle && ok) { ok = testStyle->styleId() != m_currentChildStyleId; testStyle = testStyle->parentStyle(); } if (!ok) { continue; //we cannot inherit ourself even indirectly through the parent chain } m_proxyToSource.append(i); //the style is ok for parenting } else { KoCharacterStyle *characterStyle = m_styleManager->characterStyle(id); if (characterStyle) { bool ok = true; KoCharacterStyle *testStyle = characterStyle; while (testStyle && ok) { ok = testStyle->styleId() != m_currentChildStyleId; testStyle = testStyle->parentStyle(); } if (!ok) { continue; //we cannot inherit ourself even indirectly through the parent chain } m_proxyToSource.append(i); //the style is ok for parenting } } } m_sourceToProxy.fill(-1, m_sourceModel->rowCount(QModelIndex())); for(int i = 0; i < m_proxyToSource.count(); ++i) { m_sourceToProxy[m_proxyToSource.at(i)] = i; } }
void TestStyleManager::testApplyAddedParagraphStyle() { QSignalSpy appliedSignalSpy(m_styleManager, SIGNAL(styleApplied(const KoParagraphStyle*))); // Create style, add it to the manager, then apply it. KoParagraphStyle paragraphStyle; m_styleManager->beginEdit(); m_styleManager->add(¶graphStyle); m_styleManager->endEdit(); QTextBlock block = m_doc->begin(); paragraphStyle.applyStyle(block); // Check that style is marked as used and that the correct signal was emitted. QVERIFY(m_styleManager->usedParagraphStyles().contains(paragraphStyle.styleId())); QCOMPARE(appliedSignalSpy.count(), 1); QCOMPARE(appliedSignalSpy.at(0).at(0).value<const KoParagraphStyle *>(), ¶graphStyle); }
void ParagraphSettingsDialog::slotApply() { emit startMacro(i18n("Paragraph Settings\n")); KoParagraphStyle chosenStyle; m_paragraphGeneral->save(&chosenStyle); QTextBlockFormat format; chosenStyle.applyStyle(format); m_cursor->mergeBlockFormat(format); if (chosenStyle.listStyle()) { ChangeListCommand *cmd = new ChangeListCommand(*m_cursor, chosenStyle.listStyle(), 0, ChangeListCommand::MergeWithAdjacentList); m_tool->addCommand(cmd); } else { QTextList *list = m_cursor->block().textList(); if (list) { // then remove it. list->remove(m_cursor->block()); } } emit stopMacro(); }
void TestStyles::testCopyParagraphStyle() { QTextLength length1(QTextLength::FixedLength, 10.0); QTextLength length2(QTextLength::FixedLength, 20.0); QTextLength length3(QTextLength::FixedLength, 30.0); KoParagraphStyle style1; KoParagraphStyle style2; style2.setParentStyle(&style1); style1.setLeftMargin(length1); style1.setRightMargin(length3); style2.setRightMargin(length2); KoParagraphStyle newStyle; newStyle.copyProperties(&style2); QCOMPARE(newStyle.leftMargin(), 10.0); QCOMPARE(newStyle.rightMargin(), 20.0); }
int KoTableOfContentsGeneratorInfo::styleNameToStyleId(KoTextSharedLoadingData *sharedLoadingData, QString styleName) { //find styleId of a style based on its style:name property KoParagraphStyle * style = sharedLoadingData->paragraphStyle(styleName, true); if (style) { return style->styleId(); } //if the previous way of finding styles fails fall back on using style:display-name property of a style QList<KoParagraphStyle *> paragraphStyles = sharedLoadingData->paragraphStyles(true); QList<KoParagraphStyle *>::const_iterator iter = paragraphStyles.constBegin(); for (; iter != paragraphStyles.constEnd(); ++iter) { if ((*iter)->name() == styleName) { return (*iter)->styleId(); } } return 0; }
void TestStyleManager::testAddRemoveParagraphStyle() { // Add paragraph style. KoParagraphStyle paragraphStyle; paragraphStyle.setName("Test Paragraph Style"); QSignalSpy addSignalSpy(m_styleManager, SIGNAL(styleAdded(KoParagraphStyle*))); m_styleManager->beginEdit(); m_styleManager->add(¶graphStyle); m_styleManager->endEdit(); QVERIFY(paragraphStyle.styleId() > 0); QVERIFY(!m_styleManager->usedParagraphStyles().contains(paragraphStyle.styleId())); QCOMPARE(m_styleManager->paragraphStyles().count(¶graphStyle), 1); QCOMPARE(m_styleManager->paragraphStyle(paragraphStyle.styleId()), ¶graphStyle); QCOMPARE(m_styleManager->paragraphStyle("Test Paragraph Style"), ¶graphStyle); QCOMPARE(addSignalSpy.count(), 1); QCOMPARE(addSignalSpy.at(0).at(0).value<KoParagraphStyle *>(), ¶graphStyle); // Remove paragraph style. QSignalSpy removeSignalSpy(m_styleManager, SIGNAL(styleRemoved(KoParagraphStyle*))); m_styleManager->beginEdit(); m_styleManager->remove(¶graphStyle); m_styleManager->endEdit(); QVERIFY(!m_styleManager->paragraphStyles().contains(¶graphStyle)); QVERIFY(!m_styleManager->paragraphStyle(paragraphStyle.styleId())); QVERIFY(!m_styleManager->paragraphStyle("Test Paragraph Style")); QCOMPARE(removeSignalSpy.count(), 1); QCOMPARE(removeSignalSpy.at(0).at(0).value<KoParagraphStyle *>(), ¶graphStyle); }
bool KPrPlaceholderTextStrategy::loadOdf( const KoXmlElement & element, KoShapeLoadingContext & context ) { if (KoTextSharedLoadingData *textSharedData = dynamic_cast<KoTextSharedLoadingData *>(context.sharedData(KOTEXT_SHARED_LOADING_ID))) { KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("TextShapeID"); Q_ASSERT(factory); delete m_textShape; m_textShape = factory->createDefaultShape(context.documentResourceManager()); KoTextShapeData *shapeData = qobject_cast<KoTextShapeData*>(m_textShape->userData()); shapeData->document()->setUndoRedoEnabled(false); QTextDocument *document = shapeData->document(); QTextCursor cursor(document); QTextBlock block = cursor.block(); const QString styleName = element.attributeNS(KoXmlNS::presentation, "style-name"); if (!styleName.isEmpty()) { const KoXmlElement *style = context.odfLoadingContext().stylesReader().findStyle(styleName, "presentation", context.odfLoadingContext().useStylesAutoStyles()); if (style) { KoParagraphStyle paragraphStyle; paragraphStyle.loadOdf(style, context); paragraphStyle.applyStyle(block, false); // TODO t.zachmann is the false correct? } } const QString textStyleName = element.attributeNS(KoXmlNS::draw, "text-style-name"); if (!textStyleName.isEmpty()) { KoParagraphStyle *style = textSharedData->paragraphStyle(textStyleName, context.odfLoadingContext().useStylesAutoStyles()); if (style) { style->applyStyle(block, false); // TODO t.zachmann is the false correct? } } cursor.insertText(text()); shapeData->setDirty(); shapeData->document()->setUndoRedoEnabled(true); } return true; }
void TestStyles::testApplyParagraphStyle() { KoParagraphStyle style; style.setStyleId(1001); QTextBlockFormat format; QCOMPARE(format.properties().count(), 0); style.applyStyle(format); QCOMPARE(format.properties().count(), 2); // the styleId and nextStyleId QCOMPARE(format.property(KoParagraphStyle::StyleId).toInt(), 1001); QCOMPARE(format.property(KoParagraphStyle::NextStyle).toInt(), 1001); style.setName("name"); style.setAlignment(Qt::AlignRight); style.applyStyle(format); QCOMPARE(format.properties().count(), 3); QCOMPARE(format.alignment(), Qt::AlignRight); }
void TestStyles::testTabsStorage() { KoParagraphStyle paragStyle; QVector<KoText::Tab> tabs; paragStyle.setTabPositions(tabs); QCOMPARE(paragStyle.tabPositions().count(), 0); KoText::Tab tab; tabs.append(tab); KoText::Tab tab2; tab2.position = 10; tabs.append(tab2); paragStyle.setTabPositions(tabs); QCOMPARE(paragStyle.tabPositions().count(), 2); QCOMPARE(paragStyle.tabPositions()[0], tab); QCOMPARE(paragStyle.tabPositions()[1], tab2); }
void TestStyles::testUnapplyStyle() { // Used to test OverlineColor style QColor testOverlineColor(255, 128, 64); KoCharacterStyle::LineWeight testOverlineWeight = KoCharacterStyle::ThickLineWeight; qreal testOverlineWidth = 1.5; // in this test we should avoid testing any of the hardcodedDefaultProperties; see KoCharacterStyle for details! KoParagraphStyle headers; headers.setOverlineColor(testOverlineColor); headers.setOverlineMode(KoCharacterStyle::ContinuousLineMode); headers.setOverlineStyle(KoCharacterStyle::DottedLine); headers.setOverlineType(KoCharacterStyle::DoubleLine); headers.setOverlineWidth(testOverlineWeight, testOverlineWidth); headers.setFontWeight(QFont::Bold); headers.setAlignment(Qt::AlignCenter); KoParagraphStyle head1; head1.setParentStyle(&headers); head1.setLeftMargin(QTextLength(QTextLength::FixedLength, 40)); QTextDocument doc; doc.setPlainText("abc"); QTextBlock block = doc.begin(); head1.applyStyle(block); QTextCursor cursor(block); QTextBlockFormat bf = cursor.blockFormat(); KoParagraphStyle bfStyle (bf, cursor.charFormat()); QCOMPARE(bf.alignment(), Qt::AlignCenter); QCOMPARE(bfStyle.leftMargin(), 40.); QTextCharFormat cf = cursor.charFormat(); QCOMPARE(cf.colorProperty(KoCharacterStyle::OverlineColor), testOverlineColor); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineMode), (int) KoCharacterStyle::ContinuousLineMode); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineStyle), (int) KoCharacterStyle::DottedLine); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineType), (int) KoCharacterStyle::DoubleLine); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineWeight), (int) testOverlineWeight); QCOMPARE(cf.doubleProperty(KoCharacterStyle::OverlineWidth), testOverlineWidth); head1.unapplyStyle(block); bf = cursor.blockFormat(); QCOMPARE(bf.hasProperty(QTextFormat::BlockAlignment), false); QCOMPARE(bf.hasProperty(QTextFormat::BlockLeftMargin), false); cf = cursor.charFormat(); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineColor), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineMode), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineStyle), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineType), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWeight), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWidth), false); doc.clear(); block = doc.begin(); head1.applyStyle(block); bf = cursor.blockFormat(); KoParagraphStyle bfStyle2 (bf, cursor.charFormat()); QCOMPARE(bf.alignment(), Qt::AlignCenter); QCOMPARE(bfStyle2.leftMargin(), 40.); cf = cursor.charFormat(); //QCOMPARE(cf.fontOverline(), true); QCOMPARE(cf.colorProperty(KoCharacterStyle::OverlineColor), testOverlineColor); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineMode), (int) KoCharacterStyle::ContinuousLineMode); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineStyle), (int) KoCharacterStyle::DottedLine); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineType), (int) KoCharacterStyle::DoubleLine); QCOMPARE(cf.intProperty(KoCharacterStyle::OverlineWeight), (int) testOverlineWeight); QCOMPARE(cf.doubleProperty(KoCharacterStyle::OverlineWidth), testOverlineWidth); head1.unapplyStyle(block); bf = cursor.blockFormat(); QCOMPARE(bf.hasProperty(QTextFormat::BlockAlignment), false); QCOMPARE(bf.hasProperty(QTextFormat::BlockLeftMargin), false); cf = cursor.charFormat(); //QCOMPARE(cf.hasProperty(QTextFormat::FontOverline), false); doc.setHtml("bla bla<i>italic</i>enzo"); block = doc.begin(); head1.applyStyle(block); bf = cursor.blockFormat(); KoParagraphStyle bfStyle3(bf, cursor.charFormat()); QCOMPARE(bf.alignment(), Qt::AlignCenter); QCOMPARE(bfStyle3.leftMargin(), 40.); cf = cursor.charFormat(); //QCOMPARE(cf.fontOverline(), true); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineColor), true); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineMode), true); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineStyle), true); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineType), true); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWeight), true); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWidth), true); cursor.setPosition(7); cursor.setPosition(12, QTextCursor::KeepAnchor); QTextCharFormat italic; italic.setFontItalic(true); cursor.mergeCharFormat(italic); cursor.setPosition(8); cf = cursor.charFormat(); QCOMPARE(cf.fontItalic(), true); cursor.setPosition(0); head1.unapplyStyle(block); cursor.setPosition(0); bf = cursor.blockFormat(); QCOMPARE(bf.hasProperty(QTextFormat::BlockAlignment), false); QCOMPARE(bf.hasProperty(QTextFormat::BlockLeftMargin), false); cf = cursor.charFormat(); //QCOMPARE(cf.hasProperty(QTextFormat::FontOverline), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineColor), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineMode), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineStyle), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineType), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWeight), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWidth), false); cursor.setPosition(8); cf = cursor.charFormat(); //QCOMPARE(cf.hasProperty(QTextFormat::FontOverline), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineColor), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineMode), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineStyle), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineType), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWeight), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWidth), false); QCOMPARE(cf.fontItalic(), true); cursor.setPosition(12); cf = cursor.charFormat(); //QCOMPARE(cf.hasProperty(QTextFormat::FontOverline), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineColor), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineMode), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineStyle), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineType), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWeight), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWidth), false); QCOMPARE(cf.fontItalic(), true); cursor.setPosition(13); cf = cursor.charFormat(); //QCOMPARE(cf.hasProperty(QTextFormat::FontOverline), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineColor), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineMode), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineStyle), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineType), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWeight), false); QCOMPARE(cf.hasProperty(KoCharacterStyle::OverlineWidth), false); QCOMPARE(cf.hasProperty(QTextFormat::FontWeight), false); QCOMPARE(cf.hasProperty(QTextFormat::FontItalic), false); }
void TestTableLayout::setupTest(const QString &mergedText, const QString &topRightText, const QString &midRightText, const QString &bottomLeftText, const QString &bottomMidText, const QString &bottomRightText, KoTableStyle* tableStyle) { QTextCursor cursor = setupTest(); KoParagraphStyle style; style.setStyleId(101); // needed to do manually since we don't use the stylemanager style.applyStyle(m_block); QTextTableFormat tableFormat; if (tableStyle) tableStyle->applyStyle(tableFormat); m_table = cursor.insertTable(3,3,tableFormat); m_table->mergeCells(0,0,2,2); if (mergedText.length() > 0) { m_table->cellAt(0,0).firstCursorPosition().insertText(mergedText); QTextBlock b2 = m_table->cellAt(0,0).firstCursorPosition().block(); while (b2.isValid()) { style.applyStyle(b2); b2 = b2.next(); } } if (topRightText.length() > 0) { m_table->cellAt(0,2).firstCursorPosition().insertText(topRightText); QTextBlock b2 = m_table->cellAt(0,2).firstCursorPosition().block(); while (b2.isValid()) { style.applyStyle(b2); b2 = b2.next(); } } if (midRightText.length() > 0) { m_table->cellAt(1,2).firstCursorPosition().insertText(midRightText); QTextBlock b2 = m_table->cellAt(1,2).firstCursorPosition().block(); while (b2.isValid()) { style.applyStyle(b2); b2 = b2.next(); } } if (bottomLeftText.length() > 0) { m_table->cellAt(2,0).firstCursorPosition().insertText(bottomLeftText); QTextBlock b2 = m_table->cellAt(2,0).firstCursorPosition().block(); while (b2.isValid()) { style.applyStyle(b2); b2 = b2.next(); } } if (bottomMidText.length() > 0) { m_table->cellAt(2,1).firstCursorPosition().insertText(bottomMidText); QTextBlock b2 = m_table->cellAt(2,1).firstCursorPosition().block(); while (b2.isValid()) { style.applyStyle(b2); b2 = b2.next(); } } if (bottomRightText.length() > 0) { m_table->cellAt(2,2).firstCursorPosition().insertText(bottomRightText); QTextBlock b2 = m_table->cellAt(2,2).firstCursorPosition().block(); while (b2.isValid()) { style.applyStyle(b2); b2 = b2.next(); } } }
KoFilter::ConversionStatus AsciiImport::convert(const QByteArray& from, const QByteArray& to) { // check for proper conversion if (to != "application/vnd.oasis.opendocument.text" || from != "text/plain") { return KoFilter::NotImplemented; } QFile in(m_chain->inputFile()); if (!in.open(QIODevice::ReadOnly)) { kError(30502) << "Unable to open input file!" << endl; in.close(); return KoFilter::FileNotFound; } #ifdef OUTPUT_AS_ODT_FILE #else KoDocument* document = m_chain->outputDocument(); if (!document) return KoFilter::StupidError; KWDocument *outputDoc = qobject_cast<KWDocument*>(document); outputDoc->setOutputMimeType(to); //outputDoc->setSaveInBatchMode(true); QPointer<KoUpdater> loadUpdater = outputDoc->progressUpdater()->startSubtask(2, "load"); loadUpdater->setRange(0, in.size()); QPointer<KoUpdater> layoutUpdater = outputDoc->progressUpdater()->startSubtask(3, "layout"); #endif // try to read 100000 bytes so we can be quite sure the guessed encoding is correct. // this code is inspired by the kate encoding guessing first try UTF-8 QByteArray data = in.read(100000); in.seek(0); QTextCodec *codec = QTextCodec::codecForName("UTF-8"); if (!checkEncoding(codec, data)) { KEncodingProber prober(KEncodingProber::Universal); prober.feed(data); kDebug(30502) << "guessed" << prober.encoding() << prober.confidence(); if (prober.confidence() > 0.5) codec = QTextCodec::codecForName(prober.encoding()); if (!codec || !checkEncoding(codec, data )) { codec = QTextCodec::codecForName("ISO 8859-15"); if (!checkEncoding(codec, data)) codec = QTextCodec::codecForName("UTF-8"); } } int paragraphStrategy = 0; if (!m_chain->manager()->getBatchMode()) { QPointer<AsciiImportDialog> dialog = new AsciiImportDialog(codec->name(), QApplication::activeWindow()); if (!dialog) { in.close(); return KoFilter::StupidError; } if (!dialog->exec()) { in.close(); return KoFilter::UserCancelled; } codec = dialog->getCodec(); paragraphStrategy = dialog->getParagraphStrategy(); } if (!codec) return KoFilter::StupidError; kDebug(30502) << "Charset used:" << codec->name(); #ifdef OUTPUT_AS_ODT_FILE KoStore *store = KoStore::createStore(m_chain->outputFile(), KoStore::Write, to, KoStore::Zip); if (!store || store->bad()) { kWarning(30502) << "Unable to open output file!"; delete store; return KoFilter::FileNotFound; } store->disallowNameExpansion(); kDebug(30502) << "created store."; KoOdfWriteStore odfStore(store); odfStore.manifestWriter(to); KoXmlWriter* contentWriter = odfStore.contentWriter(); if (!contentWriter) { delete store; return KoFilter::CreationError; } KoGenStyles mainStyles; KoXmlWriter *bodyWriter = odfStore.bodyWriter(); bodyWriter->startElement("office:body"); bodyWriter->startElement("office:text"); QString styleName("txt"); KoGenStyle style(KoGenStyle::ParagraphStyle, "paragraph"); style.addAttribute("style:display-name", styleName); style.addProperty("fo:font-family", "dejavu sans mono", KoGenStyle::TextType); style.addProperty("fo:font-family-generic", "modern", KoGenStyle::TextType); style.addProperty("fo:font-size", "10pt", KoGenStyle::TextType); style.addProperty("fo:font-weight", "normal", KoGenStyle::TextType); QString name(QString(QUrl::toPercentEncoding(styleName, "", " ")).replace('%', '_')); name = mainStyles.insert(style, name, KoGenStyles::DontAddNumberToName); #else KoStyleManager *styleManager = outputDoc->resourceManager()->resource(KoText::StyleManager).value<KoStyleManager*>(); KoParagraphStyle *p = styleManager->defaultParagraphStyle(); p->setFontFamily("dejavu sans mono"); p->setFontPointSize(10); p->setFontStyleHint(QFont::TypeWriter); outputDoc->appendPage(); QTextDocument *doc = outputDoc->mainFrameSet()->document(); //doc->setDefaultFont(p->font()); KoTextDocumentLayout *lay = dynamic_cast<KoTextDocumentLayout*>(doc->documentLayout()); Q_ASSERT(lay); lay->setBlockLayout(true); connect(lay, SIGNAL(layoutProgressChanged(int)), layoutUpdater, SLOT(setProgress(int))); QTextCursor cursor(doc); cursor.beginEditBlock(); QTextCharFormat charFormat; ((KoCharacterStyle*)p)->applyStyle(charFormat); cursor.setCharFormat(charFormat); #endif QTextStream stream(&in); Q_ASSERT(codec); stream.setCodec(codec); switch (paragraphStrategy) { case 1: { // Sentence: Line-break at the end of a sentence. QString stoppingPunctuation(".!?"); QString skippingEnd(" \"')"); while (!stream.atEnd()) { QString paragraph; for (;;) { const QString line = stream.readLine(); if (line.isEmpty()) break; paragraph += line + ' '; int lastPos = line.length() - 1; int maxCheck = lastPos >= 10 ? 10: lastPos + 1; QChar lastChar; // Skip a maximum of 10 quotes (or similar) at the end of the line for (int i = 0; i < maxCheck; ++i, --lastPos) { lastChar = line[lastPos]; if (lastPos == 0 || lastChar.isNull() || skippingEnd.indexOf(lastChar) == -1) break; } lastChar = line[lastPos]; if (lastChar.isNull()) continue; if (stoppingPunctuation.indexOf(lastChar) != -1) break; } if (!paragraph.isNull()) { QString s = paragraph.simplified(); #ifdef OUTPUT_AS_ODT_FILE bodyWriter->startElement("text:p"); bodyWriter->addAttribute("text:style-name", styleName); if (!s.isEmpty()) bodyWriter->addTextSpan(s); bodyWriter->endElement(); #else if (!s.isEmpty()) cursor.insertText(s /*, charFormat*/); cursor.insertBlock(); loadUpdater->setValue(stream.device()->pos()); #endif } } } break; case 2: { // Empty Line: Line-break if the line is empty. while (!stream.atEnd()) { QString paragraph; do { const QString line = stream.readLine(); if (line.isEmpty()) break; paragraph.append(line + ' '); } while(true); if (!paragraph.isNull()) { QString s = paragraph.simplified(); #ifdef OUTPUT_AS_ODT_FILE bodyWriter->startElement("text:p"); bodyWriter->addAttribute("text:style-name", styleName); if (!s.isEmpty()) bodyWriter->addTextSpan(s); bodyWriter->endElement(); #else if (!s.isEmpty()) { cursor.insertText(s /*, charFormat*/); cursor.insertBlock(); loadUpdater->setValue(stream.device()->pos()); } #endif } } } break; default: { // As Is: Line-break at the end of line. while (!stream.atEnd()) { QString s = stream.readLine(); #ifdef OUTPUT_AS_ODT_FILE bodyWriter->startElement("text:p"); bodyWriter->addAttribute("text:style-name", styleName); if (!s.isEmpty()) bodyWriter->addTextSpan(s); bodyWriter->endElement(); #else if (!s.isEmpty()) cursor.insertText(s /*, charFormat*/); cursor.insertBlock(); loadUpdater->setValue(stream.device()->pos()); #endif } } break; } #ifdef OUTPUT_AS_ODT_FILE bodyWriter->endElement(); // office:text bodyWriter->endElement(); // office:body mainStyles.saveOdfStyles(KoGenStyles::DocumentAutomaticStyles, contentWriter); odfStore.closeContentWriter(); odfStore.manifestWriter()->addManifestEntry("content.xml", "text/xml"); if (!mainStyles.saveOdfStylesDotXml(odfStore.store(), odfStore.manifestWriter())) { delete store; return KoFilter::CreationError; } if (store->open("meta.xml")) { KoStoreDevice dev(store); KoXmlWriter* xmlWriter = KoOdfWriteStore::createOasisXmlWriter(&dev, "office:document-meta"); xmlWriter->startElement("office:meta"); xmlWriter->startElement("meta:generator"); xmlWriter->addTextNode(QString("Calligra %1").arg(CALLIGRA_VERSION_STRING)); xmlWriter->endElement(); xmlWriter->startElement("meta:creation-date"); xmlWriter->addTextNode(QDateTime::currentDateTime().toString(Qt::ISODate)); xmlWriter->endElement(); xmlWriter->endElement(); // office:meta xmlWriter->endElement(); // root element xmlWriter->endDocument(); delete xmlWriter; if (store->close()) odfStore.manifestWriter()->addManifestEntry("meta.xml", "text/xml" ); } if (!odfStore.closeManifestWriter()) { kWarning() << "Error while trying to write 'META-INF/manifest.xml'. Partition full?"; delete store; return KoFilter::CreationError; } delete store; #else cursor.endEditBlock(); lay->setBlockLayout(false); lay->layout(); #endif return KoFilter::OK; }
void TestTableLayout::initTest(int rows, int columns, KoTableStyle *tableStyle, const QList<KoTableColumnStyle *> &columnStyles, const QList<KoTableRowStyle *> &rowStyles, const QMap<QPair<int, int>, KoTableCellStyle *> &cellStyles, const QMap<QPair<int, int>, QString> &cellTexts) { // Mock shape of size 200x1000 pt. m_shape = new MockTextShape(); Q_ASSERT(m_shape); m_shape->setSize(QSizeF(200, 1000)); // Document layout. m_layout = m_shape->layout; Q_ASSERT(m_layout); // Document. m_doc = m_layout->document(); Q_ASSERT(m_doc); m_doc->setDefaultFont(QFont("Sans Serif", 12, QFont::Normal, false)); // Layout state (layout helper). m_textLayout = new Layout(m_layout); Q_ASSERT(m_textLayout); m_layout->setLayout(m_textLayout); // Style manager. m_styleManager = new KoStyleManager(); Q_ASSERT(m_styleManager); KoTextDocument(m_doc).setStyleManager(m_styleManager); // Table style. m_defaultTableStyle = new KoTableStyle(); Q_ASSERT(m_defaultTableStyle); m_defaultTableStyle->setMargin(0.0); m_defaultTableStyle->setWidth(QTextLength(QTextLength::FixedLength, 200)); QTextTableFormat tableFormat; if (tableStyle) { tableStyle->applyStyle(tableFormat); } else { m_defaultTableStyle->applyStyle(tableFormat); } // Table. QTextCursor cursor(m_doc); m_table = cursor.insertTable(rows, columns, tableFormat); Q_ASSERT(m_table); // Column and row style manager. m_tableColumnAndRowStyleManager = KoTableColumnAndRowStyleManager::getManager(m_table); // Column styles. m_defaultColumnStyle.setRelativeColumnWidth(50.0); for (int col = 0; col < columns; ++col) { if (columnStyles.value(col)) { m_tableColumnAndRowStyleManager.setColumnStyle(col, *(columnStyles.at(col))); } else { m_tableColumnAndRowStyleManager.setColumnStyle(col, m_defaultColumnStyle); } } // Row styles. for (int row = 0; row < rows; ++row) { if (rowStyles.value(row)) { m_tableColumnAndRowStyleManager.setRowStyle(row, *(rowStyles.at(row))); } else { m_tableColumnAndRowStyleManager.setRowStyle(row, m_defaultRowStyle); } } // Cell styles and texts. m_defaultCellStyle = new KoTableCellStyle(); Q_ASSERT(m_defaultCellStyle); for (int row = 0; row < m_table->rows(); ++row) { for (int col = 0; col < m_table->columns(); ++col) { // Style. QTextTableCell cell = m_table->cellAt(row, col); QTextTableCellFormat cellFormat = cell.format().toTableCellFormat(); if (cellStyles.contains(qMakePair(row, col))) { cellStyles.value(qMakePair(row, col))->applyStyle(cellFormat); cell.setFormat(cellFormat.toCharFormat()); } else { m_defaultCellStyle->applyStyle(cellFormat); } cell.setFormat(cellFormat.toCharFormat()); // Text. if (cellTexts.contains(qMakePair(row, col))) { cell.firstCursorPosition().insertText(cellTexts.value(qMakePair(row, col))); } } } KoParagraphStyle style; style.setStyleId(101); // needed to do manually since we don't use the stylemanager QTextBlock b2 = m_doc->begin(); while (b2.isValid()) { style.applyStyle(b2); b2 = b2.next(); } }
void TestDocumentLayout::testInterruptedLists() { initForNewTest("ListItem1\nListItem2\nNormal Parag\nAnother parag\nListItem3\n"); // expect that normal paragraphs do not break a list (i.e not restart it) KoParagraphStyle style; KoListStyle listStyle; KoListLevelProperties llp = listStyle.levelProperties(1); llp.setStyle(KoListStyle::DecimalItem); llp.setStartValue(1); llp.setListItemSuffix("."); listStyle.setLevelProperties(llp); style.setListStyle(&listStyle); QTextBlock block = m_doc->begin(); style.applyStyle(block); block = block.next(); style.applyStyle(block); block = block.next(); block = block.next(); block = block.next(); style.applyStyle(block); m_layout->layout(); block = m_doc->begin(); KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); QVERIFY(data->counterText() == "1."); block = block.next(); data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); QVERIFY(data->counterText() == "2."); block = block.next(); QCOMPARE(block.layout()->lineAt(0).x(), 0.0); QVERIFY(block.userData() == 0); block = block.next(); QCOMPARE(block.layout()->lineAt(0).x(), 0.0); QVERIFY(block.userData() == 0); block = block.next(); // list item 3 data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); //qDebug() << data->counterText(); QVERIFY(data->counterText() == "3."); // I have doubts what consecutiveNumbering should do. Disable the feature for now. #if 0 // now the other way around block = m_doc->begin(); listStyle.setConsecutiveNumbering(false); listStyle.applyStyle(block); m_layout->layout(); data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); QVERIFY(data->counterText() == "1."); block = block.next(); data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); QVERIFY(data->counterText() == "2."); block = block.next(); QCOMPARE(block.layout()->lineAt(0).x(), 0.0); QVERIFY(block.userData() == 0); block = block.next(); QCOMPARE(block.layout()->lineAt(0).x(), 0.0); QVERIFY(block.userData() == 0); block = block.next(); // list item 3 data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); qDebug() << data->counterText(); QVERIFY(data->counterText() == "1."); #endif }
void TestDocumentLayout::testNumberedList() { initForNewTest("Base\nListItem1\nListItem2\nListItem3\nListItem4\nListItem5\nListItem6\nListItem6\nListItem7\nListItem8\nListItem9\nListItem10\nListItem11\nListItem12\n"); KoParagraphStyle style; m_styleManager->add(&style); QTextBlock block = m_doc->begin(); style.applyStyle(block); block = block.next(); KoListStyle listStyle; KoListLevelProperties llp; llp.setStyle(KoListStyle::DecimalItem); listStyle.setLevelProperties(llp); style.setListStyle(&listStyle); QTextList *previous = 0; int i; for (i = 1; i <= 9; i++) { QVERIFY(block.isValid()); // qDebug() << "->" << block.text(); style.applyStyle(block); QTextList *textList = block.textList(); QVERIFY(textList); if (previous == 0) { previous = textList; } else { QCOMPARE(textList, previous); } QCOMPARE(textList->format().intProperty(QTextListFormat::ListStyle), (int)(KoListStyle::DecimalItem)); block = block.next(); } m_layout->layout(); QTextLayout *blockLayout = m_block.layout(); QCOMPARE(blockLayout->lineAt(0).x(), 0.0); QTextBlock blok = m_doc->begin().next(); qreal indent = blok.layout()->lineAt(0).x(); QVERIFY(indent > 0.0); for (i = 1; i <= 9; ++i) { // qDebug() << "=>" << blok.text(); QTextList *textList = blok.textList(); QVERIFY(textList); QCOMPARE(blok.layout()->lineAt(0).x(), indent); // all the same indent. blok = blok.next(); } // now make number of listitems be more than 10, so we use 2 digits. for (i = 9; i <= 12; ++i) { QVERIFY(block.isValid()); style.applyStyle(block); // qDebug() << "->" << block.text(); block = block.next(); } m_layout->layout(); blockLayout = m_block.layout(); QCOMPARE(blockLayout->lineAt(0).x(), 0.0); blok = m_doc->begin().next(); qreal indent2 = blok.layout()->lineAt(0).x(); QVERIFY(indent2 > indent); // since it takes an extra digit for (i = 2; i <= 12; ++i) { // qDebug() << "=>" << blok.text(); QCOMPARE(blok.layout()->lineAt(0).x(), indent2); // all the same indent. blok = blok.next(); } // now to make sure the text is actually properly set. block = m_doc->begin().next(); i = 1; while (block.isValid() && i < 13) { KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); QCOMPARE(data->counterText(), QString::number(i++)); block = block.next(); } llp.setListItemSuffix("."); llp.setStartValue(4); listStyle.setLevelProperties(llp); QTextCursor cursor(m_doc); cursor.setPosition(10); // listItem1 QTextBlockFormat format = cursor.blockFormat(); format.setProperty(KoParagraphStyle::ListStartValue, 4); cursor.setBlockFormat(format); cursor.setPosition(40); // listItem4 format = cursor.blockFormat(); format.setProperty(KoParagraphStyle::ListStartValue, 12); cursor.setBlockFormat(format); // at this point we start numbering at 4. Have 4, 5, 6, 12, 13, 14, 15 etc m_layout->layout(); // now to make sur the text is actually properly set. block = m_doc->begin().next(); i = 4; while (block.isValid() && i < 22) { if (i == 7) { i = 12; } KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); QCOMPARE(data->counterText(), QString::number(i++)); block = block.next(); } }