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 32 33 #include <time.h> 34 #include "rootfrm.hxx" 35 #include "pagefrm.hxx" 36 #include "cntfrm.hxx" 37 #include "doc.hxx" 38 #include "IDocumentDrawModelAccess.hxx" 39 #include "IDocumentSettingAccess.hxx" 40 #include "IDocumentLayoutAccess.hxx" 41 #include "IDocumentStatistics.hxx" 42 #include "IDocumentTimerAccess.hxx" 43 #include "viewimp.hxx" 44 #include "crsrsh.hxx" 45 #include "dflyobj.hxx" 46 #include "flyfrm.hxx" 47 #include "frmtool.hxx" 48 #include "dcontact.hxx" 49 #include "ndtxt.hxx" // OnlineSpelling 50 #include "frmfmt.hxx" 51 #include "swregion.hxx" 52 #include "viewopt.hxx" // OnlineSpelling ueber Internal-TabPage testen. 53 #include "pam.hxx" // OnlineSpelling wg. der aktuellen Cursorposition 54 #include "dbg_lay.hxx" 55 #include "layouter.hxx" // LoopControlling 56 #include "docstat.hxx" 57 #include "swevent.hxx" 58 59 #include <sfx2/event.hxx> 60 61 #include <ftnidx.hxx> 62 #include <vcl/window.hxx> 63 #include <vcl/svapp.hxx> 64 #include <editeng/opaqitem.hxx> 65 #include <editeng/brshitem.hxx> 66 #include <SwSmartTagMgr.hxx> 67 68 #define _SVSTDARR_BOOLS 69 #include <svl/svstdarr.hxx> 70 71 #define _LAYACT_CXX 72 #include "layact.hxx" 73 #include <swwait.hxx> 74 #include <fmtsrnd.hxx> 75 #include <fmtanchr.hxx> 76 #include <tools/shl.hxx> 77 #include <sfx2/progress.hxx> 78 #ifndef _DOCSH_HXX 79 #include <docsh.hxx> 80 #endif 81 82 #include "swmodule.hxx" 83 #include "fmtline.hxx" 84 #include "tabfrm.hxx" 85 #include "ftnfrm.hxx" 86 #include "txtfrm.hxx" 87 #include "notxtfrm.hxx" 88 #include "flyfrms.hxx" 89 #include "mdiexp.hxx" 90 #include "fmtornt.hxx" 91 #include "sectfrm.hxx" 92 #include "lineinfo.hxx" 93 #include <acmplwrd.hxx> 94 // --> OD 2004-06-28 #i28701# 95 #include <sortedobjs.hxx> 96 #include <objectformatter.hxx> 97 #include <PostItMgr.hxx> 98 99 // <-- 100 //#pragma optimize("ity",on) 101 102 /************************************************************************* 103 |* 104 |* SwLayAction Statisches Geraffel 105 |* 106 |* Ersterstellung MA 22. Dec. 93 107 |* Letzte Aenderung MA 22. Dec. 93 108 |* 109 |*************************************************************************/ 110 111 #define IS_FLYS (pPage->GetSortedObjs()) 112 #define IS_INVAFLY (pPage->IsInvalidFly()) 113 114 115 //Sparen von Schreibarbeit um den Zugriff auf zerstoerte Seiten zu vermeiden. 116 #ifdef DBG_UTIL 117 118 static void BreakPoint() 119 { 120 return; 121 } 122 123 #define CHECKPAGE \ 124 { if ( IsAgain() ) \ 125 { BreakPoint(); \ 126 return; \ 127 } \ 128 } 129 130 #define XCHECKPAGE \ 131 { if ( IsAgain() ) \ 132 { BreakPoint(); \ 133 if( bNoLoop ) \ 134 pLayoutAccess->GetLayouter()->EndLoopControl(); \ 135 return; \ 136 } \ 137 } 138 #else 139 #define CHECKPAGE \ 140 { if ( IsAgain() ) \ 141 return; \ 142 } 143 144 #define XCHECKPAGE \ 145 { if ( IsAgain() ) \ 146 { \ 147 if( bNoLoop ) \ 148 pLayoutAccess->GetLayouter()->EndLoopControl(); \ 149 return; \ 150 } \ 151 } 152 #endif 153 154 #define RESCHEDULE \ 155 { \ 156 if ( IsReschedule() ) \ 157 { \ 158 if (pProgress) pProgress->Reschedule(); \ 159 ::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \ 160 } \ 161 } 162 163 inline sal_uLong Ticks() 164 { 165 return 1000 * clock() / CLOCKS_PER_SEC; 166 } 167 168 void SwLayAction::CheckWaitCrsr() 169 { 170 RESCHEDULE 171 if ( !IsWait() && IsWaitAllowed() && IsPaint() && 172 ((Ticks() - GetStartTicks()) >= CLOCKS_PER_SEC/2) ) 173 { 174 pWait = new SwWait( *pRoot->GetFmt()->GetDoc()->GetDocShell(), sal_True ); 175 } 176 } 177 178 /************************************************************************* 179 |* 180 |* SwLayAction::CheckIdleEnd() 181 |* 182 |* Ersterstellung MA 12. Aug. 94 183 |* Letzte Aenderung MA 24. Jun. 96 184 |* 185 |*************************************************************************/ 186 //Ist es wirklich schon soweit... 187 inline void SwLayAction::CheckIdleEnd() 188 { 189 if ( !IsInput() ) 190 bInput = GetInputType() && Application::AnyInput( GetInputType() ); 191 } 192 193 /************************************************************************* 194 |* 195 |* SwLayAction::SetStatBar() 196 |* 197 |* Ersterstellung MA 10. Aug. 94 198 |* Letzte Aenderung MA 06. Aug. 95 199 |* 200 |*************************************************************************/ 201 void SwLayAction::SetStatBar( sal_Bool bNew ) 202 { 203 if ( bNew ) 204 { 205 nEndPage = pRoot->GetPageNum(); 206 nEndPage += nEndPage * 10 / 100; 207 } 208 else 209 nEndPage = USHRT_MAX; 210 } 211 212 /************************************************************************* 213 |* 214 |* SwLayAction::PaintCntnt() 215 |* 216 |* Beschreibung Je nach Typ wird der Cntnt entsprechend seinen 217 |* Veraenderungen ausgegeben bzw. wird die auszugebende Flaeche in der 218 |* Region eingetragen. 219 |* PaintCntnt: fuellt die Region, 220 |* Ersterstellung BP 19. Jan. 92 221 |* Letzte Aenderung MA 10. Sep. 96 222 |* 223 |*************************************************************************/ 224 sal_Bool SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwCntntFrm *pCnt, 225 const SwPageFrm *pPage ) 226 { 227 SwRegionRects aTmp( rRect ); 228 const SwSortedObjs &rObjs = *pPage->GetSortedObjs(); 229 const SwFlyFrm *pSelfFly = pCnt->FindFlyFrm(); 230 sal_uInt16 i; 231 232 for ( i = 0; i < rObjs.Count() && aTmp.Count(); ++i ) 233 { 234 SdrObject *pO = rObjs[i]->DrawObj(); 235 if ( !pO->ISA(SwVirtFlyDrawObj) ) 236 continue; 237 238 // OD 2004-01-15 #110582# - do not consider invisible objects 239 const IDocumentDrawModelAccess* pIDDMA = pPage->GetFmt()->getIDocumentDrawModelAccess(); 240 if ( !pIDDMA->IsVisibleLayerId( pO->GetLayer() ) ) 241 { 242 continue; 243 } 244 245 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); 246 247 if ( pFly == pSelfFly || !rRect.IsOver( pFly->Frm() ) ) 248 continue; 249 250 if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) ) 251 continue; 252 253 if ( pFly->GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() ) 254 continue; 255 256 if ( pSelfFly ) 257 { 258 const SdrObject *pTmp = pSelfFly->GetVirtDrawObj(); 259 if ( pO->GetLayer() == pTmp->GetLayer() ) 260 { 261 if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() ) 262 //Im gleichen Layer werden nur obenliegende beachtet. 263 continue; 264 } 265 else 266 { 267 const sal_Bool bLowerOfSelf = pFly->IsLowerOf( pSelfFly ); 268 if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() ) 269 //Aus anderem Layer interessieren uns nur nicht transparente 270 //oder innenliegende 271 continue; 272 } 273 } 274 275 /// OD 19.08.2002 #99657# 276 /// Fly frame without a lower have to be subtracted from paint region. 277 /// For checking, if fly frame contains transparent graphic or 278 /// has surrounded contour, assure that fly frame has a lower 279 if ( pFly->Lower() && 280 pFly->Lower()->IsNoTxtFrm() && 281 ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() || 282 pFly->GetFmt()->GetSurround().IsContour() ) 283 ) 284 { 285 continue; 286 } 287 288 /// OD 19.08.2002 #99657# 289 /// Region of a fly frame with transparent background or a transparent 290 /// shadow have not to be subtracted from paint region 291 if ( pFly->IsBackgroundTransparent() || 292 pFly->IsShadowTransparent() ) 293 { 294 continue; 295 } 296 297 aTmp -= pFly->Frm(); 298 } 299 300 sal_Bool bRetPaint = sal_False; 301 const SwRect *pData = aTmp.GetData(); 302 for ( i = 0; i < aTmp.Count(); ++pData, ++i ) 303 bRetPaint |= pImp->GetShell()->AddPaintRect( *pData ); 304 return bRetPaint; 305 } 306 307 inline sal_Bool SwLayAction::_PaintCntnt( const SwCntntFrm *pCntnt, 308 const SwPageFrm *pPage, 309 const SwRect &rRect ) 310 { 311 if ( rRect.HasArea() ) 312 { 313 if ( pPage->GetSortedObjs() ) 314 return PaintWithoutFlys( rRect, pCntnt, pPage ); 315 else 316 return pImp->GetShell()->AddPaintRect( rRect ); 317 } 318 return sal_False; 319 } 320 321 void SwLayAction::PaintCntnt( const SwCntntFrm *pCnt, 322 const SwPageFrm *pPage, 323 const SwRect &rOldRect, 324 long nOldBottom ) 325 { 326 SWRECTFN( pCnt ) 327 328 if ( pCnt->IsCompletePaint() || !pCnt->IsTxtFrm() ) 329 { 330 SwRect aPaint( pCnt->PaintArea() ); 331 if ( !_PaintCntnt( pCnt, pPage, aPaint ) ) 332 pCnt->ResetCompletePaint(); 333 } 334 else 335 { 336 // paint the area between printing bottom and frame bottom and 337 // the area left and right beside the frame, if its height changed. 338 long nOldHeight = (rOldRect.*fnRect->fnGetHeight)(); 339 long nNewHeight = (pCnt->Frm().*fnRect->fnGetHeight)(); 340 const bool bHeightDiff = nOldHeight != nNewHeight; 341 if( bHeightDiff ) 342 { 343 // OD 05.11.2002 #94454# - consider whole potential paint area. 344 //SwRect aDrawRect( pCnt->UnionFrm( sal_True ) ); 345 SwRect aDrawRect( pCnt->PaintArea() ); 346 if( nOldHeight > nNewHeight ) 347 nOldBottom = (pCnt->*fnRect->fnGetPrtBottom)(); 348 (aDrawRect.*fnRect->fnSetTop)( nOldBottom ); 349 _PaintCntnt( pCnt, pPage, aDrawRect ); 350 } 351 // paint content area 352 SwRect aPaintRect = static_cast<SwTxtFrm*>(const_cast<SwCntntFrm*>(pCnt))->Paint(); 353 _PaintCntnt( pCnt, pPage, aPaintRect ); 354 } 355 356 if ( pCnt->IsRetouche() && !pCnt->GetNext() ) 357 { 358 const SwFrm *pTmp = pCnt; 359 if( pCnt->IsInSct() ) 360 { 361 const SwSectionFrm* pSct = pCnt->FindSctFrm(); 362 if( pSct->IsRetouche() && !pSct->GetNext() ) 363 pTmp = pSct; 364 } 365 SwRect aRect( pTmp->GetUpper()->PaintArea() ); 366 (aRect.*fnRect->fnSetTop)( (pTmp->*fnRect->fnGetPrtBottom)() ); 367 if ( !_PaintCntnt( pCnt, pPage, aRect ) ) 368 pCnt->ResetRetouche(); 369 } 370 } 371 372 /************************************************************************* 373 |* 374 |* SwLayAction::SwLayAction() 375 |* 376 |* Ersterstellung MA 30. Oct. 92 377 |* Letzte Aenderung MA 09. Jun. 95 378 |* 379 |*************************************************************************/ 380 SwLayAction::SwLayAction( SwRootFrm *pRt, SwViewImp *pI ) : 381 pRoot( pRt ), 382 pImp( pI ), 383 pOptTab( 0 ), 384 pWait( 0 ), 385 pProgress(NULL), 386 nPreInvaPage( USHRT_MAX ), 387 nStartTicks( Ticks() ), 388 nInputType( 0 ), 389 nEndPage( USHRT_MAX ), 390 nCheckPageNum( USHRT_MAX ) 391 { 392 bPaintExtraData = ::IsExtraData( pImp->GetShell()->GetDoc() ); 393 bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True; 394 bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule = 395 bUpdateExpFlds = bBrowseActionStop = bActionInProgress = sal_False; 396 // OD 14.04.2003 #106346# - init new flag <mbFormatCntntOnInterrupt>. 397 mbFormatCntntOnInterrupt = sal_False; 398 399 pImp->pLayAct = this; //Anmelden 400 } 401 402 SwLayAction::~SwLayAction() 403 { 404 ASSERT( !pWait, "Wait object not destroyed" ); 405 pImp->pLayAct = 0; //Abmelden 406 } 407 408 /************************************************************************* 409 |* 410 |* SwLayAction::Reset() 411 |* 412 |* Ersterstellung MA 11. Aug. 94 413 |* Letzte Aenderung MA 09. Jun. 95 414 |* 415 |*************************************************************************/ 416 void SwLayAction::Reset() 417 { 418 pOptTab = 0; 419 nStartTicks = Ticks(); 420 nInputType = 0; 421 nEndPage = nPreInvaPage = nCheckPageNum = USHRT_MAX; 422 bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True; 423 bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule = 424 bUpdateExpFlds = bBrowseActionStop = sal_False; 425 } 426 427 /************************************************************************* 428 |* 429 |* SwLayAction::RemoveEmptyBrowserPages() 430 |* 431 |* Ersterstellung MA 10. Sep. 97 432 |* Letzte Aenderung MA 10. Sep. 97 433 |* 434 |*************************************************************************/ 435 436 sal_Bool SwLayAction::RemoveEmptyBrowserPages() 437 { 438 //Beim umschalten vom normalen in den Browsermodus bleiben u.U. einige 439 //unangenehm lange stehen. Diese beseiten wir mal schnell. 440 sal_Bool bRet = sal_False; 441 const ViewShell *pSh = pRoot->GetCurrShell(); 442 if( pSh && pSh->GetViewOptions()->getBrowseMode() ) 443 { 444 SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower(); 445 do 446 { 447 if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->Count()) || 448 pPage->ContainsCntnt() ) 449 pPage = (SwPageFrm*)pPage->GetNext(); 450 else 451 { 452 bRet = sal_True; 453 SwPageFrm *pDel = pPage; 454 pPage = (SwPageFrm*)pPage->GetNext(); 455 pDel->Cut(); 456 delete pDel; 457 } 458 } while ( pPage ); 459 } 460 return bRet; 461 } 462 463 464 /************************************************************************* 465 |* 466 |* SwLayAction::Action() 467 |* 468 |* Ersterstellung MA 10. Aug. 94 469 |* Letzte Aenderung MA 06. Aug. 95 470 |* 471 |*************************************************************************/ 472 void SwLayAction::Action() 473 { 474 bActionInProgress = sal_True; 475 476 //TurboMode? Disqualifiziert fuer Idle-Format. 477 if ( IsPaint() && !IsIdle() && TurboAction() ) 478 { 479 delete pWait, pWait = 0; 480 pRoot->ResetTurboFlag(); 481 bActionInProgress = sal_False; 482 pRoot->DeleteEmptySct(); 483 return; 484 } 485 else if ( pRoot->GetTurbo() ) 486 { 487 pRoot->DisallowTurbo(); 488 const SwFrm *pFrm = pRoot->GetTurbo(); 489 pRoot->ResetTurbo(); 490 pFrm->InvalidatePage(); 491 } 492 pRoot->DisallowTurbo(); 493 494 if ( IsCalcLayout() ) 495 SetCheckPages( sal_False ); 496 497 InternalAction(); 498 bAgain |= RemoveEmptyBrowserPages(); 499 while ( IsAgain() ) 500 { 501 bAgain = bNextCycle = sal_False; 502 InternalAction(); 503 bAgain |= RemoveEmptyBrowserPages(); 504 } 505 pRoot->DeleteEmptySct(); 506 507 delete pWait, pWait = 0; 508 509 //Turbo-Action ist auf jedenfall wieder erlaubt. 510 pRoot->ResetTurboFlag(); 511 pRoot->ResetTurbo(); 512 513 SetCheckPages( sal_True ); 514 515 bActionInProgress = sal_False; 516 } 517 518 SwPageFrm* SwLayAction::CheckFirstVisPage( SwPageFrm *pPage ) 519 { 520 SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt(); 521 SwCntntFrm *pChk = pCnt; 522 sal_Bool bPageChgd = sal_False; 523 while ( pCnt && pCnt->IsFollow() ) 524 pCnt = static_cast<SwCntntFrm*>(pCnt)->FindMaster(); 525 if ( pCnt && pChk != pCnt ) 526 { bPageChgd = sal_True; 527 pPage = pCnt->FindPageFrm(); 528 } 529 530 if ( pPage->GetFmt()->GetDoc()->GetFtnIdxs().Count() ) 531 { 532 SwFtnContFrm *pCont = pPage->FindFtnCont(); 533 if ( pCont ) 534 { 535 pCnt = pCont->ContainsCntnt(); 536 pChk = pCnt; 537 while ( pCnt && pCnt->IsFollow() ) 538 pCnt = (SwCntntFrm*)pCnt->FindPrev(); 539 if ( pCnt && pCnt != pChk ) 540 { 541 if ( bPageChgd ) 542 { 543 //Die 'oberste' Seite benutzten. 544 SwPageFrm *pTmp = pCnt->FindPageFrm(); 545 if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() ) 546 pPage = pTmp; 547 } 548 else 549 pPage = pCnt->FindPageFrm(); 550 } 551 } 552 } 553 return pPage; 554 } 555 556 // OD 2004-05-12 #i28701# 557 // --> OD 2004-11-03 #i114798# - unlock position on start and end of page 558 // layout process. 559 class NotifyLayoutOfPageInProgress 560 { 561 private: 562 SwPageFrm& mrPageFrm; 563 564 void _UnlockPositionOfObjs() 565 { 566 SwSortedObjs* pObjs = mrPageFrm.GetSortedObjs(); 567 if ( pObjs ) 568 { 569 sal_uInt32 i = 0; 570 for ( ; i < pObjs->Count(); ++i ) 571 { 572 SwAnchoredObject* pObj = (*pObjs)[i]; 573 pObj->UnlockPosition(); 574 } 575 } 576 } 577 public: 578 NotifyLayoutOfPageInProgress( SwPageFrm& _rPageFrm ) 579 : mrPageFrm( _rPageFrm ) 580 { 581 _UnlockPositionOfObjs(); 582 _rPageFrm.SetLayoutInProgress( true ); 583 } 584 ~NotifyLayoutOfPageInProgress() 585 { 586 mrPageFrm.SetLayoutInProgress( false ); 587 _UnlockPositionOfObjs(); 588 } 589 }; 590 // <-- 591 592 void SwLayAction::InternalAction() 593 { 594 ASSERT( pRoot->Lower()->IsPageFrm(), ":-( Keine Seite unterhalb der Root."); 595 596 pRoot->Calc(); 597 598 //Die erste ungueltige bzw. zu formatierende Seite ermitteln. 599 //Bei einer Complete-Action ist es die erste ungueltige; mithin ist die 600 //erste zu formatierende Seite diejenige Seite mit der Numemr eins. 601 //Bei einer Luegen-Formatierung ist die Nummer der erste Seite die Nummer 602 //der ersten Sichtbaren Seite. 603 SwPageFrm *pPage = IsComplete() ? (SwPageFrm*)pRoot->Lower() : 604 pImp->GetFirstVisPage(); 605 if ( !pPage ) 606 pPage = (SwPageFrm*)pRoot->Lower(); 607 608 //Wenn ein "Erster-Fliess-Cntnt" innerhalb der der ersten sichtbaren Seite 609 //ein Follow ist, so schalten wir die Seite zurueck auf den Ur-Master dieses 610 //Cntnt's 611 if ( !IsComplete() ) 612 pPage = CheckFirstVisPage( pPage ); 613 sal_uInt16 nFirstPageNum = pPage->GetPhyPageNum(); 614 615 while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() ) 616 pPage = (SwPageFrm*)pPage->GetNext(); 617 618 IDocumentLayoutAccess *pLayoutAccess = pRoot->GetFmt()->getIDocumentLayoutAccess(); 619 sal_Bool bNoLoop = pPage ? SwLayouter::StartLoopControl( pRoot->GetFmt()->GetDoc(), pPage ) : sal_False; 620 sal_uInt16 nPercentPageNum = 0; 621 while ( (pPage && !IsInterrupt()) || nCheckPageNum != USHRT_MAX ) 622 { 623 if ( !pPage && nCheckPageNum != USHRT_MAX && 624 (!pPage || pPage->GetPhyPageNum() >= nCheckPageNum) ) 625 { 626 if ( !pPage || pPage->GetPhyPageNum() > nCheckPageNum ) 627 { 628 SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower(); 629 while ( pPg && pPg->GetPhyPageNum() < nCheckPageNum ) 630 pPg = (SwPageFrm*)pPg->GetNext(); 631 if ( pPg ) 632 pPage = pPg; 633 if ( !pPage ) 634 break; 635 } 636 SwPageFrm *pTmp = pPage->GetPrev() ? 637 (SwPageFrm*)pPage->GetPrev() : pPage; 638 SetCheckPages( sal_True ); 639 SwFrm::CheckPageDescs( pPage ); 640 SetCheckPages( sal_False ); 641 nCheckPageNum = USHRT_MAX; 642 pPage = pTmp; 643 continue; 644 } 645 646 if ( nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum ) 647 { 648 nPercentPageNum = pPage->GetPhyPageNum(); 649 ::SetProgressState( nPercentPageNum, pImp->GetShell()->GetDoc()->GetDocShell()); 650 } 651 pOptTab = 0; 652 //Kein ShortCut fuer Idle oder CalcLayout 653 if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) ) 654 { 655 pRoot->DeleteEmptySct(); 656 XCHECKPAGE; 657 if ( !IsInterrupt() && 658 (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) ) 659 { 660 if ( pRoot->IsAssertFlyPages() ) 661 pRoot->AssertFlyPages(); 662 if ( pRoot->IsSuperfluous() ) 663 { 664 sal_Bool bOld = IsAgain(); 665 pRoot->RemoveSuperfluous(); 666 bAgain = bOld; 667 } 668 if ( IsAgain() ) 669 { 670 if( bNoLoop ) 671 pLayoutAccess->GetLayouter()->EndLoopControl(); 672 return; 673 } 674 pPage = (SwPageFrm*)pRoot->Lower(); 675 while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() ) 676 pPage = (SwPageFrm*)pPage->GetNext(); 677 while ( pPage && pPage->GetNext() && 678 pPage->GetPhyPageNum() < nFirstPageNum ) 679 pPage = (SwPageFrm*)pPage->GetNext(); 680 continue; 681 } 682 break; 683 } 684 else 685 { 686 pRoot->DeleteEmptySct(); 687 XCHECKPAGE; 688 689 // OD 2004-05-12 #i28701# - scope for instance of class 690 // <NotifyLayoutOfPageInProgress> 691 { 692 NotifyLayoutOfPageInProgress aLayoutOfPageInProgress( *pPage ); 693 694 while ( !IsInterrupt() && !IsNextCycle() && 695 ((IS_FLYS && IS_INVAFLY) || pPage->IsInvalid()) ) 696 { 697 // OD 2004-05-10 #i28701# 698 SwObjectFormatter::FormatObjsAtFrm( *pPage, *pPage, this ); 699 if ( !IS_FLYS ) 700 { 701 //Wenn keine Flys (mehr) da sind, sind die Flags 702 //mehr als fluessig. 703 pPage->ValidateFlyLayout(); 704 pPage->ValidateFlyCntnt(); 705 } 706 // OD 2004-05-10 #i28701# - change condition 707 while ( !IsInterrupt() && !IsNextCycle() && 708 ( pPage->IsInvalid() || 709 (IS_FLYS && IS_INVAFLY) ) ) 710 { 711 PROTOCOL( pPage, PROT_FILE_INIT, 0, 0) 712 XCHECKPAGE; 713 714 // FME 2007-08-30 #i81146# new loop control 715 sal_uInt16 nLoopControlRuns_1 = 0; 716 const sal_uInt16 nLoopControlMax = 20; 717 718 while ( !IsNextCycle() && pPage->IsInvalidLayout() ) 719 { 720 pPage->ValidateLayout(); 721 722 if ( ++nLoopControlRuns_1 > nLoopControlMax ) 723 { 724 #if OSL_DEBUG_LEVEL > 1 725 ASSERT( false, "LoopControl_1 in SwLayAction::InternalAction" ) 726 #endif 727 break; 728 } 729 730 FormatLayout( pPage ); 731 XCHECKPAGE; 732 } 733 // OD 2004-05-10 #i28701# - change condition 734 if ( !IsNextCycle() && 735 ( pPage->IsInvalidCntnt() || 736 (IS_FLYS && IS_INVAFLY) ) ) 737 { 738 pPage->ValidateFlyInCnt(); 739 pPage->ValidateCntnt(); 740 // --> OD 2004-05-10 #i28701# 741 pPage->ValidateFlyLayout(); 742 pPage->ValidateFlyCntnt(); 743 // <-- 744 if ( !FormatCntnt( pPage ) ) 745 { 746 XCHECKPAGE; 747 pPage->InvalidateCntnt(); 748 pPage->InvalidateFlyInCnt(); 749 // --> OD 2004-05-10 #i28701# 750 pPage->InvalidateFlyLayout(); 751 pPage->InvalidateFlyCntnt(); 752 // <-- 753 if ( IsBrowseActionStop() ) 754 bInput = sal_True; 755 } 756 } 757 if( bNoLoop ) 758 pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE ); 759 } 760 } 761 } // end of scope for instance of class <NotifyLayoutOfPageInProgress> 762 763 764 //Eine vorige Seite kann wieder invalid sein. 765 XCHECKPAGE; 766 if ( !IS_FLYS ) 767 { 768 //Wenn keine Flys (mehr) da sind, sind die Flags 769 //mehr als fluessig. 770 pPage->ValidateFlyLayout(); 771 pPage->ValidateFlyCntnt(); 772 } 773 if ( !IsInterrupt() ) 774 { 775 SetNextCycle( sal_False ); 776 777 if ( nPreInvaPage != USHRT_MAX ) 778 { 779 if( !IsComplete() && nPreInvaPage + 2 < nFirstPageNum ) 780 { 781 pImp->SetFirstVisPageInvalid(); 782 SwPageFrm *pTmpPage = pImp->GetFirstVisPage(); 783 nFirstPageNum = pTmpPage->GetPhyPageNum(); 784 if( nPreInvaPage < nFirstPageNum ) 785 { 786 nPreInvaPage = nFirstPageNum; 787 pPage = pTmpPage; 788 } 789 } 790 while ( pPage->GetPrev() && pPage->GetPhyPageNum() > nPreInvaPage ) 791 pPage = (SwPageFrm*)pPage->GetPrev(); 792 nPreInvaPage = USHRT_MAX; 793 } 794 795 while ( pPage->GetPrev() && 796 ( ((SwPageFrm*)pPage->GetPrev())->IsInvalid() || 797 ( ((SwPageFrm*)pPage->GetPrev())->GetSortedObjs() && 798 ((SwPageFrm*)pPage->GetPrev())->IsInvalidFly())) && 799 (((SwPageFrm*)pPage->GetPrev())->GetPhyPageNum() >= 800 nFirstPageNum) ) 801 { 802 pPage = (SwPageFrm*)pPage->GetPrev(); 803 } 804 805 //Weiter bis zur naechsten invaliden Seite. 806 while ( pPage && !pPage->IsInvalid() && 807 (!IS_FLYS || !IS_INVAFLY) ) 808 { 809 pPage = (SwPageFrm*)pPage->GetNext(); 810 } 811 if( bNoLoop ) 812 pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE ); 813 } 814 CheckIdleEnd(); 815 } 816 if ( !pPage && !IsInterrupt() && 817 (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) ) 818 { 819 if ( pRoot->IsAssertFlyPages() ) 820 pRoot->AssertFlyPages(); 821 if ( pRoot->IsSuperfluous() ) 822 { 823 sal_Bool bOld = IsAgain(); 824 pRoot->RemoveSuperfluous(); 825 bAgain = bOld; 826 } 827 if ( IsAgain() ) 828 { 829 if( bNoLoop ) 830 pLayoutAccess->GetLayouter()->EndLoopControl(); 831 return; 832 } 833 pPage = (SwPageFrm*)pRoot->Lower(); 834 while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() ) 835 pPage = (SwPageFrm*)pPage->GetNext(); 836 while ( pPage && pPage->GetNext() && 837 pPage->GetPhyPageNum() < nFirstPageNum ) 838 pPage = (SwPageFrm*)pPage->GetNext(); 839 } 840 } 841 if ( IsInterrupt() && pPage ) 842 { 843 //Wenn ein Input anliegt wollen wir keinen Inhalt mehr Formatieren, 844 //Das Layout muessen wir aber schon in Ordnung bringen. 845 //Andernfalls kann folgende Situation auftreten (Bug: 3244): 846 //Am Ende des Absatz der letzten Seite wird Text eingegeben, so das 847 //der Absatz einen Follow fuer die nachste Seite erzeugt, ausserdem 848 //wird gleich schnell weitergetippt - Es liegt waehrend der 849 //Verarbeitung ein Input an. Der Absatz auf der neuen Seite wurde 850 //bereits anformatiert, die neue Seite ist Formatiert und steht 851 //auf CompletePaint, hat sich aber noch nicht im Auszugebenden Bereich 852 //eingetragen. Es wird gepaintet, das CompletePaint der Seite wird 853 //zurueckgesetzt weil der neue Absatz sich bereits eingetragen hatte, 854 //aber die Raender der Seite werden nicht gepaintet. Naja, bei der 855 //zwangslaeufig auftretenden naechsten LayAction traegt sich die Seite 856 //nicht mehr ein, weil ihre (LayoutFrm-)Flags bereits zurueckgesetzt 857 //wurden -- Der Rand der Seite wird nie gepaintet. 858 SwPageFrm *pPg = pPage; 859 XCHECKPAGE; 860 const SwRect &rVis = pImp->GetShell()->VisArea(); 861 862 while( pPg && pPg->Frm().Bottom() < rVis.Top() ) 863 pPg = (SwPageFrm*)pPg->GetNext(); 864 if( pPg != pPage ) 865 pPg = pPg ? (SwPageFrm*)pPg->GetPrev() : pPage; 866 867 // OD 14.04.2003 #106346# - set flag for interrupt content formatting 868 mbFormatCntntOnInterrupt = IsInput() && !IsStopPrt(); 869 long nBottom = rVis.Bottom(); 870 // --> OD 2005-02-15 #i42586# - format current page, if idle action is active 871 // This is an optimization for the case that the interrupt is created by 872 // the move of a form control object, which is represented by a window. 873 while ( pPg && ( pPg->Frm().Top() < nBottom || 874 ( IsIdle() && pPg == pPage ) ) ) 875 // <-- 876 { 877 // --> OD 2004-10-11 #i26945# - follow-up of #i28701# 878 NotifyLayoutOfPageInProgress aLayoutOfPageInProgress( *pPg ); 879 880 XCHECKPAGE; 881 882 // FME 2007-08-30 #i81146# new loop control 883 sal_uInt16 nLoopControlRuns_2 = 0; 884 const sal_uInt16 nLoopControlMax = 20; 885 886 // OD 14.04.2003 #106346# - special case: interrupt content formatting 887 // --> OD 2004-07-08 #i28701# - conditions, introduced by #106346#, 888 // are incorrect (marcos IS_FLYS and IS_INVAFLY only works for <pPage>) 889 // and are too strict. 890 // --> OD 2005-06-09 #i50432# - adjust interrupt formatting to 891 // normal page formatting - see above. 892 while ( ( mbFormatCntntOnInterrupt && 893 ( pPg->IsInvalid() || 894 ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) ) || 895 ( !mbFormatCntntOnInterrupt && pPg->IsInvalidLayout() ) ) 896 { 897 XCHECKPAGE; 898 // --> OD 2005-06-09 #i50432# - format also at-page anchored objects 899 SwObjectFormatter::FormatObjsAtFrm( *pPg, *pPg, this ); 900 // <-- 901 // --> OD 2005-06-09 #i50432# 902 if ( !pPg->GetSortedObjs() ) 903 { 904 pPg->ValidateFlyLayout(); 905 pPg->ValidateFlyCntnt(); 906 } 907 // <-- 908 909 // FME 2007-08-30 #i81146# new loop control 910 sal_uInt16 nLoopControlRuns_3 = 0; 911 912 while ( pPg->IsInvalidLayout() ) 913 { 914 pPg->ValidateLayout(); 915 916 if ( ++nLoopControlRuns_3 > nLoopControlMax ) 917 { 918 #if OSL_DEBUG_LEVEL > 1 919 ASSERT( false, "LoopControl_3 in Interrupt formatting in SwLayAction::InternalAction" ) 920 #endif 921 break; 922 } 923 924 FormatLayout( pPg ); 925 XCHECKPAGE; 926 } 927 928 // --> OD 2005-06-09 #i50432# 929 if ( mbFormatCntntOnInterrupt && 930 ( pPg->IsInvalidCntnt() || 931 ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) ) 932 // <-- 933 { 934 pPg->ValidateFlyInCnt(); 935 pPg->ValidateCntnt(); 936 // --> OD 2004-05-10 #i26945# - follow-up of fix #117736# 937 pPg->ValidateFlyLayout(); 938 pPg->ValidateFlyCntnt(); 939 // <-- 940 941 if ( ++nLoopControlRuns_2 > nLoopControlMax ) 942 { 943 #if OSL_DEBUG_LEVEL > 1 944 ASSERT( false, "LoopControl_2 in Interrupt formatting in SwLayAction::InternalAction" ) 945 #endif 946 break; 947 } 948 949 if ( !FormatCntnt( pPg ) ) 950 { 951 XCHECKPAGE; 952 pPg->InvalidateCntnt(); 953 pPg->InvalidateFlyInCnt(); 954 // --> OD 2004-05-10 #i26945# - follow-up of fix #117736# 955 pPg->InvalidateFlyLayout(); 956 pPg->InvalidateFlyCntnt(); 957 // <-- 958 } 959 // --> OD 2005-04-06 #i46807# - we are statisfied, if the 960 // content is formatted once complete. 961 else 962 { 963 break; 964 } 965 // <-- 966 } 967 } 968 // <-- 969 pPg = (SwPageFrm*)pPg->GetNext(); 970 } 971 // OD 14.04.2003 #106346# - reset flag for special interrupt content formatting. 972 mbFormatCntntOnInterrupt = sal_False; 973 } 974 pOptTab = 0; 975 if( bNoLoop ) 976 pLayoutAccess->GetLayouter()->EndLoopControl(); 977 } 978 /************************************************************************* 979 |* 980 |* SwLayAction::TurboAction(), _TurboAction() 981 |* 982 |* Ersterstellung MA 04. Dec. 92 983 |* Letzte Aenderung MA 15. Aug. 93 984 |* 985 |*************************************************************************/ 986 sal_Bool SwLayAction::_TurboAction( const SwCntntFrm *pCnt ) 987 { 988 989 const SwPageFrm *pPage = 0; 990 if ( !pCnt->IsValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() ) 991 { 992 const SwRect aOldRect( pCnt->UnionFrm( sal_True ) ); 993 const long nOldBottom = pCnt->Frm().Top() + pCnt->Prt().Bottom(); 994 pCnt->Calc(); 995 if ( pCnt->Frm().Bottom() < aOldRect.Bottom() ) 996 pCnt->SetRetouche(); 997 998 pPage = pCnt->FindPageFrm(); 999 PaintCntnt( pCnt, pPage, aOldRect, nOldBottom ); 1000 1001 if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTxtFrm() ) 1002 { 1003 const sal_uLong nAllLines = ((SwTxtFrm*)pCnt)->GetAllLines(); 1004 ((SwTxtFrm*)pCnt)->RecalcAllLines(); 1005 if ( nAllLines != ((SwTxtFrm*)pCnt)->GetAllLines() ) 1006 { 1007 if ( IsPaintExtraData() ) 1008 pImp->GetShell()->AddPaintRect( pCnt->Frm() ); 1009 //Damit die restlichen LineNums auf der Seite bereichnet werden 1010 //und nicht hier abgebrochen wird. 1011 //Das im RecalcAllLines zu erledigen waere teuer, weil dort 1012 //auch in unnoetigen Faellen (normale Action) auch immer die 1013 //Seite benachrichtigt werden muesste. 1014 const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm(); 1015 while ( pNxt && 1016 (pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) ) 1017 pNxt = pNxt->GetNextCntntFrm(); 1018 if ( pNxt ) 1019 pNxt->InvalidatePage(); 1020 } 1021 return sal_False; 1022 } 1023 1024 if ( pPage->IsInvalidLayout() || (IS_FLYS && IS_INVAFLY) ) 1025 return sal_False; 1026 } 1027 if ( !pPage ) 1028 pPage = pCnt->FindPageFrm(); 1029 1030 // OD 2004-05-10 #i28701# - format floating screen objects at content frame. 1031 if ( pCnt->IsTxtFrm() && 1032 !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCnt)), 1033 *pPage, this ) ) 1034 { 1035 return sal_False; 1036 } 1037 1038 if ( pPage->IsInvalidCntnt() ) 1039 return sal_False; 1040 return sal_True; 1041 } 1042 1043 sal_Bool SwLayAction::TurboAction() 1044 { 1045 sal_Bool bRet = sal_True; 1046 1047 if ( pRoot->GetTurbo() ) 1048 { 1049 if ( !_TurboAction( pRoot->GetTurbo() ) ) 1050 { 1051 CheckIdleEnd(); 1052 bRet = sal_False; 1053 } 1054 pRoot->ResetTurbo(); 1055 } 1056 else 1057 bRet = sal_False; 1058 return bRet; 1059 } 1060 /************************************************************************* 1061 |* 1062 |* SwLayAction::IsShortCut() 1063 |* 1064 |* Beschreibung: Liefert ein True, wenn die Seite vollstaendig unter 1065 |* oder rechts neben dem sichbaren Bereich liegt. 1066 |* Es kann passieren, dass sich die Verhaeltnisse derart aendern, dass 1067 |* die Verarbeitung (des Aufrufers!) mit der Vorgaengerseite der 1068 |* uebergebenen Seite weitergefuehrt werden muss. Der Paramter wird also 1069 |* ggf. veraendert! 1070 |* Fuer den BrowseMode kann auch dann der ShortCut aktiviert werden, 1071 |* wenn der ungueltige Inhalt der Seite unterhalb des sichbaren 1072 |* bereiches liegt. 1073 |* Ersterstellung MA 30. Oct. 92 1074 |* Letzte Aenderung MA 18. Jul. 96 1075 |* 1076 |*************************************************************************/ 1077 static bool lcl_IsInvaLay( const SwFrm *pFrm, long nBottom ) 1078 { 1079 if ( 1080 !pFrm->IsValid() || 1081 (pFrm->IsCompletePaint() && ( pFrm->Frm().Top() < nBottom ) ) 1082 ) 1083 { 1084 return true; 1085 } 1086 return false; 1087 } 1088 1089 static const SwFrm *lcl_FindFirstInvaLay( const SwFrm *pFrm, long nBottom ) 1090 { 1091 ASSERT( pFrm->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" ); 1092 1093 if (lcl_IsInvaLay(pFrm, nBottom)) 1094 return pFrm; 1095 pFrm = ((SwLayoutFrm*)pFrm)->Lower(); 1096 while ( pFrm ) 1097 { 1098 if ( pFrm->IsLayoutFrm() ) 1099 { 1100 if (lcl_IsInvaLay(pFrm, nBottom)) 1101 return pFrm; 1102 const SwFrm *pTmp; 1103 if ( 0 != (pTmp = lcl_FindFirstInvaLay( pFrm, nBottom )) ) 1104 return pTmp; 1105 } 1106 pFrm = pFrm->GetNext(); 1107 } 1108 return 0; 1109 } 1110 1111 static const SwFrm *lcl_FindFirstInvaCntnt( const SwLayoutFrm *pLay, long nBottom, 1112 const SwCntntFrm *pFirst ) 1113 { 1114 const SwCntntFrm *pCnt = pFirst ? pFirst->GetNextCntntFrm() : 1115 pLay->ContainsCntnt(); 1116 while ( pCnt ) 1117 { 1118 if ( !pCnt->IsValid() || pCnt->IsCompletePaint() ) 1119 { 1120 if ( pCnt->Frm().Top() <= nBottom ) 1121 return pCnt; 1122 } 1123 1124 if ( pCnt->GetDrawObjs() ) 1125 { 1126 const SwSortedObjs &rObjs = *pCnt->GetDrawObjs(); 1127 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 1128 { 1129 const SwAnchoredObject* pObj = rObjs[i]; 1130 if ( pObj->ISA(SwFlyFrm) ) 1131 { 1132 const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj); 1133 if ( pFly->IsFlyInCntFrm() ) 1134 { 1135 if ( ((SwFlyInCntFrm*)pFly)->IsInvalid() || 1136 pFly->IsCompletePaint() ) 1137 { 1138 if ( pFly->Frm().Top() <= nBottom ) 1139 return pFly; 1140 } 1141 const SwFrm *pFrm = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 ); 1142 if ( pFrm && pFrm->Frm().Bottom() <= nBottom ) 1143 return pFrm; 1144 } 1145 } 1146 } 1147 } 1148 if ( pCnt->Frm().Top() > nBottom && !pCnt->IsInTab() ) 1149 return 0; 1150 pCnt = pCnt->GetNextCntntFrm(); 1151 if ( !pLay->IsAnLower( pCnt ) ) 1152 break; 1153 } 1154 return 0; 1155 } 1156 1157 // --> OD 2005-02-21 #i37877# - consider drawing objects 1158 static const SwAnchoredObject* lcl_FindFirstInvaObj( const SwPageFrm* _pPage, 1159 long _nBottom ) 1160 { 1161 ASSERT( _pPage->GetSortedObjs(), "FindFirstInvaObj, no Objs" ) 1162 1163 for ( sal_uInt16 i = 0; i < _pPage->GetSortedObjs()->Count(); ++i ) 1164 { 1165 const SwAnchoredObject* pObj = (*_pPage->GetSortedObjs())[i]; 1166 if ( pObj->ISA(SwFlyFrm) ) 1167 { 1168 const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj); 1169 if ( pFly->Frm().Top() <= _nBottom ) 1170 { 1171 if ( pFly->IsInvalid() || pFly->IsCompletePaint() ) 1172 return pFly; 1173 1174 const SwFrm* pTmp; 1175 if ( 0 != (pTmp = lcl_FindFirstInvaCntnt( pFly, _nBottom, 0 )) && 1176 pTmp->Frm().Top() <= _nBottom ) 1177 return pFly; 1178 } 1179 } 1180 else if ( pObj->ISA(SwAnchoredDrawObject) ) 1181 { 1182 if ( !static_cast<const SwAnchoredDrawObject*>(pObj)->IsValidPos() ) 1183 { 1184 return pObj; 1185 } 1186 } 1187 } 1188 return 0; 1189 } 1190 // <-- 1191 1192 sal_Bool SwLayAction::IsShortCut( SwPageFrm *&prPage ) 1193 { 1194 sal_Bool bRet = sal_False; 1195 const ViewShell *pSh = pRoot->GetCurrShell(); 1196 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); 1197 1198 //Wenn die Seite nicht Gueltig ist wird sie schnell formatiert, sonst 1199 //gibts nix als Aerger. 1200 if ( !prPage->IsValid() ) 1201 { 1202 if ( bBrowse ) 1203 { 1204 /// OD 15.10.2002 #103517# - format complete page 1205 /// Thus, loop on all lowers of the page <prPage>, instead of only 1206 /// format its first lower. 1207 /// NOTE: In online layout (bBrowse == sal_True) a page can contain 1208 /// a header frame and/or a footer frame beside the body frame. 1209 prPage->Calc(); 1210 SwFrm* pPageLowerFrm = prPage->Lower(); 1211 while ( pPageLowerFrm ) 1212 { 1213 pPageLowerFrm->Calc(); 1214 pPageLowerFrm = pPageLowerFrm->GetNext(); 1215 } 1216 } 1217 else 1218 FormatLayout( prPage ); 1219 if ( IsAgain() ) 1220 return sal_False; 1221 } 1222 1223 1224 const SwRect &rVis = pImp->GetShell()->VisArea(); 1225 if ( (prPage->Frm().Top() >= rVis.Bottom()) || 1226 (prPage->Frm().Left()>= rVis.Right()) ) 1227 { 1228 bRet = sal_True; 1229 1230 //Jetzt wird es ein bischen unangenehm: Der erste CntntFrm dieser Seite 1231 //im Bodytext muss Formatiert werden, wenn er dabei die Seite 1232 //wechselt, muss ich nochmal eine Seite zuvor anfangen, denn 1233 //es wurde ein PageBreak verarbeitet. 1234 //Noch unangenehmer: Der naechste CntntFrm ueberhaupt muss 1235 //Formatiert werden, denn es kann passieren, dass kurzfristig 1236 //leere Seiten existieren (Bsp. Absatz ueber mehrere Seiten 1237 //wird geloescht oder verkleinert). 1238 1239 //Ist fuer den Browser uninteressant, wenn der letzte Cnt davor bereits 1240 //nicht mehr sichbar ist. 1241 1242 const SwPageFrm *p2ndPage = prPage; 1243 const SwCntntFrm *pCntnt; 1244 const SwLayoutFrm* pBody = p2ndPage->FindBodyCont(); 1245 if( p2ndPage->IsFtnPage() && pBody ) 1246 pBody = (SwLayoutFrm*)pBody->GetNext(); 1247 pCntnt = pBody ? pBody->ContainsCntnt() : 0; 1248 while ( p2ndPage && !pCntnt ) 1249 { 1250 p2ndPage = (SwPageFrm*)p2ndPage->GetNext(); 1251 if( p2ndPage ) 1252 { 1253 pBody = p2ndPage->FindBodyCont(); 1254 if( p2ndPage->IsFtnPage() && pBody ) 1255 pBody = (SwLayoutFrm*)pBody->GetNext(); 1256 pCntnt = pBody ? pBody->ContainsCntnt() : 0; 1257 } 1258 } 1259 if ( pCntnt ) 1260 { 1261 sal_Bool bTstCnt = sal_True; 1262 if ( bBrowse ) 1263 { 1264 //Der Cnt davor schon nicht mehr sichtbar? 1265 const SwFrm *pLst = pCntnt; 1266 if ( pLst->IsInTab() ) 1267 pLst = pCntnt->FindTabFrm(); 1268 if ( pLst->IsInSct() ) 1269 pLst = pCntnt->FindSctFrm(); 1270 pLst = pLst->FindPrev(); 1271 if ( pLst && 1272 (pLst->Frm().Top() >= rVis.Bottom() || 1273 pLst->Frm().Left()>= rVis.Right()) ) 1274 { 1275 bTstCnt = sal_False; 1276 } 1277 } 1278 1279 if ( bTstCnt ) 1280 { 1281 // --> OD 2004-06-04 #i27756# - check after each frame calculation, 1282 // if the content frame has changed the page. If yes, no other 1283 // frame calculation is performed 1284 bool bPageChg = false; 1285 1286 if ( pCntnt->IsInSct() ) 1287 { 1288 const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm(); 1289 if ( !pSct->IsValid() ) 1290 { 1291 pSct->Calc(); 1292 pSct->SetCompletePaint(); 1293 if ( IsAgain() ) 1294 return sal_False; 1295 // --> OD 2004-06-04 #i27756# 1296 bPageChg = pCntnt->FindPageFrm() != p2ndPage && 1297 prPage->GetPrev(); 1298 } 1299 } 1300 1301 if ( !bPageChg && !pCntnt->IsValid() ) 1302 { 1303 pCntnt->Calc(); 1304 pCntnt->SetCompletePaint(); 1305 if ( IsAgain() ) 1306 return sal_False; 1307 // --> OD 2004-06-04 #i27756# 1308 bPageChg = pCntnt->FindPageFrm() != p2ndPage && 1309 prPage->GetPrev(); 1310 } 1311 1312 if ( !bPageChg && pCntnt->IsInTab() ) 1313 { 1314 const SwTabFrm *pTab = ((SwFrm*)pCntnt)->ImplFindTabFrm(); 1315 if ( !pTab->IsValid() ) 1316 { 1317 pTab->Calc(); 1318 pTab->SetCompletePaint(); 1319 if ( IsAgain() ) 1320 return sal_False; 1321 // --> OD 2004-06-04 #i27756# 1322 bPageChg = pCntnt->FindPageFrm() != p2ndPage && 1323 prPage->GetPrev(); 1324 } 1325 } 1326 1327 if ( !bPageChg && pCntnt->IsInSct() ) 1328 { 1329 const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm(); 1330 if ( !pSct->IsValid() ) 1331 { 1332 pSct->Calc(); 1333 pSct->SetCompletePaint(); 1334 if ( IsAgain() ) 1335 return sal_False; 1336 // --> OD 2004-06-04 #i27756# 1337 bPageChg = pCntnt->FindPageFrm() != p2ndPage && 1338 prPage->GetPrev(); 1339 } 1340 } 1341 1342 // --> OD 2004-06-04 #i27756# 1343 if ( bPageChg ) 1344 { 1345 bRet = sal_False; 1346 const SwPageFrm* pTmp = pCntnt->FindPageFrm(); 1347 if ( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum() && 1348 pTmp->IsInvalid() ) 1349 { 1350 prPage = (SwPageFrm*)pTmp; 1351 } 1352 else 1353 { 1354 prPage = (SwPageFrm*)prPage->GetPrev(); 1355 } 1356 } 1357 // --> OD 2005-04-25 #121980# - no shortcut, if at previous page 1358 // an anchored object is registered, whose anchor is <pCntnt>. 1359 else if ( prPage->GetPrev() && 1360 static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs() ) 1361 { 1362 SwSortedObjs* pObjs = 1363 static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs(); 1364 if ( pObjs ) 1365 { 1366 sal_uInt32 i = 0; 1367 for ( ; i < pObjs->Count(); ++i ) 1368 { 1369 SwAnchoredObject* pObj = (*pObjs)[i]; 1370 if ( pObj->GetAnchorFrmContainingAnchPos() == pCntnt ) 1371 { 1372 bRet = sal_False; 1373 break; 1374 } 1375 } 1376 } 1377 } 1378 // <-- 1379 } 1380 } 1381 } 1382 1383 if ( !bRet && bBrowse ) 1384 { 1385 const long nBottom = rVis.Bottom(); 1386 const SwAnchoredObject* pObj( 0L ); 1387 if ( prPage->GetSortedObjs() && 1388 (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyCntnt()) && 1389 0 != (pObj = lcl_FindFirstInvaObj( prPage, nBottom )) && 1390 pObj->GetObjRect().Top() <= nBottom ) 1391 { 1392 return sal_False; 1393 } 1394 const SwFrm* pFrm( 0L ); 1395 if ( prPage->IsInvalidLayout() && 1396 0 != (pFrm = lcl_FindFirstInvaLay( prPage, nBottom )) && 1397 pFrm->Frm().Top() <= nBottom ) 1398 { 1399 return sal_False; 1400 } 1401 if ( (prPage->IsInvalidCntnt() || prPage->IsInvalidFlyInCnt()) && 1402 0 != (pFrm = lcl_FindFirstInvaCntnt( prPage, nBottom, 0 )) && 1403 pFrm->Frm().Top() <= nBottom ) 1404 { 1405 return sal_False; 1406 } 1407 bRet = sal_True; 1408 } 1409 return bRet; 1410 } 1411 1412 /************************************************************************* 1413 |* 1414 |* SwLayAction::FormatLayout(), FormatLayoutFly, FormatLayoutTab() 1415 |* 1416 |* Ersterstellung MA 30. Oct. 92 1417 |* Letzte Aenderung MA 18. May. 98 1418 |* 1419 |*************************************************************************/ 1420 // OD 15.11.2002 #105155# - introduce support for vertical layout 1421 sal_Bool SwLayAction::FormatLayout( SwLayoutFrm *pLay, sal_Bool bAddRect ) 1422 { 1423 ASSERT( !IsAgain(), "Ungueltige Seite beachten." ); 1424 if ( IsAgain() ) 1425 return sal_False; 1426 1427 sal_Bool bChanged = sal_False; 1428 sal_Bool bAlreadyPainted = sal_False; 1429 // OD 11.11.2002 #104414# - remember frame at complete paint 1430 SwRect aFrmAtCompletePaint; 1431 1432 if ( !pLay->IsValid() || pLay->IsCompletePaint() ) 1433 { 1434 if ( pLay->GetPrev() && !pLay->GetPrev()->IsValid() ) 1435 pLay->GetPrev()->SetCompletePaint(); 1436 1437 SwRect aOldRect( pLay->Frm() ); 1438 pLay->Calc(); 1439 if ( aOldRect != pLay->Frm() ) 1440 bChanged = sal_True; 1441 1442 sal_Bool bNoPaint = sal_False; 1443 if ( pLay->IsPageBodyFrm() && 1444 pLay->Frm().Pos() == aOldRect.Pos() && 1445 pLay->Lower() ) 1446 { 1447 const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell(); 1448 //Einschraenkungen wegen Kopf-/Fusszeilen 1449 if( pSh && pSh->GetViewOptions()->getBrowseMode() && 1450 !( pLay->IsCompletePaint() && pLay->FindPageFrm()->FindFtnCont() ) ) 1451 bNoPaint = sal_True; 1452 } 1453 1454 if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) ) 1455 { 1456 SwRect aPaint( pLay->Frm() ); 1457 // OD 13.02.2003 #i9719#, #105645# - consider border and shadow for 1458 // page frames -> enlarge paint rectangle correspondingly. 1459 if ( pLay->IsPageFrm() ) 1460 { 1461 SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay); 1462 const int nBorderWidth = 1463 pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->BorderPxWidth(), 0 ) ).Width(); 1464 const int nShadowWidth = 1465 pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->ShadowPxWidth(), 0 ) ).Width(); 1466 1467 //mod #i6193# added sidebar width 1468 const SwPostItMgr* pPostItMgr = pImp->GetShell()->GetPostItMgr(); 1469 const int nSidebarWidth = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0; 1470 switch ( pPageFrm->SidebarPosition() ) 1471 { 1472 case sw::sidebarwindows::SIDEBAR_LEFT: 1473 { 1474 aPaint.Left( aPaint.Left() - nBorderWidth - nSidebarWidth); 1475 aPaint.Right( aPaint.Right() + nBorderWidth + nShadowWidth); 1476 } 1477 break; 1478 case sw::sidebarwindows::SIDEBAR_RIGHT: 1479 { 1480 aPaint.Left( aPaint.Left() - nBorderWidth ); 1481 aPaint.Right( aPaint.Right() + nBorderWidth + nShadowWidth + nSidebarWidth); 1482 } 1483 break; 1484 case sw::sidebarwindows::SIDEBAR_NONE: 1485 // nothing to do 1486 break; 1487 } 1488 aPaint.Top( aPaint.Top() - nBorderWidth ); 1489 aPaint.Bottom( aPaint.Bottom() + nBorderWidth + nShadowWidth); 1490 } 1491 1492 sal_Bool bPageInBrowseMode = pLay->IsPageFrm(); 1493 if( bPageInBrowseMode ) 1494 { 1495 const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell(); 1496 if( !pSh || !pSh->GetViewOptions()->getBrowseMode() ) 1497 bPageInBrowseMode = sal_False; 1498 } 1499 if( bPageInBrowseMode ) 1500 { 1501 // NOTE: no vertical layout in online layout 1502 //Ist die Aenderung ueberhaupt sichtbar? 1503 if ( pLay->IsCompletePaint() ) 1504 { 1505 pImp->GetShell()->AddPaintRect( aPaint ); 1506 bAddRect = sal_False; 1507 } 1508 else 1509 { 1510 sal_uInt16 i; 1511 1512 SwRegionRects aRegion( aOldRect ); 1513 aRegion -= aPaint; 1514 for ( i = 0; i < aRegion.Count(); ++i ) 1515 pImp->GetShell()->AddPaintRect( aRegion[i] ); 1516 aRegion.ChangeOrigin( aPaint ); 1517 aRegion.Remove( 0, aRegion.Count() ); 1518 aRegion.Insert( aPaint, 0 ); 1519 aRegion -= aOldRect; 1520 for ( i = 0; i < aRegion.Count(); ++i ) 1521 pImp->GetShell()->AddPaintRect( aRegion[i] ); 1522 } 1523 1524 } 1525 else 1526 { 1527 pImp->GetShell()->AddPaintRect( aPaint ); 1528 bAlreadyPainted = sal_True; 1529 // OD 11.11.2002 #104414# - remember frame at complete paint 1530 aFrmAtCompletePaint = pLay->Frm(); 1531 } 1532 1533 // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing 1534 // between pages (not only for in online mode). 1535 if ( pLay->IsPageFrm() ) 1536 { 1537 const SwTwips nHalfDocBorder = GAPBETWEENPAGES; 1538 const bool bLeftToRightViewLayout = pRoot->IsLeftToRightViewLayout(); 1539 const bool bPrev = bLeftToRightViewLayout ? pLay->GetPrev() : pLay->GetNext(); 1540 const bool bNext = bLeftToRightViewLayout ? pLay->GetNext() : pLay->GetPrev(); 1541 1542 if ( bPrev ) 1543 { 1544 // top 1545 SwRect aSpaceToPrevPage( pLay->Frm() ); 1546 const SwTwips nTop = aSpaceToPrevPage.Top() - nHalfDocBorder; 1547 if ( nTop >= 0 ) 1548 aSpaceToPrevPage.Top( nTop ); 1549 aSpaceToPrevPage.Bottom( pLay->Frm().Top() ); 1550 pImp->GetShell()->AddPaintRect( aSpaceToPrevPage ); 1551 1552 // left 1553 aSpaceToPrevPage = pLay->Frm(); 1554 const SwTwips nLeft = aSpaceToPrevPage.Left() - nHalfDocBorder; 1555 if ( nLeft >= 0 ) 1556 aSpaceToPrevPage.Left( nLeft ); 1557 aSpaceToPrevPage.Right( pLay->Frm().Left() ); 1558 pImp->GetShell()->AddPaintRect( aSpaceToPrevPage ); 1559 } 1560 if ( bNext ) 1561 { 1562 // bottom 1563 SwRect aSpaceToNextPage( pLay->Frm() ); 1564 aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + nHalfDocBorder ); 1565 aSpaceToNextPage.Top( pLay->Frm().Bottom() ); 1566 pImp->GetShell()->AddPaintRect( aSpaceToNextPage ); 1567 1568 // right 1569 aSpaceToNextPage = pLay->Frm(); 1570 aSpaceToNextPage.Right( aSpaceToNextPage.Right() + nHalfDocBorder ); 1571 aSpaceToNextPage.Left( pLay->Frm().Right() ); 1572 pImp->GetShell()->AddPaintRect( aSpaceToNextPage ); 1573 } 1574 } 1575 } 1576 pLay->ResetCompletePaint(); 1577 } 1578 1579 if ( IsPaint() && bAddRect && 1580 !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() ) 1581 { 1582 // OD 15.11.2002 #105155# - vertical layout support 1583 SWRECTFN( pLay ); 1584 SwRect aRect( pLay->GetUpper()->PaintArea() ); 1585 (aRect.*fnRect->fnSetTop)( (pLay->*fnRect->fnGetPrtBottom)() ); 1586 if ( !pImp->GetShell()->AddPaintRect( aRect ) ) 1587 pLay->ResetRetouche(); 1588 } 1589 1590 if( bAlreadyPainted ) 1591 bAddRect = sal_False; 1592 1593 CheckWaitCrsr(); 1594 1595 if ( IsAgain() ) 1596 return sal_False; 1597 1598 //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind 1599 1600 if ( pLay->IsFtnFrm() ) //Hat keine LayFrms als Lower. 1601 return bChanged; 1602 1603 SwFrm *pLow = pLay->Lower(); 1604 sal_Bool bTabChanged = sal_False; 1605 while ( pLow && pLow->GetUpper() == pLay ) 1606 { 1607 if ( pLow->IsLayoutFrm() ) 1608 { 1609 if ( pLow->IsTabFrm() ) 1610 bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect ); 1611 // bereits zum Loeschen angemeldete Ueberspringen 1612 else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() ) 1613 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); 1614 } 1615 else if ( pImp->GetShell()->IsPaintLocked() ) 1616 //Abkuerzung im die Zyklen zu minimieren, bei Lock kommt das 1617 //Paint sowieso (Primaer fuer Browse) 1618 pLow->OptCalc(); 1619 1620 if ( IsAgain() ) 1621 return sal_False; 1622 pLow = pLow->GetNext(); 1623 } 1624 // OD 11.11.2002 #104414# - add complete frame area as paint area, if frame 1625 // area has been already added and after formating its lowers the frame area 1626 // is enlarged. 1627 if ( bAlreadyPainted && 1628 ( pLay->Frm().Width() > aFrmAtCompletePaint.Width() || 1629 pLay->Frm().Height() > aFrmAtCompletePaint.Height() ) 1630 ) 1631 { 1632 pImp->GetShell()->AddPaintRect( pLay->Frm() ); 1633 } 1634 return bChanged || bTabChanged; 1635 } 1636 1637 sal_Bool SwLayAction::FormatLayoutFly( SwFlyFrm* pFly ) 1638 { 1639 ASSERT( !IsAgain(), "Ungueltige Seite beachten." ); 1640 if ( IsAgain() ) 1641 return sal_False; 1642 1643 sal_Bool bChanged = false; 1644 sal_Bool bAddRect = true; 1645 1646 if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() ) 1647 { 1648 //Der Frame hat sich veraendert, er wird jetzt Formatiert 1649 const SwRect aOldRect( pFly->Frm() ); 1650 pFly->Calc(); 1651 bChanged = aOldRect != pFly->Frm(); 1652 1653 if ( IsPaint() && (pFly->IsCompletePaint() || bChanged) && 1654 pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 ) 1655 pImp->GetShell()->AddPaintRect( pFly->Frm() ); 1656 1657 if ( bChanged ) 1658 pFly->Invalidate(); 1659 else 1660 pFly->Validate(); 1661 /* 1662 //mba: it's unclear why we should invalidate always, so I remove it 1663 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1664 if ( IsPaint() && bAddRect && pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 ) 1665 pImp->GetShell()->AddPaintRect( pFly->Frm() ); 1666 1667 pFly->Invalidate(); 1668 */ 1669 bAddRect = false; 1670 pFly->ResetCompletePaint(); 1671 } 1672 1673 if ( IsAgain() ) 1674 return sal_False; 1675 1676 //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind 1677 sal_Bool bTabChanged = false; 1678 SwFrm *pLow = pFly->Lower(); 1679 while ( pLow ) 1680 { 1681 if ( pLow->IsLayoutFrm() ) 1682 { 1683 if ( pLow->IsTabFrm() ) 1684 bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect ); 1685 else 1686 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); 1687 } 1688 pLow = pLow->GetNext(); 1689 } 1690 return bChanged || bTabChanged; 1691 } 1692 1693 // OD 31.10.2002 #104100# 1694 // Implement vertical layout support 1695 sal_Bool SwLayAction::FormatLayoutTab( SwTabFrm *pTab, sal_Bool bAddRect ) 1696 { 1697 ASSERT( !IsAgain(), "8-) Ungueltige Seite beachten." ); 1698 if ( IsAgain() || !pTab->Lower() ) 1699 return sal_False; 1700 1701 IDocumentTimerAccess *pTimerAccess = pRoot->GetFmt()->getIDocumentTimerAccess(); 1702 pTimerAccess->BlockIdling(); 1703 1704 sal_Bool bChanged = sal_False; 1705 sal_Bool bPainted = sal_False; 1706 1707 const SwPageFrm *pOldPage = pTab->FindPageFrm(); 1708 1709 // OD 31.10.2002 #104100# - vertical layout support 1710 // use macro to declare and init <sal_Bool bVert>, <sal_Bool bRev> and 1711 // <SwRectFn fnRect> for table frame <pTab>. 1712 SWRECTFN( pTab ); 1713 1714 if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() ) 1715 { 1716 if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() ) 1717 { 1718 pTab->GetPrev()->SetCompletePaint(); 1719 } 1720 1721 const SwRect aOldRect( pTab->Frm() ); 1722 pTab->SetLowersFormatted( sal_False ); 1723 pTab->Calc(); 1724 if ( aOldRect != pTab->Frm() ) 1725 { 1726 bChanged = sal_True; 1727 } 1728 const SwRect aPaintFrm = pTab->PaintArea(); 1729 1730 if ( IsPaint() && bAddRect ) 1731 { 1732 // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()> 1733 if ( !pTab->IsCompletePaint() && 1734 pTab->IsComplete() && 1735 ( pTab->Frm().SSize() != pTab->Prt().SSize() || 1736 // OD 31.10.2002 #104100# - vertical layout support 1737 (pTab->*fnRect->fnGetLeftMargin)() ) && 1738 pTab->Frm().HasArea() 1739 ) 1740 { 1741 // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles. 1742 SwRect aMarginRect; 1743 1744 SwTwips nLeftMargin = (pTab->*fnRect->fnGetLeftMargin)(); 1745 if ( nLeftMargin > 0) 1746 { 1747 aMarginRect = pTab->Frm(); 1748 (aMarginRect.*fnRect->fnSetWidth)( nLeftMargin ); 1749 pImp->GetShell()->AddPaintRect( aMarginRect ); 1750 } 1751 1752 if ( (pTab->*fnRect->fnGetRightMargin)() > 0) 1753 { 1754 aMarginRect = pTab->Frm(); 1755 (aMarginRect.*fnRect->fnSetLeft)( (pTab->*fnRect->fnGetPrtRight)() ); 1756 pImp->GetShell()->AddPaintRect( aMarginRect ); 1757 } 1758 1759 SwTwips nTopMargin = (pTab->*fnRect->fnGetTopMargin)(); 1760 if ( nTopMargin > 0) 1761 { 1762 aMarginRect = pTab->Frm(); 1763 (aMarginRect.*fnRect->fnSetHeight)( nTopMargin ); 1764 pImp->GetShell()->AddPaintRect( aMarginRect ); 1765 } 1766 1767 if ( (pTab->*fnRect->fnGetBottomMargin)() > 0) 1768 { 1769 aMarginRect = pTab->Frm(); 1770 (aMarginRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); 1771 pImp->GetShell()->AddPaintRect( aMarginRect ); 1772 } 1773 } 1774 else if ( pTab->IsCompletePaint() ) 1775 { 1776 pImp->GetShell()->AddPaintRect( aPaintFrm ); 1777 bAddRect = sal_False; 1778 bPainted = sal_True; 1779 } 1780 1781 if ( pTab->IsRetouche() && !pTab->GetNext() ) 1782 { 1783 SwRect aRect( pTab->GetUpper()->PaintArea() ); 1784 // OD 04.11.2002 #104100# - vertical layout support 1785 (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); 1786 if ( !pImp->GetShell()->AddPaintRect( aRect ) ) 1787 pTab->ResetRetouche(); 1788 } 1789 } 1790 else 1791 bAddRect = sal_False; 1792 1793 if ( pTab->IsCompletePaint() && !pOptTab ) 1794 pOptTab = pTab; 1795 pTab->ResetCompletePaint(); 1796 } 1797 if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() ) 1798 { 1799 // OD 04.10.2002 #102779# 1800 // set correct rectangle for retouche: area between bottom of table frame 1801 // and bottom of paint area of the upper frame. 1802 SwRect aRect( pTab->GetUpper()->PaintArea() ); 1803 // OD 04.11.2002 #104100# - vertical layout support 1804 (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); 1805 if ( !pImp->GetShell()->AddPaintRect( aRect ) ) 1806 pTab->ResetRetouche(); 1807 } 1808 1809 CheckWaitCrsr(); 1810 1811 pTimerAccess->UnblockIdling(); 1812 1813 //Heftige Abkuerzung! 1814 if ( pTab->IsLowersFormatted() && 1815 (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) ) 1816 return sal_False; 1817 1818 //Jetzt noch die Lowers versorgen 1819 if ( IsAgain() ) 1820 return sal_False; 1821 1822 // OD 20.10.2003 #112464# - for savety reasons: 1823 // check page number before formatting lowers. 1824 if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) ) 1825 SetNextCycle( sal_True ); 1826 1827 // OD 20.10.2003 #112464# - format lowers, only if table frame is valid 1828 if ( pTab->IsValid() ) 1829 { 1830 SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower(); 1831 while ( pLow ) 1832 { 1833 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); 1834 if ( IsAgain() ) 1835 return sal_False; 1836 pLow = (SwLayoutFrm*)pLow->GetNext(); 1837 } 1838 } 1839 1840 return bChanged; 1841 } 1842 1843 /************************************************************************* 1844 |* 1845 |* SwLayAction::FormatCntnt() 1846 |* 1847 |* Ersterstellung MA 30. Oct. 92 1848 |* Letzte Aenderung MA 16. Nov. 95 1849 |* 1850 |*************************************************************************/ 1851 sal_Bool SwLayAction::FormatCntnt( const SwPageFrm *pPage ) 1852 { 1853 const SwCntntFrm *pCntnt = pPage->ContainsCntnt(); 1854 const ViewShell *pSh = pRoot->GetCurrShell(); 1855 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); 1856 1857 while ( pCntnt && pPage->IsAnLower( pCntnt ) ) 1858 { 1859 //Wenn der Cntnt sich eh nicht veraendert koennen wir ein paar 1860 //Abkuerzungen nutzen. 1861 const sal_Bool bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() || 1862 pCntnt->IsRetouche() || pCntnt->GetDrawObjs(); 1863 if ( bFull ) 1864 { 1865 //Damit wir nacher nicht suchen muessen. 1866 const sal_Bool bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow(); 1867 const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0; 1868 const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0; 1869 1870 const SwLayoutFrm*pOldUpper = pCntnt->GetUpper(); 1871 const SwTabFrm *pTab = pCntnt->FindTabFrm(); 1872 const sal_Bool bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint(); 1873 const sal_Bool bOldPaint = IsPaint(); 1874 bPaint = bOldPaint && !(pTab && pTab == pOptTab); 1875 _FormatCntnt( pCntnt, pPage ); 1876 // --> OD 2004-11-05 #i26945# - reset <bPaint> before format objects 1877 bPaint = bOldPaint; 1878 // <-- 1879 1880 // OD 2004-05-10 #i28701# - format floating screen object at content frame. 1881 // No format, if action flag <bAgain> is set or action is interrupted. 1882 // OD 2004-08-30 #117736# - allow format on interruption of action, if 1883 // it's the format for this interrupt 1884 // --> OD 2004-11-01 #i23129#, #i36347# - pass correct page frame 1885 // to the object formatter. 1886 if ( !IsAgain() && 1887 ( !IsInterrupt() || mbFormatCntntOnInterrupt ) && 1888 pCntnt->IsTxtFrm() && 1889 !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCntnt)), 1890 *(pCntnt->FindPageFrm()), this ) ) 1891 // <-- 1892 { 1893 return sal_False; 1894 } 1895 1896 if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) 1897 { 1898 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); 1899 ((SwTxtFrm*)pCntnt)->RecalcAllLines(); 1900 if ( IsPaintExtraData() && IsPaint() && 1901 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) 1902 pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); 1903 } 1904 1905 if ( IsAgain() ) 1906 return sal_False; 1907 1908 //Wenn Layout oder Flys wieder Invalid sind breche ich die Verarbeitung 1909 //vorlaeufig ab - allerdings nicht fuer die BrowseView, denn dort wird 1910 //das Layout staendig ungueltig, weil die Seitenhoehe angepasst wird. 1911 //Desgleichen wenn der Benutzer weiterarbeiten will und mindestens ein 1912 //Absatz verarbeitet wurde. 1913 if ( (!pTab || (pTab && !bInValid)) ) 1914 { 1915 CheckIdleEnd(); 1916 // OD 14.04.2003 #106346# - consider interrupt formatting. 1917 if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt ) || 1918 ( !bBrowse && pPage->IsInvalidLayout() ) || 1919 // OD 07.05.2003 #109435# - consider interrupt formatting 1920 ( IS_FLYS && IS_INVAFLY && !mbFormatCntntOnInterrupt ) 1921 ) 1922 return sal_False; 1923 } 1924 if ( pOldUpper != pCntnt->GetUpper() ) 1925 { 1926 const sal_uInt16 nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum(); 1927 if ( nCurNum < pPage->GetPhyPageNum() ) 1928 nPreInvaPage = nCurNum; 1929 1930 //Wenn der Frm mehr als eine Seite rueckwaerts geflossen ist, so 1931 //fangen wir nocheinmal von vorn an damit wir nichts auslassen. 1932 if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 ) 1933 { 1934 SetNextCycle( sal_True ); 1935 // OD 07.05.2003 #109435# - consider interrupt formatting 1936 if ( !mbFormatCntntOnInterrupt ) 1937 { 1938 return sal_False; 1939 } 1940 } 1941 } 1942 //Wenn der Frame die Seite vorwaerts gewechselt hat, so lassen wir 1943 //den Vorgaenger nocheinmal durchlaufen. 1944 //So werden einerseits Vorgaenger erwischt, die jetzt f?r Retouche 1945 //verantwortlich sind, andererseits werden die Fusszeilen 1946 //auch angefasst. 1947 sal_Bool bSetCntnt = sal_True; 1948 if ( pCntntPrev ) 1949 { 1950 if ( !pCntntPrev->IsValid() && pPage->IsAnLower( pCntntPrev ) ) 1951 pPage->InvalidateCntnt(); 1952 if ( pOldUpper != pCntnt->GetUpper() && 1953 pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() ) 1954 { 1955 pCntnt = pCntntPrev; 1956 bSetCntnt = sal_False; 1957 } 1958 } 1959 if ( bSetCntnt ) 1960 { 1961 if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() && 1962 pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom()) 1963 { 1964 const long nBottom = pImp->GetShell()->VisArea().Bottom(); 1965 const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage, 1966 nBottom, pCntnt ); 1967 if ( !pTmp ) 1968 { 1969 if ( (!(IS_FLYS && IS_INVAFLY) || 1970 !lcl_FindFirstInvaObj( pPage, nBottom )) && 1971 (!pPage->IsInvalidLayout() || 1972 !lcl_FindFirstInvaLay( pPage, nBottom ))) 1973 SetBrowseActionStop( sal_True ); 1974 // OD 14.04.2003 #106346# - consider interrupt formatting. 1975 if ( !mbFormatCntntOnInterrupt ) 1976 { 1977 return sal_False; 1978 } 1979 } 1980 } 1981 pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm(); 1982 } 1983 1984 RESCHEDULE; 1985 } 1986 else 1987 { 1988 if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) 1989 { 1990 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); 1991 ((SwTxtFrm*)pCntnt)->RecalcAllLines(); 1992 if ( IsPaintExtraData() && IsPaint() && 1993 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) 1994 pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); 1995 } 1996 1997 //Falls der Frm schon vor der Abarbeitung hier formatiert wurde. 1998 if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() && 1999 IsPaint() ) 2000 PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom()); 2001 if ( IsIdle() ) 2002 { 2003 CheckIdleEnd(); 2004 // OD 14.04.2003 #106346# - consider interrupt formatting. 2005 if ( IsInterrupt() && !mbFormatCntntOnInterrupt ) 2006 return sal_False; 2007 } 2008 if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() && 2009 pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom()) 2010 { 2011 const long nBottom = pImp->GetShell()->VisArea().Bottom(); 2012 const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage, 2013 nBottom, pCntnt ); 2014 if ( !pTmp ) 2015 { 2016 if ( (!(IS_FLYS && IS_INVAFLY) || 2017 !lcl_FindFirstInvaObj( pPage, nBottom )) && 2018 (!pPage->IsInvalidLayout() || 2019 !lcl_FindFirstInvaLay( pPage, nBottom ))) 2020 SetBrowseActionStop( sal_True ); 2021 // OD 14.04.2003 #106346# - consider interrupt formatting. 2022 if ( !mbFormatCntntOnInterrupt ) 2023 { 2024 return sal_False; 2025 } 2026 } 2027 } 2028 pCntnt = pCntnt->GetNextCntntFrm(); 2029 } 2030 } 2031 CheckWaitCrsr(); 2032 // OD 14.04.2003 #106346# - consider interrupt formatting. 2033 return !IsInterrupt() || mbFormatCntntOnInterrupt; 2034 } 2035 /************************************************************************* 2036 |* 2037 |* SwLayAction::_FormatCntnt() 2038 |* 2039 |* Beschreibung Returnt sal_True wenn der Absatz verarbeitet wurde, 2040 |* sal_False wenn es nichts zu verarbeiten gab. 2041 |* Ersterstellung MA 07. Dec. 92 2042 |* Letzte Aenderung MA 11. Mar. 98 2043 |* 2044 |*************************************************************************/ 2045 void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt, 2046 const SwPageFrm *pPage ) 2047 { 2048 //wird sind hier evtl. nur angekommen, weil der Cntnt DrawObjekte haelt. 2049 const sal_Bool bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() && 2050 !pCntnt->IsRetouche(); 2051 SWRECTFN( pCntnt ) 2052 if ( !bDrawObjsOnly && IsPaint() ) 2053 { 2054 const SwRect aOldRect( pCntnt->UnionFrm() ); 2055 const long nOldBottom = (pCntnt->*fnRect->fnGetPrtBottom)(); 2056 pCntnt->OptCalc(); 2057 if( IsAgain() ) 2058 return; 2059 if( (*fnRect->fnYDiff)( (pCntnt->Frm().*fnRect->fnGetBottom)(), 2060 (aOldRect.*fnRect->fnGetBottom)() ) < 0 ) 2061 { 2062 pCntnt->SetRetouche(); 2063 } 2064 PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom); 2065 } 2066 else 2067 { 2068 if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() ) 2069 PaintCntnt( pCntnt, pPage, pCntnt->Frm(), 2070 (pCntnt->Frm().*fnRect->fnGetBottom)() ); 2071 pCntnt->OptCalc(); 2072 } 2073 } 2074 2075 /************************************************************************* 2076 |* 2077 |* SwLayAction::_FormatFlyCntnt() 2078 |* 2079 |* Beschreibung: 2080 |* - Returnt sal_True wenn alle Cntnts des Flys vollstaendig verarbeitet 2081 |* wurden. sal_False wenn vorzeitig unterbrochen wurde. 2082 |* Ersterstellung MA 02. Dec. 92 2083 |* Letzte Aenderung MA 24. Jun. 96 2084 |* 2085 |*************************************************************************/ 2086 sal_Bool SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly ) 2087 { 2088 const SwCntntFrm *pCntnt = pFly->ContainsCntnt(); 2089 2090 while ( pCntnt ) 2091 { 2092 // OD 2004-05-10 #i28701# 2093 _FormatCntnt( pCntnt, pCntnt->FindPageFrm() ); 2094 2095 // --> OD 2004-07-23 #i28701# - format floating screen objects 2096 // at content text frame 2097 // --> OD 2004-11-02 #i23129#, #i36347# - pass correct page frame 2098 // to the object formatter. 2099 if ( pCntnt->IsTxtFrm() && 2100 !SwObjectFormatter::FormatObjsAtFrm( 2101 *(const_cast<SwCntntFrm*>(pCntnt)), 2102 *(pCntnt->FindPageFrm()), this ) ) 2103 // <-- 2104 { 2105 // restart format with first content 2106 pCntnt = pFly->ContainsCntnt(); 2107 continue; 2108 } 2109 // <-- 2110 2111 if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) 2112 { 2113 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); 2114 ((SwTxtFrm*)pCntnt)->RecalcAllLines(); 2115 if ( IsPaintExtraData() && IsPaint() && 2116 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) 2117 pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); 2118 } 2119 2120 if ( IsAgain() ) 2121 return sal_False; 2122 2123 //wenn eine Eingabe anliegt breche ich die Verarbeitung ab. 2124 if ( !pFly->IsFlyInCntFrm() ) 2125 { 2126 CheckIdleEnd(); 2127 // OD 14.04.2003 #106346# - consider interrupt formatting. 2128 if ( IsInterrupt() && !mbFormatCntntOnInterrupt ) 2129 return sal_False; 2130 } 2131 pCntnt = pCntnt->GetNextCntntFrm(); 2132 } 2133 CheckWaitCrsr(); 2134 // OD 14.04.2003 #106346# - consider interrupt formatting. 2135 return !(IsInterrupt() && !mbFormatCntntOnInterrupt); 2136 } 2137 2138 sal_Bool SwLayAction::IsStopPrt() const 2139 { 2140 sal_Bool bResult = sal_False; 2141 2142 if (pImp != NULL && pProgress != NULL) 2143 bResult = pImp->IsStopPrt(); 2144 2145 return bResult; 2146 } 2147 2148 /************************************************************************* 2149 |* 2150 |* SwLayAction::FormatSpelling(), _FormatSpelling() 2151 |* 2152 |* Ersterstellung AMA 01. Feb. 96 2153 |* Letzte Aenderung AMA 01. Feb. 96 2154 |* 2155 |*************************************************************************/ 2156 sal_Bool SwLayIdle::_DoIdleJob( const SwCntntFrm *pCnt, IdleJobType eJob ) 2157 { 2158 ASSERT( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" ); 2159 // robust against misuse by e.g. #i52542# 2160 if( !pCnt->IsTxtFrm() ) 2161 return sal_False; 2162 2163 const SwTxtNode* pTxtNode = pCnt->GetNode()->GetTxtNode(); 2164 2165 bool bProcess = false; 2166 switch ( eJob ) 2167 { 2168 case ONLINE_SPELLING : 2169 bProcess = pTxtNode->IsWrongDirty(); break; 2170 case AUTOCOMPLETE_WORDS : 2171 bProcess = pTxtNode->IsAutoCompleteWordDirty(); break; 2172 case WORD_COUNT : 2173 bProcess = pTxtNode->IsWordCountDirty(); break; 2174 case SMART_TAGS : // SMARTTAGS 2175 bProcess = pTxtNode->IsSmartTagDirty(); break; 2176 } 2177 2178 if( bProcess ) 2179 { 2180 ViewShell *pSh = pImp->GetShell(); 2181 if( STRING_LEN == nTxtPos ) 2182 { 2183 --nTxtPos; 2184 if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() ) 2185 { 2186 SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr(); 2187 if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() ) 2188 { 2189 pCntntNode = pCrsr->GetCntntNode(); 2190 nTxtPos = pCrsr->GetPoint()->nContent.GetIndex(); 2191 } 2192 } 2193 } 2194 2195 switch ( eJob ) 2196 { 2197 case ONLINE_SPELLING : 2198 { 2199 SwRect aRepaint( ((SwTxtFrm*)pCnt)->_AutoSpell( pCntntNode, *pSh->GetViewOptions(), nTxtPos ) ); 2200 bPageValid = bPageValid && !pTxtNode->IsWrongDirty(); 2201 if( !bPageValid ) 2202 bAllValid = sal_False; 2203 if ( aRepaint.HasArea() ) 2204 pImp->GetShell()->InvalidateWindows( aRepaint ); 2205 if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) ) 2206 return sal_True; 2207 break; 2208 } 2209 case AUTOCOMPLETE_WORDS : 2210 ((SwTxtFrm*)pCnt)->CollectAutoCmplWrds( pCntntNode, nTxtPos ); 2211 if ( Application::AnyInput( INPUT_ANY ) ) 2212 return sal_True; 2213 break; 2214 case WORD_COUNT : 2215 { 2216 const xub_StrLen nEnd = pTxtNode->GetTxt().Len(); 2217 SwDocStat aStat; 2218 pTxtNode->CountWords( aStat, 0, nEnd ); 2219 if ( Application::AnyInput( INPUT_ANY ) ) 2220 return sal_True; 2221 break; 2222 } 2223 case SMART_TAGS : // SMARTTAGS 2224 { 2225 const SwRect aRepaint( ((SwTxtFrm*)pCnt)->SmartTagScan( pCntntNode, nTxtPos ) ); 2226 bPageValid = bPageValid && !pTxtNode->IsSmartTagDirty(); 2227 if( !bPageValid ) 2228 bAllValid = sal_False; 2229 if ( aRepaint.HasArea() ) 2230 pImp->GetShell()->InvalidateWindows( aRepaint ); 2231 if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) ) 2232 return sal_True; 2233 break; 2234 } 2235 } 2236 } 2237 2238 //Die im Absatz verankerten Flys wollen auch mitspielen. 2239 if ( pCnt->GetDrawObjs() ) 2240 { 2241 const SwSortedObjs &rObjs = *pCnt->GetDrawObjs(); 2242 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 2243 { 2244 SwAnchoredObject* pObj = rObjs[i]; 2245 if ( pObj->ISA(SwFlyFrm) ) 2246 { 2247 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj); 2248 if ( pFly->IsFlyInCntFrm() ) 2249 { 2250 const SwCntntFrm *pC = pFly->ContainsCntnt(); 2251 while( pC ) 2252 { 2253 if ( pC->IsTxtFrm() ) 2254 { 2255 if ( _DoIdleJob( pC, eJob ) ) 2256 return sal_True; 2257 } 2258 pC = pC->GetNextCntntFrm(); 2259 } 2260 } 2261 } 2262 } 2263 } 2264 return sal_False; 2265 } 2266 2267 sal_Bool SwLayIdle::DoIdleJob( IdleJobType eJob, sal_Bool bVisAreaOnly ) 2268 { 2269 //Spellchecken aller Inhalte der Seiten. Entweder nur der sichtbaren 2270 //Seiten oder eben aller. 2271 const ViewShell* pViewShell = pImp->GetShell(); 2272 const SwViewOption* pViewOptions = pViewShell->GetViewOptions(); 2273 const SwDoc* pDoc = pViewShell->GetDoc(); 2274 2275 switch ( eJob ) 2276 { 2277 case ONLINE_SPELLING : 2278 if( !pViewOptions->IsOnlineSpell() ) 2279 return sal_False; 2280 break; 2281 case AUTOCOMPLETE_WORDS : 2282 if( !pViewOptions->IsAutoCompleteWords() || 2283 pDoc->GetAutoCompleteWords().IsLockWordLstLocked()) 2284 return sal_False; 2285 break; 2286 case WORD_COUNT : 2287 if ( !pViewShell->getIDocumentStatistics()->GetDocStat().bModified ) 2288 return sal_False; 2289 break; 2290 case SMART_TAGS : 2291 if ( pDoc->GetDocShell()->IsHelpDocument() || 2292 pDoc->isXForms() || 2293 !SwSmartTagMgr::Get().IsSmartTagsEnabled() ) 2294 return sal_False; 2295 break; 2296 default: ASSERT( false, "Unknown idle job type" ) 2297 } 2298 2299 SwPageFrm *pPage; 2300 if ( bVisAreaOnly ) 2301 pPage = pImp->GetFirstVisPage(); 2302 else 2303 pPage = (SwPageFrm*)pRoot->Lower(); 2304 2305 pCntntNode = NULL; 2306 nTxtPos = STRING_LEN; 2307 2308 while ( pPage ) 2309 { 2310 bPageValid = sal_True; 2311 const SwCntntFrm *pCnt = pPage->ContainsCntnt(); 2312 while( pCnt && pPage->IsAnLower( pCnt ) ) 2313 { 2314 if ( _DoIdleJob( pCnt, eJob ) ) 2315 return sal_True; 2316 pCnt = pCnt->GetNextCntntFrm(); 2317 } 2318 if ( pPage->GetSortedObjs() ) 2319 { 2320 for ( sal_uInt16 i = 0; pPage->GetSortedObjs() && 2321 i < pPage->GetSortedObjs()->Count(); ++i ) 2322 { 2323 const SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i]; 2324 if ( pObj->ISA(SwFlyFrm) ) 2325 { 2326 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj); 2327 const SwCntntFrm *pC = pFly->ContainsCntnt(); 2328 while( pC ) 2329 { 2330 if ( pC->IsTxtFrm() ) 2331 { 2332 if ( _DoIdleJob( pC, eJob ) ) 2333 return sal_True; 2334 } 2335 pC = pC->GetNextCntntFrm(); 2336 } 2337 } 2338 } 2339 } 2340 2341 if( bPageValid ) 2342 { 2343 switch ( eJob ) 2344 { 2345 case ONLINE_SPELLING : pPage->ValidateSpelling(); break; 2346 case AUTOCOMPLETE_WORDS : pPage->ValidateAutoCompleteWords(); break; 2347 case WORD_COUNT : pPage->ValidateWordCount(); break; 2348 case SMART_TAGS : pPage->ValidateSmartTags(); break; // SMARTTAGS 2349 } 2350 } 2351 2352 pPage = (SwPageFrm*)pPage->GetNext(); 2353 if ( pPage && bVisAreaOnly && 2354 !pPage->Frm().IsOver( pImp->GetShell()->VisArea())) 2355 break; 2356 } 2357 return sal_False; 2358 } 2359 2360 2361 #ifdef DBG_UTIL 2362 #if OSL_DEBUG_LEVEL > 1 2363 2364 /************************************************************************* 2365 |* 2366 |* void SwLayIdle::SwLayIdle() 2367 |* 2368 |* Ersterstellung MA ?? 2369 |* Letzte Aenderung MA 09. Jun. 94 2370 |* 2371 |*************************************************************************/ 2372 void SwLayIdle::ShowIdle( ColorData eColorData ) 2373 { 2374 if ( !bIndicator ) 2375 { 2376 bIndicator = sal_True; 2377 Window *pWin = pImp->GetShell()->GetWin(); 2378 if ( pWin ) 2379 { 2380 Rectangle aRect( 0, 0, 5, 5 ); 2381 aRect = pWin->PixelToLogic( aRect ); 2382 // OD 2004-04-23 #116347# 2383 pWin->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 2384 pWin->SetFillColor( eColorData ); 2385 pWin->SetLineColor(); 2386 pWin->DrawRect( aRect ); 2387 pWin->Pop(); 2388 } 2389 } 2390 } 2391 #define SHOW_IDLE( ColorData ) ShowIdle( ColorData ) 2392 #else 2393 #define SHOW_IDLE( ColorData ) 2394 #endif 2395 #else 2396 #define SHOW_IDLE( ColorData ) 2397 #endif 2398 2399 /************************************************************************* 2400 |* 2401 |* void SwLayIdle::SwLayIdle() 2402 |* 2403 |* Ersterstellung MA 30. Oct. 92 2404 |* Letzte Aenderung MA 23. May. 95 2405 |* 2406 |*************************************************************************/ 2407 SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) : 2408 pRoot( pRt ), 2409 pImp( pI ) 2410 #ifdef DBG_UTIL 2411 #if OSL_DEBUG_LEVEL > 1 2412 , bIndicator( sal_False ) 2413 #endif 2414 #endif 2415 { 2416 pImp->pIdleAct = this; 2417 2418 SHOW_IDLE( COL_LIGHTRED ); 2419 2420 pImp->GetShell()->EnableSmooth( sal_False ); 2421 2422 //Zuerst den Sichtbaren Bereich Spellchecken, nur wenn dort nichts 2423 //zu tun war wird das IdleFormat angestossen. 2424 if ( !DoIdleJob( SMART_TAGS, sal_True ) && 2425 !DoIdleJob( ONLINE_SPELLING, sal_True ) && 2426 !DoIdleJob( AUTOCOMPLETE_WORDS, sal_True ) ) // SMARTTAGS 2427 { 2428 //Formatieren und ggf. Repaint-Rechtecke an der ViewShell vormerken. 2429 //Dabei muessen kuenstliche Actions laufen, damit es z.B. bei 2430 //Veraenderungen der Seitenzahl nicht zu unerwuenschten Effekten kommt. 2431 //Wir merken uns bei welchen Shells der Cursor sichtbar ist, damit 2432 //wir ihn bei Dokumentaenderung ggf. wieder sichbar machen koennen. 2433 SvBools aBools; 2434 ViewShell *pSh = pImp->GetShell(); 2435 do 2436 { ++pSh->nStartAction; 2437 sal_Bool bVis = sal_False; 2438 if ( pSh->ISA(SwCrsrShell) ) 2439 { 2440 #ifdef SW_CRSR_TIMER 2441 ((SwCrsrShell*)pSh)->ChgCrsrTimerFlag( sal_False ); 2442 #endif 2443 bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea()); 2444 } 2445 aBools.push_back( bVis ); 2446 pSh = (ViewShell*)pSh->GetNext(); 2447 } while ( pSh != pImp->GetShell() ); 2448 2449 SwLayAction aAction( pRoot, pImp ); 2450 aAction.SetInputType( INPUT_ANY ); 2451 aAction.SetIdle( sal_True ); 2452 aAction.SetWaitAllowed( sal_False ); 2453 aAction.Action(); 2454 2455 //Weitere Start-/EndActions nur auf wenn irgendwo Paints aufgelaufen 2456 //sind oder wenn sich die Sichtbarkeit des CharRects veraendert hat. 2457 sal_Bool bActions = sal_False; 2458 sal_uInt16 nBoolIdx = 0; 2459 do 2460 { 2461 --pSh->nStartAction; 2462 2463 if ( pSh->Imp()->GetRegion() ) 2464 bActions = sal_True; 2465 else 2466 { 2467 SwRect aTmp( pSh->VisArea() ); 2468 pSh->UISizeNotify(); 2469 2470 // --> FME 2006-08-03 #137134# 2471 // Are we supposed to crash if pSh isn't a cursor shell?! 2472 // bActions |= aTmp != pSh->VisArea() || 2473 // aBools[nBoolIdx] != ((SwCrsrShell*)pSh)->GetCharRect().IsOver( pSh->VisArea() ); 2474 2475 // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!) 2476 // and the cursor is visible. 2477 bActions |= aTmp != pSh->VisArea(); 2478 if ( aTmp == pSh->VisArea() && pSh->ISA(SwCrsrShell) ) 2479 { 2480 bActions |= aBools[nBoolIdx] != 2481 static_cast<SwCrsrShell*>(pSh)->GetCharRect().IsOver( pSh->VisArea() ); 2482 } 2483 } 2484 2485 pSh = (ViewShell*)pSh->GetNext(); 2486 ++nBoolIdx; 2487 } while ( pSh != pImp->GetShell() ); 2488 2489 if ( bActions ) 2490 { 2491 //Start- EndActions aufsetzen. ueber die CrsrShell, damit der 2492 //Cursor/Selektion und die VisArea korrekt gesetzt werden. 2493 nBoolIdx = 0; 2494 do 2495 { 2496 sal_Bool bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) ); 2497 2498 if ( bCrsrShell ) 2499 ((SwCrsrShell*)pSh)->SttCrsrMove(); 2500 // else 2501 // pSh->StartAction(); 2502 2503 //Wenn Paints aufgelaufen sind, ist es am sinnvollsten schlicht das 2504 //gesamte Window zu invalidieren. Anderfalls gibt es Paintprobleme 2505 //deren Loesung unverhaeltnissmaessig aufwendig waere. 2506 //fix(18176): 2507 SwViewImp *pViewImp = pSh->Imp(); 2508 sal_Bool bUnlock = sal_False; 2509 if ( pViewImp->GetRegion() ) 2510 { 2511 pViewImp->DelRegion(); 2512 2513 //Fuer Repaint mit virtuellem Device sorgen. 2514 pSh->LockPaint(); 2515 bUnlock = sal_True; 2516 } 2517 2518 if ( bCrsrShell ) 2519 //Wenn der Crsr sichbar war wieder sichbar machen, sonst 2520 //EndCrsrMove mit sal_True fuer IdleEnd. 2521 ((SwCrsrShell*)pSh)->EndCrsrMove( sal_True^aBools[nBoolIdx] ); 2522 // else 2523 // pSh->EndAction(); 2524 if( bUnlock ) 2525 { 2526 if( bCrsrShell ) 2527 { 2528 // UnlockPaint overwrite the selection from the 2529 // CrsrShell and calls the virtual method paint 2530 // to fill the virtual device. This fill dont have 2531 // paint the selection! -> Set the focus flag at 2532 // CrsrShell and it dont paint the selection. 2533 ((SwCrsrShell*)pSh)->ShLooseFcs(); 2534 pSh->UnlockPaint( sal_True ); 2535 ((SwCrsrShell*)pSh)->ShGetFcs( sal_False ); 2536 } 2537 else 2538 pSh->UnlockPaint( sal_True ); 2539 } 2540 2541 pSh = (ViewShell*)pSh->GetNext(); 2542 ++nBoolIdx; 2543 2544 } while ( pSh != pImp->GetShell() ); 2545 } 2546 2547 if ( !aAction.IsInterrupt() ) 2548 { 2549 if ( !DoIdleJob( WORD_COUNT, sal_False ) ) 2550 if ( !DoIdleJob( SMART_TAGS, sal_False ) ) 2551 if ( !DoIdleJob( ONLINE_SPELLING, sal_False ) ) 2552 DoIdleJob( AUTOCOMPLETE_WORDS, sal_False ); // SMARTTAGS 2553 } 2554 2555 bool bInValid = false; 2556 const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions(); 2557 const ViewShell* pViewShell = pImp->GetShell(); 2558 // See conditions in DoIdleJob() 2559 const sal_Bool bSpell = rVOpt.IsOnlineSpell(); 2560 const sal_Bool bACmplWrd = rVOpt.IsAutoCompleteWords(); 2561 const sal_Bool bWordCount = pViewShell->getIDocumentStatistics()->GetDocStat().bModified; 2562 const sal_Bool bSmartTags = !pViewShell->GetDoc()->GetDocShell()->IsHelpDocument() && 2563 !pViewShell->GetDoc()->isXForms() && 2564 SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS 2565 2566 SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower(); 2567 do 2568 { 2569 bInValid = pPg->IsInvalidCntnt() || pPg->IsInvalidLayout() || 2570 pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() || 2571 pPg->IsInvalidFlyInCnt() || 2572 (bSpell && pPg->IsInvalidSpelling()) || 2573 (bACmplWrd && pPg->IsInvalidAutoCompleteWords()) || 2574 (bWordCount && pPg->IsInvalidWordCount()) || 2575 (bSmartTags && pPg->IsInvalidSmartTags()); // SMARTTAGS 2576 2577 pPg = (SwPageFrm*)pPg->GetNext(); 2578 2579 } while ( pPg && !bInValid ); 2580 2581 if ( !bInValid ) 2582 { 2583 pRoot->ResetIdleFormat(); 2584 SfxObjectShell* pDocShell = pImp->GetShell()->GetDoc()->GetDocShell(); 2585 pDocShell->Broadcast( SfxEventHint( SW_EVENT_LAYOUT_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) ); 2586 } 2587 } 2588 2589 pImp->GetShell()->EnableSmooth( sal_True ); 2590 2591 if( pImp->IsAccessible() ) 2592 pImp->FireAccessibleEvents(); 2593 2594 #ifdef DBG_UTIL 2595 #if OSL_DEBUG_LEVEL > 1 2596 if ( bIndicator && pImp->GetShell()->GetWin() ) 2597 { 2598 // #i75172# Do not invalidate indicator, this may cause a endless loop. Instead, just repaint it 2599 // This should be replaced by an overlay object in the future, anyways. Since it's only for debug 2600 // purposes, it is not urgent. 2601 static bool bCheckWithoutInvalidating(true); 2602 if(bCheckWithoutInvalidating) 2603 { 2604 bIndicator = false; SHOW_IDLE( COL_LIGHTGREEN ); 2605 } 2606 else 2607 { 2608 Rectangle aRect( 0, 0, 5, 5 ); 2609 aRect = pImp->GetShell()->GetWin()->PixelToLogic( aRect ); 2610 pImp->GetShell()->GetWin()->Invalidate( aRect ); 2611 } 2612 } 2613 #endif 2614 #endif 2615 } 2616 2617 SwLayIdle::~SwLayIdle() 2618 { 2619 pImp->pIdleAct = 0; 2620 } 2621 2622