sc/inc/column.hxx | 3 ++ sc/inc/document.hxx | 3 ++ sc/inc/sharedformula.hxx | 5 ---- sc/inc/table.hxx | 3 ++ sc/source/core/data/column4.cxx | 34 ++++++++++++++++++++++++++++++ sc/source/core/data/document.cxx | 41 +++++++++++++++++++++++++++++-------- sc/source/core/data/document10.cxx | 10 +++++++++ sc/source/core/data/table7.cxx | 9 ++++++++ 8 files changed, 96 insertions(+), 12 deletions(-)
New commits: commit 4c93c341be1425401112eed3581e8b8a6308880d Author: Kohei Yoshida <[email protected]> Date: Thu Jan 15 20:49:36 2015 -0500 fdo#88398: Handle group listeners correctly when splitting formula group. It's basically the same thing we do in ScDocument::DeleteArea(), implemented in ScDocument::SetValue() and SetString(). Change-Id: Ifcae31aaef0e00ed8659aa5e2b9b8e206dc1a099 diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index f36f7fc..1911a95 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -704,6 +704,9 @@ private: */ std::vector<sc::FormulaGroupEntry> GetFormulaGroupEntries(); + void EndListeningIntersectedGroup( + sc::EndListeningContext& rCxt, SCROW nRow, std::vector<ScAddress>* pGroupPos = NULL ); + void EndListeningIntersectedGroups( sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos = NULL ); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index ddf427d..baf8c9c 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -2210,6 +2210,9 @@ private: void SharePooledResources( ScDocument* pSrcDoc ); + void EndListeningIntersectedGroup( + sc::EndListeningContext& rCxt, const ScAddress& rPos, std::vector<ScAddress>* pGroupPos = NULL ); + void EndListeningIntersectedGroups( sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos = NULL ); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 88a0461..3ad7162 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -1128,6 +1128,9 @@ private: ScColumn* FetchColumn( SCCOL nCol ); const ScColumn* FetchColumn( SCCOL nCol ) const; + void EndListeningIntersectedGroup( + sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, std::vector<ScAddress>* pGroupPos = NULL ); + void EndListeningIntersectedGroups( sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, std::vector<ScAddress>* pGroupPos = NULL ); diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index c46634c..b997948 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -1382,6 +1382,40 @@ void ScColumn::EndListeningFormulaCells( *pEndRow = aFunc.getEndRow(); } +void ScColumn::EndListeningIntersectedGroup( + sc::EndListeningContext& rCxt, SCROW nRow, std::vector<ScAddress>* pGroupPos ) +{ + if (!ValidRow(nRow)) + return; + + sc::CellStoreType::position_type aPos = maCells.position(nRow); + sc::CellStoreType::iterator it = aPos.first; + if (it->type != sc::element_type_formula) + // Only interested in a formula block. + return; + + ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second); + ScFormulaCellGroupRef xGroup = pFC->GetCellGroup(); + if (!xGroup) + // Not a formula group. + return; + + // End listening. + pFC->EndListeningTo(rCxt); + + if (pGroupPos) + { + if (!pFC->IsSharedTop()) + // Record the position of the top cell of the group. + pGroupPos->push_back(xGroup->mpTopCell->aPos); + + SCROW nGrpLastRow = pFC->GetSharedTopRow() + pFC->GetSharedLength() - 1; + if (nRow < nGrpLastRow) + // Record the last position of the group. + pGroupPos->push_back(ScAddress(nCol, nGrpLastRow, nTab)); + } +} + void ScColumn::EndListeningIntersectedGroups( sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos ) { diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 43117b0..ccbaf00 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -3212,10 +3212,25 @@ void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark, bool ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString, ScSetStringParam* pParam ) { - if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] ) - return maTabs[nTab]->SetString( nCol, nRow, nTab, rString, pParam ); - else + ScTable* pTab = FetchTable(nTab); + if (!pTab) return false; + + // In case setting this string affects an existing formula group, record + // its above and below position for later listening. + + std::vector<ScAddress> aGroupPos; + sc::EndListeningContext aCxt(*this); + ScAddress aPos(nCol, nRow, nTab); + EndListeningIntersectedGroup(aCxt, aPos, &aGroupPos); + aCxt.purgeEmptyBroadcasters(); + + bool bNumFmtSet = pTab->SetString(nCol, nRow, nTab, rString, pParam); + + SetNeedsListeningGroups(aGroupPos); + StartNeededListeners(); + + return bNumFmtSet; } bool ScDocument::SetString( @@ -3291,17 +3306,27 @@ void ScDocument::SetEmptyCell( const ScAddress& rPos ) void ScDocument::SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal ) { - if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size())) - if (maTabs[nTab]) - maTabs[nTab]->SetValue( nCol, nRow, rVal ); + SetValue(ScAddress(nCol, nRow, nTab), rVal); } void ScDocument::SetValue( const ScAddress& rPos, double fVal ) { - if (!TableExists(rPos.Tab())) + ScTable* pTab = FetchTable(rPos.Tab()); + if (!pTab) return; - maTabs[rPos.Tab()]->SetValue(rPos.Col(), rPos.Row(), fVal); + // In case setting this string affects an existing formula group, record + // its above and below position for later listening. + + std::vector<ScAddress> aGroupPos; + sc::EndListeningContext aCxt(*this); + EndListeningIntersectedGroup(aCxt, rPos, &aGroupPos); + aCxt.purgeEmptyBroadcasters(); + + pTab->SetValue(rPos.Col(), rPos.Row(), fVal); + + SetNeedsListeningGroups(aGroupPos); + StartNeededListeners(); } OUString ScDocument::GetString( SCCOL nCol, SCROW nRow, SCTAB nTab ) const diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index 06ab0b9..0a2e3cb 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -361,6 +361,16 @@ bool ScDocument::HasFormulaCell( const ScRange& rRange ) const return false; } +void ScDocument::EndListeningIntersectedGroup( + sc::EndListeningContext& rCxt, const ScAddress& rPos, std::vector<ScAddress>* pGroupPos ) +{ + ScTable* pTab = FetchTable(rPos.Tab()); + if (!pTab) + return; + + pTab->EndListeningIntersectedGroup(rCxt, rPos.Col(), rPos.Row(), pGroupPos); +} + void ScDocument::EndListeningIntersectedGroups( sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos ) { diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx index 2740735..f940ee5 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -199,6 +199,15 @@ bool ScTable::HasFormulaCell( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 return false; } +void ScTable::EndListeningIntersectedGroup( + sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, std::vector<ScAddress>* pGroupPos ) +{ + if (!ValidCol(nCol)) + return; + + aCol[nCol].EndListeningIntersectedGroup(rCxt, nRow, pGroupPos); +} + void ScTable::EndListeningIntersectedGroups( sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, std::vector<ScAddress>* pGroupPos ) commit ed33b94930c42968ab047602a07e5aa5eda3b99c Author: Kohei Yoshida <[email protected]> Date: Thu Jan 15 20:38:42 2015 -0500 fdo#88398: Re-enable formula group listeners. Change-Id: I1e5e9d50af471bc0e63f0d39478d96bf479583d5 diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx index 9101402..e4b25bb 100644 --- a/sc/inc/sharedformula.hxx +++ b/sc/inc/sharedformula.hxx @@ -15,10 +15,7 @@ #include <vector> -/* TODO: before this can be activated further implementation is needed to - * re-establish the area listeners in case of unshare/split/join that currently - * would get discarded. */ -#define USE_FORMULA_GROUP_LISTENER 0 +#define USE_FORMULA_GROUP_LISTENER 1 namespace sc { _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
