Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/inc/dbdata.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 "scdllapi.h"
23
#include "refreshtimer.hxx"
24
#include "address.hxx"
25
#include "global.hxx"
26
#include "rangelst.hxx"
27
28
#include <svl/listener.hxx>
29
#include <svl/poolitem.hxx>
30
31
#include <memory>
32
#include <set>
33
#include <vector>
34
35
class ScDocument;
36
struct ScSortParam;
37
struct ScQueryParam;
38
struct ScSubTotalParam;
39
class ScTokenArray;
40
41
class SC_DLLPUBLIC ScDatabaseSettingItem final : public SfxPoolItem
42
{
43
    bool mbHeaderRow;
44
    bool mbTotalRow;
45
    bool mbFirstCol;
46
    bool mbLastCol;
47
    bool mbStripedRows;
48
    bool mbStripedCols;
49
    bool mbShowFilters;
50
    OUString maStyleID;
51
52
public:
53
    static SfxPoolItem* CreateDefault();
54
    DECLARE_ITEM_TYPE_FUNCTION(ScDatabaseSettingItem)
55
    ScDatabaseSettingItem();
56
    ScDatabaseSettingItem(bool bHeaderRow, bool bTotalRow, bool bFirstCol, bool bLastCol,
57
                          bool bStripedRows, bool bStripedCols, bool bShowFilter,
58
                          const OUString& aStyleID);
59
    ScDatabaseSettingItem( const ScDatabaseSettingItem& rItem );
60
    virtual ~ScDatabaseSettingItem() override;
61
62
    virtual bool            QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const override;
63
    virtual bool            PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) override;
64
65
    ScDatabaseSettingItem& operator=( const ScDatabaseSettingItem& rItem );
66
    virtual bool operator==( const SfxPoolItem& ) const override;
67
    virtual ScDatabaseSettingItem* Clone( SfxItemPool *pPool = nullptr ) const override;
68
69
    bool HasHeaderRow() const;
70
    bool HasTotalRow() const;
71
    bool HasFirstCol() const;
72
    bool HasLastCol() const;
73
    bool HasStripedRows() const;
74
    bool HasStripedCols() const;
75
    bool HasShowFilters() const;
76
    const OUString& GetStyleID() const;
77
};
78
79
/** Enum used to indicate which portion of the DBArea is to be considered. */
80
enum class ScDBDataPortion
81
{
82
    TOP_LEFT,   ///< top left cell of area
83
    AREA        ///< entire area
84
};
85
86
// TODO: this can be merged with struct TableColumnModel
87
struct TableColumnAttributes
88
{
89
    std::optional<OUString> maTotalsRowLabel = std::nullopt;
90
    std::optional<OUString> maTotalsFunction = std::nullopt;
91
    std::optional<OUString> maCustomFunction = std::nullopt;
92
    // Whether the totals row cell for this column holds any value at all, whether or
93
    // not that value ended up producing a label or a function above. A column whose
94
    // totals row cell is empty is not the same as a column whose cell holds content
95
    // that this class chose not to describe as a label or a function.
96
    bool mbHasContent = false;
97
};
98
99
// xmlColumnPr attributes
100
struct XmlColumnPrModel
101
{
102
    sal_uInt32          mnMapId;
103
    OUString            msXpath;
104
    OUString            msXmlDataType;
105
    bool                mbDenormalized;
106
107
    explicit            XmlColumnPrModel();
108
};
109
110
struct TableColumnModel
111
{
112
    typedef std::unique_ptr<XmlColumnPrModel> XmlColumnPrModelPtr;
113
    XmlColumnPrModelPtr mxXmlColumnPr; // Special settings for XML Column Properties.
114
    XmlColumnPrModel&   createXmlColumnPr();
115
116
    OUString            maUniqueName; // unique name of the <tableColumn>
117
118
    explicit            TableColumnModel();
119
};
120
121
/** Container base class to provide selected access for ScDBData. */
122
class ScDBDataContainerBase
123
{
124
public:
125
141k
    ScDBDataContainerBase( ScDocument& rDoc ) : mrDoc(rDoc) {}
126
141k
    virtual ~ScDBDataContainerBase() {}
127
    ScDocument& GetDocument() const;
128
    ScRangeList& GetDirtyTableColumnNames();
129
130
protected:
131
    ScDocument& mrDoc;
132
    ScRangeList maDirtyTableColumnNames;
133
};
134
135
136
struct SAL_DLLPUBLIC_RTTI ScTableStyleParam
137
{
138
    OUString maStyleID;
139
    bool mbRowStripes;
140
    bool mbColumnStripes;
141
    bool mbFirstColumn;
142
    bool mbLastColumn;
143
144
    SC_DLLPUBLIC ScTableStyleParam();
145
146
    bool operator== (const ScTableStyleParam& rData) const;
147
};
148
149
class SAL_DLLPUBLIC_RTTI ScDBData final : public SvtListener, public ScRefreshTimer
150
{
151
private:
152
    std::unique_ptr<ScSortParam> mpSortParam;
153
    std::unique_ptr<ScQueryParam> mpQueryParam;
154
    std::unique_ptr<ScSubTotalParam> mpSubTotal;
155
    std::unique_ptr<ScImportParam> mpImportParam;
156
    std::unique_ptr<ScTableStyleParam> mpTableStyles;
157
158
    ScDBDataContainerBase* mpContainer;
159
160
    /// DBParam
161
    const OUString aName;
162
    OUString aUpper;
163
    OUString        aTableType;
164
    SCTAB           nTable;
165
    SCCOL           nStartCol;
166
    SCROW           nStartRow;
167
    SCCOL           nEndCol;
168
    SCROW           nEndRow;
169
    bool            bByRow;
170
    bool            bHasHeader;
171
    bool            bHasTotals;
172
    bool            bDoSize;
173
    bool            bKeepFmt;
174
    bool            bStripData;
175
176
    /// QueryParam
177
    bool            bIsAdvanced;        ///< true if created by advanced filter
178
    ScRange         aAdvSource;         ///< source range
179
180
    bool            bDBSelection;       ///< not in Param: if selection, block update
181
182
    sal_uInt16      nIndex;             ///< unique index formulas
183
    bool            bAutoFilter;        ///< AutoFilter? (not saved)
184
    bool            bModified;          ///< is set/cleared for/by(?) UpdateReference
185
186
    ::std::vector< OUString > maTableColumnNames;   ///< names of table columns
187
    ::std::vector< TableColumnModel > maTableColumnModel;
188
    bool            mbTableColumnNamesDirty;
189
    SCSIZE          nFilteredRowCount;
190
191
    using ScRefreshTimer::operator==;
192
193
public:
194
    struct less
195
    {
196
        bool operator() (const std::unique_ptr<ScDBData>& left, const std::unique_ptr<ScDBData>& right) const;
197
    };
198
199
    SC_DLLPUBLIC ScDBData(const OUString& rName,
200
             SCTAB nTab,
201
             SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bByR = true, bool bHasH = true, bool bTotals = false,
202
                          const OUString& rTableType = u""_ustr,
203
                          const OUString& rTableStyleID = u""_ustr);
204
    ScDBData(const ScDBData& rData);
205
    ScDBData(const OUString& rName, const ScDBData& rData);
206
    SC_DLLPUBLIC virtual ~ScDBData() override;
207
208
    virtual void Notify( const SfxHint& rHint ) override;
209
210
    ScDBData&   operator= (const ScDBData& rData) ;
211
212
    bool        operator== (const ScDBData& rData) const;
213
214
3.09k
    const OUString& GetName() const { return aName; }
215
37.6k
    const OUString& GetUpperName() const { return aUpper; }
216
269
    SCTAB       GetTab() const                  { return nTable; }
217
    void        GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const;
218
    SC_DLLPUBLIC void GetArea(ScRange& rRange) const;
219
    void        SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
220
    void SetArea(ScRange const& rRange)
221
0
    {
222
0
        SetArea(rRange.aStart.Tab(), rRange.aStart.Col(), rRange.aStart.Row(),
223
0
                rRange.aEnd.Col(), rRange.aEnd.Row());
224
0
    }
225
    void        MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
226
                       SCCOL nUpdateCol = -1);
227
0
    void        SetByRow(bool bByR)             { bByRow = bByR; }
228
0
    bool        IsByRow() const                 { return bByRow; }
229
1.11k
    bool        HasHeader() const               { return bHasHeader; }
230
975
    void        SetHeader(bool bHasH)           { bHasHeader = bHasH; }
231
255
    bool        HasTotals() const               { return bHasTotals; }
232
1.09k
    void        SetTotals(bool bTotals)         { bHasTotals = bTotals; }
233
259
    void        SetIndex(sal_uInt16 nInd)           { nIndex = nInd; }
234
4.00k
    sal_uInt16  GetIndex() const                { return nIndex; }
235
0
    bool        IsDoSize() const                { return bDoSize; }
236
0
    void        SetDoSize(bool bSet)            { bDoSize = bSet; }
237
0
    bool        IsKeepFmt() const               { return bKeepFmt; }
238
0
    void        SetKeepFmt(bool bSet)           { bKeepFmt = bSet; }
239
0
    bool        IsStripData() const             { return bStripData; }
240
0
    void        SetStripData(bool bSet)         { bStripData = bSet; }
241
239
    void        SetTableType(const OUString& sTableType) { aTableType = sTableType; }
242
0
    const OUString& GetTableType() const           { return aTableType; }
243
244
249
    void        SetContainer( ScDBDataContainerBase* pContainer ) { mpContainer = pContainer; }
245
    /** Returns header row range if it has headers, else invalid range. */
246
    ScRange     GetHeaderArea() const;
247
    void        StartTableColumnNamesListener();
248
    void        EndTableColumnNamesListener();
249
    SC_DLLPUBLIC void SetTableColumnNames( ::std::vector< OUString >&& rNames );
250
0
    SC_DLLPUBLIC const ::std::vector< OUString >& GetTableColumnNames() const { return maTableColumnNames; }
251
    SC_DLLPUBLIC void SetTableColumnModel( TableColumnModel& rModel )
252
1.04k
    {
253
1.04k
        maTableColumnModel.push_back(std::move(rModel));
254
1.04k
    }
255
0
    SC_DLLPUBLIC const ::std::vector< TableColumnModel >& GetTableColumnModel() const { return maTableColumnModel; }
256
498
    bool        AreTableColumnNamesDirty() const { return mbTableColumnNamesDirty; }
257
258
    /** Refresh/update the column names with the header row's cell contents. */
259
    SC_DLLPUBLIC void RefreshTableColumnNames( ScDocument* pDoc );
260
261
    /** Refresh/update the column names with the header row's cell contents
262
        within the given range. */
263
    void RefreshTableColumnNames( ScDocument& rDoc, const ScRangeList& rRangeList );
264
265
    /** Finds the column named rName and returns the corresponding offset
266
        within the table.
267
        @returns -1 if not found.
268
269
        XXX NOTE: there is no refresh of names or anything implemented yet, use
270
        this only during document load time.
271
     */
272
    sal_Int32   GetColumnNameOffset( const OUString& rName ) const;
273
274
    /** Returns table column name if nCol is within column range and the name
275
        is stored, else an empty string. */
276
    const OUString & GetTableColumnName( SCCOL nCol ) const;
277
278
    OUString GetSourceString() const;
279
    OUString GetOperations() const;
280
281
    SC_DLLPUBLIC void GetSortParam(ScSortParam& rSortParam) const;
282
    SC_DLLPUBLIC void SetSortParam(const ScSortParam& rSortParam);
283
284
    /** Remember some more settings of ScSortParam, only to be called at
285
        anonymous DB ranges as it at least overwrites bHasHeader. */
286
    void        UpdateFromSortParam( const ScSortParam& rSortParam );
287
288
    SC_DLLPUBLIC void       GetQueryParam(ScQueryParam& rQueryParam) const;
289
    SC_DLLPUBLIC void       SetQueryParam(const ScQueryParam& rQueryParam);
290
    SC_DLLPUBLIC bool       GetAdvancedQuerySource(ScRange& rSource) const;
291
    SC_DLLPUBLIC void       SetAdvancedQuerySource(const ScRange* pSource);
292
293
    SC_DLLPUBLIC void       GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const;
294
    SC_DLLPUBLIC void       SetSubTotalParam(const ScSubTotalParam& rSubTotalParam);
295
296
    // Total row param handling for Table Styles
297
    SC_DLLPUBLIC void       ImportTotalRowParam(ScSubTotalParam& rSubTotalParam,
298
                                                const std::vector<TableColumnAttributes>& rAttributesVector,
299
                                                formula::FormulaGrammar::Grammar eGrammar) const;
300
    SC_DLLPUBLIC void       CreateTotalRowParam(ScSubTotalParam& rSubTotalParam) const;
301
302
    SC_DLLPUBLIC std::vector<TableColumnAttributes>
303
                            GetTotalRowAttributes(formula::FormulaGrammar::Grammar eGrammar) const;
304
305
    OUString    GetSimpleSubTotalFunction(const ScTokenArray* pTokens, SCCOL nCol, SCROW nHeaderRow) const;
306
307
    void        GetImportParam(ScImportParam& rImportParam) const;
308
    void        SetImportParam(const ScImportParam& rImportParam);
309
310
    bool        IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
311
    bool        IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
312
313
    bool        HasImportParam() const;
314
    SC_DLLPUBLIC bool HasQueryParam() const;
315
    bool        HasSortParam() const;
316
    bool        HasSubTotalParam() const;
317
318
0
    bool        HasImportSelection() const      { return bDBSelection; }
319
0
    void        SetImportSelection(bool bSet)   { bDBSelection = bSet; }
320
321
6.28k
    bool        HasAutoFilter() const       { return bAutoFilter; }
322
465
    void        SetAutoFilter(bool bSet)    { bAutoFilter = bSet; }
323
324
0
    bool        IsModified() const          { return bModified; }
325
10
    void        SetModified(bool bMod)      { bModified = bMod; }
326
327
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
328
    bool    UpdateReference(const ScDocument& rDoc, UpdateRefMode eUpdateRefMode, SCCOL nCol1,
329
                            SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
330
                            SCCOL nDx, SCROW nDy, SCTAB nDz);
331
332
    void ExtendDataArea(const ScDocument& rDoc);
333
    void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount);
334
    void GetFilterSelCount(SCSIZE& nSelected, SCSIZE& nTotal);
335
336
    SC_DLLPUBLIC void SetTableStyleInfo(const ScTableStyleParam& rParams);
337
    SC_DLLPUBLIC const ScTableStyleParam* GetTableStyleInfo() const;
338
339
    static ScSubTotalFunc GetSubTotalFuncFromString(std::u16string_view sFunction);
340
    static OUString GetStringFromSubTotalFunc(ScSubTotalFunc eFunc);
341
342
private:
343
344
    void AdjustTableColumnNames( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1,
345
            SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 );
346
    void InvalidateTableColumnNames( bool bSwapToEmptyNames );
347
};
348
349
class ScDBCollection
350
{
351
public:
352
    enum RangeType { GlobalNamed, GlobalAnonymous, SheetAnonymous };
353
354
    /**
355
     * Stores global named database ranges.
356
     */
357
    class SC_DLLPUBLIC NamedDBs final : public ScDBDataContainerBase
358
    {
359
        friend class ScDBCollection;
360
361
        typedef ::std::set<std::unique_ptr<ScDBData>, ScDBData::less> DBsType;
362
        DBsType m_DBs;
363
        ScDBCollection& mrParent;
364
        NamedDBs(ScDBCollection& rParent, ScDocument& rDoc);
365
        NamedDBs(const NamedDBs& r, ScDBCollection& rParent);
366
        NamedDBs(const NamedDBs&) = delete;
367
        virtual ~NamedDBs() override;
368
        NamedDBs & operator=(NamedDBs const&) = delete;
369
        void initInserted( ScDBData* p );
370
371
    public:
372
        typedef DBsType::iterator iterator;
373
        typedef DBsType::const_iterator const_iterator;
374
375
        iterator begin();
376
        iterator end();
377
        const_iterator begin() const;
378
        const_iterator end() const;
379
        ScDBData* findByIndex(sal_uInt16 nIndex);
380
        ScDBData* findByUpperName(const OUString& rName);
381
        iterator findByUpperName2(const OUString& rName);
382
        iterator findByPointer(const ScDBData* p);
383
        ScDBData* findByName(const OUString& rName);
384
385
        /** Takes ownership of p and attempts to insert it into the collection.
386
            Deletes p if it could not be inserted, i.e. duplicate name.
387
            @return <TRUE/> if inserted, else <FALSE/>.
388
         */
389
        bool insert(std::unique_ptr<ScDBData> p);
390
391
        iterator erase(const iterator& itr);
392
        bool empty() const;
393
        size_t size() const;
394
        bool operator== (const NamedDBs& r) const;
395
    };
396
397
    /**
398
     * Stores global anonymous database ranges.
399
     */
400
    class AnonDBs
401
    {
402
        typedef ::std::vector<std::unique_ptr<ScDBData>> DBsType;
403
        DBsType m_DBs;
404
405
        AnonDBs& operator=(AnonDBs const&) = delete;
406
407
    public:
408
        AnonDBs();
409
        AnonDBs(AnonDBs const&);
410
411
        typedef DBsType::iterator iterator;
412
        typedef DBsType::const_iterator const_iterator;
413
414
        iterator begin();
415
        iterator end();
416
        const_iterator begin() const;
417
        const_iterator end() const;
418
        const ScDBData* findAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
419
        const ScDBData* findByRange(const ScRange& rRange) const;
420
        void deleteOnTab(SCTAB nTab);
421
        ScDBData* getByRange(const ScRange& rRange);
422
        void insert(ScDBData* p);
423
        iterator erase(const iterator& itr);
424
        bool empty() const;
425
        bool has( const ScDBData* p ) const;
426
        bool operator== (const AnonDBs& r) const;
427
    };
428
429
private:
430
    Link<Timer *, void> aRefreshHandler;
431
    ScDocument& rDoc;
432
    sal_uInt16 nEntryIndex;         ///< counter for unique indices
433
    NamedDBs maNamedDBs;
434
    AnonDBs maAnonDBs;
435
436
public:
437
    ScDBCollection(ScDocument& rDocument);
438
    ScDBCollection(const ScDBCollection& r);
439
440
1.48M
    NamedDBs& getNamedDBs() { return maNamedDBs;}
441
1.91k
    const NamedDBs& getNamedDBs() const { return maNamedDBs;}
442
443
0
    AnonDBs& getAnonDBs() { return maAnonDBs;}
444
0
    const AnonDBs& getAnonDBs() const { return maAnonDBs;}
445
446
    const ScDBData* GetTableDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
447
    ScDBData* GetTableDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion);
448
    const ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
449
    ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion);
450
    const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
451
    SC_DLLPUBLIC ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
452
    SC_DLLPUBLIC ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab );
453
    SC_DLLPUBLIC std::vector<ScDBData*> GetAllDBsFromTab(SCTAB nTab);
454
    std::vector<const ScDBData*> GetAllNamedDBsInArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
455
                                                      SCROW nRow2, SCTAB nTab) const;
456
457
    void RefreshDirtyTableColumnNames();
458
459
    void    DeleteOnTab( SCTAB nTab );
460
    void    UpdateReference(UpdateRefMode eUpdateRefMode,
461
                                SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
462
                                SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
463
                                SCCOL nDx, SCROW nDy, SCTAB nDz);
464
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
465
    void    CopyToTable(SCTAB nOldPos, SCTAB nNewPos);
466
467
    void            SetRefreshHandler( const Link<Timer *, void>& rLink )
468
20.1k
                        { aRefreshHandler = rLink; }
469
0
    const Link<Timer *, void>& GetRefreshHandler() const { return aRefreshHandler; }
470
471
    SC_DLLPUBLIC bool empty() const;
472
    bool operator== (const ScDBCollection& r) const;
473
};
474
475
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */