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