xref: /AOO41X/main/sw/source/core/view/viewimp.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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