Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "sortparam.hxx"
21 : #include "global.hxx"
22 : #include "address.hxx"
23 : #include "queryparam.hxx"
24 : #include "subtotalparam.hxx"
25 :
26 : #include <osl/diagnose.h>
27 :
28 2566 : ScSortParam::ScSortParam()
29 : {
30 2566 : Clear();
31 2566 : }
32 :
33 857 : ScSortParam::ScSortParam( const ScSortParam& r ) :
34 : nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nUserIndex(r.nUserIndex),
35 : bHasHeader(r.bHasHeader),bByRow(r.bByRow),bCaseSens(r.bCaseSens),
36 : bNaturalSort(r.bNaturalSort),bUserDef(r.bUserDef),
37 : bIncludePattern(r.bIncludePattern),bInplace(r.bInplace),
38 : nDestTab(r.nDestTab),nDestCol(r.nDestCol),nDestRow(r.nDestRow),
39 : maKeyState( r.maKeyState ),
40 : aCollatorLocale( r.aCollatorLocale ), aCollatorAlgorithm( r.aCollatorAlgorithm ),
41 857 : nCompatHeader( r.nCompatHeader )
42 : {
43 857 : }
44 :
45 3364 : ScSortParam::~ScSortParam() {}
46 :
47 2566 : void ScSortParam::Clear()
48 : {
49 : ScSortKeyState aKeyState;
50 :
51 2566 : nCol1=nCol2=nDestCol = 0;
52 2566 : nRow1=nRow2=nDestRow = 0;
53 2566 : nCompatHeader = 2;
54 2566 : nDestTab = 0;
55 2566 : nUserIndex = 0;
56 2566 : bHasHeader=bCaseSens=bUserDef=bNaturalSort = false;
57 2566 : bByRow=bIncludePattern=bInplace = true;
58 2566 : aCollatorLocale = ::com::sun::star::lang::Locale();
59 2566 : aCollatorAlgorithm.clear();
60 :
61 2566 : aKeyState.bDoSort = false;
62 2566 : aKeyState.nField = 0;
63 2566 : aKeyState.bAscending = true;
64 :
65 : // Initialize to default size
66 2566 : maKeyState.assign( DEFSORT, aKeyState );
67 2566 : }
68 :
69 51 : ScSortParam& ScSortParam::operator=( const ScSortParam& r )
70 : {
71 51 : nCol1 = r.nCol1;
72 51 : nRow1 = r.nRow1;
73 51 : nCol2 = r.nCol2;
74 51 : nRow2 = r.nRow2;
75 51 : nUserIndex = r.nUserIndex;
76 51 : bHasHeader = r.bHasHeader;
77 51 : bByRow = r.bByRow;
78 51 : bCaseSens = r.bCaseSens;
79 51 : bNaturalSort = r.bNaturalSort;
80 51 : bUserDef = r.bUserDef;
81 51 : bIncludePattern = r.bIncludePattern;
82 51 : bInplace = r.bInplace;
83 51 : nDestTab = r.nDestTab;
84 51 : nDestCol = r.nDestCol;
85 51 : nDestRow = r.nDestRow;
86 51 : maKeyState = r.maKeyState;
87 51 : aCollatorLocale = r.aCollatorLocale;
88 51 : aCollatorAlgorithm = r.aCollatorAlgorithm;
89 51 : nCompatHeader = r.nCompatHeader;
90 :
91 51 : return *this;
92 : }
93 :
94 10 : bool ScSortParam::operator==( const ScSortParam& rOther ) const
95 : {
96 10 : bool bEqual = false;
97 : // Number of Sorts the same?
98 10 : sal_uInt16 nLast = 0;
99 10 : sal_uInt16 nOtherLast = 0;
100 10 : sal_uInt16 nSortSize = GetSortKeyCount();
101 :
102 10 : if ( !maKeyState.empty() )
103 : {
104 10 : while ( maKeyState[nLast++].bDoSort && nLast < nSortSize ) ;
105 10 : nLast--;
106 : }
107 :
108 10 : if ( !rOther.maKeyState.empty() )
109 : {
110 10 : while ( rOther.maKeyState[nOtherLast++].bDoSort && nOtherLast < nSortSize ) ;
111 10 : nOtherLast--;
112 : }
113 :
114 10 : if ( (nLast == nOtherLast)
115 10 : && (nCol1 == rOther.nCol1)
116 10 : && (nRow1 == rOther.nRow1)
117 10 : && (nCol2 == rOther.nCol2)
118 10 : && (nRow2 == rOther.nRow2)
119 10 : && (bHasHeader == rOther.bHasHeader)
120 10 : && (bByRow == rOther.bByRow)
121 10 : && (bCaseSens == rOther.bCaseSens)
122 10 : && (bNaturalSort == rOther.bNaturalSort)
123 10 : && (bUserDef == rOther.bUserDef)
124 10 : && (nUserIndex == rOther.nUserIndex)
125 10 : && (bIncludePattern == rOther.bIncludePattern)
126 10 : && (bInplace == rOther.bInplace)
127 10 : && (nDestTab == rOther.nDestTab)
128 10 : && (nDestCol == rOther.nDestCol)
129 10 : && (nDestRow == rOther.nDestRow)
130 10 : && (aCollatorLocale.Language == rOther.aCollatorLocale.Language)
131 10 : && (aCollatorLocale.Country == rOther.aCollatorLocale.Country)
132 10 : && (aCollatorLocale.Variant == rOther.aCollatorLocale.Variant)
133 10 : && (aCollatorAlgorithm == rOther.aCollatorAlgorithm)
134 20 : && ( !maKeyState.empty() || !rOther.maKeyState.empty() )
135 : )
136 : {
137 10 : bEqual = true;
138 20 : for ( sal_uInt16 i=0; i<=nLast && bEqual; i++ )
139 20 : bEqual = ( maKeyState[i].nField == rOther.maKeyState[i].nField ) &&
140 20 : ( maKeyState[i].bAscending == rOther.maKeyState[i].bAscending );
141 : }
142 10 : if ( maKeyState.empty() && rOther.maKeyState.empty() )
143 0 : bEqual = true;
144 :
145 10 : return bEqual;
146 : }
147 :
148 1 : ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld ) :
149 : nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),nUserIndex(rSub.nUserIndex),
150 : bHasHeader(true),bByRow(true),bCaseSens(rSub.bCaseSens),bNaturalSort(rOld.bNaturalSort),
151 : bUserDef(rSub.bUserDef),bIncludePattern(rSub.bIncludePattern),
152 : bInplace(true),
153 : nDestTab(0),nDestCol(0),nDestRow(0),
154 : aCollatorLocale( rOld.aCollatorLocale ), aCollatorAlgorithm( rOld.aCollatorAlgorithm ),
155 1 : nCompatHeader( rOld.nCompatHeader )
156 : {
157 : sal_uInt16 i;
158 :
159 : // first the groups from the partial results
160 1 : if (rSub.bDoSort)
161 4 : for (i=0; i<MAXSUBTOTAL; i++)
162 3 : if (rSub.bGroupActive[i])
163 : {
164 : ScSortKeyState key;
165 1 : key.bDoSort = true;
166 1 : key.nField = rSub.nField[i];
167 1 : key.bAscending = rSub.bAscending;
168 1 : maKeyState.push_back(key);
169 : }
170 :
171 : // then the old settings
172 4 : for (i=0; i < rOld.GetSortKeyCount(); i++)
173 3 : if (rOld.maKeyState[i].bDoSort)
174 : {
175 0 : SCCOLROW nThisField = rOld.maKeyState[i].nField;
176 0 : bool bDouble = false;
177 0 : for (sal_uInt16 j = 0; j < GetSortKeyCount(); j++)
178 0 : if ( maKeyState[j].nField == nThisField )
179 0 : bDouble = true;
180 0 : if (!bDouble) // do not enter a field twice
181 : {
182 : ScSortKeyState key;
183 0 : key.bDoSort = true;
184 0 : key.nField = nThisField;
185 0 : key.bAscending = rOld.maKeyState[i].bAscending;
186 0 : maKeyState.push_back(key);
187 : }
188 : }
189 1 : }
190 :
191 0 : ScSortParam::ScSortParam( const ScQueryParam& rParam, SCCOL nCol ) :
192 : nCol1(nCol),nRow1(rParam.nRow1),nCol2(nCol),nRow2(rParam.nRow2),nUserIndex(0),
193 : bHasHeader(rParam.bHasHeader),bByRow(true),bCaseSens(rParam.bCaseSens),
194 : bNaturalSort(false),
195 : //TODO: what about Locale and Algorithm?
196 : bUserDef(false),bIncludePattern(false),
197 : bInplace(true),
198 0 : nDestTab(0),nDestCol(0),nDestRow(0), nCompatHeader(2)
199 : {
200 : ScSortKeyState aKeyState;
201 0 : aKeyState.bDoSort = true;
202 0 : aKeyState.nField = nCol;
203 0 : aKeyState.bAscending = true;
204 :
205 0 : maKeyState.push_back( aKeyState );
206 :
207 : // Set the rest
208 0 : aKeyState.bDoSort = false;
209 0 : aKeyState.nField = 0;
210 :
211 0 : for (sal_uInt16 i=1; i<GetSortKeyCount(); i++)
212 0 : maKeyState.push_back( aKeyState );
213 0 : }
214 :
215 1 : void ScSortParam::MoveToDest()
216 : {
217 1 : if (!bInplace)
218 : {
219 1 : SCsCOL nDifX = ((SCsCOL) nDestCol) - ((SCsCOL) nCol1);
220 1 : SCsROW nDifY = ((SCsROW) nDestRow) - ((SCsROW) nRow1);
221 :
222 1 : nCol1 = sal::static_int_cast<SCCOL>( nCol1 + nDifX );
223 1 : nRow1 = sal::static_int_cast<SCROW>( nRow1 + nDifY );
224 1 : nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nDifX );
225 1 : nRow2 = sal::static_int_cast<SCROW>( nRow2 + nDifY );
226 4 : for (sal_uInt16 i=0; i<GetSortKeyCount(); i++)
227 3 : if (bByRow)
228 3 : maKeyState[i].nField += nDifX;
229 : else
230 0 : maKeyState[i].nField += nDifY;
231 :
232 1 : bInplace = true;
233 : }
234 : else
235 : {
236 : OSL_FAIL("MoveToDest, bInplace == TRUE");
237 : }
238 1 : }
239 :
240 : namespace sc {
241 :
242 : namespace {
243 :
244 : struct ReorderIndex
245 : {
246 : struct LessByPos2 : std::binary_function<ReorderIndex, ReorderIndex, bool>
247 : {
248 133 : bool operator() ( const ReorderIndex& r1, const ReorderIndex& r2 ) const
249 : {
250 133 : return r1.mnPos2 < r2.mnPos2;
251 : }
252 : };
253 :
254 : SCCOLROW mnPos1;
255 : SCCOLROW mnPos2;
256 :
257 70 : ReorderIndex( SCCOLROW nPos1, SCCOLROW nPos2 ) : mnPos1(nPos1), mnPos2(nPos2) {}
258 : };
259 :
260 : }
261 :
262 13 : void ReorderParam::reverse()
263 : {
264 : SCCOLROW nStart;
265 13 : if (mbByRow)
266 11 : nStart = maSortRange.aStart.Row();
267 : else
268 2 : nStart = maSortRange.aStart.Col();
269 :
270 13 : size_t n = maOrderIndices.size();
271 13 : std::vector<ReorderIndex> aBucket;
272 13 : aBucket.reserve(n);
273 83 : for (size_t i = 0; i < n; ++i)
274 : {
275 70 : SCCOLROW nPos1 = i + nStart;
276 70 : SCCOLROW nPos2 = maOrderIndices[i];
277 70 : aBucket.push_back(ReorderIndex(nPos1, nPos2));
278 : }
279 :
280 13 : std::sort(aBucket.begin(), aBucket.end(), ReorderIndex::LessByPos2());
281 26 : std::vector<SCCOLROW> aNew;
282 13 : aNew.reserve(n);
283 83 : for (size_t i = 0; i < n; ++i)
284 70 : aNew.push_back(aBucket[i].mnPos1);
285 :
286 26 : maOrderIndices.swap(aNew);
287 13 : }
288 :
289 156 : }
290 :
291 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|