summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorOliver Specht <oliver.specht@cib.de>2024-10-14 14:50:06 +0200
committerThorsten Behrens <thorsten.behrens@allotropia.de>2024-12-10 17:18:10 +0100
commit5fb8e29926a5c0dd1ae027f05d48826399cc31a1 (patch)
tree92b333f15f3a399c8312810c2c7d3009263caf16 /sw
parent9877694e27f7e52ab8ac69c3729677cd8090e41f (diff)
tdf#164065 load vml textbox in a group shape
Store (vml) textbox elements to determine whether to load shape text or Writer frame. Replay elements in second step and process depending on the outcome. - result flag not yet available while processing - The text shape in docx bugdoc of tdf#152878 can now be loaded as Writer frame but with wrong size/position. - should also be applied to drawing ml shapes currently always loaded as Writer frame Change-Id: I0778057f9985f5523d91a9d757e00f2968aba350 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174902 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de> Tested-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de>
Diffstat (limited to 'sw')
-rw-r--r--sw/Library_sw_writerfilter.mk1
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf164065.docxbin0 -> 14817 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport21.cxx15
-rw-r--r--sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx199
-rw-r--r--sw/source/writerfilter/ooxml/OOXMLFastContextHandler.hxx12
-rw-r--r--sw/source/writerfilter/ooxml/ShadowContext.cxx96
-rw-r--r--sw/source/writerfilter/ooxml/ShadowContext.hxx156
7 files changed, 462 insertions, 17 deletions
diff --git a/sw/Library_sw_writerfilter.mk b/sw/Library_sw_writerfilter.mk
index a51650ce9bf2..224b73de5cc7 100644
--- a/sw/Library_sw_writerfilter.mk
+++ b/sw/Library_sw_writerfilter.mk
@@ -134,6 +134,7 @@ $(eval $(call gb_Library_add_exception_objects,sw_writerfilter,\
sw/source/writerfilter/ooxml/OOXMLParserState \
sw/source/writerfilter/ooxml/OOXMLPropertySet \
sw/source/writerfilter/ooxml/OOXMLStreamImpl \
+ sw/source/writerfilter/ooxml/ShadowContext \
))
$(eval $(call gb_Library_add_generated_exception_objects,sw_writerfilter,\
diff --git a/sw/qa/extras/ooxmlexport/data/tdf164065.docx b/sw/qa/extras/ooxmlexport/data/tdf164065.docx
new file mode 100644
index 000000000000..b66a6cdb2da4
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf164065.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index 207568ee8b76..0447f0b78f12 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -17,6 +17,7 @@
#include <com/sun/star/text/XDocumentIndex.hpp>
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/style/LineSpacing.hpp>
#include <com/sun/star/style/LineSpacingMode.hpp>
#include <com/sun/star/packages/zip/ZipFileAccess.hpp>
@@ -1189,6 +1190,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf146269)
}
}
+CPPUNIT_TEST_FIXTURE(Test, testTdf164065)
+{
+ loadAndSave("tdf164065.docx");
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+ uno::Reference<table::XCellRange> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XText> xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xCell->getString());
+}
+
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx b/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx
index 046d8c6aacb0..ab01166040fe 100644
--- a/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx
+++ b/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx
@@ -25,6 +25,7 @@
#include <oox/mathml/imexport.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/shape/ShapeFilterBase.hxx>
+#include <oox/vml/vmlshapecontext.hxx>
#include <sal/log.hxx>
#include <comphelper/embeddedobjectcontainer.hxx>
#include <comphelper/propertyvalue.hxx>
@@ -42,6 +43,7 @@
#include "OOXMLPropertySet.hxx"
#include <dmapper/GraphicHelpers.hxx>
#include <unodraw.hxx>
+#include "ShadowContext.hxx"
const sal_Unicode uCR = 0xd;
const sal_Unicode uFtnEdnRef = 0x2;
@@ -1973,7 +1975,26 @@ OOXMLFastContextHandlerWrapper::OOXMLFastContextHandlerWrapper
rtl::Reference<OOXMLFastContextHandlerShape> const & xShapeHandler)
: OOXMLFastContextHandler(pParent),
mxWrappedContext(xContext),
- mxShapeHandler(xShapeHandler)
+ mxShapeHandler(xShapeHandler),
+ mbIsWriterFrameDetected(false),
+ mbIsReplayTextBox(false)
+{
+ setId(pParent->getId());
+ setToken(pParent->getToken());
+ setPropertySet(pParent->getPropertySet());
+}
+
+OOXMLFastContextHandlerWrapper::OOXMLFastContextHandlerWrapper(OOXMLFastContextHandler * pParent,
+ rtl::Reference<ShadowContext> const & xShadowContext,
+ uno::Reference<XFastContextHandler> const& xParentContext,
+ rtl::Reference<OOXMLFastContextHandlerShape> const & xShapeHandler)
+ : OOXMLFastContextHandler(pParent),
+ mxWrappedContext(xShadowContext),
+ mxShapeHandler(xShapeHandler),
+ mxShadowContext(xShadowContext),
+ mxReplayParentContext(xParentContext),
+ mbIsWriterFrameDetected(false),
+ mbIsReplayTextBox(false)
{
setId(pParent->getId());
setToken(pParent->getToken());
@@ -2001,6 +2022,114 @@ void SAL_CALL OOXMLFastContextHandlerWrapper::endUnknownElement
mxWrappedContext->endUnknownElement(Namespace, Name);
}
+void SAL_CALL OOXMLFastContextHandlerWrapper::endFastElement(::sal_Int32 Element)
+{
+ OOXMLFastContextHandler::endFastElement(Element);
+ if (mxShadowContext.is())
+ {
+ mxWrappedContext = mxReplayParentContext;
+ mbIsReplayTextBox = true;
+ mbIsWriterFrameDetected = mxShadowContext->isWriterFrame();
+ sal_uInt16 nLevel = mxShadowContext->getElementLevel();
+ if (!nLevel)
+ {
+ std::deque<CallData>& callDataDeque = mxShadowContext->getCallData();
+ std::deque<uno::Reference<xml::sax::XFastContextHandler>> aLocalHandlers;
+ for (auto callDataIt = callDataDeque.begin(); callDataIt != callDataDeque.end(); ++callDataIt)
+ {
+ switch (callDataIt->getType())
+ {
+ case Init:
+ {
+ sal_Int32 nElement = callDataIt->getElement();
+ css::uno::Reference<css::xml::sax::XFastAttributeList> rAttribs
+ = callDataIt->getAttributes();
+ if (mbIsWriterFrameDetected)
+ {
+ oox::vml::ShapeContext* pShapeContext = dynamic_cast<oox::vml::ShapeContext*>(mxWrappedContext.get());
+ if (pShapeContext)
+ pShapeContext->setWriterShape();
+ }
+ uno::Reference< xml::sax::XFastContextHandler > newWrapper = lcl_createFastChildContext(nElement, rAttribs);
+ static_cast<OOXMLFastContextHandlerWrapper*>(newWrapper.get())->mbIsWriterFrameDetected = mbIsWriterFrameDetected;
+ aLocalHandlers.push_back(newWrapper);
+ }
+ break;
+ case ElementAttr:
+ {
+ sal_Int32 nElement = callDataIt->getElement();
+ css::uno::Reference<css::xml::sax::XFastAttributeList> rAttrs
+ = callDataIt->getAttributes();
+ auto xHandler = aLocalHandlers.back();
+ if (xHandler)
+ xHandler->startFastElement(nElement, rAttrs);
+ }
+ break;
+ case Char:
+ {
+ const ::rtl::OUString& chars = callDataIt->getChars();
+ auto xHandler = aLocalHandlers.back();
+ if (xHandler)
+ xHandler->characters(chars);
+ }
+ break;
+ case EndElementAttr:
+ {
+ sal_Int32 nElement = callDataIt->getElement();
+ auto xHandler = aLocalHandlers.back();
+ if (xHandler)
+ xHandler->endFastElement(nElement);
+ aLocalHandlers.pop_back();
+ }
+ break;
+ case Unknown:
+ {
+ const ::rtl::OUString& rNameSpace = callDataIt->getUnknownNameSpace();
+ const ::rtl::OUString& rElement = callDataIt->getUnknownElement();
+ css::uno::Reference<css::xml::sax::XFastAttributeList> rAttrs
+ = callDataIt->getAttributes();
+ auto xHandler = aLocalHandlers.back();
+ if (xHandler)
+ xHandler->startUnknownElement(rNameSpace, rElement, rAttrs);
+ }
+ break;
+ case EndUnknown:
+ {
+ const ::rtl::OUString& rNameSpace = callDataIt->getUnknownNameSpace();
+ const ::rtl::OUString& rElement = callDataIt->getUnknownElement();
+ auto xHandler = aLocalHandlers.back();
+ if (xHandler)
+ xHandler->endUnknownElement(rNameSpace, rElement);
+ aLocalHandlers.pop_back();
+ }
+ break;
+ case ElementContext:
+ {
+ sal_Int32 nElement = callDataIt->getElement();
+ css::uno::Reference<css::xml::sax::XFastAttributeList> rAttrs
+ = callDataIt->getAttributes();
+ uno::Reference< xml::sax::XFastContextHandler > newContext = aLocalHandlers.back()->createFastChildContext(nElement, rAttrs);
+ if (nElement == Token_t(NMSP_vml | XML_textbox))
+ static_cast<OOXMLFastContextHandlerWrapper*>(newContext.get())->mbIsWriterFrameDetected = mbIsWriterFrameDetected;
+ aLocalHandlers.push_back(newContext);
+ }
+ break;
+ case UnknownContext:
+ {
+ const ::rtl::OUString& rNameSpace = callDataIt->getUnknownNameSpace();
+ const ::rtl::OUString& rElement = callDataIt->getUnknownElement();
+ css::uno::Reference<css::xml::sax::XFastAttributeList> rAttrs
+ = callDataIt->getAttributes();
+ uno::Reference< xml::sax::XFastContextHandler > newContext = aLocalHandlers.back()->createUnknownChildContext(rNameSpace, rElement, rAttrs);
+ aLocalHandlers.push_back(newContext);
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
OOXMLFastContextHandlerWrapper::createUnknownChildContext
(const OUString & Namespace,
@@ -2051,12 +2180,17 @@ void OOXMLFastContextHandlerWrapper::lcl_startFastElement
{
if (mxWrappedContext.is())
mxWrappedContext->startFastElement(Element, Attribs);
-
- if (mxShapeHandler->isDMLGroupShape()
- && (Element == Token_t(NMSP_wps | XML_txbx)
- || Element == Token_t(NMSP_wps | XML_linkedTxbx)))
- {
- mpStream->startTextBoxContent();
+ if (!mxShadowContext.is())
+ {
+ bool bInTokens = mMyTokens.find(Element) != mMyTokens.end();
+ if ((mxShapeHandler->isDMLGroupShape()
+ && (Element == Token_t(NMSP_wps | XML_txbx)
+ || Element == Token_t(NMSP_wps | XML_linkedTxbx)))
+ //TODO: why check for bInTokens
+ || (!bInTokens && mbIsWriterFrameDetected && Element == Token_t(NMSP_vml | XML_textbox)))
+ {
+ mpStream->startTextBoxContent();
+ }
}
}
@@ -2066,11 +2200,16 @@ void OOXMLFastContextHandlerWrapper::lcl_endFastElement
if (mxWrappedContext.is())
mxWrappedContext->endFastElement(Element);
- if (mxShapeHandler->isDMLGroupShape()
- && (Element == Token_t(NMSP_wps | XML_txbx)
- || Element == Token_t(NMSP_wps | XML_linkedTxbx)))
+ if (!mxShadowContext.is())
{
- mpStream->endTextBoxContent();
+ bool bInTokens = mMyTokens.find(Element) != mMyTokens.end();
+ if ((mxShapeHandler->isDMLGroupShape()
+ && (Element == Token_t(NMSP_wps | XML_txbx)
+ || Element == Token_t(NMSP_wps | XML_linkedTxbx)))
+ || (!bInTokens && mbIsWriterFrameDetected && Element == Token_t(NMSP_vml | XML_textbox)))
+ {
+ mpStream->endTextBoxContent();
+ }
}
}
@@ -2080,6 +2219,10 @@ OOXMLFastContextHandlerWrapper::lcl_createFastChildContext
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
{
uno::Reference< xml::sax::XFastContextHandler > xResult;
+ if (mxShadowContext.is() && !mbIsReplayTextBox)
+ {
+ return mxShadowContext->createFastChildContext(Element, Attribs);
+ }
bool bInNamespaces = mMyNamespaces.find(oox::getNamespace(Element)) != mMyNamespaces.end();
bool bInTokens = mMyTokens.find( Element ) != mMyTokens.end( );
@@ -2100,11 +2243,34 @@ OOXMLFastContextHandlerWrapper::lcl_createFastChildContext
}
else if (mxWrappedContext.is() && !bSkipImages)
{
- rtl::Reference<OOXMLFastContextHandlerWrapper> pWrapper =
- new OOXMLFastContextHandlerWrapper
- (this, mxWrappedContext->createFastChildContext(Element, Attribs),
- mxShapeHandler);
- pWrapper->mMyNamespaces = mMyNamespaces;
+ rtl::Reference<OOXMLFastContextHandlerWrapper> pWrapper;
+ if (Element == (NMSP_vml | XML_textbox) && !mbIsReplayTextBox)
+ {
+ //TODO: change handling of drawingml, currently Writer frame only
+ rtl::Reference<ShadowContext> xShadowContext
+ = new ShadowContext(Element, Attribs);
+ pWrapper = new OOXMLFastContextHandlerWrapper(this, xShadowContext, mxWrappedContext, mxShapeHandler);
+ pWrapper->mMyNamespaces = mMyNamespaces;
+ //don't send shape here
+ bInTokens = false;
+ }
+ else
+ {
+ pWrapper =
+ new OOXMLFastContextHandlerWrapper
+ (this, mxWrappedContext->createFastChildContext(Element, Attribs),
+ mxShapeHandler);
+ if (mbIsWriterFrameDetected)
+ {
+ pWrapper->addNamespace(NMSP_doc);
+ pWrapper->addNamespace(NMSP_vmlWord);
+ pWrapper->addNamespace(NMSP_vmlOffice);
+ }
+ else
+ {
+ pWrapper->mMyNamespaces = mMyNamespaces;
+ }
+ }
pWrapper->mMyTokens = mMyTokens;
pWrapper->setPropertySet(getPropertySet());
xResult.set(pWrapper);
@@ -2243,7 +2409,6 @@ Token_t OOXMLFastContextHandlerWrapper::getToken() const
return nResult;
}
-
/*
class OOXMLFastContextHandlerLinear
*/
diff --git a/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.hxx b/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.hxx
index 03a4d40e5c2f..49abfde529ce 100644
--- a/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.hxx
+++ b/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.hxx
@@ -27,6 +27,7 @@
#include <rtl/ref.hxx>
#include "OOXMLParserState.hxx"
#include "OOXMLPropertySet.hxx"
+#include "ShadowContext.hxx"
namespace writerfilter::ooxml
{
@@ -494,9 +495,14 @@ public:
OOXMLFastContextHandlerWrapper(OOXMLFastContextHandler * pParent,
css::uno::Reference<css::xml::sax::XFastContextHandler> const & xContext,
rtl::Reference<OOXMLFastContextHandlerShape> const & xShapeHandler);
+ OOXMLFastContextHandlerWrapper(OOXMLFastContextHandler * pParent,
+ rtl::Reference<ShadowContext> const & xContext,
+ css::uno::Reference<css::xml::sax::XFastContextHandler> const & xParentContext,
+ rtl::Reference<OOXMLFastContextHandlerShape> const & xShapeHandler);
virtual ~OOXMLFastContextHandlerWrapper() override;
// css::xml::sax::XFastContextHandler:
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) override;
virtual void SAL_CALL startUnknownElement(const OUString & Namespace, const OUString & Name, const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs) override;
virtual void SAL_CALL endUnknownElement(const OUString & Namespace, const OUString & Name) override;
@@ -532,12 +538,18 @@ protected:
virtual void setToken(Token_t nToken) override;
virtual Token_t getToken() const override;
+ bool isWriterFrameDetected() const { return mbIsWriterFrameDetected;}
+
private:
css::uno::Reference<css::xml::sax::XFastContextHandler> mxWrappedContext;
rtl::Reference<OOXMLFastContextHandlerShape> mxShapeHandler;
std::set<Id> mMyNamespaces;
std::set<Token_t> mMyTokens;
OOXMLPropertySet::Pointer_t mpPropertySet;
+ rtl::Reference<ShadowContext> const mxShadowContext;
+ css::uno::Reference<css::xml::sax::XFastContextHandler> mxReplayParentContext;
+ bool mbIsWriterFrameDetected;
+ bool mbIsReplayTextBox;
OOXMLFastContextHandler * getFastContextHandler() const;
};
diff --git a/sw/source/writerfilter/ooxml/ShadowContext.cxx b/sw/source/writerfilter/ooxml/ShadowContext.cxx
new file mode 100644
index 000000000000..d850092c9adc
--- /dev/null
+++ b/sw/source/writerfilter/ooxml/ShadowContext.cxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include "ShadowContext.hxx"
+#include <ooxml/resourceids.hxx>
+#include <oox/token/namespaces.hxx>
+
+namespace writerfilter::ooxml
+{
+using namespace ::com::sun::star;
+using namespace oox;
+using namespace ::com::sun::star::xml::sax;
+
+ShadowContext::ShadowContext(::sal_Int32 nElement,
+ const uno::Reference<XFastAttributeList>& rAttribs)
+ : m_nElementLevel(0)
+ , m_bImportAsWriterFrame(false)
+{
+ CallData callData(m_nElementLevel, nElement, rAttribs, CallDataType::Init);
+ m_aCallDataDeque.push_back(callData);
+}
+ShadowContext::~ShadowContext() {}
+
+void ShadowContext::startFastElement(
+ ::sal_Int32 nElement,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& rAttribs)
+{
+ ++m_nElementLevel;
+ CallData callData(m_nElementLevel, nElement, rAttribs, CallDataType::ElementAttr);
+ m_aCallDataDeque.push_back(callData);
+ if (nElement == (oox::NMSP_doc | oox::XML_tbl))
+ {
+ m_bImportAsWriterFrame = true;
+ }
+}
+
+void ShadowContext::startUnknownElement(
+ const ::rtl::OUString& rNamespace, const ::rtl::OUString& rElement,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& rAttribs)
+{
+ ++m_nElementLevel;
+ CallData callData(m_nElementLevel, rNamespace, rElement, rAttribs, CallDataType::Unknown);
+ m_aCallDataDeque.push_back(callData);
+}
+void ShadowContext::endFastElement(::sal_Int32 nElement)
+{
+ --m_nElementLevel;
+ CallData callData(m_nElementLevel, nElement);
+ m_aCallDataDeque.push_back(callData);
+}
+void ShadowContext::endUnknownElement(const ::rtl::OUString& rNamespace,
+ const ::rtl::OUString& rElement)
+{
+ --m_nElementLevel;
+ CallData callData(m_nElementLevel, rNamespace, rElement);
+ m_aCallDataDeque.push_back(callData);
+}
+::css::uno::Reference<::css::xml::sax::XFastContextHandler> ShadowContext::createFastChildContext(
+ ::sal_Int32 nElement,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& rAttribs)
+{
+ CallData callData(m_nElementLevel, nElement, rAttribs, CallDataType::ElementContext);
+ m_aCallDataDeque.push_back(callData);
+ return this;
+}
+::css::uno::Reference<::css::xml::sax::XFastContextHandler>
+ShadowContext::createUnknownChildContext(
+ const ::rtl::OUString& rNamespace, const ::rtl::OUString& rElement,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& rAttribs)
+{
+ CallData callData(m_nElementLevel, rNamespace, rElement, rAttribs,
+ CallDataType::UnknownContext);
+ m_aCallDataDeque.push_back(callData);
+ return this;
+}
+void ShadowContext::characters(const ::rtl::OUString& aChars)
+{
+ CallData callData(m_nElementLevel, aChars);
+ m_aCallDataDeque.push_back(callData);
+}
+} //namespace
diff --git a/sw/source/writerfilter/ooxml/ShadowContext.hxx b/sw/source/writerfilter/ooxml/ShadowContext.hxx
new file mode 100644
index 000000000000..d7e389d10abd
--- /dev/null
+++ b/sw/source/writerfilter/ooxml/ShadowContext.hxx
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
+#include <sax/fastattribs.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/core/contexthandler.hxx>
+#include <queue>
+
+namespace writerfilter::ooxml
+{
+enum CallDataType
+{
+ Init,
+ ElementAttr,
+ Char,
+ EndElementAttr,
+ Unknown,
+ EndUnknown,
+ ElementContext,
+ UnknownContext
+};
+
+class CallData
+{
+ sal_uInt32 m_nLevel;
+ CallDataType m_eType;
+ sal_Int32 m_nElement;
+ css::uno::Reference<css::xml::sax::XFastAttributeList> m_aAttributes;
+
+ //char
+ ::rtl::OUString m_aChars;
+
+ //unknwon
+ ::rtl::OUString m_sNameSpace;
+ ::rtl::OUString m_sElement;
+
+public:
+ //Start unknown element or context
+ CallData(sal_uInt32 nLevel, const ::rtl::OUString& rNameSpace, const ::rtl::OUString& rElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& rAttributes,
+ CallDataType eType)
+ : m_nLevel(nLevel)
+ , m_eType(eType)
+ , m_aAttributes(new sax_fastparser::FastAttributeList(rAttributes))
+ , m_sNameSpace(rNameSpace)
+ , m_sElement(rElement)
+ {
+ }
+
+ //end unknown element
+ CallData(sal_uInt32 nLevel, const ::rtl::OUString& rNameSpace, const ::rtl::OUString& rElement)
+ : m_nLevel(nLevel)
+ , m_eType(CallDataType::EndUnknown)
+ , m_sNameSpace(rNameSpace)
+ , m_sElement(rElement)
+ {
+ }
+
+ // start fast element
+ CallData(sal_uInt32 nLevel, sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& rAttributes,
+ CallDataType eType)
+ : m_nLevel(nLevel)
+ , m_eType(eType)
+ , m_nElement(nElement)
+ , m_aAttributes(new sax_fastparser::FastAttributeList(rAttributes))
+ {
+ }
+
+ // end fast element
+ CallData(sal_uInt32 nLevel, sal_Int32 nElement)
+ : m_nLevel(nLevel)
+ , m_eType(CallDataType::EndElementAttr)
+ , m_nElement(nElement)
+ {
+ }
+
+ //chars
+ CallData(sal_uInt32 nLevel, const ::rtl::OUString& rChars)
+ : m_nLevel(nLevel)
+ , m_eType(CallDataType::Char)
+ , m_aChars(rChars)
+ {
+ }
+
+ CallData(CallData const&) = default;
+
+ sal_uInt32 getLevel() const { return m_nLevel; }
+ CallDataType getType() const { return m_eType; }
+ sal_Int32 getElement() const { return m_nElement; }
+ const ::rtl::OUString& getChars() { return m_aChars; }
+ css::uno::Reference<css::xml::sax::XFastAttributeList> getAttributes() const
+ {
+ return m_aAttributes;
+ }
+ const ::rtl::OUString& getUnknownNameSpace() const { return m_sNameSpace; }
+ const ::rtl::OUString& getUnknownElement() const { return m_sElement; }
+};
+class ShadowContext : public ::oox::core::ContextHandler_BASE
+{
+public:
+ explicit ShadowContext(::sal_Int32 Element,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& rAttribs);
+ virtual ~ShadowContext() override;
+
+ //XFastContextHandler
+ virtual void SAL_CALL startFastElement(
+ ::sal_Int32 Element,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& Attribs) override;
+ virtual void SAL_CALL startUnknownElement(
+ const ::rtl::OUString& Namespace, const ::rtl::OUString& Name,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& Attribs) override;
+ virtual void SAL_CALL endFastElement(::sal_Int32 Element) override;
+ virtual void SAL_CALL endUnknownElement(const ::rtl::OUString& Namespace,
+ const ::rtl::OUString& Name) override;
+ virtual ::css::uno::Reference<::css::xml::sax::XFastContextHandler>
+ SAL_CALL createFastChildContext(
+ ::sal_Int32 Element,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& Attribs) override;
+ virtual ::css::uno::Reference<::css::xml::sax::XFastContextHandler>
+ SAL_CALL createUnknownChildContext(
+ const ::rtl::OUString& Namespace, const ::rtl::OUString& Name,
+ const ::css::uno::Reference<::css::xml::sax::XFastAttributeList>& Attribs) override;
+ virtual void SAL_CALL characters(const ::rtl::OUString& aChars) override;
+
+ sal_uInt16 getElementLevel() const { return m_nElementLevel; }
+ bool isWriterFrame() const { return m_bImportAsWriterFrame; }
+
+ std::deque<CallData>& getCallData() { return m_aCallDataDeque; }
+
+private:
+ std::deque<CallData> m_aCallDataDeque;
+ sal_uInt16 m_nElementLevel;
+ bool m_bImportAsWriterFrame;
+};
+}