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/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>
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
{
58 OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t
const & pStream
, const uno::Reference
<task::XStatusIndicator
>& xStatusIndicator
, bool bSkipImages
, const uno::Sequence
<beans::PropertyValue
>& rDescriptor
)
60 , mxStatusIndicator(xStatusIndicator
)
62 , mbIsSubstream(false)
63 , mbSkipImages(bSkipImages
)
65 , mnProgressLastPos(0)
66 , mnProgressCurrentPos(0)
68 , m_rBaseURL(utl::MediaDescriptor(rDescriptor
).getUnpackedValueOrDefault("DocumentBaseURL", OUString()))
69 , maMediaDescriptor(rDescriptor
)
74 OOXMLDocumentImpl::~OOXMLDocumentImpl()
78 void OOXMLDocumentImpl::resolveFastSubStream(Stream
& rStreamHandler
,
79 OOXMLStream::StreamType_t nType
)
81 OOXMLStream::Pointer_t pStream
;
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
);
92 OOXMLStream::Pointer_t savedStream
= mpStream
;
95 uno::Reference
<xml::sax::XFastParser
> xParser(mpStream
->getFastParser());
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
,
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
);
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
);
164 if (OOXMLStream::CUSTOMXML
== nType
)
166 importSubStreamRelations(pStream
, OOXMLStream::CUSTOMXMLPROPS
);
168 else if (OOXMLStream::CHARTS
== nType
)
170 importSubStreamRelations(pStream
, OOXMLStream::EMBEDDINGS
);
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
);
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
;
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
)
235 sal_Int32
OOXMLDocumentImpl::getXNoteId() const
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;
264 writerfilter::Reference
<Stream
>::Pointer_t
265 OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType
, Id aType
,
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
,
282 const sal_Int32 nNoteId
)
284 writerfilter::Reference
<Stream
>::Pointer_t pStream
=
285 getXNoteStream(OOXMLStream::FOOTNOTES
, aType
, nNoteId
);
290 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator
:
291 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator
:
295 nId
= NS_ooxml::LN_footnote
;
299 resolveFastSubStreamWithId(rStream
, pStream
, nId
);
302 void OOXMLDocumentImpl::resolveEndnote(Stream
& rStream
,
304 const sal_Int32 nNoteId
)
306 writerfilter::Reference
<Stream
>::Pointer_t pStream
=
307 getXNoteStream(OOXMLStream::ENDNOTES
, aType
, nNoteId
);
312 case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator
:
313 case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator
:
317 nId
= NS_ooxml::LN_endnote
;
321 resolveFastSubStreamWithId(rStream
, pStream
, nId
);
324 void OOXMLDocumentImpl::resolveComment(Stream
& rStream
,
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
);
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
=
378 case NS_ooxml::LN_Value_ST_HdrFtr_even
:
379 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_headerl
);
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
);
384 case NS_ooxml::LN_Value_ST_HdrFtr_first
:
385 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_headerf
);
392 void OOXMLDocumentImpl::resolveFooter(Stream
& rStream
,
393 const sal_Int32 type
,
394 const OUString
& rId
)
396 writerfilter::Reference
<Stream
>::Pointer_t pStream
=
401 case NS_ooxml::LN_Value_ST_HdrFtr_even
:
402 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_footerl
);
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
);
407 case NS_ooxml::LN_Value_ST_HdrFtr_first
:
408 resolveFastSubStreamWithId(rStream
, pStream
, NS_ooxml::LN_footerf
);
416 // Ensures that the indicator is reset after exiting OOXMLDocumentImpl::resolve
417 class StatusIndicatorGuard
{
419 explicit StatusIndicatorGuard(css::uno::Reference
<css::task::XStatusIndicator
> const & xStatusIndicator
)
420 :mxStatusIndicator(xStatusIndicator
)
424 ~StatusIndicatorGuard()
426 if (mxStatusIndicator
.is())
427 mxStatusIndicator
->end();
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
);
445 uno::Reference
<xml::sax::XFastParser
> xParser(mpStream
->getFastParser());
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())
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;
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
))
515 catch (uno::RuntimeException
const&)
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
);
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";
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
)
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
;
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
586 if (mxCustomXmlProsDom
.is() && customXmlTemp
.is())
588 aCustomXmlDomList
.push_back(customXmlTemp
);
589 aCustomXmlDomPropsList
.push_back(mxCustomXmlProsDom
);
591 resolveFastSubStream(rStream
, OOXMLStream::CUSTOMXML
);
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
);
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");
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
);
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";
678 //"Unhandled content-type while grab bagging Glossary Folder");
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
);
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
);
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");
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
)
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
)
767 importSubStreamRelations(pStream
, OOXMLStream::CHARTS
);
769 if(bHeaderFooterFound
)
773 OOXMLStream::Pointer_t Stream
= OOXMLDocumentFactory::createStream(pStream
, streamType
);
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
);
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();
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
)
825 uno::Reference
<frame::XModel
> OOXMLDocumentImpl::getModel()
830 void OOXMLDocumentImpl::setDrawPage(uno::Reference
<drawing::XDrawPage
> xDrawPage
)
832 mxDrawPage
.set(xDrawPage
);
835 uno::Reference
<drawing::XDrawPage
> OOXMLDocumentImpl::getDrawPage()
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();
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( )
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
;
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: */