1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 #include <com/sun/star/uno/Sequence.hxx> 32 33 #include <hintids.hxx> 34 #include <vcl/window.hxx> 35 #include <vcl/oldprintadaptor.hxx> 36 #include <sfx2/printer.hxx> 37 #include <sfx2/progress.hxx> 38 #include <pvprtdat.hxx> 39 #include <viewsh.hxx> 40 #include <pagefrm.hxx> 41 #include <rootfrm.hxx> 42 #include <viewimp.hxx> 43 #include <viewopt.hxx> 44 #include <printdata.hxx> 45 #include <fldbas.hxx> 46 #include <ptqueue.hxx> 47 #include <swregion.hxx> 48 #include <hints.hxx> 49 #include <fntcache.hxx> 50 51 #include <statstr.hrc> // Text fuer SfxProgress 52 #include <comcore.hrc> 53 54 #include <IDocumentFieldsAccess.hxx> 55 #include <IDocumentDeviceAccess.hxx> 56 57 58 using namespace ::com::sun::star; 59 60 61 // OD 12.12.2002 #103492# 62 SwPagePreviewLayout* ViewShell::PagePreviewLayout() 63 { 64 return Imp()->PagePreviewLayout(); 65 } 66 67 void ViewShell::ShowPreViewSelection( sal_uInt16 nSelPage ) 68 { 69 Imp()->InvalidateAccessiblePreViewSelection( nSelPage ); 70 } 71 72 /** adjust view options for page preview 73 74 OD 09.01.2003 #i6467# 75 */ 76 void ViewShell::AdjustOptionsForPagePreview(SwPrintData const& rPrintOptions) 77 { 78 if ( !IsPreView() ) 79 { 80 ASSERT( false, "view shell doesn't belongs to a page preview - no adjustment of its view options"); 81 return; 82 } 83 84 PrepareForPrint( rPrintOptions ); 85 86 return; 87 } 88 89 // print brochure 90 // OD 05.05.2003 #i14016# - consider empty pages on calculation of the scaling 91 // for a page to be printed. 92 void ViewShell::PrintProspect( 93 OutputDevice *pOutDev, 94 const SwPrintData &rPrintData, 95 sal_Int32 nRenderer // the index in the vector of prospect pages to be printed 96 ) 97 { 98 const sal_Int32 nMaxRenderer = rPrintData.GetRenderData().GetPagePairsForProspectPrinting().size() - 1; 99 #if OSL_DEBUG_LEVEL > 1 100 DBG_ASSERT( 0 <= nRenderer && nRenderer <= nMaxRenderer, "nRenderer out of bounds"); 101 #endif 102 Printer *pPrinter = dynamic_cast< Printer * >(pOutDev); 103 if (!pPrinter || nMaxRenderer < 0 || nRenderer < 0 || nRenderer > nMaxRenderer) 104 return; 105 106 // save settings of OutputDevice (should be done always since the 107 // output device is now provided by a call from outside the Writer) 108 pPrinter->Push(); 109 110 std::pair< sal_Int32, sal_Int32 > rPagesToPrint = 111 rPrintData.GetRenderData().GetPagePairsForProspectPrinting()[ nRenderer ]; 112 // const sal_uInt16 nPageMax = static_cast< sal_uInt16 >(rPagesToPrint.first > rPagesToPrint.second ? 113 // rPagesToPrint.first : rPagesToPrint.second); 114 #if OSL_DEBUG_LEVEL > 1 115 DBG_ASSERT( rPagesToPrint.first == -1 || rPrintData.GetRenderData().GetValidPagesSet().count( rPagesToPrint.first ) == 1, "first Page not valid" ); 116 DBG_ASSERT( rPagesToPrint.second == -1 || rPrintData.GetRenderData().GetValidPagesSet().count( rPagesToPrint.second ) == 1, "second Page not valid" ); 117 #endif 118 119 // eine neue Shell fuer den Printer erzeugen 120 ViewShell aShell( *this, 0, pPrinter ); 121 122 SET_CURR_SHELL( &aShell ); 123 124 aShell.PrepareForPrint( rPrintData ); 125 126 //!! applying view options and formatting the dcoument should now only be done in getRendererCount! 127 128 MapMode aMapMode( MAP_TWIP ); 129 Size aPrtSize( pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), aMapMode ) ); 130 131 SwTwips nMaxRowSz, nMaxColSz; 132 133 const SwPageFrm *pStPage = 0; 134 const SwPageFrm *pNxtPage = 0; 135 const SwRenderData::ValidStartFramesMap_t &rFrms = rPrintData.GetRenderData().GetValidStartFrames(); 136 if (rPagesToPrint.first > 0) 137 { 138 SwRenderData::ValidStartFramesMap_t::const_iterator aIt( rFrms.find( rPagesToPrint.first ) ); 139 DBG_ASSERT( aIt != rFrms.end(), "failed to find start frame" ); 140 pStPage = aIt->second; 141 } 142 if (rPagesToPrint.second > 0) 143 { 144 SwRenderData::ValidStartFramesMap_t::const_iterator aIt( rFrms.find( rPagesToPrint.second ) ); 145 DBG_ASSERT( aIt != rFrms.end(), "failed to find start frame" ); 146 pNxtPage = aIt->second; 147 } 148 149 // OD 05.05.2003 #i14016# - consider empty pages on calculation 150 // of page size, used for calculation of scaling. 151 Size aSttPageSize; 152 if ( pStPage ) 153 { 154 if ( pStPage->IsEmptyPage() ) 155 { 156 if ( pStPage->GetPhyPageNum() % 2 == 0 ) 157 aSttPageSize = pStPage->GetPrev()->Frm().SSize(); 158 else 159 aSttPageSize = pStPage->GetNext()->Frm().SSize(); 160 } 161 else 162 { 163 aSttPageSize = pStPage->Frm().SSize(); 164 } 165 } 166 Size aNxtPageSize; 167 if ( pNxtPage ) 168 { 169 if ( pNxtPage->IsEmptyPage() ) 170 { 171 if ( pNxtPage->GetPhyPageNum() % 2 == 0 ) 172 aNxtPageSize = pNxtPage->GetPrev()->Frm().SSize(); 173 else 174 aNxtPageSize = pNxtPage->GetNext()->Frm().SSize(); 175 } 176 else 177 { 178 aNxtPageSize = pNxtPage->Frm().SSize(); 179 } 180 } 181 182 if( !pStPage ) 183 { 184 nMaxColSz = 2 * aNxtPageSize.Width(); 185 nMaxRowSz = aNxtPageSize.Height(); 186 } 187 else if( !pNxtPage ) 188 { 189 nMaxColSz = 2 * aSttPageSize.Width(); 190 nMaxRowSz = aSttPageSize.Height(); 191 } 192 else 193 { 194 nMaxColSz = aNxtPageSize.Width() + aSttPageSize.Width(); 195 nMaxRowSz = Max( aNxtPageSize.Height(), aSttPageSize.Height() ); 196 } 197 198 // den MapMode einstellen 199 aMapMode.SetOrigin( Point() ); 200 { 201 Fraction aScX( aPrtSize.Width(), nMaxColSz ); 202 Fraction aScY( aPrtSize.Height(), nMaxRowSz ); 203 if( aScX < aScY ) 204 aScY = aScX; 205 206 { 207 // fuer Drawing, damit diese ihre Objecte vernuenftig Painten 208 // koennen, auf "glatte" Prozentwerte setzen 209 aScY *= Fraction( 1000, 1 ); 210 long nTmp = (long)aScY; 211 if( 1 < nTmp ) 212 --nTmp; 213 else 214 nTmp = 1; 215 aScY = Fraction( nTmp, 1000 ); 216 } 217 218 aMapMode.SetScaleY( aScY ); 219 aMapMode.SetScaleX( aScY ); 220 } 221 222 Size aTmpPrtSize( pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), aMapMode ) ); 223 224 // calculate start point for equal border on all sides 225 Point aSttPt( (aTmpPrtSize.Width() - nMaxColSz) / 2, 226 (aTmpPrtSize.Height() - nMaxRowSz) / 2 ); 227 for( int nC = 0; nC < 2; ++nC ) 228 { 229 if( pStPage ) 230 { 231 aShell.Imp()->SetFirstVisPageInvalid(); 232 aShell.aVisArea = pStPage->Frm(); 233 234 Point aPos( aSttPt ); 235 aPos -= aShell.aVisArea.Pos(); 236 // aPos -= aPrtOff; 237 aMapMode.SetOrigin( aPos ); 238 pPrinter->SetMapMode( aMapMode ); 239 pStPage->GetUpper()->Paint( pStPage->Frm() ); 240 } 241 242 pStPage = pNxtPage; 243 aSttPt.X() += aTmpPrtSize.Width() / 2; 244 } 245 246 SwPaintQueue::Repaint(); 247 248 //!! applying/modifying view options and formatting the dcoument should now only be done in getRendererCount! 249 250 pFntCache->Flush(); 251 252 // restore settings of OutputDevice (should be done always now since the 253 // output device is now provided by a call from outside the Writer) 254 pPrinter->Pop(); 255 } 256 257 258