LibreOffice Module sc (master)  1
pivottablebuffer.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <pivottablebuffer.hxx>
21 
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/XDataPilotTablesSupplier.hpp>
39 #include <com/sun/star/sheet/XSheetOperation.hpp>
40 #include <com/sun/star/xml/sax/XFastAttributeList.hpp>
41 #include <osl/diagnose.h>
42 #include <tools/diagnose_ex.h>
43 #include <sal/log.hxx>
48 #include <oox/token/properties.hxx>
49 #include <oox/token/tokens.hxx>
50 #include <addressconverter.hxx>
51 #include <biffhelper.hxx>
52 
53 #include <dapiuno.hxx>
54 #include <dpobject.hxx>
55 #include <dpsave.hxx>
56 #include <dpdimsave.hxx>
57 #include <document.hxx>
58 #include <documentimport.hxx>
59 #include <workbooksettings.hxx>
60 
61 namespace oox::xls {
62 
63 using namespace ::com::sun::star::container;
64 using namespace ::com::sun::star::sheet;
65 using namespace ::com::sun::star::table;
66 using namespace ::com::sun::star::uno;
67 
68 namespace {
69 
70 const sal_Int32 OOX_PT_DATALAYOUTFIELD = -2;
71 
72 const sal_Int32 OOX_PT_PREVIOUS_ITEM = 0x001000FC;
73 const sal_Int32 OOX_PT_NEXT_ITEM = 0x001000FD;
74 
75 const sal_uInt32 BIFF12_PTFIELD_DATAFIELD = 0x00000008;
76 const sal_uInt32 BIFF12_PTFIELD_DEFAULT = 0x00000100;
77 const sal_uInt32 BIFF12_PTFIELD_SUM = 0x00000200;
78 const sal_uInt32 BIFF12_PTFIELD_COUNTA = 0x00000400;
79 const sal_uInt32 BIFF12_PTFIELD_AVERAGE = 0x00000800;
80 const sal_uInt32 BIFF12_PTFIELD_MAX = 0x00001000;
81 const sal_uInt32 BIFF12_PTFIELD_MIN = 0x00002000;
82 const sal_uInt32 BIFF12_PTFIELD_PRODUCT = 0x00004000;
83 const sal_uInt32 BIFF12_PTFIELD_COUNT = 0x00008000;
84 const sal_uInt32 BIFF12_PTFIELD_STDDEV = 0x00010000;
85 const sal_uInt32 BIFF12_PTFIELD_STDDEVP = 0x00020000;
86 const sal_uInt32 BIFF12_PTFIELD_VAR = 0x00040000;
87 const sal_uInt32 BIFF12_PTFIELD_VARP = 0x00080000;
88 
89 const sal_uInt32 BIFF12_PTFIELD_SHOWALL = 0x00000020;
90 const sal_uInt32 BIFF12_PTFIELD_OUTLINE = 0x00000040;
91 const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW = 0x00000080;
92 const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP = 0x00000100;
93 const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK = 0x00000800;
94 const sal_uInt32 BIFF12_PTFIELD_AUTOSORT = 0x00001000;
95 const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING = 0x00002000;
96 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW = 0x00004000;
97 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP = 0x00008000;
98 const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS = 0x00080000;
99 
100 const sal_uInt16 BIFF12_PTFITEM_HIDDEN = 0x0001;
101 const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS = 0x0002;
102 
103 const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME = 0x01;
104 const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS = 0x001000FE;
105 
106 const sal_uInt16 BIFF12_PTFILTER_HASNAME = 0x0001;
107 const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION = 0x0002;
108 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1 = 0x0004;
109 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2 = 0x0008;
110 
111 const sal_uInt8 BIFF12_TOP10FILTER_TOP = 0x01;
112 const sal_uInt8 BIFF12_TOP10FILTER_PERCENT = 0x02;
113 
114 const sal_uInt32 BIFF12_PTDEF_SHOWITEMS = 0x00000100;
115 const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST = 0x00000400;
116 const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS = 0x00001000;
117 const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS = 0x00002000;
118 const sal_uInt32 BIFF12_PTDEF_HIDEDRILL = 0x00100000;
119 const sal_uInt32 BIFF12_PTDEF_PRINTDRILL = 0x00200000;
120 const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS = 0x80000000;
121 
122 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW = 0x00000004;
123 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL = 0x00000008;
124 const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL = 0x00000020;
125 const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING = 0x00000080;
126 const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT = 0x00000100;
127 const sal_uInt32 BIFF12_PTDEF_SHOWERROR = 0x00000200;
128 const sal_uInt32 BIFF12_PTDEF_SHOWMISSING = 0x00000400;
129 const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN = 0x00000800;
130 const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS = 0x00001000;
131 const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS = 0x00002000;
132 const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS = 0x00004000;
133 const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES = 0x00008000;
134 const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES = 0x00020000;
135 const sal_uInt32 BIFF12_PTDEF_MERGEITEM = 0x00040000;
136 const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION = 0x00080000;
137 const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION = 0x00100000;
138 const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE = 0x00200000;
139 const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE = 0x00400000;
140 const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE = 0x00800000;
141 const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT = 0x01000000;
142 const sal_uInt32 BIFF12_PTDEF_APPLYFONT = 0x02000000;
143 const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT = 0x04000000;
144 const sal_uInt32 BIFF12_PTDEF_APPLYBORDER = 0x08000000;
145 const sal_uInt32 BIFF12_PTDEF_APPLYFILL = 0x10000000;
146 const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION = 0x20000000;
147 const sal_uInt32 BIFF12_PTDEF_HASTAG = 0x40000000;
148 
149 const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION = 0x00000040;
150 const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION = 0x00000080;
151 const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION = 0x00000400;
152 const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION = 0x00000800;
153 const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC = 0x00001000;
154 const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT = 0x00004000;
155 
156 const sal_uInt8 BIFF12_PTDEF_ROWAXIS = 1;
157 const sal_uInt8 BIFF12_PTDEF_COLAXIS = 2;
158 
159 } // namespace
160 
162  mnCacheItem( -1 ),
163  mnType( XML_data ),
164  mbShowDetails( true ),
165  mbHidden( false )
166 {
167 }
168 
170 {
171  static const sal_Int32 spnTypes[] = { XML_data, XML_default,
172  XML_sum, XML_countA, XML_avg, XML_max, XML_min, XML_product, XML_count,
173  XML_stdDev, XML_stdDevP, XML_var, XML_varP, XML_grand, XML_blank };
174  mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_data );
175 }
176 
178  mnAxis( XML_TOKEN_INVALID ),
179  mnNumFmtId( 0 ),
180  mnAutoShowItems( 10 ),
181  mnAutoShowRankBy( -1 ),
182  mnSortType( XML_manual ),
183  mnSortRefField( -1 ),
184  mnSortRefItem( -1 ),
185  mbDataField( false ),
186  mbDefaultSubtotal( true ),
187  mbSumSubtotal( false ),
188  mbCountASubtotal( false ),
189  mbAverageSubtotal( false ),
190  mbMaxSubtotal( false ),
191  mbMinSubtotal( false ),
192  mbProductSubtotal( false ),
193  mbCountSubtotal( false ),
194  mbStdDevSubtotal( false ),
195  mbStdDevPSubtotal( false ),
196  mbVarSubtotal( false ),
197  mbVarPSubtotal( false ),
198  mbShowAll( true ),
199  mbOutline( true ),
200  mbSubtotalTop( true ),
201  mbInsertBlankRow( false ),
202  mbInsertPageBreak( false ),
203  mbAutoShow( false ),
204  mbTopAutoShow( true ),
205  mbMultiPageItems( false )
206 {
207 }
208 
210 {
211  /* Weird. The axis field is organized as bit field, but only one of the
212  row/col/page flags are allowed at the same time and refer to the values
213  'axisRow', 'axisCol', and 'axisPage' of the XML attribute
214  'pivotField@axis'. Additionally, the fourth bit determines if the field
215  is a data field, which may appear combined with the row/col/page flags.
216  Therefore, this bit is unrelated to the 'axisValues' value of the
217  'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
218  boolean attribute. */
219  static const sal_Int32 spnAxisIds[] = { XML_TOKEN_INVALID, XML_axisRow, XML_axisCol, XML_TOKEN_INVALID, XML_axisPage };
220  mnAxis = STATIC_ARRAY_SELECT( spnAxisIds, nAxis, XML_TOKEN_INVALID );
221 }
222 
224  mnField( -1 ),
225  mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS )
226 {
227 }
228 
230  mnField( -1 ),
231  mnSubtotal( XML_sum ),
232  mnShowDataAs( XML_normal ),
233  mnBaseField( -1 ),
234  mnBaseItem( -1 ),
235  mnNumFmtId( 0 )
236 {
237 }
238 
239 void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal )
240 {
241  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 };
242  mnSubtotal = STATIC_ARRAY_SELECT( spnSubtotals, nSubtotal, XML_TOKEN_INVALID );
243 }
244 
245 void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs )
246 {
247  static const sal_Int32 spnShowDataAs[] = { XML_normal, XML_difference, XML_percent, XML_percentDiff, XML_runTotal, XML_percentOfRow, XML_percentOfCol, XML_percentOfTotal, XML_index };
248  mnShowDataAs = STATIC_ARRAY_SELECT( spnShowDataAs, nShowDataAs, XML_TOKEN_INVALID );
249 }
250 
251 PivotTableField::PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex ) :
252  WorkbookHelper( rPivotTable ),
253  mrPivotTable( rPivotTable ),
254  mnFieldIndex( nFieldIndex )
255 {
256 }
257 
259 {
260  /* The documentation mentions a value 'axisValues' for the attribute
261  'pivotField@axis'. But this value is not used to mark a data field, as
262  data fields may be inserted in one of the row/column/page dimensions at
263  the same time. Therefore, the boolean attribute 'pivotField@dataField'
264  is really used to mark data fields. */
265  maModel.mnAxis = rAttribs.getToken( XML_axis, XML_TOKEN_INVALID );
266  maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
267  maModel.mnAutoShowItems = rAttribs.getInteger( XML_itemPageCount, 10 );
268  maModel.mnAutoShowRankBy = rAttribs.getInteger( XML_rankBy, -1 );
269  maModel.mnSortType = rAttribs.getToken( XML_sortType, XML_manual );
270  maModel.mbDataField = rAttribs.getBool( XML_dataField, false );
271  maModel.mbDefaultSubtotal = rAttribs.getBool( XML_defaultSubtotal, true );
272  maModel.mbSumSubtotal = rAttribs.getBool( XML_sumSubtotal, false );
273  maModel.mbCountASubtotal = rAttribs.getBool( XML_countASubtotal, false );
274  maModel.mbAverageSubtotal = rAttribs.getBool( XML_avgSubtotal, false );
275  maModel.mbMaxSubtotal = rAttribs.getBool( XML_maxSubtotal, false );
276  maModel.mbMinSubtotal = rAttribs.getBool( XML_minSubtotal, false );
277  maModel.mbProductSubtotal = rAttribs.getBool( XML_productSubtotal, false );
278  maModel.mbCountSubtotal = rAttribs.getBool( XML_countSubtotal, false );
279  maModel.mbStdDevSubtotal = rAttribs.getBool( XML_stdDevSubtotal, false );
280  maModel.mbStdDevPSubtotal = rAttribs.getBool( XML_stdDevPSubtotal, false );
281  maModel.mbVarSubtotal = rAttribs.getBool( XML_varSubtotal, false );
282  maModel.mbVarPSubtotal = rAttribs.getBool( XML_varPSubtotal, false );
283  maModel.mbShowAll = rAttribs.getBool( XML_showAll, true );
284  maModel.mbOutline = rAttribs.getBool( XML_outline, true );
285  maModel.mbSubtotalTop = rAttribs.getBool( XML_subtotalTop, true );
286  maModel.mbInsertBlankRow = rAttribs.getBool( XML_insertBlankRow, false );
287  maModel.mbInsertPageBreak = rAttribs.getBool( XML_insertPageBreak, false );
288  maModel.mbAutoShow = rAttribs.getBool( XML_autoShow, false );
289  maModel.mbTopAutoShow = rAttribs.getBool( XML_topAutoShow, true );
290  maModel.mbMultiPageItems = rAttribs.getBool( XML_multipleItemSelectionAllowed, false );
291 }
292 
294 {
295  PTFieldItemModel aModel;
296  aModel.mnCacheItem = rAttribs.getInteger( XML_x, -1 );
297  aModel.mnType = rAttribs.getToken( XML_t, XML_data );
298  aModel.mbShowDetails = rAttribs.getBool( XML_sd, true );
299  aModel.mbHidden = rAttribs.getBool( XML_h, false );
300  aModel.msCaption = rAttribs.getXString( XML_n, OUString() );
301  maItems.push_back( aModel );
302 }
303 
305 {
306  // field index is stored as unsigned integer
307  maModel.mnSortRefField = static_cast< sal_Int32 >( rAttribs.getUnsigned( XML_field, SAL_MAX_UINT32 ) );
308 }
309 
311 {
312  maModel.mnSortRefItem = rAttribs.getInteger( XML_v, -1 );
313 }
314 
316 {
317  sal_uInt32 nFlags1, nFlags2;
318  nFlags1 = rStrm.readuInt32();
319  maModel.mnNumFmtId = rStrm.readInt32();
320  nFlags2 = rStrm.readuInt32();
323 
324  maModel.setBiffAxis( extractValue< sal_uInt8 >( nFlags1, 0, 3 ) );
325  maModel.mbDataField = getFlag( nFlags1, BIFF12_PTFIELD_DATAFIELD );
326  maModel.mbDefaultSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_DEFAULT );
327  maModel.mbSumSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_SUM );
328  maModel.mbCountASubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNTA );
329  maModel.mbAverageSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_AVERAGE );
330  maModel.mbMaxSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MAX );
331  maModel.mbMinSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MIN );
332  maModel.mbProductSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_PRODUCT );
333  maModel.mbCountSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNT );
334  maModel.mbStdDevSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEV );
335  maModel.mbStdDevPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEVP );
336  maModel.mbVarSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VAR );
337  maModel.mbVarPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VARP );
338 
339  maModel.mbShowAll = getFlag( nFlags2, BIFF12_PTFIELD_SHOWALL );
340  maModel.mbOutline = getFlag( nFlags2, BIFF12_PTFIELD_OUTLINE );
341  maModel.mbSubtotalTop = getFlag( nFlags2, BIFF12_PTFIELD_SUBTOTALTOP );
342  maModel.mbInsertBlankRow = getFlag( nFlags2, BIFF12_PTFIELD_INSERTBLANKROW );
343  maModel.mbInsertPageBreak = getFlag( nFlags2, BIFF12_PTFIELD_INSERTPAGEBREAK );
344  maModel.mbAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOW );
345  maModel.mbTopAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOWTOP );
346  maModel.mbMultiPageItems = getFlag( nFlags2, BIFF12_PTFIELD_MULTIPAGEITEMS );
347 
348  bool bAutoSort = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSORT );
349  bool bAscending = getFlag( nFlags2, BIFF12_PTFIELD_SORTASCENDING );
350  maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
351 }
352 
354 {
355  PTFieldItemModel aModel;
357  sal_uInt16 nFlags;
358  nType = rStrm.readuChar();
359  nFlags = rStrm.readuInt16();
360  aModel.mnCacheItem = rStrm.readInt32();
361 
362  aModel.setBiffType( nType );
363  aModel.mbShowDetails = !getFlag( nFlags, BIFF12_PTFITEM_HIDEDETAILS );
364  aModel.mbHidden = getFlag( nFlags, BIFF12_PTFITEM_HIDDEN );
365 
366  maItems.push_back( aModel );
367 }
368 
370 {
371  maModel.mnSortRefField = rStrm.readInt32();
372 }
373 
375 {
376  maModel.mnSortRefItem = rStrm.readInt32();
377 }
378 
379 void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& rxDPDesc )
380 {
381  /* Process all fields based on source data, other fields (e.g. group
382  fields) are processed from here. PivotCache::getCacheDatabaseIndex()
383  returns -1 for all fields not based on source data. */
384  Reference< XDataPilotField > xDPField;
385  sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
386  if( !((nDatabaseIdx >= 0) && rxDPDesc.is()) )
387  return;
388 
389  try
390  {
391  // try to get the source field and its name from passed DataPilot descriptor
392  Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
393  xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
394  Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
395  maDPFieldName = xDPFieldName->getName();
396  OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeImport - no field name in source data found" );
397 
398  // try to convert grouping settings
399  if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
400  {
401  // numeric grouping is done inplace, no nested group fields will appear
402  if( pCacheField->hasNumericGrouping() )
403  {
404  pCacheField->convertNumericGrouping( xDPField );
405  }
406  else if( pCacheField->hasDateGrouping() )
407  {
408  // first date group settings are inplace
409  pCacheField->createDateGroupField( xDPField );
410  // create all nested group fields (if any)
412  }
413  else if( pCacheField->hasParentGrouping() )
414  {
415 
416  // create a list of all item names, needed to map between original and group items
417  ::std::vector< OUString > aItems;
418  pCacheField->getCacheItemNames( aItems );
419  PivotCacheGroupItemVector aItemNames;
420  for( const auto& rItem : aItems )
421  aItemNames.emplace_back( rItem );
422  // create all nested group fields (if any)
423  mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, aItemNames );
424  }
425  }
426  }
427  catch( Exception& )
428  {
429  }
430 }
431 
432 void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
433 {
434  if( maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken
435  {
437  {
438  if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) )
439  {
440  maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField );
441  pCacheField->setFinalGroupName(maDPFieldName);
442  OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
443  }
444  }
445  }
446 }
447 
448 void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
449 {
450  if( !maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken
451  return;
452 
454  if( !pCacheField )
455  return;
456 
457  // data field can have user defined groupname captions, apply them
458  // if they do
459  IdCaptionPairList captionList;
460  for( const auto& rItem : maItems )
461  {
462  if ( rItem.mnType == XML_data && rItem.msCaption.getLength() )
463  captionList.emplace_back( rItem.mnCacheItem, rItem.msCaption );
464  }
465  if ( !captionList.empty() )
466  pCacheField->applyItemCaptions( captionList );
467 
468  maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, rBaseCacheField, orItemNames );
469  pCacheField->setFinalGroupName(maDPFieldName);
470  // on success, try to create nested group fields
471  Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
472  if( xDPField.is() )
473  mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames );
474 }
475 
476 void PivotTableField::finalizeImportBasedOnCache( const Reference< XDataPilotDescriptor >& rxDPDesc)
477 {
478  /* Process all fields based on source data, other fields (e.g. group
479  fields) are processed based on cache fields.*/
480  Reference< XDataPilotField > xDPField;
481  sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
482  if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
483  {
484  // Try to get the source field and its name from passed DataPilot descriptor
485  Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
486  xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
487  Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
488  maDPFieldName = xDPFieldName->getName();
489  SAL_WARN_IF( maDPFieldName.isEmpty(), "sc.filter", "PivotTableField::finalizeImportBasedOnCache - no field name in source data found" );
490  }
491  catch( Exception& )
492  {
493  }
494 
495  // Use group names already generated for another table using the same group field.
496  if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
497  {
498  if(!pCacheField->getFinalGroupName().isEmpty())
499  maDPFieldName = pCacheField->getFinalGroupName();
500  }
501 }
502 
504 {
505  convertRowColPageField( XML_axisRow );
506 }
507 
509 {
510  convertRowColPageField( XML_axisCol );
511 }
512 
514 {
516 }
517 
519 {
520  OSL_ENSURE( rPageField.mnField == mnFieldIndex, "PivotTableField::convertPageField - wrong field index" );
521  // convert all settings common for row/column/page fields
522  Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage );
523 
524  if( !xDPField.is() )
525  return;
526 
527  PropertySet aPropSet( xDPField );
528 
529  // find cache item used as 'selected page'
530  sal_Int32 nCacheItem = -1;
532  {
533  // multiple items may be selected
534  OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" );
535  // try to find a single visible item
536  bool bHasMultiItems = false;
537  for( const auto& rItem : maItems )
538  {
539  if( (rItem.mnType == XML_data) && !rItem.mbHidden )
540  {
541  bHasMultiItems = nCacheItem >= 0;
542  nCacheItem = bHasMultiItems ? -1 : rItem.mnCacheItem;
543  }
544 
545  if( bHasMultiItems )
546  break;
547  }
548  }
549  else
550  {
551  // single item may be selected
552  if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) )
553  nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem;
554  }
555 
556  if( nCacheItem < 0 )
557  return;
558 
559  if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
560  {
561  if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) )
562  {
563  ScDPObject* pDPObj = mrPivotTable.getDPObject();
564  ScDPSaveData* pSaveData = pDPObj->GetSaveData();
565  ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(pCacheField->getName());
566  OUString aSelectedPage = pSharedItem->getFormattedName(*pDim, pDPObj, DateTime(getWorkbookSettings().getNullDate()));
567  aPropSet.setProperty( PROP_SelectedPage, aSelectedPage );
568  }
569  }
570 }
571 
573 {
574  OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" );
575  OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" );
576  Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
577  if( !xDPField.is() )
578  return;
579 
580  PropertySet aPropSet( xDPField );
581 
582  // field orientation
583  aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA );
584 
585  if (!rDataField.maName.isEmpty())
586  aPropSet.setProperty(PROP_Name, rDataField.maName);
587 
588  /* Field aggregation function. Documentation is a little bit confused
589  about which names to use for the count functions. The name 'count'
590  means 'count all', and 'countNum' means 'count numbers'. On the
591  other hand, for subtotals, 'countA' means 'count all', and 'count'
592  means 'count numbers' (see above). */
593  GeneralFunction eAggFunc = GeneralFunction_SUM;
594  switch( rDataField.mnSubtotal )
595  {
596  case XML_sum: eAggFunc = GeneralFunction_SUM; break;
597  case XML_count: eAggFunc = GeneralFunction_COUNT; break;
598  case XML_average: eAggFunc = GeneralFunction_AVERAGE; break;
599  case XML_max: eAggFunc = GeneralFunction_MAX; break;
600  case XML_min: eAggFunc = GeneralFunction_MIN; break;
601  case XML_product: eAggFunc = GeneralFunction_PRODUCT; break;
602  case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS; break;
603  case XML_stdDev: eAggFunc = GeneralFunction_STDEV; break;
604  case XML_stdDevp: eAggFunc = GeneralFunction_STDEVP; break;
605  case XML_var: eAggFunc = GeneralFunction_VAR; break;
606  case XML_varp: eAggFunc = GeneralFunction_VARP; break;
607  default: OSL_FAIL( "PivotTableField::convertDataField - unknown aggregation function" );
608  }
609  aPropSet.setProperty( PROP_Function, eAggFunc );
610 
611  // field reference ('show data as')
612  DataPilotFieldReference aReference;
613  aReference.ReferenceType = DataPilotFieldReferenceType::NONE;
614  switch( rDataField.mnShowDataAs )
615  {
616  case XML_difference: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE; break;
617  case XML_percent: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE; break;
618  case XML_percentDiff: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break;
619  case XML_runTotal: aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL; break;
620  case XML_percentOfRow: aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE; break;
621  case XML_percentOfCol: aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE; break;
622  case XML_percentOfTotal: aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE; break;
623  case XML_index: aReference.ReferenceType = DataPilotFieldReferenceType::INDEX; break;
624  }
625  if( aReference.ReferenceType == DataPilotFieldReferenceType::NONE )
626  return;
627 
628  const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField );
629  if( !pCacheField )
630  return;
631 
632  aReference.ReferenceField = pCacheField->getName();
633  switch( rDataField.mnBaseItem )
634  {
635  case OOX_PT_PREVIOUS_ITEM:
636  aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
637  break;
638  case OOX_PT_NEXT_ITEM:
639  aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
640  break;
641  default:
642  aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
643  if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) )
644  aReference.ReferenceItemName = pCacheItem->getName();
645  }
646  aPropSet.setProperty( PROP_Reference, aReference );
647 }
648 
649 // private --------------------------------------------------------------------
650 
651 Reference< XDataPilotField > PivotTableField::convertRowColPageField( sal_Int32 nAxis )
652 {
653  bool bDataLayout = mnFieldIndex == OOX_PT_DATALAYOUTFIELD;
654  Reference< XDataPilotField > xDPField = bDataLayout ? mrPivotTable.getDataLayoutField() : mrPivotTable.getDataPilotField( maDPFieldName );
655  OSL_ENSURE( bDataLayout || (nAxis == maModel.mnAxis), "PivotTableField::convertRowColPageField - field axis mismatch" );
656 
657  if( xDPField.is() )
658  {
659  // TODO: Use this to set properties directly, bypassing the slow uno layer.
660  ScDPObject* pDPObj = mrPivotTable.getDPObject();
661 
662  PropertySet aPropSet( xDPField );
663 
664  // field orientation
665  DataPilotFieldOrientation eFieldOrient = DataPilotFieldOrientation_HIDDEN;
666  switch( nAxis )
667  {
668  case XML_axisRow: eFieldOrient = DataPilotFieldOrientation_ROW; break;
669  case XML_axisCol: eFieldOrient = DataPilotFieldOrientation_COLUMN; break;
670  case XML_axisPage: eFieldOrient = DataPilotFieldOrientation_PAGE; break;
671  }
672  if( eFieldOrient != DataPilotFieldOrientation_HIDDEN )
673  aPropSet.setProperty( PROP_Orientation, eFieldOrient );
674 
675  // all other settings not for the data layout field
676  if( !bDataLayout )
677  {
678  /* Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
679  explicit functions are set. This is different behaviour between
680  XML (where 'defaultSubtotal' is set regardless of other
681  functions) and binary formats (where 'defaultSubtotal' is not
682  set if other functions are set). */
683  ::std::vector< GeneralFunction > aSubtotals;
684  /* Order of subtotals is fixed in Excel. Documentation is a little
685  bit confused about which names to use for the count functions.
686  For subtotals, 'countA' means 'count all', and 'count' means
687  'count numbers'. On the other hand, for the data field
688  aggregation function, 'count' means 'count all', and 'countNum'
689  means 'count numbers' (see below). */
690  if( maModel.mbSumSubtotal ) aSubtotals.push_back( GeneralFunction_SUM );
691  if( maModel.mbCountASubtotal ) aSubtotals.push_back( GeneralFunction_COUNT );
692  if( maModel.mbAverageSubtotal ) aSubtotals.push_back( GeneralFunction_AVERAGE );
693  if( maModel.mbMaxSubtotal ) aSubtotals.push_back( GeneralFunction_MAX );
694  if( maModel.mbMinSubtotal ) aSubtotals.push_back( GeneralFunction_MIN );
695  if( maModel.mbProductSubtotal ) aSubtotals.push_back( GeneralFunction_PRODUCT );
696  if( maModel.mbCountSubtotal ) aSubtotals.push_back( GeneralFunction_COUNTNUMS );
697  if( maModel.mbStdDevSubtotal ) aSubtotals.push_back( GeneralFunction_STDEV );
698  if( maModel.mbStdDevPSubtotal ) aSubtotals.push_back( GeneralFunction_STDEVP );
699  if( maModel.mbVarSubtotal ) aSubtotals.push_back( GeneralFunction_VAR );
700  if( maModel.mbVarPSubtotal ) aSubtotals.push_back( GeneralFunction_VARP );
701  // if no function is set manually, check the 'defaultSubtotal' flag
702  if( aSubtotals.empty() && maModel.mbDefaultSubtotal )
703  aSubtotals.push_back( GeneralFunction_AUTO );
704  aPropSet.setProperty( PROP_Subtotals, ContainerHelper::vectorToSequence( aSubtotals ) );
705 
706  // layout settings
707  DataPilotFieldLayoutInfo aLayoutInfo;
708  aLayoutInfo.LayoutMode = maModel.mbOutline ?
709  (maModel.mbSubtotalTop ? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP : DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM) :
710  DataPilotFieldLayoutMode::TABULAR_LAYOUT;
711  aLayoutInfo.AddEmptyLines = maModel.mbInsertBlankRow;
712  aPropSet.setProperty( PROP_LayoutInfo, aLayoutInfo );
713  aPropSet.setProperty( PROP_ShowEmpty, maModel.mbShowAll );
714 
715  // auto show (OOXML/BIFF12 only)
716  if( maModel.mbAutoShow )
717  {
718  DataPilotFieldAutoShowInfo aAutoShowInfo;
719  aAutoShowInfo.IsEnabled = true;
720  aAutoShowInfo.ShowItemsMode = maModel.mbTopAutoShow ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
721  aAutoShowInfo.ItemCount = maModel.mnAutoShowItems;
723  aAutoShowInfo.DataField = pCacheField->getName();
724  aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
725  }
726 
727  // auto sort
728  DataPilotFieldSortInfo aSortInfo;
729  aSortInfo.IsAscending = maModel.mnSortType == XML_ascending;
730  if( (maModel.mnSortType != XML_ascending) && (maModel.mnSortType != XML_descending) )
731  {
732  aSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
733  }
734  else
735  {
736  const PivotCacheField* pCacheField = (maModel.mnSortRefField == OOX_PT_DATALAYOUTFIELD) ?
738  if( pCacheField )
739  {
740  aSortInfo.Mode = DataPilotFieldSortMode::DATA;
741  aSortInfo.Field = pCacheField->getName();
742  }
743  else
744  {
745  aSortInfo.Mode = DataPilotFieldSortMode::NAME;
746  }
747  }
748  aPropSet.setProperty( PROP_SortInfo, aSortInfo );
749 
750  // item settings
751  if (const PivotCacheField* pCacheField = mrPivotTable.getCacheField(mnFieldIndex))
752  {
753  ScDPSaveData* pSaveData = pDPObj->GetSaveData();
754  ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(pCacheField->getName());
755 
756  try
757  {
758  for( const auto& rItem : maItems )
759  {
760  if (rItem.mnType != XML_data)
761  continue;
762 
763  const PivotCacheItem* pSharedItem = pCacheField->getCacheItem(rItem.mnCacheItem);
764  if (!pSharedItem)
765  continue;
766 
767  try
768  {
769  ScDPSaveMember* pMem = pDim->GetMemberByName(pSharedItem->getFormattedName(*pDim, pDPObj, DateTime(getWorkbookSettings().getNullDate())));
770  pMem->SetShowDetails(rItem.mbShowDetails);
771  pMem->SetIsVisible(!rItem.mbHidden);
772  }
773  catch( Exception& )
774  {
775  // catch every failed container access to be able to process following items
776  }
777  }
778  }
779  catch (const Exception&) {}
780  }
781  }
782  }
783  return xDPField;
784 }
785 
787  mfValue( 0.0 ),
788  mnField( -1 ),
789  mnMemPropField( -1 ),
791  mnEvalOrder( 0 ),
792  mnId( -1 ),
793  mnMeasureField( -1 ),
794  mnMeasureHier( -1 ),
795  mbTopFilter( true )
796 {
797 }
798 
800  WorkbookHelper( rPivotTable ),
801  mrPivotTable( rPivotTable )
802 {
803 }
804 
806 {
807  maModel.maName = rAttribs.getXString( XML_name, OUString() );
808  maModel.maDescription = rAttribs.getXString( XML_description, OUString() );
809  maModel.maStrValue1 = rAttribs.getXString( XML_stringValue1, OUString() );
810  maModel.maStrValue2 = rAttribs.getXString( XML_stringValue2, OUString() );
811  maModel.mnField = rAttribs.getInteger( XML_fld, -1 );
812  maModel.mnMemPropField = rAttribs.getInteger( XML_mpFld, -1 );
813  maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
814  maModel.mnEvalOrder = rAttribs.getInteger( XML_evalOrder, 0 );
815  maModel.mnId = rAttribs.getInteger( XML_id, -1 );
816  maModel.mnMeasureField = rAttribs.getInteger( XML_iMeasureFld, -1 );
817  maModel.mnMeasureHier = rAttribs.getInteger( XML_iMeasureHier, -1 );
818 }
819 
821 {
822  OSL_ENSURE( rAttribs.getBool( XML_percent, false ) == (maModel.mnType == XML_percent),
823  "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
824  maModel.mfValue = rAttribs.getDouble( XML_val, 0.0 );
825  maModel.mbTopFilter = rAttribs.getBool( XML_top, true );
826 }
827 
829 {
830  sal_Int32 nType;
831  sal_uInt16 nFlags;
832  maModel.mnField = rStrm.readInt32();
833  maModel.mnMemPropField = rStrm.readInt32();
834  nType = rStrm.readInt32();
835  rStrm.skip( 4 ); // unused
836  maModel.mnId = rStrm.readInt32();
837  maModel.mnMeasureField = rStrm.readInt32();
838  maModel.mnMeasureHier = rStrm.readInt32();
839  nFlags = rStrm.readuInt16();
840  if( getFlag( nFlags, BIFF12_PTFILTER_HASNAME ) )
841  rStrm >> maModel.maName;
842  if( getFlag( nFlags, BIFF12_PTFILTER_HASDESCRIPTION ) )
843  rStrm >> maModel.maDescription;
844  if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE1 ) )
845  rStrm >> maModel.maStrValue1;
846  if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE2 ) )
847  rStrm >> maModel.maStrValue2;
848 
849  static const sal_Int32 spnTypes[] =
850  {
851  XML_unknown,
852  // data field top10 filter (1-3)
853  XML_count, XML_percent, XML_sum,
854  // caption filter (4-17)
855  XML_captionEqual, XML_captionNotEqual,
856  XML_captionBeginsWith, XML_captionNotBeginsWith, XML_captionEndsWith, XML_captionNotEndsWith,
857  XML_captionContains, XML_captionNotContains, XML_captionGreaterThan, XML_captionGreaterThanOrEqual,
858  XML_captionLessThan, XML_captionLessThanOrEqual, XML_captionBetween, XML_captionNotBetween,
859  // value filter (18-25)
860  XML_valueEqual, XML_valueNotEqual, XML_valueGreaterThan, XML_valueGreaterThanOrEqual,
861  XML_valueLessThan, XML_valueLessThanOrEqual, XML_valueBetween, XML_valueNotBetween,
862  // date filter (26-65)
863  XML_dateEqual, XML_dateOlderThan, XML_dateNewerThan, XML_dateBetween,
864  XML_tomorrow, XML_today, XML_yesterday, XML_nextWeek, XML_thisWeek, XML_lastWeek,
865  XML_nextMonth, XML_thisMonth, XML_lastMonth, XML_nextQuarter, XML_thisQuarter, XML_lastQuarter,
866  XML_nextYear, XML_thisYear, XML_lastYear, XML_yearToDate, XML_Q1, XML_Q2, XML_Q3, XML_Q4,
867  XML_M1, XML_M2, XML_M3, XML_M4, XML_M5, XML_M6, XML_M7, XML_M8, XML_M9, XML_M10, XML_M11, XML_M12,
868  XML_dateNotEqual, XML_dateOlderThanOrEqual, XML_dateNewerThanOrEqual, XML_dateNotBetween
869  };
870  maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
871 }
872 
874 {
875  sal_uInt8 nFlags;
876  nFlags = rStrm.readuChar();
877  maModel.mfValue = rStrm.readDouble();
878 
879  SAL_WARN_IF(
880  getFlag(nFlags, BIFF12_TOP10FILTER_PERCENT) != (maModel.mnType == XML_percent),
881  "sc.filter",
882  "PivotTableFilter::importTop10 - unexpected value of percent attribute");
883  maModel.mbTopFilter = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
884 }
885 
887 {
888  // only simple top10 filter supported
889  if( maModel.mnType != XML_count )
890  return;
891 
893  if( aPropSet.is() )
894  {
895  DataPilotFieldAutoShowInfo aAutoShowInfo;
896  aAutoShowInfo.IsEnabled = true;
897  aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
898  aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 );
900  aAutoShowInfo.DataField = pCacheField->getName();
901  aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
902  }
903 }
904 
906  mnCacheId( -1 ),
907  mnDataPosition( 0 ),
908  mnPageWrap( 0 ),
909  mnIndent( 1 ),
910  mnChartFormat( 0 ),
911  mbDataOnRows( false ),
912  mbShowError( false ),
913  mbShowMissing( true ),
914  mbShowItems( true ),
915  mbDisableFieldList( false ),
916  mbShowCalcMembers( true ),
917  mbVisualTotals( true ),
918  mbShowDrill( true ),
919  mbPrintDrill( false ),
920  mbEnableDrill( true ),
921  mbPreserveFormatting( true ),
922  mbUseAutoFormat( false ),
923  mbPageOverThenDown( false ),
924  mbSubtotalHiddenItems( false ),
925  mbRowGrandTotals( true ),
926  mbColGrandTotals( true ),
927  mbFieldPrintTitles( false ),
928  mbItemPrintTitles( false ),
929  mbMergeItem( false ),
930  mbShowEmptyRow( false ),
931  mbShowEmptyCol( false ),
932  mbShowHeaders( true ),
933  mbFieldListSortAsc( false ),
934  mbCustomListSort( true )
935 {
936 }
937 
939  mnFirstHeaderRow( 0 ),
940  mnFirstDataRow( 0 ),
941  mnFirstDataCol( 0 ),
942  mnRowPageCount( 0 ),
943  mnColPageCount( 0 )
944 {
945 }
946 
948  WorkbookHelper( rHelper ),
949  mpDPObject(nullptr),
950  maDataField( *this, OOX_PT_DATALAYOUTFIELD ),
951  mpPivotCache( nullptr )
952 {
953 }
954 
956 {
957  maDefModel.maName = rAttribs.getXString( XML_name, OUString() );
958  maDefModel.maDataCaption = rAttribs.getXString( XML_dataCaption , OUString() );
959  maDefModel.maGrandTotalCaption = rAttribs.getXString( XML_grandTotalCaption, OUString() );
960  maDefModel.maRowHeaderCaption = rAttribs.getXString( XML_rowHeaderCaption, OUString() );
961  maDefModel.maColHeaderCaption = rAttribs.getXString( XML_colHeaderCaption, OUString() );
962  maDefModel.maErrorCaption = rAttribs.getXString( XML_errorCaption, OUString() );
963  maDefModel.maMissingCaption = rAttribs.getXString( XML_missingCaption, OUString() );
964  maDefModel.maPageStyle = rAttribs.getXString( XML_pageStyle, OUString() );
965  maDefModel.maPivotTableStyle = rAttribs.getXString( XML_pivotTableStyle, OUString() );
966  maDefModel.maVacatedStyle = rAttribs.getXString( XML_vacatedStyle, OUString() );
967  maDefModel.maTag = rAttribs.getXString( XML_tag, OUString() );
968  maDefModel.mnCacheId = rAttribs.getInteger( XML_cacheId, -1 );
969  maDefModel.mnDataPosition = rAttribs.getInteger( XML_dataPosition, 0 );
970  maDefModel.mnPageWrap = rAttribs.getInteger( XML_pageWrap, 0 );
971  maDefModel.mnIndent = rAttribs.getInteger( XML_indent, 1 );
972  maDefModel.mnChartFormat = rAttribs.getInteger( XML_chartFormat, 0 );
973  maDefModel.mnAutoFormatId = rAttribs.getInteger( XML_autoFormatId, 0 );
974  maDefModel.mbDataOnRows = rAttribs.getBool( XML_dataOnRows, false );
975  maDefModel.mbShowError = rAttribs.getBool( XML_showError, false );
976  maDefModel.mbShowMissing = rAttribs.getBool( XML_showMissing, true );
977  maDefModel.mbShowItems = rAttribs.getBool( XML_showItems, true );
978  maDefModel.mbDisableFieldList = rAttribs.getBool( XML_disableFieldList, false );
979  maDefModel.mbShowCalcMembers = rAttribs.getBool( XML_showCalcMbrs, true );
980  maDefModel.mbVisualTotals = rAttribs.getBool( XML_visualTotals, true );
981  maDefModel.mbShowDrill = rAttribs.getBool( XML_showDrill, true );
982  maDefModel.mbPrintDrill = rAttribs.getBool( XML_printDrill, false );
983  maDefModel.mbEnableDrill = rAttribs.getBool( XML_enableDrill, true );
984  maDefModel.mbPreserveFormatting = rAttribs.getBool( XML_preserveFormatting, true );
985  maDefModel.mbUseAutoFormat = rAttribs.getBool( XML_useAutoFormatting, false );
986  maDefModel.mbPageOverThenDown = rAttribs.getBool( XML_pageOverThenDown, false );
987  maDefModel.mbSubtotalHiddenItems = rAttribs.getBool( XML_subtotalHiddenItems, false );
988  maDefModel.mbRowGrandTotals = rAttribs.getBool( XML_rowGrandTotals, true );
989  maDefModel.mbColGrandTotals = rAttribs.getBool( XML_colGrandTotals, true );
990  maDefModel.mbFieldPrintTitles = rAttribs.getBool( XML_fieldPrintTitles, false );
991  maDefModel.mbItemPrintTitles = rAttribs.getBool( XML_itemPrintTitles, false );
992  maDefModel.mbMergeItem = rAttribs.getBool( XML_mergeItem, false );
993  maDefModel.mbShowEmptyRow = rAttribs.getBool( XML_showEmptyRow, false );
994  maDefModel.mbShowEmptyCol = rAttribs.getBool( XML_showEmptyCol, false );
995  maDefModel.mbShowHeaders = rAttribs.getBool( XML_showHeaders, true );
996  maDefModel.mbFieldListSortAsc = rAttribs.getBool( XML_fieldListSortAscending, false );
997  maDefModel.mbCustomListSort = rAttribs.getBool( XML_customListSort, true );
998  maDefModel.mbApplyNumFmt = rAttribs.getBool( XML_applyNumberFormats, false );
999  maDefModel.mbApplyFont = rAttribs.getBool( XML_applyFontFormats, false );
1000  maDefModel.mbApplyAlignment = rAttribs.getBool( XML_applyAlignmentFormats, false );
1001  maDefModel.mbApplyBorder = rAttribs.getBool( XML_applyBorderFormats, false );
1002  maDefModel.mbApplyFill = rAttribs.getBool( XML_applyPatternFormats, false );
1003  // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
1004  maDefModel.mbApplyProtection = rAttribs.getBool( XML_applyWidthHeightFormats, false );
1005 }
1006 
1007 void PivotTable::importLocation( const AttributeList& rAttribs, sal_Int16 nSheet )
1008 {
1009  AddressConverter::convertToCellRangeUnchecked( maLocationModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet );
1010  maLocationModel.mnFirstHeaderRow = rAttribs.getInteger( XML_firstHeaderRow, 0 );
1011  maLocationModel.mnFirstDataRow = rAttribs.getInteger( XML_firstDataRow, 0 );
1012  maLocationModel.mnFirstDataCol = rAttribs.getInteger( XML_firstDataCol, 0 );
1013  maLocationModel.mnRowPageCount = rAttribs.getInteger( XML_rowPageCount, 0 );
1014  maLocationModel.mnColPageCount = rAttribs.getInteger( XML_colPageCount, 0 );
1015 }
1016 
1018 {
1019  importField( maRowFields, rAttribs );
1020 }
1021 
1023 {
1024  importField( maColFields, rAttribs );
1025 }
1026 
1028 {
1029  PTPageFieldModel aModel;
1030  aModel.maName = rAttribs.getXString( XML_name, OUString() );
1031  aModel.mnField = rAttribs.getInteger( XML_fld, -1 );
1032  // specification is wrong, XML_item is not the cache item, but the field item
1033  aModel.mnItem = rAttribs.getInteger( XML_item, BIFF12_PTPAGEFIELD_MULTIITEMS );
1034  maPageFields.push_back( aModel );
1035 }
1036 
1038 {
1039  PTDataFieldModel aModel;
1040  aModel.maName = rAttribs.getXString( XML_name, OUString() );
1041  aModel.mnField = rAttribs.getInteger( XML_fld, -1 );
1042  aModel.mnSubtotal = rAttribs.getToken( XML_subtotal, XML_sum );
1043  aModel.mnShowDataAs = rAttribs.getToken( XML_showDataAs, XML_normal );
1044  aModel.mnBaseField = rAttribs.getInteger( XML_baseField, -1 );
1045  aModel.mnBaseItem = rAttribs.getInteger( XML_baseItem, -1 );
1046  aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
1047  maDataFields.push_back( aModel );
1048 }
1049 
1050 void PivotTable::putToInteropGrabBag(const OUString& sName, const AttributeList& rAttribs)
1051 {
1052  if (auto xFastAttributeList = rAttribs.getFastAttributeList())
1053  {
1054  // Store both known and unknown attribute sequences to the grab bag as is
1055  css::uno::Sequence<css::xml::FastAttribute> aFast = xFastAttributeList->getFastAttributes();
1056  css::uno::Sequence<css::xml::Attribute> aUnk = xFastAttributeList->getUnknownAttributes();
1057  css::uno::Sequence<css::uno::Any> aVal{ css::uno::Any(aFast), css::uno::Any(aUnk) };
1058  maInteropGrabBag[sName] <<= aVal;
1059  }
1060 }
1061 
1063 {
1064  sal_uInt32 nFlags1, nFlags2, nFlags3;
1065  sal_uInt8 nDataAxis;
1066  nFlags1 = rStrm.readuInt32();
1067  nFlags2 = rStrm.readuInt32();
1068  nFlags3 = rStrm.readuInt32();
1069  nDataAxis = rStrm.readuChar();
1070  maDefModel.mnPageWrap = rStrm.readuInt8();
1071  rStrm.skip( 2 ); // refresh versions
1074  rStrm.skip( 2 ); // unused
1076  maDefModel.mnCacheId = rStrm.readInt32();
1077  rStrm >> maDefModel.maName;
1078  if( getFlag( nFlags2, BIFF12_PTDEF_HASDATACAPTION ) )
1079  rStrm >> maDefModel.maDataCaption;
1080  if( getFlag( nFlags2, BIFF12_PTDEF_HASGRANDTOTALCAPTION ) )
1082  if( !getFlag( nFlags3, BIFF12_PTDEF_NOERRORCAPTION ) ) // missing flag indicates existing string
1083  rStrm >> maDefModel.maErrorCaption;
1084  if( !getFlag( nFlags3, BIFF12_PTDEF_NOMISSINGCAPTION ) ) // missing flag indicates existing string
1085  rStrm >> maDefModel.maMissingCaption;
1086  if( getFlag( nFlags2, BIFF12_PTDEF_HASPAGESTYLE ) )
1087  rStrm >> maDefModel.maPageStyle;
1088  if( getFlag( nFlags2, BIFF12_PTDEF_HASPIVOTTABLESTYLE ) )
1089  rStrm >> maDefModel.maPivotTableStyle;
1090  if( getFlag( nFlags2, BIFF12_PTDEF_HASVACATEDSTYLE ) )
1091  rStrm >> maDefModel.maVacatedStyle;
1092  if( getFlag( nFlags2, BIFF12_PTDEF_HASTAG ) )
1093  rStrm >> maDefModel.maTag;
1094  if( getFlag( nFlags3, BIFF12_PTDEF_HASCOLHEADERCAPTION ) ) // TODO: right order (col/row)? spec is unclear
1095  rStrm >> maDefModel.maColHeaderCaption;
1096  if( getFlag( nFlags3, BIFF12_PTDEF_HASROWHEADERCAPTION ) )
1097  rStrm >> maDefModel.maRowHeaderCaption;
1098 
1099  SAL_WARN_IF(
1100  (nDataAxis != BIFF12_PTDEF_ROWAXIS) && (nDataAxis != BIFF12_PTDEF_COLAXIS),
1101  "sc.filter",
1102  "PivotTable::importPTDefinition - unexpected axis position for data field");
1103 
1104  maDefModel.mnIndent = extractValue< sal_uInt8 >( nFlags1, 24, 7 );
1105  maDefModel.mbDataOnRows = nDataAxis == BIFF12_PTDEF_ROWAXIS;
1106  maDefModel.mbShowError = getFlag( nFlags2, BIFF12_PTDEF_SHOWERROR );
1107  maDefModel.mbShowMissing = getFlag( nFlags2, BIFF12_PTDEF_SHOWMISSING );
1108  maDefModel.mbShowItems = getFlag( nFlags1, BIFF12_PTDEF_SHOWITEMS );
1109  maDefModel.mbDisableFieldList = getFlag( nFlags1, BIFF12_PTDEF_DISABLEFIELDLIST );
1110  maDefModel.mbShowCalcMembers = !getFlag( nFlags1, BIFF12_PTDEF_HIDECALCMEMBERS );
1111  maDefModel.mbVisualTotals = !getFlag( nFlags1, BIFF12_PTDEF_WITHHIDDENTOTALS );
1112  maDefModel.mbShowDrill = !getFlag( nFlags1, BIFF12_PTDEF_HIDEDRILL );
1113  maDefModel.mbPrintDrill = getFlag( nFlags1, BIFF12_PTDEF_PRINTDRILL );
1114  maDefModel.mbEnableDrill = getFlag( nFlags2, BIFF12_PTDEF_ENABLEDRILL );
1115  maDefModel.mbPreserveFormatting = getFlag( nFlags2, BIFF12_PTDEF_PRESERVEFORMATTING );
1116  maDefModel.mbUseAutoFormat = getFlag( nFlags2, BIFF12_PTDEF_USEAUTOFORMAT );
1117  maDefModel.mbPageOverThenDown = getFlag( nFlags2, BIFF12_PTDEF_PAGEOVERTHENDOWN );
1118  maDefModel.mbSubtotalHiddenItems = getFlag( nFlags2, BIFF12_PTDEF_SUBTOTALHIDDENITEMS );
1119  maDefModel.mbRowGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_ROWGRANDTOTALS );
1120  maDefModel.mbColGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_COLGRANDTOTALS );
1121  maDefModel.mbFieldPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_FIELDPRINTTITLES );
1122  maDefModel.mbItemPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_ITEMPRINTTITLES );
1123  maDefModel.mbMergeItem = getFlag( nFlags2, BIFF12_PTDEF_MERGEITEM );
1124  maDefModel.mbApplyNumFmt = getFlag( nFlags2, BIFF12_PTDEF_APPLYNUMFMT );
1125  maDefModel.mbApplyFont = getFlag( nFlags2, BIFF12_PTDEF_APPLYFONT );
1126  maDefModel.mbApplyAlignment = getFlag( nFlags2, BIFF12_PTDEF_APPLYALIGNMENT );
1127  maDefModel.mbApplyBorder = getFlag( nFlags2, BIFF12_PTDEF_APPLYBORDER );
1128  maDefModel.mbApplyFill = getFlag( nFlags2, BIFF12_PTDEF_APPLYFILL );
1129  maDefModel.mbApplyProtection = getFlag( nFlags2, BIFF12_PTDEF_APPLYPROTECTION );
1130  maDefModel.mbShowEmptyRow = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYROW );
1131  maDefModel.mbShowEmptyCol = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYCOL );
1132  maDefModel.mbShowHeaders = !getFlag( nFlags1, BIFF12_PTDEF_HIDEHEADERS );
1133  maDefModel.mbFieldListSortAsc = getFlag( nFlags3, BIFF12_PTDEF_FIELDLISTSORTASC );
1134  maDefModel.mbCustomListSort = !getFlag( nFlags3, BIFF12_PTDEF_NOCUSTOMLISTSORT );
1135 }
1136 
1137 void PivotTable::importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet )
1138 {
1139  BinRange aBinRange;
1140  rStrm >> aBinRange;
1147 }
1148 
1150 {
1151  importFields( maRowFields, rStrm );
1152 }
1153 
1155 {
1156  importFields( maColFields, rStrm );
1157 }
1158 
1160 {
1161  PTPageFieldModel aModel;
1162  sal_uInt8 nFlags;
1163  aModel.mnField = rStrm.readInt32();
1164  aModel.mnItem = rStrm.readInt32();
1165  rStrm.skip( 4 ); // hierarchy
1166  nFlags = rStrm.readuChar();
1167  if( getFlag( nFlags, BIFF12_PTPAGEFIELD_HASNAME ) )
1168  rStrm >> aModel.maName;
1169  maPageFields.push_back( aModel );
1170 }
1171 
1173 {
1174  PTDataFieldModel aModel;
1175  sal_Int32 nSubtotal, nShowDataAs;
1176  sal_uInt8 nHasName;
1177  aModel.mnField = rStrm.readInt32( );
1178  nSubtotal = rStrm.readInt32();
1179  nShowDataAs = rStrm.readInt32();
1180  aModel.mnBaseField = rStrm.readInt32();
1181  aModel.mnBaseItem = rStrm.readInt32();
1182  aModel.mnNumFmtId = rStrm.readInt32();
1183  nHasName = rStrm.readuChar();
1184  if( nHasName == 1 )
1185  rStrm >> aModel.maName;
1186  aModel.setBiffSubtotal( nSubtotal );
1187  aModel.setBiffShowDataAs( nShowDataAs );
1188  maDataFields.push_back( aModel );
1189 }
1190 
1192 {
1193  sal_Int32 nFieldIndex = static_cast< sal_Int32 >( maFields.size() );
1194  PivotTableFieldVector::value_type xTableField = std::make_shared<PivotTableField>( *this, nFieldIndex );
1195  maFields.push_back( xTableField );
1196  return *xTableField;
1197 }
1198 
1200 {
1201  PivotTableFilterVector::value_type xTableFilter = std::make_shared<PivotTableFilter>( *this );
1202  maFilters.push_back( xTableFilter );
1203  return *xTableFilter;
1204 }
1205 
1207 {
1208  if( !getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) )
1209  return;
1210 
1212  if( !mpPivotCache || !mpPivotCache->isValidDataSource() || maDefModel.maName.isEmpty() )
1213  return;
1214 
1215  // clear destination area of the original pivot table
1216  try
1217  {
1218  Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW );
1219  using namespace ::com::sun::star::sheet::CellFlags;
1220  xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED );
1221  }
1222  catch( Exception& )
1223  {
1224  }
1225 
1226  try
1227  {
1228  // create a new data pilot descriptor based on the source data
1229  Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.aStart.Tab() ), UNO_QUERY_THROW );
1230  Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW );
1231  mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW );
1232  ScRange aRange = mpPivotCache->getSourceRange();
1233  CellRangeAddress aCellRangeAddress( aRange.aStart.Tab(),
1234  aRange.aStart.Col(), aRange.aStart.Row(),
1235  aRange.aEnd.Col(), aRange.aEnd.Row() );
1236  mxDPDescriptor->setSourceRange( aCellRangeAddress );
1237  mxDPDescriptor->setTag( maDefModel.maTag );
1238 
1239  // TODO: This is a hack. Eventually we need to convert the whole thing to the internal API.
1240  auto pImpl = comphelper::getFromUnoTunnel<ScDataPilotDescriptorBase>(mxDPDescriptor);
1241  if (!pImpl)
1242  return;
1243 
1244  mpDPObject = pImpl->GetDPObject();
1245  if (!mpDPObject)
1246  return;
1247 
1248  // global data pilot properties
1249  PropertySet aDescProp( mxDPDescriptor );
1250  aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals );
1251  aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals );
1252  aDescProp.setProperty( PROP_ShowFilterButton, false );
1253  aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill );
1254 
1255  // finalize all fields, this finds field names and creates grouping fields
1257 
1258  // all row fields
1259  for( const auto& rRowField : maRowFields )
1260  if( PivotTableField* pField = getTableField( rRowField ) )
1261  pField->convertRowField();
1262 
1263  // all column fields
1264  for( const auto& rColField : maColFields )
1265  if( PivotTableField* pField = getTableField( rColField ) )
1266  pField->convertColField();
1267 
1268  // all page fields
1269  for( const auto& rPageField : maPageFields )
1270  if( PivotTableField* pField = getTableField( rPageField.mnField ) )
1271  pField->convertPageField( rPageField );
1272 
1273  // all hidden fields
1274  ::std::set< sal_Int32 > aVisFields;
1275  aVisFields.insert( maRowFields.begin(), maRowFields.end() );
1276  aVisFields.insert( maColFields.begin(), maColFields.end() );
1277  for( const auto& rPageField : maPageFields )
1278  aVisFields.insert( rPageField.mnField );
1279  sal_Int32 nIndex = 0;
1280  for( auto& rxField : maFields )
1281  {
1282  if( aVisFields.count( nIndex ) == 0 )
1283  rxField->convertHiddenField();
1284  ++nIndex;
1285  }
1286 
1287  // all data fields
1288  for( auto& rDataField : maDataFields )
1289  {
1290  if( const PivotCacheField* pCacheField = getCacheField( rDataField.mnField ) )
1291  {
1292  if ( pCacheField-> getGroupBaseField() != -1 )
1293  rDataField.mnField = pCacheField-> getGroupBaseField();
1294  }
1295  if( PivotTableField* pField = getTableField( rDataField.mnField ) )
1296  pField->convertDataField( rDataField );
1297  }
1298 
1299  // filters
1301 
1302  // calculate base position of table
1304  /* If page fields exist, include them into the destination
1305  area (they are excluded in Excel). Add an extra blank row. */
1306  if( !maPageFields.empty() )
1307  aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 );
1308 
1309  // save interop grab bag
1311 
1312  // insert the DataPilot table into the sheet
1313  xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
1314  }
1315  catch( Exception& )
1316  {
1317  TOOLS_WARN_EXCEPTION( "sc", "PivotTable::finalizeImport - exception while creating the DataPilot table" );
1318  }
1319 }
1320 
1322 {
1323  if (maFields.empty())
1324  return;
1325 
1326  /* Check whether group fields are already imported for another table
1327  sharing the same groups. */
1328  ScDPObject* pDPObj = getDPObject();
1329  const ScDocument& rDoc = getDocImport().getDoc();
1330  if (rDoc.HasPivotTable())
1331  {
1332  const ScDPCollection* pDPCollection = rDoc.GetDPCollection();
1333  assert(pDPCollection != nullptr);
1334  const ScDPDimensionSaveData* pGroups = nullptr;
1335  bool bRefFound = pDPCollection->GetReferenceGroups(*pDPObj, &pGroups);
1336  // Apply reference groups on this table.
1337  if (bRefFound && pGroups && pGroups->HasGroupDimensions()) {
1338  ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1339  if (pSaveData) {
1340  pSaveData->SetDimensionData(pGroups);
1341  pDPObj->ReloadGroupTableData();
1343  return;
1344  }
1345 
1346  }
1347  }
1349 }
1350 
1351 void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
1352 {
1353  // process all fields, there is no chaining information in the cache fields
1354  maFields.forEachMem( &PivotTableField::finalizeDateGroupingImport, ::std::cref(rxBaseDPField), nBaseFieldIdx );
1355 }
1356 
1357 void PivotTable::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField,
1358  const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
1359 {
1360  // try to create parent group fields that group the items of the passed base field
1361  if( PivotTableField* pParentTableField = maFields.get( rBaseCacheField.getParentGroupField() ).get() )
1362  pParentTableField->finalizeParentGroupingImport( rxBaseDPField, rBaseCacheField, orItemNames );
1363 }
1364 
1365 Reference< XDataPilotField > PivotTable::getDataPilotField( const OUString& rFieldName ) const
1366 {
1367  Reference< XDataPilotField > xDPField;
1368  if( !rFieldName.isEmpty() && mxDPDescriptor.is() ) try
1369  {
1370  Reference< XNameAccess > xDPFieldsNA( mxDPDescriptor->getDataPilotFields(), UNO_QUERY_THROW );
1371  xDPField.set( xDPFieldsNA->getByName( rFieldName ), UNO_QUERY );
1372  }
1373  catch( Exception& )
1374  {
1375  }
1376  return xDPField;
1377 }
1378 
1379 Reference< XDataPilotField > PivotTable::getDataPilotField( sal_Int32 nFieldIdx ) const
1380 {
1381  Reference< XDataPilotField > xDPField;
1382  if( const PivotTableField* pTableField = maFields.get( nFieldIdx ).get() )
1383  xDPField = getDataPilotField( pTableField->getDPFieldName() );
1384  return xDPField;
1385 }
1386 
1387 Reference< XDataPilotField > PivotTable::getDataLayoutField() const
1388 {
1389  Reference< XDataPilotField > xDPField;
1390  try
1391  {
1392  Reference< XDataPilotDataLayoutFieldSupplier > xDPDataFieldSupp( mxDPDescriptor, UNO_QUERY_THROW );
1393  xDPField = xDPDataFieldSupp->getDataLayoutField();
1394  }
1395  catch( Exception& )
1396  {
1397  }
1398  return xDPField;
1399 }
1400 
1402 {
1403  return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : nullptr;
1404 }
1405 
1406 const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const
1407 {
1408  return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : nullptr;
1409 }
1410 
1411 const PivotCacheField* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const
1412 {
1413  const PTDataFieldModel* pDataField = ContainerHelper::getVectorElement( maDataFields, nDataItemIdx );
1414  return pDataField ? getCacheField( pDataField->mnField ) : nullptr;
1415 }
1416 
1417 sal_Int32 PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
1418 {
1419  return mpPivotCache ? mpPivotCache->getCacheDatabaseIndex( nFieldIdx ) : -1;
1420 }
1421 
1422 // private --------------------------------------------------------------------
1423 
1425 {
1426  return (nFieldIdx == OOX_PT_DATALAYOUTFIELD) ? &maDataField : maFields.get( nFieldIdx ).get();
1427 }
1428 
1429 void PivotTable::importField( IndexVector& orFields, const AttributeList& rAttribs )
1430 {
1431  orFields.push_back( rAttribs.getInteger( XML_x, -1 ) );
1432 }
1433 
1435 {
1436  OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
1437  orFields.clear();
1438  sal_Int32 nCount = rStrm.readInt32();
1439  OSL_ENSURE( 4 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
1440  nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 4 );
1441  for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
1442  orFields.push_back( rStrm.readInt32() );
1443 }
1444 
1446  WorkbookHelper( rHelper )
1447 {
1448 }
1449 
1451 {
1452  PivotTableVector::value_type xTable = std::make_shared<PivotTable>( *this );
1453  maTables.push_back( xTable );
1454  return *xTable;
1455 }
1456 
1458 {
1460 }
1461 
1462 } // namespace oox
1463 
1464 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 mnEvalOrder
Filter type.
bool mbApplyAlignment
True = apply font from autoformatting.
Helper class to provide access to global workbook data.
void convertHiddenField()
Converts dimension and other settings for a hidden field.
void setBiffType(sal_uInt16 nType)
Sets item type for BIFF import.
::std::vector< IdCaptionPair > IdCaptionPairList
bool mbProductSubtotal
True = show minimum subtotals.
void finalizeImport()
Inserts the pivot table into the sheet.
STRING
void ReloadGroupTableData()
Definition: dpobject.cxx:810
sal_Int32 nIndex
bool mbTopFilter
Hierarchy for filter calculation.
std::map< OUString, css::uno::Any > maInteropGrabBag
Descriptor of the DataPilot object.
ScAddress aStart
Definition: address.hxx:499
PivotCache * mpPivotCache
Location settings of the pivot table.
ScDocumentImport & getDocImport()
OUString createParentGroupField(const css::uno::Reference< css::sheet::XDataPilotField > &rxBaseDPField, const PivotCacheField &rBaseCacheField, PivotCacheGroupItemVector &orItemNames) const
Creates a new grouped DataPilot field and returns its name.
ItemModelVector maItems
The parent pivot table object.
bool mbMultiPageItems
True = auto show filter shows top entries, false = bottom.
virtual void skip(sal_Int32 nBytes, size_t nAtomSize=1) override
This class has to do with handling exclusively grouped dimensions? TODO: Find out what this class doe...
Definition: dpdimsave.hxx:163
ScDPSaveMember * GetMemberByName(const OUString &rName)
Get a member object by its name.
Definition: dpsave.cxx:456
OptValue< bool > getBool(sal_Int32 nAttrToken) const
SCROW Row() const
Definition: address.hxx:261
ScDPObject * getDPObject()
bool mbTopAutoShow
True = auto show (top 10) filter enabled.
static const VectorType::value_type * getVectorElement(const VectorType &rVector, sal_Int32 nIndex)
bool HasGroupDimensions() const
Definition: dpdimsave.cxx:695
sal_Int32 mnField
Unique name of the page field.
OptValue< OUString > getXString(sal_Int32 nAttrToken) const
sal_Int32 mnNumFmtId
OptValue< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
void finalizeParentGroupingImport(const css::uno::Reference< css::sheet::XDataPilotField > &rxBaseDPField, const PivotCacheField &rBaseCacheField, PivotCacheGroupItemVector &orItemNames)
Finalizes the grouped field after import.
void finalizeImport()
Inserts all pivot tables into the sheet.
SC_DLLPUBLIC bool GetReferenceGroups(const ScDPObject &rDPObj, const ScDPDimensionSaveData **pGroups) const
Definition: dpobject.cxx:3521
sal_Int32 mnMeasureField
Unique identifier.
sal_Int32 mnSortRefItem
Reference field for autosorting.
A 2D cell range address struct for binary filters.
PTFilterModel()
True = filter shows top entries, false = bottom.
SC_DLLPUBLIC ScDPCollection * GetDPCollection()
Definition: documen3.cxx:365
bool mbStdDevPSubtotal
True = show standard deviation subtotals.
const PivotCacheItem * getCacheItem(sal_Int32 nItemIdx) const
Returns the shared or group item with the specified index.
void importRowField(const AttributeList &rAttribs)
Reads the index of a field located in the row dimension.
void importPTReferenceItem(SequenceInputStream &rStrm)
Imports pivot field item reference settings from the PTREFERENCEITEM record.
value_type get(sal_Int32 nIndex) const
void PutInteropGrabBag(std::map< OUString, css::uno::Any > &&val)
Definition: dpobject.hxx:262
ScAddress aEnd
Definition: address.hxx:500
const ScRange & getSourceRange() const
Returns the internal cell range the cache is based on.
OptValue< double > getDouble(sal_Int32 nAttrToken) const
css::uno::Reference< css::table::XCellRange > getCellRangeFromDoc(const ScRange &rRange) const
Returns the XCellRange interface for the passed cell range address.
sal_Int32 mnFieldIndex
Name of the field in DataPilot field collection.
sal_uInt32 readuInt32()
#define STATIC_ARRAY_SELECT(array, index, def)
OUString maStrValue2
First string value for label filter.
sal_Int32 mnFirstDataCol
First row of data cells (relative in pivot table).
::std::vector< sal_Int32 > IndexVector
OptValue< OUString > getString(sal_Int32 nAttrToken) const
unsigned char readuChar()
sal_uInt16 mnId
void finalizeDateGroupingImport(const css::uno::Reference< css::sheet::XDataPilotField > &rxBaseDPField, sal_Int32 nBaseFieldIdx)
Creates all date group fields for the specified cache field after import.
static bool convertToCellRangeUnchecked(ScRange &orRange, const OUString &rString, sal_Int16 nSheet)
Converts the passed string to a cell range address, without checking any sheet limits.
SC_DLLPUBLIC void SetIsVisible(bool bSet)
Definition: dpsave.cxx:95
const PivotTable & mrPivotTable
WorkbookSettings & getWorkbookSettings() const
Returns the global workbook settings object.
void importColField(const AttributeList &rAttribs)
Reads the index of a field located in the column dimension.
css::uno::Reference< css::sheet::XDataPilotField > convertRowColPageField(sal_Int32 nAxis)
Converts dimension and other settings for row, column, page, or hidden fields.
sal_Int32 getCacheDatabaseIndex(sal_Int32 nFieldIdx) const
Returns the source column index of the field with the passed index.
#define SAL_MAX_UINT32
void importDataField(const AttributeList &rAttribs)
Reads the settings of a field located in the data dimension from the dataField element.
void forEachMem(FuncType pFunc) const
void importPTFItem(SequenceInputStream &rStrm)
Imports settings of an item in this pivot field from the PTFITEM record.
bool mbOutline
True = show items without data.
sal_Int32 mnItem
Base pivot field.
sal_uInt16 readuInt16()
sal_Int32 mnSubtotal
Base pivot field.
PTFieldModel()
True = multiple items selectable in page dimension.
static void importFields(IndexVector &orFields, SequenceInputStream &rStrm)
Reads an array of field indexes for the row or column dimension.
sal_Int32 mnFirstDataRow
First row of header cells (relative in pivot table).
void importLocation(const AttributeList &rAttribs, sal_Int16 nSheet)
Reads the location of the pivot table from the location element.
int nCount
sal_Int32 mnColPageCount
Number of rows in page filter area.
void finalizeImport(const css::uno::Reference< css::sheet::XDataPilotDescriptor > &rxDPDesc)
Finalizes the field after import, creates grouping and other settings.
PivotCacheBuffer & getPivotCaches() const
Returns the collection of pivot caches.
SCTAB Tab() const
Definition: address.hxx:270
css::uno::Reference< css::sheet::XDataPilotDescriptor > mxDPDescriptor
The pivot cache this table is based on.
sal_Int32 mnField
Number of items or percent or sum to be shown.
void setBiffSubtotal(sal_Int32 nSubtotal)
Sets the subtotal aggregation function for BIFF import.
void setBiffShowDataAs(sal_Int32 nShowDataAs)
Sets the 'show data as' type for BIFF import.
void importTop10Filter(SequenceInputStream &rStrm)
Reads additional settings of a field filter from the TOP10FILTER record.
XML_TOKEN_INVALID
void finalizeFieldsImport()
Finalizes all fields, finds field names and creates grouping fields.
OptValue< sal_uInt32 > getUnsigned(sal_Int32 nAttrToken) const
bool mbHidden
True = show item details (items of child fields).
bool getFlag(Type nBitField, Type nMask)
bool mbInsertBlankRow
True = show subtotals on top of items in outline or compact mode.
void importPivotTableDefinition(const AttributeList &rAttribs)
Reads global pivot table settings from the pivotTableDefinition element.
void importPageField(const AttributeList &rAttribs)
Reads the settings of a field located in the page dimension from the pageField element.
bool mbInsertPageBreak
True = insert blank rows after items.
bool mbCountASubtotal
True = show sum subtotals.
bool mbDataField
Item in reference field for autosorting.
sal_Int32 getCacheDatabaseIndex(sal_Int32 nFieldIdx) const
Returns the source column index of the pivot field with the passed index, or -1.
double mfValue
Second string value for label filter.
void importPTPageField(SequenceInputStream &rStrm)
Reads the settings of a field located in the page dimension from the PTPAGEFIELD record.
sal_Int32 mnFirstHeaderRow
Target cell range for the pivot table.
const PPTXLayoutInfo aLayoutInfo[LAYOUT_SIZE]
PTFieldItemModel()
True = item is hidden.
#define TOOLS_WARN_EXCEPTION(area, stream)
#define SAL_MAX_INT32
IndexVector maRowFields
Data layout field.
SC_DLLPUBLIC void SetDimensionData(const ScDPDimensionSaveData *pNew)
Definition: dpsave.cxx:1202
SC_DLLPUBLIC bool HasPivotTable() const
Definition: documen3.cxx:360
void importFilter(const AttributeList &rAttribs)
Reads the settings of a field filter from the filter element.
container_type::value_type value_type
sal_Int32 mnType
bool mbAutoShow
True = insert page breaks after items.
PTLocationModel maLocationModel
Global pivot table settings.
static void importField(IndexVector &orFields, const AttributeList &rAttribs)
Reads a field index for the row or column dimension.
bool mbApplyFill
True = apply border from autoformatting.
bool mbApplyProtection
True = apply fill from autoformatting.
PivotTableFieldVector maFields
const PivotCacheField * getCacheFieldOfDataField(sal_Int32 nDataItemIdx) const
Returns the base cache field of the data field item with the specified index.
PivotTable(const WorkbookHelper &rHelper)
void finalizeImport()
Applies the filter to the associated pivot table field if possible.
void setFinalGroupName(const OUString &rFinalGroupName)
Set the finalized group name of this field.
sal_Int32 mnShowDataAs
Subtotal aggregation function.
ScDPSaveData * GetSaveData() const
Definition: dpobject.hxx:141
sal_Int32 mnNumFmtId
Base item for 'show data as'.
void applyItemCaptions(const IdCaptionPairList &vCaptions)
Apply user Captions to imported group data.
bool mbSubtotalTop
True = show in outline view, false = show in tabular view.
void putToInteropGrabBag(const OUString &sName, const AttributeList &rAttribs)
Puts the attributes to the named grab bag value.
void importPTRowFields(SequenceInputStream &rStrm)
Reads the indexes of all fields located in the row dimension from a PTROWFIELDS record.
bool mbShowAll
True = show variance of population subtotals.
SCCOL Col() const
Definition: address.hxx:266
sal_Int32 mnAutoShowRankBy
Number of items (or percent/sum) to be shown in auto show filter.
css::uno::Reference< css::sheet::XDataPilotField > getDataPilotField(const OUString &rFieldName) const
Returns the associated data pilot field for the specified pivot table field.
sal_Int32 mnType
Member property field.
void finalizeParentGroupingImport(const css::uno::Reference< css::sheet::XDataPilotField > &rxBaseDPField, const PivotCacheField &rBaseCacheField, PivotCacheGroupItemVector &orItemNames)
Creates all grouped fields for the specified cache field after import.
void importPTDefinition(SequenceInputStream &rStrm)
Reads global pivot table settings from the PTDEFINITION record.
void convertPageField(const PTPageFieldModel &rPageField)
Converts dimension and other settings for a page field.
SC_DLLPUBLIC void SetShowDetails(bool bSet)
Definition: dpsave.cxx:105
void setBiffAxis(sal_uInt8 nAxisFlags)
Sets axis type for BIFF import.
bool mbApplyBorder
True = apply alignment from autoformatting.
css::uno::Reference< css::sheet::XDataPilotField > getDataLayoutField() const
Returns the data layout field used to store all data fields in row/col dimension. ...
bool mbStdDevSubtotal
True = show count numbers subtotals.
bool mbMaxSubtotal
True = show average subtotals.
OUString maDPFieldName
Pivot field settings.
PTPageFieldModel()
Index of field item that is shown by the page field.
PivotTableField & createTableField()
Creates and returns a new pivot table field.
void importPTLocation(SequenceInputStream &rStrm, sal_Int16 nSheet)
Reads the location of the pivot table from the PTLOCATION record.
void importPTDataField(SequenceInputStream &rStrm)
Reads the settings of a field located in the data dimension from the PTDATAFIELD record.
sal_Int64 getRemaining() const
bool mbVarSubtotal
True = show standard deviation of population subtotals.
PivotTableFilterVector maFilters
Settings for all fields in data area.
void convertDataField(const PTDataFieldModel &rDataField)
Converts dimension and other settings for a data field.
sal_Int32 mnMeasureHier
Data field for filter calculation.
DataFieldVector maDataFields
Settings for all fields in page dimension.
sal_Int32 mnBaseField
Show data as, based on another field.
void importPTField(SequenceInputStream &rStrm)
Imports pivot field settings from the PTFIELD record.
PivotCacheField * getCacheField(sal_Int32 nFieldIdx)
Returns the cache field with the specified index.
void importTop10(const AttributeList &rAttribs)
Reads additional settings of a field filter from the top10 element.
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
bool mbShowDetails
User caption of the item.
sal_Int32 mnSortType
Index of the data field auto show filter is based on.
sal_Int32 mnNumFmtId
Axis this field is assigned to (none, row, column, page).
PivotTableField maDataField
All pivot table fields.
OUString msCaption
Type of the item.
void importItem(const AttributeList &rAttribs)
Imports settings of an item in this pivot field from the item element.
sal_Int32 mnRowPageCount
First column of data cells (relative in pivot table).
void convertColField()
Converts dimension and other settings for a column field.
void importReferenceItem(const AttributeList &rAttribs)
Imports pivot field item reference settings from the x element.
PTDefinitionModel maDefModel
All field filters.
const css::uno::Reference< css::xml::sax::XFastAttributeList > & getFastAttributeList() const
bool mbVarPSubtotal
True = show variance subtotals.
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
bool mbSumSubtotal
True = show default subtotals.
bool isValidDataSource() const
Returns true, if the pivot cache is based on a valid data source, so that pivot tables can be created...
PivotTable & createPivotTable()
Creates and returns a new pivot table.
OUString maStrValue1
Description of the field filter.
sal_Int32 mnAutoShowItems
Number format for field items.
bool mbApplyFont
True = apply number format from autoformatting.
static css::uno::Sequence< typename VectorType::value_type > vectorToSequence(const VectorType &rVector)
IndexVector maColFields
Indexes to fields in row dimension.
OUString getFormattedName(const ScDPSaveDimension &rSaveDim, ScDPObject *pObj, const DateTime &rNullDate) const
Returns the string representation of the item, using the actual formatting.
PivotCacheField * getCacheField(sal_Int32 nFieldIdx)
Returns the cache field with the specified index.
css::uno::Reference< css::sheet::XSpreadsheet > getSheetFromDoc(sal_Int32 nSheet) const
Returns a reference to the specified spreadsheet in the document model.
sal_Int32 mnId
Evaluation order index.
void importReference(const AttributeList &rAttribs)
Imports pivot field reference settings from the reference element.
sal_Int32 mnMemPropField
Base pivot field.
sal_Int32 mnSortRefField
Autosorting type.
void finalizeDateGroupingImport(const css::uno::Reference< css::sheet::XDataPilotField > &rxBaseDPField, sal_Int32 nBaseFieldIdx)
Finalizes the grouped date field after import.
sal_Int32 mnField
Name of the data field.
PTDataFieldModel()
Number format for the result.
PivotTableBuffer(const WorkbookHelper &rHelper)
bool mbAverageSubtotal
True = show count all subtotals.
PivotTableFilter & createTableFilter()
Creates and returns a new pivot table filter.
void finalizeImportBasedOnCache(const css::uno::Reference< css::sheet::XDataPilotDescriptor > &rxDPDesc)
bool mbApplyNumFmt
Index of predefined autoformatting.
PivotTableField * getTableField(sal_Int32 nFieldIdx)
Returns a pivot table field by its index.
void importPTReference(SequenceInputStream &rStrm)
Imports pivot field reference settings from the PTREFERENCE record.
void importPTFilter(SequenceInputStream &rStrm)
Reads the settings of a field filter from the PTFILTER record.
void importPivotField(const AttributeList &rAttribs)
Imports pivot field settings from the pivotField element.
bool mbCountSubtotal
True = show product subtotals.
PageFieldVector maPageFields
Indexes to fields in column dimension.
SC_DLLPUBLIC ScDPSaveDimension * GetDimensionByName(const OUString &rName)
Get a dimension object by its name.
Definition: dpsave.cxx:834
PTFieldModel maModel
All items of this field.
sal_Int32 mnBaseItem
Base field for 'show data as'.
OUString maDescription
Name of the field filter.
bool setProperty(sal_Int32 nPropId, const Type &rValue)
sal_Int32 getParentGroupField() const
Returns the index of the parent group field that groups the items of this field.
void convertRowField()
Converts dimension and other settings for a row field.
PTLocationModel()
Number of columns in page filter area.
bool mbMinSubtotal
True = show maximum subtotals.
PivotTableField(PivotTable &rPivotTable, sal_Int32 nFieldIndex)
OptValue< sal_Int32 > getToken(sal_Int32 nAttrToken) const
void importPTColFields(SequenceInputStream &rStrm)
Reads the indexes of all fields located in the column dimension from a PTCOLFIELDS record...
AddressConverter & getAddressConverter() const
Returns the converter for string to cell address/range conversion.
::std::vector< PivotCacheGroupItem > PivotCacheGroupItemVector
bool mbDefaultSubtotal
True = field appears in data area.
PivotCache * importPivotCacheFragment(sal_Int32 nCacheId)
Imports and stores a pivot cache definition fragment on first call, returns the imported cache on sub...
PivotTableFilter(const PivotTable &rPivotTable)
const OUString & getName() const
Returns the name of the cache field.
ScDocument & getDoc()
sal_Int32 mnType
Index to shared item in pivot cache.