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