xref: /AOO41X/main/sc/source/ui/view/prevloc.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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