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