summaryrefslogtreecommitdiff
path: root/sc/source/core/data/table3.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/table3.cxx')
-rw-r--r--sc/source/core/data/table3.cxx338
1 files changed, 225 insertions, 113 deletions
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 20e16b455c29..1958a7044d05 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -396,16 +396,26 @@ public:
}
};
+// Assume that we can handle 512MB, which with a ~100 bytes
+// ScSortInfoArray::Cell element for 500MB are about 5 million cells plus
+// overhead in one chunk.
+constexpr sal_Int32 kSortCellsChunk = 500 * 1024 * 1024 / sizeof(ScSortInfoArray::Cell);
+
namespace {
void initDataRows(
ScSortInfoArray& rArray, ScTable& rTab, ScColContainer& rCols,
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- bool bPattern, bool bHiddenFiltered )
+ bool bHiddenFiltered, bool bPattern, bool bCellNotes, bool bCellDrawObjects, bool bOnlyDataAreaExtras )
{
// Fill row-wise data table.
ScSortInfoArray::RowsType& rRows = rArray.InitDataRows(nRow2-nRow1+1, nCol2-nCol1+1);
+ const std::vector<SCCOLROW>& rOrderIndices = rArray.GetOrderIndices();
+ assert(!bOnlyDataAreaExtras || (rOrderIndices.size() == static_cast<size_t>(nRow2 - nRow1 + 1)
+ && nRow1 == rArray.GetStart()));
+
+ ScDrawLayer* pDrawLayer = (bCellDrawObjects ? rTab.GetDoc().GetDrawLayer() : nullptr);
for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
{
ScColumn& rCol = rCols[nCol];
@@ -416,17 +426,21 @@ void initDataRows(
sc::ColumnBlockConstPosition aBlockPos;
rCol.InitBlockPosition(aBlockPos);
std::map<SCROW, std::vector<SdrObject*>> aRowDrawObjects;
- ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
if (pDrawLayer)
aRowDrawObjects = pDrawLayer->GetObjectsAnchoredToRange(rTab.GetTab(), nCol, nRow1, nRow2);
- for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ for (SCROW nR = nRow1; nR <= nRow2; ++nR)
{
- ScSortInfoArray::Row& rRow = rRows[nRow-nRow1];
+ const SCROW nRow = (bOnlyDataAreaExtras ? rOrderIndices[nR - rArray.GetStart()] : nR);
+ ScSortInfoArray::Row& rRow = rRows[nR-nRow1];
ScSortInfoArray::Cell& rCell = rRow.maCells[nCol-nCol1];
- rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
- rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
- rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
+ if (!bOnlyDataAreaExtras)
+ {
+ rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
+ rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
+ }
+ if (bCellNotes)
+ rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
if (pDrawLayer)
rCell.maDrawObjects = aRowDrawObjects[nRow];
@@ -435,7 +449,7 @@ void initDataRows(
}
}
- if (bHiddenFiltered)
+ if (!bOnlyDataAreaExtras && bHiddenFiltered)
{
for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
{
@@ -464,9 +478,8 @@ std::unique_ptr<ScSortInfoArray> ScTable::CreateSortInfoArray( const sc::Reorder
pArray->SetKeepQuery(rParam.mbHiddenFiltered);
pArray->SetUpdateRefs(rParam.mbUpdateRefs);
- initDataRows(
- *pArray, *this, aCol, nCol1, nRow1, nCol2, nRow2,
- rParam.mbPattern, rParam.mbHiddenFiltered);
+ initDataRows( *pArray, *this, aCol, nCol1, nRow1, nCol2, nRow2, rParam.mbHiddenFiltered,
+ rParam.maDataAreaExtras.mbCellFormats, true, true, false);
}
else
{
@@ -508,9 +521,8 @@ std::unique_ptr<ScSortInfoArray> ScTable::CreateSortInfoArray(
}
}
- initDataRows(
- *pArray, *this, aCol, rSortParam.nCol1, nInd1, rSortParam.nCol2, nInd2,
- rSortParam.bIncludePattern, bKeepQuery);
+ initDataRows( *pArray, *this, aCol, rSortParam.nCol1, nInd1, rSortParam.nCol2, nInd2, bKeepQuery,
+ rSortParam.aDataAreaExtras.mbCellFormats, true, true, false);
}
else
{
@@ -676,8 +688,11 @@ void fillSortedColumnArray(
std::vector<std::unique_ptr<SortedColumn>>& rSortedCols,
SortedRowFlags& rRowFlags,
std::vector<SvtListener*>& rCellListeners,
- ScSortInfoArray* pArray, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress, const ScTable* pTable )
+ ScSortInfoArray* pArray, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress, const ScTable* pTable,
+ bool bOnlyDataAreaExtras )
{
+ assert(!bOnlyDataAreaExtras || !pArray->IsUpdateRefs());
+
SCROW nRow1 = pArray->GetStart();
ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
std::vector<SCCOLROW> aOrderIndices = pArray->GetOrderIndices();
@@ -696,72 +711,83 @@ void fillSortedColumnArray(
for (size_t i = 0; i < pRows->size(); ++i)
{
+ const SCROW nRow = nRow1 + i;
+
ScSortInfoArray::Row& rRow = (*pRows)[i];
for (size_t j = 0; j < rRow.maCells.size(); ++j)
{
- ScAddress aCellPos(nCol1 + j, nRow1 + i, nTab);
-
ScSortInfoArray::Cell& rCell = rRow.maCells[j];
- sc::CellStoreType& rCellStore = aSortedCols.at(j)->maCells;
- switch (rCell.maCell.meType)
+ // If bOnlyDataAreaExtras,
+ // sc::CellStoreType aSortedCols.at(j)->maCells
+ // and
+ // sc::CellTextAttrStoreType aSortedCols.at(j)->maCellTextAttrs
+ // are by definition all empty mdds::multi_type_vector, so nothing
+ // needs to be done to push *all* empty.
+
+ if (!bOnlyDataAreaExtras)
{
- 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().release());
- break;
- case CELLTYPE_FORMULA:
+ sc::CellStoreType& rCellStore = aSortedCols.at(j)->maCells;
+ switch (rCell.maCell.meType)
{
- assert(rCell.mpAttr);
- ScAddress aOldPos = rCell.maCell.mpFormula->aPos;
-
- ScFormulaCell* pNew = rCell.maCell.mpFormula->Clone( aCellPos );
- if (pArray->IsUpdateRefs())
- {
- pNew->CopyAllBroadcasters(*rCell.maCell.mpFormula);
- pNew->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, aCellPos);
- }
- else
- {
- pNew->GetCode()->AdjustReferenceOnMovedOriginIfOtherSheet(aOldPos, aCellPos);
- }
-
- if (!rCellListeners.empty())
- {
- // Original source cells will be deleted during
- // sc::CellStoreType::transfer(), SvtListener is a base
- // class, so we need to replace it.
- auto it( ::std::find( rCellListeners.begin(), rCellListeners.end(), rCell.maCell.mpFormula));
- if (it != rCellListeners.end())
- *it = pNew;
- }
-
- rCellStore.push_back(pNew);
+ 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().release());
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ assert(rCell.mpAttr);
+ ScAddress aOldPos = rCell.maCell.mpFormula->aPos;
+
+ const ScAddress aCellPos(nCol1 + j, nRow, nTab);
+ ScFormulaCell* pNew = rCell.maCell.mpFormula->Clone( aCellPos );
+ if (pArray->IsUpdateRefs())
+ {
+ pNew->CopyAllBroadcasters(*rCell.maCell.mpFormula);
+ pNew->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, aCellPos);
+ }
+ else
+ {
+ pNew->GetCode()->AdjustReferenceOnMovedOriginIfOtherSheet(aOldPos, aCellPos);
+ }
+
+ if (!rCellListeners.empty())
+ {
+ // Original source cells will be deleted during
+ // sc::CellStoreType::transfer(), SvtListener is a base
+ // class, so we need to replace it.
+ auto it( ::std::find( rCellListeners.begin(), rCellListeners.end(), rCell.maCell.mpFormula));
+ if (it != rCellListeners.end())
+ *it = pNew;
+ }
+
+ rCellStore.push_back(pNew);
+ }
+ break;
+ default:
+ //assert(!rCell.mpAttr);
+ // This assert doesn't hold, for example
+ // CopyCellsFromClipHandler may omit copying cells during
+ // PasteSpecial for which CopyTextAttrsFromClipHandler
+ // still copies a CellTextAttr. So if that really is not
+ // expected then fix it there.
+ rCellStore.push_back_empty();
}
- break;
- default:
- //assert(!rCell.mpAttr);
- // This assert doesn't hold, for example
- // CopyCellsFromClipHandler may omit copying cells during
- // PasteSpecial for which CopyTextAttrsFromClipHandler
- // still copies a CellTextAttr. So if that really is not
- // expected then fix it there.
- rCellStore.push_back_empty();
- }
-
- sc::CellTextAttrStoreType& rAttrStore = aSortedCols.at(j)->maCellTextAttrs;
- if (rCell.mpAttr)
- rAttrStore.push_back(*rCell.mpAttr);
- else
- rAttrStore.push_back_empty();
+
+ sc::CellTextAttrStoreType& rAttrStore = aSortedCols.at(j)->maCellTextAttrs;
+ if (rCell.mpAttr)
+ rAttrStore.push_back(*rCell.mpAttr);
+ else
+ rAttrStore.push_back_empty();
+ }
if (pArray->IsUpdateRefs())
{
@@ -788,13 +814,12 @@ void fillSortedColumnArray(
aSortedCols.at(j)->maCellDrawObjects.push_back(rCell.maDrawObjects);
if (rCell.mpPattern)
- aSortedCols.at(j)->setPattern(aCellPos.Row(), rCell.mpPattern);
+ aSortedCols.at(j)->setPattern(nRow, rCell.mpPattern);
}
- if (pArray->IsKeepQuery())
+ if (!bOnlyDataAreaExtras && pArray->IsKeepQuery())
{
// Hidden and filtered flags are first converted to segments.
- SCROW nRow = nRow1 + i;
aRowFlags.setRowHidden(nRow, rRow.mbHidden);
aRowFlags.setRowFiltered(nRow, rRow.mbFiltered);
}
@@ -874,6 +899,51 @@ public:
}
+void ScTable::SortReorderAreaExtrasByRow( ScSortInfoArray* pArray,
+ SCCOL nDataCol1, SCCOL nDataCol2,
+ const ScDataAreaExtras& rDataAreaExtras, ScProgress* pProgress )
+{
+ const SCROW nRow1 = pArray->GetStart();
+ const SCROW nLastRow = pArray->GetLast();
+ const SCCOL nChunkCols = std::max<SCCOL>( 1, kSortCellsChunk / (nLastRow - nRow1 + 1));
+ // Before data area.
+ for (SCCOL nCol = rDataAreaExtras.mnStartCol; nCol < nDataCol1; nCol += nChunkCols)
+ {
+ const SCCOL nEndCol = std::min<SCCOL>( nCol + nChunkCols - 1, nDataCol1 - 1);
+ initDataRows( *pArray, *this, aCol, nCol, nRow1, nEndCol, nLastRow, false,
+ rDataAreaExtras.mbCellFormats, rDataAreaExtras.mbCellNotes, rDataAreaExtras.mbCellDrawObjects, true);
+ SortReorderByRow( pArray, nCol, nEndCol, pProgress, true);
+ }
+ // Behind data area.
+ for (SCCOL nCol = nDataCol2 + 1; nCol <= rDataAreaExtras.mnEndCol; nCol += nChunkCols)
+ {
+ const SCCOL nEndCol = std::min<SCCOL>( nCol + nChunkCols - 1, rDataAreaExtras.mnEndCol);
+ initDataRows( *pArray, *this, aCol, nCol, nRow1, nEndCol, nLastRow, false,
+ rDataAreaExtras.mbCellFormats, rDataAreaExtras.mbCellNotes, rDataAreaExtras.mbCellDrawObjects, true);
+ SortReorderByRow( pArray, nCol, nEndCol, pProgress, true);
+ }
+}
+
+void ScTable::SortReorderAreaExtrasByColumn( const ScSortInfoArray* pArray,
+ SCROW nDataRow1, SCROW nDataRow2, const ScDataAreaExtras& rDataAreaExtras, ScProgress* pProgress )
+{
+ const SCCOL nCol1 = static_cast<SCCOL>(pArray->GetStart());
+ const SCCOL nLastCol = static_cast<SCCOL>(pArray->GetLast());
+ const SCROW nChunkRows = std::max<SCROW>( 1, kSortCellsChunk / (nLastCol - nCol1 + 1));
+ // Above data area.
+ for (SCROW nRow = rDataAreaExtras.mnStartRow; nRow < nDataRow1; nRow += nChunkRows)
+ {
+ const SCROW nEndRow = std::min<SCROW>( nRow + nChunkRows - 1, nDataRow1 - 1);
+ SortReorderByColumn( pArray, nRow, nEndRow, rDataAreaExtras.mbCellFormats, pProgress);
+ }
+ // Below data area.
+ for (SCROW nRow = nDataRow2 + 1; nRow <= rDataAreaExtras.mnEndRow; nRow += nChunkRows)
+ {
+ const SCROW nEndRow = std::min<SCROW>( nRow + nChunkRows - 1, rDataAreaExtras.mnEndRow);
+ SortReorderByColumn( pArray, nRow, nEndRow, rDataAreaExtras.mbCellFormats, pProgress);
+ }
+}
+
void ScTable::SortReorderByColumn(
const ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2, bool bPattern, ScProgress* pProgress )
{
@@ -1016,14 +1086,20 @@ void ScTable::SortReorderByColumn(
}
}
-void ScTable::SortReorderByRow(
- ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress )
+void ScTable::SortReorderByRow( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2,
+ ScProgress* pProgress, bool bOnlyDataAreaExtras )
{
assert(!pArray->IsUpdateRefs());
if (nCol2 < nCol1)
return;
+ // bOnlyDataAreaExtras:
+ // Data area extras by definition do not have any cell content so no
+ // formula cells either, so that handling doesn't need to be executed.
+ // However, there may be listeners of formulas listening to broadcasters of
+ // empty cells.
+
SCROW nRow1 = pArray->GetStart();
SCROW nRow2 = pArray->GetLast();
@@ -1033,6 +1109,7 @@ void ScTable::SortReorderByRow(
// When the update ref mode is disabled, we need to detach all formula
// cells in the sorted range before reordering, and re-start them
// afterward.
+ if (!bOnlyDataAreaExtras)
{
sc::EndListeningContext aCxt(rDocument);
DetachFormulaCells(aCxt, nCol1, nRow1, nCol2, nRow2);
@@ -1058,33 +1135,40 @@ void ScTable::SortReorderByRow(
}
// Split formula groups at the sort range boundaries (if applicable).
- std::vector<SCROW> aRowBounds;
- aRowBounds.reserve(2);
- aRowBounds.push_back(nRow1);
- aRowBounds.push_back(nRow2+1);
- for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
- SplitFormulaGroups(nCol, aRowBounds);
+ if (!bOnlyDataAreaExtras)
+ {
+ std::vector<SCROW> aRowBounds;
+ aRowBounds.reserve(2);
+ aRowBounds.push_back(nRow1);
+ aRowBounds.push_back(nRow2+1);
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ SplitFormulaGroups(nCol, aRowBounds);
+ }
// Cells in the data rows only reference values in the document. Make
// a copy before updating the document.
std::vector<std::unique_ptr<SortedColumn>> aSortedCols; // storage for copied cells.
SortedRowFlags aRowFlags(GetDoc().GetSheetLimits());
- fillSortedColumnArray(aSortedCols, aRowFlags, aCellListeners, pArray, nTab, nCol1, nCol2, pProgress, this);
+ fillSortedColumnArray(aSortedCols, aRowFlags, aCellListeners, pArray, nTab, nCol1, nCol2,
+ pProgress, this, bOnlyDataAreaExtras);
for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
{
SCCOL nThisCol = i + nCol1;
+ if (!bOnlyDataAreaExtras)
{
- 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);
+ }
}
{
@@ -1122,7 +1206,7 @@ void ScTable::SortReorderByRow(
aCol[nThisCol].CellStorageModified();
}
- if (pArray->IsKeepQuery())
+ if (!bOnlyDataAreaExtras && pArray->IsKeepQuery())
{
aRowFlags.maRowsHidden.build_tree();
aRowFlags.maRowsFiltered.build_tree();
@@ -1150,13 +1234,16 @@ void ScTable::SortReorderByRow(
l->Notify(aHint);
}
- // Re-group columns in the sorted range too.
- for (SCCOL i = nCol1; i <= nCol2; ++i)
- aCol[i].RegroupFormulaCells();
-
+ if (!bOnlyDataAreaExtras)
{
- sc::StartListeningContext aCxt(rDocument);
- AttachFormulaCells(aCxt, nCol1, nRow1, nCol2, nRow2);
+ // Re-group columns in the sorted range too.
+ for (SCCOL i = nCol1; i <= nCol2; ++i)
+ aCol[i].RegroupFormulaCells();
+
+ {
+ sc::StartListeningContext aCxt(rDocument);
+ AttachFormulaCells(aCxt, nCol1, nRow1, nCol2, nRow2);
+ }
}
}
@@ -1255,7 +1342,7 @@ void ScTable::SortReorderByRowRefUpdate(
std::vector<std::unique_ptr<SortedColumn>> aSortedCols; // storage for copied cells.
SortedRowFlags aRowFlags(GetDoc().GetSheetLimits());
std::vector<SvtListener*> aListenersDummy;
- fillSortedColumnArray(aSortedCols, aRowFlags, aListenersDummy, pArray, nTab, nCol1, nCol2, pProgress, this);
+ fillSortedColumnArray(aSortedCols, aRowFlags, aListenersDummy, pArray, nTab, nCol1, nCol2, pProgress, this, false);
for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
{
@@ -1701,8 +1788,8 @@ void ScTable::Sort(
if (pUndo)
{
// Copy over the basic sort parameters.
+ pUndo->maDataAreaExtras = rSortParam.aDataAreaExtras;
pUndo->mbByRow = rSortParam.bByRow;
- pUndo->mbPattern = rSortParam.bIncludePattern;
pUndo->mbHiddenFiltered = bKeepQuery;
pUndo->mbUpdateRefs = bUpdateRefs;
pUndo->mbHasHeaders = rSortParam.bHasHeader;
@@ -1713,14 +1800,15 @@ void ScTable::Sort(
aSortParam = rSortParam; // must be assigned before calling IsSorted()
if (rSortParam.bByRow)
{
- SCROW nLastRow = rSortParam.nRow2;
- SCROW nRow1 = (rSortParam.bHasHeader ? rSortParam.nRow1 + 1 : rSortParam.nRow1);
+ const SCROW nLastRow = rSortParam.nRow2;
+ const SCROW nRow1 = (rSortParam.bHasHeader ? rSortParam.nRow1 + 1 : rSortParam.nRow1);
if (nRow1 < nLastRow && !IsSorted(nRow1, nLastRow))
{
if(pProgress)
pProgress->SetState( 0, nLastRow-nRow1 );
- std::unique_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nRow1, nLastRow, bKeepQuery, bUpdateRefs));
+ std::unique_ptr<ScSortInfoArray> pArray( CreateSortInfoArray(
+ aSortParam, nRow1, nLastRow, bKeepQuery, bUpdateRefs));
if ( nLastRow - nRow1 > 255 )
DecoladeRow(pArray.get(), nRow1, nLastRow);
@@ -1729,32 +1817,46 @@ void ScTable::Sort(
if (pArray->IsUpdateRefs())
SortReorderByRowRefUpdate(pArray.get(), aSortParam.nCol1, aSortParam.nCol2, pProgress);
else
- SortReorderByRow(pArray.get(), aSortParam.nCol1, aSortParam.nCol2, pProgress);
+ {
+ SortReorderByRow(pArray.get(), aSortParam.nCol1, aSortParam.nCol2, pProgress, false);
+ if (rSortParam.aDataAreaExtras.anyExtrasWanted())
+ SortReorderAreaExtrasByRow( pArray.get(), aSortParam.nCol1, aSortParam.nCol2,
+ rSortParam.aDataAreaExtras, pProgress);
+ }
if (pUndo)
{
+ // Stored is the first data row without header row.
pUndo->maSortRange = ScRange(rSortParam.nCol1, nRow1, nTab, rSortParam.nCol2, nLastRow, nTab);
+ pUndo->maDataAreaExtras.mnStartRow = nRow1;
pUndo->maOrderIndices = pArray->GetOrderIndices();
}
}
}
else
{
- SCCOL nLastCol = rSortParam.nCol2;
- SCCOL nCol1 = (rSortParam.bHasHeader ? rSortParam.nCol1 + 1 : rSortParam.nCol1);
+ const SCCOL nLastCol = rSortParam.nCol2;
+ const SCCOL nCol1 = (rSortParam.bHasHeader ? rSortParam.nCol1 + 1 : rSortParam.nCol1);
if (nCol1 < nLastCol && !IsSorted(nCol1, nLastCol))
{
if(pProgress)
pProgress->SetState( 0, nLastCol-nCol1 );
- std::unique_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nCol1, nLastCol, bKeepQuery, bUpdateRefs));
+ std::unique_ptr<ScSortInfoArray> pArray( CreateSortInfoArray(
+ aSortParam, nCol1, nLastCol, bKeepQuery, bUpdateRefs));
QuickSort(pArray.get(), nCol1, nLastCol);
- SortReorderByColumn(pArray.get(), aSortParam.nRow1, aSortParam.nRow2, aSortParam.bIncludePattern, pProgress);
+ SortReorderByColumn(pArray.get(), rSortParam.nRow1, rSortParam.nRow2,
+ rSortParam.aDataAreaExtras.mbCellFormats, pProgress);
+ if (rSortParam.aDataAreaExtras.anyExtrasWanted() && !pArray->IsUpdateRefs())
+ SortReorderAreaExtrasByColumn( pArray.get(),
+ rSortParam.nRow1, rSortParam.nRow2, rSortParam.aDataAreaExtras, pProgress);
if (pUndo)
{
+ // Stored is the first data column without header column.
pUndo->maSortRange = ScRange(nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab);
+ pUndo->maDataAreaExtras.mnStartCol = nCol1;
pUndo->maOrderIndices = pArray->GetOrderIndices();
}
}
@@ -1779,8 +1881,14 @@ void ScTable::Reorder( const sc::ReorderParam& rParam )
SortReorderByRowRefUpdate(
pArray.get(), rParam.maSortRange.aStart.Col(), rParam.maSortRange.aEnd.Col(), nullptr);
else
- SortReorderByRow(
- pArray.get(), rParam.maSortRange.aStart.Col(), rParam.maSortRange.aEnd.Col(), nullptr);
+ {
+ SortReorderByRow( pArray.get(),
+ rParam.maSortRange.aStart.Col(), rParam.maSortRange.aEnd.Col(), nullptr, false);
+ if (rParam.maDataAreaExtras.anyExtrasWanted())
+ SortReorderAreaExtrasByRow( pArray.get(),
+ rParam.maSortRange.aStart.Col(), rParam.maSortRange.aEnd.Col(),
+ rParam.maDataAreaExtras, nullptr);
+ }
}
else
{
@@ -1788,7 +1896,11 @@ void ScTable::Reorder( const sc::ReorderParam& rParam )
pArray->SetOrderIndices(rParam.maOrderIndices);
SortReorderByColumn(
pArray.get(), rParam.maSortRange.aStart.Row(), rParam.maSortRange.aEnd.Row(),
- rParam.mbPattern, nullptr);
+ rParam.maDataAreaExtras.mbCellFormats, nullptr);
+ if (rParam.maDataAreaExtras.anyExtrasWanted() && !pArray->IsUpdateRefs())
+ SortReorderAreaExtrasByColumn( pArray.get(),
+ rParam.maSortRange.aStart.Row(), rParam.maSortRange.aEnd.Row(),
+ rParam.maDataAreaExtras, nullptr);
}
}