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 "formulagroup.hxx"
25 #include <tools/solar.h>
28 #include "cellvalue.hxx"
29 #include "mtvelements.hxx"
30 #include <vcl/vclptr.hxx>
41 class ScFlatBoolRowSegments
;
43 struct ScDBQueryParamBase
;
45 struct ScDBQueryParamInternal
;
46 struct ScDBQueryParamMatrix
;
49 class ScValueIterator
// walk through all values in an area
51 typedef sc::CellStoreType::const_position_type PositionType
;
54 const ScAttrArray
* pAttrArray
;
55 sal_uLong nNumFormat
; // for CalcAsShown
56 sal_uLong nNumFmtIndex
;
62 sal_uInt16 mnSubTotalFlags
;
68 const sc::CellStoreType
* mpCells
;
69 PositionType maCurPos
;
74 void SetPos(size_t nPos
);
77 * See if the cell at the current position is a non-empty cell. If not,
78 * move to the next non-empty cell position.
80 bool GetThis( double& rValue
, sal_uInt16
& rErr
);
85 ScDocument
* pDocument
, const ScRange
& rRange
, sal_uInt16 nSubTotalFlags
= 0x00,
86 bool bTextAsZero
= false );
88 void GetCurNumFmtInfo( short& nType
, sal_uLong
& nIndex
);
90 /// Does NOT reset rValue if no value found!
91 bool GetFirst( double& rValue
, sal_uInt16
& rErr
);
93 /// Does NOT reset rValue if no value found!
94 bool GetNext( double& rValue
, sal_uInt16
& rErr
);
97 class ScDBQueryDataIterator
111 static const sc::CellStoreType
* GetColumnCellStore(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
112 static const ScAttrArray
* GetAttrArrayByCol(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
113 static bool IsQueryValid(ScDocument
& rDoc
, const ScQueryParam
& rParam
, SCTAB nTab
, SCROW nRow
, ScRefCellValue
* pCell
);
119 virtual ~DataAccess() = 0;
120 virtual bool getCurrent(Value
& rValue
) = 0;
121 virtual bool getFirst(Value
& rValue
) = 0;
122 virtual bool getNext(Value
& rValue
) = 0;
125 class DataAccessInternal
: public DataAccess
127 typedef std::pair
<sc::CellStoreType::const_iterator
,size_t> PositionType
;
129 DataAccessInternal(ScDBQueryParamInternal
* pParam
, ScDocument
* pDoc
);
130 virtual ~DataAccessInternal();
131 virtual bool getCurrent(Value
& rValue
) override
;
132 virtual bool getFirst(Value
& rValue
) override
;
133 virtual bool getNext(Value
& rValue
) override
;
139 const sc::CellStoreType
* mpCells
;
140 PositionType maCurPos
;
141 ScDBQueryParamInternal
* mpParam
;
143 const ScAttrArray
* pAttrArray
;
144 sal_uLong nNumFormat
; // for CalcAsShown
145 sal_uLong nNumFmtIndex
;
154 class DataAccessMatrix
: public DataAccess
157 DataAccessMatrix(ScDBQueryParamMatrix
* pParam
);
158 virtual ~DataAccessMatrix();
159 virtual bool getCurrent(Value
& rValue
) override
;
160 virtual bool getFirst(Value
& rValue
) override
;
161 virtual bool getNext(Value
& rValue
) override
;
164 bool isValidQuery(SCROW mnRow
, const ScMatrix
& rMat
) const;
166 ScDBQueryParamMatrix
* mpParam
;
172 ::std::unique_ptr
<ScDBQueryParamBase
> mpParam
;
173 ::std::unique_ptr
<DataAccess
> mpData
;
176 ScDBQueryDataIterator(ScDocument
* pDocument
, ScDBQueryParamBase
* pParam
);
177 /// Does NOT reset rValue if no value found!
178 bool GetFirst(Value
& rValue
);
179 /// Does NOT reset rValue if no value found!
180 bool GetNext(Value
& rValue
);
183 class ScFormulaGroupIterator
191 std::vector
<sc::FormulaGroupEntry
> maEntries
;
194 ScFormulaGroupIterator( ScDocument
* pDoc
);
196 sc::FormulaGroupEntry
* first();
197 sc::FormulaGroupEntry
* next();
201 * Walk through all cells in an area. For SubTotal and Aggregate depending on mnSubTotalFlags.
205 typedef std::pair
<sc::CellStoreType::const_iterator
, size_t> PositionType
;
208 ScAddress maStartPos
;
212 PositionType maCurColPos
;
213 sal_uInt16 mnSubTotalFlags
;
215 ScRefCellValue maCurCell
;
219 void setPos(size_t nPos
);
221 const ScColumn
* getColumn() const;
227 ScCellIterator( ScDocument
* pDoc
, const ScRange
& rRange
, sal_uInt16 nSubTotalFlags
= 0x00 );
229 const ScAddress
& GetPos() const { return maCurPos
; }
231 CellType
getType() const { return maCurCell
.meType
;}
232 OUString
getString();
233 const EditTextObject
* getEditText() const { return maCurCell
.mpEditText
;}
234 ScFormulaCell
* getFormulaCell() { return maCurCell
.mpFormula
;}
235 const ScFormulaCell
* getFormulaCell() const { return maCurCell
.mpFormula
;}
236 ScCellValue
getCellValue() const;
237 const ScRefCellValue
& getRefCellValue() const { return maCurCell
;}
239 bool hasString() const;
240 bool hasEmptyData() const;
241 bool isEmpty() const;
242 bool equalsWithoutFormat( const ScAddress
& rPos
) const;
248 class ScQueryCellIterator
// walk through all non-empty cells in an area
250 enum StopOnMismatchBits
252 nStopOnMismatchDisabled
= 0x00,
253 nStopOnMismatchEnabled
= 0x01,
254 nStopOnMismatchOccurred
= 0x02,
255 nStopOnMismatchExecuted
= nStopOnMismatchEnabled
| nStopOnMismatchOccurred
258 enum TestEqualConditionBits
260 nTestEqualConditionDisabled
= 0x00,
261 nTestEqualConditionEnabled
= 0x01,
262 nTestEqualConditionMatched
= 0x02,
263 nTestEqualConditionFulfilled
= nTestEqualConditionEnabled
| nTestEqualConditionMatched
266 typedef sc::CellStoreType::const_position_type PositionType
;
267 PositionType maCurPos
;
269 std::unique_ptr
<ScQueryParam
> mpParam
;
271 const ScAttrArray
* pAttrArray
;
272 sal_uLong nNumFormat
;
277 sal_uInt8 nStopOnMismatch
;
278 sal_uInt8 nTestEqualCondition
;
280 bool bIgnoreMismatchOnLeadingStrings
;
282 /** Initialize position for new column. */
288 /* Only works if no regular expression is involved, only
289 searches for rows in one column, and only the first
290 query entry is considered with simple conditions
291 SC_LESS_EQUAL (sorted ascending) or SC_GREATER_EQUAL
292 (sorted descending). Check these things before
293 invocation! Delivers a starting point, continue with
294 GetThis() and GetNext() afterwards. Introduced for
295 FindEqualOrSortedLastInRange()
300 ScQueryCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
301 const ScQueryParam
& aParam
, bool bMod
= true);
302 // for bMod = FALSE the QueryParam has to be filled
306 SCCOL
GetCol() { return nCol
; }
307 SCROW
GetRow() { return nRow
; }
309 // increments all Entry.nField, if column
310 // changes, for ScInterpreter ScHLookup()
311 void SetAdvanceQueryParamEntryField( bool bVal
)
312 { bAdvanceQuery
= bVal
; }
313 void AdvanceQueryParamEntryField();
315 /** If set, iterator stops on first non-matching cell
316 content. May be used in SC_LESS_EQUAL queries where a
317 cell range is assumed to be sorted; stops on first
318 value being greater than the queried value and
319 GetFirst()/GetNext() return NULL. StoppedOnMismatch()
321 However, the iterator's conditions are not set to end
322 all queries, GetCol() and GetRow() return values for
323 the non-matching cell, further GetNext() calls may be
325 void SetStopOnMismatch( bool bVal
)
327 nStopOnMismatch
= sal::static_int_cast
<sal_uInt8
>(bVal
? nStopOnMismatchEnabled
:
328 nStopOnMismatchDisabled
);
330 bool StoppedOnMismatch() const
331 { return nStopOnMismatch
== nStopOnMismatchExecuted
; }
333 /** If set, an additional test for SC_EQUAL condition is
334 executed in ScTable::ValidQuery() if SC_LESS_EQUAL or
335 SC_GREATER_EQUAL conditions are to be tested. May be
336 used where a cell range is assumed to be sorted to stop
337 if an equal match is found. */
338 void SetTestEqualCondition( bool bVal
)
340 nTestEqualCondition
= sal::static_int_cast
<sal_uInt8
>(bVal
?
341 nTestEqualConditionEnabled
:
342 nTestEqualConditionDisabled
);
344 bool IsEqualConditionFulfilled() const
345 { return nTestEqualCondition
== nTestEqualConditionFulfilled
; }
347 /** In a range assumed to be sorted find either the last of
348 a sequence of equal entries or the last being less than
349 (or greater than) the queried value. Used by the
350 interpreter for [HV]?LOOKUP() and MATCH(). Column and
351 row position of the found entry are returned, otherwise
354 The search does not stop when encountering a string and does not
355 assume that no values follow anymore.
356 If querying for a string a mismatch on the first
357 entry, e.g. column header, is ignored.
359 @ATTENTION! StopOnMismatch, TestEqualCondition and
360 the internal IgnoreMismatchOnLeadingStrings and query
361 params are in an undefined state upon return! The
362 iterator is not usable anymore except for obtaining the
365 bool FindEqualOrSortedLastInRange( SCCOL
& nFoundCol
, SCROW
& nFoundRow
);
368 class ScDocAttrIterator
// all attribute areas
377 ScAttrIterator
* pColIter
;
380 ScDocAttrIterator(ScDocument
* pDocument
, SCTAB nTable
,
381 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
382 ~ScDocAttrIterator();
384 const ScPatternAttr
* GetNext( SCCOL
& rCol
, SCROW
& rRow1
, SCROW
& rRow2
);
387 class ScAttrRectIterator
// all attribute areas, including areas stretching
388 // across more than one column
398 ScAttrIterator
* pColIter
;
401 ScAttrRectIterator(ScDocument
* pDocument
, SCTAB nTable
,
402 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
403 ~ScAttrRectIterator();
406 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow1
, SCROW
& rRow2
);
409 class ScHorizontalCellIterator
// walk through all non empty cells in an area
413 sc::CellStoreType::const_iterator maPos
;
414 sc::CellStoreType::const_iterator maEnd
;
418 std::vector
<ColParam
>::iterator maColPos
;
419 std::vector
<ColParam
> maColPositions
;
428 SCSIZE
* pNextIndices
;
431 ScRefCellValue maCurCell
;
435 ScHorizontalCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
436 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
437 ~ScHorizontalCellIterator();
439 ScRefCellValue
* GetNext( SCCOL
& rCol
, SCROW
& rRow
);
440 bool GetPos( SCCOL
& rCol
, SCROW
& rRow
);
441 /// Set a(nother) sheet and (re)init.
442 void SetTab( SCTAB nTab
);
447 bool SkipInvalidInRow();
448 SCROW
FindNextNonEmptyRow();
451 /** Row-wise value iterator. */
452 class ScHorizontalValueIterator
456 const ScAttrArray
*pAttrArray
;
457 ScHorizontalCellIterator
*pCellIter
;
458 sal_uLong nNumFormat
; // for CalcAsShown
459 sal_uLong nNumFmtIndex
;
472 ScHorizontalValueIterator( ScDocument
* pDocument
,
473 const ScRange
& rRange
);
474 ~ScHorizontalValueIterator();
475 /// Does NOT reset rValue if no value found!
476 bool GetNext( double& rValue
, sal_uInt16
& rErr
);
479 // returns all areas with non-default formatting (horizontal)
481 class ScHorizontalAttrIterator
494 const ScPatternAttr
** ppPatterns
;
501 void InitForNextRow(bool bInitialization
);
502 bool InitForNextAttr();
505 ScHorizontalAttrIterator( ScDocument
* pDocument
, SCTAB nTable
,
506 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
507 ~ScHorizontalAttrIterator();
509 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow
);
512 // returns non-empty cells and areas with formatting (horizontal)
514 class SC_DLLPUBLIC ScUsedAreaIterator
517 ScHorizontalCellIterator aCellIter
;
518 ScHorizontalAttrIterator aAttrIter
;
525 ScRefCellValue
* pCell
;
529 const ScPatternAttr
* pPattern
;
531 SCCOL nFoundStartCol
; // results after GetNext
534 const ScPatternAttr
* pFoundPattern
;
536 ScRefCellValue maFoundCell
;
539 ScUsedAreaIterator( ScDocument
* pDocument
, SCTAB nTable
,
540 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
541 ~ScUsedAreaIterator();
545 SCCOL
GetStartCol() const { return nFoundStartCol
; }
546 SCCOL
GetEndCol() const { return nFoundEndCol
; }
547 SCROW
GetRow() const { return nFoundRow
; }
548 const ScPatternAttr
* GetPattern() const { return pFoundPattern
; }
549 const ScRefCellValue
& GetCell() const { return maFoundCell
;}
552 class ScRowBreakIterator
555 static SCROW NOT_FOUND
;
557 explicit ScRowBreakIterator(::std::set
<SCROW
>& rBreaks
);
562 ::std::set
<SCROW
>& mrBreaks
;
563 ::std::set
<SCROW
>::const_iterator maItr
;
564 ::std::set
<SCROW
>::const_iterator maEnd
;
567 class ScDocRowHeightUpdater
573 std::shared_ptr
<ScFlatBoolRowSegments
> mpRanges
;
575 TabRanges(SCTAB nTab
);
579 * Passing a NULL pointer to pTabRangesArray forces the heights of all
580 * rows in all tables to be updated.
582 explicit ScDocRowHeightUpdater(
583 ScDocument
& rDoc
, OutputDevice
* pOutDev
, double fPPTX
, double fPPTY
,
584 const ::std::vector
<TabRanges
>* pTabRangesArray
= nullptr);
593 VclPtr
<OutputDevice
> mpOutDev
;
596 const ::std::vector
<TabRanges
>* mpTabRangesArray
;
601 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */