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 "scitems.hxx" 36 #include <editeng/boxitem.hxx> 37 #include <editeng/bolnitem.hxx> 38 #include <editeng/editdata.hxx> // can be removed if table has a bLayoutRTL flag 39 #include <editeng/shaditem.hxx> 40 41 #include "fillinfo.hxx" 42 #include "document.hxx" 43 #include "cell.hxx" 44 #include "table.hxx" 45 #include "attrib.hxx" 46 #include "attarray.hxx" 47 #include "markarr.hxx" 48 #include "markdata.hxx" 49 #include "patattr.hxx" 50 #include "poolhelp.hxx" 51 #include "docpool.hxx" 52 #include "conditio.hxx" 53 #include "stlpool.hxx" 54 55 // ----------------------------------------------------------------------- 56 57 const sal_uInt16 ROWINFO_MAX = 1024; 58 59 60 enum FillInfoLinePos 61 { 62 FILP_TOP, 63 FILP_BOTTOM, 64 FILP_LEFT, 65 FILP_RIGHT 66 }; 67 68 69 inline const SvxBorderLine* GetNullOrLine( const SvxBoxItem* pBox, FillInfoLinePos eWhich ) 70 { 71 if (pBox) 72 { 73 if (eWhich==FILP_TOP) 74 return pBox->GetTop(); 75 else if (eWhich==FILP_BOTTOM) 76 return pBox->GetBottom(); 77 else if (eWhich==FILP_LEFT) 78 return pBox->GetLeft(); 79 else 80 return pBox->GetRight(); 81 } 82 else 83 return NULL; 84 } 85 86 // aehnlich wie in output.cxx 87 88 void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY, 89 ScDocument* pDoc, RowInfo* pRowInfo, 90 SCCOL nX1, SCROW nY1, SCCOL /* nX2 */, SCROW /* nY2 */, SCTAB nTab, 91 SCsCOL& rStartX, SCsROW& rStartY, SCsCOL& rEndX, SCsROW& rEndY ) 92 { 93 CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1]; 94 95 rStartX = nX; 96 rStartY = nY; 97 sal_Bool bHOver = pInfo->bHOverlapped; 98 sal_Bool bVOver = pInfo->bVOverlapped; 99 SCCOL nLastCol; 100 SCROW nLastRow; 101 102 while (bHOver) // nY konstant 103 { 104 --rStartX; 105 if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, nLastCol)) 106 { 107 bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped; 108 bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped; 109 } 110 else 111 { 112 sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr( 113 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue(); 114 bHOver = ((nOverlap & SC_MF_HOR) != 0); 115 bVOver = ((nOverlap & SC_MF_VER) != 0); 116 } 117 } 118 119 while (bVOver) 120 { 121 --rStartY; 122 123 if (nArrY>0) 124 --nArrY; // lokale Kopie ! 125 126 if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 && 127 !pDoc->ColHidden(rStartX, nTab, nLastCol) && 128 !pDoc->RowHidden(rStartY, nTab, nLastRow) && 129 (SCsROW) pRowInfo[nArrY].nRowNo == rStartY) 130 { 131 bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped; 132 bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped; 133 } 134 else 135 { 136 sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr( 137 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue(); 138 bHOver = ((nOverlap & SC_MF_HOR) != 0); 139 bVOver = ((nOverlap & SC_MF_VER) != 0); 140 } 141 } 142 143 const ScMergeAttr* pMerge; 144 if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 && 145 !pDoc->ColHidden(rStartX, nTab, nLastCol) && 146 !pDoc->RowHidden(rStartY, nTab, nLastRow) && 147 (SCsROW) pRowInfo[nArrY].nRowNo == rStartY) 148 { 149 pMerge = (const ScMergeAttr*) &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr-> 150 GetItem(ATTR_MERGE); 151 } 152 else 153 pMerge = (const ScMergeAttr*) pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE); 154 155 rEndX = rStartX + pMerge->GetColMerge() - 1; 156 rEndY = rStartY + pMerge->GetRowMerge() - 1; 157 } 158 159 #define CELLINFO(x,y) pRowInfo[nArrY+y].pCellInfo[nArrX+x] 160 161 void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, 162 SCTAB nTab, double nScaleX, double nScaleY, 163 sal_Bool bPageMode, sal_Bool bFormulaMode, const ScMarkData* pMarkData ) 164 { 165 DBG_ASSERT( pTab[nTab], "Tabelle existiert nicht" ); 166 167 sal_Bool bLayoutRTL = IsLayoutRTL( nTab ); 168 169 ScDocumentPool* pPool = xPoolHelper->GetDocPool(); 170 ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool(); 171 172 RowInfo* pRowInfo = rTabInfo.mpRowInfo; 173 174 const SvxBrushItem* pDefBackground = 175 (const SvxBrushItem*) &pPool->GetDefaultItem( ATTR_BACKGROUND ); 176 const ScMergeAttr* pDefMerge = 177 (const ScMergeAttr*) &pPool->GetDefaultItem( ATTR_MERGE ); 178 const SvxShadowItem* pDefShadow = 179 (const SvxShadowItem*) &pPool->GetDefaultItem( ATTR_SHADOW ); 180 181 SCROW nThisRow; 182 SCCOL nX; 183 SCROW nY; 184 SCsROW nSignedY; 185 SCCOL nArrX; 186 SCSIZE nArrY; 187 SCSIZE nArrCount; 188 sal_Bool bAnyMerged = sal_False; 189 sal_Bool bAnyShadow = sal_False; 190 sal_Bool bAnyCondition = sal_False; 191 192 sal_Bool bTabProtect = IsTabProtected(nTab); 193 194 // fuer Blockmarken von zusammengefassten Zellen mit 195 // versteckter erster Zeile / Spalte 196 sal_Bool bPaintMarks = sal_False; 197 sal_Bool bSkipMarks = sal_False; 198 SCCOL nBlockStartX = 0, nBlockEndX = 0; 199 SCROW nBlockEndY = 0, nBlockStartY = 0; 200 if (pMarkData && pMarkData->IsMarked()) 201 { 202 ScRange aTmpRange; 203 pMarkData->GetMarkArea(aTmpRange); 204 if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() ) 205 { 206 nBlockStartX = aTmpRange.aStart.Col(); 207 nBlockStartY = aTmpRange.aStart.Row(); 208 nBlockEndX = aTmpRange.aEnd.Col(); 209 nBlockEndY = aTmpRange.aEnd.Row(); 210 ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab ); //? noetig ? 211 if (pMarkData->IsMarkNegative()) 212 bSkipMarks = sal_True; 213 else 214 bPaintMarks = sal_True; 215 } 216 } 217 218 // zuerst nur die Eintraege fuer die ganze Spalte 219 220 nArrY=0; 221 SCROW nYExtra = nY2+1; 222 sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight; 223 SCROW nDocHeightEndRow = -1; 224 for (nSignedY=((SCsROW)nY1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++) 225 { 226 if (nSignedY >= 0) 227 nY = (SCROW) nSignedY; 228 else 229 nY = MAXROW+1; // ungueltig 230 231 if (nY > nDocHeightEndRow) 232 { 233 if (ValidRow(nY)) 234 nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow ); 235 else 236 nDocHeight = ScGlobal::nStdRowHeight; 237 } 238 239 if ( nArrY==0 || nDocHeight || nY > MAXROW ) 240 { 241 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 242 pThisRowInfo->pCellInfo = NULL; // wird unten belegt 243 244 sal_uInt16 nHeight = (sal_uInt16) ( nDocHeight * nScaleY ); 245 if (!nHeight) 246 nHeight = 1; 247 248 pThisRowInfo->nRowNo = nY; //! Fall < 0 ? 249 pThisRowInfo->nHeight = nHeight; 250 pThisRowInfo->bEmptyBack = sal_True; 251 pThisRowInfo->bEmptyText = sal_True; 252 pThisRowInfo->bChanged = sal_True; 253 pThisRowInfo->bAutoFilter = sal_False; 254 pThisRowInfo->bPushButton = sal_False; 255 pThisRowInfo->nRotMaxCol = SC_ROTMAX_NONE; 256 257 ++nArrY; 258 if (nArrY >= ROWINFO_MAX) 259 { 260 DBG_ERROR("Zu grosser Bereich bei FillInfo" ); 261 nYExtra = nSignedY; // Ende 262 nY2 = nYExtra - 1; // Bereich anpassen 263 } 264 } 265 else 266 if (nSignedY==(SCsROW) nYExtra) // zusaetzliche Zeile verdeckt ? 267 ++nYExtra; 268 } 269 nArrCount = nArrY; // incl. Dummys 270 271 // rotierter Text... 272 273 // Attribut im Dokument ueberhaupt verwendet? 274 sal_Bool bAnyItem = sal_False; 275 sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE ); 276 for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++) 277 if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem )) 278 { 279 bAnyItem = sal_True; 280 break; 281 } 282 283 SCCOL nRotMax = nX2; 284 if ( bAnyItem && HasAttrib( 0,nY1,nTab, MAXCOL,nY2+1,nTab, 285 HASATTR_ROTATE | HASATTR_CONDITIONAL ) ) 286 { 287 //! Conditionals auch bei HASATTR_ROTATE abfragen ???? 288 289 DBG_ASSERT( nArrCount>2, "nArrCount zu klein" ); 290 // FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-2, nX1, nX2 ); 291 FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nX1, nX2 ); 292 // FindMaxRotCol setzt nRotMaxCol 293 294 for (nArrY=0; nArrY<nArrCount; nArrY++) 295 if (pRowInfo[nArrY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrY].nRotMaxCol > nRotMax) 296 nRotMax = pRowInfo[nArrY].nRotMaxCol; 297 } 298 299 // Zell-Infos erst nach dem Test auf gedrehte allozieren 300 // bis nRotMax wegen nRotateDir Flag 301 302 for (nArrY=0; nArrY<nArrCount; nArrY++) 303 { 304 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 305 nY = pThisRowInfo->nRowNo; 306 pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ]; // vom Aufrufer zu loeschen ! 307 308 for (nArrX=0; nArrX<=nRotMax+2; nArrX++) // Zell-Infos vorbelegen 309 { 310 if (nArrX>0) 311 nX = nArrX-1; 312 else 313 nX = MAXCOL+1; // ungueltig 314 315 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX]; 316 pInfo->bEmptyCellText = sal_True; 317 pInfo->pCell = NULL; 318 if (bPaintMarks) 319 pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX 320 && nY >= nBlockStartY && nY <= nBlockEndY ); 321 else 322 pInfo->bMarked = sal_False; 323 pInfo->nWidth = 0; 324 325 pInfo->nClipMark = SC_CLIPMARK_NONE; 326 pInfo->bMerged = sal_False; 327 pInfo->bHOverlapped = sal_False; 328 pInfo->bVOverlapped = sal_False; 329 pInfo->bAutoFilter = sal_False; 330 pInfo->bPushButton = sal_False; 331 pInfo->bPopupButton = false; 332 pInfo->bFilterActive = false; 333 pInfo->nRotateDir = SC_ROTDIR_NONE; 334 335 pInfo->bPrinted = sal_False; // view-intern 336 pInfo->bHideGrid = sal_False; // view-intern 337 pInfo->bEditEngine = sal_False; // view-intern 338 339 pInfo->pBackground = NULL; //! weglassen? 340 pInfo->pPatternAttr = NULL; 341 pInfo->pConditionSet= NULL; 342 343 pInfo->pLinesAttr = NULL; 344 pInfo->mpTLBRLine = NULL; 345 pInfo->mpBLTRLine = NULL; 346 347 pInfo->pShadowAttr = pDefShadow; 348 pInfo->pHShadowOrigin = NULL; 349 pInfo->pVShadowOrigin = NULL; 350 } 351 } 352 353 for (nArrX=nX2+3; nArrX<=nRotMax+2; nArrX++) // restliche Breiten eintragen 354 { 355 nX = nArrX-1; 356 if ( ValidCol(nX) ) 357 { 358 if (!ColHidden(nX, nTab)) 359 { 360 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * nScaleX); 361 if (!nThisWidth) 362 nThisWidth = 1; 363 364 pRowInfo[0].pCellInfo[nArrX].nWidth = nThisWidth; 365 } 366 } 367 } 368 369 for (nArrX=0; nArrX<=nX2+2; nArrX++) // links & rechts + 1 370 { 371 nX = (nArrX>0) ? nArrX-1 : MAXCOL+1; // negativ -> ungueltig 372 373 if ( ValidCol(nX) ) 374 { 375 // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes 376 // will disturb the output 377 378 // TODO: Optimize this loop. 379 if (!ColHidden(nX, nTab)) 380 { 381 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * nScaleX); 382 if (!nThisWidth) 383 nThisWidth = 1; 384 385 pRowInfo[0].pCellInfo[nArrX].nWidth = nThisWidth; //! dies sollte reichen 386 387 ScColumn* pThisCol = &pTab[nTab]->aCol[nX]; // Spalten-Daten 388 389 nArrY = 1; 390 SCSIZE nUIndex; 391 bool bHiddenRow = true; 392 SCROW nHiddenEndRow = -1; 393 (void) pThisCol->Search( nY1, nUIndex ); 394 while ( nUIndex < pThisCol->nCount && 395 (nThisRow=pThisCol->pItems[nUIndex].nRow) <= nY2 ) 396 { 397 if (nThisRow > nHiddenEndRow) 398 bHiddenRow = RowHidden( nThisRow, nTab, nHiddenEndRow); 399 if ( !bHiddenRow ) 400 { 401 while ( pRowInfo[nArrY].nRowNo < nThisRow ) 402 ++nArrY; 403 DBG_ASSERT( pRowInfo[nArrY].nRowNo == nThisRow, "Zeile nicht gefunden in FillInfo" ); 404 405 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 406 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX]; 407 pInfo->pCell = pThisCol->pItems[nUIndex].pCell; 408 if (pInfo->pCell->GetCellType() != CELLTYPE_NOTE) 409 { 410 pThisRowInfo->bEmptyText = sal_False; // Zeile nicht leer 411 pInfo->bEmptyCellText = sal_False; // Zelle nicht leer 412 } 413 ++nArrY; 414 } 415 ++nUIndex; 416 } 417 418 if (nX+1 >= nX1) // Attribute/Blockmarken ab nX1-1 419 { 420 ScAttrArray* pThisAttrArr = pThisCol->pAttrArray; // Attribute 421 422 nArrY = 0; 423 const ScPatternAttr* pPattern; 424 SCROW nCurRow=nY1; // einzelne Zeile 425 if (nCurRow>0) 426 --nCurRow; // oben 1 mehr 427 else 428 nArrY = 1; 429 nThisRow=nCurRow; // Ende des Bereichs 430 SCSIZE nIndex; 431 (void) pThisAttrArr->Search( nCurRow, nIndex ); 432 433 434 do 435 { 436 nThisRow=pThisAttrArr->pData[nIndex].nRow; // Ende des Bereichs 437 pPattern=pThisAttrArr->pData[nIndex].pPattern; 438 439 const SvxBrushItem* pBackground = (const SvxBrushItem*) 440 &pPattern->GetItem(ATTR_BACKGROUND); 441 const SvxBoxItem* pLinesAttr = (const SvxBoxItem*) 442 &pPattern->GetItem(ATTR_BORDER); 443 444 const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >( 445 &pPattern->GetItem( ATTR_BORDER_TLBR ) ); 446 const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >( 447 &pPattern->GetItem( ATTR_BORDER_BLTR ) ); 448 449 const SvxShadowItem* pShadowAttr = (const SvxShadowItem*) 450 &pPattern->GetItem(ATTR_SHADOW); 451 if (pShadowAttr != pDefShadow) 452 bAnyShadow = sal_True; 453 454 const ScMergeAttr* pMergeAttr = (const ScMergeAttr*) 455 &pPattern->GetItem(ATTR_MERGE); 456 sal_Bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge ); 457 sal_uInt16 nOverlap = ((const ScMergeFlagAttr*) &pPattern->GetItemSet(). 458 Get(ATTR_MERGE_FLAG))->GetValue(); 459 sal_Bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0); 460 sal_Bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0); 461 sal_Bool bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0); 462 sal_Bool bPushButton = ((nOverlap & SC_MF_BUTTON) != 0); 463 sal_Bool bScenario = ((nOverlap & SC_MF_SCENARIO) != 0); 464 bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0); 465 bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0); 466 if (bMerged||bHOverlapped||bVOverlapped) 467 bAnyMerged = sal_True; // intern 468 469 sal_Bool bHidden, bHideFormula; 470 if (bTabProtect) 471 { 472 const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&) 473 pPattern->GetItem(ATTR_PROTECTION); 474 bHidden = rProtAttr.GetHideCell(); 475 bHideFormula = rProtAttr.GetHideFormula(); 476 } 477 else 478 bHidden = bHideFormula = sal_False; 479 480 sal_uLong nConditional = ((const SfxUInt32Item&)pPattern-> 481 GetItem(ATTR_CONDITIONAL)).GetValue(); 482 const ScConditionalFormat* pCondForm = NULL; 483 if ( nConditional && pCondFormList ) 484 pCondForm = pCondFormList->GetFormat( nConditional ); 485 486 do 487 { 488 SCROW nLastHiddenRow = -1; 489 bool bRowHidden = RowHidden(nCurRow, nTab, nLastHiddenRow); 490 if ( nArrY==0 || !bRowHidden ) 491 { 492 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 493 if (pBackground != pDefBackground) // Spalten-HG == Standard ? 494 pThisRowInfo->bEmptyBack = sal_False; 495 if (bAutoFilter) 496 pThisRowInfo->bAutoFilter = sal_True; 497 if (bPushButton) 498 pThisRowInfo->bPushButton = sal_True; 499 500 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX]; 501 pInfo->pBackground = pBackground; 502 pInfo->pPatternAttr = pPattern; 503 pInfo->bMerged = bMerged; 504 pInfo->bHOverlapped = bHOverlapped; 505 pInfo->bVOverlapped = bVOverlapped; 506 pInfo->bAutoFilter = bAutoFilter; 507 pInfo->bPushButton = bPushButton; 508 pInfo->bPopupButton = bPopupButton; 509 pInfo->bFilterActive = bFilterActive; 510 pInfo->pLinesAttr = pLinesAttr; 511 pInfo->mpTLBRLine = pTLBRLine; 512 pInfo->mpBLTRLine = pBLTRLine; 513 pInfo->pShadowAttr = pShadowAttr; 514 // nWidth wird nicht mehr einzeln gesetzt 515 516 sal_Bool bEmbed = sal_False; //bIsEmbedded && 517 nTab >= aEmbedRange.aStart.Tab() && 518 nTab <= aEmbedRange.aEnd.Tab() && 519 nX >= aEmbedRange.aStart.Col() && 520 nX <= aEmbedRange.aEnd.Col() && 521 nCurRow >= aEmbedRange.aStart.Row() && 522 nCurRow <= aEmbedRange.aEnd.Row(); 523 524 if (bScenario) 525 { 526 pInfo->pBackground = ScGlobal::GetButtonBrushItem(); 527 pThisRowInfo->bEmptyBack = sal_False; 528 } 529 else if (bEmbed) 530 { 531 pInfo->pBackground = ScGlobal::GetEmbeddedBrushItem(); 532 pThisRowInfo->bEmptyBack = sal_False; 533 } 534 535 if (bHidden || ( bFormulaMode && bHideFormula && pInfo->pCell 536 && pInfo->pCell->GetCellType() 537 == CELLTYPE_FORMULA )) 538 pInfo->bEmptyCellText = sal_True; 539 540 if ( pCondForm ) 541 { 542 String aStyle = pCondForm->GetCellStyle( pInfo->pCell, 543 ScAddress( nX, nCurRow, nTab ) ); 544 if (aStyle.Len()) 545 { 546 SfxStyleSheetBase* pStyleSheet = 547 pStlPool->Find( aStyle, SFX_STYLE_FAMILY_PARA ); 548 if ( pStyleSheet ) 549 { 550 //! Style-Sets cachen !!! 551 pInfo->pConditionSet = &pStyleSheet->GetItemSet(); 552 bAnyCondition = sal_True; 553 } 554 // if style is not there, treat like no condition 555 } 556 } 557 558 ++nArrY; 559 } 560 else if (bRowHidden && nLastHiddenRow >= 0) 561 { 562 nCurRow = nLastHiddenRow; 563 if (nCurRow > nThisRow) 564 nCurRow = nThisRow; 565 } 566 ++nCurRow; 567 } 568 while (nCurRow <= nThisRow && nCurRow <= nYExtra); 569 ++nIndex; 570 } 571 while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra ); 572 573 574 if (pMarkData && pMarkData->IsMultiMarked()) 575 { 576 // Blockmarken 577 const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX; 578 sal_Bool bThisMarked; 579 nArrY = 1; 580 nCurRow = nY1; // einzelne Zeile 581 nThisRow = nY1; // Ende des Bereichs 582 583 if ( pThisMarkArr->Search( nY1, nIndex ) ) 584 { 585 do 586 { 587 nThisRow=pThisMarkArr->pData[nIndex].nRow; // Ende des Bereichs 588 bThisMarked=pThisMarkArr->pData[nIndex].bMarked; 589 590 do 591 { 592 if ( !RowHidden( nCurRow,nTab ) ) 593 { 594 if ( bThisMarked ) 595 { 596 sal_Bool bSkip = bSkipMarks && 597 nX >= nBlockStartX && 598 nX <= nBlockEndX && 599 nCurRow >= nBlockStartY && 600 nCurRow <= nBlockEndY; 601 if (!bSkip) 602 { 603 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 604 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX]; 605 pInfo->bMarked = sal_True; 606 } 607 } 608 ++nArrY; 609 } 610 ++nCurRow; 611 } 612 while (nCurRow <= nThisRow && nCurRow <= nY2); 613 ++nIndex; 614 } 615 while ( nIndex < pThisMarkArr->nCount && nThisRow < nY2 ); 616 } 617 } 618 } 619 else // vordere Spalten 620 { 621 for (nArrY=1; nArrY+1<nArrCount; nArrY++) 622 { 623 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 624 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX]; 625 626 pInfo->nWidth = nThisWidth; //! oder nur 0 abfragen ?? 627 } 628 } 629 } 630 } 631 else 632 pRowInfo[0].pCellInfo[nArrX].nWidth = STD_COL_WIDTH; 633 // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht 634 } 635 636 //------------------------------------------------------------------------- 637 // bedingte Formatierung auswerten 638 639 if (bAnyCondition) 640 { 641 for (nArrY=0; nArrY<nArrCount; nArrY++) 642 { 643 for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr 644 { 645 CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nArrX]; 646 const SfxItemSet* pCondSet = pInfo->pConditionSet; 647 if (pCondSet) 648 { 649 const SfxPoolItem* pItem; 650 651 // Hintergrund 652 if ( pCondSet->GetItemState( ATTR_BACKGROUND, sal_True, &pItem ) == SFX_ITEM_SET ) 653 { 654 pInfo->pBackground = (const SvxBrushItem*) pItem; 655 pRowInfo[nArrY].bEmptyBack = sal_False; 656 } 657 658 // Umrandung 659 if ( pCondSet->GetItemState( ATTR_BORDER, sal_True, &pItem ) == SFX_ITEM_SET ) 660 pInfo->pLinesAttr = (const SvxBoxItem*) pItem; 661 662 if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, sal_True, &pItem ) == SFX_ITEM_SET ) 663 pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem ); 664 if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, sal_True, &pItem ) == SFX_ITEM_SET ) 665 pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem ); 666 667 // Schatten 668 if ( pCondSet->GetItemState( ATTR_SHADOW, sal_True, &pItem ) == SFX_ITEM_SET ) 669 { 670 pInfo->pShadowAttr = (const SvxShadowItem*) pItem; 671 bAnyShadow = sal_True; 672 } 673 } 674 } 675 } 676 } 677 678 // bedingte Formatierung Ende 679 //------------------------------------------------------------------------- 680 681 // 682 // Daten von zusammengefassten Zellen anpassen 683 // 684 685 if (bAnyMerged) 686 { 687 for (nArrY=0; nArrY<nArrCount; nArrY++) 688 { 689 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 690 nSignedY = nArrY ? pThisRowInfo->nRowNo : ((SCsROW)nY1)-1; 691 692 for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr 693 { 694 SCsCOL nSignedX = ((SCsCOL) nArrX) - 1; 695 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX]; 696 697 if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped) 698 { 699 SCsCOL nStartX; 700 SCsROW nStartY; 701 SCsCOL nEndX; 702 SCsROW nEndY; 703 lcl_GetMergeRange( nSignedX,nSignedY, nArrY, this,pRowInfo, nX1,nY1,nX2,nY2,nTab, 704 nStartX,nStartY, nEndX,nEndY ); 705 const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab ); 706 const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab ); 707 const SfxPoolItem* pItem; 708 709 // Hintergrund kopieren (oder in output.cxx) 710 711 if ( !pStartCond || pStartCond-> 712 GetItemState(ATTR_BACKGROUND,sal_True,&pItem) != SFX_ITEM_SET ) 713 pItem = &pStartPattern->GetItem(ATTR_BACKGROUND); 714 pInfo->pBackground = (const SvxBrushItem*) pItem; 715 pRowInfo[nArrY].bEmptyBack = sal_False; 716 717 // Schatten 718 719 if ( !pStartCond || pStartCond-> 720 GetItemState(ATTR_SHADOW,sal_True,&pItem) != SFX_ITEM_SET ) 721 pItem = &pStartPattern->GetItem(ATTR_SHADOW); 722 pInfo->pShadowAttr = (const SvxShadowItem*) pItem; 723 if (pInfo->pShadowAttr != pDefShadow) 724 bAnyShadow = sal_True; 725 726 // Blockmarken - wieder mit Original-Merge-Werten 727 728 sal_Bool bCellMarked = sal_False; 729 if (bPaintMarks) 730 bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX 731 && nStartX <= (SCsCOL) nBlockEndX 732 && nStartY >= (SCsROW) nBlockStartY 733 && nStartY <= (SCsROW) nBlockEndY ); 734 if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked) 735 { 736 const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX; 737 SCSIZE nIndex; 738 if ( pThisMarkArr->Search( nStartY, nIndex ) ) 739 bCellMarked=pThisMarkArr->pData[nIndex].bMarked; 740 } 741 742 pInfo->bMarked = bCellMarked; 743 } 744 } 745 } 746 } 747 748 if (bAnyShadow) // Schatten verteilen 749 { 750 for (nArrY=0; nArrY<nArrCount; nArrY++) 751 { 752 sal_Bool bTop = ( nArrY == 0 ); 753 sal_Bool bBottom = ( nArrY+1 == nArrCount ); 754 755 for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr 756 { 757 sal_Bool bLeft = ( nArrX == nX1 ); 758 sal_Bool bRight = ( nArrX == nX2+2 ); 759 760 CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nArrX]; 761 const SvxShadowItem* pThisAttr = pInfo->pShadowAttr; 762 SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE; 763 if (eLoc != SVX_SHADOW_NONE) 764 { 765 // oder Test auf != eLoc 766 767 SCsCOL nDxPos = 1; 768 SCsCOL nDxNeg = -1; 769 770 while ( nArrX+nDxPos < nX2+2 && pRowInfo[0].pCellInfo[nArrX+nDxPos].nWidth == 0 ) 771 ++nDxPos; 772 while ( nArrX+nDxNeg > nX1 && pRowInfo[0].pCellInfo[nArrX+nDxNeg].nWidth == 0 ) 773 --nDxNeg; 774 775 sal_Bool bLeftDiff = !bLeft && 776 CELLINFO(nDxNeg,0).pShadowAttr->GetLocation() == SVX_SHADOW_NONE; 777 sal_Bool bRightDiff = !bRight && 778 CELLINFO(nDxPos,0).pShadowAttr->GetLocation() == SVX_SHADOW_NONE; 779 sal_Bool bTopDiff = !bTop && 780 CELLINFO(0,-1).pShadowAttr->GetLocation() == SVX_SHADOW_NONE; 781 sal_Bool bBottomDiff = !bBottom && 782 CELLINFO(0,1).pShadowAttr->GetLocation() == SVX_SHADOW_NONE; 783 784 if ( bLayoutRTL ) 785 { 786 switch (eLoc) 787 { 788 case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break; 789 case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break; 790 case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_TOPLEFT; break; 791 case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break; 792 default: 793 { 794 // added to avoid warnings 795 } 796 } 797 } 798 799 switch (eLoc) 800 { 801 case SVX_SHADOW_BOTTOMRIGHT: 802 if (bBottomDiff) 803 { 804 CELLINFO(0,1).pHShadowOrigin = pThisAttr; 805 CELLINFO(0,1).eHShadowPart = 806 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ; 807 } 808 if (bRightDiff) 809 { 810 CELLINFO(1,0).pVShadowOrigin = pThisAttr; 811 CELLINFO(1,0).eVShadowPart = 812 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT; 813 } 814 if (bBottomDiff && bRightDiff) 815 { 816 CELLINFO(1,1).pHShadowOrigin = pThisAttr; 817 CELLINFO(1,1).eHShadowPart = SC_SHADOW_CORNER; 818 } 819 break; 820 821 case SVX_SHADOW_BOTTOMLEFT: 822 if (bBottomDiff) 823 { 824 CELLINFO(0,1).pHShadowOrigin = pThisAttr; 825 CELLINFO(0,1).eHShadowPart = 826 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ; 827 } 828 if (bLeftDiff) 829 { 830 CELLINFO(-1,0).pVShadowOrigin = pThisAttr; 831 CELLINFO(-1,0).eVShadowPart = 832 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT; 833 } 834 if (bBottomDiff && bLeftDiff) 835 { 836 CELLINFO(-1,1).pHShadowOrigin = pThisAttr; 837 CELLINFO(-1,1).eHShadowPart = SC_SHADOW_CORNER; 838 } 839 break; 840 841 case SVX_SHADOW_TOPRIGHT: 842 if (bTopDiff) 843 { 844 CELLINFO(0,-1).pHShadowOrigin = pThisAttr; 845 CELLINFO(0,-1).eHShadowPart = 846 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ; 847 } 848 if (bRightDiff) 849 { 850 CELLINFO(1,0).pVShadowOrigin = pThisAttr; 851 CELLINFO(1,0).eVShadowPart = 852 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT; 853 } 854 if (bTopDiff && bRightDiff) 855 { 856 CELLINFO(1,-1).pHShadowOrigin = pThisAttr; 857 CELLINFO(1,-1).eHShadowPart = SC_SHADOW_CORNER; 858 } 859 break; 860 861 case SVX_SHADOW_TOPLEFT: 862 if (bTopDiff) 863 { 864 CELLINFO(0,-1).pHShadowOrigin = pThisAttr; 865 CELLINFO(0,-1).eHShadowPart = 866 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ; 867 } 868 if (bLeftDiff) 869 { 870 CELLINFO(-1,0).pVShadowOrigin = pThisAttr; 871 CELLINFO(-1,0).eVShadowPart = 872 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT; 873 } 874 if (bTopDiff && bLeftDiff) 875 { 876 CELLINFO(-1,-1).pHShadowOrigin = pThisAttr; 877 CELLINFO(-1,-1).eHShadowPart = SC_SHADOW_CORNER; 878 } 879 break; 880 881 default: 882 DBG_ERROR("falscher Shadow-Enum"); 883 } 884 } 885 } 886 } 887 } 888 889 rTabInfo.mnArrCount = sal::static_int_cast<sal_uInt16>(nArrCount); 890 rTabInfo.mbPageMode = bPageMode; 891 892 // ======================================================================== 893 // *** create the frame border array *** 894 895 // RowInfo structs are filled in the range [ 0 , nArrCount-1 ] 896 // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ] 897 898 size_t nColCount = nX2 - nX1 + 3; 899 size_t nRowCount = nArrCount; 900 901 svx::frame::Array& rArray = rTabInfo.maArray; 902 rArray.Initialize( nColCount, nRowCount ); 903 rArray.SetUseDiagDoubleClipping( false ); 904 905 for( size_t nRow = 0; nRow < nRowCount; ++nRow ) 906 { 907 sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow ); 908 RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ]; 909 910 for( size_t nCol = 0; nCol < nColCount; ++nCol ) 911 { 912 sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nX1 ); 913 const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ]; 914 915 const SvxBoxItem* pBox = rInfo.pLinesAttr; 916 const SvxLineItem* pTLBR = rInfo.mpTLBRLine; 917 const SvxLineItem* pBLTR = rInfo.mpBLTRLine; 918 919 size_t nFirstCol = nCol; 920 size_t nFirstRow = nRow; 921 922 // *** merged cells *** ------------------------------------------- 923 924 if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) ) 925 { 926 // *** insert merged range in svx::frame::Array *** 927 928 /* #i69369# top-left cell of a merged range may be located in 929 a hidden column or row. Use lcl_GetMergeRange() to find the 930 complete merged range, then calculate dimensions and 931 document position of the visible range. */ 932 933 // note: document columns are always one less than CellInfoX coords 934 // note: document rows must be looked up in RowInfo structs 935 936 // current column and row in document coordinates 937 SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 ); 938 SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nY1 - 1) ); 939 940 // find entire merged range in document, returns signed document coordinates 941 SCsCOL nFirstRealDocColS, nLastRealDocColS; 942 SCsROW nFirstRealDocRowS, nLastRealDocRowS; 943 lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ), 944 nCellInfoY, this, pRowInfo, nX1,nY1,nX2,nY2,nTab, 945 nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS ); 946 947 // *complete* merged range in document coordinates 948 SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS ); 949 SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS ); 950 SCCOL nLastRealDocCol = static_cast< SCCOL >( nLastRealDocColS ); 951 SCROW nLastRealDocRow = static_cast< SCROW >( nLastRealDocRowS ); 952 953 // first visible column (nX1-1 is first processed document column) 954 SCCOL nFirstDocCol = (nX1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nX1 - 1 ) : nFirstRealDocCol; 955 sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( nFirstDocCol + 1 ); 956 nFirstCol = static_cast< size_t >( nFirstCellInfoX - nX1 ); 957 958 // last visible column (nX2+1 is last processed document column) 959 SCCOL nLastDocCol = (nX2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nX2 + 1 ) : nLastRealDocCol; 960 sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( nLastDocCol + 1 ); 961 size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nX1 ); 962 963 // first visible row 964 sal_uInt16 nFirstCellInfoY = nCellInfoY; 965 while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) || 966 ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nY1 - 1 ) >= nFirstRealDocRow)) ) 967 --nFirstCellInfoY; 968 SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nY1 - 1 ); 969 nFirstRow = static_cast< size_t >( nFirstCellInfoY ); 970 971 // last visible row 972 sal_uInt16 nLastCellInfoY = nCellInfoY; 973 while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) && 974 (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) ) 975 ++nLastCellInfoY; 976 SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nY1 - 1 ); 977 size_t nLastRow = static_cast< size_t >( nLastCellInfoY ); 978 979 // insert merged range 980 rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow ); 981 982 // *** find additional size not included in svx::frame::Array *** 983 984 // additional space before first column 985 if( nFirstCol == 0 ) 986 { 987 long nSize = 0; 988 for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol ) 989 nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * nScaleX ), 1L ); 990 rArray.SetAddMergedLeftSize( nCol, nRow, nSize ); 991 } 992 // additional space after last column 993 if( nLastCol + 1 == nColCount ) 994 { 995 long nSize = 0; 996 for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol ) 997 nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * nScaleX ), 1L ); 998 rArray.SetAddMergedRightSize( nCol, nRow, nSize ); 999 } 1000 // additional space above first row 1001 if( nFirstRow == 0 ) 1002 { 1003 long nSize = 0; 1004 for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow ) 1005 nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * nScaleY ), 1L ); 1006 rArray.SetAddMergedTopSize( nCol, nRow, nSize ); 1007 } 1008 // additional space beyond last row 1009 if( nLastRow + 1 == nRowCount ) 1010 { 1011 long nSize = 0; 1012 for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow ) 1013 nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * nScaleY ), 1L ); 1014 rArray.SetAddMergedBottomSize( nCol, nRow, nSize ); 1015 } 1016 1017 // *** use line attributes from real origin cell *** 1018 1019 if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) ) 1020 { 1021 if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) ) 1022 { 1023 const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab ); 1024 pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) ); 1025 pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) ); 1026 pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) ); 1027 } 1028 else 1029 { 1030 pBox = 0; 1031 pTLBR = pBLTR = 0; 1032 } 1033 } 1034 } 1035 1036 // *** borders *** ------------------------------------------------ 1037 1038 if( pBox ) 1039 { 1040 rArray.SetCellStyleLeft( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(), nScaleX ) ); 1041 rArray.SetCellStyleRight( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(), nScaleX ) ); 1042 rArray.SetCellStyleTop( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(), nScaleY ) ); 1043 rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), nScaleY ) ); 1044 } 1045 1046 if( pTLBR ) 1047 rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), nScaleY ) ); 1048 if( rInfo.mpBLTRLine ) 1049 rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), nScaleY ) ); 1050 } 1051 } 1052 1053 /* Mirror the entire frame array. 1054 1st param = Mirror the vertical double line styles as well. 1055 2nd param = Do not swap diagonal lines. 1056 */ 1057 if( bLayoutRTL ) 1058 rArray.MirrorSelfX( true, false ); 1059 } 1060 1061 // ============================================================================ 1062 1063 ScTableInfo::ScTableInfo() : 1064 mpRowInfo( new RowInfo[ ROWINFO_MAX ] ), 1065 mbPageMode( false ) 1066 { 1067 for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx ) 1068 mpRowInfo[ nIdx ].pCellInfo = 0; 1069 } 1070 1071 ScTableInfo::~ScTableInfo() 1072 { 1073 for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx ) 1074 delete [] mpRowInfo[ nIdx ].pCellInfo; 1075 delete [] mpRowInfo; 1076 } 1077 1078 // ============================================================================ 1079 1080