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@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx
index 3cd442e..978cf77 100644
--- a/sw/inc/textboxhelper.hxx
+++ b/sw/inc/textboxhelper.hxx
@@ -69,10 +69,10 @@
/// 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 @@
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 @@
/// 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 @@
// 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 @@
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 08e59b7..61265e2 100644
--- a/sw/qa/uitest/writer_tests7/tdf143574.py
+++ b/sw/qa/uitest/writer_tests7/tdf143574.py
@@ -33,7 +33,6 @@
# 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 1e071ef..4cee8ad 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 @@
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())
auto pObj = rSource.FindRealSdrObject();
auto pTextBoxNd = new SwTextBoxNode(pDest);
pDest->SetOtherTextBoxFormat(pTextBoxNd);
if (pObj)
{
// AS_CHAR *must not* be set on textbox fly-frame
boxAnchor.SetType(RndStdIds::FLY_AT_CHAR);
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);
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);
}
if (!bIsGroupObj)
break;
}
}
// 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);
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
auto pTextBox = new SwTextBoxNode(pDest);
pTextBox->AddTextBox(pDest->FindRealSdrObject(), pDestTextBox);
pDest->SetOtherTextBoxFormat(pTextBox);
pDestTextBox->SetOtherTextBoxFormat(pTextBox);
}
if (pDest->GetName().isEmpty())
diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx
index 609b174..0aff4b89 100644
--- a/sw/source/core/doc/docdraw.cxx
+++ b/sw/source/core/doc/docdraw.cxx
@@ -208,6 +208,8 @@
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 @@
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 @@
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 @@
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 @@
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 6ff9bf9..d8fe293c 100644
--- a/sw/source/core/doc/docfly.cxx
+++ b/sw/source/core/doc/docfly.cxx
@@ -577,7 +577,7 @@
getIDocumentState().SetModified();
SwTextBoxHelper::syncFlyFrameAttr(rFlyFormat, rSet);
//SwTextBoxHelper::syncFlyFrameAttr(rFlyFormat, rSet);
return bRet;
}
@@ -924,7 +924,7 @@
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 16ad4d8..d2ccfaf8 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -483,8 +483,11 @@
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 3858da3..93b9564 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -61,9 +61,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
// 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 @@
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 @@
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 @@
}
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 @@
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 @@
case MID_ANCHOR_ANCHORTYPE:
{
setWrapThrough(pShape);
changeAnchor(pShape);
doTextBoxPositioning(pShape);
changeAnchor(pShape, pObj);
doTextBoxPositioning(pShape, pObj);
return;
}
@@ -844,7 +848,9 @@
// 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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
} 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 @@
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 @@
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 auto pOldCnt = rOldAnch.GetContentAnchor();
const auto pNewCnt = rNewAnch.GetContentAnchor();
const uno::Any aShapeHorRelOrient
= uno::makeAny(pShape->GetHoriOrient().GetRelationOrient());
if (isAnchorTypeDifferent(pShape) || (pObj && pObj != pShape->FindRealSdrObject()))
{
const SwFormatAnchor& rOldAnch = pFormat->GetAnchor();
const SwFormatAnchor& rNewAnch = pShape->GetAnchor();
const auto pOldCnt = rOldAnch.GetContentAnchor();
const auto pNewCnt = rNewAnch.GetContentAnchor();
const uno::Any aShapeHorRelOrient
= uno::makeAny(pShape->GetHoriOrient().GetRelationOrient());
if (isAnchorTypeDifferent(pShape))
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_PAGE);
xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
aShapeHorRelOrient);
uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
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(mapAnchorType(rNewAnch.GetAnchorId()));
xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
aShapeHorRelOrient);
xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
pFormat->SetFormatAttr(rNewAnch);
}
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());
}
uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
aShapeHorRelOrient);
xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
pFormat->SetFormatAttr(rNewAnch);
}
}
catch (uno::Exception& e)
else
{
SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
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());
}
}
}
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(pObj ? pObj : pShape->FindRealSdrObject(), false));
auto nLeftSpace = pShape->GetLRSpace().GetLeft();
SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
aNewHOri.SetPos(aRect.Left() + nLeftSpace);
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))
{
tools::Rectangle aRect(getTextRectangle(pShape, false));
auto nLeftSpace = pShape->GetLRSpace().GetLeft();
SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
aNewHOri.SetPos(aRect.Left() + nLeftSpace);
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!");
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());
pFormat->SetFormatAttr(aNewHOri);
pFormat->SetFormatAttr(aNewVOri);
}
else
SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
}
return true;
SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
}
else
{
tools::Rectangle aRect(
getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), false));
// 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;
}
return false;
}
@@ -1307,52 +1324,59 @@
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()
{
// 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 @@
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 383be2c..7cd60ce 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -1091,7 +1091,7 @@
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 @@
}
// 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 @@
// 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 @@
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 fb0e1f9..33d6a83 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -967,8 +967,16 @@
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 1394c7b..6e3792e 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -400,9 +400,9 @@
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 c8fdf46..a453e99 100644
--- a/sw/source/core/frmedt/fefly1.cxx
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -446,7 +446,7 @@
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 @@
}
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 @@
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 2041bc4..c55324d 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -1102,7 +1102,7 @@
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 @@
}
}
// And set correct layer for the selected textbox.
SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat);
SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat, pObj);
}
GetDoc()->getIDocumentState().SetModified();
@@ -1220,7 +1220,7 @@
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 adcc388..76c9611 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 @@
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 33b53994..9f3bf54 100644
--- a/sw/source/core/layout/flycnt.cxx
+++ b/sw/source/core/layout/flycnt.cxx
@@ -535,7 +535,7 @@
{
// 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 260a186..de72a0e 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -375,8 +375,7 @@
// 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 @@
// 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 @@
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 fc7efcd..8fd748d 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 @@
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 @@
// #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 @@
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 @@
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 @@
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 @@
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 @@
::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 @@
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 @@
::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 @@
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 1ed8ec3..580553d 100644
--- a/sw/source/core/unocore/unodraw.cxx
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -949,6 +949,7 @@
SwXShape::~SwXShape()
{
SolarMutexGuard aGuard;
if (m_xShapeAgg.is())
{
uno::Reference< uno::XInterface > xRef;
@@ -1505,7 +1506,11 @@
}
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 beb197c..52a3b0d 100644
--- a/sw/source/uibase/shells/drawsh.cxx
+++ b/sw/source/uibase/shells/drawsh.cxx
@@ -498,7 +498,7 @@
{
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 @@
{
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;
}