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