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 #ifndef INCLUDED_SW_SOURCE_CORE_INC_FLOWFRM_HXX
21 #define INCLUDED_SW_SOURCE_CORE_INC_FLOWFRM_HXX
25 #include <swtypes.hxx>
27 class SvxFormatKeepItem
;
28 class SvxFormatBreakItem
;
35 /** Base class that provides the general functionalities for frames that are
36 allowed at page breaks (flow) and shall continue on the next page (can be
37 split), e.g. paragraphs (ContentFrame) or tables (TabFrame).
39 Some parts of these functionalities are implemented in FlowFrame while the
40 specific ones are done in the corresponding Frame classes. The FlowFrame has to
41 be seen as a base class. As such it is no Frame by itself and thus no direct
42 instances of FlowFrame can exist.
44 Actually it is not even a real Frame. The obvious implementation would be a
45 FlowFrame that is virtually inherited from SwFrame and that works with its own
46 member data. Further classes would need to inherit from FlowFrame and (via
47 multiple base classes since the class tree splits exactly at the branch
48 from SwFrame to SwContentFrame and SwLayoutFrame) also virtually from SwFrame as
49 well. Unfortunately, this leads - besides problems with compilers and
50 debugging programs - to high additional costs, that we IMHO are not able to
53 Hence, we use another technique: A FlowFrame keeps a reference to a SwFrame
54 - which it is actually itself - and they are friends. As a result, the
55 FlowFrame can work with the reference to the SwFrame instead of working with
60 // PrepareMake is allowed to lock/unlock (robustness)
61 friend inline void PrepareLock ( SwFlowFrame
* );
62 friend inline void PrepareUnlock( SwFlowFrame
* );
63 friend inline void TableSplitRecalcLock( SwFlowFrame
* );
64 friend inline void TableSplitRecalcUnlock( SwFlowFrame
* );
66 friend class SwObjectFormatterTextFrame
;
67 friend class FlowFrameJoinLockGuard
;
69 // TableSel is allowed to reset the follow-bit
70 friend inline void UnsetFollow( SwFlowFrame
*pFlow
);
72 friend void MakeFrames( SwDoc
*, const SwNodeIndex
&, const SwNodeIndex
& );
74 friend class SwNode2LayImpl
;
78 // helper methods for MoveSubTree()
79 static SwLayoutFrame
*CutTree( SwFrame
* );
80 static bool PasteTree( SwFrame
*, SwLayoutFrame
*, SwFrame
*, SwFrame
* );
82 /** indicates that a backward move was done over multiple pages
84 Needed for the interaction of _GetPrevxxx and MoveBwd so that multiple
85 pages can be skipped at the same time. In addition, it is evaluated by
86 the MoveBwd() method in TabFrame.
88 static bool s_bMoveBwdJump
;
90 /** helper method to determine previous frame for calculation of the
95 @param _pProposedPrevFrame
96 optional input parameter - pointer to frame, which should be used
97 instead of the direct previous frame.
99 const SwFrame
* GetPrevFrameForUpperSpaceCalc_( const SwFrame
* _pProposedPrevFrame
= nullptr ) const;
101 /** method to determine the upper space amount, which is considered for
106 SwTwips
GetUpperSpaceAmountConsideredForPrevFrame() const;
108 /** method to determine the upper space amount, which is considered for
113 SwTwips
GetUpperSpaceAmountConsideredForPageGrid_(
114 const SwTwips _nUpperSpaceWithoutGrid
) const;
117 SwFlowFrame
*m_pFollow
;
118 SwFlowFrame
*m_pPrecede
;
120 bool m_bLockJoin
:1; // if true than joins (and thus deletes) are prohibited!
121 bool m_bUndersized
:1; // I am smaller than needed
122 bool m_bFlyLock
:1; // stop positioning of at-character flyframes
124 // checks if forward flow makes sense to prevent infinite moves
125 inline bool IsFwdMoveAllowed() const;
126 // #i44049# - method <CalcContent(..)> has to check this property.
127 friend void CalcContent( SwLayoutFrame
*pLay
, bool bNoColl
);
128 bool IsKeepFwdMoveAllowed( bool bIgnoreMyOwnKeepValue
= false ); // like above, forward flow for Keep.
130 /** method to determine overlapping of an object that requests floating
133 1: objects that are anchored at the FlowFrame overlap
134 2: objects that are anchored somewhere else overlap
135 3: both types of objects overlap
137 sal_uInt8
BwdMoveNecessary( const SwPageFrame
*pPage
, const SwRect
&rRect
);
139 void LockJoin() { m_bLockJoin
= true; }
140 void UnlockJoin() { m_bLockJoin
= false; }
142 bool CheckMoveFwd( bool& rbMakePage
, bool bKeep
, bool bIgnoreMyOwnKeepValue
);
143 bool MoveFwd( bool bMakePage
, bool bPageBreak
, bool bMoveAlways
= false );
144 bool MoveBwd( bool &rbReformat
);
145 virtual bool ShouldBwdMoved( SwLayoutFrame
*pNewUpper
, bool &rReformat
)=0;
148 SwFlowFrame( SwFrame
&rFrame
);
149 virtual ~SwFlowFrame();
151 const SwFrame
& GetFrame() const { return m_rThis
; }
152 SwFrame
& GetFrame() { return m_rThis
; }
154 static bool IsMoveBwdJump() { return s_bMoveBwdJump
; }
155 static void SetMoveBwdJump( bool bNew
){ s_bMoveBwdJump
= bNew
; }
157 void SetUndersized( const bool bNew
) { m_bUndersized
= bNew
; }
158 bool IsUndersized() const { return m_bUndersized
; }
160 bool IsPrevObjMove() const;
162 /** hook tree onto new parent with minimal operations and notifications */
163 void MoveSubTree( SwLayoutFrame
* pParent
, SwFrame
* pSibling
= nullptr );
165 bool HasFollow() const { return m_pFollow
!= nullptr; }
166 bool IsFollow() const { return nullptr != m_pPrecede
; }
167 bool IsAnFollow( const SwFlowFrame
*pFlow
) const;
168 const SwFlowFrame
*GetFollow() const { return m_pFollow
; }
169 SwFlowFrame
*GetFollow() { return m_pFollow
; }
170 void SetFollow(SwFlowFrame
*const pFollow
);
172 const SwFlowFrame
*GetPrecede() const { return m_pPrecede
; }
173 SwFlowFrame
*GetPrecede() { return m_pPrecede
; }
175 bool IsJoinLocked() const { return m_bLockJoin
; }
176 bool IsAnyJoinLocked() const { return m_bLockJoin
|| HasLockedFollow(); }
178 bool IsPageBreak( bool bAct
) const;
179 bool IsColBreak( bool bAct
) const;
181 /** method to determine if a Keep needs to be considered (Breaks!) */
182 bool IsKeep(SvxFormatKeepItem
const& rKeep
,
183 SvxFormatBreakItem
const& rBreak
,
184 bool bBreakCheck
= false ) const;
186 bool HasLockedFollow() const;
188 bool HasParaSpaceAtPages( bool bSct
) const;
190 /** method to determine the upper space hold by the frame
194 @param _bConsiderGrid
195 optional input parameter - consider the page grid while calculating?
197 SwTwips
CalcUpperSpace( const SwBorderAttrs
*pAttrs
= nullptr,
198 const SwFrame
* pPr
= nullptr,
199 const bool _bConsiderGrid
= true ) const;
201 /** method to determine the upper space amount, which is considered for
202 the previous frame and the page grid, if option 'Use former object
207 SwTwips
GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid() const;
209 /** calculation of lower space */
210 SwTwips
CalcLowerSpace( const SwBorderAttrs
* _pAttrs
= nullptr ) const;
212 /** calculation of the additional space to be considered, if flow frame
213 is the last inside a table cell
218 optional input parameter - border attributes of the flow frame.
219 Used for optimization, if caller has already determined the border
224 SwTwips
CalcAddLowerSpaceAsLastInTableCell(
225 const SwBorderAttrs
* _pAttrs
= nullptr ) const;
229 void SetFlyLock( bool bNew
){ m_bFlyLock
= bNew
; }
230 bool IsFlyLock() const { return m_bFlyLock
; }
232 bool ForbiddenForFootnoteCntFwd() const;
234 // Casting of a Frame into a FlowFrame (if it is one, otherwise 0)
235 // These methods need to be customized in subclasses!
236 static SwFlowFrame
*CastFlowFrame( SwFrame
*pFrame
);
237 static const SwFlowFrame
*CastFlowFrame( const SwFrame
*pFrame
);
240 inline bool SwFlowFrame::IsFwdMoveAllowed() const
242 return m_rThis
.GetIndPrev() != nullptr;
245 //use this to protect a SwLayoutFrame for a given scope from getting merged with
246 //its neighbour and thus deleted
247 class FlowFrameJoinLockGuard
250 SwFlowFrame
*m_pFlow
;
251 bool m_bOldJoinLocked
;
253 //JoinLock pParent for the lifetime of the Cut/Paste call, etc. to avoid
254 //SwSectionFrame::MergeNext removing the pParent we're trying to reparent
256 FlowFrameJoinLockGuard(SwLayoutFrame
* pFrame
)
258 m_pFlow
= SwFlowFrame::CastFlowFrame(pFrame
);
261 m_bOldJoinLocked
= m_pFlow
->IsJoinLocked();
266 m_bOldJoinLocked
= false;
270 ~FlowFrameJoinLockGuard()
272 if (m_pFlow
&& !m_bOldJoinLocked
)
273 m_pFlow
->UnlockJoin();
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */