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 SC_DOCITER_HXX
21 #define SC_DOCITER_HXX
23 #include "address.hxx"
24 #include <tools/solar.h>
27 #include "cellvalue.hxx"
33 #include <boost/shared_ptr.hpp>
34 #include <boost/scoped_ptr.hpp>
42 class ScFlatBoolRowSegments
;
44 struct ScDBQueryParamBase
;
46 struct ScDBQueryParamInternal
;
47 struct ScDBQueryParamMatrix
;
50 class ScDocumentIterator
// walk through all non-empty cells
57 const ScPatternAttr
* pDefPattern
;
63 const ScPatternAttr
* pPattern
;
73 ScDocumentIterator( ScDocument
* pDocument
, SCTAB nStartTable
, SCTAB nEndTable
);
74 ~ScDocumentIterator();
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
89 const ScAttrArray
* pAttrArray
;
90 sal_uLong nNumFormat
; // for CalcAsShown
91 sal_uLong nNumFmtIndex
;
111 bool GetThis(double& rValue
, sal_uInt16
& rErr
);
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
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
);
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;
159 const ScDBQueryDataIterator
* mpParent
;
162 class DataAccessInternal
: public DataAccess
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
);
172 ScDBQueryParamInternal
* mpParam
;
174 const ScAttrArray
* pAttrArray
;
175 sal_uLong nNumFormat
; // for CalcAsShown
176 sal_uLong nNumFmtIndex
;
186 class DataAccessMatrix
: public DataAccess
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
);
196 bool isValidQuery(SCROW mnRow
, const ScMatrix
& rMat
) const;
198 ScDBQueryParamMatrix
* mpParam
;
204 ::std::auto_ptr
<ScDBQueryParamBase
> mpParam
;
205 ::std::auto_ptr
<DataAccess
> mpData
;
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
219 ScAddress maStartPos
;
225 ScRefCellValue maCurCell
;
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;
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;
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
273 boost::scoped_ptr
<ScQueryParam
> mpParam
;
275 const ScAttrArray
* pAttrArray
;
276 sal_uLong nNumFormat
;
282 sal_uInt8 nStopOnMismatch
;
283 sal_uInt8 nTestEqualCondition
;
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();
301 ScQueryCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
302 const ScQueryParam
& aParam
, bool bMod
= true);
303 // for bMod = FALSE the QueryParam has to be filled
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()
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
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
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
375 bool FindEqualOrSortedLastInRange( SCCOL
& nFoundCol
,
376 SCROW
& nFoundRow
, bool bSearchForEqualAfterMismatch
= false,
377 bool bIgnoreMismatchOnLeadingStrings
= true );
380 class ScDocAttrIterator
// all attribute areas
389 ScAttrIterator
* pColIter
;
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
410 ScAttrIterator
* pColIter
;
413 ScAttrRectIterator(ScDocument
* pDocument
, SCTAB nTable
,
414 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
415 ~ScAttrRectIterator();
418 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow1
, SCROW
& rRow2
);
421 class ScHorizontalCellIterator
// walk through all non empty cells in an area
431 SCSIZE
* pNextIndices
;
434 ScRefCellValue maCurCell
;
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
);
452 /** Row-wise value iterator. */
453 class ScHorizontalValueIterator
457 const ScAttrArray
*pAttrArray
;
458 ScHorizontalCellIterator
*pCellIter
;
459 sal_uLong nNumFormat
; // for CalcAsShown
460 sal_uLong nNumFmtIndex
;
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
500 const ScPatternAttr
** ppPatterns
;
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
520 ScHorizontalCellIterator aCellIter
;
521 ScHorizontalAttrIterator aAttrIter
;
528 ScRefCellValue
* pCell
;
532 const ScPatternAttr
* pPattern
;
534 SCCOL nFoundStartCol
; // results after GetNext
537 const ScPatternAttr
* pFoundPattern
;
539 ScRefCellValue maFoundCell
;
542 ScUsedAreaIterator( ScDocument
* pDocument
, SCTAB nTable
,
543 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
544 ~ScUsedAreaIterator();
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
558 static SCROW NOT_FOUND
;
560 explicit ScRowBreakIterator(::std::set
<SCROW
>& rBreaks
);
565 ::std::set
<SCROW
>& mrBreaks
;
566 ::std::set
<SCROW
>::const_iterator maItr
;
567 ::std::set
<SCROW
>::const_iterator maEnd
;
570 class ScDocRowHeightUpdater
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
);
596 OutputDevice
* mpOutDev
;
599 const ::std::vector
<TabRanges
>* mpTabRangesArray
;
606 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */