Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/inc/dociter.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
#pragma once
21
22
#include "address.hxx"
23
#include "formulagroup.hxx"
24
#include "global.hxx"
25
#include "scdllapi.h"
26
#include "cellvalue.hxx"
27
#include "mtvelements.hxx"
28
#include "queryparam.hxx"
29
#include "attarray.hxx"
30
#include <vcl/outdev.hxx>
31
#include <vcl/vclptr.hxx>
32
33
#include <memory>
34
#include <set>
35
#include <vector>
36
#include <optional>
37
38
class ScDocument;
39
class ScPatternAttr;
40
class ScMatrix;
41
class ScFormulaCell;
42
struct ScInterpreterContext;
43
enum class SvNumFormatType : sal_Int16;
44
45
class ScValueIterator            // walk through all values in an area
46
{
47
    typedef sc::CellStoreType::const_position_type PositionType;
48
49
    const ScDocument& mrDoc;
50
    ScInterpreterContext& mrContext;
51
    const ScAttrArray*  pAttrArray;
52
    sal_uInt32      nNumFormat;     // for CalcAsShown
53
    sal_uInt32      nNumFmtIndex;
54
    ScAddress       maStartPos;
55
    ScAddress       maEndPos;
56
    SCCOL           mnCol;
57
    SCTAB           mnTab;
58
    SCROW           nAttrEndRow;
59
    SubtotalFlags   mnSubTotalFlags;
60
    SvNumFormatType nNumFmtType;
61
    bool            bNumValid;
62
    bool            bCalcAsShown;
63
    bool            bTextAsZero;
64
65
    const sc::CellStoreType* mpCells;
66
    PositionType maCurPos;
67
68
    SCROW GetRow() const;
69
    void IncBlock();
70
    void IncPos();
71
72
    /**
73
     * See if the cell at the current position is a non-empty cell. If not,
74
     * move to the next non-empty cell position.
75
     */
76
    bool GetThis( double& rValue, FormulaError& rErr );
77
78
public:
79
80
    ScValueIterator(ScInterpreterContext& rContext,
81
        const ScRange& rRange, SubtotalFlags nSubTotalFlags = SubtotalFlags::NONE,
82
        bool bTextAsZero = false );
83
84
    void GetCurNumFmtInfo( SvNumFormatType& nType, sal_uInt32& nIndex );
85
86
    /// Does NOT reset rValue if no value found!
87
    bool GetFirst( double& rValue, FormulaError& rErr );
88
89
    /// Does NOT reset rValue if no value found!
90
    bool GetNext( double& rValue, FormulaError& rErr );
91
};
92
93
class ScDBQueryDataIterator
94
{
95
public:
96
    struct Value
97
    {
98
        OUString        maString;
99
        double          mfValue;
100
        FormulaError    mnError;
101
        bool            mbIsNumber;
102
103
        Value();
104
    };
105
106
private:
107
    static const sc::CellStoreType* GetColumnCellStore(ScDocument& rDoc, SCTAB nTab, SCCOL nCol);
108
    static const ScAttrArray* GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol);
109
    static bool IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, const ScRefCellValue* pCell);
110
111
    class DataAccess
112
    {
113
    public:
114
        DataAccess();
115
        virtual ~DataAccess() = 0;
116
        virtual bool getCurrent(Value& rValue) = 0;
117
        virtual bool getFirst(Value& rValue) = 0;
118
        virtual bool getNext(Value& rValue) = 0;
119
    };
120
121
    class DataAccessInternal final : public DataAccess
122
    {
123
        typedef std::pair<sc::CellStoreType::const_iterator,size_t> PositionType;
124
    public:
125
        DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument& rDoc, const ScInterpreterContext& rContext);
126
        virtual ~DataAccessInternal() override;
127
        virtual bool getCurrent(Value& rValue) override;
128
        virtual bool getFirst(Value& rValue) override;
129
        virtual bool getNext(Value& rValue) override;
130
131
    private:
132
        void incBlock();
133
        void incPos();
134
135
        const sc::CellStoreType* mpCells;
136
        PositionType maCurPos;
137
        ScDBQueryParamInternal* mpParam;
138
        ScDocument&         mrDoc;
139
        const ScInterpreterContext& mrContext;
140
        const ScAttrArray*  pAttrArray;
141
        sal_uInt32          nNumFormat;     // for CalcAsShown
142
        sal_uInt32          nNumFmtIndex;
143
        SCCOL               nCol;
144
        SCROW               nRow;
145
        SCROW               nAttrEndRow;
146
        SCTAB               nTab;
147
        SvNumFormatType     nNumFmtType;
148
        bool                bCalcAsShown;
149
    };
150
151
    class DataAccessMatrix final : public DataAccess
152
    {
153
    public:
154
        DataAccessMatrix(ScDBQueryParamMatrix* pParam);
155
        virtual ~DataAccessMatrix() override;
156
        virtual bool getCurrent(Value& rValue) override;
157
        virtual bool getFirst(Value& rValue) override;
158
        virtual bool getNext(Value& rValue) override;
159
160
    private:
161
        bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;
162
163
        ScDBQueryParamMatrix* mpParam;
164
        SCROW mnCurRow;
165
        SCROW mnRows;
166
    };
167
168
    ::std::unique_ptr<ScDBQueryParamBase> mpParam;
169
    ::std::unique_ptr<DataAccess>         mpData;
170
171
public:
172
                    ScDBQueryDataIterator(ScDocument& rDocument, const ScInterpreterContext& rContext, std::unique_ptr<ScDBQueryParamBase> pParam);
173
    /// Does NOT reset rValue if no value found!
174
    bool            GetFirst(Value& rValue);
175
    /// Does NOT reset rValue if no value found!
176
    bool            GetNext(Value& rValue);
177
};
178
179
class ScFormulaGroupIterator
180
{
181
private:
182
    ScDocument& mrDoc;
183
    SCTAB mnTab;
184
    SCCOL mnCol;
185
    bool mbNullCol;
186
    size_t mnIndex;
187
    std::vector<sc::FormulaGroupEntry> maEntries;
188
189
public:
190
    ScFormulaGroupIterator( ScDocument& rDoc );
191
192
    sc::FormulaGroupEntry* first();
193
    sc::FormulaGroupEntry* next();
194
};
195
196
/**
197
 * Walk through all cells in an area. For SubTotal and Aggregate depending on mnSubTotalFlags.
198
 **/
199
class ScCellIterator
200
{
201
    typedef std::pair<sc::CellStoreType::const_iterator, size_t> PositionType;
202
203
    ScDocument&   mrDoc;
204
    ScAddress     maStartPos;
205
    ScAddress     maEndPos;
206
    ScAddress     maCurPos;
207
208
    PositionType  maCurColPos;
209
    SubtotalFlags mnSubTotalFlags;
210
211
    ScRefCellValue maCurCell;
212
213
    void incBlock();
214
    void incPos();
215
    void setPos(size_t nPos);
216
217
    const ScColumn* getColumn() const;
218
219
    void init();
220
    bool getCurrent();
221
222
public:
223
    ScCellIterator( ScDocument& rDoc, const ScRange& rRange, SubtotalFlags nSubTotalFlags = SubtotalFlags::NONE );
224
225
2.14k
    const ScAddress& GetPos() const { return maCurPos; }
226
227
28.8M
    CellType getType() const { return maCurCell.getType();}
228
    OUString getString() const;
229
31.8k
    const EditTextObject* getEditText() const { return maCurCell.getEditText();}
230
28.4M
    ScFormulaCell* getFormulaCell() { return maCurCell.getFormula();}
231
0
    const ScFormulaCell* getFormulaCell() const { return maCurCell.getFormula();}
232
    ScCellValue getCellValue() const;
233
0
    const ScRefCellValue& getRefCellValue() const { return maCurCell;}
234
235
    bool hasString() const;
236
    bool isEmpty() const;
237
    bool equalsWithoutFormat( const ScAddress& rPos ) const;
238
239
    bool first();
240
    bool next();
241
};
242
243
class ScDocAttrIterator             // all attribute areas
244
{
245
private:
246
    ScDocument&     rDoc;
247
    SCTAB           nTab;
248
    SCCOL           nEndCol;
249
    SCROW           nStartRow;
250
    SCROW           nEndRow;
251
    SCCOL           nCol;
252
    std::optional<ScAttrIterator> moColIter;
253
254
public:
255
                    ScDocAttrIterator(ScDocument& rDocument, SCTAB nTable,
256
                                    SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
257
258
    const ScPatternAttr*    GetNext( SCCOL& rCol, SCROW& rRow1, SCROW& rRow2 );
259
};
260
261
class ScAttrRectIterator            // all attribute areas, including areas stretching
262
                                    // across more than one column
263
{
264
private:
265
    ScDocument&     rDoc;
266
    SCTAB           nTab;
267
    SCCOL           nEndCol;
268
    SCROW           nStartRow;
269
    SCROW           nEndRow;
270
    SCCOL           nIterStartCol;
271
    SCCOL           nIterEndCol;
272
    std::optional<ScAttrIterator>
273
                    moColIter;
274
275
public:
276
                    ScAttrRectIterator(ScDocument& rDocument, SCTAB nTable,
277
                                    SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
278
279
    void                    DataChanged();
280
    const ScPatternAttr*    GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
281
};
282
283
class ScHorizontalCellIterator      // walk through all non empty cells in an area
284
{                                   // row by row
285
    struct ColParam
286
    {
287
        sc::CellStoreType::const_iterator maPos;
288
        sc::CellStoreType::const_iterator maEnd;
289
        SCCOL mnCol;
290
    };
291
292
    std::vector<ColParam>::iterator maColPos;
293
    std::vector<ColParam> maColPositions;
294
295
    ScDocument&     rDoc;
296
    SCTAB           mnTab;
297
    SCCOL           nStartCol;
298
    SCCOL           nEndCol;
299
    SCROW           nStartRow;
300
    SCROW           nEndRow;
301
    SCCOL           mnCol;
302
    SCROW           mnRow;
303
    ScRefCellValue  maCurCell;
304
    bool            mbMore;
305
306
public:
307
    ScHorizontalCellIterator(ScDocument& rDocument, SCTAB nTable,
308
                    SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
309
    ~ScHorizontalCellIterator();
310
311
    ScRefCellValue* GetNext( SCCOL& rCol, SCROW& rRow );
312
    bool            GetPos( SCCOL& rCol, SCROW& rRow );
313
    /// Set a(nother) sheet and (re)init.
314
    void            SetTab( SCTAB nTab );
315
316
private:
317
    void            Advance();
318
    void            SkipInvalid();
319
    bool            SkipInvalidInRow();
320
    SCROW           FindNextNonEmptyRow();
321
};
322
323
/** Row-wise value iterator. */
324
class ScHorizontalValueIterator
325
{
326
private:
327
    ScDocument&               rDoc;
328
    const ScAttrArray*        pAttrArray;
329
    std::unique_ptr<ScHorizontalCellIterator>
330
                              pCellIter;
331
    sal_uInt32                nNumFormat;     // for CalcAsShown
332
    SCTAB                     nEndTab;
333
    SCCOL                     nCurCol;
334
    SCROW                     nCurRow;
335
    SCTAB                     nCurTab;
336
    SCROW                     nAttrEndRow;
337
    bool                      bCalcAsShown;
338
339
public:
340
341
                    ScHorizontalValueIterator( ScDocument& rDocument,
342
                                               const ScRange& rRange );
343
                    ~ScHorizontalValueIterator();
344
    /// Does NOT reset rValue if no value found!
345
    bool            GetNext( double& rValue, FormulaError& rErr );
346
};
347
348
class ScHorizontalAttrIterator
349
{
350
private:
351
    ScDocument&             rDoc;
352
    SCTAB                   nTab;
353
    SCCOL                   nStartCol;
354
    SCROW                   nStartRow;
355
    SCCOL                   nEndCol;
356
    SCROW                   nEndRow;
357
358
    std::unique_ptr<SCROW[]>  pNextEnd;
359
    std::unique_ptr<SCCOL[]>  pHorizEnd;
360
    std::unique_ptr<SCSIZE[]> pIndices;
361
    std::unique_ptr<const ScPatternAttr*[]>
362
                              ppPatterns;
363
    SCCOL                   nCol;
364
    SCROW                   nRow;
365
    SCROW                   nMinNextEnd;
366
367
    void InitForNextRow(bool bInitialization);
368
369
public:
370
            ScHorizontalAttrIterator( ScDocument& rDocument, SCTAB nTable,
371
                                    SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
372
            ~ScHorizontalAttrIterator();
373
374
    const ScPatternAttr*    GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow );
375
};
376
377
//  returns non-empty cells and areas with formatting (horizontal)
378
379
class SC_DLLPUBLIC ScUsedAreaIterator
380
{
381
private:
382
    ScHorizontalCellIterator    aCellIter;
383
    ScHorizontalAttrIterator    aAttrIter;
384
385
    SCCOL                   nNextCol;
386
    SCROW                   nNextRow;
387
388
    SCCOL                   nCellCol;
389
    SCROW                   nCellRow;
390
    ScRefCellValue*         pCell;
391
    SCCOL                   nAttrCol1;
392
    SCCOL                   nAttrCol2;
393
    SCROW                   nAttrRow;
394
    const ScPatternAttr*    pPattern;
395
396
    SCCOL                   nFoundStartCol;         // results after GetNext
397
    SCCOL                   nFoundEndCol;
398
    SCROW                   nFoundRow;
399
    const ScPatternAttr*    pFoundPattern;
400
401
    ScRefCellValue maFoundCell;
402
403
public:
404
            ScUsedAreaIterator( ScDocument& rDocument, SCTAB nTable,
405
                                SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
406
            ~ScUsedAreaIterator();
407
408
    bool    GetNext();
409
410
0
    SCCOL                   GetStartCol() const     { return nFoundStartCol; }
411
0
    SCCOL                   GetEndCol() const       { return nFoundEndCol; }
412
0
    SCROW                   GetRow() const          { return nFoundRow; }
413
0
    const ScPatternAttr*    GetPattern() const      { return pFoundPattern; }
414
0
    const ScRefCellValue&   GetCell() const { return maFoundCell;}
415
};
416
417
class ScRowBreakIterator
418
{
419
public:
420
    static constexpr SCROW NOT_FOUND = -1;
421
422
    explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
423
    SCROW first();
424
    SCROW next();
425
426
private:
427
    ::std::set<SCROW>& mrBreaks;
428
    ::std::set<SCROW>::const_iterator maItr;
429
    ::std::set<SCROW>::const_iterator maEnd;
430
};
431
432
class ScDocRowHeightUpdater
433
{
434
public:
435
    struct TabRanges
436
    {
437
        SCTAB mnTab;
438
        ScFlatBoolRowSegments maRanges;
439
440
        TabRanges(SCTAB nTab, SCROW nMaxRow);
441
    };
442
443
    /**
444
     * Passing a NULL pointer to pTabRangesArray forces the heights of all
445
     * rows in all tables to be updated.
446
     */
447
    explicit ScDocRowHeightUpdater(
448
        ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY,
449
        const ::std::vector<TabRanges>* pTabRangesArray);
450
451
    void update(const bool bOnlyUsedRows = false);
452
453
private:
454
    void updateAll(const bool bOnlyUsedRows);
455
456
private:
457
    ScDocument& mrDoc;
458
    VclPtr<OutputDevice> mpOutDev;
459
    double mfPPTX;
460
    double mfPPTY;
461
    const ::std::vector<TabRanges>* mpTabRangesArray;
462
};
463
464
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */