[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Thu Feb 6 06:37:41 PST 2014


 sc/inc/column.hxx                          |   17 +-
 sc/inc/compiler.hxx                        |   10 +
 sc/inc/formulacell.hxx                     |   21 ++-
 sc/inc/rangenam.hxx                        |   15 +-
 sc/inc/table.hxx                           |   17 +-
 sc/inc/tokenstringcontext.hxx              |   19 +++
 sc/source/core/data/column.cxx             |   48 ++++----
 sc/source/core/data/column2.cxx            |   46 ++++---
 sc/source/core/data/documen2.cxx           |    4 
 sc/source/core/data/documen4.cxx           |   13 +-
 sc/source/core/data/document.cxx           |   16 +-
 sc/source/core/data/formulacell.cxx        |  172 +++++++++++++++++++++++++----
 sc/source/core/data/table2.cxx             |   20 +--
 sc/source/core/data/table4.cxx             |   20 ++-
 sc/source/core/tool/compiler.cxx           |   36 ++++++
 sc/source/core/tool/rangenam.cxx           |   11 +
 sc/source/core/tool/tokenstringcontext.cxx |   43 +++++++
 17 files changed, 410 insertions(+), 118 deletions(-)

New commits:
commit 99a835ca644d69241cba9d7e4c4a315a4a3ea652
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Feb 4 10:19:47 2014 -0500

    fdo#74516: Avoid excessive building of escaped sheet names.
    
    The old code would build an array of escaped sheet names for all sheets
    on evevery invokation of ScCompiler, which unfortunately slowed down these
    "compile all formula cells" type methods, such as CompileAll(), CompileXML()
    etc.  Let's avoid that and build or re-build the list only when necessary.
    
    Conflicts:
    	sc/inc/column.hxx
    	sc/inc/table.hxx
    	sc/source/core/data/document.cxx
    	sc/source/core/tool/compiler.cxx
    
    Change-Id: Iabf7c2374b728b6701da3aae7835cca2157f6c96
    Reviewed-on: https://gerrit.libreoffice.org/7861
    Reviewed-by: Fridrich Strba <fridrich at documentfoundation.org>
    Tested-by: Fridrich Strba <fridrich at documentfoundation.org>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 414f40d..9eef085 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -56,6 +56,7 @@ struct RefUpdateMoveTabContext;
 class EditTextIterator;
 struct NoteEntry;
 class DocumentStreamAccess;
+class CompileFormulaContext;
 
 }
 
@@ -321,11 +322,11 @@ public:
     void        SetDirtyAfterLoad();
     void        SetTableOpDirty( const ScRange& );
     void        CalcAll();
-    void        CalcAfterLoad();
-    void        CompileAll();
-    void        CompileXML( ScProgress& rProgress );
+    void CalcAfterLoad( sc::CompileFormulaContext& rCxt );
+    void CompileAll( sc::CompileFormulaContext& rCxt );
+    void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress );
 
-    bool CompileErrorCells(sal_uInt16 nErrCode);
+    bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode );
 
     void        ResetChanged( SCROW nStartRow, SCROW nEndRow );
 
@@ -449,10 +450,10 @@ public:
     void        SetDirtyIfPostponed();
     void BroadcastRecalcOnRefMove();
 
-    void        CompileDBFormula();
-    void        CompileDBFormula( bool bCreateFormulaString );
-    void        CompileNameFormula( bool bCreateFormulaString );
-    void        CompileColRowNameFormula();
+    void CompileDBFormula( sc::CompileFormulaContext& rCxt );
+    void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
+    void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
+    void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
 
     sal_Int32   GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, rtl_TextEncoding eCharSet ) const;
     xub_StrLen  GetMaxNumberStringLen( sal_uInt16& nPrecision,
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index a8757e7..78f896e 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -78,6 +78,12 @@ class ScRangeData;
 class ScExternalRefManager;
 class ScTokenArray;
 
+namespace sc {
+
+class CompileFormulaContext;
+
+}
+
 // constants and data types internal to compiler
 
 /*
@@ -362,8 +368,12 @@ private:
     static void InitCharClassEnglish();
 
 public:
+    ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos );
+
     ScCompiler( ScDocument* pDocument, const ScAddress&);
 
+    ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos, ScTokenArray& rArr );
+
     ScCompiler( ScDocument* pDocument, const ScAddress&,ScTokenArray& rArr);
 
     virtual ~ScCompiler();
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 68c620c..e901c6e 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -44,6 +44,7 @@ struct RefUpdateContext;
 struct RefUpdateInsertTabContext;
 struct RefUpdateDeleteTabContext;
 struct RefUpdateMoveTabContext;
+class CompileFormulaContext;
 
 }
 
@@ -205,6 +206,8 @@ public:
     void            GetFormula( OUStringBuffer& rBuffer,
                                 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
 
+    OUString GetFormula( sc::CompileFormulaContext& rCxt ) const;
+
     void            SetDirty( bool bDirtyFlag=true );
     void            SetDirtyVar();
     // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
@@ -221,9 +224,13 @@ public:
     void            Compile(const OUString& rFormula,
                             bool bNoListening = false,
                             const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT );
-    void            CompileTokenArray( bool bNoListening = false );
-    void            CompileXML( ScProgress& rProgress );        // compile temporary string tokens
-    void            CalcAfterLoad();
+    void Compile(
+        sc::CompileFormulaContext& rCxt, const OUString& rFormula, bool bNoListening = false );
+
+    void CompileTokenArray( bool bNoListening = false );
+    void CompileTokenArray( sc::CompileFormulaContext& rCxt, bool bNoListening = false );
+    void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress );        // compile temporary string tokens
+    void CalcAfterLoad( sc::CompileFormulaContext& rCxt );
     bool            MarkUsedExternalReferences();
     void            Interpret();
     bool IsIterCell() const;
@@ -285,10 +292,10 @@ public:
 
     bool            IsRunning() const;
     void            SetRunning( bool bVal );
-    void            CompileDBFormula();
-    void            CompileDBFormula( bool bCreateFormulaString );
-    void            CompileNameFormula( bool bCreateFormulaString );
-    void            CompileColRowNameFormula();
+    void CompileDBFormula( sc::CompileFormulaContext& rCxt );
+    void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
+    void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
+    void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
     ScFormulaCell*  GetPrevious() const;
     ScFormulaCell*  GetNext() const;
     void            SetPrevious( ScFormulaCell* pF );
diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx
index 6113709..5d4aebe 100644
--- a/sc/inc/rangenam.hxx
+++ b/sc/inc/rangenam.hxx
@@ -35,10 +35,13 @@ class ScDocument;
 class ScTokenArray;
 
 namespace sc {
-    struct RefUpdateContext;
-    struct RefUpdateInsertTabContext;
-    struct RefUpdateDeleteTabContext;
-    struct RefUpdateMoveTabContext;
+
+struct RefUpdateContext;
+struct RefUpdateInsertTabContext;
+struct RefUpdateDeleteTabContext;
+struct RefUpdateMoveTabContext;
+class CompileFormulaContext;
+
 }
 
 typedef sal_uInt16 RangeType;
@@ -151,7 +154,7 @@ public:
     SCROW GetMaxRow() const;
     SCCOL GetMaxCol() const;
 
-    void            CompileUnresolvedXML();
+    void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt );
 
 #if DEBUG_FORMULA_COMPILER
     void Dump() const;
@@ -201,7 +204,7 @@ public:
     /** Compile those names that couldn't be resolved during loading and
         inserting because they may have referred a name that was inserted later.
      */
-    void CompileUnresolvedXML();
+    void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt );
 
     SC_DLLPUBLIC const_iterator begin() const;
     SC_DLLPUBLIC const_iterator end() const;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index f067658..3049698 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -68,6 +68,7 @@ struct RefUpdateDeleteTabContext;
 struct RefUpdateMoveTabContext;
 struct NoteEntry;
 class DocumentStreamAccess;
+class CompileFormulaContext;
 
 }
 
@@ -509,11 +510,11 @@ public:
     void        SetDirtyVar();
     void        SetTableOpDirty( const ScRange& );
     void        CalcAll();
-    void        CalcAfterLoad();
-    void        CompileAll();
-    void        CompileXML( ScProgress& rProgress );
+    void CalcAfterLoad( sc::CompileFormulaContext& rCxt );
+    void CompileAll( sc::CompileFormulaContext& rCxt );
+    void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress );
 
-    bool CompileErrorCells(sal_uInt16 nErrCode);
+    bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode );
 
     void UpdateReference(
         sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc = NULL,
@@ -986,10 +987,10 @@ private:
                                     const ScMarkData& rMark) const;
     bool        GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const;
     bool        TestTabRefAbs(SCTAB nTable) const;
-    void        CompileDBFormula();
-    void        CompileDBFormula( bool bCreateFormulaString );
-    void        CompileNameFormula( bool bCreateFormulaString );
-    void        CompileColRowNameFormula();
+    void CompileDBFormula( sc::CompileFormulaContext& rCxt );
+    void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
+    void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
+    void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
     void        RebuildFormulaGroups();
 
     void        StartListening( const ScAddress& rAddress, SvtListener* pListener );
diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx
index 85b61f7..3740f60 100644
--- a/sc/inc/tokenstringcontext.hxx
+++ b/sc/inc/tokenstringcontext.hxx
@@ -46,6 +46,25 @@ struct SC_DLLPUBLIC TokenStringContext
     TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram );
 };
 
+class CompileFormulaContext
+{
+    ScDocument* mpDoc;
+    formula::FormulaGrammar::Grammar meGram;
+    std::vector<OUString> maTabNames;
+
+    void updateTabNames();
+
+public:
+    CompileFormulaContext( ScDocument* pDoc );
+
+    formula::FormulaGrammar::Grammar getGrammar() const;
+    void setGrammar( formula::FormulaGrammar::Grammar eGram );
+
+    const std::vector<OUString>& getTabNames() const;
+
+    ScDocument* getDoc();
+};
+
 }
 
 #endif
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 7771f0e..0b10328 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2836,24 +2836,30 @@ struct CalcAllHandler
     }
 };
 
-struct CompileAllHandler
+class CompileAllHandler
 {
+    sc::CompileFormulaContext& mrCxt;
+public:
+    CompileAllHandler( sc::CompileFormulaContext& rCxt ) : mrCxt(rCxt) {}
+
     void operator() (size_t /*nRow*/, ScFormulaCell* pCell)
     {
         // for unconditional compilation
         // bCompile=true and pCode->nError=0
         pCell->GetCode()->SetCodeError(0);
         pCell->SetCompile(true);
-        pCell->CompileTokenArray();
+        pCell->CompileTokenArray(mrCxt);
     }
 };
 
 class CompileXMLHandler
 {
+    sc::CompileFormulaContext& mrCxt;
     ScProgress& mrProgress;
     const ScColumn& mrCol;
 public:
-    CompileXMLHandler(ScProgress& rProgress, const ScColumn& rCol) :
+    CompileXMLHandler( sc::CompileFormulaContext& rCxt, ScProgress& rProgress, const ScColumn& rCol) :
+        mrCxt(rCxt),
         mrProgress(rProgress),
         mrCol(rCol) {}
 
@@ -2865,23 +2871,24 @@ public:
         else
             pCell->SetDirtyVar();
 
-        pCell->CompileXML(mrProgress);
+        pCell->CompileXML(mrCxt, mrProgress);
     }
 };
 
 class CompileErrorCellsHandler
 {
+    sc::CompileFormulaContext& mrCxt;
     ScColumn& mrColumn;
     sc::CellStoreType::iterator miPos;
     sal_uInt16 mnErrCode;
     FormulaGrammar::Grammar meGram;
     bool mbCompiled;
 public:
-    CompileErrorCellsHandler(ScColumn& rColumn, sal_uInt16 nErrCode, FormulaGrammar::Grammar eGram) :
+    CompileErrorCellsHandler( sc::CompileFormulaContext& rCxt, ScColumn& rColumn, sal_uInt16 nErrCode ) :
+        mrCxt(rCxt),
         mrColumn(rColumn),
         miPos(mrColumn.GetCellStore().begin()),
         mnErrCode(nErrCode),
-        meGram(eGram),
         mbCompiled(false)
     {
     }
@@ -2901,9 +2908,8 @@ public:
         miPos = aPos.first;
         sc::SharedFormulaUtil::unshareFormulaCell(aPos, *pCell);
         pCell->GetCode()->SetCodeError(0);
-        OUStringBuffer aBuf;
-        pCell->GetFormula(aBuf, meGram);
-        pCell->Compile(aBuf.makeStringAndClear(), false, meGram);
+        OUString aFormula = pCell->GetFormula(mrCxt);
+        pCell->Compile(mrCxt, aFormula, false);
         mrColumn.JoinNewFormulaCell(aPos, *pCell);
 
         mbCompiled = true;
@@ -2912,11 +2918,15 @@ public:
     bool isCompiled() const { return mbCompiled; }
 };
 
-struct CalcAfterLoadHandler
+class CalcAfterLoadHandler
 {
+    sc::CompileFormulaContext& mrCxt;
+public:
+    CalcAfterLoadHandler( sc::CompileFormulaContext& rCxt ) : mrCxt(rCxt) {}
+
     void operator() (size_t /*nRow*/, ScFormulaCell* pCell)
     {
-        pCell->CalcAfterLoad();
+        pCell->CalcAfterLoad(mrCxt);
     }
 };
 
@@ -3165,29 +3175,29 @@ void ScColumn::CalcAll()
     sc::ProcessFormula(maCells, aFunc);
 }
 
-void ScColumn::CompileAll()
+void ScColumn::CompileAll( sc::CompileFormulaContext& rCxt )
 {
-    CompileAllHandler aFunc;
+    CompileAllHandler aFunc(rCxt);
     sc::ProcessFormula(maCells, aFunc);
 }
 
-void ScColumn::CompileXML( ScProgress& rProgress )
+void ScColumn::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress )
 {
-    CompileXMLHandler aFunc(rProgress, *this);
+    CompileXMLHandler aFunc(rCxt, rProgress, *this);
     sc::ProcessFormula(maCells, aFunc);
     RegroupFormulaCells();
 }
 
-bool ScColumn::CompileErrorCells(sal_uInt16 nErrCode)
+bool ScColumn::CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode )
 {
-    CompileErrorCellsHandler aHdl(*this, nErrCode, pDocument->GetGrammar());
+    CompileErrorCellsHandler aHdl(rCxt, *this, nErrCode);
     sc::ProcessFormula(maCells, aHdl);
     return aHdl.isCompiled();
 }
 
-void ScColumn::CalcAfterLoad()
+void ScColumn::CalcAfterLoad( sc::CompileFormulaContext& rCxt )
 {
-    CalcAfterLoadHandler aFunc;
+    CalcAfterLoadHandler aFunc(rCxt);
     sc::ProcessFormula(maCells, aFunc);
 }
 
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 6aef111..04f127f 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -3181,75 +3181,87 @@ void ScColumn::EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListe
 
 namespace {
 
-struct CompileDBFormulaHandler
+class CompileDBFormulaHandler
 {
+    sc::CompileFormulaContext& mrCxt;
+
+public:
+    CompileDBFormulaHandler( sc::CompileFormulaContext& rCxt ) :
+        mrCxt(rCxt) {}
+
     void operator() (size_t, ScFormulaCell* p)
     {
-        p->CompileDBFormula();
+        p->CompileDBFormula(mrCxt);
     }
 };
 
 class CompileDBFormula2Handler
 {
+    sc::CompileFormulaContext& mrCxt;
     bool mbCreateFormulaString;
 
 public:
-    CompileDBFormula2Handler(bool bCreateFormulaString) :
-        mbCreateFormulaString(bCreateFormulaString) {}
+    CompileDBFormula2Handler( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) :
+        mrCxt(rCxt), mbCreateFormulaString(bCreateFormulaString) {}
 
     void operator() (size_t, ScFormulaCell* p)
     {
-        p->CompileDBFormula(mbCreateFormulaString);
+        p->CompileDBFormula(mrCxt, mbCreateFormulaString);
     }
 };
 
 class CompileNameFormulaHandler
 {
+    sc::CompileFormulaContext& mrCxt;
     bool mbCreateFormulaString;
 
 public:
-    CompileNameFormulaHandler(bool bCreateFormulaString) :
-        mbCreateFormulaString(bCreateFormulaString) {}
+    CompileNameFormulaHandler( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString) :
+        mrCxt(rCxt), mbCreateFormulaString(bCreateFormulaString) {}
 
     void operator() (size_t, ScFormulaCell* p)
     {
-        p->CompileNameFormula(mbCreateFormulaString);
+        p->CompileNameFormula(mrCxt, mbCreateFormulaString);
     }
 };
 
 struct CompileColRowNameFormulaHandler
 {
+    sc::CompileFormulaContext& mrCxt;
+public:
+    CompileColRowNameFormulaHandler( sc::CompileFormulaContext& rCxt ) : mrCxt(rCxt) {}
+
     void operator() (size_t, ScFormulaCell* p)
     {
-        p->CompileColRowNameFormula();
+        p->CompileColRowNameFormula(mrCxt);
     }
 };
 
 }
 
-void ScColumn::CompileDBFormula()
+void ScColumn::CompileDBFormula( sc::CompileFormulaContext& rCxt )
 {
-    CompileDBFormulaHandler aFunc;
+    CompileDBFormulaHandler aFunc(rCxt);
     sc::ProcessFormula(maCells, aFunc);
     RegroupFormulaCells();
 }
 
-void ScColumn::CompileDBFormula( bool bCreateFormulaString )
+void ScColumn::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
 {
-    CompileDBFormula2Handler aFunc(bCreateFormulaString);
+    CompileDBFormula2Handler aFunc(rCxt, bCreateFormulaString);
     sc::ProcessFormula(maCells, aFunc);
     RegroupFormulaCells();
 }
 
-void ScColumn::CompileNameFormula( bool bCreateFormulaString )
+void ScColumn::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
 {
-    CompileNameFormulaHandler aFunc(bCreateFormulaString);
+    CompileNameFormulaHandler aFunc(rCxt, bCreateFormulaString);
     sc::ProcessFormula(maCells, aFunc);
 }
 
-void ScColumn::CompileColRowNameFormula()
+void ScColumn::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt )
 {
-    CompileColRowNameFormulaHandler aFunc;
+    CompileColRowNameFormulaHandler aFunc(rCxt);
     sc::ProcessFormula(maCells, aFunc);
     RegroupFormulaCells();
 }
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index ae9cbd9..d027bb4 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -93,6 +93,7 @@
 #include "scopetools.hxx"
 #include "formulagroup.hxx"
 #include "documentlinkmgr.hxx"
+#include <tokenstringcontext.hxx>
 
 using namespace com::sun::star;
 
@@ -1018,7 +1019,8 @@ sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
 
             // Readjust self-contained absolute references to this sheet
             maTabs[nDestPos]->TestTabRefAbs(nSrcPos);
-            maTabs[nDestPos]->CompileAll();
+            sc::CompileFormulaContext aFormulaCxt(this);
+            maTabs[nDestPos]->CompileAll(aFormulaCxt);
         }
 
         SetNoListening( false );
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index ed49696..fb45385 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -44,6 +44,7 @@
 #include "formulacell.hxx"
 #include "tokenarray.hxx"
 #include "scmatrix.hxx"
+#include <tokenstringcontext.hxx>
 
 using namespace formula;
 
@@ -538,41 +539,45 @@ bool ScDocument::ReplaceStyle(const SvxSearchItem& rSearchItem,
 
 void ScDocument::CompileDBFormula()
 {
+    sc::CompileFormulaContext aCxt(this);
     TableContainer::iterator it = maTabs.begin();
     for (;it != maTabs.end(); ++it)
     {
         if (*it)
-            (*it)->CompileDBFormula();
+            (*it)->CompileDBFormula(aCxt);
     }
 }
 
 void ScDocument::CompileDBFormula( bool bCreateFormulaString )
 {
+    sc::CompileFormulaContext aCxt(this);
     TableContainer::iterator it = maTabs.begin();
     for (;it != maTabs.end(); ++it)
     {
         if (*it)
-            (*it)->CompileDBFormula( bCreateFormulaString );
+            (*it)->CompileDBFormula(aCxt, bCreateFormulaString);
     }
 }
 
 void ScDocument::CompileNameFormula( bool bCreateFormulaString )
 {
+    sc::CompileFormulaContext aCxt(this);
     TableContainer::iterator it = maTabs.begin();
     for (;it != maTabs.end(); ++it)
     {
         if (*it)
-            (*it)->CompileNameFormula( bCreateFormulaString );
+            (*it)->CompileNameFormula(aCxt, bCreateFormulaString);
     }
 }
 
 void ScDocument::CompileColRowNameFormula()
 {
+    sc::CompileFormulaContext aCxt(this);
     TableContainer::iterator it = maTabs.begin();
     for (;it != maTabs.end(); ++it)
     {
         if (*it)
-            (*it)->CompileColRowNameFormula();
+            (*it)->CompileColRowNameFormula(aCxt);
     }
 }
 
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 6bbe835..99192e4 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -95,6 +95,7 @@
 #include "scopetools.hxx"
 #include "refupdatecontext.hxx"
 #include "formulagroup.hxx"
+#include <tokenstringcontext.hxx>
 
 #include "formula/vectortoken.hxx"
 
@@ -3644,10 +3645,11 @@ void ScDocument::CalcAll()
 
 void ScDocument::CompileAll()
 {
+    sc::CompileFormulaContext aCxt(this);
     TableContainer::iterator it = maTabs.begin();
     for (; it != maTabs.end(); ++it)
         if (*it)
-            (*it)->CompileAll();
+            (*it)->CompileAll(aCxt);
     SetDirty();
 }
 
@@ -3659,17 +3661,19 @@ void ScDocument::CompileXML()
     ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(
                 STR_PROGRESS_CALCULATING ), GetXMLImportedFormulaCount() );
 
+    sc::CompileFormulaContext aCxt(this);
+
     // set AutoNameCache to speed up automatic name lookup
     OSL_ENSURE( !pAutoNameCache, "AutoNameCache already set" );
     pAutoNameCache = new ScAutoNameCache( this );
 
     if (pRangeName)
-        pRangeName->CompileUnresolvedXML();
+        pRangeName->CompileUnresolvedXML(aCxt);
 
     TableContainer::iterator it = maTabs.begin();
     for (; it != maTabs.end(); ++it)
         if (*it)
-            (*it)->CompileXML( aProgress );
+            (*it)->CompileXML(aCxt, aProgress);
 
     DELETEZ( pAutoNameCache );  // valid only during CompileXML, where cell contents don't change
 
@@ -3682,6 +3686,7 @@ void ScDocument::CompileXML()
 bool ScDocument::CompileErrorCells(sal_uInt16 nErrCode)
 {
     bool bCompiled = false;
+    sc::CompileFormulaContext aCxt(this);
     TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
     for (; it != itEnd; ++it)
     {
@@ -3689,7 +3694,7 @@ bool ScDocument::CompileErrorCells(sal_uInt16 nErrCode)
         if (!pTab)
             continue;
 
-        if (pTab->CompileErrorCells(nErrCode))
+        if (pTab->CompileErrorCells(aCxt, nErrCode))
             bCompiled = true;
     }
 
@@ -3702,11 +3707,12 @@ void ScDocument::CalcAfterLoad()
         return;     // dann wird erst beim Einfuegen in das richtige Doc berechnet
 
     bCalcingAfterLoad = true;
+    sc::CompileFormulaContext aCxt(this);
     {
         TableContainer::iterator it = maTabs.begin();
         for (; it != maTabs.end(); ++it)
             if (*it)
-                (*it)->CalcAfterLoad();
+                (*it)->CalcAfterLoad(aCxt);
         for (it = maTabs.begin(); it != maTabs.end(); ++it)
             if (*it)
                 (*it)->SetDirtyAfterLoad();
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index cad2144..7d1dff1 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -50,6 +50,7 @@
 #include "types.hxx"
 #include "scopetools.hxx"
 #include "refupdatecontext.hxx"
+#include <tokenstringcontext.hxx>
 
 #include <boost/scoped_ptr.hpp>
 
@@ -882,6 +883,62 @@ void ScFormulaCell::GetFormula( OUString& rFormula, const FormulaGrammar::Gramma
     rFormula = rBuffer.makeStringAndClear();
 }
 
+OUString ScFormulaCell::GetFormula( sc::CompileFormulaContext& rCxt ) const
+{
+    OUStringBuffer aBuf;
+    if (pCode->GetCodeError() && !pCode->GetLen())
+    {
+        aBuf = OUStringBuffer( ScGlobal::GetErrorString( pCode->GetCodeError()));
+        return aBuf.makeStringAndClear();
+    }
+    else if( cMatrixFlag == MM_REFERENCE )
+    {
+        // Reference to another cell that contains a matrix formula.
+        pCode->Reset();
+        ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
+        if( p )
+        {
+            /* FIXME: original GetFormula() code obtained
+             * pCell only if (!this->IsInChangeTrack()),
+             * GetEnglishFormula() omitted that test.
+             * Can we live without in all cases? */
+            ScFormulaCell* pCell = NULL;
+            ScSingleRefData& rRef = p->GetSingleRef();
+            ScAddress aAbs = rRef.toAbs(aPos);
+            if (ValidAddress(aAbs))
+                pCell = pDocument->GetFormulaCell(aAbs);
+
+            if (pCell)
+            {
+                return pCell->GetFormula(rCxt);
+            }
+            else
+            {
+                ScCompiler aComp(rCxt, aPos, *pCode);
+                aComp.CreateStringFromTokenArray(aBuf);
+            }
+        }
+        else
+        {
+            OSL_FAIL("ScFormulaCell::GetFormula: not a matrix");
+        }
+    }
+    else
+    {
+        ScCompiler aComp(rCxt, aPos, *pCode);
+        aComp.CreateStringFromTokenArray(aBuf);
+    }
+
+    aBuf.insert( 0, '=');
+    if( cMatrixFlag )
+    {
+        aBuf.insert( 0, '{');
+        aBuf.append( '}');
+    }
+
+    return aBuf.makeStringAndClear();
+}
+
 void ScFormulaCell::GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows )
 {
     MaybeInterpret();
@@ -940,6 +997,40 @@ void ScFormulaCell::Compile( const OUString& rFormula, bool bNoListening,
         pDocument->PutInFormulaTree( this );
 }
 
+void ScFormulaCell::Compile(
+    sc::CompileFormulaContext& rCxt, const OUString& rFormula, bool bNoListening )
+{
+    if ( pDocument->IsClipOrUndo() )
+        return;
+    bool bWasInFormulaTree = pDocument->IsInFormulaTree( this );
+    if ( bWasInFormulaTree )
+        pDocument->RemoveFromFormulaTree( this );
+    // pCode may not deleted for queries, but must be empty
+    if ( pCode )
+        pCode->Clear();
+    ScTokenArray* pCodeOld = pCode;
+    ScCompiler aComp(rCxt, aPos);
+    pCode = aComp.CompileString( rFormula );
+    if ( pCodeOld )
+        delete pCodeOld;
+    if( !pCode->GetCodeError() )
+    {
+        if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() && rFormula == aResult.GetHybridFormula() )
+        {   // not recursive CompileTokenArray/Compile/CompileTokenArray
+            if ( rFormula[0] == '=' )
+                pCode->AddBad( rFormula.copy(1) );
+            else
+                pCode->AddBad( rFormula );
+        }
+        bCompile = true;
+        CompileTokenArray(rCxt, bNoListening);
+    }
+    else
+        bChanged = true;
+
+    if ( bWasInFormulaTree )
+        pDocument->PutInFormulaTree( this );
+}
 
 void ScFormulaCell::CompileTokenArray( bool bNoListening )
 {
@@ -981,8 +1072,47 @@ void ScFormulaCell::CompileTokenArray( bool bNoListening )
     }
 }
 
+void ScFormulaCell::CompileTokenArray( sc::CompileFormulaContext& rCxt, bool bNoListening )
+{
+    // Not already compiled?
+    if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
+    {
+        rCxt.setGrammar(eTempGrammar);
+        Compile(rCxt, aResult.GetHybridFormula(), bNoListening);
+    }
+    else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() )
+    {
+        // RPN length may get changed
+        bool bWasInFormulaTree = pDocument->IsInFormulaTree( this );
+        if ( bWasInFormulaTree )
+            pDocument->RemoveFromFormulaTree( this );
+
+        // Loading from within filter? No listening yet!
+        if( pDocument->IsInsertingFromOtherDoc() )
+            bNoListening = true;
 
-void ScFormulaCell::CompileXML( ScProgress& rProgress )
+        if( !bNoListening && pCode->GetCodeLen() )
+            EndListeningTo( pDocument );
+        ScCompiler aComp(rCxt, aPos, *pCode);
+        bSubTotal = aComp.CompileTokenArray();
+        if( !pCode->GetCodeError() )
+        {
+            nFormatType = aComp.GetNumFormatType();
+            bChanged = true;
+            aResult.SetToken( NULL);
+            bCompile = false;
+            if ( !bNoListening )
+                StartListeningTo( pDocument );
+        }
+        if ( bWasInFormulaTree )
+            pDocument->PutInFormulaTree( this );
+
+        if (bSubTotal)
+            pDocument->AddSubTotalCell(this);
+    }
+}
+
+void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress )
 {
     if ( cMatrixFlag == MM_REFERENCE )
     {   // is already token code via ScDocFunc::EnterMatrix, ScDocument::InsertMatrixFormula
@@ -996,8 +1126,8 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
     bool bWasInFormulaTree = pDocument->IsInFormulaTree( this);
     if (bWasInFormulaTree)
         pDocument->RemoveFromFormulaTree( this);
-    ScCompiler aComp( pDocument, aPos, *pCode);
-    aComp.SetGrammar(eTempGrammar);
+    rCxt.setGrammar(eTempGrammar);
+    ScCompiler aComp(rCxt, aPos, *pCode);
     OUString aFormula, aFormulaNmsp;
     aComp.CreateStringFromXMLTokenArray( aFormula, aFormulaNmsp );
     pDocument->DecXMLImportedFormulaCount( aFormula.getLength() );
@@ -1051,13 +1181,14 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
 }
 
 
-void ScFormulaCell::CalcAfterLoad()
+void ScFormulaCell::CalcAfterLoad( sc::CompileFormulaContext& rCxt )
 {
     bool bNewCompiled = false;
     // If a Calc 1.0-doc is read, we have a result, but no token array
     if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
     {
-        Compile( aResult.GetHybridFormula(), true, eTempGrammar);
+        rCxt.setGrammar(eTempGrammar);
+        Compile(rCxt, aResult.GetHybridFormula(), true);
         aResult.SetToken( NULL);
         bDirty = true;
         bNewCompiled = true;
@@ -1065,8 +1196,7 @@ void ScFormulaCell::CalcAfterLoad()
     // The RPN array is not created when a Calc 3.0-Doc has been read as the Range Names exist until now.
     if( pCode->GetLen() && !pCode->GetCodeLen() && !pCode->GetCodeError() )
     {
-        ScCompiler aComp(pDocument, aPos, *pCode);
-        aComp.SetGrammar(pDocument->GetGrammar());
+        ScCompiler aComp(rCxt, aPos, *pCode);
         bSubTotal = aComp.CompileTokenArray();
         nFormatType = aComp.GetNumFormatType();
         bDirty = true;
@@ -3213,7 +3343,7 @@ void ScFormulaCell::SetRunning( bool bVal )
     bRunning = bVal;
 }
 
-void ScFormulaCell::CompileDBFormula()
+void ScFormulaCell::CompileDBFormula( sc::CompileFormulaContext& rCxt )
 {
     for( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
     {
@@ -3221,14 +3351,14 @@ void ScFormulaCell::CompileDBFormula()
             || (p->GetOpCode() == ocName && p->GetIndex() >= SC_START_INDEX_DB_COLL) )
         {
             bCompile = true;
-            CompileTokenArray();
+            CompileTokenArray(rCxt);
             SetDirty();
             break;
         }
     }
 }
 
-void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString )
+void ScFormulaCell::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
 {
     // Two phases must be called after each other
     // 1. Formula String with old generated names
@@ -3256,8 +3386,7 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString )
         }
         if ( bRecompile )
         {
-            OUString aFormula;
-            GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+            OUString aFormula = GetFormula(rCxt);
             if ( GetMatrixFlag() != MM_NONE && !aFormula.isEmpty() )
             {
                 if ( aFormula[ aFormula.getLength()-1 ] == '}' )
@@ -3268,18 +3397,19 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString )
             EndListeningTo( pDocument );
             pDocument->RemoveFromFormulaTree( this );
             pCode->Clear();
-            SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+            SetHybridFormula(aFormula, rCxt.getGrammar());
         }
     }
     else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
     {
-        Compile( aResult.GetHybridFormula(), false, eTempGrammar );
+        rCxt.setGrammar(eTempGrammar);
+        Compile(rCxt, aResult.GetHybridFormula(), false);
         aResult.SetToken( NULL);
         SetDirty();
     }
 }
 
-void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString )
+void ScFormulaCell::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
 {
     // Two phases must be called after each other
     // 1. Formula String with old generated names
@@ -3303,8 +3433,7 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString )
         }
         if ( bRecompile )
         {
-            OUString aFormula;
-            GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+            OUString aFormula = GetFormula(rCxt);
             if ( GetMatrixFlag() != MM_NONE && !aFormula.isEmpty() )
             {
                 if ( aFormula[ aFormula.getLength()-1 ] == '}' )
@@ -3315,18 +3444,19 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString )
             EndListeningTo( pDocument );
             pDocument->RemoveFromFormulaTree( this );
             pCode->Clear();
-            SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
+            SetHybridFormula(aFormula, rCxt.getGrammar());
         }
     }
     else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
     {
-        Compile( aResult.GetHybridFormula(), false, eTempGrammar );
+        rCxt.setGrammar(eTempGrammar);
+        Compile(rCxt, aResult.GetHybridFormula(), false);
         aResult.SetToken( NULL);
         SetDirty();
     }
 }
 
-void ScFormulaCell::CompileColRowNameFormula()
+void ScFormulaCell::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt )
 {
     pCode->Reset();
     for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
@@ -3334,7 +3464,7 @@ void ScFormulaCell::CompileColRowNameFormula()
         if ( p->GetOpCode() == ocColRowName )
         {
             bCompile = true;
-            CompileTokenArray();
+            CompileTokenArray(rCxt);
             SetDirty();
             break;
         }
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index e81a5e2..ce0909d 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1704,44 +1704,46 @@ void ScTable::CalcAll()
 }
 
 
-void ScTable::CompileAll()
+void ScTable::CompileAll( sc::CompileFormulaContext& rCxt )
 {
-    for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CompileAll();
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].CompileAll(rCxt);
 
     if(mpCondFormatList)
         mpCondFormatList->CompileAll();
 }
 
 
-void ScTable::CompileXML( ScProgress& rProgress )
+void ScTable::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress )
 {
     if (mpRangeName)
-        mpRangeName->CompileUnresolvedXML();
+        mpRangeName->CompileUnresolvedXML(rCxt);
 
     for (SCCOL i=0; i <= MAXCOL; i++)
     {
-        aCol[i].CompileXML( rProgress );
+        aCol[i].CompileXML(rCxt, rProgress);
     }
 
     if(mpCondFormatList)
         mpCondFormatList->CompileXML();
 }
 
-bool ScTable::CompileErrorCells(sal_uInt16 nErrCode)
+bool ScTable::CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode )
 {
     bool bCompiled = false;
     for (SCCOL i = 0; i <= MAXCOL; ++i)
     {
-        if (aCol[i].CompileErrorCells(nErrCode))
+        if (aCol[i].CompileErrorCells(rCxt, nErrCode))
             bCompiled = true;
     }
 
     return bCompiled;
 }
 
-void ScTable::CalcAfterLoad()
+void ScTable::CalcAfterLoad( sc::CompileFormulaContext& rCxt )
 {
-    for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CalcAfterLoad();
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].CalcAfterLoad(rCxt);
 }
 
 bool ScTable::IsEmptyData( SCCOL nCol ) const
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index b7112bb..9a50176 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -2056,24 +2056,28 @@ bool ScTable::TestTabRefAbs(SCTAB nTable) const
     return false;
 }
 
-void ScTable::CompileDBFormula()
+void ScTable::CompileDBFormula( sc::CompileFormulaContext& rCxt )
 {
-    for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula();
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].CompileDBFormula(rCxt);
 }
 
-void ScTable::CompileDBFormula( bool bCreateFormulaString )
+void ScTable::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
 {
-    for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula( bCreateFormulaString );
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].CompileDBFormula(rCxt, bCreateFormulaString);
 }
 
-void ScTable::CompileNameFormula( bool bCreateFormulaString )
+void ScTable::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
 {
-    for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileNameFormula( bCreateFormulaString );
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].CompileNameFormula(rCxt, bCreateFormulaString);
 }
 
-void ScTable::CompileColRowNameFormula()
+void ScTable::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt )
 {
-    for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileColRowNameFormula();
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].CompileColRowNameFormula(rCxt);
 }
 
 
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index dcb676e..4a1bbd7 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -68,6 +68,7 @@
 #include "formulaparserpool.hxx"
 #include "tokenarray.hxx"
 #include "scmatrix.hxx"
+#include <tokenstringcontext.hxx>
 
 using namespace formula;
 using namespace ::com::sun::star;
@@ -1529,6 +1530,24 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
 static const ConventionXL_R1C1 ConvXL_R1C1;
 const ScCompiler::Convention * const ScCompiler::pConvXL_R1C1 = &ConvXL_R1C1;
 
+ScCompiler::ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos, ScTokenArray& rArr ) :
+    FormulaCompiler(rArr),
+    pDoc(rCxt.getDoc()),
+    aPos(rPos),
+    mpFormatter(pDoc->GetFormatTable()),
+    pCharClass(ScGlobal::pCharClass),
+    mnPredetectedReference(0),
+    mnRangeOpPosInSymbol(-1),
+    pConv(GetRefConvention(FormulaGrammar::CONV_OOO)),
+    meExtendedErrorDetection(EXTENDED_ERROR_DETECTION_NONE),
+    mbCloseBrackets(true),
+    mbRewind(false),
+    maTabNames(rCxt.getTabNames())
+{
+    nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
+    SetGrammar(rCxt.getGrammar());
+}
+
 ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArray& rArr)
         : FormulaCompiler(rArr),
         pDoc( pDocument ),
@@ -1555,6 +1574,23 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArra
     }
 }
 
+ScCompiler::ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos ) :
+    pDoc(rCxt.getDoc()),
+    aPos(rPos),
+    mpFormatter(pDoc ? pDoc->GetFormatTable() : NULL),
+    pCharClass(ScGlobal::pCharClass),
+    mnPredetectedReference(0),
+    mnRangeOpPosInSymbol(-1),
+    pConv(GetRefConvention(FormulaGrammar::CONV_OOO)),
+    meExtendedErrorDetection(EXTENDED_ERROR_DETECTION_NONE),
+    mbCloseBrackets(true),
+    mbRewind(false),
+    maTabNames(rCxt.getTabNames())
+{
+    nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
+    SetGrammar(rCxt.getGrammar());
+}
+
 ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos)
         :
         pDoc( pDocument ),
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 6130c61..5d88ee8 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -34,6 +34,7 @@
 #include "refupdat.hxx"
 #include "document.hxx"
 #include "refupdatecontext.hxx"
+#include <tokenstringcontext.hxx>
 
 #include "formula/errorcodes.hxx"
 
@@ -181,14 +182,14 @@ void ScRangeData::CompileRangeData( const OUString& rSymbol, bool bSetError )
     }
 }
 
-void ScRangeData::CompileUnresolvedXML()
+void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt )
 {
     if (pCode->GetCodeError() == errNoName)
     {
         // Reconstruct the symbol/formula and then recompile.
         OUString aSymbol;
-        ScCompiler aComp( pDoc, aPos, *pCode);
-        aComp.SetGrammar( eTempGrammar);
+        rCxt.setGrammar(eTempGrammar);
+        ScCompiler aComp(rCxt, aPos, *pCode);
         aComp.CreateStringFromTokenArray( aSymbol);
         // Don't let the compiler set an error for unknown names on final
         // compile, errors are handled by the interpreter thereafter.
@@ -764,11 +765,11 @@ void ScRangeName::UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY)
         itr->second->UpdateGrow(rArea, nGrowX, nGrowY);
 }
 
-void ScRangeName::CompileUnresolvedXML()
+void ScRangeName::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt )
 {
     DataType::iterator itr = maData.begin(), itrEnd = maData.end();
     for (; itr != itrEnd; ++itr)
-        itr->second->CompileUnresolvedXML();
+        itr->second->CompileUnresolvedXML(rCxt);
 }
 
 ScRangeName::const_iterator ScRangeName::begin() const
diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx
index a68ae75..203d36a 100644
--- a/sc/source/core/tool/tokenstringcontext.cxx
+++ b/sc/source/core/tool/tokenstringcontext.cxx
@@ -105,6 +105,49 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula
     }
 }
 
+CompileFormulaContext::CompileFormulaContext( ScDocument* pDoc ) :
+    mpDoc(pDoc), meGram(pDoc->GetGrammar())
+{
+    if (!pDoc)
+        return;
+
+    updateTabNames();
+}
+
+void CompileFormulaContext::updateTabNames()
+{
+    // Fetch all sheet names.
+    maTabNames = mpDoc->GetAllTableNames();
+    {
+        std::vector<OUString>::iterator it = maTabNames.begin(), itEnd = maTabNames.end();
+        for (; it != itEnd; ++it)
+            ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(meGram));
+    }
+}
+
+formula::FormulaGrammar::Grammar CompileFormulaContext::getGrammar() const
+{
+    return meGram;
+}
+
+void CompileFormulaContext::setGrammar( formula::FormulaGrammar::Grammar eGram )
+{
+    bool bUpdate = (meGram != eGram);
+    meGram = eGram;
+    if (bUpdate)
+        updateTabNames();
+}
+
+const std::vector<OUString>& CompileFormulaContext::getTabNames() const
+{
+    return maTabNames;
+}
+
+ScDocument* CompileFormulaContext::getDoc()
+{
+    return mpDoc;
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list