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