diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-20 21:43:25 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-20 22:12:16 -0500 |
commit | 01e14bd403e749116844b6ab0b0a7afc66347e90 (patch) | |
tree | 25180d441c3a37b5fcbe22d0aca01f3545639bed /sc | |
parent | 061e80fb866d7d6b2a7348ed6eb1852835857ec4 (diff) |
Adjust InsertRow() for group area listeners.
Change-Id: I813b45d015eb1ae8dc7bd1242152ef734b5fe08c
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/column.hxx | 5 | ||||
-rw-r--r-- | sc/inc/document.hxx | 5 | ||||
-rw-r--r-- | sc/inc/table.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/column4.cxx | 70 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 26 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 29 | ||||
-rw-r--r-- | sc/source/core/data/table7.cxx | 19 |
7 files changed, 156 insertions, 4 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index da940248f672..7c6b2cd0d3b8 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -665,6 +665,11 @@ private: * column. */ std::vector<sc::FormulaGroupEntry> GetFormulaGroupEntries(); + + void EndListeningIntersectedGroups( + sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos = NULL ); + + void SetNeedsListeningGroup( SCROW nRow ); }; #endif diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index ee43f2c97b1a..fcb92dc2e3fd 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -2178,6 +2178,11 @@ private: bool ReservePatternCount( SCTAB nTab, SCCOL nCol, SCSIZE nReserve ); void SharePooledResources( ScDocument* pSrcDoc ); + + void EndListeningIntersectedGroups( + sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos = NULL ); + + void SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray ); }; #endif diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 04ebaa94d7d1..56af84199250 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -1109,6 +1109,12 @@ private: ScColumn* FetchColumn( SCCOL nCol ); const ScColumn* FetchColumn( SCCOL nCol ) const; + void EndListeningIntersectedGroups( + sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + std::vector<ScAddress>* pGroupPos = NULL ); + + void SetNeedsListeningGroup( SCCOL nCol, SCROW nRow ); + /** * Use this to iterate through non-empty visible cells in a single column. */ diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index ba6d01546f0e..43946e53503c 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -1357,4 +1357,74 @@ void ScColumn::EndListeningFormulaCells( *pEndRow = aFunc.getEndRow(); } +void ScColumn::EndListeningIntersectedGroups( + sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos ) +{ + // Only end the intersected group. + sc::CellStoreType::position_type aPos = maCells.position(nRow1); + sc::CellStoreType::iterator it = aPos.first; + if (it->type == sc::element_type_formula) + { + ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second); + ScFormulaCellGroupRef xGroup = pFC->GetCellGroup(); + if (xGroup && !pFC->IsSharedTop()) + { + // End listening. + pFC->EndListeningTo(rCxt); + if (pGroupPos) + // Record the position of the top cell of the group. + pGroupPos->push_back(xGroup->mpTopCell->aPos); + } + } + + aPos = maCells.position(it, nRow2); + it = aPos.first; + if (it->type == sc::element_type_formula) + { + ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second); + ScFormulaCellGroupRef xGroup = pFC->GetCellGroup(); + if (xGroup && !pFC->IsSharedTop()) + { + // End listening. + pFC->EndListeningTo(rCxt); + if (pGroupPos) + { + // Record the position of the bottom cell of the group. + ScAddress aPosLast = xGroup->mpTopCell->aPos; + aPosLast.IncRow(xGroup->mnLength-1); + pGroupPos->push_back(aPosLast); + } + } + } +} + +void ScColumn::SetNeedsListeningGroup( SCROW nRow ) +{ + sc::CellStoreType::position_type aPos = maCells.position(nRow); + if (aPos.first->type != sc::element_type_formula) + // not a formula cell. + return; + + ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second); + + ScFormulaCellGroupRef xGroup = (*pp)->GetCellGroup(); + if (!xGroup) + { + // not a formula group. + (*pp)->SetNeedsListening(true); + return; + } + + // Move back to the top cell. + SCROW nTopDelta = (*pp)->aPos.Row() - xGroup->mpTopCell->aPos.Row(); + for (SCROW i = 0; i < nTopDelta; ++i) + --pp; + + // Set the needs listening flag to all cells in the group. + assert(*pp == xGroup->mpTopCell); + ScFormulaCell** ppEnd = pp + xGroup->mnLength; + for (; pp != ppEnd; ++pp) + (*pp)->SetNeedsListening(true); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 9f9e45ee41ee..a4133883d104 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -1218,11 +1218,22 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab, SCTAB nTabRangeStart = nStartTab; SCTAB nTabRangeEnd = nEndTab; lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ); + ScRange aShiftedRange(nStartCol, nStartRow, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd); + sc::EndListeningContext aEndListenCxt(*this); + + std::vector<ScAddress> aGroupPos; do { - UpdateBroadcastAreas( URM_INSDEL, ScRange( - ScAddress( nStartCol, nStartRow, nTabRangeStart ), - ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, static_cast<SCsROW>(nSize), 0 ); + aShiftedRange.aStart.SetTab(nTabRangeStart); + aShiftedRange.aEnd.SetTab(nTabRangeEnd); + + // Collect all formula groups that will get split by the shifting, + // and end all their listening. Record the position of the top + // cell of the topmost group, and the postion of the bottom cell + // of the bottommost group. + EndListeningIntersectedGroups(aEndListenCxt, aShiftedRange, &aGroupPos); + + UpdateBroadcastAreas(URM_INSDEL, aShiftedRange, 0, static_cast<SCsROW>(nSize), 0); } while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) ); @@ -1230,14 +1241,21 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab, sc::RefUpdateContext aCxt(*this); aCxt.meMode = URM_INSDEL; - aCxt.maRange = ScRange(nStartCol, nStartRow, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd); + aCxt.maRange = aShiftedRange; aCxt.mnRowDelta = nSize; do { + aCxt.maRange.aStart.SetTab(nTabRangeStart); + aCxt.maRange.aEnd.SetTab(nTabRangeEnd); UpdateReference(aCxt, pRefUndoDoc, false); // without drawing objects } while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) ); + // UpdateReference should have set "needs listening" flags to those + // whose references have been modified. We also need to set this flag + // to those that were in the groups that got split by shifting. + SetNeedsListeningGroups(aGroupPos); + for (i=nStartTab; i<=nEndTab && i < static_cast<SCTAB>(maTabs.size()); i++) if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i))) maTabs[i]->InsertRow( nStartCol, nEndCol, nStartRow, nSize ); diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index 1f14d5dd16cd..c426a196cf56 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -355,4 +355,33 @@ bool ScDocument::HasFormulaCell( const ScRange& rRange ) const return false; } +void ScDocument::EndListeningIntersectedGroups( + sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos ) +{ + for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab) + { + ScTable* pTab = FetchTable(nTab); + if (!pTab) + continue; + + pTab->EndListeningIntersectedGroups( + rCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), + pGroupPos); + } +} + +void ScDocument::SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray ) +{ + std::vector<ScAddress>::const_iterator it = rPosArray.begin(), itEnd = rPosArray.end(); + for (; it != itEnd; ++it) + { + const ScAddress& rPos = *it; + ScTable* pTab = FetchTable(rPos.Tab()); + if (!pTab) + return; + + pTab->SetNeedsListeningGroup(rPos.Col(), rPos.Row()); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx index 79a645cbbf5e..f9e429a49f06 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -199,4 +199,23 @@ bool ScTable::HasFormulaCell( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 return false; } +void ScTable::EndListeningIntersectedGroups( + sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + std::vector<ScAddress>* pGroupPos ) +{ + if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2)) + return; + + for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + aCol[nCol].EndListeningIntersectedGroups(rCxt, nRow1, nRow2, pGroupPos); +} + +void ScTable::SetNeedsListeningGroup( SCCOL nCol, SCROW nRow ) +{ + if (!ValidCol(nCol)) + return; + + aCol[nCol].SetNeedsListeningGroup(nRow); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |