Kaydet (Commit) 5d997c02 authored tarafından Miklos Vajna's avatar Miklos Vajna

sw XHTML export: improve dummy OLE object handling

It is possible that we not only have a dummy OLE object, but both the
replacement image and the native data is missing. Handle these enough so
that we don't give up exporting the document and also produce valid
output.

Change-Id: Ia973ecfbfb7e8fdecdc831b29d3a82c988ed7ea5
Reviewed-on: https://gerrit.libreoffice.org/59806Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins
üst 59a4804c
...@@ -35,6 +35,20 @@ public: ...@@ -35,6 +35,20 @@ public:
m_eUnit(FUNIT_NONE) m_eUnit(FUNIT_NONE)
{} {}
/**
* Wraps a reqif-xhtml fragment into an XHTML file, so an XML parser can
* parse it.
*/
void wrapFragment(SvMemoryStream& rStream)
{
rStream.WriteCharPtr(
"<reqif-xhtml:html xmlns:reqif-xhtml=\"http://www.w3.org/1999/xhtml\">\n");
SvFileStream aFileStream(maTempFile.GetURL(), StreamMode::READ);
rStream.WriteStream(aFileStream);
rStream.WriteCharPtr("</reqif-xhtml:html>\n");
rStream.Seek(0);
}
private: private:
bool mustCalcLayoutOf(const char* filename) override bool mustCalcLayoutOf(const char* filename) override
{ {
...@@ -603,11 +617,7 @@ DECLARE_HTMLEXPORT_TEST(testTransparentImage, "transparent-image.odt") ...@@ -603,11 +617,7 @@ DECLARE_HTMLEXPORT_TEST(testTransparentImage, "transparent-image.odt")
DECLARE_HTMLEXPORT_TEST(testTransparentImageReqIf, "transparent-image.odt") DECLARE_HTMLEXPORT_TEST(testTransparentImageReqIf, "transparent-image.odt")
{ {
SvMemoryStream aStream; SvMemoryStream aStream;
aStream.WriteCharPtr("<reqif-xhtml:html xmlns:reqif-xhtml=\"http://www.w3.org/1999/xhtml\">\n"); wrapFragment(aStream);
SvFileStream aFileStream(maTempFile.GetURL(), StreamMode::READ);
aStream.WriteStream(aFileStream);
aStream.WriteCharPtr("</reqif-xhtml:html>\n");
aStream.Seek(0);
xmlDocPtr pDoc = parseXmlStream(&aStream); xmlDocPtr pDoc = parseXmlStream(&aStream);
CPPUNIT_ASSERT(pDoc); CPPUNIT_ASSERT(pDoc);
...@@ -620,6 +630,22 @@ DECLARE_HTMLEXPORT_TEST(testTransparentImageReqIf, "transparent-image.odt") ...@@ -620,6 +630,22 @@ DECLARE_HTMLEXPORT_TEST(testTransparentImageReqIf, "transparent-image.odt")
CPPUNIT_ASSERT_MESSAGE(aMessage.toUtf8().getStr(), aSource.endsWith(".png")); CPPUNIT_ASSERT_MESSAGE(aMessage.toUtf8().getStr(), aSource.endsWith(".png"));
} }
DECLARE_HTMLEXPORT_TEST(testOleNodataReqIf, "reqif-ole-nodata.odt")
{
// This failed, io::IOException was thrown during the filter() call.
SvMemoryStream aStream;
wrapFragment(aStream);
xmlDocPtr pDoc = parseXmlStream(&aStream);
CPPUNIT_ASSERT(pDoc);
// Make sure the native <object> element has the required data attribute.
OUString aSource = getXPath(
pDoc,
"/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object/reqif-xhtml:object",
"data");
CPPUNIT_ASSERT(!aSource.isEmpty());
}
CPPUNIT_PLUGIN_IMPLEMENT(); CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/io/XActiveDataStreamer.hpp> #include <com/sun/star/io/XActiveDataStreamer.hpp>
#include <com/sun/star/io/IOException.hpp>
#include <com/sun/star/embed/XEmbedPersist2.hpp> #include <com/sun/star/embed/XEmbedPersist2.hpp>
#include <comphelper/embeddedobjectcontainer.hxx> #include <comphelper/embeddedobjectcontainer.hxx>
...@@ -74,6 +75,7 @@ ...@@ -74,6 +75,7 @@
#include <comphelper/propertysequence.hxx> #include <comphelper/propertysequence.hxx>
#include <filter/msfilter/msoleexp.hxx> #include <filter/msfilter/msoleexp.hxx>
#include <comphelper/fileurl.hxx> #include <comphelper/fileurl.hxx>
#include <osl/file.hxx>
using namespace com::sun::star; using namespace com::sun::star;
...@@ -130,6 +132,33 @@ const HtmlFrmOpts HTML_FRMOPTS_OLE_CSS1 = ...@@ -130,6 +132,33 @@ const HtmlFrmOpts HTML_FRMOPTS_OLE_CSS1 =
HtmlFrmOpts::SAlign | HtmlFrmOpts::SAlign |
HtmlFrmOpts::SSpace; HtmlFrmOpts::SSpace;
namespace
{
/**
* Calculates a filename for an image, provided the HTML file name, the image
* itself and a wanted extension.
*/
OUString lcl_CalculateFileName(const OUString* pOrigFileName, const Graphic& rGraphic,
const OUString& rExtension)
{
OUString aFileName;
if (pOrigFileName)
aFileName = *pOrigFileName;
INetURLObject aURL(aFileName);
OUString aName(aURL.getBase());
aName += "_";
aName += aURL.getExtension();
aName += "_";
aName += OUString::number(rGraphic.GetChecksum(), 16);
aURL.setBase(aName);
aURL.setExtension(rExtension);
aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
return aFileName;
}
}
void SwHTMLParser::SetFixSize( const Size& rPixSize, void SwHTMLParser::SetFixSize( const Size& rPixSize,
const Size& rTwipDfltSize, const Size& rTwipDfltSize,
bool bPrcWidth, bool bPrcHeight, bool bPrcWidth, bool bPrcHeight,
...@@ -1465,18 +1494,7 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame ...@@ -1465,18 +1494,7 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame
// Calculate the file name, which is meant to be the same as the // Calculate the file name, which is meant to be the same as the
// replacement image, just with a .ole extension. // replacement image, just with a .ole extension.
OUString aFileName; OUString aFileName = lcl_CalculateFileName(rHTMLWrt.GetOrigFileName(), aGraphic, "ole");
if (rHTMLWrt.GetOrigFileName())
aFileName = *rHTMLWrt.GetOrigFileName();
INetURLObject aURL(aFileName);
OUString aName(aURL.getBase());
aName += "_";
aName += aURL.getExtension();
aName += "_";
aName += OUString::number(aGraphic.GetChecksum(), 16);
aURL.setBase(aName);
aURL.setExtension("ole");
aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
// Write the data. // Write the data.
SwOLEObj& rOLEObj = pOLENd->GetOLEObj(); SwOLEObj& rOLEObj = pOLENd->GetOLEObj();
...@@ -1527,11 +1545,22 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame ...@@ -1527,11 +1545,22 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame
// Otherwise the native data is just a grab-bag: ODummyEmbeddedObject. // Otherwise the native data is just a grab-bag: ODummyEmbeddedObject.
OUString aStreamName = rOLEObj.GetCurrentPersistName(); OUString aStreamName = rOLEObj.GetCurrentPersistName();
uno::Reference<embed::XStorage> xStorage = pDocSh->GetStorage(); uno::Reference<embed::XStorage> xStorage = pDocSh->GetStorage();
uno::Reference<io::XStream> xInStream uno::Reference<io::XStream> xInStream;
= xStorage->openStreamElement(aStreamName, embed::ElementModes::READ); try
uno::Reference<io::XStream> xOutStream(new utl::OStreamWrapper(aOutStream)); {
comphelper::OStorageHelper::CopyInputToOutput(xInStream->getInputStream(), // Even the native data may be missing.
xOutStream->getOutputStream()); xInStream = xStorage->openStreamElement(aStreamName, embed::ElementModes::READ);
} catch (const uno::Exception& rException)
{
SAL_WARN("sw.html", "OutHTML_FrameFormatOLENodeGrf: failed to open stream element: " << rException);
}
if (xInStream.is())
{
uno::Reference<io::XStream> xOutStream(new utl::OStreamWrapper(aOutStream));
comphelper::OStorageHelper::CopyInputToOutput(xInStream->getInputStream(),
xOutStream->getOutputStream());
}
uno::Reference<beans::XPropertySet> xOutStreamProps(xInStream, uno::UNO_QUERY); uno::Reference<beans::XPropertySet> xOutStreamProps(xInStream, uno::UNO_QUERY);
if (xOutStreamProps.is()) if (xOutStreamProps.is())
xOutStreamProps->getPropertyValue("MediaType") >>= aFileType; xOutStreamProps->getPropertyValue("MediaType") >>= aFileType;
...@@ -1566,6 +1595,15 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame ...@@ -1566,6 +1595,15 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame
aFilterName = "PNG"; aFilterName = "PNG";
nFlags = XOutFlags::NONE; nFlags = XOutFlags::NONE;
aMimeType = "image/png"; aMimeType = "image/png";
if (aGraphic.GetType() == GraphicType::NONE)
{
// The OLE Object has no replacement image, write a stub.
aGraphicURL = lcl_CalculateFileName(rHTMLWrt.GetOrigFileName(), aGraphic, "png");
osl::File aFile(aGraphicURL);
aFile.open(osl_File_OpenFlag_Create);
aFile.close();
}
} }
ErrCode nErr = XOutBitmap::WriteGraphic( aGraphic, aGraphicURL, ErrCode nErr = XOutBitmap::WriteGraphic( aGraphic, aGraphicURL,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment