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_SOURCE_FILTER_INC_XEPIVOT_HXX 21 #define INCLUDED_SC_SOURCE_FILTER_INC_XEPIVOT_HXX 22 23 #include "xerecord.hxx" 24 #include "xlpivot.hxx" 25 #include "xeroot.hxx" 26 27 class ScDPObject; 28 class ScDPSaveData; 29 class ScDPSaveDimension; 30 class ScDPSaveMember; 31 class ScDPSaveGroupDimension; 32 struct ScDPNumGroupInfo; 33 34 // Pivot cache 35 36 /** Represents a data item in a pivot cache containing data of any type. */ 37 class XclExpPCItem : public XclExpRecord, public XclPCItem 38 { 39 public: 40 explicit XclExpPCItem( const OUString& rText ); 41 explicit XclExpPCItem( double fValue, const OUString& rText = OUString() ); 42 explicit XclExpPCItem( const DateTime& rDateTime, const OUString& rText = OUString() ); 43 explicit XclExpPCItem( sal_Int16 nValue ); 44 explicit XclExpPCItem( bool bValue, const OUString& rText ); 45 GetTypeFlag() const46 sal_uInt16 GetTypeFlag() const { return mnTypeFlag; } 47 48 bool EqualsText( const OUString& rText ) const; 49 bool EqualsDouble( double fValue ) const; 50 bool EqualsDateTime( const DateTime& rDateTime ) const; 51 bool EqualsBool( bool bValue ) const; 52 53 private: 54 virtual void WriteBody( XclExpStream& rStrm ) override; 55 56 private: 57 sal_uInt16 mnTypeFlag; /// Data type flag. 58 }; 59 60 class XclExpPCField : public XclExpRecord, public XclPCField, protected XclExpRoot 61 { 62 public: 63 /** Creates a standard pivot cache field, filled from sheet source data. */ 64 explicit XclExpPCField( const XclExpRoot& rRoot, 65 sal_uInt16 nFieldIdx, 66 const ScDPObject& rDPObj, const ScRange& rRange ); 67 /** Creates a child grouping pivot cache field, filled from the passed grouping info. */ 68 explicit XclExpPCField( const XclExpRoot& rRoot, 69 sal_uInt16 nFieldIdx, 70 const ScDPObject& rDPObj, const ScDPSaveGroupDimension& rGroupDim, 71 const XclExpPCField& rBaseField ); 72 virtual ~XclExpPCField() override; 73 74 /** Sets the passed field as direct grouping child field of this field. */ 75 void SetGroupChildField( const XclExpPCField& rChildField ); 76 77 /** Returns the name of this cache field. */ GetFieldName() const78 const OUString& GetFieldName() const { return maFieldInfo.maName; } 79 80 /** Returns the number of visible items of this field. */ 81 sal_uInt16 GetItemCount() const; 82 /** Returns the specified pivot cache item (returns visible items in groupings). */ 83 const XclExpPCItem* GetItem( sal_uInt16 nItemIdx ) const; 84 /** Returns the index of a pivot cache item, or EXC_PC_NOITEM on error. */ 85 sal_uInt16 GetItemIndex( const OUString& rItemName ) const; 86 87 /** Returns the size an item index needs to write out. */ 88 std::size_t GetIndexSize() const; 89 /** Writes the item index at the passed source row position as part of the SXINDEXLIST record. */ 90 void WriteIndex( XclExpStream& rStrm, sal_uInt32 nSrcRow ) const; 91 92 /** Writes the pivot cache field and all items and other related records. */ 93 virtual void Save( XclExpStream& rStrm ) override; 94 95 private: 96 typedef XclExpRecordList< XclExpPCItem > XclExpPCItemList; 97 98 /** Returns the item list that contains the visible items. 99 @descr Visible items are equal to source items in standard fields, 100 but are generated items in grouping and calculated fields. */ 101 const XclExpPCItemList& GetVisItemList() const; 102 103 /** Initializes a standard field. Inserts all original source items. */ 104 void InitStandardField( const ScRange& rRange ); 105 /** Initializes a standard grouping field. Inserts all visible grouping items. */ 106 void InitStdGroupField( const XclExpPCField& rBaseField, const ScDPSaveGroupDimension& rGroupDim ); 107 /** Initializes a numeric grouping field. Inserts all visible grouping items and the limit settings. */ 108 void InitNumGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo ); 109 /** Initializes a date grouping field. Inserts all visible grouping items and the limit settings. */ 110 void InitDateGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nDatePart ); 111 112 /** Inserts the passed index into the item index array of original items. */ 113 void InsertItemArrayIndex( size_t nListPos ); 114 /** Inserts an original source item. Updates item index array. */ 115 void InsertOrigItem( XclExpPCItem* pNewItem ); 116 /** Inserts an original text item, if it is not contained already. */ 117 void InsertOrigTextItem( const OUString& rText ); 118 /** Inserts an original value item, if it is not contained already. */ 119 void InsertOrigDoubleItem( double fValue, const OUString& rText ); 120 /** Inserts an original date/time item, if it is not contained already. */ 121 void InsertOrigDateTimeItem( const DateTime& rDateTime, const OUString& rText ); 122 /** Inserts an original boolean item, if it is not contained already. */ 123 void InsertOrigBoolItem( bool bValue, const OUString& rText ); 124 125 /** Inserts an item into the grouping item list. Does not change anything else. 126 @return The list index of the new item. */ 127 sal_uInt16 InsertGroupItem( XclExpPCItem* pNewItem ); 128 /** Generates and inserts all visible items for numeric or date grouping. */ 129 void InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nDatePart = 0 ); 130 131 /** Inserts the SXDOUBLE items that specify the limits for a numeric grouping. */ 132 void SetNumGroupLimit( const ScDPNumGroupInfo& rNumInfo ); 133 /** Inserts the SXDATETIME/SXINTEGER items that specify the limits for a date grouping. 134 @param bUseStep true = Insert the passed step value; false = always insert 1. */ 135 void SetDateGroupLimit( const ScDPNumGroupInfo& rDateInfo, bool bUseStep ); 136 137 /** Initializes flags and item count fields. */ 138 void Finalize(); 139 140 /** Writes an SXNUMGROUP record and the additional items for a numeric grouping field. */ 141 void WriteSxnumgroup( XclExpStream& rStrm ); 142 /** Writes an SXGROUPINFO record describing the item order in grouping fields. */ 143 void WriteSxgroupinfo( XclExpStream& rStrm ); 144 145 /** Writes the contents of the SXFIELD record for this field. */ 146 virtual void WriteBody( XclExpStream& rStrm ) override; 147 148 private: 149 XclExpPCItemList maOrigItemList; /// List with original items. 150 XclExpPCItemList maGroupItemList; /// List with grouping items. 151 ScfUInt16Vec maIndexVec; /// Indexes into maItemList. 152 XclExpPCItemList maNumGroupLimits; /// List with limit values for numeric grouping. 153 sal_uInt16 mnTypeFlags; /// Collected item data type flags. 154 }; 155 156 class XclExpPivotCache : protected XclExpRoot 157 { 158 public: 159 explicit XclExpPivotCache( const XclExpRoot& rRoot, 160 const ScDPObject& rDPObj, sal_uInt16 nListIdx ); 161 162 /** Returns true, if the cache has been constructed successfully. */ IsValid() const163 bool IsValid() const { return mbValid; } 164 /** Returns true, if the item index list will be written. */ 165 bool HasItemIndexList() const; 166 167 /** Returns the list index of the cache used in pivot table records. */ GetCacheIndex() const168 sal_uInt16 GetCacheIndex() const { return mnListIdx; } 169 170 /** Returns the number of pivot cache fields. */ 171 sal_uInt16 GetFieldCount() const; 172 /** Returns the specified pivot cache field. */ 173 const XclExpPCField* GetField( sal_uInt16 nFieldIdx ) const; 174 /** Returns true, if this pivot cache contains non-standard fields (e.g. grouping fields). */ 175 bool HasAddFields() const; 176 177 /** Returns true, if the passed DP object has the same data source as this cache. */ 178 bool HasEqualDataSource( const ScDPObject& rDPObj ) const; 179 180 /** Writes related records into Workbook stream and creates the pivot cache storage stream. */ 181 void Save( XclExpStream& rStrm ); 182 static void SaveXml( XclExpXmlStream& rStrm ); 183 184 private: 185 /** Adds all pivot cache fields. */ 186 void AddFields( const ScDPObject& rDPObj ); 187 188 /** Adds all standard pivot cache fields based on source data. */ 189 void AddStdFields( const ScDPObject& rDPObj ); 190 /** Adds all grouping pivot cache fields. */ 191 void AddGroupFields( const ScDPObject& rDPObj ); 192 193 /** Writes the DCONREF record containing the source range. */ 194 void WriteDconref( XclExpStream& rStrm ) const; 195 /** DCONNAME record contains range name source. */ 196 void WriteDConName( XclExpStream& rStrm ) const; 197 198 /** Creates the pivot cache storage stream and writes the cache. */ 199 void WriteCacheStream(); 200 /** Writes the SXDB record. */ 201 void WriteSxdb( XclExpStream& rStrm ) const; 202 /** Writes the SXDBEX record. */ 203 static void WriteSxdbex( XclExpStream& rStrm ); 204 /** Writes the SXINDEXLIST record list containing the item index table. */ 205 void WriteSxindexlistList( XclExpStream& rStrm ) const; 206 207 private: 208 typedef XclExpRecordList< XclExpPCField > XclExpPCFieldList; 209 typedef XclExpPCFieldList::RecordRefType XclExpPCFieldRef; 210 211 XclPCInfo maPCInfo; /// Pivot cache settings (SXDB record). 212 XclExpPCFieldList maFieldList; /// List of all pivot cache fields. 213 OUString maTabName; /// Name of source data sheet. 214 OUString maSrcRangeName; /// Range name for source data. 215 ScRange maOrigSrcRange; /// The original sheet source range. 216 ScRange maExpSrcRange; /// The exported sheet source range. 217 ScRange maDocSrcRange; /// The range used to build the cache fields and items. 218 sal_uInt16 const mnListIdx; /// List index in pivot cache buffer. 219 bool mbValid; /// true = The cache is valid for export. 220 }; 221 222 // Pivot table 223 224 class XclExpPivotTable; 225 226 /** Data field position specifying the pivot table field index (first) and data info index (second). */ 227 typedef ::std::pair< sal_uInt16, sal_uInt16 > XclPTDataFieldPos; 228 229 class XclExpPTItem : public XclExpRecord 230 { 231 public: 232 explicit XclExpPTItem( const XclExpPCField& rCacheField, sal_uInt16 nCacheIdx ); 233 explicit XclExpPTItem( sal_uInt16 nItemType, sal_uInt16 nCacheIdx ); 234 235 /** Returns the internal name of this item. */ 236 OUString GetItemName() const; 237 238 /** Fills this item with properties from the passed save member. */ 239 void SetPropertiesFromMember( const ScDPSaveMember& rSaveMem ); 240 241 private: 242 /** Writes the SXVI record body describing the pivot table item. */ 243 virtual void WriteBody( XclExpStream& rStrm ) override; 244 245 private: 246 const XclExpPCItem* mpCacheItem; /// The referred pivot cache item. 247 XclPTItemInfo maItemInfo; /// General data for this item. 248 }; 249 250 class XclExpPTField : public XclExpRecordBase 251 { 252 public: 253 explicit XclExpPTField( const XclExpPivotTable& rPTable, sal_uInt16 nCacheIdx ); 254 255 // data access ------------------------------------------------------------ 256 257 /** Returns the name of this field. */ 258 OUString GetFieldName() const; 259 /** Returns the pivot table field list index of this field. 260 * The field index is always equal to cache index. 261 */ GetFieldIndex() const262 sal_uInt16 GetFieldIndex() const { return maFieldInfo.mnCacheIdx; } 263 264 /** Returns the index of the last inserted data info struct. */ 265 sal_uInt16 GetLastDataInfoIndex() const; 266 267 /** Returns the list index of an item by its name. 268 @param nDefaultIdx This value will be returned, if the item could not be found. */ 269 sal_uInt16 GetItemIndex( const OUString& rName, sal_uInt16 nDefaultIdx ) const; 270 271 // fill data -------------------------------------------------------------- 272 273 /** Fills this field with row/column/page properties from the passed save dimension. */ 274 void SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 275 /** Fills this field with data field properties from the passed save dimension. */ 276 void SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 277 278 /** Appends special items describing the field subtotal entries. */ 279 void AppendSubtotalItems(); 280 281 // records ---------------------------------------------------------------- 282 283 /** Writes an entry for an SXPI record containing own page field info. */ 284 void WriteSxpiEntry( XclExpStream& rStrm ) const; 285 /** Writes an SXDI records containing info about a data field. */ 286 void WriteSxdi( XclExpStream& rStrm, sal_uInt16 nDataInfoIdx ) const; 287 288 /** Writes the entire pivot table field. */ 289 virtual void Save( XclExpStream& rStrm ) override; 290 291 private: 292 /** Returns an item by its name. */ 293 XclExpPTItem* GetItemAcc( const OUString& rName ); 294 295 /** Appends a special item describing a field subtotal entry. */ 296 void AppendSubtotalItem( sal_uInt16 nItemType ); 297 298 /** Writes the SXVD record introducing the field. */ 299 void WriteSxvd( XclExpStream& rStrm ) const; 300 /** Writes the SXVDEX record containing additional settings. */ 301 void WriteSxvdex( XclExpStream& rStrm ) const; 302 303 private: 304 typedef ::std::vector< XclPTDataFieldInfo > XclPTDataFieldInfoVec; 305 typedef XclExpRecordList< XclExpPTItem > XclExpPTItemList; 306 307 const XclExpPivotTable& mrPTable; /// Parent pivot table containing this field. 308 const XclExpPCField* mpCacheField; /// The referred pivot cache field. 309 XclPTFieldInfo maFieldInfo; /// General field info (SXVD record). 310 XclPTFieldExtInfo maFieldExtInfo; /// Extended field info (SXVDEX record). 311 XclPTPageFieldInfo maPageInfo; /// Page field info (entry in SXPI record). 312 XclPTDataFieldInfoVec maDataInfoVec; /// List of extended data field info (SXDI records). 313 XclExpPTItemList maItemList; /// List of all items of this field. 314 }; 315 316 class XclExpPivotTable : public XclExpRecordBase, protected XclExpRoot 317 { 318 public: 319 explicit XclExpPivotTable( const XclExpRoot& rRoot, 320 const ScDPObject& rDPObj, const XclExpPivotCache& rPCache ); 321 322 /** Returns a pivot cache field. */ 323 const XclExpPCField* GetCacheField( sal_uInt16 nCacheIdx ) const; 324 325 /** Returns the output range of the pivot table. */ GetScTab() const326 SCTAB GetScTab() const { return mnOutScTab; } 327 328 /** Returns a pivot table field by its name. */ 329 const XclExpPTField* GetField( sal_uInt16 nFieldIdx ) const; 330 /** Returns a pivot table field by its name. */ 331 const XclExpPTField* GetField( const OUString& rName ) const; 332 333 /** Returns the data-field-only index of the first data field with the passed name. 334 @param nDefaultIdx This value will be returned, if the field could not be found. */ 335 sal_uInt16 GetDataFieldIndex( const OUString& rName, sal_uInt16 nDefaultIdx ) const; 336 337 /** Writes the entire pivot table. */ 338 virtual void Save( XclExpStream& rStrm ) override; 339 340 private: 341 /** Returns a pivot table field by its name. */ 342 XclExpPTField* GetFieldAcc( const OUString& rName ); 343 /** Returns a pivot table field corresponding to the passed save dimension. */ 344 XclExpPTField* GetFieldAcc( const ScDPSaveDimension& rSaveDim ); 345 346 // fill data -------------------------------------------------------------- 347 348 /** Fills internal members with all properties from the passed save data. */ 349 void SetPropertiesFromDP( const ScDPSaveData& rSaveData ); 350 /** Fills a pivot table field with all properties from the passed save dimension. */ 351 void SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 352 /** Fills a pivot table data field with all properties from the passed save dimension. */ 353 void SetDataFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 354 355 /** Initializes any data after processing the entire source DataPilot. */ 356 void Finalize(); 357 358 // records ---------------------------------------------------------------- 359 360 /** Writes the SXVIEW record starting the pivot table. */ 361 void WriteSxview( XclExpStream& rStrm ) const; 362 /** Writes an SXIVD record for row field or column field order. */ 363 static void WriteSxivd( XclExpStream& rStrm, const ScfUInt16Vec& rFields ); 364 /** Writes the SXPI record containing page field info. */ 365 void WriteSxpi( XclExpStream& rStrm ) const; 366 /** Writes all SXDI records containing info about the data fields. */ 367 void WriteSxdiList( XclExpStream& rStrm ) const; 368 /** Writes a dummy SXLI records containing item layout info. */ 369 static void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ); 370 /** Writes the SXEX records containing additional pivot table info. */ 371 void WriteSxex( XclExpStream& rStrm ) const; 372 373 void WriteQsiSxTag( XclExpStream& rStrm ) const; 374 /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */ 375 void WriteSxViewEx9( XclExpStream& rStrm ) const; 376 377 private: 378 typedef XclExpRecordList< XclExpPTField > XclExpPTFieldList; 379 typedef XclExpPTFieldList::RecordRefType XclExpPTFieldRef; 380 typedef ::std::vector< XclPTDataFieldPos > XclPTDataFieldPosVec; 381 382 const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on. 383 XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record). 384 XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). 385 XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9) 386 XclExpPTFieldList maFieldList; /// All fields in pivot cache order. 387 ScfUInt16Vec maRowFields; /// Row field indexes. 388 ScfUInt16Vec maColFields; /// Column field indexes. 389 ScfUInt16Vec maPageFields; /// Page field indexes. 390 XclPTDataFieldPosVec maDataFields; /// Data field indexes. 391 XclExpPTField maDataOrientField; /// Special data field orientation field. 392 SCTAB mnOutScTab; /// Sheet index of the output range. 393 bool mbValid; /// true = The pivot table is valid for export. 394 bool mbFilterBtn; /// true = DataPilot has filter button. 395 }; 396 397 /** The main class for pivot table export. 398 399 This class contains all pivot caches and pivot tables in a Calc document. 400 It creates the pivot cache streams and pivot table records in the main 401 workbook stream. It supports sharing of pivot caches between multiple pivot 402 tables to decrease file size. 403 */ 404 class XclExpPivotTableManager : protected XclExpRoot 405 { 406 public: 407 explicit XclExpPivotTableManager( const XclExpRoot& rRoot ); 408 409 /** Creates all pivot tables and caches from the Calc DataPilot objects. */ 410 void CreatePivotTables(); 411 412 /** Creates a record wrapper for exporting all pivot caches. */ 413 XclExpRecordRef CreatePivotCachesRecord(); 414 /** Creates a record wrapper for exporting all pivot tables of the specified sheet. */ 415 XclExpRecordRef CreatePivotTablesRecord( SCTAB nScTab ); 416 417 /** Writes all pivot caches (all Workbook records and cache streams). */ 418 void WritePivotCaches( XclExpStream& rStrm ); 419 /** Writes all pivot tables of the specified Calc sheet. */ 420 void WritePivotTables( XclExpStream& rStrm, SCTAB nScTab ); 421 422 private: 423 /** Finds an existing (if enabled in mbShareCaches) or creates a new pivot cache. 424 @return Pointer to the pivot cache or 0, if the passed source range was invalid. */ 425 const XclExpPivotCache* CreatePivotCache( const ScDPObject& rDPObj ); 426 427 private: 428 typedef XclExpRecordList< XclExpPivotCache > XclExpPivotCacheList; 429 typedef XclExpPivotCacheList::RecordRefType XclExpPivotCacheRef; 430 typedef XclExpRecordList< XclExpPivotTable > XclExpPivotTableList; 431 typedef XclExpPivotTableList::RecordRefType XclExpPivotTableRef; 432 433 XclExpPivotCacheList maPCacheList; /// List of all pivot caches. 434 XclExpPivotTableList maPTableList; /// List of all pivot tables. 435 }; 436 437 #endif 438 439 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 440