[Libreoffice-commits] core.git: sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Dec 4 18:52:33 PST 2013


 sc/source/filter/excel/excform.cxx  |   49 +++++++++---------------------------
 sc/source/filter/excel/impop.cxx    |   33 +++++++++---------------
 sc/source/filter/excel/namebuff.cxx |   39 ++++++++++++----------------
 sc/source/filter/inc/excform.hxx    |    2 -
 sc/source/filter/inc/namebuff.hxx   |   12 ++------
 5 files changed, 48 insertions(+), 87 deletions(-)

New commits:
commit c6ccab60fa881ad80e64168ced4c5f74349512b0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Dec 4 21:52:09 2013 -0500

    Never attempt to create formula groups based on Excel's shared formula ranges.
    
    Because they are wrong more than half the time.
    
    Change-Id: I24e49c53520442be698e43976d28d0f8477648e6

diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 2b7175b..0273ddd 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -125,40 +125,18 @@ void ImportExcel::Formula(
         if (pFormConv->ReadSharedFormulaPosition(maStrm, nSharedCol, nSharedRow))
         {
             ScAddress aRefPos(aScPos.Col(), nSharedRow, GetCurrScTab());
-            ScFormulaCellGroupRef xGroup = pFormConv->GetSharedFormula(aRefPos);
-            if (xGroup)
+            const ScTokenArray* pSharedCode = pFormConv->GetSharedFormula(aRefPos);
+            if (pSharedCode)
             {
-                // Make sure the this one follows immediately below another shared formula cell.
-                LastFormula* pLast = GetLastFormula(aScPos.Col());
-                if (pLast && pLast->mpCell && pLast->mnRow == (aScPos.Row()-1))
-                {
-                    ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, xGroup);
-
-                    if (!xGroup->mpTopCell && nSharedRow == aScPos.Row())
-                        // This formula group object is a duplicate of the
-                        // original one due to Excel's multi-column shared
-                        // range, and doesn't have the top cell assigned yet.
-                        // Assign the current cell as its top cell.
-                        xGroup->mpTopCell = pCell;
-
-                    if (xGroup->mpTopCell)
-                    {
-                        rDoc.getDoc().EnsureTable(aScPos.Tab());
-                        rDoc.setFormulaCell(aScPos, pCell);
-                        xGroup->mnLength = aScPos.Row() - xGroup->mpTopCell->aPos.Row() + 1;
-                        pCell->SetNeedNumberFormat(false);
-                        if (!rtl::math::isNan(fCurVal))
-                            pCell->SetResultDouble(fCurVal);
-
-                        GetXFRangeBuffer().SetXF(aScPos, nXF);
-                        SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
-                    }
-                    else
-                    {
-                        // No idea what's going on here...
-                        delete pCell;
-                    }
-                }
+                ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, *pSharedCode);
+                rDoc.getDoc().EnsureTable(aScPos.Tab());
+                rDoc.setFormulaCell(aScPos, pCell);
+                pCell->SetNeedNumberFormat(false);
+                if (!rtl::math::isNan(fCurVal))
+                    pCell->SetResultDouble(fCurVal);
+
+                GetXFRangeBuffer().SetXF(aScPos, nXF);
+                SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
             }
             else
             {
@@ -1736,10 +1714,9 @@ bool ExcelToSc::ReadSharedFormulaPosition( XclImpStream& rStrm, SCCOL& rCol, SCR
     return true;
 }
 
-ScFormulaCellGroupRef ExcelToSc::GetSharedFormula( const ScAddress& rRefPos )
+const ScTokenArray* ExcelToSc::GetSharedFormula( const ScAddress& rRefPos ) const
 {
-    ScFormulaCellGroupRef xGroup = GetOldRoot().pShrfmlaBuff->Find(rRefPos);
-    return xGroup;
+    return GetOldRoot().pShrfmlaBuff->Find(rRefPos);
 }
 
 void ExcelToSc::SetError( ScFormulaCell &rCell, const ConvErr eErr )
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index bda23cb..b60e62a 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -876,29 +876,22 @@ void ImportExcel::Shrfmla( void )
     SCCOL nCol2 = nLastCol;
     SCROW nRow1 = mpLastFormula->mnRow;
 
-    pExcRoot->pShrfmlaBuff->Store(
-        ScRange(nCol1, nRow1, GetCurrScTab(), nCol2, nRow1, GetCurrScTab()), *pErgebnis);
+    ScAddress aPos(nCol1, nRow1, GetCurrScTab());
+    pExcRoot->pShrfmlaBuff->Store(aPos, *pErgebnis);
 
     // Create formula cell for the last formula record.
 
-    ScAddress aPos(nCol1, nRow1, GetCurrScTab());
-    ScFormulaCellGroupRef xGroup = pExcRoot->pShrfmlaBuff->Find(aPos);
-    if (xGroup)
-    {
-        ScDocumentImport& rDoc = GetDocImport();
-        xGroup->compileCode(rDoc.getDoc(), aPos, formula::FormulaGrammar::GRAM_DEFAULT);
-
-        ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, xGroup);
-        xGroup->mpTopCell = pCell;
-        rDoc.getDoc().EnsureTable(aPos.Tab());
-        rDoc.setFormulaCell(aPos, pCell);
-        pCell->SetNeedNumberFormat(false);
-        if (!rtl::math::isNan(mpLastFormula->mfValue))
-            pCell->SetResultDouble(mpLastFormula->mfValue);
-
-        GetXFRangeBuffer().SetXF(aPos, mpLastFormula->mnXF);
-        mpLastFormula->mpCell = pCell;
-    }
+    ScDocumentImport& rDoc = GetDocImport();
+
+    ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis);
+    rDoc.getDoc().EnsureTable(aPos.Tab());
+    rDoc.setFormulaCell(aPos, pCell);
+    pCell->SetNeedNumberFormat(false);
+    if (!rtl::math::isNan(mpLastFormula->mfValue))
+        pCell->SetResultDouble(mpLastFormula->mfValue);
+
+    GetXFRangeBuffer().SetXF(aPos, mpLastFormula->mnXF);
+    mpLastFormula->mpCell = pCell;
 }
 
 
diff --git a/sc/source/filter/excel/namebuff.cxx b/sc/source/filter/excel/namebuff.cxx
index 1456c89..e369dee 100644
--- a/sc/source/filter/excel/namebuff.cxx
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -70,37 +70,32 @@ void NameBuffer::operator <<( const OUString &rNewString )
 
 SharedFormulaBuffer::SharedFormulaBuffer( RootData* pRD ) : ExcRoot(pRD) {}
 
-SharedFormulaBuffer::~SharedFormulaBuffer() {}
+SharedFormulaBuffer::~SharedFormulaBuffer()
+{
+    Clear();
+}
 
 void SharedFormulaBuffer::Clear()
 {
-    maFormulaGroups.clear();
+    TokenArraysType::iterator it = maTokenArrays.begin(), itEnd = maTokenArrays.end();
+    for (; it != itEnd; ++it)
+        delete it->second;
+
+    maTokenArrays.clear();
 }
 
-void SharedFormulaBuffer::Store( const ScRange& rRange, const ScTokenArray& rArray )
+void SharedFormulaBuffer::Store( const ScAddress& rPos, const ScTokenArray& rArray )
 {
-    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);
-        // We have no ScFormulaCell yet to point mpTopCell to!?
-        // Let's hope that the only called of this in ImportExcel::Shrfmla()
-        // fixes that up properly.
-        xNewGroup->mpTopCell = NULL;
-        xNewGroup->mnLength = 1;
-        xNewGroup->setCode(rArray);
-        maFormulaGroups.insert(FormulaGroupsType::value_type(aPos, xNewGroup));
-    }
+    ScTokenArray* pCode = rArray.Clone();
+    pCode->GenHash();
+    maTokenArrays.insert(TokenArraysType::value_type(rPos, pCode));
 }
 
-ScFormulaCellGroupRef SharedFormulaBuffer::Find( const ScAddress& rRefPos ) const
+const ScTokenArray* SharedFormulaBuffer::Find( const ScAddress& rRefPos ) const
 {
-    FormulaGroupsType::const_iterator it = maFormulaGroups.find(rRefPos);
-    if (it == maFormulaGroups.end())
-        return ScFormulaCellGroupRef();
+    TokenArraysType::const_iterator it = maTokenArrays.find(rRefPos);
+    if (it == maTokenArrays.end())
+        return NULL;
 
     return it->second;
 }
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
index 3d1d9c9..ed59df7 100644
--- a/sc/source/filter/inc/excform.hxx
+++ b/sc/source/filter/inc/excform.hxx
@@ -65,7 +65,7 @@ public:
     const ScTokenArray* GetBoolErr( XclBoolError );
 
     bool ReadSharedFormulaPosition( XclImpStream& rStrm, SCCOL& rCol, SCROW& rRow );
-    ScFormulaCellGroupRef GetSharedFormula( const ScAddress& rRefPos );
+    const ScTokenArray* GetSharedFormula( const ScAddress& rRefPos ) const;
 
     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 8c6c878..a4034f9 100644
--- a/sc/source/filter/inc/namebuff.hxx
+++ b/sc/source/filter/inc/namebuff.hxx
@@ -153,21 +153,17 @@ inline void NameBuffer::SetBase( sal_uInt16 nNewBase )
  */
 class SharedFormulaBuffer : public ExcRoot
 {
-    typedef boost::unordered_map<ScAddress, ScFormulaCellGroupRef, ScAddressHashFunctor> FormulaGroupsType;
-
-    FormulaGroupsType maFormulaGroups;
+    typedef boost::unordered_map<ScAddress, ScTokenArray*, ScAddressHashFunctor> TokenArraysType;
+    TokenArraysType maTokenArrays;
 
 public:
     SharedFormulaBuffer( RootData* pRD );
     virtual ~SharedFormulaBuffer();
     void Clear();
-    void Store( const ScRange& rRange, const ScTokenArray& rArray );
-    ScFormulaCellGroupRef Find( const ScAddress& rRefPos ) const;
+    void Store( const ScAddress& rPos, const ScTokenArray& rArray );
+    const ScTokenArray* Find( const ScAddress& rRefPos ) const;
 };
 
-
-
-
 class RangeNameBufferWK3
 {
 private:


More information about the Libreoffice-commits mailing list