1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "pivottablebuffer.hxx"
23 #include <com/sun/star/container/XIndexAccess.hpp>
24 #include <com/sun/star/container/XNameAccess.hpp>
25 #include <com/sun/star/sheet/CellFlags.hpp>
26 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
27 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
28 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
29 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
30 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
31 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
32 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
33 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
34 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
35 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
36 #include <com/sun/star/sheet/GeneralFunction.hpp>
37 #include <com/sun/star/sheet/XDataPilotDataLayoutFieldSupplier.hpp>
38 #include <com/sun/star/sheet/XDataPilotField.hpp>
39 #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
40 #include <com/sun/star/sheet/XSheetOperation.hpp>
41 #include <oox/helper/attributelist.hxx>
42 #include <oox/helper/containerhelper.hxx>
43 #include <oox/helper/propertyset.hxx>
44 #include <oox/token/properties.hxx>
45 #include "addressconverter.hxx"
46 #include "biffinputstream.hxx"
48 #include "dapiuno.hxx"
49 #include "dpobject.hxx"
55 using namespace ::com::sun::star::container
;
56 using namespace ::com::sun::star::sheet
;
57 using namespace ::com::sun::star::table
;
58 using namespace ::com::sun::star::uno
;
59 using namespace com::sun::star
;
63 const sal_Int32 OOX_PT_DATALAYOUTFIELD
= -2; /// Placeholder index of data layout field.
65 const sal_Int32 OOX_PT_PREVIOUS_ITEM
= 0x001000FC; /// Calculation of data item result is based on previous item.
66 const sal_Int32 OOX_PT_NEXT_ITEM
= 0x001000FD; /// Calculation of data item result is based on next item.
68 const sal_uInt32 BIFF12_PTFIELD_DATAFIELD
= 0x00000008;
69 const sal_uInt32 BIFF12_PTFIELD_DEFAULT
= 0x00000100;
70 const sal_uInt32 BIFF12_PTFIELD_SUM
= 0x00000200;
71 const sal_uInt32 BIFF12_PTFIELD_COUNTA
= 0x00000400;
72 const sal_uInt32 BIFF12_PTFIELD_AVERAGE
= 0x00000800;
73 const sal_uInt32 BIFF12_PTFIELD_MAX
= 0x00001000;
74 const sal_uInt32 BIFF12_PTFIELD_MIN
= 0x00002000;
75 const sal_uInt32 BIFF12_PTFIELD_PRODUCT
= 0x00004000;
76 const sal_uInt32 BIFF12_PTFIELD_COUNT
= 0x00008000;
77 const sal_uInt32 BIFF12_PTFIELD_STDDEV
= 0x00010000;
78 const sal_uInt32 BIFF12_PTFIELD_STDDEVP
= 0x00020000;
79 const sal_uInt32 BIFF12_PTFIELD_VAR
= 0x00040000;
80 const sal_uInt32 BIFF12_PTFIELD_VARP
= 0x00080000;
82 const sal_uInt32 BIFF12_PTFIELD_SHOWALL
= 0x00000020;
83 const sal_uInt32 BIFF12_PTFIELD_OUTLINE
= 0x00000040;
84 const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW
= 0x00000080;
85 const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP
= 0x00000100;
86 const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK
= 0x00000800;
87 const sal_uInt32 BIFF12_PTFIELD_AUTOSORT
= 0x00001000;
88 const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING
= 0x00002000;
89 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW
= 0x00004000;
90 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP
= 0x00008000;
91 const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS
= 0x00080000;
93 const sal_uInt16 BIFF12_PTFITEM_HIDDEN
= 0x0001;
94 const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS
= 0x0002;
96 const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME
= 0x01;
97 const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS
= 0x001000FE;
99 const sal_uInt16 BIFF12_PTFILTER_HASNAME
= 0x0001;
100 const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION
= 0x0002;
101 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1
= 0x0004;
102 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2
= 0x0008;
104 const sal_uInt8 BIFF12_TOP10FILTER_TOP
= 0x01;
105 const sal_uInt8 BIFF12_TOP10FILTER_PERCENT
= 0x02;
107 const sal_uInt32 BIFF12_PTDEF_SHOWITEMS
= 0x00000100;
108 const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST
= 0x00000400;
109 const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS
= 0x00001000;
110 const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS
= 0x00002000;
111 const sal_uInt32 BIFF12_PTDEF_HIDEDRILL
= 0x00100000;
112 const sal_uInt32 BIFF12_PTDEF_PRINTDRILL
= 0x00200000;
113 const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS
= 0x80000000;
115 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW
= 0x00000004;
116 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL
= 0x00000008;
117 const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL
= 0x00000020;
118 const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING
= 0x00000080;
119 const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT
= 0x00000100;
120 const sal_uInt32 BIFF12_PTDEF_SHOWERROR
= 0x00000200;
121 const sal_uInt32 BIFF12_PTDEF_SHOWMISSING
= 0x00000400;
122 const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN
= 0x00000800;
123 const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS
= 0x00001000;
124 const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS
= 0x00002000;
125 const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS
= 0x00004000;
126 const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES
= 0x00008000;
127 const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES
= 0x00020000;
128 const sal_uInt32 BIFF12_PTDEF_MERGEITEM
= 0x00040000;
129 const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION
= 0x00080000;
130 const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION
= 0x00100000;
131 const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE
= 0x00200000;
132 const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE
= 0x00400000;
133 const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE
= 0x00800000;
134 const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT
= 0x01000000;
135 const sal_uInt32 BIFF12_PTDEF_APPLYFONT
= 0x02000000;
136 const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT
= 0x04000000;
137 const sal_uInt32 BIFF12_PTDEF_APPLYBORDER
= 0x08000000;
138 const sal_uInt32 BIFF12_PTDEF_APPLYFILL
= 0x10000000;
139 const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION
= 0x20000000;
140 const sal_uInt32 BIFF12_PTDEF_HASTAG
= 0x40000000;
142 const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION
= 0x00000040;
143 const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION
= 0x00000080;
144 const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION
= 0x00000400;
145 const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION
= 0x00000800;
146 const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC
= 0x00001000;
147 const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT
= 0x00004000;
149 const sal_uInt8 BIFF12_PTDEF_ROWAXIS
= 1;
150 const sal_uInt8 BIFF12_PTDEF_COLAXIS
= 2;
154 PTFieldItemModel::PTFieldItemModel() :
157 mbShowDetails( true ),
162 void PTFieldItemModel::setBiffType( sal_uInt16 nType
)
164 static const sal_Int32 spnTypes
[] = { XML_data
, XML_default
,
165 XML_sum
, XML_countA
, XML_avg
, XML_max
, XML_min
, XML_product
, XML_count
,
166 XML_stdDev
, XML_stdDevP
, XML_var
, XML_varP
, XML_grand
, XML_blank
};
167 mnType
= STATIC_ARRAY_SELECT( spnTypes
, nType
, XML_data
);
170 PTFieldModel::PTFieldModel() :
171 mnAxis( XML_TOKEN_INVALID
),
173 mnAutoShowItems( 10 ),
174 mnAutoShowRankBy( -1 ),
175 mnSortType( XML_manual
),
176 mnSortRefField( -1 ),
178 mbDataField( false ),
179 mbDefaultSubtotal( true ),
180 mbSumSubtotal( false ),
181 mbCountASubtotal( false ),
182 mbAverageSubtotal( false ),
183 mbMaxSubtotal( false ),
184 mbMinSubtotal( false ),
185 mbProductSubtotal( false ),
186 mbCountSubtotal( false ),
187 mbStdDevSubtotal( false ),
188 mbStdDevPSubtotal( false ),
189 mbVarSubtotal( false ),
190 mbVarPSubtotal( false ),
193 mbSubtotalTop( true ),
194 mbInsertBlankRow( false ),
195 mbInsertPageBreak( false ),
197 mbTopAutoShow( true ),
198 mbMultiPageItems( false )
202 void PTFieldModel::setBiffAxis( sal_uInt8 nAxis
)
204 /* Weird. The axis field is organized as bit field, but only one of the
205 row/col/page flags are allowed at the same time and refer to the values
206 'axisRow', 'axisCol', and 'axisPage' of the XML attribute
207 'pivotField@axis'. Additionally, the fourth bit determines if the field
208 is a data field, which may appear combined with the row/col/page flags.
209 Therefore, this bit is unrelated to the 'axisValues' value of the
210 'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
211 boolean attribute. */
212 static const sal_Int32 spnAxisIds
[] = { XML_TOKEN_INVALID
, XML_axisRow
, XML_axisCol
, XML_TOKEN_INVALID
, XML_axisPage
};
213 mnAxis
= STATIC_ARRAY_SELECT( spnAxisIds
, nAxis
, XML_TOKEN_INVALID
);
216 PTPageFieldModel::PTPageFieldModel() :
218 mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS
)
222 PTDataFieldModel::PTDataFieldModel() :
224 mnSubtotal( XML_sum
),
225 mnShowDataAs( XML_normal
),
232 void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal
)
234 static const sal_Int32 spnSubtotals
[] = { XML_sum
, XML_count
, XML_average
, XML_max
, XML_min
, XML_product
, XML_countNums
, XML_stdDev
, XML_stdDevp
, XML_var
, XML_varp
};
235 mnSubtotal
= STATIC_ARRAY_SELECT( spnSubtotals
, nSubtotal
, XML_TOKEN_INVALID
);
238 void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs
)
240 static const sal_Int32 spnShowDataAs
[] = { XML_normal
, XML_difference
, XML_percent
, XML_percentDiff
, XML_runTotal
, XML_percentOfRow
, XML_percentOfCol
, XML_percentOfTotal
, XML_index
};
241 mnShowDataAs
= STATIC_ARRAY_SELECT( spnShowDataAs
, nShowDataAs
, XML_TOKEN_INVALID
);
244 PivotTableField::PivotTableField( PivotTable
& rPivotTable
, sal_Int32 nFieldIndex
) :
245 WorkbookHelper( rPivotTable
),
246 mrPivotTable( rPivotTable
),
247 mnFieldIndex( nFieldIndex
)
251 void PivotTableField::importPivotField( const AttributeList
& rAttribs
)
253 /* The documentation mentions a value 'axisValues' for the attribute
254 'pivotField@axis'. But this value is not used to mark a data field, as
255 data fields may be inserted in one of the row/column/page dimensions at
256 the same time. Therefore, the boolean attribute 'pivotField@dataField'
257 is really used to mark data fields. */
258 maModel
.mnAxis
= rAttribs
.getToken( XML_axis
, XML_TOKEN_INVALID
);
259 maModel
.mnNumFmtId
= rAttribs
.getInteger( XML_numFmtId
, 0 );
260 maModel
.mnAutoShowItems
= rAttribs
.getInteger( XML_itemPageCount
, 10 );
261 maModel
.mnAutoShowRankBy
= rAttribs
.getInteger( XML_rankBy
, -1 );
262 maModel
.mnSortType
= rAttribs
.getToken( XML_sortType
, XML_manual
);
263 maModel
.mbDataField
= rAttribs
.getBool( XML_dataField
, false );
264 maModel
.mbDefaultSubtotal
= rAttribs
.getBool( XML_defaultSubtotal
, true );
265 maModel
.mbSumSubtotal
= rAttribs
.getBool( XML_sumSubtotal
, false );
266 maModel
.mbCountASubtotal
= rAttribs
.getBool( XML_countASubtotal
, false );
267 maModel
.mbAverageSubtotal
= rAttribs
.getBool( XML_avgSubtotal
, false );
268 maModel
.mbMaxSubtotal
= rAttribs
.getBool( XML_maxSubtotal
, false );
269 maModel
.mbMinSubtotal
= rAttribs
.getBool( XML_minSubtotal
, false );
270 maModel
.mbProductSubtotal
= rAttribs
.getBool( XML_productSubtotal
, false );
271 maModel
.mbCountSubtotal
= rAttribs
.getBool( XML_countSubtotal
, false );
272 maModel
.mbStdDevSubtotal
= rAttribs
.getBool( XML_stdDevSubtotal
, false );
273 maModel
.mbStdDevPSubtotal
= rAttribs
.getBool( XML_stdDevPSubtotal
, false );
274 maModel
.mbVarSubtotal
= rAttribs
.getBool( XML_varSubtotal
, false );
275 maModel
.mbVarPSubtotal
= rAttribs
.getBool( XML_varPSubtotal
, false );
276 maModel
.mbShowAll
= rAttribs
.getBool( XML_showAll
, true );
277 maModel
.mbOutline
= rAttribs
.getBool( XML_outline
, true );
278 maModel
.mbSubtotalTop
= rAttribs
.getBool( XML_subtotalTop
, true );
279 maModel
.mbInsertBlankRow
= rAttribs
.getBool( XML_insertBlankRow
, false );
280 maModel
.mbInsertPageBreak
= rAttribs
.getBool( XML_insertPageBreak
, false );
281 maModel
.mbAutoShow
= rAttribs
.getBool( XML_autoShow
, false );
282 maModel
.mbTopAutoShow
= rAttribs
.getBool( XML_topAutoShow
, true );
283 maModel
.mbMultiPageItems
= rAttribs
.getBool( XML_multipleItemSelectionAllowed
, false );
286 void PivotTableField::importItem( const AttributeList
& rAttribs
)
288 PTFieldItemModel aModel
;
289 aModel
.mnCacheItem
= rAttribs
.getInteger( XML_x
, -1 );
290 aModel
.mnType
= rAttribs
.getToken( XML_t
, XML_data
);
291 aModel
.mbShowDetails
= rAttribs
.getBool( XML_sd
, true );
292 aModel
.mbHidden
= rAttribs
.getBool( XML_h
, false );
293 aModel
.msCaption
= rAttribs
.getXString( XML_n
, OUString() );
294 maItems
.push_back( aModel
);
297 void PivotTableField::importReference( const AttributeList
& rAttribs
)
299 // field index is stored as unsigned integer
300 maModel
.mnSortRefField
= static_cast< sal_Int32
>( rAttribs
.getUnsigned( XML_field
, SAL_MAX_UINT32
) );
303 void PivotTableField::importReferenceItem( const AttributeList
& rAttribs
)
305 maModel
.mnSortRefItem
= rAttribs
.getInteger( XML_v
, -1 );
308 void PivotTableField::importPTField( SequenceInputStream
& rStrm
)
310 sal_uInt32 nFlags1
, nFlags2
;
311 nFlags1
= rStrm
.readuInt32();
312 maModel
.mnNumFmtId
= rStrm
.readInt32();
313 nFlags2
= rStrm
.readuInt32();
314 maModel
.mnAutoShowItems
= rStrm
.readInt32();
315 maModel
.mnAutoShowRankBy
= rStrm
.readInt32();
317 maModel
.setBiffAxis( extractValue
< sal_uInt8
>( nFlags1
, 0, 3 ) );
318 maModel
.mbDataField
= getFlag( nFlags1
, BIFF12_PTFIELD_DATAFIELD
);
319 maModel
.mbDefaultSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_DEFAULT
);
320 maModel
.mbSumSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_SUM
);
321 maModel
.mbCountASubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_COUNTA
);
322 maModel
.mbAverageSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_AVERAGE
);
323 maModel
.mbMaxSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_MAX
);
324 maModel
.mbMinSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_MIN
);
325 maModel
.mbProductSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_PRODUCT
);
326 maModel
.mbCountSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_COUNT
);
327 maModel
.mbStdDevSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_STDDEV
);
328 maModel
.mbStdDevPSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_STDDEVP
);
329 maModel
.mbVarSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_VAR
);
330 maModel
.mbVarPSubtotal
= getFlag( nFlags1
, BIFF12_PTFIELD_VARP
);
332 maModel
.mbShowAll
= getFlag( nFlags2
, BIFF12_PTFIELD_SHOWALL
);
333 maModel
.mbOutline
= getFlag( nFlags2
, BIFF12_PTFIELD_OUTLINE
);
334 maModel
.mbSubtotalTop
= getFlag( nFlags2
, BIFF12_PTFIELD_SUBTOTALTOP
);
335 maModel
.mbInsertBlankRow
= getFlag( nFlags2
, BIFF12_PTFIELD_INSERTBLANKROW
);
336 maModel
.mbInsertPageBreak
= getFlag( nFlags2
, BIFF12_PTFIELD_INSERTPAGEBREAK
);
337 maModel
.mbAutoShow
= getFlag( nFlags2
, BIFF12_PTFIELD_AUTOSHOW
);
338 maModel
.mbTopAutoShow
= getFlag( nFlags2
, BIFF12_PTFIELD_AUTOSHOWTOP
);
339 maModel
.mbMultiPageItems
= getFlag( nFlags2
, BIFF12_PTFIELD_MULTIPAGEITEMS
);
341 bool bAutoSort
= getFlag( nFlags2
, BIFF12_PTFIELD_AUTOSORT
);
342 bool bAscending
= getFlag( nFlags2
, BIFF12_PTFIELD_SORTASCENDING
);
343 maModel
.mnSortType
= bAutoSort
? (bAscending
? XML_ascending
: XML_descending
) : XML_manual
;
346 void PivotTableField::importPTFItem( SequenceInputStream
& rStrm
)
348 PTFieldItemModel aModel
;
351 nType
= rStrm
.readuChar();
352 nFlags
= rStrm
.readuInt16();
353 aModel
.mnCacheItem
= rStrm
.readInt32();
355 aModel
.setBiffType( nType
);
356 aModel
.mbShowDetails
= !getFlag( nFlags
, BIFF12_PTFITEM_HIDEDETAILS
);
357 aModel
.mbHidden
= getFlag( nFlags
, BIFF12_PTFITEM_HIDDEN
);
359 maItems
.push_back( aModel
);
362 void PivotTableField::importPTReference( SequenceInputStream
& rStrm
)
364 maModel
.mnSortRefField
= rStrm
.readInt32();
367 void PivotTableField::importPTReferenceItem( SequenceInputStream
& rStrm
)
369 maModel
.mnSortRefItem
= rStrm
.readInt32();
372 void PivotTableField::finalizeImport( const Reference
< XDataPilotDescriptor
>& rxDPDesc
)
374 /* Process all fields based on source data, other fields (e.g. group
375 fields) are processed from here. PivotCacahe::getDatabaseIndex()
376 returns -1 for all fields not based on source data. */
377 Reference
< XDataPilotField
> xDPField
;
378 sal_Int32 nDatabaseIdx
= mrPivotTable
.getCacheDatabaseIndex( mnFieldIndex
);
379 if( (nDatabaseIdx
>= 0) && rxDPDesc
.is() ) try
381 // try to get the source field and its name from passed DataPilot descriptor
382 Reference
< XIndexAccess
> xDPFieldsIA( rxDPDesc
->getDataPilotFields(), UNO_SET_THROW
);
383 xDPField
.set( xDPFieldsIA
->getByIndex( nDatabaseIdx
), UNO_QUERY_THROW
);
384 Reference
< XNamed
> xDPFieldName( xDPField
, UNO_QUERY_THROW
);
385 maDPFieldName
= xDPFieldName
->getName();
386 OSL_ENSURE( !maDPFieldName
.isEmpty(), "PivotTableField::finalizeImport - no field name in source data found" );
388 // try to convert grouping settings
389 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
391 // numeric grouping is done inplace, no nested group fields will appear
392 if( pCacheField
->hasNumericGrouping() )
394 pCacheField
->convertNumericGrouping( xDPField
);
396 else if( pCacheField
->hasDateGrouping() )
398 // first date group settings are inplace
399 pCacheField
->createDateGroupField( xDPField
);
400 // create all nested group fields (if any)
401 mrPivotTable
.finalizeDateGroupingImport( xDPField
, mnFieldIndex
);
403 else if( pCacheField
->hasParentGrouping() )
406 // create a list of all item names, needed to map between original and group items
407 ::std::vector
< OUString
> aItems
;
408 pCacheField
->getCacheItemNames( aItems
);
409 PivotCacheGroupItemVector aItemNames
;
410 for( ::std::vector
< OUString
>::iterator aIt
= aItems
.begin(), aEnd
= aItems
.end(); aIt
!= aEnd
; ++aIt
)
411 aItemNames
.push_back( PivotCacheGroupItem( *aIt
) );
412 // create all nested group fields (if any)
413 mrPivotTable
.finalizeParentGroupingImport( xDPField
, *pCacheField
, aItemNames
);
422 void PivotTableField::finalizeDateGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
, sal_Int32 nBaseFieldIdx
)
424 if( maDPFieldName
.isEmpty() ) // prevent endless loops if file format is broken
426 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
428 if( !pCacheField
->isDatabaseField() && pCacheField
->hasDateGrouping() && (pCacheField
->getGroupBaseField() == nBaseFieldIdx
) )
430 maDPFieldName
= pCacheField
->createDateGroupField( rxBaseDPField
);
431 OSL_ENSURE( !maDPFieldName
.isEmpty(), "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
437 void PivotTableField::finalizeParentGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
, const PivotCacheField
& rBaseCacheField
, PivotCacheGroupItemVector
& orItemNames
)
439 if( maDPFieldName
.isEmpty() ) // prevent endless loops if file format is broken
441 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
443 // data field can have user defined groupname captions, apply them
445 IdCaptionPairList captionList
;
446 for( ItemModelVector::iterator aIt
= maItems
.begin(), aEnd
= maItems
.end(); aIt
!= aEnd
; ++aIt
)
448 if ( aIt
->mnType
== XML_data
&& aIt
->msCaption
.getLength() )
449 captionList
.push_back( IdCaptionPair( aIt
->mnCacheItem
, aIt
->msCaption
) );
451 // #FIXME find another way out of this const nightmare prison
452 if ( !captionList
.empty() )
453 const_cast<PivotCacheField
*>( pCacheField
)->applyItemCaptions( captionList
);
454 maDPFieldName
= pCacheField
->createParentGroupField( rxBaseDPField
, rBaseCacheField
, orItemNames
);
455 // on success, try to create nested group fields
456 Reference
< XDataPilotField
> xDPField
= mrPivotTable
.getDataPilotField( maDPFieldName
);
458 mrPivotTable
.finalizeParentGroupingImport( xDPField
, *pCacheField
, orItemNames
);
463 void PivotTableField::convertRowField()
465 convertRowColPageField( XML_axisRow
);
468 void PivotTableField::convertColField()
470 convertRowColPageField( XML_axisCol
);
473 void PivotTableField::convertHiddenField()
475 convertRowColPageField( XML_TOKEN_INVALID
);
478 void PivotTableField::convertPageField( const PTPageFieldModel
& rPageField
)
480 OSL_ENSURE( rPageField
.mnField
== mnFieldIndex
, "PivotTableField::convertPageField - wrong field index" );
481 // convert all settings common for row/column/page fields
482 Reference
< XDataPilotField
> xDPField
= convertRowColPageField( XML_axisPage
);
486 PropertySet
aPropSet( xDPField
);
487 using namespace ::com::sun::star::sheet
;
489 // find cache item used as 'selected page'
490 sal_Int32 nCacheItem
= -1;
491 if( maModel
.mbMultiPageItems
)
493 // multiple items may be selected
494 OSL_ENSURE( rPageField
.mnItem
== BIFF12_PTPAGEFIELD_MULTIITEMS
, "PivotTableField::convertPageField - unexpected cache item index" );
495 // try to find a single visible item
496 bool bHasMultiItems
= false;
497 for( ItemModelVector::iterator aIt
= maItems
.begin(), aEnd
= maItems
.end(); (aIt
!= aEnd
) && !bHasMultiItems
; ++aIt
)
499 if( (aIt
->mnType
== XML_data
) && !aIt
->mbHidden
)
501 bHasMultiItems
= nCacheItem
>= 0;
502 nCacheItem
= bHasMultiItems
? -1 : aIt
->mnCacheItem
;
508 // single item may be selected
509 if( (0 <= rPageField
.mnItem
) && (rPageField
.mnItem
< static_cast< sal_Int32
>( maItems
.size() )) )
510 nCacheItem
= maItems
[ rPageField
.mnItem
].mnCacheItem
;
513 if( nCacheItem
>= 0 )
515 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
517 if( const PivotCacheItem
* pSharedItem
= pCacheField
->getCacheItem( nCacheItem
) )
519 OUString aSelectedPage
= pSharedItem
->getName();
520 aPropSet
.setProperty( PROP_SelectedPage
, aSelectedPage
);
527 void PivotTableField::convertDataField( const PTDataFieldModel
& rDataField
)
529 OSL_ENSURE( rDataField
.mnField
== mnFieldIndex
, "PivotTableField::convertDataField - wrong field index" );
530 OSL_ENSURE( maModel
.mbDataField
, "PivotTableField::convertDataField - not a data field" );
531 Reference
< XDataPilotField
> xDPField
= mrPivotTable
.getDataPilotField( maDPFieldName
);
534 PropertySet
aPropSet( xDPField
);
535 using namespace ::com::sun::star::sheet
;
538 aPropSet
.setProperty( PROP_Orientation
, DataPilotFieldOrientation_DATA
);
540 /* Field aggregation function. Documentation is a little bit confused
541 about which names to use for the count functions. The name 'count'
542 means 'count all', and 'countNum' means 'count numbers'. On the
543 other hand, for subtotals, 'countA' means 'count all', and 'count'
544 means 'count numbers' (see above). */
545 GeneralFunction eAggFunc
= GeneralFunction_SUM
;
546 switch( rDataField
.mnSubtotal
)
548 case XML_sum
: eAggFunc
= GeneralFunction_SUM
; break;
549 case XML_count
: eAggFunc
= GeneralFunction_COUNT
; break;
550 case XML_average
: eAggFunc
= GeneralFunction_AVERAGE
; break;
551 case XML_max
: eAggFunc
= GeneralFunction_MAX
; break;
552 case XML_min
: eAggFunc
= GeneralFunction_MIN
; break;
553 case XML_product
: eAggFunc
= GeneralFunction_PRODUCT
; break;
554 case XML_countNums
: eAggFunc
= GeneralFunction_COUNTNUMS
; break;
555 case XML_stdDev
: eAggFunc
= GeneralFunction_STDEV
; break;
556 case XML_stdDevp
: eAggFunc
= GeneralFunction_STDEVP
; break;
557 case XML_var
: eAggFunc
= GeneralFunction_VAR
; break;
558 case XML_varp
: eAggFunc
= GeneralFunction_VARP
; break;
559 default: OSL_FAIL( "PivotTableField::convertDataField - unknown aggregation function" );
561 aPropSet
.setProperty( PROP_Function
, eAggFunc
);
563 // field reference ('show data as')
564 DataPilotFieldReference aReference
;
565 aReference
.ReferenceType
= DataPilotFieldReferenceType::NONE
;
566 switch( rDataField
.mnShowDataAs
)
568 case XML_difference
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ITEM_DIFFERENCE
; break;
569 case XML_percent
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ITEM_PERCENTAGE
; break;
570 case XML_percentDiff
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE
; break;
571 case XML_runTotal
: aReference
.ReferenceType
= DataPilotFieldReferenceType::RUNNING_TOTAL
; break;
572 case XML_percentOfRow
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ROW_PERCENTAGE
; break;
573 case XML_percentOfCol
: aReference
.ReferenceType
= DataPilotFieldReferenceType::COLUMN_PERCENTAGE
; break;
574 case XML_percentOfTotal
: aReference
.ReferenceType
= DataPilotFieldReferenceType::TOTAL_PERCENTAGE
; break;
575 case XML_index
: aReference
.ReferenceType
= DataPilotFieldReferenceType::INDEX
; break;
577 if( aReference
.ReferenceType
!= DataPilotFieldReferenceType::NONE
)
579 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( rDataField
.mnBaseField
) )
581 aReference
.ReferenceField
= pCacheField
->getName();
582 switch( rDataField
.mnBaseItem
)
584 case OOX_PT_PREVIOUS_ITEM
:
585 aReference
.ReferenceItemType
= DataPilotFieldReferenceItemType::PREVIOUS
;
587 case OOX_PT_NEXT_ITEM
:
588 aReference
.ReferenceItemType
= DataPilotFieldReferenceItemType::NEXT
;
591 aReference
.ReferenceItemType
= DataPilotFieldReferenceItemType::NAMED
;
592 if( const PivotCacheItem
* pCacheItem
= pCacheField
->getCacheItem( rDataField
.mnBaseItem
) )
593 aReference
.ReferenceItemName
= pCacheItem
->getName();
595 aPropSet
.setProperty( PROP_Reference
, aReference
);
601 // private --------------------------------------------------------------------
603 Reference
< XDataPilotField
> PivotTableField::convertRowColPageField( sal_Int32 nAxis
)
605 bool bDataLayout
= mnFieldIndex
== OOX_PT_DATALAYOUTFIELD
;
606 Reference
< XDataPilotField
> xDPField
= bDataLayout
? mrPivotTable
.getDataLayoutField() : mrPivotTable
.getDataPilotField( maDPFieldName
);
607 OSL_ENSURE( bDataLayout
|| (nAxis
== maModel
.mnAxis
), "PivotTableField::convertRowColPageField - field axis mismatch" );
611 // TODO: Use this to set properties directly, bypassing the slow uno layer.
612 ScDPObject
* pDPObj
= mrPivotTable
.getDPObject();
614 PropertySet
aPropSet( xDPField
);
615 using namespace ::com::sun::star::sheet
;
618 DataPilotFieldOrientation eFieldOrient
= DataPilotFieldOrientation_HIDDEN
;
621 case XML_axisRow
: eFieldOrient
= DataPilotFieldOrientation_ROW
; break;
622 case XML_axisCol
: eFieldOrient
= DataPilotFieldOrientation_COLUMN
; break;
623 case XML_axisPage
: eFieldOrient
= DataPilotFieldOrientation_PAGE
; break;
625 if( eFieldOrient
!= DataPilotFieldOrientation_HIDDEN
)
626 aPropSet
.setProperty( PROP_Orientation
, eFieldOrient
);
628 // all other settings not for the data layout field
631 /* Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
632 explicit functions are set. This is different behaviour between
633 XML (where 'defaultSubtotal' is set regardless of other
634 functions) and binary formats (where 'defaultSubtotal' is not
635 set if other functions are set). */
636 ::std::vector
< GeneralFunction
> aSubtotals
;
637 /* Order of subtotals is fixed in Excel. Documentation is a little
638 bit confused about which names to use for the count functions.
639 For subtotals, 'countA' means 'count all', and 'count' means
640 'count numbers'. On the other hand, for the data field
641 aggregation function, 'count' means 'count all', and 'countNum'
642 means 'count numbers' (see below). */
643 if( maModel
.mbSumSubtotal
) aSubtotals
.push_back( GeneralFunction_SUM
);
644 if( maModel
.mbCountASubtotal
) aSubtotals
.push_back( GeneralFunction_COUNT
);
645 if( maModel
.mbAverageSubtotal
) aSubtotals
.push_back( GeneralFunction_AVERAGE
);
646 if( maModel
.mbMaxSubtotal
) aSubtotals
.push_back( GeneralFunction_MAX
);
647 if( maModel
.mbMinSubtotal
) aSubtotals
.push_back( GeneralFunction_MIN
);
648 if( maModel
.mbProductSubtotal
) aSubtotals
.push_back( GeneralFunction_PRODUCT
);
649 if( maModel
.mbCountSubtotal
) aSubtotals
.push_back( GeneralFunction_COUNTNUMS
);
650 if( maModel
.mbStdDevSubtotal
) aSubtotals
.push_back( GeneralFunction_STDEV
);
651 if( maModel
.mbStdDevPSubtotal
) aSubtotals
.push_back( GeneralFunction_STDEVP
);
652 if( maModel
.mbVarSubtotal
) aSubtotals
.push_back( GeneralFunction_VAR
);
653 if( maModel
.mbVarPSubtotal
) aSubtotals
.push_back( GeneralFunction_VARP
);
654 // if no function is set manually, check the 'defaultSubtotal' flag
655 if( aSubtotals
.empty() && maModel
.mbDefaultSubtotal
)
656 aSubtotals
.push_back( GeneralFunction_AUTO
);
657 aPropSet
.setProperty( PROP_Subtotals
, ContainerHelper::vectorToSequence( aSubtotals
) );
660 DataPilotFieldLayoutInfo aLayoutInfo
;
661 aLayoutInfo
.LayoutMode
= maModel
.mbOutline
?
662 (maModel
.mbSubtotalTop
? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP
: DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM
) :
663 DataPilotFieldLayoutMode::TABULAR_LAYOUT
;
664 aLayoutInfo
.AddEmptyLines
= maModel
.mbInsertBlankRow
;
665 aPropSet
.setProperty( PROP_LayoutInfo
, aLayoutInfo
);
666 aPropSet
.setProperty( PROP_ShowEmpty
, maModel
.mbShowAll
);
668 // auto show (OOXML/BIFF12 only)
669 if( maModel
.mbAutoShow
)
671 DataPilotFieldAutoShowInfo aAutoShowInfo
;
672 aAutoShowInfo
.IsEnabled
= sal_True
;
673 aAutoShowInfo
.ShowItemsMode
= maModel
.mbTopAutoShow
? DataPilotFieldShowItemsMode::FROM_TOP
: DataPilotFieldShowItemsMode::FROM_BOTTOM
;
674 aAutoShowInfo
.ItemCount
= maModel
.mnAutoShowItems
;
675 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheFieldOfDataField( maModel
.mnAutoShowRankBy
) )
676 aAutoShowInfo
.DataField
= pCacheField
->getName();
677 aPropSet
.setProperty( PROP_AutoShowInfo
, aAutoShowInfo
);
681 DataPilotFieldSortInfo aSortInfo
;
682 aSortInfo
.IsAscending
= maModel
.mnSortType
== XML_ascending
;
683 if( (maModel
.mnSortType
!= XML_ascending
) && (maModel
.mnSortType
!= XML_descending
) )
685 aSortInfo
.Mode
= DataPilotFieldSortMode::MANUAL
;
689 const PivotCacheField
* pCacheField
= (maModel
.mnSortRefField
== OOX_PT_DATALAYOUTFIELD
) ?
690 mrPivotTable
.getCacheFieldOfDataField( maModel
.mnSortRefItem
) : 0;
693 aSortInfo
.Mode
= DataPilotFieldSortMode::DATA
;
694 aSortInfo
.Field
= pCacheField
->getName();
698 aSortInfo
.Mode
= DataPilotFieldSortMode::NAME
;
701 aPropSet
.setProperty( PROP_SortInfo
, aSortInfo
);
704 if (const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField(mnFieldIndex
))
706 ScDPSaveData
* pSaveData
= pDPObj
->GetSaveData();
707 ScDPSaveDimension
* pDim
= pSaveData
->GetDimensionByName(pCacheField
->getName());
711 for( ItemModelVector::iterator aIt
= maItems
.begin(), aEnd
= maItems
.end(); aIt
!= aEnd
; ++aIt
)
713 if (aIt
->mnType
!= XML_data
)
716 const PivotCacheItem
* pSharedItem
= pCacheField
->getCacheItem(aIt
->mnCacheItem
);
722 ScDPSaveMember
* pMem
= pDim
->GetMemberByName(pSharedItem
->getName());
723 pMem
->SetShowDetails(aIt
->mbShowDetails
);
724 pMem
->SetIsVisible(!aIt
->mbHidden
);
728 // catch every failed container access to be able to process following items
732 catch (const Exception
&) {}
739 PTFilterModel::PTFilterModel() :
742 mnMemPropField( -1 ),
743 mnType( XML_TOKEN_INVALID
),
746 mnMeasureField( -1 ),
752 PivotTableFilter::PivotTableFilter( const PivotTable
& rPivotTable
) :
753 WorkbookHelper( rPivotTable
),
754 mrPivotTable( rPivotTable
)
758 void PivotTableFilter::importFilter( const AttributeList
& rAttribs
)
760 maModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
761 maModel
.maDescription
= rAttribs
.getXString( XML_description
, OUString() );
762 maModel
.maStrValue1
= rAttribs
.getXString( XML_stringValue1
, OUString() );
763 maModel
.maStrValue2
= rAttribs
.getXString( XML_stringValue2
, OUString() );
764 maModel
.mnField
= rAttribs
.getInteger( XML_fld
, -1 );
765 maModel
.mnMemPropField
= rAttribs
.getInteger( XML_mpFld
, -1 );
766 maModel
.mnType
= rAttribs
.getToken( XML_type
, XML_TOKEN_INVALID
);
767 maModel
.mnEvalOrder
= rAttribs
.getInteger( XML_evalOrder
, 0 );
768 maModel
.mnId
= rAttribs
.getInteger( XML_id
, -1 );
769 maModel
.mnMeasureField
= rAttribs
.getInteger( XML_iMeasureFld
, -1 );
770 maModel
.mnMeasureHier
= rAttribs
.getInteger( XML_iMeasureHier
, -1 );
773 void PivotTableFilter::importTop10( const AttributeList
& rAttribs
)
775 OSL_ENSURE( rAttribs
.getBool( XML_percent
, false ) == (maModel
.mnType
== XML_percent
),
776 "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
777 maModel
.mfValue
= rAttribs
.getDouble( XML_val
, 0.0 );
778 maModel
.mbTopFilter
= rAttribs
.getBool( XML_top
, true );
781 void PivotTableFilter::importPTFilter( SequenceInputStream
& rStrm
)
785 maModel
.mnField
= rStrm
.readInt32();
786 maModel
.mnMemPropField
= rStrm
.readInt32();
787 nType
= rStrm
.readInt32();
788 rStrm
.skip( 4 ); // unused
789 maModel
.mnId
= rStrm
.readInt32();
790 maModel
.mnMeasureField
= rStrm
.readInt32();
791 maModel
.mnMeasureHier
= rStrm
.readInt32();
792 nFlags
= rStrm
.readuInt16();
793 if( getFlag( nFlags
, BIFF12_PTFILTER_HASNAME
) )
794 rStrm
>> maModel
.maName
;
795 if( getFlag( nFlags
, BIFF12_PTFILTER_HASDESCRIPTION
) )
796 rStrm
>> maModel
.maDescription
;
797 if( getFlag( nFlags
, BIFF12_PTFILTER_HASSTRVALUE1
) )
798 rStrm
>> maModel
.maStrValue1
;
799 if( getFlag( nFlags
, BIFF12_PTFILTER_HASSTRVALUE2
) )
800 rStrm
>> maModel
.maStrValue2
;
802 static const sal_Int32 spnTypes
[] =
805 // data field top10 filter (1-3)
806 XML_count
, XML_percent
, XML_sum
,
807 // caption filter (4-17)
808 XML_captionEqual
, XML_captionNotEqual
,
809 XML_captionBeginsWith
, XML_captionNotBeginsWith
, XML_captionEndsWith
, XML_captionNotEndsWith
,
810 XML_captionContains
, XML_captionNotContains
, XML_captionGreaterThan
, XML_captionGreaterThanOrEqual
,
811 XML_captionLessThan
, XML_captionLessThanOrEqual
, XML_captionBetween
, XML_captionNotBetween
,
812 // value filter (18-25)
813 XML_valueEqual
, XML_valueNotEqual
, XML_valueGreaterThan
, XML_valueGreaterThanOrEqual
,
814 XML_valueLessThan
, XML_valueLessThanOrEqual
, XML_valueBetween
, XML_valueNotBetween
,
815 // date filter (26-65)
816 XML_dateEqual
, XML_dateOlderThan
, XML_dateNewerThan
, XML_dateBetween
,
817 XML_tomorrow
, XML_today
, XML_yesterday
, XML_nextWeek
, XML_thisWeek
, XML_lastWeek
,
818 XML_nextMonth
, XML_thisMonth
, XML_lastMonth
, XML_nextQuarter
, XML_thisQuarter
, XML_lastQuarter
,
819 XML_nextYear
, XML_thisYear
, XML_lastYear
, XML_yearToDate
, XML_Q1
, XML_Q2
, XML_Q3
, XML_Q4
,
820 XML_M1
, XML_M2
, XML_M3
, XML_M4
, XML_M5
, XML_M6
, XML_M7
, XML_M8
, XML_M9
, XML_M10
, XML_M11
, XML_M12
,
821 XML_dateNotEqual
, XML_dateOlderThanOrEqual
, XML_dateNewerThanOrEqual
, XML_dateNotBetween
823 maModel
.mnType
= STATIC_ARRAY_SELECT( spnTypes
, nType
, XML_TOKEN_INVALID
);
826 void PivotTableFilter::importTop10Filter( SequenceInputStream
& rStrm
)
829 nFlags
= rStrm
.readuChar();
830 maModel
.mfValue
= rStrm
.readDouble();
833 getFlag(nFlags
, BIFF12_TOP10FILTER_PERCENT
) != (maModel
.mnType
== XML_percent
),
835 "PivotTableFilter::importTop10 - unexpected value of percent attribute");
836 maModel
.mbTopFilter
= getFlag( nFlags
, BIFF12_TOP10FILTER_TOP
);
839 void PivotTableFilter::finalizeImport()
841 // only simple top10 filter supported
842 if( maModel
.mnType
== XML_count
)
844 PropertySet
aPropSet( mrPivotTable
.getDataPilotField( maModel
.mnField
) );
847 using namespace ::com::sun::star::sheet
;
848 DataPilotFieldAutoShowInfo aAutoShowInfo
;
849 aAutoShowInfo
.IsEnabled
= sal_True
;
850 aAutoShowInfo
.ShowItemsMode
= maModel
.mbTopFilter
? DataPilotFieldShowItemsMode::FROM_TOP
: DataPilotFieldShowItemsMode::FROM_BOTTOM
;
851 aAutoShowInfo
.ItemCount
= getLimitedValue
< sal_Int32
, double >( maModel
.mfValue
, 0, SAL_MAX_INT32
);
852 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheFieldOfDataField( maModel
.mnMeasureField
) )
853 aAutoShowInfo
.DataField
= pCacheField
->getName();
854 aPropSet
.setProperty( PROP_AutoShowInfo
, aAutoShowInfo
);
859 PTDefinitionModel::PTDefinitionModel() :
867 mbDataOnRows( false ),
868 mbShowError( false ),
869 mbShowMissing( true ),
871 mbDisableFieldList( false ),
872 mbShowCalcMembers( true ),
873 mbVisualTotals( true ),
875 mbPrintDrill( false ),
876 mbEnableDrill( true ),
877 mbPreserveFormatting( true ),
878 mbUseAutoFormat( false ),
879 mbPageOverThenDown( false ),
880 mbSubtotalHiddenItems( false ),
881 mbRowGrandTotals( true ),
882 mbColGrandTotals( true ),
883 mbFieldPrintTitles( false ),
884 mbItemPrintTitles( false ),
885 mbMergeItem( false ),
886 mbShowEmptyRow( false ),
887 mbShowEmptyCol( false ),
888 mbShowHeaders( true ),
889 mbFieldListSortAsc( false ),
890 mbCustomListSort( true )
894 PTLocationModel::PTLocationModel() :
895 mnFirstHeaderRow( 0 ),
903 PivotTable::PivotTable( const WorkbookHelper
& rHelper
) :
904 WorkbookHelper( rHelper
),
906 maDataField( *this, OOX_PT_DATALAYOUTFIELD
),
911 void PivotTable::importPivotTableDefinition( const AttributeList
& rAttribs
)
913 maDefModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
914 maDefModel
.maDataCaption
= rAttribs
.getXString( XML_dataCaption
, OUString() );
915 maDefModel
.maGrandTotalCaption
= rAttribs
.getXString( XML_grandTotalCaption
, OUString() );
916 maDefModel
.maRowHeaderCaption
= rAttribs
.getXString( XML_rowHeaderCaption
, OUString() );
917 maDefModel
.maColHeaderCaption
= rAttribs
.getXString( XML_colHeaderCaption
, OUString() );
918 maDefModel
.maErrorCaption
= rAttribs
.getXString( XML_errorCaption
, OUString() );
919 maDefModel
.maMissingCaption
= rAttribs
.getXString( XML_missingCaption
, OUString() );
920 maDefModel
.maPageStyle
= rAttribs
.getXString( XML_pageStyle
, OUString() );
921 maDefModel
.maPivotTableStyle
= rAttribs
.getXString( XML_pivotTableStyle
, OUString() );
922 maDefModel
.maVacatedStyle
= rAttribs
.getXString( XML_vacatedStyle
, OUString() );
923 maDefModel
.maTag
= rAttribs
.getXString( XML_tag
, OUString() );
924 maDefModel
.mnCacheId
= rAttribs
.getInteger( XML_cacheId
, -1 );
925 maDefModel
.mnDataPosition
= rAttribs
.getInteger( XML_dataPosition
, 0 );
926 maDefModel
.mnPageWrap
= rAttribs
.getInteger( XML_pageWrap
, 0 );
927 maDefModel
.mnIndent
= rAttribs
.getInteger( XML_indent
, 1 );
928 maDefModel
.mnChartFormat
= rAttribs
.getInteger( XML_chartFormat
, 0 );
929 maDefModel
.mnAutoFormatId
= rAttribs
.getInteger( XML_autoFormatId
, 0 );
930 maDefModel
.mbDataOnRows
= rAttribs
.getBool( XML_dataOnRows
, false );
931 maDefModel
.mbShowError
= rAttribs
.getBool( XML_showError
, false );
932 maDefModel
.mbShowMissing
= rAttribs
.getBool( XML_showMissing
, true );
933 maDefModel
.mbShowItems
= rAttribs
.getBool( XML_showItems
, true );
934 maDefModel
.mbDisableFieldList
= rAttribs
.getBool( XML_disableFieldList
, false );
935 maDefModel
.mbShowCalcMembers
= rAttribs
.getBool( XML_showCalcMbrs
, true );
936 maDefModel
.mbVisualTotals
= rAttribs
.getBool( XML_visualTotals
, true );
937 maDefModel
.mbShowDrill
= rAttribs
.getBool( XML_showDrill
, true );
938 maDefModel
.mbPrintDrill
= rAttribs
.getBool( XML_printDrill
, false );
939 maDefModel
.mbEnableDrill
= rAttribs
.getBool( XML_enableDrill
, true );
940 maDefModel
.mbPreserveFormatting
= rAttribs
.getBool( XML_preserveFormatting
, true );
941 maDefModel
.mbUseAutoFormat
= rAttribs
.getBool( XML_useAutoFormatting
, false );
942 maDefModel
.mbPageOverThenDown
= rAttribs
.getBool( XML_pageOverThenDown
, false );
943 maDefModel
.mbSubtotalHiddenItems
= rAttribs
.getBool( XML_subtotalHiddenItems
, false );
944 maDefModel
.mbRowGrandTotals
= rAttribs
.getBool( XML_rowGrandTotals
, true );
945 maDefModel
.mbColGrandTotals
= rAttribs
.getBool( XML_colGrandTotals
, true );
946 maDefModel
.mbFieldPrintTitles
= rAttribs
.getBool( XML_fieldPrintTitles
, false );
947 maDefModel
.mbItemPrintTitles
= rAttribs
.getBool( XML_itemPrintTitles
, false );
948 maDefModel
.mbMergeItem
= rAttribs
.getBool( XML_mergeItem
, false );
949 maDefModel
.mbShowEmptyRow
= rAttribs
.getBool( XML_showEmptyRow
, false );
950 maDefModel
.mbShowEmptyCol
= rAttribs
.getBool( XML_showEmptyCol
, false );
951 maDefModel
.mbShowHeaders
= rAttribs
.getBool( XML_showHeaders
, true );
952 maDefModel
.mbFieldListSortAsc
= rAttribs
.getBool( XML_fieldListSortAscending
, false );
953 maDefModel
.mbCustomListSort
= rAttribs
.getBool( XML_customListSort
, true );
954 maDefModel
.mbApplyNumFmt
= rAttribs
.getBool( XML_applyNumberFormats
, false );
955 maDefModel
.mbApplyFont
= rAttribs
.getBool( XML_applyFontFormats
, false );
956 maDefModel
.mbApplyAlignment
= rAttribs
.getBool( XML_applyAlignmentFormats
, false );
957 maDefModel
.mbApplyBorder
= rAttribs
.getBool( XML_applyBorderFormats
, false );
958 maDefModel
.mbApplyFill
= rAttribs
.getBool( XML_applyPatternFormats
, false );
959 // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
960 maDefModel
.mbApplyProtection
= rAttribs
.getBool( XML_applyWidthHeightFormats
, false );
963 void PivotTable::importLocation( const AttributeList
& rAttribs
, sal_Int16 nSheet
)
965 AddressConverter::convertToCellRangeUnchecked( maLocationModel
.maRange
, rAttribs
.getString( XML_ref
, OUString() ), nSheet
);
966 maLocationModel
.mnFirstHeaderRow
= rAttribs
.getInteger( XML_firstHeaderRow
, 0 );
967 maLocationModel
.mnFirstDataRow
= rAttribs
.getInteger( XML_firstDataRow
, 0 );
968 maLocationModel
.mnFirstDataCol
= rAttribs
.getInteger( XML_firstDataCol
, 0 );
969 maLocationModel
.mnRowPageCount
= rAttribs
.getInteger( XML_rowPageCount
, 0 );
970 maLocationModel
.mnColPageCount
= rAttribs
.getInteger( XML_colPageCount
, 0 );
973 void PivotTable::importRowField( const AttributeList
& rAttribs
)
975 importField( maRowFields
, rAttribs
);
978 void PivotTable::importColField( const AttributeList
& rAttribs
)
980 importField( maColFields
, rAttribs
);
983 void PivotTable::importPageField( const AttributeList
& rAttribs
)
985 PTPageFieldModel aModel
;
986 aModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
987 aModel
.mnField
= rAttribs
.getInteger( XML_fld
, -1 );
988 // specification is wrong, XML_item is not the cache item, but the field item
989 aModel
.mnItem
= rAttribs
.getInteger( XML_item
, BIFF12_PTPAGEFIELD_MULTIITEMS
);
990 maPageFields
.push_back( aModel
);
993 void PivotTable::importDataField( const AttributeList
& rAttribs
)
995 PTDataFieldModel aModel
;
996 aModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
997 aModel
.mnField
= rAttribs
.getInteger( XML_fld
, -1 );
998 aModel
.mnSubtotal
= rAttribs
.getToken( XML_subtotal
, XML_sum
);
999 aModel
.mnShowDataAs
= rAttribs
.getToken( XML_showDataAs
, XML_normal
);
1000 aModel
.mnBaseField
= rAttribs
.getInteger( XML_baseField
, -1 );
1001 aModel
.mnBaseItem
= rAttribs
.getInteger( XML_baseItem
, -1 );
1002 aModel
.mnNumFmtId
= rAttribs
.getInteger( XML_numFmtId
, 0 );
1003 maDataFields
.push_back( aModel
);
1006 void PivotTable::importPTDefinition( SequenceInputStream
& rStrm
)
1008 sal_uInt32 nFlags1
, nFlags2
, nFlags3
;
1009 sal_uInt8 nDataAxis
;
1010 nFlags1
= rStrm
.readuInt32();
1011 nFlags2
= rStrm
.readuInt32();
1012 nFlags3
= rStrm
.readuInt32();
1013 nDataAxis
= rStrm
.readuChar();
1014 maDefModel
.mnPageWrap
= rStrm
.readuInt8();
1015 rStrm
.skip( 2 ); // refresh versions
1016 maDefModel
.mnDataPosition
= rStrm
.readInt32();
1017 maDefModel
.mnAutoFormatId
= rStrm
.readuInt16();
1018 rStrm
.skip( 2 ); // unused
1019 maDefModel
.mnChartFormat
= rStrm
.readInt32();
1020 maDefModel
.mnCacheId
= rStrm
.readInt32();
1021 rStrm
>> maDefModel
.maName
;
1022 if( getFlag( nFlags2
, BIFF12_PTDEF_HASDATACAPTION
) )
1023 rStrm
>> maDefModel
.maDataCaption
;
1024 if( getFlag( nFlags2
, BIFF12_PTDEF_HASGRANDTOTALCAPTION
) )
1025 rStrm
>> maDefModel
.maGrandTotalCaption
;
1026 if( !getFlag( nFlags3
, BIFF12_PTDEF_NOERRORCAPTION
) ) // missing flag indicates existing string
1027 rStrm
>> maDefModel
.maErrorCaption
;
1028 if( !getFlag( nFlags3
, BIFF12_PTDEF_NOMISSINGCAPTION
) ) // missing flag indicates existing string
1029 rStrm
>> maDefModel
.maMissingCaption
;
1030 if( getFlag( nFlags2
, BIFF12_PTDEF_HASPAGESTYLE
) )
1031 rStrm
>> maDefModel
.maPageStyle
;
1032 if( getFlag( nFlags2
, BIFF12_PTDEF_HASPIVOTTABLESTYLE
) )
1033 rStrm
>> maDefModel
.maPivotTableStyle
;
1034 if( getFlag( nFlags2
, BIFF12_PTDEF_HASVACATEDSTYLE
) )
1035 rStrm
>> maDefModel
.maVacatedStyle
;
1036 if( getFlag( nFlags2
, BIFF12_PTDEF_HASTAG
) )
1037 rStrm
>> maDefModel
.maTag
;
1038 if( getFlag( nFlags3
, BIFF12_PTDEF_HASCOLHEADERCAPTION
) ) // TODO: right order (col/row)? spec is unclear
1039 rStrm
>> maDefModel
.maColHeaderCaption
;
1040 if( getFlag( nFlags3
, BIFF12_PTDEF_HASROWHEADERCAPTION
) )
1041 rStrm
>> maDefModel
.maRowHeaderCaption
;
1044 (nDataAxis
!= BIFF12_PTDEF_ROWAXIS
) && (nDataAxis
!= BIFF12_PTDEF_COLAXIS
),
1046 "PivotTable::importPTDefinition - unexpected axis position for data field");
1048 maDefModel
.mnIndent
= extractValue
< sal_uInt8
>( nFlags1
, 24, 7 );
1049 maDefModel
.mbDataOnRows
= nDataAxis
== BIFF12_PTDEF_ROWAXIS
;
1050 maDefModel
.mbShowError
= getFlag( nFlags2
, BIFF12_PTDEF_SHOWERROR
);
1051 maDefModel
.mbShowMissing
= getFlag( nFlags2
, BIFF12_PTDEF_SHOWMISSING
);
1052 maDefModel
.mbShowItems
= getFlag( nFlags1
, BIFF12_PTDEF_SHOWITEMS
);
1053 maDefModel
.mbDisableFieldList
= getFlag( nFlags1
, BIFF12_PTDEF_DISABLEFIELDLIST
);
1054 maDefModel
.mbShowCalcMembers
= !getFlag( nFlags1
, BIFF12_PTDEF_HIDECALCMEMBERS
);
1055 maDefModel
.mbVisualTotals
= !getFlag( nFlags1
, BIFF12_PTDEF_WITHHIDDENTOTALS
);
1056 maDefModel
.mbShowDrill
= !getFlag( nFlags1
, BIFF12_PTDEF_HIDEDRILL
);
1057 maDefModel
.mbPrintDrill
= getFlag( nFlags1
, BIFF12_PTDEF_PRINTDRILL
);
1058 maDefModel
.mbEnableDrill
= getFlag( nFlags2
, BIFF12_PTDEF_ENABLEDRILL
);
1059 maDefModel
.mbPreserveFormatting
= getFlag( nFlags2
, BIFF12_PTDEF_PRESERVEFORMATTING
);
1060 maDefModel
.mbUseAutoFormat
= getFlag( nFlags2
, BIFF12_PTDEF_USEAUTOFORMAT
);
1061 maDefModel
.mbPageOverThenDown
= getFlag( nFlags2
, BIFF12_PTDEF_PAGEOVERTHENDOWN
);
1062 maDefModel
.mbSubtotalHiddenItems
= getFlag( nFlags2
, BIFF12_PTDEF_SUBTOTALHIDDENITEMS
);
1063 maDefModel
.mbRowGrandTotals
= getFlag( nFlags2
, BIFF12_PTDEF_ROWGRANDTOTALS
);
1064 maDefModel
.mbColGrandTotals
= getFlag( nFlags2
, BIFF12_PTDEF_COLGRANDTOTALS
);
1065 maDefModel
.mbFieldPrintTitles
= getFlag( nFlags2
, BIFF12_PTDEF_FIELDPRINTTITLES
);
1066 maDefModel
.mbItemPrintTitles
= getFlag( nFlags2
, BIFF12_PTDEF_ITEMPRINTTITLES
);
1067 maDefModel
.mbMergeItem
= getFlag( nFlags2
, BIFF12_PTDEF_MERGEITEM
);
1068 maDefModel
.mbApplyNumFmt
= getFlag( nFlags2
, BIFF12_PTDEF_APPLYNUMFMT
);
1069 maDefModel
.mbApplyFont
= getFlag( nFlags2
, BIFF12_PTDEF_APPLYFONT
);
1070 maDefModel
.mbApplyAlignment
= getFlag( nFlags2
, BIFF12_PTDEF_APPLYALIGNMENT
);
1071 maDefModel
.mbApplyBorder
= getFlag( nFlags2
, BIFF12_PTDEF_APPLYBORDER
);
1072 maDefModel
.mbApplyFill
= getFlag( nFlags2
, BIFF12_PTDEF_APPLYFILL
);
1073 maDefModel
.mbApplyProtection
= getFlag( nFlags2
, BIFF12_PTDEF_APPLYPROTECTION
);
1074 maDefModel
.mbShowEmptyRow
= getFlag( nFlags2
, BIFF12_PTDEF_SHOWEMPTYROW
);
1075 maDefModel
.mbShowEmptyCol
= getFlag( nFlags2
, BIFF12_PTDEF_SHOWEMPTYCOL
);
1076 maDefModel
.mbShowHeaders
= !getFlag( nFlags1
, BIFF12_PTDEF_HIDEHEADERS
);
1077 maDefModel
.mbFieldListSortAsc
= getFlag( nFlags3
, BIFF12_PTDEF_FIELDLISTSORTASC
);
1078 maDefModel
.mbCustomListSort
= !getFlag( nFlags3
, BIFF12_PTDEF_NOCUSTOMLISTSORT
);
1081 void PivotTable::importPTLocation( SequenceInputStream
& rStrm
, sal_Int16 nSheet
)
1085 maLocationModel
.mnFirstHeaderRow
= rStrm
.readInt32();
1086 maLocationModel
.mnFirstDataRow
= rStrm
.readInt32();
1087 maLocationModel
.mnFirstDataCol
= rStrm
.readInt32();
1088 maLocationModel
.mnRowPageCount
= rStrm
.readInt32();
1089 maLocationModel
.mnColPageCount
= rStrm
.readInt32();
1090 AddressConverter::convertToCellRangeUnchecked( maLocationModel
.maRange
, aBinRange
, nSheet
);
1093 void PivotTable::importPTRowFields( SequenceInputStream
& rStrm
)
1095 importFields( maRowFields
, rStrm
);
1098 void PivotTable::importPTColFields( SequenceInputStream
& rStrm
)
1100 importFields( maColFields
, rStrm
);
1103 void PivotTable::importPTPageField( SequenceInputStream
& rStrm
)
1105 PTPageFieldModel aModel
;
1107 aModel
.mnField
= rStrm
.readInt32();
1108 aModel
.mnItem
= rStrm
.readInt32();
1109 rStrm
.skip( 4 ); // hierarchy
1110 nFlags
= rStrm
.readuChar();
1111 if( getFlag( nFlags
, BIFF12_PTPAGEFIELD_HASNAME
) )
1112 rStrm
>> aModel
.maName
;
1113 maPageFields
.push_back( aModel
);
1116 void PivotTable::importPTDataField( SequenceInputStream
& rStrm
)
1118 PTDataFieldModel aModel
;
1119 sal_Int32 nSubtotal
, nShowDataAs
;
1121 aModel
.mnField
= rStrm
.readInt32( );
1122 nSubtotal
= rStrm
.readInt32();
1123 nShowDataAs
= rStrm
.readInt32();
1124 aModel
.mnBaseField
= rStrm
.readInt32();
1125 aModel
.mnBaseItem
= rStrm
.readInt32();
1126 aModel
.mnNumFmtId
= rStrm
.readInt32();
1127 nHasName
= rStrm
.readuChar();
1129 rStrm
>> aModel
.maName
;
1130 aModel
.setBiffSubtotal( nSubtotal
);
1131 aModel
.setBiffShowDataAs( nShowDataAs
);
1132 maDataFields
.push_back( aModel
);
1135 PivotTableField
& PivotTable::createTableField()
1137 sal_Int32 nFieldIndex
= static_cast< sal_Int32
>( maFields
.size() );
1138 PivotTableFieldVector::value_type
xTableField( new PivotTableField( *this, nFieldIndex
) );
1139 maFields
.push_back( xTableField
);
1140 return *xTableField
;
1143 PivotTableFilter
& PivotTable::createTableFilter()
1145 PivotTableFilterVector::value_type
xTableFilter( new PivotTableFilter( *this ) );
1146 maFilters
.push_back( xTableFilter
);
1147 return *xTableFilter
;
1150 void PivotTable::finalizeImport()
1152 if( getAddressConverter().validateCellRange( maLocationModel
.maRange
, true, true ) )
1154 mpPivotCache
= getPivotCaches().importPivotCacheFragment( maDefModel
.mnCacheId
);
1155 if( mpPivotCache
&& mpPivotCache
->isValidDataSource() && !maDefModel
.maName
.isEmpty() )
1157 // clear destination area of the original pivot table
1160 Reference
< XSheetOperation
> xSheetOp( getCellRangeFromDoc( maLocationModel
.maRange
), UNO_QUERY_THROW
);
1161 using namespace ::com::sun::star::sheet::CellFlags
;
1162 xSheetOp
->clearContents( VALUE
| DATETIME
| STRING
| FORMULA
| HARDATTR
| STYLES
| EDITATTR
| FORMATTED
);
1170 // create a new data pilot descriptor based on the source data
1171 Reference
< XDataPilotTablesSupplier
> xDPTablesSupp( getSheetFromDoc( maLocationModel
.maRange
.Sheet
), UNO_QUERY_THROW
);
1172 Reference
< XDataPilotTables
> xDPTables( xDPTablesSupp
->getDataPilotTables(), UNO_SET_THROW
);
1173 mxDPDescriptor
.set( xDPTables
->createDataPilotDescriptor(), UNO_SET_THROW
);
1174 mxDPDescriptor
->setSourceRange( mpPivotCache
->getSourceRange() );
1175 mxDPDescriptor
->setTag( maDefModel
.maTag
);
1177 // TODO: This is a hack. Eventually we need to convert the whole thing to the internal API.
1178 ScDataPilotDescriptorBase
* pImpl
= ScDataPilotDescriptorBase::getImplementation(mxDPDescriptor
);
1182 mpDPObject
= pImpl
->GetDPObject();
1186 // global data pilot properties
1187 PropertySet
aDescProp( mxDPDescriptor
);
1188 aDescProp
.setProperty( PROP_ColumnGrand
, maDefModel
.mbColGrandTotals
);
1189 aDescProp
.setProperty( PROP_RowGrand
, maDefModel
.mbRowGrandTotals
);
1190 aDescProp
.setProperty( PROP_ShowFilterButton
, false );
1191 aDescProp
.setProperty( PROP_DrillDownOnDoubleClick
, maDefModel
.mbEnableDrill
);
1193 // finalize all fields, this finds field names and creates grouping fields
1194 maFields
.forEachMem( &PivotTableField::finalizeImport
, ::boost::cref( mxDPDescriptor
) );
1197 for( IndexVector::iterator aIt
= maRowFields
.begin(), aEnd
= maRowFields
.end(); aIt
!= aEnd
; ++aIt
)
1198 if( PivotTableField
* pField
= getTableField( *aIt
) )
1199 pField
->convertRowField();
1201 // all column fields
1202 for( IndexVector::iterator aIt
= maColFields
.begin(), aEnd
= maColFields
.end(); aIt
!= aEnd
; ++aIt
)
1203 if( PivotTableField
* pField
= getTableField( *aIt
) )
1204 pField
->convertColField();
1207 for( PageFieldVector::iterator aIt
= maPageFields
.begin(), aEnd
= maPageFields
.end(); aIt
!= aEnd
; ++aIt
)
1208 if( PivotTableField
* pField
= getTableField( aIt
->mnField
) )
1209 pField
->convertPageField( *aIt
);
1211 // all hidden fields
1212 ::std::set
< sal_Int32
> aVisFields
;
1213 aVisFields
.insert( maRowFields
.begin(), maRowFields
.end() );
1214 aVisFields
.insert( maColFields
.begin(), maColFields
.end() );
1215 for( PageFieldVector::iterator aIt
= maPageFields
.begin(), aEnd
= maPageFields
.end(); aIt
!= aEnd
; ++aIt
)
1216 aVisFields
.insert( aIt
->mnField
);
1217 for( PivotTableFieldVector::iterator aBeg
= maFields
.begin(), aIt
= aBeg
, aEnd
= maFields
.end(); aIt
!= aEnd
; ++aIt
)
1218 if( aVisFields
.count( static_cast< sal_Int32
>( aIt
- aBeg
) ) == 0 )
1219 (*aIt
)->convertHiddenField();
1222 for( DataFieldVector::iterator aIt
= maDataFields
.begin(), aEnd
= maDataFields
.end(); aIt
!= aEnd
; ++aIt
)
1224 if( const PivotCacheField
* pCacheField
= getCacheField( aIt
->mnField
) )
1226 if ( pCacheField
-> getGroupBaseField() != -1 )
1227 aIt
->mnField
= pCacheField
-> getGroupBaseField();
1229 if( PivotTableField
* pField
= getTableField( aIt
->mnField
) )
1230 pField
->convertDataField( *aIt
);
1234 maFilters
.forEachMem( &PivotTableFilter::finalizeImport
);
1236 // calculate base position of table
1237 CellAddress
aPos( maLocationModel
.maRange
.Sheet
, maLocationModel
.maRange
.StartColumn
, maLocationModel
.maRange
.StartRow
);
1238 /* If page fields exist, include them into the destination
1239 area (they are excluded in Excel). Add an extra blank row. */
1240 if( !maPageFields
.empty() )
1241 aPos
.Row
= ::std::max
< sal_Int32
>( static_cast< sal_Int32
>( aPos
.Row
- maPageFields
.size() - 1 ), 0 );
1243 // insert the DataPilot table into the sheet
1244 xDPTables
->insertNewByName( maDefModel
.maName
, aPos
, mxDPDescriptor
);
1248 OSL_FAIL( "PivotTable::finalizeImport - exception while creating the DataPilot table" );
1254 void PivotTable::finalizeDateGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
, sal_Int32 nBaseFieldIdx
)
1256 // process all fields, there is no chaining information in the cache fields
1257 maFields
.forEachMem( &PivotTableField::finalizeDateGroupingImport
, ::boost::cref( rxBaseDPField
), nBaseFieldIdx
);
1260 void PivotTable::finalizeParentGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
,
1261 const PivotCacheField
& rBaseCacheField
, PivotCacheGroupItemVector
& orItemNames
)
1263 // try to create parent group fields that group the items of the passed base field
1264 if( PivotTableField
* pParentTableField
= maFields
.get( rBaseCacheField
.getParentGroupField() ).get() )
1265 pParentTableField
->finalizeParentGroupingImport( rxBaseDPField
, rBaseCacheField
, orItemNames
);
1268 Reference
< XDataPilotField
> PivotTable::getDataPilotField( const OUString
& rFieldName
) const
1270 Reference
< XDataPilotField
> xDPField
;
1271 if( !rFieldName
.isEmpty() && mxDPDescriptor
.is() ) try
1273 Reference
< XNameAccess
> xDPFieldsNA( mxDPDescriptor
->getDataPilotFields(), UNO_QUERY_THROW
);
1274 xDPField
.set( xDPFieldsNA
->getByName( rFieldName
), UNO_QUERY
);
1282 Reference
< XDataPilotField
> PivotTable::getDataPilotField( sal_Int32 nFieldIdx
) const
1284 Reference
< XDataPilotField
> xDPField
;
1285 if( const PivotTableField
* pTableField
= maFields
.get( nFieldIdx
).get() )
1286 xDPField
= getDataPilotField( pTableField
->getDPFieldName() );
1290 Reference
< XDataPilotField
> PivotTable::getDataLayoutField() const
1292 Reference
< XDataPilotField
> xDPField
;
1295 Reference
< XDataPilotDataLayoutFieldSupplier
> xDPDataFieldSupp( mxDPDescriptor
, UNO_QUERY_THROW
);
1296 xDPField
= xDPDataFieldSupp
->getDataLayoutField();
1304 const PivotCacheField
* PivotTable::getCacheField( sal_Int32 nFieldIdx
) const
1306 return mpPivotCache
? mpPivotCache
->getCacheField( nFieldIdx
) : 0;
1309 const PivotCacheField
* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx
) const
1311 const PTDataFieldModel
* pDataField
= ContainerHelper::getVectorElement( maDataFields
, nDataItemIdx
);
1312 return pDataField
? getCacheField( pDataField
->mnField
) : 0;
1315 sal_Int32
PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx
) const
1317 return mpPivotCache
? mpPivotCache
->getCacheDatabaseIndex( nFieldIdx
) : -1;
1320 // private --------------------------------------------------------------------
1322 PivotTableField
* PivotTable::getTableField( sal_Int32 nFieldIdx
)
1324 return (nFieldIdx
== OOX_PT_DATALAYOUTFIELD
) ? &maDataField
: maFields
.get( nFieldIdx
).get();
1327 void PivotTable::importField( IndexVector
& orFields
, const AttributeList
& rAttribs
)
1329 orFields
.push_back( rAttribs
.getInteger( XML_x
, -1 ) );
1332 void PivotTable::importFields( IndexVector
& orFields
, SequenceInputStream
& rStrm
)
1334 OSL_ENSURE( orFields
.empty(), "PivotTable::importFields - multiple record instances" );
1336 sal_Int32 nCount
= rStrm
.readInt32();
1337 OSL_ENSURE( 4 * nCount
== rStrm
.getRemaining(), "PivotTable::importFields - invalid field count" );
1338 nCount
= static_cast< sal_Int32
>( rStrm
.getRemaining() / 4 );
1339 for( sal_Int32 nIdx
= 0; nIdx
< nCount
; ++nIdx
)
1340 orFields
.push_back( rStrm
.readInt32() );
1343 PivotTableBuffer::PivotTableBuffer( const WorkbookHelper
& rHelper
) :
1344 WorkbookHelper( rHelper
)
1348 PivotTable
& PivotTableBuffer::createPivotTable()
1350 PivotTableVector::value_type
xTable( new PivotTable( *this ) );
1351 maTables
.push_back( xTable
);
1355 void PivotTableBuffer::finalizeImport()
1357 maTables
.forEachMem( &PivotTable::finalizeImport
);
1363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */