summaryrefslogtreecommitdiff
path: root/sc/source/filter/inc/xepivot.hxx
blob: bf12728bf135fcb1cc7bc72399d93997df7eef33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */

#ifndef INCLUDED_SC_SOURCE_FILTER_INC_XEPIVOT_HXX
#define INCLUDED_SC_SOURCE_FILTER_INC_XEPIVOT_HXX

#include <map>
#include "xerecord.hxx"
#include "xlpivot.hxx"
#include "xeroot.hxx"

class ScDPObject;
class ScDPSaveData;
class ScDPSaveDimension;
class ScDPSaveMember;
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 OUString& 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 OUString& rText ) const;
    bool                EqualsDouble( double fValue ) const;
    bool                EqualsDateTime( const DateTime& rDateTime ) const;
    bool                EqualsBool( bool bValue ) const;

private:
    virtual void        WriteBody( XclExpStream& rStrm ) SAL_OVERRIDE;

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 OUString& 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 OUString& 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 ) SAL_OVERRIDE;

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 OUString& 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 ) SAL_OVERRIDE;

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;
    /** 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 );

    /** 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;
    /** DCONNAME record contains range name source. */
    void                WriteDConName( 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.
    OUString       maTabName;          /// Name of source data sheet.
    OUString       maSrcRangeName;     /// Range name for source data.
    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. */
    OUString       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 ) SAL_OVERRIDE;

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. */
    OUString       GetFieldName() const;
    /** Returns the pivot table field list index of this field.
      * The field index is always equal to cache index.
      */
    sal_uInt16          GetFieldIndex() const { return maFieldInfo.mnCacheIdx; }

    /** Returns the index of the last inserted data info struct. */
    sal_uInt16          GetLastDataInfoIndex() 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 OUString& 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 ) SAL_OVERRIDE;

private:
    /** Returns an item by its name. */
    XclExpPTItem*       GetItemAcc( const OUString& 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, size_t nId );

    /** 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 OUString& 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 OUString& rName, sal_uInt16 nDefaultIdx ) const;

    /** Writes the entire pivot table. */
    virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;

private:
    /** Returns a pivot table field by its name. */
    XclExpPTField*      GetFieldAcc( const OUString& 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.
    size_t              mnId;               /// Stream ID
};

/** 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 );
    /** Writes all pivot tables of the specified Calc sheet. */
    void                WritePivotTables( XclExpStream& 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

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */