summaryrefslogtreecommitdiff
path: root/sw/qa
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-09-02 17:44:19 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-09-10 17:29:16 +0200
commit63d93f1b92f16ad5b90507d1f349abcbed1994d5 (patch)
treec71b51bcfee75e684dd8e4e7853519b7afb847cd /sw/qa
parent51c1b256daaf33f89419e662b51096a2baafdce7 (diff)
sw reqif-xhtml export, embedded objects: take OLE1 pres data from rtf if needed
Next to the native data of an embedded object, the presentation data / replacement is included at several layers: - the OLE2 container may have it - the OLE1 container may have it - the RTF container may have it - the PNG file next to the RTF container may have it Given that various consumers pick one of the above, we try to provide presentation data in all layers. We already had code to generate the OLE1 presentation data from the OLE2 container, but we gave up for OLE1 in case the OLE2 container didn't have it. This means that in case the RTF container is wrapped in a proper RTF file, Word refuses the edit the embedded object. Fix the problem by taking the presentation data from RTF for OLE1 purposes, in case it's missing from the OLE2 container. (cherry picked from commit 0d027abbc5609b096d2a954e77aa7354a55928ab) Change-Id: I158db1c87044a3895d0c64a6e5a5384686627d96
Diffstat (limited to 'sw/qa')
-rw-r--r--sw/qa/extras/htmlexport/data/no-ole2-pres-data.odtbin0 -> 25483 bytes
-rw-r--r--sw/qa/extras/htmlexport/htmlexport.cxx74
2 files changed, 69 insertions, 5 deletions
diff --git a/sw/qa/extras/htmlexport/data/no-ole2-pres-data.odt b/sw/qa/extras/htmlexport/data/no-ole2-pres-data.odt
new file mode 100644
index 000000000000..cd65a1755746
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/no-ole2-pres-data.odt
Binary files differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index ec08d491e64f..a0bb2b073070 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -64,6 +64,16 @@ public:
rStream.Seek(0);
}
+ /// Wraps an RTF fragment into a complete RTF file, so an RTF parser can handle it.
+ static void wrapRtfFragment(const OUString& rURL, SvMemoryStream& rStream)
+ {
+ SvFileStream aRtfStream(rURL, StreamMode::READ);
+ rStream.WriteOString("{\\rtf1");
+ rStream.WriteStream(aRtfStream);
+ rStream.WriteOString("}");
+ rStream.Seek(0);
+ }
+
private:
bool mustCalcLayoutOf(const char* filename) override
{
@@ -994,12 +1004,8 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOle1PDF)
OUString aRtfUrl = aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
// Parse the ole1 data out of that.
- SvFileStream aRtfStream(aRtfUrl, StreamMode::READ);
SvMemoryStream aRtf;
- aRtf.WriteOString("{\\rtf1");
- aRtf.WriteStream(aRtfStream);
- aRtf.WriteOString("}");
- aRtf.Seek(0);
+ HtmlExportTest::wrapRtfFragment(aRtfUrl, aRtf);
tools::SvRef<TestReqIfRtfReader> xReader(new TestReqIfRtfReader(aRtf));
CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
SvMemoryStream aOle1;
@@ -1134,6 +1140,64 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testUnderlineNone)
assertXPathNoAttribute(pXmlDoc, "//reqif-xhtml:div/reqif-xhtml:p", "style");
}
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOle1PresDataNoOle2)
+{
+ // Save to reqif-xhtml.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "no-ole2-pres-data.odt";
+ mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", {});
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aStoreProperties = {
+ comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")),
+ comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")),
+ };
+ xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
+
+ // Get the .ole path.
+ SvMemoryStream aStream;
+ HtmlExportTest::wrapFragment(maTempFile, aStream);
+ xmlDocUniquePtr pDoc = parseXmlStream(&aStream);
+ CPPUNIT_ASSERT(pDoc);
+ OUString aOlePath = getXPath(
+ pDoc, "/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object", "data");
+ OUString aOleSuffix(".ole");
+ CPPUNIT_ASSERT(aOlePath.endsWith(aOleSuffix));
+ INetURLObject aUrl(maTempFile.GetURL());
+ aUrl.setBase(aOlePath.copy(0, aOlePath.getLength() - aOleSuffix.getLength()));
+ aUrl.setExtension("ole");
+ OUString aRtfUrl = aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+
+ // Parse the ole1 data out of the RTF fragment.
+ SvMemoryStream aRtf;
+ HtmlExportTest::wrapRtfFragment(aRtfUrl, aRtf);
+ tools::SvRef<TestReqIfRtfReader> xReader(new TestReqIfRtfReader(aRtf));
+ CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
+ SvMemoryStream aOle1;
+ CPPUNIT_ASSERT(xReader->WriteObjectData(aOle1));
+ CPPUNIT_ASSERT(aOle1.Tell());
+
+ // Check the content of the ole1 data.
+ // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
+ aOle1.Seek(0);
+ sal_uInt32 nData;
+ aOle1.ReadUInt32(nData); // OLEVersion
+ aOle1.ReadUInt32(nData); // FormatID
+ aOle1.ReadUInt32(nData); // ClassName
+ aOle1.SeekRel(nData);
+ aOle1.ReadUInt32(nData); // TopicName
+ aOle1.SeekRel(nData);
+ aOle1.ReadUInt32(nData); // ItemName
+ aOle1.SeekRel(nData);
+ aOle1.ReadUInt32(nData); // NativeDataSize
+ aOle1.SeekRel(nData);
+
+ aOle1.ReadUInt32(nData); // OLEVersion for presentation data
+
+ // Without the accompanying fix in place, this test would have failed as there was no
+ // presentation data after the native data in the OLE1 container. The result was not editable in
+ // Word.
+ CPPUNIT_ASSERT(aOle1.good());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */