1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27
28 #include <hintids.hxx>
29 #include <hints.hxx>
30 #include <tools/pstm.hxx>
31 #include <vcl/outdev.hxx>
32 #include <svl/itemiter.hxx>
33 #include <editeng/brshitem.hxx>
34 #include <editeng/keepitem.hxx>
35 #include <editeng/brkitem.hxx>
36 #include <fmtornt.hxx>
37 #include <pagefrm.hxx>
38 #include <section.hxx>
39 #include <rootfrm.hxx>
40 #include <cntfrm.hxx>
41 #include <dcontact.hxx>
42 #include <anchoreddrawobject.hxx>
43 #include <fmtanchr.hxx>
44 #include <viewsh.hxx>
45 #include <viewimp.hxx>
46 #include "viewopt.hxx"
47 #include <doc.hxx>
48 #include <fesh.hxx>
49 #include <docsh.hxx>
50 #include <flyfrm.hxx>
51 #include <frmtool.hxx>
52 #include <ftninfo.hxx>
53 #include <dflyobj.hxx>
54 #include <fmtclbl.hxx>
55 #include <fmtfordr.hxx>
56 #include <fmtfsize.hxx>
57 #include <fmtpdsc.hxx>
58 #include <txtftn.hxx>
59 #include <fmtftn.hxx>
60 #include <fmtsrnd.hxx>
61 #include <ftnfrm.hxx>
62 #include <tabfrm.hxx>
63 #include <htmltbl.hxx>
64 #include <flyfrms.hxx>
65 #include <sectfrm.hxx>
66 #include <fmtclds.hxx>
67 #include <txtfrm.hxx>
68 #include <ndtxt.hxx>
69 #include <bodyfrm.hxx>
70 #include <cellfrm.hxx>
71 #include <dbg_lay.hxx>
72 #include <editeng/frmdiritem.hxx>
73 #include <sortedobjs.hxx>
74 #include <svx/xdef.hxx>
75
76
77 using namespace ::com::sun::star;
78
79
80 /*************************************************************************
81 |*
82 |* SwFrm::SwFrm()
83 |*
84 |* Ersterstellung AK 12-Feb-1991
85 |* Letzte Aenderung MA 05. Apr. 94
86 |*
87 |*************************************************************************/
88
SwFrm(SwModify * pMod,SwFrm * pSib)89 SwFrm::SwFrm( SwModify *pMod, SwFrm* pSib ) :
90 SwClient( pMod ),
91 //Solution:Add a member to identify if the acc table should dispose
92 bIfAccTableShouldDisposing( sal_False ),
93 // --> OD 2006-05-10 #i65250#
94 mnFrmId( SwFrm::mnLastFrmId++ ),
95 // <--
96 mpRoot( pSib ? pSib->getRootFrm() : 0 ),
97 pUpper( 0 ),
98 pNext( 0 ),
99 pPrev( 0 ),
100 pDrawObjs( 0 )
101 , bInfBody( sal_False )
102 , bInfTab ( sal_False )
103 , bInfFly ( sal_False )
104 , bInfFtn ( sal_False )
105 , bInfSct ( sal_False )
106 {
107 #ifdef DBG_UTIL
108 bFlag01 = bFlag02 = bFlag03 = bFlag04 = bFlag05 = 0;
109 #endif
110
111 ASSERT( pMod, "Kein Frameformat uebergeben." );
112 bInvalidR2L = bInvalidVert = 1;
113 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
114 bDerivedR2L = bDerivedVert = bRightToLeft = bVertical = bReverse = bVertLR = 0;
115
116 bValidPos = bValidPrtArea = bValidSize = bValidLineNum = bRetouche =
117 bFixSize = bColLocked = sal_False;
118 bCompletePaint = bInfInvalid = sal_True;
119 }
120
KnowsFormat(const SwFmt & rFmt) const121 bool SwFrm::KnowsFormat( const SwFmt& rFmt ) const
122 {
123 return GetRegisteredIn() == &rFmt;
124 }
125
RegisterToFormat(SwFmt & rFmt)126 void SwFrm::RegisterToFormat( SwFmt& rFmt )
127 {
128 rFmt.Add( this );
129 }
130
CheckDir(sal_uInt16 nDir,sal_Bool bVert,sal_Bool bOnlyBiDi,sal_Bool bBrowse)131 void SwFrm::CheckDir( sal_uInt16 nDir, sal_Bool bVert, sal_Bool bOnlyBiDi, sal_Bool bBrowse )
132 {
133 if( FRMDIR_ENVIRONMENT == nDir || ( bVert && bOnlyBiDi ) )
134 {
135 bDerivedVert = 1;
136 if( FRMDIR_ENVIRONMENT == nDir )
137 bDerivedR2L = 1;
138 SetDirFlags( bVert );
139 }
140 else if( bVert )
141 {
142 bInvalidVert = 0;
143 if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir
144 || bBrowse )
145 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
146 {
147 bVertical = 0;
148 bVertLR = 0;
149 }
150 else
151 {
152 bVertical = 1;
153 if(FRMDIR_VERT_TOP_RIGHT == nDir)
154 bVertLR = 0;
155 else if(FRMDIR_VERT_TOP_LEFT==nDir)
156 bVertLR = 1;
157 }
158 }
159 else
160 {
161 bInvalidR2L = 0;
162 if( FRMDIR_HORI_RIGHT_TOP == nDir )
163 bRightToLeft = 1;
164 else
165 bRightToLeft = 0;
166 }
167 }
168
CheckDirection(sal_Bool bVert)169 void SwFrm::CheckDirection( sal_Bool bVert )
170 {
171 if( bVert )
172 {
173 if( !IsHeaderFrm() && !IsFooterFrm() )
174 {
175 bDerivedVert = 1;
176 SetDirFlags( bVert );
177 }
178 }
179 else
180 {
181 bDerivedR2L = 1;
182 SetDirFlags( bVert );
183 }
184 }
185
CheckDirection(sal_Bool bVert)186 void SwSectionFrm::CheckDirection( sal_Bool bVert )
187 {
188 const SwFrmFmt* pFmt = GetFmt();
189 if( pFmt )
190 {
191 const ViewShell *pSh = getRootFrm()->GetCurrShell();
192 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
193 CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
194 bVert, sal_True, bBrowseMode );
195 }
196 else
197 SwFrm::CheckDirection( bVert );
198 }
199
CheckDirection(sal_Bool bVert)200 void SwFlyFrm::CheckDirection( sal_Bool bVert )
201 {
202 const SwFrmFmt* pFmt = GetFmt();
203 if( pFmt )
204 {
205 const ViewShell *pSh = getRootFrm()->GetCurrShell();
206 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
207 CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
208 bVert, sal_False, bBrowseMode );
209 }
210 else
211 SwFrm::CheckDirection( bVert );
212 }
213
CheckDirection(sal_Bool bVert)214 void SwTabFrm::CheckDirection( sal_Bool bVert )
215 {
216 const SwFrmFmt* pFmt = GetFmt();
217 if( pFmt )
218 {
219 const ViewShell *pSh = getRootFrm()->GetCurrShell();
220 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
221 CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
222 bVert, sal_True, bBrowseMode );
223 }
224 else
225 SwFrm::CheckDirection( bVert );
226 }
227
CheckDirection(sal_Bool bVert)228 void SwCellFrm::CheckDirection( sal_Bool bVert )
229 {
230 const SwFrmFmt* pFmt = GetFmt();
231 const SfxPoolItem* pItem;
232 // --> FME 2006-03-30 #b6402837# Check if the item is set, before actually
233 // using it. Otherwise the dynamic pool default is used, which may be set
234 // to LTR in case of OOo 1.0 documents.
235 // <--
236 if( pFmt && SFX_ITEM_SET == pFmt->GetItemState( RES_FRAMEDIR, sal_True, &pItem ) )
237 {
238 const SvxFrameDirectionItem* pFrmDirItem = static_cast<const SvxFrameDirectionItem*>(pItem);
239 const ViewShell *pSh = getRootFrm()->GetCurrShell();
240 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
241 CheckDir( pFrmDirItem->GetValue(), bVert, sal_False, bBrowseMode );
242 }
243 else
244 SwFrm::CheckDirection( bVert );
245 }
246
CheckDirection(sal_Bool bVert)247 void SwTxtFrm::CheckDirection( sal_Bool bVert )
248 {
249 const ViewShell *pSh = getRootFrm()->GetCurrShell();
250 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
251 CheckDir( GetTxtNode()->GetSwAttrSet().GetFrmDir().GetValue(), bVert,
252 sal_True, bBrowseMode );
253 }
254
255 /*************************************************************************/
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)256 void SwFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
257 {
258 sal_uInt8 nInvFlags = 0;
259
260 if( pNew && RES_ATTRSET_CHG == pNew->Which() )
261 {
262 SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
263 SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
264 while( sal_True )
265 {
266 _UpdateAttrFrm( (SfxPoolItem*)aOIter.GetCurItem(),
267 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags );
268 if( aNIter.IsAtEnd() )
269 break;
270 aNIter.NextItem();
271 aOIter.NextItem();
272 }
273 }
274 else
275 _UpdateAttrFrm( pOld, pNew, nInvFlags );
276
277 if ( nInvFlags != 0 )
278 {
279 SwPageFrm *pPage = FindPageFrm();
280 InvalidatePage( pPage );
281 if ( nInvFlags & 0x01 )
282 {
283 _InvalidatePrt();
284 if( !GetPrev() && IsTabFrm() && IsInSct() )
285 FindSctFrm()->_InvalidatePrt();
286 }
287 if ( nInvFlags & 0x02 )
288 _InvalidateSize();
289 if ( nInvFlags & 0x04 )
290 _InvalidatePos();
291 if ( nInvFlags & 0x08 )
292 SetCompletePaint();
293 SwFrm *pNxt;
294 if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) )
295 {
296 pNxt->InvalidatePage( pPage );
297 if ( nInvFlags & 0x10 )
298 pNxt->_InvalidatePos();
299 if ( nInvFlags & 0x20 )
300 pNxt->SetCompletePaint();
301 }
302 }
303 }
304
_UpdateAttrFrm(const SfxPoolItem * pOld,const SfxPoolItem * pNew,sal_uInt8 & rInvFlags)305 void SwFrm::_UpdateAttrFrm( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
306 sal_uInt8 &rInvFlags )
307 {
308 sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
309 switch( nWhich )
310 {
311 case RES_BOX:
312 case RES_SHADOW:
313 Prepare( PREP_FIXSIZE_CHG );
314 // hier kein break !
315 case RES_LR_SPACE:
316 case RES_UL_SPACE:
317 rInvFlags |= 0x0B;
318 break;
319
320 case RES_HEADER_FOOTER_EAT_SPACING:
321 rInvFlags |= 0x03;
322 break;
323
324 case RES_BACKGROUND:
325 rInvFlags |= 0x28;
326 break;
327
328 case RES_KEEP:
329 rInvFlags |= 0x04;
330 break;
331
332 case RES_FRM_SIZE:
333 ReinitializeFrmSizeAttrFlags();
334 rInvFlags |= 0x13;
335 break;
336
337 case RES_FMT_CHG:
338 rInvFlags |= 0x0F;
339 break;
340
341 case RES_ROW_SPLIT:
342 {
343 if ( IsRowFrm() )
344 {
345 sal_Bool bInFollowFlowRow = 0 != IsInFollowFlowRow();
346 if ( bInFollowFlowRow || 0 != IsInSplitTableRow() )
347 {
348 SwTabFrm* pTab = FindTabFrm();
349 if ( bInFollowFlowRow )
350 pTab = pTab->FindMaster();
351 pTab->SetRemoveFollowFlowLinePending( sal_True );
352 }
353 }
354 break;
355 }
356 case RES_COL:
357 ASSERT( sal_False, "Spalten fuer neuen FrmTyp?" );
358 break;
359
360 default:
361 //UUUU the new FillStyle has to do the same as previous RES_BACKGROUND
362 if(nWhich >= XATTR_FILL_FIRST && nWhich <= XATTR_FILL_LAST)
363 {
364 rInvFlags |= 0x28;
365 }
366 /* do Nothing */;
367 }
368 }
369
370 /*************************************************************************
371 |*
372 |* SwFrm::Prepare()
373 |* Ersterstellung MA 13. Apr. 93
374 |* Letzte Aenderung MA 26. Jun. 96
375 |*
376 |*************************************************************************/
Prepare(const PrepareHint,const void *,sal_Bool)377 void SwFrm::Prepare( const PrepareHint, const void *, sal_Bool )
378 {
379 /* Do nothing */
380 }
381
382 /*************************************************************************
383 |*
384 |* SwFrm::InvalidatePage()
385 |* Beschreibung: Invalidiert die Seite, in der der Frm gerade steht.
386 |* Je nachdem ob es ein Layout, Cntnt oder FlyFrm ist wird die Seite
387 |* entsprechend Invalidiert.
388 |* Ersterstellung MA 22. Jul. 92
389 |* Letzte Aenderung MA 14. Oct. 94
390 |*
391 |*************************************************************************/
InvalidatePage(const SwPageFrm * pPage) const392 void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const
393 {
394 if ( !pPage )
395 {
396 pPage = FindPageFrm();
397 // --> OD 2004-07-02 #i28701# - for at-character and as-character
398 // anchored Writer fly frames additionally invalidate also page frame
399 // its 'anchor character' is on.
400 if ( pPage && pPage->GetUpper() && IsFlyFrm() )
401 {
402 const SwFlyFrm* pFlyFrm = static_cast<const SwFlyFrm*>(this);
403 if ( pFlyFrm->IsAutoPos() || pFlyFrm->IsFlyInCntFrm() )
404 {
405 // --> OD 2004-09-23 #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
406 // is replaced by method <FindPageFrmOfAnchor()>. It's return value
407 // have to be checked.
408 SwPageFrm* pPageFrmOfAnchor =
409 const_cast<SwFlyFrm*>(pFlyFrm)->FindPageFrmOfAnchor();
410 if ( pPageFrmOfAnchor && pPageFrmOfAnchor != pPage )
411 // <--
412 {
413 InvalidatePage( pPageFrmOfAnchor );
414 }
415 }
416 }
417 // <--
418 }
419
420 if ( pPage && pPage->GetUpper() )
421 {
422 if ( pPage->GetFmt()->GetDoc()->IsInDtor() )
423 return;
424
425 SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
426 const SwFlyFrm *pFly = FindFlyFrm();
427 if ( IsCntntFrm() )
428 {
429 if ( pRoot->IsTurboAllowed() )
430 {
431 // JP 21.09.95: wenn sich der ContentFrame 2 mal eintragen
432 // will, kann es doch eine TurboAction bleiben.
433 // ODER????
434 if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
435 pRoot->SetTurbo( (const SwCntntFrm*)this );
436 else
437 {
438 pRoot->DisallowTurbo();
439 //Die Seite des Turbo koennte eine andere als die meinige
440 //sein, deshalb muss sie invalidiert werden.
441 const SwFrm *pTmp = pRoot->GetTurbo();
442 pRoot->ResetTurbo();
443 pTmp->InvalidatePage();
444 }
445 }
446 if ( !pRoot->GetTurbo() )
447 {
448 if ( pFly )
449 { if( !pFly->IsLocked() )
450 {
451 if ( pFly->IsFlyInCntFrm() )
452 { pPage->InvalidateFlyInCnt();
453 ((SwFlyInCntFrm*)pFly)->InvalidateCntnt();
454 pFly->GetAnchorFrm()->InvalidatePage();
455 }
456 else
457 pPage->InvalidateFlyCntnt();
458 }
459 }
460 else
461 pPage->InvalidateCntnt();
462 }
463 }
464 else
465 {
466 pRoot->DisallowTurbo();
467 if ( pFly )
468 {
469 if ( !pFly->IsLocked() )
470 {
471 if ( pFly->IsFlyInCntFrm() )
472 {
473 pPage->InvalidateFlyInCnt();
474 ((SwFlyInCntFrm*)pFly)->InvalidateLayout();
475 pFly->GetAnchorFrm()->InvalidatePage();
476 }
477 else
478 pPage->InvalidateFlyLayout();
479 }
480 }
481 else
482 pPage->InvalidateLayout();
483
484 if ( pRoot->GetTurbo() )
485 { const SwFrm *pTmp = pRoot->GetTurbo();
486 pRoot->ResetTurbo();
487 pTmp->InvalidatePage();
488 }
489 }
490 pRoot->SetIdleFlags();
491
492 const SwTxtFrm *pTxtFrm = dynamic_cast< const SwTxtFrm * >(this);
493 if (pTxtFrm)
494 {
495 const SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode();
496 if (pTxtNode && pTxtNode->IsGrammarCheckDirty())
497 pRoot->SetNeedGrammarCheck( sal_True );
498 }
499 }
500 }
501
502 /*************************************************************************
503 |*
504 |* SwFrm::ChgSize()
505 |*
506 |* Ersterstellung AK 15-Feb-1991
507 |* Letzte Aenderung MA 18. Nov. 98
508 |*
509 |*************************************************************************/
ChgSize(const Size & aNewSize)510 Size SwFrm::ChgSize( const Size& aNewSize )
511 {
512 bFixSize = sal_True;
513 const Size aOldSize( Frm().SSize() );
514 if ( aNewSize == aOldSize )
515 return aOldSize;
516
517 if ( GetUpper() )
518 {
519 SWRECTFN2( this )
520 SwRect aNew( Point(0,0), aNewSize );
521 (aFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() );
522 long nNew = (aNew.*fnRect->fnGetHeight)();
523 long nDiff = nNew - (aFrm.*fnRect->fnGetHeight)();
524 if( nDiff )
525 {
526 if ( GetUpper()->IsFtnBossFrm() && HasFixSize() &&
527 NA_GROW_SHRINK !=
528 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) )
529 {
530 (aFrm.*fnRect->fnSetHeight)( nNew );
531 SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood(nDiff);
532 if ( nReal != nDiff )
533 (aFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal );
534 }
535 else
536 {
537 // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames
538 // NOTE: neighbour frames are cell and column frames.
539 if ( !bNeighb )
540 {
541 if ( nDiff > 0 )
542 Grow( nDiff );
543 else
544 Shrink( -nDiff );
545
546 if ( GetUpper() && (aFrm.*fnRect->fnGetHeight)() != nNew )
547 GetUpper()->_InvalidateSize();
548 }
549
550 // Auch wenn das Grow/Shrink noch nicht die gewuenschte Breite eingestellt hat,
551 // wie z.B. beim Aufruf durch ChgColumns, um die Spaltenbreiten einzustellen,
552 // wird die Breite jetzt gesetzt.
553 (aFrm.*fnRect->fnSetHeight)( nNew );
554 }
555 }
556 }
557 else
558 aFrm.SSize( aNewSize );
559
560 if ( Frm().SSize() != aOldSize )
561 {
562 SwPageFrm *pPage = FindPageFrm();
563 if ( GetNext() )
564 {
565 GetNext()->_InvalidatePos();
566 GetNext()->InvalidatePage( pPage );
567 }
568 if( IsLayoutFrm() )
569 {
570 if( IsRightToLeft() )
571 _InvalidatePos();
572 if( ((SwLayoutFrm*)this)->Lower() )
573 ((SwLayoutFrm*)this)->Lower()->_InvalidateSize();
574 }
575 _InvalidatePrt();
576 _InvalidateSize();
577 InvalidatePage( pPage );
578 }
579
580 return aFrm.SSize();
581 }
582
583 /*************************************************************************
584 |*
585 |* SwFrm::InsertBefore()
586 |*
587 |* Beschreibung SwFrm wird in eine bestehende Struktur eingefuegt
588 |* Eingefuegt wird unterhalb des Parent und entweder
589 |* vor pBehind oder am Ende der Kette wenn pBehind
590 |* leer ist.
591 |* Letzte Aenderung MA 06. Aug. 99
592 |*
593 |*************************************************************************/
InsertBefore(SwLayoutFrm * pParent,SwFrm * pBehind)594 void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind )
595 {
596 ASSERT( pParent, "Kein Parent fuer Insert." );
597 ASSERT( (!pBehind || (pBehind && pParent == pBehind->GetUpper())),
598 "Framebaum inkonsistent." );
599
600 pUpper = pParent;
601 pNext = pBehind;
602 if( pBehind )
603 { //Einfuegen vor pBehind.
604 if( 0 != (pPrev = pBehind->pPrev) )
605 pPrev->pNext = this;
606 else
607 pUpper->pLower = this;
608 pBehind->pPrev = this;
609 }
610 else
611 { //Einfuegen am Ende, oder als ersten Node im Unterbaum
612 pPrev = pUpper->Lower();
613 if ( pPrev )
614 {
615 while( pPrev->pNext )
616 pPrev = pPrev->pNext;
617 pPrev->pNext = this;
618 }
619 else
620 pUpper->pLower = this;
621 }
622 }
623
624 /*************************************************************************
625 |*
626 |* SwFrm::InsertBehind()
627 |*
628 |* Beschreibung SwFrm wird in eine bestehende Struktur eingefuegt
629 |* Eingefuegt wird unterhalb des Parent und entweder
630 |* hinter pBefore oder am Anfang der Kette wenn pBefore
631 |* leer ist.
632 |* Letzte Aenderung MA 06. Aug. 99
633 |*
634 |*************************************************************************/
InsertBehind(SwLayoutFrm * pParent,SwFrm * pBefore)635 void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore )
636 {
637 ASSERT( pParent, "Kein Parent fuer Insert." );
638 ASSERT( (!pBefore || (pBefore && pParent == pBefore->GetUpper())),
639 "Framebaum inkonsistent." );
640
641 pUpper = pParent;
642 pPrev = pBefore;
643 if ( pBefore )
644 {
645 //Einfuegen hinter pBefore
646 if ( 0 != (pNext = pBefore->pNext) )
647 pNext->pPrev = this;
648 pBefore->pNext = this;
649 }
650 else
651 {
652 //Einfuegen am Anfang der Kette
653 pNext = pParent->Lower();
654 if ( pParent->Lower() )
655 pParent->Lower()->pPrev = this;
656 pParent->pLower = this;
657 }
658 }
659
660 /*************************************************************************
661 |*
662 |* SwFrm::InsertGroup()
663 |*
664 |* Beschreibung Eine Kette von SwFrms wird in eine bestehende Struktur
665 |* eingefuegt
666 |* Letzte Aenderung AMA 9. Dec. 97
667 |*
668 |* Bisher wird dies genutzt, um einen SectionFrame, der ggf. schon Geschwister
669 |* mit sich bringt, in eine bestehende Struktur einzufuegen.
670 |*
671 |* Wenn man den dritten Parameter als NULL uebergibt, entspricht
672 |* diese Methode dem SwFrm::InsertBefore(..), nur eben mit Geschwistern.
673 |*
674 |* Wenn man einen dritten Parameter uebergibt, passiert folgendes:
675 |* this wird pNext von pParent,
676 |* pSct wird pNext vom Letzten der this-Kette,
677 |* pBehind wird vom pParent an den pSct umgehaengt.
678 |* Dies dient dazu: ein SectionFrm (this) wird nicht als
679 |* Kind an einen anderen SectionFrm (pParent) gehaengt, sondern pParent
680 |* wird in zwei Geschwister aufgespalten (pParent+pSct) und this dazwischen
681 |* eingebaut.
682 |*
683 |*************************************************************************/
InsertGroupBefore(SwFrm * pParent,SwFrm * pBehind,SwFrm * pSct)684 void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct )
685 {
686 ASSERT( pParent, "Kein Parent fuer Insert." );
687 ASSERT( (!pBehind || (pBehind && ( pParent == pBehind->GetUpper())
688 || ( pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm() ) ) ),
689 "Framebaum inkonsistent." );
690 if( pSct )
691 {
692 pUpper = pParent->GetUpper();
693 SwFrm *pLast = this;
694 while( pLast->GetNext() )
695 {
696 pLast = pLast->GetNext();
697 pLast->pUpper = GetUpper();
698 }
699 if( pBehind )
700 {
701 pLast->pNext = pSct;
702 pSct->pPrev = pLast;
703 pSct->pNext = pParent->GetNext();
704 }
705 else
706 {
707 pLast->pNext = pParent->GetNext();
708 if( pLast->GetNext() )
709 pLast->GetNext()->pPrev = pLast;
710 }
711 pParent->pNext = this;
712 pPrev = pParent;
713 if( pSct->GetNext() )
714 pSct->GetNext()->pPrev = pSct;
715 while( pLast->GetNext() )
716 {
717 pLast = pLast->GetNext();
718 pLast->pUpper = GetUpper();
719 }
720 if( pBehind )
721 { //Einfuegen vor pBehind.
722 if( pBehind->GetPrev() )
723 pBehind->GetPrev()->pNext = NULL;
724 else
725 pBehind->GetUpper()->pLower = NULL;
726 pBehind->pPrev = NULL;
727 SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct;
728 if( pTmp->Lower() )
729 {
730 ASSERT( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" );
731 pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower();
732 ASSERT( pTmp, "InsertGrp: Missing ColBody" );
733 }
734 pBehind->pUpper = pTmp;
735 pBehind->GetUpper()->pLower = pBehind;
736 pLast = pBehind->GetNext();
737 while ( pLast )
738 {
739 pLast->pUpper = pBehind->GetUpper();
740 pLast = pLast->GetNext();
741 };
742 }
743 else
744 {
745 ASSERT( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" );
746 delete ((SwSectionFrm*)pSct);
747 }
748 }
749 else
750 {
751 pUpper = (SwLayoutFrm*)pParent;
752 SwFrm *pLast = this;
753 while( pLast->GetNext() )
754 {
755 pLast = pLast->GetNext();
756 pLast->pUpper = GetUpper();
757 }
758 pLast->pNext = pBehind;
759 if( pBehind )
760 { //Einfuegen vor pBehind.
761 if( 0 != (pPrev = pBehind->pPrev) )
762 pPrev->pNext = this;
763 else
764 pUpper->pLower = this;
765 pBehind->pPrev = pLast;
766 }
767 else
768 { //Einfuegen am Ende, oder des ersten Nodes im Unterbaum
769 pPrev = pUpper->Lower();
770 if ( pPrev )
771 {
772 while( pPrev->pNext )
773 pPrev = pPrev->pNext;
774 pPrev->pNext = this;
775 }
776 else
777 pUpper->pLower = this;
778 }
779 }
780 }
781
782 /*************************************************************************
783 |*
784 |* SwFrm::Remove()
785 |*
786 |* Ersterstellung AK 01-Mar-1991
787 |* Letzte Aenderung MA 07. Dec. 95
788 |*
789 |*************************************************************************/
Remove()790 void SwFrm::Remove()
791 {
792 ASSERT( pUpper, "Removen ohne Upper?" );
793
794 if( pPrev )
795 // einer aus der Mitte wird removed
796 pPrev->pNext = pNext;
797 else
798 { // der erste in einer Folge wird removed
799 ASSERT( pUpper->pLower == this, "Layout inkonsistent." );
800 pUpper->pLower = pNext;
801 }
802 if( pNext )
803 pNext->pPrev = pPrev;
804
805 // Verbindung kappen.
806 pNext = pPrev = 0;
807 pUpper = 0;
808 }
809 /*************************************************************************
810 |*
811 |* SwCntntFrm::Paste()
812 |*
813 |* Ersterstellung MA 23. Feb. 94
814 |* Letzte Aenderung MA 09. Sep. 98
815 |*
816 |*************************************************************************/
Paste(SwFrm * pParent,SwFrm * pSibling)817 void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
818 {
819 ASSERT( pParent, "Kein Parent fuer Paste." );
820 ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
821 ASSERT( pParent != this, "Bin selbst der Parent." );
822 ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
823 ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
824 "Bin noch irgendwo angemeldet." );
825 ASSERT( !pSibling || pSibling->IsFlowFrm(),
826 "<SwCntntFrm::Paste(..)> - sibling not of expected type." )
827
828 //In den Baum einhaengen.
829 InsertBefore( (SwLayoutFrm*)pParent, pSibling );
830
831 SwPageFrm *pPage = FindPageFrm();
832 _InvalidateAll();
833 InvalidatePage( pPage );
834
835 if( pPage )
836 {
837 pPage->InvalidateSpelling();
838 pPage->InvalidateSmartTags(); // SMARTTAGS
839 pPage->InvalidateAutoCompleteWords();
840 pPage->InvalidateWordCount();
841 }
842
843 if ( GetNext() )
844 {
845 SwFrm* pNxt = GetNext();
846 pNxt->_InvalidatePrt();
847 pNxt->_InvalidatePos();
848 pNxt->InvalidatePage( pPage );
849 if( pNxt->IsSctFrm() )
850 pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt();
851 if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() )
852 pNxt->Prepare( PREP_FTN, 0, sal_False );
853 }
854
855 if ( Frm().Height() )
856 pParent->Grow( Frm().Height() );
857
858 if ( Frm().Width() != pParent->Prt().Width() )
859 Prepare( PREP_FIXSIZE_CHG );
860
861 if ( GetPrev() )
862 {
863 if ( IsFollow() )
864 //Ich bin jetzt direkter Nachfolger meines Masters geworden
865 ((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS );
866 else
867 {
868 if ( GetPrev()->Frm().Height() !=
869 GetPrev()->Prt().Height() + GetPrev()->Prt().Top() )
870 //Umrandung zu beruecksichtigen?
871 GetPrev()->_InvalidatePrt();
872 // OD 18.02.2003 #104989# - force complete paint of previous frame,
873 // if frame is inserted at the end of a section frame, in order to
874 // get subsidiary lines repainted for the section.
875 if ( pParent->IsSctFrm() && !GetNext() )
876 {
877 // force complete paint of previous frame, if new inserted frame
878 // in the section is the last one.
879 GetPrev()->SetCompletePaint();
880 }
881 GetPrev()->InvalidatePage( pPage );
882 }
883 }
884 if ( IsInFtn() )
885 {
886 SwFrm* pFrm = GetIndPrev();
887 if( pFrm && pFrm->IsSctFrm() )
888 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
889 if( pFrm )
890 pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
891 if( !GetNext() )
892 {
893 pFrm = FindFtnFrm()->GetNext();
894 if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) )
895 pFrm->_InvalidatePrt();
896 }
897 }
898
899 _InvalidateLineNum();
900 SwFrm *pNxt = FindNextCnt();
901 if ( pNxt )
902 {
903 while ( pNxt && pNxt->IsInTab() )
904 {
905 if( 0 != (pNxt = pNxt->FindTabFrm()) )
906 pNxt = pNxt->FindNextCnt();
907 }
908 if ( pNxt )
909 {
910 pNxt->_InvalidateLineNum();
911 if ( pNxt != GetNext() )
912 pNxt->InvalidatePage();
913 }
914 }
915 }
916
917 /*************************************************************************
918 |*
919 |* SwCntntFrm::Cut()
920 |*
921 |* Ersterstellung AK 14-Feb-1991
922 |* Letzte Aenderung MA 09. Sep. 98
923 |*
924 |*************************************************************************/
Cut()925 void SwCntntFrm::Cut()
926 {
927 ASSERT( GetUpper(), "Cut ohne Upper()." );
928
929 SwPageFrm *pPage = FindPageFrm();
930 InvalidatePage( pPage );
931 SwFrm *pFrm = GetIndPrev();
932 if( pFrm )
933 {
934 if( pFrm->IsSctFrm() )
935 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
936 if ( pFrm && pFrm->IsCntntFrm() )
937 {
938 pFrm->_InvalidatePrt();
939 if( IsInFtn() )
940 pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
941 }
942 // --> OD 2004-07-15 #i26250# - invalidate printing area of previous
943 // table frame.
944 else if ( pFrm && pFrm->IsTabFrm() )
945 {
946 pFrm->InvalidatePrt();
947 }
948 // <--
949 }
950
951 SwFrm *pNxt = FindNextCnt();
952 if ( pNxt )
953 {
954 while ( pNxt && pNxt->IsInTab() )
955 {
956 if( 0 != (pNxt = pNxt->FindTabFrm()) )
957 pNxt = pNxt->FindNextCnt();
958 }
959 if ( pNxt )
960 {
961 pNxt->_InvalidateLineNum();
962 if ( pNxt != GetNext() )
963 pNxt->InvalidatePage();
964 }
965 }
966
967 if( 0 != (pFrm = GetIndNext()) )
968 { //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
969 //berechnet, der ist jetzt, wo er der erste wird obsolet bzw. anders.
970 pFrm->_InvalidatePrt();
971 pFrm->_InvalidatePos();
972 pFrm->InvalidatePage( pPage );
973 if( pFrm->IsSctFrm() )
974 {
975 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
976 if( pFrm )
977 {
978 pFrm->_InvalidatePrt();
979 pFrm->_InvalidatePos();
980 pFrm->InvalidatePage( pPage );
981 }
982 }
983 if( pFrm && IsInFtn() )
984 pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
985 if( IsInSct() && !GetPrev() )
986 {
987 SwSectionFrm* pSct = FindSctFrm();
988 if( !pSct->IsFollow() )
989 {
990 pSct->_InvalidatePrt();
991 pSct->InvalidatePage( pPage );
992 }
993 }
994 }
995 else
996 {
997 InvalidateNextPos();
998 //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
999 if ( 0 != (pFrm = GetPrev()) )
1000 { pFrm->SetRetouche();
1001 pFrm->Prepare( PREP_WIDOWS_ORPHANS );
1002 pFrm->_InvalidatePos();
1003 pFrm->InvalidatePage( pPage );
1004 }
1005 //Wenn ich der einzige CntntFrm in meinem Upper bin (war), so muss
1006 //er die Retouche uebernehmen.
1007 //Ausserdem kann eine Leerseite entstanden sein.
1008 else
1009 { SwRootFrm *pRoot = getRootFrm();
1010 if ( pRoot )
1011 {
1012 pRoot->SetSuperfluous();
1013 GetUpper()->SetCompletePaint();
1014 GetUpper()->InvalidatePage( pPage );
1015 }
1016 if( IsInSct() )
1017 {
1018 SwSectionFrm* pSct = FindSctFrm();
1019 if( !pSct->IsFollow() )
1020 {
1021 pSct->_InvalidatePrt();
1022 pSct->InvalidatePage( pPage );
1023 }
1024 }
1025 // --> FME 2005-08-03 #i52253# The master table should take care
1026 // of removing the follow flow line.
1027 if ( IsInTab() )
1028 {
1029 SwTabFrm* pThisTab = FindTabFrm();
1030 SwTabFrm* pMasterTab = pThisTab && pThisTab->IsFollow() ? pThisTab->FindMaster() : 0;
1031 if ( pMasterTab )
1032 {
1033 pMasterTab->_InvalidatePos();
1034 pMasterTab->SetRemoveFollowFlowLinePending( sal_True );
1035 }
1036 }
1037 // <--
1038 }
1039 }
1040 //Erst removen, dann Upper Shrinken.
1041 SwLayoutFrm *pUp = GetUpper();
1042 Remove();
1043 if ( pUp )
1044 {
1045 SwSectionFrm *pSct = 0;
1046 if ( !pUp->Lower() &&
1047 ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() ) ||
1048 ( pUp->IsInSct() &&
1049 // --> FME 2004-06-03 #i29438#
1050 // We have to consider the case that the section may be "empty"
1051 // except from a temporary empty table frame.
1052 // This can happen due to the new cell split feature.
1053 !pUp->IsCellFrm() &&
1054 // <--
1055 // --> OD 2006-01-04 #126020# - adjust check for empty section
1056 // --> OD 2006-02-01 #130797# - correct fix #126020#
1057 !(pSct = pUp->FindSctFrm())->ContainsCntnt() &&
1058 !pSct->ContainsAny( true ) ) ) )
1059 // <--
1060 {
1061 if ( pUp->GetUpper() )
1062 {
1063 // --> OD 2006-09-25 #b6448963#
1064 // prevent delete of <ColLocked> footnote frame
1065 // if( pUp->IsFtnFrm() )
1066 if ( pUp->IsFtnFrm() && !pUp->IsColLocked())
1067 // <--
1068 {
1069 if( pUp->GetNext() && !pUp->GetPrev() )
1070 {
1071 SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny();
1072 if( pTmp )
1073 pTmp->_InvalidatePrt();
1074 }
1075 pUp->Cut();
1076 delete pUp;
1077 }
1078 else
1079 {
1080 // --> OD 2006-09-25 #b6448963#
1081 // if ( pSct->IsColLocked() || !pSct->IsInFtn() )
1082 if ( pSct->IsColLocked() || !pSct->IsInFtn() ||
1083 ( pUp->IsFtnFrm() && pUp->IsColLocked() ) )
1084 // <--
1085 {
1086 pSct->DelEmpty( sal_False );
1087 // Wenn ein gelockter Bereich nicht geloescht werden darf,
1088 // so ist zumindest seine Groesse durch das Entfernen seines
1089 // letzten Contents ungueltig geworden.
1090 pSct->_InvalidateSize();
1091 }
1092 else
1093 {
1094 pSct->DelEmpty( sal_True );
1095 delete pSct;
1096 }
1097 }
1098 }
1099 }
1100 else
1101 {
1102 SWRECTFN( this )
1103 long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1104 if( nFrmHeight )
1105 pUp->Shrink( nFrmHeight );
1106 }
1107 }
1108 }
1109
1110 /*************************************************************************
1111 |*
1112 |* SwLayoutFrm::Paste()
1113 |*
1114 |* Ersterstellung MA 23. Feb. 94
1115 |* Letzte Aenderung MA 23. Feb. 94
1116 |*
1117 |*************************************************************************/
Paste(SwFrm * pParent,SwFrm * pSibling)1118 void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
1119 {
1120 ASSERT( pParent, "Kein Parent fuer Paste." );
1121 ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
1122 ASSERT( pParent != this, "Bin selbst der Parent." );
1123 ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
1124 ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
1125 "Bin noch irgendwo angemeldet." );
1126
1127 //In den Baum einhaengen.
1128 InsertBefore( (SwLayoutFrm*)pParent, pSibling );
1129
1130 // OD 24.10.2002 #103517# - correct setting of variable <fnRect>
1131 // <fnRect> is used for the following:
1132 // (1) To invalidate the frame's size, if its size, which has to be the
1133 // same as its upper/parent, differs from its upper's/parent's.
1134 // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its
1135 // size, which is not determined by its upper/parent.
1136 // Which size is which depends on the frame type and the layout direction
1137 // (vertical or horizontal).
1138 // There are the following cases:
1139 // (A) Header and footer frames both in vertical and in horizontal layout
1140 // have to size the width to the upper/parent. A dimension in the height
1141 // has to cause a adjustment/grow of the upper/parent.
1142 // --> <fnRect> = fnRectHori
1143 // (B) Cell and column frames in vertical layout, the width has to be the
1144 // same as upper/parent and a dimension in height causes adjustment/grow
1145 // of the upper/parent.
1146 // --> <fnRect> = fnRectHori
1147 // in horizontal layout the other way around
1148 // --> <fnRect> = fnRectVert
1149 // (C) Other frames in vertical layout, the height has to be the
1150 // same as upper/parent and a dimension in width causes adjustment/grow
1151 // of the upper/parent.
1152 // --> <fnRect> = fnRectVert
1153 // in horizontal layout the other way around
1154 // --> <fnRect> = fnRectHori
1155 //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert;
1156 SwRectFn fnRect;
1157 if ( IsHeaderFrm() || IsFooterFrm() )
1158 fnRect = fnRectHori;
1159 else if ( IsCellFrm() || IsColumnFrm() )
1160 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1161 fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert );
1162 else
1163 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1164 fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
1165
1166
1167 if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)())
1168 _InvalidateSize();
1169 _InvalidatePos();
1170 const SwPageFrm *pPage = FindPageFrm();
1171 InvalidatePage( pPage );
1172 SwFrm *pFrm;
1173 if( !IsColumnFrm() )
1174 {
1175 if( 0 != ( pFrm = GetIndNext() ) )
1176 {
1177 pFrm->_InvalidatePos();
1178 if( IsInFtn() )
1179 {
1180 if( pFrm->IsSctFrm() )
1181 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1182 if( pFrm )
1183 pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
1184 }
1185 }
1186 if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) )
1187 {
1188 if( pFrm->IsSctFrm() )
1189 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1190 if( pFrm )
1191 pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
1192 }
1193 }
1194
1195 if( (Frm().*fnRect->fnGetHeight)() )
1196 {
1197 // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
1198 // die sich nicht in Rahmen befinden
1199 sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
1200 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
1201 : NA_GROW_SHRINK;
1202 SwTwips nGrow = (Frm().*fnRect->fnGetHeight)();
1203 if( NA_ONLY_ADJUST == nAdjust )
1204 AdjustNeighbourhood( nGrow );
1205 else
1206 {
1207 SwTwips nReal = 0;
1208 if( NA_ADJUST_GROW == nAdjust )
1209 nReal = AdjustNeighbourhood( nGrow );
1210 if( nReal < nGrow )
1211 nReal += pParent->Grow( nGrow - nReal );
1212 if( NA_GROW_ADJUST == nAdjust && nReal < nGrow )
1213 AdjustNeighbourhood( nGrow - nReal );
1214 }
1215 }
1216 }
1217
1218 /*************************************************************************
1219 |*
1220 |* SwLayoutFrm::Cut()
1221 |*
1222 |* Ersterstellung MA 23. Feb. 94
1223 |* Letzte Aenderung MA 23. Feb. 94
1224 |*
1225 |*************************************************************************/
Cut()1226 void SwLayoutFrm::Cut()
1227 {
1228 if ( GetNext() )
1229 GetNext()->_InvalidatePos();
1230
1231 SWRECTFN( this )
1232 SwTwips nShrink = (Frm().*fnRect->fnGetHeight)();
1233
1234 //Erst removen, dann Upper Shrinken.
1235 SwLayoutFrm *pUp = GetUpper();
1236
1237 // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
1238 // die sich nicht in Rahmen befinden
1239
1240 // Remove must not be called before a AdjustNeighbourhood, but it has to
1241 // be called before the upper-shrink-call, if the upper-shrink takes care
1242 // of his content
1243 if ( pUp && nShrink )
1244 {
1245 if( pUp->IsFtnBossFrm() )
1246 {
1247 sal_uInt8 nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this );
1248 if( NA_ONLY_ADJUST == nAdjust )
1249 AdjustNeighbourhood( -nShrink );
1250 else
1251 {
1252 SwTwips nReal = 0;
1253 if( NA_ADJUST_GROW == nAdjust )
1254 nReal = -AdjustNeighbourhood( -nShrink );
1255 if( nReal < nShrink )
1256 {
1257 SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)();
1258 (Frm().*fnRect->fnSetHeight)( 0 );
1259 nReal += pUp->Shrink( nShrink - nReal );
1260 (Frm().*fnRect->fnSetHeight)( nOldHeight );
1261 }
1262 if( NA_GROW_ADJUST == nAdjust && nReal < nShrink )
1263 AdjustNeighbourhood( nReal - nShrink );
1264 }
1265 Remove();
1266 }
1267 else
1268 {
1269 Remove();
1270 pUp->Shrink( nShrink );
1271 }
1272 }
1273 else
1274 Remove();
1275
1276 if( pUp && !pUp->Lower() )
1277 {
1278 pUp->SetCompletePaint();
1279 pUp->InvalidatePage();
1280 }
1281 }
1282
1283 /*************************************************************************
1284 |*
1285 |* SwFrm::Grow()
1286 |*
1287 |* Ersterstellung AK 19-Feb-1991
1288 |* Letzte Aenderung MA 05. May. 94
1289 |*
1290 |*************************************************************************/
Grow(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)1291 SwTwips SwFrm::Grow( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1292 {
1293 ASSERT( nDist >= 0, "Negatives Wachstum?" );
1294
1295 PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist )
1296
1297 if ( nDist )
1298 {
1299 SWRECTFN( this )
1300
1301 SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1302 if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) )
1303 nDist = LONG_MAX - nPrtHeight;
1304
1305 if ( IsFlyFrm() )
1306 return ((SwFlyFrm*)this)->_Grow( nDist, bTst );
1307 else if( IsSctFrm() )
1308 return ((SwSectionFrm*)this)->_Grow( nDist, bTst );
1309 else
1310 {
1311 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1312 if ( pThisCell )
1313 {
1314 const SwTabFrm* pTab = FindTabFrm();
1315
1316 // NEW TABLES
1317 if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
1318 pThisCell->GetLayoutRowSpan() < 1 )
1319 return 0;
1320 }
1321
1322 const SwTwips nReal = GrowFrm( nDist, bTst, bInfo );
1323 if( !bTst )
1324 {
1325 nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1326 (Prt().*fnRect->fnSetHeight)( nPrtHeight +
1327 ( IsCntntFrm() ? nDist : nReal ) );
1328 }
1329 return nReal;
1330 }
1331 }
1332 return 0L;
1333 }
1334
1335 /*************************************************************************
1336 |*
1337 |* SwFrm::Shrink()
1338 |*
1339 |* Ersterstellung AK 14-Feb-1991
1340 |* Letzte Aenderung MA 05. May. 94
1341 |*
1342 |*************************************************************************/
Shrink(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)1343 SwTwips SwFrm::Shrink( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1344 {
1345 ASSERT( nDist >= 0, "Negative Verkleinerung?" );
1346
1347 PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist )
1348
1349 if ( nDist )
1350 {
1351 if ( IsFlyFrm() )
1352 return ((SwFlyFrm*)this)->_Shrink( nDist, bTst );
1353 else if( IsSctFrm() )
1354 return ((SwSectionFrm*)this)->_Shrink( nDist, bTst );
1355 else
1356 {
1357 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
1358 if ( pThisCell )
1359 {
1360 const SwTabFrm* pTab = FindTabFrm();
1361
1362 // NEW TABLES
1363 if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
1364 pThisCell->GetLayoutRowSpan() < 1 )
1365 return 0;
1366 }
1367
1368 SWRECTFN( this )
1369 SwTwips nReal = (Frm().*fnRect->fnGetHeight)();
1370 ShrinkFrm( nDist, bTst, bInfo );
1371 nReal -= (Frm().*fnRect->fnGetHeight)();
1372 if( !bTst )
1373 {
1374 const SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1375 (Prt().*fnRect->fnSetHeight)( nPrtHeight -
1376 ( IsCntntFrm() ? nDist : nReal ) );
1377 }
1378 return nReal;
1379 }
1380 }
1381 return 0L;
1382 }
1383
1384 /*************************************************************************
1385 |*
1386 |* SwFrm::AdjustNeighbourhood()
1387 |*
1388 |* Beschreibung Wenn sich die Groesse eines Frm's direkt unterhalb
1389 |* eines Fussnotenbosses (Seite/Spalte) veraendert hat, so muss dieser
1390 |* "Normalisiert" werden.
1391 |* Es gibt dort immer einen Frame, der den "maximal moeglichen" Raum
1392 |* einnimmt (der Frame, der den Body.Text enhaelt) und keinen oder
1393 |* mehrere Frames die den Platz einnehmen den sie halt brauchen
1394 |* (Kopf-/Fussbereich, Fussnoten).
1395 |* Hat sich einer der Frames veraendert, so muss der Body-Text-Frame
1396 |* entsprechen wachsen oder schrumpfen; unabhaegig davon, dass er fix ist.
1397 |* !! Ist es moeglich dies allgemeiner zu loesen, also nicht auf die
1398 |* Seite beschraenkt und nicht auf einen Speziellen Frame, der den
1399 |* maximalen Platz einnimmt (gesteuert ueber Attribut FrmSize)? Probleme:
1400 |* Was ist wenn mehrere Frames nebeneinander stehen, die den maximalen
1401 |* Platz einnehmen?
1402 |* Wie wird der Maximale Platz berechnet?
1403 |* Wie klein duerfen diese Frames werden?
1404 |*
1405 |* Es wird auf jeden Fall nur so viel Platz genehmigt, dass ein
1406 |* Minimalwert fuer die Hoehe des Bodys nicht unterschritten wird.
1407 |*
1408 |* Parameter: nDiff ist der Betrag, um den Platz geschaffen werden muss
1409 |*
1410 |* Ersterstellung MA 07. May. 92
1411 |* Letzte Aenderung AMA 02. Nov. 98
1412 |*
1413 |*************************************************************************/
AdjustNeighbourhood(SwTwips nDiff,sal_Bool bTst)1414 SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, sal_Bool bTst )
1415 {
1416 PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff );
1417
1418 if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // nur innerhalb von Seiten/Spalten
1419 return 0L;
1420
1421 const ViewShell *pSh = getRootFrm()->GetCurrShell();
1422 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1423
1424 //Der (Page)Body veraendert sich nur im BrowseMode, aber nicht wenn er
1425 //Spalten enthaelt.
1426 if ( IsPageBodyFrm() && (!bBrowse ||
1427 (((SwLayoutFrm*)this)->Lower() &&
1428 ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) )
1429 return 0L;
1430
1431 //In der BrowseView kann der PageFrm selbst ersteinmal einiges von den
1432 //Wuenschen abfangen.
1433 long nBrowseAdd = 0;
1434 if ( bBrowse && GetUpper()->IsPageFrm() ) // nur (Page)BodyFrms
1435 {
1436 ViewShell *pViewShell = getRootFrm()->GetCurrShell();
1437 SwLayoutFrm *pUp = GetUpper();
1438 long nChg;
1439 const long nUpPrtBottom = pUp->Frm().Height() -
1440 pUp->Prt().Height() - pUp->Prt().Top();
1441 SwRect aInva( pUp->Frm() );
1442 if ( pViewShell )
1443 {
1444 aInva.Pos().X() = pViewShell->VisArea().Left();
1445 aInva.Width( pViewShell->VisArea().Width() );
1446 }
1447 if ( nDiff > 0 )
1448 {
1449 nChg = BROWSE_HEIGHT - pUp->Frm().Height();
1450 nChg = Min( nDiff, nChg );
1451
1452 if ( !IsBodyFrm() )
1453 {
1454 SetCompletePaint();
1455 if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->Frm().Height() )
1456 {
1457 //Ersteinmal den Body verkleinern. Der waechst dann schon
1458 //wieder.
1459 SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont();
1460 const long nTmp = nChg - pBody->Prt().Height();
1461 if ( !bTst )
1462 {
1463 pBody->Frm().Height(Max( 0L, pBody->Frm().Height() - nChg ));
1464 pBody->_InvalidatePrt();
1465 pBody->_InvalidateSize();
1466 if ( pBody->GetNext() )
1467 pBody->GetNext()->_InvalidatePos();
1468 if ( !IsHeaderFrm() )
1469 pBody->SetCompletePaint();
1470 }
1471 nChg = nTmp <= 0 ? 0 : nTmp;
1472 }
1473 }
1474
1475 const long nTmp = nUpPrtBottom + 20;
1476 aInva.Top( aInva.Bottom() - nTmp );
1477 aInva.Height( nChg + nTmp );
1478 }
1479 else
1480 {
1481 //Die Seite kann bis auf 0 schrumpfen. Die erste Seite bleibt
1482 //mindestens so gross wie die VisArea.
1483 nChg = nDiff;
1484 long nInvaAdd = 0;
1485 if ( pViewShell && !pUp->GetPrev() &&
1486 pUp->Frm().Height() + nDiff < pViewShell->VisArea().Height() )
1487 {
1488 //Das heisst aber wiederum trotzdem, das wir geeignet invalidieren
1489 //muessen.
1490 nChg = pViewShell->VisArea().Height() - pUp->Frm().Height();
1491 nInvaAdd = -(nDiff - nChg);
1492 }
1493
1494 //Invalidieren inklusive unterem Rand.
1495 long nBorder = nUpPrtBottom + 20;
1496 nBorder -= nChg;
1497 aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
1498 if ( !IsBodyFrm() )
1499 {
1500 SetCompletePaint();
1501 if ( !IsHeaderFrm() )
1502 ((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint();
1503 }
1504 //Wegen der Rahmen die Seite invalidieren. Dadurch wird die Seite
1505 //wieder entsprechend gross wenn ein Rahmen nicht passt. Das
1506 //funktioniert anderfalls nur zufaellig fuer absatzgebundene Rahmen
1507 //(NotifyFlys).
1508 pUp->InvalidateSize();
1509 }
1510 if ( !bTst )
1511 {
1512 //Unabhaengig von nChg
1513 if ( pViewShell && aInva.HasArea() && pUp->GetUpper() )
1514 pViewShell->InvalidateWindows( aInva );
1515 }
1516 if ( !bTst && nChg )
1517 {
1518 const SwRect aOldRect( pUp->Frm() );
1519 pUp->Frm().SSize().Height() += nChg;
1520 pUp->Prt().SSize().Height() += nChg;
1521 if ( pViewShell )
1522 pViewShell->Imp()->SetFirstVisPageInvalid();
1523
1524 if ( GetNext() )
1525 GetNext()->_InvalidatePos();
1526
1527 //Ggf. noch ein Repaint ausloesen.
1528 const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos();
1529 if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
1530 pViewShell->InvalidateWindows( pUp->Frm() );
1531
1532 if ( pUp->GetUpper() )
1533 {
1534 if ( pUp->GetNext() )
1535 pUp->GetNext()->InvalidatePos();
1536
1537 //Mies aber wahr: im Notify am ViewImp wird evtl. ein Calc
1538 //auf die Seite und deren Lower gerufen. Die Werte sollten
1539 //unverandert bleiben, weil der Aufrufer bereits fuer die
1540 //Anpassung von Frm und Prt sorgen wird.
1541 const long nOldFrmHeight = Frm().Height();
1542 const long nOldPrtHeight = Prt().Height();
1543 const sal_Bool bOldComplete = IsCompletePaint();
1544 if ( IsBodyFrm() )
1545 Prt().SSize().Height() = nOldFrmHeight;
1546
1547 // PAGES01
1548 if ( pUp->GetUpper() )
1549 static_cast<SwRootFrm*>(pUp->GetUpper())->CheckViewLayout( 0, 0 );
1550 //((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect );
1551
1552 Frm().SSize().Height() = nOldFrmHeight;
1553 Prt().SSize().Height() = nOldPrtHeight;
1554 bCompletePaint = bOldComplete;
1555 }
1556 if ( !IsBodyFrm() )
1557 pUp->_InvalidateSize();
1558 InvalidatePage( (SwPageFrm*)pUp );
1559 }
1560 nDiff -= nChg;
1561 if ( !nDiff )
1562 return nChg;
1563 else
1564 nBrowseAdd = nChg;
1565 }
1566
1567 const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
1568
1569 SwTwips nReal = 0,
1570 nAdd = 0;
1571 SwFrm *pFrm = 0;
1572 SWRECTFN( this )
1573
1574 if( IsBodyFrm() )
1575 {
1576 if( IsInSct() )
1577 {
1578 SwSectionFrm *pSect = FindSctFrm();
1579 if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
1580 GetNext()->IsFtnContFrm() )
1581 {
1582 SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext();
1583 SwTwips nMinH = 0;
1584 SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
1585 sal_Bool bFtn = sal_False;
1586 while( pFtn )
1587 {
1588 if( !pFtn->GetAttr()->GetFtn().IsEndNote() )
1589 {
1590 nMinH += (pFtn->Frm().*fnRect->fnGetHeight)();
1591 bFtn = sal_True;
1592 }
1593 pFtn = (SwFtnFrm*)pFtn->GetNext();
1594 }
1595 if( bFtn )
1596 nMinH += (pCont->Prt().*fnRect->fnGetTop)();
1597 nReal = (pCont->Frm().*fnRect->fnGetHeight)() - nMinH;
1598 if( nReal > nDiff )
1599 nReal = nDiff;
1600 if( nReal > 0 )
1601 pFrm = GetNext();
1602 else
1603 nReal = 0;
1604 }
1605 if( !bTst && !pSect->IsColLocked() )
1606 pSect->InvalidateSize();
1607 }
1608 if( !pFrm )
1609 return nBrowseAdd;
1610 }
1611 else
1612 {
1613 const sal_Bool bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage();
1614 if ( bFtnPage && !IsFtnContFrm() )
1615 pFrm = (SwFrm*)pBoss->FindFtnCont();
1616 if ( !pFrm )
1617 pFrm = (SwFrm*)pBoss->FindBodyCont();
1618
1619 if ( !pFrm )
1620 return 0;
1621
1622 //Wenn ich keinen finde eruebrigt sich alles weitere.
1623 nReal = (pFrm->Frm().*fnRect->fnGetHeight)();
1624 if( nReal > nDiff )
1625 nReal = nDiff;
1626 if( !bFtnPage )
1627 {
1628 //Minimalgrenze beachten!
1629 if( nReal )
1630 {
1631 const SwTwips nMax = pBoss->GetVarSpace();
1632 if ( nReal > nMax )
1633 nReal = nMax;
1634 }
1635 if( !IsFtnContFrm() && nDiff > nReal &&
1636 pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm()
1637 && ( pFrm->GetNext()->IsVertical() == IsVertical() )
1638 )
1639 {
1640 //Wenn der Body nicht genuegend her gibt, kann ich noch mal
1641 //schauen ob es eine Fussnote gibt, falls ja kann dieser
1642 //entsprechend viel gemopst werden.
1643 const SwTwips nAddMax = (pFrm->GetNext()->Frm().*fnRect->
1644 fnGetHeight)();
1645 nAdd = nDiff - nReal;
1646 if ( nAdd > nAddMax )
1647 nAdd = nAddMax;
1648 if ( !bTst )
1649 {
1650 (pFrm->GetNext()->Frm().*fnRect->fnSetHeight)(nAddMax-nAdd);
1651 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1652 if( bVert && !bVertL2R && !bRev )
1653 pFrm->GetNext()->Frm().Pos().X() += nAdd;
1654 pFrm->GetNext()->InvalidatePrt();
1655 if ( pFrm->GetNext()->GetNext() )
1656 pFrm->GetNext()->GetNext()->_InvalidatePos();
1657 }
1658 }
1659 }
1660 }
1661
1662 if ( !bTst && nReal )
1663 {
1664 SwTwips nTmp = (pFrm->Frm().*fnRect->fnGetHeight)();
1665 (pFrm->Frm().*fnRect->fnSetHeight)( nTmp - nReal );
1666 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1667 if( bVert && !bVertL2R && !bRev )
1668 pFrm->Frm().Pos().X() += nReal;
1669 pFrm->InvalidatePrt();
1670 if ( pFrm->GetNext() )
1671 pFrm->GetNext()->_InvalidatePos();
1672 if( nReal < 0 && pFrm->IsInSct() )
1673 {
1674 SwLayoutFrm* pUp = pFrm->GetUpper();
1675 if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() &&
1676 !pUp->IsColLocked() )
1677 pUp->InvalidateSize();
1678 }
1679 if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() )
1680 {
1681 const SwSortedObjs &rObjs = *pBoss->GetDrawObjs();
1682 ASSERT( pBoss->IsPageFrm(), "Header/Footer out of page?" );
1683 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
1684 {
1685 SwAnchoredObject* pAnchoredObj = rObjs[i];
1686 if ( pAnchoredObj->ISA(SwFlyFrm) )
1687 {
1688 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1689 ASSERT( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" );
1690 const SwFmtVertOrient &rVert =
1691 pFly->GetFmt()->GetVertOrient();
1692 // Wann muss invalidiert werden?
1693 // Wenn ein Rahmen am SeitenTextBereich ausgerichtet ist,
1694 // muss bei Aenderung des Headers ein TOP, MIDDLE oder NONE,
1695 // bei Aenderung des Footers ein BOTTOM oder MIDDLE
1696 // ausgerichteter Rahmen seine Position neu berechnen.
1697 if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
1698 rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) &&
1699 ((IsHeaderFrm() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) ||
1700 (IsFooterFrm() && rVert.GetVertOrient()!=text::VertOrientation::NONE &&
1701 rVert.GetVertOrient() != text::VertOrientation::TOP)) )
1702 {
1703 pFly->_InvalidatePos();
1704 pFly->_Invalidate();
1705 }
1706 }
1707 }
1708 }
1709 }
1710 return (nBrowseAdd + nReal + nAdd);
1711 }
1712
1713 /*************************************************************************
1714 |*
1715 |* SwFrm::ImplInvalidateSize(), ImplInvalidatePrt(), ImplInvalidatePos(),
1716 |* ImplInvalidateLineNum()
1717 |*
1718 |* Ersterstellung MA 15. Oct. 92
1719 |* Letzte Aenderung MA 24. Mar. 94
1720 |*
1721 |*************************************************************************/
1722 /** method to perform additional actions on an invalidation
1723
1724 OD 2004-05-19 #i28701#
1725
1726 @author OD
1727 */
_ActionOnInvalidation(const InvalidationType)1728 void SwFrm::_ActionOnInvalidation( const InvalidationType )
1729 {
1730 // default behaviour is to perform no additional action
1731 }
1732
1733 /** method to determine, if an invalidation is allowed.
1734
1735 OD 2004-05-19 #i28701#
1736
1737 @author OD
1738 */
_InvalidationAllowed(const InvalidationType) const1739 bool SwFrm::_InvalidationAllowed( const InvalidationType ) const
1740 {
1741 // default behaviour is to allow invalidation
1742 return true;
1743 }
1744
ImplInvalidateSize()1745 void SwFrm::ImplInvalidateSize()
1746 {
1747 if ( _InvalidationAllowed( INVALID_SIZE ) )
1748 {
1749 bValidSize = sal_False;
1750 if ( IsFlyFrm() )
1751 ((SwFlyFrm*)this)->_Invalidate();
1752 else
1753 InvalidatePage();
1754
1755 // OD 2004-05-19 #i28701#
1756 _ActionOnInvalidation( INVALID_SIZE );
1757 }
1758 }
1759
ImplInvalidatePrt()1760 void SwFrm::ImplInvalidatePrt()
1761 {
1762 if ( _InvalidationAllowed( INVALID_PRTAREA ) )
1763 {
1764 bValidPrtArea = sal_False;
1765 if ( IsFlyFrm() )
1766 ((SwFlyFrm*)this)->_Invalidate();
1767 else
1768 InvalidatePage();
1769
1770 // OD 2004-05-19 #i28701#
1771 _ActionOnInvalidation( INVALID_PRTAREA );
1772 }
1773 }
1774
ImplInvalidatePos()1775 void SwFrm::ImplInvalidatePos()
1776 {
1777 if ( _InvalidationAllowed( INVALID_POS ) )
1778 {
1779 bValidPos = sal_False;
1780 if ( IsFlyFrm() )
1781 {
1782 ((SwFlyFrm*)this)->_Invalidate();
1783 }
1784 else
1785 {
1786 InvalidatePage();
1787 }
1788
1789 // OD 2004-05-19 #i28701#
1790 _ActionOnInvalidation( INVALID_POS );
1791 }
1792 }
1793
ImplInvalidateLineNum()1794 void SwFrm::ImplInvalidateLineNum()
1795 {
1796 if ( _InvalidationAllowed( INVALID_LINENUM ) )
1797 {
1798 bValidLineNum = sal_False;
1799 ASSERT( IsTxtFrm(), "line numbers are implemented for text only" );
1800 InvalidatePage();
1801
1802 // OD 2004-05-19 #i28701#
1803 _ActionOnInvalidation( INVALID_LINENUM );
1804 }
1805 }
1806
1807 /*************************************************************************
1808 |*
1809 |* SwFrm::ReinitializeFrmSizeAttrFlags
1810 |*
1811 |* Ersterstellung MA 15. Oct. 96
1812 |* Letzte Aenderung MA 15. Oct. 96
1813 |*
1814 |*************************************************************************/
ReinitializeFrmSizeAttrFlags()1815 void SwFrm::ReinitializeFrmSizeAttrFlags()
1816 {
1817 const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize();
1818 if ( ATT_VAR_SIZE == rFmtSize.GetHeightSizeType() ||
1819 ATT_MIN_SIZE == rFmtSize.GetHeightSizeType())
1820 {
1821 bFixSize = sal_False;
1822 if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) )
1823 {
1824 SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower();
1825 while ( pFrm )
1826 { pFrm->_InvalidateSize();
1827 pFrm->_InvalidatePrt();
1828 pFrm = pFrm->GetNext();
1829 }
1830 SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt();
1831 // --> OD 2004-12-20 #i36991# - be save.
1832 // E.g., a row can contain *no* content.
1833 if ( pCnt )
1834 {
1835 pCnt->InvalidatePage();
1836 do
1837 {
1838 pCnt->Prepare( PREP_ADJUST_FRM );
1839 pCnt->_InvalidateSize();
1840 pCnt = pCnt->GetNextCntntFrm();
1841 } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) );
1842 }
1843 // <--
1844 }
1845 }
1846 else if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
1847 {
1848 if( IsVertical() )
1849 ChgSize( Size( rFmtSize.GetWidth(), Frm().Height()));
1850 else
1851 ChgSize( Size( Frm().Width(), rFmtSize.GetHeight()));
1852 }
1853 }
1854
1855 /*************************************************************************
1856 |* SwFrm::ValidateThisAndAllLowers()
1857 *
1858 * FME 2007-08-30 #i81146# new loop control
1859 |*************************************************************************/
ValidateThisAndAllLowers(const sal_uInt16 nStage)1860 void SwFrm::ValidateThisAndAllLowers( const sal_uInt16 nStage )
1861 {
1862 // Stage 0: Only validate frames. Do not process any objects.
1863 // Stage 1: Only validate fly frames and all of their contents.
1864 // Stage 2: Validate all.
1865
1866 const bool bOnlyObject = 1 == nStage;
1867 const bool bIncludeObjects = 1 <= nStage;
1868
1869 if ( !bOnlyObject || ISA(SwFlyFrm) )
1870 {
1871 bValidSize = sal_True;
1872 bValidPrtArea = sal_True;
1873 bValidPos = sal_True;
1874 }
1875
1876 if ( bIncludeObjects )
1877 {
1878 const SwSortedObjs* pObjs = GetDrawObjs();
1879 if ( pObjs )
1880 {
1881 const sal_uInt32 nCnt = pObjs->Count();
1882 for ( sal_uInt32 i = 0; i < nCnt; ++i )
1883 {
1884 SwAnchoredObject* pAnchObj = (*pObjs)[i];
1885 if ( pAnchObj->ISA(SwFlyFrm) )
1886 static_cast<SwFlyFrm*>(pAnchObj)->ValidateThisAndAllLowers( 2 );
1887 else if ( pAnchObj->ISA(SwAnchoredDrawObject) )
1888 static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis();
1889 }
1890 }
1891 }
1892
1893 if ( IsLayoutFrm() )
1894 {
1895 SwFrm* pLower = static_cast<SwLayoutFrm*>(this)->Lower();
1896 while ( pLower )
1897 {
1898 pLower->ValidateThisAndAllLowers( nStage );
1899 pLower = pLower->GetNext();
1900 }
1901 }
1902 }
1903
1904 /*************************************************************************
1905 |*
1906 |* SwCntntFrm::GrowFrm()
1907 |*
1908 |* Ersterstellung MA 30. Jul. 92
1909 |* Letzte Aenderung MA 25. Mar. 99
1910 |*
1911 |*************************************************************************/
GrowFrm(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)1912 SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
1913 {
1914 SWRECTFN( this )
1915
1916 SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1917 if( nFrmHeight > 0 &&
1918 nDist > (LONG_MAX - nFrmHeight ) )
1919 nDist = LONG_MAX - nFrmHeight;
1920
1921 const ViewShell *pSh = getRootFrm()->GetCurrShell();
1922 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1923 const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
1924 if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() )
1925 {
1926 if ( !bTst )
1927 {
1928 (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
1929 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1930 if( IsVertical() && !IsVertLR() && !IsReverse() )
1931 Frm().Pos().X() -= nDist;
1932 if ( GetNext() )
1933 {
1934 GetNext()->InvalidatePos();
1935 }
1936 // --> OD 2004-07-05 #i28701# - Due to the new object positioning the
1937 // frame on the next page/column can flow backward (e.g. it was moved forward
1938 // due to the positioning of its objects ). Thus, invalivate this next frame,
1939 // if document compatibility option 'Consider wrapping style influence on
1940 // object positioning' is ON.
1941 else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1942 {
1943 InvalidateNextPos();
1944 }
1945 // <--
1946 }
1947 return 0;
1948 }
1949
1950 SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)();
1951 SwFrm *pFrm = GetUpper()->Lower();
1952 while( pFrm && nReal > 0 )
1953 { nReal -= (pFrm->Frm().*fnRect->fnGetHeight)();
1954 pFrm = pFrm->GetNext();
1955 }
1956
1957 if ( !bTst )
1958 {
1959 //Cntnts werden immer auf den gewuenschten Wert gebracht.
1960 long nOld = (Frm().*fnRect->fnGetHeight)();
1961 (Frm().*fnRect->fnSetHeight)( nOld + nDist );
1962 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1963 if( IsVertical()&& !IsVertLR() && !IsReverse() )
1964 Frm().Pos().X() -= nDist;
1965 if ( nOld && IsInTab() )
1966 {
1967 SwTabFrm *pTab = FindTabFrm();
1968 if ( pTab->GetTable()->GetHTMLTableLayout() &&
1969 !pTab->IsJoinLocked() &&
1970 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
1971 {
1972 pTab->InvalidatePos();
1973 pTab->SetResizeHTMLTable();
1974 }
1975 }
1976 }
1977
1978 //Upper nur growen wenn notwendig.
1979 if ( nReal < nDist )
1980 {
1981 if( GetUpper() )
1982 {
1983 if( bTst || !GetUpper()->IsFooterFrm() )
1984 nReal = GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
1985 bTst, bInfo );
1986 else
1987 {
1988 nReal = 0;
1989 GetUpper()->InvalidateSize();
1990 }
1991 }
1992 else
1993 nReal = 0;
1994 }
1995 else
1996 nReal = nDist;
1997
1998 // --> OD 2004-07-05 #i28701# - Due to the new object positioning the
1999 // frame on the next page/column can flow backward (e.g. it was moved forward
2000 // due to the positioning of its objects ). Thus, invalivate this next frame,
2001 // if document compatibility option 'Consider wrapping style influence on
2002 // object positioning' is ON.
2003 if ( !bTst )
2004 {
2005 if ( GetNext() )
2006 {
2007 GetNext()->InvalidatePos();
2008 }
2009 else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2010 {
2011 InvalidateNextPos();
2012 }
2013 }
2014 // <--
2015
2016 return nReal;
2017 }
2018
2019 /*************************************************************************
2020 |*
2021 |* SwCntntFrm::ShrinkFrm()
2022 |*
2023 |* Ersterstellung MA 30. Jul. 92
2024 |* Letzte Aenderung MA 05. May. 94
2025 |*
2026 |*************************************************************************/
ShrinkFrm(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)2027 SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2028 {
2029 SWRECTFN( this )
2030 ASSERT( nDist >= 0, "nDist < 0" );
2031 ASSERT( nDist <= (Frm().*fnRect->fnGetHeight)(),
2032 "nDist > als aktuelle Grosse." );
2033
2034 if ( !bTst )
2035 {
2036 SwTwips nRstHeight;
2037 if( GetUpper() )
2038 nRstHeight = (Frm().*fnRect->fnBottomDist)
2039 ( (GetUpper()->*fnRect->fnGetPrtBottom)() );
2040 else
2041 nRstHeight = 0;
2042 if( nRstHeight < 0 )
2043 {
2044 SwTwips nNextHeight = 0;
2045 if( GetUpper()->IsSctFrm() && nDist > LONG_MAX/2 )
2046 {
2047 SwFrm *pNxt = GetNext();
2048 while( pNxt )
2049 {
2050 nNextHeight += (pNxt->Frm().*fnRect->fnGetHeight)();
2051 pNxt = pNxt->GetNext();
2052 }
2053 }
2054 nRstHeight = nDist + nRstHeight - nNextHeight;
2055 }
2056 else
2057 nRstHeight = nDist;
2058 (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() - nDist );
2059 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2060 if( IsVertical() && !IsVertLR() )
2061 Frm().Pos().X() += nDist;
2062 nDist = nRstHeight;
2063 if ( IsInTab() )
2064 {
2065 SwTabFrm *pTab = FindTabFrm();
2066 if ( pTab->GetTable()->GetHTMLTableLayout() &&
2067 !pTab->IsJoinLocked() &&
2068 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
2069 {
2070 pTab->InvalidatePos();
2071 pTab->SetResizeHTMLTable();
2072 }
2073 }
2074 }
2075
2076 SwTwips nReal;
2077 if( GetUpper() && nDist > 0 )
2078 {
2079 if( bTst || !GetUpper()->IsFooterFrm() )
2080 nReal = GetUpper()->Shrink( nDist, bTst, bInfo );
2081 else
2082 {
2083 nReal = 0;
2084
2085 // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you,
2086 // if there are any objects anchored inside your content, which
2087 // overlap with the shrinking frame.
2088 // This may lead to a footer frame that is too big, but this is better
2089 // than looping.
2090 // #109722# : The fix for #108745# was too strict.
2091
2092 bool bInvalidate = true;
2093 const SwRect aRect( Frm() );
2094 const SwPageFrm* pPage = FindPageFrm();
2095 const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : 0;
2096 if( pSorted )
2097 {
2098 for ( sal_uInt16 i = 0; i < pSorted->Count(); ++i )
2099 {
2100 const SwAnchoredObject* pAnchoredObj = (*pSorted)[i];
2101 const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
2102
2103 if( aBound.Left() > aRect.Right() )
2104 continue;
2105
2106 if( aBound.IsOver( aRect ) )
2107 {
2108 const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
2109 if( SURROUND_THROUGHT != rFmt.GetSurround().GetSurround() )
2110 {
2111 const SwFrm* pAnchor = pAnchoredObj->GetAnchorFrm();
2112 if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() )
2113 {
2114 bInvalidate = false;
2115 break;
2116 }
2117 }
2118 }
2119 }
2120 }
2121
2122 if ( bInvalidate )
2123 GetUpper()->InvalidateSize();
2124 }
2125 }
2126 else
2127 nReal = 0;
2128
2129 if ( !bTst )
2130 {
2131 //Die Position des naechsten Frm's veraendert sich auf jeden Fall.
2132 InvalidateNextPos();
2133
2134 //Wenn ich keinen Nachfolger habe, so muss ich mich eben selbst um
2135 //die Retusche kuemmern.
2136 if ( !GetNext() )
2137 SetRetouche();
2138 }
2139 return nReal;
2140 }
2141
2142 /*************************************************************************
2143 |*
2144 |* SwCntntFrm::Modify()
2145 |*
2146 |* Beschreibung
2147 |* Ersterstellung AK 05-Mar-1991
2148 |* Letzte Aenderung MA 13. Oct. 95
2149 |*
2150 |*************************************************************************/
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)2151 void SwCntntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
2152 {
2153 sal_uInt8 nInvFlags = 0;
2154
2155 if( pNew && RES_ATTRSET_CHG == pNew->Which() )
2156 {
2157 SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
2158 SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
2159 SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
2160 SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
2161 while( sal_True )
2162 {
2163 _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
2164 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
2165 &aOldSet, &aNewSet );
2166 if( aNIter.IsAtEnd() )
2167 break;
2168 aNIter.NextItem();
2169 aOIter.NextItem();
2170 }
2171 if ( aOldSet.Count() || aNewSet.Count() )
2172 SwFrm::Modify( &aOldSet, &aNewSet );
2173 }
2174 else
2175 _UpdateAttr( pOld, pNew, nInvFlags );
2176
2177 if ( nInvFlags != 0 )
2178 {
2179 SwPageFrm *pPage = FindPageFrm();
2180 InvalidatePage( pPage );
2181 if ( nInvFlags & 0x01 )
2182 SetCompletePaint();
2183 if ( nInvFlags & 0x02 )
2184 _InvalidatePos();
2185 if ( nInvFlags & 0x04 )
2186 _InvalidateSize();
2187 if ( nInvFlags & 0x88 )
2188 {
2189 if( IsInSct() && !GetPrev() )
2190 {
2191 SwSectionFrm *pSect = FindSctFrm();
2192 if( pSect->ContainsAny() == this )
2193 {
2194 pSect->_InvalidatePrt();
2195 pSect->InvalidatePage( pPage );
2196 }
2197 }
2198 _InvalidatePrt();
2199 }
2200 SwFrm* pNextFrm = GetIndNext();
2201 if ( pNextFrm && nInvFlags & 0x10)
2202 {
2203 pNextFrm->_InvalidatePrt();
2204 pNextFrm->InvalidatePage( pPage );
2205 }
2206 if ( pNextFrm && nInvFlags & 0x80 )
2207 {
2208 pNextFrm->SetCompletePaint();
2209 }
2210 if ( nInvFlags & 0x20 )
2211 {
2212 SwFrm* pPrevFrm = GetPrev();
2213 if ( pPrevFrm )
2214 {
2215 pPrevFrm->_InvalidatePrt();
2216 pPrevFrm->InvalidatePage( pPage );
2217 }
2218 }
2219 if ( nInvFlags & 0x40 )
2220 InvalidateNextPos();
2221 }
2222 }
2223
_UpdateAttr(const SfxPoolItem * pOld,const SfxPoolItem * pNew,sal_uInt8 & rInvFlags,SwAttrSetChg * pOldSet,SwAttrSetChg * pNewSet)2224 void SwCntntFrm::_UpdateAttr( const SfxPoolItem* pOld, const SfxPoolItem* pNew,
2225 sal_uInt8 &rInvFlags,
2226 SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2227 {
2228 sal_Bool bClear = sal_True;
2229 sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2230 switch ( nWhich )
2231 {
2232 case RES_FMT_CHG:
2233 rInvFlags = 0xFF;
2234 /* kein break hier */
2235
2236 case RES_PAGEDESC: //Attributaenderung (an/aus)
2237 if ( IsInDocBody() && !IsInTab() )
2238 {
2239 rInvFlags |= 0x02;
2240 SwPageFrm *pPage = FindPageFrm();
2241 if ( !GetPrev() )
2242 CheckPageDescs( pPage );
2243 if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() )
2244 ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( sal_True );
2245 SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
2246 pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
2247 }
2248 break;
2249
2250 case RES_UL_SPACE:
2251 {
2252 // OD 2004-02-18 #106629# - correction
2253 // Invalidation of the printing area of next frame, not only
2254 // for footnote content.
2255 if ( !GetIndNext() )
2256 {
2257 SwFrm* pNxt = FindNext();
2258 if ( pNxt )
2259 {
2260 SwPageFrm* pPg = pNxt->FindPageFrm();
2261 pNxt->InvalidatePage( pPg );
2262 pNxt->_InvalidatePrt();
2263 if( pNxt->IsSctFrm() )
2264 {
2265 SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2266 if( pCnt )
2267 {
2268 pCnt->_InvalidatePrt();
2269 pCnt->InvalidatePage( pPg );
2270 }
2271 }
2272 pNxt->SetCompletePaint();
2273 }
2274 }
2275 // OD 2004-03-17 #i11860#
2276 if ( GetIndNext() &&
2277 !GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
2278 {
2279 // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)>
2280 GetIndNext()->InvalidateObjs( true );
2281 }
2282 Prepare( PREP_UL_SPACE ); //TxtFrm muss Zeilenabst. korrigieren.
2283 rInvFlags |= 0x80;
2284 /* kein Break hier */
2285 }
2286 case RES_LR_SPACE:
2287 case RES_BOX:
2288 case RES_SHADOW:
2289 Prepare( PREP_FIXSIZE_CHG );
2290 SwFrm::Modify( pOld, pNew );
2291 rInvFlags |= 0x30;
2292 break;
2293
2294 case RES_BREAK:
2295 {
2296 rInvFlags |= 0x42;
2297 const IDocumentSettingAccess* pIDSA = GetUpper()->GetFmt()->getIDocumentSettingAccess();
2298 if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
2299 pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) )
2300 {
2301 rInvFlags |= 0x1;
2302 SwFrm* pNxt = FindNext();
2303 if( pNxt )
2304 {
2305 SwPageFrm* pPg = pNxt->FindPageFrm();
2306 pNxt->InvalidatePage( pPg );
2307 pNxt->_InvalidatePrt();
2308 if( pNxt->IsSctFrm() )
2309 {
2310 SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
2311 if( pCnt )
2312 {
2313 pCnt->_InvalidatePrt();
2314 pCnt->InvalidatePage( pPg );
2315 }
2316 }
2317 pNxt->SetCompletePaint();
2318 }
2319 }
2320 }
2321 break;
2322
2323 // OD 2004-02-26 #i25029#
2324 case RES_PARATR_CONNECT_BORDER:
2325 {
2326 rInvFlags |= 0x01;
2327 if ( IsTxtFrm() )
2328 {
2329 InvalidateNextPrtArea();
2330 }
2331 if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() )
2332 {
2333 FindTabFrm()->InvalidateSize();
2334 }
2335 }
2336 break;
2337
2338 case RES_PARATR_TABSTOP:
2339 case RES_CHRATR_PROPORTIONALFONTSIZE:
2340 case RES_CHRATR_SHADOWED:
2341 case RES_CHRATR_AUTOKERN:
2342 case RES_CHRATR_UNDERLINE:
2343 case RES_CHRATR_OVERLINE:
2344 case RES_CHRATR_KERNING:
2345 case RES_CHRATR_FONT:
2346 case RES_CHRATR_FONTSIZE:
2347 case RES_CHRATR_ESCAPEMENT:
2348 case RES_CHRATR_CONTOUR:
2349 case RES_PARATR_NUMRULE:
2350 rInvFlags |= 0x01;
2351 break;
2352
2353
2354 case RES_FRM_SIZE:
2355 rInvFlags |= 0x01;
2356 /* no break here */
2357
2358 default:
2359 bClear = sal_False;
2360 }
2361 if ( bClear )
2362 {
2363 if ( pOldSet || pNewSet )
2364 {
2365 if ( pOldSet )
2366 pOldSet->ClearItem( nWhich );
2367 if ( pNewSet )
2368 pNewSet->ClearItem( nWhich );
2369 }
2370 else
2371 SwFrm::Modify( pOld, pNew );
2372 }
2373 }
2374
2375 /*************************************************************************
2376 |*
2377 |* SwLayoutFrm::SwLayoutFrm()
2378 |*
2379 |* Ersterstellung AK 14-Feb-1991
2380 |* Letzte Aenderung MA 12. May. 95
2381 |*
2382 |*************************************************************************/
SwLayoutFrm(SwFrmFmt * pFmt,SwFrm * pSib)2383 SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt, SwFrm* pSib ):
2384 SwFrm( pFmt, pSib ),
2385 pLower( 0 )
2386 {
2387 const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize();
2388 if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
2389 bFixSize = sal_True;
2390 }
2391
2392 // --> OD 2004-06-29 #i28701#
2393 TYPEINIT1(SwLayoutFrm,SwFrm);
2394 // <--
2395 /*-----------------10.06.99 09:42-------------------
2396 * SwLayoutFrm::InnerHeight()
2397 * --------------------------------------------------*/
2398
InnerHeight() const2399 SwTwips SwLayoutFrm::InnerHeight() const
2400 {
2401 if( !Lower() )
2402 return 0;
2403 SwTwips nRet = 0;
2404 const SwFrm* pCnt = Lower();
2405 SWRECTFN( this )
2406 if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() )
2407 {
2408 do
2409 {
2410 SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight();
2411 if( pCnt->GetValidPrtAreaFlag() )
2412 nTmp += (pCnt->Frm().*fnRect->fnGetHeight)() -
2413 (pCnt->Prt().*fnRect->fnGetHeight)();
2414 if( nRet < nTmp )
2415 nRet = nTmp;
2416 pCnt = pCnt->GetNext();
2417 } while ( pCnt );
2418 }
2419 else
2420 {
2421 do
2422 {
2423 nRet += (pCnt->Frm().*fnRect->fnGetHeight)();
2424 if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() )
2425 nRet += ((SwTxtFrm*)pCnt)->GetParHeight() -
2426 (pCnt->Prt().*fnRect->fnGetHeight)();
2427 if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() )
2428 nRet += ((SwLayoutFrm*)pCnt)->InnerHeight() -
2429 (pCnt->Prt().*fnRect->fnGetHeight)();
2430 pCnt = pCnt->GetNext();
2431 } while( pCnt );
2432
2433 }
2434 return nRet;
2435 }
2436
2437 /*************************************************************************
2438 |*
2439 |* SwLayoutFrm::GrowFrm()
2440 |*
2441 |* Ersterstellung MA 30. Jul. 92
2442 |* Letzte Aenderung MA 23. Sep. 96
2443 |*
2444 |*************************************************************************/
GrowFrm(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)2445 SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2446 {
2447 const ViewShell *pSh = getRootFrm()->GetCurrShell();
2448 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2449 const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
2450 if( !(GetType() & nTmpType) && HasFixSize() )
2451 return 0;
2452
2453 SWRECTFN( this )
2454 const SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2455 const SwTwips nFrmPos = Frm().Pos().X();
2456
2457 if ( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
2458 nDist = LONG_MAX - nFrmHeight;
2459
2460 SwTwips nMin = 0;
2461 if ( GetUpper() && !IsCellFrm() )
2462 {
2463 SwFrm *pFrm = GetUpper()->Lower();
2464 while( pFrm )
2465 { nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2466 pFrm = pFrm->GetNext();
2467 }
2468 nMin = (GetUpper()->Prt().*fnRect->fnGetHeight)() - nMin;
2469 if ( nMin < 0 )
2470 nMin = 0;
2471 }
2472
2473 SwRect aOldFrm( Frm() );
2474 sal_Bool bMoveAccFrm = sal_False;
2475
2476 sal_Bool bChgPos = IsVertical() && !IsReverse();
2477 if ( !bTst )
2478 {
2479 (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
2480 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2481 if( bChgPos && !IsVertLR() )
2482 Frm().Pos().X() -= nDist;
2483 bMoveAccFrm = sal_True;
2484 }
2485
2486 SwTwips nReal = nDist - nMin;
2487 if ( nReal > 0 )
2488 {
2489 if ( GetUpper() )
2490 { // AdjustNeighbourhood jetzt auch in Spalten (aber nicht in Rahmen)
2491 sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
2492 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2493 : NA_GROW_SHRINK;
2494 if( NA_ONLY_ADJUST == nAdjust )
2495 nReal = AdjustNeighbourhood( nReal, bTst );
2496 else
2497 {
2498 if( NA_ADJUST_GROW == nAdjust )
2499 nReal += AdjustNeighbourhood( nReal, bTst );
2500
2501 SwTwips nGrow = 0;
2502 if( 0 < nReal )
2503 {
2504 SwFrm* pToGrow = GetUpper();
2505 // NEW TABLES
2506 // A cell with a row span of > 1 is allowed to grow the
2507 // line containing the end of the row span if it is
2508 // located in the same table frame:
2509 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2510 if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2511 {
2512 SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2513 if ( -1 == rEndCell.GetTabBox()->getRowSpan() )
2514 pToGrow = rEndCell.GetUpper();
2515 else
2516 pToGrow = 0;
2517 }
2518
2519 nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0;
2520 }
2521
2522 if( NA_GROW_ADJUST == nAdjust && nGrow < nReal )
2523 nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
2524
2525 if ( IsFtnFrm() && (nGrow != nReal) && GetNext() )
2526 {
2527 //Fussnoten koennen ihre Nachfolger verdraengen.
2528 SwTwips nSpace = bTst ? 0 : -nDist;
2529 const SwFrm *pFrm = GetUpper()->Lower();
2530 do
2531 { nSpace += (pFrm->Frm().*fnRect->fnGetHeight)();
2532 pFrm = pFrm->GetNext();
2533 } while ( pFrm != GetNext() );
2534 nSpace = (GetUpper()->Prt().*fnRect->fnGetHeight)() -nSpace;
2535 if ( nSpace < 0 )
2536 nSpace = 0;
2537 nSpace += nGrow;
2538 if ( nReal > nSpace )
2539 nReal = nSpace;
2540 if ( nReal && !bTst )
2541 ((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() );
2542 }
2543 else
2544 nReal = nGrow;
2545 }
2546 }
2547 else
2548 nReal = 0;
2549
2550 nReal += nMin;
2551 }
2552 else
2553 nReal = nDist;
2554
2555 if ( !bTst )
2556 {
2557 if( nReal != nDist &&
2558 // NEW TABLES
2559 ( !IsCellFrm() || static_cast<SwCellFrm*>(this)->GetLayoutRowSpan() > 1 ) )
2560 {
2561 (Frm().*fnRect->fnSetHeight)( nFrmHeight + nReal );
2562 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2563 if( bChgPos && !IsVertLR() )
2564 Frm().Pos().X() = nFrmPos - nReal;
2565 bMoveAccFrm = sal_True;
2566 }
2567
2568 if ( nReal )
2569 {
2570 SwPageFrm *pPage = FindPageFrm();
2571 if ( GetNext() )
2572 {
2573 GetNext()->_InvalidatePos();
2574 if ( GetNext()->IsCntntFrm() )
2575 GetNext()->InvalidatePage( pPage );
2576 }
2577 if ( !IsPageBodyFrm() )
2578 {
2579 _InvalidateAll();
2580 InvalidatePage( pPage );
2581 }
2582 if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2583 NotifyLowerObjs();
2584
2585 if( IsCellFrm() )
2586 InvaPercentLowers( nReal );
2587
2588 const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
2589 if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2590 SetCompletePaint();
2591 }
2592 }
2593
2594 if( bMoveAccFrm && IsAccessibleFrm() )
2595 {
2596 SwRootFrm *pRootFrm = getRootFrm();
2597 if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2598 pRootFrm->GetCurrShell() )
2599 {
2600 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2601 }
2602 }
2603 return nReal;
2604 }
2605
2606 /*************************************************************************
2607 |*
2608 |* SwLayoutFrm::ShrinkFrm()
2609 |*
2610 |* Ersterstellung MA 30. Jul. 92
2611 |* Letzte Aenderung MA 25. Mar. 99
2612 |*
2613 |*************************************************************************/
ShrinkFrm(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)2614 SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
2615 {
2616 const ViewShell *pSh = getRootFrm()->GetCurrShell();
2617 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2618 const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
2619 if( !(GetType() & nTmpType) && HasFixSize() )
2620 return 0;
2621
2622 ASSERT( nDist >= 0, "nDist < 0" );
2623 SWRECTFN( this )
2624 SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
2625 if ( nDist > nFrmHeight )
2626 nDist = nFrmHeight;
2627
2628 SwTwips nMin = 0;
2629 sal_Bool bChgPos = IsVertical() && !IsReverse();
2630 if ( Lower() )
2631 {
2632 if( !Lower()->IsNeighbourFrm() )
2633 { const SwFrm *pFrm = Lower();
2634 const long nTmp = (Prt().*fnRect->fnGetHeight)();
2635 while( pFrm && nMin < nTmp )
2636 { nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
2637 pFrm = pFrm->GetNext();
2638 }
2639 }
2640 }
2641 SwTwips nReal = nDist;
2642 SwTwips nMinDiff = (Prt().*fnRect->fnGetHeight)() - nMin;
2643 if( nReal > nMinDiff )
2644 nReal = nMinDiff;
2645 if( nReal <= 0 )
2646 return nDist;
2647
2648 SwRect aOldFrm( Frm() );
2649 sal_Bool bMoveAccFrm = sal_False;
2650
2651 SwTwips nRealDist = nReal;
2652 if ( !bTst )
2653 {
2654 (Frm().*fnRect->fnSetHeight)( nFrmHeight - nReal );
2655 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2656 if( bChgPos && !IsVertLR() )
2657 Frm().Pos().X() += nReal;
2658 bMoveAccFrm = sal_True;
2659 }
2660
2661 sal_uInt8 nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ?
2662 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
2663 : NA_GROW_SHRINK;
2664
2665 // AdjustNeighbourhood auch in Spalten (aber nicht in Rahmen)
2666 if( NA_ONLY_ADJUST == nAdjust )
2667 {
2668 if ( IsPageBodyFrm() && !bBrowse )
2669 nReal = nDist;
2670 else
2671 { nReal = AdjustNeighbourhood( -nReal, bTst );
2672 nReal *= -1;
2673 if ( !bTst && IsBodyFrm() && nReal < nRealDist )
2674 {
2675 (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2676 + nRealDist - nReal );
2677 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2678 if( bChgPos && !IsVertLR() )
2679 Frm().Pos().X() += nRealDist - nReal;
2680 ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2681 }
2682 }
2683 }
2684 else if( IsColumnFrm() || IsColBodyFrm() )
2685 {
2686 SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo );
2687 if ( nTmp != nReal )
2688 {
2689 (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
2690 + nReal - nTmp );
2691 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
2692 if( bChgPos && !IsVertLR() )
2693 Frm().Pos().X() += nTmp - nReal;
2694 ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
2695 nReal = nTmp;
2696 }
2697 }
2698 else
2699 {
2700 SwTwips nShrink = nReal;
2701 SwFrm* pToShrink = GetUpper();
2702 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
2703 // NEW TABLES
2704 if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2705 {
2706 SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
2707 pToShrink = rEndCell.GetUpper();
2708 }
2709
2710 nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0;
2711 if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
2712 && nReal < nShrink )
2713 AdjustNeighbourhood( nReal - nShrink );
2714 }
2715
2716 if( bMoveAccFrm && IsAccessibleFrm() )
2717 {
2718 SwRootFrm *pRootFrm = getRootFrm();
2719 if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
2720 pRootFrm->GetCurrShell() )
2721 {
2722 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
2723 }
2724 }
2725 if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) )
2726 {
2727 SwPageFrm *pPage = FindPageFrm();
2728 if ( GetNext() )
2729 {
2730 GetNext()->_InvalidatePos();
2731 if ( GetNext()->IsCntntFrm() )
2732 GetNext()->InvalidatePage( pPage );
2733 if ( IsTabFrm() )
2734 ((SwTabFrm*)this)->SetComplete();
2735 }
2736 else
2737 { if ( IsRetoucheFrm() )
2738 SetRetouche();
2739 if ( IsTabFrm() )
2740 {
2741 if( IsTabFrm() )
2742 ((SwTabFrm*)this)->SetComplete();
2743 if ( Lower() ) //Kann auch im Join stehen und leer sein!
2744 InvalidateNextPos();
2745 }
2746 }
2747 if ( !IsBodyFrm() )
2748 {
2749 _InvalidateAll();
2750 InvalidatePage( pPage );
2751 const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
2752 if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2753 SetCompletePaint();
2754 }
2755
2756 if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
2757 NotifyLowerObjs();
2758
2759 if( IsCellFrm() )
2760 InvaPercentLowers( nReal );
2761
2762 SwCntntFrm *pCnt;
2763 if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() &&
2764 ( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER ||
2765 ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) &&
2766 0 != (pCnt = ((SwFtnFrm*)this)->GetRefFromAttr() ) )
2767 {
2768 if ( pCnt->IsFollow() )
2769 { // Wenn wir sowieso schon in einer anderen Spalte/Seite sitzen
2770 // als der Frame mit der Referenz, dann brauchen wir nicht
2771 // auch noch seinen Master zu invalidieren.
2772 SwFrm *pTmp = pCnt->FindFtnBossFrm(sal_True) == FindFtnBossFrm(sal_True)
2773 ? pCnt->FindMaster()->GetFrm() : pCnt;
2774 pTmp->Prepare( PREP_ADJUST_FRM );
2775 pTmp->InvalidateSize();
2776 }
2777 else
2778 pCnt->InvalidatePos();
2779 }
2780 }
2781 return nReal;
2782 }
2783 /*************************************************************************
2784 |*
2785 |* SwLayoutFrm::ChgLowersProp()
2786 |*
2787 |* Beschreibung Aendert die Grosse der direkt untergeordneten Frm's
2788 |* die eine Fixe Groesse haben, proportional zur Groessenaenderung der
2789 |* PrtArea des Frm's.
2790 |* Die Variablen Frm's werden auch proportional angepasst; sie werden
2791 |* sich schon wieder zurechtwachsen/-schrumpfen.
2792 |* Ersterstellung MA 11.03.92
2793 |* Letzte Aenderung AMA 2. Nov. 98
2794 |*
2795 |*************************************************************************/
ChgLowersProp(const Size & rOldSize)2796 void SwLayoutFrm::ChgLowersProp( const Size& rOldSize )
2797 {
2798 // no change of lower properties for root frame or if no lower exists.
2799 if ( IsRootFrm() || !Lower() )
2800 return;
2801
2802 // declare and init <SwFrm* pLowerFrm> with first lower
2803 SwFrm *pLowerFrm = Lower();
2804
2805 // declare and init const booleans <bHeightChgd> and <bWidthChg>
2806 const bool bHeightChgd = rOldSize.Height() != Prt().Height();
2807 const bool bWidthChgd = rOldSize.Width() != Prt().Width();
2808
2809 // declare and init variables <bVert>, <bRev> and <fnRect>
2810 SWRECTFN( this )
2811
2812 // This shortcut basically tries to handle only lower frames that
2813 // are affected by the size change. Otherwise much more lower frames
2814 // are invalidated.
2815 if ( !( bVert ? bHeightChgd : bWidthChgd ) &&
2816 ! Lower()->IsColumnFrm() &&
2817 ( ( IsBodyFrm() && IsInDocBody() && ( !IsInSct() || !FindSctFrm()->IsColLocked() ) ) ||
2818 // --> FME 2004-07-21 #i10826# Section frames without columns should not
2819 // invalidate all lowers!
2820 IsSctFrm() ) )
2821 // <--
2822 {
2823 // Determine page frame the body frame resp. the section frame belongs to.
2824 SwPageFrm *pPage = FindPageFrm();
2825 // Determine last lower by traveling through them using <GetNext()>.
2826 // During travel check each section frame, if it will be sized to
2827 // maximum. If Yes, invalidate size of section frame and set
2828 // corresponding flags at the page.
2829 do
2830 {
2831 if( pLowerFrm->IsSctFrm() &&((SwSectionFrm*)pLowerFrm)->_ToMaximize() )
2832 {
2833 pLowerFrm->_InvalidateSize();
2834 pLowerFrm->InvalidatePage( pPage );
2835 }
2836 if( pLowerFrm->GetNext() )
2837 pLowerFrm = pLowerFrm->GetNext();
2838 else
2839 break;
2840 } while( sal_True );
2841 // If found last lower is a section frame containing no section
2842 // (section frame isn't valid and will be deleted in the future),
2843 // travel backwards.
2844 while( pLowerFrm->IsSctFrm() && !((SwSectionFrm*)pLowerFrm)->GetSection() &&
2845 pLowerFrm->GetPrev() )
2846 pLowerFrm = pLowerFrm->GetPrev();
2847 // If found last lower is a section frame, set <pLowerFrm> to its last
2848 // content, if the section frame is valid and is not sized to maximum.
2849 // Otherwise set <pLowerFrm> to NULL - In this case body frame only
2850 // contains invalid section frames.
2851 if( pLowerFrm->IsSctFrm() )
2852 pLowerFrm = ((SwSectionFrm*)pLowerFrm)->GetSection() &&
2853 !((SwSectionFrm*)pLowerFrm)->ToMaximize( sal_False ) ?
2854 ((SwSectionFrm*)pLowerFrm)->FindLastCntnt() : NULL;
2855
2856 // continue with found last lower, probably the last content of a section
2857 if ( pLowerFrm )
2858 {
2859 // If <pLowerFrm> is in a table frame, set <pLowerFrm> to this table
2860 // frame and continue.
2861 if ( pLowerFrm->IsInTab() )
2862 {
2863 // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrm> to
2864 // its table frame - check, if the table frame is also a lower
2865 // of the body frame, in order to assure that <pLowerFrm> is not
2866 // set to a frame, which is an *upper* of the body frame.
2867 SwFrm* pTableFrm = pLowerFrm->FindTabFrm();
2868 if ( IsAnLower( pTableFrm ) )
2869 {
2870 pLowerFrm = pTableFrm;
2871 }
2872 }
2873 // Check, if variable size of body frame resp. section frame has grown
2874 // OD 28.10.2002 #97265# - correct check, if variable size has grown.
2875 SwTwips nOldHeight = bVert ? rOldSize.Width() : rOldSize.Height();
2876 if( nOldHeight < (Prt().*fnRect->fnGetHeight)() )
2877 {
2878 // If variable size of body|section frame has grown, only found
2879 // last lower and the position of the its next have to be invalidated.
2880 pLowerFrm->_InvalidateAll();
2881 pLowerFrm->InvalidatePage( pPage );
2882 if( !pLowerFrm->IsFlowFrm() ||
2883 !SwFlowFrm::CastFlowFrm( pLowerFrm )->HasFollow() )
2884 pLowerFrm->InvalidateNextPos( sal_True );
2885 if ( pLowerFrm->IsTxtFrm() )
2886 ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2887 }
2888 else
2889 {
2890 // variable size of body|section frame has shrunk. Thus,
2891 // invalidate all lowers not matching the new body|section size
2892 // and the dedicated new last lower.
2893 if( bVert )
2894 {
2895 SwTwips nBot = Frm().Left() + Prt().Left();
2896 while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Left() < nBot )
2897 {
2898 pLowerFrm->_InvalidateAll();
2899 pLowerFrm->InvalidatePage( pPage );
2900 pLowerFrm = pLowerFrm->GetPrev();
2901 }
2902 }
2903 else
2904 {
2905 SwTwips nBot = Frm().Top() + Prt().Bottom();
2906 while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Top() > nBot )
2907 {
2908 pLowerFrm->_InvalidateAll();
2909 pLowerFrm->InvalidatePage( pPage );
2910 pLowerFrm = pLowerFrm->GetPrev();
2911 }
2912 }
2913 if ( pLowerFrm )
2914 {
2915 pLowerFrm->_InvalidateSize();
2916 pLowerFrm->InvalidatePage( pPage );
2917 if ( pLowerFrm->IsTxtFrm() )
2918 ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2919 }
2920 }
2921 // --> OD 2005-01-31 #i41694# - improvement by removing duplicates
2922 if ( pLowerFrm )
2923 {
2924 if ( pLowerFrm->IsInSct() )
2925 {
2926 // --> OD 2005-01-31 #i41694# - follow-up of issue #i10826#:
2927 // No invalidation of section frame, if it's the this.
2928 SwFrm* pSectFrm = pLowerFrm->FindSctFrm();
2929 if( pSectFrm != this && IsAnLower( pSectFrm ) )
2930 {
2931 pSectFrm->_InvalidateSize();
2932 pSectFrm->InvalidatePage( pPage );
2933 }
2934 // <--
2935 }
2936 }
2937 // <--
2938 }
2939 return;
2940 } // end of { special case }
2941
2942
2943 // Invalidate page for content only once.
2944 bool bInvaPageForCntnt = true;
2945
2946 // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame
2947 // adjustment, if fixed/variable size has changed.
2948 bool bFixChgd, bVarChgd;
2949 if( bVert == pLowerFrm->IsNeighbourFrm() )
2950 {
2951 bFixChgd = bWidthChgd;
2952 bVarChgd = bHeightChgd;
2953 }
2954 else
2955 {
2956 bFixChgd = bHeightChgd;
2957 bVarChgd = bWidthChgd;
2958 }
2959
2960 // Declare const unsigned short <nFixWidth> and init it this frame types
2961 // which has fixed width in vertical respectively horizontal layout.
2962 // In vertical layout these are neighbour frames (cell and column frames),
2963 // header frames and footer frames.
2964 // In horizontal layout these are all frames, which aren't neighbour frames.
2965 const sal_uInt16 nFixWidth = bVert ? (FRM_NEIGHBOUR | FRM_HEADFOOT)
2966 : ~FRM_NEIGHBOUR;
2967
2968 // Declare const unsigned short <nFixHeight> and init it this frame types
2969 // which has fixed height in vertical respectively horizontal layout.
2970 // In vertical layout these are all frames, which aren't neighbour frames,
2971 // header frames, footer frames, body frames or foot note container frames.
2972 // In horizontal layout these are neighbour frames.
2973 const sal_uInt16 nFixHeight= bVert ? ~(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC)
2974 : FRM_NEIGHBOUR;
2975
2976 // Travel through all lowers using <GetNext()>
2977 while ( pLowerFrm )
2978 {
2979 if ( pLowerFrm->IsTxtFrm() )
2980 {
2981 // Text frames will only be invalidated - prepare invalidation
2982 if ( bFixChgd )
2983 static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_FIXSIZE_CHG );
2984 if ( bVarChgd )
2985 static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_ADJUST_FRM );
2986 }
2987 else
2988 {
2989 // If lower isn't a table, row, cell or section frame, adjust its
2990 // frame size.
2991 const sal_uInt16 nLowerType = pLowerFrm->GetType();
2992 if ( !(nLowerType & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) )
2993 {
2994 if ( bWidthChgd )
2995 {
2996 if( nLowerType & nFixWidth )
2997 {
2998 // Considering previous conditions:
2999 // In vertical layout set width of column, header and
3000 // footer frames to its upper width.
3001 // In horizontal layout set width of header, footer,
3002 // foot note container, foot note, body and no-text
3003 // frames to its upper width.
3004 pLowerFrm->Frm().Width( Prt().Width() );
3005 }
3006 else if( rOldSize.Width() && !pLowerFrm->IsFtnFrm() )
3007 {
3008 // Adjust frame width proportional, if lower isn't a
3009 // foot note frame and condition <nLowerType & nFixWidth>
3010 // isn't true.
3011 // Considering previous conditions:
3012 // In vertical layout these are foot note container,
3013 // body and no-text frames.
3014 // In horizontal layout these are column and no-text frames.
3015 // OD 24.10.2002 #97265# - <double> calculation
3016 // Perform <double> calculation of new width, if
3017 // one of the coefficients is greater than 50000
3018 SwTwips nNewWidth;
3019 if ( (pLowerFrm->Frm().Width() > 50000) ||
3020 (Prt().Width() > 50000) )
3021 {
3022 double nNewWidthTmp =
3023 ( double(pLowerFrm->Frm().Width())
3024 * double(Prt().Width()) )
3025 / double(rOldSize.Width());
3026 nNewWidth = SwTwips(nNewWidthTmp);
3027 }
3028 else
3029 {
3030 nNewWidth =
3031 (pLowerFrm->Frm().Width() * Prt().Width()) / rOldSize.Width();
3032 }
3033 pLowerFrm->Frm().Width( nNewWidth );
3034 }
3035 }
3036 if ( bHeightChgd )
3037 {
3038 if( nLowerType & nFixHeight )
3039 {
3040 // Considering previous conditions:
3041 // In vertical layout set height of foot note and
3042 // no-text frames to its upper height.
3043 // In horizontal layout set height of column frames
3044 // to its upper height.
3045 pLowerFrm->Frm().Height( Prt().Height() );
3046 }
3047 // OD 01.10.2002 #102211#
3048 // add conditions <!pLowerFrm->IsHeaderFrm()> and
3049 // <!pLowerFrm->IsFooterFrm()> in order to avoid that
3050 // the <Grow> of header or footer are overwritten.
3051 // NOTE: Height of header/footer frame is determined by contents.
3052 else if ( rOldSize.Height() &&
3053 !pLowerFrm->IsFtnFrm() &&
3054 !pLowerFrm->IsHeaderFrm() &&
3055 !pLowerFrm->IsFooterFrm()
3056 )
3057 {
3058 // Adjust frame height proportional, if lower isn't a
3059 // foot note, a header or a footer frame and
3060 // condition <nLowerType & nFixHeight> isn't true.
3061 // Considering previous conditions:
3062 // In vertical layout these are column, foot note container,
3063 // body and no-text frames.
3064 // In horizontal layout these are column, foot note
3065 // container, body and no-text frames.
3066
3067 // OD 29.10.2002 #97265# - special case for page lowers
3068 // The page lowers that have to be adjusted on page height
3069 // change are the body frame and the foot note container
3070 // frame.
3071 // In vertical layout the height of both is directly
3072 // adjusted to the page height change.
3073 // In horizontal layout the height of the body frame is
3074 // directly adjsuted to the page height change and the
3075 // foot note frame height isn't touched, because its
3076 // determined by its content.
3077 // OD 31.03.2003 #108446# - apply special case for page
3078 // lowers - see description above - also for section columns.
3079 if ( IsPageFrm() ||
3080 ( IsColumnFrm() && IsInSct() )
3081 )
3082 {
3083 ASSERT( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm(),
3084 "ChgLowersProp - only for body or foot note container" );
3085 if ( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm() )
3086 {
3087 if ( IsVertical() || pLowerFrm->IsBodyFrm() )
3088 {
3089 SwTwips nNewHeight =
3090 pLowerFrm->Frm().Height() +
3091 ( Prt().Height() - rOldSize.Height() );
3092 if ( nNewHeight < 0)
3093 {
3094 // OD 01.04.2003 #108446# - adjust assertion condition and text
3095 ASSERT( !( IsPageFrm() &&
3096 (pLowerFrm->Frm().Height()>0) &&
3097 (pLowerFrm->IsValid()) ),
3098 "ChgLowersProg - negative height for lower.");
3099 nNewHeight = 0;
3100 }
3101 pLowerFrm->Frm().Height( nNewHeight );
3102 }
3103 }
3104 }
3105 else
3106 {
3107 SwTwips nNewHeight;
3108 // OD 24.10.2002 #97265# - <double> calculation
3109 // Perform <double> calculation of new height, if
3110 // one of the coefficients is greater than 50000
3111 if ( (pLowerFrm->Frm().Height() > 50000) ||
3112 (Prt().Height() > 50000) )
3113 {
3114 double nNewHeightTmp =
3115 ( double(pLowerFrm->Frm().Height())
3116 * double(Prt().Height()) )
3117 / double(rOldSize.Height());
3118 nNewHeight = SwTwips(nNewHeightTmp);
3119 }
3120 else
3121 {
3122 nNewHeight = ( pLowerFrm->Frm().Height()
3123 * Prt().Height() ) / rOldSize.Height();
3124 }
3125 if( !pLowerFrm->GetNext() )
3126 {
3127 SwTwips nSum = Prt().Height();
3128 SwFrm* pTmp = Lower();
3129 while( pTmp->GetNext() )
3130 {
3131 if( !pTmp->IsFtnContFrm() || !pTmp->IsVertical() )
3132 nSum -= pTmp->Frm().Height();
3133 pTmp = pTmp->GetNext();
3134 }
3135 if( nSum - nNewHeight == 1 &&
3136 nSum == pLowerFrm->Frm().Height() )
3137 nNewHeight = nSum;
3138 }
3139 pLowerFrm->Frm().Height( nNewHeight );
3140 }
3141 }
3142 }
3143 }
3144 } // end of else { NOT text frame }
3145
3146 pLowerFrm->_InvalidateAll();
3147 if ( bInvaPageForCntnt && pLowerFrm->IsCntntFrm() )
3148 {
3149 pLowerFrm->InvalidatePage();
3150 bInvaPageForCntnt = false;
3151 }
3152
3153 if ( !pLowerFrm->GetNext() && pLowerFrm->IsRetoucheFrm() )
3154 {
3155 //Wenn ein Wachstum stattgefunden hat, und die untergeordneten
3156 //zur Retouche faehig sind (derzeit Tab, Section und Cntnt), so
3157 //trigger ich sie an.
3158 if ( rOldSize.Height() < Prt().SSize().Height() ||
3159 rOldSize.Width() < Prt().SSize().Width() )
3160 pLowerFrm->SetRetouche();
3161 }
3162 pLowerFrm = pLowerFrm->GetNext();
3163 }
3164
3165 // Finally adjust the columns if width is set to auto
3166 // Possible optimisation: execute this code earlier in this function and
3167 // return???
3168 if ( ( (bVert && bHeightChgd) || (! bVert && bWidthChgd) ) &&
3169 Lower()->IsColumnFrm() )
3170 {
3171 // get column attribute
3172 const SwFmtCol* pColAttr = NULL;
3173 if ( IsPageBodyFrm() )
3174 {
3175 ASSERT( GetUpper()->IsPageFrm(), "Upper is not page frame" )
3176 pColAttr = &GetUpper()->GetFmt()->GetCol();
3177 }
3178 else
3179 {
3180 ASSERT( IsFlyFrm() || IsSctFrm(), "Columns not in fly or section" )
3181 pColAttr = &GetFmt()->GetCol();
3182 }
3183
3184 if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 )
3185 AdjustColumns( pColAttr, sal_False );
3186 }
3187 }
3188
3189 /*************************************************************************
3190 |*
3191 |* SwLayoutFrm::Format()
3192 |*
3193 |* Beschreibung: "Formatiert" den Frame; Frm und PrtArea.
3194 |* Die Fixsize wird hier nicht eingestellt.
3195 |* Ersterstellung MA 28. Jul. 92
3196 |* Letzte Aenderung MA 21. Mar. 95
3197 |*
3198 |*************************************************************************/
Format(const SwBorderAttrs * pAttrs)3199 void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs )
3200 {
3201 ASSERT( pAttrs, "LayoutFrm::Format, pAttrs ist 0." );
3202
3203 if ( bValidPrtArea && bValidSize )
3204 return;
3205
3206 const sal_uInt16 nLeft = (sal_uInt16)pAttrs->CalcLeft( this );
3207 const sal_uInt16 nUpper = pAttrs->CalcTop();
3208
3209 const sal_uInt16 nRight = (sal_uInt16)((SwBorderAttrs*)pAttrs)->CalcRight( this );
3210 const sal_uInt16 nLower = pAttrs->CalcBottom();
3211 sal_Bool bVert = IsVertical() && !IsPageFrm();
3212 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
3213 SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
3214 if ( !bValidPrtArea )
3215 {
3216 bValidPrtArea = sal_True;
3217 (this->*fnRect->fnSetXMargins)( nLeft, nRight );
3218 (this->*fnRect->fnSetYMargins)( nUpper, nLower );
3219 }
3220
3221 if ( !bValidSize )
3222 {
3223 if ( !HasFixSize() )
3224 {
3225 const SwTwips nBorder = nUpper + nLower;
3226 const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
3227 SwTwips nMinHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
3228 do
3229 { bValidSize = sal_True;
3230
3231 //Die Groesse in der VarSize wird durch den Inhalt plus den
3232 //Raendern bestimmt.
3233 SwTwips nRemaining = 0;
3234 SwFrm *pFrm = Lower();
3235 while ( pFrm )
3236 { nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
3237 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
3238 // Dieser TxtFrm waere gern ein bisschen groesser
3239 nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
3240 - (pFrm->Prt().*fnRect->fnGetHeight)();
3241 else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
3242 nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
3243 pFrm = pFrm->GetNext();
3244 }
3245 nRemaining += nBorder;
3246 nRemaining = Max( nRemaining, nMinHeight );
3247 const SwTwips nDiff = nRemaining-(Frm().*fnRect->fnGetHeight)();
3248 const long nOldLeft = (Frm().*fnRect->fnGetLeft)();
3249 const long nOldTop = (Frm().*fnRect->fnGetTop)();
3250 if ( nDiff )
3251 {
3252 if ( nDiff > 0 )
3253 Grow( nDiff );
3254 else
3255 Shrink( -nDiff );
3256 //Schnell auf dem kurzen Dienstweg die Position updaten.
3257 MakePos();
3258 }
3259 //Unterkante des Uppers nicht ueberschreiten.
3260 if ( GetUpper() && (Frm().*fnRect->fnGetHeight)() )
3261 {
3262 const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
3263 if( (this->*fnRect->fnSetLimit)( nLimit ) &&
3264 nOldLeft == (Frm().*fnRect->fnGetLeft)() &&
3265 nOldTop == (Frm().*fnRect->fnGetTop)() )
3266 bValidSize = bValidPrtArea = sal_True;
3267 }
3268 } while ( !bValidSize );
3269 }
3270 else if ( GetType() & 0x0018 )
3271 {
3272 do
3273 { if ( Frm().Height() != pAttrs->GetSize().Height() )
3274 ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
3275 bValidSize = sal_True;
3276 MakePos();
3277 } while ( !bValidSize );
3278 }
3279 else
3280 bValidSize = sal_True;
3281 }
3282 }
3283
3284 /*************************************************************************
3285 |*
3286 |* SwLayoutFrm::InvalidatePercentLowers()
3287 |*
3288 |* Ersterstellung MA 13. Jun. 96
3289 |* Letzte Aenderung MA 13. Jun. 96
3290 |*
3291 |*************************************************************************/
InvaPercentFlys(SwFrm * pFrm,SwTwips nDiff)3292 static void InvaPercentFlys( SwFrm *pFrm, SwTwips nDiff )
3293 {
3294 ASSERT( pFrm->GetDrawObjs(), "Can't find any Objects" );
3295 for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
3296 {
3297 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3298 if ( pAnchoredObj->ISA(SwFlyFrm) )
3299 {
3300 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3301 const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
3302 if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3303 {
3304 sal_Bool bNotify = sal_True;
3305 // If we've a fly with more than 90% relative height...
3306 if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrm() &&
3307 rSz.GetHeightPercent() != 0xFF && nDiff )
3308 {
3309 const SwFrm *pRel = pFly->IsFlyLayFrm() ? pFly->GetAnchorFrm():
3310 pFly->GetAnchorFrm()->GetUpper();
3311 // ... and we have already more than 90% height and we
3312 // not allow the text to go through...
3313 // then a notifycation could cause an endless loop, e.g.
3314 // 100% height and no text wrap inside a cell of a table.
3315 if( pFly->Frm().Height()*10 >
3316 ( nDiff + pRel->Prt().Height() )*9 &&
3317 pFly->GetFmt()->GetSurround().GetSurround() !=
3318 SURROUND_THROUGHT )
3319 bNotify = sal_False;
3320 }
3321 if( bNotify )
3322 pFly->InvalidateSize();
3323 }
3324 }
3325 }
3326 }
3327
InvaPercentLowers(SwTwips nDiff)3328 void SwLayoutFrm::InvaPercentLowers( SwTwips nDiff )
3329 {
3330 if ( GetDrawObjs() )
3331 ::InvaPercentFlys( this, nDiff );
3332
3333 SwFrm *pFrm = ContainsCntnt();
3334 if ( pFrm )
3335 do
3336 {
3337 if ( pFrm->IsInTab() && !IsTabFrm() )
3338 {
3339 SwFrm *pTmp = pFrm->FindTabFrm();
3340 ASSERT( pTmp, "Where's my TabFrm?" );
3341 if( IsAnLower( pTmp ) )
3342 pFrm = pTmp;
3343 }
3344
3345 if ( pFrm->IsTabFrm() )
3346 {
3347 const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize();
3348 if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3349 pFrm->InvalidatePrt();
3350 }
3351 else if ( pFrm->GetDrawObjs() )
3352 ::InvaPercentFlys( pFrm, nDiff );
3353 pFrm = pFrm->FindNextCnt();
3354 } while ( pFrm && IsAnLower( pFrm ) ) ;
3355 }
3356
3357 /*************************************************************************
3358 |*
3359 |* SwLayoutFrm::CalcRel()
3360 |*
3361 |* Ersterstellung MA 13. Jun. 96
3362 |* Letzte Aenderung MA 10. Oct. 96
3363 |*
3364 |*************************************************************************/
CalcRel(const SwFmtFrmSize & rSz,sal_Bool) const3365 long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, sal_Bool ) const
3366 {
3367 long nRet = rSz.GetWidth(),
3368 nPercent = rSz.GetWidthPercent();
3369
3370 if ( nPercent )
3371 {
3372 const SwFrm *pRel = GetUpper();
3373 long nRel = LONG_MAX;
3374 const ViewShell *pSh = getRootFrm()->GetCurrShell();
3375 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
3376 if( pRel->IsPageBodyFrm() && pSh && bBrowseMode && pSh->VisArea().Width() )
3377 {
3378 nRel = pSh->GetBrowseWidth();
3379 long nDiff = nRel - pRel->Prt().Width();
3380 if ( nDiff > 0 )
3381 nRel -= nDiff;
3382 }
3383 nRel = Min( nRel, pRel->Prt().Width() );
3384 nRet = nRel * nPercent / 100;
3385 }
3386 return nRet;
3387 }
3388
3389 /*************************************************************************
3390 |* Local helpers for SwLayoutFrm::FormatWidthCols()
3391 |*************************************************************************/
lcl_CalcMinColDiff(SwLayoutFrm * pLayFrm)3392 long MA_FASTCALL lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm )
3393 {
3394 long nDiff = 0, nFirstDiff = 0;
3395 SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower();
3396 ASSERT( pCol, "Where's the columnframe?" );
3397 SwFrm *pFrm = pCol->Lower();
3398 do
3399 {
3400 if( pFrm && pFrm->IsBodyFrm() )
3401 pFrm = ((SwBodyFrm*)pFrm)->Lower();
3402 if ( pFrm && pFrm->IsTxtFrm() )
3403 {
3404 const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight();
3405 if ( nTmp != USHRT_MAX )
3406 {
3407 if ( pCol == pLayFrm->Lower() )
3408 nFirstDiff = nTmp;
3409 else
3410 nDiff = nDiff ? Min( nDiff, nTmp ) : nTmp;
3411 }
3412 }
3413 //Leere Spalten ueberspringen!
3414 pCol = (SwLayoutFrm*)pCol->GetNext();
3415 while ( pCol && 0 == (pFrm = pCol->Lower()) )
3416 pCol = (SwLayoutFrm*)pCol->GetNext();
3417
3418 } while ( pFrm && pCol );
3419
3420 return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
3421 }
3422
lcl_IsFlyHeightClipped(SwLayoutFrm * pLay)3423 sal_Bool lcl_IsFlyHeightClipped( SwLayoutFrm *pLay )
3424 {
3425 SwFrm *pFrm = pLay->ContainsCntnt();
3426 while ( pFrm )
3427 {
3428 if ( pFrm->IsInTab() )
3429 pFrm = pFrm->FindTabFrm();
3430
3431 if ( pFrm->GetDrawObjs() )
3432 {
3433 sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
3434 for ( sal_uInt16 i = 0; i < nCnt; ++i )
3435 {
3436 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
3437 if ( pAnchoredObj->ISA(SwFlyFrm) )
3438 {
3439 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3440 if ( pFly->IsHeightClipped() &&
3441 ( !pFly->IsFlyFreeFrm() || pFly->GetPageFrm() ) )
3442 return sal_True;
3443 }
3444 }
3445 }
3446 pFrm = pFrm->FindNextCnt();
3447 }
3448 return sal_False;
3449 }
3450
3451 /*************************************************************************
3452 |* SwLayoutFrm::FormatWidthCols()
3453 |*************************************************************************/
FormatWidthCols(const SwBorderAttrs & rAttrs,const SwTwips nBorder,const SwTwips nMinHeight)3454 void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs,
3455 const SwTwips nBorder, const SwTwips nMinHeight )
3456 {
3457 //Wenn Spalten im Spiel sind, so wird die Groesse an der
3458 //letzten Spalte ausgerichtet.
3459 //1. Inhalt formatieren.
3460 //2. Hoehe der letzten Spalte ermitteln, wenn diese zu
3461 // zu gross ist muss der Fly wachsen.
3462 // Der Betrag um den der Fly waechst ist aber nicht etwa
3463 // der Betrag des Ueberhangs, denn wir muessen davon
3464 // ausgehen, dass etwas Masse zurueckfliesst und so
3465 // zusaetzlicher Platz geschaffen wird.
3466 // Im Ersten Ansatz ist der Betrag um den gewachsen wird
3467 // der Ueberhang geteilt durch die Spaltenanzahl oder
3468 // der Ueberhang selbst wenn er kleiner als die Spalten-
3469 // anzahl ist.
3470 //3. Weiter mit 1. bis zur Stabilitaet.
3471
3472 const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol();
3473 const sal_uInt16 nNumCols = rCol.GetNumCols();
3474
3475 sal_Bool bEnd = sal_False;
3476 sal_Bool bBackLock = sal_False;
3477 ViewShell *pSh = getRootFrm()->GetCurrShell();
3478 SwViewImp *pImp = pSh ? pSh->Imp() : 0;
3479 {
3480 // Zugrunde liegender Algorithmus
3481 // Es wird versucht, eine optimale Hoehe fuer die Spalten zu finden.
3482 // nMinimum beginnt mit der uebergebenen Mindesthoehe und wird dann als
3483 // Maximum der Hoehen gepflegt, bei denen noch Spalteninhalt aus einer
3484 // Spalte herausragt.
3485 // nMaximum beginnt bei LONG_MAX und wird als Minimum der Hoehen gepflegt,
3486 // bei denen der Inhalt gepasst hat.
3487 // Bei spaltigen Bereichen beginnt nMaximum bei dem maximalen Wert, den
3488 // die Umgebung vorgibt, dies kann natuerlich ein Wert sein, bei dem noch
3489 // Inhalt heraushaengt.
3490 // Es werden die Spalten formatiert, wenn Inhalt heraushaengt, wird nMinimum
3491 // ggf. angepasst, dann wird gewachsen, mindestens um nMinDiff, aber nicht ueber
3492 // ein groesseres nMaximum hinaus. Wenn kein Inhalt heraushaengt, sondern
3493 // noch Luft in einer Spalte ist, schrumpfen wir entsprechend, mindestens um
3494 // nMinDiff, aber nicht unter das nMinimum.
3495 // Abgebrochen wird, wenn kein Inhalt mehr heraushaengt und das Minimum sich auf
3496 // weniger als ein MinDiff dem Maximum angenaehert hat oder das von der
3497 // Umgebung vorgegebene Maximum erreicht ist und trotzdem Inhalt heraus-
3498 // haengt.
3499
3500 // Kritik an der Implementation
3501 // 1. Es kann theoretisch Situationen geben, in denen der Inhalt in einer geringeren
3502 // Hoehe passt und in einer groesseren Hoehe nicht passt. Damit der Code robust
3503 // gegen solche Verhaeltnisse ist, sind ein paar Abfragen bezgl. Minimum und Maximum
3504 // drin, die wahrscheinlich niemals zuschlagen koennen.
3505 // 2. Es wird fuer das Schrumpfen das gleiche nMinDiff benutzt wie fuer das Wachstum,
3506 // das nMinDiff ist allerdings mehr oder weniger die kleinste erste Zeilenhoehe und
3507 // als Mindestwert fuer das Schrumpfen nicht unbedingt optimal.
3508
3509 long nMinimum = nMinHeight;
3510 long nMaximum;
3511 sal_Bool bNoBalance = sal_False;
3512 SWRECTFN( this )
3513 if( IsSctFrm() )
3514 {
3515 nMaximum = (Frm().*fnRect->fnGetHeight)() - nBorder +
3516 (Frm().*fnRect->fnBottomDist)(
3517 (GetUpper()->*fnRect->fnGetPrtBottom)() );
3518 nMaximum += GetUpper()->Grow( LONG_MAX, sal_True );
3519 if( nMaximum < nMinimum )
3520 {
3521 if( nMaximum < 0 )
3522 nMinimum = nMaximum = 0;
3523 else
3524 nMinimum = nMaximum;
3525 }
3526 if( nMaximum > BROWSE_HEIGHT )
3527 nMaximum = BROWSE_HEIGHT;
3528
3529 bNoBalance = ((SwSectionFrm*)this)->GetSection()->GetFmt()->
3530 GetBalancedColumns().GetValue();
3531 SwFrm* pAny = ContainsAny();
3532 if( bNoBalance ||
3533 ( !(Frm().*fnRect->fnGetHeight)() && pAny ) )
3534 {
3535 long nTop = (this->*fnRect->fnGetTopMargin)();
3536 // --> OD 2004-11-01 #i23129# - correction: enlarge section
3537 // to the calculated maximum height.
3538 (Frm().*fnRect->fnAddBottom)( nMaximum -
3539 (Frm().*fnRect->fnGetHeight)() );
3540 // <--
3541 if( nTop > nMaximum )
3542 nTop = nMaximum;
3543 (this->*fnRect->fnSetYMargins)( nTop, 0 );
3544 }
3545 if( !pAny && !((SwSectionFrm*)this)->IsFtnLock() )
3546 {
3547 SwFtnContFrm* pFtnCont = ((SwSectionFrm*)this)->ContainsFtnCont();
3548 if( pFtnCont )
3549 {
3550 SwFrm* pFtnAny = pFtnCont->ContainsAny();
3551 if( pFtnAny && pFtnAny->IsValid() )
3552 {
3553 bBackLock = sal_True;
3554 ((SwSectionFrm*)this)->SetFtnLock( sal_True );
3555 }
3556 }
3557 }
3558 }
3559 else
3560 nMaximum = LONG_MAX;
3561
3562 // --> OD 2004-08-25 #i3317# - reset temporarly consideration
3563 // of wrapping style influence
3564 SwPageFrm* pPageFrm = FindPageFrm();
3565 SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
3566 if ( pObjs )
3567 {
3568 sal_uInt32 i = 0;
3569 for ( i = 0; i < pObjs->Count(); ++i )
3570 {
3571 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
3572
3573 if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3574 {
3575 pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3576 }
3577 }
3578 }
3579 // <--
3580 do
3581 {
3582 //Kann eine Weile dauern, deshalb hier auf Waitcrsr pruefen.
3583 if ( pImp )
3584 pImp->CheckWaitCrsr();
3585
3586 bValidSize = sal_True;
3587 //Erstmal die Spalten formatieren, das entlastet den
3588 //Stack ein wenig.
3589 //Bei der Gelegenheit stellen wir auch gleich mal die
3590 //Breiten und Hoehen der Spalten ein (so sie denn falsch sind).
3591 SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
3592
3593 // --> FME 2004-07-19 #i27399#
3594 // Simply setting the column width based on the values returned by
3595 // CalcColWidth does not work for automatic column width.
3596 AdjustColumns( &rCol, sal_False );
3597 // <--
3598
3599 for ( sal_uInt16 i = 0; i < nNumCols; ++i )
3600 {
3601 pCol->Calc();
3602 // ColumnFrms besitzen jetzt einen BodyFrm, der auch kalkuliert werden will
3603 pCol->Lower()->Calc();
3604 if( pCol->Lower()->GetNext() )
3605 pCol->Lower()->GetNext()->Calc(); // SwFtnCont
3606 pCol = (SwLayoutFrm*)pCol->GetNext();
3607 }
3608
3609 ::CalcCntnt( this );
3610
3611 pCol = (SwLayoutFrm*)Lower();
3612 ASSERT( pCol && pCol->GetNext(), ":-( Spalten auf Urlaub?");
3613 // bMinDiff wird gesetzt, wenn es keine leere Spalte gibt
3614 sal_Bool bMinDiff = sal_True;
3615 // OD 28.03.2003 #108446# - check for all column content and all columns
3616 while ( bMinDiff && pCol )
3617 {
3618 bMinDiff = 0 != pCol->ContainsCntnt();
3619 pCol = (SwLayoutFrm*)pCol->GetNext();
3620 }
3621 pCol = (SwLayoutFrm*)Lower();
3622 // OD 28.03.2003 #108446# - initialize local variable
3623 SwFrm *pLow = NULL;
3624 SwTwips nDiff = 0;
3625 SwTwips nMaxFree = 0;
3626 SwTwips nAllFree = LONG_MAX;
3627 // bFoundLower wird gesetzt, wenn es mind. eine nichtleere Spalte gibt
3628 sal_Bool bFoundLower = sal_False;
3629 while( pCol )
3630 {
3631 SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower();
3632 SwTwips nInnerHeight = (pLay->Frm().*fnRect->fnGetHeight)() -
3633 (pLay->Prt().*fnRect->fnGetHeight)();
3634 if( pLay->Lower() )
3635 {
3636 bFoundLower = sal_True;
3637 nInnerHeight += pLay->InnerHeight();
3638 }
3639 else if( nInnerHeight < 0 )
3640 nInnerHeight = 0;
3641
3642 if( pLay->GetNext() )
3643 {
3644 bFoundLower = sal_True;
3645 pLay = (SwLayoutFrm*)pLay->GetNext();
3646 ASSERT( pLay->IsFtnContFrm(),"FtnContainer exspected" );
3647 nInnerHeight += pLay->InnerHeight();
3648 nInnerHeight += (pLay->Frm().*fnRect->fnGetHeight)() -
3649 (pLay->Prt().*fnRect->fnGetHeight)();
3650 }
3651 nInnerHeight -= (pCol->Prt().*fnRect->fnGetHeight)();
3652 if( nInnerHeight > nDiff )
3653 {
3654 nDiff = nInnerHeight;
3655 nAllFree = 0;
3656 }
3657 else
3658 {
3659 if( nMaxFree < -nInnerHeight )
3660 nMaxFree = -nInnerHeight;
3661 if( nAllFree > -nInnerHeight )
3662 nAllFree = -nInnerHeight;
3663 }
3664 pCol = (SwLayoutFrm*)pCol->GetNext();
3665 }
3666
3667 if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) )
3668 {
3669 SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
3670 // Hier wird entschieden, ob wir wachsen muessen, naemlich wenn
3671 // ein Spalteninhalt (nDiff) oder ein Fly herausragt.
3672 // Bei spaltigen Bereichen wird beruecksichtigt, dass mit dem
3673 // Besitz eines nichtleeren Follows die Groesse festgelegt ist.
3674 if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
3675 ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) )
3676 {
3677 long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3678 // Das Minimum darf nicht kleiner sein als unsere PrtHeight,
3679 // solange noch etwas herausragt.
3680 if( nMinimum < nPrtHeight )
3681 nMinimum = nPrtHeight;
3682 // Es muss sichergestellt sein, dass das Maximum nicht kleiner
3683 // als die PrtHeight ist, wenn noch etwas herausragt
3684 if( nMaximum < nPrtHeight )
3685 nMaximum = nPrtHeight; // Robust, aber kann das ueberhaupt eintreten?
3686 if( !nDiff ) // wenn nur Flys herausragen, wachsen wir um nMinDiff
3687 nDiff = nMinDiff;
3688 // Wenn wir um mehr als nMinDiff wachsen wollen, wird dies auf die
3689 // Spalten verteilt
3690 if ( Abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols )
3691 nDiff /= nNumCols;
3692
3693 if ( bMinDiff )
3694 { // Wenn es keinen leeren Spalten gibt, wollen wir mind. um nMinDiff
3695 // wachsen. Sonderfall: Wenn wir kleiner als die minimale Frmhoehe
3696 // sind und die PrtHeight kleiner als nMinDiff ist, wachsen wir so,
3697 // dass die PrtHeight hinterher genau nMinDiff ist.
3698 long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
3699 if ( nFrmHeight > nMinHeight || nPrtHeight >= nMinDiff )
3700 nDiff = Max( nDiff, nMinDiff );
3701 else if( nDiff < nMinDiff )
3702 nDiff = nMinDiff - nPrtHeight + 1;
3703 }
3704 // nMaximum ist eine Groesse, in der der Inhalt gepasst hat,
3705 // oder der von der Umgebung vorgegebene Wert, deshalb
3706 // brauchen wir nicht ueber diesen Wrt hinauswachsen.
3707 if( nDiff + nPrtHeight > nMaximum )
3708 nDiff = nMaximum - nPrtHeight;
3709 }
3710 else if( nMaximum > nMinimum ) // Wir passen, haben wir auch noch Spielraum?
3711 {
3712 long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
3713 if ( nMaximum < nPrtHeight )
3714 nDiff = nMaximum - nPrtHeight; // wir sind ueber eine funktionierende
3715 // Hoehe hinausgewachsen und schrumpfen wieder auf diese zurueck,
3716 // aber kann das ueberhaupt eintreten?
3717 else
3718 { // Wir haben ein neues Maximum, eine Groesse, fuer die der Inhalt passt.
3719 nMaximum = nPrtHeight;
3720 // Wenn der Freiraum in den Spalten groesser ist als nMinDiff und wir
3721 // nicht dadurch wieder unter das Minimum rutschen, wollen wir ein wenig
3722 // Luft herauslassen.
3723 if ( !bNoBalance &&
3724 // --> OD 2004-11-04 #i23129# - <nMinDiff> can be
3725 // big, because of an object at the beginning of
3726 // a column. Thus, decrease optimization here.
3727 //nMaxFree >= nMinDiff &&
3728 nMaxFree > 0 &&
3729 // <--
3730 ( !nAllFree ||
3731 nMinimum < nPrtHeight - nMinDiff ) )
3732 {
3733 nMaxFree /= nNumCols; // auf die Spalten verteilen
3734 nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // mind. nMinDiff
3735 if( nPrtHeight + nDiff <= nMinimum ) // Unter das Minimum?
3736 nDiff = ( nMinimum - nMaximum ) / 2; // dann lieber die Mitte
3737 }
3738 else if( nAllFree )
3739 {
3740 nDiff = -nAllFree;
3741 if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum?
3742 nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3743 }
3744 }
3745 }
3746 if( nDiff ) // jetzt wird geschrumpft oder gewachsen..
3747 {
3748 Size aOldSz( Prt().SSize() );
3749 long nTop = (this->*fnRect->fnGetTopMargin)();
3750 nDiff = (Prt().*fnRect->fnGetHeight)() + nDiff + nBorder -
3751 (Frm().*fnRect->fnGetHeight)();
3752 (Frm().*fnRect->fnAddBottom)( nDiff );
3753 // --> OD 2006-08-16 #i68520#
3754 if ( dynamic_cast<SwFlyFrm*>(this) )
3755 {
3756 dynamic_cast<SwFlyFrm*>(this)->InvalidateObjRectWithSpaces();
3757 }
3758 // <--
3759 (this->*fnRect->fnSetYMargins)( nTop, nBorder - nTop );
3760 ChgLowersProp( aOldSz );
3761 NotifyLowerObjs();
3762
3763 // --> OD 2004-08-25 #i3317# - reset temporarly consideration
3764 // of wrapping style influence
3765 SwPageFrm* pTmpPageFrm = FindPageFrm();
3766 SwSortedObjs* pTmpObjs = pTmpPageFrm ? pTmpPageFrm->GetSortedObjs() : 0L;
3767 if ( pTmpObjs )
3768 {
3769 sal_uInt32 i = 0;
3770 for ( i = 0; i < pTmpObjs->Count(); ++i )
3771 {
3772 SwAnchoredObject* pAnchoredObj = (*pTmpObjs)[i];
3773
3774 if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
3775 {
3776 pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3777 }
3778 }
3779 }
3780 // <--
3781 //Es muss geeignet invalidiert werden, damit
3782 //sich die Frms huebsch ausbalancieren
3783 //- Der jeweils erste ab der zweiten Spalte bekommt
3784 // ein InvalidatePos();
3785 pCol = (SwLayoutFrm*)Lower()->GetNext();
3786 while ( pCol )
3787 {
3788 pLow = pCol->Lower();
3789 if ( pLow )
3790 pLow->_InvalidatePos();
3791 pCol = (SwLayoutFrm*)pCol->GetNext();
3792 }
3793 if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() )
3794 {
3795 // Wenn wir einen Follow erzeugt haben, muessen wir
3796 // seinem Inhalt die Chance geben, im CalcCntnt
3797 // zurueckzufliessen
3798 SwCntntFrm* pTmpCntnt =
3799 ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
3800 if( pTmpCntnt )
3801 pTmpCntnt->_InvalidatePos();
3802 }
3803 }
3804 else
3805 bEnd = sal_True;
3806 }
3807 else
3808 bEnd = sal_True;
3809
3810 } while ( !bEnd || !bValidSize );
3811 }
3812 // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set
3813 // 2nd parameter to <true>.
3814 ::CalcCntnt( this, true );
3815 if( IsSctFrm() )
3816 {
3817 // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true
3818 ::CalcCntnt( this, true );
3819 if( bBackLock )
3820 ((SwSectionFrm*)this)->SetFtnLock( sal_False );
3821 }
3822 }
3823
3824
3825 /*************************************************************************
3826 |*
3827 |* SwRootFrm::InvalidateAllCntnt()
3828 |*
3829 |* Ersterstellung MA 13. Feb. 98
3830 |* Letzte Aenderung MA 12. Aug. 00
3831 |*
3832 |*************************************************************************/
3833
lcl_InvalidateSection(SwFrm * pCnt,sal_uInt8 nInv)3834 SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, sal_uInt8 nInv )
3835 {
3836 SwSectionFrm* pSect = pCnt->FindSctFrm();
3837 // Wenn unser CntntFrm in einer Tabelle oder Fussnote steht, sind nur
3838 // Bereiche gemeint, die ebenfalls innerhalb liegen.
3839 // Ausnahme: Wenn direkt eine Tabelle uebergeben wird.
3840 if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
3841 ( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() )
3842 return NULL;
3843 if( nInv & INV_SIZE )
3844 pSect->_InvalidateSize();
3845 if( nInv & INV_POS )
3846 pSect->_InvalidatePos();
3847 if( nInv & INV_PRTAREA )
3848 pSect->_InvalidatePrt();
3849 SwFlowFrm *pFoll = pSect->GetFollow();
3850 // Temporary separation from follow
3851 pSect->SetFollow( NULL );
3852 SwCntntFrm* pRet = pSect->FindLastCntnt();
3853 pSect->SetFollow( pFoll );
3854 return pRet;
3855 }
3856
lcl_InvalidateTable(SwTabFrm * pTable,sal_uInt8 nInv)3857 SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, sal_uInt8 nInv )
3858 {
3859 if( ( nInv & INV_SECTION ) && pTable->IsInSct() )
3860 lcl_InvalidateSection( pTable, nInv );
3861 if( nInv & INV_SIZE )
3862 pTable->_InvalidateSize();
3863 if( nInv & INV_POS )
3864 pTable->_InvalidatePos();
3865 if( nInv & INV_PRTAREA )
3866 pTable->_InvalidatePrt();
3867 return pTable->FindLastCntnt();
3868 }
3869
3870 void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv );
3871
lcl_InvalidateCntnt(SwCntntFrm * pCnt,sal_uInt8 nInv)3872 void lcl_InvalidateCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3873 {
3874 SwCntntFrm *pLastTabCnt = NULL;
3875 SwCntntFrm *pLastSctCnt = NULL;
3876 while ( pCnt )
3877 {
3878 if( nInv & INV_SECTION )
3879 {
3880 if( pCnt->IsInSct() )
3881 {
3882 // Siehe oben bei Tabellen
3883 if( !pLastSctCnt )
3884 pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
3885 if( pLastSctCnt == pCnt )
3886 pLastSctCnt = NULL;
3887 }
3888 #ifdef DBG_UTIL
3889 else
3890 ASSERT( !pLastSctCnt, "Where's the last SctCntnt?" );
3891 #endif
3892 }
3893 if( nInv & INV_TABLE )
3894 {
3895 if( pCnt->IsInTab() )
3896 {
3897 // Um nicht fuer jeden CntntFrm einer Tabelle das FindTabFrm() zu rufen
3898 // und wieder die gleiche Tabelle zu invalidieren, merken wir uns den letzten
3899 // CntntFrm der Tabelle und reagieren erst wieder auf IsInTab(), wenn wir
3900 // an diesem vorbei sind.
3901 // Beim Eintritt in die Tabelle wird der LastSctCnt auf Null gesetzt,
3902 // damit Bereiche im Innern der Tabelle richtig invalidiert werden.
3903 // Sollte die Tabelle selbst in einem Bereich stehen, so wird an
3904 // diesem die Invalidierung bis zu dreimal durchgefuehrt, das ist vertretbar.
3905 if( !pLastTabCnt )
3906 {
3907 pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv );
3908 pLastSctCnt = NULL;
3909 }
3910 if( pLastTabCnt == pCnt )
3911 {
3912 pLastTabCnt = NULL;
3913 pLastSctCnt = NULL;
3914 }
3915 }
3916 #ifdef DBG_UTIL
3917 else
3918 ASSERT( !pLastTabCnt, "Where's the last TabCntnt?" );
3919 #endif
3920 }
3921
3922 if( nInv & INV_SIZE )
3923 pCnt->Prepare( PREP_CLEAR, 0, sal_False );
3924 if( nInv & INV_POS )
3925 pCnt->_InvalidatePos();
3926 if( nInv & INV_PRTAREA )
3927 pCnt->_InvalidatePrt();
3928 if ( nInv & INV_LINENUM )
3929 pCnt->InvalidateLineNum();
3930 if ( pCnt->GetDrawObjs() )
3931 lcl_InvalidateAllCntnt( pCnt, nInv );
3932 pCnt = pCnt->GetNextCntntFrm();
3933 }
3934 }
3935
lcl_InvalidateAllCntnt(SwCntntFrm * pCnt,sal_uInt8 nInv)3936 void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
3937 {
3938 SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
3939 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3940 {
3941 SwAnchoredObject* pAnchoredObj = rObjs[i];
3942 if ( pAnchoredObj->ISA(SwFlyFrm) )
3943 {
3944 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3945 if ( pFly->IsFlyInCntFrm() )
3946 {
3947 ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3948 if( nInv & INV_DIRECTION )
3949 pFly->CheckDirChange();
3950 }
3951 }
3952 }
3953 }
3954
InvalidateAllCntnt(sal_uInt8 nInv)3955 void SwRootFrm::InvalidateAllCntnt( sal_uInt8 nInv )
3956 {
3957 // Erst werden alle Seitengebundenen FlyFrms abgearbeitet.
3958 SwPageFrm *pPage = (SwPageFrm*)Lower();
3959 while( pPage )
3960 {
3961 pPage->InvalidateFlyLayout();
3962 pPage->InvalidateFlyCntnt();
3963 pPage->InvalidateFlyInCnt();
3964 pPage->InvalidateLayout();
3965 pPage->InvalidateCntnt();
3966 pPage->InvalidatePage( pPage ); //Damit ggf. auch der Turbo verschwindet
3967
3968 if ( pPage->GetSortedObjs() )
3969 {
3970 const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
3971 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3972 {
3973 SwAnchoredObject* pAnchoredObj = rObjs[i];
3974 if ( pAnchoredObj->ISA(SwFlyFrm) )
3975 {
3976 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3977 ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
3978 if ( nInv & INV_DIRECTION )
3979 pFly->CheckDirChange();
3980 }
3981 }
3982 }
3983 if( nInv & INV_DIRECTION )
3984 pPage->CheckDirChange();
3985 pPage = (SwPageFrm*)(pPage->GetNext());
3986 }
3987
3988 //Hier den gesamten Dokumentinhalt und die zeichengebundenen Flys.
3989 ::lcl_InvalidateCntnt( ContainsCntnt(), nInv );
3990
3991 if( nInv & INV_PRTAREA )
3992 {
3993 ViewShell *pSh = getRootFrm()->GetCurrShell();
3994 if( pSh )
3995 pSh->InvalidateWindows( Frm() );
3996 }
3997 }
3998
3999 /** method to invalidate/re-calculate the position of all floating
4000 screen objects (Writer fly frames and drawing objects), which are
4001 anchored to paragraph or to character.
4002
4003 OD 2004-03-16 #i11860#
4004
4005 @author OD
4006 */
InvalidateAllObjPos()4007 void SwRootFrm::InvalidateAllObjPos()
4008 {
4009 const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>(Lower());
4010 while( pPageFrm )
4011 {
4012 pPageFrm->InvalidateFlyLayout();
4013
4014 if ( pPageFrm->GetSortedObjs() )
4015 {
4016 const SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
4017 for ( sal_uInt8 i = 0; i < rObjs.Count(); ++i )
4018 {
4019 SwAnchoredObject* pAnchoredObj = rObjs[i];
4020 const SwFmtAnchor& rAnch = pAnchoredObj->GetFrmFmt().GetAnchor();
4021 if ((rAnch.GetAnchorId() != FLY_AT_PARA) &&
4022 (rAnch.GetAnchorId() != FLY_AT_CHAR))
4023 {
4024 // only to paragraph and to character anchored objects are considered.
4025 continue;
4026 }
4027 // --> OD 2004-07-07 #i28701# - special invalidation for anchored
4028 // objects, whose wrapping style influence has to be considered.
4029 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
4030 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
4031 else
4032 pAnchoredObj->InvalidateObjPos();
4033 // <--
4034 }
4035 }
4036
4037 pPageFrm = static_cast<const SwPageFrm*>(pPageFrm->GetNext());
4038 }
4039 }
4040
4041
4042