xref: /trunk/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