LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - fillinfo.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 446 577 77.3 %
Date: 2013-07-09 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10