Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / fillinfo.cxx
blob225c0cec576936a8a2fd0c65aede784823467a39
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4 * This file is part of the LibreOffice project.
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 * This file incorporates work covered by the following license notice:
12 * Licensed to the Apache Software Foundation (ASF) under one or more
13 * contributor license agreements. See the NOTICE file distributed
14 * with this work for additional information regarding copyright
15 * ownership. The ASF licenses this file to you under the Apache
16 * License, Version 2.0 (the "License"); you may not use this file
17 * except in compliance with the License. You may obtain a copy of
18 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "scitems.hxx"
22 #include <editeng/boxitem.hxx>
23 #include <editeng/lineitem.hxx>
24 #include <editeng/editdata.hxx>
25 #include <editeng/shaditem.hxx>
26 #include <editeng/brushitem.hxx>
28 #include "fillinfo.hxx"
29 #include "document.hxx"
30 #include "formulacell.hxx"
31 #include "table.hxx"
32 #include "attrib.hxx"
33 #include "attarray.hxx"
34 #include "markarr.hxx"
35 #include "markdata.hxx"
36 #include "patattr.hxx"
37 #include "poolhelp.hxx"
38 #include "docpool.hxx"
39 #include "conditio.hxx"
40 #include "colorscale.hxx"
41 #include "stlpool.hxx"
42 #include "cellvalue.hxx"
43 #include "mtvcellfunc.hxx"
45 const sal_uInt16 ROWINFO_MAX = 1024;
48 enum FillInfoLinePos
50 FILP_TOP,
51 FILP_BOTTOM,
52 FILP_LEFT,
53 FILP_RIGHT
57 // aehnlich wie in output.cxx
59 static void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
60 ScDocument* pDoc, RowInfo* pRowInfo,
61 SCCOL nX1, SCROW nY1, SCCOL /* nX2 */, SCROW /* nY2 */, SCTAB nTab,
62 SCsCOL& rStartX, SCsROW& rStartY, SCsCOL& rEndX, SCsROW& rEndY )
64 CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
66 rStartX = nX;
67 rStartY = nY;
68 bool bHOver = pInfo->bHOverlapped;
69 bool bVOver = pInfo->bVOverlapped;
70 SCCOL nLastCol;
71 SCROW nLastRow;
73 while (bHOver) // nY konstant
75 --rStartX;
76 if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol))
78 bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
79 bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
81 else
83 sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
84 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
85 bHOver = ((nOverlap & SC_MF_HOR) != 0);
86 bVOver = ((nOverlap & SC_MF_VER) != 0);
90 while (bVOver)
92 --rStartY;
94 if (nArrY>0)
95 --nArrY; // lokale Kopie !
97 if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
98 !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
99 !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
100 (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
102 bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
104 else
106 sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
107 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
108 bVOver = ((nOverlap & SC_MF_VER) != 0);
112 const ScMergeAttr* pMerge;
113 if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
114 !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
115 !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
116 (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
118 pMerge = (const ScMergeAttr*) &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
119 GetItem(ATTR_MERGE);
121 else
122 pMerge = (const ScMergeAttr*) pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE);
124 rEndX = rStartX + pMerge->GetColMerge() - 1;
125 rEndY = rStartY + pMerge->GetRowMerge() - 1;
128 namespace {
130 class RowInfoFiller
132 ScDocument& mrDoc;
133 SCTAB mnTab;
134 RowInfo* mpRowInfo;
135 SCCOL mnArrX;
136 SCSIZE& mrArrY;
137 SCROW mnHiddenEndRow;
138 bool mbHiddenRow;
140 bool isHidden(size_t nRow)
142 SCROW nThisRow = static_cast<SCROW>(nRow);
143 if (nThisRow > mnHiddenEndRow)
144 mbHiddenRow = mrDoc.RowHidden(nThisRow, mnTab, NULL, &mnHiddenEndRow);
145 return mbHiddenRow;
148 void alignArray(size_t nRow)
150 while (mpRowInfo[mrArrY].nRowNo < static_cast<SCROW>(nRow))
151 ++mrArrY;
154 void setInfo(size_t nRow, const ScRefCellValue& rCell)
156 alignArray(nRow);
158 RowInfo* pThisRowInfo = &mpRowInfo[mrArrY];
159 CellInfo* pInfo = &pThisRowInfo->pCellInfo[mnArrX];
160 pInfo->maCell = rCell;
161 pThisRowInfo->bEmptyText = false;
162 pInfo->bEmptyCellText = false;
163 ++mrArrY;
166 public:
167 RowInfoFiller(ScDocument& rDoc, SCTAB nTab, RowInfo* pRowInfo, SCCOL nArrX, SCSIZE& rArrY) :
168 mrDoc(rDoc), mnTab(nTab), mpRowInfo(pRowInfo), mnArrX(nArrX), mrArrY(rArrY),
169 mnHiddenEndRow(-1), mbHiddenRow(false) {}
171 void operator() (size_t nRow, double fVal)
173 if (!isHidden(nRow))
174 setInfo(nRow, ScRefCellValue(fVal));
177 void operator() (size_t nRow, const svl::SharedString& rStr)
179 if (!isHidden(nRow))
180 setInfo(nRow, ScRefCellValue(&rStr));
183 void operator() (size_t nRow, const EditTextObject* p)
185 if (!isHidden(nRow))
186 setInfo(nRow, ScRefCellValue(p));
189 void operator() (size_t nRow, const ScFormulaCell* p)
191 if (!isHidden(nRow))
192 setInfo(nRow, ScRefCellValue(const_cast<ScFormulaCell*>(p)));
198 void ScDocument::FillInfo(
199 ScTableInfo& rTabInfo, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
200 SCTAB nTab, double fColScale, double fRowScale, bool bPageMode, bool bFormulaMode,
201 const ScMarkData* pMarkData )
203 OSL_ENSURE( maTabs[nTab], "Table does not exist" );
205 bool bLayoutRTL = IsLayoutRTL( nTab );
207 ScDocumentPool* pPool = xPoolHelper->GetDocPool();
208 ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool();
210 RowInfo* pRowInfo = rTabInfo.mpRowInfo;
212 const SvxBrushItem* pDefBackground =
213 (const SvxBrushItem*) &pPool->GetDefaultItem( ATTR_BACKGROUND );
214 const ScMergeAttr* pDefMerge =
215 (const ScMergeAttr*) &pPool->GetDefaultItem( ATTR_MERGE );
216 const SvxShadowItem* pDefShadow =
217 (const SvxShadowItem*) &pPool->GetDefaultItem( ATTR_SHADOW );
219 SCROW nThisRow;
220 SCCOL nX;
221 SCROW nY;
222 SCsROW nSignedY;
223 SCCOL nArrCol;
224 SCSIZE nArrRow;
225 SCSIZE nArrCount;
226 bool bAnyMerged = false;
227 bool bAnyShadow = false;
228 bool bAnyCondition = false;
229 bool bAnyPreview = false;
231 bool bTabProtect = IsTabProtected(nTab);
233 // fuer Blockmarken von zusammengefassten Zellen mit
234 // versteckter erster Zeile / Spalte
235 bool bPaintMarks = false;
236 bool bSkipMarks = false;
237 SCCOL nBlockStartX = 0, nBlockEndX = 0;
238 SCROW nBlockEndY = 0, nBlockStartY = 0;
239 if (pMarkData && pMarkData->IsMarked())
241 ScRange aTmpRange;
242 pMarkData->GetMarkArea(aTmpRange);
243 if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() )
245 nBlockStartX = aTmpRange.aStart.Col();
246 nBlockStartY = aTmpRange.aStart.Row();
247 nBlockEndX = aTmpRange.aEnd.Col();
248 nBlockEndY = aTmpRange.aEnd.Row();
249 ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab ); //? noetig ?
250 if (pMarkData->IsMarkNegative())
251 bSkipMarks = true;
252 else
253 bPaintMarks = true;
257 // zuerst nur die Eintraege fuer die ganze Spalte
259 nArrRow=0;
260 SCROW nYExtra = nRow2+1;
261 sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight;
262 SCROW nDocHeightEndRow = -1;
263 for (nSignedY=((SCsROW)nRow1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
265 if (nSignedY >= 0)
266 nY = (SCROW) nSignedY;
267 else
268 nY = MAXROW+1; // ungueltig
270 if (nY > nDocHeightEndRow)
272 if (ValidRow(nY))
273 nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
274 else
275 nDocHeight = ScGlobal::nStdRowHeight;
278 if ( nArrRow==0 || nDocHeight || nY > MAXROW )
280 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
281 pThisRowInfo->pCellInfo = NULL; // wird unten belegt
283 sal_uInt16 nHeight = (sal_uInt16) ( nDocHeight * fRowScale );
284 if (!nHeight)
285 nHeight = 1;
287 pThisRowInfo->nRowNo = nY; //! Fall < 0 ?
288 pThisRowInfo->nHeight = nHeight;
289 pThisRowInfo->bEmptyBack = true;
290 pThisRowInfo->bEmptyText = true;
291 pThisRowInfo->bChanged = true;
292 pThisRowInfo->bAutoFilter = false;
293 pThisRowInfo->bPivotButton = false;
294 pThisRowInfo->nRotMaxCol = SC_ROTMAX_NONE;
296 ++nArrRow;
297 if (nArrRow >= ROWINFO_MAX)
299 OSL_FAIL("FillInfo: Range too big" );
300 nYExtra = nSignedY; // Ende
301 nRow2 = nYExtra - 1; // Bereich anpassen
304 else
305 if (nSignedY==(SCsROW) nYExtra) // zusaetzliche Zeile verdeckt ?
306 ++nYExtra;
308 nArrCount = nArrRow; // incl. Dummys
310 // rotierter Text...
312 // Attribut im Dokument ueberhaupt verwendet?
313 bool bAnyItem = false;
314 sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
315 for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
316 if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem ))
318 bAnyItem = true;
319 break;
322 SCCOL nRotMax = nCol2;
323 if ( bAnyItem && HasAttrib( 0,nRow1,nTab, MAXCOL,nRow2+1,nTab,
324 HASATTR_ROTATE | HASATTR_CONDITIONAL ) )
326 //! Conditionals auch bei HASATTR_ROTATE abfragen ????
328 OSL_ENSURE( nArrCount>2, "nArrCount too small" );
329 FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nCol1, nCol2 );
330 // FindMaxRotCol setzt nRotMaxCol
332 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
333 if (pRowInfo[nArrRow].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrRow].nRotMaxCol > nRotMax)
334 nRotMax = pRowInfo[nArrRow].nRotMaxCol;
337 // Zell-Infos erst nach dem Test auf gedrehte allozieren
338 // bis nRotMax wegen nRotateDir Flag
340 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
342 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
343 nY = pThisRowInfo->nRowNo;
344 pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ]; // vom Aufrufer zu loeschen !
346 for (nArrCol=0; nArrCol<=nRotMax+2; nArrCol++) // Zell-Infos vorbelegen
348 if (nArrCol>0)
349 nX = nArrCol-1;
350 else
351 nX = MAXCOL+1; // ungueltig
353 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
354 pInfo->bEmptyCellText = true;
355 pInfo->maCell.clear();
356 if (bPaintMarks)
357 pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX
358 && nY >= nBlockStartY && nY <= nBlockEndY );
359 else
360 pInfo->bMarked = false;
361 pInfo->nWidth = 0;
363 pInfo->nClipMark = SC_CLIPMARK_NONE;
364 pInfo->bMerged = false;
365 pInfo->bHOverlapped = false;
366 pInfo->bVOverlapped = false;
367 pInfo->bAutoFilter = false;
368 pInfo->bPivotButton = false;
369 pInfo->bPivotPopupButton = false;
370 pInfo->bFilterActive = false;
371 pInfo->nRotateDir = SC_ROTDIR_NONE;
373 pInfo->bPrinted = false; // view-intern
374 pInfo->bHideGrid = false; // view-intern
375 pInfo->bEditEngine = false; // view-intern
377 pInfo->pBackground = NULL; //! weglassen?
378 pInfo->pPatternAttr = NULL;
379 pInfo->pConditionSet= NULL;
381 pInfo->pLinesAttr = NULL;
382 pInfo->mpTLBRLine = NULL;
383 pInfo->mpBLTRLine = NULL;
385 pInfo->pShadowAttr = pDefShadow;
386 pInfo->pHShadowOrigin = NULL;
387 pInfo->pVShadowOrigin = NULL;
391 for (nArrCol=nCol2+3; nArrCol<=nRotMax+2; nArrCol++) // restliche Breiten eintragen
393 nX = nArrCol-1;
394 if ( ValidCol(nX) )
396 if (!ColHidden(nX, nTab))
398 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
399 if (!nThisWidth)
400 nThisWidth = 1;
402 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;
407 ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
408 if(pCondFormList)
409 pCondFormList->startRendering();
411 for (nArrCol=0; nArrCol<=nCol2+2; nArrCol++) // links & rechts + 1
413 nX = (nArrCol>0) ? nArrCol-1 : MAXCOL+1; // negativ -> ungueltig
415 if ( ValidCol(nX) )
417 // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
418 // will disturb the output
420 // TODO: Optimize this loop.
421 if (!ColHidden(nX, nTab))
423 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
424 if (!nThisWidth)
425 nThisWidth = 1;
427 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth; //! dies sollte reichen
429 ScColumn* pThisCol = &maTabs[nTab]->aCol[nX]; // Spalten-Daten
431 nArrRow = 1;
432 // Iterate between rows nY1 and nY2 and pick up non-empty
433 // cells that are not hidden.
434 RowInfoFiller aFunc(*this, nTab, pRowInfo, nArrCol, nArrRow);
435 sc::ParseAllNonEmpty(
436 pThisCol->maCells.begin(), pThisCol->maCells, nRow1, nRow2, aFunc);
438 if (nX+1 >= nCol1) // Attribute/Blockmarken ab nX1-1
440 ScAttrArray* pThisAttrArr = pThisCol->pAttrArray; // Attribute
442 nArrRow = 0;
443 const ScPatternAttr* pPattern;
444 SCROW nCurRow=nRow1; // einzelne Zeile
445 if (nCurRow>0)
446 --nCurRow; // oben 1 mehr
447 else
448 nArrRow = 1;
449 nThisRow=nCurRow; // Ende des Bereichs
450 SCSIZE nIndex;
451 (void) pThisAttrArr->Search( nCurRow, nIndex );
456 nThisRow=pThisAttrArr->pData[nIndex].nRow; // Ende des Bereichs
457 pPattern=pThisAttrArr->pData[nIndex].pPattern;
459 const SvxBrushItem* pBackground = (const SvxBrushItem*)
460 &pPattern->GetItem(ATTR_BACKGROUND);
461 const SvxBoxItem* pLinesAttr = (const SvxBoxItem*)
462 &pPattern->GetItem(ATTR_BORDER);
464 const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >(
465 &pPattern->GetItem( ATTR_BORDER_TLBR ) );
466 const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >(
467 &pPattern->GetItem( ATTR_BORDER_BLTR ) );
469 const SvxShadowItem* pShadowAttr = (const SvxShadowItem*)
470 &pPattern->GetItem(ATTR_SHADOW);
471 if (pShadowAttr != pDefShadow)
472 bAnyShadow = true;
474 const ScMergeAttr* pMergeAttr = (const ScMergeAttr*)
475 &pPattern->GetItem(ATTR_MERGE);
476 bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge );
477 sal_uInt16 nOverlap = ((const ScMergeFlagAttr*) &pPattern->GetItemSet().
478 Get(ATTR_MERGE_FLAG))->GetValue();
479 bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0);
480 bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0);
481 bool bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0);
482 bool bPivotButton = ((nOverlap & SC_MF_BUTTON) != 0);
483 bool bScenario = ((nOverlap & SC_MF_SCENARIO) != 0);
484 bool bPivotPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
485 bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
486 if (bMerged||bHOverlapped||bVOverlapped)
487 bAnyMerged = true; // intern
489 bool bHidden, bHideFormula;
490 if (bTabProtect)
492 const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)
493 pPattern->GetItem(ATTR_PROTECTION);
494 bHidden = rProtAttr.GetHideCell();
495 bHideFormula = rProtAttr.GetHideFormula();
497 else
498 bHidden = bHideFormula = false;
500 const std::vector<sal_uInt32>& rCondFormats = static_cast<const ScCondFormatItem&>(pPattern->GetItem(ATTR_CONDITIONAL)).GetCondFormatData();
501 bool bContainsCondFormat = !rCondFormats.empty();
505 SCROW nLastHiddenRow = -1;
506 bool bRowHidden = RowHidden(nCurRow, nTab, NULL, &nLastHiddenRow);
507 if ( nArrRow==0 || !bRowHidden )
509 if ( GetPreviewCellStyle( nX, nCurRow, nTab ) != NULL )
510 bAnyPreview = true;
511 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
512 if (pBackground != pDefBackground) // Spalten-HG == Standard ?
513 pThisRowInfo->bEmptyBack = false;
514 if (bContainsCondFormat)
515 pThisRowInfo->bEmptyBack = false;
516 if (bAutoFilter)
517 pThisRowInfo->bAutoFilter = true;
518 if (bPivotButton || bPivotPopupButton)
519 pThisRowInfo->bPivotButton = true;
521 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
522 pInfo->pBackground = pBackground;
523 pInfo->pPatternAttr = pPattern;
524 pInfo->bMerged = bMerged;
525 pInfo->bHOverlapped = bHOverlapped;
526 pInfo->bVOverlapped = bVOverlapped;
527 pInfo->bAutoFilter = bAutoFilter;
528 pInfo->bPivotButton = bPivotButton;
529 pInfo->bPivotPopupButton = bPivotPopupButton;
530 pInfo->bFilterActive = bFilterActive;
531 pInfo->pLinesAttr = pLinesAttr;
532 pInfo->mpTLBRLine = pTLBRLine;
533 pInfo->mpBLTRLine = pBLTRLine;
534 pInfo->pShadowAttr = pShadowAttr;
535 // nWidth wird nicht mehr einzeln gesetzt
537 if (bScenario)
539 pInfo->pBackground = ScGlobal::GetButtonBrushItem();
540 pThisRowInfo->bEmptyBack = false;
543 if ( bContainsCondFormat )
545 bool bFound = false;
546 for(std::vector<sal_uInt32>::const_iterator itr = rCondFormats.begin();
547 itr != rCondFormats.end() && !bFound; ++itr)
549 ScConditionalFormat* pCondForm = pCondFormList->GetFormat(*itr);
550 if(!pCondForm)
551 continue;
553 ScCondFormatData aData = pCondForm->GetData(
554 pInfo->maCell, ScAddress(nX, nCurRow, nTab));
555 if (!aData.aStyleName.isEmpty())
557 SfxStyleSheetBase* pStyleSheet =
558 pStlPool->Find( aData.aStyleName, SFX_STYLE_FAMILY_PARA );
559 if ( pStyleSheet )
561 //! Style-Sets cachen !!!
562 pInfo->pConditionSet = &pStyleSheet->GetItemSet();
563 bAnyCondition = true;
565 // we need to check already here for protected cells
566 const SfxPoolItem* pItem;
567 if ( bTabProtect && pInfo->pConditionSet->GetItemState( ATTR_PROTECTION, true, &pItem ) == SFX_ITEM_SET )
569 const ScProtectionAttr* pProtAttr = static_cast<const ScProtectionAttr*>(pItem);
570 bHidden = pProtAttr->GetHideCell();
571 bHideFormula = pProtAttr->GetHideFormula();
574 bFound = true;
577 // if style is not there, treat like no condition
579 if(aData.pColorScale)
581 pInfo->pColorScale = aData.pColorScale;
582 bFound = true;
585 if(aData.pDataBar)
587 pInfo->pDataBar = aData.pDataBar;
588 bFound = true;
590 if(aData.pIconSet)
592 pInfo->pIconSet = aData.pIconSet;
593 bFound = true;
598 if (bHidden || (bFormulaMode && bHideFormula && pInfo->maCell.meType == CELLTYPE_FORMULA))
599 pInfo->bEmptyCellText = true;
601 ++nArrRow;
603 else if (bRowHidden && nLastHiddenRow >= 0)
605 nCurRow = nLastHiddenRow;
606 if (nCurRow > nThisRow)
607 nCurRow = nThisRow;
609 ++nCurRow;
611 while (nCurRow <= nThisRow && nCurRow <= nYExtra);
612 ++nIndex;
614 while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra );
617 if (pMarkData && pMarkData->IsMultiMarked())
619 // Blockmarken
620 const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX;
621 nArrRow = 1;
622 nCurRow = nRow1; // einzelne Zeile
623 nThisRow = nRow1; // Ende des Bereichs
625 if ( pThisMarkArr->Search( nRow1, nIndex ) )
627 bool bThisMarked;
630 nThisRow=pThisMarkArr->pData[nIndex].nRow; // Ende des Bereichs
631 bThisMarked=pThisMarkArr->pData[nIndex].bMarked;
635 if ( !RowHidden( nCurRow,nTab ) )
637 if ( bThisMarked )
639 bool bSkip = bSkipMarks &&
640 nX >= nBlockStartX &&
641 nX <= nBlockEndX &&
642 nCurRow >= nBlockStartY &&
643 nCurRow <= nBlockEndY;
644 if (!bSkip)
646 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
647 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
648 pInfo->bMarked = true;
651 ++nArrRow;
653 ++nCurRow;
655 while (nCurRow <= nThisRow && nCurRow <= nRow2);
656 ++nIndex;
658 while ( nIndex < pThisMarkArr->nCount && nThisRow < nRow2 );
662 else // vordere Spalten
664 for (nArrRow=1; nArrRow+1<nArrCount; nArrRow++)
666 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
667 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
669 pInfo->nWidth = nThisWidth; //! oder nur 0 abfragen ??
674 else
675 pRowInfo[0].pCellInfo[nArrCol].nWidth = STD_COL_WIDTH;
676 // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht
679 if(pCondFormList)
680 pCondFormList->endRendering();
681 //-------------------------------------------------------------------------
682 // bedingte Formatierung auswerten
683 ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
684 // favour preview over condition
685 if (bAnyCondition || bAnyPreview)
687 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
689 for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++) // links und rechts einer mehr
691 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
692 SCCOL nCol = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;
693 ScPatternAttr* pModifiedPatt = NULL;
695 if ( ValidCol(nCol) && pRowInfo[nArrRow].nRowNo <= MAXROW )
697 if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, pRowInfo[nArrRow].nRowNo, nTab ) )
699 aAltPatterns.push_back( new ScPatternAttr( *pInfo->pPatternAttr ) );
700 pModifiedPatt = &aAltPatterns.back();
701 pModifiedPatt->SetStyleSheet( pPreviewStyle );
704 // favour preview over condition
705 const SfxItemSet* pCondSet = pModifiedPatt ? &pModifiedPatt->GetItemSet() : pInfo->pConditionSet;
707 if (pCondSet)
709 const SfxPoolItem* pItem;
711 // Hintergrund
712 if ( pCondSet->GetItemState( ATTR_BACKGROUND, true, &pItem ) == SFX_ITEM_SET )
714 pInfo->pBackground = (const SvxBrushItem*) pItem;
715 pRowInfo[nArrRow].bEmptyBack = false;
718 // Umrandung
719 if ( pCondSet->GetItemState( ATTR_BORDER, true, &pItem ) == SFX_ITEM_SET )
720 pInfo->pLinesAttr = (const SvxBoxItem*) pItem;
722 if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, true, &pItem ) == SFX_ITEM_SET )
723 pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem );
724 if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, true, &pItem ) == SFX_ITEM_SET )
725 pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem );
727 // Schatten
728 if ( pCondSet->GetItemState( ATTR_SHADOW, true, &pItem ) == SFX_ITEM_SET )
730 pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
731 bAnyShadow = true;
734 if( bAnyCondition && pInfo->pColorScale)
736 pRowInfo[nArrRow].bEmptyBack = false;
737 pInfo->pBackground = new SvxBrushItem(*pInfo->pColorScale, ATTR_BACKGROUND);
743 // bedingte Formatierung Ende
744 //-------------------------------------------------------------------------
747 // Daten von zusammengefassten Zellen anpassen
750 if (bAnyMerged)
752 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
754 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
755 nSignedY = nArrRow ? pThisRowInfo->nRowNo : ((SCsROW)nRow1)-1;
757 for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++) // links und rechts einer mehr
759 SCsCOL nSignedX = ((SCsCOL) nArrCol) - 1;
760 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
762 if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped)
764 SCsCOL nStartX;
765 SCsROW nStartY;
766 SCsCOL nEndX;
767 SCsROW nEndY;
768 lcl_GetMergeRange( nSignedX,nSignedY, nArrRow, this,pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
769 nStartX,nStartY, nEndX,nEndY );
770 const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab );
771 const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab );
772 const SfxPoolItem* pItem;
774 // Hintergrund kopieren (oder in output.cxx)
776 if ( !pStartCond || pStartCond->
777 GetItemState(ATTR_BACKGROUND,true,&pItem) != SFX_ITEM_SET )
778 pItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
779 pInfo->pBackground = (const SvxBrushItem*) pItem;
780 pRowInfo[nArrRow].bEmptyBack = false;
782 // Schatten
784 if ( !pStartCond || pStartCond->
785 GetItemState(ATTR_SHADOW,true,&pItem) != SFX_ITEM_SET )
786 pItem = &pStartPattern->GetItem(ATTR_SHADOW);
787 pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
788 if (pInfo->pShadowAttr != pDefShadow)
789 bAnyShadow = true;
791 // Blockmarken - wieder mit Original-Merge-Werten
793 bool bCellMarked = false;
794 if (bPaintMarks)
795 bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX
796 && nStartX <= (SCsCOL) nBlockEndX
797 && nStartY >= (SCsROW) nBlockStartY
798 && nStartY <= (SCsROW) nBlockEndY );
799 if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked)
801 const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX;
802 SCSIZE nIndex;
803 if ( pThisMarkArr->Search( nStartY, nIndex ) )
804 bCellMarked=pThisMarkArr->pData[nIndex].bMarked;
807 pInfo->bMarked = bCellMarked;
813 if (bAnyShadow) // Schatten verteilen
815 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
817 bool bTop = ( nArrRow == 0 );
818 bool bBottom = ( nArrRow+1 == nArrCount );
820 for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++) // links und rechts einer mehr
822 bool bLeft = ( nArrCol == nCol1 );
823 bool bRight = ( nArrCol == nCol2+2 );
825 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
826 const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
827 SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE;
828 if (eLoc != SVX_SHADOW_NONE)
830 // oder Test auf != eLoc
832 SCsCOL nDxPos = 1;
833 SCsCOL nDxNeg = -1;
835 while ( nArrCol+nDxPos < nCol2+2 && pRowInfo[0].pCellInfo[nArrCol+nDxPos].nWidth == 0 )
836 ++nDxPos;
837 while ( nArrCol+nDxNeg > nCol1 && pRowInfo[0].pCellInfo[nArrCol+nDxNeg].nWidth == 0 )
838 --nDxNeg;
840 bool bLeftDiff = !bLeft &&
841 pRowInfo[nArrRow].pCellInfo[nArrCol+nDxNeg].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
842 bool bRightDiff = !bRight &&
843 pRowInfo[nArrRow].pCellInfo[nArrCol+nDxPos].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
844 bool bTopDiff = !bTop &&
845 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
846 bool bBottomDiff = !bBottom &&
847 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
849 if ( bLayoutRTL )
851 switch (eLoc)
853 case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
854 case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
855 case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_TOPLEFT; break;
856 case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
857 default:
859 // added to avoid warnings
864 switch (eLoc)
866 case SVX_SHADOW_BOTTOMRIGHT:
867 if (bBottomDiff)
869 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
870 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
871 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
873 if (bRightDiff)
875 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
876 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
877 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
879 if (bBottomDiff && bRightDiff)
881 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
882 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
884 break;
886 case SVX_SHADOW_BOTTOMLEFT:
887 if (bBottomDiff)
889 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
890 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
891 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
893 if (bLeftDiff)
895 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
896 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
897 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
899 if (bBottomDiff && bLeftDiff)
901 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
902 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
904 break;
906 case SVX_SHADOW_TOPRIGHT:
907 if (bTopDiff)
909 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
910 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
911 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
913 if (bRightDiff)
915 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
916 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
917 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
919 if (bTopDiff && bRightDiff)
921 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
922 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
924 break;
926 case SVX_SHADOW_TOPLEFT:
927 if (bTopDiff)
929 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
930 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
931 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
933 if (bLeftDiff)
935 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
936 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
937 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
939 if (bTopDiff && bLeftDiff)
941 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
942 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
944 break;
946 default:
947 OSL_FAIL("wrong Shadow-Enum");
954 rTabInfo.mnArrCount = sal::static_int_cast<sal_uInt16>(nArrCount);
955 rTabInfo.mbPageMode = bPageMode;
957 // ========================================================================
958 // *** create the frame border array ***
960 // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
961 // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
963 size_t nColCount = nCol2 - nCol1 + 3;
964 size_t nRowCount = nArrCount;
966 svx::frame::Array& rArray = rTabInfo.maArray;
967 rArray.Initialize( nColCount, nRowCount );
968 rArray.SetUseDiagDoubleClipping( false );
970 for( size_t nRow = 0; nRow < nRowCount; ++nRow )
972 sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow );
973 RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
975 for( size_t nCol = 0; nCol < nColCount; ++nCol )
977 sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nCol1 );
978 const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
980 const SvxBoxItem* pBox = rInfo.pLinesAttr;
981 const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
982 const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
984 size_t nFirstCol = nCol;
985 size_t nFirstRow = nRow;
987 // *** merged cells *** -------------------------------------------
989 if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) )
991 // *** insert merged range in svx::frame::Array ***
993 /* #i69369# top-left cell of a merged range may be located in
994 a hidden column or row. Use lcl_GetMergeRange() to find the
995 complete merged range, then calculate dimensions and
996 document position of the visible range. */
998 // note: document columns are always one less than CellInfoX coords
999 // note: document rows must be looked up in RowInfo structs
1001 // current column and row in document coordinates
1002 SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
1003 SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nRow1 - 1) );
1005 // find entire merged range in document, returns signed document coordinates
1006 SCsCOL nFirstRealDocColS, nLastRealDocColS;
1007 SCsROW nFirstRealDocRowS, nLastRealDocRowS;
1008 lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ),
1009 nCellInfoY, this, pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
1010 nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS );
1012 // *complete* merged range in document coordinates
1013 SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS );
1014 SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS );
1015 SCCOL nLastRealDocCol = static_cast< SCCOL >( nLastRealDocColS );
1016 SCROW nLastRealDocRow = static_cast< SCROW >( nLastRealDocRowS );
1018 // first visible column (nX1-1 is first processed document column)
1019 SCCOL nFirstDocCol = (nCol1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nCol1 - 1 ) : nFirstRealDocCol;
1020 sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( nFirstDocCol + 1 );
1021 nFirstCol = static_cast< size_t >( nFirstCellInfoX - nCol1 );
1023 // last visible column (nX2+1 is last processed document column)
1024 SCCOL nLastDocCol = (nCol2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nCol2 + 1 ) : nLastRealDocCol;
1025 sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( nLastDocCol + 1 );
1026 size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nCol1 );
1028 // first visible row
1029 sal_uInt16 nFirstCellInfoY = nCellInfoY;
1030 while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) ||
1031 ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nRow1 - 1 ) >= nFirstRealDocRow)) )
1032 --nFirstCellInfoY;
1033 SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
1034 nFirstRow = static_cast< size_t >( nFirstCellInfoY );
1036 // last visible row
1037 sal_uInt16 nLastCellInfoY = nCellInfoY;
1038 while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) &&
1039 (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) )
1040 ++nLastCellInfoY;
1041 SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
1042 size_t nLastRow = static_cast< size_t >( nLastCellInfoY );
1044 // insert merged range
1045 rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
1047 // *** find additional size not included in svx::frame::Array ***
1049 // additional space before first column
1050 if( nFirstCol == 0 )
1052 long nSize = 0;
1053 for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol )
1054 nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
1055 rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
1057 // additional space after last column
1058 if( nLastCol + 1 == nColCount )
1060 long nSize = 0;
1061 for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol )
1062 nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
1063 rArray.SetAddMergedRightSize( nCol, nRow, nSize );
1065 // additional space above first row
1066 if( nFirstRow == 0 )
1068 long nSize = 0;
1069 for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow )
1070 nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
1071 rArray.SetAddMergedTopSize( nCol, nRow, nSize );
1073 // additional space beyond last row
1074 if( nLastRow + 1 == nRowCount )
1076 long nSize = 0;
1077 for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow )
1078 nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
1079 rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
1082 // *** use line attributes from real origin cell ***
1084 if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) )
1086 if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) )
1088 const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab );
1089 pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) );
1090 pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) );
1091 pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) );
1093 else
1095 pBox = 0;
1096 pTLBR = pBLTR = 0;
1101 // *** borders *** ------------------------------------------------
1103 if( pBox )
1105 rArray.SetCellStyleLeft( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(), fColScale ) );
1106 rArray.SetCellStyleRight( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(), fColScale ) );
1107 rArray.SetCellStyleTop( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(), fRowScale ) );
1108 rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), fRowScale ) );
1111 if( pTLBR )
1112 rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), fRowScale ) );
1113 if( rInfo.mpBLTRLine )
1114 rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), fRowScale ) );
1118 /* Mirror the entire frame array.
1119 1st param = Mirror the vertical double line styles as well.
1120 2nd param = Do not swap diagonal lines.
1122 if( bLayoutRTL )
1123 rArray.MirrorSelfX( true, false );
1126 // ============================================================================
1128 ScTableInfo::ScTableInfo() :
1129 mpRowInfo( new RowInfo[ ROWINFO_MAX ] ),
1130 mbPageMode( false )
1132 for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
1133 mpRowInfo[ nIdx ].pCellInfo = 0;
1136 ScTableInfo::~ScTableInfo()
1138 for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
1139 delete [] mpRowInfo[ nIdx ].pCellInfo;
1140 delete [] mpRowInfo;
1143 // ============================================================================
1145 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */