android: Update app-specific/MIME type icons
[LibreOffice.git] / writerfilter / source / ooxml / OOXMLDocumentImpl.cxx
blob3a7359df22e4112faa4d07f7fb74909fc65718e1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
45 #include <iostream>
46 #include <sfx2/objsh.hxx>
47 #include <utility>
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))
59 , mnXNoteId(0)
60 , mbIsSubstream(false)
61 , mbSkipImages(bSkipImages)
62 , mnPercentSize(0)
63 , mnProgressLastPos(0)
64 , mnProgressCurrentPos(0)
65 , mnProgressEndPos(0)
66 , m_rBaseURL(utl::MediaDescriptor(rDescriptor).getUnpackedValueOrDefault("DocumentBaseURL", OUString()))
67 , maMediaDescriptor(rDescriptor)
68 , mxGraphicMapper(graphic::GraphicMapper::create(mpStream->getContext()))
70 pushShapeContext();
73 OOXMLDocumentImpl::~OOXMLDocumentImpl()
77 void OOXMLDocumentImpl::resolveFastSubStream(Stream & rStreamHandler,
78 OOXMLStream::StreamType_t nType)
80 OOXMLStream::Pointer_t pStream;
81 try
83 pStream = OOXMLDocumentFactory::createStream(mpStream, nType);
85 catch (uno::Exception const&)
87 TOOLS_INFO_EXCEPTION("writerfilter.ooxml", "resolveFastSubStream: exception while "
88 "resolving stream " << nType);
89 return;
91 OOXMLStream::Pointer_t savedStream = mpStream;
92 mpStream = pStream;
94 uno::Reference<xml::sax::XFastParser> xParser(mpStream->getFastParser());
96 if (xParser.is())
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,
124 sal_uInt32 nId)
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);
142 return xRet;
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);
158 return xRet;
162 if (OOXMLStream::CUSTOMXML == nType)
164 importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS);
166 else if (OOXMLStream::CHARTS == nType)
168 importSubStreamRelations(pStream, OOXMLStream::EMBEDDINGS);
171 return xRet;
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);
187 return;
190 uno::Reference<io::XInputStream> xcpInputStream = cStream->getDocumentStream();
192 if (!xcpInputStream.is())
193 return;
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;
211 if(xRelation.is())
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)
230 mnXNoteId = nId;
233 sal_Int32 OOXMLDocumentImpl::getXNoteId() const
235 return mnXNoteId;
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;
255 return pRet;
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,
273 Id aType,
274 const sal_Int32 nNoteId)
276 if (!mpXFootnoteStream)
277 mpXFootnoteStream = getXNoteStream(OOXMLStream::FOOTNOTES, nNoteId);
279 Id nId;
280 switch (aType)
282 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator:
283 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator:
284 nId = aType;
285 break;
286 default:
287 nId = NS_ooxml::LN_footnote;
288 break;
291 resolveFastSubStreamWithId(rStream, mpXFootnoteStream, nId);
294 void OOXMLDocumentImpl::resolveEndnote(Stream & rStream,
295 Id aType,
296 const sal_Int32 nNoteId)
298 if (!mpXEndnoteStream)
299 mpXEndnoteStream = getXNoteStream(OOXMLStream::ENDNOTES, nNoteId);
301 Id nId;
302 switch (aType)
304 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator:
305 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator:
306 nId = aType;
307 break;
308 default:
309 nId = NS_ooxml::LN_endnote;
310 break;
313 resolveFastSubStreamWithId(rStream, mpXEndnoteStream, nId);
316 void OOXMLDocumentImpl::resolveCommentsExtendedStream(Stream& rStream)
318 resolveFastSubStream(rStream, OOXMLStream::COMMENTS_EXTENDED);
321 void OOXMLDocumentImpl::resolveComment(Stream & rStream,
322 const sal_Int32 nId)
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);
357 return pProps;
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 =
378 getSubStream(rId);
379 switch (type)
381 case NS_ooxml::LN_Value_ST_HdrFtr_even:
382 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerl);
383 break;
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);
386 break;
387 case NS_ooxml::LN_Value_ST_HdrFtr_first:
388 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerf);
389 break;
390 default:
391 break;
395 void OOXMLDocumentImpl::resolveFooter(Stream & rStream,
396 const sal_Int32 type,
397 const OUString & rId)
399 writerfilter::Reference<Stream>::Pointer_t pStream =
400 getSubStream(rId);
402 switch (type)
404 case NS_ooxml::LN_Value_ST_HdrFtr_even:
405 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerl);
406 break;
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);
409 break;
410 case NS_ooxml::LN_Value_ST_HdrFtr_first:
411 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerf);
412 break;
413 default:
414 break;
418 namespace {
419 // Ensures that the indicator is reset after exiting OOXMLDocumentImpl::resolve
420 class StatusIndicatorGuard{
421 public:
422 explicit StatusIndicatorGuard(css::uno::Reference<css::task::XStatusIndicator> xStatusIndicator)
423 :mxStatusIndicator(std::move(xStatusIndicator))
427 ~StatusIndicatorGuard()
429 if (mxStatusIndicator.is())
430 mxStatusIndicator->end();
433 private:
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);
445 return;
448 uno::Reference<xml::sax::XFastParser> xParser(mpStream->getFastParser());
450 if (mxModel.is())
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())
457 sal_Int32 nValue;
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;
473 if (!xParser.is())
474 return;
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();
491 if (pThemePtr)
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);
523 if (!rShell
524 || !rShell->IsContinueImportOnFilterExceptions(
525 Concat2View("SAXException: " + rErr.Message)))
526 throw;
528 catch (uno::RuntimeException const&)
530 throw;
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);
539 catch (...)
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())
566 return;
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";
570 bool bFound = false;
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)
582 bFound = true;
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;
591 if (bFound)
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
595 // grabbag list.
596 if (mxCustomXmlProsDom.is() && customXmlTemp.is())
598 aCustomXmlDomList.push_back(customXmlTemp);
599 aCustomXmlDomPropsList.push_back(mxCustomXmlProsDom);
600 resolveFastSubStream(rStream, OOXMLStream::CUSTOMXML);
603 bFound = false;
607 mxCustomXmlDomList = comphelper::containerToSequence(aCustomXmlDomList);
608 mxCustomXmlDomPropsList = comphelper::containerToSequence(aCustomXmlDomPropsList);
611 namespace
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);
646 return;
648 uno::Reference<embed::XRelationshipAccess> xRelationshipAccess;
649 xRelationshipAccess.set(dynamic_cast<OOXMLStreamImpl&>(*pStream).accessDocumentStream(), uno::UNO_QUERY);
650 if (!xRelationshipAccess.is())
651 return;
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, {}) + "\"");
691 continue;
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");
729 bool bFound = false;
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)
740 bFound = true;
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)
763 if(bFound)
765 importSubStreamRelations(pStream, OOXMLStream::CHARTS);
767 if(bHeaderFooterFound)
771 OOXMLStream::Pointer_t Stream = OOXMLDocumentFactory::createStream(pStream, streamType);
772 if (Stream)
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);
779 return;
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();
792 bFound = false;
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)
820 mxModel.set(xModel);
823 uno::Reference<frame::XModel> OOXMLDocumentImpl::getModel()
825 return mxModel;
828 void OOXMLDocumentImpl::setDrawPage(uno::Reference<drawing::XDrawPage> xDrawPage)
830 mxDrawPage.set(xDrawPage);
833 uno::Reference<drawing::XDrawPage> OOXMLDocumentImpl::getDrawPage()
835 return mxDrawPage;
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();
853 else
854 return {};
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( )
870 return mxThemeDom;
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;
902 OOXMLDocument *
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: */