1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svl/itemiter.hxx>
21 #include <svtools/imap.hxx>
22 #include <tools/helpers.hxx>
23 #include <editeng/protitem.hxx>
24 #include <editeng/opaqitem.hxx>
25 #include <editeng/ulspitem.hxx>
26 #include <editeng/frmdiritem.hxx>
27 #include <drawdoc.hxx>
28 #include <fmtfsize.hxx>
29 #include <fmtclds.hxx>
30 #include <fmtcntnt.hxx>
32 #include <fmtsrnd.hxx>
33 #include <fmtornt.hxx>
34 #include <fmtcnct.hxx>
36 #include <tolayoutanchoredobjectposition.hxx>
37 #include <fmtfollowtextflow.hxx>
38 #include <sortedobjs.hxx>
39 #include <objectformatter.hxx>
41 #include <swtable.hxx>
42 #include <svx/svdpage.hxx>
43 #include <svx/svdoashp.hxx>
44 #include <layouter.hxx>
45 #include <pagefrm.hxx>
46 #include <rootfrm.hxx>
47 #include <viewimp.hxx>
48 #include <viewopt.hxx>
49 #include <dcontact.hxx>
50 #include <dflyobj.hxx>
52 #include <frmtool.hxx>
56 #include <notxtfrm.hxx>
57 #include <flyfrms.hxx>
58 #include <sectfrm.hxx>
59 #include <vcl/svapp.hxx>
61 #include <IDocumentSettingAccess.hxx>
62 #include <IDocumentLayoutAccess.hxx>
63 #include <textboxhelper.hxx>
65 #include <ndindex.hxx>
67 #include <basegfx/polygon/b2dpolygontools.hxx>
68 #include <basegfx/matrix/b2dhommatrixtools.hxx>
70 using namespace ::com::sun::star
;
72 static SwTwips
lcl_CalcAutoWidth( const SwLayoutFrame
& rFrame
);
74 SwFlyFrame::SwFlyFrame( SwFlyFrameFormat
*pFormat
, SwFrame
* pSib
, SwFrame
*pAnch
) :
75 SwLayoutFrame( pFormat
, pSib
),
76 SwAnchoredObject(), // #i26791#
77 m_pPrevLink( nullptr ),
78 m_pNextLink( nullptr ),
82 m_bAutoPosition( false ),
83 m_bValidContentPos( false )
85 mnFrameType
= SwFrameType::Fly
;
87 m_bInvalid
= m_bNotifyBack
= true;
88 m_bLocked
= m_bMinHeight
=
89 m_bHeightClipped
= m_bWidthClipped
= m_bFormatHeightOnly
= false;
91 // Size setting: Fixed size is always the width
92 const SwFormatFrameSize
&rFrameSize
= pFormat
->GetFrameSize();
93 const SvxFrameDirection nDir
= pFormat
->GetFormatAttr( RES_FRAMEDIR
).GetValue();
94 if( SvxFrameDirection::Environment
== nDir
)
101 mbInvalidVert
= false;
102 mbDerivedVert
= false;
103 mbDerivedR2L
= false;
104 if( SvxFrameDirection::Horizontal_LR_TB
== nDir
|| SvxFrameDirection::Horizontal_RL_TB
== nDir
)
111 const SwViewShell
*pSh
= getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
112 if( pSh
&& pSh
->GetViewOptions()->getBrowseMode() )
121 if ( SvxFrameDirection::Vertical_LR_TB
== nDir
)
128 mbInvalidR2L
= false;
129 if( SvxFrameDirection::Horizontal_RL_TB
== nDir
)
130 mbRightToLeft
= true;
132 mbRightToLeft
= false;
136 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
137 aFrm
.Width( rFrameSize
.GetWidth() );
138 aFrm
.Height( rFrameSize
.GetHeightSizeType() == ATT_VAR_SIZE
? MINFLY
: rFrameSize
.GetHeight() );
141 // Fixed or variable Height?
142 if ( rFrameSize
.GetHeightSizeType() == ATT_MIN_SIZE
)
144 else if ( rFrameSize
.GetHeightSizeType() == ATT_FIX_SIZE
)
147 // insert columns, if necessary
150 // First the Init, then the Content:
151 // This is due to the fact that the Content may have Objects/Frames,
152 // which are then registered
159 // Put it somewhere outside so that out document is not formatted unnecessarily often
160 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
161 aFrm
.Pos().setX(FAR_AWAY
);
162 aFrm
.Pos().setY(FAR_AWAY
);
165 void SwFlyFrame::Chain( SwFrame
* _pAnch
)
167 // Connect to chain neighbours.
168 // No problem, if a neighboor doesn't exist - the construction of the
169 // neighboor will make the connection
170 const SwFormatChain
& rChain
= GetFormat()->GetChain();
171 if ( rChain
.GetPrev() || rChain
.GetNext() )
173 if ( rChain
.GetNext() )
175 SwFlyFrame
* pFollow
= FindChainNeighbour( *rChain
.GetNext(), _pAnch
);
178 OSL_ENSURE( !pFollow
->GetPrevLink(), "wrong chain detected" );
179 if ( !pFollow
->GetPrevLink() )
180 SwFlyFrame::ChainFrames( this, pFollow
);
183 if ( rChain
.GetPrev() )
185 SwFlyFrame
*pMaster
= FindChainNeighbour( *rChain
.GetPrev(), _pAnch
);
188 OSL_ENSURE( !pMaster
->GetNextLink(), "wrong chain detected" );
189 if ( !pMaster
->GetNextLink() )
190 SwFlyFrame::ChainFrames( pMaster
, this );
196 void SwFlyFrame::InsertCnt()
198 if ( !GetPrevLink() )
200 const SwFormatContent
& rContent
= GetFormat()->GetContent();
201 OSL_ENSURE( rContent
.GetContentIdx(), ":-( no content prepared." );
202 sal_uLong nIndex
= rContent
.GetContentIdx()->GetIndex();
203 // Lower() means SwColumnFrame; the Content then needs to be inserted into the (Column)BodyFrame
204 ::InsertCnt_( Lower() ? static_cast<SwLayoutFrame
*>(static_cast<SwLayoutFrame
*>(Lower())->Lower()) : static_cast<SwLayoutFrame
*>(this),
205 GetFormat()->GetDoc(), nIndex
);
207 // NoText always have a fixed height.
208 if ( Lower() && Lower()->IsNoTextFrame() )
211 m_bMinHeight
= false;
216 void SwFlyFrame::InsertColumns()
219 // Check, if column are allowed.
220 // Columns are not allowed for fly frames, which represent graphics or embedded objects.
221 const SwFormatContent
& rContent
= GetFormat()->GetContent();
222 OSL_ENSURE( rContent
.GetContentIdx(), "<SwFlyFrame::InsertColumns()> - no content prepared." );
223 SwNodeIndex
aFirstContent( *(rContent
.GetContentIdx()), 1 );
224 if ( aFirstContent
.GetNode().IsNoTextNode() )
229 const SwFormatCol
&rCol
= GetFormat()->GetCol();
230 if ( rCol
.GetNumCols() > 1 )
232 // Start off PrtArea to be as large as Frame, so that we can put in the columns
233 // properly. It'll adjust later on.
235 SwFrameAreaDefinition::FramePrintAreaWriteAccess
aPrt(*this);
236 aPrt
.Width( getFrameArea().Width() );
237 aPrt
.Height( getFrameArea().Height() );
240 const SwFormatCol aOld
; // ChgColumns() also needs an old value passed
241 ChgColumns( aOld
, rCol
);
245 void SwFlyFrame::DestroyImpl()
247 // Accessible objects for fly frames will be destroyed in this destructor.
248 // For frames bound as char or frames that don't have an anchor we have
249 // to do that ourselves. For any other frame the call RemoveFly at the
250 // anchor will do that.
251 if( IsAccessibleFrame() && GetFormat() && (IsFlyInContentFrame() || !GetAnchorFrame()) )
253 SwRootFrame
*pRootFrame
= getRootFrame();
254 if( pRootFrame
&& pRootFrame
->IsAnyShellAccessible() )
256 SwViewShell
*pVSh
= pRootFrame
->GetCurrShell();
257 if( pVSh
&& pVSh
->Imp() )
259 // Lowers aren't disposed already, so we have to do a recursive
261 pVSh
->Imp()->DisposeAccessibleFrame( this, true );
266 if( GetFormat() && !GetFormat()->GetDoc()->IsInDtor() )
268 // OD 2004-01-19 #110582#
271 // OD 2004-01-19 #110582#
274 if ( GetAnchorFrame() )
275 AnchorFrame()->RemoveFly( this );
280 SwLayoutFrame::DestroyImpl();
283 SwFlyFrame::~SwFlyFrame()
287 const IDocumentDrawModelAccess
& SwFlyFrame::getIDocumentDrawModelAccess()
289 return GetFormat()->getIDocumentDrawModelAccess();
292 // OD 2004-01-19 #110582#
293 void SwFlyFrame::Unchain()
296 UnchainFrames( GetPrevLink(), this );
298 UnchainFrames( this, GetNextLink() );
301 // OD 2004-01-19 #110582#
302 void SwFlyFrame::DeleteCnt()
304 SwFrame
* pFrame
= m_pLower
;
307 while ( pFrame
->GetDrawObjs() && pFrame
->GetDrawObjs()->size() )
309 SwAnchoredObject
*pAnchoredObj
= (*pFrame
->GetDrawObjs())[0];
310 if ( dynamic_cast<const SwFlyFrame
*>( pAnchoredObj
) != nullptr )
312 SwFrame::DestroyFrame(static_cast<SwFlyFrame
*>(pAnchoredObj
));
314 else if ( dynamic_cast<const SwAnchoredDrawObject
*>( pAnchoredObj
) != nullptr )
316 // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
317 SdrObject
* pObj
= pAnchoredObj
->DrawObj();
318 if ( dynamic_cast<const SwDrawVirtObj
*>( pObj
) != nullptr )
320 SwDrawVirtObj
* pDrawVirtObj
= static_cast<SwDrawVirtObj
*>(pObj
);
321 pDrawVirtObj
->RemoveFromWriterLayout();
322 pDrawVirtObj
->RemoveFromDrawingPage();
326 SwDrawContact
* pContact
=
327 static_cast<SwDrawContact
*>(::GetUserCall( pObj
));
330 pContact
->DisconnectFromLayout();
336 pFrame
->RemoveFromLayout();
337 SwFrame::DestroyFrame(pFrame
);
344 void SwFlyFrame::InitDrawObj()
346 // OD 2004-03-22 #i26791#
347 SetDrawObj(*SwFlyDrawContact::CreateNewRef(this, GetFormat()));
349 // Set the right Layer
350 // OD 2004-01-19 #110582#
351 IDocumentDrawModelAccess
& rIDDMA
= GetFormat()->getIDocumentDrawModelAccess();
352 SdrLayerID nHeavenId
= rIDDMA
.GetHeavenId();
353 SdrLayerID nHellId
= rIDDMA
.GetHellId();
354 // OD 2004-03-22 #i26791#
355 GetVirtDrawObj()->SetLayer( GetFormat()->GetOpaque().GetValue()
360 void SwFlyFrame::FinitDrawObj()
362 if(!GetVirtDrawObj() )
364 SwFormat
* pFormat
= GetFormat();
365 // Deregister from SdrPageViews if the Objects is still selected there.
366 if(!pFormat
->GetDoc()->IsInDtor())
368 SwViewShell
* p1St
= getRootFrame()->GetCurrShell();
371 for(SwViewShell
& rCurrentShell
: p1St
->GetRingContainer())
372 { // At the moment the Drawing can do just do an Unmark on everything,
373 // as the Object was already removed
374 if(rCurrentShell
.HasDrawView() )
375 rCurrentShell
.Imp()->GetDrawView()->UnmarkAll();
380 // Else calls delete of the ContactObj
381 GetVirtDrawObj()->SetUserCall(nullptr);
383 // Deregisters itself at the Master
384 // always use SdrObject::Free(...) for SdrObjects (!)
385 SdrObject
* pTemp(GetVirtDrawObj());
386 SdrObject::Free(pTemp
);
389 void SwFlyFrame::ChainFrames( SwFlyFrame
*pMaster
, SwFlyFrame
*pFollow
)
391 OSL_ENSURE( pMaster
&& pFollow
, "incomplete chain" );
392 OSL_ENSURE( !pMaster
->GetNextLink(), "link can not be changed" );
393 OSL_ENSURE( !pFollow
->GetPrevLink(), "link can not be changed" );
395 pMaster
->m_pNextLink
= pFollow
;
396 pFollow
->m_pPrevLink
= pMaster
;
398 if ( pMaster
->ContainsContent() )
400 // To get a text flow we need to invalidate
401 SwFrame
*pInva
= pMaster
->FindLastLower();
402 SwRectFnSet
aRectFnSet(pMaster
);
403 const long nBottom
= aRectFnSet
.GetPrtBottom(*pMaster
);
406 if( aRectFnSet
.BottomDist( pInva
->getFrameArea(), nBottom
) <= 0 )
408 pInva
->InvalidateSize();
410 pInva
= pInva
->FindPrev();
417 if ( pFollow
->ContainsContent() )
419 // There's only the content from the Masters left; the content from the Follow
420 // does not have any Frames left (should always be exactly one empty TextNode).
421 SwFrame
*pFrame
= pFollow
->ContainsContent();
422 OSL_ENSURE( !pFrame
->IsTabFrame() && !pFrame
->FindNext(), "follow in chain contains content" );
424 SwFrame::DestroyFrame(pFrame
);
427 // invalidate accessible relation set (accessibility wrapper)
428 SwViewShell
* pSh
= pMaster
->getRootFrame()->GetCurrShell();
431 SwRootFrame
* pLayout
= pMaster
->getRootFrame();
432 if( pLayout
&& pLayout
->IsAnyShellAccessible() )
433 pSh
->Imp()->InvalidateAccessibleRelationSet( pMaster
, pFollow
);
437 void SwFlyFrame::UnchainFrames( SwFlyFrame
*pMaster
, SwFlyFrame
*pFollow
)
439 pMaster
->m_pNextLink
= nullptr;
440 pFollow
->m_pPrevLink
= nullptr;
442 if ( pFollow
->ContainsContent() )
444 // The Master sucks up the content of the Follow
445 SwLayoutFrame
*pUpper
= pMaster
;
446 if ( pUpper
->Lower()->IsColumnFrame() )
448 pUpper
= static_cast<SwLayoutFrame
*>(pUpper
->GetLastLower());
449 pUpper
= static_cast<SwLayoutFrame
*>(pUpper
->Lower()); // The (Column)BodyFrame
450 OSL_ENSURE( pUpper
&& pUpper
->IsColBodyFrame(), "Missing ColumnBody" );
452 SwFlyFrame
*pFoll
= pFollow
;
455 SwFrame
*pTmp
= ::SaveContent( pFoll
);
457 ::RestoreContent( pTmp
, pUpper
, pMaster
->FindLastLower() );
458 pFoll
->SetCompletePaint();
459 pFoll
->InvalidateSize();
460 pFoll
= pFoll
->GetNextLink();
464 // The Follow needs his own content to be served
465 const SwFormatContent
&rContent
= pFollow
->GetFormat()->GetContent();
466 OSL_ENSURE( rContent
.GetContentIdx(), ":-( No content prepared." );
467 sal_uLong nIndex
= rContent
.GetContentIdx()->GetIndex();
468 // Lower() means SwColumnFrame: this one contains another SwBodyFrame
469 ::InsertCnt_( pFollow
->Lower() ? const_cast<SwLayoutFrame
*>(static_cast<const SwLayoutFrame
*>(static_cast<const SwLayoutFrame
*>(pFollow
->Lower())->Lower()))
470 : static_cast<SwLayoutFrame
*>(pFollow
),
471 pFollow
->GetFormat()->GetDoc(), ++nIndex
);
473 // invalidate accessible relation set (accessibility wrapper)
474 SwViewShell
* pSh
= pMaster
->getRootFrame()->GetCurrShell();
477 SwRootFrame
* pLayout
= pMaster
->getRootFrame();
478 if( pLayout
&& pLayout
->IsAnyShellAccessible() )
479 pSh
->Imp()->InvalidateAccessibleRelationSet( pMaster
, pFollow
);
483 SwFlyFrame
*SwFlyFrame::FindChainNeighbour( SwFrameFormat
const &rChain
, SwFrame
*pAnch
)
485 // We look for the Fly that's in the same Area.
486 // Areas can for now only be Head/Footer or Flys.
488 if ( !pAnch
) // If an Anchor was passed along, that one counts (ctor!)
489 pAnch
= AnchorFrame();
492 if ( pAnch
->IsInFly() )
493 pLay
= pAnch
->FindFlyFrame();
496 // FindFooterOrHeader is not appropriate here, as we may not have a
497 // connection to the Anchor yet.
498 pLay
= pAnch
->GetUpper();
499 while ( pLay
&& !(pLay
->GetType() & (SwFrameType::Header
|SwFrameType::Footer
)) )
500 pLay
= pLay
->GetUpper();
503 SwIterator
<SwFlyFrame
,SwFormat
> aIter( rChain
);
504 SwFlyFrame
*pFly
= aIter
.First();
509 if ( pFly
->GetAnchorFrame() )
511 if ( pFly
->GetAnchorFrame()->IsInFly() )
513 if ( pFly
->AnchorFrame()->FindFlyFrame() == pLay
)
516 else if ( pLay
== pFly
->FindFooterOrHeader() )
524 OSL_ENSURE( !aIter
.Next(), "chain with more than one instance" );
529 SwFrame
*SwFlyFrame::FindLastLower()
531 SwFrame
*pRet
= ContainsAny();
532 if ( pRet
&& pRet
->IsInTab() )
533 pRet
= pRet
->FindTabFrame();
534 SwFrame
*pNxt
= pRet
;
535 while ( pNxt
&& IsAnLower( pNxt
) )
537 pNxt
= pNxt
->FindNext();
542 bool SwFlyFrame::FrameSizeChg( const SwFormatFrameSize
&rFrameSize
)
545 SwTwips nDiffHeight
= getFrameArea().Height();
546 if ( rFrameSize
.GetHeightSizeType() == ATT_VAR_SIZE
)
547 mbFixSize
= m_bMinHeight
= false;
550 if ( rFrameSize
.GetHeightSizeType() == ATT_FIX_SIZE
)
553 m_bMinHeight
= false;
555 else if ( rFrameSize
.GetHeightSizeType() == ATT_MIN_SIZE
)
560 nDiffHeight
-= rFrameSize
.GetHeight();
562 // If the Fly contains columns, we already need to set the Fly
563 // and the Columns to the required value or else we run into problems.
566 if ( Lower()->IsColumnFrame() )
568 const SwRect
aOld( GetObjRectWithSpaces() );
569 const Size
aOldSz( getFramePrintArea().SSize() );
570 const SwTwips nDiffWidth
= getFrameArea().Width() - rFrameSize
.GetWidth();
573 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
574 aFrm
.Height( aFrm
.Height() - nDiffHeight
);
575 aFrm
.Width ( aFrm
.Width() - nDiffWidth
);
579 InvalidateObjRectWithSpaces();
582 SwFrameAreaDefinition::FramePrintAreaWriteAccess
aPrt(*this);
583 aPrt
.Height( aPrt
.Height() - nDiffHeight
);
584 aPrt
.Width ( aPrt
.Width() - nDiffWidth
);
587 ChgLowersProp( aOldSz
);
588 ::Notify( this, FindPageFrame(), aOld
);
589 setFrameAreaPositionValid(false);
592 else if ( Lower()->IsNoTextFrame() )
595 m_bMinHeight
= false;
601 void SwFlyFrame::SwClientNotify(const SwModify
& rMod
, const SfxHint
& rHint
)
603 SwFrame::SwClientNotify(rMod
, rHint
);
604 if (auto pGetZOrdnerHint
= dynamic_cast<const sw::GetZOrderHint
*>(&rHint
))
606 const auto& rFormat(dynamic_cast<const SwFrameFormat
&>(rMod
));
607 if (rFormat
.Which() == RES_FLYFRMFMT
&& rFormat
.getIDocumentLayoutAccess().GetCurrentViewShell()) // #i11176#
608 pGetZOrdnerHint
->m_rnZOrder
= GetVirtDrawObj()->GetOrdNum();
610 else if (auto pConnectedHint
= dynamic_cast<const sw::GetObjectConnectedHint
*>(&rHint
))
612 const auto& rFormat(dynamic_cast<const SwFrameFormat
&>(rMod
));
613 if (!pConnectedHint
->m_risConnected
&& rFormat
.Which() == RES_FLYFRMFMT
&& (!pConnectedHint
->m_pRoot
|| pConnectedHint
->m_pRoot
== getRootFrame()))
614 pConnectedHint
->m_risConnected
= true;
618 void SwFlyFrame::Modify( const SfxPoolItem
* pOld
, const SfxPoolItem
* pNew
)
620 sal_uInt8 nInvFlags
= 0;
622 if (pNew
&& pOld
&& RES_ATTRSET_CHG
== pNew
->Which())
624 SfxItemIter
aNIter( *static_cast<const SwAttrSetChg
*>(pNew
)->GetChgSet() );
625 SfxItemIter
aOIter( *static_cast<const SwAttrSetChg
*>(pOld
)->GetChgSet() );
626 SwAttrSetChg
aOldSet( *static_cast<const SwAttrSetChg
*>(pOld
) );
627 SwAttrSetChg
aNewSet( *static_cast<const SwAttrSetChg
*>(pNew
) );
630 UpdateAttr_( aOIter
.GetCurItem(),
631 aNIter
.GetCurItem(), nInvFlags
,
632 &aOldSet
, &aNewSet
);
633 if( aNIter
.IsAtEnd() )
638 if ( aOldSet
.Count() || aNewSet
.Count() )
639 SwLayoutFrame::Modify( &aOldSet
, &aNewSet
);
642 UpdateAttr_( pOld
, pNew
, nInvFlags
);
644 if ( nInvFlags
== 0 )
648 if ( nInvFlags
& 0x01 )
652 InvalidateObjRectWithSpaces();
654 if ( nInvFlags
& 0x02 )
658 InvalidateObjRectWithSpaces();
660 if ( nInvFlags
& 0x04 )
662 if ( nInvFlags
& 0x08 )
664 if ( nInvFlags
& 0x10 )
666 if ( ( nInvFlags
& 0x40 ) && Lower() && Lower()->IsNoTextFrame() )
667 ClrContourCache( GetVirtDrawObj() );
669 if ( nInvFlags
& 0x20 && nullptr != (pRoot
= getRootFrame()) )
670 pRoot
->InvalidateBrowseWidth();
672 if ( nInvFlags
& 0x80 )
674 // update sorted object lists, the Writer fly frame is registered at.
675 UpdateObjInSortedList();
678 // #i87645# - reset flags for the layout process (only if something has been invalidated)
679 ResetLayoutProcessBools();
683 void SwFlyFrame::UpdateAttr_( const SfxPoolItem
*pOld
, const SfxPoolItem
*pNew
,
684 sal_uInt8
&rInvFlags
,
685 SwAttrSetChg
*pOldSet
, SwAttrSetChg
*pNewSet
)
688 const sal_uInt16 nWhich
= pOld
? pOld
->Which() : pNew
? pNew
->Which() : 0;
689 SwViewShell
*pSh
= getRootFrame()->GetCurrShell();
692 case RES_VERT_ORIENT
:
693 case RES_HORI_ORIENT
:
694 // OD 22.09.2003 #i18732# - consider new option 'follow text flow'
695 case RES_FOLLOW_TEXT_FLOW
:
697 // ATTENTION: Always also change Action in ChgRePos()!
701 // OD 2004-07-01 #i28701# - consider new option 'wrap influence on position'
702 case RES_WRAP_INFLUENCE_ON_OBJPOS
:
709 // OD 2004-05-13 #i28701# - invalidate position on change of
713 // The background needs to be messaged and invalidated
714 const SwRect
aTmp( GetObjRectWithSpaces() );
715 NotifyBackground( FindPageFrame(), aTmp
, PREP_FLY_ATTR_CHG
);
717 // By changing the flow of frame-bound Frames, a vertical alignment
718 // can be activated/deactivated => MakeFlyPos
719 if( RndStdIds::FLY_AT_FLY
== GetFormat()->GetAnchor().GetAnchorId() )
722 // Delete contour in the Node if necessary
723 if ( Lower() && Lower()->IsNoTextFrame() &&
724 !GetFormat()->GetSurround().IsContour() )
726 SwNoTextNode
*pNd
= static_cast<SwNoTextNode
*>(static_cast<SwNoTextFrame
*>(Lower())->GetNode());
727 if ( pNd
->HasContour() )
728 pNd
->SetContour( nullptr );
730 // #i28701# - perform reorder of object lists
731 // at anchor frame and at page frame.
739 const SvxProtectItem
*pP
= static_cast<const SvxProtectItem
*>(pNew
);
740 GetVirtDrawObj()->SetMoveProtect( pP
->IsPosProtected() );
741 GetVirtDrawObj()->SetResizeProtect( pP
->IsSizeProtected() );
744 SwRootFrame
* pLayout
= getRootFrame();
745 if( pLayout
&& pLayout
->IsAnyShellAccessible() )
746 pSh
->Imp()->InvalidateAccessibleEditableState( true, this );
753 ChgColumns( *static_cast<const SwFormatCol
*>(pOld
), *static_cast<const SwFormatCol
*>(pNew
) );
754 const SwFormatFrameSize
&rNew
= GetFormat()->GetFrameSize();
755 if ( FrameSizeChg( rNew
) )
764 const SwFormatFrameSize
&rNew
= GetFormat()->GetFrameSize();
765 if ( FrameSizeChg( rNew
) )
768 if (pOld
&& RES_FMT_CHG
== nWhich
)
770 SwRect
aNew( GetObjRectWithSpaces() );
771 SwRect
aOld( getFrameArea() );
772 const SvxULSpaceItem
&rUL
= static_cast<const SwFormatChg
*>(pOld
)->pChangedFormat
->GetULSpace();
773 aOld
.Top( std::max( aOld
.Top() - long(rUL
.GetUpper()), 0L ) );
774 aOld
.SSize().AdjustHeight(rUL
.GetLower() );
775 const SvxLRSpaceItem
&rLR
= static_cast<const SwFormatChg
*>(pOld
)->pChangedFormat
->GetLRSpace();
776 aOld
.Left ( std::max( aOld
.Left() - rLR
.GetLeft(), 0L ) );
777 aOld
.SSize().AdjustWidth(rLR
.GetRight() );
779 NotifyBackground( FindPageFrame(), aNew
, PREP_CLEAR
);
782 // When assigning a template we cannot rely on the old column
783 // attribute. As there need to be at least enough for ChgColumns,
784 // we need to create a temporary attribute.
786 if ( Lower() && Lower()->IsColumnFrame() )
789 SwFrame
*pTmp
= Lower();
792 pTmp
= pTmp
->GetNext();
794 aCol
.Init( nCol
, 0, 1000 );
796 ChgColumns( aCol
, GetFormat()->GetCol() );
799 SwFormatURL
aURL( GetFormat()->GetURL() );
801 SwFormatFrameSize
*pNewFormatFrameSize
= nullptr;
802 SwFormatChg
*pOldFormatChg
= nullptr;
803 if (nWhich
== RES_FRM_SIZE
)
804 pNewFormatFrameSize
= const_cast<SwFormatFrameSize
*>(static_cast<const SwFormatFrameSize
*>(pNew
));
806 pOldFormatChg
= const_cast<SwFormatChg
*>(static_cast<const SwFormatChg
*>(pOld
));
808 if (aURL
.GetMap() && (pNewFormatFrameSize
|| pOldFormatChg
))
810 const SwFormatFrameSize
&rOld
= pNewFormatFrameSize
?
811 *pNewFormatFrameSize
:
812 pOldFormatChg
->pChangedFormat
->GetFrameSize();
813 //#35091# Can be "times zero", when loading the template
814 if ( rOld
.GetWidth() && rOld
.GetHeight() )
817 Fraction
aScaleX( rOld
.GetWidth(), rNew
.GetWidth() );
818 Fraction
aScaleY( rOld
.GetHeight(), rOld
.GetHeight() );
819 aURL
.GetMap()->Scale( aScaleX
, aScaleY
);
820 SwFrameFormat
*pFormat
= GetFormat();
821 pFormat
->LockModify();
822 pFormat
->SetFormatAttr( aURL
);
823 pFormat
->UnlockModify();
826 const SvxProtectItem
&rP
= GetFormat()->GetProtect();
827 GetVirtDrawObj()->SetMoveProtect( rP
.IsPosProtected() );
828 GetVirtDrawObj()->SetResizeProtect( rP
.IsSizeProtected() );
831 pSh
->InvalidateWindows( getFrameArea() );
832 const IDocumentDrawModelAccess
& rIDDMA
= GetFormat()->getIDocumentDrawModelAccess();
833 const SdrLayerID nId
= GetFormat()->GetOpaque().GetValue() ?
834 rIDDMA
.GetHeavenId() :
836 GetVirtDrawObj()->SetLayer( nId
);
840 // Delete contour in the Node if necessary
841 if( Lower()->IsNoTextFrame() &&
842 !GetFormat()->GetSurround().IsContour() )
844 SwNoTextNode
*pNd
= static_cast<SwNoTextNode
*>(static_cast<SwNoTextFrame
*>(Lower())->GetNode());
845 if ( pNd
->HasContour() )
846 pNd
->SetContour( nullptr );
848 else if( !Lower()->IsColumnFrame() )
850 SwFrame
* pFrame
= GetLastLower();
851 if( pFrame
->IsTextFrame() && static_cast<SwTextFrame
*>(pFrame
)->IsUndersized() )
852 pFrame
->Prepare( PREP_ADJUST_FRM
);
856 // #i28701# - perform reorder of object lists
857 // at anchor frame and at page frame.
866 if( pSh
&& pSh
->GetViewOptions()->getBrowseMode() )
867 getRootFrame()->InvalidateBrowseWidth();
868 SwRect
aNew( GetObjRectWithSpaces() );
869 SwRect
aOld( getFrameArea() );
872 if ( RES_UL_SPACE
== nWhich
)
874 const SvxULSpaceItem
&rUL
= *static_cast<const SvxULSpaceItem
*>(pNew
);
875 aOld
.Top( std::max( aOld
.Top() - long(rUL
.GetUpper()), 0L ) );
876 aOld
.SSize().AdjustHeight(rUL
.GetLower() );
880 const SvxLRSpaceItem
&rLR
= *static_cast<const SvxLRSpaceItem
*>(pNew
);
881 aOld
.Left ( std::max( aOld
.Left() - rLR
.GetLeft(), 0L ) );
882 aOld
.SSize().AdjustWidth(rLR
.GetRight() );
886 NotifyBackground( FindPageFrame(), aNew
, PREP_CLEAR
);
890 case RES_TEXT_VERT_ADJUST
:
892 InvalidateContentPos();
903 SetDerivedVert( false );
904 SetDerivedR2L( false );
911 pSh
->InvalidateWindows( getFrameArea() );
913 const IDocumentDrawModelAccess
& rIDDMA
= GetFormat()->getIDocumentDrawModelAccess();
914 const SdrLayerID nId
= static_cast<const SvxOpaqueItem
*>(pNew
)->GetValue() ?
915 rIDDMA
.GetHeavenId() :
917 GetVirtDrawObj()->SetLayer( nId
);
920 SwRootFrame
* pLayout
= getRootFrame();
921 if( pLayout
&& pLayout
->IsAnyShellAccessible() )
923 pSh
->Imp()->DisposeAccessibleFrame( this );
924 pSh
->Imp()->AddAccessibleFrame( this );
927 // #i28701# - perform reorder of object lists
928 // at anchor frame and at page frame.
934 // The interface changes the frame size when interacting with text frames,
935 // the Map, however, needs to be relative to FrameSize().
936 if ( (!Lower() || !Lower()->IsNoTextFrame()) && pNew
&& pOld
&&
937 static_cast<const SwFormatURL
*>(pNew
)->GetMap() && static_cast<const SwFormatURL
*>(pOld
)->GetMap() )
939 const SwFormatFrameSize
&rSz
= GetFormat()->GetFrameSize();
940 if ( rSz
.GetHeight() != getFrameArea().Height() ||
941 rSz
.GetWidth() != getFrameArea().Width() )
943 SwFormatURL
aURL( GetFormat()->GetURL() );
944 Fraction
aScaleX( getFrameArea().Width(), rSz
.GetWidth() );
945 Fraction
aScaleY( getFrameArea().Height(), rSz
.GetHeight() );
946 aURL
.GetMap()->Scale( aScaleX
, aScaleY
);
947 SwFrameFormat
*pFormat
= GetFormat();
948 pFormat
->LockModify();
949 pFormat
->SetFormatAttr( aURL
);
950 pFormat
->UnlockModify();
953 // No invalidation necessary
959 const SwFormatChain
*pChain
= static_cast<const SwFormatChain
*>(pNew
);
960 if ( pChain
->GetNext() )
962 SwFlyFrame
*pFollow
= FindChainNeighbour( *pChain
->GetNext() );
963 if ( GetNextLink() && pFollow
!= GetNextLink() )
964 SwFlyFrame::UnchainFrames( this, GetNextLink());
967 if ( pFollow
->GetPrevLink() &&
968 pFollow
->GetPrevLink() != this )
969 SwFlyFrame::UnchainFrames( pFollow
->GetPrevLink(),
971 if ( !GetNextLink() )
972 SwFlyFrame::ChainFrames( this, pFollow
);
975 else if ( GetNextLink() )
976 SwFlyFrame::UnchainFrames( this, GetNextLink() );
977 if ( pChain
->GetPrev() )
979 SwFlyFrame
*pMaster
= FindChainNeighbour( *pChain
->GetPrev() );
980 if ( GetPrevLink() && pMaster
!= GetPrevLink() )
981 SwFlyFrame::UnchainFrames( GetPrevLink(), this );
984 if ( pMaster
->GetNextLink() &&
985 pMaster
->GetNextLink() != this )
986 SwFlyFrame::UnchainFrames( pMaster
,
987 pMaster
->GetNextLink() );
988 if ( !GetPrevLink() )
989 SwFlyFrame::ChainFrames( pMaster
, this );
992 else if ( GetPrevLink() )
993 SwFlyFrame::UnchainFrames( GetPrevLink(), this );
1001 if ( pOldSet
|| pNewSet
)
1004 pOldSet
->ClearItem( nWhich
);
1006 pNewSet
->ClearItem( nWhich
);
1009 SwLayoutFrame::Modify( pOld
, pNew
);
1013 /// Gets information from the Modify
1014 bool SwFlyFrame::GetInfo( SfxPoolItem
& rInfo
) const
1016 if( RES_AUTOFMT_DOCNODE
== rInfo
.Which() )
1017 return false; // There's a FlyFrame, so use it
1018 return true; // Continue searching
1021 void SwFlyFrame::Invalidate_( SwPageFrame
const *pPage
)
1023 InvalidatePage( pPage
);
1024 m_bNotifyBack
= m_bInvalid
= true;
1027 if ( GetAnchorFrame() && nullptr != (pFrame
= AnchorFrame()->FindFlyFrame()) )
1029 // Very bad case: If the Fly is bound within another Fly which
1030 // contains columns, the Format should be from that one.
1031 if ( !pFrame
->IsLocked() && !pFrame
->IsColLocked() &&
1032 pFrame
->Lower() && pFrame
->Lower()->IsColumnFrame() )
1033 pFrame
->InvalidateSize();
1037 // if vertical position is oriented at a layout frame inside a ghost section,
1038 // assure that the position is invalidated and that the information about
1039 // the vertical position oriented frame is cleared
1040 if ( GetVertPosOrientFrame() && GetVertPosOrientFrame()->IsLayoutFrame() )
1042 const SwSectionFrame
* pSectFrame( GetVertPosOrientFrame()->FindSctFrame() );
1043 if ( pSectFrame
&& pSectFrame
->GetSection() == nullptr )
1046 ClearVertPosOrientFrame();
1051 /** Change the relative position
1053 * The position will be Fix automatically and the attribute is changed accordingly.
1055 void SwFlyFrame::ChgRelPos( const Point
&rNewPos
)
1057 if ( GetCurrRelPos() == rNewPos
)
1060 SwFrameFormat
*pFormat
= GetFormat();
1061 const bool bVert
= GetAnchorFrame()->IsVertical();
1062 const SwTwips nNewY
= bVert
? rNewPos
.X() : rNewPos
.Y();
1063 SwTwips nTmpY
= nNewY
== LONG_MAX
? 0 : nNewY
;
1066 SfxItemSet
aSet( pFormat
->GetDoc()->GetAttrPool(),
1067 svl::Items
<RES_VERT_ORIENT
, RES_HORI_ORIENT
>{});
1069 SwFormatVertOrient
aVert( pFormat
->GetVertOrient() );
1070 const SwTextFrame
*pAutoFrame
= nullptr;
1071 // #i34948# - handle also at-page and at-fly anchored
1072 // Writer fly frames
1073 const RndStdIds eAnchorType
= GetFrameFormat().GetAnchor().GetAnchorId();
1074 if ( eAnchorType
== RndStdIds::FLY_AT_PAGE
)
1076 aVert
.SetVertOrient( text::VertOrientation::NONE
);
1077 aVert
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
1079 else if ( eAnchorType
== RndStdIds::FLY_AT_FLY
)
1081 aVert
.SetVertOrient( text::VertOrientation::NONE
);
1082 aVert
.SetRelationOrient( text::RelOrientation::FRAME
);
1084 else if ( IsFlyAtContentFrame() || text::VertOrientation::NONE
!= aVert
.GetVertOrient() )
1086 if( text::RelOrientation::CHAR
== aVert
.GetRelationOrient() && IsAutoPos() )
1088 if( LONG_MAX
!= nNewY
)
1090 aVert
.SetVertOrient( text::VertOrientation::NONE
);
1091 assert(GetAnchorFrame()->IsTextFrame());
1092 pAutoFrame
= static_cast<const SwTextFrame
*>(GetAnchorFrame());
1093 TextFrameIndex
const nOfs(pAutoFrame
->MapModelToViewPos(
1094 *pFormat
->GetAnchor().GetContentAnchor()));
1095 while( pAutoFrame
->GetFollow() &&
1096 pAutoFrame
->GetFollow()->GetOfst() <= nOfs
)
1098 if( pAutoFrame
== GetAnchorFrame() )
1099 nTmpY
+= pAutoFrame
->GetRelPos().Y();
1100 nTmpY
-= pAutoFrame
->GetUpper()->getFramePrintArea().Height();
1101 pAutoFrame
= pAutoFrame
->GetFollow();
1103 nTmpY
= static_cast<SwFlyAtContentFrame
*>(this)->GetRelCharY(pAutoFrame
)-nTmpY
;
1106 aVert
.SetVertOrient( text::VertOrientation::CHAR_BOTTOM
);
1110 aVert
.SetVertOrient( text::VertOrientation::NONE
);
1111 aVert
.SetRelationOrient( text::RelOrientation::FRAME
);
1114 aVert
.SetPos( nTmpY
);
1117 // For Flys in the Cnt, the horizontal orientation is of no interest,
1119 if ( !IsFlyInContentFrame() )
1121 const SwTwips nNewX
= bVert
? rNewPos
.Y() : rNewPos
.X();
1122 SwTwips nTmpX
= nNewX
== LONG_MAX
? 0 : nNewX
;
1123 SwFormatHoriOrient
aHori( pFormat
->GetHoriOrient() );
1124 // #i34948# - handle also at-page and at-fly anchored
1125 // Writer fly frames
1126 if ( eAnchorType
== RndStdIds::FLY_AT_PAGE
)
1128 aHori
.SetHoriOrient( text::HoriOrientation::NONE
);
1129 aHori
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
1130 aHori
.SetPosToggle( false );
1132 else if ( eAnchorType
== RndStdIds::FLY_AT_FLY
)
1134 aHori
.SetHoriOrient( text::HoriOrientation::NONE
);
1135 aHori
.SetRelationOrient( text::RelOrientation::FRAME
);
1136 aHori
.SetPosToggle( false );
1138 else if ( IsFlyAtContentFrame() || text::HoriOrientation::NONE
!= aHori
.GetHoriOrient() )
1140 aHori
.SetHoriOrient( text::HoriOrientation::NONE
);
1141 if( text::RelOrientation::CHAR
== aHori
.GetRelationOrient() && IsAutoPos() )
1143 if( LONG_MAX
!= nNewX
)
1147 assert(GetAnchorFrame()->IsTextFrame());
1148 pAutoFrame
= static_cast<const SwTextFrame
*>(GetAnchorFrame());
1149 TextFrameIndex
const nOfs(pAutoFrame
->MapModelToViewPos(
1150 *pFormat
->GetAnchor().GetContentAnchor()));
1151 while( pAutoFrame
->GetFollow() &&
1152 pAutoFrame
->GetFollow()->GetOfst() <= nOfs
)
1153 pAutoFrame
= pAutoFrame
->GetFollow();
1155 nTmpX
-= static_cast<SwFlyAtContentFrame
*>(this)->GetRelCharX(pAutoFrame
);
1159 aHori
.SetRelationOrient( text::RelOrientation::FRAME
);
1160 aHori
.SetPosToggle( false );
1162 aHori
.SetPos( nTmpX
);
1165 SetCurrRelPos( rNewPos
);
1166 pFormat
->GetDoc()->SetAttr( aSet
, *pFormat
);
1170 /** "Formats" the Frame; Frame and PrtArea.
1172 * The FixSize is not inserted here.
1174 void SwFlyFrame::Format( vcl::RenderContext
* /*pRenderContext*/, const SwBorderAttrs
*pAttrs
)
1176 OSL_ENSURE( pAttrs
, "FlyFrame::Format, pAttrs is 0." );
1180 if ( !isFrameAreaSizeValid() )
1182 if ( getFrameArea().Top() == FAR_AWAY
&& getFrameArea().Left() == FAR_AWAY
)
1184 // Remove safety switch (see SwFrame::CTor)
1186 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
1192 InvalidateObjRectWithSpaces();
1195 // Check column width and set it if needed
1196 if ( Lower() && Lower()->IsColumnFrame() )
1197 AdjustColumns( nullptr, false );
1199 setFrameAreaSizeValid(true);
1201 const SwTwips nUL
= pAttrs
->CalcTopLine() + pAttrs
->CalcBottomLine();
1202 const SwTwips nLR
= pAttrs
->CalcLeftLine() + pAttrs
->CalcRightLine();
1203 const SwFormatFrameSize
&rFrameSz
= GetFormat()->GetFrameSize();
1204 Size
aRelSize( CalcRel( rFrameSz
) );
1206 OSL_ENSURE( pAttrs
->GetSize().Height() != 0 || rFrameSz
.GetHeightPercent(), "FrameAttr height is 0." );
1207 OSL_ENSURE( pAttrs
->GetSize().Width() != 0 || rFrameSz
.GetWidthPercent(), "FrameAttr width is 0." );
1209 SwRectFnSet
aRectFnSet(this);
1212 long nMinHeight
= 0;
1214 nMinHeight
= aRectFnSet
.IsVert() ? aRelSize
.Width() : aRelSize
.Height();
1216 SwTwips nRemaining
= CalcContentHeight(pAttrs
, nMinHeight
, nUL
);
1217 if( IsMinHeight() && (nRemaining
+ nUL
) < nMinHeight
)
1218 nRemaining
= nMinHeight
- nUL
;
1219 // Because the Grow/Shrink of the Flys does not directly
1220 // set the size - only indirectly by triggering a Format()
1221 // via Invalidate() - the sizes need to be set here.
1222 // Notification is running along already.
1223 // As we already got a lot of zeros per attribute, we block them
1226 if ( nRemaining
< MINFLY
)
1227 nRemaining
= MINFLY
;
1230 SwFrameAreaDefinition::FramePrintAreaWriteAccess
aPrt(*this);
1231 aRectFnSet
.SetHeight( aPrt
, nRemaining
);
1234 nRemaining
-= aRectFnSet
.GetHeight(getFrameArea());
1237 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
1238 aRectFnSet
.AddBottom( aFrm
, nRemaining
+ nUL
);
1242 if ( nRemaining
+ nUL
!= 0 )
1244 InvalidateObjRectWithSpaces();
1247 setFrameAreaSizeValid(true);
1249 if (SwFrameFormat
* pShapeFormat
= SwTextBoxHelper::getOtherTextBoxFormat(GetFormat(), RES_FLYFRMFMT
))
1251 // This fly is a textbox of a draw shape.
1252 SdrObject
* pShape
= pShapeFormat
->FindSdrObject();
1253 if (SdrObjCustomShape
* pCustomShape
= dynamic_cast<SdrObjCustomShape
*>( pShape
) )
1255 // The shape is a customshape: then inform it about the calculated fly size.
1256 Size
aSize(aRectFnSet
.GetWidth(getFrameArea()), aRectFnSet
.GetHeight(getFrameArea()));
1257 pCustomShape
->SuggestTextFrameSize(aSize
);
1258 // Do the calculations normally done after touching editeng text of the shape.
1259 pCustomShape
->NbcSetOutlinerParaObjectForText(nullptr, nullptr);
1265 // Fixed Frames do not Format itself
1266 setFrameAreaSizeValid(true);
1268 // Flys set their size using the attr
1269 SwTwips nNewSize
= aRectFnSet
.IsVert() ? aRelSize
.Width() : aRelSize
.Height();
1271 if( nNewSize
< MINFLY
)
1275 SwFrameAreaDefinition::FramePrintAreaWriteAccess
aPrt(*this);
1276 aRectFnSet
.SetHeight( aPrt
, nNewSize
);
1279 nNewSize
+= nUL
- aRectFnSet
.GetHeight(getFrameArea());
1282 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
1283 aRectFnSet
.AddBottom( aFrm
, nNewSize
);
1287 if ( nNewSize
!= 0 )
1289 InvalidateObjRectWithSpaces();
1293 if ( !m_bFormatHeightOnly
)
1295 OSL_ENSURE( aRelSize
== CalcRel( rFrameSz
), "SwFlyFrame::Format CalcRel problem" );
1296 SwTwips nNewSize
= aRectFnSet
.IsVert() ? aRelSize
.Height() : aRelSize
.Width();
1298 if ( rFrameSz
.GetWidthSizeType() != ATT_FIX_SIZE
)
1300 // #i9046# Autowidth for fly frames
1301 const SwTwips nAutoWidth
= lcl_CalcAutoWidth( *this );
1304 if( ATT_MIN_SIZE
== rFrameSz
.GetWidthSizeType() )
1305 nNewSize
= std::max( nNewSize
- nLR
, nAutoWidth
);
1307 nNewSize
= nAutoWidth
;
1313 if( nNewSize
< MINFLY
)
1317 SwFrameAreaDefinition::FramePrintAreaWriteAccess
aPrt(*this);
1318 aRectFnSet
.SetWidth( aPrt
, nNewSize
);
1321 nNewSize
+= nLR
- aRectFnSet
.GetWidth(getFrameArea());
1324 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
1325 aRectFnSet
.AddRight( aFrm
, nNewSize
);
1329 if ( nNewSize
!= 0 )
1331 InvalidateObjRectWithSpaces();
1338 // OD 14.03.2003 #i11760# - change parameter <bNoColl>: type <bool>;
1339 // default value = false.
1340 // OD 14.03.2003 #i11760# - add new parameter <bNoCalcFollow> with
1341 // default value = false.
1342 // OD 11.04.2003 #108824# - new parameter <bNoCalcFollow> was used by method
1343 // <FormatWidthCols(..)> to avoid follow formatting
1344 // for text frames. But, unformatted follows causes
1345 // problems in method <SwContentFrame::WouldFit_(..)>,
1346 // which assumes that the follows are formatted.
1347 // Thus, <bNoCalcFollow> no longer used by <FormatWidthCols(..)>.
1348 void CalcContent( SwLayoutFrame
*pLay
, bool bNoColl
)
1350 vcl::RenderContext
* pRenderContext
= pLay
->getRootFrame()->GetCurrShell()->GetOut();
1351 SwSectionFrame
* pSect
;
1352 bool bCollect
= false;
1353 if( pLay
->IsSctFrame() )
1355 pSect
= static_cast<SwSectionFrame
*>(pLay
);
1356 if( pSect
->IsEndnAtEnd() && !bNoColl
)
1359 SwLayouter::CollectEndnotes( pLay
->GetFormat()->GetDoc(), pSect
);
1361 pSect
->CalcFootnoteContent();
1365 SwFrame
*pFrame
= pLay
->ContainsAny();
1370 if( pSect
->HasFollow() )
1371 pFrame
= pSect
->GetFollow()->ContainsAny();
1374 if( pSect
->IsEndnAtEnd() )
1377 pLay
->GetFormat()->GetDoc()->getIDocumentLayoutAccess().GetLayouter()->
1378 InsertEndnotes( pSect
);
1379 bool bLock
= pSect
->IsFootnoteLock();
1380 pSect
->SetFootnoteLock( true );
1381 pSect
->CalcFootnoteContent();
1382 pSect
->CalcFootnoteContent();
1383 pSect
->SetFootnoteLock( bLock
);
1387 pFrame
->InvalidatePos_();
1392 pFrame
->InvalidatePage();
1396 // local variables to avoid loops caused by anchored object positioning
1397 SwAnchoredObject
* pAgainObj1
= nullptr;
1398 SwAnchoredObject
* pAgainObj2
= nullptr;
1400 // FME 2007-08-30 #i81146# new loop control
1401 int nLoopControlRuns
= 0;
1402 const int nLoopControlMax
= 20;
1403 const SwFrame
* pLoopControlCond
= nullptr;
1409 if( pFrame
->IsVertical() ?
1410 ( pFrame
->GetUpper()->getFramePrintArea().Height() != pFrame
->getFrameArea().Height() )
1411 : ( pFrame
->GetUpper()->getFramePrintArea().Width() != pFrame
->getFrameArea().Width() ) )
1413 pFrame
->Prepare( PREP_FIXSIZE_CHG
);
1414 pFrame
->InvalidateSize_();
1417 if ( pFrame
->IsTabFrame() )
1419 static_cast<SwTabFrame
*>(pFrame
)->m_bCalcLowers
= true;
1420 // OD 26.08.2003 #i18103# - lock move backward of follow table,
1421 // if no section content is formatted or follow table belongs
1422 // to the section, which content is formatted.
1423 if ( static_cast<SwTabFrame
*>(pFrame
)->IsFollow() &&
1424 ( !pSect
|| pSect
== pFrame
->FindSctFrame() ) )
1426 static_cast<SwTabFrame
*>(pFrame
)->m_bLockBackMove
= true;
1431 SwFrameDeleteGuard
aDeletePageGuard(pSect
? pSect
->FindPageFrame() : nullptr);
1432 SwFrameDeleteGuard
aDeleteGuard(pSect
);
1433 pFrame
->Calc(pRenderContext
);
1436 // OD 14.03.2003 #i11760# - reset control flag for follow format.
1437 if ( pFrame
->IsTextFrame() )
1439 static_cast<SwTextFrame
*>(pFrame
)->AllowFollowFormat();
1442 // #111937# The keep-attribute can cause the position
1443 // of the prev to be invalid:
1444 // OD 2004-03-15 #116560# - Do not consider invalid previous frame
1445 // due to its keep-attribute, if current frame is a follow or is locked.
1446 // #i44049# - do not consider invalid previous
1447 // frame due to its keep-attribute, if it can't move forward.
1448 // #i57765# - do not consider invalid previous
1449 // frame, if current frame has a column/page break before attribute.
1450 SwFrame
* pTmpPrev
= pFrame
->FindPrev();
1451 SwFlowFrame
* pTmpPrevFlowFrame
= pTmpPrev
&& pTmpPrev
->IsFlowFrame() ? SwFlowFrame::CastFlowFrame(pTmpPrev
) : nullptr;
1452 SwFlowFrame
* pTmpFlowFrame
= pFrame
->IsFlowFrame() ? SwFlowFrame::CastFlowFrame(pFrame
) : nullptr;
1454 bool bPrevInvalid
= pTmpPrevFlowFrame
&& pTmpFlowFrame
&&
1455 !pTmpFlowFrame
->IsFollow() &&
1456 !StackHack::IsLocked() && // #i76382#
1457 !pTmpFlowFrame
->IsJoinLocked() &&
1458 !pTmpPrev
->isFrameAreaPositionValid() &&
1459 pLay
->IsAnLower( pTmpPrev
) &&
1460 pTmpPrevFlowFrame
->IsKeep(pTmpPrev
->GetAttrSet()->GetKeep(), pTmpPrev
->GetBreakItem()) &&
1461 pTmpPrevFlowFrame
->IsKeepFwdMoveAllowed();
1463 // format floating screen objects anchored to the frame.
1464 if ( !bPrevInvalid
&& pFrame
->GetDrawObjs() && pLay
->IsAnLower( pFrame
) )
1466 bool bAgain
= false;
1467 bool bRestartLayoutProcess
= false;
1468 SwPageFrame
* pPageFrame
= pFrame
->FindPageFrame();
1469 size_t nCnt
= pFrame
->GetDrawObjs()->size();
1474 SwAnchoredObject
* pAnchoredObj
= (*pFrame
->GetDrawObjs())[i
];
1476 // determine if anchored object has to be
1477 // formatted and, in case, format it
1478 if ( !pAnchoredObj
->PositionLocked() && pAnchoredObj
->IsFormatPossible() )
1480 // #i43737# - no invalidation of
1481 // anchored object needed - causes loops for as-character
1482 // anchored objects.
1483 //pAnchoredObj->InvalidateObjPos();
1484 SwRect
aRect( pAnchoredObj
->GetObjRect() );
1485 if ( !SwObjectFormatter::FormatObj( *pAnchoredObj
, pFrame
, pPageFrame
) )
1487 bRestartLayoutProcess
= true;
1490 // #i3317# - restart layout process,
1491 // if the position of the anchored object is locked now.
1492 if ( pAnchoredObj
->PositionLocked() )
1494 bRestartLayoutProcess
= true;
1498 if ( aRect
!= pAnchoredObj
->GetObjRect() )
1501 if ( pAgainObj2
== pAnchoredObj
)
1503 OSL_FAIL( "::CalcContent(..) - loop detected, perform attribute changes to avoid the loop" );
1504 // Prevent oscillation
1505 SwFrameFormat
& rFormat
= pAnchoredObj
->GetFrameFormat();
1506 SwFormatSurround
aAttr( rFormat
.GetSurround() );
1507 if( css::text::WrapTextMode_THROUGH
!= aAttr
.GetSurround() )
1509 // When on auto position, we can only set it to
1511 if ((rFormat
.GetAnchor().GetAnchorId() ==
1512 RndStdIds::FLY_AT_CHAR
) &&
1513 (css::text::WrapTextMode_PARALLEL
==
1514 aAttr
.GetSurround()))
1516 aAttr
.SetSurround( css::text::WrapTextMode_THROUGH
);
1520 aAttr
.SetSurround( css::text::WrapTextMode_PARALLEL
);
1522 rFormat
.LockModify();
1523 rFormat
.SetFormatAttr( aAttr
);
1524 rFormat
.UnlockModify();
1529 if ( pAgainObj1
== pAnchoredObj
)
1530 pAgainObj2
= pAnchoredObj
;
1531 pAgainObj1
= pAnchoredObj
;
1535 if ( !pFrame
->GetDrawObjs() )
1537 if ( pFrame
->GetDrawObjs()->size() < nCnt
)
1540 // Do not increment index, in this case
1547 // #i28701# - restart layout process, if
1548 // requested by floating screen object formatting
1549 if ( bRestartLayoutProcess
)
1551 pFrame
= pLay
->ContainsAny();
1552 pAgainObj1
= nullptr;
1553 pAgainObj2
= nullptr;
1557 // OD 2004-05-17 #i28701# - format anchor frame after its objects
1558 // are formatted, if the wrapping style influence has to be considered.
1559 if ( pLay
->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION
) )
1561 pFrame
->Calc(pRenderContext
);
1566 pFrame
= pLay
->ContainsContent();
1567 if ( pFrame
&& pFrame
->IsInTab() )
1568 pFrame
= pFrame
->FindTabFrame();
1569 if( pFrame
&& pFrame
->IsInSct() )
1571 SwSectionFrame
* pTmp
= pFrame
->FindSctFrame();
1572 if( pTmp
!= pLay
&& pLay
->IsAnLower( pTmp
) )
1576 if ( pFrame
== pLoopControlCond
)
1580 nLoopControlRuns
= 0;
1581 pLoopControlCond
= pFrame
;
1584 if ( nLoopControlRuns
< nLoopControlMax
)
1587 OSL_FAIL( "LoopControl in CalcContent" );
1590 if ( pFrame
->IsTabFrame() )
1592 if ( static_cast<SwTabFrame
*>(pFrame
)->IsFollow() )
1593 static_cast<SwTabFrame
*>(pFrame
)->m_bLockBackMove
= false;
1596 pFrame
= bPrevInvalid
? pTmpPrev
: pFrame
->FindNext();
1597 if( !bPrevInvalid
&& pFrame
&& pFrame
->IsSctFrame() && pSect
)
1599 // Empty SectionFrames could be present here
1600 while( pFrame
&& pFrame
->IsSctFrame() && !static_cast<SwSectionFrame
*>(pFrame
)->GetSection() )
1601 pFrame
= pFrame
->FindNext();
1603 // If FindNext returns the Follow of the original Area, we want to
1604 // continue with this content as long as it flows back.
1605 if( pFrame
&& pFrame
->IsSctFrame() && ( pFrame
== pSect
->GetFollow() ||
1606 static_cast<SwSectionFrame
*>(pFrame
)->IsAnFollow( pSect
) ) )
1608 pFrame
= static_cast<SwSectionFrame
*>(pFrame
)->ContainsAny();
1610 pFrame
->InvalidatePos_();
1614 // Except for SectionFrames with Follow: the first ContentFrame of the Follow
1615 // will be formatted, so that it gets a chance to load in the pLay.
1616 // As long as these Frames are loading in pLay, we continue
1618 ( pLay
->IsAnLower( pFrame
) ||
1620 ( ( pSect
->HasFollow() &&
1621 ( pLay
->IsAnLower( pLast
) ||
1622 ( pLast
->IsInSct() &&
1623 pLast
->FindSctFrame()->IsAnFollow(pSect
) ) ) &&
1624 pSect
->GetFollow()->IsAnLower( pFrame
) ) ||
1625 ( pFrame
->IsInSct() &&
1626 pFrame
->FindSctFrame()->IsAnFollow( pSect
) ) ) ) ) );
1631 pLay
->GetFormat()->GetDoc()->getIDocumentLayoutAccess().GetLayouter()->InsertEndnotes(pSect
);
1632 pSect
->CalcFootnoteContent();
1634 if( pSect
->HasFollow() )
1636 SwSectionFrame
* pNxt
= pSect
->GetFollow();
1637 while( pNxt
&& !pNxt
->ContainsContent() )
1638 pNxt
= pNxt
->GetFollow();
1640 pNxt
->CalcFootnoteContent();
1644 pFrame
= pLay
->ContainsAny();
1655 // OD 2004-03-23 #i26791#
1656 void SwFlyFrame::MakeObjPos()
1658 if ( !isFrameAreaPositionValid() )
1660 vcl::RenderContext
* pRenderContext
= getRootFrame()->GetCurrShell()->GetOut();
1661 setFrameAreaPositionValid(true);
1663 // OD 29.10.2003 #113049# - use new class to position object
1664 GetAnchorFrame()->Calc(pRenderContext
);
1665 objectpositioning::SwToLayoutAnchoredObjectPosition
1666 aObjPositioning( *GetVirtDrawObj() );
1667 aObjPositioning
.CalcPosition();
1670 // update relative position
1671 SetCurrRelPos( aObjPositioning
.GetRelPos() );
1674 SwRectFnSet
aRectFnSet(GetAnchorFrame());
1675 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
1676 aFrm
.Pos( aObjPositioning
.GetRelPos() );
1677 aFrm
.Pos() += aRectFnSet
.GetPos(GetAnchorFrame()->getFrameArea());
1681 InvalidateObjRectWithSpaces();
1685 void SwFlyFrame::MakePrtArea( const SwBorderAttrs
&rAttrs
)
1687 if ( !isFramePrintAreaValid() )
1689 setFramePrintAreaValid(true);
1691 // OD 31.07.2003 #110978# - consider vertical layout
1692 SwRectFnSet
aRectFnSet(this);
1693 aRectFnSet
.SetXMargins( *this, rAttrs
.CalcLeftLine(),
1694 rAttrs
.CalcRightLine() );
1695 aRectFnSet
.SetYMargins( *this, rAttrs
.CalcTopLine(),
1696 rAttrs
.CalcBottomLine() );
1700 void SwFlyFrame::MakeContentPos( const SwBorderAttrs
&rAttrs
)
1702 if ( m_bValidContentPos
)
1705 m_bValidContentPos
= true;
1707 const SwTwips nUL
= rAttrs
.CalcTopLine() + rAttrs
.CalcBottomLine();
1708 Size
aRelSize( CalcRel( GetFormat()->GetFrameSize() ) );
1710 SwRectFnSet
aRectFnSet(this);
1711 long nMinHeight
= 0;
1713 nMinHeight
= aRectFnSet
.IsVert() ? aRelSize
.Width() : aRelSize
.Height();
1715 Point aNewContentPos
;
1716 aNewContentPos
= getFramePrintArea().Pos();
1717 const SdrTextVertAdjust nAdjust
= GetFormat()->GetTextVertAdjust().GetValue();
1719 if( nAdjust
!= SDRTEXTVERTADJUST_TOP
)
1721 const SwTwips nContentHeight
= CalcContentHeight(&rAttrs
, nMinHeight
, nUL
);
1724 if( nContentHeight
!= 0)
1725 nDiff
= aRectFnSet
.GetHeight(getFramePrintArea()) - nContentHeight
;
1729 if( nAdjust
== SDRTEXTVERTADJUST_CENTER
)
1731 if( aRectFnSet
.IsVertL2R() )
1732 aNewContentPos
.setX(aNewContentPos
.getX() + nDiff
/2);
1733 else if( aRectFnSet
.IsVert() )
1734 aNewContentPos
.setX(aNewContentPos
.getX() - nDiff
/2);
1736 aNewContentPos
.setY(aNewContentPos
.getY() + nDiff
/2);
1738 else if( nAdjust
== SDRTEXTVERTADJUST_BOTTOM
)
1740 if( aRectFnSet
.IsVertL2R() )
1741 aNewContentPos
.setX(aNewContentPos
.getX() + nDiff
);
1742 else if( aRectFnSet
.IsVert() )
1743 aNewContentPos
.setX(aNewContentPos
.getX() - nDiff
);
1745 aNewContentPos
.setY(aNewContentPos
.getY() + nDiff
);
1749 if( aNewContentPos
!= ContentPos() )
1751 ContentPos() = aNewContentPos
;
1752 for( SwFrame
*pFrame
= Lower(); pFrame
; pFrame
= pFrame
->GetNext())
1754 pFrame
->InvalidatePos();
1760 void SwFlyFrame::InvalidateContentPos()
1762 m_bValidContentPos
= false;
1766 SwTwips
SwFlyFrame::Grow_( SwTwips nDist
, bool bTst
)
1768 SwRectFnSet
aRectFnSet(this);
1769 if ( Lower() && !IsColLocked() && !HasFixSize() )
1771 SwTwips nSize
= aRectFnSet
.GetHeight(getFrameArea());
1772 if( nSize
> 0 && nDist
> ( LONG_MAX
- nSize
) )
1773 nDist
= LONG_MAX
- nSize
;
1778 if ( Lower()->IsColumnFrame() )
1779 { // If it's a Column Frame, the Format takes control of the
1780 // resizing (due to the adjustment).
1783 // #i28701# - unlock position of Writer fly frame
1793 const SwRect
aOld( GetObjRectWithSpaces() );
1795 const bool bOldLock
= m_bLocked
;
1797 if ( IsFlyFreeFrame() )
1799 // #i37068# - no format of position here
1800 // and prevent move in method <CheckClip(..)>.
1801 // This is needed to prevent layout loop caused by nested
1802 // Writer fly frames - inner Writer fly frames format its
1803 // anchor, which grows/shrinks the outer Writer fly frame.
1804 // Note: position will be invalidated below.
1805 setFrameAreaPositionValid(true);
1808 // Suppress format of width for autowidth frame, because the
1809 // format of the width would call <SwTextFrame::CalcFitToContent()>
1810 // for the lower frame, which initiated this grow.
1811 const bool bOldFormatHeightOnly
= m_bFormatHeightOnly
;
1812 const SwFormatFrameSize
& rFrameSz
= GetFormat()->GetFrameSize();
1813 if ( rFrameSz
.GetWidthSizeType() != ATT_FIX_SIZE
)
1815 m_bFormatHeightOnly
= true;
1817 SwViewShell
* pSh
= getRootFrame()->GetCurrShell();
1820 static_cast<SwFlyFreeFrame
*>(this)->SetNoMoveOnCheckClip( true );
1821 static_cast<SwFlyFreeFrame
*>(this)->SwFlyFreeFrame::MakeAll(pSh
->GetOut());
1822 static_cast<SwFlyFreeFrame
*>(this)->SetNoMoveOnCheckClip( false );
1825 if ( rFrameSz
.GetWidthSizeType() != ATT_FIX_SIZE
)
1827 m_bFormatHeightOnly
= bOldFormatHeightOnly
;
1831 MakeAll(getRootFrame()->GetCurrShell()->GetOut());
1836 const SwRect
aNew( GetObjRectWithSpaces() );
1838 ::Notify( this, FindPageFrame(), aOld
);
1839 return aRectFnSet
.GetHeight(aNew
)-aRectFnSet
.GetHeight(aOld
);
1846 SwTwips
SwFlyFrame::Shrink_( SwTwips nDist
, bool bTst
)
1848 if( Lower() && !IsColLocked() && !HasFixSize() )
1850 SwRectFnSet
aRectFnSet(this);
1851 SwTwips nHeight
= aRectFnSet
.GetHeight(getFrameArea());
1852 if ( nDist
> nHeight
)
1855 SwTwips nVal
= nDist
;
1856 if ( IsMinHeight() )
1858 const SwFormatFrameSize
& rFormatSize
= GetFormat()->GetFrameSize();
1859 SwTwips nFormatHeight
= aRectFnSet
.IsVert() ? rFormatSize
.GetWidth() : rFormatSize
.GetHeight();
1861 nVal
= std::min( nDist
, nHeight
- nFormatHeight
);
1867 if ( Lower()->IsColumnFrame() )
1868 { // If it's a Column Frame, the Format takes control of the
1869 // resizing (due to the adjustment).
1872 SwRect
aOld( GetObjRectWithSpaces() );
1875 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
1876 aRectFnSet
.SetHeight( aFrm
, nHeight
- nVal
);
1880 if ( nHeight
- nVal
!= 0 )
1882 InvalidateObjRectWithSpaces();
1885 nHeight
= aRectFnSet
.GetHeight(getFramePrintArea());
1888 SwFrameAreaDefinition::FramePrintAreaWriteAccess
aPrt(*this);
1889 aRectFnSet
.SetHeight( aPrt
, nHeight
- nVal
);
1894 ::Notify( this, FindPageFrame(), aOld
);
1896 if ( GetAnchorFrame()->IsInFly() )
1897 AnchorFrame()->FindFlyFrame()->Shrink( nDist
, bTst
);
1904 const SwRect
aOld( GetObjRectWithSpaces() );
1906 const bool bOldLocked
= m_bLocked
;
1908 if ( IsFlyFreeFrame() )
1910 // #i37068# - no format of position here
1911 // and prevent move in method <CheckClip(..)>.
1912 // This is needed to prevent layout loop caused by nested
1913 // Writer fly frames - inner Writer fly frames format its
1914 // anchor, which grows/shrinks the outer Writer fly frame.
1915 // Note: position will be invalidated below.
1916 setFrameAreaPositionValid(true);
1919 // Suppress format of width for autowidth frame, because the
1920 // format of the width would call <SwTextFrame::CalcFitToContent()>
1921 // for the lower frame, which initiated this shrink.
1922 const bool bOldFormatHeightOnly
= m_bFormatHeightOnly
;
1923 const SwFormatFrameSize
& rFrameSz
= GetFormat()->GetFrameSize();
1924 if ( rFrameSz
.GetWidthSizeType() != ATT_FIX_SIZE
)
1926 m_bFormatHeightOnly
= true;
1928 static_cast<SwFlyFreeFrame
*>(this)->SetNoMoveOnCheckClip( true );
1929 static_cast<SwFlyFreeFrame
*>(this)->SwFlyFreeFrame::MakeAll(getRootFrame()->GetCurrShell()->GetOut());
1930 static_cast<SwFlyFreeFrame
*>(this)->SetNoMoveOnCheckClip( false );
1932 if ( rFrameSz
.GetWidthSizeType() != ATT_FIX_SIZE
)
1934 m_bFormatHeightOnly
= bOldFormatHeightOnly
;
1938 MakeAll(getRootFrame()->GetCurrShell()->GetOut());
1943 const SwRect
aNew( GetObjRectWithSpaces() );
1946 ::Notify( this, FindPageFrame(), aOld
);
1947 if ( GetAnchorFrame()->IsInFly() )
1948 AnchorFrame()->FindFlyFrame()->Shrink( nDist
, bTst
);
1950 return aRectFnSet
.GetHeight(aOld
) -
1951 aRectFnSet
.GetHeight(aNew
);
1958 Size
SwFlyFrame::ChgSize( const Size
& aNewSize
)
1961 // If the fly frame anchored at-paragraph or at-character contains an OLE
1962 // object, assure that the new size fits into the current clipping area
1964 Size
aAdjustedNewSize( aNewSize
);
1966 if ( dynamic_cast<SwFlyAtContentFrame
*>(this) &&
1967 Lower() && dynamic_cast<SwNoTextFrame
*>(Lower()) &&
1968 static_cast<SwNoTextFrame
*>(Lower())->GetNode()->GetOLENode() )
1971 ::CalcClipRect( GetVirtDrawObj(), aClipRect
, false );
1972 if ( aAdjustedNewSize
.Width() > aClipRect
.Width() )
1974 aAdjustedNewSize
.setWidth( aClipRect
.Width() );
1976 if ( aAdjustedNewSize
.Height() > aClipRect
.Height() )
1978 aAdjustedNewSize
.setWidth( aClipRect
.Height() );
1983 if ( aAdjustedNewSize
!= getFrameArea().SSize() )
1985 SwFrameFormat
*pFormat
= GetFormat();
1986 SwFormatFrameSize
aSz( pFormat
->GetFrameSize() );
1987 aSz
.SetWidth( aAdjustedNewSize
.Width() );
1988 aSz
.SetHeight( aAdjustedNewSize
.Height() );
1989 // go via the Doc for UNDO
1990 pFormat
->GetDoc()->SetAttr( aSz
, *pFormat
);
1991 return aSz
.GetSize();
1994 return getFrameArea().SSize();
1997 bool SwFlyFrame::IsLowerOf( const SwLayoutFrame
* pUpperFrame
) const
1999 OSL_ENSURE( GetAnchorFrame(), "8-( Fly is lost in Space." );
2000 const SwFrame
* pFrame
= GetAnchorFrame();
2003 if ( pFrame
== pUpperFrame
)
2005 pFrame
= pFrame
->IsFlyFrame()
2006 ? static_cast<const SwFlyFrame
*>(pFrame
)->GetAnchorFrame()
2007 : pFrame
->GetUpper();
2012 void SwFlyFrame::Cut()
2016 void SwFrame::AppendFly( SwFlyFrame
*pNew
)
2020 m_pDrawObjs
.reset(new SwSortedObjs());
2022 m_pDrawObjs
->Insert( *pNew
);
2023 pNew
->ChgAnchorFrame( this );
2025 // Register at the page
2026 // If there's none present, register via SwPageFrame::PreparePage
2027 SwPageFrame
* pPage
= FindPageFrame();
2028 if ( pPage
!= nullptr )
2030 pPage
->AppendFlyToPage( pNew
);
2034 void SwFrame::RemoveFly( SwFlyFrame
*pToRemove
)
2036 // Deregister from the page
2037 // Could already have happened, if the page was already destructed
2038 SwPageFrame
*pPage
= pToRemove
->FindPageFrame();
2039 if ( pPage
&& pPage
->GetSortedObjs() )
2041 pPage
->RemoveFlyFromPage( pToRemove
);
2046 if ( pToRemove
->IsAccessibleFrame() &&
2047 pToRemove
->GetFormat() &&
2048 !pToRemove
->IsFlyInContentFrame() )
2050 SwRootFrame
*pRootFrame
= getRootFrame();
2051 if( pRootFrame
&& pRootFrame
->IsAnyShellAccessible() )
2053 SwViewShell
*pVSh
= pRootFrame
->GetCurrShell();
2054 if( pVSh
&& pVSh
->Imp() )
2056 pVSh
->Imp()->DisposeAccessibleFrame( pToRemove
);
2062 m_pDrawObjs
->Remove(*pToRemove
);
2063 if (!m_pDrawObjs
->size())
2065 m_pDrawObjs
.reset();
2068 pToRemove
->ChgAnchorFrame( nullptr );
2070 if ( !pToRemove
->IsFlyInContentFrame() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
2071 GetUpper()->InvalidateSize();
2074 void SwFrame::AppendDrawObj( SwAnchoredObject
& _rNewObj
)
2076 assert(!m_pDrawObjs
|| m_pDrawObjs
->is_sorted());
2078 if ( dynamic_cast<const SwAnchoredDrawObject
*>( &_rNewObj
) == nullptr )
2080 OSL_FAIL( "SwFrame::AppendDrawObj(..) - anchored object of unexpected type -> object not appended" );
2084 if ( dynamic_cast<const SwDrawVirtObj
*>(_rNewObj
.GetDrawObj()) == nullptr &&
2085 _rNewObj
.GetAnchorFrame() && _rNewObj
.GetAnchorFrame() != this )
2087 assert(!m_pDrawObjs
|| m_pDrawObjs
->is_sorted());
2088 // perform disconnect from layout, if 'master' drawing object is appended
2090 static_cast<SwDrawContact
*>(::GetUserCall( _rNewObj
.GetDrawObj() ))->
2091 DisconnectFromLayout( false );
2092 assert(!m_pDrawObjs
|| m_pDrawObjs
->is_sorted());
2095 if ( _rNewObj
.GetAnchorFrame() != this )
2099 m_pDrawObjs
.reset(new SwSortedObjs());
2101 m_pDrawObjs
->Insert(_rNewObj
);
2102 _rNewObj
.ChgAnchorFrame( this );
2106 // Assure the control objects and group objects containing controls are on the control layer
2107 if ( ::CheckControlLayer( _rNewObj
.DrawObj() ) )
2109 const IDocumentDrawModelAccess
& rIDDMA
= getIDocumentDrawModelAccess();
2110 const SdrLayerID
aCurrentLayer(_rNewObj
.DrawObj()->GetLayer());
2111 const SdrLayerID
aControlLayerID(rIDDMA
.GetControlsId());
2112 const SdrLayerID
aInvisibleControlLayerID(rIDDMA
.GetInvisibleControlsId());
2114 if(aCurrentLayer
!= aControlLayerID
&& aCurrentLayer
!= aInvisibleControlLayerID
)
2116 if ( aCurrentLayer
== rIDDMA
.GetInvisibleHellId() ||
2117 aCurrentLayer
== rIDDMA
.GetInvisibleHeavenId() )
2119 _rNewObj
.DrawObj()->SetLayer(aInvisibleControlLayerID
);
2123 _rNewObj
.DrawObj()->SetLayer(aControlLayerID
);
2125 //The layer is part of the key used to sort the obj, so update
2126 //its position if the layer changed.
2127 m_pDrawObjs
->Update(_rNewObj
);
2131 // no direct positioning needed, but invalidate the drawing object position
2132 _rNewObj
.InvalidateObjPos();
2134 // register at page frame
2135 SwPageFrame
* pPage
= FindPageFrame();
2138 pPage
->AppendDrawObjToPage( _rNewObj
);
2141 // Notify accessible layout.
2142 SwViewShell
* pSh
= getRootFrame()->GetCurrShell();
2145 SwRootFrame
* pLayout
= getRootFrame();
2146 if( pLayout
&& pLayout
->IsAnyShellAccessible() )
2148 pSh
->Imp()->AddAccessibleObj( _rNewObj
.GetDrawObj() );
2152 assert(!m_pDrawObjs
|| m_pDrawObjs
->is_sorted());
2155 void SwFrame::RemoveDrawObj( SwAnchoredObject
& _rToRemoveObj
)
2157 // Notify accessible layout.
2158 SwViewShell
* pSh
= getRootFrame()->GetCurrShell();
2161 SwRootFrame
* pLayout
= getRootFrame();
2162 if (pLayout
&& pLayout
->IsAnyShellAccessible())
2163 pSh
->Imp()->DisposeAccessibleObj(_rToRemoveObj
.GetDrawObj(), false);
2166 // deregister from page frame
2167 SwPageFrame
* pPage
= _rToRemoveObj
.GetPageFrame();
2168 if ( pPage
&& pPage
->GetSortedObjs() )
2169 pPage
->RemoveDrawObjFromPage( _rToRemoveObj
);
2171 m_pDrawObjs
->Remove(_rToRemoveObj
);
2172 if (!m_pDrawObjs
->size())
2174 m_pDrawObjs
.reset();
2176 _rToRemoveObj
.ChgAnchorFrame( nullptr );
2178 assert(!m_pDrawObjs
|| m_pDrawObjs
->is_sorted());
2181 void SwFrame::InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs
)
2183 if ( GetDrawObjs() )
2185 // #i26945# - determine page the frame is on,
2186 // in order to check, if anchored object is registered at the same
2188 const SwPageFrame
* pPageFrame
= FindPageFrame();
2189 // #i28701# - re-factoring
2190 for (SwAnchoredObject
* pAnchoredObj
: *GetDrawObjs())
2192 if ( _bNoInvaOfAsCharAnchoredObjs
&&
2193 (pAnchoredObj
->GetFrameFormat().GetAnchor().GetAnchorId()
2194 == RndStdIds::FLY_AS_CHAR
) )
2198 // #i26945# - no invalidation, if anchored object
2199 // isn't registered at the same page and instead is registered at
2200 // the page, where its anchor character text frame is on.
2201 if ( pAnchoredObj
->GetPageFrame() &&
2202 pAnchoredObj
->GetPageFrame() != pPageFrame
)
2204 SwTextFrame
* pAnchorCharFrame
= pAnchoredObj
->FindAnchorCharFrame();
2205 if ( pAnchorCharFrame
&&
2206 pAnchoredObj
->GetPageFrame() == pAnchorCharFrame
->FindPageFrame() )
2210 // #115759# - unlock its position, if anchored
2211 // object isn't registered at the page, where its anchor
2212 // character text frame is on, respectively if it has no
2213 // anchor character text frame.
2216 pAnchoredObj
->UnlockPosition();
2219 // #i51474# - reset flag, that anchored object
2220 // has cleared environment, and unlock its position, if the anchored
2221 // object is registered at the same page as the anchor frame is on.
2222 if ( pAnchoredObj
->ClearedEnvironment() &&
2223 pAnchoredObj
->GetPageFrame() &&
2224 pAnchoredObj
->GetPageFrame() == pPageFrame
)
2226 pAnchoredObj
->UnlockPosition();
2227 pAnchoredObj
->SetClearedEnvironment( false );
2229 // distinguish between writer fly frames and drawing objects
2230 if ( dynamic_cast<const SwFlyFrame
*>( pAnchoredObj
) != nullptr )
2232 SwFlyFrame
* pFly
= static_cast<SwFlyFrame
*>(pAnchoredObj
);
2233 pFly
->Invalidate_();
2234 pFly
->InvalidatePos_();
2238 pAnchoredObj
->InvalidateObjPos();
2240 } // end of loop on objects, which are connected to the frame
2244 // #i26945# - correct check, if anchored object is a lower
2245 // of the layout frame. E.g., anchor character text frame can be a follow text
2247 // #i44016# - add parameter <_bUnlockPosOfObjs> to
2248 // force an unlockposition call for the lower objects.
2249 void SwLayoutFrame::NotifyLowerObjs( const bool _bUnlockPosOfObjs
)
2251 // invalidate lower floating screen objects
2252 SwPageFrame
* pPageFrame
= FindPageFrame();
2253 if ( pPageFrame
&& pPageFrame
->GetSortedObjs() )
2255 SwSortedObjs
& rObjs
= *(pPageFrame
->GetSortedObjs());
2256 for (SwAnchoredObject
* pObj
: rObjs
)
2258 // #i26945# - check, if anchored object is a lower
2259 // of the layout frame is changed to check, if its anchor frame
2260 // is a lower of the layout frame.
2261 // determine the anchor frame - usually it's the anchor frame,
2262 // for at-character/as-character anchored objects the anchor character
2263 // text frame is taken.
2264 const SwFrame
* pAnchorFrame
= pObj
->GetAnchorFrameContainingAnchPos();
2265 if ( dynamic_cast<const SwFlyFrame
*>( pObj
) != nullptr )
2267 SwFlyFrame
* pFly
= static_cast<SwFlyFrame
*>(pObj
);
2269 if ( pFly
->getFrameArea().Left() == FAR_AWAY
)
2272 if ( pFly
->IsAnLower( this ) )
2275 // #i26945# - use <pAnchorFrame> to check, if
2276 // fly frame is lower of layout frame resp. if fly frame is
2277 // at a different page registered as its anchor frame is on.
2278 const bool bLow
= IsAnLower( pAnchorFrame
);
2279 if ( bLow
|| pAnchorFrame
->FindPageFrame() != pPageFrame
)
2281 pFly
->Invalidate_( pPageFrame
);
2282 if ( !bLow
|| pFly
->IsFlyAtContentFrame() )
2285 if ( _bUnlockPosOfObjs
)
2287 pFly
->UnlockPosition();
2289 pFly
->InvalidatePos_();
2292 pFly
->InvalidatePrt_();
2297 OSL_ENSURE( dynamic_cast<const SwAnchoredDrawObject
*>( pObj
) != nullptr,
2298 "<SwLayoutFrame::NotifyFlys() - anchored object of unexpected type" );
2299 // #i26945# - use <pAnchorFrame> to check, if
2300 // fly frame is lower of layout frame resp. if fly frame is
2301 // at a different page registered as its anchor frame is on.
2302 if ( IsAnLower( pAnchorFrame
) ||
2303 pAnchorFrame
->FindPageFrame() != pPageFrame
)
2306 if ( _bUnlockPosOfObjs
)
2308 pObj
->UnlockPosition();
2310 pObj
->InvalidateObjPos();
2317 void SwFlyFrame::NotifyDrawObj()
2319 SwVirtFlyDrawObj
* pObj
= GetVirtDrawObj();
2321 pObj
->SetRectsDirty();
2323 pObj
->BroadcastObjectChange();
2325 if ( GetFormat()->GetSurround().IsContour() )
2327 ClrContourCache( pObj
);
2329 else if(IsFlyFreeFrame() && static_cast< const SwFlyFreeFrame
* >(this)->supportsAutoContour())
2331 // RotateFlyFrame3: Also need to clear when changes happen
2332 // Caution: isTransformableSwFrame is already reset when resetting rotation, so
2333 // *additionally* reset in SwFlyFreeFrame::MakeAll when no more rotation
2334 ClrContourCache( pObj
);
2338 Size
SwFlyFrame::CalcRel( const SwFormatFrameSize
&rSz
) const
2340 Size
aRet( rSz
.GetSize() );
2342 const SwFrame
*pRel
= IsFlyLayFrame() ? GetAnchorFrame() : GetAnchorFrame()->GetUpper();
2343 if( pRel
) // LAYER_IMPL
2345 long nRelWidth
= LONG_MAX
, nRelHeight
= LONG_MAX
;
2346 const SwViewShell
*pSh
= getRootFrame()->GetCurrShell();
2347 if ( ( pRel
->IsBodyFrame() || pRel
->IsPageFrame() ) &&
2348 pSh
&& pSh
->GetViewOptions()->getBrowseMode() &&
2349 pSh
->VisArea().HasArea() )
2351 nRelWidth
= pSh
->GetBrowseWidth();
2352 nRelHeight
= pSh
->VisArea().Height();
2353 Size aBorder
= pSh
->GetOut()->PixelToLogic( pSh
->GetBrowseBorder() );
2354 nRelWidth
= std::min( nRelWidth
, pRel
->getFramePrintArea().Width() );
2355 nRelHeight
-= 2*aBorder
.Height();
2356 nRelHeight
= std::min( nRelHeight
, pRel
->getFramePrintArea().Height() );
2359 // At the moment only the "== PAGE_FRAME" and "!= PAGE_FRAME" cases are handled.
2360 // When size is a relative to page size, ignore size of SwBodyFrame.
2361 if (rSz
.GetWidthPercentRelation() != text::RelOrientation::PAGE_FRAME
)
2362 nRelWidth
= std::min( nRelWidth
, pRel
->getFramePrintArea().Width() );
2363 else if ( pRel
->IsPageFrame() )
2364 nRelWidth
= std::min( nRelWidth
, pRel
->getFrameArea().Width() );
2366 if (rSz
.GetHeightPercentRelation() != text::RelOrientation::PAGE_FRAME
)
2367 nRelHeight
= std::min( nRelHeight
, pRel
->getFramePrintArea().Height() );
2368 else if ( pRel
->IsPageFrame() )
2369 nRelHeight
= std::min( nRelHeight
, pRel
->getFrameArea().Height() );
2371 if( !pRel
->IsPageFrame() )
2373 const SwPageFrame
* pPage
= FindPageFrame();
2376 if (rSz
.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME
)
2377 // Ignore margins of pPage.
2378 nRelWidth
= std::min( nRelWidth
, pPage
->getFrameArea().Width() );
2380 nRelWidth
= std::min( nRelWidth
, pPage
->getFramePrintArea().Width() );
2381 if (rSz
.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME
)
2382 // Ignore margins of pPage.
2383 nRelHeight
= std::min( nRelHeight
, pPage
->getFrameArea().Height() );
2385 nRelHeight
= std::min( nRelHeight
, pPage
->getFramePrintArea().Height() );
2389 if ( rSz
.GetWidthPercent() && rSz
.GetWidthPercent() != SwFormatFrameSize::SYNCED
)
2390 aRet
.setWidth( nRelWidth
* rSz
.GetWidthPercent() / 100 );
2391 if ( rSz
.GetHeightPercent() && rSz
.GetHeightPercent() != SwFormatFrameSize::SYNCED
)
2392 aRet
.setHeight( nRelHeight
* rSz
.GetHeightPercent() / 100 );
2394 if ( rSz
.GetWidthPercent() == SwFormatFrameSize::SYNCED
)
2396 aRet
.setWidth( aRet
.Width() * ( aRet
.Height()) );
2397 aRet
.setWidth( aRet
.Width() / ( rSz
.GetHeight()) );
2399 else if ( rSz
.GetHeightPercent() == SwFormatFrameSize::SYNCED
)
2401 aRet
.setHeight( aRet
.Height() * ( aRet
.Width()) );
2402 aRet
.setHeight( aRet
.Height() / ( rSz
.GetWidth()) );
2408 static SwTwips
lcl_CalcAutoWidth( const SwLayoutFrame
& rFrame
)
2412 const SwFrame
* pFrame
= rFrame
.Lower();
2414 // No autowidth defined for columned frames
2415 if ( !pFrame
|| pFrame
->IsColumnFrame() )
2420 if ( pFrame
->IsSctFrame() )
2422 nMin
= lcl_CalcAutoWidth( *static_cast<const SwSectionFrame
*>(pFrame
) );
2424 if ( pFrame
->IsTextFrame() )
2426 nMin
= const_cast<SwTextFrame
*>(static_cast<const SwTextFrame
*>(pFrame
))->CalcFitToContent();
2427 const SvxLRSpaceItem
&rSpace
=
2428 static_cast<const SwTextFrame
*>(pFrame
)->GetTextNodeForParaProps()->GetSwAttrSet().GetLRSpace();
2429 if (!static_cast<const SwTextFrame
*>(pFrame
)->IsLocked())
2430 nMin
+= rSpace
.GetRight() + rSpace
.GetTextLeft() + rSpace
.GetTextFirstLineOfst();
2432 else if ( pFrame
->IsTabFrame() )
2434 const SwFormatFrameSize
& rTableFormatSz
= static_cast<const SwTabFrame
*>(pFrame
)->GetTable()->GetFrameFormat()->GetFrameSize();
2435 if ( USHRT_MAX
== rTableFormatSz
.GetSize().Width() ||
2436 text::HoriOrientation::NONE
== static_cast<const SwTabFrame
*>(pFrame
)->GetFormat()->GetHoriOrient().GetHoriOrient() )
2438 const SwPageFrame
* pPage
= rFrame
.FindPageFrame();
2440 nMin
= pFrame
->GetUpper()->IsVertical() ?
2441 pPage
->getFramePrintArea().Height() :
2442 pPage
->getFramePrintArea().Width();
2446 nMin
= rTableFormatSz
.GetSize().Width();
2453 pFrame
= pFrame
->GetNext();
2459 /// OD 16.04.2003 #i13147# - If called for paint and the <SwNoTextFrame> contains
2460 /// a graphic, load of intrinsic graphic has to be avoided.
2461 bool SwFlyFrame::GetContour( tools::PolyPolygon
& rContour
,
2462 const bool _bForPaint
) const
2464 vcl::RenderContext
* pRenderContext
= getRootFrame()->GetCurrShell()->GetOut();
2466 const bool bIsCandidate(Lower() && Lower()->IsNoTextFrame());
2470 if(GetFormat()->GetSurround().IsContour())
2472 SwNoTextNode
*pNd
= const_cast<SwNoTextNode
*>(static_cast<const SwNoTextNode
*>(static_cast<const SwNoTextFrame
*>(Lower())->GetNode()));
2473 // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
2474 // in order to avoid load of graphic, if <SwNoTextNode> contains a graphic
2475 // node and method is called for paint.
2476 std::unique_ptr
<GraphicObject
> xTmpGrfObj
;
2477 const GraphicObject
* pGrfObj
= nullptr;
2478 const SwGrfNode
* pGrfNd
= pNd
->GetGrfNode();
2479 if ( pGrfNd
&& _bForPaint
)
2481 pGrfObj
= &(pGrfNd
->GetGrfObj());
2485 xTmpGrfObj
.reset(new GraphicObject(pNd
->GetGraphic()));
2486 pGrfObj
= xTmpGrfObj
.get();
2488 assert(pGrfObj
&& "SwFlyFrame::GetContour() - No Graphic/GraphicObject found at <SwNoTextNode>.");
2489 if (pGrfObj
->GetType() != GraphicType::NONE
)
2491 if( !pNd
->HasContour() )
2493 // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
2494 // during paint. Thus, return (value of <bRet> should be <false>).
2495 if ( pGrfNd
&& _bForPaint
)
2497 OSL_FAIL( "SwFlyFrame::GetContour() - No Contour found at <SwNoTextNode> during paint." );
2500 pNd
->CreateContour();
2502 pNd
->GetContour( rContour
);
2503 // The Node holds the Polygon matching the original size of the graphic
2504 // We need to include the scaling here
2507 Lower()->Calc(pRenderContext
);
2508 static_cast<const SwNoTextFrame
*>(Lower())->GetGrfArea( aClip
, &aOrig
);
2509 // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
2510 // in order to avoid that graphic has to be loaded for contour scale.
2511 //SvxContourDlg::ScaleContour( rContour, aGrf, MapUnit::MapTwip, aOrig.SSize() );
2513 OutputDevice
* pOutDev
= Application::GetDefaultDevice();
2514 const MapMode
aDispMap( MapUnit::MapTwip
);
2515 const MapMode
aGrfMap( pGrfObj
->GetPrefMapMode() );
2516 const Size
aGrfSize( pGrfObj
->GetPrefSize() );
2519 bool bPixelMap
= aGrfMap
.GetMapUnit() == MapUnit::MapPixel
;
2522 aOrgSize
= pOutDev
->PixelToLogic( aGrfSize
, aDispMap
);
2524 aOrgSize
= OutputDevice::LogicToLogic( aGrfSize
, aGrfMap
, aDispMap
);
2526 if ( aOrgSize
.Width() && aOrgSize
.Height() )
2528 double fScaleX
= static_cast<double>(aOrig
.Width()) / aOrgSize
.Width();
2529 double fScaleY
= static_cast<double>(aOrig
.Height()) / aOrgSize
.Height();
2531 for ( sal_uInt16 j
= 0, nPolyCount
= rContour
.Count(); j
< nPolyCount
; j
++ )
2533 tools::Polygon
& rPoly
= rContour
[ j
];
2535 for ( sal_uInt16 i
= 0, nCount
= rPoly
.GetSize(); i
< nCount
; i
++ )
2538 aNewPoint
= pOutDev
->PixelToLogic( rPoly
[ i
], aDispMap
);
2540 aNewPoint
= OutputDevice::LogicToLogic( rPoly
[ i
], aGrfMap
, aDispMap
);
2542 rPoly
[ i
] = Point( FRound( aNewPoint
.getX() * fScaleX
), FRound( aNewPoint
.getY() * fScaleY
) );
2547 // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
2549 rContour
.Move( aOrig
.Left(), aOrig
.Top() );
2550 if( !aClip
.Width() )
2552 if( !aClip
.Height() )
2554 rContour
.Clip( aClip
.SVRect() );
2555 rContour
.Optimize(PolyOptimizeFlags::CLOSE
);
2561 const SwFlyFreeFrame
* pSwFlyFreeFrame(dynamic_cast< const SwFlyFreeFrame
* >(this));
2563 if(nullptr != pSwFlyFreeFrame
&&
2564 pSwFlyFreeFrame
->supportsAutoContour() &&
2565 // isTransformableSwFrame already used in supportsAutoContour(), but
2566 // better check twice when it may get changed there...
2567 pSwFlyFreeFrame
->isTransformableSwFrame())
2569 // RotateFlyFrame: use untransformed SwFrame to allow text floating around.
2570 // Will be transformed below
2571 const TransformableSwFrame
* pTransformableSwFrame(pSwFlyFreeFrame
->getTransformableSwFrame());
2572 const SwRect
aFrameArea(pTransformableSwFrame
->getUntransformedFrameArea());
2573 rContour
= tools::PolyPolygon(tools::Polygon(aFrameArea
.SVRect()));
2574 bRet
= (0 != rContour
.Count());
2578 if(bRet
&& 0 != rContour
.Count())
2580 const SwFlyFreeFrame
* pSwFlyFreeFrame(dynamic_cast< const SwFlyFreeFrame
* >(this));
2582 if(nullptr != pSwFlyFreeFrame
&& pSwFlyFreeFrame
->isTransformableSwFrame())
2584 // Need to adapt contour to transformation
2585 basegfx::B2DVector aScale
, aTranslate
;
2586 double fRotate
, fShearX
;
2587 getFrameAreaTransformation().decompose(aScale
, aTranslate
, fRotate
, fShearX
);
2589 if(!basegfx::fTools::equalZero(fRotate
))
2591 basegfx::B2DPolyPolygon
aSource(rContour
.getB2DPolyPolygon());
2592 const basegfx::B2DPoint
aCenter(getFrameAreaTransformation() * basegfx::B2DPoint(0.5, 0.5));
2593 const basegfx::B2DHomMatrix
aRotateAroundCenter(
2594 basegfx::utils::createRotateAroundPoint(
2598 aSource
.transform(aRotateAroundCenter
);
2599 rContour
= tools::PolyPolygon(aSource
);
2608 // OD 2004-03-25 #i26791#
2609 const SwVirtFlyDrawObj
* SwFlyFrame::GetVirtDrawObj() const
2611 return static_cast<const SwVirtFlyDrawObj
*>(GetDrawObj());
2613 SwVirtFlyDrawObj
* SwFlyFrame::GetVirtDrawObj()
2615 return static_cast<SwVirtFlyDrawObj
*>(DrawObj());
2618 // OD 2004-03-24 #i26791# - implementation of pure virtual method declared in
2619 // base class <SwAnchoredObject>
2621 void SwFlyFrame::InvalidateObjPos()
2625 InvalidateObjRectWithSpaces();
2628 SwFrameFormat
& SwFlyFrame::GetFrameFormat()
2630 OSL_ENSURE( GetFormat(),
2631 "<SwFlyFrame::GetFrameFormat()> - missing frame format -> crash." );
2632 return *GetFormat();
2634 const SwFrameFormat
& SwFlyFrame::GetFrameFormat() const
2636 OSL_ENSURE( GetFormat(),
2637 "<SwFlyFrame::GetFrameFormat()> - missing frame format -> crash." );
2638 return *GetFormat();
2641 const SwRect
SwFlyFrame::GetObjRect() const
2643 return getFrameArea();
2647 // for Writer fly frames the bounding rectangle equals the object rectangles
2648 const SwRect
SwFlyFrame::GetObjBoundRect() const
2650 return GetObjRect();
2654 bool SwFlyFrame::SetObjTop_( const SwTwips _nTop
)
2656 const bool bChanged( getFrameArea().Pos().getY() != _nTop
);
2657 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
2658 aFrm
.Pos().setY(_nTop
);
2662 bool SwFlyFrame::SetObjLeft_( const SwTwips _nLeft
)
2664 const bool bChanged( getFrameArea().Pos().getX() != _nLeft
);
2665 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*this);
2666 aFrm
.Pos().setX(_nLeft
);
2671 /** method to assure that anchored object is registered at the correct
2674 OD 2004-07-02 #i28701#
2676 void SwFlyFrame::RegisterAtCorrectPage()
2678 // default behaviour is to do nothing.
2681 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
2683 OD 2004-05-11 #i28701#
2685 bool SwFlyFrame::IsFormatPossible() const
2687 return SwAnchoredObject::IsFormatPossible() &&
2688 !IsLocked() && !IsColLocked();
2691 void SwFlyFrame::GetAnchoredObjects( std::vector
<SwAnchoredObject
*>& aVector
, const SwFormat
& rFormat
)
2693 SwIterator
<SwFlyFrame
,SwFormat
> aIter( rFormat
);
2694 for( SwFlyFrame
* pFlyFrame
= aIter
.First(); pFlyFrame
; pFlyFrame
= aIter
.Next() )
2695 aVector
.push_back( pFlyFrame
);
2698 const SwFlyFrameFormat
* SwFlyFrame::GetFormat() const
2700 return static_cast< const SwFlyFrameFormat
* >( GetDep() );
2703 SwFlyFrameFormat
* SwFlyFrame::GetFormat()
2705 return static_cast< SwFlyFrameFormat
* >( GetDep() );
2708 void SwFlyFrame::Calc(vcl::RenderContext
* pRenderContext
) const
2710 if ( !m_bValidContentPos
)
2711 const_cast<SwFlyFrame
*>(this)->PrepareMake(pRenderContext
);
2713 SwLayoutFrame::Calc(pRenderContext
);
2716 SwTwips
SwFlyFrame::CalcContentHeight(const SwBorderAttrs
*pAttrs
, const SwTwips nMinHeight
, const SwTwips nUL
)
2718 SwRectFnSet
aRectFnSet(this);
2719 SwTwips nHeight
= 0;
2722 if ( Lower()->IsColumnFrame() )
2724 FormatWidthCols( *pAttrs
, nUL
, nMinHeight
);
2725 nHeight
= aRectFnSet
.GetHeight(Lower()->getFrameArea());
2729 SwFrame
*pFrame
= Lower();
2732 nHeight
+= aRectFnSet
.GetHeight(pFrame
->getFrameArea());
2733 if( pFrame
->IsTextFrame() && static_cast<SwTextFrame
*>(pFrame
)->IsUndersized() )
2734 // This TextFrame would like to be a bit larger
2735 nHeight
+= static_cast<SwTextFrame
*>(pFrame
)->GetParHeight()
2736 - aRectFnSet
.GetHeight(pFrame
->getFramePrintArea());
2737 else if( pFrame
->IsSctFrame() && static_cast<SwSectionFrame
*>(pFrame
)->IsUndersized() )
2738 nHeight
+= static_cast<SwSectionFrame
*>(pFrame
)->Undersize();
2739 pFrame
= pFrame
->GetNext();
2742 if ( GetDrawObjs() )
2744 const size_t nCnt
= GetDrawObjs()->size();
2745 SwTwips nTop
= aRectFnSet
.GetTop(getFrameArea());
2746 SwTwips nBorder
= aRectFnSet
.GetHeight(getFrameArea()) -
2747 aRectFnSet
.GetHeight(getFramePrintArea());
2748 for ( size_t i
= 0; i
< nCnt
; ++i
)
2750 SwAnchoredObject
* pAnchoredObj
= (*GetDrawObjs())[i
];
2751 if ( dynamic_cast<const SwFlyFrame
*>( pAnchoredObj
) != nullptr )
2753 SwFlyFrame
* pFly
= static_cast<SwFlyFrame
*>(pAnchoredObj
);
2754 // OD 06.11.2003 #i22305# - consider
2755 // only Writer fly frames, which follow the text flow.
2756 if ( pFly
->IsFlyLayFrame() &&
2757 pFly
->getFrameArea().Top() != FAR_AWAY
&&
2758 pFly
->GetFormat()->GetFollowTextFlow().GetValue() )
2760 SwTwips nDist
= -aRectFnSet
.BottomDist( pFly
->getFrameArea(), nTop
);
2761 if( nDist
> nBorder
+ nHeight
)
2762 nHeight
= nDist
- nBorder
;
2771 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */