From c4d26f327605b77c8395bdb512d8ddcd8c11bfd1 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Tue, 13 Aug 2013 22:53:14 -0400 Subject: Regroup formula cells later in columns where references are updated. Change-Id: I4dd6ade18e72d8f57583180463f9dda3603be4c2 --- sc/source/core/data/column.cxx | 5 ++- sc/source/core/data/columnset.cxx | 66 +++++++++++++++++++++++++++++++++++++++ sc/source/core/data/document.cxx | 12 +++---- sc/source/core/data/table2.cxx | 26 ++++++++++++--- 4 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 sc/source/core/data/columnset.cxx (limited to 'sc/source/core') diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index e4ad8c71b22b..d8c3e6084146 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -2359,7 +2359,7 @@ bool ScColumn::UpdateReferenceOnCopy( const sc::RefUpdateContext& rCxt, ScDocume return aHandler.isUpdated(); } -bool ScColumn::UpdateReference( const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc ) +bool ScColumn::UpdateReference( sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc ) { if (rCxt.meMode == URM_COPY) return UpdateReferenceOnCopy(rCxt, pUndoDoc); @@ -2396,6 +2396,9 @@ bool ScColumn::UpdateReference( const sc::RefUpdateContext& rCxt, ScDocument* pU UpdateRefOnNonCopy aHandler(nCol, nTab, rCxt, pUndoDoc); sc::ProcessFormula(maCells, aHandler); + if (aHandler.isUpdated()) + rCxt.maRegroupCols.set(nTab, nCol); + return aHandler.isUpdated(); } diff --git a/sc/source/core/data/columnset.cxx b/sc/source/core/data/columnset.cxx new file mode 100644 index 000000000000..2e1f3aa956e4 --- /dev/null +++ b/sc/source/core/data/columnset.cxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "columnset.hxx" + +namespace sc { + +void ColumnSet::set(SCTAB nTab, SCCOL nCol) +{ + TabsType::iterator itTab = maTabs.find(nTab); + if (itTab == maTabs.end()) + { + std::pair r = + maTabs.insert(TabsType::value_type(nTab, ColsType())); + + if (!r.second) + // insertion failed. + return; + + itTab = r.first; + } + + ColsType& rCols = itTab->second; + rCols.insert(nCol); +} + +bool ColumnSet::has(SCTAB nTab, SCCOL nCol) const +{ + TabsType::const_iterator itTab = maTabs.find(nTab); + if (itTab == maTabs.end()) + return false; + + const ColsType& rCols = itTab->second; + return rCols.count(nCol) > 0; +} + +void ColumnSet::getColumns(SCTAB nTab, std::vector& rCols) const +{ + std::vector aCols; + TabsType::const_iterator itTab = maTabs.find(nTab); + if (itTab == maTabs.end()) + { + rCols.swap(aCols); // empty it. + return; + } + + const ColsType& rTabCols = itTab->second; + aCols.assign(rTabCols.begin(), rTabCols.end()); + + // Sort and remove duplicates. + std::sort(aCols.begin(), aCols.end()); + std::vector::iterator itCol = std::unique(aCols.begin(), aCols.end()); + aCols.erase(itCol, aCols.end()); + + rCols.swap(aCols); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index a6eb5ef4846c..9fdf84ac46cb 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -1474,8 +1474,7 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA nEndTab = static_cast(maTabs.size())-1; } - bool bOldAutoCalc = GetAutoCalc(); - SetAutoCalc( false ); // avoid multiple calculations + sc::AutoCalcSwitch aACSwitch(*this, false); // avoid multiple calculations // handle chunks of consecutive selected sheets together SCTAB nTabRangeStart = nStartTab; @@ -1499,10 +1498,10 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA } while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast(maTabs.size()) ) ); + sc::RefUpdateContext aCxt(*this); if ( ValidCol(sal::static_int_cast(nStartCol+nSize)) ) { lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast(maTabs.size()) ); - sc::RefUpdateContext aCxt(*this); aCxt.meMode = URM_INSDEL; aCxt.maRange = ScRange(sal::static_int_cast(nStartCol+nSize), nStartRow, nTabRangeStart, MAXCOL, nEndRow, nTabRangeEnd); aCxt.mnColDelta = -(static_cast(nSize)); @@ -1516,9 +1515,11 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA if (pUndoOutline) *pUndoOutline = false; - for ( i = nStartTab; i <= nEndTab && i < static_cast(maTabs.size()); i++) + for (i = nStartTab; i <= nEndTab && i < static_cast(maTabs.size()); ++i) + { if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i))) - maTabs[i]->DeleteCol( nStartCol, nStartRow, nEndRow, nSize, pUndoOutline ); + maTabs[i]->DeleteCol(aCxt.maRegroupCols, nStartCol, nStartRow, nEndRow, nSize, pUndoOutline); + } if ( ValidCol(sal::static_int_cast(nStartCol+nSize)) ) {// Listeners have been removed in UpdateReference @@ -1536,7 +1537,6 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler()); } - SetAutoCalc( bOldAutoCalc ); pChartListenerCollection->UpdateDirtyCharts(); } diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 537f85654082..f900f6286245 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -59,7 +59,21 @@ #include #include -// STATIC DATA ----------------------------------------------------------- +namespace { + +class ColumnRegroupFormulaCells +{ + ScColumn* mpCols; +public: + ColumnRegroupFormulaCells(ScColumn* pCols) : mpCols(pCols) {} + + void operator() (SCCOL nCol) + { + mpCols[nCol].RegroupFormulaCells(); + } +}; + +} sal_uInt16 ScTable::GetTextWidth(SCCOL nCol, SCROW nRow) const { @@ -425,9 +439,8 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE SetStreamValid(false); } - -void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, - bool* pUndoOutline ) +void ScTable::DeleteCol( + const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, bool* pUndoOutline ) { if (nStartRow==0 && nEndRow==MAXROW) { @@ -460,7 +473,6 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE } } - { // scope for bulk broadcast ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM()); for (SCSIZE i = 0; i < nSize; i++) @@ -479,6 +491,10 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]); } + std::vector aRegroupCols; + rRegroupCols.getColumns(nTab, aRegroupCols); + std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol)); + // Transfer those notes that will get shifted into another container. ScNotes aNotes(pDocument); ScNotes::iterator itr = maNotes.begin(); -- cgit v1.2.3