summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttila Bakos (NISZ) <bakos.attilakaroly@nisz.hu>2020-10-30 13:28:02 +0100
committerLászló Németh <nemeth@numbertext.org>2020-11-17 16:02:09 +0100
commita7bd634371285dbdceaf775dc31b6b586c7ca02f (patch)
treeeea7f95832d1bfaa4a081b23271bc28d9626e018
parent129629de708b35154a0812eaf19dd19e76e38331 (diff)
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@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r--sw/qa/extras/uiwriter/data3/AtPageTextBoxCrash.odtbin0 -> 9880 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter3.cxx39
-rw-r--r--sw/source/core/doc/textboxhelper.cxx50
3 files changed, 73 insertions, 16 deletions
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
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data3/AtPageTextBoxCrash.odt
Binary files 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: