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