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