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 0 : SwQueuedPaint( SwViewShell *pNew, const SwRect &rRect ) :
88 : pNext( 0 ),
89 : pSh( pNew ),
90 0 : aRect( rRect )
91 0 : {}
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 : SwDrawViewSave( SdrView* pSdrView );
103 : ~SwDrawViewSave();
104 : };
105 :
106 0 : void SwPaintQueue::Add( SwViewShell *pNew, const SwRect &rNew )
107 : {
108 : SwQueuedPaint *pPt;
109 0 : 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 0 : return;
117 : }
118 : }
119 0 : SwQueuedPaint *pNQ = new SwQueuedPaint( pNew, rNew );
120 0 : if ( pPt )
121 0 : pPt->pNext = pNQ;
122 : else
123 0 : pQueue = pNQ;
124 : }
125 :
126 0 : void SwPaintQueue::Repaint()
127 : {
128 0 : 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( 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 0 : }
155 :
156 5316 : void SwPaintQueue::Remove( SwViewShell *pSh )
157 : {
158 : SwQueuedPaint *pPt;
159 5316 : if ( 0 != (pPt = pQueue) )
160 : {
161 0 : SwQueuedPaint *pPrev = 0;
162 0 : while ( pPt && pPt->pSh != pSh )
163 : {
164 0 : pPrev = pPt;
165 0 : pPt = pPt->pNext;
166 : }
167 0 : if ( pPt )
168 : {
169 0 : if ( pPrev )
170 0 : pPrev->pNext = pPt->pNext;
171 0 : else if ( pPt == pQueue )
172 0 : pQueue = 0;
173 0 : delete pPt;
174 : }
175 : }
176 5316 : }
177 :
178 0 : void SetSwVisArea( SwViewShell *pSh, const SwRect &rRect )
179 : {
180 : OSL_ENSURE( !pSh->GetWin(), "Drucken mit Window?" );
181 0 : pSh->maVisArea = rRect;
182 0 : pSh->Imp()->SetFirstVisPageInvalid();
183 0 : 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 0 : aPt.X() = -aPt.X(); aPt.Y() = -aPt.Y();
190 :
191 0 : OutputDevice *pOut = pSh->GetOut();
192 :
193 0 : MapMode aMapMode( pOut->GetMapMode() );
194 0 : aMapMode.SetOrigin( aPt );
195 0 : pOut->SetMapMode( aMapMode );
196 0 : }
197 :
198 4 : 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 4 : if ( pOutDev )
204 : {
205 4 : maPrtOffst = Point();
206 :
207 4 : maPrtOffst += pOutDev->GetMapMode().GetOrigin();
208 4 : MapMode aMapMode( pOutDev->GetMapMode() );
209 4 : aMapMode.SetMapUnit( MAP_TWIP );
210 4 : pOutDev->SetMapMode( aMapMode );
211 4 : pOutDev->SetLineColor();
212 4 : pOutDev->SetFillColor();
213 : }
214 : else
215 0 : maPrtOffst.X() = maPrtOffst.Y() = 0;
216 :
217 4 : if ( !mpWin )
218 0 : mpOut = pOutDev;
219 4 : }
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 sal_uInt16 nAll = GetDoc()->GetPageDescCnt();
227 0 : bool bNewOri = eOri != ORIENTATION_PORTRAIT;
228 :
229 0 : for( sal_uInt16 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 : SwFrmFmt& rFmt = aNew.GetMaster();
242 0 : SwFmtFrmSize aSz( rFmt.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 : rFmt.SetFmtAttr( 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 sal_uInt16 nAll = pMyDoc->GetPageDescCnt();
267 :
268 0 : for( sal_uInt16 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 : SwFrmFmt& rPgFmt = 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 : SwFmtFrmSize aFrmSz( rPgFmt.GetFrmSize() );
288 0 : aFrmSz.SetSize( aSz );
289 0 : rPgFmt.SetFmtAttr( aFrmSz );
290 0 : pMyDoc->ChgPageDesc( i, aNew );
291 0 : }
292 0 : }
293 :
294 0 : void SwViewShell::CalcPagesForPrint( sal_uInt16 nMax )
295 : {
296 0 : SET_CURR_SHELL( this );
297 :
298 0 : SwRootFrm* pMyLayout = GetLayout();
299 :
300 0 : const SwFrm *pPage = pMyLayout->Lower();
301 0 : SwLayAction aAction( pMyLayout, Imp() );
302 :
303 0 : pMyLayout->StartAllAction();
304 0 : for ( sal_uInt16 i = 1; pPage && i <= nMax; pPage = pPage->GetNext(), ++i )
305 : {
306 0 : pPage->Calc();
307 0 : SwRect aOldVis( VisArea() );
308 0 : maVisArea = pPage->Frm();
309 0 : Imp()->SetFirstVisPageInvalid();
310 0 : aAction.Reset();
311 0 : aAction.SetPaint( false );
312 0 : aAction.SetWaitAllowed( false );
313 0 : aAction.SetReschedule( true );
314 :
315 0 : aAction.Action();
316 :
317 0 : maVisArea = aOldVis; //reset due to the paints
318 0 : Imp()->SetFirstVisPageInvalid();
319 : }
320 :
321 0 : pMyLayout->EndAllAction();
322 0 : }
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 = (SwFEShell*)this;
328 0 : pPrtDoc->getIDocumentFieldsAccess().LockExpFlds();
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( new SfxPrinter(*pPrt), true, true );
335 :
336 : const SfxPoolItem* pCpyItem;
337 0 : const SfxItemPool& rPool = GetAttrPool();
338 0 : for( sal_uInt16 nWh = POOLATTR_BEGIN; nWh < POOLATTR_END; ++nWh )
339 0 : if( 0 != ( pCpyItem = rPool.GetPoolDefaultItem( nWh ) ) )
340 0 : pPrtDoc->GetAttrPool().SetPoolDefaultItem( *pCpyItem );
341 :
342 : // JP 29.07.99 - Bug 67951 - set all Styles from the SourceDoc into
343 : // the PrintDoc - will be replaced!
344 0 : pPrtDoc->ReplaceStyles( *GetDoc() );
345 :
346 0 : SwShellCrsr *pActCrsr = pFESh->_GetCrsr();
347 0 : SwShellCrsr *pFirstCrsr = dynamic_cast<SwShellCrsr*>(pActCrsr->GetNext());
348 0 : if( !pActCrsr->HasMark() ) // with a multi-selection the current cursor might be empty
349 : {
350 0 : pActCrsr = dynamic_cast<SwShellCrsr*>(pActCrsr->GetPrev());
351 : }
352 :
353 : // Y-position of the first selection
354 0 : Point aSelPoint;
355 0 : if( pFESh->IsTableMode() )
356 : {
357 0 : SwShellTableCrsr* pShellTblCrsr = pFESh->GetTableCrsr();
358 :
359 0 : const SwCntntNode* pCntntNode = pShellTblCrsr->GetNode().GetCntntNode();
360 0 : const SwCntntFrm *pCntntFrm = pCntntNode ? pCntntNode->getLayoutFrm( GetLayout(), 0, pShellTblCrsr->Start() ) : 0;
361 0 : if( pCntntFrm )
362 : {
363 0 : SwRect aCharRect;
364 0 : SwCrsrMoveState aTmpState( MV_NONE );
365 0 : pCntntFrm->GetCharRect( aCharRect, *pShellTblCrsr->Start(), &aTmpState );
366 0 : aSelPoint = Point( aCharRect.Left(), aCharRect.Top() );
367 : }
368 : }
369 0 : else if (pFirstCrsr)
370 : {
371 0 : aSelPoint = pFirstCrsr->GetSttPos();
372 : }
373 :
374 0 : const SwPageFrm* pPage = GetLayout()->GetPageAtPos( aSelPoint );
375 : OSL_ENSURE( pPage, "no page found!" );
376 :
377 : // get page descriptor - fall back to the first one if pPage could not be found
378 : const SwPageDesc* pPageDesc = pPage ? pPrtDoc->FindPageDesc(
379 0 : pPage->GetPageDesc()->GetName() ) : &pPrtDoc->GetPageDesc( (sal_uInt16)0 );
380 :
381 0 : if( !pFESh->IsTableMode() && pActCrsr && pActCrsr->HasMark() )
382 : { // Tweak paragraph attributes of last paragraph
383 0 : SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
384 0 : SwTxtNode* pTxtNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx )->GetTxtNode();
385 : SwCntntNode *pLastNd =
386 0 : pActCrsr->GetCntntNode( (*pActCrsr->GetMark()) <= (*pActCrsr->GetPoint()) );
387 : // copy the paragraph attributes of the first paragraph
388 0 : if( pLastNd && pLastNd->IsTxtNode() )
389 0 : ((SwTxtNode*)pLastNd)->CopyCollFmt( *pTxtNd );
390 : }
391 :
392 : // fill it with the selected content
393 0 : pFESh->Copy( pPrtDoc );
394 :
395 : // set the page style at the first paragraph
396 : {
397 0 : SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
398 0 : SwCntntNode* pCNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx ); // go to 1st ContentNode
399 0 : if( pFESh->IsTableMode() )
400 : {
401 0 : SwTableNode* pTNd = pCNd->FindTableNode();
402 0 : if( pTNd )
403 0 : pTNd->GetTable().GetFrmFmt()->SetFmtAttr( SwFmtPageDesc( pPageDesc ) );
404 : }
405 : else
406 : {
407 0 : pCNd->SetAttr( SwFmtPageDesc( pPageDesc ) );
408 0 : if( pFirstCrsr && pFirstCrsr->HasMark() )
409 : {
410 0 : SwTxtNode *pTxtNd = pCNd->GetTxtNode();
411 0 : if( pTxtNd )
412 : {
413 : SwCntntNode *pFirstNd =
414 0 : pFirstCrsr->GetCntntNode( (*pFirstCrsr->GetMark()) > (*pFirstCrsr->GetPoint()) );
415 : // copy paragraph attributes of the first paragraph
416 0 : if( pFirstNd && pFirstNd->IsTxtNode() )
417 0 : ((SwTxtNode*)pFirstNd)->CopyCollFmt( *pTxtNd );
418 : }
419 : }
420 0 : }
421 : }
422 0 : return pPrtDoc;
423 : }
424 :
425 : // TODO: there is already a GetPageByPageNum, but it checks some physical page
426 : // number; unsure if we want that here, should find out what that is...
427 : SwPageFrm const*
428 0 : sw_getPage(SwRootFrm const& rLayout, sal_Int32 const nPage)
429 : {
430 : // yes this is O(n^2) but at least it does not crash...
431 0 : SwPageFrm const* pPage = dynamic_cast<const SwPageFrm*>(rLayout.Lower());
432 0 : for (sal_Int32 i = nPage; pPage && (i > 0); --i)
433 : {
434 0 : if (1 == i) { // note: nPage is 1-based, i.e. 0 is invalid!
435 0 : return pPage;
436 : }
437 0 : pPage = dynamic_cast<SwPageFrm const*>(pPage->GetNext());
438 : }
439 : OSL_ENSURE(pPage, "ERROR: SwPageFrm expected");
440 : OSL_FAIL("non-existent page requested");
441 0 : return 0;
442 : }
443 :
444 0 : bool SwViewShell::PrintOrPDFExport(
445 : OutputDevice *pOutDev,
446 : SwPrintData const& rPrintData,
447 : sal_Int32 nRenderer /* the index in the vector of pages to be printed */ )
448 : {
449 : // CAUTION: Do also always update the printing routines in viewpg.cxx (PrintProspect)!
450 :
451 0 : const sal_Int32 nMaxRenderer = rPrintData.GetRenderData().GetPagesToPrint().size() - 1;
452 : OSL_ENSURE( 0 <= nRenderer && nRenderer <= nMaxRenderer, "nRenderer out of bounds");
453 0 : if (!pOutDev || nMaxRenderer < 0 || nRenderer < 0 || nRenderer > nMaxRenderer)
454 0 : return false;
455 :
456 : // save settings of OutputDevice (should be done always since the
457 : // output device is now provided by a call from outside the Writer)
458 0 : pOutDev->Push();
459 :
460 : // fdo#36815 for comments in margins print to a metafile
461 : // and then scale that metafile down so that the comments
462 : // will fit on the real page, and replay that scaled
463 : // output to the real outputdevice
464 0 : GDIMetaFile *pOrigRecorder(NULL);
465 0 : GDIMetaFile *pMetaFile(NULL);
466 0 : sal_Int16 nPostItMode = rPrintData.GetPrintPostIts();
467 0 : if (nPostItMode == POSTITS_INMARGINS)
468 : {
469 : //get and disable the existing recorder
470 0 : pOrigRecorder = pOutDev->GetConnectMetaFile();
471 0 : pOutDev->SetConnectMetaFile(NULL);
472 : // turn off output to the device
473 0 : pOutDev->EnableOutput(false);
474 : // just record the rendering commands to the metafile
475 : // instead
476 0 : pMetaFile = new GDIMetaFile;
477 0 : pMetaFile->SetPrefSize(pOutDev->GetOutputSize());
478 0 : pMetaFile->SetPrefMapMode(pOutDev->GetMapMode());
479 0 : pMetaFile->Record(pOutDev);
480 : }
481 :
482 : // Print/PDF export for (multi-)selection has already generated a
483 : // temporary document with the selected text.
484 : // (see XRenderable implementation in unotxdoc.cxx)
485 : // It is implemented this way because PDF export calls this Prt function
486 : // once per page and we do not like to always have the temporary document
487 : // to be created that often here.
488 0 : SwViewShell *pShell = new SwViewShell(*this, 0, pOutDev);
489 :
490 0 : SdrView *pDrawView = pShell->GetDrawView();
491 0 : if (pDrawView)
492 : {
493 0 : pDrawView->SetBufferedOutputAllowed( false );
494 0 : pDrawView->SetBufferedOverlayAllowed( false );
495 : }
496 :
497 : { // additional scope so that the CurrShell is reset before destroying the shell
498 :
499 0 : SET_CURR_SHELL( pShell );
500 :
501 : //JP 01.02.99: Bug 61335 - the ReadOnly flag is never copied
502 0 : if( mpOpt->IsReadonly() )
503 0 : pShell->mpOpt->SetReadonly( true );
504 :
505 : // save options at draw view:
506 0 : SwDrawViewSave aDrawViewSave( pShell->GetDrawView() );
507 :
508 0 : pShell->PrepareForPrint( rPrintData );
509 :
510 0 : const sal_Int32 nPage = rPrintData.GetRenderData().GetPagesToPrint()[ nRenderer ];
511 : OSL_ENSURE( nPage < 0 ||
512 : rPrintData.GetRenderData().GetValidPagesSet().count( nPage ) == 1,
513 : "SwViewShell::PrintOrPDFExport: nPage not valid" );
514 : SwViewShell *const pViewSh2 = (nPage < 0)
515 0 : ? rPrintData.GetRenderData().m_pPostItShell.get()// post-it page
516 0 : : pShell; // a 'regular' page, not one from the post-it doc
517 :
518 : SwPageFrm const*const pStPage =
519 0 : sw_getPage(*pViewSh2->GetLayout(), abs(nPage));
520 : OSL_ENSURE( pStPage, "failed to get start page" );
521 0 : if (!pStPage)
522 : {
523 0 : return false;
524 : }
525 :
526 : //!! applying view options and formatting the document should now only be done in getRendererCount!
527 :
528 0 : ::SetSwVisArea( pViewSh2, pStPage->Frm() );
529 :
530 0 : pShell->InitPrt(pOutDev);
531 :
532 0 : ::SetSwVisArea( pViewSh2, pStPage->Frm() );
533 :
534 0 : pStPage->GetUpper()->Paint( pStPage->Frm(), &rPrintData );
535 :
536 0 : SwPaintQueue::Repaint();
537 :
538 0 : if (nPostItMode == POSTITS_INMARGINS)
539 : {
540 0 : SwPostItMgr *pPostItManager = pShell->GetPostItMgr();
541 0 : pPostItManager->CalcRects();
542 0 : pPostItManager->LayoutPostIts();
543 0 : pPostItManager->DrawNotesForPage(pOutDev, nPage-1);
544 :
545 : //Stop recording now
546 0 : pMetaFile->Stop();
547 0 : pMetaFile->WindStart();
548 : //Enable output to the device again
549 0 : pOutDev->EnableOutput(true);
550 : //Restore the original recorder
551 0 : pOutDev->SetConnectMetaFile(pOrigRecorder);
552 :
553 : //Now scale the recorded page down so the notes
554 : //will fit in the final page
555 0 : double fScale = 0.75;
556 0 : long nOrigHeight = pStPage->Frm().Height();
557 0 : long nNewHeight = nOrigHeight*fScale;
558 0 : long nShiftY = (nOrigHeight-nNewHeight)/2;
559 0 : pMetaFile->Scale( fScale, fScale );
560 0 : pMetaFile->WindStart();
561 : //Move the scaled page down to center it
562 : //the other variant of Move does not map pixels
563 : //back to the logical units correctly
564 0 : pMetaFile->Move(0, convertTwipToMm100(nShiftY), pOutDev->GetDPIX(), pOutDev->GetDPIY());
565 0 : pMetaFile->WindStart();
566 :
567 : //play back the scaled page
568 0 : pMetaFile->Play(pOutDev);
569 0 : delete pMetaFile;
570 0 : }
571 : }
572 :
573 0 : delete pShell;
574 :
575 : // restore settings of OutputDevice (should be done always now since the
576 : // output device is now provided by a call from outside the Writer)
577 0 : pOutDev->Pop();
578 :
579 0 : return true;
580 : }
581 :
582 610 : void SwViewShell::PrtOle2( SwDoc *pDoc, const SwViewOption *pOpt, const SwPrintData& rOptions,
583 : OutputDevice* pOleOut, const Rectangle& rRect )
584 : {
585 : // For printing a shell is needed. Either the Doc already has one, than we
586 : // create a new view, or it has none, than we create the first view.
587 : SwViewShell *pSh;
588 610 : if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() )
589 52 : pSh = new SwViewShell( *pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(), 0, pOleOut,VSHELLFLAG_SHARELAYOUT );
590 : else
591 558 : pSh = new SwViewShell( *pDoc, 0, pOpt, pOleOut);
592 :
593 : {
594 610 : SET_CURR_SHELL( pSh );
595 610 : pSh->PrepareForPrint( rOptions );
596 610 : pSh->SetPrtFormatOption( true );
597 :
598 610 : SwRect aSwRect( rRect );
599 610 : pSh->maVisArea = aSwRect;
600 :
601 610 : if ( pSh->GetViewOptions()->getBrowseMode() &&
602 0 : pSh->GetNext() == pSh )
603 : {
604 0 : pSh->CheckBrowseView( false );
605 0 : pSh->GetLayout()->Lower()->InvalidateSize();
606 : }
607 :
608 : // CalcPagesForPrint() should not be necessary here. The pages in the
609 : // visible area will be formatted in SwRootFrm::Paint().
610 : // Removing this gives us a performance gain during saving the
611 : // document because the thumbnail creation will not trigger a complete
612 : // formatting of the document.
613 :
614 610 : pOleOut->Push( PushFlags::CLIPREGION );
615 610 : pOleOut->IntersectClipRegion( aSwRect.SVRect() );
616 610 : pSh->GetLayout()->Paint( aSwRect );
617 :
618 610 : pOleOut->Pop();
619 : // first the CurrShell object needs to be destroyed!
620 : }
621 610 : delete pSh;
622 610 : }
623 :
624 : /// Check if the DocNodesArray contains fields.
625 0 : bool SwViewShell::IsAnyFieldInDoc() const
626 : {
627 : const SfxPoolItem* pItem;
628 0 : sal_uInt32 nMaxItems = mpDoc->GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
629 0 : for( sal_uInt32 n = 0; n < nMaxItems; ++n )
630 : {
631 0 : if( 0 != (pItem = mpDoc->GetAttrPool().GetItem2( RES_TXTATR_FIELD, n )))
632 : {
633 0 : const SwFmtFld* pFmtFld = (SwFmtFld*)pItem;
634 0 : const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
635 0 : if( pTxtFld && pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
636 : {
637 0 : return true;
638 : }
639 : }
640 : }
641 :
642 0 : nMaxItems = mpDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INPUTFIELD );
643 0 : for( sal_uInt32 n = 0; n < nMaxItems; ++n )
644 : {
645 0 : if( 0 != (pItem = mpDoc->GetAttrPool().GetItem2( RES_TXTATR_INPUTFIELD, n )))
646 : {
647 0 : const SwFmtFld* pFmtFld = (SwFmtFld*)pItem;
648 0 : const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
649 0 : if( pTxtFld && pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
650 : {
651 0 : return true;
652 : }
653 : }
654 : }
655 :
656 0 : return false;
657 : }
658 :
659 : /// Saves some settings at the draw view
660 0 : SwDrawViewSave::SwDrawViewSave( SdrView* pSdrView )
661 : : pDV( pSdrView )
662 0 : , bPrintControls(true)
663 : {
664 0 : if ( pDV )
665 : {
666 0 : bPrintControls = pDV->IsLayerPrintable( "Controls" );
667 : }
668 0 : }
669 :
670 0 : SwDrawViewSave::~SwDrawViewSave()
671 : {
672 0 : if ( pDV )
673 : {
674 0 : pDV->SetLayerPrintable( "Controls", bPrintControls );
675 : }
676 0 : }
677 :
678 : // OD 09.01.2003 #i6467# - method also called for page preview
679 610 : void SwViewShell::PrepareForPrint( const SwPrintData &rOptions )
680 : {
681 610 : mpOpt->SetGraphic ( rOptions.bPrintGraphic );
682 610 : mpOpt->SetTable ( rOptions.bPrintTable );
683 610 : mpOpt->SetDraw ( rOptions.bPrintDraw );
684 610 : mpOpt->SetControl ( rOptions.bPrintControl );
685 610 : mpOpt->SetPageBack ( rOptions.bPrintPageBackground );
686 610 : mpOpt->SetBlackFont( rOptions.bPrintBlackFont );
687 :
688 610 : if ( HasDrawView() )
689 : {
690 610 : SdrView *pDrawView = GetDrawView();
691 : // OD 09.01.2003 #i6467# - consider, if view shell belongs to page preview
692 610 : if ( !IsPreview() )
693 : {
694 610 : pDrawView->SetLayerPrintable( "Controls", rOptions.bPrintControl );
695 : }
696 : else
697 : {
698 0 : pDrawView->SetLayerVisible( "Controls", rOptions.bPrintControl );
699 : }
700 : }
701 880 : }
702 :
703 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|