summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/column.hxx17
-rw-r--r--sc/inc/document.hxx23
-rw-r--r--sc/inc/sortparam.hxx69
-rw-r--r--sc/inc/table.hxx24
-rw-r--r--sc/qa/unit/ucalc_sort.cxx8
-rw-r--r--sc/source/core/data/column2.cxx81
-rw-r--r--sc/source/core/data/document.cxx5
-rw-r--r--sc/source/core/data/sortparam.cxx41
-rw-r--r--sc/source/core/data/table1.cxx56
-rw-r--r--sc/source/core/data/table3.cxx338
-rw-r--r--sc/source/filter/xml/XMLExportDatabaseRanges.cxx2
-rw-r--r--sc/source/ui/app/transobj.cxx22
-rw-r--r--sc/source/ui/dbgui/tpsort.cxx12
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx64
-rw-r--r--sc/source/ui/undo/undosort.cxx15
-rw-r--r--sc/source/ui/unoobj/datauno.cxx4
-rw-r--r--sc/source/ui/view/cellsh2.cxx12
-rw-r--r--sc/source/ui/view/gridwin.cxx6
18 files changed, 518 insertions, 281 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 20ae065c1613..72527a76cd9e 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -218,19 +218,16 @@ public:
// data only:
bool IsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
SCSIZE GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const;
- bool HasDataAt(SCROW nRow, bool bConsiderCellNotes = false,
- bool bConsiderCellDrawObjects = false, bool bConsiderCellFormats = false) const;
- bool HasDataAt(sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
- bool bConsiderCellNotes = false, bool bConsiderCellDrawObjects = false,
- bool bConsiderCellFormats = false) const;
- bool HasDataAt(sc::ColumnBlockPosition& rBlockPos, SCROW nRow, bool bConsiderCellNotes = false,
- bool bConsiderCellDrawObjects = false, bool bConsiderCellFormats = false);
+ bool HasDataAt( SCROW nRow, ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
+ bool HasDataAt( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
+ ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
+ bool HasDataAt( sc::ColumnBlockPosition& rBlockPos, SCROW nRow,
+ ScDataAreaExtras* pDataAreaExtras = nullptr );
+ void GetDataExtrasAt( SCROW nRow, ScDataAreaExtras& rDataAreaExtras ) const;
bool HasVisibleDataAt(SCROW nRow) const;
SCROW GetFirstDataPos() const;
SCROW GetLastDataPos() const;
- SCROW GetLastDataPos(SCROW nLastRow, bool bConsiderCellNotes = false,
- bool bConsiderCellDrawObjects = false,
- bool bConsiderCellFormats = false) const;
+ SCROW GetLastDataPos( SCROW nLastRow, ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
bool GetPrevDataPos(SCROW& rRow) const;
bool GetNextDataPos(SCROW& rRow) const;
bool TrimEmptyBlocks(SCROW& rRowStart, SCROW& rRowEnd) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 7d1aac444847..7c798cf08674 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -201,6 +201,7 @@ class ScColumnsRange;
struct ScFilterEntries;
typedef o3tl::sorted_vector<sal_uInt32> ScCondFormatIndexes;
struct ScSheetLimits;
+struct ScDataAreaExtras;
namespace sc {
@@ -1398,18 +1399,20 @@ public:
/** Shrink a range to only include used data area.
- @param o_bShrunk
- Out parameter, true if area was shrunk, false if not.
+ @param o_bShrunk
+ Out parameter, true if area was shrunk, false if not.
+ @param bColumnsOnly
+ If TRUE, shrink only by columns, not rows.
@param bStickyTopRow
If TRUE, do not adjust the top row.
@param bStickyLeftCol
If TRUE, do not adjust the left column.
- @param bConsiderCellNotes
- If TRUE, consider the presence of cell notes besides data.
- @param bConsiderCellDrawObjects
- If TRUE, consider the presence of draw objects anchored to the cell.
- @param bConsiderCellFormats
- If TRUE, consider the presence of cell formats.
+ @param pDataAreaExtras
+ Consider additional area attributes like cell
+ formatting, cell notes and draw objects. The
+ possibly larger area than the actual cell
+ content data area is returned within the
+ struct.
@returns true if there is any data, false if not.
*/
@@ -1417,9 +1420,7 @@ public:
SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly,
bool bStickyTopRow = false, bool bStickyLeftCol = false,
- bool bConsiderCellNotes = false,
- bool bConsiderCellDrawObjects = false,
- bool bConsiderCellFormats = false ) const;
+ ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
/**
* Return the last non-empty row position in given columns that's no
diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 365151cf2bec..d9047f873b1e 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -37,21 +37,82 @@ struct ScSortKeyState
bool bAscending;
};
+/** Struct to hold non-data extended area, used with
+ ScDocument::ShrinkToUsedDataArea().
+*/
+struct ScDataAreaExtras
+{
+ /// If TRUE, consider the presence of cell notes besides data.
+ bool mbCellNotes = false;
+ /// If TRUE, consider the presence of draw objects anchored to the cell.
+ bool mbCellDrawObjects = false;
+ /// If TRUE, consider the presence of cell formats.
+ bool mbCellFormats = false;
+ SCCOL mnStartCol = SCCOL_MAX;
+ SCROW mnStartRow = SCROW_MAX;
+ SCCOL mnEndCol = -1;
+ SCROW mnEndRow = -1;
+
+ bool anyExtrasWanted() const { return mbCellNotes || mbCellDrawObjects || mbCellFormats; }
+ void resetArea() { mnStartCol = SCCOL_MAX; mnStartRow = SCROW_MAX; mnEndCol = -1; mnEndRow = -1; }
+
+ bool operator==( const ScDataAreaExtras& rOther ) const
+ {
+ // Ignore area range, this is used in ScSortParam::operator==().
+ return mbCellNotes == rOther.mbCellNotes
+ && mbCellDrawObjects == rOther.mbCellDrawObjects
+ && mbCellFormats == rOther.mbCellFormats;
+ }
+
+ enum class Clip
+ {
+ None,
+ Col,
+ Row
+ };
+
+ /// Obtain the overall range if area extras are larger.
+ void GetOverallRange( SCCOL& nCol1, SCROW& nRow1, SCCOL& nCol2, SCROW& nRow2, Clip eClip = Clip::None ) const
+ {
+ if (eClip != Clip::Col)
+ {
+ if (nCol1 > mnStartCol)
+ nCol1 = mnStartCol;
+ if (nCol2 < mnEndCol)
+ nCol2 = mnEndCol;
+ }
+ if (eClip != Clip::Row)
+ {
+ if (nRow1 > mnStartRow)
+ nRow1 = mnStartRow;
+ if (nRow2 < mnEndRow)
+ nRow2 = mnEndRow;
+ }
+ }
+
+ /// Set the overall range.
+ void SetOverallRange( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+ {
+ mnStartCol = nCol1;
+ mnStartRow = nRow1;
+ mnEndCol = nCol2;
+ mnEndRow = nRow2;
+ }
+};
+
struct SC_DLLPUBLIC ScSortParam
{
SCCOL nCol1;
SCROW nRow1;
SCCOL nCol2;
SCROW nRow2;
+ ScDataAreaExtras aDataAreaExtras;
sal_uInt16 nUserIndex;
bool bHasHeader;
bool bByRow;
bool bCaseSens;
bool bNaturalSort;
- bool bIncludeComments;
- bool bIncludeGraphicObjects;
bool bUserDef;
- bool bIncludePattern;
bool bInplace;
SCTAB nDestTab;
SCCOL nDestCol;
@@ -88,13 +149,13 @@ struct ReorderParam
* excludes that row / column.
*/
ScRange maSortRange;
+ ScDataAreaExtras maDataAreaExtras;
/**
* List of original column / row positions after reordering.
*/
std::vector<SCCOLROW> maOrderIndices;
bool mbByRow;
- bool mbPattern;
bool mbHiddenFiltered;
bool mbUpdateRefs;
bool mbHasHeaders;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 1f68937f87d2..c3ba8d112e9d 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -596,12 +596,11 @@ public:
bool ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly,
- bool bStickyTopRow, bool bStickyLeftCol, bool bConsiderCellNotes,
- bool bConsiderCellDrawObjects, bool bConsiderCellPatterns ) const;
+ bool bStickyTopRow, bool bStickyLeftCol,
+ ScDataAreaExtras* pDataAreaExtras ) const;
- SCROW GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow, bool bConsiderCellNotes = false,
- bool bConsiderCellDrawObjects = false,
- bool bConsiderCellPatterns = false ) const;
+ SCROW GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow,
+ ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
SCSIZE GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) const;
@@ -1194,10 +1193,17 @@ private:
const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2,
bool bKeepQuery, bool bUpdateRefs );
void QuickSort( ScSortInfoArray*, SCCOLROW nLo, SCCOLROW nHi);
- void SortReorderByColumn( const ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2, bool bPattern, ScProgress* pProgress );
-
- void SortReorderByRow( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress );
- void SortReorderByRowRefUpdate( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress );
+ void SortReorderByColumn( const ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2,
+ bool bPattern, ScProgress* pProgress );
+ void SortReorderAreaExtrasByColumn( const ScSortInfoArray* pArray, SCROW nDataRow1, SCROW nDataRow2,
+ const ScDataAreaExtras& rDataAreaExtras, ScProgress* pProgress );
+
+ void SortReorderByRow( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2,
+ ScProgress* pProgress, bool bOnlyDataAreaExtras );
+ void SortReorderByRowRefUpdate( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2,
+ ScProgress* pProgress );
+ void SortReorderAreaExtrasByRow( ScSortInfoArray* pArray, SCCOL nDataCol1, SCCOL nDataCol2,
+ const ScDataAreaExtras& rDataAreaExtras, 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/qa/unit/ucalc_sort.cxx b/sc/qa/unit/ucalc_sort.cxx
index f885fe2be76f..6e54e08952bd 100644
--- a/sc/qa/unit/ucalc_sort.cxx
+++ b/sc/qa/unit/ucalc_sort.cxx
@@ -253,7 +253,7 @@ void TestSort::testSortHorizontal()
aSortData.nRow2 = 3;
aSortData.bHasHeader = true;
aSortData.bByRow = false; // Sort by column (in horizontal direction).
- aSortData.bIncludePattern = true;
+ aSortData.aDataAreaExtras.mbCellFormats = true;
aSortData.maKeyState[0].bDoSort = true;
aSortData.maKeyState[0].nField = 0;
aSortData.maKeyState[0].bAscending = true;
@@ -320,7 +320,7 @@ void TestSort::testSortHorizontalWholeColumn()
aSortData.nRow2 = nRow2;
aSortData.bHasHeader = false;
aSortData.bByRow = false; // Sort by column (in horizontal direction).
- aSortData.bIncludePattern = true;
+ aSortData.aDataAreaExtras.mbCellFormats = true;
aSortData.maKeyState[0].bDoSort = true;
aSortData.maKeyState[0].nField = 0;
aSortData.maKeyState[0].bAscending = true;
@@ -381,7 +381,7 @@ void TestSort::testSortSingleRow()
aSortData.nRow2 = 0;
aSortData.bHasHeader = true;
aSortData.bByRow = true;
- aSortData.bIncludePattern = true;
+ aSortData.aDataAreaExtras.mbCellFormats = true;
aSortData.maKeyState[0].bDoSort = true;
aSortData.maKeyState[0].nField = 0;
aSortData.maKeyState[0].bAscending = true;
@@ -749,7 +749,7 @@ void TestSort::testSortWithCellFormats()
aSortData.nRow1 = 0;
aSortData.nRow2 = 3;
aSortData.bHasHeader = true;
- aSortData.bIncludePattern = true;
+ aSortData.aDataAreaExtras.mbCellFormats = true;
aSortData.maKeyState[0].bDoSort = true;
aSortData.maKeyState[0].nField = 0;
aSortData.maKeyState[0].bAscending = true;
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 21217e9cbbe1..e6fa9f4f728e 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -41,6 +41,7 @@
#include <scmatrix.hxx>
#include <rowheightcontext.hxx>
#include <tokenstringcontext.hxx>
+#include <sortparam.hxx>
#include <editeng/eeitem.hxx>
#include <o3tl/safeint.hxx>
@@ -1350,19 +1351,20 @@ SCROW ScColumn::GetLastDataPos() const
return GetDoc().MaxRow() - static_cast<SCROW>(it->size);
}
-SCROW ScColumn::GetLastDataPos( SCROW nLastRow, bool bConsiderCellNotes,
- bool bConsiderCellDrawObjects, bool bConsiderCellFormats ) const
+SCROW ScColumn::GetLastDataPos( SCROW nLastRow, ScDataAreaExtras* pDataAreaExtras ) const
{
- sc::CellStoreType::const_position_type aPos = maCells.position(std::min(nLastRow,GetDoc().MaxRow()));
+ nLastRow = std::min( nLastRow, GetDoc().MaxRow());
- if (bConsiderCellNotes && !IsNotesEmptyBlock(nLastRow, nLastRow))
- return nLastRow;
-
- if (bConsiderCellDrawObjects && !IsDrawObjectsEmptyBlock(nLastRow, nLastRow))
- return nLastRow;
+ if (pDataAreaExtras && pDataAreaExtras->mnEndRow < nLastRow)
+ {
+ // Check in order of likeliness.
+ if ( (pDataAreaExtras->mbCellFormats && HasVisibleAttrIn(nLastRow, nLastRow)) ||
+ (pDataAreaExtras->mbCellNotes && !IsNotesEmptyBlock(nLastRow, nLastRow)) ||
+ (pDataAreaExtras->mbCellDrawObjects && !IsDrawObjectsEmptyBlock(nLastRow, nLastRow)))
+ pDataAreaExtras->mnEndRow = nLastRow;
+ }
- if (bConsiderCellFormats && HasVisibleAttrIn(nLastRow, nLastRow))
- return nLastRow;
+ sc::CellStoreType::const_position_type aPos = maCells.position(nLastRow);
if (aPos.first->type != sc::element_type_empty)
return nLastRow;
@@ -3119,33 +3121,19 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const
rRow = nLastRow;
}
-bool ScColumn::HasDataAt(SCROW nRow, bool bConsiderCellNotes, bool bConsiderCellDrawObjects,
- bool bConsiderCellFormats) const
+bool ScColumn::HasDataAt(SCROW nRow, ScDataAreaExtras* pDataAreaExtras ) const
{
- if (bConsiderCellNotes && !IsNotesEmptyBlock(nRow, nRow))
- return true;
-
- if (bConsiderCellDrawObjects && !IsDrawObjectsEmptyBlock(nRow, nRow))
- return true;
-
- if (bConsiderCellFormats && HasVisibleAttrIn(nRow, nRow))
- return true;
+ if (pDataAreaExtras)
+ GetDataExtrasAt( nRow, *pDataAreaExtras);
return maCells.get_type(nRow) != sc::element_type_empty;
}
-bool ScColumn::HasDataAt(sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
- bool bConsiderCellNotes, bool bConsiderCellDrawObjects,
- bool bConsiderCellFormats) const
+bool ScColumn::HasDataAt( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
+ ScDataAreaExtras* pDataAreaExtras ) const
{
- if (bConsiderCellNotes && !IsNotesEmptyBlock(nRow, nRow))
- return true;
-
- if (bConsiderCellDrawObjects && !IsDrawObjectsEmptyBlock(nRow, nRow))
- return true;
-
- if (bConsiderCellFormats && HasVisibleAttrIn(nRow, nRow))
- return true;
+ if (pDataAreaExtras)
+ GetDataExtrasAt( nRow, *pDataAreaExtras);
std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(rBlockPos.miCellPos, nRow);
if (aPos.first == maCells.end())
@@ -3154,17 +3142,11 @@ bool ScColumn::HasDataAt(sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
return aPos.first->type != sc::element_type_empty;
}
-bool ScColumn::HasDataAt(sc::ColumnBlockPosition& rBlockPos, SCROW nRow,
- bool bConsiderCellNotes, bool bConsiderCellDrawObjects, bool bConsiderCellFormats)
+bool ScColumn::HasDataAt( sc::ColumnBlockPosition& rBlockPos, SCROW nRow,
+ ScDataAreaExtras* pDataAreaExtras )
{
- if (bConsiderCellNotes && !IsNotesEmptyBlock(nRow, nRow))
- return true;
-
- if (bConsiderCellDrawObjects && !IsDrawObjectsEmptyBlock(nRow, nRow))
- return true;
-
- if (bConsiderCellFormats && HasVisibleAttrIn(nRow, nRow))
- return true;
+ if (pDataAreaExtras)
+ GetDataExtrasAt( nRow, *pDataAreaExtras);
std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(rBlockPos.miCellPos, nRow);
if (aPos.first == maCells.end())
@@ -3173,6 +3155,23 @@ bool ScColumn::HasDataAt(sc::ColumnBlockPosition& rBlockPos, SCROW nRow,
return aPos.first->type != sc::element_type_empty;
}
+void ScColumn::GetDataExtrasAt( SCROW nRow, ScDataAreaExtras& rDataAreaExtras ) const
+{
+ if (rDataAreaExtras.mnStartRow <= nRow && nRow <= rDataAreaExtras.mnEndRow)
+ return;
+
+ // Check in order of likeliness.
+ if ( (rDataAreaExtras.mbCellFormats && HasVisibleAttrIn(nRow, nRow)) ||
+ (rDataAreaExtras.mbCellNotes && !IsNotesEmptyBlock(nRow, nRow)) ||
+ (rDataAreaExtras.mbCellDrawObjects && !IsDrawObjectsEmptyBlock(nRow, nRow)))
+ {
+ if (rDataAreaExtras.mnStartRow > nRow)
+ rDataAreaExtras.mnStartRow = nRow;
+ if (rDataAreaExtras.mnEndRow < nRow)
+ rDataAreaExtras.mnEndRow = nRow;
+ }
+}
+
bool ScColumn::IsAllAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
{
if (pAttrArray && rCol.pAttrArray)
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index c9a30aedc012..86e13f815c91 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1061,8 +1061,7 @@ bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow
bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStartCol,
SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly,
- bool bStickyTopRow, bool bStickyLeftCol, bool bConsiderCellNotes,
- bool bConsiderCellDrawObjects, bool bConsiderCellFormats ) const
+ bool bStickyTopRow, bool bStickyLeftCol, ScDataAreaExtras* pDataAreaExtras ) const
{
if (!ValidTab(nTab) || nTab >= static_cast<SCTAB> (maTabs.size()) || !maTabs[nTab])
{
@@ -1071,7 +1070,7 @@ bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStar
}
return maTabs[nTab]->ShrinkToUsedDataArea(
o_bShrunk, rStartCol, rStartRow, rEndCol, rEndRow, bColumnsOnly, bStickyTopRow,
- bStickyLeftCol, bConsiderCellNotes, bConsiderCellDrawObjects, bConsiderCellFormats);
+ bStickyLeftCol, pDataAreaExtras);
}
SCROW ScDocument::GetLastDataRow( SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index cd98dd07a982..cb369baae99c 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -33,11 +33,13 @@ ScSortParam::ScSortParam()
}
ScSortParam::ScSortParam( const ScSortParam& r ) :
- nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nUserIndex(r.nUserIndex),
+ nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),
+ aDataAreaExtras(r.aDataAreaExtras),
+ nUserIndex(r.nUserIndex),
bHasHeader(r.bHasHeader),bByRow(r.bByRow),bCaseSens(r.bCaseSens),
- bNaturalSort(r.bNaturalSort),bIncludeComments(r.bIncludeComments),
- bIncludeGraphicObjects(r.bIncludeGraphicObjects),bUserDef(r.bUserDef),
- bIncludePattern(r.bIncludePattern),bInplace(r.bInplace),
+ bNaturalSort(r.bNaturalSort),
+ bUserDef(r.bUserDef),
+ bInplace(r.bInplace),
nDestTab(r.nDestTab),nDestCol(r.nDestCol),nDestRow(r.nDestRow),
maKeyState( r.maKeyState ),
aCollatorLocale( r.aCollatorLocale ), aCollatorAlgorithm( r.aCollatorAlgorithm ),
@@ -53,13 +55,14 @@ void ScSortParam::Clear()
nCol1=nCol2=nDestCol = 0;
nRow1=nRow2=nDestRow = 0;
+ aDataAreaExtras = ScDataAreaExtras();
+ aDataAreaExtras.mbCellDrawObjects = true;
+ aDataAreaExtras.mbCellFormats = true;
nCompatHeader = 2;
nDestTab = 0;
nUserIndex = 0;
bHasHeader=bCaseSens=bUserDef=bNaturalSort = false;
- bIncludeComments = false;
- bIncludeGraphicObjects = true;
- bByRow=bIncludePattern=bInplace = true;
+ bByRow = bInplace = true;
aCollatorLocale = css::lang::Locale();
aCollatorAlgorithm.clear();
@@ -77,15 +80,13 @@ ScSortParam& ScSortParam::operator=( const ScSortParam& r )
nRow1 = r.nRow1;
nCol2 = r.nCol2;
nRow2 = r.nRow2;
+ aDataAreaExtras = r.aDataAreaExtras;
nUserIndex = r.nUserIndex;
bHasHeader = r.bHasHeader;
bByRow = r.bByRow;
bCaseSens = r.bCaseSens;
bNaturalSort = r.bNaturalSort;
- bIncludeComments= r.bIncludeComments;
- bIncludeGraphicObjects = r.bIncludeGraphicObjects;
bUserDef = r.bUserDef;
- bIncludePattern = r.bIncludePattern;
bInplace = r.bInplace;
nDestTab = r.nDestTab;
nDestCol = r.nDestCol;
@@ -123,15 +124,13 @@ bool ScSortParam::operator==( const ScSortParam& rOther ) const
&& (nRow1 == rOther.nRow1)
&& (nCol2 == rOther.nCol2)
&& (nRow2 == rOther.nRow2)
+ && (aDataAreaExtras == rOther.aDataAreaExtras)
&& (bHasHeader == rOther.bHasHeader)
&& (bByRow == rOther.bByRow)
&& (bCaseSens == rOther.bCaseSens)
&& (bNaturalSort == rOther.bNaturalSort)
- && (bIncludeComments== rOther.bIncludeComments)
- && (bIncludeGraphicObjects == rOther.bIncludeGraphicObjects)
&& (bUserDef == rOther.bUserDef)
&& (nUserIndex == rOther.nUserIndex)
- && (bIncludePattern == rOther.bIncludePattern)
&& (bInplace == rOther.bInplace)
&& (nDestTab == rOther.nDestTab)
&& (nDestCol == rOther.nDestCol)
@@ -155,15 +154,19 @@ bool ScSortParam::operator==( const ScSortParam& rOther ) const
}
ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld ) :
- nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),nUserIndex(rSub.nUserIndex),
+ nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),
+ aDataAreaExtras(rOld.aDataAreaExtras),
+ nUserIndex(rSub.nUserIndex),
bHasHeader(true),bByRow(true),bCaseSens(rSub.bCaseSens),bNaturalSort(rOld.bNaturalSort),
- bIncludeComments(rOld.bIncludeComments),bIncludeGraphicObjects(rOld.bIncludeGraphicObjects),
- bUserDef(rSub.bUserDef),bIncludePattern(rSub.bIncludePattern),
+ bUserDef(rSub.bUserDef),
bInplace(true),
nDestTab(0),nDestCol(0),nDestRow(0),
aCollatorLocale( rOld.aCollatorLocale ), aCollatorAlgorithm( rOld.aCollatorAlgorithm ),
nCompatHeader( rOld.nCompatHeader )
{
+ aDataAreaExtras.mbCellFormats = rSub.bIncludePattern;
+ aDataAreaExtras.resetArea();
+
sal_uInt16 i;
// first the groups from the partial results
@@ -201,12 +204,14 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld )
ScSortParam::ScSortParam( const ScQueryParam& rParam, SCCOL nCol ) :
nCol1(nCol),nRow1(rParam.nRow1),nCol2(nCol),nRow2(rParam.nRow2),nUserIndex(0),
bHasHeader(rParam.bHasHeader),bByRow(true),bCaseSens(rParam.bCaseSens),
- bNaturalSort(false),bIncludeComments(false),bIncludeGraphicObjects(true),
+ bNaturalSort(false),
//TODO: what about Locale and Algorithm?
- bUserDef(false),bIncludePattern(false),
+ bUserDef(false),
bInplace(true),
nDestTab(0),nDestCol(0),nDestRow(0), nCompatHeader(2)
{
+ aDataAreaExtras.mbCellDrawObjects = true;
+
ScSortKeyState aKeyState;
aKeyState.bDoSort = true;
aKeyState.nField = nCol;
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 40aeab42cfa2..67903850927b 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -976,7 +976,7 @@ bool ScTable::GetDataAreaSubrange( ScRange& rRange ) const
bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly, bool bStickyTopRow, bool bStickyLeftCol,
- bool bConsiderCellNotes, bool bConsiderCellDrawObjects, bool bConsiderCellFormats ) const
+ ScDataAreaExtras* pDataAreaExtras ) const
{
rStartCol = std::min<SCCOL>( rStartCol, aCol.size()-1 );
// check for rEndCol is done below.
@@ -1010,14 +1010,18 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
{
if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
{
- if (bConsiderCellNotes && !aCol[rEndCol].IsNotesEmptyBlock( rStartRow, rEndRow ))
- break;
-
- if (bConsiderCellDrawObjects && !aCol[rEndCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow ))
- break;
-
- if (bConsiderCellFormats && aCol[rEndCol].HasVisibleAttrIn(rStartRow, rEndRow))
- break;
+ if (pDataAreaExtras && pDataAreaExtras->mnEndCol < rEndCol)
+ {
+ // Check in order of likeliness.
+ if ( (pDataAreaExtras->mbCellFormats
+ && aCol[rEndCol].GetPatternCount( rStartRow, rEndRow) > 1
+ && aCol[rEndCol].HasVisibleAttrIn( rStartRow, rEndRow)) ||
+ (pDataAreaExtras->mbCellNotes
+ && !aCol[rEndCol].IsNotesEmptyBlock( rStartRow, rEndRow)) ||
+ (pDataAreaExtras->mbCellDrawObjects
+ && !aCol[rEndCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow)))
+ pDataAreaExtras->mnEndCol = rEndCol;
+ }
--rEndCol;
o_bShrunk = true;
@@ -1032,14 +1036,18 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
{
if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
{
- if (bConsiderCellNotes && !aCol[rStartCol].IsNotesEmptyBlock( rStartRow, rEndRow ))
- break;
-
- if (bConsiderCellDrawObjects && !aCol[rStartCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow ))
- break;
-
- if (bConsiderCellFormats && aCol[rEndCol].HasVisibleAttrIn(rStartRow, rEndRow))
- break;
+ if (pDataAreaExtras && pDataAreaExtras->mnStartCol > rStartCol)
+ {
+ // Check in order of likeliness.
+ if ( (pDataAreaExtras->mbCellFormats
+ && aCol[rStartCol].GetPatternCount( rStartRow, rEndRow) > 1
+ && aCol[rStartCol].HasVisibleAttrIn( rStartRow, rEndRow)) ||
+ (pDataAreaExtras->mbCellNotes
+ && !aCol[rStartCol].IsNotesEmptyBlock( rStartRow, rEndRow)) ||
+ (pDataAreaExtras->mbCellDrawObjects
+ && !aCol[rStartCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow)))
+ pDataAreaExtras->mnStartCol = rStartCol;
+ }
++rStartCol;
o_bShrunk = true;
@@ -1058,8 +1066,7 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
bool bFound = false;
for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
{
- if (aCol[i].HasDataAt(rStartRow, bConsiderCellNotes, bConsiderCellDrawObjects,
- bConsiderCellFormats))
+ if (aCol[i].HasDataAt(rStartRow, pDataAreaExtras))
bFound = true;
}
if (!bFound)
@@ -1074,8 +1081,7 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
while (rStartRow < rEndRow)
{
- SCROW nLastDataRow = GetLastDataRow(rStartCol, rEndCol, rEndRow, bConsiderCellNotes,
- bConsiderCellDrawObjects, bConsiderCellFormats);
+ SCROW nLastDataRow = GetLastDataRow(rStartCol, rEndCol, rEndRow, pDataAreaExtras);
if (0 <= nLastDataRow && nLastDataRow < rEndRow)
{
rEndRow = std::max( rStartRow, nLastDataRow);
@@ -1089,11 +1095,10 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
return rStartCol != rEndCol || (bColumnsOnly ?
!aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
(rStartRow != rEndRow ||
- aCol[rStartCol].HasDataAt( rStartRow, bConsiderCellNotes, bConsiderCellDrawObjects, bConsiderCellFormats )));
+ aCol[rStartCol].HasDataAt( rStartRow, pDataAreaExtras)));
}
-SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow, bool bConsiderCellNotes,
- bool bConsiderCellDrawObjects, bool bConsiderCellFormats ) const
+SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow, ScDataAreaExtras* pDataAreaExtras ) const
{
if ( !IsColValid( nCol1 ) || !ValidCol( nCol2 ) )
return -1;
@@ -1103,8 +1108,7 @@ SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow, bool bC
SCROW nNewLastRow = 0;
for (SCCOL i = nCol1; i <= nCol2; ++i)
{
- SCROW nThis = aCol[i].GetLastDataPos(nLastRow, bConsiderCellNotes, bConsiderCellDrawObjects,
- bConsiderCellFormats);
+ SCROW nThis = aCol[i].GetLastDataPos(nLastRow, pDataAreaExtras);
if (nNewLastRow < nThis)
nNewLastRow = nThis;
}
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);
}
}
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 106f24e593c2..b1ef4474881c 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -71,7 +71,7 @@ void writeSort(ScXMLExport& mrExport, const ScSortParam& aParam, const ScRange&
ScAddress aOutPos(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab);
- if (!aParam.bIncludePattern)
+ if (!aParam.aDataAreaExtras.mbCellFormats)
mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
if (!aParam.bInplace)
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index eaeb319dd1b8..7d1c50594e4c 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -50,6 +50,7 @@
#include <docfunc.hxx>
#include <scmod.hxx>
#include <dragdata.hxx>
+#include <sortparam.hxx>
#include <editeng/paperinf.hxx>
#include <editeng/sizeitem.hxx>
@@ -252,10 +253,23 @@ static ScRange lcl_reduceBlock(const ScDocument& rDoc, ScRange aReducedBlock, bo
SCROW nStartRow = aReducedBlock.aStart.Row();
SCCOL nEndCol = aReducedBlock.aEnd.Col();
SCROW nEndRow = aReducedBlock.aEnd.Row();
- bool bShrunk = false;
- rDoc.ShrinkToUsedDataArea( bShrunk, aReducedBlock.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow,
- false, bIncludeVisual /*bStickyTopRow*/, bIncludeVisual /*bStickyLeftCol*/,
- bIncludeVisual /*bConsiderCellNotes*/, bIncludeVisual /*bConsiderCellDrawObjects*/);
+
+ if (bIncludeVisual)
+ {
+ ScDataAreaExtras aDataAreaExtras;
+ aDataAreaExtras.mbCellNotes = true;
+ aDataAreaExtras.mbCellDrawObjects = true;
+ bool bShrunk = false;
+ rDoc.ShrinkToUsedDataArea( bShrunk, aReducedBlock.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow,
+ false, true /*bStickyTopRow*/, true /*bStickyLeftCol*/, &aDataAreaExtras);
+ aDataAreaExtras.GetOverallRange( nStartCol, nStartRow, nEndCol, nEndRow, ScDataAreaExtras::Clip::None);
+ }
+ else
+ {
+ bool bShrunk = false;
+ rDoc.ShrinkToUsedDataArea( bShrunk, aReducedBlock.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow,
+ false, false /*bStickyTopRow*/, false /*bStickyLeftCol*/);
+ }
if ( nPrintAreaEndRow > nEndRow )
nEndRow = nPrintAreaEndRow;
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
index 87989f0069d7..c9c1c15c04ab 100644
--- a/sc/source/ui/dbgui/tpsort.cxx
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -600,11 +600,11 @@ void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
}
m_xBtnCase->set_active( aSortData.bCaseSens );
- m_xBtnFormats->set_active( aSortData.bIncludePattern );
+ m_xBtnFormats->set_active( aSortData.aDataAreaExtras.mbCellFormats );
m_xBtnHeader->set_active( aSortData.bHasHeader );
m_xBtnNaturalSort->set_active( aSortData.bNaturalSort );
- m_xBtnIncComments->set_active( aSortData.bIncludeComments );
- m_xBtnIncImages->set_active( aSortData.bIncludeGraphicObjects );
+ m_xBtnIncComments->set_active( aSortData.aDataAreaExtras.mbCellNotes );
+ m_xBtnIncImages->set_active( aSortData.aDataAreaExtras.mbCellDrawObjects );
if ( aSortData.bByRow )
{
@@ -669,9 +669,9 @@ bool ScTabPageSortOptions::FillItemSet( SfxItemSet* rArgSet )
aNewSortData.bHasHeader = m_xBtnHeader->get_active();
aNewSortData.bCaseSens = m_xBtnCase->get_active();
aNewSortData.bNaturalSort = m_xBtnNaturalSort->get_active();
- aNewSortData.bIncludeComments= m_xBtnIncComments->get_active();
- aNewSortData.bIncludeGraphicObjects = m_xBtnIncImages->get_active();
- aNewSortData.bIncludePattern = m_xBtnFormats->get_active();
+ aNewSortData.aDataAreaExtras.mbCellNotes = m_xBtnIncComments->get_active();
+ aNewSortData.aDataAreaExtras.mbCellDrawObjects = m_xBtnIncImages->get_active();
+ aNewSortData.aDataAreaExtras.mbCellFormats = m_xBtnFormats->get_active();
aNewSortData.bInplace = !m_xBtnCopyResult->get_active();
aNewSortData.nDestCol = theOutPos.Col();
aNewSortData.nDestRow = theOutPos.Row();
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 3cdee27ffb1d..35374ded6acf 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -522,25 +522,58 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
return false;
}
+ const ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
+ const bool bUpdateRefs = aInputOption.GetSortRefUpdate();
+
// Adjust aLocalParam cols/rows to used data area. Keep sticky top row or
// column (depending on direction) in any case, not just if it has headers,
// so empty leading cells will be sorted to the end.
+ // aLocalParam.nCol/Row will encompass data content only, extras in
+ // aLocalParam.aDataAreaExtras.
bool bShrunk = false;
+ aLocalParam.aDataAreaExtras.resetArea();
rDoc.ShrinkToUsedDataArea(bShrunk, nTab, aLocalParam.nCol1, aLocalParam.nRow1,
aLocalParam.nCol2, aLocalParam.nRow2, false, aLocalParam.bByRow,
- !aLocalParam.bByRow, aLocalParam.bIncludeComments,
- aLocalParam.bIncludeGraphicObjects, aLocalParam.bIncludePattern);
+ !aLocalParam.bByRow,
+ (aLocalParam.aDataAreaExtras.anyExtrasWanted() ?
+ &aLocalParam.aDataAreaExtras : nullptr));
SCROW nStartRow = aLocalParam.nRow1;
if (aLocalParam.bByRow && aLocalParam.bHasHeader && nStartRow < aLocalParam.nRow2)
++nStartRow;
- if ( aLocalParam.bIncludePattern && rDoc.HasAttrib(
- aLocalParam.nCol1, nStartRow , nTab,
- aLocalParam.nCol2, aLocalParam.nRow2, nTab,
- HasAttrFlags::Merged | HasAttrFlags::Overlapped ) )
+ SCCOL nOverallCol1 = aLocalParam.nCol1;
+ SCROW nOverallRow1 = aLocalParam.nRow1;
+ SCCOL nOverallCol2 = aLocalParam.nCol2;
+ SCROW nOverallRow2 = aLocalParam.nRow2;
+ if (aLocalParam.aDataAreaExtras.anyExtrasWanted())
+ {
+ // Trailing empty excess columns/rows are excluded from being sorted,
+ // they stick at the end. Clip them.
+ const ScDataAreaExtras::Clip eClip = (aLocalParam.bByRow ?
+ ScDataAreaExtras::Clip::Row : ScDataAreaExtras::Clip::Col);
+ aLocalParam.aDataAreaExtras.GetOverallRange( nOverallCol1, nOverallRow1, nOverallCol2, nOverallRow2, eClip);
+ // Make it permanent.
+ aLocalParam.aDataAreaExtras.SetOverallRange( nOverallCol1, nOverallRow1, nOverallCol2, nOverallRow2);
+
+ if (bUpdateRefs)
+ {
+ // With update references the entire range needs to be handled as
+ // one entity for references pointing within to be moved along,
+ // even when there's no data content. For huge ranges we may be
+ // DOOMed then.
+ aLocalParam.nCol1 = nOverallCol1;
+ aLocalParam.nRow1 = nOverallRow1;
+ aLocalParam.nCol2 = nOverallCol2;
+ aLocalParam.nRow2 = nOverallRow2;
+ }
+ }
+
+ if (aLocalParam.aDataAreaExtras.mbCellFormats
+ && rDoc.HasAttrib( nOverallCol1, nStartRow, nTab, nOverallCol2, nOverallRow2, nTab,
+ HasAttrFlags::Merged | HasAttrFlags::Overlapped))
{
- // merge attributes would be mixed up during sorting
+ // Merge attributes would be mixed up during sorting.
if (!bApi)
rDocShell.ErrorMessage(STR_SORT_ERR_MERGED);
return false;
@@ -559,8 +592,7 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
aLocalParam.nRow2-nStartRow+1);
// No point adjusting row heights after the sort when all rows have the same height.
- bool bUniformRowHeight =
- rDoc.HasUniformRowHeight(nTab, nStartRow, aLocalParam.nRow2);
+ bool bUniformRowHeight = rDoc.HasUniformRowHeight(nTab, nStartRow, nOverallRow2);
bool bRepeatQuery = false; // repeat existing filter?
ScQueryParam aQueryParam;
@@ -573,8 +605,6 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
// don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
if (aLocalParam.GetSortKeyCount() && aLocalParam.maKeyState[0].bDoSort)
{
- ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
- bool bUpdateRefs = aInputOption.GetSortRefUpdate();
ScProgress aProgress(&rDocShell, ScResId(STR_PROGRESS_SORTING), 0, true);
if (!bRepeatQuery)
bRepeatQuery = rDoc.HasHiddenRows(aLocalParam.nRow1, aLocalParam.nRow2, nTab);
@@ -623,10 +653,10 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
if (bPaint)
{
PaintPartFlags nPaint = PaintPartFlags::Grid;
- SCCOL nStartX = aLocalParam.nCol1;
- SCROW nStartY = aLocalParam.nRow1;
- SCCOL nEndX = aLocalParam.nCol2;
- SCROW nEndY = aLocalParam.nRow2;
+ SCCOL nStartX = nOverallCol1;
+ SCROW nStartY = nOverallRow1;
+ SCCOL nEndX = nOverallCol2;
+ SCROW nEndY = nOverallRow2;
if ( bRepeatQuery )
{
nPaint |= PaintPartFlags::Left;
@@ -636,8 +666,8 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
rDocShell.PostPaint(ScRange(nStartX, nStartY, nTab, nEndX, nEndY, nTab), nPaint);
}
- if (!bUniformRowHeight && nStartRow <= aLocalParam.nRow2)
- rDocShell.AdjustRowHeight(nStartRow, aLocalParam.nRow2, nTab);
+ if (!bUniformRowHeight && nStartRow <= nOverallRow2)
+ rDocShell.AdjustRowHeight(nStartRow, nOverallRow2, nTab);
aModificator.SetDocumentModified();
diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
index e881c09ea7d3..ed65c760e8f4 100644
--- a/sc/source/ui/undo/undosort.cxx
+++ b/sc/source/ui/undo/undosort.cxx
@@ -45,9 +45,18 @@ void UndoSort::Execute( bool bUndo )
aParam.reverse();
rDoc.Reorder(aParam);
+ ScRange aOverallRange( maParam.maSortRange);
+ if (maParam.maDataAreaExtras.anyExtrasWanted())
+ {
+ aOverallRange.aStart.SetCol( maParam.maDataAreaExtras.mnStartCol);
+ aOverallRange.aStart.SetRow( maParam.maDataAreaExtras.mnStartRow);
+ aOverallRange.aEnd.SetCol( maParam.maDataAreaExtras.mnEndCol);
+ aOverallRange.aEnd.SetRow( maParam.maDataAreaExtras.mnEndRow);
+ }
+
if (maParam.mbHasHeaders)
{
- ScRange aMarkRange( maParam.maSortRange);
+ ScRange aMarkRange( aOverallRange);
if (maParam.mbByRow)
{
if (aMarkRange.aStart.Row() > 0)
@@ -62,14 +71,14 @@ void UndoSort::Execute( bool bUndo )
}
else
{
- ScUndoUtil::MarkSimpleBlock(pDocShell, maParam.maSortRange);
+ ScUndoUtil::MarkSimpleBlock(pDocShell, aOverallRange);
}
rDoc.SetDirty(maParam.maSortRange, true);
if (!aParam.mbUpdateRefs)
rDoc.BroadcastCells(aParam.maSortRange, SfxHintId::ScDataChanged);
- pDocShell->PostPaint(maParam.maSortRange, PaintPartFlags::Grid);
+ pDocShell->PostPaint(aOverallRange, PaintPartFlags::Grid);
pDocShell->PostDataChanged();
}
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 12a9bc44e949..41d5348ca4ba 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -306,7 +306,7 @@ void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq
pArray[3].Value <<= aFields;
pArray[4].Name = SC_UNONAME_BINDFMT;
- pArray[4].Value <<= rParam.bIncludePattern;
+ pArray[4].Value <<= rParam.aDataAreaExtras.mbCellFormats;
pArray[5].Name = SC_UNONAME_COPYOUT;
pArray[5].Value <<= !rParam.bInplace;
@@ -408,7 +408,7 @@ void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const uno::Sequence<b
rParam.bCaseSens = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
}
else if (aPropName == SC_UNONAME_BINDFMT)
- rParam.bIncludePattern = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ rParam.aDataAreaExtras.mbCellFormats = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
else if (aPropName == SC_UNONAME_COPYOUT)
rParam.bInplace = !ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
else if (aPropName == SC_UNONAME_OUTPOS)
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index b8ba37cc9244..4a1e7f04666b 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -395,9 +395,9 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
aSortParam.bByRow = true;
aSortParam.bCaseSens = false;
aSortParam.bNaturalSort = false;
- aSortParam.bIncludeComments = false;
- aSortParam.bIncludeGraphicObjects = true;
- aSortParam.bIncludePattern = true;
+ aSortParam.aDataAreaExtras.mbCellNotes = false;
+ aSortParam.aDataAreaExtras.mbCellDrawObjects = true;
+ aSortParam.aDataAreaExtras.mbCellFormats = true;
aSortParam.bInplace = true;
aSortParam.maKeyState[0].bDoSort = true;
aSortParam.maKeyState[0].nField = nCol;
@@ -449,11 +449,11 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
if ( pArgs->GetItemState( SID_SORT_NATURALSORT, true, &pItem ) == SfxItemState::SET )
aSortParam.bNaturalSort = static_cast<const SfxBoolItem*>(pItem)->GetValue();
if ( pArgs->GetItemState( SID_SORT_INCCOMMENTS, true, &pItem ) == SfxItemState::SET )
- aSortParam.bIncludeComments = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ aSortParam.aDataAreaExtras.mbCellNotes = static_cast<const SfxBoolItem*>(pItem)->GetValue();
if ( pArgs->GetItemState( SID_SORT_INCIMAGES, true, &pItem ) == SfxItemState::SET )
- aSortParam.bIncludeGraphicObjects = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ aSortParam.aDataAreaExtras.mbCellDrawObjects = static_cast<const SfxBoolItem*>(pItem)->GetValue();
if ( pArgs->GetItemState( SID_SORT_ATTRIBS, true, &pItem ) == SfxItemState::SET )
- aSortParam.bIncludePattern = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ aSortParam.aDataAreaExtras.mbCellFormats = static_cast<const SfxBoolItem*>(pItem)->GetValue();
if ( pArgs->GetItemState( SID_SORT_USERDEF, true, &pItem ) == SfxItemState::SET )
{
sal_uInt16 nUserIndex = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 7fb89c3f435f..40efbbb5e6e3 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -819,9 +819,9 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
aSortParam.bByRow = true;
aSortParam.bCaseSens = false;
aSortParam.bNaturalSort = false;
- aSortParam.bIncludeComments = false;
- aSortParam.bIncludeGraphicObjects = true;
- aSortParam.bIncludePattern = true;
+ aSortParam.aDataAreaExtras.mbCellNotes = false;
+ aSortParam.aDataAreaExtras.mbCellDrawObjects = true;
+ aSortParam.aDataAreaExtras.mbCellFormats = true;
aSortParam.bInplace = true;
aSortParam.maKeyState[0].bDoSort = true;
aSortParam.maKeyState[0].nField = nCol;