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