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