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