From 290f03e8bb5071d7716fb6563e3274caa51102f0 Mon Sep 17 00:00:00 2001 From: Andres Gomez Date: Fri, 13 Sep 2013 18:18:39 +0300 Subject: writerfilter: OOXML theme saved in InteropGrabBag The XDocuments representing the DOM of an OOXML's theme document is now stored as the PropertyValue "OOXTheme" into the "InteropGraBag" property of the SwXTextDocument. Added the importSubStream() method to the writerfilter::ooxml::OOXMLDocumentImpl class in order to create the XDocument for the theme XML fragment stream and invoked it during the resolve() method. Modified the writerfilter::ooxml::OOXMLDocument abstract class to be able to hold the OOXML's theme XDocument. Added the set/getTheme() methods to store and obtain the XDocument directly. Modified the WriterFilter::filter() method to store the OOXML's theme XDocument in the "InteropGrabBag" property of the TextDocument service SwXTextDocument implementation. Updated the UTs accordingly. Change-Id: I3960590fcf4856caf770908b983ffb6898f061c0 Reviewed-on: https://gerrit.libreoffice.org/6002 Reviewed-by: Miklos Vajna Tested-by: Miklos Vajna --- sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 20 +++++++++- writerfilter/inc/ooxml/OOXMLDocument.hxx | 3 ++ writerfilter/source/filter/ImportFilter.cxx | 33 ++++++++++++++++ writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 52 ++++++++++++++++++++++++- writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 7 ++++ 5 files changed, 113 insertions(+), 2 deletions(-) diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 9a0a10cbe805..a76086552101 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -539,6 +539,25 @@ void Test::testN764005() void Test::testSmartart() { + uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY); + uno::Sequence aGrabBag(0); + xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag; + CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty + + sal_Bool bTheme = sal_False; + for(int i = 0; i < aGrabBag.getLength(); ++i) + { + if (aGrabBag[i].Name == OUString("OOXTheme")) + { + bTheme = sal_True; + uno::Reference aThemeDom; + CPPUNIT_ASSERT(aGrabBag[i].Value >>= aThemeDom); // PropertyValue of proper type + CPPUNIT_ASSERT(aThemeDom.get()); // Reference not empty + } + } + CPPUNIT_ASSERT(bTheme); // Grab Bag has all the expected elements + uno::Reference xDrawPageSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDraws->getCount()); // One groupshape in the doc @@ -547,7 +566,6 @@ void Test::testSmartart() CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xGroup->getCount()); // 3 rectangles and an arrow in the group uno::Reference xGroupPropertySet(getShape(1), uno::UNO_QUERY); - uno::Sequence aGrabBag(0); xGroupPropertySet->getPropertyValue(OUString::createFromAscii("InteropGrabBag")) >>= aGrabBag; CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index c97e2b2b08c0..1f4930b692e3 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -239,6 +240,8 @@ public: virtual const OUString & getTarget() const = 0; virtual uno::Reference getShapeContext( ) = 0; virtual void setShapeContext( uno::Reference xContext ) = 0; + virtual uno::Reference getThemeDom( ) = 0; + virtual void setThemeDom( uno::Reference xThemeDom ) = 0; }; diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index e56cbca4dff6..df5604b74a77 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -116,6 +116,39 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes pDocument->setDrawPage(xDrawPage); pDocument->resolve(*pStream); + + // Adding the saved Theme DOM to the document's grab bag + try + { + uno::Reference xDocProps(m_xDstDoc, uno::UNO_QUERY); + if (xDocProps.is()) + { + uno::Reference xPropsInfo = xDocProps->getPropertySetInfo(); + + const OUString& aGrabBagPropName = OUString("InteropGrabBag"); + if( xPropsInfo.is() && xPropsInfo->hasPropertyByName( aGrabBagPropName ) ) + { + uno::Sequence aGrabBag; + + // We want to keep the previous items + xDocProps->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; + sal_Int32 length = aGrabBag.getLength(); + aGrabBag.realloc(length+1); + + uno::Reference aThemeDom = pDocument->getThemeDom(); + + beans::PropertyValue* pValue = aGrabBag.getArray(); + pValue[length].Name = OUString("OOXTheme"); + pValue[length].Value = uno::makeAny( aThemeDom ); + + xDocProps->setPropertyValue( aGrabBagPropName, uno::Any( aGrabBag ) ); + } + } + } + catch(const uno::Exception&) + { + } + writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream( pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT )); oox::StorageRef xVbaPrjStrg( new ::oox::ole::OleStorage( m_xContext, pVBAProjectStream->getDocumentStream(), false ) ); if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() ) diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index b64c28a10e4c..c77cebbad70c 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -20,6 +20,7 @@ #include #include +#include #include #include #include "OOXMLDocumentImpl.hxx" @@ -43,7 +44,7 @@ using namespace ::std; OOXMLDocumentImpl::OOXMLDocumentImpl (OOXMLStream::Pointer_t pStream) -: mpStream(pStream), mXNoteType(0), mbIsSubstream( false ) +: mpStream(pStream), mXNoteType(0), mxThemeDom(0), mbIsSubstream( false ) { } @@ -109,6 +110,44 @@ void OOXMLDocumentImpl::resolveFastSubStreamWithId(Stream & rStream, rStream.substream(nId, pStream); } +uno::Reference OOXMLDocumentImpl::importSubStream(OOXMLStream::StreamType_t nType) +{ + uno::Reference xRet; + + OOXMLStream::Pointer_t pStream; + try + { + pStream = OOXMLDocumentFactory::createStream(mpStream, nType); + } + catch (uno::Exception const& e) + { + SAL_INFO("writerfilter", "importSubStream: exception while " + "importing stream " << nType << " : " << e.Message); + return xRet; + } + + uno::Reference xInputStream = + pStream->getDocumentStream(); + + if (xInputStream.is()) + { + try + { + uno::Reference xContext(mpStream->getContext()); + uno::Reference xDomBuilder(xml::dom::DocumentBuilder::create(xContext)); + xRet = xDomBuilder->parse(xInputStream); + } + catch (uno::Exception const& e) + { + SAL_INFO("writerfilter", "importSubStream: exception while " + "parsing stream " << nType << " : " << e.Message); + return xRet; + } + } + + return xRet; +} + void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId) { mnXNoteId = nId; @@ -333,6 +372,7 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) (mpStream->getFastTokenHandler(xContext)); resolveFastSubStream(rStream, OOXMLStream::SETTINGS); + mxThemeDom = importSubStream(OOXMLStream::THEME); resolveFastSubStream(rStream, OOXMLStream::THEME); resolveFastSubStream(rStream, OOXMLStream::FONTTABLE); resolveFastSubStream(rStream, OOXMLStream::STYLES); @@ -411,6 +451,16 @@ uno::Reference OOXMLDocumentImpl::getShapeCo return mxShapeContext; } +void OOXMLDocumentImpl::setThemeDom( uno::Reference xThemeDom ) +{ + mxThemeDom = xThemeDom; +} + +uno::Reference OOXMLDocumentImpl::getThemeDom( ) +{ + return mxThemeDom; +} + OOXMLDocument * OOXMLDocumentFactory::createDocument (OOXMLStream::Pointer_t pStream) diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index f23725d64399..bf185041ea1a 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -22,6 +22,7 @@ #include #include +#include #include "OOXMLPropertySet.hxx" @@ -40,6 +41,7 @@ class OOXMLDocumentImpl : public OOXMLDocument uno::Reference mxModel; uno::Reference mxDrawPage; uno::Reference mxShapeContext; + uno::Reference mxThemeDom; bool mbIsSubstream; @@ -51,6 +53,8 @@ protected: writerfilter::Reference::Pointer_t pStream, sal_uInt32 nId); + uno::Reference importSubStream(OOXMLStream::StreamType_t nType); + writerfilter::Reference::Pointer_t getSubStream(const OUString & rId); @@ -104,6 +108,9 @@ public: virtual const OUString & getTarget() const; virtual uno::Reference getShapeContext( ); virtual void setShapeContext( uno::Reference xContext ); + virtual void setThemeDom(uno::Reference xThemeDom); + virtual uno::Reference getThemeDom(); + }; }} #endif // OOXML_DOCUMENT_IMPL_HXX -- cgit