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