tdf#119038 DOCX: fix FollowTextFlow handling
This fix also a clean-up for the following commits:
ad8857dab30e099a0cf6ec18d184a6c836b33317
(tdf#130120 DOCX: export o:allowincell)
14ad64270e4fbca3c24da6f55f260b1fb229556a
(tdf#129888 DOCX shape import: handle o:allowincell)
10f29d8bf05d44ca8bc11d34d1294ec17f8ac0f1
(tdf#87569 tdf#109411 DOCX import: fix shape anchor in tables)
where these patches ignored the option "Follow text flow"
and there was no possibility to switch this setting on GUI.
Now this is handled on GUI as well by replacing the
grab-bag with UNO property "IsFollowingTextFlow".
The tdf#119038 bug also fixed.
Note: Unit tests for the commits mentioned above were
modified for testing the new property, so new tests were
not added.
Change-Id: Ie35c6e280f8b33d8535ca4cd9749f110f9d592ee
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90753
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index e59b25a..abac561 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -98,10 +98,10 @@ DECLARE_OOXMLIMPORT_TEST(testTdf129888vml, "tdf129888vml.docx")
//to be calculated from the page frame instead of the table:
uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
sal_Int16 nValue;
xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
bool bValue;
xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf129888vml The line shape has bad place!",
text::RelOrientation::PAGE_FRAME, nValue);
false, bValue);
}
DECLARE_OOXMLIMPORT_TEST(testTdf129888dml, "tdf129888dml.docx")
@@ -112,18 +112,18 @@ DECLARE_OOXMLIMPORT_TEST(testTdf129888dml, "tdf129888dml.docx")
//to be calculated from the page frame instead of the table:
uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
sal_Int16 nValue;
xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
bool bValue;
xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf129888dml The shape has bad place!",
text::RelOrientation::PAGE_FRAME, nValue);
false, bValue);
}
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf130120, "tdf130120.docx")
{
//Text for exporting the allowincell attribute:
//Text for exporting the allowincell attribute:
xmlDocPtr p_XmlDoc = parseExport("word/document.xml");
assertXPath(p_XmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc/w:p/w:r/mc:AlternateContent/"
"mc:Choice/w:drawing/wp:anchor","layoutInCell","0");
"mc:Choice/w:drawing/wp:anchor", "layoutInCell", "0");
}
@@ -131,10 +131,10 @@ DECLARE_OOXMLEXPORT_TEST(testTdf87569v, "tdf87569_vml.docx")
{
//the original tdf87569 sample has vml shapes...
uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
sal_Int16 nValue;
xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
bool bValue;
xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf87569_vml: The Shape is not in the table!",
text::RelOrientation::FRAME, nValue);
true, bValue);
}
DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.docx")
@@ -249,10 +249,10 @@ DECLARE_OOXMLEXPORT_TEST(testTdf87569d, "tdf87569_drawingml.docx")
{
//if the original tdf87569 sample is upgraded it will have drawingml shapes...
uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
sal_Int16 nValue;
xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
bool bValue;
xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf87569_drawingml: The Shape is not in the table!",
text::RelOrientation::FRAME, nValue);
true, bValue);
}
DECLARE_OOXMLEXPORT_TEST(testTdf130610, "tdf130610_bold_in_2_styles.ott")
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index b59bb46..4f2550f 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -62,8 +62,8 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape)
pShape->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(),
uno::UNO_QUERY);
xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>());
xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>());
// Link FLY and DRAW formats, so it becomes a text box (needed for syncProperty calls).
uno::Reference<text::XTextFrame> xRealTextFrame(xTextFrame, uno::UNO_QUERY);
auto pTextFrame = dynamic_cast<SwXTextFrame*>(xRealTextFrame.get());
@@ -110,6 +110,8 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape)
syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::makeAny(xShape->getSize()));
uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
syncProperty(pShape, RES_FOLLOW_TEXT_FLOW, MID_FOLLOW_TEXT_FLOW,
xShapePropertySet->getPropertyValue(UNO_NAME_IS_FOLLOWING_TEXT_FLOW));
syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_ORIENT,
xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT));
syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_RELATION,
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index 734702a..9ef0f55 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1478,8 +1478,8 @@ SwXText::insertTextContentWithProperties(
uno::Reference< text::XTextRange > SAL_CALL
SwXText::appendTextContent(
const uno::Reference< text::XTextContent >& xTextContent,
const uno::Sequence< beans::PropertyValue >&
rCharacterAndParagraphProperties)
const uno::Sequence< beans::PropertyValue >& rCharacterAndParagraphProperties
)
{
// Right now this doesn't need a guard, as it's just calling the insert
// version, that has it already.
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx
index 72ba3f0..fbdee23 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -471,15 +471,9 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons
{
uno::Reference<drawing::XShape> xShape((const_cast<SdrObject*>(pObj)->getUnoShape()),
uno::UNO_QUERY);
uno::Sequence<beans::PropertyValue> propList = lclGetProperty(xShape, "InteropGrabBag");
if (propList.hasElements())
{
auto pLclProp = std::find_if(
std::begin(propList), std::end(propList),
[](const beans::PropertyValue& rProp) { return rProp.Name == "LayoutInCell"; });
if (pLclProp && pLclProp != propList.end())
pLclProp->Value >>= bLclInTabCell;
}
uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
if (xShapeProps.is())
xShapeProps->getPropertyValue("IsFollowingTextFlow") >>= bLclInTabCell;
}
if (bLclInTabCell)
attrList->add(XML_layoutInCell, "1");
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx
index 2157026..ce449a6 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -270,7 +270,7 @@ public:
,nVertOrient( text::VertOrientation::NONE )
,nVertRelation( text::RelOrientation::FRAME )
,nWrap(text::WrapTextMode_NONE)
,bLayoutInCell(false)
,bLayoutInCell(true)
,bOpaque( !rDMapper.IsInHeaderFooter() )
,bContour(false)
,bContourOutside(true)
@@ -662,7 +662,6 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
{
uno::Reference< drawing::XShape> xShape;
rValue.getAny( ) >>= xShape;
if ( xShape.is( ) )
{
// Is it a graphic image
@@ -847,7 +846,12 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
eAnchorType = text::TextContentAnchorType_AT_CHARACTER;
xShapeProps->setPropertyValue("AnchorType", uno::makeAny(eAnchorType));
if (m_pImpl->bLayoutInCell && bTextBox && m_pImpl->rDomainMapper.IsInTable()
&& m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME)
m_pImpl->nHoriRelation = text::RelOrientation::FRAME;
if(m_pImpl->rDomainMapper.IsInTable())
xShapeProps->setPropertyValue(getPropertyName(PROP_FOLLOW_TEXT_FLOW),
uno::makeAny(m_pImpl->bLayoutInCell));
//only the position orientation is handled in applyPosition()
m_pImpl->applyPosition(xShapeProps);
@@ -884,25 +888,6 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
xShapeProps->setPropertyValue("RotateAngle", uno::makeAny(nRotation));
}
//tdf#109411 If anchored object is in table, Word calculates its position from cell border
//instead of page (what is set in the sample document)
if (xShapeProps)
{
uno::Sequence<beans::PropertyValue> aShapeGrabBag;
xShapeProps->getPropertyValue("InteropGrabBag") >>= aShapeGrabBag;
beans::PropertyValue aLayInCell;
aLayInCell.Name = "LayoutInCell";
aLayInCell.Value <<= m_pImpl->bLayoutInCell;
aShapeGrabBag.realloc(1 + aShapeGrabBag.size());
aShapeGrabBag[aShapeGrabBag.size() - 1] = aLayInCell;
xShapeProps->setPropertyValue("InteropGrabBag",
uno::makeAny(aShapeGrabBag));
}
if (m_pImpl->rDomainMapper.IsInTable() && m_pImpl->bLayoutInCell &&
m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME && IsGraphic())
{
m_pImpl->nHoriRelation = text::RelOrientation::FRAME;
}
m_pImpl->applyRelativePosition(xShapeProps, /*bRelativeOnly=*/true);
@@ -1370,9 +1355,9 @@ uno::Reference<text::XTextContent> GraphicImport::createGraphicObject(uno::Refer
}
xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SURROUND ),
uno::makeAny(static_cast<sal_Int32>(m_pImpl->nWrap)));
if( m_pImpl->rDomainMapper.IsInTable() && m_pImpl->bLayoutInCell )
if( m_pImpl->rDomainMapper.IsInTable())
xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_FOLLOW_TEXT_FLOW ),
uno::makeAny(true));
uno::makeAny(m_pImpl->bLayoutInCell));
xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SURROUND_CONTOUR ),
uno::makeAny(m_pImpl->bContour));
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index e369705..02a9c78 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -37,6 +37,7 @@
#include <dmapper/PropertyIds.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <dmapper/PropertyIds.hxx>
static const sal_Unicode uCR = 0xd;
static const sal_Unicode uFtnEdnRef = 0x2;
@@ -69,7 +70,8 @@ OOXMLFastContextHandler::OOXMLFastContextHandler
mpStream(nullptr),
mnTableDepth(0),
inPositionV(false),
mbLayoutInCell(true),
mbAllowInCell(true),
mbIsVMLfound(false),
m_xContext(context),
m_bDiscardChildren(false),
m_bTookChoice(false)
@@ -90,7 +92,8 @@ OOXMLFastContextHandler::OOXMLFastContextHandler(OOXMLFastContextHandler * pCont
mpParserState(pContext->mpParserState),
mnTableDepth(pContext->mnTableDepth),
inPositionV(pContext->inPositionV),
mbLayoutInCell(pContext->mbLayoutInCell),
mbAllowInCell(pContext->mbAllowInCell),
mbIsVMLfound(pContext->mbIsVMLfound),
m_xContext(pContext->m_xContext),
m_bDiscardChildren(pContext->m_bDiscardChildren),
m_bTookChoice(pContext->m_bTookChoice)
@@ -1670,34 +1673,15 @@ void OOXMLFastContextHandlerShape::sendShape( Token_t Element )
bool bIsPicture = Element == ( NMSP_dmlPicture | XML_pic );
//tdf#87569: Fix table layout with correcting anchoring
//If anchored object is in table, Word calculates its position from cell border
//instead of page (what is set in the sample document)
uno::Reference<beans::XPropertySet> xShapePropSet(xShape, uno::UNO_QUERY);
if(xShapePropSet && bIsPicture) //TODO make grabbag for textboxes as well
if (mnTableDepth > 0 && xShapePropSet.is() && mbIsVMLfound) //if we had a table
{
uno::Sequence<beans::PropertyValue> aShapeGrabBag;
xShapePropSet->getPropertyValue("InteropGrabBag") >>= aShapeGrabBag;
beans::PropertyValue aLayInCell;
aLayInCell.Name = "LayoutInCell";
aLayInCell.Value <<= mbLayoutInCell;
aShapeGrabBag.realloc(1+aShapeGrabBag.size());
aShapeGrabBag[aShapeGrabBag.size() -1] = aLayInCell;
xShapePropSet->setPropertyValue("InteropGrabBag", uno::makeAny(aShapeGrabBag));
xShapePropSet->setPropertyValue(dmapper::getPropertyName(dmapper::PROP_FOLLOW_TEXT_FLOW),
uno::makeAny(mbAllowInCell));
}
if (mnTableDepth > 0 && mbLayoutInCell) //if we had a table
{
sal_Int16 nCurrentHorOriRel = {}; // spurious -Werror=maybe-uninitialized
xShapePropSet->getPropertyValue("HoriOrientRelation") >>= nCurrentHorOriRel;
//and the correction:
if (nCurrentHorOriRel == com::sun::star::text::RelOrientation::PAGE_FRAME)
{
xShapePropSet->setPropertyValue("HoriOrientRelation",
uno::makeAny(text::RelOrientation::FRAME));
}
}
// Notify the dmapper that the shape is ready to use
if ( !bIsPicture )
{
@@ -1748,7 +1732,7 @@ OOXMLFastContextHandlerShape::lcl_createFastChildContext
bool bGroupShape = Element == Token_t(NMSP_vml | XML_group);
// drawingML version also counts as a group shape.
bGroupShape |= mrShapeContext->getStartToken() == Token_t(NMSP_wpg | XML_wgp);
mbIsVMLfound = (getNamespace(Element) == NMSP_vmlOffice) || (getNamespace(Element) == NMSP_vml);
switch (oox::getNamespace(Element))
{
case NMSP_doc:
@@ -1771,9 +1755,8 @@ OOXMLFastContextHandlerShape::lcl_createFastChildContext
this);
//tdf129888 store allowincell attribute of the VML shape
mbLayoutInCell = true;
if (Attribs->hasAttribute(NMSP_vmlOffice | XML_allowincell))
mbLayoutInCell
mbAllowInCell
= !(Attribs->getValue(NMSP_vmlOffice | XML_allowincell) == "f");
if (!bGroupShape)
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index 079d49d..5bc4ea3 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -226,7 +226,8 @@ protected:
const css::uno::Reference< css::uno::XComponentContext >& getComponentContext() const { return m_xContext;}
bool inPositionV;
bool mbLayoutInCell; // o:allowincell
bool mbAllowInCell; // o:allowincell
bool mbIsVMLfound;
OOXMLValue::Pointer_t mpGridAfter;
private: