[Libreoffice-commits] core.git: Branch 'private/kohei/calc-shared-string' - include/svl sc/inc sc/source svl/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Oct 9 12:50:16 PDT 2013


Rebased ref, commits from common ancestor:
commit 8600e123089d50ab21b64efa6340f588f07f6b7e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Oct 9 15:44:59 2013 -0400

    Import shared formulas from xlsx without crashing.
    
    The key here is to only use the shared formula ID's and ignore the ref
    range. The ref ranges are not correct half the time.
    
    Change-Id: If65f9b1b44ab6239db37977b6dfe3f822a9cf67e

diff --git a/include/svl/sharedstring.hxx b/include/svl/sharedstring.hxx
index 183dc43..a3650a5 100644
--- a/include/svl/sharedstring.hxx
+++ b/include/svl/sharedstring.hxx
@@ -41,6 +41,8 @@ public:
 
     bool isValid() const;
     bool isEmpty() const;
+
+    sal_Int32 getLength() const;
 };
 
 }
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 076982c..c378a26 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -2014,7 +2014,7 @@ public:
     bool HasBroadcaster( SCTAB nTab, SCCOL nCol ) const;
 
 #if DEBUG_COLUMN_STORAGE
-    void DumpFormulaGroups( SCTAB nTab, SCCOL nCol ) const;
+    SC_DLLPUBLIC void DumpFormulaGroups( SCTAB nTab, SCCOL nCol ) const;
 #endif
 
 private: // CLOOK-Impl-methods
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index ec3d475..f66bd90 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1527,6 +1527,7 @@ struct FormulaGroupDumper : std::unary_function<sc::CellStoreType::value_type, v
         if (rNode.type != sc::element_type_formula)
             return;
 
+        cout << "  -- formula block" << endl;
         sc::formula_block::const_iterator it = sc::formula_block::begin(*rNode.data);
         sc::formula_block::const_iterator itEnd = sc::formula_block::end(*rNode.data);
 
@@ -1534,10 +1535,16 @@ struct FormulaGroupDumper : std::unary_function<sc::CellStoreType::value_type, v
         {
             const ScFormulaCell& rCell = **it;
             if (!rCell.IsShared())
+            {
+                cout << "  + row " << rCell.aPos.Row() << " not shared" << endl;
                 continue;
+            }
 
             if (rCell.GetSharedTopRow() != rCell.aPos.Row())
+            {
+                cout << "  + row " << rCell.aPos.Row() << " shared with top row " << rCell.GetSharedTopRow() << " with length " << rCell.GetSharedLength() << endl;
                 continue;
+            }
 
             SCROW nLen = rCell.GetSharedLength();
             cout << "  * group: start=" << rCell.aPos.Row() << ", length=" << nLen << endl;
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ae84c13..c34fa17 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2702,7 +2702,6 @@ public:
             if (eCompState == ScFormulaCell::NotEqual)
             {
                 // different formula tokens.
-                pCur->SetCellGroup(mxNone);
                 if (xCurGrp)
                 {
                     // Move to the cell after the last cell of the current group.
diff --git a/sc/source/filter/ftools/sharedformulagroups.cxx b/sc/source/filter/ftools/sharedformulagroups.cxx
index 77da587..b80bdb5 100644
--- a/sc/source/filter/ftools/sharedformulagroups.cxx
+++ b/sc/source/filter/ftools/sharedformulagroups.cxx
@@ -31,17 +31,28 @@ size_t SharedFormulaGroups::KeyHash::operator ()( const Key& rKey ) const
     return static_cast<size_t>(nVal);
 }
 
+void SharedFormulaGroups::set( size_t nSharedId, ScTokenArray* pArray )
+{
+    maStore.insert(nSharedId, pArray);
+}
+
 void SharedFormulaGroups::set( size_t nSharedId, SCCOL nCol, const ScFormulaCellGroupRef& xGroup )
 {
     Key aKey(nSharedId, nCol);
-    maStore.insert(StoreType::value_type(aKey, xGroup));
+    maColStore.insert(ColStoreType::value_type(aKey, xGroup));
+}
+
+const ScTokenArray* SharedFormulaGroups::get( size_t nSharedId ) const
+{
+    StoreType::const_iterator it = maStore.find(nSharedId);
+    return it == maStore.end() ? NULL : it->second;
 }
 
 ScFormulaCellGroupRef SharedFormulaGroups::get( size_t nSharedId, SCCOL nCol ) const
 {
     Key aKey(nSharedId, nCol);
-    StoreType::const_iterator it = maStore.find(aKey);
-    return it == maStore.end() ? ScFormulaCellGroupRef() : it->second;
+    ColStoreType::const_iterator it = maColStore.find(aKey);
+    return it == maColStore.end() ? ScFormulaCellGroupRef() : it->second;
 }
 
 }
diff --git a/sc/source/filter/inc/sharedformulagroups.hxx b/sc/source/filter/inc/sharedformulagroups.hxx
index c6058fc..0bd9484 100644
--- a/sc/source/filter/inc/sharedformulagroups.hxx
+++ b/sc/source/filter/inc/sharedformulagroups.hxx
@@ -12,7 +12,9 @@
 
 #include "address.hxx"
 #include "formulacell.hxx"
+#include "tokenarray.hxx"
 
+#include <boost/ptr_container/ptr_map.hpp>
 #include <boost/unordered_map.hpp>
 
 namespace sc {
@@ -35,11 +37,15 @@ class SharedFormulaGroups
         size_t operator() ( const Key& rKey ) const;
     };
 
-    typedef boost::unordered_map<Key, ScFormulaCellGroupRef, KeyHash> StoreType;
+    typedef boost::ptr_map<size_t, ScTokenArray> StoreType;
+    typedef boost::unordered_map<Key, ScFormulaCellGroupRef, KeyHash> ColStoreType;
+    ColStoreType maColStore;
     StoreType maStore;
 public:
 
+    void set( size_t nSharedId, ScTokenArray* pArray );
     void set( size_t nSharedId, SCCOL nCol, const ScFormulaCellGroupRef& xGroup );
+    const ScTokenArray* get( size_t nSharedId ) const;
     ScFormulaCellGroupRef get( size_t nSharedId, SCCOL nCol ) const;
 };
 
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 21e383f..2d0694f 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -94,7 +94,7 @@ void FormulaBuffer::applyCellFormula( ScDocument& rDoc, const ApiTokenSequence&
     ScFormulaCell* pNewCell = new ScFormulaCell( &rDoc, aCellPos, &aTokenArray );
     pNewCell->StartListeningTo( &rDoc );
     rDoc.EnsureTable(aCellPos.Tab());
-    rDoc.SetFormulaCell(aCellPos, pNewCell);
+    rDoc.SetGroupFormulaCell(aCellPos, pNewCell);
 }
 
 void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
@@ -149,7 +149,6 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
         for (; it != itEnd; ++it)
         {
             const table::CellAddress& rAddr = it->maAddress;
-            const table::CellRangeAddress& rRange = it->maRange;
             sal_Int32 nId = it->mnSharedId;
             const OUString& rTokenStr = it->maTokenStr;
 
@@ -159,18 +158,7 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
             aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
             ScTokenArray* pArray = aComp.CompileString(rTokenStr);
             if (pArray)
-            {
-                for (sal_Int32 nCol = rRange.StartColumn; nCol <= rRange.EndColumn; ++nCol)
-                {
-                    // Create one group per column, since Calc doesn't support
-                    // shared formulas across multiple columns.
-                    ScFormulaCellGroupRef xNewGroup(new ScFormulaCellGroup);
-                    xNewGroup->mnStart = rRange.StartRow;
-                    xNewGroup->mnLength = 1; // Length gets updated as we go.
-                    xNewGroup->setCode(*pArray);
-                    aGroups.set(nId, nCol, xNewGroup);
-                }
-            }
+                aGroups.set(nId, pArray->Clone());
         }
     }
 
@@ -180,18 +168,13 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
         for (; it != itEnd; ++it)
         {
             const table::CellAddress& rAddr = it->maAddress;
-
-            ScFormulaCellGroupRef xGroup = aGroups.get(it->mnSharedId, rAddr.Column);
-            if (!xGroup)
+            const ScTokenArray* pArray = aGroups.get(it->mnSharedId);
+            if (!pArray)
                 continue;
 
             ScAddress aPos;
             ScUnoConversion::FillScAddress(aPos, rAddr);
-            if (xGroup->mnStart == aPos.Row())
-                // Generate code for the top cell only.
-                xGroup->compileCode(rDoc, aPos, formula::FormulaGrammar::GRAM_DEFAULT);
-            ScFormulaCell* pCell = new ScFormulaCell(&rDoc, aPos, xGroup);
-
+            ScFormulaCell* pCell = new ScFormulaCell(&rDoc, aPos, pArray);
             bool bInserted = rDoc.SetGroupFormulaCell(aPos, pCell);
             if (!bInserted)
             {
@@ -200,9 +183,6 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
                 continue;
             }
 
-            // Update the length of shared formula span as we go. The length
-            // that Excel gives is not always correct.
-            xGroup->mnLength = aPos.Row() - xGroup->mnStart + 1;
             pCell->StartListeningTo(&rDoc);
 
             if (it->maCellValue.isEmpty())
diff --git a/svl/source/misc/sharedstring.cxx b/svl/source/misc/sharedstring.cxx
index 9c0cad2f..0438421 100644
--- a/svl/source/misc/sharedstring.cxx
+++ b/svl/source/misc/sharedstring.cxx
@@ -118,6 +118,11 @@ bool SharedString::isEmpty() const
     return mpData == NULL || mpData->length == 0;
 }
 
+sal_Int32 SharedString::getLength() const
+{
+    return mpData ? mpData->length : 0;
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list