[Libreoffice-commits] core.git: Branch 'private/kohei/calc-sort-fix' - 4 commits - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Fri Apr 18 13:39:38 PDT 2014
sc/inc/cellvalues.hxx | 1
sc/inc/column.hxx | 5 +
sc/inc/table.hxx | 3
sc/source/core/data/cellvalues.cxx | 54 ----------------
sc/source/core/data/column2.cxx | 11 +++
sc/source/core/data/column3.cxx | 65 ++++++++++++++++++-
sc/source/core/data/table2.cxx | 13 +++
sc/source/core/data/table3.cxx | 122 ++++++++++++++++++++++++++++++++-----
8 files changed, 201 insertions(+), 73 deletions(-)
New commits:
commit f64f40d7e932d43afd03d30dfef4633fc4664c53
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Apr 18 16:39:35 2014 -0400
Use correct index to access row arrays, to prevent out-of-range access.
Change-Id: Ia74c0f07c7f1021de92f77fdb93b2279a3b8462c
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 5bdc653..fb44fe0 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -292,7 +292,7 @@ public:
{
// Swap rows in data table.
RowsType& rRows = *mpRows;
- std::swap(rRows[nInd1], rRows[nInd2]);
+ std::swap(rRows[n1], rRows[n2]);
}
}
@@ -341,16 +341,16 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
// Filll row-wise data table.
ScSortInfoArray::RowsType& rRows = pArray->InitDataRows(
- aSortParam.nRow2 - aSortParam.nRow1 + 1, aSortParam.nCol2 - aSortParam.nCol1 + 1);
+ nInd2 - nInd1 + 1, aSortParam.nCol2 - aSortParam.nCol1 + 1);
for (SCCOL nCol = aSortParam.nCol1; nCol <= aSortParam.nCol2; ++nCol)
{
ScColumn& rCol = aCol[nCol];
sc::ColumnBlockConstPosition aBlockPos;
rCol.InitBlockPosition(aBlockPos);
- for (SCROW nRow = aSortParam.nRow1; nRow <= aSortParam.nRow2; ++nRow)
+ for (SCROW nRow = nInd1; nRow <= nInd2; ++nRow)
{
- ScSortInfoArray::RowType& rRow = *rRows[nRow-aSortParam.nRow1];
+ ScSortInfoArray::RowType& rRow = *rRows[nRow-nInd1];
ScSortInfoArray::Cell& rCell = rRow[nCol-aSortParam.nCol1];
rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
@@ -431,12 +431,13 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
if (aSortParam.bByRow)
{
+ SCROW nRow1 = aSortParam.nRow1 + (aSortParam.bHasHeader ? 1 : 0);
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);
+ DetachFormulaCells(aCxt, aSortParam.nCol1, nRow1, aSortParam.nCol2, aSortParam.nRow2);
// Cells in the data rows only reference values in the document. Make
// a copy before updating the document.
@@ -450,11 +451,11 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
for (size_t i = 0; i < pRows->size(); ++i)
{
ScSortInfoArray::RowType* pRow = (*pRows)[i];
- for (size_t nCol = 0; nCol < pRow->size(); ++nCol)
+ for (size_t j = 0; j < pRow->size(); ++j)
{
- ScSortInfoArray::Cell& rCell = (*pRow)[nCol];
+ ScSortInfoArray::Cell& rCell = (*pRow)[j];
- sc::CellStoreType& rCellStore = aSortedCols.at(nCol).maCells;
+ sc::CellStoreType& rCellStore = aSortedCols.at(j).maCells;
size_t n = rCellStore.size();
rCellStore.resize(n+1);
switch (rCell.maCell.meType)
@@ -474,7 +475,7 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
case CELLTYPE_FORMULA:
{
assert(rCell.mpAttr);
- ScAddress aCellPos(aSortParam.nCol1 + nCol, aSortParam.nRow1 + i, nTab);
+ ScAddress aCellPos(aSortParam.nCol1 + j, nRow1 + i, nTab);
sc::CellStoreType::iterator itBlk = rCellStore.set(n, rCell.maCell.mpFormula->Clone(aCellPos));
size_t nOffset = n - itBlk->position;
@@ -486,7 +487,7 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
assert(!rCell.mpAttr);
}
- sc::CellTextAttrStoreType& rAttrStore = aSortedCols.at(nCol).maCellTextAttrs;
+ sc::CellTextAttrStoreType& rAttrStore = aSortedCols.at(j).maCellTextAttrs;
rAttrStore.resize(n+1);
if (rCell.mpAttr)
rAttrStore.set(n, *rCell.mpAttr);
@@ -494,7 +495,7 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
// 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;
+ sc::BroadcasterStoreType& rBCStore = aSortedCols.at(j).maBroadcasters;
rBCStore.resize(n+1);
if (rCell.mpBroadcaster)
// A const pointer would be implicitly converted to a bool type.
@@ -512,13 +513,13 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
{
sc::CellStoreType& rDest = aCol[nThisCol].maCells;
sc::CellStoreType& rSrc = aSortedCols[i].maCells;
- rSrc.transfer(0, rSrc.size()-1, rDest, aSortParam.nRow1);
+ rSrc.transfer(0, rSrc.size()-1, rDest, nRow1);
}
{
sc::CellTextAttrStoreType& rDest = aCol[nThisCol].maCellTextAttrs;
sc::CellTextAttrStoreType& rSrc = aSortedCols[i].maCellTextAttrs;
- rSrc.transfer(0, rSrc.size()-1, rDest, aSortParam.nRow1);
+ rSrc.transfer(0, rSrc.size()-1, rDest, nRow1);
}
{
@@ -526,12 +527,12 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
// Release current broadcasters first, to prevent them from getting deleted.
SvtBroadcaster* pBC = NULL;
- for (SCROW nRow = aSortParam.nRow1; nRow <= aSortParam.nRow2; ++nRow)
+ for (SCROW nRow = 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);
+ rBCSrc.transfer(0, rBCSrc.size()-1, rBCDest, nRow1);
}
aCol[nThisCol].CellStorageModified();
@@ -540,7 +541,7 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
// 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);
+ aStartListenCxt, aSortParam.nCol1, nRow1, aSortParam.nCol2, aSortParam.nRow2);
}
else
{
commit 93d47b3308cfdc6a0283f2898ae5dca0e454d92e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Apr 18 15:40:24 2014 -0400
Use the mdds storage types directly rather than using CellValues.
Change-Id: I415b3cddc4b764668564affd573ae9cc00601278
diff --git a/sc/inc/cellvalues.hxx b/sc/inc/cellvalues.hxx
index c2bf1d3..3f36e01 100644
--- a/sc/inc/cellvalues.hxx
+++ b/sc/inc/cellvalues.hxx
@@ -49,7 +49,6 @@ public:
void copyTo( ScColumn& rCol, SCROW nRow ) const;
void assign( const std::vector<double>& rVals );
- void append( ScRefCellValue& rVal, const CellTextAttr* pAttr, const ScAddress& rPos );
size_t size() const;
diff --git a/sc/source/core/data/cellvalues.cxx b/sc/source/core/data/cellvalues.cxx
index 0740ab5..083b4d1 100644
--- a/sc/source/core/data/cellvalues.cxx
+++ b/sc/source/core/data/cellvalues.cxx
@@ -10,7 +10,6 @@
#include <cellvalues.hxx>
#include <column.hxx>
#include <cellvalue.hxx>
-#include <sharedformula.hxx>
#include <cassert>
#include <boost/noncopyable.hpp>
@@ -65,59 +64,6 @@ void CellValues::assign( const std::vector<double>& rVals )
mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
}
-void CellValues::append( ScRefCellValue& rVal, const CellTextAttr* pAttr, const ScAddress& rPos )
-{
- assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
-
- size_t n = mpImpl->maCells.size();
-
- bool bAppendAttr = true;
-
- switch (rVal.meType)
- {
- case CELLTYPE_STRING:
- {
- mpImpl->maCells.resize(n+1);
- mpImpl->maCells.set(n, *rVal.mpString);
- }
- break;
- case CELLTYPE_VALUE:
- {
- mpImpl->maCells.resize(n+1);
- mpImpl->maCells.set(n, rVal.mfValue);
- }
- break;
- case CELLTYPE_EDIT:
- {
- mpImpl->maCells.resize(n+1);
- mpImpl->maCells.set(n, rVal.mpEditText->Clone());
- }
- break;
- case CELLTYPE_FORMULA:
- {
- mpImpl->maCells.resize(n+1);
- CellStoreType::iterator itBlk = mpImpl->maCells.set(n, rVal.mpFormula->Clone(rPos));
-
- size_t nOffset = n - itBlk->position;
- CellStoreType::position_type aPos(itBlk, nOffset);
- SharedFormulaUtil::joinFormulaCellAbove(aPos);
- }
- break;
- default:
- bAppendAttr = false;
- }
-
- if (bAppendAttr)
- {
- mpImpl->maCellTextAttrs.resize(n+1);
-
- if (pAttr)
- mpImpl->maCellTextAttrs.set(n, *pAttr);
- else
- mpImpl->maCellTextAttrs.set(n, CellTextAttr());
- }
-}
-
size_t CellValues::size() const
{
assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 2bef7ba..2698f0b 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -300,7 +300,7 @@ void ScColumn::TransferCellValuesFrom( SCROW nRow, sc::CellValues& rSrc )
return;
sc::CellStoreType::position_type aPos = maCells.position(nRow);
-// DetachFormulaCells(aPos, rSrc.size());
+ DetachFormulaCells(aPos, rSrc.size());
rSrc.transferTo(*this, nRow);
@@ -311,7 +311,7 @@ void ScColumn::TransferCellValuesFrom( SCROW nRow, sc::CellValues& rSrc )
for (SCROW i = nRow; i <= nLastRow; ++i)
aRows.push_back(i);
-// BroadcastCells(aRows, SC_HINT_DATACHANGED);
+ BroadcastCells(aRows, SC_HINT_DATACHANGED);
}
void ScColumn::CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc )
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index b8db3c6..5bdc653 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -57,8 +57,8 @@
#include "mtvcellfunc.hxx"
#include "columnspanset.hxx"
#include <stlalgorithm.hxx>
-#include <cellvalues.hxx>
#include <listenercontext.hxx>
+#include <sharedformula.hxx>
#include "svl/sharedstringpool.hxx"
@@ -380,7 +380,8 @@ namespace {
struct SortedColumn : boost::noncopyable
{
- sc::CellValues maCells; /// Stores cells and cell text attributes.
+ sc::CellStoreType maCells;
+ sc::CellTextAttrStoreType maCellTextAttrs;
sc::BroadcasterStoreType maBroadcasters;
};
@@ -453,15 +454,47 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
{
ScSortInfoArray::Cell& rCell = (*pRow)[nCol];
- sc::CellValues& rStore = aSortedCols.at(nCol).maCells;
- ScAddress aCellPos(aSortParam.nCol1 + nCol, aSortParam.nRow1 + i, nTab);
- rStore.append(rCell.maCell, rCell.mpAttr, aCellPos);
+ sc::CellStoreType& rCellStore = aSortedCols.at(nCol).maCells;
+ size_t n = rCellStore.size();
+ rCellStore.resize(n+1);
+ switch (rCell.maCell.meType)
+ {
+ case CELLTYPE_STRING:
+ assert(rCell.mpAttr);
+ rCellStore.set(n, *rCell.maCell.mpString);
+ break;
+ case CELLTYPE_VALUE:
+ assert(rCell.mpAttr);
+ rCellStore.set(n, rCell.maCell.mfValue);
+ break;
+ case CELLTYPE_EDIT:
+ assert(rCell.mpAttr);
+ rCellStore.set(n, rCell.maCell.mpEditText->Clone());
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ assert(rCell.mpAttr);
+ ScAddress aCellPos(aSortParam.nCol1 + nCol, aSortParam.nRow1 + i, nTab);
+ sc::CellStoreType::iterator itBlk = rCellStore.set(n, rCell.maCell.mpFormula->Clone(aCellPos));
+
+ size_t nOffset = n - itBlk->position;
+ sc::CellStoreType::position_type aPos(itBlk, nOffset);
+ sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
+ }
+ break;
+ default:
+ assert(!rCell.mpAttr);
+ }
+
+ sc::CellTextAttrStoreType& rAttrStore = aSortedCols.at(nCol).maCellTextAttrs;
+ rAttrStore.resize(n+1);
+ if (rCell.mpAttr)
+ rAttrStore.set(n, *rCell.mpAttr);
// 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.
@@ -475,18 +508,33 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
{
SCCOL nThisCol = i + aSortParam.nCol1;
- TransferCellValuesFrom(nThisCol, aSortParam.nRow1, aSortedCols[i].maCells);
- sc::BroadcasterStoreType& rBCDest = aCol[nThisCol].maBroadcasters;
+ {
+ sc::CellStoreType& rDest = aCol[nThisCol].maCells;
+ sc::CellStoreType& rSrc = aSortedCols[i].maCells;
+ rSrc.transfer(0, rSrc.size()-1, rDest, aSortParam.nRow1);
+ }
- // 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);
+ {
+ sc::CellTextAttrStoreType& rDest = aCol[nThisCol].maCellTextAttrs;
+ sc::CellTextAttrStoreType& rSrc = aSortedCols[i].maCellTextAttrs;
+ rSrc.transfer(0, rSrc.size()-1, rDest, aSortParam.nRow1);
+ }
+
+ {
+ 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);
+ }
- // Transfer sorted broadcaster segment to the document.
- sc::BroadcasterStoreType& rBCSrc = aSortedCols[i].maBroadcasters;
- rBCSrc.transfer(0, rBCSrc.size()-1, rBCDest, aSortParam.nRow1);
+ aCol[nThisCol].CellStorageModified();
}
// Attach all formula cells within sorted range, to have them start listening again.
commit 4f74be86d5724346992f8e16e87d85c1e25277a1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Apr 18 15:19:29 2014 -0400
Handle sorting of broadcasters correctly.
Change-Id: Iab46c26606880f0fa7c7067d8514b8be3629fe0f
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 39cb015..62bb4c6 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -562,6 +562,9 @@ public:
void DetachFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength );
+ void AttachFormulaCells( sc::StartListeningContext& rCxt, SCROW nRow1, SCROW nRow2 );
+ void DetachFormulaCells( sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2 );
+
/**
* Regroup formula cells for the entire column.
*/
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 5ddcc5c..79b30f9 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1041,6 +1041,9 @@ private:
void EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
void StartAllListeners();
+ void AttachFormulaCells( sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
+ void DetachFormulaCells( sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
+
void SetLoadingMedium(bool bLoading);
SCSIZE FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 38a92c0..3008fec 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -340,15 +340,35 @@ void ScColumn::DetachFormulaCell(
namespace {
+class AttachFormulaCellsHandler
+{
+ sc::StartListeningContext& mrCxt;
+
+public:
+ AttachFormulaCellsHandler( sc::StartListeningContext& rCxt ) :
+ mrCxt(rCxt) {}
+
+ void operator() (size_t /*nRow*/, ScFormulaCell* pCell)
+ {
+ pCell->StartListeningTo(mrCxt);
+ }
+};
+
class DetachFormulaCellsHandler
{
ScDocument* mpDoc;
+ sc::EndListeningContext* mpCxt;
+
public:
- DetachFormulaCellsHandler(ScDocument* pDoc) : mpDoc(pDoc) {}
+ DetachFormulaCellsHandler( ScDocument* pDoc, sc::EndListeningContext* pCxt ) :
+ mpDoc(pDoc), mpCxt(pCxt) {}
void operator() (size_t /*nRow*/, ScFormulaCell* pCell)
{
- pCell->EndListeningTo(mpDoc);
+ if (mpCxt)
+ pCell->EndListeningTo(*mpCxt);
+ else
+ pCell->EndListeningTo(mpDoc);
}
};
@@ -370,10 +390,49 @@ void ScColumn::DetachFormulaCells(
if (pDocument->IsClipOrUndo())
return;
- DetachFormulaCellsHandler aFunc(pDocument);
+ DetachFormulaCellsHandler aFunc(pDocument, NULL);
sc::ProcessFormula(aPos.first, maCells, nRow, nNextTopRow-1, aFunc);
}
+void ScColumn::AttachFormulaCells( sc::StartListeningContext& rCxt, SCROW nRow1, SCROW nRow2 )
+{
+ sc::CellStoreType::position_type aPos = maCells.position(nRow1);
+ sc::CellStoreType::iterator it = aPos.first;
+
+ sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
+ if (ValidRow(nRow2+1))
+ {
+ aPos = maCells.position(it, nRow2+1);
+ sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
+ }
+
+ if (pDocument->IsClipOrUndo())
+ return;
+
+ AttachFormulaCellsHandler aFunc(rCxt);
+ sc::ProcessFormula(it, maCells, nRow1, nRow2, aFunc);
+}
+
+void ScColumn::DetachFormulaCells( sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2 )
+{
+ sc::CellStoreType::position_type aPos = maCells.position(nRow1);
+ sc::CellStoreType::iterator it = aPos.first;
+
+ // Split formula grouping at the top and bottom boundaries.
+ sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
+ if (ValidRow(nRow2+1))
+ {
+ aPos = maCells.position(it, nRow2+1);
+ sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
+ }
+
+ if (pDocument->IsClipOrUndo())
+ return;
+
+ DetachFormulaCellsHandler aFunc(pDocument, &rCxt);
+ sc::ProcessFormula(it, maCells, nRow1, nRow2, aFunc);
+}
+
sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
{
// See if we are overwriting an existing formula cell.
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 2698f0b..2bef7ba 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -300,7 +300,7 @@ void ScColumn::TransferCellValuesFrom( SCROW nRow, sc::CellValues& rSrc )
return;
sc::CellStoreType::position_type aPos = maCells.position(nRow);
- DetachFormulaCells(aPos, rSrc.size());
+// DetachFormulaCells(aPos, rSrc.size());
rSrc.transferTo(*this, nRow);
@@ -311,7 +311,7 @@ void ScColumn::TransferCellValuesFrom( SCROW nRow, sc::CellValues& rSrc )
for (SCROW i = nRow; i <= nLastRow; ++i)
aRows.push_back(i);
- BroadcastCells(aRows, SC_HINT_DATACHANGED);
+// BroadcastCells(aRows, SC_HINT_DATACHANGED);
}
void ScColumn::CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc )
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index af2492e..8c1842c 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1031,6 +1031,19 @@ void ScTable::StartAllListeners()
aCol[i].StartAllListeners();
}
+void ScTable::AttachFormulaCells(
+ sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ aCol[nCol].AttachFormulaCells(rCxt, nRow1, nRow2);
+}
+
+void ScTable::DetachFormulaCells(
+ sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ aCol[nCol].DetachFormulaCells(rCxt, nRow1, nRow2);
+}
void ScTable::StartNeededListeners()
{
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 97c978f..b8db3c6 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
{
commit 5ba7751debd320032c42d2b960f4d51100081bfb
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Apr 18 10:42:32 2014 -0400
Retrieve and store broadcasters into data table.
Change-Id: I107ccbbc61a5e8024f21a7a30fae9fea00c90bde
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 10970df..39cb015 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -514,6 +514,8 @@ public:
SvtBroadcaster* GetBroadcaster( SCROW nRow );
const SvtBroadcaster* GetBroadcaster( SCROW nRow ) const;
+ const SvtBroadcaster* GetBroadcaster( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
+
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
void PrepareBroadcastersForDestruction();
bool HasBroadcaster() const;
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 4e6de8d..ecdb50d 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1794,6 +1794,17 @@ const SvtBroadcaster* ScColumn::GetBroadcaster(SCROW nRow) const
return maBroadcasters.get<SvtBroadcaster*>(nRow);
}
+const SvtBroadcaster* ScColumn::GetBroadcaster( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const
+{
+ sc::BroadcasterStoreType::const_position_type aPos = maBroadcasters.position(rBlockPos.miBroadcasterPos, nRow);
+ rBlockPos.miBroadcasterPos = aPos.first;
+
+ if (aPos.first->type != sc::element_type_broadcaster)
+ return NULL;
+
+ return sc::broadcaster_block::at(*aPos.first->data, aPos.second);
+}
+
void ScColumn::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 )
{
rBlockPos.miBroadcasterPos =
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index bb793dc..97c978f 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -226,8 +226,9 @@ public:
{
ScRefCellValue maCell;
const sc::CellTextAttr* mpAttr;
+ const SvtBroadcaster* mpBroadcaster;
- Cell() : mpAttr(NULL) {}
+ Cell() : mpAttr(NULL), mpBroadcaster(NULL) {}
};
typedef std::vector<Cell> RowType;
@@ -353,6 +354,7 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
+ rCell.mpBroadcaster = rCol.GetBroadcaster(aBlockPos, nRow);
}
}
}
More information about the Libreoffice-commits
mailing list