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