summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2013-12-04 15:34:37 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2013-12-04 15:40:26 +0100
commit1a2f12f78f6b01a705e3f92ea2a281181dcfcb00 (patch)
tree1b732fd4a4d7abc4b715ad9addabfa54bcbe39f4
parent500343105707a9905f5198a4af6ad58fe307b7c2 (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.cxx18
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.hxx13
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;