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 <com/sun/star/sheet/XDimensionsSupplier.hpp>
23 #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
24 #include <com/sun/star/sheet/XLevelsSupplier.hpp>
25 #include <com/sun/star/sheet/XMembersSupplier.hpp>
26 #include <com/sun/star/sheet/XDataPilotResults.hpp>
27 #include <com/sun/star/sheet/XDataPilotMemberResults.hpp>
28 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
29 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
30 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
31 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
32 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
33 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
34 #include <com/sun/star/util/XRefreshable.hpp>
35 #include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
36 #include <com/sun/star/util/XCloneable.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/container/XNamed.hpp>
40 #include <cppuhelper/implbase.hxx>
41 #include <rtl/ref.hxx>
42 
43 #include "dptabdat.hxx"
44 #include "dpresfilter.hxx"
45 
46 #include <memory>
47 #include <unordered_map>
48 #include <unordered_set>
49 #include <vector>
50 #include <optional>
51 
52 namespace com::sun::star {
53     namespace sheet {
54         struct DataPilotFieldFilter;
55         struct MemberResult;
56     }
57 }
58 
59 class ScDPResultMember;
60 class ScDPResultData;
61 class ScDPItemData;
62 class ScDPDimensions;
63 class ScDPDimension;
64 class ScDPHierarchies;
65 class ScDPHierarchy;
66 class ScDPLevels;
67 class ScDPLevel;
68 class ScDPMembers;
69 class ScDPMember;
70 enum class ScGeneralFunction;
71 
72 //  implementation of DataPilotSource using ScDPTableData
73 
74 class ScDPSource final : public cppu::WeakImplHelper<
75                             css::sheet::XDimensionsSupplier,
76                             css::sheet::XDataPilotResults,
77                             css::util::XRefreshable,
78                             css::sheet::XDrillDownDataSupplier,
79                             css::beans::XPropertySet,
80                             css::lang::XServiceInfo >
81 {
82 private:
83     ScDPTableData*          pData;              // data source (ScDPObject manages its life time)
84     rtl::Reference<ScDPDimensions> pDimensions; // api objects
85                                                 // settings:
86 
87     std::vector<sal_Int32> maColDims;
88     std::vector<sal_Int32> maRowDims;
89     std::vector<sal_Int32> maDataDims;
90     std::vector<sal_Int32> maPageDims;
91     ScDPResultTree maResFilterSet;
92 
93     bool                    bColumnGrand;
94     bool                    bRowGrand;
95     bool                    bIgnoreEmptyRows;
96     bool                    bRepeatIfEmpty;
97 
98     sal_Int32               nDupCount;
99 
100                                                 // results:
101     std::unique_ptr<ScDPResultData>   pResData;           // keep the rest in this!
102     std::unique_ptr<ScDPResultMember> pColResRoot;
103     std::unique_ptr<ScDPResultMember> pRowResRoot;
104     std::unique_ptr<css::uno::Sequence<css::sheet::MemberResult>[]> pColResults;
105     std::unique_ptr<css::uno::Sequence<css::sheet::MemberResult>[]> pRowResults;
106     std::vector<ScDPLevel*> aColLevelList;
107     std::vector<ScDPLevel*> aRowLevelList;
108     bool                    bResultOverflow;
109     bool                    bPageFiltered;      // set if page field filters have been applied to cache table
110 
111     std::optional<OUString> mpGrandTotalName;
112 
113     void                    CreateRes_Impl();
114     void                    FillMemberResults();
115     void                    FillLevelList( css::sheet::DataPilotFieldOrientation nOrientation, std::vector<ScDPLevel*> &rList );
116     void                    FillCalcInfo(bool bIsRow, ScDPTableData::CalcInfo& rInfo, bool &bHasAutoShow);
117 
118     /**
119      * Compile a list of dimension indices that are either, column, row or
120      * page dimensions (i.e. all but data dimensions).
121      */
122     void                    GetCategoryDimensionIndices(std::unordered_set<sal_Int32>& rCatDims);
123 
124     /**
125      * Set visibilities of individual rows in the cache table based on the
126      * page field data.
127      */
128     void FilterCacheByPageDimensions();
129 
130     void                    SetDupCount( tools::Long nNew );
131 
132     OUString getDataDescription();       //! ???
133 
134     void setIgnoreEmptyRows(bool bSet);
135     void setRepeatIfEmpty(bool bSet);
136 
137     void disposeData();
138 
139 public:
140                                 ScDPSource( ScDPTableData* pD );
141     virtual                     ~ScDPSource() override;
142 
GetData()143     ScDPTableData*          GetData()       { return pData; }
GetData() const144     const ScDPTableData*    GetData() const { return pData; }
145 
146     const std::optional<OUString> &
147                             GetGrandTotalName() const;
148 
149     css::sheet::DataPilotFieldOrientation
150                             GetOrientation(sal_Int32 nColumn);
151     void                    SetOrientation(sal_Int32 nColumn, css::sheet::DataPilotFieldOrientation nNew);
152     sal_Int32               GetPosition(sal_Int32 nColumn);
153 
154     sal_Int32               GetDataDimensionCount() const;
155     ScDPDimension*          GetDataDimension(sal_Int32 nIndex);
156     OUString                GetDataDimName(sal_Int32 nIndex);
157     const ScDPCache* GetCache();
158     const ScDPItemData*         GetItemDataById( sal_Int32 nDim, sal_Int32 nId );
159     bool                        IsDataLayoutDimension(sal_Int32 nDim);
160     css::sheet::DataPilotFieldOrientation
161                                 GetDataLayoutOrientation();
162 
163     bool                        IsDateDimension(sal_Int32 nDim);
164 
165     bool                        SubTotalAllowed(sal_Int32 nColumn);      //! move to ScDPResultData
166 
167     ScDPDimension* AddDuplicated(std::u16string_view rNewName);
GetDupCount() const168     sal_Int32                    GetDupCount() const { return nDupCount; }
169 
170     sal_Int32                    GetSourceDim(sal_Int32 nDim);
171 
172     const css::uno::Sequence<css::sheet::MemberResult>*
173                             GetMemberResults( const ScDPLevel* pLevel );
174 
175     ScDPDimensions*         GetDimensionsObject();
176 
177                             // XDimensionsSupplier
178     virtual css::uno::Reference< css::container::XNameAccess >
179                             SAL_CALL getDimensions(  ) override;
180 
181                             // XDataPilotResults
182     virtual css::uno::Sequence< css::uno::Sequence< css::sheet::DataResult > > SAL_CALL getResults(  ) override;
183 
184     virtual css::uno::Sequence<double> SAL_CALL
185         getFilteredResults(
186             const css::uno::Sequence<css::sheet::DataPilotFieldFilter>& aFilters ) override;
187 
188                             // XRefreshable
189     virtual void SAL_CALL   refresh() override;
190     virtual void SAL_CALL   addRefreshListener( const css::uno::Reference< css::util::XRefreshListener >& l ) override;
191     virtual void SAL_CALL   removeRefreshListener( const css::uno::Reference< css::util::XRefreshListener >& l ) override;
192 
193                             // XDrillDownDataSupplier
194     virtual css::uno::Sequence< css::uno::Sequence< css::uno::Any > >
195         SAL_CALL getDrillDownData(const css::uno::Sequence<
196                                       css::sheet::DataPilotFieldFilter >& aFilters ) override;
197 
198                             // XPropertySet
199     virtual css::uno::Reference< css::beans::XPropertySetInfo >
200                             SAL_CALL getPropertySetInfo(  ) override;
201     virtual void SAL_CALL   setPropertyValue( const OUString& aPropertyName,
202                                     const css::uno::Any& aValue ) override;
203     virtual css::uno::Any SAL_CALL getPropertyValue(
204                                     const OUString& PropertyName ) override;
205     virtual void SAL_CALL   addPropertyChangeListener( const OUString& aPropertyName,
206                                     const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
207     virtual void SAL_CALL   removePropertyChangeListener( const OUString& aPropertyName,
208                                     const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
209     virtual void SAL_CALL   addVetoableChangeListener( const OUString& PropertyName,
210                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
211     virtual void SAL_CALL   removeVetoableChangeListener( const OUString& PropertyName,
212                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
213 
214                             // XServiceInfo
215     virtual OUString SAL_CALL getImplementationName(  ) override;
216     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
217     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
218 
219 #if DUMP_PIVOT_TABLE
220     void DumpResults() const;
221 #endif
222 };
223 
224 class ScDPDimensions : public cppu::WeakImplHelper<
225                             css::container::XNameAccess,
226                             css::lang::XServiceInfo >
227 {
228 private:
229     ScDPSource*         pSource;
230     sal_Int32           nDimCount;
231     std::unique_ptr<rtl::Reference<ScDPDimension>[]>
232                         ppDims;
233 
234 public:
235                             ScDPDimensions( ScDPSource* pSrc );
236     virtual                 ~ScDPDimensions() override;
237 
238     void                    CountChanged();
239 
240                             // XNameAccess
241     virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) override;
242     virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override;
243     virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
244 
245                             // XElementAccess
246     virtual css::uno::Type SAL_CALL getElementType() override;
247     virtual sal_Bool SAL_CALL hasElements() override;
248 
249                             // XServiceInfo
250     virtual OUString SAL_CALL getImplementationName(  ) override;
251     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
252     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
253 
254     tools::Long            getCount() const;
255     ScDPDimension*  getByIndex(tools::Long nIndex) const;
256 };
257 
258 class ScDPDimension : public cppu::WeakImplHelper<
259                             css::sheet::XHierarchiesSupplier,
260                             css::container::XNamed,
261                             css::util::XCloneable,
262                             css::beans::XPropertySet,
263                             css::lang::XServiceInfo >
264 {
265     ScDPSource*         pSource;
266     sal_Int32           nDim;               // dimension index (== column ID)
267     rtl::Reference<ScDPHierarchies> mxHierarchies;
268     ScGeneralFunction   nFunction;
269     OUString            aName;              // if empty, take from source
270     std::optional<OUString> mpLayoutName;
271     std::optional<OUString> mpSubtotalName;
272     sal_Int32           nSourceDim;         // >=0 if dup'ed
273     css::sheet::DataPilotFieldReference
274                         aReferenceValue;    // settings for "show data as" / "displayed value"
275     bool                bHasSelectedPage;
276     OUString            aSelectedPage;
277     std::unique_ptr<ScDPItemData>
278                         pSelectedData;      // internal, temporary, created from aSelectedPage
279     bool                mbHasHiddenMember;
280 
281 public:
282                             ScDPDimension( ScDPSource* pSrc, tools::Long nD );
283     virtual                 ~ScDPDimension() override;
284                             ScDPDimension(const ScDPDimension&) = delete;
285     ScDPDimension&          operator=(const ScDPDimension&) = delete;
286 
GetDimension() const287     sal_Int32               GetDimension() const    { return nDim; }        // dimension index in source
GetSourceDim() const288     sal_Int32               GetSourceDim() const    { return nSourceDim; }  // >=0 if dup'ed
289 
290     ScDPDimension*          CreateCloneObject();
291     ScDPHierarchies*        GetHierarchiesObject();
292 
293     const std::optional<OUString> & GetLayoutName() const;
294     const std::optional<OUString> & GetSubtotalName() const;
295 
296                             // XNamed
297     virtual OUString SAL_CALL getName() override;
298     virtual void SAL_CALL   setName( const OUString& aName ) override;
299 
300                             // XHierarchiesSupplier
301     virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL
302                             getHierarchies() override;
303 
304                             // XCloneable
305     virtual css::uno::Reference< css::util::XCloneable > SAL_CALL
306                             createClone() override;
307 
308                             // XPropertySet
309     virtual css::uno::Reference< css::beans::XPropertySetInfo >
310                             SAL_CALL getPropertySetInfo(  ) override;
311     virtual void SAL_CALL   setPropertyValue( const OUString& aPropertyName,
312                                     const css::uno::Any& aValue ) override;
313     virtual css::uno::Any SAL_CALL getPropertyValue(
314                                     const OUString& PropertyName ) override;
315     virtual void SAL_CALL   addPropertyChangeListener( const OUString& aPropertyName,
316                                     const css::uno::Reference<
317                                         css::beans::XPropertyChangeListener >& xListener ) override;
318     virtual void SAL_CALL   removePropertyChangeListener( const OUString& aPropertyName,
319                                     const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
320     virtual void SAL_CALL   addVetoableChangeListener( const OUString& PropertyName,
321                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
322     virtual void SAL_CALL   removeVetoableChangeListener( const OUString& PropertyName,
323                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
324 
325                             // XServiceInfo
326     virtual OUString SAL_CALL getImplementationName(  ) override;
327     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
328     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
329 
330     css::sheet::DataPilotFieldOrientation getOrientation() const;
331     bool getIsDataLayoutDimension() const;
getFunction() const332     ScGeneralFunction getFunction() const { return nFunction;}
333     void setFunction(ScGeneralFunction nNew);       // for data dimension
getUsedHierarchy()334     static tools::Long getUsedHierarchy() { return 0;}
335 
HasSelectedPage() const336     bool                        HasSelectedPage() const     { return bHasSelectedPage; }
337     const ScDPItemData&         GetSelectedData();
338 
GetReferenceValue() const339     const css::sheet::DataPilotFieldReference& GetReferenceValue() const { return aReferenceValue;}
340 };
341 
342 class ScDPHierarchies : public cppu::WeakImplHelper<
343                             css::container::XNameAccess,
344                             css::lang::XServiceInfo >
345 {
346 private:
347     ScDPSource*         pSource;
348     sal_Int32           nDim;
349     //  date columns have 3 hierarchies (flat/quarter/week), other columns only one
350     // #i52547# don't offer the incomplete date hierarchy implementation
351     static const tools::Long   nHierCount = 1;
352     std::unique_ptr<rtl::Reference<ScDPHierarchy>[]>
353                         ppHiers;
354 
355 public:
356                             ScDPHierarchies( ScDPSource* pSrc, tools::Long nD );
357     virtual                 ~ScDPHierarchies() override;
358 
359                             // XNameAccess
360     virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) override;
361     virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override;
362     virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
363 
364                             // XElementAccess
365     virtual css::uno::Type SAL_CALL getElementType() override;
366     virtual sal_Bool SAL_CALL hasElements() override;
367 
368                             // XServiceInfo
369     virtual OUString SAL_CALL getImplementationName(  ) override;
370     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
371     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
372 
373     static sal_Int32     getCount();
374     ScDPHierarchy*  getByIndex(tools::Long nIndex) const;
375 };
376 
377 class ScDPHierarchy : public cppu::WeakImplHelper<
378                             css::sheet::XLevelsSupplier,
379                             css::container::XNamed,
380                             css::lang::XServiceInfo >
381 {
382 private:
383     ScDPSource*     pSource;
384     sal_Int32            nDim;
385     sal_Int32            nHier;
386     rtl::Reference<ScDPLevels> mxLevels;
387 
388 public:
389                             ScDPHierarchy( ScDPSource* pSrc, sal_Int32 nDim, sal_Int32 nHier );
390     virtual                 ~ScDPHierarchy() override;
391 
392     ScDPLevels*             GetLevelsObject();
393 
394                             // XNamed
395     virtual OUString SAL_CALL getName() override;
396     virtual void SAL_CALL   setName( const OUString& aName ) override;
397 
398                             // XLevelsSupplier
399     virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL
400                             getLevels() override;
401 
402                             // XServiceInfo
403     virtual OUString SAL_CALL getImplementationName(  ) override;
404     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
405     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
406 };
407 
408 class ScDPLevels : public cppu::WeakImplHelper<
409                             css::container::XNameAccess,
410                             css::lang::XServiceInfo >
411 {
412 private:
413     ScDPSource*     pSource;
414     sal_Int32            nDim;
415     sal_Int32            nHier;
416     sal_Int32            nLevCount;
417     std::unique_ptr<rtl::Reference<ScDPLevel>[]>
418                     ppLevs;
419 
420 public:
421                             ScDPLevels( ScDPSource* pSrc, sal_Int32 nDim, sal_Int32 nHier );
422     virtual                 ~ScDPLevels() override;
423 
424                             // XNameAccess
425     virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) override;
426     virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override;
427     virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
428 
429                             // XElementAccess
430     virtual css::uno::Type SAL_CALL getElementType() override;
431     virtual sal_Bool SAL_CALL hasElements() override;
432 
433                             // XServiceInfo
434     virtual OUString SAL_CALL getImplementationName(  ) override;
435     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
436     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
437 
438     sal_Int32            getCount() const;
439     ScDPLevel*      getByIndex(sal_Int32 nIndex) const;
440 };
441 
442 class ScDPLevel : public cppu::WeakImplHelper<
443                             css::sheet::XMembersSupplier,
444                             css::container::XNamed,
445                             css::sheet::XDataPilotMemberResults,
446                             css::beans::XPropertySet,
447                             css::lang::XServiceInfo >
448 {
449 private:
450     ScDPSource*                 pSource;
451     sal_Int32                        nDim;
452     sal_Int32                        nHier;
453     sal_Int32                        nLev;
454     rtl::Reference<ScDPMembers> mxMembers;
455     css::uno::Sequence<sal_Int16> aSubTotals;
456     css::sheet::DataPilotFieldSortInfo     aSortInfo;      // stored user settings
457     css::sheet::DataPilotFieldAutoShowInfo aAutoShowInfo;  // stored user settings
458     css::sheet::DataPilotFieldLayoutInfo   aLayoutInfo;    // stored user settings
459                                                     // valid only from result calculation:
460     ::std::vector<sal_Int32>    aGlobalOrder;       // result of sorting by name or position
461     sal_Int32                   nSortMeasure;       // measure (index of data dimension) to sort by
462     sal_Int32                   nAutoMeasure;       // measure (index of data dimension) for AutoShow
463     bool                        bShowEmpty:1;
464     bool                        bEnableLayout:1;      // enabled only for row fields, not for the innermost one
465     bool                        bRepeatItemLabels:1;
466 
467 public:
468                             ScDPLevel( ScDPSource* pSrc, sal_Int32 nDim, sal_Int32 nHier, sal_Int32 nLevel );
469     virtual                 ~ScDPLevel() override;
470 
471     ScDPMembers*            GetMembersObject();
472 
473                             // XNamed
474     virtual OUString SAL_CALL getName() override;
475     virtual void SAL_CALL   setName( const OUString& aName ) override;
476 
477                             // XMembersSupplier
478     virtual css::uno::Reference< css::sheet::XMembersAccess > SAL_CALL
479                             getMembers() override;
480 
481                             // XDataPilotMemberResults
482     virtual css::uno::Sequence< css::sheet::MemberResult > SAL_CALL
483                             getResults() override;
484 
485                             // XPropertySet
486     virtual css::uno::Reference< css::beans::XPropertySetInfo >
487                             SAL_CALL getPropertySetInfo(  ) override;
488     virtual void SAL_CALL   setPropertyValue( const OUString& aPropertyName,
489                                     const css::uno::Any& aValue ) override;
490     virtual css::uno::Any SAL_CALL getPropertyValue(
491                                     const OUString& PropertyName ) override;
492     virtual void SAL_CALL   addPropertyChangeListener( const OUString& aPropertyName,
493                                     const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
494     virtual void SAL_CALL   removePropertyChangeListener( const OUString& aPropertyName,
495                                     const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
496     virtual void SAL_CALL   addVetoableChangeListener( const OUString& PropertyName,
497                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
498     virtual void SAL_CALL   removeVetoableChangeListener( const OUString& PropertyName,
499                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
500 
501                             // XServiceInfo
502     virtual OUString SAL_CALL getImplementationName(  ) override;
503     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
504     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
505 
506     css::uno::Sequence<sal_Int16> getSubTotals() const;
getShowEmpty() const507     bool getShowEmpty() const { return bShowEmpty;}
getRepeatItemLabels() const508     bool getRepeatItemLabels() const { return bRepeatItemLabels; }
509 
GetSortInfo() const510     const css::sheet::DataPilotFieldSortInfo& GetSortInfo() const      { return aSortInfo; }
GetAutoShow() const511     const css::sheet::DataPilotFieldAutoShowInfo& GetAutoShow() const  { return aAutoShowInfo; }
512 
513     void EvaluateSortOrder();
514     void SetEnableLayout(bool bSet);
515 
GetGlobalOrder() const516     const ::std::vector<sal_Int32>& GetGlobalOrder() const      { return aGlobalOrder; }
GetGlobalOrder()517     ::std::vector<sal_Int32>&  GetGlobalOrder()                 { return aGlobalOrder; }
GetSortMeasure() const518     sal_Int32                  GetSortMeasure() const              { return nSortMeasure; }
GetAutoMeasure() const519     sal_Int32                  GetAutoMeasure() const              { return nAutoMeasure; }
520 
IsOutlineLayout() const521     bool IsOutlineLayout() const
522     {
523         return bEnableLayout &&
524             aLayoutInfo.LayoutMode !=
525             css::sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT;
526     }
527 
IsSubtotalsAtTop() const528     bool IsSubtotalsAtTop() const
529     {
530         return bEnableLayout &&
531             aLayoutInfo.LayoutMode ==
532             css::sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP;
533     }
534 
IsAddEmpty() const535     bool IsAddEmpty() const
536     {
537         return bEnableLayout && aLayoutInfo.AddEmptyLines;
538     }
539 
540     //! number format (for data fields and date fields)
541 };
542 
543 // hash map from name to index in the member array, for fast name access
544 typedef std::unordered_map< OUString, sal_Int32 > ScDPMembersHashMap;
545 
546 class ScDPMembers : public cppu::WeakImplHelper<
547                             css::sheet::XMembersAccess,
548                             css::lang::XServiceInfo >
549 {
550 private:
551     typedef std::vector<rtl::Reference<ScDPMember> > MembersType;
552     ScDPSource*     pSource;
553     sal_Int32            nDim;
554     sal_Int32            nHier;
555     sal_Int32            nLev;
556     sal_Int32            nMbrCount;
557     mutable MembersType maMembers;
558     mutable ScDPMembersHashMap aHashMap;
559 
560 public:
561                             ScDPMembers( ScDPSource* pSrc, sal_Int32 nDim, sal_Int32 nHier, sal_Int32 nLev );
562     virtual                 ~ScDPMembers() override;
563 
564                             // XMembersAccess
565     virtual css::uno::Sequence< OUString > SAL_CALL getLocaleIndependentElementNames() override;
566 
567                             // XNameAccess
568     virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) override;
569     virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override;
570     virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
571 
572                             // XElementAccess
573     virtual css::uno::Type SAL_CALL getElementType() override;
574     virtual sal_Bool SAL_CALL hasElements() override;
575 
576                             // XServiceInfo
577     virtual OUString SAL_CALL getImplementationName(  ) override;
578     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
579     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
580 
getCount() const581     sal_Int32               getCount() const { return nMbrCount;}
582     ScDPMember*             getByIndex(sal_Int32 nIndex) const;
583 
584     sal_Int32               getMinMembers() const;
585 
586     sal_Int32               GetIndexFromName( const OUString& rName ) const;     // <0 if not found
587     const ScDPItemData*     GetSrcItemDataByIndex(  SCROW nIndex);
588 
589 private:
590     /// @throws css::uno::RuntimeException
591     css::uno::Sequence< OUString > getElementNames( bool bLocaleIndependent ) const;
592 };
593 
594 class ScDPMember : public cppu::WeakImplHelper<
595                             css::container::XNamed,
596                             css::beans::XPropertySet,
597                             css::lang::XServiceInfo >
598 {
599 private:
600     ScDPSource*     pSource;
601     sal_Int32       nDim;
602     sal_Int32       nHier;
603     sal_Int32       nLev;
604 
605     SCROW           mnDataId;
606     std::optional<OUString> mpLayoutName;
607 
608     sal_Int32       nPosition;          // manual sorting
609     bool            bVisible;
610     bool            bShowDet;
611 
612 public:
613     ScDPMember(ScDPSource* pSrc, sal_Int32 nDim, sal_Int32 nHier, sal_Int32 nLev, SCROW nIndex);
614     virtual                 ~ScDPMember() override;
615     ScDPMember(const ScDPMember&) = delete;
616     ScDPMember& operator=(const ScDPMember&) = delete;
617 
618     OUString GetNameStr( bool bLocaleIndependent ) const;
619     ScDPItemData FillItemData() const;
620     const ScDPItemData*  GetItemData() const;
GetItemDataId() const621     SCROW GetItemDataId() const { return mnDataId; }
622     bool IsNamedItem(SCROW nIndex) const;
623 
624     const std::optional<OUString> & GetLayoutName() const;
GetDim() const625     tools::Long GetDim() const { return nDim;}
626 
627     sal_Int32               Compare( const ScDPMember& rOther ) const;      // visible order
628 
629                             // XNamed
630     virtual OUString SAL_CALL getName() override;
631     virtual void SAL_CALL   setName( const OUString& aName ) override;
632 
633                             // XPropertySet
634     virtual css::uno::Reference< css::beans::XPropertySetInfo >
635                             SAL_CALL getPropertySetInfo(  ) override;
636     virtual void SAL_CALL   setPropertyValue( const OUString& aPropertyName,
637                                     const css::uno::Any& aValue ) override;
638     virtual css::uno::Any SAL_CALL getPropertyValue(
639                                     const OUString& PropertyName ) override;
640     virtual void SAL_CALL   addPropertyChangeListener( const OUString& aPropertyName,
641                                     const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
642     virtual void SAL_CALL   removePropertyChangeListener( const OUString& aPropertyName,
643                                     const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
644     virtual void SAL_CALL   addVetoableChangeListener( const OUString& PropertyName,
645                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
646     virtual void SAL_CALL   removeVetoableChangeListener( const OUString& PropertyName,
647                                     const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
648 
649                             // XServiceInfo
650     virtual OUString SAL_CALL getImplementationName(  ) override;
651     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
652     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
653 
isVisible() const654     bool isVisible() const { return bVisible;}
getShowDetails() const655     bool getShowDetails() const { return bShowDet;}
656 };
657 
658 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
659