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.yosh...@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( _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits