tdf#146803 tdf#146805 OOXML import: fix bodyPr at grouped shapes

Grouped text boxes (WPG) lost their alignment and spacing,
because the bodyPr tag what has the information for this,
processed after the textbox content, and applied to the XShape
which in case of group shape is not ready. To solve this, the
mentioned properties read for the shape member after copied
to the XShape when its ready, and than synced to the textbox.

Regression from commit 121cbc250b
"tdf#66039 DOCX: import textboxes (with tables, images etc.) in
group shapes".

Change-Id: Ifb5e8bde58613137441bec2e2b51bc67118dab40
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128854
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
Attila Bakos (NISZ)
2022-02-03 09:28:52 +01:00
committed by László Németh
parent 4a38ca4035
commit 65b09ef1c5
7 changed files with 139 additions and 1 deletions
+3
View File
@@ -205,6 +205,8 @@ public:
const Color& getFontRefColorForNodes() const { return maFontRefColorForNodes; }
void setLockedCanvas(bool bLockedCanvas);
bool getLockedCanvas() const { return mbLockedCanvas;}
void setWPGChild(bool bWPG);
bool isWPGChild() const { return mbWPGChild;}
void setWps(bool bWps);
bool getWps() const { return mbWps;}
void setTextBox(bool bTextBox);
@@ -360,6 +362,7 @@ private:
// we need separate flag because we don't want
// to propagate it when applying reference shape
bool mbLocked;
bool mbWPGChild; // Is this shape a child of a WPG shape?
bool mbLockedCanvas; ///< Is this shape part of a locked canvas?
bool mbWps; ///< Is this a wps shape?
bool mbTextBox; ///< This shape has a textbox.
+42
View File
@@ -134,6 +134,7 @@ Shape::Shape( const char* pServiceName, bool bDefaultHeight )
, mbHidden( false )
, mbHiddenMasterShape( false )
, mbLocked( false )
, mbWPGChild(false)
, mbLockedCanvas( false )
, mbWps( false )
, mbTextBox( false )
@@ -176,6 +177,7 @@ Shape::Shape( const ShapePtr& pSourceShape )
, mbHidden( pSourceShape->mbHidden )
, mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape )
, mbLocked( pSourceShape->mbLocked )
, mbWPGChild( pSourceShape->mbWPGChild )
, mbLockedCanvas( pSourceShape->mbLockedCanvas )
, mbWps( pSourceShape->mbWps )
, mbTextBox( pSourceShape->mbTextBox )
@@ -292,6 +294,41 @@ void Shape::addShape(
if ( xShapes.is() )
addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aMatrix );
if (isWPGChild() && xShape)
{
// This is a wps shape and it is the child of the WPG, now copy the
// the text body properties to the xshape.
Reference<XPropertySet> xChildWPSProperties(xShape, uno::UNO_QUERY);
if (getTextBody() && xChildWPSProperties)
{
xChildWPSProperties->setPropertyValue(
UNO_NAME_TEXT_VERTADJUST,
uno::Any(getTextBody()->getTextProperties().meVA));
xChildWPSProperties->setPropertyValue(
UNO_NAME_TEXT_LEFTDIST,
uno::Any(getTextBody()->getTextProperties().moInsets[0].has_value()
? *getTextBody()->getTextProperties().moInsets[0]
: 0));
xChildWPSProperties->setPropertyValue(
UNO_NAME_TEXT_UPPERDIST,
uno::Any(getTextBody()->getTextProperties().moInsets[1].has_value()
? *getTextBody()->getTextProperties().moInsets[1]
: 0));
xChildWPSProperties->setPropertyValue(
UNO_NAME_TEXT_RIGHTDIST,
uno::Any(getTextBody()->getTextProperties().moInsets[2].has_value()
? *getTextBody()->getTextProperties().moInsets[2]
: 0));
xChildWPSProperties->setPropertyValue(
UNO_NAME_TEXT_LOWERDIST,
uno::Any(getTextBody()->getTextProperties().moInsets[3].has_value()
? *getTextBody()->getTextProperties().moInsets[3]
: 0));
}
}
if( meFrameType == FRAMETYPE_DIAGRAM )
{
keepDiagramCompatibilityInfo();
@@ -332,6 +369,11 @@ void Shape::setLockedCanvas(bool bLockedCanvas)
mbLockedCanvas = bLockedCanvas;
}
void Shape::setWPGChild(bool bWPG)
{
mbWPGChild = bWPG;
}
void Shape::setWps(bool bWps)
{
mbWps = bWps;
+1 -1
View File
@@ -28,7 +28,7 @@ public:
const oox::drawingml::ShapePtr& getShape() const { return mpShape; }
const bool& isFullWPGSupport() { return m_bFullWPGSupport; };
const bool& isFullWPGSupport() const { return m_bFullWPGSupport; };
void setFullWPGSupport(const bool& rbUse) { m_bFullWPGSupport = rbUse; };
private:
+43
View File
@@ -8,6 +8,7 @@
*/
#include "WpsContext.hxx"
#include "WpgContext.hxx"
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <comphelper/sequenceashashmap.hxx>
@@ -24,6 +25,9 @@
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
#include <oox/drawingml/shape.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <drawingml/textbody.hxx>
#include <drawingml/textbodyproperties.hxx>
#include <optional>
@@ -39,6 +43,11 @@ WpsContext::WpsContext(ContextHandler2Helper const& rParent, uno::Reference<draw
{
if (mpShapePtr)
mpShapePtr->setWps(true);
if (const auto pParent = dynamic_cast<const WpgContext*>(&rParent))
m_bHasWPGParent = pParent->isFullWPGSupport();
else
m_bHasWPGParent = false;
}
WpsContext::~WpsContext() = default;
@@ -169,6 +178,40 @@ oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken
return this;
}
else if (m_bHasWPGParent && mpShapePtr)
{
// this WPS context has to be inside a WPG shape, so the <BodyPr> element
// cannot be applied to mxShape member, use mpShape instead, and after the
// the parent shape finished, apply it for its children.
mpShapePtr->setWPGChild(true);
oox::drawingml::TextBodyPtr pTextBody;
pTextBody.reset(new oox::drawingml::TextBody());
if (rAttribs.hasAttribute(XML_anchor))
{
drawing::TextVerticalAdjust eAdjust
= drawingml::GetTextVerticalAdjust(rAttribs.getToken(XML_anchor, XML_t));
pTextBody->getTextProperties().meVA = eAdjust;
}
sal_Int32 aInsets[] = { XML_lIns, XML_tIns, XML_rIns, XML_bIns };
for (int i = 0; i < 4; ++i)
{
if (rAttribs.hasAttribute(XML_lIns))
{
OptValue<OUString> oValue = rAttribs.getString(aInsets[i]);
if (oValue.has())
pTextBody->getTextProperties().moInsets[i]
= oox::drawingml::GetCoordinate(oValue.get());
else
// Defaults from the spec: left/right: 91440 EMU, top/bottom: 45720 EMU
pTextBody->getTextProperties().moInsets[i]
= (aInsets[i] == XML_lIns || aInsets[i] == XML_rIns) ? 254 : 127;
}
}
mpShapePtr->setTextBody(pTextBody);
}
break;
case XML_noAutofit:
case XML_spAutoFit:
+1
View File
@@ -36,6 +36,7 @@ public:
private:
css::uno::Reference<css::drawing::XShape> mxShape;
bool m_bHasWPGParent;
};
}
Binary file not shown.
@@ -12,6 +12,7 @@
#include <comphelper/scopeguard.hxx>
#include <officecfg/Office/Common.hxx>
#include <com/sun/star/drawing/XShapes.hpp>
#include <queue>
#include <swmodeltestbase.hxx>
@@ -193,6 +194,54 @@ DECLARE_OOXMLEXPORT_TEST(testTdf142407, "tdf142407.docx")
CPPUNIT_ASSERT_EQUAL( sal_Int16(36), nGridLines); // was 23, left large space before text.
}
DECLARE_OOXMLEXPORT_TEST(testWPGBodyPr, "WPGbodyPr.docx")
{
// Is load successful?
CPPUNIT_ASSERT(mxComponent);
// There are a WPG shape and a picture
CPPUNIT_ASSERT_EQUAL(2, getShapes());
// Get the WPG shape
uno::Reference<drawing::XShapes> xGroup(getShape(2), uno::UNO_QUERY);
// And the embed WPG
uno::Reference<drawing::XShapes> xEmbedGroup(xGroup->getByIndex(1), uno::UNO_QUERY);
// Get the properties of the shapes
uno::Reference<beans::XPropertySet> xOuterShape(xGroup->getByIndex(0), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xMiddleShape(xEmbedGroup->getByIndex(0), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xInnerShape(xEmbedGroup->getByIndex(1), uno::UNO_QUERY);
// Get the properties of the textboxes too
uno::Reference<beans::XPropertySet> xOuterTextBox(
xOuterShape->getPropertyValue("TextBoxContent"), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xMiddleTextBox(
xMiddleShape->getPropertyValue("TextBoxContent"), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xInnerTextBox(
xInnerShape->getPropertyValue("TextBoxContent"), uno::UNO_QUERY);
// Check the alignments
CPPUNIT_ASSERT_EQUAL(css::drawing::TextVerticalAdjust::TextVerticalAdjust_TOP,
xOuterTextBox->getPropertyValue("TextVerticalAdjust")
.get<css::drawing::TextVerticalAdjust>());
CPPUNIT_ASSERT_EQUAL(css::drawing::TextVerticalAdjust::TextVerticalAdjust_TOP,
xMiddleTextBox->getPropertyValue("TextVerticalAdjust")
.get<css::drawing::TextVerticalAdjust>());
CPPUNIT_ASSERT_EQUAL(css::drawing::TextVerticalAdjust::TextVerticalAdjust_CENTER,
xInnerTextBox->getPropertyValue("TextVerticalAdjust")
.get<css::drawing::TextVerticalAdjust>());
// Check the inset margins, all were 0 before the fix
CPPUNIT_ASSERT_EQUAL(sal_Int32(499),
xInnerShape->getPropertyValue("TextLowerDistance").get<sal_Int32>());
CPPUNIT_ASSERT_EQUAL(sal_Int32(499),
xInnerShape->getPropertyValue("TextUpperDistance").get<sal_Int32>());
CPPUNIT_ASSERT_EQUAL(sal_Int32(1000),
xInnerShape->getPropertyValue("TextLeftDistance").get<sal_Int32>());
CPPUNIT_ASSERT_EQUAL(sal_Int32(254),
xInnerShape->getPropertyValue("TextRightDistance").get<sal_Int32>());
}
DECLARE_OOXMLEXPORT_TEST(testTdf81507, "tdf81507.docx")
{
xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");