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
ScPrintFuncCache(ScDocShell * pD,const ScMarkData & rMark,const ScPrintSelectionStatus & rStatus)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
~ScPrintFuncCache()88 ScPrintFuncCache::~ScPrintFuncCache()
89 {
90 }
91
InitLocations(const ScMarkData & rMark,OutputDevice * pDev)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
FindLocation(const ScAddress & rCell,ScPrintPageLocation & rLocation) const144 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
IsSameSelection(const ScPrintSelectionStatus & rStatus) const158 sal_Bool ScPrintFuncCache::IsSameSelection( const ScPrintSelectionStatus& rStatus ) const
159 {
160 return aSelection == rStatus;
161 }
162
GetTabForPage(long nPage) const163 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
GetTabStart(SCTAB nTab) const173 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
GetDisplayStart(SCTAB nTab) const181 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