xref: /trunk/main/sw/source/core/view/vprint.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 <com/sun/star/uno/Sequence.hxx>
33 #include <com/sun/star/uno/Any.hxx>
34 #include <com/sun/star/uno/Any.hxx>
35 #include <com/sun/star/view/XRenderable.hpp>
36 
37 #include <hintids.hxx>
38 #include <rtl/ustring.hxx>
39 #include <sfx2/app.hxx>
40 #include <sfx2/objsh.hxx>
41 #include <sfx2/prnmon.hxx>
42 #include <svl/languageoptions.hxx>
43 #include <editeng/paperinf.hxx>
44 #include <editeng/pbinitem.hxx>
45 #include <svx/svdview.hxx>
46 #include <toolkit/awt/vclxdevice.hxx>
47 #include <tools/debug.hxx>
48 #include <unotools/localedatawrapper.hxx>
49 #include <unotools/moduleoptions.hxx>
50 #include <unotools/syslocale.hxx>
51 #include <vcl/oldprintadaptor.hxx>
52 
53 #include <unotxdoc.hxx>
54 #include <docsh.hxx>
55 #include <txtfld.hxx>
56 #include <fmtfld.hxx>
57 #include <fmtfsize.hxx>
58 #include <frmatr.hxx>
59 #include <rootfrm.hxx>
60 #include <pagefrm.hxx>
61 #include <cntfrm.hxx>
62 #include <doc.hxx>
63 #include <IDocumentUndoRedo.hxx>
64 #include <wdocsh.hxx>
65 #include <fesh.hxx>
66 #include <pam.hxx>
67 #include <viewimp.hxx>      // Imp->SetFirstVisPageInvalid()
68 #include <layact.hxx>
69 #include <ndtxt.hxx>
70 #include <fldbas.hxx>
71 #include <docfld.hxx>       // _SetGetExpFld
72 #include <docufld.hxx>      // PostItFld /-Type
73 #include <shellres.hxx>
74 #include <viewopt.hxx>
75 #include <printdata.hxx>    // SwPrintData
76 #include <pagedesc.hxx>
77 #include <poolfmt.hxx>      // fuer RES_POOLPAGE_JAKET
78 #include <mdiexp.hxx>       // Ansteuern der Statusleiste
79 #include <statstr.hrc>      //      -- " --
80 #include <ptqueue.hxx>
81 #include <tabfrm.hxx>
82 #include <txtfrm.hxx>       // MinPrtLine
83 #include <viscrs.hxx>       // SwShellCrsr
84 #include <fmtpdsc.hxx>      // SwFmtPageDesc
85 #include <globals.hrc>
86 
87 
88 using namespace ::com::sun::star;
89 
90 //--------------------------------------------------------------------
91 //Klasse zum Puffern von Paints
92 class SwQueuedPaint
93 {
94 public:
95     SwQueuedPaint *pNext;
96     ViewShell      *pSh;
97     SwRect          aRect;
98 
99     SwQueuedPaint( ViewShell *pNew, const SwRect &rRect ) :
100         pNext( 0 ),
101         pSh( pNew ),
102         aRect( rRect )
103     {}
104 };
105 
106 SwQueuedPaint *SwPaintQueue::pQueue = 0;
107 
108 // saves some settings from the draw view
109 class SwDrawViewSave
110 {
111     String sLayerNm;
112     SdrView* pDV;
113     sal_Bool bPrintControls;
114 public:
115     SwDrawViewSave( SdrView* pSdrView );
116     ~SwDrawViewSave();
117 };
118 
119 
120 void SwPaintQueue::Add( ViewShell *pNew, const SwRect &rNew )
121 {
122     SwQueuedPaint *pPt;
123     if ( 0 != (pPt = pQueue) )
124     {
125         while ( pPt->pSh != pNew && pPt->pNext )
126             pPt = pPt->pNext;
127         if ( pPt->pSh == pNew )
128         {
129             pPt->aRect.Union( rNew );
130             return;
131         }
132     }
133     SwQueuedPaint *pNQ = new SwQueuedPaint( pNew, rNew );
134     if ( pPt )
135         pPt->pNext = pNQ;
136     else
137         pQueue = pNQ;
138 }
139 
140 
141 
142 void SwPaintQueue::Repaint()
143 {
144     if ( !SwRootFrm::IsInPaint() && pQueue )
145     {
146         SwQueuedPaint *pPt = pQueue;
147         do
148         {   ViewShell *pSh = pPt->pSh;
149             SET_CURR_SHELL( pSh );
150             if ( pSh->IsPreView() )
151             {
152                 if ( pSh->GetWin() )
153                 {
154                     //Fuer PreView aussenherum, weil im PaintHdl (UI) die
155                     //Zeilen/Spalten bekannt sind.
156                     pSh->GetWin()->Invalidate();
157                     pSh->GetWin()->Update();
158                 }
159             }
160             else
161                 pSh->Paint( pPt->aRect.SVRect() );
162             pPt = pPt->pNext;
163         } while ( pPt );
164 
165         do
166         {   pPt = pQueue;
167             pQueue = pQueue->pNext;
168             delete pPt;
169         } while ( pQueue );
170     }
171 }
172 
173 
174 
175 void SwPaintQueue::Remove( ViewShell *pSh )
176 {
177     SwQueuedPaint *pPt;
178     if ( 0 != (pPt = pQueue) )
179     {
180         SwQueuedPaint *pPrev = 0;
181         while ( pPt && pPt->pSh != pSh )
182         {
183             pPrev = pPt;
184             pPt = pPt->pNext;
185         }
186         if ( pPt )
187         {
188             if ( pPrev )
189                 pPrev->pNext = pPt->pNext;
190             else if ( pPt == pQueue )
191                 pQueue = 0;
192             delete pPt;
193         }
194     }
195 }
196 
197 /******************************************************************************
198  *  Methode     :   void SetSwVisArea( ViewShell *pSh, Point aPrtOffset, ...
199  *  Beschreibung:
200  *  Erstellt    :   OK 04.11.94 16:27
201  *  Aenderung   :
202  ******************************************************************************/
203 
204 void SetSwVisArea( ViewShell *pSh, const SwRect &rRect, sal_Bool /*bPDFExport*/ )
205 {
206     ASSERT( !pSh->GetWin(), "Drucken mit Window?" );
207     pSh->aVisArea = rRect;
208     pSh->Imp()->SetFirstVisPageInvalid();
209     Point aPt( rRect.Pos() );
210 
211     // calculate an offset for the rectangle of the n-th page to
212     // move the start point of the output operation to a position
213     // such that in the output device all pages will be painted
214     // at the same position
215     aPt.X() = -aPt.X(); aPt.Y() = -aPt.Y();
216 
217     OutputDevice *pOut = pSh->GetOut();
218 
219     MapMode aMapMode( pOut->GetMapMode() );
220     aMapMode.SetOrigin( aPt );
221     pOut->SetMapMode( aMapMode );
222 }
223 
224 /******************************************************************************/
225 
226 void ViewShell::InitPrt( OutputDevice *pOutDev )
227 {
228     //Fuer den Printer merken wir uns einen negativen Offset, der
229     //genau dem Offset de OutputSize entspricht. Das ist notwendig,
230     //weil unser Ursprung der linken ober Ecke der physikalischen
231     //Seite ist, die Ausgaben (SV) aber den Outputoffset als Urstprung
232     //betrachten.
233     if ( pOutDev )
234     {
235         aPrtOffst = Point();
236 
237         aPrtOffst += pOutDev->GetMapMode().GetOrigin();
238         MapMode aMapMode( pOutDev->GetMapMode() );
239         aMapMode.SetMapUnit( MAP_TWIP );
240         pOutDev->SetMapMode( aMapMode );
241         pOutDev->SetLineColor();
242         pOutDev->SetFillColor();
243     }
244     else
245         aPrtOffst.X() = aPrtOffst.Y() = 0;
246 
247     if ( !pWin )
248         pOut = pOutDev;    //Oder was sonst?
249 }
250 
251 /******************************************************************************
252  *  Methode     :   void ViewShell::ChgAllPageOrientation
253  *  Erstellt    :   MA 08. Aug. 95
254  *  Aenderung   :
255  ******************************************************************************/
256 
257 
258 void ViewShell::ChgAllPageOrientation( sal_uInt16 eOri )
259 {
260     ASSERT( nStartAction, "missing an Action" );
261     SET_CURR_SHELL( this );
262 
263     sal_uInt16 nAll = GetDoc()->GetPageDescCnt();
264     sal_Bool bNewOri = Orientation(eOri) == ORIENTATION_PORTRAIT ? sal_False : sal_True;
265 
266     for( sal_uInt16 i = 0; i < nAll; ++ i )
267     {
268         const SwPageDesc& rOld =
269             const_cast<const SwDoc *>(GetDoc())->GetPageDesc( i );
270 
271         if( rOld.GetLandscape() != bNewOri )
272         {
273             SwPageDesc aNew( rOld );
274             {
275                 ::sw::UndoGuard const ug(GetDoc()->GetIDocumentUndoRedo());
276                 GetDoc()->CopyPageDesc(rOld, aNew);
277             }
278             aNew.SetLandscape( bNewOri );
279             SwFrmFmt& rFmt = aNew.GetMaster();
280             SwFmtFrmSize aSz( rFmt.GetFrmSize() );
281             // Groesse anpassen.
282             // PORTRAIT  -> Hoeher als Breit
283             // LANDSCAPE -> Breiter als Hoch
284             // Hoehe ist die VarSize, Breite ist die FixSize (per Def.)
285             if( bNewOri ? aSz.GetHeight() > aSz.GetWidth()
286                         : aSz.GetHeight() < aSz.GetWidth() )
287             {
288                 SwTwips aTmp = aSz.GetHeight();
289                 aSz.SetHeight( aSz.GetWidth() );
290                 aSz.SetWidth( aTmp );
291                 rFmt.SetFmtAttr( aSz );
292             }
293             GetDoc()->ChgPageDesc( i, aNew );
294         }
295     }
296 }
297 
298 /******************************************************************************
299  *  Methode     :   void ViewShell::ChgAllPageOrientation
300  *  Erstellt    :   MA 08. Aug. 95
301  *  Aenderung   :
302  ******************************************************************************/
303 
304 
305 void ViewShell::ChgAllPageSize( Size &rSz )
306 {
307     ASSERT( nStartAction, "missing an Action" );
308     SET_CURR_SHELL( this );
309 
310     SwDoc* pMyDoc = GetDoc();
311     sal_uInt16 nAll = pMyDoc->GetPageDescCnt();
312 
313     for( sal_uInt16 i = 0; i < nAll; ++i )
314     {
315         const SwPageDesc &rOld = const_cast<const SwDoc *>(pMyDoc)->GetPageDesc( i );
316         SwPageDesc aNew( rOld );
317         {
318             ::sw::UndoGuard const ug(GetDoc()->GetIDocumentUndoRedo());
319             GetDoc()->CopyPageDesc( rOld, aNew );
320         }
321         SwFrmFmt& rPgFmt = aNew.GetMaster();
322         Size aSz( rSz );
323         const sal_Bool bOri = aNew.GetLandscape();
324         if( bOri  ? aSz.Height() > aSz.Width()
325                   : aSz.Height() < aSz.Width() )
326         {
327             SwTwips aTmp = aSz.Height();
328             aSz.Height() = aSz.Width();
329             aSz.Width()  = aTmp;
330         }
331 
332         SwFmtFrmSize aFrmSz( rPgFmt.GetFrmSize() );
333         aFrmSz.SetSize( aSz );
334         rPgFmt.SetFmtAttr( aFrmSz );
335         pMyDoc->ChgPageDesc( i, aNew );
336     }
337 }
338 
339 
340 void ViewShell::CalcPagesForPrint( sal_uInt16 nMax )
341 {
342     SET_CURR_SHELL( this );
343 
344     SwRootFrm* pMyLayout = GetLayout();
345 
346     const SwFrm *pPage = pMyLayout->Lower();
347     SwLayAction aAction( pMyLayout, Imp() );
348 
349     pMyLayout->StartAllAction();
350     for ( sal_uInt16 i = 1; pPage && i <= nMax; pPage = pPage->GetNext(), ++i )
351     {
352         pPage->Calc();
353         SwRect aOldVis( VisArea() );
354         aVisArea = pPage->Frm();
355         Imp()->SetFirstVisPageInvalid();
356         aAction.Reset();
357         aAction.SetPaint( sal_False );
358         aAction.SetWaitAllowed( sal_False );
359         aAction.SetReschedule( sal_True );
360 
361         aAction.Action();
362 
363         aVisArea = aOldVis;             //Zuruecksetzen wg. der Paints!
364         Imp()->SetFirstVisPageInvalid();
365 //       SwPaintQueue::Repaint();
366     }
367 
368     pMyLayout->EndAllAction();
369 }
370 
371 /******************************************************************************/
372 
373 SwDoc * ViewShell::FillPrtDoc( SwDoc *pPrtDoc, const SfxPrinter* pPrt)
374 {
375     ASSERT( this->IsA( TYPE(SwFEShell) ),"ViewShell::Prt for FEShell only");
376     SwFEShell* pFESh = (SwFEShell*)this;
377     // Wir bauen uns ein neues Dokument
378 //    SwDoc *pPrtDoc = new SwDoc;
379 //    pPrtDoc->acquire();
380 //    pPrtDoc->SetRefForDocShell( (SvEmbeddedObjectRef*)&(long&)rDocShellRef );
381     pPrtDoc->LockExpFlds();
382 
383     // Der Drucker wird uebernommen
384     //! Make a copy of it since it gets destroyed with the temporary document
385     //! used for PDF export
386     if (pPrt)
387         pPrtDoc->setPrinter( new SfxPrinter(*pPrt), true, true );
388 
389     const SfxPoolItem* pCpyItem;
390     const SfxItemPool& rPool = GetAttrPool();
391     for( sal_uInt16 nWh = POOLATTR_BEGIN; nWh < POOLATTR_END; ++nWh )
392         if( 0 != ( pCpyItem = rPool.GetPoolDefaultItem( nWh ) ) )
393             pPrtDoc->GetAttrPool().SetPoolDefaultItem( *pCpyItem );
394 
395     // JP 29.07.99 - Bug 67951 - set all Styles from the SourceDoc into
396     //                              the PrintDoc - will be replaced!
397     pPrtDoc->ReplaceStyles( *GetDoc() );
398 
399     SwShellCrsr *pActCrsr = pFESh->_GetCrsr();
400     SwShellCrsr *pFirstCrsr = dynamic_cast<SwShellCrsr*>(pActCrsr->GetNext());
401     if( !pActCrsr->HasMark() ) // bei Multiselektion kann der aktuelle Cursor leer sein
402     {
403         pActCrsr = dynamic_cast<SwShellCrsr*>(pActCrsr->GetPrev());
404     }
405 
406     // Die Y-Position der ersten Selektion
407     // Die Y-Position der ersten Selektion
408     Point aSelPoint;
409     if( pFESh->IsTableMode() )
410     {
411         SwShellTableCrsr* pShellTblCrsr = pFESh->GetTableCrsr();
412 
413         const SwCntntNode* pCntntNode = pShellTblCrsr->GetNode()->GetCntntNode();
414         const SwCntntFrm *pCntntFrm = pCntntNode ? pCntntNode->getLayoutFrm( GetLayout(), 0, pShellTblCrsr->Start() ) : 0;
415         if( pCntntFrm )
416         {
417             SwRect aCharRect;
418             SwCrsrMoveState aTmpState( MV_NONE );
419             pCntntFrm->GetCharRect( aCharRect, *pShellTblCrsr->Start(), &aTmpState );
420             aSelPoint = Point( aCharRect.Left(), aCharRect.Top() );
421         }
422     }
423     else
424     {
425        aSelPoint = pFirstCrsr->GetSttPos();
426     }
427 
428     const SwPageFrm* pPage = GetLayout()->GetPageAtPos( aSelPoint );
429     ASSERT( pPage, "no page found!" );
430 
431     // get page descriptor - fall back to the first one if pPage could not be found
432     const SwPageDesc* pPageDesc = pPage ? pPrtDoc->FindPageDescByName(
433         pPage->GetPageDesc()->GetName() ) : &pPrtDoc->_GetPageDesc( (sal_uInt16)0 );
434 
435     if( !pFESh->IsTableMode() && pActCrsr->HasMark() )
436     {   // Am letzten Absatz die Absatzattribute richten:
437         SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
438         SwTxtNode* pTxtNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx )->GetTxtNode();
439         SwCntntNode *pLastNd =
440             pActCrsr->GetCntntNode( (*pActCrsr->GetMark()) <= (*pActCrsr->GetPoint()) );
441         // Hier werden die Absatzattribute des ersten Absatzes uebertragen
442         if( pLastNd && pLastNd->IsTxtNode() )
443             ((SwTxtNode*)pLastNd)->CopyCollFmt( *pTxtNd );
444     }
445 
446     // es wurde in der CORE eine neu angelegt (OLE-Objekte kopiert!)
447 //REMOVE    //      if( aDocShellRef.Is() )
448 //REMOVE    //          SwDataExchange::InitOle( aDocShellRef, pPrtDoc );
449     // und fuellen es mit dem selektierten Bereich
450     pFESh->Copy( pPrtDoc );
451 
452     //Jetzt noch am ersten Absatz die Seitenvorlage setzen
453     {
454         SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
455         SwCntntNode* pCNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx ); // gehe zum 1. ContentNode
456         if( pFESh->IsTableMode() )
457         {
458             SwTableNode* pTNd = pCNd->FindTableNode();
459             if( pTNd )
460                 pTNd->GetTable().GetFrmFmt()->SetFmtAttr( SwFmtPageDesc( pPageDesc ) );
461         }
462         else
463         {
464             pCNd->SetAttr( SwFmtPageDesc( pPageDesc ) );
465             if( pFirstCrsr->HasMark() )
466             {
467                 SwTxtNode *pTxtNd = pCNd->GetTxtNode();
468                 if( pTxtNd )
469                 {
470                     SwCntntNode *pFirstNd =
471                         pFirstCrsr->GetCntntNode( (*pFirstCrsr->GetMark()) > (*pFirstCrsr->GetPoint()) );
472                     // Hier werden die Absatzattribute des ersten Absatzes uebertragen
473                     if( pFirstNd && pFirstNd->IsTxtNode() )
474                         ((SwTxtNode*)pFirstNd)->CopyCollFmt( *pTxtNd );
475                 }
476             }
477         }
478     }
479     return pPrtDoc;
480 }
481 
482 
483 sal_Bool ViewShell::PrintOrPDFExport(
484     OutputDevice *pOutDev,
485     SwPrintData const& rPrintData,
486     sal_Int32 nRenderer     /* the index in the vector of pages to be printed */ )
487 {
488 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
489 //Immer die Druckroutinen in viewpg.cxx (PrintProspect) mitpflegen!!
490 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
491 
492     const sal_Int32 nMaxRenderer = rPrintData.GetRenderData().GetPagesToPrint().size() - 1;
493 #if OSL_DEBUG_LEVEL > 1
494     DBG_ASSERT( 0 <= nRenderer && nRenderer <= nMaxRenderer, "nRenderer out of bounds");
495 #endif
496     if (!pOutDev || nMaxRenderer < 0 || nRenderer < 0 || nRenderer > nMaxRenderer)
497         return sal_False;
498 
499     // save settings of OutputDevice (should be done always since the
500     // output device is now provided by a call from outside the Writer)
501     pOutDev->Push();
502 
503     // eine neue Shell fuer den Printer erzeugen
504     ViewShell *pShell;
505     SwDoc *pOutDevDoc;
506 
507     // Print/PDF export for (multi-)selection has already generated a
508     // temporary document with the selected text.
509     // (see XRenderable implementation in unotxdoc.cxx)
510     // It is implemented this way because PDF export calls this Prt function
511     // once per page and we do not like to always have the temporary document
512     // to be created that often here.
513     pOutDevDoc = GetDoc();
514     pShell = new ViewShell( *this, 0, pOutDev );
515 
516     SdrView *pDrawView = pShell->GetDrawView();
517     if (pDrawView)
518     {
519         pDrawView->SetBufferedOutputAllowed( false );
520         pDrawView->SetBufferedOverlayAllowed( false );
521     }
522 
523     {   //Zusaetzlicher Scope, damit die CurrShell vor dem zerstoeren der
524         //Shell zurueckgesetzt wird.
525 
526         SET_CURR_SHELL( pShell );
527 
528         //JP 01.02.99: das ReadOnly Flag wird NIE mitkopiert; Bug 61335
529         if( pOpt->IsReadonly() )
530             pShell->pOpt->SetReadonly( sal_True );
531 
532         // save options at draw view:
533         SwDrawViewSave aDrawViewSave( pShell->GetDrawView() );
534 
535         pShell->PrepareForPrint( rPrintData );
536 
537         const sal_Int32 nPage = rPrintData.GetRenderData().GetPagesToPrint()[ nRenderer ];
538 #if OSL_DEBUG_LEVEL > 1
539         DBG_ASSERT( nPage == 0 || rPrintData.GetRenderData().GetValidPagesSet().count( nPage ) == 1, "nPage not valid" );
540 #endif
541         const SwPageFrm *pStPage = 0;
542         if (nPage > 0)  // a 'regular' page, not one from the post-it document
543         {
544             const SwRenderData::ValidStartFramesMap_t &rFrms = rPrintData.GetRenderData().GetValidStartFrames();
545             SwRenderData::ValidStartFramesMap_t::const_iterator aIt( rFrms.find( nPage ) );
546             DBG_ASSERT( aIt != rFrms.end(), "failed to find start frame" );
547             if (aIt == rFrms.end())
548                 return sal_False;
549             pStPage = aIt->second;
550         }
551         else    // a page from the post-its document ...
552         {
553             DBG_ASSERT( nPage == 0, "unexpected page number. 0 for post-it pages expected" );
554             pStPage = rPrintData.GetRenderData().GetPostItStartFrames()[ nRenderer ];
555         }
556         DBG_ASSERT( pStPage, "failed to get start page" );
557 
558         //!! applying view options and formatting the dcoument should now only be done in getRendererCount!
559 
560         ViewShell *pViewSh2 = nPage == 0 ? /* post-it page? */
561                 rPrintData.GetRenderData().m_pPostItShell : pShell;
562         ::SetSwVisArea( pViewSh2, pStPage->Frm() );
563 
564 // FIXME disabled because rPrintData.aOffset is always (0,0)
565 #if 0
566         //  wenn wir einen Umschlag drucken wird ein Offset beachtet
567         if( pStPage->GetFmt()->GetPoolFmtId() == RES_POOLPAGE_JAKET )
568         {
569             Point aNewOrigin = pOutDev->GetMapMode().GetOrigin();
570             aNewOrigin += rPrintData.aOffset;
571             MapMode aTmp( pOutDev->GetMapMode() );
572             aTmp.SetOrigin( aNewOrigin );
573             pOutDev->SetMapMode( aTmp );
574         }
575 #endif
576 
577         pShell->InitPrt( pOutDev );
578 
579         pViewSh2 = nPage == 0 ? /* post-it page? */
580                 rPrintData.GetRenderData().m_pPostItShell : pShell;
581         ::SetSwVisArea( pViewSh2, pStPage->Frm() );
582 
583         pStPage->GetUpper()->Paint( pStPage->Frm(), &rPrintData );
584 
585         SwPaintQueue::Repaint();
586     }  //Zus. Scope wg. CurShell!
587 
588     delete pShell;
589 
590     // restore settings of OutputDevice (should be done always now since the
591     // output device is now provided by a call from outside the Writer)
592     pOutDev->Pop();
593 
594     return sal_True;
595 }
596 
597 /******************************************************************************
598  *  Methode     :   PrtOle2()
599  *  Beschreibung:
600  *  Erstellt    :   PK 07.12.94
601  *  Aenderung   :   MA 16. Feb. 95
602  ******************************************************************************/
603 
604 
605 
606 void ViewShell::PrtOle2( SwDoc *pDoc, const SwViewOption *pOpt, const SwPrintData& rOptions,
607                          OutputDevice* pOleOut, const Rectangle& rRect )
608 {
609   //Wir brauchen eine Shell fuer das Drucken. Entweder hat das Doc schon
610     //eine, dann legen wir uns eine neue Sicht an, oder das Doc hat noch
611     //keine, dann erzeugen wir die erste Sicht.
612     ViewShell *pSh;
613     if( pDoc->GetCurrentViewShell() )
614         pSh = new ViewShell( *pDoc->GetCurrentViewShell(), 0, pOleOut,VSHELLFLAG_SHARELAYOUT );//swmod 080129
615     else    //swmod 071108//swmod 071225
616         pSh = new ViewShell( *pDoc, 0, pOpt, pOleOut);//swmod 080129
617 
618     {
619         SET_CURR_SHELL( pSh );
620         pSh->PrepareForPrint( rOptions );
621         pSh->SetPrtFormatOption( sal_True );
622 
623         SwRect aSwRect( rRect );
624         pSh->aVisArea = aSwRect;
625 
626         if ( pSh->GetViewOptions()->getBrowseMode() &&
627              pSh->GetNext() == pSh )
628         {
629             pSh->CheckBrowseView( sal_False );
630             pSh->GetLayout()->Lower()->InvalidateSize();
631         }
632 
633         // --> FME 2005-02-10 #119474#
634         // CalcPagesForPrint() should not be necessary here. The pages in the
635         // visible area will be formatted in SwRootFrm::Paint().
636         // Removing this gives us a performance gain during saving the
637         // document because the thumbnail creation will not trigger a complete
638         // formatting of the document.
639         // Seiten fuers Drucken formatieren
640         // pSh->CalcPagesForPrint( SHRT_MAX );
641         // <--
642 
643         //#39275# jetzt will der Meyer doch ein Clipping
644         pOleOut->Push( PUSH_CLIPREGION );
645         pOleOut->IntersectClipRegion( aSwRect.SVRect() );
646         pSh->GetLayout()->Paint( aSwRect );
647 //      SFX_APP()->SpoilDemoOutput( *pOleOut, rRect );
648         pOleOut->Pop();
649 
650         // erst muss das CurrShell Object zerstoert werden!!
651     }
652     delete pSh;
653 }
654 
655 /******************************************************************************
656  *  Methode     :   IsAnyFieldInDoc()
657  *  Beschreibung:   Stellt fest, ob im DocNodesArray Felder verankert sind
658  *  Erstellt    :   JP 27.07.95
659  *  Aenderung   :   JP 10.12.97
660  ******************************************************************************/
661 
662 
663 
664 sal_Bool ViewShell::IsAnyFieldInDoc() const
665 {
666     const SfxPoolItem* pItem;
667     sal_uInt32 nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
668     for( sal_uInt32 n = 0; n < nMaxItems; ++n )
669         if( 0 != (pItem = pDoc->GetAttrPool().GetItem2( RES_TXTATR_FIELD, n )))
670         {
671             const SwFmtFld* pFmtFld = (SwFmtFld*)pItem;
672             const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
673             //#i101026# mod: do not include postits in field check
674             const SwField* pFld = pFmtFld->GetFld();
675             if( pTxtFld && pTxtFld->GetTxtNode().GetNodes().IsDocNodes() && (pFld->Which() != RES_POSTITFLD))
676                 return sal_True;
677         }
678     return sal_False;
679 }
680 
681 
682 
683 /******************************************************************************
684  *  SwDrawViewSave
685  *
686  *  Saves some settings at the draw view
687  ******************************************************************************/
688 
689 SwDrawViewSave::SwDrawViewSave( SdrView* pSdrView )
690     : pDV( pSdrView )
691 {
692     if ( pDV )
693     {
694         sLayerNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM("Controls" ) );
695         bPrintControls = pDV->IsLayerPrintable( sLayerNm );
696     }
697 }
698 
699 SwDrawViewSave::~SwDrawViewSave()
700 {
701     if ( pDV )
702     {
703         pDV->SetLayerPrintable( sLayerNm, bPrintControls );
704     }
705 }
706 
707 
708 // OD 09.01.2003 #i6467# - method also called for page preview
709 void ViewShell::PrepareForPrint( const SwPrintData &rOptions )
710 {
711     // Viewoptions fuer den Drucker setzen
712     pOpt->SetGraphic ( sal_True == rOptions.bPrintGraphic );
713     pOpt->SetTable   ( sal_True == rOptions.bPrintTable );
714     pOpt->SetDraw    ( sal_True == rOptions.bPrintDraw  );
715     pOpt->SetControl ( sal_True == rOptions.bPrintControl );
716     pOpt->SetPageBack( sal_True == rOptions.bPrintPageBackground );
717     pOpt->SetBlackFont( sal_True == rOptions.bPrintBlackFont );
718 
719     if ( HasDrawView() )
720     {
721         SdrView *pDrawView = GetDrawView();
722         String sLayerNm;
723         sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" ));
724         // OD 09.01.2003 #i6467# - consider, if view shell belongs to page preview
725         if ( !IsPreView() )
726         {
727             pDrawView->SetLayerPrintable( sLayerNm, rOptions.bPrintControl );
728         }
729         else
730         {
731             pDrawView->SetLayerVisible( sLayerNm, rOptions.bPrintControl );
732         }
733     }
734 }
735 
736