[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 167 commits - android/experimental android/sdremote avmedia/source basctl/source basebmp/test basic/source bean/native bridges/source canvas/source chart2/source codemaker/inc codemaker/source comphelper/inc comphelper/Library_comphelper.mk comphelper/Package_inc.mk comphelper/README comphelper/source config_host/config_features.h.in config_host.mk.in config_host/README configmgr/Library_configmgr.mk configmgr/source configure.ac connectivity/inc connectivity/Library_postgresql-sdbc-impl.mk connectivity/source cppcanvas/source cppuhelper/source cppunit/ExternalPackage_cppunit.mk crashrep/source cui/source dbaccess/source dbaccess/uiconfig dbaccess/UI_dbaccess.mk desktop/Library_deployment.mk desktop/Module_desktop.mk desktop/source desktop/unx desktop/win32 drawinglayer/inc drawinglayer/source editeng/source extensions/source filter/Configuration_filter.mk filter/Library_filterconfig.mk filter/source forms/source formu la/source fpicker/source framework/source hwpfilter/source i18npool/inc i18npool/qa i18npool/source i18nutil/source icu/ExternalPackage_icu.mk icu/ExternalProject_icu.mk idlc/source jvmfwk/plugins jvmfwk/source l10ntools/inc l10ntools/source l10ntools/StaticLibrary_transex.mk libpng/StaticLibrary_png.mk lingucomponent/source logerrit Makefile.in nss/ExternalProject_nss.mk nss/nsinstall.py oox/source package/source padmin/source postprocess/Rdb_services.mk redland/ExternalProject_redland.mk registry/source remotebridges/source reportdesign/source rsc/inc rsc/source sal/android sal/inc sal/osl sal/rtl sax/source scaddins/source sccomp/source sc/inc sc/Library_sc.mk sc/qa scripting/source sc/source sd/source sfx2/inc sfx2/source shell/source slideshow/source solenv/bin solenv/gbuild soltools/cpp sot/source starmath/source stoc/source svl/source svtools/source svx/Library_svxcore.mk svx/source sw/inc sw/qa sw/source toolkit/source tools/source ucb/source unodevtools/Executable_s keletonmaker.mk unodevtools/inc unodevtools/source unotools/source vbahelper/source vcl/aqua vcl/generic vcl/source vcl/unx wizards/com wizards/Pyuno_web.mk writerfilter/source writerperfect/source xmlhelp/Library_tvhlp1.mk xmlhelp/Library_ucpchelp1.mk xmlhelp/source xmloff/source xmlsecurity/source xpdf/ExternalProject_xpdf.mk

Kohei Yoshida kohei.yoshida at gmail.com
Wed Mar 27 22:11:54 PDT 2013


Rebased ref, commits from common ancestor:
commit 6a944422c42a27ce9dc6fd2432c18f3743ac088f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Mar 28 01:07:36 2013 -0400

    A bit more.
    
    Change-Id: I7617bfa094ba8e6fb2c19944362bd604f5299732

diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 0dff21a..cee5df3 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -723,17 +723,16 @@ void ScFormulaCell::GetFormula( rtl::OUStringBuffer& rBuffer,
              * pCell only if (!this->IsInChangeTrack()),
              * GetEnglishFormula() omitted that test.
              * Can we live without in all cases? */
-            ScBaseCell* pCell;
+            ScFormulaCell* pCell = NULL;
             ScSingleRefData& rRef = p->GetSingleRef();
             rRef.CalcAbsIfRel( aPos );
             if ( rRef.Valid() )
-                pCell = pDocument->GetCell( ScAddress( rRef.nCol,
-                            rRef.nRow, rRef.nTab ) );
-            else
-                pCell = NULL;
-            if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+                pCell = pDocument->GetFormulaCell(
+                    ScAddress(rRef.nCol, rRef.nRow, rRef.nTab));
+
+            if (pCell)
             {
-                ((ScFormulaCell*)pCell)->GetFormula( rBuffer, eGrammar);
+                pCell->GetFormula( rBuffer, eGrammar);
                 return;
             }
             else
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index 958162f..cd75cdd 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -67,6 +67,7 @@
 #include "rangelst.hxx"
 #include "reftokenhelper.hxx"
 #include "formulaiter.hxx"
+#include "cellvalue.hxx"
 
 #include <vector>
 
@@ -821,14 +822,12 @@ sal_uInt16 ScDetectiveFunc::InsertPredLevelArea( const ScRange& rRef,
 sal_uInt16 ScDetectiveFunc::InsertPredLevel( SCCOL nCol, SCROW nRow, ScDetectiveData& rData,
                                             sal_uInt16 nLevel )
 {
-    ScBaseCell* pCell;
-    pDoc->GetCell( nCol, nRow, nTab, pCell );
-    if (!pCell)
-        return DET_INS_EMPTY;
-    if (pCell->GetCellType() != CELLTYPE_FORMULA)
+    ScRefCellValue aCell;
+    aCell.assign(*pDoc, ScAddress(nCol, nRow, nTab));
+    if (aCell.meType != CELLTYPE_FORMULA)
         return DET_INS_EMPTY;
 
-    ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+    ScFormulaCell* pFCell = aCell.mpFormula;
     if (pFCell->IsRunning())
         return DET_INS_CIRCULAR;
 
@@ -838,7 +837,7 @@ sal_uInt16 ScDetectiveFunc::InsertPredLevel( SCCOL nCol, SCROW nRow, ScDetective
 
     sal_uInt16 nResult = DET_INS_EMPTY;
 
-    ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+    ScDetectiveRefIter aIter(pFCell);
     ScRange aRef;
     while ( aIter.GetNextRef( aRef ) )
     {
@@ -912,14 +911,12 @@ sal_uInt16 ScDetectiveFunc::FindPredLevel( SCCOL nCol, SCROW nRow, sal_uInt16 nL
 {
     OSL_ENSURE( nLevel<1000, "Level" );
 
-    ScBaseCell* pCell;
-    pDoc->GetCell( nCol, nRow, nTab, pCell );
-    if (!pCell)
-        return nLevel;
-    if (pCell->GetCellType() != CELLTYPE_FORMULA)
+    ScRefCellValue aCell;
+    aCell.assign(*pDoc, ScAddress(nCol, nRow, nTab));
+    if (aCell.meType != CELLTYPE_FORMULA)
         return nLevel;
 
-    ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+    ScFormulaCell* pFCell = aCell.mpFormula;
     if (pFCell->IsRunning())
         return nLevel;
 
@@ -935,7 +932,7 @@ sal_uInt16 ScDetectiveFunc::FindPredLevel( SCCOL nCol, SCROW nRow, sal_uInt16 nL
         DeleteArrowsAt( nCol, nRow, sal_True );                 // Pfeile, die hierher zeigen
     }
 
-    ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+    ScDetectiveRefIter aIter(pFCell);
     ScRange aRef;
     while ( aIter.GetNextRef( aRef) )
     {
@@ -974,14 +971,12 @@ sal_uInt16 ScDetectiveFunc::FindPredLevel( SCCOL nCol, SCROW nRow, sal_uInt16 nL
 sal_uInt16 ScDetectiveFunc::InsertErrorLevel( SCCOL nCol, SCROW nRow, ScDetectiveData& rData,
                                             sal_uInt16 nLevel )
 {
-    ScBaseCell* pCell;
-    pDoc->GetCell( nCol, nRow, nTab, pCell );
-    if (!pCell)
-        return DET_INS_EMPTY;
-    if (pCell->GetCellType() != CELLTYPE_FORMULA)
+    ScRefCellValue aCell;
+    aCell.assign(*pDoc, ScAddress(nCol, nRow, nTab));
+    if (aCell.meType != CELLTYPE_FORMULA)
         return DET_INS_EMPTY;
 
-    ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+    ScFormulaCell* pFCell = aCell.mpFormula;
     if (pFCell->IsRunning())
         return DET_INS_CIRCULAR;
 
@@ -991,7 +986,7 @@ sal_uInt16 ScDetectiveFunc::InsertErrorLevel( SCCOL nCol, SCROW nRow, ScDetectiv
 
     sal_uInt16 nResult = DET_INS_EMPTY;
 
-    ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
+    ScDetectiveRefIter aIter(pFCell);
     ScRange aRef;
     ScAddress aErrorPos;
     sal_Bool bHasError = false;
commit 226aefbc5587568c60c966ff22762e77c7838fd4
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Mar 28 00:54:35 2013 -0400

    Reduce calls to ScDocument::GetCell().
    
    Change-Id: I39196eced68d25b6b2ae1378f712564badfc4572

diff --git a/sc/inc/cellform.hxx b/sc/inc/cellform.hxx
index 373d6e6..08561f8 100644
--- a/sc/inc/cellform.hxx
+++ b/sc/inc/cellform.hxx
@@ -48,7 +48,7 @@ public:
         bool bUseStarFormat = false );
 
     static OUString GetString(
-        const ScDocument& rDoc, const ScAddress& rPos, sal_uLong nFormat,
+        ScDocument& rDoc, const ScAddress& rPos, sal_uLong nFormat,
         Color** ppColor, SvNumberFormatter& rFormatter, bool bNullVals = true,
         bool bFormula  = false, ScForceTextFmt eForceTextFmt = ftDontForce, bool bUseStarFormat = false );
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index ec944f6..88fcd11 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1706,15 +1706,12 @@ public:
     void                EndListeningArea( const ScRange& rRange,
                                             SvtListener* pListener );
                         /** Broadcast wrapper, calls
-    SC_DLLPUBLIC                         rHint.GetCell()->Broadcast() and AreaBroadcast()
+                            rHint.GetCell()->Broadcast() and AreaBroadcast()
                             and TrackFormulas() and conditional format list
                             SourceChanged().
                             Preferred.
                          */
     void                Broadcast( const ScHint& rHint );
-                        /// deprecated
-    void                Broadcast( sal_uLong nHint, const ScAddress& rAddr,
-                                    ScBaseCell* pCell );
                         /// only area, no cell broadcast
     void                AreaBroadcast( const ScHint& rHint );
                         /// only areas in range, no cell broadcasts
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 7603b05..b443d65 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -593,7 +593,7 @@ sal_uInt16 ScFormulaCell::GetMatrixEdge( ScAddress& rOrgPos )
                 rOrgPos = aOrg;
                 ScFormulaCell* pFCell;
                 if ( cMatrixFlag == MM_REFERENCE )
-                    pFCell = (ScFormulaCell*) pDocument->GetCell( aOrg );
+                    pFCell = pDocument->GetFormulaCell(aOrg);
                 else
                     pFCell = this;      // this MM_FORMULA
                 // There's only one this, don't compare pFCell==this.
@@ -607,17 +607,15 @@ sal_uInt16 ScFormulaCell::GetMatrixEdge( ScAddress& rOrgPos )
                         nC = 1;
                         nR = 1;
                         ScAddress aTmpOrg;
-                        ScBaseCell* pCell;
+                        ScFormulaCell* pCell;
                         ScAddress aAdr( aOrg );
                         aAdr.IncCol();
                         bool bCont = true;
                         do
                         {
-                            pCell = pDocument->GetCell( aAdr );
-                            if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
-                              && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
-                              && ((ScFormulaCell*)pCell)->GetMatrixOrigin( aTmpOrg )
-                              && aTmpOrg == aOrg )
+                            pCell = pDocument->GetFormulaCell(aAdr);
+                            if (pCell && pCell->cMatrixFlag == MM_REFERENCE &&
+                                pCell->GetMatrixOrigin(aTmpOrg) && aTmpOrg == aOrg)
                             {
                                 nC++;
                                 aAdr.IncCol();
@@ -630,11 +628,9 @@ sal_uInt16 ScFormulaCell::GetMatrixEdge( ScAddress& rOrgPos )
                         bCont = true;
                         do
                         {
-                            pCell = pDocument->GetCell( aAdr );
-                            if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
-                              && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
-                              && ((ScFormulaCell*)pCell)->GetMatrixOrigin( aTmpOrg )
-                              && aTmpOrg == aOrg )
+                            pCell = pDocument->GetFormulaCell(aAdr);
+                            if (pCell && pCell->cMatrixFlag == MM_REFERENCE &&
+                                pCell->GetMatrixOrigin(aTmpOrg) && aTmpOrg == aOrg)
                             {
                                 nR++;
                                 aAdr.IncRow();
@@ -1766,13 +1762,10 @@ bool ScFormulaCell::InterpretFormulaGroup()
         InterpretTail( SCITP_NORMAL );
         for ( sal_Int32 i = 0; i < xGroup->mnLength; i++ )
         {
-            ScBaseCell *pBaseCell = NULL;
-            pDocument->GetCell( aPos.Col(),
-                                xGroup->mnStart + i,
-                                aPos.Tab(), pBaseCell );
-            assert( pBaseCell != NULL );
-            assert( pBaseCell->GetCellType() == CELLTYPE_FORMULA );
-            ScFormulaCell *pCell = static_cast<ScFormulaCell *>( pBaseCell );
+            ScAddress aTmpPos = aPos;
+            aTmpPos.SetRow(xGroup->mnStart + i);
+            ScFormulaCell* pCell = pDocument->GetFormulaCell(aTmpPos);
+            assert( pCell != NULL );
 
             // FIXME: this set of horrors is unclear to me ... certainly
             // the above GetCell is profoundly nasty & slow ...
diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx
index 754cbdc..f7d3493 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -282,7 +282,7 @@ std::vector<double>& ScColorFormat::getValues() const
                     }
                     else if(eType == CELLTYPE_FORMULA)
                     {
-                        if(static_cast<ScFormulaCell*>(mpDoc->GetCell(aAddr))->IsValue())
+                        if (mpDoc->GetFormulaCell(aAddr)->IsValue())
                         {
                             double aVal = mpDoc->GetValue(nCol, nRow, nTab);
                             rValues.push_back(aVal);
@@ -406,7 +406,7 @@ Color* ScColorScaleFormat::GetColor( const ScAddress& rAddr ) const
 
     if (eCellType == CELLTYPE_FORMULA)
     {
-        if(!static_cast<ScFormulaCell*>(mpDoc->GetCell(rAddr))->IsValue())
+        if (!mpDoc->GetFormulaCell(rAddr)->IsValue())
             return NULL;
     }
 
@@ -663,7 +663,7 @@ ScDataBarInfo* ScDataBarFormat::GetDataBarInfo(const ScAddress& rAddr) const
 
     if (eCellType == CELLTYPE_FORMULA)
     {
-        if(!static_cast<ScFormulaCell*>(mpDoc->GetCell(rAddr))->IsValue())
+        if (!mpDoc->GetFormulaCell(rAddr)->IsValue())
             return NULL;
     }
 
@@ -801,7 +801,7 @@ ScIconSetInfo* ScIconSetFormat::GetIconSetInfo(const ScAddress& rAddr) const
 
     if (eCellType == CELLTYPE_FORMULA)
     {
-        if(!static_cast<ScFormulaCell*>(mpDoc->GetCell(rAddr))->IsValue())
+        if (!mpDoc->GetFormulaCell(rAddr)->IsValue())
             return NULL;
     }
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 150b5ad..1712fbe 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -221,7 +221,7 @@ bool ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const
                                 ScFormulaCell* pFCell;
                                 if ( ((ScFormulaCell*)pCell)->GetMatrixFlag()
                                         == MM_REFERENCE )
-                                    pFCell = (ScFormulaCell*) pDocument->GetCell( aOrg );
+                                    pFCell = pDocument->GetFormulaCell(aOrg);
                                 else
                                     pFCell = (ScFormulaCell*)pCell;
                                 SCCOL nC;
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index f813464..96ebc36 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -62,18 +62,6 @@ void ScDocument::EndListeningArea( const ScRange& rRange,
         pBASM->EndListeningArea( rRange, pListener );
 }
 
-
-void ScDocument::Broadcast( sal_uLong nHint, const ScAddress& rAddr,
-        ScBaseCell* pCell
-    )
-{
-    if ( !pBASM )
-        return ;    // Clipboard or Undo
-    ScHint aHint(nHint, rAddr, pCell ? pCell->GetBroadcaster() : NULL);
-    Broadcast( aHint );
-}
-
-
 void ScDocument::Broadcast( const ScHint& rHint )
 {
     if ( !pBASM )
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 6970b54..b467745 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -440,9 +440,8 @@ void ScTable::FillFormula(sal_uLong& /* nFormulaCounter */, bool /* bFirst */, S
         {
             if ( nDestCol >= aOrg.Col() && nDestRow >= aOrg.Row() )
             {
-                ScBaseCell* pOrgCell = pDocument->GetCell( aOrg );
-                if ( pOrgCell && pOrgCell->GetCellType() == CELLTYPE_FORMULA
-                  && ((ScFormulaCell*)pOrgCell)->GetMatrixFlag() == MM_FORMULA )
+                ScFormulaCell* pOrgCell = pDocument->GetFormulaCell(aOrg);
+                if (pOrgCell && pOrgCell->GetMatrixFlag() == MM_FORMULA)
                 {
                     ((ScFormulaCell*)pOrgCell)->SetMatColsRows(
                         nDestCol - aOrg.Col() + 1,
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 644b1a6..86e6b4f 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -1166,7 +1166,7 @@ void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* p
             switch ( pCell->GetCellType() )
             {
                 case CELLTYPE_VALUE :
-                    pDocument->Broadcast(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab), pCell);
+                    pDocument->Broadcast(ScHint(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab), pCell->GetBroadcaster()));
                     break;
                 case CELLTYPE_FORMULA :
                     ((ScFormulaCell*)pCell)->SetDirty();
@@ -1208,8 +1208,8 @@ void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* p
                 switch ( pCell->GetCellType() )
                 {
                     case CELLTYPE_VALUE :
-                        pDocument->Broadcast( SC_HINT_DATACHANGED,
-                            ScAddress( nCol, nRow, nTab ), pCell );
+                        pDocument->Broadcast(
+                            ScHint(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab), pCell->GetBroadcaster()));
                         break;
                     case CELLTYPE_FORMULA :
                         ((ScFormulaCell*)pCell)->SetDirty();
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 760a0c7..0fdc89c 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -52,6 +52,7 @@ struct ScComplexRefData;
 class ScToken;
 class ScJumpMatrix;
 class ScCellIterator;
+class ScRefCellValue;
 
 #define MAXSTACK      (4096 / sizeof(formula::FormulaToken*))
 
@@ -187,12 +188,13 @@ bool IsTableOpInRange( const ScRange& );
 sal_uLong GetCellNumberFormat( const ScAddress&, const ScBaseCell* );
 double ConvertStringToValue( const String& );
 double GetCellValue( const ScAddress&, const ScBaseCell* );
-double GetCellValue( ScCellIterator& rIter );
+double GetCellValue( const ScAddress&, ScRefCellValue& rCell );
 double GetCellValueOrZero( const ScAddress&, const ScBaseCell* );
-double GetCellValueOrZero( ScCellIterator& rIter );
+double GetCellValueOrZero( const ScAddress&, ScRefCellValue& rCell );
 double GetValueCellValue( const ScAddress&, const ScValueCell* );
 ScBaseCell* GetCell( const ScAddress& rPos );
 void GetCellString( String& rStr, const ScBaseCell* pCell );
+void GetCellString( OUString& rStr, ScRefCellValue& rCell );
 sal_uInt16 GetCellErrCode( const ScBaseCell* pCell );
 CellType GetCellType( const ScBaseCell* pCell );
 bool HasCellEmptyData( const ScBaseCell* pCell );
diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx
index d60627b..1ddfaaa 100644
--- a/sc/source/core/tool/cellform.cxx
+++ b/sc/source/core/tool/cellform.cxx
@@ -136,7 +136,7 @@ void ScCellFormat::GetString( ScRefCellValue& rCell, sal_uLong nFormat, OUString
 }
 
 OUString ScCellFormat::GetString(
-    const ScDocument& rDoc, const ScAddress& rPos, sal_uLong nFormat, Color** ppColor,
+    ScDocument& rDoc, const ScAddress& rPos, sal_uLong nFormat, Color** ppColor,
     SvNumberFormatter& rFormatter, bool bNullVals, bool bFormula, ScForceTextFmt eForceTextFmt,
     bool bUseStarFormat )
 {
@@ -180,7 +180,7 @@ OUString ScCellFormat::GetString(
         break;
         case CELLTYPE_FORMULA:
         {
-            ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(rDoc.GetCell(rPos));
+            ScFormulaCell* pFCell = rDoc.GetFormulaCell(rPos);
             if (bFormula)
             {
                 pFCell->GetFormula(aString);
diff --git a/sc/source/core/tool/chartarr.cxx b/sc/source/core/tool/chartarr.cxx
index e88c6c1..34f4605 100644
--- a/sc/source/core/tool/chartarr.cxx
+++ b/sc/source/core/tool/chartarr.cxx
@@ -116,7 +116,7 @@ ScMemChart* ScChartArray::CreateMemChart()
 
 namespace {
 
-double getCellValue( const ScDocument& rDoc, const ScAddress& rPos, double fDefault, bool bCalcAsShown )
+double getCellValue( ScDocument& rDoc, const ScAddress& rPos, double fDefault, bool bCalcAsShown )
 {
     double fRet = fDefault;
 
@@ -135,7 +135,7 @@ double getCellValue( const ScDocument& rDoc, const ScAddress& rPos, double fDefa
         break;
         case CELLTYPE_FORMULA:
         {
-            ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(rDoc.GetCell(rPos));
+            ScFormulaCell* pFCell = rDoc.GetFormulaCell(rPos);
             if (!pFCell->GetErrCode() && pFCell->IsValue())
                 fRet = pFCell->GetValue();
         }
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 80428a4..b8bf5dd 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -5277,8 +5277,10 @@ bool ScCompiler::HandleSingleRef()
     }
     if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() )
     {   // automagically or created by copying and NamePos isn't in list
-        bool bString = pDoc->HasStringData( nCol, nRow, nTab );
-        if ( !bString && !pDoc->GetCell( aLook ) )
+        ScRefCellValue aCell;
+        aCell.assign(*pDoc, aLook);
+        bool bString = aCell.hasString();
+        if (!bString && aCell.isEmpty())
             bString = true;     // empty cell is ok
         if ( bString )
         {   //! coresponds with ScInterpreter::ScColRowNameAuto()
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index a3d77ff..a54748f 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -470,11 +470,11 @@ double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCe
     return nVal;
 }
 
-double ScInterpreter::GetCellValue( ScCellIterator& rIter )
+double ScInterpreter::GetCellValue( const ScAddress& rPos, ScRefCellValue& rCell )
 {
     sal_uInt16 nErr = nGlobalError;
     nGlobalError = 0;
-    double nVal = GetCellValueOrZero(rIter);
+    double nVal = GetCellValueOrZero(rPos, rCell);
     if ( !nGlobalError || nGlobalError == errCellNoValue )
         nGlobalError = nErr;
     return nVal;
@@ -552,18 +552,16 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
     return fValue;
 }
 
-double ScInterpreter::GetCellValueOrZero( ScCellIterator& rIter )
+double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, ScRefCellValue& rCell )
 {
-    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellValueOrZero" );
     double fValue = 0.0;
 
-    CellType eType = rIter.getType();
-    const ScAddress& rPos = rIter.GetPos();
+    CellType eType = rCell.meType;
     switch (eType)
     {
         case CELLTYPE_FORMULA:
         {
-            ScFormulaCell* pFCell = rIter.getFormulaCell();
+            ScFormulaCell* pFCell = rCell.mpFormula;
             sal_uInt16 nErr = pFCell->GetErrCode();
             if( !nErr )
             {
@@ -588,7 +586,7 @@ double ScInterpreter::GetCellValueOrZero( ScCellIterator& rIter )
         break;
         case CELLTYPE_VALUE:
         {
-            fValue = rIter.getValue();
+            fValue = rCell.mfValue;
             nCurFmtIndex = pDok->GetNumberFormat( rPos );
             nCurFmtType = pFormatter->GetType( nCurFmtIndex );
             if ( bCalcAsShown && fValue != 0.0 )
@@ -600,7 +598,7 @@ double ScInterpreter::GetCellValueOrZero( ScCellIterator& rIter )
         {
             // SUM(A1:A2) differs from A1+A2. No good. But people insist on
             // it ... #i5658#
-            OUString aStr = rIter.getString();
+            OUString aStr = rCell.getString();
             fValue = ConvertStringToValue( aStr );
         }
         break;
@@ -673,6 +671,48 @@ void ScInterpreter::GetCellString( String& rStr, const ScBaseCell* pCell )
     SetError(nErr);
 }
 
+void ScInterpreter::GetCellString( OUString& rStr, ScRefCellValue& rCell )
+{
+    sal_uInt16 nErr = 0;
+
+    switch (rCell.meType)
+    {
+        case CELLTYPE_STRING:
+        case CELLTYPE_EDIT:
+            rStr = rCell.getString();
+        break;
+        case CELLTYPE_FORMULA:
+        {
+            ScFormulaCell* pFCell = rCell.mpFormula;
+            nErr = pFCell->GetErrCode();
+            if (pFCell->IsValue())
+            {
+                double fVal = pFCell->GetValue();
+                sal_uLong nIndex = pFormatter->GetStandardFormat(
+                                    NUMBERFORMAT_NUMBER,
+                                    ScGlobal::eLnge);
+                pFormatter->GetInputLineString(fVal, nIndex, rStr);
+            }
+            else
+                rStr = pFCell->GetString();
+        }
+        break;
+        case CELLTYPE_VALUE:
+        {
+            double fVal = rCell.mfValue;
+            sal_uLong nIndex = pFormatter->GetStandardFormat(
+                                    NUMBERFORMAT_NUMBER,
+                                    ScGlobal::eLnge);
+            pFormatter->GetInputLineString(fVal, nIndex, rStr);
+        }
+        break;
+        default:
+            rStr = ScGlobal::GetEmptyString();
+        break;
+    }
+
+    SetError(nErr);
+}
 
 bool ScInterpreter::CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
                             SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr)
@@ -3651,15 +3691,18 @@ void ScInterpreter::ScTableOp()
     }
     pTableOp->bCollectNotifications = false;
 
-    ScBaseCell* pFCell = pDok->GetCell( pTableOp->aFormulaPos );
-    if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA )
-        ((ScFormulaCell*)pFCell)->SetDirtyVar();
-    if ( HasCellValueData( pFCell ) )
-        PushDouble( GetCellValue( pTableOp->aFormulaPos, pFCell ));
+    ScRefCellValue aCell;
+    aCell.assign(*pDok, pTableOp->aFormulaPos);
+    if (aCell.meType == CELLTYPE_FORMULA)
+        aCell.mpFormula->SetDirtyVar();
+    if (aCell.hasNumeric())
+    {
+        PushDouble(GetCellValue(pTableOp->aFormulaPos, aCell));
+    }
     else
     {
-        String aCellString;
-        GetCellString( aCellString, pFCell );
+        OUString aCellString;
+        GetCellString(aCellString, aCell);
         PushString( aCellString );
     }
 
@@ -3681,10 +3724,10 @@ void ScInterpreter::ScTableOp()
     if ( !bReuseLastParams )
         pDok->aLastTableOpParams = *pTableOp;
 
-    if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA )
+    if (aCell.meType == CELLTYPE_FORMULA)
     {
-        ((ScFormulaCell*)pFCell)->SetDirtyVar();
-        ((ScFormulaCell*)pFCell)->GetErrCode();     // recalculate original
+        aCell.mpFormula->SetDirtyVar();
+        aCell.mpFormula->GetErrCode();     // recalculate original
     }
 
     // Reset all dirty flags so next incarnation does really collect all cell
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index a9a432c..f574c4a 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -437,7 +437,8 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
             if (aCellIter.hasNumeric())
             {
                 ScAddress aAdr(nCol, nThisRow, nTab1);
-                double fVal = GetCellValue(aCellIter);
+                ScRefCellValue aCell = aCellIter.getRefCellValue();
+                double fVal = GetCellValue(aCellIter.GetPos(), aCell);
 
                 if ( nGlobalError )
                 {
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index d51e1b5..c57a951 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -1367,8 +1367,7 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
                 // cached result.  For import, we only need to set the correct
                 // matrix geometry and the value type of the top-left element.
 
-                ScFormulaCell* pFCell =
-                    static_cast<ScFormulaCell*>( rXMLImport.GetDocument()->GetCell(rCellPos) );
+                ScFormulaCell* pFCell = rXMLImport.GetDocument()->GetFormulaCell(rCellPos);
 
                 ScMatrixRef pMat(new ScMatrix(nMatrixCols, nMatrixRows));
                 if (bFormulaTextResult && maStringValue)
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index f33a94c..0bd4dab 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -477,7 +477,7 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
     else
     {
         // still need to recalc volatile formula cells.
-        aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
+        aDocument.Broadcast( ScHint(SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL) );
     }
 
     aDocument.SetXMLFromWrapper( false );
@@ -2738,7 +2738,7 @@ void ScDocShell::SetDocumentModified( sal_Bool bIsModified /* = sal_True */ )
     {
         // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results
         // of RecalcModeAlways formulas (like OFFSET) after modifying cells
-        aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
+        aDocument.Broadcast( ScHint(SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL) );
         aDocument.InvalidateTableArea();    // #i105279# needed here
         aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
 
@@ -2758,7 +2758,7 @@ void ScDocShell::SetDocumentModified( sal_Bool bIsModified /* = sal_True */ )
             aDocument.InvalidateStyleSheetUsage();
             aDocument.InvalidateTableArea();
             aDocument.InvalidateLastTableOpParams();
-            aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
+            aDocument.Broadcast( ScHint(SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL) );
             if ( aDocument.IsForcedFormulaPending() && aDocument.GetAutoCalc() )
                 aDocument.CalcFormulaTree( sal_True );
             PostDataChanged();
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index e35551a..5c525dc 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -48,6 +48,7 @@
 #include "patattr.hxx"
 #include "docpool.hxx"
 #include "stringutil.hxx"
+#include "cellvalue.hxx"
 
 #include "globstr.hrc"
 #include <vcl/svapp.hxx>
@@ -1968,9 +1969,9 @@ bool ScImportExport::Doc2Sylk( SvStream& rStrm )
             bool bForm = false;
             SCROW r = nRow - nStartRow + 1;
             SCCOL c = nCol - nStartCol + 1;
-            ScBaseCell* pCell;
-            pDoc->GetCell( nCol, nRow, aRange.aStart.Tab(), pCell );
-            CellType eType = (pCell ? pCell->GetCellType() : CELLTYPE_NONE);
+            ScRefCellValue aCell;
+            aCell.assign(*pDoc, ScAddress(nCol, nRow, aRange.aStart.Tab()));
+            CellType eType = aCell.meType;
             switch( eType )
             {
                 case CELLTYPE_FORMULA:
@@ -2014,8 +2015,7 @@ bool ScImportExport::Doc2Sylk( SvStream& rStrm )
                 checkformula:
                     if( bForm )
                     {
-                        const ScFormulaCell* pFCell =
-                            static_cast<const ScFormulaCell*>(pCell);
+                        const ScFormulaCell* pFCell = aCell.mpFormula;
                         switch ( pFCell->GetMatrixFlag() )
                         {
                             case MM_REFERENCE :
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 20bd346..502a1ea 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -6605,7 +6605,7 @@ void SAL_CALL ScCellObj::setFormulaResult( double nValue ) throw(uno::RuntimeExc
     ScDocShell* pDocSh = GetDocShell();
     if ( pDocSh && pDocSh->GetDocument()->GetCellType( aCellPos ) == CELLTYPE_FORMULA )
     {
-        ScFormulaCell* pCell = (ScFormulaCell *)pDocSh->GetDocument()->GetCell( aCellPos );
+        ScFormulaCell* pCell = pDocSh->GetDocument()->GetFormulaCell(aCellPos);
         pCell->SetHybridDouble( nValue );
         pCell->ResetDirty();
         pCell->ResetChanged();
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 60e65dc..dc02354 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -2608,7 +2608,7 @@ void ScChart2DataSequence::BuildDataCache()
                             break;
                             case CELLTYPE_FORMULA:
                             {
-                                ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(m_pDocument->GetCell(aAdr));
+                                ScFormulaCell* pFCell = m_pDocument->GetFormulaCell(aAdr);
                                 sal_uInt16 nErr = pFCell->GetErrCode();
                                 if (nErr)
                                     break;
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index afa0dab..4ecb1fc 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1080,7 +1080,11 @@ bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
     if ( pThisRowInfo && nX <= nX2 )
         bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
     else
-        bEmpty = ( mpDoc->GetCell( ScAddress( nX, nY, nTab ) ) == NULL );
+    {
+        ScRefCellValue aCell;
+        aCell.assign(*mpDoc, ScAddress(nX, nY, nTab));
+        bEmpty = aCell.isEmpty();
+    }
 
     if ( !bEmpty && ( nX < nX1 || nX > nX2 || !pThisRowInfo ) )
     {
commit 629c793388f071ff9624e78c578a76eadef2fc34
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 23:27:30 2013 -0400

    More on replacing ScBaseCell.
    
    Change-Id: I2a512d0421ddac5bf92ad128ea2dde5772f854dd

diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index de57d8f..a55d638 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -32,7 +32,6 @@ class SvxLineItem;
 class SvxShadowItem;
 class Color;
 
-class ScBaseCell;
 class ScPatternAttr;
 
 const sal_uInt8 SC_ROTDIR_NONE       = 0;
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index ec07695..6d48956 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -4397,10 +4397,11 @@ void Test::testStreamValid()
     CPPUNIT_ASSERT_MESSAGE("Cell A1 should not have moved.", test.equals(a1));
     test = m_pDoc->GetString(0, 3, 0);
     CPPUNIT_ASSERT_MESSAGE("the old cell A2 should now be at A4.", test.equals(a2));
-    const ScBaseCell* pCell = m_pDoc->GetCell(ScAddress(0, 1, 0));
-    CPPUNIT_ASSERT_MESSAGE("Cell A2 should be empty.", pCell == NULL);
-    pCell = m_pDoc->GetCell(ScAddress(0, 2, 0));
-    CPPUNIT_ASSERT_MESSAGE("Cell A3 should be empty.", pCell == NULL);
+    ScRefCellValue aCell;
+    aCell.assign(*m_pDoc, ScAddress(0,1,0));
+    CPPUNIT_ASSERT_MESSAGE("Cell A2 should be empty.", aCell.isEmpty());
+    aCell.assign(*m_pDoc, ScAddress(0,2,0));
+    CPPUNIT_ASSERT_MESSAGE("Cell A3 should be empty.", aCell.isEmpty());
 
     // After the move, Sheet1, Sheet2, and Sheet4 should have their stream
     // invalidated, whereas Sheet3's stream should still be valid.
@@ -6256,17 +6257,17 @@ void Test::testFormulaGrouping()
 
         for (unsigned j = 0; j < SAL_N_ELEMENTS( aGroupTests[0].pFormula ); j++)
         {
-            ScBaseCell *pCell = NULL;
-            m_pDoc->GetCell( 0, (SCROW)j, 0, pCell );
-            if( !pCell )
+            ScRefCellValue aCell;
+            aCell.assign(*m_pDoc, ScAddress(0, (SCROW)j, 0));
+            if (aCell.isEmpty())
             {
                 CPPUNIT_ASSERT_MESSAGE("invalid empty cell", !aGroupTests[i].bGroup[j]);
                 continue;
             }
-            CPPUNIT_ASSERT_MESSAGE("Cell expected, but not there.", pCell != NULL);
+            CPPUNIT_ASSERT_MESSAGE("Cell expected, but not there.", !aCell.isEmpty());
             CPPUNIT_ASSERT_MESSAGE("Cell wrong type.",
-                                   pCell->GetCellType() == CELLTYPE_FORMULA);
-            ScFormulaCell *pCur = static_cast< ScFormulaCell *>( pCell );
+                                   aCell.meType == CELLTYPE_FORMULA);
+            ScFormulaCell *pCur = aCell.mpFormula;
 
             if( !!pCur->GetCellGroup().get() ^ aGroupTests[i].bGroup[j] )
             {
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 289eee8..155fad9 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -131,9 +131,7 @@ void ImportExcel::Formula(
             CellType eCellType = pD->GetCellType(aScPos);
             if( eCellType == CELLTYPE_FORMULA )
             {
-                ScBaseCell* pBaseCell;
-                pD->GetCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pBaseCell );
-                pCell = ( ScFormulaCell* ) pBaseCell;
+                pCell = pD->GetFormulaCell(aScPos);
                 if( pCell )
                     pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
             }
diff --git a/sc/source/ui/collab/sendfunc.hxx b/sc/source/ui/collab/sendfunc.hxx
index 797246d..032ff01 100644
--- a/sc/source/ui/collab/sendfunc.hxx
+++ b/sc/source/ui/collab/sendfunc.hxx
@@ -14,7 +14,6 @@
 
 #include "docfunc.hxx"
 class ScCollaboration;
-class ScBaseCell;
 
 namespace {
 
diff --git a/sc/source/ui/docshell/docsh8.cxx b/sc/source/ui/docshell/docsh8.cxx
index e9d5cc8..36811e7 100644
--- a/sc/source/ui/docshell/docsh8.cxx
+++ b/sc/source/ui/docshell/docsh8.cxx
@@ -625,20 +625,19 @@ void lcl_GetColumnTypes(
 
         if ( !bTypeDefined )
         {   // Feldtyp
-            ScBaseCell* pCell;
-            pDoc->GetCell( nCol, nFirstDataRow, nTab, pCell );
-            if ( !pCell || pCell->HasStringData() )
+            ScRefCellValue aCell;
+            aCell.assign(*pDoc, ScAddress(nCol, nFirstDataRow, nTab));
+            if (aCell.isEmpty() || aCell.hasString())
                 nDbType = sdbc::DataType::VARCHAR;
             else
             {
                 sal_uInt32 nFormat;
                 pDoc->GetNumberFormat( nCol, nFirstDataRow, nTab, nFormat );
-                if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
-                  && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) )
+                if (aCell.meType == CELLTYPE_FORMULA && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0))
                 {
                     nFormat = ScGlobal::GetStandardFormat(
-                        ((ScFormulaCell*)pCell)->GetValue(), *pNumFmt, nFormat,
-                        ((ScFormulaCell*)pCell)->GetFormatType() );
+                        aCell.mpFormula->GetValue(), *pNumFmt, nFormat,
+                        aCell.mpFormula->GetFormatType());
                 }
                 switch ( pNumFmt->GetType( nFormat ) )
                 {
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 990a947b..1e715a7 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -32,7 +32,6 @@ class Font;
 class OutputDevice;
 class EditEngine;
 class ScDocument;
-class ScBaseCell;
 class ScPatternAttr;
 class SdrObject;
 struct RowInfo;
@@ -206,10 +205,10 @@ private:
 
     sal_Bool            GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY,
                                     SCCOL& rOverX, SCROW& rOverY, sal_Bool bVisRowChanged );
-    sal_Bool            IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY );
+    bool IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY );
     void GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTab, ScRefCellValue& rCell );
 
-    sal_Bool            IsAvailable( SCCOL nX, SCROW nY );
+    bool IsAvailable( SCCOL nX, SCROW nY );
 
     void            GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY,
                                    SCCOL nCellX, SCROW nCellY, long nNeeded,
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index c31a2c3..9daf859 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -353,11 +353,10 @@ static sal_Bool lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange )
                                     rRange.aEnd.Col(),rRange.aEnd.Row() ) )
         return false;
 
+    ScRefCellValue aCell;
+    aCell.assign(*pDoc, rRange.aEnd);
     ScAddress aPos;
-    const ScBaseCell* pCell = pDoc->GetCell( rRange.aEnd );
-    return ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
-            ((ScFormulaCell*)pCell)->GetMatrixOrigin(aPos) && aPos == rRange.aStart );
-
+    return (aCell.meType == CELLTYPE_FORMULA && aCell.mpFormula->GetMatrixOrigin(aPos) && aPos == rRange.aStart);
 }
 
 static void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const Point& rPos, ScViewData* pViewData )
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index a69ef99..afa0dab 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1072,11 +1072,11 @@ inline sal_Bool IsAmbiguousScript( sal_uInt8 nScript )
              nScript != SCRIPTTYPE_COMPLEX );
 }
 
-sal_Bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
+bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
 {
     // pThisRowInfo may be NULL
 
-    sal_Bool bEmpty;
+    bool bEmpty;
     if ( pThisRowInfo && nX <= nX2 )
         bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
     else
@@ -1087,23 +1087,22 @@ sal_Bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW n
         //  for the range nX1..nX2 in RowInfo, cell protection attribute is already evaluated
         //  into bEmptyCellText in ScDocument::FillInfo / lcl_HidePrint (printfun)
 
-        sal_Bool bIsPrint = ( eType == OUTTYPE_PRINTER );
+        bool bIsPrint = ( eType == OUTTYPE_PRINTER );
 
         if ( bIsPrint || bTabProtected )
         {
             const ScProtectionAttr* pAttr = (const ScProtectionAttr*)
                     mpDoc->GetEffItem( nX, nY, nTab, ATTR_PROTECTION );
             if ( bIsPrint && pAttr->GetHidePrint() )
-                bEmpty = sal_True;
+                bEmpty = true;
             else if ( bTabProtected )
             {
                 if ( pAttr->GetHideCell() )
-                    bEmpty = sal_True;
+                    bEmpty = true;
                 else if ( mbShowFormulas && pAttr->GetHideFormula() )
                 {
-                    ScBaseCell* pCell = mpDoc->GetCell( ScAddress( nX, nY, nTab ) );
-                    if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
-                        bEmpty = sal_True;
+                    if (mpDoc->GetCellType(ScAddress(nX, nY, nTab)) == CELLTYPE_FORMULA)
+                        bEmpty = true;
                 }
             }
         }
@@ -1118,17 +1117,16 @@ void ScOutputData::GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTabP, ScRefCel
         rCell.clear();
 }
 
-sal_Bool ScOutputData::IsAvailable( SCCOL nX, SCROW nY )
+bool ScOutputData::IsAvailable( SCCOL nX, SCROW nY )
 {
     //  apply the same logic here as in DrawStrings/DrawEdit:
     //  Stop at non-empty or merged or overlapped cell,
     //  where a note is empty as well as a cell that's hidden by protection settings
 
-    const ScBaseCell* pCell = mpDoc->GetCell( ScAddress( nX, nY, nTab ) );
-    if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE && !IsEmptyCellText( NULL, nX, nY ) )
-    {
+    ScRefCellValue aCell;
+    aCell.assign(*mpDoc, ScAddress(nX, nY, nTab));
+    if (!aCell.isEmpty() && !IsEmptyCellText(NULL, nX, nY))
         return false;
-    }
 
     const ScPatternAttr* pPattern = mpDoc->GetPattern( nX, nY, nTab );
     if ( ((const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE)).IsMerged() ||
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
index 071c4e4..a6e624e 100644
--- a/sc/source/ui/view/tabvwsha.cxx
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -50,7 +50,7 @@
 #include "scabstdlg.hxx"
 #include "compiler.hxx"
 #include "markdata.hxx"
-
+#include "cellvalue.hxx"
 
 sal_Bool ScTabViewShell::GetFunction( String& rFuncStr, sal_uInt16 nErrCode )
 {
@@ -111,13 +111,10 @@ sal_Bool ScTabViewShell::GetFunction( String& rFuncStr, sal_uInt16 nErrCode )
                     pDoc->GetNumberFormat( nPosX, nPosY, nTab, nNumFmt );
                     if ( (nNumFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
                     {
-                        ScBaseCell* pCell;
-                        pDoc->GetCell( nPosX, nPosY, nTab, pCell );
-                        if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
-                        {
-
-                            nNumFmt = ((ScFormulaCell*)pCell)->GetStandardFormat(*pFormatter, nNumFmt );
-                        }
+                        ScRefCellValue aCell;
+                        aCell.assign(*pDoc, aCursor);
+                        if (aCell.meType == CELLTYPE_FORMULA)
+                            nNumFmt = aCell.mpFormula->GetStandardFormat(*pFormatter, nNumFmt);
                     }
                 }
 
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index 6494cd2..72407dc 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -213,13 +213,13 @@ enum ScAutoSum
 static ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
         SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
 {
-    ScBaseCell* pCell;
-    pDoc->GetCell( nCol, nRow, nTab, pCell );
-    if ( pCell && pCell->HasValueData() )
+    ScRefCellValue aCell;
+    aCell.assign(*pDoc, ScAddress(nCol, nRow, nTab));
+    if (aCell.hasNumeric())
     {
-        if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+        if (aCell.meType == CELLTYPE_FORMULA)
         {
-            ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode();
+            ScTokenArray* pCode = aCell.mpFormula->GetCode();
             if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
             {
                 if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
diff --git a/sc/source/ui/view/viewfun4.cxx b/sc/source/ui/view/viewfun4.cxx
index 7e7e3df..84a4202 100644
--- a/sc/source/ui/view/viewfun4.cxx
+++ b/sc/source/ui/view/viewfun4.cxx
@@ -311,7 +311,6 @@ void ScViewFunc::DoThesaurus( sal_Bool bRecord )
     String sOldText, sNewString;
     EditTextObject* pOldTObj = NULL;
     const EditTextObject* pTObject = NULL;
-    ScBaseCell* pCell = NULL;
     EditView* pEditView = NULL;
     boost::scoped_ptr<ESelection> pEditSel;
     ScEditEngineDefaulter* pThesaurusEngine;
@@ -406,7 +405,7 @@ void ScViewFunc::DoThesaurus( sal_Bool bRecord )
     if (pThesaurusEngine->IsModified())
     {
         EditTextObject* pNewTObj = NULL;
-        if (pCell && pTObject)
+        if (pTObject)
         {
             // The cell will own the text object instance.
             pDoc->SetEditText(
commit e610388522c31455bb989c957e9480fa7fbcdf6c
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 22:52:31 2013 -0400

    We only need to send the broadcaster instance with ScHint.
    
    Another ScBaseCell eliminated.
    
    Change-Id: I32a07024dd1d8ab536038942aa7209a7829d193c

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 2ee7004..46ab330 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -180,6 +180,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
 	sc/source/core/tool/adiasync \
 	sc/source/core/tool/appoptio \
 	sc/source/core/tool/autoform \
+	sc/source/core/tool/brdcst \
 	sc/source/core/tool/calcconfig \
 	sc/source/core/tool/callform \
 	sc/source/core/tool/cellform \
diff --git a/sc/inc/brdcst.hxx b/sc/inc/brdcst.hxx
index ee18de4..737e7e8 100644
--- a/sc/inc/brdcst.hxx
+++ b/sc/inc/brdcst.hxx
@@ -24,7 +24,8 @@
 #include <tools/rtti.hxx>
 #include <svl/hint.hxx>
 #include <svl/smplhint.hxx>
-class ScBaseCell;
+
+class SvtBroadcaster;
 
 #define SC_HINT_DYING       SFX_HINT_DYING
 #define SC_HINT_DATACHANGED SFX_HINT_DATACHANGED
@@ -35,14 +36,13 @@ class ScHint : public SfxSimpleHint
 {
 private:
     ScAddress   aAddress;
-    ScBaseCell* pCell;
+    SvtBroadcaster* mpBroadcaster;
 
 public:
     TYPEINFO();
-                        ScHint( sal_uLong n, const ScAddress& a, ScBaseCell* p )
-                            : SfxSimpleHint( n ), aAddress( a ), pCell( p ) {}
-    ScBaseCell*         GetCell() const { return pCell; }
-    void                SetCell( ScBaseCell* p )    { pCell = p; }
+    ScHint( sal_uLong n, const ScAddress& a, SvtBroadcaster* p );
+    SvtBroadcaster* GetBroadcaster() const;
+    void SetBroadcaster( SvtBroadcaster* p );
     const ScAddress&    GetAddress() const { return aAddress; }
           ScAddress&    GetAddress()       { return aAddress; }
     void                SetAddress( const ScAddress& rAdr ) { aAddress = rAdr; }
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index cf09270..150b5ad 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2155,7 +2155,7 @@ void ScColumn::SetDirty( const ScRange& rRange )
         else
         {
             aHint.GetAddress().SetRow( nRow );
-            aHint.SetCell( pCell );
+            aHint.SetBroadcaster(pCell->GetBroadcaster());
             pDocument->Broadcast( aHint );
         }
         nIndex++;
@@ -2184,7 +2184,7 @@ void ScColumn::SetTableOpDirty( const ScRange& rRange )
         else
         {
             aHint.GetAddress().SetRow( nRow );
-            aHint.SetCell( pCell );
+            aHint.SetBroadcaster(pCell->GetBroadcaster());
             pDocument->Broadcast( aHint );
         }
         nIndex++;
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 8e6fb19..5316ee0 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -122,7 +122,7 @@ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
                 ((ScFormulaCell*)pNewCell)->SetDirty();
             else
                 pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
-                    ScAddress( nCol, nRow, nTab ), pNewCell ) );
+                    ScAddress( nCol, nRow, nTab ), pNewCell->GetBroadcaster()) );
         }
     }
     bDirtyGroups = true;
@@ -160,7 +160,7 @@ void ScColumn::Delete( SCROW nRow )
         ScNoteCell* pNoteCell = new ScNoteCell;
         maItems[nIndex].pCell = pNoteCell; // Dummy for Interpret
         pDocument->Broadcast( ScHint( SC_HINT_DYING,
-            ScAddress( nCol, nRow, nTab ), pCell ) );
+            ScAddress( nCol, nRow, nTab ), pCell->GetBroadcaster()));
         if ( SvtBroadcaster* pBC = pCell->ReleaseBroadcaster() )
         {
             pNoteCell->TakeBroadcaster( pBC );
@@ -190,7 +190,7 @@ void ScColumn::DeleteAtIndex( SCSIZE nIndex )
     ScNoteCell* pNoteCell = new ScNoteCell;
     maItems[nIndex].pCell = pNoteCell; // Dummy for Interpret
     pDocument->Broadcast(
-        ScHint(SC_HINT_DYING, ScAddress(nCol, nRow, nTab), pCell));
+        ScHint(SC_HINT_DYING, ScAddress(nCol, nRow, nTab), pCell->GetBroadcaster()));
     pNoteCell->Delete();
     maItems.erase(maItems.begin() + nIndex);
     if (pCell->GetCellType() == CELLTYPE_FORMULA)
@@ -414,7 +414,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
                 // interpret in broadcast must not use the old cell
                 maItems[ nIdx ].pCell = pDummyCell.get();
                 aHint.GetAddress().SetRow( maItems[ nIdx ].nRow );
-                aHint.SetCell( pOldCell );
+                aHint.SetBroadcaster(pOldCell->GetBroadcaster());
                 pDocument->Broadcast( aHint );
                 pOldCell->Delete();
             }
@@ -470,7 +470,12 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
             else
             {
                 aHint.GetAddress().SetRow(nOldRow);
-                aHint.SetCell(pNoteCell ? pNoteCell : pOldCell);
+                SvtBroadcaster* pHintBC = NULL;
+                if (pNoteCell)
+                    pHintBC = pNoteCell->GetBroadcaster();
+                else if (pOldCell)
+                    pHintBC = pOldCell->GetBroadcaster();
+                aHint.SetBroadcaster(pHintBC);
                 pDocument->Broadcast(aHint);
                 if (pNoteCell != pOldCell)
                 {
@@ -553,7 +558,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
             // from maItems.
             SCSIZE nIndex;
             ScBaseCell* pCell = (Search( (*aIt)->aPos.Row(), nIndex) ? maItems[nIndex].pCell : NULL);
-            aHint.SetCell( pCell );
+            aHint.SetBroadcaster(pCell ? pCell->GetBroadcaster() : NULL);
             aHint.SetAddress( (*aIt)->aPos );
             pDocument->Broadcast( aHint );
             (*aIt)->Delete();
@@ -1195,7 +1200,7 @@ void ScColumn::BroadcastInArea( SCROW nRow1, SCROW nRow2 )
                 ((ScFormulaCell*)pCell)->SetDirty();
             else
                 pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
-                    ScAddress( nCol, nRow, nTab ), pCell ) );
+                    ScAddress(nCol, nRow, nTab), pCell->GetBroadcaster()));
             nIndex++;
         }
     }
@@ -1469,7 +1474,7 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                 }
                 else
                     pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED,
-                        ScAddress( nCol, nRow, nTabP ), pNewCell ) );
+                        ScAddress(nCol, nRow, nTabP), pNewCell->GetBroadcaster()));
             }
             else
             {
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 56eb5651..f813464 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -69,7 +69,7 @@ void ScDocument::Broadcast( sal_uLong nHint, const ScAddress& rAddr,
 {
     if ( !pBASM )
         return ;    // Clipboard or Undo
-    ScHint aHint( nHint, rAddr, pCell );
+    ScHint aHint(nHint, rAddr, pCell ? pCell->GetBroadcaster() : NULL);
     Broadcast( aHint );
 }
 
@@ -82,15 +82,11 @@ void ScDocument::Broadcast( const ScHint& rHint )
     {
         ScBulkBroadcast aBulkBroadcast( pBASM);     // scoped bulk broadcast
         bool bIsBroadcasted = false;
-        ScBaseCell* pCell = rHint.GetCell();
-        if ( pCell )
+        SvtBroadcaster* pBC = rHint.GetBroadcaster();
+        if ( pBC )
         {
-            SvtBroadcaster* pBC = pCell->GetBroadcaster();
-            if ( pBC )
-            {
-                pBC->Broadcast( rHint );
-                bIsBroadcasted = true;
-            }
+            pBC->Broadcast( rHint );
+            bIsBroadcasted = true;
         }
         if ( pBASM->AreaBroadcast( rHint ) || bIsBroadcasted )
             TrackFormulas( rHint.GetId() );
@@ -457,7 +453,7 @@ void ScDocument::TrackFormulas( sal_uLong nHintId )
         pTrack = pFormulaTrack;
         do
         {
-            ScHint aHint( nHintId, pTrack->aPos, pTrack );
+            ScHint aHint( nHintId, pTrack->aPos, pTrack->GetBroadcaster() );
             if ( ( pBC = pTrack->GetBroadcaster() ) != NULL )
                 pBC->Broadcast( aHint );
             pBASM->AreaBroadcast( aHint );
diff --git a/sc/source/core/tool/brdcst.cxx b/sc/source/core/tool/brdcst.cxx
new file mode 100644
index 0000000..e860026
--- /dev/null
+++ b/sc/source/core/tool/brdcst.cxx
@@ -0,0 +1,35 @@
+/* -*- 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 .
+ */
+
+#include "brdcst.hxx"
+
+ScHint::ScHint( sal_uLong n, const ScAddress& a, SvtBroadcaster* p ) :
+    SfxSimpleHint(n), aAddress(a), mpBroadcaster(p) {}
+
+SvtBroadcaster* ScHint::GetBroadcaster() const
+{
+    return mpBroadcaster;
+}
+
+void ScHint::SetBroadcaster( SvtBroadcaster* p )
+{
+    mpBroadcaster = p;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit f847a0e29bb2bf1f2992c1e67cf2aa281bcfe355
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 21:25:14 2013 -0400

    Some header cleansup. Some headers are no longer needed.
    
    Change-Id: I56fb26da04b03d0692837d4a05aacd2a793ee2ae

diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index f732019..0dff21a 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -17,16 +17,13 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <svl/zforlist.hxx>
+#include "cell.hxx"
 
 #include "scitems.hxx"
 #include "attrib.hxx"
-#include "cell.hxx"
 #include "compiler.hxx"
 #include "interpre.hxx"
 #include "document.hxx"
-#include "scmatrix.hxx"
-#include "dociter.hxx"
 #include "docoptio.hxx"
 #include "rechead.hxx"
 #include "rangenam.hxx"
@@ -36,16 +33,15 @@
 #include "progress.hxx"
 #include "editutil.hxx"
 #include "recursionhelper.hxx"
-#include "postit.hxx"
 #include "externalrefmgr.hxx"
 #include "macromgr.hxx"
 #include "dbdata.hxx"
 #include "globalnames.hxx"
+#include "cellvalue.hxx"
 
-#include <editeng/editobj.hxx>
 #include <svl/intitem.hxx>
-#include <editeng/flditem.hxx>
 #include <svl/broadcast.hxx>
+#include <svl/zforlist.hxx>
 
 using namespace formula;
 // More or less arbitrary, of course all recursions must fit into available
commit 0c0191cfb7ffaa3631fc9556bfda7fdecf5b00e7
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 21:18:29 2013 -0400

    Some followup cleanup now that these methods are in the formula cell only.
    
    Change-Id: I796bf379f004a1371c86362e57eaac4a511f34cd

diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 6369e18d..7603b05 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1820,82 +1820,83 @@ bool ScFormulaCell::InterpretFormulaGroup()
 
 void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
 {
-    if (!pDoc->IsClipOrUndo() && !pDoc->GetNoListening() && !IsInChangeTrack())
+    if (pDoc->IsClipOrUndo() || pDoc->GetNoListening() || IsInChangeTrack())
+        return;
+
+    pDoc->SetDetectiveDirty(true);  // It has changed something
+
+    ScTokenArray* pArr = GetCode();
+    if( pArr->IsRecalcModeAlways() )
     {
-        pDoc->SetDetectiveDirty(true);  // It has changed something
+        pDoc->StartListeningArea(BCA_LISTEN_ALWAYS, this);
+        SetNeedsListening( false);
+        return;
+    }
 
-        ScFormulaCell* pFormCell = (ScFormulaCell*)this;
-        ScTokenArray* pArr = pFormCell->GetCode();
-        if( pArr->IsRecalcModeAlways() )
-            pDoc->StartListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
-        else
+    pArr->Reset();
+    ScToken* t;
+    while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+    {
+        StackVar eType = t->GetType();
+        ScSingleRefData& rRef1 = t->GetSingleRef();
+        ScSingleRefData& rRef2 = (eType == svDoubleRef ?
+            t->GetDoubleRef().Ref2 : rRef1);
+        switch( eType )
         {
-            pArr->Reset();
-            ScToken* t;
-            while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
-            {
-                StackVar eType = t->GetType();
-                ScSingleRefData& rRef1 = t->GetSingleRef();
-                ScSingleRefData& rRef2 = (eType == svDoubleRef ?
-                    t->GetDoubleRef().Ref2 : rRef1);
-                switch( eType )
+            case svSingleRef:
+                rRef1.CalcAbsIfRel(aPos);
+                if ( rRef1.Valid() )
                 {
-                    case svSingleRef:
-                        rRef1.CalcAbsIfRel( pFormCell->aPos );
-                        if ( rRef1.Valid() )
-                        {
-                            pDoc->StartListeningCell(
-                                ScAddress( rRef1.nCol,
-                                           rRef1.nRow,
-                                           rRef1.nTab ), pFormCell );
+                    pDoc->StartListeningCell(
+                        ScAddress( rRef1.nCol,
+                                   rRef1.nRow,
+                                   rRef1.nTab ), this );
+                }
+            break;
+            case svDoubleRef:
+                t->CalcAbsIfRel(aPos);
+                if ( rRef1.Valid() && rRef2.Valid() )
+                {
+                    if ( t->GetOpCode() == ocColRowNameAuto )
+                    {   // automagically
+                        if ( rRef1.IsColRel() )
+                        {   // ColName
+                            pDoc->StartListeningArea( ScRange (
+                                rRef1.nCol,
+                                rRef1.nRow,
+                                rRef1.nTab,
+                                rRef2.nCol,
+                                MAXROW,
+                                rRef2.nTab ), this );
                         }
-                    break;
-                    case svDoubleRef:
-                        t->CalcAbsIfRel( pFormCell->aPos );
-                        if ( rRef1.Valid() && rRef2.Valid() )
-                        {
-                            if ( t->GetOpCode() == ocColRowNameAuto )
-                            {   // automagically
-                                if ( rRef1.IsColRel() )
-                                {   // ColName
-                                    pDoc->StartListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        rRef2.nCol,
-                                        MAXROW,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                                else
-                                {   // RowName
-                                    pDoc->StartListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        MAXCOL,
-                                        rRef2.nRow,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                            }
-                            else
-                            {
-                                pDoc->StartListeningArea( ScRange (
-                                    rRef1.nCol,
-                                    rRef1.nRow,
-                                    rRef1.nTab,
-                                    rRef2.nCol,
-                                    rRef2.nRow,
-                                    rRef2.nTab ), pFormCell );
-                            }
+                        else
+                        {   // RowName
+                            pDoc->StartListeningArea( ScRange (
+                                rRef1.nCol,
+                                rRef1.nRow,
+                                rRef1.nTab,
+                                MAXCOL,
+                                rRef2.nRow,
+                                rRef2.nTab ), this );
                         }
-                    break;
-                    default:
-                        ;   // nothing
+                    }
+                    else
+                    {
+                        pDoc->StartListeningArea( ScRange (
+                            rRef1.nCol,
+                            rRef1.nRow,
+                            rRef1.nTab,
+                            rRef2.nCol,
+                            rRef2.nRow,
+                            rRef2.nTab ), this );
+                    }
                 }
-            }
+            break;
+            default:
+                ;   // nothing
         }
-        pFormCell->SetNeedsListening( false);
     }
+    SetNeedsListening( false);
 }
 
 //  pArr gesetzt -> Referenzen von anderer Zelle nehmen
@@ -1904,83 +1905,83 @@ void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
 void ScFormulaCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr,
         ScAddress aCellPos )
 {
-    if (!pDoc->IsClipOrUndo() && !IsInChangeTrack())
+    if (pDoc->IsClipOrUndo() || IsInChangeTrack())
+        return;
+
+    pDoc->SetDetectiveDirty(true);  // It has changed something
+
+    if ( GetCode()->IsRecalcModeAlways() )
     {
-        pDoc->SetDetectiveDirty(true);  // It has changed something
+        pDoc->EndListeningArea( BCA_LISTEN_ALWAYS, this );
+        return;
+    }
 
-        ScFormulaCell* pFormCell = (ScFormulaCell*)this;
-        if( pFormCell->GetCode()->IsRecalcModeAlways() )
-            pDoc->EndListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
-        else
+    if (!pArr)
+    {
+        pArr = GetCode();
+        aCellPos = aPos;
+    }
+    pArr->Reset();
+    ScToken* t;
+    while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+    {
+        StackVar eType = t->GetType();
+        ScSingleRefData& rRef1 = t->GetSingleRef();
+        ScSingleRefData& rRef2 = (eType == svDoubleRef ?
+            t->GetDoubleRef().Ref2 : rRef1);
+        switch( eType )
         {
-            if (!pArr)
-            {
-                pArr = pFormCell->GetCode();
-                aCellPos = pFormCell->aPos;
-            }
-            pArr->Reset();
-            ScToken* t;
-            while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
-            {
-                StackVar eType = t->GetType();
-                ScSingleRefData& rRef1 = t->GetSingleRef();
-                ScSingleRefData& rRef2 = (eType == svDoubleRef ?
-                    t->GetDoubleRef().Ref2 : rRef1);
-                switch( eType )
+            case svSingleRef:
+                rRef1.CalcAbsIfRel( aCellPos );
+                if ( rRef1.Valid() )
                 {
-                    case svSingleRef:
-                        rRef1.CalcAbsIfRel( aCellPos );
-                        if ( rRef1.Valid() )
-                        {
-                            pDoc->EndListeningCell(
-                                ScAddress( rRef1.nCol,
-                                           rRef1.nRow,
-                                           rRef1.nTab ), pFormCell );
+                    pDoc->EndListeningCell(
+                        ScAddress( rRef1.nCol,
+                                   rRef1.nRow,
+                                   rRef1.nTab ), this );
+                }
+            break;
+            case svDoubleRef:
+                t->CalcAbsIfRel( aCellPos );
+                if ( rRef1.Valid() && rRef2.Valid() )
+                {
+                    if ( t->GetOpCode() == ocColRowNameAuto )
+                    {   // automagically
+                        if ( rRef1.IsColRel() )
+                        {   // ColName
+                            pDoc->EndListeningArea( ScRange (
+                                rRef1.nCol,
+                                rRef1.nRow,
+                                rRef1.nTab,
+                                rRef2.nCol,
+                                MAXROW,
+                                rRef2.nTab ), this );
                         }
-                    break;
-                    case svDoubleRef:
-                        t->CalcAbsIfRel( aCellPos );
-                        if ( rRef1.Valid() && rRef2.Valid() )
-                        {
-                            if ( t->GetOpCode() == ocColRowNameAuto )
-                            {   // automagically
-                                if ( rRef1.IsColRel() )
-                                {   // ColName
-                                    pDoc->EndListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        rRef2.nCol,
-                                        MAXROW,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                                else
-                                {   // RowName
-                                    pDoc->EndListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        MAXCOL,
-                                        rRef2.nRow,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                            }
-                            else
-                            {
-                                pDoc->EndListeningArea( ScRange (
-                                    rRef1.nCol,
-                                    rRef1.nRow,
-                                    rRef1.nTab,
-                                    rRef2.nCol,
-                                    rRef2.nRow,
-                                    rRef2.nTab ), pFormCell );
-                            }
+                        else
+                        {   // RowName
+                            pDoc->EndListeningArea( ScRange (
+                                rRef1.nCol,
+                                rRef1.nRow,
+                                rRef1.nTab,
+                                MAXCOL,
+                                rRef2.nRow,
+                                rRef2.nTab ), this );
                         }
-                    break;
-                    default:
-                        ;   // nothing
+                    }
+                    else
+                    {
+                        pDoc->EndListeningArea( ScRange (
+                            rRef1.nCol,
+                            rRef1.nRow,
+                            rRef1.nTab,
+                            rRef2.nCol,
+                            rRef2.nRow,
+                            rRef2.nTab ), this );
+                    }
                 }
-            }
+            break;
+            default:
+                ;   // nothing
         }
     }
 }
commit d832acf33debc09d8d869d8db354049b69af2a6c
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 21:09:37 2013 -0400

    Now we don't need to check for the cell type; it's always of formula type.
    
    Change-Id: I4066975340f7e8a89e9e4d07cc7bed3851da52b6

diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index a68203f..6369e18d 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1820,10 +1820,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
 
 void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
 {
-    if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
-            && !pDoc->GetNoListening()
-            && !((ScFormulaCell*)this)->IsInChangeTrack()
-        )
+    if (!pDoc->IsClipOrUndo() && !pDoc->GetNoListening() && !IsInChangeTrack())
     {
         pDoc->SetDetectiveDirty(true);  // It has changed something
 
@@ -1907,9 +1904,7 @@ void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
 void ScFormulaCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr,
         ScAddress aCellPos )
 {
-    if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
-            && !((ScFormulaCell*)this)->IsInChangeTrack()
-        )
+    if (!pDoc->IsClipOrUndo() && !IsInChangeTrack())
     {
         pDoc->SetDetectiveDirty(true);  // It has changed something
 
commit 96228fa3ec1ac4aaf648f791d9249418b1213f1a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 21:07:40 2013 -0400

    Stop exporting symbols of these cell classes except for ScFormulaCell.
    
    And move StartListeningTo() and EndListeningTo() methods from ScBaseCell
    to ScFormulaCell.  They really do belong only to the formula cells.
    
    Change-Id: I468cd899beec0d8281ebb0d57fe6205a0fc4f534

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index c3443d2..b0919a6 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -51,7 +51,7 @@ class SvtBroadcaster;
 class ScProgress;
 class ScPatternAttr;
 
-class SC_DLLPUBLIC ScBaseCell
+class ScBaseCell
 {
 protected:
                     ~ScBaseCell();  // not virtual - not to be called directly.
@@ -91,12 +91,6 @@ public:
     /** Deletes the own cell broadcaster. */
     void            DeleteBroadcaster();
 
-    // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
-    void            StartListeningTo( ScDocument* pDoc );
-    void            EndListeningTo( ScDocument* pDoc,
-                                    ScTokenArray* pArr = NULL,
-                                    ScAddress aPos = ScAddress() );
-
     /** Error code if ScFormulaCell, else 0. */
     sal_uInt16          GetErrorCode() const;
     /** ScFormulaCell with formula::svEmptyCell result, or ScNoteCell (may have been
@@ -120,7 +114,7 @@ protected:
 
 // ============================================================================
 
-class SC_DLLPUBLIC ScNoteCell : public ScBaseCell
+class ScNoteCell : public ScBaseCell
 {
 public:
 #ifdef USE_MEMPOOL
@@ -158,7 +152,7 @@ private:
     double          mfValue;
 };
 
-class SC_DLLPUBLIC ScStringCell : public ScBaseCell
+class ScStringCell : public ScBaseCell
 {
 public:
 #ifdef USE_MEMPOOL
@@ -179,7 +173,7 @@ private:
     rtl::OUString   maString;
 };
 
-class SC_DLLPUBLIC ScEditCell : public ScBaseCell
+class ScEditCell : public ScBaseCell
 {
     EditTextObject* mpData;
     mutable OUString* mpString;        // for faster access to formulas
@@ -578,6 +572,11 @@ public:
     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
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 03fbe68..f732019 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -277,179 +277,6 @@ void ScBaseCell::DeleteBroadcaster()
     DELETEZ( mpBroadcaster );
 }
 
-void ScBaseCell::StartListeningTo( ScDocument* pDoc )
-{
-    if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
-            && !pDoc->GetNoListening()
-            && !((ScFormulaCell*)this)->IsInChangeTrack()
-        )
-    {
-        pDoc->SetDetectiveDirty(true);  // It has changed something
-
-        ScFormulaCell* pFormCell = (ScFormulaCell*)this;
-        ScTokenArray* pArr = pFormCell->GetCode();
-        if( pArr->IsRecalcModeAlways() )
-            pDoc->StartListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
-        else
-        {
-            pArr->Reset();
-            ScToken* t;
-            while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
-            {
-                StackVar eType = t->GetType();
-                ScSingleRefData& rRef1 = t->GetSingleRef();
-                ScSingleRefData& rRef2 = (eType == svDoubleRef ?
-                    t->GetDoubleRef().Ref2 : rRef1);
-                switch( eType )
-                {
-                    case svSingleRef:
-                        rRef1.CalcAbsIfRel( pFormCell->aPos );
-                        if ( rRef1.Valid() )
-                        {
-                            pDoc->StartListeningCell(
-                                ScAddress( rRef1.nCol,
-                                           rRef1.nRow,
-                                           rRef1.nTab ), pFormCell );
-                        }
-                    break;
-                    case svDoubleRef:
-                        t->CalcAbsIfRel( pFormCell->aPos );
-                        if ( rRef1.Valid() && rRef2.Valid() )
-                        {
-                            if ( t->GetOpCode() == ocColRowNameAuto )
-                            {   // automagically
-                                if ( rRef1.IsColRel() )
-                                {   // ColName
-                                    pDoc->StartListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        rRef2.nCol,
-                                        MAXROW,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                                else
-                                {   // RowName
-                                    pDoc->StartListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        MAXCOL,
-                                        rRef2.nRow,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                            }
-                            else
-                            {
-                                pDoc->StartListeningArea( ScRange (
-                                    rRef1.nCol,
-                                    rRef1.nRow,
-                                    rRef1.nTab,
-                                    rRef2.nCol,
-                                    rRef2.nRow,
-                                    rRef2.nTab ), pFormCell );
-                            }
-                        }
-                    break;
-                    default:
-                        ;   // nothing
-                }
-            }
-        }
-        pFormCell->SetNeedsListening( false);
-    }
-}
-
-//  pArr gesetzt -> Referenzen von anderer Zelle nehmen
-// Then aPos must also be commited
-
-void ScBaseCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr,
-        ScAddress aPos )
-{
-    if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
-            && !((ScFormulaCell*)this)->IsInChangeTrack()
-        )
-    {
-        pDoc->SetDetectiveDirty(true);  // It has changed something
-
-        ScFormulaCell* pFormCell = (ScFormulaCell*)this;
-        if( pFormCell->GetCode()->IsRecalcModeAlways() )
-            pDoc->EndListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
-        else
-        {
-            if (!pArr)
-            {
-                pArr = pFormCell->GetCode();
-                aPos = pFormCell->aPos;
-            }
-            pArr->Reset();
-            ScToken* t;
-            while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
-            {
-                StackVar eType = t->GetType();
-                ScSingleRefData& rRef1 = t->GetSingleRef();
-                ScSingleRefData& rRef2 = (eType == svDoubleRef ?
-                    t->GetDoubleRef().Ref2 : rRef1);
-                switch( eType )
-                {
-                    case svSingleRef:
-                        rRef1.CalcAbsIfRel( aPos );
-                        if ( rRef1.Valid() )
-                        {
-                            pDoc->EndListeningCell(
-                                ScAddress( rRef1.nCol,
-                                           rRef1.nRow,
-                                           rRef1.nTab ), pFormCell );
-                        }
-                    break;
-                    case svDoubleRef:
-                        t->CalcAbsIfRel( aPos );
-                        if ( rRef1.Valid() && rRef2.Valid() )
-                        {
-                            if ( t->GetOpCode() == ocColRowNameAuto )
-                            {   // automagically
-                                if ( rRef1.IsColRel() )
-                                {   // ColName
-                                    pDoc->EndListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        rRef2.nCol,
-                                        MAXROW,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                                else
-                                {   // RowName
-                                    pDoc->EndListeningArea( ScRange (
-                                        rRef1.nCol,
-                                        rRef1.nRow,
-                                        rRef1.nTab,
-                                        MAXCOL,
-                                        rRef2.nRow,
-                                        rRef2.nTab ), pFormCell );
-                                }
-                            }
-                            else
-                            {
-                                pDoc->EndListeningArea( ScRange (
-                                    rRef1.nCol,
-                                    rRef1.nRow,
-                                    rRef1.nTab,
-                                    rRef2.nCol,
-                                    rRef2.nRow,
-                                    rRef2.nTab ), pFormCell );
-                            }
-                        }
-                    break;
-                    default:
-                        ;   // nothing
-                }
-            }
-        }
-    }
-}
-
-
 sal_uInt16 ScBaseCell::GetErrorCode() const
 {
     switch ( eCellType )
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 297f8d0..a68203f 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1818,6 +1818,178 @@ bool ScFormulaCell::InterpretFormulaGroup()
     }
 }
 
+void ScFormulaCell::StartListeningTo( ScDocument* pDoc )
+{
+    if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
+            && !pDoc->GetNoListening()
+            && !((ScFormulaCell*)this)->IsInChangeTrack()
+        )
+    {
+        pDoc->SetDetectiveDirty(true);  // It has changed something
+
+        ScFormulaCell* pFormCell = (ScFormulaCell*)this;
+        ScTokenArray* pArr = pFormCell->GetCode();
+        if( pArr->IsRecalcModeAlways() )
+            pDoc->StartListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
+        else
+        {
+            pArr->Reset();
+            ScToken* t;
+            while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+            {
+                StackVar eType = t->GetType();
+                ScSingleRefData& rRef1 = t->GetSingleRef();
+                ScSingleRefData& rRef2 = (eType == svDoubleRef ?
+                    t->GetDoubleRef().Ref2 : rRef1);
+                switch( eType )
+                {
+                    case svSingleRef:
+                        rRef1.CalcAbsIfRel( pFormCell->aPos );
+                        if ( rRef1.Valid() )
+                        {
+                            pDoc->StartListeningCell(
+                                ScAddress( rRef1.nCol,
+                                           rRef1.nRow,
+                                           rRef1.nTab ), pFormCell );
+                        }
+                    break;
+                    case svDoubleRef:
+                        t->CalcAbsIfRel( pFormCell->aPos );
+                        if ( rRef1.Valid() && rRef2.Valid() )
+                        {
+                            if ( t->GetOpCode() == ocColRowNameAuto )
+                            {   // automagically
+                                if ( rRef1.IsColRel() )
+                                {   // ColName
+                                    pDoc->StartListeningArea( ScRange (
+                                        rRef1.nCol,
+                                        rRef1.nRow,
+                                        rRef1.nTab,
+                                        rRef2.nCol,
+                                        MAXROW,
+                                        rRef2.nTab ), pFormCell );
+                                }
+                                else
+                                {   // RowName
+                                    pDoc->StartListeningArea( ScRange (
+                                        rRef1.nCol,
+                                        rRef1.nRow,
+                                        rRef1.nTab,
+                                        MAXCOL,
+                                        rRef2.nRow,
+                                        rRef2.nTab ), pFormCell );
+                                }
+                            }
+                            else
+                            {
+                                pDoc->StartListeningArea( ScRange (
+                                    rRef1.nCol,
+                                    rRef1.nRow,
+                                    rRef1.nTab,
+                                    rRef2.nCol,
+                                    rRef2.nRow,
+                                    rRef2.nTab ), pFormCell );
+                            }
+                        }
+                    break;
+                    default:
+                        ;   // nothing
+                }
+            }
+        }
+        pFormCell->SetNeedsListening( false);
+    }
+}
+
+//  pArr gesetzt -> Referenzen von anderer Zelle nehmen
+// Then aPos must also be commited
+
+void ScFormulaCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr,
+        ScAddress aCellPos )
+{
+    if ( eCellType == CELLTYPE_FORMULA && !pDoc->IsClipOrUndo()
+            && !((ScFormulaCell*)this)->IsInChangeTrack()
+        )
+    {
+        pDoc->SetDetectiveDirty(true);  // It has changed something
+
+        ScFormulaCell* pFormCell = (ScFormulaCell*)this;
+        if( pFormCell->GetCode()->IsRecalcModeAlways() )
+            pDoc->EndListeningArea( BCA_LISTEN_ALWAYS, pFormCell );
+        else
+        {
+            if (!pArr)
+            {
+                pArr = pFormCell->GetCode();
+                aCellPos = pFormCell->aPos;
+            }
+            pArr->Reset();
+            ScToken* t;
+            while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
+            {
+                StackVar eType = t->GetType();
+                ScSingleRefData& rRef1 = t->GetSingleRef();
+                ScSingleRefData& rRef2 = (eType == svDoubleRef ?
+                    t->GetDoubleRef().Ref2 : rRef1);
+                switch( eType )
+                {
+                    case svSingleRef:
+                        rRef1.CalcAbsIfRel( aCellPos );
+                        if ( rRef1.Valid() )
+                        {
+                            pDoc->EndListeningCell(
+                                ScAddress( rRef1.nCol,
+                                           rRef1.nRow,
+                                           rRef1.nTab ), pFormCell );
+                        }
+                    break;
+                    case svDoubleRef:
+                        t->CalcAbsIfRel( aCellPos );
+                        if ( rRef1.Valid() && rRef2.Valid() )
+                        {
+                            if ( t->GetOpCode() == ocColRowNameAuto )
+                            {   // automagically
+                                if ( rRef1.IsColRel() )
+                                {   // ColName
+                                    pDoc->EndListeningArea( ScRange (
+                                        rRef1.nCol,
+                                        rRef1.nRow,
+                                        rRef1.nTab,
+                                        rRef2.nCol,
+                                        MAXROW,
+                                        rRef2.nTab ), pFormCell );
+                                }
+                                else
+                                {   // RowName
+                                    pDoc->EndListeningArea( ScRange (
+                                        rRef1.nCol,
+                                        rRef1.nRow,
+                                        rRef1.nTab,
+                                        MAXCOL,
+                                        rRef2.nRow,
+                                        rRef2.nTab ), pFormCell );
+                                }
+                            }
+                            else
+                            {
+                                pDoc->EndListeningArea( ScRange (
+                                    rRef1.nCol,
+                                    rRef1.nRow,
+                                    rRef1.nTab,
+                                    rRef2.nCol,
+                                    rRef2.nRow,
+                                    rRef2.nTab ), pFormCell );
+                            }
+                        }
+                    break;
+                    default:
+                        ;   // nothing
+                }
+            }
+        }
+    }
+}
+
 // ============================================================================
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index fb5e261..8e6fb19 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -84,7 +84,7 @@ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
 
             if ( pOldCell->GetCellType() == CELLTYPE_FORMULA && !pDocument->IsClipOrUndo() )
             {
-                pOldCell->EndListeningTo( pDocument );
+                static_cast<ScFormulaCell*>(pOldCell)->EndListeningTo( pDocument );
                 // If in EndListening NoteCell is destroyed in same Col
                 if ( nIndex >= maItems.size() || maItems[nIndex].nRow != nRow )
                     Search(nRow, nIndex);
@@ -110,8 +110,10 @@ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
     // After Import we call CalcAfterLoad and in there Listening.
     if ( !(pDocument->IsClipOrUndo() || pDocument->IsInsertingFromOtherDoc()) )
     {
-        pNewCell->StartListeningTo( pDocument );
         CellType eCellType = pNewCell->GetCellType();
+        if (eCellType == CELLTYPE_FORMULA)
+            static_cast<ScFormulaCell*>(pNewCell)->StartListeningTo(pDocument);
+
         // A note cell is only created by StartListeningCell when loading,
         // triggering Formula cells must be dirty anyway.
         if ( !(pDocument->IsCalcingAfterLoad() && eCellType == CELLTYPE_NOTE) )
@@ -171,7 +173,8 @@ void ScColumn::Delete( SCROW nRow )
             maScriptTypes.set_empty(nRow, nRow);
             // Should we free memory here (delta)? It'll be slower!
         }
-        pCell->EndListeningTo( pDocument );
+        if (pCell->GetCellType() == CELLTYPE_FORMULA)
+            static_cast<ScFormulaCell*>(pCell)->EndListeningTo(pDocument);
         pCell->Delete();
         bDirtyGroups = true;
 
@@ -190,7 +193,8 @@ void ScColumn::DeleteAtIndex( SCSIZE nIndex )
         ScHint(SC_HINT_DYING, ScAddress(nCol, nRow, nTab), pCell));
     pNoteCell->Delete();
     maItems.erase(maItems.begin() + nIndex);
-    pCell->EndListeningTo( pDocument );
+    if (pCell->GetCellType() == CELLTYPE_FORMULA)
+        static_cast<ScFormulaCell*>(pCell)->EndListeningTo(pDocument);
     pCell->Delete();
 
     bDirtyGroups = true;
@@ -1446,7 +1450,7 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
 
                 if ( pOldCell->GetCellType() == CELLTYPE_FORMULA )
                 {
-                    pOldCell->EndListeningTo( pDocument );
+                    static_cast<ScFormulaCell*>(pOldCell)->EndListeningTo(pDocument);
                     // If in EndListening NoteCell destroyed in same in gleicher Col
                     if ( i >= maItems.size() || maItems[i].nRow != nRow )
                         Search(nRow, i);
@@ -1460,7 +1464,7 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
 
                 if ( pNewCell->GetCellType() == CELLTYPE_FORMULA )
                 {
-                    pNewCell->StartListeningTo( pDocument );
+                    static_cast<ScFormulaCell*>(pNewCell)->StartListeningTo(pDocument);
                     ((ScFormulaCell*)pNewCell)->SetDirty();
                 }
                 else
commit 49f9492358944b45cb9878aea0d6158df8301869
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 20:35:34 2013 -0400

    attrarray.cxx is now free of ScBaseCell.
    
    Change-Id: I9a323062fc341ef5fc20f2922503a88f3a45ce0d

diff --git a/sc/inc/editutil.hxx b/sc/inc/editutil.hxx
index 5f979cb..f18c094 100644
--- a/sc/inc/editutil.hxx
+++ b/sc/inc/editutil.hxx
@@ -64,6 +64,8 @@ public:
     static EditTextObject* CreateURLObjectFromURL(
         ScDocument& rDoc, const OUString& rURL, const OUString& rText );
 
+    static void RemoveCharAttribs( EditTextObject& rEditText, const ScPatternAttr& rAttr );
+
 public:
                 ScEditUtil( ScDocument* pDocument, SCCOL nX, SCROW nY, SCTAB nZ,
                             const Point& rScrPosPixel,
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 9d1996a..29522130 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -17,6 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include "attarray.hxx"
 #include "scitems.hxx"
 #include <svx/algitem.hxx>
 #include <editeng/boxitem.hxx>
@@ -29,7 +30,6 @@
 #include <editeng/fontitem.hxx>
 #include <unotools/fontcvt.hxx>
 
-#include "attarray.hxx"
 #include "global.hxx"
 #include "document.hxx"
 #include "docpool.hxx"
@@ -41,6 +41,8 @@
 #include "globstr.hrc"
 #include "segmenttree.hxx"
 #include "cell.hxx"
+#include "cellvalue.hxx"
+#include "editutil.hxx"
 #include <rtl/strbuf.hxx>
 
 // STATIC DATA -----------------------------------------------------------
@@ -352,20 +354,24 @@ void ScAttrArray::RemoveCellCharAttribs( SCROW nStartRow, SCROW nEndRow,
 {
     for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
     {
-        ScBaseCell* pCell;
-        pDocument->GetCell(nCol, nRow, nTab, pCell);
-        if (pCell && pCell->GetCellType() == CELLTYPE_EDIT)
+        ScAddress aPos(nCol, nRow, nTab);
+        ScRefCellValue aCell;
+        aCell.assign(*pDocument, aPos);
+        if (aCell.meType != CELLTYPE_EDIT || !aCell.mpEditText)
+            continue;
+
+        EditTextObject* pOldData = NULL;
+        if (pDataArray)
+            pOldData = aCell.mpEditText->Clone();
+
+        // Direct modification of cell content - something to watch out for if
+        // we decide to share edit text instances in the future.
+        ScEditUtil::RemoveCharAttribs(const_cast<EditTextObject&>(*aCell.mpEditText), *pPattern);
+
+        if (pDataArray)
         {
-            EditTextObject* pOldData = NULL;
-            ScEditCell* pEditCell = static_cast<ScEditCell*>(pCell);
-            if (pDataArray)
-                pOldData = pEditCell->GetData()->Clone();
-            pEditCell->RemoveCharAttribs(*pPattern);
-            if (pDataArray)
-            {
-                EditTextObject* pNewData = pEditCell->GetData()->Clone();
-                pDataArray->AddItem(nTab, nCol, nRow, pOldData, pNewData);
-            }
+            EditTextObject* pNewData = aCell.mpEditText->Clone();
+            pDataArray->AddItem(nTab, nCol, nRow, pOldData, pNewData);
         }
     }
 }
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index cacd5e1..297f8d0 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -146,24 +146,7 @@ const EditTextObject* ScEditCell::GetData() const
 
 void ScEditCell::RemoveCharAttribs( const ScPatternAttr& rAttr )
 {
-    const struct {
-        sal_uInt16 nAttrType;
-        sal_uInt16 nCharType;
-    } AttrTypeMap[] = {
-        { ATTR_FONT,        EE_CHAR_FONTINFO },
-        { ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT },
-        { ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT },
-        { ATTR_FONT_COLOR,  EE_CHAR_COLOR }
-    };
-    sal_uInt16 nMapCount = sizeof (AttrTypeMap) / sizeof (AttrTypeMap[0]);
-
-    const SfxItemSet& rSet = rAttr.GetItemSet();
-    const SfxPoolItem* pItem;
-    for (sal_uInt16 i = 0; i < nMapCount; ++i)
-    {
-        if ( rSet.GetItemState(AttrTypeMap[i].nAttrType, false, &pItem) == SFX_ITEM_SET )
-            mpData->RemoveCharAttribs(AttrTypeMap[i].nCharType);
-    }
+    ScEditUtil::RemoveCharAttribs(*mpData, rAttr);
 }
 
 void ScEditCell::UpdateFields(SCTAB nTab)
diff --git a/sc/source/core/tool/editutil.cxx b/sc/source/core/tool/editutil.cxx
index 53f36ad..4e1955c 100644
--- a/sc/source/core/tool/editutil.cxx
+++ b/sc/source/core/tool/editutil.cxx
@@ -114,6 +114,28 @@ EditTextObject* ScEditUtil::CreateURLObjectFromURL( ScDocument& rDoc, const OUSt
     return rEE.CreateTextObject();
 }
 
+void ScEditUtil::RemoveCharAttribs( EditTextObject& rEditText, const ScPatternAttr& rAttr )
+{
+    const struct {
+        sal_uInt16 nAttrType;
+        sal_uInt16 nCharType;
+    } AttrTypeMap[] = {
+        { ATTR_FONT,        EE_CHAR_FONTINFO },
+        { ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT },
+        { ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT },
+        { ATTR_FONT_COLOR,  EE_CHAR_COLOR }
+    };
+    sal_uInt16 nMapCount = sizeof (AttrTypeMap) / sizeof (AttrTypeMap[0]);
+
+    const SfxItemSet& rSet = rAttr.GetItemSet();
+    const SfxPoolItem* pItem;
+    for (sal_uInt16 i = 0; i < nMapCount; ++i)
+    {
+        if ( rSet.GetItemState(AttrTypeMap[i].nAttrType, false, &pItem) == SFX_ITEM_SET )
+            rEditText.RemoveCharAttribs(AttrTypeMap[i].nCharType);
+    }
+}
+
 //------------------------------------------------------------------------
 
 Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, sal_Bool bForceToTop )
commit f861f02ac9eadd9b3ab9f0b6c3c42e570805f537
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 27 19:44:04 2013 -0400

    cellsuno.cxx is now free of ScBaseCell.
    
    Change-Id: Idc967bf3028c93e80edec81823d620e9f2626556

diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 1b9a2e5..20bd346 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -6663,20 +6663,19 @@ table::CellContentType ScCellObj::GetResultType_Impl()
 sal_Int32 SAL_CALL ScCellObj::getError() throw(uno::RuntimeException)
 {
     SolarMutexGuard aGuard;
-    sal_uInt16 nError = 0;
     ScDocShell* pDocSh = GetDocShell();
-    if (pDocSh)
-    {
-        ScBaseCell* pCell = pDocSh->GetDocument()->GetCell( aCellPos );
-        if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
-            nError = ((ScFormulaCell*)pCell)->GetErrCode();
-        // sonst bleibt's bei 0
-    }
-    else
+    if (!pDocSh)
     {
         OSL_FAIL("keine DocShell");     //! Exception oder so?
+        return 0;
     }
 
+    sal_uInt16 nError = 0;
+    ScRefCellValue aCell;
+    aCell.assign(*pDocSh->GetDocument(), aCellPos);
+    if (aCell.meType == CELLTYPE_FORMULA)
+        nError = aCell.mpFormula->GetErrCode();
+
     return nError;
 }
 
@@ -6687,16 +6686,17 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellObj::getTokens() throw(uno::Ru
     SolarMutexGuard aGuard;
     uno::Sequence<sheet::FormulaToken> aSequence;
     ScDocShell* pDocSh = GetDocShell();
-    if ( pDocSh )
+    if (!pDocSh)
+        return aSequence;
+
+    ScDocument* pDoc = pDocSh->GetDocument();
+    ScRefCellValue aCell;
+    aCell.assign(*pDoc, aCellPos);
+    if (aCell.meType == CELLTYPE_FORMULA)
     {
-        ScDocument* pDoc = pDocSh->GetDocument();
-        ScBaseCell* pCell = pDoc->GetCell( aCellPos );
-        if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
-        {
-            ScTokenArray* pTokenArray = static_cast<ScFormulaCell*>(pCell)->GetCode();
-            if ( pTokenArray )
-                (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aSequence, *pTokenArray );
-        }
+        ScTokenArray* pTokenArray = aCell.mpFormula->GetCode();
+        if (pTokenArray)

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list