Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef INCLUDED_SW_SOURCE_CORE_INC_FLOWFRM_HXX
21 : #define INCLUDED_SW_SOURCE_CORE_INC_FLOWFRM_HXX
22 :
23 : #include "frmtool.hxx"
24 :
25 : class SwPageFrm;
26 : class SwRect;
27 : class SwBorderAttrs;
28 : class SwDoc;
29 : class SwNodeIndex;
30 : // #i44049#
31 : class SwObjectFormatterTextFrm;
32 :
33 : /** Base class that provides the general functionalities for frames that are
34 : allowed at page breaks (flow) and shall continue on the next page (can be
35 : split), e.g. paragraphs (ContentFrm) or tables (TabFrm).
36 :
37 : Some parts of these functionalities are implemented in FlowFrm while the
38 : specific ones are done in the corresponding Frm classes. The FlowFrm has to
39 : be seen as a base class. As such it is no Frm by itself and thus no direct
40 : instances of FlowFrm can exist.
41 :
42 : Actually it is not even a real Frm. The obvious implementation would be a
43 : FlowFrm that is virtually inherited from SwFrm and that works with its own
44 : member data. Further classes would need to inherit from FlowFrm and (via
45 : multiple base classes since the class tree splits exactly at the branch
46 : from SwFrm to SwContentFrm and SwLayoutFrm) also virtually from SwFrm as
47 : well. Unfortunately, this leads - besides problems with compilers and
48 : debugging programs - to high additional costs, that we IMHO are not able to
49 : afford nowadays.
50 :
51 : Hence, we use another technique: A FlowFrm keeps a reference to a SwFrm
52 : - which it is actually itself - and they are friends. As a result, the
53 : FlowFrm can work with the reference to the SwFrm instead of working with
54 : its own this-pointer.
55 : */
56 : class SwFlowFrm
57 : {
58 : // PrepareMake is allowed to lock/unlock (robustness)
59 : friend inline void PrepareLock ( SwFlowFrm * );
60 : friend inline void PrepareUnlock( SwFlowFrm * );
61 : friend inline void TableSplitRecalcLock( SwFlowFrm * );
62 : friend inline void TableSplitRecalcUnlock( SwFlowFrm * );
63 : // #i44049#
64 : friend class SwObjectFormatterTextFrm;
65 : friend class FlowFrmJoinLockGuard;
66 :
67 : // TableSel is allowed to reset the follow-bit
68 : friend inline void UnsetFollow( SwFlowFrm *pFlow );
69 :
70 : friend void MakeFrms( SwDoc *, const SwNodeIndex &, const SwNodeIndex & );
71 :
72 : friend class SwNode2LayImpl;
73 :
74 : SwFrm& m_rThis;
75 :
76 : // helper methods for MoveSubTree()
77 : static SwLayoutFrm *CutTree( SwFrm* );
78 : static bool PasteTree( SwFrm *, SwLayoutFrm *, SwFrm *, SwFrm* );
79 :
80 : /** indicates that a backward move was done over multiple pages
81 :
82 : Needed for the interaction of _GetPrevxxx and MoveBwd so that multiple
83 : pages can be skipped at the same time. In addition, it is evaluated by
84 : the MoveBwd() method in TabFrm.
85 : */
86 : static bool m_bMoveBwdJump;
87 :
88 : /** helper method to determine previous frame for calculation of the
89 : upper space
90 :
91 : #i11860#
92 :
93 : @param _pProposedPrevFrm
94 : optional input parameter - pointer to frame, which should be used
95 : instead of the direct previous frame.
96 : */
97 : const SwFrm* _GetPrevFrmForUpperSpaceCalc( const SwFrm* _pProposedPrevFrm = 0L ) const;
98 :
99 : /** method to detemine the upper space amount, which is considered for
100 : the previous frame
101 :
102 : #i11860#
103 : */
104 : SwTwips _GetUpperSpaceAmountConsideredForPrevFrm() const;
105 :
106 : /** method to detemine the upper space amount, which is considered for
107 : the page grid
108 :
109 : #i11860#
110 : */
111 : SwTwips _GetUpperSpaceAmountConsideredForPageGrid(
112 : const SwTwips _nUpperSpaceWithoutGrid ) const;
113 :
114 : protected:
115 : SwFlowFrm *m_pFollow;
116 : SwFlowFrm *m_pPrecede;
117 :
118 : bool m_bLockJoin :1; // if true than joins (and thus deletes) are prohibited!
119 : bool m_bUndersized:1; // I am smaller than needed
120 : bool m_bFlyLock :1; // stop positioning of at-character flyframes
121 :
122 : // checks if forward flow makes sense to prevent infinite moves
123 : inline bool IsFwdMoveAllowed();
124 : // #i44049# - method <CalcContent(..)> has to check this property.
125 : friend void CalcContent( SwLayoutFrm *pLay, bool bNoColl, bool bNoCalcFollow );
126 : bool IsKeepFwdMoveAllowed(); // like above, forward flow for Keep.
127 :
128 : /** method to determine overlapping of an object that requests floating
129 :
130 : 0: no overlapping
131 : 1: objects that are anchored at the FlowFrm overlap
132 : 2: objects that are anchored somewhere else overlap
133 : 3: both types of objects overlap
134 : */
135 : sal_uInt8 BwdMoveNecessary( const SwPageFrm *pPage, const SwRect &rRect );
136 :
137 90410 : void LockJoin() { m_bLockJoin = true; }
138 80307 : void UnlockJoin() { m_bLockJoin = false; }
139 :
140 : bool CheckMoveFwd( bool& rbMakePage, bool bKeep, bool bMovedBwd );
141 : bool MoveFwd( bool bMakePage, bool bPageBreak, bool bMoveAlways = false );
142 : bool MoveBwd( bool &rbReformat );
143 : virtual bool ShouldBwdMoved( SwLayoutFrm *pNewUpper, bool bHead, bool &rReformat )=0;
144 :
145 : public:
146 : SwFlowFrm( SwFrm &rFrm );
147 : virtual ~SwFlowFrm();
148 :
149 7553 : const SwFrm& GetFrm() const { return m_rThis; }
150 15952 : SwFrm& GetFrm() { return m_rThis; }
151 :
152 17243 : static bool IsMoveBwdJump() { return m_bMoveBwdJump; }
153 40079 : static void SetMoveBwdJump( bool bNew ){ m_bMoveBwdJump = bNew; }
154 :
155 20351 : inline void SetUndersized( const bool bNew ) { m_bUndersized = bNew; }
156 306088 : inline bool IsUndersized() const { return m_bUndersized; }
157 :
158 : bool IsPrevObjMove() const;
159 :
160 : /** hook tree onto new parent with minimal operations and notifications */
161 : void MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling = 0 );
162 :
163 396038 : bool HasFollow() const { return m_pFollow != nullptr; }
164 2653361 : bool IsFollow() const { return 0 != m_pPrecede; }
165 : bool IsAnFollow( const SwFlowFrm *pFlow ) const;
166 281829 : const SwFlowFrm *GetFollow() const { return m_pFollow; }
167 1105173 : SwFlowFrm *GetFollow() { return m_pFollow; }
168 : void SetFollow(SwFlowFrm *const pFollow);
169 :
170 41014 : const SwFlowFrm *GetPrecede() const { return m_pPrecede; }
171 909 : SwFlowFrm *GetPrecede() { return m_pPrecede; }
172 :
173 152489 : bool IsJoinLocked() const { return m_bLockJoin; }
174 4970 : bool IsAnyJoinLocked() const { return m_bLockJoin || HasLockedFollow(); }
175 :
176 : bool IsPageBreak( bool bAct ) const;
177 : bool IsColBreak( bool bAct ) const;
178 :
179 : /** method to determine if a Keep needs to be considered (Breaks!) */
180 : bool IsKeep( const SwAttrSet& rAttrs, bool bBreakCheck = false ) const;
181 :
182 : bool HasLockedFollow() const;
183 :
184 : bool HasParaSpaceAtPages( bool bSct ) const;
185 :
186 : /** method to determine the upper space hold by the frame
187 :
188 : #i11860#
189 :
190 : @param _bConsiderGrid
191 : optional input parameter - consider the page grid while calculating?
192 : */
193 : SwTwips CalcUpperSpace( const SwBorderAttrs *pAttrs = NULL,
194 : const SwFrm* pPr = NULL,
195 : const bool _bConsiderGrid = true ) const;
196 :
197 : /** method to determine the upper space amount, which is considered for
198 : the previous frame and the page grid, if option 'Use former object
199 : positioning' is OFF
200 :
201 : #i11860#
202 : */
203 : SwTwips GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() const;
204 :
205 : /** calculation of lower space */
206 : SwTwips CalcLowerSpace( const SwBorderAttrs* _pAttrs = 0L ) const;
207 :
208 : /** calculation of the additional space to be considered, if flow frame
209 : is the last inside a table cell
210 :
211 : #i26250
212 :
213 : @param _pAttrs
214 : optional input parameter - border attributes of the flow frame.
215 : Used for optimization, if caller has already determined the border
216 : attributes.
217 :
218 : @return SwTwips
219 : */
220 : SwTwips CalcAddLowerSpaceAsLastInTableCell(
221 : const SwBorderAttrs* _pAttrs = 0L ) const;
222 :
223 : void CheckKeep();
224 :
225 68948 : void SetFlyLock( bool bNew ){ m_bFlyLock = bNew; }
226 69378 : bool IsFlyLock() const { return m_bFlyLock; }
227 :
228 : // Casting of a Frm into a FlowFrm (if it is one, otherwise 0)
229 : // These methods need to be customized in subclasses!
230 : static SwFlowFrm *CastFlowFrm( SwFrm *pFrm );
231 : static const SwFlowFrm *CastFlowFrm( const SwFrm *pFrm );
232 : };
233 :
234 2367 : inline bool SwFlowFrm::IsFwdMoveAllowed()
235 : {
236 2367 : return m_rThis.GetIndPrev() != 0;
237 : }
238 :
239 : //use this to protect a SwLayoutFrm for a given scope from getting merged with
240 : //its neighbour and thus deleted
241 : class FlowFrmJoinLockGuard
242 : {
243 : private:
244 : SwFlowFrm *m_pFlow;
245 : bool m_bOldJoinLocked;
246 : public:
247 : //JoinLock pParent for the lifetime of the Cut/Paste call, etc. to avoid
248 : //SwSectionFrm::MergeNext removing the pParent we're trying to reparent
249 : //into
250 63019 : FlowFrmJoinLockGuard(SwLayoutFrm* pFrm)
251 : {
252 63019 : m_pFlow = SwFlowFrm::CastFlowFrm(pFrm);
253 63019 : if (m_pFlow)
254 : {
255 1720 : m_bOldJoinLocked = m_pFlow->IsJoinLocked();
256 1720 : m_pFlow->LockJoin();
257 : }
258 : else
259 : {
260 61299 : m_bOldJoinLocked = false;
261 : }
262 63019 : }
263 :
264 63019 : ~FlowFrmJoinLockGuard()
265 : {
266 63019 : if (m_pFlow && !m_bOldJoinLocked)
267 1720 : m_pFlow->UnlockJoin();
268 63019 : }
269 : };
270 :
271 : #endif
272 :
273 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|