1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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> // can be removed if table has a bLayoutRTL flag
25 #include <editeng/shaditem.hxx>
26 #include <editeng/brushitem.hxx>
28 #include "fillinfo.hxx"
29 #include "document.hxx"
30 #include "formulacell.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"
46 // -----------------------------------------------------------------------
48 const sal_uInt16 ROWINFO_MAX
= 1024;
60 // aehnlich wie in output.cxx
62 static void lcl_GetMergeRange( SCsCOL nX
, SCsROW nY
, SCSIZE nArrY
,
63 ScDocument
* pDoc
, RowInfo
* pRowInfo
,
64 SCCOL nX1
, SCROW nY1
, SCCOL
/* nX2 */, SCROW
/* nY2 */, SCTAB nTab
,
65 SCsCOL
& rStartX
, SCsROW
& rStartY
, SCsCOL
& rEndX
, SCsROW
& rEndY
)
67 CellInfo
* pInfo
= &pRowInfo
[nArrY
].pCellInfo
[nX
+1];
71 bool bHOver
= pInfo
->bHOverlapped
;
72 bool bVOver
= pInfo
->bVOverlapped
;
76 while (bHOver
) // nY konstant
79 if (rStartX
>= (SCsCOL
) nX1
&& !pDoc
->ColHidden(rStartX
, nTab
, NULL
, &nLastCol
))
81 bHOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bHOverlapped
;
82 bVOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bVOverlapped
;
86 sal_uInt16 nOverlap
= ((ScMergeFlagAttr
*)pDoc
->GetAttr(
87 rStartX
, rStartY
, nTab
, ATTR_MERGE_FLAG
))->GetValue();
88 bHOver
= ((nOverlap
& SC_MF_HOR
) != 0);
89 bVOver
= ((nOverlap
& SC_MF_VER
) != 0);
98 --nArrY
; // lokale Kopie !
100 if (rStartX
>= (SCsCOL
) nX1
&& rStartY
>= (SCsROW
) nY1
&&
101 !pDoc
->ColHidden(rStartX
, nTab
, NULL
, &nLastCol
) &&
102 !pDoc
->RowHidden(rStartY
, nTab
, NULL
, &nLastRow
) &&
103 (SCsROW
) pRowInfo
[nArrY
].nRowNo
== rStartY
)
105 bVOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bVOverlapped
;
109 sal_uInt16 nOverlap
= ((ScMergeFlagAttr
*)pDoc
->GetAttr(
110 rStartX
, rStartY
, nTab
, ATTR_MERGE_FLAG
))->GetValue();
111 bVOver
= ((nOverlap
& SC_MF_VER
) != 0);
115 const ScMergeAttr
* pMerge
;
116 if (rStartX
>= (SCsCOL
) nX1
&& rStartY
>= (SCsROW
) nY1
&&
117 !pDoc
->ColHidden(rStartX
, nTab
, NULL
, &nLastCol
) &&
118 !pDoc
->RowHidden(rStartY
, nTab
, NULL
, &nLastRow
) &&
119 (SCsROW
) pRowInfo
[nArrY
].nRowNo
== rStartY
)
121 pMerge
= (const ScMergeAttr
*) &pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].pPatternAttr
->
125 pMerge
= (const ScMergeAttr
*) pDoc
->GetAttr(rStartX
,rStartY
,nTab
,ATTR_MERGE
);
127 rEndX
= rStartX
+ pMerge
->GetColMerge() - 1;
128 rEndY
= rStartY
+ pMerge
->GetRowMerge() - 1;
131 #define CELLINFO(x,y) pRowInfo[nArrY+y].pCellInfo[nArrX+x]
133 void ScDocument::FillInfo( ScTableInfo
& rTabInfo
, SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
,
134 SCTAB nTab
, double nScaleX
, double nScaleY
,
135 bool bPageMode
, bool bFormulaMode
, const ScMarkData
* pMarkData
)
137 OSL_ENSURE( maTabs
[nTab
], "Table does not exist" );
139 bool bLayoutRTL
= IsLayoutRTL( nTab
);
141 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
142 ScStyleSheetPool
* pStlPool
= xPoolHelper
->GetStylePool();
144 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
146 const SvxBrushItem
* pDefBackground
=
147 (const SvxBrushItem
*) &pPool
->GetDefaultItem( ATTR_BACKGROUND
);
148 const ScMergeAttr
* pDefMerge
=
149 (const ScMergeAttr
*) &pPool
->GetDefaultItem( ATTR_MERGE
);
150 const SvxShadowItem
* pDefShadow
=
151 (const SvxShadowItem
*) &pPool
->GetDefaultItem( ATTR_SHADOW
);
160 bool bAnyMerged
= false;
161 bool bAnyShadow
= false;
162 bool bAnyCondition
= false;
164 bool bTabProtect
= IsTabProtected(nTab
);
166 // fuer Blockmarken von zusammengefassten Zellen mit
167 // versteckter erster Zeile / Spalte
168 bool bPaintMarks
= false;
169 bool bSkipMarks
= false;
170 SCCOL nBlockStartX
= 0, nBlockEndX
= 0;
171 SCROW nBlockEndY
= 0, nBlockStartY
= 0;
172 if (pMarkData
&& pMarkData
->IsMarked())
175 pMarkData
->GetMarkArea(aTmpRange
);
176 if ( nTab
>= aTmpRange
.aStart
.Tab() && nTab
<= aTmpRange
.aEnd
.Tab() )
178 nBlockStartX
= aTmpRange
.aStart
.Col();
179 nBlockStartY
= aTmpRange
.aStart
.Row();
180 nBlockEndX
= aTmpRange
.aEnd
.Col();
181 nBlockEndY
= aTmpRange
.aEnd
.Row();
182 ExtendHidden( nBlockStartX
, nBlockStartY
, nBlockEndX
, nBlockEndY
, nTab
); //? noetig ?
183 if (pMarkData
->IsMarkNegative())
190 // zuerst nur die Eintraege fuer die ganze Spalte
193 SCROW nYExtra
= nY2
+1;
194 sal_uInt16 nDocHeight
= ScGlobal::nStdRowHeight
;
195 SCROW nDocHeightEndRow
= -1;
196 for (nSignedY
=((SCsROW
)nY1
)-1; nSignedY
<=(SCsROW
)nYExtra
; nSignedY
++)
199 nY
= (SCROW
) nSignedY
;
201 nY
= MAXROW
+1; // ungueltig
203 if (nY
> nDocHeightEndRow
)
206 nDocHeight
= GetRowHeight( nY
, nTab
, NULL
, &nDocHeightEndRow
);
208 nDocHeight
= ScGlobal::nStdRowHeight
;
211 if ( nArrY
==0 || nDocHeight
|| nY
> MAXROW
)
213 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
214 pThisRowInfo
->pCellInfo
= NULL
; // wird unten belegt
216 sal_uInt16 nHeight
= (sal_uInt16
) ( nDocHeight
* nScaleY
);
220 pThisRowInfo
->nRowNo
= nY
; //! Fall < 0 ?
221 pThisRowInfo
->nHeight
= nHeight
;
222 pThisRowInfo
->bEmptyBack
= true;
223 pThisRowInfo
->bEmptyText
= true;
224 pThisRowInfo
->bChanged
= true;
225 pThisRowInfo
->bAutoFilter
= false;
226 pThisRowInfo
->bPivotButton
= false;
227 pThisRowInfo
->nRotMaxCol
= SC_ROTMAX_NONE
;
230 if (nArrY
>= ROWINFO_MAX
)
232 OSL_FAIL("FillInfo: Range too big" );
233 nYExtra
= nSignedY
; // Ende
234 nY2
= nYExtra
- 1; // Bereich anpassen
238 if (nSignedY
==(SCsROW
) nYExtra
) // zusaetzliche Zeile verdeckt ?
241 nArrCount
= nArrY
; // incl. Dummys
245 // Attribut im Dokument ueberhaupt verwendet?
246 bool bAnyItem
= false;
247 sal_uInt32 nRotCount
= pPool
->GetItemCount2( ATTR_ROTATE_VALUE
);
248 for (sal_uInt32 nItem
=0; nItem
<nRotCount
; nItem
++)
249 if (pPool
->GetItem2( ATTR_ROTATE_VALUE
, nItem
))
256 if ( bAnyItem
&& HasAttrib( 0,nY1
,nTab
, MAXCOL
,nY2
+1,nTab
,
257 HASATTR_ROTATE
| HASATTR_CONDITIONAL
) )
259 //! Conditionals auch bei HASATTR_ROTATE abfragen ????
261 OSL_ENSURE( nArrCount
>2, "nArrCount too small" );
262 // FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-2, nX1, nX2 );
263 FindMaxRotCol( nTab
, &pRowInfo
[1], nArrCount
-1, nX1
, nX2
);
264 // FindMaxRotCol setzt nRotMaxCol
266 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
267 if (pRowInfo
[nArrY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nArrY
].nRotMaxCol
> nRotMax
)
268 nRotMax
= pRowInfo
[nArrY
].nRotMaxCol
;
271 // Zell-Infos erst nach dem Test auf gedrehte allozieren
272 // bis nRotMax wegen nRotateDir Flag
274 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
276 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
277 nY
= pThisRowInfo
->nRowNo
;
278 pThisRowInfo
->pCellInfo
= new CellInfo
[ nRotMax
+1+2 ]; // vom Aufrufer zu loeschen !
280 for (nArrX
=0; nArrX
<=nRotMax
+2; nArrX
++) // Zell-Infos vorbelegen
285 nX
= MAXCOL
+1; // ungueltig
287 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
288 pInfo
->bEmptyCellText
= true;
289 pInfo
->maCell
.clear();
291 pInfo
->bMarked
= ( nX
>= nBlockStartX
&& nX
<= nBlockEndX
292 && nY
>= nBlockStartY
&& nY
<= nBlockEndY
);
294 pInfo
->bMarked
= false;
297 pInfo
->nClipMark
= SC_CLIPMARK_NONE
;
298 pInfo
->bMerged
= false;
299 pInfo
->bHOverlapped
= false;
300 pInfo
->bVOverlapped
= false;
301 pInfo
->bAutoFilter
= false;
302 pInfo
->bPivotButton
= false;
303 pInfo
->bPivotPopupButton
= false;
304 pInfo
->bFilterActive
= false;
305 pInfo
->nRotateDir
= SC_ROTDIR_NONE
;
307 pInfo
->bPrinted
= false; // view-intern
308 pInfo
->bHideGrid
= false; // view-intern
309 pInfo
->bEditEngine
= false; // view-intern
311 pInfo
->pBackground
= NULL
; //! weglassen?
312 pInfo
->pPatternAttr
= NULL
;
313 pInfo
->pConditionSet
= NULL
;
315 pInfo
->pLinesAttr
= NULL
;
316 pInfo
->mpTLBRLine
= NULL
;
317 pInfo
->mpBLTRLine
= NULL
;
319 pInfo
->pShadowAttr
= pDefShadow
;
320 pInfo
->pHShadowOrigin
= NULL
;
321 pInfo
->pVShadowOrigin
= NULL
;
325 for (nArrX
=nX2
+3; nArrX
<=nRotMax
+2; nArrX
++) // restliche Breiten eintragen
330 if (!ColHidden(nX
, nTab
))
332 sal_uInt16 nThisWidth
= (sal_uInt16
) (GetColWidth( nX
, nTab
) * nScaleX
);
336 pRowInfo
[0].pCellInfo
[nArrX
].nWidth
= nThisWidth
;
341 ScConditionalFormatList
* pCondFormList
= GetCondFormList(nTab
);
343 pCondFormList
->startRendering();
345 for (nArrX
=0; nArrX
<=nX2
+2; nArrX
++) // links & rechts + 1
347 nX
= (nArrX
>0) ? nArrX
-1 : MAXCOL
+1; // negativ -> ungueltig
351 // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
352 // will disturb the output
354 // TODO: Optimize this loop.
355 if (!ColHidden(nX
, nTab
))
357 sal_uInt16 nThisWidth
= (sal_uInt16
) (GetColWidth( nX
, nTab
) * nScaleX
);
361 pRowInfo
[0].pCellInfo
[nArrX
].nWidth
= nThisWidth
; //! dies sollte reichen
363 ScColumn
* pThisCol
= &maTabs
[nTab
]->aCol
[nX
]; // Spalten-Daten
367 bool bHiddenRow
= true;
368 SCROW nHiddenEndRow
= -1;
369 (void) pThisCol
->Search( nY1
, nUIndex
);
370 while ( nUIndex
< pThisCol
->maItems
.size() &&
371 (nThisRow
=pThisCol
->maItems
[nUIndex
].nRow
) <= nY2
)
373 if (nThisRow
> nHiddenEndRow
)
374 bHiddenRow
= RowHidden( nThisRow
, nTab
, NULL
, &nHiddenEndRow
);
377 while ( pRowInfo
[nArrY
].nRowNo
< nThisRow
)
379 OSL_ENSURE( pRowInfo
[nArrY
].nRowNo
== nThisRow
, "FillInfo: Row not found" );
381 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
382 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
383 pInfo
->maCell
.assign(*pThisCol
->maItems
[nUIndex
].pCell
);
384 pThisRowInfo
->bEmptyText
= false; // Zeile nicht leer
385 pInfo
->bEmptyCellText
= false; // Zelle nicht leer
391 if (nX
+1 >= nX1
) // Attribute/Blockmarken ab nX1-1
393 ScAttrArray
* pThisAttrArr
= pThisCol
->pAttrArray
; // Attribute
396 const ScPatternAttr
* pPattern
;
397 SCROW nCurRow
=nY1
; // einzelne Zeile
399 --nCurRow
; // oben 1 mehr
402 nThisRow
=nCurRow
; // Ende des Bereichs
404 (void) pThisAttrArr
->Search( nCurRow
, nIndex
);
409 nThisRow
=pThisAttrArr
->pData
[nIndex
].nRow
; // Ende des Bereichs
410 pPattern
=pThisAttrArr
->pData
[nIndex
].pPattern
;
412 const SvxBrushItem
* pBackground
= (const SvxBrushItem
*)
413 &pPattern
->GetItem(ATTR_BACKGROUND
);
414 const SvxBoxItem
* pLinesAttr
= (const SvxBoxItem
*)
415 &pPattern
->GetItem(ATTR_BORDER
);
417 const SvxLineItem
* pTLBRLine
= static_cast< const SvxLineItem
* >(
418 &pPattern
->GetItem( ATTR_BORDER_TLBR
) );
419 const SvxLineItem
* pBLTRLine
= static_cast< const SvxLineItem
* >(
420 &pPattern
->GetItem( ATTR_BORDER_BLTR
) );
422 const SvxShadowItem
* pShadowAttr
= (const SvxShadowItem
*)
423 &pPattern
->GetItem(ATTR_SHADOW
);
424 if (pShadowAttr
!= pDefShadow
)
427 const ScMergeAttr
* pMergeAttr
= (const ScMergeAttr
*)
428 &pPattern
->GetItem(ATTR_MERGE
);
429 bool bMerged
= ( pMergeAttr
!= pDefMerge
&& *pMergeAttr
!= *pDefMerge
);
430 sal_uInt16 nOverlap
= ((const ScMergeFlagAttr
*) &pPattern
->GetItemSet().
431 Get(ATTR_MERGE_FLAG
))->GetValue();
432 bool bHOverlapped
= ((nOverlap
& SC_MF_HOR
) != 0);
433 bool bVOverlapped
= ((nOverlap
& SC_MF_VER
) != 0);
434 bool bAutoFilter
= ((nOverlap
& SC_MF_AUTO
) != 0);
435 bool bPivotButton
= ((nOverlap
& SC_MF_BUTTON
) != 0);
436 bool bScenario
= ((nOverlap
& SC_MF_SCENARIO
) != 0);
437 bool bPivotPopupButton
= ((nOverlap
& SC_MF_BUTTON_POPUP
) != 0);
438 bool bFilterActive
= ((nOverlap
& SC_MF_HIDDEN_MEMBER
) != 0);
439 if (bMerged
||bHOverlapped
||bVOverlapped
)
440 bAnyMerged
= true; // intern
442 bool bHidden
, bHideFormula
;
445 const ScProtectionAttr
& rProtAttr
= (const ScProtectionAttr
&)
446 pPattern
->GetItem(ATTR_PROTECTION
);
447 bHidden
= rProtAttr
.GetHideCell();
448 bHideFormula
= rProtAttr
.GetHideFormula();
451 bHidden
= bHideFormula
= false;
453 const std::vector
<sal_uInt32
>& rCondFormats
= static_cast<const ScCondFormatItem
&>(pPattern
->GetItem(ATTR_CONDITIONAL
)).GetCondFormatData();
454 bool bContainsCondFormat
= !rCondFormats
.empty();
458 SCROW nLastHiddenRow
= -1;
459 bool bRowHidden
= RowHidden(nCurRow
, nTab
, NULL
, &nLastHiddenRow
);
460 if ( nArrY
==0 || !bRowHidden
)
462 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
463 if (pBackground
!= pDefBackground
) // Spalten-HG == Standard ?
464 pThisRowInfo
->bEmptyBack
= false;
465 if (bContainsCondFormat
)
466 pThisRowInfo
->bEmptyBack
= false;
468 pThisRowInfo
->bAutoFilter
= true;
469 if (bPivotButton
|| bPivotPopupButton
)
470 pThisRowInfo
->bPivotButton
= true;
472 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
473 pInfo
->pBackground
= pBackground
;
474 pInfo
->pPatternAttr
= pPattern
;
475 pInfo
->bMerged
= bMerged
;
476 pInfo
->bHOverlapped
= bHOverlapped
;
477 pInfo
->bVOverlapped
= bVOverlapped
;
478 pInfo
->bAutoFilter
= bAutoFilter
;
479 pInfo
->bPivotButton
= bPivotButton
;
480 pInfo
->bPivotPopupButton
= bPivotPopupButton
;
481 pInfo
->bFilterActive
= bFilterActive
;
482 pInfo
->pLinesAttr
= pLinesAttr
;
483 pInfo
->mpTLBRLine
= pTLBRLine
;
484 pInfo
->mpBLTRLine
= pBLTRLine
;
485 pInfo
->pShadowAttr
= pShadowAttr
;
486 // nWidth wird nicht mehr einzeln gesetzt
490 pInfo
->pBackground
= ScGlobal::GetButtonBrushItem();
491 pThisRowInfo
->bEmptyBack
= false;
494 if ( bContainsCondFormat
)
497 for(std::vector
<sal_uInt32
>::const_iterator itr
= rCondFormats
.begin();
498 itr
!= rCondFormats
.end() && !bFound
; ++itr
)
500 ScConditionalFormat
* pCondForm
= pCondFormList
->GetFormat(*itr
);
504 ScCondFormatData aData
= pCondForm
->GetData(
505 pInfo
->maCell
, ScAddress(nX
, nCurRow
, nTab
));
506 if (!aData
.aStyleName
.isEmpty())
508 SfxStyleSheetBase
* pStyleSheet
=
509 pStlPool
->Find( aData
.aStyleName
, SFX_STYLE_FAMILY_PARA
);
512 //! Style-Sets cachen !!!
513 pInfo
->pConditionSet
= &pStyleSheet
->GetItemSet();
514 bAnyCondition
= true;
516 // we need to check already here for protected cells
517 const SfxPoolItem
* pItem
;
518 if ( bTabProtect
&& pInfo
->pConditionSet
->GetItemState( ATTR_PROTECTION
, true, &pItem
) == SFX_ITEM_SET
)
520 const ScProtectionAttr
* pProtAttr
= static_cast<const ScProtectionAttr
*>(pItem
);
521 bHidden
= pProtAttr
->GetHideCell();
522 bHideFormula
= pProtAttr
->GetHideFormula();
528 // if style is not there, treat like no condition
530 if(aData
.pColorScale
)
532 pInfo
->pColorScale
= aData
.pColorScale
;
538 pInfo
->pDataBar
= aData
.pDataBar
;
543 pInfo
->pIconSet
= aData
.pIconSet
;
549 if (bHidden
|| (bFormulaMode
&& bHideFormula
&& pInfo
->maCell
.meType
== CELLTYPE_FORMULA
))
550 pInfo
->bEmptyCellText
= true;
554 else if (bRowHidden
&& nLastHiddenRow
>= 0)
556 nCurRow
= nLastHiddenRow
;
557 if (nCurRow
> nThisRow
)
562 while (nCurRow
<= nThisRow
&& nCurRow
<= nYExtra
);
565 while ( nIndex
< pThisAttrArr
->nCount
&& nThisRow
< nYExtra
);
568 if (pMarkData
&& pMarkData
->IsMultiMarked())
571 const ScMarkArray
* pThisMarkArr
= pMarkData
->GetArray()+nX
;
573 nCurRow
= nY1
; // einzelne Zeile
574 nThisRow
= nY1
; // Ende des Bereichs
576 if ( pThisMarkArr
->Search( nY1
, nIndex
) )
581 nThisRow
=pThisMarkArr
->pData
[nIndex
].nRow
; // Ende des Bereichs
582 bThisMarked
=pThisMarkArr
->pData
[nIndex
].bMarked
;
586 if ( !RowHidden( nCurRow
,nTab
) )
590 bool bSkip
= bSkipMarks
&&
591 nX
>= nBlockStartX
&&
593 nCurRow
>= nBlockStartY
&&
594 nCurRow
<= nBlockEndY
;
597 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
598 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
599 pInfo
->bMarked
= true;
606 while (nCurRow
<= nThisRow
&& nCurRow
<= nY2
);
609 while ( nIndex
< pThisMarkArr
->nCount
&& nThisRow
< nY2
);
613 else // vordere Spalten
615 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
617 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
618 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
620 pInfo
->nWidth
= nThisWidth
; //! oder nur 0 abfragen ??
626 pRowInfo
[0].pCellInfo
[nArrX
].nWidth
= STD_COL_WIDTH
;
627 // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht
631 pCondFormList
->endRendering();
632 //-------------------------------------------------------------------------
633 // bedingte Formatierung auswerten
637 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
639 for (nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++) // links und rechts einer mehr
641 CellInfo
* pInfo
= &pRowInfo
[nArrY
].pCellInfo
[nArrX
];
642 const SfxItemSet
* pCondSet
= pInfo
->pConditionSet
;
645 const SfxPoolItem
* pItem
;
648 if ( pCondSet
->GetItemState( ATTR_BACKGROUND
, true, &pItem
) == SFX_ITEM_SET
)
650 pInfo
->pBackground
= (const SvxBrushItem
*) pItem
;
651 pRowInfo
[nArrY
].bEmptyBack
= false;
655 if ( pCondSet
->GetItemState( ATTR_BORDER
, true, &pItem
) == SFX_ITEM_SET
)
656 pInfo
->pLinesAttr
= (const SvxBoxItem
*) pItem
;
658 if ( pCondSet
->GetItemState( ATTR_BORDER_TLBR
, true, &pItem
) == SFX_ITEM_SET
)
659 pInfo
->mpTLBRLine
= static_cast< const SvxLineItem
* >( pItem
);
660 if ( pCondSet
->GetItemState( ATTR_BORDER_BLTR
, true, &pItem
) == SFX_ITEM_SET
)
661 pInfo
->mpBLTRLine
= static_cast< const SvxLineItem
* >( pItem
);
664 if ( pCondSet
->GetItemState( ATTR_SHADOW
, true, &pItem
) == SFX_ITEM_SET
)
666 pInfo
->pShadowAttr
= (const SvxShadowItem
*) pItem
;
670 if(pInfo
->pColorScale
)
672 pRowInfo
[nArrY
].bEmptyBack
= false;
673 pInfo
->pBackground
= new SvxBrushItem(*pInfo
->pColorScale
, ATTR_BACKGROUND
);
679 // bedingte Formatierung Ende
680 //-------------------------------------------------------------------------
683 // Daten von zusammengefassten Zellen anpassen
688 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
690 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
691 nSignedY
= nArrY
? pThisRowInfo
->nRowNo
: ((SCsROW
)nY1
)-1;
693 for (nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++) // links und rechts einer mehr
695 SCsCOL nSignedX
= ((SCsCOL
) nArrX
) - 1;
696 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
698 if (pInfo
->bMerged
|| pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
704 lcl_GetMergeRange( nSignedX
,nSignedY
, nArrY
, this,pRowInfo
, nX1
,nY1
,nX2
,nY2
,nTab
,
705 nStartX
,nStartY
, nEndX
,nEndY
);
706 const ScPatternAttr
* pStartPattern
= GetPattern( nStartX
,nStartY
,nTab
);
707 const SfxItemSet
* pStartCond
= GetCondResult( nStartX
,nStartY
,nTab
);
708 const SfxPoolItem
* pItem
;
710 // Hintergrund kopieren (oder in output.cxx)
712 if ( !pStartCond
|| pStartCond
->
713 GetItemState(ATTR_BACKGROUND
,true,&pItem
) != SFX_ITEM_SET
)
714 pItem
= &pStartPattern
->GetItem(ATTR_BACKGROUND
);
715 pInfo
->pBackground
= (const SvxBrushItem
*) pItem
;
716 pRowInfo
[nArrY
].bEmptyBack
= false;
720 if ( !pStartCond
|| pStartCond
->
721 GetItemState(ATTR_SHADOW
,true,&pItem
) != SFX_ITEM_SET
)
722 pItem
= &pStartPattern
->GetItem(ATTR_SHADOW
);
723 pInfo
->pShadowAttr
= (const SvxShadowItem
*) pItem
;
724 if (pInfo
->pShadowAttr
!= pDefShadow
)
727 // Blockmarken - wieder mit Original-Merge-Werten
729 bool bCellMarked
= false;
731 bCellMarked
= ( nStartX
>= (SCsCOL
) nBlockStartX
732 && nStartX
<= (SCsCOL
) nBlockEndX
733 && nStartY
>= (SCsROW
) nBlockStartY
734 && nStartY
<= (SCsROW
) nBlockEndY
);
735 if (pMarkData
&& pMarkData
->IsMultiMarked() && !bCellMarked
)
737 const ScMarkArray
* pThisMarkArr
= pMarkData
->GetArray()+nStartX
;
739 if ( pThisMarkArr
->Search( nStartY
, nIndex
) )
740 bCellMarked
=pThisMarkArr
->pData
[nIndex
].bMarked
;
743 pInfo
->bMarked
= bCellMarked
;
749 if (bAnyShadow
) // Schatten verteilen
751 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
753 bool bTop
= ( nArrY
== 0 );
754 bool bBottom
= ( nArrY
+1 == nArrCount
);
756 for (nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++) // links und rechts einer mehr
758 bool bLeft
= ( nArrX
== nX1
);
759 bool bRight
= ( nArrX
== nX2
+2 );
761 CellInfo
* pInfo
= &pRowInfo
[nArrY
].pCellInfo
[nArrX
];
762 const SvxShadowItem
* pThisAttr
= pInfo
->pShadowAttr
;
763 SvxShadowLocation eLoc
= pThisAttr
? pThisAttr
->GetLocation() : SVX_SHADOW_NONE
;
764 if (eLoc
!= SVX_SHADOW_NONE
)
766 // oder Test auf != eLoc
771 while ( nArrX
+nDxPos
< nX2
+2 && pRowInfo
[0].pCellInfo
[nArrX
+nDxPos
].nWidth
== 0 )
773 while ( nArrX
+nDxNeg
> nX1
&& pRowInfo
[0].pCellInfo
[nArrX
+nDxNeg
].nWidth
== 0 )
776 bool bLeftDiff
= !bLeft
&&
777 CELLINFO(nDxNeg
,0).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
778 bool bRightDiff
= !bRight
&&
779 CELLINFO(nDxPos
,0).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
780 bool bTopDiff
= !bTop
&&
781 CELLINFO(0,-1).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
782 bool bBottomDiff
= !bBottom
&&
783 CELLINFO(0,1).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
789 case SVX_SHADOW_BOTTOMRIGHT
: eLoc
= SVX_SHADOW_BOTTOMLEFT
; break;
790 case SVX_SHADOW_BOTTOMLEFT
: eLoc
= SVX_SHADOW_BOTTOMRIGHT
; break;
791 case SVX_SHADOW_TOPRIGHT
: eLoc
= SVX_SHADOW_TOPLEFT
; break;
792 case SVX_SHADOW_TOPLEFT
: eLoc
= SVX_SHADOW_TOPRIGHT
; break;
795 // added to avoid warnings
802 case SVX_SHADOW_BOTTOMRIGHT
:
805 CELLINFO(0,1).pHShadowOrigin
= pThisAttr
;
806 CELLINFO(0,1).eHShadowPart
=
807 bLeftDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
811 CELLINFO(1,0).pVShadowOrigin
= pThisAttr
;
812 CELLINFO(1,0).eVShadowPart
=
813 bTopDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
815 if (bBottomDiff
&& bRightDiff
)
817 CELLINFO(1,1).pHShadowOrigin
= pThisAttr
;
818 CELLINFO(1,1).eHShadowPart
= SC_SHADOW_CORNER
;
822 case SVX_SHADOW_BOTTOMLEFT
:
825 CELLINFO(0,1).pHShadowOrigin
= pThisAttr
;
826 CELLINFO(0,1).eHShadowPart
=
827 bRightDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
831 CELLINFO(-1,0).pVShadowOrigin
= pThisAttr
;
832 CELLINFO(-1,0).eVShadowPart
=
833 bTopDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
835 if (bBottomDiff
&& bLeftDiff
)
837 CELLINFO(-1,1).pHShadowOrigin
= pThisAttr
;
838 CELLINFO(-1,1).eHShadowPart
= SC_SHADOW_CORNER
;
842 case SVX_SHADOW_TOPRIGHT
:
845 CELLINFO(0,-1).pHShadowOrigin
= pThisAttr
;
846 CELLINFO(0,-1).eHShadowPart
=
847 bLeftDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
851 CELLINFO(1,0).pVShadowOrigin
= pThisAttr
;
852 CELLINFO(1,0).eVShadowPart
=
853 bBottomDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
855 if (bTopDiff
&& bRightDiff
)
857 CELLINFO(1,-1).pHShadowOrigin
= pThisAttr
;
858 CELLINFO(1,-1).eHShadowPart
= SC_SHADOW_CORNER
;
862 case SVX_SHADOW_TOPLEFT
:
865 CELLINFO(0,-1).pHShadowOrigin
= pThisAttr
;
866 CELLINFO(0,-1).eHShadowPart
=
867 bRightDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
871 CELLINFO(-1,0).pVShadowOrigin
= pThisAttr
;
872 CELLINFO(-1,0).eVShadowPart
=
873 bBottomDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
875 if (bTopDiff
&& bLeftDiff
)
877 CELLINFO(-1,-1).pHShadowOrigin
= pThisAttr
;
878 CELLINFO(-1,-1).eHShadowPart
= SC_SHADOW_CORNER
;
883 OSL_FAIL("wrong Shadow-Enum");
890 rTabInfo
.mnArrCount
= sal::static_int_cast
<sal_uInt16
>(nArrCount
);
891 rTabInfo
.mbPageMode
= bPageMode
;
893 // ========================================================================
894 // *** create the frame border array ***
896 // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
897 // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
899 size_t nColCount
= nX2
- nX1
+ 3;
900 size_t nRowCount
= nArrCount
;
902 svx::frame::Array
& rArray
= rTabInfo
.maArray
;
903 rArray
.Initialize( nColCount
, nRowCount
);
904 rArray
.SetUseDiagDoubleClipping( false );
906 for( size_t nRow
= 0; nRow
< nRowCount
; ++nRow
)
908 sal_uInt16 nCellInfoY
= static_cast< sal_uInt16
>( nRow
);
909 RowInfo
& rThisRowInfo
= pRowInfo
[ nCellInfoY
];
911 for( size_t nCol
= 0; nCol
< nColCount
; ++nCol
)
913 sal_uInt16 nCellInfoX
= static_cast< sal_uInt16
>( nCol
+ nX1
);
914 const CellInfo
& rInfo
= rThisRowInfo
.pCellInfo
[ nCellInfoX
];
916 const SvxBoxItem
* pBox
= rInfo
.pLinesAttr
;
917 const SvxLineItem
* pTLBR
= rInfo
.mpTLBRLine
;
918 const SvxLineItem
* pBLTR
= rInfo
.mpBLTRLine
;
920 size_t nFirstCol
= nCol
;
921 size_t nFirstRow
= nRow
;
923 // *** merged cells *** -------------------------------------------
925 if( !rArray
.IsMerged( nCol
, nRow
) && (rInfo
.bMerged
|| rInfo
.bHOverlapped
|| rInfo
.bVOverlapped
) )
927 // *** insert merged range in svx::frame::Array ***
929 /* #i69369# top-left cell of a merged range may be located in
930 a hidden column or row. Use lcl_GetMergeRange() to find the
931 complete merged range, then calculate dimensions and
932 document position of the visible range. */
934 // note: document columns are always one less than CellInfoX coords
935 // note: document rows must be looked up in RowInfo structs
937 // current column and row in document coordinates
938 SCCOL nCurrDocCol
= static_cast< SCCOL
>( nCellInfoX
- 1 );
939 SCROW nCurrDocRow
= static_cast< SCROW
>( (nCellInfoY
> 0) ? rThisRowInfo
.nRowNo
: (nY1
- 1) );
941 // find entire merged range in document, returns signed document coordinates
942 SCsCOL nFirstRealDocColS
, nLastRealDocColS
;
943 SCsROW nFirstRealDocRowS
, nLastRealDocRowS
;
944 lcl_GetMergeRange( static_cast< SCsCOL
>( nCurrDocCol
), static_cast< SCsROW
>( nCurrDocRow
),
945 nCellInfoY
, this, pRowInfo
, nX1
,nY1
,nX2
,nY2
,nTab
,
946 nFirstRealDocColS
, nFirstRealDocRowS
, nLastRealDocColS
, nLastRealDocRowS
);
948 // *complete* merged range in document coordinates
949 SCCOL nFirstRealDocCol
= static_cast< SCCOL
>( nFirstRealDocColS
);
950 SCROW nFirstRealDocRow
= static_cast< SCROW
>( nFirstRealDocRowS
);
951 SCCOL nLastRealDocCol
= static_cast< SCCOL
>( nLastRealDocColS
);
952 SCROW nLastRealDocRow
= static_cast< SCROW
>( nLastRealDocRowS
);
954 // first visible column (nX1-1 is first processed document column)
955 SCCOL nFirstDocCol
= (nX1
> 0) ? ::std::max
< SCCOL
>( nFirstRealDocCol
, nX1
- 1 ) : nFirstRealDocCol
;
956 sal_uInt16 nFirstCellInfoX
= static_cast< sal_uInt16
>( nFirstDocCol
+ 1 );
957 nFirstCol
= static_cast< size_t >( nFirstCellInfoX
- nX1
);
959 // last visible column (nX2+1 is last processed document column)
960 SCCOL nLastDocCol
= (nX2
< MAXCOL
) ? ::std::min
< SCCOL
>( nLastRealDocCol
, nX2
+ 1 ) : nLastRealDocCol
;
961 sal_uInt16 nLastCellInfoX
= static_cast< sal_uInt16
>( nLastDocCol
+ 1 );
962 size_t nLastCol
= static_cast< size_t >( nLastCellInfoX
- nX1
);
965 sal_uInt16 nFirstCellInfoY
= nCellInfoY
;
966 while( ((nFirstCellInfoY
> 1) && (pRowInfo
[ nFirstCellInfoY
- 1 ].nRowNo
>= nFirstRealDocRow
)) ||
967 ((nFirstCellInfoY
== 1) && (static_cast< SCROW
>( nY1
- 1 ) >= nFirstRealDocRow
)) )
969 SCROW nFirstDocRow
= (nFirstCellInfoY
> 0) ? pRowInfo
[ nFirstCellInfoY
].nRowNo
: static_cast< SCROW
>( nY1
- 1 );
970 nFirstRow
= static_cast< size_t >( nFirstCellInfoY
);
973 sal_uInt16 nLastCellInfoY
= nCellInfoY
;
974 while( (sal::static_int_cast
<SCSIZE
>(nLastCellInfoY
+ 1) < nArrCount
) &&
975 (pRowInfo
[ nLastCellInfoY
+ 1 ].nRowNo
<= nLastRealDocRow
) )
977 SCROW nLastDocRow
= (nLastCellInfoY
> 0) ? pRowInfo
[ nLastCellInfoY
].nRowNo
: static_cast< SCROW
>( nY1
- 1 );
978 size_t nLastRow
= static_cast< size_t >( nLastCellInfoY
);
980 // insert merged range
981 rArray
.SetMergedRange( nFirstCol
, nFirstRow
, nLastCol
, nLastRow
);
983 // *** find additional size not included in svx::frame::Array ***
985 // additional space before first column
989 for( SCCOL nDocCol
= nFirstRealDocCol
; nDocCol
< nFirstDocCol
; ++nDocCol
)
990 nSize
+= std::max( static_cast< long >( GetColWidth( nDocCol
, nTab
) * nScaleX
), 1L );
991 rArray
.SetAddMergedLeftSize( nCol
, nRow
, nSize
);
993 // additional space after last column
994 if( nLastCol
+ 1 == nColCount
)
997 for( SCCOL nDocCol
= nLastDocCol
+ 1; nDocCol
<= nLastRealDocCol
; ++nDocCol
)
998 nSize
+= std::max( static_cast< long >( GetColWidth( nDocCol
, nTab
) * nScaleX
), 1L );
999 rArray
.SetAddMergedRightSize( nCol
, nRow
, nSize
);
1001 // additional space above first row
1002 if( nFirstRow
== 0 )
1005 for( SCROW nDocRow
= nFirstRealDocRow
; nDocRow
< nFirstDocRow
; ++nDocRow
)
1006 nSize
+= std::max( static_cast< long >( GetRowHeight( nDocRow
, nTab
) * nScaleY
), 1L );
1007 rArray
.SetAddMergedTopSize( nCol
, nRow
, nSize
);
1009 // additional space beyond last row
1010 if( nLastRow
+ 1 == nRowCount
)
1013 for( SCROW nDocRow
= nLastDocRow
+ 1; nDocRow
<= nLastRealDocRow
; ++nDocRow
)
1014 nSize
+= std::max( static_cast< long >( GetRowHeight( nDocRow
, nTab
) * nScaleY
), 1L );
1015 rArray
.SetAddMergedBottomSize( nCol
, nRow
, nSize
);
1018 // *** use line attributes from real origin cell ***
1020 if( (nFirstRealDocCol
!= nCurrDocCol
) || (nFirstRealDocRow
!= nCurrDocRow
) )
1022 if( const ScPatternAttr
* pPattern
= GetPattern( nFirstRealDocCol
, nFirstRealDocRow
, nTab
) )
1024 const SfxItemSet
* pCond
= GetCondResult( nFirstRealDocCol
, nFirstRealDocRow
, nTab
);
1025 pBox
= static_cast< const SvxBoxItem
* >( &pPattern
->GetItem( ATTR_BORDER
, pCond
) );
1026 pTLBR
= static_cast< const SvxLineItem
* >( &pPattern
->GetItem( ATTR_BORDER_TLBR
, pCond
) );
1027 pBLTR
= static_cast< const SvxLineItem
* >( &pPattern
->GetItem( ATTR_BORDER_BLTR
, pCond
) );
1037 // *** borders *** ------------------------------------------------
1041 rArray
.SetCellStyleLeft( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetLeft(), nScaleX
) );
1042 rArray
.SetCellStyleRight( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetRight(), nScaleX
) );
1043 rArray
.SetCellStyleTop( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetTop(), nScaleY
) );
1044 rArray
.SetCellStyleBottom( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetBottom(), nScaleY
) );
1048 rArray
.SetCellStyleTLBR( nFirstCol
, nFirstRow
, svx::frame::Style( pTLBR
->GetLine(), nScaleY
) );
1049 if( rInfo
.mpBLTRLine
)
1050 rArray
.SetCellStyleBLTR( nFirstCol
, nFirstRow
, svx::frame::Style( pBLTR
->GetLine(), nScaleY
) );
1054 /* Mirror the entire frame array.
1055 1st param = Mirror the vertical double line styles as well.
1056 2nd param = Do not swap diagonal lines.
1059 rArray
.MirrorSelfX( true, false );
1062 // ============================================================================
1064 ScTableInfo::ScTableInfo() :
1065 mpRowInfo( new RowInfo
[ ROWINFO_MAX
] ),
1068 for( sal_uInt16 nIdx
= 0; nIdx
< ROWINFO_MAX
; ++nIdx
)
1069 mpRowInfo
[ nIdx
].pCellInfo
= 0;
1072 ScTableInfo::~ScTableInfo()
1074 for( sal_uInt16 nIdx
= 0; nIdx
< ROWINFO_MAX
; ++nIdx
)
1075 delete [] mpRowInfo
[ nIdx
].pCellInfo
;
1076 delete [] mpRowInfo
;
1079 // ============================================================================
1081 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */