Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <hintids.hxx>
22 : #include <hints.hxx>
23 : #include <vcl/outdev.hxx>
24 : #include <svl/itemiter.hxx>
25 : #include <editeng/brushitem.hxx>
26 : #include <editeng/keepitem.hxx>
27 : #include <editeng/formatbreakitem.hxx>
28 : #include <fmtornt.hxx>
29 : #include <pagefrm.hxx>
30 : #include <section.hxx>
31 : #include <rootfrm.hxx>
32 : #include <cntfrm.hxx>
33 : #include <dcontact.hxx>
34 : #include <anchoreddrawobject.hxx>
35 : #include <fmtanchr.hxx>
36 : #include <viewsh.hxx>
37 : #include <viewimp.hxx>
38 : #include "viewopt.hxx"
39 : #include <doc.hxx>
40 : #include <fesh.hxx>
41 : #include <docsh.hxx>
42 : #include <flyfrm.hxx>
43 : #include <frmtool.hxx>
44 : #include <ftninfo.hxx>
45 : #include <dflyobj.hxx>
46 : #include <fmtclbl.hxx>
47 : #include <fmtfordr.hxx>
48 : #include <fmtfsize.hxx>
49 : #include <fmtpdsc.hxx>
50 : #include <txtftn.hxx>
51 : #include <fmtftn.hxx>
52 : #include <fmtsrnd.hxx>
53 : #include <ftnfrm.hxx>
54 : #include <tabfrm.hxx>
55 : #include <htmltbl.hxx>
56 : #include <flyfrms.hxx>
57 : #include <sectfrm.hxx>
58 : #include <fmtclds.hxx>
59 : #include <txtfrm.hxx>
60 : #include <ndtxt.hxx>
61 : #include <bodyfrm.hxx>
62 : #include <cellfrm.hxx>
63 : #include <dbg_lay.hxx>
64 : #include <editeng/frmdiritem.hxx>
65 : // OD 2004-05-24 #i28701#
66 : #include <sortedobjs.hxx>
67 : #include <viewopt.hxx>
68 :
69 :
70 : using namespace ::com::sun::star;
71 :
72 :
73 : /*************************************************************************
74 : |*
75 : |* SwFrm::SwFrm()
76 : |*
77 : |*************************************************************************/
78 :
79 10089 : SwFrm::SwFrm( SwModify *pMod, SwFrm* pSib ) :
80 : SwClient( pMod ),
81 : // #i65250#
82 : mnFrmId( SwFrm::mnLastFrmId++ ),
83 : mpRoot( pSib ? pSib->getRootFrm() : 0 ),
84 : mpUpper( 0 ),
85 : mpNext( 0 ),
86 : mpPrev( 0 ),
87 : mpDrawObjs( 0 ),
88 : mnType(0),
89 : mbInfBody( sal_False ),
90 : mbInfTab ( sal_False ),
91 : mbInfFly ( sal_False ),
92 : mbInfFtn ( sal_False ),
93 10089 : mbInfSct ( sal_False )
94 : {
95 : OSL_ENSURE( pMod, "No frame format given." );
96 10089 : mbInvalidR2L = mbInvalidVert = 1;
97 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
98 10089 : mbDerivedR2L = mbDerivedVert = mbRightToLeft = mbVertical = mbReverse = mbVertLR = 0;
99 :
100 : mbValidPos = mbValidPrtArea = mbValidSize = mbValidLineNum = mbRetouche =
101 10089 : mbFixSize = mbColLocked = sal_False;
102 10089 : mbCompletePaint = mbInfInvalid = sal_True;
103 10089 : }
104 :
105 237 : const IDocumentDrawModelAccess* SwFrm::getIDocumentDrawModelAccess()
106 : {
107 237 : return GetUpper()->GetFmt()->getIDocumentDrawModelAccess();
108 : }
109 :
110 0 : bool SwFrm::KnowsFormat( const SwFmt& rFmt ) const
111 : {
112 0 : return GetRegisteredIn() == &rFmt;
113 : }
114 :
115 47 : void SwFrm::RegisterToFormat( SwFmt& rFmt )
116 : {
117 47 : rFmt.Add( this );
118 47 : }
119 :
120 6743 : void SwFrm::CheckDir( sal_uInt16 nDir, sal_Bool bVert, sal_Bool bOnlyBiDi, sal_Bool bBrowse )
121 : {
122 6743 : if( FRMDIR_ENVIRONMENT == nDir || ( bVert && bOnlyBiDi ) )
123 : {
124 4199 : mbDerivedVert = 1;
125 4199 : if( FRMDIR_ENVIRONMENT == nDir )
126 2368 : mbDerivedR2L = 1;
127 4199 : SetDirFlags( bVert );
128 : }
129 2544 : else if( bVert )
130 : {
131 310 : mbInvalidVert = 0;
132 310 : if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir
133 1 : || bBrowse )
134 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
135 : {
136 309 : mbVertical = 0;
137 309 : mbVertLR = 0;
138 : }
139 : else
140 : {
141 1 : mbVertical = 1;
142 1 : if(FRMDIR_VERT_TOP_RIGHT == nDir)
143 1 : mbVertLR = 0;
144 0 : else if(FRMDIR_VERT_TOP_LEFT==nDir)
145 0 : mbVertLR = 1;
146 : }
147 : }
148 : else
149 : {
150 2234 : mbInvalidR2L = 0;
151 2234 : if( FRMDIR_HORI_RIGHT_TOP == nDir )
152 4 : mbRightToLeft = 1;
153 : else
154 2230 : mbRightToLeft = 0;
155 : }
156 6743 : }
157 :
158 32092 : void SwFrm::CheckDirection( sal_Bool bVert )
159 : {
160 32092 : if( bVert )
161 : {
162 29556 : if( !IsHeaderFrm() && !IsFooterFrm() )
163 : {
164 3014 : mbDerivedVert = 1;
165 3014 : SetDirFlags( bVert );
166 : }
167 : }
168 : else
169 : {
170 2536 : mbDerivedR2L = 1;
171 2536 : SetDirFlags( bVert );
172 : }
173 32092 : }
174 :
175 132 : void SwSectionFrm::CheckDirection( sal_Bool bVert )
176 : {
177 132 : const SwFrmFmt* pFmt = GetFmt();
178 132 : if( pFmt )
179 : {
180 132 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
181 132 : const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
182 132 : CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
183 264 : bVert, sal_True, bBrowseMode );
184 : }
185 : else
186 0 : SwFrm::CheckDirection( bVert );
187 132 : }
188 :
189 2 : void SwFlyFrm::CheckDirection( sal_Bool bVert )
190 : {
191 2 : const SwFrmFmt* pFmt = GetFmt();
192 2 : if( pFmt )
193 : {
194 2 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
195 2 : const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
196 2 : CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
197 4 : bVert, sal_False, bBrowseMode );
198 : }
199 : else
200 0 : SwFrm::CheckDirection( bVert );
201 2 : }
202 :
203 265 : void SwTabFrm::CheckDirection( sal_Bool bVert )
204 : {
205 265 : const SwFrmFmt* pFmt = GetFmt();
206 265 : if( pFmt )
207 : {
208 265 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
209 265 : const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
210 265 : CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
211 530 : bVert, sal_True, bBrowseMode );
212 : }
213 : else
214 0 : SwFrm::CheckDirection( bVert );
215 265 : }
216 :
217 3021 : void SwCellFrm::CheckDirection( sal_Bool bVert )
218 : {
219 3021 : const SwFrmFmt* pFmt = GetFmt();
220 : const SfxPoolItem* pItem;
221 : // Check if the item is set, before actually
222 : // using it. Otherwise the dynamic pool default is used, which may be set
223 : // to LTR in case of OOo 1.0 documents.
224 3021 : if( pFmt && SFX_ITEM_SET == pFmt->GetItemState( RES_FRAMEDIR, sal_True, &pItem ) )
225 : {
226 618 : const SvxFrameDirectionItem* pFrmDirItem = static_cast<const SvxFrameDirectionItem*>(pItem);
227 618 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
228 618 : const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
229 618 : CheckDir( pFrmDirItem->GetValue(), bVert, sal_False, bBrowseMode );
230 : }
231 : else
232 2403 : SwFrm::CheckDirection( bVert );
233 3021 : }
234 :
235 5726 : void SwTxtFrm::CheckDirection( sal_Bool bVert )
236 : {
237 5726 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
238 5726 : const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
239 5726 : CheckDir( GetTxtNode()->GetSwAttrSet().GetFrmDir().GetValue(), bVert,
240 11452 : sal_True, bBrowseMode );
241 5726 : }
242 :
243 : /*************************************************************************/
244 2375 : void SwFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
245 : {
246 2375 : sal_uInt8 nInvFlags = 0;
247 :
248 2375 : if( pNew && RES_ATTRSET_CHG == pNew->Which() )
249 : {
250 1397 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
251 2794 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
252 : while( true )
253 : {
254 : _UpdateAttrFrm( (SfxPoolItem*)aOIter.GetCurItem(),
255 1486 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags );
256 1486 : if( aNIter.IsAtEnd() )
257 1397 : break;
258 89 : aNIter.NextItem();
259 89 : aOIter.NextItem();
260 1397 : }
261 : }
262 : else
263 978 : _UpdateAttrFrm( pOld, pNew, nInvFlags );
264 :
265 2375 : if ( nInvFlags != 0 )
266 : {
267 1049 : SwPageFrm *pPage = FindPageFrm();
268 1049 : InvalidatePage( pPage );
269 1049 : if ( nInvFlags & 0x01 )
270 : {
271 1006 : _InvalidatePrt();
272 1006 : if( !GetPrev() && IsTabFrm() && IsInSct() )
273 0 : FindSctFrm()->_InvalidatePrt();
274 : }
275 1049 : if ( nInvFlags & 0x02 )
276 1006 : _InvalidateSize();
277 1049 : if ( nInvFlags & 0x04 )
278 838 : _InvalidatePos();
279 1049 : if ( nInvFlags & 0x08 )
280 1036 : SetCompletePaint();
281 : SwFrm *pNxt;
282 1049 : if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) )
283 : {
284 45 : pNxt->InvalidatePage( pPage );
285 45 : if ( nInvFlags & 0x10 )
286 10 : pNxt->_InvalidatePos();
287 45 : if ( nInvFlags & 0x20 )
288 35 : pNxt->SetCompletePaint();
289 : }
290 : }
291 2375 : }
292 :
293 2464 : void SwFrm::_UpdateAttrFrm( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
294 : sal_uInt8 &rInvFlags )
295 : {
296 2464 : sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
297 2464 : switch( nWhich )
298 : {
299 : case RES_BOX:
300 : case RES_SHADOW:
301 25 : Prepare( PREP_FIXSIZE_CHG );
302 : // no break here!
303 : case RES_LR_SPACE:
304 : case RES_UL_SPACE:
305 158 : rInvFlags |= 0x0B;
306 158 : break;
307 :
308 : case RES_HEADER_FOOTER_EAT_SPACING:
309 0 : rInvFlags |= 0x03;
310 0 : break;
311 :
312 : case RES_BACKGROUND:
313 : case RES_FILL_STYLE:
314 : case RES_FILL_GRADIENT:
315 42 : rInvFlags |= 0x28;
316 42 : break;
317 :
318 : case RES_KEEP:
319 1 : rInvFlags |= 0x04;
320 1 : break;
321 :
322 : case RES_FRM_SIZE:
323 12 : ReinitializeFrmSizeAttrFlags();
324 12 : rInvFlags |= 0x13;
325 12 : break;
326 :
327 : case RES_FMT_CHG:
328 837 : rInvFlags |= 0x0F;
329 837 : break;
330 :
331 : case RES_ROW_SPLIT:
332 : {
333 1 : if ( IsRowFrm() )
334 : {
335 1 : bool bInFollowFlowRow = 0 != IsInFollowFlowRow();
336 1 : if ( bInFollowFlowRow || 0 != IsInSplitTableRow() )
337 : {
338 0 : SwTabFrm* pTab = FindTabFrm();
339 0 : if ( bInFollowFlowRow )
340 0 : pTab = pTab->FindMaster();
341 0 : pTab->SetRemoveFollowFlowLinePending( sal_True );
342 : }
343 : }
344 1 : break;
345 : }
346 : case RES_COL:
347 : OSL_FAIL( "Columns for new FrmTyp?" );
348 0 : break;
349 :
350 : default:
351 : /* do Nothing */;
352 : }
353 2464 : }
354 :
355 : /*************************************************************************
356 : |*
357 : |* SwFrm::Prepare()
358 : |*
359 : |*************************************************************************/
360 61 : void SwFrm::Prepare( const PrepareHint, const void *, sal_Bool )
361 : {
362 : /* Do nothing */
363 61 : }
364 :
365 : /**
366 : * Invalidates the page in which the Frm is currently placed.
367 : * The page is invalidated depending on the type (Layout, Cntnt, FlyFrm)
368 : */
369 36138 : void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const
370 : {
371 36138 : if ( !pPage )
372 : {
373 28454 : pPage = FindPageFrm();
374 : // #i28701# - for at-character and as-character
375 : // anchored Writer fly frames additionally invalidate also page frame
376 : // its 'anchor character' is on.
377 28454 : if ( pPage && pPage->GetUpper() && IsFlyFrm() )
378 : {
379 902 : const SwFlyFrm* pFlyFrm = static_cast<const SwFlyFrm*>(this);
380 902 : if ( pFlyFrm->IsAutoPos() || pFlyFrm->IsFlyInCntFrm() )
381 : {
382 : // #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
383 : // is replaced by method <FindPageFrmOfAnchor()>. It's return value
384 : // have to be checked.
385 : SwPageFrm* pPageFrmOfAnchor =
386 663 : const_cast<SwFlyFrm*>(pFlyFrm)->FindPageFrmOfAnchor();
387 663 : if ( pPageFrmOfAnchor && pPageFrmOfAnchor != pPage )
388 : {
389 0 : InvalidatePage( pPageFrmOfAnchor );
390 : }
391 : }
392 : }
393 : }
394 :
395 36138 : if ( pPage && pPage->GetUpper() )
396 : {
397 31978 : if ( pPage->GetFmt()->GetDoc()->IsInDtor() )
398 36138 : return;
399 :
400 31978 : SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
401 31978 : const SwFlyFrm *pFly = FindFlyFrm();
402 31978 : if ( IsCntntFrm() )
403 : {
404 21631 : if ( pRoot->IsTurboAllowed() )
405 : {
406 : // If a ContentFrame wants to register for a second time, make it a TurboAction.
407 5714 : if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
408 5120 : pRoot->SetTurbo( (const SwCntntFrm*)this );
409 : else
410 : {
411 594 : pRoot->DisallowTurbo();
412 : //The page of the Turbo could be a different one then mine,
413 : //therefore we have to invalidate it.
414 594 : const SwFrm *pTmp = pRoot->GetTurbo();
415 594 : pRoot->ResetTurbo();
416 594 : pTmp->InvalidatePage();
417 : }
418 : }
419 21631 : if ( !pRoot->GetTurbo() )
420 : {
421 16495 : if ( pFly )
422 1078 : { if( !pFly->IsLocked() )
423 : {
424 1078 : if ( pFly->IsFlyInCntFrm() )
425 410 : { pPage->InvalidateFlyInCnt();
426 410 : ((SwFlyInCntFrm*)pFly)->InvalidateCntnt();
427 410 : pFly->GetAnchorFrm()->InvalidatePage();
428 : }
429 : else
430 668 : pPage->InvalidateFlyCntnt();
431 : }
432 : }
433 : else
434 15417 : pPage->InvalidateCntnt();
435 : }
436 : }
437 : else
438 : {
439 10347 : pRoot->DisallowTurbo();
440 10347 : if ( pFly )
441 : {
442 1470 : if ( !pFly->IsLocked() )
443 : {
444 1427 : if ( pFly->IsFlyInCntFrm() )
445 : {
446 517 : pPage->InvalidateFlyInCnt();
447 517 : ((SwFlyInCntFrm*)pFly)->InvalidateLayout();
448 517 : pFly->GetAnchorFrm()->InvalidatePage();
449 : }
450 : else
451 910 : pPage->InvalidateFlyLayout();
452 : }
453 : }
454 : else
455 8877 : pPage->InvalidateLayout();
456 :
457 10347 : if ( pRoot->GetTurbo() )
458 71 : { const SwFrm *pTmp = pRoot->GetTurbo();
459 71 : pRoot->ResetTurbo();
460 71 : pTmp->InvalidatePage();
461 : }
462 : }
463 31978 : pRoot->SetIdleFlags();
464 :
465 31978 : const SwTxtFrm *pTxtFrm = dynamic_cast< const SwTxtFrm * >(this);
466 31978 : if (pTxtFrm)
467 : {
468 21237 : const SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode();
469 21237 : if (pTxtNode && pTxtNode->IsGrammarCheckDirty())
470 21201 : pRoot->SetNeedGrammarCheck( sal_True );
471 : }
472 : }
473 : }
474 :
475 : /*************************************************************************
476 : |*
477 : |* SwFrm::ChgSize()
478 : |*
479 : |*************************************************************************/
480 1137 : Size SwFrm::ChgSize( const Size& aNewSize )
481 : {
482 1137 : mbFixSize = sal_True;
483 1137 : const Size aOldSize( Frm().SSize() );
484 1137 : if ( aNewSize == aOldSize )
485 149 : return aOldSize;
486 :
487 988 : if ( GetUpper() )
488 : {
489 79 : SWRECTFN2( this )
490 79 : SwRect aNew( Point(0,0), aNewSize );
491 79 : (maFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() );
492 79 : long nNew = (aNew.*fnRect->fnGetHeight)();
493 79 : long nDiff = nNew - (maFrm.*fnRect->fnGetHeight)();
494 79 : if( nDiff )
495 : {
496 83 : if ( GetUpper()->IsFtnBossFrm() && HasFixSize() &&
497 : NA_GROW_SHRINK !=
498 10 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) )
499 : {
500 10 : (maFrm.*fnRect->fnSetHeight)( nNew );
501 10 : SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood(nDiff);
502 10 : if ( nReal != nDiff )
503 4 : (maFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal );
504 : }
505 : else
506 : {
507 : // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames
508 : // NOTE: neighbour frames are cell and column frames.
509 63 : if ( !bNeighb )
510 : {
511 3 : if ( nDiff > 0 )
512 2 : Grow( nDiff );
513 : else
514 1 : Shrink( -nDiff );
515 :
516 3 : if ( GetUpper() && (maFrm.*fnRect->fnGetHeight)() != nNew )
517 3 : GetUpper()->_InvalidateSize();
518 : }
519 :
520 : // Even if grow/shrink did not yet set the desired width, for
521 : // example when called by ChgColumns to set the column width, we
522 : // set the right width now.
523 63 : (maFrm.*fnRect->fnSetHeight)( nNew );
524 : }
525 : }
526 : }
527 : else
528 909 : maFrm.SSize( aNewSize );
529 :
530 988 : if ( Frm().SSize() != aOldSize )
531 : {
532 988 : SwPageFrm *pPage = FindPageFrm();
533 988 : if ( GetNext() )
534 : {
535 44 : GetNext()->_InvalidatePos();
536 44 : GetNext()->InvalidatePage( pPage );
537 : }
538 988 : if( IsLayoutFrm() )
539 : {
540 988 : if( IsRightToLeft() )
541 0 : _InvalidatePos();
542 988 : if( ((SwLayoutFrm*)this)->Lower() )
543 75 : ((SwLayoutFrm*)this)->Lower()->_InvalidateSize();
544 : }
545 988 : _InvalidatePrt();
546 988 : _InvalidateSize();
547 988 : InvalidatePage( pPage );
548 : }
549 :
550 988 : return maFrm.SSize();
551 : }
552 :
553 : /** Insert SwFrm into existing structure.
554 : *
555 : * Insertion is done below the parent either before pBehind or
556 : * at the end of the chain if pBehind is empty.
557 : */
558 2549 : void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind )
559 : {
560 : OSL_ENSURE( pParent, "No parent for insert." );
561 : OSL_ENSURE( (!pBehind || (pBehind && pParent == pBehind->GetUpper())),
562 : "Frame tree is inconsistent." );
563 :
564 2549 : mpUpper = pParent;
565 2549 : mpNext = pBehind;
566 2549 : if( pBehind )
567 : { //Insert before pBehind.
568 333 : if( 0 != (mpPrev = pBehind->mpPrev) )
569 77 : mpPrev->mpNext = this;
570 : else
571 256 : mpUpper->pLower = this;
572 333 : pBehind->mpPrev = this;
573 : }
574 : else
575 : { //Insert at the end, or as first node in the sub tree
576 2216 : mpPrev = mpUpper->Lower();
577 2216 : if ( mpPrev )
578 : {
579 1718 : while( mpPrev->mpNext )
580 864 : mpPrev = mpPrev->mpNext;
581 427 : mpPrev->mpNext = this;
582 : }
583 : else
584 1789 : mpUpper->pLower = this;
585 : }
586 2549 : }
587 :
588 : /** Insert SwFrm into existing structure.
589 : *
590 : * Insertion is done below the parent either after pBehind or
591 : * at the beginning of the chain if pBehind is empty.
592 : */
593 6780 : void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore )
594 : {
595 : OSL_ENSURE( pParent, "No Parent for Insert." );
596 : OSL_ENSURE( (!pBefore || (pBefore && pParent == pBefore->GetUpper())),
597 : "Frame tree is inconsistent." );
598 :
599 6780 : mpUpper = pParent;
600 6780 : mpPrev = pBefore;
601 6780 : if ( pBefore )
602 : {
603 : //Insert after pBefore
604 2962 : if ( 0 != (mpNext = pBefore->mpNext) )
605 32 : mpNext->mpPrev = this;
606 2962 : pBefore->mpNext = this;
607 : }
608 : else
609 : {
610 : //Insert at the beginning of the chain
611 3818 : mpNext = pParent->Lower();
612 3818 : if ( pParent->Lower() )
613 21 : pParent->Lower()->mpPrev = this;
614 3818 : pParent->pLower = this;
615 : }
616 6780 : }
617 :
618 : /** Insert a chain of SwFrms into an existing struction
619 : *
620 : * Currently, this method is used to insert a SectionFrame (which may have some siblings) into an
621 : * existing structure. If the third parameter is NULL, this method is (besides handling the
622 : * siblings) equal to SwFrm::InsertBefore(..).
623 : *
624 : * If the third parameter is passed, the following happens:
625 : * - this becomes mpNext of pParent
626 : * - pSct becomes mpNext of the last one in the this-chain
627 : * - pBehind is reconnected from pParent to pSct
628 : * The purpose is: a SectionFrm (this) won't become a child of another SectionFrm (pParent), but
629 : * pParent gets split into two siblings (pParent+pSect) and this is inserted between.
630 : */
631 0 : void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct )
632 : {
633 : OSL_ENSURE( pParent, "No parent for insert." );
634 : OSL_ENSURE( (!pBehind || ( (pBehind && (pParent == pBehind->GetUpper()))
635 : || ((pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm())) ) ),
636 : "Frame tree inconsistent." );
637 0 : if( pSct )
638 : {
639 0 : mpUpper = pParent->GetUpper();
640 0 : SwFrm *pLast = this;
641 0 : while( pLast->GetNext() )
642 : {
643 0 : pLast = pLast->GetNext();
644 0 : pLast->mpUpper = GetUpper();
645 : }
646 0 : if( pBehind )
647 : {
648 0 : pLast->mpNext = pSct;
649 0 : pSct->mpPrev = pLast;
650 0 : pSct->mpNext = pParent->GetNext();
651 : }
652 : else
653 : {
654 0 : pLast->mpNext = pParent->GetNext();
655 0 : if( pLast->GetNext() )
656 0 : pLast->GetNext()->mpPrev = pLast;
657 : }
658 0 : pParent->mpNext = this;
659 0 : mpPrev = pParent;
660 0 : if( pSct->GetNext() )
661 0 : pSct->GetNext()->mpPrev = pSct;
662 0 : while( pLast->GetNext() )
663 : {
664 0 : pLast = pLast->GetNext();
665 0 : pLast->mpUpper = GetUpper();
666 : }
667 0 : if( pBehind )
668 : { // Insert before pBehind.
669 0 : if( pBehind->GetPrev() )
670 0 : pBehind->GetPrev()->mpNext = NULL;
671 : else
672 0 : pBehind->GetUpper()->pLower = NULL;
673 0 : pBehind->mpPrev = NULL;
674 0 : SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct;
675 0 : if( pTmp->Lower() )
676 : {
677 : OSL_ENSURE( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" );
678 0 : pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower();
679 : OSL_ENSURE( pTmp, "InsertGrp: Missing ColBody" );
680 : }
681 0 : pBehind->mpUpper = pTmp;
682 0 : pBehind->GetUpper()->pLower = pBehind;
683 0 : pLast = pBehind->GetNext();
684 0 : while ( pLast )
685 : {
686 0 : pLast->mpUpper = pBehind->GetUpper();
687 0 : pLast = pLast->GetNext();
688 : };
689 : }
690 : else
691 : {
692 : OSL_ENSURE( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" );
693 0 : delete ((SwSectionFrm*)pSct);
694 : }
695 : }
696 : else
697 : {
698 0 : mpUpper = (SwLayoutFrm*)pParent;
699 0 : SwFrm *pLast = this;
700 0 : while( pLast->GetNext() )
701 : {
702 0 : pLast = pLast->GetNext();
703 0 : pLast->mpUpper = GetUpper();
704 : }
705 0 : pLast->mpNext = pBehind;
706 0 : if( pBehind )
707 : { // Insert before pBehind.
708 0 : if( 0 != (mpPrev = pBehind->mpPrev) )
709 0 : mpPrev->mpNext = this;
710 : else
711 0 : mpUpper->pLower = this;
712 0 : pBehind->mpPrev = pLast;
713 : }
714 : else
715 : {
716 : //Insert at the end, or ... the first node in the subtree
717 0 : mpPrev = mpUpper->Lower();
718 0 : if ( mpPrev )
719 : {
720 0 : while( mpPrev->mpNext )
721 0 : mpPrev = mpPrev->mpNext;
722 0 : mpPrev->mpNext = this;
723 : }
724 : else
725 0 : mpUpper->pLower = this;
726 : }
727 : }
728 0 : }
729 :
730 : /*************************************************************************
731 : |*
732 : |* SwFrm::Remove()
733 : |*
734 : |*************************************************************************/
735 5714 : void SwFrm::Remove()
736 : {
737 : OSL_ENSURE( mpUpper, "Remove without upper?" );
738 :
739 5714 : if( mpPrev )
740 : // one out of the middle is removed
741 474 : mpPrev->mpNext = mpNext;
742 : else
743 : { // the first in a list is removed //TODO
744 : OSL_ENSURE( mpUpper->pLower == this, "Layout is inconsistent." );
745 5240 : mpUpper->pLower = mpNext;
746 : }
747 5714 : if( mpNext )
748 2110 : mpNext->mpPrev = mpPrev;
749 :
750 : // Remove link
751 5714 : mpNext = mpPrev = 0;
752 5714 : mpUpper = 0;
753 5714 : }
754 : /*************************************************************************
755 : |*
756 : |* SwCntntFrm::Paste()
757 : |*
758 : |*************************************************************************/
759 363 : void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
760 : {
761 : OSL_ENSURE( pParent, "No parent for pasting." );
762 : OSL_ENSURE( pParent->IsLayoutFrm(), "Parent is CntntFrm." );
763 : OSL_ENSURE( pParent != this, "I'm the parent." );
764 : OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
765 : OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
766 : "I'm still registered somewhere" );
767 : OSL_ENSURE( !pSibling || pSibling->IsFlowFrm(),
768 : "<SwCntntFrm::Paste(..)> - sibling not of expected type." );
769 :
770 : //Insert in the tree.
771 363 : InsertBefore( (SwLayoutFrm*)pParent, pSibling );
772 :
773 363 : SwPageFrm *pPage = FindPageFrm();
774 363 : _InvalidateAll();
775 363 : InvalidatePage( pPage );
776 :
777 363 : if( pPage )
778 : {
779 363 : pPage->InvalidateSpelling();
780 363 : pPage->InvalidateSmartTags(); // SMARTTAGS
781 363 : pPage->InvalidateAutoCompleteWords();
782 363 : pPage->InvalidateWordCount();
783 : }
784 :
785 363 : if ( GetNext() )
786 : {
787 201 : SwFrm* pNxt = GetNext();
788 201 : pNxt->_InvalidatePrt();
789 201 : pNxt->_InvalidatePos();
790 201 : pNxt->InvalidatePage( pPage );
791 201 : if( pNxt->IsSctFrm() )
792 3 : pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt();
793 201 : if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() )
794 5 : pNxt->Prepare( PREP_FTN, 0, sal_False );
795 : }
796 :
797 363 : if ( Frm().Height() )
798 25 : pParent->Grow( Frm().Height() );
799 :
800 363 : if ( Frm().Width() != pParent->Prt().Width() )
801 325 : Prepare( PREP_FIXSIZE_CHG );
802 :
803 363 : if ( GetPrev() )
804 : {
805 212 : if ( IsFollow() )
806 : //I'm a direct follower of my master now
807 25 : ((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS );
808 : else
809 : {
810 374 : if ( GetPrev()->Frm().Height() !=
811 187 : GetPrev()->Prt().Height() + GetPrev()->Prt().Top() )
812 : {
813 : // Take the border into account?
814 5 : GetPrev()->_InvalidatePrt();
815 : }
816 : // OD 18.02.2003 #104989# - force complete paint of previous frame,
817 : // if frame is inserted at the end of a section frame, in order to
818 : // get subsidiary lines repainted for the section.
819 187 : if ( pParent->IsSctFrm() && !GetNext() )
820 : {
821 : // force complete paint of previous frame, if new inserted frame
822 : // in the section is the last one.
823 2 : GetPrev()->SetCompletePaint();
824 : }
825 187 : GetPrev()->InvalidatePage( pPage );
826 : }
827 : }
828 363 : if ( IsInFtn() )
829 : {
830 8 : SwFrm* pFrm = GetIndPrev();
831 8 : if( pFrm && pFrm->IsSctFrm() )
832 1 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
833 8 : if( pFrm )
834 4 : pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
835 8 : if( !GetNext() )
836 : {
837 3 : pFrm = FindFtnFrm()->GetNext();
838 3 : if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) )
839 0 : pFrm->_InvalidatePrt();
840 : }
841 : }
842 :
843 363 : _InvalidateLineNum();
844 363 : SwFrm *pNxt = FindNextCnt();
845 363 : if ( pNxt )
846 : {
847 495 : while ( pNxt && pNxt->IsInTab() )
848 : {
849 11 : if( 0 != (pNxt = pNxt->FindTabFrm()) )
850 11 : pNxt = pNxt->FindNextCnt();
851 : }
852 242 : if ( pNxt )
853 : {
854 242 : pNxt->_InvalidateLineNum();
855 242 : if ( pNxt != GetNext() )
856 54 : pNxt->InvalidatePage();
857 : }
858 : }
859 363 : }
860 :
861 : /*************************************************************************
862 : |*
863 : |* SwCntntFrm::Cut()
864 : |*
865 : |*************************************************************************/
866 137 : void SwCntntFrm::Cut()
867 : {
868 : OSL_ENSURE( GetUpper(), "Cut without Upper()." );
869 :
870 137 : SwPageFrm *pPage = FindPageFrm();
871 137 : InvalidatePage( pPage );
872 137 : SwFrm *pFrm = GetIndPrev();
873 137 : if( pFrm )
874 : {
875 83 : if( pFrm->IsSctFrm() )
876 11 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
877 83 : if ( pFrm && pFrm->IsCntntFrm() )
878 : {
879 73 : pFrm->_InvalidatePrt();
880 73 : if( IsInFtn() )
881 4 : pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
882 : }
883 : // #i26250# - invalidate printing area of previous
884 : // table frame.
885 10 : else if ( pFrm && pFrm->IsTabFrm() )
886 : {
887 2 : pFrm->InvalidatePrt();
888 : }
889 : }
890 :
891 137 : SwFrm *pNxt = FindNextCnt();
892 137 : if ( pNxt )
893 : {
894 201 : while ( pNxt && pNxt->IsInTab() )
895 : {
896 3 : if( 0 != (pNxt = pNxt->FindTabFrm()) )
897 3 : pNxt = pNxt->FindNextCnt();
898 : }
899 99 : if ( pNxt )
900 : {
901 99 : pNxt->_InvalidateLineNum();
902 99 : if ( pNxt != GetNext() )
903 51 : pNxt->InvalidatePage();
904 : }
905 : }
906 :
907 137 : if( 0 != (pFrm = GetIndNext()) )
908 : {
909 : // The old follow may have calculated a gap to the predecessor which
910 : // now becomes obsolete or different as it becomes the first one itself
911 87 : pFrm->_InvalidatePrt();
912 87 : pFrm->_InvalidatePos();
913 87 : pFrm->InvalidatePage( pPage );
914 87 : if( pFrm->IsSctFrm() )
915 : {
916 29 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
917 29 : if( pFrm )
918 : {
919 9 : pFrm->_InvalidatePrt();
920 9 : pFrm->_InvalidatePos();
921 9 : pFrm->InvalidatePage( pPage );
922 : }
923 : }
924 87 : if( pFrm && IsInFtn() )
925 2 : pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
926 87 : if( IsInSct() && !GetPrev() )
927 : {
928 23 : SwSectionFrm* pSct = FindSctFrm();
929 23 : if( !pSct->IsFollow() )
930 : {
931 2 : pSct->_InvalidatePrt();
932 2 : pSct->InvalidatePage( pPage );
933 : }
934 : }
935 : }
936 : else
937 : {
938 50 : InvalidateNextPos();
939 : //Someone needs to do the retouching: predecessor or upper
940 50 : if ( 0 != (pFrm = GetPrev()) )
941 40 : { pFrm->SetRetouche();
942 40 : pFrm->Prepare( PREP_WIDOWS_ORPHANS );
943 40 : pFrm->_InvalidatePos();
944 40 : pFrm->InvalidatePage( pPage );
945 : }
946 : // If I'm (was) the only CntntFrm in my upper, it has to do the
947 : // retouching. Also, perhaps a page became empty.
948 : else
949 10 : { SwRootFrm *pRoot = getRootFrm();
950 10 : if ( pRoot )
951 : {
952 10 : pRoot->SetSuperfluous();
953 10 : GetUpper()->SetCompletePaint();
954 10 : GetUpper()->InvalidatePage( pPage );
955 : }
956 10 : if( IsInSct() )
957 : {
958 0 : SwSectionFrm* pSct = FindSctFrm();
959 0 : if( !pSct->IsFollow() )
960 : {
961 0 : pSct->_InvalidatePrt();
962 0 : pSct->InvalidatePage( pPage );
963 : }
964 : }
965 : // #i52253# The master table should take care
966 : // of removing the follow flow line.
967 10 : if ( IsInTab() )
968 : {
969 0 : SwTabFrm* pThisTab = FindTabFrm();
970 0 : SwTabFrm* pMasterTab = pThisTab && pThisTab->IsFollow() ? pThisTab->FindMaster() : 0;
971 0 : if ( pMasterTab )
972 : {
973 0 : pMasterTab->_InvalidatePos();
974 0 : pMasterTab->SetRemoveFollowFlowLinePending( sal_True );
975 : }
976 : }
977 : }
978 : }
979 : //Remove first, then shrink the upper.
980 137 : SwLayoutFrm *pUp = GetUpper();
981 137 : Remove();
982 137 : if ( pUp )
983 : {
984 137 : SwSectionFrm *pSct = 0;
985 193 : if ( !pUp->Lower() &&
986 66 : ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() ) ||
987 56 : ( pUp->IsInSct() &&
988 : // #i29438#
989 : // We have to consider the case that the section may be "empty"
990 : // except from a temporary empty table frame.
991 : // This can happen due to the new cell split feature.
992 69 : !pUp->IsCellFrm() &&
993 : // #126020# - adjust check for empty section
994 : // #130797# - correct fix #126020#
995 69 : !(pSct = pUp->FindSctFrm())->ContainsCntnt() &&
996 23 : !pSct->ContainsAny( true ) ) ) )
997 : {
998 23 : if ( pUp->GetUpper() )
999 : {
1000 : //
1001 : // prevent delete of <ColLocked> footnote frame
1002 23 : if ( pUp->IsFtnFrm() && !pUp->IsColLocked())
1003 : {
1004 0 : if( pUp->GetNext() && !pUp->GetPrev() )
1005 : {
1006 0 : SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny();
1007 0 : if( pTmp )
1008 0 : pTmp->_InvalidatePrt();
1009 : }
1010 0 : pUp->Cut();
1011 0 : delete pUp;
1012 : }
1013 : else
1014 : {
1015 : //
1016 46 : if ( pSct->IsColLocked() || !pSct->IsInFtn() ||
1017 0 : ( pUp->IsFtnFrm() && pUp->IsColLocked() ) )
1018 : {
1019 23 : pSct->DelEmpty( sal_False );
1020 : // If a locked section may not be deleted then at least
1021 : // its size became invalid after removing its last
1022 : // content.
1023 23 : pSct->_InvalidateSize();
1024 : }
1025 : else
1026 : {
1027 0 : pSct->DelEmpty( sal_True );
1028 0 : delete pSct;
1029 : }
1030 : }
1031 : }
1032 : }
1033 : else
1034 : {
1035 114 : SWRECTFN( this )
1036 114 : long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1037 114 : if( nFrmHeight )
1038 89 : pUp->Shrink( nFrmHeight );
1039 : }
1040 : }
1041 137 : }
1042 :
1043 : /*************************************************************************
1044 : |*
1045 : |* SwLayoutFrm::Paste()
1046 : |*
1047 : |*************************************************************************/
1048 1131 : void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
1049 : {
1050 : OSL_ENSURE( pParent, "No parent for pasting." );
1051 : OSL_ENSURE( pParent->IsLayoutFrm(), "Parent is CntntFrm." );
1052 : OSL_ENSURE( pParent != this, "I'm the parent oneself." );
1053 : OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
1054 : OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
1055 : "I'm still registered somewhere." );
1056 :
1057 : //Insert in the tree.
1058 1131 : InsertBefore( (SwLayoutFrm*)pParent, pSibling );
1059 :
1060 : // OD 24.10.2002 #103517# - correct setting of variable <fnRect>
1061 : // <fnRect> is used for the following:
1062 : // (1) To invalidate the frame's size, if its size, which has to be the
1063 : // same as its upper/parent, differs from its upper's/parent's.
1064 : // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its
1065 : // size, which is not determined by its upper/parent.
1066 : // Which size is which depends on the frame type and the layout direction
1067 : // (vertical or horizontal).
1068 : // There are the following cases:
1069 : // (A) Header and footer frames both in vertical and in horizontal layout
1070 : // have to size the width to the upper/parent. A dimension in the height
1071 : // has to cause a adjustment/grow of the upper/parent.
1072 : // --> <fnRect> = fnRectHori
1073 : // (B) Cell and column frames in vertical layout, the width has to be the
1074 : // same as upper/parent and a dimension in height causes adjustment/grow
1075 : // of the upper/parent.
1076 : // --> <fnRect> = fnRectHori
1077 : // in horizontal layout the other way around
1078 : // --> <fnRect> = fnRectVert
1079 : // (C) Other frames in vertical layout, the height has to be the
1080 : // same as upper/parent and a dimension in width causes adjustment/grow
1081 : // of the upper/parent.
1082 : // --> <fnRect> = fnRectVert
1083 : // in horizontal layout the other way around
1084 : // --> <fnRect> = fnRectHori
1085 : //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert;
1086 : SwRectFn fnRect;
1087 1131 : if ( IsHeaderFrm() || IsFooterFrm() )
1088 163 : fnRect = fnRectHori;
1089 968 : else if ( IsCellFrm() || IsColumnFrm() )
1090 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1091 19 : fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert );
1092 : else
1093 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1094 949 : fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
1095 :
1096 :
1097 1131 : if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)())
1098 209 : _InvalidateSize();
1099 1131 : _InvalidatePos();
1100 1131 : const SwPageFrm *pPage = FindPageFrm();
1101 1131 : InvalidatePage( pPage );
1102 : SwFrm *pFrm;
1103 1131 : if( !IsColumnFrm() )
1104 : {
1105 1112 : if( 0 != ( pFrm = GetIndNext() ) )
1106 : {
1107 77 : pFrm->_InvalidatePos();
1108 77 : if( IsInFtn() )
1109 : {
1110 0 : if( pFrm->IsSctFrm() )
1111 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1112 0 : if( pFrm )
1113 0 : pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
1114 : }
1115 : }
1116 1112 : if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) )
1117 : {
1118 27 : if( pFrm->IsSctFrm() )
1119 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1120 27 : if( pFrm )
1121 27 : pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
1122 : }
1123 : }
1124 :
1125 1131 : if( (Frm().*fnRect->fnGetHeight)() )
1126 : {
1127 : // AdjustNeighbourhood is now also called in columns which are not
1128 : // placed inside a frame
1129 907 : sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
1130 907 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
1131 1814 : : NA_GROW_SHRINK;
1132 907 : SwTwips nGrow = (Frm().*fnRect->fnGetHeight)();
1133 907 : if( NA_ONLY_ADJUST == nAdjust )
1134 907 : AdjustNeighbourhood( nGrow );
1135 : else
1136 : {
1137 0 : SwTwips nReal = 0;
1138 0 : if( NA_ADJUST_GROW == nAdjust )
1139 0 : nReal = AdjustNeighbourhood( nGrow );
1140 0 : if( nReal < nGrow )
1141 0 : nReal += pParent->Grow( nGrow - nReal );
1142 0 : if( NA_GROW_ADJUST == nAdjust && nReal < nGrow )
1143 0 : AdjustNeighbourhood( nGrow - nReal );
1144 : }
1145 : }
1146 1131 : }
1147 :
1148 : /*************************************************************************
1149 : |*
1150 : |* SwLayoutFrm::Cut()
1151 : |*
1152 : |*************************************************************************/
1153 40 : void SwLayoutFrm::Cut()
1154 : {
1155 40 : if ( GetNext() )
1156 9 : GetNext()->_InvalidatePos();
1157 :
1158 40 : SWRECTFN( this )
1159 40 : SwTwips nShrink = (Frm().*fnRect->fnGetHeight)();
1160 :
1161 : //Remove first, then shrink upper.
1162 40 : SwLayoutFrm *pUp = GetUpper();
1163 :
1164 : // AdjustNeighbourhood is now also called in columns which are not
1165 : // placed inside a frame
1166 :
1167 : // Remove must not be called before a AdjustNeighbourhood, but it has to
1168 : // be called before the upper-shrink-call, if the upper-shrink takes care
1169 : // of his content
1170 40 : if ( pUp && nShrink )
1171 : {
1172 34 : if( pUp->IsFtnBossFrm() )
1173 : {
1174 27 : sal_uInt8 nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this );
1175 27 : if( NA_ONLY_ADJUST == nAdjust )
1176 27 : AdjustNeighbourhood( -nShrink );
1177 : else
1178 : {
1179 0 : SwTwips nReal = 0;
1180 0 : if( NA_ADJUST_GROW == nAdjust )
1181 0 : nReal = -AdjustNeighbourhood( -nShrink );
1182 0 : if( nReal < nShrink )
1183 : {
1184 0 : SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)();
1185 0 : (Frm().*fnRect->fnSetHeight)( 0 );
1186 0 : nReal += pUp->Shrink( nShrink - nReal );
1187 0 : (Frm().*fnRect->fnSetHeight)( nOldHeight );
1188 : }
1189 0 : if( NA_GROW_ADJUST == nAdjust && nReal < nShrink )
1190 0 : AdjustNeighbourhood( nReal - nShrink );
1191 : }
1192 27 : Remove();
1193 : }
1194 : else
1195 : {
1196 7 : Remove();
1197 7 : pUp->Shrink( nShrink );
1198 34 : }
1199 : }
1200 : else
1201 6 : Remove();
1202 :
1203 40 : if( pUp && !pUp->Lower() )
1204 : {
1205 4 : pUp->SetCompletePaint();
1206 4 : pUp->InvalidatePage();
1207 : }
1208 40 : }
1209 :
1210 : /*************************************************************************
1211 : |*
1212 : |* SwFrm::Grow()
1213 : |*
1214 : |*************************************************************************/
1215 12842 : SwTwips SwFrm::Grow( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1216 : {
1217 : OSL_ENSURE( nDist >= 0, "Negative growth?" );
1218 :
1219 : PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist )
1220 :
1221 12842 : if ( nDist )
1222 : {
1223 12840 : SWRECTFN( this )
1224 :
1225 12840 : SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1226 12840 : if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) )
1227 1503 : nDist = LONG_MAX - nPrtHeight;
1228 :
1229 12840 : if ( IsFlyFrm() )
1230 134 : return ((SwFlyFrm*)this)->_Grow( nDist, bTst );
1231 12706 : else if( IsSctFrm() )
1232 328 : return ((SwSectionFrm*)this)->_Grow( nDist, bTst );
1233 : else
1234 : {
1235 12378 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1236 12378 : if ( pThisCell )
1237 : {
1238 1218 : const SwTabFrm* pTab = FindTabFrm();
1239 :
1240 : // NEW TABLES
1241 2434 : if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
1242 1216 : pThisCell->GetLayoutRowSpan() < 1 )
1243 2 : return 0;
1244 : }
1245 :
1246 12376 : const SwTwips nReal = GrowFrm( nDist, bTst, bInfo );
1247 12376 : if( !bTst )
1248 : {
1249 8943 : nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1250 8943 : (Prt().*fnRect->fnSetHeight)( nPrtHeight +
1251 8943 : ( IsCntntFrm() ? nDist : nReal ) );
1252 : }
1253 12376 : return nReal;
1254 : }
1255 : }
1256 2 : return 0L;
1257 : }
1258 :
1259 : /*************************************************************************
1260 : |*
1261 : |* SwFrm::Shrink()
1262 : |*
1263 : |*************************************************************************/
1264 2954 : SwTwips SwFrm::Shrink( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1265 : {
1266 : OSL_ENSURE( nDist >= 0, "Negative reduction?" );
1267 :
1268 : PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist )
1269 :
1270 2954 : if ( nDist )
1271 : {
1272 2859 : if ( IsFlyFrm() )
1273 9 : return ((SwFlyFrm*)this)->_Shrink( nDist, bTst );
1274 2850 : else if( IsSctFrm() )
1275 45 : return ((SwSectionFrm*)this)->_Shrink( nDist, bTst );
1276 : else
1277 : {
1278 2805 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1279 2805 : if ( pThisCell )
1280 : {
1281 819 : const SwTabFrm* pTab = FindTabFrm();
1282 :
1283 : // NEW TABLES
1284 1637 : if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
1285 818 : pThisCell->GetLayoutRowSpan() < 1 )
1286 1 : return 0;
1287 : }
1288 :
1289 2804 : SWRECTFN( this )
1290 2804 : SwTwips nReal = (Frm().*fnRect->fnGetHeight)();
1291 2804 : ShrinkFrm( nDist, bTst, bInfo );
1292 2804 : nReal -= (Frm().*fnRect->fnGetHeight)();
1293 2804 : if( !bTst )
1294 : {
1295 2804 : const SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1296 2804 : (Prt().*fnRect->fnSetHeight)( nPrtHeight -
1297 2804 : ( IsCntntFrm() ? nDist : nReal ) );
1298 : }
1299 2804 : return nReal;
1300 : }
1301 : }
1302 95 : return 0L;
1303 : }
1304 :
1305 : /** Adjust surrounding neighbourhood after insertion
1306 : *
1307 : * A Frm needs "normalization" if it is directly placed below a footnote boss (page/column) and its
1308 : * size changes. There is always a frame that takes the maximum possible space (the frame that
1309 : * contains the Body text) and zero or more frames which only take the space needed (header/footer
1310 : * area, footnote container). If one of these frames changes, the body-text-frame has to grow or
1311 : * shrink accordingly, even tough it's fixed.
1312 : *
1313 : * !! Is it possible to do this in a generic way and not restrict it to the page and a distinct
1314 : * frame which takes the maximum space (controlled using the FrmSize attribute)?
1315 : * Problems:
1316 : * - What if multiple frames taking the maximum space are placed next to each other?
1317 : * - How is the maximum space calculated?
1318 : * - How small can those frames become?
1319 : *
1320 : * In any case, only a certain amount of space is allowed, so we never go below a minimum value for
1321 : * the height of the body.
1322 : *
1323 : * @param nDiff the value around which the space has to be allocated
1324 : */
1325 1411 : SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, sal_Bool bTst )
1326 : {
1327 : PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff );
1328 :
1329 1411 : if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // only inside pages/columns
1330 0 : return 0L;
1331 :
1332 1411 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
1333 1411 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1334 :
1335 : //The (Page-)Body only changes in BrowseMode, but only if it does not
1336 : //contain columns.
1337 2324 : if ( IsPageBodyFrm() && (!bBrowse ||
1338 12 : (((SwLayoutFrm*)this)->Lower() &&
1339 6 : ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) )
1340 907 : return 0L;
1341 :
1342 : //In BrowseView mode the PageFrm can handle some of the requests.
1343 504 : long nBrowseAdd = 0;
1344 504 : if ( bBrowse && GetUpper()->IsPageFrm() ) // only (Page-)BodyFrms
1345 : {
1346 6 : ViewShell *pViewShell = getRootFrm()->GetCurrShell();
1347 6 : SwLayoutFrm *pUp = GetUpper();
1348 : long nChg;
1349 12 : const long nUpPrtBottom = pUp->Frm().Height() -
1350 12 : pUp->Prt().Height() - pUp->Prt().Top();
1351 6 : SwRect aInva( pUp->Frm() );
1352 6 : if ( pViewShell )
1353 : {
1354 6 : aInva.Pos().X() = pViewShell->VisArea().Left();
1355 6 : aInva.Width( pViewShell->VisArea().Width() );
1356 : }
1357 6 : if ( nDiff > 0 )
1358 : {
1359 2 : nChg = BROWSE_HEIGHT - pUp->Frm().Height();
1360 2 : nChg = std::min( nDiff, nChg );
1361 :
1362 2 : if ( !IsBodyFrm() )
1363 : {
1364 0 : SetCompletePaint();
1365 0 : if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->Frm().Height() )
1366 : {
1367 : //First minimize Body, it will grow again later.
1368 0 : SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont();
1369 0 : const long nTmp = nChg - pBody->Prt().Height();
1370 0 : if ( !bTst )
1371 : {
1372 0 : pBody->Frm().Height(std::max( 0L, pBody->Frm().Height() - nChg ));
1373 0 : pBody->_InvalidatePrt();
1374 0 : pBody->_InvalidateSize();
1375 0 : if ( pBody->GetNext() )
1376 0 : pBody->GetNext()->_InvalidatePos();
1377 0 : if ( !IsHeaderFrm() )
1378 0 : pBody->SetCompletePaint();
1379 : }
1380 0 : nChg = nTmp <= 0 ? 0 : nTmp;
1381 : }
1382 : }
1383 :
1384 2 : const long nTmp = nUpPrtBottom + 20;
1385 2 : aInva.Top( aInva.Bottom() - nTmp );
1386 2 : aInva.Height( nChg + nTmp );
1387 : }
1388 : else
1389 : {
1390 : //The page can shrink to 0. The fist page keeps the same size like
1391 : //VisArea.
1392 4 : nChg = nDiff;
1393 4 : long nInvaAdd = 0;
1394 8 : if ( pViewShell && !pUp->GetPrev() &&
1395 4 : pUp->Frm().Height() + nDiff < pViewShell->VisArea().Height() )
1396 : {
1397 : // This means that we have to invalidate adequately.
1398 4 : nChg = pViewShell->VisArea().Height() - pUp->Frm().Height();
1399 4 : nInvaAdd = -(nDiff - nChg);
1400 : }
1401 :
1402 : //Invalidate including bottom border.
1403 4 : long nBorder = nUpPrtBottom + 20;
1404 4 : nBorder -= nChg;
1405 4 : aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
1406 4 : if ( !IsBodyFrm() )
1407 : {
1408 0 : SetCompletePaint();
1409 0 : if ( !IsHeaderFrm() )
1410 0 : ((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint();
1411 : }
1412 : //Invalidate the page because of the frames. Thereby the page becomes
1413 : //the right size again if a frame didn't fit. This only works
1414 : //randomly for paragraph bound frames otherwise (NotifyFlys).
1415 4 : pUp->InvalidateSize();
1416 : }
1417 6 : if ( !bTst )
1418 : {
1419 : //Independent from nChg
1420 6 : if ( pViewShell && aInva.HasArea() && pUp->GetUpper() )
1421 4 : pViewShell->InvalidateWindows( aInva );
1422 : }
1423 6 : if ( !bTst && nChg )
1424 : {
1425 2 : pUp->Frm().SSize().Height() += nChg;
1426 2 : pUp->Prt().SSize().Height() += nChg;
1427 2 : if ( pViewShell )
1428 2 : pViewShell->Imp()->SetFirstVisPageInvalid();
1429 :
1430 2 : if ( GetNext() )
1431 0 : GetNext()->_InvalidatePos();
1432 :
1433 : //Trigger a repaint if necessary.
1434 2 : const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos();
1435 2 : if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
1436 0 : pViewShell->InvalidateWindows( pUp->Frm() );
1437 :
1438 2 : if ( pUp->GetUpper() )
1439 : {
1440 2 : if ( pUp->GetNext() )
1441 0 : pUp->GetNext()->InvalidatePos();
1442 :
1443 : //Sad but true: during notify on ViewImp a Calc on the page and
1444 : //its Lower may be called. The values should not be changed
1445 : //because the caller takes care of the adjustment of Frm and
1446 : //Prt.
1447 2 : const long nOldFrmHeight = Frm().Height();
1448 2 : const long nOldPrtHeight = Prt().Height();
1449 2 : const sal_Bool bOldComplete = IsCompletePaint();
1450 2 : if ( IsBodyFrm() )
1451 2 : Prt().SSize().Height() = nOldFrmHeight;
1452 :
1453 2 : if ( pUp->GetUpper() )
1454 2 : static_cast<SwRootFrm*>(pUp->GetUpper())->CheckViewLayout( 0, 0 );
1455 : //((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect );
1456 :
1457 2 : Frm().SSize().Height() = nOldFrmHeight;
1458 2 : Prt().SSize().Height() = nOldPrtHeight;
1459 2 : mbCompletePaint = bOldComplete;
1460 : }
1461 2 : if ( !IsBodyFrm() )
1462 0 : pUp->_InvalidateSize();
1463 2 : InvalidatePage( (SwPageFrm*)pUp );
1464 : }
1465 6 : nDiff -= nChg;
1466 6 : if ( !nDiff )
1467 2 : return nChg;
1468 : else
1469 4 : nBrowseAdd = nChg;
1470 : }
1471 :
1472 502 : const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
1473 :
1474 502 : SwTwips nReal = 0,
1475 502 : nAdd = 0;
1476 502 : SwFrm *pFrm = 0;
1477 502 : SWRECTFN( this )
1478 :
1479 502 : if( IsBodyFrm() )
1480 : {
1481 8 : if( IsInSct() )
1482 : {
1483 0 : SwSectionFrm *pSect = FindSctFrm();
1484 0 : if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
1485 0 : GetNext()->IsFtnContFrm() )
1486 : {
1487 0 : SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext();
1488 0 : SwTwips nMinH = 0;
1489 0 : SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
1490 0 : bool bFtn = false;
1491 0 : while( pFtn )
1492 : {
1493 0 : if( !pFtn->GetAttr()->GetFtn().IsEndNote() )
1494 : {
1495 0 : nMinH += (pFtn->Frm().*fnRect->fnGetHeight)();
1496 0 : bFtn = true;
1497 : }
1498 0 : pFtn = (SwFtnFrm*)pFtn->GetNext();
1499 : }
1500 0 : if( bFtn )
1501 0 : nMinH += (pCont->Prt().*fnRect->fnGetTop)();
1502 0 : nReal = (pCont->Frm().*fnRect->fnGetHeight)() - nMinH;
1503 0 : if( nReal > nDiff )
1504 0 : nReal = nDiff;
1505 0 : if( nReal > 0 )
1506 0 : pFrm = GetNext();
1507 : else
1508 0 : nReal = 0;
1509 : }
1510 0 : if( !bTst && !pSect->IsColLocked() )
1511 0 : pSect->InvalidateSize();
1512 : }
1513 8 : if( !pFrm )
1514 8 : return nBrowseAdd;
1515 : }
1516 : else
1517 : {
1518 494 : const bool bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage();
1519 494 : if ( bFtnPage && !IsFtnContFrm() )
1520 0 : pFrm = (SwFrm*)pBoss->FindFtnCont();
1521 494 : if ( !pFrm )
1522 494 : pFrm = (SwFrm*)pBoss->FindBodyCont();
1523 :
1524 494 : if ( !pFrm )
1525 0 : return 0;
1526 :
1527 : //If not one is found, everything else is solved.
1528 494 : nReal = (pFrm->Frm().*fnRect->fnGetHeight)();
1529 494 : if( nReal > nDiff )
1530 489 : nReal = nDiff;
1531 494 : if( !bFtnPage )
1532 : {
1533 : //Respect the minimal boundary!
1534 484 : if( nReal )
1535 : {
1536 484 : const SwTwips nMax = pBoss->GetVarSpace();
1537 484 : if ( nReal > nMax )
1538 0 : nReal = nMax;
1539 : }
1540 1183 : if( !IsFtnContFrm() && nDiff > nReal &&
1541 0 : pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm()
1542 484 : && ( pFrm->GetNext()->IsVertical() == IsVertical() )
1543 : )
1544 : {
1545 : //If the Body doesn't return enough, we look for a footnote, if
1546 : //there is one, we steal there accordingly.
1547 0 : const SwTwips nAddMax = (pFrm->GetNext()->Frm().*fnRect->
1548 0 : fnGetHeight)();
1549 0 : nAdd = nDiff - nReal;
1550 0 : if ( nAdd > nAddMax )
1551 0 : nAdd = nAddMax;
1552 0 : if ( !bTst )
1553 : {
1554 0 : (pFrm->GetNext()->Frm().*fnRect->fnSetHeight)(nAddMax-nAdd);
1555 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1556 0 : if( bVert && !bVertL2R && !bRev )
1557 0 : pFrm->GetNext()->Frm().Pos().X() += nAdd;
1558 0 : pFrm->GetNext()->InvalidatePrt();
1559 0 : if ( pFrm->GetNext()->GetNext() )
1560 0 : pFrm->GetNext()->GetNext()->_InvalidatePos();
1561 : }
1562 : }
1563 : }
1564 : }
1565 :
1566 494 : if ( !bTst && nReal )
1567 : {
1568 327 : SwTwips nTmp = (pFrm->Frm().*fnRect->fnGetHeight)();
1569 327 : (pFrm->Frm().*fnRect->fnSetHeight)( nTmp - nReal );
1570 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1571 327 : if( bVert && !bVertL2R && !bRev )
1572 0 : pFrm->Frm().Pos().X() += nReal;
1573 327 : pFrm->InvalidatePrt();
1574 327 : if ( pFrm->GetNext() )
1575 309 : pFrm->GetNext()->_InvalidatePos();
1576 327 : if( nReal < 0 && pFrm->IsInSct() )
1577 : {
1578 0 : SwLayoutFrm* pUp = pFrm->GetUpper();
1579 0 : if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() &&
1580 0 : !pUp->IsColLocked() )
1581 0 : pUp->InvalidateSize();
1582 : }
1583 327 : if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() )
1584 : {
1585 0 : const SwSortedObjs &rObjs = *pBoss->GetDrawObjs();
1586 : OSL_ENSURE( pBoss->IsPageFrm(), "Header/Footer out of page?" );
1587 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
1588 : {
1589 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
1590 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
1591 : {
1592 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1593 : OSL_ENSURE( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" );
1594 : const SwFmtVertOrient &rVert =
1595 0 : pFly->GetFmt()->GetVertOrient();
1596 : // When do we have to invalidate?
1597 : // If a frame is aligned on a PageTextArea and the header
1598 : // changes a TOP, MIDDLE or NONE aligned frame needs to
1599 : // recalculate it's position; if the footer changes a BOTTOM
1600 : // or MIDDLE aligned frame needs to recalculate it's
1601 : // position.
1602 0 : if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
1603 0 : rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) &&
1604 0 : ((IsHeaderFrm() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) ||
1605 0 : (IsFooterFrm() && rVert.GetVertOrient()!=text::VertOrientation::NONE &&
1606 0 : rVert.GetVertOrient() != text::VertOrientation::TOP)) )
1607 : {
1608 0 : pFly->_InvalidatePos();
1609 0 : pFly->_Invalidate();
1610 : }
1611 : }
1612 : }
1613 : }
1614 : }
1615 494 : return (nBrowseAdd + nReal + nAdd);
1616 : }
1617 :
1618 : /** method to perform additional actions on an invalidation (2004-05-19 #i28701#) */
1619 31644 : void SwFrm::_ActionOnInvalidation( const InvalidationType )
1620 : {
1621 : // default behaviour is to perform no additional action
1622 31644 : }
1623 :
1624 : /** method to determine, if an invalidation is allowed (2004-05-19 #i28701#) */
1625 31879 : bool SwFrm::_InvalidationAllowed( const InvalidationType ) const
1626 : {
1627 : // default behaviour is to allow invalidation
1628 31879 : return true;
1629 : }
1630 :
1631 7365 : void SwFrm::ImplInvalidateSize()
1632 : {
1633 7365 : if ( _InvalidationAllowed( INVALID_SIZE ) )
1634 : {
1635 7365 : mbValidSize = sal_False;
1636 7365 : if ( IsFlyFrm() )
1637 0 : ((SwFlyFrm*)this)->_Invalidate();
1638 : else
1639 7365 : InvalidatePage();
1640 :
1641 : // OD 2004-05-19 #i28701#
1642 7365 : _ActionOnInvalidation( INVALID_SIZE );
1643 : }
1644 7365 : }
1645 :
1646 4949 : void SwFrm::ImplInvalidatePrt()
1647 : {
1648 4949 : if ( _InvalidationAllowed( INVALID_PRTAREA ) )
1649 : {
1650 4949 : mbValidPrtArea = sal_False;
1651 4949 : if ( IsFlyFrm() )
1652 0 : ((SwFlyFrm*)this)->_Invalidate();
1653 : else
1654 4949 : InvalidatePage();
1655 :
1656 : // OD 2004-05-19 #i28701#
1657 4949 : _ActionOnInvalidation( INVALID_PRTAREA );
1658 : }
1659 4949 : }
1660 :
1661 4431 : void SwFrm::ImplInvalidatePos()
1662 : {
1663 4431 : if ( _InvalidationAllowed( INVALID_POS ) )
1664 : {
1665 4425 : mbValidPos = sal_False;
1666 4425 : if ( IsFlyFrm() )
1667 : {
1668 164 : ((SwFlyFrm*)this)->_Invalidate();
1669 : }
1670 : else
1671 : {
1672 4261 : InvalidatePage();
1673 : }
1674 :
1675 : // OD 2004-05-19 #i28701#
1676 4425 : _ActionOnInvalidation( INVALID_POS );
1677 : }
1678 4431 : }
1679 :
1680 1761 : void SwFrm::ImplInvalidateLineNum()
1681 : {
1682 1761 : if ( _InvalidationAllowed( INVALID_LINENUM ) )
1683 : {
1684 1761 : mbValidLineNum = sal_False;
1685 : OSL_ENSURE( IsTxtFrm(), "line numbers are implemented for text only" );
1686 1761 : InvalidatePage();
1687 :
1688 : // OD 2004-05-19 #i28701#
1689 1761 : _ActionOnInvalidation( INVALID_LINENUM );
1690 : }
1691 1761 : }
1692 :
1693 : /*************************************************************************
1694 : |*
1695 : |* SwFrm::ReinitializeFrmSizeAttrFlags
1696 : |*
1697 : |*************************************************************************/
1698 12 : void SwFrm::ReinitializeFrmSizeAttrFlags()
1699 : {
1700 12 : const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize();
1701 18 : if ( ATT_VAR_SIZE == rFmtSize.GetHeightSizeType() ||
1702 6 : ATT_MIN_SIZE == rFmtSize.GetHeightSizeType())
1703 : {
1704 8 : mbFixSize = sal_False;
1705 8 : if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) )
1706 : {
1707 5 : SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower();
1708 35 : while ( pFrm )
1709 25 : { pFrm->_InvalidateSize();
1710 25 : pFrm->_InvalidatePrt();
1711 25 : pFrm = pFrm->GetNext();
1712 : }
1713 5 : SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt();
1714 : // #i36991# - be save.
1715 : // E.g., a row can contain *no* content.
1716 5 : if ( pCnt )
1717 : {
1718 5 : pCnt->InvalidatePage();
1719 25 : do
1720 : {
1721 25 : pCnt->Prepare( PREP_ADJUST_FRM );
1722 25 : pCnt->_InvalidateSize();
1723 25 : pCnt = pCnt->GetNextCntntFrm();
1724 25 : } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) );
1725 : }
1726 : }
1727 : }
1728 4 : else if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
1729 : {
1730 4 : if( IsVertical() )
1731 0 : ChgSize( Size( rFmtSize.GetWidth(), Frm().Height()));
1732 : else
1733 4 : ChgSize( Size( Frm().Width(), rFmtSize.GetHeight()));
1734 : }
1735 12 : }
1736 :
1737 : /*************************************************************************
1738 : |* SwFrm::ValidateThisAndAllLowers()
1739 : *
1740 : * FME 2007-08-30 #i81146# new loop control
1741 : |*************************************************************************/
1742 0 : void SwFrm::ValidateThisAndAllLowers( const sal_uInt16 nStage )
1743 : {
1744 : // Stage 0: Only validate frames. Do not process any objects.
1745 : // Stage 1: Only validate fly frames and all of their contents.
1746 : // Stage 2: Validate all.
1747 :
1748 0 : const bool bOnlyObject = 1 == nStage;
1749 0 : const bool bIncludeObjects = 1 <= nStage;
1750 :
1751 0 : if ( !bOnlyObject || ISA(SwFlyFrm) )
1752 : {
1753 0 : mbValidSize = sal_True;
1754 0 : mbValidPrtArea = sal_True;
1755 0 : mbValidPos = sal_True;
1756 : }
1757 :
1758 0 : if ( bIncludeObjects )
1759 : {
1760 0 : const SwSortedObjs* pObjs = GetDrawObjs();
1761 0 : if ( pObjs )
1762 : {
1763 0 : const sal_uInt32 nCnt = pObjs->Count();
1764 0 : for ( sal_uInt32 i = 0; i < nCnt; ++i )
1765 : {
1766 0 : SwAnchoredObject* pAnchObj = (*pObjs)[i];
1767 0 : if ( pAnchObj->ISA(SwFlyFrm) )
1768 0 : static_cast<SwFlyFrm*>(pAnchObj)->ValidateThisAndAllLowers( 2 );
1769 0 : else if ( pAnchObj->ISA(SwAnchoredDrawObject) )
1770 0 : static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis();
1771 : }
1772 : }
1773 : }
1774 :
1775 0 : if ( IsLayoutFrm() )
1776 : {
1777 0 : SwFrm* pLower = static_cast<SwLayoutFrm*>(this)->Lower();
1778 0 : while ( pLower )
1779 : {
1780 0 : pLower->ValidateThisAndAllLowers( nStage );
1781 0 : pLower = pLower->GetNext();
1782 : }
1783 : }
1784 0 : }
1785 :
1786 : /*************************************************************************
1787 : |*
1788 : |* SwCntntFrm::GrowFrm()
1789 : |*
1790 : |*************************************************************************/
1791 6934 : SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1792 : {
1793 6934 : SWRECTFN( this )
1794 :
1795 6934 : SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1796 9198 : if( nFrmHeight > 0 &&
1797 2264 : nDist > (LONG_MAX - nFrmHeight ) )
1798 1 : nDist = LONG_MAX - nFrmHeight;
1799 :
1800 6934 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
1801 6934 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1802 6934 : const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse with Body
1803 6934 : if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() )
1804 : {
1805 3838 : if ( !bTst )
1806 : {
1807 3015 : (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
1808 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1809 3015 : if( IsVertical() && !IsVertLR() && !IsReverse() )
1810 0 : Frm().Pos().X() -= nDist;
1811 3015 : if ( GetNext() )
1812 : {
1813 1119 : GetNext()->InvalidatePos();
1814 : }
1815 : // #i28701# - Due to the new object positioning the
1816 : // frame on the next page/column can flow backward (e.g. it was moved forward
1817 : // due to the positioning of its objects ). Thus, invalivate this next frame,
1818 : // if document compatibility option 'Consider wrapping style influence on
1819 : // object positioning' is ON.
1820 1896 : else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1821 : {
1822 413 : InvalidateNextPos();
1823 : }
1824 : }
1825 3838 : return 0;
1826 : }
1827 :
1828 3096 : SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)();
1829 3096 : SwFrm *pFrm = GetUpper()->Lower();
1830 18835 : while( pFrm && nReal > 0 )
1831 12643 : { nReal -= (pFrm->Frm().*fnRect->fnGetHeight)();
1832 12643 : pFrm = pFrm->GetNext();
1833 : }
1834 :
1835 3096 : if ( !bTst )
1836 : {
1837 : //Cntnts are always resized to the wished value.
1838 2486 : long nOld = (Frm().*fnRect->fnGetHeight)();
1839 2486 : (Frm().*fnRect->fnSetHeight)( nOld + nDist );
1840 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1841 2486 : if( IsVertical()&& !IsVertLR() && !IsReverse() )
1842 2 : Frm().Pos().X() -= nDist;
1843 2486 : if ( nOld && IsInTab() )
1844 : {
1845 230 : SwTabFrm *pTab = FindTabFrm();
1846 460 : if ( pTab->GetTable()->GetHTMLTableLayout() &&
1847 230 : !pTab->IsJoinLocked() &&
1848 0 : !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
1849 : {
1850 0 : pTab->InvalidatePos();
1851 0 : pTab->SetResizeHTMLTable();
1852 : }
1853 : }
1854 : }
1855 :
1856 : //Only grow Upper if necessary.
1857 3096 : if ( nReal < nDist )
1858 : {
1859 1572 : if( GetUpper() )
1860 : {
1861 1572 : if( bTst || !GetUpper()->IsFooterFrm() )
1862 1504 : nReal = GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
1863 3008 : bTst, bInfo );
1864 : else
1865 : {
1866 68 : nReal = 0;
1867 68 : GetUpper()->InvalidateSize();
1868 : }
1869 : }
1870 : else
1871 0 : nReal = 0;
1872 : }
1873 : else
1874 1524 : nReal = nDist;
1875 :
1876 : // #i28701# - Due to the new object positioning the
1877 : // frame on the next page/column can flow backward (e.g. it was moved forward
1878 : // due to the positioning of its objects ). Thus, invalivate this next frame,
1879 : // if document compatibility option 'Consider wrapping style influence on
1880 : // object positioning' is ON.
1881 3096 : if ( !bTst )
1882 : {
1883 2486 : if ( GetNext() )
1884 : {
1885 383 : GetNext()->InvalidatePos();
1886 : }
1887 2103 : else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1888 : {
1889 1024 : InvalidateNextPos();
1890 : }
1891 : }
1892 :
1893 3096 : return nReal;
1894 : }
1895 :
1896 : /*************************************************************************
1897 : |*
1898 : |* SwCntntFrm::ShrinkFrm()
1899 : |*
1900 : |*************************************************************************/
1901 616 : SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1902 : {
1903 616 : SWRECTFN( this )
1904 : OSL_ENSURE( nDist >= 0, "nDist < 0" );
1905 : OSL_ENSURE( nDist <= (Frm().*fnRect->fnGetHeight)(),
1906 : "nDist > than current size." );
1907 :
1908 616 : if ( !bTst )
1909 : {
1910 : SwTwips nRstHeight;
1911 616 : if( GetUpper() )
1912 616 : nRstHeight = (Frm().*fnRect->fnBottomDist)
1913 616 : ( (GetUpper()->*fnRect->fnGetPrtBottom)() );
1914 : else
1915 0 : nRstHeight = 0;
1916 616 : if( nRstHeight < 0 )
1917 : {
1918 399 : SwTwips nNextHeight = 0;
1919 399 : if( GetUpper()->IsSctFrm() && nDist > LONG_MAX/2 )
1920 : {
1921 0 : SwFrm *pNxt = GetNext();
1922 0 : while( pNxt )
1923 : {
1924 0 : nNextHeight += (pNxt->Frm().*fnRect->fnGetHeight)();
1925 0 : pNxt = pNxt->GetNext();
1926 : }
1927 : }
1928 399 : nRstHeight = nDist + nRstHeight - nNextHeight;
1929 : }
1930 : else
1931 217 : nRstHeight = nDist;
1932 616 : (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() - nDist );
1933 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1934 616 : if( IsVertical() && !IsVertLR() )
1935 3 : Frm().Pos().X() += nDist;
1936 616 : nDist = nRstHeight;
1937 616 : if ( IsInTab() )
1938 : {
1939 217 : SwTabFrm *pTab = FindTabFrm();
1940 434 : if ( pTab->GetTable()->GetHTMLTableLayout() &&
1941 217 : !pTab->IsJoinLocked() &&
1942 0 : !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
1943 : {
1944 0 : pTab->InvalidatePos();
1945 0 : pTab->SetResizeHTMLTable();
1946 : }
1947 : }
1948 : }
1949 :
1950 : SwTwips nReal;
1951 616 : if( GetUpper() && nDist > 0 )
1952 : {
1953 317 : if( bTst || !GetUpper()->IsFooterFrm() )
1954 317 : nReal = GetUpper()->Shrink( nDist, bTst, bInfo );
1955 : else
1956 : {
1957 0 : nReal = 0;
1958 :
1959 : // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you,
1960 : // if there are any objects anchored inside your content, which
1961 : // overlap with the shrinking frame.
1962 : // This may lead to a footer frame that is too big, but this is better
1963 : // than looping.
1964 : // #109722# : The fix for #108745# was too strict.
1965 :
1966 0 : bool bInvalidate = true;
1967 0 : const SwRect aRect( Frm() );
1968 0 : const SwPageFrm* pPage = FindPageFrm();
1969 0 : const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : 0;
1970 0 : if( pSorted )
1971 : {
1972 0 : for ( sal_uInt16 i = 0; i < pSorted->Count(); ++i )
1973 : {
1974 0 : const SwAnchoredObject* pAnchoredObj = (*pSorted)[i];
1975 0 : const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
1976 :
1977 0 : if( aBound.Left() > aRect.Right() )
1978 0 : continue;
1979 :
1980 0 : if( aBound.IsOver( aRect ) )
1981 : {
1982 0 : const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1983 0 : if( SURROUND_THROUGHT != rFmt.GetSurround().GetSurround() )
1984 : {
1985 0 : const SwFrm* pAnchor = pAnchoredObj->GetAnchorFrm();
1986 0 : if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() )
1987 : {
1988 0 : bInvalidate = false;
1989 0 : break;
1990 : }
1991 : }
1992 : }
1993 : }
1994 : }
1995 :
1996 0 : if ( bInvalidate )
1997 0 : GetUpper()->InvalidateSize();
1998 : }
1999 : }
2000 : else
2001 299 : nReal = 0;
2002 :
2003 616 : if ( !bTst )
2004 : {
2005 : //The position of the next Frm changes for sure.
2006 616 : InvalidateNextPos();
2007 :
2008 : //If I don't have a successor I have to do the retouch by myself.
2009 616 : if ( !GetNext() )
2010 525 : SetRetouche();
2011 : }
2012 616 : return nReal;
2013 : }
2014 :
2015 : /*************************************************************************
2016 : |*
2017 : |* SwCntntFrm::Modify()
2018 : |*
2019 : |*************************************************************************/
2020 1594 : void SwCntntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
2021 : {
2022 1594 : sal_uInt8 nInvFlags = 0;
2023 :
2024 1594 : if( pNew && RES_ATTRSET_CHG == pNew->Which() )
2025 : {
2026 1517 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
2027 3034 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
2028 3034 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
2029 3034 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
2030 : while( true )
2031 : {
2032 : _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
2033 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
2034 1537 : &aOldSet, &aNewSet );
2035 1537 : if( aNIter.IsAtEnd() )
2036 1517 : break;
2037 20 : aNIter.NextItem();
2038 20 : aOIter.NextItem();
2039 : }
2040 1517 : if ( aOldSet.Count() || aNewSet.Count() )
2041 2671 : SwFrm::Modify( &aOldSet, &aNewSet );
2042 : }
2043 : else
2044 77 : _UpdateAttr( pOld, pNew, nInvFlags );
2045 :
2046 1594 : if ( nInvFlags != 0 )
2047 : {
2048 438 : SwPageFrm *pPage = FindPageFrm();
2049 438 : InvalidatePage( pPage );
2050 438 : if ( nInvFlags & 0x01 )
2051 374 : SetCompletePaint();
2052 438 : if ( nInvFlags & 0x02 )
2053 41 : _InvalidatePos();
2054 438 : if ( nInvFlags & 0x04 )
2055 31 : _InvalidateSize();
2056 438 : if ( nInvFlags & 0x88 )
2057 : {
2058 37 : if( IsInSct() && !GetPrev() )
2059 : {
2060 0 : SwSectionFrm *pSect = FindSctFrm();
2061 0 : if( pSect->ContainsAny() == this )
2062 : {
2063 0 : pSect->_InvalidatePrt();
2064 0 : pSect->InvalidatePage( pPage );
2065 : }
2066 : }
2067 37 : _InvalidatePrt();
2068 : }
2069 438 : SwFrm* mpNextFrm = GetIndNext();
2070 438 : if ( mpNextFrm && nInvFlags & 0x10)
2071 : {
2072 16 : mpNextFrm->_InvalidatePrt();
2073 16 : mpNextFrm->InvalidatePage( pPage );
2074 : }
2075 438 : if ( mpNextFrm && nInvFlags & 0x80 )
2076 : {
2077 2 : mpNextFrm->SetCompletePaint();
2078 : }
2079 438 : if ( nInvFlags & 0x20 )
2080 : {
2081 86 : SwFrm* pPrevFrm = GetPrev();
2082 86 : if ( pPrevFrm )
2083 : {
2084 32 : pPrevFrm->_InvalidatePrt();
2085 32 : pPrevFrm->InvalidatePage( pPage );
2086 : }
2087 : }
2088 438 : if ( nInvFlags & 0x40 )
2089 31 : InvalidateNextPos();
2090 : }
2091 1594 : }
2092 :
2093 1614 : void SwCntntFrm::_UpdateAttr( const SfxPoolItem* pOld, const SfxPoolItem* pNew,
2094 : sal_uInt8 &rInvFlags,
2095 : SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2096 : {
2097 1614 : bool bClear = true;
2098 1614 : sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2099 1614 : switch ( nWhich )
2100 : {
2101 : case RES_FMT_CHG:
2102 31 : rInvFlags = 0xFF;
2103 : /* no break here */
2104 :
2105 : case RES_PAGEDESC: //attribute changes (on/off)
2106 42 : if ( IsInDocBody() && !IsInTab() )
2107 : {
2108 40 : rInvFlags |= 0x02;
2109 40 : SwPageFrm *pPage = FindPageFrm();
2110 40 : if ( !GetPrev() )
2111 33 : CheckPageDescs( pPage );
2112 40 : if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() )
2113 0 : ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( sal_True );
2114 40 : SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
2115 40 : pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
2116 : }
2117 42 : break;
2118 :
2119 : case RES_UL_SPACE:
2120 : {
2121 : // OD 2004-02-18 #106629# - correction
2122 : // Invalidation of the printing area of next frame, not only
2123 : // for footnote content.
2124 6 : if ( !GetIndNext() )
2125 : {
2126 6 : SwFrm* pNxt = FindNext();
2127 6 : if ( pNxt )
2128 : {
2129 0 : SwPageFrm* pPg = pNxt->FindPageFrm();
2130 0 : pNxt->InvalidatePage( pPg );
2131 0 : pNxt->_InvalidatePrt();
2132 0 : if( pNxt->IsSctFrm() )
2133 : {
2134 0 : SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2135 0 : if( pCnt )
2136 : {
2137 0 : pCnt->_InvalidatePrt();
2138 0 : pCnt->InvalidatePage( pPg );
2139 : }
2140 : }
2141 0 : pNxt->SetCompletePaint();
2142 : }
2143 : }
2144 : // OD 2004-03-17 #i11860#
2145 6 : if ( GetIndNext() &&
2146 0 : !GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
2147 : {
2148 : // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)>
2149 0 : GetIndNext()->InvalidateObjs( true );
2150 : }
2151 6 : Prepare( PREP_UL_SPACE ); //TxtFrm has to correct line spacing.
2152 6 : rInvFlags |= 0x80;
2153 : /* no break here */
2154 : }
2155 : case RES_LR_SPACE:
2156 : case RES_BOX:
2157 : case RES_SHADOW:
2158 55 : Prepare( PREP_FIXSIZE_CHG );
2159 55 : SwFrm::Modify( pOld, pNew );
2160 55 : rInvFlags |= 0x30;
2161 55 : break;
2162 :
2163 : case RES_BREAK:
2164 : {
2165 0 : rInvFlags |= 0x42;
2166 0 : const IDocumentSettingAccess* pIDSA = GetUpper()->GetFmt()->getIDocumentSettingAccess();
2167 0 : if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
2168 0 : pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) )
2169 : {
2170 0 : rInvFlags |= 0x1;
2171 0 : SwFrm* pNxt = FindNext();
2172 0 : if( pNxt )
2173 : {
2174 0 : SwPageFrm* pPg = pNxt->FindPageFrm();
2175 0 : pNxt->InvalidatePage( pPg );
2176 0 : pNxt->_InvalidatePrt();
2177 0 : if( pNxt->IsSctFrm() )
2178 : {
2179 0 : SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2180 0 : if( pCnt )
2181 : {
2182 0 : pCnt->_InvalidatePrt();
2183 0 : pCnt->InvalidatePage( pPg );
2184 : }
2185 : }
2186 0 : pNxt->SetCompletePaint();
2187 : }
2188 : }
2189 : }
2190 0 : break;
2191 :
2192 : // OD 2004-02-26 #i25029#
2193 : case RES_PARATR_CONNECT_BORDER:
2194 : {
2195 0 : rInvFlags |= 0x01;
2196 0 : if ( IsTxtFrm() )
2197 : {
2198 0 : InvalidateNextPrtArea();
2199 : }
2200 0 : if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() )
2201 : {
2202 0 : FindTabFrm()->InvalidateSize();
2203 : }
2204 : }
2205 0 : break;
2206 :
2207 : case RES_PARATR_TABSTOP:
2208 : case RES_CHRATR_PROPORTIONALFONTSIZE:
2209 : case RES_CHRATR_SHADOWED:
2210 : case RES_CHRATR_AUTOKERN:
2211 : case RES_CHRATR_UNDERLINE:
2212 : case RES_CHRATR_OVERLINE:
2213 : case RES_CHRATR_KERNING:
2214 : case RES_CHRATR_FONT:
2215 : case RES_CHRATR_FONTSIZE:
2216 : case RES_CHRATR_ESCAPEMENT:
2217 : case RES_CHRATR_CONTOUR:
2218 : case RES_PARATR_NUMRULE:
2219 343 : rInvFlags |= 0x01;
2220 343 : break;
2221 :
2222 :
2223 : case RES_FRM_SIZE:
2224 0 : rInvFlags |= 0x01;
2225 : /* no break here */
2226 :
2227 : default:
2228 1174 : bClear = false;
2229 : }
2230 1614 : if ( bClear )
2231 : {
2232 440 : if ( pOldSet || pNewSet )
2233 : {
2234 367 : if ( pOldSet )
2235 367 : pOldSet->ClearItem( nWhich );
2236 734 : if ( pNewSet )
2237 367 : pNewSet->ClearItem( nWhich );
2238 : }
2239 : else
2240 73 : SwFrm::Modify( pOld, pNew );
2241 : }
2242 1614 : }
2243 :
2244 : /*************************************************************************
2245 : |*
2246 : |* SwLayoutFrm::SwLayoutFrm()
2247 : |*
2248 : |*************************************************************************/
2249 5687 : SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt, SwFrm* pSib ):
2250 : SwFrm( pFmt, pSib ),
2251 5687 : pLower( 0 )
2252 : {
2253 5687 : const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize();
2254 5687 : if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
2255 1370 : mbFixSize = sal_True;
2256 5687 : }
2257 :
2258 : // #i28701#
2259 45932 : TYPEINIT1(SwLayoutFrm,SwFrm);
2260 : /*--------------------------------------------------
2261 : * SwLayoutFrm::InnerHeight()
2262 : * --------------------------------------------------*/
2263 :
2264 313 : SwTwips SwLayoutFrm::InnerHeight() const
2265 : {
2266 313 : if( !Lower() )
2267 15 : return 0;
2268 298 : SwTwips nRet = 0;
2269 298 : const SwFrm* pCnt = Lower();
2270 298 : SWRECTFN( this )
2271 298 : if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() )
2272 : {
2273 44 : do
2274 : {
2275 44 : SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight();
2276 44 : if( pCnt->GetValidPrtAreaFlag() )
2277 44 : nTmp += (pCnt->Frm().*fnRect->fnGetHeight)() -
2278 44 : (pCnt->Prt().*fnRect->fnGetHeight)();
2279 44 : if( nRet < nTmp )
2280 36 : nRet = nTmp;
2281 44 : pCnt = pCnt->GetNext();
2282 : } while ( pCnt );
2283 : }
2284 : else
2285 : {
2286 271 : do
2287 : {
2288 271 : nRet += (pCnt->Frm().*fnRect->fnGetHeight)();
2289 271 : if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() )
2290 0 : nRet += ((SwTxtFrm*)pCnt)->GetParHeight() -
2291 0 : (pCnt->Prt().*fnRect->fnGetHeight)();
2292 271 : if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() )
2293 44 : nRet += ((SwLayoutFrm*)pCnt)->InnerHeight() -
2294 44 : (pCnt->Prt().*fnRect->fnGetHeight)();
2295 271 : pCnt = pCnt->GetNext();
2296 : } while( pCnt );
2297 :
2298 : }
2299 298 : return nRet;
2300 : }
2301 :
2302 : /*************************************************************************
2303 : |*
2304 : |* SwLayoutFrm::GrowFrm()
2305 : |*
2306 : |*************************************************************************/
2307 3775 : SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2308 : {
2309 3775 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
2310 3775 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2311 3775 : const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse with Body
2312 3775 : if( !(GetType() & nTmpType) && HasFixSize() )
2313 643 : return 0;
2314 :
2315 3132 : SWRECTFN( this )
2316 3132 : const SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2317 3132 : const SwTwips nFrmPos = Frm().Pos().X();
2318 :
2319 3132 : if ( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
2320 463 : nDist = LONG_MAX - nFrmHeight;
2321 :
2322 3132 : SwTwips nMin = 0;
2323 3132 : if ( GetUpper() && !IsCellFrm() )
2324 : {
2325 1916 : SwFrm *pFrm = GetUpper()->Lower();
2326 9640 : while( pFrm )
2327 5808 : { nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2328 5808 : pFrm = pFrm->GetNext();
2329 : }
2330 1916 : nMin = (GetUpper()->Prt().*fnRect->fnGetHeight)() - nMin;
2331 1916 : if ( nMin < 0 )
2332 64 : nMin = 0;
2333 : }
2334 :
2335 3132 : SwRect aOldFrm( Frm() );
2336 3132 : bool bMoveAccFrm = false;
2337 :
2338 3132 : bool bChgPos = IsVertical() && !IsReverse();
2339 3132 : if ( !bTst )
2340 : {
2341 2097 : (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
2342 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2343 2097 : if( bChgPos && !IsVertLR() )
2344 0 : Frm().Pos().X() -= nDist;
2345 2097 : bMoveAccFrm = true;
2346 : }
2347 :
2348 3132 : SwTwips nReal = nDist - nMin;
2349 3132 : if ( nReal > 0 )
2350 : {
2351 3122 : if ( GetUpper() )
2352 : { // AdjustNeighbourhood now only for the columns (but not in frames)
2353 3122 : sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
2354 343 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2355 3465 : : NA_GROW_SHRINK;
2356 3122 : if( NA_ONLY_ADJUST == nAdjust )
2357 209 : nReal = AdjustNeighbourhood( nReal, bTst );
2358 : else
2359 : {
2360 2913 : if( NA_ADJUST_GROW == nAdjust )
2361 0 : nReal += AdjustNeighbourhood( nReal, bTst );
2362 :
2363 2913 : SwTwips nGrow = 0;
2364 2913 : if( 0 < nReal )
2365 : {
2366 2913 : SwFrm* pToGrow = GetUpper();
2367 : // NEW TABLES
2368 : // A cell with a row span of > 1 is allowed to grow the
2369 : // line containing the end of the row span if it is
2370 : // located in the same table frame:
2371 2913 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2372 2913 : if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2373 : {
2374 0 : SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2375 0 : if ( -1 == rEndCell.GetTabBox()->getRowSpan() )
2376 0 : pToGrow = rEndCell.GetUpper();
2377 : else
2378 0 : pToGrow = 0;
2379 : }
2380 :
2381 2913 : nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0;
2382 : }
2383 :
2384 2913 : if( NA_GROW_ADJUST == nAdjust && nGrow < nReal )
2385 0 : nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
2386 :
2387 2913 : if ( IsFtnFrm() && (nGrow != nReal) && GetNext() )
2388 : {
2389 : //Footnotes can replace their successor.
2390 0 : SwTwips nSpace = bTst ? 0 : -nDist;
2391 0 : const SwFrm *pFrm = GetUpper()->Lower();
2392 0 : do
2393 0 : { nSpace += (pFrm->Frm().*fnRect->fnGetHeight)();
2394 0 : pFrm = pFrm->GetNext();
2395 0 : } while ( pFrm != GetNext() );
2396 0 : nSpace = (GetUpper()->Prt().*fnRect->fnGetHeight)() -nSpace;
2397 0 : if ( nSpace < 0 )
2398 0 : nSpace = 0;
2399 0 : nSpace += nGrow;
2400 0 : if ( nReal > nSpace )
2401 0 : nReal = nSpace;
2402 0 : if ( nReal && !bTst )
2403 0 : ((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() );
2404 : }
2405 : else
2406 2913 : nReal = nGrow;
2407 : }
2408 : }
2409 : else
2410 0 : nReal = 0;
2411 :
2412 3122 : nReal += nMin;
2413 : }
2414 : else
2415 10 : nReal = nDist;
2416 :
2417 3132 : if ( !bTst )
2418 : {
2419 2718 : if( nReal != nDist &&
2420 : // NEW TABLES
2421 696 : ( !IsCellFrm() || static_cast<SwCellFrm*>(this)->GetLayoutRowSpan() > 1 ) )
2422 : {
2423 182 : (Frm().*fnRect->fnSetHeight)( nFrmHeight + nReal );
2424 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2425 182 : if( bChgPos && !IsVertLR() )
2426 0 : Frm().Pos().X() = nFrmPos - nReal;
2427 182 : bMoveAccFrm = true;
2428 : }
2429 :
2430 2097 : if ( nReal )
2431 : {
2432 1660 : SwPageFrm *pPage = FindPageFrm();
2433 1660 : if ( GetNext() )
2434 : {
2435 941 : GetNext()->_InvalidatePos();
2436 941 : if ( GetNext()->IsCntntFrm() )
2437 0 : GetNext()->InvalidatePage( pPage );
2438 : }
2439 1660 : if ( !IsPageBodyFrm() )
2440 : {
2441 1658 : _InvalidateAll();
2442 1658 : InvalidatePage( pPage );
2443 : }
2444 1660 : if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2445 790 : NotifyLowerObjs();
2446 :
2447 1660 : if( IsCellFrm() )
2448 497 : InvaPercentLowers( nReal );
2449 :
2450 1660 : const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
2451 1660 : if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2452 1 : SetCompletePaint();
2453 : }
2454 : }
2455 :
2456 3132 : if( bMoveAccFrm && IsAccessibleFrm() )
2457 : {
2458 1008 : SwRootFrm *pRootFrm = getRootFrm();
2459 1008 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2460 0 : pRootFrm->GetCurrShell() )
2461 : {
2462 0 : pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2463 : }
2464 : }
2465 3132 : return nReal;
2466 : }
2467 :
2468 : /*************************************************************************
2469 : |*
2470 : |* SwLayoutFrm::ShrinkFrm()
2471 : |*
2472 : |*************************************************************************/
2473 1469 : SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2474 : {
2475 1469 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
2476 1469 : const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2477 1469 : const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
2478 1469 : if( !(GetType() & nTmpType) && HasFixSize() )
2479 457 : return 0;
2480 :
2481 : OSL_ENSURE( nDist >= 0, "nDist < 0" );
2482 1012 : SWRECTFN( this )
2483 1012 : SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2484 1012 : if ( nDist > nFrmHeight )
2485 38 : nDist = nFrmHeight;
2486 :
2487 1012 : SwTwips nMin = 0;
2488 1012 : bool bChgPos = IsVertical() && !IsReverse();
2489 1012 : if ( Lower() )
2490 : {
2491 970 : if( !Lower()->IsNeighbourFrm() )
2492 970 : { const SwFrm *pFrm = Lower();
2493 970 : const long nTmp = (Prt().*fnRect->fnGetHeight)();
2494 4976 : while( pFrm && nMin < nTmp )
2495 3036 : { nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2496 3036 : pFrm = pFrm->GetNext();
2497 : }
2498 : }
2499 : }
2500 1012 : SwTwips nReal = nDist;
2501 1012 : SwTwips nMinDiff = (Prt().*fnRect->fnGetHeight)() - nMin;
2502 1012 : if( nReal > nMinDiff )
2503 0 : nReal = nMinDiff;
2504 1012 : if( nReal <= 0 )
2505 0 : return nDist;
2506 :
2507 1012 : SwRect aOldFrm( Frm() );
2508 1012 : bool bMoveAccFrm = false;
2509 :
2510 1012 : SwTwips nRealDist = nReal;
2511 1012 : if ( !bTst )
2512 : {
2513 1012 : (Frm().*fnRect->fnSetHeight)( nFrmHeight - nReal );
2514 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2515 1012 : if( bChgPos && !IsVertLR() )
2516 0 : Frm().Pos().X() += nReal;
2517 1012 : bMoveAccFrm = true;
2518 : }
2519 :
2520 2024 : sal_uInt8 nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ?
2521 65 : ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2522 1077 : : NA_GROW_SHRINK;
2523 :
2524 : // AdjustNeighbourhood also in columns (but not in frames)
2525 1012 : if( NA_ONLY_ADJUST == nAdjust )
2526 : {
2527 21 : if ( IsPageBodyFrm() && !bBrowse )
2528 0 : nReal = nDist;
2529 : else
2530 21 : { nReal = AdjustNeighbourhood( -nReal, bTst );
2531 21 : nReal *= -1;
2532 21 : if ( !bTst && IsBodyFrm() && nReal < nRealDist )
2533 : {
2534 8 : (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2535 8 : + nRealDist - nReal );
2536 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2537 4 : if( bChgPos && !IsVertLR() )
2538 0 : Frm().Pos().X() += nRealDist - nReal;
2539 : OSL_ENSURE( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2540 : }
2541 : }
2542 : }
2543 991 : else if( IsColumnFrm() || IsColBodyFrm() )
2544 : {
2545 88 : SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo );
2546 88 : if ( nTmp != nReal )
2547 : {
2548 152 : (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2549 152 : + nReal - nTmp );
2550 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2551 76 : if( bChgPos && !IsVertLR() )
2552 0 : Frm().Pos().X() += nTmp - nReal;
2553 : OSL_ENSURE( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2554 76 : nReal = nTmp;
2555 : }
2556 : }
2557 : else
2558 : {
2559 903 : SwTwips nShrink = nReal;
2560 903 : SwFrm* pToShrink = GetUpper();
2561 903 : const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2562 : // NEW TABLES
2563 903 : if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2564 : {
2565 0 : SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2566 0 : pToShrink = rEndCell.GetUpper();
2567 : }
2568 :
2569 903 : nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0;
2570 903 : if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
2571 0 : && nReal < nShrink )
2572 0 : AdjustNeighbourhood( nReal - nShrink );
2573 : }
2574 :
2575 1012 : if( bMoveAccFrm && IsAccessibleFrm() )
2576 : {
2577 905 : SwRootFrm *pRootFrm = getRootFrm();
2578 905 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2579 0 : pRootFrm->GetCurrShell() )
2580 : {
2581 0 : pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2582 : }
2583 : }
2584 1012 : if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) )
2585 : {
2586 221 : SwPageFrm *pPage = FindPageFrm();
2587 221 : if ( GetNext() )
2588 : {
2589 96 : GetNext()->_InvalidatePos();
2590 96 : if ( GetNext()->IsCntntFrm() )
2591 28 : GetNext()->InvalidatePage( pPage );
2592 96 : if ( IsTabFrm() )
2593 80 : ((SwTabFrm*)this)->SetComplete();
2594 : }
2595 : else
2596 125 : { if ( IsRetoucheFrm() )
2597 5 : SetRetouche();
2598 125 : if ( IsTabFrm() )
2599 : {
2600 0 : if( IsTabFrm() )
2601 0 : ((SwTabFrm*)this)->SetComplete();
2602 0 : if ( Lower() ) // Can also be in the Join and be empty!
2603 0 : InvalidateNextPos();
2604 : }
2605 : }
2606 221 : if ( !IsBodyFrm() )
2607 : {
2608 173 : _InvalidateAll();
2609 173 : InvalidatePage( pPage );
2610 173 : const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
2611 173 : if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2612 0 : SetCompletePaint();
2613 : }
2614 :
2615 221 : if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2616 126 : NotifyLowerObjs();
2617 :
2618 221 : if( IsCellFrm() )
2619 65 : InvaPercentLowers( nReal );
2620 :
2621 : SwCntntFrm *pCnt;
2622 452 : if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() &&
2623 5 : ( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER ||
2624 221 : ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) &&
2625 : 0 != (pCnt = ((SwFtnFrm*)this)->GetRefFromAttr() ) )
2626 : {
2627 5 : if ( pCnt->IsFollow() )
2628 : { // If we are in an other column/page than the frame with the
2629 : // reference, we don't need to invalidate its master.
2630 0 : SwFrm *pTmp = pCnt->FindFtnBossFrm(sal_True) == FindFtnBossFrm(sal_True)
2631 0 : ? pCnt->FindMaster()->GetFrm() : pCnt;
2632 0 : pTmp->Prepare( PREP_ADJUST_FRM );
2633 0 : pTmp->InvalidateSize();
2634 : }
2635 : else
2636 5 : pCnt->InvalidatePos();
2637 : }
2638 : }
2639 1012 : return nReal;
2640 : }
2641 :
2642 : /**
2643 : * Changes the size of the directly subsidiary Frm's that have a fixed size, proportionally to the
2644 : * size change of the PrtArea of the Frm's.
2645 : *
2646 : * The variable Frms are also proportionally adapted; they will grow/shrink again by themselves.
2647 : */
2648 5248 : void SwLayoutFrm::ChgLowersProp( const Size& rOldSize )
2649 : {
2650 : // no change of lower properties for root frame or if no lower exists.
2651 5248 : if ( IsRootFrm() || !Lower() )
2652 2112 : return;
2653 :
2654 : // declare and init <SwFrm* pLowerFrm> with first lower
2655 3136 : SwFrm *pLowerFrm = Lower();
2656 :
2657 : // declare and init const booleans <bHeightChgd> and <bWidthChg>
2658 3136 : const bool bHeightChgd = rOldSize.Height() != Prt().Height();
2659 3136 : const bool bWidthChgd = rOldSize.Width() != Prt().Width();
2660 :
2661 : // declare and init variables <bVert>, <bRev> and <fnRect>
2662 3136 : SWRECTFN( this )
2663 :
2664 : // This shortcut basically tries to handle only lower frames that
2665 : // are affected by the size change. Otherwise much more lower frames
2666 : // are invalidated.
2667 7206 : if ( !( bVert ? bHeightChgd : bWidthChgd ) &&
2668 4118 : ! Lower()->IsColumnFrm() &&
2669 1822 : ( ( IsBodyFrm() && IsInDocBody() && ( !IsInSct() || !FindSctFrm()->IsColLocked() ) ) ||
2670 : // #i10826# Section frames without columns should not
2671 : // invalidate all lowers!
2672 800 : IsSctFrm() ) )
2673 : {
2674 : // Determine page frame the body frame resp. the section frame belongs to.
2675 92 : SwPageFrm *pPage = FindPageFrm();
2676 : // Determine last lower by traveling through them using <GetNext()>.
2677 : // During travel check each section frame, if it will be sized to
2678 : // maximum. If Yes, invalidate size of section frame and set
2679 : // corresponding flags at the page.
2680 : do
2681 : {
2682 128 : if( pLowerFrm->IsSctFrm() &&((SwSectionFrm*)pLowerFrm)->_ToMaximize() )
2683 : {
2684 0 : pLowerFrm->_InvalidateSize();
2685 0 : pLowerFrm->InvalidatePage( pPage );
2686 : }
2687 128 : if( pLowerFrm->GetNext() )
2688 36 : pLowerFrm = pLowerFrm->GetNext();
2689 : else
2690 92 : break;
2691 : } while( true );
2692 : // If found last lower is a section frame containing no section
2693 : // (section frame isn't valid and will be deleted in the future),
2694 : // travel backwards.
2695 184 : while( pLowerFrm->IsSctFrm() && !((SwSectionFrm*)pLowerFrm)->GetSection() &&
2696 0 : pLowerFrm->GetPrev() )
2697 0 : pLowerFrm = pLowerFrm->GetPrev();
2698 : // If found last lower is a section frame, set <pLowerFrm> to its last
2699 : // content, if the section frame is valid and is not sized to maximum.
2700 : // Otherwise set <pLowerFrm> to NULL - In this case body frame only
2701 : // contains invalid section frames.
2702 92 : if( pLowerFrm->IsSctFrm() )
2703 0 : pLowerFrm = ((SwSectionFrm*)pLowerFrm)->GetSection() &&
2704 0 : !((SwSectionFrm*)pLowerFrm)->ToMaximize( sal_False ) ?
2705 0 : ((SwSectionFrm*)pLowerFrm)->FindLastCntnt() : NULL;
2706 :
2707 : // continue with found last lower, probably the last content of a section
2708 92 : if ( pLowerFrm )
2709 : {
2710 : // If <pLowerFrm> is in a table frame, set <pLowerFrm> to this table
2711 : // frame and continue.
2712 92 : if ( pLowerFrm->IsInTab() )
2713 : {
2714 : // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrm> to
2715 : // its table frame - check, if the table frame is also a lower
2716 : // of the body frame, in order to assure that <pLowerFrm> is not
2717 : // set to a frame, which is an *upper* of the body frame.
2718 0 : SwFrm* pTableFrm = pLowerFrm->FindTabFrm();
2719 0 : if ( IsAnLower( pTableFrm ) )
2720 : {
2721 0 : pLowerFrm = pTableFrm;
2722 : }
2723 : }
2724 : // Check, if variable size of body frame resp. section frame has grown
2725 : // OD 28.10.2002 #97265# - correct check, if variable size has grown.
2726 92 : SwTwips nOldHeight = bVert ? rOldSize.Width() : rOldSize.Height();
2727 92 : if( nOldHeight < (Prt().*fnRect->fnGetHeight)() )
2728 : {
2729 : // If variable size of body|section frame has grown, only found
2730 : // last lower and the position of the its next have to be invalidated.
2731 16 : pLowerFrm->_InvalidateAll();
2732 16 : pLowerFrm->InvalidatePage( pPage );
2733 32 : if( !pLowerFrm->IsFlowFrm() ||
2734 16 : !SwFlowFrm::CastFlowFrm( pLowerFrm )->HasFollow() )
2735 16 : pLowerFrm->InvalidateNextPos( sal_True );
2736 16 : if ( pLowerFrm->IsTxtFrm() )
2737 16 : ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2738 : }
2739 : else
2740 : {
2741 : // variable size of body|section frame has shrinked. Thus,
2742 : // invalidate all lowers not matching the new body|section size
2743 : // and the dedicated new last lower.
2744 76 : if( bVert )
2745 : {
2746 0 : SwTwips nBot = Frm().Left() + Prt().Left();
2747 0 : while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Left() < nBot )
2748 : {
2749 0 : pLowerFrm->_InvalidateAll();
2750 0 : pLowerFrm->InvalidatePage( pPage );
2751 0 : pLowerFrm = pLowerFrm->GetPrev();
2752 : }
2753 : }
2754 : else
2755 : {
2756 76 : SwTwips nBot = Frm().Top() + Prt().Bottom();
2757 152 : while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Top() > nBot )
2758 : {
2759 0 : pLowerFrm->_InvalidateAll();
2760 0 : pLowerFrm->InvalidatePage( pPage );
2761 0 : pLowerFrm = pLowerFrm->GetPrev();
2762 : }
2763 : }
2764 76 : if ( pLowerFrm )
2765 : {
2766 76 : pLowerFrm->_InvalidateSize();
2767 76 : pLowerFrm->InvalidatePage( pPage );
2768 76 : if ( pLowerFrm->IsTxtFrm() )
2769 76 : ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2770 : }
2771 : }
2772 : // #i41694# - improvement by removing duplicates
2773 92 : if ( pLowerFrm )
2774 : {
2775 92 : if ( pLowerFrm->IsInSct() )
2776 : {
2777 : // #i41694# - follow-up of issue #i10826#
2778 : // No invalidation of section frame, if it's the this.
2779 2 : SwFrm* pSectFrm = pLowerFrm->FindSctFrm();
2780 2 : if( pSectFrm != this && IsAnLower( pSectFrm ) )
2781 : {
2782 0 : pSectFrm->_InvalidateSize();
2783 0 : pSectFrm->InvalidatePage( pPage );
2784 : }
2785 : }
2786 : }
2787 : }
2788 128 : return;
2789 : } // end of { special case }
2790 :
2791 :
2792 : // Invalidate page for content only once.
2793 3044 : bool bInvaPageForCntnt = true;
2794 :
2795 : // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame
2796 : // adjustment, if fixed/variable size has changed.
2797 : bool bFixChgd, bVarChgd;
2798 3044 : if( bVert == pLowerFrm->IsNeighbourFrm() )
2799 : {
2800 2997 : bFixChgd = bWidthChgd;
2801 2997 : bVarChgd = bHeightChgd;
2802 : }
2803 : else
2804 : {
2805 47 : bFixChgd = bHeightChgd;
2806 47 : bVarChgd = bWidthChgd;
2807 : }
2808 :
2809 : // Declare const unsigned short <nFixWidth> and init it this frame types
2810 : // which has fixed width in vertical respectively horizontal layout.
2811 : // In vertical layout these are neighbour frames (cell and column frames),
2812 : // header frames and footer frames.
2813 : // In horizontal layout these are all frames, which aren't neighbour frames.
2814 : const sal_uInt16 nFixWidth = bVert ? (FRM_NEIGHBOUR | FRM_HEADFOOT)
2815 3044 : : ~FRM_NEIGHBOUR;
2816 :
2817 : // Declare const unsigned short <nFixHeight> and init it this frame types
2818 : // which has fixed height in vertical respectively horizontal layout.
2819 : // In vertical layout these are all frames, which aren't neighbour frames,
2820 : // header frames, footer frames, body frames or foot note container frames.
2821 : // In horizontal layout these are neighbour frames.
2822 : const sal_uInt16 nFixHeight= bVert ? ~(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC)
2823 3044 : : FRM_NEIGHBOUR;
2824 :
2825 : // Travel through all lowers using <GetNext()>
2826 9982 : while ( pLowerFrm )
2827 : {
2828 3894 : if ( pLowerFrm->IsTxtFrm() )
2829 : {
2830 : // Text frames will only be invalidated - prepare invalidation
2831 2825 : if ( bFixChgd )
2832 2172 : static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_FIXSIZE_CHG );
2833 2825 : if ( bVarChgd )
2834 1950 : static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2835 : }
2836 : else
2837 : {
2838 : // If lower isn't a table, row, cell or section frame, adjust its
2839 : // frame size.
2840 1069 : const sal_uInt16 nLowerType = pLowerFrm->GetType();
2841 1069 : if ( !(nLowerType & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) )
2842 : {
2843 569 : if ( bWidthChgd )
2844 : {
2845 283 : if( nLowerType & nFixWidth )
2846 : {
2847 : // Considering previous conditions:
2848 : // In vertical layout set width of column, header and
2849 : // footer frames to its upper width.
2850 : // In horizontal layout set width of header, footer,
2851 : // foot note container, foot note, body and no-text
2852 : // frames to its upper width.
2853 282 : pLowerFrm->Frm().Width( Prt().Width() );
2854 : }
2855 1 : else if( rOldSize.Width() && !pLowerFrm->IsFtnFrm() )
2856 : {
2857 : // Adjust frame width proportional, if lower isn't a
2858 : // foot note frame and condition <nLowerType & nFixWidth>
2859 : // isn't true.
2860 : // Considering previous conditions:
2861 : // In vertical layout these are foot note container,
2862 : // body and no-text frames.
2863 : // In horizontal layout these are column and no-text frames.
2864 : // OD 24.10.2002 #97265# - <double> calculation
2865 : // Perform <double> calculation of new width, if
2866 : // one of the coefficients is greater than 50000
2867 : SwTwips nNewWidth;
2868 2 : if ( (pLowerFrm->Frm().Width() > 50000) ||
2869 1 : (Prt().Width() > 50000) )
2870 : {
2871 : double nNewWidthTmp =
2872 0 : ( double(pLowerFrm->Frm().Width())
2873 0 : * double(Prt().Width()) )
2874 0 : / double(rOldSize.Width());
2875 0 : nNewWidth = SwTwips(nNewWidthTmp);
2876 : }
2877 : else
2878 : {
2879 : nNewWidth =
2880 1 : (pLowerFrm->Frm().Width() * Prt().Width()) / rOldSize.Width();
2881 : }
2882 1 : pLowerFrm->Frm().Width( nNewWidth );
2883 : }
2884 : }
2885 569 : if ( bHeightChgd )
2886 : {
2887 530 : if( nLowerType & nFixHeight )
2888 : {
2889 : // Considering previous conditions:
2890 : // In vertical layout set height of foot note and
2891 : // no-text frames to its upper height.
2892 : // In horizontal layout set height of column frames
2893 : // to its upper height.
2894 136 : pLowerFrm->Frm().Height( Prt().Height() );
2895 : }
2896 : // OD 01.10.2002 #102211#
2897 : // add conditions <!pLowerFrm->IsHeaderFrm()> and
2898 : // <!pLowerFrm->IsFooterFrm()> in order to avoid that
2899 : // the <Grow> of header or footer are overwritten.
2900 : // NOTE: Height of header/footer frame is determined by contents.
2901 963 : else if ( rOldSize.Height() &&
2902 349 : !pLowerFrm->IsFtnFrm() &&
2903 742 : !pLowerFrm->IsHeaderFrm() &&
2904 174 : !pLowerFrm->IsFooterFrm()
2905 : )
2906 : {
2907 : // Adjust frame height proportional, if lower isn't a
2908 : // foot note, a header or a footer frame and
2909 : // condition <nLowerType & nFixHeight> isn't true.
2910 : // Considering previous conditions:
2911 : // In vertical layout these are column, foot note container,
2912 : // body and no-text frames.
2913 : // In horizontal layout these are column, foot note
2914 : // container, body and no-text frames.
2915 :
2916 : // OD 29.10.2002 #97265# - special case for page lowers
2917 : // The page lowers that have to be adjusted on page height
2918 : // change are the body frame and the foot note container
2919 : // frame.
2920 : // In vertical layout the height of both is directly
2921 : // adjusted to the page height change.
2922 : // In horizontal layout the height of the body frame is
2923 : // directly adjsuted to the page height change and the
2924 : // foot note frame height isn't touched, because its
2925 : // determined by its content.
2926 : // OD 31.03.2003 #108446# - apply special case for page
2927 : // lowers - see description above - also for section columns.
2928 498 : if ( IsPageFrm() ||
2929 304 : ( IsColumnFrm() && IsInSct() )
2930 : )
2931 : {
2932 : OSL_ENSURE( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm(),
2933 : "ChgLowersProp - only for body or foot note container" );
2934 170 : if ( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm() )
2935 : {
2936 170 : if ( IsVertical() || pLowerFrm->IsBodyFrm() )
2937 : {
2938 : SwTwips nNewHeight =
2939 170 : pLowerFrm->Frm().Height() +
2940 170 : ( Prt().Height() - rOldSize.Height() );
2941 170 : if ( nNewHeight < 0)
2942 : {
2943 : // OD 01.04.2003 #108446# - adjust assertion condition and text
2944 : OSL_ENSURE( !( IsPageFrm() &&
2945 : (pLowerFrm->Frm().Height()>0) &&
2946 : (pLowerFrm->IsValid()) ),
2947 : "ChgLowersProg - negative height for lower.");
2948 0 : nNewHeight = 0;
2949 : }
2950 170 : pLowerFrm->Frm().Height( nNewHeight );
2951 : }
2952 : }
2953 : }
2954 : else
2955 : {
2956 : SwTwips nNewHeight;
2957 : // OD 24.10.2002 #97265# - <double> calculation
2958 : // Perform <double> calculation of new height, if
2959 : // one of the coefficients is greater than 50000
2960 8 : if ( (pLowerFrm->Frm().Height() > 50000) ||
2961 4 : (Prt().Height() > 50000) )
2962 : {
2963 : double nNewHeightTmp =
2964 0 : ( double(pLowerFrm->Frm().Height())
2965 0 : * double(Prt().Height()) )
2966 0 : / double(rOldSize.Height());
2967 0 : nNewHeight = SwTwips(nNewHeightTmp);
2968 : }
2969 : else
2970 : {
2971 4 : nNewHeight = ( pLowerFrm->Frm().Height()
2972 4 : * Prt().Height() ) / rOldSize.Height();
2973 : }
2974 4 : if( !pLowerFrm->GetNext() )
2975 : {
2976 4 : SwTwips nSum = Prt().Height();
2977 4 : SwFrm* pTmp = Lower();
2978 8 : while( pTmp->GetNext() )
2979 : {
2980 0 : if( !pTmp->IsFtnContFrm() || !pTmp->IsVertical() )
2981 0 : nSum -= pTmp->Frm().Height();
2982 0 : pTmp = pTmp->GetNext();
2983 : }
2984 4 : if( nSum - nNewHeight == 1 &&
2985 0 : nSum == pLowerFrm->Frm().Height() )
2986 0 : nNewHeight = nSum;
2987 : }
2988 4 : pLowerFrm->Frm().Height( nNewHeight );
2989 : }
2990 : }
2991 : }
2992 : }
2993 : } // end of else { NOT text frame }
2994 :
2995 3894 : pLowerFrm->_InvalidateAll();
2996 3894 : if ( bInvaPageForCntnt && pLowerFrm->IsCntntFrm() )
2997 : {
2998 2595 : pLowerFrm->InvalidatePage();
2999 2595 : bInvaPageForCntnt = false;
3000 : }
3001 :
3002 3894 : if ( !pLowerFrm->GetNext() && pLowerFrm->IsRetoucheFrm() )
3003 : {
3004 : //If a growth took place and the subordinate elements can retouch
3005 : //itself (currently Tabs, Sections and Cntnt) we trigger it.
3006 3491 : if ( rOldSize.Height() < Prt().SSize().Height() ||
3007 849 : rOldSize.Width() < Prt().SSize().Width() )
3008 2490 : pLowerFrm->SetRetouche();
3009 : }
3010 3894 : pLowerFrm = pLowerFrm->GetNext();
3011 : }
3012 :
3013 : // Finally adjust the columns if width is set to auto
3014 : // Possible optimisation: execute this code earlier in this function and
3015 : // return???
3016 5246 : if ( ( (bVert && bHeightChgd) || (! bVert && bWidthChgd) ) &&
3017 2202 : Lower()->IsColumnFrm() )
3018 : {
3019 : // get column attribute
3020 0 : const SwFmtCol* pColAttr = NULL;
3021 0 : if ( IsPageBodyFrm() )
3022 : {
3023 : OSL_ENSURE( GetUpper()->IsPageFrm(), "Upper is not page frame" );
3024 0 : pColAttr = &GetUpper()->GetFmt()->GetCol();
3025 : }
3026 : else
3027 : {
3028 : OSL_ENSURE( IsFlyFrm() || IsSctFrm(), "Columns not in fly or section" );
3029 0 : pColAttr = &GetFmt()->GetCol();
3030 : }
3031 :
3032 0 : if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 )
3033 0 : AdjustColumns( pColAttr, sal_False );
3034 : }
3035 : }
3036 :
3037 : /** "Formats" the Frame; Frm and PrtArea.
3038 : *
3039 : * The Fixsize is not set here.
3040 : */
3041 2065 : void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs )
3042 : {
3043 : OSL_ENSURE( pAttrs, "LayoutFrm::Format, pAttrs ist 0." );
3044 :
3045 2065 : if ( mbValidPrtArea && mbValidSize )
3046 2065 : return;
3047 :
3048 2065 : const sal_uInt16 nLeft = (sal_uInt16)pAttrs->CalcLeft( this );
3049 2065 : const sal_uInt16 nUpper = pAttrs->CalcTop();
3050 :
3051 2065 : const sal_uInt16 nRight = (sal_uInt16)((SwBorderAttrs*)pAttrs)->CalcRight( this );
3052 2065 : const sal_uInt16 nLower = pAttrs->CalcBottom();
3053 2065 : bool bVert = IsVertical() && !IsPageFrm();
3054 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
3055 2065 : SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
3056 2065 : if ( !mbValidPrtArea )
3057 : {
3058 1274 : mbValidPrtArea = sal_True;
3059 1274 : (this->*fnRect->fnSetXMargins)( nLeft, nRight );
3060 1274 : (this->*fnRect->fnSetYMargins)( nUpper, nLower );
3061 : }
3062 :
3063 2065 : if ( !mbValidSize )
3064 : {
3065 2046 : if ( !HasFixSize() )
3066 : {
3067 139 : const SwTwips nBorder = nUpper + nLower;
3068 139 : const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
3069 139 : SwTwips nMinHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
3070 156 : do
3071 156 : { mbValidSize = sal_True;
3072 :
3073 : //The size in VarSize is calculated using the content plus the
3074 : // borders.
3075 156 : SwTwips nRemaining = 0;
3076 156 : SwFrm *pFrm = Lower();
3077 521 : while ( pFrm )
3078 209 : { nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
3079 209 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
3080 : // This TxtFrm would like to be a bit bigger
3081 0 : nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
3082 0 : - (pFrm->Prt().*fnRect->fnGetHeight)();
3083 209 : else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
3084 0 : nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
3085 209 : pFrm = pFrm->GetNext();
3086 : }
3087 156 : nRemaining += nBorder;
3088 156 : nRemaining = std::max( nRemaining, nMinHeight );
3089 156 : const SwTwips nDiff = nRemaining-(Frm().*fnRect->fnGetHeight)();
3090 156 : const long nOldLeft = (Frm().*fnRect->fnGetLeft)();
3091 156 : const long nOldTop = (Frm().*fnRect->fnGetTop)();
3092 156 : if ( nDiff )
3093 : {
3094 17 : if ( nDiff > 0 )
3095 17 : Grow( nDiff );
3096 : else
3097 0 : Shrink( -nDiff );
3098 : //Updates the positions using the fast channel.
3099 17 : MakePos();
3100 : }
3101 : //Don't exceed the bottom edge of the Upper.
3102 156 : if ( GetUpper() && (Frm().*fnRect->fnGetHeight)() )
3103 : {
3104 119 : const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
3105 238 : if( (this->*fnRect->fnSetLimit)( nLimit ) &&
3106 119 : nOldLeft == (Frm().*fnRect->fnGetLeft)() &&
3107 0 : nOldTop == (Frm().*fnRect->fnGetTop)() )
3108 0 : mbValidSize = mbValidPrtArea = sal_True;
3109 : }
3110 156 : } while ( !mbValidSize );
3111 : }
3112 1907 : else if ( GetType() & 0x0018 )
3113 : {
3114 1 : do
3115 1 : { if ( Frm().Height() != pAttrs->GetSize().Height() )
3116 1 : ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
3117 1 : mbValidSize = sal_True;
3118 1 : MakePos();
3119 1 : } while ( !mbValidSize );
3120 : }
3121 : else
3122 1906 : mbValidSize = sal_True;
3123 : }
3124 : }
3125 :
3126 : /*************************************************************************
3127 : |*
3128 : |* SwLayoutFrm::InvalidatePercentLowers()
3129 : |*
3130 : |*************************************************************************/
3131 51 : static void InvaPercentFlys( SwFrm *pFrm, SwTwips nDiff )
3132 : {
3133 : OSL_ENSURE( pFrm->GetDrawObjs(), "Can't find any Objects" );
3134 114 : for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
3135 : {
3136 63 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3137 63 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3138 : {
3139 17 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3140 17 : const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
3141 17 : if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3142 : {
3143 0 : bool bNotify = true;
3144 : // If we've a fly with more than 90% relative height...
3145 0 : if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrm() &&
3146 0 : rSz.GetHeightPercent() != 0xFF && nDiff )
3147 : {
3148 0 : const SwFrm *pRel = pFly->IsFlyLayFrm() ? pFly->GetAnchorFrm():
3149 0 : pFly->GetAnchorFrm()->GetUpper();
3150 : // ... and we have already more than 90% height and we
3151 : // not allow the text to go through...
3152 : // then a notifycation could cause an endless loop, e.g.
3153 : // 100% height and no text wrap inside a cell of a table.
3154 0 : if( pFly->Frm().Height()*10 >
3155 0 : ( nDiff + pRel->Prt().Height() )*9 &&
3156 0 : pFly->GetFmt()->GetSurround().GetSurround() !=
3157 : SURROUND_THROUGHT )
3158 0 : bNotify = false;
3159 : }
3160 0 : if( bNotify )
3161 0 : pFly->InvalidateSize();
3162 : }
3163 : }
3164 : }
3165 51 : }
3166 :
3167 6206 : void SwLayoutFrm::InvaPercentLowers( SwTwips nDiff )
3168 : {
3169 6206 : if ( GetDrawObjs() )
3170 0 : ::InvaPercentFlys( this, nDiff );
3171 :
3172 6206 : SwFrm *pFrm = ContainsCntnt();
3173 6206 : if ( pFrm )
3174 12844 : do
3175 : {
3176 12844 : if ( pFrm->IsInTab() && !IsTabFrm() )
3177 : {
3178 10031 : SwFrm *pTmp = pFrm->FindTabFrm();
3179 : OSL_ENSURE( pTmp, "Where's my TabFrm?" );
3180 10031 : if( IsAnLower( pTmp ) )
3181 90 : pFrm = pTmp;
3182 : }
3183 :
3184 12844 : if ( pFrm->IsTabFrm() )
3185 : {
3186 90 : const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize();
3187 90 : if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3188 11 : pFrm->InvalidatePrt();
3189 : }
3190 12754 : else if ( pFrm->GetDrawObjs() )
3191 51 : ::InvaPercentFlys( pFrm, nDiff );
3192 12844 : pFrm = pFrm->FindNextCnt();
3193 12844 : } while ( pFrm && IsAnLower( pFrm ) ) ;
3194 6206 : }
3195 :
3196 : /*************************************************************************
3197 : |*
3198 : |* SwLayoutFrm::CalcRel()
3199 : |*
3200 : |*************************************************************************/
3201 725 : long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, sal_Bool ) const
3202 : {
3203 725 : long nRet = rSz.GetWidth(),
3204 725 : nPercent = rSz.GetWidthPercent();
3205 :
3206 725 : if ( nPercent )
3207 : {
3208 30 : const SwFrm *pRel = GetUpper();
3209 30 : long nRel = LONG_MAX;
3210 30 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
3211 30 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
3212 30 : if( pRel->IsPageBodyFrm() && pSh && bBrowseMode && pSh->VisArea().Width() )
3213 : {
3214 0 : nRel = pSh->GetBrowseWidth();
3215 0 : long nDiff = nRel - pRel->Prt().Width();
3216 0 : if ( nDiff > 0 )
3217 0 : nRel -= nDiff;
3218 : }
3219 30 : nRel = std::min( nRel, pRel->Prt().Width() );
3220 30 : nRet = nRel * nPercent / 100;
3221 : }
3222 725 : return nRet;
3223 : }
3224 :
3225 : // Local helpers for SwLayoutFrm::FormatWidthCols()
3226 :
3227 46 : static long lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm )
3228 : {
3229 46 : long nDiff = 0, nFirstDiff = 0;
3230 46 : SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower();
3231 : OSL_ENSURE( pCol, "Where's the columnframe?" );
3232 46 : SwFrm *pFrm = pCol->Lower();
3233 142 : do
3234 : {
3235 142 : if( pFrm && pFrm->IsBodyFrm() )
3236 142 : pFrm = ((SwBodyFrm*)pFrm)->Lower();
3237 142 : if ( pFrm && pFrm->IsTxtFrm() )
3238 : {
3239 33 : const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight();
3240 33 : if ( nTmp != USHRT_MAX )
3241 : {
3242 33 : if ( pCol == pLayFrm->Lower() )
3243 33 : nFirstDiff = nTmp;
3244 : else
3245 0 : nDiff = nDiff ? std::min( nDiff, nTmp ) : nTmp;
3246 : }
3247 : }
3248 : //Skip empty columns!
3249 142 : pCol = (SwLayoutFrm*)pCol->GetNext();
3250 284 : while ( pCol && 0 == (pFrm = pCol->Lower()) )
3251 0 : pCol = (SwLayoutFrm*)pCol->GetNext();
3252 :
3253 96 : } while ( pFrm && pCol );
3254 :
3255 46 : return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
3256 : }
3257 :
3258 46 : static bool lcl_IsFlyHeightClipped( SwLayoutFrm *pLay )
3259 : {
3260 46 : SwFrm *pFrm = pLay->ContainsCntnt();
3261 639 : while ( pFrm )
3262 : {
3263 547 : if ( pFrm->IsInTab() )
3264 0 : pFrm = pFrm->FindTabFrm();
3265 :
3266 547 : if ( pFrm->GetDrawObjs() )
3267 : {
3268 0 : sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
3269 0 : for ( sal_uInt16 i = 0; i < nCnt; ++i )
3270 : {
3271 0 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3272 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3273 : {
3274 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3275 0 : if ( pFly->IsHeightClipped() &&
3276 0 : ( !pFly->IsFlyFreeFrm() || pFly->GetPageFrm() ) )
3277 0 : return true;
3278 : }
3279 : }
3280 : }
3281 547 : pFrm = pFrm->FindNextCnt();
3282 : }
3283 46 : return false;
3284 : }
3285 :
3286 : /*************************************************************************
3287 : |* SwLayoutFrm::FormatWidthCols()
3288 : |*************************************************************************/
3289 3 : void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs,
3290 : const SwTwips nBorder, const SwTwips nMinHeight )
3291 : {
3292 : //If there are columns involved, the size is adjusted using the last column.
3293 : //1. Format content.
3294 : //2. Calculate height of the last column: if it's too big, the Fly has to
3295 : // grow. The amount by which the Fly grows is not the amount of the
3296 : // overhang because we have to act on the assumption that some text flows
3297 : // back which will generate some more space.
3298 : // The amount which we grow by equals the overhang
3299 : // divided by the amount of columns or the overhang itself if it's smaller
3300 : // than the amount of columns.
3301 : //3. Go back to 1. until everything is stable.
3302 :
3303 3 : const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol();
3304 3 : const sal_uInt16 nNumCols = rCol.GetNumCols();
3305 :
3306 3 : bool bEnd = false;
3307 3 : bool bBackLock = false;
3308 3 : ViewShell *pSh = getRootFrm()->GetCurrShell();
3309 3 : SwViewImp *pImp = pSh ? pSh->Imp() : 0;
3310 : {
3311 : // Underlying algorithm
3312 : // We try to find the optimal height for the column.
3313 : // nMinimum starts with the passed minimum height and is then remembered
3314 : // as the maximum height on which column content still juts out of a
3315 : // column.
3316 : // nMaximum starts with LONG_MAX and is then remembered as the minimum
3317 : // width on which the content fitted.
3318 : // In column based sections nMaximum starts at the maximum value which
3319 : // the surrounding defines, this can certainly be a value on which
3320 : // content still juts out.
3321 : // The columns are formatted. If content still juts out, nMinimum is
3322 : // adjusted accordingly, then we grow, at least by uMinDiff but not
3323 : // over a certain nMaximum. If no content juts out but there is still
3324 : // some space left in the column, shrinking is done accordingly, at
3325 : // least by nMindIff but not below the nMinimum.
3326 : // Cancel as soon as no content juts out and the difference from minimum
3327 : // to maximum is less than MinDiff or the maximum which was defined by
3328 : // the surrounding is reached even if some content still juts out.
3329 :
3330 : // Criticism of this implementation
3331 : // 1. Theoretically situations are possible in which the content fits in
3332 : // a lower height but not in a higher height. To ensure that the code
3333 : // handles such situations the code contains a few checks concerning
3334 : // minimum and maximum which probably are never triggered.
3335 : // 2. We use the same nMinDiff for shrinking and growing, but nMinDiff
3336 : // is more or less the smallest first line height and doesn't seem ideal
3337 : // as minimum value.
3338 :
3339 3 : long nMinimum = nMinHeight;
3340 : long nMaximum;
3341 3 : sal_Bool bNoBalance = sal_False;
3342 3 : SWRECTFN( this )
3343 3 : if( IsSctFrm() )
3344 : {
3345 3 : nMaximum = (Frm().*fnRect->fnGetHeight)() - nBorder +
3346 3 : (Frm().*fnRect->fnBottomDist)(
3347 3 : (GetUpper()->*fnRect->fnGetPrtBottom)() );
3348 3 : nMaximum += GetUpper()->Grow( LONG_MAX, sal_True );
3349 3 : if( nMaximum < nMinimum )
3350 : {
3351 0 : if( nMaximum < 0 )
3352 0 : nMinimum = nMaximum = 0;
3353 : else
3354 0 : nMinimum = nMaximum;
3355 : }
3356 3 : if( nMaximum > BROWSE_HEIGHT )
3357 0 : nMaximum = BROWSE_HEIGHT;
3358 :
3359 3 : bNoBalance = ((SwSectionFrm*)this)->GetSection()->GetFmt()->
3360 3 : GetBalancedColumns().GetValue();
3361 3 : SwFrm* pAny = ContainsAny();
3362 8 : if( bNoBalance ||
3363 5 : ( !(Frm().*fnRect->fnGetHeight)() && pAny ) )
3364 : {
3365 2 : long nTop = (this->*fnRect->fnGetTopMargin)();
3366 : // #i23129# - correction
3367 : // to the calculated maximum height.
3368 2 : (Frm().*fnRect->fnAddBottom)( nMaximum -
3369 2 : (Frm().*fnRect->fnGetHeight)() );
3370 2 : if( nTop > nMaximum )
3371 0 : nTop = nMaximum;
3372 2 : (this->*fnRect->fnSetYMargins)( nTop, 0 );
3373 : }
3374 3 : if( !pAny && !((SwSectionFrm*)this)->IsFtnLock() )
3375 : {
3376 0 : SwFtnContFrm* pFtnCont = ((SwSectionFrm*)this)->ContainsFtnCont();
3377 0 : if( pFtnCont )
3378 : {
3379 0 : SwFrm* pFtnAny = pFtnCont->ContainsAny();
3380 0 : if( pFtnAny && pFtnAny->IsValid() )
3381 : {
3382 0 : bBackLock = true;
3383 0 : ((SwSectionFrm*)this)->SetFtnLock( sal_True );
3384 : }
3385 : }
3386 : }
3387 : }
3388 : else
3389 0 : nMaximum = LONG_MAX;
3390 :
3391 : // #i3317# - reset temporarly consideration
3392 : // of wrapping style influence
3393 3 : SwPageFrm* pPageFrm = FindPageFrm();
3394 3 : SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
3395 3 : if ( pObjs )
3396 : {
3397 0 : sal_uInt32 i = 0;
3398 0 : for ( i = 0; i < pObjs->Count(); ++i )
3399 : {
3400 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
3401 :
3402 0 : if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3403 : {
3404 0 : pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3405 : }
3406 : }
3407 : }
3408 48 : do
3409 : {
3410 : //Could take a while therefore check for Waitcrsr here.
3411 48 : if ( pImp )
3412 48 : pImp->CheckWaitCrsr();
3413 :
3414 48 : mbValidSize = sal_True;
3415 : //First format the column as this will relieve the stack a bit.
3416 : //Also set width and height of the column (if they are wrong)
3417 : //while we are at it.
3418 48 : SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
3419 :
3420 : // #i27399#
3421 : // Simply setting the column width based on the values returned by
3422 : // CalcColWidth does not work for automatic column width.
3423 48 : AdjustColumns( &rCol, sal_False );
3424 :
3425 194 : for ( sal_uInt16 i = 0; i < nNumCols; ++i )
3426 : {
3427 146 : pCol->Calc();
3428 : // ColumnFrms have a BodyFrm now, which needs to be calculated
3429 146 : pCol->Lower()->Calc();
3430 146 : if( pCol->Lower()->GetNext() )
3431 0 : pCol->Lower()->GetNext()->Calc(); // SwFtnCont
3432 146 : pCol = (SwLayoutFrm*)pCol->GetNext();
3433 : }
3434 :
3435 48 : ::CalcCntnt( this );
3436 :
3437 48 : pCol = (SwLayoutFrm*)Lower();
3438 : OSL_ENSURE( pCol && pCol->GetNext(), ":-( column making holidays?");
3439 : // set bMinDiff if no empty columns exist
3440 48 : bool bMinDiff = true;
3441 : // OD 28.03.2003 #108446# - check for all column content and all columns
3442 177 : while ( bMinDiff && pCol )
3443 : {
3444 81 : bMinDiff = 0 != pCol->ContainsCntnt();
3445 81 : pCol = (SwLayoutFrm*)pCol->GetNext();
3446 : }
3447 48 : pCol = (SwLayoutFrm*)Lower();
3448 : // OD 28.03.2003 #108446# - initialize local variable
3449 48 : SwFrm *pLow = NULL;
3450 48 : SwTwips nDiff = 0;
3451 48 : SwTwips nMaxFree = 0;
3452 48 : SwTwips nAllFree = LONG_MAX;
3453 : // set bFoundLower if there is at least one non-empty column
3454 48 : bool bFoundLower = false;
3455 242 : while( pCol )
3456 : {
3457 146 : SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower();
3458 146 : SwTwips nInnerHeight = (pLay->Frm().*fnRect->fnGetHeight)() -
3459 146 : (pLay->Prt().*fnRect->fnGetHeight)();
3460 146 : if( pLay->Lower() )
3461 : {
3462 33 : bFoundLower = true;
3463 33 : nInnerHeight += pLay->InnerHeight();
3464 : }
3465 113 : else if( nInnerHeight < 0 )
3466 0 : nInnerHeight = 0;
3467 :
3468 146 : if( pLay->GetNext() )
3469 : {
3470 0 : bFoundLower = true;
3471 0 : pLay = (SwLayoutFrm*)pLay->GetNext();
3472 : OSL_ENSURE( pLay->IsFtnContFrm(),"FtnContainer exspected" );
3473 0 : nInnerHeight += pLay->InnerHeight();
3474 0 : nInnerHeight += (pLay->Frm().*fnRect->fnGetHeight)() -
3475 0 : (pLay->Prt().*fnRect->fnGetHeight)();
3476 : }
3477 146 : nInnerHeight -= (pCol->Prt().*fnRect->fnGetHeight)();
3478 146 : if( nInnerHeight > nDiff )
3479 : {
3480 0 : nDiff = nInnerHeight;
3481 0 : nAllFree = 0;
3482 : }
3483 : else
3484 : {
3485 146 : if( nMaxFree < -nInnerHeight )
3486 68 : nMaxFree = -nInnerHeight;
3487 146 : if( nAllFree > -nInnerHeight )
3488 48 : nAllFree = -nInnerHeight;
3489 : }
3490 146 : pCol = (SwLayoutFrm*)pCol->GetNext();
3491 : }
3492 :
3493 48 : if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) )
3494 : {
3495 46 : SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
3496 : // Here we decide if growing is needed - this is the case, if
3497 : // column content (nDiff) or a Fly juts over.
3498 : // In sections with columns we take into account to set the size
3499 : // when having a non-empty Follow.
3500 105 : if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
3501 92 : ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) )
3502 : {
3503 13 : long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3504 : // The minimum must not be smaller than our PrtHeight as
3505 : // long as something juts over.
3506 13 : if( nMinimum < nPrtHeight )
3507 13 : nMinimum = nPrtHeight;
3508 : // The maximum must not be smaller than PrtHeight if
3509 : // something still juts over.
3510 13 : if( nMaximum < nPrtHeight )
3511 0 : nMaximum = nPrtHeight; // Robust, but will this ever happen?
3512 13 : if( !nDiff ) // If only Flys jut over, we grow by nMinDiff
3513 13 : nDiff = nMinDiff;
3514 : // If we should grow more than by nMinDiff we split it over
3515 : // the columns
3516 13 : if ( std::abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols )
3517 0 : nDiff /= nNumCols;
3518 :
3519 13 : if ( bMinDiff )
3520 : { // If no empty column exists, we want to grow at least
3521 : // by nMinDiff. Special case: If we are smaller than the
3522 : // minimal FrmHeight and PrtHeight is smaller than
3523 : // nMindiff we grow in a way that PrtHeight is exactly
3524 : // nMinDiff afterwards.
3525 0 : long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
3526 0 : if ( nFrmHeight > nMinHeight || nPrtHeight >= nMinDiff )
3527 0 : nDiff = std::max( nDiff, nMinDiff );
3528 0 : else if( nDiff < nMinDiff )
3529 0 : nDiff = nMinDiff - nPrtHeight + 1;
3530 : }
3531 : // nMaximum has a size which fits the content or the
3532 : // requested value from the surrounding therefore we don't
3533 : // need to exceed this value.
3534 13 : if( nDiff + nPrtHeight > nMaximum )
3535 13 : nDiff = nMaximum - nPrtHeight;
3536 : }
3537 33 : else if( nMaximum > nMinimum ) // We fit, do we still have some margin?
3538 : {
3539 33 : long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3540 33 : if ( nMaximum < nPrtHeight )
3541 0 : nDiff = nMaximum - nPrtHeight; // We grew over a working
3542 : // height and shrink back to it, but will this ever
3543 : // happen?
3544 : else
3545 : { // We have a new maximum, a size which fits for the content.
3546 33 : nMaximum = nPrtHeight;
3547 : // If the margin in the column is bigger than nMinDiff
3548 : // and we therefore drop under the minimum, we deflate
3549 : // a bit.
3550 33 : if ( !bNoBalance &&
3551 : // #i23129# - <nMinDiff> can be
3552 : // big, because of an object at the beginning of
3553 : // a column. Thus, decrease optimization here.
3554 : //nMaxFree >= nMinDiff &&
3555 33 : nMaxFree > 0 &&
3556 20 : ( !nAllFree ||
3557 20 : nMinimum < nPrtHeight - nMinDiff ) )
3558 : {
3559 31 : nMaxFree /= nNumCols; // disperse over the columns
3560 31 : nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // min nMinDiff
3561 62 : if( nPrtHeight + nDiff <= nMinimum ) // below the minimum?
3562 13 : nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3563 : }
3564 2 : else if( nAllFree )
3565 : {
3566 2 : nDiff = -nAllFree;
3567 2 : if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum?
3568 0 : nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3569 : }
3570 : }
3571 : }
3572 46 : if( nDiff ) // now we shrink or grow...
3573 : {
3574 44 : Size aOldSz( Prt().SSize() );
3575 44 : long nTop = (this->*fnRect->fnGetTopMargin)();
3576 88 : nDiff = (Prt().*fnRect->fnGetHeight)() + nDiff + nBorder -
3577 88 : (Frm().*fnRect->fnGetHeight)();
3578 44 : (Frm().*fnRect->fnAddBottom)( nDiff );
3579 : // #i68520#
3580 44 : if ( dynamic_cast<SwFlyFrm*>(this) )
3581 : {
3582 0 : dynamic_cast<SwFlyFrm*>(this)->InvalidateObjRectWithSpaces();
3583 : }
3584 44 : (this->*fnRect->fnSetYMargins)( nTop, nBorder - nTop );
3585 44 : ChgLowersProp( aOldSz );
3586 44 : NotifyLowerObjs();
3587 :
3588 : // #i3317# - reset temporarly consideration
3589 : // of wrapping style influence
3590 44 : SwPageFrm* pTmpPageFrm = FindPageFrm();
3591 44 : SwSortedObjs* pTmpObjs = pTmpPageFrm ? pTmpPageFrm->GetSortedObjs() : 0L;
3592 44 : if ( pTmpObjs )
3593 : {
3594 0 : sal_uInt32 i = 0;
3595 0 : for ( i = 0; i < pTmpObjs->Count(); ++i )
3596 : {
3597 0 : SwAnchoredObject* pAnchoredObj = (*pTmpObjs)[i];
3598 :
3599 0 : if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3600 : {
3601 0 : pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3602 : }
3603 : }
3604 : }
3605 : //Invalidate suitable to nicely balance the Frms.
3606 : //- Every first one after the second column gets a
3607 : // InvalidatePos();
3608 44 : pCol = (SwLayoutFrm*)Lower()->GetNext();
3609 180 : while ( pCol )
3610 : {
3611 92 : pLow = pCol->Lower();
3612 92 : if ( pLow )
3613 92 : pLow->_InvalidatePos();
3614 92 : pCol = (SwLayoutFrm*)pCol->GetNext();
3615 : }
3616 44 : if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() )
3617 : {
3618 : // If we created a Follow, we need to give its content
3619 : // the opportunity to flow back inside the CalcCntnt
3620 : SwCntntFrm* pTmpCntnt =
3621 13 : ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
3622 13 : if( pTmpCntnt )
3623 13 : pTmpCntnt->_InvalidatePos();
3624 : }
3625 : }
3626 : else
3627 2 : bEnd = true;
3628 : }
3629 : else
3630 2 : bEnd = true;
3631 :
3632 52 : } while ( !bEnd || !mbValidSize );
3633 : }
3634 : // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set
3635 : // 2nd parameter to <true>.
3636 3 : ::CalcCntnt( this, true );
3637 3 : if( IsSctFrm() )
3638 : {
3639 : // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true
3640 3 : ::CalcCntnt( this, true );
3641 3 : if( bBackLock )
3642 0 : ((SwSectionFrm*)this)->SetFtnLock( sal_False );
3643 : }
3644 3 : }
3645 :
3646 :
3647 : /*************************************************************************
3648 : |*
3649 : |* SwRootFrm::InvalidateAllCntnt()
3650 : |*
3651 : |*************************************************************************/
3652 :
3653 0 : static SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, sal_uInt8 nInv )
3654 : {
3655 0 : SwSectionFrm* pSect = pCnt->FindSctFrm();
3656 : // If our CntntFrm is placed inside a table or a footnote, only sections
3657 : // which are also placed inside are meant.
3658 : // Exception: If a table is directly passed.
3659 0 : if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
3660 0 : ( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() )
3661 0 : return NULL;
3662 0 : if( nInv & INV_SIZE )
3663 0 : pSect->_InvalidateSize();
3664 0 : if( nInv & INV_POS )
3665 0 : pSect->_InvalidatePos();
3666 0 : if( nInv & INV_PRTAREA )
3667 0 : pSect->_InvalidatePrt();
3668 0 : SwFlowFrm *pFoll = pSect->GetFollow();
3669 : // Temporary separation from follow
3670 0 : pSect->SetFollow( NULL );
3671 0 : SwCntntFrm* pRet = pSect->FindLastCntnt();
3672 0 : pSect->SetFollow( pFoll );
3673 0 : return pRet;
3674 : }
3675 :
3676 0 : static SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, sal_uInt8 nInv )
3677 : {
3678 0 : if( ( nInv & INV_SECTION ) && pTable->IsInSct() )
3679 0 : lcl_InvalidateSection( pTable, nInv );
3680 0 : if( nInv & INV_SIZE )
3681 0 : pTable->_InvalidateSize();
3682 0 : if( nInv & INV_POS )
3683 0 : pTable->_InvalidatePos();
3684 0 : if( nInv & INV_PRTAREA )
3685 0 : pTable->_InvalidatePrt();
3686 0 : return pTable->FindLastCntnt();
3687 : }
3688 :
3689 : static void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv );
3690 :
3691 27 : static void lcl_InvalidateCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3692 : {
3693 27 : SwCntntFrm *pLastTabCnt = NULL;
3694 27 : SwCntntFrm *pLastSctCnt = NULL;
3695 86 : while ( pCnt )
3696 : {
3697 32 : if( nInv & INV_SECTION )
3698 : {
3699 0 : if( pCnt->IsInSct() )
3700 : {
3701 : // See above at tables
3702 0 : if( !pLastSctCnt )
3703 0 : pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
3704 0 : if( pLastSctCnt == pCnt )
3705 0 : pLastSctCnt = NULL;
3706 : }
3707 : #if OSL_DEBUG_LEVEL > 0
3708 : else
3709 : OSL_ENSURE( !pLastSctCnt, "Where's the last SctCntnt?" );
3710 : #endif
3711 : }
3712 32 : if( nInv & INV_TABLE )
3713 : {
3714 13 : if( pCnt->IsInTab() )
3715 : {
3716 : // To not call FindTabFrm() for each CntntFrm of a table and
3717 : // then invalidate the table, we remember the last CntntFrm of
3718 : // the table and ignore IsInTab() until we are past it.
3719 : // When entering the table, LastSctCnt is set to null, so
3720 : // sections inside the table are correctly invalidated.
3721 : // If the table itself is in a section the
3722 : // invalidation is done three times, which is acceptable.
3723 0 : if( !pLastTabCnt )
3724 : {
3725 0 : pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv );
3726 0 : pLastSctCnt = NULL;
3727 : }
3728 0 : if( pLastTabCnt == pCnt )
3729 : {
3730 0 : pLastTabCnt = NULL;
3731 0 : pLastSctCnt = NULL;
3732 : }
3733 : }
3734 : #if OSL_DEBUG_LEVEL > 0
3735 : else
3736 : OSL_ENSURE( !pLastTabCnt, "Where's the last TabCntnt?" );
3737 : #endif
3738 : }
3739 :
3740 32 : if( nInv & INV_SIZE )
3741 21 : pCnt->Prepare( PREP_CLEAR, 0, sal_False );
3742 32 : if( nInv & INV_POS )
3743 26 : pCnt->_InvalidatePos();
3744 32 : if( nInv & INV_PRTAREA )
3745 26 : pCnt->_InvalidatePrt();
3746 32 : if ( nInv & INV_LINENUM )
3747 6 : pCnt->InvalidateLineNum();
3748 32 : if ( pCnt->GetDrawObjs() )
3749 0 : lcl_InvalidateAllCntnt( pCnt, nInv );
3750 32 : pCnt = pCnt->GetNextCntntFrm();
3751 : }
3752 27 : }
3753 :
3754 0 : static void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3755 : {
3756 0 : SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
3757 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3758 : {
3759 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
3760 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3761 : {
3762 0 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3763 0 : if ( pFly->IsFlyInCntFrm() )
3764 : {
3765 0 : ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3766 0 : if( nInv & INV_DIRECTION )
3767 0 : pFly->CheckDirChange();
3768 : }
3769 : }
3770 : }
3771 0 : }
3772 :
3773 27 : void SwRootFrm::InvalidateAllCntnt( sal_uInt8 nInv )
3774 : {
3775 : // First process all page bound FlyFrms.
3776 27 : SwPageFrm *pPage = (SwPageFrm*)Lower();
3777 81 : while( pPage )
3778 : {
3779 27 : pPage->InvalidateFlyLayout();
3780 27 : pPage->InvalidateFlyCntnt();
3781 27 : pPage->InvalidateFlyInCnt();
3782 27 : pPage->InvalidateLayout();
3783 27 : pPage->InvalidateCntnt();
3784 27 : pPage->InvalidatePage( pPage ); // So even the Turbo disappears if applicable
3785 :
3786 27 : if ( pPage->GetSortedObjs() )
3787 : {
3788 0 : const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
3789 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3790 : {
3791 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
3792 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3793 : {
3794 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3795 0 : ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3796 0 : if ( nInv & INV_DIRECTION )
3797 0 : pFly->CheckDirChange();
3798 : }
3799 : }
3800 : }
3801 27 : if( nInv & INV_DIRECTION )
3802 2 : pPage->CheckDirChange();
3803 27 : pPage = (SwPageFrm*)(pPage->GetNext());
3804 : }
3805 :
3806 : //Invalidate the whole document content and the character bound Flys here.
3807 27 : ::lcl_InvalidateCntnt( ContainsCntnt(), nInv );
3808 :
3809 27 : if( nInv & INV_PRTAREA )
3810 : {
3811 26 : ViewShell *pSh = getRootFrm()->GetCurrShell();
3812 26 : if( pSh )
3813 26 : pSh->InvalidateWindows( Frm() );
3814 : }
3815 27 : }
3816 :
3817 : /**
3818 : * Invalidate/re-calculate the position of all floating screen objects (Writer fly frames and
3819 : * drawing objects), that are anchored to paragraph or to character. (2004-03-16 #i11860#)
3820 : */
3821 0 : void SwRootFrm::InvalidateAllObjPos()
3822 : {
3823 0 : const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>(Lower());
3824 0 : while( pPageFrm )
3825 : {
3826 0 : pPageFrm->InvalidateFlyLayout();
3827 :
3828 0 : if ( pPageFrm->GetSortedObjs() )
3829 : {
3830 0 : const SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
3831 0 : for ( sal_uInt8 i = 0; i < rObjs.Count(); ++i )
3832 : {
3833 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
3834 0 : const SwFmtAnchor& rAnch = pAnchoredObj->GetFrmFmt().GetAnchor();
3835 0 : if ((rAnch.GetAnchorId() != FLY_AT_PARA) &&
3836 0 : (rAnch.GetAnchorId() != FLY_AT_CHAR))
3837 : {
3838 : // only to paragraph and to character anchored objects are considered.
3839 0 : continue;
3840 : }
3841 : // #i28701# - special invalidation for anchored
3842 : // objects, whose wrapping style influence has to be considered.
3843 0 : if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
3844 0 : pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
3845 : else
3846 0 : pAnchoredObj->InvalidateObjPos();
3847 : }
3848 : }
3849 :
3850 0 : pPageFrm = static_cast<const SwPageFrm*>(pPageFrm->GetNext());
3851 : }
3852 99 : }
3853 :
3854 :
3855 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|