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