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 134 : 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 134 : bRepeatRow( bRepRow )
53 : {
54 134 : }
55 : };
56 :
57 76 : ScPreviewTableInfo::ScPreviewTableInfo() :
58 : nTab(0),
59 : nCols(0),
60 : nRows(0),
61 : pColInfo(NULL),
62 76 : pRowInfo(NULL)
63 : {
64 76 : }
65 :
66 76 : ScPreviewTableInfo::~ScPreviewTableInfo()
67 : {
68 76 : delete[] pColInfo;
69 76 : delete[] pRowInfo;
70 76 : }
71 :
72 76 : void ScPreviewTableInfo::SetTab( SCTAB nNewTab )
73 : {
74 76 : nTab = nNewTab;
75 76 : }
76 :
77 76 : void ScPreviewTableInfo::SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo )
78 : {
79 76 : delete[] pColInfo;
80 76 : pColInfo = pNewInfo;
81 76 : nCols = nCount;
82 76 : }
83 :
84 76 : void ScPreviewTableInfo::SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo )
85 : {
86 76 : delete[] pRowInfo;
87 76 : pRowInfo = pNewInfo;
88 76 : nRows = nCount;
89 76 : }
90 :
91 76 : void ScPreviewTableInfo::LimitToArea( const Rectangle& rPixelArea )
92 : {
93 76 : if ( pColInfo )
94 : {
95 : // cells completely left of the visible area
96 76 : SCCOL nStart = 0;
97 152 : while ( nStart < nCols && pColInfo[nStart].nPixelEnd < rPixelArea.Left() )
98 0 : ++nStart;
99 :
100 : // cells completely right of the visible area
101 76 : SCCOL nEnd = nCols;
102 152 : while ( nEnd > 0 && pColInfo[nEnd-1].nPixelStart > rPixelArea.Right() )
103 0 : --nEnd;
104 :
105 76 : 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 76 : if ( pRowInfo )
121 : {
122 : // cells completely above the visible area
123 76 : SCROW nStart = 0;
124 152 : while ( nStart < nRows && pRowInfo[nStart].nPixelEnd < rPixelArea.Top() )
125 0 : ++nStart;
126 :
127 : // cells completely below the visible area
128 76 : SCROW nEnd = nRows;
129 152 : while ( nEnd > 0 && pRowInfo[nEnd-1].nPixelStart > rPixelArea.Bottom() )
130 0 : --nEnd;
131 :
132 76 : 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 76 : }
147 :
148 16 : ScPreviewLocationData::ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin ) :
149 : pWindow( pWin ),
150 : pDoc( pDocument ),
151 : nDrawRanges( 0 ),
152 16 : nPrintTab( 0 )
153 : {
154 16 : }
155 :
156 32 : ScPreviewLocationData::~ScPreviewLocationData()
157 : {
158 16 : Clear();
159 16 : }
160 :
161 42 : void ScPreviewLocationData::SetCellMapMode( const MapMode& rMapMode )
162 : {
163 42 : aCellMapMode = rMapMode;
164 42 : }
165 :
166 42 : void ScPreviewLocationData::SetPrintTab( SCTAB nNew )
167 : {
168 42 : nPrintTab = nNew;
169 42 : }
170 :
171 58 : void ScPreviewLocationData::Clear()
172 : {
173 58 : aEntries.clear();
174 :
175 58 : nDrawRanges = 0;
176 58 : }
177 :
178 42 : void ScPreviewLocationData::AddCellRange( const Rectangle& rRect, const ScRange& rRange, bool bRepCol, bool bRepRow,
179 : const MapMode& rDrawMap )
180 : {
181 42 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
182 42 : 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 42 : if ( nDrawRanges < SC_PREVIEW_MAXRANGES )
187 : {
188 42 : aDrawRectangle[nDrawRanges] = aPixelRect;
189 42 : aDrawMapMode[nDrawRanges] = rDrawMap;
190 :
191 42 : 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 42 : if (bRepRow)
201 0 : aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPROW;
202 : else
203 42 : aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_TAB;
204 : }
205 :
206 42 : ++nDrawRanges;
207 : }
208 42 : }
209 :
210 4 : void ScPreviewLocationData::AddColHeaders( const Rectangle& rRect, SCCOL nStartCol, SCCOL nEndCol, bool bRepCol )
211 : {
212 4 : SCTAB nTab = 0; //! ?
213 4 : ScRange aRange( nStartCol, 0, nTab, nEndCol, 0, nTab );
214 4 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
215 :
216 4 : aEntries.push_front( new ScPreviewLocationEntry( SC_PLOC_COLHEADER, aPixelRect, aRange, bRepCol, false ) );
217 4 : }
218 :
219 4 : void ScPreviewLocationData::AddRowHeaders( const Rectangle& rRect, SCROW nStartRow, SCROW nEndRow, bool bRepRow )
220 : {
221 4 : SCTAB nTab = 0; //! ?
222 4 : ScRange aRange( 0, nStartRow, nTab, 0, nEndRow, nTab );
223 4 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
224 :
225 4 : aEntries.push_front( new ScPreviewLocationEntry( SC_PLOC_ROWHEADER, aPixelRect, aRange, false, bRepRow ) );
226 4 : }
227 :
228 84 : void ScPreviewLocationData::AddHeaderFooter( const Rectangle& rRect, bool bHeader, bool bLeft )
229 : {
230 84 : ScRange aRange; //! ?
231 84 : Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
232 :
233 : ScPreviewLocationType eType = bHeader ?
234 : ( bLeft ? SC_PLOC_LEFTHEADER : SC_PLOC_RIGHTHEADER ) :
235 84 : ( bLeft ? SC_PLOC_LEFTFOOTER : SC_PLOC_RIGHTFOOTER );
236 :
237 84 : aEntries.push_front( new ScPreviewLocationEntry( eType, aPixelRect, aRange, false, false ) );
238 84 : }
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 32 : void ScPreviewLocationData::GetDrawRange( sal_uInt16 nPos, Rectangle& rPixelRect, MapMode& rMapMode, sal_uInt8& rRangeId ) const
257 : {
258 : OSL_ENSURE( nPos < nDrawRanges, "wrong position" );
259 32 : if ( nPos < nDrawRanges )
260 : {
261 32 : rPixelRect = aDrawRectangle[nPos];
262 32 : rMapMode = aDrawMapMode[nPos];
263 32 : rRangeId = aDrawRangeId[nPos];
264 : }
265 32 : }
266 :
267 76 : static ScPreviewLocationEntry* lcl_GetEntryByAddress( const boost::ptr_list<ScPreviewLocationEntry> &rEntries,
268 : const ScAddress& rPos, ScPreviewLocationType eType )
269 : {
270 76 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
271 108 : for (it = rEntries.begin(); it != rEntries.end(); ++it)
272 : {
273 108 : if ( it->eType == eType && it->aCellRange.In( rPos ) )
274 76 : return const_cast<ScPreviewLocationEntry*>(&(*it));
275 : }
276 :
277 0 : return NULL;
278 : }
279 :
280 76 : Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, const ScRange& rRange ) const
281 : {
282 76 : const double nScaleX = HMM_PER_TWIPS;
283 76 : const double nScaleY = HMM_PER_TWIPS;
284 76 : SCTAB nTab = rRange.aStart.Tab();
285 :
286 76 : long nPosX = 0;
287 76 : SCCOL nEndCol = rCellPos.Col();
288 76 : 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 76 : long nSizeX = (long) ( pDoc->GetColWidth( nEndCol, nTab ) * nScaleX );
295 :
296 76 : SCROW nEndRow = rCellPos.Row();
297 : long nPosY = (long) pDoc->GetScaledRowHeight( rRange.aStart.Row(),
298 76 : nEndRow, nTab, nScaleY);
299 76 : long nSizeY = (long) ( pDoc->GetRowHeight( nEndRow, nTab ) * nScaleY );
300 :
301 76 : Size aOffsetLogic( nPosX, nPosY );
302 76 : Size aSizeLogic( nSizeX, nSizeY );
303 76 : Size aOffsetPixel = pWindow->LogicToPixel( aOffsetLogic, aCellMapMode );
304 76 : Size aSizePixel = pWindow->LogicToPixel( aSizeLogic, aCellMapMode );
305 :
306 76 : return Rectangle( Point( aOffsetPixel.Width(), aOffsetPixel.Height() ), aSizePixel );
307 : }
308 :
309 76 : bool ScPreviewLocationData::GetCellPosition( const ScAddress& rCellPos, Rectangle& rCellRect ) const
310 : {
311 76 : ScPreviewLocationEntry* pEntry = lcl_GetEntryByAddress( aEntries, rCellPos, SC_PLOC_CELLRANGE );
312 76 : if ( pEntry )
313 : {
314 76 : Rectangle aOffsetRect = GetOffsetPixel( rCellPos, pEntry->aCellRange );
315 152 : rCellRect = Rectangle( aOffsetRect.Left() + pEntry->aPixelRect.Left(),
316 152 : aOffsetRect.Top() + pEntry->aPixelRect.Top(),
317 152 : aOffsetRect.Right() + pEntry->aPixelRect.Left(),
318 532 : aOffsetRect.Bottom() + pEntry->aPixelRect.Top() );
319 76 : return true;
320 : }
321 0 : return false;
322 : }
323 :
324 176 : bool ScPreviewLocationData::HasCellsInRange( const Rectangle& rVisiblePixel ) const
325 : {
326 176 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
327 176 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
328 : {
329 176 : if ( it->eType == SC_PLOC_CELLRANGE || it->eType == SC_PLOC_COLHEADER || it->eType == SC_PLOC_ROWHEADER )
330 176 : if ( it->aPixelRect.IsOver( rVisiblePixel ) )
331 176 : return true;
332 : }
333 :
334 0 : return false;
335 : }
336 :
337 1462 : bool ScPreviewLocationData::GetHeaderPosition( Rectangle& rRect ) const
338 : {
339 1462 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
340 4570 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
341 : {
342 4570 : if ( it->eType == SC_PLOC_LEFTHEADER || it->eType == SC_PLOC_RIGHTHEADER )
343 : {
344 1462 : rRect = it->aPixelRect;
345 1462 : return true;
346 : }
347 : }
348 :
349 0 : return false;
350 : }
351 :
352 234 : bool ScPreviewLocationData::GetFooterPosition( Rectangle& rRect ) const
353 : {
354 234 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
355 636 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
356 : {
357 636 : if ( it->eType == SC_PLOC_LEFTFOOTER || it->eType == SC_PLOC_RIGHTFOOTER )
358 : {
359 234 : rRect = it->aPixelRect;
360 234 : return true;
361 : }
362 : }
363 :
364 0 : return false;
365 : }
366 :
367 30 : bool ScPreviewLocationData::IsHeaderLeft() const
368 : {
369 30 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
370 98 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
371 : {
372 98 : if ( it->eType == SC_PLOC_LEFTHEADER )
373 0 : return true;
374 :
375 98 : if ( it->eType == SC_PLOC_RIGHTHEADER )
376 30 : return false;
377 : }
378 :
379 0 : return false;
380 : }
381 :
382 6 : bool ScPreviewLocationData::IsFooterLeft() const
383 : {
384 6 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
385 20 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
386 : {
387 20 : if ( it->eType == SC_PLOC_LEFTFOOTER )
388 0 : return true;
389 :
390 20 : if ( it->eType == SC_PLOC_RIGHTFOOTER )
391 6 : return false;
392 : }
393 :
394 0 : return false;
395 : }
396 :
397 84 : long ScPreviewLocationData::GetNoteCountInRange( const Rectangle& rVisiblePixel, bool bNoteMarks ) const
398 : {
399 84 : ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
400 :
401 84 : sal_uLong nRet = 0;
402 84 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
403 352 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
404 : {
405 268 : if ( it->eType == eType && it->aPixelRect.IsOver( rVisiblePixel ) )
406 0 : ++nRet;
407 : }
408 :
409 84 : 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 76 : void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPreviewTableInfo& rInfo ) const
456 : {
457 76 : const double nScaleX = HMM_PER_TWIPS;
458 76 : const double nScaleY = HMM_PER_TWIPS;
459 :
460 : // from left to right:
461 76 : bool bHasHeaderCol = false;
462 76 : bool bHasRepCols = false;
463 76 : bool bHasMainCols = false;
464 76 : SCCOL nRepeatColStart = 0;
465 76 : SCCOL nRepeatColEnd = 0;
466 76 : SCCOL nMainColStart = 0;
467 76 : SCCOL nMainColEnd = 0;
468 :
469 : // from top to bottom:
470 76 : bool bHasHeaderRow = false;
471 76 : bool bHasRepRows = false;
472 76 : bool bHasMainRows = false;
473 76 : SCROW nRepeatRowStart = 0;
474 76 : SCROW nRepeatRowEnd = 0;
475 76 : SCROW nMainRowStart = 0;
476 76 : SCROW nMainRowEnd = 0;
477 :
478 76 : Rectangle aHeaderRect, aRepeatRect, aMainRect;
479 76 : SCTAB nTab = 0;
480 :
481 76 : boost::ptr_list<ScPreviewLocationEntry>::const_iterator it;
482 404 : for (it = aEntries.begin(); it != aEntries.end(); ++it)
483 : {
484 328 : if ( it->eType == SC_PLOC_CELLRANGE )
485 : {
486 76 : 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 76 : bHasMainCols = true;
497 76 : nMainColStart = it->aCellRange.aStart.Col();
498 76 : nMainColEnd = it->aCellRange.aEnd.Col();
499 76 : aMainRect.Left() = it->aPixelRect.Left();
500 76 : aMainRect.Right() = it->aPixelRect.Right();
501 : }
502 76 : 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 76 : bHasMainRows = true;
513 76 : nMainRowStart = it->aCellRange.aStart.Row();
514 76 : nMainRowEnd = it->aCellRange.aEnd.Row();
515 76 : aMainRect.Top() = it->aPixelRect.Top();
516 76 : aMainRect.Bottom() = it->aPixelRect.Bottom();
517 : }
518 76 : nTab = it->aCellRange.aStart.Tab(); //! store separately?
519 : }
520 252 : else if ( it->eType == SC_PLOC_ROWHEADER )
521 : {
522 : // row headers result in an additional column
523 50 : bHasHeaderCol = true;
524 50 : aHeaderRect.Left() = it->aPixelRect.Left();
525 50 : aHeaderRect.Right() = it->aPixelRect.Right();
526 : }
527 202 : else if ( it->eType == SC_PLOC_COLHEADER )
528 : {
529 : // column headers result in an additional row
530 50 : bHasHeaderRow = true;
531 50 : aHeaderRect.Top() = it->aPixelRect.Top();
532 50 : aHeaderRect.Bottom() = it->aPixelRect.Bottom();
533 : }
534 : }
535 :
536 : // get column info
537 :
538 76 : SCCOL nColCount = 0;
539 : SCCOL nCol;
540 76 : if ( bHasHeaderCol )
541 50 : ++nColCount;
542 76 : if ( bHasRepCols )
543 0 : for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
544 0 : if (!pDoc->ColHidden(nCol, nTab))
545 0 : ++nColCount;
546 76 : if ( bHasMainCols )
547 160 : for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
548 84 : if (!pDoc->ColHidden(nCol, nTab))
549 84 : ++nColCount;
550 :
551 76 : if ( nColCount > 0 )
552 : {
553 76 : ScPreviewColRowInfo* pColInfo = new ScPreviewColRowInfo[ nColCount ];
554 76 : SCCOL nColPos = 0;
555 :
556 76 : if ( bHasHeaderCol )
557 : {
558 50 : pColInfo[nColPos].Set( true, 0, aHeaderRect.Left(), aHeaderRect.Right() );
559 50 : ++nColPos;
560 : }
561 76 : 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 76 : if ( bHasMainCols )
581 : {
582 76 : long nPosX = 0;
583 160 : for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
584 84 : if (!pDoc->ColHidden(nCol, nTab))
585 : {
586 84 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
587 84 : long nNextX = nPosX + (long) (nDocW * nScaleX);
588 :
589 84 : long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
590 84 : long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
591 : pColInfo[nColPos].Set( false, nCol,
592 84 : aMainRect.Left() + nPixelStart,
593 168 : aMainRect.Left() + nPixelEnd );
594 :
595 84 : nPosX = nNextX;
596 84 : ++nColPos;
597 : }
598 : }
599 76 : rInfo.SetColInfo( nColCount, pColInfo );
600 : }
601 : else
602 0 : rInfo.SetColInfo( 0, NULL );
603 :
604 : // get row info
605 :
606 76 : SCROW nRowCount = 0;
607 76 : if ( bHasHeaderRow )
608 50 : ++nRowCount;
609 76 : if ( bHasRepRows )
610 0 : nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab);
611 76 : if ( bHasMainRows )
612 76 : nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab);
613 :
614 76 : if ( nRowCount > 0 )
615 : {
616 76 : ScPreviewColRowInfo* pRowInfo = new ScPreviewColRowInfo[ nRowCount ];
617 76 : SCROW nRowPos = 0;
618 :
619 76 : if ( bHasHeaderRow )
620 : {
621 50 : pRowInfo[nRowPos].Set( true, 0, aHeaderRect.Top(), aHeaderRect.Bottom() );
622 50 : ++nRowPos;
623 : }
624 76 : 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 76 : if ( bHasMainRows )
646 : {
647 76 : long nPosY = 0;
648 152 : for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow)
649 : {
650 76 : if (pDoc->RowHidden(nRow, nTab))
651 0 : continue;
652 :
653 76 : sal_uInt16 nDocH = pDoc->GetOriginalHeight( nRow, nTab );
654 76 : long nNextY = nPosY + (long) (nDocH * nScaleY);
655 :
656 76 : long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height();
657 76 : long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1;
658 : pRowInfo[nRowPos].Set( false, nRow,
659 76 : aMainRect.Top() + nPixelStart,
660 152 : aMainRect.Top() + nPixelEnd );
661 :
662 76 : nPosY = nNextY;
663 76 : ++nRowPos;
664 : }
665 : }
666 76 : rInfo.SetRowInfo( nRowCount, pRowInfo );
667 : }
668 : else
669 0 : rInfo.SetRowInfo( 0, NULL );
670 :
671 : // limit to visible area
672 :
673 76 : rInfo.SetTab( nTab );
674 76 : rInfo.LimitToArea( rVisiblePixel );
675 76 : }
676 :
677 32 : 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 32 : Rectangle aClipRect;
682 32 : ScPreviewTableInfo aTableInfo;
683 32 : GetTableInfo( rVisRect, aTableInfo );
684 :
685 96 : if ( (rCellPos.Col() >= 0) &&
686 96 : (rCellPos.Row() >= 0) && (rCellPos.Col() < aTableInfo.GetCols()) &&
687 32 : (rCellPos.Row() < aTableInfo.GetRows()) )
688 : {
689 32 : SCCOL nCol(0);
690 32 : SCROW nRow(0);
691 32 : if (bColHeader)
692 24 : nCol = rCellPos.Col();
693 : else
694 8 : nRow = rCellPos.Row();
695 32 : const ScPreviewColRowInfo& rColInfo = aTableInfo.GetColInfo()[nCol];
696 32 : const ScPreviewColRowInfo& rRowInfo = aTableInfo.GetRowInfo()[nRow];
697 :
698 32 : if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
699 32 : aClipRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
700 : }
701 32 : return aClipRect;
702 : }
703 :
704 42 : Rectangle ScPreviewLocationData::GetCellOutputRect(const ScAddress& rCellPos) const
705 : {
706 : // first a stupid implementation
707 : // NN says here should be done more
708 42 : Rectangle aRect;
709 42 : GetCellPosition(rCellPos, aRect);
710 42 : 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 228 : }
730 :
731 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|