xref: /trunk/main/sw/source/core/view/viewimp.cxx (revision 31bbceb0f9d64c0c2c3b22a794a1666c1f33396e)
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