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 .
20 #ifndef SC_DOCITER_HXX
21 #define SC_DOCITER_HXX
23 #include "address.hxx"
24 #include <tools/solar.h>
32 #include <boost/shared_ptr.hpp>
33 #include <boost/scoped_ptr.hpp>
41 class ScFlatBoolRowSegments
;
43 struct ScDBQueryParamBase
;
45 struct ScDBQueryParamInternal
;
46 struct ScDBQueryParamMatrix
;
48 class ScDocumentIterator
// walk through all non-empty cells
55 const ScPatternAttr
* pDefPattern
;
61 const ScPatternAttr
* pPattern
;
71 ScDocumentIterator( ScDocument
* pDocument
, SCTAB nStartTable
, SCTAB nEndTable
);
72 ~ScDocumentIterator();
77 ScBaseCell
* GetCell();
78 const ScPatternAttr
* GetPattern();
79 void GetPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
);
82 class ScValueIterator
// walk through all values in an area
87 const ScAttrArray
* pAttrArray
;
88 sal_uLong nNumFormat
; // for CalcAsShown
89 sal_uLong nNumFmtIndex
;
109 bool GetThis(double& rValue
, sal_uInt16
& rErr
);
112 ScValueIterator(ScDocument
* pDocument
,
113 const ScRange
& rRange
, bool bSTotal
= false,
114 bool bTextAsZero
= false );
115 void GetCurNumFmtInfo( short& nType
, sal_uLong
& nIndex
);
116 /// Does NOT reset rValue if no value found!
117 bool GetFirst(double& rValue
, sal_uInt16
& rErr
);
118 /// Does NOT reset rValue if no value found!
119 bool GetNext(double& rValue
, sal_uInt16
& rErr
)
121 return bNextValid
? ( bNextValid
= false, rValue
= fNextValue
,
122 rErr
= 0, nRow
= nNextRow
,
123 ++nColRow
, bNumValid
= false, true )
124 : ( ++nRow
, GetThis(rValue
, rErr
) );
128 class ScDBQueryDataIterator
133 ::rtl::OUString maString
;
142 static SCROW
GetRowByColEntryIndex(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
, SCSIZE nColRow
);
143 static ScBaseCell
* GetCellByColEntryIndex(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
, SCSIZE nColRow
);
144 static ScAttrArray
* GetAttrArrayByCol(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
145 static bool IsQueryValid(ScDocument
& rDoc
, const ScQueryParam
& rParam
, SCTAB nTab
, SCROW nRow
, ScBaseCell
* pCell
);
146 static SCSIZE
SearchColEntryIndex(ScDocument
& rDoc
, SCTAB nTab
, SCROW nRow
, SCCOL nCol
);
151 DataAccess(const ScDBQueryDataIterator
* pParent
);
152 virtual ~DataAccess() = 0;
153 virtual bool getCurrent(Value
& rValue
) = 0;
154 virtual bool getFirst(Value
& rValue
) = 0;
155 virtual bool getNext(Value
& rValue
) = 0;
157 const ScDBQueryDataIterator
* mpParent
;
160 class DataAccessInternal
: public DataAccess
163 DataAccessInternal(const ScDBQueryDataIterator
* pParent
, ScDBQueryParamInternal
* pParam
, ScDocument
* pDoc
);
164 virtual ~DataAccessInternal();
165 virtual bool getCurrent(Value
& rValue
);
166 virtual bool getFirst(Value
& rValue
);
167 virtual bool getNext(Value
& rValue
);
170 ScDBQueryParamInternal
* mpParam
;
172 const ScAttrArray
* pAttrArray
;
173 sal_uLong nNumFormat
; // for CalcAsShown
174 sal_uLong nNumFmtIndex
;
184 class DataAccessMatrix
: public DataAccess
187 DataAccessMatrix(const ScDBQueryDataIterator
* pParent
, ScDBQueryParamMatrix
* pParam
);
188 virtual ~DataAccessMatrix();
189 virtual bool getCurrent(Value
& rValue
);
190 virtual bool getFirst(Value
& rValue
);
191 virtual bool getNext(Value
& rValue
);
194 bool isValidQuery(SCROW mnRow
, const ScMatrix
& rMat
) const;
196 ScDBQueryParamMatrix
* mpParam
;
202 ::std::auto_ptr
<ScDBQueryParamBase
> mpParam
;
203 ::std::auto_ptr
<DataAccess
> mpData
;
206 ScDBQueryDataIterator(ScDocument
* pDocument
, ScDBQueryParamBase
* pParam
);
207 /// Does NOT reset rValue if no value found!
208 bool GetFirst(Value
& rValue
);
209 /// Does NOT reset rValue if no value found!
210 bool GetNext(Value
& rValue
);
213 class ScCellIterator
// walk through all cells in an area
214 { // for SubTotal no hidden and no sub-total lines
229 ScBaseCell
* GetThis();
231 ScCellIterator(ScDocument
* pDocument
,
232 SCCOL nSCol
, SCROW nSRow
, SCTAB nSTab
,
233 SCCOL nECol
, SCROW nERow
, SCTAB nETab
,
234 bool bSTotal
= false);
235 ScCellIterator(ScDocument
* pDocument
,
236 const ScRange
& rRange
, bool bSTotal
= false);
237 ScBaseCell
* GetFirst();
238 ScBaseCell
* GetNext();
239 SCCOL
GetCol() const { return nCol
; }
240 SCROW
GetRow() const { return nRow
; }
241 SCTAB
GetTab() const { return nTab
; }
242 ScAddress
GetPos() const { return ScAddress( nCol
, nRow
, nTab
); }
245 class ScQueryCellIterator
// walk through all non-empty cells in an area
247 enum StopOnMismatchBits
249 nStopOnMismatchDisabled
= 0x00,
250 nStopOnMismatchEnabled
= 0x01,
251 nStopOnMismatchOccurred
= 0x02,
252 nStopOnMismatchExecuted
= nStopOnMismatchEnabled
| nStopOnMismatchOccurred
255 enum TestEqualConditionBits
257 nTestEqualConditionDisabled
= 0x00,
258 nTestEqualConditionEnabled
= 0x01,
259 nTestEqualConditionMatched
= 0x02,
260 nTestEqualConditionFulfilled
= nTestEqualConditionEnabled
| nTestEqualConditionMatched
264 boost::scoped_ptr
<ScQueryParam
> mpParam
;
266 const ScAttrArray
* pAttrArray
;
267 sal_uLong nNumFormat
;
273 sal_uInt8 nStopOnMismatch
;
274 sal_uInt8 nTestEqualCondition
;
276 bool bIgnoreMismatchOnLeadingStrings
;
278 ScBaseCell
* GetThis();
280 /* Only works if no regular expression is involved, only
281 searches for rows in one column, and only the first
282 query entry is considered with simple conditions
283 SC_LESS_EQUAL (sorted ascending) or SC_GREATER_EQUAL
284 (sorted descending). Check these things before
285 invocation! Delivers a starting point, continue with
286 GetThis() and GetNext() afterwards. Introduced for
287 FindEqualOrSortedLastInRange()
289 ScBaseCell
* BinarySearch();
292 ScQueryCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
293 const ScQueryParam
& aParam
, bool bMod
= true);
294 // for bMod = FALSE the QueryParam has to be filled
296 ScBaseCell
* GetFirst();
297 ScBaseCell
* GetNext();
298 SCCOL
GetCol() { return nCol
; }
299 SCROW
GetRow() { return nRow
; }
301 // increments all Entry.nField, if column
302 // changes, for ScInterpreter ScHLookup()
303 void SetAdvanceQueryParamEntryField( bool bVal
)
304 { bAdvanceQuery
= bVal
; }
305 void AdvanceQueryParamEntryField();
307 /** If set, iterator stops on first non-matching cell
308 content. May be used in SC_LESS_EQUAL queries where a
309 cell range is assumed to be sorted; stops on first
310 value being greater than the queried value and
311 GetFirst()/GetNext() return NULL. StoppedOnMismatch()
313 However, the iterator's conditions are not set to end
314 all queries, GetCol() and GetRow() return values for
315 the non-matching cell, further GetNext() calls may be
317 void SetStopOnMismatch( bool bVal
)
319 nStopOnMismatch
= sal::static_int_cast
<sal_uInt8
>(bVal
? nStopOnMismatchEnabled
:
320 nStopOnMismatchDisabled
);
322 bool StoppedOnMismatch() const
323 { return nStopOnMismatch
== nStopOnMismatchExecuted
; }
325 /** If set, an additional test for SC_EQUAL condition is
326 executed in ScTable::ValidQuery() if SC_LESS_EQUAL or
327 SC_GREATER_EQUAL conditions are to be tested. May be
328 used where a cell range is assumed to be sorted to stop
329 if an equal match is found. */
330 void SetTestEqualCondition( bool bVal
)
332 nTestEqualCondition
= sal::static_int_cast
<sal_uInt8
>(bVal
?
333 nTestEqualConditionEnabled
:
334 nTestEqualConditionDisabled
);
336 bool IsEqualConditionFulfilled() const
337 { return nTestEqualCondition
== nTestEqualConditionFulfilled
; }
339 /** In a range assumed to be sorted find either the last of
340 a sequence of equal entries or the last being less than
341 (or greater than) the queried value. Used by the
342 interpreter for [HV]?LOOKUP() and MATCH(). Column and
343 row position of the found entry are returned, otherwise
346 @param bSearchForEqualAfterMismatch
347 Continue searching for an equal entry even if the
348 last entry matching the range was found, in case
349 the data is not sorted. Is always done if regular
350 expressions are involved.
352 @param bIgnoreMismatchOnLeadingStrings
353 Normally strings are sorted behind numerical
354 values. If this parameter is true, the search does
355 not stop when encountering a string and does not
356 assume that no values follow anymore.
357 If querying for a string a mismatch on the first
358 entry, e.g. column header, is ignored.
360 @ATTENTION! StopOnMismatch, TestEqualCondition and
361 the internal IgnoreMismatchOnLeadingStrings and query
362 params are in an undefined state upon return! The
363 iterator is not usable anymore except for obtaining the
366 bool FindEqualOrSortedLastInRange( SCCOL
& nFoundCol
,
367 SCROW
& nFoundRow
, bool bSearchForEqualAfterMismatch
= false,
368 bool bIgnoreMismatchOnLeadingStrings
= true );
371 class ScDocAttrIterator
// all attribute areas
380 ScAttrIterator
* pColIter
;
383 ScDocAttrIterator(ScDocument
* pDocument
, SCTAB nTable
,
384 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
385 ~ScDocAttrIterator();
387 const ScPatternAttr
* GetNext( SCCOL
& rCol
, SCROW
& rRow1
, SCROW
& rRow2
);
390 class ScAttrRectIterator
// all attribute areas, including areas stretching
391 // across more then one column
401 ScAttrIterator
* pColIter
;
404 ScAttrRectIterator(ScDocument
* pDocument
, SCTAB nTable
,
405 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
406 ~ScAttrRectIterator();
409 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow1
, SCROW
& rRow2
);
412 class ScHorizontalCellIterator
// walk through all non empty cells in an area
422 SCSIZE
* pNextIndices
;
428 ScHorizontalCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
429 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
430 ~ScHorizontalCellIterator();
432 ScBaseCell
* GetNext( SCCOL
& rCol
, SCROW
& rRow
);
433 bool ReturnNext( SCCOL
& rCol
, SCROW
& rRow
);
434 /// Set a(nother) sheet and (re)init.
435 void SetTab( SCTAB nTab
);
442 /** Row-wise value iterator. */
443 class ScHorizontalValueIterator
447 const ScAttrArray
*pAttrArray
;
448 ScHorizontalCellIterator
*pCellIter
;
449 sal_uLong nNumFormat
; // for CalcAsShown
450 sal_uLong nNumFmtIndex
;
464 ScHorizontalValueIterator( ScDocument
* pDocument
,
465 const ScRange
& rRange
,
466 bool bSTotal
= false,
467 bool bTextAsZero
= false );
468 ~ScHorizontalValueIterator();
469 /// Does NOT reset rValue if no value found!
470 bool GetNext( double& rValue
, sal_uInt16
& rErr
);
475 // returns all areas with non-default formatting (horizontal)
478 class ScHorizontalAttrIterator
490 const ScPatternAttr
** ppPatterns
;
496 ScHorizontalAttrIterator( ScDocument
* pDocument
, SCTAB nTable
,
497 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
498 ~ScHorizontalAttrIterator();
500 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow
);
504 // returns non-empty cells and areas with formatting (horizontal)
507 class SC_DLLPUBLIC ScUsedAreaIterator
510 ScHorizontalCellIterator aCellIter
;
511 ScHorizontalAttrIterator aAttrIter
;
518 const ScBaseCell
* pCell
;
522 const ScPatternAttr
* pPattern
;
524 SCCOL nFoundStartCol
; // results after GetNext
527 const ScPatternAttr
* pFoundPattern
;
528 const ScBaseCell
* pFoundCell
;
531 ScUsedAreaIterator( ScDocument
* pDocument
, SCTAB nTable
,
532 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
533 ~ScUsedAreaIterator();
537 SCCOL
GetStartCol() const { return nFoundStartCol
; }
538 SCCOL
GetEndCol() const { return nFoundEndCol
; }
539 SCROW
GetRow() const { return nFoundRow
; }
540 const ScPatternAttr
* GetPattern() const { return pFoundPattern
; }
541 const ScBaseCell
* GetCell() const { return pFoundCell
; }
544 class ScRowBreakIterator
547 static SCROW NOT_FOUND
;
549 explicit ScRowBreakIterator(::std::set
<SCROW
>& rBreaks
);
554 ::std::set
<SCROW
>& mrBreaks
;
555 ::std::set
<SCROW
>::const_iterator maItr
;
556 ::std::set
<SCROW
>::const_iterator maEnd
;
559 class ScDocRowHeightUpdater
565 ::boost::shared_ptr
<ScFlatBoolRowSegments
> mpRanges
;
567 TabRanges(SCTAB nTab
);
571 * Passing a NULL pointer to pTabRangesArray forces the heights of all
572 * rows in all tables to be updated.
574 explicit ScDocRowHeightUpdater(
575 ScDocument
& rDoc
, OutputDevice
* pOutDev
, double fPPTX
, double fPPTY
,
576 const ::std::vector
<TabRanges
>* pTabRangesArray
= NULL
);
585 OutputDevice
* mpOutDev
;
588 const ::std::vector
<TabRanges
>* mpTabRangesArray
;
595 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */