From 8f79f22a8d4b1c2d209c55cd618c24428960088f Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Tue, 6 Mar 2018 22:43:34 -0500 Subject: oox: preserve the ContentType of custom files Generic logic to preserve custom files with their correct ContentType. Standard default file extensions with respective ContentType preserved in [Content_Types].xml. Change-Id: I651ed691e9a4745cd2cb4b3c4d4c5fd7287b66c2 Reviewed-on: https://gerrit.libreoffice.org/50856 Tested-by: Jenkins Reviewed-by: Jan Holesovsky --- oox/source/core/xmlfilterbase.cxx | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'oox/source') diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index b4836634ed2a..0388fae5f473 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -960,13 +961,6 @@ void XmlFilterBase::importCustomFragments(css::uno::Reference xRelations(xDocumentStorage, UNO_QUERY); if (xRelations.is()) { - // These are all the custom types we recognize and can preserve. - static const std::set sCustomTypes = { - "http://schemas.dell.com/ddp/2016/relationships/xenFile", - "http://schemas.dell.com/ddp/2016/relationships/hmacFile", - "http://schemas.dell.com/ddp/2016/relationships/metadataFile" - }; - uno::Sequence> aSeqs = xRelations->getAllRelationships(); std::vector aCustomFragments; @@ -986,7 +980,8 @@ void XmlFilterBase::importCustomFragments(css::uno::Reference> aCustomXmlDomPropsList; //FIXME: Ideally, we should get these the relations, but it seems that is not consistently set. // In some cases it's stored in the workbook relationships, which is unexpected. So we discover them directly. - for (int i = 1; i < 100; ++i) + for (int i = 1; ; ++i) { Reference xCustDoc = importFragment("customXml/item" + OUString::number(i) + ".xml"); Reference xCustDocProps = importFragment("customXml/itemProps" + OUString::number(i) + ".xml"); @@ -1025,6 +1020,14 @@ void XmlFilterBase::importCustomFragments(css::uno::Reference> aContentTypeInfo; + uno::Reference xInputStream = openInputStream("[Content_Types].xml"); + if (xInputStream.is()) + aContentTypeInfo = comphelper::OFOPXMLHelper::ReadContentTypeSequence(xInputStream, getComponentContext()); + + aGrabBagProperties["OOXContentTypes"] <<= aContentTypeInfo; + Reference xModel(getModel(), UNO_QUERY); oox::core::XmlFilterBase::putPropertiesToDocumentGrabBag(xModel, aGrabBagProperties); } @@ -1045,6 +1048,7 @@ void XmlFilterBase::exportCustomFragments() uno::Sequence customFragments; uno::Sequence customFragmentTypes; uno::Sequence customFragmentTargets; + uno::Sequence> aContentTypes; uno::Sequence propList; xPropSet->getPropertyValue(aName) >>= propList; @@ -1071,6 +1075,10 @@ void XmlFilterBase::exportCustomFragments() { propList[nProp].Value >>= customFragmentTargets; } + else if (propName == "OOXContentTypes") + { + propList[nProp].Value >>= aContentTypes; + } } // Expect customXmlDomPropslist.getLength() == customXmlDomlist.getLength(). @@ -1110,10 +1118,16 @@ void XmlFilterBase::exportCustomFragments() for (sal_Int32 j = 0; j < customFragments.getLength(); j++) { addRelation(customFragmentTypes[j], customFragmentTargets[j]); - Reference xOutStream = openOutputStream(customFragmentTargets[j]); + const OUString aFilename = customFragmentTargets[j]; + Reference xOutStream = openOutputStream(aFilename); xOutStream->writeBytes(customFragments[j]); - // BinaryXInputStream aInStrm(openOutputStream(customFragmentTargets[j]), true); - // aInStrm.copyToStream(xOutputStream); + uno::Reference xProps(xOutStream, uno::UNO_QUERY); + if (xProps.is()) + { + const OUString aType = comphelper::OFOPXMLHelper::GetContentTypeByName(aContentTypes, aFilename); + const OUString aContentType = (aType.getLength() ? aType : OUString("application/octet-stream")); + xProps->setPropertyValue("MediaType", uno::makeAny(aContentType)); + } } } -- cgit