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