Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/outdev.hxx>
31 : :
32 : : #include "prevloc.hxx"
33 : : #include "document.hxx"
34 : :
35 : : enum ScPreviewLocationType
36 : : {
37 : : SC_PLOC_CELLRANGE,
38 : : SC_PLOC_COLHEADER,
39 : : SC_PLOC_ROWHEADER,
40 : : SC_PLOC_LEFTHEADER,
41 : : SC_PLOC_RIGHTHEADER,
42 : : SC_PLOC_LEFTFOOTER,
43 : : SC_PLOC_RIGHTFOOTER,
44 : : SC_PLOC_NOTEMARK,
45 : : SC_PLOC_NOTETEXT
46 : : };
47 : :
48 : : struct ScPreviewLocationEntry
49 : : {
50 : : ScPreviewLocationType eType;
51 : : Rectangle aPixelRect;
52 : : ScRange aCellRange;
53 : : sal_Bool bRepeatCol;
54 : : sal_Bool bRepeatRow;
55 : :
56 : 135 : ScPreviewLocationEntry( ScPreviewLocationType eNewType, const Rectangle& rPixel, const ScRange& rRange,
57 : : sal_Bool bRepCol, sal_Bool bRepRow ) :
58 : : eType( eNewType ),
59 : : aPixelRect( rPixel ),
60 : : aCellRange( rRange ),
61 : : bRepeatCol( bRepCol ),
62 : 135 : bRepeatRow( bRepRow )
63 : : {
64 : 135 : }
65 : : };
66 : :
67 : 63 : ScPreviewTableInfo::ScPreviewTableInfo() :
68 : : nTab(0),
69 : : nCols(0),
70 : : nRows(0),
71 : : pColInfo(NULL),
72 : 63 : pRowInfo(NULL)
73 : : {
74 : 63 : }
75 : :
76 : 63 : ScPreviewTableInfo::~ScPreviewTableInfo()
77 : : {
78 [ + - ]: 63 : delete[] pColInfo;
79 [ + - ]: 63 : delete[] pRowInfo;
80 : 63 : }
81 : :
82 : 63 : void ScPreviewTableInfo::SetTab( SCTAB nNewTab )
83 : : {
84 : 63 : nTab = nNewTab;
85 : 63 : }
86 : :
87 : 63 : void ScPreviewTableInfo::SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo )
88 : : {
89 [ - + ]: 63 : delete[] pColInfo;
90 : 63 : pColInfo = pNewInfo;
91 : 63 : nCols = nCount;
92 : 63 : }
93 : :
94 : 63 : void ScPreviewTableInfo::SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo )
95 : : {
96 [ - + ]: 63 : delete[] pRowInfo;
97 : 63 : pRowInfo = pNewInfo;
98 : 63 : nRows = nCount;
99 : 63 : }
100 : :
101 : 63 : void ScPreviewTableInfo::LimitToArea( const Rectangle& rPixelArea )
102 : : {
103 [ + - ]: 63 : if ( pColInfo )
104 : : {
105 : : // cells completely left of the visible area
106 : 63 : SCCOL nStart = 0;
107 [ + - ][ - + ]: 63 : while ( nStart < nCols && pColInfo[nStart].nPixelEnd < rPixelArea.Left() )
[ - + ]
108 : 0 : ++nStart;
109 : :
110 : : // cells completely right of the visible area
111 : 63 : SCCOL nEnd = nCols;
112 [ + - ][ - + ]: 63 : while ( nEnd > 0 && pColInfo[nEnd-1].nPixelStart > rPixelArea.Right() )
[ - + ]
113 : 0 : --nEnd;
114 : :
115 [ + - ][ - + ]: 63 : if ( nStart > 0 || nEnd < nCols )
116 : : {
117 [ # # ]: 0 : if ( nEnd > nStart )
118 : : {
119 : 0 : SCCOL nNewCount = nEnd - nStart;
120 : 0 : ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
121 [ # # ]: 0 : for (SCCOL i=0; i<nNewCount; i++)
122 : 0 : pNewInfo[i] = pColInfo[nStart + i];
123 : 0 : SetColInfo( nNewCount, pNewInfo );
124 : : }
125 : : else
126 : 0 : SetColInfo( 0, NULL ); // all invisible
127 : : }
128 : : }
129 : :
130 [ + - ]: 63 : if ( pRowInfo )
131 : : {
132 : : // cells completely above the visible area
133 : 63 : SCROW nStart = 0;
134 [ + - ][ - + ]: 63 : while ( nStart < nRows && pRowInfo[nStart].nPixelEnd < rPixelArea.Top() )
[ - + ]
135 : 0 : ++nStart;
136 : :
137 : : // cells completely below the visible area
138 : 63 : SCROW nEnd = nRows;
139 [ + - ][ - + ]: 63 : while ( nEnd > 0 && pRowInfo[nEnd-1].nPixelStart > rPixelArea.Bottom() )
[ - + ]
140 : 0 : --nEnd;
141 : :
142 [ + - ][ - + ]: 63 : if ( nStart > 0 || nEnd < nRows )
143 : : {
144 [ # # ]: 0 : if ( nEnd > nStart )
145 : : {
146 : 0 : SCROW nNewCount = nEnd - nStart;
147 : 0 : ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
148 [ # # ]: 0 : for (SCROW i=0; i<nNewCount; i++)
149 : 0 : pNewInfo[i] = pRowInfo[nStart + i];
150 : 0 : SetRowInfo( nNewCount, pNewInfo );
151 : : }
152 : : else
153 : 0 : SetRowInfo( 0, NULL ); // all invisible
154 : : }
155 : : }
156 : 63 : }
157 : :
158 : 16 : ScPreviewLocationData::ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin ) :
159 : : pWindow( pWin ),
160 : : pDoc( pDocument ),
161 : : nDrawRanges( 0 ),
162 [ + - ][ + + ]: 144 : nPrintTab( 0 )
[ + - ][ + + ]
[ + - # #
# # ]
163 : : {
164 [ # # # # ]: 16 : }
165 : :
166 [ + - ][ + - ]: 96 : ScPreviewLocationData::~ScPreviewLocationData()
167 : : {
168 [ + - ]: 16 : Clear();
169 [ + - ][ + + ]: 96 : }
[ # # # # ]
170 : :
171 : 41 : void ScPreviewLocationData::SetCellMapMode( const MapMode& rMapMode )
172 : : {
173 : 41 : aCellMapMode = rMapMode;
174 : 41 : }
175 : :
176 : 41 : void ScPreviewLocationData::SetPrintTab( SCTAB nNew )
177 : : {
178 : 41 : nPrintTab = nNew;
179 : 41 : }
180 : :
181 : 57 : void ScPreviewLocationData::Clear()
182 : : {
183 : 57 : aEntries.clear();
184 : :
185 : 57 : nDrawRanges = 0;
186 : 57 : }
187 : :
188 : 41 : void ScPreviewLocationData::AddCellRange( const Rectangle& rRect, const ScRange& rRange, sal_Bool bRepCol, sal_Bool bRepRow,
189 : : const MapMode& rDrawMap )
190 : : {
191 [ + - ]: 41 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
192 [ + - ][ + - ]: 41 : aEntries.push_front( new ScPreviewLocationEntry( SC_PLOC_CELLRANGE, aPixelRect, rRange, bRepCol, bRepRow ) );
193 : :
194 : : OSL_ENSURE( nDrawRanges < SC_PREVIEW_MAXRANGES, "too many ranges" );
195 : :
196 [ + - ]: 41 : if ( nDrawRanges < SC_PREVIEW_MAXRANGES )
197 : : {
198 : 41 : aDrawRectangle[nDrawRanges] = aPixelRect;
199 [ + - ]: 41 : aDrawMapMode[nDrawRanges] = rDrawMap;
200 : :
201 [ - + ]: 41 : if (bRepCol)
202 : : {
203 [ # # ]: 0 : if (bRepRow)
204 : 0 : aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_EDGE;
205 : : else
206 : 0 : aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPCOL;
207 : : }
208 : : else
209 : : {
210 [ - + ]: 41 : if (bRepRow)
211 : 0 : aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPROW;
212 : : else
213 : 41 : aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_TAB;
214 : : }
215 : :
216 : 41 : ++nDrawRanges;
217 : : }
218 : 41 : }
219 : :
220 : 6 : void ScPreviewLocationData::AddColHeaders( const Rectangle& rRect, SCCOL nStartCol, SCCOL nEndCol, sal_Bool bRepCol )
221 : : {
222 : 6 : SCTAB nTab = 0; //! ?
223 : 6 : ScRange aRange( nStartCol, 0, nTab, nEndCol, 0, nTab );
224 [ + - ]: 6 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
225 : :
226 [ + - ][ + - ]: 6 : aEntries.push_front( new ScPreviewLocationEntry( SC_PLOC_COLHEADER, aPixelRect, aRange, bRepCol, false ) );
227 : 6 : }
228 : :
229 : 6 : void ScPreviewLocationData::AddRowHeaders( const Rectangle& rRect, SCROW nStartRow, SCROW nEndRow, sal_Bool bRepRow )
230 : : {
231 : 6 : SCTAB nTab = 0; //! ?
232 : 6 : ScRange aRange( 0, nStartRow, nTab, 0, nEndRow, nTab );
233 [ + - ]: 6 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
234 : :
235 [ + - ][ + - ]: 6 : aEntries.push_front( new ScPreviewLocationEntry( SC_PLOC_ROWHEADER, aPixelRect, aRange, false, bRepRow ) );
236 : 6 : }
237 : :
238 : 82 : void ScPreviewLocationData::AddHeaderFooter( const Rectangle& rRect, sal_Bool bHeader, sal_Bool bLeft )
239 : : {
240 : 82 : ScRange aRange; //! ?
241 [ + - ]: 82 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
242 : :
243 : : ScPreviewLocationType eType = bHeader ?
244 : : ( bLeft ? SC_PLOC_LEFTHEADER : SC_PLOC_RIGHTHEADER ) :
245 [ + + ][ - + ]: 82 : ( bLeft ? SC_PLOC_LEFTFOOTER : SC_PLOC_RIGHTFOOTER );
[ - + ]
246 : :
247 [ + - ][ + - ]: 82 : aEntries.push_front( new ScPreviewLocationEntry( eType, aPixelRect, aRange, false, false ) );
248 : 82 : }
249 : :
250 : 0 : void ScPreviewLocationData::AddNoteMark( const Rectangle& rRect, const ScAddress& rPos )
251 : : {
252 : 0 : ScRange aRange( rPos );
253 [ # # ]: 0 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
254 : :
255 [ # # ][ # # ]: 0 : aEntries.push_front( new ScPreviewLocationEntry( SC_PLOC_NOTEMARK, aPixelRect, aRange, false, false ) );
256 : 0 : }
257 : :
258 : 0 : void ScPreviewLocationData::AddNoteText( const Rectangle& rRect, const ScAddress& rPos )
259 : : {
260 : 0 : ScRange aRange( rPos );
261 [ # # ]: 0 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
262 : :
263 [ # # ][ # # ]: 0 : aEntries.push_front( new ScPreviewLocationEntry( SC_PLOC_NOTETEXT, aPixelRect, aRange, false, false ) );
264 : 0 : }
265 : :
266 : 34 : void ScPreviewLocationData::GetDrawRange( sal_uInt16 nPos, Rectangle& rPixelRect, MapMode& rMapMode, sal_uInt8& rRangeId ) const
267 : : {
268 : : OSL_ENSURE( nPos < nDrawRanges, "wrong position" );
269 [ + - ]: 34 : if ( nPos < nDrawRanges )
270 : : {
271 : 34 : rPixelRect = aDrawRectangle[nPos];
272 : 34 : rMapMode = aDrawMapMode[nPos];
273 : 34 : rRangeId = aDrawRangeId[nPos];
274 : : }
275 : 34 : }
276 : :
277 : 58 : ScPreviewLocationEntry* lcl_GetEntryByAddress( const boost::ptr_list<ScPreviewLocationEntry> &rEntries,
278 : : const ScAddress& rPos, ScPreviewLocationType eType )
279 : : {
280 [ + - ]: 58 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
281 [ + - ][ + - ]: 76 : for (it = rEntries.begin(); it != rEntries.end(); ++it)
[ + - ][ + - ]
[ + - ]
282 : : {
283 [ + - ][ + + ]: 76 : if ( it->eType == eType && it->aCellRange.In( rPos ) )
[ + - ][ + - ]
[ + + ]
284 [ + - ]: 58 : return const_cast<ScPreviewLocationEntry*>(&(*it));
285 : : }
286 : :
287 : 58 : return NULL;
288 : : }
289 : :
290 : :
291 : 58 : Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, const ScRange& rRange ) const
292 : : {
293 : 58 : const double nScaleX = HMM_PER_TWIPS;
294 : 58 : const double nScaleY = HMM_PER_TWIPS;
295 : 58 : SCTAB nTab = rRange.aStart.Tab();
296 : :
297 : 58 : long nPosX = 0;
298 : 58 : SCCOL nEndCol = rCellPos.Col();
299 [ + + ]: 67 : for (SCCOL nCol = rRange.aStart.Col(); nCol < nEndCol; nCol++)
300 : : {
301 [ + - ]: 9 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
302 [ + - ]: 9 : if (nDocW)
303 : 9 : nPosX += (long) (nDocW * nScaleX);
304 : : }
305 [ + - ]: 58 : long nSizeX = (long) ( pDoc->GetColWidth( nEndCol, nTab ) * nScaleX );
306 : :
307 : 58 : SCROW nEndRow = rCellPos.Row();
308 : : long nPosY = (long) pDoc->GetScaledRowHeight( rRange.aStart.Row(),
309 [ + - ]: 58 : nEndRow, nTab, nScaleY);
310 [ + - ]: 58 : long nSizeY = (long) ( pDoc->GetRowHeight( nEndRow, nTab ) * nScaleY );
311 : :
312 : 58 : Size aOffsetLogic( nPosX, nPosY );
313 : 58 : Size aSizeLogic( nSizeX, nSizeY );
314 [ + - ]: 58 : Size aOffsetPixel = pWindow->LogicToPixel( aOffsetLogic, aCellMapMode );
315 [ + - ]: 58 : Size aSizePixel = pWindow->LogicToPixel( aSizeLogic, aCellMapMode );
316 : :
317 [ + - ]: 58 : return Rectangle( Point( aOffsetPixel.Width(), aOffsetPixel.Height() ), aSizePixel );
318 : : }
319 : :
320 : 58 : sal_Bool ScPreviewLocationData::GetCellPosition( const ScAddress& rCellPos, Rectangle& rCellRect ) const
321 : : {
322 : 58 : ScPreviewLocationEntry* pEntry = lcl_GetEntryByAddress( aEntries, rCellPos, SC_PLOC_CELLRANGE );
323 [ + - ]: 58 : if ( pEntry )
324 : : {
325 [ + - ]: 58 : Rectangle aOffsetRect = GetOffsetPixel( rCellPos, pEntry->aCellRange );
326 : 58 : rCellRect = Rectangle( aOffsetRect.Left() + pEntry->aPixelRect.Left(),
327 : 58 : aOffsetRect.Top() + pEntry->aPixelRect.Top(),
328 : 58 : aOffsetRect.Right() + pEntry->aPixelRect.Left(),
329 [ + - ]: 116 : aOffsetRect.Bottom() + pEntry->aPixelRect.Top() );
330 : 58 : return sal_True;
331 : : }
332 : 58 : return false;
333 : : }
334 : :
335 : 166 : sal_Bool ScPreviewLocationData::HasCellsInRange( const Rectangle& rVisiblePixel ) const
336 : : {
337 [ + - ]: 166 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
338 [ + - ][ # # ]: 166 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ + - ][ + - ]
[ + - ]
339 : : {
340 [ + - ][ + + ]: 166 : if ( it->eType == SC_PLOC_CELLRANGE || it->eType == SC_PLOC_COLHEADER || it->eType == SC_PLOC_ROWHEADER )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
341 [ + - ][ + - ]: 166 : if ( it->aPixelRect.IsOver( rVisiblePixel ) )
[ + - ]
342 : 166 : return true;
343 : : }
344 : :
345 : 166 : return false;
346 : : }
347 : :
348 : 2001 : sal_Bool ScPreviewLocationData::GetHeaderPosition( Rectangle& rRect ) const
349 : : {
350 [ + - ]: 2001 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
351 [ + - ][ + - ]: 6119 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ + - ][ + - ]
[ + - ]
352 : : {
353 [ + - ][ + - ]: 6119 : if ( it->eType == SC_PLOC_LEFTHEADER || it->eType == SC_PLOC_RIGHTHEADER )
[ + - ][ + + ]
[ + + ]
354 : : {
355 [ + - ]: 2001 : rRect = it->aPixelRect;
356 : 2001 : return true;
357 : : }
358 : : }
359 : :
360 : 2001 : return false;
361 : : }
362 : :
363 : 196 : sal_Bool ScPreviewLocationData::GetFooterPosition( Rectangle& rRect ) const
364 : : {
365 [ + - ]: 196 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
366 [ + - ][ + - ]: 496 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ + - ][ + - ]
[ + - ]
367 : : {
368 [ + - ][ + - ]: 496 : if ( it->eType == SC_PLOC_LEFTFOOTER || it->eType == SC_PLOC_RIGHTFOOTER )
[ + - ][ + + ]
[ + + ]
369 : : {
370 [ + - ]: 196 : rRect = it->aPixelRect;
371 : 196 : return true;
372 : : }
373 : : }
374 : :
375 : 196 : return false;
376 : : }
377 : :
378 : 31 : sal_Bool ScPreviewLocationData::IsHeaderLeft() const
379 : : {
380 [ + - ]: 31 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
381 [ + - ][ + - ]: 99 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ + - ][ + - ]
[ + - ]
382 : : {
383 [ + - ][ - + ]: 99 : if ( it->eType == SC_PLOC_LEFTHEADER )
384 : 0 : return true;
385 : :
386 [ + - ][ + + ]: 99 : if ( it->eType == SC_PLOC_RIGHTHEADER )
387 : 31 : return false;
388 : : }
389 : :
390 : 31 : return false;
391 : : }
392 : :
393 : 5 : sal_Bool ScPreviewLocationData::IsFooterLeft() const
394 : : {
395 [ + - ]: 5 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
396 [ + - ][ + - ]: 16 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ + - ][ + - ]
[ + - ]
397 : : {
398 [ + - ][ - + ]: 16 : if ( it->eType == SC_PLOC_LEFTFOOTER )
399 : 0 : return true;
400 : :
401 [ + - ][ + + ]: 16 : if ( it->eType == SC_PLOC_RIGHTFOOTER )
402 : 5 : return false;
403 : : }
404 : :
405 : 5 : return false;
406 : : }
407 : :
408 : 84 : long ScPreviewLocationData::GetNoteCountInRange( const Rectangle& rVisiblePixel, sal_Bool bNoteMarks ) const
409 : : {
410 [ + + ]: 84 : ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
411 : :
412 : 84 : sal_uLong nRet = 0;
413 [ + - ]: 84 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
414 [ + - ][ + - ]: 364 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ + - ][ + - ]
[ + + ]
415 : : {
416 [ + - ][ - + ]: 280 : if ( it->eType == eType && it->aPixelRect.IsOver( rVisiblePixel ) )
[ # # ][ # # ]
[ # # ][ - + ]
417 : 0 : ++nRet;
418 : : }
419 : :
420 : 84 : return nRet;
421 : : }
422 : :
423 : 0 : sal_Bool ScPreviewLocationData::GetNoteInRange( const Rectangle& rVisiblePixel, long nIndex, sal_Bool bNoteMarks,
424 : : ScAddress& rCellPos, Rectangle& rNoteRect ) const
425 : : {
426 [ # # ]: 0 : ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
427 : :
428 : 0 : sal_uLong nPos = 0;
429 [ # # ]: 0 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
430 [ # # ][ # # ]: 0 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ # # ][ # # ]
[ # # ]
431 : : {
432 [ # # ][ # # ]: 0 : if ( it->eType == eType && it->aPixelRect.IsOver( rVisiblePixel ) )
[ # # ][ # # ]
[ # # ][ # # ]
433 : : {
434 [ # # ]: 0 : if ( nPos == sal::static_int_cast<sal_uLong>(nIndex) )
435 : : {
436 [ # # ]: 0 : rCellPos = it->aCellRange.aStart;
437 [ # # ]: 0 : rNoteRect = it->aPixelRect;
438 : 0 : return true;
439 : : }
440 : 0 : ++nPos;
441 : : }
442 : : }
443 : :
444 : 0 : return false;
445 : : }
446 : :
447 : 0 : Rectangle ScPreviewLocationData::GetNoteInRangeOutputRect(const Rectangle& rVisiblePixel, sal_Bool bNoteMarks, const ScAddress& aCellPos) const
448 : : {
449 [ # # ]: 0 : ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
450 : :
451 : 0 : sal_uLong nPos = 0;
452 [ # # ]: 0 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
453 [ # # ][ # # ]: 0 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ # # ][ # # ]
[ # # ]
454 : : {
455 [ # # ][ # # ]: 0 : if ( it->eType == eType && it->aPixelRect.IsOver( rVisiblePixel ) )
[ # # ][ # # ]
[ # # ][ # # ]
456 : : {
457 [ # # ][ # # ]: 0 : if ( aCellPos == it->aCellRange.aStart )
458 [ # # ]: 0 : return it->aPixelRect;
459 : 0 : ++nPos;
460 : : }
461 : : }
462 : :
463 [ # # ]: 0 : return Rectangle();
464 : : }
465 : :
466 : 63 : void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPreviewTableInfo& rInfo ) const
467 : : {
468 : 63 : const double nScaleX = HMM_PER_TWIPS;
469 : 63 : const double nScaleY = HMM_PER_TWIPS;
470 : :
471 : : // from left to right:
472 : 63 : sal_Bool bHasHeaderCol = false;
473 : 63 : sal_Bool bHasRepCols = false;
474 : 63 : sal_Bool bHasMainCols = false;
475 : 63 : SCCOL nRepeatColStart = 0;
476 : 63 : SCCOL nRepeatColEnd = 0;
477 : 63 : SCCOL nMainColStart = 0;
478 : 63 : SCCOL nMainColEnd = 0;
479 : :
480 : : // from top to bottom:
481 : 63 : sal_Bool bHasHeaderRow = false;
482 : 63 : sal_Bool bHasRepRows = false;
483 : 63 : sal_Bool bHasMainRows = false;
484 : 63 : SCROW nRepeatRowStart = 0;
485 : 63 : SCROW nRepeatRowEnd = 0;
486 : 63 : SCROW nMainRowStart = 0;
487 : 63 : SCROW nMainRowEnd = 0;
488 : :
489 [ + - ][ + - ]: 63 : Rectangle aHeaderRect, aRepeatRect, aMainRect;
[ + - ]
490 : 63 : SCTAB nTab = 0;
491 : :
492 [ + - ]: 63 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
493 [ + - ][ + - ]: 322 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ + - ][ + - ]
[ + + ]
494 : : {
495 [ + - ][ + + ]: 259 : if ( it->eType == SC_PLOC_CELLRANGE )
496 : : {
497 [ + - ][ - + ]: 63 : if ( it->bRepeatCol )
498 : : {
499 : 0 : bHasRepCols = true;
500 [ # # ]: 0 : nRepeatColStart = it->aCellRange.aStart.Col();
501 [ # # ]: 0 : nRepeatColEnd = it->aCellRange.aEnd.Col();
502 [ # # ]: 0 : aRepeatRect.Left() = it->aPixelRect.Left();
503 [ # # ]: 0 : aRepeatRect.Right() = it->aPixelRect.Right();
504 : : }
505 : : else
506 : : {
507 : 63 : bHasMainCols = true;
508 [ + - ]: 63 : nMainColStart = it->aCellRange.aStart.Col();
509 [ + - ]: 63 : nMainColEnd = it->aCellRange.aEnd.Col();
510 [ + - ]: 63 : aMainRect.Left() = it->aPixelRect.Left();
511 [ + - ]: 63 : aMainRect.Right() = it->aPixelRect.Right();
512 : : }
513 [ + - ][ - + ]: 63 : if ( it->bRepeatRow )
514 : : {
515 : 0 : bHasRepRows = true;
516 [ # # ]: 0 : nRepeatRowStart = it->aCellRange.aStart.Row();
517 [ # # ]: 0 : nRepeatRowEnd = it->aCellRange.aEnd.Row();
518 [ # # ]: 0 : aRepeatRect.Top() = it->aPixelRect.Top();
519 [ # # ]: 0 : aRepeatRect.Bottom() = it->aPixelRect.Bottom();
520 : : }
521 : : else
522 : : {
523 : 63 : bHasMainRows = true;
524 [ + - ]: 63 : nMainRowStart = it->aCellRange.aStart.Row();
525 [ + - ]: 63 : nMainRowEnd = it->aCellRange.aEnd.Row();
526 [ + - ]: 63 : aMainRect.Top() = it->aPixelRect.Top();
527 [ + - ]: 63 : aMainRect.Bottom() = it->aPixelRect.Bottom();
528 : : }
529 [ + - ]: 63 : nTab = it->aCellRange.aStart.Tab(); //! store separately?
530 : : }
531 [ + - ][ + + ]: 196 : else if ( it->eType == SC_PLOC_ROWHEADER )
532 : : {
533 : : // row headers result in an additional column
534 : 35 : bHasHeaderCol = true;
535 [ + - ]: 35 : aHeaderRect.Left() = it->aPixelRect.Left();
536 [ + - ]: 35 : aHeaderRect.Right() = it->aPixelRect.Right();
537 : : }
538 [ + - ][ + + ]: 161 : else if ( it->eType == SC_PLOC_COLHEADER )
539 : : {
540 : : // column headers result in an additional row
541 : 35 : bHasHeaderRow = true;
542 [ + - ]: 35 : aHeaderRect.Top() = it->aPixelRect.Top();
543 [ + - ]: 35 : aHeaderRect.Bottom() = it->aPixelRect.Bottom();
544 : : }
545 : : }
546 : :
547 : : //
548 : : // get column info
549 : : //
550 : :
551 : 63 : SCCOL nColCount = 0;
552 : : SCCOL nCol;
553 [ + + ]: 63 : if ( bHasHeaderCol )
554 : 35 : ++nColCount;
555 [ - + ]: 63 : if ( bHasRepCols )
556 [ # # ]: 0 : for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
557 [ # # ][ # # ]: 0 : if (!pDoc->ColHidden(nCol, nTab))
558 : 0 : ++nColCount;
559 [ + - ]: 63 : if ( bHasMainCols )
560 [ + + ]: 136 : for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
561 [ + - ][ + - ]: 73 : if (!pDoc->ColHidden(nCol, nTab))
562 : 73 : ++nColCount;
563 : :
564 [ + - ]: 63 : if ( nColCount > 0 )
565 : : {
566 [ + - ]: 63 : ScPreviewColRowInfo* pColInfo = new ScPreviewColRowInfo[ nColCount ];
567 : 63 : SCCOL nColPos = 0;
568 : :
569 [ + + ]: 63 : if ( bHasHeaderCol )
570 : : {
571 : 35 : pColInfo[nColPos].Set( sal_True, 0, aHeaderRect.Left(), aHeaderRect.Right() );
572 : 35 : ++nColPos;
573 : : }
574 [ - + ]: 63 : if ( bHasRepCols )
575 : : {
576 : 0 : long nPosX = 0;
577 [ # # ]: 0 : for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
578 [ # # ][ # # ]: 0 : if (!pDoc->ColHidden(nCol, nTab))
579 : : {
580 [ # # ]: 0 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
581 : 0 : long nNextX = nPosX + (long) (nDocW * nScaleX);
582 : :
583 [ # # ]: 0 : long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
584 [ # # ]: 0 : long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
585 : : pColInfo[nColPos].Set( false, nCol,
586 : 0 : aRepeatRect.Left() + nPixelStart,
587 : 0 : aRepeatRect.Left() + nPixelEnd );
588 : :
589 : 0 : nPosX = nNextX;
590 : 0 : ++nColPos;
591 : : }
592 : : }
593 [ + - ]: 63 : if ( bHasMainCols )
594 : : {
595 : 63 : long nPosX = 0;
596 [ + + ]: 136 : for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
597 [ + - ][ + - ]: 73 : if (!pDoc->ColHidden(nCol, nTab))
598 : : {
599 [ + - ]: 73 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
600 : 73 : long nNextX = nPosX + (long) (nDocW * nScaleX);
601 : :
602 [ + - ]: 73 : long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
603 [ + - ]: 73 : long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
604 : : pColInfo[nColPos].Set( false, nCol,
605 : 73 : aMainRect.Left() + nPixelStart,
606 : 146 : aMainRect.Left() + nPixelEnd );
607 : :
608 : 73 : nPosX = nNextX;
609 : 73 : ++nColPos;
610 : : }
611 : : }
612 : 63 : rInfo.SetColInfo( nColCount, pColInfo );
613 : : }
614 : : else
615 : 0 : rInfo.SetColInfo( 0, NULL );
616 : :
617 : : //
618 : : // get row info
619 : : //
620 : :
621 : 63 : SCROW nRowCount = 0;
622 [ + + ]: 63 : if ( bHasHeaderRow )
623 : 35 : ++nRowCount;
624 [ - + ]: 63 : if ( bHasRepRows )
625 [ # # ]: 0 : nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab);
626 [ + - ]: 63 : if ( bHasMainRows )
627 [ + - ]: 63 : nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab);
628 : :
629 [ + - ]: 63 : if ( nRowCount > 0 )
630 : : {
631 [ + - ]: 63 : ScPreviewColRowInfo* pRowInfo = new ScPreviewColRowInfo[ nRowCount ];
632 : 63 : SCROW nRowPos = 0;
633 : :
634 [ + + ]: 63 : if ( bHasHeaderRow )
635 : : {
636 : 35 : pRowInfo[nRowPos].Set( sal_True, 0, aHeaderRect.Top(), aHeaderRect.Bottom() );
637 : 35 : ++nRowPos;
638 : : }
639 [ - + ]: 63 : if ( bHasRepRows )
640 : : {
641 : 0 : long nPosY = 0;
642 [ # # ]: 0 : for (SCROW nRow = nRepeatRowStart; nRow <= nRepeatRowEnd; ++nRow)
643 : : {
644 [ # # ][ # # ]: 0 : if (pDoc->RowHidden(nRow, nTab))
645 : 0 : continue;
646 : :
647 [ # # ]: 0 : sal_uInt16 nDocH = pDoc->GetOriginalHeight( nRow, nTab );
648 : 0 : long nNextY = nPosY + (long) (nDocH * nScaleY);
649 : :
650 [ # # ]: 0 : long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height();
651 [ # # ]: 0 : long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1;
652 : : pRowInfo[nRowPos].Set( false, nRow,
653 : 0 : aRepeatRect.Top() + nPixelStart,
654 : 0 : aRepeatRect.Top() + nPixelEnd );
655 : :
656 : 0 : nPosY = nNextY;
657 : 0 : ++nRowPos;
658 : : }
659 : : }
660 [ + - ]: 63 : if ( bHasMainRows )
661 : : {
662 : 63 : long nPosY = 0;
663 [ + + ]: 126 : for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow)
664 : : {
665 [ + - ][ - + ]: 63 : if (pDoc->RowHidden(nRow, nTab))
666 : 0 : continue;
667 : :
668 [ + - ]: 63 : sal_uInt16 nDocH = pDoc->GetOriginalHeight( nRow, nTab );
669 : 63 : long nNextY = nPosY + (long) (nDocH * nScaleY);
670 : :
671 [ + - ]: 63 : long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height();
672 [ + - ]: 63 : long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1;
673 : : pRowInfo[nRowPos].Set( false, nRow,
674 : 63 : aMainRect.Top() + nPixelStart,
675 : 126 : aMainRect.Top() + nPixelEnd );
676 : :
677 : 63 : nPosY = nNextY;
678 : 63 : ++nRowPos;
679 : : }
680 : : }
681 : 63 : rInfo.SetRowInfo( nRowCount, pRowInfo );
682 : : }
683 : : else
684 : 0 : rInfo.SetRowInfo( 0, NULL );
685 : :
686 : : //
687 : : // limit to visible area
688 : : //
689 : :
690 : 63 : rInfo.SetTab( nTab );
691 [ + - ]: 63 : rInfo.LimitToArea( rVisiblePixel );
692 : 63 : }
693 : :
694 : 22 : Rectangle ScPreviewLocationData::GetHeaderCellOutputRect(const Rectangle& rVisRect, const ScAddress& rCellPos, sal_Bool bColHeader) const
695 : : {
696 : : // first a stupid implementation
697 : : // NN says here should be done more
698 [ + - ]: 22 : Rectangle aClipRect;
699 : 22 : ScPreviewTableInfo aTableInfo;
700 [ + - ]: 22 : GetTableInfo( rVisRect, aTableInfo );
701 : :
702 [ + - + - : 88 : if ( (rCellPos.Col() >= 0) &&
+ - + - ]
[ + - ]
703 : 44 : (rCellPos.Row() >= 0) && (rCellPos.Col() < aTableInfo.GetCols()) &&
704 : 22 : (rCellPos.Row() < aTableInfo.GetRows()) )
705 : : {
706 : 22 : SCCOL nCol(0);
707 : 22 : SCROW nRow(0);
708 [ + + ]: 22 : if (bColHeader)
709 : 16 : nCol = rCellPos.Col();
710 : : else
711 : 6 : nRow = rCellPos.Row();
712 : 22 : const ScPreviewColRowInfo& rColInfo = aTableInfo.GetColInfo()[nCol];
713 : 22 : const ScPreviewColRowInfo& rRowInfo = aTableInfo.GetRowInfo()[nRow];
714 : :
715 [ # # ][ - + ]: 22 : if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
716 [ + - ]: 22 : aClipRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
717 : : }
718 : 22 : return aClipRect;
719 : : }
720 : :
721 : 39 : Rectangle ScPreviewLocationData::GetCellOutputRect(const ScAddress& rCellPos) const
722 : : {
723 : : // first a stupid implementation
724 : : // NN says here should be done more
725 : 39 : Rectangle aRect;
726 : 39 : GetCellPosition(rCellPos, aRect);
727 : 39 : return aRect;
728 : : }
729 : :
730 : : // GetMainCellRange is used for links in PDF export
731 : :
732 : 0 : sal_Bool ScPreviewLocationData::GetMainCellRange( ScRange& rRange, Rectangle& rPixRect ) const
733 : : {
734 [ # # ]: 0 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
735 [ # # ][ # # ]: 0 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
[ # # ][ # # ]
[ # # ]
736 : : {
737 [ # # ][ # # ]: 0 : if ( it->eType == SC_PLOC_CELLRANGE && !it->bRepeatCol && !it->bRepeatRow )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
738 : : {
739 [ # # ]: 0 : rRange = it->aCellRange;
740 [ # # ]: 0 : rPixRect = it->aPixelRect;
741 : 0 : return true;
742 : : }
743 : : }
744 : :
745 : 0 : return false;
746 : : }
747 : :
748 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|