Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / inc / dociter.hxx
blob20775a5d5814a17561bb9802a912bb5d551e8e2b
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 <tools/solar.h>
26 #include "global.hxx"
27 #include "scdllapi.h"
28 #include "cellvalue.hxx"
29 #include "mtvelements.hxx"
30 #include <vcl/vclptr.hxx>
32 #include <memory>
33 #include <set>
34 #include <vector>
36 class ScDocument;
37 class ScPatternAttr;
38 class ScAttrArray;
39 class ScAttrIterator;
40 class ScRange;
41 class ScFlatBoolRowSegments;
42 class ScMatrix;
43 struct ScDBQueryParamBase;
44 struct ScQueryParam;
45 struct ScDBQueryParamInternal;
46 struct ScDBQueryParamMatrix;
47 class ScFormulaCell;
49 class ScValueIterator // walk through all values in an area
51 typedef sc::CellStoreType::const_position_type PositionType;
53 ScDocument* pDoc;
54 const ScAttrArray* pAttrArray;
55 sal_uLong nNumFormat; // for CalcAsShown
56 sal_uLong nNumFmtIndex;
57 ScAddress maStartPos;
58 ScAddress maEndPos;
59 SCCOL mnCol;
60 SCTAB mnTab;
61 SCROW nAttrEndRow;
62 sal_uInt16 mnSubTotalFlags;
63 short nNumFmtType;
64 bool bNumValid;
65 bool bCalcAsShown;
66 bool bTextAsZero;
68 const sc::CellStoreType* mpCells;
69 PositionType maCurPos;
71 SCROW GetRow() const;
72 void IncBlock();
73 void IncPos();
74 void SetPos(size_t nPos);
76 /**
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 );
82 public:
84 ScValueIterator(
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
99 public:
100 struct Value
102 OUString maString;
103 double mfValue;
104 sal_uInt16 mnError;
105 bool mbIsNumber;
107 Value();
110 private:
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);
115 class DataAccess
117 public:
118 DataAccess();
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;
128 public:
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;
135 private:
136 void incBlock();
137 void incPos();
139 const sc::CellStoreType* mpCells;
140 PositionType maCurPos;
141 ScDBQueryParamInternal* mpParam;
142 ScDocument* mpDoc;
143 const ScAttrArray* pAttrArray;
144 sal_uLong nNumFormat; // for CalcAsShown
145 sal_uLong nNumFmtIndex;
146 SCCOL nCol;
147 SCROW nRow;
148 SCROW nAttrEndRow;
149 SCTAB nTab;
150 short nNumFmtType;
151 bool bCalcAsShown;
154 class DataAccessMatrix : public DataAccess
156 public:
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;
163 private:
164 bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;
166 ScDBQueryParamMatrix* mpParam;
167 SCROW mnCurRow;
168 SCROW mnRows;
169 SCCOL mnCols;
172 ::std::unique_ptr<ScDBQueryParamBase> mpParam;
173 ::std::unique_ptr<DataAccess> mpData;
175 public:
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
185 private:
186 ScDocument* mpDoc;
187 SCTAB mnTab;
188 SCCOL mnCol;
189 bool mbNullCol;
190 size_t mnIndex;
191 std::vector<sc::FormulaGroupEntry> maEntries;
193 public:
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.
203 class ScCellIterator
205 typedef std::pair<sc::CellStoreType::const_iterator, size_t> PositionType;
207 ScDocument* mpDoc;
208 ScAddress maStartPos;
209 ScAddress maEndPos;
210 ScAddress maCurPos;
212 PositionType maCurColPos;
213 sal_uInt16 mnSubTotalFlags;
215 ScRefCellValue maCurCell;
217 void incBlock();
218 void incPos();
219 void setPos(size_t nPos);
221 const ScColumn* getColumn() const;
223 void init();
224 bool getCurrent();
226 public:
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;
244 bool first();
245 bool next();
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;
270 ScDocument* pDoc;
271 const ScAttrArray* pAttrArray;
272 sal_uLong nNumFormat;
273 SCTAB nTab;
274 SCCOL nCol;
275 SCROW nRow;
276 SCROW nAttrEndRow;
277 sal_uInt8 nStopOnMismatch;
278 sal_uInt8 nTestEqualCondition;
279 bool bAdvanceQuery;
280 bool bIgnoreMismatchOnLeadingStrings;
282 /** Initialize position for new column. */
283 void InitPos();
284 void IncPos();
285 void IncBlock();
286 bool GetThis();
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()
297 bool BinarySearch();
299 public:
300 ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
301 const ScQueryParam& aParam, bool bMod = true);
302 // for bMod = FALSE the QueryParam has to be filled
303 // (bIsString)
304 bool GetFirst();
305 bool GetNext();
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()
320 returns true then.
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
324 executed. */
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
352 invalid.
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
363 number format!
365 bool FindEqualOrSortedLastInRange( SCCOL& nFoundCol, SCROW& nFoundRow );
368 class ScDocAttrIterator // all attribute areas
370 private:
371 ScDocument* pDoc;
372 SCTAB nTab;
373 SCCOL nEndCol;
374 SCROW nStartRow;
375 SCROW nEndRow;
376 SCCOL nCol;
377 ScAttrIterator* pColIter;
379 public:
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
390 private:
391 ScDocument* pDoc;
392 SCTAB nTab;
393 SCCOL nEndCol;
394 SCROW nStartRow;
395 SCROW nEndRow;
396 SCCOL nIterStartCol;
397 SCCOL nIterEndCol;
398 ScAttrIterator* pColIter;
400 public:
401 ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
402 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
403 ~ScAttrRectIterator();
405 void DataChanged();
406 const ScPatternAttr* GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
409 class ScHorizontalCellIterator // walk through all non empty cells in an area
410 { // row by row
411 struct ColParam
413 sc::CellStoreType::const_iterator maPos;
414 sc::CellStoreType::const_iterator maEnd;
415 SCCOL mnCol;
418 std::vector<ColParam>::iterator maColPos;
419 std::vector<ColParam> maColPositions;
421 ScDocument* pDoc;
422 SCTAB mnTab;
423 SCCOL nStartCol;
424 SCCOL nEndCol;
425 SCROW nStartRow;
426 SCROW nEndRow;
427 SCROW* pNextRows;
428 SCSIZE* pNextIndices;
429 SCCOL mnCol;
430 SCROW mnRow;
431 ScRefCellValue maCurCell;
432 bool mbMore;
434 public:
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 );
444 private:
445 void Advance();
446 void SkipInvalid();
447 bool SkipInvalidInRow();
448 SCROW FindNextNonEmptyRow();
451 /** Row-wise value iterator. */
452 class ScHorizontalValueIterator
454 private:
455 ScDocument *pDoc;
456 const ScAttrArray *pAttrArray;
457 ScHorizontalCellIterator *pCellIter;
458 sal_uLong nNumFormat; // for CalcAsShown
459 sal_uLong nNumFmtIndex;
460 SCTAB nEndTab;
461 SCCOL nCurCol;
462 SCROW nCurRow;
463 SCTAB nCurTab;
464 SCROW nAttrEndRow;
465 short nNumFmtType;
466 bool bNumValid;
467 bool bCalcAsShown;
468 bool bTextAsZero;
470 public:
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
483 private:
484 ScDocument* pDoc;
485 SCTAB nTab;
486 SCCOL nStartCol;
487 SCROW nStartRow;
488 SCCOL nEndCol;
489 SCROW nEndRow;
491 SCROW* pNextEnd;
492 SCCOL* pHorizEnd;
493 SCSIZE* pIndices;
494 const ScPatternAttr** ppPatterns;
495 SCCOL nCol;
496 SCROW nRow;
497 bool bRowEmpty;
498 bool bRepeatedRow;
499 SCROW nMinNextEnd;
501 void InitForNextRow(bool bInitialization);
502 bool InitForNextAttr();
504 public:
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
516 private:
517 ScHorizontalCellIterator aCellIter;
518 ScHorizontalAttrIterator aAttrIter;
520 SCCOL nNextCol;
521 SCROW nNextRow;
523 SCCOL nCellCol;
524 SCROW nCellRow;
525 ScRefCellValue* pCell;
526 SCCOL nAttrCol1;
527 SCCOL nAttrCol2;
528 SCROW nAttrRow;
529 const ScPatternAttr* pPattern;
531 SCCOL nFoundStartCol; // results after GetNext
532 SCCOL nFoundEndCol;
533 SCROW nFoundRow;
534 const ScPatternAttr* pFoundPattern;
536 ScRefCellValue maFoundCell;
538 public:
539 ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
540 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
541 ~ScUsedAreaIterator();
543 bool GetNext();
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
554 public:
555 static SCROW NOT_FOUND;
557 explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
558 SCROW first();
559 SCROW next();
561 private:
562 ::std::set<SCROW>& mrBreaks;
563 ::std::set<SCROW>::const_iterator maItr;
564 ::std::set<SCROW>::const_iterator maEnd;
567 class ScDocRowHeightUpdater
569 public:
570 struct TabRanges
572 SCTAB mnTab;
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);
586 void update();
588 private:
589 void updateAll();
591 private:
592 ScDocument& mrDoc;
593 VclPtr<OutputDevice> mpOutDev;
594 double mfPPTX;
595 double mfPPTY;
596 const ::std::vector<TabRanges>* mpTabRangesArray;
599 #endif
601 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */