LCOV - code coverage report
Current view: top level - sc/source/core/data - column.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 651 1036 62.8 %
Date: 2012-08-25 Functions: 70 88 79.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 571 1424 40.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <map>
      30                 :            : 
      31                 :            : #include <svl/poolcach.hxx>
      32                 :            : #include <svl/zforlist.hxx>
      33                 :            : #include <editeng/scripttypeitem.hxx>
      34                 :            : #include <string.h>
      35                 :            : 
      36                 :            : #include "scitems.hxx"
      37                 :            : #include "column.hxx"
      38                 :            : #include "cell.hxx"
      39                 :            : #include "document.hxx"
      40                 :            : #include "docpool.hxx"
      41                 :            : #include "attarray.hxx"
      42                 :            : #include "patattr.hxx"
      43                 :            : #include "compiler.hxx"
      44                 :            : #include "brdcst.hxx"
      45                 :            : #include "markdata.hxx"
      46                 :            : #include "detfunc.hxx"          // for Notes in Sort/Swap
      47                 :            : #include "postit.hxx"
      48                 :            : 
      49                 :            : //#pragma optimize ( "", off )
      50                 :            : //  nur Search ohne Optimierung!
      51                 :            : 
      52                 :            : // STATIC DATA -----------------------------------------------------------
      53                 :            : using ::editeng::SvxBorderLine;
      54                 :            : using namespace formula;
      55                 :            : 
      56                 :      38698 : inline bool IsAmbiguousScriptNonZero( sal_uInt8 nScript )
      57                 :            : {
      58                 :            :     //! move to a header file
      59                 :            :     return ( nScript != SCRIPTTYPE_LATIN &&
      60                 :            :              nScript != SCRIPTTYPE_ASIAN &&
      61                 :            :              nScript != SCRIPTTYPE_COMPLEX &&
      62 [ +  + ][ +  - ]:      38698 :              nScript != 0 );
         [ +  - ][ -  + ]
      63                 :            : }
      64                 :            : 
      65                 :            : // ----------------------------------------------------------------------------
      66                 :            : 
      67                 :         12 : ScColumn::DoubleAllocSwitch::DoubleAllocSwitch(bool bNewVal) :
      68                 :         12 :     mbOldVal(ScColumn::bDoubleAlloc)
      69                 :            : {
      70                 :         12 :     ScColumn::bDoubleAlloc = bNewVal;
      71                 :         12 : }
      72                 :            : 
      73                 :         12 : ScColumn::DoubleAllocSwitch::~DoubleAllocSwitch()
      74                 :            : {
      75                 :         12 :     ScColumn::bDoubleAlloc = mbOldVal;
      76                 :         12 : }
      77                 :            : 
      78                 :            : // ----------------------------------------------------------------------------
      79                 :            : 
      80                 :    1982464 : ScColumn::ScColumn() :
      81                 :            :     nCol( 0 ),
      82                 :            :     pAttrArray( NULL ),
      83                 :    1982464 :     pDocument( NULL )
      84                 :            : {
      85                 :    1982464 : }
      86                 :            : 
      87                 :            : 
      88                 :    1787904 : ScColumn::~ScColumn()
      89                 :            : {
      90         [ +  - ]:    1787904 :     FreeAll();
      91 [ +  - ][ +  - ]:    1787904 :     delete pAttrArray;
      92                 :    1787904 : }
      93                 :            : 
      94                 :            : 
      95                 :    1982464 : void ScColumn::Init(SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc)
      96                 :            : {
      97                 :    1982464 :     nCol = nNewCol;
      98                 :    1982464 :     nTab = nNewTab;
      99                 :    1982464 :     pDocument = pDoc;
     100         [ +  - ]:    1982464 :     pAttrArray = new ScAttrArray( nCol, nTab, pDocument );
     101                 :    1982464 : }
     102                 :            : 
     103                 :            : 
     104                 :          0 : SCsROW ScColumn::GetNextUnprotected( SCROW nRow, bool bUp ) const
     105                 :            : {
     106                 :          0 :     return pAttrArray->GetNextUnprotected(nRow, bUp);
     107                 :            : }
     108                 :            : 
     109                 :            : 
     110                 :     351946 : sal_uInt16 ScColumn::GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const
     111                 :            : {
     112                 :            :     // nothing:0, inside:1, bottom:2, left:4, top:8, right:16, open:32
     113         [ +  + ]:     351946 :     if ( maItems.empty() )
     114                 :     342343 :         return 0;
     115         [ +  + ]:       9603 :     if ( nRow1 == nRow2 )
     116                 :            :     {
     117                 :            :         SCSIZE nIndex;
     118 [ +  - ][ +  + ]:       8732 :         if ( Search( nRow1, nIndex ) )
     119                 :            :         {
     120                 :       3202 :             ScBaseCell* pCell = maItems[nIndex].pCell;
     121         [ +  + ]:       3288 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA
           [ +  +  +  + ]
     122         [ +  - ]:         86 :                 && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
     123                 :            :             {
     124                 :          8 :                 ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
     125 [ +  - ][ +  - ]:          8 :                 return ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
     126                 :            :             }
     127                 :            :         }
     128                 :       8732 :         return 0;
     129                 :            :     }
     130                 :            :     else
     131                 :            :     {
     132                 :        871 :         ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
     133                 :        871 :         bool bOpen = false;
     134                 :        871 :         sal_uInt16 nEdges = 0;
     135                 :            :         SCSIZE nIndex;
     136         [ +  - ]:        871 :         Search( nRow1, nIndex );
     137 [ +  + ][ +  + ]:       4034 :         while ( nIndex < maItems.size() && maItems[nIndex].nRow <= nRow2 )
                 [ +  + ]
     138                 :            :         {
     139                 :       3163 :             ScBaseCell* pCell = maItems[nIndex].pCell;
     140         [ +  + ]:       3202 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA
           [ +  +  +  + ]
     141         [ +  - ]:         39 :                 && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
     142                 :            :             {
     143 [ +  - ][ +  - ]:          4 :                 nEdges = ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
     144         [ +  - ]:          4 :                 if ( nEdges )
     145                 :            :                 {
     146         [ +  + ]:          4 :                     if ( nEdges & 8 )
     147                 :          1 :                         bOpen = true;       // top edge opens, keep on looking
     148         [ -  + ]:          3 :                     else if ( !bOpen )
     149                 :          0 :                         return nEdges | 32; // there's something that wasn't opened
     150         [ -  + ]:          3 :                     else if ( nEdges & 1 )
     151                 :          0 :                         return nEdges;      // inside
     152                 :            :                     // (nMask & 16 and  (4 and not 16)) or
     153                 :            :                     // (nMask & 4  and (16 and not 4))
     154 [ +  - ][ +  - ]:          4 :                     if ( ((nMask & 16) && (nEdges & 4)  && !(nEdges & 16))
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
     155                 :          4 :                         || ((nMask & 4)  && (nEdges & 16) && !(nEdges & 4)) )
     156                 :          0 :                         return nEdges;      // only left/right edge
     157         [ +  + ]:          4 :                     if ( nEdges & 2 )
     158                 :          1 :                         bOpen = false;      // bottom edge closes
     159                 :            :                 }
     160                 :            :             }
     161                 :       3163 :             nIndex++;
     162                 :            :         }
     163         [ -  + ]:        871 :         if ( bOpen )
     164                 :          0 :             nEdges |= 32;           // not closed, matrix continues
     165                 :     351946 :         return nEdges;
     166                 :            :     }
     167                 :            : }
     168                 :            : 
     169                 :            : 
     170                 :      56320 : bool ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const
     171                 :            : {
     172         [ +  - ]:      56320 :     if ( rMark.IsMultiMarked() )
     173                 :            :     {
     174                 :      56320 :         bool bFound = false;
     175                 :            : 
     176                 :      56320 :         ScAddress aOrg( ScAddress::INITIALIZE_INVALID );
     177                 :      56320 :         ScAddress aCurOrg( ScAddress::INITIALIZE_INVALID );
     178                 :            :         SCROW nTop, nBottom;
     179         [ +  - ]:      56320 :         ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
     180 [ +  - ][ +  - ]:      56711 :         while ( !bFound && aMarkIter.Next( nTop, nBottom ) )
         [ +  + ][ +  + ]
     181                 :            :         {
     182                 :        391 :             bool bOpen = false;
     183                 :            :             sal_uInt16 nEdges;
     184                 :            :             SCSIZE nIndex;
     185         [ +  - ]:        391 :             Search( nTop, nIndex );
     186 [ +  - ][ +  + ]:       1457 :             while ( !bFound && nIndex < maItems.size() && maItems[nIndex].nRow <= nBottom )
         [ +  + ][ +  + ]
     187                 :            :             {
     188                 :       1066 :                 ScBaseCell* pCell = maItems[nIndex].pCell;
     189         [ -  + ]:       1066 :                 if ( pCell->GetCellType() == CELLTYPE_FORMULA
           [ -  +  #  # ]
     190         [ #  # ]:          0 :                     && ((ScFormulaCell*)pCell)->GetMatrixFlag() )
     191                 :            :                 {
     192 [ #  # ][ #  # ]:          0 :                     nEdges = ((ScFormulaCell*)pCell)->GetMatrixEdge( aOrg );
     193         [ #  # ]:          0 :                     if ( nEdges )
     194                 :            :                     {
     195         [ #  # ]:          0 :                         if ( nEdges & 8 )
     196                 :          0 :                             bOpen = true;   // top edge opens, keep on looking
     197         [ #  # ]:          0 :                         else if ( !bOpen )
     198                 :          0 :                             return true;    // there's something that wasn't opened
     199         [ #  # ]:          0 :                         else if ( nEdges & 1 )
     200                 :          0 :                             bFound = true;  // inside, all selected?
     201                 :            :                         // (4 and not 16) or (16 and not 4)
     202         [ #  # ]:          0 :                         if ( (((nEdges & 4) | 16) ^ ((nEdges & 16) | 4)) )
     203                 :          0 :                             bFound = true;  // only left/right edge, all selected?
     204         [ #  # ]:          0 :                         if ( nEdges & 2 )
     205                 :          0 :                             bOpen = false;  // bottom edge closes
     206                 :            : 
     207         [ #  # ]:          0 :                         if ( bFound )
     208                 :            :                         {   // all selected?
     209         [ #  # ]:          0 :                             if ( aCurOrg != aOrg )
     210                 :            :                             {   // new matrix to check?
     211                 :          0 :                                 aCurOrg = aOrg;
     212                 :            :                                 ScFormulaCell* pFCell;
     213 [ #  # ][ #  # ]:          0 :                                 if ( ((ScFormulaCell*)pCell)->GetMatrixFlag()
     214                 :            :                                         == MM_REFERENCE )
     215 [ #  # ][ #  # ]:          0 :                                     pFCell = (ScFormulaCell*) pDocument->GetCell( aOrg );
     216                 :            :                                 else
     217         [ #  # ]:          0 :                                     pFCell = (ScFormulaCell*)pCell;
     218                 :            :                                 SCCOL nC;
     219                 :            :                                 SCROW nR;
     220         [ #  # ]:          0 :                                 pFCell->GetMatColsRows( nC, nR );
     221                 :            :                                 ScRange aRange( aOrg, ScAddress(
     222                 :          0 :                                     aOrg.Col() + nC - 1, aOrg.Row() + nR - 1,
     223                 :          0 :                                     aOrg.Tab() ) );
     224 [ #  # ][ #  # ]:          0 :                                 if ( rMark.IsAllMarked( aRange ) )
     225                 :          0 :                                     bFound = false;
     226                 :            :                             }
     227                 :            :                             else
     228                 :          0 :                                 bFound = false;     // done already
     229                 :            :                         }
     230                 :            :                     }
     231                 :            :                 }
     232                 :       1066 :                 nIndex++;
     233                 :            :             }
     234         [ -  + ]:        391 :             if ( bOpen )
     235                 :        391 :                 return true;
     236                 :            :         }
     237         [ +  - ]:      56320 :         return bFound;
     238                 :            :     }
     239                 :            :     else
     240                 :      56320 :         return false;
     241                 :            : }
     242                 :            : 
     243                 :            : 
     244                 :    8066085 : bool ScColumn::HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const
     245                 :            : {
     246                 :    8066085 :     return pAttrArray->HasAttrib( nRow1, nRow2, nMask );
     247                 :            : }
     248                 :            : 
     249                 :            : 
     250                 :          0 : bool ScColumn::HasAttribSelection( const ScMarkData& rMark, sal_uInt16 nMask ) const
     251                 :            : {
     252                 :          0 :     bool bFound = false;
     253                 :            : 
     254                 :            :     SCROW nTop;
     255                 :            :     SCROW nBottom;
     256                 :            : 
     257         [ #  # ]:          0 :     if (rMark.IsMultiMarked())
     258                 :            :     {
     259         [ #  # ]:          0 :         ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
     260 [ #  # ][ #  # ]:          0 :         while (aMarkIter.Next( nTop, nBottom ) && !bFound)
         [ #  # ][ #  # ]
     261                 :            :         {
     262 [ #  # ][ #  # ]:          0 :             if (pAttrArray->HasAttrib( nTop, nBottom, nMask ))
     263                 :          0 :                 bFound = true;
     264         [ #  # ]:          0 :         }
     265                 :            :     }
     266                 :            : 
     267                 :          0 :     return bFound;
     268                 :            : }
     269                 :            : 
     270                 :            : 
     271                 :       9873 : bool ScColumn::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
     272                 :            :                             SCCOL& rPaintCol, SCROW& rPaintRow,
     273                 :            :                             bool bRefresh )
     274                 :            : {
     275                 :       9873 :     return pAttrArray->ExtendMerge( nThisCol, nStartRow, nEndRow, rPaintCol, rPaintRow, bRefresh );
     276                 :            : }
     277                 :            : 
     278                 :            : 
     279                 :     136192 : void ScColumn::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, bool bDeep ) const
     280                 :            : {
     281                 :            :     SCROW nTop;
     282                 :            :     SCROW nBottom;
     283                 :            : 
     284         [ +  - ]:     136192 :     if ( rMark.IsMultiMarked() )
     285                 :            :     {
     286                 :     136192 :         const ScMarkArray* pArray = rMark.GetArray() + nCol;
     287         [ +  + ]:     136192 :         if ( pArray->HasMarks() )
     288                 :            :         {
     289         [ +  - ]:        738 :             ScMarkArrayIter aMarkIter( pArray );
     290 [ +  - ][ +  + ]:       1623 :             while (aMarkIter.Next( nTop, nBottom ))
     291 [ +  - ][ +  - ]:       1623 :                 pAttrArray->MergePatternArea( nTop, nBottom, rState, bDeep );
     292                 :            :         }
     293                 :            :     }
     294                 :     136192 : }
     295                 :            : 
     296                 :            : 
     297                 :      66433 : void ScColumn::MergePatternArea( ScMergePatternState& rState, SCROW nRow1, SCROW nRow2, bool bDeep ) const
     298                 :            : {
     299                 :      66433 :     pAttrArray->MergePatternArea( nRow1, nRow2, rState, bDeep );
     300                 :      66433 : }
     301                 :            : 
     302                 :            : 
     303                 :        158 : void ScColumn::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
     304                 :            :                             ScLineFlags& rFlags,
     305                 :            :                             SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight ) const
     306                 :            : {
     307                 :        158 :     pAttrArray->MergeBlockFrame( pLineOuter, pLineInner, rFlags, nStartRow, nEndRow, bLeft, nDistRight );
     308                 :        158 : }
     309                 :            : 
     310                 :            : 
     311                 :       3130 : void ScColumn::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
     312                 :            :                             SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight )
     313                 :            : {
     314                 :       3130 :     pAttrArray->ApplyBlockFrame( pLineOuter, pLineInner, nStartRow, nEndRow, bLeft, nDistRight );
     315                 :       3130 : }
     316                 :            : 
     317                 :            : 
     318                 :      36882 : const ScPatternAttr* ScColumn::GetPattern( SCROW nRow ) const
     319                 :            : {
     320                 :      36882 :     return pAttrArray->GetPattern( nRow );
     321                 :            : }
     322                 :            : 
     323                 :            : 
     324                 :      11914 : const SfxPoolItem* ScColumn::GetAttr( SCROW nRow, sal_uInt16 nWhich ) const
     325                 :            : {
     326                 :      11914 :     return &pAttrArray->GetPattern( nRow )->GetItemSet().Get(nWhich);
     327                 :            : }
     328                 :            : 
     329                 :            : 
     330                 :          0 : const ScPatternAttr* ScColumn::GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const
     331                 :            : {
     332         [ #  # ]:          0 :     ::std::map< const ScPatternAttr*, size_t > aAttrMap;
     333                 :          0 :     const ScPatternAttr* pMaxPattern = 0;
     334                 :          0 :     size_t nMaxCount = 0;
     335                 :            : 
     336         [ #  # ]:          0 :     ScAttrIterator aAttrIter( pAttrArray, nStartRow, nEndRow );
     337                 :            :     const ScPatternAttr* pPattern;
     338                 :          0 :     SCROW nAttrRow1 = 0, nAttrRow2 = 0;
     339                 :            : 
     340 [ #  # ][ #  # ]:          0 :     while( (pPattern = aAttrIter.Next( nAttrRow1, nAttrRow2 )) != 0 )
     341                 :            :     {
     342         [ #  # ]:          0 :         size_t& rnCount = aAttrMap[ pPattern ];
     343                 :          0 :         rnCount += (nAttrRow2 - nAttrRow1 + 1);
     344         [ #  # ]:          0 :         if( rnCount > nMaxCount )
     345                 :            :         {
     346                 :          0 :             pMaxPattern = pPattern;
     347                 :          0 :             nMaxCount = rnCount;
     348                 :            :         }
     349                 :            :     }
     350                 :            : 
     351                 :          0 :     return pMaxPattern;
     352                 :            : }
     353                 :            : 
     354                 :          0 : sal_uInt32 ScColumn::GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const
     355                 :            : {
     356                 :            :     SCROW nPatStartRow, nPatEndRow;
     357         [ #  # ]:          0 :     const ScPatternAttr* pPattern = pAttrArray->GetPatternRange(nPatStartRow, nPatEndRow, nStartRow);
     358 [ #  # ][ #  # ]:          0 :     sal_uInt32 nFormat = pPattern->GetNumberFormat(pDocument->GetFormatTable());
     359         [ #  # ]:          0 :     while (nEndRow > nPatEndRow)
     360                 :            :     {
     361                 :          0 :         nStartRow = nPatEndRow + 1;
     362         [ #  # ]:          0 :         pPattern = pAttrArray->GetPatternRange(nPatStartRow, nPatEndRow, nStartRow);
     363 [ #  # ][ #  # ]:          0 :         sal_uInt32 nTmpFormat = pPattern->GetNumberFormat(pDocument->GetFormatTable());
     364         [ #  # ]:          0 :         if (nFormat != nTmpFormat)
     365                 :          0 :             return 0;
     366                 :            :     }
     367                 :          0 :     return nFormat;
     368                 :            : }
     369                 :            : 
     370                 :            : 
     371                 :      25538 : sal_uInt32 ScColumn::GetNumberFormat( SCROW nRow ) const
     372                 :            : {
     373                 :      25538 :     return pAttrArray->GetPattern( nRow )->GetNumberFormat( pDocument->GetFormatTable() );
     374                 :            : }
     375                 :            : 
     376                 :            : 
     377                 :     102400 : SCsROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray )
     378                 :            : {
     379                 :     102400 :     SCROW nTop = 0;
     380                 :     102400 :     SCROW nBottom = 0;
     381                 :     102400 :     bool bFound = false;
     382                 :            : 
     383         [ +  - ]:     102400 :     if ( rMark.IsMultiMarked() )
     384                 :            :     {
     385         [ +  - ]:     102400 :         ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
     386 [ +  - ][ +  + ]:     103020 :         while (aMarkIter.Next( nTop, nBottom ))
     387                 :            :         {
     388         [ +  - ]:        620 :             pAttrArray->ApplyCacheArea( nTop, nBottom, pCache, pDataArray );
     389                 :        620 :             bFound = true;
     390         [ +  - ]:     102400 :         }
     391                 :            :     }
     392                 :            : 
     393         [ +  + ]:     102400 :     if (!bFound)
     394                 :     101855 :         return -1;
     395 [ +  + ][ -  + ]:        545 :     else if (nTop==0 && nBottom==MAXROW)
     396                 :          0 :         return 0;
     397                 :            :     else
     398                 :     102400 :         return nBottom;
     399                 :            : }
     400                 :            : 
     401                 :            : 
     402                 :       8192 : void ScColumn::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark )
     403                 :            : {
     404                 :            :     SCROW nTop;
     405                 :            :     SCROW nBottom;
     406                 :            : 
     407 [ +  - ][ +  - ]:       8192 :     if ( pAttrArray && rMark.IsMultiMarked() )
                 [ +  - ]
     408                 :            :     {
     409         [ +  - ]:       8192 :         ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
     410 [ +  - ][ +  + ]:       8226 :         while (aMarkIter.Next( nTop, nBottom ))
     411 [ +  - ][ +  - ]:       8226 :             pAttrArray->ChangeIndent(nTop, nBottom, bIncrement);
     412                 :            :     }
     413                 :       8192 : }
     414                 :            : 
     415                 :            : 
     416                 :          0 : void ScColumn::ClearSelectionItems( const sal_uInt16* pWhich,const ScMarkData& rMark )
     417                 :            : {
     418                 :            :     SCROW nTop;
     419                 :            :     SCROW nBottom;
     420                 :            : 
     421 [ #  # ][ #  # ]:          0 :     if ( pAttrArray && rMark.IsMultiMarked() )
                 [ #  # ]
     422                 :            :     {
     423         [ #  # ]:          0 :         ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
     424 [ #  # ][ #  # ]:          0 :         while (aMarkIter.Next( nTop, nBottom ))
     425 [ #  # ][ #  # ]:          0 :             pAttrArray->ClearItems(nTop, nBottom, pWhich);
     426                 :            :     }
     427                 :          0 : }
     428                 :            : 
     429                 :            : 
     430                 :      14336 : void ScColumn::DeleteSelection( sal_uInt16 nDelFlag, const ScMarkData& rMark )
     431                 :            : {
     432                 :            :     SCROW nTop;
     433                 :            :     SCROW nBottom;
     434                 :            : 
     435         [ +  - ]:      14336 :     if ( rMark.IsMultiMarked() )
     436                 :            :     {
     437         [ +  - ]:      14336 :         ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
     438 [ +  - ][ +  + ]:      15398 :         while (aMarkIter.Next( nTop, nBottom ))
     439 [ +  - ][ +  - ]:      15398 :             DeleteArea(nTop, nBottom, nDelFlag);
     440                 :            :     }
     441                 :      14336 : }
     442                 :            : 
     443                 :            : 
     444                 :         87 : void ScColumn::ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr )
     445                 :            : {
     446                 :         87 :     const SfxItemSet* pSet = &rPatAttr.GetItemSet();
     447 [ +  - ][ +  - ]:         87 :     SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
     448                 :            : 
     449         [ +  - ]:         87 :     const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
     450                 :            : 
     451                 :            :     //  true = alten Eintrag behalten
     452                 :            : 
     453         [ +  - ]:         87 :     ScPatternAttr* pNewPattern = (ScPatternAttr*) &aCache.ApplyTo( *pPattern, true );
     454         [ +  - ]:         87 :     ScDocumentPool::CheckRef( *pPattern );
     455         [ +  - ]:         87 :     ScDocumentPool::CheckRef( *pNewPattern );
     456                 :            : 
     457         [ +  - ]:         87 :     if (pNewPattern != pPattern)
     458 [ +  - ][ +  - ]:         87 :       pAttrArray->SetPattern( nRow, pNewPattern );
     459                 :         87 : }
     460                 :            : 
     461                 :            : 
     462                 :      50155 : void ScColumn::ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr,
     463                 :            :                                  ScEditDataArray* pDataArray )
     464                 :            : {
     465                 :      50155 :     const SfxItemSet* pSet = &rPatAttr.GetItemSet();
     466 [ +  - ][ +  - ]:      50155 :     SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
     467 [ +  - ][ +  - ]:      50155 :     pAttrArray->ApplyCacheArea( nStartRow, nEndRow, &aCache, pDataArray );
     468                 :      50155 : }
     469                 :            : 
     470                 :      24940 : bool ScColumn::SetAttrEntries(ScAttrEntry* pData, SCSIZE nSize)
     471                 :            : {
     472                 :      24940 :     return pAttrArray->SetAttrEntries(pData, nSize);
     473                 :            : }
     474                 :            : 
     475                 :          0 : void ScColumn::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
     476                 :            :         const ScPatternAttr& rPattern, short nNewType )
     477                 :            : {
     478                 :          0 :     const SfxItemSet* pSet = &rPattern.GetItemSet();
     479 [ #  # ][ #  # ]:          0 :     SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
     480         [ #  # ]:          0 :     SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
     481                 :          0 :     SCROW nEndRow = rRange.aEnd.Row();
     482         [ #  # ]:          0 :     for ( SCROW nRow = rRange.aStart.Row(); nRow <= nEndRow; nRow++ )
     483                 :            :     {
     484                 :            :         SCROW nRow1, nRow2;
     485                 :            :         const ScPatternAttr* pPattern = pAttrArray->GetPatternRange(
     486         [ #  # ]:          0 :             nRow1, nRow2, nRow );
     487         [ #  # ]:          0 :         sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter );
     488         [ #  # ]:          0 :         short nOldType = pFormatter->GetType( nFormat );
     489 [ #  # ][ #  # ]:          0 :         if ( nOldType == nNewType || pFormatter->IsCompatible( nOldType, nNewType ) )
         [ #  # ][ #  # ]
     490                 :          0 :             nRow = nRow2;
     491                 :            :         else
     492                 :            :         {
     493                 :          0 :             SCROW nNewRow1 = Max( nRow1, nRow );
     494                 :          0 :             SCROW nNewRow2 = Min( nRow2, nEndRow );
     495         [ #  # ]:          0 :             pAttrArray->ApplyCacheArea( nNewRow1, nNewRow2, &aCache );
     496                 :          0 :             nRow = nNewRow2;
     497                 :            :         }
     498         [ #  # ]:          0 :     }
     499                 :          0 : }
     500                 :            : 
     501                 :            : 
     502                 :          5 : void ScColumn::ApplyStyle( SCROW nRow, const ScStyleSheet& rStyle )
     503                 :            : {
     504                 :          5 :     const ScPatternAttr* pPattern = pAttrArray->GetPattern(nRow);
     505         [ +  - ]:          5 :     ScPatternAttr* pNewPattern = new ScPatternAttr(*pPattern);
     506         [ +  - ]:          5 :     if (pNewPattern)
     507                 :            :     {
     508                 :          5 :         pNewPattern->SetStyleSheet((ScStyleSheet*)&rStyle);
     509                 :          5 :         pAttrArray->SetPattern(nRow, pNewPattern, true);
     510         [ +  - ]:          5 :         delete pNewPattern;
     511                 :            :     }
     512                 :          5 : }
     513                 :            : 
     514                 :            : 
     515                 :       5545 : void ScColumn::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleSheet& rStyle )
     516                 :            : {
     517                 :       5545 :     pAttrArray->ApplyStyleArea(nStartRow, nEndRow, (ScStyleSheet*)&rStyle);
     518                 :       5545 : }
     519                 :            : 
     520                 :            : 
     521                 :     200704 : void ScColumn::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
     522                 :            : {
     523                 :            :     SCROW nTop;
     524                 :            :     SCROW nBottom;
     525                 :            : 
     526         [ +  - ]:     200704 :     if ( rMark.IsMultiMarked() )
     527                 :            :     {
     528         [ +  - ]:     200704 :         ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
     529 [ +  - ][ +  + ]:     202172 :         while (aMarkIter.Next( nTop, nBottom ))
     530 [ +  - ][ +  - ]:     202172 :             pAttrArray->ApplyStyleArea(nTop, nBottom, (ScStyleSheet*)&rStyle);
     531                 :            :     }
     532                 :     200704 : }
     533                 :            : 
     534                 :            : 
     535                 :          0 : void ScColumn::ApplySelectionLineStyle( const ScMarkData& rMark,
     536                 :            :                                     const SvxBorderLine* pLine, bool bColorOnly )
     537                 :            : {
     538 [ #  # ][ #  # ]:          0 :     if ( bColorOnly && !pLine )
     539                 :          0 :         return;
     540                 :            : 
     541                 :            :     SCROW nTop;
     542                 :            :     SCROW nBottom;
     543                 :            : 
     544         [ #  # ]:          0 :     if (rMark.IsMultiMarked())
     545                 :            :     {
     546         [ #  # ]:          0 :         ScMarkArrayIter aMarkIter( rMark.GetArray()+nCol );
     547 [ #  # ][ #  # ]:          0 :         while (aMarkIter.Next( nTop, nBottom ))
     548 [ #  # ][ #  # ]:          0 :             pAttrArray->ApplyLineStyleArea(nTop, nBottom, pLine, bColorOnly );
     549                 :            :     }
     550                 :            : }
     551                 :            : 
     552                 :            : 
     553                 :        112 : const ScStyleSheet* ScColumn::GetStyle( SCROW nRow ) const
     554                 :            : {
     555                 :        112 :     return pAttrArray->GetPattern( nRow )->GetStyleSheet();
     556                 :            : }
     557                 :            : 
     558                 :            : 
     559                 :         40 : const ScStyleSheet* ScColumn::GetSelectionStyle( const ScMarkData& rMark, bool& rFound ) const
     560                 :            : {
     561                 :         40 :     rFound = false;
     562         [ -  + ]:         40 :     if (!rMark.IsMultiMarked())
     563                 :            :     {
     564                 :            :         OSL_FAIL("ScColumn::GetSelectionStyle ohne Selektion");
     565                 :          0 :         return NULL;
     566                 :            :     }
     567                 :            : 
     568                 :         40 :     bool bEqual = true;
     569                 :            : 
     570                 :         40 :     const ScStyleSheet* pStyle = NULL;
     571                 :            :     const ScStyleSheet* pNewStyle;
     572                 :            : 
     573         [ +  - ]:         40 :     ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
     574                 :            :     SCROW nTop;
     575                 :            :     SCROW nBottom;
     576 [ +  - ][ +  - ]:         80 :     while (bEqual && aMarkIter.Next( nTop, nBottom ))
         [ +  + ][ +  + ]
     577                 :            :     {
     578         [ +  - ]:         40 :         ScAttrIterator aAttrIter( pAttrArray, nTop, nBottom );
     579                 :            :         SCROW nRow;
     580                 :            :         SCROW nDummy;
     581                 :            :         const ScPatternAttr* pPattern;
     582 [ +  - ][ +  - ]:        120 :         while (bEqual && ( pPattern = aAttrIter.Next( nRow, nDummy ) ) != NULL)
         [ +  + ][ +  + ]
     583                 :            :         {
     584                 :         80 :             pNewStyle = pPattern->GetStyleSheet();
     585                 :         80 :             rFound = true;
     586 [ +  + ][ -  + ]:         80 :             if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
                 [ +  - ]
     587                 :          0 :                 bEqual = false;                                             // unterschiedliche
     588                 :         80 :             pStyle = pNewStyle;
     589                 :            :         }
     590                 :            :     }
     591                 :            : 
     592 [ +  - ][ +  - ]:         40 :     return bEqual ? pStyle : NULL;
     593                 :            : }
     594                 :            : 
     595                 :            : 
     596                 :       8340 : const ScStyleSheet* ScColumn::GetAreaStyle( bool& rFound, SCROW nRow1, SCROW nRow2 ) const
     597                 :            : {
     598                 :       8340 :     rFound = false;
     599                 :            : 
     600                 :       8340 :     bool bEqual = true;
     601                 :            : 
     602                 :       8340 :     const ScStyleSheet* pStyle = NULL;
     603                 :            :     const ScStyleSheet* pNewStyle;
     604                 :            : 
     605         [ +  - ]:       8340 :     ScAttrIterator aAttrIter( pAttrArray, nRow1, nRow2 );
     606                 :            :     SCROW nRow;
     607                 :            :     SCROW nDummy;
     608                 :            :     const ScPatternAttr* pPattern;
     609 [ +  - ][ +  - ]:      16680 :     while (bEqual && ( pPattern = aAttrIter.Next( nRow, nDummy ) ) != NULL)
         [ +  + ][ +  + ]
     610                 :            :     {
     611                 :       8340 :         pNewStyle = pPattern->GetStyleSheet();
     612                 :       8340 :         rFound = true;
     613 [ -  + ][ #  # ]:       8340 :         if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
                 [ +  - ]
     614                 :          0 :             bEqual = false;                                             // unterschiedliche
     615                 :       8340 :         pStyle = pNewStyle;
     616                 :            :     }
     617                 :            : 
     618         [ +  - ]:       8340 :     return bEqual ? pStyle : NULL;
     619                 :            : }
     620                 :            : 
     621                 :    5344256 : void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
     622                 :            : {
     623                 :    5344256 :     pAttrArray->FindStyleSheet( pStyleSheet, rUsedRows, bReset );
     624                 :    5344256 : }
     625                 :            : 
     626                 :          0 : bool ScColumn::IsStyleSheetUsed( const ScStyleSheet& rStyle, bool bGatherAllStyles ) const
     627                 :            : {
     628                 :          0 :     return pAttrArray->IsStyleSheetUsed( rStyle, bGatherAllStyles );
     629                 :            : }
     630                 :            : 
     631                 :            : 
     632                 :       1422 : bool ScColumn::ApplyFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags )
     633                 :            : {
     634                 :       1422 :     return pAttrArray->ApplyFlags( nStartRow, nEndRow, nFlags );
     635                 :            : }
     636                 :            : 
     637                 :            : 
     638                 :      12119 : bool ScColumn::RemoveFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags )
     639                 :            : {
     640                 :      12119 :     return pAttrArray->RemoveFlags( nStartRow, nEndRow, nFlags );
     641                 :            : }
     642                 :            : 
     643                 :            : 
     644                 :          4 : void ScColumn::ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* pWhich )
     645                 :            : {
     646                 :          4 :     pAttrArray->ClearItems( nStartRow, nEndRow, pWhich );
     647                 :          4 : }
     648                 :            : 
     649                 :            : 
     650                 :        207 : void ScColumn::SetPattern( SCROW nRow, const ScPatternAttr& rPatAttr, bool bPutToPool )
     651                 :            : {
     652                 :        207 :     pAttrArray->SetPattern( nRow, &rPatAttr, bPutToPool );
     653                 :        207 : }
     654                 :            : 
     655                 :            : 
     656                 :         37 : void ScColumn::SetPatternArea( SCROW nStartRow, SCROW nEndRow,
     657                 :            :                                 const ScPatternAttr& rPatAttr, bool bPutToPool )
     658                 :            : {
     659                 :         37 :     pAttrArray->SetPatternArea( nStartRow, nEndRow, &rPatAttr, bPutToPool );
     660                 :         37 : }
     661                 :            : 
     662                 :            : 
     663                 :        874 : void ScColumn::ApplyAttr( SCROW nRow, const SfxPoolItem& rAttr )
     664                 :            : {
     665                 :            :     //  um nur ein neues SetItem zu erzeugen, brauchen wir keinen SfxItemPoolCache.
     666                 :            :     //! Achtung: der SfxItemPoolCache scheint zuviele Refs fuer das neue SetItem zu erzeugen ??
     667                 :            : 
     668                 :        874 :     ScDocumentPool* pDocPool = pDocument->GetPool();
     669                 :            : 
     670                 :        874 :     const ScPatternAttr* pOldPattern = pAttrArray->GetPattern( nRow );
     671         [ +  - ]:        874 :     ScPatternAttr* pTemp = new ScPatternAttr(*pOldPattern);
     672                 :        874 :     pTemp->GetItemSet().Put(rAttr);
     673                 :        874 :     const ScPatternAttr* pNewPattern = (const ScPatternAttr*) &pDocPool->Put( *pTemp );
     674                 :            : 
     675         [ +  + ]:        874 :     if ( pNewPattern != pOldPattern )
     676                 :        841 :         pAttrArray->SetPattern( nRow, pNewPattern );
     677                 :            :     else
     678                 :         33 :         pDocPool->Remove( *pNewPattern );       // ausser Spesen nichts gewesen
     679                 :            : 
     680         [ +  - ]:        874 :     delete pTemp;
     681                 :            : 
     682                 :            :         // alte Version mit SfxItemPoolCache:
     683                 :        874 : }
     684                 :            : 
     685                 :            : #ifdef _MSC_VER
     686                 :            : #pragma optimize ( "", off )
     687                 :            : #endif
     688                 :            : 
     689                 :            : 
     690                 :    6278583 : bool ScColumn::Search( SCROW nRow, SCSIZE& nIndex ) const
     691                 :            : {
     692         [ +  + ]:    6278583 :     if ( maItems.empty() )
     693                 :            :     {
     694                 :    6135576 :         nIndex = 0;
     695                 :    6135576 :         return false;
     696                 :            :     }
     697                 :     143007 :     SCROW nMinRow = maItems[0].nRow;
     698         [ +  + ]:     143007 :     if ( nRow <= nMinRow )
     699                 :            :     {
     700                 :      68791 :         nIndex = 0;
     701                 :      68791 :         return nRow == nMinRow;
     702                 :            :     }
     703                 :      74216 :     SCROW nMaxRow = maItems.back().nRow;
     704         [ +  + ]:      74216 :     if ( nRow >= nMaxRow )
     705                 :            :     {
     706         [ +  + ]:      29958 :         if ( nRow == nMaxRow )
     707                 :            :         {
     708                 :      11619 :             nIndex = maItems.size() - 1;
     709                 :      11619 :             return true;
     710                 :            :         }
     711                 :            :         else
     712                 :            :         {
     713                 :      18339 :             nIndex = maItems.size();
     714                 :      18339 :             return false;
     715                 :            :         }
     716                 :            :     }
     717                 :            : 
     718                 :            :     long nOldLo, nOldHi;
     719                 :      44258 :     long    nLo     = nOldLo = 0;
     720                 :      44258 :     long    nHi     = nOldHi = Min(static_cast<long>(maItems.size())-1, static_cast<long>(nRow) );
     721                 :      44258 :     long    i       = 0;
     722                 :      44258 :     bool    bFound  = false;
     723                 :            :     // quite continuous distribution? => interpolating search
     724                 :      44258 :     bool    bInterpol = (static_cast<SCSIZE>(nMaxRow - nMinRow) < maItems.size() * 2);
     725                 :            :     SCROW   nR;
     726                 :            : 
     727 [ +  + ][ +  + ]:     113260 :     while ( !bFound && nLo <= nHi )
                 [ +  + ]
     728                 :            :     {
     729 [ +  + ][ +  + ]:      69002 :         if ( !bInterpol || nHi - nLo < 3 )
     730                 :      43727 :             i = (nLo+nHi) / 2;          // no effort, no division by zero
     731                 :            :         else
     732                 :            :         {   // interpolating search
     733                 :      25275 :             long nLoRow = maItems[nLo].nRow;     // no unsigned underflow upon substraction
     734                 :            :             i = nLo + (long)((long)(nRow - nLoRow) * (nHi - nLo)
     735                 :      25275 :                 / (maItems[nHi].nRow - nLoRow));
     736 [ +  + ][ +  + ]:      25275 :             if ( i < 0 || static_cast<SCSIZE>(i) >= maItems.size() )
                 [ +  + ]
     737                 :            :             {   // oops ...
     738                 :         52 :                 i = (nLo+nHi) / 2;
     739                 :         52 :                 bInterpol = false;
     740                 :            :             }
     741                 :            :         }
     742                 :      69002 :         nR = maItems[i].nRow;
     743         [ +  + ]:      69002 :         if ( nR < nRow )
     744                 :            :         {
     745                 :      22999 :             nLo = i+1;
     746         [ +  + ]:      22999 :             if ( bInterpol )
     747                 :            :             {
     748         [ +  + ]:      19180 :                 if ( nLo <= nOldLo )
     749                 :        144 :                     bInterpol = false;
     750                 :            :                 else
     751                 :      19036 :                     nOldLo = nLo;
     752                 :            :             }
     753                 :            :         }
     754                 :            :         else
     755                 :            :         {
     756         [ +  + ]:      46003 :             if ( nR > nRow )
     757                 :            :             {
     758                 :       4708 :                 nHi = i-1;
     759         [ +  + ]:       4708 :                 if ( bInterpol )
     760                 :            :                 {
     761         [ +  + ]:       2019 :                     if ( nHi >= nOldHi )
     762                 :          3 :                         bInterpol = false;
     763                 :            :                     else
     764                 :       2016 :                         nOldHi = nHi;
     765                 :            :                 }
     766                 :            :             }
     767                 :            :             else
     768                 :      41295 :                 bFound = true;
     769                 :            :         }
     770                 :            :     }
     771         [ +  + ]:      44258 :     if (bFound)
     772                 :      41295 :         nIndex = static_cast<SCSIZE>(i);
     773                 :            :     else
     774                 :       2963 :         nIndex = static_cast<SCSIZE>(nLo); // rear index
     775                 :    6278583 :     return bFound;
     776                 :            : }
     777                 :            : 
     778                 :            : #ifdef _MSC_VER
     779                 :            : #pragma optimize ( "", on )
     780                 :            : #endif
     781                 :            : 
     782                 :            : 
     783                 :      33756 : ScBaseCell* ScColumn::GetCell( SCROW nRow ) const
     784                 :            : {
     785                 :            :     SCSIZE nIndex;
     786 [ +  - ][ +  + ]:      33756 :     if (Search(nRow, nIndex))
     787                 :      25531 :         return maItems[nIndex].pCell;
     788                 :      33756 :     return NULL;
     789                 :            : }
     790                 :            : 
     791                 :            : 
     792                 :       1301 : void ScColumn::Resize( SCSIZE nSize )
     793                 :            : {
     794         [ -  + ]:       1301 :     if (nSize > sal::static_int_cast<SCSIZE>(MAXROWCOUNT))
     795                 :          0 :         nSize = MAXROWCOUNT;
     796         [ -  + ]:       1301 :     if (nSize < maItems.size())
     797                 :          0 :         nSize = maItems.size();
     798                 :            : 
     799                 :       1301 :     maItems.reserve(nSize);
     800                 :       1301 : }
     801                 :            : 
     802                 :            : //  SwapRow zum Sortieren
     803                 :            : 
     804                 :            : namespace {
     805                 :            : 
     806                 :            : /** Moves broadcaster from old cell to new cell if exists, otherwise creates a new note cell. */
     807                 :          0 : void lclTakeBroadcaster( ScBaseCell*& rpCell, SvtBroadcaster* pBC )
     808                 :            : {
     809         [ #  # ]:          0 :     if( pBC )
     810                 :            :     {
     811         [ #  # ]:          0 :         if( rpCell )
     812                 :          0 :             rpCell->TakeBroadcaster( pBC );
     813                 :            :         else
     814         [ #  # ]:          0 :             rpCell = new ScNoteCell( pBC );
     815                 :            :     }
     816                 :          0 : }
     817                 :            : 
     818                 :            : } // namespace
     819                 :            : 
     820                 :         72 : void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
     821                 :            : {
     822                 :            :     /*  Simple swap of cell pointers does not work if broadcasters exist (crash
     823                 :            :         if cell broadcasts directly or indirectly to itself). While swapping
     824                 :            :         the cells, broadcasters have to remain at old positions! */
     825                 :            : 
     826                 :            :     /*  While cloning cells, do not clone notes, but move note pointers to new
     827                 :            :         cells. This prevents creation of new caption drawing objects for every
     828                 :            :         swap operation while sorting. */
     829                 :            : 
     830                 :         72 :     ScBaseCell* pCell1 = 0;
     831                 :            :     SCSIZE nIndex1;
     832 [ +  - ][ +  + ]:         72 :     if ( Search( nRow1, nIndex1 ) )
     833                 :         24 :         pCell1 = maItems[nIndex1].pCell;
     834                 :            : 
     835                 :         72 :     ScBaseCell* pCell2 = 0;
     836                 :            :     SCSIZE nIndex2;
     837 [ +  - ][ +  + ]:         72 :     if ( Search( nRow2, nIndex2 ) )
     838                 :         25 :         pCell2 = maItems[nIndex2].pCell;
     839                 :            : 
     840                 :            :     // no cells found, nothing to do
     841 [ +  + ][ +  + ]:         72 :     if ( !pCell1 && !pCell2 )
     842                 :            :         return ;
     843                 :            : 
     844                 :            :     // swap variables if first cell is empty, to save some code below
     845         [ +  + ]:         31 :     if ( !pCell1 )
     846                 :            :     {
     847                 :          7 :         ::std::swap( nRow1, nRow2 );
     848                 :          7 :         ::std::swap( nIndex1, nIndex2 );
     849                 :          7 :         ::std::swap( pCell1, pCell2 );
     850                 :            :     }
     851                 :            : 
     852                 :            :     // from here: first cell (pCell1, nIndex1) exists always
     853                 :            : 
     854                 :         31 :     ScAddress aPos1( nCol, nRow1, nTab );
     855                 :         31 :     ScAddress aPos2( nCol, nRow2, nTab );
     856                 :            : 
     857                 :         31 :     CellType eType1 = pCell1->GetCellType();
     858         [ +  + ]:         31 :     CellType eType2 = pCell2 ? pCell2->GetCellType() : CELLTYPE_NONE;
     859                 :            : 
     860 [ -  + ][ #  # ]:         31 :     ScFormulaCell* pFmlaCell1 = (eType1 == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell1 ) : 0;
     861 [ -  + ][ #  # ]:         31 :     ScFormulaCell* pFmlaCell2 = (eType2 == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell2 ) : 0;
     862                 :            : 
     863                 :            :     // simple swap if no formula cells present
     864 [ +  - ][ +  - ]:         31 :     if ( !pFmlaCell1 && !pFmlaCell2 )
     865                 :            :     {
     866                 :            :         // remember cell broadcasters, must remain at old position
     867         [ +  - ]:         31 :         SvtBroadcaster* pBC1 = pCell1->ReleaseBroadcaster();
     868                 :            : 
     869         [ +  + ]:         31 :         if ( pCell2 )
     870                 :            :         {
     871                 :            :             /*  Both cells exist, no formula cells involved, a simple swap can
     872                 :            :                 be performed (but keep broadcasters and notes at old position). */
     873                 :         18 :             maItems[nIndex1].pCell = pCell2;
     874                 :         18 :             maItems[nIndex2].pCell = pCell1;
     875                 :            : 
     876         [ +  - ]:         18 :             SvtBroadcaster* pBC2 = pCell2->ReleaseBroadcaster();
     877         [ +  - ]:         18 :             pCell1->TakeBroadcaster( pBC2 );
     878         [ +  - ]:         18 :             pCell2->TakeBroadcaster( pBC1 );
     879                 :            :         }
     880                 :            :         else
     881                 :            :         {
     882 [ -  + ][ #  # ]:         13 :             ScNoteCell* pDummyCell = pBC1 ? new ScNoteCell( pBC1 ) : 0;
                 [ #  # ]
     883         [ -  + ]:         13 :             if ( pDummyCell )
     884                 :            :             {
     885                 :            :                 // insert dummy note cell (without note) containing old broadcaster
     886                 :          0 :                 maItems[nIndex1].pCell = pDummyCell;
     887                 :            :             }
     888                 :            :             else
     889                 :            :             {
     890                 :            :                 // remove ColEntry at old position
     891 [ +  - ][ +  - ]:         13 :                 maItems.erase( maItems.begin() + nIndex1 );
     892                 :            :             }
     893                 :            : 
     894                 :            :             // insert ColEntry at new position
     895         [ +  - ]:         13 :             Insert( nRow2, pCell1 );
     896                 :            :         }
     897                 :            : 
     898                 :            :         return;
     899                 :            :     }
     900                 :            : 
     901                 :            :     // from here: at least one of the cells is a formula cell
     902                 :            : 
     903                 :            :     /*  Never move any array formulas. Disabling sort if parts of array
     904                 :            :         formulas are contained is done at UI. */
     905 [ #  # ][ #  # ]:          0 :     if ( (pFmlaCell1 && (pFmlaCell1->GetMatrixFlag() != 0)) || (pFmlaCell2 && (pFmlaCell2->GetMatrixFlag() != 0)) )
         [ #  # ][ #  # ]
                 [ #  # ]
     906                 :            :         return;
     907                 :            : 
     908                 :            :     // do not swap, if formulas are equal
     909 [ #  # ][ #  # ]:          0 :     if ( pFmlaCell1 && pFmlaCell2 )
     910                 :            :     {
     911                 :          0 :         ScTokenArray* pCode1 = pFmlaCell1->GetCode();
     912                 :          0 :         ScTokenArray* pCode2 = pFmlaCell2->GetCode();
     913                 :            : 
     914         [ #  # ]:          0 :         if (pCode1->GetLen() == pCode2->GetLen())       // nicht-UPN
     915                 :            :         {
     916                 :          0 :             bool bEqual = true;
     917                 :          0 :             sal_uInt16 nLen = pCode1->GetLen();
     918                 :          0 :             FormulaToken** ppToken1 = pCode1->GetArray();
     919                 :          0 :             FormulaToken** ppToken2 = pCode2->GetArray();
     920         [ #  # ]:          0 :             for (sal_uInt16 i=0; i<nLen; i++)
     921                 :            :             {
     922 [ #  # ][ #  # ]:          0 :                 if ( !ppToken1[i]->TextEqual(*(ppToken2[i])) ||
         [ #  # ][ #  # ]
                 [ #  # ]
     923 [ #  # ][ #  # ]:          0 :                         ppToken1[i]->Is3DRef() || ppToken2[i]->Is3DRef() )
     924                 :            :                 {
     925                 :          0 :                     bEqual = false;
     926                 :          0 :                     break;
     927                 :            :                 }
     928                 :            :             }
     929                 :            : 
     930                 :            :             // do not swap formula cells with equal formulas
     931         [ #  # ]:          0 :             if (bEqual)
     932                 :            :             {
     933                 :            :                 return;
     934                 :            :             }
     935                 :            :         }
     936                 :            :     }
     937                 :            : 
     938                 :            :     /*  Create clone of pCell1 at position of pCell2 (pCell1 exists always, see
     939                 :            :         variable swapping above). Do not clone the note, but move pointer of
     940                 :            :         old note to new cell. */
     941         [ #  # ]:          0 :     ScBaseCell* pNew2 = pCell1->Clone( *pDocument, aPos2, SC_CLONECELL_ADJUST3DREL );
     942                 :            : 
     943                 :            :     /*  Create clone of pCell2 at position of pCell1. Do not clone the note,
     944                 :            :         but move pointer of old note to new cell. */
     945                 :          0 :     ScBaseCell* pNew1 = 0;
     946         [ #  # ]:          0 :     if ( pCell2 )
     947                 :            :     {
     948         [ #  # ]:          0 :         pNew1 = pCell2->Clone( *pDocument, aPos1, SC_CLONECELL_ADJUST3DREL );
     949                 :            :     }
     950                 :            : 
     951                 :            :     // move old broadcasters new cells at the same old position
     952         [ #  # ]:          0 :     SvtBroadcaster* pBC1 = pCell1->ReleaseBroadcaster();
     953         [ #  # ]:          0 :     lclTakeBroadcaster( pNew1, pBC1 );
     954 [ #  # ][ #  # ]:          0 :     SvtBroadcaster* pBC2 = pCell2 ? pCell2->ReleaseBroadcaster() : 0;
     955         [ #  # ]:          0 :     lclTakeBroadcaster( pNew2, pBC2 );
     956                 :            : 
     957                 :            :     /*  Insert the new cells. Old cell has to be deleted, if there is no new
     958                 :            :         cell (call to Insert deletes old cell by itself). */
     959         [ #  # ]:          0 :     if ( !pNew1 )
     960         [ #  # ]:          0 :         Delete( nRow1 );            // deletes pCell1
     961                 :            :     else
     962         [ #  # ]:          0 :         Insert( nRow1, pNew1 );     // deletes pCell1, inserts pNew1
     963                 :            : 
     964 [ #  # ][ #  # ]:          0 :     if ( pCell2 && !pNew2 )
     965         [ #  # ]:          0 :         Delete( nRow2 );            // deletes pCell2
     966         [ #  # ]:          0 :     else if ( pNew2 )
     967         [ #  # ]:         72 :         Insert( nRow2, pNew2 );     // deletes pCell2 (if existing), inserts pNew2
     968                 :            : }
     969                 :            : 
     970                 :            : 
     971                 :          0 : void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
     972                 :            : {
     973                 :          0 :     ScBaseCell* pCell1 = 0;
     974                 :            :     SCSIZE nIndex1;
     975 [ #  # ][ #  # ]:          0 :     if ( Search( nRow, nIndex1 ) )
     976                 :          0 :         pCell1 = maItems[nIndex1].pCell;
     977                 :            : 
     978                 :          0 :     ScBaseCell* pCell2 = 0;
     979                 :            :     SCSIZE nIndex2;
     980 [ #  # ][ #  # ]:          0 :     if ( rCol.Search( nRow, nIndex2 ) )
     981                 :          0 :         pCell2 = rCol.maItems[nIndex2].pCell;
     982                 :            : 
     983                 :            :     // reverse call if own cell is missing (ensures own existing cell in following code)
     984         [ #  # ]:          0 :     if( !pCell1 )
     985                 :            :     {
     986         [ #  # ]:          0 :         if( pCell2 )
     987         [ #  # ]:          0 :             rCol.SwapCell( nRow, *this );
     988                 :          0 :         return;
     989                 :            :     }
     990                 :            : 
     991                 :            :     // from here: own cell (pCell1, nIndex1) exists always
     992                 :            : 
     993 [ #  # ][ #  # ]:          0 :     ScFormulaCell* pFmlaCell1 = (pCell1->GetCellType() == CELLTYPE_FORMULA) ? static_cast< ScFormulaCell* >( pCell1 ) : 0;
     994 [ #  # ][ #  # ]:          0 :     ScFormulaCell* pFmlaCell2 = (pCell2 && (pCell2->GetCellType() == CELLTYPE_FORMULA)) ? static_cast< ScFormulaCell* >( pCell2 ) : 0;
                 [ #  # ]
     995                 :            : 
     996         [ #  # ]:          0 :     if ( pCell2 )
     997                 :            :     {
     998                 :            :         // Tauschen
     999                 :          0 :         maItems[nIndex1].pCell = pCell2;
    1000                 :          0 :         rCol.maItems[nIndex2].pCell = pCell1;
    1001                 :            :         // Referenzen aktualisieren
    1002                 :          0 :         SCsCOL dx = rCol.nCol - nCol;
    1003         [ #  # ]:          0 :         if ( pFmlaCell1 )
    1004                 :            :         {
    1005                 :            :             ScRange aRange( ScAddress( rCol.nCol, 0, nTab ),
    1006                 :          0 :                             ScAddress( rCol.nCol, MAXROW, nTab ) );
    1007                 :          0 :             pFmlaCell1->aPos.SetCol( rCol.nCol );
    1008         [ #  # ]:          0 :             pFmlaCell1->UpdateReference(URM_MOVE, aRange, dx, 0, 0);
    1009                 :            :         }
    1010         [ #  # ]:          0 :         if ( pFmlaCell2 )
    1011                 :            :         {
    1012                 :            :             ScRange aRange( ScAddress( nCol, 0, nTab ),
    1013                 :          0 :                             ScAddress( nCol, MAXROW, nTab ) );
    1014                 :          0 :             pFmlaCell2->aPos.SetCol( nCol );
    1015         [ #  # ]:          0 :             pFmlaCell2->UpdateReference(URM_MOVE, aRange, -dx, 0, 0);
    1016                 :            :         }
    1017                 :            :     }
    1018                 :            :     else
    1019                 :            :     {
    1020                 :            :         // Loeschen
    1021 [ #  # ][ #  # ]:          0 :         maItems.erase(maItems.begin() + nIndex1);
    1022                 :            :         // Referenzen aktualisieren
    1023                 :          0 :         SCsCOL dx = rCol.nCol - nCol;
    1024         [ #  # ]:          0 :         if ( pFmlaCell1 )
    1025                 :            :         {
    1026                 :            :             ScRange aRange( ScAddress( rCol.nCol, 0, nTab ),
    1027                 :          0 :                             ScAddress( rCol.nCol, MAXROW, nTab ) );
    1028                 :          0 :             pFmlaCell1->aPos.SetCol( rCol.nCol );
    1029         [ #  # ]:          0 :             pFmlaCell1->UpdateReference(URM_MOVE, aRange, dx, 0, 0);
    1030                 :            :         }
    1031                 :            :         // Einfuegen
    1032         [ #  # ]:          0 :         rCol.Insert(nRow, pCell1);
    1033                 :            :     }
    1034                 :            : }
    1035                 :            : 
    1036                 :            : 
    1037                 :          7 : bool ScColumn::TestInsertCol( SCROW nStartRow, SCROW nEndRow) const
    1038                 :            : {
    1039         [ -  + ]:          7 :     if (!IsEmpty())
    1040                 :            :     {
    1041                 :          0 :         bool bTest = true;
    1042         [ #  # ]:          0 :         if ( !maItems.empty() )
    1043 [ #  # ][ #  # ]:          0 :             for (SCSIZE i=0; (i<maItems.size()) && bTest; i++)
                 [ #  # ]
    1044                 :          0 :                 bTest = (maItems[i].nRow < nStartRow) || (maItems[i].nRow > nEndRow)
    1045         [ #  # ]:          0 :                         || maItems[i].pCell->IsBlank();
           [ #  #  #  # ]
    1046                 :            : 
    1047                 :            :         //  AttrArray testet nur zusammengefasste
    1048                 :            : 
    1049 [ #  # ][ #  # ]:          0 :         if ((bTest) && (pAttrArray))
    1050                 :          0 :             bTest = pAttrArray->TestInsertCol(nStartRow, nEndRow);
    1051                 :            : 
    1052                 :            :         //!     rausgeschobene Attribute bei Undo beruecksichtigen
    1053                 :            : 
    1054                 :          0 :         return bTest;
    1055                 :            :     }
    1056                 :            :     else
    1057                 :          7 :         return true;
    1058                 :            : }
    1059                 :            : 
    1060                 :            : 
    1061                 :      18735 : bool ScColumn::TestInsertRow( SCSIZE nSize ) const
    1062                 :            : {
    1063                 :            :     //  AttrArray only looks for merged cells
    1064                 :            : 
    1065         [ +  + ]:      18735 :     if ( !maItems.empty() )
    1066                 :         20 :         return ( nSize <= sal::static_int_cast<SCSIZE>(MAXROW) &&
    1067 [ +  - ][ +  - ]:         20 :                  maItems[maItems.size()-1].nRow <= MAXROW-(SCROW)nSize && pAttrArray->TestInsertRow( nSize ) );
                 [ +  - ]
    1068                 :            :     else
    1069                 :      18735 :         return pAttrArray->TestInsertRow( nSize );
    1070                 :            : }
    1071                 :            : 
    1072                 :            : 
    1073                 :      18735 : void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
    1074                 :            : {
    1075         [ +  - ]:      18735 :     pAttrArray->InsertRow( nStartRow, nSize );
    1076                 :            : 
    1077                 :            :     //! Search
    1078                 :            : 
    1079         [ +  + ]:      18735 :     if ( maItems.empty() )
    1080                 :            :         return;
    1081                 :            : 
    1082                 :            :     SCSIZE i;
    1083         [ +  - ]:         20 :     Search( nStartRow, i );
    1084         [ +  + ]:         20 :     if ( i >= maItems.size() )
    1085                 :            :         return ;
    1086                 :            : 
    1087                 :          8 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1088         [ +  - ]:          8 :     pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
    1089                 :            : 
    1090                 :          8 :     SCSIZE nNewCount = maItems.size();
    1091                 :          8 :     bool bCountChanged = false;
    1092                 :          8 :     ScAddress aAdr( nCol, 0, nTab );
    1093         [ +  - ]:          8 :     ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL );    // only areas (ScBaseCell* == NULL)
    1094                 :          8 :     ScAddress& rAddress = aHint.GetAddress();
    1095                 :            :     // for sparse occupation use single broadcasts, not ranges
    1096         [ +  - ]:          8 :     bool bSingleBroadcasts = (((maItems.back().nRow - maItems[i].nRow) /
    1097                 :          8 :                 (maItems.size() - i)) > 1);
    1098         [ -  + ]:          8 :     if ( bSingleBroadcasts )
    1099                 :            :     {
    1100                 :          0 :         SCROW nLastBroadcast = MAXROW+1;
    1101         [ #  # ]:          0 :         for ( ; i < maItems.size(); i++)
    1102                 :            :         {
    1103                 :          0 :             SCROW nOldRow = maItems[i].nRow;
    1104                 :            :             // Change source broadcaster
    1105         [ #  # ]:          0 :             if ( nLastBroadcast != nOldRow )
    1106                 :            :             {   // Do not broadcast a direct sequence twice
    1107                 :          0 :                 rAddress.SetRow( nOldRow );
    1108         [ #  # ]:          0 :                 pDocument->AreaBroadcast( aHint );
    1109                 :            :             }
    1110                 :          0 :             SCROW nNewRow = (maItems[i].nRow += nSize);
    1111                 :            :             // Change target broadcaster
    1112                 :          0 :             rAddress.SetRow( nNewRow );
    1113         [ #  # ]:          0 :             pDocument->AreaBroadcast( aHint );
    1114                 :          0 :             nLastBroadcast = nNewRow;
    1115                 :          0 :             ScBaseCell* pCell = maItems[i].pCell;
    1116         [ #  # ]:          0 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1117         [ #  # ]:          0 :                 ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
    1118 [ #  # ][ #  # ]:          0 :             if ( nNewRow > MAXROW && !bCountChanged )
    1119                 :            :             {
    1120                 :          0 :                 nNewCount = i;
    1121                 :          0 :                 bCountChanged = true;
    1122                 :            :             }
    1123                 :            :         }
    1124                 :            :     }
    1125                 :            :     else
    1126                 :            :     {
    1127                 :          8 :         rAddress.SetRow( maItems[i].nRow );
    1128                 :          8 :         ScRange aRange( rAddress );
    1129         [ +  + ]:         16 :         for ( ; i < maItems.size(); i++)
    1130                 :            :         {
    1131                 :          8 :             SCROW nNewRow = (maItems[i].nRow += nSize);
    1132                 :          8 :             ScBaseCell* pCell = maItems[i].pCell;
    1133         [ -  + ]:          8 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1134         [ #  # ]:          0 :                 ((ScFormulaCell*)pCell)->aPos.SetRow( nNewRow );
    1135 [ -  + ][ #  # ]:          8 :             if ( nNewRow > MAXROW && !bCountChanged )
    1136                 :            :             {
    1137                 :          0 :                 nNewCount = i;
    1138                 :          0 :                 bCountChanged = true;
    1139                 :          0 :                 aRange.aEnd.SetRow( MAXROW );
    1140                 :            :             }
    1141                 :            :         }
    1142         [ +  - ]:          8 :         if ( !bCountChanged )
    1143         [ +  - ]:          8 :             aRange.aEnd.SetRow( maItems.back().nRow );
    1144         [ +  - ]:          8 :         pDocument->AreaBroadcastInRange( aRange, aHint );
    1145                 :            :     }
    1146                 :            : 
    1147         [ -  + ]:          8 :     if (bCountChanged)
    1148                 :            :     {
    1149                 :          0 :         SCSIZE nDelCount = maItems.size() - nNewCount;
    1150         [ #  # ]:          0 :         ScBaseCell** ppDelCells = new ScBaseCell*[nDelCount];
    1151         [ #  # ]:          0 :         SCROW* pDelRows = new SCROW[nDelCount];
    1152         [ #  # ]:          0 :         for (i = 0; i < nDelCount; i++)
    1153                 :            :         {
    1154                 :          0 :             ppDelCells[i] = maItems[nNewCount+i].pCell;
    1155                 :          0 :             pDelRows[i] = maItems[nNewCount+i].nRow;
    1156                 :            :         }
    1157         [ #  # ]:          0 :         maItems.resize( nNewCount );
    1158                 :            : 
    1159         [ #  # ]:          0 :         for (i = 0; i < nDelCount; i++)
    1160                 :            :         {
    1161                 :          0 :             ScBaseCell* pCell = ppDelCells[i];
    1162                 :            :             OSL_ENSURE( pCell->IsBlank(), "sichtbare Zelle weggeschoben" );
    1163                 :          0 :             SvtBroadcaster* pBC = pCell->GetBroadcaster();
    1164         [ #  # ]:          0 :             if (pBC)
    1165                 :            :             {
    1166         [ #  # ]:          0 :                 MoveListeners( *pBC, pDelRows[i] - nSize );
    1167         [ #  # ]:          0 :                 pCell->DeleteBroadcaster();
    1168         [ #  # ]:          0 :                 pCell->Delete();
    1169                 :            :             }
    1170                 :            :         }
    1171                 :            : 
    1172         [ #  # ]:          0 :         delete [] pDelRows;
    1173         [ #  # ]:          0 :         delete [] ppDelCells;
    1174                 :            :     }
    1175                 :            : 
    1176 [ +  - ][ +  - ]:      18735 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1177                 :            : }
    1178                 :            : 
    1179                 :            : 
    1180                 :         21 : void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, bool bKeepScenarioFlags)
    1181                 :            : {
    1182                 :            :     pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray,
    1183         [ -  + ]:         21 :                             bKeepScenarioFlags ? (SC_MF_ALL & ~SC_MF_SCENARIO) : SC_MF_ALL );
    1184                 :            : 
    1185                 :            :     SCSIZE i;
    1186                 :         21 :     SCSIZE nBlockCount = 0;
    1187                 :         21 :     SCSIZE nStartIndex = 0, nEndIndex = 0;
    1188         [ +  + ]:         63 :     for (i = 0; i < maItems.size(); i++)
    1189 [ +  - ][ +  - ]:         42 :         if ((maItems[i].nRow >= nRow1) && (maItems[i].nRow <= nRow2))
                 [ +  - ]
    1190                 :            :         {
    1191         [ +  + ]:         42 :             if (!nBlockCount)
    1192                 :         15 :                 nStartIndex = i;
    1193                 :         42 :             nEndIndex = i;
    1194                 :         42 :             ++nBlockCount;
    1195                 :            : 
    1196                 :            :             //  im Clipboard muessen interpretierte Zellen stehen, um andere Formate
    1197                 :            :             //  (Text, Grafik...) erzueugen zu koennen
    1198                 :            : 
    1199         [ +  + ]:         42 :             if ( maItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
    1200                 :            :             {
    1201         [ +  - ]:         36 :                 ScFormulaCell* pFCell = (ScFormulaCell*) maItems[i].pCell;
    1202 [ +  + ][ +  - ]:         36 :                 if (pFCell->GetDirty() && pDocument->GetAutoCalc())
                 [ +  + ]
    1203                 :         27 :                     pFCell->Interpret();
    1204                 :            :             }
    1205                 :            :         }
    1206                 :            : 
    1207         [ +  + ]:         21 :     if (nBlockCount)
    1208                 :            :     {
    1209 [ +  - ][ +  - ]:         15 :         rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
    1210                 :         15 :         ScAddress aOwnPos( nCol, 0, nTab );
    1211                 :         15 :         ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
    1212         [ +  + ]:         57 :         for (i = nStartIndex; i <= nEndIndex; i++)
    1213                 :            :         {
    1214                 :         42 :             aOwnPos.SetRow( maItems[i].nRow );
    1215                 :         42 :             aDestPos.SetRow( maItems[i].nRow );
    1216         [ +  - ]:         42 :             ScBaseCell* pNewCell = maItems[i].pCell->Clone( *rColumn.pDocument, aDestPos, SC_CLONECELL_DEFAULT );
    1217         [ +  - ]:         42 :             rColumn.Append( aDestPos.Row(), pNewCell );
    1218                 :            :         }
    1219                 :            :     }
    1220                 :         21 : }
    1221                 :            : 
    1222                 :            : 
    1223                 :      70483 : void ScColumn::CopyToColumn(SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked,
    1224                 :            :                                 ScColumn& rColumn, const ScMarkData* pMarkData, bool bAsLink )
    1225                 :            : {
    1226         [ +  + ]:      70483 :     if (bMarked)
    1227                 :            :     {
    1228                 :            :         SCROW nStart, nEnd;
    1229 [ +  - ][ +  - ]:       1395 :         if (pMarkData && pMarkData->IsMultiMarked())
                 [ +  - ]
    1230                 :            :         {
    1231         [ +  - ]:       1395 :             ScMarkArrayIter aIter( pMarkData->GetArray()+nCol );
    1232                 :            : 
    1233 [ +  - ][ +  + ]:       1780 :             while ( aIter.Next( nStart, nEnd ) && nStart <= nRow2 )
         [ +  - ][ +  + ]
    1234                 :            :             {
    1235         [ +  - ]:        385 :                 if ( nEnd >= nRow1 )
    1236                 :            :                     CopyToColumn( Max(nRow1,nStart), Min(nRow2,nEnd),
    1237         [ +  - ]:        385 :                                     nFlags, false, rColumn, pMarkData, bAsLink );
    1238         [ +  - ]:       1395 :             }
    1239                 :            :         }
    1240                 :            :         else
    1241                 :            :         {
    1242                 :            :             OSL_FAIL("CopyToColumn: bMarked, aber keine Markierung");
    1243                 :            :         }
    1244                 :      70483 :         return;
    1245                 :            :     }
    1246                 :            : 
    1247         [ +  + ]:      69088 :     if ( (nFlags & IDF_ATTRIB) != 0 )
    1248                 :            :     {
    1249         [ -  + ]:      52328 :         if ( (nFlags & IDF_STYLES) != IDF_STYLES )
    1250                 :            :         {   // StyleSheets im Zieldokument bleiben erhalten
    1251                 :            :             // z.B. DIF und RTF Clipboard-Import
    1252         [ #  # ]:          0 :             for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ )
    1253                 :            :             {
    1254                 :            :                 const ScStyleSheet* pStyle =
    1255                 :          0 :                     rColumn.pAttrArray->GetPattern( nRow )->GetStyleSheet();
    1256                 :          0 :                 const ScPatternAttr* pPattern = pAttrArray->GetPattern( nRow );
    1257         [ #  # ]:          0 :                 ScPatternAttr* pNewPattern = new ScPatternAttr( *pPattern );
    1258                 :          0 :                 pNewPattern->SetStyleSheet( (ScStyleSheet*)pStyle );
    1259                 :          0 :                 rColumn.pAttrArray->SetPattern( nRow, pNewPattern, true );
    1260         [ #  # ]:          0 :                 delete pNewPattern;
    1261                 :            :             }
    1262                 :            :         }
    1263                 :            :         else
    1264                 :      52328 :             pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray);
    1265                 :            :     }
    1266                 :            : 
    1267                 :            : 
    1268         [ +  + ]:      69088 :     if ((nFlags & IDF_CONTENTS) != 0)
    1269                 :            :     {
    1270                 :            :         SCSIZE i;
    1271                 :      64841 :         SCSIZE nBlockCount = 0;
    1272                 :      64841 :         SCSIZE nStartIndex = 0, nEndIndex = 0;
    1273         [ +  + ]:      68750 :         for (i = 0; i < maItems.size(); i++)
    1274 [ +  + ][ +  + ]:       3909 :             if ((maItems[i].nRow >= nRow1) && (maItems[i].nRow <= nRow2))
                 [ +  + ]
    1275                 :            :             {
    1276         [ +  + ]:       3414 :                 if (!nBlockCount)
    1277                 :        833 :                     nStartIndex = i;
    1278                 :       3414 :                 nEndIndex = i;
    1279                 :       3414 :                 ++nBlockCount;
    1280                 :            :             }
    1281                 :            : 
    1282         [ +  + ]:      64841 :         if (nBlockCount)
    1283                 :            :         {
    1284 [ +  - ][ +  - ]:        833 :             rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
    1285                 :        833 :             ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
    1286         [ +  + ]:       4247 :             for (i = nStartIndex; i <= nEndIndex; i++)
    1287                 :            :             {
    1288                 :       3414 :                 aDestPos.SetRow( maItems[i].nRow );
    1289                 :            :                 ScBaseCell* pNew = bAsLink ?
    1290         [ #  # ]:          0 :                     CreateRefCell( rColumn.pDocument, aDestPos, i, nFlags ) :
    1291 [ #  # ][ +  - ]:       3414 :                     CloneCell( i, nFlags, *rColumn.pDocument, aDestPos );
                 [ -  + ]
    1292                 :            : 
    1293         [ +  + ]:       3414 :                 if (pNew)
    1294                 :            :                 {
    1295                 :            :                     // Special case to allow removing of cell instances.  A
    1296                 :            :                     // string cell with empty content is used to indicate an
    1297                 :            :                     // empty cell.
    1298         [ +  + ]:       3193 :                     if (pNew->GetCellType() == CELLTYPE_STRING)
    1299                 :            :                     {
    1300                 :       1235 :                         rtl::OUString aStr = static_cast<ScStringCell*>(pNew)->GetString();
    1301         [ -  + ]:       1235 :                         if (aStr.isEmpty())
    1302                 :            :                             // A string cell with empty string.  Delete the cell itself.
    1303         [ #  # ]:          0 :                             rColumn.Delete(maItems[i].nRow);
    1304                 :            :                         else
    1305                 :            :                             // non-empty string cell
    1306         [ +  - ]:       1235 :                             rColumn.Insert(maItems[i].nRow, pNew);
    1307                 :            :                     }
    1308                 :            :                     else
    1309         [ +  - ]:       1958 :                         rColumn.Insert(maItems[i].nRow, pNew);
    1310                 :            :                 }
    1311                 :            :             }
    1312                 :            :         }
    1313                 :            :     }
    1314                 :            : }
    1315                 :            : 
    1316                 :            : 
    1317                 :         18 : void ScColumn::UndoToColumn(SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked,
    1318                 :            :                                 ScColumn& rColumn, const ScMarkData* pMarkData )
    1319                 :            : {
    1320         [ +  - ]:         18 :     if (nRow1 > 0)
    1321                 :         18 :         CopyToColumn( 0, nRow1-1, IDF_FORMULA, false, rColumn );
    1322                 :            : 
    1323                 :         18 :     CopyToColumn( nRow1, nRow2, nFlags, bMarked, rColumn, pMarkData );      //! bMarked ????
    1324                 :            : 
    1325         [ +  - ]:         18 :     if (nRow2 < MAXROW)
    1326                 :         18 :         CopyToColumn( nRow2+1, MAXROW, IDF_FORMULA, false, rColumn );
    1327                 :         18 : }
    1328                 :            : 
    1329                 :            : 
    1330                 :          0 : void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
    1331                 :            : {
    1332                 :          0 :     ScDocument& rDestDoc = *rDestCol.pDocument;
    1333                 :          0 :     ScAddress aOwnPos( nCol, 0, nTab );
    1334                 :          0 :     ScAddress aDestPos( rDestCol.nCol, 0, rDestCol.nTab );
    1335                 :            : 
    1336                 :          0 :     SCSIZE nPosCount = rPosCol.maItems.size();
    1337         [ #  # ]:          0 :     for (SCSIZE nPosIndex = 0; nPosIndex < nPosCount; nPosIndex++)
    1338                 :            :     {
    1339                 :          0 :         aOwnPos.SetRow( rPosCol.maItems[nPosIndex].nRow );
    1340                 :          0 :         aDestPos.SetRow( aOwnPos.Row() );
    1341                 :            :         SCSIZE nThisIndex;
    1342 [ #  # ][ #  # ]:          0 :         if ( Search( aDestPos.Row(), nThisIndex ) )
    1343                 :            :         {
    1344         [ #  # ]:          0 :             ScBaseCell* pNew = maItems[nThisIndex].pCell->Clone( rDestDoc, aDestPos );
    1345         [ #  # ]:          0 :             rDestCol.Insert( aDestPos.Row(), pNew );
    1346                 :            :         }
    1347                 :            :     }
    1348                 :            : 
    1349                 :          0 : }
    1350                 :            : 
    1351                 :            : 
    1352                 :          0 : void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
    1353                 :            : {
    1354                 :            :     //  Dies ist die Szenario-Tabelle, die Daten werden hineinkopiert
    1355                 :            : 
    1356         [ #  # ]:          0 :     ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
    1357                 :          0 :     SCROW nStart = -1, nEnd = -1;
    1358         [ #  # ]:          0 :     const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
    1359         [ #  # ]:          0 :     while (pPattern)
    1360                 :            :     {
    1361 [ #  # ][ #  # ]:          0 :         if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
    1362                 :            :         {
    1363         [ #  # ]:          0 :             DeleteArea( nStart, nEnd, IDF_CONTENTS );
    1364                 :            :             ((ScColumn&)rSrcCol).
    1365         [ #  # ]:          0 :                 CopyToColumn( nStart, nEnd, IDF_CONTENTS, false, *this );
    1366                 :            : 
    1367                 :            :             //  UpdateUsed nicht noetig, schon in TestCopyScenario passiert
    1368                 :            : 
    1369                 :          0 :             SCsTAB nDz = nTab - rSrcCol.nTab;
    1370                 :            :             UpdateReference(URM_COPY, nCol, nStart, nTab,
    1371                 :            :                                       nCol, nEnd,   nTab,
    1372         [ #  # ]:          0 :                                       0, 0, nDz, NULL);
    1373         [ #  # ]:          0 :             UpdateCompile();
    1374                 :            :         }
    1375                 :            : 
    1376                 :            :         //! CopyToColumn "const" machen !!!
    1377                 :            : 
    1378         [ #  # ]:          0 :         pPattern = aAttrIter.Next( nStart, nEnd );
    1379                 :            :     }
    1380                 :          0 : }
    1381                 :            : 
    1382                 :            : 
    1383                 :          0 : void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
    1384                 :            : {
    1385                 :            :     //  Dies ist die Szenario-Tabelle, die Daten werden in die andere kopiert
    1386                 :            : 
    1387         [ #  # ]:          0 :     ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
    1388                 :          0 :     SCROW nStart = -1, nEnd = -1;
    1389         [ #  # ]:          0 :     const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
    1390         [ #  # ]:          0 :     while (pPattern)
    1391                 :            :     {
    1392 [ #  # ][ #  # ]:          0 :         if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
    1393                 :            :         {
    1394         [ #  # ]:          0 :             rDestCol.DeleteArea( nStart, nEnd, IDF_CONTENTS );
    1395                 :            :             ((ScColumn*)this)->
    1396         [ #  # ]:          0 :                 CopyToColumn( nStart, nEnd, IDF_CONTENTS, false, rDestCol );
    1397                 :            : 
    1398                 :            :             //  UpdateUsed nicht noetig, schon in TestCopyScenario passiert
    1399                 :            : 
    1400                 :          0 :             SCsTAB nDz = rDestCol.nTab - nTab;
    1401                 :            :             rDestCol.UpdateReference(URM_COPY, rDestCol.nCol, nStart, rDestCol.nTab,
    1402                 :            :                                                rDestCol.nCol, nEnd,   rDestCol.nTab,
    1403         [ #  # ]:          0 :                                                0, 0, nDz, NULL);
    1404         [ #  # ]:          0 :             rDestCol.UpdateCompile();
    1405                 :            :         }
    1406                 :            : 
    1407                 :            :         //! CopyToColumn "const" machen !!!
    1408                 :            : 
    1409         [ #  # ]:          0 :         pPattern = aAttrIter.Next( nStart, nEnd );
    1410                 :            :     }
    1411                 :          0 : }
    1412                 :            : 
    1413                 :            : 
    1414                 :          0 : bool ScColumn::TestCopyScenarioTo( const ScColumn& rDestCol ) const
    1415                 :            : {
    1416                 :          0 :     bool bOk = true;
    1417         [ #  # ]:          0 :     ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
    1418                 :          0 :     SCROW nStart = 0, nEnd = 0;
    1419         [ #  # ]:          0 :     const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
    1420 [ #  # ][ #  # ]:          0 :     while (pPattern && bOk)
                 [ #  # ]
    1421                 :            :     {
    1422 [ #  # ][ #  # ]:          0 :         if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
    1423 [ #  # ][ #  # ]:          0 :             if ( rDestCol.pAttrArray->HasAttrib( nStart, nEnd, HASATTR_PROTECTED ) )
    1424                 :          0 :                 bOk = false;
    1425                 :            : 
    1426         [ #  # ]:          0 :         pPattern = aAttrIter.Next( nStart, nEnd );
    1427                 :            :     }
    1428                 :          0 :     return bOk;
    1429                 :            : }
    1430                 :            : 
    1431                 :            : 
    1432                 :       1024 : void ScColumn::MarkScenarioIn( ScMarkData& rDestMark ) const
    1433                 :            : {
    1434                 :       1024 :     ScRange aRange( nCol, 0, nTab );
    1435                 :            : 
    1436         [ +  - ]:       1024 :     ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
    1437                 :       1024 :     SCROW nStart = -1, nEnd = -1;
    1438         [ +  - ]:       1024 :     const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
    1439         [ +  + ]:       2062 :     while (pPattern)
    1440                 :            :     {
    1441 [ +  - ][ +  + ]:       1038 :         if ( ((ScMergeFlagAttr&)pPattern->GetItem( ATTR_MERGE_FLAG )).IsScenario() )
    1442                 :            :         {
    1443                 :         14 :             aRange.aStart.SetRow( nStart );
    1444                 :         14 :             aRange.aEnd.SetRow( nEnd );
    1445         [ +  - ]:         14 :             rDestMark.SetMultiMarkArea( aRange, true );
    1446                 :            :         }
    1447                 :            : 
    1448         [ +  - ]:       1038 :         pPattern = aAttrIter.Next( nStart, nEnd );
    1449                 :            :     }
    1450                 :       1024 : }
    1451                 :            : 
    1452                 :            : 
    1453                 :       8182 : void ScColumn::SwapCol(ScColumn& rCol)
    1454                 :            : {
    1455                 :       8182 :     maItems.swap(rCol.maItems);
    1456                 :            : 
    1457                 :       8182 :     ScAttrArray* pTempAttr = rCol.pAttrArray;
    1458                 :       8182 :     rCol.pAttrArray = pAttrArray;
    1459                 :       8182 :     pAttrArray = pTempAttr;
    1460                 :            : 
    1461                 :            :     // AttrArray muss richtige Spaltennummer haben
    1462                 :       8182 :     pAttrArray->SetCol(nCol);
    1463                 :       8182 :     rCol.pAttrArray->SetCol(rCol.nCol);
    1464                 :            : 
    1465                 :            :     SCSIZE i;
    1466         [ +  + ]:       8226 :     for (i = 0; i < maItems.size(); i++)
    1467                 :            :     {
    1468         [ +  - ]:         44 :         ScFormulaCell* pCell = (ScFormulaCell*) maItems[i].pCell;
    1469         [ -  + ]:         44 :         if( pCell->GetCellType() == CELLTYPE_FORMULA)
    1470                 :          0 :             pCell->aPos.SetCol(nCol);
    1471                 :            :     }
    1472         [ -  + ]:       8182 :     for (i = 0; i < rCol.maItems.size(); i++)
    1473                 :            :     {
    1474         [ #  # ]:          0 :         ScFormulaCell* pCell = (ScFormulaCell*) rCol.maItems[i].pCell;
    1475         [ #  # ]:          0 :         if( pCell->GetCellType() == CELLTYPE_FORMULA)
    1476                 :          0 :             pCell->aPos.SetCol(rCol.nCol);
    1477                 :            :     }
    1478                 :       8182 : }
    1479                 :            : 
    1480                 :            : 
    1481                 :       3066 : void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
    1482                 :            : {
    1483                 :       3066 :     pAttrArray->MoveTo(nStartRow, nEndRow, *rCol.pAttrArray);
    1484                 :            : 
    1485         [ -  + ]:       3066 :     if ( !maItems.empty() )
    1486                 :            :     {
    1487         [ #  # ]:          0 :         ::std::vector<SCROW> aRows;
    1488                 :          0 :         bool bConsecutive = true;
    1489                 :            :         SCSIZE i;
    1490         [ #  # ]:          0 :         Search( nStartRow, i);  // i points to start row or position thereafter
    1491                 :          0 :         SCSIZE nStartPos = i;
    1492 [ #  # ][ #  # ]:          0 :         for ( ; i < maItems.size() && maItems[i].nRow <= nEndRow; ++i)
                 [ #  # ]
    1493                 :            :         {
    1494                 :          0 :             SCROW nRow = maItems[i].nRow;
    1495         [ #  # ]:          0 :             aRows.push_back( nRow);
    1496         [ #  # ]:          0 :             rCol.Insert( nRow, maItems[i].pCell);
    1497         [ #  # ]:          0 :             if (nRow != maItems[i].nRow)
    1498                 :            :             {   // Listener inserted
    1499                 :          0 :                 bConsecutive = false;
    1500         [ #  # ]:          0 :                 Search( nRow, i);
    1501                 :            :             }
    1502                 :            :         }
    1503                 :          0 :         SCSIZE nStopPos = i;
    1504         [ #  # ]:          0 :         if (nStartPos < nStopPos)
    1505                 :            :         {
    1506                 :            :             // Create list of ranges of cell entry positions
    1507                 :            :             typedef ::std::pair<SCSIZE,SCSIZE> PosPair;
    1508                 :            :             typedef ::std::vector<PosPair> EntryPosPairs;
    1509         [ #  # ]:          0 :             EntryPosPairs aEntries;
    1510         [ #  # ]:          0 :             if (bConsecutive)
    1511 [ #  # ][ #  # ]:          0 :                 aEntries.push_back( PosPair(nStartPos, nStopPos));
    1512                 :            :             else
    1513                 :            :             {
    1514                 :          0 :                 bool bFirst = true;
    1515                 :          0 :                 nStopPos = 0;
    1516 [ #  # ][ #  # ]:          0 :                 for (::std::vector<SCROW>::const_iterator it( aRows.begin());
           [ #  #  #  # ]
                 [ #  # ]
    1517 [ #  # ][ #  # ]:          0 :                         it != aRows.end() && nStopPos < maItems.size(); ++it,
                 [ #  # ]
    1518                 :            :                         ++nStopPos)
    1519                 :            :                 {
    1520 [ #  # ][ #  # ]:          0 :                     if (!bFirst && *it != maItems[nStopPos].nRow)
         [ #  # ][ #  # ]
    1521                 :            :                     {
    1522 [ #  # ][ #  # ]:          0 :                         aEntries.push_back( PosPair(nStartPos, nStopPos));
    1523                 :          0 :                         bFirst = true;
    1524                 :            :                     }
    1525 [ #  # ][ #  # ]:          0 :                     if (bFirst && Search( *it, nStartPos))
         [ #  # ][ #  # ]
                 [ #  # ]
    1526                 :            :                     {
    1527                 :          0 :                         bFirst = false;
    1528                 :          0 :                         nStopPos = nStartPos;
    1529                 :            :                     }
    1530                 :            :                 }
    1531 [ #  # ][ #  # ]:          0 :                 if (!bFirst && nStartPos < nStopPos)
    1532 [ #  # ][ #  # ]:          0 :                     aEntries.push_back( PosPair(nStartPos, nStopPos));
    1533                 :            :             }
    1534                 :            :             // Broadcast changes
    1535                 :          0 :             ScAddress aAdr( nCol, 0, nTab );
    1536         [ #  # ]:          0 :             ScHint aHint( SC_HINT_DYING, aAdr, NULL );  // areas only
    1537                 :          0 :             ScAddress& rAddress = aHint.GetAddress();
    1538 [ #  # ][ #  # ]:          0 :             ScNoteCell* pNoteCell = new ScNoteCell;     // Dummy like in DeleteRange
    1539                 :            : 
    1540                 :            :             // must iterate backwards, because indexes of following cells become invalid
    1541   [ #  #  #  # ]:          0 :             for (EntryPosPairs::reverse_iterator it( aEntries.rbegin());
                 [ #  # ]
    1542                 :          0 :                     it != aEntries.rend(); ++it)
    1543                 :            :             {
    1544         [ #  # ]:          0 :                 nStartPos = (*it).first;
    1545         [ #  # ]:          0 :                 nStopPos = (*it).second;
    1546         [ #  # ]:          0 :                 for (i=nStartPos; i<nStopPos; ++i)
    1547                 :          0 :                     maItems[i].pCell = pNoteCell;
    1548         [ #  # ]:          0 :                 for (i=nStartPos; i<nStopPos; ++i)
    1549                 :            :                 {
    1550                 :          0 :                     rAddress.SetRow( maItems[i].nRow );
    1551         [ #  # ]:          0 :                     pDocument->AreaBroadcast( aHint );
    1552                 :            :                 }
    1553 [ #  # ][ #  # ]:          0 :                 maItems.erase(maItems.begin() + nStartPos, maItems.begin() + nStopPos - 1);
         [ #  # ][ #  # ]
    1554                 :            :             }
    1555 [ #  # ][ #  # ]:          0 :             pNoteCell->Delete();
    1556                 :          0 :         }
    1557                 :            :     }
    1558                 :       3066 : }
    1559                 :            : 
    1560                 :            : 
    1561                 :      62559 : bool ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
    1562                 :            :              SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
    1563                 :            :              ScDocument* pUndoDoc )
    1564                 :            : {
    1565                 :      62559 :     bool bUpdated = false;
    1566         [ +  + ]:      62559 :     if ( !maItems.empty() )
    1567                 :            :     {
    1568                 :            :         ScRange aRange( ScAddress( nCol1, nRow1, nTab1 ),
    1569                 :        166 :                         ScAddress( nCol2, nRow2, nTab2 ) );
    1570 [ +  + ][ +  + ]:        166 :         if ( eUpdateRefMode == URM_COPY && nRow1 == nRow2 )
    1571                 :            :         {   // z.B. eine einzelne Zelle aus dem Clipboard eingefuegt
    1572                 :            :             SCSIZE nIndex;
    1573 [ +  - ][ +  - ]:          9 :             if ( Search( nRow1, nIndex ) )
    1574                 :            :             {
    1575         [ +  - ]:          9 :                 ScFormulaCell* pCell = (ScFormulaCell*) maItems[nIndex].pCell;
    1576         [ +  + ]:          9 :                 if( pCell->GetCellType() == CELLTYPE_FORMULA)
    1577                 :            :                     bUpdated |= pCell->UpdateReference(
    1578         [ +  - ]:          3 :                         eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
    1579                 :          9 :             }
    1580                 :            :         }
    1581                 :            :         else
    1582                 :            :         {
    1583                 :            :             // For performance reasons two loop bodies instead of
    1584                 :            :             // testing for update mode in each iteration.
    1585                 :            :             // Anyways, this is still a bottleneck on large arrays with few
    1586                 :            :             // formulas cells.
    1587         [ +  + ]:        157 :             if ( eUpdateRefMode == URM_COPY )
    1588                 :            :             {
    1589                 :            :                 SCSIZE i;
    1590         [ +  - ]:        101 :                 Search( nRow1, i );
    1591         [ +  + ]:        341 :                 for ( ; i < maItems.size(); i++ )
    1592                 :            :                 {
    1593                 :        240 :                     SCROW nRow = maItems[i].nRow;
    1594         [ -  + ]:        240 :                     if ( nRow > nRow2 )
    1595                 :          0 :                         break;
    1596                 :        240 :                     ScBaseCell* pCell = maItems[i].pCell;
    1597         [ +  + ]:        240 :                     if( pCell->GetCellType() == CELLTYPE_FORMULA)
    1598                 :            :                     {
    1599                 :            :                         bUpdated |= ((ScFormulaCell*)pCell)->UpdateReference(
    1600 [ +  - ][ +  - ]:         43 :                             eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
    1601         [ -  + ]:         43 :                         if ( nRow != maItems[i].nRow )
    1602         [ #  # ]:          0 :                             Search( nRow, i );  // Listener removed/inserted?
    1603                 :            :                     }
    1604                 :            :                 }
    1605                 :            :             }
    1606                 :            :             else
    1607                 :            :             {
    1608                 :         56 :                 SCSIZE i = 0;
    1609         [ +  + ]:        293 :                 for ( ; i < maItems.size(); i++ )
    1610                 :            :                 {
    1611                 :        127 :                     ScBaseCell* pCell = maItems[i].pCell;
    1612         [ +  + ]:        127 :                     if( pCell->GetCellType() == CELLTYPE_FORMULA)
    1613                 :            :                     {
    1614                 :         18 :                         SCROW nRow = maItems[i].nRow;
    1615                 :            :                         // When deleting rows on several sheets, the formula's position may be updated with the first call,
    1616                 :            :                         // so the undo position must be passed from here.
    1617                 :         18 :                         ScAddress aUndoPos( nCol, nRow, nTab );
    1618                 :            :                         bUpdated |= ((ScFormulaCell*)pCell)->UpdateReference(
    1619 [ +  - ][ +  - ]:         18 :                             eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc, &aUndoPos );
    1620         [ -  + ]:         18 :                         if ( nRow != maItems[i].nRow )
    1621         [ #  # ]:         18 :                             Search( nRow, i );  // Listener removed/inserted?
    1622                 :            :                     }
    1623                 :            :                 }
    1624                 :            :             }
    1625                 :            :         }
    1626                 :            :     }
    1627                 :      62559 :     return bUpdated;
    1628                 :            : }
    1629                 :            : 
    1630                 :            : 
    1631                 :          0 : void ScColumn::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
    1632                 :            :                                     ScDocument* pUndoDoc )
    1633                 :            : {
    1634         [ #  # ]:          0 :     if ( !maItems.empty() )
    1635         [ #  # ]:          0 :         for (SCSIZE i=0; i<maItems.size(); i++)
    1636                 :            :         {
    1637                 :          0 :             ScBaseCell* pCell = maItems[i].pCell;
    1638         [ #  # ]:          0 :             if (pCell->GetCellType() == CELLTYPE_FORMULA)
    1639                 :            :             {
    1640                 :          0 :                 SCROW nRow = maItems[i].nRow;
    1641 [ #  # ][ #  # ]:          0 :                 ((ScFormulaCell*)pCell)->UpdateTranspose( rSource, rDest, pUndoDoc );
    1642         [ #  # ]:          0 :                 if ( nRow != maItems[i].nRow )
    1643         [ #  # ]:          0 :                     Search( nRow, i );              // Listener geloescht/eingefuegt?
    1644                 :            :             }
    1645                 :            :         }
    1646                 :          0 : }
    1647                 :            : 
    1648                 :            : 
    1649                 :          0 : void ScColumn::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
    1650                 :            : {
    1651         [ #  # ]:          0 :     if ( !maItems.empty() )
    1652         [ #  # ]:          0 :         for (SCSIZE i=0; i<maItems.size(); i++)
    1653                 :            :         {
    1654                 :          0 :             ScBaseCell* pCell = maItems[i].pCell;
    1655         [ #  # ]:          0 :             if (pCell->GetCellType() == CELLTYPE_FORMULA)
    1656                 :            :             {
    1657                 :          0 :                 SCROW nRow = maItems[i].nRow;
    1658 [ #  # ][ #  # ]:          0 :                 ((ScFormulaCell*)pCell)->UpdateGrow( rArea, nGrowX, nGrowY );
    1659         [ #  # ]:          0 :                 if ( nRow != maItems[i].nRow )
    1660         [ #  # ]:          0 :                     Search( nRow, i );              // Listener geloescht/eingefuegt?
    1661                 :            :             }
    1662                 :            :         }
    1663                 :          0 : }
    1664                 :            : 
    1665                 :            : 
    1666                 :     112640 : void ScColumn::UpdateInsertTab(SCTAB nInsPos, SCTAB nNewSheets)
    1667                 :            : {
    1668         [ +  + ]:     112640 :     if (nTab >= nInsPos)
    1669                 :            :     {
    1670                 :      90112 :         nTab += nNewSheets;
    1671                 :      90112 :         pAttrArray->SetTab(nTab);
    1672                 :            :     }
    1673                 :            : 
    1674                 :     112640 :     UpdateInsertTabOnlyCells(nInsPos, nNewSheets);
    1675                 :     112640 : }
    1676                 :            : 
    1677                 :     112640 : void ScColumn::UpdateInsertTabOnlyCells(SCTAB nInsPos, SCTAB nNewSheets)
    1678                 :            : {
    1679         [ +  + ]:     112640 :     if (maItems.empty())
    1680                 :     112640 :         return;
    1681                 :            : 
    1682         [ +  + ]:       1585 :     for (size_t i = 0; i < maItems.size(); ++i)
    1683                 :            :     {
    1684      [ +  -  + ]:       1406 :         switch (maItems[i].pCell->GetCellType())
    1685                 :            :         {
    1686                 :            :             case CELLTYPE_FORMULA:
    1687                 :            :             {
    1688                 :         18 :                 SCROW nRow = maItems[i].nRow;
    1689         [ +  - ]:         18 :                 ScFormulaCell* p = static_cast<ScFormulaCell*>(maItems[i].pCell);
    1690         [ +  - ]:         18 :                 p->UpdateInsertTab(nInsPos, nNewSheets);
    1691         [ -  + ]:         18 :                 if (nRow != maItems[i].nRow)
    1692         [ #  # ]:          0 :                     Search(nRow, i);      // Listener deleted/inserted?
    1693                 :            :             }
    1694                 :         18 :             break;
    1695                 :            :             case CELLTYPE_EDIT:
    1696                 :            :             {
    1697                 :          0 :                 ScEditCell* p = static_cast<ScEditCell*>(maItems[i].pCell);
    1698         [ #  # ]:          0 :                 p->UpdateFields(nTab);
    1699                 :            :             }
    1700                 :          0 :             break;
    1701                 :            :             default:
    1702                 :            :                 ;
    1703                 :            :         }
    1704                 :            :     }
    1705                 :            : }
    1706                 :            : 
    1707                 :      10240 : void ScColumn::UpdateInsertTabAbs(SCTAB nNewPos)
    1708                 :            : {
    1709         [ +  + ]:      10240 :     if (maItems.empty())
    1710                 :      10240 :         return;
    1711                 :            : 
    1712         [ +  + ]:          2 :     for (size_t i = 0; i < maItems.size(); ++i)
    1713                 :            :     {
    1714      [ -  -  + ]:          1 :         switch (maItems[i].pCell->GetCellType())
    1715                 :            :         {
    1716                 :            :             case CELLTYPE_FORMULA:
    1717                 :            :             {
    1718                 :          0 :                 SCROW nRow = maItems[i].nRow;
    1719         [ #  # ]:          0 :                 ScFormulaCell* p = static_cast<ScFormulaCell*>(maItems[i].pCell);
    1720         [ #  # ]:          0 :                 p->UpdateInsertTabAbs(nNewPos);
    1721         [ #  # ]:          0 :                 if (nRow != maItems[i].nRow)
    1722         [ #  # ]:          0 :                     Search(nRow, i);      // Listener deleted/inserted?
    1723                 :            :             }
    1724                 :          0 :             break;
    1725                 :            :             case CELLTYPE_EDIT:
    1726                 :            :             {
    1727                 :          0 :                 ScEditCell* p = static_cast<ScEditCell*>(maItems[i].pCell);
    1728         [ #  # ]:          0 :                 p->UpdateFields(nTab);
    1729                 :            :             }
    1730                 :          0 :             break;
    1731                 :            :             default:
    1732                 :            :                 ;
    1733                 :            :         }
    1734                 :            :     }
    1735                 :            : }
    1736                 :            : 
    1737                 :     273408 : void ScColumn::UpdateDeleteTab(SCTAB nDelPos, bool bIsMove, ScColumn* pRefUndo, SCTAB nSheets)
    1738                 :            : {
    1739         [ +  + ]:     273408 :     if (nTab > nDelPos)
    1740                 :            :     {
    1741                 :      58368 :         nTab -= nSheets;
    1742                 :      58368 :         pAttrArray->SetTab(nTab);
    1743                 :            :     }
    1744                 :            : 
    1745         [ +  + ]:     273408 :     if (maItems.empty())
    1746                 :     273408 :         return;
    1747                 :            : 
    1748         [ +  + ]:       3495 :     for (size_t i = 0; i < maItems.size(); ++i)
    1749                 :            :     {
    1750      [ +  -  + ]:       2948 :         switch (maItems[i].pCell->GetCellType())
    1751                 :            :         {
    1752                 :            :             case CELLTYPE_FORMULA:
    1753                 :            :             {
    1754                 :         79 :                 SCROW nRow = maItems[i].nRow;
    1755         [ +  - ]:         79 :                 ScFormulaCell* pOld = static_cast<ScFormulaCell*>(maItems[i].pCell);
    1756                 :            : 
    1757                 :            :                 /*  Do not copy cell note to the undo document. Undo will copy
    1758                 :            :                     back the formula cell while keeping the original note. */
    1759 [ +  + ][ +  - ]:         79 :                 ScBaseCell* pSave = pRefUndo ? pOld->Clone( *pDocument ) : 0;
    1760                 :            : 
    1761         [ +  - ]:         79 :                 bool bChanged = pOld->UpdateDeleteTab(nDelPos, bIsMove, nSheets);
    1762         [ -  + ]:         79 :                 if ( nRow != maItems[i].nRow )
    1763         [ #  # ]:          0 :                     Search( nRow, i );      // Listener geloescht/eingefuegt?
    1764                 :            : 
    1765         [ +  + ]:         79 :                 if (pRefUndo)
    1766                 :            :                 {
    1767         [ +  - ]:         10 :                     if (bChanged)
    1768         [ +  - ]:         10 :                         pRefUndo->Insert( nRow, pSave );
    1769         [ #  # ]:          0 :                     else if(pSave)
    1770         [ #  # ]:          0 :                         pSave->Delete();
    1771                 :            :                 }
    1772                 :            :             }
    1773                 :         79 :             break;
    1774                 :            :             case CELLTYPE_EDIT:
    1775                 :            :             {
    1776                 :          0 :                 ScEditCell* p = static_cast<ScEditCell*>(maItems[i].pCell);
    1777         [ #  # ]:          0 :                 p->UpdateFields(nTab);
    1778                 :            :             }
    1779                 :          0 :             break;
    1780                 :            :             default:
    1781                 :            :                 ;
    1782                 :            :         }
    1783                 :            :     }
    1784                 :            : }
    1785                 :            : 
    1786                 :      30720 : void ScColumn::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
    1787                 :            : {
    1788                 :      30720 :     nTab = nTabNo;
    1789                 :      30720 :     pAttrArray->SetTab( nTabNo );
    1790         [ +  + ]:      30720 :     if (maItems.empty())
    1791                 :      30720 :         return;
    1792                 :            : 
    1793         [ +  + ]:        354 :     for (size_t i = 0; i < maItems.size(); ++i)
    1794                 :            :     {
    1795      [ -  -  + ]:        306 :         switch (maItems[i].pCell->GetCellType())
    1796                 :            :         {
    1797                 :            :             case CELLTYPE_FORMULA:
    1798                 :            :             {
    1799         [ #  # ]:          0 :                 ScFormulaCell* p = static_cast<ScFormulaCell*>(maItems[i].pCell);
    1800                 :          0 :                 SCROW nRow = maItems[i].nRow;
    1801         [ #  # ]:          0 :                 p->UpdateMoveTab(nOldPos, nNewPos, nTabNo);
    1802         [ #  # ]:          0 :                 if (nRow != maItems[i].nRow)
    1803         [ #  # ]:          0 :                     Search(nRow, i);      // Listener deleted/inserted?
    1804                 :            :             }
    1805                 :          0 :             break;
    1806                 :            :             case CELLTYPE_EDIT:
    1807                 :            :             {
    1808                 :          0 :                 ScEditCell* p = static_cast<ScEditCell*>(maItems[i].pCell);
    1809         [ #  # ]:          0 :                 p->UpdateFields(nTab);
    1810                 :            :             }
    1811                 :          0 :             break;
    1812                 :            :             default:
    1813                 :            :                 ;
    1814                 :            :         }
    1815                 :            :     }
    1816                 :            : }
    1817                 :            : 
    1818                 :            : 
    1819                 :     382976 : void ScColumn::UpdateCompile( bool bForceIfNameInUse )
    1820                 :            : {
    1821         [ +  + ]:     382976 :     if ( !maItems.empty() )
    1822         [ +  + ]:       4477 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1823                 :            :         {
    1824         [ +  - ]:       3920 :             ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
    1825         [ +  + ]:       3920 :             if( p->GetCellType() == CELLTYPE_FORMULA )
    1826                 :            :             {
    1827                 :         73 :                 SCROW nRow = maItems[i].nRow;
    1828         [ +  - ]:         73 :                 p->UpdateCompile( bForceIfNameInUse );
    1829         [ -  + ]:         73 :                 if ( nRow != maItems[i].nRow )
    1830         [ #  # ]:          0 :                     Search( nRow, i );      // Listener geloescht/eingefuegt?
    1831                 :            :             }
    1832                 :            :         }
    1833                 :     382976 : }
    1834                 :            : 
    1835                 :            : 
    1836                 :       4096 : void ScColumn::SetTabNo(SCTAB nNewTab)
    1837                 :            : {
    1838                 :       4096 :     nTab = nNewTab;
    1839                 :       4096 :     pAttrArray->SetTab( nNewTab );
    1840         [ +  + ]:       4096 :     if ( !maItems.empty() )
    1841         [ +  + ]:         44 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1842                 :            :         {
    1843         [ +  - ]:         28 :             ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
    1844         [ +  + ]:         28 :             if( p->GetCellType() == CELLTYPE_FORMULA )
    1845                 :         10 :                 p->aPos.SetTab( nNewTab );
    1846                 :            :         }
    1847                 :       4096 : }
    1848                 :            : 
    1849                 :          9 : void ScColumn::FindRangeNamesInUse(SCROW nRow1, SCROW nRow2, std::set<sal_uInt16>& rIndexes) const
    1850                 :            : {
    1851         [ +  - ]:          9 :     if ( !maItems.empty() )
    1852         [ +  + ]:         18 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1853   [ +  -  +  -  :         27 :             if ((maItems[i].nRow >= nRow1) &&
           +  + ][ +  + ]
    1854                 :          9 :                 (maItems[i].nRow <= nRow2) &&
    1855                 :          9 :                 (maItems[i].pCell->GetCellType() == CELLTYPE_FORMULA))
    1856         [ +  - ]:          3 :                     ((ScFormulaCell*)maItems[i].pCell)->FindRangeNamesInUse(rIndexes);
    1857                 :          9 : }
    1858                 :            : 
    1859                 :     351232 : void ScColumn::SetDirtyVar()
    1860                 :            : {
    1861         [ +  + ]:     358746 :     for (SCSIZE i=0; i<maItems.size(); i++)
    1862                 :            :     {
    1863         [ +  - ]:       7514 :         ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
    1864         [ +  + ]:       7514 :         if( p->GetCellType() == CELLTYPE_FORMULA )
    1865                 :       1641 :             p->SetDirtyVar();
    1866                 :            :     }
    1867                 :     351232 : }
    1868                 :            : 
    1869                 :            : 
    1870                 :     825344 : void ScColumn::SetDirty()
    1871                 :            : {
    1872                 :            :     // wird nur dokumentweit verwendet, kein FormulaTrack
    1873                 :     825344 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1874                 :     825344 :     pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
    1875         [ +  + ]:     837967 :     for (SCSIZE i=0; i<maItems.size(); i++)
    1876                 :            :     {
    1877         [ +  - ]:      12623 :         ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
    1878         [ +  + ]:      12623 :         if( p->GetCellType() == CELLTYPE_FORMULA )
    1879                 :            :         {
    1880                 :         84 :             p->SetDirtyVar();
    1881         [ +  + ]:         84 :             if ( !pDocument->IsInFormulaTree( p ) )
    1882                 :         72 :                 pDocument->PutInFormulaTree( p );
    1883                 :            :         }
    1884                 :            :     }
    1885                 :     825344 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1886                 :     825344 : }
    1887                 :            : 
    1888                 :            : 
    1889                 :       4296 : void ScColumn::SetDirty( const ScRange& rRange )
    1890                 :            : {   // broadcastet alles innerhalb eines Range, mit FormulaTrack
    1891         [ +  + ]:       4296 :     if ( maItems.empty() )
    1892                 :       4296 :         return ;
    1893                 :        191 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1894         [ +  - ]:        191 :     pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
    1895                 :        191 :     SCROW nRow2 = rRange.aEnd.Row();
    1896                 :        191 :     ScAddress aPos( nCol, 0, nTab );
    1897         [ +  - ]:        191 :     ScHint aHint( SC_HINT_DATACHANGED, aPos, NULL );
    1898                 :            :     SCROW nRow;
    1899                 :            :     SCSIZE nIndex;
    1900         [ +  - ]:        191 :     Search( rRange.aStart.Row(), nIndex );
    1901 [ +  + ][ +  + ]:        508 :     while ( nIndex < maItems.size() && (nRow = maItems[nIndex].nRow) <= nRow2 )
                 [ +  + ]
    1902                 :            :     {
    1903                 :        317 :         ScBaseCell* pCell = maItems[nIndex].pCell;
    1904         [ +  + ]:        317 :         if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1905 [ +  - ][ +  - ]:         45 :             ((ScFormulaCell*)pCell)->SetDirty();
    1906                 :            :         else
    1907                 :            :         {
    1908                 :        272 :             aHint.GetAddress().SetRow( nRow );
    1909                 :        272 :             aHint.SetCell( pCell );
    1910         [ +  - ]:        272 :             pDocument->Broadcast( aHint );
    1911                 :            :         }
    1912                 :        317 :         nIndex++;
    1913                 :            :     }
    1914 [ +  - ][ +  - ]:       4296 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1915                 :            : }
    1916                 :            : 
    1917                 :            : 
    1918                 :         60 : void ScColumn::SetTableOpDirty( const ScRange& rRange )
    1919                 :            : {
    1920         [ +  - ]:         60 :     if ( maItems.empty() )
    1921                 :         60 :         return ;
    1922                 :         60 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1923         [ +  - ]:         60 :     pDocument->SetAutoCalc( false );    // no multiple recalculation
    1924                 :         60 :     SCROW nRow2 = rRange.aEnd.Row();
    1925                 :         60 :     ScAddress aPos( nCol, 0, nTab );
    1926         [ +  - ]:         60 :     ScHint aHint( SC_HINT_TABLEOPDIRTY, aPos, NULL );
    1927                 :            :     SCROW nRow;
    1928                 :            :     SCSIZE nIndex;
    1929         [ +  - ]:         60 :     Search( rRange.aStart.Row(), nIndex );
    1930 [ +  - ][ +  + ]:        120 :     while ( nIndex < maItems.size() && (nRow = maItems[nIndex].nRow) <= nRow2 )
                 [ +  + ]
    1931                 :            :     {
    1932                 :         60 :         ScBaseCell* pCell = maItems[nIndex].pCell;
    1933         [ -  + ]:         60 :         if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1934 [ #  # ][ #  # ]:          0 :             ((ScFormulaCell*)pCell)->SetTableOpDirty();
    1935                 :            :         else
    1936                 :            :         {
    1937                 :         60 :             aHint.GetAddress().SetRow( nRow );
    1938                 :         60 :             aHint.SetCell( pCell );
    1939         [ +  - ]:         60 :             pDocument->Broadcast( aHint );
    1940                 :            :         }
    1941                 :         60 :         nIndex++;
    1942                 :            :     }
    1943 [ +  - ][ +  - ]:         60 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1944                 :            : }
    1945                 :            : 
    1946                 :            : 
    1947                 :     184320 : void ScColumn::SetDirtyAfterLoad()
    1948                 :            : {
    1949                 :     184320 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1950                 :     184320 :     pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
    1951         [ +  + ]:     192038 :     for (SCSIZE i=0; i<maItems.size(); i++)
    1952                 :            :     {
    1953         [ +  - ]:       7718 :         ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
    1954                 :            : #if 1
    1955                 :            :         // Simply set dirty and append to FormulaTree, without broadcasting,
    1956                 :            :         // which is a magnitude faster. This is used to calculate the entire
    1957                 :            :         // document, e.g. when loading alien file formats.
    1958         [ +  + ]:       7718 :         if ( p->GetCellType() == CELLTYPE_FORMULA )
    1959                 :       1773 :             p->SetDirtyAfterLoad();
    1960                 :            : #else
    1961                 :            : /* This was used with the binary file format that stored results, where only
    1962                 :            :  * newly compiled and volatile functions and their dependents had to be
    1963                 :            :  * recalculated, which was faster then. Since that was moved to 'binfilter' to
    1964                 :            :  * convert to an XML file this isn't needed anymore, and not used for other
    1965                 :            :  * file formats. Kept for reference in case mechanism needs to be reactivated
    1966                 :            :  * for some file formats, we'd have to introduce a controlling parameter to
    1967                 :            :  * this method here then.
    1968                 :            : */
    1969                 :            : 
    1970                 :            :         // If the cell was alsready dirty because of CalcAfterLoad,
    1971                 :            :         // FormulaTracking has to take place.
    1972                 :            :         if ( p->GetCellType() == CELLTYPE_FORMULA && p->GetDirty() )
    1973                 :            :             p->SetDirty();
    1974                 :            : #endif
    1975                 :            :     }
    1976                 :     184320 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1977                 :     184320 : }
    1978                 :            : 
    1979                 :            : 
    1980                 :      50176 : void ScColumn::SetRelNameDirty()
    1981                 :            : {
    1982                 :      50176 :     bool bOldAutoCalc = pDocument->GetAutoCalc();
    1983                 :      50176 :     pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
    1984         [ +  + ]:      50299 :     for (SCSIZE i=0; i<maItems.size(); i++)
    1985                 :            :     {
    1986         [ +  - ]:        123 :         ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
    1987 [ +  + ][ -  + ]:        123 :         if( p->GetCellType() == CELLTYPE_FORMULA && p->HasRelNameReference() )
                 [ -  + ]
    1988                 :          0 :             p->SetDirty();
    1989                 :            :     }
    1990                 :      50176 :     pDocument->SetAutoCalc( bOldAutoCalc );
    1991                 :      50176 : }
    1992                 :            : 
    1993                 :            : 
    1994                 :     351232 : void ScColumn::CalcAll()
    1995                 :            : {
    1996         [ +  + ]:     351232 :     if ( !maItems.empty() )
    1997         [ +  + ]:       8251 :         for (SCSIZE i=0; i<maItems.size(); i++)
    1998                 :            :         {
    1999                 :       7514 :             ScBaseCell* pCell = maItems[i].pCell;
    2000         [ +  + ]:       7514 :             if (pCell->GetCellType() == CELLTYPE_FORMULA)
    2001                 :            :             {
    2002                 :            : #if OSL_DEBUG_LEVEL > 1
    2003                 :            :                 // nach F9 ctrl-F9: ueberprueft die Berechnung per FormulaTree
    2004                 :            :                 ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
    2005                 :            :                 double nOldVal, nNewVal;
    2006                 :            :                 nOldVal = pFCell->GetValue();
    2007                 :            : #endif
    2008         [ +  - ]:       1641 :                 ((ScFormulaCell*)pCell)->Interpret();
    2009                 :            : #if OSL_DEBUG_LEVEL > 1
    2010                 :            :                 if ( pFCell->GetCode()->IsRecalcModeNormal() )
    2011                 :            :                     nNewVal = pFCell->GetValue();
    2012                 :            :                 else
    2013                 :            :                     nNewVal = nOldVal;  // random(), jetzt() etc.
    2014                 :            :                 OSL_ENSURE( nOldVal==nNewVal, "CalcAll: nOldVal != nNewVal" );
    2015                 :            : #endif
    2016                 :            :             }
    2017                 :            :         }
    2018                 :     351232 : }
    2019                 :            : 
    2020                 :            : 
    2021                 :       8192 : void ScColumn::CompileAll()
    2022                 :            : {
    2023         [ +  + ]:       8192 :     if ( !maItems.empty() )
    2024         [ +  + ]:         73 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    2025                 :            :         {
    2026                 :         47 :             ScBaseCell* pCell = maItems[i].pCell;
    2027         [ +  + ]:         47 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    2028                 :            :             {
    2029                 :         13 :                 SCROW nRow = maItems[i].nRow;
    2030                 :            :                 // fuer unbedingtes kompilieren
    2031                 :            :                 // bCompile=true und pCode->nError=0
    2032         [ +  - ]:         13 :                 ((ScFormulaCell*)pCell)->GetCode()->SetCodeError( 0 );
    2033         [ +  - ]:         13 :                 ((ScFormulaCell*)pCell)->SetCompile( true );
    2034 [ +  - ][ +  - ]:         13 :                 ((ScFormulaCell*)pCell)->CompileTokenArray();
    2035         [ -  + ]:         13 :                 if ( nRow != maItems[i].nRow )
    2036         [ #  # ]:          0 :                     Search( nRow, i );      // Listener geloescht/eingefuegt?
    2037                 :            :             }
    2038                 :            :         }
    2039                 :       8192 : }
    2040                 :            : 
    2041                 :            : 
    2042                 :     229376 : void ScColumn::CompileXML( ScProgress& rProgress )
    2043                 :            : {
    2044         [ +  + ]:     229376 :     if ( !maItems.empty() )
    2045         [ +  + ]:       6515 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    2046                 :            :         {
    2047                 :       5921 :             ScBaseCell* pCell = maItems[i].pCell;
    2048         [ +  + ]:       5921 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    2049                 :            :             {
    2050                 :       1202 :                 SCROW nRow = maItems[i].nRow;
    2051 [ +  - ][ +  - ]:       1202 :                 ((ScFormulaCell*)pCell)->CompileXML( rProgress );
    2052         [ +  + ]:       1202 :                 if ( nRow != maItems[i].nRow )
    2053         [ +  - ]:          6 :                     Search( nRow, i );      // Listener geloescht/eingefuegt?
    2054                 :            :             }
    2055                 :            :         }
    2056                 :     229376 : }
    2057                 :            : 
    2058                 :            : 
    2059                 :     184320 : void ScColumn::CalcAfterLoad()
    2060                 :            : {
    2061         [ +  + ]:     184320 :     if ( !maItems.empty() )
    2062         [ +  + ]:       8479 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    2063                 :            :         {
    2064                 :       7718 :             ScBaseCell* pCell = maItems[i].pCell;
    2065         [ +  + ]:       7718 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    2066         [ +  - ]:       1773 :                 ((ScFormulaCell*)pCell)->CalcAfterLoad();
    2067                 :            :         }
    2068                 :     184320 : }
    2069                 :            : 
    2070                 :            : 
    2071                 :      12555 : void ScColumn::ResetChanged( SCROW nStartRow, SCROW nEndRow )
    2072                 :            : {
    2073         [ +  + ]:      12555 :     if ( !maItems.empty() )
    2074                 :            :     {
    2075                 :            :         SCSIZE nIndex;
    2076         [ +  - ]:       4301 :         Search(nStartRow,nIndex);
    2077 [ +  + ][ +  + ]:      17321 :         while (nIndex<maItems.size() && maItems[nIndex].nRow <= nEndRow)
                 [ +  + ]
    2078                 :            :         {
    2079                 :      13020 :             ScBaseCell* pCell = maItems[nIndex].pCell;
    2080         [ +  + ]:      13020 :             if (pCell->GetCellType() == CELLTYPE_FORMULA)
    2081 [ +  - ][ +  - ]:        288 :                 ((ScFormulaCell*)pCell)->ResetChanged();
    2082                 :      13020 :             ++nIndex;
    2083                 :            :         }
    2084                 :            :     }
    2085                 :      12555 : }
    2086                 :            : 
    2087                 :            : 
    2088                 :    1840674 : bool ScColumn::HasEditCells(SCROW nStartRow, SCROW nEndRow, SCROW& rFirst) const
    2089                 :            : {
    2090                 :            :     //  used in GetOptimalHeight - ambiguous script type counts as edit cell
    2091                 :            : 
    2092                 :    1840674 :     SCROW nRow = 0;
    2093                 :            :     SCSIZE nIndex;
    2094         [ +  - ]:    1840674 :     Search(nStartRow,nIndex);
    2095 [ +  + ][ +  + ]:    1879372 :     while ( (nIndex < maItems.size()) ? ((nRow=maItems[nIndex].nRow) <= nEndRow) : false )
                 [ +  + ]
    2096                 :            :     {
    2097                 :      39139 :         ScBaseCell* pCell = maItems[nIndex].pCell;
    2098                 :      39139 :         CellType eCellType = pCell->GetCellType();
    2099 [ +  + ][ -  + ]:      77901 :         if ( eCellType == CELLTYPE_EDIT ||
                 [ +  + ]
           [ +  +  +  - ]
    2100         [ +  - ]:      38698 :              IsAmbiguousScriptNonZero( pDocument->GetScriptType(nCol, nRow, nTab, pCell) ) ||
    2101 [ +  - ][ +  - ]:         64 :              ((eCellType == CELLTYPE_FORMULA) && ((ScFormulaCell*)pCell)->IsMultilineResult()) )
    2102                 :            :         {
    2103                 :        441 :             rFirst = nRow;
    2104                 :        441 :             return true;
    2105                 :            :         }
    2106                 :      38698 :         ++nIndex;
    2107                 :            :     }
    2108                 :            : 
    2109                 :    1840674 :     return false;
    2110                 :            : }
    2111                 :            : 
    2112                 :            : 
    2113                 :          0 : SCsROW ScColumn::SearchStyle( SCsROW nRow, const ScStyleSheet* pSearchStyle,
    2114                 :            :                                 bool bUp, bool bInSelection, const ScMarkData& rMark )
    2115                 :            : {
    2116         [ #  # ]:          0 :     if (bInSelection)
    2117                 :            :     {
    2118         [ #  # ]:          0 :         if (rMark.IsMultiMarked())
    2119                 :            :             return pAttrArray->SearchStyle( nRow, pSearchStyle, bUp,
    2120                 :          0 :                                     (ScMarkArray*) rMark.GetArray()+nCol );     //! const
    2121                 :            :         else
    2122                 :          0 :             return -1;
    2123                 :            :     }
    2124                 :            :     else
    2125                 :          0 :         return pAttrArray->SearchStyle( nRow, pSearchStyle, bUp, NULL );
    2126                 :            : }
    2127                 :            : 
    2128                 :            : 
    2129                 :          0 : bool ScColumn::SearchStyleRange( SCsROW& rRow, SCsROW& rEndRow, const ScStyleSheet* pSearchStyle,
    2130                 :            :                                     bool bUp, bool bInSelection, const ScMarkData& rMark )
    2131                 :            : {
    2132         [ #  # ]:          0 :     if (bInSelection)
    2133                 :            :     {
    2134         [ #  # ]:          0 :         if (rMark.IsMultiMarked())
    2135                 :            :             return pAttrArray->SearchStyleRange( rRow, rEndRow, pSearchStyle, bUp,
    2136                 :          0 :                                     (ScMarkArray*) rMark.GetArray()+nCol );     //! const
    2137                 :            :         else
    2138                 :          0 :             return false;
    2139                 :            :     }
    2140                 :            :     else
    2141                 :          0 :         return pAttrArray->SearchStyleRange( rRow, rEndRow, pSearchStyle, bUp, NULL );
    2142                 :            : }
    2143                 :            : 
    2144                 :            : 
    2145                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10