1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/sequenceashashmap.hxx>
22 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
23 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
24 #include <com/sun/star/xml/sax/SAXException.hpp>
25 #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
26 #include <com/sun/star/graphic/GraphicMapper.hpp>
27 #include <ooxml/resourceids.hxx>
28 #include <oox/drawingml/theme.hxx>
29 #include <oox/shape/ShapeFilterBase.hxx>
30 #include "OOXMLStreamImpl.hxx"
31 #include "OOXMLDocumentImpl.hxx"
32 #include "OOXMLBinaryObjectReference.hxx"
33 #include "OOXMLFastDocumentHandler.hxx"
34 #include "OOXMLPropertySet.hxx"
36 #include <sal/log.hxx>
37 #include <comphelper/diagnose_ex.hxx>
38 #include <svx/dialmgr.hxx>
39 #include <svx/strings.hrc>
40 #include <comphelper/sequence.hxx>
41 #include <comphelper/namedvaluecollection.hxx>
42 #include <cppuhelper/exc_hlp.hxx>
43 #include <unotools/mediadescriptor.hxx>
46 #include <sfx2/objsh.hxx>
49 // this extern variable is declared in OOXMLStreamImpl.hxx
50 OUString customTarget
;
51 OUString embeddingsTarget
;
52 using namespace ::com::sun::star
;
53 namespace writerfilter::ooxml
56 OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream
, uno::Reference
<task::XStatusIndicator
> xStatusIndicator
, bool bSkipImages
, const uno::Sequence
<beans::PropertyValue
>& rDescriptor
)
57 : mpStream(std::move(pStream
))
58 , mxStatusIndicator(std::move(xStatusIndicator
))
60 , mbIsSubstream(false)
61 , mbSkipImages(bSkipImages
)
63 , mnProgressLastPos(0)
64 , mnProgressCurrentPos(0)
66 , m_rBaseURL(utl::MediaDescriptor(rDescriptor
).getUnpackedValueOrDefault("DocumentBaseURL", OUString()))
67 , maMediaDescriptor(rDescriptor
)
68 , mxGraphicMapper(graphic::GraphicMapper::create(mpStream
->getContext()))
73 OOXMLDocumentImpl::~OOXMLDocumentImpl()
77 void OOXMLDocumentImpl::resolveFastSubStream(Stream
& rStreamHandler
,
78 OOXMLStream::StreamType_t nType
)
80 OOXMLStream::Pointer_t pStream
;
83 pStream
= OOXMLDocumentFactory::createStream(mpStream
, nType
);
85 catch (uno::Exception
const&)
87 TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "resolveFastSubStream: exception while "
88 "resolving stream " << nType
);
91 OOXMLStream::Pointer_t savedStream
= mpStream
;
94 uno::Reference
<xml::sax::XFastParser
> xParser(mpStream
->getFastParser());
98 uno::Reference
<uno::XComponentContext
> xContext(mpStream
->getContext());
99 rtl::Reference
<OOXMLFastDocumentHandler
> pDocHandler
=
100 new OOXMLFastDocumentHandler(xContext
, &rStreamHandler
, this, mnXNoteId
);
102 uno::Reference
<xml::sax::XFastTokenHandler
> xTokenHandler(mpStream
->getFastTokenHandler());
104 xParser
->setFastDocumentHandler(pDocHandler
);
105 xParser
->setTokenHandler(xTokenHandler
);
107 uno::Reference
<io::XInputStream
> xInputStream
= mpStream
->getDocumentStream();
109 if (xInputStream
.is())
111 struct xml::sax::InputSource oInputSource
;
112 oInputSource
.aInputStream
= xInputStream
;
113 xParser
->parseStream(oInputSource
);
115 xInputStream
->closeInput();
119 mpStream
= savedStream
;
122 void OOXMLDocumentImpl::resolveFastSubStreamWithId(Stream
& rStream
,
123 const writerfilter::Reference
<Stream
>::Pointer_t
& pStream
,
126 rStream
.substream(nId
, pStream
);
129 uno::Reference
<xml::dom::XDocument
> OOXMLDocumentImpl::importSubStream(OOXMLStream::StreamType_t nType
)
131 uno::Reference
<xml::dom::XDocument
> xRet
;
133 OOXMLStream::Pointer_t pStream
;
136 pStream
= OOXMLDocumentFactory::createStream(mpStream
, nType
);
138 catch (uno::Exception
const&)
140 TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while "
141 "importing stream " << nType
);
145 uno::Reference
<io::XInputStream
> xInputStream
= pStream
->getDocumentStream();
146 if (xInputStream
.is())
150 uno::Reference
<uno::XComponentContext
> xContext(mpStream
->getContext());
151 uno::Reference
<xml::dom::XDocumentBuilder
> xDomBuilder(xml::dom::DocumentBuilder::create(xContext
));
152 xRet
= xDomBuilder
->parse(xInputStream
);
154 catch (uno::Exception
const&)
156 TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while "
157 "parsing stream " << nType
);
162 if (OOXMLStream::CUSTOMXML
== nType
)
164 importSubStreamRelations(pStream
, OOXMLStream::CUSTOMXMLPROPS
);
166 else if (OOXMLStream::CHARTS
== nType
)
168 importSubStreamRelations(pStream
, OOXMLStream::EMBEDDINGS
);
175 void OOXMLDocumentImpl::importSubStreamRelations(const OOXMLStream::Pointer_t
& pStream
, OOXMLStream::StreamType_t nType
)
177 uno::Reference
<xml::dom::XDocument
> xRelation
;
178 OOXMLStream::Pointer_t cStream
;
181 cStream
= OOXMLDocumentFactory::createStream(pStream
, nType
);
183 catch (uno::Exception
const&)
185 TOOLS_WARN_EXCEPTION("writerfilter.ooxml", "importSubStreamRelations: exception while "
186 "importing stream " << nType
);
190 uno::Reference
<io::XInputStream
> xcpInputStream
= cStream
->getDocumentStream();
192 if (!xcpInputStream
.is())
195 // importing itemprops files for item.xml from customXml.
196 if (OOXMLStream::CUSTOMXMLPROPS
== nType
)
200 uno::Reference
<uno::XComponentContext
> xcpContext(pStream
->getContext());
201 uno::Reference
<xml::dom::XDocumentBuilder
> xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext
));
202 xRelation
= xDomBuilder
->parse(xcpInputStream
);
204 catch (uno::Exception
const&)
206 TOOLS_WARN_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while "
207 "parsing stream " << nType
);
208 mxCustomXmlProsDom
= xRelation
;
213 mxCustomXmlProsDom
= xRelation
;
216 else if(OOXMLStream::EMBEDDINGS
== nType
)
218 mxEmbeddings
= xcpInputStream
;
220 else if(OOXMLStream::CHARTS
== nType
)
222 importSubStreamRelations(cStream
, OOXMLStream::EMBEDDINGS
);
228 void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId
)
233 sal_Int32
OOXMLDocumentImpl::getXNoteId() const
238 const OUString
& OOXMLDocumentImpl::getTarget() const
240 return mpStream
->getTarget();
243 writerfilter::Reference
<Stream
>::Pointer_t
244 OOXMLDocumentImpl::getSubStream(const OUString
& rId
)
246 OOXMLStream::Pointer_t pStream
247 (OOXMLDocumentFactory::createStream(mpStream
, rId
));
249 OOXMLDocumentImpl
* pTemp
;
250 // Do not pass status indicator to sub-streams: they are typically marginal in size, so we just track the main document for now.
251 writerfilter::Reference
<Stream
>::Pointer_t
pRet( pTemp
= new OOXMLDocumentImpl(pStream
, uno::Reference
<task::XStatusIndicator
>(), mbSkipImages
, maMediaDescriptor
));
252 pTemp
->setModel(mxModel
);
253 pTemp
->setDrawPage(mxDrawPage
);
254 pTemp
->mbIsSubstream
= true;
258 writerfilter::Reference
<Stream
>::Pointer_t
259 OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType
, const sal_Int32 nId
)
261 OOXMLStream::Pointer_t pStream
=
262 OOXMLDocumentFactory::createStream(mpStream
, nType
);
263 // See above, no status indicator for the note stream, either.
264 OOXMLDocumentImpl
* pDocument
= new OOXMLDocumentImpl(pStream
, uno::Reference
<task::XStatusIndicator
>(), mbSkipImages
, maMediaDescriptor
);
265 pDocument
->setXNoteId(nId
);
266 pDocument
->setModel(getModel());
267 pDocument
->setDrawPage(getDrawPage());
269 return writerfilter::Reference
<Stream
>::Pointer_t(pDocument
);
272 void OOXMLDocumentImpl::resolveFootnote(Stream
& rStream
,
274 const sal_Int32 nNoteId
)
276 if (!mpXFootnoteStream
)
277 mpXFootnoteStream
= getXNoteStream(OOXMLStream::FOOTNOTES
, nNoteId
);
282 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator
:
283 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator
:
287 nId
= NS_ooxml::LN_footnote
;
291 resolveFastSubStreamWithId(rStream
, mpXFootnoteStream
, nId
);
294 void OOXMLDocumentImpl::resolveEndnote(Stream
& rStream
,
296 const sal_Int32 nNoteId
)
298 if (!mpXEndnoteStream
)
299 mpXEndnoteStream
= getXNoteStream(OOXMLStream::ENDNOTES
, nNoteId
);
304 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator
:
305 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator
:
309 nId
= NS_ooxml::LN_endnote
;
313 resolveFastSubStreamWithId(rStream
, mpXEndnoteStream
, nId
);
316 void OOXMLDocumentImpl::resolveCommentsExtendedStream(Stream
& rStream
)
318 resolveFastSubStream(rStream
, OOXMLStream::COMMENTS_EXTENDED
);
321 void OOXMLDocumentImpl::resolveComment(Stream
& rStream
,
324 if (!mbCommentsExtendedResolved
)
326 resolveCommentsExtendedStream(rStream
);
327 mbCommentsExtendedResolved
= true;
330 writerfilter::Reference
<Stream
>::Pointer_t pStream
=
331 getXNoteStream(OOXMLStream::COMMENTS
, nId
);
333 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_annotation
);
336 OOXMLPropertySet
* OOXMLDocumentImpl::getPicturePropSet
337 (const OUString
& rId
)
339 OOXMLStream::Pointer_t pStream
340 (OOXMLDocumentFactory::createStream(mpStream
, rId
));
342 writerfilter::Reference
<BinaryObj
>::Pointer_t pPicture
343 (new OOXMLBinaryObjectReference(pStream
));
345 OOXMLValue::Pointer_t
pPayloadValue(new OOXMLBinaryValue(pPicture
));
347 OOXMLPropertySet::Pointer_t
pBlipSet(new OOXMLPropertySet
);
349 pBlipSet
->add(NS_ooxml::LN_payload
, pPayloadValue
, OOXMLProperty::ATTRIBUTE
);
351 OOXMLValue::Pointer_t
pBlipValue(new OOXMLPropertySetValue(pBlipSet
));
353 OOXMLPropertySet
* pProps
= new OOXMLPropertySet
;
355 pProps
->add(NS_ooxml::LN_blip
, pBlipValue
, OOXMLProperty::ATTRIBUTE
);
360 void OOXMLDocumentImpl::resolvePicture(Stream
& rStream
,
361 const OUString
& rId
)
363 OOXMLPropertySet::Pointer_t
pProps(getPicturePropSet(rId
));
365 rStream
.props(pProps
.get());
368 OUString
OOXMLDocumentImpl::getTargetForId(const OUString
& rId
)
370 return mpStream
->getTargetForId(rId
);
373 void OOXMLDocumentImpl::resolveHeader(Stream
& rStream
,
374 const sal_Int32 type
,
375 const OUString
& rId
)
377 writerfilter::Reference
<Stream
>::Pointer_t pStream
=
381 case NS_ooxml::LN_Value_ST_HdrFtr_even
:
382 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_headerl
);
384 case NS_ooxml::LN_Value_ST_HdrFtr_default
: // here we assume that default is right, but not necessarily true :-(
385 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_headerr
);
387 case NS_ooxml::LN_Value_ST_HdrFtr_first
:
388 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_headerf
);
395 void OOXMLDocumentImpl::resolveFooter(Stream
& rStream
,
396 const sal_Int32 type
,
397 const OUString
& rId
)
399 writerfilter::Reference
<Stream
>::Pointer_t pStream
=
404 case NS_ooxml::LN_Value_ST_HdrFtr_even
:
405 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_footerl
);
407 case NS_ooxml::LN_Value_ST_HdrFtr_default
: // here we assume that default is right, but not necessarily true :-(
408 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_footerr
);
410 case NS_ooxml::LN_Value_ST_HdrFtr_first
:
411 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_footerf
);
419 // Ensures that the indicator is reset after exiting OOXMLDocumentImpl::resolve
420 class StatusIndicatorGuard
{
422 explicit StatusIndicatorGuard(css::uno::Reference
<css::task::XStatusIndicator
> xStatusIndicator
)
423 :mxStatusIndicator(std::move(xStatusIndicator
))
427 ~StatusIndicatorGuard()
429 if (mxStatusIndicator
.is())
430 mxStatusIndicator
->end();
434 css::uno::Reference
<css::task::XStatusIndicator
> mxStatusIndicator
;
438 void OOXMLDocumentImpl::resolve(Stream
& rStream
)
440 StatusIndicatorGuard
aStatusIndicatorGuard(mxStatusIndicator
);
442 if (utl::MediaDescriptor(maMediaDescriptor
).getUnpackedValueOrDefault("ReadGlossaries", false))
444 resolveFastSubStream(rStream
, OOXMLStream::GLOSSARY
);
448 uno::Reference
<xml::sax::XFastParser
> xParser(mpStream
->getFastParser());
452 uno::Reference
<document::XDocumentPropertiesSupplier
> xDocumentPropertiesSupplier(mxModel
, uno::UNO_QUERY
);
453 uno::Reference
<document::XDocumentProperties
> xDocumentProperties
= xDocumentPropertiesSupplier
->getDocumentProperties();
454 comphelper::SequenceAsHashMap
aMap(xDocumentProperties
->getDocumentStatistics());
455 if (aMap
.find("ParagraphCount") != aMap
.end())
458 if (aMap
["ParagraphCount"] >>= nValue
)
460 if (mxStatusIndicator
.is())
462 // We want to care about the progress if we know the estimated paragraph count and we have given a status indicator as well.
463 // Set the end position only here, so later it's enough to check if that is non-zero in incrementProgress().
464 mnProgressEndPos
= nValue
;
465 OUString
aDocLoad(SvxResId(RID_SVXSTR_DOC_LOAD
));
466 mxStatusIndicator
->start(aDocLoad
, mnProgressEndPos
);
467 mnPercentSize
= mnProgressEndPos
/ 100;
476 uno::Reference
<uno::XComponentContext
> xContext(mpStream
->getContext());
478 rStream
.setDocumentReference(this);
480 rtl::Reference
<OOXMLFastDocumentHandler
> pDocHandler
=
481 new OOXMLFastDocumentHandler(xContext
, &rStream
, this, mnXNoteId
);
482 pDocHandler
->setIsSubstream( mbIsSubstream
);
483 uno::Reference
< xml::sax::XFastTokenHandler
> xTokenHandler(mpStream
->getFastTokenHandler());
485 resolveFastSubStream(rStream
, OOXMLStream::SETTINGS
);
486 mxThemeDom
= importSubStream(OOXMLStream::THEME
);
487 resolveFastSubStream(rStream
, OOXMLStream::THEME
);
488 // Convert the oox::Theme to the draw page
490 auto pThemePtr
= getTheme();
492 pThemePtr
->addTheme(getDrawPage());
494 mxGlossaryDocDom
= importSubStream(OOXMLStream::GLOSSARY
);
495 if (mxGlossaryDocDom
.is())
496 resolveGlossaryStream(rStream
);
498 resolveEmbeddingsStream(mpStream
);
500 // Custom xml's are handled as part of grab bag.
501 resolveCustomXmlStream(rStream
);
503 resolveFastSubStream(rStream
, OOXMLStream::FONTTABLE
);
504 resolveFastSubStream(rStream
, OOXMLStream::STYLES
);
505 resolveFastSubStream(rStream
, OOXMLStream::NUMBERING
);
507 xParser
->setFastDocumentHandler( pDocHandler
);
508 xParser
->setTokenHandler( xTokenHandler
);
510 xml::sax::InputSource aParserInput
;
511 aParserInput
.sSystemId
= mpStream
->getTarget();
512 aParserInput
.aInputStream
= mpStream
->getDocumentStream();
515 xParser
->parseStream(aParserInput
);
517 catch (xml::sax::SAXException
const& rErr
)
519 // don't silently swallow these - handlers may not have been executed,
520 // and the domain mapper is likely in an inconsistent state
521 // In case user chooses to try to continue loading, don't ask again for this file
522 SfxObjectShell
* rShell
= SfxObjectShell::GetShellFromComponent(mxModel
);
524 || !rShell
->IsContinueImportOnFilterExceptions(
525 Concat2View("SAXException: " + rErr
.Message
)))
528 catch (uno::RuntimeException
const&)
532 // note: cannot throw anything other than SAXException out of here?
533 catch (uno::Exception
const&)
535 css::uno::Any anyEx
= cppu::getCaughtException();
536 SAL_WARN("writerfilter.ooxml", "OOXMLDocumentImpl::resolve(): " << exceptionToString(anyEx
));
537 throw lang::WrappedTargetRuntimeException("", nullptr, anyEx
);
541 SAL_WARN("writerfilter.ooxml",
542 "OOXMLDocumentImpl::resolve(): non-UNO exception");
546 void OOXMLDocumentImpl::incrementProgress()
548 mnProgressCurrentPos
++;
549 // 1) If we know the end
550 // 2) We progressed enough that updating makes sense
551 // 3) We did not reach the end yet (possible in case the doc stat is misleading)
552 if (mnProgressEndPos
&& mnProgressCurrentPos
> (mnProgressLastPos
+ mnPercentSize
) && mnProgressLastPos
< mnProgressEndPos
)
554 mnProgressLastPos
= mnProgressCurrentPos
;
555 if (mxStatusIndicator
.is())
556 mxStatusIndicator
->setValue(mnProgressLastPos
);
560 void OOXMLDocumentImpl::resolveCustomXmlStream(Stream
& rStream
)
562 // Resolving all item[n].xml files from CustomXml folder.
563 uno::Reference
<embed::XRelationshipAccess
> xRelationshipAccess
;
564 xRelationshipAccess
.set(dynamic_cast<OOXMLStreamImpl
&>(*mpStream
).accessDocumentStream(), uno::UNO_QUERY
);
565 if (!xRelationshipAccess
.is())
568 static const char sCustomType
[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
569 static const char sCustomTypeStrict
[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/customXml";
571 const uno::Sequence
<uno::Sequence
< beans::StringPair
>> aSeqs
= xRelationshipAccess
->getAllRelationships();
572 std::vector
<uno::Reference
<xml::dom::XDocument
>> aCustomXmlDomList
;
573 std::vector
<uno::Reference
<xml::dom::XDocument
>> aCustomXmlDomPropsList
;
574 for (const uno::Sequence
<beans::StringPair
>& aSeq
: aSeqs
)
576 for (const beans::StringPair
& aPair
: aSeq
)
578 // Need to resolve only customxml files from document relationships.
579 // Skipping other files.
580 if (aPair
.Second
== sCustomType
||
581 aPair
.Second
== sCustomTypeStrict
)
583 else if (aPair
.First
== "Target" && bFound
)
585 // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
586 // to ensure customxml target is visited in lcl_getTarget.
587 customTarget
= aPair
.Second
;
593 uno::Reference
<xml::dom::XDocument
> customXmlTemp
= importSubStream(OOXMLStream::CUSTOMXML
);
594 // This will add all item[n].xml with its relationship file i.e itemprops.xml to
596 if (mxCustomXmlProsDom
.is() && customXmlTemp
.is())
598 aCustomXmlDomList
.push_back(customXmlTemp
);
599 aCustomXmlDomPropsList
.push_back(mxCustomXmlProsDom
);
600 resolveFastSubStream(rStream
, OOXMLStream::CUSTOMXML
);
607 mxCustomXmlDomList
= comphelper::containerToSequence(aCustomXmlDomList
);
608 mxCustomXmlDomPropsList
= comphelper::containerToSequence(aCustomXmlDomPropsList
);
613 const char sSettingsType
[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings";
614 const char sStylesType
[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
615 const char sFonttableType
[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable";
616 const char sWebSettings
[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings";
617 const char sSettingsTypeStrict
[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/settings";
618 const char sStylesTypeStrict
[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/styles";
619 const char sFonttableTypeStrict
[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/fontTable";
620 const char sWebSettingsStrict
[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/webSettings";
622 constexpr OUStringLiteral sId
= u
"Id";
623 constexpr OUStringLiteral sType
= u
"Type";
624 constexpr OUStringLiteral sTarget
= u
"Target";
625 constexpr OUStringLiteral sTargetMode
= u
"TargetMode";
626 constexpr OUStringLiteral sContentType
= u
"_contentType";
627 constexpr OUStringLiteral sRelDom
= u
"_relDom";
628 constexpr OUStringLiteral sSettingsContentType
= u
"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml";
629 constexpr OUStringLiteral sStylesContentType
= u
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
630 constexpr OUStringLiteral sWebsettingsContentType
= u
"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml";
631 constexpr OUStringLiteral sFonttableContentType
= u
"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml";
634 // See DocxExport::WriteGlossary
635 void OOXMLDocumentImpl::resolveGlossaryStream(Stream
& /*rStream*/)
637 OOXMLStream::Pointer_t pStream
;
640 pStream
= OOXMLDocumentFactory::createStream(mpStream
, OOXMLStream::GLOSSARY
);
642 catch (uno::Exception
const&)
644 TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "resolveGlossaryStream: exception while "
645 "createStream for glossary" << OOXMLStream::GLOSSARY
);
648 uno::Reference
<embed::XRelationshipAccess
> xRelationshipAccess
;
649 xRelationshipAccess
.set(dynamic_cast<OOXMLStreamImpl
&>(*pStream
).accessDocumentStream(), uno::UNO_QUERY
);
650 if (!xRelationshipAccess
.is())
654 const uno::Sequence
< uno::Sequence
< beans::StringPair
> >aSeqs
= xRelationshipAccess
->getAllRelationships();
655 std::vector
< uno::Sequence
<beans::NamedValue
> > aGlossaryDomList
;
656 for (const uno::Sequence
< beans::StringPair
>& aSeq
: aSeqs
)
658 comphelper::NamedValueCollection aRelDefinition
;
659 for (const auto& [name
, value
] : aSeq
)
660 aRelDefinition
.put(name
, value
);
662 const OUString gType
= aRelDefinition
.getOrDefault(sType
, OUString
{});
663 OOXMLStream::StreamType_t
nType(OOXMLStream::UNKNOWN
);
664 if (gType
== sSettingsType
|| gType
== sSettingsTypeStrict
)
666 nType
= OOXMLStream::SETTINGS
;
667 aRelDefinition
.put(sContentType
, sSettingsContentType
);
669 else if (gType
== sStylesType
|| gType
== sStylesTypeStrict
)
671 nType
= OOXMLStream::STYLES
;
672 aRelDefinition
.put(sContentType
, sStylesContentType
);
674 else if (gType
== sWebSettings
|| gType
== sWebSettingsStrict
)
676 nType
= OOXMLStream::WEBSETTINGS
;
677 aRelDefinition
.put(sContentType
, sWebsettingsContentType
);
679 else if (gType
== sFonttableType
|| gType
== sFonttableTypeStrict
)
681 nType
= OOXMLStream::FONTTABLE
;
682 aRelDefinition
.put(sContentType
, sFonttableContentType
);
684 else if (aRelDefinition
.getOrDefault(sTargetMode
, OUString
{}) != "External")
686 // Some internal relation, but we don't create a DOM for it here yet?
687 SAL_WARN("writerfilter.ooxml", "Unknown type of glossary internal relation: "
688 "Id=\"" + aRelDefinition
.getOrDefault
<OUString
>(sId
, {}) + "\" "
689 "Type=\"" + gType
+ "\" "
690 "Target=\"" + aRelDefinition
.getOrDefault
<OUString
>(sTarget
, {}) + "\"");
694 if (nType
!= OOXMLStream::UNKNOWN
)
698 auto gStream
= OOXMLDocumentFactory::createStream(pStream
, nType
);
699 uno::Reference xInputStream
= gStream
->getDocumentStream();
700 uno::Reference
xContext(pStream
->getContext());
701 uno::Reference
xDomBuilder(xml::dom::DocumentBuilder::create(xContext
));
702 uno::Reference xDom
= xDomBuilder
->parse(xInputStream
);
703 aRelDefinition
.put(sRelDom
, xDom
);
705 catch (uno::Exception
const&)
707 TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "importSubStream: exception while "
708 "parsing stream of Type" << nType
);
711 aGlossaryDomList
.push_back(aRelDefinition
.getNamedValues());
713 mxGlossaryDomList
= comphelper::containerToSequence(aGlossaryDomList
);
716 void OOXMLDocumentImpl::resolveEmbeddingsStream(const OOXMLStream::Pointer_t
& pStream
)
718 uno::Reference
<embed::XRelationshipAccess
> xRelationshipAccess
;
719 xRelationshipAccess
.set(dynamic_cast<OOXMLStreamImpl
&>(*pStream
).accessDocumentStream(), uno::UNO_QUERY
);
720 if (xRelationshipAccess
.is())
722 OUString
const sChartType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart");
723 OUString
const sChartTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/chart");
724 OUString
const sFootersType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
725 OUString
const sFootersTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/footer");
726 OUString
const sHeaderType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
727 OUString
const sHeaderTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/header");
730 bool bHeaderFooterFound
= false;
731 OOXMLStream::StreamType_t streamType
= OOXMLStream::UNKNOWN
;
732 const uno::Sequence
< uno::Sequence
< beans::StringPair
> >aSeqs
= xRelationshipAccess
->getAllRelationships();
733 for (const uno::Sequence
< beans::StringPair
>& aSeq
: aSeqs
)
735 for (const beans::StringPair
& aPair
: aSeq
)
737 if (aPair
.Second
== sChartType
||
738 aPair
.Second
== sChartTypeStrict
)
742 else if(aPair
.Second
== sFootersType
||
743 aPair
.Second
== sFootersTypeStrict
)
745 bHeaderFooterFound
= true;
746 streamType
= OOXMLStream::FOOTER
;
748 else if(aPair
.Second
== sHeaderType
||
749 aPair
.Second
== sHeaderTypeStrict
)
751 bHeaderFooterFound
= true;
752 streamType
= OOXMLStream::HEADER
;
754 else if(aPair
.First
== "Target" && ( bFound
|| bHeaderFooterFound
))
756 // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
757 // to ensure chart.xml target is visited in lcl_getTarget.
758 customTarget
= aPair
.Second
;
761 if( bFound
|| bHeaderFooterFound
)
765 importSubStreamRelations(pStream
, OOXMLStream::CHARTS
);
767 if(bHeaderFooterFound
)
771 OOXMLStream::Pointer_t Stream
= OOXMLDocumentFactory::createStream(pStream
, streamType
);
773 resolveEmbeddingsStream(Stream
);
775 catch (uno::Exception
const&)
777 TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "resolveEmbeddingsStream: can't find header/footer whilst "
778 "resolving stream " << streamType
);
783 beans::PropertyValue embeddingsTemp
;
784 // This will add all .xlsx and .bin to grabbag list.
785 if(bFound
&& mxEmbeddings
.is())
787 embeddingsTemp
.Name
= embeddingsTarget
;
788 embeddingsTemp
.Value
<<= mxEmbeddings
;
789 m_aEmbeddings
.push_back(embeddingsTemp
);
790 mxEmbeddings
.clear();
793 bHeaderFooterFound
= false;
797 if (!m_aEmbeddings
.empty())
798 mxEmbeddingsList
= comphelper::containerToSequence(m_aEmbeddings
);
801 uno::Reference
<xml::dom::XDocument
> OOXMLDocumentImpl::getGlossaryDocDom( )
803 return mxGlossaryDocDom
;
806 uno::Sequence
<uno::Sequence
< beans::NamedValue
> > OOXMLDocumentImpl::getGlossaryDomList()
808 return mxGlossaryDomList
;
811 uno::Reference
<io::XInputStream
> OOXMLDocumentImpl::getInputStreamForId(const OUString
& rId
)
813 OOXMLStream::Pointer_t
pStream(OOXMLDocumentFactory::createStream(mpStream
, rId
));
815 return pStream
->getDocumentStream();
818 void OOXMLDocumentImpl::setModel(uno::Reference
<frame::XModel
> xModel
)
823 uno::Reference
<frame::XModel
> OOXMLDocumentImpl::getModel()
828 void OOXMLDocumentImpl::setDrawPage(uno::Reference
<drawing::XDrawPage
> xDrawPage
)
830 mxDrawPage
.set(xDrawPage
);
833 uno::Reference
<drawing::XDrawPage
> OOXMLDocumentImpl::getDrawPage()
838 const uno::Sequence
<beans::PropertyValue
>& OOXMLDocumentImpl::getMediaDescriptor() const
840 return maMediaDescriptor
;
843 void OOXMLDocumentImpl::setShapeContext( rtl::Reference
<oox::shape::ShapeContextHandler
> xContext
)
845 if (!maShapeContexts
.empty())
846 maShapeContexts
.top() = xContext
;
849 rtl::Reference
<oox::shape::ShapeContextHandler
> OOXMLDocumentImpl::getShapeContext( )
851 if (!maShapeContexts
.empty())
852 return maShapeContexts
.top();
857 void OOXMLDocumentImpl::pushShapeContext()
859 maShapeContexts
.push({});
862 void OOXMLDocumentImpl::popShapeContext()
864 if (!maShapeContexts
.empty())
865 maShapeContexts
.pop();
868 uno::Reference
<xml::dom::XDocument
> OOXMLDocumentImpl::getThemeDom( )
873 uno::Sequence
<uno::Reference
<xml::dom::XDocument
> > OOXMLDocumentImpl::getCustomXmlDomList( )
875 return mxCustomXmlDomList
;
878 uno::Sequence
<uno::Reference
<xml::dom::XDocument
> > OOXMLDocumentImpl::getCustomXmlDomPropsList( )
880 return mxCustomXmlDomPropsList
;
883 uno::Sequence
<beans::PropertyValue
> OOXMLDocumentImpl::getEmbeddingsList( )
885 return mxEmbeddingsList
;
888 const rtl::Reference
<oox::shape::ShapeFilterBase
>& OOXMLDocumentImpl::getShapeFilterBase()
890 if (!mxShapeFilterBase
)
891 mxShapeFilterBase
= new oox::shape::ShapeFilterBase(mpStream
->getContext());
892 return mxShapeFilterBase
;
895 const rtl::Reference
<oox::drawingml::ThemeFilterBase
>& OOXMLDocumentImpl::getThemeFilterBase()
897 if (!mxThemeFilterBase
)
898 mxThemeFilterBase
= new oox::drawingml::ThemeFilterBase(mpStream
->getContext());
899 return mxThemeFilterBase
;
903 OOXMLDocumentFactory::createDocument
904 (const OOXMLStream::Pointer_t
& pStream
,
905 const uno::Reference
<task::XStatusIndicator
>& xStatusIndicator
,
906 bool mbSkipImages
, const uno::Sequence
<beans::PropertyValue
>& rDescriptor
)
908 return new OOXMLDocumentImpl(pStream
, xStatusIndicator
, mbSkipImages
, rDescriptor
);
913 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */