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 60 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 73 ScPreviewTableInfo::ScPreviewTableInfo() : 74 nTab(0), 75 nCols(0), 76 nRows(0), 77 pColInfo(NULL), 78 pRowInfo(NULL) 79 { 80 } 81 82 ScPreviewTableInfo::~ScPreviewTableInfo() 83 { 84 delete[] pColInfo; 85 delete[] pRowInfo; 86 } 87 88 void ScPreviewTableInfo::SetTab( SCTAB nNewTab ) 89 { 90 nTab = nNewTab; 91 } 92 93 void ScPreviewTableInfo::SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo ) 94 { 95 delete[] pColInfo; 96 pColInfo = pNewInfo; 97 nCols = nCount; 98 } 99 100 void ScPreviewTableInfo::SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo ) 101 { 102 delete[] pRowInfo; 103 pRowInfo = pNewInfo; 104 nRows = nCount; 105 } 106 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 166 ScPreviewLocationData::ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin ) : 167 pWindow( pWin ), 168 pDoc( pDocument ), 169 nDrawRanges( 0 ), 170 nPrintTab( 0 ) 171 { 172 } 173 174 ScPreviewLocationData::~ScPreviewLocationData() 175 { 176 Clear(); 177 } 178 179 void ScPreviewLocationData::SetCellMapMode( const MapMode& rMapMode ) 180 { 181 aCellMapMode = rMapMode; 182 } 183 184 void ScPreviewLocationData::SetPrintTab( SCTAB nNew ) 185 { 186 nPrintTab = nNew; 187 } 188 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 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 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 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 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 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 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 270 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 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 332 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 361 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 376 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 390 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 405 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 420 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 434 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 448 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 463 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 487 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 506 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 735 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 762 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 773 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