1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pivottablebuffer.cxx,v $
10 * $Revision: 1.3.28.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/xls/pivottablebuffer.hxx"
33 #include <com/sun/star/container/XIndexAccess.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/sheet/CellFlags.hpp>
36 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
37 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
38 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
39 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
40 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
41 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
42 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
43 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
44 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
45 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
46 #include <com/sun/star/sheet/GeneralFunction.hpp>
47 #include <com/sun/star/sheet/XDataPilotDataLayoutFieldSupplier.hpp>
48 #include <com/sun/star/sheet/XDataPilotField.hpp>
49 #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
50 #include <com/sun/star/sheet/XSheetOperation.hpp>
51 #include "properties.hxx"
52 #include "oox/helper/attributelist.hxx"
53 #include "oox/helper/propertyset.hxx"
54 #include "oox/helper/recordinputstream.hxx"
55 #include "oox/xls/addressconverter.hxx"
56 #include "oox/xls/biffinputstream.hxx"
58 using ::rtl::OUString
;
59 using ::com::sun::star::uno::Exception
;
60 using ::com::sun::star::uno::Reference
;
61 using ::com::sun::star::uno::UNO_QUERY
;
62 using ::com::sun::star::uno::UNO_QUERY_THROW
;
63 using ::com::sun::star::uno::UNO_SET_THROW
;
64 using ::com::sun::star::beans::XPropertySet
;
65 using ::com::sun::star::container::XIndexAccess
;
66 using ::com::sun::star::container::XNameAccess
;
67 using ::com::sun::star::container::XNamed
;
68 using ::com::sun::star::table::CellAddress
;
69 using ::com::sun::star::sheet::DataPilotFieldOrientation
;
70 using ::com::sun::star::sheet::XDataPilotDataLayoutFieldSupplier
;
71 using ::com::sun::star::sheet::XDataPilotDescriptor
;
72 using ::com::sun::star::sheet::XDataPilotField
;
73 using ::com::sun::star::sheet::XDataPilotTables
;
74 using ::com::sun::star::sheet::XDataPilotTablesSupplier
;
75 using ::com::sun::star::sheet::XSheetOperation
;
80 // ============================================================================
84 const sal_Int32 OOX_PT_DATALAYOUTFIELD
= -2; /// Placeholder index of data layout field.
86 const sal_Int32 OOX_PT_PREVIOUS_ITEM
= 0x001000FC; /// Calculation of data item result is based on previous item.
87 const sal_Int32 OOX_PT_NEXT_ITEM
= 0x001000FD; /// Calculation of data item result is based on next item.
89 // ----------------------------------------------------------------------------
91 const sal_uInt32 OOBIN_PTFIELD_DATAFIELD
= 0x00000008;
92 const sal_uInt32 OOBIN_PTFIELD_DEFAULT
= 0x00000100;
93 const sal_uInt32 OOBIN_PTFIELD_SUM
= 0x00000200;
94 const sal_uInt32 OOBIN_PTFIELD_COUNTA
= 0x00000400;
95 const sal_uInt32 OOBIN_PTFIELD_AVERAGE
= 0x00000800;
96 const sal_uInt32 OOBIN_PTFIELD_MAX
= 0x00001000;
97 const sal_uInt32 OOBIN_PTFIELD_MIN
= 0x00002000;
98 const sal_uInt32 OOBIN_PTFIELD_PRODUCT
= 0x00004000;
99 const sal_uInt32 OOBIN_PTFIELD_COUNT
= 0x00008000;
100 const sal_uInt32 OOBIN_PTFIELD_STDDEV
= 0x00010000;
101 const sal_uInt32 OOBIN_PTFIELD_STDDEVP
= 0x00020000;
102 const sal_uInt32 OOBIN_PTFIELD_VAR
= 0x00040000;
103 const sal_uInt32 OOBIN_PTFIELD_VARP
= 0x00080000;
105 const sal_uInt32 OOBIN_PTFIELD_SHOWALL
= 0x00000020;
106 const sal_uInt32 OOBIN_PTFIELD_OUTLINE
= 0x00000040;
107 const sal_uInt32 OOBIN_PTFIELD_INSERTBLANKROW
= 0x00000080;
108 const sal_uInt32 OOBIN_PTFIELD_SUBTOTALTOP
= 0x00000100;
109 const sal_uInt32 OOBIN_PTFIELD_INSERTPAGEBREAK
= 0x00000800;
110 const sal_uInt32 OOBIN_PTFIELD_AUTOSORT
= 0x00001000;
111 const sal_uInt32 OOBIN_PTFIELD_SORTASCENDING
= 0x00002000;
112 const sal_uInt32 OOBIN_PTFIELD_AUTOSHOW
= 0x00004000;
113 const sal_uInt32 OOBIN_PTFIELD_AUTOSHOWTOP
= 0x00008000;
114 const sal_uInt32 OOBIN_PTFIELD_MULTIPAGEITEMS
= 0x00080000;
116 const sal_uInt16 OOBIN_PTFITEM_HIDDEN
= 0x0001;
117 const sal_uInt16 OOBIN_PTFITEM_HIDEDETAILS
= 0x0002;
119 const sal_uInt8 OOBIN_PTPAGEFIELD_HASNAME
= 0x01;
120 const sal_uInt8 OOBIN_PTPAGEFIELD_HASOLAPCAPTION
= 0x02;
121 const sal_Int32 OOBIN_PTPAGEFIELD_MULTIITEMS
= 0x001000FE;
123 const sal_uInt16 OOBIN_PTFILTER_HASNAME
= 0x0001;
124 const sal_uInt16 OOBIN_PTFILTER_HASDESCRIPTION
= 0x0002;
125 const sal_uInt16 OOBIN_PTFILTER_HASSTRVALUE1
= 0x0004;
126 const sal_uInt16 OOBIN_PTFILTER_HASSTRVALUE2
= 0x0008;
128 const sal_uInt8 OOBIN_TOP10FILTER_TOP
= 0x01;
129 const sal_uInt8 OOBIN_TOP10FILTER_PERCENT
= 0x02;
131 const sal_uInt32 OOBIN_PTDEF_SHOWITEMS
= 0x00000100;
132 const sal_uInt32 OOBIN_PTDEF_DISABLEFIELDLIST
= 0x00000400;
133 const sal_uInt32 OOBIN_PTDEF_HIDECALCMEMBERS
= 0x00001000;
134 const sal_uInt32 OOBIN_PTDEF_WITHHIDDENTOTALS
= 0x00002000;
135 const sal_uInt32 OOBIN_PTDEF_HIDEDRILL
= 0x00100000;
136 const sal_uInt32 OOBIN_PTDEF_PRINTDRILL
= 0x00200000;
137 const sal_uInt32 OOBIN_PTDEF_HIDEHEADERS
= 0x80000000;
139 const sal_uInt32 OOBIN_PTDEF_SHOWEMPTYROW
= 0x00000004;
140 const sal_uInt32 OOBIN_PTDEF_SHOWEMPTYCOL
= 0x00000008;
141 const sal_uInt32 OOBIN_PTDEF_ENABLEDRILL
= 0x00000020;
142 const sal_uInt32 OOBIN_PTDEF_PRESERVEFORMATTING
= 0x00000080;
143 const sal_uInt32 OOBIN_PTDEF_SHOWERROR
= 0x00000200;
144 const sal_uInt32 OOBIN_PTDEF_SHOWMISSING
= 0x00000400;
145 const sal_uInt32 OOBIN_PTDEF_PAGEOVERTHENDOWN
= 0x00000800;
146 const sal_uInt32 OOBIN_PTDEF_SUBTOTALHIDDENITEMS
= 0x00001000;
147 const sal_uInt32 OOBIN_PTDEF_ROWGRANDTOTALS
= 0x00002000;
148 const sal_uInt32 OOBIN_PTDEF_COLGRANDTOTALS
= 0x00004000;
149 const sal_uInt32 OOBIN_PTDEF_FIELDPRINTTITLES
= 0x00008000;
150 const sal_uInt32 OOBIN_PTDEF_ITEMPRINTTITLES
= 0x00020000;
151 const sal_uInt32 OOBIN_PTDEF_MERGEITEM
= 0x00040000;
152 const sal_uInt32 OOBIN_PTDEF_HASDATACAPTION
= 0x00080000;
153 const sal_uInt32 OOBIN_PTDEF_HASGRANDTOTALCAPTION
= 0x00100000;
154 const sal_uInt32 OOBIN_PTDEF_HASPAGESTYLE
= 0x00200000;
155 const sal_uInt32 OOBIN_PTDEF_HASPIVOTTABLESTYLE
= 0x00400000;
156 const sal_uInt32 OOBIN_PTDEF_HASVACATEDSTYLE
= 0x00800000;
157 const sal_uInt32 OOBIN_PTDEF_HASTAG
= 0x40000000;
159 const sal_uInt32 OOBIN_PTDEF_NOERRORCAPTION
= 0x00000040;
160 const sal_uInt32 OOBIN_PTDEF_NOMISSINGCAPTION
= 0x00000080;
161 const sal_uInt32 OOBIN_PTDEF_HASROWHEADERCAPTION
= 0x00000400;
162 const sal_uInt32 OOBIN_PTDEF_HASCOLHEADERCAPTION
= 0x00000800;
163 const sal_uInt32 OOBIN_PTDEF_FIELDLISTSORTASC
= 0x00001000;
164 const sal_uInt32 OOBIN_PTDEF_NOCUSTOMLISTSORT
= 0x00004000;
166 const sal_uInt8 OOBIN_PTDEF_ROWAXIS
= 1;
167 const sal_uInt8 OOBIN_PTDEF_COLAXIS
= 2;
169 // ----------------------------------------------------------------------------
171 const sal_uInt16 BIFF_PT_NOSTRING
= 0xFFFF;
173 const sal_uInt16 BIFF_PTFIELD_DATAFIELD
= 0x0008;
174 const sal_uInt16 BIFF_PTFIELD_DEFAULT
= 0x0001;
175 const sal_uInt16 BIFF_PTFIELD_SUM
= 0x0002;
176 const sal_uInt16 BIFF_PTFIELD_COUNTA
= 0x0004;
177 const sal_uInt16 BIFF_PTFIELD_AVERAGE
= 0x0008;
178 const sal_uInt16 BIFF_PTFIELD_MAX
= 0x0010;
179 const sal_uInt16 BIFF_PTFIELD_MIN
= 0x0020;
180 const sal_uInt16 BIFF_PTFIELD_PRODUCT
= 0x0040;
181 const sal_uInt16 BIFF_PTFIELD_COUNT
= 0x0080;
182 const sal_uInt16 BIFF_PTFIELD_STDDEV
= 0x0100;
183 const sal_uInt16 BIFF_PTFIELD_STDDEVP
= 0x0200;
184 const sal_uInt16 BIFF_PTFIELD_VAR
= 0x0400;
185 const sal_uInt16 BIFF_PTFIELD_VARP
= 0x0800;
187 const sal_uInt32 BIFF_PTFIELD2_SHOWALL
= 0x00000001;
188 const sal_uInt32 BIFF_PTFIELD2_AUTOSORT
= 0x00000200;
189 const sal_uInt32 BIFF_PTFIELD2_SORTASCENDING
= 0x00000400;
190 const sal_uInt32 BIFF_PTFIELD2_AUTOSHOW
= 0x00000800;
191 const sal_uInt32 BIFF_PTFIELD2_AUTOSHOWTOP
= 0x00001000;
192 const sal_uInt32 BIFF_PTFIELD2_OUTLINE
= 0x00200000;
193 const sal_uInt32 BIFF_PTFIELD2_INSERTBLANKROW
= 0x00400000;
194 const sal_uInt32 BIFF_PTFIELD2_SUBTOTALTOP
= 0x00800000;
196 const sal_uInt16 BIFF_PTFITEM_HIDDEN
= 0x0001;
197 const sal_uInt16 BIFF_PTFITEM_HIDEDETAILS
= 0x0002;
199 const sal_uInt16 BIFF_PTDEF_ROWGRANDTOTALS
= 0x0001;
200 const sal_uInt16 BIFF_PTDEF_COLGRANDTOTALS
= 0x0002;
202 const sal_uInt8 BIFF_PTDEF_ROWAXIS
= 1;
203 const sal_uInt8 BIFF_PTDEF_COLAXIS
= 2;
205 const sal_uInt32 BIFF_PTDEF2_PAGEOVERTHENDOWN
= 0x00000001;
206 const sal_uInt32 BIFF_PTDE2F_ENABLEDRILL
= 0x00020000;
207 const sal_uInt32 BIFF_PTDEF2_PRESERVEFORMATTING
= 0x00080000;
208 const sal_uInt32 BIFF_PTDEF2_MERGEITEM
= 0x00100000;
209 const sal_uInt32 BIFF_PTDEF2_SHOWERROR
= 0x00200000;
210 const sal_uInt32 BIFF_PTDEF2_SHOWMISSING
= 0x00400000;
211 const sal_uInt32 BIFF_PTDEF2_SUBTOTALHIDDENITEMS
= 0x00800000;
213 const sal_Int16 BIFF_PTPAGEFIELDS_ALLITEMS
= 0x7FFD;
215 const sal_Int16 BIFF_PTDATAFIELD_PREVIOUS
= 0x7FFB;
216 const sal_Int16 BIFF_PTDATAFIELD_NEXT
= 0x7FFC;
218 // ----------------------------------------------------------------------------
220 OUString
lclReadPivotString( const WorkbookHelper
& rHelper
, BiffInputStream
& rStrm
, sal_uInt16 nLen
)
222 if( nLen
== BIFF_PT_NOSTRING
)
224 return (rHelper
.getBiff() == BIFF8
) ? rStrm
.readUniStringBody( nLen
) : rStrm
.readCharArrayUC( nLen
, rHelper
.getTextEncoding() );
229 // ============================================================================
231 PTFieldItemModel::PTFieldItemModel() :
234 mbShowDetails( true ),
239 void PTFieldItemModel::setBinType( sal_uInt16 nType
)
241 static const sal_Int32 spnTypes
[] = { XML_data
, XML_default
,
242 XML_sum
, XML_countA
, XML_avg
, XML_max
, XML_min
, XML_product
, XML_count
,
243 XML_stdDev
, XML_stdDevP
, XML_var
, XML_varP
, XML_grand
, XML_blank
};
244 mnType
= STATIC_ARRAY_SELECT( spnTypes
, nType
, XML_data
);
247 // ----------------------------------------------------------------------------
249 PTFieldModel::PTFieldModel() :
250 mnAxis( XML_TOKEN_INVALID
),
252 mnAutoShowItems( 10 ),
253 mnAutoShowRankBy( -1 ),
254 mnSortType( XML_manual
),
255 mnSortRefField( -1 ),
257 mbDataField( false ),
258 mbDefaultSubtotal( true ),
259 mbSumSubtotal( false ),
260 mbCountASubtotal( false ),
261 mbAverageSubtotal( false ),
262 mbMaxSubtotal( false ),
263 mbMinSubtotal( false ),
264 mbProductSubtotal( false ),
265 mbCountSubtotal( false ),
266 mbStdDevSubtotal( false ),
267 mbStdDevPSubtotal( false ),
268 mbVarSubtotal( false ),
269 mbVarPSubtotal( false ),
272 mbSubtotalTop( true ),
273 mbInsertBlankRow( false ),
274 mbInsertPageBreak( false ),
276 mbTopAutoShow( true ),
277 mbMultiPageItems( false )
281 void PTFieldModel::setBinAxis( sal_uInt8 nAxis
)
283 /* Weird. The axis field is organized as bit field, but only one of the
284 row/col/page flags are allowed at the same time and refer to the values
285 'axisRow', 'axisCol', and 'axisPage' of the XML attribute
286 'pivotField@axis'. Additionally, the fourth bit determines if the field
287 is a data field, which may appear combined with the row/col/page flags.
288 Therefore, this bit is unrelated to the 'axisValues' value of the
289 'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
290 boolean attribute. */
291 static const sal_Int32 spnAxisIds
[] = { XML_TOKEN_INVALID
, XML_axisRow
, XML_axisCol
, XML_TOKEN_INVALID
, XML_axisPage
};
292 mnAxis
= STATIC_ARRAY_SELECT( spnAxisIds
, nAxis
, XML_TOKEN_INVALID
);
295 // ----------------------------------------------------------------------------
297 PTPageFieldModel::PTPageFieldModel() :
299 mnItem( OOBIN_PTPAGEFIELD_MULTIITEMS
)
303 // ----------------------------------------------------------------------------
305 PTDataFieldModel::PTDataFieldModel() :
307 mnSubtotal( XML_sum
),
308 mnShowDataAs( XML_normal
),
315 void PTDataFieldModel::setBinSubtotal( sal_Int32 nSubtotal
)
317 static 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
};
318 mnSubtotal
= STATIC_ARRAY_SELECT( spnSubtotals
, nSubtotal
, XML_TOKEN_INVALID
);
321 void PTDataFieldModel::setBinShowDataAs( sal_Int32 nShowDataAs
)
323 static sal_Int32 spnShowDataAs
[] = { XML_normal
, XML_difference
, XML_percent
, XML_percentDiff
, XML_runTotal
, XML_percentOfRow
, XML_percentOfCol
, XML_percentOfTotal
, XML_index
};
324 mnShowDataAs
= STATIC_ARRAY_SELECT( spnShowDataAs
, nShowDataAs
, XML_TOKEN_INVALID
);
327 // ----------------------------------------------------------------------------
329 PivotTableField::PivotTableField( PivotTable
& rPivotTable
, sal_Int32 nFieldIndex
) :
330 WorkbookHelper( rPivotTable
),
331 mrPivotTable( rPivotTable
),
332 mnFieldIndex( nFieldIndex
)
336 void PivotTableField::importPivotField( const AttributeList
& rAttribs
)
338 /* The documentation mentions a value 'axisValues' for the attribute
339 'pivotField@axis'. But this value is not used to mark a data field, as
340 data fields may be inserted in one of the row/column/page dimensions at
341 the same time. Therefore, the boolean attribute 'pivotField@dataField'
342 is really used to mark data fields. */
343 maModel
.mnAxis
= rAttribs
.getToken( XML_axis
, XML_TOKEN_INVALID
);
344 maModel
.mnNumFmtId
= rAttribs
.getInteger( XML_numFmtId
, 0 );
345 maModel
.mnAutoShowItems
= rAttribs
.getInteger( XML_itemPageCount
, 10 );
346 maModel
.mnAutoShowRankBy
= rAttribs
.getInteger( XML_rankBy
, -1 );
347 maModel
.mnSortType
= rAttribs
.getToken( XML_sortType
, XML_manual
);
348 maModel
.mbDataField
= rAttribs
.getBool( XML_dataField
, false );
349 maModel
.mbDefaultSubtotal
= rAttribs
.getBool( XML_defaultSubtotal
, true );
350 maModel
.mbSumSubtotal
= rAttribs
.getBool( XML_sumSubtotal
, false );
351 maModel
.mbCountASubtotal
= rAttribs
.getBool( XML_countASubtotal
, false );
352 maModel
.mbAverageSubtotal
= rAttribs
.getBool( XML_avgSubtotal
, false );
353 maModel
.mbMaxSubtotal
= rAttribs
.getBool( XML_maxSubtotal
, false );
354 maModel
.mbMinSubtotal
= rAttribs
.getBool( XML_minSubtotal
, false );
355 maModel
.mbProductSubtotal
= rAttribs
.getBool( XML_productSubtotal
, false );
356 maModel
.mbCountSubtotal
= rAttribs
.getBool( XML_countSubtotal
, false );
357 maModel
.mbStdDevSubtotal
= rAttribs
.getBool( XML_stdDevSubtotal
, false );
358 maModel
.mbStdDevPSubtotal
= rAttribs
.getBool( XML_stdDevPSubtotal
, false );
359 maModel
.mbVarSubtotal
= rAttribs
.getBool( XML_varSubtotal
, false );
360 maModel
.mbVarPSubtotal
= rAttribs
.getBool( XML_varPSubtotal
, false );
361 maModel
.mbShowAll
= rAttribs
.getBool( XML_showAll
, true );
362 maModel
.mbOutline
= rAttribs
.getBool( XML_outline
, true );
363 maModel
.mbSubtotalTop
= rAttribs
.getBool( XML_subtotalTop
, true );
364 maModel
.mbInsertBlankRow
= rAttribs
.getBool( XML_insertBlankRow
, false );
365 maModel
.mbInsertPageBreak
= rAttribs
.getBool( XML_insertPageBreak
, false );
366 maModel
.mbAutoShow
= rAttribs
.getBool( XML_autoShow
, false );
367 maModel
.mbTopAutoShow
= rAttribs
.getBool( XML_topAutoShow
, true );
368 maModel
.mbMultiPageItems
= rAttribs
.getBool( XML_multipleItemSelectionAllowed
, false );
371 void PivotTableField::importItem( const AttributeList
& rAttribs
)
373 PTFieldItemModel aModel
;
374 aModel
.mnCacheItem
= rAttribs
.getInteger( XML_x
, -1 );
375 aModel
.mnType
= rAttribs
.getToken( XML_t
, XML_data
);
376 aModel
.mbShowDetails
= rAttribs
.getBool( XML_sd
, true );
377 aModel
.mbHidden
= rAttribs
.getBool( XML_h
, false );
378 maItems
.push_back( aModel
);
381 void PivotTableField::importReference( const AttributeList
& rAttribs
)
383 // field index is stored as unsigned integer
384 maModel
.mnSortRefField
= static_cast< sal_Int32
>( rAttribs
.getUnsigned( XML_field
, SAL_MAX_UINT32
) );
387 void PivotTableField::importReferenceItem( const AttributeList
& rAttribs
)
389 maModel
.mnSortRefItem
= rAttribs
.getInteger( XML_v
, -1 );
392 void PivotTableField::importPTField( RecordInputStream
& rStrm
)
394 sal_uInt32 nFlags1
, nFlags2
;
395 rStrm
>> nFlags1
>> maModel
.mnNumFmtId
>> nFlags2
>> maModel
.mnAutoShowItems
>> maModel
.mnAutoShowRankBy
;
397 maModel
.setBinAxis( extractValue
< sal_uInt8
>( nFlags1
, 0, 3 ) );
398 maModel
.mbDataField
= getFlag( nFlags1
, OOBIN_PTFIELD_DATAFIELD
);
399 maModel
.mbDefaultSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_DEFAULT
);
400 maModel
.mbSumSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_SUM
);
401 maModel
.mbCountASubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_COUNTA
);
402 maModel
.mbAverageSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_AVERAGE
);
403 maModel
.mbMaxSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_MAX
);
404 maModel
.mbMinSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_MIN
);
405 maModel
.mbProductSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_PRODUCT
);
406 maModel
.mbCountSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_COUNT
);
407 maModel
.mbStdDevSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_STDDEV
);
408 maModel
.mbStdDevPSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_STDDEVP
);
409 maModel
.mbVarSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_VAR
);
410 maModel
.mbVarPSubtotal
= getFlag( nFlags1
, OOBIN_PTFIELD_VARP
);
412 maModel
.mbShowAll
= getFlag( nFlags2
, OOBIN_PTFIELD_SHOWALL
);
413 maModel
.mbOutline
= getFlag( nFlags2
, OOBIN_PTFIELD_OUTLINE
);
414 maModel
.mbSubtotalTop
= getFlag( nFlags2
, OOBIN_PTFIELD_SUBTOTALTOP
);
415 maModel
.mbInsertBlankRow
= getFlag( nFlags2
, OOBIN_PTFIELD_INSERTBLANKROW
);
416 maModel
.mbInsertPageBreak
= getFlag( nFlags2
, OOBIN_PTFIELD_INSERTPAGEBREAK
);
417 maModel
.mbAutoShow
= getFlag( nFlags2
, OOBIN_PTFIELD_AUTOSHOW
);
418 maModel
.mbTopAutoShow
= getFlag( nFlags2
, OOBIN_PTFIELD_AUTOSHOWTOP
);
419 maModel
.mbMultiPageItems
= getFlag( nFlags2
, OOBIN_PTFIELD_MULTIPAGEITEMS
);
421 bool bAutoSort
= getFlag( nFlags2
, OOBIN_PTFIELD_AUTOSORT
);
422 bool bAscending
= getFlag( nFlags2
, OOBIN_PTFIELD_SORTASCENDING
);
423 maModel
.mnSortType
= bAutoSort
? (bAscending
? XML_ascending
: XML_descending
) : XML_manual
;
426 void PivotTableField::importPTFItem( RecordInputStream
& rStrm
)
428 PTFieldItemModel aModel
;
431 rStrm
>> nType
>> nFlags
>> aModel
.mnCacheItem
;
433 aModel
.setBinType( nType
);
434 aModel
.mbShowDetails
= !getFlag( nFlags
, OOBIN_PTFITEM_HIDEDETAILS
);
435 aModel
.mbHidden
= getFlag( nFlags
, OOBIN_PTFITEM_HIDDEN
);
437 maItems
.push_back( aModel
);
440 void PivotTableField::importPTReference( RecordInputStream
& rStrm
)
442 rStrm
>> maModel
.mnSortRefField
;
445 void PivotTableField::importPTReferenceItem( RecordInputStream
& rStrm
)
447 rStrm
>> maModel
.mnSortRefItem
;
450 void PivotTableField::importPTField( BiffInputStream
& rStrm
)
452 sal_uInt16 nAxis
, nSubtCount
, nSubtotals
;
453 rStrm
>> nAxis
>> nSubtCount
>> nSubtotals
;
454 rStrm
.skip( 2 ); // item count
456 maModel
.setBinAxis( extractValue
< sal_uInt8
>( nAxis
, 0, 3 ) );
457 maModel
.mbDataField
= getFlag( nAxis
, BIFF_PTFIELD_DATAFIELD
);
459 maModel
.mbDefaultSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_DEFAULT
);
460 maModel
.mbSumSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_SUM
);
461 maModel
.mbCountASubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_COUNTA
);
462 maModel
.mbAverageSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_AVERAGE
);
463 maModel
.mbMaxSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_MAX
);
464 maModel
.mbMinSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_MIN
);
465 maModel
.mbProductSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_PRODUCT
);
466 maModel
.mbCountSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_COUNT
);
467 maModel
.mbStdDevSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_STDDEV
);
468 maModel
.mbStdDevPSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_STDDEVP
);
469 maModel
.mbVarSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_VAR
);
470 maModel
.mbVarPSubtotal
= getFlag( nSubtotals
, BIFF_PTFIELD_VARP
);
472 // set different defaults for BIFF
473 maModel
.mbShowAll
= maModel
.mbOutline
= maModel
.mbSubtotalTop
= false;
475 // read following items
476 while( (rStrm
.getNextRecId() == BIFF_ID_PTFITEM
) && rStrm
.startNextRecord() )
477 importPTFItem( rStrm
);
479 // read following PTFIELD2 record with additional field settings
480 if( (getBiff() == BIFF8
) && (rStrm
.getNextRecId() == BIFF_ID_PTFIELD2
) && rStrm
.startNextRecord() )
481 importPTField2( rStrm
);
484 void PivotTableField::importPTField2( BiffInputStream
& rStrm
)
488 maModel
.mnSortRefItem
= rStrm
.readInt16();
489 maModel
.mnAutoShowRankBy
= rStrm
.readInt16();
490 maModel
.mnNumFmtId
= rStrm
.readuInt16();
492 maModel
.mnAutoShowItems
= extractValue
< sal_Int32
>( nFlags
, 24, 8 );
493 maModel
.mbShowAll
= getFlag( nFlags
, BIFF_PTFIELD2_SHOWALL
);
494 maModel
.mbOutline
= getFlag( nFlags
, BIFF_PTFIELD2_OUTLINE
);
495 maModel
.mbSubtotalTop
= getFlag( nFlags
, BIFF_PTFIELD2_SUBTOTALTOP
);
496 maModel
.mbInsertBlankRow
= getFlag( nFlags
, BIFF_PTFIELD2_INSERTBLANKROW
);
497 maModel
.mbAutoShow
= getFlag( nFlags
, BIFF_PTFIELD2_AUTOSHOW
);
498 maModel
.mbTopAutoShow
= getFlag( nFlags
, BIFF_PTFIELD2_AUTOSHOWTOP
);
500 bool bAutoSort
= getFlag( nFlags
, BIFF_PTFIELD2_AUTOSORT
);
501 bool bAscending
= getFlag( nFlags
, BIFF_PTFIELD2_SORTASCENDING
);
502 maModel
.mnSortType
= bAutoSort
? (bAscending
? XML_ascending
: XML_descending
) : XML_manual
;
503 // mnSortRefField == OOX_PT_DATALAYOUTFIELD will indicate sorting by data field
504 if( maModel
.mnSortRefItem
>= 0 )
505 maModel
.mnSortRefField
= OOX_PT_DATALAYOUTFIELD
;
508 void PivotTableField::importPTFItem( BiffInputStream
& rStrm
)
510 PTFieldItemModel aModel
;
511 sal_uInt16 nType
, nFlags
;
512 sal_Int16 nCacheItem
;
513 rStrm
>> nType
>> nFlags
>> nCacheItem
;
515 aModel
.setBinType( nType
);
516 aModel
.mnCacheItem
= nCacheItem
;
517 aModel
.mbShowDetails
= !getFlag( nFlags
, BIFF_PTFITEM_HIDEDETAILS
);
518 aModel
.mbHidden
= getFlag( nFlags
, BIFF_PTFITEM_HIDDEN
);
520 maItems
.push_back( aModel
);
523 void PivotTableField::finalizeImport( const Reference
< XDataPilotDescriptor
>& rxDPDesc
)
525 /* Process all fields based on source data, other fields (e.g. group
526 fields) are processed from here. PivotCacahe::getDatabaseIndex()
527 returns -1 for all fields not based on source data. */
528 Reference
< XDataPilotField
> xDPField
;
529 sal_Int32 nDatabaseIdx
= mrPivotTable
.getCacheDatabaseIndex( mnFieldIndex
);
530 if( (nDatabaseIdx
>= 0) && rxDPDesc
.is() ) try
532 // try to get the source field and its name from passed DataPilot descriptor
533 Reference
< XIndexAccess
> xDPFieldsIA( rxDPDesc
->getDataPilotFields(), UNO_SET_THROW
);
534 xDPField
.set( xDPFieldsIA
->getByIndex( nDatabaseIdx
), UNO_QUERY_THROW
);
535 Reference
< XNamed
> xDPFieldName( xDPField
, UNO_QUERY_THROW
);
536 maDPFieldName
= xDPFieldName
->getName();
537 OSL_ENSURE( maDPFieldName
.getLength() > 0, "PivotTableField::finalizeImport - no field name in source data found" );
539 // try to convert grouping settings
540 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
542 // numeric grouping is done inplace, no nested group fields will appear
543 if( pCacheField
->hasNumericGrouping() )
545 pCacheField
->convertNumericGrouping( xDPField
);
547 else if( pCacheField
->hasDateGrouping() )
549 // first date group settings are inplace
550 pCacheField
->createDateGroupField( xDPField
);
551 // create all nested group fields (if any)
552 mrPivotTable
.finalizeDateGroupingImport( xDPField
, mnFieldIndex
);
554 else if( pCacheField
->hasParentGrouping() )
556 // create a list of all item names, needed to map between original and group items
557 ::std::vector
< OUString
> aItems
;
558 pCacheField
->getCacheItemNames( aItems
);
559 PivotCacheGroupItemVector aItemNames
;
560 for( ::std::vector
< OUString
>::iterator aIt
= aItems
.begin(), aEnd
= aItems
.end(); aIt
!= aEnd
; ++aIt
)
561 aItemNames
.push_back( PivotCacheGroupItem( *aIt
) );
562 // create all nested group fields (if any)
563 mrPivotTable
.finalizeParentGroupingImport( xDPField
, *pCacheField
, aItemNames
);
572 void PivotTableField::finalizeDateGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
, sal_Int32 nBaseFieldIdx
)
574 if( maDPFieldName
.getLength() == 0 ) // prevent endless loops if file format is broken
576 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
578 if( !pCacheField
->isDatabaseField() && pCacheField
->hasDateGrouping() && (pCacheField
->getGroupBaseField() == nBaseFieldIdx
) )
580 maDPFieldName
= pCacheField
->createDateGroupField( rxBaseDPField
);
581 OSL_ENSURE( maDPFieldName
.getLength() > 0, "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
587 void PivotTableField::finalizeParentGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
, PivotCacheGroupItemVector
& orItemNames
)
589 if( maDPFieldName
.getLength() == 0 ) // prevent endless loops if file format is broken
591 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
593 maDPFieldName
= pCacheField
->createParentGroupField( rxBaseDPField
, orItemNames
);
594 // on success, try to create nested group fields
595 Reference
< XDataPilotField
> xDPField
= mrPivotTable
.getDataPilotField( maDPFieldName
);
597 mrPivotTable
.finalizeParentGroupingImport( xDPField
, *pCacheField
, orItemNames
);
602 void PivotTableField::convertRowField()
604 convertRowColPageField( XML_axisRow
);
607 void PivotTableField::convertColField()
609 convertRowColPageField( XML_axisCol
);
612 void PivotTableField::convertHiddenField()
614 convertRowColPageField( XML_TOKEN_INVALID
);
617 void PivotTableField::convertPageField( const PTPageFieldModel
& rPageField
)
619 OSL_ENSURE( rPageField
.mnField
== mnFieldIndex
, "PivotTableField::convertPageField - wrong field index" );
620 // convert all settings common for row/column/page fields
621 Reference
< XDataPilotField
> xDPField
= convertRowColPageField( XML_axisPage
);
625 PropertySet
aPropSet( xDPField
);
626 using namespace ::com::sun::star::sheet
;
628 // find cache item used as 'selected page'
629 sal_Int32 nCacheItem
= -1;
630 if( maModel
.mbMultiPageItems
)
632 // multiple items may be selected
633 OSL_ENSURE( rPageField
.mnItem
== OOBIN_PTPAGEFIELD_MULTIITEMS
, "PivotTableField::convertPageField - unexpected cache item index" );
634 // try to find a single visible item
635 bool bHasMultiItems
= false;
636 for( ItemModelVector::iterator aIt
= maItems
.begin(), aEnd
= maItems
.end(); (aIt
!= aEnd
) && !bHasMultiItems
; ++aIt
)
638 if( (aIt
->mnType
== XML_data
) && !aIt
->mbHidden
)
640 bHasMultiItems
= nCacheItem
>= 0;
641 nCacheItem
= bHasMultiItems
? -1 : aIt
->mnCacheItem
;
647 // single item may be selected
648 if( (0 <= rPageField
.mnItem
) && (rPageField
.mnItem
< static_cast< sal_Int32
>( maItems
.size() )) )
649 nCacheItem
= maItems
[ rPageField
.mnItem
].mnCacheItem
;
652 if( nCacheItem
>= 0 )
654 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) )
656 if( const PivotCacheItem
* pSharedItem
= pCacheField
->getCacheItem( nCacheItem
) )
658 OUString aSelectedPage
= pSharedItem
->getName();
659 if( aSelectedPage
.getLength() > 0 )
660 aPropSet
.setProperty( PROP_SelectedPage
, aSelectedPage
);
667 void PivotTableField::convertDataField( const PTDataFieldModel
& rDataField
)
669 OSL_ENSURE( rDataField
.mnField
== mnFieldIndex
, "PivotTableField::convertDataField - wrong field index" );
670 OSL_ENSURE( maModel
.mbDataField
, "PivotTableField::convertDataField - not a data field" );
671 Reference
< XDataPilotField
> xDPField
= mrPivotTable
.getDataPilotField( maDPFieldName
);
674 PropertySet
aPropSet( xDPField
);
675 using namespace ::com::sun::star::sheet
;
678 aPropSet
.setProperty( PROP_Orientation
, DataPilotFieldOrientation_DATA
);
680 /* Field aggregation function. Documentation is a little bit confused
681 about which names to use for the count functions. The name 'count'
682 means 'count all', and 'countNum' means 'count numbers'. On the
683 other hand, for subtotals, 'countA' means 'count all', and 'count'
684 means 'count numbers' (see above). */
685 GeneralFunction eAggFunc
= GeneralFunction_SUM
;
686 switch( rDataField
.mnSubtotal
)
688 case XML_sum
: eAggFunc
= GeneralFunction_SUM
; break;
689 case XML_count
: eAggFunc
= GeneralFunction_COUNT
; break;
690 case XML_average
: eAggFunc
= GeneralFunction_AVERAGE
; break;
691 case XML_max
: eAggFunc
= GeneralFunction_MAX
; break;
692 case XML_min
: eAggFunc
= GeneralFunction_MIN
; break;
693 case XML_product
: eAggFunc
= GeneralFunction_PRODUCT
; break;
694 case XML_countNums
: eAggFunc
= GeneralFunction_COUNTNUMS
; break;
695 case XML_stdDev
: eAggFunc
= GeneralFunction_STDEV
; break;
696 case XML_stdDevp
: eAggFunc
= GeneralFunction_STDEVP
; break;
697 case XML_var
: eAggFunc
= GeneralFunction_VAR
; break;
698 case XML_varp
: eAggFunc
= GeneralFunction_VARP
; break;
699 default: OSL_ENSURE( false, "PivotTableField::convertDataField - unknown aggregation function" );
701 aPropSet
.setProperty( PROP_Function
, eAggFunc
);
703 // field reference ('show data as')
704 DataPilotFieldReference aReference
;
705 aReference
.ReferenceType
= DataPilotFieldReferenceType::NONE
;
706 switch( rDataField
.mnShowDataAs
)
708 case XML_difference
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ITEM_DIFFERENCE
; break;
709 case XML_percent
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ITEM_PERCENTAGE
; break;
710 case XML_percentDiff
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE
; break;
711 case XML_runTotal
: aReference
.ReferenceType
= DataPilotFieldReferenceType::RUNNING_TOTAL
; break;
712 case XML_percentOfRow
: aReference
.ReferenceType
= DataPilotFieldReferenceType::ROW_PERCENTAGE
; break;
713 case XML_percentOfCol
: aReference
.ReferenceType
= DataPilotFieldReferenceType::COLUMN_PERCENTAGE
; break;
714 case XML_percentOfTotal
: aReference
.ReferenceType
= DataPilotFieldReferenceType::TOTAL_PERCENTAGE
; break;
715 case XML_index
: aReference
.ReferenceType
= DataPilotFieldReferenceType::INDEX
; break;
717 if( aReference
.ReferenceType
!= DataPilotFieldReferenceType::NONE
)
719 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( rDataField
.mnBaseField
) )
721 aReference
.ReferenceField
= pCacheField
->getName();
722 switch( rDataField
.mnBaseItem
)
724 case OOX_PT_PREVIOUS_ITEM
:
725 aReference
.ReferenceItemType
= DataPilotFieldReferenceItemType::PREVIOUS
;
727 case OOX_PT_NEXT_ITEM
:
728 aReference
.ReferenceItemType
= DataPilotFieldReferenceItemType::NEXT
;
731 aReference
.ReferenceItemType
= DataPilotFieldReferenceItemType::NAMED
;
732 if( const PivotCacheItem
* pCacheItem
= pCacheField
->getCacheItem( rDataField
.mnBaseItem
) )
733 aReference
.ReferenceItemName
= pCacheItem
->getName();
735 aPropSet
.setProperty( PROP_Reference
, aReference
);
741 // private --------------------------------------------------------------------
743 Reference
< XDataPilotField
> PivotTableField::convertRowColPageField( sal_Int32 nAxis
)
745 bool bDataLayout
= mnFieldIndex
== OOX_PT_DATALAYOUTFIELD
;
746 Reference
< XDataPilotField
> xDPField
= bDataLayout
? mrPivotTable
.getDataLayoutField() : mrPivotTable
.getDataPilotField( maDPFieldName
);
747 OSL_ENSURE( bDataLayout
|| (nAxis
== maModel
.mnAxis
), "PivotTableField::convertRowColPageField - field axis mismatch" );
751 PropertySet
aPropSet( xDPField
);
752 using namespace ::com::sun::star::sheet
;
755 DataPilotFieldOrientation eFieldOrient
= DataPilotFieldOrientation_HIDDEN
;
758 case XML_axisRow
: eFieldOrient
= DataPilotFieldOrientation_ROW
; break;
759 case XML_axisCol
: eFieldOrient
= DataPilotFieldOrientation_COLUMN
; break;
760 case XML_axisPage
: eFieldOrient
= DataPilotFieldOrientation_PAGE
; break;
762 if( eFieldOrient
!= DataPilotFieldOrientation_HIDDEN
)
763 aPropSet
.setProperty( PROP_Orientation
, eFieldOrient
);
765 // all other settings not for the data layout field
768 /* Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
769 explicit functions are set. This is different behaviour between
770 XML (where 'defaultSubtotal' is set regardless of other
771 functions) and binary formats (where 'defaultSubtotal' is not
772 set if other functions are set). */
773 ::std::vector
< GeneralFunction
> aSubtotals
;
774 /* Order of subtotals is fixed in Excel. Documentation is a little
775 bit confused about which names to use for the count functions.
776 For subtotals, 'countA' means 'count all', and 'count' means
777 'count numbers'. On the other hand, for the data field
778 aggregation function, 'count' means 'count all', and 'countNum'
779 means 'count numbers' (see below). */
780 if( maModel
.mbSumSubtotal
) aSubtotals
.push_back( GeneralFunction_SUM
);
781 if( maModel
.mbCountASubtotal
) aSubtotals
.push_back( GeneralFunction_COUNT
);
782 if( maModel
.mbAverageSubtotal
) aSubtotals
.push_back( GeneralFunction_AVERAGE
);
783 if( maModel
.mbMaxSubtotal
) aSubtotals
.push_back( GeneralFunction_MAX
);
784 if( maModel
.mbMinSubtotal
) aSubtotals
.push_back( GeneralFunction_MIN
);
785 if( maModel
.mbProductSubtotal
) aSubtotals
.push_back( GeneralFunction_PRODUCT
);
786 if( maModel
.mbCountSubtotal
) aSubtotals
.push_back( GeneralFunction_COUNTNUMS
);
787 if( maModel
.mbStdDevSubtotal
) aSubtotals
.push_back( GeneralFunction_STDEV
);
788 if( maModel
.mbStdDevPSubtotal
) aSubtotals
.push_back( GeneralFunction_STDEVP
);
789 if( maModel
.mbVarSubtotal
) aSubtotals
.push_back( GeneralFunction_VAR
);
790 if( maModel
.mbVarPSubtotal
) aSubtotals
.push_back( GeneralFunction_VARP
);
791 // if no function is set manually, check the 'defaultSubtotal' flag
792 if( aSubtotals
.empty() && maModel
.mbDefaultSubtotal
)
793 aSubtotals
.push_back( GeneralFunction_AUTO
);
794 aPropSet
.setProperty( PROP_Subtotals
, ContainerHelper::vectorToSequence( aSubtotals
) );
797 DataPilotFieldLayoutInfo aLayoutInfo
;
798 aLayoutInfo
.LayoutMode
= maModel
.mbOutline
?
799 (maModel
.mbSubtotalTop
? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP
: DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM
) :
800 DataPilotFieldLayoutMode::TABULAR_LAYOUT
;
801 aLayoutInfo
.AddEmptyLines
= maModel
.mbInsertBlankRow
;
802 aPropSet
.setProperty( PROP_LayoutInfo
, aLayoutInfo
);
803 aPropSet
.setProperty( PROP_ShowEmpty
, maModel
.mbShowAll
);
805 // auto show (OOXML3/OOBIN3 only)
806 if( maModel
.mbAutoShow
)
808 DataPilotFieldAutoShowInfo aAutoShowInfo
;
809 aAutoShowInfo
.IsEnabled
= sal_True
;
810 aAutoShowInfo
.ShowItemsMode
= maModel
.mbTopAutoShow
? DataPilotFieldShowItemsMode::FROM_TOP
: DataPilotFieldShowItemsMode::FROM_BOTTOM
;
811 aAutoShowInfo
.ItemCount
= maModel
.mnAutoShowItems
;
812 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheFieldOfDataField( maModel
.mnAutoShowRankBy
) )
813 aAutoShowInfo
.DataField
= pCacheField
->getName();
814 aPropSet
.setProperty( PROP_AutoShowInfo
, aAutoShowInfo
);
818 DataPilotFieldSortInfo aSortInfo
;
819 aSortInfo
.IsAscending
= maModel
.mnSortType
== XML_ascending
;
820 if( (maModel
.mnSortType
!= XML_ascending
) && (maModel
.mnSortType
!= XML_descending
) )
822 aSortInfo
.Mode
= DataPilotFieldSortMode::MANUAL
;
826 const PivotCacheField
* pCacheField
= (maModel
.mnSortRefField
== OOX_PT_DATALAYOUTFIELD
) ?
827 mrPivotTable
.getCacheFieldOfDataField( maModel
.mnSortRefItem
) : 0;
830 aSortInfo
.Mode
= DataPilotFieldSortMode::DATA
;
831 aSortInfo
.Field
= pCacheField
->getName();
835 aSortInfo
.Mode
= DataPilotFieldSortMode::NAME
;
838 aPropSet
.setProperty( PROP_SortInfo
, aSortInfo
);
841 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheField( mnFieldIndex
) ) try
843 Reference
< XNameAccess
> xDPItemsNA( xDPField
->getItems(), UNO_QUERY_THROW
);
844 for( ItemModelVector::iterator aIt
= maItems
.begin(), aEnd
= maItems
.end(); aIt
!= aEnd
; ++aIt
)
846 if( aIt
->mnType
== XML_data
)
848 if( const PivotCacheItem
* pSharedItem
= pCacheField
->getCacheItem( aIt
->mnCacheItem
) ) try
850 PropertySet
aItemProp( xDPItemsNA
->getByName( pSharedItem
->getName() ) );
851 aItemProp
.setProperty( PROP_ShowDetail
, aIt
->mbShowDetails
);
852 aItemProp
.setProperty( PROP_IsHidden
, aIt
->mbHidden
);
856 // catch every failed container access to be able to process following items
869 // ============================================================================
871 PTFilterModel::PTFilterModel() :
874 mnMemPropField( -1 ),
875 mnType( XML_TOKEN_INVALID
),
878 mnMeasureField( -1 ),
884 // ----------------------------------------------------------------------------
886 PivotTableFilter::PivotTableFilter( const PivotTable
& rPivotTable
) :
887 WorkbookHelper( rPivotTable
),
888 mrPivotTable( rPivotTable
)
892 void PivotTableFilter::importFilter( const AttributeList
& rAttribs
)
894 maModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
895 maModel
.maDescription
= rAttribs
.getXString( XML_description
, OUString() );
896 maModel
.maStrValue1
= rAttribs
.getXString( XML_stringValue1
, OUString() );
897 maModel
.maStrValue2
= rAttribs
.getXString( XML_stringValue2
, OUString() );
898 maModel
.mnField
= rAttribs
.getInteger( XML_fld
, -1 );
899 maModel
.mnMemPropField
= rAttribs
.getInteger( XML_mpFld
, -1 );
900 maModel
.mnType
= rAttribs
.getToken( XML_type
, XML_TOKEN_INVALID
);
901 maModel
.mnEvalOrder
= rAttribs
.getInteger( XML_evalOrder
, 0 );
902 maModel
.mnId
= rAttribs
.getInteger( XML_id
, -1 );
903 maModel
.mnMeasureField
= rAttribs
.getInteger( XML_iMeasureFld
, -1 );
904 maModel
.mnMeasureHier
= rAttribs
.getInteger( XML_iMeasureHier
, -1 );
907 void PivotTableFilter::importTop10( const AttributeList
& rAttribs
)
909 OSL_ENSURE( rAttribs
.getBool( XML_percent
, false ) == (maModel
.mnType
== XML_percent
),
910 "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
911 maModel
.mfValue
= rAttribs
.getDouble( XML_val
, 0.0 );
912 maModel
.mbTopFilter
= rAttribs
.getBool( XML_top
, true );
915 void PivotTableFilter::importPTFilter( RecordInputStream
& rStrm
)
919 rStrm
>> maModel
.mnField
>> maModel
.mnMemPropField
>> nType
;
920 rStrm
.skip( 4 ); // unused
921 rStrm
>> maModel
.mnId
>> maModel
.mnMeasureField
>> maModel
.mnMeasureHier
>> nFlags
;
922 if( getFlag( nFlags
, OOBIN_PTFILTER_HASNAME
) )
923 rStrm
>> maModel
.maName
;
924 if( getFlag( nFlags
, OOBIN_PTFILTER_HASDESCRIPTION
) )
925 rStrm
>> maModel
.maDescription
;
926 if( getFlag( nFlags
, OOBIN_PTFILTER_HASSTRVALUE1
) )
927 rStrm
>> maModel
.maStrValue1
;
928 if( getFlag( nFlags
, OOBIN_PTFILTER_HASSTRVALUE2
) )
929 rStrm
>> maModel
.maStrValue2
;
931 static sal_Int32 spnTypes
[] =
934 // data field top10 filter (1-3)
935 XML_count
, XML_percent
, XML_sum
,
936 // caption filter (4-17)
937 XML_captionEqual
, XML_captionNotEqual
,
938 XML_captionBeginsWith
, XML_captionNotBeginsWith
, XML_captionEndsWith
, XML_captionNotEndsWith
,
939 XML_captionContains
, XML_captionNotContains
, XML_captionGreaterThan
, XML_captionGreaterThanOrEqual
,
940 XML_captionLessThan
, XML_captionLessThanOrEqual
, XML_captionBetween
, XML_captionNotBetween
,
941 // value filter (18-25)
942 XML_valueEqual
, XML_valueNotEqual
, XML_valueGreaterThan
, XML_valueGreaterThanOrEqual
,
943 XML_valueLessThan
, XML_valueLessThanOrEqual
, XML_valueBetween
, XML_valueNotBetween
,
944 // date filter (26-65)
945 XML_dateEqual
, XML_dateOlderThan
, XML_dateNewerThan
, XML_dateBetween
,
946 XML_tomorrow
, XML_today
, XML_yesterday
, XML_nextWeek
, XML_thisWeek
, XML_lastWeek
,
947 XML_nextMonth
, XML_thisMonth
, XML_lastMonth
, XML_nextQuarter
, XML_thisQuarter
, XML_lastQuarter
,
948 XML_nextYear
, XML_thisYear
, XML_lastYear
, XML_yearToDate
, XML_Q1
, XML_Q2
, XML_Q3
, XML_Q4
,
949 XML_M1
, XML_M2
, XML_M3
, XML_M4
, XML_M5
, XML_M6
, XML_M7
, XML_M8
, XML_M9
, XML_M10
, XML_M11
, XML_M12
,
950 XML_dateNotEqual
, XML_dateOlderThanOrEqual
, XML_dateNewerThanOrEqual
, XML_dateNotBetween
952 maModel
.mnType
= STATIC_ARRAY_SELECT( spnTypes
, nType
, XML_TOKEN_INVALID
);
955 void PivotTableFilter::importTop10Filter( RecordInputStream
& rStrm
)
958 rStrm
>> nFlags
>> maModel
.mfValue
;
960 OSL_ENSURE( getFlag( nFlags
, OOBIN_TOP10FILTER_PERCENT
) == (maModel
.mnType
== XML_percent
),
961 "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
962 maModel
.mbTopFilter
= getFlag( nFlags
, OOBIN_TOP10FILTER_TOP
);
965 void PivotTableFilter::finalizeImport()
967 // only simple top10 filter supported
968 if( maModel
.mnType
== XML_count
)
970 PropertySet
aPropSet( mrPivotTable
.getDataPilotField( maModel
.mnField
) );
973 using namespace ::com::sun::star::sheet
;
974 DataPilotFieldAutoShowInfo aAutoShowInfo
;
975 aAutoShowInfo
.IsEnabled
= sal_True
;
976 aAutoShowInfo
.ShowItemsMode
= maModel
.mbTopFilter
? DataPilotFieldShowItemsMode::FROM_TOP
: DataPilotFieldShowItemsMode::FROM_BOTTOM
;
977 aAutoShowInfo
.ItemCount
= getLimitedValue
< sal_Int32
, double >( maModel
.mfValue
, 0, SAL_MAX_INT32
);
978 if( const PivotCacheField
* pCacheField
= mrPivotTable
.getCacheFieldOfDataField( maModel
.mnMeasureField
) )
979 aAutoShowInfo
.DataField
= pCacheField
->getName();
980 aPropSet
.setProperty( PROP_AutoShowInfo
, aAutoShowInfo
);
985 // ============================================================================
987 PTDefinitionModel::PTDefinitionModel() :
995 mbDataOnRows( false ),
996 mbShowError( false ),
997 mbShowMissing( true ),
999 mbDisableFieldList( false ),
1000 mbShowCalcMembers( true ),
1001 mbVisualTotals( true ),
1002 mbShowDrill( true ),
1003 mbPrintDrill( false ),
1004 mbEnableDrill( true ),
1005 mbPreserveFormatting( true ),
1006 mbPageOverThenDown( false ),
1007 mbSubtotalHiddenItems( false ),
1008 mbRowGrandTotals( true ),
1009 mbColGrandTotals( true ),
1010 mbFieldPrintTitles( false ),
1011 mbItemPrintTitles( false ),
1012 mbMergeItem( false ),
1013 mbShowEmptyRow( false ),
1014 mbShowEmptyCol( false ),
1015 mbShowHeaders( true ),
1016 mbFieldListSortAsc( false ),
1017 mbCustomListSort( true )
1021 // ----------------------------------------------------------------------------
1023 PTLocationModel::PTLocationModel() :
1024 mnFirstHeaderRow( 0 ),
1025 mnFirstDataRow( 0 ),
1026 mnFirstDataCol( 0 ),
1027 mnRowPageCount( 0 ),
1032 // ----------------------------------------------------------------------------
1034 PivotTable::PivotTable( const WorkbookHelper
& rHelper
) :
1035 WorkbookHelper( rHelper
),
1036 maDataField( *this, OOX_PT_DATALAYOUTFIELD
),
1041 void PivotTable::importPivotTableDefinition( const AttributeList
& rAttribs
)
1043 maDefModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
1044 maDefModel
.maDataCaption
= rAttribs
.getXString( XML_dataCaption
, OUString() );
1045 maDefModel
.maGrandTotalCaption
= rAttribs
.getXString( XML_grandTotalCaption
, OUString() );
1046 maDefModel
.maRowHeaderCaption
= rAttribs
.getXString( XML_rowHeaderCaption
, OUString() );
1047 maDefModel
.maColHeaderCaption
= rAttribs
.getXString( XML_colHeaderCaption
, OUString() );
1048 maDefModel
.maErrorCaption
= rAttribs
.getXString( XML_errorCaption
, OUString() );
1049 maDefModel
.maMissingCaption
= rAttribs
.getXString( XML_missingCaption
, OUString() );
1050 maDefModel
.maPageStyle
= rAttribs
.getXString( XML_pageStyle
, OUString() );
1051 maDefModel
.maPivotTableStyle
= rAttribs
.getXString( XML_pivotTableStyle
, OUString() );
1052 maDefModel
.maVacatedStyle
= rAttribs
.getXString( XML_vacatedStyle
, OUString() );
1053 maDefModel
.maTag
= rAttribs
.getXString( XML_tag
, OUString() );
1054 maDefModel
.mnCacheId
= rAttribs
.getInteger( XML_cacheId
, -1 );
1055 maDefModel
.mnDataPosition
= rAttribs
.getInteger( XML_dataPosition
, 0 );
1056 maDefModel
.mnPageWrap
= rAttribs
.getInteger( XML_pageWrap
, 0 );
1057 maDefModel
.mnIndent
= rAttribs
.getInteger( XML_indent
, 1 );
1058 maDefModel
.mnChartFormat
= rAttribs
.getInteger( XML_chartFormat
, 0 );
1059 maDefModel
.mbDataOnRows
= rAttribs
.getBool( XML_dataOnRows
, false );
1060 maDefModel
.mbShowError
= rAttribs
.getBool( XML_showError
, false );
1061 maDefModel
.mbShowMissing
= rAttribs
.getBool( XML_showMissing
, true );
1062 maDefModel
.mbShowItems
= rAttribs
.getBool( XML_showItems
, true );
1063 maDefModel
.mbDisableFieldList
= rAttribs
.getBool( XML_disableFieldList
, false );
1064 maDefModel
.mbShowCalcMembers
= rAttribs
.getBool( XML_showCalcMbrs
, true );
1065 maDefModel
.mbVisualTotals
= rAttribs
.getBool( XML_visualTotals
, true );
1066 maDefModel
.mbShowDrill
= rAttribs
.getBool( XML_showDrill
, true );
1067 maDefModel
.mbPrintDrill
= rAttribs
.getBool( XML_printDrill
, false );
1068 maDefModel
.mbEnableDrill
= rAttribs
.getBool( XML_enableDrill
, true );
1069 maDefModel
.mbPreserveFormatting
= rAttribs
.getBool( XML_preserveFormatting
, true );
1070 maDefModel
.mbPageOverThenDown
= rAttribs
.getBool( XML_pageOverThenDown
, false );
1071 maDefModel
.mbSubtotalHiddenItems
= rAttribs
.getBool( XML_subtotalHiddenItems
, false );
1072 maDefModel
.mbRowGrandTotals
= rAttribs
.getBool( XML_rowGrandTotals
, true );
1073 maDefModel
.mbColGrandTotals
= rAttribs
.getBool( XML_colGrandTotals
, true );
1074 maDefModel
.mbFieldPrintTitles
= rAttribs
.getBool( XML_fieldPrintTitles
, false );
1075 maDefModel
.mbItemPrintTitles
= rAttribs
.getBool( XML_itemPrintTitles
, false );
1076 maDefModel
.mbMergeItem
= rAttribs
.getBool( XML_mergeItem
, false );
1077 maDefModel
.mbShowEmptyRow
= rAttribs
.getBool( XML_showEmptyRow
, false );
1078 maDefModel
.mbShowEmptyCol
= rAttribs
.getBool( XML_showEmptyCol
, false );
1079 maDefModel
.mbShowHeaders
= rAttribs
.getBool( XML_showHeaders
, true );
1080 maDefModel
.mbFieldListSortAsc
= rAttribs
.getBool( XML_fieldListSortAscending
, false );
1081 maDefModel
.mbCustomListSort
= rAttribs
.getBool( XML_customListSort
, true );
1084 void PivotTable::importLocation( const AttributeList
& rAttribs
, sal_Int16 nSheet
)
1086 getAddressConverter().convertToCellRangeUnchecked( maLocationModel
.maRange
, rAttribs
.getString( XML_ref
, OUString() ), nSheet
);
1087 maLocationModel
.mnFirstHeaderRow
= rAttribs
.getInteger( XML_firstHeaderRow
, 0 );
1088 maLocationModel
.mnFirstDataRow
= rAttribs
.getInteger( XML_firstDataRow
, 0 );
1089 maLocationModel
.mnFirstDataCol
= rAttribs
.getInteger( XML_firstDataCol
, 0 );
1090 maLocationModel
.mnRowPageCount
= rAttribs
.getInteger( XML_rowPageCount
, 0 );
1091 maLocationModel
.mnColPageCount
= rAttribs
.getInteger( XML_colPageCount
, 0 );
1094 void PivotTable::importRowField( const AttributeList
& rAttribs
)
1096 importField( maRowFields
, rAttribs
);
1099 void PivotTable::importColField( const AttributeList
& rAttribs
)
1101 importField( maColFields
, rAttribs
);
1104 void PivotTable::importPageField( const AttributeList
& rAttribs
)
1106 PTPageFieldModel aModel
;
1107 aModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
1108 aModel
.mnField
= rAttribs
.getInteger( XML_fld
, -1 );
1109 // specification is wrong, XML_item is not the cache item, but the field item
1110 aModel
.mnItem
= rAttribs
.getInteger( XML_item
, OOBIN_PTPAGEFIELD_MULTIITEMS
);
1111 maPageFields
.push_back( aModel
);
1114 void PivotTable::importDataField( const AttributeList
& rAttribs
)
1116 PTDataFieldModel aModel
;
1117 aModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
1118 aModel
.mnField
= rAttribs
.getInteger( XML_fld
, -1 );
1119 aModel
.mnSubtotal
= rAttribs
.getToken( XML_subtotal
, XML_sum
);
1120 aModel
.mnShowDataAs
= rAttribs
.getToken( XML_showDataAs
, XML_normal
);
1121 aModel
.mnBaseField
= rAttribs
.getInteger( XML_baseField
, -1 );
1122 aModel
.mnBaseItem
= rAttribs
.getInteger( XML_baseItem
, -1 );
1123 aModel
.mnNumFmtId
= rAttribs
.getInteger( XML_numFmtId
, 0 );
1124 maDataFields
.push_back( aModel
);
1127 void PivotTable::importPTDefinition( RecordInputStream
& rStrm
)
1129 sal_uInt32 nFlags1
, nFlags2
, nFlags3
;
1130 sal_uInt8 nDataAxis
;
1131 rStrm
>> nFlags1
>> nFlags2
>> nFlags3
>> nDataAxis
;
1132 maDefModel
.mnPageWrap
= rStrm
.readuInt8();
1133 rStrm
.skip( 2 ); // refresh versions
1134 rStrm
>> maDefModel
.mnDataPosition
;
1135 rStrm
.skip( 4 ); // 2 bytes autoformat id, 2 bytes unused
1136 rStrm
>> maDefModel
.mnChartFormat
>> maDefModel
.mnCacheId
>> maDefModel
.maName
;
1137 if( getFlag( nFlags2
, OOBIN_PTDEF_HASDATACAPTION
) )
1138 rStrm
>> maDefModel
.maDataCaption
;
1139 if( getFlag( nFlags2
, OOBIN_PTDEF_HASGRANDTOTALCAPTION
) )
1140 rStrm
>> maDefModel
.maGrandTotalCaption
;
1141 if( !getFlag( nFlags3
, OOBIN_PTDEF_NOERRORCAPTION
) ) // missing flag indicates existing string
1142 rStrm
>> maDefModel
.maErrorCaption
;
1143 if( !getFlag( nFlags3
, OOBIN_PTDEF_NOMISSINGCAPTION
) ) // missing flag indicates existing string
1144 rStrm
>> maDefModel
.maMissingCaption
;
1145 if( getFlag( nFlags2
, OOBIN_PTDEF_HASPAGESTYLE
) )
1146 rStrm
>> maDefModel
.maPageStyle
;
1147 if( getFlag( nFlags2
, OOBIN_PTDEF_HASPIVOTTABLESTYLE
) )
1148 rStrm
>> maDefModel
.maPivotTableStyle
;
1149 if( getFlag( nFlags2
, OOBIN_PTDEF_HASVACATEDSTYLE
) )
1150 rStrm
>> maDefModel
.maVacatedStyle
;
1151 if( getFlag( nFlags2
, OOBIN_PTDEF_HASTAG
) )
1152 rStrm
>> maDefModel
.maTag
;
1153 if( getFlag( nFlags3
, OOBIN_PTDEF_HASCOLHEADERCAPTION
) ) // TODO: right order (col/row)? spec is unclear
1154 rStrm
>> maDefModel
.maColHeaderCaption
;
1155 if( getFlag( nFlags3
, OOBIN_PTDEF_HASROWHEADERCAPTION
) )
1156 rStrm
>> maDefModel
.maRowHeaderCaption
;
1158 OSL_ENSURE( (nDataAxis
== OOBIN_PTDEF_ROWAXIS
) || (nDataAxis
== OOBIN_PTDEF_COLAXIS
),
1159 "PivotTable::importPTDefinition - unexpected axis position for data field" );
1161 maDefModel
.mnIndent
= extractValue
< sal_uInt8
>( nFlags1
, 24, 7 );
1162 maDefModel
.mbDataOnRows
= nDataAxis
== OOBIN_PTDEF_ROWAXIS
;
1163 maDefModel
.mbShowError
= getFlag( nFlags2
, OOBIN_PTDEF_SHOWERROR
);
1164 maDefModel
.mbShowMissing
= getFlag( nFlags2
, OOBIN_PTDEF_SHOWMISSING
);
1165 maDefModel
.mbShowItems
= getFlag( nFlags1
, OOBIN_PTDEF_SHOWITEMS
);
1166 maDefModel
.mbDisableFieldList
= getFlag( nFlags1
, OOBIN_PTDEF_DISABLEFIELDLIST
);
1167 maDefModel
.mbShowCalcMembers
= !getFlag( nFlags1
, OOBIN_PTDEF_HIDECALCMEMBERS
);
1168 maDefModel
.mbVisualTotals
= !getFlag( nFlags1
, OOBIN_PTDEF_WITHHIDDENTOTALS
);
1169 maDefModel
.mbShowDrill
= !getFlag( nFlags1
, OOBIN_PTDEF_HIDEDRILL
);
1170 maDefModel
.mbPrintDrill
= getFlag( nFlags1
, OOBIN_PTDEF_PRINTDRILL
);
1171 maDefModel
.mbEnableDrill
= getFlag( nFlags2
, OOBIN_PTDEF_ENABLEDRILL
);
1172 maDefModel
.mbPreserveFormatting
= getFlag( nFlags2
, OOBIN_PTDEF_PRESERVEFORMATTING
);
1173 maDefModel
.mbPageOverThenDown
= getFlag( nFlags2
, OOBIN_PTDEF_PAGEOVERTHENDOWN
);
1174 maDefModel
.mbSubtotalHiddenItems
= getFlag( nFlags2
, OOBIN_PTDEF_SUBTOTALHIDDENITEMS
);
1175 maDefModel
.mbRowGrandTotals
= getFlag( nFlags2
, OOBIN_PTDEF_ROWGRANDTOTALS
);
1176 maDefModel
.mbColGrandTotals
= getFlag( nFlags2
, OOBIN_PTDEF_COLGRANDTOTALS
);
1177 maDefModel
.mbFieldPrintTitles
= getFlag( nFlags2
, OOBIN_PTDEF_FIELDPRINTTITLES
);
1178 maDefModel
.mbItemPrintTitles
= getFlag( nFlags2
, OOBIN_PTDEF_ITEMPRINTTITLES
);
1179 maDefModel
.mbMergeItem
= getFlag( nFlags2
, OOBIN_PTDEF_MERGEITEM
);
1180 maDefModel
.mbShowEmptyRow
= getFlag( nFlags2
, OOBIN_PTDEF_SHOWEMPTYROW
);
1181 maDefModel
.mbShowEmptyCol
= getFlag( nFlags2
, OOBIN_PTDEF_SHOWEMPTYCOL
);
1182 maDefModel
.mbShowHeaders
= !getFlag( nFlags1
, OOBIN_PTDEF_HIDEHEADERS
);
1183 maDefModel
.mbFieldListSortAsc
= getFlag( nFlags3
, OOBIN_PTDEF_FIELDLISTSORTASC
);
1184 maDefModel
.mbCustomListSort
= !getFlag( nFlags3
, OOBIN_PTDEF_NOCUSTOMLISTSORT
);
1187 void PivotTable::importPTLocation( RecordInputStream
& rStrm
, sal_Int16 nSheet
)
1190 rStrm
>> aBinRange
>> maLocationModel
.mnFirstHeaderRow
1191 >> maLocationModel
.mnFirstDataRow
>> maLocationModel
.mnFirstDataCol
1192 >> maLocationModel
.mnRowPageCount
>> maLocationModel
.mnColPageCount
;
1193 getAddressConverter().convertToCellRangeUnchecked( maLocationModel
.maRange
, aBinRange
, nSheet
);
1196 void PivotTable::importPTRowFields( RecordInputStream
& rStrm
)
1198 importFields( maRowFields
, rStrm
);
1201 void PivotTable::importPTColFields( RecordInputStream
& rStrm
)
1203 importFields( maColFields
, rStrm
);
1206 void PivotTable::importPTPageField( RecordInputStream
& rStrm
)
1208 PTPageFieldModel aModel
;
1210 rStrm
>> aModel
.mnField
>> aModel
.mnItem
;
1211 rStrm
.skip( 4 ); // hierarchy
1213 if( getFlag( nFlags
, OOBIN_PTPAGEFIELD_HASNAME
) )
1214 rStrm
>> aModel
.maName
;
1215 maPageFields
.push_back( aModel
);
1218 void PivotTable::importPTDataField( RecordInputStream
& rStrm
)
1220 PTDataFieldModel aModel
;
1221 sal_Int32 nSubtotal
, nShowDataAs
;
1223 rStrm
>> aModel
.mnField
>> nSubtotal
>> nShowDataAs
>> aModel
.mnBaseField
>> aModel
.mnBaseItem
>> aModel
.mnNumFmtId
>> nHasName
;
1225 rStrm
>> aModel
.maName
;
1226 aModel
.setBinSubtotal( nSubtotal
);
1227 aModel
.setBinShowDataAs( nShowDataAs
);
1228 maDataFields
.push_back( aModel
);
1231 void PivotTable::importPTDefinition( BiffInputStream
& rStrm
, sal_Int16 nSheet
)
1234 sal_uInt16 nFlags
, nTabNameLen
, nDataNameLen
;
1236 maLocationModel
.mnFirstHeaderRow
= rStrm
.readuInt16();
1237 maLocationModel
.mnFirstDataRow
= rStrm
.readuInt16();
1238 maLocationModel
.mnFirstDataCol
= rStrm
.readuInt16();
1239 maDefModel
.mnCacheId
= rStrm
.readuInt16();
1240 rStrm
.skip( 2 ); // unused
1241 maDefModel
.mbDataOnRows
= rStrm
.readuInt16() == BIFF_PTDEF_ROWAXIS
;
1242 maDefModel
.mnDataPosition
= rStrm
.readInt16();
1243 rStrm
.skip( 2 ); // number of fields
1244 rStrm
>> maDefModel
.mnRowFields
>> maDefModel
.mnColFields
;
1245 rStrm
.skip( 8 ); // number of page fields, data fields, data rows, data columns
1247 maDefModel
.mnChartFormat
= rStrm
.readuInt16();
1248 rStrm
>> nTabNameLen
>> nDataNameLen
;
1249 maDefModel
.maName
= lclReadPivotString( *this, rStrm
, nTabNameLen
);
1250 maDefModel
.maDataCaption
= lclReadPivotString( *this, rStrm
, nDataNameLen
);
1252 maDefModel
.mbRowGrandTotals
= getFlag( nFlags
, BIFF_PTDEF_ROWGRANDTOTALS
);
1253 maDefModel
.mbColGrandTotals
= getFlag( nFlags
, BIFF_PTDEF_COLGRANDTOTALS
);
1255 getAddressConverter().convertToCellRangeUnchecked( maLocationModel
.maRange
, aBinRange
, nSheet
);
1258 void PivotTable::importPTDefinition2( BiffInputStream
& rStrm
)
1260 if( getBiff() == BIFF8
)
1262 sal_uInt16 nErrCaptLen
, nMissCaptLen
, nTagLen
, nPageStyleLen
, nTabStyleLen
, nVacStyleLen
;
1264 rStrm
.skip( 2 ); // number of formatting records
1265 rStrm
>> nErrCaptLen
>> nMissCaptLen
>> nTagLen
;
1266 rStrm
.skip( 6 ); // number of selection records, page rows, page columns
1267 rStrm
>> nFlags
>> nPageStyleLen
>> nTabStyleLen
>> nVacStyleLen
;
1268 maDefModel
.maErrorCaption
= lclReadPivotString( *this, rStrm
, nErrCaptLen
);
1269 maDefModel
.maMissingCaption
= lclReadPivotString( *this, rStrm
, nMissCaptLen
);
1270 maDefModel
.maTag
= lclReadPivotString( *this, rStrm
, nTagLen
);
1271 maDefModel
.maPageStyle
= lclReadPivotString( *this, rStrm
, nPageStyleLen
);
1272 maDefModel
.maPivotTableStyle
= lclReadPivotString( *this, rStrm
, nTabStyleLen
);
1273 maDefModel
.maVacatedStyle
= lclReadPivotString( *this, rStrm
, nVacStyleLen
);
1275 maDefModel
.mbShowError
= getFlag( nFlags
, BIFF_PTDEF2_SHOWERROR
);
1276 maDefModel
.mbShowMissing
= getFlag( nFlags
, BIFF_PTDEF2_SHOWMISSING
);
1277 maDefModel
.mbEnableDrill
= getFlag( nFlags
, BIFF_PTDE2F_ENABLEDRILL
);
1278 maDefModel
.mbPreserveFormatting
= getFlag( nFlags
, BIFF_PTDEF2_PRESERVEFORMATTING
);
1279 maDefModel
.mbPageOverThenDown
= getFlag( nFlags
, BIFF_PTDEF2_PAGEOVERTHENDOWN
);
1280 maDefModel
.mbSubtotalHiddenItems
= getFlag( nFlags
, BIFF_PTDEF2_SUBTOTALHIDDENITEMS
);
1281 maDefModel
.mbMergeItem
= getFlag( nFlags
, BIFF_PTDEF2_MERGEITEM
);
1285 void PivotTable::importPTRowColFields( BiffInputStream
& rStrm
)
1287 // first PTROWCOLFIELDS record contains row fields unless there are no row fields
1288 if( (maDefModel
.mnRowFields
> 0) && maRowFields
.empty() )
1289 importFields( maRowFields
, rStrm
, maDefModel
.mnRowFields
);
1290 else if( (maDefModel
.mnColFields
> 0) && maColFields
.empty() )
1291 importFields( maColFields
, rStrm
, maDefModel
.mnColFields
);
1294 void PivotTable::importPTPageFields( BiffInputStream
& rStrm
)
1296 while( rStrm
.getRemaining() >= 6 )
1298 PTPageFieldModel aModel
;
1299 sal_Int16 nField
, nItem
;
1300 rStrm
>> nField
>> nItem
;
1301 rStrm
.skip( 2 ); // dropdown object ID
1302 aModel
.mnField
= nField
;
1303 aModel
.mnItem
= (nItem
== BIFF_PTPAGEFIELDS_ALLITEMS
) ? OOBIN_PTPAGEFIELD_MULTIITEMS
: nItem
;
1304 maPageFields
.push_back( aModel
);
1308 void PivotTable::importPTDataField( BiffInputStream
& rStrm
)
1310 PTDataFieldModel aModel
;
1311 sal_Int16 nField
, nBaseField
, nBaseItem
;
1312 sal_uInt16 nSubtotal
, nShowDataAs
, nNumFmt
, nNameLen
;
1313 rStrm
>> nField
>> nSubtotal
>> nShowDataAs
>> nBaseField
>> nBaseItem
>> nNumFmt
>> nNameLen
;
1314 aModel
.maName
= lclReadPivotString( *this, rStrm
, nNameLen
);
1316 aModel
.mnField
= nField
;
1317 aModel
.setBinSubtotal( nSubtotal
);
1318 aModel
.setBinShowDataAs( nShowDataAs
);
1319 aModel
.mnBaseField
= nBaseField
;
1322 case BIFF_PTDATAFIELD_PREVIOUS
: aModel
.mnBaseItem
= OOX_PT_PREVIOUS_ITEM
; break;
1323 case BIFF_PTDATAFIELD_NEXT
: aModel
.mnBaseItem
= OOX_PT_NEXT_ITEM
; break;
1324 default: aModel
.mnBaseItem
= nBaseItem
;
1326 aModel
.mnNumFmtId
= nNumFmt
;
1328 maDataFields
.push_back( aModel
);
1331 PivotTableField
& PivotTable::createTableField()
1333 sal_Int32 nFieldIndex
= static_cast< sal_Int32
>( maFields
.size() );
1334 PivotTableFieldVector::value_type
xTableField( new PivotTableField( *this, nFieldIndex
) );
1335 maFields
.push_back( xTableField
);
1336 return *xTableField
;
1339 PivotTableFilter
& PivotTable::createTableFilter()
1341 PivotTableFilterVector::value_type
xTableFilter( new PivotTableFilter( *this ) );
1342 maFilters
.push_back( xTableFilter
);
1343 return *xTableFilter
;
1346 void PivotTable::finalizeImport()
1348 if( getAddressConverter().validateCellRange( maLocationModel
.maRange
, true, true ) )
1350 mpPivotCache
= getPivotCaches().importPivotCacheFragment( maDefModel
.mnCacheId
);
1351 if( mpPivotCache
&& mpPivotCache
->isValidDataSource() && (maDefModel
.maName
.getLength() > 0) )
1353 // clear destination area of the original pivot table
1356 Reference
< XSheetOperation
> xSheetOp( getCellRangeFromDoc( maLocationModel
.maRange
), UNO_QUERY_THROW
);
1357 using namespace ::com::sun::star::sheet::CellFlags
;
1358 xSheetOp
->clearContents( VALUE
| DATETIME
| STRING
| FORMULA
| HARDATTR
| STYLES
| EDITATTR
| FORMATTED
);
1366 // create a new data pilot descriptor based on the source data
1367 Reference
< XDataPilotTablesSupplier
> xDPTablesSupp( getSheetFromDoc( maLocationModel
.maRange
.Sheet
), UNO_QUERY_THROW
);
1368 Reference
< XDataPilotTables
> xDPTables( xDPTablesSupp
->getDataPilotTables(), UNO_SET_THROW
);
1369 mxDPDescriptor
.set( xDPTables
->createDataPilotDescriptor(), UNO_SET_THROW
);
1370 mxDPDescriptor
->setSourceRange( mpPivotCache
->getSourceRange() );
1371 mxDPDescriptor
->setTag( maDefModel
.maTag
);
1373 // global data pilot properties
1374 PropertySet
aDescProp( mxDPDescriptor
);
1375 aDescProp
.setProperty( PROP_ColumnGrand
, maDefModel
.mbColGrandTotals
);
1376 aDescProp
.setProperty( PROP_RowGrand
, maDefModel
.mbRowGrandTotals
);
1377 aDescProp
.setProperty( PROP_ShowFilterButton
, false );
1378 aDescProp
.setProperty( PROP_DrillDownOnDoubleClick
, maDefModel
.mbEnableDrill
);
1380 // finalize all fields, this finds field names and creates grouping fields
1381 maFields
.forEachMem( &PivotTableField::finalizeImport
, ::boost::cref( mxDPDescriptor
) );
1384 for( IndexVector::iterator aIt
= maRowFields
.begin(), aEnd
= maRowFields
.end(); aIt
!= aEnd
; ++aIt
)
1385 if( PivotTableField
* pField
= getTableField( *aIt
) )
1386 pField
->convertRowField();
1388 // all column fields
1389 for( IndexVector::iterator aIt
= maColFields
.begin(), aEnd
= maColFields
.end(); aIt
!= aEnd
; ++aIt
)
1390 if( PivotTableField
* pField
= getTableField( *aIt
) )
1391 pField
->convertColField();
1394 for( PageFieldVector::iterator aIt
= maPageFields
.begin(), aEnd
= maPageFields
.end(); aIt
!= aEnd
; ++aIt
)
1395 if( PivotTableField
* pField
= getTableField( aIt
->mnField
) )
1396 pField
->convertPageField( *aIt
);
1398 // all hidden fields
1399 ::std::set
< sal_Int32
> aVisFields
;
1400 aVisFields
.insert( maRowFields
.begin(), maRowFields
.end() );
1401 aVisFields
.insert( maColFields
.begin(), maColFields
.end() );
1402 for( PageFieldVector::iterator aIt
= maPageFields
.begin(), aEnd
= maPageFields
.end(); aIt
!= aEnd
; ++aIt
)
1403 aVisFields
.insert( aIt
->mnField
);
1404 for( PivotTableFieldVector::iterator aBeg
= maFields
.begin(), aIt
= aBeg
, aEnd
= maFields
.end(); aIt
!= aEnd
; ++aIt
)
1405 if( aVisFields
.count( static_cast< sal_Int32
>( aIt
- aBeg
) ) == 0 )
1406 (*aIt
)->convertHiddenField();
1409 for( DataFieldVector::iterator aIt
= maDataFields
.begin(), aEnd
= maDataFields
.end(); aIt
!= aEnd
; ++aIt
)
1410 if( PivotTableField
* pField
= getTableField( aIt
->mnField
) )
1411 pField
->convertDataField( *aIt
);
1414 maFilters
.forEachMem( &PivotTableFilter::finalizeImport
);
1416 // calculate base position of table
1417 CellAddress
aPos( maLocationModel
.maRange
.Sheet
, maLocationModel
.maRange
.StartColumn
, maLocationModel
.maRange
.StartRow
);
1418 /* If page fields exist, include them into the destination
1419 area (they are excluded in Excel). Add an extra blank row. */
1420 if( !maPageFields
.empty() )
1421 aPos
.Row
= ::std::max
< sal_Int32
>( static_cast< sal_Int32
>( aPos
.Row
- maPageFields
.size() - 1 ), 0 );
1423 // insert the DataPilot table into the sheet
1424 xDPTables
->insertNewByName( maDefModel
.maName
, aPos
, mxDPDescriptor
);
1428 OSL_ENSURE( false, "PivotTable::finalizeImport - exception while creating the pivot table" );
1434 void PivotTable::finalizeDateGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
, sal_Int32 nBaseFieldIdx
)
1436 // process all fields, there is no chaining information in the cache fields
1437 maFields
.forEachMem( &PivotTableField::finalizeDateGroupingImport
, ::boost::cref( rxBaseDPField
), nBaseFieldIdx
);
1440 void PivotTable::finalizeParentGroupingImport( const Reference
< XDataPilotField
>& rxBaseDPField
,
1441 const PivotCacheField
& rBaseCacheField
, PivotCacheGroupItemVector
& orItemNames
)
1443 // try to create parent group fields that group the items of the passed base field
1444 if( PivotTableField
* pParentTableField
= maFields
.get( rBaseCacheField
.getParentGroupField() ).get() )
1445 pParentTableField
->finalizeParentGroupingImport( rxBaseDPField
, orItemNames
);
1448 Reference
< XDataPilotField
> PivotTable::getDataPilotField( const OUString
& rFieldName
) const
1450 Reference
< XDataPilotField
> xDPField
;
1451 if( (rFieldName
.getLength() > 0) && mxDPDescriptor
.is() ) try
1453 Reference
< XNameAccess
> xDPFieldsNA( mxDPDescriptor
->getDataPilotFields(), UNO_QUERY_THROW
);
1454 xDPField
.set( xDPFieldsNA
->getByName( rFieldName
), UNO_QUERY
);
1462 Reference
< XDataPilotField
> PivotTable::getDataPilotField( sal_Int32 nFieldIdx
) const
1464 Reference
< XDataPilotField
> xDPField
;
1465 if( const PivotTableField
* pTableField
= maFields
.get( nFieldIdx
).get() )
1466 xDPField
= getDataPilotField( pTableField
->getDPFieldName() );
1470 Reference
< XDataPilotField
> PivotTable::getDataLayoutField() const
1472 Reference
< XDataPilotField
> xDPField
;
1475 Reference
< XDataPilotDataLayoutFieldSupplier
> xDPDataFieldSupp( mxDPDescriptor
, UNO_QUERY_THROW
);
1476 xDPField
= xDPDataFieldSupp
->getDataLayoutField();
1484 const PivotCacheField
* PivotTable::getCacheField( sal_Int32 nFieldIdx
) const
1486 return mpPivotCache
? mpPivotCache
->getCacheField( nFieldIdx
) : 0;
1489 const PivotCacheField
* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx
) const
1491 const PTDataFieldModel
* pDataField
= ContainerHelper::getVectorElement( maDataFields
, nDataItemIdx
);
1492 return pDataField
? getCacheField( pDataField
->mnField
) : 0;
1495 sal_Int32
PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx
) const
1497 return mpPivotCache
? mpPivotCache
->getCacheDatabaseIndex( nFieldIdx
) : -1;
1500 // private --------------------------------------------------------------------
1502 PivotTableField
* PivotTable::getTableField( sal_Int32 nFieldIdx
)
1504 return (nFieldIdx
== OOX_PT_DATALAYOUTFIELD
) ? &maDataField
: maFields
.get( nFieldIdx
).get();
1507 void PivotTable::importField( IndexVector
& orFields
, const AttributeList
& rAttribs
)
1509 orFields
.push_back( rAttribs
.getInteger( XML_x
, -1 ) );
1512 void PivotTable::importFields( IndexVector
& orFields
, RecordInputStream
& rStrm
)
1514 OSL_ENSURE( orFields
.empty(), "PivotTable::importFields - multiple record instances" );
1516 sal_Int32 nCount
= rStrm
.readInt32();
1517 OSL_ENSURE( 4 * nCount
== rStrm
.getRemaining(), "PivotTable::importFields - invalid field count" );
1518 nCount
= static_cast< sal_Int32
>( rStrm
.getRemaining() / 4 );
1519 for( sal_Int32 nIdx
= 0; nIdx
< nCount
; ++nIdx
)
1520 orFields
.push_back( rStrm
.readInt32() );
1523 void PivotTable::importFields( IndexVector
& orFields
, BiffInputStream
& rStrm
, sal_Int32 nCount
)
1525 OSL_ENSURE( orFields
.empty(), "PivotTable::importFields - multiple record instances" );
1527 OSL_ENSURE( 2 * nCount
== rStrm
.getRemaining(), "PivotTable::importFields - invalid field count" );
1528 nCount
= static_cast< sal_Int32
>( rStrm
.getRemaining() / 2 );
1529 for( sal_Int32 nIdx
= 0; nIdx
< nCount
; ++nIdx
)
1530 orFields
.push_back( rStrm
.readInt16() );
1533 // ============================================================================
1535 PivotTableBuffer::PivotTableBuffer( const WorkbookHelper
& rHelper
) :
1536 WorkbookHelper( rHelper
)
1540 PivotTable
& PivotTableBuffer::createPivotTable()
1542 PivotTableVector::value_type
xTable( new PivotTable( *this ) );
1543 maTables
.push_back( xTable
);
1547 void PivotTableBuffer::finalizeImport()
1549 maTables
.forEachMem( &PivotTable::finalizeImport
);
1552 // ============================================================================