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 <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
21 #include <com/sun/star/xml/sax/FastShapeContextHandler.hpp>
22 #include <com/sun/star/xml/sax/SAXException.hpp>
23 #include <ooxml/resourceids.hxx>
24 #include <oox/token/namespaces.hxx>
25 #include <sal/log.hxx>
26 #include <comphelper/embeddedobjectcontainer.hxx>
27 #include <cppuhelper/exc_hlp.hxx>
28 #include <tools/globname.hxx>
29 #include <comphelper/classids.hxx>
30 #include <sfx2/sfxbasemodel.hxx>
31 #include "OOXMLFastContextHandler.hxx"
32 #include "OOXMLFactory.hxx"
33 #include "Handler.hxx"
35 static const sal_Unicode uCR
= 0xd;
36 static const sal_Unicode uFtnEdnSep
= 0x3;
37 static const sal_Unicode uTab
= 0x9;
38 static const sal_Unicode uPgNum
= 0x0;
39 static const sal_Unicode uNoBreakHyphen
= 0x2011;
40 static const sal_Unicode uSoftHyphen
= 0xAD;
42 static const sal_uInt8 cFtnEdnCont
= 0x4;
43 static const sal_uInt8 cFieldLock
= 0x8;
45 namespace writerfilter
{
48 using namespace ::com::sun::star
;
50 using namespace ::std
;
53 class OOXMLFastContextHandler
56 OOXMLFastContextHandler::OOXMLFastContextHandler
57 (uno::Reference
< uno::XComponentContext
> const & context
)
61 mnToken(oox::XML_TOKEN_COUNT
),
66 m_bDiscardChildren(false),
69 if (mpParserState
.get() == nullptr)
70 mpParserState
= new OOXMLParserState();
72 mpParserState
->incContextCount();
75 OOXMLFastContextHandler::OOXMLFastContextHandler(OOXMLFastContextHandler
* pContext
)
76 : cppu::WeakImplHelper
<xml::sax::XFastContextHandler
>(),
80 mnToken(oox::XML_TOKEN_COUNT
),
81 mpStream(pContext
->mpStream
),
82 mpParserState(pContext
->mpParserState
),
83 mnTableDepth(pContext
->mnTableDepth
),
84 inPositionV(pContext
->inPositionV
),
85 m_xContext(pContext
->m_xContext
),
86 m_bDiscardChildren(pContext
->m_bDiscardChildren
),
87 m_bTookChoice(pContext
->m_bTookChoice
)
89 if (mpParserState
.get() == nullptr)
90 mpParserState
= new OOXMLParserState();
92 mpParserState
->incContextCount();
95 OOXMLFastContextHandler::~OOXMLFastContextHandler()
99 bool OOXMLFastContextHandler::prepareMceContext(Token_t nElement
, const uno::Reference
<xml::sax::XFastAttributeList
>& rAttribs
)
101 switch (oox::getBaseToken(nElement
))
103 case XML_AlternateContent
:
105 SavedAlternateState aState
;
106 aState
.m_bDiscardChildren
= m_bDiscardChildren
;
107 m_bDiscardChildren
= false;
108 aState
.m_bTookChoice
= m_bTookChoice
;
109 m_bTookChoice
= false;
110 mpParserState
->getSavedAlternateStates().push_back(aState
);
115 OUString aRequires
= rAttribs
->getOptionalValue(XML_Requires
);
116 static const char* aFeatures
[] = {
120 for (const char *p
: aFeatures
)
122 if (aRequires
.equalsAscii(p
))
124 m_bTookChoice
= true;
132 // If Choice is already taken, then let's ignore the Fallback.
133 return m_bTookChoice
;
136 SAL_WARN("writerfilter", "OOXMLFastContextHandler::prepareMceContext: unhandled element:" << oox::getBaseToken(nElement
));
142 // xml::sax::XFastContextHandler:
143 void SAL_CALL
OOXMLFastContextHandler::startFastElement
145 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
147 // Set xml:space value early, to allow child contexts use it when dealing with strings.
148 if (Attribs
&& Attribs
->hasAttribute(oox::NMSP_xml
| oox::XML_space
))
150 mbPreserveSpace
= Attribs
->getValue(oox::NMSP_xml
| oox::XML_space
) == "preserve";
151 mbPreserveSpaceSet
= true;
154 if (oox::getNamespace(Element
) == NMSP_mce
)
155 m_bDiscardChildren
= prepareMceContext(Element
, Attribs
);
157 else if (!m_bDiscardChildren
)
160 lcl_startFastElement(Element
, Attribs
);
164 void SAL_CALL
OOXMLFastContextHandler::startUnknownElement
165 (const OUString
& /*Namespace*/, const OUString
& /*Name*/,
166 const uno::Reference
< xml::sax::XFastAttributeList
> & /*Attribs*/)
170 void SAL_CALL
OOXMLFastContextHandler::endFastElement(Token_t Element
)
172 if (Element
== (NMSP_mce
| XML_Choice
) || Element
== (NMSP_mce
| XML_Fallback
))
173 m_bDiscardChildren
= false;
174 else if (Element
== (NMSP_mce
| XML_AlternateContent
))
176 SavedAlternateState
aState(mpParserState
->getSavedAlternateStates().back());
177 mpParserState
->getSavedAlternateStates().pop_back();
178 m_bDiscardChildren
= aState
.m_bDiscardChildren
;
179 m_bTookChoice
= aState
.m_bTookChoice
;
181 else if (!m_bDiscardChildren
)
182 lcl_endFastElement(Element
);
185 void OOXMLFastContextHandler::lcl_startFastElement
187 const uno::Reference
< xml::sax::XFastAttributeList
> & /*Attribs*/)
189 OOXMLFactory::startAction(this);
190 if( Element
== (NMSP_dmlWordDr
|XML_positionV
) )
192 else if( Element
== (NMSP_dmlWordDr
|XML_positionH
) )
197 void OOXMLFastContextHandler::lcl_endFastElement
198 (Token_t
/*Element*/)
200 OOXMLFactory::endAction(this);
203 void SAL_CALL
OOXMLFastContextHandler::endUnknownElement
204 (const OUString
& , const OUString
& )
208 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
209 OOXMLFastContextHandler::createFastChildContext
211 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
213 uno::Reference
< xml::sax::XFastContextHandler
> xResult
;
214 if (oox::getNamespace(Element
) != NMSP_mce
&& !m_bDiscardChildren
)
215 xResult
.set(lcl_createFastChildContext(Element
, Attribs
));
216 else if (oox::getNamespace(Element
) == NMSP_mce
)
222 uno::Reference
< xml::sax::XFastContextHandler
>
223 OOXMLFastContextHandler::lcl_createFastChildContext
225 const uno::Reference
< xml::sax::XFastAttributeList
> & /*Attribs*/)
227 return OOXMLFactory::createFastChildContext(this, Element
);
230 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
231 OOXMLFastContextHandler::createUnknownChildContext
234 const uno::Reference
< xml::sax::XFastAttributeList
> & /*Attribs*/)
236 return uno::Reference
< xml::sax::XFastContextHandler
>
237 (new OOXMLFastContextHandler(*const_cast<const OOXMLFastContextHandler
*>(this)));
240 void SAL_CALL
OOXMLFastContextHandler::characters
241 (const OUString
& aChars
)
243 lcl_characters(aChars
);
246 void OOXMLFastContextHandler::lcl_characters
247 (const OUString
& rString
)
249 if (!m_bDiscardChildren
)
250 OOXMLFactory::characters(this, rString
);
253 void OOXMLFastContextHandler::setStream(Stream
* pStream
)
258 OOXMLValue::Pointer_t
OOXMLFastContextHandler::getValue() const
260 return OOXMLValue::Pointer_t();
263 void OOXMLFastContextHandler::attributes
264 (const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
266 OOXMLFactory::attributes(this, Attribs
);
269 void OOXMLFastContextHandler::startAction()
271 OOXMLFactory::startAction(this);
274 void OOXMLFastContextHandler::endAction()
276 OOXMLFactory::endAction(this);
279 void OOXMLFastContextHandler::setId(Id rId
)
284 Id
OOXMLFastContextHandler::getId() const
289 void OOXMLFastContextHandler::setDefine(Id nDefine
)
295 void OOXMLFastContextHandler::setToken(Token_t nToken
)
300 Token_t
OOXMLFastContextHandler::getToken() const
305 void OOXMLFastContextHandler::sendTableDepth() const
307 if (mnTableDepth
> 0)
309 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
311 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(mnTableDepth
);
312 pProps
->add(NS_ooxml::LN_tblDepth
, pVal
, OOXMLProperty::SPRM
);
315 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(1);
316 pProps
->add(NS_ooxml::LN_inTbl
, pVal
, OOXMLProperty::SPRM
);
319 mpStream
->props(pProps
.get());
323 void OOXMLFastContextHandler::setHandle()
325 mpParserState
->setHandle();
326 mpStream
->info(mpParserState
->getHandle());
329 void OOXMLFastContextHandler::startCharacterGroup()
331 if (isForwardEvents())
333 if (mpParserState
->isInCharacterGroup())
336 if (! mpParserState
->isInParagraphGroup())
337 startParagraphGroup();
339 if (! mpParserState
->isInCharacterGroup())
341 mpStream
->startCharacterGroup();
342 mpParserState
->setInCharacterGroup(true);
343 mpParserState
->resolveCharacterProperties(*mpStream
);
346 // tdf#108714 : if we have a postponed break information,
347 // then apply it now, before any other paragraph content.
348 mpParserState
->resolvePostponedBreak(*mpStream
);
352 void OOXMLFastContextHandler::endCharacterGroup()
354 if (isForwardEvents() && mpParserState
->isInCharacterGroup())
356 mpStream
->endCharacterGroup();
357 mpParserState
->setInCharacterGroup(false);
361 void OOXMLFastContextHandler::pushBiDiEmbedLevel() {}
363 void OOXMLFastContextHandler::popBiDiEmbedLevel() {}
365 void OOXMLFastContextHandler::startParagraphGroup()
367 if (isForwardEvents())
369 if (mpParserState
->isInParagraphGroup())
372 if (! mpParserState
->isInSectionGroup())
375 if (! mpParserState
->isInParagraphGroup())
377 mpStream
->startParagraphGroup();
378 mpParserState
->setInParagraphGroup(true);
383 void OOXMLFastContextHandler::endParagraphGroup()
385 if (isForwardEvents())
387 if (mpParserState
->isInCharacterGroup())
390 if (mpParserState
->isInParagraphGroup())
392 mpStream
->endParagraphGroup();
393 mpParserState
->setInParagraphGroup(false);
398 void OOXMLFastContextHandler::startSdt()
400 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
401 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(1);
402 pProps
->add(NS_ooxml::LN_CT_SdtBlock_sdtContent
, pVal
, OOXMLProperty::ATTRIBUTE
);
403 mpStream
->props(pProps
.get());
406 void OOXMLFastContextHandler::endSdt()
408 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
409 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(1);
410 pProps
->add(NS_ooxml::LN_CT_SdtBlock_sdtEndContent
, pVal
, OOXMLProperty::ATTRIBUTE
);
411 mpStream
->props(pProps
.get());
414 void OOXMLFastContextHandler::startSectionGroup()
416 if (isForwardEvents())
418 if (mpParserState
->isInSectionGroup())
421 if (! mpParserState
->isInSectionGroup())
423 mpStream
->info(mpParserState
->getHandle());
424 mpStream
->startSectionGroup();
425 mpParserState
->setInSectionGroup(true);
430 void OOXMLFastContextHandler::endSectionGroup()
432 if (isForwardEvents())
434 if (mpParserState
->isInParagraphGroup())
437 if (mpParserState
->isInSectionGroup())
439 mpStream
->endSectionGroup();
440 mpParserState
->setInSectionGroup(false);
445 void OOXMLFastContextHandler::setLastParagraphInSection()
447 mpParserState
->setLastParagraphInSection(true);
448 mpStream
->markLastParagraphInSection( );
451 void OOXMLFastContextHandler::setLastSectionGroup()
453 mpStream
->markLastSectionGroup( );
456 void OOXMLFastContextHandler::newProperty
457 (Id
/*nId*/, const OOXMLValue::Pointer_t
& /*pVal*/)
461 void OOXMLFastContextHandler::setPropertySet
462 (const OOXMLPropertySet::Pointer_t
& /* pPropertySet */)
466 OOXMLPropertySet::Pointer_t
OOXMLFastContextHandler::getPropertySet() const
468 return OOXMLPropertySet::Pointer_t();
471 void OOXMLFastContextHandler::startField()
473 startCharacterGroup();
474 if (isForwardEvents())
475 mpStream
->text(&cFieldStart
, 1);
479 void OOXMLFastContextHandler::fieldSeparator()
481 startCharacterGroup();
482 if (isForwardEvents())
483 mpStream
->text(&cFieldSep
, 1);
487 void OOXMLFastContextHandler::endField()
489 startCharacterGroup();
490 if (isForwardEvents())
491 mpStream
->text(&cFieldEnd
, 1);
495 void OOXMLFastContextHandler::lockField()
497 startCharacterGroup();
498 if (isForwardEvents())
499 mpStream
->text(&cFieldLock
, 1);
503 void OOXMLFastContextHandler::ftnednref()
507 void OOXMLFastContextHandler::ftnednsep()
509 if (isForwardEvents())
510 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uFtnEdnSep
), 1);
513 void OOXMLFastContextHandler::ftnedncont()
515 if (isForwardEvents())
516 mpStream
->text(&cFtnEdnCont
, 1);
519 void OOXMLFastContextHandler::pgNum()
521 if (isForwardEvents())
522 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uPgNum
), 1);
525 void OOXMLFastContextHandler::tab()
527 if (isForwardEvents())
528 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uTab
), 1);
531 void OOXMLFastContextHandler::symbol()
533 if (isForwardEvents())
534 sendPropertiesWithId(NS_ooxml::LN_EG_RunInnerContent_sym
);
537 void OOXMLFastContextHandler::cr()
539 if (isForwardEvents())
540 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uCR
), 1);
543 void OOXMLFastContextHandler::noBreakHyphen()
545 if (isForwardEvents())
546 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uNoBreakHyphen
), 1);
549 void OOXMLFastContextHandler::softHyphen()
551 if (isForwardEvents())
552 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uSoftHyphen
), 1);
555 void OOXMLFastContextHandler::handleLastParagraphInSection()
557 if (mpParserState
->isLastParagraphInSection())
559 mpParserState
->setLastParagraphInSection(false);
564 void OOXMLFastContextHandler::endOfParagraph()
566 if (! mpParserState
->isInCharacterGroup())
567 startCharacterGroup();
568 if (isForwardEvents())
569 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uCR
), 1);
571 mpParserState
->getDocument()->incrementProgress();
574 void OOXMLFastContextHandler::startTxbxContent()
577 This usually means there are recursive <w:p> elements, and the ones
578 inside and outside of w:txbxContent should not interfere (e.g.
579 the lastParagraphInSection setting). So save the whole state
580 and possibly start new groups for the nested content (not section
581 group though, as that'd cause the txbxContent to be moved onto
582 another page, I'm not sure how that should work exactly).
584 mpParserState
->startTxbxContent();
585 startParagraphGroup();
588 void OOXMLFastContextHandler::endTxbxContent()
591 mpParserState
->endTxbxContent();
595 // XML schema defines white space as one of four characters:
596 // #x9 (tab), #xA (line feed), #xD (carriage return), and #x20 (space)
597 bool IsXMLWhitespace(sal_Unicode cChar
)
599 return cChar
== 0x9 || cChar
== 0xA || cChar
== 0xD || cChar
== 0x20;
602 OUString
TrimXMLWhitespace(const OUString
& sText
)
604 sal_Int32 nTrimmedStart
= 0;
605 const sal_Int32 nLen
= sText
.getLength();
606 sal_Int32 nTrimmedEnd
= nLen
- 1;
607 while (nTrimmedStart
< nLen
&& IsXMLWhitespace(sText
[nTrimmedStart
]))
609 while (nTrimmedStart
<= nTrimmedEnd
&& IsXMLWhitespace(sText
[nTrimmedEnd
]))
611 if ((nTrimmedStart
== 0) && (nTrimmedEnd
== nLen
- 1))
613 else if (nTrimmedStart
> nTrimmedEnd
)
616 return sText
.copy(nTrimmedStart
, nTrimmedEnd
-nTrimmedStart
+1);
620 void OOXMLFastContextHandler::text(const OUString
& sText
)
622 if (isForwardEvents())
624 // tdf#108806: CRLFs in XML were converted to \n before this point.
625 // These must be converted to spaces before further processing.
626 OUString sNormalizedText
= sText
.replaceAll("\n", " ");
627 // tdf#108995: by default, leading and trailing white space is ignored;
628 // tabs are converted to spaces
629 if (!IsPreserveSpace())
631 sNormalizedText
= TrimXMLWhitespace(sNormalizedText
).replaceAll("\t", " ");
633 mpStream
->utext(reinterpret_cast < const sal_uInt8
* >
634 (sNormalizedText
.getStr()),
635 sNormalizedText
.getLength());
639 void OOXMLFastContextHandler::positionOffset(const OUString
& rText
)
641 if (isForwardEvents())
642 mpStream
->positionOffset(rText
, inPositionV
);
645 void OOXMLFastContextHandler::ignore()
649 void OOXMLFastContextHandler::alignH(const OUString
& rText
)
651 if (isForwardEvents())
652 mpStream
->align(rText
, /*bVertical=*/false);
655 void OOXMLFastContextHandler::alignV(const OUString
& rText
)
657 if (isForwardEvents())
658 mpStream
->align(rText
, /*bVertical=*/true);
661 void OOXMLFastContextHandler::positivePercentage(const OUString
& rText
)
663 if (isForwardEvents())
664 mpStream
->positivePercentage(rText
);
667 void OOXMLFastContextHandler::startGlossaryEntry()
669 if (isForwardEvents())
670 mpStream
->startGlossaryEntry();
673 void OOXMLFastContextHandler::endGlossaryEntry()
675 if (isForwardEvents())
676 mpStream
->endGlossaryEntry();
679 void OOXMLFastContextHandler::propagateCharacterProperties()
681 mpParserState
->setCharacterProperties(getPropertySet());
684 void OOXMLFastContextHandler::propagateCharacterPropertiesAsSet(Id nId
)
686 OOXMLValue::Pointer_t
pValue(new OOXMLPropertySetValue(getPropertySet()));
687 OOXMLPropertySet::Pointer_t
pPropertySet(new OOXMLPropertySet
);
689 pPropertySet
->add(nId
, pValue
, OOXMLProperty::SPRM
);
690 mpParserState
->setCharacterProperties(pPropertySet
);
693 void OOXMLFastContextHandler::propagateCellProperties()
695 mpParserState
->setCellProperties(getPropertySet());
698 void OOXMLFastContextHandler::propagateRowProperties()
700 mpParserState
->setRowProperties(getPropertySet());
703 void OOXMLFastContextHandler::propagateTableProperties()
705 OOXMLPropertySet::Pointer_t pProps
= getPropertySet();
707 mpParserState
->setTableProperties(pProps
);
710 void OOXMLFastContextHandler::sendCellProperties()
712 mpParserState
->resolveCellProperties(*mpStream
);
715 void OOXMLFastContextHandler::sendRowProperties()
717 mpParserState
->resolveRowProperties(*mpStream
);
720 void OOXMLFastContextHandler::sendTableProperties()
722 mpParserState
->resolveTableProperties(*mpStream
);
725 void OOXMLFastContextHandler::clearTableProps()
727 mpParserState
->setTableProperties(new OOXMLPropertySet());
730 void OOXMLFastContextHandler::sendPropertiesWithId(Id nId
)
732 OOXMLValue::Pointer_t
pValue(new OOXMLPropertySetValue(getPropertySet()));
733 OOXMLPropertySet::Pointer_t
pPropertySet(new OOXMLPropertySet
);
735 pPropertySet
->add(nId
, pValue
, OOXMLProperty::SPRM
);
736 mpStream
->props(pPropertySet
.get());
739 void OOXMLFastContextHandler::clearProps()
741 setPropertySet(new OOXMLPropertySet());
744 void OOXMLFastContextHandler::setDefaultBooleanValue()
748 void OOXMLFastContextHandler::setDefaultIntegerValue()
752 void OOXMLFastContextHandler::setDefaultHexValue()
756 void OOXMLFastContextHandler::setDefaultStringValue()
760 void OOXMLFastContextHandler::setDocument(OOXMLDocumentImpl
* pDocument
)
762 mpParserState
->setDocument(pDocument
);
765 OOXMLDocumentImpl
* OOXMLFastContextHandler::getDocument()
767 return mpParserState
->getDocument();
770 void OOXMLFastContextHandler::setForwardEvents(bool bForwardEvents
)
772 mpParserState
->setForwardEvents(bForwardEvents
);
775 bool OOXMLFastContextHandler::isForwardEvents() const
777 return mpParserState
->isForwardEvents();
780 void OOXMLFastContextHandler::setXNoteId(const sal_Int32 nId
)
782 mpParserState
->setXNoteId(nId
);
785 void OOXMLFastContextHandler::setXNoteId(const OOXMLValue::Pointer_t
& pValue
)
787 mpParserState
->setXNoteId(sal_Int32(pValue
->getInt()));
790 sal_Int32
OOXMLFastContextHandler::getXNoteId() const
792 return mpParserState
->getXNoteId();
795 void OOXMLFastContextHandler::resolveFootnote
796 (const sal_Int32 nId
)
798 mpParserState
->getDocument()->resolveFootnote
802 void OOXMLFastContextHandler::resolveEndnote(const sal_Int32 nId
)
804 mpParserState
->getDocument()->resolveEndnote
808 void OOXMLFastContextHandler::resolveComment(const sal_Int32 nId
)
810 mpParserState
->getDocument()->resolveComment(*mpStream
, nId
);
813 void OOXMLFastContextHandler::resolvePicture(const OUString
& rId
)
815 mpParserState
->getDocument()->resolvePicture(*mpStream
, rId
);
818 void OOXMLFastContextHandler::resolveHeader
819 (const sal_Int32 type
, const OUString
& rId
)
821 mpParserState
->getDocument()->resolveHeader(*mpStream
, type
, rId
);
824 void OOXMLFastContextHandler::resolveFooter
825 (const sal_Int32 type
, const OUString
& rId
)
827 mpParserState
->getDocument()->resolveFooter(*mpStream
, type
, rId
);
830 // Add the data pointed to by the reference as another property.
831 void OOXMLFastContextHandler::resolveData(const OUString
& rId
)
833 OOXMLDocument
* objDocument
= getDocument();
834 SAL_WARN_IF(!objDocument
, "writerfilter", "no document to resolveData");
838 uno::Reference
<io::XInputStream
> xInputStream
839 (objDocument
->getInputStreamForId(rId
));
841 OOXMLValue::Pointer_t
aValue(new OOXMLInputStreamValue(xInputStream
));
843 newProperty(NS_ooxml::LN_inputstream
, aValue
);
846 OUString
OOXMLFastContextHandler::getTargetForId
847 (const OUString
& rId
)
849 return mpParserState
->getDocument()->getTargetForId(rId
);
852 void OOXMLFastContextHandler::sendPropertyToParent()
854 if (mpParent
!= nullptr)
856 OOXMLPropertySet::Pointer_t
pProps(mpParent
->getPropertySet());
858 if (pProps
.get() != nullptr)
860 pProps
->add(mId
, getValue(), OOXMLProperty::SPRM
);
865 void OOXMLFastContextHandler::sendPropertiesToParent()
867 if (mpParent
!= nullptr)
869 OOXMLPropertySet::Pointer_t
pParentProps(mpParent
->getPropertySet());
871 if (pParentProps
.get() != nullptr)
873 OOXMLPropertySet::Pointer_t
pProps(getPropertySet());
875 if (pProps
.get() != nullptr)
877 OOXMLValue::Pointer_t pValue
878 (new OOXMLPropertySetValue(getPropertySet()));
880 pParentProps
->add(getId(), pValue
, OOXMLProperty::SPRM
);
887 bool OOXMLFastContextHandler::IsPreserveSpace() const
889 // xml:space attribute applies to all elements within the content of the element where it is specified,
890 // unless overridden with another instance of the xml:space attribute
891 if (mbPreserveSpaceSet
)
892 return mbPreserveSpace
;
894 return mpParent
->IsPreserveSpace();
895 return false; // default value
899 class OOXMLFastContextHandlerStream
902 OOXMLFastContextHandlerStream::OOXMLFastContextHandlerStream
903 (OOXMLFastContextHandler
* pContext
)
904 : OOXMLFastContextHandler(pContext
),
905 mpPropertySetAttrs(new OOXMLPropertySet
)
909 OOXMLFastContextHandlerStream::~OOXMLFastContextHandlerStream()
913 void OOXMLFastContextHandlerStream::newProperty(Id nId
,
914 const OOXMLValue::Pointer_t
& pVal
)
918 mpPropertySetAttrs
->add(nId
, pVal
, OOXMLProperty::ATTRIBUTE
);
922 void OOXMLFastContextHandlerStream::sendProperty(Id nId
)
924 OOXMLPropertySetEntryToString
aHandler(nId
);
925 getPropertySetAttrs()->resolve(aHandler
);
926 const OUString
& sText
= aHandler
.getString();
927 mpStream
->utext(reinterpret_cast < const sal_uInt8
* >
933 OOXMLPropertySet::Pointer_t
OOXMLFastContextHandlerStream::getPropertySet()
936 return getPropertySetAttrs();
939 void OOXMLFastContextHandlerStream::handleHyperlink()
941 OOXMLHyperlinkHandler
aHyperlinkHandler(this);
942 getPropertySetAttrs()->resolve(aHyperlinkHandler
);
943 aHyperlinkHandler
.writetext();
947 class OOXMLFastContextHandlerProperties
949 OOXMLFastContextHandlerProperties::OOXMLFastContextHandlerProperties
950 (OOXMLFastContextHandler
* pContext
)
951 : OOXMLFastContextHandler(pContext
), mpPropertySet(new OOXMLPropertySet
),
954 if (pContext
->getResource() == STREAM
)
958 OOXMLFastContextHandlerProperties::~OOXMLFastContextHandlerProperties()
962 void OOXMLFastContextHandlerProperties::lcl_endFastElement
963 (Token_t
/*Element*/)
971 if (isForwardEvents())
973 mpStream
->props(mpPropertySet
.get());
978 sendPropertiesToParent();
981 catch (const uno::RuntimeException
&)
985 catch (const xml::sax::SAXException
&)
989 catch (const uno::Exception
& e
)
991 auto a
= cppu::getCaughtException();
992 throw lang::WrappedTargetRuntimeException(e
.Message
, e
.Context
, a
);
996 OOXMLValue::Pointer_t
OOXMLFastContextHandlerProperties::getValue() const
998 return OOXMLValue::Pointer_t(new OOXMLPropertySetValue(mpPropertySet
));
1001 void OOXMLFastContextHandlerProperties::newProperty
1002 (Id nId
, const OOXMLValue::Pointer_t
& pVal
)
1006 mpPropertySet
->add(nId
, pVal
, OOXMLProperty::ATTRIBUTE
);
1010 void OOXMLFastContextHandlerProperties::handleXNotes()
1014 case W_TOKEN(footnoteReference
):
1016 OOXMLFootnoteHandler
aFootnoteHandler(this);
1017 mpPropertySet
->resolve(aFootnoteHandler
);
1020 case W_TOKEN(endnoteReference
):
1022 OOXMLEndnoteHandler
aEndnoteHandler(this);
1023 mpPropertySet
->resolve(aEndnoteHandler
);
1031 void OOXMLFastContextHandlerProperties::handleHdrFtr()
1035 case W_TOKEN(footerReference
):
1037 OOXMLFooterHandler
aFooterHandler(this);
1038 mpPropertySet
->resolve(aFooterHandler
);
1039 aFooterHandler
.finalize();
1042 case W_TOKEN(headerReference
):
1044 OOXMLHeaderHandler
aHeaderHandler(this);
1045 mpPropertySet
->resolve(aHeaderHandler
);
1046 aHeaderHandler
.finalize();
1054 void OOXMLFastContextHandlerProperties::handleComment()
1056 OOXMLCommentHandler
aCommentHandler(this);
1057 getPropertySet()->resolve(aCommentHandler
);
1060 void OOXMLFastContextHandlerProperties::handlePicture()
1062 OOXMLPictureHandler
aPictureHandler(this);
1063 getPropertySet()->resolve(aPictureHandler
);
1066 void OOXMLFastContextHandlerProperties::handleBreak()
1068 if(isForwardEvents())
1070 OOXMLBreakHandler
aBreakHandler(*mpStream
);
1071 getPropertySet()->resolve(aBreakHandler
);
1075 // tdf#108714 : allow <w:br> at block level (despite this is illegal according to ECMA-376-1:2016)
1076 void OOXMLFastContextHandlerProperties::handleOutOfOrderBreak()
1078 if(isForwardEvents())
1080 mpParserState
->setPostponedBreak(getPropertySet());
1084 void OOXMLFastContextHandlerProperties::handleOLE()
1086 OOXMLOLEHandler
aOLEHandler(this);
1087 getPropertySet()->resolve(aOLEHandler
);
1090 void OOXMLFastContextHandlerProperties::handleFontRel()
1092 OOXMLEmbeddedFontHandler
handler(this);
1093 getPropertySet()->resolve(handler
);
1096 void OOXMLFastContextHandlerProperties::handleHyperlinkURL() {
1097 OOXMLHyperlinkURLHandler
aHyperlinkURLHandler(this);
1098 getPropertySet()->resolve(aHyperlinkURLHandler
);
1101 void OOXMLFastContextHandlerProperties::setPropertySet
1102 (const OOXMLPropertySet::Pointer_t
& pPropertySet
)
1104 if (pPropertySet
.get() != nullptr)
1105 mpPropertySet
= pPropertySet
;
1108 OOXMLPropertySet::Pointer_t
1109 OOXMLFastContextHandlerProperties::getPropertySet() const
1111 return mpPropertySet
;
1115 * class OOXMLFasContextHandlerPropertyTable
1118 OOXMLFastContextHandlerPropertyTable::OOXMLFastContextHandlerPropertyTable
1119 (OOXMLFastContextHandler
* pContext
)
1120 : OOXMLFastContextHandlerProperties(pContext
)
1124 OOXMLFastContextHandlerPropertyTable::~OOXMLFastContextHandlerPropertyTable()
1128 void OOXMLFastContextHandlerPropertyTable::lcl_endFastElement
1129 (Token_t
/*Element*/)
1131 OOXMLPropertySet::Pointer_t
pPropSet(mpPropertySet
->clone());
1132 OOXMLTable::ValuePointer_t pTmpVal
1133 (new OOXMLPropertySetValue(pPropSet
));
1135 mTable
.add(pTmpVal
);
1137 writerfilter::Reference
<Table
>::Pointer_t
pTable(mTable
.clone());
1139 mpStream
->table(mId
, pTable
);
1145 class OOXMLFastContextHandlerValue
1148 OOXMLFastContextHandlerValue::OOXMLFastContextHandlerValue
1149 (OOXMLFastContextHandler
* pContext
)
1150 : OOXMLFastContextHandler(pContext
)
1154 OOXMLFastContextHandlerValue::~OOXMLFastContextHandlerValue()
1158 void OOXMLFastContextHandlerValue::setValue(const OOXMLValue::Pointer_t
& pValue
)
1163 OOXMLValue::Pointer_t
OOXMLFastContextHandlerValue::getValue() const
1168 void OOXMLFastContextHandlerValue::lcl_endFastElement
1169 (Token_t
/*Element*/)
1171 sendPropertyToParent();
1176 void OOXMLFastContextHandlerValue::setDefaultBooleanValue()
1178 if (mpValue
.get() == nullptr)
1180 OOXMLValue::Pointer_t pValue
= OOXMLBooleanValue::Create(true);
1185 void OOXMLFastContextHandlerValue::setDefaultIntegerValue()
1187 if (mpValue
.get() == nullptr)
1189 OOXMLValue::Pointer_t pValue
= OOXMLIntegerValue::Create(0);
1194 void OOXMLFastContextHandlerValue::setDefaultHexValue()
1196 if (mpValue
.get() == nullptr)
1198 OOXMLValue::Pointer_t
pValue(new OOXMLHexValue(sal_uInt32(0)));
1203 void OOXMLFastContextHandlerValue::setDefaultStringValue()
1205 if (mpValue
.get() == nullptr)
1207 OOXMLValue::Pointer_t
pValue(new OOXMLStringValue(OUString()));
1212 // ECMA-376-1:2016 17.3.2.8; https://www.unicode.org/reports/tr9/#Explicit_Directional_Embeddings
1213 void OOXMLFastContextHandlerValue::pushBiDiEmbedLevel()
1216 = mpValue
.get() && mpValue
.get()->getInt() == NS_ooxml::LN_Value_ST_Direction_rtl
;
1217 OOXMLFactory::characters(this, bRtl
? u
"\u202B" : u
"\u202A"); // RLE / LRE
1220 void OOXMLFastContextHandlerValue::popBiDiEmbedLevel()
1222 OOXMLFactory::characters(this, u
"\u202C"); // PDF (POP DIRECTIONAL FORMATTING)
1226 class OOXMLFastContextHandlerTable
1229 OOXMLFastContextHandlerTable::OOXMLFastContextHandlerTable
1230 (OOXMLFastContextHandler
* pContext
)
1231 : OOXMLFastContextHandler(pContext
)
1235 OOXMLFastContextHandlerTable::~OOXMLFastContextHandlerTable()
1239 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
1240 OOXMLFastContextHandlerTable::createFastChildContext
1242 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1246 mCurrentChild
.set(OOXMLFastContextHandler::createFastChildContext(Element
, Attribs
));
1248 return mCurrentChild
;
1251 void OOXMLFastContextHandlerTable::lcl_endFastElement
1252 (Token_t
/*Element*/)
1256 writerfilter::Reference
<Table
>::Pointer_t
pTable(mTable
.clone());
1257 if (isForwardEvents() && mId
!= 0x0)
1259 mpStream
->table(mId
, pTable
);
1263 void OOXMLFastContextHandlerTable::addCurrentChild()
1265 OOXMLFastContextHandler
* pHandler
= dynamic_cast<OOXMLFastContextHandler
*>(mCurrentChild
.get());
1266 if (pHandler
!= nullptr)
1268 OOXMLValue::Pointer_t
pValue(pHandler
->getValue());
1270 if (pValue
.get() != nullptr)
1272 OOXMLTable::ValuePointer_t
pTmpVal(pValue
->clone());
1273 mTable
.add(pTmpVal
);
1279 class OOXMLFastContextHandlerXNote
1282 OOXMLFastContextHandlerXNote::OOXMLFastContextHandlerXNote
1283 (OOXMLFastContextHandler
* pContext
)
1284 : OOXMLFastContextHandlerProperties(pContext
)
1285 , mbForwardEventsSaved(false)
1291 OOXMLFastContextHandlerXNote::~OOXMLFastContextHandlerXNote()
1295 void OOXMLFastContextHandlerXNote::lcl_startFastElement
1296 (Token_t
/*Element*/,
1297 const uno::Reference
< xml::sax::XFastAttributeList
> & /*Attribs*/)
1299 mbForwardEventsSaved
= isForwardEvents();
1301 // If this is the note we're looking for or this is the footnote separator one.
1302 if (mnMyXNoteId
== getXNoteId() || static_cast<sal_uInt32
>(mnMyXNoteType
) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator
)
1303 setForwardEvents(true);
1305 setForwardEvents(false);
1310 void OOXMLFastContextHandlerXNote::lcl_endFastElement
1315 OOXMLFastContextHandlerProperties::lcl_endFastElement(Element
);
1317 setForwardEvents(mbForwardEventsSaved
);
1320 void OOXMLFastContextHandlerXNote::checkId(const OOXMLValue::Pointer_t
& pValue
)
1322 mnMyXNoteId
= sal_Int32(pValue
->getInt());
1325 void OOXMLFastContextHandlerXNote::checkType(const OOXMLValue::Pointer_t
& pValue
)
1327 mnMyXNoteType
= pValue
->getInt();
1331 class OOXMLFastContextHandlerTextTableCell
1334 OOXMLFastContextHandlerTextTableCell::OOXMLFastContextHandlerTextTableCell
1335 (OOXMLFastContextHandler
* pContext
)
1336 : OOXMLFastContextHandler(pContext
)
1340 OOXMLFastContextHandlerTextTableCell::~OOXMLFastContextHandlerTextTableCell()
1344 void OOXMLFastContextHandlerTextTableCell::startCell()
1346 if (isForwardEvents())
1348 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
1350 OOXMLValue::Pointer_t pVal
= OOXMLBooleanValue::Create(mnTableDepth
> 0);
1351 pProps
->add(NS_ooxml::LN_tcStart
, pVal
, OOXMLProperty::SPRM
);
1354 mpStream
->props(pProps
.get());
1358 void OOXMLFastContextHandlerTextTableCell::endCell()
1360 if (isForwardEvents())
1362 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
1364 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(mnTableDepth
);
1365 pProps
->add(NS_ooxml::LN_tblDepth
, pVal
, OOXMLProperty::SPRM
);
1368 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(1);
1369 pProps
->add(NS_ooxml::LN_inTbl
, pVal
, OOXMLProperty::SPRM
);
1372 OOXMLValue::Pointer_t pVal
= OOXMLBooleanValue::Create(mnTableDepth
> 0);
1373 pProps
->add(NS_ooxml::LN_tblCell
, pVal
, OOXMLProperty::SPRM
);
1376 OOXMLValue::Pointer_t pVal
= OOXMLBooleanValue::Create(mnTableDepth
> 0);
1377 pProps
->add(NS_ooxml::LN_tcEnd
, pVal
, OOXMLProperty::SPRM
);
1380 mpStream
->props(pProps
.get());
1385 class OOXMLFastContextHandlerTextTableRow
1388 OOXMLFastContextHandlerTextTableRow::OOXMLFastContextHandlerTextTableRow
1389 (OOXMLFastContextHandler
* pContext
)
1390 : OOXMLFastContextHandler(pContext
)
1394 OOXMLFastContextHandlerTextTableRow::~OOXMLFastContextHandlerTextTableRow()
1398 void OOXMLFastContextHandlerTextTableRow::startRow()
1402 void OOXMLFastContextHandlerTextTableRow::endRow()
1406 // Grid after is the same as grid before, the empty cells are just
1407 // inserted after the real ones, not before.
1408 handleGridBefore(mpGridAfter
);
1409 mpGridAfter
= nullptr;
1412 startParagraphGroup();
1414 if (isForwardEvents())
1416 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
1418 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(mnTableDepth
);
1419 pProps
->add(NS_ooxml::LN_tblDepth
, pVal
, OOXMLProperty::SPRM
);
1422 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(1);
1423 pProps
->add(NS_ooxml::LN_inTbl
, pVal
, OOXMLProperty::SPRM
);
1426 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(1);
1427 pProps
->add(NS_ooxml::LN_tblRow
, pVal
, OOXMLProperty::SPRM
);
1430 mpStream
->props(pProps
.get());
1433 startCharacterGroup();
1435 if (isForwardEvents())
1436 mpStream
->utext(reinterpret_cast<const sal_uInt8
*>(&uCR
), 1);
1438 endCharacterGroup();
1439 endParagraphGroup();
1442 void OOXMLFastContextHandlerTextTableRow::handleGridAfter(const OOXMLValue::Pointer_t
& rValue
)
1444 if (OOXMLFastContextHandler
* pTableRowProperties
= getParent())
1446 if (OOXMLFastContextHandler
* pTableRow
= pTableRowProperties
->getParent())
1447 // Save the value into the table row context, so it can be handled
1448 // right before the end of the row.
1449 pTableRow
->setGridAfter(rValue
);
1454 OOXMLValue::Pointer_t
fakeNoBorder()
1456 OOXMLPropertySet::Pointer_t
pProps( new OOXMLPropertySet
);
1457 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(0);
1458 pProps
->add(NS_ooxml::LN_CT_Border_val
, pVal
, OOXMLProperty::ATTRIBUTE
);
1459 OOXMLValue::Pointer_t
pValue( new OOXMLPropertySetValue( pProps
));
1464 // Handle w:gridBefore here by faking necessary input that'll fake cells. I'm apparently
1465 // not insane enough to find out how to add cells in dmapper.
1466 void OOXMLFastContextHandlerTextTableRow::handleGridBefore( const OOXMLValue::Pointer_t
& val
)
1468 int count
= val
->getInt();
1475 if (isForwardEvents())
1477 // This whole part is OOXMLFastContextHandlerTextTableCell::endCell() .
1478 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
1480 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(mnTableDepth
);
1481 pProps
->add(NS_ooxml::LN_tblDepth
, pVal
, OOXMLProperty::SPRM
);
1484 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(1);
1485 pProps
->add(NS_ooxml::LN_inTbl
, pVal
, OOXMLProperty::SPRM
);
1488 OOXMLValue::Pointer_t pVal
= OOXMLBooleanValue::Create(mnTableDepth
> 0);
1489 pProps
->add(NS_ooxml::LN_tblCell
, pVal
, OOXMLProperty::SPRM
);
1492 mpStream
->props(pProps
.get());
1494 // fake <w:tcBorders> with no border
1495 OOXMLPropertySet::Pointer_t
pCellProps( new OOXMLPropertySet
);
1497 OOXMLPropertySet::Pointer_t
pBorderProps( new OOXMLPropertySet
);
1498 static Id borders
[] = { NS_ooxml::LN_CT_TcBorders_top
, NS_ooxml::LN_CT_TcBorders_bottom
,
1499 NS_ooxml::LN_CT_TcBorders_start
, NS_ooxml::LN_CT_TcBorders_end
};
1500 for(sal_uInt32 border
: borders
)
1501 pBorderProps
->add(border
, fakeNoBorder(), OOXMLProperty::SPRM
);
1502 OOXMLValue::Pointer_t
pValue( new OOXMLPropertySetValue( pBorderProps
));
1503 pCellProps
->add(NS_ooxml::LN_CT_TcPrBase_tcBorders
, pValue
, OOXMLProperty::SPRM
);
1504 mpParserState
->setCellProperties(pCellProps
);
1508 sendCellProperties();
1509 endParagraphGroup();
1514 class OOXMLFastContextHandlerTextTable
1517 OOXMLFastContextHandlerTextTable::OOXMLFastContextHandlerTextTable
1518 (OOXMLFastContextHandler
* pContext
)
1519 : OOXMLFastContextHandler(pContext
)
1523 OOXMLFastContextHandlerTextTable::~OOXMLFastContextHandlerTextTable()
1528 void OOXMLFastContextHandlerTextTable::lcl_startFastElement
1529 (Token_t
/*Element*/,
1530 const uno::Reference
< xml::sax::XFastAttributeList
> & /*Attribs*/)
1532 mpParserState
->startTable();
1535 OOXMLPropertySet::Pointer_t
pProps( new OOXMLPropertySet
);
1537 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(mnTableDepth
);
1538 pProps
->add(NS_ooxml::LN_tblStart
, pVal
, OOXMLProperty::SPRM
);
1540 mpParserState
->setCharacterProperties(pProps
);
1545 void OOXMLFastContextHandlerTextTable::lcl_endFastElement
1546 (Token_t
/*Element*/)
1550 OOXMLPropertySet::Pointer_t
pProps( new OOXMLPropertySet
);
1552 OOXMLValue::Pointer_t pVal
= OOXMLIntegerValue::Create(mnTableDepth
);
1553 pProps
->add(NS_ooxml::LN_tblEnd
, pVal
, OOXMLProperty::SPRM
);
1555 mpParserState
->setCharacterProperties(pProps
);
1558 mpParserState
->endTable();
1562 void OOXMLFastContextHandlerTextTable::start_P_Tbl()
1564 // Normally, when one paragraph ends, and another begins,
1565 // in OOXMLFactory_wml::endAction handler for <w:p>,
1566 // pHandler->endOfParagraph() is called, which (among other things)
1567 // calls TableManager::setHandle() to update current cell's starting point.
1568 // Then, in OOXMLFactory_wml::startAction for next <w:p>,
1569 // pHandler->startParagraphGroup() is called, which ends previous group,
1570 // and there, it pushes cells to row in TableManager::endParagraphGroup()
1571 // (cells have correct bounds defined by mCurHandle).
1572 // When a table is child of a <w:p>, that paragraph doesn't end before nested
1573 // paragraph begins. So, pHandler->endOfParagraph() was not (and should not be)
1574 // called. But as next paragraph starts, is the previous group is closed, then
1575 // cells will have wrong boundings. Here, we know that we *are* in paragraph
1576 // group, but it should not be finished.
1577 mpParserState
->setInParagraphGroup(false);
1581 class OOXMLFastContextHandlerShape
1584 OOXMLFastContextHandlerShape::OOXMLFastContextHandlerShape
1585 (OOXMLFastContextHandler
* pContext
)
1586 : OOXMLFastContextHandlerProperties(pContext
), m_bShapeSent( false ),
1587 m_bShapeStarted(false), m_bShapeContextPushed(false)
1591 OOXMLFastContextHandlerShape::~OOXMLFastContextHandlerShape()
1593 if (m_bShapeContextPushed
)
1594 getDocument()->popShapeContext();
1597 void OOXMLFastContextHandlerShape::lcl_startFastElement
1599 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1603 if (mrShapeContext
.is())
1605 mrShapeContext
->startFastElement(Element
, Attribs
);
1609 void SAL_CALL
OOXMLFastContextHandlerShape::startUnknownElement
1610 (const OUString
& Namespace
,
1611 const OUString
& Name
,
1612 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1614 if (mrShapeContext
.is())
1615 mrShapeContext
->startUnknownElement(Namespace
, Name
, Attribs
);
1618 void OOXMLFastContextHandlerShape::setToken(Token_t nToken
)
1620 if (nToken
== Token_t(NMSP_wps
| XML_wsp
) || nToken
== Token_t(NMSP_dmlPicture
| XML_pic
))
1622 // drawingML shapes are independent, <wps:bodyPr> is not parsed after
1623 // shape contents without pushing/popping the stack.
1624 m_bShapeContextPushed
= true;
1625 getDocument()->pushShapeContext();
1628 mrShapeContext
.set(getDocument()->getShapeContext());
1629 if (!mrShapeContext
.is())
1631 // Define the shape context for the whole document
1632 mrShapeContext
= css::xml::sax::FastShapeContextHandler::create(getComponentContext());
1633 getDocument()->setShapeContext(mrShapeContext
);
1636 mrShapeContext
->setModel(getDocument()->getModel());
1637 uno::Reference
<document::XDocumentPropertiesSupplier
> xDocSupplier(getDocument()->getModel(), uno::UNO_QUERY_THROW
);
1638 mrShapeContext
->setDocumentProperties(xDocSupplier
->getDocumentProperties());
1639 mrShapeContext
->setDrawPage(getDocument()->getDrawPage());
1640 mrShapeContext
->setMediaDescriptor(getDocument()->getMediaDescriptor());
1642 mrShapeContext
->setRelationFragmentPath(mpParserState
->getTarget());
1644 OOXMLFastContextHandler::setToken(nToken
);
1646 if (mrShapeContext
.is())
1647 mrShapeContext
->setStartToken(nToken
);
1650 void OOXMLFastContextHandlerShape::sendShape( Token_t Element
)
1652 if ( mrShapeContext
.is() && !m_bShapeSent
)
1654 awt::Point aPosition
= mpStream
->getPositionOffset();
1655 mrShapeContext
->setPosition(aPosition
);
1656 uno::Reference
<drawing::XShape
> xShape(mrShapeContext
->getShape());
1657 m_bShapeSent
= true;
1660 OOXMLValue::Pointer_t
1661 pValue(new OOXMLShapeValue(xShape
));
1662 newProperty(NS_ooxml::LN_shape
, pValue
);
1664 bool bIsPicture
= Element
== ( NMSP_dmlPicture
| XML_pic
);
1666 // Notify the dmapper that the shape is ready to use
1669 mpStream
->startShape( xShape
);
1670 m_bShapeStarted
= true;
1676 void OOXMLFastContextHandlerShape::lcl_endFastElement
1679 if (mrShapeContext
.is())
1681 mrShapeContext
->endFastElement(Element
);
1682 sendShape( Element
);
1685 OOXMLFastContextHandlerProperties::lcl_endFastElement(Element
);
1687 // Ending the shape should be the last thing to do
1688 bool bIsPicture
= Element
== ( NMSP_dmlPicture
| XML_pic
);
1689 if ( !bIsPicture
&& m_bShapeStarted
)
1690 mpStream
->endShape( );
1693 void SAL_CALL
OOXMLFastContextHandlerShape::endUnknownElement
1694 (const OUString
& Namespace
,
1695 const OUString
& Name
)
1697 if (mrShapeContext
.is())
1698 mrShapeContext
->endUnknownElement(Namespace
, Name
);
1701 uno::Reference
< xml::sax::XFastContextHandler
>
1702 OOXMLFastContextHandlerShape::lcl_createFastChildContext
1704 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1706 uno::Reference
< xml::sax::XFastContextHandler
> xContextHandler
;
1708 bool bGroupShape
= Element
== Token_t(NMSP_vml
| XML_group
);
1709 // drawingML version also counts as a group shape.
1710 bGroupShape
|= mrShapeContext
->getStartToken() == Token_t(NMSP_wpg
| XML_wgp
);
1712 switch (oox::getNamespace(Element
))
1716 case NMSP_vmlOffice
:
1718 xContextHandler
.set(OOXMLFactory::createFastChildContextFromStart(this, Element
));
1721 if (!xContextHandler
.is())
1723 if (mrShapeContext
.is())
1725 uno::Reference
<XFastContextHandler
> pChildContext
=
1726 mrShapeContext
->createFastChildContext(Element
, Attribs
);
1728 OOXMLFastContextHandlerWrapper
* pWrapper
=
1729 new OOXMLFastContextHandlerWrapper(this, pChildContext
);
1733 pWrapper
->addNamespace(NMSP_doc
);
1734 pWrapper
->addNamespace(NMSP_vmlWord
);
1735 pWrapper
->addNamespace(NMSP_vmlOffice
);
1736 pWrapper
->addToken( NMSP_vml
|XML_textbox
);
1739 xContextHandler
.set(pWrapper
);
1742 xContextHandler
.set(this);
1747 // VML import of shape text is already handled by
1748 // OOXMLFastContextHandlerWrapper::lcl_createFastChildContext(), here we
1749 // handle the WPS import of shape text, as there the parent context is a
1750 // Shape one, so a different situation.
1751 if (Element
== static_cast<sal_Int32
>(NMSP_wps
| XML_txbx
) ||
1752 Element
== static_cast<sal_Int32
>(NMSP_wps
| XML_linkedTxbx
) )
1755 return xContextHandler
;
1758 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
1759 OOXMLFastContextHandlerShape::createUnknownChildContext
1760 (const OUString
& Namespace
,
1761 const OUString
& Name
,
1762 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1764 uno::Reference
< xml::sax::XFastContextHandler
> xResult
;
1766 if (mrShapeContext
.is())
1767 xResult
.set(mrShapeContext
->createUnknownChildContext
1768 (Namespace
, Name
, Attribs
));
1773 void OOXMLFastContextHandlerShape::lcl_characters
1774 (const OUString
& aChars
)
1776 if (mrShapeContext
.is())
1777 mrShapeContext
->characters(aChars
);
1781 class OOXMLFastContextHandlerWrapper
1784 OOXMLFastContextHandlerWrapper::OOXMLFastContextHandlerWrapper
1785 (OOXMLFastContextHandler
* pParent
,
1786 uno::Reference
<XFastContextHandler
> const & xContext
)
1787 : OOXMLFastContextHandler(pParent
), mxContext(xContext
)
1789 setId(pParent
->getId());
1790 setToken(pParent
->getToken());
1791 setPropertySet(pParent
->getPropertySet());
1794 OOXMLFastContextHandlerWrapper::~OOXMLFastContextHandlerWrapper()
1798 void SAL_CALL
OOXMLFastContextHandlerWrapper::startUnknownElement
1799 (const OUString
& Namespace
,
1800 const OUString
& Name
,
1801 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1804 mxContext
->startUnknownElement(Namespace
, Name
, Attribs
);
1807 void SAL_CALL
OOXMLFastContextHandlerWrapper::endUnknownElement
1808 (const OUString
& Namespace
,
1809 const OUString
& Name
)
1812 mxContext
->endUnknownElement(Namespace
, Name
);
1815 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
1816 OOXMLFastContextHandlerWrapper::createUnknownChildContext
1817 (const OUString
& Namespace
,
1818 const OUString
& Name
,
1819 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1821 uno::Reference
< xml::sax::XFastContextHandler
> xResult
;
1824 xResult
= mxContext
->createUnknownChildContext
1825 (Namespace
, Name
, Attribs
);
1832 void OOXMLFastContextHandlerWrapper::attributes
1833 (const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1837 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
1838 if (pHandler
!= nullptr)
1839 pHandler
->attributes(Attribs
);
1843 OOXMLFastContextHandler::ResourceEnum_t
1844 OOXMLFastContextHandlerWrapper::getResource() const
1849 void OOXMLFastContextHandlerWrapper::addNamespace(Id nId
)
1851 mMyNamespaces
.insert(nId
);
1854 void OOXMLFastContextHandlerWrapper::addToken( Token_t Token
)
1856 mMyTokens
.insert( Token
);
1859 void OOXMLFastContextHandlerWrapper::lcl_startFastElement
1861 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1864 mxContext
->startFastElement(Element
, Attribs
);
1867 void OOXMLFastContextHandlerWrapper::lcl_endFastElement
1871 mxContext
->endFastElement(Element
);
1874 uno::Reference
< xml::sax::XFastContextHandler
>
1875 OOXMLFastContextHandlerWrapper::lcl_createFastChildContext
1877 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
1879 uno::Reference
< xml::sax::XFastContextHandler
> xResult
;
1881 bool bInNamespaces
= mMyNamespaces
.find(oox::getNamespace(Element
)) != mMyNamespaces
.end();
1882 bool bInTokens
= mMyTokens
.find( Element
) != mMyTokens
.end( );
1884 // We have methods to _add_ individual tokens or whole namespaces to be
1885 // processed by writerfilter (instead of oox), but we have no method to
1886 // filter out a single token. Just hardwire the 'wrap' and 'signatureline' tokens
1887 // here until we need a more generic solution.
1888 bool bIsWrap
= Element
== static_cast<sal_Int32
>(NMSP_vmlWord
| XML_wrap
);
1889 bool bIsSignatureLine
= Element
== static_cast<sal_Int32
>(NMSP_vmlOffice
| XML_signatureline
);
1890 bool bSkipImages
= getDocument()->IsSkipImages() && oox::getNamespace(Element
) == NMSP_dml
&&
1891 !((oox::getBaseToken(Element
) == XML_linkedTxbx
) || (oox::getBaseToken(Element
) == XML_txbx
));
1893 if ( bInNamespaces
&& ((!bIsWrap
&& !bIsSignatureLine
) || dynamic_cast<OOXMLFastContextHandlerShape
&>(*mpParent
).isShapeSent()) )
1894 xResult
.set(OOXMLFactory::createFastChildContextFromStart(this, Element
));
1895 else if (mxContext
.is() && !bSkipImages
)
1897 OOXMLFastContextHandlerWrapper
* pWrapper
=
1898 new OOXMLFastContextHandlerWrapper
1899 (this, mxContext
->createFastChildContext(Element
, Attribs
));
1900 pWrapper
->mMyNamespaces
= mMyNamespaces
;
1901 pWrapper
->setPropertySet(getPropertySet());
1902 xResult
.set(pWrapper
);
1908 static_cast<OOXMLFastContextHandlerShape
*>(mpParent
)->sendShape( Element
);
1913 void OOXMLFastContextHandlerWrapper::lcl_characters
1914 (const OUString
& aChars
)
1917 mxContext
->characters(aChars
);
1920 OOXMLFastContextHandler
*
1921 OOXMLFastContextHandlerWrapper::getFastContextHandler() const
1924 return dynamic_cast<OOXMLFastContextHandler
*>(mxContext
.get());
1929 void OOXMLFastContextHandlerWrapper::newProperty
1930 (Id nId
, const OOXMLValue::Pointer_t
& pVal
)
1934 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
1935 if (pHandler
!= nullptr)
1936 pHandler
->newProperty(nId
, pVal
);
1940 void OOXMLFastContextHandlerWrapper::setPropertySet
1941 (const OOXMLPropertySet::Pointer_t
& pPropertySet
)
1945 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
1946 if (pHandler
!= nullptr)
1947 pHandler
->setPropertySet(pPropertySet
);
1950 mpPropertySet
= pPropertySet
;
1953 OOXMLPropertySet::Pointer_t
OOXMLFastContextHandlerWrapper::getPropertySet()
1956 OOXMLPropertySet::Pointer_t
pResult(mpPropertySet
);
1960 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
1961 if (pHandler
!= nullptr)
1962 pResult
= pHandler
->getPropertySet();
1968 string
OOXMLFastContextHandlerWrapper::getType() const
1970 string sResult
= "Wrapper(";
1974 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
1975 if (pHandler
!= nullptr)
1976 sResult
+= pHandler
->getType();
1984 void OOXMLFastContextHandlerWrapper::setId(Id rId
)
1986 OOXMLFastContextHandler::setId(rId
);
1990 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
1991 if (pHandler
!= nullptr)
1992 pHandler
->setId(rId
);
1996 Id
OOXMLFastContextHandlerWrapper::getId() const
1998 Id nResult
= OOXMLFastContextHandler::getId();
2002 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
2003 if (pHandler
!= nullptr && pHandler
->getId() != 0)
2004 nResult
= pHandler
->getId();
2010 void OOXMLFastContextHandlerWrapper::setToken(Token_t nToken
)
2012 OOXMLFastContextHandler::setToken(nToken
);
2016 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
2017 if (pHandler
!= nullptr)
2018 pHandler
->setToken(nToken
);
2022 Token_t
OOXMLFastContextHandlerWrapper::getToken() const
2024 Token_t nResult
= OOXMLFastContextHandler::getToken();
2028 OOXMLFastContextHandler
* pHandler
= getFastContextHandler();
2029 if (pHandler
!= nullptr)
2030 nResult
= pHandler
->getToken();
2038 class OOXMLFastContextHandlerLinear
2041 OOXMLFastContextHandlerLinear::OOXMLFastContextHandlerLinear(OOXMLFastContextHandler
* pContext
)
2042 : OOXMLFastContextHandlerProperties(pContext
)
2047 void OOXMLFastContextHandlerLinear::lcl_startFastElement(Token_t Element
,
2048 const uno::Reference
< xml::sax::XFastAttributeList
>& Attribs
)
2050 buffer
.appendOpeningTag( Element
, Attribs
);
2054 void OOXMLFastContextHandlerLinear::lcl_endFastElement(Token_t Element
)
2056 buffer
.appendClosingTag( Element
);
2057 if( --depthCount
== 0 )
2061 uno::Reference
< xml::sax::XFastContextHandler
>
2062 OOXMLFastContextHandlerLinear::lcl_createFastChildContext(Token_t
,
2063 const uno::Reference
< xml::sax::XFastAttributeList
>&)
2065 uno::Reference
< xml::sax::XFastContextHandler
> xContextHandler
;
2066 xContextHandler
.set( this );
2067 return xContextHandler
;
2070 void OOXMLFastContextHandlerLinear::lcl_characters(const OUString
& aChars
)
2072 buffer
.appendCharacters( aChars
);
2076 class OOXMLFastContextHandlerLinear
2079 OOXMLFastContextHandlerMath::OOXMLFastContextHandlerMath(OOXMLFastContextHandler
* pContext
)
2080 : OOXMLFastContextHandlerLinear(pContext
)
2084 void OOXMLFastContextHandlerMath::process()
2086 SvGlobalName
name( SO3_SM_CLASSID
);
2087 comphelper::EmbeddedObjectContainer container
;
2089 uno::Sequence
<beans::PropertyValue
> objArgs(1);
2090 objArgs
[0].Name
= "DefaultParentBaseURL";
2091 objArgs
[0].Value
<<= getDocument()->GetDocumentBaseURL();
2092 uno::Reference
<embed::XEmbeddedObject
> ref
=
2093 container
.CreateEmbeddedObject(name
.GetByteSequence(), objArgs
, aName
);
2097 uno::Reference
< uno::XInterface
> component(ref
->getComponent(), uno::UNO_QUERY_THROW
);
2098 // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
2099 // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
2100 // to RTLD_GLOBAL, so most probably a gcc bug.
2101 oox::FormulaImportBase
& import
= dynamic_cast<oox::FormulaImportBase
&>(dynamic_cast<SfxBaseModel
&>(*component
.get()));
2102 import
.readFormulaOoxml(buffer
);
2103 if (isForwardEvents())
2105 OOXMLPropertySet::Pointer_t
pProps(new OOXMLPropertySet
);
2106 OOXMLValue::Pointer_t
pVal( new OOXMLStarMathValue( ref
));
2107 pProps
->add(NS_ooxml::LN_starmath
, pVal
, OOXMLProperty::ATTRIBUTE
);
2108 mpStream
->props( pProps
.get() );
2114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */