bump product version to 4.1.6.2
[LibreOffice.git] / sc / inc / dociter.hxx
blobcfffb7ef2f56c0fa39b09fad6fc43cee28efed10
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 SC_DOCITER_HXX
21 #define SC_DOCITER_HXX
23 #include "address.hxx"
24 #include <tools/solar.h>
25 #include "global.hxx"
26 #include "scdllapi.h"
27 #include "cellvalue.hxx"
29 #include <memory>
31 #include <set>
32 #include <vector>
33 #include <boost/shared_ptr.hpp>
34 #include <boost/scoped_ptr.hpp>
36 class ScDocument;
37 class ScBaseCell;
38 class ScPatternAttr;
39 class ScAttrArray;
40 class ScAttrIterator;
41 class ScRange;
42 class ScFlatBoolRowSegments;
43 class ScMatrix;
44 struct ScDBQueryParamBase;
45 struct ScQueryParam;
46 struct ScDBQueryParamInternal;
47 struct ScDBQueryParamMatrix;
48 class ScFormulaCell;
50 class ScDocumentIterator // walk through all non-empty cells
52 private:
53 ScDocument* pDoc;
54 SCTAB nStartTab;
55 SCTAB nEndTab;
57 const ScPatternAttr* pDefPattern;
59 SCCOL nCol;
60 SCROW nRow;
61 SCTAB nTab;
62 ScBaseCell* pCell;
63 const ScPatternAttr* pPattern;
66 SCSIZE nColPos;
67 SCSIZE nAttrPos;
69 bool GetThis();
70 bool GetThisCol();
72 public:
73 ScDocumentIterator( ScDocument* pDocument, SCTAB nStartTable, SCTAB nEndTable );
74 ~ScDocumentIterator();
76 bool GetFirst();
77 bool GetNext();
79 ScCellValue GetCellValue() const;
80 const ScPatternAttr* GetPattern();
81 void GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab );
84 class ScValueIterator // walk through all values in an area
86 private:
87 double fNextValue;
88 ScDocument* pDoc;
89 const ScAttrArray* pAttrArray;
90 sal_uLong nNumFormat; // for CalcAsShown
91 sal_uLong nNumFmtIndex;
92 SCCOL nStartCol;
93 SCROW nStartRow;
94 SCTAB nStartTab;
95 SCCOL nEndCol;
96 SCROW nEndRow;
97 SCTAB nEndTab;
98 SCCOL nCol;
99 SCROW nRow;
100 SCTAB nTab;
101 SCSIZE nColRow;
102 SCROW nNextRow;
103 SCROW nAttrEndRow;
104 short nNumFmtType;
105 bool bNumValid;
106 bool bSubTotal;
107 bool bNextValid;
108 bool bCalcAsShown;
109 bool bTextAsZero;
111 bool GetThis(double& rValue, sal_uInt16& rErr);
112 public:
114 ScValueIterator(ScDocument* pDocument,
115 const ScRange& rRange, bool bSTotal = false,
116 bool bTextAsZero = false );
117 void GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
118 /// Does NOT reset rValue if no value found!
119 bool GetFirst(double& rValue, sal_uInt16& rErr);
120 /// Does NOT reset rValue if no value found!
121 bool GetNext(double& rValue, sal_uInt16& rErr)
123 return bNextValid ? ( bNextValid = false, rValue = fNextValue,
124 rErr = 0, nRow = nNextRow,
125 ++nColRow, bNumValid = false, true )
126 : ( ++nRow, GetThis(rValue, rErr) );
130 class ScDBQueryDataIterator
132 public:
133 struct Value
135 OUString maString;
136 double mfValue;
137 sal_uInt16 mnError;
138 bool mbIsNumber;
140 Value();
143 private:
144 static SCROW GetRowByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow);
145 static ScBaseCell* GetCellByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow);
146 static const ScAttrArray* GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol);
147 static bool IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScBaseCell* pCell);
148 static SCSIZE SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCROW nRow, SCCOL nCol);
150 class DataAccess
152 public:
153 DataAccess(const ScDBQueryDataIterator* pParent);
154 virtual ~DataAccess() = 0;
155 virtual bool getCurrent(Value& rValue) = 0;
156 virtual bool getFirst(Value& rValue) = 0;
157 virtual bool getNext(Value& rValue) = 0;
158 protected:
159 const ScDBQueryDataIterator* mpParent;
162 class DataAccessInternal : public DataAccess
164 public:
165 DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc);
166 virtual ~DataAccessInternal();
167 virtual bool getCurrent(Value& rValue);
168 virtual bool getFirst(Value& rValue);
169 virtual bool getNext(Value& rValue);
171 private:
172 ScDBQueryParamInternal* mpParam;
173 ScDocument* mpDoc;
174 const ScAttrArray* pAttrArray;
175 sal_uLong nNumFormat; // for CalcAsShown
176 sal_uLong nNumFmtIndex;
177 SCCOL nCol;
178 SCROW nRow;
179 SCSIZE nColRow;
180 SCROW nAttrEndRow;
181 SCTAB nTab;
182 short nNumFmtType;
183 bool bCalcAsShown;
186 class DataAccessMatrix : public DataAccess
188 public:
189 DataAccessMatrix(const ScDBQueryDataIterator* pParent, ScDBQueryParamMatrix* pParam);
190 virtual ~DataAccessMatrix();
191 virtual bool getCurrent(Value& rValue);
192 virtual bool getFirst(Value& rValue);
193 virtual bool getNext(Value& rValue);
195 private:
196 bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;
198 ScDBQueryParamMatrix* mpParam;
199 SCROW mnCurRow;
200 SCROW mnRows;
201 SCCOL mnCols;
204 ::std::auto_ptr<ScDBQueryParamBase> mpParam;
205 ::std::auto_ptr<DataAccess> mpData;
207 public:
208 ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam);
209 /// Does NOT reset rValue if no value found!
210 bool GetFirst(Value& rValue);
211 /// Does NOT reset rValue if no value found!
212 bool GetNext(Value& rValue);
215 class ScCellIterator // walk through all cells in an area
216 { // for SubTotal no hidden and no sub-total lines
217 private:
218 ScDocument* mpDoc;
219 ScAddress maStartPos;
220 ScAddress maEndPos;
221 ScAddress maCurPos;
222 SCSIZE mnIndex;
223 bool mbSubTotal;
225 ScRefCellValue maCurCell;
227 void init();
228 bool getCurrent();
230 public:
231 ScCellIterator( ScDocument* pDoc, const ScRange& rRange, bool bSTotal = false );
233 const ScAddress& GetPos() const { return maCurPos; }
235 CellType getType() const;
236 OUString getString();
237 const EditTextObject* getEditText() const;
238 ScFormulaCell* getFormulaCell();
239 const ScFormulaCell* getFormulaCell() const;
240 double getValue();
241 ScCellValue getCellValue() const;
242 const ScRefCellValue& getRefCellValue() const;
244 bool hasString() const;
245 bool hasNumeric() const;
246 bool hasEmptyData() const;
247 bool isEmpty() const;
248 bool equalsWithoutFormat( const ScAddress& rPos ) const;
250 bool first();
251 bool next();
254 class ScQueryCellIterator // walk through all non-empty cells in an area
256 enum StopOnMismatchBits
258 nStopOnMismatchDisabled = 0x00,
259 nStopOnMismatchEnabled = 0x01,
260 nStopOnMismatchOccurred = 0x02,
261 nStopOnMismatchExecuted = nStopOnMismatchEnabled | nStopOnMismatchOccurred
264 enum TestEqualConditionBits
266 nTestEqualConditionDisabled = 0x00,
267 nTestEqualConditionEnabled = 0x01,
268 nTestEqualConditionMatched = 0x02,
269 nTestEqualConditionFulfilled = nTestEqualConditionEnabled | nTestEqualConditionMatched
272 private:
273 boost::scoped_ptr<ScQueryParam> mpParam;
274 ScDocument* pDoc;
275 const ScAttrArray* pAttrArray;
276 sal_uLong nNumFormat;
277 SCTAB nTab;
278 SCCOL nCol;
279 SCROW nRow;
280 SCSIZE nColRow;
281 SCROW nAttrEndRow;
282 sal_uInt8 nStopOnMismatch;
283 sal_uInt8 nTestEqualCondition;
284 bool bAdvanceQuery;
285 bool bIgnoreMismatchOnLeadingStrings;
287 ScBaseCell* 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 ScBaseCell* BinarySearch();
300 public:
301 ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
302 const ScQueryParam& aParam, bool bMod = true);
303 // for bMod = FALSE the QueryParam has to be filled
304 // (bIsString)
305 ScBaseCell* GetFirst();
306 ScBaseCell* 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 @param bSearchForEqualAfterMismatch
356 Continue searching for an equal entry even if the
357 last entry matching the range was found, in case
358 the data is not sorted. Is always done if regular
359 expressions are involved.
361 @param bIgnoreMismatchOnLeadingStrings
362 Normally strings are sorted behind numerical
363 values. If this parameter is true, the search does
364 not stop when encountering a string and does not
365 assume that no values follow anymore.
366 If querying for a string a mismatch on the first
367 entry, e.g. column header, is ignored.
369 @ATTENTION! StopOnMismatch, TestEqualCondition and
370 the internal IgnoreMismatchOnLeadingStrings and query
371 params are in an undefined state upon return! The
372 iterator is not usable anymore except for obtaining the
373 number format!
375 bool FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
376 SCROW& nFoundRow, bool bSearchForEqualAfterMismatch = false,
377 bool bIgnoreMismatchOnLeadingStrings = true );
380 class ScDocAttrIterator // all attribute areas
382 private:
383 ScDocument* pDoc;
384 SCTAB nTab;
385 SCCOL nEndCol;
386 SCROW nStartRow;
387 SCROW nEndRow;
388 SCCOL nCol;
389 ScAttrIterator* pColIter;
391 public:
392 ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable,
393 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
394 ~ScDocAttrIterator();
396 const ScPatternAttr* GetNext( SCCOL& rCol, SCROW& rRow1, SCROW& rRow2 );
399 class ScAttrRectIterator // all attribute areas, including areas stretching
400 // across more then one column
402 private:
403 ScDocument* pDoc;
404 SCTAB nTab;
405 SCCOL nEndCol;
406 SCROW nStartRow;
407 SCROW nEndRow;
408 SCCOL nIterStartCol;
409 SCCOL nIterEndCol;
410 ScAttrIterator* pColIter;
412 public:
413 ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
414 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
415 ~ScAttrRectIterator();
417 void DataChanged();
418 const ScPatternAttr* GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
421 class ScHorizontalCellIterator // walk through all non empty cells in an area
422 { // row by row
423 private:
424 ScDocument* pDoc;
425 SCTAB nTab;
426 SCCOL nStartCol;
427 SCCOL nEndCol;
428 SCROW nStartRow;
429 SCROW nEndRow;
430 SCROW* pNextRows;
431 SCSIZE* pNextIndices;
432 SCCOL nCol;
433 SCROW nRow;
434 ScRefCellValue maCurCell;
435 bool bMore;
437 public:
438 ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
439 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
440 ~ScHorizontalCellIterator();
442 ScRefCellValue* GetNext( SCCOL& rCol, SCROW& rRow );
443 bool ReturnNext( SCCOL& rCol, SCROW& rRow );
444 /// Set a(nother) sheet and (re)init.
445 void SetTab( SCTAB nTab );
447 private:
448 void Advance();
452 /** Row-wise value iterator. */
453 class ScHorizontalValueIterator
455 private:
456 ScDocument *pDoc;
457 const ScAttrArray *pAttrArray;
458 ScHorizontalCellIterator *pCellIter;
459 sal_uLong nNumFormat; // for CalcAsShown
460 sal_uLong nNumFmtIndex;
461 SCTAB nEndTab;
462 SCCOL nCurCol;
463 SCROW nCurRow;
464 SCTAB nCurTab;
465 SCROW nAttrEndRow;
466 short nNumFmtType;
467 bool bNumValid;
468 bool bSubTotal;
469 bool bCalcAsShown;
470 bool bTextAsZero;
472 public:
474 ScHorizontalValueIterator( ScDocument* pDocument,
475 const ScRange& rRange,
476 bool bSTotal = false,
477 bool bTextAsZero = false );
478 ~ScHorizontalValueIterator();
479 /// Does NOT reset rValue if no value found!
480 bool GetNext( double& rValue, sal_uInt16& rErr );
485 // returns all areas with non-default formatting (horizontal)
488 class ScHorizontalAttrIterator
490 private:
491 ScDocument* pDoc;
492 SCTAB nTab;
493 SCCOL nStartCol;
494 SCROW nStartRow;
495 SCCOL nEndCol;
496 SCROW nEndRow;
498 SCROW* pNextEnd;
499 SCSIZE* pIndices;
500 const ScPatternAttr** ppPatterns;
501 SCCOL nCol;
502 SCROW nRow;
503 bool bRowEmpty;
505 public:
506 ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
507 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
508 ~ScHorizontalAttrIterator();
510 const ScPatternAttr* GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow );
514 // returns non-empty cells and areas with formatting (horizontal)
517 class SC_DLLPUBLIC ScUsedAreaIterator
519 private:
520 ScHorizontalCellIterator aCellIter;
521 ScHorizontalAttrIterator aAttrIter;
523 SCCOL nNextCol;
524 SCROW nNextRow;
526 SCCOL nCellCol;
527 SCROW nCellRow;
528 ScRefCellValue* pCell;
529 SCCOL nAttrCol1;
530 SCCOL nAttrCol2;
531 SCROW nAttrRow;
532 const ScPatternAttr* pPattern;
534 SCCOL nFoundStartCol; // results after GetNext
535 SCCOL nFoundEndCol;
536 SCROW nFoundRow;
537 const ScPatternAttr* pFoundPattern;
539 ScRefCellValue maFoundCell;
541 public:
542 ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
543 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
544 ~ScUsedAreaIterator();
546 bool GetNext();
548 SCCOL GetStartCol() const { return nFoundStartCol; }
549 SCCOL GetEndCol() const { return nFoundEndCol; }
550 SCROW GetRow() const { return nFoundRow; }
551 const ScPatternAttr* GetPattern() const { return pFoundPattern; }
552 const ScRefCellValue& GetCell() const;
555 class ScRowBreakIterator
557 public:
558 static SCROW NOT_FOUND;
560 explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
561 SCROW first();
562 SCROW next();
564 private:
565 ::std::set<SCROW>& mrBreaks;
566 ::std::set<SCROW>::const_iterator maItr;
567 ::std::set<SCROW>::const_iterator maEnd;
570 class ScDocRowHeightUpdater
572 public:
573 struct TabRanges
575 SCTAB mnTab;
576 ::boost::shared_ptr<ScFlatBoolRowSegments> mpRanges;
578 TabRanges(SCTAB nTab);
582 * Passing a NULL pointer to pTabRangesArray forces the heights of all
583 * rows in all tables to be updated.
585 explicit ScDocRowHeightUpdater(
586 ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY,
587 const ::std::vector<TabRanges>* pTabRangesArray = NULL);
589 void update();
591 private:
592 void updateAll();
594 private:
595 ScDocument& mrDoc;
596 OutputDevice* mpOutDev;
597 double mfPPTX;
598 double mfPPTY;
599 const ::std::vector<TabRanges>* mpTabRangesArray;
603 #endif
606 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */