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_sc.hxx" 30 31 32 33 // INCLUDE --------------------------------------------------------------- 34 35 #include <tools/multisel.hxx> 36 37 #include "pfuncache.hxx" 38 #include "printfun.hxx" 39 #include "docsh.hxx" 40 #include "markdata.hxx" 41 #include "prevloc.hxx" 42 43 //------------------------------------------------------------------------ 44 45 ScPrintFuncCache::ScPrintFuncCache( ScDocShell* pD, const ScMarkData& rMark, 46 const ScPrintSelectionStatus& rStatus ) : 47 aSelection( rStatus ), 48 pDocSh( pD ), 49 nTotalPages( 0 ), 50 bLocInitialized( false ) 51 { 52 // page count uses the stored cell widths for the printer anyway, 53 // so ScPrintFunc with the document's printer can be used to count 54 55 SfxPrinter* pPrinter = pDocSh->GetPrinter(); 56 57 ScRange aRange; 58 const ScRange* pSelRange = NULL; 59 if ( rMark.IsMarked() ) 60 { 61 rMark.GetMarkArea( aRange ); 62 pSelRange = &aRange; 63 } 64 65 ScDocument* pDoc = pDocSh->GetDocument(); 66 SCTAB nTabCount = pDoc->GetTableCount(); 67 68 // avoid repeated progress bars if row heights for all sheets are needed 69 if ( nTabCount > 1 && rMark.GetSelectCount() == nTabCount ) 70 pDocSh->UpdatePendingRowHeights( nTabCount-1, true ); 71 72 SCTAB nTab; 73 for ( nTab=0; nTab<nTabCount; nTab++ ) 74 { 75 long nAttrPage = nTab > 0 ? nFirstAttr[nTab-1] : 1; 76 77 long nThisTab = 0; 78 if ( rMark.GetTableSelect( nTab ) ) 79 { 80 ScPrintFunc aFunc( pDocSh, pPrinter, nTab, nAttrPage, 0, pSelRange, &aSelection.GetOptions() ); 81 nThisTab = aFunc.GetTotalPages(); 82 nFirstAttr[nTab] = aFunc.GetFirstPageNo(); // from page style or previous sheet 83 } 84 else 85 nFirstAttr[nTab] = nAttrPage; 86 87 nPages[nTab] = nThisTab; 88 nTotalPages += nThisTab; 89 } 90 } 91 92 ScPrintFuncCache::~ScPrintFuncCache() 93 { 94 } 95 96 void ScPrintFuncCache::InitLocations( const ScMarkData& rMark, OutputDevice* pDev ) 97 { 98 if ( bLocInitialized ) 99 return; // initialize only once 100 101 ScRange aRange; 102 const ScRange* pSelRange = NULL; 103 if ( rMark.IsMarked() ) 104 { 105 rMark.GetMarkArea( aRange ); 106 pSelRange = &aRange; 107 } 108 109 long nRenderer = 0; // 0-based physical page number across sheets 110 long nTabStart = 0; 111 112 ScDocument* pDoc = pDocSh->GetDocument(); 113 SCTAB nTabCount = pDoc->GetTableCount(); 114 for ( SCTAB nTab=0; nTab<nTabCount; nTab++ ) 115 { 116 if ( rMark.GetTableSelect( nTab ) ) 117 { 118 ScPrintFunc aFunc( pDev, pDocSh, nTab, nFirstAttr[nTab], nTotalPages, pSelRange, &aSelection.GetOptions() ); 119 aFunc.SetRenderFlag( sal_True ); 120 121 long nDisplayStart = GetDisplayStart( nTab ); 122 123 for ( long nPage=0; nPage<nPages[nTab]; nPage++ ) 124 { 125 Range aPageRange( nRenderer+1, nRenderer+1 ); 126 MultiSelection aPage( aPageRange ); 127 aPage.SetTotalRange( Range(0,RANGE_MAX) ); 128 aPage.Select( aPageRange ); 129 130 ScPreviewLocationData aLocData( pDoc, pDev ); 131 aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, &aLocData ); 132 133 ScRange aCellRange; 134 Rectangle aPixRect; 135 if ( aLocData.GetMainCellRange( aCellRange, aPixRect ) ) 136 aLocations.push_back( ScPrintPageLocation( nRenderer, aCellRange, aPixRect ) ); 137 138 ++nRenderer; 139 } 140 141 nTabStart += nPages[nTab]; 142 } 143 } 144 145 bLocInitialized = true; 146 } 147 148 bool ScPrintFuncCache::FindLocation( const ScAddress& rCell, ScPrintPageLocation& rLocation ) const 149 { 150 for ( std::vector<ScPrintPageLocation>::const_iterator aIter(aLocations.begin()); 151 aIter != aLocations.end(); aIter++ ) 152 { 153 if ( aIter->aCellRange.In( rCell ) ) 154 { 155 rLocation = *aIter; 156 return true; 157 } 158 } 159 return false; // not found 160 } 161 162 sal_Bool ScPrintFuncCache::IsSameSelection( const ScPrintSelectionStatus& rStatus ) const 163 { 164 return aSelection == rStatus; 165 } 166 167 SCTAB ScPrintFuncCache::GetTabForPage( long nPage ) const 168 { 169 ScDocument* pDoc = pDocSh->GetDocument(); 170 SCTAB nTabCount = pDoc->GetTableCount(); 171 SCTAB nTab = 0; 172 while ( nTab < nTabCount && nPage >= nPages[nTab] ) 173 nPage -= nPages[nTab++]; 174 return nTab; 175 } 176 177 long ScPrintFuncCache::GetTabStart( SCTAB nTab ) const 178 { 179 long nRet = 0; 180 for ( SCTAB i=0; i<nTab; i++ ) 181 nRet += nPages[i]; 182 return nRet; 183 } 184 185 long ScPrintFuncCache::GetDisplayStart( SCTAB nTab ) const 186 { 187 //! merge with lcl_GetDisplayStart in preview? 188 189 long nDisplayStart = 0; 190 ScDocument* pDoc = pDocSh->GetDocument(); 191 for (SCTAB i=0; i<nTab; i++) 192 { 193 if ( pDoc->NeedPageResetAfterTab(i) ) 194 nDisplayStart = 0; 195 else 196 nDisplayStart += nPages[i]; 197 } 198 return nDisplayStart; 199 } 200 201 202