[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 3 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Mon Aug 5 21:27:38 PDT 2013


 sc/inc/column.hxx                      |    5 -
 sc/inc/document.hxx                    |    1 
 sc/inc/formulacell.hxx                 |   12 ++
 sc/inc/table.hxx                       |    1 
 sc/inc/tokenarray.hxx                  |    6 +
 sc/qa/unit/data/xls/shared-formula.xls |binary
 sc/qa/unit/filters-test.cxx            |    9 ++
 sc/source/core/data/column3.cxx        |   25 ++++-
 sc/source/core/data/documen2.cxx       |    8 +
 sc/source/core/data/formulacell.cxx    |  103 ++++++++++++++++++------
 sc/source/core/data/table2.cxx         |    8 +
 sc/source/core/tool/token.cxx          |   36 ++++++++
 sc/source/filter/excel/excform.cxx     |  141 +++++++++++++++------------------
 sc/source/filter/excel/impop.cxx       |    2 
 sc/source/filter/excel/namebuff.cxx    |   97 ++++++----------------
 sc/source/filter/excel/read.cxx        |    2 
 sc/source/filter/inc/excform.hxx       |    2 
 sc/source/filter/inc/namebuff.hxx      |   35 +++-----
 sc/source/filter/inc/root.hxx          |    4 
 19 files changed, 294 insertions(+), 203 deletions(-)

New commits:
commit c12146c1c0614b9ddd55ec5bed458e581369af16
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Aug 6 00:15:10 2013 -0400

    Map shared formula from xls to formula groups, and share the tokens as well.
    
    No more mapping to range names.
    
    Change-Id: Ic43b6ef35a91fe4d6fff748ebc22969ba4e036db

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 045b76a..22bb9bd 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -275,6 +275,7 @@ public:
      */
     ScFormulaCell* SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
     ScFormulaCell* SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell );
+    bool SetGroupFormulaCell( SCROW nRow, ScFormulaCell* pCell );
 
     void SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast = true );
     void SetRawString( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const OUString& rStr, bool bBroadcast = true );
@@ -507,8 +508,8 @@ private:
 
     sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow );
     sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
-    void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell );
-    void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell );
+    void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell, bool bJoin = true );
+    void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell, bool bJoin = true );
     void BroadcastNewCell( SCROW nRow );
     bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 90e0148..8b82fb7 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -804,6 +804,7 @@ public:
      *         is deleted automatically on failure to insert.
      */
     SC_DLLPUBLIC ScFormulaCell* SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
+    SC_DLLPUBLIC bool SetGroupFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
 
     SC_DLLPUBLIC void InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
                                         SCCOL nCol2, SCROW nRow2,
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 6480056..f857aff 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -27,6 +27,7 @@
 #include "types.hxx"
 
 #include <set>
+#include <boost/noncopyable.hpp>
 
 namespace sc {
 
@@ -43,7 +44,7 @@ class ScProgress;
 class ScTokenArray;
 struct ScSimilarFormulaDelta;
 
-struct SC_DLLPUBLIC ScFormulaCellGroup
+struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable
 {
     mutable size_t mnRefCount;
 
@@ -55,6 +56,8 @@ struct SC_DLLPUBLIC ScFormulaCellGroup
 
     ScFormulaCellGroup();
     ~ScFormulaCellGroup();
+
+    void setCode( const ScTokenArray& rCode );
 };
 
 inline void intrusive_ptr_add_ref(const ScFormulaCellGroup *p)
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 37c1430..a95f2bc 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -340,6 +340,7 @@ public:
      *         is deleted automatically on failure to insert.
      */
     ScFormulaCell* SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell );
+    bool SetGroupFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell );
 
     void        SetValue( SCCOL nCol, SCROW nRow, const double& rVal );
     void        SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError);
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index f9a4ff1..09a9798 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -62,6 +62,12 @@ public:
 
     ScFormulaVectorState GetVectorState() const;
 
+    /**
+     * If the array contains at least one relative row reference or named
+     * expression, it's variant. Otherwise invariant.
+     */
+    bool IsInvariant() const;
+
     /// Exactly and only one range (valid or deleted)
     bool IsReference( ScRange& rRange, const ScAddress& rPos ) const;
     /// Exactly and only one valid range (no #REF!s)
diff --git a/sc/qa/unit/data/xls/shared-formula.xls b/sc/qa/unit/data/xls/shared-formula.xls
index a9be6b7..f27acb4 100644
Binary files a/sc/qa/unit/data/xls/shared-formula.xls and b/sc/qa/unit/data/xls/shared-formula.xls differ
diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx
index 1d7eeca..957e0e0 100644
--- a/sc/qa/unit/filters-test.cxx
+++ b/sc/qa/unit/filters-test.cxx
@@ -32,6 +32,8 @@
 #include "cellform.hxx"
 #include "drwlayer.hxx"
 #include "userdat.hxx"
+#include "formulacell.hxx"
+
 #include <svx/svdpage.hxx>
 
 using namespace ::com::sun::star;
@@ -344,6 +346,13 @@ void ScFiltersTest::testSharedFormulaXLS()
         double fCheck = i*10.0;
         CPPUNIT_ASSERT_EQUAL(fCheck, fVal);
     }
+
+    ScFormulaCell* pCell = pDoc->GetFormulaCell(ScAddress(1,18,0));
+    CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pCell);
+    ScFormulaCellGroupRef xGroup = pCell->GetCellGroup();
+    CPPUNIT_ASSERT_MESSAGE("This cell should be a part of a cell group.", xGroup);
+    CPPUNIT_ASSERT_MESSAGE("Incorrect group geometry.", xGroup->mnStart == 2 && xGroup->mnLength == 17);
+
     xDocSh->DoClose();
 }
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 4474aec..461193c 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -381,16 +381,17 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
 }
 
 void ScColumn::ActivateNewFormulaCell(
-    const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell )
+    const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell, bool bJoin )
 {
-    ActivateNewFormulaCell(maCells.position(itPos, nRow), rCell);
+    ActivateNewFormulaCell(maCells.position(itPos, nRow), rCell, bJoin);
 }
 
 void ScColumn::ActivateNewFormulaCell(
-    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell )
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell, bool bJoin )
 {
-    // See if this new formula cell can join an existing shared formula group.
-    JoinNewFormulaCell(aPos, rCell);
+    if (bJoin)
+        // See if this new formula cell can join an existing shared formula group.
+        JoinNewFormulaCell(aPos, rCell);
 
     // When we insert from the Clipboard we still have wrong (old) References!
     // First they are rewired in CopyBlockFromClip via UpdateReference and the
@@ -1729,6 +1730,20 @@ ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCR
     return pCell;
 }
 
+bool ScColumn::SetGroupFormulaCell( SCROW nRow, ScFormulaCell* pCell )
+{
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
+    sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+    if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+        pCell->SetNeedNumberFormat(true);
+    it = maCells.set(it, nRow, pCell);
+    maCellTextAttrs.set(nRow, sc::CellTextAttr());
+    CellStorageModified();
+
+    ActivateNewFormulaCell(it, nRow, *pCell, false);
+    return true;
+}
+
 namespace {
 
 class FilterEntriesHandler
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 7a9e9d6..720b504 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -1075,6 +1075,14 @@ ScFormulaCell* ScDocument::SetFormulaCell( const ScAddress& rPos, ScFormulaCell*
     return maTabs[rPos.Tab()]->SetFormulaCell(rPos.Col(), rPos.Row(), pCell);
 }
 
+bool ScDocument::SetGroupFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell )
+{
+    if (!TableExists(rPos.Tab()))
+        return false;
+
+    return maTabs[rPos.Tab()]->SetGroupFormulaCell(rPos.Col(), rPos.Row(), pCell);
+}
+
 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
 {
     delete pConsolidateDlgData;
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index cdedb66..b9db55a 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -397,6 +397,14 @@ ScFormulaCellGroup::~ScFormulaCellGroup()
     delete mpCode;
 }
 
+void ScFormulaCellGroup::setCode( const ScTokenArray& rCode )
+{
+    delete mpCode;
+    mpCode = rCode.Clone();
+    mbInvariant = mpCode->IsInvariant();
+    mpCode->GenHash();
+}
+
 // ============================================================================
 
 ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
@@ -522,8 +530,6 @@ ScFormulaCell::ScFormulaCell(
 
     if (bSubTotal)
         pDocument->AddSubTotalCell(this);
-
-    pCode->GenHash();
 }
 
 ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags ) :
@@ -3358,7 +3364,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
 
     // Re-build formulae groups if necessary - ideally this is done at
     // import / insert / delete etc. and is integral to the data structures
-    pDocument->RebuildFormulaGroups();
+//  pDocument->RebuildFormulaGroups();
 
     if (!mxGroup || !pCode)
         return false;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 278096e..537f856 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1453,6 +1453,14 @@ ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* p
     return aCol[nCol].SetFormulaCell(nRow, pCell);
 }
 
+bool ScTable::SetGroupFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell )
+{
+    if (!ValidColRow(nCol, nRow))
+        return false;
+
+    return aCol[nCol].SetGroupFormulaCell(nRow, pCell);
+}
+
 void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
 {
     if (ValidColRow(nCol, nRow))
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 4703cde..d74182d 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1474,6 +1474,42 @@ ScFormulaVectorState ScTokenArray::GetVectorState() const
     return meVectorState;
 }
 
+bool ScTokenArray::IsInvariant() const
+{
+    FormulaToken** p = pCode;
+    FormulaToken** pEnd = p + static_cast<size_t>(nLen);
+    for (; p != pEnd; ++p)
+    {
+        switch ((*p)->GetType())
+        {
+            case svSingleRef:
+            case svExternalSingleRef:
+            {
+                const ScToken* pT = static_cast<const ScToken*>(*p);
+                const ScSingleRefData& rRef = pT->GetSingleRef();
+                if (rRef.IsRowRel())
+                    return false;
+            }
+            break;
+            case svDoubleRef:
+            case svExternalDoubleRef:
+            {
+                const ScToken* pT = static_cast<const ScToken*>(*p);
+                const ScComplexRefData& rRef = pT->GetDoubleRef();
+                if (rRef.Ref1.IsRowRel() || rRef.Ref2.IsRowRel())
+                    return false;
+            }
+            break;
+            case svIndex:
+                return false;
+            default:
+                ;
+        }
+    }
+
+    return true;
+}
+
 bool ScTokenArray::IsReference( ScRange& rRange, const ScAddress& rPos ) const
 {
     return ImplGetReference(rRange, rPos, false);
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 4f60d7e..e236dad 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -101,7 +101,6 @@ void ImportExcel::Formula4()
 void ImportExcel::Formula(
     const XclAddress& rXclPos, sal_uInt16 nXF, sal_uInt16 nFormLen, double fCurVal, bool bShrFmla)
 {
-
     ScAddress aScPos( ScAddress::UNINITIALIZED );
     if (!GetAddressConverter().ConvertAddress(aScPos, rXclPos, GetCurrScTab(), true))
         // Conversion failed.
@@ -115,13 +114,18 @@ void ImportExcel::Formula(
     if (bShrFmla)
     {
         // This is a shared formula. Get the token array from the shared formula pool.
-        pResult = pFormConv->GetShrFmla(maStrm, nFormLen);
-        if (!pResult)
+        ScFormulaCellGroupRef xGroup = pFormConv->GetSharedFormula(maStrm, aScPos.Col(), nFormLen);
+        if (!xGroup)
             return;
 
-        ScFormulaCell* pCell = new ScFormulaCell( pD, aScPos, pResult );
+        ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, xGroup);
         pD->EnsureTable(aScPos.Tab());
-        pCell = pD->SetFormulaCell(aScPos, pCell);
+        bool bInserted = pD->SetGroupFormulaCell(aScPos, pCell);
+        if (!bInserted)
+        {
+            delete pCell;
+            return;
+        }
         pCell->SetNeedNumberFormat(false);
         if (!rtl::math::isNan(fCurVal))
             pCell->SetResultDouble(fCurVal);
@@ -1673,38 +1677,33 @@ const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
     return pErgebnis;
 }
 
-
-// if a shared formula was found, stream seeks to first byte after <nFormulaLen>,
-// else stream pointer stays unchanged
-const ScTokenArray* ExcelToSc::GetShrFmla( XclImpStream& aIn, sal_Size nFormulaLen )
+ScFormulaCellGroupRef ExcelToSc::GetSharedFormula( XclImpStream& aIn, SCCOL nCol, sal_Size nFormulaLen )
 {
     if (!nFormulaLen)
-        return NULL;
+        return ScFormulaCellGroupRef();
 
     aIn.PushPosition();
 
     sal_uInt8 nOp;
     aIn >> nOp;
 
-    if (nOp != 0x01)   // Shared Formula       [    277]
+    if (nOp != 0x01)   // must be PtgExp token.
     {
         aIn.PopPosition();
-        return NULL;
+        return ScFormulaCellGroupRef();
     }
 
-    sal_uInt16 nCol, nRow;
-    aIn >> nRow >> nCol;
+    sal_uInt16 nLeftCol, nRow;
+    aIn >> nRow >> nLeftCol;
 
-    aStack << aPool.StoreName( GetOldRoot().pShrfmlaBuff->Find(
-        ScAddress(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab())), true);
+    ScAddress aRefPos(nCol, nRow, GetCurrScTab());
+    ScFormulaCellGroupRef xGroup = GetOldRoot().pShrfmlaBuff->Find(aRefPos);
 
     aIn.PopPosition();
-
     aIn.Ignore(nFormulaLen);
-    return aPool[aStack.Get()];
+    return xGroup;
 }
 
-
 void ExcelToSc::SetError( ScFormulaCell &rCell, const ConvErr eErr )
 {
     sal_uInt16  nInd;
diff --git a/sc/source/filter/excel/namebuff.cxx b/sc/source/filter/excel/namebuff.cxx
index 6279c87..ac609a4 100644
--- a/sc/source/filter/excel/namebuff.cxx
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -20,9 +20,6 @@
 
 #include "namebuff.hxx"
 
-#include <string.h>
-
-#include "rangenam.hxx"
 #include "document.hxx"
 #include "compiler.hxx"
 #include "scextopt.hxx"
@@ -32,6 +29,7 @@
 #include "xltools.hxx"
 #include "xiroot.hxx"
 
+#include <string.h>
 
 sal_uInt32 StringHashEntry::MakeHashCode( const String& r )
 {
@@ -70,84 +68,41 @@ void NameBuffer::operator <<( const String &rNewString )
     maHashes.push_back( new StringHashEntry( rNewString ) );
 }
 
+SharedFormulaBuffer::SharedFormulaBuffer( RootData* pRD ) : ExcRoot(pRD) {}
 
-#if OSL_DEBUG_LEVEL > 0
-sal_uInt16  nShrCnt;
-#endif
-
-
-size_t SharedFormulaBuffer::ScAddressHashFunc::operator() (const ScAddress &addr) const
-{
-    // Use something simple, it is just a hash.
-    return static_cast< sal_uInt16 >( addr.Row() ) | (static_cast< sal_uInt8 >( addr.Col() ) << 16);
-}
-
-const size_t nBase = 16384; // Range~ und Shared~ Dingens mit jeweils der Haelfte Ids
-SharedFormulaBuffer::SharedFormulaBuffer( RootData* pRD ) :
-    ExcRoot( pRD ),
-    mnCurrIdx (nBase)
-{
-#if OSL_DEBUG_LEVEL > 0
-    nShrCnt = 0;
-#endif
-}
-
-SharedFormulaBuffer::~SharedFormulaBuffer()
-{
-}
+SharedFormulaBuffer::~SharedFormulaBuffer() {}
 
 void SharedFormulaBuffer::Clear()
 {
-    index_hash.clear();
-    // do not clear index_list, index calculation depends on complete list size...
-    // do not change mnCurrIdx
+    maFormulaGroups.clear();
 }
 
-void SharedFormulaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
+void SharedFormulaBuffer::Store( const ScRange& rRange, const ScTokenArray& rArray )
 {
-    String          aName( CreateName( rRange.aStart ) );
-
-    OSL_ENSURE( mnCurrIdx <= 0xFFFF, "*ShrfmlaBuffer::Store(): I'm getting sick...!" );
-
-    ScRangeData* pData = new ScRangeData( pExcRoot->pIR->GetDocPtr(), aName, rToken, rRange.aStart, RT_SHARED );
-    const ScAddress& rMaxPos = pExcRoot->pIR->GetMaxPos();
-    pData->SetMaxCol(rMaxPos.Col());
-    pData->SetMaxRow(rMaxPos.Row());
-    pData->SetIndex( static_cast< sal_uInt16 >( mnCurrIdx ) );
-    pExcRoot->pIR->GetNamedRanges().insert( pData );
-    index_hash[rRange.aStart] = static_cast< sal_uInt16 >( mnCurrIdx );
-    index_list.push_front (rRange);
-    ++mnCurrIdx;
+    SCROW nGroupLen = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
+    for (SCCOL i = rRange.aStart.Col(); i <= rRange.aEnd.Col(); ++i)
+    {
+        // Create one group per column.
+        ScAddress aPos = rRange.aStart;
+        aPos.SetCol(i);
+
+        ScFormulaCellGroupRef xNewGroup(new ScFormulaCellGroup);
+        xNewGroup->mnStart = rRange.aStart.Row();
+        xNewGroup->mnLength = nGroupLen;
+        xNewGroup->mpCode = rArray.Clone();
+        xNewGroup->mbInvariant = rArray.IsInvariant();
+        xNewGroup->setCode(rArray);
+        maFormulaGroups.insert(FormulaGroupsType::value_type(aPos, xNewGroup));
+    }
 }
 
-
-sal_uInt16 SharedFormulaBuffer::Find( const ScAddress & aAddr ) const
+ScFormulaCellGroupRef SharedFormulaBuffer::Find( const ScAddress& rRefPos ) const
 {
-    ShrfmlaHash::const_iterator hash = index_hash.find (aAddr);
-    if (hash != index_hash.end())
-        return hash->second;
-
-    // It was not hashed on the top left corner ?  do a brute force search
-    unsigned int ind = nBase;
-    for (ShrfmlaList::const_iterator ptr = index_list.end(); ptr != index_list.begin() ; ind++)
-        if ((--ptr)->In (aAddr))
-            return static_cast< sal_uInt16 >( ind );
-    return static_cast< sal_uInt16 >( mnCurrIdx );
-}
-
+    FormulaGroupsType::const_iterator it = maFormulaGroups.find(rRefPos);
+    if (it == maFormulaGroups.end())
+        return ScFormulaCellGroupRef();
 
-#define SHRFMLA_BASENAME    "SHARED_FORMULA_"
-
-String SharedFormulaBuffer::CreateName( const ScRange& r )
-{
-    OUString aName = SHRFMLA_BASENAME +
-                     OUString::number( r.aStart.Col() ) + "_" +
-                     OUString::number( r.aStart.Row() ) + "_" +
-                     OUString::number( r.aEnd.Col() )   + "_" +
-                     OUString::number( r.aEnd.Row() )   + "_" +
-                     OUString::number( r.aStart.Tab() );
-
-    return aName;
+    return it->second;
 }
 
 sal_Int16 ExtSheetBuffer::Add( const String& rFPAN, const String& rTN, const sal_Bool bSWB )
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
index fb866fe..0e2004c 100644
--- a/sc/source/filter/inc/excform.hxx
+++ b/sc/source/filter/inc/excform.hxx
@@ -63,7 +63,7 @@ public:
 
     void                GetDummy( const ScTokenArray*& );
     const ScTokenArray* GetBoolErr( XclBoolError );
-    const ScTokenArray* GetShrFmla( XclImpStream& rStrm, sal_Size nFormulaLen );
+    ScFormulaCellGroupRef GetSharedFormula( XclImpStream& rStrm, SCCOL nCol, sal_Size nFormulaLen );
 
     static void         SetError( ScFormulaCell& rCell, const ConvErr eErr );
 
diff --git a/sc/source/filter/inc/namebuff.hxx b/sc/source/filter/inc/namebuff.hxx
index 6f5aa28..97aebc1 100644
--- a/sc/source/filter/inc/namebuff.hxx
+++ b/sc/source/filter/inc/namebuff.hxx
@@ -26,6 +26,8 @@
 #include "xiroot.hxx"
 
 #include "rangenam.hxx"
+#include "formulacell.hxx"
+
 #include <boost/unordered_map.hpp>
 #include <list>
 
@@ -146,30 +148,21 @@ inline void NameBuffer::SetBase( sal_uInt16 nNewBase )
     nBase = nNewBase;
 }
 
-
-
-
+/**
+ * Store and manage shared formula tokens.
+ */
 class SharedFormulaBuffer : public ExcRoot
 {
-    struct ScAddressHashFunc : public std::unary_function< const ScAddress &, size_t >
-    {
-        size_t operator() (const ScAddress &addr) const;
-    };
-    typedef boost::unordered_map <ScAddress, sal_uInt16, ScAddressHashFunc> ShrfmlaHash;
-    typedef std::list <ScRange>                                  ShrfmlaList;
+    typedef boost::unordered_map<ScAddress, ScFormulaCellGroupRef, ScAddressHashFunctor> FormulaGroupsType;
 
-    ShrfmlaHash  index_hash;
-    ShrfmlaList  index_list;
-    size_t                  mnCurrIdx;
+    FormulaGroupsType maFormulaGroups;
 
 public:
     SharedFormulaBuffer( RootData* pRD );
     virtual ~SharedFormulaBuffer();
-    void                    Clear();
-    void                    Store( const ScRange& rRange, const ScTokenArray& );
-    sal_uInt16                  Find (const ScAddress & rAddress ) const;
-
-    static String           CreateName( const ScRange& );
+    void Clear();
+    void Store( const ScRange& rRange, const ScTokenArray& rArray );
+    ScFormulaCellGroupRef Find( const ScAddress& rRefPos ) const;
 };
 
 
commit f9e9ba86e17ee758cfbb2061ffed1786f88573e8
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Mon Aug 5 22:31:58 2013 -0400

    Rename this to SharedFormulaBuffer, which is readable.
    
    ShrfmlaBuffer is not readable.
    
    Change-Id: Ic91f7c2fcc15d4210af4f97341199ce03593d223

diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index 2cf90d2..28ddd9f 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -125,7 +125,7 @@ ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ):
     pExcRoot->pIR = this;   // ExcRoot -> XclImpRoot
     pExcRoot->eDateiTyp = BiffX;
     pExcRoot->pExtSheetBuff = new ExtSheetBuffer( pExcRoot );   //&aExtSheetBuff;
-    pExcRoot->pShrfmlaBuff = new ShrfmlaBuffer( pExcRoot );     //&aShrfrmlaBuff;
+    pExcRoot->pShrfmlaBuff = new SharedFormulaBuffer( pExcRoot );     //&aShrfrmlaBuff;
     pExcRoot->pExtNameBuff = new ExtNameBuff ( *this );
 
     pExtNameBuff = new NameBuffer( pExcRoot );          //prevent empty rootdata
diff --git a/sc/source/filter/excel/namebuff.cxx b/sc/source/filter/excel/namebuff.cxx
index eb9e90cc..6279c87 100644
--- a/sc/source/filter/excel/namebuff.cxx
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -76,14 +76,14 @@ sal_uInt16  nShrCnt;
 #endif
 
 
-size_t ShrfmlaBuffer::ScAddressHashFunc::operator() (const ScAddress &addr) const
+size_t SharedFormulaBuffer::ScAddressHashFunc::operator() (const ScAddress &addr) const
 {
     // Use something simple, it is just a hash.
     return static_cast< sal_uInt16 >( addr.Row() ) | (static_cast< sal_uInt8 >( addr.Col() ) << 16);
 }
 
 const size_t nBase = 16384; // Range~ und Shared~ Dingens mit jeweils der Haelfte Ids
-ShrfmlaBuffer::ShrfmlaBuffer( RootData* pRD ) :
+SharedFormulaBuffer::SharedFormulaBuffer( RootData* pRD ) :
     ExcRoot( pRD ),
     mnCurrIdx (nBase)
 {
@@ -92,18 +92,18 @@ ShrfmlaBuffer::ShrfmlaBuffer( RootData* pRD ) :
 #endif
 }
 
-ShrfmlaBuffer::~ShrfmlaBuffer()
+SharedFormulaBuffer::~SharedFormulaBuffer()
 {
 }
 
-void ShrfmlaBuffer::Clear()
+void SharedFormulaBuffer::Clear()
 {
     index_hash.clear();
     // do not clear index_list, index calculation depends on complete list size...
     // do not change mnCurrIdx
 }
 
-void ShrfmlaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
+void SharedFormulaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
 {
     String          aName( CreateName( rRange.aStart ) );
 
@@ -121,7 +121,7 @@ void ShrfmlaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
 }
 
 
-sal_uInt16 ShrfmlaBuffer::Find( const ScAddress & aAddr ) const
+sal_uInt16 SharedFormulaBuffer::Find( const ScAddress & aAddr ) const
 {
     ShrfmlaHash::const_iterator hash = index_hash.find (aAddr);
     if (hash != index_hash.end())
@@ -138,7 +138,7 @@ sal_uInt16 ShrfmlaBuffer::Find( const ScAddress & aAddr ) const
 
 #define SHRFMLA_BASENAME    "SHARED_FORMULA_"
 
-String ShrfmlaBuffer::CreateName( const ScRange& r )
+String SharedFormulaBuffer::CreateName( const ScRange& r )
 {
     OUString aName = SHRFMLA_BASENAME +
                      OUString::number( r.aStart.Col() ) + "_" +
diff --git a/sc/source/filter/inc/namebuff.hxx b/sc/source/filter/inc/namebuff.hxx
index 38ead51..6f5aa28 100644
--- a/sc/source/filter/inc/namebuff.hxx
+++ b/sc/source/filter/inc/namebuff.hxx
@@ -149,7 +149,7 @@ inline void NameBuffer::SetBase( sal_uInt16 nNewBase )
 
 
 
-class ShrfmlaBuffer : public ExcRoot
+class SharedFormulaBuffer : public ExcRoot
 {
     struct ScAddressHashFunc : public std::unary_function< const ScAddress &, size_t >
     {
@@ -163,14 +163,14 @@ class ShrfmlaBuffer : public ExcRoot
     size_t                  mnCurrIdx;
 
 public:
-                            ShrfmlaBuffer( RootData* pRD );
-    virtual                 ~ShrfmlaBuffer();
+    SharedFormulaBuffer( RootData* pRD );
+    virtual ~SharedFormulaBuffer();
     void                    Clear();
     void                    Store( const ScRange& rRange, const ScTokenArray& );
     sal_uInt16                  Find (const ScAddress & rAddress ) const;
 
     static String           CreateName( const ScRange& );
-    };
+};
 
 
 
diff --git a/sc/source/filter/inc/root.hxx b/sc/source/filter/inc/root.hxx
index 1c9e075..492a463 100644
--- a/sc/source/filter/inc/root.hxx
+++ b/sc/source/filter/inc/root.hxx
@@ -30,7 +30,7 @@
 class ScRangeName;
 
 class RangeNameBufferWK3;
-class ShrfmlaBuffer;
+class SharedFormulaBuffer;
 class ExtNameBuff;
 class ExtSheetBuffer;
 class ExcelToSc;
@@ -51,7 +51,7 @@ struct RootData     // -> Inkarnation jeweils im ImportExcel-Objekt!
 {
     BiffTyp             eDateiTyp;              // feine Differenzierung
     ExtSheetBuffer*     pExtSheetBuff;
-    ShrfmlaBuffer*      pShrfmlaBuff;
+    SharedFormulaBuffer*      pShrfmlaBuff;
     ExtNameBuff*        pExtNameBuff;
     ExcelToSc*          pFmlaConverter;
     XclImpColRowSettings* pColRowBuff;        // Col/Row-Einstellungen 1 Tabelle
commit 0ea90c486493a10ec796f3420e7a23c72549d64c
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Mon Aug 5 22:26:11 2013 -0400

    Prepare for importing shared formulas as formula groups from xls.
    
    Still the first step.
    
    Change-Id: I1897c9c2cd3a5b5245febbfba76e1b088054f578

diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 1213959..6480056 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -47,6 +47,7 @@ struct SC_DLLPUBLIC ScFormulaCellGroup
 {
     mutable size_t mnRefCount;
 
+    ScTokenArray* mpCode;
     SCROW mnStart;  // Start offset of that cell
     SCROW mnLength; // How many of these do we have ?
     bool mbInvariant;
@@ -77,6 +78,7 @@ enum ScMatrixMode {
 class SC_DLLPUBLIC ScFormulaCell : public SvtListener
 {
 private:
+    ScFormulaCellGroupRef mxGroup;       // re-factoring hack - group of formulae we're part of.
     ScFormulaResult aResult;
     formula::FormulaGrammar::Grammar  eTempGrammar;   // used between string (creation) and (re)compilation
     ScTokenArray*   pCode;              // The (new) token array
@@ -85,7 +87,6 @@ private:
     ScFormulaCell*  pNext;
     ScFormulaCell*  pPreviousTrack;
     ScFormulaCell*  pNextTrack;
-    ScFormulaCellGroupRef xGroup;       // re-factoring hack - group of formulae we're part of.
     sal_uInt16      nSeenInIteration;   // Iteration cycle in which the cell was last encountered
     sal_uInt8       cMatrixFlag;        // One of ScMatrixMode
     short           nFormatType;
@@ -146,6 +147,10 @@ public:
                     const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
                     sal_uInt8 = MM_NONE );
 
+    ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScFormulaCellGroupRef& xGroup,
+                   const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
+                   sal_uInt8 = MM_NONE );
+
     /** With formula string and grammar to compile with.
        formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
         also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefor uses the address
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 0ad7cb6..cdedb66 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -384,6 +384,7 @@ void adjustDBRange(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldD
 
 ScFormulaCellGroup::ScFormulaCellGroup() :
     mnRefCount(0),
+    mpCode(NULL),
     mnStart(0),
     mnLength(0),
     mbInvariant(false),
@@ -393,6 +394,7 @@ ScFormulaCellGroup::ScFormulaCellGroup() :
 
 ScFormulaCellGroup::~ScFormulaCellGroup()
 {
+    delete mpCode;
 }
 
 // ============================================================================
@@ -477,6 +479,53 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
     pCode->GenHash();
 }
 
+ScFormulaCell::ScFormulaCell(
+    ScDocument* pDoc, const ScAddress& rPos, const ScFormulaCellGroupRef& xGroup,
+    const FormulaGrammar::Grammar eGrammar, sal_uInt8 cInd ) :
+    mxGroup(xGroup),
+    eTempGrammar( eGrammar),
+    pCode(xGroup->mpCode ? xGroup->mpCode : new ScTokenArray),
+    pDocument( pDoc ),
+    pPrevious(0),
+    pNext(0),
+    pPreviousTrack(0),
+    pNextTrack(0),
+    nSeenInIteration(0),
+    cMatrixFlag ( cInd ),
+    nFormatType ( NUMBERFORMAT_NUMBER ),
+    bDirty(false),
+    bChanged( false ),
+    bRunning( false ),
+    bCompile( false ),
+    bSubTotal( false ),
+    bIsIterCell( false ),
+    bInChangeTrack( false ),
+    bTableOpDirty( false ),
+    bNeedListening( false ),
+    mbNeedsNumberFormat( false ),
+    aPos( rPos )
+{
+    // UPN-Array generation
+    if( pCode->GetLen() && !pCode->GetCodeError() && !pCode->GetCodeLen() )
+    {
+        ScCompiler aComp( pDocument, aPos, *pCode);
+        aComp.SetGrammar(eTempGrammar);
+        bSubTotal = aComp.CompileTokenArray();
+        nFormatType = aComp.GetNumFormatType();
+    }
+    else
+    {
+        pCode->Reset();
+        if ( pCode->GetNextOpCodeRPN( ocSubTotal ) )
+            bSubTotal = true;
+    }
+
+    if (bSubTotal)
+        pDocument->AddSubTotalCell(this);
+
+    pCode->GenHash();
+}
+
 ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags ) :
     SvtListener(),
     aResult( rCell.aResult ),
@@ -605,7 +654,9 @@ ScFormulaCell::~ScFormulaCell()
     if (pDocument->HasExternalRefManager())
         pDocument->GetExternalRefManager()->removeRefCell(this);
 
-    delete pCode;
+    if (!mxGroup || !mxGroup->mpCode)
+        // Formula token is not shared.
+        delete pCode;
 }
 
 ScFormulaCell* ScFormulaCell::Clone() const
@@ -1579,8 +1630,8 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
 void ScFormulaCell::SetDirtyVar()
 {
     bDirty = true;
-    if (xGroup)
-        xGroup->meCalcState = sc::GroupCalcEnabled;
+    if (mxGroup)
+        mxGroup->meCalcState = sc::GroupCalcEnabled;
 
     // mark the sheet of this cell to be calculated
     //#FIXME do we need to revert this remnant of old fake vba events? pDocument->AddCalculateTable( aPos.Tab() );
@@ -2239,8 +2290,8 @@ bool ScFormulaCell::UpdateReferenceOnShift(
         // This formula cell itself is being shifted during cell range
         // insertion or deletion. Update its position.
         aPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
-        if (xGroup && xGroup->mnStart == aOldPos.Row())
-            xGroup->mnStart += rCxt.mnRowDelta;
+        if (mxGroup && mxGroup->mnStart == aOldPos.Row())
+            mxGroup->mnStart += rCxt.mnRowDelta;
 
         bCellStateChanged = aPos != aOldPos;
     }
@@ -3074,12 +3125,12 @@ void            ScFormulaCell::SetNextTrack( ScFormulaCell* pF )       { pNextTr
 
 ScFormulaCellGroupRef ScFormulaCell::GetCellGroup()
 {
-    return xGroup;
+    return mxGroup;
 }
 
 void ScFormulaCell::SetCellGroup( const ScFormulaCellGroupRef &xRef )
 {
-    xGroup = xRef;
+    mxGroup = xRef;
 }
 
 ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& rOther ) const
@@ -3309,10 +3360,10 @@ bool ScFormulaCell::InterpretFormulaGroup()
     // import / insert / delete etc. and is integral to the data structures
     pDocument->RebuildFormulaGroups();
 
-    if (!xGroup || !pCode)
+    if (!mxGroup || !pCode)
         return false;
 
-    if (xGroup->meCalcState == sc::GroupCalcDisabled)
+    if (mxGroup->meCalcState == sc::GroupCalcDisabled)
         return false;
 
     switch (pCode->GetVectorState())
@@ -3328,28 +3379,28 @@ bool ScFormulaCell::InterpretFormulaGroup()
             return false;
     }
 
-    if (xGroup->mbInvariant)
+    if (mxGroup->mbInvariant)
         return InterpretInvariantFormulaGroup();
 
     sc::FormulaGroupContext aCxt;
     ScTokenArray aCode;
     ScAddress aTopPos = aPos;
-    aTopPos.SetRow(xGroup->mnStart);
+    aTopPos.SetRow(mxGroup->mnStart);
     GroupTokenConverter aConverter(aCxt, aCode, *pDocument, *this, aTopPos);
     if (!aConverter.convert(*pCode))
     {
-        xGroup->meCalcState = sc::GroupCalcDisabled;
+        mxGroup->meCalcState = sc::GroupCalcDisabled;
         return false;
     }
 
-    xGroup->meCalcState = sc::GroupCalcRunning;
-    if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, aTopPos, xGroup, aCode))
+    mxGroup->meCalcState = sc::GroupCalcRunning;
+    if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, aTopPos, mxGroup, aCode))
     {
-        xGroup->meCalcState = sc::GroupCalcDisabled;
+        mxGroup->meCalcState = sc::GroupCalcDisabled;
         return false;
     }
 
-    xGroup->meCalcState = sc::GroupCalcEnabled;
+    mxGroup->meCalcState = sc::GroupCalcEnabled;
     return true;
 }
 
@@ -3409,10 +3460,10 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
         aResult.SetToken(aInterpreter.GetResultToken().get());
     }
 
-    for ( sal_Int32 i = 0; i < xGroup->mnLength; i++ )
+    for ( sal_Int32 i = 0; i < mxGroup->mnLength; i++ )
     {
         ScAddress aTmpPos = aPos;
-        aTmpPos.SetRow(xGroup->mnStart + i);
+        aTmpPos.SetRow(mxGroup->mnStart + i);
         ScFormulaCell* pCell = pDocument->GetFormulaCell(aTmpPos);
         assert( pCell != NULL );
 
@@ -3642,21 +3693,21 @@ void ScFormulaCell::EndListeningTo( sc::EndListeningContext& rCxt )
 
 bool ScFormulaCell::IsShared() const
 {
-    return xGroup.get() != NULL;
+    return mxGroup.get() != NULL;
 }
 
 bool ScFormulaCell::IsSharedInvariant() const
 {
-    return xGroup ? xGroup->mbInvariant : false;
+    return mxGroup ? mxGroup->mbInvariant : false;
 }
 
 SCROW ScFormulaCell::GetSharedTopRow() const
 {
-    return xGroup ? xGroup->mnStart : -1;
+    return mxGroup ? mxGroup->mnStart : -1;
 }
 SCROW ScFormulaCell::GetSharedLength() const
 {
-    return xGroup ? xGroup->mnLength : 0;
+    return mxGroup ? mxGroup->mnLength : 0;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index b2a1619..4f60d7e 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -101,56 +101,63 @@ void ImportExcel::Formula4()
 void ImportExcel::Formula(
     const XclAddress& rXclPos, sal_uInt16 nXF, sal_uInt16 nFormLen, double fCurVal, bool bShrFmla)
 {
-    ConvErr eErr = ConvOK;
 
     ScAddress aScPos( ScAddress::UNINITIALIZED );
-    if( GetAddressConverter().ConvertAddress( aScPos, rXclPos, GetCurrScTab(), true ) )
-    {
-        // Formula will be read next, length in nFormLen
-        const ScTokenArray* pResult = NULL;
-        bool bConvert = false;
+    if (!GetAddressConverter().ConvertAddress(aScPos, rXclPos, GetCurrScTab(), true))
+        // Conversion failed.
+        return;
 
-        pFormConv->Reset( aScPos );
+    // Formula will be read next, length in nFormLen
+    const ScTokenArray* pResult = NULL;
 
-        if( bShrFmla )
-            bConvert = !pFormConv->GetShrFmla( pResult, maStrm, nFormLen );
-        else
-            bConvert = true;
+    pFormConv->Reset( aScPos );
 
-        if( bConvert )
-            eErr = pFormConv->Convert( pResult, maStrm, nFormLen, true, FT_CellFormula);
+    if (bShrFmla)
+    {
+        // This is a shared formula. Get the token array from the shared formula pool.
+        pResult = pFormConv->GetShrFmla(maStrm, nFormLen);
+        if (!pResult)
+            return;
+
+        ScFormulaCell* pCell = new ScFormulaCell( pD, aScPos, pResult );
+        pD->EnsureTable(aScPos.Tab());
+        pCell = pD->SetFormulaCell(aScPos, pCell);
+        pCell->SetNeedNumberFormat(false);
+        if (!rtl::math::isNan(fCurVal))
+            pCell->SetResultDouble(fCurVal);
+
+        GetXFRangeBuffer().SetXF(aScPos, nXF);
+        return;
+    }
 
-        ScFormulaCell* pCell = NULL;
+    ConvErr eErr = pFormConv->Convert( pResult, maStrm, nFormLen, true, FT_CellFormula);
 
-        if (pResult)
-        {
-            pCell = new ScFormulaCell( pD, aScPos, pResult );
-            pD->EnsureTable(aScPos.Tab());
-            pCell = pD->SetFormulaCell(aScPos, pCell);
-        }
-        else
-        {
-            CellType eCellType = pD->GetCellType(aScPos);
-            if( eCellType == CELLTYPE_FORMULA )
-            {
-                pCell = pD->GetFormulaCell(aScPos);
-                if( pCell )
-                    pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
-            }
-        }
+    ScFormulaCell* pCell = NULL;
 
+    if (pResult)
+    {
+        pCell = new ScFormulaCell( pD, aScPos, pResult );
+        pD->EnsureTable(aScPos.Tab());
+        pCell = pD->SetFormulaCell(aScPos, pCell);
+    }
+    else
+    {
+        pCell = pD->GetFormulaCell(aScPos);
         if (pCell)
-        {
-            pCell->SetNeedNumberFormat(false);
-            if( eErr != ConvOK )
-                ExcelToSc::SetError( *pCell, eErr );
+            pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+    }
 
-            if (!rtl::math::isNan(fCurVal))
-                pCell->SetResultDouble(fCurVal);
-        }
+    if (pCell)
+    {
+        pCell->SetNeedNumberFormat(false);
+        if( eErr != ConvOK )
+            ExcelToSc::SetError( *pCell, eErr );
 
-        GetXFRangeBuffer().SetXF( aScPos, nXF );
+        if (!rtl::math::isNan(fCurVal))
+            pCell->SetResultDouble(fCurVal);
     }
+
+    GetXFRangeBuffer().SetXF(aScPos, nXF);
 }
 
 
@@ -1669,45 +1676,32 @@ const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
 
 // if a shared formula was found, stream seeks to first byte after <nFormulaLen>,
 // else stream pointer stays unchanged
-sal_Bool ExcelToSc::GetShrFmla( const ScTokenArray*& rpErgebnis, XclImpStream& aIn, sal_Size nFormulaLen )
+const ScTokenArray* ExcelToSc::GetShrFmla( XclImpStream& aIn, sal_Size nFormulaLen )
 {
-    sal_uInt8           nOp;
-    sal_Bool            bRet = sal_True;
+    if (!nFormulaLen)
+        return NULL;
 
-    if( nFormulaLen == 0 )
-        bRet = false;
-    else
-    {
-        aIn.PushPosition();
-
-        aIn >> nOp;
+    aIn.PushPosition();
 
-        if( nOp == 0x01 )   // Shared Formula       [    277]
-        {
-            sal_uInt16 nCol, nRow;
-
-            aIn >> nRow >> nCol;
-
-            aStack << aPool.StoreName( GetOldRoot().pShrfmlaBuff->Find(
-                ScAddress(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab())), true);
-
-            bRet = sal_True;
-        }
-        else
-            bRet = false;
+    sal_uInt8 nOp;
+    aIn >> nOp;
 
+    if (nOp != 0x01)   // Shared Formula       [    277]
+    {
         aIn.PopPosition();
+        return NULL;
     }
 
-    if( bRet )
-    {
-        aIn.Ignore( nFormulaLen );
-        rpErgebnis = aPool[ aStack.Get() ];
-    }
-    else
-        rpErgebnis = NULL;
+    sal_uInt16 nCol, nRow;
+    aIn >> nRow >> nCol;
+
+    aStack << aPool.StoreName( GetOldRoot().pShrfmlaBuff->Find(
+        ScAddress(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab())), true);
+
+    aIn.PopPosition();
 
-    return bRet;
+    aIn.Ignore(nFormulaLen);
+    return aPool[aStack.Get()];
 }
 
 
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index d1ec8ae..9c4c5e7 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -1140,7 +1140,7 @@ FltError ImportExcel8::Read( void )
                     case EXC_ID2_ARRAY:
                     case EXC_ID3_ARRAY: Array34(); break;      // ARRAY        [  34    ]
                     case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345   ]
-                    case 0x04BC: Shrfmla(); break;      // SHRFMLA      [    5   ]
+                    case EXC_ID_SHRFMLA: Shrfmla(); break;      // SHRFMLA      [    5   ]
                     case 0x0867: SheetProtection(); break; // SHEETPROTECTION
                 }
             }
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
index 1b7786f..fb866fe 100644
--- a/sc/source/filter/inc/excform.hxx
+++ b/sc/source/filter/inc/excform.hxx
@@ -63,7 +63,7 @@ public:
 
     void                GetDummy( const ScTokenArray*& );
     const ScTokenArray* GetBoolErr( XclBoolError );
-    sal_Bool                GetShrFmla( const ScTokenArray*&, XclImpStream& rStrm, sal_Size nFormulaLen );
+    const ScTokenArray* GetShrFmla( XclImpStream& rStrm, sal_Size nFormulaLen );
 
     static void         SetError( ScFormulaCell& rCell, const ConvErr eErr );
 


More information about the Libreoffice-commits mailing list