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