summaryrefslogtreecommitdiff
path: root/sc/source/core/data/table3.cxx
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-04-18 15:19:29 -0400
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-04-23 21:08:21 -0400
commitcd83e2f1674c04c8a489cf5a15ef35c25491ee6e (patch)
tree1fd8f2b3f2427fa6b54f1965ea9b20e2f4376047 /sc/source/core/data/table3.cxx
parent0ba7b36a5601cb227aeab347e3c2944ece59438d (diff)
Handle sorting of broadcasters correctly.
Change-Id: Iab46c26606880f0fa7c7067d8514b8be3629fe0f
Diffstat (limited to 'sc/source/core/data/table3.cxx')
-rw-r--r--sc/source/core/data/table3.cxx51
1 files changed, 46 insertions, 5 deletions
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 97c978ff149e..b8db3c614404 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -58,6 +58,7 @@
#include "columnspanset.hxx"
#include <stlalgorithm.hxx>
#include <cellvalues.hxx>
+#include <listenercontext.hxx>
#include "svl/sharedstringpool.hxx"
@@ -375,6 +376,15 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
return pArray;
}
+namespace {
+
+struct SortedColumn : boost::noncopyable
+{
+ sc::CellValues maCells; /// Stores cells and cell text attributes.
+ sc::BroadcasterStoreType maBroadcasters;
+};
+
+}
bool ScTable::IsSortCollatorGlobal() const
{
@@ -423,14 +433,18 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
assert(pRows); // In sort-by-row mode we must have data rows already populated.
+ // Detach all formula cells within the sorted range first.
+ sc::EndListeningContext aCxt(*pDocument);
+ DetachFormulaCells(aCxt, aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2);
+
// Cells in the data rows only reference values in the document. Make
// a copy before updating the document.
size_t nColCount = aSortParam.nCol2 - aSortParam.nCol1 + 1;
- boost::ptr_vector<sc::CellValues> aSortedCols; // storage for copied cells.
+ boost::ptr_vector<SortedColumn> aSortedCols; // storage for copied cells.
aSortedCols.reserve(nColCount);
for (size_t i = 0; i < nColCount; ++i)
- aSortedCols.push_back(new sc::CellValues);
+ aSortedCols.push_back(new SortedColumn);
for (size_t i = 0; i < pRows->size(); ++i)
{
@@ -438,9 +452,20 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
for (size_t nCol = 0; nCol < pRow->size(); ++nCol)
{
ScSortInfoArray::Cell& rCell = (*pRow)[nCol];
- sc::CellValues& rStore = aSortedCols.at(nCol);
+
+ sc::CellValues& rStore = aSortedCols.at(nCol).maCells;
ScAddress aCellPos(aSortParam.nCol1 + nCol, aSortParam.nRow1 + i, nTab);
rStore.append(rCell.maCell, rCell.mpAttr, aCellPos);
+
+ // At this point each broadcaster instance is managed by 2
+ // containers. We will release those in the original storage
+ // below before transferring them to the document.
+ sc::BroadcasterStoreType& rBCStore = aSortedCols.at(nCol).maBroadcasters;
+ size_t n = rBCStore.size();
+ rBCStore.resize(n+1);
+ if (rCell.mpBroadcaster)
+ // A const pointer would be implicitly converted to a bool type.
+ rBCStore.set(n, const_cast<SvtBroadcaster*>(rCell.mpBroadcaster));
}
if (pProgress)
@@ -449,9 +474,25 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
{
- sc::CellValues& rSortedCol = aSortedCols[i];
- TransferCellValuesFrom(i+aSortParam.nCol1, aSortParam.nRow1, rSortedCol);
+ SCCOL nThisCol = i + aSortParam.nCol1;
+ TransferCellValuesFrom(nThisCol, aSortParam.nRow1, aSortedCols[i].maCells);
+
+ sc::BroadcasterStoreType& rBCDest = aCol[nThisCol].maBroadcasters;
+
+ // Release current broadcasters first, to prevent them from getting deleted.
+ SvtBroadcaster* pBC = NULL;
+ for (SCROW nRow = aSortParam.nRow1; nRow <= aSortParam.nRow2; ++nRow)
+ rBCDest.release(nRow, pBC);
+
+ // Transfer sorted broadcaster segment to the document.
+ sc::BroadcasterStoreType& rBCSrc = aSortedCols[i].maBroadcasters;
+ rBCSrc.transfer(0, rBCSrc.size()-1, rBCDest, aSortParam.nRow1);
}
+
+ // Attach all formula cells within sorted range, to have them start listening again.
+ sc::StartListeningContext aStartListenCxt(*pDocument);
+ AttachFormulaCells(
+ aStartListenCxt, aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2);
}
else
{