1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
26 #include "address.hxx"
27 #include <com/sun/star/lang/Locale.hpp>
29 #include "celltextattr.hxx"
30 #include "cellvalue.hxx"
31 #include "patattr.hxx"
32 #include <tools/color.hxx>
34 struct ScSubTotalParam
;
39 enum class ScColorSortMode
{
50 ScColorSortMode aColorSortMode
;
51 Color aColorSortColor
;
54 /** Struct to hold non-data extended area, used with
55 ScDocument::ShrinkToUsedDataArea().
57 struct ScDataAreaExtras
59 /// If TRUE, consider the presence of cell notes besides data.
60 bool mbCellNotes
= false;
61 /// If TRUE, consider the presence of draw objects anchored to the cell.
62 bool mbCellDrawObjects
= false;
63 /// If TRUE, consider the presence of cell formats.
64 bool mbCellFormats
= false;
65 SCCOL mnStartCol
= SCCOL_MAX
;
66 SCROW mnStartRow
= SCROW_MAX
;
70 bool anyExtrasWanted() const { return mbCellNotes
|| mbCellDrawObjects
|| mbCellFormats
; }
71 void resetArea() { mnStartCol
= SCCOL_MAX
; mnStartRow
= SCROW_MAX
; mnEndCol
= -1; mnEndRow
= -1; }
73 bool operator==( const ScDataAreaExtras
& rOther
) const
75 // Ignore area range, this is used in ScSortParam::operator==().
76 return mbCellNotes
== rOther
.mbCellNotes
77 && mbCellDrawObjects
== rOther
.mbCellDrawObjects
78 && mbCellFormats
== rOther
.mbCellFormats
;
88 /// Obtain the overall range if area extras are larger.
89 void GetOverallRange( SCCOL
& nCol1
, SCROW
& nRow1
, SCCOL
& nCol2
, SCROW
& nRow2
, Clip eClip
= Clip::None
) const
91 if (eClip
!= Clip::Col
)
93 if (nCol1
> mnStartCol
)
98 if (eClip
!= Clip::Row
)
100 if (nRow1
> mnStartRow
)
102 if (nRow2
< mnEndRow
)
107 /// Set the overall range.
108 void SetOverallRange( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
117 struct SC_DLLPUBLIC ScSortParam
124 ScDataAreaExtras aDataAreaExtras
;
125 sal_uInt16 nUserIndex
;
135 ::std::vector
<ScSortKeyState
>
137 css::lang::Locale aCollatorLocale
;
138 OUString aCollatorAlgorithm
;
139 sal_uInt16 nCompatHeader
;
142 ScSortParam( const ScSortParam
& r
);
144 ScSortParam( const ScSubTotalParam
& rSub
, const ScSortParam
& rOld
);
146 ScSortParam( const ScQueryParam
&, SCCOL nCol
);
149 ScSortParam
& operator= ( const ScSortParam
& r
);
150 bool operator== ( const ScSortParam
& rOther
) const;
154 sal_uInt16
GetSortKeyCount() const { return maKeyState
.size(); }
157 struct ScSortInfo final
159 ScRefCellValue maCell
;
163 class ScSortInfoArray
169 ScRefCellValue maCell
;
170 const sc::CellTextAttr
* mpAttr
;
171 const ScPostIt
* mpNote
;
172 std::vector
<SdrObject
*> maDrawObjects
;
173 CellAttributeHolder maPattern
;
175 Cell() : mpAttr(nullptr), mpNote(nullptr), maPattern() {}
180 std::vector
<Cell
> maCells
;
185 explicit Row( size_t nColSize
) : maCells(nColSize
, Cell()), mbHidden(false), mbFiltered(false) {}
188 typedef std::vector
<Row
> RowsType
;
191 std::unique_ptr
<RowsType
> mpRows
; /// row-wise data table for sort by row operation.
193 std::vector
<std::unique_ptr
<ScSortInfo
[]>> mvppInfo
;
195 SCCOLROW mnLastIndex
; /// index of last non-empty cell position.
197 std::vector
<SCCOLROW
> maOrderIndices
;
202 ScSortInfoArray(const ScSortInfoArray
&) = delete;
203 const ScSortInfoArray
& operator=(const ScSortInfoArray
&) = delete;
205 ScSortInfoArray( sal_uInt16 nSorts
, SCCOLROW nInd1
, SCCOLROW nInd2
) :
212 SCSIZE
nCount( nInd2
- nInd1
+ 1 );
215 for ( sal_uInt16 nSort
= 0; nSort
< nSorts
; nSort
++ )
217 mvppInfo
[nSort
].reset(new ScSortInfo
[nCount
]);
221 for (size_t i
= 0; i
< nCount
; ++i
)
222 maOrderIndices
.push_back(i
+nStart
);
225 void SetKeepQuery( bool b
) { mbKeepQuery
= b
; }
227 bool IsKeepQuery() const { return mbKeepQuery
; }
229 void SetUpdateRefs( bool b
) { mbUpdateRefs
= b
; }
231 bool IsUpdateRefs() const { return mbUpdateRefs
; }
234 * Call this only during normal sorting, not from reordering.
236 std::unique_ptr
<ScSortInfo
[]> const & GetFirstArray() const
242 * Call this only during normal sorting, not from reordering.
244 ScSortInfo
& Get( sal_uInt16 nSort
, SCCOLROW nInd
)
246 return mvppInfo
[nSort
][ nInd
- nStart
];
250 * Call this only during normal sorting, not from reordering.
252 void Swap( SCCOLROW nInd1
, SCCOLROW nInd2
)
254 if (nInd1
== nInd2
) // avoid self-move-assign
256 SCSIZE n1
= static_cast<SCSIZE
>(nInd1
- nStart
);
257 SCSIZE n2
= static_cast<SCSIZE
>(nInd2
- nStart
);
258 for ( sal_uInt16 nSort
= 0; nSort
< static_cast<sal_uInt16
>(mvppInfo
.size()); nSort
++ )
260 auto & ppInfo
= mvppInfo
[nSort
];
261 std::swap(ppInfo
[n1
], ppInfo
[n2
]);
264 std::swap(maOrderIndices
[n1
], maOrderIndices
[n2
]);
268 // Swap rows in data table.
269 RowsType
& rRows
= *mpRows
;
270 std::swap(rRows
[n1
], rRows
[n2
]);
274 void SetOrderIndices( std::vector
<SCCOLROW
>&& rIndices
)
276 maOrderIndices
= std::move(rIndices
);
280 * @param rIndices indices are actual row positions on the sheet, not an
281 * offset from the top row.
283 void ReorderByRow( const std::vector
<SCCOLROW
>& rIndices
)
288 RowsType
& rRows
= *mpRows
;
290 std::vector
<SCCOLROW
> aOrderIndices2
;
291 aOrderIndices2
.reserve(rIndices
.size());
294 aRows2
.reserve(rRows
.size());
296 for (const auto& rIndex
: rIndices
)
298 size_t nPos
= rIndex
- nStart
; // switch to an offset to top row.
299 aRows2
.push_back(rRows
[nPos
]);
300 aOrderIndices2
.push_back(maOrderIndices
[nPos
]);
304 maOrderIndices
.swap(aOrderIndices2
);
307 sal_uInt16
GetUsedSorts() const { return mvppInfo
.size(); }
309 SCCOLROW
GetStart() const { return nStart
; }
310 SCCOLROW
GetLast() const { return mnLastIndex
; }
312 const std::vector
<SCCOLROW
>& GetOrderIndices() const { return maOrderIndices
; }
314 RowsType
& InitDataRows( size_t nRowSize
, size_t nColSize
)
316 mpRows
.reset(new RowsType
);
317 mpRows
->resize(nRowSize
, Row(nColSize
));
321 RowsType
* GetDataRows()
332 * This sort range already takes into account the presence or absence of
333 * header row / column i.e. if a header row / column is present, it
334 * excludes that row / column.
337 ScDataAreaExtras maDataAreaExtras
;
340 * List of original column / row positions after reordering.
342 std::vector
<SCCOLROW
> maOrderIndices
;
344 bool mbHiddenFiltered
;
349 * Reorder the position indices such that it can be used to undo the
350 * original reordering.
356 , mbHiddenFiltered(false)
357 , mbUpdateRefs(false)
358 , mbHasHeaders(false)
365 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */