xref: /trunk/main/sw/source/core/view/vnew.cxx (revision 3a7cf181c55416e69e525ddc0b38c22235ec1569)
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 <sfx2/printer.hxx>
33 #include <rtl/logfile.hxx>
34 #include <doc.hxx>
35 #include <IDocumentUndoRedo.hxx>
36 #include <docsh.hxx>
37 #include <viewsh.hxx>
38 #include <rootfrm.hxx>
39 #include <viewimp.hxx>
40 #include <viewopt.hxx>
41 #include <txtfrm.hxx>       // Zugriff auf TxtCache
42 #include <notxtfrm.hxx>
43 #include <fntcache.hxx>
44 #include <docufld.hxx>
45 #include <ptqueue.hxx>
46 #include <dview.hxx>        // SdrView
47 #include <ndgrf.hxx>
48 #include <ndindex.hxx>
49 #include <accessibilityoptions.hxx>
50 #include <switerator.hxx>
51 
52 /*************************************************************************
53 |*
54 |*  ViewShell::Init()
55 |*************************************************************************/
56 
57 void ViewShell::Init( const SwViewOption *pNewOpt )
58 {
59     RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722",  "ViewShell::Init" );
60 
61     bDocSizeChgd = sal_False;
62 
63     // Wir gehen auf Nummer sicher:
64     // Wir muessen die alten Fontinformationen wegschmeissen,
65     // wenn die Druckeraufloesung oder der Zoomfaktor sich aendert.
66     // Init() und Reformat() sind die sichersten Stellen.
67     pFntCache->Flush( );
68 
69     // ViewOptions werden dynamisch angelegt
70     if( !pOpt )
71     {
72         pOpt = new SwViewOption;
73 
74         // Ein ApplyViewOptions braucht nicht gerufen zu werden
75         if( pNewOpt )
76         {
77             *pOpt = *pNewOpt;
78             // Der Zoomfaktor muss eingestellt werden, weil in der CTOR-
79             // phase aus Performancegruenden kein ApplyViewOptions gerufen wird.
80             if( GetWin() && 100 != pOpt->GetZoom() )
81             {
82                 MapMode aMode( pWin->GetMapMode() );
83                 const Fraction aNewFactor( pOpt->GetZoom(), 100 );
84                 aMode.SetScaleX( aNewFactor );
85                 aMode.SetScaleY( aNewFactor );
86                 pWin->SetMapMode( aMode );
87             }
88         }
89     }
90 
91     SwDocShell* pDShell = pDoc->GetDocShell();
92     pDoc->set(IDocumentSettingAccess::HTML_MODE, 0 != ::GetHtmlMode( pDShell ) );
93 
94     // JP 02.02.99: Bug 61335 - Readonly-Flag an den ViewOptions setzen,
95     //              bevor das Layout angelegt wird. Ansonsten muesste man
96     //              nochmals durchformatieren!!
97     if( pDShell && pDShell->IsReadOnly() )
98         pOpt->SetReadonly( sal_True );
99 
100     RTL_LOGFILE_CONTEXT_TRACE( aLog, "View::Init - before InitPrt" );
101 
102     // --> FME 2007-11-06 #i82967#
103     OutputDevice* pPDFOut = 0;
104     if ( pOut && pOut->GetPDFWriter() )
105         pPDFOut = pOut;
106     // <--
107 
108     // --> FME 2005-01-21 #i41075#
109     // Only setup the printer if we need one:
110     const bool bBrowseMode = pOpt->getBrowseMode();
111     if( pPDFOut )
112         InitPrt( pPDFOut );
113     // <--
114 
115     // --> FME 2005-03-16 #i44963# Good occasion to check if page sizes in
116     // page descriptions are still set to (LONG_MAX, LONG_MAX) (html import)
117     if ( !bBrowseMode )
118     {
119         pDoc->CheckDefaultPageFmt();
120     }
121     // <--
122 
123     RTL_LOGFILE_CONTEXT_TRACE( aLog, "View::Init - after InitPrt" );
124 
125     if( GetWin() )
126     {
127         pOpt->Init( GetWin() );
128         GetWin()->SetFillColor();
129         GetWin()->SetBackground();
130         GetWin()->SetLineColor();
131     }
132 
133     // Create a new layout, if there is no one available
134     if( !pLayout )
135     {
136         // Here's the code which disables the usage of "multiple" layouts at the moment
137         // If the problems with controls and groups objects are solved,
138         // this code can be removed...
139         ViewShell *pCurrShell = GetDoc()->GetCurrentViewShell();
140         if( pCurrShell )
141             pLayout = pCurrShell->pLayout;
142         // end of "disable multiple layouts"
143         if( !pLayout )
144         {
145             // switched to two step construction because creating the layout in SwRootFrm needs a valid pLayout set
146             pLayout = SwRootFrmPtr(new SwRootFrm( pDoc->GetDfltFrmFmt(), this ));//swmod081016
147             pLayout->Init( pDoc->GetDfltFrmFmt() );
148 
149             // mba: the layout refactoring overlooked an important detail
150             // prior to that change, the layout always was destroyed in the dtor of swdoc
151             // it is necessary to suppress notifications in the layout when the layout is discarded in its dtor
152             // unfortunately this was done by asking whether the doc is in dtor - though the correct question should
153             // have been if the rootfrm is in dtor (or even better: discard the layout before the SwRootFrm is destroyed!)
154             // SwDoc::IsInDtor() is used at several places all over the code that need to be checked whether
155             // "pDoc->IsInDtor()" means what is says or in fact should check for "pRootFrm->IsInDtor()". As this will take some time, I decided
156             // to postpone that investigations and the changes it will bring to the 3.5 release and for 3.4 make sure
157             // that the layout still gets destroyed in the doc dtor. This is done by sharing "the" layout (that we still have) with the doc.
158             GetDoc()->ShareLayout( pLayout );
159         }
160     }
161     SizeChgNotify();    //swmod 071108
162 
163     // --> #i31958#
164     // XForms mode: initialize XForms mode, based on design mode (draw view)
165     //   MakeDrawView() requires layout
166     if( GetDoc()->isXForms() )
167     {
168         if( ! HasDrawView() )
169             MakeDrawView();
170         pOpt->SetFormView( ! GetDrawView()->IsDesignMode() );
171     }
172     // <-- #i31958#
173 }
174 
175 /*************************************************************************
176 |*
177 |*  ViewShell::ViewShell()  CTor fuer die erste Shell.
178 |*************************************************************************/
179 
180 ViewShell::ViewShell( SwDoc& rDocument, Window *pWindow,
181                         const SwViewOption *pNewOpt, OutputDevice *pOutput,
182                         long nFlags )
183     :
184     aBrowseBorder(),
185     pSfxViewShell( 0 ),
186     pImp( new SwViewImp( this ) ),
187     pWin( pWindow ),
188     pOut( pOutput ? pOutput
189                   : pWindow ? (OutputDevice*)pWindow
190                             : (OutputDevice*)rDocument.getPrinter( true )),
191     mpTmpRef( 0 ),
192     pOpt( 0 ),
193     pAccOptions( new SwAccessibilityOptions ),
194     mpTargetPaintWindow(0), // #i74769#
195     mpBufferedOut(0), // #i74769#
196     pDoc( &rDocument ),
197     nStartAction( 0 ),
198     nLockPaint( 0 ),
199     mnPrePostPaintCount(0L), // #i72754#
200     mpPrePostOutDev(0), // #i72754#
201     maPrePostMapMode()
202 {
203     RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722",  "ViewShell::SwViewShell" );
204 
205     // OD 2004-06-01 #i26791# - in order to suppress event handling in
206     // <SwDrawContact::Changed> during contruction of <ViewShell> instance
207     mbInConstructor = true;
208 
209     bPaintInProgress = bViewLocked = bInEndAction = bFrameView =
210     bEndActionByVirDev = sal_False;
211     bPaintWorks = bEnableSmooth = sal_True;
212     bPreView = 0 !=( VSHELLFLAG_ISPREVIEW & nFlags );
213 
214     // --> OD 2005-02-11 #i38810# - Do not reset modified state of document,
215     // if it's already been modified.
216     const bool bIsDocModified( pDoc->IsModified() );
217     // <--
218     pDoc->acquire();
219     pOutput = pOut;
220     Init( pNewOpt );    //verstellt ggf. das Outdev (InitPrt())
221     pOut = pOutput;
222 
223     // OD 28.03.2003 #108470# - initialize print preview layout after layout
224     // is created in <ViewShell::Init(..)> - called above.
225     if ( bPreView )
226     {
227         // OD 12.12.2002 #103492# - init page preview layout
228         pImp->InitPagePreviewLayout();
229     }
230 
231     SET_CURR_SHELL( this );
232 
233     ((SwHiddenTxtFieldType*)pDoc->GetSysFldType( RES_HIDDENTXTFLD ))->
234         SetHiddenFlag( !pOpt->IsShowHiddenField() );
235 
236     //In Init wird ein Standard-FrmFmt angelegt.
237     // --> OD 2005-02-11 #i38810#
238     if (   !pDoc->GetIDocumentUndoRedo().IsUndoNoResetModified()
239         && !bIsDocModified )
240     // <--
241     {
242         pDoc->ResetModified();
243     }
244 
245     //Format-Cache erweitern.
246     if ( SwTxtFrm::GetTxtCache()->GetCurMax() < 2550 )
247         SwTxtFrm::GetTxtCache()->IncreaseMax( 100 );
248     if( pOpt->IsGridVisible() || getIDocumentDrawModelAccess()->GetDrawModel() )
249         Imp()->MakeDrawView();
250 
251     // OD 2004-06-01 #i26791#
252     mbInConstructor = false;
253 }
254 
255 /*************************************************************************
256 |*
257 |*  ViewShell::ViewShell()  CTor fuer weitere Shells auf ein Dokument.
258 |*************************************************************************/
259 
260 ViewShell::ViewShell( ViewShell& rShell, Window *pWindow,
261                         OutputDevice *pOutput, long nFlags ) :
262     Ring( &rShell ),
263     aBrowseBorder( rShell.aBrowseBorder ),
264     pSfxViewShell( 0 ),
265     pImp( new SwViewImp( this ) ),
266     pWin( pWindow ),
267     pOut( pOutput ? pOutput
268                   : pWindow ? (OutputDevice*)pWindow
269                             : (OutputDevice*)rShell.GetDoc()->getPrinter( true )),
270     mpTmpRef( 0 ),
271     pOpt( 0 ),
272     pAccOptions( new SwAccessibilityOptions ),
273     mpTargetPaintWindow(0), // #i74769#
274     mpBufferedOut(0), // #i74769#
275     pDoc( rShell.GetDoc() ),
276     nStartAction( 0 ),
277     nLockPaint( 0 ),
278     mnPrePostPaintCount(0L), // #i72754#
279     mpPrePostOutDev(0), // #i72754#
280     maPrePostMapMode()
281 {
282     RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722",  "ViewShell::SwViewShell" );
283 
284     // OD 2004-06-01 #i26791# - in order to suppress event handling in
285     // <SwDrawContact::Changed> during contruction of <ViewShell> instance
286     mbInConstructor = true;
287 
288     bPaintWorks = bEnableSmooth = sal_True;
289     bPaintInProgress = bViewLocked = bInEndAction = bFrameView =
290     bEndActionByVirDev = sal_False;
291     bPreView = 0 !=( VSHELLFLAG_ISPREVIEW & nFlags );
292     if( nFlags & VSHELLFLAG_SHARELAYOUT ) //swmod 080125
293         pLayout = rShell.pLayout;//swmod 080125
294 
295     SET_CURR_SHELL( this );
296 
297     pDoc->acquire();
298     sal_Bool bModified = pDoc->IsModified();
299 
300     pOutput = pOut;
301     Init( rShell.GetViewOptions() );    //verstellt ggf. das Outdev (InitPrt())
302     pOut = pOutput;
303 
304     // OD 12.12.2002 #103492#
305     if ( bPreView )
306         pImp->InitPagePreviewLayout();
307 
308     ((SwHiddenTxtFieldType*)pDoc->GetSysFldType( RES_HIDDENTXTFLD ))->
309             SetHiddenFlag( !pOpt->IsShowHiddenField() );
310 
311     // in Init wird ein Standard-FrmFmt angelegt
312     if( !bModified && !pDoc->GetIDocumentUndoRedo().IsUndoNoResetModified() )
313     {
314         pDoc->ResetModified();
315     }
316 
317     //Format-Cache erweitern.
318     if ( SwTxtFrm::GetTxtCache()->GetCurMax() < 2550 )
319         SwTxtFrm::GetTxtCache()->IncreaseMax( 100 );
320     if( pOpt->IsGridVisible() || getIDocumentDrawModelAccess()->GetDrawModel() )
321         Imp()->MakeDrawView();
322 
323     // OD 2004-06-01 #i26791#
324     mbInConstructor = false;
325 
326 }
327 
328 /******************************************************************************
329 |*
330 |*  ViewShell::~ViewShell()
331 |*
332 ******************************************************************************/
333 
334 ViewShell::~ViewShell()
335 {
336     {
337         SET_CURR_SHELL( this );
338         bPaintWorks = sal_False;
339 
340         // FME 2004-06-21 #i9684# Stopping the animated graphics is not
341         // necessary during printing or pdf export, because the animation
342         // has not been started in this case.
343         if( pDoc && GetWin() )
344         {
345             SwNodes& rNds = pDoc->GetNodes();
346             SwGrfNode *pGNd;
347 
348             SwStartNode *pStNd;
349             SwNodeIndex aIdx( *rNds.GetEndOfAutotext().StartOfSectionNode(), 1 );
350             while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
351             {
352                 aIdx++;
353                 if ( 0 != ( pGNd = aIdx.GetNode().GetGrfNode() ) )
354                 {
355                     if( pGNd->IsAnimated() )
356                     {
357                         SwIterator<SwFrm,SwGrfNode> aIter( *pGNd );
358                         for( SwFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
359                         {
360                             ASSERT( pFrm->IsNoTxtFrm(), "GraphicNode with Text?" );
361                             ((SwNoTxtFrm*)pFrm)->StopAnimation( pOut );
362                         }
363                     }
364                 }
365                 aIdx.Assign( *pStNd->EndOfSectionNode(), +1 );
366             }
367 
368             GetDoc()->StopNumRuleAnimations( pOut );
369         }
370 
371         delete pImp; //Erst loeschen, damit die LayoutViews vernichtet werden.
372         pImp = 0;   // Set to zero, because ~SwFrm relies on it.
373 
374         if ( pDoc )
375         {
376             if( !pDoc->release() )
377                 delete pDoc, pDoc = 0;
378             else
379                 GetLayout()->ResetNewLayout();
380         }//swmod 080317
381 
382         delete pOpt;
383 
384         //Format-Cache zurueckschrauben.
385         if ( SwTxtFrm::GetTxtCache()->GetCurMax() > 250 )
386             SwTxtFrm::GetTxtCache()->DecreaseMax( 100 );
387 
388         //Ggf. aus der PaintQueue entfernen lassen
389         SwPaintQueue::Remove( this );
390 
391         ASSERT( !nStartAction, "EndAction() pending." );
392     }
393 
394     if ( pDoc )
395     {
396         GetLayout()->DeRegisterShell( this );
397         if(pDoc->GetCurrentViewShell()==this)
398             pDoc->SetCurrentViewShell( this->GetNext()!=this ?
399             (ViewShell*)this->GetNext() : NULL );
400     }
401 
402     delete mpTmpRef;
403     delete pAccOptions;
404 }
405 
406 sal_Bool ViewShell::HasDrawView() const
407 {
408     return Imp() ? Imp()->HasDrawView() : 0;
409 }
410 
411 void ViewShell::MakeDrawView()
412 {
413     Imp()->MakeDrawView( );
414 }
415 
416 SdrView* ViewShell::GetDrawView()
417 {
418     return Imp()->GetDrawView();
419 }
420 
421 SdrView* ViewShell::GetDrawViewWithValidMarkList()
422 {
423     SwDrawView* pDView = Imp()->GetDrawView();
424     pDView->ValidateMarkList();
425     return pDView;
426 }
427