void StoreDropTest::showZipContents( QByteArray data, const char* mimeType, bool oasis ) { if ( data.isEmpty() ) { setText( "No data!" ); return; } QBuffer buffer( data ); KoStore * store = KoStore::createStore( &buffer, KoStore::Read ); if ( store->bad() ) { setText( "Invalid ZIP!" ); return; } store->disallowNameExpansion(); QString txt = QString( "Valid ZIP file found for format " ) + mimeType + "\n"; if ( oasis ) { txt += loadTextFile( store, "content.xml" ); txt += loadTextFile( store, "styles.xml" ); txt += loadTextFile( store, "settings.xml" ); txt += loadTextFile( store, "META-INF/manifest.xml" ); } else { txt += loadTextFile( store, "maindoc.xml" ); } setText( txt ); }
bool KoOdfPaste::paste(KoOdf::DocumentType documentType, const QByteArray &bytes) { if (bytes.isEmpty()) return false; QBuffer buffer; buffer.setData(bytes); KoStore * store = KoStore::createStore(&buffer, KoStore::Read); store->disallowNameExpansion(); KoOdfReadStore odfStore(store); // KoOdfReadStore does not delete the store on destruction QString errorMessage; if (! odfStore.loadAndParse(errorMessage)) { kWarning(30002) << "loading and parsing failed:" << errorMessage; delete store; return false; } KoXmlElement content = odfStore.contentDoc().documentElement(); KoXmlElement realBody(KoXml::namedItemNS(content, KoXmlNS::office, "body")); if (realBody.isNull()) { kWarning(30002) << "No body tag found"; delete store; return false; } KoXmlElement body = KoXml::namedItemNS(realBody, KoXmlNS::office, KoOdf::bodyContentElement(documentType, false)); if (body.isNull()) { kWarning(30002) << "No" << KoOdf::bodyContentElement(documentType, true) << "tag found"; delete store; return false; } bool retval = process(body, odfStore); delete store; return retval; }
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; }
void KoOdfCollectionLoader::loadNativeFile(const QString& path) { delete m_shapeLoadingContext; delete m_loadingContext; m_shapeLoadingContext = 0; m_loadingContext = 0; if(m_odfStore) { delete m_odfStore->store(); delete m_odfStore; m_odfStore = 0; } KoStore* store = KoStore::createStore(path, KoStore::Read); if(store->bad()) { emit loadingFailed(i18n("Not a valid KOffice file: %1", m_path)); delete store; return; } store->disallowNameExpansion(); m_odfStore = new KoOdfReadStore(store); QString errorMessage; if(!m_odfStore->loadAndParse(errorMessage)) { emit loadingFailed(errorMessage); return; } KoOdfLoadingContext* m_loadingContext = new KoOdfLoadingContext(m_odfStore->styles(), m_odfStore->store()); // it ok here to pass an empty dataCenterMap as we don't have a document // tz: not sure if that is 100% correct what if an image is loaded in the collection it needs a image collection QMap<QString, KoDataCenter *> dataCenterMap; m_shapeLoadingContext = new KoShapeLoadingContext(*m_loadingContext, dataCenterMap); KoXmlElement content = m_odfStore->contentDoc().documentElement(); KoXmlElement realBody ( KoXml::namedItemNS( content, KoXmlNS::office, "body" ) ); if (realBody.isNull()) { kError() << "No body tag found!" << endl; emit loadingFailed(i18n("No body tag found in file: %1", path)); return; } m_body = KoXml::namedItemNS(realBody, KoXmlNS::office, "drawing"); if (m_body.isNull()) { kError() << "No office:drawing tag found!" << endl; emit loadingFailed(i18n("No office:drawing tag found in file: %1", path)); return; } m_page = m_body.firstChild().toElement(); if (m_page.isNull()) { kError() << "No shapes found!" << endl; emit loadingFailed(i18n("No shapes found in file: %1", path)); return; } m_shape = m_page.firstChild().toElement(); if (m_shape.isNull()) { kError() << "No shapes found!" << endl; emit loadingFailed(i18n("No shapes found in file: %1", path)); return; } m_loadingTimer->start(); }
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; }