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