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