xref: /trunk/main/sc/inc/dociter.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 #ifndef SC_DOCITER_HXX
29 #define SC_DOCITER_HXX
30 
31 #include "address.hxx"
32 #include <tools/solar.h>
33 #include "global.hxx"
34 #include "scdllapi.h"
35 #include "queryparam.hxx"
36 
37 #include <memory>
38 
39 #include <set>
40 
41 class ScDocument;
42 class ScBaseCell;
43 class ScPatternAttr;
44 class ScAttrArray;
45 class ScAttrIterator;
46 class ScRange;
47 
48 class ScDocumentIterator                // alle nichtleeren Zellen durchgehen
49 {
50 private:
51     ScDocument*             pDoc;
52     SCTAB                   nStartTab;
53     SCTAB                   nEndTab;
54 
55     const ScPatternAttr*    pDefPattern;
56 
57     SCCOL                   nCol;
58     SCROW                   nRow;
59     SCTAB                   nTab;
60     ScBaseCell*             pCell;
61     const ScPatternAttr*    pPattern;
62 
63 
64     SCSIZE                  nColPos;
65     SCSIZE                  nAttrPos;
66 
67     sal_Bool                    GetThis();
68     sal_Bool                    GetThisCol();
69 
70 public:
71             ScDocumentIterator( ScDocument* pDocument, SCTAB nStartTable, SCTAB nEndTable );
72             ~ScDocumentIterator();
73 
74     sal_Bool                    GetFirst();
75     sal_Bool                    GetNext();
76 
77     ScBaseCell*             GetCell();
78     const ScPatternAttr*    GetPattern();
79     void                    GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab );
80 };
81 
82 class ScValueIterator            // alle Zahlenwerte in einem Bereich durchgehen
83 {
84 private:
85     double          fNextValue;
86     ScDocument*     pDoc;
87     const ScAttrArray*  pAttrArray;
88     sal_uLong           nNumFormat;     // fuer CalcAsShown
89     sal_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     sal_Bool            bNumValid;
104     sal_Bool            bSubTotal;
105     sal_Bool            bNextValid;
106     sal_Bool            bCalcAsShown;
107     sal_Bool            bTextAsZero;
108 
109     sal_Bool            GetThis(double& rValue, sal_uInt16& 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                  sal_Bool bSTotal = sal_False, sal_Bool bTextAsZero = sal_False);
115 
116                     ScValueIterator(ScDocument* pDocument,
117                                     const ScRange& rRange, sal_Bool bSTotal = sal_False,
118                                     sal_Bool bTextAsZero = sal_False );
119     void            GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
120     /// Does NOT reset rValue if no value found!
121     sal_Bool            GetFirst(double& rValue, sal_uInt16& rErr);
122     /// Does NOT reset rValue if no value found!
123     sal_Bool            GetNext(double& rValue, sal_uInt16& rErr)
124                     {
125                         return bNextValid ? ( bNextValid = sal_False, rValue = fNextValue,
126                                                 rErr = 0, nRow = nNextRow,
127                                                 ++nColRow, bNumValid = sal_False, sal_True )
128                                           : ( ++nRow, GetThis(rValue, rErr) );
129                     }
130 };
131 
132 // ============================================================================
133 
134 class ScDBQueryDataIterator
135 {
136 public:
137     struct Value
138     {
139         ::rtl::OUString maString;
140         double          mfValue;
141         sal_uInt16      mnError;
142         bool            mbIsNumber;
143 
144         Value();
145     };
146 
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);
153 
154     class DataAccess
155     {
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;
164     };
165 
166     class DataAccessInternal : public DataAccess
167     {
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);
174 
175     private:
176         ScDBQueryParamInternal* mpParam;
177         ScDocument*         mpDoc;
178         const ScAttrArray*  pAttrArray;
179         sal_uLong               nNumFormat;     // for CalcAsShown
180         sal_uLong               nNumFmtIndex;
181         SCCOL               nCol;
182         SCROW               nRow;
183         SCSIZE              nColRow;
184         SCROW               nAttrEndRow;
185         SCTAB               nTab;
186         short               nNumFmtType;
187         bool                bCalcAsShown;
188     };
189 
190     class DataAccessMatrix : public DataAccess
191     {
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);
198 
199     private:
200         bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;
201 
202         ScDBQueryParamMatrix* mpParam;
203         SCROW mnCurRow;
204         SCROW mnRows;
205         SCCOL mnCols;
206     };
207 
208     ::std::auto_ptr<ScDBQueryParamBase> mpParam;
209     ::std::auto_ptr<DataAccess>         mpData;
210 
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);
217 };
218 
219 // ============================================================================
220 
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     sal_Bool            bSubTotal;
236 
237     ScBaseCell*     GetThis();
238 public:
239                     ScCellIterator(ScDocument* pDocument,
240                                    SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
241                                    SCCOL nECol, SCROW nERow, SCTAB nETab,
242                                    sal_Bool bSTotal = sal_False);
243                     ScCellIterator(ScDocument* pDocument,
244                                    const ScRange& rRange, sal_Bool bSTotal = sal_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 ); }
251 };
252 
253 class ScQueryCellIterator           // alle nichtleeren Zellen in einem Bereich
254 {                                   // durchgehen
255     enum StopOnMismatchBits
256     {
257         nStopOnMismatchDisabled = 0x00,
258         nStopOnMismatchEnabled  = 0x01,
259         nStopOnMismatchOccured  = 0x02,
260         nStopOnMismatchExecuted = nStopOnMismatchEnabled | nStopOnMismatchOccured
261     };
262 
263     enum TestEqualConditionBits
264     {
265         nTestEqualConditionDisabled = 0x00,
266         nTestEqualConditionEnabled  = 0x01,
267         nTestEqualConditionMatched  = 0x02,
268         nTestEqualConditionFulfilled = nTestEqualConditionEnabled | nTestEqualConditionMatched
269     };
270 
271 private:
272     ScQueryParam    aParam;
273     ScDocument*     pDoc;
274     const ScAttrArray*  pAttrArray;
275     sal_uLong           nNumFormat;
276     SCTAB           nTab;
277     SCCOL           nCol;
278     SCROW           nRow;
279     SCSIZE          nColRow;
280     SCROW           nAttrEndRow;
281     sal_uInt8            nStopOnMismatch;
282     sal_uInt8            nTestEqualCondition;
283     sal_Bool            bAdvanceQuery;
284     sal_Bool            bIgnoreMismatchOnLeadingStrings;
285 
286     ScBaseCell*     GetThis();
287 
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()
296                      */
297     ScBaseCell*     BinarySearch();
298 
299 public:
300                     ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
301                                         const ScQueryParam& aParam, sal_Bool bMod = sal_True);
302                                         // fuer bMod = sal_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; }
308 
309                     // setzt alle Entry.nField einen weiter, wenn Spalte
310                     // wechselt, fuer ScInterpreter ScHLookup()
311     void            SetAdvanceQueryParamEntryField( sal_Bool bVal )
312                         { bAdvanceQuery = bVal; }
313     void            AdvanceQueryParamEntryField();
314 
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 sal_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( sal_Bool bVal )
326                         {
327                             nStopOnMismatch = sal::static_int_cast<sal_uInt8>(bVal ? nStopOnMismatchEnabled :
328                                 nStopOnMismatchDisabled);
329                         }
330     sal_Bool            StoppedOnMismatch() const
331                         { return nStopOnMismatch == nStopOnMismatchExecuted; }
332 
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( sal_Bool bVal )
339                         {
340                             nTestEqualCondition = sal::static_int_cast<sal_uInt8>(bVal ?
341                                 nTestEqualConditionEnabled :
342                                 nTestEqualConditionDisabled);
343                         }
344     sal_Bool            IsEqualConditionFulfilled() const
345                         { return nTestEqualCondition == nTestEqualConditionFulfilled; }
346 
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.
353 
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.
359 
360                         @param bIgnoreMismatchOnLeadingStrings
361                             Normally strings are sorted behind numerical
362                             values. If this parameter is sal_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.
367 
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!
373                       */
374     sal_Bool            FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
375                         SCROW& nFoundRow, sal_Bool bSearchForEqualAfterMismatch = sal_False,
376                         sal_Bool bIgnoreMismatchOnLeadingStrings = sal_True );
377 };
378 
379 class ScDocAttrIterator             // alle Attribut-Bereiche
380 {
381 private:
382     ScDocument*     pDoc;
383     SCTAB           nTab;
384     SCCOL           nEndCol;
385     SCROW           nStartRow;
386     SCROW           nEndRow;
387     SCCOL           nCol;
388     ScAttrIterator* pColIter;
389 
390 public:
391                     ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable,
392                                     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
393                     ~ScDocAttrIterator();
394 
395     const ScPatternAttr*    GetNext( SCCOL& rCol, SCROW& rRow1, SCROW& rRow2 );
396 };
397 
398 class ScAttrRectIterator            // alle Attribut-Bereiche, auch Bereiche ueber mehrere Spalten
399 {
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;
409 
410 public:
411                     ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
412                                     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
413                     ~ScAttrRectIterator();
414 
415     void                    DataChanged();
416     const ScPatternAttr*    GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
417 };
418 
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           nStartRow;
427     SCROW           nEndRow;
428     SCROW*          pNextRows;
429     SCSIZE*         pNextIndices;
430     SCCOL           nCol;
431     SCROW           nRow;
432     sal_Bool            bMore;
433 
434 public:
435                     ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
436                                     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
437                     ~ScHorizontalCellIterator();
438 
439     ScBaseCell*     GetNext( SCCOL& rCol, SCROW& rRow );
440     sal_Bool            ReturnNext( SCCOL& rCol, SCROW& rRow );
441     /// Set a(nother) sheet and (re)init.
442     void            SetTab( SCTAB nTab );
443 
444 private:
445     void            Advance();
446 };
447 
448 
449 /** Row-wise value iterator. */
450 class ScHorizontalValueIterator
451 {
452 private:
453     ScDocument               *pDoc;
454     const ScAttrArray        *pAttrArray;
455     ScHorizontalCellIterator *pCellIter;
456     sal_uLong                 nNumFormat;     // for CalcAsShown
457     sal_uLong                 nNumFmtIndex;
458     SCTAB                     nEndTab;
459     SCCOL                     nCurCol;
460     SCROW                     nCurRow;
461     SCTAB                     nCurTab;
462     SCROW                     nAttrEndRow;
463     short                     nNumFmtType;
464     bool                      bNumValid;
465     bool                      bSubTotal;
466     bool                      bCalcAsShown;
467     bool                      bTextAsZero;
468 
469 public:
470 
471                     ScHorizontalValueIterator( ScDocument* pDocument,
472                                                const ScRange& rRange,
473                                                bool bSTotal = false,
474                                                bool bTextAsZero = false );
475                     ~ScHorizontalValueIterator();
476     void            GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
477     /// Does NOT reset rValue if no value found!
478     bool            GetNext( double& rValue, sal_uInt16& rErr );
479 };
480 
481 
482 //
483 //  gibt alle Bereiche mit nicht-Default-Formatierung zurueck (horizontal)
484 //
485 
486 class ScHorizontalAttrIterator
487 {
488 private:
489     ScDocument*             pDoc;
490     SCTAB                   nTab;
491     SCCOL                   nStartCol;
492     SCROW                   nStartRow;
493     SCCOL                   nEndCol;
494     SCROW                   nEndRow;
495 
496     SCROW*                  pNextEnd;
497     SCSIZE*                 pIndices;
498     const ScPatternAttr**   ppPatterns;
499     SCCOL                   nCol;
500     SCROW                   nRow;
501     sal_Bool                    bRowEmpty;
502 
503 public:
504             ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
505                                     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
506             ~ScHorizontalAttrIterator();
507 
508     const ScPatternAttr*    GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow );
509 };
510 
511 //
512 //  gibt nichtleere Zellen und Bereiche mit Formatierung zurueck (horizontal)
513 //
514 
515 class SC_DLLPUBLIC ScUsedAreaIterator
516 {
517 private:
518     ScHorizontalCellIterator    aCellIter;
519     ScHorizontalAttrIterator    aAttrIter;
520 
521     SCCOL                   nNextCol;
522     SCROW                   nNextRow;
523 
524     SCCOL                   nCellCol;
525     SCROW                   nCellRow;
526     const ScBaseCell*       pCell;
527     SCCOL                   nAttrCol1;
528     SCCOL                   nAttrCol2;
529     SCROW                   nAttrRow;
530     const ScPatternAttr*    pPattern;
531 
532     SCCOL                   nFoundStartCol;         // Ergebnisse nach GetNext
533     SCCOL                   nFoundEndCol;
534     SCROW                   nFoundRow;
535     const ScPatternAttr*    pFoundPattern;
536     const ScBaseCell*       pFoundCell;
537 
538 public:
539             ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
540                                 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
541             ~ScUsedAreaIterator();
542 
543     sal_Bool    GetNext();
544 
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 ScBaseCell*       GetCell() const         { return pFoundCell; }
550 };
551 
552 // ============================================================================
553 
554 class ScRowBreakIterator
555 {
556 public:
557     static SCROW NOT_FOUND;
558 
559     explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
560     SCROW first();
561     SCROW next();
562 
563 private:
564     ::std::set<SCROW>& mrBreaks;
565     ::std::set<SCROW>::const_iterator maItr;
566     ::std::set<SCROW>::const_iterator maEnd;
567 };
568 
569 #endif
570 
571 
572