summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-08-14 12:34:20 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-08-14 19:25:42 -0400
commit5dd2e45e65641134309265db30c9d5f304d0a583 (patch)
tree196c80fb7ae82a85b18d19b56a4f3d13fb3a8ea7 /sc
parent25763e59625ce83de4b82927359108f9e7878744 (diff)
Avoid wholesale rebuilding of formula groups at re-calc time.
And do it once when importing xls, xlsx, and ods documents. Although xls(x) file formats support shared formula natively, it's still beneficial to re-group it as some old xls documents limit the length of shared formula span to only 64, or some don't use shared formulas at all even though they could. And re-grouping just once is not terribly expensive. Change-Id: Iff9c605d19baa187553ddab6af8b9fbd4c366d7d
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/column.hxx1
-rw-r--r--sc/inc/document.hxx15
-rw-r--r--sc/qa/unit/filters-test.cxx9
-rw-r--r--sc/source/core/data/column3.cxx11
-rw-r--r--sc/source/core/data/documentimport.cxx1
-rw-r--r--sc/source/core/data/formulacell.cxx4
-rw-r--r--sc/source/core/data/table6.cxx2
-rw-r--r--sc/source/filter/excel/excform.cxx7
-rw-r--r--sc/source/filter/excel/read.cxx2
-rw-r--r--sc/source/filter/oox/workbookhelper.cxx1
10 files changed, 31 insertions, 22 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 14d0bfee12fd..49cc24aa8f38 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -163,7 +163,6 @@ public:
void FreeAll();
void SwapRow( SCROW nRow1, SCROW nRow2 );
void SwapCell( SCROW nRow, ScColumn& rCol);
- void RebuildFormulaGroups();
bool HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const;
bool HasAttribSelection( const ScMarkData& rMark, sal_uInt16 nMask ) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 8b82fb77aa04..c74c6c8349d3 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -798,12 +798,23 @@ public:
formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_DEFAULT );
/**
- * Takes ownership of pCell
+ * Set formula cell, and transfer its ownership to the document. This call
+ * attempts to group the passed formula cell with the adjacent cells or
+ * cell groups if appropriate.
*
* @return pCell if it was successfully inserted, NULL otherwise. pCell
* is deleted automatically on failure to insert.
*/
SC_DLLPUBLIC ScFormulaCell* SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
+
+ /**
+ * Set formula cell, and transfer its ownership to the document. Unlike
+ * SetFormulaCell(), this call will <i>not</i> attempt to group the passed
+ * formula cell with the adjacent cells or cell groups.
+ *
+ * @return true if the cell is inserted, false otherwise. The caller
+ * should delete the cell instance if the method returns false.
+ */
SC_DLLPUBLIC bool SetGroupFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
SC_DLLPUBLIC void InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
@@ -1801,7 +1812,7 @@ public:
SC_DLLPUBLIC void CalcFormulaTree(
bool bOnlyForced = false, bool bProgressBar = true, bool bSetAllDirty = true );
void ClearFormulaTree();
- void RebuildFormulaGroups();
+ SC_DLLPUBLIC void RebuildFormulaGroups();
void AppendToFormulaTrack( ScFormulaCell* pCell );
void RemoveFromFormulaTrack( ScFormulaCell* pCell );
void TrackFormulas( sal_uLong nHintId = SC_HINT_DATACHANGED );
diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx
index 957e0e005894..deb1571dd4cf 100644
--- a/sc/qa/unit/filters-test.cxx
+++ b/sc/qa/unit/filters-test.cxx
@@ -351,7 +351,7 @@ void ScFiltersTest::testSharedFormulaXLS()
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);
+ CPPUNIT_ASSERT_MESSAGE("Incorrect group geometry.", xGroup->mnStart == 1 && xGroup->mnLength == 18);
xDocSh->DoClose();
}
@@ -369,6 +369,13 @@ void ScFiltersTest::testSharedFormulaXLSX()
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 == 1 && xGroup->mnLength == 18);
+
xDocSh->DoClose();
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 0ac06e7e4726..b452b68b17ed 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2742,17 +2742,6 @@ public:
}
-// Very[!] slow way to look for and merge contiguous runs
-// of similar formulae into a formulagroup
-void ScColumn::RebuildFormulaGroups()
-{
- if (!mbDirtyGroups)
- return;
-
- RegroupFormulaCells();
- mbDirtyGroups = false;
-}
-
void ScColumn::RegroupFormulaCells()
{
// re-build formula groups.
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 1c368b404d45..d3dd4dbcb97b 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -353,6 +353,7 @@ void ScDocumentImport::initColumn(ScColumn& rCol)
CellTextAttrInitializer aFunc(mpImpl->mnDefaultScriptNumeric);
std::for_each(rCol.maCells.begin(), rCol.maCells.end(), aFunc);
aFunc.swap(rCol.maCellTextAttrs);
+ rCol.RegroupFormulaCells();
rCol.CellStorageModified();
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index f40e5a53bde5..a7491a224ffb 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3510,10 +3510,6 @@ bool ScFormulaCell::InterpretFormulaGroup()
if (!ScInterpreter::GetGlobalConfig().mbOpenCLEnabled)
return false;
- // Re-build formulae groups if necessary - ideally this is done at
- // import / insert / delete etc. and is integral to the data structures
- pDocument->RebuildFormulaGroups();
-
if (!mxGroup || !pCode)
return false;
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index 540eb55dc17b..3f23fa0c0500 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -1029,7 +1029,7 @@ bool ScTable::SearchRangeForAllEmptyCells(
void ScTable::RebuildFormulaGroups()
{
for (SCCOL i=0; i<=MAXCOL; i++)
- aCol[i].RebuildFormulaGroups();
+ aCol[i].RegroupFormulaCells();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index e9f5cf626327..56a18f8f81d4 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -146,7 +146,12 @@ void ImportExcel::Formula(
{
pCell = new ScFormulaCell( pD, aScPos, pResult );
pD->EnsureTable(aScPos.Tab());
- pCell = pD->SetFormulaCell(aScPos, pCell);
+ bool bInserted = pD->SetGroupFormulaCell(aScPos, pCell);
+ if (!bInserted)
+ {
+ delete pCell;
+ return;
+ }
}
else
{
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index 9c4c5e77b334..01629f53930a 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -1278,13 +1278,13 @@ FltError ImportExcel8::Read( void )
break;
}
}
-
}
// #i45843# Convert pivot tables before calculation, so they are available
// for the GETPIVOTDATA function.
if( GetBiff() == EXC_BIFF8 )
GetPivotTableManager().ConvertPivotTables();
+ pD->RebuildFormulaGroups();
pProgress.reset();
#if 0
// Excel documents look much better without this call; better in the
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 8802389372c1..dbdf45dc3054 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -636,6 +636,7 @@ void WorkbookGlobals::finalize()
//stop preventing establishment of listeners as is done in
//ScDocShell::AfterXMLLoading() for ods
getScDocument().SetInsertingFromOtherDoc(false);
+ getScDocument().RebuildFormulaGroups();
}
}