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 INCLUDED_SC_INC_DOCITER_HXX
21 #define INCLUDED_SC_INC_DOCITER_HXX
23 #include "address.hxx"
24 #include <tools/solar.h>
27 #include "cellvalue.hxx"
28 #include "mtvelements.hxx"
34 #include <boost/shared_ptr.hpp>
35 #include <boost/scoped_ptr.hpp>
42 class ScFlatBoolRowSegments
;
44 struct ScDBQueryParamBase
;
46 struct ScDBQueryParamInternal
;
47 struct ScDBQueryParamMatrix
;
50 class ScValueIterator
// walk through all values in an area
52 typedef sc::CellStoreType::const_position_type PositionType
;
55 const ScAttrArray
* pAttrArray
;
56 sal_uLong nNumFormat
; // for CalcAsShown
57 sal_uLong nNumFmtIndex
;
69 const sc::CellStoreType
* mpCells
;
70 PositionType maCurPos
;
75 void SetPos(size_t nPos
);
78 * See if the cell at the current position is a non-empty cell. If not,
79 * move to the next non-empty cell position.
81 bool GetThis( double& rValue
, sal_uInt16
& rErr
);
86 ScDocument
* pDocument
, const ScRange
& rRange
, bool bSTotal
= false,
87 bool bTextAsZero
= false );
89 void GetCurNumFmtInfo( short& nType
, sal_uLong
& nIndex
);
91 /// Does NOT reset rValue if no value found!
92 bool GetFirst( double& rValue
, sal_uInt16
& rErr
);
94 /// Does NOT reset rValue if no value found!
95 bool GetNext( double& rValue
, sal_uInt16
& rErr
);
98 class ScDBQueryDataIterator
112 static const sc::CellStoreType
* GetColumnCellStore(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
113 static const ScAttrArray
* GetAttrArrayByCol(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
114 static bool IsQueryValid(ScDocument
& rDoc
, const ScQueryParam
& rParam
, SCTAB nTab
, SCROW nRow
, ScRefCellValue
* pCell
);
119 DataAccess(const ScDBQueryDataIterator
* pParent
);
120 virtual ~DataAccess() = 0;
121 virtual bool getCurrent(Value
& rValue
) = 0;
122 virtual bool getFirst(Value
& rValue
) = 0;
123 virtual bool getNext(Value
& rValue
) = 0;
125 const ScDBQueryDataIterator
* mpParent
;
128 class DataAccessInternal
: public DataAccess
130 typedef std::pair
<sc::CellStoreType::const_iterator
,size_t> PositionType
;
132 DataAccessInternal(const ScDBQueryDataIterator
* pParent
, ScDBQueryParamInternal
* pParam
, ScDocument
* pDoc
);
133 virtual ~DataAccessInternal();
134 virtual bool getCurrent(Value
& rValue
) SAL_OVERRIDE
;
135 virtual bool getFirst(Value
& rValue
) SAL_OVERRIDE
;
136 virtual bool getNext(Value
& rValue
) SAL_OVERRIDE
;
142 const sc::CellStoreType
* mpCells
;
143 PositionType maCurPos
;
144 ScDBQueryParamInternal
* mpParam
;
146 const ScAttrArray
* pAttrArray
;
147 sal_uLong nNumFormat
; // for CalcAsShown
148 sal_uLong nNumFmtIndex
;
157 class DataAccessMatrix
: public DataAccess
160 DataAccessMatrix(const ScDBQueryDataIterator
* pParent
, ScDBQueryParamMatrix
* pParam
);
161 virtual ~DataAccessMatrix();
162 virtual bool getCurrent(Value
& rValue
) SAL_OVERRIDE
;
163 virtual bool getFirst(Value
& rValue
) SAL_OVERRIDE
;
164 virtual bool getNext(Value
& rValue
) SAL_OVERRIDE
;
167 bool isValidQuery(SCROW mnRow
, const ScMatrix
& rMat
) const;
169 ScDBQueryParamMatrix
* mpParam
;
175 ::std::auto_ptr
<ScDBQueryParamBase
> mpParam
;
176 ::std::auto_ptr
<DataAccess
> mpData
;
179 ScDBQueryDataIterator(ScDocument
* pDocument
, ScDBQueryParamBase
* pParam
);
180 /// Does NOT reset rValue if no value found!
181 bool GetFirst(Value
& rValue
);
182 /// Does NOT reset rValue if no value found!
183 bool GetNext(Value
& rValue
);
187 * Walk through all cells in an area. For SubTotal no hidden and no
192 typedef std::pair
<sc::CellStoreType::const_iterator
, size_t> PositionType
;
195 ScAddress maStartPos
;
199 PositionType maCurColPos
;
202 ScRefCellValue maCurCell
;
206 void setPos(size_t nPos
);
208 const ScColumn
* getColumn() const;
214 ScCellIterator( ScDocument
* pDoc
, const ScRange
& rRange
, bool bSTotal
= false );
216 const ScAddress
& GetPos() const { return maCurPos
; }
218 CellType
getType() const;
219 OUString
getString();
220 const EditTextObject
* getEditText() const;
221 ScFormulaCell
* getFormulaCell();
222 const ScFormulaCell
* getFormulaCell() const;
223 ScCellValue
getCellValue() const;
224 const ScRefCellValue
& getRefCellValue() const;
226 bool hasString() const;
227 bool hasEmptyData() const;
228 bool isEmpty() const;
229 bool equalsWithoutFormat( const ScAddress
& rPos
) const;
235 class ScQueryCellIterator
// walk through all non-empty cells in an area
237 enum StopOnMismatchBits
239 nStopOnMismatchDisabled
= 0x00,
240 nStopOnMismatchEnabled
= 0x01,
241 nStopOnMismatchOccurred
= 0x02,
242 nStopOnMismatchExecuted
= nStopOnMismatchEnabled
| nStopOnMismatchOccurred
245 enum TestEqualConditionBits
247 nTestEqualConditionDisabled
= 0x00,
248 nTestEqualConditionEnabled
= 0x01,
249 nTestEqualConditionMatched
= 0x02,
250 nTestEqualConditionFulfilled
= nTestEqualConditionEnabled
| nTestEqualConditionMatched
253 typedef sc::CellStoreType::const_position_type PositionType
;
254 PositionType maCurPos
;
256 boost::scoped_ptr
<ScQueryParam
> mpParam
;
258 const ScAttrArray
* pAttrArray
;
259 sal_uLong nNumFormat
;
264 sal_uInt8 nStopOnMismatch
;
265 sal_uInt8 nTestEqualCondition
;
267 bool bIgnoreMismatchOnLeadingStrings
;
269 /** Initialize position for new column. */
275 /* Only works if no regular expression is involved, only
276 searches for rows in one column, and only the first
277 query entry is considered with simple conditions
278 SC_LESS_EQUAL (sorted ascending) or SC_GREATER_EQUAL
279 (sorted descending). Check these things before
280 invocation! Delivers a starting point, continue with
281 GetThis() and GetNext() afterwards. Introduced for
282 FindEqualOrSortedLastInRange()
287 ScQueryCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
288 const ScQueryParam
& aParam
, bool bMod
= true);
289 // for bMod = FALSE the QueryParam has to be filled
293 SCCOL
GetCol() { return nCol
; }
294 SCROW
GetRow() { return nRow
; }
296 // increments all Entry.nField, if column
297 // changes, for ScInterpreter ScHLookup()
298 void SetAdvanceQueryParamEntryField( bool bVal
)
299 { bAdvanceQuery
= bVal
; }
300 void AdvanceQueryParamEntryField();
302 /** If set, iterator stops on first non-matching cell
303 content. May be used in SC_LESS_EQUAL queries where a
304 cell range is assumed to be sorted; stops on first
305 value being greater than the queried value and
306 GetFirst()/GetNext() return NULL. StoppedOnMismatch()
308 However, the iterator's conditions are not set to end
309 all queries, GetCol() and GetRow() return values for
310 the non-matching cell, further GetNext() calls may be
312 void SetStopOnMismatch( bool bVal
)
314 nStopOnMismatch
= sal::static_int_cast
<sal_uInt8
>(bVal
? nStopOnMismatchEnabled
:
315 nStopOnMismatchDisabled
);
317 bool StoppedOnMismatch() const
318 { return nStopOnMismatch
== nStopOnMismatchExecuted
; }
320 /** If set, an additional test for SC_EQUAL condition is
321 executed in ScTable::ValidQuery() if SC_LESS_EQUAL or
322 SC_GREATER_EQUAL conditions are to be tested. May be
323 used where a cell range is assumed to be sorted to stop
324 if an equal match is found. */
325 void SetTestEqualCondition( bool bVal
)
327 nTestEqualCondition
= sal::static_int_cast
<sal_uInt8
>(bVal
?
328 nTestEqualConditionEnabled
:
329 nTestEqualConditionDisabled
);
331 bool IsEqualConditionFulfilled() const
332 { return nTestEqualCondition
== nTestEqualConditionFulfilled
; }
334 /** In a range assumed to be sorted find either the last of
335 a sequence of equal entries or the last being less than
336 (or greater than) the queried value. Used by the
337 interpreter for [HV]?LOOKUP() and MATCH(). Column and
338 row position of the found entry are returned, otherwise
341 @param bSearchForEqualAfterMismatch
342 Continue searching for an equal entry even if the
343 last entry matching the range was found, in case
344 the data is not sorted. Is always done if regular
345 expressions are involved.
347 @param bIgnoreMismatchOnLeadingStrings
348 Normally strings are sorted behind numerical
349 values. If this parameter is true, the search does
350 not stop when encountering a string and does not
351 assume that no values follow anymore.
352 If querying for a string a mismatch on the first
353 entry, e.g. column header, is ignored.
355 @ATTENTION! StopOnMismatch, TestEqualCondition and
356 the internal IgnoreMismatchOnLeadingStrings and query
357 params are in an undefined state upon return! The
358 iterator is not usable anymore except for obtaining the
361 bool FindEqualOrSortedLastInRange( SCCOL
& nFoundCol
,
362 SCROW
& nFoundRow
, bool bSearchForEqualAfterMismatch
= false,
363 bool bIgnoreMismatchOnLeadingStrings
= true );
366 class ScDocAttrIterator
// all attribute areas
375 ScAttrIterator
* pColIter
;
378 ScDocAttrIterator(ScDocument
* pDocument
, SCTAB nTable
,
379 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
380 ~ScDocAttrIterator();
382 const ScPatternAttr
* GetNext( SCCOL
& rCol
, SCROW
& rRow1
, SCROW
& rRow2
);
385 class ScAttrRectIterator
// all attribute areas, including areas stretching
386 // across more then one column
396 ScAttrIterator
* pColIter
;
399 ScAttrRectIterator(ScDocument
* pDocument
, SCTAB nTable
,
400 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
401 ~ScAttrRectIterator();
404 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow1
, SCROW
& rRow2
);
407 class ScHorizontalCellIterator
// walk through all non empty cells in an area
411 sc::CellStoreType::const_iterator maPos
;
412 sc::CellStoreType::const_iterator maEnd
;
416 std::vector
<ColParam
>::iterator maColPos
;
417 std::vector
<ColParam
> maColPositions
;
426 SCSIZE
* pNextIndices
;
429 ScRefCellValue maCurCell
;
433 ScHorizontalCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
434 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
435 ~ScHorizontalCellIterator();
437 ScRefCellValue
* GetNext( SCCOL
& rCol
, SCROW
& rRow
);
438 bool GetPos( SCCOL
& rCol
, SCROW
& rRow
);
439 /// Set a(nother) sheet and (re)init.
440 void SetTab( SCTAB nTab
);
445 bool SkipInvalidInRow();
446 SCROW
FindNextNonEmptyRow();
450 /** Row-wise value iterator. */
451 class ScHorizontalValueIterator
455 const ScAttrArray
*pAttrArray
;
456 ScHorizontalCellIterator
*pCellIter
;
457 sal_uLong nNumFormat
; // for CalcAsShown
458 sal_uLong nNumFmtIndex
;
472 ScHorizontalValueIterator( ScDocument
* pDocument
,
473 const ScRange
& rRange
,
474 bool bSTotal
= false,
475 bool bTextAsZero
= false );
476 ~ScHorizontalValueIterator();
477 /// Does NOT reset rValue if no value found!
478 bool GetNext( double& rValue
, sal_uInt16
& rErr
);
481 // returns all areas with non-default formatting (horizontal)
484 class ScHorizontalAttrIterator
496 const ScPatternAttr
** ppPatterns
;
502 ScHorizontalAttrIterator( ScDocument
* pDocument
, SCTAB nTable
,
503 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
504 ~ScHorizontalAttrIterator();
506 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow
);
510 // returns non-empty cells and areas with formatting (horizontal)
513 class SC_DLLPUBLIC ScUsedAreaIterator
516 ScHorizontalCellIterator aCellIter
;
517 ScHorizontalAttrIterator aAttrIter
;
524 ScRefCellValue
* pCell
;
528 const ScPatternAttr
* pPattern
;
530 SCCOL nFoundStartCol
; // results after GetNext
533 const ScPatternAttr
* pFoundPattern
;
535 ScRefCellValue maFoundCell
;
538 ScUsedAreaIterator( ScDocument
* pDocument
, SCTAB nTable
,
539 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
540 ~ScUsedAreaIterator();
544 SCCOL
GetStartCol() const { return nFoundStartCol
; }
545 SCCOL
GetEndCol() const { return nFoundEndCol
; }
546 SCROW
GetRow() const { return nFoundRow
; }
547 const ScPatternAttr
* GetPattern() const { return pFoundPattern
; }
548 const ScRefCellValue
& GetCell() const;
551 class ScRowBreakIterator
554 static SCROW NOT_FOUND
;
556 explicit ScRowBreakIterator(::std::set
<SCROW
>& rBreaks
);
561 ::std::set
<SCROW
>& mrBreaks
;
562 ::std::set
<SCROW
>::const_iterator maItr
;
563 ::std::set
<SCROW
>::const_iterator maEnd
;
566 class ScDocRowHeightUpdater
572 ::boost::shared_ptr
<ScFlatBoolRowSegments
> mpRanges
;
574 TabRanges(SCTAB nTab
);
578 * Passing a NULL pointer to pTabRangesArray forces the heights of all
579 * rows in all tables to be updated.
581 explicit ScDocRowHeightUpdater(
582 ScDocument
& rDoc
, OutputDevice
* pOutDev
, double fPPTX
, double fPPTY
,
583 const ::std::vector
<TabRanges
>* pTabRangesArray
= NULL
);
592 OutputDevice
* mpOutDev
;
595 const ::std::vector
<TabRanges
>* mpTabRangesArray
;
602 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */