Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/inc/dpsave.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 <memory>
23
#include <ostream>
24
#include <vector>
25
26
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
27
#include <rtl/ustring.hxx>
28
#include <sal/types.h>
29
#include <tools/long.hxx>
30
31
#include "scdllapi.h"
32
#include "calcmacros.hxx"
33
34
#include <unordered_map>
35
#include <unordered_set>
36
#include <optional>
37
38
namespace com::sun::star::sheet {
39
    class XDimensionsSupplier;
40
    struct DataPilotFieldReference;
41
    struct DataPilotFieldSortInfo;
42
    struct DataPilotFieldAutoShowInfo;
43
    struct DataPilotFieldLayoutInfo;
44
}
45
46
class ScDPDimCalcSaveData;
47
class ScDPDimensionSaveData;
48
class ScDPTableData;
49
enum class ScGeneralFunction;
50
namespace sc { class PivotTableFormats; }
51
namespace tools { class XmlWriter; }
52
53
// classes to save Data Pilot settings
54
55
class ScDPSaveMember
56
{
57
private:
58
    OUString aName;
59
    std::optional<OUString> mpLayoutName; // custom name to be displayed in the table.
60
    sal_uInt16 nVisibleMode;
61
    sal_uInt16 nShowDetailsMode;
62
63
public:
64
    ScDPSaveMember(OUString aName);
65
    ScDPSaveMember(const ScDPSaveMember& r);
66
    ~ScDPSaveMember();
67
68
    bool operator== ( const ScDPSaveMember& r ) const;
69
70
    const OUString& GetName() const
71
6.88k
        { return aName; }
72
73
    SC_DLLPUBLIC bool HasIsVisible() const;
74
    SC_DLLPUBLIC void SetIsVisible(bool bSet);
75
    bool GetIsVisible() const
76
1.82k
        { return bool(nVisibleMode); }
77
78
    SC_DLLPUBLIC bool HasShowDetails() const;
79
    SC_DLLPUBLIC void SetShowDetails(bool bSet);
80
    bool GetShowDetails() const
81
0
        { return bool(nShowDetailsMode); }
82
83
    void SetName( const OUString& rNew ); // used if the source member was renamed (groups)
84
85
    SC_DLLPUBLIC void SetLayoutName( const OUString& rName );
86
    SC_DLLPUBLIC const std::optional<OUString> & GetLayoutName() const;
87
    void RemoveLayoutName();
88
89
    void WriteToSource( const css::uno::Reference<css::uno::XInterface>& xMember,
90
                            sal_Int32 nPosition );
91
92
    void dumpAsXml(tools::XmlWriter& rWriter) const;
93
94
#if DUMP_PIVOT_TABLE
95
    void Dump(int nIndent = 0) const;
96
#endif
97
};
98
99
class ScDPSaveDimension
100
{
101
private:
102
    OUString aName;
103
    std::optional<OUString> mpLayoutName;
104
    std::optional<OUString> mpSubtotalName;
105
    bool bIsDataLayout;
106
    bool bDupFlag;
107
    css::sheet::DataPilotFieldOrientation nOrientation;
108
    ScGeneralFunction nFunction; // for data dimensions
109
    tools::Long nUsedHierarchy;
110
    sal_uInt16 nShowEmptyMode; //! at level
111
    bool bRepeatItemLabels; //! at level
112
    bool bSubTotalDefault; //! at level
113
    std::vector<ScGeneralFunction> maSubTotalFuncs;
114
    std::unique_ptr<css::sheet::DataPilotFieldReference> pReferenceValue;
115
    std::unique_ptr<css::sheet::DataPilotFieldSortInfo> pSortInfo; // (level)
116
    std::unique_ptr<css::sheet::DataPilotFieldAutoShowInfo> pAutoShowInfo; // (level)
117
    std::unique_ptr<css::sheet::DataPilotFieldLayoutInfo> pLayoutInfo; // (level)
118
119
public:
120
    typedef std::unordered_set<OUString> MemberSetType;
121
    typedef std::vector<ScDPSaveMember*> MemberList;
122
123
private:
124
    std::unordered_map<OUString, std::unique_ptr<ScDPSaveMember>> maMemberHash;
125
    MemberList maMemberList;
126
127
public:
128
    ScDPSaveDimension(OUString aName, bool bDataLayout);
129
    ScDPSaveDimension(const ScDPSaveDimension& r);
130
    ~ScDPSaveDimension();
131
132
    bool operator== ( const ScDPSaveDimension& r ) const;
133
134
    const MemberList& GetMembers() const
135
0
        { return maMemberList; }
136
137
    void AddMember(std::unique_ptr<ScDPSaveMember> pMember);
138
139
    void SetDupFlag(bool bSet)
140
18
        { bDupFlag = bSet; }
141
142
    bool GetDupFlag() const
143
991
        { return bDupFlag; }
144
145
    const OUString& GetName() const
146
20.7k
        { return aName; }
147
148
    bool IsDataLayout() const
149
6.21k
        { return bIsDataLayout; }
150
151
    void SetName( const OUString& rNew ); // used if the source dim was renamed (groups)
152
153
    SC_DLLPUBLIC void SetOrientation(css::sheet::DataPilotFieldOrientation nNew);
154
    SC_DLLPUBLIC void SetSubTotals(std::vector<ScGeneralFunction> && rFuncs);
155
    tools::Long GetSubTotalsCount() const
156
0
        { return maSubTotalFuncs.size(); }
157
158
    ScGeneralFunction GetSubTotalFunc(tools::Long nIndex) const
159
0
        { return maSubTotalFuncs[nIndex]; }
160
161
    SC_DLLPUBLIC bool HasShowEmpty() const;
162
    SC_DLLPUBLIC void SetShowEmpty(bool bSet);
163
    bool GetShowEmpty() const
164
0
        { return bool(nShowEmptyMode); }
165
166
    void SetRepeatItemLabels(bool bSet);
167
    bool GetRepeatItemLabels() const
168
0
        { return bRepeatItemLabels; }
169
170
    SC_DLLPUBLIC void SetFunction(ScGeneralFunction nNew);
171
    ScGeneralFunction GetFunction() const
172
0
        { return nFunction; }
173
174
    void SetUsedHierarchy(tools::Long nNew);
175
    tools::Long GetUsedHierarchy() const
176
0
        { return nUsedHierarchy; }
177
178
    SC_DLLPUBLIC void SetLayoutName(const OUString& rName);
179
    SC_DLLPUBLIC const std::optional<OUString> & GetLayoutName() const;
180
    void RemoveLayoutName();
181
    SC_DLLPUBLIC void SetSubtotalName(const OUString& rName);
182
    SC_DLLPUBLIC const std::optional<OUString> & GetSubtotalName() const;
183
    void RemoveSubtotalName();
184
185
    bool IsMemberNameInUse(const OUString& rName) const;
186
187
    const css::sheet::DataPilotFieldReference* GetReferenceValue() const
188
0
        { return pReferenceValue.get(); }
189
190
    SC_DLLPUBLIC void SetReferenceValue(const css::sheet::DataPilotFieldReference* pNew);
191
192
    const css::sheet::DataPilotFieldSortInfo* GetSortInfo() const
193
0
        { return pSortInfo.get(); }
194
195
    SC_DLLPUBLIC void SetSortInfo(const css::sheet::DataPilotFieldSortInfo* pNew);
196
    const css::sheet::DataPilotFieldAutoShowInfo* GetAutoShowInfo() const
197
0
        { return pAutoShowInfo.get(); }
198
199
    SC_DLLPUBLIC void SetAutoShowInfo(const css::sheet::DataPilotFieldAutoShowInfo* pNew);
200
    const css::sheet::DataPilotFieldLayoutInfo* GetLayoutInfo() const
201
0
        { return pLayoutInfo.get(); }
202
203
    SC_DLLPUBLIC void SetLayoutInfo(const css::sheet::DataPilotFieldLayoutInfo* pNew);
204
205
    SC_DLLPUBLIC void SetCurrentPage( const OUString* pPage ); // NULL = no selection (all)
206
    OUString GetCurrentPage() const; // only for ODF compatibility
207
208
    css::sheet::DataPilotFieldOrientation GetOrientation() const
209
3.63k
        { return nOrientation; }
210
211
    SC_DLLPUBLIC ScDPSaveMember* GetExistingMemberByName(const OUString& rName);
212
213
    /**
214
     * Get a member object by its name.  If one doesn't exist, create a new
215
     * object and return it.  This class manages the life cycle of all member
216
     * objects belonging to it, so <i>don't delete the returned instance.</i>
217
     *
218
     * @param rName member name
219
     *
220
     * @return pointer to the member object.
221
     */
222
    SC_DLLPUBLIC ScDPSaveMember* GetMemberByName(const OUString& rName);
223
224
    void SetMemberPosition( const OUString& rName, sal_Int32 nNewPos );
225
226
    void WriteToSource( const css::uno::Reference<css::uno::XInterface>& xDim );
227
228
    void UpdateMemberVisibility(const std::unordered_map< OUString, bool>& rData);
229
230
    SC_DLLPUBLIC bool HasInvisibleMember() const;
231
232
    void RemoveObsoleteMembers(const MemberSetType& rMembers);
233
234
    void dumpAsXml(tools::XmlWriter& rWriter) const;
235
236
#if DUMP_PIVOT_TABLE
237
    void Dump(int nIndent = 0) const;
238
#endif
239
};
240
241
class ScDPSaveData
242
{
243
    typedef std::unordered_map<OUString, size_t> DupNameCountType;
244
public:
245
    typedef std::unordered_map<OUString, size_t> DimOrderType;
246
    typedef std::vector<std::unique_ptr<ScDPSaveDimension>> DimsType;
247
248
private:
249
    DimsType m_DimList;
250
    DupNameCountType maDupNameCounts; /// keep track of number of duplicates in each name.
251
    std::unique_ptr<ScDPDimensionSaveData> mpDimensionData; // settings that create new dimensions
252
    std::unique_ptr<ScDPDimCalcSaveData> mpDimCalcData; // settings that create new dimensions
253
    sal_uInt16 mnColumnGrandMode;
254
    sal_uInt16 mnRowGrandMode;
255
    sal_uInt16 mnIgnoreEmptyMode;
256
    sal_uInt16 mnRepeatEmptyMode;
257
    bool mbFilterButton; // not passed to DataPilotSource
258
    bool mbDrillDown; // not passed to DataPilotSource
259
    bool mbExpandCollapse; // not passed to DataPilotSource
260
261
    /** if true, all dimensions already have all of their member instances
262
     *  created. */
263
    bool mbDimensionMembersBuilt;
264
265
    std::unique_ptr<sc::PivotTableFormats> mpFormats;
266
    std::optional<OUString> mpGrandTotalName;
267
    mutable std::unique_ptr<DimOrderType> mpDimOrder; // dimension order for row and column dimensions, to traverse result tree.
268
269
public:
270
    SC_DLLPUBLIC ScDPSaveData();
271
    ScDPSaveData(const ScDPSaveData& r);
272
    SC_DLLPUBLIC ~ScDPSaveData();
273
274
    ScDPSaveData& operator= ( const ScDPSaveData& r );
275
276
    SC_DLLPUBLIC bool operator==(const ScDPSaveData& r) const;
277
278
    SC_DLLPUBLIC bool hasFormats();
279
    SC_DLLPUBLIC sc::PivotTableFormats const& getFormats();
280
    SC_DLLPUBLIC void setFormats(sc::PivotTableFormats const& rPivotTableFormats);
281
282
    SC_DLLPUBLIC void SetGrandTotalName(const OUString& rName);
283
    SC_DLLPUBLIC const std::optional<OUString> & GetGrandTotalName() const;
284
285
699
    const DimsType& GetDimensions() const { return m_DimList; }
286
287
    /**
288
     * Get sort order map to sort row and column dimensions in order of
289
     * appearance. Row dimensions get sorted before column dimensions.  This
290
     * is used to traverse result tree, which is structured following this
291
     * order.
292
     */
293
    const DimOrderType& GetDimensionSortOrder() const;
294
295
    /**
296
     * Get all dimensions in a given orientation.  The order represents the
297
     * actual order of occurrence.  The returned list also includes data
298
     * layout dimension.
299
     *
300
     * @param eOrientation orientation
301
     * @param rDims (out) list of dimensions for specified orientation
302
     */
303
    SC_DLLPUBLIC void GetAllDimensionsByOrientation(
304
        css::sheet::DataPilotFieldOrientation eOrientation,
305
        std::vector<const ScDPSaveDimension*>& rDims) const;
306
307
    void AddDimension(ScDPSaveDimension* pDim);
308
309
    /**
310
     * Get a dimension object by its name.  <i>If one doesn't exist for the
311
     * given name, it creates a new one.</i>
312
     *
313
     * @param rName dimension name
314
     *
315
     * @return pointer to the dimension object.  The ScDPSaveData instance
316
     *         manages its life cycle; hence the caller must
317
     *         <i>not</i> delete this object.
318
     */
319
    SC_DLLPUBLIC ScDPSaveDimension* GetDimensionByName(const OUString& rName);
320
    SC_DLLPUBLIC ScDPSaveDimension* GetDataLayoutDimension();
321
    SC_DLLPUBLIC ScDPSaveDimension* GetExistingDataLayoutDimension() const;
322
323
    ScDPSaveDimension* DuplicateDimension(std::u16string_view rName);
324
    SC_DLLPUBLIC ScDPSaveDimension& DuplicateDimension(const ScDPSaveDimension& rDim);
325
326
    SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(std::u16string_view rName) const;
327
    SC_DLLPUBLIC ScDPSaveDimension* GetNewDimensionByName(const OUString& rName);
328
329
    void RemoveDimensionByName(const OUString& rName);
330
331
    ScDPSaveDimension* GetInnermostDimension(css::sheet::DataPilotFieldOrientation nOrientation);
332
    ScDPSaveDimension* GetFirstDimension(css::sheet::DataPilotFieldOrientation eOrientation);
333
    SC_DLLPUBLIC tools::Long GetDataDimensionCount() const;
334
335
    void SetPosition( ScDPSaveDimension* pDim, tools::Long nNew );
336
    SC_DLLPUBLIC void SetColumnGrand( bool bSet );
337
0
    bool GetColumnGrand() const { return bool(mnColumnGrandMode); }
338
339
    SC_DLLPUBLIC void SetRowGrand( bool bSet );
340
0
    bool GetRowGrand() const { return bool(mnRowGrandMode); }
341
342
    SC_DLLPUBLIC void SetIgnoreEmptyRows( bool bSet );
343
943
    bool GetIgnoreEmptyRows() const { return bool(mnIgnoreEmptyMode); }
344
345
    SC_DLLPUBLIC void SetRepeatIfEmpty( bool bSet );
346
943
    bool GetRepeatIfEmpty() const { return bool(mnRepeatEmptyMode); }
347
348
    SC_DLLPUBLIC void SetFilterButton( bool bSet );
349
309
    bool GetFilterButton() const { return mbFilterButton; }
350
351
    SC_DLLPUBLIC void SetDrillDown( bool bSet );
352
0
    bool GetDrillDown() const { return mbDrillDown; }
353
354
    SC_DLLPUBLIC void SetExpandCollapse( bool bSet );
355
309
    bool GetExpandCollapse() const { return mbExpandCollapse; }
356
357
    void WriteToSource( const css::uno::Reference<css::sheet::XDimensionsSupplier>& xSource );
358
    bool IsEmpty() const;
359
360
796
    const ScDPDimensionSaveData* GetExistingDimensionData() const { return mpDimensionData.get(); }
361
618
    const ScDPDimCalcSaveData* GetExistingDimCalcData() const { return mpDimCalcData.get(); }
362
363
    void RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames = nullptr );
364
365
    SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there
366
    SC_DLLPUBLIC void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied
367
    SC_DLLPUBLIC ScDPDimCalcSaveData* GetDimCalcData(); // create if not there
368
    SC_DLLPUBLIC void SetDimCalcData( const ScDPDimCalcSaveData* pNew ); // copied
369
    void BuildAllDimensionMembers(ScDPTableData* pData);
370
    void SyncAllDimensionMembers(ScDPTableData* pData);
371
372
    /**
373
     * Check whether a dimension has one or more invisible members.
374
     *
375
     * @param rDimName dimension name
376
     */
377
    SC_DLLPUBLIC bool HasInvisibleMember(std::u16string_view rDimName) const;
378
379
    void dumpAsXml(tools::XmlWriter& rWriter) const;
380
381
#if DUMP_PIVOT_TABLE
382
    void Dump() const;
383
#endif
384
385
private:
386
    void CheckDuplicateName(ScDPSaveDimension& rDim);
387
    void RemoveDuplicateNameCount(const OUString& rName);
388
389
    /**
390
     * Append a new original dimension. Not to be called to insert a duplicate
391
     * dimension.
392
     *
393
     * @param rName Dimension name. The name must be the original dimension
394
     *              name; not a duplicate dimension name.
395
     * @param bDataLayout true if this is a data layout dimension, false
396
     *                    otherwise.
397
     *
398
     * @return pointer to the new dimension just inserted.
399
     */
400
    ScDPSaveDimension* AppendNewDimension(const OUString& rName, bool bDataLayout);
401
402
    void DimensionsChanged();
403
};
404
405
inline std::ostream& operator<<(std::ostream& rStrm, const ScDPSaveData& rData)
406
0
{
407
0
    rStrm << "SaveData[dimensions = " << rData.GetDimensions().size() << "]";
408
0
    return rStrm;
409
0
}
410
411
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */