Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/inc/dpobject.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 "global.hxx"
24
#include "address.hxx"
25
#include "dpcache.hxx"
26
#include "dptypes.hxx"
27
#include "pivot.hxx"
28
#include "calcmacros.hxx"
29
30
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
31
#include <o3tl/sorted_vector.hxx>
32
#include <unotools/resmgr.hxx>
33
34
#include <memory>
35
#include <vector>
36
#include <map>
37
38
namespace com::sun::star {
39
40
    namespace container {
41
        class XIndexAccess;
42
        class XNameAccess;
43
    }
44
45
    namespace sdbc {
46
        class XRowSet;
47
    }
48
49
    namespace sheet {
50
        class XMembersAccess;
51
        class XDimensionsSupplier;
52
        struct DataPilotTablePositionData;
53
        struct DataPilotTableHeaderData;
54
        struct DataPilotFieldFilter;
55
    }
56
}
57
58
namespace tools
59
{
60
    class Rectangle;
61
    class XmlWriter;
62
}
63
class ScTokenArray;
64
class ScDPSaveData;
65
class ScDPOutput;
66
struct ScImportSourceDesc;
67
class ScSheetSourceDesc;
68
class ScDPTableData;
69
class ScDPDimCalcSaveData;
70
class ScDPDimensionSaveData;
71
class ScRangeList;
72
class ScDocument;
73
74
struct ScDPServiceDesc
75
{
76
    OUString aServiceName;
77
    OUString aParSource;
78
    OUString aParName;
79
    OUString aParUser;
80
    OUString aParPass;
81
82
    ScDPServiceDesc( OUString aServ, OUString aSrc, OUString aNam,
83
                     OUString aUser, OUString aPass );
84
85
    bool operator== ( const ScDPServiceDesc& rOther ) const;
86
};
87
88
namespace sc
89
{
90
91
/** Stores the style information for a pivot table */
92
struct PivotTableStyleInfo
93
{
94
    // Style name, which is used to determine how the pivot table is styles
95
    OUString maName;
96
97
    // Should headers be styled
98
    bool mbShowRowHeaders = false;
99
    bool mbShowColHeaders = false;
100
101
    // Should use stripes / bands
102
    bool mbShowRowStripes = false;
103
    bool mbShowColStripes = false;
104
105
    bool mbShowLastColumn = false;
106
107
    // If no name is set, the style is not used
108
    bool isSet() const
109
0
    {
110
0
        return !maName.isEmpty();
111
0
    }
112
};
113
114
}
115
116
class ScDPObject
117
{
118
private:
119
    ScDocument* mpDocument;
120
121
    // Settings
122
    std::unique_ptr<ScDPSaveData> mpSaveData;
123
    OUString maTableName;
124
    OUString maTableTag;
125
    ScRange maOutputRange;
126
    std::unique_ptr<ScSheetSourceDesc> mpSheetDescription; //  for sheet data
127
    std::unique_ptr<ScImportSourceDesc> mpImportDescription; //  for database data
128
    std::unique_ptr<ScDPServiceDesc> mpServiceDescription; //  for external service
129
    std::shared_ptr<ScDPTableData> mpTableData; // cached data
130
131
    css::uno::Reference<css::sheet::XDimensionsSupplier> mxSource;
132
    std::unique_ptr<ScDPOutput> mpOutput;
133
134
    sal_Int32 mnHeaderRows;    // page fields plus filter button
135
    bool mbHeaderLayout : 1;  // true : grid, false : standard
136
    bool mbAllowMove : 1;
137
    bool mbSettingsChanged : 1;
138
    bool mbEnableGetPivotData : 1;
139
    bool mbHideHeader : 1 = false;
140
    bool mbSpillError : 1 = false;
141
142
    sc::PivotTableStyleInfo maStyleInfo;
143
144
    void              CreateObjects();
145
    void              CreateOutput();
146
    void ClearSource();
147
    void FillLabelDataForDimension(
148
        const css::uno::Reference< css::container::XIndexAccess>& xDims,
149
        sal_Int32 nDim, ScDPLabelData& rLabelData);
150
151
public:
152
    SC_DLLPUBLIC ScDPObject(ScDocument* pD);
153
    ScDPObject(const ScDPObject& r);
154
    SC_DLLPUBLIC ~ScDPObject();
155
156
    ScDPObject& operator= (const ScDPObject& r);
157
158
    void EnableGetPivotData(bool b);
159
160
    void                SetAllowMove(bool bSet);
161
162
    void                InvalidateData();
163
    void Clear();
164
    void ClearTableData();
165
    ScDPTableData* GetTableData();
166
167
    SC_DLLPUBLIC void ReloadGroupTableData();
168
169
    /** Render the pivot table at input position. When bCheckForSpill is true,
170
        first verify the output range is unblocked. If blocked, write #SPILL!
171
        into input position, mark the object's spill state, and return false.
172
        Otherwise write the table and return true. */
173
    SC_DLLPUBLIC bool Output(const ScAddress& rPos, bool bCheckForSpill = false);
174
    bool HasSpillError() const;
175
0
    void SetSpillError(bool bSpillError) { mbSpillError = bSpillError; }
176
    ScRange             GetNewOutputRange( bool& rOverflow );
177
178
    SC_DLLPUBLIC ScRange GetOutputRangeByType( sal_Int32 nType );
179
    SC_DLLPUBLIC ScRange GetOutputRangeByType( sal_Int32 nType ) const;
180
181
    SC_DLLPUBLIC void SetSaveData(const ScDPSaveData& rData);
182
6.67k
    ScDPSaveData* GetSaveData() const { return mpSaveData.get(); }
183
184
    SC_DLLPUBLIC void SetOutRange(const ScRange& rRange);
185
    SC_DLLPUBLIC const ScRange& GetOutRange() const;
186
187
    SC_DLLPUBLIC void   SetHeaderLayout(bool bUseGrid);
188
0
    bool                GetHeaderLayout() const { return mbHeaderLayout;}
189
190
    SC_DLLPUBLIC void SetHideHeader(bool bHideHeader);
191
0
    bool GetHideHeader() const { return mbHideHeader; }
192
193
    SC_DLLPUBLIC void   SetSheetDesc(const ScSheetSourceDesc& rDesc);
194
    void                SetImportDesc(const ScImportSourceDesc& rDesc);
195
    void                SetServiceData(const ScDPServiceDesc& rDesc);
196
197
    void                WriteSourceDataTo( ScDPObject& rDest ) const;
198
199
    SC_DLLPUBLIC void   InsertCalculatedFieldToCache(sal_Int32 nIndex, const OUString& rFieldName,
200
                                                     const std::shared_ptr<ScTokenArray>& pArray);
201
    void                RemoveCalculatedFieldFromCache(const OUString& rFieldName);
202
203
910
    const ScSheetSourceDesc* GetSheetDesc() const { return mpSheetDescription.get(); }
204
0
    const ScImportSourceDesc* GetImportSourceDesc() const { return mpImportDescription.get(); }
205
0
    const ScDPServiceDesc* GetDPServiceDesc() const { return mpServiceDescription.get(); }
206
207
    SC_DLLPUBLIC css::uno::Reference<css::sheet::XDimensionsSupplier> const & GetSource();
208
209
    bool                IsSheetData() const;
210
0
    bool IsImportData() const { return mpImportDescription != nullptr; }
211
0
    bool IsServiceData() const { return mpServiceDescription != nullptr; }
212
213
214
    SC_DLLPUBLIC void SetName(const OUString& rNew);
215
1.11k
    const OUString& GetName() const { return maTableName; }
216
    void SetTag(const OUString& rNew);
217
309
    const OUString& GetTag() const { return maTableTag; }
218
219
    /**
220
     *  Data description cell displays the description of a data dimension if
221
     *  and only if there is only one data dimension.  It's usually located at
222
     *  the upper-left corner of the table output.
223
     */
224
    bool                IsDataDescriptionCell(const ScAddress& rPos);
225
226
    bool                IsDimNameInUse(std::u16string_view rName) const;
227
    SC_DLLPUBLIC OUString GetDimName( tools::Long nDim, bool& rIsDataLayout, sal_Int32* pFlags = nullptr );
228
    SC_DLLPUBLIC bool   IsDuplicated( tools::Long nDim );
229
    SC_DLLPUBLIC tools::Long GetDimCount();
230
    void                GetHeaderPositionData(const ScAddress& rPos, css::sheet::DataPilotTableHeaderData& rData);
231
    SC_DLLPUBLIC tools::Long GetHeaderDim( const ScAddress& rPos, css::sheet::DataPilotFieldOrientation& rOrient );
232
    bool                GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop,
233
                                       tools::Long nDragDim,
234
                                       tools::Rectangle& rPosRect, css::sheet::DataPilotFieldOrientation& rOrient, tools::Long& rDimPos );
235
    bool                IsFilterButton( const ScAddress& rPos );
236
237
    static OUString GetFormattedString(const ScDPTableData* pTableData, tools::Long nDimension, const double fValue);
238
    SC_DLLPUBLIC OUString GetFormattedString( std::u16string_view rDimName, const double fValue );
239
240
    double GetPivotData(
241
        const OUString& rDataFieldName,
242
        std::vector<css::sheet::DataPilotFieldFilter>& rFilters);
243
244
    bool ParseFilters(
245
        OUString& rDataFieldName,
246
        std::vector<css::sheet::DataPilotFieldFilter>& rFilters,
247
        std::vector<sal_Int16>& rFilterFuncs,
248
        std::u16string_view rFilterList );
249
250
    void GetMemberResultNames(ScDPUniqueStringSet& rNames, tools::Long nDimension);
251
252
    void                ToggleDetails(const css::sheet::DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj);
253
254
    void                FillOldParam(ScPivotParam& rParam) const;
255
    void                FillLabelData(sal_Int32 nDim, ScDPLabelData& Labels);
256
    void                FillLabelData(ScPivotParam& rParam);
257
258
    void                GetFieldIdsNames(css::sheet::DataPilotFieldOrientation nOrient, std::vector<tools::Long>& rIndices,
259
                                         std::vector<OUString>& rNames);
260
261
    bool                GetHierarchiesNA( sal_Int32 nDim, css::uno::Reference< css::container::XNameAccess >& xHiers );
262
    void                GetHierarchies( sal_Int32 nDim, css::uno::Sequence< OUString >& rHiers );
263
264
    SC_DLLPUBLIC sal_Int32 GetUsedHierarchy( sal_Int32 nDim );
265
266
    bool                GetMembersNA( sal_Int32 nDim, css::uno::Reference< css::sheet::XMembersAccess >& xMembers );
267
    bool                GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, css::uno::Reference< css::sheet::XMembersAccess >& xMembers );
268
269
    bool                GetMemberNames( sal_Int32 nDim, css::uno::Sequence< OUString >& rNames );
270
    SC_DLLPUBLIC bool   GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers );
271
272
    void                UpdateReference( UpdateRefMode eUpdateRefMode,
273
                                         const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz );
274
    bool                RefsEqual( const ScDPObject& r ) const;
275
    void                WriteRefsTo( ScDPObject& r ) const;
276
277
    void                GetPositionData(const ScAddress& rPos, css::sheet::DataPilotTablePositionData& rPosData);
278
279
    bool                GetDataFieldPositionData(const ScAddress& rPos,
280
                                                 css::uno::Sequence<
281
                                                    css::sheet::DataPilotFieldFilter >& rFilters);
282
283
    void                GetDrillDownData(const ScAddress& rPos,
284
                                         css::uno::Sequence< css::uno::Sequence< css::uno::Any > >& rTableData);
285
286
    // apply drop-down attribute, initialize mnHeaderRows, without accessing the source
287
    // (button attribute must be present)
288
    void                RefreshAfterLoad();
289
290
    sc::PivotTableStyleInfo const& getStyleInfo() const
291
0
    {
292
0
        return maStyleInfo;
293
0
    }
294
295
    void setStyleInfo(sc::PivotTableStyleInfo const& rStyleInfo)
296
309
    {
297
309
        maStyleInfo = rStyleInfo;
298
309
    }
299
300
    SC_DLLPUBLIC void BuildAllDimensionMembers();
301
302
    /**
303
     * Remove in the save data entries for members that don't exist anymore.
304
     * This is called during pivot table refresh.
305
     */
306
    SC_DLLPUBLIC bool SyncAllDimensionMembers();
307
308
    static bool         HasRegisteredSources();
309
    static std::vector<OUString> GetRegisteredSources();
310
    static css::uno::Reference<css::sheet::XDimensionsSupplier>
311
                        CreateSource( const ScDPServiceDesc& rDesc );
312
313
    static void ConvertOrientation(
314
        ScDPSaveData& rSaveData,
315
        const ScPivotFieldVector& rFields, css::sheet::DataPilotFieldOrientation nOrient,
316
        const css::uno::Reference< css::sheet::XDimensionsSupplier>& xSource,
317
        const ScDPLabelDataVector& rLabels,
318
        const ScPivotFieldVector* pRefColFields = nullptr,
319
        const ScPivotFieldVector* pRefRowFields = nullptr,
320
        const ScPivotFieldVector* pRefPageFields = nullptr );
321
322
    SC_DLLPUBLIC static bool IsOrientationAllowed( css::sheet::DataPilotFieldOrientation nOrient, sal_Int32 nDimFlags );
323
324
    void dumpAsXml(tools::XmlWriter& rWriter) const;
325
    void dumpXmlFile() const;
326
327
#if DUMP_PIVOT_TABLE
328
    void Dump() const;
329
    void DumpCache() const;
330
#endif
331
};
332
333
class ScDPCollection
334
{
335
    friend class ScDPCache;
336
public:
337
338
    /**
339
     * Stores and manages all caches from internal sheets.
340
     */
341
    class SheetCaches
342
    {
343
        friend class ScDPCollection;
344
        typedef std::map<size_t, std::unique_ptr<ScDPCache>> CachesType;
345
        typedef std::vector<ScRange> RangeIndexType;
346
        CachesType m_Caches;
347
        RangeIndexType maRanges;
348
        ScDocument& mrDoc;
349
    public:
350
        SheetCaches(ScDocument& rDoc);
351
        bool hasCache(const ScRange& rRange) const;
352
        const ScDPCache* getCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData, const ScDPDimCalcSaveData* pCalculatedDimData);
353
        SC_DLLPUBLIC size_t size() const;
354
355
        void updateReference(
356
            UpdateRefMode eMode, const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz);
357
358
        SC_DLLPUBLIC ScDPCache* getExistingCache(const ScRange& rRange);
359
        SC_DLLPUBLIC const ScDPCache* getExistingCache(const ScRange& rRange) const;
360
361
        void updateCache(const ScRange& rRange, o3tl::sorted_vector<ScDPObject*>& rRefs);
362
        bool remove(const ScDPCache* p);
363
364
        SC_DLLPUBLIC const std::vector<ScRange>& getAllRanges() const;
365
    };
366
367
    /**
368
     * Data caches for range name based source data.
369
     */
370
    class NameCaches
371
    {
372
        friend class ScDPCollection;
373
        typedef ::std::map<OUString, std::unique_ptr<ScDPCache>> CachesType;
374
        CachesType m_Caches;
375
        ScDocument& mrDoc;
376
    public:
377
        NameCaches(ScDocument& rDoc);
378
        bool hasCache(const OUString& rName) const;
379
        const ScDPCache* getCache(const OUString& rName, const ScRange& rRange,
380
                                  const ScDPDimensionSaveData* pDimData, const ScDPDimCalcSaveData* pCalculatedDimData);
381
        ScDPCache* getExistingCache(const OUString& rName);
382
        size_t size() const;
383
    private:
384
385
        void updateCache(
386
            const OUString& rName, const ScRange& rRange, o3tl::sorted_vector<ScDPObject*>& rRefs);
387
        bool remove(const ScDPCache* p);
388
    };
389
390
    /**
391
     * Defines connection type to external data source.  Used as a key to look
392
     * up database cache.
393
     */
394
    struct DBType
395
    {
396
        sal_Int32 mnSdbType;
397
        OUString maDBName;
398
        OUString maCommand;
399
        DBType(sal_Int32 nSdbType, OUString aDBName, OUString aCommand);
400
401
        struct less
402
        {
403
            bool operator() (const DBType& left, const DBType& right) const;
404
        };
405
    };
406
407
    /**
408
     * Data caches for external database sources.
409
     */
410
    class DBCaches
411
    {
412
        friend class ScDPCollection;
413
        typedef ::std::map<DBType, std::unique_ptr<ScDPCache>, DBType::less> CachesType;
414
        CachesType m_Caches;
415
        ScDocument& mrDoc;
416
    public:
417
        DBCaches(ScDocument& rDoc);
418
        bool hasCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) const;
419
        const ScDPCache* getCache(
420
            sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, const ScDPDimensionSaveData* pDimData, const ScDPDimCalcSaveData* pCalculatedDimData);
421
        ScDPCache* getExistingCache(sal_Int32 nSdbType, const OUString& rDBName,
422
                                    const OUString& rCommand);
423
424
    private:
425
426
        static css::uno::Reference<css::sdbc::XRowSet> createRowSet(
427
            sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand);
428
429
        void updateCache(
430
            sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
431
            o3tl::sorted_vector<ScDPObject*>& rRefs);
432
        bool remove(const ScDPCache* p);
433
    };
434
435
    ScDPCollection(ScDocument& rDocument);
436
    ScDPCollection(const ScDPCollection& r);
437
    ~ScDPCollection();
438
439
    TranslateId ReloadCache(const ScDPObject* pDPObj, o3tl::sorted_vector<ScDPObject*>& rRefs);
440
    bool ReloadGroupsInCache(const ScDPObject* pDPObj, o3tl::sorted_vector<ScDPObject*>& rRefs);
441
    SC_DLLPUBLIC bool GetReferenceGroups(const ScDPObject& rDPObj, const ScDPDimensionSaveData** pGroups) const;
442
443
    SC_DLLPUBLIC size_t GetCount() const;
444
    SC_DLLPUBLIC ScDPObject& operator[](size_t nIndex);
445
    SC_DLLPUBLIC const ScDPObject& operator[](size_t nIndex) const;
446
447
    SC_DLLPUBLIC ScDPObject* GetByName(std::u16string_view rName) const;
448
449
    void DeleteOnTab( SCTAB nTab );
450
    void UpdateReference( UpdateRefMode eUpdateRefMode,
451
                          const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz );
452
    void CopyToTab( SCTAB nOld, SCTAB nNew );
453
    bool RefsEqual( const ScDPCollection& r ) const;
454
    void WriteRefsTo( ScDPCollection& r ) const;
455
456
    /**
457
     * Create a new name that's not yet used by any existing data pilot
458
     * objects.  All data pilot names are 'DataPilot' + <num>
459
     *
460
     * @return new name for data pilot object.
461
     */
462
    OUString CreateNewName() const;
463
464
    void FreeTable(const ScDPObject* pDPObj);
465
466
    /** Deletes all pivot tables on the input tab. */
467
    void DeleteByTab(SCTAB nTab);
468
    SC_DLLPUBLIC ScDPObject* InsertNewTable(std::unique_ptr<ScDPObject> pDPObj);
469
    SC_DLLPUBLIC bool HasTable(const ScDPObject* pDPObj) const;
470
471
    SC_DLLPUBLIC SheetCaches& GetSheetCaches();
472
    SC_DLLPUBLIC const SheetCaches& GetSheetCaches() const;
473
    NameCaches& GetNameCaches();
474
    SC_DLLPUBLIC const NameCaches& GetNameCaches() const;
475
    DBCaches& GetDBCaches();
476
    SC_DLLPUBLIC const DBCaches& GetDBCaches() const;
477
478
    ScRangeList GetAllTableRanges( SCTAB nTab ) const;
479
    bool IntersectsTableByColumns( SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCTAB nTab ) const;
480
    bool IntersectsTableByRows( SCCOL nCol, SCROW nRow1, SCROW nRow2, SCTAB nTab ) const;
481
    bool HasTable( const ScRange& rRange ) const;
482
483
private:
484
    /** Only to be called from ScDPCache::RemoveReference(). */
485
    void RemoveCache(const ScDPCache* pCache);
486
487
    void GetAllTables(const ScRange& rSrcRange, o3tl::sorted_vector<ScDPObject*>& rRefs) const;
488
    void GetAllTables(std::u16string_view rSrcName, o3tl::sorted_vector<ScDPObject*>& rRefs) const;
489
    void GetAllTables(
490
        sal_Int32 nSdbType, std::u16string_view rDBName, std::u16string_view rCommand,
491
        o3tl::sorted_vector<ScDPObject*>& rRefs) const;
492
493
private:
494
    typedef std::vector< std::unique_ptr<ScDPObject> > TablesType;
495
496
    ScDocument& mrDoc;
497
    TablesType maTables;
498
    SheetCaches maSheetCaches;
499
    NameCaches maNameCaches;
500
    DBCaches maDBCaches;
501
};
502
503
bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right);
504
505
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */