package/source/xstor/owriteablestream.cxx | 4 sw/qa/extras/ooxmlexport/data/testGlossary.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 8 + sw/source/filter/ww8/docxexport.cxx | 76 +++++++++++++++ sw/source/filter/ww8/docxexport.hxx | 2 writerfilter/inc/ooxml/OOXMLDocument.hxx | 6 - writerfilter/source/filter/ImportFilter.cxx | 8 + writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 116 ++++++++++++++++++++++++ writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 6 + writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 8 + 10 files changed, 229 insertions(+), 5 deletions(-)
New commits: commit 88b9e7f391910e534b0faf7378ec4c6929d4d44a Author: Rohit Deshmukh <rohit.deshm...@synerzip.com> Date: Wed Nov 27 13:53:12 2013 +0530 fdo#71786 : Implemented Glossary folder 1. Glosary folder is imported as Intrograb and exported. 2. Added unit test case Reviewed on: https://gerrit.libreoffice.org/6825 Conflicts: sw/qa/extras/ooxmlexport/ooxmlexport.cxx writerfilter/source/filter/ImportFilter.cxx Change-Id: Ifd51a75a65e030d44d30e02cd7ab51fb088186b3 diff --git a/package/source/xstor/owriteablestream.cxx b/package/source/xstor/owriteablestream.cxx index 9d987a5..bc7086e 100644 --- a/package/source/xstor/owriteablestream.cxx +++ b/package/source/xstor/owriteablestream.cxx @@ -3104,6 +3104,10 @@ void SAL_CALL OWriteStream::setPropertyValue( const OUString& aPropertyName, con else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE && ( aPropertyName == "IsEncrypted" || aPropertyName == "Encrypted" ) ) throw beans::PropertyVetoException(); // TODO + else if ( aPropertyName == "RelId" ) + { + aValue >>= m_pImpl->m_nRelId; + } else throw beans::UnknownPropertyException(); // TODO diff --git a/sw/qa/extras/ooxmlexport/data/testGlossary.docx b/sw/qa/extras/ooxmlexport/data/testGlossary.docx new file mode 100644 index 0000000..eb05758 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/testGlossary.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 7267838..a7e28cf 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -2115,6 +2115,14 @@ DECLARE_OOXMLEXPORT_TEST(testcolumnbreak, "columnbreak.docx") assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:r[1]/w:br", "type", "column"); } +DECLARE_OOXMLEXPORT_TEST(testGlossary, "testGlossary.docx") +{ + xmlDocPtr pXmlDoc = parseExport("word/glossary/document.xml"); + if (!pXmlDoc) + return; + assertXPath(pXmlDoc, "/w:glossaryDocument", "Ignorable", "w14 wp14"); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 6c7a66b..2edcf56 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -64,7 +64,7 @@ #include "ww8par.hxx" #include "ww8scan.hxx" - +#include <oox/token/properties.hxx> #include <comphelper/string.hxx> #include <rtl/ustrbuf.hxx> #include <vcl/font.hxx> @@ -361,6 +361,8 @@ void DocxExport::ExportDocument_Impl() WriteTheme(); + WriteGlossary(); + WriteCustomXml(); WriteActiveX(); @@ -831,6 +833,78 @@ void DocxExport::WriteTheme() uno::Sequence< beans::StringPair >() ); } +void DocxExport::WriteGlossary() +{ + uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW ); + + uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); + OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG; + if ( !xPropSetInfo->hasPropertyByName( pName ) ) + return; + + uno::Reference<xml::dom::XDocument> glossaryDocDom; + uno::Sequence< uno::Sequence< uno::Any> > glossaryDomList; + uno::Sequence< beans::PropertyValue > propList; + xPropSet->getPropertyValue( pName ) >>= propList; + sal_Int32 collectedProperties = 0; + for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp ) + { + OUString propName = propList[nProp].Name; + if ( propName == "OOXGlossary" ) + { + propList[nProp].Value >>= glossaryDocDom; + collectedProperties++; + } + if (propName == "OOXGlossaryDom") + { + propList[nProp].Value >>= glossaryDomList; + collectedProperties++; + } + if (collectedProperties == 2) + break; + } + + // no glossary dom to write + if ( !glossaryDocDom.is() ) + return; + + m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/glossaryDocument", + "glossary/document.xml" ); + + uno::Reference< io::XOutputStream > xOutputStream = GetFilter().openFragmentStream( "word/glossary/document.xml", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml" ); + + uno::Reference< xml::sax::XSAXSerializable > serializer( glossaryDocDom, uno::UNO_QUERY ); + uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() ); + writer->setOutputStream( xOutputStream ); + serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ), + uno::Sequence< beans::StringPair >() ); + + + sal_Int32 length = glossaryDomList.getLength(); + for ( int i =0; i < length; i++) + { + uno::Sequence< uno::Any> glossaryElement = glossaryDomList[i]; + OUString gTarget, gType, gId, contentType; + uno::Reference<xml::dom::XDocument> xDom; + glossaryElement[0] >>= xDom; + glossaryElement[1] >>= gId; + glossaryElement[2] >>= gType; + glossaryElement[3] >>= gTarget; + glossaryElement[4] >>= contentType; + gId = gId.copy(3); //"rId" only save the numeric value + + PropertySet aProps(xOutputStream); + aProps.setAnyProperty( PROP_RelId, uno::makeAny( sal_Int32( gId.toInt32() ))); + m_pFilter->addRelation( xOutputStream, gType, gTarget); + uno::Reference< xml::sax::XSAXSerializable > gserializer( xDom, uno::UNO_QUERY ); + writer->setOutputStream(GetFilter().openFragmentStream( "word/glossary/" + gTarget, contentType ) ); + gserializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ), + uno::Sequence< beans::StringPair >() ); + } +} + void DocxExport::WriteCustomXml() { uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW ); diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx index 1eb75c2..cac754e 100644 --- a/sw/source/filter/ww8/docxexport.hxx +++ b/sw/source/filter/ww8/docxexport.hxx @@ -210,6 +210,8 @@ private: /// Write word/theme/theme1.xml void WriteTheme(); + void WriteGlossary(); + /// Write customXml/item[n].xml and customXml/itemProps[n].xml void WriteCustomXml(); diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index 97bb876..13f365e 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -75,8 +75,8 @@ using namespace com::sun::star; class WRITERFILTER_OOXML_DLLPUBLIC OOXMLStream { public: - enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, FONTTABLE, NUMBERING, - FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, SETTINGS, VBAPROJECT }; + enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, WEBSETTINGS, FONTTABLE, NUMBERING, + FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, GLOSSARY, SETTINGS, VBAPROJECT }; typedef boost::shared_ptr<OOXMLStream> Pointer_t; virtual ~OOXMLStream() {} @@ -242,6 +242,8 @@ public: virtual void setShapeContext( uno::Reference<xml::sax::XFastShapeContextHandler> xContext ) = 0; virtual uno::Reference<xml::dom::XDocument> getThemeDom( ) = 0; virtual void setThemeDom( uno::Reference<xml::dom::XDocument> xThemeDom ) = 0; + virtual uno::Reference<xml::dom::XDocument> getGlossaryDocDom( ) = 0; + virtual uno::Sequence<uno::Sequence< uno::Any> > getGlossaryDomList() = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList( ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList( ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList( ) = 0; diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index 2854088..843e37a 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -120,7 +120,7 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes pDocument->resolve(*pStream); // Adding some properties to the document's grab bag for interoperability purposes: - uno::Sequence<beans::PropertyValue> aGrabBagProperties(6); + uno::Sequence<beans::PropertyValue> aGrabBagProperties(8); // Adding the saved Theme DOM aGrabBagProperties[0].Name = "OOXTheme"; @@ -142,6 +142,12 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes aGrabBagProperties[5].Name = "ThemeFontLangProps"; aGrabBagProperties[5].Value = uno::makeAny( aDomainMapper->GetThemeFontLangProperties() ); + // Adding the saved Glossary Documnet DOM to the document's grab bag + aGrabBagProperties[6].Name = "OOXGlossary"; + aGrabBagProperties[6].Value = uno::makeAny( pDocument->getGlossaryDocDom() ); + aGrabBagProperties[7].Name = "OOXGlossaryDom"; + aGrabBagProperties[7].Value = uno::makeAny( pDocument->getGlossaryDomList() ); + putPropertiesToDocumentGrabBag( aGrabBagProperties ); writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream( pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT )); diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index f272375..2f5f280 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -438,6 +438,9 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) resolveFastSubStream(rStream, OOXMLStream::SETTINGS); mxThemeDom = importSubStream(OOXMLStream::THEME); resolveFastSubStream(rStream, OOXMLStream::THEME); + mxGlossaryDocDom = importSubStream(OOXMLStream::GLOSSARY); + if (mxGlossaryDocDom.is()) + resolveGlossaryStream(rStream); // Custom xml's are handled as part of grab bag. resolveCustomXmlStream(rStream); @@ -523,6 +526,109 @@ void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream) } } +void OOXMLDocumentImpl::resolveGlossaryStream(Stream & /*rStream*/) +{ + static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"); + static OUString sStylesWithEffects("http://schemas.microsoft.com/office/2007/relationships/stylesWithEffects"); + static OUString sStylesType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"); + static OUString sFonttableType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"); + static OUString sWebSettings("http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings"); + + OOXMLStream::Pointer_t pStream; + try + { + pStream = OOXMLDocumentFactory::createStream(mpStream, OOXMLStream::GLOSSARY); + } + catch (uno::Exception const& e) + { + SAL_INFO("writerfilter", "resolveGlossaryStream: exception while " + "createStream for glossary" << OOXMLStream::GLOSSARY << " : " << e.Message); + return; + } + uno::Reference<embed::XRelationshipAccess> mxRelationshipAccess; + mxRelationshipAccess.set((*dynamic_cast<OOXMLStreamImpl *>(pStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW); + if (mxRelationshipAccess.is()) + { + + uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = + mxRelationshipAccess->getAllRelationships(); + uno::Sequence<uno::Sequence< uno::Any> > mxGlossaryDomListTemp(aSeqs.getLength()); + sal_Int32 counter = 0; + for (sal_Int32 j = 0; j < aSeqs.getLength(); j++) + { + OOXMLStream::Pointer_t gStream; + uno::Sequence< beans::StringPair > aSeq = aSeqs[j]; + //Follows following aSeq[0] is Id, aSeq[1] is Type, aSeq[2] is Target + OUString gId(aSeq[0].Second); + OUString gType(aSeq[1].Second); + OUString gTarget(aSeq[2].Second); + OUString contentType; + + OOXMLStream::StreamType_t nType; + bool bFound = true; + if(gType.compareTo(sSettingsType) == 0) + { + nType = OOXMLStream::SETTINGS; + contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"; + } + else if(gType.compareTo(sStylesType) == 0) + { + nType = OOXMLStream::STYLES; + contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"; + } + else if(gType.compareTo(sWebSettings) == 0) + { + nType = OOXMLStream::WEBSETTINGS; + contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"; + } + else if(gType.compareTo(sFonttableType) == 0) + { + nType = OOXMLStream::FONTTABLE; + contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"; + } + else + { + bFound = false; + //"Unhandled content-type while grab bagging Glossary Folder"); + } + + if (bFound) + { + uno::Reference<xml::dom::XDocument> xDom; + try + { + gStream = OOXMLDocumentFactory::createStream(pStream, nType); + uno::Reference<io::XInputStream> xInputStream = gStream->getDocumentStream(); + uno::Reference<uno::XComponentContext> xContext(pStream->getContext()); + uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xContext)); + xDom = xDomBuilder->parse(xInputStream); + } + catch (uno::Exception const& e) + { + SAL_INFO("writerfilter glossary grab bag", "importSubStream: exception while " + "parsing stream of Type" << nType << " : " << e.Message); + return; + } + + if (xDom.is()) + { + uno::Sequence< uno::Any > glossaryTuple (5); + glossaryTuple[0] = uno::makeAny(xDom); + glossaryTuple[1] = uno::makeAny(gId); + glossaryTuple[2] = uno::makeAny(gType); + glossaryTuple[3] = uno::makeAny(gTarget); + glossaryTuple[4] = uno::makeAny(contentType); + mxGlossaryDomListTemp[counter] = glossaryTuple; + counter++; + } + } + } + mxGlossaryDomListTemp.realloc(counter); + mxGlossaryDomList = mxGlossaryDomListTemp; + } +} + + void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) { // Resolving all ActiveX[n].xml files from ActiveX folder. @@ -579,6 +685,16 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) } } +uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::getGlossaryDocDom( ) +{ + return mxGlossaryDocDom; +} + +uno::Sequence<uno::Sequence< uno::Any> > OOXMLDocumentImpl::getGlossaryDomList() +{ + return mxGlossaryDomList; +} + uno::Reference<io::XInputStream> OOXMLDocumentImpl::getInputStreamForId(const OUString & rId) { OOXMLStream::Pointer_t pStream(OOXMLDocumentFactory::createStream(mpStream, rId)); diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index d7506ce..ae4d695 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -40,6 +40,8 @@ class OOXMLDocumentImpl : public OOXMLDocument uno::Reference<frame::XModel> mxModel; uno::Reference<drawing::XDrawPage> mxDrawPage; + uno::Reference<xml::dom::XDocument> mxGlossaryDocDom; + uno::Sequence < uno::Sequence< uno::Any > > mxGlossaryDomList; uno::Reference<xml::sax::XFastShapeContextHandler> mxShapeContext; uno::Reference<xml::dom::XDocument> mxThemeDom; uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomList; @@ -73,7 +75,7 @@ protected: void setIsSubstream( bool bSubstream ) { mbIsSubstream = bSubstream; }; void resolveCustomXmlStream(Stream & rStream); void resolveActiveXStream(Stream & rStream); - + void resolveGlossaryStream(Stream & rStream); public: OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream); virtual ~OOXMLDocumentImpl(); @@ -123,6 +125,8 @@ public: virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList(); virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList(); virtual uno::Sequence<uno::Reference<io::XInputStream> > getActiveXBinList(); + virtual uno::Reference<xml::dom::XDocument> getGlossaryDocDom(); + virtual uno::Sequence<uno::Sequence< uno::Any> > getGlossaryDomList(); }; }} #endif // OOXML_DOCUMENT_IMPL_HXX diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx index dd68754..c119cfb 100644 --- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx @@ -114,6 +114,8 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> static OUString sCustomPropsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps"); static OUString sActiveXType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/control"); static OUString sActiveXBinType("http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"); + static OUString sGlossaryType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/glossaryDocument"); + static OUString sWebSettings("http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings"); static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"); static OUString sTarget("Target"); static OUString sTargetMode("TargetMode"); @@ -166,6 +168,12 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> case SETTINGS: sStreamType = sSettingsType; break; + case GLOSSARY: + sStreamType = sGlossaryType; + break; + case WEBSETTINGS: + sStreamType = sWebSettings; + break; default: break; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits