1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #ifndef SC_DOCITER_HXX
29 #define SC_DOCITER_HXX
31 #include "address.hxx"
32 #include <tools/solar.h>
35 #include "queryparam.hxx"
48 class ScDocumentIterator
// alle nichtleeren Zellen durchgehen
55 const ScPatternAttr
* pDefPattern
;
61 const ScPatternAttr
* pPattern
;
71 ScDocumentIterator( ScDocument
* pDocument
, SCTAB nStartTable
, SCTAB nEndTable
);
72 ~ScDocumentIterator();
77 ScBaseCell
* GetCell();
78 const ScPatternAttr
* GetPattern();
79 void GetPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
);
82 class ScValueIterator
// alle Zahlenwerte in einem Bereich durchgehen
87 const ScAttrArray
* pAttrArray
;
88 ULONG nNumFormat
; // fuer CalcAsShown
109 BOOL
GetThis(double& rValue
, USHORT
& rErr
);
111 //UNUSED2008-05 ScValueIterator(ScDocument* pDocument,
112 //UNUSED2008-05 SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
113 //UNUSED2008-05 SCCOL nECol, SCROW nERow, SCTAB nETab,
114 //UNUSED2008-05 BOOL bSTotal = FALSE, BOOL bTextAsZero = FALSE);
116 ScValueIterator(ScDocument
* pDocument
,
117 const ScRange
& rRange
, BOOL bSTotal
= FALSE
,
118 BOOL bTextAsZero
= FALSE
);
119 void GetCurNumFmtInfo( short& nType
, ULONG
& nIndex
);
120 /// Does NOT reset rValue if no value found!
121 BOOL
GetFirst(double& rValue
, USHORT
& rErr
);
122 /// Does NOT reset rValue if no value found!
123 BOOL
GetNext(double& rValue
, USHORT
& rErr
)
125 return bNextValid
? ( bNextValid
= FALSE
, rValue
= fNextValue
,
126 rErr
= 0, nRow
= nNextRow
,
127 ++nColRow
, bNumValid
= FALSE
, TRUE
)
128 : ( ++nRow
, GetThis(rValue
, rErr
) );
132 // ============================================================================
134 class ScDBQueryDataIterator
139 ::rtl::OUString maString
;
148 static SCROW
GetRowByColEntryIndex(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
, SCSIZE nColRow
);
149 static ScBaseCell
* GetCellByColEntryIndex(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
, SCSIZE nColRow
);
150 static ScAttrArray
* GetAttrArrayByCol(ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
);
151 static bool IsQueryValid(ScDocument
& rDoc
, const ScQueryParam
& rParam
, SCTAB nTab
, SCROW nRow
, ScBaseCell
* pCell
);
152 static SCSIZE
SearchColEntryIndex(ScDocument
& rDoc
, SCTAB nTab
, SCROW nRow
, SCCOL nCol
);
157 DataAccess(const ScDBQueryDataIterator
* pParent
);
158 virtual ~DataAccess() = 0;
159 virtual bool getCurrent(Value
& rValue
) = 0;
160 virtual bool getFirst(Value
& rValue
) = 0;
161 virtual bool getNext(Value
& rValue
) = 0;
163 const ScDBQueryDataIterator
* mpParent
;
166 class DataAccessInternal
: public DataAccess
169 DataAccessInternal(const ScDBQueryDataIterator
* pParent
, ScDBQueryParamInternal
* pParam
, ScDocument
* pDoc
);
170 virtual ~DataAccessInternal();
171 virtual bool getCurrent(Value
& rValue
);
172 virtual bool getFirst(Value
& rValue
);
173 virtual bool getNext(Value
& rValue
);
176 ScDBQueryParamInternal
* mpParam
;
178 const ScAttrArray
* pAttrArray
;
179 ULONG nNumFormat
; // for CalcAsShown
190 class DataAccessMatrix
: public DataAccess
193 DataAccessMatrix(const ScDBQueryDataIterator
* pParent
, ScDBQueryParamMatrix
* pParam
);
194 virtual ~DataAccessMatrix();
195 virtual bool getCurrent(Value
& rValue
);
196 virtual bool getFirst(Value
& rValue
);
197 virtual bool getNext(Value
& rValue
);
200 bool isValidQuery(SCROW mnRow
, const ScMatrix
& rMat
) const;
202 ScDBQueryParamMatrix
* mpParam
;
208 ::std::auto_ptr
<ScDBQueryParamBase
> mpParam
;
209 ::std::auto_ptr
<DataAccess
> mpData
;
212 ScDBQueryDataIterator(ScDocument
* pDocument
, ScDBQueryParamBase
* pParam
);
213 /// Does NOT reset rValue if no value found!
214 bool GetFirst(Value
& rValue
);
215 /// Does NOT reset rValue if no value found!
216 bool GetNext(Value
& rValue
);
219 // ============================================================================
221 class ScCellIterator
// alle Zellen in einem Bereich durchgehen
222 { // bei SubTotal aber keine ausgeblendeten und
223 private: // SubTotalZeilen
237 ScBaseCell
* GetThis();
239 ScCellIterator(ScDocument
* pDocument
,
240 SCCOL nSCol
, SCROW nSRow
, SCTAB nSTab
,
241 SCCOL nECol
, SCROW nERow
, SCTAB nETab
,
242 BOOL bSTotal
= FALSE
);
243 ScCellIterator(ScDocument
* pDocument
,
244 const ScRange
& rRange
, BOOL bSTotal
= FALSE
);
245 ScBaseCell
* GetFirst();
246 ScBaseCell
* GetNext();
247 SCCOL
GetCol() const { return nCol
; }
248 SCROW
GetRow() const { return nRow
; }
249 SCTAB
GetTab() const { return nTab
; }
250 ScAddress
GetPos() const { return ScAddress( nCol
, nRow
, nTab
); }
253 class ScQueryCellIterator
// alle nichtleeren Zellen in einem Bereich
255 enum StopOnMismatchBits
257 nStopOnMismatchDisabled
= 0x00,
258 nStopOnMismatchEnabled
= 0x01,
259 nStopOnMismatchOccured
= 0x02,
260 nStopOnMismatchExecuted
= nStopOnMismatchEnabled
| nStopOnMismatchOccured
263 enum TestEqualConditionBits
265 nTestEqualConditionDisabled
= 0x00,
266 nTestEqualConditionEnabled
= 0x01,
267 nTestEqualConditionMatched
= 0x02,
268 nTestEqualConditionFulfilled
= nTestEqualConditionEnabled
| nTestEqualConditionMatched
274 const ScAttrArray
* pAttrArray
;
281 BYTE nStopOnMismatch
;
282 BYTE nTestEqualCondition
;
284 BOOL bIgnoreMismatchOnLeadingStrings
;
286 ScBaseCell
* 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 ScBaseCell
* BinarySearch();
300 ScQueryCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
301 const ScQueryParam
& aParam
, BOOL bMod
= TRUE
);
302 // fuer bMod = FALSE muss der QueryParam
303 // weiter aufgefuellt sein (bIsString)
304 ScBaseCell
* GetFirst();
305 ScBaseCell
* GetNext();
306 SCCOL
GetCol() { return nCol
; }
307 SCROW
GetRow() { return nRow
; }
309 // setzt alle Entry.nField einen weiter, wenn Spalte
310 // wechselt, fuer 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()
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
325 void SetStopOnMismatch( BOOL bVal
)
327 nStopOnMismatch
= sal::static_int_cast
<BYTE
>(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
<BYTE
>(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
354 @param bSearchForEqualAfterMismatch
355 Continue searching for an equal entry even if the
356 last entry matching the range was found, in case
357 the data is not sorted. Is always done if regular
358 expressions are involved.
360 @param bIgnoreMismatchOnLeadingStrings
361 Normally strings are sorted behind numerical
362 values. If this parameter is TRUE, the search does
363 not stop when encountering a string and does not
364 assume that no values follow anymore.
365 If querying for a string a mismatch on the first
366 entry, e.g. column header, is ignored.
368 @ATTENTION! StopOnMismatch, TestEqualCondition and
369 the internal IgnoreMismatchOnLeadingStrings and query
370 params are in an undefined state upon return! The
371 iterator is not usable anymore except for obtaining the
374 BOOL
FindEqualOrSortedLastInRange( SCCOL
& nFoundCol
,
375 SCROW
& nFoundRow
, BOOL bSearchForEqualAfterMismatch
= FALSE
,
376 BOOL bIgnoreMismatchOnLeadingStrings
= TRUE
);
379 class ScDocAttrIterator
// alle Attribut-Bereiche
388 ScAttrIterator
* pColIter
;
391 ScDocAttrIterator(ScDocument
* pDocument
, SCTAB nTable
,
392 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
393 ~ScDocAttrIterator();
395 const ScPatternAttr
* GetNext( SCCOL
& rCol
, SCROW
& rRow1
, SCROW
& rRow2
);
398 class ScAttrRectIterator
// alle Attribut-Bereiche, auch Bereiche ueber mehrere Spalten
408 ScAttrIterator
* pColIter
;
411 ScAttrRectIterator(ScDocument
* pDocument
, SCTAB nTable
,
412 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
413 ~ScAttrRectIterator();
416 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow1
, SCROW
& rRow2
);
419 class ScHorizontalCellIterator
// alle nichtleeren Zellen in einem Bereich
420 { // zeilenweise durchgehen
428 SCSIZE
* pNextIndices
;
434 ScHorizontalCellIterator(ScDocument
* pDocument
, SCTAB nTable
,
435 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
436 ~ScHorizontalCellIterator();
438 ScBaseCell
* GetNext( SCCOL
& rCol
, SCROW
& rRow
);
439 BOOL
ReturnNext( SCCOL
& rCol
, SCROW
& rRow
);
447 // gibt alle Bereiche mit nicht-Default-Formatierung zurueck (horizontal)
450 class ScHorizontalAttrIterator
462 const ScPatternAttr
** ppPatterns
;
468 ScHorizontalAttrIterator( ScDocument
* pDocument
, SCTAB nTable
,
469 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
470 ~ScHorizontalAttrIterator();
472 const ScPatternAttr
* GetNext( SCCOL
& rCol1
, SCCOL
& rCol2
, SCROW
& rRow
);
476 // gibt nichtleere Zellen und Bereiche mit Formatierung zurueck (horizontal)
479 class SC_DLLPUBLIC ScUsedAreaIterator
482 ScHorizontalCellIterator aCellIter
;
483 ScHorizontalAttrIterator aAttrIter
;
490 const ScBaseCell
* pCell
;
494 const ScPatternAttr
* pPattern
;
496 SCCOL nFoundStartCol
; // Ergebnisse nach GetNext
499 const ScPatternAttr
* pFoundPattern
;
500 const ScBaseCell
* pFoundCell
;
503 ScUsedAreaIterator( ScDocument
* pDocument
, SCTAB nTable
,
504 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
505 ~ScUsedAreaIterator();
509 SCCOL
GetStartCol() const { return nFoundStartCol
; }
510 SCCOL
GetEndCol() const { return nFoundEndCol
; }
511 SCROW
GetRow() const { return nFoundRow
; }
512 const ScPatternAttr
* GetPattern() const { return pFoundPattern
; }
513 const ScBaseCell
* GetCell() const { return pFoundCell
; }
516 // ============================================================================
518 class ScRowBreakIterator
521 static SCROW NOT_FOUND
;
523 explicit ScRowBreakIterator(::std::set
<SCROW
>& rBreaks
);
528 ::std::set
<SCROW
>& mrBreaks
;
529 ::std::set
<SCROW
>::const_iterator maItr
;
530 ::std::set
<SCROW
>::const_iterator maEnd
;