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