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