| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #ifndef SC_XEPIVOT_HXX |
| #define SC_XEPIVOT_HXX |
| |
| #include <map> |
| #include "xerecord.hxx" |
| #include "xlpivot.hxx" |
| #include "xeroot.hxx" |
| |
| class ScDPObject; |
| class ScDPSaveData; |
| class ScDPSaveDimension; |
| class ScDPSaveMember; |
| class ScDPDimensionSaveData; |
| class ScDPSaveGroupDimension; |
| class ScDPSaveNumGroupDimension; |
| struct ScDPNumGroupInfo; |
| |
| // ============================================================================ |
| // Pivot cache |
| // ============================================================================ |
| |
| /** Represents a data item in a pivot cache containing data of any type. */ |
| class XclExpPCItem : public XclExpRecord, public XclPCItem |
| { |
| public: |
| explicit XclExpPCItem( const String& rText ); |
| explicit XclExpPCItem( double fValue ); |
| explicit XclExpPCItem( const DateTime& rDateTime ); |
| explicit XclExpPCItem( sal_Int16 nValue ); |
| explicit XclExpPCItem( bool bValue ); |
| |
| inline sal_uInt16 GetTypeFlag() const { return mnTypeFlag; } |
| |
| bool EqualsText( const String& rText ) const; |
| bool EqualsDouble( double fValue ) const; |
| bool EqualsDateTime( const DateTime& rDateTime ) const; |
| bool EqualsBool( bool bValue ) const; |
| |
| private: |
| virtual void WriteBody( XclExpStream& rStrm ); |
| |
| private: |
| sal_uInt16 mnTypeFlag; /// Data type flag. |
| }; |
| |
| // ============================================================================ |
| |
| class XclExpPivotCache; |
| |
| class XclExpPCField : public XclExpRecord, public XclPCField, protected XclExpRoot |
| { |
| public: |
| /** Creates a standard pivot cache field, filled from sheet source data. */ |
| explicit XclExpPCField( const XclExpRoot& rRoot, |
| const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx, |
| const ScDPObject& rDPObj, const ScRange& rRange ); |
| /** Creates a child grouping pivot cache field, filled from the passed grouping info. */ |
| explicit XclExpPCField( const XclExpRoot& rRoot, |
| const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx, |
| const ScDPObject& rDPObj, const ScDPSaveGroupDimension& rGroupDim, |
| const XclExpPCField& rBaseField ); |
| virtual ~XclExpPCField(); |
| |
| /** Sets the passed field as direct grouping child field of this field. */ |
| void SetGroupChildField( const XclExpPCField& rChildField ); |
| /** Converts this standard field into a numeric grouping field. */ |
| void ConvertToNumGroup( const ScDPObject& rDPObj, const ScDPSaveNumGroupDimension& rNumGroupDim ); |
| |
| /** Returns the name of this cache field. */ |
| inline const String& GetFieldName() const { return maFieldInfo.maName; } |
| |
| /** Returns the number of visible items of this field. */ |
| sal_uInt16 GetItemCount() const; |
| /** Returns the specified pivot cache item (returns visible items in groupings). */ |
| const XclExpPCItem* GetItem( sal_uInt16 nItemIdx ) const; |
| /** Returns the index of a pivot cache item, or EXC_PC_NOITEM on error. */ |
| sal_uInt16 GetItemIndex( const String& rItemName ) const; |
| |
| /** Returns the size an item index needs to write out. */ |
| sal_Size GetIndexSize() const; |
| /** Writes the item index at the passed source row position as part of the SXINDEXLIST record. */ |
| void WriteIndex( XclExpStream& rStrm, sal_uInt32 nSrcRow ) const; |
| |
| /** Writes the pivot cache field and all items and other related records. */ |
| virtual void Save( XclExpStream& rStrm ); |
| |
| private: |
| typedef XclExpRecordList< XclExpPCItem > XclExpPCItemList; |
| |
| /** Returns the item list that contains the visible items. |
| @descr Visible items are equal to source items in standard fields, |
| but are generated items in grouping and calculated fields. */ |
| const XclExpPCItemList& GetVisItemList() const; |
| |
| /** Initializes a standard field. Inserts all original source items. */ |
| void InitStandardField( const ScRange& rRange ); |
| /** Initializes a standard grouping field. Inserts all visible grouping items. */ |
| void InitStdGroupField( const XclExpPCField& rBaseField, const ScDPSaveGroupDimension& rGroupDim ); |
| /** Initializes a numeric grouping field. Inserts all visible grouping items and the limit settings. */ |
| void InitNumGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo ); |
| /** Initializes a date grouping field. Inserts all visible grouping items and the limit settings. */ |
| void InitDateGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nDatePart ); |
| |
| /** Inserts the passed index into the item index array of original items. */ |
| void InsertItemArrayIndex( size_t nListPos ); |
| /** Inserts an original source item. Updates item index array. */ |
| void InsertOrigItem( XclExpPCItem* pNewItem ); |
| /** Inserts an original text item, if it is not contained already. */ |
| void InsertOrigTextItem( const String& rText ); |
| /** Inserts an original value item, if it is not contained already. */ |
| void InsertOrigDoubleItem( double fValue ); |
| /** Inserts an original date/time item, if it is not contained already. */ |
| void InsertOrigDateTimeItem( const DateTime& rDateTime ); |
| /** Inserts an original boolean item, if it is not contained already. */ |
| void InsertOrigBoolItem( bool bValue ); |
| |
| /** Inserts an item into the grouping item list. Does not change anything else. |
| @return The list index of the new item. */ |
| sal_uInt16 InsertGroupItem( XclExpPCItem* pNewItem ); |
| /** Generates and inserts all visible items for numeric or date grouping. */ |
| void InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nDatePart = 0 ); |
| |
| /** Inserts the SXDOUBLE items that specify the limits for a numeric grouping. */ |
| void SetNumGroupLimit( const ScDPNumGroupInfo& rNumInfo ); |
| /** Inserts the SXDATETIME/SXINTEGER items that specify the limits for a date grouping. |
| @param bUseStep true = Insert the passed step value; false = always insert 1. */ |
| void SetDateGroupLimit( const ScDPNumGroupInfo& rDateInfo, bool bUseStep ); |
| |
| /** Initializes flags and item count fields. */ |
| void Finalize(); |
| |
| /** Writes an SXNUMGROUP record and the additional items for a numeric grouping field. */ |
| void WriteSxnumgroup( XclExpStream& rStrm ); |
| /** Writes an SXGROUPINFO record describing the item order in grouping fields. */ |
| void WriteSxgroupinfo( XclExpStream& rStrm ); |
| |
| /** Writes the contents of the SXFIELD record for this field. */ |
| virtual void WriteBody( XclExpStream& rStrm ); |
| |
| private: |
| const XclExpPivotCache& mrPCache; /// Parent pivot cache containing this field. |
| XclExpPCItemList maOrigItemList; /// List with original items. |
| XclExpPCItemList maGroupItemList; /// List with grouping items. |
| ScfUInt16Vec maIndexVec; /// Indexes into maItemList. |
| XclExpPCItemList maNumGroupLimits; /// List with limit values for numeric grouping. |
| sal_uInt16 mnTypeFlags; /// Collected item data type flags. |
| }; |
| |
| // ============================================================================ |
| |
| class XclExpPivotCache : protected XclExpRoot |
| { |
| public: |
| explicit XclExpPivotCache( const XclExpRoot& rRoot, |
| const ScDPObject& rDPObj, sal_uInt16 nListIdx ); |
| |
| /** Returns true, if the cache has been constructed successfully. */ |
| inline bool IsValid() const { return mbValid; } |
| /** Returns true, if the item index list will be written. */ |
| bool HasItemIndexList() const; |
| |
| /** Returns the stream identifier used to create the cache stream. */ |
| inline sal_uInt16 GetStreamId() const { return maPCInfo.mnStrmId; } |
| /** Returns the list index of the cache used in pivot table records. */ |
| inline sal_uInt16 GetCacheIndex() const { return mnListIdx; } |
| |
| /** Returns the number of pivot cache fields. */ |
| sal_uInt16 GetFieldCount() const; |
| /** Returns the specified pivot cache field. */ |
| const XclExpPCField* GetField( sal_uInt16 nFieldIdx ) const; |
| //UNUSED2009-05 /** Returns a pivot cache field by its name. */ |
| //UNUSED2009-05 const XclExpPCField* GetField( const String& rFieldName ) const; |
| /** Returns true, if this pivot cache contains non-standard fields (e.g. grouping fields). */ |
| bool HasAddFields() const; |
| |
| /** Returns true, if the passed DP object has the same data source as this cache. */ |
| bool HasEqualDataSource( const ScDPObject& rDPObj ) const; |
| |
| /** Writes related records into Workbook stream and creates the pivot cache storage stream. */ |
| virtual void Save( XclExpStream& rStrm ); |
| virtual void SaveXml( XclExpXmlStream& rStrm ); |
| |
| private: |
| /** Returns read/write access to a pivot cache field. */ |
| XclExpPCField* GetFieldAcc( sal_uInt16 nFieldIdx ); |
| /** Returns read/write access to a pivot cache field. */ |
| XclExpPCField* GetFieldAcc( const String& rFieldName ); |
| |
| /** Adds all pivot cache fields. */ |
| void AddFields( const ScDPObject& rDPObj ); |
| |
| /** Adds all standard pivot cache fields based on source data. */ |
| void AddStdFields( const ScDPObject& rDPObj ); |
| /** Adds all grouping pivot cache fields. */ |
| void AddGroupFields( const ScDPObject& rDPObj ); |
| /** Adds all calculated pivot cache fields. */ |
| void AddCalcFields( const ScDPObject& rDPObj ); |
| |
| /** Writes the DCONREF record containing the source range. */ |
| void WriteDconref( XclExpStream& rStrm ) const; |
| |
| /** Creates the pivot cache storage stream and writes the cache. */ |
| void WriteCacheStream(); |
| /** Writes the SXDB record. */ |
| void WriteSxdb( XclExpStream& rStrm ) const; |
| /** Writes the SXDBEX record. */ |
| void WriteSxdbex( XclExpStream& rStrm ) const; |
| /** Writes the SXINDEXLIST record list containing the item index table. */ |
| void WriteSxindexlistList( XclExpStream& rStrm ) const; |
| |
| private: |
| typedef XclExpRecordList< XclExpPCField > XclExpPCFieldList; |
| typedef XclExpPCFieldList::RecordRefType XclExpPCFieldRef; |
| |
| XclPCInfo maPCInfo; /// Pivot cache settings (SXDB record). |
| XclExpPCFieldList maFieldList; /// List of all pivot cache fields. |
| String maTabName; /// Name of source data sheet. |
| ScRange maOrigSrcRange; /// The original sheet source range. |
| ScRange maExpSrcRange; /// The exported sheet source range. |
| ScRange maDocSrcRange; /// The range used to build the cache fields and items. |
| sal_uInt16 mnListIdx; /// List index in pivot cache buffer. |
| bool mbValid; /// true = The cache is valid for export. |
| }; |
| |
| // ============================================================================ |
| // Pivot table |
| // ============================================================================ |
| |
| class XclExpPivotTable; |
| |
| /** Data field position specifying the pivot table field index (first) and data info index (second). */ |
| typedef ::std::pair< sal_uInt16, sal_uInt16 > XclPTDataFieldPos; |
| |
| // ============================================================================ |
| |
| class XclExpPTItem : public XclExpRecord |
| { |
| public: |
| explicit XclExpPTItem( const XclExpPCField& rCacheField, sal_uInt16 nCacheIdx ); |
| explicit XclExpPTItem( sal_uInt16 nItemType, sal_uInt16 nCacheIdx, bool bUseCache ); |
| |
| /** Returns the internal name of this item. */ |
| const String& GetItemName() const; |
| |
| /** Fills this item with properties from the passed save member. */ |
| void SetPropertiesFromMember( const ScDPSaveMember& rSaveMem ); |
| |
| private: |
| /** Writes the SXVI record body describing the pivot table item. */ |
| virtual void WriteBody( XclExpStream& rStrm ); |
| |
| private: |
| const XclExpPCItem* mpCacheItem; /// The referred pivot cache item. |
| XclPTItemInfo maItemInfo; /// General data for this item. |
| }; |
| |
| // ============================================================================ |
| |
| class XclExpPTField : public XclExpRecordBase |
| { |
| public: |
| explicit XclExpPTField( const XclExpPivotTable& rPTable, sal_uInt16 nCacheIdx ); |
| |
| // data access ------------------------------------------------------------ |
| |
| /** Returns the name of this field. */ |
| const String& GetFieldName() const; |
| /** Returns the pivot table field list index of this field. */ |
| sal_uInt16 GetFieldIndex() const; |
| |
| /** Returns the index of the last inserted data info struct. */ |
| sal_uInt16 GetLastDataInfoIndex() const; |
| |
| //UNUSED2009-05 /** Returns an item by its name. */ |
| //UNUSED2009-05 const XclExpPTItem* GetItem( const String& rName ) const; |
| /** Returns the list index of an item by its name. |
| @param nDefaultIdx This value will be returned, if the item could not be found. */ |
| sal_uInt16 GetItemIndex( const String& rName, sal_uInt16 nDefaultIdx ) const; |
| |
| // fill data -------------------------------------------------------------- |
| |
| /** Fills this field with row/column/page properties from the passed save dimension. */ |
| void SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); |
| /** Fills this field with data field properties from the passed save dimension. */ |
| void SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); |
| |
| /** Appends special items describing the field subtotal entries. */ |
| void AppendSubtotalItems(); |
| |
| // records ---------------------------------------------------------------- |
| |
| /** Writes an entry for an SXPI record containing own page field info. */ |
| void WriteSxpiEntry( XclExpStream& rStrm ) const; |
| /** Writes an SXDI records containing info about a data field. */ |
| void WriteSxdi( XclExpStream& rStrm, sal_uInt16 nDataInfoIdx ) const; |
| |
| /** Writes the entire pivot table field. */ |
| virtual void Save( XclExpStream& rStrm ); |
| |
| // ------------------------------------------------------------------------ |
| private: |
| /** Returns an item by its name. */ |
| XclExpPTItem* GetItemAcc( const String& rName ); |
| |
| /** Appends a special item describing a field subtotal entry. */ |
| void AppendSubtotalItem( sal_uInt16 nItemType ); |
| |
| /** Writes the SXVD record introducing the field. */ |
| void WriteSxvd( XclExpStream& rStrm ) const; |
| /** Writes the SXVDEX record containing additional settings. */ |
| void WriteSxvdex( XclExpStream& rStrm ) const; |
| |
| private: |
| typedef ::std::vector< XclPTDataFieldInfo > XclPTDataFieldInfoVec; |
| typedef XclExpRecordList< XclExpPTItem > XclExpPTItemList; |
| |
| const XclExpPivotTable& mrPTable; /// Parent pivot table containing this field. |
| const XclExpPCField* mpCacheField; /// The referred pivot cache field. |
| XclPTFieldInfo maFieldInfo; /// General field info (SXVD record). |
| XclPTFieldExtInfo maFieldExtInfo; /// Extended field info (SXVDEX record). |
| XclPTPageFieldInfo maPageInfo; /// Page field info (entry in SXPI record). |
| XclPTDataFieldInfoVec maDataInfoVec; /// List of extended data field info (SXDI records). |
| XclExpPTItemList maItemList; /// List of all items of this field. |
| }; |
| |
| // ============================================================================ |
| |
| class XclExpPivotTable : public XclExpRecordBase, protected XclExpRoot |
| { |
| public: |
| explicit XclExpPivotTable( const XclExpRoot& rRoot, |
| const ScDPObject& rDPObj, const XclExpPivotCache& rPCache ); |
| |
| /** Returns a pivot cache field. */ |
| const XclExpPCField* GetCacheField( sal_uInt16 nCacheIdx ) const; |
| |
| /** Returns the output range of the pivot table. */ |
| inline SCTAB GetScTab() const { return mnOutScTab; } |
| |
| /** Returns a pivot table field by its name. */ |
| const XclExpPTField* GetField( sal_uInt16 nFieldIdx ) const; |
| /** Returns a pivot table field by its name. */ |
| const XclExpPTField* GetField( const String& rName ) const; |
| |
| /** Returns the data-field-only index of the first data field with the passed name. |
| @param nDefaultIdx This value will be returned, if the field could not be found. */ |
| sal_uInt16 GetDataFieldIndex( const String& rName, sal_uInt16 nDefaultIdx ) const; |
| |
| /** Writes the entire pivot table. */ |
| virtual void Save( XclExpStream& rStrm ); |
| |
| // ------------------------------------------------------------------------ |
| private: |
| /** Returns a pivot table field by its name. */ |
| XclExpPTField* GetFieldAcc( const String& rName ); |
| /** Returns a pivot table field corresponding to the passed save dimension. */ |
| XclExpPTField* GetFieldAcc( const ScDPSaveDimension& rSaveDim ); |
| |
| // fill data -------------------------------------------------------------- |
| |
| /** Fills internal members with all properties from the passed save data. */ |
| void SetPropertiesFromDP( const ScDPSaveData& rSaveData ); |
| /** Fills a pivot table field with all properties from the passed save dimension. */ |
| void SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); |
| /** Fills a pivot table data field with all properties from the passed save dimension. */ |
| void SetDataFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); |
| |
| /** Initializes any data after processing the entire source DataPilot. */ |
| void Finalize(); |
| |
| // records ---------------------------------------------------------------- |
| |
| /** Writes the SXVIEW record starting the pivot table. */ |
| void WriteSxview( XclExpStream& rStrm ) const; |
| /** Writes an SXIVD record for row field or column field order. */ |
| void WriteSxivd( XclExpStream& rStrm, const ScfUInt16Vec& rFields ) const; |
| /** Writes the SXPI record containing page field info. */ |
| void WriteSxpi( XclExpStream& rStrm ) const; |
| /** Writes all SXDI records containing info about the data fields. */ |
| void WriteSxdiList( XclExpStream& rStrm ) const; |
| /** Writes a dummy SXLI records containing item layout info. */ |
| void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const; |
| /** Writes the SXEX records containing additional pivot table info. */ |
| void WriteSxex( XclExpStream& rStrm ) const; |
| |
| void WriteQsiSxTag( XclExpStream& rStrm ) const; |
| /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */ |
| void WriteSxViewEx9( XclExpStream& rStrm ) const; |
| |
| // ------------------------------------------------------------------------ |
| private: |
| typedef XclExpRecordList< XclExpPTField > XclExpPTFieldList; |
| typedef XclExpPTFieldList::RecordRefType XclExpPTFieldRef; |
| typedef ::std::vector< XclPTDataFieldPos > XclPTDataFieldPosVec; |
| |
| const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on. |
| XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record). |
| XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). |
| XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9) |
| XclExpPTFieldList maFieldList; /// All fields in pivot cache order. |
| ScfUInt16Vec maRowFields; /// Row field indexes. |
| ScfUInt16Vec maColFields; /// Column field indexes. |
| ScfUInt16Vec maPageFields; /// Page field indexes. |
| XclPTDataFieldPosVec maDataFields; /// Data field indexes. |
| XclExpPTField maDataOrientField; /// Special data field orientation field. |
| SCTAB mnOutScTab; /// Sheet index of the output range. |
| bool mbValid; /// true = The pivot table is valid for export. |
| bool mbFilterBtn; /// true = DataPilot has filter button. |
| }; |
| |
| // ============================================================================ |
| |
| /** The main class for pivot table export. |
| |
| This class contains all pivot caches and pivot tables in a Calc document. |
| It creates the pivot cache streams and pivot table records in the main |
| workbook stream. It supports sharing of pivot caches between multiple pivot |
| tables to decrease file size. |
| */ |
| class XclExpPivotTableManager : protected XclExpRoot |
| { |
| public: |
| explicit XclExpPivotTableManager( const XclExpRoot& rRoot ); |
| |
| /** Creates all pivot tables and caches from the Calc DataPilot objects. */ |
| void CreatePivotTables(); |
| |
| /** Creates a record wrapper for exporting all pivot caches. */ |
| XclExpRecordRef CreatePivotCachesRecord(); |
| /** Creates a record wrapper for exporting all pivot tables of the specified sheet. */ |
| XclExpRecordRef CreatePivotTablesRecord( SCTAB nScTab ); |
| |
| /** Writes all pivot caches (all Workbook records and cache streams). */ |
| void WritePivotCaches( XclExpStream& rStrm ); |
| void WritePivotCachesXml( XclExpXmlStream& rStrm ); |
| /** Writes all pivot tables of the specified Calc sheet. */ |
| void WritePivotTables( XclExpStream& rStrm, SCTAB nScTab ); |
| void WritePivotTablesXml( XclExpXmlStream& rStrm, SCTAB nScTab ); |
| |
| private: |
| /** Finds an existing (if enabled in mbShareCaches) or creates a new pivot cache. |
| @return Pointer to the pivot cache or 0, if the passed source range was invalid. */ |
| const XclExpPivotCache* CreatePivotCache( const ScDPObject& rDPObj ); |
| |
| private: |
| typedef XclExpRecordList< XclExpPivotCache > XclExpPivotCacheList; |
| typedef XclExpPivotCacheList::RecordRefType XclExpPivotCacheRef; |
| typedef XclExpRecordList< XclExpPivotTable > XclExpPivotTableList; |
| typedef XclExpPivotTableList::RecordRefType XclExpPivotTableRef; |
| |
| XclExpPivotCacheList maPCacheList; /// List of all pivot caches. |
| XclExpPivotTableList maPTableList; /// List of all pivot tables. |
| bool mbShareCaches; /// true = Tries to share caches between tables. |
| }; |
| |
| // ============================================================================ |
| |
| #endif |
| |