tdf#83671 SmartArt: preserve pos and size for metafile
Import of a SmartArt creates a group with a background shape and then
the SmartArt shapes. The background shape determines the position and
size of the group.
The method Shape::convertSmartArtToMetafile() replaces the existing
SmartArt shapes with a metafile object and thereby throws away the
background shape. Thus the group takes it size from the metafile object,
which has default size 100x100 (Hmm) and position 0|0.
The patch remembers the original size and position from the background
shape and applies it then to the metafile shape.
Change-Id: Id7b1ccd20b2597c5e2adca7294a994fd2e0e066f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141830
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index e43b6b9..7357e36 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1966,9 +1966,16 @@ void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase)
// from them
Reference<XShape> xShape(renderDiagramToGraphic(rFilterBase));
Reference<XShapes> xShapes(mxShape, UNO_QUERY_THROW);
tools::Rectangle aBackgroundRect
= SdrObject::getSdrObjectFromXShape(
Reference<XShape>(xShapes->getByIndex(0), UNO_QUERY_THROW))
->GetLogicRect();
while (xShapes->hasElements())
xShapes->remove(Reference<XShape>(xShapes->getByIndex(0), UNO_QUERY_THROW));
xShapes->add(xShape);
SdrObject::getSdrObjectFromXShape(
Reference<XShape>(xShapes->getByIndex(0), UNO_QUERY_THROW))
->NbcSetLogicRect(aBackgroundRect);
}
catch (const Exception&)
{
diff --git a/sc/qa/unit/subsequent_filters_test2.cxx b/sc/qa/unit/subsequent_filters_test2.cxx
index 1ce547a..8ae23af 100644
--- a/sc/qa/unit/subsequent_filters_test2.cxx
+++ b/sc/qa/unit/subsequent_filters_test2.cxx
@@ -187,6 +187,7 @@ public:
void testInvalidBareBiff5();
void testTooManyColsRows();
void testTdf83671_SmartArt_import();
void testTdf83671_SmartArt_import2();
CPPUNIT_TEST_SUITE(ScFiltersTest2);
@@ -304,6 +305,7 @@ public:
CPPUNIT_TEST(testInvalidBareBiff5);
CPPUNIT_TEST(testTooManyColsRows);
CPPUNIT_TEST(testTdf83671_SmartArt_import);
CPPUNIT_TEST(testTdf83671_SmartArt_import2);
CPPUNIT_TEST_SUITE_END();
};
@@ -3089,6 +3091,52 @@ void ScFiltersTest2::testTdf83671_SmartArt_import()
xDocSh->DoClose();
}
void ScFiltersTest2::testTdf83671_SmartArt_import2()
{
// The example doc contains a diagram (SmartArt). Such should be imported as group object.
// With conversion enabled, the group contains only a graphic. Error was, that the shape
// had size 100x100 Hmm and position 0|0.
// Make sure SmartArt is loaded with converting to metafile
bool bUseGroup = officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::get();
if (bUseGroup)
{
std::shared_ptr<comphelper::ConfigurationChanges> pChange(
comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::set(false, pChange);
pChange->commit();
}
// Get document and shape
ScDocShellRef xDocSh = loadDoc(u"tdf83671_SmartArt_import.", FORMAT_XLSX);
ScDocument& rDoc = xDocSh->GetDocument();
ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
SdrPage* pPage = pDrawLayer->GetPage(0);
SdrObject* pObj = pPage->GetObj(0);
// Check that it is a group shape with 1 child
CPPUNIT_ASSERT(pObj->IsGroupObject());
SdrObjList* pChildren = pObj->getChildrenOfSdrObject();
CPPUNIT_ASSERT_EQUAL(size_t(1), pChildren->GetObjCount());
// The child shape should have about 60mm x 42mm size and position 1164|1270.
// Without fix its size was 100x100 and position 0|0.
tools::Rectangle aBackground = pChildren->GetObj(0)->GetLogicRect();
CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(6000), aBackground.getOpenWidth(), 10);
CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(4200), aBackground.getOpenHeight(), 10);
CPPUNIT_ASSERT_EQUAL(Point(1164, 1270), aBackground.GetPos());
if (bUseGroup)
{
std::shared_ptr<comphelper::ConfigurationChanges> pChange(
comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::set(true, pChange);
pChange->commit();
}
xDocSh->DoClose();
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest2);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/subsequent_setup.mk b/sc/subsequent_setup.mk
index 5e649e5..5c9b092 100644
--- a/sc/subsequent_setup.mk
+++ b/sc/subsequent_setup.mk
@@ -104,6 +104,7 @@ $(eval $(call gb_CppunitTest_use_components,sc_subsequent_$(1),\
svl/util/svl \
svl/source/fsstor/fsstorage \
svtools/util/svt \
svx/util/svxcore \
toolkit/util/tk \
ucb/source/core/ucb1 \
ucb/source/ucp/file/ucpfile1 \