LCOV - code coverage report
Current view: top level - sc/source/core/data - cell2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 315 835 37.7 %
Date: 2012-08-25 Functions: 37 69 53.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 271 1244 21.8 %

           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 <algorithm>
      30                 :            : #include <deque>
      31                 :            : 
      32                 :            : #include <boost/bind.hpp>
      33                 :            : #include <sal/macros.h>
      34                 :            : #include <vcl/mapmod.hxx>
      35                 :            : #include <editeng/editobj.hxx>
      36                 :            : #include <editeng/editstat.hxx>
      37                 :            : #include "editeng/fieldupdater.hxx"
      38                 :            : 
      39                 :            : #include "cell.hxx"
      40                 :            : #include "compiler.hxx"
      41                 :            : #include "formula/errorcodes.hxx"
      42                 :            : #include "document.hxx"
      43                 :            : #include "rangenam.hxx"
      44                 :            : #include "rechead.hxx"
      45                 :            : #include "refupdat.hxx"
      46                 :            : #include "scmatrix.hxx"
      47                 :            : #include "editutil.hxx"
      48                 :            : #include "chgtrack.hxx"
      49                 :            : #include "externalrefmgr.hxx"
      50                 :            : #include "scitems.hxx"
      51                 :            : #include "patattr.hxx"
      52                 :            : #include <rtl/strbuf.hxx>
      53                 :            : 
      54                 :            : using namespace formula;
      55                 :            : 
      56                 :            : // STATIC DATA -----------------------------------------------------------
      57                 :            : 
      58                 :            : #ifdef USE_MEMPOOL
      59                 :         51 : IMPL_FIXEDMEMPOOL_NEWDEL( ScEditCell )
      60                 :            : #endif
      61                 :            : 
      62                 :            : // ============================================================================
      63                 :            : 
      64                 :        403 : ScEditCell::ScEditCell( const EditTextObject* pObject, ScDocument* pDocP,
      65                 :            :             const SfxItemPool* pFromPool )  :
      66                 :            :         ScBaseCell( CELLTYPE_EDIT ),
      67                 :            :         pString( NULL ),
      68                 :        403 :         pDoc( pDocP )
      69                 :            : {
      70         [ +  - ]:        403 :     SetTextObject( pObject, pFromPool );
      71                 :        403 : }
      72                 :            : 
      73                 :        389 : ScEditCell::ScEditCell(const ScEditCell& rCell, ScDocument& rDoc, const ScAddress& rDestPos) :
      74                 :        389 :     ScBaseCell(rCell), pString(NULL), pDoc(&rDoc)
      75                 :            : {
      76 [ +  - ][ +  - ]:        389 :     SetTextObject( rCell.pData, rCell.pDoc->GetEditPool() );
      77         [ +  - ]:        389 :     UpdateFields(rDestPos.Tab());
      78                 :        389 : }
      79                 :            : 
      80                 :         53 : ScEditCell::ScEditCell( const rtl::OUString& rString, ScDocument* pDocP )  :
      81                 :            :         ScBaseCell( CELLTYPE_EDIT ),
      82                 :            :         pString( NULL ),
      83                 :         53 :         pDoc( pDocP )
      84                 :            : {
      85                 :            :     OSL_ENSURE( rString.indexOf('\n') != -1 ||
      86                 :            :                 rString.indexOf(CHAR_CR) != -1,
      87                 :            :                 "EditCell mit einfachem Text !?!?" );
      88                 :            : 
      89         [ +  - ]:         53 :     EditEngine& rEngine = pDoc->GetEditEngine();
      90 [ +  - ][ +  - ]:         53 :     rEngine.SetText( rString );
                 [ +  - ]
      91         [ +  - ]:         53 :     pData = rEngine.CreateTextObject();
      92                 :         53 : }
      93                 :            : 
      94                 :        845 : ScEditCell::~ScEditCell()
      95                 :            : {
      96 [ +  - ][ +  - ]:        845 :     delete pData;
      97         [ +  + ]:        845 :     delete pString;
      98                 :            : 
      99                 :            : #if OSL_DEBUG_LEVEL > 0
     100                 :            :     eCellType = CELLTYPE_DESTROYED;
     101                 :            : #endif
     102                 :        845 : }
     103                 :            : 
     104                 :        124 : void ScEditCell::SetData( const EditTextObject* pObject,
     105                 :            :             const SfxItemPool* pFromPool )
     106                 :            : {
     107         [ +  - ]:        124 :     if ( pString )
     108                 :            :     {
     109         [ +  - ]:        124 :         delete pString;
     110                 :        124 :         pString = NULL;
     111                 :            :     }
     112         [ +  - ]:        124 :     delete pData;
     113                 :        124 :     SetTextObject( pObject, pFromPool );
     114                 :        124 : }
     115                 :            : 
     116                 :       1079 : void ScEditCell::GetData( const EditTextObject*& rpObject ) const
     117                 :            : {
     118                 :       1079 :     rpObject = pData;
     119                 :       1079 : }
     120                 :            : 
     121                 :        653 : rtl::OUString ScEditCell::GetString() const
     122                 :            : {
     123         [ +  + ]:        653 :     if ( pString )
     124                 :        316 :         return *pString;
     125                 :            : 
     126         [ +  - ]:        337 :     if ( pData )
     127                 :            :     {
     128                 :            :         // auch Text von URL-Feldern, Doc-Engine ist eine ScFieldEditEngine
     129         [ +  - ]:        337 :         EditEngine& rEngine = pDoc->GetEditEngine();
     130         [ +  - ]:        337 :         rEngine.SetText( *pData );
     131 [ +  - ][ +  - ]:        337 :         rtl::OUString sRet = ScEditUtil::GetMultilineString(rEngine); // string with line separators between paragraphs
                 [ +  - ]
     132                 :            :         // cache short strings for formulas
     133         [ +  - ]:        337 :         if ( sRet.getLength() < 256 )
     134         [ +  - ]:        337 :             pString = new rtl::OUString(sRet);   //! non-const
     135                 :        337 :         return sRet;
     136                 :            :     }
     137                 :            : 
     138                 :        653 :     return rtl::OUString();
     139                 :            : }
     140                 :            : 
     141                 :          0 : void ScEditCell::RemoveCharAttribs( const ScPatternAttr& rAttr )
     142                 :            : {
     143                 :            :     const struct {
     144                 :            :         sal_uInt16 nAttrType;
     145                 :            :         sal_uInt16 nCharType;
     146                 :            :     } AttrTypeMap[] = {
     147                 :            :         { ATTR_FONT,        EE_CHAR_FONTINFO },
     148                 :            :         { ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT },
     149                 :            :         { ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT },
     150                 :            :         { ATTR_FONT_COLOR,  EE_CHAR_COLOR }
     151                 :          0 :     };
     152                 :          0 :     sal_uInt16 nMapCount = sizeof (AttrTypeMap) / sizeof (AttrTypeMap[0]);
     153                 :            : 
     154                 :          0 :     const SfxItemSet& rSet = rAttr.GetItemSet();
     155                 :            :     const SfxPoolItem* pItem;
     156         [ #  # ]:          0 :     for (sal_uInt16 i = 0; i < nMapCount; ++i)
     157                 :            :     {
     158 [ #  # ][ #  # ]:          0 :         if ( rSet.GetItemState(AttrTypeMap[i].nAttrType, false, &pItem) == SFX_ITEM_SET )
     159         [ #  # ]:          0 :             pData->RemoveCharAttribs(AttrTypeMap[i].nCharType);
     160                 :            :     }
     161                 :          0 : }
     162                 :            : 
     163                 :        389 : void ScEditCell::UpdateFields(SCTAB nTab)
     164                 :            : {
     165         [ +  - ]:        389 :     editeng::FieldUpdater aUpdater = pData->GetFieldUpdater();
     166 [ +  - ][ +  - ]:        389 :     aUpdater.updateTableFields(nTab);
     167                 :        389 : }
     168                 :            : 
     169                 :        916 : void ScEditCell::SetTextObject( const EditTextObject* pObject,
     170                 :            :             const SfxItemPool* pFromPool )
     171                 :            : {
     172         [ +  - ]:        916 :     if ( pObject )
     173                 :            :     {
     174 [ +  - ][ +  - ]:        916 :         if ( pFromPool && pDoc->GetEditPool() == pFromPool )
                 [ +  - ]
     175                 :        916 :             pData = pObject->Clone();
     176                 :            :         else
     177                 :            :         {   //! anderer Pool
     178                 :            :             // Leider gibt es keinen anderen Weg, um den Pool umzuhaengen,
     179                 :            :             // als das Object durch eine entsprechende Engine zu schleusen..
     180                 :          0 :             EditEngine& rEngine = pDoc->GetEditEngine();
     181         [ #  # ]:          0 :             if ( pObject->HasOnlineSpellErrors() )
     182                 :            :             {
     183                 :          0 :                 sal_uLong nControl = rEngine.GetControlWord();
     184                 :          0 :                 const sal_uLong nSpellControl = EE_CNTRL_ONLINESPELLING | EE_CNTRL_ALLOWBIGOBJS;
     185                 :          0 :                 bool bNewControl = ( (nControl & nSpellControl) != nSpellControl );
     186         [ #  # ]:          0 :                 if ( bNewControl )
     187                 :          0 :                     rEngine.SetControlWord( nControl | nSpellControl );
     188                 :          0 :                 rEngine.SetText( *pObject );
     189                 :          0 :                 pData = rEngine.CreateTextObject();
     190         [ #  # ]:          0 :                 if ( bNewControl )
     191                 :          0 :                     rEngine.SetControlWord( nControl );
     192                 :            :             }
     193                 :            :             else
     194                 :            :             {
     195                 :          0 :                 rEngine.SetText( *pObject );
     196                 :          0 :                 pData = rEngine.CreateTextObject();
     197                 :            :             }
     198                 :            :         }
     199                 :            :     }
     200                 :            :     else
     201                 :          0 :         pData = NULL;
     202                 :        916 : }
     203                 :            : 
     204                 :        606 : ScEditDataArray::ScEditDataArray()
     205                 :            : {
     206                 :        606 : }
     207                 :            : 
     208                 :        606 : ScEditDataArray::~ScEditDataArray()
     209                 :            : {
     210                 :        606 : }
     211                 :            : 
     212                 :          0 : void ScEditDataArray::AddItem(SCTAB nTab, SCCOL nCol, SCROW nRow,
     213                 :            :                               EditTextObject* pOldData, EditTextObject* pNewData)
     214                 :            : {
     215         [ #  # ]:          0 :     maArray.push_back(Item(nTab, nCol, nRow, pOldData, pNewData));
     216                 :          0 : }
     217                 :            : 
     218                 :          0 : const ScEditDataArray::Item* ScEditDataArray::First()
     219                 :            : {
     220         [ #  # ]:          0 :     maIter = maArray.begin();
     221 [ #  # ][ #  # ]:          0 :     if (maIter == maArray.end())
     222                 :          0 :         return NULL;
     223                 :          0 :     return &(*maIter++);
     224                 :            : }
     225                 :            : 
     226                 :          0 : const ScEditDataArray::Item* ScEditDataArray::Next()
     227                 :            : {
     228 [ #  # ][ #  # ]:          0 :     if (maIter == maArray.end())
     229                 :          0 :         return NULL;
     230                 :          0 :     return &(*maIter++);
     231                 :            : }
     232                 :            : 
     233                 :            : // ============================================================================
     234                 :            : 
     235                 :          0 : ScEditDataArray::Item::Item(SCTAB nTab, SCCOL nCol, SCROW nRow,
     236                 :            :                             EditTextObject* pOldData, EditTextObject* pNewData) :
     237                 :            :     mnTab(nTab),
     238                 :            :     mnCol(nCol),
     239         [ #  # ]:          0 :     mnRow(nRow)
     240                 :            : {
     241         [ #  # ]:          0 :     mpOldData.reset(pOldData);
     242         [ #  # ]:          0 :     mpNewData.reset(pNewData);
     243                 :          0 : }
     244                 :            : 
     245         [ #  # ]:          0 : ScEditDataArray::Item::~Item()
     246                 :            : {
     247                 :          0 : }
     248                 :            : 
     249                 :          0 : const EditTextObject* ScEditDataArray::Item::GetOldData() const
     250                 :            : {
     251                 :          0 :     return mpOldData.get();
     252                 :            : }
     253                 :            : 
     254                 :          0 : const EditTextObject* ScEditDataArray::Item::GetNewData() const
     255                 :            : {
     256                 :          0 :     return mpNewData.get();
     257                 :            : }
     258                 :            : 
     259                 :          0 : SCTAB ScEditDataArray::Item::GetTab() const
     260                 :            : {
     261                 :          0 :     return mnTab;
     262                 :            : }
     263                 :            : 
     264                 :          0 : SCCOL ScEditDataArray::Item::GetCol() const
     265                 :            : {
     266                 :          0 :     return mnCol;
     267                 :            : }
     268                 :            : 
     269                 :          0 : SCROW ScEditDataArray::Item::GetRow() const
     270                 :            : {
     271                 :          0 :     return mnRow;
     272                 :            : }
     273                 :            : 
     274                 :            : // ============================================================================
     275                 :            : 
     276                 :            : namespace
     277                 :            : {
     278                 :            : 
     279                 :            : using std::deque;
     280                 :            : 
     281                 :            : typedef SCCOLROW(*DimensionSelector)(const ScSingleRefData&);
     282                 :            : 
     283                 :            : 
     284                 :          0 : static SCCOLROW lcl_GetCol(const ScSingleRefData& rData)
     285                 :            : {
     286                 :          0 :     return rData.nCol;
     287                 :            : }
     288                 :            : 
     289                 :            : 
     290                 :          0 : static SCCOLROW lcl_GetRow(const ScSingleRefData& rData)
     291                 :            : {
     292                 :          0 :     return rData.nRow;
     293                 :            : }
     294                 :            : 
     295                 :            : 
     296                 :          0 : static SCCOLROW lcl_GetTab(const ScSingleRefData& rData)
     297                 :            : {
     298                 :          0 :     return rData.nTab;
     299                 :            : }
     300                 :            : 
     301                 :            : 
     302                 :            : /** Check if both references span the same range in selected dimension.
     303                 :            :  */
     304                 :            : static bool
     305                 :          0 : lcl_checkRangeDimension(
     306                 :            :         const SingleDoubleRefProvider& rRef1,
     307                 :            :         const SingleDoubleRefProvider& rRef2,
     308                 :            :         const DimensionSelector aWhich)
     309                 :            : {
     310                 :            :     return
     311                 :          0 :         aWhich(rRef1.Ref1) == aWhich(rRef2.Ref1)
     312 [ #  # ][ #  # ]:          0 :         && aWhich(rRef1.Ref2) == aWhich(rRef2.Ref2);
     313                 :            : }
     314                 :            : 
     315                 :            : 
     316                 :            : static bool
     317                 :          0 : lcl_checkRangeDimensions(
     318                 :            :         const SingleDoubleRefProvider& rRef1,
     319                 :            :         const SingleDoubleRefProvider& rRef2,
     320                 :            :         bool& bCol, bool& bRow, bool& bTab)
     321                 :            : {
     322                 :          0 :     const bool bSameCols(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetCol));
     323                 :          0 :     const bool bSameRows(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetRow));
     324                 :          0 :     const bool bSameTabs(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetTab));
     325                 :            : 
     326                 :            :     // Test if exactly two dimensions are equal
     327 [ #  # ][ #  # ]:          0 :     if (!(bSameCols ^ bSameRows ^ bSameTabs)
         [ #  # ][ #  # ]
     328                 :            :             && (bSameCols || bSameRows || bSameTabs))
     329                 :            :     {
     330                 :          0 :         bCol = !bSameCols;
     331                 :          0 :         bRow = !bSameRows;
     332                 :          0 :         bTab = !bSameTabs;
     333                 :          0 :         return true;
     334                 :            :     }
     335                 :          0 :     return false;
     336                 :            : }
     337                 :            : 
     338                 :            : 
     339                 :            : /** Check if references in given reference list can possibly
     340                 :            :     form a range. To do that, two of their dimensions must be the same.
     341                 :            :  */
     342                 :            : static bool
     343                 :          0 : lcl_checkRangeDimensions(
     344                 :            :         const deque<ScToken*>::const_iterator aBegin,
     345                 :            :         const deque<ScToken*>::const_iterator aEnd,
     346                 :            :         bool& bCol, bool& bRow, bool& bTab)
     347                 :            : {
     348                 :          0 :     deque<ScToken*>::const_iterator aCur(aBegin);
     349         [ #  # ]:          0 :     ++aCur;
     350 [ #  # ][ #  # ]:          0 :     const SingleDoubleRefProvider aRef(**aBegin);
     351                 :          0 :     bool bOk(false);
     352                 :            :     {
     353 [ #  # ][ #  # ]:          0 :         const SingleDoubleRefProvider aRefCur(**aCur);
     354         [ #  # ]:          0 :         bOk = lcl_checkRangeDimensions(aRef, aRefCur, bCol, bRow, bTab);
     355                 :            :     }
     356 [ #  # ][ #  # ]:          0 :     while (bOk && aCur != aEnd)
         [ #  # ][ #  # ]
     357                 :            :     {
     358 [ #  # ][ #  # ]:          0 :         const SingleDoubleRefProvider aRefCur(**aCur);
     359                 :          0 :         bool bColTmp(false);
     360                 :          0 :         bool bRowTmp(false);
     361                 :          0 :         bool bTabTmp(false);
     362         [ #  # ]:          0 :         bOk = lcl_checkRangeDimensions(aRef, aRefCur, bColTmp, bRowTmp, bTabTmp);
     363 [ #  # ][ #  # ]:          0 :         bOk = bOk && (bCol == bColTmp && bRow == bRowTmp && bTab == bTabTmp);
         [ #  # ][ #  # ]
     364         [ #  # ]:          0 :         ++aCur;
     365                 :          0 :     }
     366                 :            : 
     367 [ #  # ][ #  # ]:          0 :     if (bOk && aCur == aEnd)
         [ #  # ][ #  # ]
     368                 :            :     {
     369                 :          0 :         return true;
     370                 :            :     }
     371                 :          0 :     return false;
     372                 :            : }
     373                 :            : 
     374                 :            : 
     375                 :            : bool
     376                 :          0 : lcl_lessReferenceBy(
     377                 :            :         const ScToken* const pRef1, const ScToken* const pRef2,
     378                 :            :         const DimensionSelector aWhich)
     379                 :            : {
     380         [ #  # ]:          0 :     const SingleDoubleRefProvider rRef1(*pRef1);
     381         [ #  # ]:          0 :     const SingleDoubleRefProvider rRef2(*pRef2);
     382 [ #  # ][ #  # ]:          0 :     return aWhich(rRef1.Ref1) < aWhich(rRef2.Ref1);
     383                 :            : }
     384                 :            : 
     385                 :            : 
     386                 :            : /** Returns true if range denoted by token pRef2 starts immediately after
     387                 :            :     range denoted by token pRef1. Dimension, in which the comparison takes
     388                 :            :     place, is given by aWhich.
     389                 :            :  */
     390                 :            : bool
     391                 :          0 : lcl_isImmediatelyFollowing(
     392                 :            :         const ScToken* const pRef1, const ScToken* const pRef2,
     393                 :            :         const DimensionSelector aWhich)
     394                 :            : {
     395         [ #  # ]:          0 :     const SingleDoubleRefProvider rRef1(*pRef1);
     396         [ #  # ]:          0 :     const SingleDoubleRefProvider rRef2(*pRef2);
     397 [ #  # ][ #  # ]:          0 :     return aWhich(rRef2.Ref1) - aWhich(rRef1.Ref2) == 1;
     398                 :            : }
     399                 :            : 
     400                 :            : 
     401                 :            : static bool
     402                 :          0 : lcl_checkIfAdjacent(
     403                 :            :         const deque<ScToken*>& rReferences,
     404                 :            :         const DimensionSelector aWhich)
     405                 :            : {
     406                 :            :     typedef deque<ScToken*>::const_iterator Iter;
     407                 :          0 :     Iter aBegin(rReferences.begin());
     408                 :          0 :     Iter aEnd(rReferences.end());
     409                 :          0 :     Iter aBegin1(aBegin);
     410 [ #  # ][ #  # ]:          0 :     ++aBegin1, --aEnd;
     411                 :            :     return std::equal(
     412                 :            :             aBegin, aEnd, aBegin1,
     413 [ #  # ][ #  # ]:          0 :             boost::bind(lcl_isImmediatelyFollowing, _1, _2, aWhich));
     414                 :            : }
     415                 :            : 
     416                 :            : 
     417                 :            : static void
     418                 :          0 : lcl_fillRangeFromRefList(
     419                 :            :         const deque<ScToken*>& rReferences, ScRange& rRange)
     420                 :            : {
     421                 :            :     const ScSingleRefData aStart(
     422 [ #  # ][ #  # ]:          0 :             SingleDoubleRefProvider(*rReferences.front()).Ref1);
     423                 :          0 :     rRange.aStart.Set(aStart.nCol, aStart.nRow, aStart.nTab);
     424                 :            :     const ScSingleRefData aEnd(
     425 [ #  # ][ #  # ]:          0 :             SingleDoubleRefProvider(*rReferences.back()).Ref2);
     426                 :          0 :     rRange.aEnd.Set(aEnd.nCol, aEnd.nRow, aEnd.nTab);
     427                 :          0 : }
     428                 :            : 
     429                 :            : 
     430                 :            : static bool
     431                 :          0 : lcl_refListFormsOneRange(
     432                 :            :         const ScAddress& aPos, deque<ScToken*>& rReferences,
     433                 :            :         ScRange& rRange)
     434                 :            : {
     435                 :            :     std::for_each(
     436                 :            :             rReferences.begin(), rReferences.end(),
     437                 :            :             bind(&ScToken::CalcAbsIfRel, _1, aPos))
     438 [ #  # ][ #  # ]:          0 :         ;
     439         [ #  # ]:          0 :     if (rReferences.size() == 1) {
     440         [ #  # ]:          0 :         lcl_fillRangeFromRefList(rReferences, rRange);
     441                 :          0 :         return true;
     442                 :            :     }
     443                 :            : 
     444                 :          0 :     bool bCell(false);
     445                 :          0 :     bool bRow(false);
     446                 :          0 :     bool bTab(false);
     447 [ #  # ][ #  # ]:          0 :     if (lcl_checkRangeDimensions(rReferences.begin(), rReferences.end(),
     448 [ #  # ][ #  # ]:          0 :             bCell, bRow, bTab))
     449                 :            :     {
     450                 :            :         DimensionSelector aWhich;
     451         [ #  # ]:          0 :         if (bCell)
     452                 :            :         {
     453                 :          0 :             aWhich = lcl_GetCol;
     454                 :            :         }
     455         [ #  # ]:          0 :         else if (bRow)
     456                 :            :         {
     457                 :          0 :             aWhich = lcl_GetRow;
     458                 :            :         }
     459         [ #  # ]:          0 :         else if (bTab)
     460                 :            :         {
     461                 :          0 :             aWhich = lcl_GetTab;
     462                 :            :         }
     463                 :            :         else
     464                 :            :         {
     465                 :            :             OSL_FAIL( "lcl_checkRangeDimensions shouldn't allow that!");
     466                 :          0 :             aWhich = lcl_GetRow;    // initialize to avoid warning
     467                 :            :         }
     468                 :            :         // Sort the references by start of range
     469                 :            :         std::sort(rReferences.begin(), rReferences.end(),
     470 [ #  # ][ #  # ]:          0 :                 boost::bind(lcl_lessReferenceBy, _1, _2, aWhich));
     471 [ #  # ][ #  # ]:          0 :         if (lcl_checkIfAdjacent(rReferences, aWhich))
     472                 :            :         {
     473         [ #  # ]:          0 :             lcl_fillRangeFromRefList(rReferences, rRange);
     474                 :          0 :             return true;
     475                 :            :         }
     476                 :            :     }
     477                 :          0 :     return false;
     478                 :            : }
     479                 :            : 
     480                 :            : 
     481                 :          0 : bool lcl_isReference(const FormulaToken& rToken)
     482                 :            : {
     483                 :            :     return
     484                 :          0 :         rToken.GetType() == svSingleRef ||
     485 [ #  # ][ #  # ]:          0 :         rToken.GetType() == svDoubleRef;
     486                 :            : }
     487                 :            : 
     488                 :            : }
     489                 :            : 
     490                 :         49 : bool ScFormulaCell::IsEmpty()
     491                 :            : {
     492                 :         49 :     MaybeInterpret();
     493                 :         49 :     return aResult.GetCellResultType() == formula::svEmptyCell;
     494                 :            : }
     495                 :            : 
     496                 :       1808 : bool ScFormulaCell::IsEmptyDisplayedAsString()
     497                 :            : {
     498                 :       1808 :     MaybeInterpret();
     499                 :       1808 :     return aResult.IsEmptyDisplayedAsString();
     500                 :            : }
     501                 :            : 
     502                 :       6509 : bool ScFormulaCell::IsValue()
     503                 :            : {
     504                 :       6509 :     MaybeInterpret();
     505                 :       6509 :     return aResult.IsValue();
     506                 :            : }
     507                 :            : 
     508                 :       4995 : double ScFormulaCell::GetValue()
     509                 :            : {
     510                 :       4995 :     MaybeInterpret();
     511   [ -  +  +  + ]:       9893 :     if ((!pCode->GetCodeError() || pCode->GetCodeError() == errDoubleRef) &&
         [ +  + ][ +  + ]
     512                 :       4898 :             !aResult.GetResultError())
     513                 :       4796 :         return aResult.GetDouble();
     514                 :       4995 :     return 0.0;
     515                 :            : }
     516                 :            : 
     517                 :          3 : double ScFormulaCell::GetValueAlways()
     518                 :            : {
     519                 :            :     // for goal seek: return result value even if error code is set
     520                 :          3 :     MaybeInterpret();
     521                 :          3 :     return aResult.GetDouble();
     522                 :            : }
     523                 :            : 
     524                 :        411 : rtl::OUString ScFormulaCell::GetString()
     525                 :            : {
     526                 :        411 :     MaybeInterpret();
     527   [ -  +  +  - ]:        774 :     if ((!pCode->GetCodeError() || pCode->GetCodeError() == errDoubleRef) &&
         [ +  + ][ +  + ]
     528                 :        363 :             !aResult.GetResultError())
     529                 :        363 :         return aResult.GetString();
     530                 :        411 :     return rtl::OUString();
     531                 :            : }
     532                 :            : 
     533                 :        154 : const ScMatrix* ScFormulaCell::GetMatrix()
     534                 :            : {
     535         [ +  - ]:        154 :     if ( pDocument->GetAutoCalc() )
     536                 :            :     {
     537                 :            :         // Was stored !bDirty but an accompanying matrix cell was bDirty?
     538                 :            :         // => we need to get the matrix.
     539 [ +  + ][ +  - ]:        154 :         if (!bDirty && cMatrixFlag == MM_FORMULA && !aResult.GetMatrix())
         [ +  - ][ +  + ]
                 [ +  + ]
           [ +  +  #  # ]
     540                 :         58 :             bDirty = true;
     541         [ +  + ]:        154 :         if ( IsDirtyOrInTableOpDirty() )
     542                 :         61 :             Interpret();
     543                 :            :     }
     544                 :        154 :     return aResult.GetMatrix().get();
     545                 :            : }
     546                 :            : 
     547                 :         17 : bool ScFormulaCell::GetMatrixOrigin( ScAddress& rPos ) const
     548                 :            : {
     549      [ +  +  - ]:         17 :     switch ( cMatrixFlag )
     550                 :            :     {
     551                 :            :         case MM_FORMULA :
     552                 :         11 :             rPos = aPos;
     553                 :         11 :             return true;
     554                 :            :         case MM_REFERENCE :
     555                 :            :         {
     556                 :          6 :             pCode->Reset();
     557                 :          6 :             ScToken* t = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
     558         [ +  - ]:          6 :             if( t )
     559                 :            :             {
     560                 :          6 :                 ScSingleRefData& rRef = t->GetSingleRef();
     561                 :          6 :                 rRef.CalcAbsIfRel( aPos );
     562         [ +  - ]:          6 :                 if ( rRef.Valid() )
     563                 :            :                 {
     564                 :          6 :                     rPos.Set( rRef.nCol, rRef.nRow, rRef.nTab );
     565                 :          6 :                     return true;
     566                 :            :                 }
     567                 :            :             }
     568                 :            :         }
     569                 :          0 :         break;
     570                 :            :     }
     571                 :         17 :     return false;
     572                 :            : }
     573                 :            : 
     574                 :            : 
     575                 :            : /*
     576                 :            :  Edge-Values:
     577                 :            : 
     578                 :            :    8
     579                 :            :  4   16
     580                 :            :    2
     581                 :            : 
     582                 :            :  inside: 1
     583                 :            :  outside: 0
     584                 :            :  (reserved: open: 32)
     585                 :            :  */
     586                 :            : 
     587                 :         12 : sal_uInt16 ScFormulaCell::GetMatrixEdge( ScAddress& rOrgPos )
     588                 :            : {
     589         [ +  - ]:         12 :     switch ( cMatrixFlag )
     590                 :            :     {
     591                 :            :         case MM_FORMULA :
     592                 :            :         case MM_REFERENCE :
     593                 :            :         {
     594                 :            :             static SCCOL nC;
     595                 :            :             static SCROW nR;
     596                 :         12 :             ScAddress aOrg;
     597 [ -  + ][ +  - ]:         12 :             if ( !GetMatrixOrigin( aOrg ) )
     598                 :          0 :                 return 0;               // bad luck..
     599         [ +  + ]:         12 :             if ( aOrg != rOrgPos )
     600                 :            :             {   // First time or a different matrix than last time.
     601                 :          9 :                 rOrgPos = aOrg;
     602                 :            :                 ScFormulaCell* pFCell;
     603         [ +  + ]:          9 :                 if ( cMatrixFlag == MM_REFERENCE )
     604 [ +  - ][ +  - ]:          1 :                     pFCell = (ScFormulaCell*) pDocument->GetCell( aOrg );
     605                 :            :                 else
     606                 :          8 :                     pFCell = this;      // this MM_FORMULA
     607                 :            :                 // There's only one this, don't compare pFCell==this.
     608 [ +  - ][ +  - ]:          9 :                 if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA
         [ +  - ][ +  - ]
     609                 :            :                   && pFCell->cMatrixFlag == MM_FORMULA )
     610                 :            :                 {
     611         [ +  - ]:          9 :                     pFCell->GetMatColsRows( nC, nR );
     612 [ +  - ][ -  + ]:          9 :                     if ( nC == 0 || nR == 0 )
     613                 :            :                     {
     614                 :            :                         // No ScMatrixFormulaCellToken available yet, calculate new.
     615                 :          0 :                         nC = 1;
     616                 :          0 :                         nR = 1;
     617                 :          0 :                         ScAddress aTmpOrg;
     618                 :            :                         ScBaseCell* pCell;
     619                 :          0 :                         ScAddress aAdr( aOrg );
     620         [ #  # ]:          0 :                         aAdr.IncCol();
     621                 :          0 :                         bool bCont = true;
     622         [ #  # ]:          0 :                         do
     623                 :            :                         {
     624         [ #  # ]:          0 :                             pCell = pDocument->GetCell( aAdr );
     625 [ #  # ][ #  # ]:          0 :                             if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     626         [ #  # ]:          0 :                               && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
     627 [ #  # ][ #  # ]:          0 :                               && ((ScFormulaCell*)pCell)->GetMatrixOrigin( aTmpOrg )
     628                 :          0 :                               && aTmpOrg == aOrg )
     629                 :            :                             {
     630                 :          0 :                                 nC++;
     631         [ #  # ]:          0 :                                 aAdr.IncCol();
     632                 :            :                             }
     633                 :            :                             else
     634                 :          0 :                                 bCont = false;
     635                 :            :                         } while ( bCont );
     636                 :          0 :                         aAdr = aOrg;
     637         [ #  # ]:          0 :                         aAdr.IncRow();
     638                 :          0 :                         bCont = true;
     639         [ #  # ]:          0 :                         do
     640                 :            :                         {
     641         [ #  # ]:          0 :                             pCell = pDocument->GetCell( aAdr );
     642 [ #  # ][ #  # ]:          0 :                             if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     643         [ #  # ]:          0 :                               && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
     644 [ #  # ][ #  # ]:          0 :                               && ((ScFormulaCell*)pCell)->GetMatrixOrigin( aTmpOrg )
     645                 :          0 :                               && aTmpOrg == aOrg )
     646                 :            :                             {
     647                 :          0 :                                 nR++;
     648         [ #  # ]:          0 :                                 aAdr.IncRow();
     649                 :            :                             }
     650                 :            :                             else
     651                 :          0 :                                 bCont = false;
     652                 :            :                         } while ( bCont );
     653         [ #  # ]:          0 :                         pFCell->SetMatColsRows( nC, nR );
     654                 :            :                     }
     655                 :            :                 }
     656                 :            :                 else
     657                 :            :                 {
     658                 :            : #if OSL_DEBUG_LEVEL > 0
     659                 :            :                     rtl::OUString aTmp;
     660                 :            :                     rtl::OStringBuffer aMsg(RTL_CONSTASCII_STRINGPARAM(
     661                 :            :                         "broken Matrix, no MatFormula at origin, Pos: "));
     662                 :            :                     aPos.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
     663                 :            :                     aMsg.append(rtl::OUStringToOString(aTmp, RTL_TEXTENCODING_ASCII_US));
     664                 :            :                     aMsg.append(RTL_CONSTASCII_STRINGPARAM(", MatOrg: "));
     665                 :            :                     aOrg.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
     666                 :            :                     aMsg.append(rtl::OUStringToOString(aTmp, RTL_TEXTENCODING_ASCII_US));
     667                 :            :                     OSL_FAIL(aMsg.getStr());
     668                 :            : #endif
     669                 :          0 :                     return 0;           // bad luck ...
     670                 :            :                 }
     671                 :            :             }
     672                 :            :             // here we are, healthy and clean, somewhere in between
     673                 :         12 :             SCsCOL dC = aPos.Col() - aOrg.Col();
     674                 :         12 :             SCsROW dR = aPos.Row() - aOrg.Row();
     675                 :         12 :             sal_uInt16 nEdges = 0;
     676 [ +  - ][ +  - ]:         12 :             if ( dC >= 0 && dR >= 0 && dC < nC && dR < nR )
         [ +  - ][ +  - ]
     677                 :            :             {
     678         [ +  - ]:         12 :                 if ( dC == 0 )
     679                 :         12 :                     nEdges |= 4;            // left edge
     680         [ +  + ]:         12 :                 if ( dC+1 == nC )
     681                 :          6 :                     nEdges |= 16;           // right edge
     682         [ +  + ]:         12 :                 if ( dR == 0 )
     683                 :          8 :                     nEdges |= 8;            // top edge
     684         [ +  + ]:         12 :                 if ( dR+1 == nR )
     685                 :          2 :                     nEdges |= 2;            // bottom edge
     686         [ -  + ]:         12 :                 if ( !nEdges )
     687                 :          0 :                     nEdges = 1;             // inside
     688                 :            :             }
     689                 :            : #if OSL_DEBUG_LEVEL > 0
     690                 :            :             else
     691                 :            :             {
     692                 :            :                 rtl::OUString aTmp;
     693                 :            :                 rtl::OStringBuffer aMsg( "broken Matrix, Pos: " );
     694                 :            :                 aPos.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
     695                 :            :                 aMsg.append(rtl::OUStringToOString(aTmp, RTL_TEXTENCODING_UTF8 ));
     696                 :            :                 aMsg.append(RTL_CONSTASCII_STRINGPARAM(", MatOrg: "));
     697                 :            :                 aOrg.Format( aTmp, SCA_VALID_COL | SCA_VALID_ROW, pDocument );
     698                 :            :                 aMsg.append(rtl::OUStringToOString(aTmp, RTL_TEXTENCODING_UTF8 ));
     699                 :            :                 aMsg.append(RTL_CONSTASCII_STRINGPARAM(", MatCols: "));
     700                 :            :                 aMsg.append(static_cast<sal_Int32>( nC ));
     701                 :            :                 aMsg.append(RTL_CONSTASCII_STRINGPARAM(", MatRows: "));
     702                 :            :                 aMsg.append(static_cast<sal_Int32>( nR ));
     703                 :            :                 aMsg.append(RTL_CONSTASCII_STRINGPARAM(", DiffCols: "));
     704                 :            :                 aMsg.append(static_cast<sal_Int32>( dC ));
     705                 :            :                 aMsg.append(RTL_CONSTASCII_STRINGPARAM(", DiffRows: "));
     706                 :            :                 aMsg.append(static_cast<sal_Int32>( dR ));
     707                 :            :                 OSL_FAIL( aMsg.makeStringAndClear().getStr());
     708                 :            :             }
     709                 :            : #endif
     710                 :         12 :             return nEdges;
     711                 :            : //            break;
     712                 :            :         }
     713                 :            :         default:
     714                 :         12 :             return 0;
     715                 :            :     }
     716                 :            : }
     717                 :            : 
     718                 :       2849 : sal_uInt16 ScFormulaCell::GetErrCode()
     719                 :            : {
     720                 :       2849 :     MaybeInterpret();
     721                 :            : 
     722                 :            :     /* FIXME: If ScTokenArray::SetCodeError() was really only for code errors
     723                 :            :      * and not also abused for signaling other error conditions we could bail
     724                 :            :      * out even before attempting to interpret broken code. */
     725                 :       2849 :     sal_uInt16 nErr =  pCode->GetCodeError();
     726         [ +  + ]:       2849 :     if (nErr)
     727                 :         81 :         return nErr;
     728                 :       2849 :     return aResult.GetResultError();
     729                 :            : }
     730                 :            : 
     731                 :         16 : sal_uInt16 ScFormulaCell::GetRawError()
     732                 :            : {
     733                 :         16 :     sal_uInt16 nErr =  pCode->GetCodeError();
     734         [ -  + ]:         16 :     if (nErr)
     735                 :          0 :         return nErr;
     736                 :         16 :     return aResult.GetResultError();
     737                 :            : }
     738                 :            : 
     739                 :         10 : bool ScFormulaCell::HasOneReference( ScRange& r ) const
     740                 :            : {
     741                 :         10 :     pCode->Reset();
     742                 :         10 :     ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
     743 [ +  - ][ +  - ]:         10 :     if( p && !pCode->GetNextReferenceRPN() )        // nur eine!
                 [ +  - ]
     744                 :            :     {
     745         [ +  - ]:         10 :         p->CalcAbsIfRel( aPos );
     746         [ +  - ]:         10 :         SingleDoubleRefProvider aProv( *p );
     747                 :            :         r.aStart.Set( aProv.Ref1.nCol,
     748                 :            :                       aProv.Ref1.nRow,
     749                 :         10 :                       aProv.Ref1.nTab );
     750                 :            :         r.aEnd.Set( aProv.Ref2.nCol,
     751                 :            :                     aProv.Ref2.nRow,
     752                 :         10 :                     aProv.Ref2.nTab );
     753                 :         10 :         return true;
     754                 :            :     }
     755                 :            :     else
     756                 :         10 :         return false;
     757                 :            : }
     758                 :            : 
     759                 :            : bool
     760                 :         10 : ScFormulaCell::HasRefListExpressibleAsOneReference(ScRange& rRange) const
     761                 :            : {
     762                 :            :     /* If there appears just one reference in the formula, it's the same
     763                 :            :        as HasOneReference(). If there are more of them, they can denote
     764                 :            :        one range if they are (sole) arguments of one function.
     765                 :            :        Union of these references must form one range and their
     766                 :            :        intersection must be empty set.
     767                 :            :     */
     768                 :            : 
     769                 :            :     // Detect the simple case of exactly one reference in advance without all
     770                 :            :     // overhead.
     771                 :            :     // #i107741# Doing so actually makes outlines using SUBTOTAL(x;reference)
     772                 :            :     // work again, where the function does not have only references.
     773 [ +  - ][ +  - ]:         10 :     if (HasOneReference( rRange))
     774                 :         10 :         return true;
     775                 :            : 
     776                 :          0 :     pCode->Reset();
     777                 :            :     // Get first reference, if any
     778                 :            :     ScToken* const pFirstReference(
     779 [ #  # ][ #  # ]:          0 :             dynamic_cast<ScToken*>(pCode->GetNextReferenceRPN()));
     780         [ #  # ]:          0 :     if (pFirstReference)
     781                 :            :     {
     782                 :            :         // Collect all consecutive references, starting by the one
     783                 :            :         // already found
     784         [ #  # ]:          0 :         std::deque<ScToken*> aReferences;
     785         [ #  # ]:          0 :         aReferences.push_back(pFirstReference);
     786         [ #  # ]:          0 :         FormulaToken* pToken(pCode->NextRPN());
     787                 :          0 :         FormulaToken* pFunction(0);
     788         [ #  # ]:          0 :         while (pToken)
     789                 :            :         {
     790         [ #  # ]:          0 :             if (lcl_isReference(*pToken))
     791                 :            :             {
     792 [ #  # ][ #  # ]:          0 :                 aReferences.push_back(dynamic_cast<ScToken*>(pToken));
     793         [ #  # ]:          0 :                 pToken = pCode->NextRPN();
     794                 :            :             }
     795                 :            :             else
     796                 :            :             {
     797 [ #  # ][ #  # ]:          0 :                 if (pToken->IsFunction())
     798                 :            :                 {
     799                 :          0 :                     pFunction = pToken;
     800                 :            :                 }
     801                 :          0 :                 break;
     802                 :            :             }
     803                 :            :         }
     804 [ #  # ][ #  # ]:          0 :         if (pFunction && !pCode->GetNextReferenceRPN()
           [ #  #  #  # ]
                 [ #  # ]
     805         [ #  # ]:          0 :                 && (pFunction->GetParamCount() == aReferences.size()))
     806                 :            :         {
     807         [ #  # ]:          0 :             return lcl_refListFormsOneRange(aPos, aReferences, rRange);
     808         [ #  # ]:          0 :         }
     809                 :            :     }
     810                 :         10 :     return false;
     811                 :            : }
     812                 :            : 
     813                 :         79 : bool ScFormulaCell::HasRelNameReference() const
     814                 :            : {
     815                 :         79 :     pCode->Reset();
     816                 :            :     ScToken* t;
     817         [ +  + ]:        172 :     while ( ( t = static_cast<ScToken*>(pCode->GetNextReferenceRPN()) ) != NULL )
     818                 :            :     {
     819   [ +  -  +  +  :        198 :         if ( t->GetSingleRef().IsRelName() ||
           -  + ][ -  + ]
     820                 :         93 :                 (t->GetType() == formula::svDoubleRef &&
     821                 :         12 :                 t->GetDoubleRef().Ref2.IsRelName()) )
     822                 :          0 :             return true;
     823                 :            :     }
     824                 :         79 :     return false;
     825                 :            : }
     826                 :            : 
     827                 :          0 : bool ScFormulaCell::HasColRowName() const
     828                 :            : {
     829                 :          0 :     pCode->Reset();
     830                 :          0 :     return (pCode->GetNextColRowName() != NULL);
     831                 :            : }
     832                 :            : 
     833                 :         64 : bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
     834                 :            :                                     const ScRange& r,
     835                 :            :                                     SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
     836                 :            :                                     ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
     837                 :            : {
     838                 :         64 :     bool bCellStateChanged = false;
     839                 :            : 
     840                 :         64 :     SCCOL nCol1 = r.aStart.Col();
     841                 :         64 :     SCROW nRow1 = r.aStart.Row();
     842                 :         64 :     SCTAB nTab1 = r.aStart.Tab();
     843                 :         64 :     SCCOL nCol2 = r.aEnd.Col();
     844                 :         64 :     SCROW nRow2 = r.aEnd.Row();
     845                 :         64 :     SCTAB nTab2 = r.aEnd.Tab();
     846                 :         64 :     SCCOL nCol = aPos.Col();
     847                 :         64 :     SCROW nRow = aPos.Row();
     848                 :         64 :     SCTAB nTab = aPos.Tab();
     849                 :         64 :     ScAddress aUndoPos( aPos );         // position for undo cell in pUndoDoc
     850         [ +  + ]:         64 :     if ( pUndoCellPos )
     851                 :         18 :         aUndoPos = *pUndoCellPos;
     852                 :         64 :     ScAddress aOldPos( aPos );
     853                 :            : //  bool bPosChanged = false;           // ob diese Zelle bewegt wurde
     854                 :         64 :     bool bIsInsert = false;
     855         [ +  + ]:         64 :     if (eUpdateRefMode == URM_INSDEL)
     856                 :            :     {
     857 [ +  - ][ +  + ]:         18 :         bIsInsert = (nDx >= 0 && nDy >= 0 && nDz >= 0);
                 [ +  - ]
     858 [ -  + ][ #  # ]:         18 :         if ( nDx && nRow >= nRow1 && nRow <= nRow2 &&
         [ #  # ][ #  # ]
                 [ #  # ]
     859                 :            :             nTab >= nTab1 && nTab <= nTab2 )
     860                 :            :         {
     861         [ #  # ]:          0 :             if (nCol >= nCol1)
     862                 :            :             {
     863                 :          0 :                 nCol = sal::static_int_cast<SCCOL>( nCol + nDx );
     864         [ #  # ]:          0 :                 if ((SCsCOL) nCol < 0)
     865                 :          0 :                     nCol = 0;
     866         [ #  # ]:          0 :                 else if ( nCol > MAXCOL )
     867                 :          0 :                     nCol = MAXCOL;
     868                 :          0 :                 bCellStateChanged = aPos.Col() != nCol;
     869                 :          0 :                 aPos.SetCol( nCol );
     870                 :            :             }
     871                 :            :         }
     872 [ +  - ][ +  - ]:         18 :         if ( nDy && nCol >= nCol1 && nCol <= nCol2 &&
         [ +  - ][ +  - ]
                 [ +  + ]
     873                 :            :             nTab >= nTab1 && nTab <= nTab2 )
     874                 :            :         {
     875         [ +  + ]:          6 :             if (nRow >= nRow1)
     876                 :            :             {
     877                 :          3 :                 nRow = sal::static_int_cast<SCROW>( nRow + nDy );
     878         [ -  + ]:          3 :                 if ((SCsROW) nRow < 0)
     879                 :          0 :                     nRow = 0;
     880         [ -  + ]:          3 :                 else if ( nRow > MAXROW )
     881                 :          0 :                     nRow = MAXROW;
     882                 :          3 :                 bCellStateChanged = aPos.Row() != nRow;
     883                 :          3 :                 aPos.SetRow( nRow );
     884                 :            :             }
     885                 :            :         }
     886 [ -  + ][ #  # ]:         18 :         if ( nDz && nCol >= nCol1 && nCol <= nCol2 &&
         [ #  # ][ #  # ]
                 [ #  # ]
     887                 :            :             nRow >= nRow1 && nRow <= nRow2 )
     888                 :            :         {
     889         [ #  # ]:          0 :             if (nTab >= nTab1)
     890                 :            :             {
     891         [ #  # ]:          0 :                 SCTAB nMaxTab = pDocument->GetTableCount() - 1;
     892                 :          0 :                 nTab = sal::static_int_cast<SCTAB>( nTab + nDz );
     893         [ #  # ]:          0 :                 if ((SCsTAB) nTab < 0)
     894                 :          0 :                     nTab = 0;
     895         [ #  # ]:          0 :                 else if ( nTab > nMaxTab )
     896                 :          0 :                     nTab = nMaxTab;
     897                 :          0 :                 bCellStateChanged = aPos.Tab() != nTab;
     898                 :          0 :                 aPos.SetTab( nTab );
     899                 :            :             }
     900                 :            :         }
     901                 :            :     }
     902         [ +  - ]:         46 :     else if ( r.In( aPos ) )
     903                 :            :     {
     904                 :         46 :         aOldPos.Set( nCol - nDx, nRow - nDy, nTab - nDz );
     905                 :            :     }
     906                 :            : 
     907                 :         64 :     bool bHasRefs = false;
     908                 :         64 :     bool bHasColRowNames = false;
     909                 :         64 :     bool bOnRefMove = false;
     910         [ +  - ]:         64 :     if ( !pDocument->IsClipOrUndo() )
     911                 :            :     {
     912                 :         64 :         pCode->Reset();
     913         [ +  - ]:         64 :         bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
     914 [ +  - ][ +  + ]:         64 :         if ( !bHasRefs || eUpdateRefMode == URM_COPY )
     915                 :            :         {
     916                 :         46 :             pCode->Reset();
     917         [ +  - ]:         46 :             bHasColRowNames = (pCode->GetNextColRowName() != NULL);
     918 [ -  + ][ #  # ]:         46 :             bHasRefs = bHasRefs || bHasColRowNames;
     919                 :            :         }
     920                 :         64 :         bOnRefMove = pCode->IsRecalcModeOnRefMove();
     921                 :            :     }
     922 [ -  + ][ #  # ]:         64 :     if( bHasRefs || bOnRefMove )
     923                 :            :     {
     924 [ -  + ][ #  # ]:         64 :         ScTokenArray* pOld = pUndoDoc ? pCode->Clone() : NULL;
     925                 :            :         ScRangeData* pRangeData;
     926                 :         64 :         bool bValChanged = false;
     927                 :         64 :         bool bRangeModified = false;    // any range, not only shared formula
     928                 :         64 :         bool bRefSizeChanged = false;
     929         [ +  - ]:         64 :         if ( bHasRefs )
     930                 :            :         {
     931         [ +  - ]:         64 :             ScCompiler aComp(pDocument, aPos, *pCode);
     932 [ +  - ][ +  - ]:         64 :             aComp.SetGrammar(pDocument->GetGrammar());
     933                 :            :             pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, r,
     934                 :            :                                              nDx, nDy, nDz,
     935         [ +  - ]:         64 :                                              bValChanged, bRefSizeChanged);
     936 [ +  - ][ +  - ]:         64 :             bRangeModified = aComp.HasModifiedRange();
     937                 :            :         }
     938                 :            :         else
     939                 :            :         {
     940                 :          0 :             bValChanged = false;
     941                 :          0 :             pRangeData = NULL;
     942                 :          0 :             bRangeModified = false;
     943                 :          0 :             bRefSizeChanged = false;
     944                 :            :         }
     945                 :            : 
     946                 :         64 :         bCellStateChanged |= bValChanged;
     947                 :            : 
     948         [ +  + ]:         64 :         if ( bOnRefMove )
     949 [ +  - ][ +  - ]:          6 :             bOnRefMove = (bValChanged || (aPos != aOldPos));
     950                 :            :             // Cell may reference itself, e.g. ocColumn, ocRow without parameter
     951                 :            : 
     952                 :            :         bool bColRowNameCompile, bHasRelName, bNewListening, bInDeleteUndo;
     953         [ +  - ]:         64 :         if ( bHasRefs )
     954                 :            :         {
     955                 :            :             // Upon Insert ColRowNames have to be recompiled in case the
     956                 :            :             // insertion occurs right in front of the range.
     957                 :            :             bColRowNameCompile =
     958 [ +  + ][ +  - ]:         64 :                 (eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0));
                 [ +  + ]
     959         [ +  + ]:         64 :             if ( bColRowNameCompile )
     960                 :            :             {
     961                 :         12 :                 bColRowNameCompile = false;
     962                 :            :                 ScToken* t;
     963                 :         12 :                 ScRangePairList* pColList = pDocument->GetColNameRanges();
     964                 :         12 :                 ScRangePairList* pRowList = pDocument->GetRowNameRanges();
     965                 :         12 :                 pCode->Reset();
     966 [ +  - ][ +  - ]:         12 :                 while ( !bColRowNameCompile && (t = static_cast<ScToken*>(pCode->GetNextColRowName())) != NULL )
         [ -  + ][ -  + ]
     967                 :            :                 {
     968         [ #  # ]:          0 :                     ScSingleRefData& rRef = t->GetSingleRef();
     969 [ #  # ][ #  # ]:          0 :                     if ( nDy > 0 && rRef.IsColRel() )
                 [ #  # ]
     970                 :            :                     {   // ColName
     971         [ #  # ]:          0 :                         rRef.CalcAbsIfRel( aPos );
     972                 :          0 :                         ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
     973         [ #  # ]:          0 :                         ScRangePair* pR = pColList->Find( aAdr );
     974         [ #  # ]:          0 :                         if ( pR )
     975                 :            :                         {   // definiert
     976         [ #  # ]:          0 :                             if ( pR->GetRange(1).aStart.Row() == nRow1 )
     977                 :          0 :                                 bColRowNameCompile = true;
     978                 :            :                         }
     979                 :            :                         else
     980                 :            :                         {   // on the fly
     981         [ #  # ]:          0 :                             if ( rRef.nRow + 1 == nRow1 )
     982                 :          0 :                                 bColRowNameCompile = true;
     983                 :            :                         }
     984                 :            :                     }
     985 [ #  # ][ #  # ]:          0 :                     if ( nDx > 0 && rRef.IsRowRel() )
                 [ #  # ]
     986                 :            :                     {   // RowName
     987         [ #  # ]:          0 :                         rRef.CalcAbsIfRel( aPos );
     988                 :          0 :                         ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
     989         [ #  # ]:          0 :                         ScRangePair* pR = pRowList->Find( aAdr );
     990         [ #  # ]:          0 :                         if ( pR )
     991                 :            :                         {   // definiert
     992         [ #  # ]:          0 :                             if ( pR->GetRange(1).aStart.Col() == nCol1 )
     993                 :          0 :                                 bColRowNameCompile = true;
     994                 :            :                         }
     995                 :            :                         else
     996                 :            :                         {   // on the fly
     997         [ #  # ]:          0 :                             if ( rRef.nCol + 1 == nCol1 )
     998                 :          0 :                                 bColRowNameCompile = true;
     999                 :            :                         }
    1000                 :            :                     }
    1001                 :            :                 }
    1002                 :            :             }
    1003         [ -  + ]:         52 :             else if ( eUpdateRefMode == URM_MOVE )
    1004                 :            :             {   // bei Move/D&D neu kompilieren wenn ColRowName verschoben wurde
    1005                 :            :                 // oder diese Zelle auf einen zeigt und verschoben wurde
    1006                 :          0 :                 bColRowNameCompile = bCompile;      // evtl. aus Copy-ctor
    1007         [ #  # ]:          0 :                 if ( !bColRowNameCompile )
    1008                 :            :                 {
    1009                 :          0 :                     bool bMoved = (aPos != aOldPos);
    1010                 :          0 :                     pCode->Reset();
    1011         [ #  # ]:          0 :                     ScToken* t = static_cast<ScToken*>(pCode->GetNextColRowName());
    1012 [ #  # ][ #  # ]:          0 :                     if ( t && bMoved )
    1013                 :          0 :                         bColRowNameCompile = true;
    1014 [ #  # ][ #  # ]:          0 :                     while ( t && !bColRowNameCompile )
                 [ #  # ]
    1015                 :            :                     {
    1016         [ #  # ]:          0 :                         ScSingleRefData& rRef = t->GetSingleRef();
    1017         [ #  # ]:          0 :                         rRef.CalcAbsIfRel( aPos );
    1018         [ #  # ]:          0 :                         if ( rRef.Valid() )
    1019                 :            :                         {
    1020                 :          0 :                             ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
    1021         [ #  # ]:          0 :                             if ( r.In( aAdr ) )
    1022                 :          0 :                                 bColRowNameCompile = true;
    1023                 :            :                         }
    1024         [ #  # ]:          0 :                         t = static_cast<ScToken*>(pCode->GetNextColRowName());
    1025                 :            :                     }
    1026                 :            :                 }
    1027                 :            :             }
    1028 [ +  + ][ -  + ]:         52 :             else if ( eUpdateRefMode == URM_COPY && bHasColRowNames && bValChanged )
                 [ #  # ]
    1029                 :            :             {
    1030                 :          0 :                 bColRowNameCompile = true;
    1031                 :            :             }
    1032                 :         64 :             ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
    1033 [ #  # ][ -  + ]:         64 :             if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
                 [ -  + ]
    1034                 :          0 :                 bInDeleteUndo = true;
    1035                 :            :             else
    1036                 :         64 :                 bInDeleteUndo = false;
    1037                 :            :             // RelNameRefs are always moved
    1038         [ +  - ]:         64 :             bHasRelName = HasRelNameReference();
    1039                 :            :             // Reference changed and new listening needed?
    1040                 :            :             // Except in Insert/Delete without specialties.
    1041                 :            :             bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
    1042                 :            :                     || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
    1043                 :            :                             bInDeleteUndo || bRefSizeChanged)) ||
    1044                 :            :                     (bHasRelName && eUpdateRefMode != URM_COPY))
    1045                 :            :                 // #i36299# Don't duplicate action during cut&paste / drag&drop
    1046                 :            :                 // on a cell in the range moved, start/end listeners is done
    1047                 :            :                 // via ScDocument::DeleteArea() and ScDocument::CopyFromClip().
    1048                 :            :                 && !(eUpdateRefMode == URM_MOVE &&
    1049 [ +  - ][ +  - ]:         64 :                         pDocument->IsInsertingFromOtherDoc() && r.In(aPos));
         [ +  - ][ +  + ]
         [ +  - ][ +  - ]
         [ +  + ][ -  + ]
         [ #  # ][ -  + ]
         [ #  # ][ #  # ]
    1050         [ +  + ]:         64 :             if ( bNewListening )
    1051         [ +  - ]:          2 :                 EndListeningTo( pDocument, pOld, aOldPos );
    1052                 :            :         }
    1053                 :            :         else
    1054                 :            :         {
    1055                 :            :             bColRowNameCompile = bHasRelName = bNewListening = bInDeleteUndo =
    1056                 :          0 :                 false;
    1057                 :            :         }
    1058                 :            : 
    1059                 :         64 :         bool bNeedDirty = false;
    1060                 :            :         // NeedDirty bei Aenderungen ausser Copy und Move/Insert ohne RelNames
    1061 [ +  - ][ +  - ]:         64 :         if ( bRangeModified || pRangeData || bColRowNameCompile ||
         [ +  - ][ +  + ]
         [ +  - ][ -  + ]
         [ #  # ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
    1062                 :            :                 (bValChanged && eUpdateRefMode != URM_COPY &&
    1063                 :            :                  (eUpdateRefMode != URM_MOVE || bHasRelName) &&
    1064                 :          9 :                  (!bIsInsert || bHasRelName || bInDeleteUndo ||
    1065                 :            :                   bRefSizeChanged)) || bOnRefMove)
    1066                 :          9 :             bNeedDirty = true;
    1067                 :            :         else
    1068                 :         55 :             bNeedDirty = false;
    1069 [ -  + ][ #  # ]:         64 :         if (pUndoDoc && (bValChanged || pRangeData || bOnRefMove))
         [ #  # ][ #  # ]
    1070                 :            :         {
    1071                 :            :             //  Copy the cell to aUndoPos, which is its current position in the document,
    1072                 :            :             //  so this works when UpdateReference is called before moving the cells
    1073                 :            :             //  (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference
    1074                 :            :             //  is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed).
    1075                 :            : 
    1076                 :            :             // If there is already a formula cell in the undo document, don't overwrite it,
    1077                 :            :             // the first (oldest) is the important cell.
    1078 [ #  # ][ #  # ]:          0 :             if ( pUndoDoc->GetCellType( aUndoPos ) != CELLTYPE_FORMULA )
    1079                 :            :             {
    1080                 :            :                 ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos,
    1081 [ #  # ][ #  # ]:          0 :                         pOld, eTempGrammar, cMatrixFlag );
    1082         [ #  # ]:          0 :                 pFCell->aResult.SetToken( NULL);  // to recognize it as changed later (Cut/Paste!)
    1083 [ #  # ][ #  # ]:          0 :                 pUndoDoc->PutCell( aUndoPos, pFCell );
    1084                 :            :             }
    1085                 :            :         }
    1086                 :         64 :         bValChanged = false;
    1087         [ -  + ]:         64 :         if ( pRangeData )
    1088                 :            :         {   // Replace shared formula with own formula
    1089         [ #  # ]:          0 :             pDocument->RemoveFromFormulaTree( this );   // update formula count
    1090 [ #  # ][ #  # ]:          0 :             delete pCode;
    1091         [ #  # ]:          0 :             pCode = pRangeData->GetCode()->Clone();
    1092                 :            :             // #i18937# #i110008# call MoveRelWrap, but with the old position
    1093 [ #  # ][ #  # ]:          0 :             ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
                 [ #  # ]
    1094         [ #  # ]:          0 :             ScCompiler aComp2(pDocument, aPos, *pCode);
    1095 [ #  # ][ #  # ]:          0 :             aComp2.SetGrammar(pDocument->GetGrammar());
    1096                 :            :             aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, r,
    1097         [ #  # ]:          0 :                 nDx, nDy, nDz );
    1098                 :          0 :             bValChanged = true;
    1099         [ #  # ]:          0 :             bNeedDirty = true;
    1100                 :            :         }
    1101 [ +  - ][ +  - ]:         64 :         if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
         [ +  - ][ -  + ]
                 [ -  + ]
    1102                 :            :         {
    1103         [ #  # ]:          0 :             CompileTokenArray( bNewListening ); // kein Listening
    1104                 :          0 :             bNeedDirty = true;
    1105                 :            :         }
    1106         [ +  - ]:         64 :         if ( !bInDeleteUndo )
    1107                 :            :         {   // In ChangeTrack Delete-Reject listeners are established in
    1108                 :            :             // InsertCol/InsertRow
    1109         [ +  + ]:         64 :             if ( bNewListening )
    1110                 :            :             {
    1111         [ +  - ]:          2 :                 if ( eUpdateRefMode == URM_INSDEL )
    1112                 :            :                 {
    1113                 :            :                     // Inserts/Deletes re-establish listeners after all
    1114                 :            :                     // UpdateReference calls.
    1115                 :            :                     // All replaced shared formula listeners have to be
    1116                 :            :                     // established after an Insert or Delete. Do nothing here.
    1117                 :          2 :                     SetNeedsListening( true);
    1118                 :            :                 }
    1119                 :            :                 else
    1120         [ #  # ]:          0 :                     StartListeningTo( pDocument );
    1121                 :            :             }
    1122                 :            :         }
    1123 [ +  + ][ +  + ]:         64 :         if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
         [ -  + ][ #  # ]
    1124                 :            :         {   // Referenzen abgeschnitten, ungueltig o.ae.?
    1125                 :          9 :             bool bOldAutoCalc = pDocument->GetAutoCalc();
    1126                 :            :             // kein Interpret in SubMinimalRecalc wegen evtl. falscher Referenzen
    1127         [ +  - ]:          9 :             pDocument->SetAutoCalc( false );
    1128         [ +  - ]:          9 :             SetDirty();
    1129         [ +  - ]:          9 :             pDocument->SetAutoCalc( bOldAutoCalc );
    1130                 :            :         }
    1131                 :            : 
    1132 [ -  + ][ #  # ]:         64 :         delete pOld;
    1133                 :            :     }
    1134                 :         64 :     return bCellStateChanged;
    1135                 :            : }
    1136                 :            : 
    1137                 :         18 : void ScFormulaCell::UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets)
    1138                 :            : {
    1139                 :         18 :     bool bPosChanged = ( aPos.Tab() >= nTable ? true : false );
    1140                 :         18 :     pCode->Reset();
    1141 [ +  - ][ +  - ]:         18 :     if( pCode->GetNextReferenceRPN() && !pDocument->IsClipOrUndo() )
                 [ +  - ]
    1142                 :            :     {
    1143         [ +  - ]:         18 :         EndListeningTo( pDocument );
    1144                 :            :         // IncTab _nach_ EndListeningTo und _vor_ Compiler UpdateInsertTab !
    1145         [ +  - ]:         18 :         if ( bPosChanged )
    1146         [ +  - ]:         18 :             aPos.IncTab(nNewSheets);
    1147                 :            :         ScRangeData* pRangeData;
    1148         [ +  - ]:         18 :         ScCompiler aComp(pDocument, aPos, *pCode);
    1149 [ +  - ][ +  - ]:         18 :         aComp.SetGrammar(pDocument->GetGrammar());
    1150         [ +  - ]:         18 :         pRangeData = aComp.UpdateInsertTab( nTable, false, nNewSheets );
    1151         [ -  + ]:         18 :         if (pRangeData)                     // Shared Formula gegen echte Formel
    1152                 :            :         {                                   // austauschen
    1153                 :            :             bool bRefChanged;
    1154         [ #  # ]:          0 :             pDocument->RemoveFromFormulaTree( this );   // update formula count
    1155 [ #  # ][ #  # ]:          0 :             delete pCode;
    1156 [ #  # ][ #  # ]:          0 :             pCode = new ScTokenArray( *pRangeData->GetCode() );
    1157         [ #  # ]:          0 :             ScCompiler aComp2(pDocument, aPos, *pCode);
    1158 [ #  # ][ #  # ]:          0 :             aComp2.SetGrammar(pDocument->GetGrammar());
    1159 [ #  # ][ #  # ]:          0 :             aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
                 [ #  # ]
    1160         [ #  # ]:          0 :             aComp2.UpdateInsertTab( nTable, false, nNewSheets );
    1161                 :            :             // If the shared formula contained a named range/formula containing
    1162                 :            :             // an absolute reference to a sheet, those have to be readjusted.
    1163         [ #  # ]:          0 :             aComp2.UpdateDeleteTab( nTable, false, true, bRefChanged, nNewSheets );
    1164         [ #  # ]:          0 :             bCompile = true;
    1165         [ +  - ]:         18 :         }
    1166                 :            :         // kein StartListeningTo weil pTab[nTab] noch nicht existiert!
    1167                 :            :     }
    1168         [ #  # ]:          0 :     else if ( bPosChanged )
    1169                 :          0 :         aPos.IncTab();
    1170                 :         18 : }
    1171                 :            : 
    1172                 :         79 : bool ScFormulaCell::UpdateDeleteTab(SCTAB nTable, bool bIsMove, SCTAB nSheets)
    1173                 :            : {
    1174                 :         79 :     bool bRefChanged = false;
    1175                 :         79 :     bool bPosChanged = ( aPos.Tab() >= nTable + nSheets ? true : false );
    1176                 :         79 :     pCode->Reset();
    1177 [ +  + ][ +  - ]:         79 :     if( pCode->GetNextReferenceRPN() && !pDocument->IsClipOrUndo() )
         [ +  + ][ +  - ]
    1178                 :            :     {
    1179         [ +  - ]:         76 :         EndListeningTo( pDocument );
    1180                 :            :         // IncTab _nach_ EndListeningTo und _vor_ Compiler UpdateDeleteTab !
    1181         [ +  + ]:         76 :         if ( bPosChanged )
    1182         [ +  - ]:         28 :             aPos.IncTab(-1*nSheets);
    1183                 :            :         ScRangeData* pRangeData;
    1184         [ +  - ]:         76 :         ScCompiler aComp(pDocument, aPos, *pCode);
    1185 [ +  - ][ +  - ]:         76 :         aComp.SetGrammar(pDocument->GetGrammar());
    1186         [ +  - ]:         76 :         pRangeData = aComp.UpdateDeleteTab(nTable, bIsMove, false, bRefChanged, nSheets);
    1187         [ -  + ]:         76 :         if (pRangeData)                     // Shared Formula gegen echte Formel
    1188                 :            :         {                                   // austauschen
    1189         [ #  # ]:          0 :             pDocument->RemoveFromFormulaTree( this );   // update formula count
    1190 [ #  # ][ #  # ]:          0 :             delete pCode;
    1191         [ #  # ]:          0 :             pCode = pRangeData->GetCode()->Clone();
    1192         [ #  # ]:          0 :             ScCompiler aComp2(pDocument, aPos, *pCode);
    1193 [ #  # ][ #  # ]:          0 :             aComp2.SetGrammar(pDocument->GetGrammar());
    1194         [ #  # ]:          0 :             aComp2.CompileTokenArray();
    1195 [ #  # ][ #  # ]:          0 :             aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
                 [ #  # ]
    1196         [ #  # ]:          0 :             aComp2.UpdateDeleteTab( nTable, false, false, bRefChanged, nSheets );
    1197                 :            :             // If the shared formula contained a named range/formula containing
    1198                 :            :             // an absolute reference to a sheet, those have to be readjusted.
    1199         [ #  # ]:          0 :             aComp2.UpdateInsertTab( nTable,true, nSheets );
    1200                 :            :             // bRefChanged kann beim letzten UpdateDeleteTab zurueckgesetzt worden sein
    1201                 :          0 :             bRefChanged = true;
    1202         [ #  # ]:          0 :             bCompile = true;
    1203         [ +  - ]:         76 :         }
    1204                 :            :         // kein StartListeningTo weil pTab[nTab] noch nicht korrekt!
    1205                 :            :     }
    1206         [ -  + ]:          3 :     else if ( bPosChanged )
    1207         [ #  # ]:          0 :         aPos.IncTab(-1*nSheets);
    1208                 :            : 
    1209                 :         79 :     return bRefChanged;
    1210                 :            : }
    1211                 :            : 
    1212                 :          0 : void ScFormulaCell::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
    1213                 :            : {
    1214                 :          0 :     pCode->Reset();
    1215 [ #  # ][ #  # ]:          0 :     if( pCode->GetNextReferenceRPN() && !pDocument->IsClipOrUndo() )
                 [ #  # ]
    1216                 :            :     {
    1217         [ #  # ]:          0 :         EndListeningTo( pDocument );
    1218                 :            :         // SetTab _nach_ EndListeningTo und _vor_ Compiler UpdateMoveTab !
    1219                 :          0 :         aPos.SetTab( nTabNo );
    1220                 :            :         ScRangeData* pRangeData;
    1221         [ #  # ]:          0 :         ScCompiler aComp(pDocument, aPos, *pCode);
    1222 [ #  # ][ #  # ]:          0 :         aComp.SetGrammar(pDocument->GetGrammar());
    1223         [ #  # ]:          0 :         pRangeData = aComp.UpdateMoveTab( nOldPos, nNewPos, false );
    1224         [ #  # ]:          0 :         if (pRangeData)                     // Shared Formula gegen echte Formel
    1225                 :            :         {                                   // austauschen
    1226         [ #  # ]:          0 :             pDocument->RemoveFromFormulaTree( this );   // update formula count
    1227 [ #  # ][ #  # ]:          0 :             delete pCode;
    1228         [ #  # ]:          0 :             pCode = pRangeData->GetCode()->Clone();
    1229         [ #  # ]:          0 :             ScCompiler aComp2(pDocument, aPos, *pCode);
    1230 [ #  # ][ #  # ]:          0 :             aComp2.SetGrammar(pDocument->GetGrammar());
    1231         [ #  # ]:          0 :             aComp2.CompileTokenArray();
    1232 [ #  # ][ #  # ]:          0 :             aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
                 [ #  # ]
    1233         [ #  # ]:          0 :             aComp2.UpdateMoveTab( nOldPos, nNewPos, true );
    1234         [ #  # ]:          0 :             bCompile = true;
    1235         [ #  # ]:          0 :         }
    1236                 :            :         // kein StartListeningTo weil pTab[nTab] noch nicht korrekt!
    1237                 :            :     }
    1238                 :            :     else
    1239                 :          0 :         aPos.SetTab( nTabNo );
    1240                 :          0 : }
    1241                 :            : 
    1242                 :          0 : void ScFormulaCell::UpdateInsertTabAbs(SCTAB nTable)
    1243                 :            : {
    1244         [ #  # ]:          0 :     if( !pDocument->IsClipOrUndo() )
    1245                 :            :     {
    1246                 :          0 :         pCode->Reset();
    1247                 :          0 :         ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
    1248         [ #  # ]:          0 :         while( p )
    1249                 :            :         {
    1250                 :          0 :             ScSingleRefData& rRef1 = p->GetSingleRef();
    1251 [ #  # ][ #  # ]:          0 :             if( !rRef1.IsTabRel() && (SCsTAB) nTable <= rRef1.nTab )
                 [ #  # ]
    1252                 :          0 :                 rRef1.nTab++;
    1253         [ #  # ]:          0 :             if( p->GetType() == formula::svDoubleRef )
    1254                 :            :             {
    1255                 :          0 :                 ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
    1256 [ #  # ][ #  # ]:          0 :                 if( !rRef2.IsTabRel() && (SCsTAB) nTable <= rRef2.nTab )
                 [ #  # ]
    1257                 :          0 :                     rRef2.nTab++;
    1258                 :            :             }
    1259                 :          0 :             p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
    1260                 :            :         }
    1261                 :            :     }
    1262                 :          0 : }
    1263                 :            : 
    1264                 :          4 : bool ScFormulaCell::TestTabRefAbs(SCTAB nTable)
    1265                 :            : {
    1266                 :          4 :     bool bRet = false;
    1267         [ +  - ]:          4 :     if( !pDocument->IsClipOrUndo() )
    1268                 :            :     {
    1269                 :          4 :         pCode->Reset();
    1270                 :          4 :         ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
    1271         [ +  + ]:         10 :         while( p )
    1272                 :            :         {
    1273                 :          6 :             ScSingleRefData& rRef1 = p->GetSingleRef();
    1274         [ +  + ]:          6 :             if( !rRef1.IsTabRel() )
    1275                 :            :             {
    1276         [ +  - ]:          2 :                 if( (SCsTAB) nTable != rRef1.nTab )
    1277                 :          2 :                     bRet = true;
    1278         [ #  # ]:          0 :                 else if (nTable != aPos.Tab())
    1279                 :          0 :                     rRef1.nTab = aPos.Tab();
    1280                 :            :             }
    1281         [ -  + ]:          6 :             if( p->GetType() == formula::svDoubleRef )
    1282                 :            :             {
    1283                 :          0 :                 ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
    1284         [ #  # ]:          0 :                 if( !rRef2.IsTabRel() )
    1285                 :            :                 {
    1286         [ #  # ]:          0 :                     if( (SCsTAB) nTable != rRef2.nTab )
    1287                 :          0 :                         bRet = true;
    1288         [ #  # ]:          0 :                     else if (nTable != aPos.Tab())
    1289                 :          0 :                         rRef2.nTab = aPos.Tab();
    1290                 :            :                 }
    1291                 :            :             }
    1292                 :          6 :             p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
    1293                 :            :         }
    1294                 :            :     }
    1295                 :          4 :     return bRet;
    1296                 :            : }
    1297                 :            : 
    1298                 :         73 : void ScFormulaCell::UpdateCompile( bool bForceIfNameInUse )
    1299                 :            : {
    1300 [ -  + ][ #  # ]:         73 :     if ( bForceIfNameInUse && !bCompile )
    1301                 :          0 :         bCompile = pCode->HasNameOrColRowName();
    1302         [ -  + ]:         73 :     if ( bCompile )
    1303                 :          0 :         pCode->SetCodeError( 0 );   // make sure it will really be compiled
    1304                 :         73 :     CompileTokenArray();
    1305                 :         73 : }
    1306                 :            : 
    1307                 :            : //  Referenzen transponieren - wird nur in Clipboard-Dokumenten aufgerufen
    1308                 :            : 
    1309                 :          0 : void ScFormulaCell::TransposeReference()
    1310                 :            : {
    1311                 :          0 :     bool bFound = false;
    1312                 :          0 :     pCode->Reset();
    1313                 :            :     ScToken* t;
    1314         [ #  # ]:          0 :     while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
    1315                 :            :     {
    1316                 :          0 :         ScSingleRefData& rRef1 = t->GetSingleRef();
    1317 [ #  # ][ #  # ]:          0 :         if ( rRef1.IsColRel() && rRef1.IsRowRel() )
                 [ #  # ]
    1318                 :            :         {
    1319                 :          0 :             bool bDouble = (t->GetType() == formula::svDoubleRef);
    1320         [ #  # ]:          0 :             ScSingleRefData& rRef2 = (bDouble ? t->GetDoubleRef().Ref2 : rRef1);
    1321 [ #  # ][ #  # ]:          0 :             if ( !bDouble || (rRef2.IsColRel() && rRef2.IsRowRel()) )
         [ #  # ][ #  # ]
    1322                 :            :             {
    1323                 :            :                 sal_Int16 nTemp;
    1324                 :            : 
    1325                 :          0 :                 nTemp = rRef1.nRelCol;
    1326                 :          0 :                 rRef1.nRelCol = static_cast<SCCOL>(rRef1.nRelRow);
    1327                 :          0 :                 rRef1.nRelRow = static_cast<SCROW>(nTemp);
    1328                 :            : 
    1329         [ #  # ]:          0 :                 if ( bDouble )
    1330                 :            :                 {
    1331                 :          0 :                     nTemp = rRef2.nRelCol;
    1332                 :          0 :                     rRef2.nRelCol = static_cast<SCCOL>(rRef2.nRelRow);
    1333                 :          0 :                     rRef2.nRelRow = static_cast<SCROW>(nTemp);
    1334                 :            :                 }
    1335                 :            : 
    1336                 :          0 :                 bFound = true;
    1337                 :            :             }
    1338                 :            :         }
    1339                 :            :     }
    1340                 :            : 
    1341         [ #  # ]:          0 :     if (bFound)
    1342                 :          0 :         bCompile = true;
    1343                 :          0 : }
    1344                 :            : 
    1345                 :          0 : void ScFormulaCell::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
    1346                 :            :                                         ScDocument* pUndoDoc )
    1347                 :            : {
    1348         [ #  # ]:          0 :     EndListeningTo( pDocument );
    1349                 :            : 
    1350                 :          0 :     ScAddress aOldPos = aPos;
    1351                 :          0 :     bool bPosChanged = false;           // ob diese Zelle bewegt wurde
    1352                 :            : 
    1353                 :            :     ScRange aDestRange( rDest, ScAddress(
    1354                 :          0 :                 static_cast<SCCOL>(rDest.Col() + rSource.aEnd.Row() - rSource.aStart.Row()),
    1355                 :          0 :                 static_cast<SCROW>(rDest.Row() + rSource.aEnd.Col() - rSource.aStart.Col()),
    1356                 :          0 :                 rDest.Tab() + rSource.aEnd.Tab() - rSource.aStart.Tab() ) );
    1357         [ #  # ]:          0 :     if ( aDestRange.In( aOldPos ) )
    1358                 :            :     {
    1359                 :            :         //  Position zurueckrechnen
    1360                 :          0 :         SCsCOL nRelPosX = aOldPos.Col();
    1361                 :          0 :         SCsROW nRelPosY = aOldPos.Row();
    1362                 :          0 :         SCsTAB nRelPosZ = aOldPos.Tab();
    1363         [ #  # ]:          0 :         ScRefUpdate::DoTranspose( nRelPosX, nRelPosY, nRelPosZ, pDocument, aDestRange, rSource.aStart );
    1364                 :          0 :         aOldPos.Set( nRelPosX, nRelPosY, nRelPosZ );
    1365                 :          0 :         bPosChanged = true;
    1366                 :            :     }
    1367                 :            : 
    1368 [ #  # ][ #  # ]:          0 :     ScTokenArray* pOld = pUndoDoc ? pCode->Clone() : NULL;
    1369                 :          0 :     bool bRefChanged = false;
    1370                 :            :     ScToken* t;
    1371                 :            : 
    1372                 :          0 :     ScRangeData* pShared = NULL;
    1373                 :          0 :     pCode->Reset();
    1374 [ #  # ][ #  # ]:          0 :     while( (t = static_cast<ScToken*>(pCode->GetNextReferenceOrName())) != NULL )
    1375                 :            :     {
    1376         [ #  # ]:          0 :         if( t->GetOpCode() == ocName )
    1377                 :            :         {
    1378 [ #  # ][ #  # ]:          0 :             ScRangeData* pName = pDocument->GetRangeName()->findByIndex( t->GetIndex() );
                 [ #  # ]
    1379         [ #  # ]:          0 :             if (pName)
    1380                 :            :             {
    1381         [ #  # ]:          0 :                 if (pName->IsModified())
    1382                 :          0 :                     bRefChanged = true;
    1383         [ #  # ]:          0 :                 if (pName->HasType(RT_SHAREDMOD))
    1384                 :          0 :                     pShared = pName;
    1385                 :            :             }
    1386                 :            :         }
    1387         [ #  # ]:          0 :         else if( t->GetType() != svIndex )
    1388                 :            :         {
    1389         [ #  # ]:          0 :             t->CalcAbsIfRel( aOldPos );
    1390                 :            :             bool bMod;
    1391                 :            :             {   // own scope for SingleDoubleRefModifier dtor if SingleRef
    1392         [ #  # ]:          0 :                 SingleDoubleRefModifier aMod( *t );
    1393                 :          0 :                 ScComplexRefData& rRef = aMod.Ref();
    1394                 :            :                 bMod = (ScRefUpdate::UpdateTranspose( pDocument, rSource,
    1395 [ #  # ][ #  # ]:          0 :                     rDest, rRef ) != UR_NOTHING || bPosChanged);
                 [ #  # ]
    1396                 :            :             }
    1397         [ #  # ]:          0 :             if ( bMod )
    1398                 :            :             {
    1399         [ #  # ]:          0 :                 t->CalcRelFromAbs( aPos );
    1400                 :          0 :                 bRefChanged = true;
    1401                 :            :             }
    1402                 :            :         }
    1403                 :            :     }
    1404                 :            : 
    1405         [ #  # ]:          0 :     if (pShared)            // Shared Formula gegen echte Formel austauschen
    1406                 :            :     {
    1407         [ #  # ]:          0 :         pDocument->RemoveFromFormulaTree( this );   // update formula count
    1408 [ #  # ][ #  # ]:          0 :         delete pCode;
    1409 [ #  # ][ #  # ]:          0 :         pCode = new ScTokenArray( *pShared->GetCode() );
    1410                 :          0 :         bRefChanged = true;
    1411                 :          0 :         pCode->Reset();
    1412 [ #  # ][ #  # ]:          0 :         while( (t = static_cast<ScToken*>(pCode->GetNextReference())) != NULL )
    1413                 :            :         {
    1414         [ #  # ]:          0 :             if( t->GetType() != svIndex )
    1415                 :            :             {
    1416         [ #  # ]:          0 :                 t->CalcAbsIfRel( aOldPos );
    1417                 :            :                 bool bMod;
    1418                 :            :                 {   // own scope for SingleDoubleRefModifier dtor if SingleRef
    1419         [ #  # ]:          0 :                     SingleDoubleRefModifier aMod( *t );
    1420                 :          0 :                     ScComplexRefData& rRef = aMod.Ref();
    1421                 :            :                     bMod = (ScRefUpdate::UpdateTranspose( pDocument, rSource,
    1422 [ #  # ][ #  # ]:          0 :                         rDest, rRef ) != UR_NOTHING || bPosChanged);
                 [ #  # ]
    1423                 :            :                 }
    1424         [ #  # ]:          0 :                 if ( bMod )
    1425         [ #  # ]:          0 :                     t->CalcRelFromAbs( aPos );
    1426                 :            :             }
    1427                 :            :         }
    1428                 :            :     }
    1429                 :            : 
    1430         [ #  # ]:          0 :     if (bRefChanged)
    1431                 :            :     {
    1432         [ #  # ]:          0 :         if (pUndoDoc)
    1433                 :            :         {
    1434                 :            :             ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aPos, pOld,
    1435 [ #  # ][ #  # ]:          0 :                     eTempGrammar, cMatrixFlag);
    1436         [ #  # ]:          0 :             pFCell->aResult.SetToken( NULL);  // to recognize it as changed later (Cut/Paste!)
    1437 [ #  # ][ #  # ]:          0 :             pUndoDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pFCell );
    1438                 :            :         }
    1439                 :            : 
    1440                 :          0 :         bCompile = true;
    1441         [ #  # ]:          0 :         CompileTokenArray();                // ruft auch StartListeningTo
    1442         [ #  # ]:          0 :         SetDirty();
    1443                 :            :     }
    1444                 :            :     else
    1445         [ #  # ]:          0 :         StartListeningTo( pDocument );      // Listener wie vorher
    1446                 :            : 
    1447 [ #  # ][ #  # ]:          0 :     delete pOld;
    1448                 :          0 : }
    1449                 :            : 
    1450                 :          0 : void ScFormulaCell::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
    1451                 :            : {
    1452         [ #  # ]:          0 :     EndListeningTo( pDocument );
    1453                 :            : 
    1454                 :          0 :     bool bRefChanged = false;
    1455                 :            :     ScToken* t;
    1456                 :          0 :     ScRangeData* pShared = NULL;
    1457                 :            : 
    1458                 :          0 :     pCode->Reset();
    1459         [ #  # ]:          0 :     while( (t = static_cast<ScToken*>(pCode->GetNextReferenceOrName())) != NULL )
    1460                 :            :     {
    1461         [ #  # ]:          0 :         if( t->GetOpCode() == ocName )
    1462                 :            :         {
    1463                 :          0 :             ScRangeData* pName = pDocument->GetRangeName()->findByIndex( t->GetIndex() );
    1464         [ #  # ]:          0 :             if (pName)
    1465                 :            :             {
    1466         [ #  # ]:          0 :                 if (pName->IsModified())
    1467                 :          0 :                     bRefChanged = true;
    1468         [ #  # ]:          0 :                 if (pName->HasType(RT_SHAREDMOD))
    1469                 :          0 :                     pShared = pName;
    1470                 :            :             }
    1471                 :            :         }
    1472         [ #  # ]:          0 :         else if( t->GetType() != svIndex )
    1473                 :            :         {
    1474                 :          0 :             t->CalcAbsIfRel( aPos );
    1475                 :            :             bool bMod;
    1476                 :            :             {   // own scope for SingleDoubleRefModifier dtor if SingleRef
    1477         [ #  # ]:          0 :                 SingleDoubleRefModifier aMod( *t );
    1478                 :          0 :                 ScComplexRefData& rRef = aMod.Ref();
    1479                 :            :                 bMod = (ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY,
    1480         [ #  # ]:          0 :                     rRef ) != UR_NOTHING);
    1481                 :            :             }
    1482         [ #  # ]:          0 :             if ( bMod )
    1483                 :            :             {
    1484                 :          0 :                 t->CalcRelFromAbs( aPos );
    1485                 :          0 :                 bRefChanged = true;
    1486                 :            :             }
    1487                 :            :         }
    1488                 :            :     }
    1489                 :            : 
    1490         [ #  # ]:          0 :     if (pShared)            // Shared Formula gegen echte Formel austauschen
    1491                 :            :     {
    1492                 :          0 :         pDocument->RemoveFromFormulaTree( this );   // update formula count
    1493         [ #  # ]:          0 :         delete pCode;
    1494         [ #  # ]:          0 :         pCode = new ScTokenArray( *pShared->GetCode() );
    1495                 :          0 :         bRefChanged = true;
    1496                 :          0 :         pCode->Reset();
    1497         [ #  # ]:          0 :         while( (t = static_cast<ScToken*>(pCode->GetNextReference())) != NULL )
    1498                 :            :         {
    1499         [ #  # ]:          0 :             if( t->GetType() != svIndex )
    1500                 :            :             {
    1501                 :          0 :                 t->CalcAbsIfRel( aPos );
    1502                 :            :                 bool bMod;
    1503                 :            :                 {   // own scope for SingleDoubleRefModifier dtor if SingleRef
    1504         [ #  # ]:          0 :                     SingleDoubleRefModifier aMod( *t );
    1505                 :          0 :                     ScComplexRefData& rRef = aMod.Ref();
    1506                 :            :                     bMod = (ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY,
    1507         [ #  # ]:          0 :                         rRef ) != UR_NOTHING);
    1508                 :            :                 }
    1509         [ #  # ]:          0 :                 if ( bMod )
    1510                 :          0 :                     t->CalcRelFromAbs( aPos );
    1511                 :            :             }
    1512                 :            :         }
    1513                 :            :     }
    1514                 :            : 
    1515         [ #  # ]:          0 :     if (bRefChanged)
    1516                 :            :     {
    1517                 :          0 :         bCompile = true;
    1518                 :          0 :         CompileTokenArray();                // ruft auch StartListeningTo
    1519                 :          0 :         SetDirty();
    1520                 :            :     }
    1521                 :            :     else
    1522                 :          0 :         StartListeningTo( pDocument );      // Listener wie vorher
    1523                 :          0 : }
    1524                 :            : 
    1525                 :          9 : void lcl_FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes, ScTokenArray* pCode, ScRangeName* pNames)
    1526                 :            : {
    1527         [ +  + ]:         39 :     for (FormulaToken* p = pCode->First(); p; p = pCode->Next())
    1528                 :            :     {
    1529         [ +  + ]:         30 :         if (p->GetOpCode() == ocName)
    1530                 :            :         {
    1531         [ +  - ]:          6 :             sal_uInt16 nTokenIndex = p->GetIndex();
    1532         [ +  - ]:          6 :             rIndexes.insert( nTokenIndex );
    1533                 :            : 
    1534 [ +  - ][ +  - ]:          6 :             ScRangeData* pSubName = pNames->findByIndex(p->GetIndex());
    1535         [ +  - ]:          6 :             if (pSubName)
    1536         [ +  - ]:          6 :                 lcl_FindRangeNamesInUse(rIndexes, pSubName->GetCode(), pNames);
    1537                 :            :         }
    1538                 :            :     }
    1539                 :          9 : }
    1540                 :            : 
    1541                 :          3 : void ScFormulaCell::FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const
    1542                 :            : {
    1543                 :          3 :     lcl_FindRangeNamesInUse( rIndexes, pCode, pDocument->GetRangeName() );
    1544                 :          3 : }
    1545                 :            : 
    1546                 :        770 : bool ScFormulaCell::IsChanged() const
    1547                 :            : {
    1548                 :        770 :     return bChanged;
    1549                 :            : }
    1550                 :            : 
    1551                 :        381 : void ScFormulaCell::ResetChanged()
    1552                 :            : {
    1553                 :        381 :     bChanged = false;
    1554                 :        381 : }
    1555                 :            : 
    1556                 :          7 : void ScFormulaCell::CompileDBFormula()
    1557                 :            : {
    1558         [ +  + ]:         56 :     for( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
    1559                 :            :     {
    1560   [ +  -  -  +  :         98 :         if ( p->GetOpCode() == ocDBArea
           #  # ][ -  + ]
    1561                 :         49 :             || (p->GetOpCode() == ocName && p->GetIndex() >= SC_START_INDEX_DB_COLL) )
    1562                 :            :         {
    1563                 :          0 :             bCompile = true;
    1564                 :          0 :             CompileTokenArray();
    1565                 :          0 :             SetDirty();
    1566                 :          0 :             break;
    1567                 :            :         }
    1568                 :            :     }
    1569                 :          7 : }
    1570                 :            : 
    1571                 :          0 : void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString )
    1572                 :            : {
    1573                 :            :     // zwei Phasen, muessen (!) nacheinander aufgerufen werden:
    1574                 :            :     // 1. FormelString mit alten Namen erzeugen
    1575                 :            :     // 2. FormelString mit neuen Namen kompilieren
    1576         [ #  # ]:          0 :     if ( bCreateFormulaString )
    1577                 :            :     {
    1578                 :          0 :         bool bRecompile = false;
    1579                 :          0 :         pCode->Reset();
    1580 [ #  # ][ #  # ]:          0 :         for ( FormulaToken* p = pCode->First(); p && !bRecompile; p = pCode->Next() )
                 [ #  # ]
    1581                 :            :         {
    1582      [ #  #  # ]:          0 :             switch ( p->GetOpCode() )
    1583                 :            :             {
    1584                 :            :                 case ocBad:             // DB-Bereich evtl. zugefuegt
    1585                 :            :                 case ocColRowName:      // falls Namensgleichheit
    1586                 :            :                 case ocDBArea:          // DB-Bereich
    1587                 :          0 :                     bRecompile = true;
    1588                 :          0 :                 break;
    1589                 :            :                 case ocName:
    1590         [ #  # ]:          0 :                     if ( p->GetIndex() >= SC_START_INDEX_DB_COLL )
    1591                 :          0 :                         bRecompile = true;  // DB-Bereich
    1592                 :          0 :                 break;
    1593                 :            :                 default:
    1594                 :            :                     ; // nothing
    1595                 :            :             }
    1596                 :            :         }
    1597         [ #  # ]:          0 :         if ( bRecompile )
    1598                 :            :         {
    1599                 :          0 :             rtl::OUString aFormula;
    1600         [ #  # ]:          0 :             GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
    1601 [ #  # ][ #  # ]:          0 :             if ( GetMatrixFlag() != MM_NONE && !aFormula.isEmpty() )
                 [ #  # ]
    1602                 :            :             {
    1603         [ #  # ]:          0 :                 if ( aFormula[ aFormula.getLength()-1 ] == '}' )
    1604                 :          0 :                     aFormula = aFormula.copy( 0, aFormula.getLength()-1 );
    1605         [ #  # ]:          0 :                 if ( aFormula[0] == '{' )
    1606                 :          0 :                     aFormula = aFormula.copy( 1 );
    1607                 :            :             }
    1608         [ #  # ]:          0 :             EndListeningTo( pDocument );
    1609         [ #  # ]:          0 :             pDocument->RemoveFromFormulaTree( this );
    1610         [ #  # ]:          0 :             pCode->Clear();
    1611         [ #  # ]:          0 :             SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
    1612                 :            :         }
    1613                 :            :     }
    1614 [ #  # ][ #  # ]:          0 :     else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
                 [ #  # ]
    1615                 :            :     {
    1616         [ #  # ]:          0 :         Compile( aResult.GetHybridFormula(), false, eTempGrammar );
    1617                 :          0 :         aResult.SetToken( NULL);
    1618                 :          0 :         SetDirty();
    1619                 :            :     }
    1620                 :          0 : }
    1621                 :            : 
    1622                 :          0 : void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString )
    1623                 :            : {
    1624                 :            :     // zwei Phasen, muessen (!) nacheinander aufgerufen werden:
    1625                 :            :     // 1. FormelString mit alten RangeNames erzeugen
    1626                 :            :     // 2. FormelString mit neuen RangeNames kompilieren
    1627         [ #  # ]:          0 :     if ( bCreateFormulaString )
    1628                 :            :     {
    1629                 :          0 :         bool bRecompile = false;
    1630                 :          0 :         pCode->Reset();
    1631 [ #  # ][ #  # ]:          0 :         for ( FormulaToken* p = pCode->First(); p && !bRecompile; p = pCode->Next() )
                 [ #  # ]
    1632                 :            :         {
    1633         [ #  # ]:          0 :             switch ( p->GetOpCode() )
    1634                 :            :             {
    1635                 :            :                 case ocBad:             // RangeName evtl. zugefuegt
    1636                 :            :                 case ocColRowName:      // falls Namensgleichheit
    1637                 :          0 :                     bRecompile = true;
    1638                 :          0 :                 break;
    1639                 :            :                 default:
    1640         [ #  # ]:          0 :                     if ( p->GetType() == svIndex )
    1641                 :          0 :                         bRecompile = true;  // RangeName
    1642                 :            :             }
    1643                 :            :         }
    1644         [ #  # ]:          0 :         if ( bRecompile )
    1645                 :            :         {
    1646                 :          0 :             rtl::OUString aFormula;
    1647         [ #  # ]:          0 :             GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
    1648 [ #  # ][ #  # ]:          0 :             if ( GetMatrixFlag() != MM_NONE && !aFormula.isEmpty() )
                 [ #  # ]
    1649                 :            :             {
    1650         [ #  # ]:          0 :                 if ( aFormula[ aFormula.getLength()-1 ] == '}' )
    1651                 :          0 :                     aFormula = aFormula.copy( 0, aFormula.getLength()-1 );
    1652         [ #  # ]:          0 :                 if ( aFormula[0] == '{' )
    1653                 :          0 :                     aFormula = aFormula.copy( 1 );
    1654                 :            :             }
    1655         [ #  # ]:          0 :             EndListeningTo( pDocument );
    1656         [ #  # ]:          0 :             pDocument->RemoveFromFormulaTree( this );
    1657         [ #  # ]:          0 :             pCode->Clear();
    1658         [ #  # ]:          0 :             SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
    1659                 :            :         }
    1660                 :            :     }
    1661 [ #  # ][ #  # ]:          0 :     else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
                 [ #  # ]
    1662                 :            :     {
    1663         [ #  # ]:          0 :         Compile( aResult.GetHybridFormula(), false, eTempGrammar );
    1664                 :          0 :         aResult.SetToken( NULL);
    1665                 :          0 :         SetDirty();
    1666                 :            :     }
    1667                 :          0 : }
    1668                 :            : 
    1669                 :          0 : void ScFormulaCell::CompileColRowNameFormula()
    1670                 :            : {
    1671                 :          0 :     pCode->Reset();
    1672         [ #  # ]:          0 :     for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
    1673                 :            :     {
    1674         [ #  # ]:          0 :         if ( p->GetOpCode() == ocColRowName )
    1675                 :            :         {
    1676                 :          0 :             bCompile = true;
    1677                 :          0 :             CompileTokenArray();
    1678                 :          0 :             SetDirty();
    1679                 :          0 :             break;
    1680                 :            :         }
    1681                 :            :     }
    1682 [ +  - ][ +  - ]:        153 : }
    1683                 :            : 
    1684                 :            : // ============================================================================
    1685                 :            : 
    1686                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10