Пример #1
0
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);
    }
}
Пример #2
0
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);
Пример #3
0
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;
}
Пример #4
0
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));
        }
    }
Пример #6
0
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);
}
Пример #7
0
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);
    }
}
Пример #8
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);
}
Пример #9
0
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);
}
Пример #10
0
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();
    }
}
Пример #11
0
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);
    }
}
Пример #12
0
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
            }
Пример #13
0
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;
}
Пример #14
0
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;
}