xref: /trunk/main/oox/source/xls/pivottablebuffer.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/xls/pivottablebuffer.hxx"
29 
30 #include <set>
31 #include <com/sun/star/container/XIndexAccess.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/sheet/CellFlags.hpp>
34 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
35 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
36 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
37 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
38 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
39 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
40 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
41 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
42 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
43 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
44 #include <com/sun/star/sheet/GeneralFunction.hpp>
45 #include <com/sun/star/sheet/XDataPilotDataLayoutFieldSupplier.hpp>
46 #include <com/sun/star/sheet/XDataPilotField.hpp>
47 #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
48 #include <com/sun/star/sheet/XSheetOperation.hpp>
49 #include "oox/helper/attributelist.hxx"
50 #include "oox/helper/containerhelper.hxx"
51 #include "oox/helper/propertyset.hxx"
52 #include "oox/xls/addressconverter.hxx"
53 #include "oox/xls/biffinputstream.hxx"
54 
55 namespace oox {
56 namespace xls {
57 
58 // ============================================================================
59 
60 using namespace ::com::sun::star::container;
61 using namespace ::com::sun::star::sheet;
62 using namespace ::com::sun::star::table;
63 using namespace ::com::sun::star::uno;
64 
65 using ::rtl::OUString;
66 
67 // ============================================================================
68 
69 namespace {
70 
71 const sal_Int32 OOX_PT_DATALAYOUTFIELD              = -2;           /// Placeholder index of data layout field.
72 
73 const sal_Int32 OOX_PT_PREVIOUS_ITEM                = 0x001000FC;   /// Calculation of data item result is based on previous item.
74 const sal_Int32 OOX_PT_NEXT_ITEM                    = 0x001000FD;   /// Calculation of data item result is based on next item.
75 
76 // ----------------------------------------------------------------------------
77 
78 const sal_uInt32 BIFF12_PTFIELD_DATAFIELD           = 0x00000008;
79 const sal_uInt32 BIFF12_PTFIELD_DEFAULT             = 0x00000100;
80 const sal_uInt32 BIFF12_PTFIELD_SUM                 = 0x00000200;
81 const sal_uInt32 BIFF12_PTFIELD_COUNTA              = 0x00000400;
82 const sal_uInt32 BIFF12_PTFIELD_AVERAGE             = 0x00000800;
83 const sal_uInt32 BIFF12_PTFIELD_MAX                 = 0x00001000;
84 const sal_uInt32 BIFF12_PTFIELD_MIN                 = 0x00002000;
85 const sal_uInt32 BIFF12_PTFIELD_PRODUCT             = 0x00004000;
86 const sal_uInt32 BIFF12_PTFIELD_COUNT               = 0x00008000;
87 const sal_uInt32 BIFF12_PTFIELD_STDDEV              = 0x00010000;
88 const sal_uInt32 BIFF12_PTFIELD_STDDEVP             = 0x00020000;
89 const sal_uInt32 BIFF12_PTFIELD_VAR                 = 0x00040000;
90 const sal_uInt32 BIFF12_PTFIELD_VARP                = 0x00080000;
91 
92 const sal_uInt32 BIFF12_PTFIELD_SHOWALL             = 0x00000020;
93 const sal_uInt32 BIFF12_PTFIELD_OUTLINE             = 0x00000040;
94 const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW      = 0x00000080;
95 const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP         = 0x00000100;
96 const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK     = 0x00000800;
97 const sal_uInt32 BIFF12_PTFIELD_AUTOSORT            = 0x00001000;
98 const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING       = 0x00002000;
99 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW            = 0x00004000;
100 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP         = 0x00008000;
101 const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS      = 0x00080000;
102 
103 const sal_uInt16 BIFF12_PTFITEM_HIDDEN              = 0x0001;
104 const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS         = 0x0002;
105 
106 const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME          = 0x01;
107 const sal_uInt8 BIFF12_PTPAGEFIELD_HASOLAPCAPTION   = 0x02;
108 const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS       = 0x001000FE;
109 
110 const sal_uInt16 BIFF12_PTFILTER_HASNAME            = 0x0001;
111 const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION     = 0x0002;
112 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1       = 0x0004;
113 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2       = 0x0008;
114 
115 const sal_uInt8 BIFF12_TOP10FILTER_TOP              = 0x01;
116 const sal_uInt8 BIFF12_TOP10FILTER_PERCENT          = 0x02;
117 
118 const sal_uInt32 BIFF12_PTDEF_SHOWITEMS             = 0x00000100;
119 const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST      = 0x00000400;
120 const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS       = 0x00001000;
121 const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS      = 0x00002000;
122 const sal_uInt32 BIFF12_PTDEF_HIDEDRILL             = 0x00100000;
123 const sal_uInt32 BIFF12_PTDEF_PRINTDRILL            = 0x00200000;
124 const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS           = 0x80000000;
125 
126 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW          = 0x00000004;
127 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL          = 0x00000008;
128 const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL           = 0x00000020;
129 const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING    = 0x00000080;
130 const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT         = 0x00000100;
131 const sal_uInt32 BIFF12_PTDEF_SHOWERROR             = 0x00000200;
132 const sal_uInt32 BIFF12_PTDEF_SHOWMISSING           = 0x00000400;
133 const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN      = 0x00000800;
134 const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS   = 0x00001000;
135 const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS        = 0x00002000;
136 const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS        = 0x00004000;
137 const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES      = 0x00008000;
138 const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES       = 0x00020000;
139 const sal_uInt32 BIFF12_PTDEF_MERGEITEM             = 0x00040000;
140 const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION        = 0x00080000;
141 const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION  = 0x00100000;
142 const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE          = 0x00200000;
143 const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE    = 0x00400000;
144 const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE       = 0x00800000;
145 const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT           = 0x01000000;
146 const sal_uInt32 BIFF12_PTDEF_APPLYFONT             = 0x02000000;
147 const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT        = 0x04000000;
148 const sal_uInt32 BIFF12_PTDEF_APPLYBORDER           = 0x08000000;
149 const sal_uInt32 BIFF12_PTDEF_APPLYFILL             = 0x10000000;
150 const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION       = 0x20000000;
151 const sal_uInt32 BIFF12_PTDEF_HASTAG                = 0x40000000;
152 
153 const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION        = 0x00000040;
154 const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION      = 0x00000080;
155 const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION   = 0x00000400;
156 const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION   = 0x00000800;
157 const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC      = 0x00001000;
158 const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT      = 0x00004000;
159 
160 const sal_uInt8 BIFF12_PTDEF_ROWAXIS                = 1;
161 const sal_uInt8 BIFF12_PTDEF_COLAXIS                = 2;
162 
163 // ----------------------------------------------------------------------------
164 
165 const sal_uInt16 BIFF_PT_NOSTRING                   = 0xFFFF;
166 
167 const sal_uInt16 BIFF_PTFIELD_DATAFIELD             = 0x0008;
168 const sal_uInt16 BIFF_PTFIELD_DEFAULT               = 0x0001;
169 const sal_uInt16 BIFF_PTFIELD_SUM                   = 0x0002;
170 const sal_uInt16 BIFF_PTFIELD_COUNTA                = 0x0004;
171 const sal_uInt16 BIFF_PTFIELD_AVERAGE               = 0x0008;
172 const sal_uInt16 BIFF_PTFIELD_MAX                   = 0x0010;
173 const sal_uInt16 BIFF_PTFIELD_MIN                   = 0x0020;
174 const sal_uInt16 BIFF_PTFIELD_PRODUCT               = 0x0040;
175 const sal_uInt16 BIFF_PTFIELD_COUNT                 = 0x0080;
176 const sal_uInt16 BIFF_PTFIELD_STDDEV                = 0x0100;
177 const sal_uInt16 BIFF_PTFIELD_STDDEVP               = 0x0200;
178 const sal_uInt16 BIFF_PTFIELD_VAR                   = 0x0400;
179 const sal_uInt16 BIFF_PTFIELD_VARP                  = 0x0800;
180 
181 const sal_uInt32 BIFF_PTFIELD2_SHOWALL              = 0x00000001;
182 const sal_uInt32 BIFF_PTFIELD2_AUTOSORT             = 0x00000200;
183 const sal_uInt32 BIFF_PTFIELD2_SORTASCENDING        = 0x00000400;
184 const sal_uInt32 BIFF_PTFIELD2_AUTOSHOW             = 0x00000800;
185 const sal_uInt32 BIFF_PTFIELD2_AUTOSHOWTOP          = 0x00001000;
186 const sal_uInt32 BIFF_PTFIELD2_OUTLINE              = 0x00200000;
187 const sal_uInt32 BIFF_PTFIELD2_INSERTBLANKROW       = 0x00400000;
188 const sal_uInt32 BIFF_PTFIELD2_SUBTOTALTOP          = 0x00800000;
189 
190 const sal_uInt16 BIFF_PTFITEM_HIDDEN                = 0x0001;
191 const sal_uInt16 BIFF_PTFITEM_HIDEDETAILS           = 0x0002;
192 
193 const sal_uInt16 BIFF_PTDEF_ROWGRANDTOTALS          = 0x0001;
194 const sal_uInt16 BIFF_PTDEF_COLGRANDTOTALS          = 0x0002;
195 
196 const sal_uInt8 BIFF_PTDEF_ROWAXIS                  = 1;
197 const sal_uInt8 BIFF_PTDEF_COLAXIS                  = 2;
198 
199 const sal_uInt32 BIFF_PTDEF2_PAGEOVERTHENDOWN       = 0x00000001;
200 const sal_uInt32 BIFF_PTDE2F_ENABLEDRILL            = 0x00020000;
201 const sal_uInt32 BIFF_PTDEF2_PRESERVEFORMATTING     = 0x00080000;
202 const sal_uInt32 BIFF_PTDEF2_MERGEITEM              = 0x00100000;
203 const sal_uInt32 BIFF_PTDEF2_SHOWERROR              = 0x00200000;
204 const sal_uInt32 BIFF_PTDEF2_SHOWMISSING            = 0x00400000;
205 const sal_uInt32 BIFF_PTDEF2_SUBTOTALHIDDENITEMS    = 0x00800000;
206 
207 const sal_Int16 BIFF_PTPAGEFIELDS_ALLITEMS          = 0x7FFD;
208 
209 const sal_Int16 BIFF_PTDATAFIELD_PREVIOUS           = 0x7FFB;
210 const sal_Int16 BIFF_PTDATAFIELD_NEXT               = 0x7FFC;
211 
212 // ----------------------------------------------------------------------------
213 
214 OUString lclReadPivotString( const WorkbookHelper& rHelper, BiffInputStream& rStrm, sal_uInt16 nLen )
215 {
216     if( nLen == BIFF_PT_NOSTRING )
217         return OUString();
218     return (rHelper.getBiff() == BIFF8) ? rStrm.readUniStringBody( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() );
219 }
220 
221 } // namespace
222 
223 // ============================================================================
224 
225 PTFieldItemModel::PTFieldItemModel() :
226     mnCacheItem( -1 ),
227     mnType( XML_data ),
228     mbShowDetails( true ),
229     mbHidden( false )
230 {
231 }
232 
233 void PTFieldItemModel::setBiffType( sal_uInt16 nType )
234 {
235     static const sal_Int32 spnTypes[] = { XML_data, XML_default,
236         XML_sum, XML_countA, XML_avg, XML_max, XML_min, XML_product, XML_count,
237         XML_stdDev, XML_stdDevP, XML_var, XML_varP, XML_grand, XML_blank };
238     mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_data );
239 }
240 
241 // ----------------------------------------------------------------------------
242 
243 PTFieldModel::PTFieldModel() :
244     mnAxis( XML_TOKEN_INVALID ),
245     mnNumFmtId( 0 ),
246     mnAutoShowItems( 10 ),
247     mnAutoShowRankBy( -1 ),
248     mnSortType( XML_manual ),
249     mnSortRefField( -1 ),
250     mnSortRefItem( -1 ),
251     mbDataField( false ),
252     mbDefaultSubtotal( true ),
253     mbSumSubtotal( false ),
254     mbCountASubtotal( false ),
255     mbAverageSubtotal( false ),
256     mbMaxSubtotal( false ),
257     mbMinSubtotal( false ),
258     mbProductSubtotal( false ),
259     mbCountSubtotal( false ),
260     mbStdDevSubtotal( false ),
261     mbStdDevPSubtotal( false ),
262     mbVarSubtotal( false ),
263     mbVarPSubtotal( false ),
264     mbShowAll( true ),
265     mbOutline( true ),
266     mbSubtotalTop( true ),
267     mbInsertBlankRow( false ),
268     mbInsertPageBreak( false ),
269     mbAutoShow( false ),
270     mbTopAutoShow( true ),
271     mbMultiPageItems( false )
272 {
273 }
274 
275 void PTFieldModel::setBiffAxis( sal_uInt8 nAxis )
276 {
277     /*  Weird. The axis field is organized as bit field, but only one of the
278         row/col/page flags are allowed at the same time and refer to the values
279         'axisRow', 'axisCol', and 'axisPage' of the XML attribute
280         'pivotField@axis'. Additionally, the fourth bit determines if the field
281         is a data field, which may appear combined with the row/col/page flags.
282         Therefore, this bit is unrelated to the 'axisValues' value of the
283         'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
284         boolean attribute. */
285     static const sal_Int32 spnAxisIds[] = { XML_TOKEN_INVALID, XML_axisRow, XML_axisCol, XML_TOKEN_INVALID, XML_axisPage };
286     mnAxis = STATIC_ARRAY_SELECT( spnAxisIds, nAxis, XML_TOKEN_INVALID );
287 }
288 
289 // ----------------------------------------------------------------------------
290 
291 PTPageFieldModel::PTPageFieldModel() :
292     mnField( -1 ),
293     mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS )
294 {
295 }
296 
297 // ----------------------------------------------------------------------------
298 
299 PTDataFieldModel::PTDataFieldModel() :
300     mnField( -1 ),
301     mnSubtotal( XML_sum ),
302     mnShowDataAs( XML_normal ),
303     mnBaseField( -1 ),
304     mnBaseItem( -1 ),
305     mnNumFmtId( 0 )
306 {
307 }
308 
309 void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal )
310 {
311     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 };
312     mnSubtotal = STATIC_ARRAY_SELECT( spnSubtotals, nSubtotal, XML_TOKEN_INVALID );
313 }
314 
315 void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs )
316 {
317     static sal_Int32 spnShowDataAs[] = { XML_normal, XML_difference, XML_percent, XML_percentDiff, XML_runTotal, XML_percentOfRow, XML_percentOfCol, XML_percentOfTotal, XML_index };
318     mnShowDataAs = STATIC_ARRAY_SELECT( spnShowDataAs, nShowDataAs, XML_TOKEN_INVALID );
319 }
320 
321 // ----------------------------------------------------------------------------
322 
323 PivotTableField::PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex ) :
324     WorkbookHelper( rPivotTable ),
325     mrPivotTable( rPivotTable ),
326     mnFieldIndex( nFieldIndex )
327 {
328 }
329 
330 void PivotTableField::importPivotField( const AttributeList& rAttribs )
331 {
332     /*  The documentation mentions a value 'axisValues' for the attribute
333         'pivotField@axis'. But this value is not used to mark a data field, as
334         data fields may be inserted in one of the row/column/page dimensions at
335         the same time. Therefore, the boolean attribute 'pivotField@dataField'
336         is really used to mark data fields. */
337     maModel.mnAxis            = rAttribs.getToken( XML_axis, XML_TOKEN_INVALID );
338     maModel.mnNumFmtId        = rAttribs.getInteger( XML_numFmtId, 0 );
339     maModel.mnAutoShowItems   = rAttribs.getInteger( XML_itemPageCount, 10 );
340     maModel.mnAutoShowRankBy  = rAttribs.getInteger( XML_rankBy, -1 );
341     maModel.mnSortType        = rAttribs.getToken( XML_sortType, XML_manual );
342     maModel.mbDataField       = rAttribs.getBool( XML_dataField, false );
343     maModel.mbDefaultSubtotal = rAttribs.getBool( XML_defaultSubtotal, true );
344     maModel.mbSumSubtotal     = rAttribs.getBool( XML_sumSubtotal, false );
345     maModel.mbCountASubtotal  = rAttribs.getBool( XML_countASubtotal, false );
346     maModel.mbAverageSubtotal = rAttribs.getBool( XML_avgSubtotal, false );
347     maModel.mbMaxSubtotal     = rAttribs.getBool( XML_maxSubtotal, false );
348     maModel.mbMinSubtotal     = rAttribs.getBool( XML_minSubtotal, false );
349     maModel.mbProductSubtotal = rAttribs.getBool( XML_productSubtotal, false );
350     maModel.mbCountSubtotal   = rAttribs.getBool( XML_countSubtotal, false );
351     maModel.mbStdDevSubtotal  = rAttribs.getBool( XML_stdDevSubtotal, false );
352     maModel.mbStdDevPSubtotal = rAttribs.getBool( XML_stdDevPSubtotal, false );
353     maModel.mbVarSubtotal     = rAttribs.getBool( XML_varSubtotal, false );
354     maModel.mbVarPSubtotal    = rAttribs.getBool( XML_varPSubtotal, false );
355     maModel.mbShowAll         = rAttribs.getBool( XML_showAll, true );
356     maModel.mbOutline         = rAttribs.getBool( XML_outline, true );
357     maModel.mbSubtotalTop     = rAttribs.getBool( XML_subtotalTop, true );
358     maModel.mbInsertBlankRow  = rAttribs.getBool( XML_insertBlankRow, false );
359     maModel.mbInsertPageBreak = rAttribs.getBool( XML_insertPageBreak, false );
360     maModel.mbAutoShow        = rAttribs.getBool( XML_autoShow, false );
361     maModel.mbTopAutoShow     = rAttribs.getBool( XML_topAutoShow, true );
362     maModel.mbMultiPageItems  = rAttribs.getBool( XML_multipleItemSelectionAllowed, false );
363 }
364 
365 void PivotTableField::importItem( const AttributeList& rAttribs )
366 {
367     PTFieldItemModel aModel;
368     aModel.mnCacheItem   = rAttribs.getInteger( XML_x, -1 );
369     aModel.mnType        = rAttribs.getToken( XML_t, XML_data );
370     aModel.mbShowDetails = rAttribs.getBool( XML_sd, true );
371     aModel.mbHidden      = rAttribs.getBool( XML_h, false );
372     maItems.push_back( aModel );
373 }
374 
375 void PivotTableField::importReference( const AttributeList& rAttribs )
376 {
377     // field index is stored as unsigned integer
378     maModel.mnSortRefField = static_cast< sal_Int32 >( rAttribs.getUnsigned( XML_field, SAL_MAX_UINT32 ) );
379 }
380 
381 void PivotTableField::importReferenceItem( const AttributeList& rAttribs )
382 {
383     maModel.mnSortRefItem = rAttribs.getInteger( XML_v, -1 );
384 }
385 
386 void PivotTableField::importPTField( SequenceInputStream& rStrm )
387 {
388     sal_uInt32 nFlags1, nFlags2;
389     rStrm >> nFlags1 >> maModel.mnNumFmtId >> nFlags2 >> maModel.mnAutoShowItems >> maModel.mnAutoShowRankBy;
390 
391     maModel.setBiffAxis( extractValue< sal_uInt8 >( nFlags1, 0, 3 ) );
392     maModel.mbDataField       = getFlag( nFlags1, BIFF12_PTFIELD_DATAFIELD );
393     maModel.mbDefaultSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_DEFAULT );
394     maModel.mbSumSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_SUM );
395     maModel.mbCountASubtotal  = getFlag( nFlags1, BIFF12_PTFIELD_COUNTA );
396     maModel.mbAverageSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_AVERAGE );
397     maModel.mbMaxSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_MAX );
398     maModel.mbMinSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_MIN );
399     maModel.mbProductSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_PRODUCT );
400     maModel.mbCountSubtotal   = getFlag( nFlags1, BIFF12_PTFIELD_COUNT );
401     maModel.mbStdDevSubtotal  = getFlag( nFlags1, BIFF12_PTFIELD_STDDEV );
402     maModel.mbStdDevPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEVP );
403     maModel.mbVarSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_VAR );
404     maModel.mbVarPSubtotal    = getFlag( nFlags1, BIFF12_PTFIELD_VARP );
405 
406     maModel.mbShowAll         = getFlag( nFlags2, BIFF12_PTFIELD_SHOWALL );
407     maModel.mbOutline         = getFlag( nFlags2, BIFF12_PTFIELD_OUTLINE );
408     maModel.mbSubtotalTop     = getFlag( nFlags2, BIFF12_PTFIELD_SUBTOTALTOP );
409     maModel.mbInsertBlankRow  = getFlag( nFlags2, BIFF12_PTFIELD_INSERTBLANKROW );
410     maModel.mbInsertPageBreak = getFlag( nFlags2, BIFF12_PTFIELD_INSERTPAGEBREAK );
411     maModel.mbAutoShow        = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOW );
412     maModel.mbTopAutoShow     = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOWTOP );
413     maModel.mbMultiPageItems  = getFlag( nFlags2, BIFF12_PTFIELD_MULTIPAGEITEMS );
414 
415     bool bAutoSort = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSORT );
416     bool bAscending = getFlag( nFlags2, BIFF12_PTFIELD_SORTASCENDING );
417     maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
418 }
419 
420 void PivotTableField::importPTFItem( SequenceInputStream& rStrm )
421 {
422     PTFieldItemModel aModel;
423     sal_uInt8 nType;
424     sal_uInt16 nFlags;
425     rStrm >> nType >> nFlags >> aModel.mnCacheItem;
426 
427     aModel.setBiffType( nType );
428     aModel.mbShowDetails = !getFlag( nFlags, BIFF12_PTFITEM_HIDEDETAILS );
429     aModel.mbHidden      = getFlag( nFlags, BIFF12_PTFITEM_HIDDEN );
430 
431     maItems.push_back( aModel );
432 }
433 
434 void PivotTableField::importPTReference( SequenceInputStream& rStrm )
435 {
436     rStrm >> maModel.mnSortRefField;
437 }
438 
439 void PivotTableField::importPTReferenceItem( SequenceInputStream& rStrm )
440 {
441     rStrm >> maModel.mnSortRefItem;
442 }
443 
444 void PivotTableField::importPTField( BiffInputStream& rStrm )
445 {
446     sal_uInt16 nAxis, nSubtCount, nSubtotals;
447     rStrm >> nAxis >> nSubtCount >> nSubtotals;
448     rStrm.skip( 2 );    // item count
449 
450     maModel.setBiffAxis( extractValue< sal_uInt8 >( nAxis, 0, 3 ) );
451     maModel.mbDataField       = getFlag( nAxis, BIFF_PTFIELD_DATAFIELD );
452 
453     maModel.mbDefaultSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_DEFAULT );
454     maModel.mbSumSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_SUM );
455     maModel.mbCountASubtotal  = getFlag( nSubtotals, BIFF_PTFIELD_COUNTA );
456     maModel.mbAverageSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_AVERAGE );
457     maModel.mbMaxSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_MAX );
458     maModel.mbMinSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_MIN );
459     maModel.mbProductSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_PRODUCT );
460     maModel.mbCountSubtotal   = getFlag( nSubtotals, BIFF_PTFIELD_COUNT );
461     maModel.mbStdDevSubtotal  = getFlag( nSubtotals, BIFF_PTFIELD_STDDEV );
462     maModel.mbStdDevPSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_STDDEVP );
463     maModel.mbVarSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_VAR );
464     maModel.mbVarPSubtotal    = getFlag( nSubtotals, BIFF_PTFIELD_VARP );
465 
466     // set different defaults for BIFF
467     maModel.mbShowAll = maModel.mbOutline = maModel.mbSubtotalTop = false;
468 
469     // read following items
470     while( (rStrm.getNextRecId() == BIFF_ID_PTFITEM) && rStrm.startNextRecord() )
471         importPTFItem( rStrm );
472 
473     // read following PTFIELD2 record with additional field settings
474     if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_PTFIELD2) && rStrm.startNextRecord() )
475         importPTField2( rStrm );
476 }
477 
478 void PivotTableField::importPTField2( BiffInputStream& rStrm )
479 {
480     sal_uInt32 nFlags;
481     rStrm >> nFlags;
482     maModel.mnSortRefItem    = rStrm.readInt16();
483     maModel.mnAutoShowRankBy = rStrm.readInt16();
484     maModel.mnNumFmtId       = rStrm.readuInt16();
485 
486     maModel.mnAutoShowItems   = extractValue< sal_Int32 >( nFlags, 24, 8 );
487     maModel.mbShowAll         = getFlag( nFlags, BIFF_PTFIELD2_SHOWALL );
488     maModel.mbOutline         = getFlag( nFlags, BIFF_PTFIELD2_OUTLINE );
489     maModel.mbSubtotalTop     = getFlag( nFlags, BIFF_PTFIELD2_SUBTOTALTOP );
490     maModel.mbInsertBlankRow  = getFlag( nFlags, BIFF_PTFIELD2_INSERTBLANKROW );
491     maModel.mbAutoShow        = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOW );
492     maModel.mbTopAutoShow     = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOWTOP );
493 
494     bool bAutoSort = getFlag( nFlags, BIFF_PTFIELD2_AUTOSORT );
495     bool bAscending = getFlag( nFlags, BIFF_PTFIELD2_SORTASCENDING );
496     maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
497     // mnSortRefField == OOX_PT_DATALAYOUTFIELD will indicate sorting by data field
498     if( maModel.mnSortRefItem >= 0 )
499         maModel.mnSortRefField = OOX_PT_DATALAYOUTFIELD;
500 }
501 
502 void PivotTableField::importPTFItem( BiffInputStream& rStrm )
503 {
504     PTFieldItemModel aModel;
505     sal_uInt16 nType, nFlags;
506     sal_Int16 nCacheItem;
507     rStrm >> nType >> nFlags >> nCacheItem;
508 
509     aModel.setBiffType( nType );
510     aModel.mnCacheItem = nCacheItem;
511     aModel.mbShowDetails = !getFlag( nFlags, BIFF_PTFITEM_HIDEDETAILS );
512     aModel.mbHidden      = getFlag( nFlags, BIFF_PTFITEM_HIDDEN );
513 
514     maItems.push_back( aModel );
515 }
516 
517 void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& rxDPDesc )
518 {
519     /*  Process all fields based on source data, other fields (e.g. group
520         fields) are processed from here. PivotCacahe::getDatabaseIndex()
521         returns -1 for all fields not based on source data. */
522     Reference< XDataPilotField > xDPField;
523     sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
524     if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
525     {
526         // try to get the source field and its name from passed DataPilot descriptor
527         Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
528         xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
529         Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
530         maDPFieldName = xDPFieldName->getName();
531         OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeImport - no field name in source data found" );
532 
533         // try to convert grouping settings
534         if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
535         {
536             // numeric grouping is done inplace, no nested group fields will appear
537             if( pCacheField->hasNumericGrouping() )
538             {
539                 pCacheField->convertNumericGrouping( xDPField );
540             }
541             else if( pCacheField->hasDateGrouping() )
542             {
543                 // first date group settings are inplace
544                 pCacheField->createDateGroupField( xDPField );
545                 // create all nested group fields (if any)
546                 mrPivotTable.finalizeDateGroupingImport( xDPField, mnFieldIndex );
547             }
548             else if( pCacheField->hasParentGrouping() )
549             {
550                 // create a list of all item names, needed to map between original and group items
551                 ::std::vector< OUString > aItems;
552                 pCacheField->getCacheItemNames( aItems );
553                 PivotCacheGroupItemVector aItemNames;
554                 for( ::std::vector< OUString >::iterator aIt = aItems.begin(), aEnd = aItems.end(); aIt != aEnd; ++aIt )
555                     aItemNames.push_back( PivotCacheGroupItem( *aIt ) );
556                 // create all nested group fields (if any)
557                 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, aItemNames );
558             }
559         }
560     }
561     catch( Exception& )
562     {
563     }
564 }
565 
566 void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
567 {
568     if( maDPFieldName.getLength() == 0 )    // prevent endless loops if file format is broken
569     {
570         if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
571         {
572             if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) )
573             {
574                 maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField );
575                 OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
576             }
577         }
578     }
579 }
580 
581 void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, PivotCacheGroupItemVector& orItemNames )
582 {
583     if( maDPFieldName.getLength() == 0 )    // prevent endless loops if file format is broken
584     {
585         if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
586         {
587             maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, orItemNames );
588             // on success, try to create nested group fields
589             Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
590             if( xDPField.is() )
591                 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames );
592         }
593     }
594 }
595 
596 void PivotTableField::convertRowField()
597 {
598     convertRowColPageField( XML_axisRow );
599 }
600 
601 void PivotTableField::convertColField()
602 {
603     convertRowColPageField( XML_axisCol );
604 }
605 
606 void PivotTableField::convertHiddenField()
607 {
608     convertRowColPageField( XML_TOKEN_INVALID );
609 }
610 
611 void PivotTableField::convertPageField( const PTPageFieldModel& rPageField )
612 {
613     OSL_ENSURE( rPageField.mnField == mnFieldIndex, "PivotTableField::convertPageField - wrong field index" );
614     // convert all settings common for row/column/page fields
615     Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage );
616 
617     if( xDPField.is() )
618     {
619         PropertySet aPropSet( xDPField );
620         using namespace ::com::sun::star::sheet;
621 
622         // find cache item used as 'selected page'
623         sal_Int32 nCacheItem = -1;
624         if( maModel.mbMultiPageItems )
625         {
626             // multiple items may be selected
627             OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" );
628             // try to find a single visible item
629             bool bHasMultiItems = false;
630             for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); (aIt != aEnd) && !bHasMultiItems; ++aIt )
631             {
632                 if( (aIt->mnType == XML_data) && !aIt->mbHidden )
633                 {
634                     bHasMultiItems = nCacheItem >= 0;
635                     nCacheItem = bHasMultiItems ? -1 : aIt->mnCacheItem;
636                 }
637             }
638         }
639         else
640         {
641             // single item may be selected
642             if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) )
643                 nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem;
644         }
645 
646         if( nCacheItem >= 0 )
647         {
648             if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
649             {
650                 if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) )
651                 {
652                     OUString aSelectedPage = pSharedItem->getName();
653                     if( aSelectedPage.getLength() > 0 )
654                         aPropSet.setProperty( PROP_SelectedPage, aSelectedPage );
655                 }
656             }
657         }
658     }
659 }
660 
661 void PivotTableField::convertDataField( const PTDataFieldModel& rDataField )
662 {
663     OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" );
664     OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" );
665     Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
666     if( xDPField.is() )
667     {
668         PropertySet aPropSet( xDPField );
669         using namespace ::com::sun::star::sheet;
670 
671         // field orientation
672         aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA );
673 
674         /*  Field aggregation function. Documentation is a little bit confused
675             about which names to use for the count functions. The name 'count'
676             means 'count all', and 'countNum' means 'count numbers'. On the
677             other hand, for subtotals, 'countA' means 'count all', and 'count'
678             means 'count numbers' (see above). */
679         GeneralFunction eAggFunc = GeneralFunction_SUM;
680         switch( rDataField.mnSubtotal )
681         {
682             case XML_sum:       eAggFunc = GeneralFunction_SUM;         break;
683             case XML_count:     eAggFunc = GeneralFunction_COUNT;       break;
684             case XML_average:   eAggFunc = GeneralFunction_AVERAGE;     break;
685             case XML_max:       eAggFunc = GeneralFunction_MAX;         break;
686             case XML_min:       eAggFunc = GeneralFunction_MIN;         break;
687             case XML_product:   eAggFunc = GeneralFunction_PRODUCT;     break;
688             case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS;   break;
689             case XML_stdDev:    eAggFunc = GeneralFunction_STDEV;       break;
690             case XML_stdDevp:   eAggFunc = GeneralFunction_STDEVP;      break;
691             case XML_var:       eAggFunc = GeneralFunction_VAR;         break;
692             case XML_varp:      eAggFunc = GeneralFunction_VARP;        break;
693             default:            OSL_ENSURE( false, "PivotTableField::convertDataField - unknown aggregation function" );
694         }
695         aPropSet.setProperty( PROP_Function, eAggFunc );
696 
697         // field reference ('show data as')
698         DataPilotFieldReference aReference;
699         aReference.ReferenceType = DataPilotFieldReferenceType::NONE;
700         switch( rDataField.mnShowDataAs )
701         {
702             case XML_difference:        aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE;            break;
703             case XML_percent:           aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE;            break;
704             case XML_percentDiff:       aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break;
705             case XML_runTotal:          aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL;              break;
706             case XML_percentOfRow:      aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE;             break;
707             case XML_percentOfCol:      aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE;          break;
708             case XML_percentOfTotal:    aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE;           break;
709             case XML_index:             aReference.ReferenceType = DataPilotFieldReferenceType::INDEX;                      break;
710         }
711         if( aReference.ReferenceType != DataPilotFieldReferenceType::NONE )
712         {
713             if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ) )
714             {
715                 aReference.ReferenceField = pCacheField->getName();
716                 switch( rDataField.mnBaseItem )
717                 {
718                     case OOX_PT_PREVIOUS_ITEM:
719                         aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
720                     break;
721                     case OOX_PT_NEXT_ITEM:
722                         aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
723                     break;
724                     default:
725                         aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
726                         if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) )
727                             aReference.ReferenceItemName = pCacheItem->getName();
728                 }
729                 aPropSet.setProperty( PROP_Reference, aReference );
730             }
731         }
732     }
733 }
734 
735 // private --------------------------------------------------------------------
736 
737 Reference< XDataPilotField > PivotTableField::convertRowColPageField( sal_Int32 nAxis )
738 {
739     bool bDataLayout = mnFieldIndex == OOX_PT_DATALAYOUTFIELD;
740     Reference< XDataPilotField > xDPField = bDataLayout ? mrPivotTable.getDataLayoutField() : mrPivotTable.getDataPilotField( maDPFieldName );
741     OSL_ENSURE( bDataLayout || (nAxis == maModel.mnAxis), "PivotTableField::convertRowColPageField - field axis mismatch" );
742 
743     if( xDPField.is() )
744     {
745         PropertySet aPropSet( xDPField );
746         using namespace ::com::sun::star::sheet;
747 
748         // field orientation
749         DataPilotFieldOrientation eFieldOrient = DataPilotFieldOrientation_HIDDEN;
750         switch( nAxis )
751         {
752             case XML_axisRow:   eFieldOrient = DataPilotFieldOrientation_ROW;       break;
753             case XML_axisCol:   eFieldOrient = DataPilotFieldOrientation_COLUMN;    break;
754             case XML_axisPage:  eFieldOrient = DataPilotFieldOrientation_PAGE;      break;
755         }
756         if( eFieldOrient != DataPilotFieldOrientation_HIDDEN )
757             aPropSet.setProperty( PROP_Orientation, eFieldOrient );
758 
759         // all other settings not for the data layout field
760         if( !bDataLayout )
761         {
762             /*  Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
763                 explicit functions are set. This is different behaviour between
764                 XML (where 'defaultSubtotal' is set regardless of other
765                 functions) and binary formats (where 'defaultSubtotal' is not
766                 set if other functions are set). */
767             ::std::vector< GeneralFunction > aSubtotals;
768             /*  Order of subtotals is fixed in Excel. Documentation is a little
769                 bit confused about which names to use for the count functions.
770                 For subtotals, 'countA' means 'count all', and 'count' means
771                 'count numbers'. On the other hand, for the data field
772                 aggregation function, 'count' means 'count all', and 'countNum'
773                 means 'count numbers' (see below). */
774             if( maModel.mbSumSubtotal )     aSubtotals.push_back( GeneralFunction_SUM );
775             if( maModel.mbCountASubtotal )  aSubtotals.push_back( GeneralFunction_COUNT );
776             if( maModel.mbAverageSubtotal ) aSubtotals.push_back( GeneralFunction_AVERAGE );
777             if( maModel.mbMaxSubtotal )     aSubtotals.push_back( GeneralFunction_MAX );
778             if( maModel.mbMinSubtotal )     aSubtotals.push_back( GeneralFunction_MIN );
779             if( maModel.mbProductSubtotal ) aSubtotals.push_back( GeneralFunction_PRODUCT );
780             if( maModel.mbCountSubtotal )   aSubtotals.push_back( GeneralFunction_COUNTNUMS );
781             if( maModel.mbStdDevSubtotal )  aSubtotals.push_back( GeneralFunction_STDEV );
782             if( maModel.mbStdDevPSubtotal ) aSubtotals.push_back( GeneralFunction_STDEVP );
783             if( maModel.mbVarSubtotal )     aSubtotals.push_back( GeneralFunction_VAR );
784             if( maModel.mbVarPSubtotal )    aSubtotals.push_back( GeneralFunction_VARP );
785             // if no function is set manually, check the 'defaultSubtotal' flag
786             if( aSubtotals.empty() && maModel.mbDefaultSubtotal )
787                 aSubtotals.push_back( GeneralFunction_AUTO );
788             aPropSet.setProperty( PROP_Subtotals, ContainerHelper::vectorToSequence( aSubtotals ) );
789 
790             // layout settings
791             DataPilotFieldLayoutInfo aLayoutInfo;
792             aLayoutInfo.LayoutMode = maModel.mbOutline ?
793                 (maModel.mbSubtotalTop ? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP : DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM) :
794                 DataPilotFieldLayoutMode::TABULAR_LAYOUT;
795             aLayoutInfo.AddEmptyLines = maModel.mbInsertBlankRow;
796             aPropSet.setProperty( PROP_LayoutInfo, aLayoutInfo );
797             aPropSet.setProperty( PROP_ShowEmpty, maModel.mbShowAll );
798 
799             // auto show (OOXML/BIFF12 only)
800             if( maModel.mbAutoShow )
801             {
802                 DataPilotFieldAutoShowInfo aAutoShowInfo;
803                 aAutoShowInfo.IsEnabled = sal_True;
804                 aAutoShowInfo.ShowItemsMode = maModel.mbTopAutoShow ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
805                 aAutoShowInfo.ItemCount = maModel.mnAutoShowItems;
806                 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnAutoShowRankBy ) )
807                     aAutoShowInfo.DataField = pCacheField->getName();
808                 aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
809             }
810 
811             // auto sort
812             DataPilotFieldSortInfo aSortInfo;
813             aSortInfo.IsAscending = maModel.mnSortType == XML_ascending;
814             if( (maModel.mnSortType != XML_ascending) && (maModel.mnSortType != XML_descending) )
815             {
816                 aSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
817             }
818             else
819             {
820                 const PivotCacheField* pCacheField = (maModel.mnSortRefField == OOX_PT_DATALAYOUTFIELD) ?
821                     mrPivotTable.getCacheFieldOfDataField( maModel.mnSortRefItem ) : 0;
822                 if( pCacheField )
823                 {
824                     aSortInfo.Mode = DataPilotFieldSortMode::DATA;
825                     aSortInfo.Field = pCacheField->getName();
826                 }
827                 else
828                 {
829                     aSortInfo.Mode = DataPilotFieldSortMode::NAME;
830                 }
831             }
832             aPropSet.setProperty( PROP_SortInfo, aSortInfo );
833 
834             // item settings
835             if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) try
836             {
837                 Reference< XNameAccess > xDPItemsNA( xDPField->getItems(), UNO_QUERY_THROW );
838                 for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
839                 {
840                     if( aIt->mnType == XML_data )
841                     {
842                         if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( aIt->mnCacheItem ) ) try
843                         {
844                             PropertySet aItemProp( xDPItemsNA->getByName( pSharedItem->getName() ) );
845                             aItemProp.setProperty( PROP_ShowDetail, aIt->mbShowDetails );
846                             aItemProp.setProperty( PROP_IsHidden, aIt->mbHidden );
847                         }
848                         catch( Exception& )
849                         {
850                             // catch every failed container access to be able to process following items
851                         }
852                     }
853                 }
854             }
855             catch( Exception& )
856             {
857             }
858         }
859     }
860     return xDPField;
861 }
862 
863 // ============================================================================
864 
865 PTFilterModel::PTFilterModel() :
866     mfValue( 0.0 ),
867     mnField( -1 ),
868     mnMemPropField( -1 ),
869     mnType( XML_TOKEN_INVALID ),
870     mnEvalOrder( 0 ),
871     mnId( -1 ),
872     mnMeasureField( -1 ),
873     mnMeasureHier( -1 ),
874     mbTopFilter( true )
875 {
876 }
877 
878 // ----------------------------------------------------------------------------
879 
880 PivotTableFilter::PivotTableFilter( const PivotTable& rPivotTable ) :
881     WorkbookHelper( rPivotTable ),
882     mrPivotTable( rPivotTable )
883 {
884 }
885 
886 void PivotTableFilter::importFilter( const AttributeList& rAttribs )
887 {
888     maModel.maName         = rAttribs.getXString( XML_name, OUString() );
889     maModel.maDescription  = rAttribs.getXString( XML_description, OUString() );
890     maModel.maStrValue1    = rAttribs.getXString( XML_stringValue1, OUString() );
891     maModel.maStrValue2    = rAttribs.getXString( XML_stringValue2, OUString() );
892     maModel.mnField        = rAttribs.getInteger( XML_fld, -1 );
893     maModel.mnMemPropField = rAttribs.getInteger( XML_mpFld, -1 );
894     maModel.mnType         = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
895     maModel.mnEvalOrder    = rAttribs.getInteger( XML_evalOrder, 0 );
896     maModel.mnId           = rAttribs.getInteger( XML_id, -1 );
897     maModel.mnMeasureField = rAttribs.getInteger( XML_iMeasureFld, -1 );
898     maModel.mnMeasureHier  = rAttribs.getInteger( XML_iMeasureHier, -1 );
899 }
900 
901 void PivotTableFilter::importTop10( const AttributeList& rAttribs )
902 {
903     OSL_ENSURE( rAttribs.getBool( XML_percent, false ) == (maModel.mnType == XML_percent),
904         "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
905     maModel.mfValue     = rAttribs.getDouble( XML_val, 0.0 );
906     maModel.mbTopFilter = rAttribs.getBool( XML_top, true );
907 }
908 
909 void PivotTableFilter::importPTFilter( SequenceInputStream& rStrm )
910 {
911     sal_Int32 nType;
912     sal_uInt16 nFlags;
913     rStrm >> maModel.mnField >> maModel.mnMemPropField >> nType;
914     rStrm.skip( 4 );    // unused
915     rStrm >> maModel.mnId >> maModel.mnMeasureField >> maModel.mnMeasureHier >> nFlags;
916     if( getFlag( nFlags, BIFF12_PTFILTER_HASNAME ) )
917         rStrm >> maModel.maName;
918     if( getFlag( nFlags, BIFF12_PTFILTER_HASDESCRIPTION ) )
919         rStrm >> maModel.maDescription;
920     if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE1 ) )
921         rStrm >> maModel.maStrValue1;
922     if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE2 ) )
923         rStrm >> maModel.maStrValue2;
924 
925     static sal_Int32 spnTypes[] =
926     {
927         XML_unknown,
928         // data field top10 filter (1-3)
929         XML_count, XML_percent, XML_sum,
930         // caption filter (4-17)
931         XML_captionEqual, XML_captionNotEqual,
932         XML_captionBeginsWith, XML_captionNotBeginsWith, XML_captionEndsWith, XML_captionNotEndsWith,
933         XML_captionContains, XML_captionNotContains, XML_captionGreaterThan, XML_captionGreaterThanOrEqual,
934         XML_captionLessThan, XML_captionLessThanOrEqual, XML_captionBetween, XML_captionNotBetween,
935         // value filter (18-25)
936         XML_valueEqual, XML_valueNotEqual, XML_valueGreaterThan, XML_valueGreaterThanOrEqual,
937         XML_valueLessThan, XML_valueLessThanOrEqual, XML_valueBetween, XML_valueNotBetween,
938         // date filter (26-65)
939         XML_dateEqual, XML_dateOlderThan, XML_dateNewerThan, XML_dateBetween,
940         XML_tomorrow, XML_today, XML_yesterday, XML_nextWeek, XML_thisWeek, XML_lastWeek,
941         XML_nextMonth, XML_thisMonth, XML_lastMonth, XML_nextQuarter, XML_thisQuarter, XML_lastQuarter,
942         XML_nextYear, XML_thisYear, XML_lastYear, XML_yearToDate, XML_Q1, XML_Q2, XML_Q3, XML_Q4,
943         XML_M1, XML_M2, XML_M3, XML_M4, XML_M5, XML_M6, XML_M7, XML_M8, XML_M9, XML_M10, XML_M11, XML_M12,
944         XML_dateNotEqual, XML_dateOlderThanOrEqual, XML_dateNewerThanOrEqual, XML_dateNotBetween
945     };
946     maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
947 }
948 
949 void PivotTableFilter::importTop10Filter( SequenceInputStream& rStrm )
950 {
951     sal_uInt8 nFlags;
952     rStrm >> nFlags >> maModel.mfValue;
953 
954     OSL_ENSURE( getFlag( nFlags, BIFF12_TOP10FILTER_PERCENT ) == (maModel.mnType == XML_percent),
955         "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
956     maModel.mbTopFilter = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
957 }
958 
959 void PivotTableFilter::finalizeImport()
960 {
961     // only simple top10 filter supported
962     if( maModel.mnType == XML_count )
963     {
964         PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) );
965         if( aPropSet.is() )
966         {
967             using namespace ::com::sun::star::sheet;
968             DataPilotFieldAutoShowInfo aAutoShowInfo;
969             aAutoShowInfo.IsEnabled = sal_True;
970             aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
971             aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 );
972             if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) )
973                 aAutoShowInfo.DataField = pCacheField->getName();
974             aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
975         }
976     }
977 }
978 
979 // ============================================================================
980 
981 PTDefinitionModel::PTDefinitionModel() :
982     mnCacheId( -1 ),
983     mnDataPosition( 0 ),
984     mnPageWrap( 0 ),
985     mnIndent( 1 ),
986     mnChartFormat( 0 ),
987     mnRowFields( 0 ),
988     mnColFields( 0 ),
989     mbDataOnRows( false ),
990     mbShowError( false ),
991     mbShowMissing( true ),
992     mbShowItems( true ),
993     mbDisableFieldList( false ),
994     mbShowCalcMembers( true ),
995     mbVisualTotals( true ),
996     mbShowDrill( true ),
997     mbPrintDrill( false ),
998     mbEnableDrill( true ),
999     mbPreserveFormatting( true ),
1000     mbUseAutoFormat( false ),
1001     mbPageOverThenDown( false ),
1002     mbSubtotalHiddenItems( false ),
1003     mbRowGrandTotals( true ),
1004     mbColGrandTotals( true ),
1005     mbFieldPrintTitles( false ),
1006     mbItemPrintTitles( false ),
1007     mbMergeItem( false ),
1008     mbShowEmptyRow( false ),
1009     mbShowEmptyCol( false ),
1010     mbShowHeaders( true ),
1011     mbFieldListSortAsc( false ),
1012     mbCustomListSort( true )
1013 {
1014 }
1015 
1016 // ----------------------------------------------------------------------------
1017 
1018 PTLocationModel::PTLocationModel() :
1019     mnFirstHeaderRow( 0 ),
1020     mnFirstDataRow( 0 ),
1021     mnFirstDataCol( 0 ),
1022     mnRowPageCount( 0 ),
1023     mnColPageCount( 0 )
1024 {
1025 }
1026 
1027 // ----------------------------------------------------------------------------
1028 
1029 PivotTable::PivotTable( const WorkbookHelper& rHelper ) :
1030     WorkbookHelper( rHelper ),
1031     maDataField( *this, OOX_PT_DATALAYOUTFIELD ),
1032     mpPivotCache( 0 )
1033 {
1034 }
1035 
1036 void PivotTable::importPivotTableDefinition( const AttributeList& rAttribs )
1037 {
1038     maDefModel.maName                = rAttribs.getXString( XML_name, OUString() );
1039     maDefModel.maDataCaption         = rAttribs.getXString( XML_dataCaption , OUString() );
1040     maDefModel.maGrandTotalCaption   = rAttribs.getXString( XML_grandTotalCaption, OUString() );
1041     maDefModel.maRowHeaderCaption    = rAttribs.getXString( XML_rowHeaderCaption, OUString() );
1042     maDefModel.maColHeaderCaption    = rAttribs.getXString( XML_colHeaderCaption, OUString() );
1043     maDefModel.maErrorCaption        = rAttribs.getXString( XML_errorCaption, OUString() );
1044     maDefModel.maMissingCaption      = rAttribs.getXString( XML_missingCaption, OUString() );
1045     maDefModel.maPageStyle           = rAttribs.getXString( XML_pageStyle, OUString() );
1046     maDefModel.maPivotTableStyle     = rAttribs.getXString( XML_pivotTableStyle, OUString() );
1047     maDefModel.maVacatedStyle        = rAttribs.getXString( XML_vacatedStyle, OUString() );
1048     maDefModel.maTag                 = rAttribs.getXString( XML_tag, OUString() );
1049     maDefModel.mnCacheId             = rAttribs.getInteger( XML_cacheId, -1 );
1050     maDefModel.mnDataPosition        = rAttribs.getInteger( XML_dataPosition, 0 );
1051     maDefModel.mnPageWrap            = rAttribs.getInteger( XML_pageWrap, 0 );
1052     maDefModel.mnIndent              = rAttribs.getInteger( XML_indent, 1 );
1053     maDefModel.mnChartFormat         = rAttribs.getInteger( XML_chartFormat, 0 );
1054     maDefModel.mnAutoFormatId        = rAttribs.getInteger( XML_autoFormatId, 0 );
1055     maDefModel.mbDataOnRows          = rAttribs.getBool( XML_dataOnRows, false );
1056     maDefModel.mbShowError           = rAttribs.getBool( XML_showError, false );
1057     maDefModel.mbShowMissing         = rAttribs.getBool( XML_showMissing, true );
1058     maDefModel.mbShowItems           = rAttribs.getBool( XML_showItems, true );
1059     maDefModel.mbDisableFieldList    = rAttribs.getBool( XML_disableFieldList, false );
1060     maDefModel.mbShowCalcMembers     = rAttribs.getBool( XML_showCalcMbrs, true );
1061     maDefModel.mbVisualTotals        = rAttribs.getBool( XML_visualTotals, true );
1062     maDefModel.mbShowDrill           = rAttribs.getBool( XML_showDrill, true );
1063     maDefModel.mbPrintDrill          = rAttribs.getBool( XML_printDrill, false );
1064     maDefModel.mbEnableDrill         = rAttribs.getBool( XML_enableDrill, true );
1065     maDefModel.mbPreserveFormatting  = rAttribs.getBool( XML_preserveFormatting, true );
1066     maDefModel.mbUseAutoFormat       = rAttribs.getBool( XML_useAutoFormatting, false );
1067     maDefModel.mbPageOverThenDown    = rAttribs.getBool( XML_pageOverThenDown, false );
1068     maDefModel.mbSubtotalHiddenItems = rAttribs.getBool( XML_subtotalHiddenItems, false );
1069     maDefModel.mbRowGrandTotals      = rAttribs.getBool( XML_rowGrandTotals, true );
1070     maDefModel.mbColGrandTotals      = rAttribs.getBool( XML_colGrandTotals, true );
1071     maDefModel.mbFieldPrintTitles    = rAttribs.getBool( XML_fieldPrintTitles, false );
1072     maDefModel.mbItemPrintTitles     = rAttribs.getBool( XML_itemPrintTitles, false );
1073     maDefModel.mbMergeItem           = rAttribs.getBool( XML_mergeItem, false );
1074     maDefModel.mbShowEmptyRow        = rAttribs.getBool( XML_showEmptyRow, false );
1075     maDefModel.mbShowEmptyCol        = rAttribs.getBool( XML_showEmptyCol, false );
1076     maDefModel.mbShowHeaders         = rAttribs.getBool( XML_showHeaders, true );
1077     maDefModel.mbFieldListSortAsc    = rAttribs.getBool( XML_fieldListSortAscending, false );
1078     maDefModel.mbCustomListSort      = rAttribs.getBool( XML_customListSort, true );
1079     maDefModel.mbApplyNumFmt         = rAttribs.getBool( XML_applyNumberFormats, false );
1080     maDefModel.mbApplyFont           = rAttribs.getBool( XML_applyFontFormats, false );
1081     maDefModel.mbApplyAlignment      = rAttribs.getBool( XML_applyAlignmentFormats, false );
1082     maDefModel.mbApplyBorder         = rAttribs.getBool( XML_applyBorderFormats, false );
1083     maDefModel.mbApplyFill           = rAttribs.getBool( XML_applyPatternFormats, false );
1084     // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
1085     maDefModel.mbApplyProtection     = rAttribs.getBool( XML_applyWidthHeightFormats, false );
1086 }
1087 
1088 void PivotTable::importLocation( const AttributeList& rAttribs, sal_Int16 nSheet )
1089 {
1090     getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet );
1091     maLocationModel.mnFirstHeaderRow = rAttribs.getInteger( XML_firstHeaderRow, 0 );
1092     maLocationModel.mnFirstDataRow   = rAttribs.getInteger( XML_firstDataRow, 0 );
1093     maLocationModel.mnFirstDataCol   = rAttribs.getInteger( XML_firstDataCol, 0 );
1094     maLocationModel.mnRowPageCount   = rAttribs.getInteger( XML_rowPageCount, 0 );
1095     maLocationModel.mnColPageCount   = rAttribs.getInteger( XML_colPageCount, 0 );
1096 }
1097 
1098 void PivotTable::importRowField( const AttributeList& rAttribs )
1099 {
1100     importField( maRowFields, rAttribs );
1101 }
1102 
1103 void PivotTable::importColField( const AttributeList& rAttribs )
1104 {
1105     importField( maColFields, rAttribs );
1106 }
1107 
1108 void PivotTable::importPageField( const AttributeList& rAttribs )
1109 {
1110     PTPageFieldModel aModel;
1111     aModel.maName      = rAttribs.getXString( XML_name, OUString() );
1112     aModel.mnField     = rAttribs.getInteger( XML_fld, -1 );
1113     // specification is wrong, XML_item is not the cache item, but the field item
1114     aModel.mnItem      = rAttribs.getInteger( XML_item, BIFF12_PTPAGEFIELD_MULTIITEMS );
1115     maPageFields.push_back( aModel );
1116 }
1117 
1118 void PivotTable::importDataField( const AttributeList& rAttribs )
1119 {
1120     PTDataFieldModel aModel;
1121     aModel.maName       = rAttribs.getXString( XML_name, OUString() );
1122     aModel.mnField      = rAttribs.getInteger( XML_fld, -1 );
1123     aModel.mnSubtotal   = rAttribs.getToken( XML_subtotal, XML_sum );
1124     aModel.mnShowDataAs = rAttribs.getToken( XML_showDataAs, XML_normal );
1125     aModel.mnBaseField  = rAttribs.getInteger( XML_baseField, -1 );
1126     aModel.mnBaseItem   = rAttribs.getInteger( XML_baseItem, -1 );
1127     aModel.mnNumFmtId   = rAttribs.getInteger( XML_numFmtId, 0 );
1128     maDataFields.push_back( aModel );
1129 }
1130 
1131 void PivotTable::importPTDefinition( SequenceInputStream& rStrm )
1132 {
1133     sal_uInt32 nFlags1, nFlags2, nFlags3;
1134     sal_uInt8 nDataAxis;
1135     rStrm >> nFlags1 >> nFlags2 >> nFlags3 >> nDataAxis;
1136     maDefModel.mnPageWrap = rStrm.readuInt8();
1137     rStrm.skip( 2 );    // refresh versions
1138     rStrm >> maDefModel.mnDataPosition;
1139     maDefModel.mnAutoFormatId = rStrm.readuInt16();
1140     rStrm.skip( 2 );    // unused
1141     rStrm >> maDefModel.mnChartFormat >> maDefModel.mnCacheId >> maDefModel.maName;
1142     if( getFlag( nFlags2, BIFF12_PTDEF_HASDATACAPTION ) )
1143         rStrm >> maDefModel.maDataCaption;
1144     if( getFlag( nFlags2, BIFF12_PTDEF_HASGRANDTOTALCAPTION ) )
1145         rStrm >> maDefModel.maGrandTotalCaption;
1146     if( !getFlag( nFlags3, BIFF12_PTDEF_NOERRORCAPTION ) )   // missing flag indicates existing string
1147         rStrm >> maDefModel.maErrorCaption;
1148     if( !getFlag( nFlags3, BIFF12_PTDEF_NOMISSINGCAPTION ) ) // missing flag indicates existing string
1149         rStrm >> maDefModel.maMissingCaption;
1150     if( getFlag( nFlags2, BIFF12_PTDEF_HASPAGESTYLE ) )
1151         rStrm >> maDefModel.maPageStyle;
1152     if( getFlag( nFlags2, BIFF12_PTDEF_HASPIVOTTABLESTYLE ) )
1153         rStrm >> maDefModel.maPivotTableStyle;
1154     if( getFlag( nFlags2, BIFF12_PTDEF_HASVACATEDSTYLE ) )
1155         rStrm >> maDefModel.maVacatedStyle;
1156     if( getFlag( nFlags2, BIFF12_PTDEF_HASTAG ) )
1157         rStrm >> maDefModel.maTag;
1158     if( getFlag( nFlags3, BIFF12_PTDEF_HASCOLHEADERCAPTION ) )   // TODO: right order (col/row)? spec is unclear
1159         rStrm >> maDefModel.maColHeaderCaption;
1160     if( getFlag( nFlags3, BIFF12_PTDEF_HASROWHEADERCAPTION ) )
1161         rStrm >> maDefModel.maRowHeaderCaption;
1162 
1163     OSL_ENSURE( (nDataAxis == BIFF12_PTDEF_ROWAXIS) || (nDataAxis == BIFF12_PTDEF_COLAXIS),
1164         "PivotTable::importPTDefinition - unexpected axis position for data field" );
1165 
1166     maDefModel.mnIndent              = extractValue< sal_uInt8 >( nFlags1, 24, 7 );
1167     maDefModel.mbDataOnRows          = nDataAxis == BIFF12_PTDEF_ROWAXIS;
1168     maDefModel.mbShowError           = getFlag( nFlags2, BIFF12_PTDEF_SHOWERROR );
1169     maDefModel.mbShowMissing         = getFlag( nFlags2, BIFF12_PTDEF_SHOWMISSING );
1170     maDefModel.mbShowItems           = getFlag( nFlags1, BIFF12_PTDEF_SHOWITEMS );
1171     maDefModel.mbDisableFieldList    = getFlag( nFlags1, BIFF12_PTDEF_DISABLEFIELDLIST );
1172     maDefModel.mbShowCalcMembers     = !getFlag( nFlags1, BIFF12_PTDEF_HIDECALCMEMBERS );
1173     maDefModel.mbVisualTotals        = !getFlag( nFlags1, BIFF12_PTDEF_WITHHIDDENTOTALS );
1174     maDefModel.mbShowDrill           = !getFlag( nFlags1, BIFF12_PTDEF_HIDEDRILL );
1175     maDefModel.mbPrintDrill          = getFlag( nFlags1, BIFF12_PTDEF_PRINTDRILL );
1176     maDefModel.mbEnableDrill         = getFlag( nFlags2, BIFF12_PTDEF_ENABLEDRILL );
1177     maDefModel.mbPreserveFormatting  = getFlag( nFlags2, BIFF12_PTDEF_PRESERVEFORMATTING );
1178     maDefModel.mbUseAutoFormat       = getFlag( nFlags2, BIFF12_PTDEF_USEAUTOFORMAT );
1179     maDefModel.mbPageOverThenDown    = getFlag( nFlags2, BIFF12_PTDEF_PAGEOVERTHENDOWN );
1180     maDefModel.mbSubtotalHiddenItems = getFlag( nFlags2, BIFF12_PTDEF_SUBTOTALHIDDENITEMS );
1181     maDefModel.mbRowGrandTotals      = getFlag( nFlags2, BIFF12_PTDEF_ROWGRANDTOTALS );
1182     maDefModel.mbColGrandTotals      = getFlag( nFlags2, BIFF12_PTDEF_COLGRANDTOTALS );
1183     maDefModel.mbFieldPrintTitles    = getFlag( nFlags2, BIFF12_PTDEF_FIELDPRINTTITLES );
1184     maDefModel.mbItemPrintTitles     = getFlag( nFlags2, BIFF12_PTDEF_ITEMPRINTTITLES );
1185     maDefModel.mbMergeItem           = getFlag( nFlags2, BIFF12_PTDEF_MERGEITEM );
1186     maDefModel.mbApplyNumFmt         = getFlag( nFlags2, BIFF12_PTDEF_APPLYNUMFMT );
1187     maDefModel.mbApplyFont           = getFlag( nFlags2, BIFF12_PTDEF_APPLYFONT );
1188     maDefModel.mbApplyAlignment      = getFlag( nFlags2, BIFF12_PTDEF_APPLYALIGNMENT );
1189     maDefModel.mbApplyBorder         = getFlag( nFlags2, BIFF12_PTDEF_APPLYBORDER );
1190     maDefModel.mbApplyFill           = getFlag( nFlags2, BIFF12_PTDEF_APPLYFILL );
1191     maDefModel.mbApplyProtection     = getFlag( nFlags2, BIFF12_PTDEF_APPLYPROTECTION );
1192     maDefModel.mbShowEmptyRow        = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYROW );
1193     maDefModel.mbShowEmptyCol        = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYCOL );
1194     maDefModel.mbShowHeaders         = !getFlag( nFlags1, BIFF12_PTDEF_HIDEHEADERS );
1195     maDefModel.mbFieldListSortAsc    = getFlag( nFlags3, BIFF12_PTDEF_FIELDLISTSORTASC );
1196     maDefModel.mbCustomListSort      = !getFlag( nFlags3, BIFF12_PTDEF_NOCUSTOMLISTSORT );
1197 }
1198 
1199 void PivotTable::importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet )
1200 {
1201     BinRange aBinRange;
1202     rStrm   >> aBinRange >> maLocationModel.mnFirstHeaderRow
1203             >> maLocationModel.mnFirstDataRow >> maLocationModel.mnFirstDataCol
1204             >> maLocationModel.mnRowPageCount >> maLocationModel.mnColPageCount;
1205     getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
1206 }
1207 
1208 void PivotTable::importPTRowFields( SequenceInputStream& rStrm )
1209 {
1210     importFields( maRowFields, rStrm );
1211 }
1212 
1213 void PivotTable::importPTColFields( SequenceInputStream& rStrm )
1214 {
1215     importFields( maColFields, rStrm );
1216 }
1217 
1218 void PivotTable::importPTPageField( SequenceInputStream& rStrm )
1219 {
1220     PTPageFieldModel aModel;
1221     sal_uInt8 nFlags;
1222     rStrm >> aModel.mnField >> aModel.mnItem;
1223     rStrm.skip( 4 );    // hierarchy
1224     rStrm >> nFlags;
1225     if( getFlag( nFlags, BIFF12_PTPAGEFIELD_HASNAME ) )
1226         rStrm >> aModel.maName;
1227     maPageFields.push_back( aModel );
1228 }
1229 
1230 void PivotTable::importPTDataField( SequenceInputStream& rStrm )
1231 {
1232     PTDataFieldModel aModel;
1233     sal_Int32 nSubtotal, nShowDataAs;
1234     sal_uInt8 nHasName;
1235     rStrm >> aModel.mnField >> nSubtotal >> nShowDataAs >> aModel.mnBaseField >> aModel.mnBaseItem >> aModel.mnNumFmtId >> nHasName;
1236     if( nHasName == 1 )
1237         rStrm >> aModel.maName;
1238     aModel.setBiffSubtotal( nSubtotal );
1239     aModel.setBiffShowDataAs( nShowDataAs );
1240     maDataFields.push_back( aModel );
1241 }
1242 
1243 void PivotTable::importPTDefinition( BiffInputStream& rStrm, sal_Int16 nSheet )
1244 {
1245     BinRange aBinRange;
1246     sal_uInt16 nFlags, nTabNameLen, nDataNameLen;
1247     rStrm >> aBinRange;
1248     maLocationModel.mnFirstHeaderRow = rStrm.readuInt16();
1249     maLocationModel.mnFirstDataRow   = rStrm.readuInt16();
1250     maLocationModel.mnFirstDataCol   = rStrm.readuInt16();
1251     maDefModel.mnCacheId             = rStrm.readuInt16();
1252     rStrm.skip( 2 );                 // unused
1253     maDefModel.mbDataOnRows          = rStrm.readuInt16() == BIFF_PTDEF_ROWAXIS;
1254     maDefModel.mnDataPosition        = rStrm.readInt16();
1255     rStrm.skip( 2 );                 // number of fields
1256     rStrm >> maDefModel.mnRowFields >> maDefModel.mnColFields;
1257     rStrm.skip( 8 );                 // number of page fields, data fields, data rows, data columns
1258     rStrm >> nFlags;
1259     maDefModel.mnChartFormat         = rStrm.readuInt16();
1260     rStrm >> nTabNameLen >> nDataNameLen;
1261     maDefModel.maName                = lclReadPivotString( *this, rStrm, nTabNameLen );
1262     maDefModel.maDataCaption         = lclReadPivotString( *this, rStrm, nDataNameLen );
1263 
1264     maDefModel.mbRowGrandTotals  = getFlag( nFlags, BIFF_PTDEF_ROWGRANDTOTALS );
1265     maDefModel.mbColGrandTotals  = getFlag( nFlags, BIFF_PTDEF_COLGRANDTOTALS );
1266 
1267     getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
1268 }
1269 
1270 void PivotTable::importPTDefinition2( BiffInputStream& rStrm )
1271 {
1272     if( getBiff() == BIFF8 )
1273     {
1274         sal_uInt16 nErrCaptLen, nMissCaptLen, nTagLen, nPageStyleLen, nTabStyleLen, nVacStyleLen;
1275         sal_uInt32 nFlags;
1276         rStrm.skip( 2 );    // number of formatting records
1277         rStrm >> nErrCaptLen >> nMissCaptLen >> nTagLen;
1278         rStrm.skip( 6 );    // number of selection records, page rows, page columns
1279         rStrm >> nFlags >> nPageStyleLen >> nTabStyleLen >> nVacStyleLen;
1280         maDefModel.maErrorCaption    = lclReadPivotString( *this, rStrm, nErrCaptLen );
1281         maDefModel.maMissingCaption  = lclReadPivotString( *this, rStrm, nMissCaptLen );
1282         maDefModel.maTag             = lclReadPivotString( *this, rStrm, nTagLen );
1283         maDefModel.maPageStyle       = lclReadPivotString( *this, rStrm, nPageStyleLen );
1284         maDefModel.maPivotTableStyle = lclReadPivotString( *this, rStrm, nTabStyleLen );
1285         maDefModel.maVacatedStyle    = lclReadPivotString( *this, rStrm, nVacStyleLen );
1286 
1287         maDefModel.mbShowError           = getFlag( nFlags, BIFF_PTDEF2_SHOWERROR );
1288         maDefModel.mbShowMissing         = getFlag( nFlags, BIFF_PTDEF2_SHOWMISSING );
1289         maDefModel.mbEnableDrill         = getFlag( nFlags, BIFF_PTDE2F_ENABLEDRILL );
1290         maDefModel.mbPreserveFormatting  = getFlag( nFlags, BIFF_PTDEF2_PRESERVEFORMATTING );
1291         maDefModel.mbPageOverThenDown    = getFlag( nFlags, BIFF_PTDEF2_PAGEOVERTHENDOWN );
1292         maDefModel.mbSubtotalHiddenItems = getFlag( nFlags, BIFF_PTDEF2_SUBTOTALHIDDENITEMS );
1293         maDefModel.mbMergeItem           = getFlag( nFlags, BIFF_PTDEF2_MERGEITEM );
1294     }
1295 }
1296 
1297 void PivotTable::importPTRowColFields( BiffInputStream& rStrm )
1298 {
1299     // first PTROWCOLFIELDS record contains row fields unless there are no row fields
1300     if( (maDefModel.mnRowFields > 0) && maRowFields.empty() )
1301         importFields( maRowFields, rStrm, maDefModel.mnRowFields );
1302     else if( (maDefModel.mnColFields > 0) && maColFields.empty() )
1303         importFields( maColFields, rStrm, maDefModel.mnColFields );
1304 }
1305 
1306 void PivotTable::importPTPageFields( BiffInputStream& rStrm )
1307 {
1308     while( rStrm.getRemaining() >= 6 )
1309     {
1310         PTPageFieldModel aModel;
1311         sal_Int16 nField, nItem;
1312         rStrm >> nField >> nItem;
1313         rStrm.skip( 2 );    // dropdown object ID
1314         aModel.mnField = nField;
1315         aModel.mnItem = (nItem == BIFF_PTPAGEFIELDS_ALLITEMS) ? BIFF12_PTPAGEFIELD_MULTIITEMS : nItem;
1316         maPageFields.push_back( aModel );
1317     }
1318 }
1319 
1320 void PivotTable::importPTDataField( BiffInputStream& rStrm )
1321 {
1322     PTDataFieldModel aModel;
1323     sal_Int16 nField, nBaseField, nBaseItem;
1324     sal_uInt16 nSubtotal, nShowDataAs, nNumFmt, nNameLen;
1325     rStrm >> nField >> nSubtotal >> nShowDataAs >> nBaseField >> nBaseItem >> nNumFmt >> nNameLen;
1326     aModel.maName = lclReadPivotString( *this, rStrm, nNameLen );
1327 
1328     aModel.mnField = nField;
1329     aModel.setBiffSubtotal( nSubtotal );
1330     aModel.setBiffShowDataAs( nShowDataAs );
1331     aModel.mnBaseField = nBaseField;
1332     switch( nBaseItem )
1333     {
1334         case BIFF_PTDATAFIELD_PREVIOUS: aModel.mnBaseItem = OOX_PT_PREVIOUS_ITEM;   break;
1335         case BIFF_PTDATAFIELD_NEXT:     aModel.mnBaseItem = OOX_PT_NEXT_ITEM;       break;
1336         default:                        aModel.mnBaseItem = nBaseItem;
1337     }
1338     aModel.mnNumFmtId = nNumFmt;
1339 
1340     maDataFields.push_back( aModel );
1341 }
1342 
1343 PivotTableField& PivotTable::createTableField()
1344 {
1345     sal_Int32 nFieldIndex = static_cast< sal_Int32 >( maFields.size() );
1346     PivotTableFieldVector::value_type xTableField( new PivotTableField( *this, nFieldIndex ) );
1347     maFields.push_back( xTableField );
1348     return *xTableField;
1349 }
1350 
1351 PivotTableFilter& PivotTable::createTableFilter()
1352 {
1353     PivotTableFilterVector::value_type xTableFilter( new PivotTableFilter( *this ) );
1354     maFilters.push_back( xTableFilter );
1355     return *xTableFilter;
1356 }
1357 
1358 void PivotTable::finalizeImport()
1359 {
1360     if( getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) )
1361     {
1362         mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId );
1363         if( mpPivotCache && mpPivotCache->isValidDataSource() && (maDefModel.maName.getLength() > 0) )
1364         {
1365             // clear destination area of the original pivot table
1366             try
1367             {
1368                 Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW );
1369                 using namespace ::com::sun::star::sheet::CellFlags;
1370                 xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED );
1371             }
1372             catch( Exception& )
1373             {
1374             }
1375 
1376             try
1377             {
1378                 // create a new data pilot descriptor based on the source data
1379                 Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.Sheet ), UNO_QUERY_THROW );
1380                 Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW );
1381                 mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW );
1382                 mxDPDescriptor->setSourceRange( mpPivotCache->getSourceRange() );
1383                 mxDPDescriptor->setTag( maDefModel.maTag );
1384 
1385                 // global data pilot properties
1386                 PropertySet aDescProp( mxDPDescriptor );
1387                 aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals );
1388                 aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals );
1389                 aDescProp.setProperty( PROP_ShowFilterButton, false );
1390                 aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill );
1391 
1392                 // finalize all fields, this finds field names and creates grouping fields
1393                 maFields.forEachMem( &PivotTableField::finalizeImport, ::boost::cref( mxDPDescriptor ) );
1394 
1395                 // all row fields
1396                 for( IndexVector::iterator aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
1397                     if( PivotTableField* pField = getTableField( *aIt ) )
1398                         pField->convertRowField();
1399 
1400                 // all column fields
1401                 for( IndexVector::iterator aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt )
1402                     if( PivotTableField* pField = getTableField( *aIt ) )
1403                         pField->convertColField();
1404 
1405                 // all page fields
1406                 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
1407                     if( PivotTableField* pField = getTableField( aIt->mnField ) )
1408                         pField->convertPageField( *aIt );
1409 
1410                 // all hidden fields
1411                 ::std::set< sal_Int32 > aVisFields;
1412                 aVisFields.insert( maRowFields.begin(), maRowFields.end() );
1413                 aVisFields.insert( maColFields.begin(), maColFields.end() );
1414                 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
1415                     aVisFields.insert( aIt->mnField );
1416                 for( PivotTableFieldVector::iterator aBeg = maFields.begin(), aIt = aBeg, aEnd = maFields.end(); aIt != aEnd; ++aIt )
1417                     if( aVisFields.count( static_cast< sal_Int32 >( aIt - aBeg ) ) == 0 )
1418                         (*aIt)->convertHiddenField();
1419 
1420                 // all data fields
1421                 for( DataFieldVector::iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
1422                     if( PivotTableField* pField = getTableField( aIt->mnField ) )
1423                         pField->convertDataField( *aIt );
1424 
1425                 // filters
1426                 maFilters.forEachMem( &PivotTableFilter::finalizeImport );
1427 
1428                 // calculate base position of table
1429                 CellAddress aPos( maLocationModel.maRange.Sheet, maLocationModel.maRange.StartColumn, maLocationModel.maRange.StartRow );
1430                 /*  If page fields exist, include them into the destination
1431                     area (they are excluded in Excel). Add an extra blank row. */
1432                 if( !maPageFields.empty() )
1433                     aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 );
1434 
1435                 // insert the DataPilot table into the sheet
1436                 xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
1437             }
1438             catch( Exception& )
1439             {
1440                 OSL_ENSURE( false, "PivotTable::finalizeImport - exception while creating the DataPilot table" );
1441             }
1442         }
1443     }
1444 }
1445 
1446 void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
1447 {
1448     // process all fields, there is no chaining information in the cache fields
1449     maFields.forEachMem( &PivotTableField::finalizeDateGroupingImport, ::boost::cref( rxBaseDPField ), nBaseFieldIdx );
1450 }
1451 
1452 void PivotTable::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField,
1453         const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
1454 {
1455     // try to create parent group fields that group the items of the passed base field
1456     if( PivotTableField* pParentTableField = maFields.get( rBaseCacheField.getParentGroupField() ).get() )
1457         pParentTableField->finalizeParentGroupingImport( rxBaseDPField, orItemNames );
1458 }
1459 
1460 Reference< XDataPilotField > PivotTable::getDataPilotField( const OUString& rFieldName ) const
1461 {
1462     Reference< XDataPilotField > xDPField;
1463     if( (rFieldName.getLength() > 0) && mxDPDescriptor.is() ) try
1464     {
1465         Reference< XNameAccess > xDPFieldsNA( mxDPDescriptor->getDataPilotFields(), UNO_QUERY_THROW );
1466         xDPField.set( xDPFieldsNA->getByName( rFieldName ), UNO_QUERY );
1467     }
1468     catch( Exception& )
1469     {
1470     }
1471     return xDPField;
1472 }
1473 
1474 Reference< XDataPilotField > PivotTable::getDataPilotField( sal_Int32 nFieldIdx ) const
1475 {
1476     Reference< XDataPilotField > xDPField;
1477     if( const PivotTableField* pTableField = maFields.get( nFieldIdx ).get() )
1478         xDPField = getDataPilotField( pTableField->getDPFieldName() );
1479     return xDPField;
1480 }
1481 
1482 Reference< XDataPilotField > PivotTable::getDataLayoutField() const
1483 {
1484     Reference< XDataPilotField > xDPField;
1485     try
1486     {
1487         Reference< XDataPilotDataLayoutFieldSupplier > xDPDataFieldSupp( mxDPDescriptor, UNO_QUERY_THROW );
1488         xDPField = xDPDataFieldSupp->getDataLayoutField();
1489     }
1490     catch( Exception& )
1491     {
1492     }
1493     return xDPField;
1494 }
1495 
1496 const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const
1497 {
1498     return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : 0;
1499 }
1500 
1501 const PivotCacheField* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const
1502 {
1503     const PTDataFieldModel* pDataField = ContainerHelper::getVectorElement( maDataFields, nDataItemIdx );
1504     return pDataField ? getCacheField( pDataField->mnField ) : 0;
1505 }
1506 
1507 sal_Int32 PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
1508 {
1509     return mpPivotCache ? mpPivotCache->getCacheDatabaseIndex( nFieldIdx ) : -1;
1510 }
1511 
1512 // private --------------------------------------------------------------------
1513 
1514 PivotTableField* PivotTable::getTableField( sal_Int32 nFieldIdx )
1515 {
1516     return (nFieldIdx == OOX_PT_DATALAYOUTFIELD) ? &maDataField : maFields.get( nFieldIdx ).get();
1517 }
1518 
1519 void PivotTable::importField( IndexVector& orFields, const AttributeList& rAttribs )
1520 {
1521     orFields.push_back( rAttribs.getInteger( XML_x, -1 ) );
1522 }
1523 
1524 void PivotTable::importFields( IndexVector& orFields, SequenceInputStream& rStrm )
1525 {
1526     OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
1527     orFields.clear();
1528     sal_Int32 nCount = rStrm.readInt32();
1529     OSL_ENSURE( 4 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
1530     nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 4 );
1531     for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
1532         orFields.push_back( rStrm.readInt32() );
1533 }
1534 
1535 void PivotTable::importFields( IndexVector& orFields, BiffInputStream& rStrm, sal_Int32 nCount )
1536 {
1537     OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
1538     orFields.clear();
1539     OSL_ENSURE( 2 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
1540     nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 2 );
1541     for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
1542         orFields.push_back( rStrm.readInt16() );
1543 }
1544 
1545 // ============================================================================
1546 
1547 PivotTableBuffer::PivotTableBuffer( const WorkbookHelper& rHelper ) :
1548     WorkbookHelper( rHelper )
1549 {
1550 }
1551 
1552 PivotTable& PivotTableBuffer::createPivotTable()
1553 {
1554     PivotTableVector::value_type xTable( new PivotTable( *this ) );
1555     maTables.push_back( xTable );
1556     return *xTable;
1557 }
1558 
1559 void PivotTableBuffer::finalizeImport()
1560 {
1561     maTables.forEachMem( &PivotTable::finalizeImport );
1562 }
1563 
1564 // ============================================================================
1565 
1566 } // namespace xls
1567 } // namespace oox
1568