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