Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/uno/Sequence.hxx>
21 : #include <com/sun/star/uno/Any.hxx>
22 : #include <com/sun/star/view/XRenderable.hpp>
23 :
24 : #include <hintids.hxx>
25 : #include <sfx2/app.hxx>
26 : #include <sfx2/objsh.hxx>
27 : #include <sfx2/prnmon.hxx>
28 : #include <svl/languageoptions.hxx>
29 : #include <editeng/paperinf.hxx>
30 : #include <editeng/pbinitem.hxx>
31 : #include <svx/svdview.hxx>
32 : #include <toolkit/awt/vclxdevice.hxx>
33 : #include <unotools/localedatawrapper.hxx>
34 : #include <unotools/moduleoptions.hxx>
35 : #include <unotools/syslocale.hxx>
36 : #include <vcl/oldprintadaptor.hxx>
37 :
38 : #include <unotxdoc.hxx>
39 : #include <docsh.hxx>
40 : #include <txtfld.hxx>
41 : #include <fmtfld.hxx>
42 : #include <fmtfsize.hxx>
43 : #include <frmatr.hxx>
44 : #include <rootfrm.hxx>
45 : #include <pagefrm.hxx>
46 : #include <cntfrm.hxx>
47 : #include <doc.hxx>
48 : #include <IDocumentUndoRedo.hxx>
49 : #include <IDocumentDeviceAccess.hxx>
50 : #include <IDocumentFieldsAccess.hxx>
51 : #include <IDocumentLayoutAccess.hxx>
52 : #include <wdocsh.hxx>
53 : #include <fesh.hxx>
54 : #include <pam.hxx>
55 : #include <viewimp.hxx>
56 : #include <layact.hxx>
57 : #include <ndtxt.hxx>
58 : #include <fldbas.hxx>
59 : #include <docfld.hxx>
60 : #include <docufld.hxx>
61 : #include <shellres.hxx>
62 : #include <viewopt.hxx>
63 : #include <printdata.hxx>
64 : #include <pagedesc.hxx>
65 : #include <poolfmt.hxx>
66 : #include <mdiexp.hxx>
67 : #include <statstr.hrc>
68 : #include <ptqueue.hxx>
69 : #include <tabfrm.hxx>
70 : #include <txtfrm.hxx>
71 : #include <viscrs.hxx>
72 : #include <fmtpdsc.hxx>
73 : #include <globals.hrc>
74 : #include "PostItMgr.hxx"
75 : #include <vprint.hxx>
76 :
77 : using namespace ::com::sun::star;
78 :
79 : /// Painting buffer
80 : class SwQueuedPaint
81 : {
82 : public:
83 : SwQueuedPaint *pNext;
84 : SwViewShell *pSh;
85 : SwRect aRect;
86 :
87 1 : SwQueuedPaint( SwViewShell *pNew, const SwRect &rRect ) :
88 : pNext( 0 ),
89 : pSh( pNew ),
90 1 : aRect( rRect )
91 1 : {}
92 : };
93 :
94 : SwQueuedPaint *SwPaintQueue::pQueue = 0;
95 :
96 : // saves some settings from the draw view
97 : class SwDrawViewSave
98 : {
99 : SdrView* pDV;
100 : bool bPrintControls;
101 : public:
102 : explicit SwDrawViewSave( SdrView* pSdrView );
103 : ~SwDrawViewSave();
104 : };
105 :
106 1 : void SwPaintQueue::Add( SwViewShell *pNew, const SwRect &rNew )
107 : {
108 : SwQueuedPaint *pPt;
109 1 : if ( 0 != (pPt = pQueue) )
110 : {
111 0 : while ( pPt->pSh != pNew && pPt->pNext )
112 0 : pPt = pPt->pNext;
113 0 : if ( pPt->pSh == pNew )
114 : {
115 0 : pPt->aRect.Union( rNew );
116 1 : return;
117 : }
118 : }
119 1 : SwQueuedPaint *pNQ = new SwQueuedPaint( pNew, rNew );
120 1 : if ( pPt )
121 0 : pPt->pNext = pNQ;
122 : else
123 1 : pQueue = pNQ;
124 : }
125 :
126 1 : void SwPaintQueue::Repaint()
127 : {
128 1 : if ( !SwRootFrm::IsInPaint() && pQueue )
129 : {
130 0 : SwQueuedPaint *pPt = pQueue;
131 0 : do
132 0 : { SwViewShell *pSh = pPt->pSh;
133 0 : SET_CURR_SHELL( pSh );
134 0 : if ( pSh->IsPreview() )
135 : {
136 0 : if ( pSh->GetWin() )
137 : {
138 : // for previewing, since rows/columns are known in PaintHdl (UI)
139 0 : pSh->GetWin()->Invalidate();
140 0 : pSh->GetWin()->Update();
141 : }
142 : }
143 : else
144 0 : pSh->Paint(*pSh->GetOut(), pPt->aRect.SVRect());
145 0 : pPt = pPt->pNext;
146 : } while ( pPt );
147 :
148 0 : do
149 0 : { pPt = pQueue;
150 0 : pQueue = pQueue->pNext;
151 0 : delete pPt;
152 : } while ( pQueue );
153 : }
154 1 : }
155 :
156 3105 : void SwPaintQueue::Remove( SwViewShell *pSh )
157 : {
158 : SwQueuedPaint *pPt;
159 3105 : if ( 0 != (pPt = pQueue) )
160 : {
161 2 : SwQueuedPaint *pPrev = 0;
162 5 : while ( pPt && pPt->pSh != pSh )
163 : {
164 1 : pPrev = pPt;
165 1 : pPt = pPt->pNext;
166 : }
167 2 : if ( pPt )
168 : {
169 1 : if ( pPrev )
170 0 : pPrev->pNext = pPt->pNext;
171 1 : else if ( pPt == pQueue )
172 1 : pQueue = 0;
173 1 : delete pPt;
174 : }
175 : }
176 3105 : }
177 :
178 2 : void SetSwVisArea( SwViewShell *pSh, const SwRect &rRect )
179 : {
180 : OSL_ENSURE( !pSh->GetWin(), "Drucken mit Window?" );
181 2 : pSh->maVisArea = rRect;
182 2 : pSh->Imp()->SetFirstVisPageInvalid();
183 2 : Point aPt( rRect.Pos() );
184 :
185 : // calculate an offset for the rectangle of the n-th page to
186 : // move the start point of the output operation to a position
187 : // such that in the output device all pages will be painted
188 : // at the same position
189 2 : aPt.X() = -aPt.X(); aPt.Y() = -aPt.Y();
190 :
191 2 : vcl::RenderContext *pOut = pSh->GetOut();
192 :
193 2 : MapMode aMapMode( pOut->GetMapMode() );
194 2 : aMapMode.SetOrigin( aPt );
195 2 : pOut->SetMapMode( aMapMode );
196 2 : }
197 :
198 2 : void SwViewShell::InitPrt( OutputDevice *pOutDev )
199 : {
200 : // For printing we use a negative offset (exactly the offset of OutputSize).
201 : // This is necessary because the origin is in the upper left corner of the
202 : // physical page while the output uses OutputOffset as origin.
203 2 : if ( pOutDev )
204 : {
205 2 : maPrtOffst = Point();
206 :
207 2 : maPrtOffst += pOutDev->GetMapMode().GetOrigin();
208 2 : MapMode aMapMode( pOutDev->GetMapMode() );
209 2 : aMapMode.SetMapUnit( MAP_TWIP );
210 2 : pOutDev->SetMapMode( aMapMode );
211 2 : pOutDev->SetLineColor();
212 2 : pOutDev->SetFillColor();
213 : }
214 : else
215 0 : maPrtOffst.X() = maPrtOffst.Y() = 0;
216 :
217 2 : if ( !mpWin )
218 1 : mpOut = pOutDev;
219 2 : }
220 :
221 0 : void SwViewShell::ChgAllPageOrientation( Orientation eOri )
222 : {
223 : OSL_ENSURE( mnStartAction, "missing an Action" );
224 0 : SET_CURR_SHELL( this );
225 :
226 0 : const size_t nAll = GetDoc()->GetPageDescCnt();
227 0 : bool bNewOri = eOri != ORIENTATION_PORTRAIT;
228 :
229 0 : for( size_t i = 0; i < nAll; ++ i )
230 : {
231 0 : const SwPageDesc& rOld = GetDoc()->GetPageDesc( i );
232 :
233 0 : if( rOld.GetLandscape() != bNewOri )
234 : {
235 0 : SwPageDesc aNew( rOld );
236 : {
237 0 : ::sw::UndoGuard const ug(GetDoc()->GetIDocumentUndoRedo());
238 0 : GetDoc()->CopyPageDesc(rOld, aNew);
239 : }
240 0 : aNew.SetLandscape( bNewOri );
241 0 : SwFrameFormat& rFormat = aNew.GetMaster();
242 0 : SwFormatFrmSize aSz( rFormat.GetFrmSize() );
243 : // adjust size
244 : // PORTRAIT -> higher than wide
245 : // LANDSCAPE -> wider than high
246 : // Height is the VarSize, width the FixSize (per Def.)
247 0 : if( bNewOri ? aSz.GetHeight() > aSz.GetWidth()
248 0 : : aSz.GetHeight() < aSz.GetWidth() )
249 : {
250 0 : SwTwips aTmp = aSz.GetHeight();
251 0 : aSz.SetHeight( aSz.GetWidth() );
252 0 : aSz.SetWidth( aTmp );
253 0 : rFormat.SetFormatAttr( aSz );
254 : }
255 0 : GetDoc()->ChgPageDesc( i, aNew );
256 : }
257 0 : }
258 0 : }
259 :
260 0 : void SwViewShell::ChgAllPageSize( Size &rSz )
261 : {
262 : OSL_ENSURE( mnStartAction, "missing an Action" );
263 0 : SET_CURR_SHELL( this );
264 :
265 0 : SwDoc* pMyDoc = GetDoc();
266 0 : const size_t nAll = pMyDoc->GetPageDescCnt();
267 :
268 0 : for( size_t i = 0; i < nAll; ++i )
269 : {
270 0 : const SwPageDesc &rOld = pMyDoc->GetPageDesc( i );
271 0 : SwPageDesc aNew( rOld );
272 : {
273 0 : ::sw::UndoGuard const ug(GetDoc()->GetIDocumentUndoRedo());
274 0 : GetDoc()->CopyPageDesc( rOld, aNew );
275 : }
276 0 : SwFrameFormat& rPgFormat = aNew.GetMaster();
277 0 : Size aSz( rSz );
278 0 : const bool bOri = aNew.GetLandscape();
279 0 : if( bOri ? aSz.Height() > aSz.Width()
280 0 : : aSz.Height() < aSz.Width() )
281 : {
282 0 : SwTwips aTmp = aSz.Height();
283 0 : aSz.Height() = aSz.Width();
284 0 : aSz.Width() = aTmp;
285 : }
286 :
287 0 : SwFormatFrmSize aFrmSz( rPgFormat.GetFrmSize() );
288 0 : aFrmSz.SetSize( aSz );
289 0 : rPgFormat.SetFormatAttr( aFrmSz );
290 0 : pMyDoc->ChgPageDesc( i, aNew );
291 0 : }
292 0 : }
293 :
294 1 : void SwViewShell::CalcPagesForPrint( sal_uInt16 nMax )
295 : {
296 1 : SET_CURR_SHELL( this );
297 :
298 1 : SwRootFrm* pMyLayout = GetLayout();
299 :
300 1 : const SwFrm *pPage = pMyLayout->Lower();
301 2 : SwLayAction aAction( pMyLayout, Imp() );
302 :
303 1 : pMyLayout->StartAllAction();
304 2 : for ( sal_uInt16 i = 1; pPage && i <= nMax; pPage = pPage->GetNext(), ++i )
305 : {
306 1 : pPage->Calc();
307 1 : SwRect aOldVis( VisArea() );
308 1 : maVisArea = pPage->Frm();
309 1 : Imp()->SetFirstVisPageInvalid();
310 1 : aAction.Reset();
311 1 : aAction.SetPaint( false );
312 1 : aAction.SetWaitAllowed( false );
313 1 : aAction.SetReschedule( true );
314 :
315 1 : aAction.Action();
316 :
317 1 : maVisArea = aOldVis; //reset due to the paints
318 1 : Imp()->SetFirstVisPageInvalid();
319 : }
320 :
321 2 : pMyLayout->EndAllAction();
322 1 : }
323 :
324 0 : SwDoc * SwViewShell::FillPrtDoc( SwDoc *pPrtDoc, const SfxPrinter* pPrt)
325 : {
326 : OSL_ENSURE( this->IsA( TYPE(SwFEShell) ),"SwViewShell::Prt for FEShell only");
327 0 : SwFEShell* pFESh = static_cast<SwFEShell*>(this);
328 0 : pPrtDoc->getIDocumentFieldsAccess().LockExpFields();
329 :
330 : // use given printer
331 : //! Make a copy of it since it gets destroyed with the temporary document
332 : //! used for PDF export
333 0 : if (pPrt)
334 0 : pPrtDoc->getIDocumentDeviceAccess().setPrinter( VclPtr<SfxPrinter>::Create(*pPrt), true, true );
335 :
336 0 : const SfxItemPool& rPool = GetAttrPool();
337 0 : for( sal_uInt16 nWh = POOLATTR_BEGIN; nWh < POOLATTR_END; ++nWh )
338 : {
339 0 : const SfxPoolItem* pCpyItem = rPool.GetPoolDefaultItem( nWh );
340 0 : if( 0 != pCpyItem )
341 0 : pPrtDoc->GetAttrPool().SetPoolDefaultItem( *pCpyItem );
342 : }
343 :
344 : // JP 29.07.99 - Bug 67951 - set all Styles from the SourceDoc into
345 : // the PrintDoc - will be replaced!
346 0 : pPrtDoc->ReplaceStyles( *GetDoc() );
347 :
348 0 : SwShellCrsr *pActCrsr = pFESh->_GetCrsr();
349 0 : SwShellCrsr *pFirstCrsr = dynamic_cast<SwShellCrsr*>(pActCrsr->GetNext());
350 0 : if( !pActCrsr->HasMark() ) // with a multi-selection the current cursor might be empty
351 : {
352 0 : pActCrsr = dynamic_cast<SwShellCrsr*>(pActCrsr->GetPrev());
353 : }
354 :
355 : // Y-position of the first selection
356 0 : Point aSelPoint;
357 0 : if( pFESh->IsTableMode() )
358 : {
359 0 : SwShellTableCrsr* pShellTableCrsr = pFESh->GetTableCrsr();
360 :
361 0 : const SwContentNode* pContentNode = pShellTableCrsr->GetNode().GetContentNode();
362 0 : const SwContentFrm *pContentFrm = pContentNode ? pContentNode->getLayoutFrm( GetLayout(), 0, pShellTableCrsr->Start() ) : 0;
363 0 : if( pContentFrm )
364 : {
365 0 : SwRect aCharRect;
366 0 : SwCrsrMoveState aTmpState( MV_NONE );
367 0 : pContentFrm->GetCharRect( aCharRect, *pShellTableCrsr->Start(), &aTmpState );
368 0 : aSelPoint = Point( aCharRect.Left(), aCharRect.Top() );
369 : }
370 : }
371 0 : else if (pFirstCrsr)
372 : {
373 0 : aSelPoint = pFirstCrsr->GetSttPos();
374 : }
375 :
376 0 : const SwPageFrm* pPage = GetLayout()->GetPageAtPos( aSelPoint );
377 : OSL_ENSURE( pPage, "no page found!" );
378 :
379 : // get page descriptor - fall back to the first one if pPage could not be found
380 : const SwPageDesc* pPageDesc = pPage ? pPrtDoc->FindPageDesc(
381 0 : pPage->GetPageDesc()->GetName() ) : &pPrtDoc->GetPageDesc( 0 );
382 :
383 0 : if( !pFESh->IsTableMode() && pActCrsr && pActCrsr->HasMark() )
384 : { // Tweak paragraph attributes of last paragraph
385 0 : SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
386 0 : SwTextNode* pTextNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx )->GetTextNode();
387 : SwContentNode *pLastNd =
388 0 : pActCrsr->GetContentNode( (*pActCrsr->GetMark()) <= (*pActCrsr->GetPoint()) );
389 : // copy the paragraph attributes of the first paragraph
390 0 : if( pLastNd && pLastNd->IsTextNode() )
391 0 : static_cast<SwTextNode*>(pLastNd)->CopyCollFormat( *pTextNd );
392 : }
393 :
394 : // fill it with the selected content
395 0 : pFESh->Copy( pPrtDoc );
396 :
397 : // set the page style at the first paragraph
398 : {
399 0 : SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
400 0 : SwContentNode* pCNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx ); // go to 1st ContentNode
401 0 : if( pFESh->IsTableMode() )
402 : {
403 0 : SwTableNode* pTNd = pCNd->FindTableNode();
404 0 : if( pTNd )
405 0 : pTNd->GetTable().GetFrameFormat()->SetFormatAttr( SwFormatPageDesc( pPageDesc ) );
406 : }
407 : else
408 : {
409 0 : pCNd->SetAttr( SwFormatPageDesc( pPageDesc ) );
410 0 : if( pFirstCrsr && pFirstCrsr->HasMark() )
411 : {
412 0 : SwTextNode *pTextNd = pCNd->GetTextNode();
413 0 : if( pTextNd )
414 : {
415 : SwContentNode *pFirstNd =
416 0 : pFirstCrsr->GetContentNode( (*pFirstCrsr->GetMark()) > (*pFirstCrsr->GetPoint()) );
417 : // copy paragraph attributes of the first paragraph
418 0 : if( pFirstNd && pFirstNd->IsTextNode() )
419 0 : static_cast<SwTextNode*>(pFirstNd)->CopyCollFormat( *pTextNd );
420 : }
421 : }
422 0 : }
423 : }
424 0 : return pPrtDoc;
425 : }
426 :
427 : // TODO: there is already a GetPageByPageNum, but it checks some physical page
428 : // number; unsure if we want that here, should find out what that is...
429 : SwPageFrm const*
430 1 : sw_getPage(SwRootFrm const& rLayout, sal_Int32 const nPage)
431 : {
432 : // yes this is O(n^2) but at least it does not crash...
433 1 : SwPageFrm const* pPage = dynamic_cast<const SwPageFrm*>(rLayout.Lower());
434 1 : for (sal_Int32 i = nPage; pPage && (i > 0); --i)
435 : {
436 1 : if (1 == i) { // note: nPage is 1-based, i.e. 0 is invalid!
437 1 : return pPage;
438 : }
439 0 : pPage = dynamic_cast<SwPageFrm const*>(pPage->GetNext());
440 : }
441 : OSL_ENSURE(pPage, "ERROR: SwPageFrm expected");
442 : OSL_FAIL("non-existent page requested");
443 0 : return 0;
444 : }
445 :
446 1 : bool SwViewShell::PrintOrPDFExport(
447 : OutputDevice *pOutDev,
448 : SwPrintData const& rPrintData,
449 : sal_Int32 nRenderer /* the index in the vector of pages to be printed */ )
450 : {
451 : // CAUTION: Do also always update the printing routines in viewpg.cxx (PrintProspect)!
452 :
453 1 : const sal_Int32 nMaxRenderer = rPrintData.GetRenderData().GetPagesToPrint().size() - 1;
454 : OSL_ENSURE( 0 <= nRenderer && nRenderer <= nMaxRenderer, "nRenderer out of bounds");
455 1 : if (!pOutDev || nMaxRenderer < 0 || nRenderer < 0 || nRenderer > nMaxRenderer)
456 0 : return false;
457 :
458 : // save settings of OutputDevice (should be done always since the
459 : // output device is now provided by a call from outside the Writer)
460 1 : pOutDev->Push();
461 :
462 : // fdo#36815 for comments in margins print to a metafile
463 : // and then scale that metafile down so that the comments
464 : // will fit on the real page, and replay that scaled
465 : // output to the real outputdevice
466 1 : GDIMetaFile *pOrigRecorder(NULL);
467 1 : GDIMetaFile *pMetaFile(NULL);
468 1 : sal_Int16 nPostItMode = rPrintData.GetPrintPostIts();
469 1 : if (nPostItMode == POSTITS_INMARGINS)
470 : {
471 : //get and disable the existing recorder
472 0 : pOrigRecorder = pOutDev->GetConnectMetaFile();
473 0 : pOutDev->SetConnectMetaFile(NULL);
474 : // turn off output to the device
475 0 : pOutDev->EnableOutput(false);
476 : // just record the rendering commands to the metafile
477 : // instead
478 0 : pMetaFile = new GDIMetaFile;
479 0 : pMetaFile->SetPrefSize(pOutDev->GetOutputSize());
480 0 : pMetaFile->SetPrefMapMode(pOutDev->GetMapMode());
481 0 : pMetaFile->Record(pOutDev);
482 : }
483 :
484 : // Print/PDF export for (multi-)selection has already generated a
485 : // temporary document with the selected text.
486 : // (see XRenderable implementation in unotxdoc.cxx)
487 : // It is implemented this way because PDF export calls this Prt function
488 : // once per page and we do not like to always have the temporary document
489 : // to be created that often here.
490 1 : SwViewShell *pShell = new SwViewShell(*this, 0, pOutDev);
491 :
492 1 : SdrView *pDrawView = pShell->GetDrawView();
493 1 : if (pDrawView)
494 : {
495 1 : pDrawView->SetBufferedOutputAllowed( false );
496 1 : pDrawView->SetBufferedOverlayAllowed( false );
497 : }
498 :
499 : { // additional scope so that the CurrShell is reset before destroying the shell
500 :
501 1 : SET_CURR_SHELL( pShell );
502 :
503 : //JP 01.02.99: Bug 61335 - the ReadOnly flag is never copied
504 1 : if( mpOpt->IsReadonly() )
505 0 : pShell->mpOpt->SetReadonly( true );
506 :
507 : // save options at draw view:
508 2 : SwDrawViewSave aDrawViewSave( pShell->GetDrawView() );
509 :
510 1 : pShell->PrepareForPrint( rPrintData );
511 :
512 1 : const sal_Int32 nPage = rPrintData.GetRenderData().GetPagesToPrint()[ nRenderer ];
513 : OSL_ENSURE( nPage < 0 ||
514 : rPrintData.GetRenderData().GetValidPagesSet().count( nPage ) == 1,
515 : "SwViewShell::PrintOrPDFExport: nPage not valid" );
516 : SwViewShell *const pViewSh2 = (nPage < 0)
517 0 : ? rPrintData.GetRenderData().m_pPostItShell.get()// post-it page
518 1 : : pShell; // a 'regular' page, not one from the post-it doc
519 :
520 : SwPageFrm const*const pStPage =
521 1 : sw_getPage(*pViewSh2->GetLayout(), abs(nPage));
522 : OSL_ENSURE( pStPage, "failed to get start page" );
523 1 : if (!pStPage)
524 : {
525 0 : return false;
526 : }
527 :
528 : //!! applying view options and formatting the document should now only be done in getRendererCount!
529 :
530 1 : ::SetSwVisArea( pViewSh2, pStPage->Frm() );
531 :
532 1 : pShell->InitPrt(pOutDev);
533 :
534 1 : ::SetSwVisArea( pViewSh2, pStPage->Frm() );
535 :
536 1 : pStPage->GetUpper()->Paint( pStPage->Frm(), &rPrintData );
537 :
538 1 : SwPaintQueue::Repaint();
539 :
540 : SwPostItMgr *pPostItManager = (nPostItMode == POSTITS_INMARGINS) ?
541 1 : pShell->GetPostItMgr() : NULL;
542 1 : if (pPostItManager)
543 : {
544 0 : pPostItManager->CalcRects();
545 0 : pPostItManager->LayoutPostIts();
546 0 : pPostItManager->DrawNotesForPage(pOutDev, nPage-1);
547 :
548 : //Stop recording now
549 0 : pMetaFile->Stop();
550 0 : pMetaFile->WindStart();
551 : //Enable output to the device again
552 0 : pOutDev->EnableOutput(true);
553 : //Restore the original recorder
554 0 : pOutDev->SetConnectMetaFile(pOrigRecorder);
555 :
556 : //Now scale the recorded page down so the notes
557 : //will fit in the final page
558 0 : double fScale = 0.75;
559 0 : long nOrigHeight = pStPage->Frm().Height();
560 0 : long nNewHeight = nOrigHeight*fScale;
561 0 : long nShiftY = (nOrigHeight-nNewHeight)/2;
562 0 : pMetaFile->Scale( fScale, fScale );
563 0 : pMetaFile->WindStart();
564 : //Move the scaled page down to center it
565 : //the other variant of Move does not map pixels
566 : //back to the logical units correctly
567 0 : pMetaFile->Move(0, convertTwipToMm100(nShiftY), pOutDev->GetDPIX(), pOutDev->GetDPIY());
568 0 : pMetaFile->WindStart();
569 :
570 : //play back the scaled page
571 0 : pMetaFile->Play(pOutDev);
572 0 : delete pMetaFile;
573 1 : }
574 : }
575 :
576 1 : delete pShell;
577 :
578 : // restore settings of OutputDevice (should be done always now since the
579 : // output device is now provided by a call from outside the Writer)
580 1 : pOutDev->Pop();
581 :
582 1 : return true;
583 : }
584 :
585 347 : void SwViewShell::PrtOle2( SwDoc *pDoc, const SwViewOption *pOpt, const SwPrintData& rOptions,
586 : OutputDevice* pOleOut, const Rectangle& rRect )
587 : {
588 : // For printing a shell is needed. Either the Doc already has one, than we
589 : // create a new view, or it has none, than we create the first view.
590 : SwViewShell *pSh;
591 347 : if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() )
592 66 : pSh = new SwViewShell( *pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(), 0, pOleOut,VSHELLFLAG_SHARELAYOUT );
593 : else
594 281 : pSh = new SwViewShell( *pDoc, 0, pOpt, pOleOut);
595 :
596 : {
597 347 : SET_CURR_SHELL( pSh );
598 347 : pSh->PrepareForPrint( rOptions );
599 347 : pSh->SetPrtFormatOption( true );
600 :
601 347 : SwRect aSwRect( rRect );
602 347 : pSh->maVisArea = aSwRect;
603 :
604 1041 : if ( pSh->GetViewOptions()->getBrowseMode() &&
605 347 : pSh->GetRingContainer().size() == 1 )
606 : {
607 0 : pSh->CheckBrowseView( false );
608 0 : pSh->GetLayout()->Lower()->InvalidateSize();
609 : }
610 :
611 : // CalcPagesForPrint() should not be necessary here. The pages in the
612 : // visible area will be formatted in SwRootFrm::Paint().
613 : // Removing this gives us a performance gain during saving the
614 : // document because the thumbnail creation will not trigger a complete
615 : // formatting of the document.
616 :
617 347 : pOleOut->Push( PushFlags::CLIPREGION );
618 347 : pOleOut->IntersectClipRegion( aSwRect.SVRect() );
619 347 : pSh->GetLayout()->Paint( aSwRect );
620 :
621 347 : pOleOut->Pop();
622 : // first the CurrShell object needs to be destroyed!
623 : }
624 347 : delete pSh;
625 347 : }
626 :
627 : /// Check if the DocNodesArray contains fields.
628 1 : bool SwViewShell::IsAnyFieldInDoc() const
629 : {
630 : const SfxPoolItem* pItem;
631 1 : sal_uInt32 nMaxItems = mpDoc->GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
632 1 : for( sal_uInt32 n = 0; n < nMaxItems; ++n )
633 : {
634 0 : if( 0 != (pItem = mpDoc->GetAttrPool().GetItem2( RES_TXTATR_FIELD, n )))
635 : {
636 0 : const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
637 0 : const SwTextField* pTextField = pFormatField->GetTextField();
638 0 : if( pTextField && pTextField->GetTextNode().GetNodes().IsDocNodes() )
639 : {
640 0 : return true;
641 : }
642 : }
643 : }
644 :
645 1 : nMaxItems = mpDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INPUTFIELD );
646 1 : for( sal_uInt32 n = 0; n < nMaxItems; ++n )
647 : {
648 0 : if( 0 != (pItem = mpDoc->GetAttrPool().GetItem2( RES_TXTATR_INPUTFIELD, n )))
649 : {
650 0 : const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
651 0 : const SwTextField* pTextField = pFormatField->GetTextField();
652 0 : if( pTextField && pTextField->GetTextNode().GetNodes().IsDocNodes() )
653 : {
654 0 : return true;
655 : }
656 : }
657 : }
658 :
659 1 : return false;
660 : }
661 :
662 : /// Saves some settings at the draw view
663 1 : SwDrawViewSave::SwDrawViewSave( SdrView* pSdrView )
664 : : pDV( pSdrView )
665 1 : , bPrintControls(true)
666 : {
667 1 : if ( pDV )
668 : {
669 1 : bPrintControls = pDV->IsLayerPrintable( "Controls" );
670 : }
671 1 : }
672 :
673 1 : SwDrawViewSave::~SwDrawViewSave()
674 : {
675 1 : if ( pDV )
676 : {
677 1 : pDV->SetLayerPrintable( "Controls", bPrintControls );
678 : }
679 1 : }
680 :
681 : // OD 09.01.2003 #i6467# - method also called for page preview
682 348 : void SwViewShell::PrepareForPrint( const SwPrintData &rOptions )
683 : {
684 348 : mpOpt->SetGraphic ( rOptions.bPrintGraphic );
685 348 : mpOpt->SetTable ( rOptions.bPrintTable );
686 348 : mpOpt->SetDraw ( rOptions.bPrintDraw );
687 348 : mpOpt->SetControl ( rOptions.bPrintControl );
688 348 : mpOpt->SetPageBack ( rOptions.bPrintPageBackground );
689 348 : mpOpt->SetBlackFont( rOptions.bPrintBlackFont );
690 :
691 348 : if ( HasDrawView() )
692 : {
693 348 : SdrView *pDrawView = GetDrawView();
694 : // OD 09.01.2003 #i6467# - consider, if view shell belongs to page preview
695 348 : if ( !IsPreview() )
696 : {
697 348 : pDrawView->SetLayerPrintable( "Controls", rOptions.bPrintControl );
698 : }
699 : else
700 : {
701 0 : pDrawView->SetLayerVisible( "Controls", rOptions.bPrintControl );
702 : }
703 : }
704 525 : }
705 :
706 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|