1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 28 29 // INCLUDE --------------------------------------------------------------- 30 31 #include <tools/multisel.hxx> 32 33 #include "pfuncache.hxx" 34 #include "printfun.hxx" 35 #include "docsh.hxx" 36 #include "markdata.hxx" 37 #include "prevloc.hxx" 38 39 //------------------------------------------------------------------------ 40 41 ScPrintFuncCache::ScPrintFuncCache( ScDocShell* pD, const ScMarkData& rMark, 42 const ScPrintSelectionStatus& rStatus ) : 43 aSelection( rStatus ), 44 pDocSh( pD ), 45 nTotalPages( 0 ), 46 bLocInitialized( false ) 47 { 48 // page count uses the stored cell widths for the printer anyway, 49 // so ScPrintFunc with the document's printer can be used to count 50 51 SfxPrinter* pPrinter = pDocSh->GetPrinter(); 52 53 ScRange aRange; 54 const ScRange* pSelRange = NULL; 55 if ( rMark.IsMarked() ) 56 { 57 rMark.GetMarkArea( aRange ); 58 pSelRange = &aRange; 59 } 60 61 ScDocument* pDoc = pDocSh->GetDocument(); 62 SCTAB nTabCount = pDoc->GetTableCount(); 63 64 // avoid repeated progress bars if row heights for all sheets are needed 65 if ( nTabCount > 1 && rMark.GetSelectCount() == nTabCount ) 66 pDocSh->UpdatePendingRowHeights( nTabCount-1, true ); 67 68 SCTAB nTab; 69 for ( nTab=0; nTab<nTabCount; nTab++ ) 70 { 71 long nAttrPage = nTab > 0 ? nFirstAttr[nTab-1] : 1; 72 73 long nThisTab = 0; 74 if ( rMark.GetTableSelect( nTab ) ) 75 { 76 ScPrintFunc aFunc( pDocSh, pPrinter, nTab, nAttrPage, 0, pSelRange, &aSelection.GetOptions() ); 77 nThisTab = aFunc.GetTotalPages(); 78 nFirstAttr[nTab] = aFunc.GetFirstPageNo(); // from page style or previous sheet 79 } 80 else 81 nFirstAttr[nTab] = nAttrPage; 82 83 nPages[nTab] = nThisTab; 84 nTotalPages += nThisTab; 85 } 86 } 87 88 ScPrintFuncCache::~ScPrintFuncCache() 89 { 90 } 91 92 void ScPrintFuncCache::InitLocations( const ScMarkData& rMark, OutputDevice* pDev ) 93 { 94 if ( bLocInitialized ) 95 return; // initialize only once 96 97 ScRange aRange; 98 const ScRange* pSelRange = NULL; 99 if ( rMark.IsMarked() ) 100 { 101 rMark.GetMarkArea( aRange ); 102 pSelRange = &aRange; 103 } 104 105 long nRenderer = 0; // 0-based physical page number across sheets 106 long nTabStart = 0; 107 108 ScDocument* pDoc = pDocSh->GetDocument(); 109 SCTAB nTabCount = pDoc->GetTableCount(); 110 for ( SCTAB nTab=0; nTab<nTabCount; nTab++ ) 111 { 112 if ( rMark.GetTableSelect( nTab ) ) 113 { 114 ScPrintFunc aFunc( pDev, pDocSh, nTab, nFirstAttr[nTab], nTotalPages, pSelRange, &aSelection.GetOptions() ); 115 aFunc.SetRenderFlag( sal_True ); 116 117 long nDisplayStart = GetDisplayStart( nTab ); 118 119 for ( long nPage=0; nPage<nPages[nTab]; nPage++ ) 120 { 121 Range aPageRange( nRenderer+1, nRenderer+1 ); 122 MultiSelection aPage( aPageRange ); 123 aPage.SetTotalRange( Range(0,RANGE_MAX) ); 124 aPage.Select( aPageRange ); 125 126 ScPreviewLocationData aLocData( pDoc, pDev ); 127 aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, &aLocData ); 128 129 ScRange aCellRange; 130 Rectangle aPixRect; 131 if ( aLocData.GetMainCellRange( aCellRange, aPixRect ) ) 132 aLocations.push_back( ScPrintPageLocation( nRenderer, aCellRange, aPixRect ) ); 133 134 ++nRenderer; 135 } 136 137 nTabStart += nPages[nTab]; 138 } 139 } 140 141 bLocInitialized = true; 142 } 143 144 bool ScPrintFuncCache::FindLocation( const ScAddress& rCell, ScPrintPageLocation& rLocation ) const 145 { 146 for ( std::vector<ScPrintPageLocation>::const_iterator aIter(aLocations.begin()); 147 aIter != aLocations.end(); aIter++ ) 148 { 149 if ( aIter->aCellRange.In( rCell ) ) 150 { 151 rLocation = *aIter; 152 return true; 153 } 154 } 155 return false; // not found 156 } 157 158 sal_Bool ScPrintFuncCache::IsSameSelection( const ScPrintSelectionStatus& rStatus ) const 159 { 160 return aSelection == rStatus; 161 } 162 163 SCTAB ScPrintFuncCache::GetTabForPage( long nPage ) const 164 { 165 ScDocument* pDoc = pDocSh->GetDocument(); 166 SCTAB nTabCount = pDoc->GetTableCount(); 167 SCTAB nTab = 0; 168 while ( nTab < nTabCount && nPage >= nPages[nTab] ) 169 nPage -= nPages[nTab++]; 170 return nTab; 171 } 172 173 long ScPrintFuncCache::GetTabStart( SCTAB nTab ) const 174 { 175 long nRet = 0; 176 for ( SCTAB i=0; i<nTab; i++ ) 177 nRet += nPages[i]; 178 return nRet; 179 } 180 181 long ScPrintFuncCache::GetDisplayStart( SCTAB nTab ) const 182 { 183 //! merge with lcl_GetDisplayStart in preview? 184 185 long nDisplayStart = 0; 186 ScDocument* pDoc = pDocSh->GetDocument(); 187 for (SCTAB i=0; i<nTab; i++) 188 { 189 if ( pDoc->NeedPageResetAfterTab(i) ) 190 nDisplayStart = 0; 191 else 192 nDisplayStart += nPages[i]; 193 } 194 return nDisplayStart; 195 } 196 197 198