[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 87 commits - basctl/source bean/Library_officebean.mk chart2/Module_chart2.mk chart2/qa chart2/source chart2/UI_chart2.mk chart2/uiconfig comphelper/inc comphelper/source compilerplugins/clang compilerplugins/Makefile-clang.mk config_host/config_features.h.in configure.ac connectivity/Module_connectivity.mk connectivity/source dbaccess/source desktop/Executable_unopkg.com.mk desktop/Executable_unopkg.mk desktop/source desktop/StaticLibrary_winextendloaderenv.mk dictionaries drawinglayer/inc drawinglayer/source dtrans/StaticLibrary_dtobj.mk embedserv/Library_inprocserv.mk forms/source helpcontent2 i18npool/CustomTarget_localedata.mk i18npool/inc i18npool/source l10ntools/source Library_merged.mk lingucomponent/StaticLibrary_ulingu.mk oox/source reportdesign/Module_reportdesign.mk RepositoryModule_host.mk sal/inc sal/Library_uwinapi.mk sax/StaticLibrary_sax_shared.mk sc/inc sc/Library_sc.mk sc/qa sc/source sdext/StaticLi brary_pdfimport_s.mk sd/source sfx2/source solenv/bin solenv/gbuild sw/qa sw/source tools/README tools/StaticLibrary_ooopathutils.mk vcl/inc vcl/source vcl/StaticLibrary_vclmain.mk vcl/unx writerfilter/source writerperfect/StaticLibrary_writerperfect.mk

Kohei Yoshida kohei.yoshida at gmail.com
Thu Mar 28 14:02:44 PDT 2013


Rebased ref, commits from common ancestor:
commit 00ca3ed129e23d8a08f577efc1e4225bf248dbaf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Mar 28 16:13:57 2013 -0400

    Forgot to remove this from ScValueCell.
    
    Change-Id: I9cbc3cc7dc22d9b8a8ca01037fa976ee563c156e

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index a42b0722..1384c2b 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -117,7 +117,7 @@ private:
                     ScNoteCell( const ScNoteCell& );
 };
 
-class SC_DLLPUBLIC ScValueCell : public ScBaseCell
+class ScValueCell : public ScBaseCell
 {
 public:
 #ifdef USE_MEMPOOL
commit ae227f90adea1244f3e8509d095918a86b9a0926
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Mar 28 16:09:02 2013 -0400

    Remove GetErrorCode() from ScBaseCell; only relevant for ScFormulaCell.
    
    Change-Id: I5c41fc88bf138411ded334f823ab6187401c96df

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 60a70f5..a42b0722 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -80,8 +80,6 @@ public:
     /** Deletes the own cell broadcaster. */
     void            DeleteBroadcaster();
 
-    /** Error code if ScFormulaCell, else 0. */
-    sal_uInt16          GetErrorCode() const;
     /** ScFormulaCell with formula::svEmptyCell result, or ScNoteCell (may have been
         created due to reference to empty cell). */
     bool            HasEmptyData() const;
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index aa6e2a2..3862e88 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -141,18 +141,6 @@ void ScBaseCell::DeleteBroadcaster()
     DELETEZ( mpBroadcaster );
 }
 
-sal_uInt16 ScBaseCell::GetErrorCode() const
-{
-    switch ( eCellType )
-    {
-        case CELLTYPE_FORMULA :
-            return ((ScFormulaCell*)this)->GetErrCode();
-        default:
-            return 0;
-    }
-}
-
-
 bool ScBaseCell::HasEmptyData() const
 {
     switch ( eCellType )
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 5b18f3c..0aa3b17 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1391,7 +1391,7 @@ void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol
                 if (rCell.GetDirty() && pDocument->GetAutoCalc())
                     rCell.Interpret();
 
-                if (rCell.GetErrorCode())
+                if (rCell.GetErrCode())
                     // Skip cells with error.
                     break;
 
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 13bbec7..0a1e4b0 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1229,14 +1229,15 @@ public:
     }
 
     bool isQueryByValue(
-        const ScQueryEntry::Item& rItem, SCCOL nCol, SCROW nRow, const ScBaseCell* pCell)
+        const ScQueryEntry::Item& rItem, SCCOL nCol, SCROW nRow, ScBaseCell* pCell)
     {
         if (rItem.meType == ScQueryEntry::ByString)
             return false;
 
         if (pCell)
         {
-            if (pCell->GetErrorCode())
+            if (pCell->GetCellType() == CELLTYPE_FORMULA &&
+                static_cast<ScFormulaCell*>(pCell)->GetErrCode())
                 // Error values are compared as string.
                 return false;
 
@@ -1361,10 +1362,10 @@ public:
 
         if ( pCell )
         {
-            if (pCell->GetCellType() == CELLTYPE_FORMULA && pCell->GetErrorCode())
+            if (pCell->GetCellType() == CELLTYPE_FORMULA && static_cast<ScFormulaCell*>(pCell)->GetErrCode())
             {
                 // Error cell is evaluated as string (for now).
-                aCellStr = ScGlobal::GetErrorString(pCell->GetErrorCode());
+                aCellStr = ScGlobal::GetErrorString(static_cast<ScFormulaCell*>(pCell)->GetErrCode());
             }
             else if (pCell->GetCellType() != CELLTYPE_NOTE)
             {
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 6247e51..e24fc66 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -192,7 +192,7 @@ double ScInterpreter::GetValueCellValue( const ScAddress& rPos, double fOrig )
 
 sal_uInt16 ScInterpreter::GetCellErrCode( const ScRefCellValue& rCell )
 {
-    return rCell.meType == CELLTYPE_FORMULA ? rCell.mpFormula->GetErrorCode() : 0;
+    return rCell.meType == CELLTYPE_FORMULA ? rCell.mpFormula->GetErrCode() : 0;
 }
 
 /** Convert string content to numeric value.
commit 0106deffedee8345a0fafcae0a86b6f52fad8c45
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Mar 28 15:52:57 2013 -0400

    Remove some headers in cell.hxx.
    
    Change-Id: Ic99967a3ef6a35ca4fc465054e0d4de512cafb43

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 217cfab..60a70f5 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -20,23 +20,12 @@
 #ifndef SC_CELL_HXX
 #define SC_CELL_HXX
 
-#include <stddef.h>
+#include "scdllapi.h"
+#include "global.hxx"
 
-#include <set>
-#include <vector>
-#include <boost/shared_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
+#include "tools/mempool.hxx"
 
-#include <tools/mempool.hxx>
-#include <svl/listener.hxx>
-#include "global.hxx"
-#include "rangenam.hxx"
-#include "formula/grammar.hxx"
-#include "tokenarray.hxx"
-#include "formularesult.hxx"
-#include <rtl/ustrbuf.hxx>
-#include <unotools/fontcvt.hxx>
-#include "scdllapi.h"
+#include <boost/shared_ptr.hpp>
 
 #define USE_MEMPOOL
 
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 8bdcbc0..45a708d 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -21,7 +21,14 @@
 #define SC_FORMULACELL_HXX
 
 #include "cell.hxx"
+#include "formularesult.hxx"
 
+#include "formula/tokenarray.hxx"
+#include "svl/listener.hxx"
+
+#include <set>
+
+class ScTokenArray;
 struct ScSimilarFormulaDelta;
 
 struct SC_DLLPUBLIC ScFormulaCellGroup
@@ -276,9 +283,9 @@ public:
     void            SetResultDouble( double n )     { aResult.SetDouble( n); }
 
     void            SetErrCode( sal_uInt16 n );
-    inline bool     IsHyperLinkCell() const { return pCode && pCode->IsHyperLink(); }
+    bool IsHyperLinkCell() const;
     EditTextObject* CreateURLObject();
-    void            GetURLResult( rtl::OUString& rURL, rtl::OUString& rCellText );
+    void GetURLResult( OUString& rURL, OUString& rCellText );
 
     /** Determines whether or not the result string contains more than one paragraph */
     bool            IsMultilineResult();
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index c287f10..c3a333c 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -15,6 +15,7 @@
 #include "editeng/editstat.hxx"
 #include "stringutil.hxx"
 #include "editutil.hxx"
+#include "tokenarray.hxx"
 #include "formula/token.hxx"
 
 namespace {
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index c046192..5b18f3c 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -32,6 +32,7 @@
 #include "postit.hxx"
 #include "globalnames.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 #include <svl/poolcach.hxx>
 #include <svl/zforlist.hxx>
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 2e878e2..afd0cff 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -55,6 +55,7 @@
 #include "segmenttree.hxx"
 #include "docparam.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 #include <math.h>
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index bd7586e..06472a4 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -47,6 +47,7 @@
 #include "docpool.hxx"
 #include "globalnames.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 #include <com/sun/star/i18n/LocaleDataItem.hpp>
 
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 237c7f0..be84d58 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -38,6 +38,7 @@
 #include "colorscale.hxx"
 #include "cellvalue.hxx"
 #include "editutil.hxx"
+#include "tokenarray.hxx"
 
 using namespace formula;
 //------------------------------------------------------------------------
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 6dfad05..ea13837 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -43,6 +43,7 @@
 #include "attrib.hxx"
 #include "cell.hxx"
 #include "formulacell.hxx"
+#include "tokenarray.hxx"
 
 using namespace formula;
 
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 85c3cf9..191ca7d 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -35,6 +35,8 @@
 #include "conditio.hxx"
 #include "colorscale.hxx"
 #include "sheetevents.hxx"
+#include "tokenarray.hxx"
+
 #include <tools/shl.hxx>
 
 
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 00912d2..dc01d58 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -37,6 +37,7 @@
 #include "validat.hxx"
 #include "editutil.hxx"
 #include "chgtrack.hxx"
+#include "tokenarray.hxx"
 
 #include "formula/errorcodes.hxx"
 #include "svl/intitem.hxx"
@@ -1693,6 +1694,11 @@ void ScFormulaCell::MaybeInterpret()
         Interpret();
 }
 
+bool ScFormulaCell::IsHyperLinkCell() const
+{
+    return pCode && pCode->IsHyperLink();
+}
+
 EditTextObject* ScFormulaCell::CreateURLObject()
 {
     rtl::OUString aCellText;
diff --git a/sc/source/core/data/formulaiter.cxx b/sc/source/core/data/formulaiter.cxx
index 29c2bb8..5a7152d 100644
--- a/sc/source/core/data/formulaiter.cxx
+++ b/sc/source/core/data/formulaiter.cxx
@@ -20,6 +20,7 @@
 #include "formulaiter.hxx"
 
 #include "formulacell.hxx"
+#include "tokenarray.hxx"
 #include "formula/token.hxx"
 
 using namespace formula;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 85b4946..f7521c2 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -17,15 +17,6 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "scitems.hxx"
-#include <editeng/boxitem.hxx>
-#include "editeng/editobj.hxx"
-#include <svl/poolcach.hxx>
-#include <unotools/charclass.hxx>
-#include <math.h>
-#include <svl/PasswordHelper.hxx>
-#include <unotools/transliterationwrapper.hxx>
-
 #include "table.hxx"
 #include "patattr.hxx"
 #include "docpool.hxx"
@@ -51,6 +42,16 @@
 #include "queryentry.hxx"
 #include "dbdata.hxx"
 #include "colorscale.hxx"
+#include "tokenarray.hxx"
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include "editeng/editobj.hxx"
+#include <svl/poolcach.hxx>
+#include <unotools/charclass.hxx>
+#include <math.h>
+#include <svl/PasswordHelper.hxx>
+#include <unotools/transliterationwrapper.hxx>
 
 // STATIC DATA -----------------------------------------------------------
 
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 5468ecb..13bbec7 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -53,6 +53,7 @@
 #include "subtotalparam.hxx"
 #include "docpool.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 #include <vector>
 #include <boost/unordered_set.hpp>
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index 16267bf..588e05b 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -42,6 +42,7 @@
 #include "typedstrdata.hxx"
 #include "dociter.hxx"
 #include "editutil.hxx"
+#include "tokenarray.hxx"
 
 #include <math.h>
 #include <memory>
diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx
index 3c41eb6..cf02128 100644
--- a/sc/source/core/tool/chgtrack.cxx
+++ b/sc/source/core/tool/chgtrack.cxx
@@ -31,6 +31,7 @@
 #include "markdata.hxx"
 #include "globstr.hrc"
 #include "editutil.hxx"
+#include "tokenarray.hxx"
 
 #include <tools/shl.hxx>        // SHL_CALC
 #include <tools/rtti.hxx>
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 7cee7f6..e17500d 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -62,6 +62,7 @@
 #include "convuno.hxx"
 #include "tokenuno.hxx"
 #include "formulaparserpool.hxx"
+#include "tokenarray.hxx"
 
 using namespace formula;
 using namespace ::com::sun::star;
diff --git a/sc/source/core/tool/consoli.cxx b/sc/source/core/tool/consoli.cxx
index a27be85..1d7309a 100644
--- a/sc/source/core/tool/consoli.cxx
+++ b/sc/source/core/tool/consoli.cxx
@@ -24,6 +24,7 @@
 #include "subtotal.hxx"
 #include "formula/errorcodes.hxx"
 #include "formulacell.hxx"
+#include "tokenarray.hxx"
 
 #include <math.h>
 #include <string.h>
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 1d9e857..0bbeab95 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include "interpre.hxx"
+
 #include "scitems.hxx"
 #include <editeng/langitem.hxx>
 #include <editeng/justifyitem.hxx>
@@ -33,7 +35,6 @@
 #include <rtl/ustring.hxx>
 #include <rtl/logfile.hxx>
 
-#include "interpre.hxx"
 #include "patattr.hxx"
 #include "global.hxx"
 #include "document.hxx"
@@ -45,16 +46,6 @@
 #include "attrib.hxx"
 #include "jumpmatrix.hxx"
 #include "random.hxx"
-
-#include <comphelper/processfactory.hxx>
-#include <comphelper/string.hxx>
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <vector>
-#include <memory>
-#include <limits>
 #include "cellkeytranslator.hxx"
 #include "lookupcache.hxx"
 #include "rangenam.hxx"
@@ -65,6 +56,17 @@
 #include "doubleref.hxx"
 #include "queryparam.hxx"
 #include "queryentry.hxx"
+#include "tokenarray.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <vector>
+#include <memory>
+#include <limits>
 
 static const sal_uInt64 n2power48 = SAL_CONST_UINT64( 281474976710656); // 2^48
 
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index 7768a08..cdb1535 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include "interpre.hxx"
+
 #include <comphelper/string.hxx>
 #include <sfx2/linkmgr.hxx>
 #include <sfx2/dispatch.hxx>
@@ -26,7 +28,6 @@
 #include <rtl/logfile.hxx>
 #include <sal/macros.h>
 
-#include "interpre.hxx"
 #include "attrib.hxx"
 #include "sc.hrc"
 #include "ddelink.hxx"
@@ -41,6 +42,7 @@
 #include "hints.hxx"
 #include "dpobject.hxx"
 #include "postit.hxx"
+#include "tokenarray.hxx"
 
 #include <string.h>
 #include <math.h>
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 83d02f1..6247e51 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include "interpre.hxx"
+
 #include <rangelst.hxx>
 #include <sfx2/app.hxx>
 #include <sfx2/docfile.hxx>
@@ -38,7 +40,6 @@
 #include <com/sun/star/sheet/XSheetCellRange.hpp>
 #include <comphelper/processfactory.hxx>
 
-#include "interpre.hxx"
 #include "global.hxx"
 #include "dbdata.hxx"
 #include "formulacell.hxx"
@@ -61,6 +62,7 @@
 #include "macromgr.hxx"
 #include "doubleref.hxx"
 #include "queryparam.hxx"
+#include "tokenarray.hxx"
 
 #include <math.h>
 #include <float.h>
diff --git a/sc/source/filter/excel/xelink.cxx b/sc/source/filter/excel/xelink.cxx
index 027a123..8c2b451 100644
--- a/sc/source/filter/excel/xelink.cxx
+++ b/sc/source/filter/excel/xelink.cxx
@@ -26,6 +26,7 @@
 #include "formulacell.hxx"
 #include "scextopt.hxx"
 #include "externalrefmgr.hxx"
+#include "tokenarray.hxx"
 
 #include <vector>
 #include <memory>
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 0f541b5..2356793 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -38,6 +38,7 @@
 #include "rangelst.hxx"
 #include "compiler.hxx"
 #include "formulacell.hxx"
+#include "tokenarray.hxx"
 
 #include <../../ui/inc/docsh.hxx>
 #include <../../ui/inc/viewdata.hxx>
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 2366e70..4237988 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -33,6 +33,7 @@
 #include "xecontent.hxx"
 #include "xeescher.hxx"
 #include "xeextlst.hxx"
+#include "tokenarray.hxx"
 
 using namespace ::oox;
 
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 59286f5..d2f49e6 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -21,6 +21,7 @@
 #include "rangelst.hxx"
 #include "autonamecache.hxx"
 #include "tokenuno.hxx"
+#include "tokenarray.hxx"
 
 namespace oox {
 namespace xls {
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 6a53ea1..295d5e6 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -49,6 +49,7 @@
 #include "formulacell.hxx"
 #include "editattributemap.hxx"
 #include "stringutil.hxx"
+#include "tokenarray.hxx"
 
 #include <xmloff/xmltkmap.hxx>
 #include <xmloff/xmltoken.hxx>
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 4bd0c01..349b1e2 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -17,6 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include "inputhdl.hxx"
 #include "scitems.hxx"
 #include <editeng/eeitem.hxx>
 
@@ -74,9 +75,7 @@
 #include "editable.hxx"
 #include "funcdesc.hxx"
 #include "markdata.hxx"
-
-#define _INPUTHDL_CXX
-#include "inputhdl.hxx"
+#include "tokenarray.hxx"
 
 //  max. Ranges im RangeFinder
 #define RANGEFIND_MAX   32
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 09e571c..fbdfdc0 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -82,6 +82,7 @@
 #include "dpobject.hxx"
 #include "stringutil.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 #include <memory>
 #include <basic/basmgr.hxx>
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index a08787b..4aa8b99 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -49,6 +49,7 @@
 #include "docpool.hxx"
 #include "stringutil.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 #include "globstr.hrc"
 #include <vcl/svapp.hxx>
diff --git a/sc/source/ui/docshell/tablink.cxx b/sc/source/ui/docshell/tablink.cxx
index 4de384a..8077cd3 100644
--- a/sc/source/ui/docshell/tablink.cxx
+++ b/sc/source/ui/docshell/tablink.cxx
@@ -43,8 +43,7 @@
 #include "formula/opcode.hxx"
 #include "formulacell.hxx"
 #include "formulaiter.hxx"
-
-using ::rtl::OUString;
+#include "tokenarray.hxx"
 
 struct TableLink_Impl
 {
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index 1b825af..e0db50c 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -26,6 +26,8 @@
 
 #include <tools/fract.hxx>
 #include <tools/gen.hxx>
+#include "tools/link.hxx"
+#include "vcl/vclevent.hxx"
 #include <editeng/svxenum.hxx>
 
 #include <set>
@@ -118,7 +120,6 @@ private:
     static bool             bAutoComplete;              // from app options
     static bool             bOptLoaded;
 
-#ifdef _INPUTHDL_CXX
 private:
     void            UpdateActiveView();
     void            SyncViews( EditView* pSourceView = NULL );
@@ -157,7 +158,6 @@ private:
     DECL_LINK( ModifyHdl, void* );
     DECL_LINK( ShowHideTipVisibleParentListener, VclWindowEvent* );
     DECL_LINK( ShowHideTipVisibleSecParentListener, VclWindowEvent* );
-#endif
 
 public:
                     ScInputHandler();
diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx
index 52f0c3a..e6d9aec 100644
--- a/sc/source/ui/miscdlgs/anyrefdg.cxx
+++ b/sc/source/ui/miscdlgs/anyrefdg.cxx
@@ -41,7 +41,7 @@
 #include "global.hxx"
 #include "inputopt.hxx"
 #include "rangeutl.hxx"
-
+#include "tokenarray.hxx"
 
 ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings)
  : m_pDlg(_pDlg)
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 5a9e6b2..2c0c2b7 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -121,6 +121,7 @@
 #include "editeng/escapementitem.hxx"
 #include "stringutil.hxx"
 #include "formulaiter.hxx"
+#include "tokenarray.hxx"
 
 #include <list>
 #include <boost/scoped_ptr.hpp>
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index e32ad53..a3e6797 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -36,6 +36,7 @@
 #include "tokenuno.hxx"
 #include "docsh.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 #include "formula/opcode.hxx"
 
diff --git a/sc/source/ui/unoobj/funcuno.cxx b/sc/source/ui/unoobj/funcuno.cxx
index 8594c63..558d170 100644
--- a/sc/source/ui/unoobj/funcuno.cxx
+++ b/sc/source/ui/unoobj/funcuno.cxx
@@ -43,6 +43,7 @@
 #include "clipparam.hxx"
 #include "dociter.hxx"
 #include "stringutil.hxx"
+#include "tokenarray.hxx"
 
 using namespace com::sun::star;
 
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
index 45e2c38..43a04a4 100644
--- a/sc/source/ui/view/tabvwsha.cxx
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -51,6 +51,7 @@
 #include "compiler.hxx"
 #include "markdata.hxx"
 #include "cellvalue.hxx"
+#include "tokenarray.hxx"
 
 sal_Bool ScTabViewShell::GetFunction( String& rFuncStr, sal_uInt16 nErrCode )
 {
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index 7f15a3f..22a25ec 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -78,6 +78,7 @@
 #include "tabbgcolor.hxx"
 #include "clipparam.hxx"
 #include "prnsave.hxx"
+#include "tokenarray.hxx"
 
 #include <boost/scoped_ptr.hpp>
 #include <vector>
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 5316300..4bb63bc 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -74,6 +74,8 @@
 #include "funcdesc.hxx"
 #include "docuno.hxx"
 #include "cellsuno.hxx"
+#include "tokenarray.hxx"
+
 //==================================================================
 
 static void lcl_PostRepaintCondFormat( const ScConditionalFormat *pCondFmt, ScDocShell *pDocSh )
commit 428b0aeceecbccb7558a246eda090ececd28d7c5
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Mar 28 15:20:14 2013 -0400

    Move ScFormulaCell into its own header source files: formulacell.?xx.
    
    Change-Id: I65f2cb12c06784b5bcf6c6a2fad773825b6c409c

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 46ab330..8d89830 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -143,6 +143,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
 	sc/source/core/data/drawpage \
 	sc/source/core/data/drwlayer \
 	sc/source/core/data/fillinfo \
+	sc/source/core/data/formulacell \
 	sc/source/core/data/formulaiter \
 	sc/source/core/data/funcdesc \
 	sc/source/core/data/global \
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 7395713..217cfab 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -300,284 +300,6 @@ private:
     ::std::vector<Item> maArray;
 };
 
-struct ScSimilarFormulaDelta;
-
-struct SC_DLLPUBLIC ScFormulaCellGroup
-{
-    sal_Int32              mnRefCount;
-    ScSimilarFormulaDelta *mpDelta;  // difference between items in column
-    sal_Int32              mnStart;  // Start offset of that cell
-    sal_Int32              mnLength; // How many of these do we have ?
-
-    ScFormulaCellGroup();
-    ~ScFormulaCellGroup();
-
-    bool IsCompatible( ScSimilarFormulaDelta *pDelta );
-};
-inline void intrusive_ptr_add_ref(ScFormulaCellGroup *p)
-{
-    p->mnRefCount++;
-}
-inline void intrusive_ptr_release(ScFormulaCellGroup *p)
-{
-    if( --p->mnRefCount == 0 )
-        delete p;
-}
-
-typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef;
-
-enum ScMatrixMode {
-    MM_NONE      = 0,                   // No matrix formula
-    MM_FORMULA   = 1,                   // Upper left matrix formula cell
-    MM_REFERENCE = 2,                   // Remaining cells, via ocMatRef reference token
-    MM_FAKE      = 3                    // Interpret "as-if" matrix formula (legacy)
-};
-
-class SC_DLLPUBLIC ScFormulaCell : public ScBaseCell, public SvtListener
-{
-private:
-    ScFormulaResult aResult;
-    formula::FormulaGrammar::Grammar  eTempGrammar;   // used between string (creation) and (re)compilation
-    ScTokenArray*   pCode;              // The (new) token array
-    ScDocument*     pDocument;
-    ScFormulaCell*  pPrevious;
-    ScFormulaCell*  pNext;
-    ScFormulaCell*  pPreviousTrack;
-    ScFormulaCell*  pNextTrack;
-    ScFormulaCellGroupRef xGroup;       // re-factoring hack - group of formulae we're part of.
-    sal_uLong       nFormatIndex;       // Number format set by calculation
-    short           nFormatType;        // Number format type set by calculation
-    sal_uInt16      nSeenInIteration;   // Iteration cycle in which the cell was last encountered
-    sal_uInt8       cMatrixFlag;        // One of ScMatrixMode
-    bool            bDirty         : 1; // Must be (re)calculated
-    bool            bChanged       : 1; // Whether something changed regarding display/representation
-    bool            bRunning       : 1; // Already interpreting right now
-    bool            bCompile       : 1; // Must be (re)compiled
-    bool            bSubTotal      : 1; // Cell is part of or contains a SubTotal
-    bool            bIsIterCell    : 1; // Cell is part of a circular reference
-    bool            bInChangeTrack : 1; // Cell is in ChangeTrack
-    bool            bTableOpDirty  : 1; // Dirty flag for TableOp
-    bool            bNeedListening : 1; // Listeners need to be re-established after UpdateReference
-
-                    enum ScInterpretTailParameter
-                    {
-                        SCITP_NORMAL,
-                        SCITP_FROM_ITERATION,
-                        SCITP_CLOSE_ITERATION_CIRCLE
-                    };
-    void            InterpretTail( ScInterpretTailParameter );
-
-    ScFormulaCell( const ScFormulaCell& );
-
-public:
-
-#ifdef USE_MEMPOOL
-    DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
-#endif
-
-    ScAddress       aPos;
-
-                    ~ScFormulaCell();
-
-    using ScBaseCell::Clone;
-
-    ScFormulaCell* Clone() const;
-
-    /** Empty formula cell, or with a preconstructed token array. */
-    ScFormulaCell( ScDocument*, const ScAddress&, const ScTokenArray* = NULL,
-                    const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
-                    sal_uInt8 = MM_NONE );
-
-    /** With formula string and grammar to compile with.
-       formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
-        also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefor uses the address
-        convention associated with rPos::nTab by default. */
-    ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
-                    const rtl::OUString& rFormula,
-                    const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
-                    sal_uInt8 cMatInd = MM_NONE );
-
-    ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT );
-
-    size_t GetHash() const;
-
-    ScFormulaVectorState GetVectorState() const;
-
-    void            GetFormula( rtl::OUString& rFormula,
-                                const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
-    void            GetFormula( rtl::OUStringBuffer& rBuffer,
-                                const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
-
-    void            SetDirty( bool bDirtyFlag=true );
-    void            SetDirtyVar();
-    // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
-    void            SetDirtyAfterLoad();
-    inline void     ResetTableOpDirtyVar() { bTableOpDirty = false; }
-    void            SetTableOpDirty();
-    bool            IsDirtyOrInTableOpDirty() const;
-    bool            GetDirty() const { return bDirty; }
-    void            ResetDirty() { bDirty = false; }
-    bool            NeedsListening() const { return bNeedListening; }
-    void            SetNeedsListening( bool bVar ) { bNeedListening = bVar; }
-    void            Compile(const rtl::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();
-    bool            MarkUsedExternalReferences();
-    void            Interpret();
-    inline bool     IsIterCell() const { return bIsIterCell; }
-    inline sal_uInt16   GetSeenInIteration() const { return nSeenInIteration; }
-
-    bool            HasOneReference( ScRange& r ) const;
-    /* Checks if the formula contains reference list that can be
-       expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
-       reference list is not required to be sorted (i.e. A3;A1;A2 is
-       still recognized as A1:A3), but no overlapping is allowed.
-       If one reference is recognized, the rRange is filled.
-
-       It is similar to HasOneReference(), but more general.
-     */
-    bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
-    bool            HasRelNameReference() const;
-    bool            HasColRowName() const;
-
-    bool            UpdateReference(UpdateRefMode eUpdateRefMode,
-                                    const ScRange& r,
-                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
-                                    ScDocument* pUndoDoc = NULL,
-                                    const ScAddress* pUndoCellPos = NULL );
-
-    void            TransposeReference();
-    void            UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
-                                        ScDocument* pUndoDoc );
-
-    void            UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
-
-    void            UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets = 1);
-    void            UpdateInsertTabAbs(SCTAB nTable);
-    bool            UpdateDeleteTab(SCTAB nTable, bool bIsMove = false, SCTAB nSheets = 1);
-    void            UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo);
-    void            UpdateRenameTab(SCTAB nTable, const rtl::OUString& rName);
-    bool            TestTabRefAbs(SCTAB nTable);
-    void            UpdateCompile( bool bForceIfNameInUse = false );
-    void            FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const;
-    bool            IsSubTotal() const                      { return bSubTotal; }
-    bool            IsChanged() const;
-    void            ResetChanged();
-    bool            IsEmpty();      // formula::svEmptyCell result
-                    // display as empty string if formula::svEmptyCell result
-    bool            IsEmptyDisplayedAsString();
-    bool            IsValue();      // also true if formula::svEmptyCell
-    bool            IsHybridValueCell(); // for cells after import to deal with inherited number formats
-    double          GetValue();
-    double          GetValueAlways();   // ignore errors
-    rtl::OUString   GetString();
-    const ScMatrix* GetMatrix();
-    bool            GetMatrixOrigin( ScAddress& rPos ) const;
-    void            GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
-    sal_uInt16      GetMatrixEdge( ScAddress& rOrgPos );
-    sal_uInt16      GetErrCode();   // interpret first if necessary
-    sal_uInt16      GetRawError();  // don't interpret, just return code or result error
-    short           GetFormatType() const                   { return nFormatType; }
-    sal_uLong       GetFormatIndex() const                  { return nFormatIndex; }
-    void            GetFormatInfo( short& nType, sal_uLong& nIndex ) const
-                        { nType = nFormatType; nIndex = nFormatIndex; }
-    sal_uInt8       GetMatrixFlag() const                   { return cMatrixFlag; }
-    ScTokenArray*   GetCode() const                         { return pCode; }
-
-    bool            IsRunning() const                       { return bRunning; }
-    void            SetRunning( bool bVal )                 { bRunning = bVal; }
-    void            CompileDBFormula();
-    void            CompileDBFormula( bool bCreateFormulaString );
-    void            CompileNameFormula( bool bCreateFormulaString );
-    void            CompileColRowNameFormula();
-    ScFormulaCell*  GetPrevious() const                 { return pPrevious; }
-    ScFormulaCell*  GetNext() const                     { return pNext; }
-    void            SetPrevious( ScFormulaCell* pF )    { pPrevious = pF; }
-    void            SetNext( ScFormulaCell* pF )        { pNext = pF; }
-    ScFormulaCell*  GetPreviousTrack() const                { return pPreviousTrack; }
-    ScFormulaCell*  GetNextTrack() const                    { return pNextTrack; }
-    void            SetPreviousTrack( ScFormulaCell* pF )   { pPreviousTrack = pF; }
-    void            SetNextTrack( ScFormulaCell* pF )       { pNextTrack = pF; }
-
-    virtual void    Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
-    void            SetCompile( bool bVal ) { bCompile = bVal; }
-    ScDocument*     GetDocument() const     { return pDocument; }
-    void            SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag=true );
-    void            GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
-
-                    // cell belongs to ChangeTrack and not to the real document
-    void            SetInChangeTrack( bool bVal ) { bInChangeTrack = bVal; }
-    bool            IsInChangeTrack() const { return bInChangeTrack; }
-
-                    // standard format for type and format
-                    // for format "Standard" possibly the format used in the formula cell
-    sal_uLong       GetStandardFormat( SvNumberFormatter& rFormatter, sal_uLong nFormat ) const;
-
-    // For import filters!
-    void            AddRecalcMode( formula::ScRecalcMode );
-    /** For import only: set a double result. */
-    void            SetHybridDouble( double n )     { aResult.SetHybridDouble( n); }
-    /** For import only: set a string result.
-        If for whatever reason you have to use both, SetHybridDouble() and
-        SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
-        for performance reasons.*/
-    void            SetHybridString( const rtl::OUString& r )
-                        { aResult.SetHybridString( r); }
-    /** For import only: set a temporary formula string to be compiled later.
-        If for whatever reason you have to use both, SetHybridDouble() and
-        SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
-        for performance reasons.*/
-    void            SetHybridFormula( const rtl::OUString& r,
-                                    const formula::FormulaGrammar::Grammar eGrammar )
-                        { aResult.SetHybridFormula( r); eTempGrammar = eGrammar; }
-
-    /**
-     * For import only: use for formula cells that return a number
-     * formatted as some kind of string
-     */
-    void SetHybridValueString( double nVal, const OUString& r )
-                        { aResult.SetHybridValueString( nVal, r ); }
-
-    void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
-    {
-        aResult.SetMatrix(nCols, nRows, pMat, pUL);
-    }
-
-    /** For import only: set a double result.
-        Use this instead of SetHybridDouble() if there is no (temporary)
-        formula string because the formula is present as a token array, as it
-        is the case for binary Excel import.
-     */
-    void            SetResultDouble( double n )     { aResult.SetDouble( n); }
-
-    void            SetErrCode( sal_uInt16 n );
-    inline bool     IsHyperLinkCell() const { return pCode && pCode->IsHyperLink(); }
-    EditTextObject* CreateURLObject();
-    void            GetURLResult( rtl::OUString& rURL, rtl::OUString& rCellText );
-
-    /** Determines whether or not the result string contains more than one paragraph */
-    bool            IsMultilineResult();
-
-    void            MaybeInterpret();
-
-    // Temporary formula cell grouping API
-    ScFormulaCellGroupRef  GetCellGroup()
-        { return xGroup; }
-    void                   SetCellGroup( const ScFormulaCellGroupRef &xRef )
-        { xGroup = xRef; }
-    ScSimilarFormulaDelta *BuildDeltaTo( ScFormulaCell *pOther );
-    void                   ReleaseDelta( ScSimilarFormulaDelta *pDelta );
-    bool                   InterpretFormulaGroup();
-
-    // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
-    void StartListeningTo( ScDocument* pDoc );
-    void EndListeningTo(
-        ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
-};
-
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
new file mode 100644
index 0000000..8bdcbc0
--- /dev/null
+++ b/sc/inc/formulacell.hxx
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef SC_FORMULACELL_HXX
+#define SC_FORMULACELL_HXX
+
+#include "cell.hxx"
+
+struct ScSimilarFormulaDelta;
+
+struct SC_DLLPUBLIC ScFormulaCellGroup
+{
+    sal_Int32              mnRefCount;
+    ScSimilarFormulaDelta *mpDelta;  // difference between items in column
+    sal_Int32              mnStart;  // Start offset of that cell
+    sal_Int32              mnLength; // How many of these do we have ?
+
+    ScFormulaCellGroup();
+    ~ScFormulaCellGroup();
+
+    bool IsCompatible( ScSimilarFormulaDelta *pDelta );
+};
+inline void intrusive_ptr_add_ref(ScFormulaCellGroup *p)
+{
+    p->mnRefCount++;
+}
+inline void intrusive_ptr_release(ScFormulaCellGroup *p)
+{
+    if( --p->mnRefCount == 0 )
+        delete p;
+}
+
+typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef;
+
+enum ScMatrixMode {
+    MM_NONE      = 0,                   // No matrix formula
+    MM_FORMULA   = 1,                   // Upper left matrix formula cell
+    MM_REFERENCE = 2,                   // Remaining cells, via ocMatRef reference token
+    MM_FAKE      = 3                    // Interpret "as-if" matrix formula (legacy)
+};
+
+class SC_DLLPUBLIC ScFormulaCell : public ScBaseCell, public SvtListener
+{
+private:
+    ScFormulaResult aResult;
+    formula::FormulaGrammar::Grammar  eTempGrammar;   // used between string (creation) and (re)compilation
+    ScTokenArray*   pCode;              // The (new) token array
+    ScDocument*     pDocument;
+    ScFormulaCell*  pPrevious;
+    ScFormulaCell*  pNext;
+    ScFormulaCell*  pPreviousTrack;
+    ScFormulaCell*  pNextTrack;
+    ScFormulaCellGroupRef xGroup;       // re-factoring hack - group of formulae we're part of.
+    sal_uLong       nFormatIndex;       // Number format set by calculation
+    short           nFormatType;        // Number format type set by calculation
+    sal_uInt16      nSeenInIteration;   // Iteration cycle in which the cell was last encountered
+    sal_uInt8       cMatrixFlag;        // One of ScMatrixMode
+    bool            bDirty         : 1; // Must be (re)calculated
+    bool            bChanged       : 1; // Whether something changed regarding display/representation
+    bool            bRunning       : 1; // Already interpreting right now
+    bool            bCompile       : 1; // Must be (re)compiled
+    bool            bSubTotal      : 1; // Cell is part of or contains a SubTotal
+    bool            bIsIterCell    : 1; // Cell is part of a circular reference
+    bool            bInChangeTrack : 1; // Cell is in ChangeTrack
+    bool            bTableOpDirty  : 1; // Dirty flag for TableOp
+    bool            bNeedListening : 1; // Listeners need to be re-established after UpdateReference
+
+                    enum ScInterpretTailParameter
+                    {
+                        SCITP_NORMAL,
+                        SCITP_FROM_ITERATION,
+                        SCITP_CLOSE_ITERATION_CIRCLE
+                    };
+    void            InterpretTail( ScInterpretTailParameter );
+
+    ScFormulaCell( const ScFormulaCell& );
+
+public:
+
+#ifdef USE_MEMPOOL
+    DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
+#endif
+
+    ScAddress       aPos;
+
+                    ~ScFormulaCell();
+
+    using ScBaseCell::Clone;
+
+    ScFormulaCell* Clone() const;
+
+    /** Empty formula cell, or with a preconstructed token array. */
+    ScFormulaCell( ScDocument*, const ScAddress&, const ScTokenArray* = NULL,
+                    const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
+                    sal_uInt8 = MM_NONE );
+
+    /** With formula string and grammar to compile with.
+       formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
+        also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefor uses the address
+        convention associated with rPos::nTab by default. */
+    ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
+                    const rtl::OUString& rFormula,
+                    const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
+                    sal_uInt8 cMatInd = MM_NONE );
+
+    ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT );
+
+    size_t GetHash() const;
+
+    ScFormulaVectorState GetVectorState() const;
+
+    void            GetFormula( rtl::OUString& rFormula,
+                                const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
+    void            GetFormula( rtl::OUStringBuffer& rBuffer,
+                                const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
+
+    void            SetDirty( bool bDirtyFlag=true );
+    void            SetDirtyVar();
+    // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
+    void            SetDirtyAfterLoad();
+    inline void     ResetTableOpDirtyVar() { bTableOpDirty = false; }
+    void            SetTableOpDirty();
+    bool            IsDirtyOrInTableOpDirty() const;
+    bool            GetDirty() const { return bDirty; }
+    void            ResetDirty() { bDirty = false; }
+    bool            NeedsListening() const { return bNeedListening; }
+    void            SetNeedsListening( bool bVar ) { bNeedListening = bVar; }
+    void            Compile(const rtl::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();
+    bool            MarkUsedExternalReferences();
+    void            Interpret();
+    inline bool     IsIterCell() const { return bIsIterCell; }
+    inline sal_uInt16   GetSeenInIteration() const { return nSeenInIteration; }
+
+    bool            HasOneReference( ScRange& r ) const;
+    /* Checks if the formula contains reference list that can be
+       expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
+       reference list is not required to be sorted (i.e. A3;A1;A2 is
+       still recognized as A1:A3), but no overlapping is allowed.
+       If one reference is recognized, the rRange is filled.
+
+       It is similar to HasOneReference(), but more general.
+     */
+    bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
+    bool            HasRelNameReference() const;
+    bool            HasColRowName() const;
+
+    bool            UpdateReference(UpdateRefMode eUpdateRefMode,
+                                    const ScRange& r,
+                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+                                    ScDocument* pUndoDoc = NULL,
+                                    const ScAddress* pUndoCellPos = NULL );
+
+    void            TransposeReference();
+    void            UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
+                                        ScDocument* pUndoDoc );
+
+    void            UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
+
+    void            UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets = 1);
+    void            UpdateInsertTabAbs(SCTAB nTable);
+    bool            UpdateDeleteTab(SCTAB nTable, bool bIsMove = false, SCTAB nSheets = 1);
+    void            UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo);
+    void            UpdateRenameTab(SCTAB nTable, const rtl::OUString& rName);
+    bool            TestTabRefAbs(SCTAB nTable);
+    void            UpdateCompile( bool bForceIfNameInUse = false );
+    void            FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const;
+    bool            IsSubTotal() const                      { return bSubTotal; }
+    bool            IsChanged() const;
+    void            ResetChanged();
+    bool            IsEmpty();      // formula::svEmptyCell result
+                    // display as empty string if formula::svEmptyCell result
+    bool            IsEmptyDisplayedAsString();
+    bool            IsValue();      // also true if formula::svEmptyCell
+    bool            IsHybridValueCell(); // for cells after import to deal with inherited number formats
+    double          GetValue();
+    double          GetValueAlways();   // ignore errors
+    rtl::OUString   GetString();
+    const ScMatrix* GetMatrix();
+    bool            GetMatrixOrigin( ScAddress& rPos ) const;
+    void            GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
+    sal_uInt16      GetMatrixEdge( ScAddress& rOrgPos );
+    sal_uInt16      GetErrCode();   // interpret first if necessary
+    sal_uInt16      GetRawError();  // don't interpret, just return code or result error
+    short           GetFormatType() const                   { return nFormatType; }
+    sal_uLong       GetFormatIndex() const                  { return nFormatIndex; }
+    void            GetFormatInfo( short& nType, sal_uLong& nIndex ) const
+                        { nType = nFormatType; nIndex = nFormatIndex; }
+    sal_uInt8       GetMatrixFlag() const                   { return cMatrixFlag; }
+    ScTokenArray*   GetCode() const                         { return pCode; }
+
+    bool            IsRunning() const                       { return bRunning; }
+    void            SetRunning( bool bVal )                 { bRunning = bVal; }
+    void            CompileDBFormula();
+    void            CompileDBFormula( bool bCreateFormulaString );
+    void            CompileNameFormula( bool bCreateFormulaString );
+    void            CompileColRowNameFormula();
+    ScFormulaCell*  GetPrevious() const                 { return pPrevious; }
+    ScFormulaCell*  GetNext() const                     { return pNext; }
+    void            SetPrevious( ScFormulaCell* pF )    { pPrevious = pF; }
+    void            SetNext( ScFormulaCell* pF )        { pNext = pF; }
+    ScFormulaCell*  GetPreviousTrack() const                { return pPreviousTrack; }
+    ScFormulaCell*  GetNextTrack() const                    { return pNextTrack; }
+    void            SetPreviousTrack( ScFormulaCell* pF )   { pPreviousTrack = pF; }
+    void            SetNextTrack( ScFormulaCell* pF )       { pNextTrack = pF; }
+
+    virtual void    Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
+    void            SetCompile( bool bVal ) { bCompile = bVal; }
+    ScDocument*     GetDocument() const     { return pDocument; }
+    void            SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag=true );
+    void            GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
+
+                    // cell belongs to ChangeTrack and not to the real document
+    void            SetInChangeTrack( bool bVal ) { bInChangeTrack = bVal; }
+    bool            IsInChangeTrack() const { return bInChangeTrack; }
+
+                    // standard format for type and format
+                    // for format "Standard" possibly the format used in the formula cell
+    sal_uLong       GetStandardFormat( SvNumberFormatter& rFormatter, sal_uLong nFormat ) const;
+
+    // For import filters!
+    void            AddRecalcMode( formula::ScRecalcMode );
+    /** For import only: set a double result. */
+    void            SetHybridDouble( double n )     { aResult.SetHybridDouble( n); }
+    /** For import only: set a string result.
+        If for whatever reason you have to use both, SetHybridDouble() and
+        SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
+        for performance reasons.*/
+    void            SetHybridString( const rtl::OUString& r )
+                        { aResult.SetHybridString( r); }
+    /** For import only: set a temporary formula string to be compiled later.
+        If for whatever reason you have to use both, SetHybridDouble() and
+        SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
+        for performance reasons.*/
+    void            SetHybridFormula( const rtl::OUString& r,
+                                    const formula::FormulaGrammar::Grammar eGrammar )
+                        { aResult.SetHybridFormula( r); eTempGrammar = eGrammar; }
+
+    /**
+     * For import only: use for formula cells that return a number
+     * formatted as some kind of string
+     */
+    void SetHybridValueString( double nVal, const OUString& r )
+                        { aResult.SetHybridValueString( nVal, r ); }
+
+    void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
+    {
+        aResult.SetMatrix(nCols, nRows, pMat, pUL);
+    }
+
+    /** For import only: set a double result.
+        Use this instead of SetHybridDouble() if there is no (temporary)
+        formula string because the formula is present as a token array, as it
+        is the case for binary Excel import.
+     */
+    void            SetResultDouble( double n )     { aResult.SetDouble( n); }
+
+    void            SetErrCode( sal_uInt16 n );
+    inline bool     IsHyperLinkCell() const { return pCode && pCode->IsHyperLink(); }
+    EditTextObject* CreateURLObject();
+    void            GetURLResult( rtl::OUString& rURL, rtl::OUString& rCellText );
+
+    /** Determines whether or not the result string contains more than one paragraph */
+    bool            IsMultilineResult();
+
+    void            MaybeInterpret();
+
+    // Temporary formula cell grouping API
+    ScFormulaCellGroupRef  GetCellGroup()
+        { return xGroup; }
+    void                   SetCellGroup( const ScFormulaCellGroupRef &xRef )
+        { xGroup = xRef; }
+    ScSimilarFormulaDelta *BuildDeltaTo( ScFormulaCell *pOther );
+    void                   ReleaseDelta( ScSimilarFormulaDelta *pDelta );
+    bool                   InterpretFormulaGroup();
+
+    // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
+    void StartListeningTo( ScDocument* pDoc );
+    void EndListeningTo(
+        ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 130be28..a00b518 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -50,7 +50,7 @@
 #include <editeng/borderline.hxx>
 #include <dbdata.hxx>
 #include "validat.hxx"
-#include "cell.hxx"
+#include "formulacell.hxx"
 #include "drwlayer.hxx"
 #include "userdat.hxx"
 #include "dpobject.hxx"
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 6d48956..6416340 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -33,7 +33,7 @@
 #include <osl/file.hxx>
 
 #include "scdll.hxx"
-#include "cell.hxx"
+#include "formulacell.hxx"
 #include "document.hxx"
 #include "stringutil.hxx"
 #include "scmatrix.hxx"
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 29522130..d52bcc6 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -40,7 +40,7 @@
 #include "rechead.hxx"
 #include "globstr.hrc"
 #include "segmenttree.hxx"
-#include "cell.hxx"
+#include "formulacell.hxx"
 #include "cellvalue.hxx"
 #include "editutil.hxx"
 #include <rtl/strbuf.hxx>
diff --git a/sc/source/core/data/autonamecache.cxx b/sc/source/core/data/autonamecache.cxx
index 6629c51..1dca11e 100644
--- a/sc/source/core/data/autonamecache.cxx
+++ b/sc/source/core/data/autonamecache.cxx
@@ -22,7 +22,7 @@
 #include "autonamecache.hxx"
 #include "dociter.hxx"
 #include "queryparam.hxx"
-#include "cell.hxx"
+#include "formulacell.hxx"
 #include "cellvalue.hxx"
 #include "editutil.hxx"
 #include "document.hxx"
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 66032a8..aa6e2a2 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -19,45 +19,15 @@
 
 #include "cell.hxx"
 
-#include "scitems.hxx"
-#include "attrib.hxx"
-#include "compiler.hxx"
-#include "interpre.hxx"
 #include "document.hxx"
-#include "docoptio.hxx"
-#include "rechead.hxx"
-#include "rangenam.hxx"
-#include "brdcst.hxx"
-#include "ddelink.hxx"
-#include "validat.hxx"
-#include "progress.hxx"
-#include "editutil.hxx"
-#include "recursionhelper.hxx"
-#include "externalrefmgr.hxx"
-#include "macromgr.hxx"
-#include "dbdata.hxx"
-#include "globalnames.hxx"
-#include "cellvalue.hxx"
+#include "formulacell.hxx"
 
-#include <svl/intitem.hxx>
 #include <svl/broadcast.hxx>
-#include <svl/zforlist.hxx>
-
-using namespace formula;
-// More or less arbitrary, of course all recursions must fit into available
-// stack space (which is what on all systems we don't know yet?). Choosing a
-// lower value may be better than trying a much higher value that also isn't
-// sufficient but temporarily leads to high memory consumption. On the other
-// hand, if the value fits all recursions, execution is quicker as no resumes
-// are necessary. Could be made a configurable option.
-// Allow for a year's calendar (366).
-const sal_uInt16 MAXRECURSION = 400;
 
 // STATIC DATA -----------------------------------------------------------
 
 #ifdef USE_MEMPOOL
 IMPL_FIXEDMEMPOOL_NEWDEL( ScValueCell )
-IMPL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
 IMPL_FIXEDMEMPOOL_NEWDEL( ScStringCell )
 IMPL_FIXEDMEMPOOL_NEWDEL( ScNoteCell )
 #endif
@@ -104,108 +74,6 @@ ScBaseCell* lclCloneCell( const ScBaseCell& rSrcCell, ScDocument& rDestDoc, cons
     return 0;
 }
 
-void adjustRangeName(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldDoc, const ScAddress& aNewPos, const ScAddress& aOldPos)
-{
-    bool bOldGlobal = pToken->IsGlobal();
-    SCTAB aOldTab = aOldPos.Tab();
-    rtl::OUString aRangeName;
-    int nOldIndex = pToken->GetIndex();
-    ScRangeData* pOldRangeData = NULL;
-
-    //search the name of the RangeName
-    if (!bOldGlobal)
-    {
-        pOldRangeData = pOldDoc->GetRangeName(aOldTab)->findByIndex(nOldIndex);
-        if (!pOldRangeData)
-            return;     //might be an error in the formula array
-        aRangeName = pOldRangeData->GetUpperName();
-    }
-    else
-    {
-        pOldRangeData = pOldDoc->GetRangeName()->findByIndex(nOldIndex);
-        if (!pOldRangeData)
-            return;     //might be an error in the formula array
-        aRangeName = pOldRangeData->GetUpperName();
-    }
-
-    //find corresponding range name in new document
-    //first search for local range name then global range names
-    SCTAB aNewTab = aNewPos.Tab();
-    ScRangeName* pRangeName = rNewDoc.GetRangeName(aNewTab);
-    ScRangeData* pRangeData = NULL;
-    bool bNewGlobal = false;
-    //search local range names
-    if (pRangeName)
-    {
-        pRangeData = pRangeName->findByUpperName(aRangeName);
-    }
-    //search global range names
-    if (!pRangeData)
-    {
-        bNewGlobal = true;
-        pRangeName = rNewDoc.GetRangeName();
-        if (pRangeName)
-            pRangeData = pRangeName->findByUpperName(aRangeName);
-    }
-    //if no range name was found copy it
-    if (!pRangeData)
-    {
-        bNewGlobal = bOldGlobal;
-        pRangeData = new ScRangeData(*pOldRangeData, &rNewDoc);
-        ScTokenArray* pRangeNameToken = pRangeData->GetCode();
-        if (rNewDoc.GetPool() != const_cast<ScDocument*>(pOldDoc)->GetPool())
-        {
-            pRangeNameToken->ReadjustAbsolute3DReferences(pOldDoc, &rNewDoc, pRangeData->GetPos(), true);
-            pRangeNameToken->AdjustAbsoluteRefs(pOldDoc, aOldPos, aNewPos, false, true);
-        }
-
-        bool bInserted;
-        if (bNewGlobal)
-            bInserted = rNewDoc.GetRangeName()->insert(pRangeData);
-        else
-            bInserted = rNewDoc.GetRangeName(aNewTab)->insert(pRangeData);
-        if (!bInserted)
-        {
-            //if this happened we have a real problem
-            pRangeData = NULL;
-            pToken->SetIndex(0);
-            OSL_FAIL("inserting the range name should not fail");
-            return;
-        }
-    }
-    sal_Int32 nIndex = pRangeData->GetIndex();
-    pToken->SetIndex(nIndex);
-    pToken->SetGlobal(bNewGlobal);
-}
-
-void adjustDBRange(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldDoc)
-{
-    ScDBCollection* pOldDBCollection = pOldDoc->GetDBCollection();
-    if (!pOldDBCollection)
-        return;//strange error case, don't do anything
-    ScDBCollection::NamedDBs& aOldNamedDBs = pOldDBCollection->getNamedDBs();
-    ScDBData* pDBData = aOldNamedDBs.findByIndex(pToken->GetIndex());
-    if (!pDBData)
-        return; //invalid index
-    rtl::OUString aDBName = pDBData->GetUpperName();
-
-    //search in new document
-    ScDBCollection* pNewDBCollection = rNewDoc.GetDBCollection();
-    if (!pNewDBCollection)
-    {
-        pNewDBCollection = new ScDBCollection(&rNewDoc);
-        rNewDoc.SetDBCollection(pNewDBCollection);
-    }
-    ScDBCollection::NamedDBs& aNewNamedDBs = pNewDBCollection->getNamedDBs();
-    ScDBData* pNewDBData = aNewNamedDBs.findByUpperName(aDBName);
-    if (!pNewDBData)
-    {
-        pNewDBData = new ScDBData(*pDBData);
-        aNewNamedDBs.insert(pNewDBData);
-    }
-    pToken->SetIndex(pNewDBData->GetIndex());
-}
-
 } // namespace
 
 ScBaseCell* ScBaseCell::Clone( ScDocument& rDestDoc, int nCloneFlags ) const
@@ -388,1329 +256,4 @@ ScStringCell::~ScStringCell()
 }
 #endif
 
-// ============================================================================
-
-//
-//      ScFormulaCell
-//
-
-ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
-                              const rtl::OUString& rFormula,
-                              const FormulaGrammar::Grammar eGrammar,
-                              sal_uInt8 cMatInd ) :
-    ScBaseCell( CELLTYPE_FORMULA ),
-    eTempGrammar( eGrammar),
-    pCode( NULL ),
-    pDocument( pDoc ),
-    pPrevious(0),
-    pNext(0),
-    pPreviousTrack(0),
-    pNextTrack(0),
-    nFormatIndex(0),
-    nFormatType( NUMBERFORMAT_NUMBER ),
-    nSeenInIteration(0),
-    cMatrixFlag ( cMatInd ),
-    bDirty( true ), // -> Because of the use of the Auto Pilot Function was: cMatInd != 0
-    bChanged( false ),
-    bRunning( false ),
-    bCompile( false ),
-    bSubTotal( false ),
-    bIsIterCell( false ),
-    bInChangeTrack( false ),
-    bTableOpDirty( false ),
-    bNeedListening( false ),
-    aPos( rPos )
-{
-    Compile( rFormula, true, eGrammar );    // bNoListening, Insert does that
-    if (!pCode)
-        // We need to have a non-NULL token array instance at all times.
-        pCode = new ScTokenArray;
-}
-
-// Used by import filters
-
-ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
-                              const ScTokenArray* pArr,
-                              const FormulaGrammar::Grammar eGrammar, sal_uInt8 cInd ) :
-    ScBaseCell( CELLTYPE_FORMULA ),
-    eTempGrammar( eGrammar),
-    pCode( pArr ? new ScTokenArray( *pArr ) : new ScTokenArray ),
-    pDocument( pDoc ),
-    pPrevious(0),
-    pNext(0),
-    pPreviousTrack(0),
-    pNextTrack(0),
-    nFormatIndex(0),
-    nFormatType( NUMBERFORMAT_NUMBER ),
-    nSeenInIteration(0),
-    cMatrixFlag ( cInd ),
-    bDirty( NULL != pArr ), // -> Because of the use of the Auto Pilot Function was: cInd != 0
-    bChanged( false ),
-    bRunning( false ),
-    bCompile( false ),
-    bSubTotal( false ),
-    bIsIterCell( false ),
-    bInChangeTrack( false ),
-    bTableOpDirty( false ),
-    bNeedListening( false ),
-    aPos( rPos )
-{
-    // UPN-Array generation
-    if( pCode->GetLen() && !pCode->GetCodeError() && !pCode->GetCodeLen() )
-    {
-        ScCompiler aComp( pDocument, aPos, *pCode);
-        aComp.SetGrammar(eTempGrammar);
-        bSubTotal = aComp.CompileTokenArray();
-        nFormatType = aComp.GetNumFormatType();
-    }
-    else
-    {
-        pCode->Reset();
-        if ( pCode->GetNextOpCodeRPN( ocSubTotal ) )
-            bSubTotal = true;
-    }
-
-    if (bSubTotal)
-        pDocument->AddSubTotalCell(this);
-}
-
-ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags ) :
-    ScBaseCell( rCell ),
-    SvtListener(),
-    aResult( rCell.aResult ),
-    eTempGrammar( rCell.eTempGrammar),
-    pDocument( &rDoc ),
-    pPrevious(0),
-    pNext(0),
-    pPreviousTrack(0),
-    pNextTrack(0),
-    nFormatIndex( &rDoc == rCell.pDocument ? rCell.nFormatIndex : 0 ),
-    nFormatType( rCell.nFormatType ),
-    nSeenInIteration(0),
-    cMatrixFlag ( rCell.cMatrixFlag ),
-    bDirty( rCell.bDirty ),
-    bChanged( rCell.bChanged ),
-    bRunning( false ),
-    bCompile( rCell.bCompile ),
-    bSubTotal( rCell.bSubTotal ),
-    bIsIterCell( false ),
-    bInChangeTrack( false ),
-    bTableOpDirty( false ),
-    bNeedListening( false ),
-    aPos( rPos )
-{
-    pCode = rCell.pCode->Clone();
-
-    //  set back any errors and recompile
-    //  not in the Clipboard - it must keep the received error flag
-    //  Special Length=0: as bad cells are generated, then they are also retained
-    if ( pCode->GetCodeError() && !pDocument->IsClipboard() && pCode->GetLen() )
-    {
-        pCode->SetCodeError( 0 );
-        bCompile = true;
-    }
-    //! Compile ColRowNames on URM_MOVE/URM_COPY _after_ UpdateReference
-    bool bCompileLater = false;
-    bool bClipMode = rCell.pDocument->IsClipboard();
-
-    //update ScNameTokens
-    if (!pDocument->IsClipOrUndo() || rDoc.IsUndo())
-    {
-        if (!pDocument->IsClipboardSource() || aPos.Tab() != rCell.aPos.Tab())
-        {
-            ScToken* pToken = NULL;
-            while((pToken = static_cast<ScToken*>(pCode->GetNextName()))!= NULL)
-            {
-                OpCode eOpCode = pToken->GetOpCode();
-                if (eOpCode == ocName)
-                    adjustRangeName(pToken, rDoc, rCell.pDocument, aPos, rCell.aPos);
-                else if (eOpCode == ocDBArea)
-                    adjustDBRange(pToken, rDoc, rCell.pDocument);
-            }
-        }
-
-        bool bCopyBetweenDocs = pDocument->GetPool() != rCell.pDocument->GetPool();
-        if (bCopyBetweenDocs && !(nCloneFlags & SC_CLONECELL_NOMAKEABS_EXTERNAL))
-        {
-            pCode->ReadjustAbsolute3DReferences( rCell.pDocument, &rDoc, rCell.aPos);
-        }
-
-        pCode->AdjustAbsoluteRefs( rCell.pDocument, rCell.aPos, aPos, false, bCopyBetweenDocs );
-    }
-
-    if ( nCloneFlags & SC_CLONECELL_ADJUST3DREL )
-        pCode->ReadjustRelative3DReferences( rCell.aPos, aPos );
-
-    if( !bCompile )
-    {   // Name references with references and ColRowNames
-        pCode->Reset();
-        ScToken* t;
-        while ( ( t = static_cast<ScToken*>(pCode->GetNextReferenceOrName()) ) != NULL && !bCompile )
-        {
-            if ( t->IsExternalRef() )
-            {
-                // External name, cell, and area references.
-                bCompile = true;
-            }
-            else if ( t->GetType() == svIndex )
-            {
-                ScRangeData* pRangeData = rDoc.GetRangeName()->findByIndex( t->GetIndex() );
-                if( pRangeData )
-                {
-                    if( pRangeData->HasReferences() )
-                        bCompile = true;
-                }
-                else
-                    bCompile = true;    // invalid reference!
-            }
-            else if ( t->GetOpCode() == ocColRowName )
-            {
-                bCompile = true;        // new lookup needed
-                bCompileLater = bClipMode;
-            }
-        }
-    }
-    if( bCompile )
-    {
-        if ( !bCompileLater && bClipMode )
-        {
-            // Merging ranges needs the actual positions after UpdateReference.
-            // ColRowNames need new lookup after positions are adjusted.
-            bCompileLater = pCode->HasOpCode( ocRange) || pCode->HasOpCode( ocColRowName);
-        }
-        if ( !bCompileLater )
-        {
-            // bNoListening, not at all if in Clipboard/Undo,
-            // and not from Clipboard either, instead after Insert(Clone) and UpdateReference.
-            CompileTokenArray( true );
-        }
-    }
-
-    if( nCloneFlags & SC_CLONECELL_STARTLISTENING )
-        StartListeningTo( &rDoc );
-
-    if (bSubTotal)
-        pDocument->AddSubTotalCell(this);
-}
-
-ScFormulaCell::~ScFormulaCell()
-{
-    pDocument->RemoveFromFormulaTree( this );
-    pDocument->RemoveSubTotalCell(this);
-    if (pCode->HasOpCode(ocMacro))
-        pDocument->GetMacroManager()->RemoveDependentCell(this);
-
-    if (pDocument->HasExternalRefManager())
-        pDocument->GetExternalRefManager()->removeRefCell(this);
-
-    delete pCode;
-#if OSL_DEBUG_LEVEL > 0
-    eCellType = CELLTYPE_DESTROYED;
-#endif
-}
-
-ScFormulaCell* ScFormulaCell::Clone() const
-{
-    return new ScFormulaCell(*this, *pDocument, aPos);
-}
-
-size_t ScFormulaCell::GetHash() const
-{
-    return pCode->GetHash();
-}
-
-ScFormulaVectorState ScFormulaCell::GetVectorState() const
-{
-    return pCode->GetVectorState();
-}
-
-void ScFormulaCell::GetFormula( rtl::OUStringBuffer& rBuffer,
-                                const FormulaGrammar::Grammar eGrammar ) const
-{
-    if( pCode->GetCodeError() && !pCode->GetLen() )
-    {
-        rBuffer = rtl::OUStringBuffer( ScGlobal::GetErrorString( pCode->GetCodeError()));
-        return;
-    }
-    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();
-            rRef.CalcAbsIfRel( aPos );
-            if ( rRef.Valid() )
-                pCell = pDocument->GetFormulaCell(
-                    ScAddress(rRef.nCol, rRef.nRow, rRef.nTab));
-
-            if (pCell)
-            {
-                pCell->GetFormula( rBuffer, eGrammar);
-                return;
-            }
-            else
-            {
-                ScCompiler aComp( pDocument, aPos, *pCode);
-                aComp.SetGrammar(eGrammar);
-                aComp.CreateStringFromTokenArray( rBuffer );
-            }
-        }
-        else
-        {
-            OSL_FAIL("ScFormulaCell::GetFormula: not a matrix");
-        }
-    }
-    else
-    {
-        ScCompiler aComp( pDocument, aPos, *pCode);
-        aComp.SetGrammar(eGrammar);
-        aComp.CreateStringFromTokenArray( rBuffer );
-    }
-
-    sal_Unicode ch('=');
-    rBuffer.insert( 0, &ch, 1 );
-    if( cMatrixFlag )
-    {
-        sal_Unicode ch2('{');
-        rBuffer.insert( 0, &ch2, 1);
-        rBuffer.append( sal_Unicode('}'));
-    }
-}
-
-void ScFormulaCell::GetFormula( rtl::OUString& rFormula, const FormulaGrammar::Grammar eGrammar ) const
-{
-    rtl::OUStringBuffer rBuffer( rFormula );
-    GetFormula( rBuffer, eGrammar );
-    rFormula = rBuffer.makeStringAndClear();
-}
-
-void ScFormulaCell::GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows )
-{
-    MaybeInterpret();
-
-    const ScMatrix* pMat = NULL;
-    if (!pCode->GetCodeError() && aResult.GetType() == svMatrixCell &&
-            ((pMat = static_cast<const ScToken*>(aResult.GetToken().get())->GetMatrix()) != 0))
-        pMat->GetDimensions( rCols, rRows );
-    else
-    {
-        rCols = 0;
-        rRows = 0;
-    }
-}
-
-void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
-                            const FormulaGrammar::Grammar eGrammar )
-{
-    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( pDocument, aPos);
-    aComp.SetGrammar(eGrammar);
-    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( bNoListening );
-    }
-    else
-    {
-        bChanged = true;
-        pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
-        pDocument->SetScriptType(aPos, SC_SCRIPTTYPE_UNKNOWN);
-    }
-    if ( bWasInFormulaTree )
-        pDocument->PutInFormulaTree( this );
-}
-
-
-void ScFormulaCell::CompileTokenArray( bool bNoListening )
-{
-    // Not already compiled?
-    if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
-        Compile( aResult.GetHybridFormula(), bNoListening, eTempGrammar);
-    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;
-
-        if( !bNoListening && pCode->GetCodeLen() )
-            EndListeningTo( pDocument );
-        ScCompiler aComp(pDocument, aPos, *pCode);
-        aComp.SetGrammar(pDocument->GetGrammar());
-        bSubTotal = aComp.CompileTokenArray();
-        if( !pCode->GetCodeError() )
-        {
-            nFormatType = aComp.GetNumFormatType();
-            nFormatIndex = 0;
-            bChanged = true;
-            aResult.SetToken( NULL);
-            bCompile = false;
-            if ( !bNoListening )
-                StartListeningTo( pDocument );
-        }
-        if ( bWasInFormulaTree )
-            pDocument->PutInFormulaTree( this );
-
-        if (bSubTotal)
-            pDocument->AddSubTotalCell(this);
-    }
-}
-
-
-void ScFormulaCell::CompileXML( ScProgress& rProgress )
-{
-    if ( cMatrixFlag == MM_REFERENCE )
-    {   // is already token code via ScDocFunc::EnterMatrix, ScDocument::InsertMatrixFormula
-        // just establish listeners
-        StartListeningTo( pDocument );
-        return ;
-    }
-
-    ScCompiler aComp( pDocument, aPos, *pCode);
-    aComp.SetGrammar(eTempGrammar);
-    rtl::OUString aFormula, aFormulaNmsp;
-    aComp.CreateStringFromXMLTokenArray( aFormula, aFormulaNmsp );
-    pDocument->DecXMLImportedFormulaCount( aFormula.getLength() );
-    rProgress.SetStateCountDownOnPercent( pDocument->GetXMLImportedFormulaCount() );
-    // pCode may not deleted for queries, but must be empty
-    if ( pCode )
-        pCode->Clear();
-    ScTokenArray* pCodeOld = pCode;
-    pCode = aComp.CompileString( aFormula, aFormulaNmsp );
-    delete pCodeOld;
-    if( !pCode->GetCodeError() )
-    {
-        if ( !pCode->GetLen() )
-        {
-            if ( aFormula[0] == '=' )
-                pCode->AddBad( aFormula.copy( 1 ) );
-            else
-                pCode->AddBad( aFormula );
-        }
-        bSubTotal = aComp.CompileTokenArray();
-        if( !pCode->GetCodeError() )
-        {
-            nFormatType = aComp.GetNumFormatType();
-            nFormatIndex = 0;
-            bChanged = true;
-            bCompile = false;
-            StartListeningTo( pDocument );
-        }
-
-        if (bSubTotal)
-            pDocument->AddSubTotalCell(this);
-    }
-    else
-    {
-        bChanged = true;
-        pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
-        pDocument->SetScriptType(aPos, SC_SCRIPTTYPE_UNKNOWN);
-    }
-
-    //  Same as in Load: after loading, it must be known if ocMacro is in any formula
-    //  (for macro warning, CompileXML is called at the end of loading XML file)
-    if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) )
-        pDocument->SetHasMacroFunc( true );
-
-    //volatile cells must be added here for import
-    if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() ||
-        pCode->IsRecalcModeOnLoad() || pCode->IsRecalcModeOnLoadOnce() )
-    {
-        // During load, only those cells that are marked explicitly dirty get
-        // recalculated.  So we need to set it dirty here.
-        SetDirtyVar();
-        pDocument->PutInFormulaTree(this);
-    }
-}
-
-
-void ScFormulaCell::CalcAfterLoad()
-{
-    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);
-        aResult.SetToken( NULL);
-        bDirty = true;
-        bNewCompiled = true;
-    }
-    // The UPN 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());
-        bSubTotal = aComp.CompileTokenArray();
-        nFormatType = aComp.GetNumFormatType();
-        nFormatIndex = 0;
-        bDirty = true;
-        bCompile = false;
-        bNewCompiled = true;
-
-        if (bSubTotal)
-            pDocument->AddSubTotalCell(this);
-    }
-
-    // On OS/2 with broken FPU exception, we can somehow store /0 without Err503. Later on in
-    // the BLC Lib NumberFormatter crashes when doing a fabs (NAN) (# 32739 #).
-    // We iron this out here for all systems, such that we also have an Err503 here.
-    if ( aResult.IsValue() && !::rtl::math::isFinite( aResult.GetDouble() ) )
-    {
-        OSL_FAIL("Formula cell INFINITY!!! Where does this document come from?");
-        aResult.SetResultError( errIllegalFPOperation );
-        bDirty = true;
-    }
-
-    // DoubleRefs for binary operators were always a Matrix before version v5.0.
-    // Now this is only the case when when in an array formula, otherwise it's an implicit intersection
-    if ( pDocument->GetSrcVersion() < SC_MATRIX_DOUBLEREF &&
-            GetMatrixFlag() == MM_NONE && pCode->HasMatrixDoubleRefOps() )
-    {
-        cMatrixFlag = MM_FORMULA;
-        SetMatColsRows( 1, 1);
-    }
-
-    // Do the cells need to be calculated? After Load cells can contain an error code, and then start
-    // the listener and Recalculate (if needed) if not RECALCMODE_NORMAL
-    if( !bNewCompiled || !pCode->GetCodeError() )
-    {
-        StartListeningTo( pDocument );
-        if( !pCode->IsRecalcModeNormal() )
-            bDirty = true;
-    }
-    if ( pCode->IsRecalcModeAlways() )
-    {   // random(), today(), now() always stay in the FormulaTree, so that they are calculated
-        // for each F9
-        bDirty = true;
-    }
-    // No SetDirty yet, as no all Listeners are known yet (only in SetDirtyAfterLoad)
-}
-
-
-bool ScFormulaCell::MarkUsedExternalReferences()
-{
-    return pCode && pDocument->MarkUsedExternalReferences( *pCode);
-}
-
-
-void ScFormulaCell::Interpret()
-{
-    if (!IsDirtyOrInTableOpDirty() || pDocument->GetRecursionHelper().IsInReturn())
-        return;     // no double/triple processing
-
-    //! HACK:
-    //  If the call originates from a Reschedule in DdeLink update, leave dirty
-    //  Better: Do a Dde Link Update without Reschedule or do it completely asynchronously!
-    if ( pDocument->IsInDdeLinkUpdate() )
-        return;
-
-    if (bRunning)
-    {
-        if (!pDocument->GetDocOptions().IsIter())
-        {
-            aResult.SetResultError( errCircularReference );
-            return;
-        }
-
-        if (aResult.GetResultError() == errCircularReference)
-            aResult.SetResultError( 0 );
-
-        // Start or add to iteration list.
-        if (!pDocument->GetRecursionHelper().IsDoingIteration() ||
-                !pDocument->GetRecursionHelper().GetRecursionInIterationStack().top()->bIsIterCell)
-            pDocument->GetRecursionHelper().SetInIterationReturn( true);
-
-        return;
-    }
-    // no multiple interprets for GetErrCode, IsValue, GetValue and
-    // different entry point recursions. Would also lead to premature
-    // convergence in iterations.
-    if (pDocument->GetRecursionHelper().GetIteration() && nSeenInIteration ==
-            pDocument->GetRecursionHelper().GetIteration())
-        return ;
-
-    ScRecursionHelper& rRecursionHelper = pDocument->GetRecursionHelper();
-    bool bOldRunning = bRunning;
-    if (rRecursionHelper.GetRecursionCount() > MAXRECURSION)
-    {
-        bRunning = true;
-        rRecursionHelper.SetInRecursionReturn( true);
-    }
-    else
-    {
-        if ( ! InterpretFormulaGroup() )
-            InterpretTail( SCITP_NORMAL);
-    }
-
-    // While leaving a recursion or iteration stack, insert its cells to the
-    // recursion list in reverse order.
-    if (rRecursionHelper.IsInReturn())
-    {
-        if (rRecursionHelper.GetRecursionCount() > 0 ||
-                !rRecursionHelper.IsDoingRecursion())
-            rRecursionHelper.Insert( this, bOldRunning, aResult);
-        bool bIterationFromRecursion = false;
-        bool bResumeIteration = false;
-        do
-        {
-            if ((rRecursionHelper.IsInIterationReturn() &&
-                        rRecursionHelper.GetRecursionCount() == 0 &&
-                        !rRecursionHelper.IsDoingIteration()) ||
-                    bIterationFromRecursion || bResumeIteration)
-            {
-                ScFormulaCell* pIterCell = this; // scope for debug convenience
-                bool & rDone = rRecursionHelper.GetConvergingReference();
-                rDone = false;
-                if (!bIterationFromRecursion && bResumeIteration)
-                {
-                    bResumeIteration = false;
-                    // Resuming iteration expands the range.
-                    ScFormulaRecursionList::const_iterator aOldStart(
-                            rRecursionHelper.GetLastIterationStart());
-                    rRecursionHelper.ResumeIteration();
-                    // Mark new cells being in iteration.
-                    for (ScFormulaRecursionList::const_iterator aIter(
-                                rRecursionHelper.GetIterationStart()); aIter !=
-                            aOldStart; ++aIter)
-                    {
-                        pIterCell = (*aIter).pCell;
-                        pIterCell->bIsIterCell = true;
-                    }
-                    // Mark older cells dirty again, in case they converted
-                    // without accounting for all remaining cells in the circle
-                    // that weren't touched so far, e.g. conditional. Restore
-                    // backuped result.
-                    sal_uInt16 nIteration = rRecursionHelper.GetIteration();
-                    for (ScFormulaRecursionList::const_iterator aIter(
-                                aOldStart); aIter !=
-                            rRecursionHelper.GetIterationEnd(); ++aIter)
-                    {
-                        pIterCell = (*aIter).pCell;
-                        if (pIterCell->nSeenInIteration == nIteration)
-                        {
-                            if (!pIterCell->bDirty || aIter == aOldStart)
-                            {
-                                pIterCell->aResult = (*aIter).aPreviousResult;
-                            }
-                            --pIterCell->nSeenInIteration;
-                        }
-                        pIterCell->bDirty = true;
-                    }
-                }
-                else
-                {
-                    bResumeIteration = false;
-                    // Close circle once.
-                    rRecursionHelper.GetList().back().pCell->InterpretTail(
-                            SCITP_CLOSE_ITERATION_CIRCLE);
-                    // Start at 1, init things.
-                    rRecursionHelper.StartIteration();
-                    // Mark all cells being in iteration.
-                    for (ScFormulaRecursionList::const_iterator aIter(
-                                rRecursionHelper.GetIterationStart()); aIter !=
-                            rRecursionHelper.GetIterationEnd(); ++aIter)
-                    {
-                        pIterCell = (*aIter).pCell;
-                        pIterCell->bIsIterCell = true;
-                    }
-                }
-                bIterationFromRecursion = false;
-                sal_uInt16 nIterMax = pDocument->GetDocOptions().GetIterCount();
-                for ( ; rRecursionHelper.GetIteration() <= nIterMax && !rDone;
-                        rRecursionHelper.IncIteration())
-                {
-                    rDone = true;
-                    for ( ScFormulaRecursionList::iterator aIter(
-                                rRecursionHelper.GetIterationStart()); aIter !=
-                            rRecursionHelper.GetIterationEnd() &&
-                            !rRecursionHelper.IsInReturn(); ++aIter)
-                    {
-                        pIterCell = (*aIter).pCell;
-                        if (pIterCell->IsDirtyOrInTableOpDirty() &&
-                                rRecursionHelper.GetIteration() !=
-                                pIterCell->GetSeenInIteration())
-                        {
-                            (*aIter).aPreviousResult = pIterCell->aResult;
-                            pIterCell->InterpretTail( SCITP_FROM_ITERATION);
-                        }
-                        rDone = rDone && !pIterCell->IsDirtyOrInTableOpDirty();
-                    }
-                    if (rRecursionHelper.IsInReturn())
-                    {
-                        bResumeIteration = true;
-                        break;  // for
-                        // Don't increment iteration.
-                    }
-                }
-                if (!bResumeIteration)
-                {
-                    if (rDone)
-                    {
-                        for (ScFormulaRecursionList::const_iterator aIter(
-                                    rRecursionHelper.GetIterationStart());
-                                aIter != rRecursionHelper.GetIterationEnd();
-                                ++aIter)
-                        {
-                            pIterCell = (*aIter).pCell;
-                            pIterCell->bIsIterCell = false;
-                            pIterCell->nSeenInIteration = 0;
-                            pIterCell->bRunning = (*aIter).bOldRunning;
-                        }
-                    }
-                    else
-                    {
-                        for (ScFormulaRecursionList::const_iterator aIter(
-                                    rRecursionHelper.GetIterationStart());
-                                aIter != rRecursionHelper.GetIterationEnd();
-                                ++aIter)
-                        {
-                            pIterCell = (*aIter).pCell;
-                            pIterCell->bIsIterCell = false;
-                            pIterCell->nSeenInIteration = 0;
-                            pIterCell->bRunning = (*aIter).bOldRunning;
-                            // If one cell didn't converge, all cells of this
-                            // circular dependency don't, no matter whether
-                            // single cells did.
-                            pIterCell->bDirty = false;
-                            pIterCell->bTableOpDirty = false;
-                            pIterCell->aResult.SetResultError( errNoConvergence);
-                            pIterCell->bChanged = true;
-                            pDocument->SetTextWidth(pIterCell->aPos, TEXTWIDTH_DIRTY);
-                            pDocument->SetScriptType(pIterCell->aPos, SC_SCRIPTTYPE_UNKNOWN);
-                        }
-                    }
-                    // End this iteration and remove entries.
-                    rRecursionHelper.EndIteration();
-                    bResumeIteration = rRecursionHelper.IsDoingIteration();
-                }
-            }
-            if (rRecursionHelper.IsInRecursionReturn() &&
-                    rRecursionHelper.GetRecursionCount() == 0 &&
-                    !rRecursionHelper.IsDoingRecursion())
-            {
-                bIterationFromRecursion = false;
-                // Iterate over cells known so far, start with the last cell
-                // encountered, inserting new cells if another recursion limit
-                // is reached. Repeat until solved.
-                rRecursionHelper.SetDoingRecursion( true);
-                do
-                {
-                    rRecursionHelper.SetInRecursionReturn( false);
-                    for (ScFormulaRecursionList::const_iterator aIter(
-                                rRecursionHelper.GetIterationStart());
-                            !rRecursionHelper.IsInReturn() && aIter !=
-                            rRecursionHelper.GetIterationEnd(); ++aIter)
-                    {
-                        ScFormulaCell* pCell = (*aIter).pCell;
-                        if (pCell->IsDirtyOrInTableOpDirty())
-                        {
-                            pCell->InterpretTail( SCITP_NORMAL);
-                            if (!pCell->IsDirtyOrInTableOpDirty() && !pCell->IsIterCell())
-                                pCell->bRunning = (*aIter).bOldRunning;
-                        }
-                    }
-                } while (rRecursionHelper.IsInRecursionReturn());
-                rRecursionHelper.SetDoingRecursion( false);
-                if (rRecursionHelper.IsInIterationReturn())
-                {
-                    if (!bResumeIteration)
-                        bIterationFromRecursion = true;
-                }
-                else if (bResumeIteration ||
-                        rRecursionHelper.IsDoingIteration())
-                    rRecursionHelper.GetList().erase(
-                            rRecursionHelper.GetIterationStart(),
-                            rRecursionHelper.GetLastIterationStart());
-                else
-                    rRecursionHelper.Clear();
-            }
-        } while (bIterationFromRecursion || bResumeIteration);
-    }
-}
-
-void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
-{
-    class RecursionCounter
-    {
-        ScRecursionHelper&  rRec;
-        bool                bStackedInIteration;
-        public:
-        RecursionCounter( ScRecursionHelper& r, ScFormulaCell* p ) : rRec(r)
-        {
-            bStackedInIteration = rRec.IsDoingIteration();
-            if (bStackedInIteration)
-                rRec.GetRecursionInIterationStack().push( p);
-            rRec.IncRecursionCount();
-        }
-        ~RecursionCounter()
-        {
-            rRec.DecRecursionCount();
-            if (bStackedInIteration)
-                rRec.GetRecursionInIterationStack().pop();
-        }
-    } aRecursionCounter( pDocument->GetRecursionHelper(), this);
-    nSeenInIteration = pDocument->GetRecursionHelper().GetIteration();
-    if( !pCode->GetCodeLen() && !pCode->GetCodeError() )
-    {
-        // #i11719# no UPN and no error and no token code but result string present
-        // => interpretation of this cell during name-compilation and unknown names
-        // => can't exchange underlying code array in CompileTokenArray() /
-        // Compile() because interpreter's token iterator would crash or pCode
-        // would be deleted twice if this cell was interpreted during
-        // compilation.
-        // This should only be a temporary condition and, since we set an
-        // error, if ran into it again we'd bump into the dirty-clearing
-        // condition further down.
-        if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
-        {
-            pCode->SetCodeError( errNoCode );
-            // This is worth an assertion; if encountered in daily work
-            // documents we might need another solution. Or just confirm correctness.
-            OSL_FAIL( "ScFormulaCell::Interpret: no UPN, no error, no token, but hybrid formula string" );
-            return;
-        }
-        CompileTokenArray();
-    }
-
-    if( pCode->GetCodeLen() && pDocument )
-    {
-        class StackCleaner
-        {
-            ScDocument*     pDoc;
-            ScInterpreter*  pInt;
-            public:
-            StackCleaner( ScDocument* pD, ScInterpreter* pI )
-                : pDoc(pD), pInt(pI)
-                {}
-            ~StackCleaner()
-            {
-                delete pInt;
-                pDoc->DecInterpretLevel();
-            }
-        };
-        pDocument->IncInterpretLevel();
-        ScInterpreter* p = new ScInterpreter( this, pDocument, aPos, *pCode );
-        StackCleaner aStackCleaner( pDocument, p);
-        sal_uInt16 nOldErrCode = aResult.GetResultError();
-        if ( nSeenInIteration == 0 )
-        {   // Only the first time
-            // With bChanged=false, if a newly compiled cell has a result of
-            // 0.0, no change is detected and the cell will not be repainted.
-            // bChanged = false;
-            aResult.SetResultError( 0 );
-        }
-
-        switch ( aResult.GetResultError() )
-        {
-            case errCircularReference :     // will be determined again if so
-                aResult.SetResultError( 0 );
-            break;
-        }
-
-        bool bOldRunning = bRunning;
-        bRunning = true;
-        p->Interpret();
-        if (pDocument->GetRecursionHelper().IsInReturn() && eTailParam != SCITP_CLOSE_ITERATION_CIRCLE)
-        {
-            if (nSeenInIteration > 0)
-                --nSeenInIteration;     // retry when iteration is resumed
-            return;
-        }
-        bRunning = bOldRunning;
-
-        // #i102616# For single-sheet saving consider only content changes, not format type,
-        // because format type isn't set on loading (might be changed later)
-        bool bContentChanged = false;
-
-        // Do not create a HyperLink() cell if the formula results in an error.
-        if( p->GetError() && pCode->IsHyperLink())
-            pCode->SetHyperLink(false);
-
-        if( p->GetError() && p->GetError() != errCircularReference)
-        {
-            bDirty = false;
-            bTableOpDirty = false;
-            bChanged = true;
-        }
-        if (eTailParam == SCITP_FROM_ITERATION && IsDirtyOrInTableOpDirty())
-        {
-            bool bIsValue = aResult.IsValue();  // the previous type
-            // Did it converge?
-            if ((bIsValue && p->GetResultType() == svDouble && fabs(
-                            p->GetNumResult() - aResult.GetDouble()) <=
-                        pDocument->GetDocOptions().GetIterEps()) ||
-                    (!bIsValue && p->GetResultType() == svString &&
-                     p->GetStringResult() == aResult.GetString()))
-            {
-                // A convergence in the first iteration doesn't necessarily
-                // mean that it's done, it may be as not all related cells
-                // of a circle changed their values yet. If the set really
-                // converges it will do so also during the next iteration. This
-                // fixes situations like of #i44115#. If this wasn't wanted an
-                // initial "uncalculated" value would be needed for all cells
-                // of a circular dependency => graph needed before calculation.
-                if (nSeenInIteration > 1 ||
-                        pDocument->GetDocOptions().GetIterCount() == 1)
-                {
-                    bDirty = false;
-                    bTableOpDirty = false;
-                }
-            }
-        }
-
-        // New error code?
-        if( p->GetError() != nOldErrCode )
-        {
-            bChanged = true;
-            // bContentChanged only has to be set if the file content would be changed
-            if ( aResult.GetCellResultType() != svUnknown )
-                bContentChanged = true;
-        }
-        // Different number format?
-        if( nFormatType != p->GetRetFormatType() )
-        {
-            nFormatType = p->GetRetFormatType();
-            bChanged = true;
-        }
-        if( nFormatIndex != p->GetRetFormatIndex() )
-        {
-            nFormatIndex = p->GetRetFormatIndex();
-            bChanged = true;
-        }
-
-        // In case of changes just obtain the result, no temporary and
-        // comparison needed anymore.
-        if (bChanged)
-        {
-            // #i102616# Compare anyway if the sheet is still marked unchanged for single-sheet saving
-            // Also handle special cases of initial results after loading.
-            if ( !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
-            {
-                ScFormulaResult aNewResult( p->GetResultToken().get());
-                StackVar eOld = aResult.GetCellResultType();
-                StackVar eNew = aNewResult.GetCellResultType();
-                if ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && aNewResult.GetDouble() == 0.0 ) ) )
-                {
-                    // ScXMLTableRowCellContext::EndElement doesn't call SetFormulaResultDouble for 0
-                    // -> no change
-                }
-                else
-                {
-                    if ( eOld == svHybridCell || eOld == svHybridValueCell )     // string result from SetFormulaResultString?
-                        eOld = svString;            // ScHybridCellToken has a valid GetString method
-
-                    // #i106045# use approxEqual to compare with stored value
-                    bContentChanged = (eOld != eNew ||
-                            (eNew == svDouble && !rtl::math::approxEqual( aResult.GetDouble(), aNewResult.GetDouble() )) ||
-                            (eNew == svString && aResult.GetString() != aNewResult.GetString()));
-                }
-            }
-
-            aResult.SetToken( p->GetResultToken().get() );
-        }
-        else
-        {
-            ScFormulaResult aNewResult( p->GetResultToken().get());
-            StackVar eOld = aResult.GetCellResultType();
-            StackVar eNew = aNewResult.GetCellResultType();
-            bChanged = (eOld != eNew ||
-                    (eNew == svDouble && aResult.GetDouble() != aNewResult.GetDouble()) ||
-                    (eNew == svString && aResult.GetString() != aNewResult.GetString()));
-
-            // #i102616# handle special cases of initial results after loading (only if the sheet is still marked unchanged)
-            if ( bChanged && !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
-            {
-                if ( ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && aNewResult.GetDouble() == 0.0 ) ) ) ||
-                     ( (eOld == svHybridCell || eOld == svHybridValueCell) && eNew == svString && aResult.GetString() == aNewResult.GetString() ) ||
-                     ( eOld == svDouble && eNew == svDouble && rtl::math::approxEqual( aResult.GetDouble(), aNewResult.GetDouble() ) ) )
-                {
-                    // no change, see above
-                }
-                else
-                    bContentChanged = true;
-            }
-
-            aResult.Assign( aNewResult);
-        }
-
-        // Precision as shown?
-        if ( aResult.IsValue() && !p->GetError()
-          && pDocument->GetDocOptions().IsCalcAsShown()
-          && nFormatType != NUMBERFORMAT_DATE
-          && nFormatType != NUMBERFORMAT_TIME
-          && nFormatType != NUMBERFORMAT_DATETIME )
-        {
-            sal_uLong nFormat = pDocument->GetNumberFormat( aPos );
-            if ( nFormatIndex && (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
-                nFormat = nFormatIndex;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list