Bump version to 6.4-15
[LibreOffice.git] / sc / inc / dociter.hxx
blob3479ee67ca0841713495f04afd43d8551d649dc4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "global.hxx"
26 #include "scdllapi.h"
27 #include "cellvalue.hxx"
28 #include "mtvelements.hxx"
29 #include "queryparam.hxx"
30 #include <vcl/outdev.hxx>
31 #include <vcl/vclptr.hxx>
33 #include <memory>
34 #include <set>
35 #include <vector>
37 class ScDocument;
38 class ScPatternAttr;
39 class ScAttrArray;
40 class ScAttrIterator;
41 class ScFlatBoolRowSegments;
42 class ScMatrix;
43 struct ScDBQueryParamBase;
44 struct ScQueryParam;
45 struct ScDBQueryParamInternal;
46 struct ScDBQueryParamMatrix;
47 class ScFormulaCell;
48 class OutputDevice;
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;
56 ScDocument* pDoc;
57 ScInterpreterContext* pContext;
58 const ScAttrArray* pAttrArray;
59 sal_uInt32 nNumFormat; // for CalcAsShown
60 sal_uInt32 nNumFmtIndex;
61 ScAddress maStartPos;
62 ScAddress maEndPos;
63 SCCOL mnCol;
64 SCTAB mnTab;
65 SCROW nAttrEndRow;
66 SubtotalFlags const mnSubTotalFlags;
67 SvNumFormatType nNumFmtType;
68 bool bNumValid;
69 bool const bCalcAsShown;
70 bool const bTextAsZero;
72 const sc::CellStoreType* mpCells;
73 PositionType maCurPos;
75 SCROW GetRow() const;
76 void IncBlock();
77 void IncPos();
79 /**
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 );
85 public:
87 ScValueIterator(
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
104 public:
105 struct Value
107 OUString maString;
108 double mfValue;
109 FormulaError mnError;
110 bool mbIsNumber;
112 Value();
115 private:
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);
120 class DataAccess
122 public:
123 DataAccess();
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;
133 public:
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;
140 private:
141 void incBlock();
142 void incPos();
144 const sc::CellStoreType* mpCells;
145 PositionType maCurPos;
146 ScDBQueryParamInternal* mpParam;
147 ScDocument* mpDoc;
148 const ScInterpreterContext& mrContext;
149 const ScAttrArray* pAttrArray;
150 sal_uInt32 nNumFormat; // for CalcAsShown
151 sal_uInt32 nNumFmtIndex;
152 SCCOL const nCol;
153 SCROW nRow;
154 SCROW nAttrEndRow;
155 SCTAB const nTab;
156 SvNumFormatType nNumFmtType;
157 bool const bCalcAsShown;
160 class DataAccessMatrix final : public DataAccess
162 public:
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;
169 private:
170 bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;
172 ScDBQueryParamMatrix* mpParam;
173 SCROW mnCurRow;
174 SCROW mnRows;
177 ::std::unique_ptr<ScDBQueryParamBase> mpParam;
178 ::std::unique_ptr<DataAccess> mpData;
180 public:
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
190 private:
191 ScDocument* mpDoc;
192 SCTAB mnTab;
193 SCCOL mnCol;
194 bool mbNullCol;
195 size_t mnIndex;
196 std::vector<sc::FormulaGroupEntry> maEntries;
198 public:
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.
208 class ScCellIterator
210 typedef std::pair<sc::CellStoreType::const_iterator, size_t> PositionType;
212 ScDocument* mpDoc;
213 ScAddress maStartPos;
214 ScAddress maEndPos;
215 ScAddress maCurPos;
217 PositionType maCurColPos;
218 SubtotalFlags const mnSubTotalFlags;
220 ScRefCellValue maCurCell;
222 void incBlock();
223 void incPos();
224 void setPos(size_t nPos);
226 const ScColumn* getColumn() const;
228 void init();
229 bool getCurrent();
231 public:
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;
248 bool first();
249 bool next();
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;
274 ScDocument* pDoc;
275 const ScInterpreterContext& mrContext;
276 SCTAB nTab;
277 SCCOL nCol;
278 SCROW nRow;
279 sal_uInt8 nStopOnMismatch;
280 sal_uInt8 nTestEqualCondition;
281 bool bAdvanceQuery;
282 bool bIgnoreMismatchOnLeadingStrings;
284 /** Initialize position for new column. */
285 void InitPos();
286 void IncPos();
287 void IncBlock();
288 bool GetThis();
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()
299 bool BinarySearch();
301 public:
302 ScQueryCellIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, SCTAB nTable,
303 const ScQueryParam& aParam, bool bMod);
304 // when !bMod, the QueryParam has to be filled
305 // (bIsString)
306 bool GetFirst();
307 bool GetNext();
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()
322 returns true then.
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
326 executed. */
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
354 invalid.
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
365 number format!
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;
377 ScDocument* pDoc;
378 const ScInterpreterContext& mrContext;
379 SCTAB nTab;
380 SCCOL nCol;
381 SCROW nRow;
383 /** Initialize position for new column. */
384 void InitPos();
385 void IncPos();
386 void IncBlock();
387 void AdvanceQueryParamEntryField();
389 public:
390 ScCountIfCellIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, SCTAB nTable,
391 const ScQueryParam& aParam);
392 int GetCount();
395 class ScDocAttrIterator // all attribute areas
397 private:
398 ScDocument* pDoc;
399 SCTAB nTab;
400 SCCOL nEndCol;
401 SCROW const nStartRow;
402 SCROW const nEndRow;
403 SCCOL nCol;
404 std::unique_ptr<ScAttrIterator>
405 pColIter;
407 public:
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
418 private:
419 ScDocument* pDoc;
420 SCTAB nTab;
421 SCCOL nEndCol;
422 SCROW const nStartRow;
423 SCROW const nEndRow;
424 SCCOL nIterStartCol;
425 SCCOL nIterEndCol;
426 std::unique_ptr<ScAttrIterator>
427 pColIter;
429 public:
430 ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
431 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
432 ~ScAttrRectIterator();
434 void DataChanged();
435 const ScPatternAttr* GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
438 class ScHorizontalCellIterator // walk through all non empty cells in an area
439 { // row by row
440 struct ColParam
442 sc::CellStoreType::const_iterator maPos;
443 sc::CellStoreType::const_iterator maEnd;
444 SCCOL mnCol;
447 std::vector<ColParam>::iterator maColPos;
448 std::vector<ColParam> maColPositions;
450 ScDocument* pDoc;
451 SCTAB mnTab;
452 SCCOL const nStartCol;
453 SCCOL nEndCol;
454 SCROW const nStartRow;
455 SCROW const nEndRow;
456 SCCOL mnCol;
457 SCROW mnRow;
458 ScRefCellValue maCurCell;
459 bool mbMore;
461 public:
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 );
471 private:
472 void Advance();
473 void SkipInvalid();
474 bool SkipInvalidInRow();
475 SCROW FindNextNonEmptyRow();
478 /** Row-wise value iterator. */
479 class ScHorizontalValueIterator
481 private:
482 ScDocument *pDoc;
483 const ScAttrArray *pAttrArray;
484 std::unique_ptr<ScHorizontalCellIterator>
485 pCellIter;
486 sal_uInt32 nNumFormat; // for CalcAsShown
487 SCTAB nEndTab;
488 SCCOL nCurCol;
489 SCROW nCurRow;
490 SCTAB nCurTab;
491 SCROW nAttrEndRow;
492 bool const bCalcAsShown;
494 public:
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
507 private:
508 ScDocument* pDoc;
509 SCTAB nTab;
510 SCCOL const nStartCol;
511 SCROW const nStartRow;
512 SCCOL nEndCol;
513 SCROW const nEndRow;
515 std::unique_ptr<SCROW[]> pNextEnd;
516 std::unique_ptr<SCCOL[]> pHorizEnd;
517 std::unique_ptr<SCSIZE[]> pIndices;
518 std::unique_ptr<const ScPatternAttr*[]>
519 ppPatterns;
520 SCCOL nCol;
521 SCROW nRow;
522 bool bRowEmpty;
523 SCROW nMinNextEnd;
525 void InitForNextRow(bool bInitialization);
526 bool InitForNextAttr();
528 public:
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
540 private:
541 ScHorizontalCellIterator aCellIter;
542 ScHorizontalAttrIterator aAttrIter;
544 SCCOL nNextCol;
545 SCROW nNextRow;
547 SCCOL nCellCol;
548 SCROW nCellRow;
549 ScRefCellValue* pCell;
550 SCCOL nAttrCol1;
551 SCCOL nAttrCol2;
552 SCROW nAttrRow;
553 const ScPatternAttr* pPattern;
555 SCCOL nFoundStartCol; // results after GetNext
556 SCCOL nFoundEndCol;
557 SCROW nFoundRow;
558 const ScPatternAttr* pFoundPattern;
560 ScRefCellValue maFoundCell;
562 public:
563 ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
564 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
565 ~ScUsedAreaIterator();
567 bool GetNext();
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
578 public:
579 static constexpr SCROW NOT_FOUND = -1;
581 explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
582 SCROW first();
583 SCROW next();
585 private:
586 ::std::set<SCROW>& mrBreaks;
587 ::std::set<SCROW>::const_iterator maItr;
588 ::std::set<SCROW>::const_iterator const maEnd;
591 class ScDocRowHeightUpdater
593 public:
594 struct TabRanges
596 SCTAB mnTab;
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);
610 void update();
612 private:
613 void updateAll();
615 private:
616 ScDocument& mrDoc;
617 VclPtr<OutputDevice> mpOutDev;
618 double const mfPPTX;
619 double const mfPPTY;
620 const ::std::vector<TabRanges>* mpTabRangesArray;
623 #endif
625 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */