tdf#132810 Prevent crashes with gallery objects
The problem is the formats for the gallery objects
may be non-existent but the code attempts to use
them anyway, causing crashes. The fix is to check
for the existence of the proper format objects
before using them, so as to prevent the crashes.
I tested creating/deleting multiple objects with
multiple rounds of undo/redo and believe this change
to cover all the crashes that can occur (there were
several).
Change-Id: I9d5d704eaa381be861ac1758ad58269706437a27
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161950
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162078
diff --git a/sw/inc/anchoredobject.hxx b/sw/inc/anchoredobject.hxx
index 19cd2e7..9af1984 100644
--- a/sw/inc/anchoredobject.hxx
+++ b/sw/inc/anchoredobject.hxx
@@ -318,6 +318,7 @@ class SW_DLLPUBLIC SwAnchoredObject
void SetCurrRelPos( Point _aRelPos );
// accessors to the format
bool HasFrameFormat() const;
virtual SwFrameFormat& GetFrameFormat() = 0;
virtual const SwFrameFormat& GetFrameFormat() const = 0;
diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx
index aecbe2a..521ca2b 100644
--- a/sw/source/core/doc/docdraw.cxx
+++ b/sw/source/core/doc/docdraw.cxx
@@ -463,14 +463,17 @@ bool SwDoc::DeleteSelection( SwDrawView& rDrawView )
SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
if( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr )
{
SwDrawContact *pC = static_cast<SwDrawContact*>(GetUserCall(pObj));
SwDrawFrameFormat *pFrameFormat = static_cast<SwDrawFrameFormat*>(pC->GetFormat());
if( pFrameFormat &&
RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId() )
if (SwDrawContact* pC = static_cast<SwDrawContact*>(GetUserCall(pObj)))
{
rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), true );
--i;
getIDocumentLayoutAccess().DelLayoutFormat( pFrameFormat );
SwDrawFrameFormat* pFrameFormat
= static_cast<SwDrawFrameFormat*>(pC->GetFormat());
if (pFrameFormat
&& RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId())
{
rDrawView.MarkObj(pObj, rDrawView.Imp().GetPageView(), true);
--i;
getIDocumentLayoutAccess().DelLayoutFormat(pFrameFormat);
}
}
}
}
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
index 9d70464..2bd1aca 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -977,16 +977,19 @@ void SwDrawView::DeleteMarked()
{
SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj();
SwContact* pContact = GetUserCall(pObject);
SwFrameFormat* pFormat = pContact->GetFormat();
if (pObject->getChildrenOfSdrObject())
if (pContact)
{
auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, pFormat);
for (auto& rChildTextBox : pChildTextBoxes)
aTextBoxesToDelete.push_back(rChildTextBox);
}
else
if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
SwFrameFormat* pFormat = pContact->GetFormat();
if (pObject->getChildrenOfSdrObject())
{
auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, pFormat);
for (auto& rChildTextBox : pChildTextBoxes)
aTextBoxesToDelete.push_back(rChildTextBox);
}
else if (SwFrameFormat* pTextBox
= SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
aTextBoxesToDelete.push_back(pTextBox);
}
}
if ( pDoc->DeleteSelection( *this ) )
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index 9a18e79..30e448d 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -2221,14 +2221,16 @@ RndStdIds SwFEShell::GetAnchorId() const
nRet = RndStdIds::UNKNOWN;
break;
}
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
RndStdIds nId = pContact->GetFormat()->GetAnchor().GetAnchorId();
if ( nRet == RndStdIds(SHRT_MAX) )
nRet = nId;
else if ( nRet != nId )
if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
{
nRet = RndStdIds::UNKNOWN;
break;
RndStdIds nId = pContact->GetFormat()->GetAnchor().GetAnchorId();
if (nRet == RndStdIds(SHRT_MAX))
nRet = nId;
else if (nRet != nId)
{
nRet = RndStdIds::UNKNOWN;
break;
}
}
}
}
@@ -3152,17 +3154,19 @@ Color SwFEShell::GetShapeBackground() const
OSL_ENSURE( dynamic_cast<const SwVirtFlyDrawObj*>( pSdrObj) == nullptr, "wrong usage of SwFEShell::GetShapeBackground - selected object is not a drawing object!");
if ( dynamic_cast<const SwVirtFlyDrawObj*>( pSdrObj) == nullptr )
{
// determine page frame of the frame the shape is anchored.
const SwFrame* pAnchorFrame =
static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrame( pSdrObj );
OSL_ENSURE( pAnchorFrame, "inconsistent model - no anchor at shape!");
if ( pAnchorFrame )
if (SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall(pSdrObj)))
{
const SwPageFrame* pPageFrame = pAnchorFrame->FindPageFrame();
OSL_ENSURE( pPageFrame, "inconsistent model - no page!");
if ( pPageFrame )
// determine page frame of the frame the shape is anchored.
const SwFrame * pAnchorFrame = pDrawContact->GetAnchorFrame(pSdrObj);
OSL_ENSURE(pAnchorFrame, "inconsistent model - no anchor at shape!");
if (pAnchorFrame)
{
aRetColor = pPageFrame->GetDrawBackgroundColor();
const SwPageFrame* pPageFrame = pAnchorFrame->FindPageFrame();
OSL_ENSURE(pPageFrame, "inconsistent model - no page!");
if (pPageFrame)
{
aRetColor = pPageFrame->GetDrawBackgroundColor();
}
}
}
}
diff --git a/sw/source/core/layout/anchoredobject.cxx b/sw/source/core/layout/anchoredobject.cxx
index 42e7dd3..fe959a6 100644
--- a/sw/source/core/layout/anchoredobject.cxx
+++ b/sw/source/core/layout/anchoredobject.cxx
@@ -32,6 +32,7 @@
#include <layouter.hxx>
#include <osl/diagnose.h>
#include <flyfrms.hxx>
#include <dcontact.hxx>
using namespace ::com::sun::star;
@@ -98,6 +99,8 @@ void SwAnchoredObject::ClearVertPosOrientFrame()
}
}
bool SwAnchoredObject::HasFrameFormat() const { return GetUserCall(GetDrawObj()); }
SwAnchoredObject::~SwAnchoredObject()
{
ClearVertPosOrientFrame();
@@ -408,29 +411,33 @@ bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const
{
bool bRet( false );
const SwFrameFormat& rObjFormat = GetFrameFormat();
if (HasFrameFormat())
{
const SwFrameFormat& rObjFormat = GetFrameFormat();
// --> #i3317# - add condition <IsTmpConsiderWrapInfluence()>
// --> #i55204#
// - correction: wrapping style influence has been considered, if condition
// <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type
// or its wrapping style.
if ( IsTmpConsiderWrapInfluence() )
{
bRet = true;
}
else if ( rObjFormat.getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
{
const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor();
if ( ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) ||
(rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)) &&
rObjFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH )
// --> #i3317# - add condition <IsTmpConsiderWrapInfluence()>
// --> #i55204#
// - correction: wrapping style influence has been considered, if condition
// <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type
// or its wrapping style.
if (IsTmpConsiderWrapInfluence())
{
// --> #i34520# - text also wraps around anchored
// objects in the layer Hell - see the text formatting.
// Thus, it hasn't to be checked here.
bRet = true;
}
else if (rObjFormat.getIDocumentSettingAccess().get(
DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION))
{
const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor();
if (((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
|| (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA))
&& rObjFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH)
{
// --> #i34520# - text also wraps around anchored
// objects in the layer Hell - see the text formatting.
// Thus, it hasn't to be checked here.
bRet = true;
}
}
}
return bRet;
@@ -567,18 +574,23 @@ const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const
if ( !mbObjRectWithSpacesValid )
{
maObjRectWithSpaces = GetObjBoundRect();
const SwFrameFormat& rFormat = GetFrameFormat();
const SvxULSpaceItem& rUL = rFormat.GetULSpace();
const SvxLRSpaceItem& rLR = rFormat.GetLRSpace();
if (HasFrameFormat())
{
maObjRectWithSpaces.Top ( std::max( maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), tools::Long(0) ));
maObjRectWithSpaces.Left( std::max( maObjRectWithSpaces.Left()- rLR.GetLeft(), tools::Long(0) ));
maObjRectWithSpaces.AddHeight(rUL.GetLower() );
maObjRectWithSpaces.AddWidth(rLR.GetRight() );
}
const SwFrameFormat& rFormat = GetFrameFormat();
const SvxULSpaceItem& rUL = rFormat.GetULSpace();
const SvxLRSpaceItem& rLR = rFormat.GetLRSpace();
{
maObjRectWithSpaces.Top(std::max(
maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), tools::Long(0)));
maObjRectWithSpaces.Left(
std::max(maObjRectWithSpaces.Left() - rLR.GetLeft(), tools::Long(0)));
maObjRectWithSpaces.AddHeight(rUL.GetLower());
maObjRectWithSpaces.AddWidth(rLR.GetRight());
}
mbObjRectWithSpacesValid = true;
maLastObjRect = GetObjRect();
mbObjRectWithSpacesValid = true;
maLastObjRect = GetObjRect();
}
}
return maObjRectWithSpaces;
@@ -709,39 +721,43 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame()
// --> #i44339# - check, if anchor frame exists.
if ( mpAnchorFrame )
{
const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor();
if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) ||
(rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR))
if (HasFrameFormat())
{
SwTextFrame *const pFrame(static_cast<SwTextFrame*>(AnchorFrame()));
TextFrameIndex const nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor()));
pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset);
}
else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame())
{
// See if this fly is split. If so, then the anchor is also split. All anchors are
// empty, except the last follow.
if (pFlyFrame->IsFlySplitAllowed())
const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor();
if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
|| (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR))
{
auto pFlyAtContentFrame = static_cast<SwFlyAtContentFrame*>(pFlyFrame);
SwFlyAtContentFrame* pFly = pFlyAtContentFrame;
SwTextFrame* pAnchor = static_cast<SwTextFrame*>(AnchorFrame());
// If we have to jump back N frames to find the master fly, then we have to step N
// frames from the master anchor to reach the correct follow anchor.
while (pFly->GetPrecede())
SwTextFrame* const pFrame(static_cast<SwTextFrame*>(AnchorFrame()));
TextFrameIndex const nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor()));
pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset);
}
else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame())
{
// See if this fly is split. If so, then the anchor is also split. All anchors are
// empty, except the last follow.
if (pFlyFrame->IsFlySplitAllowed())
{
pFly = pFly->GetPrecede();
if (!pAnchor)
auto pFlyAtContentFrame = static_cast<SwFlyAtContentFrame*>(pFlyFrame);
SwFlyAtContentFrame* pFly = pFlyAtContentFrame;
SwTextFrame* pAnchor = static_cast<SwTextFrame*>(AnchorFrame());
// If we have to jump back N frames to find the master fly, then we have to step N
// frames from the master anchor to reach the correct follow anchor.
while (pFly->GetPrecede())
{
SAL_WARN("sw.layout", "SwAnchoredObject::FindAnchorCharFrame: fly chain "
"length is longer then anchor chain length");
break;
pFly = pFly->GetPrecede();
if (!pAnchor)
{
SAL_WARN("sw.layout",
"SwAnchoredObject::FindAnchorCharFrame: fly chain "
"length is longer then anchor chain length");
break;
}
pAnchor = pAnchor->GetFollow();
}
pAnchor = pAnchor->GetFollow();
}
if (pAnchor)
{
pAnchorCharFrame = pAnchor;
if (pAnchor)
{
pAnchorCharFrame = pAnchor;
}
}
}
}
@@ -758,7 +774,9 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame()
*/
bool SwAnchoredObject::IsFormatPossible() const
{
return GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetDrawObj()->GetLayer() );
if (HasFrameFormat())
return GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetDrawObj()->GetLayer() );
return false;
}
bool SwAnchoredObject::IsDraggingOffPageAllowed(const SwFrameFormat* pFrameFormat)
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 457a0d4..66e27ad 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -1140,8 +1140,9 @@ void SwPageFrame::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj )
}
if ( GetUpper() )
{
if (RndStdIds::FLY_AS_CHAR !=
_rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId())
if (_rToRemoveObj.HasFrameFormat()
&& RndStdIds::FLY_AS_CHAR
!= _rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId())
{
static_cast<SwRootFrame*>(GetUpper())->SetSuperfluous();
InvalidatePage();
@@ -1454,63 +1455,67 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove )
}
else
{
const SwDrawContact *pC = static_cast<const SwDrawContact*>(GetUserCall(pSdrObj));
const SwFrameFormat *pFormat = pC->GetFormat();
const SwFormatAnchor &rAnch = pFormat->GetAnchor();
if ( RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId() )
if (const SwDrawContact* pC = static_cast<const SwDrawContact*>(GetUserCall(pSdrObj)))
{
const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj );
if( !pAnchorFrame )
const SwFrameFormat* pFormat = pC->GetFormat();
const SwFormatAnchor& rAnch = pFormat->GetAnchor();
if (RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId())
{
OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." );
const_cast<SwDrawContact*>(pC)->ConnectToLayout();
pAnchorFrame = pC->GetAnchorFrame();
}
const SwFrame* pUp = pAnchorFrame->GetUpper();
rRect = pUp->getFramePrintArea();
rRect += pUp->getFrameArea().Pos();
SwRectFnSet aRectFnSet(pAnchorFrame);
tools::Long nHeight = (9*aRectFnSet.GetHeight(rRect))/10;
tools::Long nTop;
const SvxULSpaceItem &rUL = pFormat->GetULSpace();
SwRect aSnapRect( pSdrObj->GetSnapRect() );
tools::Long nTmpH = 0;
if( bMove )
{
nTop = aRectFnSet.YInc( aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().X() :
pSdrObj->GetAnchorPos().Y(), -nHeight );
tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect);
aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
pSdrObj->GetAnchorPos().Y() :
pSdrObj->GetAnchorPos().X(), nWidth );
const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj);
if (!pAnchorFrame)
{
OSL_FAIL("<::CalcClipRect(..)> - missing anchor frame.");
const_cast<SwDrawContact*>(pC)->ConnectToLayout();
pAnchorFrame = pC->GetAnchorFrame();
}
const SwFrame* pUp = pAnchorFrame->GetUpper();
rRect = pUp->getFramePrintArea();
rRect += pUp->getFrameArea().Pos();
SwRectFnSet aRectFnSet(pAnchorFrame);
tools::Long nHeight = (9 * aRectFnSet.GetHeight(rRect)) / 10;
tools::Long nTop;
const SvxULSpaceItem& rUL = pFormat->GetULSpace();
SwRect aSnapRect(pSdrObj->GetSnapRect());
tools::Long nTmpH = 0;
if (bMove)
{
nTop = aRectFnSet.YInc(aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().X()
: pSdrObj->GetAnchorPos().Y(),
-nHeight);
tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect);
aRectFnSet.SetLeftAndWidth(rRect,
aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().Y()
: pSdrObj->GetAnchorPos().X(),
nWidth);
}
else
{
// #i26791# - value of <nTmpH> is needed to
// calculate value of <nTop>.
nTmpH = aRectFnSet.IsVert() ? pSdrObj->GetCurrentBoundRect().GetWidth()
: pSdrObj->GetCurrentBoundRect().GetHeight();
nTop = aRectFnSet.YInc(aRectFnSet.GetTop(aSnapRect),
rUL.GetLower() + nTmpH - nHeight);
}
nHeight = 2 * nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
aRectFnSet.SetTopAndHeight(rRect, nTop, nHeight);
}
else
{
// #i26791# - value of <nTmpH> is needed to
// calculate value of <nTop>.
nTmpH = aRectFnSet.IsVert() ? pSdrObj->GetCurrentBoundRect().GetWidth() :
pSdrObj->GetCurrentBoundRect().GetHeight();
nTop = aRectFnSet.YInc( aRectFnSet.GetTop(aSnapRect),
rUL.GetLower() + nTmpH - nHeight );
}
nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight );
}
else
{
// restrict clip rectangle for drawing
// objects in header/footer to the page frame.
// #i26791#
const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj );
if ( pAnchorFrame && pAnchorFrame->FindFooterOrHeader() )
{
// clip frame is the page frame the header/footer is on.
const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame();
rRect = pClipFrame->getFrameArea();
}
else
{
bRet = false;
// restrict clip rectangle for drawing
// objects in header/footer to the page frame.
// #i26791#
const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj);
if (pAnchorFrame && pAnchorFrame->FindFooterOrHeader())
{
// clip frame is the page frame the header/footer is on.
const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame();
rRect = pClipFrame->getFrameArea();
}
else
{
bRet = false;
}
}
}
}
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index c3fa35f..c4dbb28 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -3404,8 +3404,10 @@ void Notify_Background( const SdrObject* pObj,
else
{
pFlyFrame = nullptr;
pAnchor = const_cast<SwFrame*>(
GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrame() );
if (SwDrawContact* pC = static_cast<SwDrawContact*>(GetUserCall(pObj)))
pAnchor = const_cast<SwFrame*>(pC->GetAnchoredObj(pObj)->GetAnchorFrame());
else
return;
}
if( PrepareHint::FlyFrameLeave != eHint && pAnchor->IsInFly() )
pArea = pAnchor->FindFlyFrame();
diff --git a/sw/source/core/layout/sortedobjs.cxx b/sw/source/core/layout/sortedobjs.cxx
index ce581bb..1e5f1aa 100644
--- a/sw/source/core/layout/sortedobjs.cxx
+++ b/sw/source/core/layout/sortedobjs.cxx
@@ -78,10 +78,14 @@ struct ObjAnchorOrder
const SwAnchoredObject* _pNewAnchoredObj )
{
// get attributes of listed object
if (!_pListedAnchoredObj->HasFrameFormat())
return false;
const SwFrameFormat& rFormatListed = _pListedAnchoredObj->GetFrameFormat();
const SwFormatAnchor* pAnchorListed = &(rFormatListed.GetAnchor());
// get attributes of new object
if (!_pNewAnchoredObj->HasFrameFormat())
return false;
const SwFrameFormat& rFormatNew = _pNewAnchoredObj->GetFrameFormat();
const SwFormatAnchor* pAnchorNew = &(rFormatNew.GetAnchor());
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index ff5566f..6d25e4c 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -768,78 +768,85 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj,
if ( bEvade )
{
// #i26945#
const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor();
OSL_ENSURE( RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(),
"Don't call GetTop with a FlyInContentFrame" );
if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
return true; // We always avoid page anchored ones
// If Flys anchored at paragraph are caught in a FlyCnt, then
// their influence ends at the borders of the FlyCnt!
// If we are currently formatting the text of the FlyCnt, then
// it has to get out of the way of the Frame anchored at paragraph!
// m_pCurrFrame is the anchor of pNew?
// #i26945#
const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame();
if (pTmp == m_pCurrFrame)
return true;
if( pTmp->IsTextFrame() && ( pTmp->IsInFly() || pTmp->IsInFootnote() ) )
if (_pAnchoredObj->HasFrameFormat())
{
const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor();
OSL_ENSURE(RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(),
"Don't call GetTop with a FlyInContentFrame");
if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
return true; // We always avoid page anchored ones
// If Flys anchored at paragraph are caught in a FlyCnt, then
// their influence ends at the borders of the FlyCnt!
// If we are currently formatting the text of the FlyCnt, then
// it has to get out of the way of the Frame anchored at paragraph!
// m_pCurrFrame is the anchor of pNew?
// #i26945#
Point aPos = _pAnchoredObj->GetObjRect().Pos();
pTmp = GetVirtualUpper( pTmp, aPos );
}
// #i26945#
// If <pTmp> is a text frame inside a table, take the upper
// of the anchor frame, which contains the anchor position.
else if ( pTmp->IsTextFrame() && pTmp->IsInTab() )
{
pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj)
->GetAnchorFrameContainingAnchPos()->GetUpper();
}
// #i28701# - consider all objects in same context,
// if wrapping style is considered on object positioning.
// Thus, text will wrap around negative positioned objects.
// #i3317# - remove condition on checking,
// if wrappings style is considered on object positioning.
// Thus, text is wrapping around negative positioned objects.
// #i35640# - no consideration of negative
// positioned objects, if wrapping style isn't considered on
// object position and former text wrapping is applied.
// This condition is typically for documents imported from the
// OpenOffice.org file format.
const IDocumentSettingAccess* pIDSA = &m_pCurrFrame->GetDoc().getIDocumentSettingAccess();
if ( ( pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ||
!pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) ) &&
::FindContext( pTmp, SwFrameType::None ) == ::FindContext(m_pCurrFrame, SwFrameType::None))
{
return true;
}
const SwFrame* pHeader = nullptr;
if (m_pCurrFrame->GetNext() != pTmp &&
(IsFrameInSameContext( pTmp, m_pCurrFrame ) ||
// #i13832#, #i24135# wrap around objects in page header
( !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) &&
nullptr != ( pHeader = pTmp->FindFooterOrHeader() ) &&
m_pCurrFrame->IsInDocBody())))
{
if( pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId() )
const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame();
if (pTmp == m_pCurrFrame)
return true;
// Compare indices:
// The Index of the other is retrieved from the anchor attr.
SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex();
// Now check whether the current paragraph is before the anchor
// of the displaced object in the text, then we don't have to
// get out of its way.
// If possible determine Index via SwFormatAnchor because
// otherwise it's quite expensive.
if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex)
m_nCurrFrameNodeIndex = m_pCurrFrame->GetTextNodeFirst()->GetIndex();
if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) || nTmpIndex < m_nCurrFrameNodeIndex)
if (pTmp->IsTextFrame() && (pTmp->IsInFly() || pTmp->IsInFootnote()))
{
// #i26945#
Point aPos = _pAnchoredObj->GetObjRect().Pos();
pTmp = GetVirtualUpper(pTmp, aPos);
}
// #i26945#
// If <pTmp> is a text frame inside a table, take the upper
// of the anchor frame, which contains the anchor position.
else if (pTmp->IsTextFrame() && pTmp->IsInTab())
{
pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj)
->GetAnchorFrameContainingAnchPos()
->GetUpper();
}
// #i28701# - consider all objects in same context,
// if wrapping style is considered on object positioning.
// Thus, text will wrap around negative positioned objects.
// #i3317# - remove condition on checking,
// if wrappings style is considered on object positioning.
// Thus, text is wrapping around negative positioned objects.
// #i35640# - no consideration of negative
// positioned objects, if wrapping style isn't considered on
// object position and former text wrapping is applied.
// This condition is typically for documents imported from the
// OpenOffice.org file format.
const IDocumentSettingAccess* pIDSA
= &m_pCurrFrame->GetDoc().getIDocumentSettingAccess();
if ((pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION)
|| !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING))
&& ::FindContext(pTmp, SwFrameType::None)
== ::FindContext(m_pCurrFrame, SwFrameType::None))
{
return true;
}
const SwFrame* pHeader = nullptr;
if (m_pCurrFrame->GetNext() != pTmp
&& (IsFrameInSameContext(pTmp, m_pCurrFrame) ||
// #i13832#, #i24135# wrap around objects in page header
(!pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING)
&& nullptr != (pHeader = pTmp->FindFooterOrHeader())
&& m_pCurrFrame->IsInDocBody())))
{
if (pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId())
return true;
// Compare indices:
// The Index of the other is retrieved from the anchor attr.
SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex();
// Now check whether the current paragraph is before the anchor
// of the displaced object in the text, then we don't have to
// get out of its way.
// If possible determine Index via SwFormatAnchor because
// otherwise it's quite expensive.
if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex)
m_nCurrFrameNodeIndex = m_pCurrFrame->GetTextNodeFirst()->GetIndex();
if (FrameContainsNode(*m_pCurrFrame, nTmpIndex)
|| nTmpIndex < m_nCurrFrameNodeIndex)
return true;
}
}
}
}
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 322928e..d2c3f0e 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -4662,19 +4662,23 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
SdrObject* pObj = pSdrView ? pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr;
if (pObj)
{
SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat();
SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT);
if (!pShapeFormat)
if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
{
pSdrView->UnmarkAllObj();
pSdrView->MarkObj(pObj,pPV);
}
else
{
// If the fly frame is a textbox of a shape, then select the shape instead.
SdrObject* pShape = pShapeFormat->FindSdrObject();
pSdrView->UnmarkAllObj();
pSdrView->MarkObj(pShape, pPV);
SwFrameFormat* pFormat = pContact->GetFormat();
SwFrameFormat* pShapeFormat
= SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT);
if (!pShapeFormat)
{
pSdrView->UnmarkAllObj();
pSdrView->MarkObj(pObj, pPV);
}
else
{
// If the fly frame is a textbox of a shape, then select the shape instead.
SdrObject* pShape = pShapeFormat->FindSdrObject();
pSdrView->UnmarkAllObj();
pSdrView->MarkObj(pShape, pPV);
}
}
}
}
diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx
index a5a63a6..d5eec21 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -836,8 +836,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet)
SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient));
if (pFrameFormat)
{
SwFormatHoriOrient aHOrient(
pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient));
}
}
if (bVert && !bDisableThis && rMarkList.GetMarkCount() == 1)
@@ -860,8 +864,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet)
SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient));
if (pFrameFormat)
{
SwFormatVertOrient aVOrient(
pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient));
}
}
}
break;