sw/inc/fmtwrapinfluenceonobjpos.hxx | 5 sw/qa/extras/ooxmlexport/data/tdf124600b.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 9 sw/source/core/attr/fmtwrapinfluenceonobjpos.cxx | 10 - sw/source/core/doc/textboxhelper.cxx | 8 sw/source/core/inc/tocntntanchoredobjectposition.hxx | 4 sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx | 92 +++++++--- sw/source/filter/ww8/docxsdrexport.cxx | 4 writerfilter/source/dmapper/GraphicImport.cxx | 9 9 files changed, 110 insertions(+), 31 deletions(-)
New commits: commit f8c7a2284b88c149addc8a30abb0cad8a10dad77 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Sep 20 11:55:21 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Sep 20 12:42:17 2019 +0200 Related: tdf#124600 sw anchored object allow overlap: add DOCX filter Which also made it necessary to support allow-overlap=no for not only shapes, but for shapes-with-text in the layout. Change-Id: Ibd229d21995c0a1053db6bbab0a6ccbbf75f36d3 Reviewed-on: https://gerrit.libreoffice.org/79277 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/inc/fmtwrapinfluenceonobjpos.hxx b/sw/inc/fmtwrapinfluenceonobjpos.hxx index 8e56be1ed653..897e825b14ff 100644 --- a/sw/inc/fmtwrapinfluenceonobjpos.hxx +++ b/sw/inc/fmtwrapinfluenceonobjpos.hxx @@ -21,6 +21,7 @@ #include "hintids.hxx" #include "format.hxx" +#include "swtypes.hxx" #include <svl/poolitem.hxx> #include <com/sun/star/text/WrapInfluenceOnPosition.hpp> @@ -30,6 +31,8 @@ private: sal_Int16 mnWrapInfluenceOnPosition; /// Allow objects to overlap, permitted by default. bool mbAllowOverlap = true; + /// Vertical offset added during positioning to avoid an overlap. + SwTwips mnOverlapVertOffset = 0; public: @@ -59,6 +62,8 @@ public: void SetAllowOverlap(bool bAllowOverlap); bool GetAllowOverlap() const; + void SetOverlapVertOffset(SwTwips nOverlapVertOffset); + SwTwips GetOverlapVertOffset() const; void dumpAsXml(xmlTextWriterPtr pWriter) const override; }; diff --git a/sw/qa/extras/ooxmlexport/data/tdf124600b.docx b/sw/qa/extras/ooxmlexport/data/tdf124600b.docx new file mode 100644 index 000000000000..aa25ada91baf Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf124600b.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index dd059cdb6af9..ad5aec4e6d39 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -279,6 +279,15 @@ DECLARE_OOXMLEXPORT_TEST(tdf123912_protectedForm, "tdf123912_protectedForm.odt") CPPUNIT_ASSERT_EQUAL_MESSAGE("Section1 is protected", false, getProperty<bool>(xSect, "IsProtected")); } +DECLARE_OOXMLEXPORT_TEST(tdf124600b, "tdf124600b.docx") +{ + // <wp:anchor allowOverlap="0"> was lost on roundtrip, we always wrote "1" on export. + bool bAllowOverlap1 = getProperty<bool>(getShape(1), "AllowOverlap"); + CPPUNIT_ASSERT(!bAllowOverlap1); + bool bAllowOverlap2 = getProperty<bool>(getShape(2), "AllowOverlap"); + CPPUNIT_ASSERT(!bAllowOverlap2); +} + DECLARE_OOXMLEXPORT_TEST(testDateControl, "empty-date-control.odt") { // Check that we exported the empty date control correctly diff --git a/sw/source/core/attr/fmtwrapinfluenceonobjpos.cxx b/sw/source/core/attr/fmtwrapinfluenceonobjpos.cxx index a593416407c3..4182bb90a95a 100644 --- a/sw/source/core/attr/fmtwrapinfluenceonobjpos.cxx +++ b/sw/source/core/attr/fmtwrapinfluenceonobjpos.cxx @@ -43,7 +43,8 @@ bool SwFormatWrapInfluenceOnObjPos::operator==( const SfxPoolItem& rAttr ) const const SwFormatWrapInfluenceOnObjPos& rAttribute = static_cast<const SwFormatWrapInfluenceOnObjPos&>(rAttr); return (mnWrapInfluenceOnPosition == rAttribute.GetWrapInfluenceOnObjPos() - && mbAllowOverlap == rAttribute.mbAllowOverlap); + && mbAllowOverlap == rAttribute.mbAllowOverlap + && mnOverlapVertOffset == rAttribute.mnOverlapVertOffset); } SfxPoolItem* SwFormatWrapInfluenceOnObjPos::Clone( SfxItemPool * ) const @@ -154,6 +155,13 @@ bool SwFormatWrapInfluenceOnObjPos::GetAllowOverlap() const return mbAllowOverlap; } +void SwFormatWrapInfluenceOnObjPos::SetOverlapVertOffset(SwTwips nOverlapVertOffset) +{ + mnOverlapVertOffset = nOverlapVertOffset; +} + +SwTwips SwFormatWrapInfluenceOnObjPos::GetOverlapVertOffset() const { return mnOverlapVertOffset; } + void SwFormatWrapInfluenceOnObjPos::dumpAsXml(xmlTextWriterPtr pWriter) const { xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatWrapInfluenceOnObjPos")); diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 83672434b79d..89072dffae14 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -563,6 +563,14 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u case RES_FRAMEDIR: aPropertyName = UNO_NAME_WRITING_MODE; break; + case RES_WRAP_INFLUENCE_ON_OBJPOS: + switch (nMemberID) + { + case MID_ALLOW_OVERLAP: + aPropertyName = UNO_NAME_ALLOW_OVERLAP; + break; + } + break; } if (!aPropertyName.isEmpty()) diff --git a/sw/source/core/inc/tocntntanchoredobjectposition.hxx b/sw/source/core/inc/tocntntanchoredobjectposition.hxx index 01033a6f1e7b..07dd957cdf9c 100644 --- a/sw/source/core/inc/tocntntanchoredobjectposition.hxx +++ b/sw/source/core/inc/tocntntanchoredobjectposition.hxx @@ -81,6 +81,10 @@ namespace objectpositioning /** frame, at which the vertical position is oriented at */ const SwLayoutFrame& GetVertPosOrientFrame() const { return *mpVertPosOrientFrame;} + + /// In case overlap is not allowed, re-position the current object. + void CalcOverlap(const SwTextFrame* pAnchorFrameForVertPos, Point& rRelPos, + const SwTwips nTopOfAnch); }; } // namespace objectpositioning diff --git a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx index f26b48ac0a98..0fc56d1af80e 100644 --- a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx @@ -44,6 +44,7 @@ #include <dflyobj.hxx> #include <fmtwrapinfluenceonobjpos.hxx> #include <sortedobjs.hxx> +#include <textboxhelper.hxx> using namespace objectpositioning; using namespace ::com::sun::star; @@ -975,32 +976,7 @@ void SwToContentAnchoredObjectPosition::CalcPosition() // If it was requested to not overlap with already formatted objects, take care of that // here. - bool bAllowOverlap = rFrameFormat.GetWrapInfluenceOnObjPos().GetAllowOverlap(); - if (!bAllowOverlap) - { - // Get the list of objects. - const SwSortedObjs& rSortedObjs = *pAnchorFrameForVertPos->GetDrawObjs(); - for (const auto& pAnchoredObj : rSortedObjs) - { - if (pAnchoredObj == &GetAnchoredObj()) - { - // We found ourselves, stop iterating. - break; - } - - if (!GetAnchoredObj().GetObjRect().IsOver(pAnchoredObj->GetObjRect())) - { - // Found an already positioned object, but it doesn't overlap, ignore. - continue; - } - - // Already formatted, overlaps: resolve the conflict by shifting ourselves down. - SwTwips nYDiff - = pAnchoredObj->GetObjRect().Bottom() - GetAnchoredObj().GetObjRect().Top(); - aRelPos.setY(aRelPos.getY() + nYDiff + 1); - GetAnchoredObj().SetObjTop(nTopOfAnch + aRelPos.Y()); - } - } + CalcOverlap(pAnchorFrameForVertPos, aRelPos, nTopOfAnch); } // determine 'horizontal' position @@ -1097,6 +1073,70 @@ void SwToContentAnchoredObjectPosition::CalcPosition() GetAnchoredObj().SetCurrRelPos( aRelPos ); } +void SwToContentAnchoredObjectPosition::CalcOverlap(const SwTextFrame* pAnchorFrameForVertPos, + Point& rRelPos, const SwTwips nTopOfAnch) +{ + const SwFrameFormat& rFrameFormat = GetFrameFormat(); + bool bAllowOverlap = rFrameFormat.GetWrapInfluenceOnObjPos().GetAllowOverlap(); + if (bAllowOverlap) + { + return; + } + + if (SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT)) + { + // This is the frame part of a textbox, just take the offset from the textbox's shape part. + SwFrameFormat* pShapeOfTextBox + = SwTextBoxHelper::getOtherTextBoxFormat(&rFrameFormat, RES_FLYFRMFMT); + if (pShapeOfTextBox) + { + SwTwips nYDiff = pShapeOfTextBox->GetWrapInfluenceOnObjPos().GetOverlapVertOffset(); + if (nYDiff > 0) + { + rRelPos.setY(rRelPos.getY() + nYDiff + 1); + GetAnchoredObj().SetObjTop(nTopOfAnch + rRelPos.Y()); + } + } + return; + } + + // Get the list of objects. + const SwSortedObjs& rSortedObjs = *pAnchorFrameForVertPos->GetDrawObjs(); + for (const auto& pAnchoredObj : rSortedObjs) + { + if (pAnchoredObj == &GetAnchoredObj()) + { + // We found ourselves, stop iterating. + break; + } + + if (SwTextBoxHelper::isTextBox(&pAnchoredObj->GetFrameFormat(), RES_FLYFRMFMT)) + { + // Overlapping with the frame of a textbox is fine. + continue; + } + + if (!GetAnchoredObj().GetObjRect().IsOver(pAnchoredObj->GetObjRect())) + { + // Found an already positioned object, but it doesn't overlap, ignore. + continue; + } + + // Already formatted, overlaps: resolve the conflict by shifting ourselves down. + SwTwips nYDiff = pAnchoredObj->GetObjRect().Bottom() - GetAnchoredObj().GetObjRect().Top(); + rRelPos.setY(rRelPos.getY() + nYDiff + 1); + GetAnchoredObj().SetObjTop(nTopOfAnch + rRelPos.Y()); + + // Store our offset that avoids the overlap. If this is a shape of a textbox, then the frame + // of the textbox will use it. + SwFormatWrapInfluenceOnObjPos aInfluence(rFrameFormat.GetWrapInfluenceOnObjPos()); + aInfluence.SetOverlapVertOffset(nYDiff); + const_cast<SwFrameFormat&>(rFrameFormat).LockModify(); + const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr(aInfluence); + const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify(); + } +} + /** * Determine frame for horizontal position */ diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index d250b4747bdd..de82c29deae6 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -24,6 +24,7 @@ #include <fmtornt.hxx> #include <fmtfsize.hxx> #include <frmatr.hxx> +#include <fmtwrapinfluenceonobjpos.hxx> #include "docxattributeoutput.hxx" #include "docxexportfilter.hxx" #include <comphelper/flagguard.hxx> @@ -465,7 +466,8 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons attrList->add(XML_simplePos, "0"); attrList->add(XML_locked, "0"); attrList->add(XML_layoutInCell, "1"); - attrList->add(XML_allowOverlap, "1"); // TODO + bool bAllowOverlap = pFrameFormat->GetWrapInfluenceOnObjPos().GetAllowOverlap(); + attrList->add(XML_allowOverlap, bAllowOverlap ? "1" : "0"); if (pObj != nullptr) // It seems 0 and 1 have special meaning: just start counting from 2 to avoid issues with that. attrList->add(XML_relativeHeight, OString::number(pObj->GetOrdNum() + 2)); diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx index c148d7989e0d..269a4e290ecb 100644 --- a/writerfilter/source/dmapper/GraphicImport.cxx +++ b/writerfilter/source/dmapper/GraphicImport.cxx @@ -197,6 +197,7 @@ public: sal_Int16 nVertRelation; text::WrapTextMode nWrap; bool bLayoutInCell; + bool bAllowOverlap = true; bool bOpaque; bool bContour; bool bContourOutside; @@ -596,9 +597,9 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue) break; case NS_ooxml::LN_CT_Anchor_hidden: // 90992; - ignored break; - case NS_ooxml::LN_CT_Anchor_allowOverlap: // 90993; - //enable overlapping - ignored - break; + case NS_ooxml::LN_CT_Anchor_allowOverlap: + m_pImpl->bAllowOverlap = nIntValue != 0; + break; case NS_ooxml::LN_CT_Anchor_wp14_anchorId: case NS_ooxml::LN_CT_Inline_wp14_anchorId: { @@ -866,6 +867,8 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue) xShapeProps->setPropertyValue("Surround", uno::makeAny(static_cast<sal_Int32>(m_pImpl->nWrap))); m_pImpl->applyZOrder(xShapeProps); m_pImpl->applyName(xShapeProps); + xShapeProps->setPropertyValue("AllowOverlap", + uno::makeAny(m_pImpl->bAllowOverlap)); // Get the grab-bag set by oox, merge with our one and then put it back. comphelper::SequenceAsHashMap aInteropGrabBag(xShapeProps->getPropertyValue("InteropGrabBag")); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits