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"
27 #include "cellvalue.hxx"
28 #include "mtvelements.hxx"
29 #include <vcl/vclptr.hxx>
39 class ScFlatBoolRowSegments
;
40 struct ScInterpreterContext
;
42 struct ScDBQueryParamBase
;
44 struct ScDBQueryParamInternal
;
45 struct ScDBQueryParamMatrix
;
47 struct ScInterpreterContext
;
48 enum class SvNumFormatType
: sal_Int16
;
50 class ScValueIterator
// walk through all values in an area
52 typedef sc::CellStoreType::const_position_type PositionType
;
55 ScInterpreterContext
* pContext
;
56 const ScAttrArray
* pAttrArray
;
57 sal_uInt32 nNumFormat
; // for CalcAsShown
58 sal_uInt32 nNumFmtIndex
;
64 SubtotalFlags mnSubTotalFlags
;
65 SvNumFormatType nNumFmtType
;
70 const sc::CellStoreType
* mpCells
;
71 PositionType maCurPos
;
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
, FormulaError
& rErr
);
86 ScDocument
* pDocument
, const ScRange
& rRange
, SubtotalFlags nSubTotalFlags
= SubtotalFlags::NONE
,
87 bool bTextAsZero
= false );
89 void GetCurNumFmtInfo( const ScInterpreterContext
& rContext
, SvNumFormatType
& nType
, sal_uInt32
& nIndex
);
91 /// Does NOT reset rValue if no value found!
92 bool GetFirst( double& rValue
, FormulaError
& rErr
);
94 /// Does NOT reset rValue if no value found!
95 bool GetNext( double& rValue
, FormulaError
& rErr
);
97 void SetInterpreterContext( ScInterpreterContext
* context
) { pContext
= context
; }
100 class ScDBQueryDataIterator
107 FormulaError mnError
;
114 static const sc::CellStoreType
* GetColumnCellStore(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
115 static const ScAttrArray
* GetAttrArrayByCol(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
116 static bool IsQueryValid(ScDocument
& rDoc
, const ScQueryParam
& rParam
, SCTAB nTab
, SCROW nRow
, const ScRefCellValue
* pCell
);
122 virtual ~DataAccess() = 0;
123 virtual bool getCurrent(Value
& rValue
) = 0;
124 virtual bool getFirst(Value
& rValue
) = 0;
125 virtual bool getNext(Value
& rValue
) = 0;
128 class DataAccessInternal
: public DataAccess
130 typedef std::pair
<sc::CellStoreType::const_iterator
,size_t> PositionType
;
132 DataAccessInternal(ScDBQueryParamInternal
* pParam
, ScDocument
* pDoc
, const ScInterpreterContext
& rContext
);
133 virtual ~DataAccessInternal() override
;
134 virtual bool getCurrent(Value
& rValue
) override
;
135 virtual bool getFirst(Value
& rValue
) override
;
136 virtual bool getNext(Value
& rValue
) override
;
142 const sc::CellStoreType
* mpCells
;
143 PositionType maCurPos
;
144 ScDBQueryParamInternal
* mpParam
;
146 const ScInterpreterContext
& mrContext
;
147 const ScAttrArray
* pAttrArray
;
148 sal_uInt32 nNumFormat
; // for CalcAsShown
149 sal_uInt32 nNumFmtIndex
;
154 SvNumFormatType nNumFmtType
;
158 class DataAccessMatrix
: public DataAccess
161 DataAccessMatrix(ScDBQueryParamMatrix
* pParam
);
162 virtual ~DataAccessMatrix() override
;
163 virtual bool getCurrent(Value
& rValue
) override
;
164 virtual bool getFirst(Value
& rValue
) override
;
165 virtual bool getNext(Value
& rValue
) override
;
168 bool isValidQuery(SCROW mnRow
, const ScMatrix
& rMat
) const;
170 ScDBQueryParamMatrix
* mpParam
;
175 ::std::unique_ptr
<ScDBQueryParamBase
> mpParam
;
176 ::std::unique_ptr
<DataAccess
> mpData
;
179 ScDBQueryDataIterator(ScDocument
* pDocument
, const ScInterpreterContext
& rContext
, 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
);
186 class ScFormulaGroupIterator
194 std::vector
<sc::FormulaGroupEntry
> maEntries
;
197 ScFormulaGroupIterator( ScDocument
* pDoc
);
199 sc::FormulaGroupEntry
* first();
200 sc::FormulaGroupEntry
* next();
204 * Walk through all cells in an area. For SubTotal and Aggregate depending on mnSubTotalFlags.
208 typedef std::pair
<sc::CellStoreType::const_iterator
, size_t> PositionType
;
211 ScAddress maStartPos
;
215 PositionType maCurColPos
;
216 SubtotalFlags mnSubTotalFlags
;
218 ScRefCellValue maCurCell
;
222 void setPos(size_t nPos
);
224 const ScColumn
* getColumn() const;
230 ScCellIterator( ScDocument
* pDoc
, const ScRange
& rRange
, SubtotalFlags nSubTotalFlags
= SubtotalFlags::NONE
);
232 const ScAddress
& GetPos() const { return maCurPos
; }
234 CellType
getType() const { return maCurCell
.meType
;}
235 OUString
getString();
236 const EditTextObject
* getEditText() const { return maCurCell
.mpEditText
;}
237 ScFormulaCell
* getFormulaCell() { return maCurCell
.mpFormula
;}
238 const ScFormulaCell
* getFormulaCell() const { return maCurCell
.mpFormula
;}
239 ScCellValue
getCellValue() const;
240 const ScRefCellValue
& getRefCellValue() const { return maCurCell
;}
242 bool hasString() const;
243 bool hasEmptyData() const;
244 bool isEmpty() const;
245 bool equalsWithoutFormat( const ScAddress
& rPos
) const;
251 class ScQueryCellIterator
// walk through all non-empty cells in an area
253 enum StopOnMismatchBits
255 nStopOnMismatchDisabled
= 0x00,
256 nStopOnMismatchEnabled
= 0x01,
257 nStopOnMismatchOccurred
= 0x02,
258 nStopOnMismatchExecuted
= nStopOnMismatchEnabled
| nStopOnMismatchOccurred
261 enum TestEqualConditionBits
263 nTestEqualConditionDisabled
= 0x00,
264 nTestEqualConditionEnabled
= 0x01,
265 nTestEqualConditionMatched
= 0x02,
266 nTestEqualConditionFulfilled
= nTestEqualConditionEnabled
| nTestEqualConditionMatched
269 typedef sc::CellStoreType::const_position_type PositionType
;
270 PositionType maCurPos
;
272 std::unique_ptr
<ScQueryParam
> mpParam
;
274 const ScInterpreterContext
& mrContext
;
278 sal_uInt8 nStopOnMismatch
;
279 sal_uInt8 nTestEqualCondition
;
281 bool bIgnoreMismatchOnLeadingStrings
;
283 /** Initialize position for new column. */
289 /* Only works if no regular expression is involved, only
290 searches for rows in one column, and only the first
291 query entry is considered with simple conditions
292 SC_LESS_EQUAL (sorted ascending) or SC_GREATER_EQUAL
293 (sorted descending). Check these things before
294 invocation! Delivers a starting point, continue with
295 GetThis() and GetNext() afterwards. Introduced for
296 FindEqualOrSortedLastInRange()
301 ScQueryCellIterator(ScDocument
* pDocument
, const ScInterpreterContext
& rContext
, SCTAB nTable
,
302 const ScQueryParam
& aParam
, bool bMod
);
303 // when !bMod, the QueryParam has to be filled
307 SCCOL
GetCol() { return nCol
; }
308 SCROW
GetRow() { return nRow
; }
310 // increments all Entry.nField, if column
311 // changes, for ScInterpreter ScHLookup()
312 void SetAdvanceQueryParamEntryField( bool bVal
)
313 { bAdvanceQuery
= bVal
; }
314 void AdvanceQueryParamEntryField();
316 /** If set, iterator stops on first non-matching cell
317 content. May be used in SC_LESS_EQUAL queries where a
318 cell range is assumed to be sorted; stops on first
319 value being greater than the queried value and
320 GetFirst()/GetNext() return NULL. StoppedOnMismatch()
322 However, the iterator's conditions are not set to end
323 all queries, GetCol() and GetRow() return values for
324 the non-matching cell, further GetNext() calls may be
326 void SetStopOnMismatch( bool bVal
)
328 nStopOnMismatch
= sal::static_int_cast
<sal_uInt8
>(bVal
? nStopOnMismatchEnabled
:
329 nStopOnMismatchDisabled
);
331 bool StoppedOnMismatch() const
332 { return nStopOnMismatch
== nStopOnMismatchExecuted
; }
334 /** If set, an additional test for SC_EQUAL condition is
335 executed in ScTable::ValidQuery() if SC_LESS_EQUAL or
336 SC_GREATER_EQUAL conditions are to be tested. May be
337 used where a cell range is assumed to be sorted to stop
338 if an equal match is found. */
339 void SetTestEqualCondition( bool bVal
)
341 nTestEqualCondition
= sal::static_int_cast
<sal_uInt8
>(bVal
?
342 nTestEqualConditionEnabled
:
343 nTestEqualConditionDisabled
);
345 bool IsEqualConditionFulfilled() const
346 { return nTestEqualCondition
== nTestEqualConditionFulfilled
; }
348 /** In a range assumed to be sorted find either the last of
349 a sequence of equal entries or the last being less than
350 (or greater than) the queried value. Used by the
351 interpreter for [HV]?LOOKUP() and MATCH(). Column and
352 row position of the found entry are returned, otherwise
355 The search does 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
, SCROW
& nFoundRow
);
369 class ScDocAttrIterator
// all attribute areas
378 std::unique_ptr
<ScAttrIterator
>
382 ScDocAttrIterator(ScDocument
* pDocument
, SCTAB nTable
,
383 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
384 ~ScDocAttrIterator();
386 const ScPatternAttr
* GetNext( SCCOL
& rCol
, SCROW
& rRow1
, SCROW
& rRow2
);
389 class ScAttrRectIterator
// all attribute areas, including areas stretching
390 // across more than one column
400 std::unique_ptr
<ScAttrIterator
>
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
416 sc::CellStoreType::const_iterator maPos
;
417 sc::CellStoreType::const_iterator maEnd
;
421 std::vector
<ColParam
>::iterator maColPos
;
422 std::vector
<ColParam
> maColPositions
;
432 ScRefCellValue maCurCell
;
436 ScHorizontalCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
437 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
438 ~ScHorizontalCellIterator();
440 ScRefCellValue
* GetNext( SCCOL
& rCol
, SCROW
& rRow
);
441 bool GetPos( SCCOL
& rCol
, SCROW
& rRow
);
442 /// Set a(nother) sheet and (re)init.
443 void SetTab( SCTAB nTab
);
448 bool SkipInvalidInRow();
449 SCROW
FindNextNonEmptyRow();
452 /** Row-wise value iterator. */
453 class ScHorizontalValueIterator
457 const ScAttrArray
*pAttrArray
;
458 std::unique_ptr
<ScHorizontalCellIterator
>
460 sal_uInt32 nNumFormat
; // for CalcAsShown
470 ScHorizontalValueIterator( ScDocument
* pDocument
,
471 const ScRange
& rRange
);
472 ~ScHorizontalValueIterator();
473 /// Does NOT reset rValue if no value found!
474 bool GetNext( double& rValue
, FormulaError
& rErr
);
477 // returns all areas with non-default formatting (horizontal)
479 class ScHorizontalAttrIterator
489 std::unique_ptr
<SCROW
[]> pNextEnd
;
490 std::unique_ptr
<SCCOL
[]> pHorizEnd
;
491 std::unique_ptr
<SCSIZE
[]> pIndices
;
492 std::unique_ptr
<const ScPatternAttr
*[]>
499 void InitForNextRow(bool bInitialization
);
500 bool InitForNextAttr();
503 ScHorizontalAttrIterator( ScDocument
* pDocument
, SCTAB nTable
,
504 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
505 ~ScHorizontalAttrIterator();
507 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow
);
510 // returns non-empty cells and areas with formatting (horizontal)
512 class SC_DLLPUBLIC ScUsedAreaIterator
515 ScHorizontalCellIterator aCellIter
;
516 ScHorizontalAttrIterator aAttrIter
;
523 ScRefCellValue
* pCell
;
527 const ScPatternAttr
* pPattern
;
529 SCCOL nFoundStartCol
; // results after GetNext
532 const ScPatternAttr
* pFoundPattern
;
534 ScRefCellValue maFoundCell
;
537 ScUsedAreaIterator( ScDocument
* pDocument
, SCTAB nTable
,
538 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
539 ~ScUsedAreaIterator();
543 SCCOL
GetStartCol() const { return nFoundStartCol
; }
544 SCCOL
GetEndCol() const { return nFoundEndCol
; }
545 SCROW
GetRow() const { return nFoundRow
; }
546 const ScPatternAttr
* GetPattern() const { return pFoundPattern
; }
547 const ScRefCellValue
& GetCell() const { return maFoundCell
;}
550 class ScRowBreakIterator
553 static constexpr SCROW NOT_FOUND
= -1;
555 explicit ScRowBreakIterator(::std::set
<SCROW
>& rBreaks
);
560 ::std::set
<SCROW
>& mrBreaks
;
561 ::std::set
<SCROW
>::const_iterator maItr
;
562 ::std::set
<SCROW
>::const_iterator maEnd
;
565 class ScDocRowHeightUpdater
571 std::shared_ptr
<ScFlatBoolRowSegments
> mpRanges
;
573 TabRanges(SCTAB nTab
);
577 * Passing a NULL pointer to pTabRangesArray forces the heights of all
578 * rows in all tables to be updated.
580 explicit ScDocRowHeightUpdater(
581 ScDocument
& rDoc
, OutputDevice
* pOutDev
, double fPPTX
, double fPPTY
,
582 const ::std::vector
<TabRanges
>* pTabRangesArray
);
591 VclPtr
<OutputDevice
> mpOutDev
;
594 const ::std::vector
<TabRanges
>* mpTabRangesArray
;
599 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */