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