[Libreoffice-commits] core.git: sw/inc sw/qa sw/source
Attila Bakos (NISZ) (via logerrit)
logerrit at kemper.freedesktop.org
Thu Sep 16 10:56:47 UTC 2021
sw/inc/textboxhelper.hxx | 14
sw/qa/uitest/writer_tests7/tdf143574.py | 3
sw/source/core/doc/DocumentLayoutManager.cxx | 81 +++-
sw/source/core/doc/docdraw.cxx | 30 +
sw/source/core/doc/docfly.cxx | 4
sw/source/core/doc/docfmt.cxx | 7
sw/source/core/doc/textboxhelper.cxx | 456 ++++++++++++++-------------
sw/source/core/draw/dcontact.cxx | 31 +
sw/source/core/draw/dview.cxx | 12
sw/source/core/frmedt/fecopy.cxx | 4
sw/source/core/frmedt/fefly1.cxx | 22 +
sw/source/core/frmedt/feshview.cxx | 6
sw/source/core/layout/atrfrm.cxx | 15
sw/source/core/layout/flycnt.cxx | 2
sw/source/core/text/porfly.cxx | 13
sw/source/core/undo/undraw.cxx | 110 ++++++
sw/source/core/unocore/unodraw.cxx | 7
sw/source/uibase/shells/drawsh.cxx | 4
18 files changed, 531 insertions(+), 290 deletions(-)
New commits:
commit ba5156abace2e41ec4d21397c0875f7e1efd2beb
Author: Attila Bakos (NISZ) <bakos.attilakaroly at nisz.hu>
AuthorDate: Wed Sep 1 16:38:07 2021 +0200
Commit: László Németh <nemeth at numbertext.org>
CommitDate: Thu Sep 16 12:56:10 2021 +0200
tdf#143574 tdf#144271 sw: textboxes in group shapes - part 2
Sync textboxes with group shapes, adding textboxes to
group shapes, copying textboxes with group shapes,
grouping/ungrouping group shapes with textboxes, removing
textboxes from group shapes.
This patch fixes a memory leak (tdf#144271) introduced
by commit 504d78acb866495fd954fcd6db22ea68f174a5ab
"tdf#143574 sw: textboxes in group shapes - part 1".
Note: AS_CHAR anchoring is far not the best for group
shapes and import/export is still missing.
Change-Id: I7dc3b8d36c4a04f792ae4742fe4a45af9227a17e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121449
Tested-by: László Németh <nemeth at numbertext.org>
Reviewed-by: László Németh <nemeth at numbertext.org>
diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx
index 3cd442ed7194..978cf77327b9 100644
--- a/sw/inc/textboxhelper.hxx
+++ b/sw/inc/textboxhelper.hxx
@@ -69,10 +69,10 @@ public:
/// Sync property of TextBox with the one of the shape.
static void syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
- const css::uno::Any& rValue);
+ const css::uno::Any& rValue, SdrObject* pObj = nullptr);
/// Does the same, but works on properties which lack an sw-specific WID / MemberID.
static void syncProperty(SwFrameFormat* pShape, std::u16string_view rPropertyName,
- const css::uno::Any& rValue);
+ const css::uno::Any& rValue, SdrObject* pObj = nullptr);
/// Get a property of the underlying TextFrame.
static void getProperty(SwFrameFormat const* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
css::uno::Any& rValue);
@@ -83,7 +83,7 @@ public:
static css::text::TextContentAnchorType mapAnchorType(const RndStdIds& rAnchorID);
/// Similar to syncProperty(), but used by the internal API (e.g. for UI purposes).
- static void syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const& rSet);
+ static void syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const& rSet, SdrObject* pObj);
/// Copy shape attributes to the text frame
static void updateTextBoxMargin(SdrObject* pObj);
@@ -94,11 +94,11 @@ public:
/// Sets the anchor of the associated textframe of the given shape, and
/// returns true on success.
- static bool changeAnchor(SwFrameFormat* pShape);
+ static bool changeAnchor(SwFrameFormat* pShape, SdrObject* pObj);
/// Does the positioning for the associated textframe of the shape, and
/// returns true on success.
- static bool doTextBoxPositioning(SwFrameFormat* pShape);
+ 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.
@@ -112,7 +112,7 @@ public:
// 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);
+ static bool DoTextBoxZOrderCorrection(SwFrameFormat* pShape, SdrObject* pObj);
/**
* If we have an associated TextFrame, then return that.
@@ -134,7 +134,7 @@ public:
static css::uno::Reference<css::text::XTextFrame>
getUnoTextFrame(css::uno::Reference<css::drawing::XShape> const& xShape);
/// Return the textbox rectangle of a draw shape (in twips).
- static tools::Rectangle getTextRectangle(SwFrameFormat* pShape, bool bAbsolute = true);
+ static tools::Rectangle getTextRectangle(SdrObject* pShape, bool bAbsolute = true);
/**
* Is the frame format a text box?
diff --git a/sw/qa/uitest/writer_tests7/tdf143574.py b/sw/qa/uitest/writer_tests7/tdf143574.py
index 08e59b7c682a..61265e229f57 100644
--- a/sw/qa/uitest/writer_tests7/tdf143574.py
+++ b/sw/qa/uitest/writer_tests7/tdf143574.py
@@ -33,7 +33,6 @@ class tdf143574(UITestCase):
# At this point the Writer crashed here before the fix.
self.xUITest.executeCommand(".uno:AddTextBox");
- #follow up commit will introduce:
- #self.assertEqual(True, document.DrawPage.getByIndex(0).getByIndex(2).TextBox)
+ self.assertEqual(True, document.DrawPage.getByIndex(0).getByIndex(2).TextBox)
# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/core/doc/DocumentLayoutManager.cxx b/sw/source/core/doc/DocumentLayoutManager.cxx
index 1e071ef3ac5e..4cee8ad7c0b0 100644
--- a/sw/source/core/doc/DocumentLayoutManager.cxx
+++ b/sw/source/core/doc/DocumentLayoutManager.cxx
@@ -41,6 +41,7 @@
#include <frameformats.hxx>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
#include <osl/diagnose.h>
using namespace ::com::sun::star;
@@ -463,38 +464,64 @@ SwFrameFormat *DocumentLayoutManager::CopyLayoutFormat(
pDest->MakeFrames();
// If the draw format has a TextBox, then copy its fly format as well.
- if (SwFrameFormat* pSourceTextBox = SwTextBoxHelper::getOtherTextBoxFormat(&rSource, RES_DRAWFRMFMT))
+ if (rSource.Which() == RES_DRAWFRMFMT && rSource.GetOtherTextBoxFormat())
{
- SwFormatAnchor boxAnchor(rNewAnchor);
- if (RndStdIds::FLY_AS_CHAR == boxAnchor.GetAnchorId())
- {
- // AS_CHAR *must not* be set on textbox fly-frame
- boxAnchor.SetType(RndStdIds::FLY_AT_CHAR);
- }
- // presumably these anchors are supported though not sure
- assert(RndStdIds::FLY_AT_CHAR == boxAnchor.GetAnchorId() || RndStdIds::FLY_AT_PARA == boxAnchor.GetAnchorId()
- || boxAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE);
+ auto pObj = rSource.FindRealSdrObject();
+ auto pTextBoxNd = new SwTextBoxNode(pDest);
+ pDest->SetOtherTextBoxFormat(pTextBoxNd);
- if (!bMakeFrames && rNewAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ if (pObj)
{
- // If the draw format is as-char, then it will be copied with bMakeFrames=false, but
- // doing the same for the fly format would result in not making fly frames at all.
- bMakeFrames = true;
- }
-
- SwFrameFormat* pDestTextBox = CopyLayoutFormat(*pSourceTextBox,
- boxAnchor, bSetTextFlyAtt, bMakeFrames);
- SwAttrSet aSet(pDest->GetAttrSet());
- SwFormatContent aContent(pDestTextBox->GetContent().GetContentIdx()->GetNode().GetStartNode());
- aSet.Put(aContent);
- pDest->SetFormatAttr(aSet);
+ const bool bIsGroupObj = pObj->getChildrenOfSdrObject();
+ for (size_t it = 0;
+ it < (bIsGroupObj ? pObj->getChildrenOfSdrObject()->GetObjCount() : 1); it++)
+ {
+ auto pChild = bIsGroupObj ? pObj->getChildrenOfSdrObject()->GetObj(it)
+ : const_cast<SdrObject*>(pObj);
+ if (auto pSourceTextBox
+ = SwTextBoxHelper::getOtherTextBoxFormat(&rSource, RES_DRAWFRMFMT, pChild))
+ {
+ SwFormatAnchor boxAnchor(rNewAnchor);
+ if (RndStdIds::FLY_AS_CHAR == boxAnchor.GetAnchorId())
+ {
+ // AS_CHAR *must not* be set on textbox fly-frame
+ boxAnchor.SetType(RndStdIds::FLY_AT_CHAR);
+ }
+ // presumably these anchors are supported though not sure
+ assert(RndStdIds::FLY_AT_CHAR == boxAnchor.GetAnchorId()
+ || RndStdIds::FLY_AT_PARA == boxAnchor.GetAnchorId()
+ || boxAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE);
- // Link FLY and DRAW formats, so it becomes a text box
- auto pTextBox = new SwTextBoxNode(pDest);
- pTextBox->AddTextBox(pDest->FindRealSdrObject(), pDestTextBox);
+ if (!bMakeFrames && rNewAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ // If the draw format is as-char, then it will be copied with bMakeFrames=false, but
+ // doing the same for the fly format would result in not making fly frames at all.
+ bMakeFrames = true;
+ }
+ SwFrameFormat* pDestTextBox
+ = CopyLayoutFormat(*pSourceTextBox, boxAnchor, bSetTextFlyAtt, bMakeFrames);
+
+ SwAttrSet aSet(pDest->GetAttrSet());
+ SwFormatContent aContent(
+ pDestTextBox->GetContent().GetContentIdx()->GetNode().GetStartNode());
+ aSet.Put(aContent);
+ pDest->SetFormatAttr(aSet);
+
+ // Link FLY and DRAW formats, so it becomes a text box
+ SdrObject* pNewObj = pDest->FindRealSdrObject();
+ if (bIsGroupObj && pDest && pDest->FindRealSdrObject()
+ && pDest->FindRealSdrObject()->getChildrenOfSdrObject()
+ && (pDest->FindRealSdrObject()->getChildrenOfSdrObject()->GetObjCount() > it)
+ && pDest->FindRealSdrObject()->getChildrenOfSdrObject()->GetObj(it))
+ pNewObj = pDest->FindRealSdrObject()->getChildrenOfSdrObject()->GetObj(it);
+ pTextBoxNd->AddTextBox(pNewObj, pDestTextBox);
+ pDestTextBox->SetOtherTextBoxFormat(pTextBoxNd);
+ }
- pDest->SetOtherTextBoxFormat(pTextBox);
- pDestTextBox->SetOtherTextBoxFormat(pTextBox);
+ if (!bIsGroupObj)
+ break;
+ }
+ }
}
if (pDest->GetName().isEmpty())
diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx
index 609b174072e0..0aff4b8993ff 100644
--- a/sw/source/core/doc/docdraw.cxx
+++ b/sw/source/core/doc/docdraw.cxx
@@ -208,6 +208,8 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
static_cast<SwAnchoredDrawObject*>(pMyContact->GetAnchoredObj( pObj ));
bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned();
}
+
+ std::vector<std::pair<SwFrameFormat*, SdrObject*>> vSavedTextBoxes;
// Destroy ContactObjects and formats.
for( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
{
@@ -221,6 +223,9 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
OSL_ENSURE( bGroupMembersNotPositioned == pAnchoredDrawObj->NotYetPositioned(),
"<SwDoc::GroupSelection(..)> - group members have different positioning status!" );
#endif
+ // Before the format will be killed, save its textbox for later use.
+ if (auto pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pContact->GetFormat(), RES_DRAWFRMFMT, pObj))
+ vSavedTextBoxes.push_back(std::pair<SwFrameFormat*, SdrObject*>(pTextBox, pObj));
pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
// Deletes itself!
@@ -247,6 +252,16 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
pFormat->SetPositionLayoutDir(
text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
+ // Add the saved textboxes to the new format.
+ auto pTextBoxNode = new SwTextBoxNode(pFormat);
+ for (auto& pTextBoxEntry : vSavedTextBoxes)
+ {
+ pTextBoxNode->AddTextBox(pTextBoxEntry.second, pTextBoxEntry.first);
+ pTextBoxEntry.first->SetOtherTextBoxFormat(pTextBoxNode);
+ }
+ pFormat->SetOtherTextBoxFormat(pTextBoxNode);
+ vSavedTextBoxes.clear();
+
rDrawView.GroupMarked();
OSL_ENSURE( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
@@ -311,6 +326,11 @@ void SwDoc::UnGroupSelection( SdrView& rDrawView )
if ( auto pObjGroup = dynamic_cast<SdrObjGroup*>(pObj) )
{
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+
+ SwTextBoxNode* pTextBoxNode = nullptr;
+ if (auto pGroupFormat = pContact->GetFormat())
+ pTextBoxNode = pGroupFormat->GetOtherTextBoxFormat();
+
SwFormatAnchor aAnch( pContact->GetFormat()->GetAnchor() );
SdrObjList *pLst = pObjGroup->GetSubList();
@@ -327,6 +347,16 @@ void SwDoc::UnGroupSelection( SdrView& rDrawView )
SwDrawFrameFormat *pFormat = MakeDrawFrameFormat( GetUniqueShapeName(),
GetDfltFrameFormat() );
pFormat->SetFormatAttr( aAnch );
+
+ if (pTextBoxNode)
+ if (auto pTextBoxFormat = pTextBoxNode->GetTextBox(pSubObj))
+ {
+ auto pNewTextBoxNode = new SwTextBoxNode(pFormat);
+ pNewTextBoxNode->AddTextBox(pSubObj, pTextBoxFormat);
+ pFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
+ pTextBoxFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
+ }
+
// #i36010# - set layout direction of the position
pFormat->SetPositionLayoutDir(
text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx
index 6ff9bf910240..d8fe293c7f0a 100644
--- a/sw/source/core/doc/docfly.cxx
+++ b/sw/source/core/doc/docfly.cxx
@@ -577,7 +577,7 @@ bool SwDoc::SetFlyFrameAttr( SwFrameFormat& rFlyFormat, SfxItemSet& rSet )
getIDocumentState().SetModified();
- SwTextBoxHelper::syncFlyFrameAttr(rFlyFormat, rSet);
+ //SwTextBoxHelper::syncFlyFrameAttr(rFlyFormat, rSet);
return bRet;
}
@@ -924,7 +924,7 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList,
RES_DRAWFRMFMT))
{
SwTextBoxHelper::syncFlyFrameAttr(*pContact->GetFormat(),
- pContact->GetFormat()->GetAttrSet());
+ pContact->GetFormat()->GetAttrSet(), pObj);
}
}
break;
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 16ad4d8dfcd0..d2ccfaf81544 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -483,8 +483,11 @@ void SwDoc::SetAttr( const SfxItemSet& rSet, SwFormat& rFormat )
auto pShapeFormat = dynamic_cast<SwFrameFormat*>(&rFormat);
if (pShapeFormat && SwTextBoxHelper::isTextBox(pShapeFormat, RES_DRAWFRMFMT))
{
- SwTextBoxHelper::syncFlyFrameAttr(*pShapeFormat, rSet);
- SwTextBoxHelper::changeAnchor(pShapeFormat);
+ if (auto pObj = pShapeFormat->FindRealSdrObject())
+ {
+ SwTextBoxHelper::syncFlyFrameAttr(*pShapeFormat, rSet, pObj);
+ SwTextBoxHelper::changeAnchor(pShapeFormat, pObj);
+ }
}
getIDocumentState().SetModified();
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index 3858da359a3c..93b9564a59bf 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -61,9 +61,10 @@ using namespace com::sun::star;
void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCopyText)
{
- if (dynamic_cast<SdrObjGroup*>(pObject->getParentSdrObjectFromSdrObject()))
- // The GroupShape Textbox creation method call comes here.
- return;
+ assert(pShape);
+ assert(pObject);
+
+ const bool bIsGroupObj = dynamic_cast<SdrObjGroup*>(pObject->getParentSdrObjectFromSdrObject());
// If TextBox wasn't enabled previously
if (pShape->GetOtherTextBoxFormat() && pShape->GetOtherTextBoxFormat()->GetTextBox(pObject))
@@ -74,9 +75,9 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCo
if (bCopyText)
{
- if (auto pSdrShape = pShape->FindRealSdrObject())
+ if (pObject)
{
- uno::Reference<text::XText> xSrcCnt(pSdrShape->getWeakUnoShape(), uno::UNO_QUERY);
+ uno::Reference<text::XText> xSrcCnt(pObject->getWeakUnoShape(), uno::UNO_QUERY);
auto xCur = xSrcCnt->createTextCursor();
xCur->gotoStart(false);
xCur->gotoEnd(true);
@@ -94,8 +95,7 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCo
uno::UNO_QUERY);
try
{
- SdrObject* pSourceSDRShape = pShape->FindRealSdrObject();
- uno::Reference<text::XTextContent> XSourceShape(pSourceSDRShape->getUnoShape(),
+ uno::Reference<text::XTextContent> XSourceShape(pObject->getUnoShape(),
uno::UNO_QUERY_THROW);
xTextContentAppend->insertTextContentWithProperties(
xTextFrame, uno::Sequence<beans::PropertyValue>(), XSourceShape->getAnchor());
@@ -155,45 +155,47 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCo
pShape->SetFormatAttr(aSet);
}
- DoTextBoxZOrderCorrection(pShape);
+ DoTextBoxZOrderCorrection(pShape, pObject);
+
// Also initialize the properties, which are not constant, but inherited from the shape's ones.
- uno::Reference<drawing::XShape> xShape(pShape->FindRealSdrObject()->getUnoShape(),
- uno::UNO_QUERY);
- syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::makeAny(xShape->getSize()));
+ uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
+ syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::makeAny(xShape->getSize()), pObject);
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));
+ xShapePropertySet->getPropertyValue(UNO_NAME_IS_FOLLOWING_TEXT_FLOW), pObject);
syncProperty(pShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE,
- xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE));
+ xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE), pObject);
syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_ORIENT,
- xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT));
+ xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT), pObject);
syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_RELATION,
- xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION));
+ xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION), pObject);
syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_ORIENT,
- xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT));
+ xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT), pObject);
syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_RELATION,
- xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION));
+ xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION), pObject);
syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_POSITION,
- xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION));
+ xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION), pObject);
syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_POSITION,
- xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION));
+ xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION), pObject);
syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT,
- xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT));
+ xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT), pObject);
syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0,
- xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST));
+ xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST), pObject);
text::WritingMode eMode;
if (xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_WRITINGMODE) >>= eMode)
- syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)));
+ syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)), pObject);
+
+ if (bIsGroupObj)
+ doTextBoxPositioning(pShape, pObject);
// Check if the shape had text before and move it to the new textframe
if (!bCopyText || sCopyableText.isEmpty())
return;
- auto pSdrShape = pShape->FindRealSdrObject();
- if (pSdrShape)
+ if (pObject)
{
- auto pSourceText = dynamic_cast<SdrTextObj*>(pSdrShape);
+ auto pSourceText = dynamic_cast<SdrTextObj*>(pObject);
uno::Reference<text::XTextRange> xDestText(xRealTextFrame, uno::UNO_QUERY);
xDestText->setString(sCopyableText);
@@ -415,12 +417,14 @@ uno::Any SwTextBoxHelper::queryInterface(const SwFrameFormat* pShape, const uno:
return aRet;
}
-tools::Rectangle SwTextBoxHelper::getTextRectangle(SwFrameFormat* pShape, bool bAbsolute)
+tools::Rectangle SwTextBoxHelper::getTextRectangle(SdrObject* pShape, bool bAbsolute)
{
tools::Rectangle aRet;
aRet.SetEmpty();
- auto pSdrShape = pShape->FindRealSdrObject();
- auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(pSdrShape);
+
+ assert(pShape);
+
+ auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(pShape);
if (pCustomShape)
{
// Need to temporarily release the lock acquired in
@@ -435,17 +439,17 @@ tools::Rectangle SwTextBoxHelper::getTextRectangle(SwFrameFormat* pShape, bool b
if (nLocks)
xLockable->setActionLocks(nLocks);
}
- else if (pSdrShape)
+ else if (pShape)
{
// fallback - get *any* bound rect we can possibly get hold of
- aRet = pSdrShape->GetCurrentBoundRect();
+ aRet = pShape->GetCurrentBoundRect();
}
- if (!bAbsolute && pSdrShape)
+ if (!bAbsolute && pShape)
{
// Relative, so count the logic (reference) rectangle, see the EnhancedCustomShape2d ctor.
- Point aPoint(pSdrShape->GetSnapRect().Center());
- Size aSize(pSdrShape->GetLogicRect().GetSize());
+ Point aPoint(pShape->GetSnapRect().Center());
+ Size aSize(pShape->GetLogicRect().GetSize());
aPoint.AdjustX(-(aSize.Width() / 2));
aPoint.AdjustY(-(aSize.Height() / 2));
tools::Rectangle aLogicRect(aPoint, aSize);
@@ -456,12 +460,12 @@ tools::Rectangle SwTextBoxHelper::getTextRectangle(SwFrameFormat* pShape, bool b
}
void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rPropertyName,
- const css::uno::Any& rValue)
+ const css::uno::Any& rValue, SdrObject* pObj)
{
// Textframes does not have valid horizontal adjust property, so map it to paragraph adjust property
if (rPropertyName == UNO_NAME_TEXT_HORZADJUST)
{
- SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
+ SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
if (!pFormat)
return;
@@ -506,7 +510,7 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rP
// CustomShapeGeometry changes the textbox position offset and size, so adjust both.
syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::Any());
- SdrObject* pObject = pShape->FindRealSdrObject();
+ SdrObject* pObject = pObj ? pObj : pShape->FindRealSdrObject();
if (pObject)
{
tools::Rectangle aRectangle(pObject->GetSnapRect());
@@ -518,7 +522,7 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rP
uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
}
- SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
+ SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
if (!pFormat)
return;
@@ -555,30 +559,30 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rP
if (nDirection)
{
- syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(nDirection));
+ syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(nDirection), pObj);
}
}
}
else if (rPropertyName == UNO_NAME_TEXT_VERT_ADJUST)
- syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, rValue);
+ syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, rValue, pObj);
else if (rPropertyName == UNO_NAME_TEXT_AUTOGROWHEIGHT)
- syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, rValue);
+ syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, rValue, pObj);
else if (rPropertyName == UNO_NAME_TEXT_LEFTDIST)
- syncProperty(pShape, RES_BOX, LEFT_BORDER_DISTANCE, rValue);
+ syncProperty(pShape, RES_BOX, LEFT_BORDER_DISTANCE, rValue, pObj);
else if (rPropertyName == UNO_NAME_TEXT_RIGHTDIST)
- syncProperty(pShape, RES_BOX, RIGHT_BORDER_DISTANCE, rValue);
+ syncProperty(pShape, RES_BOX, RIGHT_BORDER_DISTANCE, rValue, pObj);
else if (rPropertyName == UNO_NAME_TEXT_UPPERDIST)
- syncProperty(pShape, RES_BOX, TOP_BORDER_DISTANCE, rValue);
+ syncProperty(pShape, RES_BOX, TOP_BORDER_DISTANCE, rValue, pObj);
else if (rPropertyName == UNO_NAME_TEXT_LOWERDIST)
- syncProperty(pShape, RES_BOX, BOTTOM_BORDER_DISTANCE, rValue);
+ syncProperty(pShape, RES_BOX, BOTTOM_BORDER_DISTANCE, rValue, pObj);
else if (rPropertyName == UNO_NAME_TEXT_WRITINGMODE)
{
text::WritingMode eMode;
sal_Int16 eMode2;
if (rValue >>= eMode)
- syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)));
+ syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)), pObj);
else if (rValue >>= eMode2)
- syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(eMode2));
+ syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(eMode2), pObj);
}
else
SAL_INFO("sw.core", "SwTextBoxHelper::syncProperty: unhandled property: "
@@ -635,7 +639,7 @@ css::uno::Any SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, const OU
}
void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
- const css::uno::Any& rValue)
+ const css::uno::Any& rValue, SdrObject* pObj)
{
// No shape yet? Then nothing to do, initial properties are set by create().
if (!pShape)
@@ -644,7 +648,7 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u
uno::Any aValue(rValue);
nMemberID &= ~CONVERT_TWIPS;
- SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
+ SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
if (!pFormat)
return;
@@ -745,8 +749,8 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u
case MID_ANCHOR_ANCHORTYPE:
{
setWrapThrough(pShape);
- changeAnchor(pShape);
- doTextBoxPositioning(pShape);
+ changeAnchor(pShape, pObj);
+ doTextBoxPositioning(pShape, pObj);
return;
}
@@ -844,7 +848,9 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u
// Position/size should be the text position/size, not the shape one as-is.
if (bAdjustX || bAdjustY || bAdjustSize)
{
- tools::Rectangle aRect = getTextRectangle(pShape, /*bAbsolute=*/false);
+ changeAnchor(pShape, pObj);
+ tools::Rectangle aRect
+ = getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), /*bAbsolute=*/false);
if (!aRect.IsEmpty())
{
if (bAdjustX || bAdjustY)
@@ -929,9 +935,10 @@ text::TextContentAnchorType SwTextBoxHelper::mapAnchorType(const RndStdIds& rAnc
return aAnchorType;
}
-void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const& rSet)
+void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const& rSet,
+ SdrObject* pObj)
{
- SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, RES_DRAWFRMFMT);
+ SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, RES_DRAWFRMFMT, pObj);
if (!pFormat)
return;
@@ -950,12 +957,14 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const&
// The new position can be with anchor changing so sync it!
const text::TextContentAnchorType aNewAnchorType
= mapAnchorType(rShape.GetAnchor().GetAnchorId());
- syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType));
+ syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
+ pObj);
if (bInlineAnchored)
return;
SwFormatVertOrient aOrient(pItem->StaticWhichCast(RES_VERT_ORIENT));
- tools::Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
+ tools::Rectangle aRect = getTextRectangle(pObj ? pObj : rShape.FindRealSdrObject(),
+ /*bAbsolute=*/false);
if (!aRect.IsEmpty())
aOrient.SetPos(aOrient.GetPos() + aRect.Top());
@@ -978,12 +987,14 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const&
// The new position can be with anchor changing so sync it!
const text::TextContentAnchorType aNewAnchorType
= mapAnchorType(rShape.GetAnchor().GetAnchorId());
- syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType));
+ syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
+ pObj);
if (bInlineAnchored)
return;
SwFormatHoriOrient aOrient(pItem->StaticWhichCast(RES_HORI_ORIENT));
- tools::Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
+ tools::Rectangle aRect = getTextRectangle(pObj ? pObj : rShape.FindRealSdrObject(),
+ /*bAbsolute=*/false);
if (!aRect.IsEmpty())
aOrient.SetPos(aOrient.GetPos() + aRect.Left());
@@ -1003,13 +1014,18 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const&
SwFormatHoriOrient aHoriOrient(rShape.GetHoriOrient());
SwFormatFrameSize aSize(pFormat->GetFrameSize());
- tools::Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
+ tools::Rectangle aRect = getTextRectangle(pObj ? pObj : rShape.FindRealSdrObject(),
+ /*bAbsolute=*/false);
if (!aRect.IsEmpty())
{
if (!bInlineAnchored)
{
- aVertOrient.SetPos(aVertOrient.GetPos() + aRect.Top());
- aHoriOrient.SetPos(aHoriOrient.GetPos() + aRect.Left());
+ aVertOrient.SetPos(
+ (pObj ? pObj->GetRelativePos().getX() : aVertOrient.GetPos())
+ + aRect.Top());
+ aHoriOrient.SetPos(
+ (pObj ? pObj->GetRelativePos().getY() : aHoriOrient.GetPos())
+ + aRect.Left());
aTextBoxSet.Put(aVertOrient);
aTextBoxSet.Put(aHoriOrient);
@@ -1029,7 +1045,7 @@ 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));
+ uno::Any(aNewAnchorType), pObj);
}
else
{
@@ -1048,9 +1064,10 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const&
} while (pItem && (0 != pItem->Which()));
if (aTextBoxSet.Count())
- pFormat->GetDoc()->SetFlyFrameAttr(*pFormat, aTextBoxSet);
+ pFormat->SetFormatAttr(aTextBoxSet);
+ //pFormat->GetDoc()->SetFlyFrameAttr(*pFormat, aTextBoxSet);
- DoTextBoxZOrderCorrection(&rShape);
+ DoTextBoxZOrderCorrection(&rShape, pObj);
}
void SwTextBoxHelper::updateTextBoxMargin(SdrObject* pObj)
@@ -1092,8 +1109,8 @@ void SwTextBoxHelper::updateTextBoxMargin(SdrObject* pObj)
syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_WIDTH_TYPE,
uno::Any(bIsAutoWrap ? text::SizeType::FIX : text::SizeType::MIN));
- changeAnchor(pParentFormat);
- DoTextBoxZOrderCorrection(pParentFormat);
+ changeAnchor(pParentFormat, pObj);
+ DoTextBoxZOrderCorrection(pParentFormat, pObj);
}
bool SwTextBoxHelper::setWrapThrough(SwFrameFormat* pShape)
@@ -1129,147 +1146,147 @@ bool SwTextBoxHelper::setWrapThrough(SwFrameFormat* pShape)
return false;
}
-bool SwTextBoxHelper::changeAnchor(SwFrameFormat* pShape)
+bool SwTextBoxHelper::changeAnchor(SwFrameFormat* pShape, SdrObject* pObj)
{
- if (isTextBoxShapeHasValidTextFrame(pShape))
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
{
- if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
- {
- const SwFormatAnchor& rOldAnch = pFormat->GetAnchor();
- const SwFormatAnchor& rNewAnch = pShape->GetAnchor();
+ const SwFormatAnchor& rOldAnch = pFormat->GetAnchor();
+ const SwFormatAnchor& rNewAnch = pShape->GetAnchor();
- const auto pOldCnt = rOldAnch.GetContentAnchor();
- const auto pNewCnt = rNewAnch.GetContentAnchor();
+ const auto pOldCnt = rOldAnch.GetContentAnchor();
+ const auto pNewCnt = rNewAnch.GetContentAnchor();
- const uno::Any aShapeHorRelOrient
- = uno::makeAny(pShape->GetHoriOrient().GetRelationOrient());
+ const uno::Any aShapeHorRelOrient
+ = uno::makeAny(pShape->GetHoriOrient().GetRelationOrient());
- if (isAnchorTypeDifferent(pShape))
+ if (isAnchorTypeDifferent(pShape) || (pObj && pObj != pShape->FindRealSdrObject()))
+ {
+ try
{
- try
+ ::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())
{
- ::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)
+ {
+ 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(text::TextContentAnchorType_AT_PAGE);
+ uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
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()));
+ pFormat->SetFormatAttr(rNewAnch);
}
- else if (rOldAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && pNewCnt)
+ }
+ else
+ {
+ if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
{
- 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);
- }
+ 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
{
- 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());
- }
+ xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
+ aShapeHorRelOrient);
+ pFormat->SetFormatAttr(pShape->GetAnchor());
}
}
- catch (uno::Exception& e)
- {
- SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
- }
}
-
- return doTextBoxPositioning(pShape) && DoTextBoxZOrderCorrection(pShape);
+ catch (uno::Exception& e)
+ {
+ SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
+ }
}
+
+ return doTextBoxPositioning(pShape, pObj) && DoTextBoxZOrderCorrection(pShape, pObj);
}
+
return false;
}
-bool SwTextBoxHelper::doTextBoxPositioning(SwFrameFormat* pShape)
+bool SwTextBoxHelper::doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pObj)
{
- if (isTextBoxShapeHasValidTextFrame(pShape))
+ const bool bIsGroupObj = (pObj != pShape->FindRealSdrObject()) && pObj;
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
{
- if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
+ ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
+ if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
{
- ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
- if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
- {
- tools::Rectangle aRect(getTextRectangle(pShape, false));
+ tools::Rectangle aRect(
+ getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), false));
- auto nLeftSpace = pShape->GetLRSpace().GetLeft();
+ auto nLeftSpace = pShape->GetLRSpace().GetLeft();
- SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
- aNewHOri.SetPos(aRect.Left() + nLeftSpace);
+ SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
+ aNewHOri.SetPos(aRect.Left() + nLeftSpace);
- SwFormatVertOrient aNewVOri(pFormat->GetVertOrient());
- aNewVOri.SetPos(aRect.Top() + pShape->GetVertOrient().GetPos());
+ SwFormatVertOrient aNewVOri(pFormat->GetVertOrient());
+ aNewVOri.SetPos(aRect.Top() + pShape->GetVertOrient().GetPos());
- // 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!");
+ // tdf#140598: Do not apply wrong rectangle position.
+ if (aRect.TopLeft() != Point(0, 0))
+ {
+ pFormat->SetFormatAttr(aNewHOri);
+ pFormat->SetFormatAttr(aNewVOri);
}
else
- {
- tools::Rectangle aRect(getTextRectangle(pShape, false));
-
- // tdf#140598: Do not apply wrong rectangle position.
- if (aRect.TopLeft() != Point(0, 0))
- {
- SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
- aNewHOri.SetPos(aNewHOri.GetPos() + aRect.Left());
- SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
- aNewVOri.SetPos(aNewVOri.GetPos() + aRect.Top());
+ SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
+ }
+ else
+ {
+ tools::Rectangle aRect(
+ getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), false));
- pFormat->SetFormatAttr(aNewHOri);
- pFormat->SetFormatAttr(aNewVOri);
- }
- else
- SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
+ // 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);
}
- return true;
+ else
+ SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
}
+ return true;
}
+
return false;
}
@@ -1307,52 +1324,59 @@ bool SwTextBoxHelper::isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShap
return false;
}
-bool SwTextBoxHelper::DoTextBoxZOrderCorrection(SwFrameFormat* pShape)
+bool SwTextBoxHelper::DoTextBoxZOrderCorrection(SwFrameFormat* pShape, SdrObject* pObj)
{
- if (isTextBoxShapeHasValidTextFrame(pShape))
+ // TODO: do this with group shape textboxes.
+ SdrObject* pShpObj = nullptr;
+ //if (pObj)
+ // pShpObj = pObj;
+ //else
+ pShpObj = pShape->FindRealSdrObject();
+
+ if (pShpObj)
{
- if (SdrObject* pShpObj = pShape->FindRealSdrObject())
+ if (SdrObject* pFrmObj
+ = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj)->FindRealSdrObject())
{
- if (SdrObject* pFrmObj
- = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT)->FindRealSdrObject())
+ // Get the draw model from the doc
+ SwDrawModel* pDrawModel
+ = pShape->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ if (pDrawModel)
{
- // Get the draw model from the doc
- SwDrawModel* pDrawModel
- = pShape->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
- if (pDrawModel)
- {
- // Not really sure this will work all page, but it seems it will.
- auto pPage = pDrawModel->GetPage(0);
- // Recalc all Zorders
- pPage->RecalcObjOrdNums();
- // If the shape is behind the frame, is good, but if there are some objects
- // between of them that is wrong so put the frame exactly one level higher
- // than the shape.
- if (pFrmObj->GetOrdNum() > pShpObj->GetOrdNum())
- pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pShpObj->GetOrdNum() + 1);
- else
- // Else, if the frame is behind the shape, bring to the front of it.
- while (pFrmObj->GetOrdNum() <= pShpObj->GetOrdNum())
- {
- pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pFrmObj->GetOrdNum() + 1);
- // If there is any problem with the indexes, do not run over the infinity
- if (pPage->GetObjCount() == pFrmObj->GetOrdNum())
- break;
- }
- pPage->RecalcObjOrdNums();
- return true; // Success
- }
- SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
- "No Valid Draw model for SdrObject for the shape!");
+ // Not really sure this will work all page, but it seems it will.
+ auto pPage = pDrawModel->GetPage(0);
+ // Recalc all Zorders
+ pPage->RecalcObjOrdNums();
+ // Here is a counter avoiding running to in infinity:
+ sal_uInt16 nIterator = 0;
+ // If the shape is behind the frame, is good, but if there are some objects
+ // between of them that is wrong so put the frame exactly one level higher
+ // than the shape.
+ if (pFrmObj->GetOrdNum() > pShpObj->GetOrdNum())
+ pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pShpObj->GetOrdNum() + 1);
+ else
+ // Else, if the frame is behind the shape, bring to the front of it.
+ while (pFrmObj->GetOrdNum() <= pShpObj->GetOrdNum())
+ {
+ pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pFrmObj->GetOrdNum() + 1);
+ // If there is any problem with the indexes, do not run over the infinity
+ if (pPage->GetObjCount() == pFrmObj->GetOrdNum())
+ break;
+ ++nIterator;
+ if (nIterator > 300)
+ break; // Do not run to infinity
+ }
+ pPage->RecalcObjOrdNums();
+ return true; // Success
}
SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
- "No Valid SdrObject for the frame!");
+ "No Valid Draw model for SdrObject for the shape!");
}
SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
- "No Valid SdrObject for the shape!");
+ "No Valid SdrObject for the frame!");
}
SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
- "No Valid TextFrame!");
+ "No Valid SdrObject for the shape!");
return false;
}
@@ -1369,14 +1393,10 @@ SwTextBoxNode::SwTextBoxNode(SwFrameFormat* pOwnerShape)
SwTextBoxNode::~SwTextBoxNode()
{
- // This only happens if the shape or the doc is in dtor.
- for (auto& rTextBoxEntry : m_pTextBoxes)
- {
- rTextBoxEntry.m_pDrawObject = nullptr;
- m_pOwnerShapeFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
- rTextBoxEntry.m_pTextBoxFormat);
- }
- m_pOwnerShapeFormat->SetOtherTextBoxFormat(nullptr);
+ m_pTextBoxes.clear();
+
+ if (m_pOwnerShapeFormat && m_pOwnerShapeFormat->GetOtherTextBoxFormat())
+ m_pOwnerShapeFormat->SetOtherTextBoxFormat(nullptr);
}
void SwTextBoxNode::AddTextBox(SdrObject* pDrawObject, SwFrameFormat* pNewTextBox)
@@ -1403,21 +1423,19 @@ void SwTextBoxNode::DelTextBox(SdrObject* pDrawObject)
assert(pDrawObject);
if (m_pTextBoxes.size())
{
- for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
+ for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end();)
{
if (it->m_pDrawObject == pDrawObject)
{
m_pOwnerShapeFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
it->m_pTextBoxFormat);
- m_pTextBoxes.erase(it);
+ it = m_pTextBoxes.erase(it);
break;
}
+ else
+ ++it;
}
}
- if (!m_pTextBoxes.size())
- {
- m_pOwnerShapeFormat->SetOtherTextBoxFormat(nullptr);
- }
}
SwFrameFormat* SwTextBoxNode::GetTextBox(const SdrObject* pDrawObject) const
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
index 383be2c56f51..7cd60ce197d0 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -1091,7 +1091,7 @@ static void lcl_textBoxSizeNotify(SwFrameFormat* pFormat)
SfxItemSet aResizeSet(pFormat->GetDoc()->GetAttrPool(), svl::Items<RES_FRM_SIZE, RES_FRM_SIZE>);
SwFormatFrameSize aSize;
aResizeSet.Put(aSize);
- SwTextBoxHelper::syncFlyFrameAttr(*pFormat, aResizeSet);
+ SwTextBoxHelper::syncFlyFrameAttr(*pFormat, aResizeSet, pFormat->FindRealSdrObject());
}
}
@@ -1249,6 +1249,12 @@ void SwDrawContact::Changed_( const SdrObject& rObj,
}
// use geometry of drawing object
aObjRect = pGroupObj->GetSnapRect();
+
+ for (size_t i = 0; i < pGroupObj->getChildrenOfSdrObject()->GetObjCount(); ++i )
+ {
+ SwTextBoxHelper::doTextBoxPositioning(GetFormat(), pGroupObj->getChildrenOfSdrObject()->GetObj(i));
+ }
+
}
SwTwips nXPosDiff(0);
SwTwips nYPosDiff(0);
@@ -1338,7 +1344,7 @@ void SwDrawContact::Changed_( const SdrObject& rObj,
// tdf#135198: keep text box together with its shape
SwRect aObjRect(rObj.GetSnapRect());
const SwPageFrame* rPageFrame = pAnchoredDrawObj->GetPageFrame();
- if (rPageFrame && rPageFrame->isFrameAreaPositionValid())
+ if (rPageFrame && rPageFrame->isFrameAreaPositionValid() && !rObj.getChildrenOfSdrObject())
{
SwDoc* const pDoc = GetFormat()->GetDoc();
@@ -1349,14 +1355,29 @@ void SwDrawContact::Changed_( const SdrObject& rObj,
const bool bEnableSetModified = pDoc->getIDocumentState().IsEnableSetModified();
pDoc->getIDocumentState().SetEnableSetModified(false);
- SfxItemSet aSyncSet(pDoc->GetAttrPool(),
- svl::Items<RES_VERT_ORIENT, RES_ANCHOR>);
+ SfxItemSet aSyncSet(
+ pDoc->GetAttrPool(),
+ svl::Items<RES_VERT_ORIENT, RES_HORI_ORIENT, RES_ANCHOR, RES_ANCHOR>);
+ aSyncSet.Put(GetFormat()->GetHoriOrient());
aSyncSet.Put(SwFormatVertOrient(aObjRect.Top() - rPageFrame->getFrameArea().Top(),
text::VertOrientation::NONE,
text::RelOrientation::PAGE_FRAME));
aSyncSet.Put(SwFormatAnchor(RndStdIds::FLY_AT_PAGE, pAnchoredDrawObj->GetPageFrame()->GetPhyPageNum()));
- SwTextBoxHelper::syncFlyFrameAttr(*GetFormat(), aSyncSet);
+ auto pSdrObj = const_cast<SdrObject*>(&rObj);
+ if (pSdrObj != GetFormat()->FindRealSdrObject())
+ {
+ SfxItemSet aSet(
+ pDoc->GetAttrPool(),
+ svl::Items<RES_FRM_SIZE, RES_FRM_SIZE>);
+
+ aSet.Put(aSyncSet);
+ aSet.Put(pSdrObj->GetMergedItem(RES_FRM_SIZE));
+ SwTextBoxHelper::syncFlyFrameAttr(*GetFormat(), aSet, pSdrObj);
+ SwTextBoxHelper::changeAnchor(GetFormat(), pSdrObj);
+ }
+ else
+ SwTextBoxHelper::syncFlyFrameAttr(*GetFormat(), aSyncSet, GetFormat()->FindRealSdrObject());
pDoc->getIDocumentState().SetEnableSetModified(bEnableSetModified);
}
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
index fb0e1f9c8294..33d6a83fb1f8 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -967,8 +967,16 @@ void SwDrawView::DeleteMarked()
SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj();
SwContact* pContact = GetUserCall(pObject);
SwFrameFormat* pFormat = pContact->GetFormat();
- if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
- aTextBoxesToDelete.push_back(pTextBox);
+ if (auto pChildren = pObject->getChildrenOfSdrObject())
+ {
+ for (size_t it = 0; it < pChildren->GetObjCount(); ++it)
+ if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(
+ pFormat, RES_DRAWFRMFMT, pChildren->GetObj(it)))
+ aTextBoxesToDelete.push_back(pTextBox);
+ }
+ else
+ if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
+ aTextBoxesToDelete.push_back(pTextBox);
}
if ( pDoc->DeleteSelection( *this ) )
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 1394c7b7469b..6e3792eb9f29 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -400,9 +400,9 @@ bool SwFEShell::CopyDrawSel( SwFEShell& rDestShell, const Point& rSttPt,
if (SwDrawFrameFormat *pDrawFormat = dynamic_cast<SwDrawFrameFormat*>(pFormat))
pDrawFormat->PosAttrSet();
}
- if (SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
+ if (SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, pObj))
{
- SwTextBoxHelper::syncFlyFrameAttr(*pFormat, pFormat->GetAttrSet());
+ SwTextBoxHelper::syncFlyFrameAttr(*pFormat, pFormat->GetAttrSet(), pObj);
}
if( bSelectInsert )
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
index c8fdf46bb185..a453e9906c65 100644
--- a/sw/source/core/frmedt/fefly1.cxx
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -446,7 +446,7 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt )
bool bTextBox = false;
if (rFormat.Which() == RES_DRAWFRMFMT)
{
- bTextBox = SwTextBoxHelper::isTextBox(&rFormat, RES_DRAWFRMFMT);
+ bTextBox = SwTextBoxHelper::isTextBox(&rFormat, RES_DRAWFRMFMT, pObj);
}
SwFlyFrame* pFly = nullptr;
@@ -471,8 +471,9 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt )
}
else if (bTextBox)
{
- auto pFlyFormat = dynamic_cast<const SwFlyFrameFormat*>(
- SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT));
+ auto pFlyFormat
+ = dynamic_cast<const SwFlyFrameFormat*>(SwTextBoxHelper::getOtherTextBoxFormat(
+ &rFormat, RES_DRAWFRMFMT, pObj ? pObj : rFormat.FindRealSdrObject()));
if (pFlyFormat)
{
pFly = pFlyFormat->GetFrame();
@@ -612,9 +613,20 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt )
new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch ));
}
rFormat.GetDoc()->SetAttr( aAnch, rFormat );
- if (SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT))
+ if (SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT,
+ pObj ? pObj : rFormat.FindRealSdrObject()))
{
- SwTextBoxHelper::syncFlyFrameAttr(rFormat, rFormat.GetAttrSet());
+ if (pObj->getChildrenOfSdrObject())
+ {
+ for (size_t i = 0;
+ i < pObj->getChildrenOfSdrObject()->GetObjCount(); ++i)
+ SwTextBoxHelper::changeAnchor(
+ &rFormat, pObj->getChildrenOfSdrObject()->GetObj(i));
+ }
+ else
+ SwTextBoxHelper::syncFlyFrameAttr(
+ rFormat, rFormat.GetAttrSet(),
+ pObj ? pObj : rFormat.FindRealSdrObject());
}
}
// #i28701# - no call of method
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index 2041bc4e7451..c55324d48150 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -1102,7 +1102,7 @@ void SwFEShell::SelectionToTop( bool bTop )
pPage->SetObjectOrdNum(pObj->GetOrdNum(), pObj->GetOrdNum() + nShift);
}
// The shape is on the right level, correct the layer of the frame
- SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat);
+ SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat, pObj);
}
GetDoc()->getIDocumentState().SetModified();
@@ -1152,7 +1152,7 @@ void SwFEShell::SelectionToBottom( bool bBottom )
}
}
// And set correct layer for the selected textbox.
- SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat);
+ SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat, pObj);
}
GetDoc()->getIDocumentState().SetModified();
@@ -1220,7 +1220,7 @@ void SwFEShell::ChangeOpaque( SdrLayerID nLayerId )
pFormat->SetFormatAttr( aOpa );
// If pObj has textframe, put its textframe to the right level
if (auto pTextBx = FindFrameFormat(pObj))
- SwTextBoxHelper::DoTextBoxZOrderCorrection(pTextBx);
+ SwTextBoxHelper::DoTextBoxZOrderCorrection(pTextBx, pObj);
}
}
}
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index adcc38806465..76c961168110 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -90,6 +90,7 @@
#include <hints.hxx>
#include <frameformats.hxx>
#include <unoprnms.hxx>
+#include <svx/svdpage.hxx>
#include <ndtxt.hxx>
@@ -2551,16 +2552,18 @@ SwFrameFormat::~SwFrameFormat()
auto pObj = FindRealSdrObject();
if (Which() == RES_FLYFRMFMT && pObj)
{
- // This is a fly-frame-format just del this
+ // This is a fly-frame-format just delete this
// textbox entry from the draw-frame-format.
m_pOtherTextBoxFormat->DelTextBox(pObj);
-
- // delete format after deleting the last textbox
- if (!m_pOtherTextBoxFormat->GetTextBoxCount())
- delete m_pOtherTextBoxFormat;
}
- m_pOtherTextBoxFormat = nullptr;
+ if (Which() == RES_DRAWFRMFMT)
+ {
+ // This format is the owner shape, so its time
+ // to del the textbox node.
+ delete m_pOtherTextBoxFormat;
+ m_pOtherTextBoxFormat = nullptr;
+ }
}
}
diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx
index 33b539949917..9f3bf54debb0 100644
--- a/sw/source/core/layout/flycnt.cxx
+++ b/sw/source/core/layout/flycnt.cxx
@@ -535,7 +535,7 @@ void SwFlyAtContentFrame::MakeAll(vcl::RenderContext* pRenderContext)
{
// get the text area of the shape
const tools::Rectangle aTextRectangle
- = SwTextBoxHelper::getTextRectangle(pShapeFormat, false);
+ = SwTextBoxHelper::getTextRectangle(pShapeFormat->FindRealSdrObject(), false);
// get the original textframe position
SwFormatHoriOrient aHOri = pShapeFormat->GetHoriOrient();
SwFormatVertOrient aVOri = pShapeFormat->GetVertOrient();
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index 260a1860d375..de72a0ec6076 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -375,8 +375,7 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, const Point &rBase,
// 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(pShape);
- tools::Long nXoffs = SwTextBoxHelper::getTextRectangle(pShape, false).Left();
+ tools::Rectangle aTextRectangle = SwTextBoxHelper::getTextRectangle(pSdrObj);
const auto aPos(pShape->GetAnchor().GetContentAnchor());
SwFormatVertOrient aVert(pTextBox->GetVertOrient());
@@ -385,7 +384,13 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, const Point &rBase,
// 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())
+ 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);
@@ -396,7 +401,7 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, const Point &rBase,
else
{
aVert.SetVertOrient(css::text::VertOrientation::NONE);
- aVert.SetPos(SwTextBoxHelper::getTextRectangle(pShape, false).Top());
+ aVert.SetPos(SwTextBoxHelper::getTextRectangle(pShape->FindRealSdrObject(), false).Top());
}
SwFormatAnchor aNewTxBxAnchor(pTextBox->GetAnchor());
diff --git a/sw/source/core/undo/undraw.cxx b/sw/source/core/undo/undraw.cxx
index fc7efcdfec70..8fd748dda95e 100644
--- a/sw/source/core/undo/undraw.cxx
+++ b/sw/source/core/undo/undraw.cxx
@@ -41,6 +41,7 @@
#include <dcontact.hxx>
#include <viewsh.hxx>
#include <frameformats.hxx>
+#include <textboxhelper.hxx>
struct SwUndoGroupObjImpl
{
@@ -196,6 +197,22 @@ void SwUndoDrawGroup::UndoImpl(::sw::UndoRedoContext &)
auto pObj = m_pObjArray[0].pObj;
pObj->SetUserCall(nullptr);
+ // This will store the textboxes what were owned by this group
+ std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
+ if (auto pOldTextBoxNode = pFormat->GetOtherTextBoxFormat())
+ {
+ if (auto pChildren = pObj->getChildrenOfSdrObject())
+ {
+ for (size_t idx = 0; idx < pChildren->GetObjCount(); idx++)
+ {
+ auto pChild = pChildren->GetObj(idx);
+
+ if (auto pTextBox = pOldTextBoxNode->GetTextBox(pChild))
+ vTextBoxes.push_back(std::pair(pChild, pTextBox));
+ }
+ }
+ }
+
::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
pFormat->RemoveAllUnos();
@@ -219,6 +236,18 @@ void SwUndoDrawGroup::UndoImpl(::sw::UndoRedoContext &)
// #i45718# - follow-up of #i35635# move object to visible layer
pContact->MoveObjToVisibleLayer( pObj );
+ for (auto& rElem : vTextBoxes)
+ {
+ if (rElem.first == pObj)
+ {
+ auto pNewTextBoxNode = new SwTextBoxNode(rSave.pFormat);
+ rSave.pFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
+ pNewTextBoxNode->AddTextBox(rElem.first, rElem.second);
+ rElem.second->SetOtherTextBoxFormat(pNewTextBoxNode);
+ break;
+ }
+ }
+
SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
// #i45952# - notify that position attributes are already set
@@ -237,6 +266,9 @@ void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
SwDoc* pDoc = m_pObjArray[0].pFormat->GetDoc();
SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
+ // This will store the textboxes from the ex-group-shapes
+ std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
+
for( sal_uInt16 n = 1; n < m_nSize; ++n )
{
SwUndoGroupObjImpl& rSave = m_pObjArray[n];
@@ -245,6 +277,13 @@ void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ // Save the textboxes
+ if (auto pOldTextBoxNode = rSave.pFormat->GetOtherTextBoxFormat())
+ {
+ if (auto pTextBox = pOldTextBoxNode->GetTextBox(pObj))
+ vTextBoxes.push_back(std::pair(pObj, pTextBox));
+ }
+
// object will destroy itself
pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
pObj->SetUserCall( nullptr );
@@ -268,6 +307,18 @@ void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
SwDrawFrameFormat* pDrawFrameFormat = m_pObjArray[0].pFormat;
+ // Restore the textboxes
+ if (vTextBoxes.size())
+ {
+ auto pNewTextBoxNode = new SwTextBoxNode(m_pObjArray[0].pFormat);
+ for (auto& rElem : vTextBoxes)
+ {
+ pNewTextBoxNode->AddTextBox(rElem.first, rElem.second);
+ rElem.second->SetOtherTextBoxFormat(pNewTextBoxNode);
+ }
+ m_pObjArray[0].pFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
+ }
+
// #i45952# - notify that position attributes are already set
OSL_ENSURE(pDrawFrameFormat,
"<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
@@ -339,6 +390,9 @@ void SwUndoDrawUnGroup::UndoImpl(::sw::UndoRedoContext & rContext)
SwDoc *const pDoc = & rContext.GetDoc();
SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
+ // This will store the textboxes what were owned by this group
+ std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
+
// remove from array
for( sal_uInt16 n = 1; n < m_nSize; ++n )
{
@@ -346,6 +400,23 @@ void SwUndoDrawUnGroup::UndoImpl(::sw::UndoRedoContext & rContext)
::lcl_SaveAnchor( rSave.pFormat, rSave.nNodeIdx );
+ // copy the textboxes for later use to this vector
+ if (auto pTxBxNd = rSave.pFormat->GetOtherTextBoxFormat())
+ {
+ if (auto pGroupObj = m_pObjArray[0].pObj)
+ {
+ if (auto pChildren = pGroupObj->getChildrenOfSdrObject())
+ {
+ for (size_t idx = 0; idx < pChildren->GetObjCount(); idx++)
+ {
+ auto pChild = pChildren->GetObj(idx);
+ if (auto pTextBox = pTxBxNd->GetTextBox(pChild))
+ vTextBoxes.push_back(std::pair(pChild, pTextBox));
+ }
+ }
+ }
+ }
+
rSave.pFormat->RemoveAllUnos();
rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), rSave.pFormat ));
@@ -362,6 +433,19 @@ void SwUndoDrawUnGroup::UndoImpl(::sw::UndoRedoContext & rContext)
SwDrawFrameFormat* pDrawFrameFormat = m_pObjArray[0].pFormat;
+ // Restore the vector content for the new formats
+ if (vTextBoxes.size())
+ {
+ auto pNewTxBxNd = new SwTextBoxNode(m_pObjArray[0].pFormat);
+ for (auto& rElem : vTextBoxes)
+ {
+ pNewTxBxNd->AddTextBox(rElem.first, rElem.second);
+ rElem.second->SetOtherTextBoxFormat(pNewTxBxNd);
+ }
+ m_pObjArray[0].pFormat->SetOtherTextBoxFormat(pNewTxBxNd);
+ }
+
+
// #i45952# - notify that position attributes are already set
OSL_ENSURE(pDrawFrameFormat,
"<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
@@ -380,6 +464,19 @@ void SwUndoDrawUnGroup::RedoImpl(::sw::UndoRedoContext &)
::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
+ // Store the textboxes in this vector for later use.
+ std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
+ if (auto pTextBoxNode = pFormat->GetOtherTextBoxFormat())
+ {
+ auto pMasterObj = m_pObjArray[0].pObj;
+
+ if (auto pObjList = pMasterObj->getChildrenOfSdrObject())
+ for (size_t idx = 0; idx < pObjList->GetObjCount(); idx++)
+ {
+ vTextBoxes.push_back(std::pair(pObjList->GetObj(idx), pTextBoxNode->GetTextBox(pObjList->GetObj(idx))));
+ }
+ }
+
pFormat->RemoveAllUnos();
// remove from array
@@ -396,6 +493,19 @@ void SwUndoDrawUnGroup::RedoImpl(::sw::UndoRedoContext &)
SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
+ // Restore the textboxes for the restored group shape.
+ for (auto& pElem : vTextBoxes)
+ {
+ if (pElem.first == rSave.pObj)
+ {
+ auto pTmpTxBxNd = new SwTextBoxNode(rSave.pFormat);
+ pTmpTxBxNd->AddTextBox(rSave.pObj, pElem.second);
+ pFormat->SetOtherTextBoxFormat(pTmpTxBxNd);
+ pElem.second->SetOtherTextBoxFormat(pTmpTxBxNd);
+ break;
+ }
+ }
+
// #i45952# - notify that position attributes are already set
OSL_ENSURE(pDrawFrameFormat,
"<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx
index 1ed8ec3a5d2e..580553dbf8a2 100644
--- a/sw/source/core/unocore/unodraw.cxx
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -949,6 +949,7 @@ void SwXShape::AddExistingShapeToFormat( SdrObject const & _rObj )
SwXShape::~SwXShape()
{
SolarMutexGuard aGuard;
+
if (m_xShapeAgg.is())
{
uno::Reference< uno::XInterface > xRef;
@@ -1505,7 +1506,11 @@ uno::Any SwXShape::getPropertyValue(const OUString& rPropertyName)
}
else if (pEntry->nWID == FN_TEXT_BOX)
{
- bool bValue = SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT);
+ auto pSvxShape = GetSvxShape();
+ bool bValue = SwTextBoxHelper::isTextBox(
+ pFormat, RES_DRAWFRMFMT,
+ ((pSvxShape && pSvxShape->GetSdrObject()) ? pSvxShape->GetSdrObject()
+ : pFormat->FindRealSdrObject()));
aRet <<= bValue;
}
else if (pEntry->nWID == RES_CHAIN)
diff --git a/sw/source/uibase/shells/drawsh.cxx b/sw/source/uibase/shells/drawsh.cxx
index beb197c87fa9..52a3b0d02beb 100644
--- a/sw/source/uibase/shells/drawsh.cxx
+++ b/sw/source/uibase/shells/drawsh.cxx
@@ -498,7 +498,7 @@ void SwDrawShell::GetState(SfxItemSet& rSet)
{
SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
// Allow creating a TextBox only in case this is a draw format without a TextBox so far.
- if (pFrameFormat && pFrameFormat->Which() == RES_DRAWFRMFMT && !SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT))
+ if (pFrameFormat && pFrameFormat->Which() == RES_DRAWFRMFMT && !SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj))
{
if (SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>( pObj) )
{
@@ -521,7 +521,7 @@ void SwDrawShell::GetState(SfxItemSet& rSet)
{
SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
// Allow removing a TextBox only in case it has one.
- if (pFrameFormat && SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT))
+ if (pFrameFormat && SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj))
bDisable = false;
}
More information about the Libreoffice-commits
mailing list