Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / filter / oox / pivottablebuffer.cxx
blob04a432ae8d92d727793f826485dc8d32eaa1cddc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
22 #include <set>
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 <oox/token/tokens.hxx>
46 #include "addressconverter.hxx"
47 #include "biffinputstream.hxx"
49 #include "dapiuno.hxx"
50 #include "dpobject.hxx"
51 #include "dpsave.hxx"
52 #include "dpdimsave.hxx"
53 #include "document.hxx"
54 #include "documentimport.hxx"
56 namespace oox {
57 namespace xls {
59 using namespace ::com::sun::star::container;
60 using namespace ::com::sun::star::sheet;
61 using namespace ::com::sun::star::table;
62 using namespace ::com::sun::star::uno;
63 using namespace com::sun::star;
65 namespace {
67 const sal_Int32 OOX_PT_DATALAYOUTFIELD = -2; /// Placeholder index of data layout field.
69 const sal_Int32 OOX_PT_PREVIOUS_ITEM = 0x001000FC; /// Calculation of data item result is based on previous item.
70 const sal_Int32 OOX_PT_NEXT_ITEM = 0x001000FD; /// Calculation of data item result is based on next item.
72 const sal_uInt32 BIFF12_PTFIELD_DATAFIELD = 0x00000008;
73 const sal_uInt32 BIFF12_PTFIELD_DEFAULT = 0x00000100;
74 const sal_uInt32 BIFF12_PTFIELD_SUM = 0x00000200;
75 const sal_uInt32 BIFF12_PTFIELD_COUNTA = 0x00000400;
76 const sal_uInt32 BIFF12_PTFIELD_AVERAGE = 0x00000800;
77 const sal_uInt32 BIFF12_PTFIELD_MAX = 0x00001000;
78 const sal_uInt32 BIFF12_PTFIELD_MIN = 0x00002000;
79 const sal_uInt32 BIFF12_PTFIELD_PRODUCT = 0x00004000;
80 const sal_uInt32 BIFF12_PTFIELD_COUNT = 0x00008000;
81 const sal_uInt32 BIFF12_PTFIELD_STDDEV = 0x00010000;
82 const sal_uInt32 BIFF12_PTFIELD_STDDEVP = 0x00020000;
83 const sal_uInt32 BIFF12_PTFIELD_VAR = 0x00040000;
84 const sal_uInt32 BIFF12_PTFIELD_VARP = 0x00080000;
86 const sal_uInt32 BIFF12_PTFIELD_SHOWALL = 0x00000020;
87 const sal_uInt32 BIFF12_PTFIELD_OUTLINE = 0x00000040;
88 const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW = 0x00000080;
89 const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP = 0x00000100;
90 const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK = 0x00000800;
91 const sal_uInt32 BIFF12_PTFIELD_AUTOSORT = 0x00001000;
92 const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING = 0x00002000;
93 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW = 0x00004000;
94 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP = 0x00008000;
95 const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS = 0x00080000;
97 const sal_uInt16 BIFF12_PTFITEM_HIDDEN = 0x0001;
98 const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS = 0x0002;
100 const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME = 0x01;
101 const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS = 0x001000FE;
103 const sal_uInt16 BIFF12_PTFILTER_HASNAME = 0x0001;
104 const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION = 0x0002;
105 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1 = 0x0004;
106 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2 = 0x0008;
108 const sal_uInt8 BIFF12_TOP10FILTER_TOP = 0x01;
109 const sal_uInt8 BIFF12_TOP10FILTER_PERCENT = 0x02;
111 const sal_uInt32 BIFF12_PTDEF_SHOWITEMS = 0x00000100;
112 const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST = 0x00000400;
113 const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS = 0x00001000;
114 const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS = 0x00002000;
115 const sal_uInt32 BIFF12_PTDEF_HIDEDRILL = 0x00100000;
116 const sal_uInt32 BIFF12_PTDEF_PRINTDRILL = 0x00200000;
117 const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS = 0x80000000;
119 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW = 0x00000004;
120 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL = 0x00000008;
121 const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL = 0x00000020;
122 const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING = 0x00000080;
123 const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT = 0x00000100;
124 const sal_uInt32 BIFF12_PTDEF_SHOWERROR = 0x00000200;
125 const sal_uInt32 BIFF12_PTDEF_SHOWMISSING = 0x00000400;
126 const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN = 0x00000800;
127 const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS = 0x00001000;
128 const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS = 0x00002000;
129 const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS = 0x00004000;
130 const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES = 0x00008000;
131 const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES = 0x00020000;
132 const sal_uInt32 BIFF12_PTDEF_MERGEITEM = 0x00040000;
133 const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION = 0x00080000;
134 const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION = 0x00100000;
135 const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE = 0x00200000;
136 const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE = 0x00400000;
137 const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE = 0x00800000;
138 const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT = 0x01000000;
139 const sal_uInt32 BIFF12_PTDEF_APPLYFONT = 0x02000000;
140 const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT = 0x04000000;
141 const sal_uInt32 BIFF12_PTDEF_APPLYBORDER = 0x08000000;
142 const sal_uInt32 BIFF12_PTDEF_APPLYFILL = 0x10000000;
143 const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION = 0x20000000;
144 const sal_uInt32 BIFF12_PTDEF_HASTAG = 0x40000000;
146 const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION = 0x00000040;
147 const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION = 0x00000080;
148 const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION = 0x00000400;
149 const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION = 0x00000800;
150 const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC = 0x00001000;
151 const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT = 0x00004000;
153 const sal_uInt8 BIFF12_PTDEF_ROWAXIS = 1;
154 const sal_uInt8 BIFF12_PTDEF_COLAXIS = 2;
156 } // namespace
158 PTFieldItemModel::PTFieldItemModel() :
159 mnCacheItem( -1 ),
160 mnType( XML_data ),
161 mbShowDetails( true ),
162 mbHidden( false )
166 void PTFieldItemModel::setBiffType( sal_uInt16 nType )
168 static const sal_Int32 spnTypes[] = { XML_data, XML_default,
169 XML_sum, XML_countA, XML_avg, XML_max, XML_min, XML_product, XML_count,
170 XML_stdDev, XML_stdDevP, XML_var, XML_varP, XML_grand, XML_blank };
171 mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_data );
174 PTFieldModel::PTFieldModel() :
175 mnAxis( XML_TOKEN_INVALID ),
176 mnNumFmtId( 0 ),
177 mnAutoShowItems( 10 ),
178 mnAutoShowRankBy( -1 ),
179 mnSortType( XML_manual ),
180 mnSortRefField( -1 ),
181 mnSortRefItem( -1 ),
182 mbDataField( false ),
183 mbDefaultSubtotal( true ),
184 mbSumSubtotal( false ),
185 mbCountASubtotal( false ),
186 mbAverageSubtotal( false ),
187 mbMaxSubtotal( false ),
188 mbMinSubtotal( false ),
189 mbProductSubtotal( false ),
190 mbCountSubtotal( false ),
191 mbStdDevSubtotal( false ),
192 mbStdDevPSubtotal( false ),
193 mbVarSubtotal( false ),
194 mbVarPSubtotal( false ),
195 mbShowAll( true ),
196 mbOutline( true ),
197 mbSubtotalTop( true ),
198 mbInsertBlankRow( false ),
199 mbInsertPageBreak( false ),
200 mbAutoShow( false ),
201 mbTopAutoShow( true ),
202 mbMultiPageItems( false )
206 void PTFieldModel::setBiffAxis( sal_uInt8 nAxis )
208 /* Weird. The axis field is organized as bit field, but only one of the
209 row/col/page flags are allowed at the same time and refer to the values
210 'axisRow', 'axisCol', and 'axisPage' of the XML attribute
211 'pivotField@axis'. Additionally, the fourth bit determines if the field
212 is a data field, which may appear combined with the row/col/page flags.
213 Therefore, this bit is unrelated to the 'axisValues' value of the
214 'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
215 boolean attribute. */
216 static const sal_Int32 spnAxisIds[] = { XML_TOKEN_INVALID, XML_axisRow, XML_axisCol, XML_TOKEN_INVALID, XML_axisPage };
217 mnAxis = STATIC_ARRAY_SELECT( spnAxisIds, nAxis, XML_TOKEN_INVALID );
220 PTPageFieldModel::PTPageFieldModel() :
221 mnField( -1 ),
222 mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS )
226 PTDataFieldModel::PTDataFieldModel() :
227 mnField( -1 ),
228 mnSubtotal( XML_sum ),
229 mnShowDataAs( XML_normal ),
230 mnBaseField( -1 ),
231 mnBaseItem( -1 ),
232 mnNumFmtId( 0 )
236 void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal )
238 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 };
239 mnSubtotal = STATIC_ARRAY_SELECT( spnSubtotals, nSubtotal, XML_TOKEN_INVALID );
242 void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs )
244 static const sal_Int32 spnShowDataAs[] = { XML_normal, XML_difference, XML_percent, XML_percentDiff, XML_runTotal, XML_percentOfRow, XML_percentOfCol, XML_percentOfTotal, XML_index };
245 mnShowDataAs = STATIC_ARRAY_SELECT( spnShowDataAs, nShowDataAs, XML_TOKEN_INVALID );
248 PivotTableField::PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex ) :
249 WorkbookHelper( rPivotTable ),
250 mrPivotTable( rPivotTable ),
251 mnFieldIndex( nFieldIndex )
255 void PivotTableField::importPivotField( const AttributeList& rAttribs )
257 /* The documentation mentions a value 'axisValues' for the attribute
258 'pivotField@axis'. But this value is not used to mark a data field, as
259 data fields may be inserted in one of the row/column/page dimensions at
260 the same time. Therefore, the boolean attribute 'pivotField@dataField'
261 is really used to mark data fields. */
262 maModel.mnAxis = rAttribs.getToken( XML_axis, XML_TOKEN_INVALID );
263 maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
264 maModel.mnAutoShowItems = rAttribs.getInteger( XML_itemPageCount, 10 );
265 maModel.mnAutoShowRankBy = rAttribs.getInteger( XML_rankBy, -1 );
266 maModel.mnSortType = rAttribs.getToken( XML_sortType, XML_manual );
267 maModel.mbDataField = rAttribs.getBool( XML_dataField, false );
268 maModel.mbDefaultSubtotal = rAttribs.getBool( XML_defaultSubtotal, true );
269 maModel.mbSumSubtotal = rAttribs.getBool( XML_sumSubtotal, false );
270 maModel.mbCountASubtotal = rAttribs.getBool( XML_countASubtotal, false );
271 maModel.mbAverageSubtotal = rAttribs.getBool( XML_avgSubtotal, false );
272 maModel.mbMaxSubtotal = rAttribs.getBool( XML_maxSubtotal, false );
273 maModel.mbMinSubtotal = rAttribs.getBool( XML_minSubtotal, false );
274 maModel.mbProductSubtotal = rAttribs.getBool( XML_productSubtotal, false );
275 maModel.mbCountSubtotal = rAttribs.getBool( XML_countSubtotal, false );
276 maModel.mbStdDevSubtotal = rAttribs.getBool( XML_stdDevSubtotal, false );
277 maModel.mbStdDevPSubtotal = rAttribs.getBool( XML_stdDevPSubtotal, false );
278 maModel.mbVarSubtotal = rAttribs.getBool( XML_varSubtotal, false );
279 maModel.mbVarPSubtotal = rAttribs.getBool( XML_varPSubtotal, false );
280 maModel.mbShowAll = rAttribs.getBool( XML_showAll, true );
281 maModel.mbOutline = rAttribs.getBool( XML_outline, true );
282 maModel.mbSubtotalTop = rAttribs.getBool( XML_subtotalTop, true );
283 maModel.mbInsertBlankRow = rAttribs.getBool( XML_insertBlankRow, false );
284 maModel.mbInsertPageBreak = rAttribs.getBool( XML_insertPageBreak, false );
285 maModel.mbAutoShow = rAttribs.getBool( XML_autoShow, false );
286 maModel.mbTopAutoShow = rAttribs.getBool( XML_topAutoShow, true );
287 maModel.mbMultiPageItems = rAttribs.getBool( XML_multipleItemSelectionAllowed, false );
290 void PivotTableField::importItem( const AttributeList& rAttribs )
292 PTFieldItemModel aModel;
293 aModel.mnCacheItem = rAttribs.getInteger( XML_x, -1 );
294 aModel.mnType = rAttribs.getToken( XML_t, XML_data );
295 aModel.mbShowDetails = rAttribs.getBool( XML_sd, true );
296 aModel.mbHidden = rAttribs.getBool( XML_h, false );
297 aModel.msCaption = rAttribs.getXString( XML_n, OUString() );
298 maItems.push_back( aModel );
301 void PivotTableField::importReference( const AttributeList& rAttribs )
303 // field index is stored as unsigned integer
304 maModel.mnSortRefField = static_cast< sal_Int32 >( rAttribs.getUnsigned( XML_field, SAL_MAX_UINT32 ) );
307 void PivotTableField::importReferenceItem( const AttributeList& rAttribs )
309 maModel.mnSortRefItem = rAttribs.getInteger( XML_v, -1 );
312 void PivotTableField::importPTField( SequenceInputStream& rStrm )
314 sal_uInt32 nFlags1, nFlags2;
315 nFlags1 = rStrm.readuInt32();
316 maModel.mnNumFmtId = rStrm.readInt32();
317 nFlags2 = rStrm.readuInt32();
318 maModel.mnAutoShowItems = rStrm.readInt32();
319 maModel.mnAutoShowRankBy = rStrm.readInt32();
321 maModel.setBiffAxis( extractValue< sal_uInt8 >( nFlags1, 0, 3 ) );
322 maModel.mbDataField = getFlag( nFlags1, BIFF12_PTFIELD_DATAFIELD );
323 maModel.mbDefaultSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_DEFAULT );
324 maModel.mbSumSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_SUM );
325 maModel.mbCountASubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNTA );
326 maModel.mbAverageSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_AVERAGE );
327 maModel.mbMaxSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MAX );
328 maModel.mbMinSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MIN );
329 maModel.mbProductSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_PRODUCT );
330 maModel.mbCountSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNT );
331 maModel.mbStdDevSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEV );
332 maModel.mbStdDevPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEVP );
333 maModel.mbVarSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VAR );
334 maModel.mbVarPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VARP );
336 maModel.mbShowAll = getFlag( nFlags2, BIFF12_PTFIELD_SHOWALL );
337 maModel.mbOutline = getFlag( nFlags2, BIFF12_PTFIELD_OUTLINE );
338 maModel.mbSubtotalTop = getFlag( nFlags2, BIFF12_PTFIELD_SUBTOTALTOP );
339 maModel.mbInsertBlankRow = getFlag( nFlags2, BIFF12_PTFIELD_INSERTBLANKROW );
340 maModel.mbInsertPageBreak = getFlag( nFlags2, BIFF12_PTFIELD_INSERTPAGEBREAK );
341 maModel.mbAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOW );
342 maModel.mbTopAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOWTOP );
343 maModel.mbMultiPageItems = getFlag( nFlags2, BIFF12_PTFIELD_MULTIPAGEITEMS );
345 bool bAutoSort = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSORT );
346 bool bAscending = getFlag( nFlags2, BIFF12_PTFIELD_SORTASCENDING );
347 maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
350 void PivotTableField::importPTFItem( SequenceInputStream& rStrm )
352 PTFieldItemModel aModel;
353 sal_uInt8 nType;
354 sal_uInt16 nFlags;
355 nType = rStrm.readuChar();
356 nFlags = rStrm.readuInt16();
357 aModel.mnCacheItem = rStrm.readInt32();
359 aModel.setBiffType( nType );
360 aModel.mbShowDetails = !getFlag( nFlags, BIFF12_PTFITEM_HIDEDETAILS );
361 aModel.mbHidden = getFlag( nFlags, BIFF12_PTFITEM_HIDDEN );
363 maItems.push_back( aModel );
366 void PivotTableField::importPTReference( SequenceInputStream& rStrm )
368 maModel.mnSortRefField = rStrm.readInt32();
371 void PivotTableField::importPTReferenceItem( SequenceInputStream& rStrm )
373 maModel.mnSortRefItem = rStrm.readInt32();
376 void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& rxDPDesc )
378 /* Process all fields based on source data, other fields (e.g. group
379 fields) are processed from here. PivotCacahe::getDatabaseIndex()
380 returns -1 for all fields not based on source data. */
381 Reference< XDataPilotField > xDPField;
382 sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
383 if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
385 // try to get the source field and its name from passed DataPilot descriptor
386 Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
387 xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
388 Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
389 maDPFieldName = xDPFieldName->getName();
390 OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeImport - no field name in source data found" );
392 // try to convert grouping settings
393 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
395 // numeric grouping is done inplace, no nested group fields will appear
396 if( pCacheField->hasNumericGrouping() )
398 pCacheField->convertNumericGrouping( xDPField );
400 else if( pCacheField->hasDateGrouping() )
402 // first date group settings are inplace
403 pCacheField->createDateGroupField( xDPField );
404 // create all nested group fields (if any)
405 mrPivotTable.finalizeDateGroupingImport( xDPField, mnFieldIndex );
407 else if( pCacheField->hasParentGrouping() )
410 // create a list of all item names, needed to map between original and group items
411 ::std::vector< OUString > aItems;
412 pCacheField->getCacheItemNames( aItems );
413 PivotCacheGroupItemVector aItemNames;
414 for( ::std::vector< OUString >::iterator aIt = aItems.begin(), aEnd = aItems.end(); aIt != aEnd; ++aIt )
415 aItemNames.push_back( PivotCacheGroupItem( *aIt ) );
416 // create all nested group fields (if any)
417 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, aItemNames );
421 catch( Exception& )
426 void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
428 if( maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken
430 if( PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
432 if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) )
434 maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField );
435 pCacheField->setFinalGroupName(maDPFieldName);
436 OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
442 void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
444 if( maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken
446 if( PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
448 // data field can have user defined groupname captions, apply them
449 // if they do
450 IdCaptionPairList captionList;
451 for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
453 if ( aIt->mnType == XML_data && aIt->msCaption.getLength() )
454 captionList.push_back( IdCaptionPair( aIt->mnCacheItem, aIt->msCaption ) );
456 if ( !captionList.empty() )
457 pCacheField->applyItemCaptions( captionList );
459 maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, rBaseCacheField, orItemNames );
460 pCacheField->setFinalGroupName(maDPFieldName);
461 // on success, try to create nested group fields
462 Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
463 if( xDPField.is() )
464 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames );
469 void PivotTableField::finalizeImportBasedOnCache( const Reference< XDataPilotDescriptor >& rxDPDesc)
471 /* Process all fields based on source data, other fields (e.g. group
472 fields) are processed based on cache fields.*/
473 Reference< XDataPilotField > xDPField;
474 sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
475 if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
477 // Try to get the source field and its name from passed DataPilot descriptor
478 Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
479 xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
480 Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
481 maDPFieldName = xDPFieldName->getName();
482 SAL_WARN_IF( maDPFieldName.isEmpty(), "sc.filter", "PivotTableField::finalizeImportBasedOnCache - no field name in source data found" );
484 catch( Exception& )
488 // Use group names already generated for another table using the same group field.
489 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
491 if(!pCacheField->getFinalGroupName().isEmpty())
492 maDPFieldName = pCacheField->getFinalGroupName();
496 void PivotTableField::convertRowField()
498 convertRowColPageField( XML_axisRow );
501 void PivotTableField::convertColField()
503 convertRowColPageField( XML_axisCol );
506 void PivotTableField::convertHiddenField()
508 convertRowColPageField( XML_TOKEN_INVALID );
511 void PivotTableField::convertPageField( const PTPageFieldModel& rPageField )
513 OSL_ENSURE( rPageField.mnField == mnFieldIndex, "PivotTableField::convertPageField - wrong field index" );
514 // convert all settings common for row/column/page fields
515 Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage );
517 if( xDPField.is() )
519 PropertySet aPropSet( xDPField );
520 using namespace ::com::sun::star::sheet;
522 // find cache item used as 'selected page'
523 sal_Int32 nCacheItem = -1;
524 if( maModel.mbMultiPageItems )
526 // multiple items may be selected
527 OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" );
528 // try to find a single visible item
529 bool bHasMultiItems = false;
530 for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); (aIt != aEnd) && !bHasMultiItems; ++aIt )
532 if( (aIt->mnType == XML_data) && !aIt->mbHidden )
534 bHasMultiItems = nCacheItem >= 0;
535 nCacheItem = bHasMultiItems ? -1 : aIt->mnCacheItem;
539 else
541 // single item may be selected
542 if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) )
543 nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem;
546 if( nCacheItem >= 0 )
548 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
550 if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) )
552 OUString aSelectedPage = pSharedItem->getName();
553 aPropSet.setProperty( PROP_SelectedPage, aSelectedPage );
560 void PivotTableField::convertDataField( const PTDataFieldModel& rDataField )
562 OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" );
563 OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" );
564 Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
565 if( xDPField.is() )
567 PropertySet aPropSet( xDPField );
568 using namespace ::com::sun::star::sheet;
570 // field orientation
571 aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA );
573 /* Field aggregation function. Documentation is a little bit confused
574 about which names to use for the count functions. The name 'count'
575 means 'count all', and 'countNum' means 'count numbers'. On the
576 other hand, for subtotals, 'countA' means 'count all', and 'count'
577 means 'count numbers' (see above). */
578 GeneralFunction eAggFunc = GeneralFunction_SUM;
579 switch( rDataField.mnSubtotal )
581 case XML_sum: eAggFunc = GeneralFunction_SUM; break;
582 case XML_count: eAggFunc = GeneralFunction_COUNT; break;
583 case XML_average: eAggFunc = GeneralFunction_AVERAGE; break;
584 case XML_max: eAggFunc = GeneralFunction_MAX; break;
585 case XML_min: eAggFunc = GeneralFunction_MIN; break;
586 case XML_product: eAggFunc = GeneralFunction_PRODUCT; break;
587 case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS; break;
588 case XML_stdDev: eAggFunc = GeneralFunction_STDEV; break;
589 case XML_stdDevp: eAggFunc = GeneralFunction_STDEVP; break;
590 case XML_var: eAggFunc = GeneralFunction_VAR; break;
591 case XML_varp: eAggFunc = GeneralFunction_VARP; break;
592 default: OSL_FAIL( "PivotTableField::convertDataField - unknown aggregation function" );
594 aPropSet.setProperty( PROP_Function, eAggFunc );
596 // field reference ('show data as')
597 DataPilotFieldReference aReference;
598 aReference.ReferenceType = DataPilotFieldReferenceType::NONE;
599 switch( rDataField.mnShowDataAs )
601 case XML_difference: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE; break;
602 case XML_percent: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE; break;
603 case XML_percentDiff: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break;
604 case XML_runTotal: aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL; break;
605 case XML_percentOfRow: aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE; break;
606 case XML_percentOfCol: aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE; break;
607 case XML_percentOfTotal: aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE; break;
608 case XML_index: aReference.ReferenceType = DataPilotFieldReferenceType::INDEX; break;
610 if( aReference.ReferenceType != DataPilotFieldReferenceType::NONE )
612 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ) )
614 aReference.ReferenceField = pCacheField->getName();
615 switch( rDataField.mnBaseItem )
617 case OOX_PT_PREVIOUS_ITEM:
618 aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
619 break;
620 case OOX_PT_NEXT_ITEM:
621 aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
622 break;
623 default:
624 aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
625 if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) )
626 aReference.ReferenceItemName = pCacheItem->getName();
628 aPropSet.setProperty( PROP_Reference, aReference );
634 // private --------------------------------------------------------------------
636 Reference< XDataPilotField > PivotTableField::convertRowColPageField( sal_Int32 nAxis )
638 bool bDataLayout = mnFieldIndex == OOX_PT_DATALAYOUTFIELD;
639 Reference< XDataPilotField > xDPField = bDataLayout ? mrPivotTable.getDataLayoutField() : mrPivotTable.getDataPilotField( maDPFieldName );
640 OSL_ENSURE( bDataLayout || (nAxis == maModel.mnAxis), "PivotTableField::convertRowColPageField - field axis mismatch" );
642 if( xDPField.is() )
644 // TODO: Use this to set properties directly, bypassing the slow uno layer.
645 ScDPObject* pDPObj = mrPivotTable.getDPObject();
647 PropertySet aPropSet( xDPField );
648 using namespace ::com::sun::star::sheet;
650 // field orientation
651 DataPilotFieldOrientation eFieldOrient = DataPilotFieldOrientation_HIDDEN;
652 switch( nAxis )
654 case XML_axisRow: eFieldOrient = DataPilotFieldOrientation_ROW; break;
655 case XML_axisCol: eFieldOrient = DataPilotFieldOrientation_COLUMN; break;
656 case XML_axisPage: eFieldOrient = DataPilotFieldOrientation_PAGE; break;
658 if( eFieldOrient != DataPilotFieldOrientation_HIDDEN )
659 aPropSet.setProperty( PROP_Orientation, eFieldOrient );
661 // all other settings not for the data layout field
662 if( !bDataLayout )
664 /* Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
665 explicit functions are set. This is different behaviour between
666 XML (where 'defaultSubtotal' is set regardless of other
667 functions) and binary formats (where 'defaultSubtotal' is not
668 set if other functions are set). */
669 ::std::vector< GeneralFunction > aSubtotals;
670 /* Order of subtotals is fixed in Excel. Documentation is a little
671 bit confused about which names to use for the count functions.
672 For subtotals, 'countA' means 'count all', and 'count' means
673 'count numbers'. On the other hand, for the data field
674 aggregation function, 'count' means 'count all', and 'countNum'
675 means 'count numbers' (see below). */
676 if( maModel.mbSumSubtotal ) aSubtotals.push_back( GeneralFunction_SUM );
677 if( maModel.mbCountASubtotal ) aSubtotals.push_back( GeneralFunction_COUNT );
678 if( maModel.mbAverageSubtotal ) aSubtotals.push_back( GeneralFunction_AVERAGE );
679 if( maModel.mbMaxSubtotal ) aSubtotals.push_back( GeneralFunction_MAX );
680 if( maModel.mbMinSubtotal ) aSubtotals.push_back( GeneralFunction_MIN );
681 if( maModel.mbProductSubtotal ) aSubtotals.push_back( GeneralFunction_PRODUCT );
682 if( maModel.mbCountSubtotal ) aSubtotals.push_back( GeneralFunction_COUNTNUMS );
683 if( maModel.mbStdDevSubtotal ) aSubtotals.push_back( GeneralFunction_STDEV );
684 if( maModel.mbStdDevPSubtotal ) aSubtotals.push_back( GeneralFunction_STDEVP );
685 if( maModel.mbVarSubtotal ) aSubtotals.push_back( GeneralFunction_VAR );
686 if( maModel.mbVarPSubtotal ) aSubtotals.push_back( GeneralFunction_VARP );
687 // if no function is set manually, check the 'defaultSubtotal' flag
688 if( aSubtotals.empty() && maModel.mbDefaultSubtotal )
689 aSubtotals.push_back( GeneralFunction_AUTO );
690 aPropSet.setProperty( PROP_Subtotals, ContainerHelper::vectorToSequence( aSubtotals ) );
692 // layout settings
693 DataPilotFieldLayoutInfo aLayoutInfo;
694 aLayoutInfo.LayoutMode = maModel.mbOutline ?
695 (maModel.mbSubtotalTop ? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP : DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM) :
696 DataPilotFieldLayoutMode::TABULAR_LAYOUT;
697 aLayoutInfo.AddEmptyLines = maModel.mbInsertBlankRow;
698 aPropSet.setProperty( PROP_LayoutInfo, aLayoutInfo );
699 aPropSet.setProperty( PROP_ShowEmpty, maModel.mbShowAll );
701 // auto show (OOXML/BIFF12 only)
702 if( maModel.mbAutoShow )
704 DataPilotFieldAutoShowInfo aAutoShowInfo;
705 aAutoShowInfo.IsEnabled = true;
706 aAutoShowInfo.ShowItemsMode = maModel.mbTopAutoShow ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
707 aAutoShowInfo.ItemCount = maModel.mnAutoShowItems;
708 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnAutoShowRankBy ) )
709 aAutoShowInfo.DataField = pCacheField->getName();
710 aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
713 // auto sort
714 DataPilotFieldSortInfo aSortInfo;
715 aSortInfo.IsAscending = maModel.mnSortType == XML_ascending;
716 if( (maModel.mnSortType != XML_ascending) && (maModel.mnSortType != XML_descending) )
718 aSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
720 else
722 const PivotCacheField* pCacheField = (maModel.mnSortRefField == OOX_PT_DATALAYOUTFIELD) ?
723 mrPivotTable.getCacheFieldOfDataField( maModel.mnSortRefItem ) : nullptr;
724 if( pCacheField )
726 aSortInfo.Mode = DataPilotFieldSortMode::DATA;
727 aSortInfo.Field = pCacheField->getName();
729 else
731 aSortInfo.Mode = DataPilotFieldSortMode::NAME;
734 aPropSet.setProperty( PROP_SortInfo, aSortInfo );
736 // item settings
737 if (const PivotCacheField* pCacheField = mrPivotTable.getCacheField(mnFieldIndex))
739 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
740 ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(pCacheField->getName());
744 for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
746 if (aIt->mnType != XML_data)
747 continue;
749 const PivotCacheItem* pSharedItem = pCacheField->getCacheItem(aIt->mnCacheItem);
750 if (!pSharedItem)
751 continue;
755 ScDPSaveMember* pMem = pDim->GetMemberByName(pSharedItem->getName());
756 pMem->SetShowDetails(aIt->mbShowDetails);
757 pMem->SetIsVisible(!aIt->mbHidden);
759 catch( Exception& )
761 // catch every failed container access to be able to process following items
765 catch (const Exception&) {}
769 return xDPField;
772 PTFilterModel::PTFilterModel() :
773 mfValue( 0.0 ),
774 mnField( -1 ),
775 mnMemPropField( -1 ),
776 mnType( XML_TOKEN_INVALID ),
777 mnEvalOrder( 0 ),
778 mnId( -1 ),
779 mnMeasureField( -1 ),
780 mnMeasureHier( -1 ),
781 mbTopFilter( true )
785 PivotTableFilter::PivotTableFilter( const PivotTable& rPivotTable ) :
786 WorkbookHelper( rPivotTable ),
787 mrPivotTable( rPivotTable )
791 void PivotTableFilter::importFilter( const AttributeList& rAttribs )
793 maModel.maName = rAttribs.getXString( XML_name, OUString() );
794 maModel.maDescription = rAttribs.getXString( XML_description, OUString() );
795 maModel.maStrValue1 = rAttribs.getXString( XML_stringValue1, OUString() );
796 maModel.maStrValue2 = rAttribs.getXString( XML_stringValue2, OUString() );
797 maModel.mnField = rAttribs.getInteger( XML_fld, -1 );
798 maModel.mnMemPropField = rAttribs.getInteger( XML_mpFld, -1 );
799 maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
800 maModel.mnEvalOrder = rAttribs.getInteger( XML_evalOrder, 0 );
801 maModel.mnId = rAttribs.getInteger( XML_id, -1 );
802 maModel.mnMeasureField = rAttribs.getInteger( XML_iMeasureFld, -1 );
803 maModel.mnMeasureHier = rAttribs.getInteger( XML_iMeasureHier, -1 );
806 void PivotTableFilter::importTop10( const AttributeList& rAttribs )
808 OSL_ENSURE( rAttribs.getBool( XML_percent, false ) == (maModel.mnType == XML_percent),
809 "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
810 maModel.mfValue = rAttribs.getDouble( XML_val, 0.0 );
811 maModel.mbTopFilter = rAttribs.getBool( XML_top, true );
814 void PivotTableFilter::importPTFilter( SequenceInputStream& rStrm )
816 sal_Int32 nType;
817 sal_uInt16 nFlags;
818 maModel.mnField = rStrm.readInt32();
819 maModel.mnMemPropField = rStrm.readInt32();
820 nType = rStrm.readInt32();
821 rStrm.skip( 4 ); // unused
822 maModel.mnId = rStrm.readInt32();
823 maModel.mnMeasureField = rStrm.readInt32();
824 maModel.mnMeasureHier = rStrm.readInt32();
825 nFlags = rStrm.readuInt16();
826 if( getFlag( nFlags, BIFF12_PTFILTER_HASNAME ) )
827 rStrm >> maModel.maName;
828 if( getFlag( nFlags, BIFF12_PTFILTER_HASDESCRIPTION ) )
829 rStrm >> maModel.maDescription;
830 if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE1 ) )
831 rStrm >> maModel.maStrValue1;
832 if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE2 ) )
833 rStrm >> maModel.maStrValue2;
835 static const sal_Int32 spnTypes[] =
837 XML_unknown,
838 // data field top10 filter (1-3)
839 XML_count, XML_percent, XML_sum,
840 // caption filter (4-17)
841 XML_captionEqual, XML_captionNotEqual,
842 XML_captionBeginsWith, XML_captionNotBeginsWith, XML_captionEndsWith, XML_captionNotEndsWith,
843 XML_captionContains, XML_captionNotContains, XML_captionGreaterThan, XML_captionGreaterThanOrEqual,
844 XML_captionLessThan, XML_captionLessThanOrEqual, XML_captionBetween, XML_captionNotBetween,
845 // value filter (18-25)
846 XML_valueEqual, XML_valueNotEqual, XML_valueGreaterThan, XML_valueGreaterThanOrEqual,
847 XML_valueLessThan, XML_valueLessThanOrEqual, XML_valueBetween, XML_valueNotBetween,
848 // date filter (26-65)
849 XML_dateEqual, XML_dateOlderThan, XML_dateNewerThan, XML_dateBetween,
850 XML_tomorrow, XML_today, XML_yesterday, XML_nextWeek, XML_thisWeek, XML_lastWeek,
851 XML_nextMonth, XML_thisMonth, XML_lastMonth, XML_nextQuarter, XML_thisQuarter, XML_lastQuarter,
852 XML_nextYear, XML_thisYear, XML_lastYear, XML_yearToDate, XML_Q1, XML_Q2, XML_Q3, XML_Q4,
853 XML_M1, XML_M2, XML_M3, XML_M4, XML_M5, XML_M6, XML_M7, XML_M8, XML_M9, XML_M10, XML_M11, XML_M12,
854 XML_dateNotEqual, XML_dateOlderThanOrEqual, XML_dateNewerThanOrEqual, XML_dateNotBetween
856 maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
859 void PivotTableFilter::importTop10Filter( SequenceInputStream& rStrm )
861 sal_uInt8 nFlags;
862 nFlags = rStrm.readuChar();
863 maModel.mfValue = rStrm.readDouble();
865 SAL_WARN_IF(
866 getFlag(nFlags, BIFF12_TOP10FILTER_PERCENT) != (maModel.mnType == XML_percent),
867 "sc.filter",
868 "PivotTableFilter::importTop10 - unexpected value of percent attribute");
869 maModel.mbTopFilter = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
872 void PivotTableFilter::finalizeImport()
874 // only simple top10 filter supported
875 if( maModel.mnType == XML_count )
877 PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) );
878 if( aPropSet.is() )
880 using namespace ::com::sun::star::sheet;
881 DataPilotFieldAutoShowInfo aAutoShowInfo;
882 aAutoShowInfo.IsEnabled = true;
883 aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
884 aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 );
885 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) )
886 aAutoShowInfo.DataField = pCacheField->getName();
887 aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
892 PTDefinitionModel::PTDefinitionModel() :
893 mnCacheId( -1 ),
894 mnDataPosition( 0 ),
895 mnPageWrap( 0 ),
896 mnIndent( 1 ),
897 mnChartFormat( 0 ),
898 mbDataOnRows( false ),
899 mbShowError( false ),
900 mbShowMissing( true ),
901 mbShowItems( true ),
902 mbDisableFieldList( false ),
903 mbShowCalcMembers( true ),
904 mbVisualTotals( true ),
905 mbShowDrill( true ),
906 mbPrintDrill( false ),
907 mbEnableDrill( true ),
908 mbPreserveFormatting( true ),
909 mbUseAutoFormat( false ),
910 mbPageOverThenDown( false ),
911 mbSubtotalHiddenItems( false ),
912 mbRowGrandTotals( true ),
913 mbColGrandTotals( true ),
914 mbFieldPrintTitles( false ),
915 mbItemPrintTitles( false ),
916 mbMergeItem( false ),
917 mbShowEmptyRow( false ),
918 mbShowEmptyCol( false ),
919 mbShowHeaders( true ),
920 mbFieldListSortAsc( false ),
921 mbCustomListSort( true )
925 PTLocationModel::PTLocationModel() :
926 mnFirstHeaderRow( 0 ),
927 mnFirstDataRow( 0 ),
928 mnFirstDataCol( 0 ),
929 mnRowPageCount( 0 ),
930 mnColPageCount( 0 )
934 PivotTable::PivotTable( const WorkbookHelper& rHelper ) :
935 WorkbookHelper( rHelper ),
936 mpDPObject(nullptr),
937 maDataField( *this, OOX_PT_DATALAYOUTFIELD ),
938 mpPivotCache( nullptr )
942 void PivotTable::importPivotTableDefinition( const AttributeList& rAttribs )
944 maDefModel.maName = rAttribs.getXString( XML_name, OUString() );
945 maDefModel.maDataCaption = rAttribs.getXString( XML_dataCaption , OUString() );
946 maDefModel.maGrandTotalCaption = rAttribs.getXString( XML_grandTotalCaption, OUString() );
947 maDefModel.maRowHeaderCaption = rAttribs.getXString( XML_rowHeaderCaption, OUString() );
948 maDefModel.maColHeaderCaption = rAttribs.getXString( XML_colHeaderCaption, OUString() );
949 maDefModel.maErrorCaption = rAttribs.getXString( XML_errorCaption, OUString() );
950 maDefModel.maMissingCaption = rAttribs.getXString( XML_missingCaption, OUString() );
951 maDefModel.maPageStyle = rAttribs.getXString( XML_pageStyle, OUString() );
952 maDefModel.maPivotTableStyle = rAttribs.getXString( XML_pivotTableStyle, OUString() );
953 maDefModel.maVacatedStyle = rAttribs.getXString( XML_vacatedStyle, OUString() );
954 maDefModel.maTag = rAttribs.getXString( XML_tag, OUString() );
955 maDefModel.mnCacheId = rAttribs.getInteger( XML_cacheId, -1 );
956 maDefModel.mnDataPosition = rAttribs.getInteger( XML_dataPosition, 0 );
957 maDefModel.mnPageWrap = rAttribs.getInteger( XML_pageWrap, 0 );
958 maDefModel.mnIndent = rAttribs.getInteger( XML_indent, 1 );
959 maDefModel.mnChartFormat = rAttribs.getInteger( XML_chartFormat, 0 );
960 maDefModel.mnAutoFormatId = rAttribs.getInteger( XML_autoFormatId, 0 );
961 maDefModel.mbDataOnRows = rAttribs.getBool( XML_dataOnRows, false );
962 maDefModel.mbShowError = rAttribs.getBool( XML_showError, false );
963 maDefModel.mbShowMissing = rAttribs.getBool( XML_showMissing, true );
964 maDefModel.mbShowItems = rAttribs.getBool( XML_showItems, true );
965 maDefModel.mbDisableFieldList = rAttribs.getBool( XML_disableFieldList, false );
966 maDefModel.mbShowCalcMembers = rAttribs.getBool( XML_showCalcMbrs, true );
967 maDefModel.mbVisualTotals = rAttribs.getBool( XML_visualTotals, true );
968 maDefModel.mbShowDrill = rAttribs.getBool( XML_showDrill, true );
969 maDefModel.mbPrintDrill = rAttribs.getBool( XML_printDrill, false );
970 maDefModel.mbEnableDrill = rAttribs.getBool( XML_enableDrill, true );
971 maDefModel.mbPreserveFormatting = rAttribs.getBool( XML_preserveFormatting, true );
972 maDefModel.mbUseAutoFormat = rAttribs.getBool( XML_useAutoFormatting, false );
973 maDefModel.mbPageOverThenDown = rAttribs.getBool( XML_pageOverThenDown, false );
974 maDefModel.mbSubtotalHiddenItems = rAttribs.getBool( XML_subtotalHiddenItems, false );
975 maDefModel.mbRowGrandTotals = rAttribs.getBool( XML_rowGrandTotals, true );
976 maDefModel.mbColGrandTotals = rAttribs.getBool( XML_colGrandTotals, true );
977 maDefModel.mbFieldPrintTitles = rAttribs.getBool( XML_fieldPrintTitles, false );
978 maDefModel.mbItemPrintTitles = rAttribs.getBool( XML_itemPrintTitles, false );
979 maDefModel.mbMergeItem = rAttribs.getBool( XML_mergeItem, false );
980 maDefModel.mbShowEmptyRow = rAttribs.getBool( XML_showEmptyRow, false );
981 maDefModel.mbShowEmptyCol = rAttribs.getBool( XML_showEmptyCol, false );
982 maDefModel.mbShowHeaders = rAttribs.getBool( XML_showHeaders, true );
983 maDefModel.mbFieldListSortAsc = rAttribs.getBool( XML_fieldListSortAscending, false );
984 maDefModel.mbCustomListSort = rAttribs.getBool( XML_customListSort, true );
985 maDefModel.mbApplyNumFmt = rAttribs.getBool( XML_applyNumberFormats, false );
986 maDefModel.mbApplyFont = rAttribs.getBool( XML_applyFontFormats, false );
987 maDefModel.mbApplyAlignment = rAttribs.getBool( XML_applyAlignmentFormats, false );
988 maDefModel.mbApplyBorder = rAttribs.getBool( XML_applyBorderFormats, false );
989 maDefModel.mbApplyFill = rAttribs.getBool( XML_applyPatternFormats, false );
990 // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
991 maDefModel.mbApplyProtection = rAttribs.getBool( XML_applyWidthHeightFormats, false );
994 void PivotTable::importLocation( const AttributeList& rAttribs, sal_Int16 nSheet )
996 AddressConverter::convertToCellRangeUnchecked( maLocationModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet );
997 maLocationModel.mnFirstHeaderRow = rAttribs.getInteger( XML_firstHeaderRow, 0 );
998 maLocationModel.mnFirstDataRow = rAttribs.getInteger( XML_firstDataRow, 0 );
999 maLocationModel.mnFirstDataCol = rAttribs.getInteger( XML_firstDataCol, 0 );
1000 maLocationModel.mnRowPageCount = rAttribs.getInteger( XML_rowPageCount, 0 );
1001 maLocationModel.mnColPageCount = rAttribs.getInteger( XML_colPageCount, 0 );
1004 void PivotTable::importRowField( const AttributeList& rAttribs )
1006 importField( maRowFields, rAttribs );
1009 void PivotTable::importColField( const AttributeList& rAttribs )
1011 importField( maColFields, rAttribs );
1014 void PivotTable::importPageField( const AttributeList& rAttribs )
1016 PTPageFieldModel aModel;
1017 aModel.maName = rAttribs.getXString( XML_name, OUString() );
1018 aModel.mnField = rAttribs.getInteger( XML_fld, -1 );
1019 // specification is wrong, XML_item is not the cache item, but the field item
1020 aModel.mnItem = rAttribs.getInteger( XML_item, BIFF12_PTPAGEFIELD_MULTIITEMS );
1021 maPageFields.push_back( aModel );
1024 void PivotTable::importDataField( const AttributeList& rAttribs )
1026 PTDataFieldModel aModel;
1027 aModel.maName = rAttribs.getXString( XML_name, OUString() );
1028 aModel.mnField = rAttribs.getInteger( XML_fld, -1 );
1029 aModel.mnSubtotal = rAttribs.getToken( XML_subtotal, XML_sum );
1030 aModel.mnShowDataAs = rAttribs.getToken( XML_showDataAs, XML_normal );
1031 aModel.mnBaseField = rAttribs.getInteger( XML_baseField, -1 );
1032 aModel.mnBaseItem = rAttribs.getInteger( XML_baseItem, -1 );
1033 aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
1034 maDataFields.push_back( aModel );
1037 void PivotTable::importPTDefinition( SequenceInputStream& rStrm )
1039 sal_uInt32 nFlags1, nFlags2, nFlags3;
1040 sal_uInt8 nDataAxis;
1041 nFlags1 = rStrm.readuInt32();
1042 nFlags2 = rStrm.readuInt32();
1043 nFlags3 = rStrm.readuInt32();
1044 nDataAxis = rStrm.readuChar();
1045 maDefModel.mnPageWrap = rStrm.readuInt8();
1046 rStrm.skip( 2 ); // refresh versions
1047 maDefModel.mnDataPosition = rStrm.readInt32();
1048 maDefModel.mnAutoFormatId = rStrm.readuInt16();
1049 rStrm.skip( 2 ); // unused
1050 maDefModel.mnChartFormat = rStrm.readInt32();
1051 maDefModel.mnCacheId = rStrm.readInt32();
1052 rStrm >> maDefModel.maName;
1053 if( getFlag( nFlags2, BIFF12_PTDEF_HASDATACAPTION ) )
1054 rStrm >> maDefModel.maDataCaption;
1055 if( getFlag( nFlags2, BIFF12_PTDEF_HASGRANDTOTALCAPTION ) )
1056 rStrm >> maDefModel.maGrandTotalCaption;
1057 if( !getFlag( nFlags3, BIFF12_PTDEF_NOERRORCAPTION ) ) // missing flag indicates existing string
1058 rStrm >> maDefModel.maErrorCaption;
1059 if( !getFlag( nFlags3, BIFF12_PTDEF_NOMISSINGCAPTION ) ) // missing flag indicates existing string
1060 rStrm >> maDefModel.maMissingCaption;
1061 if( getFlag( nFlags2, BIFF12_PTDEF_HASPAGESTYLE ) )
1062 rStrm >> maDefModel.maPageStyle;
1063 if( getFlag( nFlags2, BIFF12_PTDEF_HASPIVOTTABLESTYLE ) )
1064 rStrm >> maDefModel.maPivotTableStyle;
1065 if( getFlag( nFlags2, BIFF12_PTDEF_HASVACATEDSTYLE ) )
1066 rStrm >> maDefModel.maVacatedStyle;
1067 if( getFlag( nFlags2, BIFF12_PTDEF_HASTAG ) )
1068 rStrm >> maDefModel.maTag;
1069 if( getFlag( nFlags3, BIFF12_PTDEF_HASCOLHEADERCAPTION ) ) // TODO: right order (col/row)? spec is unclear
1070 rStrm >> maDefModel.maColHeaderCaption;
1071 if( getFlag( nFlags3, BIFF12_PTDEF_HASROWHEADERCAPTION ) )
1072 rStrm >> maDefModel.maRowHeaderCaption;
1074 SAL_WARN_IF(
1075 (nDataAxis != BIFF12_PTDEF_ROWAXIS) && (nDataAxis != BIFF12_PTDEF_COLAXIS),
1076 "sc.filter",
1077 "PivotTable::importPTDefinition - unexpected axis position for data field");
1079 maDefModel.mnIndent = extractValue< sal_uInt8 >( nFlags1, 24, 7 );
1080 maDefModel.mbDataOnRows = nDataAxis == BIFF12_PTDEF_ROWAXIS;
1081 maDefModel.mbShowError = getFlag( nFlags2, BIFF12_PTDEF_SHOWERROR );
1082 maDefModel.mbShowMissing = getFlag( nFlags2, BIFF12_PTDEF_SHOWMISSING );
1083 maDefModel.mbShowItems = getFlag( nFlags1, BIFF12_PTDEF_SHOWITEMS );
1084 maDefModel.mbDisableFieldList = getFlag( nFlags1, BIFF12_PTDEF_DISABLEFIELDLIST );
1085 maDefModel.mbShowCalcMembers = !getFlag( nFlags1, BIFF12_PTDEF_HIDECALCMEMBERS );
1086 maDefModel.mbVisualTotals = !getFlag( nFlags1, BIFF12_PTDEF_WITHHIDDENTOTALS );
1087 maDefModel.mbShowDrill = !getFlag( nFlags1, BIFF12_PTDEF_HIDEDRILL );
1088 maDefModel.mbPrintDrill = getFlag( nFlags1, BIFF12_PTDEF_PRINTDRILL );
1089 maDefModel.mbEnableDrill = getFlag( nFlags2, BIFF12_PTDEF_ENABLEDRILL );
1090 maDefModel.mbPreserveFormatting = getFlag( nFlags2, BIFF12_PTDEF_PRESERVEFORMATTING );
1091 maDefModel.mbUseAutoFormat = getFlag( nFlags2, BIFF12_PTDEF_USEAUTOFORMAT );
1092 maDefModel.mbPageOverThenDown = getFlag( nFlags2, BIFF12_PTDEF_PAGEOVERTHENDOWN );
1093 maDefModel.mbSubtotalHiddenItems = getFlag( nFlags2, BIFF12_PTDEF_SUBTOTALHIDDENITEMS );
1094 maDefModel.mbRowGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_ROWGRANDTOTALS );
1095 maDefModel.mbColGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_COLGRANDTOTALS );
1096 maDefModel.mbFieldPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_FIELDPRINTTITLES );
1097 maDefModel.mbItemPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_ITEMPRINTTITLES );
1098 maDefModel.mbMergeItem = getFlag( nFlags2, BIFF12_PTDEF_MERGEITEM );
1099 maDefModel.mbApplyNumFmt = getFlag( nFlags2, BIFF12_PTDEF_APPLYNUMFMT );
1100 maDefModel.mbApplyFont = getFlag( nFlags2, BIFF12_PTDEF_APPLYFONT );
1101 maDefModel.mbApplyAlignment = getFlag( nFlags2, BIFF12_PTDEF_APPLYALIGNMENT );
1102 maDefModel.mbApplyBorder = getFlag( nFlags2, BIFF12_PTDEF_APPLYBORDER );
1103 maDefModel.mbApplyFill = getFlag( nFlags2, BIFF12_PTDEF_APPLYFILL );
1104 maDefModel.mbApplyProtection = getFlag( nFlags2, BIFF12_PTDEF_APPLYPROTECTION );
1105 maDefModel.mbShowEmptyRow = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYROW );
1106 maDefModel.mbShowEmptyCol = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYCOL );
1107 maDefModel.mbShowHeaders = !getFlag( nFlags1, BIFF12_PTDEF_HIDEHEADERS );
1108 maDefModel.mbFieldListSortAsc = getFlag( nFlags3, BIFF12_PTDEF_FIELDLISTSORTASC );
1109 maDefModel.mbCustomListSort = !getFlag( nFlags3, BIFF12_PTDEF_NOCUSTOMLISTSORT );
1112 void PivotTable::importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet )
1114 BinRange aBinRange;
1115 rStrm >> aBinRange;
1116 maLocationModel.mnFirstHeaderRow = rStrm.readInt32();
1117 maLocationModel.mnFirstDataRow = rStrm.readInt32();
1118 maLocationModel.mnFirstDataCol = rStrm.readInt32();
1119 maLocationModel.mnRowPageCount = rStrm.readInt32();
1120 maLocationModel.mnColPageCount = rStrm.readInt32();
1121 AddressConverter::convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
1124 void PivotTable::importPTRowFields( SequenceInputStream& rStrm )
1126 importFields( maRowFields, rStrm );
1129 void PivotTable::importPTColFields( SequenceInputStream& rStrm )
1131 importFields( maColFields, rStrm );
1134 void PivotTable::importPTPageField( SequenceInputStream& rStrm )
1136 PTPageFieldModel aModel;
1137 sal_uInt8 nFlags;
1138 aModel.mnField = rStrm.readInt32();
1139 aModel.mnItem = rStrm.readInt32();
1140 rStrm.skip( 4 ); // hierarchy
1141 nFlags = rStrm.readuChar();
1142 if( getFlag( nFlags, BIFF12_PTPAGEFIELD_HASNAME ) )
1143 rStrm >> aModel.maName;
1144 maPageFields.push_back( aModel );
1147 void PivotTable::importPTDataField( SequenceInputStream& rStrm )
1149 PTDataFieldModel aModel;
1150 sal_Int32 nSubtotal, nShowDataAs;
1151 sal_uInt8 nHasName;
1152 aModel.mnField = rStrm.readInt32( );
1153 nSubtotal = rStrm.readInt32();
1154 nShowDataAs = rStrm.readInt32();
1155 aModel.mnBaseField = rStrm.readInt32();
1156 aModel.mnBaseItem = rStrm.readInt32();
1157 aModel.mnNumFmtId = rStrm.readInt32();
1158 nHasName = rStrm.readuChar();
1159 if( nHasName == 1 )
1160 rStrm >> aModel.maName;
1161 aModel.setBiffSubtotal( nSubtotal );
1162 aModel.setBiffShowDataAs( nShowDataAs );
1163 maDataFields.push_back( aModel );
1166 PivotTableField& PivotTable::createTableField()
1168 sal_Int32 nFieldIndex = static_cast< sal_Int32 >( maFields.size() );
1169 PivotTableFieldVector::value_type xTableField( new PivotTableField( *this, nFieldIndex ) );
1170 maFields.push_back( xTableField );
1171 return *xTableField;
1174 PivotTableFilter& PivotTable::createTableFilter()
1176 PivotTableFilterVector::value_type xTableFilter( new PivotTableFilter( *this ) );
1177 maFilters.push_back( xTableFilter );
1178 return *xTableFilter;
1181 void PivotTable::finalizeImport()
1183 if( getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) )
1185 mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId );
1186 if( mpPivotCache && mpPivotCache->isValidDataSource() && !maDefModel.maName.isEmpty() )
1188 // clear destination area of the original pivot table
1191 Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW );
1192 using namespace ::com::sun::star::sheet::CellFlags;
1193 xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED );
1195 catch( Exception& )
1201 // create a new data pilot descriptor based on the source data
1202 Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.Sheet ), UNO_QUERY_THROW );
1203 Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW );
1204 mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW );
1205 mxDPDescriptor->setSourceRange( mpPivotCache->getSourceRange() );
1206 mxDPDescriptor->setTag( maDefModel.maTag );
1208 // TODO: This is a hack. Eventually we need to convert the whole thing to the internal API.
1209 ScDataPilotDescriptorBase* pImpl = ScDataPilotDescriptorBase::getImplementation(mxDPDescriptor);
1210 if (!pImpl)
1211 return;
1213 mpDPObject = pImpl->GetDPObject();
1214 if (!mpDPObject)
1215 return;
1217 // global data pilot properties
1218 PropertySet aDescProp( mxDPDescriptor );
1219 aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals );
1220 aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals );
1221 aDescProp.setProperty( PROP_ShowFilterButton, false );
1222 aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill );
1224 // finalize all fields, this finds field names and creates grouping fields
1225 finalizeFieldsImport();
1227 // all row fields
1228 for( IndexVector::iterator aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
1229 if( PivotTableField* pField = getTableField( *aIt ) )
1230 pField->convertRowField();
1232 // all column fields
1233 for( IndexVector::iterator aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt )
1234 if( PivotTableField* pField = getTableField( *aIt ) )
1235 pField->convertColField();
1237 // all page fields
1238 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
1239 if( PivotTableField* pField = getTableField( aIt->mnField ) )
1240 pField->convertPageField( *aIt );
1242 // all hidden fields
1243 ::std::set< sal_Int32 > aVisFields;
1244 aVisFields.insert( maRowFields.begin(), maRowFields.end() );
1245 aVisFields.insert( maColFields.begin(), maColFields.end() );
1246 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
1247 aVisFields.insert( aIt->mnField );
1248 for( PivotTableFieldVector::iterator aBeg = maFields.begin(), aIt = aBeg, aEnd = maFields.end(); aIt != aEnd; ++aIt )
1249 if( aVisFields.count( static_cast< sal_Int32 >( aIt - aBeg ) ) == 0 )
1250 (*aIt)->convertHiddenField();
1252 // all data fields
1253 for( DataFieldVector::iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
1255 if( const PivotCacheField* pCacheField = getCacheField( aIt->mnField ) )
1257 if ( pCacheField-> getGroupBaseField() != -1 )
1258 aIt->mnField = pCacheField-> getGroupBaseField();
1260 if( PivotTableField* pField = getTableField( aIt->mnField ) )
1261 pField->convertDataField( *aIt );
1264 // filters
1265 maFilters.forEachMem( &PivotTableFilter::finalizeImport );
1267 // calculate base position of table
1268 CellAddress aPos( maLocationModel.maRange.Sheet, maLocationModel.maRange.StartColumn, maLocationModel.maRange.StartRow );
1269 /* If page fields exist, include them into the destination
1270 area (they are excluded in Excel). Add an extra blank row. */
1271 if( !maPageFields.empty() )
1272 aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 );
1274 // insert the DataPilot table into the sheet
1275 xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
1277 catch( Exception& )
1279 OSL_FAIL( "PivotTable::finalizeImport - exception while creating the DataPilot table" );
1285 void PivotTable::finalizeFieldsImport()
1287 if (maFields.empty())
1288 return;
1290 /* Check whether group fields are already imported for an other table
1291 sharing the same groups. */
1292 ScDPObject* pDPObj = getDPObject();
1293 const ScDocument& rDoc = getDocImport().getDoc();
1294 if (rDoc.HasPivotTable())
1296 const ScDPCollection* pDPCollection = rDoc.GetDPCollection();
1297 assert(pDPCollection != nullptr);
1298 const ScDPDimensionSaveData* pGroups = nullptr;
1299 bool bRefFound = pDPCollection->GetReferenceGroups(*pDPObj, &pGroups);
1300 // Apply reference groups on this table.
1301 if (bRefFound && pGroups && pGroups->HasGroupDimensions()) {
1302 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1303 if (pSaveData) {
1304 pSaveData->SetDimensionData(pGroups);
1305 pDPObj->ReloadGroupTableData();
1306 maFields.forEachMem(&PivotTableField::finalizeImportBasedOnCache, ::std::cref(mxDPDescriptor));
1307 return;
1312 maFields.forEachMem(&PivotTableField::finalizeImport, ::std::cref(mxDPDescriptor));
1315 void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
1317 // process all fields, there is no chaining information in the cache fields
1318 maFields.forEachMem( &PivotTableField::finalizeDateGroupingImport, ::std::cref(rxBaseDPField), nBaseFieldIdx );
1321 void PivotTable::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField,
1322 const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
1324 // try to create parent group fields that group the items of the passed base field
1325 if( PivotTableField* pParentTableField = maFields.get( rBaseCacheField.getParentGroupField() ).get() )
1326 pParentTableField->finalizeParentGroupingImport( rxBaseDPField, rBaseCacheField, orItemNames );
1329 Reference< XDataPilotField > PivotTable::getDataPilotField( const OUString& rFieldName ) const
1331 Reference< XDataPilotField > xDPField;
1332 if( !rFieldName.isEmpty() && mxDPDescriptor.is() ) try
1334 Reference< XNameAccess > xDPFieldsNA( mxDPDescriptor->getDataPilotFields(), UNO_QUERY_THROW );
1335 xDPField.set( xDPFieldsNA->getByName( rFieldName ), UNO_QUERY );
1337 catch( Exception& )
1340 return xDPField;
1343 Reference< XDataPilotField > PivotTable::getDataPilotField( sal_Int32 nFieldIdx ) const
1345 Reference< XDataPilotField > xDPField;
1346 if( const PivotTableField* pTableField = maFields.get( nFieldIdx ).get() )
1347 xDPField = getDataPilotField( pTableField->getDPFieldName() );
1348 return xDPField;
1351 Reference< XDataPilotField > PivotTable::getDataLayoutField() const
1353 Reference< XDataPilotField > xDPField;
1356 Reference< XDataPilotDataLayoutFieldSupplier > xDPDataFieldSupp( mxDPDescriptor, UNO_QUERY_THROW );
1357 xDPField = xDPDataFieldSupp->getDataLayoutField();
1359 catch( Exception& )
1362 return xDPField;
1365 PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx )
1367 return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : nullptr;
1370 const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const
1372 return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : nullptr;
1375 const PivotCacheField* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const
1377 const PTDataFieldModel* pDataField = ContainerHelper::getVectorElement( maDataFields, nDataItemIdx );
1378 return pDataField ? getCacheField( pDataField->mnField ) : nullptr;
1381 sal_Int32 PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
1383 return mpPivotCache ? mpPivotCache->getCacheDatabaseIndex( nFieldIdx ) : -1;
1386 // private --------------------------------------------------------------------
1388 PivotTableField* PivotTable::getTableField( sal_Int32 nFieldIdx )
1390 return (nFieldIdx == OOX_PT_DATALAYOUTFIELD) ? &maDataField : maFields.get( nFieldIdx ).get();
1393 void PivotTable::importField( IndexVector& orFields, const AttributeList& rAttribs )
1395 orFields.push_back( rAttribs.getInteger( XML_x, -1 ) );
1398 void PivotTable::importFields( IndexVector& orFields, SequenceInputStream& rStrm )
1400 OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
1401 orFields.clear();
1402 sal_Int32 nCount = rStrm.readInt32();
1403 OSL_ENSURE( 4 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
1404 nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 4 );
1405 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
1406 orFields.push_back( rStrm.readInt32() );
1409 PivotTableBuffer::PivotTableBuffer( const WorkbookHelper& rHelper ) :
1410 WorkbookHelper( rHelper )
1414 PivotTable& PivotTableBuffer::createPivotTable()
1416 PivotTableVector::value_type xTable( new PivotTable( *this ) );
1417 maTables.push_back( xTable );
1418 return *xTable;
1421 void PivotTableBuffer::finalizeImport()
1423 maTables.forEachMem( &PivotTable::finalizeImport );
1426 } // namespace xls
1427 } // namespace oox
1429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */