diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2013-12-04 15:34:37 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2013-12-04 15:40:26 +0100 |
commit | 1a2f12f78f6b01a705e3f92ea2a281181dcfcb00 (patch) | |
tree | 1b732fd4a4d7abc4b715ad9addabfa54bcbe39f4 | |
parent | 500343105707a9905f5198a4af6ad58fe307b7c2 (diff) |
writerfilter: support nested mc:AlternateContent
It turns out it's possible to nest this, e.g. <mc:Choice
Requires="wps">, and inside that, a <mc:Choice Requires="wp14">.
Change-Id: Icb6250dcc5059894112d8eeba9f327659a42280e
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 18 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.hxx | 13 |
2 files changed, 30 insertions, 1 deletions
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index 14787f73a0eb..78a446075d95 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -155,7 +155,8 @@ OOXMLFastContextHandler::OOXMLFastContextHandler inPositionV(pContext->inPositionV), m_xContext(pContext->m_xContext), m_bDiscardChildren(pContext->m_bDiscardChildren), - m_bTookChoice(pContext->m_bTookChoice) + m_bTookChoice(pContext->m_bTookChoice), + m_aSavedAlternateStates(pContext->m_aSavedAlternateStates) { if (pContext != NULL) { @@ -183,6 +184,14 @@ bool OOXMLFastContextHandler::prepareMceContext(Token_t nElement, const uno::Ref switch (oox::getBaseToken(nElement)) { case OOXML_AlternateContent: + { + SavedAlternateState aState; + aState.m_bDiscardChildren = m_bDiscardChildren; + m_bDiscardChildren = false; + aState.m_bTookChoice = m_bTookChoice; + m_bTookChoice = false; + m_aSavedAlternateStates.push(aState); + } break; case OOXML_Choice: { @@ -265,6 +274,13 @@ throw (uno::RuntimeException, xml::sax::SAXException) if (Element == (NS_mce | OOXML_Choice) || Element == (NS_mce | OOXML_Fallback)) m_bDiscardChildren = false; + else if (Element == (NS_mce | OOXML_AlternateContent)) + { + SavedAlternateState aState(m_aSavedAlternateStates.top()); + m_aSavedAlternateStates.pop(); + m_bDiscardChildren = aState.m_bDiscardChildren; + m_bTookChoice = aState.m_bTookChoice; + } if (!m_bDiscardChildren) lcl_endFastElement(Element); diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx index 14a49a35d03e..86a3b25a7afa 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx @@ -47,6 +47,18 @@ using namespace ::com::sun::star::xml::sax; typedef boost::shared_ptr<Stream> StreamPointer_t; +/** + * Struct to store our 'alternate state'. If multiple mc:AlternateContent + * elements arrive, then while the inner ones are active, the original state is + * saved away, and once they inner goes out of scope, the original state is + * restored. + */ +struct SavedAlternateState +{ + bool m_bDiscardChildren; + bool m_bTookChoice; ///< Did we take the Choice or want Fallback instead? +}; + class OOXMLFastContextHandler: public ::cppu::WeakImplHelper1< xml::sax::XFastContextHandler> @@ -293,6 +305,7 @@ private: uno::Reference< uno::XComponentContext > m_xContext; bool m_bDiscardChildren; bool m_bTookChoice; ///< Did we take the Choice or want Fallback instead? + std::stack<SavedAlternateState> m_aSavedAlternateStates; static sal_uInt32 mnInstanceCount; |