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