示例#1
0
void KoBookmark::saveOdf(KoShapeSavingContext &context)
{
    KoXmlWriter *writer = &context.xmlWriter();
    QString nodeName;
    if (d->type == SinglePosition)
        nodeName = "text:bookmark";
    else if (d->type == StartBookmark)
        nodeName = "text:bookmark-start";
    else if (d->type == EndBookmark)
        nodeName = "text:bookmark-end";
    writer->startElement(nodeName.toLatin1(), false);
    writer->addAttribute("text:name", d->name.toLatin1());

    if (d->type == StartBookmark && inlineRdf()) {
        inlineRdf()->saveOdf(context, writer);
    }
    writer->endElement();
}
void PresentationVariable::saveOdf(KoShapeSavingContext & context)
{
    KoXmlWriter *writer = &context.xmlWriter();
    const char * type = "";
    switch (m_type) {
    case KPrDeclarations::Footer:
        type = "presentation:footer";
        break;
    case KPrDeclarations::Header:
        type = "presentation:header";
        break;
    case KPrDeclarations::DateTime:
        type = "presentation:date-time";
        break;
    }
    writer->startElement(type);
    writer->endElement();
}
示例#3
0
bool PictureBase::saveAsBase64(KoXmlWriter& writer) const
{
    QBuffer buffer;
    buffer.open(QIODevice::ReadWrite);
    if (!save(&buffer))
        return false;
    QByteArray encoded = buffer.buffer().toBase64();
    writer.addTextNode(encoded);
    return true;
}
void DatabaseManager::saveOdf(KoXmlWriter& xmlWriter) const
{
    QList< QPair<QRectF, Database> > databases;
    const Region region(QRect(QPoint(1, 1), QPoint(KS_colMax, KS_rowMax)));
    const QList<Sheet*>& sheets = d->map->sheetList();
    for (int i = 0; i < sheets.count(); ++i)
        databases << sheets[i]->cellStorage()->databases(region);
    if (databases.isEmpty())
        return;

    xmlWriter.startElement("table:database-ranges");
    for (int i = 0; i < databases.count(); ++i) {
        Database database = databases[i].second;
        database.setRange(Region(databases[i].first.toRect(), database.range().firstSheet()));
        if (!database.range().isValid())
            continue;
        database.saveOdf(xmlWriter);
    }
    xmlWriter.endElement();
}
示例#5
0
static void writePartDesc(KoXmlWriter& w, int id, Part* part)
{
    w.startElement("music:score-part");
    w.addAttribute("id", QString("P%1").arg(id));

    w.startElement("music:part-name");
    w.addTextNode(part->name());
    w.endElement(); // music:part-name

    QString abbr = part->shortName(false);
    if (!abbr.isNull()) {
        w.startElement("music:part-abbreviation");
        w.addTextNode(abbr);
        w.endElement(); // music:part-abbreviation
    }

    w.endElement(); // music:score-part
}
示例#6
0
void saveOdfLabel(KoShape *label, KoXmlWriter &bodyWriter,
                  KoGenStyles &mainStyles, LabelType labelType)
{
    // Don't save hidden labels, as that's the way of removing them
    // from a chart.
    if (!label->isVisible())
        return;

    TextLabelData *labelData = qobject_cast<TextLabelData*>(label->userData());
    if (!labelData)
        return;

    if (labelType == FooterLabelType)
        bodyWriter.startElement("chart:footer");
    else if (labelType == SubTitleLabelType)
        bodyWriter.startElement("chart:subtitle");
    else // if (labelType == TitleLabelType)
        bodyWriter.startElement("chart:title");

    bodyWriter.addAttributePt("svg:x", label->position().x());
    bodyWriter.addAttributePt("svg:y", label->position().y());
    bodyWriter.addAttributePt("svg:width", label->size().width());
    bodyWriter.addAttributePt("svg:height", label->size().height());

    // TODO: Save text label color
    QTextCursor cursor(labelData->document());
    QFont labelFont = cursor.charFormat().font();

    KoGenStyle autoStyle(KoGenStyle::ChartAutoStyle, "chart", 0);
    autoStyle.addPropertyPt("style:rotation-angle", 360 - label->rotation());
    saveOdfFont(autoStyle, labelFont, QColor());
    bodyWriter.addAttribute("chart:style-name", mainStyles.insert(autoStyle, "ch"));

    bodyWriter.startElement("text:p");
    bodyWriter.addTextNode(labelData->document()->toPlainText());
    bodyWriter.endElement(); // text:p
    bodyWriter.endElement(); // chart:title/subtitle/footer
}
示例#7
0
static void writeTimeSignature(KoXmlWriter& w, TimeSignature* ts, Part* part)
{
    w.startElement("music:time");
    
    if (part->staffCount() > 1) {
        // only write staff info when more than one staff exists
        Staff* s = ts->staff();
        w.addAttribute("number", QString::number(part->indexOfStaff(s) + 1));
    }
    
    w.startElement("music:beats");
    w.addTextNode(QString::number(ts->beats()));
    w.endElement(); // music:beats
    
    w.startElement("music:beat-type");
    w.addTextNode(QString::number(ts->beat()));
    w.endElement(); // music:beat-type
    
    w.endElement(); // music:time
}
示例#8
0
bool KoGenStyles::saveOdfStylesDotXml(KoStore* store, KoXmlWriter* manifestWriter) const
{
    if (!store->open("styles.xml"))
        return false;

    manifestWriter->addManifestEntry("styles.xml",  "text/xml");

    KoStoreDevice stylesDev(store);
    KoXmlWriter* stylesWriter = KoOdfWriteStore::createOasisXmlWriter(&stylesDev, "office:document-styles");

    d->saveOdfFontFaceDecls(stylesWriter);
    d->saveOdfDocumentStyles(stylesWriter);
    d->saveOdfAutomaticStyles(stylesWriter, true, d->rawOdfAutomaticStyles_stylesDotXml);
    d->saveOdfMasterStyles(stylesWriter);

    stylesWriter->endElement(); // root element (office:document-styles)
    stylesWriter->endDocument();
    delete stylesWriter;

    if (!store->close())   // done with styles.xml
        return false;

    return true;
}
示例#9
0
QByteArray HancomWordImport::Private::createManifest()
{
  KoXmlWriter* manifestWriter;
  QByteArray manifestData;
  QBuffer manifestBuffer( &manifestData );

  manifestBuffer.open( QIODevice::WriteOnly );
  manifestWriter = new KoXmlWriter( &manifestBuffer );

  manifestWriter->startDocument( "manifest:manifest" );
  manifestWriter->startElement( "manifest:manifest" );
  manifestWriter->addAttribute( "xmlns:manifest", "urn:oasis:names:tc:openoffice:xmlns:manifest:1.0" );
  manifestWriter->addManifestEntry( "/", "application/vnd.oasis.opendocument.text" );
  manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
  manifestWriter->addManifestEntry( "content.xml", "text/xml" );
  manifestWriter->endElement();
  manifestWriter->endDocument();
  delete manifestWriter;

  return manifestData;
}
示例#10
0
bool KoDocumentInfo::saveOasisAboutInfo(KoXmlWriter &xmlWriter)
{
    foreach(const QString &tag, m_aboutTags) {
        if (!aboutInfo(tag).isEmpty() || tag == "title") {
            if (tag == "keyword") {
                foreach(const QString & tmp, aboutInfo("keyword").split(';')) {
                    xmlWriter.startElement("meta:keyword");
                    xmlWriter.addTextNode(tmp);
                    xmlWriter.endElement();
                }
            } else if (tag == "title" || tag == "description" || tag == "subject" ||
                       tag == "date" || tag == "language") {
                QByteArray elementName(QString("dc:" + tag).toLatin1());
                xmlWriter.startElement(elementName);
                xmlWriter.addTextNode(aboutInfo(tag));
                xmlWriter.endElement();
            } else {
                QByteArray elementName(QString("meta:" + tag).toLatin1());
                xmlWriter.startElement(elementName);
                xmlWriter.addTextNode(aboutInfo(tag));
                xmlWriter.endElement();
            }
        }
示例#11
0
bool KoDocumentInfo::saveOasisAuthorInfo(KoXmlWriter &xmlWriter)
{
    foreach(const QString & tag, m_authorTags) {
        if (!authorInfo(tag).isEmpty() && tag == "creator") {
            xmlWriter.startElement("dc:creator");
            xmlWriter.addTextNode(authorInfo("creator"));
            xmlWriter.endElement();
        } else if (!authorInfo(tag).isEmpty()) {
            xmlWriter.startElement("meta:user-defined");
            xmlWriter.addAttribute("meta:name", tag);
            xmlWriter.addTextNode(authorInfo(tag));
            xmlWriter.endElement();
        }
    }

    return true;
}
示例#12
0
void MusicXmlWriter::writeSheet(KoXmlWriter& w, Sheet* sheet, bool writeNamespaceDef)
{
//    w.startDocument("score-partwise", "-//Recordare//DTD MusicXML 1.1 Partwise//EN",
//        "http://www.musicxml.org/dtds/partwise.dtd");
    w.startElement("music:score-partwise");
    if (writeNamespaceDef) {
        w.addAttribute("xmlns:music", "http://www.calligra.org/music");
    }
    w.addAttribute("version", "1.1");

    w.startElement("music:part-list");
    for (int i = 0; i < sheet->partCount(); i++) {
        for (int pg = 0; pg < sheet->partGroupCount(); pg++) {
            if (sheet->partGroup(pg)->firstPart() == i) {
                writePartGroup(w, pg+1, sheet->partGroup(pg));
            }
        }
        writePartDesc(w, i, sheet->part(i));
        for (int pg = 0; pg < sheet->partGroupCount(); pg++) {
            if (sheet->partGroup(pg)->lastPart() == i) {
                w.startElement("music:part-group");
                w.addAttribute("type", "stop");
                w.addAttribute("number", pg+1);
                w.endElement(); // music:part-group
            }
        }
    }
    w.endElement(); // music:part-list

    for (int i = 0; i < sheet->partCount(); i++) {
        writePart(w, i, sheet->part(i));
    }

    w.endElement(); // music:score-partwise
//    w.endDocument();
}
示例#13
0
void Ko3dScene::Lightsource::saveOdf(KoXmlWriter &writer) const
{
    writer.startElement("dr3d:light");

    writer.addAttribute("dr3d:diffuse-color", m_diffuseColor.name());
    writer.addAttribute("dr3d:direction", (QString("(%1 %2 %3)")
                                           .arg(m_direction.x(), 0, 'f', 11)
                                           .arg(m_direction.y(), 0, 'f', 11)
                                           .arg(m_direction.z(), 0, 'f', 11)));
    writer.addAttribute("dr3d:enabled", m_enabled);
    writer.addAttribute("dr3d:specular", m_specular);

    writer.endElement(); // dr3d:light
}
示例#14
0
static void writeKeySignature(KoXmlWriter& w, KeySignature* ks, Part* part)
{
    w.startElement("music:key");
    
    if (part->staffCount() > 1) {
        // only write staff info when more than one staff exists
        Staff* s = ks->staff();
        w.addAttribute("number", QString::number(part->indexOfStaff(s) + 1));
    }
    
    w.startElement("music:fifths");
    w.addTextNode(QString::number(ks->accidentals()));
    w.endElement(); // music:fifths
    
    w.endElement(); // music:key
}
示例#15
0
static void writeClef(KoXmlWriter& w, Clef* clef, Part* part)
{
    w.startElement("music:clef");
  
      if (part->staffCount() > 1) {
        // only write staff info when more than one staff exists
        Staff* s = clef->staff();
        w.addAttribute("number", QString::number(part->indexOfStaff(s) + 1));
    }
    
    w.startElement("music:sign");
    switch (clef->shape()) {
        case Clef::GClef: w.addTextNode("G"); break;
        case Clef::FClef: w.addTextNode("F"); break;
        case Clef::CClef: w.addTextNode("C"); break;
    }
    w.endElement(); // music:sign
    
    w.endElement(); // music:clef
}
示例#16
0
bool KoDocumentInfo::saveOasis( KoStore* store )
{
    KoStoreDevice dev( store );
    KoXmlWriter* xmlWriter = KoDocument::createOasisXmlWriter( &dev, "office:document-meta" );
    xmlWriter->startElement( "office:meta" );

    xmlWriter->startElement( "meta:generator");
    xmlWriter->addTextNode( QString( "KOffice/%1" ).arg( KOFFICE_VERSION_STRING ) );
    xmlWriter->endElement();
    QStringList lst = pages();
    QStringList::ConstIterator it = lst.begin();
    for( ; it != lst.end(); ++it )
    {
        KoDocumentInfoPage* p = page( *it );
        Q_ASSERT( p );
        if ( !p->saveOasis( *xmlWriter ) )
            return false;
    }
    xmlWriter->endElement();
    xmlWriter->endElement(); // root element
    xmlWriter->endDocument();
    delete xmlWriter;
    return true;
}
void KPrFadeOverColorStrategy::saveOdfSmilAttributes(KoXmlWriter & xmlWriter) const
{
    KPrPageEffectStrategy::saveOdfSmilAttributes(xmlWriter);
    xmlWriter.addAttribute("smil:fadeColor", m_fadeColor.name());
}
示例#18
0
static void writePart(KoXmlWriter& w, int id, Part* part)
{
    w.startElement("music:part");
    w.addAttribute("id", QString("P%1").arg(id));

    for (int i = 0; i < part->sheet()->barCount(); i++) {
        Bar* bar = part->sheet()->bar(i);
        
        w.startElement("music:measure");
        w.addAttribute("number", i+1);

        bool inAttributes = false;
        if (i == 0) {
            w.startElement("music:attributes");
            w.startElement("music:divisions");
            w.addTextNode(QString::number(QuarterLength));
            w.endElement(); // music:divisions
            inAttributes = true;
        }

        for (int st = 0; st < part->staffCount(); st++) {
            Staff* staff = part->staff(st);
            for (int e = 0; e < bar->staffElementCount(staff); e++) {
                StaffElement* se = bar->staffElement(staff, e);
                
                KeySignature* ks = dynamic_cast<KeySignature*>(se);
                if (ks) {
                    if (!inAttributes) {
                        w.startElement("music:attributes");
                        inAttributes = true;
                    }
                    writeKeySignature(w, ks, part);
                }
            }
        }
        for (int st = 0; st < part->staffCount(); st++) {
            Staff* staff = part->staff(st);
            for (int e = 0; e < bar->staffElementCount(staff); e++) {
                StaffElement* se = bar->staffElement(staff, e);
                
                TimeSignature* ts = dynamic_cast<TimeSignature*>(se);
                if (ts) {
                    if (!inAttributes) {
                        w.startElement("music:attributes");
                        inAttributes = true;
                    }
                    writeTimeSignature(w, ts, part);
                }
            }
        }

        if (i == 0 && part->staffCount() != 1) {
            w.startElement("music:staves");
            w.addTextNode(QString::number(part->staffCount()));
            w.endElement(); // music:staves
        }            
            
        for (int st = 0; st < part->staffCount(); st++) {
            Staff* staff = part->staff(st);
            for (int e = 0; e < bar->staffElementCount(staff); e++) {
                StaffElement* se = bar->staffElement(staff, e);
                
                Clef* c = dynamic_cast<Clef*>(se);
                if (c) {
                    if (!inAttributes) {
                        w.startElement("music:attributes");
                        inAttributes = true;
                    }
                    writeClef(w, c, part);
                }
            }
        }

        if (inAttributes) {
            w.endElement(); // music:attributes
        }

        int curTime = 0;
        for (int voice = 0; voice < part->voiceCount(); voice++) {
            if (curTime != 0) {
                w.startElement("music:backup");
                w.startElement("music:duration");
                w.addTextNode(QString::number(curTime));
                w.endElement(); // music:duration
                w.endElement(); // music:backup
            }

            Voice* v = part->voice(voice);
            VoiceBar* vb = part->sheet()->bar(i)->voice(v);
            for (int e = 0; e < vb->elementCount(); e++) {
                VoiceElement* ve = vb->element(e);
                curTime += ve->length();

                Chord* c =  dynamic_cast<Chord*>(ve);
                if(c) writeChord(w, c, v, part, i);
            }
        }
        w.endElement(); // music:measure
    }

    w.endElement(); // music:part
}
示例#19
0
void Ko3dScene::saveOdfAttributes(KoXmlWriter &writer) const
{
    // 1. Write scene attributes
    // Camera attributes
    writer.addAttribute("dr3d:vrp", (QString("(%1 %2 %3)")
                                     .arg(d->vrp.x(), 0, 'f', 11)
                                     .arg(d->vrp.y(), 0, 'f', 11)
                                     .arg(d->vrp.z(), 0, 'f', 11)));
    writer.addAttribute("dr3d:vpn", (QString("(%1 %2 %3)")
                                     .arg(d->vpn.x(), 0, 'f', 11)
                                     .arg(d->vpn.y(), 0, 'f', 11)
                                     .arg(d->vpn.z(), 0, 'f', 11)));
    writer.addAttribute("dr3d:vup", (QString("(%1 %2 %3)")
                                     .arg(d->vup.x(), 0, 'f', 11)
                                     .arg(d->vup.y(), 0, 'f', 11)
                                     .arg(d->vup.z(), 0, 'f', 11)));

    writer.addAttribute("dr3d:projection", (d->projection == Parallel) ? "parallel" : "perspective");

    writer.addAttribute("dr3d:distance", d->distance);
    writer.addAttribute("dr3d:focal-length", d->focalLength);
    writer.addAttribute("dr3d:shadow-slant", d->shadowSlant);
    writer.addAttribute("dr3d:ambient-color", d->ambientColor.name());

    // Rendering attributes
    switch (d->shadeMode) {
    case Flat:
        writer.addAttribute("dr3d:shade-mode", "flat");
        break;
    case Phong:
        writer.addAttribute("dr3d:shade-mode", "phong");
        break;
    case Draft:
        writer.addAttribute("dr3d:shade-mode", "draft");
        break;
    case Gouraud:
    default:
        writer.addAttribute("dr3d:shade-mode", "gouraud");
        break;
    }

    writer.addAttribute("dr3d:lighting-mode", d->lightingMode);
    writer.addAttribute("dr3d:transform", d->transform);
}
示例#20
0
static void writePartGroup(KoXmlWriter& w, int id, PartGroup* group)
{
    w.startElement("music:part-group");
    w.addAttribute("type", "start");
    w.addAttribute("number", id);

    if (!group->name().isNull()) {
        w.startElement("music:group-name");
        w.addTextNode(group->name());
        w.endElement(); // music:group-name
    }
    if (!group->shortName(false).isNull()) {
        w.startElement("music:group-abbreviation");
        w.addTextNode(group->shortName());
        w.endElement(); // music:group-abbreviation
    }

    if (group->symbol() != PartGroup::None) {
        w.startElement("music:group-symbol");
        switch (group->symbol()) {
            case PartGroup::None:       w.addTextNode("none");   break;
            case PartGroup::Brace:      w.addTextNode("brace");  break;
            case PartGroup::Line:       w.addTextNode("line");   break;
            case PartGroup::Bracket:    w.addTextNode("bracket"); break;
        }
        w.endElement(); // music:group-symbol
    }

    w.startElement("music:group-barline");
    w.addTextNode(group->commonBarLines() ? "yes" : "no");
    w.endElement(); // music:group-barline

    w.endElement(); // music:part-group
}
示例#21
0
KoFilter::ConversionStatus KoOdfExporter::convert(const QByteArray& from, const QByteArray& to)
{
    // check for proper conversion
    if (!acceptsSourceMimeType(from)) {
        kWarning(30003) << "Invalid source mimetype" << from;
        return KoFilter::NotImplemented;
    }
    if (!acceptsDestinationMimeType(to)) {
        kWarning(30003) << "Invalid destination mimetype" << to;
        return KoFilter::NotImplemented;
    }

    //create output files
    KoStore *outputStore = KoStore::createStore(m_chain->outputFile(), KoStore::Write, to, KoStore::Zip);
    if (!outputStore || outputStore->bad()) {
        kWarning(30003) << "Unable to open output file!";
        delete outputStore;
        return KoFilter::FileNotFound;
    }
    outputStore->disallowNameExpansion();
    kDebug(30003) << "created outputStore.";
    KoOdfWriteStore oasisStore(outputStore);

    kDebug(30003) << "created oasisStore.";

    // KoGenStyles for writing styles while we're parsing
    KoGenStyles mainStyles;

    KoOdfWriters writers;
    writers.mainStyles = &mainStyles;

    // create a writer for meta.xml
    QBuffer buf;
    buf.open(QIODevice::WriteOnly);
    KoXmlWriter metaWriter(&buf);
    writers.meta = &metaWriter;

    // create a writer for manifest.xml
    QBuffer manifestBuf;
    manifestBuf.open(QIODevice::WriteOnly);
    KoXmlWriter manifestWriter(&manifestBuf);
    writers.manifest = &manifestWriter;

    //open contentWriter & bodyWriter *temp* writers
    //so we can write picture files while we parse
    QBuffer contentBuf;
    KoXmlWriter contentWriter(&contentBuf);
    writers.content = &contentWriter;
    QBuffer bodyBuf;
    KoXmlWriter bodyWriter(&bodyBuf);
    writers.body = &bodyWriter;

    // open main tags
    bodyWriter.startElement("office:body");
    bodyWriter.startElement(d->bodyContentElement.constData());

    RETURN_IF_ERROR( createDocument(outputStore, &writers) )

    //save the office:automatic-styles & and fonts in content.xml
    mainStyles.saveOdfStyles(KoGenStyles::FontFaceDecls, &contentWriter);
    mainStyles.saveOdfStyles(KoGenStyles::DocumentAutomaticStyles, &contentWriter);

    //close tags in body
    bodyWriter.endElement();//office:*
    bodyWriter.endElement();//office:body

    //now create real content/body writers & dump the information there
    KoXmlWriter* realContentWriter = oasisStore.contentWriter();
    if (!realContentWriter) {
        kWarning(30003) << "Error creating the content writer.";
        delete outputStore;
        return KoFilter::CreationError;
    }
    realContentWriter->addCompleteElement(&contentBuf);

    KoXmlWriter* realBodyWriter = oasisStore.bodyWriter();
    if (!realBodyWriter) {
        kWarning(30003) << "Error creating the body writer.";
        delete outputStore;
        return KoFilter::CreationError;
    }
    realBodyWriter->addCompleteElement(&bodyBuf);

    //now close content & body writers
    if (!oasisStore.closeContentWriter()) {
        kWarning(30003) << "Error closing content.";
        delete outputStore;
        return KoFilter::CreationError;
    }

    kDebug(30003) << "closed content & body writers.";

    //create the manifest file
    KoXmlWriter* realManifestWriter = oasisStore.manifestWriter(to);
    //create the styles.xml file
    mainStyles.saveOdfStylesDotXml(outputStore, realManifestWriter);
    realManifestWriter->addManifestEntry("content.xml", "text/xml");
    realManifestWriter->addCompleteElement(&manifestBuf);

    kDebug(30003) << "created manifest and styles.xml";

    // create settings.xml, apparently it is used to note calligra that msoffice files should
    // have different behavior with some things
    if (!outputStore->open("settings.xml")) {
        delete outputStore;
        return KoFilter::CreationError;
    }

    KoStoreDevice settingsDev(outputStore);
    KoXmlWriter* settings = KoOdfWriteStore::createOasisXmlWriter(&settingsDev, "office:document-settings");
    settings->startElement("office:settings");
    settings->startElement("config:config-item-set");
    settings->addAttribute("config:name", "ooo:configuration-settings");
    writeConfigurationSettings(settings);
    settings->endElement(); // config:config-item-set
    settings->endElement(); // office:settings
    settings->endElement(); // office:document-settings
    settings->endDocument();
    delete settings;
    realManifestWriter->addManifestEntry("settings.xml", "text/xml");
    if (!outputStore->close()) {
        delete outputStore;
        return KoFilter::CreationError;
    }

    //create meta.xml
    if (!outputStore->open("meta.xml")) {
        delete outputStore;
        return KoFilter::CreationError;
    }
    KoStoreDevice metaDev(outputStore);
    KoXmlWriter* meta = KoOdfWriteStore::createOasisXmlWriter(&metaDev, "office:document-meta");
    meta->startElement("office:meta");
    meta->addCompleteElement(&buf);
    meta->endElement(); //office:meta
    meta->endElement(); //office:document-meta
    meta->endDocument();
    delete meta;
    if (!outputStore->close()) {
        delete outputStore;
        return KoFilter::CreationError;
    }
    realManifestWriter->addManifestEntry("meta.xml", "text/xml");
    oasisStore.closeManifestWriter();
    delete outputStore;

    return KoFilter::OK;
}
示例#22
0
void KoInlineNote::saveOdf(KoShapeSavingContext & context)
{
    KoXmlWriter *writer = &context.xmlWriter();
    QTextDocument *document = new QTextDocument();
    KoTextDocument textDocument(document);
    Q_ASSERT(!d->styleManager.isNull());
    textDocument.setStyleManager(d->styleManager.data());

    QTextCursor cursor(document);
    cursor.insertFragment(d->text);

    if (d->type == Footnote || d->type == Endnote) {
        writer->startElement("text:note", false);
        if (d->type == Footnote)
            writer->addAttribute("text:note-class", "footnote");
        else
            writer->addAttribute("text:note-class", "endnote");
        writer->addAttribute("text:id", d->id);
        writer->startElement("text:note-citation", false);
        if (!autoNumbering())
            writer->addAttribute("text:label", d->label);
        writer->addTextNode(d->label);
        writer->endElement();

        writer->startElement("text:note-body", false);
        KoTextWriter textWriter(context);
        textWriter.write(document, 0);
        writer->endElement();

        writer->endElement();
    }
    else if (d->type == Annotation) {
        writer->startElement("office:annotation");
        if (!d->author.isEmpty()) {
            writer->startElement("dc:creator");
            writer->addTextNode(d->author);
            writer->endElement();
        }
        if (d->date.isValid()) {
            writer->startElement("dc:date");
            writer->addTextSpan(d->date.toString(Qt::ISODate));
            writer->endElement();
        }

        KoTextWriter textWriter(context);
        textWriter.write(document, 0);

        writer->endElement();
    }

    delete document;
}
示例#23
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;
}
示例#24
0
// Called by Document before invoking the table-row-functors
void WordsTableHandler::tableStart(Words::Table* table)
{
    kDebug(30513);

    Q_ASSERT(table);
    Q_ASSERT(!table->name.isEmpty());

    wvWare::SharedPtr<const wvWare::Word97::TAP> tap = table->tap;
    KoXmlWriter* writer = currentWriter();

    m_currentTable = table;
    m_cellOpen = false;
    m_row = -1;
    m_currentY = 0;

#ifdef DEBUG_TABLEHANDLER
    for (unsigned int i = 0; i < (unsigned int)table->m_cellEdges.size(); i++) {
        kDebug(30513) << table->m_cellEdges[i];
    }
#endif

    if (m_currentTable->floating) {
        const KoGenStyle::PropertyType gt = KoGenStyle::GraphicType;
        KoGenStyle style(KoGenStyle::GraphicAutoStyle, "graphic");
        if (document()->writingHeader()) {
            style.setAutoStyleInStylesDotXml(true);
        }

        //style:wrap
        if (tap->textWrap) {
            if (tap->dxaAbs == -8) {
                style.addProperty("style:wrap", "left", gt);
            }
            else if (tap->dxaAbs == 0) {
                style.addProperty("style:wrap", "right", gt);
            } else {
                style.addProperty("style:wrap", "parallel", gt);
            }
            //ODF-1.2: Specifies the number of paragraphs that can wrap around
            //a frame if wrap mode is in {left, right, parallel, dynamic} and
            //anchor type is in {char, paragraph}.
            style.addProperty("style:number-wrapped-paragraphs", "no-limit", gt);
        } else {
            style.addProperty("style:wrap", "none", gt);
        }
        //fo:margin
        style.addPropertyPt("fo:margin-left", twipsToPt(tap->dxaFromText), gt);
        style.addPropertyPt("fo:margin-right", twipsToPt(tap->dxaFromTextRight), gt);
        style.addPropertyPt("fo:margin-top", twipsToPt(tap->dyaFromText), gt);
        style.addPropertyPt("fo:margin-bottom", twipsToPt(tap->dyaFromTextBottom), gt);

        int dxaAbs = 0;
        int dyaAbs = 0;

        //style:horizontal-pos - horizontal position of the anchor
        QString pos = Conversion::getHorizontalPos(tap->dxaAbs);
        style.addProperty("style:horizontal-pos", pos, gt);
        if (pos == "from-left") {
            dxaAbs = tap->dxaAbs;
        }
        //style:vertical-pos - vertical position of the anchor
        pos = Conversion::getVerticalPos(tap->dyaAbs);
        style.addProperty("style:vertical-pos", pos, gt);
        if (pos == "from-top") {
            dyaAbs = tap->dyaAbs;
        }
        //style:vertical-rel - relative vertical position of the anchor
        pos = Conversion::getVerticalRel(tap->pcVert);
	if (!pos.isEmpty()) {
            style.addProperty("style:vertical-rel", pos, gt);
        }
        //style:horizontal-rel - relative horizontal position of the anchor
        pos = Conversion::getHorizontalRel(tap->pcHorz);
        if (!pos.isEmpty()) {
            style.addProperty("style:horizontal-rel", pos, gt);
        }
        //draw:auto-grow-height
        style.addProperty("draw:auto-grow-height", "true", gt);

        const QString drawStyleName = m_mainStyles->insert(style);

        writer->startElement("draw:frame");
        writer->addAttribute("draw:style-name", drawStyleName.toUtf8());
        writer->addAttribute("text:anchor-type", "paragraph");

        int width = table->m_cellEdges[table->m_cellEdges.size() - 1] - table->m_cellEdges[0];
        writer->addAttributePt("svg:width", twipsToPt(width));

        if (style.property("style:horizontal-pos", gt) == "from-left") {
            writer->addAttributePt("svg:x", twipsToPt(dxaAbs + tap->rgdxaCenter[0]));
        }

        writer->addAttributePt("svg:y", twipsToPt(dyaAbs));
        writer->startElement("draw:text-box");
    } //absolutely positioned table

    KoGenStyle tableStyle(KoGenStyle::TableAutoStyle, "table");
    if (document()->writingHeader()) {
        tableStyle.setAutoStyleInStylesDotXml(true);
    }

    //TODO: process the border color information <table:border-color>

    if (tap->fBiDi == 1) {
        tableStyle.addProperty("style:writing-mode", "rl-tb");
    } else {
        tableStyle.addProperty("style:writing-mode", "lr-tb");
    }

    //process horizontal align information
    QString align;
    if (m_currentTable->floating) {
        align = QString("margins");
    } else {
        switch (tap->jc) {
        case hAlignLeft:
            align = QString("left");
            break;
        case hAlignCenter:
            align = QString("center");
            break;
        case hAlignRight:
            align = QString("right");
            break;
        }
    }
    tableStyle.addProperty("table:align", align);

    int width = table->m_cellEdges[table->m_cellEdges.size() - 1] - table->m_cellEdges[0];
    tableStyle.addPropertyPt("style:width", twipsToPt(width));
    tableStyle.addProperty("table:border-model", "collapsing");

    //process the margin information
    if (!m_currentTable->floating) {
        tableStyle.addPropertyPt("fo:margin-left", twipsToPt(tap->rgdxaCenter[0]));
    }

    //check if we need a master page name attribute.
    if (document()->writeMasterPageName() && !document()->writingHeader()) {
        tableStyle.addAttribute("style:master-page-name", document()->masterPageName());
        document()->set_writeMasterPageName(false);
    }

    QString tableStyleName = m_mainStyles->insert(tableStyle, QLatin1String("Table"), KoGenStyles::AllowDuplicates);

    //start table in content
    writer->startElement("table:table");
    writer->addAttribute("table:style-name", tableStyleName);

    // Write the table:table-column descriptions.
    for (int r = 0; r < table->m_cellEdges.size() - 1; r++) {
        KoGenStyle tableColumnStyle(KoGenStyle::TableColumnAutoStyle, "table-column");

        //in case a header or footer is processed, save the style into styles.xml
        if (document()->writingHeader()) {
            tableColumnStyle.setAutoStyleInStylesDotXml(true);
        }

        tableColumnStyle.addPropertyPt("style:column-width",
                                       (table->m_cellEdges[r+1] - table->m_cellEdges[r]) / 20.0);

        QString tableColumnStyleName;
        if (r >= 26) {
            tableColumnStyleName = m_mainStyles->insert(tableColumnStyle, tableStyleName + ".A" + QChar('A' + r - 26), KoGenStyles::DontAddNumberToName);
        } else {
            tableColumnStyleName = m_mainStyles->insert(tableColumnStyle, tableStyleName + '.' + QChar('A' + r), KoGenStyles::DontAddNumberToName);
        }

        writer->startElement("table:table-column");
        writer->addAttribute("table:style-name", tableColumnStyleName);
        writer->endElement();
    }
}
示例#25
0
void CompositeEffect::save(KoXmlWriter &writer)
{
    writer.startElement(CompositeEffectId);

    saveCommonAttributes(writer);

    switch (m_operation) {
    case CompositeOver:
        writer.addAttribute("operator", "over");
        break;
    case CompositeIn:
        writer.addAttribute("operator", "in");
        break;
    case CompositeOut:
        writer.addAttribute("operator", "out");
        break;
    case CompositeAtop:
        writer.addAttribute("operator", "atop");
        break;
    case CompositeXor:
        writer.addAttribute("operator", "xor");
        break;
    case Arithmetic:
        writer.addAttribute("operator", "arithmetic");
        writer.addAttribute("k1", QString("%1").arg(m_k[0]));
        writer.addAttribute("k2", QString("%1").arg(m_k[1]));
        writer.addAttribute("k3", QString("%1").arg(m_k[2]));
        writer.addAttribute("k4", QString("%1").arg(m_k[3]));
        break;
    }

    writer.addAttribute("in2", inputs().at(1));

    writer.endElement();
}
示例#26
0
void KoInlineNote::saveOdf(KoShapeSavingContext & context)
{
    KoXmlWriter *writer = &context.xmlWriter();
    writer->startElement("text:note", false);
    if (d->type == Footnote)
        writer->addAttribute("text:note-class", "footnote");
    else
        writer->addAttribute("text:note-class", "endnote");
    writer->addAttribute("text:id", d->id);
    writer->startElement("text:note-citation", false);
    if (!autoNumbering())
        writer->addAttribute("text:label", d->label);
    writer->addTextNode(d->label);
    writer->endElement();
    writer->startElement("text:note-body", false);
    writer->startElement("text:p");
    writer->addTextNode(d->text);
    writer->endElement();
    writer->endElement();
    writer->endElement();
}
示例#27
0
bool DocBase::saveOdfHelper(SavingContext & documentContext, SaveFlag saveFlag,
                            QString* /*plainText*/)
{
    Q_UNUSED(saveFlag);
    KoStore * store = documentContext.odfStore.store();
    KoXmlWriter * manifestWriter = documentContext.odfStore.manifestWriter();

    KoStoreDevice dev(store);
    KoGenStyles mainStyles;//for compile

    KoXmlWriter* contentWriter = documentContext.odfStore.contentWriter();

    KoXmlWriter* bodyWriter = documentContext.odfStore.bodyWriter();
    KoShapeSavingContext savingContext(*bodyWriter, mainStyles, documentContext.embeddedSaver);

    //todo fixme just add a element for testing saving content.xml
    bodyWriter->startElement("office:body");
    bodyWriter->startElement("office:spreadsheet");

    // Saving the map.
    map()->saveOdf(*contentWriter, savingContext);

    bodyWriter->endElement(); ////office:spreadsheet
    bodyWriter->endElement(); ////office:body

    // Done with writing out the contents to the tempfile, we can now write out the automatic styles
    mainStyles.saveOdfStyles(KoGenStyles::DocumentAutomaticStyles, contentWriter);

    documentContext.odfStore.closeContentWriter();

    //add manifest line for content.xml
    manifestWriter->addManifestEntry("content.xml",  "text/xml");

    mainStyles.saveOdfStylesDotXml(store, manifestWriter);

    if (!store->open("settings.xml"))
        return false;

    KoXmlWriter* settingsWriter = KoOdfWriteStore::createOasisXmlWriter(&dev, "office:document-settings");
    settingsWriter->startElement("office:settings");
    settingsWriter->startElement("config:config-item-set");
    settingsWriter->addAttribute("config:name", "view-settings");

    saveUnitOdf(settingsWriter);

    saveOdfSettings(*settingsWriter);

    settingsWriter->endElement(); // config:config-item-set

    settingsWriter->startElement("config:config-item-set");
    settingsWriter->addAttribute("config:name", "configuration-settings");
    settingsWriter->addConfigItem("SpellCheckerIgnoreList", d->spellListIgnoreAll.join(","));
    settingsWriter->endElement(); // config:config-item-set
    settingsWriter->endElement(); // office:settings
    settingsWriter->endElement(); // Root:element
    settingsWriter->endDocument();
    delete settingsWriter;

    if (!store->close())
        return false;

    if (!savingContext.saveDataCenter(store, manifestWriter)) {
        return false;
    }

    manifestWriter->addManifestEntry("settings.xml", "text/xml");

    setModified(false);

    return true;
}
示例#28
0
void WordsTableHandler::tableCellStart()
{
    kDebug(30513) ;

    if (!m_tap) {
        return;
    }
    KoXmlWriter*  writer = currentWriter();

    //increment the column number so we know where we are
    m_column++;
    //get the number of cells in this row
    int nbCells = m_tap->itcMac;
    //make sure we didn't get more columns than possible number of cells
    Q_ASSERT(m_column < nbCells);
    //if our column number is greater than or equal to number of cells
    if (m_column >= nbCells) {
        return;
    }
    // Get table cell descriptor
    //merging, alignment, ... information
    const wvWare::Word97::TC& tc = m_tap->rgtc[ m_column ];

    //left boundary of current cell
    int leftEdgePos = m_tap->rgdxaCenter[ m_column ]; // in DXAs
    //right boundary of current cell
    int rightEdgePos = m_tap->rgdxaCenter[ m_column+1 ]; // in DXAs

    // Check for merged cells
    // ## We can ignore that one. Our cell-edge magic is much more flexible.
#if 0
    int colSize = 1;
    if (tc.fFirstMerged) {
        // This cell is the first one of a series of merged cells ->
        // we want to find out its size.
        int i = m_column + 1;
        while (i < nbCells && m_tap->rgtc[ i ].fMerged && !m_tap->rgtc[i].fFirstMerged) {
            ++colSize;
            ++i;
        }
    }
#endif
    int rowSpan = 1;
    //if this is the first of some vertically merged cells...
    if (tc.fVertRestart) {
//         kDebug(30513) <<"fVertRestart is set!";
        // This cell is the first one of a series of vertically merged cells ->
        // we want to find out its size.
        QList<Words::Row>::Iterator it = m_currentTable->rows.begin() +  m_row + 1;
        for (; it != m_currentTable->rows.end(); ++it)  {
            // Find cell right below us in row (*it), if any
            Words::TAPptr tapBelow = (*it).tap;
            const wvWare::Word97::TC* tcBelow = 0L;
            for (int c = 0; !tcBelow && c < tapBelow->itcMac ; ++c) {
                if (qAbs(tapBelow->rgdxaCenter[ c ] - leftEdgePos) <= 3
                        && qAbs(tapBelow->rgdxaCenter[ c + 1 ] - rightEdgePos) <= 3) {
                    tcBelow = &tapBelow->rgtc[ c ];
//                     kDebug(30513) <<"found cell below, at (Word) column" << c
//                                   <<" fVertMerge:" << tcBelow->fVertMerge;
                }
            }
            if (tcBelow && tcBelow->fVertMerge && !tcBelow->fVertRestart) {
                ++rowSpan;
            } else {
                break;
            }
        }
        //kDebug(30513) <<"rowSpan=" << rowSpan;
    }

    // Check how many cells that means, according to our cell edge array.
    int leftCellNumber  = m_currentTable->columnNumber(leftEdgePos);
    int rightCellNumber = m_currentTable->columnNumber(rightEdgePos);

    // In cases where not all columns are present, ensure that the last
    // column spans the remainder of the table.
    // ### It would actually be more closer to the original if we created
    // an empty cell from m_column+1 to the last column. (table-6.doc)
    if (m_column == nbCells - 1)  {
        rightCellNumber = m_currentTable->m_cellEdges.size() - 1;
        rightEdgePos = m_currentTable->m_cellEdges[ rightCellNumber ];
    }

#ifdef DEBUG_TABLEHANDLER
    kDebug(30513) << "left edge = " << leftEdgePos << ", right edge = " << rightEdgePos;
    kDebug(30513) << "leftCellNumber = " << leftCellNumber << ", rightCellNumber = " << rightCellNumber;
#endif

    //NOTE: The cacheCellEdge f. took care of unsorted tap->rgdxaCenter values.
    //The following assert is not up2date.
//     Q_ASSERT(rightCellNumber >= leftCellNumber);

    // the resulting number of merged cells horizontally
    int colSpan = rightCellNumber - leftCellNumber;

    // Put a filler in for cells that are part of a merged cell.  According to
    // the [MS-DOC] spec. those must be empty (we'll get a warning if not).
    //
    if (tc.fVertMerge && !tc.fVertRestart) {
        m_cellOpen = true;
        writer->startElement("table:covered-table-cell");
        // store colSpan so covered elements can be added on cell close
        m_colSpan = colSpan;
        return;
    }
    // We are now sure we have a real cell (and not a covered one)
    QRectF cellRect(leftEdgePos / 20.0,  // left
                    m_currentY, // top
                    (rightEdgePos - leftEdgePos) / 20.0,   // width
                    rowHeight());  // height
    // I can pass these sizes to ODF now...
#ifdef DEBUG_TABLEHANDLER
    kDebug(30513) << " tableCellStart row=" << m_row << ", column=" << m_column <<
                     " colSpan=" << colSpan <<
                     " (from" << leftCellNumber << " to" << rightCellNumber << " for Words)" <<
                     " rowSpan=" << rowSpan <<
                     " cellRect=" << cellRect;
#endif

    // Sort out the borders.
    //
    // From experimenting with Word the following can be said about
    // horizontal borders:
    //
    //  - They always use the collapsing border model (.doc
    //    additionally has the notion of table wide borders)
    //  - The default borders are merged into the odt output by
    //   "winning" over the cell borders due to wider lines
    //  - Word also defines table-wide borders (even between cell
    //    minimum values)
    //  - If the default is thicker or same width then it wins. At the
    //    top or bottom of table the cell always wins
    //
    // The following can be said about vertical borders:
    //  - The cell to the left of the border always defines the value.
    //  - Well then a winner with the table wide definitions is also found.
    //
#ifdef DEBUG_TABLEHANDLER
    kDebug(30513) << "CellBorders=" << m_row << m_column
                  << "top" << tc.brcTop.brcType << tc.brcTop.dptLineWidth
                  << "left" << tc.brcLeft.brcType << tc.brcLeft.dptLineWidth
                  << "bottom" << tc.brcBottom.brcType << tc.brcBottom.dptLineWidth
                  << "right" << tc.brcRight.brcType << tc.brcRight.dptLineWidth;
#endif

    const wvWare::Word97::BRC brcNone;
    const wvWare::Word97::BRC& brcTop = (m_row > 0) ?
                                        brcWinner(tc.brcTop, m_tap->rgbrcTable[4]) :
                                        ((tc.brcTop.brcType > 0 && tc.brcTop.brcType < 64) ? tc.brcTop :
                                        m_tap->rgbrcTable[0]);
    const wvWare::Word97::BRC& brcBottom = (m_row < m_currentTable->rows.size() - 1) ?
                                           brcWinner(tc.brcBottom, m_tap->rgbrcTable[4]) :
                                           brcWinner(tc.brcBottom, m_tap->rgbrcTable[2]);
    const wvWare::Word97::BRC& brcLeft = (m_column > 0) ?
                                         brcWinner(tc.brcLeft, m_tap->rgbrcTable[5]) :
                                         brcWinner(tc.brcLeft, m_tap->rgbrcTable[1]);
    const wvWare::Word97::BRC& brcRight = (m_column < nbCells - 1) ?
                                          brcWinner(tc.brcRight, m_tap->rgbrcTable[5]) :
                                          brcWinner(tc.brcRight, m_tap->rgbrcTable[3]);

    const wvWare::Word97::BRC& brcTL2BR = tc.brcTL2BR;
    const wvWare::Word97::BRC& brcTR2BL = tc.brcTR2BL;

    KoGenStyle cellStyle(KoGenStyle::TableCellAutoStyle, "table-cell");

    //in case a header or footer is processed, save the style into styles.xml
    if (document()->writingHeader()) {
        cellStyle.setAutoStyleInStylesDotXml(true);
    }

    //set borders for the four edges of the cell
    if (brcTop.brcType > 0 && brcTop.brcType < 64) {
        cellStyle.addProperty("fo:border-top", Conversion::setBorderAttributes(brcTop));
        QString kba = Conversion::borderCalligraAttributes(brcTop);
        if (!kba.isEmpty()) {
            cellStyle.addProperty("calligra:specialborder-top",kba);
        }
        QString dba = Conversion::setDoubleBorderAttributes(brcTop);
        if (!dba.isEmpty()) {
            cellStyle.addProperty("style:border-line-width-top", dba);
        }
    }

    //left
    if (brcLeft.brcType > 0 && brcLeft.brcType < 64) {
        cellStyle.addProperty("fo:border-left", Conversion::setBorderAttributes(brcLeft));
        QString kba = Conversion::borderCalligraAttributes(brcLeft);
        if (!kba.isEmpty()) {
            cellStyle.addProperty("calligra:specialborder-left",kba);
        }
        QString dba = Conversion::setDoubleBorderAttributes(brcLeft);
        if (!dba.isEmpty()) {
            cellStyle.addProperty("style:border-line-width-left", dba);
        }
    }

    //bottom
    if (brcBottom.brcType != 0 && brcBottom.brcType < 64) {
        cellStyle.addProperty("fo:border-bottom", Conversion::setBorderAttributes(brcBottom));
        QString kba = Conversion::borderCalligraAttributes(brcBottom);
        if (!kba.isEmpty()) {
            cellStyle.addProperty("calligra:specialborder-bottom",kba);
        }
        QString dba = Conversion::setDoubleBorderAttributes(brcBottom);
        if (!dba.isEmpty()) {
            cellStyle.addProperty("style:border-line-width-bottom", dba);
        }
    }

    //right
    if (brcRight.brcType > 0 && brcRight.brcType < 64) {
        cellStyle.addProperty("fo:border-right", Conversion::setBorderAttributes(brcRight));
        QString kba = Conversion::borderCalligraAttributes(brcRight);
        if (!kba.isEmpty()) {
            cellStyle.addProperty("calligra:specialborder-right",kba);
        }
        QString dba = Conversion::setDoubleBorderAttributes(brcRight);
        if (!dba.isEmpty()) {
            cellStyle.addProperty("style:border-line-width-right", dba);
        }
    }

    //top left to bottom right
    if (brcTL2BR.brcType > 0 && brcTL2BR.brcType < 64) {
        cellStyle.addProperty("style:diagonal-tl-br", Conversion::setBorderAttributes(brcTL2BR));
        QString kba = Conversion::borderCalligraAttributes(brcTL2BR);
        if (!kba.isEmpty()) {
            cellStyle.addProperty("calligra:specialborder-tl-br",kba);
        }
        QString dba = Conversion::setDoubleBorderAttributes(brcTL2BR);
        if (!dba.isEmpty()) {
            cellStyle.addProperty("style:diagonal-tl-br-widths", dba);
        }
    }

    //top right to bottom left
    if (brcTR2BL.brcType > 0 && brcTR2BL.brcType < 64) {
        cellStyle.addProperty("style:diagonal-bl-tr", Conversion::setBorderAttributes(brcTR2BL));
        QString kba = Conversion::borderCalligraAttributes(brcTR2BL);
        if (!kba.isEmpty()) {
            cellStyle.addProperty("calligra:specialborder-tr-bl",kba);
        }
        QString dba = Conversion::setDoubleBorderAttributes(brcTR2BL);
        if (!dba.isEmpty()) {
            cellStyle.addProperty("style:diagonal-bl-tr-widths", dba);
        }
    }

    //text direction
    //if(tc.fVertical) {
    //    cellStyle.addProperty("style:direction", "ttb");
    //}

    //process vertical alignment information
    QString align;
    switch (tc.vertAlign) {
    case vAlignTop:
        align = QString("top");
        break;
    case vAlignMiddle:
        align = QString("middle");
        break;
    case vAlignBottom:
        align = QString("bottom");
        break;
    }
    cellStyle.addProperty("style:vertical-align", align);

    //process cell padding information
    qreal padVert = twipsToPt(m_tap->padVert);
    qreal padHorz = twipsToPt(m_tap->padHorz);
    cellStyle.addPropertyPt("fo:padding-top", padVert);
    cellStyle.addPropertyPt("fo:padding-bottom", padVert);
    cellStyle.addPropertyPt("fo:padding-left", padHorz);
    cellStyle.addPropertyPt("fo:padding-right", padHorz);

    QString cellStyleName = m_mainStyles->insert(cellStyle, "cell");

//     emit sigTableCellStart( m_row, leftCellNumber, rowSpan, colSpan, cellRect, m_currentTable->name,
//                             brcTop, brcBottom, brcLeft, brcRight, m_tap->rgshd[ m_column ] );

    // Start a table cell in the content.
    writer->startElement("table:table-cell");
    m_cellOpen = true;
    writer->addAttribute("table:style-name", cellStyleName.toUtf8());

    if (rowSpan > 1) {
        writer->addAttribute("table:number-rows-spanned", rowSpan);
    }
    if (colSpan > 1) {
        writer->addAttribute("table:number-columns-spanned", colSpan);
        m_colSpan = colSpan;
    } else {
        // If not set to colSpan, we need to (re)set it to a known value.
        m_colSpan = 1;
    }
    m_cellStyleName = cellStyleName;
}
void GenValidationStyles::writeStyle(KoXmlWriter& writer)
{
    if (m_styles.count() > 0) {
        writer.startElement("table:content-validations");
        StyleMap::Iterator it;
        for (it = m_styles.begin(); it != m_styles.end(); ++it) {
            writer.startElement("table:content-validation");
            writer.addAttribute("table:name", it.value());
            writer.addAttribute("table:allow-empty-cell", it.key().allowEmptyCell);
            writer.addAttribute("table:condition", it.key().condition);

            writer.startElement("table:help-message");
            writer.addAttribute("table:title", it.key().title);
            writer.addAttribute("table:display", it.key().displayValidationInformation);

            QStringList text = it.key().messageInfo.split('\n', QString::SkipEmptyParts);
            for (QStringList::Iterator it2 = text.begin(); it2 != text.end(); ++it2) {
                writer.startElement("text:p");
                writer.addTextNode(*it2);
                writer.endElement();
            }
            writer.endElement();

            writer.startElement("table:error-message");
            writer.addAttribute("table:message-type", it.key().messageType);

            writer.addAttribute("table:title", it.key().titleInfo);
            writer.addAttribute("table:display", it.key().displayMessage);
            text = it.key().message.split('\n', QString::SkipEmptyParts);
            for (QStringList::Iterator it3 = text.begin(); it3 != text.end(); ++it3) {
                writer.startElement("text:p");
                writer.addTextNode(*it3);
                writer.endElement();
            }
            writer.endElement();

            writer.endElement();
        }
        writer.endElement();//close sheet:content-validation
    }
}
示例#30
0
static void writeChord(KoXmlWriter& w, Chord* chord, Voice* voice, Part* part, int bar)
{
    if (!chord->noteCount()) {
        w.startElement("music:note");

        w.startElement("music:rest");
        w.endElement();  // music:rest

        w.startElement("music:duration");
        w.addTextNode(QString::number(chord->length()));
        w.endElement(); // music:duration
        
        w.startElement("music:voice");
        w.addTextNode(QString::number(part->indexOfVoice(voice) + 1));
        w.endElement(); // music:voice
        
        w.startElement("music:type");
        w.addTextNode(durationToString(chord->duration()));
        w.endElement(); // music:type
        
        for (int i = 0; i < chord->dots(); i++) {
            w.startElement("music:dot");
            w.endElement(); // music:dot
        }
        
        if (part->staffCount() > 1) {
            // only write staff info when more than one staff exists
            Staff* s = chord->staff();
            w.startElement("music:staff");
            w.addTextNode(QString::number(part->indexOfStaff(s) + 1));
            w.endElement();  //music:staff
        }
        w.endElement(); // music:note
    } else for (int n = 0; n < chord->noteCount(); n++) {
        Staff* staff = chord->note(n)->staff();
        w.startElement("music:note");
        
        if (n > 0) {
            w.startElement("music:chord");
            w.endElement(); // music:chord
        }

        w.startElement("music:pitch");
        w.startElement("music:step");
        int pitch = chord->note(n)->pitch();
        char note = 'A' + ((((pitch + 2) % 7) + 7) % 7);
        w.addTextNode(QString(note));
        w.endElement(); // music:step

        if (chord->note(n)->accidentals()) {
            w.startElement("music:alter");
            w.addTextNode(QString::number(chord->note(n)->accidentals()));
            w.endElement(); // music:alter
        }
        
        w.startElement("music:octave");
        w.addTextNode(QString::number((pitch + 4*7) / 7)); // first add, than divide to get proper rounding
        w.endElement(); // music:octave
        w.endElement(); // music:pitch
        w.startElement("music:duration");
        w.addTextNode(QString::number(chord->length()));
        w.endElement(); // music:duration
        
        w.startElement("music:voice");
        w.addTextNode(QString::number(part->indexOfVoice(voice) + 1));
        w.endElement(); // music:voice
        
        w.startElement("music:type");
        w.addTextNode(durationToString(chord->duration()));
        w.endElement(); // music:type
        
        for (int i = 0; i < chord->dots(); i++) {
            w.startElement("music:dot");
            w.endElement(); // music:dot
        }
        
        int activeAccidentals = 0;
        KeySignature* ks = staff->lastKeySignatureChange(bar);
        if (ks) activeAccidentals = ks->accidentals(chord->note(n)->pitch());
        VoiceBar* vb = chord->voiceBar();
        // next check the bar for the last previous note in the same voice with the same pitch
        for (int e = 0; e < vb->elementCount(); e++) {
            Chord* c = dynamic_cast<Chord*>(vb->element(e));
            if (!c) continue;
            if (c == chord) break;
            for (int nid = 0; nid < c->noteCount(); nid++) {
                Note* note = c->note(nid);
                if (note->staff() != staff) continue;
                if (note->pitch() == chord->note(n)->pitch()) {
                    activeAccidentals = note->accidentals();
                }
            }
        }
        
        if (chord->note(n)->accidentals() != activeAccidentals) {
            w.startElement("music:accidental");
            switch (chord->note(n)->accidentals()) {
                case -2: w.addTextNode("flat-flat"); break;
                case -1: w.addTextNode("flat"); break;
                case  0: w.addTextNode("natural"); break;
                case  1: w.addTextNode("sharp"); break;
                case  2: w.addTextNode("double-sharp"); break;
            }
            w.endElement(); // music:accidental
        }
        
        if (part->staffCount() > 1) {
            // only write staff info when more than one staff exists
            Staff* s = chord->note(n)->staff();
            w.startElement("music:staff");
            w.addTextNode(QString::number(part->indexOfStaff(s) + 1));
            w.endElement();  //music:staff
        }
        w.endElement(); // music:note
    }
}