summaryrefslogtreecommitdiff
path: root/sc/source/core/data
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2015-01-15 20:49:36 -0500
committerEike Rathke <erack@redhat.com>2015-01-16 18:13:16 +0000
commit6240e598f29ee5e95c56e5885f539ce470d9afd6 (patch)
tree797784b2e40ac469ca9c0f1bd6a193ad28e1f69d /sc/source/core/data
parentc52c20a9fbb9a1a75e57ac0ca08d057f4266e12c (diff)
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 (cherry picked from commit 4c93c341be1425401112eed3581e8b8a6308880d) Reviewed-on: https://gerrit.libreoffice.org/13946 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc/source/core/data')
-rw-r--r--sc/source/core/data/column4.cxx34
-rw-r--r--sc/source/core/data/document.cxx41
-rw-r--r--sc/source/core/data/document10.cxx10
-rw-r--r--sc/source/core/data/table7.cxx9
4 files changed, 86 insertions, 8 deletions
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 23862965ad59..19e3b14f4e98 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 58ade9cf72c1..b9307c11dc54 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3200,10 +3200,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(
@@ -3279,17 +3294,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 06ab0b98bf28..0a2e3cbfd6b6 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 274073508aea..f940ee5c332e 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 )