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