[Libreoffice-commits] core.git: sw/inc sw/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Fri Apr 9 13:20:31 UTC 2021
sw/inc/dcontact.hxx | 4 +--
sw/source/core/draw/dcontact.cxx | 42 ++++++++++++++++++++++++++++++--------
sw/source/core/layout/frmtool.cxx | 2 -
3 files changed, 37 insertions(+), 11 deletions(-)
New commits:
commit c2eae4998b3ae79210ef0b5c064e9833218c22de
Author: Michael Stahl <michael.stahl at allotropia.de>
AuthorDate: Fri Apr 9 12:08:24 2021 +0200
Commit: Michael Stahl <michael.stahl at allotropia.de>
CommitDate: Fri Apr 9 15:19:50 2021 +0200
tdf#141549 sw: fix ordering of virtual SdrObjects for textboxes
In header/footer it turns out that not only can the text box be inserted
after the shape, it can also be inserted before the shape.
This is because SwDrawFrameFormat::MakeFrames() ends up first destroying
all the SwDrawVirtObj and then creating them from scratch again, while
the SwVirtFlyDrawObj survives.
4 SwDrawContact::DisconnectFromLayout(bool) (this=0x6ed0200, _bMoveMasterToInvisibleLayer=false) at sw/source/core/draw/dcontact.cxx:1664
5 SwDrawContact::ConnectToLayout(SwFormatAnchor const*) (this=0x6ed0200, pAnch=0x0) at sw/source/core/draw/dcontact.cxx:1791
6 SwDrawContact::SwClientNotify(SwModify const&, SfxHint const&) (this=0x6ed0200, rMod=..., rHint=...) at sw/source/core/draw/dcontact.cxx:1521
7 SwModify::CallSwClientNotify(SfxHint const&) const (this=0x6ecfd80, rHint=...) at sw/source/core/attr/calbck.cxx:321
8 sw::BroadcastingModify::CallSwClientNotify(SfxHint const&) const (this=0x6ecfd80, rHint=...) at sw/source/core/attr/calbck.cxx:326
9 SwDrawFrameFormat::MakeFrames() (this=0x6ecfd80) at sw/source/core/layout/atrfrm.cxx:3394
10 AppendAllObjs(SwFrameFormats const*, SwFrame const*) (pTable=0x69c1920, pSib=0x38c6100) at sw/source/core/layout/frmtool.cxx:1349
11 InsertCnt_(SwLayoutFrame*, SwDoc*, unsigned long, bool, unsigned long, SwFrame*, sw::FrameMode) (pLay=0x6be4320, pDoc=0x69af7c0, nIndex=157, bPages=true, nEndIndex=0, pPrv=0x6baedc0, eMode=sw::FrameMode::New) at sw/source/core/layout/frmtool.cxx:1927
Fix this by searching for the existing SwVirtFlyDrawObj in
SwDrawVirtObj::AddToDrawingPage().
(regression from 3bc8f90e9693f710f12632f69b9348c1c833c906)
Change-Id: Ic00878685ab16018c9331190f1e80f874c1a9a4e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113844
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>
diff --git a/sw/inc/dcontact.hxx b/sw/inc/dcontact.hxx
index 52893220dde9..c596a61e4980 100644
--- a/sw/inc/dcontact.hxx
+++ b/sw/inc/dcontact.hxx
@@ -251,7 +251,7 @@ class SwDrawVirtObj final : public SdrVirtObj
void RemoveFromWriterLayout();
/// connection to drawing layer
- void AddToDrawingPage();
+ void AddToDrawingPage(SwFrame const& rAnchorFrame);
void RemoveFromDrawingPage();
/** is 'virtual' drawing object connected to writer layout and
@@ -401,7 +401,7 @@ class SAL_DLLPUBLIC_RTTI SwDrawContact final : public SwContact
/// Moves all SW-connections to new Master)
void ChangeMasterObject( SdrObject *pNewMaster );
- SwDrawVirtObj* AddVirtObj();
+ SwDrawVirtObj* AddVirtObj(SwFrame const& rAnchorFrame);
void NotifyBackgrdOfAllVirtObjs( const tools::Rectangle* pOldBoundRect );
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
index 11687c41d0d5..f45d7278d59c 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -827,7 +827,7 @@ SwFrame* SwDrawContact::GetAnchorFrame(SdrObject const *const pDrawObj)
/** add a 'virtual' drawing object to drawing page.
*/
-SwDrawVirtObj* SwDrawContact::AddVirtObj()
+SwDrawVirtObj* SwDrawContact::AddVirtObj(SwFrame const& rAnchorFrame)
{
maDrawVirtObjs.push_back(
SwDrawVirtObjPtr(
@@ -835,7 +835,7 @@ SwDrawVirtObj* SwDrawContact::AddVirtObj()
GetMaster()->getSdrModelFromSdrObject(),
*GetMaster(),
*this)));
- maDrawVirtObjs.back()->AddToDrawingPage();
+ maDrawVirtObjs.back()->AddToDrawingPage(rAnchorFrame);
return maDrawVirtObjs.back().get();
}
@@ -1926,7 +1926,7 @@ void SwDrawContact::ConnectToLayout( const SwFormatAnchor* pAnch )
else
{
// append 'virtual' drawing object
- SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
+ SwDrawVirtObj* pDrawVirtObj = AddVirtObj(*pFrame);
if ( pAnch->GetAnchorId() == RndStdIds::FLY_AS_CHAR )
{
ClrContourCache( pDrawVirtObj );
@@ -2274,30 +2274,56 @@ void SwDrawVirtObj::RemoveFromWriterLayout()
}
}
-void SwDrawVirtObj::AddToDrawingPage()
+void SwDrawVirtObj::AddToDrawingPage(SwFrame const& rAnchorFrame)
{
// determine 'master'
SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
// insert 'virtual' drawing object into page, set layer and user call.
SdrPage* pDrawPg = pOrgMasterSdrObj->getSdrPageFromSdrObject();
+ // default: insert before master object
+ auto NOTM_nOrdNum(GetReferencedObj().GetOrdNum());
+
+ // maintain invariant that a shape's textbox immediately follows the shape
+ // also for the multiple SdrDrawVirtObj created for shapes in header/footer
+ if (SwFrameFormat const*const pFlyFormat =
+ SwTextBoxHelper::getOtherTextBoxFormat(mrDrawContact.GetFormat(), RES_DRAWFRMFMT))
+ {
+ // this is for the case when the flyframe SdrVirtObj is created before the draw one
+ if (SwSortedObjs const*const pObjs = rAnchorFrame.GetDrawObjs())
+ {
+ for (SwAnchoredObject const*const pAnchoredObj : *pObjs)
+ {
+ if (&pAnchoredObj->GetFrameFormat() == pFlyFormat)
+ {
+ assert(dynamic_cast<SwFlyFrame const*>(pAnchoredObj));
+ NOTM_nOrdNum = pAnchoredObj->GetDrawObj()->GetOrdNum();
+ // the master SdrObj should have the highest index
+ assert(NOTM_nOrdNum < GetReferencedObj().GetOrdNum());
+ break;
+ }
+ }
+ }
+ // this happens on initial insertion, the draw object is created first
+ SAL_INFO_IF(GetReferencedObj().GetOrdNum() == NOTM_nOrdNum, "sw", "AddToDrawingPage: cannot find SdrObject for text box's shape");
+ }
+
// #i27030# - apply order number of referenced object
if ( nullptr != pDrawPg )
{
// #i27030# - apply order number of referenced object
- pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
+ pDrawPg->InsertObject(this, NOTM_nOrdNum);
}
else
{
pDrawPg = getSdrPageFromSdrObject();
if ( pDrawPg )
{
- pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
- GetReferencedObj().GetOrdNum() );
+ pDrawPg->SetObjectOrdNum(GetOrdNumDirect(), NOTM_nOrdNum);
}
else
{
- SetOrdNum( GetReferencedObj().GetOrdNum() );
+ SetOrdNum(NOTM_nOrdNum);
}
}
SetUserCall( &mrDrawContact );
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 2d5131c4e658..557bc2414e63 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -1027,7 +1027,7 @@ void AppendObj(SwFrame *const pFrame, SwPageFrame *const pPage, SwFrameFormat *c
pNew->GetAnchorFrame() != pFrame &&
!pNew->GetDrawObjectByAnchorFrame( *pFrame ) )
{
- SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
+ SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(*pFrame);
pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
pDrawVirtObj->ActionChanged();
More information about the Libreoffice-commits
mailing list