tdf#134987 convert DOCX to ODT: fix lost charts

Embedded charts of DOCX documents were lost or replaced
by images during conversion to native ODT format,
resulted by bad handling of XEmbedPersist objects in
EmbeddedObjectContainer.

Note: Add missing loext:external-data to ODF 1.3 schema
definition to fix ODF validation error in gerrit.

See commit 2054af83fe
(fdo#72520 : Added property to store external data path in chart)
and commit a49a9dab31
(fix one more ODF validation error).

Change-Id: I9edff9af3a79370ea447ffc6078da3520d0c6f63
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104104
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
Balazs Varga
2020-10-09 10:20:49 +02:00
committed by László Németh
parent 51f807841a
commit a41cf57c1e
4 changed files with 70 additions and 0 deletions

View File

@@ -931,6 +931,14 @@ bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed
}
OUString aTempName, aMediaType;
/* Do not create a new name for a removed object, in the pImpl->mpTempObjectContainer,
because the original m_aEntryName of xObj will be overwritten by InsertEmbeddedObject(),
so uno::Reference < embed::XEmbeddedObject >& xObj will misbehave in
EmbeddedObjectContainer::StoreAsChildren and SfxObjectShell::SaveCompletedChildren
and will throw an exception because of objects with the same names! */
if( !pImpl->mpTempObjectContainer->HasEmbeddedObject(aName) )
aTempName = aName;
pImpl->mpTempObjectContainer->InsertEmbeddedObject( xObj, aTempName );
uno::Reference < io::XInputStream > xStream = GetGraphicStream( xObj, &aMediaType );

View File

@@ -2472,4 +2472,13 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
</rng:optional>
</rng:define>
<!-- TODO no proposal -->
<rng:define name="style-chart-properties-attlist" combine="interleave">
<rng:optional>
<rng:attribute name="loext:external-data">
<rng:ref name="string"/>
</rng:attribute>
</rng:optional>
</rng:define>
</rng:grammar>

Binary file not shown.

View File

@@ -46,6 +46,7 @@
#include <comphelper/storagehelper.hxx>
#include <comphelper/fileformat.h>
#include <comphelper/propertysequence.hxx>
#include <comphelper/documentconstants.hxx>
#include <unotools/streamwrap.hxx>
#include <svl/PasswordHelper.hxx>
#include <comphelper/sequenceashashmap.hxx>
@@ -778,6 +779,58 @@ DECLARE_ODFEXPORT_TEST(testFdo58949, "fdo58949.docx")
CPPUNIT_ASSERT_EQUAL(3, nMatches);
}
DECLARE_ODFEXPORT_TEST(testTdf134987, "tdf134987.docx")
{
uno::Reference<text::XTextEmbeddedObjectsSupplier> xTEOSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XNameAccess> xAccess(xTEOSupplier->getEmbeddedObjects());
uno::Sequence<OUString> aSeq(xAccess->getElementNames());
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aSeq.getLength());
OUString aMediaType;
// checking first object (formula)
{
uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier(xAccess->getByName("1"), uno::UNO_QUERY);
uno::Reference<lang::XComponent> xObj(xEOSupplier->getEmbeddedObject());
CPPUNIT_ASSERT(xObj.is());
uno::Reference<document::XStorageBasedDocument> xSBDoc(xObj, uno::UNO_QUERY);
uno::Reference<embed::XStorage> xStorage(xSBDoc->getDocumentStorage());
CPPUNIT_ASSERT(xStorage.is());
uno::Reference< beans::XPropertySet > xStorProps(xStorage, uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(xStorProps->getPropertyValue("MediaType") >>= aMediaType);
CPPUNIT_ASSERT(aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII));
}
// checking second object (chart)
{
uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier(xAccess->getByName("2"), uno::UNO_QUERY);
uno::Reference<lang::XComponent> xObj(xEOSupplier->getEmbeddedObject());
CPPUNIT_ASSERT(xObj.is());
uno::Reference<document::XStorageBasedDocument> xSBDoc(xObj, uno::UNO_QUERY);
uno::Reference<embed::XStorage> xStorage(xSBDoc->getDocumentStorage());
CPPUNIT_ASSERT(xStorage.is());
uno::Reference< beans::XPropertySet > xStorProps(xStorage, uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(xStorProps->getPropertyValue("MediaType") >>= aMediaType);
CPPUNIT_ASSERT(aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII));
}
// checking third object (chart)
{
uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier(xAccess->getByName("3"), uno::UNO_QUERY);
uno::Reference<lang::XComponent> xObj(xEOSupplier->getEmbeddedObject());
CPPUNIT_ASSERT(xObj.is());
uno::Reference<document::XStorageBasedDocument> xSBDoc(xObj, uno::UNO_QUERY);
uno::Reference<embed::XStorage> xStorage(xSBDoc->getDocumentStorage());
CPPUNIT_ASSERT(xStorage.is());
uno::Reference< beans::XPropertySet > xStorProps(xStorage, uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(xStorProps->getPropertyValue("MediaType") >>= aMediaType);
CPPUNIT_ASSERT(aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII));
}
}
DECLARE_ODFEXPORT_TEST(testStylePageNumber, "ooo321_stylepagenumber.odt")
{
CPPUNIT_ASSERT_EQUAL(5, getPages());