lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / writerfilter / source / ooxml / OOXMLDocumentImpl.cxx
blob7b0148edc4c9c82c6b066619bbe9ad87774ec730
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/xml/sax/XParser.hpp>
24 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
25 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
26 #include <com/sun/star/xml/sax/SAXException.hpp>
27 #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
28 #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
29 #include <ooxml/resourceids.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 <tools/diagnose_ex.h>
38 #include <unotools/resmgr.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/settings.hxx>
41 #include <svx/dialmgr.hxx>
42 #include <svx/strings.hrc>
43 #include <comphelper/sequence.hxx>
44 #include <cppuhelper/exc_hlp.hxx>
45 #include <unotools/mediadescriptor.hxx>
47 #include <iostream>
48 #include <sfx2/objsh.hxx>
50 // this extern variable is declared in OOXMLStreamImpl.hxx
51 OUString customTarget;
52 OUString embeddingsTarget;
53 using namespace ::com::sun::star;
54 namespace writerfilter {
55 namespace ooxml
58 OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t const & pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator, bool bSkipImages, const uno::Sequence<beans::PropertyValue>& rDescriptor)
59 : mpStream(pStream)
60 , mxStatusIndicator(xStatusIndicator)
61 , mnXNoteId(0)
62 , mbIsSubstream(false)
63 , mbSkipImages(bSkipImages)
64 , mnPercentSize(0)
65 , mnProgressLastPos(0)
66 , mnProgressCurrentPos(0)
67 , mnProgressEndPos(0)
68 , m_rBaseURL(utl::MediaDescriptor(rDescriptor).getUnpackedValueOrDefault("DocumentBaseURL", OUString()))
69 , maMediaDescriptor(rDescriptor)
71 pushShapeContext();
74 OOXMLDocumentImpl::~OOXMLDocumentImpl()
78 void OOXMLDocumentImpl::resolveFastSubStream(Stream & rStreamHandler,
79 OOXMLStream::StreamType_t nType)
81 OOXMLStream::Pointer_t pStream;
82 try
84 pStream = OOXMLDocumentFactory::createStream(mpStream, nType);
86 catch (uno::Exception const& e)
88 SAL_INFO("writerfilter.ooxml", "resolveFastSubStream: exception while "
89 "resolving stream " << nType << " : " << e);
90 return;
92 OOXMLStream::Pointer_t savedStream = mpStream;
93 mpStream = pStream;
95 uno::Reference<xml::sax::XFastParser> xParser(mpStream->getFastParser());
97 if (xParser.is())
99 uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
100 OOXMLFastDocumentHandler * pDocHandler =
101 new OOXMLFastDocumentHandler(xContext, &rStreamHandler, this, mnXNoteId);
103 uno::Reference<xml::sax::XFastDocumentHandler> xDocumentHandler(pDocHandler);
104 uno::Reference<xml::sax::XFastTokenHandler> xTokenHandler(mpStream->getFastTokenHandler());
106 xParser->setFastDocumentHandler(xDocumentHandler);
107 xParser->setTokenHandler(xTokenHandler);
109 uno::Reference<io::XInputStream> xInputStream = pStream->getDocumentStream();
111 if (xInputStream.is())
113 struct xml::sax::InputSource oInputSource;
114 oInputSource.aInputStream = xInputStream;
115 xParser->parseStream(oInputSource);
117 xInputStream->closeInput();
121 mpStream = savedStream;
124 void OOXMLDocumentImpl::resolveFastSubStreamWithId(Stream & rStream,
125 const writerfilter::Reference<Stream>::Pointer_t& pStream,
126 sal_uInt32 nId)
128 rStream.substream(nId, pStream);
131 uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStream::StreamType_t nType)
133 uno::Reference<xml::dom::XDocument> xRet;
135 OOXMLStream::Pointer_t pStream;
138 pStream = OOXMLDocumentFactory::createStream(mpStream, nType);
140 catch (uno::Exception const& e)
142 SAL_INFO("writerfilter.ooxml", "importSubStream: exception while "
143 "importing stream " << nType << " : " << e);
144 return xRet;
147 uno::Reference<io::XInputStream> xInputStream = pStream->getDocumentStream();
148 if (xInputStream.is())
152 uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
153 uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xContext));
154 xRet = xDomBuilder->parse(xInputStream);
156 catch (uno::Exception const& e)
158 SAL_INFO("writerfilter.ooxml", "importSubStream: exception while "
159 "parsing stream " << nType << " : " << e);
160 return xRet;
164 if (OOXMLStream::CUSTOMXML == nType)
166 importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS);
168 else if (OOXMLStream::CHARTS == nType)
170 importSubStreamRelations(pStream, OOXMLStream::EMBEDDINGS);
173 return xRet;
177 void OOXMLDocumentImpl::importSubStreamRelations(const OOXMLStream::Pointer_t& pStream, OOXMLStream::StreamType_t nType)
179 uno::Reference<xml::dom::XDocument> xRelation;
180 OOXMLStream::Pointer_t cStream;
183 cStream = OOXMLDocumentFactory::createStream(pStream, nType);
185 catch (uno::Exception const& e)
187 SAL_WARN("writerfilter.ooxml", "importSubStreamRelations: exception while "
188 "importing stream " << nType << " : " << e);
189 return;
192 uno::Reference<io::XInputStream> xcpInputStream = cStream->getDocumentStream();
194 if (xcpInputStream.is())
196 // importing itemprops files for item.xml from customXml.
197 if (OOXMLStream::CUSTOMXMLPROPS == nType)
201 uno::Reference<uno::XComponentContext> xcpContext(pStream->getContext());
202 uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext));
203 xRelation = xDomBuilder->parse(xcpInputStream);
205 catch (uno::Exception const& e)
207 SAL_WARN("writerfilter.ooxml", "importSubStream: exception while "
208 "parsing stream " << nType << " : " << e);
209 mxCustomXmlProsDom = xRelation;
212 if(xRelation.is())
214 mxCustomXmlProsDom = xRelation;
217 else if(OOXMLStream::EMBEDDINGS == nType)
219 mxEmbeddings = xcpInputStream;
221 else if(OOXMLStream::CHARTS == nType)
223 importSubStreamRelations(cStream, OOXMLStream::EMBEDDINGS);
230 void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId)
232 mnXNoteId = nId;
235 sal_Int32 OOXMLDocumentImpl::getXNoteId() const
237 return mnXNoteId;
240 void OOXMLDocumentImpl::setXNoteType(Id /*nId*/)
244 const OUString & OOXMLDocumentImpl::getTarget() const
246 return mpStream->getTarget();
249 writerfilter::Reference<Stream>::Pointer_t
250 OOXMLDocumentImpl::getSubStream(const OUString & rId)
252 OOXMLStream::Pointer_t pStream
253 (OOXMLDocumentFactory::createStream(mpStream, rId));
255 OOXMLDocumentImpl * pTemp;
256 // Do not pass status indicator to sub-streams: they are typically marginal in size, so we just track the main document for now.
257 writerfilter::Reference<Stream>::Pointer_t pRet( pTemp = new OOXMLDocumentImpl(pStream, uno::Reference<task::XStatusIndicator>(), mbSkipImages, maMediaDescriptor));
258 pTemp->setModel(mxModel);
259 pTemp->setDrawPage(mxDrawPage);
260 pTemp->mbIsSubstream = true;
261 return pRet;
264 writerfilter::Reference<Stream>::Pointer_t
265 OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType, Id aType,
266 const sal_Int32 nId)
268 OOXMLStream::Pointer_t pStream =
269 OOXMLDocumentFactory::createStream(mpStream, nType);
270 // See above, no status indicator for the note stream, either.
271 OOXMLDocumentImpl * pDocument = new OOXMLDocumentImpl(pStream, uno::Reference<task::XStatusIndicator>(), mbSkipImages, maMediaDescriptor);
272 pDocument->setXNoteId(nId);
273 pDocument->setXNoteType(aType);
274 pDocument->setModel(getModel());
275 pDocument->setDrawPage(getDrawPage());
277 return writerfilter::Reference<Stream>::Pointer_t(pDocument);
280 void OOXMLDocumentImpl::resolveFootnote(Stream & rStream,
281 Id aType,
282 const sal_Int32 nNoteId)
284 writerfilter::Reference<Stream>::Pointer_t pStream =
285 getXNoteStream(OOXMLStream::FOOTNOTES, aType, nNoteId);
287 Id nId;
288 switch (aType)
290 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator:
291 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator:
292 nId = aType;
293 break;
294 default:
295 nId = NS_ooxml::LN_footnote;
296 break;
299 resolveFastSubStreamWithId(rStream, pStream, nId);
302 void OOXMLDocumentImpl::resolveEndnote(Stream & rStream,
303 Id aType,
304 const sal_Int32 nNoteId)
306 writerfilter::Reference<Stream>::Pointer_t pStream =
307 getXNoteStream(OOXMLStream::ENDNOTES, aType, nNoteId);
309 Id nId;
310 switch (aType)
312 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator:
313 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator:
314 nId = aType;
315 break;
316 default:
317 nId = NS_ooxml::LN_endnote;
318 break;
321 resolveFastSubStreamWithId(rStream, pStream, nId);
324 void OOXMLDocumentImpl::resolveComment(Stream & rStream,
325 const sal_Int32 nId)
327 writerfilter::Reference<Stream>::Pointer_t pStream =
328 getXNoteStream(OOXMLStream::COMMENTS, 0, nId);
330 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_annotation);
333 OOXMLPropertySet * OOXMLDocumentImpl::getPicturePropSet
334 (const OUString & rId)
336 OOXMLStream::Pointer_t pStream
337 (OOXMLDocumentFactory::createStream(mpStream, rId));
339 writerfilter::Reference<BinaryObj>::Pointer_t pPicture
340 (new OOXMLBinaryObjectReference(pStream));
342 OOXMLValue::Pointer_t pPayloadValue(new OOXMLBinaryValue(pPicture));
344 OOXMLPropertySet::Pointer_t pBlipSet(new OOXMLPropertySet);
346 pBlipSet->add(NS_ooxml::LN_payload, pPayloadValue, OOXMLProperty::ATTRIBUTE);
348 OOXMLValue::Pointer_t pBlipValue(new OOXMLPropertySetValue(pBlipSet));
350 OOXMLPropertySet * pProps = new OOXMLPropertySet;
352 pProps->add(NS_ooxml::LN_blip, pBlipValue, OOXMLProperty::ATTRIBUTE);
354 return pProps;
357 void OOXMLDocumentImpl::resolvePicture(Stream & rStream,
358 const OUString & rId)
360 OOXMLPropertySet::Pointer_t pProps(getPicturePropSet(rId));
362 rStream.props(pProps.get());
365 OUString OOXMLDocumentImpl::getTargetForId(const OUString & rId)
367 return mpStream->getTargetForId(rId);
370 void OOXMLDocumentImpl::resolveHeader(Stream & rStream,
371 const sal_Int32 type,
372 const OUString & rId)
374 writerfilter::Reference<Stream>::Pointer_t pStream =
375 getSubStream(rId);
376 switch (type)
378 case NS_ooxml::LN_Value_ST_HdrFtr_even:
379 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerl);
380 break;
381 case NS_ooxml::LN_Value_ST_HdrFtr_default: // here we assume that default is right, but not necessarily true :-(
382 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerr);
383 break;
384 case NS_ooxml::LN_Value_ST_HdrFtr_first:
385 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerf);
386 break;
387 default:
388 break;
392 void OOXMLDocumentImpl::resolveFooter(Stream & rStream,
393 const sal_Int32 type,
394 const OUString & rId)
396 writerfilter::Reference<Stream>::Pointer_t pStream =
397 getSubStream(rId);
399 switch (type)
401 case NS_ooxml::LN_Value_ST_HdrFtr_even:
402 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerl);
403 break;
404 case NS_ooxml::LN_Value_ST_HdrFtr_default: // here we assume that default is right, but not necessarily true :-(
405 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerr);
406 break;
407 case NS_ooxml::LN_Value_ST_HdrFtr_first:
408 resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerf);
409 break;
410 default:
411 break;
415 namespace {
416 // Ensures that the indicator is reset after exiting OOXMLDocumentImpl::resolve
417 class StatusIndicatorGuard{
418 public:
419 explicit StatusIndicatorGuard(css::uno::Reference<css::task::XStatusIndicator> const & xStatusIndicator)
420 :mxStatusIndicator(xStatusIndicator)
424 ~StatusIndicatorGuard()
426 if (mxStatusIndicator.is())
427 mxStatusIndicator->end();
430 private:
431 css::uno::Reference<css::task::XStatusIndicator> mxStatusIndicator;
435 void OOXMLDocumentImpl::resolve(Stream & rStream)
437 StatusIndicatorGuard aStatusIndicatorGuard(mxStatusIndicator);
439 if (utl::MediaDescriptor(maMediaDescriptor).getUnpackedValueOrDefault("ReadGlossaries", false))
441 resolveFastSubStream(rStream, OOXMLStream::GLOSSARY);
442 return;
445 uno::Reference<xml::sax::XFastParser> xParser(mpStream->getFastParser());
447 if (mxModel.is())
449 uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxModel, uno::UNO_QUERY);
450 uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
451 comphelper::SequenceAsHashMap aMap(xDocumentProperties->getDocumentStatistics());
452 if (aMap.find("ParagraphCount") != aMap.end())
454 sal_Int32 nValue;
455 if (aMap["ParagraphCount"] >>= nValue)
457 if (mxStatusIndicator.is())
459 // We want to care about the progress if we know the estimated paragraph count and we have given a status indicator as well.
460 // Set the end position only here, so later it's enough to check if that is non-zero in incrementProgress().
461 mnProgressEndPos = nValue;
462 OUString aDocLoad(SvxResId(RID_SVXSTR_DOC_LOAD));
463 mxStatusIndicator->start(aDocLoad, mnProgressEndPos);
464 mnPercentSize = mnProgressEndPos / 100;
470 if (xParser.is())
472 uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
474 OOXMLFastDocumentHandler * pDocHandler =
475 new OOXMLFastDocumentHandler(xContext, &rStream, this, mnXNoteId);
476 pDocHandler->setIsSubstream( mbIsSubstream );
477 uno::Reference < xml::sax::XFastDocumentHandler > xDocumentHandler(pDocHandler);
478 uno::Reference < xml::sax::XFastTokenHandler > xTokenHandler(mpStream->getFastTokenHandler());
480 resolveFastSubStream(rStream, OOXMLStream::SETTINGS);
481 mxThemeDom = importSubStream(OOXMLStream::THEME);
482 resolveFastSubStream(rStream, OOXMLStream::THEME);
483 mxGlossaryDocDom = importSubStream(OOXMLStream::GLOSSARY);
484 if (mxGlossaryDocDom.is())
485 resolveGlossaryStream(rStream);
487 resolveEmbeddingsStream(mpStream);
489 // Custom xml's are handled as part of grab bag.
490 resolveCustomXmlStream(rStream);
492 resolveFastSubStream(rStream, OOXMLStream::FONTTABLE);
493 resolveFastSubStream(rStream, OOXMLStream::STYLES);
494 resolveFastSubStream(rStream, OOXMLStream::NUMBERING);
496 xParser->setFastDocumentHandler( xDocumentHandler );
497 xParser->setTokenHandler( xTokenHandler );
499 xml::sax::InputSource aParserInput;
500 aParserInput.sSystemId = mpStream->getTarget();
501 aParserInput.aInputStream = mpStream->getDocumentStream();
504 xParser->parseStream(aParserInput);
506 catch (xml::sax::SAXException const& rErr)
508 // don't silently swallow these - handlers may not have been executed,
509 // and the domain mapper is likely in an inconsistent state
510 // In case user chooses to try to continue loading, don't ask again for this file
511 SfxObjectShell* rShell = SfxObjectShell::GetShellFromComponent(mxModel);
512 if (!rShell || !rShell->IsContinueImportOnFilterExceptions("SAXException: " + rErr.Message))
513 throw;
515 catch (uno::RuntimeException const&)
517 throw;
519 // note: cannot throw anything other than SAXException out of here?
520 catch (uno::Exception const&)
522 css::uno::Any anyEx = cppu::getCaughtException();
523 SAL_WARN("writerfilter.ooxml", "OOXMLDocumentImpl::resolve(): " << exceptionToString(anyEx));
524 throw lang::WrappedTargetRuntimeException("", nullptr, anyEx);
526 catch (...)
528 SAL_WARN("writerfilter.ooxml",
529 "OOXMLDocumentImpl::resolve(): non-UNO exception");
534 void OOXMLDocumentImpl::incrementProgress()
536 mnProgressCurrentPos++;
537 // 1) If we know the end
538 // 2) We progressed enough that updating makes sense
539 // 3) We did not reach the end yet (possible in case the doc stat is misleading)
540 if (mnProgressEndPos && mnProgressCurrentPos > (mnProgressLastPos + mnPercentSize) && mnProgressLastPos < mnProgressEndPos)
542 mnProgressLastPos = mnProgressCurrentPos;
543 if (mxStatusIndicator.is())
544 mxStatusIndicator->setValue(mnProgressLastPos);
548 void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream)
550 // Resolving all item[n].xml files from CustomXml folder.
551 uno::Reference<embed::XRelationshipAccess> xRelationshipAccess;
552 xRelationshipAccess.set(dynamic_cast<OOXMLStreamImpl&>(*mpStream.get()).accessDocumentStream(), uno::UNO_QUERY);
553 if (xRelationshipAccess.is())
555 static const char sCustomType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
556 static const char sCustomTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/customXml";
557 bool bFound = false;
558 sal_Int32 counter = 0;
559 uno::Sequence<uno::Sequence< beans::StringPair>> aSeqs = xRelationshipAccess->getAllRelationships();
560 std::vector<uno::Reference<xml::dom::XDocument>> aCustomXmlDomList;
561 std::vector<uno::Reference<xml::dom::XDocument>> aCustomXmlDomPropsList;
562 for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
564 const uno::Sequence<beans::StringPair>& aSeq = aSeqs[j];
565 for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
567 const beans::StringPair& aPair = aSeq[i];
568 // Need to resolve only customxml files from document relationships.
569 // Skipping other files.
570 if (aPair.Second == sCustomType ||
571 aPair.Second == sCustomTypeStrict)
572 bFound = true;
573 else if (aPair.First == "Target" && bFound)
575 // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
576 // to ensure customxml target is visited in lcl_getTarget.
577 customTarget = aPair.Second;
581 if (bFound)
583 uno::Reference<xml::dom::XDocument> customXmlTemp = importSubStream(OOXMLStream::CUSTOMXML);
584 // This will add all item[n].xml with its relationship file i.e itemprops.xml to
585 // grabbag list.
586 if (mxCustomXmlProsDom.is() && customXmlTemp.is())
588 aCustomXmlDomList.push_back(customXmlTemp);
589 aCustomXmlDomPropsList.push_back(mxCustomXmlProsDom);
590 counter++;
591 resolveFastSubStream(rStream, OOXMLStream::CUSTOMXML);
594 bFound = false;
598 mxCustomXmlDomList = comphelper::containerToSequence(aCustomXmlDomList);
599 mxCustomXmlDomPropsList = comphelper::containerToSequence(aCustomXmlDomPropsList);
603 void OOXMLDocumentImpl::resolveGlossaryStream(Stream & /*rStream*/)
605 static const char sSettingsType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings";
606 static const char sStylesType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
607 static const char sFonttableType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable";
608 static const char sWebSettings[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings";
609 static const char sSettingsTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/settings";
610 static const char sStylesTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/styles";
611 static const char sFonttableTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/fontTable";
612 static const char sWebSettingsStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/webSettings";
614 OOXMLStream::Pointer_t pStream;
617 pStream = OOXMLDocumentFactory::createStream(mpStream, OOXMLStream::GLOSSARY);
619 catch (uno::Exception const& e)
621 SAL_INFO("writerfilter.ooxml", "resolveGlossaryStream: exception while "
622 "createStream for glossary" << OOXMLStream::GLOSSARY << " : " << e);
623 return;
625 uno::Reference<embed::XRelationshipAccess> xRelationshipAccess;
626 xRelationshipAccess.set(dynamic_cast<OOXMLStreamImpl&>(*pStream.get()).accessDocumentStream(), uno::UNO_QUERY);
627 if (xRelationshipAccess.is())
630 uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = xRelationshipAccess->getAllRelationships();
631 std::vector< uno::Sequence<uno::Any> > aGlossaryDomList;
632 sal_Int32 counter = 0;
633 for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
635 OOXMLStream::Pointer_t gStream;
636 uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
637 //Follows following aSeq[0] is Id, aSeq[1] is Type, aSeq[2] is Target
638 if (aSeq.getLength() < 3)
640 SAL_WARN("writerfilter.ooxml", "too short sequence");
641 continue;
644 OUString gId(aSeq[0].Second);
645 OUString gType(aSeq[1].Second);
646 OUString gTarget(aSeq[2].Second);
647 OUString contentType;
649 OOXMLStream::StreamType_t nType(OOXMLStream::UNKNOWN);
650 bool bFound = true;
651 if(gType == sSettingsType ||
652 gType == sSettingsTypeStrict)
654 nType = OOXMLStream::SETTINGS;
655 contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml";
657 else if(gType == sStylesType ||
658 gType == sStylesTypeStrict)
660 nType = OOXMLStream::STYLES;
661 contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
663 else if(gType == sWebSettings ||
664 gType == sWebSettingsStrict)
666 nType = OOXMLStream::WEBSETTINGS;
667 contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml";
669 else if(gType == sFonttableType ||
670 gType == sFonttableTypeStrict)
672 nType = OOXMLStream::FONTTABLE;
673 contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml";
675 else
677 bFound = false;
678 //"Unhandled content-type while grab bagging Glossary Folder");
681 if (bFound)
683 uno::Reference<xml::dom::XDocument> xDom;
686 gStream = OOXMLDocumentFactory::createStream(pStream, nType);
687 uno::Reference<io::XInputStream> xInputStream = gStream->getDocumentStream();
688 uno::Reference<uno::XComponentContext> xContext(pStream->getContext());
689 uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xContext));
690 xDom = xDomBuilder->parse(xInputStream);
692 catch (uno::Exception const& e)
694 SAL_INFO("writerfilter.ooxml", "importSubStream: exception while "
695 "parsing stream of Type" << nType << " : " << e);
696 return;
699 if (xDom.is())
701 uno::Sequence< uno::Any > glossaryTuple (5);
702 glossaryTuple[0] <<= xDom;
703 glossaryTuple[1] <<= gId;
704 glossaryTuple[2] <<= gType;
705 glossaryTuple[3] <<= gTarget;
706 glossaryTuple[4] <<= contentType;
707 aGlossaryDomList.push_back(glossaryTuple);
708 counter++;
712 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.get()).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 uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = xRelationshipAccess->getAllRelationships();
733 for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
735 uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
736 for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
738 beans::StringPair aPair = aSeq[i];
739 if (aPair.Second == sChartType ||
740 aPair.Second == sChartTypeStrict)
742 bFound = true;
744 else if(aPair.Second == sFootersType ||
745 aPair.Second == sFootersTypeStrict)
747 bHeaderFooterFound = true;
748 streamType = OOXMLStream::FOOTER;
750 else if(aPair.Second == sHeaderType ||
751 aPair.Second == sHeaderTypeStrict)
753 bHeaderFooterFound = true;
754 streamType = OOXMLStream::HEADER;
756 else if(aPair.First == "Target" && ( bFound || bHeaderFooterFound ))
758 // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
759 // to ensure chart.xml target is visited in lcl_getTarget.
760 customTarget = aPair.Second;
763 if( bFound || bHeaderFooterFound)
765 if(bFound)
767 importSubStreamRelations(pStream, OOXMLStream::CHARTS);
769 if(bHeaderFooterFound)
773 OOXMLStream::Pointer_t Stream = OOXMLDocumentFactory::createStream(pStream, streamType);
774 if (Stream)
775 resolveEmbeddingsStream(Stream);
777 catch (uno::Exception const& e)
779 SAL_INFO("writerfilter.ooxml", "resolveEmbeddingsStream: can't find header/footer whilst "
780 "resolving stream " << streamType << " : " << e);
781 return;
785 beans::PropertyValue embeddingsTemp;
786 // This will add all .xlsx and .bin to grabbag list.
787 if(bFound && mxEmbeddings.is())
789 embeddingsTemp.Name = embeddingsTarget;
790 embeddingsTemp.Value <<= mxEmbeddings;
791 aEmbeddings.push_back(embeddingsTemp);
792 mxEmbeddings.clear();
794 bFound = false;
795 bHeaderFooterFound = false;
799 if (!aEmbeddings.empty())
800 mxEmbeddingsList = comphelper::containerToSequence(aEmbeddings);
803 uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::getGlossaryDocDom( )
805 return mxGlossaryDocDom;
808 uno::Sequence<uno::Sequence< uno::Any> > OOXMLDocumentImpl::getGlossaryDomList()
810 return mxGlossaryDomList;
813 uno::Reference<io::XInputStream> OOXMLDocumentImpl::getInputStreamForId(const OUString & rId)
815 OOXMLStream::Pointer_t pStream(OOXMLDocumentFactory::createStream(mpStream, rId));
817 return pStream->getDocumentStream();
820 void OOXMLDocumentImpl::setModel(uno::Reference<frame::XModel> xModel)
822 mxModel.set(xModel);
825 uno::Reference<frame::XModel> OOXMLDocumentImpl::getModel()
827 return mxModel;
830 void OOXMLDocumentImpl::setDrawPage(uno::Reference<drawing::XDrawPage> xDrawPage)
832 mxDrawPage.set(xDrawPage);
835 uno::Reference<drawing::XDrawPage> OOXMLDocumentImpl::getDrawPage()
837 return mxDrawPage;
840 const uno::Sequence<beans::PropertyValue>& OOXMLDocumentImpl::getMediaDescriptor()
842 return maMediaDescriptor;
845 void OOXMLDocumentImpl::setShapeContext( uno::Reference<xml::sax::XFastShapeContextHandler> xContext )
847 if (!maShapeContexts.empty())
848 maShapeContexts.top() = xContext;
851 uno::Reference<xml::sax::XFastShapeContextHandler> OOXMLDocumentImpl::getShapeContext( )
853 if (!maShapeContexts.empty())
854 return maShapeContexts.top();
855 else
856 return uno::Reference<xml::sax::XFastShapeContextHandler>();
859 void OOXMLDocumentImpl::pushShapeContext()
861 maShapeContexts.push(uno::Reference<xml::sax::XFastShapeContextHandler>());
864 void OOXMLDocumentImpl::popShapeContext()
866 if (!maShapeContexts.empty())
867 maShapeContexts.pop();
870 uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::getThemeDom( )
872 return mxThemeDom;
875 uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getCustomXmlDomList( )
877 return mxCustomXmlDomList;
880 uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getCustomXmlDomPropsList( )
882 return mxCustomXmlDomPropsList;
885 uno::Sequence<beans::PropertyValue > OOXMLDocumentImpl::getEmbeddingsList( )
887 return mxEmbeddingsList;
890 OOXMLDocument *
891 OOXMLDocumentFactory::createDocument
892 (const OOXMLStream::Pointer_t& pStream,
893 const uno::Reference<task::XStatusIndicator>& xStatusIndicator,
894 bool mbSkipImages, const uno::Sequence<beans::PropertyValue>& rDescriptor)
896 return new OOXMLDocumentImpl(pStream, xStatusIndicator, mbSkipImages, rDescriptor);
901 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */