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 "queryparam.hxx"
30 #include <vcl/outdev.hxx>
31 #include <vcl/vclptr.hxx>
41 class ScFlatBoolRowSegments
;
43 struct ScDBQueryParamBase
;
45 struct ScDBQueryParamInternal
;
46 struct ScDBQueryParamMatrix
;
49 struct ScInterpreterContext
;
50 enum class SvNumFormatType
: sal_Int16
;
52 class ScValueIterator
// walk through all values in an area
54 typedef sc::CellStoreType::const_position_type PositionType
;
57 ScInterpreterContext
* pContext
;
58 const ScAttrArray
* pAttrArray
;
59 sal_uInt32 nNumFormat
; // for CalcAsShown
60 sal_uInt32 nNumFmtIndex
;
66 SubtotalFlags
const mnSubTotalFlags
;
67 SvNumFormatType nNumFmtType
;
69 bool const bCalcAsShown
;
70 bool const bTextAsZero
;
72 const sc::CellStoreType
* mpCells
;
73 PositionType maCurPos
;
80 * See if the cell at the current position is a non-empty cell. If not,
81 * move to the next non-empty cell position.
83 bool GetThis( double& rValue
, FormulaError
& rErr
);
88 ScDocument
* pDocument
, const ScRange
& rRange
, SubtotalFlags nSubTotalFlags
= SubtotalFlags::NONE
,
89 bool bTextAsZero
= false );
91 void GetCurNumFmtInfo( const ScInterpreterContext
& rContext
, SvNumFormatType
& nType
, sal_uInt32
& nIndex
);
93 /// Does NOT reset rValue if no value found!
94 bool GetFirst( double& rValue
, FormulaError
& rErr
);
96 /// Does NOT reset rValue if no value found!
97 bool GetNext( double& rValue
, FormulaError
& rErr
);
99 void SetInterpreterContext( ScInterpreterContext
* context
) { pContext
= context
; }
102 class ScDBQueryDataIterator
109 FormulaError mnError
;
116 static const sc::CellStoreType
* GetColumnCellStore(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
117 static const ScAttrArray
* GetAttrArrayByCol(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
118 static bool IsQueryValid(ScDocument
& rDoc
, const ScQueryParam
& rParam
, SCTAB nTab
, SCROW nRow
, const ScRefCellValue
* pCell
);
124 virtual ~DataAccess() = 0;
125 virtual bool getCurrent(Value
& rValue
) = 0;
126 virtual bool getFirst(Value
& rValue
) = 0;
127 virtual bool getNext(Value
& rValue
) = 0;
130 class DataAccessInternal final
: public DataAccess
132 typedef std::pair
<sc::CellStoreType::const_iterator
,size_t> PositionType
;
134 DataAccessInternal(ScDBQueryParamInternal
* pParam
, ScDocument
* pDoc
, const ScInterpreterContext
& rContext
);
135 virtual ~DataAccessInternal() override
;
136 virtual bool getCurrent(Value
& rValue
) override
;
137 virtual bool getFirst(Value
& rValue
) override
;
138 virtual bool getNext(Value
& rValue
) override
;
144 const sc::CellStoreType
* mpCells
;
145 PositionType maCurPos
;
146 ScDBQueryParamInternal
* mpParam
;
148 const ScInterpreterContext
& mrContext
;
149 const ScAttrArray
* pAttrArray
;
150 sal_uInt32 nNumFormat
; // for CalcAsShown
151 sal_uInt32 nNumFmtIndex
;
156 SvNumFormatType nNumFmtType
;
157 bool const bCalcAsShown
;
160 class DataAccessMatrix final
: public DataAccess
163 DataAccessMatrix(ScDBQueryParamMatrix
* pParam
);
164 virtual ~DataAccessMatrix() override
;
165 virtual bool getCurrent(Value
& rValue
) override
;
166 virtual bool getFirst(Value
& rValue
) override
;
167 virtual bool getNext(Value
& rValue
) override
;
170 bool isValidQuery(SCROW mnRow
, const ScMatrix
& rMat
) const;
172 ScDBQueryParamMatrix
* mpParam
;
177 ::std::unique_ptr
<ScDBQueryParamBase
> mpParam
;
178 ::std::unique_ptr
<DataAccess
> mpData
;
181 ScDBQueryDataIterator(ScDocument
* pDocument
, const ScInterpreterContext
& rContext
, std::unique_ptr
<ScDBQueryParamBase
> pParam
);
182 /// Does NOT reset rValue if no value found!
183 bool GetFirst(Value
& rValue
);
184 /// Does NOT reset rValue if no value found!
185 bool GetNext(Value
& rValue
);
188 class ScFormulaGroupIterator
196 std::vector
<sc::FormulaGroupEntry
> maEntries
;
199 ScFormulaGroupIterator( ScDocument
* pDoc
);
201 sc::FormulaGroupEntry
* first();
202 sc::FormulaGroupEntry
* next();
206 * Walk through all cells in an area. For SubTotal and Aggregate depending on mnSubTotalFlags.
210 typedef std::pair
<sc::CellStoreType::const_iterator
, size_t> PositionType
;
213 ScAddress maStartPos
;
217 PositionType maCurColPos
;
218 SubtotalFlags
const mnSubTotalFlags
;
220 ScRefCellValue maCurCell
;
224 void setPos(size_t nPos
);
226 const ScColumn
* getColumn() const;
232 ScCellIterator( ScDocument
* pDoc
, const ScRange
& rRange
, SubtotalFlags nSubTotalFlags
= SubtotalFlags::NONE
);
234 const ScAddress
& GetPos() const { return maCurPos
; }
236 CellType
getType() const { return maCurCell
.meType
;}
237 OUString
getString() const;
238 const EditTextObject
* getEditText() const { return maCurCell
.mpEditText
;}
239 ScFormulaCell
* getFormulaCell() { return maCurCell
.mpFormula
;}
240 const ScFormulaCell
* getFormulaCell() const { return maCurCell
.mpFormula
;}
241 ScCellValue
getCellValue() const;
242 const ScRefCellValue
& getRefCellValue() const { return maCurCell
;}
244 bool hasString() const;
245 bool isEmpty() const;
246 bool equalsWithoutFormat( const ScAddress
& rPos
) const;
252 class ScQueryCellIterator
// walk through all non-empty cells in an area
254 enum StopOnMismatchBits
256 nStopOnMismatchDisabled
= 0x00,
257 nStopOnMismatchEnabled
= 0x01,
258 nStopOnMismatchOccurred
= 0x02,
259 nStopOnMismatchExecuted
= nStopOnMismatchEnabled
| nStopOnMismatchOccurred
262 enum TestEqualConditionBits
264 nTestEqualConditionDisabled
= 0x00,
265 nTestEqualConditionEnabled
= 0x01,
266 nTestEqualConditionMatched
= 0x02,
267 nTestEqualConditionFulfilled
= nTestEqualConditionEnabled
| nTestEqualConditionMatched
270 typedef sc::CellStoreType::const_position_type PositionType
;
271 PositionType maCurPos
;
273 std::unique_ptr
<ScQueryParam
> mpParam
;
275 const ScInterpreterContext
& mrContext
;
279 sal_uInt8 nStopOnMismatch
;
280 sal_uInt8 nTestEqualCondition
;
282 bool bIgnoreMismatchOnLeadingStrings
;
284 /** Initialize position for new column. */
290 /* Only works if no regular expression is involved, only
291 searches for rows in one column, and only the first
292 query entry is considered with simple conditions
293 SC_LESS_EQUAL (sorted ascending) or SC_GREATER_EQUAL
294 (sorted descending). Check these things before
295 invocation! Delivers a starting point, continue with
296 GetThis() and GetNext() afterwards. Introduced for
297 FindEqualOrSortedLastInRange()
302 ScQueryCellIterator(ScDocument
* pDocument
, const ScInterpreterContext
& rContext
, SCTAB nTable
,
303 const ScQueryParam
& aParam
, bool bMod
);
304 // when !bMod, the QueryParam has to be filled
308 SCCOL
GetCol() const { return nCol
; }
309 SCROW
GetRow() const { return nRow
; }
311 // increments all Entry.nField, if column
312 // changes, for ScInterpreter ScHLookup()
313 void SetAdvanceQueryParamEntryField( bool bVal
)
314 { bAdvanceQuery
= bVal
; }
315 void AdvanceQueryParamEntryField();
317 /** If set, iterator stops on first non-matching cell
318 content. May be used in SC_LESS_EQUAL queries where a
319 cell range is assumed to be sorted; stops on first
320 value being greater than the queried value and
321 GetFirst()/GetNext() return NULL. StoppedOnMismatch()
323 However, the iterator's conditions are not set to end
324 all queries, GetCol() and GetRow() return values for
325 the non-matching cell, further GetNext() calls may be
327 void SetStopOnMismatch( bool bVal
)
329 nStopOnMismatch
= sal::static_int_cast
<sal_uInt8
>(bVal
? nStopOnMismatchEnabled
:
330 nStopOnMismatchDisabled
);
332 bool StoppedOnMismatch() const
333 { return nStopOnMismatch
== nStopOnMismatchExecuted
; }
335 /** If set, an additional test for SC_EQUAL condition is
336 executed in ScTable::ValidQuery() if SC_LESS_EQUAL or
337 SC_GREATER_EQUAL conditions are to be tested. May be
338 used where a cell range is assumed to be sorted to stop
339 if an equal match is found. */
340 void SetTestEqualCondition( bool bVal
)
342 nTestEqualCondition
= sal::static_int_cast
<sal_uInt8
>(bVal
?
343 nTestEqualConditionEnabled
:
344 nTestEqualConditionDisabled
);
346 bool IsEqualConditionFulfilled() const
347 { return nTestEqualCondition
== nTestEqualConditionFulfilled
; }
349 /** In a range assumed to be sorted find either the last of
350 a sequence of equal entries or the last being less than
351 (or greater than) the queried value. Used by the
352 interpreter for [HV]?LOOKUP() and MATCH(). Column and
353 row position of the found entry are returned, otherwise
356 The search does not stop when encountering a string and does not
357 assume that no values follow anymore.
358 If querying for a string a mismatch on the first
359 entry, e.g. column header, is ignored.
361 @ATTENTION! StopOnMismatch, TestEqualCondition and
362 the internal IgnoreMismatchOnLeadingStrings and query
363 params are in an undefined state upon return! The
364 iterator is not usable anymore except for obtaining the
367 bool FindEqualOrSortedLastInRange( SCCOL
& nFoundCol
, SCROW
& nFoundRow
);
370 // Used by ScInterpreter::ScCountIf.
371 // Walk through all non-empty cells in an area.
372 class ScCountIfCellIterator
374 typedef sc::CellStoreType::const_position_type PositionType
;
375 PositionType maCurPos
;
376 ScQueryParam maParam
;
378 const ScInterpreterContext
& mrContext
;
383 /** Initialize position for new column. */
387 void AdvanceQueryParamEntryField();
390 ScCountIfCellIterator(ScDocument
* pDocument
, const ScInterpreterContext
& rContext
, SCTAB nTable
,
391 const ScQueryParam
& aParam
);
395 class ScDocAttrIterator
// all attribute areas
401 SCROW
const nStartRow
;
404 std::unique_ptr
<ScAttrIterator
>
408 ScDocAttrIterator(ScDocument
* pDocument
, SCTAB nTable
,
409 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
410 ~ScDocAttrIterator();
412 const ScPatternAttr
* GetNext( SCCOL
& rCol
, SCROW
& rRow1
, SCROW
& rRow2
);
415 class ScAttrRectIterator
// all attribute areas, including areas stretching
416 // across more than one column
422 SCROW
const nStartRow
;
426 std::unique_ptr
<ScAttrIterator
>
430 ScAttrRectIterator(ScDocument
* pDocument
, SCTAB nTable
,
431 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
432 ~ScAttrRectIterator();
435 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow1
, SCROW
& rRow2
);
438 class ScHorizontalCellIterator
// walk through all non empty cells in an area
442 sc::CellStoreType::const_iterator maPos
;
443 sc::CellStoreType::const_iterator maEnd
;
447 std::vector
<ColParam
>::iterator maColPos
;
448 std::vector
<ColParam
> maColPositions
;
452 SCCOL
const nStartCol
;
454 SCROW
const nStartRow
;
458 ScRefCellValue maCurCell
;
462 ScHorizontalCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
463 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
464 ~ScHorizontalCellIterator();
466 ScRefCellValue
* GetNext( SCCOL
& rCol
, SCROW
& rRow
);
467 bool GetPos( SCCOL
& rCol
, SCROW
& rRow
);
468 /// Set a(nother) sheet and (re)init.
469 void SetTab( SCTAB nTab
);
474 bool SkipInvalidInRow();
475 SCROW
FindNextNonEmptyRow();
478 /** Row-wise value iterator. */
479 class ScHorizontalValueIterator
483 const ScAttrArray
*pAttrArray
;
484 std::unique_ptr
<ScHorizontalCellIterator
>
486 sal_uInt32 nNumFormat
; // for CalcAsShown
492 bool const bCalcAsShown
;
496 ScHorizontalValueIterator( ScDocument
* pDocument
,
497 const ScRange
& rRange
);
498 ~ScHorizontalValueIterator();
499 /// Does NOT reset rValue if no value found!
500 bool GetNext( double& rValue
, FormulaError
& rErr
);
503 // returns all areas with non-default formatting (horizontal)
505 class ScHorizontalAttrIterator
510 SCCOL
const nStartCol
;
511 SCROW
const nStartRow
;
515 std::unique_ptr
<SCROW
[]> pNextEnd
;
516 std::unique_ptr
<SCCOL
[]> pHorizEnd
;
517 std::unique_ptr
<SCSIZE
[]> pIndices
;
518 std::unique_ptr
<const ScPatternAttr
*[]>
525 void InitForNextRow(bool bInitialization
);
526 bool InitForNextAttr();
529 ScHorizontalAttrIterator( ScDocument
* pDocument
, SCTAB nTable
,
530 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
531 ~ScHorizontalAttrIterator();
533 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow
);
536 // returns non-empty cells and areas with formatting (horizontal)
538 class SC_DLLPUBLIC ScUsedAreaIterator
541 ScHorizontalCellIterator aCellIter
;
542 ScHorizontalAttrIterator aAttrIter
;
549 ScRefCellValue
* pCell
;
553 const ScPatternAttr
* pPattern
;
555 SCCOL nFoundStartCol
; // results after GetNext
558 const ScPatternAttr
* pFoundPattern
;
560 ScRefCellValue maFoundCell
;
563 ScUsedAreaIterator( ScDocument
* pDocument
, SCTAB nTable
,
564 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
565 ~ScUsedAreaIterator();
569 SCCOL
GetStartCol() const { return nFoundStartCol
; }
570 SCCOL
GetEndCol() const { return nFoundEndCol
; }
571 SCROW
GetRow() const { return nFoundRow
; }
572 const ScPatternAttr
* GetPattern() const { return pFoundPattern
; }
573 const ScRefCellValue
& GetCell() const { return maFoundCell
;}
576 class ScRowBreakIterator
579 static constexpr SCROW NOT_FOUND
= -1;
581 explicit ScRowBreakIterator(::std::set
<SCROW
>& rBreaks
);
586 ::std::set
<SCROW
>& mrBreaks
;
587 ::std::set
<SCROW
>::const_iterator maItr
;
588 ::std::set
<SCROW
>::const_iterator
const maEnd
;
591 class ScDocRowHeightUpdater
597 ScFlatBoolRowSegments maRanges
;
599 TabRanges(SCTAB nTab
);
603 * Passing a NULL pointer to pTabRangesArray forces the heights of all
604 * rows in all tables to be updated.
606 explicit ScDocRowHeightUpdater(
607 ScDocument
& rDoc
, OutputDevice
* pOutDev
, double fPPTX
, double fPPTY
,
608 const ::std::vector
<TabRanges
>* pTabRangesArray
);
617 VclPtr
<OutputDevice
> mpOutDev
;
620 const ::std::vector
<TabRanges
>* mpTabRangesArray
;
625 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */