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(), 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 dass 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 bisschen 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 sichtbar 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 (shadow removed now) 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 1461 //mod #i6193# added sidebar width 1462 const SwPostItMgr* pPostItMgr = pImp->GetShell()->GetPostItMgr(); 1463 const int nSidebarWidth = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0; 1464 switch ( pPageFrm->SidebarPosition() ) 1465 { 1466 case sw::sidebarwindows::SIDEBAR_LEFT: 1467 { 1468 aPaint.Left( aPaint.Left() - nBorderWidth - nSidebarWidth); 1469 aPaint.Right( aPaint.Right() + nBorderWidth ); 1470 } 1471 break; 1472 case sw::sidebarwindows::SIDEBAR_RIGHT: 1473 { 1474 aPaint.Left( aPaint.Left() - nBorderWidth ); 1475 aPaint.Right( aPaint.Right() + nBorderWidth + nSidebarWidth); 1476 } 1477 break; 1478 case sw::sidebarwindows::SIDEBAR_NONE: 1479 // nothing to do 1480 break; 1481 } 1482 aPaint.Top( aPaint.Top() - nBorderWidth ); 1483 aPaint.Bottom( aPaint.Bottom() + nBorderWidth ); 1484 } 1485 1486 sal_Bool bPageInBrowseMode = pLay->IsPageFrm(); 1487 if( bPageInBrowseMode ) 1488 { 1489 const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell(); 1490 if( !pSh || !pSh->GetViewOptions()->getBrowseMode() ) 1491 bPageInBrowseMode = sal_False; 1492 } 1493 if( bPageInBrowseMode ) 1494 { 1495 // NOTE: no vertical layout in online layout 1496 //Ist die Aenderung ueberhaupt sichtbar? 1497 if ( pLay->IsCompletePaint() ) 1498 { 1499 pImp->GetShell()->AddPaintRect( aPaint ); 1500 bAddRect = sal_False; 1501 } 1502 else 1503 { 1504 sal_uInt16 i; 1505 1506 SwRegionRects aRegion( aOldRect ); 1507 aRegion -= aPaint; 1508 for ( i = 0; i < aRegion.Count(); ++i ) 1509 pImp->GetShell()->AddPaintRect( aRegion[i] ); 1510 aRegion.ChangeOrigin( aPaint ); 1511 aRegion.Remove( 0, aRegion.Count() ); 1512 aRegion.Insert( aPaint, 0 ); 1513 aRegion -= aOldRect; 1514 for ( i = 0; i < aRegion.Count(); ++i ) 1515 pImp->GetShell()->AddPaintRect( aRegion[i] ); 1516 } 1517 1518 } 1519 else 1520 { 1521 pImp->GetShell()->AddPaintRect( aPaint ); 1522 bAlreadyPainted = sal_True; 1523 // OD 11.11.2002 #104414# - remember frame at complete paint 1524 aFrmAtCompletePaint = pLay->Frm(); 1525 } 1526 1527 // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing 1528 // between pages (not only for in online mode). 1529 if ( pLay->IsPageFrm() ) 1530 { 1531 const SwTwips nHalfDocBorder = GAPBETWEENPAGES; 1532 const bool bLeftToRightViewLayout = pRoot->IsLeftToRightViewLayout(); 1533 const bool bPrev = bLeftToRightViewLayout ? pLay->GetPrev() : pLay->GetNext(); 1534 const bool bNext = bLeftToRightViewLayout ? pLay->GetNext() : pLay->GetPrev(); 1535 1536 if ( bPrev ) 1537 { 1538 // top 1539 SwRect aSpaceToPrevPage( pLay->Frm() ); 1540 const SwTwips nTop = aSpaceToPrevPage.Top() - nHalfDocBorder; 1541 if ( nTop >= 0 ) 1542 aSpaceToPrevPage.Top( nTop ); 1543 aSpaceToPrevPage.Bottom( pLay->Frm().Top() ); 1544 pImp->GetShell()->AddPaintRect( aSpaceToPrevPage ); 1545 1546 // left 1547 aSpaceToPrevPage = pLay->Frm(); 1548 const SwTwips nLeft = aSpaceToPrevPage.Left() - nHalfDocBorder; 1549 if ( nLeft >= 0 ) 1550 aSpaceToPrevPage.Left( nLeft ); 1551 aSpaceToPrevPage.Right( pLay->Frm().Left() ); 1552 pImp->GetShell()->AddPaintRect( aSpaceToPrevPage ); 1553 } 1554 if ( bNext ) 1555 { 1556 // bottom 1557 SwRect aSpaceToNextPage( pLay->Frm() ); 1558 aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + nHalfDocBorder ); 1559 aSpaceToNextPage.Top( pLay->Frm().Bottom() ); 1560 pImp->GetShell()->AddPaintRect( aSpaceToNextPage ); 1561 1562 // right 1563 aSpaceToNextPage = pLay->Frm(); 1564 aSpaceToNextPage.Right( aSpaceToNextPage.Right() + nHalfDocBorder ); 1565 aSpaceToNextPage.Left( pLay->Frm().Right() ); 1566 pImp->GetShell()->AddPaintRect( aSpaceToNextPage ); 1567 } 1568 } 1569 } 1570 pLay->ResetCompletePaint(); 1571 } 1572 1573 if ( IsPaint() && bAddRect && 1574 !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() ) 1575 { 1576 // OD 15.11.2002 #105155# - vertical layout support 1577 SWRECTFN( pLay ); 1578 SwRect aRect( pLay->GetUpper()->PaintArea() ); 1579 (aRect.*fnRect->fnSetTop)( (pLay->*fnRect->fnGetPrtBottom)() ); 1580 if ( !pImp->GetShell()->AddPaintRect( aRect ) ) 1581 pLay->ResetRetouche(); 1582 } 1583 1584 if( bAlreadyPainted ) 1585 bAddRect = sal_False; 1586 1587 CheckWaitCrsr(); 1588 1589 if ( IsAgain() ) 1590 return sal_False; 1591 1592 //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind 1593 1594 if ( pLay->IsFtnFrm() ) //Hat keine LayFrms als Lower. 1595 return bChanged; 1596 1597 SwFrm *pLow = pLay->Lower(); 1598 sal_Bool bTabChanged = sal_False; 1599 while ( pLow && pLow->GetUpper() == pLay ) 1600 { 1601 if ( pLow->IsLayoutFrm() ) 1602 { 1603 if ( pLow->IsTabFrm() ) 1604 bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect ); 1605 // bereits zum Loeschen angemeldete Ueberspringen 1606 else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() ) 1607 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); 1608 } 1609 else if ( pImp->GetShell()->IsPaintLocked() ) 1610 //Abkuerzung im die Zyklen zu minimieren, bei Lock kommt das 1611 //Paint sowieso (Primaer fuer Browse) 1612 pLow->OptCalc(); 1613 1614 if ( IsAgain() ) 1615 return sal_False; 1616 pLow = pLow->GetNext(); 1617 } 1618 // OD 11.11.2002 #104414# - add complete frame area as paint area, if frame 1619 // area has been already added and after formating its lowers the frame area 1620 // is enlarged. 1621 if ( bAlreadyPainted && 1622 ( pLay->Frm().Width() > aFrmAtCompletePaint.Width() || 1623 pLay->Frm().Height() > aFrmAtCompletePaint.Height() ) 1624 ) 1625 { 1626 pImp->GetShell()->AddPaintRect( pLay->Frm() ); 1627 } 1628 return bChanged || bTabChanged; 1629 } 1630 1631 sal_Bool SwLayAction::FormatLayoutFly( SwFlyFrm* pFly ) 1632 { 1633 ASSERT( !IsAgain(), "Ungueltige Seite beachten." ); 1634 if ( IsAgain() ) 1635 return sal_False; 1636 1637 sal_Bool bChanged = false; 1638 sal_Bool bAddRect = true; 1639 1640 if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() ) 1641 { 1642 //Der Frame hat sich veraendert, er wird jetzt Formatiert 1643 const SwRect aOldRect( pFly->Frm() ); 1644 pFly->Calc(); 1645 bChanged = aOldRect != pFly->Frm(); 1646 1647 if ( IsPaint() && (pFly->IsCompletePaint() || bChanged) && 1648 pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 ) 1649 pImp->GetShell()->AddPaintRect( pFly->Frm() ); 1650 1651 if ( bChanged ) 1652 pFly->Invalidate(); 1653 else 1654 pFly->Validate(); 1655 /* 1656 //mba: it's unclear why we should invalidate always, so I remove it 1657 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1658 if ( IsPaint() && bAddRect && pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 ) 1659 pImp->GetShell()->AddPaintRect( pFly->Frm() ); 1660 1661 pFly->Invalidate(); 1662 */ 1663 bAddRect = false; 1664 pFly->ResetCompletePaint(); 1665 } 1666 1667 if ( IsAgain() ) 1668 return sal_False; 1669 1670 //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind 1671 sal_Bool bTabChanged = false; 1672 SwFrm *pLow = pFly->Lower(); 1673 while ( pLow ) 1674 { 1675 if ( pLow->IsLayoutFrm() ) 1676 { 1677 if ( pLow->IsTabFrm() ) 1678 bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect ); 1679 else 1680 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); 1681 } 1682 pLow = pLow->GetNext(); 1683 } 1684 return bChanged || bTabChanged; 1685 } 1686 1687 // OD 31.10.2002 #104100# 1688 // Implement vertical layout support 1689 sal_Bool SwLayAction::FormatLayoutTab( SwTabFrm *pTab, sal_Bool bAddRect ) 1690 { 1691 ASSERT( !IsAgain(), "8-) Ungueltige Seite beachten." ); 1692 if ( IsAgain() || !pTab->Lower() ) 1693 return sal_False; 1694 1695 IDocumentTimerAccess *pTimerAccess = pRoot->GetFmt()->getIDocumentTimerAccess(); 1696 pTimerAccess->BlockIdling(); 1697 1698 sal_Bool bChanged = sal_False; 1699 sal_Bool bPainted = sal_False; 1700 1701 const SwPageFrm *pOldPage = pTab->FindPageFrm(); 1702 1703 // OD 31.10.2002 #104100# - vertical layout support 1704 // use macro to declare and init <sal_Bool bVert>, <sal_Bool bRev> and 1705 // <SwRectFn fnRect> for table frame <pTab>. 1706 SWRECTFN( pTab ); 1707 1708 if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() ) 1709 { 1710 if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() ) 1711 { 1712 pTab->GetPrev()->SetCompletePaint(); 1713 } 1714 1715 const SwRect aOldRect( pTab->Frm() ); 1716 pTab->SetLowersFormatted( sal_False ); 1717 pTab->Calc(); 1718 if ( aOldRect != pTab->Frm() ) 1719 { 1720 bChanged = sal_True; 1721 } 1722 const SwRect aPaintFrm = pTab->PaintArea(); 1723 1724 if ( IsPaint() && bAddRect ) 1725 { 1726 // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()> 1727 if ( !pTab->IsCompletePaint() && 1728 pTab->IsComplete() && 1729 ( pTab->Frm().SSize() != pTab->Prt().SSize() || 1730 // OD 31.10.2002 #104100# - vertical layout support 1731 (pTab->*fnRect->fnGetLeftMargin)() ) && 1732 pTab->Frm().HasArea() 1733 ) 1734 { 1735 // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles. 1736 SwRect aMarginRect; 1737 1738 SwTwips nLeftMargin = (pTab->*fnRect->fnGetLeftMargin)(); 1739 if ( nLeftMargin > 0) 1740 { 1741 aMarginRect = pTab->Frm(); 1742 (aMarginRect.*fnRect->fnSetWidth)( nLeftMargin ); 1743 pImp->GetShell()->AddPaintRect( aMarginRect ); 1744 } 1745 1746 if ( (pTab->*fnRect->fnGetRightMargin)() > 0) 1747 { 1748 aMarginRect = pTab->Frm(); 1749 (aMarginRect.*fnRect->fnSetLeft)( (pTab->*fnRect->fnGetPrtRight)() ); 1750 pImp->GetShell()->AddPaintRect( aMarginRect ); 1751 } 1752 1753 SwTwips nTopMargin = (pTab->*fnRect->fnGetTopMargin)(); 1754 if ( nTopMargin > 0) 1755 { 1756 aMarginRect = pTab->Frm(); 1757 (aMarginRect.*fnRect->fnSetHeight)( nTopMargin ); 1758 pImp->GetShell()->AddPaintRect( aMarginRect ); 1759 } 1760 1761 if ( (pTab->*fnRect->fnGetBottomMargin)() > 0) 1762 { 1763 aMarginRect = pTab->Frm(); 1764 (aMarginRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); 1765 pImp->GetShell()->AddPaintRect( aMarginRect ); 1766 } 1767 } 1768 else if ( pTab->IsCompletePaint() ) 1769 { 1770 pImp->GetShell()->AddPaintRect( aPaintFrm ); 1771 bAddRect = sal_False; 1772 bPainted = sal_True; 1773 } 1774 1775 if ( pTab->IsRetouche() && !pTab->GetNext() ) 1776 { 1777 SwRect aRect( pTab->GetUpper()->PaintArea() ); 1778 // OD 04.11.2002 #104100# - vertical layout support 1779 (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); 1780 if ( !pImp->GetShell()->AddPaintRect( aRect ) ) 1781 pTab->ResetRetouche(); 1782 } 1783 } 1784 else 1785 bAddRect = sal_False; 1786 1787 if ( pTab->IsCompletePaint() && !pOptTab ) 1788 pOptTab = pTab; 1789 pTab->ResetCompletePaint(); 1790 } 1791 if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() ) 1792 { 1793 // OD 04.10.2002 #102779# 1794 // set correct rectangle for retouche: area between bottom of table frame 1795 // and bottom of paint area of the upper frame. 1796 SwRect aRect( pTab->GetUpper()->PaintArea() ); 1797 // OD 04.11.2002 #104100# - vertical layout support 1798 (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); 1799 if ( !pImp->GetShell()->AddPaintRect( aRect ) ) 1800 pTab->ResetRetouche(); 1801 } 1802 1803 CheckWaitCrsr(); 1804 1805 pTimerAccess->UnblockIdling(); 1806 1807 //Heftige Abkuerzung! 1808 if ( pTab->IsLowersFormatted() && 1809 (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) ) 1810 return sal_False; 1811 1812 //Jetzt noch die Lowers versorgen 1813 if ( IsAgain() ) 1814 return sal_False; 1815 1816 // OD 20.10.2003 #112464# - for safety reasons: 1817 // check page number before formatting lowers. 1818 if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) ) 1819 SetNextCycle( sal_True ); 1820 1821 // OD 20.10.2003 #112464# - format lowers, only if table frame is valid 1822 if ( pTab->IsValid() ) 1823 { 1824 SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower(); 1825 while ( pLow ) 1826 { 1827 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); 1828 if ( IsAgain() ) 1829 return sal_False; 1830 pLow = (SwLayoutFrm*)pLow->GetNext(); 1831 } 1832 } 1833 1834 return bChanged; 1835 } 1836 1837 /************************************************************************* 1838 |* 1839 |* SwLayAction::FormatCntnt() 1840 |* 1841 |* Ersterstellung MA 30. Oct. 92 1842 |* Letzte Aenderung MA 16. Nov. 95 1843 |* 1844 |*************************************************************************/ 1845 sal_Bool SwLayAction::FormatCntnt( const SwPageFrm *pPage ) 1846 { 1847 const SwCntntFrm *pCntnt = pPage->ContainsCntnt(); 1848 const ViewShell *pSh = pRoot->GetCurrShell(); 1849 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); 1850 1851 while ( pCntnt && pPage->IsAnLower( pCntnt ) ) 1852 { 1853 //Wenn der Cntnt sich eh nicht veraendert koennen wir ein paar 1854 //Abkuerzungen nutzen. 1855 const sal_Bool bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() || 1856 pCntnt->IsRetouche() || pCntnt->GetDrawObjs(); 1857 if ( bFull ) 1858 { 1859 //Damit wir nacher nicht suchen muessen. 1860 const sal_Bool bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow(); 1861 const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0; 1862 const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0; 1863 1864 const SwLayoutFrm*pOldUpper = pCntnt->GetUpper(); 1865 const SwTabFrm *pTab = pCntnt->FindTabFrm(); 1866 const sal_Bool bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint(); 1867 const sal_Bool bOldPaint = IsPaint(); 1868 bPaint = bOldPaint && !(pTab && pTab == pOptTab); 1869 _FormatCntnt( pCntnt, pPage ); 1870 // --> OD 2004-11-05 #i26945# - reset <bPaint> before format objects 1871 bPaint = bOldPaint; 1872 // <-- 1873 1874 // OD 2004-05-10 #i28701# - format floating screen object at content frame. 1875 // No format, if action flag <bAgain> is set or action is interrupted. 1876 // OD 2004-08-30 #117736# - allow format on interruption of action, if 1877 // it's the format for this interrupt 1878 // --> OD 2004-11-01 #i23129#, #i36347# - pass correct page frame 1879 // to the object formatter. 1880 if ( !IsAgain() && 1881 ( !IsInterrupt() || mbFormatCntntOnInterrupt ) && 1882 pCntnt->IsTxtFrm() && 1883 !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCntnt)), 1884 *(pCntnt->FindPageFrm()), this ) ) 1885 // <-- 1886 { 1887 return sal_False; 1888 } 1889 1890 if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) 1891 { 1892 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); 1893 ((SwTxtFrm*)pCntnt)->RecalcAllLines(); 1894 if ( IsPaintExtraData() && IsPaint() && 1895 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) 1896 pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); 1897 } 1898 1899 if ( IsAgain() ) 1900 return sal_False; 1901 1902 //Wenn Layout oder Flys wieder Invalid sind breche ich die Verarbeitung 1903 //vorlaeufig ab - allerdings nicht fuer die BrowseView, denn dort wird 1904 //das Layout staendig ungueltig, weil die Seitenhoehe angepasst wird. 1905 //Desgleichen wenn der Benutzer weiterarbeiten will und mindestens ein 1906 //Absatz verarbeitet wurde. 1907 if ( (!pTab || (pTab && !bInValid)) ) 1908 { 1909 CheckIdleEnd(); 1910 // OD 14.04.2003 #106346# - consider interrupt formatting. 1911 if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt ) || 1912 ( !bBrowse && pPage->IsInvalidLayout() ) || 1913 // OD 07.05.2003 #109435# - consider interrupt formatting 1914 ( IS_FLYS && IS_INVAFLY && !mbFormatCntntOnInterrupt ) 1915 ) 1916 return sal_False; 1917 } 1918 if ( pOldUpper != pCntnt->GetUpper() ) 1919 { 1920 const sal_uInt16 nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum(); 1921 if ( nCurNum < pPage->GetPhyPageNum() ) 1922 nPreInvaPage = nCurNum; 1923 1924 //Wenn der Frm mehr als eine Seite rueckwaerts geflossen ist, so 1925 //fangen wir nocheinmal von vorn an damit wir nichts auslassen. 1926 if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 ) 1927 { 1928 SetNextCycle( sal_True ); 1929 // OD 07.05.2003 #109435# - consider interrupt formatting 1930 if ( !mbFormatCntntOnInterrupt ) 1931 { 1932 return sal_False; 1933 } 1934 } 1935 } 1936 //Wenn der Frame die Seite vorwaerts gewechselt hat, so lassen wir 1937 //den Vorgaenger nocheinmal durchlaufen. 1938 //So werden einerseits Vorgaenger erwischt, die jetzt f?r Retouche 1939 //verantwortlich sind, andererseits werden die Fusszeilen 1940 //auch angefasst. 1941 sal_Bool bSetCntnt = sal_True; 1942 if ( pCntntPrev ) 1943 { 1944 if ( !pCntntPrev->IsValid() && pPage->IsAnLower( pCntntPrev ) ) 1945 pPage->InvalidateCntnt(); 1946 if ( pOldUpper != pCntnt->GetUpper() && 1947 pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() ) 1948 { 1949 pCntnt = pCntntPrev; 1950 bSetCntnt = sal_False; 1951 } 1952 } 1953 if ( bSetCntnt ) 1954 { 1955 if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() && 1956 pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom()) 1957 { 1958 const long nBottom = pImp->GetShell()->VisArea().Bottom(); 1959 const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage, 1960 nBottom, pCntnt ); 1961 if ( !pTmp ) 1962 { 1963 if ( (!(IS_FLYS && IS_INVAFLY) || 1964 !lcl_FindFirstInvaObj( pPage, nBottom )) && 1965 (!pPage->IsInvalidLayout() || 1966 !lcl_FindFirstInvaLay( pPage, nBottom ))) 1967 SetBrowseActionStop( sal_True ); 1968 // OD 14.04.2003 #106346# - consider interrupt formatting. 1969 if ( !mbFormatCntntOnInterrupt ) 1970 { 1971 return sal_False; 1972 } 1973 } 1974 } 1975 pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm(); 1976 } 1977 1978 RESCHEDULE; 1979 } 1980 else 1981 { 1982 if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) 1983 { 1984 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); 1985 ((SwTxtFrm*)pCntnt)->RecalcAllLines(); 1986 if ( IsPaintExtraData() && IsPaint() && 1987 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) 1988 pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); 1989 } 1990 1991 //Falls der Frm schon vor der Abarbeitung hier formatiert wurde. 1992 if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() && 1993 IsPaint() ) 1994 PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom()); 1995 if ( IsIdle() ) 1996 { 1997 CheckIdleEnd(); 1998 // OD 14.04.2003 #106346# - consider interrupt formatting. 1999 if ( IsInterrupt() && !mbFormatCntntOnInterrupt ) 2000 return sal_False; 2001 } 2002 if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() && 2003 pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom()) 2004 { 2005 const long nBottom = pImp->GetShell()->VisArea().Bottom(); 2006 const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage, 2007 nBottom, pCntnt ); 2008 if ( !pTmp ) 2009 { 2010 if ( (!(IS_FLYS && IS_INVAFLY) || 2011 !lcl_FindFirstInvaObj( pPage, nBottom )) && 2012 (!pPage->IsInvalidLayout() || 2013 !lcl_FindFirstInvaLay( pPage, nBottom ))) 2014 SetBrowseActionStop( sal_True ); 2015 // OD 14.04.2003 #106346# - consider interrupt formatting. 2016 if ( !mbFormatCntntOnInterrupt ) 2017 { 2018 return sal_False; 2019 } 2020 } 2021 } 2022 pCntnt = pCntnt->GetNextCntntFrm(); 2023 } 2024 } 2025 CheckWaitCrsr(); 2026 // OD 14.04.2003 #106346# - consider interrupt formatting. 2027 return !IsInterrupt() || mbFormatCntntOnInterrupt; 2028 } 2029 /************************************************************************* 2030 |* 2031 |* SwLayAction::_FormatCntnt() 2032 |* 2033 |* Beschreibung Returnt sal_True wenn der Absatz verarbeitet wurde, 2034 |* sal_False wenn es nichts zu verarbeiten gab. 2035 |* Ersterstellung MA 07. Dec. 92 2036 |* Letzte Aenderung MA 11. Mar. 98 2037 |* 2038 |*************************************************************************/ 2039 void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt, 2040 const SwPageFrm *pPage ) 2041 { 2042 //wird sind hier evtl. nur angekommen, weil der Cntnt DrawObjekte haelt. 2043 const sal_Bool bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() && 2044 !pCntnt->IsRetouche(); 2045 SWRECTFN( pCntnt ) 2046 if ( !bDrawObjsOnly && IsPaint() ) 2047 { 2048 const SwRect aOldRect( pCntnt->UnionFrm() ); 2049 const long nOldBottom = (pCntnt->*fnRect->fnGetPrtBottom)(); 2050 pCntnt->OptCalc(); 2051 if( IsAgain() ) 2052 return; 2053 if( (*fnRect->fnYDiff)( (pCntnt->Frm().*fnRect->fnGetBottom)(), 2054 (aOldRect.*fnRect->fnGetBottom)() ) < 0 ) 2055 { 2056 pCntnt->SetRetouche(); 2057 } 2058 PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom); 2059 } 2060 else 2061 { 2062 if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() ) 2063 PaintCntnt( pCntnt, pPage, pCntnt->Frm(), 2064 (pCntnt->Frm().*fnRect->fnGetBottom)() ); 2065 pCntnt->OptCalc(); 2066 } 2067 } 2068 2069 /************************************************************************* 2070 |* 2071 |* SwLayAction::_FormatFlyCntnt() 2072 |* 2073 |* Beschreibung: 2074 |* - Returnt sal_True wenn alle Cntnts des Flys vollstaendig verarbeitet 2075 |* wurden. sal_False wenn vorzeitig unterbrochen wurde. 2076 |* Ersterstellung MA 02. Dec. 92 2077 |* Letzte Aenderung MA 24. Jun. 96 2078 |* 2079 |*************************************************************************/ 2080 sal_Bool SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly ) 2081 { 2082 const SwCntntFrm *pCntnt = pFly->ContainsCntnt(); 2083 2084 while ( pCntnt ) 2085 { 2086 // OD 2004-05-10 #i28701# 2087 _FormatCntnt( pCntnt, pCntnt->FindPageFrm() ); 2088 2089 // --> OD 2004-07-23 #i28701# - format floating screen objects 2090 // at content text frame 2091 // --> OD 2004-11-02 #i23129#, #i36347# - pass correct page frame 2092 // to the object formatter. 2093 if ( pCntnt->IsTxtFrm() && 2094 !SwObjectFormatter::FormatObjsAtFrm( 2095 *(const_cast<SwCntntFrm*>(pCntnt)), 2096 *(pCntnt->FindPageFrm()), this ) ) 2097 // <-- 2098 { 2099 // restart format with first content 2100 pCntnt = pFly->ContainsCntnt(); 2101 continue; 2102 } 2103 // <-- 2104 2105 if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) 2106 { 2107 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); 2108 ((SwTxtFrm*)pCntnt)->RecalcAllLines(); 2109 if ( IsPaintExtraData() && IsPaint() && 2110 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) 2111 pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); 2112 } 2113 2114 if ( IsAgain() ) 2115 return sal_False; 2116 2117 //wenn eine Eingabe anliegt breche ich die Verarbeitung ab. 2118 if ( !pFly->IsFlyInCntFrm() ) 2119 { 2120 CheckIdleEnd(); 2121 // OD 14.04.2003 #106346# - consider interrupt formatting. 2122 if ( IsInterrupt() && !mbFormatCntntOnInterrupt ) 2123 return sal_False; 2124 } 2125 pCntnt = pCntnt->GetNextCntntFrm(); 2126 } 2127 CheckWaitCrsr(); 2128 // OD 14.04.2003 #106346# - consider interrupt formatting. 2129 return !(IsInterrupt() && !mbFormatCntntOnInterrupt); 2130 } 2131 2132 sal_Bool SwLayAction::IsStopPrt() const 2133 { 2134 sal_Bool bResult = sal_False; 2135 2136 if (pImp != NULL && pProgress != NULL) 2137 bResult = pImp->IsStopPrt(); 2138 2139 return bResult; 2140 } 2141 2142 /************************************************************************* 2143 |* 2144 |* SwLayAction::FormatSpelling(), _FormatSpelling() 2145 |* 2146 |* Ersterstellung AMA 01. Feb. 96 2147 |* Letzte Aenderung AMA 01. Feb. 96 2148 |* 2149 |*************************************************************************/ 2150 sal_Bool SwLayIdle::_DoIdleJob( const SwCntntFrm *pCnt, IdleJobType eJob ) 2151 { 2152 ASSERT( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" ); 2153 // robust against misuse by e.g. #i52542# 2154 if( !pCnt->IsTxtFrm() ) 2155 return sal_False; 2156 2157 const SwTxtNode* pTxtNode = pCnt->GetNode()->GetTxtNode(); 2158 2159 bool bProcess = false; 2160 switch ( eJob ) 2161 { 2162 case ONLINE_SPELLING : 2163 bProcess = pTxtNode->IsWrongDirty(); break; 2164 case AUTOCOMPLETE_WORDS : 2165 bProcess = pTxtNode->IsAutoCompleteWordDirty(); break; 2166 case WORD_COUNT : 2167 bProcess = pTxtNode->IsWordCountDirty(); break; 2168 case SMART_TAGS : // SMARTTAGS 2169 bProcess = pTxtNode->IsSmartTagDirty(); break; 2170 } 2171 2172 if( bProcess ) 2173 { 2174 ViewShell *pSh = pImp->GetShell(); 2175 if( STRING_LEN == nTxtPos ) 2176 { 2177 --nTxtPos; 2178 if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() ) 2179 { 2180 SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr(); 2181 if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() ) 2182 { 2183 pCntntNode = pCrsr->GetCntntNode(); 2184 nTxtPos = pCrsr->GetPoint()->nContent.GetIndex(); 2185 } 2186 } 2187 } 2188 2189 switch ( eJob ) 2190 { 2191 case ONLINE_SPELLING : 2192 { 2193 SwRect aRepaint( ((SwTxtFrm*)pCnt)->_AutoSpell( pCntntNode, *pSh->GetViewOptions(), nTxtPos ) ); 2194 bPageValid = bPageValid && !pTxtNode->IsWrongDirty(); 2195 if( !bPageValid ) 2196 bAllValid = sal_False; 2197 if ( aRepaint.HasArea() ) 2198 pImp->GetShell()->InvalidateWindows( aRepaint ); 2199 if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) ) 2200 return sal_True; 2201 break; 2202 } 2203 case AUTOCOMPLETE_WORDS : 2204 ((SwTxtFrm*)pCnt)->CollectAutoCmplWrds( pCntntNode, nTxtPos ); 2205 if ( Application::AnyInput( INPUT_ANY ) ) 2206 return sal_True; 2207 break; 2208 case WORD_COUNT : 2209 { 2210 const xub_StrLen nEnd = pTxtNode->GetTxt().Len(); 2211 SwDocStat aStat; 2212 pTxtNode->CountWords( aStat, 0, nEnd ); 2213 if ( Application::AnyInput( INPUT_ANY ) ) 2214 return sal_True; 2215 break; 2216 } 2217 case SMART_TAGS : // SMARTTAGS 2218 { 2219 try { 2220 const SwRect aRepaint( ((SwTxtFrm*)pCnt)->SmartTagScan( pCntntNode, nTxtPos ) ); 2221 bPageValid = bPageValid && !pTxtNode->IsSmartTagDirty(); 2222 if( !bPageValid ) 2223 bAllValid = sal_False; 2224 if ( aRepaint.HasArea() ) 2225 pImp->GetShell()->InvalidateWindows( aRepaint ); 2226 } catch( const ::com::sun::star::uno::RuntimeException& e) { 2227 // #i122885# handle smarttag problems gracefully and provide diagnostics 2228 DBG_WARNING( rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); 2229 } 2230 if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD|INPUT_OTHER|INPUT_PAINT ) ) 2231 return sal_True; 2232 break; 2233 } 2234 } 2235 } 2236 2237 //Die im Absatz verankerten Flys wollen auch mitspielen. 2238 if ( pCnt->GetDrawObjs() ) 2239 { 2240 const SwSortedObjs &rObjs = *pCnt->GetDrawObjs(); 2241 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 2242 { 2243 SwAnchoredObject* pObj = rObjs[i]; 2244 if ( pObj->ISA(SwFlyFrm) ) 2245 { 2246 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj); 2247 if ( pFly->IsFlyInCntFrm() ) 2248 { 2249 const SwCntntFrm *pC = pFly->ContainsCntnt(); 2250 while( pC ) 2251 { 2252 if ( pC->IsTxtFrm() ) 2253 { 2254 if ( _DoIdleJob( pC, eJob ) ) 2255 return sal_True; 2256 } 2257 pC = pC->GetNextCntntFrm(); 2258 } 2259 } 2260 } 2261 } 2262 } 2263 return sal_False; 2264 } 2265 2266 sal_Bool SwLayIdle::DoIdleJob( IdleJobType eJob, sal_Bool bVisAreaOnly ) 2267 { 2268 //Spellchecken aller Inhalte der Seiten. Entweder nur der sichtbaren 2269 //Seiten oder eben aller. 2270 const ViewShell* pViewShell = pImp->GetShell(); 2271 const SwViewOption* pViewOptions = pViewShell->GetViewOptions(); 2272 const SwDoc* pDoc = pViewShell->GetDoc(); 2273 2274 switch ( eJob ) 2275 { 2276 case ONLINE_SPELLING : 2277 if( !pViewOptions->IsOnlineSpell() ) 2278 return sal_False; 2279 break; 2280 case AUTOCOMPLETE_WORDS : 2281 if( !pViewOptions->IsAutoCompleteWords() || 2282 pDoc->GetAutoCompleteWords().IsLockWordLstLocked()) 2283 return sal_False; 2284 break; 2285 case WORD_COUNT : 2286 if ( !pViewShell->getIDocumentStatistics()->GetDocStat().bModified ) 2287 return sal_False; 2288 break; 2289 case SMART_TAGS : 2290 if ( pDoc->GetDocShell()->IsHelpDocument() || 2291 pDoc->isXForms() || 2292 !SwSmartTagMgr::Get().IsSmartTagsEnabled() ) 2293 return sal_False; 2294 break; 2295 default: ASSERT( false, "Unknown idle job type" ) 2296 } 2297 2298 SwPageFrm *pPage; 2299 if ( bVisAreaOnly ) 2300 pPage = pImp->GetFirstVisPage(); 2301 else 2302 pPage = (SwPageFrm*)pRoot->Lower(); 2303 2304 pCntntNode = NULL; 2305 nTxtPos = STRING_LEN; 2306 2307 while ( pPage ) 2308 { 2309 bPageValid = sal_True; 2310 const SwCntntFrm *pCnt = pPage->ContainsCntnt(); 2311 while( pCnt && pPage->IsAnLower( pCnt ) ) 2312 { 2313 if ( _DoIdleJob( pCnt, eJob ) ) 2314 return sal_True; 2315 pCnt = pCnt->GetNextCntntFrm(); 2316 } 2317 if ( pPage->GetSortedObjs() ) 2318 { 2319 for ( sal_uInt16 i = 0; pPage->GetSortedObjs() && 2320 i < pPage->GetSortedObjs()->Count(); ++i ) 2321 { 2322 const SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i]; 2323 if ( pObj->ISA(SwFlyFrm) ) 2324 { 2325 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj); 2326 const SwCntntFrm *pC = pFly->ContainsCntnt(); 2327 while( pC ) 2328 { 2329 if ( pC->IsTxtFrm() ) 2330 { 2331 if ( _DoIdleJob( pC, eJob ) ) 2332 return sal_True; 2333 } 2334 pC = pC->GetNextCntntFrm(); 2335 } 2336 } 2337 } 2338 } 2339 2340 if( bPageValid ) 2341 { 2342 switch ( eJob ) 2343 { 2344 case ONLINE_SPELLING : pPage->ValidateSpelling(); break; 2345 case AUTOCOMPLETE_WORDS : pPage->ValidateAutoCompleteWords(); break; 2346 case WORD_COUNT : pPage->ValidateWordCount(); break; 2347 case SMART_TAGS : pPage->ValidateSmartTags(); break; // SMARTTAGS 2348 } 2349 } 2350 2351 pPage = (SwPageFrm*)pPage->GetNext(); 2352 if ( pPage && bVisAreaOnly && 2353 !pPage->Frm().IsOver( pImp->GetShell()->VisArea())) 2354 break; 2355 } 2356 return sal_False; 2357 } 2358 2359 2360 #ifdef DBG_UTIL 2361 #if OSL_DEBUG_LEVEL > 1 2362 2363 /************************************************************************* 2364 |* 2365 |* void SwLayIdle::SwLayIdle() 2366 |* 2367 |* Ersterstellung MA ?? 2368 |* Letzte Aenderung MA 09. Jun. 94 2369 |* 2370 |*************************************************************************/ 2371 void SwLayIdle::ShowIdle( ColorData eColorData ) 2372 { 2373 if ( !bIndicator ) 2374 { 2375 bIndicator = sal_True; 2376 Window *pWin = pImp->GetShell()->GetWin(); 2377 if ( pWin ) 2378 { 2379 Rectangle aRect( 0, 0, 5, 5 ); 2380 aRect = pWin->PixelToLogic( aRect ); 2381 // OD 2004-04-23 #116347# 2382 pWin->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 2383 pWin->SetFillColor( eColorData ); 2384 pWin->SetLineColor(); 2385 pWin->DrawRect( aRect ); 2386 pWin->Pop(); 2387 } 2388 } 2389 } 2390 #define SHOW_IDLE( ColorData ) ShowIdle( ColorData ) 2391 #else 2392 #define SHOW_IDLE( ColorData ) 2393 #endif 2394 #else 2395 #define SHOW_IDLE( ColorData ) 2396 #endif 2397 2398 /************************************************************************* 2399 |* 2400 |* void SwLayIdle::SwLayIdle() 2401 |* 2402 |* Ersterstellung MA 30. Oct. 92 2403 |* Letzte Aenderung MA 23. May. 95 2404 |* 2405 |*************************************************************************/ 2406 SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) : 2407 pRoot( pRt ), 2408 pImp( pI ) 2409 #ifdef DBG_UTIL 2410 #if OSL_DEBUG_LEVEL > 1 2411 , bIndicator( sal_False ) 2412 #endif 2413 #endif 2414 { 2415 pImp->pIdleAct = this; 2416 2417 SHOW_IDLE( COL_LIGHTRED ); 2418 2419 pImp->GetShell()->EnableSmooth( sal_False ); 2420 2421 //Zuerst den Sichtbaren Bereich Spellchecken, nur wenn dort nichts 2422 //zu tun war wird das IdleFormat angestossen. 2423 if ( !DoIdleJob( SMART_TAGS, sal_True ) && 2424 !DoIdleJob( ONLINE_SPELLING, sal_True ) && 2425 !DoIdleJob( AUTOCOMPLETE_WORDS, sal_True ) ) // SMARTTAGS 2426 { 2427 //Formatieren und ggf. Repaint-Rechtecke an der ViewShell vormerken. 2428 //Dabei muessen kuenstliche Actions laufen, damit es z.B. bei 2429 //Veraenderungen der Seitenzahl nicht zu unerwuenschten Effekten kommt. 2430 //Wir merken uns bei welchen Shells der Cursor sichtbar ist, damit 2431 //wir ihn bei Dokumentaenderung ggf. wieder sichbar machen koennen. 2432 SvBools aBools; 2433 ViewShell *pSh = pImp->GetShell(); 2434 do 2435 { ++pSh->nStartAction; 2436 sal_Bool bVis = sal_False; 2437 if ( pSh->ISA(SwCrsrShell) ) 2438 { 2439 #ifdef SW_CRSR_TIMER 2440 ((SwCrsrShell*)pSh)->ChgCrsrTimerFlag( sal_False ); 2441 #endif 2442 bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea()); 2443 } 2444 aBools.push_back( bVis ); 2445 pSh = (ViewShell*)pSh->GetNext(); 2446 } while ( pSh != pImp->GetShell() ); 2447 2448 SwLayAction aAction( pRoot, pImp ); 2449 aAction.SetInputType( INPUT_ANY ); 2450 aAction.SetIdle( sal_True ); 2451 aAction.SetWaitAllowed( sal_False ); 2452 aAction.Action(); 2453 2454 //Weitere Start-/EndActions nur auf wenn irgendwo Paints aufgelaufen 2455 //sind oder wenn sich die Sichtbarkeit des CharRects veraendert hat. 2456 sal_Bool bActions = sal_False; 2457 sal_uInt16 nBoolIdx = 0; 2458 do 2459 { 2460 --pSh->nStartAction; 2461 2462 if ( pSh->Imp()->GetRegion() ) 2463 bActions = sal_True; 2464 else 2465 { 2466 SwRect aTmp( pSh->VisArea() ); 2467 pSh->UISizeNotify(); 2468 2469 // --> FME 2006-08-03 #137134# 2470 // Are we supposed to crash if pSh isn't a cursor shell?! 2471 // bActions |= aTmp != pSh->VisArea() || 2472 // aBools[nBoolIdx] != ((SwCrsrShell*)pSh)->GetCharRect().IsOver( pSh->VisArea() ); 2473 2474 // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!) 2475 // and the cursor is visible. 2476 bActions |= aTmp != pSh->VisArea(); 2477 if ( aTmp == pSh->VisArea() && pSh->ISA(SwCrsrShell) ) 2478 { 2479 bActions |= aBools[nBoolIdx] != 2480 static_cast<SwCrsrShell*>(pSh)->GetCharRect().IsOver( pSh->VisArea() ); 2481 } 2482 } 2483 2484 pSh = (ViewShell*)pSh->GetNext(); 2485 ++nBoolIdx; 2486 } while ( pSh != pImp->GetShell() ); 2487 2488 if ( bActions ) 2489 { 2490 //Start- EndActions aufsetzen. ueber die CrsrShell, damit der 2491 //Cursor/Selektion und die VisArea korrekt gesetzt werden. 2492 nBoolIdx = 0; 2493 do 2494 { 2495 sal_Bool bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) ); 2496 2497 if ( bCrsrShell ) 2498 ((SwCrsrShell*)pSh)->SttCrsrMove(); 2499 // else 2500 // pSh->StartAction(); 2501 2502 //Wenn Paints aufgelaufen sind, ist es am sinnvollsten schlicht das 2503 //gesamte Window zu invalidieren. Anderfalls gibt es Paintprobleme 2504 //deren Loesung unverhaeltnissmaessig aufwendig waere. 2505 //fix(18176): 2506 SwViewImp *pViewImp = pSh->Imp(); 2507 sal_Bool bUnlock = sal_False; 2508 if ( pViewImp->GetRegion() ) 2509 { 2510 pViewImp->DelRegion(); 2511 2512 //Fuer Repaint mit virtuellem Device sorgen. 2513 pSh->LockPaint(); 2514 bUnlock = sal_True; 2515 } 2516 2517 if ( bCrsrShell ) 2518 //Wenn der Crsr sichbar war wieder sichbar machen, sonst 2519 //EndCrsrMove mit sal_True fuer IdleEnd. 2520 ((SwCrsrShell*)pSh)->EndCrsrMove( sal_True^aBools[nBoolIdx] ); 2521 // else 2522 // pSh->EndAction(); 2523 if( bUnlock ) 2524 { 2525 if( bCrsrShell ) 2526 { 2527 // UnlockPaint overwrite the selection from the 2528 // CrsrShell and calls the virtual method paint 2529 // to fill the virtual device. This fill dont have 2530 // paint the selection! -> Set the focus flag at 2531 // CrsrShell and it dont paint the selection. 2532 ((SwCrsrShell*)pSh)->ShLooseFcs(); 2533 pSh->UnlockPaint( sal_True ); 2534 ((SwCrsrShell*)pSh)->ShGetFcs( sal_False ); 2535 } 2536 else 2537 pSh->UnlockPaint( sal_True ); 2538 } 2539 2540 pSh = (ViewShell*)pSh->GetNext(); 2541 ++nBoolIdx; 2542 2543 } while ( pSh != pImp->GetShell() ); 2544 } 2545 2546 if ( !aAction.IsInterrupt() ) 2547 { 2548 if ( !DoIdleJob( WORD_COUNT, sal_False ) ) 2549 if ( !DoIdleJob( SMART_TAGS, sal_False ) ) 2550 if ( !DoIdleJob( ONLINE_SPELLING, sal_False ) ) 2551 DoIdleJob( AUTOCOMPLETE_WORDS, sal_False ); // SMARTTAGS 2552 } 2553 2554 bool bInValid = false; 2555 const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions(); 2556 const ViewShell* pViewShell = pImp->GetShell(); 2557 // See conditions in DoIdleJob() 2558 const sal_Bool bSpell = rVOpt.IsOnlineSpell(); 2559 const sal_Bool bACmplWrd = rVOpt.IsAutoCompleteWords(); 2560 const sal_Bool bWordCount = pViewShell->getIDocumentStatistics()->GetDocStat().bModified; 2561 const sal_Bool bSmartTags = !pViewShell->GetDoc()->GetDocShell()->IsHelpDocument() && 2562 !pViewShell->GetDoc()->isXForms() && 2563 SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS 2564 2565 SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower(); 2566 do 2567 { 2568 bInValid = pPg->IsInvalidCntnt() || pPg->IsInvalidLayout() || 2569 pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() || 2570 pPg->IsInvalidFlyInCnt() || 2571 (bSpell && pPg->IsInvalidSpelling()) || 2572 (bACmplWrd && pPg->IsInvalidAutoCompleteWords()) || 2573 (bWordCount && pPg->IsInvalidWordCount()) || 2574 (bSmartTags && pPg->IsInvalidSmartTags()); // SMARTTAGS 2575 2576 pPg = (SwPageFrm*)pPg->GetNext(); 2577 2578 } while ( pPg && !bInValid ); 2579 2580 if ( !bInValid ) 2581 { 2582 pRoot->ResetIdleFormat(); 2583 SfxObjectShell* pDocShell = pImp->GetShell()->GetDoc()->GetDocShell(); 2584 pDocShell->Broadcast( SfxEventHint( SW_EVENT_LAYOUT_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) ); 2585 } 2586 } 2587 2588 pImp->GetShell()->EnableSmooth( sal_True ); 2589 2590 if( pImp->IsAccessible() ) 2591 pImp->FireAccessibleEvents(); 2592 2593 #ifdef DBG_UTIL 2594 #if OSL_DEBUG_LEVEL > 1 2595 if ( bIndicator && pImp->GetShell()->GetWin() ) 2596 { 2597 // #i75172# Do not invalidate indicator, this may cause a endless loop. Instead, just repaint it 2598 // This should be replaced by an overlay object in the future, anyways. Since it's only for debug 2599 // purposes, it is not urgent. 2600 static bool bCheckWithoutInvalidating(true); 2601 if(bCheckWithoutInvalidating) 2602 { 2603 bIndicator = false; SHOW_IDLE( COL_LIGHTGREEN ); 2604 } 2605 else 2606 { 2607 Rectangle aRect( 0, 0, 5, 5 ); 2608 aRect = pImp->GetShell()->GetWin()->PixelToLogic( aRect ); 2609 pImp->GetShell()->GetWin()->Invalidate( aRect ); 2610 } 2611 } 2612 #endif 2613 #endif 2614 } 2615 2616 SwLayIdle::~SwLayIdle() 2617 { 2618 pImp->pIdleAct = 0; 2619 } 2620