[ooo-build-commit] .: patches/dev300
Kohei Yoshida
kohei at kemper.freedesktop.org
Thu Feb 11 10:25:28 PST 2010
patches/dev300/apply | 3
patches/dev300/calc-subtotal-function-update.diff | 161 ++++++++++++++++++++++
2 files changed, 164 insertions(+)
New commits:
commit 5c9ee5cb31ebb1c012ef170fc90baa7fa58f3725
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Thu Feb 11 13:24:00 2010 -0500
Keep track of cells containing SUBTOTAL functions for updates.
* patches/dev300/apply:
* patches/dev300/calc-subtotal-function-update.diff: let's not mark
the filtered ranges dirty when filtering, which may cause stack
overflow due to too much recursion. Instead, only mark the
affected cells with SUBTOTAL functions dirty in order to force
re-calculation of SUBTOTAL values after filtering. (n#578802)
diff --git a/patches/dev300/apply b/patches/dev300/apply
index cc6065c..694392f 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3531,6 +3531,9 @@ calc-english-func-names-sc.diff, i#38765, kohei
calc-english-func-names-formula.diff, i#38765, kohei
calc-english-func-names-officecfg.diff, i#38765, kohei
+# Keep track of cells with SUBTOTAL functions the right way.
+calc-subtotal-function-update.diff, n#578802, kohei
+
[ NovellEvaluation ]
# enable the Subscription menu
novell-subscription-enable-in-menu.diff
diff --git a/patches/dev300/calc-subtotal-function-update.diff b/patches/dev300/calc-subtotal-function-update.diff
new file mode 100644
index 0000000..1bfe57d
--- /dev/null
+++ b/patches/dev300/calc-subtotal-function-update.diff
@@ -0,0 +1,161 @@
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index 82b1582..237e3f8 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -436,6 +436,7 @@ private:
+
+ // for worksheet calculate event
+ ::std::vector< SCTAB > maTabs;
++ ::std::set<ScFormulaCell*> maSubTotalCells;
+
+ public:
+ SC_DLLPUBLIC ULONG GetCellCount() const; // alle Zellen
+@@ -1783,6 +1784,11 @@ public:
+ { return eStorageGrammar; }
+
+ SfxUndoManager* GetUndoManager();
++
++ void AddSubTotalCell(ScFormulaCell* pCell);
++ void RemoveSubTotalCell(ScFormulaCell* pCell);
++ void SetSubTotalCellsDirty(const ScRange& rDirtyRange);
++
+ private: // CLOOK-Impl-Methoden
+
+ /**
+diff --git sc/source/core/data/cell.cxx sc/source/core/data/cell.cxx
+index 7643365..312ad38 100644
+--- sc/source/core/data/cell.cxx
++++ sc/source/core/data/cell.cxx
+@@ -728,6 +728,9 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
+ if ( pCode->GetNextOpCodeRPN( ocSubTotal ) )
+ bSubTotal = TRUE;
+ }
++
++ if (bSubTotal)
++ pDocument->AddSubTotalCell(this);
+ }
+
+ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags ) :
+@@ -818,11 +821,15 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
+
+ if( nCloneFlags & SC_CLONECELL_STARTLISTENING )
+ StartListeningTo( &rDoc );
++
++ if (bSubTotal)
++ pDocument->AddSubTotalCell(this);
+ }
+
+ ScFormulaCell::~ScFormulaCell()
+ {
+ pDocument->RemoveFromFormulaTree( this );
++ pDocument->RemoveSubTotalCell(this);
+ if (pCode->HasOpCode(ocMacro))
+ pDocument->GetMacroManager()->RemoveDependentCell(this);
+
+@@ -988,6 +995,9 @@ void ScFormulaCell::CompileTokenArray( BOOL bNoListening )
+ }
+ if ( bWasInFormulaTree )
+ pDocument->PutInFormulaTree( this );
++
++ if (bSubTotal)
++ pDocument->AddSubTotalCell(this);
+ }
+ }
+
+@@ -1031,6 +1041,9 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
+ bCompile = FALSE;
+ StartListeningTo( pDocument );
+ }
++
++ if (bSubTotal)
++ pDocument->AddSubTotalCell(this);
+ }
+ else
+ {
+@@ -1070,6 +1083,9 @@ void ScFormulaCell::CalcAfterLoad()
+ bDirty = TRUE;
+ bCompile = FALSE;
+ bNewCompiled = TRUE;
++
++ if (bSubTotal)
++ pDocument->AddSubTotalCell(this);
+ }
+ // irgendwie koennen unter os/2 mit rotter FPU-Exception /0 ohne Err503
+ // gespeichert werden, woraufhin spaeter im NumberFormatter die BLC Lib
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 40df826..148648f 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -5245,6 +5245,54 @@ SfxUndoManager* ScDocument::GetUndoManager()
+ return mpUndoManager;
+ }
+
++void ScDocument::AddSubTotalCell(ScFormulaCell* pCell)
++{
++ maSubTotalCells.insert(pCell);
++}
++
++void ScDocument::RemoveSubTotalCell(ScFormulaCell* pCell)
++{
++ maSubTotalCells.erase(pCell);
++}
++
++namespace {
++
++bool lcl_hasDirtyRange(ScFormulaCell* pCell, const ScRange& rDirtyRange)
++{
++ ScDetectiveRefIter aRefIter(pCell);
++ ScRange aRange;
++ while (aRefIter.GetNextRef(aRange))
++ {
++ if (aRange.Intersects(rDirtyRange))
++ return true;
++ }
++ return false;
++}
++
++}
++
++void ScDocument::SetSubTotalCellsDirty(const ScRange& rDirtyRange)
++{
++ // to update the list by skipping cells that no longer contain subtotal function.
++ set<ScFormulaCell*> aNewSet;
++
++ bool bOldRecalc = GetAutoCalc();
++ SetAutoCalc(false);
++ set<ScFormulaCell*>::iterator itr = maSubTotalCells.begin(), itrEnd = maSubTotalCells.end();
++ for (; itr != itrEnd; ++itr)
++ {
++ ScFormulaCell* pCell = *itr;
++ if (pCell->IsSubTotal())
++ {
++ aNewSet.insert(pCell);
++ if (lcl_hasDirtyRange(pCell, rDirtyRange))
++ pCell->SetDirty();
++ }
++ }
++
++ SetAutoCalc(bOldRecalc);
++ maSubTotalCells.swap(aNewSet); // update the list.
++}
+
+ void ScDocument::EnableUndo( bool bVal )
+ {
+diff --git sc/source/ui/docshell/dbdocfun.cxx sc/source/ui/docshell/dbdocfun.cxx
+index 4180060..5e90946 100644
+--- sc/source/ui/docshell/dbdocfun.cxx
++++ sc/source/ui/docshell/dbdocfun.cxx
+@@ -944,10 +944,9 @@ BOOL ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam,
+ pDoc->UpdatePageBreaks( nTab );
+ }
+
+- // #i23299# because of Subtotal functions, the whole rows must be set dirty
+- ScRange aDirtyRange( 0 , aLocalParam.nRow1, nDestTab,
+- MAXCOL, aLocalParam.nRow2, nDestTab );
+- pDoc->SetDirty( aDirtyRange );
++ // #i23299# Subtotal functions depend on cell's filtered states.
++ ScRange aDirtyRange(0 , aLocalParam.nRow1, nDestTab, MAXCOL, aLocalParam.nRow2, nDestTab);
++ pDoc->SetSubTotalCellsDirty(aDirtyRange);
+
+ if ( bRecord )
+ {
More information about the ooo-build-commit
mailing list