summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttila Bakos (NISZ) <bakos.attilakaroly@nisz.hu>2021-02-22 14:28:59 +0100
committerLászló Németh <nemeth@numbertext.org>2021-03-01 16:04:05 +0100
commit493a916a3113e877835c9bc7c93faef0d29f9a33 (patch)
treea0a35dbc7bdc5dbb6df2c4cb71a245c8b5f45c7e
parent13f53741dabc33c5ac12ae26538a2803c6ba1073 (diff)
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 <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
-rwxr-xr-xsw/qa/extras/uiwriter/data3/AsCharTxBxTest.docxbin0 -> 19888 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter3.cxx52
-rw-r--r--sw/source/core/doc/textboxhelper.cxx89
-rw-r--r--sw/source/core/text/porfly.cxx32
4 files changed, 144 insertions, 29 deletions
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
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data3/AsCharTxBxTest.docx
Binary files 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();
}