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