summaryrefslogtreecommitdiff
path: root/sc/source/core
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-08-13 22:53:14 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-08-13 23:01:21 -0400
commitc4d26f327605b77c8395bdb512d8ddcd8c11bfd1 (patch)
treea86a61a45d24aef8c8b6e0346ef5c3cee4819da5 /sc/source/core
parentf110e4190e575915a584e60cd2fb58dcb5eb5eaa (diff)
Regroup formula cells later in columns where references are updated.
Change-Id: I4dd6ade18e72d8f57583180463f9dda3603be4c2
Diffstat (limited to 'sc/source/core')
-rw-r--r--sc/source/core/data/column.cxx5
-rw-r--r--sc/source/core/data/columnset.cxx66
-rw-r--r--sc/source/core/data/document.cxx12
-rw-r--r--sc/source/core/data/table2.cxx26
4 files changed, 97 insertions, 12 deletions
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<TabsType::iterator,bool> 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<SCCOL>& rCols) const
+{
+ std::vector<SCCOL> 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<SCCOL>::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<SCTAB>(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<SCTAB>(maTabs.size()) ) );
+ sc::RefUpdateContext aCxt(*this);
if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
{
lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
- sc::RefUpdateContext aCxt(*this);
aCxt.meMode = URM_INSDEL;
aCxt.maRange = ScRange(sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart, MAXCOL, nEndRow, nTabRangeEnd);
aCxt.mnColDelta = -(static_cast<SCCOL>(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<SCTAB>(maTabs.size()); i++)
+ for (i = nStartTab; i <= nEndTab && i < static_cast<SCTAB>(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<SCCOL>(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 <svl/PasswordHelper.hxx>
#include <unotools/transliterationwrapper.hxx>
-// 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<SCCOL> 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();