sw/qa/extras/uiwriter/data3/AsCharTxBxTest.docx |binary
 sw/qa/extras/uiwriter/uiwriter3.cxx             |   52 ++++++++++++++
 sw/source/core/doc/textboxhelper.cxx            |   89 +++++++++++++++++++-----
 sw/source/core/text/porfly.cxx                  |   32 +++++---
 4 files changed, 144 insertions(+), 29 deletions(-)

New commits:
commit 493a916a3113e877835c9bc7c93faef0d29f9a33
Author:     Attila Bakos (NISZ) <bakos.attilakar...@nisz.hu>
AuthorDate: Mon Feb 22 14:28:59 2021 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Mar 1 16:04:05 2021 +0100

    tdf#140158 tdf#138598 tdf#140598 sw: fix sync of AS_CHAR textboxes
    
    Textboxes anchored "As Character" fell apart, when
    typing before some characters or inserting a page break.
    
    By fixing that, the tdf#138598 bug also have fixed which
    was a regression from commit b6850bbe95418ecfde404be1696548f18d200c9b
    (tdf#106153 sw compatibility: fix textboxes exceeding the page).
    
    In addition, tdf140598 is also fixed, which was
    a regression from commit c96c386c5db45dc4d5e358915caad7474e373068
    (tdf#136516 add positioning to SwTextBoxHelper::syncProperty()).
    
    Change-Id: Ifeadd8b2055ce52a019d651369ca41185de7bbe3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111338
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sw/qa/extras/uiwriter/data3/AsCharTxBxTest.docx 
b/sw/qa/extras/uiwriter/data3/AsCharTxBxTest.docx
new file mode 100755
index 000000000000..7603b80d2c2d
Binary files /dev/null and b/sw/qa/extras/uiwriter/data3/AsCharTxBxTest.docx 
differ
diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx 
b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 7bb002b03ae9..6ee8609b5a24 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -960,6 +960,58 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf134253)
     CPPUNIT_ASSERT_EQUAL(6, getPages());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, TestAsCharTextBox)
+{
+    // Releated tickets:
+    // tdf#138598 Replace vertical alignment of As_char textboxes in footer
+    // tdf#140158 Remove horizontal positioning of As_char textboxes, because
+    // the anchor moving does the same for it.
+
+    load(DATA_DIRECTORY, "AsCharTxBxTest.docx");
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+
+    // Add 3x tab to the doc
+    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
+    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
+    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
+    Scheduler::ProcessEventsToIdle();
+
+    auto pExportDump = parseLayoutDump();
+    CPPUNIT_ASSERT(pExportDump);
+
+    // Check if the texbox fallen apart due to the tabs
+    const double nLeftSideOfShape1
+        = getXPath(pExportDump, 
"/root/page/body/txt/anchored/SwAnchoredDrawObject/bounds", "left")
+              .toDouble();
+    const double nLeftSideOfTxBx1
+        = getXPath(pExportDump, 
"/root/page/body/txt/anchored/fly/infos/bounds", "left").toDouble();
+
+    CPPUNIT_ASSERT(nLeftSideOfShape1 < nLeftSideOfTxBx1);
+
+    // Another test is for the tdf#138598: Check footer textbox
+    const double nLeftSideOfShape2
+        = getXPath(pExportDump, 
"/root/page[2]/footer/txt/anchored/SwAnchoredDrawObject/bounds",
+                   "left")
+              .toDouble();
+    const double nLeftSideOfTxBx2
+        = getXPath(pExportDump, 
"/root/page[2]/footer/txt/anchored/fly/infos/bounds", "left")
+              .toDouble();
+
+    CPPUNIT_ASSERT(nLeftSideOfShape2 < nLeftSideOfTxBx2);
+
+    const double nTopSideOfShape2
+        = getXPath(pExportDump, 
"/root/page[2]/footer/txt/anchored/SwAnchoredDrawObject/bounds",
+                   "top")
+              .toDouble();
+    const double nTopSideOfTxBx2
+        = getXPath(pExportDump, 
"/root/page[2]/footer/txt/anchored/fly/infos/bounds", "top")
+              .toDouble();
+
+    CPPUNIT_ASSERT(nTopSideOfShape2 < nTopSideOfTxBx2);
+    // Without the fix in place the two texboxes has been fallen apart, and  
asserts will broken.
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf76636)
 {
     load(DATA_DIRECTORY, "tdf76636.doc");
diff --git a/sw/source/core/doc/textboxhelper.cxx 
b/sw/source/core/doc/textboxhelper.cxx
index 37b612034d44..abe8f38d2124 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -711,10 +711,39 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, 
sal_uInt16 nWID, sal_u
                     if (aValue.get<text::TextContentAnchorType>()
                         == 
text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER)
                     {
-                        xPropertySet->setPropertyValue(
-                            UNO_NAME_ANCHOR_TYPE,
-                            uno::makeAny(
-                                
text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH));
+                        if (const auto aPos = 
pShape->GetAnchor().GetContentAnchor())
+                        {
+                            xPropertySet->setPropertyValue(
+                                UNO_NAME_ANCHOR_TYPE,
+                                uno::makeAny(text::TextContentAnchorType::
+                                                 
TextContentAnchorType_AT_CHARACTER));
+                            xPropertySet->setPropertyValue(
+                                UNO_NAME_HORI_ORIENT_RELATION,
+                                uno::makeAny(text::RelOrientation::CHAR));
+
+                            auto pAnch = pFormat->GetAnchor();
+                            
pAnch.SetAnchor(pShape->GetAnchor().GetContentAnchor());
+                            tools::Rectangle aRect(getTextRectangle(pShape, 
false));
+
+                            SwFormatHoriOrient 
aNewHOri(pFormat->GetHoriOrient());
+                            aNewHOri.SetPos(aRect.getX());
+
+                            SwFormatVertOrient 
aNewVOri(pFormat->GetVertOrient());
+                            aNewVOri.SetPos(aRect.getY());
+
+                            pFormat->SetFormatAttr(pAnch);
+                            // tdf#140598: Do not apply wrong rectangle 
position.
+                            if (aRect.TopLeft() != Point(0, 0))
+                            {
+                                pFormat->SetFormatAttr(aNewHOri);
+                                pFormat->SetFormatAttr(aNewVOri);
+                            }
+                            else
+                                SAL_WARN("sw.core",
+                                         "SwTextBoxHelper::syncProperty: 
Repositioning failed!");
+                        }
+
+                        return;
                     }
                     else // Otherwise copy the anchor type of the shape
                     {
@@ -725,9 +754,15 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, 
sal_uInt16 nWID, sal_u
                     if (aValue.get<text::TextContentAnchorType>()
                         == 
text::TextContentAnchorType::TextContentAnchorType_AT_PAGE)
                     {
-                        xPropertySet->setPropertyValue(
-                            UNO_NAME_ANCHOR_PAGE_NO,
-                            uno::makeAny(pShape->GetAnchor().GetPageNum()));
+                        if (pShape->GetAnchor().GetPageNum())
+                            xPropertySet->setPropertyValue(
+                                UNO_NAME_ANCHOR_PAGE_NO,
+                                
uno::makeAny(pShape->GetAnchor().GetPageNum()));
+                        else
+                        {
+                            SAL_WARN("sw.core", 
"SwTextBoxHelper::syncProperty: Invalid Page Num!");
+                            return;
+                        }
                     }
                     // At-Content Anchors have to be synced:
                     if (aValue.get<text::TextContentAnchorType>()
@@ -748,15 +783,25 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, 
sal_uInt16 nWID, sal_u
                                      "SwTextBoxHelper::syncProperty: Anchor 
without content!");
                     }
                     // And the repositioning:
-                    tools::Rectangle aRect(getTextRectangle(pShape, false));
+                    if (pShape->GetAnchor().GetAnchorId() != 
RndStdIds::FLY_AS_CHAR)
+                    {
+                        tools::Rectangle aRect(getTextRectangle(pShape, 
false));
 
-                    SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
-                    aNewHOri.SetPos(aNewHOri.GetPos() + aRect.getX());
-                    SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
-                    aNewVOri.SetPos(aNewVOri.GetPos() + aRect.getY());
+                        // tdf#140598: Do not apply wrong rectangle position.
+                        if (aRect.TopLeft() != Point(0, 0))
+                        {
+                            SwFormatHoriOrient 
aNewHOri(pShape->GetHoriOrient());
+                            aNewHOri.SetPos(aNewHOri.GetPos() + aRect.getX());
+                            SwFormatVertOrient 
aNewVOri(pShape->GetVertOrient());
+                            aNewVOri.SetPos(aNewVOri.GetPos() + aRect.getY());
 
-                    pFormat->SetFormatAttr(aNewHOri);
-                    pFormat->SetFormatAttr(aNewVOri);
+                            pFormat->SetFormatAttr(aNewHOri);
+                            pFormat->SetFormatAttr(aNewVOri);
+                        }
+                        else
+                            SAL_WARN("sw.core",
+                                     "SwTextBoxHelper::syncProperty: 
Repositioning failed!");
+                    }
                     return;
                 }
                 break;
@@ -947,6 +992,7 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& 
rShape, SfxItemSet const&
     if (!pFormat)
         return;
 
+    const bool bInlineAnchored = rShape.GetAnchor().GetAnchorId() == 
RndStdIds::FLY_AS_CHAR;
     SfxItemSet aTextBoxSet(pFormat->GetDoc()->GetAttrPool(), 
aFrameFormatSetRange);
 
     SfxItemIter aIter(rSet);
@@ -962,6 +1008,8 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& 
rShape, SfxItemSet const&
                 const text::TextContentAnchorType aNewAnchorType
                     = mapAnchorType(rShape.GetAnchor().GetAnchorId());
                 syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, 
uno::Any(aNewAnchorType));
+                if (bInlineAnchored)
+                    return;
                 auto& rOrient = static_cast<const SwFormatVertOrient&>(*pItem);
                 SwFormatVertOrient aOrient(rOrient);
 
@@ -990,6 +1038,8 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& 
rShape, SfxItemSet const&
                     = mapAnchorType(rShape.GetAnchor().GetAnchorId());
                 syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, 
uno::Any(aNewAnchorType));
                 auto& rOrient = static_cast<const SwFormatHoriOrient&>(*pItem);
+                if (bInlineAnchored)
+                    return;
                 SwFormatHoriOrient aOrient(rOrient);
 
                 tools::Rectangle aRect = getTextRectangle(&rShape, 
/*bAbsolute=*/false);
@@ -1015,11 +1065,14 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& 
rShape, SfxItemSet const&
                 tools::Rectangle aRect = getTextRectangle(&rShape, 
/*bAbsolute=*/false);
                 if (!aRect.IsEmpty())
                 {
-                    aVertOrient.SetPos(aVertOrient.GetPos() + aRect.getY());
-                    aTextBoxSet.Put(aVertOrient);
+                    if (!bInlineAnchored)
+                    {
+                        aVertOrient.SetPos(aVertOrient.GetPos() + 
aRect.getY());
+                        aHoriOrient.SetPos(aHoriOrient.GetPos() + 
aRect.getX());
 
-                    aHoriOrient.SetPos(aHoriOrient.GetPos() + aRect.getX());
-                    aTextBoxSet.Put(aHoriOrient);
+                        aTextBoxSet.Put(aVertOrient);
+                        aTextBoxSet.Put(aHoriOrient);
+                    }
 
                     aSize.SetWidth(aRect.getWidth());
                     aSize.SetHeight(aRect.getHeight());
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index 8fcbb7ff4ae9..e41afd83d7cb 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -352,20 +352,30 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, 
const Point &rBase,
             // is relative to the print area of the anchor text frame.
             tools::Rectangle aTextRectangle = 
SwTextBoxHelper::getTextRectangle(pShape);
 
-            SwFormatHoriOrient aHori(pTextBox->GetHoriOrient());
-            aHori.SetHoriOrient(css::text::HoriOrientation::NONE);
-            sal_Int32 nLeft = aTextRectangle.getX() - 
rFrame.getFrameArea().Left()
-                              - rFrame.getFramePrintArea().Left();
-            aHori.SetPos(nLeft);
-
+            const auto aPos(pShape->GetAnchor().GetContentAnchor());
             SwFormatVertOrient aVert(pTextBox->GetVertOrient());
-            aVert.SetVertOrient(css::text::VertOrientation::NONE);
-            sal_Int32 const nTop = aTextRectangle.getY() - 
rFrame.getFrameArea().Top()
-                                   - rFrame.getFramePrintArea().Top();
-            aVert.SetPos(nTop);
+
+            // tdf#138598 Replace vertical alignment of As_char textboxes in 
footer
+            // tdf#140158 Remove horizontal positioning of As_char textboxes, 
because
+            // the anchor moving does the same for it.
+            if (!aPos->nNode.GetNode().FindFooterStartNode())
+            {
+                aVert.SetVertOrient(css::text::VertOrientation::NONE);
+                sal_Int32 const nTop = aTextRectangle.getY() - 
rFrame.getFrameArea().Top()
+                                       - rFrame.getFramePrintArea().Top();
+                aVert.SetPos(nTop);
+            }
+            else
+            {
+                aVert.SetVertOrient(css::text::VertOrientation::NONE);
+                aVert.SetPos(SwTextBoxHelper::getTextRectangle(pShape, 
false).getY());
+            }
+
+            SwFormatAnchor aNewTxBxAnchor(pTextBox->GetAnchor());
+            aNewTxBxAnchor.SetAnchor(aPos);
 
             pTextBox->LockModify();
-            pTextBox->SetFormatAttr(aHori);
+            pTextBox->SetFormatAttr(aNewTxBxAnchor);
             pTextBox->SetFormatAttr(aVert);
             pTextBox->UnlockModify();
         }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to