summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Luth <justin.luth@collabora.com>2023-04-12 08:57:36 -0400
committerAndras Timar <andras.timar@collabora.com>2023-04-12 21:33:00 +0200
commit1f53c056c4bdd403a709f72263168137d7bdb1c0 (patch)
treed5c174b5dc22bf8e18e83f1703b6d34c8b53a042
parent9fd195881bd79c6b3ed09167e8d0af2769e72071 (diff)
Revert "tdf#147126 sw: fix missing as_char anchoring of group textboxes"
This reverts commit 341e397d970d10281fbc9691874b4441a841837d. It was added for T38690 and removed for T41585 Change-Id: I39cd0711047a131a3d60106b8682097411318781 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150293 Reviewed-by: Justin Luth <jluth@mail.com> Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r--sw/inc/textboxhelper.hxx17
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx18
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport2.cxx4
-rw-r--r--sw/qa/extras/uiwriter/data/tdf147126.docxbin39793 -> 0 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter3.cxx132
-rw-r--r--sw/source/core/doc/textboxhelper.cxx281
-rw-r--r--sw/source/core/frmedt/feshview.cxx8
-rw-r--r--sw/source/core/text/porfly.cxx56
-rw-r--r--xmloff/qa/unit/draw.cxx2
9 files changed, 235 insertions, 283 deletions
diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx
index fd194a639bcc..1a0cadabc0e9 100644
--- a/sw/inc/textboxhelper.hxx
+++ b/sw/inc/textboxhelper.hxx
@@ -92,6 +92,10 @@ public:
/// Copy shape attributes to the text frame
static void updateTextBoxMargin(SdrObject* pObj);
+ /// Sets the surround to through for the textframe of the given shape,
+ /// not to interfere with the layout. Returns true on success.
+ static bool setWrapThrough(SwFrameFormat* pShape);
+
/// Sets the anchor of the associated textframe of the given shape, and
/// returns true on success.
static bool changeAnchor(SwFrameFormat* pShape, SdrObject* pObj);
@@ -100,9 +104,19 @@ public:
/// returns true on success.
static bool doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pObj);
+ /// Returns true if the anchor different for the given shape, and the
+ /// associated textframe of the given shape.
+ /// Note: In case of AS_CHAR anchor the anchor type must be different,
+ /// because if not, layout breaks, but this situation also handled by
+ /// this function, and returns true in that case too.
+ static std::optional<bool> isAnchorTypeDifferent(const SwFrameFormat* pShape);
+
/// Sets the correct size of textframe depending on the given SdrObject.
static bool syncTextBoxSize(SwFrameFormat* pShape, SdrObject* pObj);
+ /// Returns true if the given shape has a valid textframe.
+ static bool isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape);
+
// Returns true on success. Synchronize z-order of the text frame of the given textbox
// by setting it one level higher than the z-order of the shape of the textbox.
static bool DoTextBoxZOrderCorrection(SwFrameFormat* pShape, const SdrObject* pObj);
@@ -174,8 +188,7 @@ public:
/// Calls the method given by pFunc with every textboxes of the group given by pFormat.
static void synchronizeGroupTextBoxProperty(bool pFunc(SwFrameFormat*, SdrObject*),
SwFrameFormat* pFormat, SdrObject* pObj);
-
- /// Collect all textboxes of the group given by the pGroupObj Parameter. Returns with a
+ /// Collect all textboxes of the group given by the pGoupObj Parameter. Returns with a
/// vector filled with the textboxes.
static std::vector<SwFrameFormat*> CollectTextBoxes(SdrObject* pGroupObject,
SwFrameFormat* pFormat);
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index b84b9ef1f9d6..3747aa399a27 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -400,16 +400,14 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testFdo78910, "fdo78910.docx")
assertXPath ( pXmlDoc, "//w:hyperlink[2]/w:r[5]/w:fldChar", "fldCharType", "end" );
}
-// FIXME: During this test a pure VML shape get converted to DML and crash at verifying.
-// CPPUNIT_TEST_FIXTURE(Test, testFDO78590)
-// DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testFDO78590, "FDO78590.docx")
-// {
-// xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
-//
-// // This is to ensure that the fld starts and ends inside a hyperlink...
-// assertXPath ( pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:framePr", "w", "9851" );
-// assertXPath ( pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:framePr", "h", "1669" );
-// }
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testFDO78590, "FDO78590.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+
+ // This is to ensure that the fld starts and ends inside a hyperlink...
+ assertXPath ( pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:framePr", "w", "9851" );
+ assertXPath ( pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:framePr", "h", "1669" );
+}
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testSdtCitationRun, "sdt-citation-run.docx")
{
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 2736775b2c81..232b67ab4056 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -246,10 +246,10 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf114212)
{
load(mpTestDocumentPath, "tdf114212.docx");
// Without the accompanying fix in place, this test would have failed with:
- // - Expected: 1428
+ // - Expected: 1427
// - Actual : 387
OUString aTop = parseDump("//anchored/fly[1]/infos/bounds", "top");
- CPPUNIT_ASSERT_EQUAL(OUString("1428"), aTop);
+ CPPUNIT_ASSERT_EQUAL(OUString("1427"), aTop);
}
CPPUNIT_TEST_FIXTURE(Test, testTdf109524)
diff --git a/sw/qa/extras/uiwriter/data/tdf147126.docx b/sw/qa/extras/uiwriter/data/tdf147126.docx
deleted file mode 100644
index 01ad39b345f4..000000000000
--- a/sw/qa/extras/uiwriter/data/tdf147126.docx
+++ /dev/null
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 563b631727a0..a1a1272ae23d 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -158,138 +158,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testVariableFieldTableRowSplitHeader)
assertXPath(pXmlDoc, "/root/page[5]/footer/txt[1]/Special[1]", "rText", "4");
}
-CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf147126)
-{
- createSwDoc(DATA_DIRECTORY, "tdf147126.docx");
- CPPUNIT_ASSERT(mxComponent);
- SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
- CPPUNIT_ASSERT(pTextDoc);
-
- const auto pLayoutXML1 = parseLayoutDump();
-
- for (auto nFly = 1; nFly < 8; ++nFly)
- {
- const auto nFlyLeft = getXPath(pLayoutXML1,
- OString::Concat("/root/page/body/txt[2]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "left")
- .toInt64();
- const auto nFlyRight = getXPath(pLayoutXML1,
- OString::Concat("/root/page/body/txt[2]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "width")
- .toInt64();
- const auto nFlyTop = getXPath(pLayoutXML1,
- OString::Concat("/root/page/body/txt[2]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "top")
- .toInt64();
- const auto nFlyBottom = getXPath(pLayoutXML1,
- OString::Concat("/root/page/body/txt[2]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "height")
- .toInt64();
-
- const auto sDrawRect = getXPath(
- pLayoutXML1,
- OString::Concat("/root/page/body/txt[2]/anchored/SwAnchoredDrawObject/SdrObjGroup/"
- "SdrObjList/SdrObject[")
- + OString::Concat(OString::number(nFly)) + OString::Concat("]"),
- "aOutRect");
-
- const auto nComaPos1 = sDrawRect.indexOf(',', 0);
- const auto nComaPos2 = sDrawRect.indexOf(',', nComaPos1 + 1);
- const auto nComaPos3 = sDrawRect.indexOf(',', nComaPos2 + 1);
-
- const auto nDraw1 = OUString(sDrawRect.subView(0, nComaPos1).data()).toInt64();
- const auto nDraw2
- = OUString(sDrawRect.subView(nComaPos1 + 1, nComaPos2 - nComaPos1).data()).toInt64();
- const auto nDraw3
- = OUString(sDrawRect.subView(nComaPos2 + 1, nComaPos3 - nComaPos2).data()).toInt64();
- const auto nDraw4
- = OUString(
- sDrawRect.subView(nComaPos3 + 1, sDrawRect.getLength() - nComaPos3 - 1).data())
- .toInt64();
-
- CPPUNIT_ASSERT_GREATER(nDraw1, nFlyLeft);
- CPPUNIT_ASSERT_GREATER(nDraw2, nFlyTop);
- CPPUNIT_ASSERT_LESS(nDraw3, nFlyRight);
- CPPUNIT_ASSERT_LESS(nDraw4, nFlyBottom);
- }
-
- for (auto nLineBreakCount = 0; nLineBreakCount < 4; ++nLineBreakCount)
- {
- pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
- Scheduler::ProcessEventsToIdle();
- }
- for (auto nSpaceCount = 0; nSpaceCount < 10; ++nSpaceCount)
- {
- pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SPACE);
- Scheduler::ProcessEventsToIdle();
- }
-
- dumpLayout(mxComponent);
- const auto pLayoutXML2 = parseLayoutDump();
-
- for (auto nFly = 1; nFly < 8; ++nFly)
- {
- const auto nFlyLeft = getXPath(pLayoutXML2,
- OString::Concat("/root/page/body/txt[6]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "left")
- .toInt64();
- const auto nFlyRight = getXPath(pLayoutXML2,
- OString::Concat("/root/page/body/txt[6]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "width")
- .toInt64();
- const auto nFlyTop = getXPath(pLayoutXML2,
- OString::Concat("/root/page/body/txt[6]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "top")
- .toInt64();
- const auto nFlyBottom = getXPath(pLayoutXML2,
- OString::Concat("/root/page/body/txt[6]/anchored/fly[")
- + OString::Concat(OString::number(nFly))
- + OString::Concat("]/infos/bounds"),
- "height")
- .toInt64();
-
- const auto sDrawRect = getXPath(
- pLayoutXML2,
- OString::Concat("/root/page/body/txt[6]/anchored/SwAnchoredDrawObject/SdrObjGroup/"
- "SdrObjList/SdrObject[")
- + OString::Concat(OString::number(nFly)) + OString::Concat("]"),
- "aOutRect");
-
- const auto nComaPos1 = sDrawRect.indexOf(',', 0);
- const auto nComaPos2 = sDrawRect.indexOf(',', nComaPos1 + 1);
- const auto nComaPos3 = sDrawRect.indexOf(',', nComaPos2 + 1);
-
- const auto nDraw1 = OUString(sDrawRect.subView(0, nComaPos1).data()).toInt64();
- const auto nDraw2
- = OUString(sDrawRect.subView(nComaPos1 + 1, nComaPos2 - nComaPos1).data()).toInt64();
- const auto nDraw3
- = OUString(sDrawRect.subView(nComaPos2 + 1, nComaPos3 - nComaPos2).data()).toInt64();
- const auto nDraw4
- = OUString(
- sDrawRect.subView(nComaPos3 + 1, sDrawRect.getLength() - nComaPos3 - 1).data())
- .toInt64();
-
- CPPUNIT_ASSERT_GREATER(nDraw1, nFlyLeft);
- CPPUNIT_ASSERT_GREATER(nDraw2, nFlyTop);
- CPPUNIT_ASSERT_LESS(nDraw3, nFlyRight);
- CPPUNIT_ASSERT_LESS(nDraw4, nFlyBottom);
- }
-}
-
CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf129382)
{
SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf129382.docx");
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index b09e98f343a7..1b9155f9b6e8 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -318,9 +318,6 @@ void SwTextBoxHelper::set(SwFrameFormat* pShapeFormat, SdrObject* pObj,
}
// Do sync for the new textframe.
synchronizeGroupTextBoxProperty(&changeAnchor, pShapeFormat, pObj);
- synchronizeGroupTextBoxProperty(&syncTextBoxSize, pShapeFormat, pObj);
-
- updateTextBoxMargin(pObj);
}
void SwTextBoxHelper::destroy(const SwFrameFormat* pShape, const SdrObject* pObject)
@@ -869,7 +866,10 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u
{
case MID_ANCHOR_ANCHORTYPE:
{
+ setWrapThrough(pShape);
changeAnchor(pShape, pObj);
+ doTextBoxPositioning(pShape, pObj);
+
return;
}
break;
@@ -1183,6 +1183,7 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const&
if (aTextBoxSet.Count())
pFormat->SetFormatAttr(aTextBoxSet);
+ //pFormat->GetDoc()->SetFlyFrameAttr(*pFormat, aTextBoxSet);
DoTextBoxZOrderCorrection(&rShape, pObj);
}
@@ -1202,35 +1203,67 @@ void SwTextBoxHelper::updateTextBoxMargin(SdrObject* pObj)
// Sync the padding
syncProperty(pParentFormat, UNO_NAME_TEXT_LEFTDIST,
- xPropertySet->getPropertyValue(UNO_NAME_TEXT_LEFTDIST), pObj);
+ xPropertySet->getPropertyValue(UNO_NAME_TEXT_LEFTDIST));
syncProperty(pParentFormat, UNO_NAME_TEXT_RIGHTDIST,
- xPropertySet->getPropertyValue(UNO_NAME_TEXT_RIGHTDIST), pObj);
+ xPropertySet->getPropertyValue(UNO_NAME_TEXT_RIGHTDIST));
syncProperty(pParentFormat, UNO_NAME_TEXT_UPPERDIST,
- xPropertySet->getPropertyValue(UNO_NAME_TEXT_UPPERDIST), pObj);
+ xPropertySet->getPropertyValue(UNO_NAME_TEXT_UPPERDIST));
syncProperty(pParentFormat, UNO_NAME_TEXT_LOWERDIST,
- xPropertySet->getPropertyValue(UNO_NAME_TEXT_LOWERDIST), pObj);
+ xPropertySet->getPropertyValue(UNO_NAME_TEXT_LOWERDIST));
// Sync the text aligning
syncProperty(pParentFormat, UNO_NAME_TEXT_VERTADJUST,
- xPropertySet->getPropertyValue(UNO_NAME_TEXT_VERTADJUST), pObj);
+ xPropertySet->getPropertyValue(UNO_NAME_TEXT_VERTADJUST));
syncProperty(pParentFormat, UNO_NAME_TEXT_HORZADJUST,
- xPropertySet->getPropertyValue(UNO_NAME_TEXT_HORZADJUST), pObj);
+ xPropertySet->getPropertyValue(UNO_NAME_TEXT_HORZADJUST));
// tdf137803: Sync autogrow:
const bool bIsAutoGrow
= xPropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT).get<bool>();
const bool bIsAutoWrap = xPropertySet->getPropertyValue(UNO_NAME_TEXT_WORDWRAP).get<bool>();
- syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, uno::Any(bIsAutoGrow),
- pObj);
+ syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, uno::Any(bIsAutoGrow));
syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_WIDTH_TYPE,
- uno::Any(bIsAutoWrap ? text::SizeType::FIX : text::SizeType::MIN), pObj);
+ uno::Any(bIsAutoWrap ? text::SizeType::FIX : text::SizeType::MIN));
changeAnchor(pParentFormat, pObj);
DoTextBoxZOrderCorrection(pParentFormat, pObj);
}
+bool SwTextBoxHelper::setWrapThrough(SwFrameFormat* pShape)
+{
+ OUString sErrMsg;
+ if (isTextBoxShapeHasValidTextFrame(pShape))
+ {
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
+ {
+ ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
+ if (auto xFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat))
+ try
+ {
+ uno::Reference<beans::XPropertySet> const xPropertySet(xFrame, uno::UNO_QUERY);
+ xPropertySet->setPropertyValue(UNO_NAME_SURROUND,
+ uno::makeAny(text::WrapTextMode_THROUGH));
+ return true;
+ }
+ catch (uno::Exception& e)
+ {
+ sErrMsg = "Exception caught: " + e.Message;
+ }
+ else
+ sErrMsg = "No XTextFrame!";
+ }
+ else
+ sErrMsg = "No Other TextBox Format!";
+ }
+ else
+ sErrMsg = "Not a Valid TextBox object!";
+
+ SAL_WARN("sw.core", "SwTextBoxHelper::setWrapThrough: " << sErrMsg);
+ return false;
+}
+
bool SwTextBoxHelper::changeAnchor(SwFrameFormat* pShape, SdrObject* pObj)
{
if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
@@ -1244,68 +1277,72 @@ bool SwTextBoxHelper::changeAnchor(SwFrameFormat* pShape, SdrObject* pObj)
const uno::Any aShapeHorRelOrient
= uno::makeAny(pShape->GetHoriOrient().GetRelationOrient());
- try
+ if (isAnchorTypeDifferent(pShape) || (pObj && pObj != pShape->FindRealSdrObject()))
{
- ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
- uno::Reference<beans::XPropertySet> const xPropertySet(
- SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
- if (pOldCnt && rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
- && rNewAnch.GetPageNum())
- {
- uno::Any aValue(text::TextContentAnchorType_AT_PAGE);
- xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION, aShapeHorRelOrient);
- xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
- xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
- uno::Any(rNewAnch.GetPageNum()));
- }
- else if (rOldAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && pNewCnt)
+ try
{
- if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
- {
- uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
- xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
- xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
- uno::Any(text::RelOrientation::CHAR));
- xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
- uno::Any(text::RelOrientation::PRINT_AREA));
- SwFormatAnchor aPos(pFormat->GetAnchor());
- aPos.SetAnchor(pNewCnt);
- pFormat->SetFormatAttr(aPos);
- }
- else
+ ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
+ uno::Reference<beans::XPropertySet> const xPropertySet(
+ SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
+ if (pOldCnt && rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
+ && rNewAnch.GetPageNum())
{
- uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
+ uno::Any aValue(text::TextContentAnchorType_AT_PAGE);
xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
aShapeHorRelOrient);
xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
- pFormat->SetFormatAttr(rNewAnch);
+ xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
+ uno::Any(rNewAnch.GetPageNum()));
}
- }
- else
- {
- if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ else if (rOldAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && pNewCnt)
{
- uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
- xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
- xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
- uno::Any(text::RelOrientation::CHAR));
- xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
- uno::Any(text::RelOrientation::PRINT_AREA));
- SwFormatAnchor aPos(pFormat->GetAnchor());
- aPos.SetAnchor(pNewCnt);
- pFormat->SetFormatAttr(aPos);
+ if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
+ xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
+ xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
+ uno::Any(text::RelOrientation::CHAR));
+ xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
+ uno::Any(text::RelOrientation::PRINT_AREA));
+ SwFormatAnchor aPos(pFormat->GetAnchor());
+ aPos.SetAnchor(pNewCnt);
+ pFormat->SetFormatAttr(aPos);
+ }
+ else
+ {
+ uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
+ xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
+ aShapeHorRelOrient);
+ xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
+ pFormat->SetFormatAttr(rNewAnch);
+ }
}
else
{
- xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
- aShapeHorRelOrient);
- pFormat->SetFormatAttr(pShape->GetAnchor());
+ if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
+ xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
+ xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
+ uno::Any(text::RelOrientation::CHAR));
+ xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
+ uno::Any(text::RelOrientation::PRINT_AREA));
+ SwFormatAnchor aPos(pFormat->GetAnchor());
+ aPos.SetAnchor(pNewCnt);
+ pFormat->SetFormatAttr(aPos);
+ }
+ else
+ {
+ xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
+ aShapeHorRelOrient);
+ pFormat->SetFormatAttr(pShape->GetAnchor());
+ }
}
}
- }
- catch (uno::Exception& e)
- {
- SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
+ catch (uno::Exception& e)
+ {
+ SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
+ }
}
return doTextBoxPositioning(pShape, pObj) && DoTextBoxZOrderCorrection(pShape, pObj);
@@ -1328,80 +1365,42 @@ bool SwTextBoxHelper::doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pOb
auto nLeftSpace = pShape->GetLRSpace().GetLeft();
SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
- aNewHOri.SetPos(aRect.Left() + nLeftSpace
- + (bIsGroupObj ? pObj->GetRelativePos().getX() : 0));
+ aNewHOri.SetPos(aRect.Left() + nLeftSpace);
+
SwFormatVertOrient aNewVOri(pFormat->GetVertOrient());
+ aNewVOri.SetPos(aRect.Top() + pShape->GetVertOrient().GetPos());
- if (bIsGroupObj)
+ // tdf#140598: Do not apply wrong rectangle position.
+ if (aRect.TopLeft() != Point(0, 0))
{
- aNewVOri.SetPos(
- ((pObj->GetRelativePos().getY()) > 0
- ? (pShape->GetVertOrient().GetPos() > 0
- ? pObj->GetRelativePos().getY()
- : pObj->GetRelativePos().getY() - pShape->GetVertOrient().GetPos())
- : (pShape->GetVertOrient().GetPos() > 0
- ? 0 // Is this can be a variation?
- : pObj->GetRelativePos().getY() - pShape->GetVertOrient().GetPos()))
- + aRect.Top());
+ pFormat->SetFormatAttr(aNewHOri);
+ pFormat->SetFormatAttr(aNewVOri);
}
else
- {
- aNewVOri.SetPos(
- ((pShape->GetVertOrient().GetPos()) > 0 ? pShape->GetVertOrient().GetPos() : 0)
- + aRect.Top());
- }
-
- if (pShape->GetVertOrient().GetVertOrient() != text::VertOrientation::NONE)
- {
- aNewVOri.SetVertOrient(text::VertOrientation::NONE);
- switch (pShape->GetVertOrient().GetVertOrient())
- {
- case text::VertOrientation::TOP:
- case text::VertOrientation::CHAR_TOP:
- case text::VertOrientation::LINE_TOP:
- {
- aNewVOri.SetPos(aNewVOri.GetPos() - pShape->GetFrameSize().GetHeight());
- break;
- }
- case text::VertOrientation::BOTTOM:
- case text::VertOrientation::CHAR_BOTTOM:
- case text::VertOrientation::LINE_BOTTOM:
- {
- aNewVOri.SetPos(aNewVOri.GetPos() + pShape->GetFrameSize().GetHeight());
- break;
- }
- case text::VertOrientation::CENTER:
- case text::VertOrientation::CHAR_CENTER:
- case text::VertOrientation::LINE_CENTER:
- {
- aNewVOri.SetPos(aNewVOri.GetPos()
- + std::lroundf(pShape->GetFrameSize().GetHeight() / 2));
- break;
- }
- default:
- break;
- }
- }
-
- pFormat->SetFormatAttr(aNewHOri);
- pFormat->SetFormatAttr(aNewVOri);
+ SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
}
else
{
tools::Rectangle aRect(
getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), false));
- SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
- aNewHOri.SetPos(
- (bIsGroupObj && pObj ? pObj->GetRelativePos().getX() : aNewHOri.GetPos())
- + aRect.Left());
- SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
- aNewVOri.SetPos(
- (bIsGroupObj && pObj ? pObj->GetRelativePos().getY() : aNewVOri.GetPos())
- + aRect.Top());
-
- pFormat->SetFormatAttr(aNewHOri);
- pFormat->SetFormatAttr(aNewVOri);
+ // tdf#140598: Do not apply wrong rectangle position.
+ if (aRect.TopLeft() != Point(0, 0) || bIsGroupObj)
+ {
+ SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
+ aNewHOri.SetPos(
+ (bIsGroupObj && pObj ? pObj->GetRelativePos().getX() : aNewHOri.GetPos())
+ + aRect.Left());
+ SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
+ aNewVOri.SetPos(
+ (bIsGroupObj && pObj ? pObj->GetRelativePos().getY() : aNewVOri.GetPos())
+ + aRect.Top());
+
+ pFormat->SetFormatAttr(aNewHOri);
+ pFormat->SetFormatAttr(aNewVOri);
+ }
+ else
+ SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
}
return true;
}
@@ -1409,6 +1408,23 @@ bool SwTextBoxHelper::doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pOb
return false;
}
+std::optional<bool> SwTextBoxHelper::isAnchorTypeDifferent(const SwFrameFormat* pShape)
+{
+ std::optional<bool> bRet;
+ if (isTextBoxShapeHasValidTextFrame(pShape))
+ {
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
+ {
+ if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ bRet = (pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AT_CHAR
+ && pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR);
+ else
+ bRet = pFormat->GetAnchor().GetAnchorId() != pShape->GetAnchor().GetAnchorId();
+ }
+ }
+ return bRet;
+}
+
bool SwTextBoxHelper::syncTextBoxSize(SwFrameFormat* pShape, SdrObject* pObj)
{
if (!pShape || !pObj)
@@ -1428,6 +1444,23 @@ bool SwTextBoxHelper::syncTextBoxSize(SwFrameFormat* pShape, SdrObject* pObj)
return false;
}
+bool SwTextBoxHelper::isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape)
+{
+ if (pShape && pShape->Which() == RES_DRAWFRMFMT)
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
+ if (pFormat && pFormat->Which() == RES_FLYFRMFMT)
+ return true;
+ else
+ SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: "
+ "Shape does not have valid textframe!");
+ else
+ SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: "
+ "Shape does not have associated frame!");
+ else
+ SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: Not valid shape!");
+ return false;
+}
+
bool SwTextBoxHelper::DoTextBoxZOrderCorrection(SwFrameFormat* pShape, const SdrObject* pObj)
{
// TODO: do this with group shape textboxes.
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index d74bc7e1c2cf..eab41d781c7a 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -1070,7 +1070,7 @@ void SwFEShell::SelectionToTop( bool bTop )
if (auto pFormat = FindFrameFormat(pObj))
{
// If it has not textframe skip...
- if (!SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT, pObj))
+ if (!SwTextBoxHelper::isTextBoxShapeHasValidTextFrame(pFormat))
continue;
// If it has a textframe so it is a textbox, get its page
if (auto pDrwModel
@@ -1100,7 +1100,7 @@ void SwFEShell::SelectionToTop( bool bTop )
// If this object is a textbox, two level increasing needed
// (one for the shape and one for the frame)
if (auto pNextFormat = FindFrameFormat(pNextObj))
- if (SwTextBoxHelper::isTextBox(pNextFormat, RES_DRAWFRMFMT, pNextObj)
+ if (SwTextBoxHelper::isTextBox(pNextFormat, RES_DRAWFRMFMT)
|| SwTextBoxHelper::isTextBox(pNextFormat, RES_FLYFRMFMT))
nShift++;
}
@@ -1139,7 +1139,7 @@ void SwFEShell::SelectionToBottom( bool bBottom )
if (auto pFormat = FindFrameFormat(pObj))
{
// If the shape has not textframes skip.
- if (!SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT, pObj))
+ if (!SwTextBoxHelper::isTextBoxShapeHasValidTextFrame(pFormat))
continue;
// If has, move the shape to correct level with...
if (auto pDrwModel
@@ -1152,7 +1152,7 @@ void SwFEShell::SelectionToBottom( bool bBottom )
{
// If the lower has no textframe, just do nothing, else move by one lower
if (auto pNextFormat = FindFrameFormat(pNextObj))
- if (SwTextBoxHelper::isTextBox(pNextFormat, RES_DRAWFRMFMT, pNextObj)
+ if (SwTextBoxHelper::isTextBox(pNextFormat, RES_DRAWFRMFMT)
|| SwTextBoxHelper::isTextBox(pNextFormat, RES_FLYFRMFMT))
pPage->SetObjectOrdNum(pObj->GetOrdNum(), pObj->GetOrdNum() - 1);
}
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index fc1b28f990d4..fc540731a975 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -26,7 +26,6 @@
#include <frmfmt.hxx>
#include <viewsh.hxx>
#include <textboxhelper.hxx>
-#include <IDocumentState.hxx>
#include <frmatr.hxx>
#include <sal/log.hxx>
@@ -364,15 +363,56 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, const Point &rBase,
aObjPositioning.CalcPosition();
}
- if (auto pFormat = FindFrameFormat(pSdrObj))
+ SwFrameFormat* pShape = FindFrameFormat(pSdrObj);
+ const SwFormatAnchor& rAnchor(pShape->GetAnchor());
+ if (rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
{
- if (pFormat->GetOtherTextBoxFormat())
+ // This is an inline draw shape, see if it has a textbox.
+ SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
+ if (pTextBox)
{
- const bool bModified = pFormat->GetDoc()->getIDocumentState().IsEnableSetModified();
- pFormat->GetDoc()->getIDocumentState().SetEnableSetModified(false);
- SwTextBoxHelper::synchronizeGroupTextBoxProperty(SwTextBoxHelper::changeAnchor, pFormat,
- pFormat->FindRealSdrObject());
- pFormat->GetDoc()->getIDocumentState().SetEnableSetModified(bModified);
+ // It has, so look up its text rectangle, and adjust the position
+ // of the textbox accordingly.
+ // Both rectangles are absolute, SwFormatHori/VertOrient's position
+ // is relative to the print area of the anchor text frame.
+ tools::Rectangle aTextRectangle = SwTextBoxHelper::getTextRectangle(pSdrObj);
+
+ const auto aPos(pShape->GetAnchor().GetContentAnchor());
+ SwFormatVertOrient aVert(pTextBox->GetVertOrient());
+ SwFormatHoriOrient aHori(pTextBox->GetHoriOrient());
+
+ // 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.
+ const bool bIsInHeaderFooter = aPos->nNode.GetNode().FindFooterStartNode();
+ // TODO: Find solution for Group Shapes in Header/Footer.
+ tools::Long nXoffs
+ = SwTextBoxHelper::getTextRectangle(
+ bIsInHeaderFooter ? pShape->FindRealSdrObject() : pSdrObj, false)
+ .Left();
+ if (!bIsInHeaderFooter)
+ {
+ aVert.SetVertOrient(css::text::VertOrientation::NONE);
+ aVert.SetRelationOrient(css::text::RelOrientation::FRAME);
+ auto const nTop = aTextRectangle.Top() - rFrame.getFrameArea().Top()
+ - rFrame.getFramePrintArea().Top();
+ aVert.SetPos(nTop);
+ }
+ else
+ {
+ aVert.SetVertOrient(css::text::VertOrientation::NONE);
+ aVert.SetPos(SwTextBoxHelper::getTextRectangle(pShape->FindRealSdrObject(), false).Top());
+ }
+
+ SwFormatAnchor aNewTxBxAnchor(pTextBox->GetAnchor());
+ aNewTxBxAnchor.SetAnchor(aPos);
+ aHori.SetPos(nXoffs + pShape->GetLRSpace().GetLeft());
+
+ pTextBox->LockModify();
+ pTextBox->SetFormatAttr(aNewTxBxAnchor);
+ pTextBox->SetFormatAttr(aVert);
+ pTextBox->SetFormatAttr(aHori);
+ pTextBox->UnlockModify();
}
}
diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx
index 114d1cb204f2..3f80c1770900 100644
--- a/xmloff/qa/unit/draw.cxx
+++ b/xmloff/qa/unit/draw.cxx
@@ -138,7 +138,7 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testTextBoxLoss)
// Make sure that the shape is still a textbox.
uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
- uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
bool bTextBox = false;
xShape->getPropertyValue("TextBox") >>= bTextBox;