Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "scitems.hxx"
30 : : #include <editeng/boxitem.hxx>
31 : : #include <editeng/bolnitem.hxx>
32 : : #include <editeng/editdata.hxx> // can be removed if table has a bLayoutRTL flag
33 : : #include <editeng/shaditem.hxx>
34 : : #include <editeng/brshitem.hxx>
35 : :
36 : : #include "fillinfo.hxx"
37 : : #include "document.hxx"
38 : : #include "cell.hxx"
39 : : #include "table.hxx"
40 : : #include "attrib.hxx"
41 : : #include "attarray.hxx"
42 : : #include "markarr.hxx"
43 : : #include "markdata.hxx"
44 : : #include "patattr.hxx"
45 : : #include "poolhelp.hxx"
46 : : #include "docpool.hxx"
47 : : #include "conditio.hxx"
48 : : #include "colorscale.hxx"
49 : : #include "stlpool.hxx"
50 : :
51 : : // -----------------------------------------------------------------------
52 : :
53 : : const sal_uInt16 ROWINFO_MAX = 1024;
54 : :
55 : :
56 : : enum FillInfoLinePos
57 : : {
58 : : FILP_TOP,
59 : : FILP_BOTTOM,
60 : : FILP_LEFT,
61 : : FILP_RIGHT
62 : : };
63 : :
64 : :
65 : : inline const ::editeng::SvxBorderLine* GetNullOrLine( const SvxBoxItem* pBox, FillInfoLinePos eWhich )
66 : : {
67 : : if (pBox)
68 : : {
69 : : if (eWhich==FILP_TOP)
70 : : return pBox->GetTop();
71 : : else if (eWhich==FILP_BOTTOM)
72 : : return pBox->GetBottom();
73 : : else if (eWhich==FILP_LEFT)
74 : : return pBox->GetLeft();
75 : : else
76 : : return pBox->GetRight();
77 : : }
78 : : else
79 : : return NULL;
80 : : }
81 : :
82 : : // aehnlich wie in output.cxx
83 : :
84 : 81 : void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
85 : : ScDocument* pDoc, RowInfo* pRowInfo,
86 : : SCCOL nX1, SCROW nY1, SCCOL /* nX2 */, SCROW /* nY2 */, SCTAB nTab,
87 : : SCsCOL& rStartX, SCsROW& rStartY, SCsCOL& rEndX, SCsROW& rEndY )
88 : : {
89 : 81 : CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
90 : :
91 : 81 : rStartX = nX;
92 : 81 : rStartY = nY;
93 : 81 : bool bHOver = pInfo->bHOverlapped;
94 : 81 : bool bVOver = pInfo->bVOverlapped;
95 : : SCCOL nLastCol;
96 : : SCROW nLastRow;
97 : :
98 [ + + ]: 191 : while (bHOver) // nY konstant
99 : : {
100 : 110 : --rStartX;
101 [ + - ][ + - ]: 110 : if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol))
[ + - ][ + - ]
102 : : {
103 : 110 : bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
104 : 110 : bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
105 : : }
106 : : else
107 : : {
108 : : sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
109 [ # # ]: 0 : rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
110 : 0 : bHOver = ((nOverlap & SC_MF_HOR) != 0);
111 : 0 : bVOver = ((nOverlap & SC_MF_VER) != 0);
112 : : }
113 : : }
114 : :
115 [ + + ]: 211 : while (bVOver)
116 : : {
117 : 130 : --rStartY;
118 : :
119 [ + - ]: 130 : if (nArrY>0)
120 : 130 : --nArrY; // lokale Kopie !
121 : :
122 [ + - ][ + - ]: 390 : if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
[ + - ][ + - ]
[ + - ][ + - ]
123 [ + - ]: 130 : !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
124 [ + - ]: 130 : !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
125 : 130 : (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
126 : : {
127 : 130 : bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
128 : 130 : bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
129 : : }
130 : : else
131 : : {
132 : : sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
133 [ # # ]: 0 : rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
134 : 0 : bHOver = ((nOverlap & SC_MF_HOR) != 0);
135 : 0 : bVOver = ((nOverlap & SC_MF_VER) != 0);
136 : : }
137 : : }
138 : :
139 : : const ScMergeAttr* pMerge;
140 [ + - ][ + - ]: 243 : if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
[ + - ][ + - ]
[ + - ][ + - ]
141 [ + - ]: 81 : !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
142 [ + - ]: 81 : !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
143 : 81 : (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
144 : : {
145 : 81 : pMerge = (const ScMergeAttr*) &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
146 [ + - ]: 81 : GetItem(ATTR_MERGE);
147 : : }
148 : : else
149 [ # # ]: 0 : pMerge = (const ScMergeAttr*) pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE);
150 : :
151 : 81 : rEndX = rStartX + pMerge->GetColMerge() - 1;
152 : 81 : rEndY = rStartY + pMerge->GetRowMerge() - 1;
153 : 81 : }
154 : :
155 : : #define CELLINFO(x,y) pRowInfo[nArrY+y].pCellInfo[nArrX+x]
156 : :
157 : 5170 : void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
158 : : SCTAB nTab, double nScaleX, double nScaleY,
159 : : bool bPageMode, bool bFormulaMode, const ScMarkData* pMarkData )
160 : : {
161 : : OSL_ENSURE( maTabs[nTab], "Tabelle existiert nicht" );
162 : :
163 [ + - ]: 5170 : bool bLayoutRTL = IsLayoutRTL( nTab );
164 : :
165 : 5170 : ScDocumentPool* pPool = xPoolHelper->GetDocPool();
166 [ + - ]: 5170 : ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool();
167 : :
168 : 5170 : RowInfo* pRowInfo = rTabInfo.mpRowInfo;
169 : :
170 : : const SvxBrushItem* pDefBackground =
171 [ + - ]: 5170 : (const SvxBrushItem*) &pPool->GetDefaultItem( ATTR_BACKGROUND );
172 : : const ScMergeAttr* pDefMerge =
173 [ + - ]: 5170 : (const ScMergeAttr*) &pPool->GetDefaultItem( ATTR_MERGE );
174 : : const SvxShadowItem* pDefShadow =
175 [ + - ]: 5170 : (const SvxShadowItem*) &pPool->GetDefaultItem( ATTR_SHADOW );
176 : :
177 : : SCROW nThisRow;
178 : : SCCOL nX;
179 : : SCROW nY;
180 : : SCsROW nSignedY;
181 : : SCCOL nArrX;
182 : : SCSIZE nArrY;
183 : : SCSIZE nArrCount;
184 : 5170 : bool bAnyMerged = false;
185 : 5170 : bool bAnyShadow = false;
186 : 5170 : bool bAnyCondition = false;
187 : :
188 [ + - ]: 5170 : bool bTabProtect = IsTabProtected(nTab);
189 : :
190 : : // fuer Blockmarken von zusammengefassten Zellen mit
191 : : // versteckter erster Zeile / Spalte
192 : 5170 : bool bPaintMarks = false;
193 : 5170 : bool bSkipMarks = false;
194 : 5170 : SCCOL nBlockStartX = 0, nBlockEndX = 0;
195 : 5170 : SCROW nBlockEndY = 0, nBlockStartY = 0;
196 [ + + ][ + + ]: 5170 : if (pMarkData && pMarkData->IsMarked())
[ + + ]
197 : : {
198 : 1 : ScRange aTmpRange;
199 [ + - ]: 1 : pMarkData->GetMarkArea(aTmpRange);
200 [ + - ][ + - ]: 1 : if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() )
[ + - ]
201 : : {
202 : 1 : nBlockStartX = aTmpRange.aStart.Col();
203 : 1 : nBlockStartY = aTmpRange.aStart.Row();
204 : 1 : nBlockEndX = aTmpRange.aEnd.Col();
205 : 1 : nBlockEndY = aTmpRange.aEnd.Row();
206 [ + - ]: 1 : ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab ); //? noetig ?
207 [ - + ]: 1 : if (pMarkData->IsMarkNegative())
208 : 0 : bSkipMarks = true;
209 : : else
210 : 1 : bPaintMarks = true;
211 : : }
212 : : }
213 : :
214 : : // zuerst nur die Eintraege fuer die ganze Spalte
215 : :
216 : 5170 : nArrY=0;
217 : 5170 : SCROW nYExtra = nY2+1;
218 : 5170 : sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight;
219 : 5170 : SCROW nDocHeightEndRow = -1;
220 [ + + ]: 126855 : for (nSignedY=((SCsROW)nY1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
221 : : {
222 [ + + ]: 121685 : if (nSignedY >= 0)
223 : 116804 : nY = (SCROW) nSignedY;
224 : : else
225 : 4881 : nY = MAXROW+1; // ungueltig
226 : :
227 [ + + ]: 121685 : if (nY > nDocHeightEndRow)
228 : : {
229 [ + + ]: 12981 : if (ValidRow(nY))
230 [ + - ]: 8100 : nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
231 : : else
232 : 4881 : nDocHeight = ScGlobal::nStdRowHeight;
233 : : }
234 : :
235 [ + + ][ + + ]: 121685 : if ( nArrY==0 || nDocHeight || nY > MAXROW )
[ - + ]
236 : : {
237 : 121446 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
238 : 121446 : pThisRowInfo->pCellInfo = NULL; // wird unten belegt
239 : :
240 : 121446 : sal_uInt16 nHeight = (sal_uInt16) ( nDocHeight * nScaleY );
241 [ - + ]: 121446 : if (!nHeight)
242 : 0 : nHeight = 1;
243 : :
244 : 121446 : pThisRowInfo->nRowNo = nY; //! Fall < 0 ?
245 : 121446 : pThisRowInfo->nHeight = nHeight;
246 : 121446 : pThisRowInfo->bEmptyBack = true;
247 : 121446 : pThisRowInfo->bEmptyText = true;
248 : 121446 : pThisRowInfo->bChanged = true;
249 : 121446 : pThisRowInfo->bAutoFilter = false;
250 : 121446 : pThisRowInfo->bPushButton = false;
251 : 121446 : pThisRowInfo->nRotMaxCol = SC_ROTMAX_NONE;
252 : :
253 : 121446 : ++nArrY;
254 [ - + ]: 121446 : if (nArrY >= ROWINFO_MAX)
255 : : {
256 : : OSL_FAIL("Zu grosser Bereich bei FillInfo" );
257 : 0 : nYExtra = nSignedY; // Ende
258 : 0 : nY2 = nYExtra - 1; // Bereich anpassen
259 : 121446 : }
260 : : }
261 : : else
262 [ - + ]: 239 : if (nSignedY==(SCsROW) nYExtra) // zusaetzliche Zeile verdeckt ?
263 : 0 : ++nYExtra;
264 : : }
265 : 5170 : nArrCount = nArrY; // incl. Dummys
266 : :
267 : : // rotierter Text...
268 : :
269 : : // Attribut im Dokument ueberhaupt verwendet?
270 : 5170 : bool bAnyItem = false;
271 [ + - ]: 5170 : sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
272 [ + - ]: 5170 : for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
273 [ + - ][ + - ]: 5170 : if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem ))
274 : : {
275 : 5170 : bAnyItem = true;
276 : 5170 : break;
277 : : }
278 : :
279 : 5170 : SCCOL nRotMax = nX2;
280 [ + - ][ + + ]: 10340 : if ( bAnyItem && HasAttrib( 0,nY1,nTab, MAXCOL,nY2+1,nTab,
[ + + ]
281 [ + - ]: 5170 : HASATTR_ROTATE | HASATTR_CONDITIONAL ) )
282 : : {
283 : : //! Conditionals auch bei HASATTR_ROTATE abfragen ????
284 : :
285 : : OSL_ENSURE( nArrCount>2, "nArrCount zu klein" );
286 : : // FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-2, nX1, nX2 );
287 [ + - ]: 532 : FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nX1, nX2 );
288 : : // FindMaxRotCol setzt nRotMaxCol
289 : :
290 [ + + ]: 5134 : for (nArrY=0; nArrY<nArrCount; nArrY++)
291 [ + + ][ - + ]: 4602 : if (pRowInfo[nArrY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrY].nRotMaxCol > nRotMax)
292 : 0 : nRotMax = pRowInfo[nArrY].nRotMaxCol;
293 : : }
294 : :
295 : : // Zell-Infos erst nach dem Test auf gedrehte allozieren
296 : : // bis nRotMax wegen nRotateDir Flag
297 : :
298 [ + + ]: 126616 : for (nArrY=0; nArrY<nArrCount; nArrY++)
299 : : {
300 : 121446 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
301 : 121446 : nY = pThisRowInfo->nRowNo;
302 [ + - ][ + + ]: 1570321 : pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ]; // vom Aufrufer zu loeschen !
303 : :
304 [ + + ]: 1570321 : for (nArrX=0; nArrX<=nRotMax+2; nArrX++) // Zell-Infos vorbelegen
305 : : {
306 [ + + ]: 1448875 : if (nArrX>0)
307 : 1327429 : nX = nArrX-1;
308 : : else
309 : 121446 : nX = MAXCOL+1; // ungueltig
310 : :
311 : 1448875 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
312 : 1448875 : pInfo->bEmptyCellText = true;
313 : 1448875 : pInfo->pCell = NULL;
314 [ + + ]: 1448875 : if (bPaintMarks)
315 : : pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX
316 [ + - ][ + + ]: 348 : && nY >= nBlockStartY && nY <= nBlockEndY );
[ + - ][ + + ]
317 : : else
318 : 1448527 : pInfo->bMarked = false;
319 : 1448875 : pInfo->nWidth = 0;
320 : :
321 : 1448875 : pInfo->nClipMark = SC_CLIPMARK_NONE;
322 : 1448875 : pInfo->bMerged = false;
323 : 1448875 : pInfo->bHOverlapped = false;
324 : 1448875 : pInfo->bVOverlapped = false;
325 : 1448875 : pInfo->bAutoFilter = false;
326 : 1448875 : pInfo->bPushButton = false;
327 : 1448875 : pInfo->bPopupButton = false;
328 : 1448875 : pInfo->bFilterActive = false;
329 : 1448875 : pInfo->nRotateDir = SC_ROTDIR_NONE;
330 : :
331 : 1448875 : pInfo->bPrinted = false; // view-intern
332 : 1448875 : pInfo->bHideGrid = false; // view-intern
333 : 1448875 : pInfo->bEditEngine = false; // view-intern
334 : :
335 : 1448875 : pInfo->pBackground = NULL; //! weglassen?
336 : 1448875 : pInfo->pPatternAttr = NULL;
337 : 1448875 : pInfo->pConditionSet= NULL;
338 : :
339 : 1448875 : pInfo->pLinesAttr = NULL;
340 : 1448875 : pInfo->mpTLBRLine = NULL;
341 : 1448875 : pInfo->mpBLTRLine = NULL;
342 : :
343 : 1448875 : pInfo->pShadowAttr = pDefShadow;
344 : 1448875 : pInfo->pHShadowOrigin = NULL;
345 : 1448875 : pInfo->pVShadowOrigin = NULL;
346 : : }
347 : : }
348 : :
349 [ - + ]: 5170 : for (nArrX=nX2+3; nArrX<=nRotMax+2; nArrX++) // restliche Breiten eintragen
350 : : {
351 : 0 : nX = nArrX-1;
352 [ # # ]: 0 : if ( ValidCol(nX) )
353 : : {
354 [ # # ][ # # ]: 0 : if (!ColHidden(nX, nTab))
355 : : {
356 [ # # ]: 0 : sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * nScaleX);
357 [ # # ]: 0 : if (!nThisWidth)
358 : 0 : nThisWidth = 1;
359 : :
360 : 0 : pRowInfo[0].pCellInfo[nArrX].nWidth = nThisWidth;
361 : : }
362 : : }
363 : : }
364 : :
365 [ + - ]: 5170 : ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
366 [ + + ]: 66364 : for (nArrX=0; nArrX<=nX2+2; nArrX++) // links & rechts + 1
367 : : {
368 [ + + ]: 61194 : nX = (nArrX>0) ? nArrX-1 : MAXCOL+1; // negativ -> ungueltig
369 : :
370 [ + + ]: 61194 : if ( ValidCol(nX) )
371 : : {
372 : : // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
373 : : // will disturb the output
374 : :
375 : : // TODO: Optimize this loop.
376 [ + - ][ + - ]: 56024 : if (!ColHidden(nX, nTab))
377 : : {
378 [ + - ]: 56024 : sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * nScaleX);
379 [ - + ]: 56024 : if (!nThisWidth)
380 : 0 : nThisWidth = 1;
381 : :
382 : 56024 : pRowInfo[0].pCellInfo[nArrX].nWidth = nThisWidth; //! dies sollte reichen
383 : :
384 : 56024 : ScColumn* pThisCol = &maTabs[nTab]->aCol[nX]; // Spalten-Daten
385 : :
386 : 56024 : nArrY = 1;
387 : : SCSIZE nUIndex;
388 : 56024 : bool bHiddenRow = true;
389 : 56024 : SCROW nHiddenEndRow = -1;
390 [ + - ]: 56024 : (void) pThisCol->Search( nY1, nUIndex );
391 [ + + + + ]: 264758 : while ( nUIndex < pThisCol->maItems.size() &&
[ + + ]
392 : 104855 : (nThisRow=pThisCol->maItems[nUIndex].nRow) <= nY2 )
393 : : {
394 [ + + ]: 103879 : if (nThisRow > nHiddenEndRow)
395 [ + - ]: 24145 : bHiddenRow = RowHidden( nThisRow, nTab, NULL, &nHiddenEndRow);
396 [ + + ]: 103879 : if ( !bHiddenRow )
397 : : {
398 [ + + ]: 122061 : while ( pRowInfo[nArrY].nRowNo < nThisRow )
399 : 18543 : ++nArrY;
400 : : OSL_ENSURE( pRowInfo[nArrY].nRowNo == nThisRow, "Zeile nicht gefunden in FillInfo" );
401 : :
402 : 103518 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
403 : 103518 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
404 : 103518 : pInfo->pCell = pThisCol->maItems[nUIndex].pCell;
405 [ + + ]: 103518 : if (pInfo->pCell->GetCellType() != CELLTYPE_NOTE)
406 : : {
407 : 103260 : pThisRowInfo->bEmptyText = false; // Zeile nicht leer
408 : 103260 : pInfo->bEmptyCellText = false; // Zelle nicht leer
409 : : }
410 : 103518 : ++nArrY;
411 : : }
412 : 103879 : ++nUIndex;
413 : : }
414 : :
415 [ + + ]: 56024 : if (nX+1 >= nX1) // Attribute/Blockmarken ab nX1-1
416 : : {
417 : 55392 : ScAttrArray* pThisAttrArr = pThisCol->pAttrArray; // Attribute
418 : :
419 : 55392 : nArrY = 0;
420 : : const ScPatternAttr* pPattern;
421 : 55392 : SCROW nCurRow=nY1; // einzelne Zeile
422 [ + + ]: 55392 : if (nCurRow>0)
423 : 2766 : --nCurRow; // oben 1 mehr
424 : : else
425 : 52626 : nArrY = 1;
426 : 55392 : nThisRow=nCurRow; // Ende des Bereichs
427 : : SCSIZE nIndex;
428 [ + - ]: 55392 : (void) pThisAttrArr->Search( nCurRow, nIndex );
429 : :
430 : :
431 [ + + ][ + + ]: 65866 : do
[ + + ]
432 : : {
433 : 65866 : nThisRow=pThisAttrArr->pData[nIndex].nRow; // Ende des Bereichs
434 : 65866 : pPattern=pThisAttrArr->pData[nIndex].pPattern;
435 : :
436 : : const SvxBrushItem* pBackground = (const SvxBrushItem*)
437 [ + - ]: 65866 : &pPattern->GetItem(ATTR_BACKGROUND);
438 : : const SvxBoxItem* pLinesAttr = (const SvxBoxItem*)
439 [ + - ]: 65866 : &pPattern->GetItem(ATTR_BORDER);
440 : :
441 : : const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >(
442 [ + - ]: 65866 : &pPattern->GetItem( ATTR_BORDER_TLBR ) );
443 : : const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >(
444 [ + - ]: 65866 : &pPattern->GetItem( ATTR_BORDER_BLTR ) );
445 : :
446 : : const SvxShadowItem* pShadowAttr = (const SvxShadowItem*)
447 [ + - ]: 65866 : &pPattern->GetItem(ATTR_SHADOW);
448 [ + + ]: 65866 : if (pShadowAttr != pDefShadow)
449 : 2009 : bAnyShadow = true;
450 : :
451 : : const ScMergeAttr* pMergeAttr = (const ScMergeAttr*)
452 [ + - ]: 65866 : &pPattern->GetItem(ATTR_MERGE);
453 [ + + ][ + - ]: 65866 : bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge );
[ + + ]
454 : 65866 : sal_uInt16 nOverlap = ((const ScMergeFlagAttr*) &pPattern->GetItemSet().
455 [ + - ]: 65866 : Get(ATTR_MERGE_FLAG))->GetValue();
456 : 65866 : bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0);
457 : 65866 : bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0);
458 : 65866 : bool bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0);
459 : 65866 : bool bPushButton = ((nOverlap & SC_MF_BUTTON) != 0);
460 : 65866 : bool bScenario = ((nOverlap & SC_MF_SCENARIO) != 0);
461 : 65866 : bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
462 : 65866 : bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
463 [ + + ][ + + ]: 65866 : if (bMerged||bHOverlapped||bVOverlapped)
[ + + ]
464 : 36 : bAnyMerged = true; // intern
465 : :
466 : : bool bHidden, bHideFormula;
467 [ - + ]: 65866 : if (bTabProtect)
468 : : {
469 : : const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)
470 [ # # ]: 0 : pPattern->GetItem(ATTR_PROTECTION);
471 : 0 : bHidden = rProtAttr.GetHideCell();
472 : 0 : bHideFormula = rProtAttr.GetHideFormula();
473 : : }
474 : : else
475 : 65866 : bHidden = bHideFormula = false;
476 : :
477 : : sal_uLong nConditional = ((const SfxUInt32Item&)pPattern->
478 [ + - ]: 65866 : GetItem(ATTR_CONDITIONAL)).GetValue();
479 : :
480 : 65866 : const ScConditionalFormat* pCondForm = NULL;
481 [ + - ][ + + ]: 65866 : if ( nConditional && pCondFormList )
482 [ + - ]: 2115 : pCondForm = pCondFormList->GetFormat( nConditional );
483 : :
484 [ + + ][ + + ]: 1272441 : do
[ + + ]
485 : : {
486 : 1272441 : SCROW nLastHiddenRow = -1;
487 [ + - ]: 1272441 : bool bRowHidden = RowHidden(nCurRow, nTab, NULL, &nLastHiddenRow);
488 [ + + ][ + + ]: 1272441 : if ( nArrY==0 || !bRowHidden )
489 : : {
490 : 1270827 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
491 [ + + ]: 1270827 : if (pBackground != pDefBackground) // Spalten-HG == Standard ?
492 : 9121 : pThisRowInfo->bEmptyBack = false;
493 [ + + ]: 1270827 : if (bAutoFilter)
494 : 110 : pThisRowInfo->bAutoFilter = true;
495 [ + + ]: 1270827 : if (bPushButton)
496 : 576 : pThisRowInfo->bPushButton = true;
497 : :
498 : 1270827 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
499 : 1270827 : pInfo->pBackground = pBackground;
500 : 1270827 : pInfo->pPatternAttr = pPattern;
501 : 1270827 : pInfo->bMerged = bMerged;
502 : 1270827 : pInfo->bHOverlapped = bHOverlapped;
503 : 1270827 : pInfo->bVOverlapped = bVOverlapped;
504 : 1270827 : pInfo->bAutoFilter = bAutoFilter;
505 : 1270827 : pInfo->bPushButton = bPushButton;
506 : 1270827 : pInfo->bPopupButton = bPopupButton;
507 : 1270827 : pInfo->bFilterActive = bFilterActive;
508 : 1270827 : pInfo->pLinesAttr = pLinesAttr;
509 : 1270827 : pInfo->mpTLBRLine = pTLBRLine;
510 : 1270827 : pInfo->mpBLTRLine = pBLTRLine;
511 : 1270827 : pInfo->pShadowAttr = pShadowAttr;
512 : : // nWidth wird nicht mehr einzeln gesetzt
513 : :
514 : 1270827 : bool bEmbed = false; //bIsEmbedded &&
515 : : #if 0 // Huh? Is this intentional or accidental? Clang warns
516 : : // "expression result unused", so ifdef out these lines. The
517 : : // code has been like this since 2004.
518 : : nTab >= aEmbedRange.aStart.Tab() &&
519 : : nTab <= aEmbedRange.aEnd.Tab() &&
520 : : nX >= aEmbedRange.aStart.Col() &&
521 : : nX <= aEmbedRange.aEnd.Col() &&
522 : : nCurRow >= aEmbedRange.aStart.Row() &&
523 : : nCurRow <= aEmbedRange.aEnd.Row();
524 : : #endif
525 [ - + ]: 1270827 : if (bScenario)
526 : : {
527 [ # # ]: 0 : pInfo->pBackground = ScGlobal::GetButtonBrushItem();
528 : 0 : pThisRowInfo->bEmptyBack = false;
529 : : }
530 [ - + ]: 1270827 : else if (bEmbed)
531 : : {
532 : 0 : pInfo->pBackground = ScGlobal::GetEmbeddedBrushItem();
533 : 0 : pThisRowInfo->bEmptyBack = false;
534 : : }
535 : :
536 [ + - ][ - + ]: 1270827 : if (bHidden || ( bFormulaMode && bHideFormula && pInfo->pCell
[ # # ]
[ # # # # ]
[ - + ]
537 : 0 : && pInfo->pCell->GetCellType()
538 : : == CELLTYPE_FORMULA ))
539 : 0 : pInfo->bEmptyCellText = true;
540 : :
541 [ + + ]: 1270827 : if ( pCondForm )
542 : : {
543 : : ScCondFormatData aData = pCondForm->GetData( pInfo->pCell,
544 [ + - ]: 10177 : ScAddress( nX, nCurRow, nTab ) );
545 [ + + ]: 10177 : if (!aData.aStyleName.isEmpty())
546 : : {
547 : : SfxStyleSheetBase* pStyleSheet =
548 [ + - ][ + - ]: 4 : pStlPool->Find( aData.aStyleName, SFX_STYLE_FAMILY_PARA );
[ + - ]
549 [ + - ]: 4 : if ( pStyleSheet )
550 : : {
551 : : //! Style-Sets cachen !!!
552 [ + - ]: 4 : pInfo->pConditionSet = &pStyleSheet->GetItemSet();
553 : 4 : bAnyCondition = true;
554 : : }
555 : : // if style is not there, treat like no condition
556 : : }
557 [ - + ]: 10177 : if(aData.pColorScale)
558 : : {
559 : 0 : pInfo->pColorScale = aData.pColorScale;
560 : : }
561 : :
562 [ - + ]: 10177 : if(aData.pDataBar)
563 : : {
564 : 0 : pInfo->pDataBar = aData.pDataBar;
565 : 10177 : }
566 : : }
567 : :
568 : 1270827 : ++nArrY;
569 : : }
570 [ + - ][ + - ]: 1614 : else if (bRowHidden && nLastHiddenRow >= 0)
571 : : {
572 : 1614 : nCurRow = nLastHiddenRow;
573 [ + + ]: 1614 : if (nCurRow > nThisRow)
574 : 52 : nCurRow = nThisRow;
575 : : }
576 : 1272441 : ++nCurRow;
577 : : }
578 : : while (nCurRow <= nThisRow && nCurRow <= nYExtra);
579 : 65866 : ++nIndex;
580 : : }
581 : : while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra );
582 : :
583 : :
584 [ + + ][ + + ]: 55392 : if (pMarkData && pMarkData->IsMultiMarked())
[ + + ]
585 : : {
586 : : // Blockmarken
587 : 165 : const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX;
588 : : bool bThisMarked;
589 : 165 : nArrY = 1;
590 : 165 : nCurRow = nY1; // einzelne Zeile
591 : 165 : nThisRow = nY1; // Ende des Bereichs
592 : :
593 [ + + ][ + - ]: 165 : if ( pThisMarkArr->Search( nY1, nIndex ) )
594 : : {
595 [ + + ][ + - ]: 55467 : do
[ + + ]
596 : : {
597 : 150 : nThisRow=pThisMarkArr->pData[nIndex].nRow; // Ende des Bereichs
598 : 150 : bThisMarked=pThisMarkArr->pData[nIndex].bMarked;
599 : :
600 [ + + ][ + + ]: 2025 : do
[ + + ]
601 : : {
602 [ + - ][ + - ]: 2025 : if ( !RowHidden( nCurRow,nTab ) )
603 : : {
604 [ + + ]: 2025 : if ( bThisMarked )
605 : : {
606 : : bool bSkip = bSkipMarks &&
607 : : nX >= nBlockStartX &&
608 : : nX <= nBlockEndX &&
609 : : nCurRow >= nBlockStartY &&
610 [ - + ][ # # ]: 170 : nCurRow <= nBlockEndY;
[ # # ][ # # ]
[ # # ]
611 [ + - ]: 170 : if (!bSkip)
612 : : {
613 : 170 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
614 : 170 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
615 : 170 : pInfo->bMarked = true;
616 : : }
617 : : }
618 : 2025 : ++nArrY;
619 : : }
620 : 2025 : ++nCurRow;
621 : : }
622 : : while (nCurRow <= nThisRow && nCurRow <= nY2);
623 : 150 : ++nIndex;
624 : : }
625 : : while ( nIndex < pThisMarkArr->nCount && nThisRow < nY2 );
626 : : }
627 : : }
628 : : }
629 : : else // vordere Spalten
630 : : {
631 [ + + ]: 58736 : for (nArrY=1; nArrY+1<nArrCount; nArrY++)
632 : : {
633 : 2712 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
634 : 2712 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
635 : :
636 : 2712 : pInfo->nWidth = nThisWidth; //! oder nur 0 abfragen ??
637 : : }
638 : : }
639 : : }
640 : : }
641 : : else
642 : 5170 : pRowInfo[0].pCellInfo[nArrX].nWidth = STD_COL_WIDTH;
643 : : // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht
644 : : }
645 : :
646 : : //-------------------------------------------------------------------------
647 : : // bedingte Formatierung auswerten
648 : :
649 [ + + ]: 5170 : if (bAnyCondition)
650 : : {
651 [ + + ]: 126 : for (nArrY=0; nArrY<nArrCount; nArrY++)
652 : : {
653 [ + + ]: 1526 : for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr
654 : : {
655 : 1404 : CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nArrX];
656 : 1404 : const SfxItemSet* pCondSet = pInfo->pConditionSet;
657 [ + + ]: 1404 : if (pCondSet)
658 : : {
659 : : const SfxPoolItem* pItem;
660 : :
661 : : // Hintergrund
662 [ + - ][ - + ]: 4 : if ( pCondSet->GetItemState( ATTR_BACKGROUND, true, &pItem ) == SFX_ITEM_SET )
663 : : {
664 : 0 : pInfo->pBackground = (const SvxBrushItem*) pItem;
665 : 0 : pRowInfo[nArrY].bEmptyBack = false;
666 : : }
667 : :
668 : : // Umrandung
669 [ + - ][ - + ]: 4 : if ( pCondSet->GetItemState( ATTR_BORDER, true, &pItem ) == SFX_ITEM_SET )
670 : 0 : pInfo->pLinesAttr = (const SvxBoxItem*) pItem;
671 : :
672 [ + - ][ - + ]: 4 : if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, true, &pItem ) == SFX_ITEM_SET )
673 : 0 : pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem );
674 [ + - ][ - + ]: 4 : if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, true, &pItem ) == SFX_ITEM_SET )
675 : 0 : pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem );
676 : :
677 : : // Schatten
678 [ + - ][ - + ]: 4 : if ( pCondSet->GetItemState( ATTR_SHADOW, true, &pItem ) == SFX_ITEM_SET )
679 : : {
680 : 0 : pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
681 : 4 : bAnyShadow = true;
682 : : }
683 : : }
684 [ - + ]: 1404 : if(pInfo->pColorScale)
685 : : {
686 : 0 : pRowInfo[nArrY].bEmptyBack = false;
687 [ # # ][ # # ]: 0 : pInfo->pBackground = new SvxBrushItem(*pInfo->pColorScale, ATTR_BACKGROUND);
688 : : }
689 : : }
690 : : }
691 : : }
692 : :
693 : : // bedingte Formatierung Ende
694 : : //-------------------------------------------------------------------------
695 : :
696 : : //
697 : : // Daten von zusammengefassten Zellen anpassen
698 : : //
699 : :
700 [ + + ]: 5170 : if (bAnyMerged)
701 : : {
702 [ + + ]: 152 : for (nArrY=0; nArrY<nArrCount; nArrY++)
703 : : {
704 : 147 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
705 [ + + ]: 147 : nSignedY = nArrY ? pThisRowInfo->nRowNo : ((SCsROW)nY1)-1;
706 : :
707 [ + + ]: 1911 : for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr
708 : : {
709 : 1764 : SCsCOL nSignedX = ((SCsCOL) nArrX) - 1;
710 : 1764 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
711 : :
712 [ + + ][ + + ]: 1764 : if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped)
[ + + ]
713 : : {
714 : : SCsCOL nStartX;
715 : : SCsROW nStartY;
716 : : SCsCOL nEndX;
717 : : SCsROW nEndY;
718 : : lcl_GetMergeRange( nSignedX,nSignedY, nArrY, this,pRowInfo, nX1,nY1,nX2,nY2,nTab,
719 [ + - ]: 76 : nStartX,nStartY, nEndX,nEndY );
720 [ + - ]: 76 : const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab );
721 [ + - ]: 76 : const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab );
722 : : const SfxPoolItem* pItem;
723 : :
724 : : // Hintergrund kopieren (oder in output.cxx)
725 : :
726 [ - + ][ # # ]: 76 : if ( !pStartCond || pStartCond->
[ + - ]
727 [ # # ]: 0 : GetItemState(ATTR_BACKGROUND,true,&pItem) != SFX_ITEM_SET )
728 [ + - ]: 76 : pItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
729 : 76 : pInfo->pBackground = (const SvxBrushItem*) pItem;
730 : 76 : pRowInfo[nArrY].bEmptyBack = false;
731 : :
732 : : // Schatten
733 : :
734 [ - + ][ # # ]: 76 : if ( !pStartCond || pStartCond->
[ + - ]
735 [ # # ]: 0 : GetItemState(ATTR_SHADOW,true,&pItem) != SFX_ITEM_SET )
736 [ + - ]: 76 : pItem = &pStartPattern->GetItem(ATTR_SHADOW);
737 : 76 : pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
738 [ - + ]: 76 : if (pInfo->pShadowAttr != pDefShadow)
739 : 0 : bAnyShadow = true;
740 : :
741 : : // Blockmarken - wieder mit Original-Merge-Werten
742 : :
743 : 76 : bool bCellMarked = false;
744 [ - + ]: 76 : if (bPaintMarks)
745 : : bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX
746 : : && nStartX <= (SCsCOL) nBlockEndX
747 : : && nStartY >= (SCsROW) nBlockStartY
748 [ # # ][ # # ]: 0 : && nStartY <= (SCsROW) nBlockEndY );
[ # # ][ # # ]
749 [ + + ][ - + ]: 76 : if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked)
[ # # ][ - + ]
750 : : {
751 : 0 : const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX;
752 : : SCSIZE nIndex;
753 [ # # ][ # # ]: 0 : if ( pThisMarkArr->Search( nStartY, nIndex ) )
754 : 0 : bCellMarked=pThisMarkArr->pData[nIndex].bMarked;
755 : : }
756 : :
757 : 76 : pInfo->bMarked = bCellMarked;
758 : : }
759 : : }
760 : : }
761 : : }
762 : :
763 [ + + ]: 5170 : if (bAnyShadow) // Schatten verteilen
764 : : {
765 [ + + ]: 4348 : for (nArrY=0; nArrY<nArrCount; nArrY++)
766 : : {
767 : 3842 : bool bTop = ( nArrY == 0 );
768 : 3842 : bool bBottom = ( nArrY+1 == nArrCount );
769 : :
770 [ + + ]: 49942 : for (nArrX=nX1; nArrX<=nX2+2; nArrX++) // links und rechts einer mehr
771 : : {
772 : 46100 : bool bLeft = ( nArrX == nX1 );
773 : 46100 : bool bRight = ( nArrX == nX2+2 );
774 : :
775 : 46100 : CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nArrX];
776 : 46100 : const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
777 [ + - ]: 46100 : SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE;
778 [ - + ]: 46100 : if (eLoc != SVX_SHADOW_NONE)
779 : : {
780 : : // oder Test auf != eLoc
781 : :
782 : 0 : SCsCOL nDxPos = 1;
783 : 0 : SCsCOL nDxNeg = -1;
784 : :
785 [ # # ][ # # ]: 0 : while ( nArrX+nDxPos < nX2+2 && pRowInfo[0].pCellInfo[nArrX+nDxPos].nWidth == 0 )
[ # # ]
786 : 0 : ++nDxPos;
787 [ # # ][ # # ]: 0 : while ( nArrX+nDxNeg > nX1 && pRowInfo[0].pCellInfo[nArrX+nDxNeg].nWidth == 0 )
[ # # ]
788 : 0 : --nDxNeg;
789 : :
790 : 0 : bool bLeftDiff = !bLeft &&
791 [ # # ][ # # ]: 0 : CELLINFO(nDxNeg,0).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
792 : 0 : bool bRightDiff = !bRight &&
793 [ # # ][ # # ]: 0 : CELLINFO(nDxPos,0).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
794 : 0 : bool bTopDiff = !bTop &&
795 [ # # ][ # # ]: 0 : CELLINFO(0,-1).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
796 : 0 : bool bBottomDiff = !bBottom &&
797 [ # # ][ # # ]: 0 : CELLINFO(0,1).pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
798 : :
799 [ # # ]: 0 : if ( bLayoutRTL )
800 : : {
801 [ # # # # : 0 : switch (eLoc)
# ]
802 : : {
803 : 0 : case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
804 : 0 : case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
805 : 0 : case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_TOPLEFT; break;
806 : 0 : case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
807 : : default:
808 : : {
809 : : // added to avoid warnings
810 : : }
811 : : }
812 : : }
813 : :
814 [ # # # # : 0 : switch (eLoc)
# ]
815 : : {
816 : : case SVX_SHADOW_BOTTOMRIGHT:
817 [ # # ]: 0 : if (bBottomDiff)
818 : : {
819 : 0 : CELLINFO(0,1).pHShadowOrigin = pThisAttr;
820 : 0 : CELLINFO(0,1).eHShadowPart =
821 [ # # ]: 0 : bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
822 : : }
823 [ # # ]: 0 : if (bRightDiff)
824 : : {
825 : 0 : CELLINFO(1,0).pVShadowOrigin = pThisAttr;
826 : 0 : CELLINFO(1,0).eVShadowPart =
827 [ # # ]: 0 : bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
828 : : }
829 [ # # ][ # # ]: 0 : if (bBottomDiff && bRightDiff)
830 : : {
831 : 0 : CELLINFO(1,1).pHShadowOrigin = pThisAttr;
832 : 0 : CELLINFO(1,1).eHShadowPart = SC_SHADOW_CORNER;
833 : : }
834 : 0 : break;
835 : :
836 : : case SVX_SHADOW_BOTTOMLEFT:
837 [ # # ]: 0 : if (bBottomDiff)
838 : : {
839 : 0 : CELLINFO(0,1).pHShadowOrigin = pThisAttr;
840 : 0 : CELLINFO(0,1).eHShadowPart =
841 [ # # ]: 0 : bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
842 : : }
843 [ # # ]: 0 : if (bLeftDiff)
844 : : {
845 : 0 : CELLINFO(-1,0).pVShadowOrigin = pThisAttr;
846 : 0 : CELLINFO(-1,0).eVShadowPart =
847 [ # # ]: 0 : bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
848 : : }
849 [ # # ][ # # ]: 0 : if (bBottomDiff && bLeftDiff)
850 : : {
851 : 0 : CELLINFO(-1,1).pHShadowOrigin = pThisAttr;
852 : 0 : CELLINFO(-1,1).eHShadowPart = SC_SHADOW_CORNER;
853 : : }
854 : 0 : break;
855 : :
856 : : case SVX_SHADOW_TOPRIGHT:
857 [ # # ]: 0 : if (bTopDiff)
858 : : {
859 : 0 : CELLINFO(0,-1).pHShadowOrigin = pThisAttr;
860 : 0 : CELLINFO(0,-1).eHShadowPart =
861 [ # # ]: 0 : bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
862 : : }
863 [ # # ]: 0 : if (bRightDiff)
864 : : {
865 : 0 : CELLINFO(1,0).pVShadowOrigin = pThisAttr;
866 : 0 : CELLINFO(1,0).eVShadowPart =
867 [ # # ]: 0 : bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
868 : : }
869 [ # # ][ # # ]: 0 : if (bTopDiff && bRightDiff)
870 : : {
871 : 0 : CELLINFO(1,-1).pHShadowOrigin = pThisAttr;
872 : 0 : CELLINFO(1,-1).eHShadowPart = SC_SHADOW_CORNER;
873 : : }
874 : 0 : break;
875 : :
876 : : case SVX_SHADOW_TOPLEFT:
877 [ # # ]: 0 : if (bTopDiff)
878 : : {
879 : 0 : CELLINFO(0,-1).pHShadowOrigin = pThisAttr;
880 : 0 : CELLINFO(0,-1).eHShadowPart =
881 [ # # ]: 0 : bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
882 : : }
883 [ # # ]: 0 : if (bLeftDiff)
884 : : {
885 : 0 : CELLINFO(-1,0).pVShadowOrigin = pThisAttr;
886 : 0 : CELLINFO(-1,0).eVShadowPart =
887 [ # # ]: 0 : bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
888 : : }
889 [ # # ][ # # ]: 0 : if (bTopDiff && bLeftDiff)
890 : : {
891 : 0 : CELLINFO(-1,-1).pHShadowOrigin = pThisAttr;
892 : 0 : CELLINFO(-1,-1).eHShadowPart = SC_SHADOW_CORNER;
893 : : }
894 : 0 : break;
895 : :
896 : : default:
897 : : OSL_FAIL("falscher Shadow-Enum");
898 : : }
899 : : }
900 : : }
901 : : }
902 : : }
903 : :
904 : 5170 : rTabInfo.mnArrCount = sal::static_int_cast<sal_uInt16>(nArrCount);
905 : 5170 : rTabInfo.mbPageMode = bPageMode;
906 : :
907 : : // ========================================================================
908 : : // *** create the frame border array ***
909 : :
910 : : // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
911 : : // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
912 : :
913 : 5170 : size_t nColCount = nX2 - nX1 + 3;
914 : 5170 : size_t nRowCount = nArrCount;
915 : :
916 : 5170 : svx::frame::Array& rArray = rTabInfo.maArray;
917 [ + - ]: 5170 : rArray.Initialize( nColCount, nRowCount );
918 [ + - ]: 5170 : rArray.SetUseDiagDoubleClipping( false );
919 : :
920 [ + + ]: 126616 : for( size_t nRow = 0; nRow < nRowCount; ++nRow )
921 : : {
922 : 121446 : sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow );
923 : 121446 : RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
924 : :
925 [ + + ]: 1564417 : for( size_t nCol = 0; nCol < nColCount; ++nCol )
926 : : {
927 : 1442971 : sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nX1 );
928 : 1442971 : const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
929 : :
930 : 1442971 : const SvxBoxItem* pBox = rInfo.pLinesAttr;
931 : 1442971 : const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
932 : 1442971 : const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
933 : :
934 : 1442971 : size_t nFirstCol = nCol;
935 : 1442971 : size_t nFirstRow = nRow;
936 : :
937 : : // *** merged cells *** -------------------------------------------
938 : :
939 [ + - ][ + + ]: 1442971 : if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) )
[ + + ][ + - ]
[ - + ][ + + ]
940 : : {
941 : : // *** insert merged range in svx::frame::Array ***
942 : :
943 : : /* #i69369# top-left cell of a merged range may be located in
944 : : a hidden column or row. Use lcl_GetMergeRange() to find the
945 : : complete merged range, then calculate dimensions and
946 : : document position of the visible range. */
947 : :
948 : : // note: document columns are always one less than CellInfoX coords
949 : : // note: document rows must be looked up in RowInfo structs
950 : :
951 : : // current column and row in document coordinates
952 : 5 : SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
953 [ + - ]: 5 : SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nY1 - 1) );
954 : :
955 : : // find entire merged range in document, returns signed document coordinates
956 : : SCsCOL nFirstRealDocColS, nLastRealDocColS;
957 : : SCsROW nFirstRealDocRowS, nLastRealDocRowS;
958 : : lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ),
959 : : nCellInfoY, this, pRowInfo, nX1,nY1,nX2,nY2,nTab,
960 [ + - ]: 5 : nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS );
961 : :
962 : : // *complete* merged range in document coordinates
963 : 5 : SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS );
964 : 5 : SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS );
965 : 5 : SCCOL nLastRealDocCol = static_cast< SCCOL >( nLastRealDocColS );
966 : 5 : SCROW nLastRealDocRow = static_cast< SCROW >( nLastRealDocRowS );
967 : :
968 : : // first visible column (nX1-1 is first processed document column)
969 [ - + ][ # # ]: 5 : SCCOL nFirstDocCol = (nX1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nX1 - 1 ) : nFirstRealDocCol;
[ - + ][ # # ]
970 : 5 : sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( nFirstDocCol + 1 );
971 : 5 : nFirstCol = static_cast< size_t >( nFirstCellInfoX - nX1 );
972 : :
973 : : // last visible column (nX2+1 is last processed document column)
974 [ + - ][ + - ]: 5 : SCCOL nLastDocCol = (nX2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nX2 + 1 ) : nLastRealDocCol;
[ + - ][ # # ]
975 : 5 : sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( nLastDocCol + 1 );
976 : 5 : size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nX1 );
977 : :
978 : : // first visible row
979 : 5 : sal_uInt16 nFirstCellInfoY = nCellInfoY;
980 [ - + ][ # # ]: 5 : while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) ||
[ + - ][ - + ]
[ - + ]
981 : : ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nY1 - 1 ) >= nFirstRealDocRow)) )
982 : 0 : --nFirstCellInfoY;
983 [ + - ]: 5 : SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nY1 - 1 );
984 : 5 : nFirstRow = static_cast< size_t >( nFirstCellInfoY );
985 : :
986 : : // last visible row
987 : 5 : sal_uInt16 nLastCellInfoY = nCellInfoY;
988 [ + - ][ + + ]: 20 : while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) &&
[ + + ]
989 : 20 : (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) )
990 : 15 : ++nLastCellInfoY;
991 [ + - ]: 5 : SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nY1 - 1 );
992 : 5 : size_t nLastRow = static_cast< size_t >( nLastCellInfoY );
993 : :
994 : : // insert merged range
995 [ + - ]: 5 : rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
996 : :
997 : : // *** find additional size not included in svx::frame::Array ***
998 : :
999 : : // additional space before first column
1000 [ - + ]: 5 : if( nFirstCol == 0 )
1001 : : {
1002 : 0 : long nSize = 0;
1003 [ # # ]: 0 : for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol )
1004 [ # # ][ # # ]: 0 : nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * nScaleX ), 1L );
1005 [ # # ]: 0 : rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
1006 : : }
1007 : : // additional space after last column
1008 [ - + ]: 5 : if( nLastCol + 1 == nColCount )
1009 : : {
1010 : 0 : long nSize = 0;
1011 [ # # ]: 0 : for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol )
1012 [ # # ][ # # ]: 0 : nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * nScaleX ), 1L );
1013 [ # # ]: 0 : rArray.SetAddMergedRightSize( nCol, nRow, nSize );
1014 : : }
1015 : : // additional space above first row
1016 [ - + ]: 5 : if( nFirstRow == 0 )
1017 : : {
1018 : 0 : long nSize = 0;
1019 [ # # ]: 0 : for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow )
1020 [ # # ][ # # ]: 0 : nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * nScaleY ), 1L );
1021 [ # # ]: 0 : rArray.SetAddMergedTopSize( nCol, nRow, nSize );
1022 : : }
1023 : : // additional space beyond last row
1024 [ - + ]: 5 : if( nLastRow + 1 == nRowCount )
1025 : : {
1026 : 0 : long nSize = 0;
1027 [ # # ]: 0 : for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow )
1028 [ # # ][ # # ]: 0 : nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * nScaleY ), 1L );
1029 [ # # ]: 0 : rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
1030 : : }
1031 : :
1032 : : // *** use line attributes from real origin cell ***
1033 : :
1034 [ + - ][ - + ]: 5 : if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) )
1035 : : {
1036 [ # # ][ # # ]: 0 : if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) )
1037 : : {
1038 [ # # ]: 0 : const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab );
1039 [ # # ]: 0 : pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) );
1040 [ # # ]: 0 : pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) );
1041 [ # # ]: 0 : pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) );
1042 : : }
1043 : : else
1044 : : {
1045 : 0 : pBox = 0;
1046 : 5 : pTLBR = pBLTR = 0;
1047 : : }
1048 : : }
1049 : : }
1050 : :
1051 : : // *** borders *** ------------------------------------------------
1052 : :
1053 [ + + ]: 1442971 : if( pBox )
1054 : : {
1055 [ + - ][ + - ]: 1270827 : rArray.SetCellStyleLeft( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(), nScaleX ) );
1056 [ + - ][ + - ]: 1270827 : rArray.SetCellStyleRight( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(), nScaleX ) );
1057 [ + - ][ + - ]: 1270827 : rArray.SetCellStyleTop( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(), nScaleY ) );
1058 [ + - ][ + - ]: 1270827 : rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), nScaleY ) );
1059 : : }
1060 : :
1061 [ + + ]: 1442971 : if( pTLBR )
1062 [ + - ][ + - ]: 1270827 : rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), nScaleY ) );
1063 [ + + ]: 1442971 : if( rInfo.mpBLTRLine )
1064 [ + - ][ + - ]: 1270827 : rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), nScaleY ) );
1065 : : }
1066 : : }
1067 : :
1068 : : /* Mirror the entire frame array.
1069 : : 1st param = Mirror the vertical double line styles as well.
1070 : : 2nd param = Do not swap diagonal lines.
1071 : : */
1072 [ + + ]: 5170 : if( bLayoutRTL )
1073 [ + - ]: 4 : rArray.MirrorSelfX( true, false );
1074 : 5170 : }
1075 : :
1076 : : // ============================================================================
1077 : :
1078 : 5170 : ScTableInfo::ScTableInfo() :
1079 [ + + ]: 5299250 : mpRowInfo( new RowInfo[ ROWINFO_MAX ] ),
1080 [ + - ]: 5170 : mbPageMode( false )
1081 : : {
1082 [ + + ]: 5299250 : for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
1083 : 5294080 : mpRowInfo[ nIdx ].pCellInfo = 0;
1084 : 5170 : }
1085 : :
1086 : 5170 : ScTableInfo::~ScTableInfo()
1087 : : {
1088 [ + + ]: 5299250 : for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
1089 [ + + ][ + + ]: 6742955 : delete [] mpRowInfo[ nIdx ].pCellInfo;
1090 [ + - ]: 5170 : delete [] mpRowInfo;
1091 : 5170 : }
1092 : :
1093 : : // ============================================================================
1094 : :
1095 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|