[Libreoffice-commits] core.git: Branch 'private/kohei/calc-sort-fix' - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Tue Apr 22 19:48:18 PDT 2014
sc/inc/table.hxx | 3
sc/source/core/data/table3.cxx | 360 ++++++++++++++++++++---------------------
2 files changed, 184 insertions(+), 179 deletions(-)
New commits:
commit abf25629eb57ea473e5b69a5f744c43aabfaa9c4
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Apr 22 22:47:48 2014 -0400
New method SortReorderByRow() for the new row-based reordering.
Easier to follow this way.
Change-Id: Idf7e93106f1e1927967f4917062ee619ed71d694
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index a521fa34..b90de97 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1016,7 +1016,8 @@ private:
short Compare( ScSortInfoArray*, SCCOLROW nIndex1, SCCOLROW nIndex2) const;
ScSortInfoArray* CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery );
void QuickSort( ScSortInfoArray*, SCsCOLROW nLo, SCsCOLROW nHi);
- void SortReorder( ScSortInfoArray*, ScProgress* );
+ void SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress );
+ void SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress );
bool CreateExcelQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam);
bool CreateStarQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam);
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index bedbb62..88f3ea7 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -523,224 +523,228 @@ void ScTable::DestroySortCollator()
void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
{
+ if (aSortParam.bByRow)
+ {
+ SortReorderByRow(pArray, pProgress);
+ return;
+ }
+
size_t nCount = pArray->GetCount();
SCCOLROW nStart = pArray->GetStart();
ScSortInfo** ppInfo = pArray->GetFirstArray();
- if (aSortParam.bByRow)
- {
- SCROW nRow1 = pArray->GetStart();
- SCROW nRow2 = pArray->GetLast();
- ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
- assert(pRows); // In sort-by-row mode we must have data rows already populated.
+ std::vector<ScSortInfo*> aTable(nCount);
+ SCSIZE nPos;
+ for ( nPos = 0; nPos < nCount; nPos++ )
+ aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
+
+ SCCOLROW nDest = nStart;
+ for ( nPos = 0; nPos < nCount; nPos++, nDest++ )
+ {
+ SCCOLROW nOrg = ppInfo[nPos]->nOrg;
+ if ( nDest != nOrg )
+ {
+ SwapCol( static_cast<SCCOL>(nDest), static_cast<SCCOL>(nOrg) );
+ // neue Position des weggeswapten eintragen
+ ScSortInfo* p = ppInfo[nPos];
+ p->nOrg = nDest;
+ ::std::swap(p, aTable[nDest-nStart]);
+ p->nOrg = nOrg;
+ ::std::swap(p, aTable[nOrg-nStart]);
+ OSL_ENSURE( p == ppInfo[nPos], "SortReorder: nOrg MisMatch" );
+ }
+ if(pProgress)
+ pProgress->SetStateOnPercent( nPos );
+ }
+}
+
+void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
+{
+ SCROW nRow1 = pArray->GetStart();
+ SCROW nRow2 = pArray->GetLast();
+ 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, nRow1, aSortParam.nCol2, nRow2);
+ // Detach all formula cells within the sorted range first.
+ sc::EndListeningContext aCxt(*pDocument);
+ DetachFormulaCells(aCxt, aSortParam.nCol1, nRow1, aSortParam.nCol2, nRow2);
- // Cells in the data rows only reference values in the document. Make
- // a copy before updating the document.
+ // 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<SortedColumn> aSortedCols; // storage for copied cells.
- SortedRowFlags aRowFlags;
- aSortedCols.reserve(nColCount);
- for (size_t i = 0; i < nColCount; ++i)
- {
- // In the sorted column container, element positions and row
- // positions must match, else formula cells may mis-behave during
- // grouping.
- aSortedCols.push_back(new SortedColumn(nRow1));
- }
+ size_t nColCount = aSortParam.nCol2 - aSortParam.nCol1 + 1;
+ boost::ptr_vector<SortedColumn> aSortedCols; // storage for copied cells.
+ SortedRowFlags aRowFlags;
+ aSortedCols.reserve(nColCount);
+ for (size_t i = 0; i < nColCount; ++i)
+ {
+ // In the sorted column container, element positions and row
+ // positions must match, else formula cells may mis-behave during
+ // grouping.
+ aSortedCols.push_back(new SortedColumn(nRow1));
+ }
- for (size_t i = 0; i < pRows->size(); ++i)
+ for (size_t i = 0; i < pRows->size(); ++i)
+ {
+ ScSortInfoArray::Row* pRow = (*pRows)[i];
+ for (size_t j = 0; j < pRow->maCells.size(); ++j)
{
- ScSortInfoArray::Row* pRow = (*pRows)[i];
- for (size_t j = 0; j < pRow->maCells.size(); ++j)
- {
- ScAddress aCellPos(aSortParam.nCol1 + j, nRow1 + i, nTab);
+ ScAddress aCellPos(aSortParam.nCol1 + j, nRow1 + i, nTab);
- ScSortInfoArray::Cell& rCell = pRow->maCells[j];
+ ScSortInfoArray::Cell& rCell = pRow->maCells[j];
- sc::CellStoreType& rCellStore = aSortedCols.at(j).maCells;
- switch (rCell.maCell.meType)
+ sc::CellStoreType& rCellStore = aSortedCols.at(j).maCells;
+ switch (rCell.maCell.meType)
+ {
+ case CELLTYPE_STRING:
+ assert(rCell.mpAttr);
+ rCellStore.push_back(*rCell.maCell.mpString);
+ break;
+ case CELLTYPE_VALUE:
+ assert(rCell.mpAttr);
+ rCellStore.push_back(rCell.maCell.mfValue);
+ break;
+ case CELLTYPE_EDIT:
+ assert(rCell.mpAttr);
+ rCellStore.push_back(rCell.maCell.mpEditText->Clone());
+ break;
+ case CELLTYPE_FORMULA:
{
- case CELLTYPE_STRING:
- assert(rCell.mpAttr);
- rCellStore.push_back(*rCell.maCell.mpString);
- break;
- case CELLTYPE_VALUE:
- assert(rCell.mpAttr);
- rCellStore.push_back(rCell.maCell.mfValue);
- break;
- case CELLTYPE_EDIT:
- assert(rCell.mpAttr);
- rCellStore.push_back(rCell.maCell.mpEditText->Clone());
- break;
- case CELLTYPE_FORMULA:
- {
- assert(rCell.mpAttr);
- size_t n = rCellStore.size();
- sc::CellStoreType::iterator itBlk = rCellStore.push_back(rCell.maCell.mpFormula->Clone(aCellPos));
-
- // Join the formula cells as we fill the container.
- size_t nOffset = n - itBlk->position;
- sc::CellStoreType::position_type aPos(itBlk, nOffset);
- sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
- }
- break;
- default:
- assert(!rCell.mpAttr);
- rCellStore.push_back_empty();
+ assert(rCell.mpAttr);
+ size_t n = rCellStore.size();
+ sc::CellStoreType::iterator itBlk = rCellStore.push_back(rCell.maCell.mpFormula->Clone(aCellPos));
+
+ // Join the formula cells as we fill the container.
+ size_t nOffset = n - itBlk->position;
+ sc::CellStoreType::position_type aPos(itBlk, nOffset);
+ sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
}
+ break;
+ default:
+ assert(!rCell.mpAttr);
+ rCellStore.push_back_empty();
+ }
- sc::CellTextAttrStoreType& rAttrStore = aSortedCols.at(j).maCellTextAttrs;
- if (rCell.mpAttr)
- rAttrStore.push_back(*rCell.mpAttr);
- else
- rAttrStore.push_back_empty();
-
- // 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(j).maBroadcasters;
- if (rCell.mpBroadcaster)
- // A const pointer would be implicitly converted to a bool type.
- rBCStore.push_back(const_cast<SvtBroadcaster*>(rCell.mpBroadcaster));
- else
- rBCStore.push_back_empty();
-
- // The same with cell note instances ...
- sc::CellNoteStoreType& rNoteStore = aSortedCols.at(j).maCellNotes;
- if (rCell.mpNote)
- rNoteStore.push_back(const_cast<ScPostIt*>(rCell.mpNote));
- else
- rNoteStore.push_back_empty();
+ sc::CellTextAttrStoreType& rAttrStore = aSortedCols.at(j).maCellTextAttrs;
+ if (rCell.mpAttr)
+ rAttrStore.push_back(*rCell.mpAttr);
+ else
+ rAttrStore.push_back_empty();
+
+ // 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(j).maBroadcasters;
+ if (rCell.mpBroadcaster)
+ // A const pointer would be implicitly converted to a bool type.
+ rBCStore.push_back(const_cast<SvtBroadcaster*>(rCell.mpBroadcaster));
+ else
+ rBCStore.push_back_empty();
- if (rCell.mpPattern)
- aSortedCols.at(j).setPattern(aCellPos.Row(), rCell.mpPattern);
- }
+ // The same with cell note instances ...
+ sc::CellNoteStoreType& rNoteStore = aSortedCols.at(j).maCellNotes;
+ if (rCell.mpNote)
+ rNoteStore.push_back(const_cast<ScPostIt*>(rCell.mpNote));
+ else
+ rNoteStore.push_back_empty();
- if (pArray->IsKeepQuery())
- {
- // Hidden and filtered flags are first converted to segments.
- SCROW nRow = nRow1 + i;
- aRowFlags.setRowHidden(nRow, pRow->mbHidden);
- aRowFlags.setRowFiltered(nRow, pRow->mbFiltered);
- }
+ if (rCell.mpPattern)
+ aSortedCols.at(j).setPattern(aCellPos.Row(), rCell.mpPattern);
+ }
- if (pProgress)
- pProgress->SetStateOnPercent(i);
+ if (pArray->IsKeepQuery())
+ {
+ // Hidden and filtered flags are first converted to segments.
+ SCROW nRow = nRow1 + i;
+ aRowFlags.setRowHidden(nRow, pRow->mbHidden);
+ aRowFlags.setRowFiltered(nRow, pRow->mbFiltered);
}
- for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
+ if (pProgress)
+ pProgress->SetStateOnPercent(i);
+ }
+
+ for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
+ {
+ SCCOL nThisCol = i + aSortParam.nCol1;
+
{
- SCCOL nThisCol = i + aSortParam.nCol1;
+ sc::CellStoreType& rDest = aCol[nThisCol].maCells;
+ sc::CellStoreType& rSrc = aSortedCols[i].maCells;
+ rSrc.transfer(nRow1, nRow2, rDest, nRow1);
+ }
- {
- sc::CellStoreType& rDest = aCol[nThisCol].maCells;
- sc::CellStoreType& rSrc = aSortedCols[i].maCells;
- rSrc.transfer(nRow1, nRow2, rDest, nRow1);
- }
+ {
+ sc::CellTextAttrStoreType& rDest = aCol[nThisCol].maCellTextAttrs;
+ sc::CellTextAttrStoreType& rSrc = aSortedCols[i].maCellTextAttrs;
+ rSrc.transfer(nRow1, nRow2, rDest, nRow1);
+ }
- {
- sc::CellTextAttrStoreType& rDest = aCol[nThisCol].maCellTextAttrs;
- sc::CellTextAttrStoreType& rSrc = aSortedCols[i].maCellTextAttrs;
- rSrc.transfer(nRow1, nRow2, rDest, nRow1);
- }
+ {
+ sc::BroadcasterStoreType& rSrc = aSortedCols[i].maBroadcasters;
+ sc::BroadcasterStoreType& rDest = aCol[nThisCol].maBroadcasters;
- {
- sc::BroadcasterStoreType& rSrc = aSortedCols[i].maBroadcasters;
- sc::BroadcasterStoreType& rDest = aCol[nThisCol].maBroadcasters;
+ // Release current broadcasters first, to prevent them from getting deleted.
+ rDest.release_range(nRow1, nRow2);
- // Release current broadcasters first, to prevent them from getting deleted.
- rDest.release_range(nRow1, nRow2);
+ // Transfer sorted broadcaster segment to the document.
+ rSrc.transfer(nRow1, nRow2, rDest, nRow1);
+ }
- // Transfer sorted broadcaster segment to the document.
- rSrc.transfer(nRow1, nRow2, rDest, nRow1);
- }
+ {
+ sc::CellNoteStoreType& rSrc = aSortedCols[i].maCellNotes;
+ sc::CellNoteStoreType& rDest = aCol[nThisCol].maCellNotes;
- {
- sc::CellNoteStoreType& rSrc = aSortedCols[i].maCellNotes;
- sc::CellNoteStoreType& rDest = aCol[nThisCol].maCellNotes;
+ // Do the same as broadcaster storage transfer (to prevent double deletion).
+ rDest.release_range(nRow1, nRow2);
+ rSrc.transfer(nRow1, nRow2, rDest, nRow1);
+ aCol[nThisCol].UpdateNoteCaptions(nRow1, nRow2);
+ }
- // Do the same as broadcaster storage transfer (to prevent double deletion).
- rDest.release_range(nRow1, nRow2);
- rSrc.transfer(nRow1, nRow2, rDest, nRow1);
- aCol[nThisCol].UpdateNoteCaptions(nRow1, nRow2);
- }
+ {
+ // Get all row spans where the pattern is not NULL.
+ std::vector<PatternSpan> aSpans =
+ sc::toSpanArrayWithValue<SCROW,const ScPatternAttr*,PatternSpan>(
+ aSortedCols[i].maPatterns);
+ std::vector<PatternSpan>::iterator it = aSpans.begin(), itEnd = aSpans.end();
+ for (; it != itEnd; ++it)
{
- // Get all row spans where the pattern is not NULL.
- std::vector<PatternSpan> aSpans =
- sc::toSpanArrayWithValue<SCROW,const ScPatternAttr*,PatternSpan>(
- aSortedCols[i].maPatterns);
-
- std::vector<PatternSpan>::iterator it = aSpans.begin(), itEnd = aSpans.end();
- for (; it != itEnd; ++it)
- {
- assert(it->mpPattern); // should never be NULL.
- aCol[nThisCol].SetPatternArea(it->mnRow1, it->mnRow2, *it->mpPattern, true);
- }
+ assert(it->mpPattern); // should never be NULL.
+ aCol[nThisCol].SetPatternArea(it->mnRow1, it->mnRow2, *it->mpPattern, true);
}
-
- aCol[nThisCol].CellStorageModified();
}
- if (pArray->IsKeepQuery())
- {
- aRowFlags.maRowsHidden.build_tree();
- aRowFlags.maRowsFiltered.build_tree();
+ aCol[nThisCol].CellStorageModified();
+ }
- // Remove all flags in the range first.
- SetRowHidden(nRow1, nRow2, false);
- SetRowFiltered(nRow1, nRow2, false);
+ if (pArray->IsKeepQuery())
+ {
+ aRowFlags.maRowsHidden.build_tree();
+ aRowFlags.maRowsFiltered.build_tree();
- std::vector<sc::RowSpan> aSpans =
- sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsHidden, nRow1);
+ // Remove all flags in the range first.
+ SetRowHidden(nRow1, nRow2, false);
+ SetRowFiltered(nRow1, nRow2, false);
- std::vector<sc::RowSpan>::const_iterator it = aSpans.begin(), itEnd = aSpans.end();
- for (; it != itEnd; ++it)
- SetRowHidden(it->mnRow1, it->mnRow2, true);
+ std::vector<sc::RowSpan> aSpans =
+ sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsHidden, nRow1);
- aSpans = sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsFiltered, nRow1);
+ std::vector<sc::RowSpan>::const_iterator it = aSpans.begin(), itEnd = aSpans.end();
+ for (; it != itEnd; ++it)
+ SetRowHidden(it->mnRow1, it->mnRow2, true);
- it = aSpans.begin(), itEnd = aSpans.end();
- for (; it != itEnd; ++it)
- SetRowFiltered(it->mnRow1, it->mnRow2, true);
- }
+ aSpans = sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsFiltered, nRow1);
- // Attach all formula cells within sorted range, to have them start listening again.
- sc::StartListeningContext aStartListenCxt(*pDocument);
- AttachFormulaCells(
- aStartListenCxt, aSortParam.nCol1, nRow1, aSortParam.nCol2, nRow2);
+ it = aSpans.begin(), itEnd = aSpans.end();
+ for (; it != itEnd; ++it)
+ SetRowFiltered(it->mnRow1, it->mnRow2, true);
}
- else
- {
- std::vector<ScSortInfo*> aTable(nCount);
- SCSIZE nPos;
- for ( nPos = 0; nPos < nCount; nPos++ )
- aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
- SCCOLROW nDest = nStart;
- for ( nPos = 0; nPos < nCount; nPos++, nDest++ )
- {
- SCCOLROW nOrg = ppInfo[nPos]->nOrg;
- if ( nDest != nOrg )
- {
- SwapCol( static_cast<SCCOL>(nDest), static_cast<SCCOL>(nOrg) );
- // neue Position des weggeswapten eintragen
- ScSortInfo* p = ppInfo[nPos];
- p->nOrg = nDest;
- ::std::swap(p, aTable[nDest-nStart]);
- p->nOrg = nOrg;
- ::std::swap(p, aTable[nOrg-nStart]);
- OSL_ENSURE( p == ppInfo[nPos], "SortReorder: nOrg MisMatch" );
- }
- if(pProgress)
- pProgress->SetStateOnPercent( nPos );
- }
- }
+ // Attach all formula cells within sorted range, to have them start listening again.
+ sc::StartListeningContext aStartListenCxt(*pDocument);
+ AttachFormulaCells(
+ aStartListenCxt, aSortParam.nCol1, nRow1, aSortParam.nCol2, nRow2);
}
short ScTable::CompareCell(
More information about the Libreoffice-commits
mailing list