update dev300-m58
[ooovba.git] / sw / source / core / view / viewpg.cxx
bloba3c3482a8e0bc2b82112d87fa37e65182e44c2a4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewpg.cxx,v $
10 * $Revision: 1.31 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <vcl/window.hxx>
37 #include <sfx2/printer.hxx>
38 #include <sfx2/progress.hxx>
39 #include <pvprtdat.hxx>
40 #include <viewsh.hxx>
41 #include <pagefrm.hxx>
42 #include <rootfrm.hxx>
43 #include <viewimp.hxx>
44 #include <viewopt.hxx>
45 #include <swprtopt.hxx> // SwPrtOptions
46 #include <fldbas.hxx>
47 #include <ptqueue.hxx>
48 #include <swregion.hxx>
49 #include <hints.hxx>
50 #include <fntcache.hxx>
52 #ifndef _STATSTR_HRC
53 #include <statstr.hrc> // Text fuer SfxProgress
54 #endif
55 #ifndef _COMCORE_HRC
56 #include <comcore.hrc>
57 #endif
59 #include <IDocumentFieldsAccess.hxx>
60 #include <IDocumentDeviceAccess.hxx>
62 // OD 12.12.2002 #103492#
63 SwPagePreviewLayout* ViewShell::PagePreviewLayout()
65 return Imp()->PagePreviewLayout();
68 void ViewShell::ShowPreViewSelection( sal_uInt16 nSelPage )
70 Imp()->InvalidateAccessiblePreViewSelection( nSelPage );
73 /** adjust view options for page preview
75 OD 09.01.2003 #i6467#
77 void ViewShell::AdjustOptionsForPagePreview( const SwPrtOptions &_rPrintOptions )
79 if ( !IsPreView() )
81 ASSERT( false, "view shell doesn't belongs to a page preview - no adjustment of its view options");
82 return;
85 PrepareForPrint( _rPrintOptions );
87 return;
90 // output print preview on printer
91 // OD 05.05.2003 #i14016# - consider empty pages on calculation of scaling
92 // and on calculation of paint offset.
93 void ViewShell::PrintPreViewPage( SwPrtOptions& rOptions,
94 USHORT nRowCol, SfxProgress& rProgress,
95 const SwPagePreViewPrtData* pPrtData )
97 if( !rOptions.aMulti.GetSelectCount() )
98 return;
100 // wenn kein Drucker vorhanden ist, wird nicht gedruckt
101 SfxPrinter* pPrt = getIDocumentDeviceAccess()->getPrinter(false);
102 if( !pPrt || !pPrt->GetName().Len() )
103 return;
105 // schoen waers gewesen !!! const MultiSelection& rMulti = rOptions.aMulti;
106 MultiSelection aMulti( rOptions.aMulti );
107 Range aPages( aMulti.FirstSelected(), aMulti.LastSelected() );
108 if ( aPages.Max() > USHRT_MAX )
109 aPages.Max() = USHRT_MAX;
111 ASSERT( aPages.Min() > 0,
112 "Seite 0 Drucken?" );
113 ASSERT( aPages.Min() <= aPages.Max(),
114 "MinSeite groesser MaxSeite." );
116 // eine neue Shell fuer den Printer erzeugen
117 ViewShell aShell( *this, 0 );
118 if ( &GetRefDev() == pPrt )
119 aShell.mpTmpRef = new SfxPrinter( *pPrt );
121 SET_CURR_SHELL( &aShell );
123 aShell.PrepareForPrint( rOptions );
125 // gibt es versteckte Absatzfelder, unnoetig wenn die Absaetze bereits
126 // ausgeblendet sind.
127 int bHiddenFlds = FALSE;
128 SwFieldType* pFldType = 0;
129 if ( GetViewOptions()->IsShowHiddenPara() )
131 pFldType = getIDocumentFieldsAccess()->GetSysFldType( RES_HIDDENPARAFLD );
132 bHiddenFlds = 0 != pFldType->GetDepends();
133 if( bHiddenFlds )
135 SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
136 pFldType->Modify( &aHnt, 0);
140 // Seiten fuers Drucken formatieren
141 aShell.CalcPagesForPrint( (USHORT)aPages.Max(), &rProgress );
143 USHORT nCopyCnt = rOptions.bCollate ? rOptions.nCopyCount : 1;
144 BOOL bStartJob = FALSE;
146 const bool bPrintEmptyPages = rOptions.IsPrintEmptyPages();
148 for ( USHORT nCnt = 0; nCnt < nCopyCnt; nCnt++ )
150 if( rOptions.IsPrintSingleJobs() && rOptions.GetJobName().Len() &&
151 ( bStartJob || rOptions.bJobStartet ) )
153 pPrt->EndJob();
154 rOptions.bJobStartet = TRUE;
156 // Reschedule statt Yield, da Yield keine Events abarbeitet
157 // und es sonst eine Endlosschleife gibt.
158 while( pPrt->IsPrinting() )
159 rProgress.Reschedule();
161 rOptions.MakeNextJobName();
162 bStartJob = pPrt->StartJob( rOptions.GetJobName() );
165 const SwPageFrm *pStPage = (SwPageFrm*)GetLayout()->Lower();
166 const SwFrm *pEndPage = pStPage;
167 USHORT i;
169 for( i = 1; pStPage && i < (USHORT)aPages.Min(); ++i )
170 pStPage = (SwPageFrm*)pStPage->GetNext();
172 if( !pStPage ) // dann wars das
174 if( bHiddenFlds )
176 SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
177 pFldType->Modify( &aHnt, 0);
178 CalcPagesForPrint( (USHORT)aPages.Max() );
180 return;
183 // unsere SttPage haben wir, dann die EndPage suchen
184 USHORT nFirstPageNo = i;
185 USHORT nLastPageNo = i;
186 USHORT nPageNo = 1;
188 pEndPage = pStPage;
190 if( pStPage->GetNext() && (i != (USHORT)aPages.Max()) )
192 pEndPage = pEndPage->GetNext();
193 for( ++i,++nLastPageNo;
194 pEndPage->GetNext() && i < (USHORT)aPages.Max(); ++i )
196 pEndPage = pEndPage->GetNext();
197 ++nLastPageNo;
201 if( rOptions.bPrintReverse )
203 const SwFrm *pTmp = pStPage;
204 pStPage = (SwPageFrm*)pEndPage;
205 pEndPage = pTmp;
206 nPageNo = nLastPageNo;
208 else
209 nPageNo = nFirstPageNo;
211 // ein Array fuer die Seiten anlegen, die auf eine Drucker-Seite
212 // gedruckt werden sollen.
213 BYTE nRow = BYTE(nRowCol >> 8), nCol = BYTE(nRowCol & 0xff);
214 USHORT nPages = nRow * nCol;
215 SwPageFrm** aPageArr = new SwPageFrm* [ nPages ];
216 memset( aPageArr, 0, sizeof( SwPageFrm* ) * nPages );
217 USHORT nCntPage = 0;
219 SwTwips nCalcW = 0, nCalcH = 0, nMaxRowSz = 0, nMaxColSz = 0;
221 MapMode aOld( pPrt->GetMapMode() );
222 MapMode aMapMode( MAP_TWIP );
223 Size aPrtSize( pPrt->PixelToLogic( pPrt->GetPaperSizePixel(), aMapMode ));
224 if( pPrtData )
226 aPrtSize.Width() -= pPrtData->GetLeftSpace() +
227 pPrtData->GetRightSpace() +
228 ( pPrtData->GetHorzSpace() * (nCol - 1));
229 aPrtSize.Height() -= pPrtData->GetTopSpace() +
230 pPrtData->GetBottomSpace() +
231 ( pPrtData->GetVertSpace() * (nRow - 1));
234 aMulti.Select( Range( nLastPageNo+1, USHRT_MAX ), FALSE );
235 USHORT nSelCount = USHORT((aMulti.GetSelectCount()+nPages-1) / nPages);
236 nSelCount = nSelCount * nCopyCnt;
237 USHORT nPrintCount = 1;
239 const XubString aTmp( SW_RES( STR_STATSTR_PRINT ) );
240 rProgress.SetText( aTmp );
241 //HACK, damit die Anzeige nicht durcheinander kommt:
242 rProgress.SetState( 1, nSelCount );
243 rProgress.SetText( aTmp );
244 bStartJob = TRUE;
246 while( pStPage )
248 // Mag der Anwender noch ?
249 rProgress.Reschedule();
251 if ( !pPrt->IsJobActive() )
252 break;
254 // --> FME 2005-12-12 #b6354161# Feature - Print empty pages
255 // --> OD 2007-10-22 #i79738# - correct condition:
256 // always consider, if page is selected for print.
257 if( aMulti.IsSelected( nPageNo ) &&
258 ( bPrintEmptyPages || !pStPage->IsEmptyPage() ) )
259 // <--
261 if( rOptions.bPrintReverse )
262 aPageArr[ nPages - ++nCntPage ] = (SwPageFrm*)pStPage;
263 else
264 aPageArr[ nCntPage++ ] = (SwPageFrm*)pStPage;
266 // OD 05.05.2003 #i14016# - consider empty pages on calculation
267 // of page size, used for calculation of scaling.
268 Size aPageSize;
269 if ( pStPage->IsEmptyPage() )
271 if ( pStPage->GetPhyPageNum() % 2 == 0 )
272 aPageSize = pStPage->GetPrev()->Frm().SSize();
273 else
274 aPageSize = pStPage->GetNext()->Frm().SSize();
276 else
278 aPageSize = pStPage->Frm().SSize();
280 nCalcW += aPageSize.Width();
281 if( nCalcH < aPageSize.Height() )
282 nCalcH = aPageSize.Height();
284 if( 0 == (nCntPage % nCol ) || // neue Zeile
285 nCntPage == nPages || pStPage == pEndPage )
287 // sollte die Seite nicht gefuellt sein, so erweiter
288 // anhand der letzen Seite. Dadurch hat auch die
289 // letze Seite die richtigen Spalten/Reihen.
290 // BUG: 17695
291 if( pStPage == pEndPage && nCntPage != nPages )
293 // dann Werte mit der letzen Seite auffuellen
294 if( nCntPage < nCol )
295 nCalcW += aPageSize.Width() * (nCol - nCntPage);
297 BYTE nRows = (BYTE) ( nCntPage / nCol + 1 );
298 if( nRows < nRow )
299 nCalcH += ( nRow - nRows ) * nCalcH;
302 if( nMaxColSz < nCalcW )
303 nMaxColSz = nCalcW;
304 nCalcW = 0;
305 nMaxRowSz += nCalcH;
308 if( nCntPage == nPages || pStPage == pEndPage )
310 // den MapMode einstellen
311 aMapMode.SetOrigin( Point() );
313 Fraction aScX( aPrtSize.Width(), nMaxColSz );
314 Fraction aScY( aPrtSize.Height(), nMaxRowSz );
317 if( aScX < aScY )
318 aScY = aScX;
320 // fuer Drawing, damit diese ihre Objecte vernuenftig Painten
321 // koennen, auf "glatte" Prozentwerte setzen
322 aScY *= Fraction( 1000, 1 );
323 long nTmp = (long)aScY;
324 if( 1 < nTmp )
325 --nTmp;
326 else
327 nTmp = 1;
328 aScY = Fraction( nTmp, 1000 );
329 aScX = aScY;
332 aMapMode.SetScaleY( aScY );
333 aMapMode.SetScaleX( aScX );
336 Point aPrtOff( pPrt->PixelToLogic(
337 pPrt->GetPageOffsetPixel(), aMapMode ) );
338 long nPageHeight = (nMaxRowSz / nRow);
340 // dann kann das drucken losgehen
341 rProgress.SetState( nPrintCount++, nSelCount );
343 pPrt->StartPage();
344 Point aCalcPt;
345 SwPageFrm** ppTmpPg = aPageArr;
347 // ist das Array nicht vollsteandig gefuellt ?
348 if( rOptions.bPrintReverse && nCntPage != nPages )
350 // beim Rueckwaertsdruck alle Seiten nach vorne
351 // verschieben!
352 memmove( ppTmpPg, ppTmpPg + (nPages - nCntPage),
353 nCntPage * sizeof( SwPageFrm*) );
354 aPageArr[ nCntPage ] = 0; // Endekennung
357 long nHOffs = 0, nVOffs = 0, nXStt = 0;
358 if( pPrtData )
360 const Fraction& rScaleX = aMapMode.GetScaleX();
361 const Fraction& rScaleY = aMapMode.GetScaleY();
362 Fraction aF( pPrtData->GetTopSpace(), 1 );
363 aCalcPt.Y() = aF /= rScaleY;
364 aF = Fraction( pPrtData->GetLeftSpace(), 1 );
365 nXStt = aF /= rScaleX;
366 aF = Fraction( pPrtData->GetVertSpace(), 1 );
367 nVOffs = aF /= rScaleY;
368 aF = Fraction( pPrtData->GetHorzSpace(), 1 );
369 nHOffs = aF /= rScaleX;
372 for( BYTE nR = 0; *ppTmpPg && nR < nRow; ++nR )
374 aCalcPt.X() = nXStt;
375 for( BYTE nC = 0; *ppTmpPg && nC < nCol; ++nC )
377 aShell.Imp()->SetFirstVisPageInvalid();
378 aShell.aVisArea = (*ppTmpPg)->Frm();
380 Point aPos( aCalcPt );
381 aPos -= aShell.aVisArea.Pos();
382 aPos -= aPrtOff;
383 aMapMode.SetOrigin( aPos );
384 pPrt->SetMapMode( aMapMode );
385 (*ppTmpPg)->GetUpper()->Paint( (*ppTmpPg)->Frm() );
386 // OD 05.05.2003 #i14016# - consider empty pages
387 // on calculation of the paint offset for the next page.
388 aCalcPt.X() += nHOffs;
389 if ( (*ppTmpPg)->IsEmptyPage() )
391 if ( (*ppTmpPg)->GetPhyPageNum() % 2 == 0 )
392 aCalcPt.X() += (*ppTmpPg)->GetPrev()->Frm().SSize().Width();
393 else
394 aCalcPt.X() += (*ppTmpPg)->GetNext()->Frm().SSize().Width();
396 else
398 aCalcPt.X() += (*ppTmpPg)->Frm().Width();
400 ++ppTmpPg;
402 aCalcPt.Y() += nVOffs + nPageHeight;
404 pPrt->EndPage();
405 SwPaintQueue::Repaint();
407 memset( aPageArr, 0, sizeof( SwPageFrm* ) * nPages );
408 nCntPage = 0;
409 nMaxRowSz = nMaxColSz = nCalcH = nCalcW = 0;
413 if( pStPage == pEndPage )
414 pStPage = 0;
415 else if( rOptions.bPrintReverse )
417 --nPageNo;
418 pStPage = (SwPageFrm*)pStPage->GetPrev();
420 else
422 ++nPageNo;
423 pStPage = (SwPageFrm*)pStPage->GetNext();
426 pPrt->SetMapMode( aOld );
428 if( bHiddenFlds )
430 SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
431 pFldType->Modify( &aHnt, 0);
432 CalcPagesForPrint( (USHORT)aPages.Max() );
434 delete[] aPageArr;
436 if( bStartJob )
437 rOptions.bJobStartet = TRUE;
439 pFntCache->Flush();
442 // print brochure
443 // OD 05.05.2003 #i14016# - consider empty pages on calculation of the scaling
444 // for a page to be printed.
445 void ViewShell::PrintProspect( SwPrtOptions& rOptions,
446 SfxProgress& rProgress , BOOL bRTL)
448 if( !rOptions.aMulti.GetSelectCount() )
449 return;
451 // wenn kein Drucker vorhanden ist, wird nicht gedruckt
452 SfxPrinter* pPrt = getIDocumentDeviceAccess()->getPrinter(false);
453 if( !pPrt || !pPrt->GetName().Len() ||
454 ( !rOptions.bPrintLeftPage && !rOptions.bPrintRightPage ))
455 return;
457 MultiSelection aMulti( rOptions.aMulti );
458 Range aPages( aMulti.FirstSelected(), aMulti.LastSelected() );
459 if ( aPages.Max() > USHRT_MAX )
460 aPages.Max() = USHRT_MAX;
462 ASSERT( aPages.Min() > 0,
463 "Seite 0 Drucken?" );
464 ASSERT( aPages.Min() <= aPages.Max(),
465 "MinSeite groesser MaxSeite." );
467 // eine neue Shell fuer den Printer erzeugen
468 ViewShell aShell( *this, 0 );
469 if ( &GetRefDev() == pPrt )
470 aShell.mpTmpRef = new SfxPrinter( *pPrt );
472 SET_CURR_SHELL( &aShell );
474 aShell.PrepareForPrint( rOptions );
476 // gibt es versteckte Absatzfelder, unnoetig wenn die Absaetze bereits
477 // ausgeblendet sind.
478 int bHiddenFlds = FALSE;
479 SwFieldType* pFldType = 0;
480 if ( GetViewOptions()->IsShowHiddenPara() )
482 pFldType = getIDocumentFieldsAccess()->GetSysFldType( RES_HIDDENPARAFLD );
483 bHiddenFlds = 0 != pFldType->GetDepends();
484 if( bHiddenFlds )
486 SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
487 pFldType->Modify( &aHnt, 0);
491 // Seiten fuers Drucken formatieren
492 aShell.CalcPagesForPrint( (USHORT)aPages.Max(), &rProgress );
494 USHORT nCopyCnt = rOptions.bCollate ? rOptions.nCopyCount : 1;
496 const SwPageFrm *pStPage = (SwPageFrm*)GetLayout()->Lower();
497 USHORT i;
499 for( i = 1; pStPage && i < (USHORT)aPages.Min(); ++i )
500 pStPage = (SwPageFrm*)pStPage->GetNext();
502 if( !pStPage ) // dann wars das
504 if( bHiddenFlds )
506 SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
507 pFldType->Modify( &aHnt, 0);
508 CalcPagesForPrint( (USHORT)aPages.Max() );
510 return;
513 // unsere SttPage haben wir, dann die EndPage suchen
514 SvPtrarr aArr( 255, 255 );
515 aArr.Insert( (void*)pStPage, aArr.Count() );
517 while( pStPage->GetNext() && i < (USHORT)aPages.Max() )
519 pStPage = (SwPageFrm*)pStPage->GetNext();
520 if( aMulti.IsSelected( ++i ) )
521 aArr.Insert( (void*)pStPage, aArr.Count() );
524 // auf Doppelseiten auffuellen
525 if( 1 == aArr.Count() ) // eine Seite ist ein Sonderfall
526 aArr.Insert( (void*)0, 1 );
527 else
529 while( aArr.Count() & 3 )
530 aArr.Insert( (void*)0, aArr.Count() );
532 if( rOptions.bPrintReverse && 4 < aArr.Count() )
534 // das Array umsortieren
535 // Array: 1 2 3 4 5 6 7 8
536 // soll: 3 4 1 2 7 8 5 6
537 // Algorhytmus:
538 // vordere Haelfte: Austausch von 2 Pointer von Vorne vor die Haelfte
539 // hintere Haelfte: Austausch von 2 Pointer von der Haelfte nach hinten
541 USHORT nHalf = aArr.Count() / 2;
542 USHORT nSwapCount = nHalf / 4;
544 VoidPtr* ppArrStt = (VoidPtr*)aArr.GetData();
545 VoidPtr* ppArrHalf = (VoidPtr*)aArr.GetData() + nHalf;
547 for( int nLoop = 0; nLoop < 2; ++nLoop )
549 for( USHORT n = 0; n < nSwapCount; ++n )
551 void* pTmp = *ppArrStt;
552 *ppArrStt++ = *(ppArrHalf-2);
553 *(ppArrHalf-2) = pTmp;
555 pTmp = *ppArrStt;
556 *ppArrStt++ = *--ppArrHalf;
557 *ppArrHalf-- = pTmp;
559 ppArrStt = (VoidPtr*)aArr.GetData() + nHalf;
560 ppArrHalf = (VoidPtr*)aArr.GetData() + aArr.Count();
565 BOOL bStartJob = FALSE;
567 for( USHORT nCnt = 0; nCnt < nCopyCnt; nCnt++ )
569 if( rOptions.IsPrintSingleJobs() && rOptions.GetJobName().Len() &&
570 ( bStartJob || rOptions.bJobStartet ) )
572 pPrt->EndJob();
573 rOptions.bJobStartet = TRUE;
575 // Reschedule statt Yield, da Yield keine Events abarbeitet
576 // und es sonst eine Endlosschleife gibt.
577 while( pPrt->IsPrinting() )
578 rProgress.Reschedule();
580 rOptions.MakeNextJobName();
581 bStartJob = pPrt->StartJob( rOptions.GetJobName() );
584 // dann sorge mal dafuer, das alle Seiten in der richtigen
585 // Reihenfolge stehen:
586 USHORT nSPg = 0, nEPg = aArr.Count(), nStep = 1;
587 if( 0 == (nEPg & 1 )) // ungerade gibt es nicht!
588 --nEPg;
590 if( !rOptions.bPrintLeftPage )
591 ++nStep;
592 else if( !rOptions.bPrintRightPage )
594 ++nStep;
595 ++nSPg, --nEPg;
598 USHORT nCntPage = (( nEPg - nSPg ) / ( 2 * nStep )) + 1;
600 MapMode aOld( pPrt->GetMapMode() );
601 MapMode aMapMode( MAP_TWIP );
602 Size aPrtSize( pPrt->PixelToLogic( pPrt->GetPaperSizePixel(), aMapMode ) );
604 const XubString aTmp( SW_RES( STR_STATSTR_PRINT ) );
605 rProgress.SetText( aTmp );
606 //HACK, damit die Anzeige nicht durcheinander kommt:
607 rProgress.SetState( 1, nCntPage );
608 rProgress.SetText( aTmp );
610 for( USHORT nPrintCount = 0; nSPg < nEPg &&
611 nPrintCount < nCntPage; ++nPrintCount )
613 // Mag der Anwender noch ?
614 rProgress.Reschedule();
616 if ( !pPrt->IsJobActive() )
617 break;
619 SwTwips nMaxRowSz, nMaxColSz;
620 pStPage = (SwPageFrm*)aArr[ nSPg ];
621 const SwPageFrm* pNxtPage = nEPg < aArr.Count()
622 ? (SwPageFrm*)aArr[ nEPg ]
623 : 0;
625 // OD 05.05.2003 #i14016# - consider empty pages on calculation
626 // of page size, used for calculation of scaling.
627 Size aSttPageSize;
628 if ( pStPage )
630 if ( pStPage->IsEmptyPage() )
632 if ( pStPage->GetPhyPageNum() % 2 == 0 )
633 aSttPageSize = pStPage->GetPrev()->Frm().SSize();
634 else
635 aSttPageSize = pStPage->GetNext()->Frm().SSize();
637 else
639 aSttPageSize = pStPage->Frm().SSize();
642 Size aNxtPageSize;
643 if ( pNxtPage )
645 if ( pNxtPage->IsEmptyPage() )
647 if ( pNxtPage->GetPhyPageNum() % 2 == 0 )
648 aNxtPageSize = pNxtPage->GetPrev()->Frm().SSize();
649 else
650 aNxtPageSize = pNxtPage->GetNext()->Frm().SSize();
652 else
654 aNxtPageSize = pNxtPage->Frm().SSize();
658 if( !pStPage )
660 nMaxColSz = 2 * aNxtPageSize.Width();
661 nMaxRowSz = aNxtPageSize.Height();
663 else if( !pNxtPage )
665 nMaxColSz = 2 * aSttPageSize.Width();
666 nMaxRowSz = aSttPageSize.Height();
668 else
670 nMaxColSz = aNxtPageSize.Width() +
671 aSttPageSize.Width();
672 nMaxRowSz = Max( aNxtPageSize.Height(),
673 aSttPageSize.Height() );
676 short nRtlOfs = bRTL ? 1 : 0;
677 if( 0 == (( nSPg + nRtlOfs) & 1 ) ) // switch for odd number in LTR, even number in RTL
679 const SwPageFrm* pTmp = pStPage;
680 pStPage = pNxtPage;
681 pNxtPage = pTmp;
684 // den MapMode einstellen
685 aMapMode.SetOrigin( Point() );
687 Fraction aScX( aPrtSize.Width(), nMaxColSz );
688 Fraction aScY( aPrtSize.Height(), nMaxRowSz );
689 if( aScX < aScY )
690 aScY = aScX;
693 // fuer Drawing, damit diese ihre Objecte vernuenftig Painten
694 // koennen, auf "glatte" Prozentwerte setzen
695 aScY *= Fraction( 1000, 1 );
696 long nTmp = (long)aScY;
697 if( 1 < nTmp )
698 --nTmp;
699 else
700 nTmp = 1;
701 aScY = Fraction( nTmp, 1000 );
704 aMapMode.SetScaleY( aScY );
705 aMapMode.SetScaleX( aScY );
708 Point aPrtOff( pPrt->PixelToLogic(
709 pPrt->GetPageOffsetPixel(), aMapMode ) );
710 Size aTmpPrtSize( pPrt->PixelToLogic(
711 pPrt->GetPaperSizePixel(), aMapMode ) );
713 // dann kann das drucken losgehen
714 bStartJob = TRUE;
715 rProgress.SetState( nPrintCount, nCntPage );
717 pPrt->StartPage();
719 Point aSttPt;
720 for( int nC = 0; nC < 2; ++nC )
722 if( pStPage )
724 aShell.Imp()->SetFirstVisPageInvalid();
725 aShell.aVisArea = pStPage->Frm();
727 Point aPos( aSttPt );
728 aPos -= aShell.aVisArea.Pos();
729 aPos -= aPrtOff;
730 aMapMode.SetOrigin( aPos );
731 pPrt->SetMapMode( aMapMode );
732 pStPage->GetUpper()->Paint( pStPage->Frm() );
735 pStPage = pNxtPage;
736 aSttPt.X() += aTmpPrtSize.Width() / 2;
739 pPrt->EndPage();
740 SwPaintQueue::Repaint();
741 nSPg = nSPg + nStep;
742 nEPg = nEPg - nStep;
744 pPrt->SetMapMode( aOld );
746 if( bHiddenFlds )
748 SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
749 pFldType->Modify( &aHnt, 0);
750 CalcPagesForPrint( (USHORT)aPages.Max() );
753 if( bStartJob )
754 rOptions.bJobStartet = TRUE;
756 pFntCache->Flush();