summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt K <mattkse@gmail.com>2024-01-11 20:37:01 -0600
committerMike Kaganski <mike.kaganski@collabora.com>2024-01-13 18:21:02 +0100
commit19062c98da5b2e9edc7a99068fa06a83c7578826 (patch)
treecf510636e97993f82deb99ba7289fd29f03c46a1
parent9fdf51275beb617abd67a82a76efe1d1f6fdf0a6 (diff)
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>
-rw-r--r--sw/inc/anchoredobject.hxx1
-rw-r--r--sw/source/core/doc/docdraw.cxx17
-rw-r--r--sw/source/core/draw/dview.cxx19
-rw-r--r--sw/source/core/frmedt/feshview.cxx36
-rw-r--r--sw/source/core/layout/anchoredobject.cxx134
-rw-r--r--sw/source/core/layout/flylay.cxx113
-rw-r--r--sw/source/core/layout/frmtool.cxx6
-rw-r--r--sw/source/core/layout/sortedobjs.cxx4
-rw-r--r--sw/source/core/text/txtfly.cxx143
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx28
-rw-r--r--sw/source/uibase/shells/drwbassh.cxx16
11 files changed, 288 insertions, 229 deletions
diff --git a/sw/inc/anchoredobject.hxx b/sw/inc/anchoredobject.hxx
index 19cd2e75802b..9af198425714 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 aecbe2ac824f..521ca2b0ba15 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 f7ab7cda9fbd..98c0014b1a17 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -979,16 +979,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 9a18e7934c03..30e448dec8e3 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 42e7dd39fcd2..fe959a688723 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();
-
- // --> #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() )
+ if (HasFrameFormat())
{
- 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 )
+ 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())
{
- // --> #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();
+ }
+ if (pAnchor)
+ {
+ pAnchorCharFrame = pAnchor;
}
- pAnchor = pAnchor->GetFollow();
- }
- 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 457a0d41bbf3..66e27adb8f47 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 );
- }
- 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();
+ 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
{
- 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 c3fa35fcdc7b..c4dbb28f0073 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 ce581bb663ef..1e5f1aa293be 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 ff5566f537ac..6d25e4c96581 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 e89614319903..f01cf9256c74 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 a5a63a66343d..d5eec2132093 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;