/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: */ |