merged tag ooo/OOO330_m14
[LibreOffice.git] / sc / inc / dociter.hxx
blobd995550a2f1db58ab5c0a67c97819aac18098df0
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>
33 #include "global.hxx"
34 #include "scdllapi.h"
35 #include "queryparam.hxx"
37 #include <memory>
39 #include <set>
41 class ScDocument;
42 class ScBaseCell;
43 class ScPatternAttr;
44 class ScAttrArray;
45 class ScAttrIterator;
46 class ScRange;
48 class ScDocumentIterator // alle nichtleeren Zellen durchgehen
50 private:
51 ScDocument* pDoc;
52 SCTAB nStartTab;
53 SCTAB nEndTab;
55 const ScPatternAttr* pDefPattern;
57 SCCOL nCol;
58 SCROW nRow;
59 SCTAB nTab;
60 ScBaseCell* pCell;
61 const ScPatternAttr* pPattern;
64 SCSIZE nColPos;
65 SCSIZE nAttrPos;
67 BOOL GetThis();
68 BOOL GetThisCol();
70 public:
71 ScDocumentIterator( ScDocument* pDocument, SCTAB nStartTable, SCTAB nEndTable );
72 ~ScDocumentIterator();
74 BOOL GetFirst();
75 BOOL GetNext();
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
84 private:
85 double fNextValue;
86 ScDocument* pDoc;
87 const ScAttrArray* pAttrArray;
88 ULONG nNumFormat; // fuer CalcAsShown
89 ULONG nNumFmtIndex;
90 SCCOL nStartCol;
91 SCROW nStartRow;
92 SCTAB nStartTab;
93 SCCOL nEndCol;
94 SCROW nEndRow;
95 SCTAB nEndTab;
96 SCCOL nCol;
97 SCROW nRow;
98 SCTAB nTab;
99 SCSIZE nColRow;
100 SCROW nNextRow;
101 SCROW nAttrEndRow;
102 short nNumFmtType;
103 BOOL bNumValid;
104 BOOL bSubTotal;
105 BOOL bNextValid;
106 BOOL bCalcAsShown;
107 BOOL bTextAsZero;
109 BOOL GetThis(double& rValue, USHORT& rErr);
110 public:
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
136 public:
137 struct Value
139 ::rtl::OUString maString;
140 double mfValue;
141 sal_uInt16 mnError;
142 bool mbIsNumber;
144 Value();
147 private:
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);
154 class DataAccess
156 public:
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;
162 protected:
163 const ScDBQueryDataIterator* mpParent;
166 class DataAccessInternal : public DataAccess
168 public:
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);
175 private:
176 ScDBQueryParamInternal* mpParam;
177 ScDocument* mpDoc;
178 const ScAttrArray* pAttrArray;
179 ULONG nNumFormat; // for CalcAsShown
180 ULONG nNumFmtIndex;
181 SCCOL nCol;
182 SCROW nRow;
183 SCSIZE nColRow;
184 SCROW nAttrEndRow;
185 SCTAB nTab;
186 short nNumFmtType;
187 bool bCalcAsShown;
190 class DataAccessMatrix : public DataAccess
192 public:
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);
199 private:
200 bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;
202 ScDBQueryParamMatrix* mpParam;
203 SCROW mnCurRow;
204 SCROW mnRows;
205 SCCOL mnCols;
208 ::std::auto_ptr<ScDBQueryParamBase> mpParam;
209 ::std::auto_ptr<DataAccess> mpData;
211 public:
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
224 ScDocument* pDoc;
225 SCCOL nStartCol;
226 SCROW nStartRow;
227 SCTAB nStartTab;
228 SCCOL nEndCol;
229 SCROW nEndRow;
230 SCTAB nEndTab;
231 SCCOL nCol;
232 SCROW nRow;
233 SCTAB nTab;
234 SCSIZE nColRow;
235 BOOL bSubTotal;
237 ScBaseCell* GetThis();
238 public:
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
254 { // durchgehen
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
271 private:
272 ScQueryParam aParam;
273 ScDocument* pDoc;
274 const ScAttrArray* pAttrArray;
275 ULONG nNumFormat;
276 SCTAB nTab;
277 SCCOL nCol;
278 SCROW nRow;
279 SCSIZE nColRow;
280 SCROW nAttrEndRow;
281 BYTE nStopOnMismatch;
282 BYTE nTestEqualCondition;
283 BOOL bAdvanceQuery;
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();
299 public:
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()
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<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
352 invalid.
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
372 number format!
374 BOOL FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
375 SCROW& nFoundRow, BOOL bSearchForEqualAfterMismatch = FALSE,
376 BOOL bIgnoreMismatchOnLeadingStrings = TRUE );
379 class ScDocAttrIterator // alle Attribut-Bereiche
381 private:
382 ScDocument* pDoc;
383 SCTAB nTab;
384 SCCOL nEndCol;
385 SCROW nStartRow;
386 SCROW nEndRow;
387 SCCOL nCol;
388 ScAttrIterator* pColIter;
390 public:
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
400 private:
401 ScDocument* pDoc;
402 SCTAB nTab;
403 SCCOL nEndCol;
404 SCROW nStartRow;
405 SCROW nEndRow;
406 SCCOL nIterStartCol;
407 SCCOL nIterEndCol;
408 ScAttrIterator* pColIter;
410 public:
411 ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
412 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
413 ~ScAttrRectIterator();
415 void DataChanged();
416 const ScPatternAttr* GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
419 class ScHorizontalCellIterator // alle nichtleeren Zellen in einem Bereich
420 { // zeilenweise durchgehen
421 private:
422 ScDocument* pDoc;
423 SCTAB nTab;
424 SCCOL nStartCol;
425 SCCOL nEndCol;
426 SCROW nEndRow;
427 SCROW* pNextRows;
428 SCSIZE* pNextIndices;
429 SCCOL nCol;
430 SCROW nRow;
431 BOOL bMore;
433 public:
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 );
441 private:
442 void Advance();
447 // gibt alle Bereiche mit nicht-Default-Formatierung zurueck (horizontal)
450 class ScHorizontalAttrIterator
452 private:
453 ScDocument* pDoc;
454 SCTAB nTab;
455 SCCOL nStartCol;
456 SCROW nStartRow;
457 SCCOL nEndCol;
458 SCROW nEndRow;
460 SCROW* pNextEnd;
461 SCSIZE* pIndices;
462 const ScPatternAttr** ppPatterns;
463 SCCOL nCol;
464 SCROW nRow;
465 BOOL bRowEmpty;
467 public:
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
481 private:
482 ScHorizontalCellIterator aCellIter;
483 ScHorizontalAttrIterator aAttrIter;
485 SCCOL nNextCol;
486 SCROW nNextRow;
488 SCCOL nCellCol;
489 SCROW nCellRow;
490 const ScBaseCell* pCell;
491 SCCOL nAttrCol1;
492 SCCOL nAttrCol2;
493 SCROW nAttrRow;
494 const ScPatternAttr* pPattern;
496 SCCOL nFoundStartCol; // Ergebnisse nach GetNext
497 SCCOL nFoundEndCol;
498 SCROW nFoundRow;
499 const ScPatternAttr* pFoundPattern;
500 const ScBaseCell* pFoundCell;
502 public:
503 ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
504 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
505 ~ScUsedAreaIterator();
507 BOOL GetNext();
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
520 public:
521 static SCROW NOT_FOUND;
523 explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
524 SCROW first();
525 SCROW next();
527 private:
528 ::std::set<SCROW>& mrBreaks;
529 ::std::set<SCROW>::const_iterator maItr;
530 ::std::set<SCROW>::const_iterator maEnd;
533 #endif