Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sc / inc / dociter.hxx
blob18b9d7826c2a03b1d64a1ee3aed7d3c18734c5ec
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 <vcl/vclptr.hxx>
31 #include <memory>
32 #include <set>
33 #include <vector>
35 class ScDocument;
36 class ScPatternAttr;
37 class ScAttrArray;
38 class ScAttrIterator;
39 class ScFlatBoolRowSegments;
40 struct ScInterpreterContext;
41 class ScMatrix;
42 struct ScDBQueryParamBase;
43 struct ScQueryParam;
44 struct ScDBQueryParamInternal;
45 struct ScDBQueryParamMatrix;
46 class ScFormulaCell;
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;
54 ScDocument* pDoc;
55 ScInterpreterContext* pContext;
56 const ScAttrArray* pAttrArray;
57 sal_uInt32 nNumFormat; // for CalcAsShown
58 sal_uInt32 nNumFmtIndex;
59 ScAddress maStartPos;
60 ScAddress maEndPos;
61 SCCOL mnCol;
62 SCTAB mnTab;
63 SCROW nAttrEndRow;
64 SubtotalFlags mnSubTotalFlags;
65 SvNumFormatType nNumFmtType;
66 bool bNumValid;
67 bool bCalcAsShown;
68 bool bTextAsZero;
70 const sc::CellStoreType* mpCells;
71 PositionType maCurPos;
73 SCROW GetRow() const;
74 void IncBlock();
75 void IncPos();
77 /**
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 );
83 public:
85 ScValueIterator(
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
102 public:
103 struct Value
105 OUString maString;
106 double mfValue;
107 FormulaError mnError;
108 bool mbIsNumber;
110 Value();
113 private:
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);
118 class DataAccess
120 public:
121 DataAccess();
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;
131 public:
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;
138 private:
139 void incBlock();
140 void incPos();
142 const sc::CellStoreType* mpCells;
143 PositionType maCurPos;
144 ScDBQueryParamInternal* mpParam;
145 ScDocument* mpDoc;
146 const ScInterpreterContext& mrContext;
147 const ScAttrArray* pAttrArray;
148 sal_uInt32 nNumFormat; // for CalcAsShown
149 sal_uInt32 nNumFmtIndex;
150 SCCOL nCol;
151 SCROW nRow;
152 SCROW nAttrEndRow;
153 SCTAB nTab;
154 SvNumFormatType nNumFmtType;
155 bool bCalcAsShown;
158 class DataAccessMatrix : public DataAccess
160 public:
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;
167 private:
168 bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;
170 ScDBQueryParamMatrix* mpParam;
171 SCROW mnCurRow;
172 SCROW mnRows;
175 ::std::unique_ptr<ScDBQueryParamBase> mpParam;
176 ::std::unique_ptr<DataAccess> mpData;
178 public:
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
188 private:
189 ScDocument* mpDoc;
190 SCTAB mnTab;
191 SCCOL mnCol;
192 bool mbNullCol;
193 size_t mnIndex;
194 std::vector<sc::FormulaGroupEntry> maEntries;
196 public:
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.
206 class ScCellIterator
208 typedef std::pair<sc::CellStoreType::const_iterator, size_t> PositionType;
210 ScDocument* mpDoc;
211 ScAddress maStartPos;
212 ScAddress maEndPos;
213 ScAddress maCurPos;
215 PositionType maCurColPos;
216 SubtotalFlags mnSubTotalFlags;
218 ScRefCellValue maCurCell;
220 void incBlock();
221 void incPos();
222 void setPos(size_t nPos);
224 const ScColumn* getColumn() const;
226 void init();
227 bool getCurrent();
229 public:
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;
247 bool first();
248 bool next();
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;
273 ScDocument* pDoc;
274 const ScInterpreterContext& mrContext;
275 SCTAB nTab;
276 SCCOL nCol;
277 SCROW nRow;
278 sal_uInt8 nStopOnMismatch;
279 sal_uInt8 nTestEqualCondition;
280 bool bAdvanceQuery;
281 bool bIgnoreMismatchOnLeadingStrings;
283 /** Initialize position for new column. */
284 void InitPos();
285 void IncPos();
286 void IncBlock();
287 bool GetThis();
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()
298 bool BinarySearch();
300 public:
301 ScQueryCellIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, SCTAB nTable,
302 const ScQueryParam& aParam, bool bMod);
303 // when !bMod, the QueryParam has to be filled
304 // (bIsString)
305 bool GetFirst();
306 bool GetNext();
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()
321 returns true then.
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
325 executed. */
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
353 invalid.
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
364 number format!
366 bool FindEqualOrSortedLastInRange( SCCOL& nFoundCol, SCROW& nFoundRow );
369 class ScDocAttrIterator // all attribute areas
371 private:
372 ScDocument* pDoc;
373 SCTAB nTab;
374 SCCOL nEndCol;
375 SCROW nStartRow;
376 SCROW nEndRow;
377 SCCOL nCol;
378 std::unique_ptr<ScAttrIterator>
379 pColIter;
381 public:
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
392 private:
393 ScDocument* pDoc;
394 SCTAB nTab;
395 SCCOL nEndCol;
396 SCROW nStartRow;
397 SCROW nEndRow;
398 SCCOL nIterStartCol;
399 SCCOL nIterEndCol;
400 std::unique_ptr<ScAttrIterator>
401 pColIter;
403 public:
404 ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
405 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
406 ~ScAttrRectIterator();
408 void DataChanged();
409 const ScPatternAttr* GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
412 class ScHorizontalCellIterator // walk through all non empty cells in an area
413 { // row by row
414 struct ColParam
416 sc::CellStoreType::const_iterator maPos;
417 sc::CellStoreType::const_iterator maEnd;
418 SCCOL mnCol;
421 std::vector<ColParam>::iterator maColPos;
422 std::vector<ColParam> maColPositions;
424 ScDocument* pDoc;
425 SCTAB mnTab;
426 SCCOL nStartCol;
427 SCCOL nEndCol;
428 SCROW nStartRow;
429 SCROW nEndRow;
430 SCCOL mnCol;
431 SCROW mnRow;
432 ScRefCellValue maCurCell;
433 bool mbMore;
435 public:
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 );
445 private:
446 void Advance();
447 void SkipInvalid();
448 bool SkipInvalidInRow();
449 SCROW FindNextNonEmptyRow();
452 /** Row-wise value iterator. */
453 class ScHorizontalValueIterator
455 private:
456 ScDocument *pDoc;
457 const ScAttrArray *pAttrArray;
458 std::unique_ptr<ScHorizontalCellIterator>
459 pCellIter;
460 sal_uInt32 nNumFormat; // for CalcAsShown
461 SCTAB nEndTab;
462 SCCOL nCurCol;
463 SCROW nCurRow;
464 SCTAB nCurTab;
465 SCROW nAttrEndRow;
466 bool bCalcAsShown;
468 public:
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
481 private:
482 ScDocument* pDoc;
483 SCTAB nTab;
484 SCCOL nStartCol;
485 SCROW nStartRow;
486 SCCOL nEndCol;
487 SCROW nEndRow;
489 std::unique_ptr<SCROW[]> pNextEnd;
490 std::unique_ptr<SCCOL[]> pHorizEnd;
491 std::unique_ptr<SCSIZE[]> pIndices;
492 std::unique_ptr<const ScPatternAttr*[]>
493 ppPatterns;
494 SCCOL nCol;
495 SCROW nRow;
496 bool bRowEmpty;
497 SCROW nMinNextEnd;
499 void InitForNextRow(bool bInitialization);
500 bool InitForNextAttr();
502 public:
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
514 private:
515 ScHorizontalCellIterator aCellIter;
516 ScHorizontalAttrIterator aAttrIter;
518 SCCOL nNextCol;
519 SCROW nNextRow;
521 SCCOL nCellCol;
522 SCROW nCellRow;
523 ScRefCellValue* pCell;
524 SCCOL nAttrCol1;
525 SCCOL nAttrCol2;
526 SCROW nAttrRow;
527 const ScPatternAttr* pPattern;
529 SCCOL nFoundStartCol; // results after GetNext
530 SCCOL nFoundEndCol;
531 SCROW nFoundRow;
532 const ScPatternAttr* pFoundPattern;
534 ScRefCellValue maFoundCell;
536 public:
537 ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
538 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
539 ~ScUsedAreaIterator();
541 bool GetNext();
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
552 public:
553 static constexpr SCROW NOT_FOUND = -1;
555 explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
556 SCROW first();
557 SCROW next();
559 private:
560 ::std::set<SCROW>& mrBreaks;
561 ::std::set<SCROW>::const_iterator maItr;
562 ::std::set<SCROW>::const_iterator maEnd;
565 class ScDocRowHeightUpdater
567 public:
568 struct TabRanges
570 SCTAB mnTab;
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);
584 void update();
586 private:
587 void updateAll();
589 private:
590 ScDocument& mrDoc;
591 VclPtr<OutputDevice> mpOutDev;
592 double mfPPTX;
593 double mfPPTY;
594 const ::std::vector<TabRanges>* mpTabRangesArray;
597 #endif
599 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */