Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <svl/smplhint.hxx>
31 : : #include <svl/itemiter.hxx>
32 : : #include <hints.hxx>
33 : : #include <txtftn.hxx>
34 : : #include <fmtftn.hxx>
35 : : #include <fmtclbl.hxx>
36 : : #include "sectfrm.hxx"
37 : : #include "section.hxx" // SwSection
38 : : #include "frmtool.hxx" // StackHack
39 : : #include "doc.hxx" // SwDoc
40 : : #include "cntfrm.hxx" // SwCntntFrm
41 : : #include "rootfrm.hxx" // SwRootFrm
42 : : #include "pagefrm.hxx" // SwPageFrm
43 : : #include "fmtpdsc.hxx" // SwFmtPageDesc
44 : : #include "fmtcntnt.hxx" // SwFmtCntnt
45 : : #include "ndindex.hxx" // SwNodeIndex
46 : : #include "ftnidx.hxx"
47 : : #include "txtfrm.hxx" // SwTxtFrm
48 : : #include "fmtclds.hxx" // SwFmtCol
49 : : #include "colfrm.hxx" // SwColumnFrm
50 : : #include "tabfrm.hxx" // SwTabFrm
51 : : #include "flyfrm.hxx" // SwFlyFrm
52 : : #include "ftnfrm.hxx" // SwFtnFrm
53 : : #include "layouter.hxx" // SwLayouter
54 : : #include "dbg_lay.hxx"
55 : : #include "viewsh.hxx"
56 : : #include "viewopt.hxx"
57 : : #include "viewimp.hxx"
58 : : #include <editeng/ulspitem.hxx>
59 : : #include <editeng/lrspitem.hxx>
60 : : #include <editeng/brshitem.hxx>
61 : : #include <fmtftntx.hxx>
62 : : // OD 2004-05-24 #i28701#
63 : : #include <dflyobj.hxx>
64 : : #include <flyfrms.hxx>
65 : : #include <sortedobjs.hxx>
66 : :
67 : : /*************************************************************************
68 : : |*
69 : : |* SwSectionFrm::SwSectionFrm(), ~SwSectionFrm()
70 : : |*
71 : : |*************************************************************************/
72 : 162 : SwSectionFrm::SwSectionFrm( SwSection &rSect, SwFrm* pSib )
73 : 162 : : SwLayoutFrm( rSect.GetFmt(), pSib )
74 : : , SwFlowFrm( static_cast<SwFrm&>(*this) )
75 : : , pSection( &rSect )
76 : : , bFtnAtEnd(false)
77 : : , bEndnAtEnd(false)
78 : : , bCntntLock(false)
79 : : , bOwnFtnNum(false)
80 [ + - ]: 162 : , bFtnLock(false)
81 : : {
82 : 162 : nType = FRMC_SECTION;
83 : :
84 [ + - ]: 162 : CalcFtnAtEndFlag();
85 [ + - ]: 162 : CalcEndAtEndFlag();
86 : 162 : }
87 : :
88 : 45 : SwSectionFrm::SwSectionFrm( SwSectionFrm &rSect, sal_Bool bMaster ) :
89 : 45 : SwLayoutFrm( rSect.GetFmt(), rSect.getRootFrm() ),
90 : : SwFlowFrm( (SwFrm&)*this ),
91 : 45 : pSection( rSect.GetSection() ),
92 : 45 : bFtnAtEnd( rSect.IsFtnAtEnd() ),
93 : 45 : bEndnAtEnd( rSect.IsEndnAtEnd() ),
94 : : bCntntLock( false ),
95 : : bOwnFtnNum( false ),
96 [ + - ]: 45 : bFtnLock( false )
97 : : {
98 : 45 : nType = FRMC_SECTION;
99 : :
100 : : PROTOCOL( this, PROT_SECTION, bMaster ? ACT_CREATE_MASTER : ACT_CREATE_FOLLOW, &rSect )
101 : :
102 [ + + ]: 45 : if( bMaster )
103 : : {
104 [ - + ]: 16 : if( rSect.IsFollow() )
105 : : {
106 [ # # ]: 0 : SwSectionFrm* pMaster = rSect.FindMaster();
107 [ # # ]: 0 : pMaster->SetFollow( this );
108 : : }
109 [ + - ]: 16 : SetFollow( &rSect );
110 : : }
111 : : else
112 : : {
113 [ - + ][ + - ]: 29 : SetFollow( rSect.GetFollow() );
114 [ + - ]: 29 : rSect.SetFollow( this );
115 [ + - ]: 29 : if( !GetFollow() )
116 [ + - ]: 29 : rSect.SimpleFormat();
117 [ + + ]: 29 : if( !rSect.IsColLocked() )
118 [ + - ]: 3 : rSect.InvalidateSize();
119 : : }
120 : 45 : }
121 : :
122 : : // NOTE: call <SwSectionFrm::Init()> directly after creation of a new section
123 : : // frame and its insert in the layout.
124 : 207 : void SwSectionFrm::Init()
125 : : {
126 : : OSL_ENSURE( GetUpper(), "SwSectionFrm::Init before insertion?!" );
127 [ - + ][ # # ]: 207 : SWRECTFN( this )
[ # # ][ - + ]
128 [ + - ]: 207 : long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
129 [ + - ]: 207 : (Frm().*fnRect->fnSetWidth)( nWidth );
130 [ + - ]: 207 : (Frm().*fnRect->fnSetHeight)( 0 );
131 : :
132 : : // #109700# LRSpace for sections
133 : 207 : const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
134 [ + - ]: 207 : (Prt().*fnRect->fnSetLeft)( rLRSpace.GetLeft() );
135 : 414 : (Prt().*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() -
136 [ + - ]: 414 : rLRSpace.GetRight() );
137 [ + - ]: 207 : (Prt().*fnRect->fnSetHeight)( 0 );
138 : :
139 : 207 : const SwFmtCol &rCol = GetFmt()->GetCol();
140 [ + + ][ + - ]: 207 : if( ( rCol.GetNumCols() > 1 || IsAnyNoteAtEnd() ) && !IsInFtn() )
[ + + ][ + + ]
141 : : {
142 [ + - ][ + - ]: 38 : const SwFmtCol *pOld = Lower() ? &rCol : new SwFmtCol;
143 : 38 : ChgColumns( *pOld, rCol, IsAnyNoteAtEnd() );
144 [ + - ]: 38 : if( pOld != &rCol )
145 [ + - ]: 38 : delete pOld;
146 : : }
147 : 207 : }
148 : :
149 [ + - ]: 207 : SwSectionFrm::~SwSectionFrm()
150 : : {
151 [ + - ][ + - ]: 207 : if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
[ + - ][ + - ]
[ + - ]
152 : : {
153 : 207 : SwRootFrm *pRootFrm = getRootFrm();
154 [ + - ]: 207 : if( pRootFrm )
155 [ + - ]: 207 : pRootFrm->RemoveFromList( this ); //swmod 071108//swmod 071225
156 [ - + ]: 207 : if( IsFollow() )
157 : : {
158 [ # # ]: 0 : SwSectionFrm *pMaster = FindMaster();
159 [ # # ]: 0 : if( pMaster )
160 : : {
161 : : PROTOCOL( this, PROT_SECTION, ACT_DEL_FOLLOW, pMaster )
162 [ # # ][ # # ]: 0 : pMaster->SetFollow( GetFollow() );
163 : : // A Master always grabs the space until the lower edge of his
164 : : // Upper. If he doesn't have a Follow anymore, he can
165 : : // release it, which is why the Size of the Master is
166 : : // invalidated.
167 [ # # ]: 0 : if( !GetFollow() )
168 [ # # ]: 0 : pMaster->InvalidateSize();
169 : : }
170 : : }
171 : 207 : else if( HasFollow() )
172 : : {
173 : : PROTOCOL( this, PROT_SECTION, ACT_DEL_MASTER, GetFollow() )
174 : : }
175 : : }
176 [ - + ]: 414 : }
177 : :
178 : :
179 : : /*************************************************************************
180 : : |*
181 : : |* SwSectionFrm::DelEmpty()
182 : : |*
183 : : |*************************************************************************/
184 : 136 : void SwSectionFrm::DelEmpty( sal_Bool bRemove )
185 : : {
186 [ + + ]: 136 : if( IsColLocked() )
187 : : {
188 : : OSL_ENSURE( !bRemove, "Don't delete locked SectionFrms" );
189 : 136 : return;
190 : : }
191 : 108 : SwFrm* pUp = GetUpper();
192 [ + - ]: 108 : if( pUp )
193 : : {
194 : : // #i27138#
195 : : // notify accessibility paragraphs objects about changed
196 : : // CONTENT_FLOWS_FROM/_TO relation.
197 : : // Relation CONTENT_FLOWS_FROM for current next paragraph will change
198 : : // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
199 : : {
200 : 108 : ViewShell* pViewShell( getRootFrm()->GetCurrShell() );
201 [ + - - + ]: 216 : if ( pViewShell && pViewShell->GetLayout() &&
[ - + ][ + - ]
202 : 108 : pViewShell->GetLayout()->IsAnyShellAccessible() )
203 : : {
204 : : pViewShell->InvalidateAccessibleParaFlowRelation(
205 : 0 : dynamic_cast<SwTxtFrm*>(FindNextCnt( true )),
206 [ # # ][ # # ]: 0 : dynamic_cast<SwTxtFrm*>(FindPrevCnt( true )) );
207 : : }
208 : : }
209 : 108 : _Cut( bRemove );
210 : : }
211 [ + + ]: 108 : if( IsFollow() )
212 : : {
213 : 42 : SwSectionFrm *pMaster = FindMaster();
214 [ - + ]: 42 : pMaster->SetFollow( GetFollow() );
215 : : // A Master always grabs the space until the lower edge of his
216 : : // Upper. If he doesn't have a Follow anymore, he can
217 : : // release it, which is why the Size of the Master is
218 : : // invalidated.
219 [ + + ][ + + ]: 42 : if( !GetFollow() && !pMaster->IsColLocked() )
[ + - ]
220 : 2 : pMaster->InvalidateSize();
221 : : }
222 : 108 : SetFollow(0);
223 [ + - ]: 108 : if( pUp )
224 : : {
225 : 108 : Frm().Height( 0 );
226 : : // If we are destroyed immediately anyway, we don't need
227 : : // to put us into the list
228 [ + + ]: 108 : if( bRemove )
229 : : { // If we already were half dead before this DelEmpty,
230 : : // we are likely in the list and have to remove us from
231 : : // it
232 [ + + ][ + - ]: 48 : if( !pSection && getRootFrm() )
[ + + ]
233 : 2 : getRootFrm()->RemoveFromList( this );
234 : : }
235 [ + - ]: 60 : else if( getRootFrm() )
236 : 60 : getRootFrm()->InsertEmptySct( this ); //swmod 071108//swmod 071225
237 : 108 : pSection = NULL; // like this a reanimation is virtually impossible though
238 : : }
239 : : }
240 : :
241 : : /*************************************************************************
242 : : |*
243 : : |* SwSectionFrm::Cut()
244 : : |*
245 : : |*************************************************************************/
246 : 0 : void SwSectionFrm::Cut()
247 : : {
248 : 0 : _Cut( sal_True );
249 : 0 : }
250 : :
251 : 108 : void SwSectionFrm::_Cut( sal_Bool bRemove )
252 : : {
253 : : OSL_ENSURE( GetUpper(), "Cut ohne Upper()." );
254 : :
255 : : PROTOCOL( this, PROT_CUT, 0, GetUpper() )
256 : :
257 : 108 : SwPageFrm *pPage = FindPageFrm();
258 : 108 : InvalidatePage( pPage );
259 : 108 : SwFrm *pFrm = GetNext();
260 : 108 : SwFrm* pPrepFrm = NULL;
261 [ + - ][ + + ]: 184 : while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
[ + + ][ + + ]
262 : 76 : pFrm = pFrm->GetNext();
263 [ + - ]: 108 : if( pFrm )
264 : : { // The former successor might have calculated a gap to the predecessor
265 : : // which is now obsolete since he becomes the first
266 : 108 : pFrm->_InvalidatePrt();
267 : 108 : pFrm->_InvalidatePos();
268 [ + + ]: 108 : if( pFrm->IsSctFrm() )
269 : 58 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
270 [ + + ][ + - ]: 108 : if ( pFrm && pFrm->IsCntntFrm() )
[ + + ]
271 : : {
272 : 94 : pFrm->InvalidatePage( pPage );
273 [ + - ][ + + ]: 94 : if( IsInFtn() && !GetIndPrev() )
[ + + ]
274 : 2 : pPrepFrm = pFrm;
275 : : }
276 : : }
277 : : else
278 : : {
279 : 0 : InvalidateNextPos();
280 : : // Someone has to take over the retouching: predecessor or Upper
281 [ # # ]: 0 : if ( 0 != (pFrm = GetPrev()) )
282 : 0 : { pFrm->SetRetouche();
283 : 0 : pFrm->Prepare( PREP_WIDOWS_ORPHANS );
284 [ # # ]: 0 : if ( pFrm->IsCntntFrm() )
285 : 0 : pFrm->InvalidatePage( pPage );
286 : : }
287 : : // If I am (was) the only FlowFrm in my Upper, then he has to take over
288 : : // the retouching.
289 : : // Furthermore a blank page could have emerged
290 : : else
291 : 0 : { SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
292 : 0 : pRoot->SetSuperfluous();
293 : 0 : GetUpper()->SetCompletePaint();
294 : : }
295 : : }
296 : : // First remove, then shrink Upper
297 : 108 : SwLayoutFrm *pUp = GetUpper();
298 [ + + ]: 108 : if( bRemove )
299 : : {
300 : 48 : Remove();
301 [ - + ][ # # ]: 48 : if( pUp && !pUp->Lower() && pUp->IsFtnFrm() && !pUp->IsColLocked() &&
[ # # # # ]
[ - + ][ + - ]
302 : 0 : pUp->GetUpper() )
303 : : {
304 : 0 : pUp->Cut();
305 [ # # ]: 0 : delete pUp;
306 : 0 : pUp = NULL;
307 : : }
308 : : }
309 [ + + ]: 108 : if( pPrepFrm )
310 : 2 : pPrepFrm->Prepare( PREP_FTN );
311 [ + - ]: 108 : if ( pUp )
312 : : {
313 [ - + ][ # # ]: 108 : SWRECTFN( this );
[ # # ][ - + ]
314 [ + - ]: 108 : SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
315 [ + + ]: 108 : if( nFrmHeight > 0 )
316 : : {
317 [ + + ]: 36 : if( !bRemove )
318 : : {
319 [ + - ]: 20 : (Frm().*fnRect->fnSetHeight)( 0 );
320 [ + - ]: 20 : (Prt().*fnRect->fnSetHeight)( 0 );
321 : : }
322 : 36 : pUp->Shrink( nFrmHeight );
323 : : }
324 : : }
325 : 108 : }
326 : :
327 : : /*************************************************************************
328 : : |*
329 : : |* SwSectionFrm::Paste()
330 : : |*
331 : : |*************************************************************************/
332 : :
333 : 0 : void SwSectionFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
334 : : {
335 : : OSL_ENSURE( pParent, "Kein Parent fuer Paste." );
336 : : OSL_ENSURE( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
337 : : OSL_ENSURE( pParent != this, "Bin selbst der Parent." );
338 : : OSL_ENSURE( pSibling != this, "Bin mein eigener Nachbar." );
339 : : OSL_ENSURE( !GetPrev() && !GetUpper(),
340 : : "Bin noch irgendwo angemeldet." );
341 : :
342 : : PROTOCOL( this, PROT_PASTE, 0, GetUpper() )
343 : :
344 : : // Add to the tree
345 : 0 : SwSectionFrm* pSect = pParent->FindSctFrm();
346 : : // #156927#
347 : : // Assure that parent is not inside a table frame, which is inside the found section frame.
348 [ # # ]: 0 : if ( pSect )
349 : : {
350 : 0 : SwTabFrm* pTableFrm = pParent->FindTabFrm();
351 [ # # ]: 0 : if ( pTableFrm &&
[ # # # # ]
352 : 0 : pSect->IsAnLower( pTableFrm ) )
353 : : {
354 : 0 : pSect = 0;
355 : : }
356 : : }
357 : :
358 [ # # ][ # # ]: 0 : SWRECTFN( pParent )
[ # # ][ # # ]
359 [ # # ][ # # ]: 0 : if( pSect && HasToBreak( pSect ) )
[ # # ]
360 : : {
361 [ # # ]: 0 : if( pParent->IsColBodyFrm() ) // dealing with a single-column area
362 : : {
363 : : // If we are coincidentally at the end of a column, pSibling
364 : : // has to point to the first frame of the next column in order
365 : : // for the content of the next column to be moved correctly to the
366 : : // newly created pSect by the InsertGroup
367 : 0 : SwColumnFrm *pCol = (SwColumnFrm*)pParent->GetUpper();
368 [ # # ][ # # ]: 0 : while( !pSibling && 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
[ # # ]
369 : 0 : pSibling = ((SwLayoutFrm*)((SwColumnFrm*)pCol)->Lower())->Lower();
370 [ # # ]: 0 : if( pSibling )
371 : : {
372 : : // Even worse: every following column content has to
373 : : // be attached to the pSibling-chain in order to be
374 : : // taken along
375 : 0 : SwFrm *pTmp = pSibling;
376 [ # # ]: 0 : while ( 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
377 : : {
378 [ # # ]: 0 : while ( pTmp->GetNext() )
379 : 0 : pTmp = pTmp->GetNext();
380 : 0 : SwFrm* pSave = ::SaveCntnt( pCol );
381 : 0 : ::RestoreCntnt( pSave, pSibling->GetUpper(), pTmp, true );
382 : : }
383 : : }
384 : : }
385 : 0 : pParent = pSect;
386 [ # # ]: 0 : pSect = new SwSectionFrm( *((SwSectionFrm*)pParent)->GetSection(), pParent );
387 : : // if pParent is decomposed into two parts, its Follow has to be attached
388 : : // to the new second part
389 [ # # ]: 0 : pSect->SetFollow( ((SwSectionFrm*)pParent)->GetFollow() );
390 : 0 : ((SwSectionFrm*)pParent)->SetFollow( NULL );
391 [ # # ]: 0 : if( pSect->GetFollow() )
392 : 0 : pParent->_InvalidateSize();
393 : :
394 : 0 : InsertGroupBefore( pParent, pSibling, pSect );
395 : 0 : pSect->Init();
396 [ # # ]: 0 : (pSect->*fnRect->fnMakePos)( pSect->GetUpper(), pSect->GetPrev(), sal_True);
397 [ # # ]: 0 : if( !((SwLayoutFrm*)pParent)->Lower() )
398 : : {
399 : 0 : SwSectionFrm::MoveCntntAndDelete( (SwSectionFrm*)pParent, sal_False );
400 : 0 : pParent = this;
401 : : }
402 : : }
403 : : else
404 : 0 : InsertGroupBefore( pParent, pSibling, NULL );
405 : :
406 : 0 : _InvalidateAll();
407 : 0 : SwPageFrm *pPage = FindPageFrm();
408 : 0 : InvalidatePage( pPage );
409 : :
410 [ # # ]: 0 : if ( pSibling )
411 : : {
412 : 0 : pSibling->_InvalidatePos();
413 : 0 : pSibling->_InvalidatePrt();
414 [ # # ]: 0 : if ( pSibling->IsCntntFrm() )
415 : 0 : pSibling->InvalidatePage( pPage );
416 : : }
417 : :
418 [ # # ]: 0 : SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
419 [ # # ]: 0 : if( nFrmHeight )
420 : 0 : pParent->Grow( nFrmHeight );
421 : :
422 [ # # ]: 0 : if ( GetPrev() )
423 : : {
424 [ # # ]: 0 : if ( !IsFollow() )
425 : : {
426 : 0 : GetPrev()->InvalidateSize();
427 [ # # ]: 0 : if ( GetPrev()->IsCntntFrm() )
428 : 0 : GetPrev()->InvalidatePage( pPage );
429 : : }
430 : : }
431 : 0 : }
432 : :
433 : :
434 : : /*************************************************************************
435 : : |*
436 : : |* SwSectionFrm::HasToBreak()
437 : : |*
438 : : |* Here it's decided whether the this-SectionFrm should break up
439 : : |* the passed (Section)frm (or not).
440 : : |* Initiall, all superior sections are broken up. Later on that could
441 : : |* be made configurable.
442 : : |*
443 : : |*************************************************************************/
444 : :
445 : 0 : sal_Bool SwSectionFrm::HasToBreak( const SwFrm* pFrm ) const
446 : : {
447 [ # # ]: 0 : if( !pFrm->IsSctFrm() )
448 : 0 : return sal_False;
449 : :
450 : 0 : SwSectionFmt *pTmp = (SwSectionFmt*)GetFmt();
451 : : // if( !pTmp->GetSect().GetValue() )
452 : : // return sal_False;
453 : :
454 : 0 : const SwFrmFmt *pOtherFmt = ((SwSectionFrm*)pFrm)->GetFmt();
455 : 0 : do
456 : : {
457 : 0 : pTmp = pTmp->GetParent();
458 [ # # ]: 0 : if( !pTmp )
459 : 0 : return sal_False;
460 [ # # ]: 0 : if( pTmp == pOtherFmt )
461 : 0 : return sal_True;
462 : : } while( sal_True ); // ( pTmp->GetSect().GetValue() );
463 : : }
464 : :
465 : : /*************************************************************************
466 : : |*
467 : : |* SwSectionFrm::MergeNext()
468 : : |*
469 : : |* Merges two SectionFrms, in case it's about the same section.
470 : : |* This can be necessary when a (sub)section is deleted that had
471 : : |* divided another part into two.
472 : : |*
473 : : |*************************************************************************/
474 : :
475 : 6 : void SwSectionFrm::MergeNext( SwSectionFrm* pNxt )
476 : : {
477 [ + - ][ - + ]: 6 : if( !pNxt->IsJoinLocked() && GetSection() == pNxt->GetSection() )
[ - + ]
478 : : {
479 : : PROTOCOL( this, PROT_SECTION, ACT_MERGE, pNxt )
480 : :
481 : 0 : SwFrm* pTmp = ::SaveCntnt( pNxt );
482 [ # # ]: 0 : if( pTmp )
483 : : {
484 : 0 : SwFrm* pLast = Lower();
485 : 0 : SwLayoutFrm* pLay = this;
486 [ # # ]: 0 : if( pLast )
487 : : {
488 [ # # ]: 0 : while( pLast->GetNext() )
489 : 0 : pLast = pLast->GetNext();
490 [ # # ]: 0 : if( pLast->IsColumnFrm() )
491 : : { // Columns now with BodyFrm
492 : 0 : pLay = (SwLayoutFrm*)((SwLayoutFrm*)pLast)->Lower();
493 : 0 : pLast = pLay->Lower();
494 [ # # ]: 0 : if( pLast )
495 [ # # ]: 0 : while( pLast->GetNext() )
496 : 0 : pLast = pLast->GetNext();
497 : : }
498 : : }
499 : 0 : ::RestoreCntnt( pTmp, pLay, pLast, true );
500 : : }
501 [ # # ]: 0 : SetFollow( pNxt->GetFollow() );
502 : 0 : pNxt->SetFollow( NULL );
503 : 0 : pNxt->Cut();
504 [ # # ]: 0 : delete pNxt;
505 : 0 : InvalidateSize();
506 : : }
507 : 6 : }
508 : :
509 : : /*************************************************************************
510 : : |*
511 : : |* SwSectionFrm::SplitSect()
512 : : |*
513 : : |* Divides a SectionFrm into two parts. The second one starts with the
514 : : |* passed frame.
515 : : |* This is required when inserting an inner section, because the MoveFwd
516 : : |* cannot have the desired effect within a frame or a table cell.
517 : : |*
518 : : |*************************************************************************/
519 : :
520 : 6 : sal_Bool SwSectionFrm::SplitSect( SwFrm* pFrm, sal_Bool bApres )
521 : : {
522 : : OSL_ENSURE( pFrm, "SplitSect: Why?" );
523 [ + - ]: 6 : SwFrm* pOther = bApres ? pFrm->FindNext() : pFrm->FindPrev();
524 [ - + ]: 6 : if( !pOther )
525 : 0 : return sal_False;
526 : 6 : SwSectionFrm* pSect = pOther->FindSctFrm();
527 [ - + ]: 6 : if( pSect != this )
528 : 0 : return sal_False;
529 : : // Put the content aside
530 [ + - ]: 6 : SwFrm* pSav = ::SaveCntnt( this, bApres ? pOther : pFrm );
531 : : OSL_ENSURE( pSav, "SplitSect: What's on?" );
532 [ + - ]: 6 : if( pSav ) // be robust
533 : : { // Create a new SctFrm, not as a Follower/master
534 [ + - ]: 6 : SwSectionFrm* pNew = new SwSectionFrm( *pSect->GetSection(), pSect );
535 : 6 : pNew->InsertBehind( pSect->GetUpper(), pSect );
536 : 6 : pNew->Init();
537 [ # # ][ # # ]: 6 : SWRECTFN( this )
[ - + ][ - + ]
538 [ + - ]: 6 : (pNew->*fnRect->fnMakePos)( NULL, pSect, sal_True );
539 : : // OD 25.03.2003 #108339# - restore content:
540 : : // determine layout frame for restoring content after the initialization
541 : : // of the section frame. In the section initialization the columns are
542 : : // created.
543 : : {
544 : 6 : SwLayoutFrm* pLay = pNew;
545 : : // Search for last layout frame, e.g. for columned sections.
546 [ - + ][ # # ]: 6 : while( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
[ - + ]
547 : 0 : pLay = (SwLayoutFrm*)pLay->Lower();
548 : 6 : ::RestoreCntnt( pSav, pLay, NULL, true );
549 : : }
550 : 6 : _InvalidateSize();
551 [ - + ]: 6 : if( HasFollow() )
552 : : {
553 [ # # ]: 0 : pNew->SetFollow( GetFollow() );
554 : 0 : SetFollow( NULL );
555 : : }
556 : 6 : return sal_True;
557 : : }
558 : 6 : return sal_False;
559 : : }
560 : :
561 : : /*************************************************************************
562 : : |*
563 : : |* SwSectionFrm::MoveCntntAndDelete()
564 : : |*
565 : : |* MoveCntnt is called for destroying a SectionFrms, due to
566 : : |* the cancellation or hiding of a section, to handle the content.
567 : : |* If the SectionFrm hasn't broken up another one, then the content
568 : : |* is moved to the Upper. Otherwise the content is moved to another
569 : : |* SectionFrm, which has to be potentially merged.
570 : : |*
571 : : |*************************************************************************/
572 : : // If a multi-column section is cancelled, the ContentFrms have to be
573 : : // invalidated
574 : :
575 : 8 : void lcl_InvalidateInfFlags( SwFrm* pFrm, sal_Bool bInva )
576 : : {
577 [ + + ]: 16 : while ( pFrm )
578 : : {
579 : 8 : pFrm->InvalidateInfFlags();
580 [ - + ]: 8 : if( bInva )
581 : : {
582 : 0 : pFrm->_InvalidatePos();
583 : 0 : pFrm->_InvalidateSize();
584 : 0 : pFrm->_InvalidatePrt();
585 : : }
586 [ - + ]: 8 : if( pFrm->IsLayoutFrm() )
587 : 0 : lcl_InvalidateInfFlags( ((SwLayoutFrm*)pFrm)->GetLower(), sal_False );
588 : 8 : pFrm = pFrm->GetNext();
589 : : }
590 : 8 : }
591 : :
592 : :
593 : : //
594 : : // Works like SwCntntFrm::ImplGetNextCntntFrm, but starts with a LayoutFrm
595 : : //
596 : 8 : SwCntntFrm* lcl_GetNextCntntFrm( const SwLayoutFrm* pLay, bool bFwd )
597 : : {
598 [ + + ]: 8 : if ( bFwd )
599 : : {
600 [ + - ][ + + ]: 4 : if ( pLay->GetNext() && pLay->GetNext()->IsCntntFrm() )
[ + + ]
601 : 2 : return (SwCntntFrm*)pLay->GetNext();
602 : : }
603 : : else
604 : : {
605 [ + + ][ - + ]: 4 : if ( pLay->GetPrev() && pLay->GetPrev()->IsCntntFrm() )
[ - + ]
606 : 0 : return (SwCntntFrm*)pLay->GetPrev();
607 : : }
608 : :
609 : : // #100926#
610 : 6 : const SwFrm* pFrm = pLay;
611 : 6 : SwCntntFrm *pCntntFrm = 0;
612 : 6 : sal_Bool bGoingUp = sal_True;
613 [ + + ][ + + ]: 26 : do {
614 : 28 : const SwFrm *p = 0;
615 : 28 : sal_Bool bGoingFwdOrBwd = sal_False, bGoingDown = sal_False;
616 : :
617 [ + + ][ + - ]: 28 : bGoingDown = !bGoingUp && ( 0 != ( p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0 ) );
[ + + ]
618 [ + + ]: 28 : if ( !bGoingDown )
619 : : {
620 : 18 : bGoingFwdOrBwd = ( 0 != ( p = pFrm->IsFlyFrm() ?
621 : : ( bFwd ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink() ) :
622 [ # # ][ + + ]: 18 : ( bFwd ? pFrm->GetNext() :pFrm->GetPrev() ) ) );
[ - + ]
623 [ + + ]: 18 : if ( !bGoingFwdOrBwd )
624 : : {
625 : 12 : bGoingUp = (0 != (p = pFrm->GetUpper() ) );
626 [ + + ]: 12 : if ( !bGoingUp )
627 : 2 : return 0;
628 : : }
629 : : }
630 : :
631 [ + + ][ + + ]: 26 : bGoingUp = !( bGoingFwdOrBwd || bGoingDown );
632 : :
633 [ + + ][ + + ]: 26 : if( !bFwd && bGoingDown && p )
[ + - ]
634 [ + + ]: 8 : while ( p->GetNext() )
635 : 2 : p = p->GetNext();
636 : :
637 : 26 : pFrm = p;
638 : 26 : } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
639 : :
640 : 8 : return pCntntFrm;
641 : : }
642 : :
643 : : #define FIRSTLEAF( pLayFrm ) ( ( pLayFrm->Lower() && pLayFrm->Lower()->IsColumnFrm() )\
644 : : ? pLayFrm->GetNextLayoutLeaf() \
645 : : : pLayFrm )
646 : :
647 : 18 : void SwSectionFrm::MoveCntntAndDelete( SwSectionFrm* pDel, sal_Bool bSave )
648 : : {
649 [ + - ][ + + ]: 18 : sal_Bool bSize = pDel->Lower() && pDel->Lower()->IsColumnFrm();
650 : 18 : SwFrm* pPrv = pDel->GetPrev();
651 : 18 : SwLayoutFrm* pUp = pDel->GetUpper();
652 : : // OD 27.03.2003 #i12711# - initialize local pointer variables.
653 : 18 : SwSectionFrm* pPrvSct = NULL;
654 : 18 : SwSectionFrm* pNxtSct = NULL;
655 : 18 : SwSectionFmt* pParent = static_cast<SwSectionFmt*>(pDel->GetFmt())->GetParent();
656 [ - + ][ - + ]: 18 : if( pDel->IsInTab() && pParent )
[ + + ]
657 : : {
658 : 0 : SwTabFrm *pTab = pDel->FindTabFrm();
659 : : // If we are within a table, we can only have broken up sections that
660 : : // are inside as well, but not a section that contains the whole table.
661 [ # # ][ # # ]: 0 : if( pTab->IsInSct() && pParent == pTab->FindSctFrm()->GetFmt() )
[ # # ]
662 : 0 : pParent = NULL;
663 : : }
664 : : // If our Format has a parent, we have probably broken up another
665 : : // SectionFrm, which has to be checked. To do so we first acquire the
666 : : // succeeding and the preceding CntntFrm, let's see if they
667 : : // lay in the SectionFrms.
668 : : // OD 27.03.2003 #i12711# - check, if previous and next section belonging
669 : : // together and can be joined, *not* only if deleted section contains content.
670 [ + + ]: 18 : if ( pParent )
671 : : {
672 : 4 : SwFrm* pPrvCntnt = lcl_GetNextCntntFrm( pDel, false );
673 [ + + ]: 4 : pPrvSct = pPrvCntnt ? pPrvCntnt->FindSctFrm() : NULL;
674 : 4 : SwFrm* pNxtCntnt = lcl_GetNextCntntFrm( pDel, true );
675 [ + - ]: 4 : pNxtSct = pNxtCntnt ? pNxtCntnt->FindSctFrm() : NULL;
676 : : }
677 : : else
678 : : {
679 : 14 : pParent = NULL;
680 : 14 : pPrvSct = pNxtSct = NULL;
681 : : }
682 : :
683 : : // Now the content is put aside and the frame is destroyed
684 [ + + ]: 18 : SwFrm *pSave = bSave ? ::SaveCntnt( pDel ) : NULL;
685 : 18 : sal_Bool bOldFtn = sal_True;
686 [ + + ][ + + ]: 18 : if( pSave && pUp->IsFtnFrm() )
[ + + ]
687 : : {
688 : 2 : bOldFtn = ((SwFtnFrm*)pUp)->IsColLocked();
689 : 2 : ((SwFtnFrm*)pUp)->ColLock();
690 : : }
691 : 18 : pDel->DelEmpty( sal_True );
692 [ + - ]: 18 : delete pDel;
693 [ + + ]: 18 : if( pParent )
694 : : { // Search for the appropriate insert position
695 [ - + ][ # # ]: 4 : if( pNxtSct && pNxtSct->GetFmt() == pParent )
[ - + ]
696 : : { // Here we can insert outselves at the beginning
697 [ # # ][ # # ]: 0 : pUp = FIRSTLEAF( pNxtSct );
698 : 0 : pPrv = NULL;
699 [ # # ][ # # ]: 0 : if( pPrvSct && !( pPrvSct->GetFmt() == pParent ) )
[ # # ]
700 : 0 : pPrvSct = NULL; // In order that nothing is merged
701 : : }
702 [ + + ][ + - ]: 4 : else if( pPrvSct && pPrvSct->GetFmt() == pParent )
[ + + ]
703 : : { // Wonderful, here we can insert ourselves at the end
704 : 2 : pUp = pPrvSct;
705 [ + - ][ + - ]: 2 : if( pUp->Lower() && pUp->Lower()->IsColumnFrm() )
[ + - ]
706 : : {
707 : 2 : pUp = static_cast<SwLayoutFrm*>(pUp->GetLastLower());
708 : : // The body of the last column
709 : 2 : pUp = static_cast<SwLayoutFrm*>(pUp->Lower());
710 : : }
711 : : // In order to perform the insertion after the last one
712 : 2 : pPrv = pUp->GetLastLower();
713 : 2 : pPrvSct = NULL; // Such that nothing is merged
714 : : }
715 : : else
716 : : {
717 [ - + ]: 2 : if( pSave )
718 : : { // Following situations: before and after the section-to-be
719 : : // deleted there is the section boundary of the enclosing
720 : : // section, or another (sibling) section connects subsequently,
721 : : // that derives from the same Parent.
722 : : // In that case, there's not (yet) a part of our parent available
723 : : // that can store the content, so we create it here.
724 [ # # ]: 0 : pPrvSct = new SwSectionFrm( *pParent->GetSection(), pUp );
725 : 0 : pPrvSct->InsertBehind( pUp, pPrv );
726 : 0 : pPrvSct->Init();
727 [ # # ][ # # ]: 0 : SWRECTFN( pUp )
[ # # ][ # # ]
728 [ # # ]: 0 : (pPrvSct->*fnRect->fnMakePos)( pUp, pPrv, sal_True );
729 [ # # ][ # # ]: 0 : pUp = FIRSTLEAF( pPrvSct );
730 : 0 : pPrv = NULL;
731 : : }
732 : 2 : pPrvSct = NULL; // Such that nothing will be merged
733 : : }
734 : : }
735 : : // The content is going to be inserted..
736 [ + + ]: 18 : if( pSave )
737 : : {
738 : 8 : lcl_InvalidateInfFlags( pSave, bSize );
739 : 8 : ::RestoreCntnt( pSave, pUp, pPrv, true );
740 : 8 : pUp->FindPageFrm()->InvalidateCntnt();
741 [ + + ]: 8 : if( !bOldFtn )
742 : 2 : ((SwFtnFrm*)pUp)->ColUnlock();
743 : : }
744 : : // Now two parts of the superior section could possibly be merged
745 [ - + ][ # # ]: 18 : if( pPrvSct && !pPrvSct->IsJoinLocked() )
[ - + ]
746 : : {
747 : : OSL_ENSURE( pNxtSct, "MoveCntnt: No Merge" );
748 : 0 : pPrvSct->MergeNext( pNxtSct );
749 : : }
750 : 18 : }
751 : :
752 : 275 : void SwSectionFrm::MakeAll()
753 : : {
754 [ + - ][ + + ]: 275 : if ( IsJoinLocked() || IsColLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
[ + - ][ - + ]
[ + + ]
755 : 3 : return;
756 [ + + ]: 272 : if( !pSection ) // Via DelEmpty
757 : : {
758 : : #ifdef DBG_UTIL
759 : : OSL_ENSURE( getRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
760 : : #endif
761 [ + + ]: 28 : if( !bValidPos )
762 : : {
763 [ + - ]: 14 : if( GetUpper() )
764 : : {
765 [ - + ][ # # ]: 14 : SWRECTFN( GetUpper() )
[ # # ][ - + ]
766 [ + - ]: 14 : (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), sal_False );
767 : : }
768 : : }
769 : 28 : bValidSize = bValidPos = bValidPrtArea = sal_True;
770 : 28 : return;
771 : : }
772 : 244 : LockJoin(); // I don't let myself to be destroyed on the way
773 : :
774 [ + + ][ - + ]: 244 : while( GetNext() && GetNext() == GetFollow() )
[ - + ]
775 : : {
776 : 0 : const SwFrm* pFoll = GetFollow();
777 : 0 : MergeNext( (SwSectionFrm*)GetNext() );
778 [ # # ]: 0 : if( pFoll == GetFollow() )
779 : 0 : break;
780 : : }
781 : :
782 : : // OD 2004-03-15 #116561# - In online layout join the follows, if section
783 : : // can grow.
784 : 244 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
785 [ - + # # ]: 244 : if( pSh && pSh->GetViewOptions()->getBrowseMode() &&
[ - + ][ + - ]
786 : 0 : ( Grow( LONG_MAX, true ) > 0 ) )
787 : : {
788 [ # # ]: 0 : while( GetFollow() )
789 : : {
790 : 0 : const SwFrm* pFoll = GetFollow();
791 : 0 : MergeNext( GetFollow() );
792 [ # # ]: 0 : if( pFoll == GetFollow() )
793 : 0 : break;
794 : : }
795 : : }
796 : :
797 : : // A section with Follow uses all the space until the lower edge of the
798 : : // Upper. If it moves, its size can grow or decrease...
799 [ + + ][ - + ]: 244 : if( !bValidPos && ToMaximize( sal_False ) )
[ - + ]
800 : 0 : bValidSize = sal_False;
801 : :
802 : : #if OSL_DEBUG_LEVEL > 1
803 : : const SwFmtCol &rCol = GetFmt()->GetCol();
804 : : (void)rCol;
805 : : #endif
806 : 244 : SwLayoutFrm::MakeAll();
807 : 244 : UnlockJoin();
808 [ + + ][ + + ]: 244 : if( pSection && IsSuperfluous() )
[ + - ]
809 : 275 : DelEmpty( sal_False );
810 : : }
811 : :
812 : 0 : sal_Bool SwSectionFrm::ShouldBwdMoved( SwLayoutFrm *, sal_Bool , sal_Bool & )
813 : : {
814 : : OSL_FAIL( "Hups, wo ist meine Tarnkappe?" );
815 : 0 : return sal_False;
816 : : }
817 : :
818 : 0 : const SwSectionFmt* SwSectionFrm::_GetEndSectFmt() const
819 : : {
820 : 0 : const SwSectionFmt *pFmt = pSection->GetFmt();
821 [ # # ]: 0 : while( !pFmt->GetEndAtTxtEnd().IsAtEnd() )
822 : : {
823 [ # # ]: 0 : if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
824 : 0 : pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
825 : : else
826 : 0 : return NULL;
827 : : }
828 : 0 : return pFmt;
829 : : }
830 : :
831 : 716 : void lcl_FindCntntFrm( SwCntntFrm* &rpCntntFrm, SwFtnFrm* &rpFtnFrm,
832 : : SwFrm* pFrm, sal_Bool &rbChkFtn )
833 : : {
834 [ + + ]: 716 : if( pFrm )
835 : : {
836 [ + + ]: 720 : while( pFrm->GetNext() )
837 : 92 : pFrm = pFrm->GetNext();
838 [ + + ][ + + ]: 1342 : while( !rpCntntFrm && pFrm )
[ + + ]
839 : : {
840 [ + + ]: 714 : if( pFrm->IsCntntFrm() )
841 : 386 : rpCntntFrm = (SwCntntFrm*)pFrm;
842 [ + - ]: 328 : else if( pFrm->IsLayoutFrm() )
843 : : {
844 [ - + ]: 328 : if( pFrm->IsFtnFrm() )
845 : : {
846 [ # # ]: 0 : if( rbChkFtn )
847 : : {
848 : 0 : rpFtnFrm = (SwFtnFrm*)pFrm;
849 : 0 : rbChkFtn = rpFtnFrm->GetAttr()->GetFtn().IsEndNote();
850 : : }
851 : : }
852 : : else
853 : : lcl_FindCntntFrm( rpCntntFrm, rpFtnFrm,
854 : 328 : ((SwLayoutFrm*)pFrm)->Lower(), rbChkFtn );
855 : : }
856 : 714 : pFrm = pFrm->GetPrev();
857 : : }
858 : : }
859 : 716 : }
860 : :
861 : 388 : SwCntntFrm *SwSectionFrm::FindLastCntnt( sal_uInt8 nMode )
862 : : {
863 : 388 : SwCntntFrm *pRet = NULL;
864 : 388 : SwFtnFrm *pFtnFrm = NULL;
865 : 388 : SwSectionFrm *pSect = this;
866 [ - + ]: 388 : if( nMode )
867 : : {
868 : 0 : const SwSectionFmt *pFmt = IsEndnAtEnd() ? GetEndSectFmt() :
869 [ # # ][ # # ]: 0 : pSection->GetFmt();
870 : 0 : do {
871 [ # # ]: 0 : while( pSect->HasFollow() )
872 : 0 : pSect = pSect->GetFollow();
873 [ # # ]: 0 : SwFrm* pTmp = pSect->FindNext();
874 [ # # ]: 0 : while( pTmp && pTmp->IsSctFrm() &&
[ # # # # ]
[ # # ]
875 : 0 : !((SwSectionFrm*)pTmp)->GetSection() )
876 [ # # ]: 0 : pTmp = pTmp->FindNext();
877 [ # # ][ # # ]: 0 : if( pTmp && pTmp->IsSctFrm() &&
[ # # ][ # # ]
878 [ # # ]: 0 : ((SwSectionFrm*)pTmp)->IsDescendantFrom( pFmt ) )
879 : 0 : pSect = (SwSectionFrm*)pTmp;
880 : : else
881 : 0 : break;
882 : : } while( sal_True );
883 : : }
884 : 388 : sal_Bool bFtnFound = nMode == FINDMODE_ENDNOTE;
885 [ # # ]: 0 : do
886 : : {
887 [ + - ]: 388 : lcl_FindCntntFrm( pRet, pFtnFrm, pSect->Lower(), bFtnFound );
888 [ + + ][ - + ]: 388 : if( pRet || !pSect->IsFollow() || !nMode ||
[ # # ][ # # ]
[ # # ][ + - ]
889 : : ( FINDMODE_MYLAST == nMode && this == pSect ) )
890 : 388 : break;
891 [ # # ]: 0 : pSect = pSect->FindMaster();
892 : : } while( pSect );
893 [ - + ][ # # ]: 388 : if( ( nMode == FINDMODE_ENDNOTE ) && pFtnFrm )
894 [ # # ]: 0 : pRet = pFtnFrm->ContainsCntnt();
895 : 388 : return pRet;
896 : : }
897 : :
898 : 92 : sal_Bool SwSectionFrm::CalcMinDiff( SwTwips& rMinDiff ) const
899 : : {
900 [ + + ]: 92 : if( ToMaximize( sal_True ) )
901 : : {
902 [ - + ][ # # ]: 26 : SWRECTFN( this )
[ # # ][ - + ]
903 [ + - ]: 26 : rMinDiff = (GetUpper()->*fnRect->fnGetPrtBottom)();
904 [ + - ]: 26 : rMinDiff = (Frm().*fnRect->fnBottomDist)( rMinDiff );
905 : 26 : return sal_True;
906 : : }
907 : 92 : return sal_False;
908 : : }
909 : :
910 : : /*************************************************************************
911 : : *
912 : : * SwSectionFrm::CollectEndnotes( )
913 : : *
914 : : * CollectEndnotes looks for endnotes in the sectionfrm and his follows,
915 : : * the endnotes will cut off the layout and put into the array.
916 : : * If the first endnote is not a master-SwFtnFrm, the whole sectionfrm
917 : : * contains only endnotes and it is not necessary to collect them.
918 : : *
919 : : *************************************************************************/
920 : :
921 : 30 : SwFtnFrm* lcl_FindEndnote( SwSectionFrm* &rpSect, sal_Bool &rbEmpty,
922 : : SwLayouter *pLayouter )
923 : : {
924 : : // if rEmpty is set, the rpSect is already searched
925 [ - + ]: 30 : SwSectionFrm* pSect = rbEmpty ? rpSect->GetFollow() : rpSect;
926 [ + + ]: 60 : while( pSect )
927 : : {
928 : : OSL_ENSURE( (pSect->Lower() && pSect->Lower()->IsColumnFrm()) || pSect->GetUpper()->IsFtnFrm(),
929 : : "InsertEndnotes: Where's my column?" );
930 : :
931 : : // i73332: Columned section in endnote
932 : 30 : SwColumnFrm* pCol = 0;
933 [ + - ][ + - ]: 30 : if(pSect->Lower() && pSect->Lower()->IsColumnFrm())
[ + - ]
934 : 30 : pCol = (SwColumnFrm*)pSect->Lower();
935 : :
936 [ + + ]: 60 : while( pCol ) // check all columns
937 : : {
938 : 30 : SwFtnContFrm* pFtnCont = pCol->FindFtnCont();
939 [ - + ]: 30 : if( pFtnCont )
940 : : {
941 : 0 : SwFtnFrm* pRet = (SwFtnFrm*)pFtnCont->Lower();
942 [ # # ]: 0 : while( pRet ) // look for endnotes
943 : : {
944 [ # # ]: 0 : if( pRet->GetAttr()->GetFtn().IsEndNote() )
945 : : {
946 [ # # ]: 0 : if( pRet->GetMaster() )
947 : : {
948 [ # # ]: 0 : if( pLayouter )
949 : 0 : pLayouter->CollectEndnote( pRet );
950 : : else
951 : 0 : return 0;
952 : : }
953 : : else
954 : 0 : return pRet; // Found
955 : : }
956 : 0 : pRet = (SwFtnFrm*)pRet->GetNext();
957 : : }
958 : : }
959 : 30 : pCol = (SwColumnFrm*)pCol->GetNext();
960 : : }
961 : 30 : rpSect = pSect;
962 [ - + ]: 30 : pSect = pLayouter ? pSect->GetFollow() : NULL;
963 : 30 : rbEmpty = sal_True;
964 : : }
965 : 30 : return NULL;
966 : : }
967 : :
968 : 8 : void lcl_ColumnRefresh( SwSectionFrm* pSect, sal_Bool bFollow )
969 : : {
970 [ + + ]: 16 : while( pSect )
971 : : {
972 : 8 : sal_Bool bOldLock = pSect->IsColLocked();
973 : 8 : pSect->ColLock();
974 [ + + ][ + + ]: 8 : if( pSect->Lower() && pSect->Lower()->IsColumnFrm() )
[ + - ]
975 : : {
976 : 2 : SwColumnFrm *pCol = (SwColumnFrm*)pSect->Lower();
977 [ + + ]: 4 : do
978 : 4 : { pCol->_InvalidateSize();
979 : 4 : pCol->_InvalidatePos();
980 : 4 : ((SwLayoutFrm*)pCol)->Lower()->_InvalidateSize();
981 : 4 : pCol->Calc(); // calculation of column and
982 : 4 : ((SwLayoutFrm*)pCol)->Lower()->Calc(); // body
983 : 4 : pCol = (SwColumnFrm*)pCol->GetNext();
984 : : } while ( pCol );
985 : : }
986 [ + - ]: 8 : if( !bOldLock )
987 : 8 : pSect->ColUnlock();
988 [ - + ]: 8 : if( bFollow )
989 : 0 : pSect = pSect->GetFollow();
990 : : else
991 : 8 : pSect = NULL;
992 : : }
993 : 8 : }
994 : :
995 : 0 : void SwSectionFrm::CollectEndnotes( SwLayouter* pLayouter )
996 : : {
997 : : OSL_ENSURE( IsColLocked(), "CollectEndnotes: You love the risk?" );
998 : : // i73332: Section in footnode does not have columns!
999 : : OSL_ENSURE( (Lower() && Lower()->IsColumnFrm()) || GetUpper()->IsFtnFrm(), "Where's my column?" );
1000 : :
1001 : 0 : SwSectionFrm* pSect = this;
1002 : : SwFtnFrm* pFtn;
1003 : 0 : sal_Bool bEmpty = sal_False;
1004 : : // pSect is the last sectionfrm without endnotes or the this-pointer
1005 : : // the first sectionfrm with endnotes may be destroyed, when the endnotes
1006 : : // is cutted
1007 [ # # ][ # # ]: 0 : while( 0 != (pFtn = lcl_FindEndnote( pSect, bEmpty, pLayouter )) )
1008 [ # # ]: 0 : pLayouter->CollectEndnote( pFtn );
1009 [ # # ][ # # ]: 0 : if( pLayouter->HasEndnotes() )
1010 [ # # ]: 0 : lcl_ColumnRefresh( this, sal_True );
1011 : 0 : }
1012 : :
1013 : : /*************************************************************************
1014 : : |*
1015 : : |* SwSectionFrm::_CheckClipping( sal_Bool bGrow, sal_Bool bMaximize )
1016 : : |*
1017 : : |* Description: Fits the size to the surroundings.
1018 : : |* Those that have a Follow or foot notes, have to extend until
1019 : : |* the lower edge of a upper (bMaximize)
1020 : : |* They must not extend above the Upper, as the case may be one can
1021 : : |* try to grow its upper (bGrow)
1022 : : |* If the size had to be changed, the content is calculated.
1023 : : |*
1024 : : |*************************************************************************/
1025 : :
1026 : : /// OD 18.09.2002 #100522#
1027 : : /// perform calculation of content, only if height has changed.
1028 : 360 : void SwSectionFrm::_CheckClipping( sal_Bool bGrow, sal_Bool bMaximize )
1029 : : {
1030 [ - + ][ # # ]: 360 : SWRECTFN( this )
[ # # ][ - + ]
1031 : : long nDiff;
1032 [ + - ]: 360 : SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1033 [ - + ]: 360 : if( bGrow && ( !IsInFly() || !GetUpper()->IsColBodyFrm() ||
[ # # # # ]
[ + + ][ + + ]
1034 : 0 : !FindFlyFrm()->IsLocked() ) )
1035 : : {
1036 [ + - ]: 180 : nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine );
1037 [ + + ]: 180 : if( !bMaximize )
1038 : 163 : nDiff += Undersize();
1039 [ + + ]: 180 : if( nDiff > 0 )
1040 : : {
1041 : 3 : long nAdd = GetUpper()->Grow( nDiff );
1042 [ # # ][ - + ]: 3 : if( bVert && !bRev )
1043 : 0 : nDeadLine -= nAdd;
1044 : : else
1045 : 3 : nDeadLine += nAdd;
1046 : : }
1047 : : }
1048 [ + - ]: 360 : nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine );
1049 [ + + ][ + + ]: 360 : SetUndersized( !bMaximize && nDiff >= 0 );
1050 : 360 : const bool bCalc = ( IsUndersized() || bMaximize ) &&
1051 : : ( nDiff ||
1052 [ + + ][ + + ]: 360 : (Prt().*fnRect->fnGetTop)() > (Frm().*fnRect->fnGetHeight)() );
[ + - ][ + - ]
[ - + ][ + + ]
1053 : : // OD 03.11.2003 #i19737# - introduce local variable <bExtraCalc> to indicate
1054 : : // that a calculation has to be done beside the value of <bCalc>.
1055 : 360 : bool bExtraCalc = false;
1056 [ + + ][ + + ]: 360 : if( !bCalc && !bGrow && IsAnyNoteAtEnd() && !IsInFtn() )
[ + + ][ + - ]
[ + + ]
1057 : : {
1058 : 36 : SwSectionFrm *pSect = this;
1059 : 36 : sal_Bool bEmpty = sal_False;
1060 : 36 : SwLayoutFrm* pFtn = IsEndnAtEnd() ?
1061 [ + - ][ + + ]: 36 : lcl_FindEndnote( pSect, bEmpty, NULL ) : NULL;
1062 [ - + ]: 36 : if( pFtn )
1063 : : {
1064 [ # # ]: 0 : pFtn = pFtn->FindFtnBossFrm();
1065 [ # # ]: 0 : SwFrm* pTmp = FindLastCntnt( FINDMODE_LASTCNT );
1066 : : // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
1067 [ # # ][ # # ]: 0 : if ( pTmp && pFtn->IsBefore( pTmp->FindFtnBossFrm() ) )
[ # # ][ # # ]
[ # # ]
1068 : 0 : bExtraCalc = true;
1069 : : }
1070 [ - + ][ # # ]: 36 : else if( GetFollow() && !GetFollow()->ContainsAny() )
[ # # ][ - + ]
1071 : 36 : bExtraCalc = true;
1072 : : }
1073 [ + + ][ - + ]: 360 : if ( bCalc || bExtraCalc )
1074 : : {
1075 [ + - ][ + - ]: 17 : nDiff = (*fnRect->fnYDiff)( nDeadLine, (Frm().*fnRect->fnGetTop)() );
[ + - ]
1076 [ - + ]: 17 : if( nDiff < 0 )
1077 : : {
1078 : 0 : nDiff = 0;
1079 [ # # ][ # # ]: 0 : nDeadLine = (Frm().*fnRect->fnGetTop)();
1080 : : }
1081 : 17 : const Size aOldSz( Prt().SSize() );
1082 [ + - ][ + - ]: 17 : long nTop = (this->*fnRect->fnGetTopMargin)();
1083 [ + - ][ + - ]: 17 : (Frm().*fnRect->fnSetBottom)( nDeadLine );
1084 [ + - ][ + - ]: 17 : nDiff = (Frm().*fnRect->fnGetHeight)();
1085 [ - + ]: 17 : if( nTop > nDiff )
1086 : 0 : nTop = nDiff;
1087 [ + - ][ + - ]: 17 : (this->*fnRect->fnSetYMargins)( nTop, 0 );
1088 : :
1089 : : // OD 18.09.2002 #100522#
1090 : : // Determine, if height has changed.
1091 : : // Note: In vertical layout the height equals the width value.
1092 : : bool bHeightChanged = bVert ?
1093 : 0 : (aOldSz.Width() != Prt().Width()) :
1094 [ - + ]: 17 : (aOldSz.Height() != Prt().Height());
1095 : : // Last but not least we have changed the height again, thus the inner
1096 : : // layout (columns) is calculated and the content as well.
1097 : : // OD 18.09.2002 #100522#
1098 : : // calculate content, only if height has changed.
1099 : : // OD 03.11.2003 #i19737# - restriction of content calculation too strong.
1100 : : // If an endnote has an incorrect position or a follow section contains
1101 : : // no content except footnotes/endnotes, the content has also been calculated.
1102 [ - + ][ # # ]: 17 : if ( ( bHeightChanged || bExtraCalc ) && Lower() )
[ + + ][ + + ]
1103 : : {
1104 [ - + ]: 3 : if( Lower()->IsColumnFrm() )
1105 : : {
1106 [ # # ]: 0 : lcl_ColumnRefresh( this, sal_False );
1107 [ # # ]: 0 : ::CalcCntnt( this );
1108 : : }
1109 : : else
1110 : : {
1111 [ + - ]: 3 : ChgLowersProp( aOldSz );
1112 [ + - ][ - + ]: 3 : if( !bMaximize && !IsCntntLocked() )
[ - + ]
1113 [ # # ]: 17 : ::CalcCntnt( this );
1114 : : }
1115 : : }
1116 : : }
1117 : 360 : }
1118 : :
1119 : 34 : void SwSectionFrm::SimpleFormat()
1120 : : {
1121 [ + + ][ - + ]: 34 : if ( IsJoinLocked() || IsColLocked() )
[ + + ]
1122 : 34 : return;
1123 : : // OSL_ENSURE( pFollow, "SimpleFormat: Follow required" );
1124 : 8 : LockJoin();
1125 [ # # ][ # # ]: 8 : SWRECTFN( this )
[ - + ][ - + ]
1126 [ + + ][ + - ]: 8 : if( GetPrev() || GetUpper() )
[ + - ]
1127 : : {
1128 : : //
1129 : : // assure notifications on position changes.
1130 [ + - ]: 8 : const SwLayNotify aNotify( this );
1131 [ + - ][ + - ]: 8 : (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), sal_False );
1132 [ + - ]: 8 : bValidPos = sal_True;
1133 : : }
1134 [ + - ]: 8 : SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1135 : : // OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in
1136 : : // order to get calculated lowers, not only if there space left in its upper.
1137 [ + - ][ + - ]: 8 : if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) >= 0 )
1138 : : {
1139 [ + - ]: 8 : (Frm().*fnRect->fnSetBottom)( nDeadLine );
1140 [ + - ]: 8 : long nHeight = (Frm().*fnRect->fnGetHeight)();
1141 : 8 : long nTop = CalcUpperSpace();
1142 [ - + ]: 8 : if( nTop > nHeight )
1143 : 0 : nTop = nHeight;
1144 [ + - ]: 8 : (this->*fnRect->fnSetYMargins)( nTop, 0 );
1145 : : }
1146 : 8 : lcl_ColumnRefresh( this, sal_False );
1147 : 8 : UnlockJoin();
1148 : : }
1149 : :
1150 : : // #i40147# - helper class to perform extra section format
1151 : : // to position anchored objects and to keep the position of whose objects locked.
1152 : : class ExtraFormatToPositionObjs
1153 : : {
1154 : : private:
1155 : : SwSectionFrm* mpSectFrm;
1156 : : bool mbExtraFormatPerformed;
1157 : :
1158 : : public:
1159 : 180 : ExtraFormatToPositionObjs( SwSectionFrm& _rSectFrm)
1160 : : : mpSectFrm( &_rSectFrm ),
1161 : 180 : mbExtraFormatPerformed( false )
1162 : 180 : {}
1163 : :
1164 : 180 : ~ExtraFormatToPositionObjs()
1165 : : {
1166 [ - + ]: 180 : if ( mbExtraFormatPerformed )
1167 : : {
1168 : : // release keep locked position of lower floating screen objects
1169 : 0 : SwPageFrm* pPageFrm = mpSectFrm->FindPageFrm();
1170 [ # # ]: 0 : SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
1171 [ # # ]: 0 : if ( pObjs )
1172 : : {
1173 : 0 : sal_uInt32 i = 0;
1174 [ # # ]: 0 : for ( i = 0; i < pObjs->Count(); ++i )
1175 : : {
1176 : 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1177 : :
1178 [ # # ]: 0 : if ( mpSectFrm->IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
1179 : : {
1180 : 0 : pAnchoredObj->SetKeepPosLocked( false );
1181 : : }
1182 : : }
1183 : : }
1184 : : }
1185 : 180 : }
1186 : :
1187 : : // #i81555#
1188 : 0 : void InitObjs( SwFrm& rFrm )
1189 : : {
1190 : 0 : SwSortedObjs* pObjs = rFrm.GetDrawObjs();
1191 [ # # ]: 0 : if ( pObjs )
1192 : : {
1193 : 0 : sal_uInt32 i = 0;
1194 [ # # ]: 0 : for ( i = 0; i < pObjs->Count(); ++i )
1195 : : {
1196 : 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1197 : :
1198 : 0 : pAnchoredObj->UnlockPosition();
1199 : 0 : pAnchoredObj->SetClearedEnvironment( false );
1200 : : }
1201 : : }
1202 [ # # ]: 0 : SwLayoutFrm* pLayoutFrm = dynamic_cast<SwLayoutFrm*>(&rFrm);
1203 [ # # ]: 0 : if ( pLayoutFrm != 0 )
1204 : : {
1205 : 0 : SwFrm* pLowerFrm = pLayoutFrm->GetLower();
1206 [ # # ]: 0 : while ( pLowerFrm != 0 )
1207 : : {
1208 : 0 : InitObjs( *pLowerFrm );
1209 : :
1210 : 0 : pLowerFrm = pLowerFrm->GetNext();
1211 : : }
1212 : : }
1213 : 0 : }
1214 : :
1215 : 0 : void FormatSectionToPositionObjs()
1216 : : {
1217 : : // perform extra format for multi-columned section.
1218 [ # # ]: 0 : if ( mpSectFrm->Lower() && mpSectFrm->Lower()->IsColumnFrm() &&
[ # # # # ]
[ # # ]
1219 : 0 : mpSectFrm->Lower()->GetNext() )
1220 : : {
1221 : : // grow section till bottom of printing area of upper frame
1222 [ # # ][ # # ]: 0 : SWRECTFN( mpSectFrm );
[ # # ][ # # ]
[ # # ]
1223 [ # # ][ # # ]: 0 : SwTwips nTopMargin = (mpSectFrm->*fnRect->fnGetTopMargin)();
1224 : 0 : Size aOldSectPrtSize( mpSectFrm->Prt().SSize() );
1225 : 0 : SwTwips nDiff = (mpSectFrm->Frm().*fnRect->fnBottomDist)(
1226 [ # # ][ # # ]: 0 : (mpSectFrm->GetUpper()->*fnRect->fnGetPrtBottom)() );
[ # # ][ # # ]
1227 [ # # ][ # # ]: 0 : (mpSectFrm->Frm().*fnRect->fnAddBottom)( nDiff );
1228 [ # # ][ # # ]: 0 : (mpSectFrm->*fnRect->fnSetYMargins)( nTopMargin, 0 );
1229 : : // #i59789#
1230 : : // suppress formatting, if printing area of section is too narrow
1231 [ # # ][ # # ]: 0 : if ( (mpSectFrm->Prt().*fnRect->fnGetHeight)() <= 0 )
[ # # ]
1232 : : {
1233 : 0 : return;
1234 : : }
1235 [ # # ]: 0 : mpSectFrm->ChgLowersProp( aOldSectPrtSize );
1236 : :
1237 : : // format column frames and its body and footnote container
1238 : 0 : SwColumnFrm* pColFrm = static_cast<SwColumnFrm*>(mpSectFrm->Lower());
1239 [ # # ]: 0 : while ( pColFrm )
1240 : : {
1241 [ # # ]: 0 : pColFrm->Calc();
1242 [ # # ]: 0 : pColFrm->Lower()->Calc();
1243 [ # # ]: 0 : if ( pColFrm->Lower()->GetNext() )
1244 : : {
1245 [ # # ]: 0 : pColFrm->Lower()->GetNext()->Calc();
1246 : : }
1247 : :
1248 : 0 : pColFrm = static_cast<SwColumnFrm*>(pColFrm->GetNext());
1249 : : }
1250 : :
1251 : : // unlock position of lower floating screen objects for the extra format
1252 : : // #i81555#
1253 : : // Section frame can already have changed the page and its content
1254 : : // can still be on the former page.
1255 : : // Thus, initialize objects via lower-relationship
1256 [ # # ]: 0 : InitObjs( *mpSectFrm );
1257 : :
1258 : : // format content - first with collecting its foot-/endnotes before content
1259 : : // format, second without collecting its foot-/endnotes.
1260 [ # # ]: 0 : ::CalcCntnt( mpSectFrm );
1261 [ # # ]: 0 : ::CalcCntnt( mpSectFrm, true );
1262 : :
1263 : : // keep locked position of lower floating screen objects
1264 [ # # ]: 0 : SwPageFrm* pPageFrm = mpSectFrm->FindPageFrm();
1265 [ # # ]: 0 : SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
1266 [ # # ]: 0 : if ( pObjs )
1267 : : {
1268 : 0 : sal_uInt32 i = 0;
1269 [ # # ][ # # ]: 0 : for ( i = 0; i < pObjs->Count(); ++i )
1270 : : {
1271 [ # # ]: 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1272 : :
1273 [ # # ][ # # ]: 0 : if ( mpSectFrm->IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
[ # # ]
1274 : : {
1275 : 0 : pAnchoredObj->SetKeepPosLocked( true );
1276 : : }
1277 : : }
1278 : : }
1279 : :
1280 : 0 : mbExtraFormatPerformed = true;
1281 : : }
1282 : : }
1283 : : };
1284 : :
1285 : : /*************************************************************************
1286 : : |*
1287 : : |* SwSectionFrm::Format()
1288 : : |*
1289 : : |* Description: "formats" the frame; Frm and PrtArea
1290 : : |*
1291 : : |*************************************************************************/
1292 : :
1293 : 184 : void SwSectionFrm::Format( const SwBorderAttrs *pAttr )
1294 : : {
1295 [ - + ]: 184 : if( !pSection ) // via DelEmpty
1296 : : {
1297 : : #ifdef DBG_UTIL
1298 : : OSL_ENSURE( getRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
1299 : : #endif
1300 : 0 : bValidSize = bValidPos = bValidPrtArea = sal_True;
1301 : 184 : return;
1302 : : }
1303 [ - + ][ # # ]: 184 : SWRECTFN( this )
[ # # ][ - + ]
1304 [ + - ]: 184 : if ( !bValidPrtArea )
1305 : : {
1306 : : PROTOCOL( this, PROT_PRTAREA, 0, 0 )
1307 : 184 : bValidPrtArea = sal_True;
1308 : 184 : SwTwips nUpper = CalcUpperSpace();
1309 : :
1310 : : // #109700# LRSpace for sections
1311 : 184 : const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
1312 [ + - ]: 184 : (this->*fnRect->fnSetXMargins)( rLRSpace.GetLeft(), rLRSpace.GetRight() );
1313 : :
1314 [ + + ][ + - ]: 184 : if( nUpper != (this->*fnRect->fnGetTopMargin)() )
1315 : : {
1316 : 18 : bValidSize = sal_False;
1317 : 18 : SwFrm* pOwn = ContainsAny();
1318 [ + + ]: 18 : if( pOwn )
1319 : 4 : pOwn->_InvalidatePos();
1320 : : }
1321 [ + - ]: 184 : (this->*fnRect->fnSetYMargins)( nUpper, 0 );
1322 : : }
1323 : :
1324 [ + + ]: 184 : if ( !bValidSize )
1325 : : {
1326 : : PROTOCOL_ENTER( this, PROT_SIZE, 0, 0 )
1327 [ + - ][ + - ]: 180 : const long nOldHeight = (Frm().*fnRect->fnGetHeight)();
1328 : 180 : sal_Bool bOldLock = IsColLocked();
1329 : 180 : ColLock();
1330 : :
1331 : 180 : bValidSize = sal_True;
1332 : :
1333 : : // The size is only determined by the content, if the SectFrm does not have a
1334 : : // Follow. Otherwise it fills (occupies) the Upper down to the lower edge.
1335 : : // It is not responsible for the text flow, but the content is.
1336 [ + - ]: 180 : sal_Bool bMaximize = ToMaximize( sal_False );
1337 : :
1338 : : // OD 2004-05-17 #i28701# - If the wrapping style has to be considered
1339 : : // on object positioning, an extra formatting has to be performed
1340 : : // to determine the correct positions the floating screen objects.
1341 : : // #i40147#
1342 : : // use new helper class <ExtraFormatToPositionObjs>.
1343 : : // This class additionally keep the locked position of the objects
1344 : : // and releases this position lock keeping on destruction.
1345 : 180 : ExtraFormatToPositionObjs aExtraFormatToPosObjs( *this );
1346 [ - + # # ]: 343 : if ( !bMaximize &&
[ - + ][ + + ]
1347 [ + - ][ + - ]: 163 : GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
[ + - ]
1348 [ # # ][ # # ]: 0 : !GetFmt()->GetBalancedColumns().GetValue() )
1349 : : {
1350 [ # # ]: 0 : aExtraFormatToPosObjs.FormatSectionToPositionObjs();
1351 : : }
1352 : :
1353 : : // Column widths have to be adjusted before calling _CheckClipping.
1354 : : // _CheckClipping can cause the formatting of the lower frames
1355 : : // which still have a width of 0.
1356 [ + + ][ + + ]: 180 : const sal_Bool bHasColumns = Lower() && Lower()->IsColumnFrm();
1357 [ + + ][ + + ]: 180 : if ( bHasColumns && Lower()->GetNext() )
[ + + ]
1358 [ + - ]: 6 : AdjustColumns( 0, sal_False );
1359 : :
1360 [ + - ]: 180 : if( GetUpper() )
1361 : : {
1362 [ + - ][ + - ]: 180 : long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
1363 [ + - ][ + - ]: 180 : (aFrm.*fnRect->fnSetWidth)( nWidth );
1364 : :
1365 : : // #109700# LRSpace for sections
1366 [ + - ][ + - ]: 180 : const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
1367 : 180 : (aPrt.*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() -
1368 [ + - ][ + - ]: 360 : rLRSpace.GetRight() );
1369 : :
1370 : : // OD 15.10.2002 #103517# - allow grow in online layout
1371 : : // Thus, set <..IsBrowseMode()> as parameter <bGrow> on calling
1372 : : // method <_CheckClipping(..)>.
1373 : 180 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
1374 [ - + ][ + - ]: 180 : _CheckClipping( pSh && pSh->GetViewOptions()->getBrowseMode(), bMaximize );
[ + - ]
1375 [ + - ]: 180 : bMaximize = ToMaximize( sal_False );
1376 : 180 : bValidSize = sal_True;
1377 : : }
1378 : :
1379 : : // Check the width of the columns and adjust if necessary
1380 [ + + ][ + + ]: 180 : if ( bHasColumns && ! Lower()->GetNext() && bMaximize )
[ - + ][ - + ]
1381 [ # # ]: 0 : ((SwColumnFrm*)Lower())->Lower()->Calc();
1382 : :
1383 [ + + ]: 180 : if ( !bMaximize )
1384 : : {
1385 [ + - ][ + - ]: 163 : SwTwips nRemaining = (this->*fnRect->fnGetTopMargin)();
1386 : 163 : SwFrm *pFrm = pLower;
1387 [ + + ]: 163 : if( pFrm )
1388 : : {
1389 [ + + ][ + + ]: 149 : if( pFrm->IsColumnFrm() && pFrm->GetNext() )
[ + + ]
1390 : : {
1391 : : // #i61435#
1392 : : // suppress formatting, if upper frame has height <= 0
1393 [ + - ][ + - ]: 6 : if ( (GetUpper()->Frm().*fnRect->fnGetHeight)() > 0 )
[ + - ]
1394 : : {
1395 [ + - ]: 6 : FormatWidthCols( *pAttr, nRemaining, MINLAY );
1396 : : }
1397 : : // #126020# - adjust check for empty section
1398 : : // #130797# - correct fix #126020#
1399 [ - + ][ # # ]: 6 : while( HasFollow() && !GetFollow()->ContainsCntnt() &&
[ # # ][ # # ]
[ - + ]
1400 [ # # ]: 0 : !GetFollow()->ContainsAny( true ) )
1401 : : {
1402 : 0 : SwFrm* pOld = GetFollow();
1403 [ # # ]: 0 : GetFollow()->DelEmpty( sal_False );
1404 [ # # ]: 0 : if( pOld == GetFollow() )
1405 : 0 : break;
1406 : : }
1407 [ + - ]: 6 : bMaximize = ToMaximize( sal_False );
1408 [ + - ][ + - ]: 6 : nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
1409 : : }
1410 : : else
1411 : : {
1412 [ + + ]: 143 : if( pFrm->IsColumnFrm() )
1413 : : {
1414 [ + - ]: 36 : pFrm->Calc();
1415 : 36 : pFrm = ((SwColumnFrm*)pFrm)->Lower();
1416 [ + - ]: 36 : pFrm->Calc();
1417 : 36 : pFrm = ((SwLayoutFrm*)pFrm)->Lower();
1418 [ + - ]: 36 : CalcFtnCntnt();
1419 : : }
1420 : : // If we are in a columned frame which calls a CalcCntnt
1421 : : // in the FormatWidthCols, the content might need calculating
1422 [ + - ][ + + ]: 143 : if( pFrm && !pFrm->IsValid() && IsInFly() &&
[ + - ]
[ - + # # ]
[ - + ]
1423 [ # # ]: 0 : FindFlyFrm()->IsColLocked() )
1424 [ # # ]: 0 : ::CalcCntnt( this );
1425 [ + - ]: 143 : nRemaining += InnerHeight();
1426 : 143 : bMaximize = HasFollow();
1427 : : }
1428 : : }
1429 : :
1430 [ + - ][ + - ]: 163 : SwTwips nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining;
1431 [ + + ]: 163 : if( nDiff < 0)
1432 : : {
1433 [ + - ][ + - ]: 7 : SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1434 : : {
1435 [ + - ][ + - ]: 7 : long nBottom = (Frm().*fnRect->fnGetBottom)();
1436 [ + - ]: 7 : nBottom = (*fnRect->fnYInc)( nBottom, -nDiff );
1437 [ + - ]: 7 : long nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine );
1438 [ + + ]: 7 : if( nTmpDiff > 0 )
1439 : : {
1440 [ + - ]: 3 : nTmpDiff = GetUpper()->Grow( nTmpDiff, sal_True );
1441 [ + - ]: 3 : nDeadLine = (*fnRect->fnYInc)( nDeadLine, nTmpDiff );
1442 [ + - ]: 3 : nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine );
1443 [ + - ]: 3 : if( nTmpDiff > 0 )
1444 : 3 : nDiff += nTmpDiff;
1445 [ - + ]: 3 : if( nDiff > 0 )
1446 : 0 : nDiff = 0;
1447 : : }
1448 : : }
1449 : : }
1450 [ + + ]: 163 : if( nDiff )
1451 : : {
1452 [ + - ][ + - ]: 49 : long nTmp = nRemaining - (Frm().*fnRect->fnGetHeight)();
1453 [ + - ][ + - ]: 49 : long nTop = (this->*fnRect->fnGetTopMargin)();
1454 [ + - ][ + - ]: 49 : (Frm().*fnRect->fnAddBottom)( nTmp );
1455 [ + - ][ + - ]: 49 : (this->*fnRect->fnSetYMargins)( nTop, 0 );
1456 [ + - ]: 49 : InvalidateNextPos();
1457 [ + - ][ + + ]: 49 : if( pLower && ( !pLower->IsColumnFrm() || !pLower->GetNext() ) )
[ + - ][ + - ]
1458 : : {
1459 : : // If a single-column section just created the space that
1460 : : // was requested by the "undersized" paragraphs, then they
1461 : : // have to be invalidated and calculated, so they fully cover it
1462 : 49 : pFrm = pLower;
1463 [ + + ]: 49 : if( pFrm->IsColumnFrm() )
1464 : : {
1465 [ + - ]: 22 : pFrm->_InvalidateSize();
1466 [ + - ]: 22 : pFrm->_InvalidatePos();
1467 [ + - ]: 22 : pFrm->Calc();
1468 : 22 : pFrm = ((SwColumnFrm*)pFrm)->Lower();
1469 [ + - ]: 22 : pFrm->Calc();
1470 : 22 : pFrm = ((SwLayoutFrm*)pFrm)->Lower();
1471 [ + - ]: 22 : CalcFtnCntnt();
1472 : : }
1473 : 49 : sal_Bool bUnderSz = sal_False;
1474 [ + + ]: 98 : while( pFrm )
1475 : : {
1476 [ + - ][ - + ]: 49 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
[ - + ]
1477 : : {
1478 [ # # ]: 0 : pFrm->Prepare( PREP_ADJUST_FRM );
1479 : 0 : bUnderSz = sal_True;
1480 : : }
1481 : 49 : pFrm = pFrm->GetNext();
1482 : : }
1483 [ - + ][ # # ]: 49 : if( bUnderSz && !IsCntntLocked() )
[ - + ]
1484 [ # # ]: 0 : ::CalcCntnt( this );
1485 : : }
1486 : : }
1487 : : }
1488 : :
1489 : : // Do not exceed the lower edge of the Upper.
1490 : : // Do not extend below the lower edge with Sections with Follows
1491 [ + - ]: 180 : if ( GetUpper() )
1492 [ + - ]: 180 : _CheckClipping( sal_True, bMaximize );
1493 [ + - ]: 180 : if( !bOldLock )
1494 : 180 : ColUnlock();
1495 [ + - ][ + - ]: 180 : long nDiff = nOldHeight - (Frm().*fnRect->fnGetHeight)();
1496 [ + + ]: 180 : if( nDiff > 0 )
1497 : : {
1498 [ + + ]: 44 : if( !GetNext() )
1499 : 16 : SetRetouche(); // Take over the retouching ourselves
1500 [ + - ][ + - ]: 44 : if( GetUpper() && !GetUpper()->IsFooterFrm() )
[ + - ]
1501 [ + - ]: 44 : GetUpper()->Shrink( nDiff );
1502 : : }
1503 [ + + ]: 180 : if( IsUndersized() )
1504 [ + - ]: 180 : bValidPrtArea = sal_True;
1505 : : }
1506 : : }
1507 : :
1508 : : /*************************************************************************
1509 : : |*
1510 : : |* SwFrm::GetNextSctLeaf()
1511 : : |*
1512 : : |* Description: Returns the next layout sheet where the frame
1513 : : |* can be moved in.
1514 : : |* New pages are created only if the parameter sal_True is set
1515 : : |*
1516 : : |*************************************************************************/
1517 : :
1518 : :
1519 : 79 : SwLayoutFrm *SwFrm::GetNextSctLeaf( MakePageType eMakePage )
1520 : : {
1521 : : // Attention: Nested sections are currently not supported
1522 : :
1523 : : PROTOCOL_ENTER( this, PROT_LEAF, ACT_NEXT_SECT, GetUpper()->FindSctFrm() )
1524 : :
1525 : : // Shortcuts for "columned" sections, if we're not in the last column
1526 : : // Can we slide to the next column of the section?
1527 [ - + ][ # # ]: 79 : if( IsColBodyFrm() && GetUpper()->GetNext() )
[ - + ]
1528 : 0 : return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetNext())->Lower();
1529 [ + + ][ + + ]: 79 : if( GetUpper()->IsColBodyFrm() && GetUpper()->GetUpper()->GetNext() )
[ + + ]
1530 : 50 : return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetUpper()->GetNext())->Lower();
1531 : : // Inside a section, in tables, or sections of headers/footers, there can be only
1532 : : // one column shift be made, one of the above shortcuts should have applied!
1533 [ + - ][ - + ]: 29 : if( GetUpper()->IsInTab() || FindFooterOrHeader() )
[ - + ]
1534 : 0 : return 0;
1535 : :
1536 : : // Why GetUpper()? This crashes sometimes, because in
1537 : : // FlyAtCnt::MakeFlyPos there is an Orient of the SectionFrm and on this a
1538 : : // GetLeaf is called
1539 : : // SwSectionFrm *pSect = GetUpper()->FindSctFrm();
1540 : 29 : SwSectionFrm *pSect = FindSctFrm();
1541 : 29 : sal_Bool bWrongPage = sal_False;
1542 : : OSL_ENSURE( pSect, "GetNextSctLeaf: Missing SectionFrm" );
1543 : :
1544 : : // Shortcut for sections with Follows. That's ok,
1545 : : // if no columns or pages (except dummy pages) lie in between.
1546 : : // In case of linked frames and in footnotes the shortcut would get
1547 : : // even more costly
1548 [ # # ][ - + ]: 29 : if( pSect->HasFollow() && pSect->IsInDocBody() )
[ - + ]
1549 : : {
1550 [ # # ]: 0 : if( pSect->GetFollow() == pSect->GetNext() )
1551 : : {
1552 : 0 : SwPageFrm *pPg = pSect->GetFollow()->FindPageFrm();
1553 [ # # ]: 0 : if( WrongPageDesc( pPg ) )
1554 : 0 : bWrongPage = sal_True;
1555 : : else
1556 [ # # ][ # # ]: 0 : return FIRSTLEAF( pSect->GetFollow() );
1557 : : }
1558 : : else
1559 : : {
1560 : : SwFrm* pTmp;
1561 [ # # # # ]: 0 : if( !pSect->GetUpper()->IsColBodyFrm() ||
[ # # ]
1562 : 0 : 0 == ( pTmp = pSect->GetUpper()->GetUpper()->GetNext() ) )
1563 : 0 : pTmp = pSect->FindPageFrm()->GetNext();
1564 [ # # ]: 0 : if( pTmp ) // is now the next column or page
1565 : : {
1566 : 0 : SwFrm* pTmpX = pTmp;
1567 [ # # ][ # # ]: 0 : if( pTmp->IsPageFrm() && ((SwPageFrm*)pTmp)->IsEmptyPage() )
[ # # ]
1568 : 0 : pTmp = pTmp->GetNext(); // skip dummy pages
1569 : 0 : SwFrm *pUp = pSect->GetFollow()->GetUpper();
1570 : : // pUp becomes the next column if the Follow lies in a column
1571 : : // that is not a "not first" one, otherwise the page
1572 [ # # ][ # # ]: 0 : if( !pUp->IsColBodyFrm() ||
[ # # ]
1573 : 0 : !( pUp = pUp->GetUpper() )->GetPrev() )
1574 : 0 : pUp = pUp->FindPageFrm();
1575 : : // Now pUp and pTmp have to be the same page/column, otherwise
1576 : : // pages or columns lie between Master and Follow
1577 [ # # ][ # # ]: 0 : if( pUp == pTmp || pUp->GetNext() == pTmpX )
[ # # ]
1578 : : {
1579 : 0 : SwPageFrm* pNxtPg = pUp->IsPageFrm() ?
1580 [ # # ]: 0 : (SwPageFrm*)pUp : pUp->FindPageFrm();
1581 [ # # ]: 0 : if( WrongPageDesc( pNxtPg ) )
1582 : 0 : bWrongPage = sal_True;
1583 : : else
1584 [ # # ][ # # ]: 0 : return FIRSTLEAF( pSect->GetFollow() );
1585 : : }
1586 : : }
1587 : : }
1588 : : }
1589 : :
1590 : : // Always end up in the same section: Body again inside Body etc.
1591 : 29 : const sal_Bool bBody = IsInDocBody();
1592 : 29 : const sal_Bool bFtnPage = FindPageFrm()->IsFtnPage();
1593 : :
1594 : : SwLayoutFrm *pLayLeaf;
1595 : : // A shortcut for TabFrms such that not all cells need to be visited
1596 [ - + ]: 29 : if( bWrongPage )
1597 : 0 : pLayLeaf = 0;
1598 [ - + ]: 29 : else if( IsTabFrm() )
1599 : : {
1600 : 0 : SwCntntFrm* pTmpCnt = ((SwTabFrm*)this)->FindLastCntnt();
1601 [ # # ]: 0 : pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : 0;
1602 : : }
1603 : : else
1604 : : {
1605 : 29 : pLayLeaf = GetNextLayoutLeaf();
1606 [ - + ]: 29 : if( IsColumnFrm() )
1607 : : {
1608 [ # # ][ # # ]: 0 : while( pLayLeaf && ((SwColumnFrm*)this)->IsAnLower( pLayLeaf ) )
[ # # ]
1609 : 0 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1610 : : }
1611 : : }
1612 : :
1613 : 29 : SwLayoutFrm *pOldLayLeaf = 0; // Such that in case of newly
1614 : : // created pages, the search is
1615 : : // not started over at the beginning
1616 : :
1617 : 42 : while( sal_True )
1618 : : {
1619 [ + + ]: 71 : if( pLayLeaf )
1620 : : {
1621 : : // A layout leaf was found, let's see whether it can store me or
1622 : : // another SectionFrm can be inserted here, or we have to continue
1623 : : // searching
1624 : 66 : SwPageFrm* pNxtPg = pLayLeaf->FindPageFrm();
1625 [ - + ][ - + ]: 66 : if ( !bFtnPage && pNxtPg->IsFtnPage() )
[ + - ]
1626 : : { // If I reached the end note pages it's over
1627 : 0 : pLayLeaf = 0;
1628 : 0 : continue;
1629 : : }
1630 : : // Once inBody always inBody, don't step into tables and not into other sections
1631 [ + - ][ + - : 298 : if ( (bBody && !pLayLeaf->IsInDocBody()) ||
+ - + - +
+ - + #
# ][ + + ]
1632 : 66 : (IsInFtn() != pLayLeaf->IsInFtn() ) ||
1633 : 66 : pLayLeaf->IsInTab() ||
1634 : 100 : ( pLayLeaf->IsInSct() && ( !pSect->HasFollow()
1635 : 0 : || pSect->GetFollow() != pLayLeaf->FindSctFrm() ) ) )
1636 : : {
1637 : : // Rejected - try again.
1638 : 34 : pOldLayLeaf = pLayLeaf;
1639 : 34 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1640 : 34 : continue;
1641 : : }
1642 [ + + ]: 32 : if( WrongPageDesc( pNxtPg ) )
1643 : : {
1644 [ - + ]: 3 : if( bWrongPage )
1645 : 0 : break; // there's a column between me and my right page
1646 : 3 : pLayLeaf = 0;
1647 : 3 : bWrongPage = sal_True;
1648 : 3 : pOldLayLeaf = 0;
1649 : 3 : continue;
1650 : : }
1651 : : }
1652 : : // There is no further LayoutFrm that fits, so a new page
1653 : : // has to be created, although new pages are worthless within a frame
1654 [ + - ][ + - ]: 5 : else if( !pSect->IsInFly() &&
[ + - ][ + - ]
1655 : : ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
1656 : : {
1657 : 2 : InsertPage(pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
1658 [ + + ]: 5 : sal_False );
1659 : : // and again the whole thing
1660 [ + + ]: 5 : pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1661 : 5 : continue;
1662 : : }
1663 : 29 : break;
1664 : : }
1665 : :
1666 [ + - ]: 29 : if( pLayLeaf )
1667 : : {
1668 : : // We have found the suitable layout sheet. If there (in the sheet) is
1669 : : // already a Follow of our section, we take its first layout sheet,
1670 : : // otherwise it is time to create a section follow
1671 : : SwSectionFrm* pNew;
1672 : :
1673 : : // This can be omitted if existing Follows were cut short
1674 : 29 : SwFrm* pFirst = pLayLeaf->Lower();
1675 : : // Here SectionFrms that are to be deleted must be ignored
1676 [ + + ][ + + ]: 101 : while( pFirst && pFirst->IsSctFrm() && !((SwSectionFrm*)pFirst)->GetSection() )
[ + + ][ + + ]
1677 : 72 : pFirst = pFirst->GetNext();
1678 [ + + ][ + + ]: 29 : if( pFirst && pFirst->IsSctFrm() && pSect->GetFollow() == pFirst )
[ - + ][ - + ]
1679 : 0 : pNew = pSect->GetFollow();
1680 [ - + ]: 29 : else if( MAKEPAGE_NOSECTION == eMakePage )
1681 : 0 : return pLayLeaf;
1682 : : else
1683 : : {
1684 [ + - ]: 29 : pNew = new SwSectionFrm( *pSect, sal_False );
1685 : 29 : pNew->InsertBefore( pLayLeaf, pLayLeaf->Lower() );
1686 : 29 : pNew->Init();
1687 [ # # ][ # # ]: 29 : SWRECTFN( pNew )
[ - + ][ - + ]
1688 [ + - ]: 29 : (pNew->*fnRect->fnMakePos)( pLayLeaf, NULL, sal_True );
1689 : :
1690 : : // If our section frame has a successor then that has to be
1691 : : // moved behind the new Follow of the section frames
1692 : 29 : SwFrm* pTmp = pSect->GetNext();
1693 [ + - ][ + + ]: 29 : if( pTmp && pTmp != pSect->GetFollow() )
[ + + ]
1694 : : {
1695 : : SwFlowFrm* pNxt;
1696 : 2 : SwCntntFrm* pNxtCntnt = NULL;
1697 [ - + ]: 2 : if( pTmp->IsCntntFrm() )
1698 : : {
1699 [ # # ]: 0 : pNxt = (SwCntntFrm*)pTmp;
1700 : 0 : pNxtCntnt = (SwCntntFrm*)pTmp;
1701 : : }
1702 : : else
1703 : : {
1704 : 2 : pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
1705 [ + - ]: 2 : if( pTmp->IsSctFrm() )
1706 [ + - ]: 2 : pNxt = (SwSectionFrm*)pTmp;
1707 : : else
1708 : : {
1709 : : OSL_ENSURE( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
1710 [ # # ]: 0 : pNxt = (SwTabFrm*)pTmp;
1711 : : }
1712 [ - + ][ # # ]: 2 : while( !pNxtCntnt && 0 != ( pTmp = pTmp->GetNext() ) )
[ - + ]
1713 : : {
1714 [ # # ]: 0 : if( pTmp->IsCntntFrm() )
1715 : 0 : pNxtCntnt = (SwCntntFrm*)pTmp;
1716 : : else
1717 : 0 : pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
1718 : : }
1719 : : }
1720 [ + - ]: 2 : if( pNxtCntnt )
1721 : : {
1722 : 2 : SwFtnBossFrm* pOldBoss = pSect->FindFtnBossFrm( sal_True );
1723 [ - + ]: 2 : if( pOldBoss == pNxtCntnt->FindFtnBossFrm( sal_True ) )
1724 : : {
1725 : : SwSaveFtnHeight aHeight( pOldBoss,
1726 [ # # ]: 0 : pOldBoss->Frm().Top() + pOldBoss->Frm().Height() );
1727 : : pSect->GetUpper()->MoveLowerFtns( pNxtCntnt, pOldBoss,
1728 [ # # ][ # # ]: 0 : pLayLeaf->FindFtnBossFrm( sal_True ), sal_False );
[ # # ]
1729 : : }
1730 : : }
1731 : 2 : ((SwFlowFrm*)pNxt)->MoveSubTree( pLayLeaf, pNew->GetNext() );
1732 : : }
1733 [ - + ]: 29 : if( pNew->GetFollow() )
1734 : 0 : pNew->SimpleFormat();
1735 : : }
1736 : : // The wanted layout sheet is now the first of the determined SctFrms:
1737 [ + + ][ + - ]: 29 : pLayLeaf = FIRSTLEAF( pNew );
1738 : : }
1739 : 79 : return pLayLeaf;
1740 : : }
1741 : :
1742 : : /*************************************************************************
1743 : : |*
1744 : : |* SwFrm::GetPrevSctLeaf()
1745 : : |*
1746 : : |* Description Returns the preceding layout sheet where the frame
1747 : : |* can be moved into
1748 : : |*
1749 : : |*************************************************************************/
1750 : :
1751 : :
1752 : 282 : SwLayoutFrm *SwFrm::GetPrevSctLeaf( MakePageType )
1753 : : {
1754 : : PROTOCOL_ENTER( this, PROT_LEAF, ACT_PREV_SECT, GetUpper()->FindSctFrm() )
1755 : :
1756 : : SwLayoutFrm* pCol;
1757 : : // ColumnFrm always contain a BodyFrm now
1758 [ - + ]: 282 : if( IsColBodyFrm() )
1759 : 0 : pCol = GetUpper();
1760 [ + + ]: 282 : else if( GetUpper()->IsColBodyFrm() )
1761 : 202 : pCol = GetUpper()->GetUpper();
1762 : : else
1763 : 80 : pCol = NULL;
1764 : 282 : sal_Bool bJump = sal_False;
1765 [ + + ]: 282 : if( pCol )
1766 : : {
1767 [ - + ]: 202 : if( pCol->GetPrev() )
1768 : : {
1769 [ # # ]: 0 : do
1770 : : {
1771 : 0 : pCol = (SwLayoutFrm*)pCol->GetPrev();
1772 : : // Is there any content?
1773 : : // Gibt es dort Inhalt?
1774 [ # # ]: 0 : if( ((SwLayoutFrm*)pCol->Lower())->Lower() )
1775 : : {
1776 [ # # ]: 0 : if( bJump ) // Did we skip a blank page?
1777 : 0 : SwFlowFrm::SetMoveBwdJump( sal_True );
1778 : 0 : return (SwLayoutFrm*)pCol->Lower(); // The columnm body
1779 : : }
1780 : 0 : bJump = sal_True;
1781 : 0 : } while( pCol->GetPrev() );
1782 : :
1783 : : // We get here when all columns are empty, pCol is now the
1784 : : // first column, we need the body though
1785 : 0 : pCol = (SwLayoutFrm*)pCol->Lower();
1786 : : }
1787 : : else
1788 : 202 : pCol = NULL;
1789 : : }
1790 : :
1791 [ - + ]: 282 : if( bJump ) // Did we skip a blank page?
1792 : 0 : SwFlowFrm::SetMoveBwdJump( sal_True );
1793 : :
1794 : : // Within sections in tables or section in headers/footers there can
1795 : : // be only one column change be made, one of the above shortcuts should
1796 : : // have applied, also when the section has a pPrev.
1797 : : // Now we even consider an empty column...
1798 : : OSL_ENSURE( FindSctFrm(), "GetNextSctLeaf: Missing SectionFrm" );
1799 [ - + ][ # # ]: 282 : if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() )
[ - + ][ - + ]
1800 : 0 : return pCol;
1801 : :
1802 : : // === IMPORTANT ===
1803 : : // Precondition, which needs to be hold, is that the <this> frame can be
1804 : : // inside a table, but then the found section frame <pSect> is also inside
1805 : : // this table.
1806 : 282 : SwSectionFrm *pSect = FindSctFrm();
1807 : :
1808 : : // #i95698#
1809 : : // A table cell containing directly a section does not break - see lcl_FindSectionsInRow(..)
1810 : : // Thus, a table inside a section, which is inside another table can only
1811 : : // flow backward in the columns of its section.
1812 : : // Note: The table cell, which contains the section, can not have a master table cell.
1813 [ # # ][ - + ]: 282 : if ( IsTabFrm() && pSect->IsInTab() )
[ - + ]
1814 : : {
1815 : 0 : return pCol;
1816 : : }
1817 : :
1818 : : {
1819 : : SwFrm *pPrv;
1820 [ + + ]: 282 : if( 0 != ( pPrv = pSect->GetIndPrev() ) )
1821 : : {
1822 : : // Mooching, half dead SectionFrms shouldn't confuse us
1823 [ + - ][ + + ]: 128 : while( pPrv && pPrv->IsSctFrm() && !((SwSectionFrm*)pPrv)->GetSection() )
[ - + ][ - + ]
1824 : 0 : pPrv = pPrv->GetPrev();
1825 [ + - ]: 128 : if( pPrv )
1826 : 128 : return pCol;
1827 : : }
1828 : : }
1829 : :
1830 : 154 : const sal_Bool bBody = IsInDocBody();
1831 : 154 : const sal_Bool bFly = IsInFly();
1832 : :
1833 : 154 : SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
1834 : 154 : SwLayoutFrm *pPrevLeaf = 0;
1835 : :
1836 [ + + ]: 160 : while ( pLayLeaf )
1837 : : {
1838 : : // Never step into tables or sections
1839 [ + - ][ - + ]: 48 : if ( pLayLeaf->IsInTab() || pLayLeaf->IsInSct() )
[ - + ]
1840 : : {
1841 : 0 : pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1842 : : }
1843 [ + - ][ + + ]: 48 : else if ( bBody && pLayLeaf->IsInDocBody() )
[ + + ]
1844 : : {
1845 : : // If there is a pLayLeaf has a lower pLayLeaf is the frame we are looking for.
1846 : : // Exception: pLayLeaf->Lower() is a zombie section frame
1847 : 42 : const SwFrm* pTmp = pLayLeaf->Lower();
1848 : : // OD 11.04.2003 #108824# - consider, that the zombie section frame
1849 : : // can have frame below it in the found layout leaf.
1850 : : // Thus, skipping zombie section frame, if possible.
1851 [ + - ][ - + : 42 : while ( pTmp && pTmp->IsSctFrm() &&
# # # # ]
[ - + ]
1852 : 0 : !( static_cast<const SwSectionFrm*>(pTmp)->GetSection() ) &&
1853 : 0 : pTmp->GetNext()
1854 : : )
1855 : : {
1856 : 0 : pTmp = pTmp->GetNext();
1857 : : }
1858 [ + - - + : 84 : if ( pTmp &&
# # ][ + - ]
1859 : 42 : ( !pTmp->IsSctFrm() ||
1860 : 0 : ( static_cast<const SwSectionFrm*>(pTmp)->GetSection() )
1861 : : )
1862 : : )
1863 : : {
1864 : 42 : break;
1865 : : }
1866 : 0 : pPrevLeaf = pLayLeaf;
1867 : 0 : pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1868 [ # # ]: 0 : if ( pLayLeaf )
1869 : 0 : SwFlowFrm::SetMoveBwdJump( sal_True );
1870 : : }
1871 [ - + ]: 6 : else if ( bFly )
1872 : 0 : break; // Cntnts in Flys every layout sheet should be right. Why?
1873 : : else
1874 : 6 : pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1875 : : }
1876 [ + + ]: 154 : if( !pLayLeaf )
1877 : : {
1878 [ + - ]: 112 : if( !pPrevLeaf )
1879 : 112 : return pCol;
1880 : 0 : pLayLeaf = pPrevLeaf;
1881 : : }
1882 : :
1883 : 42 : SwSectionFrm* pNew = NULL;
1884 : : // At first go to the end of the layout sheet
1885 : 42 : SwFrm *pTmp = pLayLeaf->Lower();
1886 [ + - ]: 42 : if( pTmp )
1887 : : {
1888 [ + + ]: 252 : while( pTmp->GetNext() )
1889 : 210 : pTmp = pTmp->GetNext();
1890 [ + + ]: 42 : if( pTmp->IsSctFrm() )
1891 : : {
1892 : : // Half dead ones only interfere here
1893 [ - + ]: 28 : while( !((SwSectionFrm*)pTmp)->GetSection() && pTmp->GetPrev() &&
[ # # # # ]
[ - + ]
1894 : 0 : pTmp->GetPrev()->IsSctFrm() )
1895 : 0 : pTmp = pTmp->GetPrev();
1896 [ + + ]: 28 : if( ((SwSectionFrm*)pTmp)->GetFollow() == pSect )
1897 : 26 : pNew = (SwSectionFrm*)pTmp;
1898 : : }
1899 : : }
1900 [ + + ]: 42 : if( !pNew )
1901 : : {
1902 [ + - ]: 16 : pNew = new SwSectionFrm( *pSect, sal_True );
1903 : 16 : pNew->InsertBefore( pLayLeaf, NULL );
1904 : 16 : pNew->Init();
1905 [ # # ][ # # ]: 16 : SWRECTFN( pNew )
[ - + ][ - + ]
1906 [ + - ]: 16 : (pNew->*fnRect->fnMakePos)( pLayLeaf, pNew->GetPrev(), sal_True );
1907 : :
1908 [ + - ][ + + ]: 16 : pLayLeaf = FIRSTLEAF( pNew );
1909 [ + + ]: 16 : if( !pNew->Lower() ) // Format single column sections
1910 : : {
1911 : 14 : pNew->MakePos();
1912 : 14 : pLayLeaf->Format(); // In order that the PrtArea is correct for the MoveBwd
1913 : : }
1914 : : else
1915 : 2 : pNew->SimpleFormat();
1916 : : }
1917 : : else
1918 : : {
1919 [ + - ][ + - ]: 26 : pLayLeaf = FIRSTLEAF( pNew );
1920 [ + - ]: 26 : if( pLayLeaf->IsColBodyFrm() )
1921 : : {
1922 : : // In existent section columns we're looking for the last not empty
1923 : : // column.
1924 : 26 : SwLayoutFrm *pTmpLay = pLayLeaf;
1925 [ + + ]: 76 : while( pLayLeaf->GetUpper()->GetNext() )
1926 : : {
1927 : 50 : pLayLeaf = (SwLayoutFrm*)((SwLayoutFrm*)pLayLeaf->GetUpper()->GetNext())->Lower();
1928 [ - + ]: 50 : if( pLayLeaf->Lower() )
1929 : 0 : pTmpLay = pLayLeaf;
1930 : : }
1931 : : // If we skipped an empty column, we've to set the jump-flag
1932 [ + - ]: 26 : if( pLayLeaf != pTmpLay )
1933 : : {
1934 : 26 : pLayLeaf = pTmpLay;
1935 : 26 : SwFlowFrm::SetMoveBwdJump( sal_True );
1936 : : }
1937 : : }
1938 : : }
1939 : 282 : return pLayLeaf;
1940 : : }
1941 : :
1942 : 276 : SwTwips lcl_DeadLine( const SwFrm* pFrm )
1943 : : {
1944 : 276 : const SwLayoutFrm* pUp = pFrm->GetUpper();
1945 [ + - ][ - + ]: 276 : while( pUp && pUp->IsInSct() )
[ - + ]
1946 : : {
1947 [ # # ]: 0 : if( pUp->IsSctFrm() )
1948 : 0 : pUp = pUp->GetUpper();
1949 : : // Columns now with BodyFrm
1950 [ # # ][ # # ]: 0 : else if( pUp->IsColBodyFrm() && pUp->GetUpper()->GetUpper()->IsSctFrm() )
[ # # ]
1951 : 0 : pUp = pUp->GetUpper()->GetUpper();
1952 : : else
1953 : 0 : break;
1954 : : }
1955 [ - + ][ # # ]: 276 : SWRECTFN( pFrm )
[ # # ][ - + ]
1956 [ + - ]: 276 : return pUp ? (pUp->*fnRect->fnGetPrtBottom)() :
1957 [ + - ][ # # ]: 552 : (pFrm->Frm().*fnRect->fnGetBottom)();
1958 : : }
1959 : : // SwSectionFrm::Growable(..) checks whether the SectionFrm is still able to
1960 : : // grow, as case may be the environment has to be asked
1961 : :
1962 : 49 : sal_Bool SwSectionFrm::Growable() const
1963 : : {
1964 [ - + ][ # # ]: 49 : SWRECTFN( this )
[ # # ][ - + ]
1965 [ + + ]: 49 : if( (*fnRect->fnYDiff)( lcl_DeadLine( this ),
1966 [ + - ]: 49 : (Frm().*fnRect->fnGetBottom)() ) > 0 )
1967 : 46 : return sal_True;
1968 : :
1969 [ + - ][ - + ]: 49 : return ( GetUpper() && ((SwFrm*)GetUpper())->Grow( LONG_MAX, sal_True ) );
1970 : : }
1971 : :
1972 : : /*************************************************************************
1973 : : |*
1974 : : |* SwSectionFrm::_Grow(), _Shrink()
1975 : : |*
1976 : : |*************************************************************************/
1977 : :
1978 : 539 : SwTwips SwSectionFrm::_Grow( SwTwips nDist, sal_Bool bTst )
1979 : : {
1980 [ + + ][ + - ]: 539 : if ( !IsColLocked() && !HasFixSize() )
[ + + ]
1981 : : {
1982 [ - + ][ # # ]: 337 : SWRECTFN( this )
[ # # ][ - + ]
1983 [ + - ]: 337 : long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1984 [ + + ][ + + ]: 337 : if( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
1985 : 20 : nDist = LONG_MAX - nFrmHeight;
1986 : :
1987 [ - + ]: 337 : if ( nDist <= 0L )
1988 : 0 : return 0L;
1989 : :
1990 [ + - ][ - + ]: 337 : sal_Bool bInCalcCntnt = GetUpper() && IsInFly() && FindFlyFrm()->IsLocked();
[ # # ]
1991 : : // OD 2004-03-15 #116561# - allow grow in online layout
1992 : 804 : sal_Bool bGrow = !Lower() || !Lower()->IsColumnFrm() || !Lower()->GetNext() ||
1993 [ - + ][ + + : 804 : GetSection()->GetFmt()->GetBalancedColumns().GetValue();
+ + + + ]
1994 [ + + ]: 337 : if( !bGrow )
1995 : : {
1996 : 106 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
1997 [ - + ][ + - ]: 106 : bGrow = pSh && pSh->GetViewOptions()->getBrowseMode();
1998 : : }
1999 [ + + ]: 337 : if( bGrow )
2000 : : {
2001 : : SwTwips nGrow;
2002 [ + + ]: 231 : if( IsInFtn() )
2003 : 4 : nGrow = 0;
2004 : : else
2005 : : {
2006 : 227 : nGrow = lcl_DeadLine( this );
2007 : : nGrow = (*fnRect->fnYDiff)( nGrow,
2008 [ + - ]: 227 : (Frm().*fnRect->fnGetBottom)() );
2009 : : }
2010 : 231 : SwTwips nSpace = nGrow;
2011 [ + - ][ + + ]: 231 : if( !bInCalcCntnt && nGrow < nDist && GetUpper() )
[ + - ][ + + ]
2012 : 110 : nGrow += GetUpper()->Grow( LONG_MAX, sal_True );
2013 : :
2014 [ + + ]: 231 : if( nGrow > nDist )
2015 : 123 : nGrow = nDist;
2016 [ + + ]: 231 : if( nGrow <= 0 )
2017 : : {
2018 : 37 : nGrow = 0;
2019 [ + - ][ + + ]: 37 : if( nDist && !bTst )
2020 : : {
2021 [ - + ]: 20 : if( bInCalcCntnt )
2022 : 0 : _InvalidateSize();
2023 : : else
2024 : 20 : InvalidateSize();
2025 : : }
2026 : : }
2027 [ + + ]: 194 : else if( !bTst )
2028 : : {
2029 [ - + ]: 131 : if( bInCalcCntnt )
2030 : 0 : _InvalidateSize();
2031 [ + + ][ - + ]: 135 : else if( nSpace < nGrow && nDist != nSpace + GetUpper()->
[ - + ]
2032 : 4 : Grow( nGrow - nSpace, sal_False ) )
2033 : 0 : InvalidateSize();
2034 : : else
2035 : : {
2036 : : const SvxGraphicPosition ePos =
2037 : 131 : GetAttrSet()->GetBackground().GetGraphicPos();
2038 [ + - ][ + + ]: 131 : if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2039 : : {
2040 : 26 : SetCompletePaint();
2041 : 26 : InvalidatePage();
2042 : : }
2043 [ + - ][ - + ]: 131 : if( GetUpper() && GetUpper()->IsHeaderFrm() )
[ - + ]
2044 : 0 : GetUpper()->InvalidateSize();
2045 : : }
2046 [ + - ]: 131 : (Frm().*fnRect->fnAddBottom)( nGrow );
2047 [ + - ]: 131 : long nPrtHeight = (Prt().*fnRect->fnGetHeight)() + nGrow;
2048 [ + - ]: 131 : (Prt().*fnRect->fnSetHeight)( nPrtHeight );
2049 : :
2050 [ + + ][ - + ]: 131 : if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
[ - + ][ + - ]
2051 : : {
2052 : 0 : SwFrm* pTmp = Lower();
2053 [ # # ]: 0 : do
2054 : : {
2055 : 0 : pTmp->_InvalidateSize();
2056 : 0 : pTmp = pTmp->GetNext();
2057 : : } while ( pTmp );
2058 : 0 : _InvalidateSize();
2059 : : }
2060 [ + + ]: 131 : if( GetNext() )
2061 : : {
2062 : 110 : SwFrm *pFrm = GetNext();
2063 [ + - ][ + + ]: 110 : while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
[ - + ][ - + ]
2064 : 0 : pFrm = pFrm->GetNext();
2065 [ + - ]: 110 : if( pFrm )
2066 : : {
2067 [ - + ]: 110 : if( bInCalcCntnt )
2068 : 0 : pFrm->_InvalidatePos();
2069 : : else
2070 : 110 : pFrm->InvalidatePos();
2071 : : }
2072 : : }
2073 : : // #i28701# - Due to the new object positioning
2074 : : // the frame on the next page/column can flow backward (e.g. it
2075 : : // was moved forward due to the positioning of its objects ).
2076 : : // Thus, invalivate this next frame, if document compatibility
2077 : : // option 'Consider wrapping style influence on object positioning' is ON.
2078 [ - + ]: 21 : else if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2079 : : {
2080 : 0 : InvalidateNextPos();
2081 : : }
2082 : : }
2083 : 231 : return nGrow;
2084 : : }
2085 [ + + ]: 106 : if ( !bTst )
2086 : : {
2087 [ - + ]: 54 : if( bInCalcCntnt )
2088 : 0 : _InvalidateSize();
2089 : : else
2090 : 54 : InvalidateSize();
2091 : : }
2092 : : }
2093 : 539 : return 0L;
2094 : : }
2095 : :
2096 : 93 : SwTwips SwSectionFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
2097 : : {
2098 [ + - ][ + + ]: 93 : if ( Lower() && !IsColLocked() && !HasFixSize() )
[ + - ][ + + ]
2099 : : {
2100 [ - + ]: 17 : if( ToMaximize( sal_False ) )
2101 : : {
2102 [ # # ]: 0 : if( !bTst )
2103 : 0 : InvalidateSize();
2104 : : }
2105 : : else
2106 : : {
2107 [ - + ][ # # ]: 17 : SWRECTFN( this )
[ # # ][ - + ]
2108 [ + - ]: 17 : long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2109 [ - + ]: 17 : if ( nDist > nFrmHeight )
2110 : 0 : nDist = nFrmHeight;
2111 : :
2112 [ + + ]: 17 : if ( Lower()->IsColumnFrm() && Lower()->GetNext() && // FtnAtEnd
[ - + # # ]
[ - + ]
2113 : 0 : !GetSection()->GetFmt()->GetBalancedColumns().GetValue() )
2114 : : { // With column bases the format takes over the control of the
2115 : : // growth (because of the balance)
2116 [ # # ]: 0 : if ( !bTst )
2117 : 0 : InvalidateSize();
2118 : 0 : return nDist;
2119 : : }
2120 [ + - ]: 17 : else if( !bTst )
2121 : : {
2122 : : const SvxGraphicPosition ePos =
2123 : 17 : GetAttrSet()->GetBackground().GetGraphicPos();
2124 [ + - ][ + + ]: 17 : if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2125 : : {
2126 : 10 : SetCompletePaint();
2127 : 10 : InvalidatePage();
2128 : : }
2129 [ + - ]: 17 : (Frm().*fnRect->fnAddBottom)( -nDist );
2130 [ + - ]: 17 : long nPrtHeight = (Prt().*fnRect->fnGetHeight)() - nDist;
2131 [ + - ]: 17 : (Prt().*fnRect->fnSetHeight)( nPrtHeight );
2132 : :
2133 : : // We do not allow a section frame to shrink the its upper
2134 : : // footer frame. This is because in the calculation of a
2135 : : // footer frame, the content of the section frame is _not_
2136 : : // calculated. If there is a fly frame overlapping with the
2137 : : // footer frame, the section frame is not affected by this
2138 : : // during the calculation of the footer frame size.
2139 : : // The footer frame does not grow in its FormatSize function
2140 : : // but during the calculation of the content of the section
2141 : : // frame. The section frame grows until some of its text is
2142 : : // located on top of the fly frame. The next call of CalcCntnt
2143 : : // tries to shrink the section and here it would also shrink
2144 : : // the footer. This may not happen, because shrinking the footer
2145 : : // would cause the top of the section frame to overlap with the
2146 : : // fly frame again, this would result in a perfect loop.
2147 [ + - ][ + - ]: 17 : if( GetUpper() && !GetUpper()->IsFooterFrm() )
[ + - ]
2148 : 17 : GetUpper()->Shrink( nDist, bTst );
2149 : :
2150 [ + - ][ + + ]: 17 : if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
[ - + ][ - + ]
2151 : : {
2152 : 0 : SwFrm* pTmp = Lower();
2153 [ # # ]: 0 : do
2154 : : {
2155 : 0 : pTmp->_InvalidateSize();
2156 : 0 : pTmp = pTmp->GetNext();
2157 : : } while ( pTmp );
2158 : : }
2159 [ + + ]: 17 : if( GetNext() )
2160 : : {
2161 : 14 : SwFrm* pFrm = GetNext();
2162 [ + - ][ + + ]: 16 : while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
[ + - ][ + + ]
2163 : 2 : pFrm = pFrm->GetNext();
2164 [ + - ]: 14 : if( pFrm )
2165 : 14 : pFrm->InvalidatePos();
2166 : : else
2167 : 0 : SetRetouche();
2168 : : }
2169 : : else
2170 : 3 : SetRetouche();
2171 : 17 : return nDist;
2172 : : }
2173 : : }
2174 : : }
2175 : 93 : return 0L;
2176 : : }
2177 : :
2178 : : /*************************************************************************
2179 : : |*
2180 : : |* SwSectionFrm::MoveAllowed()
2181 : : |*
2182 : : |* When are Frms within a SectionFrms moveable?
2183 : : |* If they are not in the last column of a SectionFrms yet,
2184 : : |* if there is no Follow,
2185 : : |* if the SectionFrm cannot grow anymore, then it gets more complicated,
2186 : : |* in that case it depends on whether the SectionFrm can find a next
2187 : : |* layout sheet. In (column based/chained) Flys this is checked via
2188 : : |* GetNextLayout, in tables and headers/footers there is none, however in the
2189 : : |* DocBody and in foot notes there is always one.
2190 : : |* This routine is used in the TxtFormatter to decided whether it's allowed to
2191 : : |* create a (paragraph-)Follow or whether the paragraph has to stick together
2192 : : |*
2193 : : |*************************************************************************/
2194 : :
2195 : 227 : sal_Bool SwSectionFrm::MoveAllowed( const SwFrm* pFrm) const
2196 : : {
2197 : : // Is there a Follow or is the Frame not in the last column?
2198 [ + - ]: 421 : if( HasFollow() || ( pFrm->GetUpper()->IsColBodyFrm() &&
[ + + + + ]
[ + + ]
2199 : 194 : pFrm->GetUpper()->GetUpper()->GetNext() ) )
2200 : 126 : return sal_True;
2201 [ - + ]: 101 : if( pFrm->IsInFtn() )
2202 : : {
2203 [ # # ]: 0 : if( IsInFtn() )
2204 : : {
2205 [ # # ]: 0 : if( GetUpper()->IsInSct() )
2206 : : {
2207 [ # # ]: 0 : if( Growable() )
2208 : 0 : return sal_False;
2209 : 0 : return GetUpper()->FindSctFrm()->MoveAllowed( this );
2210 : : }
2211 : : else
2212 : 0 : return sal_True;
2213 : : }
2214 : : // The content of footnote inside a columned sectionfrm is moveable
2215 : : // except in the last column
2216 : 0 : const SwLayoutFrm *pLay = pFrm->FindFtnFrm()->GetUpper()->GetUpper();
2217 [ # # ][ # # ]: 0 : if( pLay->IsColumnFrm() && pLay->GetNext() )
[ # # ]
2218 : : {
2219 : : // The first paragraph in the first footnote in the first column
2220 : : // in the sectionfrm at the top of the page is not moveable,
2221 : : // if the columnbody is empty.
2222 : 0 : sal_Bool bRet = sal_False;
2223 [ # # ]: 0 : if( pLay->GetIndPrev() || pFrm->GetIndPrev() ||
[ # # # # ]
[ # # ]
2224 : 0 : pFrm->FindFtnFrm()->GetPrev() )
2225 : 0 : bRet = sal_True;
2226 : : else
2227 : : {
2228 : 0 : SwLayoutFrm* pBody = ((SwColumnFrm*)pLay)->FindBodyCont();
2229 [ # # ][ # # ]: 0 : if( pBody && pBody->Lower() )
[ # # ]
2230 : 0 : bRet = sal_True;
2231 : : }
2232 [ # # ][ # # ]: 0 : if( bRet && ( IsFtnAtEnd() || !Growable() ) )
[ # # ][ # # ]
2233 : 0 : return sal_True;
2234 : : }
2235 : : }
2236 : : // Or can the section still grow?
2237 [ + + ][ + + ]: 101 : if( !IsColLocked() && Growable() )
[ + + ]
2238 : 46 : return sal_False;
2239 : : // Now it has to be examined whether there is a layout sheet wherein
2240 : : // a section Follow can be created
2241 [ + - ][ - + ]: 55 : if( IsInTab() || ( !IsInDocBody() && FindFooterOrHeader() ) )
[ # # ][ - + ]
2242 : 0 : return sal_False; // It doesn't work in tables/headers/footers
2243 [ - + ]: 55 : if( IsInFly() ) // In column based or chained frames
2244 : 0 : return 0 != ((SwFrm*)GetUpper())->GetNextLeaf( MAKEPAGE_NONE );
2245 : 227 : return sal_True;
2246 : : }
2247 : :
2248 : : /** Called for a frame inside a section with no direct previous frame (or only
2249 : : previous empty section frames) the previous frame of the outer section is
2250 : : returned, if the frame is the first flowing content of this section.
2251 : :
2252 : : Note: For a frame inside a table frame, which is inside a section frame,
2253 : : NULL is returned.
2254 : : */
2255 : 3137 : SwFrm* SwFrm::_GetIndPrev() const
2256 : : {
2257 : 3137 : SwFrm *pRet = NULL;
2258 : : // #i79774#
2259 : : // Do not assert, if the frame has a direct previous frame, because it
2260 : : // could be an empty section frame. The caller has to assure, that the
2261 : : // frame has no direct previous frame or only empty section frames as
2262 : : // previous frames.
2263 : : OSL_ENSURE( /*!pPrev &&*/ IsInSct(), "Why?" );
2264 : 3137 : const SwFrm* pSct = GetUpper();
2265 [ - + ]: 3137 : if( !pSct )
2266 : 0 : return NULL;
2267 [ + + ]: 3137 : if( pSct->IsSctFrm() )
2268 : 867 : pRet = pSct->GetIndPrev();
2269 [ + + ][ + - ]: 2270 : else if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
[ + + ]
2270 : : {
2271 : : // Do not return the previous frame of the outer section, if in one
2272 : : // of the previous columns is content.
2273 : 1242 : const SwFrm* pCol = GetUpper()->GetUpper()->GetPrev();
2274 [ + + ]: 1686 : while( pCol )
2275 : : {
2276 : : OSL_ENSURE( pCol->IsColumnFrm(), "GetIndPrev(): ColumnFrm expected" );
2277 : : OSL_ENSURE( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
2278 : : "GetIndPrev(): Where's the body?");
2279 [ - + ]: 444 : if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
2280 : 0 : return NULL;
2281 : 444 : pCol = pCol->GetPrev();
2282 : : }
2283 : 1242 : pRet = pSct->GetIndPrev();
2284 : : }
2285 : :
2286 : : // skip empty section frames
2287 [ + + ][ + + ]: 3137 : while( pRet && pRet->IsSctFrm() && !((SwSectionFrm*)pRet)->GetSection() )
[ - + ][ - + ]
2288 : 0 : pRet = pRet->GetIndPrev();
2289 : 3137 : return pRet;
2290 : : }
2291 : :
2292 : 1347 : SwFrm* SwFrm::_GetIndNext()
2293 : : {
2294 : : OSL_ENSURE( !pNext && IsInSct(), "Why?" );
2295 : 1347 : SwFrm* pSct = GetUpper();
2296 [ - + ]: 1347 : if( !pSct )
2297 : 0 : return NULL;
2298 [ + + ]: 1347 : if( pSct->IsSctFrm() )
2299 : 528 : return pSct->GetIndNext();
2300 [ + + ][ + - ]: 819 : if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
[ + + ]
2301 : : { // We can only return the successor of the SectionFrms if there is no
2302 : : // content in the successing columns
2303 : 448 : SwFrm* pCol = GetUpper()->GetUpper()->GetNext();
2304 [ + + ]: 1094 : while( pCol )
2305 : : {
2306 : : OSL_ENSURE( pCol->IsColumnFrm(), "GetIndNext(): ColumnFrm expected" );
2307 : : OSL_ENSURE( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
2308 : : "GetIndNext(): Where's the body?");
2309 [ - + ]: 646 : if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
2310 : 0 : return NULL;
2311 : 646 : pCol = pCol->GetNext();
2312 : : }
2313 : 448 : return pSct->GetIndNext();
2314 : : }
2315 : 1347 : return NULL;
2316 : : }
2317 : :
2318 : 0 : sal_Bool SwSectionFrm::IsDescendantFrom( const SwSectionFmt* pFmt ) const
2319 : : {
2320 [ # # ][ # # ]: 0 : if( !pSection || !pFmt )
2321 : 0 : return sal_False;
2322 : 0 : const SwSectionFmt *pMyFmt = pSection->GetFmt();
2323 [ # # ]: 0 : while( pFmt != pMyFmt )
2324 : : {
2325 [ # # ]: 0 : if( pMyFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
2326 : 0 : pMyFmt = (SwSectionFmt*)pMyFmt->GetRegisteredIn();
2327 : : else
2328 : 0 : return sal_False;
2329 : : }
2330 : 0 : return sal_True;
2331 : : }
2332 : :
2333 : 196 : void SwSectionFrm::CalcFtnAtEndFlag()
2334 : : {
2335 : 196 : SwSectionFmt *pFmt = GetSection()->GetFmt();
2336 : 196 : sal_uInt16 nVal = pFmt->GetFtnAtTxtEnd( sal_False ).GetValue();
2337 : 196 : bFtnAtEnd = FTNEND_ATPGORDOCEND != nVal;
2338 : : bOwnFtnNum = FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
2339 [ + + ][ + + ]: 196 : FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
2340 [ + + ][ + - ]: 238 : while( !bFtnAtEnd && !bOwnFtnNum )
[ + + ]
2341 : : {
2342 [ + + ]: 212 : if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
2343 : 42 : pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
2344 : : else
2345 : 170 : break;
2346 : 42 : nVal = pFmt->GetFtnAtTxtEnd( sal_False ).GetValue();
2347 [ + + ]: 42 : if( FTNEND_ATPGORDOCEND != nVal )
2348 : : {
2349 : 4 : bFtnAtEnd = sal_True;
2350 : : bOwnFtnNum = bOwnFtnNum ||FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
2351 [ + - ][ + + ]: 4 : FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
[ - + ]
2352 : : }
2353 : : }
2354 : 196 : }
2355 : :
2356 : 76 : bool SwSectionFrm::IsEndnoteAtMyEnd() const
2357 : : {
2358 : 76 : return pSection->GetFmt()->GetEndAtTxtEnd( sal_False ).IsAtEnd();
2359 : : }
2360 : :
2361 : 206 : void SwSectionFrm::CalcEndAtEndFlag()
2362 : : {
2363 : 206 : SwSectionFmt *pFmt = GetSection()->GetFmt();
2364 : 206 : bEndnAtEnd = pFmt->GetEndAtTxtEnd( sal_False ).IsAtEnd();
2365 [ + + ]: 250 : while( !bEndnAtEnd )
2366 : : {
2367 [ + + ]: 226 : if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
2368 : 44 : pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
2369 : : else
2370 : 182 : break;
2371 : 44 : bEndnAtEnd = pFmt->GetEndAtTxtEnd( sal_False ).IsAtEnd();
2372 : : }
2373 : 206 : }
2374 : :
2375 : : /*************************************************************************
2376 : : |*
2377 : : |* SwSectionFrm::Modify()
2378 : : |*
2379 : : |*************************************************************************/
2380 : :
2381 : 154 : void SwSectionFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
2382 : : {
2383 : 154 : sal_uInt8 nInvFlags = 0;
2384 : :
2385 [ + - ][ + + ]: 154 : if( pNew && RES_ATTRSET_CHG == pNew->Which() )
[ + + ]
2386 : : {
2387 [ + - ]: 56 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
2388 [ + - ]: 56 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
2389 [ + - ]: 56 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
2390 [ + - ]: 56 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
2391 : 12 : while( sal_True )
2392 : : {
2393 : : _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
2394 : : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
2395 [ + - ]: 68 : &aOldSet, &aNewSet );
2396 [ + + ]: 68 : if( aNIter.IsAtEnd() )
2397 : 56 : break;
2398 [ + - ]: 12 : aNIter.NextItem();
2399 [ + - ]: 12 : aOIter.NextItem();
2400 : : }
2401 [ + + ][ - + ]: 56 : if ( aOldSet.Count() || aNewSet.Count() )
[ + + ]
2402 [ + - ][ + - ]: 56 : SwLayoutFrm::Modify( &aOldSet, &aNewSet );
[ + - ][ + - ]
[ + - ]
2403 : : }
2404 : : else
2405 [ + - ]: 98 : _UpdateAttr( pOld, pNew, nInvFlags );
2406 : :
2407 [ + + ]: 154 : if ( nInvFlags != 0 )
2408 : : {
2409 [ + - ]: 38 : if ( nInvFlags & 0x01 )
2410 [ + - ]: 38 : InvalidateSize();
2411 [ + + ]: 38 : if ( nInvFlags & 0x10 )
2412 : 8 : SetCompletePaint();
2413 : : }
2414 : 154 : }
2415 : :
2416 : 18 : void SwSectionFrm::SwClientNotify( const SwModify& rMod, const SfxHint& rHint )
2417 : : {
2418 : : // #i117863#: The hint needs to indicate whether to keep the SwSectionFrm
2419 : : // content or not.
2420 : : const SwSectionFrmMoveAndDeleteHint* pHint =
2421 [ - + ]: 18 : dynamic_cast<const SwSectionFrmMoveAndDeleteHint*>(&rHint);
2422 [ + - ][ + - ]: 18 : if ( pHint && pHint->GetId() == SFX_HINT_DYING && &rMod == GetRegisteredIn() )
[ + - ][ + - ]
2423 : : {
2424 : 18 : SwSectionFrm::MoveCntntAndDelete( this, pHint->IsSaveCntnt() );
2425 : : }
2426 : 18 : }
2427 : :
2428 : 166 : void SwSectionFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
2429 : : sal_uInt8 &rInvFlags,
2430 : : SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2431 : : {
2432 : 166 : sal_Bool bClear = sal_True;
2433 [ + - ][ # # ]: 166 : const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2434 [ + + + + : 166 : switch( nWhich )
+ - + + ]
2435 : : { // Suppress multi columns in foot notes
2436 : : case RES_FMT_CHG:
2437 : : {
2438 : 2 : const SwFmtCol& rNewCol = GetFmt()->GetCol();
2439 [ + - ]: 2 : if( !IsInFtn() )
2440 : : {
2441 : : // Nasty case. When allocating a template we can not count
2442 : : // on the old column attribute. We're left with creating a
2443 : : // temporary attribute here.
2444 [ + - ]: 2 : SwFmtCol aCol;
2445 [ + - ][ - + ]: 2 : if ( Lower() && Lower()->IsColumnFrm() )
[ - + ]
2446 : : {
2447 : 0 : sal_uInt16 nCol = 0;
2448 : 0 : SwFrm *pTmp = Lower();
2449 [ # # ]: 0 : do
2450 : 0 : { ++nCol;
2451 : 0 : pTmp = pTmp->GetNext();
2452 : : } while ( pTmp );
2453 [ # # ]: 0 : aCol.Init( nCol, 0, 1000 );
2454 : : }
2455 : 2 : bool bChgFtn = IsFtnAtEnd();
2456 : 2 : bool const bChgEndn = IsEndnAtEnd();
2457 [ + - ]: 2 : bool const bChgMyEndn = IsEndnoteAtMyEnd();
2458 [ + - ]: 2 : CalcFtnAtEndFlag();
2459 [ + - ]: 2 : CalcEndAtEndFlag();
2460 : 2 : bChgFtn = ( bChgFtn != IsFtnAtEnd() ) ||
2461 : 2 : ( bChgEndn != IsEndnAtEnd() ) ||
2462 [ + - ][ - + ]: 4 : ( bChgMyEndn != IsEndnoteAtMyEnd() );
[ + - + - ]
2463 [ + - ]: 2 : ChgColumns( aCol, rNewCol, bChgFtn );
2464 [ + - ]: 2 : rInvFlags |= 0x10;
2465 : : }
2466 : 2 : rInvFlags |= 0x01;
2467 : 2 : bClear = sal_False;
2468 : : }
2469 : 2 : break;
2470 : :
2471 : : case RES_COL:
2472 [ + - ]: 6 : if( !IsInFtn() )
2473 : : {
2474 : 6 : ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
2475 : 6 : rInvFlags |= 0x11;
2476 : : }
2477 : 6 : break;
2478 : :
2479 : : case RES_FTN_AT_TXTEND:
2480 [ + - ]: 32 : if( !IsInFtn() )
2481 : : {
2482 : 32 : bool const bOld = IsFtnAtEnd();
2483 : 32 : CalcFtnAtEndFlag();
2484 [ + + ]: 32 : if (bOld != IsFtnAtEnd())
2485 : : {
2486 : 10 : const SwFmtCol& rNewCol = GetFmt()->GetCol();
2487 : 10 : ChgColumns( rNewCol, rNewCol, sal_True );
2488 : 10 : rInvFlags |= 0x01;
2489 : : }
2490 : : }
2491 : 32 : break;
2492 : :
2493 : : case RES_END_AT_TXTEND:
2494 [ + - ]: 42 : if( !IsInFtn() )
2495 : : {
2496 : 42 : bool const bOld = IsEndnAtEnd();
2497 : 42 : bool const bMyOld = IsEndnoteAtMyEnd();
2498 : 42 : CalcEndAtEndFlag();
2499 [ - + ][ + + ]: 42 : if (bOld != IsEndnAtEnd() || bMyOld != IsEndnoteAtMyEnd())
[ + + ]
2500 : : {
2501 : 12 : const SwFmtCol& rNewCol = GetFmt()->GetCol();
2502 : 12 : ChgColumns( rNewCol, rNewCol, sal_True );
2503 : 12 : rInvFlags |= 0x01;
2504 : : }
2505 : : }
2506 : 42 : break;
2507 : : case RES_COLUMNBALANCE:
2508 : 8 : rInvFlags |= 0x01;
2509 : 8 : break;
2510 : :
2511 : : case RES_FRAMEDIR :
2512 : 0 : SetDerivedR2L( sal_False );
2513 : 0 : CheckDirChange();
2514 : 0 : break;
2515 : :
2516 : : case RES_PROTECT:
2517 : : {
2518 : 4 : ViewShell *pSh = getRootFrm()->GetCurrShell();
2519 [ - + ][ - + ]: 4 : if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
[ + - ]
2520 : 0 : pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this );
2521 : : }
2522 : 4 : break;
2523 : :
2524 : : default:
2525 : 72 : bClear = sal_False;
2526 : : }
2527 [ + + ]: 166 : if ( bClear )
2528 : : {
2529 [ + + ][ - + ]: 92 : if ( pOldSet || pNewSet )
2530 : : {
2531 [ + - ]: 14 : if ( pOldSet )
2532 : 14 : pOldSet->ClearItem( nWhich );
2533 [ + - ]: 28 : if ( pNewSet )
2534 : 14 : pNewSet->ClearItem( nWhich );
2535 : : }
2536 : : else
2537 : 92 : SwLayoutFrm::Modify( pOld, pNew );
2538 : : }
2539 : 166 : }
2540 : :
2541 : : /*--------------------------------------------------
2542 : : * SwSectionFrm::ToMaximize(..): A follow or a ftncontainer at the end of the
2543 : : * page causes a maximal Size of the sectionframe.
2544 : : * --------------------------------------------------*/
2545 : :
2546 : 666 : sal_Bool SwSectionFrm::ToMaximize( sal_Bool bCheckFollow ) const
2547 : : {
2548 [ + + ]: 666 : if( HasFollow() )
2549 : : {
2550 [ + + ]: 60 : if( !bCheckFollow ) // Don't check superfluous follows
2551 : 34 : return sal_True;
2552 : 26 : const SwSectionFrm* pFoll = GetFollow();
2553 [ + - ][ - + ]: 26 : while( pFoll && pFoll->IsSuperfluous() )
[ - + ]
2554 : 0 : pFoll = pFoll->GetFollow();
2555 [ + - ]: 26 : if( pFoll )
2556 : 26 : return sal_True;
2557 : : }
2558 [ + + ]: 606 : if( IsFtnAtEnd() )
2559 : 68 : return sal_False;
2560 : 538 : const SwFtnContFrm* pCont = ContainsFtnCont();
2561 [ + + ]: 538 : if( !IsEndnAtEnd() )
2562 : 510 : return 0 != pCont;
2563 : 28 : sal_Bool bRet = sal_False;
2564 [ - + ][ # # ]: 28 : while( pCont && !bRet )
[ - + ]
2565 : : {
2566 [ # # ]: 0 : if( pCont->FindFootNote() )
2567 : 0 : bRet = sal_True;
2568 : : else
2569 : 0 : pCont = ContainsFtnCont( pCont );
2570 : : }
2571 : 666 : return bRet;
2572 : : }
2573 : :
2574 : : /*--------------------------------------------------
2575 : : * sal_Bool SwSectionFrm::ContainsFtnCont()
2576 : : * checks every Column for FtnContFrms.
2577 : : * --------------------------------------------------*/
2578 : :
2579 : 776 : SwFtnContFrm* SwSectionFrm::ContainsFtnCont( const SwFtnContFrm* pCont ) const
2580 : : {
2581 : 776 : SwFtnContFrm* pRet = NULL;
2582 : : const SwLayoutFrm* pLay;
2583 [ - + ]: 776 : if( pCont )
2584 : : {
2585 : 0 : pLay = pCont->FindFtnBossFrm( 0 );
2586 : : OSL_ENSURE( IsAnLower( pLay ), "ConatainsFtnCont: Wrong FtnContainer" );
2587 : 0 : pLay = (SwLayoutFrm*)pLay->GetNext();
2588 : : }
2589 [ + + ][ + + ]: 776 : else if( Lower() && Lower()->IsColumnFrm() )
[ + + ]
2590 : 312 : pLay = (SwLayoutFrm*)Lower();
2591 : : else
2592 : 464 : pLay = NULL;
2593 [ + - ][ + + ]: 1538 : while ( !pRet && pLay )
[ + + ]
2594 : : {
2595 [ + - ][ - + ]: 762 : if( pLay->Lower() && pLay->Lower()->GetNext() )
[ - + ]
2596 : : {
2597 : : OSL_ENSURE( pLay->Lower()->GetNext()->IsFtnContFrm(),
2598 : : "ToMaximize: Unexspected Frame" );
2599 : 0 : pRet = (SwFtnContFrm*)pLay->Lower()->GetNext();
2600 : : }
2601 : : OSL_ENSURE( !pLay->GetNext() || pLay->GetNext()->IsLayoutFrm(),
2602 : : "ToMaximize: ColFrm exspected" );
2603 : 762 : pLay = (SwLayoutFrm*)pLay->GetNext();
2604 : : }
2605 : 776 : return pRet;
2606 : : }
2607 : :
2608 : 30 : void SwSectionFrm::InvalidateFtnPos()
2609 : : {
2610 : 30 : SwFtnContFrm* pCont = ContainsFtnCont( NULL );
2611 [ - + ]: 30 : if( pCont )
2612 : : {
2613 : 0 : SwFrm *pTmp = pCont->ContainsCntnt();
2614 [ # # ]: 0 : if( pTmp )
2615 : 0 : pTmp->_InvalidatePos();
2616 : : }
2617 : 30 : }
2618 : :
2619 : : /*--------------------------------------------------
2620 : : * SwSectionFrm::Undersize() returns the value that the section
2621 : : * would like to be greater if it has undersized TxtFrms in it,
2622 : : * otherwise Null..
2623 : : * If necessary the undersized-flag is corrected.
2624 : : * --------------------------------------------------*/
2625 : :
2626 : 163 : long SwSectionFrm::Undersize( sal_Bool bOverSize )
2627 : : {
2628 : 163 : bUndersized = sal_False;
2629 [ - + ][ # # ]: 163 : SWRECTFN( this )
[ # # ][ - + ]
2630 [ + - ]: 163 : long nRet = InnerHeight() - (Prt().*fnRect->fnGetHeight)();
2631 [ - + ]: 163 : if( nRet > 0 )
2632 : 0 : bUndersized = sal_True;
2633 [ + - ]: 163 : else if( !bOverSize )
2634 : 163 : nRet = 0;
2635 : 163 : return nRet;
2636 : : }
2637 : :
2638 : : /// OD 01.04.2003 #108446# - determine next frame for footnote/endnote formatting
2639 : : /// before format of current one, because current one can move backward.
2640 : : /// After moving backward to a previous page method <FindNext()> will return
2641 : : /// the text frame presenting the first page footnote, if it exists. Thus, the
2642 : : /// rest of the footnote/endnote container would not be formatted.
2643 : 192 : void SwSectionFrm::CalcFtnCntnt()
2644 : : {
2645 : 192 : SwFtnContFrm* pCont = ContainsFtnCont();
2646 [ - + ]: 192 : if( pCont )
2647 : : {
2648 : 0 : SwFrm* pFrm = pCont->ContainsAny();
2649 [ # # ]: 0 : if( pFrm )
2650 : 0 : pCont->Calc();
2651 [ # # ][ # # ]: 0 : while( pFrm && IsAnLower( pFrm ) )
[ # # ]
2652 : : {
2653 : 0 : SwFtnFrm* pFtn = pFrm->FindFtnFrm();
2654 [ # # ]: 0 : if( pFtn )
2655 : 0 : pFtn->Calc();
2656 : : // OD 01.04.2003 #108446# - determine next frame before format current frame.
2657 : 0 : SwFrm* pNextFrm = 0;
2658 : : {
2659 [ # # ]: 0 : if( pFrm->IsSctFrm() )
2660 : : {
2661 : 0 : pNextFrm = static_cast<SwSectionFrm*>(pFrm)->ContainsAny();
2662 : : }
2663 [ # # ]: 0 : if( !pNextFrm )
2664 : : {
2665 : 0 : pNextFrm = pFrm->FindNext();
2666 : : }
2667 : : }
2668 : 0 : pFrm->Calc();
2669 : 0 : pFrm = pNextFrm;
2670 : : }
2671 : : }
2672 : 192 : }
2673 : : /* --------------------------------------------------
2674 : : * If a SectionFrm gets empty, e.g. because its content changes the page/column,
2675 : : * it is not destroyed immediately (there could be a pointer left to it on the
2676 : : * stack), instead it puts itself in a list at the RootFrm, which is processed
2677 : : * later on (in Layaction::Action among others). Its size is set to Null and
2678 : : * the pointer to its page as well. Such SectionFrms that are to be deleted
2679 : : * must be ignored by the layout/during formatting.
2680 : : *
2681 : : * With InsertEmptySct the RootFrm stores a SectionFrm in the list,
2682 : : * with RemoveFromList it can be removed from the list (Dtor),
2683 : : * with DeleteEmptySct the list is processed and the SectionFrms are destroyed.
2684 : : * --------------------------------------------------*/
2685 : :
2686 : 60 : void SwRootFrm::InsertEmptySct( SwSectionFrm* pDel )
2687 : : {
2688 [ + + ]: 60 : if( !pDestroy )
2689 [ + - ]: 4 : pDestroy = new SwDestroyList;
2690 : 60 : pDestroy->insert( pDel );
2691 : 60 : }
2692 : :
2693 : 280 : void SwRootFrm::_DeleteEmptySct()
2694 : : {
2695 : : OSL_ENSURE( pDestroy, "Keine Liste, keine Kekse" );
2696 [ + + ]: 338 : while( !pDestroy->empty() )
2697 : : {
2698 : 58 : SwSectionFrm* pSect = *pDestroy->begin();
2699 : 58 : pDestroy->erase( pDestroy->begin() );
2700 : : OSL_ENSURE( !pSect->IsColLocked() && !pSect->IsJoinLocked(),
2701 : : "DeleteEmptySct: Locked SectionFrm" );
2702 [ + - ][ + - ]: 58 : if( !pSect->Frm().HasArea() && !pSect->ContainsCntnt() )
[ + - ]
2703 : : {
2704 : 58 : SwLayoutFrm* pUp = pSect->GetUpper();
2705 : 58 : pSect->Remove();
2706 [ + - ]: 58 : delete pSect;
2707 [ + - ][ + + ]: 58 : if( pUp && !pUp->Lower() )
[ + + ]
2708 : : {
2709 [ + - ]: 2 : if( pUp->IsPageBodyFrm() )
2710 : 2 : pUp->getRootFrm()->SetSuperfluous();
2711 [ # # ]: 0 : else if( pUp->IsFtnFrm() && !pUp->IsColLocked() &&
[ # # # # ]
[ # # ]
2712 : 0 : pUp->GetUpper() )
2713 : : {
2714 : 0 : pUp->Cut();
2715 [ # # ]: 0 : delete pUp;
2716 : : }
2717 : : }
2718 : : }
2719 : : else {
2720 : : OSL_ENSURE( pSect->GetSection(), "DeleteEmptySct: Halbtoter SectionFrm?!" );
2721 : : }
2722 : : }
2723 : 280 : }
2724 : :
2725 : 64 : void SwRootFrm::_RemoveFromList( SwSectionFrm* pSct )
2726 : : {
2727 : : OSL_ENSURE( pDestroy, "Where's my list?" );
2728 : 64 : pDestroy->erase( pSct );
2729 : 64 : }
2730 : :
2731 : : #ifdef DBG_UTIL
2732 : : bool SwRootFrm::IsInDelList( SwSectionFrm* pSct ) const
2733 : : {
2734 : : return pDestroy && pDestroy->find( pSct ) != pDestroy->end();
2735 : : }
2736 : : #endif
2737 : :
2738 : 0 : bool SwSectionFrm::IsBalancedSection() const
2739 : : {
2740 : 0 : bool bRet = false;
2741 [ # # ][ # # ]: 0 : if ( GetSection() && Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
[ # # ][ # # ]
[ # # ]
2742 : : {
2743 : 0 : bRet = !GetSection()->GetFmt()->GetBalancedColumns().GetValue();
2744 : : }
2745 : 0 : return bRet;
2746 : : }
2747 : :
2748 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|