Coverage Report

Created: 2026-04-09 11:41

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
};
93
94
// xmlColumnPr attributes
95
struct XmlColumnPrModel
96
{
97
    sal_uInt32          mnMapId;
98
    OUString            msXpath;
99
    OUString            msXmlDataType;
100
    bool                mbDenormalized;
101
102
    explicit            XmlColumnPrModel();
103
};
104
105
struct TableColumnModel
106
{
107
    typedef std::unique_ptr<XmlColumnPrModel> XmlColumnPrModelPtr;
108
    XmlColumnPrModelPtr mxXmlColumnPr; // Special settings for XML Column Properties.
109
    XmlColumnPrModel&   createXmlColumnPr();
110
111
    OUString            maUniqueName; // unique name of the <tableColumn>
112
113
    explicit            TableColumnModel();
114
};
115
116
/** Container base class to provide selected access for ScDBData. */
117
class ScDBDataContainerBase
118
{
119
public:
120
166k
    ScDBDataContainerBase( ScDocument& rDoc ) : mrDoc(rDoc) {}
121
166k
    virtual ~ScDBDataContainerBase() {}
122
    ScDocument& GetDocument() const;
123
    ScRangeList& GetDirtyTableColumnNames();
124
125
protected:
126
    ScDocument& mrDoc;
127
    ScRangeList maDirtyTableColumnNames;
128
};
129
130
131
struct SAL_DLLPUBLIC_RTTI ScTableStyleParam
132
{
133
    OUString maStyleID;
134
    bool mbRowStripes;
135
    bool mbColumnStripes;
136
    bool mbFirstColumn;
137
    bool mbLastColumn;
138
139
    SC_DLLPUBLIC ScTableStyleParam();
140
141
    bool operator== (const ScTableStyleParam& rData) const;
142
};
143
144
class SAL_DLLPUBLIC_RTTI ScDBData final : public SvtListener, public ScRefreshTimer
145
{
146
private:
147
    std::unique_ptr<ScSortParam> mpSortParam;
148
    std::unique_ptr<ScQueryParam> mpQueryParam;
149
    std::unique_ptr<ScSubTotalParam> mpSubTotal;
150
    std::unique_ptr<ScImportParam> mpImportParam;
151
    std::unique_ptr<ScTableStyleParam> mpTableStyles;
152
153
    ScDBDataContainerBase* mpContainer;
154
155
    /// DBParam
156
    const OUString aName;
157
    OUString aUpper;
158
    OUString        aTableType;
159
    SCTAB           nTable;
160
    SCCOL           nStartCol;
161
    SCROW           nStartRow;
162
    SCCOL           nEndCol;
163
    SCROW           nEndRow;
164
    bool            bByRow;
165
    bool            bHasHeader;
166
    bool            bHasTotals;
167
    bool            bDoSize;
168
    bool            bKeepFmt;
169
    bool            bStripData;
170
171
    /// QueryParam
172
    bool            bIsAdvanced;        ///< true if created by advanced filter
173
    ScRange         aAdvSource;         ///< source range
174
175
    bool            bDBSelection;       ///< not in Param: if selection, block update
176
177
    sal_uInt16      nIndex;             ///< unique index formulas
178
    bool            bAutoFilter;        ///< AutoFilter? (not saved)
179
    bool            bModified;          ///< is set/cleared for/by(?) UpdateReference
180
181
    ::std::vector< OUString > maTableColumnNames;   ///< names of table columns
182
    ::std::vector< TableColumnModel > maTableColumnModel;
183
    bool            mbTableColumnNamesDirty;
184
    SCSIZE          nFilteredRowCount;
185
186
    using ScRefreshTimer::operator==;
187
188
public:
189
    struct less
190
    {
191
        bool operator() (const std::unique_ptr<ScDBData>& left, const std::unique_ptr<ScDBData>& right) const;
192
    };
193
194
    SC_DLLPUBLIC ScDBData(const OUString& rName,
195
             SCTAB nTab,
196
             SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bByR = true, bool bHasH = true, bool bTotals = false,
197
                          const OUString& rTableType = u""_ustr,
198
                          const OUString& rTableStyleID = u""_ustr);
199
    ScDBData(const ScDBData& rData);
200
    ScDBData(const OUString& rName, const ScDBData& rData);
201
    SC_DLLPUBLIC virtual ~ScDBData() override;
202
203
    virtual void Notify( const SfxHint& rHint ) override;
204
205
    ScDBData&   operator= (const ScDBData& rData) ;
206
207
    bool        operator== (const ScDBData& rData) const;
208
209
2.92k
    const OUString& GetName() const { return aName; }
210
37.0k
    const OUString& GetUpperName() const { return aUpper; }
211
283
    SCTAB       GetTab() const                  { return nTable; }
212
    void        GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const;
213
    SC_DLLPUBLIC void GetArea(ScRange& rRange) const;
214
    void        SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
215
    void        MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
216
                       SCCOL nUpdateCol = -1);
217
0
    void        SetByRow(bool bByR)             { bByRow = bByR; }
218
1.02k
    bool        HasHeader() const               { return bHasHeader; }
219
958
    void        SetHeader(bool bHasH)           { bHasHeader = bHasH; }
220
222
    bool        HasTotals() const               { return bHasTotals; }
221
1.07k
    void        SetTotals(bool bTotals)         { bHasTotals = bTotals; }
222
230
    void        SetIndex(sal_uInt16 nInd)           { nIndex = nInd; }
223
3.52k
    sal_uInt16  GetIndex() const                { return nIndex; }
224
0
    bool        IsDoSize() const                { return bDoSize; }
225
0
    void        SetDoSize(bool bSet)            { bDoSize = bSet; }
226
0
    bool        IsKeepFmt() const               { return bKeepFmt; }
227
0
    void        SetKeepFmt(bool bSet)           { bKeepFmt = bSet; }
228
0
    bool        IsStripData() const             { return bStripData; }
229
0
    void        SetStripData(bool bSet)         { bStripData = bSet; }
230
222
    void        SetTableType(const OUString& sTableType) { aTableType = sTableType; }
231
0
    const OUString& GetTableType() const           { return aTableType; }
232
233
226
    void        SetContainer( ScDBDataContainerBase* pContainer ) { mpContainer = pContainer; }
234
    /** Returns header row range if has headers, else invalid range. */
235
    ScRange     GetHeaderArea() const;
236
    void        StartTableColumnNamesListener();
237
    void        EndTableColumnNamesListener();
238
    SC_DLLPUBLIC void SetTableColumnNames( ::std::vector< OUString >&& rNames );
239
0
    SC_DLLPUBLIC const ::std::vector< OUString >& GetTableColumnNames() const { return maTableColumnNames; }
240
    SC_DLLPUBLIC void SetTableColumnModel( TableColumnModel& rModel )
241
965
    {
242
965
        maTableColumnModel.push_back(std::move(rModel));
243
965
    }
244
0
    SC_DLLPUBLIC const ::std::vector< TableColumnModel >& GetTableColumnModel() const { return maTableColumnModel; }
245
1.64k
    bool        AreTableColumnNamesDirty() const { return mbTableColumnNamesDirty; }
246
247
    /** Refresh/update the column names with the header row's cell contents. */
248
    SC_DLLPUBLIC void RefreshTableColumnNames( ScDocument* pDoc );
249
250
    /** Refresh/update the column names with the header row's cell contents
251
        within the given range. */
252
    void RefreshTableColumnNames( ScDocument& rDoc, const ScRange& rRange );
253
254
    /** Finds the column named rName and returns the corresponding offset
255
        within the table.
256
        @returns -1 if not found.
257
258
        XXX NOTE: there is no refresh of names or anything implemented yet, use
259
        this only during document load time.
260
     */
261
    sal_Int32   GetColumnNameOffset( const OUString& rName ) const;
262
263
    /** Returns table column name if nCol is within column range and name
264
        is stored, else empty string. */
265
    const OUString & GetTableColumnName( SCCOL nCol ) const;
266
267
    OUString GetSourceString() const;
268
    OUString GetOperations() const;
269
270
    SC_DLLPUBLIC void GetSortParam(ScSortParam& rSortParam) const;
271
    SC_DLLPUBLIC void SetSortParam(const ScSortParam& rSortParam);
272
273
    /** Remember some more settings of ScSortParam, only to be called at
274
        anonymous DB ranges as it at least overwrites bHasHeader. */
275
    void        UpdateFromSortParam( const ScSortParam& rSortParam );
276
277
    SC_DLLPUBLIC void       GetQueryParam(ScQueryParam& rQueryParam) const;
278
    SC_DLLPUBLIC void       SetQueryParam(const ScQueryParam& rQueryParam);
279
    SC_DLLPUBLIC bool       GetAdvancedQuerySource(ScRange& rSource) const;
280
    SC_DLLPUBLIC void       SetAdvancedQuerySource(const ScRange* pSource);
281
282
    SC_DLLPUBLIC void       GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const;
283
    SC_DLLPUBLIC void       SetSubTotalParam(const ScSubTotalParam& rSubTotalParam);
284
285
    // Total row param handling for Table Styles
286
    SC_DLLPUBLIC void       ImportTotalRowParam(ScSubTotalParam& rSubTotalParam,
287
                                                const std::vector<TableColumnAttributes>& rAttributesVector,
288
                                                formula::FormulaGrammar::Grammar eGrammar) const;
289
    SC_DLLPUBLIC void       CreateTotalRowParam(ScSubTotalParam& rSubTotalParam) const;
290
291
    SC_DLLPUBLIC std::vector<TableColumnAttributes>
292
                            GetTotalRowAttributes(formula::FormulaGrammar::Grammar eGrammar) const;
293
294
    OUString    GetSimpleSubTotalFunction(const ScTokenArray* pTokens, SCCOL nCol, SCROW nHeaderRow) const;
295
296
    void        GetImportParam(ScImportParam& rImportParam) const;
297
    void        SetImportParam(const ScImportParam& rImportParam);
298
299
    bool        IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
300
    bool        IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
301
302
    bool        HasImportParam() const;
303
    SC_DLLPUBLIC bool HasQueryParam() const;
304
    bool        HasSortParam() const;
305
    bool        HasSubTotalParam() const;
306
307
0
    bool        HasImportSelection() const      { return bDBSelection; }
308
0
    void        SetImportSelection(bool bSet)   { bDBSelection = bSet; }
309
310
6.01k
    bool        HasAutoFilter() const       { return bAutoFilter; }
311
458
    void        SetAutoFilter(bool bSet)    { bAutoFilter = bSet; }
312
313
0
    bool        IsModified() const          { return bModified; }
314
4
    void        SetModified(bool bMod)      { bModified = bMod; }
315
316
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
317
    bool    UpdateReference(const ScDocument& rDoc, UpdateRefMode eUpdateRefMode, SCCOL nCol1,
318
                            SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
319
                            SCCOL nDx, SCROW nDy, SCTAB nDz);
320
321
    void ExtendDataArea(const ScDocument& rDoc);
322
    void ExtendBackColorArea(const ScDocument& rDoc);
323
    void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount);
324
    void GetFilterSelCount(SCSIZE& nSelected, SCSIZE& nTotal);
325
326
    SC_DLLPUBLIC void SetTableStyleInfo(const ScTableStyleParam& rParams);
327
    SC_DLLPUBLIC const ScTableStyleParam* GetTableStyleInfo() const;
328
    void RemoveTableStyleInfo();
329
330
    static ScSubTotalFunc GetSubTotalFuncFromString(std::u16string_view sFunction);
331
    static OUString GetStringFromSubTotalFunc(ScSubTotalFunc eFunc);
332
333
private:
334
335
    void AdjustTableColumnNames( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1,
336
            SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 );
337
    void InvalidateTableColumnNames( bool bSwapToEmptyNames );
338
};
339
340
class ScDBCollection
341
{
342
public:
343
    enum RangeType { GlobalNamed, GlobalAnonymous, SheetAnonymous };
344
345
    /**
346
     * Stores global named database ranges.
347
     */
348
    class SC_DLLPUBLIC NamedDBs final : public ScDBDataContainerBase
349
    {
350
        friend class ScDBCollection;
351
352
        typedef ::std::set<std::unique_ptr<ScDBData>, ScDBData::less> DBsType;
353
        DBsType m_DBs;
354
        ScDBCollection& mrParent;
355
        NamedDBs(ScDBCollection& rParent, ScDocument& rDoc);
356
        NamedDBs(const NamedDBs& r, ScDBCollection& rParent);
357
        NamedDBs(const NamedDBs&) = delete;
358
        virtual ~NamedDBs() override;
359
        NamedDBs & operator=(NamedDBs const&) = delete;
360
        void initInserted( ScDBData* p );
361
362
    public:
363
        typedef DBsType::iterator iterator;
364
        typedef DBsType::const_iterator const_iterator;
365
366
        iterator begin();
367
        iterator end();
368
        const_iterator begin() const;
369
        const_iterator end() const;
370
        ScDBData* findByIndex(sal_uInt16 nIndex);
371
        ScDBData* findByUpperName(const OUString& rName);
372
        iterator findByUpperName2(const OUString& rName);
373
        iterator findByPointer(const ScDBData* p);
374
        ScDBData* findByName(const OUString& rName);
375
376
        /** Takes ownership of p and attempts to insert it into the collection.
377
            Deletes p if it could not be inserted, i.e. duplicate name.
378
            @return <TRUE/> if inserted, else <FALSE/>.
379
         */
380
        bool insert(std::unique_ptr<ScDBData> p);
381
382
        iterator erase(const iterator& itr);
383
        bool empty() const;
384
        size_t size() const;
385
        bool operator== (const NamedDBs& r) const;
386
    };
387
388
    /**
389
     * Stores global anonymous database ranges.
390
     */
391
    class AnonDBs
392
    {
393
        typedef ::std::vector<std::unique_ptr<ScDBData>> DBsType;
394
        DBsType m_DBs;
395
396
        AnonDBs& operator=(AnonDBs const&) = delete;
397
398
    public:
399
        AnonDBs();
400
        AnonDBs(AnonDBs const&);
401
402
        typedef DBsType::iterator iterator;
403
        typedef DBsType::const_iterator const_iterator;
404
405
        iterator begin();
406
        iterator end();
407
        const_iterator begin() const;
408
        const_iterator end() const;
409
        const ScDBData* findAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
410
        const ScDBData* findByRange(const ScRange& rRange) const;
411
        void deleteOnTab(SCTAB nTab);
412
        ScDBData* getByRange(const ScRange& rRange);
413
        void insert(ScDBData* p);
414
        iterator erase(const iterator& itr);
415
        bool empty() const;
416
        bool has( const ScDBData* p ) const;
417
        bool operator== (const AnonDBs& r) const;
418
    };
419
420
private:
421
    Link<Timer *, void> aRefreshHandler;
422
    ScDocument& rDoc;
423
    sal_uInt16 nEntryIndex;         ///< counter for unique indices
424
    NamedDBs maNamedDBs;
425
    AnonDBs maAnonDBs;
426
427
public:
428
    ScDBCollection(ScDocument& rDocument);
429
    ScDBCollection(const ScDBCollection& r);
430
431
2.76M
    NamedDBs& getNamedDBs() { return maNamedDBs;}
432
1.96k
    const NamedDBs& getNamedDBs() const { return maNamedDBs;}
433
434
0
    AnonDBs& getAnonDBs() { return maAnonDBs;}
435
0
    const AnonDBs& getAnonDBs() const { return maAnonDBs;}
436
437
    const ScDBData* GetTableDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
438
    ScDBData* GetTableDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion);
439
    const ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
440
    ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion);
441
    const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
442
    SC_DLLPUBLIC ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
443
    SC_DLLPUBLIC ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab );
444
    SC_DLLPUBLIC std::vector<ScDBData*> GetAllDBsFromTab(SCTAB nTab);
445
    std::vector<const ScDBData*> GetAllNamedDBsInArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
446
                                                      SCROW nRow2, SCTAB nTab) const;
447
448
    void RefreshDirtyTableColumnNames();
449
450
    void    DeleteOnTab( SCTAB nTab );
451
    void    UpdateReference(UpdateRefMode eUpdateRefMode,
452
                                SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
453
                                SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
454
                                SCCOL nDx, SCROW nDy, SCTAB nDz);
455
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
456
    void    CopyToTable(SCTAB nOldPos, SCTAB nNewPos);
457
458
    void            SetRefreshHandler( const Link<Timer *, void>& rLink )
459
69.1k
                        { aRefreshHandler = rLink; }
460
0
    const Link<Timer *, void>& GetRefreshHandler() const { return aRefreshHandler; }
461
462
    SC_DLLPUBLIC bool empty() const;
463
    bool operator== (const ScDBCollection& r) const;
464
};
465
466
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */