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