[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:44:44 PDT 2013
include/svl/sharedstring.hxx | 2 +
sc/inc/document.hxx | 2 -
sc/source/core/data/column2.cxx | 7 +++++
sc/source/core/data/column3.cxx | 1
sc/source/filter/ftools/sharedformulagroups.cxx | 17 +++++++++++--
sc/source/filter/inc/sharedformulagroups.hxx | 8 +++++-
sc/source/filter/oox/formulabuffer.cxx | 30 ++++--------------------
svl/source/misc/sharedstring.cxx | 5 ++++
8 files changed, 41 insertions(+), 31 deletions(-)
New commits:
commit a9f860c5b50c09abdaeb7123d5f5e40f3c709dac
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..a4e3b7b 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);
}
}
@@ -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