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 #include "crsrsh.hxx" 28 #include "rootfrm.hxx" 29 #include "pagefrm.hxx" 30 #include "viewimp.hxx" 31 #include "errhdl.hxx" 32 #include "viewopt.hxx" 33 #include "flyfrm.hxx" 34 #include "frmfmt.hxx" 35 #include "layact.hxx" 36 #include "swregion.hxx" 37 #include "dflyobj.hxx" 38 #include "dview.hxx" 39 #include <tools/shl.hxx> 40 #include <swmodule.hxx> 41 #include <svx/svdpage.hxx> 42 #include <accmap.hxx> 43 #include <pagepreviewlayout.hxx> 44 #include <comcore.hrc> 45 #include <svx/svdundo.hxx> 46 #include <IDocumentLayoutAccess.hxx> 47 #include <IDocumentDrawModelAccess.hxx> 48 #include <IDocumentDeviceAccess.hxx> 49 #include <IDocumentSettingAccess.hxx> 50 #include <drawdoc.hxx> 51 52 /************************************************************************* 53 |* SwViewImp::Init() 54 |* 55 |* Ersterstellung MA 25. Jul. 94 56 |* Letzte Aenderung MA 03. Nov. 95 57 **************************************************************************/ 58 59 void SwViewImp::Init( const SwViewOption *pNewOpt ) 60 { 61 ASSERT( pDrawView, "SwViewImp::Init without DrawView" ); 62 // Jetzt die PageView erzeugen wenn sie noch nicht existiert. 63 SwRootFrm *pRoot = pSh->GetLayout(); //swmod 071108//swmod 071225 64 if ( !pSdrPageView ) 65 { 66 IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 67 if ( !pRoot->GetDrawPage() ) 68 pRoot->SetDrawPage( pIDDMA->GetDrawModel()->GetPage( 0 ) ); 69 70 if ( pRoot->GetDrawPage()->GetSize() != pRoot->Frm().SSize() ) 71 pRoot->GetDrawPage()->SetSize( pRoot->Frm().SSize() ); 72 73 pSdrPageView = pDrawView->ShowSdrPage( pRoot->GetDrawPage()); 74 // OD 26.06.2003 #108784# - notify drawing page view about invisible 75 // layers. 76 pIDDMA->NotifyInvisibleLayers( *pSdrPageView ); 77 } 78 pDrawView->SetDragStripes( pNewOpt->IsCrossHair() ); 79 pDrawView->SetGridSnap( pNewOpt->IsSnap() ); 80 pDrawView->SetGridVisible( pNewOpt->IsGridVisible() ); 81 const Size &rSz = pNewOpt->GetSnapSize(); 82 pDrawView->SetGridCoarse( rSz ); 83 const Size aFSize 84 ( rSz.Width() ? rSz.Width() /Max(short(1),pNewOpt->GetDivisionX()):0, 85 rSz.Height()? rSz.Height()/Max(short(1),pNewOpt->GetDivisionY()):0); 86 pDrawView->SetGridFine( aFSize ); 87 Fraction aSnGrWdtX(rSz.Width(), pNewOpt->GetDivisionX() + 1); 88 Fraction aSnGrWdtY(rSz.Height(), pNewOpt->GetDivisionY() + 1); 89 pDrawView->SetSnapGridWidth( aSnGrWdtX, aSnGrWdtY ); 90 91 if ( pRoot->Frm().HasArea() ) 92 pDrawView->SetWorkArea( pRoot->Frm().SVRect() ); 93 94 if ( GetShell()->IsPreView() ) 95 pDrawView->SetAnimationEnabled( sal_False ); 96 97 pDrawView->SetUseIncompatiblePathCreateInterface( sal_False ); 98 pDrawView->SetSolidMarkHdl(pNewOpt->IsSolidMarkHdl()); 99 100 // it's a JOE interface ! 101 pDrawView->SetMarkHdlSizePixel(pNewOpt->IsBigMarkHdl() ? 9 : 7); 102 } 103 104 /************************************************************************* 105 |* SwViewImp::SwViewImp() CTor fuer die Core-Internas 106 |* 107 |* Ersterstellung MA 25. Jul. 94 108 |* Letzte Aenderung MA 06. Sep. 96 109 **************************************************************************/ 110 111 SwViewImp::SwViewImp( ViewShell *pParent ) : 112 pSh( pParent ), 113 pDrawView( 0 ), 114 pSdrPageView( 0 ), 115 pFirstVisPage( 0 ), 116 pRegion( 0 ), 117 pLayAct( 0 ), 118 pIdleAct( 0 ), 119 pAccMap( 0 ), 120 pSdrObjCached(NULL), 121 nRestoreActions( 0 ), 122 // OD 12.12.2002 #103492# 123 mpPgPrevwLayout( 0 ) 124 { 125 //bResetXorVisibility = 126 //HMHbShowHdlPaint = 127 bResetHdlHiddenPaint = 128 bSmoothUpdate = bStopSmooth = bStopPrt = sal_False; 129 bFirstPageInvalid = sal_True; 130 } 131 132 /****************************************************************************** 133 |* SwViewImp::~SwViewImp() 134 |* 135 |* Ersterstellung MA 25. Jul. 94 136 |* Letzte Aenderung MA 16. Dec. 94 137 ******************************************************************************/ 138 139 SwViewImp::~SwViewImp() 140 { 141 delete pAccMap; 142 143 // OD 12.12.2002 #103492# 144 delete mpPgPrevwLayout; 145 146 //JP 29.03.96: nach ShowSdrPage muss auch HideSdrPage gemacht werden!!! 147 if( pDrawView ) 148 pDrawView->HideSdrPage(); 149 150 delete pDrawView; 151 152 DelRegion(); 153 154 ASSERT( !pLayAct, "Have action for the rest of your life." ); 155 ASSERT( !pIdleAct,"Be idle for the rest of your life." ); 156 } 157 158 /****************************************************************************** 159 |* SwViewImp::DelRegions() 160 |* 161 |* Ersterstellung MA 14. Apr. 94 162 |* Letzte Aenderung MA 14. Apr. 94 163 ******************************************************************************/ 164 165 void SwViewImp::DelRegion() 166 { 167 DELETEZ(pRegion); 168 } 169 170 /****************************************************************************** 171 |* SwViewImp::AddPaintRect() 172 |* 173 |* Ersterstellung MA ?? 174 |* Letzte Aenderung MA 27. Jul. 94 175 ******************************************************************************/ 176 177 sal_Bool SwViewImp::AddPaintRect( const SwRect &rRect ) 178 { 179 if ( rRect.IsOver( pSh->VisArea() ) ) 180 { 181 if ( !pRegion ) 182 pRegion = new SwRegionRects( pSh->VisArea() ); 183 (*pRegion) -= rRect; 184 return sal_True; 185 } 186 return sal_False; 187 } 188 189 190 /****************************************************************************** 191 |* ViewImp::CheckWaitCrsr() 192 |* 193 |* Ersterstellung MA 10. Aug. 94 194 |* Letzte Aenderung MA 10. Aug. 94 195 ******************************************************************************/ 196 197 void SwViewImp::CheckWaitCrsr() 198 { 199 if ( pLayAct ) 200 pLayAct->CheckWaitCrsr(); 201 } 202 203 /****************************************************************************** 204 |* ViewImp::IsCalcLayoutProgress() 205 |* 206 |* Ersterstellung MA 12. Aug. 94 207 |* Letzte Aenderung MA 12. Aug. 94 208 ******************************************************************************/ 209 210 sal_Bool SwViewImp::IsCalcLayoutProgress() const 211 { 212 if ( pLayAct ) 213 return pLayAct->IsCalcLayout(); 214 return sal_False; 215 } 216 217 /****************************************************************************** 218 |* ViewImp::IsUpdateExpFlds() 219 |* 220 |* Ersterstellung MA 28. Mar. 96 221 |* Letzte Aenderung MA 28. Mar. 96 222 ******************************************************************************/ 223 224 sal_Bool SwViewImp::IsUpdateExpFlds() 225 { 226 if ( pLayAct && pLayAct->IsCalcLayout() ) 227 { 228 pLayAct->SetUpdateExpFlds(); 229 return sal_True; 230 } 231 return sal_False; 232 } 233 234 235 /****************************************************************************** 236 |* SwViewImp::SetFirstVisPage(), ImplGetFirstVisPage(); 237 |* 238 |* Ersterstellung MA 21. Sep. 93 239 |* Letzte Aenderung MA 08. Mar. 94 240 ******************************************************************************/ 241 242 void SwViewImp::SetFirstVisPage() 243 { 244 if ( pSh->bDocSizeChgd && pSh->VisArea().Top() > pSh->GetLayout()->Frm().Height() ) 245 { 246 //Wir stecken in einer Aktion und die VisArea sitzt wegen 247 //Loeschoperationen hinter der erste sichtbaren Seite. 248 //Damit nicht zu heftig formatiert wird, liefern wir die letzte Seite 249 //zurueck. 250 pFirstVisPage = (SwPageFrm*)pSh->GetLayout()->Lower(); 251 while ( pFirstVisPage && pFirstVisPage->GetNext() ) 252 pFirstVisPage = (SwPageFrm*)pFirstVisPage->GetNext(); 253 } 254 else 255 { 256 const SwViewOption* pSwViewOption = GetShell()->GetViewOptions(); 257 const bool bBookMode = pSwViewOption->IsViewLayoutBookMode(); 258 259 SwPageFrm *pPage = (SwPageFrm*)pSh->GetLayout()->Lower(); 260 SwRect aPageRect = pPage->Frm(); 261 while ( pPage && !aPageRect.IsOver( pSh->VisArea() ) ) 262 { 263 pPage = (SwPageFrm*)pPage->GetNext(); 264 if ( pPage ) 265 { 266 aPageRect = pPage->Frm(); 267 if ( bBookMode && pPage->IsEmptyPage() ) 268 { 269 const SwPageFrm& rFormatPage = pPage->GetFormatPage(); 270 aPageRect.SSize() = rFormatPage.Frm().SSize(); 271 } 272 } 273 } 274 pFirstVisPage = pPage ? pPage : (SwPageFrm*)pSh->GetLayout()->Lower(); 275 } 276 bFirstPageInvalid = sal_False; 277 } 278 279 /****************************************************************************** 280 |* SwViewImp::MakeDrawView(); 281 |* 282 |* Ersterstellung AMA 01. Nov. 95 283 |* Letzte Aenderung AMA 01. Nov. 95 284 ******************************************************************************/ 285 286 void SwViewImp::MakeDrawView() 287 { 288 IDocumentDrawModelAccess* pIDDMA = GetShell()->getIDocumentDrawModelAccess(); 289 290 // the else here is not an error, _MakeDrawModel() calls this method again 291 // after the DrawModel is created to create DrawViews for all shells... 292 if( !pIDDMA->GetDrawModel() ) 293 { 294 pIDDMA->_MakeDrawModel(); 295 } 296 else 297 { 298 if ( !pDrawView ) 299 { 300 // #i72809# 301 // Discussed with FME, he also thinks that the getPrinter is old and not correct. When i got 302 // him right, it anyways returns GetOut() when it's a printer, but NULL when not. He suggested 303 // to use GetOut() and check the existing cases. 304 // Check worked well. Took a look at viewing, printing, PDF export and print preview with a test 305 // document which has an empty 2nd page (right page, see bug) 306 OutputDevice* pOutDevForDrawView = GetShell()->GetWin(); 307 308 if(!pOutDevForDrawView) 309 { 310 // pOutDevForDrawView = (OutputDevice*)GetShell()->getIDocumentDeviceAccess()->getPrinter( false ); 311 pOutDevForDrawView = GetShell()->GetOut(); 312 } 313 314 pDrawView = new SwDrawView( *this, pIDDMA->GetDrawModel(), pOutDevForDrawView); 315 } 316 317 GetDrawView()->SetActiveLayer( XubString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Heaven" ) ) ); 318 const SwViewOption* pSwViewOption = GetShell()->GetViewOptions(); 319 Init(pSwViewOption); 320 321 // #i68597# If document is read-only, we will not profit from overlay, 322 // so switch it off. 323 if(pDrawView && pDrawView->IsBufferedOverlayAllowed()) 324 { 325 bool bIsReadOnly(pSwViewOption->IsReadonly()); 326 327 #ifdef DBG_UTIL 328 // add test possibilities 329 static bool bAlwaysActivateForTest(false); 330 if(bAlwaysActivateForTest && bIsReadOnly) 331 { 332 bIsReadOnly = false; 333 } 334 #endif 335 336 if(bIsReadOnly) 337 { 338 pDrawView->SetBufferedOverlayAllowed(false); 339 } 340 } 341 } 342 } 343 344 /****************************************************************************** 345 |* SwViewImp::GetRetoucheColor() 346 |* 347 |* Ersterstellung MA 24. Jun. 98 348 |* Letzte Aenderung MA 24. Jun. 98 349 ******************************************************************************/ 350 351 Color SwViewImp::GetRetoucheColor() const 352 { 353 Color aRet( COL_TRANSPARENT ); 354 const ViewShell &rSh = *GetShell(); 355 if ( rSh.GetWin() ) 356 { 357 if ( rSh.GetViewOptions()->getBrowseMode() && 358 COL_TRANSPARENT != rSh.GetViewOptions()->GetRetoucheColor().GetColor() ) 359 aRet = rSh.GetViewOptions()->GetRetoucheColor(); 360 else if(rSh.GetViewOptions()->IsPagePreview() && 361 !SW_MOD()->GetAccessibilityOptions().GetIsForPagePreviews()) 362 aRet.SetColor(COL_WHITE); 363 else 364 aRet = SwViewOption::GetDocColor(); 365 } 366 return aRet; 367 } 368 369 /** create page preview layout 370 371 OD 12.12.2002 #103492# 372 373 @author OD 374 */ 375 void SwViewImp::InitPagePreviewLayout() 376 { 377 ASSERT( pSh->GetLayout(), "no layout - page preview layout can not be created."); 378 if ( pSh->GetLayout() ) 379 mpPgPrevwLayout = new SwPagePreviewLayout( *pSh, *(pSh->GetLayout()) ); 380 } 381 382 void SwViewImp::UpdateAccessible() 383 { 384 // We require a layout and an XModel to be accessible. 385 IDocumentLayoutAccess* pIDLA = GetShell()->getIDocumentLayoutAccess(); 386 Window *pWin = GetShell()->GetWin(); 387 ASSERT( GetShell()->GetLayout(), "no layout, no access" ); //swmod 071108//swmod 071225 388 ASSERT( pWin, "no window, no access" ); 389 390 if( IsAccessible() && pIDLA->GetCurrentViewShell() && pWin ) //swmod 071108//swmod 071225 391 GetAccessibleMap().GetDocumentView(); 392 } 393 394 void SwViewImp::DisposeAccessible( const SwFrm *pFrm, 395 const SdrObject *pObj, 396 sal_Bool bRecursive ) 397 { 398 ASSERT( !pFrm || pFrm->IsAccessibleFrm(), "frame is not accessible" ); 399 ViewShell *pVSh = GetShell(); 400 ViewShell *pTmp = pVSh; 401 do 402 { 403 if( pTmp->Imp()->IsAccessible() ) 404 pTmp->Imp()->GetAccessibleMap().Dispose( pFrm, pObj, 0, bRecursive ); 405 pTmp = (ViewShell *)pTmp->GetNext(); 406 } while ( pTmp != pVSh ); 407 } 408 409 void SwViewImp::MoveAccessible( const SwFrm *pFrm, const SdrObject *pObj, 410 const SwRect& rOldFrm ) 411 { 412 ASSERT( !pFrm || pFrm->IsAccessibleFrm(), "frame is not accessible" ); 413 ViewShell *pVSh = GetShell(); 414 ViewShell *pTmp = pVSh; 415 do 416 { 417 if( pTmp->Imp()->IsAccessible() ) 418 pTmp->Imp()->GetAccessibleMap().InvalidatePosOrSize( pFrm, pObj, 0, 419 rOldFrm ); 420 pTmp = (ViewShell *)pTmp->GetNext(); 421 } while ( pTmp != pVSh ); 422 } 423 424 void SwViewImp::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage) 425 { 426 if( IsAccessible() ) 427 GetAccessibleMap().FirePageChangeEvent( nOldPage, nNewPage); 428 } 429 430 void SwViewImp::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection) 431 { 432 if( IsAccessible() ) 433 GetAccessibleMap().FireSectionChangeEvent(nOldSection, nNewSection); 434 } 435 void SwViewImp::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn) 436 { 437 if( IsAccessible() ) 438 GetAccessibleMap().FireColumnChangeEvent(nOldColumn, nNewColumn); 439 } 440 void SwViewImp::InvalidateAccessibleFrmContent( const SwFrm *pFrm ) 441 { 442 ASSERT( pFrm->IsAccessibleFrm(), "frame is not accessible" ); 443 ViewShell *pVSh = GetShell(); 444 ViewShell *pTmp = pVSh; 445 do 446 { 447 if( pTmp->Imp()->IsAccessible() ) 448 pTmp->Imp()->GetAccessibleMap().InvalidateContent( pFrm ); 449 pTmp = (ViewShell *)pTmp->GetNext(); 450 } while ( pTmp != pVSh ); 451 } 452 453 void SwViewImp::InvalidateAccessibleCursorPosition( const SwFrm *pFrm ) 454 { 455 if( IsAccessible() ) 456 GetAccessibleMap().InvalidateCursorPosition( pFrm ); 457 } 458 459 void SwViewImp::InvalidateAccessibleEditableState( sal_Bool bAllShells, 460 const SwFrm *pFrm ) 461 { 462 if( bAllShells ) 463 { 464 ViewShell *pVSh = GetShell(); 465 ViewShell *pTmp = pVSh; 466 do 467 { 468 if( pTmp->Imp()->IsAccessible() ) 469 pTmp->Imp()->GetAccessibleMap().InvalidateStates( ACC_STATE_EDITABLE, pFrm ); 470 pTmp = (ViewShell *)pTmp->GetNext(); 471 } while ( pTmp != pVSh ); 472 } 473 else if( IsAccessible() ) 474 { 475 GetAccessibleMap().InvalidateStates( ACC_STATE_EDITABLE, pFrm ); 476 } 477 } 478 479 void SwViewImp::InvalidateAccessibleRelationSet( const SwFlyFrm *pMaster, 480 const SwFlyFrm *pFollow ) 481 { 482 ViewShell *pVSh = GetShell(); 483 ViewShell *pTmp = pVSh; 484 do 485 { 486 if( pTmp->Imp()->IsAccessible() ) 487 pTmp->Imp()->GetAccessibleMap().InvalidateRelationSet( pMaster, 488 pFollow ); 489 pTmp = (ViewShell *)pTmp->GetNext(); 490 } while ( pTmp != pVSh ); 491 } 492 493 /** invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs 494 495 OD 2005-12-01 #i27138# 496 497 @author OD 498 */ 499 void SwViewImp::_InvalidateAccessibleParaFlowRelation( const SwTxtFrm* _pFromTxtFrm, 500 const SwTxtFrm* _pToTxtFrm ) 501 { 502 if ( !_pFromTxtFrm && !_pToTxtFrm ) 503 { 504 // No text frame provided. Thus, nothing to do. 505 return; 506 } 507 508 ViewShell* pVSh = GetShell(); 509 ViewShell* pTmp = pVSh; 510 do 511 { 512 if ( pTmp->Imp()->IsAccessible() ) 513 { 514 if ( _pFromTxtFrm ) 515 { 516 pTmp->Imp()->GetAccessibleMap(). 517 InvalidateParaFlowRelation( *_pFromTxtFrm, true ); 518 } 519 if ( _pToTxtFrm ) 520 { 521 pTmp->Imp()->GetAccessibleMap(). 522 InvalidateParaFlowRelation( *_pToTxtFrm, false ); 523 } 524 } 525 pTmp = (ViewShell *)pTmp->GetNext(); 526 } while ( pTmp != pVSh ); 527 } 528 529 /** invalidate text selection for paragraphs 530 531 OD 2005-12-12 #i27301# 532 533 @author OD 534 */ 535 void SwViewImp::_InvalidateAccessibleParaTextSelection() 536 { 537 ViewShell* pVSh = GetShell(); 538 ViewShell* pTmp = pVSh; 539 do 540 { 541 if ( pTmp->Imp()->IsAccessible() ) 542 { 543 pTmp->Imp()->GetAccessibleMap().InvalidateTextSelectionOfAllParas(); 544 } 545 546 pTmp = (ViewShell *)pTmp->GetNext(); 547 } while ( pTmp != pVSh ); 548 } 549 550 /** invalidate attributes for paragraphs 551 552 OD 2009-01-06 #i88069# 553 554 @author OD 555 */ 556 void SwViewImp::_InvalidateAccessibleParaAttrs( const SwTxtFrm& rTxtFrm ) 557 { 558 ViewShell* pVSh = GetShell(); 559 ViewShell* pTmp = pVSh; 560 do 561 { 562 if ( pTmp->Imp()->IsAccessible() ) 563 { 564 pTmp->Imp()->GetAccessibleMap().InvalidateAttr( rTxtFrm ); 565 } 566 567 pTmp = (ViewShell *)pTmp->GetNext(); 568 } while ( pTmp != pVSh ); 569 } 570 571 // OD 15.01.2003 #103492# - method signature change due to new page preview functionality 572 void SwViewImp::UpdateAccessiblePreview( const std::vector<PrevwPage*>& _rPrevwPages, 573 const Fraction& _rScale, 574 const SwPageFrm* _pSelectedPageFrm, 575 const Size& _rPrevwWinSize ) 576 { 577 if( IsAccessible() ) 578 GetAccessibleMap().UpdatePreview( _rPrevwPages, _rScale, 579 _pSelectedPageFrm, _rPrevwWinSize ); 580 } 581 582 void SwViewImp::InvalidateAccessiblePreViewSelection( sal_uInt16 nSelPage ) 583 { 584 if( IsAccessible() ) 585 GetAccessibleMap().InvalidatePreViewSelection( nSelPage ); 586 } 587 588 SwAccessibleMap *SwViewImp::CreateAccessibleMap() 589 { 590 ASSERT( !pAccMap, "accessible map exists" ) 591 pAccMap = new SwAccessibleMap( GetShell() ); 592 return pAccMap; 593 } 594 595 void SwViewImp::FireAccessibleEvents() 596 { 597 if( IsAccessible() ) 598 GetAccessibleMap().FireEvents(); 599 } 600 601 IMPL_LINK(SwViewImp, SetStopPrt, void *, EMPTYARG) 602 { 603 bStopPrt = sal_True; 604 605 return 0; 606 } 607