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>
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"
43 #include "mtvcellfunc.hxx"
45 const sal_uInt16 ROWINFO_MAX
= 1024;
55 // Similar as in output.cxx
57 static void lcl_GetMergeRange( SCsCOL nX
, SCsROW nY
, SCSIZE nArrY
,
58 ScDocument
* pDoc
, RowInfo
* pRowInfo
,
59 SCCOL nX1
, SCROW nY1
, SCCOL
/* nX2 */, SCROW
/* nY2 */, SCTAB nTab
,
60 SCsCOL
& rStartX
, SCsROW
& rStartY
, SCsCOL
& rEndX
, SCsROW
& rEndY
)
62 CellInfo
* pInfo
= &pRowInfo
[nArrY
].pCellInfo
[nX
+1];
66 bool bHOver
= pInfo
->bHOverlapped
;
67 bool bVOver
= pInfo
->bVOverlapped
;
71 while (bHOver
) // nY constant
74 if (rStartX
>= (SCsCOL
) nX1
&& !pDoc
->ColHidden(rStartX
, nTab
, NULL
, &nLastCol
))
76 bHOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bHOverlapped
;
77 bVOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bVOverlapped
;
81 sal_uInt16 nOverlap
= static_cast<const ScMergeFlagAttr
*>(pDoc
->GetAttr(
82 rStartX
, rStartY
, nTab
, ATTR_MERGE_FLAG
))->GetValue();
83 bHOver
= ((nOverlap
& SC_MF_HOR
) != 0);
84 bVOver
= ((nOverlap
& SC_MF_VER
) != 0);
93 --nArrY
; // local copy !
95 if (rStartX
>= (SCsCOL
) nX1
&& rStartY
>= (SCsROW
) nY1
&&
96 !pDoc
->ColHidden(rStartX
, nTab
, NULL
, &nLastCol
) &&
97 !pDoc
->RowHidden(rStartY
, nTab
, NULL
, &nLastRow
) &&
98 (SCsROW
) pRowInfo
[nArrY
].nRowNo
== rStartY
)
100 bVOver
= pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].bVOverlapped
;
104 sal_uInt16 nOverlap
= static_cast<const ScMergeFlagAttr
*>(pDoc
->GetAttr(
105 rStartX
, rStartY
, nTab
, ATTR_MERGE_FLAG
))->GetValue();
106 bVOver
= ((nOverlap
& SC_MF_VER
) != 0);
110 const ScMergeAttr
* pMerge
;
111 if (rStartX
>= (SCsCOL
) nX1
&& rStartY
>= (SCsROW
) nY1
&&
112 !pDoc
->ColHidden(rStartX
, nTab
, NULL
, &nLastCol
) &&
113 !pDoc
->RowHidden(rStartY
, nTab
, NULL
, &nLastRow
) &&
114 (SCsROW
) pRowInfo
[nArrY
].nRowNo
== rStartY
)
116 pMerge
= static_cast<const ScMergeAttr
*>( &pRowInfo
[nArrY
].pCellInfo
[rStartX
+1].pPatternAttr
->
117 GetItem(ATTR_MERGE
));
120 pMerge
= static_cast<const ScMergeAttr
*>( pDoc
->GetAttr(rStartX
,rStartY
,nTab
,ATTR_MERGE
) );
122 rEndX
= rStartX
+ pMerge
->GetColMerge() - 1;
123 rEndY
= rStartY
+ pMerge
->GetRowMerge() - 1;
135 SCROW mnHiddenEndRow
;
138 bool isHidden(size_t nRow
)
140 SCROW nThisRow
= static_cast<SCROW
>(nRow
);
141 if (nThisRow
> mnHiddenEndRow
)
142 mbHiddenRow
= mrDoc
.RowHidden(nThisRow
, mnTab
, NULL
, &mnHiddenEndRow
);
146 void alignArray(size_t nRow
)
148 while (mpRowInfo
[mrArrY
].nRowNo
< static_cast<SCROW
>(nRow
))
152 void setInfo(size_t nRow
, const ScRefCellValue
& rCell
)
156 RowInfo
* pThisRowInfo
= &mpRowInfo
[mrArrY
];
157 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[mnArrX
];
158 pInfo
->maCell
= rCell
;
159 pThisRowInfo
->bEmptyText
= false;
160 pInfo
->bEmptyCellText
= false;
165 RowInfoFiller(ScDocument
& rDoc
, SCTAB nTab
, RowInfo
* pRowInfo
, SCCOL nArrX
, SCSIZE
& rArrY
) :
166 mrDoc(rDoc
), mnTab(nTab
), mpRowInfo(pRowInfo
), mnArrX(nArrX
), mrArrY(rArrY
),
167 mnHiddenEndRow(-1), mbHiddenRow(false) {}
169 void operator() (size_t nRow
, double fVal
)
172 setInfo(nRow
, ScRefCellValue(fVal
));
175 void operator() (size_t nRow
, const svl::SharedString
& rStr
)
178 setInfo(nRow
, ScRefCellValue(&rStr
));
181 void operator() (size_t nRow
, const EditTextObject
* p
)
184 setInfo(nRow
, ScRefCellValue(p
));
187 void operator() (size_t nRow
, const ScFormulaCell
* p
)
190 setInfo(nRow
, ScRefCellValue(const_cast<ScFormulaCell
*>(p
)));
196 void ScDocument::FillInfo(
197 ScTableInfo
& rTabInfo
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
198 SCTAB nTab
, double fColScale
, double fRowScale
, bool bPageMode
, bool bFormulaMode
,
199 const ScMarkData
* pMarkData
)
201 OSL_ENSURE( maTabs
[nTab
], "Table does not exist" );
203 bool bLayoutRTL
= IsLayoutRTL( nTab
);
205 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
206 ScStyleSheetPool
* pStlPool
= xPoolHelper
->GetStylePool();
208 RowInfo
* pRowInfo
= rTabInfo
.mpRowInfo
;
210 const SvxBrushItem
* pDefBackground
=
211 static_cast<const SvxBrushItem
*>( &pPool
->GetDefaultItem( ATTR_BACKGROUND
) );
212 const ScMergeAttr
* pDefMerge
=
213 static_cast<const ScMergeAttr
*>( &pPool
->GetDefaultItem( ATTR_MERGE
) );
214 const SvxShadowItem
* pDefShadow
=
215 static_cast<const SvxShadowItem
*>( &pPool
->GetDefaultItem( ATTR_SHADOW
) );
224 bool bAnyMerged
= false;
225 bool bAnyShadow
= false;
226 bool bAnyCondition
= false;
227 bool bAnyPreview
= false;
229 bool bTabProtect
= IsTabProtected(nTab
);
231 // for block marks of merged cells
232 // with hidden first row/column
233 bool bPaintMarks
= false;
234 bool bSkipMarks
= false;
235 SCCOL nBlockStartX
= 0, nBlockEndX
= 0;
236 SCROW nBlockEndY
= 0, nBlockStartY
= 0;
237 if (pMarkData
&& pMarkData
->IsMarked())
240 pMarkData
->GetMarkArea(aTmpRange
);
241 if ( nTab
>= aTmpRange
.aStart
.Tab() && nTab
<= aTmpRange
.aEnd
.Tab() )
243 nBlockStartX
= aTmpRange
.aStart
.Col();
244 nBlockStartY
= aTmpRange
.aStart
.Row();
245 nBlockEndX
= aTmpRange
.aEnd
.Col();
246 nBlockEndY
= aTmpRange
.aEnd
.Row();
247 ExtendHidden( nBlockStartX
, nBlockStartY
, nBlockEndX
, nBlockEndY
, nTab
); //? needed ?
248 if (pMarkData
->IsMarkNegative())
255 // first only the entries for the entire column
258 SCROW nYExtra
= nRow2
+1;
259 sal_uInt16 nDocHeight
= ScGlobal::nStdRowHeight
;
260 SCROW nDocHeightEndRow
= -1;
261 for (nSignedY
=((SCsROW
)nRow1
)-1; nSignedY
<=(SCsROW
)nYExtra
; nSignedY
++)
264 nY
= (SCROW
) nSignedY
;
266 nY
= MAXROW
+1; // invalid
268 if (nY
> nDocHeightEndRow
)
271 nDocHeight
= GetRowHeight( nY
, nTab
, NULL
, &nDocHeightEndRow
);
273 nDocHeight
= ScGlobal::nStdRowHeight
;
276 if ( nArrRow
==0 || nDocHeight
|| nY
> MAXROW
)
278 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrRow
];
279 pThisRowInfo
->pCellInfo
= NULL
; // is loaded below
281 sal_uInt16 nHeight
= (sal_uInt16
) ( nDocHeight
* fRowScale
);
285 pThisRowInfo
->nRowNo
= nY
; //TODO: case < 0 ?
286 pThisRowInfo
->nHeight
= nHeight
;
287 pThisRowInfo
->bEmptyBack
= true;
288 pThisRowInfo
->bEmptyText
= true;
289 pThisRowInfo
->bChanged
= true;
290 pThisRowInfo
->bAutoFilter
= false;
291 pThisRowInfo
->bPivotButton
= false;
292 pThisRowInfo
->nRotMaxCol
= SC_ROTMAX_NONE
;
295 if (nArrRow
>= ROWINFO_MAX
)
297 OSL_FAIL("FillInfo: Range too big" );
298 nYExtra
= nSignedY
; // End
299 nRow2
= nYExtra
- 1; // Adjust range
303 if (nSignedY
==(SCsROW
) nYExtra
) // hidden additional line?
306 nArrCount
= nArrRow
; // incl. Dummys
310 // Is Attribute really used in document?
311 bool bAnyItem
= false;
312 sal_uInt32 nRotCount
= pPool
->GetItemCount2( ATTR_ROTATE_VALUE
);
313 for (sal_uInt32 nItem
=0; nItem
<nRotCount
; nItem
++)
314 if (pPool
->GetItem2( ATTR_ROTATE_VALUE
, nItem
))
320 SCCOL nRotMax
= nCol2
;
321 if ( bAnyItem
&& HasAttrib( 0,nRow1
,nTab
, MAXCOL
,nRow2
+1,nTab
,
322 HASATTR_ROTATE
| HASATTR_CONDITIONAL
) )
324 //TODO: check Conditionals also for HASATTR_ROTATE ????
326 OSL_ENSURE( nArrCount
>2, "nArrCount too small" );
327 FindMaxRotCol( nTab
, &pRowInfo
[1], nArrCount
-1, nCol1
, nCol2
);
328 // FindMaxRotCol setzt nRotMaxCol
330 for (nArrRow
=0; nArrRow
<nArrCount
; nArrRow
++)
331 if (pRowInfo
[nArrRow
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nArrRow
].nRotMaxCol
> nRotMax
)
332 nRotMax
= pRowInfo
[nArrRow
].nRotMaxCol
;
335 // Allocate cell information only after the test rotation
336 // to nRotMax due to nRotateDir Flag
338 for (nArrRow
=0; nArrRow
<nArrCount
; nArrRow
++)
340 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrRow
];
341 nY
= pThisRowInfo
->nRowNo
;
342 pThisRowInfo
->pCellInfo
= new CellInfo
[ nRotMax
+1+2 ]; // to delete the caller!
344 for (nArrCol
=0; nArrCol
<=nRotMax
+2; nArrCol
++) // Preassign cell info
349 nX
= MAXCOL
+1; // invalid
351 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrCol
];
352 pInfo
->bEmptyCellText
= true;
353 pInfo
->maCell
.clear();
355 pInfo
->bMarked
= ( nX
>= nBlockStartX
&& nX
<= nBlockEndX
356 && nY
>= nBlockStartY
&& nY
<= nBlockEndY
);
358 pInfo
->bMarked
= false;
361 pInfo
->nClipMark
= SC_CLIPMARK_NONE
;
362 pInfo
->bMerged
= false;
363 pInfo
->bHOverlapped
= false;
364 pInfo
->bVOverlapped
= false;
365 pInfo
->bAutoFilter
= false;
366 pInfo
->bPivotButton
= false;
367 pInfo
->bPivotPopupButton
= false;
368 pInfo
->bFilterActive
= false;
369 pInfo
->nRotateDir
= SC_ROTDIR_NONE
;
371 pInfo
->bPrinted
= false; // view-internal
372 pInfo
->bHideGrid
= false; // view-internal
373 pInfo
->bEditEngine
= false; // view-internal
375 pInfo
->pBackground
= NULL
; //TODO: omit?
376 pInfo
->pPatternAttr
= NULL
;
377 pInfo
->pConditionSet
= NULL
;
379 pInfo
->pLinesAttr
= NULL
;
380 pInfo
->mpTLBRLine
= NULL
;
381 pInfo
->mpBLTRLine
= NULL
;
383 pInfo
->pShadowAttr
= pDefShadow
;
384 pInfo
->pHShadowOrigin
= NULL
;
385 pInfo
->pVShadowOrigin
= NULL
;
389 for (nArrCol
=nCol2
+3; nArrCol
<=nRotMax
+2; nArrCol
++) // Add remaining widths
394 if (!ColHidden(nX
, nTab
))
396 sal_uInt16 nThisWidth
= (sal_uInt16
) (GetColWidth( nX
, nTab
) * fColScale
);
400 pRowInfo
[0].pCellInfo
[nArrCol
].nWidth
= nThisWidth
;
405 ScConditionalFormatList
* pCondFormList
= GetCondFormList(nTab
);
407 pCondFormList
->startRendering();
409 for (nArrCol
=0; nArrCol
<=nCol2
+2; nArrCol
++) // left & right + 1
411 nX
= (nArrCol
>0) ? nArrCol
-1 : MAXCOL
+1; // negative -> invalid
415 // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
416 // will disturb the output
418 // TODO: Optimize this loop.
419 if (!ColHidden(nX
, nTab
))
421 sal_uInt16 nThisWidth
= (sal_uInt16
) (GetColWidth( nX
, nTab
) * fColScale
);
425 pRowInfo
[0].pCellInfo
[nArrCol
].nWidth
= nThisWidth
; //TODO: this should be enough
427 ScColumn
* pThisCol
= &maTabs
[nTab
]->aCol
[nX
]; // Column data
430 // Iterate between rows nY1 and nY2 and pick up non-empty
431 // cells that are not hidden.
432 RowInfoFiller
aFunc(*this, nTab
, pRowInfo
, nArrCol
, nArrRow
);
433 sc::ParseAllNonEmpty(
434 pThisCol
->maCells
.begin(), pThisCol
->maCells
, nRow1
, nRow2
, aFunc
);
436 if (nX
+1 >= nCol1
) // Attribute/Blockmark from nX1-1
438 ScAttrArray
* pThisAttrArr
= pThisCol
->pAttrArray
; // Attribute
441 const ScPatternAttr
* pPattern
;
442 SCROW nCurRow
=nRow1
; // single rows
444 --nCurRow
; // 1 more on top
447 nThisRow
=nCurRow
; // end of range
449 (void) pThisAttrArr
->Search( nCurRow
, nIndex
);
453 nThisRow
=pThisAttrArr
->pData
[nIndex
].nRow
; // End of range
454 pPattern
=pThisAttrArr
->pData
[nIndex
].pPattern
;
456 const SvxBrushItem
* pBackground
= static_cast<const SvxBrushItem
*>(
457 &pPattern
->GetItem(ATTR_BACKGROUND
));
458 const SvxBoxItem
* pLinesAttr
= static_cast<const SvxBoxItem
*>(
459 &pPattern
->GetItem(ATTR_BORDER
));
461 const SvxLineItem
* pTLBRLine
= static_cast< const SvxLineItem
* >(
462 &pPattern
->GetItem( ATTR_BORDER_TLBR
) );
463 const SvxLineItem
* pBLTRLine
= static_cast< const SvxLineItem
* >(
464 &pPattern
->GetItem( ATTR_BORDER_BLTR
) );
466 const SvxShadowItem
* pShadowAttr
= static_cast<const SvxShadowItem
*>(
467 &pPattern
->GetItem(ATTR_SHADOW
));
468 if (pShadowAttr
!= pDefShadow
)
471 const ScMergeAttr
* pMergeAttr
= static_cast<const ScMergeAttr
*>(
472 &pPattern
->GetItem(ATTR_MERGE
));
473 bool bMerged
= ( pMergeAttr
!= pDefMerge
&& *pMergeAttr
!= *pDefMerge
);
474 sal_uInt16 nOverlap
= static_cast<const ScMergeFlagAttr
*>( &pPattern
->GetItemSet().
475 Get(ATTR_MERGE_FLAG
))->GetValue();
476 bool bHOverlapped
= ((nOverlap
& SC_MF_HOR
) != 0);
477 bool bVOverlapped
= ((nOverlap
& SC_MF_VER
) != 0);
478 bool bAutoFilter
= ((nOverlap
& SC_MF_AUTO
) != 0);
479 bool bPivotButton
= ((nOverlap
& SC_MF_BUTTON
) != 0);
480 bool bScenario
= ((nOverlap
& SC_MF_SCENARIO
) != 0);
481 bool bPivotPopupButton
= ((nOverlap
& SC_MF_BUTTON_POPUP
) != 0);
482 bool bFilterActive
= ((nOverlap
& SC_MF_HIDDEN_MEMBER
) != 0);
483 if (bMerged
||bHOverlapped
||bVOverlapped
)
484 bAnyMerged
= true; // internal
486 bool bHidden
, bHideFormula
;
489 const ScProtectionAttr
& rProtAttr
= static_cast<const ScProtectionAttr
&>(
490 pPattern
->GetItem(ATTR_PROTECTION
));
491 bHidden
= rProtAttr
.GetHideCell();
492 bHideFormula
= rProtAttr
.GetHideFormula();
495 bHidden
= bHideFormula
= false;
497 const std::vector
<sal_uInt32
>& rCondFormats
= static_cast<const ScCondFormatItem
&>(pPattern
->GetItem(ATTR_CONDITIONAL
)).GetCondFormatData();
498 bool bContainsCondFormat
= !rCondFormats
.empty();
502 SCROW nLastHiddenRow
= -1;
503 bool bRowHidden
= RowHidden(nCurRow
, nTab
, NULL
, &nLastHiddenRow
);
504 if ( nArrRow
==0 || !bRowHidden
)
506 if ( GetPreviewCellStyle( nX
, nCurRow
, nTab
) != NULL
)
508 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrRow
];
509 if (pBackground
!= pDefBackground
) // Column background == Default ?
510 pThisRowInfo
->bEmptyBack
= false;
511 if (bContainsCondFormat
)
512 pThisRowInfo
->bEmptyBack
= false;
514 pThisRowInfo
->bAutoFilter
= true;
515 if (bPivotButton
|| bPivotPopupButton
)
516 pThisRowInfo
->bPivotButton
= true;
518 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrCol
];
519 pInfo
->pBackground
= pBackground
;
520 pInfo
->pPatternAttr
= pPattern
;
521 pInfo
->bMerged
= bMerged
;
522 pInfo
->bHOverlapped
= bHOverlapped
;
523 pInfo
->bVOverlapped
= bVOverlapped
;
524 pInfo
->bAutoFilter
= bAutoFilter
;
525 pInfo
->bPivotButton
= bPivotButton
;
526 pInfo
->bPivotPopupButton
= bPivotPopupButton
;
527 pInfo
->bFilterActive
= bFilterActive
;
528 pInfo
->pLinesAttr
= pLinesAttr
;
529 pInfo
->mpTLBRLine
= pTLBRLine
;
530 pInfo
->mpBLTRLine
= pBLTRLine
;
531 pInfo
->pShadowAttr
= pShadowAttr
;
532 // nWidth is no longer set individually
536 pInfo
->pBackground
= ScGlobal::GetButtonBrushItem();
537 pThisRowInfo
->bEmptyBack
= false;
540 if ( bContainsCondFormat
)
543 for(std::vector
<sal_uInt32
>::const_iterator itr
= rCondFormats
.begin();
544 itr
!= rCondFormats
.end() && !bFound
; ++itr
)
546 ScConditionalFormat
* pCondForm
= pCondFormList
->GetFormat(*itr
);
550 ScCondFormatData aData
= pCondForm
->GetData(
551 pInfo
->maCell
, ScAddress(nX
, nCurRow
, nTab
));
552 if (!aData
.aStyleName
.isEmpty())
554 SfxStyleSheetBase
* pStyleSheet
=
555 pStlPool
->Find( aData
.aStyleName
, SFX_STYLE_FAMILY_PARA
);
558 //TODO: cache Style-Sets !!!
559 pInfo
->pConditionSet
= &pStyleSheet
->GetItemSet();
560 bAnyCondition
= true;
562 // we need to check already here for protected cells
563 const SfxPoolItem
* pItem
;
564 if ( bTabProtect
&& pInfo
->pConditionSet
->GetItemState( ATTR_PROTECTION
, true, &pItem
) == SfxItemState::SET
)
566 const ScProtectionAttr
* pProtAttr
= static_cast<const ScProtectionAttr
*>(pItem
);
567 bHidden
= pProtAttr
->GetHideCell();
568 bHideFormula
= pProtAttr
->GetHideFormula();
574 // if style is not there, treat like no condition
576 if(aData
.pColorScale
)
578 pInfo
->pColorScale
.reset(aData
.pColorScale
);
584 pInfo
->pDataBar
.reset(aData
.pDataBar
);
589 pInfo
->pIconSet
.reset(aData
.pIconSet
);
595 if (bHidden
|| (bFormulaMode
&& bHideFormula
&& pInfo
->maCell
.meType
== CELLTYPE_FORMULA
))
596 pInfo
->bEmptyCellText
= true;
600 else if (bRowHidden
&& nLastHiddenRow
>= 0)
602 nCurRow
= nLastHiddenRow
;
603 if (nCurRow
> nThisRow
)
608 while (nCurRow
<= nThisRow
&& nCurRow
<= nYExtra
);
611 while ( nIndex
< pThisAttrArr
->nCount
&& nThisRow
< nYExtra
);
613 if (pMarkData
&& pMarkData
->IsMultiMarked())
616 const ScMarkArray
* pThisMarkArr
= pMarkData
->GetArray()+nX
;
618 nCurRow
= nRow1
; // single rows
619 nThisRow
= nRow1
; // End of range
621 if ( pThisMarkArr
->Search( nRow1
, nIndex
) )
625 nThisRow
=pThisMarkArr
->pData
[nIndex
].nRow
; // End of range
626 const bool bThisMarked
=pThisMarkArr
->pData
[nIndex
].bMarked
;
630 if ( !RowHidden( nCurRow
,nTab
) )
634 bool bSkip
= bSkipMarks
&&
635 nX
>= nBlockStartX
&&
637 nCurRow
>= nBlockStartY
&&
638 nCurRow
<= nBlockEndY
;
641 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrRow
];
642 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrCol
];
643 pInfo
->bMarked
= true;
650 while (nCurRow
<= nThisRow
&& nCurRow
<= nRow2
);
653 while ( nIndex
< pThisMarkArr
->nCount
&& nThisRow
< nRow2
);
657 else // columns in front
659 for (nArrRow
=1; nArrRow
+1<nArrCount
; nArrRow
++)
661 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrRow
];
662 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrCol
];
664 pInfo
->nWidth
= nThisWidth
; //TODO: or check only 0 ??
670 pRowInfo
[0].pCellInfo
[nArrCol
].nWidth
= STD_COL_WIDTH
;
671 // STD_COL_WIDTH farthest to the left and right is needed for DrawExtraShadow
675 pCondFormList
->endRendering();
677 // bedingte Formatierung auswerten
678 ::boost::ptr_vector
<ScPatternAttr
> aAltPatterns
;
679 // favour preview over condition
680 if (bAnyCondition
|| bAnyPreview
)
682 for (nArrRow
=0; nArrRow
<nArrCount
; nArrRow
++)
684 for (nArrCol
=nCol1
; nArrCol
<=nCol2
+2; nArrCol
++) // 1 more left and right
686 CellInfo
* pInfo
= &pRowInfo
[nArrRow
].pCellInfo
[nArrCol
];
687 SCCOL nCol
= (nArrCol
>0) ? nArrCol
-1 : MAXCOL
+1;
688 ScPatternAttr
* pModifiedPatt
= NULL
;
690 if ( ValidCol(nCol
) && pRowInfo
[nArrRow
].nRowNo
<= MAXROW
)
692 if ( ScStyleSheet
* pPreviewStyle
= GetPreviewCellStyle( nCol
, pRowInfo
[nArrRow
].nRowNo
, nTab
) )
694 aAltPatterns
.push_back( new ScPatternAttr( *pInfo
->pPatternAttr
) );
695 pModifiedPatt
= &aAltPatterns
.back();
696 pModifiedPatt
->SetStyleSheet( pPreviewStyle
);
699 // favour preview over condition
700 const SfxItemSet
* pCondSet
= pModifiedPatt
? &pModifiedPatt
->GetItemSet() : pInfo
->pConditionSet
;
704 const SfxPoolItem
* pItem
;
707 if ( pCondSet
->GetItemState( ATTR_BACKGROUND
, true, &pItem
) == SfxItemState::SET
)
709 pInfo
->pBackground
= static_cast<const SvxBrushItem
*>(pItem
);
710 pRowInfo
[nArrRow
].bEmptyBack
= false;
714 if ( pCondSet
->GetItemState( ATTR_BORDER
, true, &pItem
) == SfxItemState::SET
)
715 pInfo
->pLinesAttr
= static_cast<const SvxBoxItem
*>(pItem
);
717 if ( pCondSet
->GetItemState( ATTR_BORDER_TLBR
, true, &pItem
) == SfxItemState::SET
)
718 pInfo
->mpTLBRLine
= static_cast< const SvxLineItem
* >( pItem
);
719 if ( pCondSet
->GetItemState( ATTR_BORDER_BLTR
, true, &pItem
) == SfxItemState::SET
)
720 pInfo
->mpBLTRLine
= static_cast< const SvxLineItem
* >( pItem
);
723 if ( pCondSet
->GetItemState( ATTR_SHADOW
, true, &pItem
) == SfxItemState::SET
)
725 pInfo
->pShadowAttr
= static_cast<const SvxShadowItem
*>(pItem
);
729 if( bAnyCondition
&& pInfo
->pColorScale
)
731 pRowInfo
[nArrRow
].bEmptyBack
= false;
732 pInfo
->pBackground
= new SvxBrushItem(*pInfo
->pColorScale
, ATTR_BACKGROUND
);
738 // End conditional formatting
740 // Adjust data from merged cells
744 for (nArrRow
=0; nArrRow
<nArrCount
; nArrRow
++)
746 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrRow
];
747 nSignedY
= nArrRow
? pThisRowInfo
->nRowNo
: ((SCsROW
)nRow1
)-1;
749 for (nArrCol
=nCol1
; nArrCol
<=nCol2
+2; nArrCol
++) // 1 more left and right
751 SCsCOL nSignedX
= ((SCsCOL
) nArrCol
) - 1;
752 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nArrCol
];
754 if (pInfo
->bMerged
|| pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
760 lcl_GetMergeRange( nSignedX
,nSignedY
, nArrRow
, this,pRowInfo
, nCol1
,nRow1
,nCol2
,nRow2
,nTab
,
761 nStartX
,nStartY
, nEndX
,nEndY
);
762 const ScPatternAttr
* pStartPattern
= GetPattern( nStartX
,nStartY
,nTab
);
763 const SfxItemSet
* pStartCond
= GetCondResult( nStartX
,nStartY
,nTab
);
764 const SfxPoolItem
* pItem
;
766 // Copy Background (or in output.cxx)
768 if ( !pStartCond
|| pStartCond
->
769 GetItemState(ATTR_BACKGROUND
,true,&pItem
) != SfxItemState::SET
)
770 pItem
= &pStartPattern
->GetItem(ATTR_BACKGROUND
);
771 pInfo
->pBackground
= static_cast<const SvxBrushItem
*>(pItem
);
772 pRowInfo
[nArrRow
].bEmptyBack
= false;
776 if ( !pStartCond
|| pStartCond
->
777 GetItemState(ATTR_SHADOW
,true,&pItem
) != SfxItemState::SET
)
778 pItem
= &pStartPattern
->GetItem(ATTR_SHADOW
);
779 pInfo
->pShadowAttr
= static_cast<const SvxShadowItem
*>(pItem
);
780 if (pInfo
->pShadowAttr
!= pDefShadow
)
783 // Block marks - again with the original merge values
785 bool bCellMarked
= false;
787 bCellMarked
= ( nStartX
>= (SCsCOL
) nBlockStartX
788 && nStartX
<= (SCsCOL
) nBlockEndX
789 && nStartY
>= (SCsROW
) nBlockStartY
790 && nStartY
<= (SCsROW
) nBlockEndY
);
791 if (pMarkData
&& pMarkData
->IsMultiMarked() && !bCellMarked
)
793 const ScMarkArray
* pThisMarkArr
= pMarkData
->GetArray()+nStartX
;
795 if ( pThisMarkArr
->Search( nStartY
, nIndex
) )
796 bCellMarked
=pThisMarkArr
->pData
[nIndex
].bMarked
;
799 pInfo
->bMarked
= bCellMarked
;
805 if (bAnyShadow
) // distribute Shadow
807 for (nArrRow
=0; nArrRow
<nArrCount
; nArrRow
++)
809 bool bTop
= ( nArrRow
== 0 );
810 bool bBottom
= ( nArrRow
+1 == nArrCount
);
812 for (nArrCol
=nCol1
; nArrCol
<=nCol2
+2; nArrCol
++) // 1 more left and right
814 bool bLeft
= ( nArrCol
== nCol1
);
815 bool bRight
= ( nArrCol
== nCol2
+2 );
817 CellInfo
* pInfo
= &pRowInfo
[nArrRow
].pCellInfo
[nArrCol
];
818 const SvxShadowItem
* pThisAttr
= pInfo
->pShadowAttr
;
819 SvxShadowLocation eLoc
= pThisAttr
? pThisAttr
->GetLocation() : SVX_SHADOW_NONE
;
820 if (eLoc
!= SVX_SHADOW_NONE
)
822 // or test on != eLoc
827 while ( nArrCol
+nDxPos
< nCol2
+2 && pRowInfo
[0].pCellInfo
[nArrCol
+nDxPos
].nWidth
== 0 )
829 while ( nArrCol
+nDxNeg
> nCol1
&& pRowInfo
[0].pCellInfo
[nArrCol
+nDxNeg
].nWidth
== 0 )
832 bool bLeftDiff
= !bLeft
&&
833 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
+nDxNeg
].pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
834 bool bRightDiff
= !bRight
&&
835 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
+nDxPos
].pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
836 bool bTopDiff
= !bTop
&&
837 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
].pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
838 bool bBottomDiff
= !bBottom
&&
839 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
].pShadowAttr
->GetLocation() == SVX_SHADOW_NONE
;
845 case SVX_SHADOW_BOTTOMRIGHT
: eLoc
= SVX_SHADOW_BOTTOMLEFT
; break;
846 case SVX_SHADOW_BOTTOMLEFT
: eLoc
= SVX_SHADOW_BOTTOMRIGHT
; break;
847 case SVX_SHADOW_TOPRIGHT
: eLoc
= SVX_SHADOW_TOPLEFT
; break;
848 case SVX_SHADOW_TOPLEFT
: eLoc
= SVX_SHADOW_TOPRIGHT
; break;
851 // added to avoid warnings
858 case SVX_SHADOW_BOTTOMRIGHT
:
861 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
].pHShadowOrigin
= pThisAttr
;
862 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
].eHShadowPart
=
863 bLeftDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
867 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
+1].pVShadowOrigin
= pThisAttr
;
868 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
+1].eVShadowPart
=
869 bTopDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
871 if (bBottomDiff
&& bRightDiff
)
873 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
+1].pHShadowOrigin
= pThisAttr
;
874 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
+1].eHShadowPart
= SC_SHADOW_CORNER
;
878 case SVX_SHADOW_BOTTOMLEFT
:
881 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
].pHShadowOrigin
= pThisAttr
;
882 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
].eHShadowPart
=
883 bRightDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
887 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
-1].pVShadowOrigin
= pThisAttr
;
888 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
-1].eVShadowPart
=
889 bTopDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
891 if (bBottomDiff
&& bLeftDiff
)
893 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
-1].pHShadowOrigin
= pThisAttr
;
894 pRowInfo
[nArrRow
+1].pCellInfo
[nArrCol
-1].eHShadowPart
= SC_SHADOW_CORNER
;
898 case SVX_SHADOW_TOPRIGHT
:
901 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
].pHShadowOrigin
= pThisAttr
;
902 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
].eHShadowPart
=
903 bLeftDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
907 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
+1].pVShadowOrigin
= pThisAttr
;
908 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
+1].eVShadowPart
=
909 bBottomDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
911 if (bTopDiff
&& bRightDiff
)
913 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
+1].pHShadowOrigin
= pThisAttr
;
914 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
+1].eHShadowPart
= SC_SHADOW_CORNER
;
918 case SVX_SHADOW_TOPLEFT
:
921 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
].pHShadowOrigin
= pThisAttr
;
922 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
].eHShadowPart
=
923 bRightDiff
? SC_SHADOW_HSTART
: SC_SHADOW_HORIZ
;
927 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
-1].pVShadowOrigin
= pThisAttr
;
928 pRowInfo
[nArrRow
].pCellInfo
[nArrCol
-1].eVShadowPart
=
929 bBottomDiff
? SC_SHADOW_VSTART
: SC_SHADOW_VERT
;
931 if (bTopDiff
&& bLeftDiff
)
933 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
-1].pHShadowOrigin
= pThisAttr
;
934 pRowInfo
[nArrRow
-1].pCellInfo
[nArrCol
-1].eHShadowPart
= SC_SHADOW_CORNER
;
939 OSL_FAIL("wrong Shadow-Enum");
946 rTabInfo
.mnArrCount
= sal::static_int_cast
<sal_uInt16
>(nArrCount
);
947 rTabInfo
.mbPageMode
= bPageMode
;
949 // *** create the frame border array ***
951 // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
952 // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
954 size_t nColCount
= nCol2
- nCol1
+ 3;
955 size_t nRowCount
= nArrCount
;
957 svx::frame::Array
& rArray
= rTabInfo
.maArray
;
958 rArray
.Initialize( nColCount
, nRowCount
);
959 rArray
.SetUseDiagDoubleClipping( false );
961 for( size_t nRow
= 0; nRow
< nRowCount
; ++nRow
)
963 sal_uInt16 nCellInfoY
= static_cast< sal_uInt16
>( nRow
);
964 RowInfo
& rThisRowInfo
= pRowInfo
[ nCellInfoY
];
966 for( size_t nCol
= 0; nCol
< nColCount
; ++nCol
)
968 sal_uInt16 nCellInfoX
= static_cast< sal_uInt16
>( nCol
+ nCol1
);
969 const CellInfo
& rInfo
= rThisRowInfo
.pCellInfo
[ nCellInfoX
];
971 const SvxBoxItem
* pBox
= rInfo
.pLinesAttr
;
972 const SvxLineItem
* pTLBR
= rInfo
.mpTLBRLine
;
973 const SvxLineItem
* pBLTR
= rInfo
.mpBLTRLine
;
975 size_t nFirstCol
= nCol
;
976 size_t nFirstRow
= nRow
;
978 // *** merged cells *** -------------------------------------------
980 if( !rArray
.IsMerged( nCol
, nRow
) && (rInfo
.bMerged
|| rInfo
.bHOverlapped
|| rInfo
.bVOverlapped
) )
982 // *** insert merged range in svx::frame::Array ***
984 /* #i69369# top-left cell of a merged range may be located in
985 a hidden column or row. Use lcl_GetMergeRange() to find the
986 complete merged range, then calculate dimensions and
987 document position of the visible range. */
989 // note: document columns are always one less than CellInfoX coords
990 // note: document rows must be looked up in RowInfo structs
992 // current column and row in document coordinates
993 SCCOL nCurrDocCol
= static_cast< SCCOL
>( nCellInfoX
- 1 );
994 SCROW nCurrDocRow
= static_cast< SCROW
>( (nCellInfoY
> 0) ? rThisRowInfo
.nRowNo
: (nRow1
- 1) );
996 // find entire merged range in document, returns signed document coordinates
997 SCsCOL nFirstRealDocColS
, nLastRealDocColS
;
998 SCsROW nFirstRealDocRowS
, nLastRealDocRowS
;
999 lcl_GetMergeRange( static_cast< SCsCOL
>( nCurrDocCol
), static_cast< SCsROW
>( nCurrDocRow
),
1000 nCellInfoY
, this, pRowInfo
, nCol1
,nRow1
,nCol2
,nRow2
,nTab
,
1001 nFirstRealDocColS
, nFirstRealDocRowS
, nLastRealDocColS
, nLastRealDocRowS
);
1003 // *complete* merged range in document coordinates
1004 SCCOL nFirstRealDocCol
= static_cast< SCCOL
>( nFirstRealDocColS
);
1005 SCROW nFirstRealDocRow
= static_cast< SCROW
>( nFirstRealDocRowS
);
1006 SCCOL nLastRealDocCol
= static_cast< SCCOL
>( nLastRealDocColS
);
1007 SCROW nLastRealDocRow
= static_cast< SCROW
>( nLastRealDocRowS
);
1009 // first visible column (nX1-1 is first processed document column)
1010 SCCOL nFirstDocCol
= (nCol1
> 0) ? ::std::max
< SCCOL
>( nFirstRealDocCol
, nCol1
- 1 ) : nFirstRealDocCol
;
1011 sal_uInt16 nFirstCellInfoX
= static_cast< sal_uInt16
>( nFirstDocCol
+ 1 );
1012 nFirstCol
= static_cast< size_t >( nFirstCellInfoX
- nCol1
);
1014 // last visible column (nX2+1 is last processed document column)
1015 SCCOL nLastDocCol
= (nCol2
< MAXCOL
) ? ::std::min
< SCCOL
>( nLastRealDocCol
, nCol2
+ 1 ) : nLastRealDocCol
;
1016 sal_uInt16 nLastCellInfoX
= static_cast< sal_uInt16
>( nLastDocCol
+ 1 );
1017 size_t nLastCol
= static_cast< size_t >( nLastCellInfoX
- nCol1
);
1019 // first visible row
1020 sal_uInt16 nFirstCellInfoY
= nCellInfoY
;
1021 while( ((nFirstCellInfoY
> 1) && (pRowInfo
[ nFirstCellInfoY
- 1 ].nRowNo
>= nFirstRealDocRow
)) ||
1022 ((nFirstCellInfoY
== 1) && (static_cast< SCROW
>( nRow1
- 1 ) >= nFirstRealDocRow
)) )
1024 SCROW nFirstDocRow
= (nFirstCellInfoY
> 0) ? pRowInfo
[ nFirstCellInfoY
].nRowNo
: static_cast< SCROW
>( nRow1
- 1 );
1025 nFirstRow
= static_cast< size_t >( nFirstCellInfoY
);
1028 sal_uInt16 nLastCellInfoY
= nCellInfoY
;
1029 while( (sal::static_int_cast
<SCSIZE
>(nLastCellInfoY
+ 1) < nArrCount
) &&
1030 (pRowInfo
[ nLastCellInfoY
+ 1 ].nRowNo
<= nLastRealDocRow
) )
1032 SCROW nLastDocRow
= (nLastCellInfoY
> 0) ? pRowInfo
[ nLastCellInfoY
].nRowNo
: static_cast< SCROW
>( nRow1
- 1 );
1033 size_t nLastRow
= static_cast< size_t >( nLastCellInfoY
);
1035 // insert merged range
1036 rArray
.SetMergedRange( nFirstCol
, nFirstRow
, nLastCol
, nLastRow
);
1038 // *** find additional size not included in svx::frame::Array ***
1040 // additional space before first column
1041 if( nFirstCol
== 0 )
1044 for( SCCOL nDocCol
= nFirstRealDocCol
; nDocCol
< nFirstDocCol
; ++nDocCol
)
1045 nSize
+= std::max( static_cast< long >( GetColWidth( nDocCol
, nTab
) * fColScale
), 1L );
1046 rArray
.SetAddMergedLeftSize( nCol
, nRow
, nSize
);
1048 // additional space after last column
1049 if( nLastCol
+ 1 == nColCount
)
1052 for( SCCOL nDocCol
= nLastDocCol
+ 1; nDocCol
<= nLastRealDocCol
; ++nDocCol
)
1053 nSize
+= std::max( static_cast< long >( GetColWidth( nDocCol
, nTab
) * fColScale
), 1L );
1054 rArray
.SetAddMergedRightSize( nCol
, nRow
, nSize
);
1056 // additional space above first row
1057 if( nFirstRow
== 0 )
1060 for( SCROW nDocRow
= nFirstRealDocRow
; nDocRow
< nFirstDocRow
; ++nDocRow
)
1061 nSize
+= std::max( static_cast< long >( GetRowHeight( nDocRow
, nTab
) * fRowScale
), 1L );
1062 rArray
.SetAddMergedTopSize( nCol
, nRow
, nSize
);
1064 // additional space beyond last row
1065 if( nLastRow
+ 1 == nRowCount
)
1068 for( SCROW nDocRow
= nLastDocRow
+ 1; nDocRow
<= nLastRealDocRow
; ++nDocRow
)
1069 nSize
+= std::max( static_cast< long >( GetRowHeight( nDocRow
, nTab
) * fRowScale
), 1L );
1070 rArray
.SetAddMergedBottomSize( nCol
, nRow
, nSize
);
1073 // *** use line attributes from real origin cell ***
1075 if( (nFirstRealDocCol
!= nCurrDocCol
) || (nFirstRealDocRow
!= nCurrDocRow
) )
1077 if( const ScPatternAttr
* pPattern
= GetPattern( nFirstRealDocCol
, nFirstRealDocRow
, nTab
) )
1079 const SfxItemSet
* pCond
= GetCondResult( nFirstRealDocCol
, nFirstRealDocRow
, nTab
);
1080 pBox
= static_cast< const SvxBoxItem
* >( &pPattern
->GetItem( ATTR_BORDER
, pCond
) );
1081 pTLBR
= static_cast< const SvxLineItem
* >( &pPattern
->GetItem( ATTR_BORDER_TLBR
, pCond
) );
1082 pBLTR
= static_cast< const SvxLineItem
* >( &pPattern
->GetItem( ATTR_BORDER_BLTR
, pCond
) );
1092 // *** borders *** ------------------------------------------------
1096 rArray
.SetCellStyleLeft( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetLeft(), fColScale
) );
1097 rArray
.SetCellStyleRight( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetRight(), fColScale
) );
1098 rArray
.SetCellStyleTop( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetTop(), fRowScale
) );
1099 rArray
.SetCellStyleBottom( nFirstCol
, nFirstRow
, svx::frame::Style( pBox
->GetBottom(), fRowScale
) );
1103 rArray
.SetCellStyleTLBR( nFirstCol
, nFirstRow
, svx::frame::Style( pTLBR
->GetLine(), fRowScale
) );
1105 rArray
.SetCellStyleBLTR( nFirstCol
, nFirstRow
, svx::frame::Style( pBLTR
->GetLine(), fRowScale
) );
1109 /* Mirror the entire frame array.
1110 1st param = Mirror the vertical double line styles as well.
1111 2nd param = Do not swap diagonal lines.
1114 rArray
.MirrorSelfX( true, false );
1117 ScTableInfo::ScTableInfo()
1118 : mpRowInfo(new RowInfo
[ROWINFO_MAX
])
1122 memset(mpRowInfo
, 0, ROWINFO_MAX
*sizeof(RowInfo
));
1125 ScTableInfo::~ScTableInfo()
1127 for( sal_uInt16 nIdx
= 0; nIdx
< ROWINFO_MAX
; ++nIdx
)
1128 delete [] mpRowInfo
[ nIdx
].pCellInfo
;
1129 delete [] mpRowInfo
;
1132 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */