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