Coverage Report

Created: 2025-11-16 09:57

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