/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include "OOXMLStreamImpl.hxx" #include "OOXMLDocumentImpl.hxx" #include "OOXMLBinaryObjectReference.hxx" #include "OOXMLFastDocumentHandler.hxx" #include "OOXMLPropertySet.hxx" #include #include #include #include #include #include #include #include #include #include // this extern variable is declared in OOXMLStreamImpl.hxx OUString customTarget; OUString embeddingsTarget; using namespace ::com::sun::star; namespace writerfilter::ooxml { OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t const & pStream, const uno::Reference& xStatusIndicator, bool bSkipImages, const uno::Sequence& rDescriptor) : mpStream(pStream) , mxStatusIndicator(xStatusIndicator) , mnXNoteId(0) , mbIsSubstream(false) , mbSkipImages(bSkipImages) , mnPercentSize(0) , mnProgressLastPos(0) , mnProgressCurrentPos(0) , mnProgressEndPos(0) , m_rBaseURL(utl::MediaDescriptor(rDescriptor).getUnpackedValueOrDefault("DocumentBaseURL", OUString())) , maMediaDescriptor(rDescriptor) , mxGraphicMapper(graphic::GraphicMapper::create(mpStream->getContext())) { pushShapeContext(); } OOXMLDocumentImpl::~OOXMLDocumentImpl() { } void OOXMLDocumentImpl::resolveFastSubStream(Stream & rStreamHandler, OOXMLStream::StreamType_t nType) { OOXMLStream::Pointer_t pStream; try { pStream = OOXMLDocumentFactory::createStream(mpStream, nType); } catch (uno::Exception const&) { TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "resolveFastSubStream: exception while " "resolving stream " << nType); return; } OOXMLStream::Pointer_t savedStream = mpStream; mpStream = pStream; uno::Reference xParser(mpStream->getFastParser()); if (xParser.is()) { uno::Reference xContext(mpStream->getContext()); rtl::Reference pDocHandler = new OOXMLFastDocumentHandler(xContext, &rStreamHandler, this, mnXNoteId); uno::Reference xTokenHandler(mpStream->getFastTokenHandler()); xParser->setFastDocumentHandler(pDocHandler); xParser->setTokenHandler(xTokenHandler); uno::Reference xInputStream = mpStream->getDocumentStream(); if (xInputStream.is()) { struct xml::sax::InputSource oInputSource; oInputSource.aInputStream = xInputStream; xParser->parseStream(oInputSource); xInputStream->closeInput(); } } mpStream = savedStream; } void OOXMLDocumentImpl::resolveFastSubStreamWithId(Stream & rStream, const writerfilter::Reference::Pointer_t& pStream, sal_uInt32 nId) { rStream.substream(nId, pStream); } uno::Reference OOXMLDocumentImpl::importSubStream(OOXMLStream::StreamType_t nType) { uno::Reference xRet; OOXMLStream::Pointer_t pStream; try { pStream = OOXMLDocumentFactory::createStream(mpStream, nType); } catch (uno::Exception const&) { TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while " "importing stream " << nType); return xRet; } uno::Reference xInputStream = pStream->getDocumentStream(); if (xInputStream.is()) { try { uno::Reference xContext(mpStream->getContext()); uno::Reference xDomBuilder(xml::dom::DocumentBuilder::create(xContext)); xRet = xDomBuilder->parse(xInputStream); } catch (uno::Exception const&) { TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while " "parsing stream " << nType); return xRet; } } if (OOXMLStream::CUSTOMXML == nType) { importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS); } else if (OOXMLStream::CHARTS == nType) { importSubStreamRelations(pStream, OOXMLStream::EMBEDDINGS); } return xRet; } void OOXMLDocumentImpl::importSubStreamRelations(const OOXMLStream::Pointer_t& pStream, OOXMLStream::StreamType_t nType) { uno::Reference xRelation; OOXMLStream::Pointer_t cStream; try { cStream = OOXMLDocumentFactory::createStream(pStream, nType); } catch (uno::Exception const&) { TOOLS_WARN_EXCEPTION("writerfilter.ooxml", "importSubStreamRelations: exception while " "importing stream " << nType); return; } uno::Reference xcpInputStream = cStream->getDocumentStream(); if (!xcpInputStream.is()) return; // importing itemprops files for item.xml from customXml. if (OOXMLStream::CUSTOMXMLPROPS == nType) { try { uno::Reference xcpContext(pStream->getContext()); uno::Reference xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext)); xRelation = xDomBuilder->parse(xcpInputStream); } catch (uno::Exception const&) { TOOLS_WARN_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while " "parsing stream " << nType); mxCustomXmlProsDom = xRelation; } if(xRelation.is()) { mxCustomXmlProsDom = xRelation; } } else if(OOXMLStream::EMBEDDINGS == nType) { mxEmbeddings = xcpInputStream; } else if(OOXMLStream::CHARTS == nType) { importSubStreamRelations(cStream, OOXMLStream::EMBEDDINGS); } } void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId) { mnXNoteId = nId; } sal_Int32 OOXMLDocumentImpl::getXNoteId() const { return mnXNoteId; } const OUString & OOXMLDocumentImpl::getTarget() const { return mpStream->getTarget(); } writerfilter::Reference::Pointer_t OOXMLDocumentImpl::getSubStream(const OUString & rId) { OOXMLStream::Pointer_t pStream (OOXMLDocumentFactory::createStream(mpStream, rId)); OOXMLDocumentImpl * pTemp; // Do not pass status indicator to sub-streams: they are typically marginal in size, so we just track the main document for now. writerfilter::Reference::Pointer_t pRet( pTemp = new OOXMLDocumentImpl(pStream, uno::Reference(), mbSkipImages, maMediaDescriptor)); pTemp->setModel(mxModel); pTemp->setDrawPage(mxDrawPage); pTemp->mbIsSubstream = true; return pRet; } writerfilter::Reference::Pointer_t OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType, const sal_Int32 nId) { OOXMLStream::Pointer_t pStream = OOXMLDocumentFactory::createStream(mpStream, nType); // See above, no status indicator for the note stream, either. OOXMLDocumentImpl * pDocument = new OOXMLDocumentImpl(pStream, uno::Reference(), mbSkipImages, maMediaDescriptor); pDocument->setXNoteId(nId); pDocument->setModel(getModel()); pDocument->setDrawPage(getDrawPage()); return writerfilter::Reference::Pointer_t(pDocument); } void OOXMLDocumentImpl::resolveFootnote(Stream & rStream, Id aType, const sal_Int32 nNoteId) { if (!mpXFootnoteStream) mpXFootnoteStream = getXNoteStream(OOXMLStream::FOOTNOTES, nNoteId); Id nId; switch (aType) { case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator: case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator: nId = aType; break; default: nId = NS_ooxml::LN_footnote; break; } resolveFastSubStreamWithId(rStream, mpXFootnoteStream, nId); } void OOXMLDocumentImpl::resolveEndnote(Stream & rStream, Id aType, const sal_Int32 nNoteId) { if (!mpXEndnoteStream) mpXEndnoteStream = getXNoteStream(OOXMLStream::ENDNOTES, nNoteId); Id nId; switch (aType) { case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator: case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator: nId = aType; break; default: nId = NS_ooxml::LN_endnote; break; } resolveFastSubStreamWithId(rStream, mpXEndnoteStream, nId); } void OOXMLDocumentImpl::resolveCommentsExtendedStream(Stream& rStream) { resolveFastSubStream(rStream, OOXMLStream::COMMENTS_EXTENDED); } void OOXMLDocumentImpl::resolveComment(Stream & rStream, const sal_Int32 nId) { if (!mbCommentsExtendedResolved) { resolveCommentsExtendedStream(rStream); mbCommentsExtendedResolved = true; } writerfilter::Reference::Pointer_t pStream = getXNoteStream(OOXMLStream::COMMENTS, nId); resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_annotation); } OOXMLPropertySet * OOXMLDocumentImpl::getPicturePropSet (const OUString & rId) { OOXMLStream::Pointer_t pStream (OOXMLDocumentFactory::createStream(mpStream, rId)); writerfilter::Reference::Pointer_t pPicture (new OOXMLBinaryObjectReference(pStream)); OOXMLValue::Pointer_t pPayloadValue(new OOXMLBinaryValue(pPicture)); OOXMLPropertySet::Pointer_t pBlipSet(new OOXMLPropertySet); pBlipSet->add(NS_ooxml::LN_payload, pPayloadValue, OOXMLProperty::ATTRIBUTE); OOXMLValue::Pointer_t pBlipValue(new OOXMLPropertySetValue(pBlipSet)); OOXMLPropertySet * pProps = new OOXMLPropertySet; pProps->add(NS_ooxml::LN_blip, pBlipValue, OOXMLProperty::ATTRIBUTE); return pProps; } void OOXMLDocumentImpl::resolvePicture(Stream & rStream, const OUString & rId) { OOXMLPropertySet::Pointer_t pProps(getPicturePropSet(rId)); rStream.props(pProps.get()); } OUString OOXMLDocumentImpl::getTargetForId(const OUString & rId) { return mpStream->getTargetForId(rId); } void OOXMLDocumentImpl::resolveHeader(Stream & rStream, const sal_Int32 type, const OUString & rId) { writerfilter::Reference::Pointer_t pStream = getSubStream(rId); switch (type) { case NS_ooxml::LN_Value_ST_HdrFtr_even: resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerl); break; case NS_ooxml::LN_Value_ST_HdrFtr_default: // here we assume that default is right, but not necessarily true :-( resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerr); break; case NS_ooxml::LN_Value_ST_HdrFtr_first: resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerf); break; default: break; } } void OOXMLDocumentImpl::resolveFooter(Stream & rStream, const sal_Int32 type, const OUString & rId) { writerfilter::Reference::Pointer_t pStream = getSubStream(rId); switch (type) { case NS_ooxml::LN_Value_ST_HdrFtr_even: resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerl); break; case NS_ooxml::LN_Value_ST_HdrFtr_default: // here we assume that default is right, but not necessarily true :-( resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerr); break; case NS_ooxml::LN_Value_ST_HdrFtr_first: resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerf); break; default: break; } } namespace { // Ensures that the indicator is reset after exiting OOXMLDocumentImpl::resolve class StatusIndicatorGuard{ public: explicit StatusIndicatorGuard(css::uno::Reference const & xStatusIndicator) :mxStatusIndicator(xStatusIndicator) { } ~StatusIndicatorGuard() { if (mxStatusIndicator.is()) mxStatusIndicator->end(); } private: css::uno::Reference mxStatusIndicator; }; } void OOXMLDocumentImpl::resolve(Stream & rStream) { StatusIndicatorGuard aStatusIndicatorGuard(mxStatusIndicator); if (utl::MediaDescriptor(maMediaDescriptor).getUnpackedValueOrDefault("ReadGlossaries", false)) { resolveFastSubStream(rStream, OOXMLStream::GLOSSARY); return; } uno::Reference xParser(mpStream->getFastParser()); if (mxModel.is()) { uno::Reference xDocumentPropertiesSupplier(mxModel, uno::UNO_QUERY); uno::Reference xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties(); comphelper::SequenceAsHashMap aMap(xDocumentProperties->getDocumentStatistics()); if (aMap.find("ParagraphCount") != aMap.end()) { sal_Int32 nValue; if (aMap["ParagraphCount"] >>= nValue) { if (mxStatusIndicator.is()) { // We want to care about the progress if we know the estimated paragraph count and we have given a status indicator as well. // Set the end position only here, so later it's enough to check if that is non-zero in incrementProgress(). mnProgressEndPos = nValue; OUString aDocLoad(SvxResId(RID_SVXSTR_DOC_LOAD)); mxStatusIndicator->start(aDocLoad, mnProgressEndPos); mnPercentSize = mnProgressEndPos / 100; } } } } if (!xParser.is()) return; uno::Reference xContext(mpStream->getContext()); rStream.setDocumentReference(this); rtl::Reference pDocHandler = new OOXMLFastDocumentHandler(xContext, &rStream, this, mnXNoteId); pDocHandler->setIsSubstream( mbIsSubstream ); uno::Reference < xml::sax::XFastTokenHandler > xTokenHandler(mpStream->getFastTokenHandler()); resolveFastSubStream(rStream, OOXMLStream::SETTINGS); mxThemeDom = importSubStream(OOXMLStream::THEME); resolveFastSubStream(rStream, OOXMLStream::THEME); mxGlossaryDocDom = importSubStream(OOXMLStream::GLOSSARY); if (mxGlossaryDocDom.is()) resolveGlossaryStream(rStream); resolveEmbeddingsStream(mpStream); // Custom xml's are handled as part of grab bag. resolveCustomXmlStream(rStream); resolveFastSubStream(rStream, OOXMLStream::FONTTABLE); resolveFastSubStream(rStream, OOXMLStream::STYLES); resolveFastSubStream(rStream, OOXMLStream::NUMBERING); xParser->setFastDocumentHandler( pDocHandler ); xParser->setTokenHandler( xTokenHandler ); xml::sax::InputSource aParserInput; aParserInput.sSystemId = mpStream->getTarget(); aParserInput.aInputStream = mpStream->getDocumentStream(); try { xParser->parseStream(aParserInput); } catch (xml::sax::SAXException const& rErr) { // don't silently swallow these - handlers may not have been executed, // and the domain mapper is likely in an inconsistent state // In case user chooses to try to continue loading, don't ask again for this file SfxObjectShell* rShell = SfxObjectShell::GetShellFromComponent(mxModel); if (!rShell || !rShell->IsContinueImportOnFilterExceptions( OUStringConcatenation("SAXException: " + rErr.Message))) throw; } catch (uno::RuntimeException const&) { throw; } // note: cannot throw anything other than SAXException out of here? catch (uno::Exception const&) { css::uno::Any anyEx = cppu::getCaughtException(); SAL_WARN("writerfilter.ooxml", "OOXMLDocumentImpl::resolve(): " << exceptionToString(anyEx)); throw lang::WrappedTargetRuntimeException("", nullptr, anyEx); } catch (...) { SAL_WARN("writerfilter.ooxml", "OOXMLDocumentImpl::resolve(): non-UNO exception"); } } void OOXMLDocumentImpl::incrementProgress() { mnProgressCurrentPos++; // 1) If we know the end // 2) We progressed enough that updating makes sense // 3) We did not reach the end yet (possible in case the doc stat is misleading) if (mnProgressEndPos && mnProgressCurrentPos > (mnProgressLastPos + mnPercentSize) && mnProgressLastPos < mnProgressEndPos) { mnProgressLastPos = mnProgressCurrentPos; if (mxStatusIndicator.is()) mxStatusIndicator->setValue(mnProgressLastPos); } } void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream) { // Resolving all item[n].xml files from CustomXml folder. uno::Reference xRelationshipAccess; xRelationshipAccess.set(dynamic_cast(*mpStream).accessDocumentStream(), uno::UNO_QUERY); if (!xRelationshipAccess.is()) return; static const char sCustomType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"; static const char sCustomTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/customXml"; bool bFound = false; const uno::Sequence> aSeqs = xRelationshipAccess->getAllRelationships(); std::vector> aCustomXmlDomList; std::vector> aCustomXmlDomPropsList; for (const uno::Sequence& aSeq : aSeqs) { for (const beans::StringPair& aPair : aSeq) { // Need to resolve only customxml files from document relationships. // Skipping other files. if (aPair.Second == sCustomType || aPair.Second == sCustomTypeStrict) bFound = true; else if (aPair.First == "Target" && bFound) { // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl // to ensure customxml target is visited in lcl_getTarget. customTarget = aPair.Second; } } if (bFound) { uno::Reference customXmlTemp = importSubStream(OOXMLStream::CUSTOMXML); // This will add all item[n].xml with its relationship file i.e itemprops.xml to // grabbag list. if (mxCustomXmlProsDom.is() && customXmlTemp.is()) { aCustomXmlDomList.push_back(customXmlTemp); aCustomXmlDomPropsList.push_back(mxCustomXmlProsDom); resolveFastSubStream(rStream, OOXMLStream::CUSTOMXML); } bFound = false; } } mxCustomXmlDomList = comphelper::containerToSequence(aCustomXmlDomList); mxCustomXmlDomPropsList = comphelper::containerToSequence(aCustomXmlDomPropsList); } namespace { const char sSettingsType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"; const char sStylesType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"; const char sFonttableType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"; const char sWebSettings[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings"; const char sSettingsTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/settings"; const char sStylesTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/styles"; const char sFonttableTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/fontTable"; const char sWebSettingsStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/webSettings"; constexpr OUStringLiteral sId = u"Id"; constexpr OUStringLiteral sType = u"Type"; constexpr OUStringLiteral sTarget = u"Target"; constexpr OUStringLiteral sTargetMode = u"TargetMode"; constexpr OUStringLiteral sContentType = u"_contentType"; constexpr OUStringLiteral sRelDom = u"_relDom"; constexpr OUStringLiteral sSettingsContentType = u"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"; constexpr OUStringLiteral sStylesContentType = u"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"; constexpr OUStringLiteral sWebsettingsContentType = u"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"; constexpr OUStringLiteral sFonttableContentType = u"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"; } // See DocxExport::WriteGlossary void OOXMLDocumentImpl::resolveGlossaryStream(Stream & /*rStream*/) { OOXMLStream::Pointer_t pStream; try { pStream = OOXMLDocumentFactory::createStream(mpStream, OOXMLStream::GLOSSARY); } catch (uno::Exception const&) { TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "resolveGlossaryStream: exception while " "createStream for glossary" << OOXMLStream::GLOSSARY); return; } uno::Reference xRelationshipAccess; xRelationshipAccess.set(dynamic_cast(*pStream).accessDocumentStream(), uno::UNO_QUERY); if (!xRelationshipAccess.is()) return; const uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = xRelationshipAccess->getAllRelationships(); std::vector< uno::Sequence > aGlossaryDomList; for (const uno::Sequence< beans::StringPair >& aSeq : aSeqs) { comphelper::NamedValueCollection aRelDefinition; for (const auto& [name, value] : aSeq) aRelDefinition.put(name, value); const OUString gType = aRelDefinition.getOrDefault(sType, OUString{}); OOXMLStream::StreamType_t nType(OOXMLStream::UNKNOWN); if (gType == sSettingsType || gType == sSettingsTypeStrict) { nType = OOXMLStream::SETTINGS; aRelDefinition.put(sContentType, sSettingsContentType); } else if (gType == sStylesType || gType == sStylesTypeStrict) { nType = OOXMLStream::STYLES; aRelDefinition.put(sContentType, sStylesContentType); } else if (gType == sWebSettings || gType == sWebSettingsStrict) { nType = OOXMLStream::WEBSETTINGS; aRelDefinition.put(sContentType, sWebsettingsContentType); } else if (gType == sFonttableType || gType == sFonttableTypeStrict) { nType = OOXMLStream::FONTTABLE; aRelDefinition.put(sContentType, sFonttableContentType); } else if (aRelDefinition.getOrDefault(sTargetMode, OUString{}) != "External") { // Some internal relation, but we don't create a DOM for it here yet? SAL_WARN("writerfilter.ooxml", "Unknown type of glossary internal relation: " "Id=\"" + aRelDefinition.getOrDefault(sId, {}) + "\" " "Type=\"" + gType + "\" " "Target=\"" + aRelDefinition.getOrDefault(sTarget, {}) + "\""); continue; } if (nType != OOXMLStream::UNKNOWN) { try { auto gStream = OOXMLDocumentFactory::createStream(pStream, nType); uno::Reference xInputStream = gStream->getDocumentStream(); uno::Reference xContext(pStream->getContext()); uno::Reference xDomBuilder(xml::dom::DocumentBuilder::create(xContext)); uno::Reference xDom = xDomBuilder->parse(xInputStream); aRelDefinition.put(sRelDom, xDom); } catch (uno::Exception const&) { TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while " "parsing stream of Type" << nType); } } aGlossaryDomList.push_back(aRelDefinition.getNamedValues()); } mxGlossaryDomList = comphelper::containerToSequence(aGlossaryDomList); } void OOXMLDocumentImpl::resolveEmbeddingsStream(const OOXMLStream::Pointer_t& pStream) { uno::Reference xRelationshipAccess; xRelationshipAccess.set(dynamic_cast(*pStream).accessDocumentStream(), uno::UNO_QUERY); if (xRelationshipAccess.is()) { OUString const sChartType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"); OUString const sChartTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/chart"); OUString const sFootersType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"); OUString const sFootersTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/footer"); OUString const sHeaderType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"); OUString const sHeaderTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/header"); bool bFound = false; bool bHeaderFooterFound = false; OOXMLStream::StreamType_t streamType = OOXMLStream::UNKNOWN; const uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = xRelationshipAccess->getAllRelationships(); for (const uno::Sequence< beans::StringPair >& aSeq : aSeqs) { for (const beans::StringPair& aPair : aSeq) { if (aPair.Second == sChartType || aPair.Second == sChartTypeStrict) { bFound = true; } else if(aPair.Second == sFootersType || aPair.Second == sFootersTypeStrict) { bHeaderFooterFound = true; streamType = OOXMLStream::FOOTER; } else if(aPair.Second == sHeaderType || aPair.Second == sHeaderTypeStrict) { bHeaderFooterFound = true; streamType = OOXMLStream::HEADER; } else if(aPair.First == "Target" && ( bFound || bHeaderFooterFound )) { // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl // to ensure chart.xml target is visited in lcl_getTarget. customTarget = aPair.Second; } } if( bFound || bHeaderFooterFound) { if(bFound) { importSubStreamRelations(pStream, OOXMLStream::CHARTS); } if(bHeaderFooterFound) { try { OOXMLStream::Pointer_t Stream = OOXMLDocumentFactory::createStream(pStream, streamType); if (Stream) resolveEmbeddingsStream(Stream); } catch (uno::Exception const&) { TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "resolveEmbeddingsStream: can't find header/footer whilst " "resolving stream " << streamType); return; } } beans::PropertyValue embeddingsTemp; // This will add all .xlsx and .bin to grabbag list. if(bFound && mxEmbeddings.is()) { embeddingsTemp.Name = embeddingsTarget; embeddingsTemp.Value <<= mxEmbeddings; aEmbeddings.push_back(embeddingsTemp); mxEmbeddings.clear(); } bFound = false; bHeaderFooterFound = false; } } } if (!aEmbeddings.empty()) mxEmbeddingsList = comphelper::containerToSequence(aEmbeddings); } uno::Reference OOXMLDocumentImpl::getGlossaryDocDom( ) { return mxGlossaryDocDom; } uno::Sequence > OOXMLDocumentImpl::getGlossaryDomList() { return mxGlossaryDomList; } uno::Reference OOXMLDocumentImpl::getInputStreamForId(const OUString & rId) { OOXMLStream::Pointer_t pStream(OOXMLDocumentFactory::createStream(mpStream, rId)); return pStream->getDocumentStream(); } void OOXMLDocumentImpl::setModel(uno::Reference xModel) { mxModel.set(xModel); } uno::Reference OOXMLDocumentImpl::getModel() { return mxModel; } void OOXMLDocumentImpl::setDrawPage(uno::Reference xDrawPage) { mxDrawPage.set(xDrawPage); } uno::Reference OOXMLDocumentImpl::getDrawPage() { return mxDrawPage; } const uno::Sequence& OOXMLDocumentImpl::getMediaDescriptor() const { return maMediaDescriptor; } void OOXMLDocumentImpl::setShapeContext( rtl::Reference xContext ) { if (!maShapeContexts.empty()) maShapeContexts.top() = xContext; } rtl::Reference OOXMLDocumentImpl::getShapeContext( ) { if (!maShapeContexts.empty()) return maShapeContexts.top(); else return {}; } void OOXMLDocumentImpl::pushShapeContext() { maShapeContexts.push({}); } void OOXMLDocumentImpl::popShapeContext() { if (!maShapeContexts.empty()) maShapeContexts.pop(); } uno::Reference OOXMLDocumentImpl::getThemeDom( ) { return mxThemeDom; } uno::Sequence > OOXMLDocumentImpl::getCustomXmlDomList( ) { return mxCustomXmlDomList; } uno::Sequence > OOXMLDocumentImpl::getCustomXmlDomPropsList( ) { return mxCustomXmlDomPropsList; } uno::Sequence OOXMLDocumentImpl::getEmbeddingsList( ) { return mxEmbeddingsList; } const rtl::Reference& OOXMLDocumentImpl::getShapeFilterBase() { if (!mxShapeFilterBase) mxShapeFilterBase = new oox::shape::ShapeFilterBase(mpStream->getContext()); return mxShapeFilterBase; } OOXMLDocument * OOXMLDocumentFactory::createDocument (const OOXMLStream::Pointer_t& pStream, const uno::Reference& xStatusIndicator, bool mbSkipImages, const uno::Sequence& rDescriptor) { return new OOXMLDocumentImpl(pStream, xStatusIndicator, mbSkipImages, rDescriptor); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */