[Libreoffice-commits] core.git: sw/inc sw/qa sw/source writerfilter/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Sep 20 10:43:24 UTC 2019


 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 <vmiklos at collabora.com>
AuthorDate: Fri Sep 20 11:55:21 2019 +0200
Commit:     Miklos Vajna <vmiklos at 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 <vmiklos at 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"));


More information about the Libreoffice-commits mailing list