[ooo-build-commit] .: patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Oct 5 15:18:11 PDT 2010


 patches/dev300/apply                                       |    4 
 patches/dev300/calc-extref-interpreter-rework-formula.diff |   95 
 patches/dev300/calc-extref-interpreter-rework-sc.diff      | 1785 -------------
 3 files changed, 1884 deletions(-)

New commits:
commit 5a2a190f58f95a23a14a4db04abdfbb7195de1a7
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Tue Oct 5 18:17:49 2010 -0400

    Removed calc-extref-interpreter-rework-*.diff; moved to git.

diff --git a/patches/dev300/apply b/patches/dev300/apply
index bbeae44..4d2ed40 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -2656,10 +2656,6 @@ calc-formula-db-function-fix.diff, n#594332, n#595713, kohei
 # Opening an xml file with xls extension
 sc-xml-with-xls-ext.diff, n#527738, muthusuba
 
-# Treat external reference tokens with ocPush & dump ocExternalRef opcode.
-calc-extref-interpreter-rework-formula.diff, n#628876, kohei
-calc-extref-interpreter-rework-sc.diff,      n#628876, kohei
-
 [ GentooExperimental ]
 SectionOwner => hmth
 # make Python2 optional
diff --git a/patches/dev300/calc-extref-interpreter-rework-formula.diff b/patches/dev300/calc-extref-interpreter-rework-formula.diff
deleted file mode 100644
index 67b1745..0000000
--- a/patches/dev300/calc-extref-interpreter-rework-formula.diff
+++ /dev/null
@@ -1,95 +0,0 @@
-diff --git formula/inc/formula/token.hxx formula/inc/formula/token.hxx
-index be1b2f6..8b4f53a 100644
---- formula/inc/formula/token.hxx
-+++ formula/inc/formula/token.hxx
-@@ -113,6 +113,7 @@ public:
-     inline  StackVar      		GetType() const         { return eType; }
-             BOOL                IsFunction() const; // pure functions, no operators
-             BOOL                IsMatrixFunction() const;   // if a function _always_ returns a Matrix
-+            bool                IsExternalRef() const;
-             BYTE                GetParamCount() const;
-     inline  void                IncRef() const          { nRefCnt++; }
-     inline  void                DecRef() const
-diff --git formula/inc/formula/tokenarray.hxx formula/inc/formula/tokenarray.hxx
-index 042dbb9..5bbfaf4 100644
---- formula/inc/formula/tokenarray.hxx
-+++ formula/inc/formula/tokenarray.hxx
-@@ -126,6 +126,7 @@ public:
-     FormulaToken* LastRPN() { nIndex = nRPN; return PrevRPN(); }
-     FormulaToken* PrevRPN();
- 
-+    bool    HasExternalRef() const;
-     BOOL    HasOpCode( OpCode ) const;
-     BOOL    HasOpCodeRPN( OpCode ) const;
-     /// Token of type svIndex or opcode ocColRowName
-diff --git formula/source/core/api/FormulaCompiler.cxx formula/source/core/api/FormulaCompiler.cxx
-index 7e26cde..7395044 100644
---- formula/source/core/api/FormulaCompiler.cxx
-+++ formula/source/core/api/FormulaCompiler.cxx
-@@ -905,7 +905,7 @@ BOOL FormulaCompiler::GetToken()
-     }
-     if( pToken->GetOpCode() == ocSubTotal )
-         glSubTotal = TRUE;
--    else if ( pToken->GetOpCode() == ocExternalRef )
-+    else if ( pToken->IsExternalRef() )
-     {
-         return HandleExternalReference(*pToken);
-     }
-@@ -1187,7 +1187,7 @@ void FormulaCompiler::Factor()
-                 bCorrected = TRUE;
-             }
-         }
--        else if ( eOp == ocExternalRef )
-+        else if ( pToken->IsExternalRef() )
-         {
-             PutCode(pToken);
-             eOp = NextToken();
-@@ -1607,7 +1607,7 @@ FormulaToken* FormulaCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuff
-     }
-     if( bNext ) 
-     {
--        if (eOp == ocExternalRef)
-+        if (t->IsExternalRef())
-         {
-             CreateStringFromExternal(rBuffer, pTokenP);
-         }
-diff --git formula/source/core/api/token.cxx formula/source/core/api/token.cxx
-index ccc7406..028197c 100644
---- formula/source/core/api/token.cxx
-+++ formula/source/core/api/token.cxx
-@@ -145,6 +145,18 @@ BOOL FormulaToken::IsMatrixFunction() const
-     return formula::FormulaCompiler::IsMatrixFunction(GetOpCode());
- }
- 
-+bool FormulaToken::IsExternalRef() const
-+{
-+    switch (eType)
-+    {
-+        case svExternalSingleRef:
-+        case svExternalDoubleRef:
-+        case svExternalName:
-+            return true;
-+    }
-+    return false;
-+}
-+
- BOOL FormulaToken::operator==( const FormulaToken& rToken ) const
- {
-     // don't compare reference count!
-@@ -550,6 +562,16 @@ FormulaToken* FormulaTokenArray::PeekPrevNoSpaces()
-         return NULL;
- }
- 
-+bool FormulaTokenArray::HasExternalRef() const
-+{
-+    for ( USHORT j=0; j < nLen; j++ )
-+    {
-+        if (pCode[j]->IsExternalRef())
-+            return true;
-+    }
-+    return false;
-+}
-+
- BOOL FormulaTokenArray::HasOpCode( OpCode eOp ) const
- {
-     for ( USHORT j=0; j < nLen; j++ )
diff --git a/patches/dev300/calc-extref-interpreter-rework-sc.diff b/patches/dev300/calc-extref-interpreter-rework-sc.diff
deleted file mode 100644
index 1376ff3..0000000
--- a/patches/dev300/calc-extref-interpreter-rework-sc.diff
+++ /dev/null
@@ -1,1785 +0,0 @@
-diff --git sc/inc/document.hxx sc/inc/document.hxx
-index f5a285d..2b5dc0f 100644
---- sc/inc/document.hxx
-+++ sc/inc/document.hxx
-@@ -501,7 +501,7 @@ public:
-     ScFieldEditEngine*	CreateFieldEditEngine();
-     void				DisposeFieldEditEngine(ScFieldEditEngine*& rpEditEngine);
- 
--    SC_DLLPUBLIC ScRangeName*	GetRangeName();
-+    SC_DLLPUBLIC ScRangeName*	GetRangeName() const;
-     void			SetRangeName( ScRangeName* pNewRangeName );
-     SCTAB			GetMaxTableNumber() { return nMaxTableNumber; }
-     void			SetMaxTableNumber(SCTAB nNumber) { nMaxTableNumber = nNumber; }
-@@ -804,7 +804,7 @@ public:
-     SC_DLLPUBLIC void			GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, double& rValue );
-     SC_DLLPUBLIC double			RoundValueAsShown( double fVal, ULONG nFormat );
-     SC_DLLPUBLIC void			GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
--                                     sal_uInt32& rFormat );
-+                                     sal_uInt32& rFormat ) const;
-     sal_uInt32      GetNumberFormat( const ScRange& rRange ) const;
-     SC_DLLPUBLIC sal_uInt32		GetNumberFormat( const ScAddress& ) const;
-                     /** If no number format attribute is set and the cell
-diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
-index 49627f2..44e9e68 100644
---- sc/inc/externalrefmgr.hxx
-+++ sc/inc/externalrefmgr.hxx
-@@ -684,7 +684,47 @@ private:
- 
-     void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
- 
--    ScDocument* getSrcDocument(sal_uInt16 nFileId);
-+    void fillCellFormat(sal_uInt32 nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const;
-+
-+    ScExternalRefCache::TokenRef getSingleRefTokenFromSrcDoc(
-+        sal_uInt16 nFileId, const ScDocument* pSrcDoc, const ScAddress& rCell, 
-+        ScExternalRefCache::CellFormat* pFmt);
-+
-+    /**
-+     * Retrieve a range token array from a source document instance. 
-+     * 
-+     * @param pSrcDoc pointer to the source document instance.
-+     * @param rTabName name of the first table.
-+     * @param rRange range specified.  Upon successful retrieval, this range 
-+     *               gets modified to contain the correct table IDs, and in
-+     *               case the range is larger than the data area of the source
-+     *               document, it gets reduced to the data area.
-+     * @param rCacheData an array of structs, with each struct containing the 
-+     *                   table name and the data in the specified range.
-+     * 
-+     * @return range token array
-+     */
-+    ScExternalRefCache::TokenArrayRef getDoubleRefTokensFromSrcDoc(
-+        const ScDocument* pSrcDoc, const String& rTabName, ScRange& rRange,
-+        ::std::vector<ScExternalRefCache::SingleRangeData>& rCacheData);
-+
-+    /**
-+     * Retrieve range name token array from a source document instance.
-+     * 
-+     * @param nFileId file ID of the source document.
-+     * @param pSrcDoc pointer to the source document instance
-+     * @param rName range name to retrieve.  Note that the range name lookup 
-+     *              is case <i>in</i>-sensitive, and upon successful retrieval
-+     *              of the range name array, this name gets updated to the
-+     *              actual range name with the correct casing.
-+     * 
-+     * @return range name token array
-+     */
-+    ScExternalRefCache::TokenArrayRef getRangeNameTokensFromSrcDoc(
-+        sal_uInt16 nFileId, const ScDocument* pSrcDoc, String& rName);
-+    
-+    const ScDocument* getInMemorySrcDocument(sal_uInt16 nFileId);
-+    const ScDocument* getSrcDocument(sal_uInt16 nFileId);
-     SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, String& rFilter);
-     bool isFileLoadable(const String& rFile) const;
- 
-@@ -711,7 +751,7 @@ private:
-      */
-     void purgeStaleSrcDocument(sal_Int32 nTimeOut);
- 
--    sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, ScDocument* pSrcDoc);
-+    sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc);
- 
- private:
-     /** cache of referenced ranges and names from source documents. */
-diff --git sc/source/core/data/cell.cxx sc/source/core/data/cell.cxx
-index cf9f40a..8104d0a 100644
---- sc/source/core/data/cell.cxx
-+++ sc/source/core/data/cell.cxx
-@@ -774,7 +774,7 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
-         ScToken* t;
-         while ( ( t = static_cast<ScToken*>(pCode->GetNextReferenceOrName()) ) != NULL && !bCompile )
-         {
--            if ( t->GetOpCode() == ocExternalRef )
-+            if ( t->IsExternalRef() )
-             {
-                 // External name, cell, and area references.
-                 bCompile = true;
-diff --git sc/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
-index 27ed1f8..213b28d 100644
---- sc/source/core/data/documen3.cxx
-+++ sc/source/core/data/documen3.cxx
-@@ -93,7 +93,7 @@ using ::std::auto_ptr;
- 
- //------------------------------------------------------------------------
- 
--ScRangeName* ScDocument::GetRangeName()
-+ScRangeName* ScDocument::GetRangeName() const
- {
-     return pRangeName;
- }
-diff --git sc/source/core/data/documen4.cxx sc/source/core/data/documen4.cxx
-index cbd55fd..48f3e2b 100644
---- sc/source/core/data/documen4.cxx
-+++ sc/source/core/data/documen4.cxx
-@@ -305,7 +305,7 @@ bool ScDocument::MarkUsedExternalReferences( ScTokenArray & rArr )
-         ScToken* t;
-         while (!bAllMarked && (t = static_cast<ScToken*>(rArr.GetNextReferenceOrName())) != NULL)
-         {
--            if (t->GetOpCode() == ocExternalRef)
-+            if (t->IsExternalRef())
-             {
-                 if (!pRefMgr)
-                     pRefMgr = GetExternalRefManager();
-diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
-index c32cf41..ea615c5 100644
---- sc/source/core/data/document.cxx
-+++ sc/source/core/data/document.cxx
-@@ -2722,7 +2722,7 @@ double ScDocument::GetValue( const ScAddress& rPos )
- 
- 
- void ScDocument::GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
--                                  sal_uInt32& rFormat )
-+                                  sal_uInt32& rFormat ) const
- {
-     if (VALIDTAB(nTab))
-         if (pTab[nTab])
-diff --git sc/source/core/inc/interpre.hxx sc/source/core/inc/interpre.hxx
-index b28bfc1..65dc19d 100644
---- sc/source/core/inc/interpre.hxx
-+++ sc/source/core/inc/interpre.hxx
-@@ -35,6 +35,7 @@
- #include "scdll.hxx"
- #include "document.hxx"
- #include "scmatrix.hxx"
-+#include "externalrefmgr.hxx"
- 
- #include <math.h>
- #include <map>
-@@ -305,10 +306,15 @@ void DoubleRefToVars( const ScToken* p,
-         SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
-         SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
-         BOOL bDontCheckForTableOp = FALSE );
--ScDBRangeBase* PopDoubleRef();
-+ScDBRangeBase* PopDBDoubleRef();
- void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
-                           SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
-                           BOOL bDontCheckForTableOp = FALSE );
-+void PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName, ScSingleRefData& rRef);
-+void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL);
-+void PopExternalDoubleRef(sal_uInt16& rFileId, String& rTabName, ScComplexRefData& rRef);
-+void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
-+void PopExternalDoubleRef(ScMatrixRef& rMat);
- BOOL PopDoubleRefOrSingleRef( ScAddress& rAdr );
- void PopDoubleRefPushMatrix();
- // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
-@@ -326,7 +332,12 @@ void PushStringBuffer( const sal_Unicode* pString );
- void PushString( const String& rString );
- void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab);
- void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
--                                 SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
-+                   SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
-+void PushExternalSingleRef(sal_uInt16 nFileId, const String& rTabName, 
-+                           SCCOL nCol, SCROW nRow, SCTAB nTab);
-+void PushExternalDoubleRef(sal_uInt16 nFileId, const String& rTabName, 
-+                           SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 
-+                           SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
- void PushMatrix(ScMatrix* pMat);
- void PushError( USHORT nError );
- /// Raw stack type without default replacements.
-@@ -338,11 +349,13 @@ formula::StackVar GetStackType( BYTE nParam );
- BYTE GetByte() { return cPar; }
- // generiert aus DoubleRef positionsabhaengige SingleRef
- BOOL DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr );
-+double GetDoubleFromMatrix(const ScMatrixRef& pMat);
- double GetDouble();
- double GetDoubleWithDefault(double nDefault);
- BOOL IsMissing();
- BOOL GetBool() { return GetDouble() != 0.0; }
- const String& GetString();
-+const String& GetStringFromMatrix(const ScMatrixRef& pMat);
- // pop matrix and obtain one element, upper left or according to jump matrix
- ScMatValType GetDoubleOrStringFromMatrix( double& rDouble, String& rString );
- ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken,
-@@ -538,7 +551,6 @@ BOOL SetSbxVariable( SbxVariable* pVar, SCCOL nCol, SCROW nRow, SCTAB nTab );
- void ScErrorType();
- void ScDBArea();
- void ScColRowNameAuto();
--void ScExternalRef();
- void ScGetPivotData();
- void ScHyperLink();
- void ScBahtText();
-diff --git sc/source/core/tool/address.cxx sc/source/core/tool/address.cxx
-index 78d2c31..622a85b 100644
---- sc/source/core/tool/address.cxx
-+++ sc/source/core/tool/address.cxx
-@@ -1015,7 +1015,18 @@ lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAdd
-             nBits = 0;
- 
-         if (!bExtDoc && (!pDoc || !pDoc->GetTable( aTab, nTab )))
--            nBits = 0;
-+        {
-+            // Specified table name is not found in this document.  Assume this is an external document.
-+            bExtDoc = true;
-+            aDocName = aTab;
-+            xub_StrLen n = aTab.SearchBackward('.');
-+            if (n != STRING_NOTFOUND && n > 0)
-+                // Extension found.  Strip it.
-+                aTab.Erase(n);
-+            else
-+                // No extension found.  This is probably not an external document.
-+                nBits = 0;
-+        }
-     }
-     else
-     {
-diff --git sc/source/core/tool/interpr1.cxx sc/source/core/tool/interpr1.cxx
-index 9c86e45..5646386 100644
---- sc/source/core/tool/interpr1.cxx
-+++ sc/source/core/tool/interpr1.cxx
-@@ -3106,6 +3106,59 @@ void ScInterpreter::ScMax( BOOL bTextAsZero )
- #pragma optimize("",on)
- #endif
- 
-+namespace {
-+
-+void IterateMatrix(
-+    const ScMatrixRef& pMat, ScIterFunc eFunc, BOOL bTextAsZero, 
-+    ULONG& rCount, short& rFuncFmtType, double& fVal, double& fRes, double& fMem, BOOL& bNull)
-+{
-+    if (!pMat)
-+        return;
-+
-+    SCSIZE nC, nR;
-+    rFuncFmtType = NUMBERFORMAT_NUMBER;
-+    pMat->GetDimensions(nC, nR);
-+    if( eFunc == ifCOUNT2 )
-+        rCount += (ULONG) nC * nR;
-+    else
-+    {
-+        for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
-+        {
-+            for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
-+            {
-+                if (!pMat->IsString(nMatCol,nMatRow))
-+                {
-+                    rCount++;
-+                    fVal = pMat->GetDouble(nMatCol,nMatRow);
-+                    switch( eFunc )
-+                    {
-+                        case ifAVERAGE:
-+                        case ifSUM:
-+                            if ( bNull && fVal != 0.0 )
-+                            {
-+                                bNull = FALSE;
-+                                fMem = fVal;
-+                            }
-+                            else
-+                                fRes += fVal;
-+                            break;
-+                        case ifSUMSQ:   fRes += fVal * fVal; break;
-+                        case ifPRODUCT: fRes *= fVal; break;
-+                        default: ; // nothing
-+                    }
-+                }
-+                else if ( bTextAsZero )
-+                {
-+                    rCount++;
-+                    if ( eFunc == ifPRODUCT )
-+                        fRes = 0.0;
-+                }
-+            }
-+        }
-+    }
-+}
-+
-+}
- 
- double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
- {
-@@ -3187,6 +3240,71 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
-                 }
-                 nFuncFmtType = NUMBERFORMAT_NUMBER;
-                 break;
-+            case svExternalSingleRef:
-+            {
-+                ScExternalRefCache::TokenRef pToken;
-+                ScExternalRefCache::CellFormat aFmt;
-+                PopExternalSingleRef(pToken, &aFmt);
-+                if (nGlobalError && (eFunc == ifCOUNT2 || eFunc == ifCOUNT))
-+                {
-+                    nGlobalError = 0;
-+                    if ( eFunc == ifCOUNT2 )
-+                        ++nCount;
-+                    break;
-+                }
-+
-+                if (!pToken)
-+                    break;
-+
-+                StackVar eType = pToken->GetType();
-+                if (eFunc == ifCOUNT2)
-+                {
-+                    if (eType != formula::svEmptyCell)
-+                        nCount++;
-+                    if (nGlobalError)
-+                        nGlobalError = 0;
-+                }
-+                else if (eType == formula::svDouble)
-+                {
-+                    nCount++;
-+                    fVal = pToken->GetDouble();
-+                    if (aFmt.mbIsSet)
-+                    {
-+                        nFuncFmtType = aFmt.mnType;
-+                        nFuncFmtIndex = aFmt.mnIndex;
-+                    }
-+                    switch( eFunc )
-+                    {
-+                        case ifAVERAGE:
-+                        case ifSUM:
-+                            if ( bNull && fVal != 0.0 )
-+                            {
-+                                bNull = FALSE;
-+                                fMem = fVal;
-+                            }
-+                            else
-+                                fRes += fVal;
-+                            break;
-+                        case ifSUMSQ:   fRes += fVal * fVal; break;
-+                        case ifPRODUCT: fRes *= fVal; break;
-+                        case ifCOUNT:
-+                            if ( nGlobalError )
-+                            {    
-+                                nGlobalError = 0;
-+                                nCount--;
-+                            }
-+                            break;
-+                        default: ; // nothing
-+                    }
-+                }
-+                else if (bTextAsZero && eType == formula::svString)
-+                {
-+                    nCount++;
-+                    if ( eFunc == ifPRODUCT )
-+                        fRes = 0.0;
-+                }
-+            }
-+            break;
-             case svSingleRef :
-             {
-                 PopSingleRef( aAdr );
-@@ -3333,53 +3451,20 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
-                 }
-             }
-             break;
-+            case svExternalDoubleRef:
-+            {
-+                ScMatrixRef pMat;
-+                PopExternalDoubleRef(pMat);
-+                if (nGlobalError)
-+                    break;
-+
-+                IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fVal, fMem, fRes, bNull);
-+            }
-+            break;
-             case svMatrix :
-             {
-                 ScMatrixRef pMat = PopMatrix();
--                if (pMat)
--                {
--                    SCSIZE nC, nR;
--                    nFuncFmtType = NUMBERFORMAT_NUMBER;
--                    pMat->GetDimensions(nC, nR);
--                    if( eFunc == ifCOUNT2 )
--                        nCount += (ULONG) nC * nR;
--                    else
--                    {
--                        for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
--                        {
--                            for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
--                            {
--                                if (!pMat->IsString(nMatCol,nMatRow))
--                                {
--                                    nCount++;
--                                    fVal = pMat->GetDouble(nMatCol,nMatRow);
--                                    switch( eFunc )
--                                    {
--                                        case ifAVERAGE:
--                                        case ifSUM:
--                                            if ( bNull && fVal != 0.0 )
--                                            {
--                                                bNull = FALSE;
--                                                fMem = fVal;
--                                            }
--                                            else
--                                                fRes += fVal;
--                                            break;
--                                        case ifSUMSQ:   fRes += fVal * fVal; break;
--                                        case ifPRODUCT: fRes *= fVal; break;
--                                        default: ; // nothing
--                                    }
--                                }
--                                else if ( bTextAsZero )
--                                {
--                                    nCount++;
--                                    if ( eFunc == ifPRODUCT )
--                                        fRes = 0.0;
--                                }
--                            }
--                        }
--                    }
--                }
-+                IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fVal, fMem, fRes, bNull);
-             }
-             break;
-             case svError:
-@@ -4094,29 +4179,39 @@ void ScInterpreter::ScMatch()
-         SCCOL nCol2 = 0;
-         SCROW nRow2 = 0;
-         SCTAB nTab2 = 0;
--        if (GetStackType() == svDoubleRef)
-+
-+        switch (GetStackType())
-         {
--            PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
--            if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2))
-+            case svDoubleRef:
-             {
--                PushIllegalParameter();
--                return;
-+                PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
-+                if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2))
-+                {
-+                    PushIllegalParameter();
-+                    return;
-+                }
-             }
--        }
--        else if (GetStackType() == svMatrix)
--        {
--            pMatSrc = PopMatrix();
--            if (!pMatSrc)
-+            break;
-+            case svMatrix:
-+            case svExternalDoubleRef:
-             {
-+                if (GetStackType() == svMatrix)
-+                    pMatSrc = PopMatrix();
-+                else
-+                    PopExternalDoubleRef(pMatSrc);
-+
-+                if (!pMatSrc)
-+                {
-+                    PushIllegalParameter();
-+                    return;
-+                }
-+            }
-+            break;
-+            default:
-                 PushIllegalParameter();
-                 return;
--            }
--        }
--        else
--        {
--            PushIllegalParameter();
--            return;
-         }
-+
-         if (nGlobalError == 0)
-         {
-             double fVal;
-@@ -4174,6 +4269,32 @@ void ScInterpreter::ScMatch()
-                     }
-                 }
-                 break;
-+                case svExternalSingleRef:
-+                {
-+                    ScExternalRefCache::TokenRef pToken;
-+                    PopExternalSingleRef(pToken);
-+                    if (!pToken)
-+                    {
-+                        PushInt(0);
-+                        return;
-+                    }
-+                    if (pToken->GetType() == svDouble)
-+                    {
-+                        rEntry.bQueryByString = false;
-+                        rEntry.nVal = pToken->GetDouble();
-+                    }
-+                    else
-+                    {
-+                        rEntry.bQueryByString = true;
-+                        *rEntry.pStr = pToken->GetString();
-+                    }
-+                }
-+                break;
-+                case svExternalDoubleRef:
-+                    // TODO: Implement this.
-+                    PushIllegalParameter();
-+                    return;
-+                break;
-                 case svMatrix :
-                 {
-                     ScMatValType nType = GetDoubleOrStringFromMatrix(
-@@ -5861,7 +5982,7 @@ ScDBQueryParamBase* ScInterpreter::GetDBParams( BOOL& rMissingField )
-     if ( GetByte() == 3 )
-     {
-         // First, get the query criteria range.
--        ::std::auto_ptr<ScDBRangeBase> pQueryRef( PopDoubleRef() );
-+        ::std::auto_ptr<ScDBRangeBase> pQueryRef( PopDBDoubleRef() );
-         if (!pQueryRef.get())
-             return NULL;
- 
-@@ -5919,7 +6040,7 @@ ScDBQueryParamBase* ScInterpreter::GetDBParams( BOOL& rMissingField )
-                 SetError( errIllegalParameter );
-         }
- 
--        auto_ptr<ScDBRangeBase> pDBRef( PopDoubleRef() );
-+        auto_ptr<ScDBRangeBase> pDBRef( PopDBDoubleRef() );
- 
-         if (nGlobalError || !pDBRef.get())
-             return NULL;
-@@ -6328,15 +6450,10 @@ void ScInterpreter::ScIndirect()
-         {
-             if (aExtInfo.mbExternal)
-             {
--                /* TODO: future versions should implement a proper subroutine 
--                 * token. This procedure here is a minimally invasive fix for 
--                 * #i101645# in OOo3.1.1 */
--                // Push a subroutine on the instruction code stack that 
--                // resolves the external reference as the next instruction.
--                aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok, 
--                            aExtInfo, aRefAd, &aRefAd2));
--                // Signal subroutine call to interpreter.
--                PushTempToken( new FormulaUnknownToken( ocCall));
-+                PushExternalDoubleRef(
-+                    aExtInfo.mnFileId, aExtInfo.maTabName, 
-+                    aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
-+                    aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab());
-             }
-             else
-                 PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
-@@ -6348,15 +6465,8 @@ void ScInterpreter::ScIndirect()
-         {
-             if (aExtInfo.mbExternal)
-             {
--                /* TODO: future versions should implement a proper subroutine 
--                 * token. This procedure here is a minimally invasive fix for 
--                 * #i101645# in OOo3.1.1 */
--                // Push a subroutine on the instruction code stack that 
--                // resolves the external reference as the next instruction.
--                aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok, 
--                            aExtInfo, aRefAd, NULL));
--                // Signal subroutine call to interpreter.
--                PushTempToken( new FormulaUnknownToken( ocCall));
-+                PushExternalSingleRef(
-+                    aExtInfo.mnFileId, aExtInfo.maTabName, aRefAd.Col(), aRefAd.Row(), aRefAd.Tab());
-             }
-             else
-                 PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
-@@ -6540,6 +6650,44 @@ void ScInterpreter::ScOffset()
-                     PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
-             }
-         }
-+        else if (GetStackType() == svExternalSingleRef)
-+        {
-+            sal_uInt16 nFileId;
-+            String aTabName;
-+            ScSingleRefData aRef;
-+            PopExternalSingleRef(nFileId, aTabName, aRef);
-+            aRef.CalcAbsIfRel(aPos);
-+            nCol1 = aRef.nCol;
-+            nRow1 = aRef.nRow;
-+            nTab1 = aRef.nTab;
-+
-+            if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0))
-+            {
-+                nCol1 = (SCCOL)((long) nCol1 + nColPlus);
-+                nRow1 = (SCROW)((long) nRow1 + nRowPlus);
-+                if (!ValidCol(nCol1) || !ValidRow(nRow1))
-+                    PushIllegalArgument();
-+                else
-+                    PushExternalSingleRef(nFileId, aTabName, nCol1, nRow1, nTab1);
-+            }
-+            else
-+            {
-+                if (nColNew < 0)
-+                    nColNew = 1;
-+                if (nRowNew < 0)
-+                    nRowNew = 1;
-+                nCol1 = (SCCOL)((long)nCol1+nColPlus);      // ! nCol1 wird veraendert!
-+                nRow1 = (SCROW)((long)nRow1+nRowPlus);
-+                nCol2 = (SCCOL)((long)nCol1+nColNew-1);
-+                nRow2 = (SCROW)((long)nRow1+nRowNew-1);
-+                PushIllegalArgument();
-+                if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
-+                    !ValidCol(nCol2) || !ValidRow(nRow2))
-+                    PushIllegalArgument();
-+                else
-+                    PushExternalDoubleRef(nFileId, aTabName, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
-+            }
-+        }
-         else if (GetStackType() == svDoubleRef)
-         {
-             PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
-@@ -6557,6 +6705,33 @@ void ScInterpreter::ScOffset()
-             else
-                 PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
-         }
-+        else if (GetStackType() == svExternalDoubleRef)
-+        {
-+            sal_uInt16 nFileId;
-+            String aTabName;
-+            ScComplexRefData aRef;
-+            PopExternalDoubleRef(nFileId, aTabName, aRef);
-+            aRef.CalcAbsIfRel(aPos);
-+            nCol1 = aRef.Ref1.nCol;
-+            nRow1 = aRef.Ref1.nRow;
-+            nTab1 = aRef.Ref1.nTab;
-+            nCol2 = aRef.Ref2.nCol;
-+            nRow2 = aRef.Ref2.nRow;
-+            nTab2 = aRef.Ref2.nTab;
-+            if (nColNew < 0)
-+                nColNew = nCol2 - nCol1 + 1;
-+            if (nRowNew < 0)
-+                nRowNew = nRow2 - nRow1 + 1;
-+            nCol1 = (SCCOL)((long)nCol1+nColPlus);
-+            nRow1 = (SCROW)((long)nRow1+nRowPlus);
-+            nCol2 = (SCCOL)((long)nCol1+nColNew-1);
-+            nRow2 = (SCROW)((long)nRow1+nRowNew-1);
-+            if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
-+                !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2)
-+                PushIllegalArgument();
-+            else
-+                PushExternalDoubleRef(nFileId, aTabName, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
-+        }
-         else
-             PushIllegalParameter();
-     }
-diff --git sc/source/core/tool/interpr4.cxx sc/source/core/tool/interpr4.cxx
-index 49c4d2a..5a824e5 100644
---- sc/source/core/tool/interpr4.cxx
-+++ sc/source/core/tool/interpr4.cxx
-@@ -1249,40 +1249,42 @@ void ScInterpreter::DoubleRefToVars( const ScToken* p,
-     }
- }
- 
--ScDBRangeBase* ScInterpreter::PopDoubleRef()
-+ScDBRangeBase* ScInterpreter::PopDBDoubleRef()
- {
--    if (!sp)
--    {    
--        SetError(errUnknownStackVariable);
--        return NULL;
--    }
--
--    --sp;
--    FormulaToken* p = pStack[sp];
--    switch (p->GetType())
-+    StackVar eType = GetStackType();
-+    switch (eType)
-     {
-+        case svUnknown:
-+            SetError(errUnknownStackVariable);
-+        break;
-         case svError:
--            nGlobalError = p->GetError();
-+            PopError();
-         break;
-         case svDoubleRef:
-         {
-             SCCOL nCol1, nCol2;
-             SCROW nRow1, nRow2;
-             SCTAB nTab1, nTab2;
--            DoubleRefToVars(static_cast<ScToken*>(p), 
--                            nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, false);
--            
-+            PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, false);
-+            if (nGlobalError)
-+                break;
-             return new ScDBInternalRange(pDok,
-                 ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
-         }
-         case svMatrix:
-+        case svExternalDoubleRef:
-         {
--            ScMatrixRef pMat = static_cast<ScToken*>(p)->GetMatrix();
-+            ScMatrixRef pMat;
-+            if (eType == svMatrix)
-+                pMat = PopMatrix();
-+            else
-+                PopExternalDoubleRef(pMat);
-             return new ScDBExternalRange(pDok, pMat);
-         }
-         default:
-             SetError( errIllegalParameter);
-     }
-+
-     return NULL;
- }
- 
-@@ -1402,6 +1404,171 @@ void ScInterpreter::PopDoubleRef( ScRange& rRange, BOOL bDontCheckForTableOp )
-         SetError( errUnknownStackVariable);
- }
- 
-+void ScInterpreter::PopExternalSingleRef(sal_uInt16& rFileId, String& rTabName, ScSingleRefData& rRef)
-+{
-+    if (!sp)
-+    {
-+        SetError(errUnknownStackVariable);
-+        return;
-+    }
-+
-+    --sp;
-+    FormulaToken* p = pStack[sp];
-+    StackVar eType = p->GetType();
-+
-+    if (eType == svError)
-+    {
-+        nGlobalError = p->GetError();
-+        return;
-+    }
-+
-+    if (eType != svExternalSingleRef)
-+    {
-+        SetError( errIllegalParameter);
-+        return;
-+    }
-+
-+    rFileId = p->GetIndex();
-+    rTabName = p->GetString();
-+    rRef = static_cast<ScToken*>(p)->GetSingleRef();
-+}
-+
-+void ScInterpreter::PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt)
-+{
-+
-+    sal_uInt16 nFileId;
-+    String aTabName;
-+    ScSingleRefData aData;
-+    PopExternalSingleRef(nFileId, aTabName, aData);
-+    if (nGlobalError)
-+        return;
-+
-+    ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
-+    const String* pFile = pRefMgr->getExternalFileName(nFileId);
-+    if (!pFile)
-+    {
-+        SetError(errNoName);
-+        return;
-+    }
-+
-+    if (aData.IsTabRel())
-+    {
-+        DBG_ERROR("ScCompiler::GetToken: external single reference must have an absolute table reference!");
-+        SetError(errNoRef);
-+        return;
-+    }
-+
-+    aData.CalcAbsIfRel(aPos);
-+    ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab);
-+    ScExternalRefCache::CellFormat aFmt;
-+    ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(
-+        nFileId, aTabName, aAddr, &aPos, NULL, &aFmt);
-+
-+    if (!xNew)
-+    {
-+        SetError(errNoRef);
-+        return;
-+    }
-+
-+    rToken = xNew;
-+    if (pFmt)
-+        *pFmt = aFmt;
-+}
-+
-+void ScInterpreter::PopExternalDoubleRef(sal_uInt16& rFileId, String& rTabName, ScComplexRefData& rRef)
-+{
-+    if (!sp)
-+    {
-+        SetError(errUnknownStackVariable);
-+        return;
-+    }
-+
-+    --sp;
-+    FormulaToken* p = pStack[sp];
-+    StackVar eType = p->GetType();
-+
-+    if (eType == svError)
-+    {
-+        nGlobalError = p->GetError();
-+        return;
-+    }
-+
-+    if (eType != svExternalDoubleRef)
-+    {
-+        SetError( errIllegalParameter);
-+        return;
-+    }
-+
-+    rFileId = p->GetIndex();
-+    rTabName = p->GetString();
-+    rRef = static_cast<ScToken*>(p)->GetDoubleRef();
-+}
-+
-+void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray)
-+{
-+    sal_uInt16 nFileId;
-+    String aTabName;
-+    ScComplexRefData aData;
-+    PopExternalDoubleRef(nFileId, aTabName, aData);
-+    if (nGlobalError)
-+        return;
-+
-+    ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
-+    const String* pFile = pRefMgr->getExternalFileName(nFileId);
-+    if (!pFile)
-+    {
-+        SetError(errNoName);
-+        return;
-+    }
-+    if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
-+    {
-+        DBG_ERROR("ScCompiler::GetToken: external double reference must have an absolute table reference!");
-+        SetError(errNoRef);
-+        return;
-+    }
-+
-+    aData.CalcAbsIfRel(aPos);
-+    ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab,
-+                   aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
-+    ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(
-+        nFileId, aTabName, aRange, &aPos);
-+
-+    if (!pArray)
-+    {
-+        SetError(errIllegalArgument);
-+        return;
-+    }
-+
-+    ScToken* pToken = static_cast<ScToken*>(pArray->First());
-+    if (pToken->GetType() != svMatrix)
-+    {
-+        SetError(errIllegalArgument);
-+        return;
-+    }
-+
-+    if (pArray->Next())
-+    {
-+        // Can't handle more than one matrix per parameter.
-+        SetError( errIllegalArgument);
-+        return;
-+    }
-+
-+    rArray = pArray;
-+}
-+
-+void ScInterpreter::PopExternalDoubleRef(ScMatrixRef& rMat)
-+{
-+    ScExternalRefCache::TokenArrayRef pArray;
-+    PopExternalDoubleRef(pArray);
-+    if (nGlobalError)
-+        return;
-+
-+    // For now, we only support single range data for external
-+    // references, which means the array should only contain a
-+    // single matrix token.
-+    ScToken* p = static_cast<ScToken*>(pArray->First());
-+    rMat = p->GetMatrix();
-+}
- 
- BOOL ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr )
- {
-@@ -1684,6 +1851,40 @@ void ScInterpreter::PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
- }
- 
- 
-+void ScInterpreter::PushExternalSingleRef(
-+    sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, SCTAB nTab)
-+{
-+    if (!IfErrorPushError())
-+    {
-+        ScSingleRefData aRef;
-+        aRef.InitFlags();
-+        aRef.nCol = nCol;
-+        aRef.nRow = nRow;
-+        aRef.nTab = nTab;
-+        PushTempTokenWithoutError( new ScExternalSingleRefToken(nFileId, rTabName, aRef)) ;
-+    }
-+}
-+
-+
-+void ScInterpreter::PushExternalDoubleRef(
-+    sal_uInt16 nFileId, const String& rTabName, 
-+    SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
-+{
-+    if (!IfErrorPushError())
-+    {
-+        ScComplexRefData aRef;
-+        aRef.InitFlags();
-+        aRef.Ref1.nCol = nCol1;
-+        aRef.Ref1.nRow = nRow1;
-+        aRef.Ref1.nTab = nTab1;
-+        aRef.Ref2.nCol = nCol2;
-+        aRef.Ref2.nRow = nRow2;
-+        aRef.Ref2.nTab = nTab2;
-+        PushTempTokenWithoutError( new ScExternalDoubleRefToken(nFileId, rTabName, aRef) );
-+    }
-+}
-+
-+
- void ScInterpreter::PushMatrix(ScMatrix* pMat)
- {
-     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushMatrix" );
-@@ -1886,6 +2087,23 @@ BOOL ScInterpreter::DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& r
-     return bOk;
- }
- 
-+double ScInterpreter::GetDoubleFromMatrix(const ScMatrixRef& pMat)
-+{
-+    if (!pMat)
-+        return 0.0;
-+
-+    if ( !pJumpMatrix )
-+        return pMat->GetDouble( 0 );
-+
-+    SCSIZE nCols, nRows, nC, nR;
-+    pMat->GetDimensions( nCols, nRows);
-+    pJumpMatrix->GetPos( nC, nR);
-+    if ( nC < nCols && nR < nRows )
-+        return pMat->GetDouble( nC, nR);
-+
-+    SetError( errNoValue);
-+    return 0.0;
-+}
- 
- double ScInterpreter::GetDouble()
- {
-@@ -1921,26 +2139,28 @@ double ScInterpreter::GetDouble()
-                 nVal = 0.0;
-         }
-         break;
-+        case svExternalSingleRef:
-+        {
-+            ScExternalRefCache::TokenRef pToken;
-+            PopExternalSingleRef(pToken);
-+            if (!nGlobalError && pToken)
-+                nVal = pToken->GetDouble();
-+        }
-+        break;
-+        case svExternalDoubleRef:
-+        {
-+            ScMatrixRef pMat;
-+            PopExternalDoubleRef(pMat);
-+            if (nGlobalError)
-+                break;
-+
-+            nVal = GetDoubleFromMatrix(pMat);
-+        }
-+        break;
-         case svMatrix:
-         {
-             ScMatrixRef pMat = PopMatrix();
--            if ( !pMat )
--                nVal = 0.0;
--            else if ( !pJumpMatrix )
--                nVal = pMat->GetDouble( 0 );
--            else
--            {
--                SCSIZE nCols, nRows, nC, nR;
--                pMat->GetDimensions( nCols, nRows);
--                pJumpMatrix->GetPos( nC, nR);
--                if ( nC < nCols && nR < nRows )
--                    nVal = pMat->GetDouble( nC, nR);
--                else
--                {
--                    SetError( errNoValue);
--                    nVal = 0.0;
--                }
--            }
-+            nVal = GetDoubleFromMatrix(pMat);
-         }
-         break;
-         case svError:
-@@ -2029,30 +2249,23 @@ const String& ScInterpreter::GetString()
-             else
-                 return EMPTY_STRING;
-         }
-+        case svExternalSingleRef:
-+        {
-+            ScExternalRefCache::TokenRef pToken;
-+            PopExternalSingleRef(pToken);
-+            return nGlobalError ? EMPTY_STRING : pToken->GetString();
-+        }
-+        case svExternalDoubleRef:
-+        {
-+            ScMatrixRef pMat;
-+            PopExternalDoubleRef(pMat);
-+            return GetStringFromMatrix(pMat);
-+        }
-         //break;
-         case svMatrix:
-         {
-             ScMatrixRef pMat = PopMatrix();
--            if ( !pMat )
--                ;   // nothing
--            else if ( !pJumpMatrix )
--            {
--                aTempStr = pMat->GetString( *pFormatter, 0, 0);
--                return aTempStr;
--            }
--            else
--            {
--                SCSIZE nCols, nRows, nC, nR;
--                pMat->GetDimensions( nCols, nRows);
--                pJumpMatrix->GetPos( nC, nR);
--                if ( nC < nCols && nR < nRows )
--                {
--                    aTempStr = pMat->GetString( *pFormatter, nC, nR);
--                    return aTempStr;
--                }
--                else
--                    SetError( errNoValue);
--            }
-+            return GetStringFromMatrix(pMat);
-         }
-         break;
-         default:
-@@ -2062,7 +2275,30 @@ const String& ScInterpreter::GetString()
-     return EMPTY_STRING;
- }
- 
--
-+const String& ScInterpreter::GetStringFromMatrix(const ScMatrixRef& pMat)
-+{
-+    if ( !pMat )
-+        ;   // nothing
-+    else if ( !pJumpMatrix )
-+    {
-+        aTempStr = pMat->GetString( *pFormatter, 0, 0);
-+        return aTempStr;
-+    }
-+    else
-+    {
-+        SCSIZE nCols, nRows, nC, nR;
-+        pMat->GetDimensions( nCols, nRows);
-+        pJumpMatrix->GetPos( nC, nR);
-+        if ( nC < nCols && nR < nRows )
-+        {
-+            aTempStr = pMat->GetString( *pFormatter, nC, nR);
-+            return aTempStr;
-+        }
-+        else
-+            SetError( errNoValue);
-+    }
-+    return EMPTY_STRING;
-+}
- 
- ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble,
-         String& rString )
-@@ -3295,82 +3531,6 @@ void ScInterpreter::ScColRowNameAuto()
-         PushError( errNoRef );
- }
- 
--void ScInterpreter::ScExternalRef()
--{
--    ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
--    const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex());
--    if (!pFile)
--        PushError(errNoName);
--
--    switch (pCur->GetType())
--    {
--        case svExternalSingleRef:
--        {
--            ScSingleRefData aData(static_cast<const ScToken*>(pCur)->GetSingleRef());
--            if (aData.IsTabRel())
--            {
--                DBG_ERROR("ScCompiler::GetToken: external single reference must have an absolute table reference!");
--                break;
--            }
--
--            aData.CalcAbsIfRel(aPos);
--            ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab);
--            ScExternalRefCache::CellFormat aFmt;
--            ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(
--                pCur->GetIndex(), pCur->GetString(), aAddr, &aPos, NULL, &aFmt);
--
--            if (!xNew)
--                break;
--
--            PushTempToken( *xNew);      // push a clone
--
--            if (aFmt.mbIsSet)
--            {
--                nFuncFmtType = aFmt.mnType;
--                nFuncFmtIndex = aFmt.mnIndex;
--            }
--            return;
--        }
--        //break;    // unreachable, prevent compiler warning
--        case svExternalDoubleRef:
--        {
--            ScComplexRefData aData(static_cast<const ScToken*>(pCur)->GetDoubleRef());
--            if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
--            {
--                DBG_ERROR("ScCompiler::GetToken: external double reference must have an absolute table reference!");
--                break;
--            }
--
--            aData.CalcAbsIfRel(aPos);
--            ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab,
--                           aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
--            ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getDoubleRefTokens(
--                pCur->GetIndex(), pCur->GetString(), aRange, &aPos);
--
--            if (!xNew)
--                break;
--
--            ScToken* p = static_cast<ScToken*>(xNew->First());
--            if (p->GetType() != svMatrix)
--                break;
--
--            if (xNew->Next())
--            {
--                // Can't handle more than one matrix per parameter.
--                SetError( errIllegalArgument);
--                break;
--            }
--
--            PushMatrix(p->GetMatrix());
--            return;
--        }
--        //break;    // unreachable, prevent compiler warning
--        default:
--            ;
--    }
--    PushError(errNoRef);
--}
--
- // --- internals ------------------------------------------------------------
- 
- 
-@@ -3443,6 +3603,7 @@ void ScInterpreter::GlobalExit()        // static
- 
- StackVar ScInterpreter::Interpret()
- {
-+//  StackPrinter __stack_printer__("ScInterpreter::Interpret");
-     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Interpret" );
-     short nRetTypeExpr = NUMBERFORMAT_UNDEFINED;
-     ULONG nRetIndexExpr = 0;
-@@ -3526,7 +3687,6 @@ StackVar ScInterpreter::Interpret()
-                 case ocDBArea           : ScDBArea();                   break;
-                 case ocColRowNameAuto   : ScColRowNameAuto();           break;
- // separated    case ocPush             : Push( (ScToken&) *pCur );     break;
--                case ocExternalRef      : ScExternalRef();              break;
-                 case ocIf               : ScIfJump();                   break;
-                 case ocChose            : ScChoseJump();                break;
-                 case ocAdd              : ScAdd();                      break;
-@@ -3998,9 +4158,15 @@ StackVar ScInterpreter::Interpret()
-                     }
-                 }
-                 // no break
-+                case svExternalDoubleRef:
-                 case svMatrix :
-                 {
--                    ScMatrixRef xMat = PopMatrix();
-+                    ScMatrixRef xMat;
-+                    if (pCur->GetType() == svMatrix)
-+                        xMat = PopMatrix();
-+                    else
-+                        PopExternalDoubleRef(xMat);
-+
-                     if (xMat)
-                     {
-                         ScMatValType nMatValType;
-@@ -4045,6 +4211,23 @@ StackVar ScInterpreter::Interpret()
-                         SetError( errUnknownStackVariable);
-                 }
-                 break;
-+                case svExternalSingleRef:
-+                {
-+                    ScExternalRefCache::TokenRef pToken;
-+                    ScExternalRefCache::CellFormat aFmt;
-+                    PopExternalSingleRef(pToken, &aFmt);
-+                    if (nGlobalError)
-+                        break;
-+
-+                    PushTempToken(*pToken);
-+
-+                    if (aFmt.mbIsSet)
-+                    {
-+                        nFuncFmtType = aFmt.mnType;
-+                        nFuncFmtIndex = aFmt.mnIndex;
-+                    }
-+                }
-+                break;
-                 default :
-                     SetError( errUnknownStackVariable);
-             }
-diff --git sc/source/core/tool/token.cxx sc/source/core/tool/token.cxx
-index 66665b0..fc368d0 100644
---- sc/source/core/tool/token.cxx
-+++ sc/source/core/tool/token.cxx
-@@ -240,7 +240,7 @@ void ScRawToken::SetName( USHORT n )
- 
- void ScRawToken::SetExternalSingleRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
- {
--    eOp = ocExternalRef;
-+    eOp = ocPush;
-     eType = svExternalSingleRef;
-     nRefCnt = 0;
- 
-@@ -255,7 +255,7 @@ void ScRawToken::SetExternalSingleRef( sal_uInt16 nFileId, const String& rTabNam
- 
- void ScRawToken::SetExternalDoubleRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
- {
--    eOp = ocExternalRef;
-+    eOp = ocPush;
-     eType = svExternalDoubleRef;
-     nRefCnt = 0;
- 
-@@ -269,7 +269,7 @@ void ScRawToken::SetExternalDoubleRef( sal_uInt16 nFileId, const String& rTabNam
- 
- void ScRawToken::SetExternalName( sal_uInt16 nFileId, const String& rName )
- {
--    eOp = ocExternalRef;
-+    eOp = ocPush;
-     eType = svExternalName;
-     nRefCnt = 0;
- 
-@@ -347,37 +347,26 @@ ScRawToken* ScRawToken::Clone() const
-         static USHORT nOffset = lcl_ScRawTokenOffset();     // offset of sbyte
-         USHORT n = nOffset;
- 
--        if (eOp == ocExternalRef)
-+        switch( eType )
-         {
--            switch (eType)
--            {
--                case svExternalSingleRef:
--                case svExternalDoubleRef: n += sizeof(extref); break;
--                case svExternalName:      n += sizeof(extname); break;
--                default:
--                {
--                    DBG_ERROR1( "unknown ScRawToken::Clone() external type %d", int(eType));
--                }
--            }
--        }
--        else
--        {
--            switch( eType )
-+            case svSep:         break;
-+            case svByte:        n += sizeof(ScRawToken::sbyte); break;
-+            case svDouble:      n += sizeof(double); break;
-+            case svString:      n = sal::static_int_cast<USHORT>( n + GetStrLenBytes( cStr ) + GetStrLenBytes( 1 ) ); break;
-+            case svSingleRef:
-+            case svDoubleRef:   n += sizeof(aRef); break;
-+            case svMatrix:      n += sizeof(ScMatrix*); break;
-+            case svIndex:       n += sizeof(USHORT); break;
-+            case svJump:        n += nJump[ 0 ] * 2 + 2; break;
-+            case svExternal:    n = sal::static_int_cast<USHORT>( n + GetStrLenBytes( cStr+1 ) + GetStrLenBytes( 2 ) ); break;
-+
-+            // external references
-+            case svExternalSingleRef:
-+            case svExternalDoubleRef: n += sizeof(extref); break;
-+            case svExternalName:      n += sizeof(extname); break;
-+            default:
-             {
--                case svSep:         break;
--                case svByte:        n += sizeof(ScRawToken::sbyte); break;
--                case svDouble:      n += sizeof(double); break;
--                case svString:      n = sal::static_int_cast<USHORT>( n + GetStrLenBytes( cStr ) + GetStrLenBytes( 1 ) ); break;
--                case svSingleRef:
--                case svDoubleRef:   n += sizeof(aRef); break;
--                case svMatrix:      n += sizeof(ScMatrix*); break;
--                case svIndex:       n += sizeof(USHORT); break;
--                case svJump:        n += nJump[ 0 ] * 2 + 2; break;
--                case svExternal:    n = sal::static_int_cast<USHORT>( n + GetStrLenBytes( cStr+1 ) + GetStrLenBytes( 2 ) ); break;
--                default:
--                {
--                    DBG_ERROR1( "unknown ScRawToken::Clone() type %d", int(eType));
--                }
-+                DBG_ERROR1( "unknown ScRawToken::Clone() type %d", int(eType));
-             }
-         }
-         p = (ScRawToken*) new BYTE[ n ];
-@@ -841,7 +830,7 @@ BOOL ScMatrixToken::operator==( const FormulaToken& r ) const
- // ============================================================================
- 
- ScExternalSingleRefToken::ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r ) :
--    ScToken( svExternalSingleRef, ocExternalRef),
-+    ScToken( svExternalSingleRef, ocPush),
-     mnFileId(nFileId),
-     maTabName(rTabName),
-     maSingleRef(r)
-@@ -907,7 +896,7 @@ BOOL ScExternalSingleRefToken::operator ==( const FormulaToken& r ) const
- // ============================================================================
- 
- ScExternalDoubleRefToken::ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r ) :
--    ScToken( svExternalDoubleRef, ocExternalRef),
-+    ScToken( svExternalDoubleRef, ocPush),
-     mnFileId(nFileId),
-     maTabName(rTabName),
-     maDoubleRef(r)
-@@ -993,7 +982,7 @@ BOOL ScExternalDoubleRefToken::operator ==( const FormulaToken& r ) const
- // ============================================================================
- 
- ScExternalNameToken::ScExternalNameToken( sal_uInt16 nFileId, const String& rName ) :
--    ScToken( svExternalName, ocExternalRef),
-+    ScToken( svExternalName, ocPush),
-     mnFileId(nFileId),
-     maName(rName)
- {
-diff --git sc/source/filter/excel/xeformula.cxx sc/source/filter/excel/xeformula.cxx
-index 17124e8..3fa343a 100644
---- sc/source/filter/excel/xeformula.cxx
-+++ sc/source/filter/excel/xeformula.cxx
-@@ -2104,7 +2104,7 @@ void XclExpFmlaCompImpl::ProcessExternalName( const XclExpScToken& rTokData )
-             {
-                 for( FormulaToken* pScToken = xArray->First(); pScToken; pScToken = xArray->Next() )
-                 {
--                    if( pScToken->GetOpCode() == ocExternalRef )
-+                    if( pScToken->IsExternalRef() )
-                     {
-                         switch( pScToken->GetType() )
-                         {
-diff --git sc/source/filter/excel/xelink.cxx sc/source/filter/excel/xelink.cxx
-index 645abc2..efb0be6 100644
---- sc/source/filter/excel/xelink.cxx
-+++ sc/source/filter/excel/xelink.cxx
-@@ -968,7 +968,7 @@ void XclExpExtName::WriteAddData( XclExpStream& rStrm )
-             break;
- 
-         const ScToken* p = static_cast<const ScToken*>(mpArray->First());
--        if (p->GetOpCode() != ocExternalRef)
-+        if (!p->IsExternalRef())
-             break;
- 
-         switch (p->GetType())
-diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
-index 8291375..01af6d0 100644
---- sc/source/ui/docshell/externalrefmgr.cxx
-+++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -145,7 +145,7 @@ struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void>
-         // External names, external cell and range references all have a
-         // ocExternalRef token.
-         const ScTokenArray* pCode = pCell->GetCode();
--        if (!pCode->HasOpCode( ocExternalRef))
-+        if (!pCode->HasExternalRef())
-             return;
- 
-         ScTokenArray* pArray = pCell->GetCode();
-@@ -1362,7 +1362,7 @@ static FormulaToken* lcl_convertToToken(ScBaseCell* pCell)
-     return NULL;
- }
- 
--static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, ScRange& rRange,
-+static ScTokenArray* lcl_convertToTokenArray(const ScDocument* pSrcDoc, ScRange& rRange,
-                                              vector<ScExternalRefCache::SingleRangeData>& rCacheData)
- {
-     ScAddress& s = rRange.aStart;
-@@ -1665,6 +1665,27 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
-     if (pFmt)
-         pFmt->mbIsSet = false;
- 
-+    const ScDocument* pSrcDoc = getInMemorySrcDocument(nFileId);
-+    if (pSrcDoc)
-+    {   
-+        // source document already loaded in memory.  Re-use this instance.
-+        // We don't even cache data when the document is loaded.
-+
-+        SCTAB nTab;
-+        if (!pSrcDoc->GetTable(rTabName, nTab))
-+        {
-+            // specified table name doesn't exist in the source document.
-+            ScExternalRefCache::TokenRef pToken(new FormulaErrorToken(errNoRef));
-+            return pToken;
-+        }
-+
-+        if (pTab)
-+            *pTab = nTab;
-+
-+        return getSingleRefTokenFromSrcDoc(
-+            nFileId, pSrcDoc, ScAddress(rCell.Col(),rCell.Row(),nTab), pFmt);
-+    }
-+
-     // Check if the given table name and the cell position is cached.
-     sal_uInt32 nFmtIndex = 0;
-     ScExternalRefCache::TokenRef pToken = maRefCache.getCellData(
-@@ -1672,21 +1693,12 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
-     if (pToken)
-     {
-         // Cache hit !
--        if (pFmt)
--        {
--            short nFmtType = mpDoc->GetFormatTable()->GetType(nFmtIndex);
--            if (nFmtType != NUMBERFORMAT_UNDEFINED)
--            {
--                pFmt->mbIsSet = true;
--                pFmt->mnIndex = nFmtIndex;
--                pFmt->mnType = nFmtType;
--            }
--        }
-+        fillCellFormat(nFmtIndex, pFmt);
-         return pToken;
-     }
- 
-     // reference not cached.  read from the source document.
--    ScDocument* pSrcDoc = getSrcDocument(nFileId);
-+    pSrcDoc = getSrcDocument(nFileId);
-     if (!pSrcDoc)
-     {
-         // Source document not reachable.  Throw a reference error.
-@@ -1694,7 +1706,6 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
-         return pToken;
-     }
- 
--    ScBaseCell* pCell = NULL;
-     SCTAB nTab;
-     if (!pSrcDoc->GetTable(rTabName, nTab))
-     {
-@@ -1723,33 +1734,14 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
-         return pToken;
-     }
- 
--    pSrcDoc->GetCell(rCell.Col(), rCell.Row(), nTab, pCell);
--    ScExternalRefCache::TokenRef pTok(lcl_convertToToken(pCell));
--
--    pSrcDoc->GetNumberFormat(rCell.Col(), rCell.Row(), nTab, nFmtIndex);
--    nFmtIndex = getMappedNumberFormat(nFileId, nFmtIndex, pSrcDoc);
--    if (pFmt)
--    {
--        short nFmtType = mpDoc->GetFormatTable()->GetType(nFmtIndex);
--        if (nFmtType != NUMBERFORMAT_UNDEFINED)
--        {
--            pFmt->mbIsSet = true;
--            pFmt->mnIndex = nFmtIndex;
--            pFmt->mnType = nFmtType;
--        }
--    }
--
--    if (!pTok.get())
--    {
--        // Generate an error for unresolvable cells.
--        pTok.reset( new FormulaErrorToken( errNoValue));
--    }
-+    pToken = getSingleRefTokenFromSrcDoc(
-+        nFileId, pSrcDoc, ScAddress(rCell.Col(),rCell.Row(),nTab), pFmt);
- 
-     // Now, insert the token into cache table but don't cache empty cells.
--    if (pTok->GetType() != formula::svEmptyCell)
--        maRefCache.setCellData(nFileId, rTabName, rCell.Col(), rCell.Row(), pTok, nFmtIndex);
-+    if (pToken->GetType() != formula::svEmptyCell)
-+        maRefCache.setCellData(nFileId, rTabName, rCell.Col(), rCell.Row(), pToken, nFmtIndex);
- 
--    return pTok;
-+    return pToken;
- }
- 
- ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
-@@ -1760,6 +1752,15 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
- 
-     maybeLinkExternalFile(nFileId);
- 
-+    ScRange aRange(rRange);
-+    const ScDocument* pSrcDoc = getInMemorySrcDocument(nFileId);
-+    if (pSrcDoc)
-+    {
-+        // Document already loaded.
-+        vector<ScExternalRefCache::SingleRangeData> aCacheData;
-+        return getDoubleRefTokensFromSrcDoc(pSrcDoc, rTabName, aRange, aCacheData);
-+    }
-+
-     // Check if the given table name and the cell position is cached.
-     ScExternalRefCache::TokenArrayRef pArray = 
-         maRefCache.getCellRangeData(nFileId, rTabName, rRange);
-@@ -1767,7 +1768,7 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
-         // Cache hit !
-         return pArray;
- 
--    ScDocument* pSrcDoc = getSrcDocument(nFileId);
-+    pSrcDoc = getSrcDocument(nFileId);
-     if (!pSrcDoc)
-     {
-         // Source document is not reachable.  Throw a reference error.
-@@ -1776,38 +1777,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
-         return pArray;
-     }
- 
--    SCTAB nTab1;
--    if (!pSrcDoc->GetTable(rTabName, nTab1))
--    {
--        // specified table name doesn't exist in the source document.
--        pArray.reset(new ScTokenArray);
--        pArray->AddToken(FormulaErrorToken(errNoRef));
--        return pArray;
--    }
--
--    ScRange aRange(rRange);
--    SCTAB nTabSpan = aRange.aEnd.Tab() - aRange.aStart.Tab();
--
-     vector<ScExternalRefCache::SingleRangeData> aCacheData;
--    aCacheData.reserve(nTabSpan+1);
--    aCacheData.push_back(ScExternalRefCache::SingleRangeData());
--    aCacheData.back().maTableName = ScGlobal::pCharClass->upper(rTabName);
--
--    for (SCTAB i = 1; i < nTabSpan + 1; ++i)
--    {
--        String aTabName;
--        if (!pSrcDoc->GetName(nTab1 + 1, aTabName))
--            // source document doesn't have any table by the specified name.
--            break;
--
--        aCacheData.push_back(ScExternalRefCache::SingleRangeData());
--        aCacheData.back().maTableName = ScGlobal::pCharClass->upper(aTabName);
--    }
--
--    aRange.aStart.SetTab(nTab1);
--    aRange.aEnd.SetTab(nTab1 + nTabSpan);
--
--    pArray.reset(lcl_convertToTokenArray(pSrcDoc, aRange, aCacheData));
-+    pArray = getDoubleRefTokensFromSrcDoc(pSrcDoc, rTabName, aRange, aCacheData);    
- 
-     if (pArray)
-         // Cache these values.
-@@ -1836,14 +1807,159 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(sal_u
- 
-     maybeLinkExternalFile(nFileId);
- 
-+    String aName = rName; // make a copy to have the casing corrected.
-+    const ScDocument* pSrcDoc = getInMemorySrcDocument(nFileId);
-+    if (pSrcDoc)
-+    {
-+        // Document already loaded in memory.
-+        return getRangeNameTokensFromSrcDoc(nFileId, pSrcDoc, aName);
-+    }
-+
-     ScExternalRefCache::TokenArrayRef pArray = maRefCache.getRangeNameTokens(nFileId, rName);
-     if (pArray.get())
-+        // This range name is cached.
-         return pArray;
- 
--    ScDocument* pSrcDoc = getSrcDocument(nFileId);
-+    pSrcDoc = getSrcDocument(nFileId);
-     if (!pSrcDoc)
-+        // failed to load document from disk.
-         return ScExternalRefCache::TokenArrayRef();
- 
-+    pArray = getRangeNameTokensFromSrcDoc(nFileId, pSrcDoc, aName);
-+
-+    if (pArray)
-+        // Cache this range name array.
-+        maRefCache.setRangeNameTokens(nFileId, aName, pArray);
-+
-+    return pArray;
-+}
-+
-+void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
-+{
-+    RefCellMap::iterator itrFile = maRefCells.find(nFileId);
-+    if (itrFile == maRefCells.end())
-+        return;
-+
-+    RefCellSet& rRefCells = itrFile->second;
-+    for_each(rRefCells.begin(), rRefCells.end(), UpdateFormulaCell());
-+
-+    ScViewData* pViewData = ScDocShell::GetViewData();
-+    if (!pViewData)
-+        return;
-+
-+    ScTabViewShell* pVShell = pViewData->GetViewShell();
-+    if (!pVShell)
-+        return;
-+
-+    // Repainting the grid also repaints the texts, but is there a better way
-+    // to refresh texts?
-+    pVShell->Invalidate(FID_REPAINT);
-+    pVShell->PaintGrid();
-+}
-+
-+void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell)
-+{
-+    RefCellMap::iterator itr = maRefCells.find(nFileId);
-+    if (itr == maRefCells.end())
-+    {
-+        RefCellSet aRefCells;
-+        pair<RefCellMap::iterator, bool> r = maRefCells.insert(
-+            RefCellMap::value_type(nFileId, aRefCells));
-+        if (!r.second)
-+            // insertion failed.
-+            return;
-+
-+        itr = r.first;
-+    }
-+
-+    ScBaseCell* pCell = mpDoc->GetCell(rCell);
-+    if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
-+        itr->second.insert(static_cast<ScFormulaCell*>(pCell));
-+}
-+
-+void ScExternalRefManager::fillCellFormat(sal_uInt32 nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const
-+{
-+    if (!pFmt)
-+        return;
-+
-+    short nFmtType = mpDoc->GetFormatTable()->GetType(nFmtIndex);
-+    if (nFmtType != NUMBERFORMAT_UNDEFINED)
-+    {
-+        pFmt->mbIsSet = true;
-+        pFmt->mnIndex = nFmtIndex;
-+        pFmt->mnType = nFmtType;
-+    }
-+}
-+
-+ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefTokenFromSrcDoc(
-+    sal_uInt16 nFileId, const ScDocument* pSrcDoc, const ScAddress& rCell, 
-+    ScExternalRefCache::CellFormat* pFmt)
-+{
-+    // Get the cell from src doc, and convert it into a token.
-+    ScBaseCell* pCell = NULL;
-+    pSrcDoc->GetCell(rCell.Col(), rCell.Row(), rCell.Tab(), pCell);
-+    ScExternalRefCache::TokenRef pToken(lcl_convertToToken(pCell));
-+
-+    if (!pToken.get())
-+    {
-+        // Generate an error for unresolvable cells.
-+        pToken.reset( new FormulaErrorToken( errNoValue));
-+    }
-+
-+    // Get number format information.
-+    sal_uInt32 nFmtIndex = 0;
-+    pSrcDoc->GetNumberFormat(rCell.Col(), rCell.Row(), rCell.Tab(), nFmtIndex);
-+    nFmtIndex = getMappedNumberFormat(nFileId, nFmtIndex, pSrcDoc);
-+    fillCellFormat(nFmtIndex, pFmt);
-+    return pToken;
-+}
-+
-+ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokensFromSrcDoc(
-+    const ScDocument* pSrcDoc, const String& rTabName, ScRange& rRange,
-+    vector<ScExternalRefCache::SingleRangeData>& rCacheData)
-+{
-+    ScExternalRefCache::TokenArrayRef pArray;
-+    SCTAB nTab1;
-+
-+    if (!pSrcDoc->GetTable(rTabName, nTab1))
-+    {
-+        // specified table name doesn't exist in the source document.
-+        pArray.reset(new ScTokenArray);
-+        pArray->AddToken(FormulaErrorToken(errNoRef));
-+        return pArray;
-+    }
-+
-+    ScRange aRange(rRange);
-+    SCTAB nTabSpan = aRange.aEnd.Tab() - aRange.aStart.Tab();
-+
-+    vector<ScExternalRefCache::SingleRangeData> aCacheData;
-+    aCacheData.reserve(nTabSpan+1);
-+    aCacheData.push_back(ScExternalRefCache::SingleRangeData());
-+    aCacheData.back().maTableName = ScGlobal::pCharClass->upper(rTabName);
-+
-+    for (SCTAB i = 1; i < nTabSpan + 1; ++i)
-+    {
-+        String aTabName;
-+        if (!pSrcDoc->GetName(nTab1 + 1, aTabName))
-+            // source document doesn't have any table by the specified name.
-+            break;
-+
-+        aCacheData.push_back(ScExternalRefCache::SingleRangeData());
-+        aCacheData.back().maTableName = ScGlobal::pCharClass->upper(aTabName);
-+    }
-+
-+    aRange.aStart.SetTab(nTab1);
-+    aRange.aEnd.SetTab(nTab1 + nTabSpan);
-+
-+    pArray.reset(lcl_convertToTokenArray(pSrcDoc, aRange, aCacheData));
-+    rRange = aRange;
-+    rCacheData.swap(aCacheData);
-+    return pArray;
-+}
-+
-+ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokensFromSrcDoc(
-+    sal_uInt16 nFileId, const ScDocument* pSrcDoc, String& rName)
-+{
-     ScRangeName* pExtNames = pSrcDoc->GetRangeName();
-     String aUpperName = ScGlobal::pCharClass->upper(rName);
-     USHORT n;
-@@ -1896,55 +2012,37 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(sal_u
-             pNew->AddToken(*pToken);
-     }
- 
--    // Make sure to pass the correctly-cased range name here.
--    maRefCache.setRangeNameTokens(nFileId, pRangeData->GetName(), pNew);
-+    rName = pRangeData->GetName(); // Get the correctly-cased name.
-     return pNew;
- }
- 
--void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
-+const ScDocument* ScExternalRefManager::getInMemorySrcDocument(sal_uInt16 nFileId)
- {
--    RefCellMap::iterator itrFile = maRefCells.find(nFileId);
--    if (itrFile == maRefCells.end())
--        return;
--
--    RefCellSet& rRefCells = itrFile->second;
--    for_each(rRefCells.begin(), rRefCells.end(), UpdateFormulaCell());
--
--    ScViewData* pViewData = ScDocShell::GetViewData();
--    if (!pViewData)
--        return;
--
--    ScTabViewShell* pVShell = pViewData->GetViewShell();
--    if (!pVShell)
--        return;
--
--    // Repainting the grid also repaints the texts, but is there a better way
--    // to refresh texts?
--    pVShell->Invalidate(FID_REPAINT);
--    pVShell->PaintGrid();
--}
-+    const String* pFileName = getExternalFileName(nFileId);
-+    if (!pFileName)
-+        return NULL;
- 
--void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell)
--{
--    RefCellMap::iterator itr = maRefCells.find(nFileId);
--    if (itr == maRefCells.end())
-+    TypeId aType(TYPE(ScDocShell));
-+    ScDocShell* pShell = static_cast<ScDocShell*>(SfxObjectShell::GetFirst(&aType, false));
-+    while (pShell)
-     {
--        RefCellSet aRefCells;
--        pair<RefCellMap::iterator, bool> r = maRefCells.insert(
--            RefCellMap::value_type(nFileId, aRefCells));
--        if (!r.second)
--            // insertion failed.
--            return;
--
--        itr = r.first;
-+        SfxMedium* pMedium = pShell->GetMedium();
-+        if (pMedium)
-+        {
-+            String aName = pMedium->GetName();
-+            // TODO: We should make the case sensitivity platform dependent.
-+            if (pFileName->EqualsIgnoreCaseAscii(aName))
-+            {
-+                // Found !
-+                return pShell->GetDocument();
-+            }
-+        }
-+        pShell = static_cast<ScDocShell*>(SfxObjectShell::GetNext(*pShell, &aType, false));
-     }
--
--    ScBaseCell* pCell = mpDoc->GetCell(rCell);
--    if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
--        itr->second.insert(static_cast<ScFormulaCell*>(pCell));
-+    return NULL;
- }
- 
--ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
-+const ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
- {
-     if (!mpDoc->IsExecuteLinkEnabled())
-         return NULL;
-@@ -2414,7 +2512,7 @@ void ScExternalRefManager::purgeStaleSrcDocument(sal_Int32 nTimeOut)
-         maSrcDocTimer.Stop();
- }
- 
--sal_uInt32 ScExternalRefManager::getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, ScDocument* pSrcDoc)
-+sal_uInt32 ScExternalRefManager::getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc)
- {
-     NumFmtMap::iterator itr = maNumFormatMap.find(nFileId);
-     if (itr == maNumFormatMap.end())


More information about the ooo-build-commit mailing list