void KPrPlaceholderTextStrategy::paint( QPainter & painter, const KoViewConverter &converter, const QRectF & rect, KoShapePaintingContext &paintcontext) { if ( m_textShape ) { painter.save(); m_textShape->setSize( rect.size() ); // this code is needed to make sure the text of the textshape is layouted before it is painted KoTextShapeData * shapeData = qobject_cast<KoTextShapeData*>( m_textShape->userData() ); QTextDocument * document = shapeData->document(); KoTextDocumentLayout * lay = qobject_cast<KoTextDocumentLayout*>( document->documentLayout() ); if ( lay ) { lay->layout(); } m_textShape->paint( painter, converter, paintcontext); KoShape::applyConversion( painter, converter ); QPen pen(Qt::gray, 0); //pen.setStyle( Qt::DashLine ); // endless loop painter.setPen( pen ); painter.drawRect( rect ); painter.restore(); } else { KPrPlaceholderStrategy::paint( painter, converter, rect, paintcontext); } }
void KWRootAreaProvider::clearPages(int pageNumber) { if (pageNumber > pages().count()) { return; } KoTextDocumentLayout *lay = dynamic_cast<KoTextDocumentLayout*>(frameSet()->document()->documentLayout()); Q_ASSERT(lay); int prevPageIndex = pageNumber - 2; do { KWRootAreaPage *prevPage = prevPageIndex >= 0 && prevPageIndex < pages().count() ? pages()[prevPageIndex] : 0; if (prevPage) { if (prevPage->rootAreas.isEmpty()) { --prevPageIndex; continue; // this page doesn't have any root-areas so try the next previous page } QList<KoTextLayoutRootArea *> rootAreas = prevPage->rootAreas; foreach(KoTextLayoutRootArea *area, rootAreas) { releaseAllAfter(area); lay->removeRootArea(area); } } else { releaseAllAfter(0); lay->removeRootArea(0); } } while(false);
void TestChangeTrackedDelete::testPrefixMerge() { TextTool *textTool = new TextTool(new MockCanvas); KoTextEditor *textEditor = textTool->textEditor(); QVERIFY(textEditor); QTextDocument *document = textEditor->document(); KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout *>(document->documentLayout()); QTextCursor *cursor = textEditor->cursor(); cursor->insertText("Hello World"); cursor->setPosition(3); ChangeTrackedDeleteCommand *delCommand = new ChangeTrackedDeleteCommand(ChangeTrackedDeleteCommand::NextChar, textTool); textEditor->addCommand(delCommand); QCOMPARE(document->characterAt(3).unicode(), (ushort)(QChar::ObjectReplacementCharacter)); cursor->setPosition(4); delCommand = new ChangeTrackedDeleteCommand(ChangeTrackedDeleteCommand::NextChar, textTool); textEditor->addCommand(delCommand); // This is weird. Without this loop present the succeeding call to inlineTextObject returs NULL. Why ?????? for (int i = 0; i < document->characterCount(); i++) { cursor->setPosition(i); } cursor->setPosition(4); KoDeleteChangeMarker *testMarker = dynamic_cast<KoDeleteChangeMarker *>(layout->inlineTextObjectManager()->inlineTextObject(*cursor)); QTextDocumentFragment deleteData = KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->getDeleteData(); QCOMPARE(deleteData.toPlainText(), QString("lo")); delete textTool; }
void TestChangeTrackedDelete::testListDelete() { TextTool *textTool = new TextTool(new MockCanvas); KoTextEditor *textEditor = textTool->textEditor(); QVERIFY(textEditor); QTextDocument *document = textEditor->document(); KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout *>(document->documentLayout()); QTextCursor *cursor = textEditor->cursor(); insertSampleList(document); cursor->setPosition(16); cursor->setPosition(152, QTextCursor::KeepAnchor); ChangeTrackedDeleteCommand *delCommand = new ChangeTrackedDeleteCommand(ChangeTrackedDeleteCommand::NextChar, textTool); textEditor->addCommand(delCommand); QCOMPARE(document->characterAt(16).unicode(), (ushort)(QChar::ObjectReplacementCharacter)); // This is weird. Without this loop present the succeeding call to inlineTextObject returs NULL. Why ?????? for (int i = 0; i < document->characterCount(); i++) { cursor->setPosition(i); } cursor->setPosition(17); KoDeleteChangeMarker *testMarker = dynamic_cast<KoDeleteChangeMarker *>(layout->inlineTextObjectManager()->inlineTextObject(*cursor)); QTextDocumentFragment deleteData = KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->getDeleteData(); QTextDocument deleteDocument; QTextCursor deleteCursor(&deleteDocument); deleteCursor.insertFragment(deleteData); bool listFound = false; for (int i = 0; i < deleteDocument.characterCount(); i++) { deleteCursor.setPosition(i); if (deleteCursor.currentList()) { listFound = true; continue; } } QVERIFY(listFound == true); QTextList *deletedList = deleteCursor.currentList(); bool deletedListStatus = deletedList->format().boolProperty(KoDeleteChangeMarker::DeletedList); QVERIFY(deletedListStatus == true); bool deletedListItemStatus; deletedListItemStatus = deletedList->item(0).blockFormat().boolProperty(KoDeleteChangeMarker::DeletedListItem); QVERIFY(deletedListItemStatus == true); deletedListItemStatus = deletedList->item(1).blockFormat().boolProperty(KoDeleteChangeMarker::DeletedListItem); QVERIFY(deletedListItemStatus == true); deletedListItemStatus = deletedList->item(2).blockFormat().boolProperty(KoDeleteChangeMarker::DeletedListItem); QVERIFY(deletedListItemStatus == true); deletedListItemStatus = deletedList->item(3).blockFormat().boolProperty(KoDeleteChangeMarker::DeletedListItem); QVERIFY(deletedListItemStatus == true); deletedListItemStatus = deletedList->item(4).blockFormat().boolProperty(KoDeleteChangeMarker::DeletedListItem); QVERIFY(deletedListItemStatus == true); delete textTool; }
void SimpleParagraphWidget::fillListButtons() { KoZoomHandler zoomHandler; zoomHandler.setZoom(1.2); zoomHandler.setDpi(72, 72); KoInlineTextObjectManager itom; KoTextRangeManager tlm; TextShape textShape(&itom, &tlm); textShape.setSize(QSizeF(300, 100)); QTextCursor cursor (textShape.textShapeData()->document()); foreach(const Lists::ListStyleItem &item, Lists::genericListStyleItems()) { QPixmap pm(48,48); pm.fill(Qt::transparent); QPainter p(&pm); p.translate(0, -1.5); p.setRenderHint(QPainter::Antialiasing); if(item.style != KoListStyle::None) { KoListStyle listStyle; KoListLevelProperties llp = listStyle.levelProperties(1); llp.setStyle(item.style); if (KoListStyle::isNumberingStyle(item.style)) { llp.setStartValue(1); llp.setListItemSuffix("."); } listStyle.setLevelProperties(llp); cursor.select(QTextCursor::Document); QTextCharFormat textCharFormat=cursor.blockCharFormat(); textCharFormat.setFontPointSize(11); textCharFormat.setFontWeight(QFont::Normal); cursor.setCharFormat(textCharFormat); QTextBlock cursorBlock = cursor.block(); KoTextBlockData data(cursorBlock); cursor.insertText("----"); listStyle.applyStyle(cursor.block(),1); cursorBlock = cursor.block(); KoTextBlockData data1(cursorBlock); cursor.insertText("\n----"); cursorBlock = cursor.block(); KoTextBlockData data2(cursorBlock); cursor.insertText("\n----"); cursorBlock = cursor.block(); KoTextBlockData data3(cursorBlock); KoTextDocumentLayout *lay = dynamic_cast<KoTextDocumentLayout*>(textShape.textShapeData()->document()->documentLayout()); if(lay) lay->layout(); KoShapePaintingContext paintContext; //FIXME textShape.paintComponent(p, zoomHandler, paintContext); widget.bulletListButton->addItem(pm, static_cast<int> (item.style)); } }
void KoTextDocument::setInlineTextObjectManager(KoInlineTextObjectManager *manager) { QVariant v; v.setValue(manager); m_document->addResource(KoTextDocument::InlineTextManager, InlineObjectTextManagerURL, v); KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(m_document->documentLayout()); if (lay) lay->setInlineTextObjectManager(manager); }
void KoVariable::setValue(const QString &value) { Q_D(KoVariable); if (d->value == value) return; d->value = value; d->modified = true; if (d->document) { KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(d->document->documentLayout()); if (lay) lay->documentChanged(d->lastPositionInDocument, 0, 0); } }
void PageVariable::resize(const QTextDocument *document, QTextInlineObject object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd) { KoTextPage *page = 0; if (m_type != PageCount) { #if 0 // the code is left here to do some testing KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(document->documentLayout()); KoTextLayoutRootArea *rootArea = 0; KoTextPage *page2 = 0; if (lay) { rootArea = lay->rootAreaForPosition(posInDocument); if (rootArea) { page2 = rootArea->page(); } } #endif page = document->resource(KoTextDocument::LayoutTextPage, KoTextDocument::LayoutTextPageUrl).value<KoTextPage*>(); } int pagenumber = 0; switch (m_type) { case PageCount: break; case PageNumber: if (page) { // the text is not yet layouted therefore we don't get the rootArea // if we don't do that we get an endless change of the variable. QString currentValue = value(); if (currentValue.isEmpty() || ! m_fixed) { pagenumber = page->visiblePageNumber(m_pageselect, m_pageadjust); KoOdfNumberDefinition defaultDefinition; // FIXME Should fetch from pagestyle QString newValue = pagenumber >= 0 ? m_numberFormat.formattedNumber(pagenumber, &defaultDefinition) : QString(); // only update value when changed if (currentValue != newValue) { setValue(newValue); } } } break; case PageContinuation: if (page) { // the text is not yet layouted therefore we don't get the rootArea // if we don't do that we get an endless change of the variable. pagenumber = page->visiblePageNumber(m_pageselect); setValue(pagenumber >= 0 ? m_continuation : QString()); } break; } KoVariable::resize(document, object, posInDocument, format, pd); }
void PresentationVariable::resize(const QTextDocument *document, QTextInlineObject &object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd) { KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(document->documentLayout()); if (lay) { KoTextLayoutRootArea *rootArea = lay->rootAreaForPosition(posInDocument); if (rootArea) { if (KoPATextPage *textPage = dynamic_cast<KoPATextPage*>(rootArea->page())) { if (KPrPage *page = dynamic_cast<KPrPage*>(textPage->page())) { setValue(page->declaration(m_type)); } } } } KoVariable::resize(document, object, posInDocument, format, pd); }
void KoTextShapeContainerModel::childChanged(KoShape *child, KoShape::ChangeType type) { if (type == KoShape::RotationChanged || type == KoShape::ScaleChanged || type == KoShape::ShearChanged || type == KoShape::SizeChanged) { KoTextShapeData *data = dynamic_cast<KoTextShapeData*>(child->parent()->userData()); Q_ASSERT(data); data->foul(); KoTextDocumentLayout *lay = dynamic_cast<KoTextDocumentLayout*>(data->document()->documentLayout()); if (lay) lay->interruptLayout(); data->fireResizeEvent(); } }
void ShowChangesCommand::checkAndAddAnchoredShapes(int position, int length) { KoInlineTextObjectManager *inlineObjectManager = KoTextDocument(m_document).inlineTextObjectManager(); Q_ASSERT(inlineObjectManager); QTextCursor cursor = m_textEditor->document()->find(QString(QChar::ObjectReplacementCharacter), position); while(!cursor.isNull() && cursor.position() < position + length) { QTextCharFormat fmt = cursor.charFormat(); KoInlineObject *object = inlineObjectManager->inlineTextObject(fmt); Q_ASSERT(object); /* FIXME KoTextAnchor *anchor = dynamic_cast<KoTextAnchor *>(object); if (!anchor) { continue; } */ #if 0 // TODO -- since March 2010... KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(m_document->documentLayout()); KoShapeContainer *container = dynamic_cast<KoShapeContainer *>(lay->shapeForPosition(i)); // a very ugly hack. Since this class is going away soon, it should be okay if (!container) container = dynamic_cast<KoShapeContainer *>((lay->shapes()).at(0)); if (container) { container->addShape(anchor->shape()); KUndo2Command *shapeCommand = m_canvas->shapeController()->addShapeDirect(anchor->shape()); shapeCommand->redo(); m_shapeCommands.push_front(shapeCommand); } #endif cursor = m_textEditor->document()->find(QString(QChar::ObjectReplacementCharacter), position); } }
void KoTextLoader::loadBody(const KoXmlElement &bodyElem, QTextCursor &cursor) { const QTextBlockFormat defaultBlockFormat = cursor.blockFormat(); const QTextCharFormat defaultCharFormat = cursor.charFormat(); const QTextDocument *document = cursor.block().document(); d->styleManager = KoTextDocument(document).styleManager(); Q_ASSERT(d->styleManager); d->changeTracker = KoTextDocument(document).changeTracker(); // if (!d->changeTracker) // d->changeTracker = dynamic_cast<KoChangeTracker *>(d->context.dataCenterMap().value("ChangeTracker")); // Q_ASSERT(d->changeTracker); kDebug(32500) << "text-style:" << KoTextDebug::textAttributes( cursor.blockCharFormat() ); #if 0 if ((document->isEmpty()) && (d->styleManager)) { QTextBlock block = cursor.block(); d->styleManager->defaultParagraphStyle()->applyStyle(block); } #endif startBody(KoXml::childNodesCount(bodyElem)); KoXmlElement tag; bool usedParagraph = false; // set to true if we found a tag that used the paragraph, indicating that the next round needs to start a new one. forEachElement(tag, bodyElem) { if (! tag.isNull()) { const QString localName = tag.localName(); if (tag.namespaceURI() == KoXmlNS::text) { if (usedParagraph) cursor.insertBlock(defaultBlockFormat, defaultCharFormat); usedParagraph = true; if (d->changeTracker && localName == "tracked-changes") { d->changeTracker->loadOdfChanges(tag); usedParagraph = false; } else if (d->changeTracker && localName == "change-start") { loadChangedRegion(tag, cursor); usedParagraph = false; } else if (d->changeTracker && localName == "change-end") { d->currentChangeId = 0; usedParagraph = false; } else if (localName == "p") { // text paragraph loadParagraph(tag, cursor); } else if (localName == "h") { // heading loadHeading(tag, cursor); } else if (localName == "unordered-list" || localName == "ordered-list" // OOo-1.1 || localName == "list" || localName == "numbered-paragraph") { // OASIS loadList(tag, cursor); } else if (localName == "section") { // Temporary support (###TODO) loadSection(tag, cursor); } else { KoVariable *var = KoVariableRegistry::instance()->createFromOdf(tag, d->context); if (var) { KoTextDocumentLayout *layout = dynamic_cast<KoTextDocumentLayout*>(cursor.block().document()->documentLayout()); if (layout) { KoInlineTextObjectManager *textObjectManager = layout->inlineTextObjectManager(); if (textObjectManager) { KoVariableManager *varManager = textObjectManager->variableManager(); if (varManager) { textObjectManager->insertInlineObject(cursor, var); } } } } else { usedParagraph = false; kWarning(32500) << "unhandled text:" << localName; } } } else if (tag.namespaceURI() == KoXmlNS::draw) { loadShape(tag, cursor); } else if (tag.namespaceURI() == KoXmlNS::table) { if (localName == "table") { loadTable(tag, cursor); } else { kWarning(32500) << "unhandled table:" << localName; } #if 0 // TODO commented out for now if (localName == "table") { cursor.insertText("\n"); cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1); QTextTable *tbl = cursor.insertTable(1, 1); int rows = 0; int columns = 0; kDebug(32500) << "Table inserted"; KoXmlElement tblTag; forEachElement(tblTag, tag) { if (! tblTag.isNull()) { const QString tblLocalName = tblTag.localName(); if (tblTag.namespaceURI() == KoXmlNS::table) { if (tblLocalName == "table-column") { // Do some parsing with the column, see §8.2.1, ODF 1.1 spec int repeatColumn = tblTag.attributeNS(KoXmlNS::table, "number-columns-repeated", "1").toInt(); columns = columns + repeatColumn; if (rows > 0) tbl->resize(rows, columns); else tbl->resize(1, columns); } else if (tblLocalName == "table-row") { // Lot of work to do here... rows++; if (columns > 0) tbl->resize(rows, columns); else tbl->resize(rows, 1); // Added a row int currentCell = 0; KoXmlElement rowTag; forEachElement(rowTag, tblTag) { if (!rowTag.isNull()) { const QString rowLocalName = rowTag.localName(); if (rowTag.namespaceURI() == KoXmlNS::table) { if (rowLocalName == "table-cell") { // Ok, it's a cell... const int currentRow = tbl->rows() - 1; QTextTableCell cell = tbl->cellAt(currentRow, currentCell); if (cell.isValid()) { cursor = cell.firstCursorPosition(); loadBody(context, rowTag, cursor); } else kDebug(32500) << "Invalid table-cell row=" << currentRow << " column=" << currentCell; currentCell++; } } } } } } } } cursor = tbl->lastCursorPosition(); cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); } else { kWarning(32500) << "KoTextLoader::loadBody unhandled table::" << localName; } #endif }
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 TestChangeTrackedDelete::testTableDelete() { TextTool *textTool = new TextTool(new MockCanvas); KoTextEditor *textEditor = textTool->textEditor(); QVERIFY(textEditor); QTextDocument *document = textEditor->document(); KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout *>(document->documentLayout()); QTextCursor *cursor = textEditor->cursor(); insertSampleTable(document); cursor->setPosition(13); cursor->setPosition(102, QTextCursor::KeepAnchor); ChangeTrackedDeleteCommand *delCommand = new ChangeTrackedDeleteCommand(ChangeTrackedDeleteCommand::NextChar, textTool); textEditor->addCommand(delCommand); QCOMPARE(document->characterAt(13).unicode(), (ushort)(QChar::ObjectReplacementCharacter)); // This is weird. Without this loop present the succeeding call to inlineTextObject returs NULL. Why ?????? for (int i = 0; i < document->characterCount(); i++) { cursor->setPosition(i); } cursor->setPosition(14); KoDeleteChangeMarker *testMarker = dynamic_cast<KoDeleteChangeMarker *>(layout->inlineTextObjectManager()->inlineTextObject(*cursor)); QTextDocumentFragment deleteData = KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->getDeleteData(); QTextDocument deleteDocument; QTextCursor deleteCursor(&deleteDocument); deleteCursor.insertFragment(deleteData); bool tableFound = false; for (int i = 0; i < deleteDocument.characterCount(); i++) { deleteCursor.setPosition(i); if (deleteCursor.currentTable()) { tableFound = true; break; } } QVERIFY(tableFound == true); QTextTable *table = deleteCursor.currentTable(); QVERIFY(table->rows() == 3); QVERIFY(table->columns() == 3); tableFound = false; for (int i = 0; i < document->characterCount(); i++) { deleteCursor.setPosition(i); if (deleteCursor.currentTable()) { tableFound = true; break; } } QVERIFY(tableFound == false); delCommand->undo(); tableFound = false; for (int i = 0; i < document->characterCount(); i++) { deleteCursor.setPosition(i); if (deleteCursor.currentTable()) { tableFound = true; break; } } QVERIFY(tableFound == true); delete textTool; }