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

Attila Bakos (NISZ) (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 17 15:02:48 UTC 2020


 sw/qa/extras/uiwriter/data3/AtPageTextBoxCrash.odt |binary
 sw/qa/extras/uiwriter/uiwriter3.cxx                |   39 ++++++++++++++++
 sw/source/core/doc/textboxhelper.cxx               |   50 ++++++++++++++-------
 3 files changed, 73 insertions(+), 16 deletions(-)

New commits:
commit a7bd634371285dbdceaf775dc31b6b586c7ca02f
Author:     Attila Bakos (NISZ) <bakos.attilakaroly at nisz.hu>
AuthorDate: Fri Oct 30 13:28:02 2020 +0100
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Tue Nov 17 16:02:09 2020 +0100

    tdf#137802 tdf#84691 sw: sync anchoring of textbox with UNO
    
    It was possible to anchor the textbox both to page and
    paragraph, resulting crash during file saving.
    
    Change-Id: I0c95a13c0d8d58cd7cc1fa86de1b80bf088ba782
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105046
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/sw/qa/extras/uiwriter/data3/AtPageTextBoxCrash.odt b/sw/qa/extras/uiwriter/data3/AtPageTextBoxCrash.odt
new file mode 100644
index 000000000000..20e58dfc0670
Binary files /dev/null and b/sw/qa/extras/uiwriter/data3/AtPageTextBoxCrash.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 09cad813f162..841b03493bf6 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -1856,6 +1856,45 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf127652)
     CPPUNIT_ASSERT_EQUAL_MESSAGE("We are on the wrong page!", assertPage, currentPage);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, AtPageTextBoxCrash)
+{
+    // Load sample file
+    load(DATA_DIRECTORY, "AtPageTextBoxCrash.odt");
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+
+    // Get the Writer-Shell for later use
+    SwWrtShell* pWrtSh = pTextDoc->GetDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtSh);
+
+    // Get the format of the shape
+    const SwFrameFormats& rFrmFormats = *pWrtSh->GetDoc()->GetSpzFrameFormats();
+    CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
+    auto pShape = rFrmFormats.front();
+    CPPUNIT_ASSERT(pShape);
+
+    // Add a textbox to the shape
+    SwTextBoxHelper::create(pShape);
+    auto pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
+    CPPUNIT_ASSERT(pTxBxFrm);
+
+    // Change its anchor to page
+    uno::Reference<beans::XPropertySet> xShpProps(getShape(1), uno::UNO_QUERY_THROW);
+    xShpProps->setPropertyValue(
+        "AnchorType", uno::makeAny(text::TextContentAnchorType::TextContentAnchorType_AT_PAGE));
+
+    // The page anchored objects must not have content anchor
+    // unless this will lead to crash later, for example on
+    // removing the paragraph where it is achored to...
+    CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AT_PAGE, pTxBxFrm->GetAnchor().GetAnchorId());
+    CPPUNIT_ASSERT(!pTxBxFrm->GetAnchor().GetContentAnchor());
+
+    // Remove the paragraph where the textframe should be anchored
+    // before. Now with the patch it must not crash...
+    auto xPara = getParagraph(1);
+    xPara->getText()->setString(OUString());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf135661)
 {
     load(DATA_DIRECTORY, "tdf135661.odt");
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index 82a1c9b6fdd7..b62269faa787 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -130,6 +130,8 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape)
     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_ANCHOR, MID_ANCHOR_ANCHORTYPE,
+                 xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE));
     syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_ORIENT,
                  xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT));
     syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_RELATION,
@@ -160,15 +162,10 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape)
         return;
 
     SfxItemSet aTxFrmSet(pFormat->GetDoc()->GetAttrPool(), aFrameFormatSetRange);
-    SwFormatAnchor aNewAnch = pFormat->GetAnchor();
 
-    if (pShape->GetAnchor().GetContentAnchor())
-        aNewAnch.SetAnchor(pShape->GetAnchor().GetContentAnchor());
-    if (pShape->GetAnchor().GetPageNum() > 0)
-        aNewAnch.SetPageNum(pShape->GetAnchor().GetPageNum());
-
-    aNewAnch.SetType(pShape->GetAnchor().GetAnchorId());
-    aTxFrmSet.Put(aNewAnch);
+    if (rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR
+        || rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA)
+        aTxFrmSet.Put(rAnch);
 
     SwFormatVertOrient aVOri(pFormat->GetVertOrient());
     SwFormatHoriOrient aHOri(pFormat->GetHoriOrient());
@@ -626,17 +623,38 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u
             switch (nMemberID)
             {
                 case MID_ANCHOR_ANCHORTYPE:
+                {
+                    uno::Reference<beans::XPropertySet> const xPropertySet(
+                        SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat),
+                        uno::UNO_QUERY);
+                    // Surround (Wrap) has to be THROUGH always:
+                    xPropertySet->setPropertyValue(UNO_NAME_SURROUND,
+                                                   uno::makeAny(text::WrapTextMode_THROUGH));
+                    // Use At_Char anchor instead of As_Char anchoring:
                     if (aValue.get<text::TextContentAnchorType>()
-                        == text::TextContentAnchorType_AS_CHARACTER)
+                        == text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER)
                     {
-                        uno::Reference<beans::XPropertySet> const xPropertySet(
-                            SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat),
-                            uno::UNO_QUERY);
-                        xPropertySet->setPropertyValue(UNO_NAME_SURROUND,
-                                                       uno::makeAny(text::WrapTextMode_THROUGH));
-                        return;
+                        xPropertySet->setPropertyValue(
+                            UNO_NAME_ANCHOR_TYPE,
+                            uno::makeAny(
+                                text::TextContentAnchorType::TextContentAnchorType_AT_CHARACTER));
                     }
-                    break;
+                    else // Otherwise copy the anchor type of the shape
+                    {
+                        xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
+                    }
+                    // After anchoring the position must be set as well:
+                    if (aValue.get<text::TextContentAnchorType>()
+                        == text::TextContentAnchorType::TextContentAnchorType_AT_PAGE)
+                    {
+                        xPropertySet->setPropertyValue(
+                            UNO_NAME_ANCHOR_PAGE_NO,
+                            uno::makeAny(pShape->GetAnchor().GetPageNum()));
+                    }
+
+                    return;
+                }
+                break;
             }
             break;
         case FN_TEXT_RANGE:


More information about the Libreoffice-commits mailing list