LCOV - code coverage report
Current view: top level - sc/source/core/tool - token.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1700 0.0 %
Date: 2014-04-14 Functions: 0 191 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <cstddef>
      21             : #include <cstdio>
      22             : 
      23             : #include <string.h>
      24             : #include <tools/mempool.hxx>
      25             : #include <osl/diagnose.h>
      26             : #include <sfx2/docfile.hxx>
      27             : 
      28             : #include "token.hxx"
      29             : #include "tokenarray.hxx"
      30             : #include "reftokenhelper.hxx"
      31             : #include "clipparam.hxx"
      32             : #include "compiler.hxx"
      33             : #include <formula/compiler.hrc>
      34             : #include "rechead.hxx"
      35             : #include "parclass.hxx"
      36             : #include "jumpmatrix.hxx"
      37             : #include "rangeseq.hxx"
      38             : #include "externalrefmgr.hxx"
      39             : #include "document.hxx"
      40             : #include "refupdatecontext.hxx"
      41             : #include "tokenstringcontext.hxx"
      42             : #include "types.hxx"
      43             : #include "globstr.hrc"
      44             : #include "addincol.hxx"
      45             : #include "svl/sharedstring.hxx"
      46             : 
      47             : using ::std::vector;
      48             : 
      49             : #include <com/sun/star/sheet/ComplexReference.hpp>
      50             : #include <com/sun/star/sheet/ExternalReference.hpp>
      51             : #include <com/sun/star/sheet/ReferenceFlags.hpp>
      52             : #include <com/sun/star/sheet/NameToken.hpp>
      53             : 
      54             : using namespace formula;
      55             : using namespace com::sun::star;
      56             : 
      57             : namespace
      58             : {
      59           0 :     void lcl_SingleRefToCalc( ScSingleRefData& rRef, const sheet::SingleReference& rAPI )
      60             :     {
      61           0 :         rRef.InitFlags();
      62             : 
      63           0 :         rRef.SetColRel(     ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_RELATIVE ) != 0 );
      64           0 :         rRef.SetRowRel(     ( rAPI.Flags & sheet::ReferenceFlags::ROW_RELATIVE    ) != 0 );
      65           0 :         rRef.SetTabRel(     ( rAPI.Flags & sheet::ReferenceFlags::SHEET_RELATIVE  ) != 0 );
      66           0 :         rRef.SetColDeleted( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_DELETED  ) != 0 );
      67           0 :         rRef.SetRowDeleted( ( rAPI.Flags & sheet::ReferenceFlags::ROW_DELETED     ) != 0 );
      68           0 :         rRef.SetTabDeleted( ( rAPI.Flags & sheet::ReferenceFlags::SHEET_DELETED   ) != 0 );
      69           0 :         rRef.SetFlag3D(     ( rAPI.Flags & sheet::ReferenceFlags::SHEET_3D        ) != 0 );
      70           0 :         rRef.SetRelName(    ( rAPI.Flags & sheet::ReferenceFlags::RELATIVE_NAME   ) != 0 );
      71             : 
      72           0 :         if (rRef.IsColRel())
      73           0 :             rRef.SetRelCol(static_cast<SCCOL>(rAPI.RelativeColumn));
      74             :         else
      75           0 :             rRef.SetAbsCol(static_cast<SCCOL>(rAPI.Column));
      76             : 
      77           0 :         if (rRef.IsRowRel())
      78           0 :             rRef.SetRelRow(static_cast<SCROW>(rAPI.RelativeRow));
      79             :         else
      80           0 :             rRef.SetAbsRow(static_cast<SCROW>(rAPI.Row));
      81             : 
      82           0 :         if (rRef.IsTabRel())
      83           0 :             rRef.SetRelTab(static_cast<SCsTAB>(rAPI.RelativeSheet));
      84             :         else
      85           0 :             rRef.SetAbsTab(static_cast<SCsTAB>(rAPI.Sheet));
      86           0 :     }
      87             : 
      88           0 :     void lcl_ExternalRefToCalc( ScSingleRefData& rRef, const sheet::SingleReference& rAPI )
      89             :     {
      90           0 :         rRef.InitFlags();
      91             : 
      92           0 :         rRef.SetColRel(     ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_RELATIVE ) != 0 );
      93           0 :         rRef.SetRowRel(     ( rAPI.Flags & sheet::ReferenceFlags::ROW_RELATIVE    ) != 0 );
      94           0 :         rRef.SetColDeleted( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_DELETED  ) != 0 );
      95           0 :         rRef.SetRowDeleted( ( rAPI.Flags & sheet::ReferenceFlags::ROW_DELETED     ) != 0 );
      96           0 :         rRef.SetTabDeleted( false );    // sheet must not be deleted for external refs
      97           0 :         rRef.SetFlag3D(     ( rAPI.Flags & sheet::ReferenceFlags::SHEET_3D        ) != 0 );
      98           0 :         rRef.SetRelName(    false );
      99             : 
     100           0 :         if (rRef.IsColRel())
     101           0 :             rRef.SetRelCol(static_cast<SCCOL>(rAPI.RelativeColumn));
     102             :         else
     103           0 :             rRef.SetAbsCol(static_cast<SCCOL>(rAPI.Column));
     104             : 
     105           0 :         if (rRef.IsRowRel())
     106           0 :             rRef.SetRelRow(static_cast<SCROW>(rAPI.RelativeRow));
     107             :         else
     108           0 :             rRef.SetAbsRow(static_cast<SCROW>(rAPI.Row));
     109             : 
     110             :         // sheet index must be absolute for external refs
     111           0 :         rRef.SetAbsTab(0);
     112           0 :     }
     113             : 
     114             : } // namespace
     115             : 
     116             : // Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2)
     117             : 
     118             : // Since RawTokens are temporary for the compiler, don't align on 4k and waste memory.
     119             : // ScRawToken size is FixMembers + MAXSTRLEN + ~4 ~= 1036
     120           0 : IMPL_FIXEDMEMPOOL_NEWDEL( ScRawToken )
     121             : // Some ScDoubleRawToken, FixMembers + sizeof(double) ~= 16
     122           0 : IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken )
     123             : 
     124             : // Need a whole bunch of ScSingleRefToken
     125           0 : IMPL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken )
     126             : // Need quite a lot of ScDoubleRefToken
     127           0 : IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken )
     128             : 
     129             : // --- class ScRawToken -----------------------------------------------------
     130             : 
     131           0 : sal_Int32 ScRawToken::GetStrLen( const sal_Unicode* pStr )
     132             : {
     133           0 :     if ( !pStr )
     134           0 :         return 0;
     135           0 :     const sal_Unicode* p = pStr;
     136           0 :     while ( *p )
     137           0 :         p++;
     138           0 :     return sal::static_int_cast<sal_Int32>( p - pStr );
     139             : }
     140             : 
     141             : 
     142           0 : void ScRawToken::SetOpCode( OpCode e )
     143             : {
     144           0 :     eOp   = e;
     145           0 :     switch (eOp)
     146             :     {
     147             :         case ocIf:
     148           0 :             eType = svJump;
     149           0 :             nJump[ 0 ] = 3; // If, Else, Behind
     150           0 :             break;
     151             :         case ocIfError:
     152             :         case ocIfNA:
     153           0 :             eType = svJump;
     154           0 :             nJump[ 0 ] = 2; // If, Behind
     155           0 :             break;
     156             :         case ocChose:
     157           0 :             eType = svJump;
     158           0 :             nJump[ 0 ] = FORMULA_MAXJUMPCOUNT + 1;
     159           0 :             break;
     160             :         case ocMissing:
     161           0 :             eType = svMissing;
     162           0 :             break;
     163             :         case ocSep:
     164             :         case ocOpen:
     165             :         case ocClose:
     166             :         case ocArrayRowSep:
     167             :         case ocArrayColSep:
     168             :         case ocArrayOpen:
     169             :         case ocArrayClose:
     170           0 :             eType = svSep;
     171           0 :             break;
     172             :         default:
     173           0 :             eType = svByte;
     174           0 :             sbyte.cByte = 0;
     175           0 :             sbyte.bHasForceArray = ScParameterClassification::HasForceArray( eOp);
     176             :     }
     177           0 :     nRefCnt = 0;
     178           0 : }
     179             : 
     180           0 : void ScRawToken::SetString( rtl_uString* pData, rtl_uString* pDataIgoreCase )
     181             : {
     182           0 :     eOp   = ocPush;
     183           0 :     eType = svString;
     184           0 :     nRefCnt = 0;
     185             : 
     186           0 :     sharedstring.mpData = pData;
     187           0 :     sharedstring.mpDataIgnoreCase = pDataIgoreCase;
     188           0 : }
     189             : 
     190           0 : void ScRawToken::SetSingleReference( const ScSingleRefData& rRef )
     191             : {
     192           0 :     eOp       = ocPush;
     193           0 :     eType     = svSingleRef;
     194             :     aRef.Ref1 =
     195           0 :     aRef.Ref2 = rRef;
     196           0 :     nRefCnt   = 0;
     197           0 : }
     198             : 
     199           0 : void ScRawToken::SetDoubleReference( const ScComplexRefData& rRef )
     200             : {
     201           0 :     eOp   = ocPush;
     202           0 :     eType = svDoubleRef;
     203           0 :     aRef  = rRef;
     204           0 :     nRefCnt = 0;
     205           0 : }
     206             : 
     207           0 : void ScRawToken::SetDouble(double rVal)
     208             : {
     209           0 :     eOp   = ocPush;
     210           0 :     eType = svDouble;
     211           0 :     nValue = rVal;
     212           0 :     nRefCnt = 0;
     213           0 : }
     214             : 
     215           0 : void ScRawToken::SetErrorConstant( sal_uInt16 nErr )
     216             : {
     217           0 :     eOp   = ocPush;
     218           0 :     eType = svError;
     219           0 :     nError = nErr;
     220           0 :     nRefCnt = 0;
     221           0 : }
     222             : 
     223           0 : void ScRawToken::SetName(bool bGlobal, sal_uInt16 nIndex)
     224             : {
     225           0 :     eOp = ocName;
     226           0 :     eType = svIndex;
     227           0 :     nRefCnt = 0;
     228             : 
     229           0 :     name.bGlobal = bGlobal;
     230           0 :     name.nIndex = nIndex;
     231           0 : }
     232             : 
     233           0 : void ScRawToken::SetExternalSingleRef( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef )
     234             : {
     235           0 :     eOp = ocPush;
     236           0 :     eType = svExternalSingleRef;
     237           0 :     nRefCnt = 0;
     238             : 
     239           0 :     extref.nFileId = nFileId;
     240             :     extref.aRef.Ref1 =
     241           0 :     extref.aRef.Ref2 = rRef;
     242             : 
     243           0 :     sal_Int32 n = rTabName.getLength();
     244           0 :     memcpy(extref.cTabName, rTabName.getStr(), n*sizeof(sal_Unicode));
     245           0 :     extref.cTabName[n] = 0;
     246           0 : }
     247             : 
     248           0 : void ScRawToken::SetExternalDoubleRef( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef )
     249             : {
     250           0 :     eOp = ocPush;
     251           0 :     eType = svExternalDoubleRef;
     252           0 :     nRefCnt = 0;
     253             : 
     254           0 :     extref.nFileId = nFileId;
     255           0 :     extref.aRef = rRef;
     256             : 
     257           0 :     sal_Int32 n = rTabName.getLength();
     258           0 :     memcpy(extref.cTabName, rTabName.getStr(), n*sizeof(sal_Unicode));
     259           0 :     extref.cTabName[n] = 0;
     260           0 : }
     261             : 
     262           0 : void ScRawToken::SetExternalName( sal_uInt16 nFileId, const OUString& rName )
     263             : {
     264           0 :     eOp = ocPush;
     265           0 :     eType = svExternalName;
     266           0 :     nRefCnt = 0;
     267             : 
     268           0 :     extname.nFileId = nFileId;
     269             : 
     270           0 :     sal_Int32 n = rName.getLength();
     271           0 :     memcpy(extname.cName, rName.getStr(), n*sizeof(sal_Unicode));
     272           0 :     extname.cName[n] = 0;
     273           0 : }
     274             : 
     275           0 : void ScRawToken::SetExternal( const sal_Unicode* pStr )
     276             : {
     277           0 :     eOp   = ocExternal;
     278           0 :     eType = svExternal;
     279           0 :     sal_Int32 nLen = GetStrLen( pStr ) + 1;
     280           0 :     if( nLen >= MAXSTRLEN )
     281           0 :         nLen = MAXSTRLEN-1;
     282             :     // Platz fuer Byte-Parameter lassen!
     283           0 :     memcpy( cStr+1, pStr, GetStrLenBytes( nLen ) );
     284           0 :     cStr[ nLen+1 ] = 0;
     285           0 :     nRefCnt = 0;
     286           0 : }
     287             : 
     288             : 
     289           0 : bool ScRawToken::IsValidReference() const
     290             : {
     291           0 :     switch (eType)
     292             :     {
     293             :         case svSingleRef:
     294           0 :             return aRef.Ref1.Valid();
     295             :         case svDoubleRef:
     296           0 :             return aRef.Valid();
     297             :         case svExternalSingleRef:
     298             :         case svExternalDoubleRef:
     299           0 :             return true;
     300             :         default:
     301             :             ;   // nothing
     302             :     }
     303           0 :     return false;
     304             : }
     305             : 
     306             : 
     307           0 : sal_uInt16 ScRawToken::sbyteOffset()
     308             : {
     309             :     // offset of sbyte in ScRawToken
     310             :     // offsetof(ScRawToken, sbyte) gives a warning with gcc, because ScRawToken is no POD
     311             : 
     312           0 :     ScRawToken aToken;
     313           0 :     return static_cast<sal_uInt16>( reinterpret_cast<char*>(&aToken.sbyte) - reinterpret_cast<char*>(&aToken) );
     314             : }
     315             : 
     316           0 : ScRawToken* ScRawToken::Clone() const
     317             : {
     318             :     ScRawToken* p;
     319           0 :     if ( eType == svDouble )
     320             :     {
     321           0 :         p = (ScRawToken*) new ScDoubleRawToken;
     322           0 :         p->eOp = eOp;
     323           0 :         p->eType = eType;
     324           0 :         p->nValue = nValue;
     325             :     }
     326             :     else
     327             :     {
     328           0 :         static sal_uInt16 nOffset = sbyteOffset();     // offset of sbyte
     329           0 :         sal_uInt16 n = nOffset;
     330             : 
     331           0 :         switch( eType )
     332             :         {
     333           0 :             case svSep:         break;
     334           0 :             case svByte:        n += sizeof(ScRawToken::sbyte); break;
     335           0 :             case svDouble:      n += sizeof(double); break;
     336           0 :             case svError:       n += sizeof(nError); break;
     337           0 :             case svString:      n += sizeof(sharedstring); break;
     338             :             case svSingleRef:
     339           0 :             case svDoubleRef:   n += sizeof(aRef); break;
     340           0 :             case svMatrix:      n += sizeof(ScMatrix*); break;
     341           0 :             case svIndex:       n += sizeof(name); break;
     342           0 :             case svJump:        n += nJump[ 0 ] * 2 + 2; break;
     343           0 :             case svExternal:    n = sal::static_int_cast<sal_uInt16>( n + GetStrLenBytes( cStr+1 ) + GetStrLenBytes( 2 ) ); break;
     344             : 
     345             :             // external references
     346             :             case svExternalSingleRef:
     347           0 :             case svExternalDoubleRef: n += sizeof(extref); break;
     348           0 :             case svExternalName:      n += sizeof(extname); break;
     349             :             default:
     350             :             {
     351             :                 OSL_TRACE( "unknown ScRawToken::Clone() type %d", int(eType));
     352             :             }
     353             :         }
     354           0 :         p = (ScRawToken*) new sal_uInt8[ n ];
     355           0 :         memcpy( p, this, n * sizeof(sal_uInt8) );
     356             :     }
     357           0 :     p->nRefCnt = 0;
     358           0 :     p->bRaw = false;
     359           0 :     return p;
     360             : }
     361             : 
     362             : 
     363           0 : FormulaToken* ScRawToken::CreateToken() const
     364             : {
     365             : #if OSL_DEBUG_LEVEL > 1
     366             : #define IF_NOT_OPCODE_ERROR(o,c) if (eOp!=o) OSL_TRACE( #c "::ctor: OpCode %d lost, converted to " #o "; maybe inherit from FormulaToken instead!", int(eOp))
     367             : #else
     368             : #define IF_NOT_OPCODE_ERROR(o,c)
     369             : #endif
     370           0 :     switch ( GetType() )
     371             :     {
     372             :         case svByte :
     373           0 :             return new FormulaByteToken( eOp, sbyte.cByte, sbyte.bHasForceArray );
     374             :         case svDouble :
     375             :             IF_NOT_OPCODE_ERROR( ocPush, FormulaDoubleToken);
     376           0 :             return new FormulaDoubleToken( nValue );
     377             :         case svString :
     378             :         {
     379           0 :             svl::SharedString aSS(sharedstring.mpData, sharedstring.mpDataIgnoreCase);
     380           0 :             if (eOp == ocPush)
     381           0 :                 return new FormulaStringToken(aSS);
     382             :             else
     383           0 :                 return new FormulaStringOpToken(eOp, aSS);
     384             :         }
     385             :         case svSingleRef :
     386           0 :             if (eOp == ocPush)
     387           0 :                 return new ScSingleRefToken( aRef.Ref1 );
     388             :             else
     389           0 :                 return new ScSingleRefToken( aRef.Ref1, eOp );
     390             :         case svDoubleRef :
     391           0 :             if (eOp == ocPush)
     392           0 :                 return new ScDoubleRefToken( aRef );
     393             :             else
     394           0 :                 return new ScDoubleRefToken( aRef, eOp );
     395             :         case svMatrix :
     396             :             IF_NOT_OPCODE_ERROR( ocPush, ScMatrixToken);
     397           0 :             return new ScMatrixToken( pMat );
     398             :         case svIndex :
     399           0 :             return new FormulaIndexToken( eOp, name.nIndex, name.bGlobal);
     400             :         case svExternalSingleRef:
     401             :             {
     402           0 :                 OUString aTabName(extref.cTabName);
     403           0 :                 return new ScExternalSingleRefToken(extref.nFileId, aTabName, extref.aRef.Ref1);
     404             :             }
     405             :         case svExternalDoubleRef:
     406             :             {
     407           0 :                 OUString aTabName(extref.cTabName);
     408           0 :                 return new ScExternalDoubleRefToken(extref.nFileId, aTabName, extref.aRef);
     409             :             }
     410             :         case svExternalName:
     411             :             {
     412           0 :                 OUString aName(extname.cName);
     413           0 :                 return new ScExternalNameToken( extname.nFileId, aName );
     414             :             }
     415             :         case svJump :
     416           0 :             return new FormulaJumpToken( eOp, (short*) nJump );
     417             :         case svExternal :
     418           0 :             return new FormulaExternalToken( eOp, sbyte.cByte, OUString( cStr+1 ) );
     419             :         case svFAP :
     420           0 :             return new FormulaFAPToken( eOp, sbyte.cByte, NULL );
     421             :         case svMissing :
     422             :             IF_NOT_OPCODE_ERROR( ocMissing, FormulaMissingToken);
     423           0 :             return new FormulaMissingToken;
     424             :         case svSep :
     425           0 :             return new FormulaToken( svSep,eOp );
     426             :         case svError :
     427           0 :             return new FormulaErrorToken( nError );
     428             :         case svUnknown :
     429           0 :             return new FormulaUnknownToken( eOp );
     430             :         default:
     431             :             {
     432             :                 OSL_TRACE( "unknown ScRawToken::CreateToken() type %d", int(GetType()));
     433           0 :                 return new FormulaUnknownToken( ocBad );
     434             :             }
     435             :     }
     436             : #undef IF_NOT_OPCODE_ERROR
     437             : }
     438             : 
     439             : 
     440           0 : void ScRawToken::Delete()
     441             : {
     442           0 :     if ( bRaw )
     443           0 :         delete this;                            // FixedMemPool ScRawToken
     444             :     else
     445             :     {   // created per Clone
     446           0 :         switch ( eType )
     447             :         {
     448             :             case svDouble :
     449           0 :                 delete (ScDoubleRawToken*) this;    // FixedMemPool ScDoubleRawToken
     450           0 :             break;
     451             :             default:
     452           0 :                 delete [] (sal_uInt8*) this;
     453             :         }
     454             :     }
     455           0 : }
     456             : 
     457             : 
     458             : // --- class ScToken --------------------------------------------------------
     459             : 
     460           0 : static ScSingleRefData lcl_ScToken_InitSingleRef()
     461             : {
     462             :     ScSingleRefData aRef;
     463           0 :     aRef.InitAddress( ScAddress() );
     464           0 :     return aRef;
     465             : }
     466             : 
     467           0 : static ScComplexRefData lcl_ScToken_InitDoubleRef()
     468             : {
     469             :     ScComplexRefData aRef;
     470           0 :     aRef.Ref1 = lcl_ScToken_InitSingleRef();
     471           0 :     aRef.Ref2 = aRef.Ref1;
     472           0 :     return aRef;
     473             : }
     474             : 
     475           0 : ScToken::~ScToken()
     476             : {
     477           0 : }
     478             : 
     479             : //  TextEqual: if same formula entered (for optimization in sort)
     480           0 : bool ScToken::TextEqual( const FormulaToken& _rToken ) const
     481             : {
     482           0 :     if ( eType == svSingleRef || eType == svDoubleRef )
     483             :     {
     484             :         //  in relative Refs only compare relative parts
     485             : 
     486           0 :         if ( eType != _rToken.GetType() || GetOpCode() != _rToken.GetOpCode() )
     487           0 :             return false;
     488             : 
     489           0 :         const ScToken& rToken = static_cast<const ScToken&>(_rToken);
     490             :         ScComplexRefData aTemp1;
     491           0 :         if ( eType == svSingleRef )
     492             :         {
     493           0 :             aTemp1.Ref1 = GetSingleRef();
     494           0 :             aTemp1.Ref2 = aTemp1.Ref1;
     495             :         }
     496             :         else
     497           0 :             aTemp1 = GetDoubleRef();
     498             : 
     499             :         ScComplexRefData aTemp2;
     500           0 :         if ( rToken.eType == svSingleRef )
     501             :         {
     502           0 :             aTemp2.Ref1 = rToken.GetSingleRef();
     503           0 :             aTemp2.Ref2 = aTemp2.Ref1;
     504             :         }
     505             :         else
     506           0 :             aTemp2 = rToken.GetDoubleRef();
     507             : 
     508           0 :         ScAddress aPos;
     509           0 :         ScRange aRange1 = aTemp1.toAbs(aPos), aRange2 = aTemp2.toAbs(aPos);
     510             : 
     511             :         //  memcmp doesn't work because of the alignment byte after bFlags.
     512             :         //  After SmartRelAbs only absolute parts have to be compared.
     513           0 :         return aRange1 == aRange2 && aTemp1.Ref1.FlagValue() == aTemp2.Ref1.FlagValue() && aTemp1.Ref2.FlagValue() == aTemp2.Ref2.FlagValue();
     514             :     }
     515             :     else
     516           0 :         return *this == _rToken;     // else normal operator==
     517             : }
     518             : 
     519             : 
     520           0 : bool ScToken::Is3DRef() const
     521             : {
     522           0 :     switch ( eType )
     523             :     {
     524             :         case svDoubleRef :
     525           0 :             if ( GetSingleRef2().IsFlag3D() )
     526           0 :                 return true;
     527             :         //! fallthru
     528             :         case svSingleRef :
     529           0 :             if ( GetSingleRef().IsFlag3D() )
     530           0 :                 return true;
     531           0 :             break;
     532             :         default:
     533             :         {
     534             :             // added to avoid warnings
     535             :         }
     536             :     }
     537           0 :     return false;
     538             : }
     539             : 
     540             : #if DEBUG_FORMULA_COMPILER
     541             : void ScToken::Dump() const
     542             : {
     543             :     cout << "-- ScToken (base class)" << endl;
     544             : }
     545             : #endif
     546             : 
     547           0 : FormulaTokenRef ScToken::ExtendRangeReference( FormulaToken & rTok1, FormulaToken & rTok2,
     548             :         const ScAddress & rPos, bool bReuseDoubleRef )
     549             : {
     550             : 
     551             :     StackVar sv1, sv2;
     552             :     // Doing a RangeOp with RefList is probably utter nonsense, but Xcl
     553             :     // supports it, so do we.
     554           0 :     if (((sv1 = rTok1.GetType()) != svSingleRef && sv1 != svDoubleRef && sv1 != svRefList &&
     555           0 :             sv1 != svExternalSingleRef && sv1 != svExternalDoubleRef ) ||
     556           0 :         ((sv2 = rTok2.GetType()) != svSingleRef && sv2 != svDoubleRef && sv2 != svRefList))
     557           0 :         return NULL;
     558             : 
     559           0 :     ScToken *p1 = static_cast<ScToken*>(&rTok1);
     560           0 :     ScToken *p2 = static_cast<ScToken*>(&rTok2);
     561             : 
     562           0 :     ScTokenRef xRes;
     563           0 :     bool bExternal = (sv1 == svExternalSingleRef);
     564           0 :     if ((sv1 == svSingleRef || bExternal) && sv2 == svSingleRef)
     565             :     {
     566             :         // Range references like Sheet1.A1:A2 are generalized and built by
     567             :         // first creating a DoubleRef from the first SingleRef, effectively
     568             :         // generating Sheet1.A1:A1, and then extending that with A2 as if
     569             :         // Sheet1.A1:A1:A2 was encountered, so the mechanisms to adjust the
     570             :         // references apply as well.
     571             : 
     572             :         /* Given the current structure of external references an external
     573             :          * reference can only be extended if the second reference does not
     574             :          * point to a different sheet. 'file'#Sheet1.A1:A2 is ok,
     575             :          * 'file'#Sheet1.A1:Sheet2.A2 is not. Since we can't determine from a
     576             :          * svSingleRef whether the sheet would be different from the one given
     577             :          * in the external reference, we have to bail out if there is any sheet
     578             :          * specified. NOTE: Xcl does handle external 3D references as in
     579             :          * '[file]Sheet1:Sheet2'!A1:A2
     580             :          *
     581             :          * FIXME: For OOo syntax be smart and remember an external singleref
     582             :          * encountered and if followed by ocRange and singleref, create an
     583             :          * external singleref for the second singleref. Both could then be
     584             :          * merged here. For Xcl syntax already parse an external range
     585             :          * reference entirely, cumbersome. */
     586             : 
     587           0 :         const ScSingleRefData& rRef2 = p2->GetSingleRef();
     588           0 :         if (bExternal && rRef2.IsFlag3D())
     589           0 :             return NULL;
     590             : 
     591             :         ScComplexRefData aRef;
     592           0 :         aRef.Ref1 = aRef.Ref2 = p1->GetSingleRef();
     593           0 :         aRef.Ref2.SetFlag3D( false);
     594           0 :         aRef.Extend( rRef2, rPos);
     595           0 :         if (bExternal)
     596           0 :             xRes = new ScExternalDoubleRefToken( p1->GetIndex(), p1->GetString(), aRef);
     597             :         else
     598           0 :             xRes = new ScDoubleRefToken( aRef);
     599             :     }
     600             :     else
     601             :     {
     602           0 :         bExternal |= (sv1 == svExternalDoubleRef);
     603           0 :         const ScRefList* pRefList = NULL;
     604           0 :         if (sv1 == svDoubleRef)
     605             :         {
     606           0 :             xRes = (bReuseDoubleRef && p1->GetRef() == 1 ? p1 : static_cast<ScToken*>(p1->Clone()));
     607           0 :             sv1 = svUnknown;    // mark as handled
     608             :         }
     609           0 :         else if (sv2 == svDoubleRef)
     610             :         {
     611           0 :             xRes = (bReuseDoubleRef && p2->GetRef() == 1 ? p2 : static_cast<ScToken*>(p2->Clone()));
     612           0 :             sv2 = svUnknown;    // mark as handled
     613             :         }
     614           0 :         else if (sv1 == svRefList)
     615           0 :             pRefList = p1->GetRefList();
     616           0 :         else if (sv2 == svRefList)
     617           0 :             pRefList = p2->GetRefList();
     618           0 :         if (pRefList)
     619             :         {
     620           0 :             if (!pRefList->size())
     621           0 :                 return NULL;
     622           0 :             if (bExternal)
     623           0 :                 return NULL;    // external reference list not possible
     624           0 :             xRes = new ScDoubleRefToken( (*pRefList)[0] );
     625             :         }
     626           0 :         if (!xRes)
     627           0 :             return NULL;    // shouldn't happen..
     628           0 :         StackVar sv[2] = { sv1, sv2 };
     629           0 :         ScToken* pt[2] = { p1, p2 };
     630           0 :         ScComplexRefData& rRef = xRes->GetDoubleRef();
     631           0 :         for (size_t i=0; i<2; ++i)
     632             :         {
     633           0 :             switch (sv[i])
     634             :             {
     635             :                 case svSingleRef:
     636           0 :                     rRef.Extend( pt[i]->GetSingleRef(), rPos);
     637           0 :                     break;
     638             :                 case svDoubleRef:
     639           0 :                     rRef.Extend( pt[i]->GetDoubleRef(), rPos);
     640           0 :                     break;
     641             :                 case svRefList:
     642             :                     {
     643           0 :                         const ScRefList* p = pt[i]->GetRefList();
     644           0 :                         if (!p->size())
     645           0 :                             return NULL;
     646           0 :                         ScRefList::const_iterator it( p->begin());
     647           0 :                         ScRefList::const_iterator end( p->end());
     648           0 :                         for ( ; it != end; ++it)
     649             :                         {
     650           0 :                             rRef.Extend( *it, rPos);
     651             :                         }
     652             :                     }
     653           0 :                     break;
     654             :                 case svExternalSingleRef:
     655           0 :                     if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
     656           0 :                         return NULL;    // no other sheets with external refs
     657             :                     else
     658           0 :                         rRef.Extend( pt[i]->GetSingleRef(), rPos);
     659           0 :                     break;
     660             :                 case svExternalDoubleRef:
     661           0 :                     if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
     662           0 :                         return NULL;    // no other sheets with external refs
     663             :                     else
     664           0 :                         rRef.Extend( pt[i]->GetDoubleRef(), rPos);
     665           0 :                     break;
     666             :                 default:
     667             :                     ;   // nothing, prevent compiler warning
     668             :             }
     669             :         }
     670             :     }
     671           0 :     return FormulaTokenRef(xRes.get());
     672             : }
     673             : 
     674           0 : const ScSingleRefData& ScToken::GetSingleRef() const
     675             : {
     676             :     OSL_FAIL( "ScToken::GetSingleRef: virtual dummy called" );
     677           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     678           0 :     return aDummySingleRef;
     679             : }
     680             : 
     681           0 : ScSingleRefData& ScToken::GetSingleRef()
     682             : {
     683             :     OSL_FAIL( "ScToken::GetSingleRef: virtual dummy called" );
     684           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     685           0 :     return aDummySingleRef;
     686             : }
     687             : 
     688           0 : const ScComplexRefData& ScToken::GetDoubleRef() const
     689             : {
     690             :     OSL_FAIL( "ScToken::GetDoubleRef: virtual dummy called" );
     691           0 :     static ScComplexRefData aDummyDoubleRef = lcl_ScToken_InitDoubleRef();
     692           0 :     return aDummyDoubleRef;
     693             : }
     694             : 
     695           0 : ScComplexRefData& ScToken::GetDoubleRef()
     696             : {
     697             :     OSL_FAIL( "ScToken::GetDoubleRef: virtual dummy called" );
     698           0 :     static ScComplexRefData aDummyDoubleRef = lcl_ScToken_InitDoubleRef();
     699           0 :     return aDummyDoubleRef;
     700             : }
     701             : 
     702           0 : const ScSingleRefData& ScToken::GetSingleRef2() const
     703             : {
     704             :     OSL_FAIL( "ScToken::GetSingleRef2: virtual dummy called" );
     705           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     706           0 :     return aDummySingleRef;
     707             : }
     708             : 
     709           0 : ScSingleRefData& ScToken::GetSingleRef2()
     710             : {
     711             :     OSL_FAIL( "ScToken::GetSingleRef2: virtual dummy called" );
     712           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     713           0 :     return aDummySingleRef;
     714             : }
     715             : 
     716           0 : const ScMatrix* ScToken::GetMatrix() const
     717             : {
     718             :     OSL_FAIL( "ScToken::GetMatrix: virtual dummy called" );
     719           0 :     return NULL;
     720             : }
     721             : 
     722           0 : ScMatrix* ScToken::GetMatrix()
     723             : {
     724             :     OSL_FAIL( "ScToken::GetMatrix: virtual dummy called" );
     725           0 :     return NULL;
     726             : }
     727             : 
     728             : 
     729           0 : ScJumpMatrix* ScToken::GetJumpMatrix() const
     730             : {
     731             :     OSL_FAIL( "ScToken::GetJumpMatrix: virtual dummy called" );
     732           0 :     return NULL;
     733             : }
     734           0 : const ScRefList* ScToken::GetRefList() const
     735             : {
     736             :     OSL_FAIL( "ScToken::GetRefList: virtual dummy called" );
     737           0 :     return NULL;
     738             : }
     739             : 
     740           0 : ScRefList* ScToken::GetRefList()
     741             : {
     742             :     OSL_FAIL( "ScToken::GetRefList: virtual dummy called" );
     743           0 :     return NULL;
     744             : }
     745             : 
     746             : // real implementations of virtual functions
     747             : 
     748             : 
     749             : 
     750           0 : const ScSingleRefData&    ScSingleRefToken::GetSingleRef() const  { return aSingleRef; }
     751           0 : ScSingleRefData&          ScSingleRefToken::GetSingleRef()        { return aSingleRef; }
     752           0 : bool ScSingleRefToken::operator==( const FormulaToken& r ) const
     753             : {
     754           0 :     return FormulaToken::operator==( r ) && aSingleRef == static_cast<const ScToken&>(r).GetSingleRef();
     755             : }
     756             : 
     757             : #if DEBUG_FORMULA_COMPILER
     758             : void ScSingleRefToken::Dump() const
     759             : {
     760             :     cout << "-- ScSingleRefToken" << endl;
     761             :     aSingleRef.Dump(1);
     762             : }
     763             : #endif
     764             : 
     765           0 : const ScSingleRefData&    ScDoubleRefToken::GetSingleRef() const  { return aDoubleRef.Ref1; }
     766           0 : ScSingleRefData&          ScDoubleRefToken::GetSingleRef()        { return aDoubleRef.Ref1; }
     767           0 : const ScComplexRefData&     ScDoubleRefToken::GetDoubleRef() const  { return aDoubleRef; }
     768           0 : ScComplexRefData&           ScDoubleRefToken::GetDoubleRef()        { return aDoubleRef; }
     769           0 : const ScSingleRefData&    ScDoubleRefToken::GetSingleRef2() const { return aDoubleRef.Ref2; }
     770           0 : ScSingleRefData&          ScDoubleRefToken::GetSingleRef2()       { return aDoubleRef.Ref2; }
     771           0 : bool ScDoubleRefToken::operator==( const FormulaToken& r ) const
     772             : {
     773           0 :     return FormulaToken::operator==( r ) && aDoubleRef == static_cast<const ScToken&>(r).GetDoubleRef();
     774             : }
     775             : 
     776             : #if DEBUG_FORMULA_COMPILER
     777             : void ScDoubleRefToken::Dump() const
     778             : {
     779             :     cout << "-- ScDoubleRefToken" << endl;
     780             :     aDoubleRef.Dump(1);
     781             : }
     782             : #endif
     783             : 
     784           0 : const ScRefList*        ScRefListToken::GetRefList() const  { return &aRefList; }
     785           0 :       ScRefList*        ScRefListToken::GetRefList()        { return &aRefList; }
     786           0 : bool ScRefListToken::operator==( const FormulaToken& r ) const
     787             : {
     788           0 :     return FormulaToken::operator==( r ) && &aRefList == static_cast<const ScToken&>(r).GetRefList();
     789             : }
     790             : 
     791           0 : ScMatrixToken::ScMatrixToken( const ScMatrixRef& p ) :
     792           0 :     ScToken(formula::svMatrix), pMatrix(p) {}
     793             : 
     794           0 : ScMatrixToken::ScMatrixToken( const ScMatrixToken& r ) :
     795           0 :     ScToken(r), pMatrix(r.pMatrix) {}
     796             : 
     797           0 : const ScMatrix* ScMatrixToken::GetMatrix() const        { return pMatrix.get(); }
     798           0 : ScMatrix*       ScMatrixToken::GetMatrix()              { return pMatrix.get(); }
     799           0 : bool ScMatrixToken::operator==( const FormulaToken& r ) const
     800             : {
     801           0 :     return FormulaToken::operator==( r ) && pMatrix == static_cast<const ScToken&>(r).GetMatrix();
     802             : }
     803             : 
     804           0 : ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef ) :
     805           0 :     ScToken(formula::svMatrix), mpMatrix(p), maRef(rRef) {}
     806             : 
     807           0 : ScMatrixRangeToken::ScMatrixRangeToken( const sc::RangeMatrix& rMat ) :
     808           0 :     ScToken(formula::svMatrix), mpMatrix(rMat.mpMat)
     809             : {
     810           0 :     maRef.InitRange(rMat.mnCol1, rMat.mnRow1, rMat.mnTab1, rMat.mnCol2, rMat.mnRow2, rMat.mnTab2);
     811           0 : }
     812             : 
     813           0 : ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRangeToken& r ) :
     814           0 :     ScToken(r), mpMatrix(r.mpMatrix), maRef(r.maRef) {}
     815             : 
     816           0 : sal_uInt8 ScMatrixRangeToken::GetByte() const
     817             : {
     818           0 :     return MATRIX_TOKEN_HAS_RANGE;
     819             : }
     820             : 
     821           0 : const ScMatrix* ScMatrixRangeToken::GetMatrix() const
     822             : {
     823           0 :     return mpMatrix.get();
     824             : }
     825             : 
     826           0 : ScMatrix* ScMatrixRangeToken::GetMatrix()
     827             : {
     828           0 :     return mpMatrix.get();
     829             : }
     830             : 
     831           0 : const ScComplexRefData& ScMatrixRangeToken::GetDoubleRef() const
     832             : {
     833           0 :     return maRef;
     834             : }
     835             : 
     836           0 : ScComplexRefData& ScMatrixRangeToken::GetDoubleRef()
     837             : {
     838           0 :     return maRef;
     839             : }
     840             : 
     841           0 : bool ScMatrixRangeToken::operator==( const FormulaToken& r ) const
     842             : {
     843           0 :     return FormulaToken::operator==(r) && mpMatrix == static_cast<const ScToken&>(r).GetMatrix();
     844             : }
     845             : 
     846           0 : FormulaToken* ScMatrixRangeToken::Clone() const
     847             : {
     848           0 :     return new ScMatrixRangeToken(*this);
     849             : }
     850             : 
     851           0 : ScExternalSingleRefToken::ScExternalSingleRefToken( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScSingleRefData& r ) :
     852             :     ScToken( svExternalSingleRef, ocPush),
     853             :     mnFileId(nFileId),
     854             :     maTabName(rTabName),
     855           0 :     maSingleRef(r)
     856             : {
     857           0 : }
     858             : 
     859           0 : ScExternalSingleRefToken::ScExternalSingleRefToken( const ScExternalSingleRefToken& r ) :
     860             :     ScToken(r),
     861             :     mnFileId(r.mnFileId),
     862             :     maTabName(r.maTabName),
     863           0 :     maSingleRef(r.maSingleRef)
     864             : {
     865           0 : }
     866             : 
     867           0 : ScExternalSingleRefToken::~ScExternalSingleRefToken()
     868             : {
     869           0 : }
     870             : 
     871           0 : sal_uInt16 ScExternalSingleRefToken::GetIndex() const
     872             : {
     873           0 :     return mnFileId;
     874             : }
     875             : 
     876           0 : svl::SharedString ScExternalSingleRefToken::GetString() const
     877             : {
     878           0 :     return maTabName;
     879             : }
     880             : 
     881           0 : const ScSingleRefData& ScExternalSingleRefToken::GetSingleRef() const
     882             : {
     883           0 :     return maSingleRef;
     884             : }
     885             : 
     886           0 : ScSingleRefData& ScExternalSingleRefToken::GetSingleRef()
     887             : {
     888           0 :     return maSingleRef;
     889             : }
     890             : 
     891           0 : bool ScExternalSingleRefToken::operator ==( const FormulaToken& r ) const
     892             : {
     893           0 :     if (!FormulaToken::operator==(r))
     894           0 :         return false;
     895             : 
     896           0 :     if (mnFileId != r.GetIndex())
     897           0 :         return false;
     898             : 
     899           0 :     if (maTabName != r.GetString())
     900           0 :         return false;
     901             : 
     902           0 :     return maSingleRef == static_cast<const ScToken&>(r).GetSingleRef();
     903             : }
     904             : 
     905           0 : ScExternalDoubleRefToken::ScExternalDoubleRefToken( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScComplexRefData& r ) :
     906             :     ScToken( svExternalDoubleRef, ocPush),
     907             :     mnFileId(nFileId),
     908             :     maTabName(rTabName),
     909           0 :     maDoubleRef(r)
     910             : {
     911           0 : }
     912             : 
     913           0 : ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r ) :
     914             :     ScToken(r),
     915             :     mnFileId(r.mnFileId),
     916             :     maTabName(r.maTabName),
     917           0 :     maDoubleRef(r.maDoubleRef)
     918             : {
     919           0 : }
     920             : 
     921           0 : ScExternalDoubleRefToken::~ScExternalDoubleRefToken()
     922             : {
     923           0 : }
     924             : 
     925           0 : sal_uInt16 ScExternalDoubleRefToken::GetIndex() const
     926             : {
     927           0 :     return mnFileId;
     928             : }
     929             : 
     930           0 : svl::SharedString ScExternalDoubleRefToken::GetString() const
     931             : {
     932           0 :     return maTabName;
     933             : }
     934             : 
     935           0 : const ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef() const
     936             : {
     937           0 :     return maDoubleRef.Ref1;
     938             : }
     939             : 
     940           0 : ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef()
     941             : {
     942           0 :     return maDoubleRef.Ref1;
     943             : }
     944             : 
     945           0 : const ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef2() const
     946             : {
     947           0 :     return maDoubleRef.Ref2;
     948             : }
     949             : 
     950           0 : ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef2()
     951             : {
     952           0 :     return maDoubleRef.Ref2;
     953             : }
     954             : 
     955           0 : const ScComplexRefData& ScExternalDoubleRefToken::GetDoubleRef() const
     956             : {
     957           0 :     return maDoubleRef;
     958             : }
     959             : 
     960           0 : ScComplexRefData& ScExternalDoubleRefToken::GetDoubleRef()
     961             : {
     962           0 :     return maDoubleRef;
     963             : }
     964             : 
     965           0 : bool ScExternalDoubleRefToken::operator ==( const FormulaToken& r ) const
     966             : {
     967           0 :     if (!ScToken::operator==(r))
     968           0 :         return false;
     969             : 
     970           0 :     if (mnFileId != r.GetIndex())
     971           0 :         return false;
     972             : 
     973           0 :     if (maTabName != r.GetString())
     974           0 :         return false;
     975             : 
     976           0 :     return maDoubleRef == static_cast<const ScToken&>(r).GetDoubleRef();
     977             : }
     978             : 
     979           0 : ScExternalNameToken::ScExternalNameToken( sal_uInt16 nFileId, const svl::SharedString& rName ) :
     980             :     ScToken( svExternalName, ocPush),
     981             :     mnFileId(nFileId),
     982           0 :     maName(rName)
     983             : {
     984           0 : }
     985             : 
     986           0 : ScExternalNameToken::ScExternalNameToken( const ScExternalNameToken& r ) :
     987             :     ScToken(r),
     988             :     mnFileId(r.mnFileId),
     989           0 :     maName(r.maName)
     990             : {
     991           0 : }
     992             : 
     993           0 : ScExternalNameToken::~ScExternalNameToken() {}
     994             : 
     995           0 : sal_uInt16 ScExternalNameToken::GetIndex() const
     996             : {
     997           0 :     return mnFileId;
     998             : }
     999             : 
    1000           0 : svl::SharedString ScExternalNameToken::GetString() const
    1001             : {
    1002           0 :     return maName;
    1003             : }
    1004             : 
    1005           0 : bool ScExternalNameToken::operator==( const FormulaToken& r ) const
    1006             : {
    1007           0 :     if ( !FormulaToken::operator==(r) )
    1008           0 :         return false;
    1009             : 
    1010           0 :     if (mnFileId != r.GetIndex())
    1011           0 :         return false;
    1012             : 
    1013           0 :     return maName.getData() == r.GetString().getData();
    1014             : }
    1015             : 
    1016           0 : ScJumpMatrix* ScJumpMatrixToken::GetJumpMatrix() const  { return pJumpMatrix; }
    1017           0 : bool ScJumpMatrixToken::operator==( const FormulaToken& r ) const
    1018             : {
    1019           0 :     return FormulaToken::operator==( r ) && pJumpMatrix == static_cast<const ScToken&>(r).GetJumpMatrix();
    1020             : }
    1021           0 : ScJumpMatrixToken::~ScJumpMatrixToken()
    1022             : {
    1023           0 :     delete pJumpMatrix;
    1024           0 : }
    1025             : 
    1026           0 : double          ScEmptyCellToken::GetDouble() const     { return 0.0; }
    1027             : 
    1028           0 : svl::SharedString ScEmptyCellToken::GetString() const
    1029             : {
    1030           0 :     return svl::SharedString::getEmptyString();
    1031             : }
    1032             : 
    1033           0 : bool ScEmptyCellToken::operator==( const FormulaToken& r ) const
    1034             : {
    1035           0 :     return FormulaToken::operator==( r ) &&
    1036           0 :         bInherited == static_cast< const ScEmptyCellToken & >(r).IsInherited() &&
    1037           0 :         bDisplayedAsString == static_cast< const ScEmptyCellToken & >(r).IsDisplayedAsString();
    1038             : }
    1039             : 
    1040           0 : ScMatrixCellResultToken::ScMatrixCellResultToken( const ScConstMatrixRef& pMat, formula::FormulaToken* pUL ) :
    1041           0 :     ScToken(formula::svMatrixCell), xMatrix(pMat), xUpperLeft(pUL) {}
    1042             : 
    1043           0 : ScMatrixCellResultToken::ScMatrixCellResultToken( const ScMatrixCellResultToken& r ) :
    1044           0 :     ScToken(r), xMatrix(r.xMatrix), xUpperLeft(r.xUpperLeft) {}
    1045             : 
    1046           0 : double          ScMatrixCellResultToken::GetDouble() const  { return xUpperLeft->GetDouble(); }
    1047             : 
    1048           0 : svl::SharedString ScMatrixCellResultToken::GetString() const
    1049             : {
    1050           0 :     return xUpperLeft->GetString();
    1051             : }
    1052             : 
    1053           0 : const ScMatrix* ScMatrixCellResultToken::GetMatrix() const  { return xMatrix.get(); }
    1054             : // Non-const GetMatrix() is private and unused but must be implemented to
    1055             : // satisfy vtable linkage.
    1056           0 : ScMatrix* ScMatrixCellResultToken::GetMatrix()
    1057             : {
    1058           0 :     return const_cast<ScMatrix*>(xMatrix.get());
    1059             : }
    1060             : 
    1061           0 : bool ScMatrixCellResultToken::operator==( const FormulaToken& r ) const
    1062             : {
    1063           0 :     return FormulaToken::operator==( r ) &&
    1064           0 :         xUpperLeft == static_cast<const ScMatrixCellResultToken &>(r).xUpperLeft &&
    1065           0 :         xMatrix == static_cast<const ScMatrixCellResultToken &>(r).xMatrix;
    1066             : }
    1067             : 
    1068           0 : FormulaToken* ScMatrixCellResultToken::Clone() const
    1069             : {
    1070           0 :     return new ScMatrixCellResultToken(*this);
    1071             : }
    1072             : 
    1073           0 : void ScMatrixCellResultToken::Assign( const ScMatrixCellResultToken & r )
    1074             : {
    1075           0 :     xMatrix = r.xMatrix;
    1076           0 :     xUpperLeft = r.xUpperLeft;
    1077           0 : }
    1078             : 
    1079           0 : ScMatrixFormulaCellToken::ScMatrixFormulaCellToken(
    1080             :     SCCOL nC, SCROW nR, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL ) :
    1081           0 :     ScMatrixCellResultToken(pMat, pUL), nRows(nR), nCols(nC) {}
    1082             : 
    1083           0 : ScMatrixFormulaCellToken::ScMatrixFormulaCellToken( SCCOL nC, SCROW nR ) :
    1084           0 :     ScMatrixCellResultToken(NULL, NULL), nRows(nR), nCols(nC) {}
    1085             : 
    1086           0 : ScMatrixFormulaCellToken::ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken& r ) :
    1087           0 :     ScMatrixCellResultToken(r), nRows(r.nRows), nCols(r.nCols)
    1088             : {
    1089             :     // xUpperLeft is modifiable through
    1090             :     // SetUpperLeftDouble(), so clone it.
    1091           0 :     if (xUpperLeft)
    1092           0 :         xUpperLeft = xUpperLeft->Clone();
    1093           0 : }
    1094             : 
    1095           0 : bool ScMatrixFormulaCellToken::operator==( const FormulaToken& r ) const
    1096             : {
    1097           0 :     const ScMatrixFormulaCellToken* p = dynamic_cast<const ScMatrixFormulaCellToken*>(&r);
    1098           0 :     return p && ScMatrixCellResultToken::operator==( r ) &&
    1099           0 :         nCols == p->nCols && nRows == p->nRows;
    1100             : }
    1101             : 
    1102           0 : void ScMatrixFormulaCellToken::Assign( const ScMatrixCellResultToken & r )
    1103             : {
    1104           0 :     ScMatrixCellResultToken::Assign( r);
    1105           0 : }
    1106             : 
    1107           0 : void ScMatrixFormulaCellToken::Assign( const formula::FormulaToken& r )
    1108             : {
    1109           0 :     if (this == &r)
    1110           0 :         return;
    1111           0 :     const ScMatrixCellResultToken* p = dynamic_cast<const ScMatrixCellResultToken*>(&r);
    1112           0 :     if (p)
    1113           0 :         ScMatrixCellResultToken::Assign( *p);
    1114             :     else
    1115             :     {
    1116             :         OSL_ENSURE( r.GetType() != svMatrix, "ScMatrixFormulaCellToken::operator=: assigning ScMatrixToken to ScMatrixFormulaCellToken is not proper, use ScMatrixCellResultToken instead");
    1117           0 :         if (r.GetType() == svMatrix)
    1118             :         {
    1119           0 :             xUpperLeft = NULL;
    1120           0 :             xMatrix = static_cast<const ScToken&>(r).GetMatrix();
    1121             :         }
    1122             :         else
    1123             :         {
    1124           0 :             xUpperLeft = &r;
    1125           0 :             xMatrix = NULL;
    1126             :         }
    1127             :     }
    1128             : }
    1129             : 
    1130           0 : void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f )
    1131             : {
    1132           0 :     switch (GetUpperLeftType())
    1133             :     {
    1134             :         case svDouble:
    1135           0 :             const_cast<FormulaToken*>(xUpperLeft.get())->GetDoubleAsReference() = f;
    1136           0 :             break;
    1137             :         case svString:
    1138           0 :             xUpperLeft = new FormulaDoubleToken( f);
    1139           0 :             break;
    1140             :         case svUnknown:
    1141           0 :             if (!xUpperLeft)
    1142             :             {
    1143           0 :                 xUpperLeft = new FormulaDoubleToken( f);
    1144           0 :                 break;
    1145             :             }
    1146             :             // fall thru
    1147             :         default:
    1148             :             {
    1149             :                 OSL_FAIL("ScMatrixFormulaCellToken::SetUpperLeftDouble: not modifying unhandled token type");
    1150             :             }
    1151             :     }
    1152           0 : }
    1153             : 
    1154           0 : void ScMatrixFormulaCellToken::ResetResult()
    1155             : {
    1156           0 :     xMatrix = NULL;
    1157           0 :     xUpperLeft = NULL;
    1158           0 : }
    1159             : 
    1160             : 
    1161           0 : double ScHybridCellToken::GetDouble() const { return mfDouble; }
    1162             : 
    1163           0 : svl::SharedString ScHybridCellToken::GetString() const
    1164             : {
    1165           0 :     return maString;
    1166             : }
    1167             : 
    1168           0 : bool ScHybridCellToken::operator==( const FormulaToken& r ) const
    1169             : {
    1170           0 :     return FormulaToken::operator==( r ) &&
    1171           0 :         mfDouble == r.GetDouble() && maString == r.GetString() &&
    1172           0 :         maFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
    1173             : }
    1174             : 
    1175             : 
    1176             : 
    1177             : 
    1178           0 : bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken& _aToken,formula::ExternalReferenceHelper* _pRef)
    1179             : {
    1180           0 :     bool bError = FormulaTokenArray::AddFormulaToken(_aToken,_pRef);
    1181           0 :     if ( bError )
    1182             :     {
    1183           0 :         bError = false;
    1184           0 :         const OpCode eOpCode = static_cast<OpCode>(_aToken.OpCode);      //! assuming equal values for the moment
    1185             : 
    1186           0 :         const uno::TypeClass eClass = _aToken.Data.getValueTypeClass();
    1187           0 :         switch ( eClass )
    1188             :         {
    1189             :             case uno::TypeClass_STRUCT:
    1190             :                 {
    1191           0 :                     uno::Type aType = _aToken.Data.getValueType();
    1192           0 :                     if ( aType.equals( cppu::UnoType<sheet::SingleReference>::get() ) )
    1193             :                     {
    1194             :                         ScSingleRefData aSingleRef;
    1195           0 :                         sheet::SingleReference aApiRef;
    1196           0 :                         _aToken.Data >>= aApiRef;
    1197           0 :                         lcl_SingleRefToCalc( aSingleRef, aApiRef );
    1198           0 :                         if ( eOpCode == ocPush )
    1199           0 :                             AddSingleReference( aSingleRef );
    1200           0 :                         else if ( eOpCode == ocColRowName )
    1201           0 :                             AddColRowName( aSingleRef );
    1202             :                         else
    1203           0 :                             bError = true;
    1204             :                     }
    1205           0 :                     else if ( aType.equals( cppu::UnoType<sheet::ComplexReference>::get() ) )
    1206             :                     {
    1207             :                         ScComplexRefData aComplRef;
    1208           0 :                         sheet::ComplexReference aApiRef;
    1209           0 :                         _aToken.Data >>= aApiRef;
    1210           0 :                         lcl_SingleRefToCalc( aComplRef.Ref1, aApiRef.Reference1 );
    1211           0 :                         lcl_SingleRefToCalc( aComplRef.Ref2, aApiRef.Reference2 );
    1212             : 
    1213           0 :                         if ( eOpCode == ocPush )
    1214           0 :                             AddDoubleReference( aComplRef );
    1215             :                         else
    1216           0 :                             bError = true;
    1217             :                     }
    1218           0 :                     else if ( aType.equals( cppu::UnoType<sheet::NameToken>::get() ) )
    1219             :                     {
    1220           0 :                         sheet::NameToken aTokenData;
    1221           0 :                         _aToken.Data >>= aTokenData;
    1222           0 :                         if ( eOpCode == ocName )
    1223           0 :                             AddRangeName(aTokenData.Index, aTokenData.Global);
    1224           0 :                         else if (eOpCode == ocDBArea)
    1225           0 :                             AddDBRange(aTokenData.Index);
    1226             :                         else
    1227           0 :                             bError = true;
    1228             :                     }
    1229           0 :                     else if ( aType.equals( cppu::UnoType<sheet::ExternalReference>::get() ) )
    1230             :                     {
    1231           0 :                         sheet::ExternalReference aApiExtRef;
    1232           0 :                         if( (eOpCode == ocPush) && (_aToken.Data >>= aApiExtRef) && (0 <= aApiExtRef.Index) && (aApiExtRef.Index <= SAL_MAX_UINT16) )
    1233             :                         {
    1234           0 :                             sal_uInt16 nFileId = static_cast< sal_uInt16 >( aApiExtRef.Index );
    1235           0 :                             sheet::SingleReference aApiSRef;
    1236           0 :                             sheet::ComplexReference aApiCRef;
    1237           0 :                             OUString aName;
    1238           0 :                             if( aApiExtRef.Reference >>= aApiSRef )
    1239             :                             {
    1240             :                                 // try to resolve cache index to sheet name
    1241           0 :                                 size_t nCacheId = static_cast< size_t >( aApiSRef.Sheet );
    1242           0 :                                 OUString aTabName = _pRef->getCacheTableName( nFileId, nCacheId );
    1243           0 :                                 if( !aTabName.isEmpty() )
    1244             :                                 {
    1245             :                                     ScSingleRefData aSingleRef;
    1246             :                                     // convert column/row settings, set sheet index to absolute
    1247           0 :                                     lcl_ExternalRefToCalc( aSingleRef, aApiSRef );
    1248           0 :                                     AddExternalSingleReference( nFileId, aTabName, aSingleRef );
    1249             :                                 }
    1250             :                                 else
    1251           0 :                                     bError = true;
    1252             :                             }
    1253           0 :                             else if( aApiExtRef.Reference >>= aApiCRef )
    1254             :                             {
    1255             :                                 // try to resolve cache index to sheet name.
    1256           0 :                                 size_t nCacheId = static_cast< size_t >( aApiCRef.Reference1.Sheet );
    1257           0 :                                 OUString aTabName = _pRef->getCacheTableName( nFileId, nCacheId );
    1258           0 :                                 if( !aTabName.isEmpty() )
    1259             :                                 {
    1260             :                                     ScComplexRefData aComplRef;
    1261             :                                     // convert column/row settings, set sheet index to absolute
    1262           0 :                                     lcl_ExternalRefToCalc( aComplRef.Ref1, aApiCRef.Reference1 );
    1263           0 :                                     lcl_ExternalRefToCalc( aComplRef.Ref2, aApiCRef.Reference2 );
    1264             :                                     // NOTE: This assumes that cached sheets are in consecutive order!
    1265             :                                     aComplRef.Ref2.SetAbsTab(
    1266           0 :                                         aComplRef.Ref1.Tab() + static_cast<SCTAB>(aApiCRef.Reference2.Sheet - aApiCRef.Reference1.Sheet));
    1267           0 :                                     AddExternalDoubleReference( nFileId, aTabName, aComplRef );
    1268             :                                 }
    1269             :                                 else
    1270           0 :                                     bError = true;
    1271             :                             }
    1272           0 :                             else if( aApiExtRef.Reference >>= aName )
    1273             :                             {
    1274           0 :                                 if( !aName.isEmpty() )
    1275           0 :                                     AddExternalName( nFileId, aName );
    1276             :                                 else
    1277           0 :                                     bError = true;
    1278             :                             }
    1279             :                             else
    1280           0 :                                 bError = true;
    1281             :                         }
    1282             :                         else
    1283           0 :                             bError = true;
    1284             :                     }
    1285             :                     else
    1286           0 :                         bError = true;      // unknown struct
    1287             :                 }
    1288           0 :                 break;
    1289             :             case uno::TypeClass_SEQUENCE:
    1290             :                 {
    1291           0 :                     if ( eOpCode != ocPush )
    1292           0 :                         bError = true;      // not an inline array
    1293           0 :                     else if (!_aToken.Data.getValueType().equals( getCppuType(
    1294           0 :                                     (uno::Sequence< uno::Sequence< uno::Any > > *)0)))
    1295           0 :                         bError = true;      // unexpected sequence type
    1296             :                     else
    1297             :                     {
    1298           0 :                         ScMatrixRef xMat = ScSequenceToMatrix::CreateMixedMatrix( _aToken.Data);
    1299           0 :                         if (xMat)
    1300           0 :                             AddMatrix( xMat);
    1301             :                         else
    1302           0 :                             bError = true;
    1303             :                     }
    1304             :                 }
    1305           0 :                 break;
    1306             :             default:
    1307           0 :                 bError = true;
    1308             :         }
    1309             :     }
    1310           0 :     return bError;
    1311             : }
    1312             : 
    1313           0 : void ScTokenArray::CheckToken( const FormulaToken& r )
    1314             : {
    1315           0 :     if (meVectorState == FormulaVectorDisabled)
    1316             :         // It's already disabled.  No more checking needed.
    1317           0 :         return;
    1318             : 
    1319           0 :     OpCode eOp = r.GetOpCode();
    1320             : 
    1321           0 :     if (SC_OPCODE_START_FUNCTION <= eOp && eOp < SC_OPCODE_STOP_FUNCTION)
    1322             :     {
    1323             :         // This is a function opcode. For now, we only support vectorization
    1324             :         // for min, max, sum and average.
    1325           0 :         switch (eOp)
    1326             :         {
    1327             :             case ocAverage:
    1328             :             case ocMin:
    1329             :             case ocMinA:
    1330             :             case ocMax:
    1331             :             case ocMaxA:
    1332             :             case ocSum:
    1333             :             case ocSumIfs:
    1334             :             case ocSumProduct:
    1335             :             case ocCount:
    1336             :             case ocCount2:
    1337             :             case ocVLookup:
    1338             :             case ocLIA:
    1339             :             case ocIRR:
    1340             :             case ocMIRR:
    1341             :             case ocRMZ:
    1342             :             case ocZins:
    1343             :             case ocZGZ:
    1344             :             case ocKapz:
    1345             :             case ocFisher:
    1346             :             case ocFisherInv:
    1347             :             case ocGamma:
    1348             :             case ocGammaLn:
    1349             :             case ocNotAvail:
    1350             :             case ocGauss:
    1351             :             case ocGeoMean:
    1352             :             case ocHarMean:
    1353             :             case ocDIA:
    1354             :             case ocCorrel:
    1355             :             case ocNegBinomVert:
    1356             :             case ocPearson:
    1357             :             case ocRSQ:
    1358             :             case ocCos:
    1359             :             case ocCosecant:
    1360             :             case ocCosecantHyp:
    1361             :             case ocISPMT:
    1362             :             case ocLaufz:
    1363             :             case ocSinHyp:
    1364             :             case ocAbs:
    1365             :             case ocBW:
    1366             :             case ocSin:
    1367             :             case ocTan:
    1368             :             case ocTanHyp:
    1369             :             case ocStandard:
    1370             :             case ocWeibull:
    1371             :             case ocMedian:
    1372             :             case ocGDA:
    1373             :             case ocZW:
    1374             :             case ocVBD:
    1375             :             case ocKurt:
    1376             :             case ocZZR:
    1377             :             case ocNormDist:
    1378             :             case ocArcCos:
    1379             :             case ocSqrt:
    1380             :             case ocArcCosHyp:
    1381             :             case ocNPV:
    1382             :             case ocStdNormDist:
    1383             :             case ocNormInv:
    1384             :             case ocSNormInv:
    1385             :             case ocVariationen:
    1386             :             case ocVariationen2:
    1387             :             case ocPhi:
    1388             :             case ocZinsZ:
    1389             :             case ocConfidence:
    1390             :             case ocIntercept:
    1391             :             case ocGDA2:
    1392             :             case ocLogInv:
    1393             :             case ocArcCot:
    1394             :             case ocCosHyp:
    1395             :             case ocKritBinom:
    1396             :             case ocArcCotHyp:
    1397             :             case ocArcSin:
    1398             :             case ocArcSinHyp:
    1399             :             case ocArcTan:
    1400             :             case ocArcTanHyp:
    1401             :             case ocBitAnd:
    1402             :             case ocForecast:
    1403             :             case ocLogNormDist:
    1404             :             case ocGammaDist:
    1405             :             case ocLn:
    1406             :             case ocRound:
    1407             :             case ocCot:
    1408             :             case ocCotHyp:
    1409             :             case ocFDist:
    1410             :             case ocVar:
    1411             :             case ocChiDist:
    1412             :             case ocPower:
    1413             :             case ocOdd:
    1414             :             case ocChiSqDist:
    1415             :             case ocChiSqInv:
    1416             :             case ocGammaInv:
    1417             :             case ocFloor:
    1418             :             case ocFInv:
    1419             :             case ocFTest:
    1420             :             case ocB:
    1421             :             case ocBetaDist:
    1422             :             case ocExp:
    1423             :             case ocLog10:
    1424             :             case ocExpDist:
    1425             :             case ocAverageIfs:
    1426             :             case ocCountIfs:
    1427             :             case ocKombin2:
    1428             :             case ocEven:
    1429             :             case ocLog:
    1430             :             case ocMod:
    1431             :             case ocTrunc:
    1432             :             case ocSchiefe:
    1433             :             case ocArcTan2:
    1434             :             case ocBitOr:
    1435             :             case ocBitLshift:
    1436             :             case ocBitRshift:
    1437             :             case ocBitXor:
    1438             :             case ocChiInv:
    1439             :             case ocPoissonDist:
    1440             :             case ocSumSQ:
    1441             :             case ocSkewp:
    1442             :             case ocBinomDist:
    1443             :             case ocVarP:
    1444             :             case ocCeil:
    1445             :             case ocKombin:
    1446             :             case ocDevSq:
    1447             :             case ocStDev:
    1448             :             case ocSlope:
    1449             :             case ocSTEYX:
    1450             :             case ocZTest:
    1451             :             case ocPi:
    1452             :             case ocRandom:
    1453             :             case ocProduct:
    1454             :             case ocHypGeomDist:
    1455             :             case ocSumX2MY2:
    1456             :             case ocSumX2DY2:
    1457             :             case ocBetaInv:
    1458             :             case ocTTest:
    1459             :             case ocTDist:
    1460             :             case ocTInv:
    1461             :             case ocSumXMY2:
    1462             :             case ocStDevP:
    1463             :             case ocCovar:
    1464             :             case ocAnd:
    1465             :             case ocOr:
    1466             :             case ocNot:
    1467             :             case ocXor:
    1468             :             case ocDBMax:
    1469             :             case ocDBMin:
    1470             :             case ocDBProduct:
    1471             :             case ocDBAverage:
    1472             :             case ocDBStdDev:
    1473             :             case ocDBStdDevP:
    1474             :             case ocDBSum:
    1475             :             case ocDBVar:
    1476             :             case ocDBVarP:
    1477             :             case ocAverageIf:
    1478             :             case ocDBCount:
    1479             :             case ocDBCount2:
    1480             :             case ocDeg:
    1481             :             case ocRoundUp:
    1482             :             case ocRoundDown:
    1483             :             case ocInt:
    1484             :             case ocRad:
    1485             :             case ocCountIf:
    1486             :             case ocIsEven:
    1487             :             case ocIsOdd:
    1488             :             case ocFact:
    1489             :             case ocAverageA:
    1490             :             case ocVarA:
    1491             :             case ocVarPA:
    1492             :             case ocStDevA:
    1493             :             case ocStDevPA:
    1494             :             case ocSecant:
    1495             :             case ocSecantHyp:
    1496             :             case ocSumIf:
    1497             :             case ocNegSub:
    1498             :             case ocAveDev:
    1499             :             // Don't change the state.
    1500           0 :             break;
    1501             :             default:
    1502           0 :                 meVectorState = FormulaVectorDisabled;
    1503             :         }
    1504           0 :         return;
    1505             :     }
    1506             : 
    1507           0 :     if (eOp == ocPush)
    1508             :     {
    1509             :         // This is a stack variable.  See if this is a reference.
    1510             : 
    1511           0 :         switch (r.GetType())
    1512             :         {
    1513             :             case svByte:
    1514             :             case svDouble:
    1515             :             case svString:
    1516             :                 // Don't change the state.
    1517           0 :             break;
    1518             :             case svSingleRef:
    1519             :             case svDoubleRef:
    1520             :                 // Depends on the reference state.
    1521           0 :                 meVectorState = FormulaVectorCheckReference;
    1522           0 :             break;
    1523             :             case svError:
    1524             :             case svEmptyCell:
    1525             :             case svExternal:
    1526             :             case svExternalDoubleRef:
    1527             :             case svExternalName:
    1528             :             case svExternalSingleRef:
    1529             :             case svFAP:
    1530             :             case svHybridCell:
    1531             :             case svHybridValueCell:
    1532             :             case svIndex:
    1533             :             case svJump:
    1534             :             case svJumpMatrix:
    1535             :             case svMatrix:
    1536             :             case svMatrixCell:
    1537             :             case svMissing:
    1538             :             case svRefList:
    1539             :             case svSep:
    1540             :             case svSubroutine:
    1541             :             case svUnknown:
    1542             :                 // We don't support vectorization on these.
    1543           0 :                 meVectorState = FormulaVectorDisabled;
    1544             :             default:
    1545             :                 ;
    1546             :         }
    1547             :     }
    1548             : }
    1549             : 
    1550           0 : bool ScTokenArray::ImplGetReference( ScRange& rRange, const ScAddress& rPos, bool bValidOnly ) const
    1551             : {
    1552           0 :     bool bIs = false;
    1553           0 :     if ( pCode && nLen == 1 )
    1554             :     {
    1555           0 :         const FormulaToken* pToken = pCode[0];
    1556           0 :         if ( pToken )
    1557             :         {
    1558           0 :             if ( pToken->GetType() == svSingleRef )
    1559             :             {
    1560           0 :                 const ScSingleRefData& rRef = ((const ScSingleRefToken*)pToken)->GetSingleRef();
    1561           0 :                 rRange.aStart = rRange.aEnd = rRef.toAbs(rPos);
    1562           0 :                 bIs = !bValidOnly || ValidAddress(rRange.aStart);
    1563             :             }
    1564           0 :             else if ( pToken->GetType() == svDoubleRef )
    1565             :             {
    1566           0 :                 const ScComplexRefData& rCompl = ((const ScDoubleRefToken*)pToken)->GetDoubleRef();
    1567           0 :                 const ScSingleRefData& rRef1 = rCompl.Ref1;
    1568           0 :                 const ScSingleRefData& rRef2 = rCompl.Ref2;
    1569           0 :                 rRange.aStart = rRef1.toAbs(rPos);
    1570           0 :                 rRange.aEnd   = rRef2.toAbs(rPos);
    1571           0 :                 bIs = !bValidOnly || ValidRange(rRange);
    1572             :             }
    1573             :         }
    1574             :     }
    1575           0 :     return bIs;
    1576             : }
    1577             : 
    1578             : namespace {
    1579             : 
    1580             : // we want to compare for similar not identical formulae
    1581             : // so we can't use actual row & column indices.
    1582           0 : size_t HashSingleRef( const ScSingleRefData& rRef )
    1583             : {
    1584           0 :     size_t nVal = 0;
    1585             : 
    1586           0 :     nVal += size_t(rRef.IsColRel());
    1587           0 :     nVal += (size_t(rRef.IsRowRel()) << 1);
    1588           0 :     nVal += (size_t(rRef.IsTabRel()) << 2);
    1589             : 
    1590           0 :     return nVal;
    1591             : }
    1592             : 
    1593             : }
    1594             : 
    1595           0 : void ScTokenArray::GenHash()
    1596             : {
    1597             :     static OUStringHash aHasher;
    1598             : 
    1599           0 :     size_t nHash = 1;
    1600             :     OpCode eOp;
    1601             :     StackVar eType;
    1602             :     const ScToken* p;
    1603           0 :     sal_uInt16 n = std::min<sal_uInt16>(nLen, 20);
    1604           0 :     for (sal_uInt16 i = 0; i < n; ++i)
    1605             :     {
    1606           0 :         p = static_cast<const ScToken*>(pCode[i]);
    1607           0 :         eOp = p->GetOpCode();
    1608           0 :         if (eOp == ocPush)
    1609             :         {
    1610             :             // This is stack variable. Do additional differentiation.
    1611           0 :             eType = p->GetType();
    1612           0 :             switch (eType)
    1613             :             {
    1614             :                 case svByte:
    1615             :                 {
    1616             :                     // Constant value.
    1617           0 :                     sal_uInt8 nVal = p->GetByte();
    1618           0 :                     nHash += static_cast<size_t>(nVal);
    1619             :                 }
    1620           0 :                 break;
    1621             :                 case svDouble:
    1622             :                 {
    1623             :                     // Constant value.
    1624           0 :                     double fVal = p->GetDouble();
    1625           0 :                     nHash += static_cast<size_t>(fVal);
    1626             :                 }
    1627           0 :                 break;
    1628             :                 case svString:
    1629             :                 {
    1630             :                     // Constant string.
    1631           0 :                     OUString aStr = p->GetString().getString();
    1632           0 :                     nHash += aHasher(aStr);
    1633             :                 }
    1634           0 :                 break;
    1635             :                 case svSingleRef:
    1636             :                 {
    1637           0 :                     size_t nVal = HashSingleRef(p->GetSingleRef());
    1638           0 :                     nHash += nVal;
    1639             :                 }
    1640           0 :                 break;
    1641             :                 case svDoubleRef:
    1642             :                 {
    1643           0 :                     const ScComplexRefData& rRef = p->GetDoubleRef();
    1644           0 :                     size_t nVal1 = HashSingleRef(rRef.Ref1);
    1645           0 :                     size_t nVal2 = HashSingleRef(rRef.Ref2);
    1646           0 :                     nHash += nVal1;
    1647           0 :                     nHash += nVal2;
    1648             :                 }
    1649           0 :                 break;
    1650             :                 default:
    1651             :                     // Use the opcode value in all the other cases.
    1652           0 :                     nHash += static_cast<size_t>(eOp);
    1653             :             }
    1654             :         }
    1655             :         else
    1656             :             // Use the opcode value in all the other cases.
    1657           0 :             nHash += static_cast<size_t>(eOp);
    1658             : 
    1659           0 :         nHash = (nHash << 4) - nHash;
    1660             :     }
    1661             : 
    1662           0 :     mnHashValue = nHash;
    1663           0 : }
    1664             : 
    1665           0 : size_t ScTokenArray::GetHash() const
    1666             : {
    1667           0 :     return mnHashValue;
    1668             : }
    1669             : 
    1670           0 : ScFormulaVectorState ScTokenArray::GetVectorState() const
    1671             : {
    1672           0 :     return meVectorState;
    1673             : }
    1674             : 
    1675           0 : bool ScTokenArray::IsInvariant() const
    1676             : {
    1677           0 :     FormulaToken** p = pCode;
    1678           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    1679           0 :     for (; p != pEnd; ++p)
    1680             :     {
    1681           0 :         switch ((*p)->GetType())
    1682             :         {
    1683             :             case svSingleRef:
    1684             :             case svExternalSingleRef:
    1685             :             {
    1686           0 :                 const ScToken* pT = static_cast<const ScToken*>(*p);
    1687           0 :                 const ScSingleRefData& rRef = pT->GetSingleRef();
    1688           0 :                 if (rRef.IsRowRel())
    1689           0 :                     return false;
    1690             :             }
    1691           0 :             break;
    1692             :             case svDoubleRef:
    1693             :             case svExternalDoubleRef:
    1694             :             {
    1695           0 :                 const ScToken* pT = static_cast<const ScToken*>(*p);
    1696           0 :                 const ScComplexRefData& rRef = pT->GetDoubleRef();
    1697           0 :                 if (rRef.Ref1.IsRowRel() || rRef.Ref2.IsRowRel())
    1698           0 :                     return false;
    1699             :             }
    1700           0 :             break;
    1701             :             case svIndex:
    1702           0 :                 return false;
    1703             :             default:
    1704             :                 ;
    1705             :         }
    1706             :     }
    1707             : 
    1708           0 :     return true;
    1709             : }
    1710             : 
    1711           0 : bool ScTokenArray::IsReference( ScRange& rRange, const ScAddress& rPos ) const
    1712             : {
    1713           0 :     return ImplGetReference(rRange, rPos, false);
    1714             : }
    1715             : 
    1716           0 : bool ScTokenArray::IsValidReference( ScRange& rRange, const ScAddress& rPos ) const
    1717             : {
    1718           0 :     return ImplGetReference(rRange, rPos, true);
    1719             : }
    1720             : 
    1721           0 : ScTokenArray::ScTokenArray() :
    1722             :     FormulaTokenArray(),
    1723             :     mnHashValue(0),
    1724           0 :     meVectorState(FormulaVectorEnabled)
    1725             : {
    1726           0 : }
    1727             : 
    1728           0 : ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) :
    1729             :     FormulaTokenArray(rArr),
    1730             :     mnHashValue(rArr.mnHashValue),
    1731           0 :     meVectorState(rArr.meVectorState)
    1732             : {
    1733           0 : }
    1734             : 
    1735           0 : ScTokenArray::~ScTokenArray()
    1736             : {
    1737           0 : }
    1738             : 
    1739           0 : ScTokenArray& ScTokenArray::operator=( const ScTokenArray& rArr )
    1740             : {
    1741           0 :     Clear();
    1742           0 :     Assign( rArr );
    1743           0 :     return *this;
    1744             : }
    1745             : 
    1746           0 : ScTokenArray* ScTokenArray::Clone() const
    1747             : {
    1748           0 :     ScTokenArray* p = new ScTokenArray();
    1749           0 :     p->nLen = nLen;
    1750           0 :     p->nRPN = nRPN;
    1751           0 :     p->nRefs = nRefs;
    1752           0 :     p->nMode = nMode;
    1753           0 :     p->nError = nError;
    1754           0 :     p->bHyperLink = bHyperLink;
    1755           0 :     p->mnHashValue = mnHashValue;
    1756           0 :     p->meVectorState = meVectorState;
    1757             : 
    1758             :     FormulaToken** pp;
    1759           0 :     if( nLen )
    1760             :     {
    1761           0 :         pp = p->pCode = new FormulaToken*[ nLen ];
    1762           0 :         memcpy( pp, pCode, nLen * sizeof( ScToken* ) );
    1763           0 :         for( sal_uInt16 i = 0; i < nLen; i++, pp++ )
    1764             :         {
    1765           0 :             *pp = (*pp)->Clone();
    1766           0 :             (*pp)->IncRef();
    1767             :         }
    1768             :     }
    1769           0 :     if( nRPN )
    1770             :     {
    1771           0 :         pp = p->pRPN = new FormulaToken*[ nRPN ];
    1772           0 :         memcpy( pp, pRPN, nRPN * sizeof( ScToken* ) );
    1773           0 :         for( sal_uInt16 i = 0; i < nRPN; i++, pp++ )
    1774             :         {
    1775           0 :             FormulaToken* t = *pp;
    1776           0 :             if( t->GetRef() > 1 )
    1777             :             {
    1778           0 :                 FormulaToken** p2 = pCode;
    1779           0 :                 sal_uInt16 nIdx = 0xFFFF;
    1780           0 :                 for( sal_uInt16 j = 0; j < nLen; j++, p2++ )
    1781             :                 {
    1782           0 :                     if( *p2 == t )
    1783             :                     {
    1784           0 :                         nIdx = j; break;
    1785             :                     }
    1786             :                 }
    1787           0 :                 if( nIdx == 0xFFFF )
    1788           0 :                     *pp = t->Clone();
    1789             :                 else
    1790           0 :                     *pp = p->pCode[ nIdx ];
    1791             :             }
    1792             :             else
    1793           0 :                 *pp = t->Clone();
    1794           0 :             (*pp)->IncRef();
    1795             :         }
    1796             :     }
    1797           0 :     return p;
    1798             : }
    1799             : 
    1800           0 : FormulaToken* ScTokenArray::AddRawToken( const ScRawToken& r )
    1801             : {
    1802           0 :     return Add( r.CreateToken() );
    1803             : }
    1804             : 
    1805             : // Utility function to ensure that there is strict alternation of values and
    1806             : // separators.
    1807             : static bool
    1808           0 : checkArraySep( bool & bPrevWasSep, bool bNewVal )
    1809             : {
    1810           0 :     bool bResult = (bPrevWasSep == bNewVal);
    1811           0 :     bPrevWasSep = bNewVal;
    1812           0 :     return bResult;
    1813             : }
    1814             : 
    1815           0 : FormulaToken* ScTokenArray::MergeArray( )
    1816             : {
    1817           0 :     int nCol = -1, nRow = 0;
    1818           0 :     int i, nPrevRowSep = -1, nStart = 0;
    1819           0 :     bool bPrevWasSep = false; // top of stack is ocArrayClose
    1820             :     FormulaToken* t;
    1821           0 :     bool bNumeric = false;  // numeric value encountered in current element
    1822             : 
    1823             :     // (1) Iterate from the end to the start to find matrix dims
    1824             :     // and do basic validation.
    1825           0 :     for ( i = nLen ; i-- > nStart ; )
    1826             :     {
    1827           0 :         t = pCode[i];
    1828           0 :         switch ( t->GetOpCode() )
    1829             :         {
    1830             :             case ocPush :
    1831           0 :                 if( checkArraySep( bPrevWasSep, false ) )
    1832             :                 {
    1833           0 :                     return NULL;
    1834             :                 }
    1835             : 
    1836             :                 // no references or nested arrays
    1837           0 :                 if ( t->GetType() != svDouble  && t->GetType() != svString )
    1838             :                 {
    1839           0 :                     return NULL;
    1840             :                 }
    1841           0 :                 bNumeric = (t->GetType() == svDouble);
    1842           0 :             break;
    1843             : 
    1844             :             case ocMissing :
    1845             :             case ocTrue :
    1846             :             case ocFalse :
    1847           0 :                 if( checkArraySep( bPrevWasSep, false ) )
    1848             :                 {
    1849           0 :                     return NULL;
    1850             :                 }
    1851           0 :                 bNumeric = false;
    1852           0 :             break;
    1853             : 
    1854             :             case ocArrayColSep :
    1855             :             case ocSep :
    1856           0 :                 if( checkArraySep( bPrevWasSep, true ) )
    1857             :                 {
    1858           0 :                     return NULL;
    1859             :                 }
    1860           0 :                 bNumeric = false;
    1861           0 :             break;
    1862             : 
    1863             :             case ocArrayClose :
    1864             :                 // not possible with the , but check just in case
    1865             :                 // something changes in the future
    1866           0 :                 if( i != (nLen-1))
    1867             :                 {
    1868           0 :                     return NULL;
    1869             :                 }
    1870             : 
    1871           0 :                 if( checkArraySep( bPrevWasSep, true ) )
    1872             :                 {
    1873           0 :                     return NULL;
    1874             :                 }
    1875             : 
    1876           0 :                 nPrevRowSep = i;
    1877           0 :                 bNumeric = false;
    1878           0 :             break;
    1879             : 
    1880             :             case ocArrayOpen :
    1881           0 :                 nStart = i; // stop iteration
    1882             :                 // fall through to ArrayRowSep
    1883             : 
    1884             :             case ocArrayRowSep :
    1885           0 :                 if( checkArraySep( bPrevWasSep, true ) )
    1886             :                 {
    1887           0 :                     return NULL;
    1888             :                 }
    1889             : 
    1890           0 :                 if( nPrevRowSep < 0 ||              // missing ocArrayClose
    1891           0 :                     ((nPrevRowSep - i) % 2) == 1)   // no complex elements
    1892             :                 {
    1893           0 :                     return NULL;
    1894             :                 }
    1895             : 
    1896           0 :                 if( nCol < 0 )
    1897             :                 {
    1898           0 :                     nCol = (nPrevRowSep - i) / 2;
    1899             :                 }
    1900           0 :                 else if( (nPrevRowSep - i)/2 != nCol)   // irregular array
    1901             :                 {
    1902           0 :                     return NULL;
    1903             :                 }
    1904             : 
    1905           0 :                 nPrevRowSep = i;
    1906           0 :                 nRow++;
    1907           0 :                 bNumeric = false;
    1908           0 :             break;
    1909             : 
    1910             :             case ocNegSub :
    1911             :             case ocAdd :
    1912             :                 // negation or unary plus must precede numeric value
    1913           0 :                 if( !bNumeric )
    1914             :                 {
    1915           0 :                     return NULL;
    1916             :                 }
    1917           0 :                 --nPrevRowSep;      // shorten this row by 1
    1918           0 :                 bNumeric = false;   // one level only, no --42
    1919           0 :             break;
    1920             : 
    1921             :             case ocSpaces :
    1922             :                 // ignore spaces
    1923           0 :                 --nPrevRowSep;      // shorten this row by 1
    1924           0 :             break;
    1925             : 
    1926             :             default :
    1927             :                 // no functions or operators
    1928           0 :                 return NULL;
    1929             :         }
    1930             :     }
    1931           0 :     if( nCol <= 0 || nRow <= 0 )
    1932           0 :         return NULL;
    1933             : 
    1934           0 :     int nSign = 1;
    1935           0 :     ScMatrix* pArray = new ScMatrix(nCol, nRow, 0.0);
    1936           0 :     for ( i = nStart, nCol = 0, nRow = 0 ; i < nLen ; i++ )
    1937             :     {
    1938           0 :         t = pCode[i];
    1939             : 
    1940           0 :         switch ( t->GetOpCode() )
    1941             :         {
    1942             :             case ocPush :
    1943           0 :                 if ( t->GetType() == svDouble )
    1944             :                 {
    1945           0 :                     pArray->PutDouble( t->GetDouble() * nSign, nCol, nRow );
    1946           0 :                     nSign = 1;
    1947             :                 }
    1948           0 :                 else if ( t->GetType() == svString )
    1949             :                 {
    1950           0 :                     pArray->PutString(svl::SharedString(t->GetString()), nCol, nRow);
    1951             :                 }
    1952           0 :             break;
    1953             : 
    1954             :             case ocMissing :
    1955           0 :                 pArray->PutEmpty( nCol, nRow );
    1956           0 :             break;
    1957             : 
    1958             :             case ocTrue :
    1959           0 :                 pArray->PutBoolean( true, nCol, nRow );
    1960           0 :             break;
    1961             : 
    1962             :             case ocFalse :
    1963           0 :                 pArray->PutBoolean( false, nCol, nRow );
    1964           0 :             break;
    1965             : 
    1966             :             case ocArrayColSep :
    1967             :             case ocSep :
    1968           0 :                 nCol++;
    1969           0 :             break;
    1970             : 
    1971             :             case ocArrayRowSep :
    1972           0 :                 nRow++; nCol = 0;
    1973           0 :             break;
    1974             : 
    1975             :             case ocNegSub :
    1976           0 :                 nSign = -nSign;
    1977           0 :             break;
    1978             : 
    1979             :             default :
    1980           0 :                 break;
    1981             :         }
    1982           0 :         pCode[i] = NULL;
    1983           0 :         t->DecRef();
    1984             :     }
    1985           0 :     nLen = sal_uInt16( nStart );
    1986           0 :     return AddMatrix( pArray );
    1987             : }
    1988             : 
    1989             : 
    1990           0 : FormulaToken* ScTokenArray::MergeRangeReference( const ScAddress & rPos )
    1991             : {
    1992           0 :     if (!pCode || !nLen)
    1993           0 :         return NULL;
    1994           0 :     sal_uInt16 nIdx = nLen;
    1995             :     FormulaToken *p1, *p2, *p3;      // ref, ocRange, ref
    1996             :     // The actual types are checked in ExtendRangeReference().
    1997           0 :     if (((p3 = PeekPrev(nIdx)) != 0) &&
    1998           0 :             (((p2 = PeekPrev(nIdx)) != 0) && p2->GetOpCode() == ocRange) &&
    1999           0 :             ((p1 = PeekPrev(nIdx)) != 0))
    2000             :     {
    2001           0 :         FormulaTokenRef p = ScToken::ExtendRangeReference( *p1, *p3, rPos, true);
    2002           0 :         if (p)
    2003             :         {
    2004           0 :             p->IncRef();
    2005           0 :             p1->DecRef();
    2006           0 :             p2->DecRef();
    2007           0 :             p3->DecRef();
    2008           0 :             nLen -= 2;
    2009           0 :             pCode[ nLen-1 ] = p.get();
    2010           0 :             nRefs--;
    2011           0 :         }
    2012             :     }
    2013           0 :     return pCode[ nLen-1 ];
    2014             : }
    2015             : 
    2016           0 : FormulaToken* ScTokenArray::AddOpCode( OpCode e )
    2017             : {
    2018           0 :     ScRawToken t;
    2019           0 :     t.SetOpCode( e );
    2020           0 :     return AddRawToken( t );
    2021             : }
    2022             : 
    2023           0 : FormulaToken* ScTokenArray::AddSingleReference( const ScSingleRefData& rRef )
    2024             : {
    2025           0 :     return Add( new ScSingleRefToken( rRef ) );
    2026             : }
    2027             : 
    2028           0 : FormulaToken* ScTokenArray::AddMatrixSingleReference( const ScSingleRefData& rRef )
    2029             : {
    2030           0 :     return Add( new ScSingleRefToken( rRef, ocMatRef ) );
    2031             : }
    2032             : 
    2033           0 : FormulaToken* ScTokenArray::AddDoubleReference( const ScComplexRefData& rRef )
    2034             : {
    2035           0 :     return Add( new ScDoubleRefToken( rRef ) );
    2036             : }
    2037             : 
    2038           0 : FormulaToken* ScTokenArray::AddMatrix( const ScMatrixRef& p )
    2039             : {
    2040           0 :     return Add( new ScMatrixToken( p ) );
    2041             : }
    2042             : 
    2043           0 : FormulaToken* ScTokenArray::AddRangeName( sal_uInt16 n, bool bGlobal )
    2044             : {
    2045           0 :     return Add( new FormulaIndexToken( ocName, n, bGlobal));
    2046             : }
    2047             : 
    2048           0 : FormulaToken* ScTokenArray::AddDBRange( sal_uInt16 n )
    2049             : {
    2050           0 :     return Add( new FormulaIndexToken( ocDBArea, n));
    2051             : }
    2052             : 
    2053           0 : FormulaToken* ScTokenArray::AddExternalName( sal_uInt16 nFileId, const OUString& rName )
    2054             : {
    2055           0 :     return Add( new ScExternalNameToken(nFileId, rName) );
    2056             : }
    2057             : 
    2058           0 : FormulaToken* ScTokenArray::AddExternalSingleReference( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef )
    2059             : {
    2060           0 :     return Add( new ScExternalSingleRefToken(nFileId, rTabName, rRef) );
    2061             : }
    2062             : 
    2063           0 : FormulaToken* ScTokenArray::AddExternalDoubleReference( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef )
    2064             : {
    2065           0 :     return Add( new ScExternalDoubleRefToken(nFileId, rTabName, rRef) );
    2066             : }
    2067             : 
    2068           0 : FormulaToken* ScTokenArray::AddColRowName( const ScSingleRefData& rRef )
    2069             : {
    2070           0 :     return Add( new ScSingleRefToken( rRef, ocColRowName ) );
    2071             : }
    2072             : 
    2073           0 : bool ScTokenArray::GetAdjacentExtendOfOuterFuncRefs( SCCOLROW& nExtend,
    2074             :         const ScAddress& rPos, ScDirection eDir )
    2075             : {
    2076           0 :     SCCOL nCol = 0;
    2077           0 :     SCROW nRow = 0;
    2078           0 :     switch ( eDir )
    2079             :     {
    2080             :         case DIR_BOTTOM :
    2081           0 :             if ( rPos.Row() < MAXROW )
    2082           0 :                 nRow = (nExtend = rPos.Row()) + 1;
    2083             :             else
    2084           0 :                 return false;
    2085           0 :         break;
    2086             :         case DIR_RIGHT :
    2087           0 :             if ( rPos.Col() < MAXCOL )
    2088           0 :                 nCol = static_cast<SCCOL>(nExtend = rPos.Col()) + 1;
    2089             :             else
    2090           0 :                 return false;
    2091           0 :         break;
    2092             :         case DIR_TOP :
    2093           0 :             if ( rPos.Row() > 0 )
    2094           0 :                 nRow = (nExtend = rPos.Row()) - 1;
    2095             :             else
    2096           0 :                 return false;
    2097           0 :         break;
    2098             :         case DIR_LEFT :
    2099           0 :             if ( rPos.Col() > 0 )
    2100           0 :                 nCol = static_cast<SCCOL>(nExtend = rPos.Col()) - 1;
    2101             :             else
    2102           0 :                 return false;
    2103           0 :         break;
    2104             :         default:
    2105             :             OSL_FAIL( "unknown Direction" );
    2106           0 :             return false;
    2107             :     }
    2108           0 :     if ( pRPN && nRPN )
    2109             :     {
    2110           0 :         FormulaToken* t = pRPN[nRPN-1];
    2111           0 :         if ( t->GetType() == svByte )
    2112             :         {
    2113           0 :             sal_uInt8 nParamCount = t->GetByte();
    2114           0 :             if ( nParamCount && nRPN > nParamCount )
    2115             :             {
    2116           0 :                 bool bRet = false;
    2117           0 :                 sal_uInt16 nParam = nRPN - nParamCount - 1;
    2118           0 :                 for ( ; nParam < nRPN-1; nParam++ )
    2119             :                 {
    2120           0 :                     FormulaToken* p = pRPN[nParam];
    2121           0 :                     switch ( p->GetType() )
    2122             :                     {
    2123             :                         case svSingleRef :
    2124             :                         {
    2125           0 :                             ScSingleRefData& rRef = static_cast<ScToken*>(p)->GetSingleRef();
    2126           0 :                             ScAddress aAbs = rRef.toAbs(rPos);
    2127           0 :                             switch ( eDir )
    2128             :                             {
    2129             :                                 case DIR_BOTTOM :
    2130           0 :                                     if (aAbs.Row() == nRow && aAbs.Row() > nExtend)
    2131             :                                     {
    2132           0 :                                         nExtend = aAbs.Row();
    2133           0 :                                         bRet = true;
    2134             :                                     }
    2135           0 :                                 break;
    2136             :                                 case DIR_RIGHT :
    2137           0 :                                     if (aAbs.Col() == nCol && static_cast<SCCOLROW>(aAbs.Col()) > nExtend)
    2138             :                                     {
    2139           0 :                                         nExtend = aAbs.Col();
    2140           0 :                                         bRet = true;
    2141             :                                     }
    2142           0 :                                 break;
    2143             :                                 case DIR_TOP :
    2144           0 :                                     if (aAbs.Row() == nRow && aAbs.Row() < nExtend)
    2145             :                                     {
    2146           0 :                                         nExtend = aAbs.Row();
    2147           0 :                                         bRet = true;
    2148             :                                     }
    2149           0 :                                 break;
    2150             :                                 case DIR_LEFT :
    2151           0 :                                     if (aAbs.Col() == nCol && static_cast<SCCOLROW>(aAbs.Col()) < nExtend)
    2152             :                                     {
    2153           0 :                                         nExtend = aAbs.Col();
    2154           0 :                                         bRet = true;
    2155             :                                     }
    2156           0 :                                 break;
    2157             :                             }
    2158             :                         }
    2159           0 :                         break;
    2160             :                         case svDoubleRef :
    2161             :                         {
    2162           0 :                             ScComplexRefData& rRef = static_cast<ScToken*>(p)->GetDoubleRef();
    2163           0 :                             ScRange aAbs = rRef.toAbs(rPos);
    2164           0 :                             switch ( eDir )
    2165             :                             {
    2166             :                                 case DIR_BOTTOM :
    2167           0 :                                     if (aAbs.aStart.Row() == nRow && aAbs.aEnd.Row() > nExtend)
    2168             :                                     {
    2169           0 :                                         nExtend = aAbs.aEnd.Row();
    2170           0 :                                         bRet = true;
    2171             :                                     }
    2172           0 :                                 break;
    2173             :                                 case DIR_RIGHT :
    2174           0 :                                     if (aAbs.aStart.Col() == nCol && static_cast<SCCOLROW>(aAbs.aEnd.Col()) > nExtend)
    2175             :                                     {
    2176           0 :                                         nExtend = aAbs.aEnd.Col();
    2177           0 :                                         bRet = true;
    2178             :                                     }
    2179           0 :                                 break;
    2180             :                                 case DIR_TOP :
    2181           0 :                                     if (aAbs.aEnd.Row() == nRow && aAbs.aStart.Row() < nExtend)
    2182             :                                     {
    2183           0 :                                         nExtend = aAbs.aStart.Row();
    2184           0 :                                         bRet = true;
    2185             :                                     }
    2186           0 :                                 break;
    2187             :                                 case DIR_LEFT :
    2188           0 :                                     if (aAbs.aEnd.Col() == nCol && static_cast<SCCOLROW>(aAbs.aStart.Col()) < nExtend)
    2189             :                                     {
    2190           0 :                                         nExtend = aAbs.aStart.Col();
    2191           0 :                                         bRet = true;
    2192             :                                     }
    2193           0 :                                 break;
    2194             :                             }
    2195             :                         }
    2196           0 :                         break;
    2197             :                         default:
    2198             :                         {
    2199             :                             // added to avoid warnings
    2200             :                         }
    2201             :                     } // switch
    2202             :                 } // for
    2203           0 :                 return bRet;
    2204             :             }
    2205             :         }
    2206             :     }
    2207           0 :     return false;
    2208             : }
    2209             : 
    2210             : 
    2211           0 : void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos,
    2212             :         const ScAddress& rNewPos )
    2213             : {
    2214           0 :     for ( sal_uInt16 j=0; j<nLen; ++j )
    2215             :     {
    2216           0 :         switch ( pCode[j]->GetType() )
    2217             :         {
    2218             :             case svDoubleRef :
    2219             :             {
    2220           0 :                 ScSingleRefData& rRef2 = static_cast<ScToken*>(pCode[j])->GetSingleRef2();
    2221             :                 // Also adjust if the reference is of the form Sheet1.A2:A3
    2222           0 :                 if ( rRef2.IsFlag3D() || static_cast<ScToken*>(pCode[j])->GetSingleRef().IsFlag3D() )
    2223             :                 {
    2224           0 :                     ScAddress aAbs = rRef2.toAbs(rOldPos);
    2225           0 :                     rRef2.SetAddress(aAbs, rNewPos);
    2226             :                 }
    2227             :             }
    2228             :             //! fallthru
    2229             :             case svSingleRef :
    2230             :             {
    2231           0 :                 ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef();
    2232           0 :                 if ( rRef1.IsFlag3D() )
    2233             :                 {
    2234           0 :                     ScAddress aAbs = rRef1.toAbs(rOldPos);
    2235           0 :                     rRef1.SetAddress(aAbs, rNewPos);
    2236             :                 }
    2237             :             }
    2238           0 :             break;
    2239             :             default:
    2240             :             {
    2241             :                 // added to avoid warnings
    2242             :             }
    2243             :         }
    2244             :     }
    2245           0 : }
    2246             : 
    2247             : namespace {
    2248             : 
    2249           0 : void GetExternalTableData(const ScDocument* pOldDoc, const ScDocument* pNewDoc, const SCTAB nTab, OUString& rTabName, sal_uInt16& rFileId)
    2250             : {
    2251           0 :     OUString aFileName = pOldDoc->GetFileURL();;
    2252           0 :     rFileId = pNewDoc->GetExternalRefManager()->getExternalFileId(aFileName);
    2253           0 :     rTabName = pOldDoc->GetCopyTabName(nTab);
    2254           0 :     if (rTabName.isEmpty())
    2255           0 :         pOldDoc->GetName(nTab, rTabName);
    2256           0 : }
    2257             : 
    2258           0 : bool IsInCopyRange( const ScRange& rRange, const ScDocument* pClipDoc )
    2259             : {
    2260           0 :     ScClipParam& rClipParam = const_cast<ScDocument*>(pClipDoc)->GetClipParam();
    2261           0 :     return rClipParam.maRanges.In(rRange);
    2262             : }
    2263             : 
    2264           0 : bool SkipReference(ScToken* pToken, const ScAddress& rPos, const ScDocument* pOldDoc, bool bRangeName, bool bCheckCopyArea)
    2265             : {
    2266           0 :     ScRange aRange;
    2267             : 
    2268           0 :     if (!ScRefTokenHelper::getRangeFromToken(aRange, pToken, rPos))
    2269           0 :         return true;
    2270             : 
    2271           0 :     if (bRangeName && aRange.aStart.Tab() == rPos.Tab())
    2272             :     {
    2273           0 :         switch (pToken->GetType())
    2274             :         {
    2275             :             case svDoubleRef:
    2276             :                 {
    2277           0 :                     ScSingleRefData& rRef = pToken->GetSingleRef2();
    2278           0 :                     if (rRef.IsColRel() || rRef.IsRowRel())
    2279           0 :                         return true;
    2280             :                 } // fall through
    2281             :             case svSingleRef:
    2282             :                 {
    2283           0 :                     ScSingleRefData& rRef = pToken->GetSingleRef();
    2284           0 :                     if (rRef.IsColRel() || rRef.IsRowRel())
    2285           0 :                         return true;
    2286             :                 }
    2287           0 :                 break;
    2288             :             default:
    2289           0 :                 break;
    2290             :         }
    2291             :     }
    2292             : 
    2293           0 :     if (bCheckCopyArea && IsInCopyRange(aRange, pOldDoc))
    2294           0 :         return true;
    2295             : 
    2296           0 :     return false;
    2297             : }
    2298             : 
    2299           0 : void AdjustSingleRefData( ScSingleRefData& rRef, const ScAddress& rOldPos, const ScAddress& rNewPos)
    2300             : {
    2301           0 :     SCsCOL nCols = rNewPos.Col() - rOldPos.Col();
    2302           0 :     SCsROW nRows = rNewPos.Row() - rOldPos.Row();
    2303           0 :     SCsTAB nTabs = rNewPos.Tab() - rOldPos.Tab();
    2304             : 
    2305           0 :     if (!rRef.IsColRel())
    2306           0 :         rRef.IncCol(nCols);
    2307             : 
    2308           0 :     if (!rRef.IsRowRel())
    2309           0 :         rRef.IncRow(nRows);
    2310             : 
    2311           0 :     if (!rRef.IsTabRel())
    2312           0 :         rRef.IncTab(nTabs);
    2313           0 : }
    2314             : 
    2315             : }
    2316             : 
    2317           0 : void ScTokenArray::ReadjustAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos, bool bRangeName )
    2318             : {
    2319           0 :     for ( sal_uInt16 j=0; j<nLen; ++j )
    2320             :     {
    2321           0 :         switch ( pCode[j]->GetType() )
    2322             :         {
    2323             :             case svDoubleRef :
    2324             :             {
    2325           0 :                 if (SkipReference(static_cast<ScToken*>(pCode[j]), rPos, pOldDoc, bRangeName, true))
    2326           0 :                     continue;
    2327             : 
    2328           0 :                 ScComplexRefData& rRef = static_cast<ScToken*>(pCode[j])->GetDoubleRef();
    2329           0 :                 ScSingleRefData& rRef2 = rRef.Ref2;
    2330           0 :                 ScSingleRefData& rRef1 = rRef.Ref1;
    2331             : 
    2332           0 :                 if ( (rRef2.IsFlag3D() && !rRef2.IsTabRel()) || (rRef1.IsFlag3D() && !rRef1.IsTabRel()) )
    2333             :                 {
    2334           0 :                     OUString aTabName;
    2335             :                     sal_uInt16 nFileId;
    2336           0 :                     GetExternalTableData(pOldDoc, pNewDoc, rRef1.Tab(), aTabName, nFileId);
    2337           0 :                     pCode[j]->DecRef();
    2338           0 :                     ScExternalDoubleRefToken* pToken = new ScExternalDoubleRefToken(nFileId, aTabName, rRef);
    2339           0 :                     pToken->IncRef();
    2340           0 :                     pCode[j] = pToken;
    2341             :                 }
    2342             :             }
    2343           0 :             break;
    2344             :             case svSingleRef :
    2345             :             {
    2346           0 :                 if (SkipReference(static_cast<ScToken*>(pCode[j]), rPos, pOldDoc, bRangeName, true))
    2347           0 :                     continue;
    2348             : 
    2349           0 :                 ScSingleRefData& rRef = static_cast<ScToken*>(pCode[j])->GetSingleRef();
    2350             : 
    2351           0 :                 if ( rRef.IsFlag3D() && !rRef.IsTabRel() )
    2352             :                 {
    2353           0 :                     OUString aTabName;
    2354             :                     sal_uInt16 nFileId;
    2355           0 :                     GetExternalTableData(pOldDoc, pNewDoc, rRef.Tab(), aTabName, nFileId);
    2356             :                     //replace with ScExternalSingleRefToken and adjust references
    2357           0 :                     pCode[j]->DecRef();
    2358           0 :                     ScExternalSingleRefToken* pToken = new ScExternalSingleRefToken(nFileId, aTabName, rRef);
    2359           0 :                     pToken->IncRef();
    2360           0 :                     pCode[j] = pToken;
    2361             :                 }
    2362             :             }
    2363           0 :             break;
    2364             :             default:
    2365             :             {
    2366             :                 // added to avoid warnings
    2367             :             }
    2368             :         }
    2369             :     }
    2370           0 : }
    2371             : 
    2372           0 : void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bRangeName, bool bCheckCopyRange)
    2373             : {
    2374           0 :     for ( sal_uInt16 j=0; j<nLen; ++j )
    2375             :     {
    2376           0 :         switch ( pCode[j]->GetType() )
    2377             :         {
    2378             :             case svDoubleRef :
    2379             :             {
    2380           0 :                 if (!SkipReference(static_cast<ScToken*>(pCode[j]), rOldPos, pOldDoc, false, bCheckCopyRange))
    2381           0 :                     continue;
    2382             : 
    2383           0 :                 ScComplexRefData& rRef = static_cast<ScToken*>(pCode[j])->GetDoubleRef();
    2384           0 :                 ScSingleRefData& rRef2 = rRef.Ref2;
    2385           0 :                 ScSingleRefData& rRef1 = rRef.Ref1;
    2386             : 
    2387             :                 // for range names only adjust if all parts are absolute
    2388           0 :                 if (!bRangeName || !(rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel()))
    2389           0 :                     AdjustSingleRefData( rRef1, rOldPos, rNewPos );
    2390           0 :                 if (!bRangeName || !(rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel()))
    2391           0 :                     AdjustSingleRefData( rRef2, rOldPos, rNewPos );
    2392             :             }
    2393           0 :             break;
    2394             :             case svSingleRef :
    2395             :             {
    2396           0 :                 if (!SkipReference(static_cast<ScToken*>(pCode[j]), rOldPos, pOldDoc, false, bCheckCopyRange))
    2397           0 :                     continue;
    2398             : 
    2399           0 :                 ScSingleRefData& rRef = static_cast<ScToken*>(pCode[j])->GetSingleRef();
    2400             : 
    2401             :                 // for range names only adjust if all parts are absolute
    2402           0 :                 if (!bRangeName || !(rRef.IsColRel() || rRef.IsRowRel() || rRef.IsTabRel()))
    2403           0 :                     AdjustSingleRefData( rRef, rOldPos, rNewPos );
    2404             :             }
    2405           0 :             break;
    2406             :             default:
    2407             :             {
    2408             :                 // added to avoid warnings
    2409             :             }
    2410             :         }
    2411             :     }
    2412           0 : }
    2413             : 
    2414             : namespace {
    2415             : 
    2416           0 : ScRange getSelectedRange( const sc::RefUpdateContext& rCxt )
    2417             : {
    2418           0 :     ScRange aSelectedRange(ScAddress::INITIALIZE_INVALID);
    2419           0 :     if (rCxt.mnColDelta < 0)
    2420             :     {
    2421             :         // Delete and shift to left.
    2422           0 :         aSelectedRange.aStart = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta, rCxt.maRange.aStart.Row(), rCxt.maRange.aStart.Tab());
    2423           0 :         aSelectedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab());
    2424             :     }
    2425           0 :     else if (rCxt.mnRowDelta < 0)
    2426             :     {
    2427             :         // Delete and shift up.
    2428           0 :         aSelectedRange.aStart = ScAddress(rCxt.maRange.aStart.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta, rCxt.maRange.aStart.Tab());
    2429           0 :         aSelectedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()-1, rCxt.maRange.aEnd.Tab());
    2430             :     }
    2431           0 :     else if (rCxt.mnTabDelta < 0)
    2432             :     {
    2433             :         // Deleting sheets.
    2434             :         // TODO : Figure out what to do here.
    2435             :     }
    2436           0 :     else if (rCxt.mnColDelta > 0)
    2437             :     {
    2438             :         // Insert and shift to the right.
    2439           0 :         aSelectedRange.aStart = rCxt.maRange.aStart;
    2440           0 :         aSelectedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab());
    2441             :     }
    2442           0 :     else if (rCxt.mnRowDelta > 0)
    2443             :     {
    2444             :         // Insert and shift down.
    2445           0 :         aSelectedRange.aStart = rCxt.maRange.aStart;
    2446           0 :         aSelectedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta-1, rCxt.maRange.aEnd.Tab());
    2447             :     }
    2448           0 :     else if (rCxt.mnTabDelta > 0)
    2449             :     {
    2450             :         // Inserting sheets.
    2451             :         // TODO : Figure out what to do here.
    2452             :     }
    2453             : 
    2454           0 :     return aSelectedRange;
    2455             : }
    2456             : 
    2457           0 : void setRefDeleted( ScSingleRefData& rRef, const sc::RefUpdateContext& rCxt )
    2458             : {
    2459           0 :     if (rCxt.mnColDelta < 0)
    2460           0 :         rRef.SetColDeleted(true);
    2461           0 :     else if (rCxt.mnRowDelta < 0)
    2462           0 :         rRef.SetRowDeleted(true);
    2463           0 :     else if (rCxt.mnTabDelta < 0)
    2464           0 :         rRef.SetTabDeleted(true);
    2465           0 : }
    2466             : 
    2467           0 : void restoreDeletedRef( ScSingleRefData& rRef, const sc::RefUpdateContext& rCxt )
    2468             : {
    2469           0 :     if (rCxt.mnColDelta)
    2470             :     {
    2471           0 :         if (rRef.IsColDeleted())
    2472           0 :             rRef.SetColDeleted(false);
    2473             :     }
    2474           0 :     else if (rCxt.mnRowDelta)
    2475             :     {
    2476           0 :         if (rRef.IsRowDeleted())
    2477           0 :             rRef.SetRowDeleted(false);
    2478             :     }
    2479           0 :     else if (rCxt.mnTabDelta)
    2480             :     {
    2481           0 :         if (rRef.IsTabDeleted())
    2482           0 :             rRef.SetTabDeleted(false);
    2483             :     }
    2484           0 : }
    2485             : 
    2486           0 : void setRefDeleted( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt )
    2487             : {
    2488           0 :     if (rCxt.mnColDelta < 0)
    2489             :     {
    2490           0 :         rRef.Ref1.SetColDeleted(true);
    2491           0 :         rRef.Ref2.SetColDeleted(true);
    2492             :     }
    2493           0 :     else if (rCxt.mnRowDelta < 0)
    2494             :     {
    2495           0 :         rRef.Ref1.SetRowDeleted(true);
    2496           0 :         rRef.Ref2.SetRowDeleted(true);
    2497             :     }
    2498           0 :     else if (rCxt.mnTabDelta < 0)
    2499             :     {
    2500           0 :         rRef.Ref1.SetTabDeleted(true);
    2501           0 :         rRef.Ref2.SetTabDeleted(true);
    2502             :     }
    2503           0 : }
    2504             : 
    2505           0 : bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange )
    2506             : {
    2507           0 :     if (rCxt.mnColDelta < 0)
    2508             :     {
    2509             :         // Shifting left.
    2510           0 :         if (rRefRange.aStart.Row() < rDeletedRange.aStart.Row() || rDeletedRange.aEnd.Row() < rRefRange.aEnd.Row())
    2511             :             // Deleted range is only partially overlapping in vertical direction. Bail out.
    2512           0 :             return false;
    2513             : 
    2514             :         // Move the last column position to the left.
    2515           0 :         SCCOL nDelta = rDeletedRange.aStart.Col() - rDeletedRange.aEnd.Col() - 1;
    2516           0 :         rRefRange.aEnd.IncCol(nDelta);
    2517           0 :         return true;
    2518             :     }
    2519           0 :     else if (rCxt.mnRowDelta < 0)
    2520             :     {
    2521             :         // Shifting up.
    2522             : 
    2523           0 :         if (rRefRange.aStart.Col() < rDeletedRange.aStart.Col() || rDeletedRange.aEnd.Col() < rRefRange.aEnd.Col())
    2524             :             // Deleted range is only partially overlapping in horizontal direction. Bail out.
    2525           0 :             return false;
    2526             : 
    2527             :         // Move the last row position up.
    2528           0 :         SCROW nDelta = rDeletedRange.aStart.Row() - rDeletedRange.aEnd.Row() - 1;
    2529           0 :         rRefRange.aEnd.IncRow(nDelta);
    2530           0 :         return true;
    2531             :     }
    2532             : 
    2533           0 :     return false;
    2534             : }
    2535             : 
    2536           0 : bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange )
    2537             : {
    2538           0 :     if (!rSelectedRange.Intersects(rRefRange))
    2539           0 :         return false;
    2540             : 
    2541           0 :     if (rCxt.mnColDelta > 0)
    2542             :     {
    2543             :         // Insert and shifting right.
    2544           0 :         if (rRefRange.aStart.Row() < rSelectedRange.aStart.Row() || rSelectedRange.aEnd.Row() < rRefRange.aEnd.Row())
    2545             :             // Selected range is only partially overlapping in vertical direction. Bail out.
    2546           0 :             return false;
    2547             : 
    2548           0 :         if (!rCxt.mrDoc.IsExpandRefs() && rSelectedRange.aStart.Col() == rRefRange.aStart.Col())
    2549             :             // Selected range is at the left end and the edge expansion is turned off.  No expansion.
    2550           0 :             return false;
    2551             : 
    2552             :         // Move the last column position to the right.
    2553           0 :         SCCOL nDelta = rSelectedRange.aEnd.Col() - rSelectedRange.aStart.Col() + 1;
    2554           0 :         rRefRange.aEnd.IncCol(nDelta);
    2555           0 :         return true;
    2556             :     }
    2557           0 :     else if (rCxt.mnRowDelta > 0)
    2558             :     {
    2559             :         // Insert and shifting down.
    2560           0 :         if (rRefRange.aStart.Col() < rSelectedRange.aStart.Col() || rSelectedRange.aEnd.Col() < rRefRange.aEnd.Col())
    2561             :             // Selected range is only partially overlapping in horizontal direction. Bail out.
    2562           0 :             return false;
    2563             : 
    2564           0 :         if (!rCxt.mrDoc.IsExpandRefs() && rSelectedRange.aStart.Row() == rRefRange.aStart.Row())
    2565             :             // Selected range is at the top end and the edge expansion is turned off.  No expansion.
    2566           0 :             return false;
    2567             : 
    2568             :         // Move the last row position down.
    2569           0 :         SCROW nDelta = rSelectedRange.aEnd.Row() - rSelectedRange.aStart.Row() + 1;
    2570           0 :         rRefRange.aEnd.IncRow(nDelta);
    2571           0 :         return true;
    2572             :     }
    2573           0 :     return false;
    2574             : }
    2575             : 
    2576             : /**
    2577             :  * Check if the referenced range is expandable when the selected range is
    2578             :  * not overlapping the referenced range.
    2579             :  */
    2580           0 : bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange )
    2581             : {
    2582           0 :     if (!rCxt.mrDoc.IsExpandRefs())
    2583             :         // Edge-expansion is turned off.
    2584           0 :         return false;
    2585             : 
    2586           0 :     if (rCxt.mnColDelta > 0)
    2587             :     {
    2588             :         // Insert and shift right.
    2589           0 :         if (rRefRange.aStart.Row() < rSelectedRange.aStart.Row() || rSelectedRange.aEnd.Row() < rRefRange.aEnd.Row())
    2590             :             // Selected range is only partially overlapping in vertical direction. Bail out.
    2591           0 :             return false;
    2592             : 
    2593           0 :         if (rSelectedRange.aStart.Col() - rRefRange.aEnd.Col() != 1)
    2594             :             // Selected range is not immediately adjacent. Bail out.
    2595           0 :             return false;
    2596             : 
    2597             :         // Move the last column position to the right.
    2598           0 :         SCCOL nDelta = rSelectedRange.aEnd.Col() - rSelectedRange.aStart.Col() + 1;
    2599           0 :         rRefRange.aEnd.IncCol(nDelta);
    2600           0 :         return true;
    2601             :     }
    2602           0 :     else if (rCxt.mnRowDelta > 0)
    2603             :     {
    2604           0 :         if (rRefRange.aStart.Col() < rSelectedRange.aStart.Col() || rSelectedRange.aEnd.Col() < rRefRange.aEnd.Col())
    2605             :             // Selected range is only partially overlapping in horizontal direction. Bail out.
    2606           0 :             return false;
    2607             : 
    2608           0 :         if (rSelectedRange.aStart.Row() - rRefRange.aEnd.Row() != 1)
    2609             :             // Selected range is not immediately adjacent. Bail out.
    2610           0 :             return false;
    2611             : 
    2612             :         // Move the last row position down.
    2613           0 :         SCROW nDelta = rSelectedRange.aEnd.Row() - rSelectedRange.aStart.Row() + 1;
    2614           0 :         rRefRange.aEnd.IncRow(nDelta);
    2615           0 :         return true;
    2616             :     }
    2617             : 
    2618           0 :     return false;
    2619             : }
    2620             : 
    2621           0 : bool isNameModified( const sc::UpdatedRangeNames& rUpdatedNames, SCTAB nOldTab, const formula::FormulaToken& rToken )
    2622             : {
    2623           0 :     if (rToken.GetOpCode() != ocName)
    2624           0 :         return false;
    2625             : 
    2626           0 :     SCTAB nTab = -1;
    2627           0 :     if (!rToken.IsGlobal())
    2628           0 :         nTab = nOldTab;
    2629             : 
    2630             :     // Check if this named expression has been modified.
    2631           0 :     return rUpdatedNames.isNameUpdated(nTab, rToken.GetIndex());
    2632             : }
    2633             : 
    2634             : }
    2635             : 
    2636           0 : sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos )
    2637             : {
    2638           0 :     ScRange aSelectedRange = getSelectedRange(rCxt);
    2639             : 
    2640           0 :     sc::RefUpdateResult aRes;
    2641           0 :     ScAddress aNewPos = rOldPos;
    2642           0 :     bool bCellShifted = rCxt.maRange.In(rOldPos);
    2643           0 :     if (bCellShifted)
    2644           0 :         aNewPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
    2645             : 
    2646           0 :     FormulaToken** p = pCode;
    2647           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    2648           0 :     for (; p != pEnd; ++p)
    2649             :     {
    2650           0 :         switch ((*p)->GetType())
    2651             :         {
    2652             :             case svSingleRef:
    2653             :             {
    2654           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2655           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    2656           0 :                 ScAddress aAbs = rRef.toAbs(rOldPos);
    2657             : 
    2658           0 :                 if (rCxt.isDeleted() && aSelectedRange.In(aAbs))
    2659             :                 {
    2660             :                     // This reference is in the deleted region.
    2661           0 :                     setRefDeleted(rRef, rCxt);
    2662           0 :                     aRes.mbValueChanged = true;
    2663           0 :                     break;
    2664             :                 }
    2665             : 
    2666           0 :                 if (!rCxt.isDeleted() && rRef.IsDeleted())
    2667             :                 {
    2668             :                     // Check if the token has reference to previously deleted region.
    2669           0 :                     ScAddress aCheckPos = rRef.toAbs(aNewPos);
    2670           0 :                     if (rCxt.maRange.In(aCheckPos))
    2671             :                     {
    2672           0 :                         restoreDeletedRef(rRef, rCxt);
    2673           0 :                         aRes.mbValueChanged = true;
    2674           0 :                         break;
    2675             :                     }
    2676             :                 }
    2677             : 
    2678           0 :                 if (rCxt.maRange.In(aAbs))
    2679             :                 {
    2680           0 :                     aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
    2681           0 :                     aRes.mbReferenceModified = true;
    2682             :                 }
    2683             : 
    2684           0 :                 rRef.SetAddress(aAbs, aNewPos);
    2685             :             }
    2686           0 :             break;
    2687             :             case svDoubleRef:
    2688             :             {
    2689           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2690           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    2691           0 :                 ScRange aAbs = rRef.toAbs(rOldPos);
    2692             : 
    2693           0 :                 if (rCxt.isDeleted())
    2694             :                 {
    2695           0 :                     if (aSelectedRange.In(aAbs))
    2696             :                     {
    2697             :                         // This reference is in the deleted region.
    2698           0 :                         setRefDeleted(rRef, rCxt);
    2699           0 :                         aRes.mbValueChanged = true;
    2700           0 :                         break;
    2701             :                     }
    2702           0 :                     else if (aSelectedRange.Intersects(aAbs))
    2703             :                     {
    2704           0 :                         if (shrinkRange(rCxt, aAbs, aSelectedRange))
    2705             :                         {
    2706             :                             // The reference range has been shrunk.
    2707           0 :                             rRef.SetRange(aAbs, aNewPos);
    2708           0 :                             aRes.mbValueChanged = true;
    2709           0 :                             aRes.mbReferenceModified = true;
    2710           0 :                             break;
    2711             :                         }
    2712             :                     }
    2713             :                 }
    2714             : 
    2715           0 :                 if (rCxt.isInserted())
    2716             :                 {
    2717           0 :                     if (expandRange(rCxt, aAbs, aSelectedRange))
    2718             :                     {
    2719             :                         // The reference range has been expanded.
    2720           0 :                         rRef.SetRange(aAbs, aNewPos);
    2721           0 :                         aRes.mbValueChanged = true;
    2722           0 :                         aRes.mbReferenceModified = true;
    2723           0 :                         break;
    2724             :                     }
    2725             : 
    2726           0 :                     if (expandRangeByEdge(rCxt, aAbs, aSelectedRange))
    2727             :                     {
    2728             :                         // The reference range has been expanded on the edge.
    2729           0 :                         rRef.SetRange(aAbs, aNewPos);
    2730           0 :                         aRes.mbValueChanged = true;
    2731           0 :                         aRes.mbReferenceModified = true;
    2732           0 :                         break;
    2733             :                     }
    2734             :                 }
    2735             : 
    2736           0 :                 if (rCxt.maRange.In(aAbs))
    2737             :                 {
    2738           0 :                     aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
    2739           0 :                     aRes.mbReferenceModified = true;
    2740             :                 }
    2741           0 :                 else if (rCxt.maRange.Intersects(aAbs))
    2742             :                 {
    2743             :                     // Part of the referenced range is being shifted. This
    2744             :                     // will change the values of the range.
    2745           0 :                     aRes.mbValueChanged = true;
    2746             :                 }
    2747             : 
    2748           0 :                 rRef.SetRange(aAbs, aNewPos);
    2749             :             }
    2750           0 :             break;
    2751             :             case svExternalSingleRef:
    2752             :             {
    2753             :                 // For external reference, just reset the reference with
    2754             :                 // respect to the new cell position.
    2755           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2756           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    2757           0 :                 ScAddress aAbs = rRef.toAbs(rOldPos);
    2758           0 :                 rRef.SetAddress(aAbs, aNewPos);
    2759             :             }
    2760           0 :             break;
    2761             :             case svExternalDoubleRef:
    2762             :             {
    2763             :                 // Same as above.
    2764           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2765           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    2766           0 :                 ScRange aAbs = rRef.toAbs(rOldPos);
    2767           0 :                 rRef.SetRange(aAbs, aNewPos);
    2768             :             }
    2769           0 :             break;
    2770             :             case svIndex:
    2771             :             {
    2772           0 :                 if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **p))
    2773           0 :                     aRes.mbNameModified = true;
    2774             :             }
    2775           0 :             break;
    2776             :             default:
    2777             :                 ;
    2778             :         }
    2779             :     }
    2780             : 
    2781           0 :     return aRes;
    2782             : }
    2783             : 
    2784           0 : sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove(
    2785             :     const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos, const ScAddress& rNewPos )
    2786             : {
    2787             :     // When moving, the range is the destination range. We need to use the old
    2788             :     // range prior to the move for hit analysis.
    2789           0 :     ScRange aOldRange = rCxt.maRange;
    2790           0 :     aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
    2791             : 
    2792           0 :     sc::RefUpdateResult aRes;
    2793             : 
    2794           0 :     FormulaToken** p = pCode;
    2795           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    2796           0 :     for (; p != pEnd; ++p)
    2797             :     {
    2798           0 :         switch ((*p)->GetType())
    2799             :         {
    2800             :             case svSingleRef:
    2801             :             {
    2802           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2803           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    2804           0 :                 ScAddress aAbs = rRef.toAbs(rOldPos);
    2805           0 :                 if (aOldRange.In(aAbs))
    2806             :                 {
    2807           0 :                     aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
    2808           0 :                     aRes.mbReferenceModified = true;
    2809             :                 }
    2810             : 
    2811           0 :                 rRef.SetAddress(aAbs, rNewPos);
    2812             :             }
    2813           0 :             break;
    2814             :             case svDoubleRef:
    2815             :             {
    2816           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2817           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    2818           0 :                 ScRange aAbs = rRef.toAbs(rOldPos);
    2819           0 :                 if (aOldRange.In(aAbs))
    2820             :                 {
    2821           0 :                     aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
    2822           0 :                     aRes.mbReferenceModified = true;
    2823             :                 }
    2824             : 
    2825           0 :                 rRef.SetRange(aAbs, rNewPos);
    2826             :             }
    2827           0 :             break;
    2828             :             case svIndex:
    2829             :             {
    2830           0 :                 if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **p))
    2831           0 :                     aRes.mbNameModified = true;
    2832             :             }
    2833           0 :             break;
    2834             :             default:
    2835             :                 ;
    2836             :         }
    2837             :     }
    2838             : 
    2839           0 :     return aRes;
    2840             : }
    2841             : 
    2842           0 : void ScTokenArray::MoveReference(
    2843             :     const ScAddress& rPos, const ScRange& rMovedRange, const ScAddress& rDelta )
    2844             : {
    2845           0 :     FormulaToken** p = pCode;
    2846           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    2847           0 :     for (; p != pEnd; ++p)
    2848             :     {
    2849           0 :         switch ((*p)->GetType())
    2850             :         {
    2851             :             case svSingleRef:
    2852             :             {
    2853           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2854           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    2855           0 :                 ScAddress aAbs = rRef.toAbs(rPos);
    2856           0 :                 if (rMovedRange.In(aAbs))
    2857             :                 {
    2858           0 :                     aAbs.Move(rDelta.Col(), rDelta.Row(), rDelta.Tab());
    2859           0 :                     rRef.SetAddress(aAbs, rPos);
    2860             :                 }
    2861             :             }
    2862           0 :             break;
    2863             :             case svDoubleRef:
    2864             :             {
    2865           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2866           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    2867           0 :                 ScRange aAbs = rRef.toAbs(rPos);
    2868           0 :                 if (rMovedRange.In(aAbs))
    2869             :                 {
    2870           0 :                     aAbs.Move(rDelta.Col(), rDelta.Row(), rDelta.Tab());
    2871           0 :                     rRef.SetRange(aAbs, rPos);
    2872             :                 }
    2873             :             }
    2874           0 :             break;
    2875             :             default:
    2876             :                 ;
    2877             :         }
    2878             :     }
    2879           0 : }
    2880             : 
    2881             : namespace {
    2882             : 
    2883           0 : bool adjustSingleRefInName(
    2884             :     ScSingleRefData& rRef, const sc::RefUpdateContext& rCxt, const ScAddress& rPos )
    2885             : {
    2886           0 :     ScAddress aAbs = rRef.toAbs(rPos);
    2887             : 
    2888           0 :     if (aAbs.Tab() < rCxt.maRange.aStart.Tab() || rCxt.maRange.aEnd.Tab() < aAbs.Tab())
    2889             :     {
    2890             :         // This references a sheet that has not shifted. Don't change it.
    2891           0 :         return false;
    2892             :     }
    2893             : 
    2894           0 :     if (rRef.IsColRel() || rRef.IsRowRel())
    2895             :     {
    2896             :         // Adjust references only when both column and row are absolute.
    2897           0 :         return false;
    2898             :     }
    2899             : 
    2900           0 :     bool bChanged = false;
    2901             : 
    2902           0 :     if (rCxt.mnColDelta)
    2903             :     {
    2904             :         // Adjust absolute column reference.
    2905           0 :         if (rCxt.maRange.aStart.Col() <= rRef.Col() && rRef.Col() <= rCxt.maRange.aEnd.Col())
    2906             :         {
    2907           0 :             rRef.IncCol(rCxt.mnColDelta);
    2908           0 :             bChanged = true;
    2909             :         }
    2910             :     }
    2911             : 
    2912           0 :     if (rCxt.mnRowDelta)
    2913             :     {
    2914             :         // Adjust absolute row reference.
    2915           0 :         if (rCxt.maRange.aStart.Row() <= rRef.Row() && rRef.Row() <= rCxt.maRange.aEnd.Row())
    2916             :         {
    2917           0 :             rRef.IncRow(rCxt.mnRowDelta);
    2918           0 :             bChanged = true;
    2919             :         }
    2920             :     }
    2921             : 
    2922           0 :     if (!rRef.IsTabRel() && rCxt.mnTabDelta)
    2923             :     {
    2924             :         // Sheet range has already been checked above.
    2925           0 :         rRef.IncTab(rCxt.mnTabDelta);
    2926           0 :         bChanged = true;
    2927             :     }
    2928             : 
    2929           0 :     return bChanged;
    2930             : }
    2931             : 
    2932           0 : bool adjustDoubleRefInName(
    2933             :     ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt, const ScAddress& rPos )
    2934             : {
    2935           0 :     bool bRefChanged = false;
    2936           0 :     if (rCxt.mnRowDelta > 0 && rCxt.mrDoc.IsExpandRefs() && !rRef.Ref1.IsRowRel() && !rRef.Ref2.IsRowRel())
    2937             :     {
    2938             :         // Check and see if we should expand the range at the top.
    2939           0 :         ScRange aSelectedRange = getSelectedRange(rCxt);
    2940           0 :         ScRange aAbs = rRef.toAbs(rPos);
    2941           0 :         if (aSelectedRange.Intersects(aAbs))
    2942             :         {
    2943             :             // Selection intersects the referenced range. Only expand the
    2944             :             // bottom position.
    2945           0 :             rRef.Ref2.IncRow(rCxt.mnRowDelta);
    2946           0 :             return true;
    2947             :         }
    2948             :     }
    2949             : 
    2950           0 :     if (adjustSingleRefInName(rRef.Ref1, rCxt, rPos))
    2951           0 :         bRefChanged = true;
    2952             : 
    2953           0 :     if (adjustSingleRefInName(rRef.Ref2, rCxt, rPos))
    2954           0 :         bRefChanged = true;
    2955             : 
    2956           0 :     return bRefChanged;
    2957             : }
    2958             : 
    2959             : }
    2960             : 
    2961           0 : sc::RefUpdateResult ScTokenArray::AdjustReferenceInName(
    2962             :     const sc::RefUpdateContext& rCxt, const ScAddress& rPos )
    2963             : {
    2964           0 :     if (rCxt.meMode == URM_MOVE)
    2965           0 :         return AdjustReferenceInMovedName(rCxt, rPos);
    2966             : 
    2967           0 :     sc::RefUpdateResult aRes;
    2968             : 
    2969           0 :     FormulaToken** p = pCode;
    2970           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    2971           0 :     for (; p != pEnd; ++p)
    2972             :     {
    2973           0 :         switch ((*p)->GetType())
    2974             :         {
    2975             :             case svSingleRef:
    2976             :             {
    2977           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2978           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    2979           0 :                 if (adjustSingleRefInName(rRef, rCxt, rPos))
    2980           0 :                     aRes.mbReferenceModified = true;
    2981             :             }
    2982           0 :             break;
    2983             :             case svDoubleRef:
    2984             :             {
    2985           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    2986           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    2987           0 :                 ScRange aAbs = rRef.toAbs(rPos);
    2988           0 :                 if (rCxt.maRange.In(aAbs))
    2989             :                 {
    2990             :                     // This range is entirely within the shifted region.
    2991           0 :                     if (adjustDoubleRefInName(rRef, rCxt, rPos))
    2992           0 :                         aRes.mbReferenceModified = true;
    2993             :                 }
    2994           0 :                 else if (rCxt.maRange.Intersects(aAbs))
    2995             :                 {
    2996           0 :                     if (rCxt.mnColDelta && rCxt.maRange.aStart.Row() <= aAbs.aStart.Row() && aAbs.aEnd.Row() <= rCxt.maRange.aEnd.Row())
    2997             :                     {
    2998           0 :                         if (adjustDoubleRefInName(rRef, rCxt, rPos))
    2999           0 :                             aRes.mbReferenceModified = true;
    3000             :                     }
    3001           0 :                     if (rCxt.mnRowDelta && rCxt.maRange.aStart.Col() <= aAbs.aStart.Col() && aAbs.aEnd.Col() <= rCxt.maRange.aEnd.Col())
    3002             :                     {
    3003           0 :                         if (adjustDoubleRefInName(rRef, rCxt, rPos))
    3004           0 :                             aRes.mbReferenceModified = true;
    3005             :                     }
    3006             :                 }
    3007           0 :                 else if (rCxt.mnRowDelta > 0 && rCxt.mrDoc.IsExpandRefs())
    3008             :                 {
    3009             :                     // Check if we could expand range reference by the bottom
    3010             :                     // edge. For named expressions, we only expand absolute
    3011             :                     // references.
    3012           0 :                     if (!rRef.Ref1.IsRowRel() && !rRef.Ref2.IsRowRel() && aAbs.aEnd.Row()+1 == rCxt.maRange.aStart.Row())
    3013             :                     {
    3014             :                         // Expand by the bottom edge.
    3015           0 :                         rRef.Ref2.IncRow(rCxt.mnRowDelta);
    3016           0 :                         aRes.mbReferenceModified = true;
    3017             :                     }
    3018             :                 }
    3019             :             }
    3020           0 :             break;
    3021             :             default:
    3022             :                 ;
    3023             :         }
    3024             :     }
    3025             : 
    3026           0 :     return aRes;
    3027             : }
    3028             : 
    3029           0 : sc::RefUpdateResult ScTokenArray::AdjustReferenceInMovedName( const sc::RefUpdateContext& rCxt, const ScAddress& rPos )
    3030             : {
    3031             :     // When moving, the range is the destination range.
    3032           0 :     ScRange aOldRange = rCxt.maRange;
    3033           0 :     aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
    3034             : 
    3035             :     // In a named expression, we'll move the reference only when the reference
    3036             :     // is entirely absolute.
    3037             : 
    3038           0 :     sc::RefUpdateResult aRes;
    3039             : 
    3040             : 
    3041           0 :     FormulaToken** p = pCode;
    3042           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    3043           0 :     for (; p != pEnd; ++p)
    3044             :     {
    3045           0 :         switch ((*p)->GetType())
    3046             :         {
    3047             :             case svSingleRef:
    3048             :             {
    3049           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3050           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    3051           0 :                 if (rRef.IsColRel() || rRef.IsRowRel() || rRef.IsTabRel())
    3052           0 :                     continue;
    3053             : 
    3054           0 :                 ScAddress aAbs = rRef.toAbs(rPos);
    3055           0 :                 if (aOldRange.In(aAbs))
    3056             :                 {
    3057           0 :                     aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
    3058           0 :                     aRes.mbReferenceModified = true;
    3059             :                 }
    3060             : 
    3061           0 :                 rRef.SetAddress(aAbs, rPos);
    3062             :             }
    3063           0 :             break;
    3064             :             case svDoubleRef:
    3065             :             {
    3066           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3067           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    3068           0 :                 if (rRef.Ref1.IsColRel() || rRef.Ref1.IsRowRel() || rRef.Ref1.IsTabRel() ||
    3069           0 :                     rRef.Ref2.IsColRel() || rRef.Ref2.IsRowRel() || rRef.Ref2.IsTabRel())
    3070           0 :                     continue;
    3071             : 
    3072           0 :                 ScRange aAbs = rRef.toAbs(rPos);
    3073           0 :                 if (aOldRange.In(aAbs))
    3074             :                 {
    3075           0 :                     aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
    3076           0 :                     aRes.mbReferenceModified = true;
    3077             :                 }
    3078             : 
    3079           0 :                 rRef.SetRange(aAbs, rPos);
    3080             :             }
    3081           0 :             break;
    3082             :             default:
    3083             :                 ;
    3084             :         }
    3085             :     }
    3086             : 
    3087           0 :     return aRes;
    3088             : }
    3089             : 
    3090             : namespace {
    3091             : 
    3092           0 : bool adjustSingleRefOnDeletedTab( ScSingleRefData& rRef, SCTAB nDelPos, SCTAB nSheets, const ScAddress& rOldPos, const ScAddress& rNewPos )
    3093             : {
    3094           0 :     ScAddress aAbs = rRef.toAbs(rOldPos);
    3095           0 :     if (nDelPos <= aAbs.Tab() && aAbs.Tab() < nDelPos + nSheets)
    3096             :     {
    3097           0 :         rRef.SetTabDeleted(true);
    3098           0 :         return true;
    3099             :     }
    3100             : 
    3101           0 :     if (nDelPos < aAbs.Tab())
    3102             :     {
    3103             :         // Reference sheet needs to be adjusted.
    3104           0 :         aAbs.IncTab(-1*nSheets);
    3105           0 :         rRef.SetAddress(aAbs, rNewPos);
    3106           0 :         return true;
    3107             :     }
    3108           0 :     else if (rOldPos.Tab() != rNewPos.Tab())
    3109             :     {
    3110             :         // Cell itself has moved.
    3111           0 :         rRef.SetAddress(aAbs, rNewPos);
    3112           0 :         return true;
    3113             :     }
    3114             : 
    3115           0 :     return false;
    3116             : }
    3117             : 
    3118           0 : bool adjustSingleRefOnInsertedTab( ScSingleRefData& rRef, SCTAB nInsPos, SCTAB nSheets, const ScAddress& rOldPos, const ScAddress& rNewPos )
    3119             : {
    3120           0 :     ScAddress aAbs = rRef.toAbs(rOldPos);
    3121           0 :     if (nInsPos <= aAbs.Tab())
    3122             :     {
    3123             :         // Reference sheet needs to be adjusted.
    3124           0 :         aAbs.IncTab(nSheets);
    3125           0 :         rRef.SetAddress(aAbs, rNewPos);
    3126           0 :         return true;
    3127             :     }
    3128           0 :     else if (rOldPos.Tab() != rNewPos.Tab())
    3129             :     {
    3130             :         // Cell itself has moved.
    3131           0 :         rRef.SetAddress(aAbs, rNewPos);
    3132           0 :         return true;
    3133             :     }
    3134             : 
    3135           0 :     return false;
    3136             : }
    3137             : 
    3138             : }
    3139             : 
    3140           0 : sc::RefUpdateResult ScTokenArray::AdjustReferenceOnDeletedTab( sc::RefUpdateDeleteTabContext& rCxt, const ScAddress& rOldPos )
    3141             : {
    3142           0 :     sc::RefUpdateResult aRes;
    3143           0 :     ScAddress aNewPos = rOldPos;
    3144           0 :     if (rCxt.mnDeletePos < rOldPos.Tab())
    3145           0 :         aNewPos.IncTab(-1*rCxt.mnSheets);
    3146             : 
    3147           0 :     FormulaToken** p = pCode;
    3148           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    3149           0 :     for (; p != pEnd; ++p)
    3150             :     {
    3151           0 :         switch ((*p)->GetType())
    3152             :         {
    3153             :             case svSingleRef:
    3154             :             {
    3155           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3156           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    3157           0 :                 if (adjustSingleRefOnDeletedTab(rRef, rCxt.mnDeletePos, rCxt.mnSheets, rOldPos, aNewPos))
    3158           0 :                     aRes.mbReferenceModified = true;
    3159             :             }
    3160           0 :             break;
    3161             :             case svDoubleRef:
    3162             :             {
    3163           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3164           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    3165           0 :                 if (adjustSingleRefOnDeletedTab(rRef.Ref1, rCxt.mnDeletePos, rCxt.mnSheets, rOldPos, aNewPos))
    3166           0 :                     aRes.mbReferenceModified = true;
    3167           0 :                 if (adjustSingleRefOnDeletedTab(rRef.Ref2, rCxt.mnDeletePos, rCxt.mnSheets, rOldPos, aNewPos))
    3168           0 :                     aRes.mbReferenceModified = true;
    3169             :             }
    3170           0 :             break;
    3171             :             case svIndex:
    3172             :             {
    3173           0 :                 if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **p))
    3174           0 :                     aRes.mbNameModified = true;
    3175             :             }
    3176           0 :             break;
    3177             :             default:
    3178             :                 ;
    3179             :         }
    3180             :     }
    3181           0 :     return aRes;
    3182             : }
    3183             : 
    3184           0 : sc::RefUpdateResult ScTokenArray::AdjustReferenceOnInsertedTab( sc::RefUpdateInsertTabContext& rCxt, const ScAddress& rOldPos )
    3185             : {
    3186           0 :     sc::RefUpdateResult aRes;
    3187           0 :     ScAddress aNewPos = rOldPos;
    3188           0 :     if (rCxt.mnInsertPos <= rOldPos.Tab())
    3189           0 :         aNewPos.IncTab(rCxt.mnSheets);
    3190             : 
    3191           0 :     FormulaToken** p = pCode;
    3192           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    3193           0 :     for (; p != pEnd; ++p)
    3194             :     {
    3195           0 :         switch ((*p)->GetType())
    3196             :         {
    3197             :             case svSingleRef:
    3198             :             {
    3199           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3200           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    3201           0 :                 if (adjustSingleRefOnInsertedTab(rRef, rCxt.mnInsertPos, rCxt.mnSheets, rOldPos, aNewPos))
    3202           0 :                     aRes.mbReferenceModified = true;
    3203             :             }
    3204           0 :             break;
    3205             :             case svDoubleRef:
    3206             :             {
    3207           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3208           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    3209           0 :                 if (adjustSingleRefOnInsertedTab(rRef.Ref1, rCxt.mnInsertPos, rCxt.mnSheets, rOldPos, aNewPos))
    3210           0 :                     aRes.mbReferenceModified = true;
    3211           0 :                 if (adjustSingleRefOnInsertedTab(rRef.Ref2, rCxt.mnInsertPos, rCxt.mnSheets, rOldPos, aNewPos))
    3212           0 :                     aRes.mbReferenceModified = true;
    3213             :             }
    3214           0 :             break;
    3215             :             case svIndex:
    3216             :             {
    3217           0 :                 if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **p))
    3218           0 :                     aRes.mbNameModified = true;
    3219             :             }
    3220           0 :             break;
    3221             :             default:
    3222             :                 ;
    3223             :         }
    3224             :     }
    3225           0 :     return aRes;
    3226             : }
    3227             : 
    3228             : namespace {
    3229             : 
    3230           0 : bool adjustTabOnMove( ScAddress& rPos, sc::RefUpdateMoveTabContext& rCxt )
    3231             : {
    3232           0 :     SCTAB nNewTab = rCxt.getNewTab(rPos.Tab());
    3233           0 :     if (nNewTab == rPos.Tab())
    3234           0 :         return false;
    3235             : 
    3236           0 :     rPos.SetTab(nNewTab);
    3237           0 :     return true;
    3238             : }
    3239             : 
    3240             : }
    3241             : 
    3242           0 : sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMovedTab( sc::RefUpdateMoveTabContext& rCxt, const ScAddress& rOldPos )
    3243             : {
    3244           0 :     sc::RefUpdateResult aRes;
    3245           0 :     if (rCxt.mnOldPos == rCxt.mnNewPos)
    3246           0 :         return aRes;
    3247             : 
    3248           0 :     ScAddress aNewPos = rOldPos;
    3249           0 :     if (adjustTabOnMove(aNewPos, rCxt))
    3250           0 :         aRes.mbReferenceModified = true;
    3251             : 
    3252           0 :     FormulaToken** p = pCode;
    3253           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    3254           0 :     for (; p != pEnd; ++p)
    3255             :     {
    3256           0 :         switch ((*p)->GetType())
    3257             :         {
    3258             :             case svSingleRef:
    3259             :             {
    3260           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3261           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    3262           0 :                 ScAddress aAbs = rRef.toAbs(rOldPos);
    3263           0 :                 if (adjustTabOnMove(aAbs, rCxt))
    3264           0 :                     aRes.mbReferenceModified = true;
    3265           0 :                 rRef.SetAddress(aAbs, aNewPos);
    3266             :             }
    3267           0 :             break;
    3268             :             case svDoubleRef:
    3269             :             {
    3270           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3271           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    3272           0 :                 ScRange aAbs = rRef.toAbs(rOldPos);
    3273           0 :                 if (adjustTabOnMove(aAbs.aStart, rCxt))
    3274           0 :                     aRes.mbReferenceModified = true;
    3275           0 :                 if (adjustTabOnMove(aAbs.aEnd, rCxt))
    3276           0 :                     aRes.mbReferenceModified = true;
    3277           0 :                 rRef.SetRange(aAbs, aNewPos);
    3278             :             }
    3279           0 :             break;
    3280             :             case svIndex:
    3281             :             {
    3282           0 :                 if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **p))
    3283           0 :                     aRes.mbNameModified = true;
    3284             :             }
    3285           0 :             break;
    3286             :             default:
    3287             :                 ;
    3288             :         }
    3289             :     }
    3290             : 
    3291           0 :     return aRes;
    3292             : }
    3293             : 
    3294             : namespace {
    3295             : 
    3296           0 : void clearTabDeletedFlag( ScSingleRefData& rRef, const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab )
    3297             : {
    3298           0 :     if (!rRef.IsTabDeleted())
    3299           0 :         return;
    3300             : 
    3301           0 :     ScAddress aAbs = rRef.toAbs(rPos);
    3302           0 :     if (nStartTab <=  aAbs.Tab() && aAbs.Tab() <= nEndTab)
    3303           0 :         rRef.SetTabDeleted(false);
    3304             : }
    3305             : 
    3306             : }
    3307             : 
    3308           0 : void ScTokenArray::ClearTabDeleted( const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab )
    3309             : {
    3310           0 :     if (nEndTab < nStartTab)
    3311           0 :         return;
    3312             : 
    3313           0 :     FormulaToken** p = pCode;
    3314           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    3315           0 :     for (; p != pEnd; ++p)
    3316             :     {
    3317           0 :         switch ((*p)->GetType())
    3318             :         {
    3319             :             case svSingleRef:
    3320             :             {
    3321           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3322           0 :                 ScSingleRefData& rRef = pToken->GetSingleRef();
    3323           0 :                 clearTabDeletedFlag(rRef, rPos, nStartTab, nEndTab);
    3324             :             }
    3325           0 :             break;
    3326             :             case svDoubleRef:
    3327             :             {
    3328           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3329           0 :                 ScComplexRefData& rRef = pToken->GetDoubleRef();
    3330           0 :                 clearTabDeletedFlag(rRef.Ref1, rPos, nStartTab, nEndTab);
    3331           0 :                 clearTabDeletedFlag(rRef.Ref2, rPos, nStartTab, nEndTab);
    3332             :             }
    3333           0 :             break;
    3334             :             default:
    3335             :                 ;
    3336             :         }
    3337             :     }
    3338             : }
    3339             : 
    3340             : namespace {
    3341             : 
    3342           0 : void checkBounds(
    3343             :     const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen,
    3344             :     const ScSingleRefData& rRef, std::vector<SCROW>& rBounds)
    3345             : {
    3346           0 :     if (!rRef.IsRowRel())
    3347           0 :         return;
    3348             : 
    3349           0 :     ScRange aCheckRange = rCxt.maRange;
    3350           0 :     if (rCxt.meMode == URM_MOVE)
    3351             :         // Check bounds against the old range prior to the move.
    3352           0 :         aCheckRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
    3353             : 
    3354           0 :     ScRange aAbs(rRef.toAbs(rPos));
    3355           0 :     aAbs.aEnd.IncRow(nGroupLen-1);
    3356           0 :     if (!aCheckRange.Intersects(aAbs))
    3357           0 :         return;
    3358             : 
    3359             :     // Get the boundary row positions.
    3360           0 :     if (aAbs.aEnd.Row() < aCheckRange.aStart.Row())
    3361             :         // No intersections.
    3362           0 :         return;
    3363             : 
    3364           0 :     if (aAbs.aStart.Row() <= aCheckRange.aStart.Row())
    3365             :     {
    3366             :         //    +-+ <---- top
    3367             :         //    | |
    3368             :         // +--+-+--+ <---- boundary row position
    3369             :         // |  | |  |
    3370             :         // |       |
    3371             :         // +-------+
    3372             : 
    3373             :         // Add offset from the reference top to the cell position.
    3374           0 :         SCROW nOffset = aCheckRange.aStart.Row() - aAbs.aStart.Row();
    3375           0 :         rBounds.push_back(rPos.Row()+nOffset);
    3376             :     }
    3377             : 
    3378           0 :     if (aAbs.aEnd.Row() >= aCheckRange.aEnd.Row())
    3379             :     {
    3380             :         // only check for end range
    3381             : 
    3382             :         // +-------+
    3383             :         // |       |
    3384             :         // |  | |  |
    3385             :         // +--+-+--+ <---- boundary row position
    3386             :         //    | |
    3387             :         //    +-+
    3388             : 
    3389             :         // Ditto.
    3390           0 :         SCROW nOffset = aCheckRange.aEnd.Row() + 1 - aAbs.aStart.Row();
    3391           0 :         rBounds.push_back(rPos.Row()+nOffset);
    3392             :     }
    3393             : }
    3394             : 
    3395             : }
    3396             : 
    3397           0 : void ScTokenArray::CheckRelativeReferenceBounds(
    3398             :     const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const
    3399             : {
    3400           0 :     FormulaToken** p = pCode;
    3401           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    3402           0 :     for (; p != pEnd; ++p)
    3403             :     {
    3404           0 :         switch ((*p)->GetType())
    3405             :         {
    3406             :             case svSingleRef:
    3407             :             {
    3408           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3409           0 :                 checkBounds(rCxt, rPos, nGroupLen, pToken->GetSingleRef(), rBounds);
    3410             :             }
    3411           0 :             break;
    3412             :             case svDoubleRef:
    3413             :             {
    3414           0 :                 ScToken* pToken = static_cast<ScToken*>(*p);
    3415           0 :                 const ScComplexRefData& rRef = pToken->GetDoubleRef();
    3416           0 :                 checkBounds(rCxt, rPos, nGroupLen, rRef.Ref1, rBounds);
    3417           0 :                 checkBounds(rCxt, rPos, nGroupLen, rRef.Ref2, rBounds);
    3418             :             }
    3419           0 :             break;
    3420             :             default:
    3421             :                 ;
    3422             :         }
    3423             :     }
    3424           0 : }
    3425             : 
    3426             : namespace {
    3427             : 
    3428           0 : void appendDouble( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, double fVal )
    3429             : {
    3430           0 :     if (rCxt.mxOpCodeMap->isEnglish())
    3431             :     {
    3432             :         rtl::math::doubleToUStringBuffer(
    3433           0 :             rBuf, fVal, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
    3434             :     }
    3435             :     else
    3436             :     {
    3437           0 :         SvtSysLocale aSysLocale;
    3438             :         rtl::math::doubleToUStringBuffer(
    3439             :             rBuf, fVal,
    3440             :             rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
    3441           0 :             aSysLocale.GetLocaleDataPtr()->getNumDecimalSep()[0], true);
    3442             :     }
    3443           0 : }
    3444             : 
    3445           0 : void appendString( OUStringBuffer& rBuf, const OUString& rStr )
    3446             : {
    3447           0 :     rBuf.append('"');
    3448           0 :     rBuf.append(rStr.replaceAll("\"", "\"\""));
    3449           0 :     rBuf.append('"');
    3450           0 : }
    3451             : 
    3452           0 : void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, const FormulaToken& rToken, const ScAddress& rPos )
    3453             : {
    3454           0 :     if (rToken.IsExternalRef())
    3455             :     {
    3456           0 :         size_t nFileId = rToken.GetIndex();
    3457           0 :         OUString aTabName = rToken.GetString().getString();
    3458           0 :         if (nFileId >= rCxt.maExternalFileNames.size())
    3459             :             // out of bound
    3460           0 :             return;
    3461             : 
    3462           0 :         OUString aFileName = rCxt.maExternalFileNames[nFileId];
    3463             : 
    3464           0 :         switch (rToken.GetType())
    3465             :         {
    3466             :             case svExternalName:
    3467           0 :                 rBuf.append(rCxt.mpRefConv->makeExternalNameStr(aFileName, aTabName));
    3468           0 :             break;
    3469             :             case svExternalSingleRef:
    3470             :                 rCxt.mpRefConv->makeExternalRefStr(
    3471           0 :                        rBuf, rPos, aFileName, aTabName, static_cast<const ScToken&>(rToken).GetSingleRef());
    3472           0 :             break;
    3473             :             case svExternalDoubleRef:
    3474             :             {
    3475             :                 sc::TokenStringContext::IndexNamesMapType::const_iterator it =
    3476           0 :                     rCxt.maExternalCachedTabNames.find(nFileId);
    3477             : 
    3478           0 :                 if (it == rCxt.maExternalCachedTabNames.end())
    3479           0 :                     return;
    3480             : 
    3481             :                 rCxt.mpRefConv->makeExternalRefStr(
    3482           0 :                     rBuf, rPos, aFileName, it->second, aTabName, static_cast<const ScToken&>(rToken).GetDoubleRef());
    3483             :             }
    3484           0 :             break;
    3485             :             default:
    3486             :                 // warning, not error, otherwise we may end up with a never
    3487             :                 // ending message box loop if this was the cursor cell to be redrawn.
    3488             :                 OSL_FAIL("appendTokenByType: unknown type of ocExternalRef");
    3489             :         }
    3490           0 :         return;
    3491             :     }
    3492             : 
    3493           0 :     OpCode eOp = rToken.GetOpCode();
    3494           0 :     switch (rToken.GetType())
    3495             :     {
    3496             :         case svDouble:
    3497           0 :             appendDouble(rCxt, rBuf, rToken.GetDouble());
    3498           0 :         break;
    3499             :         case svString:
    3500             :         {
    3501           0 :             OUString aStr = rToken.GetString().getString();
    3502           0 :             if (eOp == ocBad || eOp == ocStringXML)
    3503             :             {
    3504           0 :                 rBuf.append(aStr);
    3505           0 :                 return;
    3506             :             }
    3507             : 
    3508           0 :             appendString(rBuf, aStr);
    3509             :         }
    3510           0 :         break;
    3511             :         case svSingleRef:
    3512             :         {
    3513           0 :             if (rCxt.mpRefConv)
    3514             :             {
    3515           0 :                 const ScSingleRefData& rRef = static_cast<const ScToken&>(rToken).GetSingleRef();
    3516             :                 ScComplexRefData aRef;
    3517           0 :                 aRef.Ref1 = rRef;
    3518           0 :                 aRef.Ref2 = rRef;
    3519           0 :                 rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, aRef, true);
    3520             :             }
    3521             :             else
    3522           0 :                 rBuf.append(rCxt.maErrRef);
    3523             :         }
    3524           0 :         break;
    3525             :         case svDoubleRef:
    3526             :         {
    3527           0 :             if (rCxt.mpRefConv)
    3528             :             {
    3529           0 :                 const ScComplexRefData& rRef = static_cast<const ScToken&>(rToken).GetDoubleRef();
    3530           0 :                 rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, rRef, false);
    3531             :             }
    3532             :             else
    3533           0 :                 rBuf.append(rCxt.maErrRef);
    3534             :         }
    3535           0 :         break;
    3536             :         case svMatrix:
    3537             :         {
    3538           0 :             const ScMatrix* pMat = static_cast<const ScToken&>(rToken).GetMatrix();
    3539           0 :             if (!pMat)
    3540           0 :                 return;
    3541             : 
    3542             :             size_t nC, nMaxC, nR, nMaxR;
    3543           0 :             pMat->GetDimensions(nMaxC, nMaxR);
    3544             : 
    3545           0 :             rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayOpen));
    3546           0 :             for (nR = 0 ; nR < nMaxR ; ++nR)
    3547             :             {
    3548           0 :                 if (nR > 0)
    3549             :                 {
    3550           0 :                     rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayRowSep));
    3551             :                 }
    3552             : 
    3553           0 :                 for (nC = 0 ; nC < nMaxC ; ++nC)
    3554             :                 {
    3555           0 :                     if (nC > 0)
    3556             :                     {
    3557           0 :                         rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayColSep));
    3558             :                     }
    3559             : 
    3560           0 :                     if (pMat->IsValue(nC, nR))
    3561             :                     {
    3562           0 :                         if (pMat->IsBoolean(nC, nR))
    3563             :                         {
    3564           0 :                             bool bVal = pMat->GetDouble(nC, nR) != 0.0;
    3565           0 :                             rBuf.append(rCxt.mxOpCodeMap->getSymbol(bVal ? ocTrue : ocFalse));
    3566             :                         }
    3567             :                         else
    3568             :                         {
    3569           0 :                             sal_uInt16 nErr = pMat->GetError(nC, nR);
    3570           0 :                             if (nErr)
    3571           0 :                                 rBuf.append(ScGlobal::GetErrorString(nErr));
    3572             :                             else
    3573           0 :                                 appendDouble(rCxt, rBuf, pMat->GetDouble(nC, nR));
    3574             :                         }
    3575             :                     }
    3576           0 :                     else if (pMat->IsEmpty(nC, nR))
    3577             :                     {
    3578             :                         // Skip it.
    3579             :                     }
    3580           0 :                     else if (pMat->IsString(nC, nR))
    3581           0 :                         appendString(rBuf, pMat->GetString(nC, nR).getString());
    3582             :                 }
    3583             :             }
    3584           0 :             rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayClose));
    3585             :         }
    3586           0 :         break;
    3587             :         case svIndex:
    3588             :         {
    3589             :             typedef sc::TokenStringContext::IndexNameMapType NameType;
    3590             : 
    3591           0 :             sal_uInt16 nIndex = rToken.GetIndex();
    3592           0 :             switch (eOp)
    3593             :             {
    3594             :                 case ocName:
    3595             :                 {
    3596           0 :                     if (rToken.IsGlobal())
    3597             :                     {
    3598             :                         // global named range
    3599           0 :                         NameType::const_iterator it = rCxt.maGlobalRangeNames.find(nIndex);
    3600           0 :                         if (it == rCxt.maGlobalRangeNames.end())
    3601             :                         {
    3602           0 :                             rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
    3603           0 :                             break;
    3604             :                         }
    3605             : 
    3606           0 :                         rBuf.append(it->second);
    3607             :                     }
    3608             :                     else
    3609             :                     {
    3610             :                         // sheet-local named range
    3611           0 :                         sc::TokenStringContext::TabIndexMapType::const_iterator itTab = rCxt.maSheetRangeNames.find(rPos.Tab());
    3612           0 :                         if (itTab == rCxt.maSheetRangeNames.end())
    3613             :                         {
    3614           0 :                             rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
    3615           0 :                             break;
    3616             :                         }
    3617             : 
    3618           0 :                         const NameType& rNames = itTab->second;
    3619           0 :                         NameType::const_iterator it = rNames.find(nIndex);
    3620           0 :                         if (it == rNames.end())
    3621             :                         {
    3622           0 :                             rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
    3623           0 :                             break;
    3624             :                         }
    3625             : 
    3626           0 :                         rBuf.append(it->second);
    3627             :                     }
    3628             :                 }
    3629           0 :                 break;
    3630             :                 case ocDBArea:
    3631             :                 {
    3632           0 :                     NameType::const_iterator it = rCxt.maNamedDBs.find(nIndex);
    3633           0 :                     if (it != rCxt.maNamedDBs.end())
    3634           0 :                         rBuf.append(it->second);
    3635             :                 }
    3636           0 :                 break;
    3637             :                 default:
    3638           0 :                     rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
    3639             :             }
    3640             :         }
    3641           0 :         break;
    3642             :         case svExternal:
    3643             :         {
    3644             :             // mapped or translated name of AddIns
    3645           0 :             OUString aAddIn = rToken.GetExternal();
    3646           0 :             bool bMapped = rCxt.mxOpCodeMap->isPODF();     // ODF 1.1 directly uses programmatical name
    3647           0 :             if (!bMapped && rCxt.mxOpCodeMap->hasExternals())
    3648             :             {
    3649           0 :                 const ExternalHashMap& rExtMap = *rCxt.mxOpCodeMap->getReverseExternalHashMap();
    3650           0 :                 ExternalHashMap::const_iterator it = rExtMap.find(aAddIn);
    3651           0 :                 if (it != rExtMap.end())
    3652             :                 {
    3653           0 :                     aAddIn = it->second;
    3654           0 :                     bMapped = true;
    3655             :                 }
    3656             :             }
    3657             : 
    3658           0 :             if (!bMapped && !rCxt.mxOpCodeMap->isEnglish())
    3659           0 :                 ScGlobal::GetAddInCollection()->LocalizeString(aAddIn);
    3660             : 
    3661           0 :             rBuf.append(aAddIn);
    3662             :         }
    3663           0 :         break;
    3664             :         case svError:
    3665             :         {
    3666           0 :             sal_uInt16 nErr = rToken.GetError();
    3667             :             OpCode eOpErr;
    3668           0 :             switch (nErr)
    3669             :             {
    3670             :                 break;
    3671             :                 case errDivisionByZero:
    3672           0 :                     eOpErr = ocErrDivZero;
    3673           0 :                 break;
    3674             :                 case errNoValue:
    3675           0 :                     eOpErr = ocErrValue;
    3676           0 :                 break;
    3677             :                 case errNoRef:
    3678           0 :                     eOpErr = ocErrRef;
    3679           0 :                 break;
    3680             :                 case errNoName:
    3681           0 :                     eOpErr = ocErrName;
    3682           0 :                 break;
    3683             :                 case errIllegalFPOperation:
    3684           0 :                     eOpErr = ocErrNum;
    3685           0 :                 break;
    3686             :                 case NOTAVAILABLE:
    3687           0 :                     eOpErr = ocErrNA;
    3688           0 :                 break;
    3689             :                 case errNoCode:
    3690             :                 default:
    3691           0 :                     eOpErr = ocErrNull;
    3692             :             }
    3693           0 :             rBuf.append(rCxt.mxOpCodeMap->getSymbol(eOpErr));
    3694             :         }
    3695           0 :         break;
    3696             :         case svByte:
    3697             :         case svJump:
    3698             :         case svFAP:
    3699             :         case svMissing:
    3700             :         case svSep:
    3701             :         default:
    3702             :             ;
    3703             :     }
    3704             : }
    3705             : 
    3706             : }
    3707             : 
    3708           0 : OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const
    3709             : {
    3710           0 :     if (!nLen)
    3711           0 :         return OUString();
    3712             : 
    3713           0 :     OUStringBuffer aBuf;
    3714             : 
    3715           0 :     FormulaToken** p = pCode;
    3716           0 :     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
    3717           0 :     for (; p != pEnd; ++p)
    3718             :     {
    3719           0 :         const FormulaToken* pToken = *p;
    3720           0 :         OpCode eOp = pToken->GetOpCode();
    3721           0 :         bool bCheckType = true;
    3722           0 :         if (eOp == ocSpaces)
    3723             :         {
    3724             :             // TODO : Handle intersection operator '!!'.
    3725           0 :             aBuf.append(' ');
    3726           0 :             continue;
    3727             :         }
    3728             : 
    3729           0 :         if (eOp < rCxt.mxOpCodeMap->getSymbolCount())
    3730           0 :             aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp));
    3731             : 
    3732           0 :         if (bCheckType)
    3733           0 :             appendTokenByType(rCxt, aBuf, *pToken, rPos);
    3734             :     }
    3735             : 
    3736           0 :     return aBuf.makeStringAndClear();
    3737           0 : }
    3738             : 
    3739             : #if DEBUG_FORMULA_COMPILER
    3740             : void ScTokenArray::Dump() const
    3741             : {
    3742             :     for (sal_uInt16 i = 0; i < nLen; ++i)
    3743             :     {
    3744             :         const ScToken* p = dynamic_cast<const ScToken*>(pCode[i]);
    3745             :         if (!p)
    3746             :         {
    3747             :             cout << "-- (non ScToken)" << endl;
    3748             :             continue;
    3749             :         }
    3750             : 
    3751             :         p->Dump();
    3752             :     }
    3753             : }
    3754             : #endif
    3755             : 
    3756             : 
    3757             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10