1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <tools/multisel.hxx>
22 #include "pfuncache.hxx"
23 #include "printfun.hxx"
25 #include "markdata.hxx"
26 #include "prevloc.hxx"
28 ScPrintFuncCache::ScPrintFuncCache( ScDocShell
* pD
, const ScMarkData
& rMark
,
29 const ScPrintSelectionStatus
& rStatus
) :
30 aSelection( rStatus
),
35 bLocInitialized( false )
37 // page count uses the stored cell widths for the printer anyway,
38 // so ScPrintFunc with the document's printer can be used to count
40 SfxPrinter
* pPrinter
= pDocSh
->GetPrinter();
43 const ScRange
* pSelRange
= NULL
;
44 if ( rMark
.IsMarked() )
46 rMark
.GetMarkArea( aRange
);
50 ScDocument
& rDoc
= pDocSh
->GetDocument();
51 SCTAB nTabCount
= rDoc
.GetTableCount();
53 // avoid repeated progress bars if row heights for all sheets are needed
54 if ( nTabCount
> 1 && rMark
.GetSelectCount() == nTabCount
)
55 pDocSh
->UpdatePendingRowHeights( nTabCount
-1, true );
58 for ( nTab
=0; nTab
<nTabCount
; nTab
++ )
60 long nAttrPage
= nTab
> 0 ? nFirstAttr
[nTab
-1] : 1;
63 if ( rMark
.GetTableSelect( nTab
) )
65 ScPrintFunc
aFunc( pDocSh
, pPrinter
, nTab
, nAttrPage
, 0, pSelRange
, &aSelection
.GetOptions() );
66 nThisTab
= aFunc
.GetTotalPages();
67 nFirstAttr
.push_back( aFunc
.GetFirstPageNo() ); // from page style or previous sheet
70 nFirstAttr
.push_back( nAttrPage
);
72 nPages
.push_back( nThisTab
);
73 nTotalPages
+= nThisTab
;
77 ScPrintFuncCache::~ScPrintFuncCache()
81 void ScPrintFuncCache::InitLocations( const ScMarkData
& rMark
, OutputDevice
* pDev
)
83 if ( bLocInitialized
)
84 return; // initialize only once
87 const ScRange
* pSelRange
= NULL
;
88 if ( rMark
.IsMarked() )
90 rMark
.GetMarkArea( aRange
);
94 long nRenderer
= 0; // 0-based physical page number across sheets
97 ScDocument
& rDoc
= pDocSh
->GetDocument();
98 SCTAB nTabCount
= rDoc
.GetTableCount();
99 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
100 for (; itr
!= itrEnd
&& (*itr
) < nTabCount
; ++itr
)
103 ScPrintFunc
aFunc( pDev
, pDocSh
, nTab
, nFirstAttr
[nTab
], nTotalPages
, pSelRange
, &aSelection
.GetOptions() );
104 aFunc
.SetRenderFlag( true );
106 long nDisplayStart
= GetDisplayStart( nTab
);
108 for ( long nPage
=0; nPage
<nPages
[nTab
]; nPage
++ )
110 Range
aPageRange( nRenderer
+1, nRenderer
+1 );
111 MultiSelection
aPage( aPageRange
);
112 aPage
.SetTotalRange( Range(0,RANGE_MAX
) );
113 aPage
.Select( aPageRange
);
115 ScPreviewLocationData
aLocData( &rDoc
, pDev
);
116 aFunc
.DoPrint( aPage
, nTabStart
, nDisplayStart
, false, &aLocData
);
120 if ( aLocData
.GetMainCellRange( aCellRange
, aPixRect
) )
121 aLocations
.push_back( ScPrintPageLocation( nRenderer
, aCellRange
, aPixRect
) );
126 nTabStart
+= nPages
[nTab
];
129 bLocInitialized
= true;
132 bool ScPrintFuncCache::FindLocation( const ScAddress
& rCell
, ScPrintPageLocation
& rLocation
) const
134 for ( std::vector
<ScPrintPageLocation
>::const_iterator
aIter(aLocations
.begin()), aEnd(aLocations
.end());
135 aIter
!= aEnd
; ++aIter
)
137 if ( aIter
->aCellRange
.In( rCell
) )
143 return false; // not found
146 bool ScPrintFuncCache::IsSameSelection( const ScPrintSelectionStatus
& rStatus
) const
148 return aSelection
== rStatus
;
151 SCTAB
ScPrintFuncCache::GetTabForPage( long nPage
) const
153 ScDocument
& rDoc
= pDocSh
->GetDocument();
154 SCTAB nTabCount
= rDoc
.GetTableCount();
156 while ( nTab
< nTabCount
&& nPage
>= nPages
[nTab
] )
157 nPage
-= nPages
[nTab
++];
158 if (nTab
>= nTabCount
)
159 nTab
= nTabCount
- 1;
163 long ScPrintFuncCache::GetTabStart( SCTAB nTab
) const
166 for ( SCTAB i
=0; i
<nTab
&& i
< static_cast<SCTAB
>(nPages
.size()); i
++ )
171 long ScPrintFuncCache::GetDisplayStart( SCTAB nTab
) const
173 //! merge with lcl_GetDisplayStart in preview?
175 long nDisplayStart
= 0;
176 ScDocument
& rDoc
= pDocSh
->GetDocument();
177 for (SCTAB i
=0; i
<nTab
; i
++)
179 if ( rDoc
.NeedPageResetAfterTab(i
) )
183 if ( i
< static_cast<SCTAB
>(nPages
.size()) )
184 nDisplayStart
+= nPages
[i
];
186 OSL_FAIL("nPages out of bounds, FIX IT!");
189 return nDisplayStart
;
192 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */