1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fillinfo.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/boxitem.hxx>
40 #include <svx/bolnitem.hxx>
41 #include <svx/editdata.hxx> // can be removed if table has a bLayoutRTL flag
42 #include <svx/shaditem.hxx>
44 #include "fillinfo.hxx"
45 #include "document.hxx"
49 #include "attarray.hxx"
50 #include "markarr.hxx"
51 #include "markdata.hxx"
52 #include "patattr.hxx"
53 #include "poolhelp.hxx"
54 #include "docpool.hxx"
55 #include "conditio.hxx"
56 #include "stlpool.hxx"
58 // -----------------------------------------------------------------------
60 const USHORT ROWINFO_MAX
= 1024;
72 inline const SvxBorderLine
* GetNullOrLine( const SvxBoxItem
* pBox
, FillInfoLinePos eWhich
)
77 return pBox
->GetTop();
78 else if (eWhich
==FILP_BOTTOM
)
79 return pBox
->GetBottom();
80 else if (eWhich
==FILP_LEFT
)
81 return pBox
->GetLeft();
83 return pBox
->GetRight();
89 // aehnlich wie in output.cxx
91 void lcl_GetMergeRange( SCsCOL nX
, SCsROW nY
, SCSIZE nArrY
,
92 ScDocument
* pDoc
, RowInfo
* pRowInfo
,
93 SCCOL nX1
, SCROW nY1
, SCCOL
/* nX2 */, SCROW
/* nY2 */, SCTAB nTab
,
94 SCsCOL
& rStartX
, SCsROW
& rStartY
, SCsCOL
& rEndX
, SCsROW
& rEndY
)
96 CellInfo
* pInfo
= &pRowInfo
[nArrY
].pCellInfo
[nX
+1];
100 BOOL bHOver
= pInfo
->bHOverlapped
;
101 BOOL bVOver
= pInfo
->bVOverlapped
;
105 while (bHOver
) // nY konstant
108 if (rStartX
>= (SCsCOL
) nX1
&& !pDoc
->ColHidden(rStartX
, nTab
, nLastCol
))
110 bHOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bHOverlapped
;
111 bVOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bVOverlapped
;
115 USHORT nOverlap
= ((ScMergeFlagAttr
*)pDoc
->GetAttr(
116 rStartX
, rStartY
, nTab
, ATTR_MERGE_FLAG
))->GetValue();
117 bHOver
= ((nOverlap
& SC_MF_HOR
) != 0);
118 bVOver
= ((nOverlap
& SC_MF_VER
) != 0);
127 --nArrY
; // lokale Kopie !
129 if (rStartX
>= (SCsCOL
) nX1
&& rStartY
>= (SCsROW
) nY1
&&
130 !pDoc
->ColHidden(rStartX
, nTab
, nLastCol
) &&
131 !pDoc
->RowHidden(rStartY
, nTab
, nLastRow
) &&
132 (SCsROW
) pRowInfo
[nArrY
].nRowNo
== rStartY
)
134 bHOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bHOverlapped
;
135 bVOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bVOverlapped
;
139 USHORT nOverlap
= ((ScMergeFlagAttr
*)pDoc
->GetAttr(
140 rStartX
, rStartY
, nTab
, ATTR_MERGE_FLAG
))->GetValue();
141 bHOver
= ((nOverlap
& SC_MF_HOR
) != 0);
142 bVOver
= ((nOverlap
& SC_MF_VER
) != 0);
146 const ScMergeAttr
* pMerge
;
147 if (rStartX
>= (SCsCOL
) nX1
&& rStartY
>= (SCsROW
) nY1
&&
148 !pDoc
->ColHidden(rStartX
, nTab
, nLastCol
) &&
149 !pDoc
->RowHidden(rStartY
, nTab
, nLastRow
) &&
150 (SCsROW
) pRowInfo
[nArrY
].nRowNo
== rStartY
)
152 pMerge
= (const ScMergeAttr
*) &pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].pPatternAttr
->
156 pMerge
= (const ScMergeAttr
*) pDoc
->GetAttr(rStartX
,rStartY
,nTab
,ATTR_MERGE
);
158 rEndX
= rStartX
+ pMerge
->GetColMerge() - 1;
159 rEndY
= rStartY
+ pMerge
->GetRowMerge() - 1;
162 #define CELLINFO(x,y) pRowInfo[nArrY+y].pCellInfo[nArrX+x]
164 void ScDocument::FillInfo( ScTableInfo
& rTabInfo
, SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
,
165 SCTAB nTab
, double nScaleX
, double nScaleY
,
166 BOOL bPageMode
, BOOL bFormulaMode
, const ScMarkData
* pMarkData
)
168 DBG_ASSERT( pTab
[nTab
], "Tabelle existiert nicht" );
170 BOOL bLayoutRTL
= IsLayoutRTL( nTab
);
172 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
173 ScStyleSheetPool
* pStlPool
= xPoolHelper
->GetStylePool();
175 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
177 const SvxBrushItem
* pDefBackground
=
178 (const SvxBrushItem
*) &pPool
->GetDefaultItem( ATTR_BACKGROUND
);
179 const ScMergeAttr
* pDefMerge
=
180 (const ScMergeAttr
*) &pPool
->GetDefaultItem( ATTR_MERGE
);
181 const SvxShadowItem
* pDefShadow
=
182 (const SvxShadowItem
*) &pPool
->GetDefaultItem( ATTR_SHADOW
);
191 BOOL bAnyMerged
= FALSE
;
192 BOOL bAnyShadow
= FALSE
;
193 BOOL bAnyCondition
= FALSE
;
195 BOOL bTabProtect
= IsTabProtected(nTab
);
197 // fuer Blockmarken von zusammengefassten Zellen mit
198 // versteckter erster Zeile / Spalte
199 BOOL bPaintMarks
= FALSE
;
200 BOOL bSkipMarks
= FALSE
;
201 SCCOL nBlockStartX
= 0, nBlockEndX
= 0;
202 SCROW nBlockEndY
= 0, nBlockStartY
= 0;
203 if (pMarkData
&& pMarkData
->IsMarked())
206 pMarkData
->GetMarkArea(aTmpRange
);
207 if ( nTab
>= aTmpRange
.aStart
.Tab() && nTab
<= aTmpRange
.aEnd
.Tab() )
209 nBlockStartX
= aTmpRange
.aStart
.Col();
210 nBlockStartY
= aTmpRange
.aStart
.Row();
211 nBlockEndX
= aTmpRange
.aEnd
.Col();
212 nBlockEndY
= aTmpRange
.aEnd
.Row();
213 ExtendHidden( nBlockStartX
, nBlockStartY
, nBlockEndX
, nBlockEndY
, nTab
); //? noetig ?
214 if (pMarkData
->IsMarkNegative())
221 // zuerst nur die Eintraege fuer die ganze Spalte
224 SCROW nYExtra
= nY2
+1;
225 for (nSignedY
=((SCsROW
)nY1
)-1; nSignedY
<=(SCsROW
)nYExtra
; nSignedY
++)
228 nY
= (SCROW
) nSignedY
;
230 nY
= MAXROW
+1; // ungueltig
234 nDocHeight
= GetRowHeight( nY
, nTab
);
236 nDocHeight
= ScGlobal::nStdRowHeight
;
238 if ( nArrY
==0 || nDocHeight
|| nY
> MAXROW
)
240 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
241 pThisRowInfo
->pCellInfo
= NULL
; // wird unten belegt
243 USHORT nHeight
= (USHORT
) ( nDocHeight
* nScaleY
);
247 pThisRowInfo
->nRowNo
= nY
; //! Fall < 0 ?
248 pThisRowInfo
->nHeight
= nHeight
;
249 pThisRowInfo
->bEmptyBack
= TRUE
;
250 pThisRowInfo
->bEmptyText
= TRUE
;
251 pThisRowInfo
->bChanged
= TRUE
;
252 pThisRowInfo
->bAutoFilter
= FALSE
;
253 pThisRowInfo
->bPushButton
= FALSE
;
254 pThisRowInfo
->nRotMaxCol
= SC_ROTMAX_NONE
;
257 if (nArrY
>= ROWINFO_MAX
)
259 DBG_ERROR("Zu grosser Bereich bei FillInfo" );
260 nYExtra
= nSignedY
; // Ende
261 nY2
= nYExtra
- 1; // Bereich anpassen
265 if (nSignedY
==(SCsROW
) nYExtra
) // zusaetzliche Zeile verdeckt ?
268 nArrCount
= nArrY
; // incl. Dummys
272 // Attribut im Dokument ueberhaupt verwendet?
273 BOOL bAnyItem
= FALSE
;
274 USHORT nRotCount
= pPool
->GetItemCount( ATTR_ROTATE_VALUE
);
275 for (USHORT nItem
=0; nItem
<nRotCount
; nItem
++)
276 if (pPool
->GetItem( ATTR_ROTATE_VALUE
, nItem
))
283 if ( bAnyItem
&& HasAttrib( 0,nY1
,nTab
, MAXCOL
,nY2
+1,nTab
,
284 HASATTR_ROTATE
| HASATTR_CONDITIONAL
) )
286 //! Conditionals auch bei HASATTR_ROTATE abfragen ????
288 DBG_ASSERT( nArrCount
>2, "nArrCount zu klein" );
289 // FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-2, nX1, nX2 );
290 FindMaxRotCol( nTab
, &pRowInfo
[1], nArrCount
-1, nX1
, nX2
);
291 // FindMaxRotCol setzt nRotMaxCol
293 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
294 if (pRowInfo
[nArrY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nArrY
].nRotMaxCol
> nRotMax
)
295 nRotMax
= pRowInfo
[nArrY
].nRotMaxCol
;
298 // Zell-Infos erst nach dem Test auf gedrehte allozieren
299 // bis nRotMax wegen nRotateDir Flag
301 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
303 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
304 nY
= pThisRowInfo
->nRowNo
;
305 pThisRowInfo
->pCellInfo
= new CellInfo
[ nRotMax
+1+2 ]; // vom Aufrufer zu loeschen !
307 for (nArrX
=0; nArrX
<=nRotMax
+2; nArrX
++) // Zell-Infos vorbelegen
312 nX
= MAXCOL
+1; // ungueltig
314 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
315 pInfo
->bEmptyCellText
= TRUE
;
318 pInfo
->bMarked
= ( nX
>= nBlockStartX
&& nX
<= nBlockEndX
319 && nY
>= nBlockStartY
&& nY
<= nBlockEndY
);
321 pInfo
->bMarked
= FALSE
;
324 pInfo
->nClipMark
= SC_CLIPMARK_NONE
;
325 pInfo
->bMerged
= FALSE
;
326 pInfo
->bHOverlapped
= FALSE
;
327 pInfo
->bVOverlapped
= FALSE
;
328 pInfo
->bAutoFilter
= FALSE
;
329 pInfo
->bPushButton
= FALSE
;
330 pInfo
->bPopupButton
= false;
331 pInfo
->bFilterActive
= false;
332 pInfo
->nRotateDir
= SC_ROTDIR_NONE
;
334 pInfo
->bPrinted
= FALSE
; // view-intern
335 pInfo
->bHideGrid
= FALSE
; // view-intern
336 pInfo
->bEditEngine
= FALSE
; // view-intern
338 pInfo
->pBackground
= NULL
; //! weglassen?
339 pInfo
->pPatternAttr
= NULL
;
340 pInfo
->pConditionSet
= NULL
;
342 pInfo
->pLinesAttr
= NULL
;
343 pInfo
->mpTLBRLine
= NULL
;
344 pInfo
->mpBLTRLine
= NULL
;
346 pInfo
->pShadowAttr
= pDefShadow
;
347 pInfo
->pHShadowOrigin
= NULL
;
348 pInfo
->pVShadowOrigin
= NULL
;
352 for (nArrX
=nX2
+3; nArrX
<=nRotMax
+2; nArrX
++) // restliche Breiten eintragen
357 if (!ColHidden(nX
, nTab
))
359 USHORT nThisWidth
= (USHORT
) (GetColWidth( nX
, nTab
) * nScaleX
);
363 pRowInfo
[0].pCellInfo
[nArrX
].nWidth
= nThisWidth
;
368 for (nArrX
=0; nArrX
<=nX2
+2; nArrX
++) // links & rechts + 1
370 nX
= (nArrX
>0) ? nArrX
-1 : MAXCOL
+1; // negativ -> ungueltig
374 // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
375 // will disturb the output
377 // TODO: Optimize this loop.
378 if (!ColHidden(nX
, nTab
))
380 USHORT nThisWidth
= (USHORT
) (GetColWidth( nX
, nTab
) * nScaleX
);
384 pRowInfo
[0].pCellInfo
[nArrX
].nWidth
= nThisWidth
; //! dies sollte reichen
386 ScColumn
* pThisCol
= &pTab
[nTab
]->aCol
[nX
]; // Spalten-Daten
390 (void) pThisCol
->Search( nY1
, nUIndex
);
391 while ( nUIndex
< pThisCol
->nCount
&&
392 (nThisRow
=pThisCol
->pItems
[nUIndex
].nRow
) <= nY2
)
394 if ( !RowHidden( nThisRow
,nTab
) )
396 while ( pRowInfo
[nArrY
].nRowNo
< nThisRow
)
398 DBG_ASSERT( pRowInfo
[nArrY
].nRowNo
== nThisRow
, "Zeile nicht gefunden in FillInfo" );
400 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
401 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
402 pInfo
->pCell
= pThisCol
->pItems
[nUIndex
].pCell
;
403 if (pInfo
->pCell
->GetCellType() != CELLTYPE_NOTE
)
405 pThisRowInfo
->bEmptyText
= FALSE
; // Zeile nicht leer
406 pInfo
->bEmptyCellText
= FALSE
; // Zelle nicht leer
413 if (nX
+1 >= nX1
) // Attribute/Blockmarken ab nX1-1
415 ScAttrArray
* pThisAttrArr
= pThisCol
->pAttrArray
; // Attribute
418 const ScPatternAttr
* pPattern
;
419 SCROW nCurRow
=nY1
; // einzelne Zeile
421 --nCurRow
; // oben 1 mehr
424 nThisRow
=nCurRow
; // Ende des Bereichs
426 (void) pThisAttrArr
->Search( nCurRow
, nIndex
);
431 nThisRow
=pThisAttrArr
->pData
[nIndex
].nRow
; // Ende des Bereichs
432 pPattern
=pThisAttrArr
->pData
[nIndex
].pPattern
;
434 const SvxBrushItem
* pBackground
= (const SvxBrushItem
*)
435 &pPattern
->GetItem(ATTR_BACKGROUND
);
436 const SvxBoxItem
* pLinesAttr
= (const SvxBoxItem
*)
437 &pPattern
->GetItem(ATTR_BORDER
);
439 const SvxLineItem
* pTLBRLine
= static_cast< const SvxLineItem
* >(
440 &pPattern
->GetItem( ATTR_BORDER_TLBR
) );
441 const SvxLineItem
* pBLTRLine
= static_cast< const SvxLineItem
* >(
442 &pPattern
->GetItem( ATTR_BORDER_BLTR
) );
444 const SvxShadowItem
* pShadowAttr
= (const SvxShadowItem
*)
445 &pPattern
->GetItem(ATTR_SHADOW
);
446 if (pShadowAttr
!= pDefShadow
)
449 const ScMergeAttr
* pMergeAttr
= (const ScMergeAttr
*)
450 &pPattern
->GetItem(ATTR_MERGE
);
451 BOOL bMerged
= ( pMergeAttr
!= pDefMerge
&& *pMergeAttr
!= *pDefMerge
);
452 USHORT nOverlap
= ((const ScMergeFlagAttr
*) &pPattern
->GetItemSet().
453 Get(ATTR_MERGE_FLAG
))->GetValue();
454 BOOL bHOverlapped
= ((nOverlap
& SC_MF_HOR
) != 0);
455 BOOL bVOverlapped
= ((nOverlap
& SC_MF_VER
) != 0);
456 BOOL bAutoFilter
= ((nOverlap
& SC_MF_AUTO
) != 0);
457 BOOL bPushButton
= ((nOverlap
& SC_MF_BUTTON
) != 0);
458 BOOL bScenario
= ((nOverlap
& SC_MF_SCENARIO
) != 0);
459 bool bPopupButton
= ((nOverlap
& SC_MF_BUTTON_POPUP
) != 0);
460 bool bFilterActive
= ((nOverlap
& SC_MF_HIDDEN_MEMBER
) != 0);
461 if (bMerged
||bHOverlapped
||bVOverlapped
)
462 bAnyMerged
= TRUE
; // intern
464 BOOL bHidden
, bHideFormula
;
467 const ScProtectionAttr
& rProtAttr
= (const ScProtectionAttr
&)
468 pPattern
->GetItem(ATTR_PROTECTION
);
469 bHidden
= rProtAttr
.GetHideCell();
470 bHideFormula
= rProtAttr
.GetHideFormula();
473 bHidden
= bHideFormula
= FALSE
;
475 ULONG nConditional
= ((const SfxUInt32Item
&)pPattern
->
476 GetItem(ATTR_CONDITIONAL
)).GetValue();
477 const ScConditionalFormat
* pCondForm
= NULL
;
478 if ( nConditional
&& pCondFormList
)
479 pCondForm
= pCondFormList
->GetFormat( nConditional
);
485 SCROW nLastHiddenRow
= -1;
486 bool bRowHidden
= RowHidden(nCurRow
, nTab
, nLastHiddenRow
);
488 bool bRowHidden
= RowHidden(nCurRow
, nTab
);
490 if ( nArrY
==0 || !bRowHidden
)
492 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
493 if (pBackground
!= pDefBackground
) // Spalten-HG == Standard ?
494 pThisRowInfo
->bEmptyBack
= FALSE
;
496 pThisRowInfo
->bAutoFilter
= TRUE
;
498 pThisRowInfo
->bPushButton
= TRUE
;
500 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
501 pInfo
->pBackground
= pBackground
;
502 pInfo
->pPatternAttr
= pPattern
;
503 pInfo
->bMerged
= bMerged
;
504 pInfo
->bHOverlapped
= bHOverlapped
;
505 pInfo
->bVOverlapped
= bVOverlapped
;
506 pInfo
->bAutoFilter
= bAutoFilter
;
507 pInfo
->bPushButton
= bPushButton
;
508 pInfo
->bPopupButton
= bPopupButton
;
509 pInfo
->bFilterActive
= bFilterActive
;
510 pInfo
->pLinesAttr
= pLinesAttr
;
511 pInfo
->mpTLBRLine
= pTLBRLine
;
512 pInfo
->mpBLTRLine
= pBLTRLine
;
513 pInfo
->pShadowAttr
= pShadowAttr
;
514 // nWidth wird nicht mehr einzeln gesetzt
516 BOOL bEmbed
= FALSE
; //bIsEmbedded &&
517 nTab
>= aEmbedRange
.aStart
.Tab() &&
518 nTab
<= aEmbedRange
.aEnd
.Tab() &&
519 nX
>= aEmbedRange
.aStart
.Col() &&
520 nX
<= aEmbedRange
.aEnd
.Col() &&
521 nCurRow
>= aEmbedRange
.aStart
.Row() &&
522 nCurRow
<= aEmbedRange
.aEnd
.Row();
526 pInfo
->pBackground
= ScGlobal::GetButtonBrushItem();
527 pThisRowInfo
->bEmptyBack
= FALSE
;
531 pInfo
->pBackground
= ScGlobal::GetEmbeddedBrushItem();
532 pThisRowInfo
->bEmptyBack
= FALSE
;
535 if (bHidden
|| ( bFormulaMode
&& bHideFormula
&& pInfo
->pCell
536 && pInfo
->pCell
->GetCellType()
537 == CELLTYPE_FORMULA
))
538 pInfo
->bEmptyCellText
= TRUE
;
542 String aStyle
= pCondForm
->GetCellStyle( pInfo
->pCell
,
543 ScAddress( nX
, nCurRow
, nTab
) );
546 SfxStyleSheetBase
* pStyleSheet
=
547 pStlPool
->Find( aStyle
, SFX_STYLE_FAMILY_PARA
);
550 //! Style-Sets cachen !!!
551 pInfo
->pConditionSet
= &pStyleSheet
->GetItemSet();
552 bAnyCondition
= TRUE
;
554 // if style is not there, treat like no condition
561 else if (bRowHidden
&& nLastHiddenRow
>= 0)
563 nCurRow
= nLastHiddenRow
;
564 if (nCurRow
> nThisRow
)
570 while (nCurRow
<= nThisRow
&& nCurRow
<= nYExtra
);
573 while ( nIndex
< pThisAttrArr
->nCount
&& nThisRow
< nYExtra
);
576 if (pMarkData
&& pMarkData
->IsMultiMarked())
579 const ScMarkArray
* pThisMarkArr
= pMarkData
->GetArray()+nX
;
582 nCurRow
= nY1
; // einzelne Zeile
583 nThisRow
= nY1
; // Ende des Bereichs
585 if ( pThisMarkArr
->Search( nY1
, nIndex
) )
589 nThisRow
=pThisMarkArr
->pData
[nIndex
].nRow
; // Ende des Bereichs
590 bThisMarked
=pThisMarkArr
->pData
[nIndex
].bMarked
;
594 if ( !RowHidden( nCurRow
,nTab
) )
598 BOOL bSkip
= bSkipMarks
&&
599 nX
>= nBlockStartX
&&
601 nCurRow
>= nBlockStartY
&&
602 nCurRow
<= nBlockEndY
;
605 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
606 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
607 pInfo
->bMarked
= TRUE
;
614 while (nCurRow
<= nThisRow
&& nCurRow
<= nY2
);
617 while ( nIndex
< pThisMarkArr
->nCount
&& nThisRow
< nY2
);
621 else // vordere Spalten
623 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
625 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
626 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
628 pInfo
->nWidth
= nThisWidth
; //! oder nur 0 abfragen ??
634 pRowInfo
[0].pCellInfo
[nArrX
].nWidth
= STD_COL_WIDTH
;
635 // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht
638 //-------------------------------------------------------------------------
639 // bedingte Formatierung auswerten
643 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
645 for (nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++) // links und rechts einer mehr
647 CellInfo
* pInfo
= &pRowInfo
[nArrY
].pCellInfo
[nArrX
];
648 const SfxItemSet
* pCondSet
= pInfo
->pConditionSet
;
651 const SfxPoolItem
* pItem
;
654 if ( pCondSet
->GetItemState( ATTR_BACKGROUND
, TRUE
, &pItem
) == SFX_ITEM_SET
)
656 pInfo
->pBackground
= (const SvxBrushItem
*) pItem
;
657 pRowInfo
[nArrY
].bEmptyBack
= FALSE
;
661 if ( pCondSet
->GetItemState( ATTR_BORDER
, TRUE
, &pItem
) == SFX_ITEM_SET
)
662 pInfo
->pLinesAttr
= (const SvxBoxItem
*) pItem
;
664 if ( pCondSet
->GetItemState( ATTR_BORDER_TLBR
, TRUE
, &pItem
) == SFX_ITEM_SET
)
665 pInfo
->mpTLBRLine
= static_cast< const SvxLineItem
* >( pItem
);
666 if ( pCondSet
->GetItemState( ATTR_BORDER_BLTR
, TRUE
, &pItem
) == SFX_ITEM_SET
)
667 pInfo
->mpBLTRLine
= static_cast< const SvxLineItem
* >( pItem
);
670 if ( pCondSet
->GetItemState( ATTR_SHADOW
, TRUE
, &pItem
) == SFX_ITEM_SET
)
672 pInfo
->pShadowAttr
= (const SvxShadowItem
*) pItem
;
680 // bedingte Formatierung Ende
681 //-------------------------------------------------------------------------
684 // Daten von zusammengefassten Zellen anpassen
689 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
691 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
692 nSignedY
= nArrY
? pThisRowInfo
->nRowNo
: ((SCsROW
)nY1
)-1;
694 for (nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++) // links und rechts einer mehr
696 SCsCOL nSignedX
= ((SCsCOL
) nArrX
) - 1;
697 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrX
];
699 if (pInfo
->bMerged
|| pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
705 lcl_GetMergeRange( nSignedX
,nSignedY
, nArrY
, this,pRowInfo
, nX1
,nY1
,nX2
,nY2
,nTab
,
706 nStartX
,nStartY
, nEndX
,nEndY
);
707 const ScPatternAttr
* pStartPattern
= GetPattern( nStartX
,nStartY
,nTab
);
708 const SfxItemSet
* pStartCond
= GetCondResult( nStartX
,nStartY
,nTab
);
709 const SfxPoolItem
* pItem
;
711 // Hintergrund kopieren (oder in output.cxx)
713 if ( !pStartCond
|| pStartCond
->
714 GetItemState(ATTR_BACKGROUND
,TRUE
,&pItem
) != SFX_ITEM_SET
)
715 pItem
= &pStartPattern
->GetItem(ATTR_BACKGROUND
);
716 pInfo
->pBackground
= (const SvxBrushItem
*) pItem
;
717 pRowInfo
[nArrY
].bEmptyBack
= FALSE
;
721 if ( !pStartCond
|| pStartCond
->
722 GetItemState(ATTR_SHADOW
,TRUE
,&pItem
) != SFX_ITEM_SET
)
723 pItem
= &pStartPattern
->GetItem(ATTR_SHADOW
);
724 pInfo
->pShadowAttr
= (const SvxShadowItem
*) pItem
;
725 if (pInfo
->pShadowAttr
!= pDefShadow
)
728 // Blockmarken - wieder mit Original-Merge-Werten
730 BOOL bCellMarked
= FALSE
;
732 bCellMarked
= ( nStartX
>= (SCsCOL
) nBlockStartX
733 && nStartX
<= (SCsCOL
) nBlockEndX
734 && nStartY
>= (SCsROW
) nBlockStartY
735 && nStartY
<= (SCsROW
) nBlockEndY
);
736 if (pMarkData
&& pMarkData
->IsMultiMarked() && !bCellMarked
)
738 const ScMarkArray
* pThisMarkArr
= pMarkData
->GetArray()+nStartX
;
740 if ( pThisMarkArr
->Search( nStartY
, nIndex
) )
741 bCellMarked
=pThisMarkArr
->pData
[nIndex
].bMarked
;
744 pInfo
->bMarked
= bCellMarked
;
750 if (bAnyShadow
) // Schatten verteilen
752 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
754 BOOL bTop
= ( nArrY
== 0 );
755 BOOL bBottom
= ( nArrY
+1 == nArrCount
);
757 for (nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++) // links und rechts einer mehr
759 BOOL bLeft
= ( nArrX
== nX1
);
760 BOOL bRight
= ( nArrX
== nX2
+2 );
762 CellInfo
* pInfo
= &pRowInfo
[nArrY
].pCellInfo
[nArrX
];
763 const SvxShadowItem
* pThisAttr
= pInfo
->pShadowAttr
;
764 SvxShadowLocation eLoc
= pThisAttr
? pThisAttr
->GetLocation() : SVX_SHADOW_NONE
;
765 if (eLoc
!= SVX_SHADOW_NONE
)
767 // oder Test auf != eLoc
772 while ( nArrX
+nDxPos
< nX2
+2 && pRowInfo
[0].pCellInfo
[nArrX
+nDxPos
].nWidth
== 0 )
774 while ( nArrX
+nDxNeg
> nX1
&& pRowInfo
[0].pCellInfo
[nArrX
+nDxNeg
].nWidth
== 0 )
777 BOOL bLeftDiff
= !bLeft
&&
778 CELLINFO(nDxNeg
,0).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
779 BOOL bRightDiff
= !bRight
&&
780 CELLINFO(nDxPos
,0).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
781 BOOL bTopDiff
= !bTop
&&
782 CELLINFO(0,-1).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
783 BOOL bBottomDiff
= !bBottom
&&
784 CELLINFO(0,1).pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
790 case SVX_SHADOW_BOTTOMRIGHT
: eLoc
= SVX_SHADOW_BOTTOMLEFT
; break;
791 case SVX_SHADOW_BOTTOMLEFT
: eLoc
= SVX_SHADOW_BOTTOMRIGHT
; break;
792 case SVX_SHADOW_TOPRIGHT
: eLoc
= SVX_SHADOW_TOPLEFT
; break;
793 case SVX_SHADOW_TOPLEFT
: eLoc
= SVX_SHADOW_TOPRIGHT
; break;
796 // added to avoid warnings
803 case SVX_SHADOW_BOTTOMRIGHT
:
806 CELLINFO(0,1).pHShadowOrigin
= pThisAttr
;
807 CELLINFO(0,1).eHShadowPart
=
808 bLeftDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
812 CELLINFO(1,0).pVShadowOrigin
= pThisAttr
;
813 CELLINFO(1,0).eVShadowPart
=
814 bTopDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
816 if (bBottomDiff
&& bRightDiff
)
818 CELLINFO(1,1).pHShadowOrigin
= pThisAttr
;
819 CELLINFO(1,1).eHShadowPart
= SC_SHADOW_CORNER
;
823 case SVX_SHADOW_BOTTOMLEFT
:
826 CELLINFO(0,1).pHShadowOrigin
= pThisAttr
;
827 CELLINFO(0,1).eHShadowPart
=
828 bRightDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
832 CELLINFO(-1,0).pVShadowOrigin
= pThisAttr
;
833 CELLINFO(-1,0).eVShadowPart
=
834 bTopDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
836 if (bBottomDiff
&& bLeftDiff
)
838 CELLINFO(-1,1).pHShadowOrigin
= pThisAttr
;
839 CELLINFO(-1,1).eHShadowPart
= SC_SHADOW_CORNER
;
843 case SVX_SHADOW_TOPRIGHT
:
846 CELLINFO(0,-1).pHShadowOrigin
= pThisAttr
;
847 CELLINFO(0,-1).eHShadowPart
=
848 bLeftDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
852 CELLINFO(1,0).pVShadowOrigin
= pThisAttr
;
853 CELLINFO(1,0).eVShadowPart
=
854 bBottomDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
856 if (bTopDiff
&& bRightDiff
)
858 CELLINFO(1,-1).pHShadowOrigin
= pThisAttr
;
859 CELLINFO(1,-1).eHShadowPart
= SC_SHADOW_CORNER
;
863 case SVX_SHADOW_TOPLEFT
:
866 CELLINFO(0,-1).pHShadowOrigin
= pThisAttr
;
867 CELLINFO(0,-1).eHShadowPart
=
868 bRightDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
872 CELLINFO(-1,0).pVShadowOrigin
= pThisAttr
;
873 CELLINFO(-1,0).eVShadowPart
=
874 bBottomDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
876 if (bTopDiff
&& bLeftDiff
)
878 CELLINFO(-1,-1).pHShadowOrigin
= pThisAttr
;
879 CELLINFO(-1,-1).eHShadowPart
= SC_SHADOW_CORNER
;
884 DBG_ERROR("falscher Shadow-Enum");
891 rTabInfo
.mnArrCount
= sal::static_int_cast
<USHORT
>(nArrCount
);
892 rTabInfo
.mbPageMode
= bPageMode
;
894 // ========================================================================
895 // *** create the frame border array ***
897 // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
898 // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
900 size_t nColCount
= nX2
- nX1
+ 3;
901 size_t nRowCount
= nArrCount
;
903 svx::frame::Array
& rArray
= rTabInfo
.maArray
;
904 rArray
.Initialize( nColCount
, nRowCount
);
905 rArray
.SetUseDiagDoubleClipping( false );
907 for( size_t nRow
= 0; nRow
< nRowCount
; ++nRow
)
909 USHORT nCellInfoY
= static_cast< USHORT
>( nRow
);
910 RowInfo
& rThisRowInfo
= pRowInfo
[ nCellInfoY
];
912 for( size_t nCol
= 0; nCol
< nColCount
; ++nCol
)
914 USHORT nCellInfoX
= static_cast< USHORT
>( nCol
+ nX1
);
915 const CellInfo
& rInfo
= rThisRowInfo
.pCellInfo
[ nCellInfoX
];
917 const SvxBoxItem
* pBox
= rInfo
.pLinesAttr
;
918 const SvxLineItem
* pTLBR
= rInfo
.mpTLBRLine
;
919 const SvxLineItem
* pBLTR
= rInfo
.mpBLTRLine
;
921 size_t nFirstCol
= nCol
;
922 size_t nFirstRow
= nRow
;
924 // *** merged cells *** -------------------------------------------
926 if( !rArray
.IsMerged( nCol
, nRow
) && (rInfo
.bMerged
|| rInfo
.bHOverlapped
|| rInfo
.bVOverlapped
) )
928 // *** insert merged range in svx::frame::Array ***
930 /* #i69369# top-left cell of a merged range may be located in
931 a hidden column or row. Use lcl_GetMergeRange() to find the
932 complete merged range, then calculate dimensions and
933 document position of the visible range. */
935 // note: document columns are always one less than CellInfoX coords
936 // note: document rows must be looked up in RowInfo structs
938 // current column and row in document coordinates
939 SCCOL nCurrDocCol
= static_cast< SCCOL
>( nCellInfoX
- 1 );
940 SCROW nCurrDocRow
= static_cast< SCROW
>( (nCellInfoY
> 0) ? rThisRowInfo
.nRowNo
: (nY1
- 1) );
942 // find entire merged range in document, returns signed document coordinates
943 SCsCOL nFirstRealDocColS
, nLastRealDocColS
;
944 SCsROW nFirstRealDocRowS
, nLastRealDocRowS
;
945 lcl_GetMergeRange( static_cast< SCsCOL
>( nCurrDocCol
), static_cast< SCsROW
>( nCurrDocRow
),
946 nCellInfoY
, this, pRowInfo
, nX1
,nY1
,nX2
,nY2
,nTab
,
947 nFirstRealDocColS
, nFirstRealDocRowS
, nLastRealDocColS
, nLastRealDocRowS
);
949 // *complete* merged range in document coordinates
950 SCCOL nFirstRealDocCol
= static_cast< SCCOL
>( nFirstRealDocColS
);
951 SCROW nFirstRealDocRow
= static_cast< SCROW
>( nFirstRealDocRowS
);
952 SCCOL nLastRealDocCol
= static_cast< SCCOL
>( nLastRealDocColS
);
953 SCROW nLastRealDocRow
= static_cast< SCROW
>( nLastRealDocRowS
);
955 // first visible column (nX1-1 is first processed document column)
956 SCCOL nFirstDocCol
= (nX1
> 0) ? ::std::max
< SCCOL
>( nFirstRealDocCol
, nX1
- 1 ) : nFirstRealDocCol
;
957 USHORT nFirstCellInfoX
= static_cast< USHORT
>( nFirstDocCol
+ 1 );
958 nFirstCol
= static_cast< size_t >( nFirstCellInfoX
- nX1
);
960 // last visible column (nX2+1 is last processed document column)
961 SCCOL nLastDocCol
= (nX2
< MAXCOL
) ? ::std::min
< SCCOL
>( nLastRealDocCol
, nX2
+ 1 ) : nLastRealDocCol
;
962 USHORT nLastCellInfoX
= static_cast< USHORT
>( nLastDocCol
+ 1 );
963 size_t nLastCol
= static_cast< size_t >( nLastCellInfoX
- nX1
);
966 USHORT nFirstCellInfoY
= nCellInfoY
;
967 while( ((nFirstCellInfoY
> 1) && (pRowInfo
[ nFirstCellInfoY
- 1 ].nRowNo
>= nFirstRealDocRow
)) ||
968 ((nFirstCellInfoY
== 1) && (static_cast< SCROW
>( nY1
- 1 ) >= nFirstRealDocRow
)) )
970 SCROW nFirstDocRow
= (nFirstCellInfoY
> 0) ? pRowInfo
[ nFirstCellInfoY
].nRowNo
: static_cast< SCROW
>( nY1
- 1 );
971 nFirstRow
= static_cast< size_t >( nFirstCellInfoY
);
974 USHORT nLastCellInfoY
= nCellInfoY
;
975 while( (sal::static_int_cast
<SCSIZE
>(nLastCellInfoY
+ 1) < nArrCount
) &&
976 (pRowInfo
[ nLastCellInfoY
+ 1 ].nRowNo
<= nLastRealDocRow
) )
978 SCROW nLastDocRow
= (nLastCellInfoY
> 0) ? pRowInfo
[ nLastCellInfoY
].nRowNo
: static_cast< SCROW
>( nY1
- 1 );
979 size_t nLastRow
= static_cast< size_t >( nLastCellInfoY
);
981 // insert merged range
982 rArray
.SetMergedRange( nFirstCol
, nFirstRow
, nLastCol
, nLastRow
);
984 // *** find additional size not included in svx::frame::Array ***
986 // additional space before first column
990 for( SCCOL nDocCol
= nFirstRealDocCol
; nDocCol
< nFirstDocCol
; ++nDocCol
)
991 nSize
+= std::max( static_cast< long >( GetColWidth( nDocCol
, nTab
) * nScaleX
), 1L );
992 rArray
.SetAddMergedLeftSize( nCol
, nRow
, nSize
);
994 // additional space after last column
995 if( nLastCol
+ 1 == nColCount
)
998 for( SCCOL nDocCol
= nLastDocCol
+ 1; nDocCol
<= nLastRealDocCol
; ++nDocCol
)
999 nSize
+= std::max( static_cast< long >( GetColWidth( nDocCol
, nTab
) * nScaleX
), 1L );
1000 rArray
.SetAddMergedRightSize( nCol
, nRow
, nSize
);
1002 // additional space above first row
1003 if( nFirstRow
== 0 )
1006 for( SCROW nDocRow
= nFirstRealDocRow
; nDocRow
< nFirstDocRow
; ++nDocRow
)
1007 nSize
+= std::max( static_cast< long >( GetRowHeight( nDocRow
, nTab
) * nScaleY
), 1L );
1008 rArray
.SetAddMergedTopSize( nCol
, nRow
, nSize
);
1010 // additional space beyond last row
1011 if( nLastRow
+ 1 == nRowCount
)
1014 for( SCROW nDocRow
= nLastDocRow
+ 1; nDocRow
<= nLastRealDocRow
; ++nDocRow
)
1015 nSize
+= std::max( static_cast< long >( GetRowHeight( nDocRow
, nTab
) * nScaleY
), 1L );
1016 rArray
.SetAddMergedBottomSize( nCol
, nRow
, nSize
);
1019 // *** use line attributes from real origin cell ***
1021 if( (nFirstRealDocCol
!= nCurrDocCol
) || (nFirstRealDocRow
!= nCurrDocRow
) )
1023 if( const ScPatternAttr
* pPattern
= GetPattern( nFirstRealDocCol
, nFirstRealDocRow
, nTab
) )
1025 const SfxItemSet
* pCond
= GetCondResult( nFirstRealDocCol
, nFirstRealDocRow
, nTab
);
1026 pBox
= static_cast< const SvxBoxItem
* >( &pPattern
->GetItem( ATTR_BORDER
, pCond
) );
1027 pTLBR
= static_cast< const SvxLineItem
* >( &pPattern
->GetItem( ATTR_BORDER_TLBR
, pCond
) );
1028 pBLTR
= static_cast< const SvxLineItem
* >( &pPattern
->GetItem( ATTR_BORDER_BLTR
, pCond
) );
1038 // *** borders *** ------------------------------------------------
1042 rArray
.SetCellStyleLeft( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetLeft(), nScaleX
) );
1043 rArray
.SetCellStyleRight( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetRight(), nScaleX
) );
1044 rArray
.SetCellStyleTop( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetTop(), nScaleY
) );
1045 rArray
.SetCellStyleBottom( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetBottom(), nScaleY
) );
1049 rArray
.SetCellStyleTLBR( nFirstCol
, nFirstRow
, svx::frame::Style( pTLBR
->GetLine(), nScaleY
) );
1050 if( rInfo
.mpBLTRLine
)
1051 rArray
.SetCellStyleBLTR( nFirstCol
, nFirstRow
, svx::frame::Style( pBLTR
->GetLine(), nScaleY
) );
1055 /* Mirror the entire frame array.
1056 1st param = Mirror the vertical double line styles as well.
1057 2nd param = Do not swap diagonal lines.
1060 rArray
.MirrorSelfX( true, false );
1063 // ============================================================================
1065 ScTableInfo::ScTableInfo() :
1066 mpRowInfo( new RowInfo
[ ROWINFO_MAX
] ),
1069 for( USHORT nIdx
= 0; nIdx
< ROWINFO_MAX
; ++nIdx
)
1070 mpRowInfo
[ nIdx
].pCellInfo
= 0;
1073 ScTableInfo::~ScTableInfo()
1075 for( USHORT nIdx
= 0; nIdx
< ROWINFO_MAX
; ++nIdx
)
1076 delete [] mpRowInfo
[ nIdx
].pCellInfo
;
1077 delete [] mpRowInfo
;
1080 // ============================================================================