Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "pivotcachebuffer.hxx"
30 : :
31 : : #include <set>
32 : : #include <com/sun/star/container/XIndexAccess.hpp>
33 : : #include <com/sun/star/container/XNameAccess.hpp>
34 : : #include <com/sun/star/container/XNamed.hpp>
35 : : #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
36 : : #include <com/sun/star/sheet/DataPilotFieldGroupInfo.hpp>
37 : : #include <com/sun/star/sheet/XDataPilotFieldGrouping.hpp>
38 : : #include <rtl/ustrbuf.hxx>
39 : : #include "oox/core/filterbase.hxx"
40 : : #include "oox/helper/attributelist.hxx"
41 : : #include "oox/helper/containerhelper.hxx"
42 : : #include "oox/helper/propertyset.hxx"
43 : : #include "oox/token/properties.hxx"
44 : : #include "biffinputstream.hxx"
45 : : #include "defnamesbuffer.hxx"
46 : : #include "excelhandlers.hxx"
47 : : #include "pivotcachefragment.hxx"
48 : : #include "sheetdatabuffer.hxx"
49 : : #include "tablebuffer.hxx"
50 : : #include "unitconverter.hxx"
51 : : #include "worksheetbuffer.hxx"
52 : :
53 : : namespace oox {
54 : : namespace xls {
55 : :
56 : : // ============================================================================
57 : :
58 : : using namespace ::com::sun::star::container;
59 : : using namespace ::com::sun::star::sheet;
60 : : using namespace ::com::sun::star::table;
61 : : using namespace ::com::sun::star::uno;
62 : : using namespace ::com::sun::star::util;
63 : :
64 : : using ::oox::core::Relations;
65 : : using ::rtl::OUString;
66 : : using ::rtl::OUStringBuffer;
67 : :
68 : : // ============================================================================
69 : :
70 : : namespace {
71 : :
72 : : const sal_uInt16 BIFF12_PCDFIELD_SERVERFIELD = 0x0001;
73 : : const sal_uInt16 BIFF12_PCDFIELD_NOUNIQUEITEMS = 0x0002;
74 : : const sal_uInt16 BIFF12_PCDFIELD_DATABASEFIELD = 0x0004;
75 : : const sal_uInt16 BIFF12_PCDFIELD_HASCAPTION = 0x0008;
76 : : const sal_uInt16 BIFF12_PCDFIELD_MEMBERPROPFIELD = 0x0010;
77 : : const sal_uInt16 BIFF12_PCDFIELD_HASFORMULA = 0x0100;
78 : : const sal_uInt16 BIFF12_PCDFIELD_HASPROPERTYNAME = 0x0200;
79 : :
80 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASSEMIMIXED = 0x0001;
81 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASNONDATE = 0x0002;
82 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASDATE = 0x0004;
83 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASSTRING = 0x0008;
84 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASBLANK = 0x0010;
85 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASMIXED = 0x0020;
86 : : const sal_uInt16 BIFF12_PCDFSITEMS_ISNUMERIC = 0x0040;
87 : : const sal_uInt16 BIFF12_PCDFSITEMS_ISINTEGER = 0x0080;
88 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASMINMAX = 0x0100;
89 : : const sal_uInt16 BIFF12_PCDFSITEMS_HASLONGTEXT = 0x0200;
90 : :
91 : : const sal_uInt16 BIFF12_PCITEM_ARRAY_DOUBLE = 0x0001;
92 : : const sal_uInt16 BIFF12_PCITEM_ARRAY_STRING = 0x0002;
93 : : const sal_uInt16 BIFF12_PCITEM_ARRAY_ERROR = 0x0010;
94 : : const sal_uInt16 BIFF12_PCITEM_ARRAY_DATE = 0x0020;
95 : :
96 : : const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOSTART = 0x01;
97 : : const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOEND = 0x02;
98 : : const sal_uInt8 BIFF12_PCDFRANGEPR_DATEGROUP = 0x04;
99 : :
100 : : const sal_uInt8 BIFF12_PCDEFINITION_SAVEDATA = 0x01;
101 : : const sal_uInt8 BIFF12_PCDEFINITION_INVALID = 0x02;
102 : : const sal_uInt8 BIFF12_PCDEFINITION_REFRESHONLOAD = 0x04;
103 : : const sal_uInt8 BIFF12_PCDEFINITION_OPTIMIZEMEMORY = 0x08;
104 : : const sal_uInt8 BIFF12_PCDEFINITION_ENABLEREFRESH = 0x10;
105 : : const sal_uInt8 BIFF12_PCDEFINITION_BACKGROUNDQUERY = 0x20;
106 : : const sal_uInt8 BIFF12_PCDEFINITION_UPGRADEONREFR = 0x40;
107 : : const sal_uInt8 BIFF12_PCDEFINITION_TUPELCACHE = 0x80;
108 : :
109 : : const sal_uInt8 BIFF12_PCDEFINITION_HASUSERNAME = 0x01;
110 : : const sal_uInt8 BIFF12_PCDEFINITION_HASRELID = 0x02;
111 : : const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTSUBQUERY = 0x04;
112 : : const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTDRILL = 0x08;
113 : :
114 : : const sal_uInt8 BIFF12_PCDWBSOURCE_HASRELID = 0x01;
115 : : const sal_uInt8 BIFF12_PCDWBSOURCE_HASSHEET = 0x02;
116 : :
117 : : // ----------------------------------------------------------------------------
118 : :
119 : : const sal_uInt16 BIFF_PCDSOURCE_WORKSHEET = 0x0001;
120 : : const sal_uInt16 BIFF_PCDSOURCE_EXTERNAL = 0x0002;
121 : : const sal_uInt16 BIFF_PCDSOURCE_CONSOLIDATION = 0x0004;
122 : : const sal_uInt16 BIFF_PCDSOURCE_SCENARIO = 0x0010;
123 : :
124 : : const sal_uInt16 BIFF_PC_NOSTRING = 0xFFFF;
125 : :
126 : : const sal_uInt16 BIFF_PCDFIELD_HASITEMS = 0x0001;
127 : : const sal_uInt16 BIFF_PCDFIELD_HASUNSHAREDITEMS = 0x0002;
128 : : const sal_uInt16 BIFF_PCDFIELD_CALCULATED = 0x0004;
129 : : const sal_uInt16 BIFF_PCDFIELD_HASPARENT = 0x0008;
130 : : const sal_uInt16 BIFF_PCDFIELD_RANGEGROUP = 0x0010;
131 : : const sal_uInt16 BIFF_PCDFIELD_ISNUMERIC = 0x0020;
132 : : const sal_uInt16 BIFF_PCDFIELD_HASSEMIMIXED = 0x0080;
133 : : const sal_uInt16 BIFF_PCDFIELD_HASMINMAX = 0x0100;
134 : : const sal_uInt16 BIFF_PCDFIELD_HASLONGINDEX = 0x0200;
135 : : const sal_uInt16 BIFF_PCDFIELD_HASNONDATE = 0x0400;
136 : : const sal_uInt16 BIFF_PCDFIELD_HASDATE = 0x0800;
137 : : const sal_uInt16 BIFF_PCDFIELD_SERVERFIELD = 0x2000;
138 : : const sal_uInt16 BIFF_PCDFIELD_NOUNIQUEITEMS = 0x4000;
139 : :
140 : : const sal_uInt16 BIFF_PCDFRANGEPR_AUTOSTART = 0x0001;
141 : : const sal_uInt16 BIFF_PCDFRANGEPR_AUTOEND = 0x0002;
142 : :
143 : : const sal_uInt16 BIFF_PCDEFINITION_SAVEDATA = 0x0001;
144 : : const sal_uInt16 BIFF_PCDEFINITION_INVALID = 0x0002;
145 : : const sal_uInt16 BIFF_PCDEFINITION_REFRESHONLOAD = 0x0004;
146 : : const sal_uInt16 BIFF_PCDEFINITION_OPTIMIZEMEMORY = 0x0008;
147 : : const sal_uInt16 BIFF_PCDEFINITION_BACKGROUNDQUERY = 0x0010;
148 : : const sal_uInt16 BIFF_PCDEFINITION_ENABLEREFRESH = 0x0020;
149 : :
150 : : // ----------------------------------------------------------------------------
151 : :
152 : : /** Adjusts the weird date format read from binary streams.
153 : :
154 : : Dates before 1900-Mar-01 are stored including the non-existing leap day
155 : : 1900-02-29. Time values (without date) are stored as times of day
156 : : 1900-Jan-00. Nothing has to be done when the workbook is stored in 1904
157 : : date mode (dates before 1904-Jan-01 will not occur in this case).
158 : : */
159 : 0 : void lclAdjustBinDateTime( DateTime& orDateTime )
160 : : {
161 [ # # ][ # # ]: 0 : if( (orDateTime.Year == 1900) && (orDateTime.Month <= 2) )
162 : : {
163 : : OSL_ENSURE( (orDateTime.Month == 1) || ((orDateTime.Month == 2) && (orDateTime.Day > 0)), "lclAdjustBinDateTime - invalid date" );
164 [ # # # ]: 0 : switch( orDateTime.Month )
165 : : {
166 [ # # ]: 0 : case 2: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; --orDateTime.Month; } break;
167 [ # # ]: 0 : case 1: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; orDateTime.Month = 12; --orDateTime.Year; } break;
168 : : }
169 : : }
170 : 0 : }
171 : :
172 : : } // namespace
173 : :
174 : : // ============================================================================
175 : :
176 : 0 : PivotCacheItem::PivotCacheItem() :
177 : 0 : mnType( XML_m ), mbUnused( false )
178 : : {
179 : 0 : }
180 : :
181 : 0 : void PivotCacheItem::readString( const AttributeList& rAttribs )
182 : : {
183 [ # # ][ # # ]: 0 : maValue <<= rAttribs.getXString( XML_v, OUString() );
184 : 0 : mnType = XML_s;
185 : 0 : }
186 : :
187 : 0 : void PivotCacheItem::readNumeric( const AttributeList& rAttribs )
188 : : {
189 [ # # ]: 0 : maValue <<= rAttribs.getDouble( XML_v, 0.0 );
190 : 0 : mnType = XML_n;
191 : 0 : mbUnused = rAttribs.getBool( XML_u, false );
192 : 0 : }
193 : :
194 : 0 : void PivotCacheItem::readDate( const AttributeList& rAttribs )
195 : : {
196 [ # # ][ # # ]: 0 : maValue <<= rAttribs.getDateTime( XML_v, DateTime() );
197 : 0 : mnType = XML_d;
198 : 0 : }
199 : :
200 : 0 : void PivotCacheItem::readBool( const AttributeList& rAttribs )
201 : : {
202 [ # # ]: 0 : maValue <<= rAttribs.getBool( XML_v, false );
203 : 0 : mnType = XML_b;
204 : 0 : }
205 : :
206 : 0 : void PivotCacheItem::readError( const AttributeList& rAttribs, const UnitConverter& rUnitConverter )
207 : : {
208 [ # # ][ # # ]: 0 : maValue <<= static_cast< sal_Int32 >( rUnitConverter.calcBiffErrorCode( rAttribs.getXString( XML_v, OUString() ) ) );
[ # # ]
209 : 0 : mnType = XML_e;
210 : 0 : }
211 : :
212 : 0 : void PivotCacheItem::readIndex( const AttributeList& rAttribs )
213 : : {
214 [ # # ]: 0 : maValue <<= rAttribs.getInteger( XML_v, -1 );
215 : 0 : mnType = XML_x;
216 : 0 : }
217 : :
218 : 0 : void PivotCacheItem::readString( SequenceInputStream& rStrm )
219 : : {
220 [ # # ]: 0 : maValue <<= BiffHelper::readString( rStrm );
221 : 0 : mnType = XML_s;
222 : 0 : }
223 : :
224 : 0 : void PivotCacheItem::readDouble( SequenceInputStream& rStrm )
225 : : {
226 [ # # ]: 0 : maValue <<= rStrm.readDouble();
227 : 0 : mnType = XML_n;
228 : 0 : }
229 : :
230 : 0 : void PivotCacheItem::readDate( SequenceInputStream& rStrm )
231 : : {
232 : 0 : DateTime aDateTime;
233 [ # # ]: 0 : aDateTime.Year = rStrm.readuInt16();
234 [ # # ]: 0 : aDateTime.Month = rStrm.readuInt16();
235 [ # # ]: 0 : aDateTime.Day = rStrm.readuInt8();
236 [ # # ]: 0 : aDateTime.Hours = rStrm.readuInt8();
237 [ # # ]: 0 : aDateTime.Minutes = rStrm.readuInt8();
238 [ # # ]: 0 : aDateTime.Seconds = rStrm.readuInt8();
239 : 0 : lclAdjustBinDateTime( aDateTime );
240 [ # # ]: 0 : maValue <<= aDateTime;
241 : 0 : mnType = XML_d;
242 : 0 : }
243 : :
244 : 0 : void PivotCacheItem::readBool( SequenceInputStream& rStrm )
245 : : {
246 [ # # ]: 0 : maValue <<= (rStrm.readuInt8() != 0);
247 : 0 : mnType = XML_b;
248 : 0 : }
249 : :
250 : 0 : void PivotCacheItem::readError( SequenceInputStream& rStrm )
251 : : {
252 [ # # ]: 0 : maValue <<= static_cast< sal_Int32 >( rStrm.readuInt8() );
253 : 0 : mnType = XML_e;
254 : 0 : }
255 : :
256 : 0 : void PivotCacheItem::readIndex( SequenceInputStream& rStrm )
257 : : {
258 [ # # ]: 0 : maValue <<= rStrm.readInt32();
259 : 0 : mnType = XML_x;
260 : 0 : }
261 : :
262 : 0 : void PivotCacheItem::readString( BiffInputStream& rStrm, const WorkbookHelper& rHelper )
263 : : {
264 [ # # ][ # # ]: 0 : maValue <<= (rHelper.getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( true, rHelper.getTextEncoding() );
265 : 0 : mnType = XML_s;
266 : 0 : }
267 : :
268 : 0 : void PivotCacheItem::readDouble( BiffInputStream& rStrm )
269 : : {
270 [ # # ]: 0 : maValue <<= rStrm.readDouble();
271 : 0 : mnType = XML_n;
272 : 0 : }
273 : :
274 : 0 : void PivotCacheItem::readInteger( BiffInputStream& rStrm )
275 : : {
276 [ # # ]: 0 : maValue <<= rStrm.readInt16();
277 : 0 : mnType = XML_i; // fake, used for BIFF only
278 : 0 : }
279 : :
280 : 0 : void PivotCacheItem::readDate( BiffInputStream& rStrm )
281 : : {
282 : 0 : DateTime aDateTime;
283 [ # # ]: 0 : aDateTime.Year = rStrm.readuInt16();
284 [ # # ]: 0 : aDateTime.Month = rStrm.readuInt16();
285 [ # # ]: 0 : aDateTime.Day = rStrm.readuInt8();
286 [ # # ]: 0 : aDateTime.Hours = rStrm.readuInt8();
287 [ # # ]: 0 : aDateTime.Minutes = rStrm.readuInt8();
288 [ # # ]: 0 : aDateTime.Seconds = rStrm.readuInt8();
289 : 0 : lclAdjustBinDateTime( aDateTime );
290 [ # # ]: 0 : maValue <<= aDateTime;
291 : 0 : mnType = XML_d;
292 : 0 : }
293 : :
294 : 0 : void PivotCacheItem::readBool( BiffInputStream& rStrm )
295 : : {
296 [ # # ]: 0 : maValue <<= (rStrm.readuInt8() != 0);
297 : 0 : mnType = XML_b;
298 : 0 : }
299 : :
300 : 0 : void PivotCacheItem::readError( BiffInputStream& rStrm )
301 : : {
302 [ # # ]: 0 : maValue <<= static_cast< sal_Int32 >( rStrm.readuInt8() );
303 : 0 : mnType = XML_e;
304 : 0 : }
305 : :
306 : 0 : void PivotCacheItem::setStringValue( const OUString& sString )
307 : : {
308 : 0 : mnType = XML_s;
309 : 0 : maValue <<= sString;
310 : 0 : }
311 : :
312 : 0 : OUString PivotCacheItem::getName() const
313 : : {
314 [ # # # # : 0 : switch( mnType )
# # # # ]
315 : : {
316 : 0 : case XML_m: return OUString();
317 : 0 : case XML_s: return maValue.get< OUString >();
318 : 0 : case XML_n: return OUString::valueOf( maValue.get< double >() ); // !TODO
319 : 0 : case XML_i: return OUString::valueOf( maValue.get< sal_Int32 >() );
320 : 0 : case XML_d: return OUString(); // !TODO
321 : 0 : case XML_b: return OUString::valueOf( static_cast< sal_Bool >( maValue.get< bool >() ) ); // !TODO
322 : 0 : case XML_e: return OUString(); // !TODO
323 : : }
324 : : OSL_FAIL( "PivotCacheItem::getName - invalid data type" );
325 : 0 : return OUString();
326 : : }
327 : :
328 : : // ----------------------------------------------------------------------------
329 : :
330 : 0 : PivotCacheItemList::PivotCacheItemList( const WorkbookHelper& rHelper ) :
331 [ # # ]: 0 : WorkbookHelper( rHelper )
332 : : {
333 : 0 : }
334 : :
335 : 0 : void PivotCacheItemList::importItem( sal_Int32 nElement, const AttributeList& rAttribs )
336 : : {
337 : 0 : PivotCacheItem& rItem = createItem();
338 [ # # # # : 0 : switch( nElement )
# # # ]
339 : : {
340 : 0 : case XLS_TOKEN( m ): break;
341 : 0 : case XLS_TOKEN( s ): rItem.readString( rAttribs ); break;
342 : 0 : case XLS_TOKEN( n ): rItem.readNumeric( rAttribs ); break;
343 : 0 : case XLS_TOKEN( d ): rItem.readDate( rAttribs ); break;
344 : 0 : case XLS_TOKEN( b ): rItem.readBool( rAttribs ); break;
345 : 0 : case XLS_TOKEN( e ): rItem.readError( rAttribs, getUnitConverter() ); break;
346 : : default: OSL_FAIL( "PivotCacheItemList::importItem - unknown element type" );
347 : : }
348 : 0 : }
349 : :
350 : 0 : void PivotCacheItemList::importItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
351 : : {
352 [ # # ]: 0 : if( nRecId == BIFF12_ID_PCITEM_ARRAY )
353 : : {
354 : 0 : importArray( rStrm );
355 : 0 : return;
356 : : }
357 : :
358 : 0 : PivotCacheItem& rItem = createItem();
359 [ # # # # : 0 : switch( nRecId )
# # # ]
360 : : {
361 : : case BIFF12_ID_PCITEM_MISSING:
362 : 0 : case BIFF12_ID_PCITEMA_MISSING: break;
363 : : case BIFF12_ID_PCITEM_STRING:
364 : 0 : case BIFF12_ID_PCITEMA_STRING: rItem.readString( rStrm ); break;
365 : : case BIFF12_ID_PCITEM_DOUBLE:
366 : 0 : case BIFF12_ID_PCITEMA_DOUBLE: rItem.readDouble( rStrm ); break;
367 : : case BIFF12_ID_PCITEM_DATE:
368 : 0 : case BIFF12_ID_PCITEMA_DATE: rItem.readDate( rStrm ); break;
369 : : case BIFF12_ID_PCITEM_BOOL:
370 : 0 : case BIFF12_ID_PCITEMA_BOOL: rItem.readBool( rStrm ); break;
371 : : case BIFF12_ID_PCITEM_ERROR:
372 : 0 : case BIFF12_ID_PCITEMA_ERROR: rItem.readError( rStrm ); break;
373 : : default: OSL_FAIL( "PivotCacheItemList::importItem - unknown record type" );
374 : : }
375 : : }
376 : :
377 : 0 : void PivotCacheItemList::importItemList( BiffInputStream& rStrm, sal_uInt16 nCount )
378 : : {
379 : 0 : bool bLoop = true;
380 [ # # ][ # # ]: 0 : for( sal_uInt16 nItemIdx = 0; bLoop && (nItemIdx < nCount); ++nItemIdx )
[ # # ]
381 : : {
382 : 0 : bLoop = rStrm.startNextRecord();
383 [ # # # # : 0 : if( bLoop ) switch( rStrm.getRecId() )
# # # # ]
[ # # ]
384 : : {
385 : 0 : case BIFF_ID_PCITEM_MISSING: createItem(); break;
386 : 0 : case BIFF_ID_PCITEM_STRING: createItem().readString( rStrm, *this ); break;
387 : 0 : case BIFF_ID_PCITEM_DOUBLE: createItem().readDouble( rStrm ); break;
388 : 0 : case BIFF_ID_PCITEM_INTEGER: createItem().readInteger( rStrm ); break;
389 : 0 : case BIFF_ID_PCITEM_DATE: createItem().readDate( rStrm ); break;
390 : 0 : case BIFF_ID_PCITEM_BOOL: createItem().readBool( rStrm ); break;
391 : 0 : case BIFF_ID_PCITEM_ERROR: createItem().readError( rStrm ); break;
392 : 0 : default: rStrm.rewindRecord(); bLoop = false;
393 : : }
394 : : }
395 : : OSL_ENSURE( bLoop, "PivotCacheItemList::importItemList - could not read all cache item records" );
396 : 0 : }
397 : :
398 : 0 : const PivotCacheItem* PivotCacheItemList::getCacheItem( sal_Int32 nItemIdx ) const
399 : : {
400 : 0 : return ContainerHelper::getVectorElement( maItems, nItemIdx );
401 : : }
402 : :
403 : 0 : void PivotCacheItemList::applyItemCaptions( const IdCaptionPairList& vCaptions )
404 : : {
405 [ # # ][ # # ]: 0 : for( IdCaptionPairList::const_iterator aIt = vCaptions.begin(), aEnd = vCaptions.end(); aIt != aEnd; ++aIt )
406 : : {
407 [ # # ]: 0 : if ( static_cast<sal_uInt32>( aIt->first ) < maItems.size() )
408 [ # # ]: 0 : maItems[ aIt->first ].setStringValue( aIt->second );
409 : : }
410 : 0 : }
411 : :
412 : 0 : void PivotCacheItemList::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
413 : : {
414 : 0 : orItemNames.clear();
415 : 0 : orItemNames.reserve( maItems.size() );
416 [ # # ][ # # ]: 0 : for( CacheItemVector::const_iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
417 [ # # ][ # # ]: 0 : orItemNames.push_back( aIt->getName() );
418 : 0 : }
419 : :
420 : : // private --------------------------------------------------------------------
421 : :
422 : 0 : PivotCacheItem& PivotCacheItemList::createItem()
423 : : {
424 : 0 : maItems.resize( maItems.size() + 1 );
425 : 0 : return maItems.back();
426 : : }
427 : :
428 : 0 : void PivotCacheItemList::importArray( SequenceInputStream& rStrm )
429 : : {
430 : 0 : sal_uInt16 nType = rStrm.readuInt16();
431 : 0 : sal_Int32 nCount = rStrm.readInt32();
432 [ # # ][ # # ]: 0 : for( sal_Int32 nIdx = 0; !rStrm.isEof() && (nIdx < nCount); ++nIdx )
[ # # ]
433 : : {
434 [ # # # # : 0 : switch( nType )
# ]
435 : : {
436 : 0 : case BIFF12_PCITEM_ARRAY_DOUBLE: createItem().readDouble( rStrm ); break;
437 : 0 : case BIFF12_PCITEM_ARRAY_STRING: createItem().readString( rStrm ); break;
438 : 0 : case BIFF12_PCITEM_ARRAY_ERROR: createItem().readError( rStrm ); break;
439 : 0 : case BIFF12_PCITEM_ARRAY_DATE: createItem().readDate( rStrm ); break;
440 : : default:
441 : : OSL_FAIL( "PivotCacheItemList::importArray - unknown data type" );
442 : 0 : nIdx = nCount;
443 : : }
444 : : }
445 : 0 : }
446 : :
447 : : // ============================================================================
448 : :
449 : 0 : PCFieldModel::PCFieldModel() :
450 : : mnNumFmtId( 0 ),
451 : : mnSqlType( 0 ),
452 : : mnHierarchy( 0 ),
453 : : mnLevel( 0 ),
454 : : mnMappingCount( 0 ),
455 : : mbDatabaseField( true ),
456 : : mbServerField( false ),
457 : : mbUniqueList( true ),
458 : 0 : mbMemberPropField( false )
459 : : {
460 : 0 : }
461 : :
462 : : // ----------------------------------------------------------------------------
463 : :
464 : 0 : PCSharedItemsModel::PCSharedItemsModel() :
465 : : mbHasSemiMixed( true ),
466 : : mbHasNonDate( true ),
467 : : mbHasDate( false ),
468 : : mbHasString( true ),
469 : : mbHasBlank( false ),
470 : : mbHasMixed( false ),
471 : : mbIsNumeric( false ),
472 : : mbIsInteger( false ),
473 : : mbHasLongText( false ),
474 : 0 : mbHasLongIndexes( false )
475 : : {
476 : 0 : }
477 : :
478 : : // ----------------------------------------------------------------------------
479 : :
480 : 0 : PCFieldGroupModel::PCFieldGroupModel() :
481 : : mfStartValue( 0.0 ),
482 : : mfEndValue( 0.0 ),
483 : : mfInterval( 1.0 ),
484 : : mnParentField( -1 ),
485 : : mnBaseField( -1 ),
486 : : mnGroupBy( XML_range ),
487 : : mbRangeGroup( false ),
488 : : mbDateGroup( false ),
489 : : mbAutoStart( true ),
490 : 0 : mbAutoEnd( true )
491 : : {
492 : 0 : }
493 : :
494 : 0 : void PCFieldGroupModel::setBiffGroupBy( sal_uInt8 nGroupBy )
495 : : {
496 : : static const sal_Int32 spnGroupBy[] = { XML_range,
497 : : XML_seconds, XML_minutes, XML_hours, XML_days, XML_months, XML_quarters, XML_years };
498 [ # # ]: 0 : mnGroupBy = STATIC_ARRAY_SELECT( spnGroupBy, nGroupBy, XML_range );
499 : 0 : }
500 : :
501 : : // ----------------------------------------------------------------------------
502 : :
503 : 0 : PivotCacheField::PivotCacheField( const WorkbookHelper& rHelper, bool bIsDatabaseField ) :
504 : : WorkbookHelper( rHelper ),
505 : : maSharedItems( rHelper ),
506 [ # # ][ # # ]: 0 : maGroupItems( rHelper )
[ # # ]
507 : : {
508 : 0 : maFieldModel.mbDatabaseField = bIsDatabaseField;
509 : 0 : }
510 : :
511 : 0 : void PivotCacheField::importCacheField( const AttributeList& rAttribs )
512 : : {
513 [ # # ]: 0 : maFieldModel.maName = rAttribs.getXString( XML_name, OUString() );
514 [ # # ]: 0 : maFieldModel.maCaption = rAttribs.getXString( XML_caption, OUString() );
515 [ # # ]: 0 : maFieldModel.maPropertyName = rAttribs.getXString( XML_propertyName, OUString() );
516 [ # # ]: 0 : maFieldModel.maFormula = rAttribs.getXString( XML_formula, OUString() );
517 : 0 : maFieldModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
518 : 0 : maFieldModel.mnSqlType = rAttribs.getInteger( XML_sqlType, 0 );
519 : 0 : maFieldModel.mnHierarchy = rAttribs.getInteger( XML_hierarchy, 0 );
520 : 0 : maFieldModel.mnLevel = rAttribs.getInteger( XML_level, 0 );
521 : 0 : maFieldModel.mnMappingCount = rAttribs.getInteger( XML_mappingCount, 0 );
522 : 0 : maFieldModel.mbDatabaseField = rAttribs.getBool( XML_databaseField, true );
523 : 0 : maFieldModel.mbServerField = rAttribs.getBool( XML_serverField, false );
524 : 0 : maFieldModel.mbUniqueList = rAttribs.getBool( XML_uniqueList, true );
525 : 0 : maFieldModel.mbMemberPropField = rAttribs.getBool( XML_memberPropertyField, false );
526 : 0 : }
527 : :
528 : 0 : void PivotCacheField::importSharedItems( const AttributeList& rAttribs )
529 : : {
530 : : OSL_ENSURE( maSharedItems.empty(), "PivotCacheField::importSharedItems - multiple shared items elements" );
531 : 0 : maSharedItemsModel.mbHasSemiMixed = rAttribs.getBool( XML_containsSemiMixedTypes, true );
532 : 0 : maSharedItemsModel.mbHasNonDate = rAttribs.getBool( XML_containsNonDate, true );
533 : 0 : maSharedItemsModel.mbHasDate = rAttribs.getBool( XML_containsDate, false );
534 : 0 : maSharedItemsModel.mbHasString = rAttribs.getBool( XML_containsString, true );
535 : 0 : maSharedItemsModel.mbHasBlank = rAttribs.getBool( XML_containsBlank, false );
536 : 0 : maSharedItemsModel.mbHasMixed = rAttribs.getBool( XML_containsMixedTypes, false );
537 : 0 : maSharedItemsModel.mbIsNumeric = rAttribs.getBool( XML_containsNumber, false );
538 : 0 : maSharedItemsModel.mbIsInteger = rAttribs.getBool( XML_containsInteger, false );
539 : 0 : maSharedItemsModel.mbHasLongText = rAttribs.getBool( XML_longText, false );
540 : 0 : }
541 : :
542 : 0 : void PivotCacheField::importSharedItem( sal_Int32 nElement, const AttributeList& rAttribs )
543 : : {
544 : 0 : maSharedItems.importItem( nElement, rAttribs );
545 : 0 : }
546 : :
547 : 0 : void PivotCacheField::importFieldGroup( const AttributeList& rAttribs )
548 : : {
549 : 0 : maFieldGroupModel.mnParentField = rAttribs.getInteger( XML_par, -1 );
550 : 0 : maFieldGroupModel.mnBaseField = rAttribs.getInteger( XML_base, -1 );
551 : 0 : }
552 : :
553 : 0 : void PivotCacheField::importRangePr( const AttributeList& rAttribs )
554 : : {
555 [ # # ]: 0 : maFieldGroupModel.maStartDate = rAttribs.getDateTime( XML_startDate, DateTime() );
556 [ # # ]: 0 : maFieldGroupModel.maEndDate = rAttribs.getDateTime( XML_endDate, DateTime() );
557 : 0 : maFieldGroupModel.mfStartValue = rAttribs.getDouble( XML_startNum, 0.0 );
558 : 0 : maFieldGroupModel.mfEndValue = rAttribs.getDouble( XML_endNum, 0.0 );
559 : 0 : maFieldGroupModel.mfInterval = rAttribs.getDouble( XML_groupInterval, 1.0 );
560 : 0 : maFieldGroupModel.mnGroupBy = rAttribs.getToken( XML_groupBy, XML_range );
561 : 0 : maFieldGroupModel.mbRangeGroup = true;
562 : 0 : maFieldGroupModel.mbDateGroup = maFieldGroupModel.mnGroupBy != XML_range;
563 : 0 : maFieldGroupModel.mbAutoStart = rAttribs.getBool( XML_autoStart, true );
564 : 0 : maFieldGroupModel.mbAutoEnd = rAttribs.getBool( XML_autoEnd, true );
565 : 0 : }
566 : :
567 : 0 : void PivotCacheField::importDiscretePrItem( sal_Int32 nElement, const AttributeList& rAttribs )
568 : : {
569 : : OSL_ENSURE( nElement == XLS_TOKEN( x ), "PivotCacheField::importDiscretePrItem - unexpected element" );
570 [ # # ]: 0 : if( nElement == XLS_TOKEN( x ) )
571 [ # # ]: 0 : maDiscreteItems.push_back( rAttribs.getInteger( XML_v, -1 ) );
572 : 0 : }
573 : :
574 : 0 : void PivotCacheField::importGroupItem( sal_Int32 nElement, const AttributeList& rAttribs )
575 : : {
576 : 0 : maGroupItems.importItem( nElement, rAttribs );
577 : 0 : }
578 : :
579 : 0 : void PivotCacheField::importPCDField( SequenceInputStream& rStrm )
580 : : {
581 : : sal_uInt16 nFlags;
582 [ # # ][ # # ]: 0 : rStrm >> nFlags >> maFieldModel.mnNumFmtId;
583 [ # # ]: 0 : maFieldModel.mnSqlType = rStrm.readInt16();
584 [ # # ][ # # ]: 0 : rStrm >> maFieldModel.mnHierarchy >> maFieldModel.mnLevel >> maFieldModel.mnMappingCount >> maFieldModel.maName;
[ # # ][ # # ]
585 [ # # ]: 0 : if( getFlag( nFlags, BIFF12_PCDFIELD_HASCAPTION ) )
586 [ # # ]: 0 : rStrm >> maFieldModel.maCaption;
587 [ # # ]: 0 : if( getFlag( nFlags, BIFF12_PCDFIELD_HASFORMULA ) )
588 [ # # ][ # # ]: 0 : rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
[ # # ]
589 [ # # ]: 0 : if( maFieldModel.mnMappingCount > 0 )
590 [ # # ][ # # ]: 0 : rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
[ # # ]
591 [ # # ]: 0 : if( getFlag( nFlags, BIFF12_PCDFIELD_HASPROPERTYNAME ) )
592 [ # # ]: 0 : rStrm >> maFieldModel.maPropertyName;
593 : :
594 : 0 : maFieldModel.mbDatabaseField = getFlag( nFlags, BIFF12_PCDFIELD_DATABASEFIELD );
595 : 0 : maFieldModel.mbServerField = getFlag( nFlags, BIFF12_PCDFIELD_SERVERFIELD );
596 : 0 : maFieldModel.mbUniqueList = !getFlag( nFlags, BIFF12_PCDFIELD_NOUNIQUEITEMS );
597 : 0 : maFieldModel.mbMemberPropField = getFlag( nFlags, BIFF12_PCDFIELD_MEMBERPROPFIELD );
598 : 0 : }
599 : :
600 : 0 : void PivotCacheField::importPCDFSharedItems( SequenceInputStream& rStrm )
601 : : {
602 : : sal_uInt16 nFlags;
603 [ # # ]: 0 : rStrm >> nFlags;
604 : 0 : maSharedItemsModel.mbHasSemiMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSEMIMIXED );
605 : 0 : maSharedItemsModel.mbHasNonDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASNONDATE );
606 : 0 : maSharedItemsModel.mbHasDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASDATE );
607 : 0 : maSharedItemsModel.mbHasString = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSTRING );
608 : 0 : maSharedItemsModel.mbHasBlank = getFlag( nFlags, BIFF12_PCDFSITEMS_HASBLANK );
609 : 0 : maSharedItemsModel.mbHasMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASMIXED );
610 : 0 : maSharedItemsModel.mbIsNumeric = getFlag( nFlags, BIFF12_PCDFSITEMS_ISNUMERIC );
611 : 0 : maSharedItemsModel.mbIsInteger = getFlag( nFlags, BIFF12_PCDFSITEMS_ISINTEGER );
612 : 0 : maSharedItemsModel.mbHasLongText = getFlag( nFlags, BIFF12_PCDFSITEMS_HASLONGTEXT );
613 : 0 : }
614 : :
615 : 0 : void PivotCacheField::importPCDFSharedItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
616 : : {
617 : 0 : maSharedItems.importItem( nRecId, rStrm );
618 : 0 : }
619 : :
620 : 0 : void PivotCacheField::importPCDFieldGroup( SequenceInputStream& rStrm )
621 : : {
622 : 0 : rStrm >> maFieldGroupModel.mnParentField >> maFieldGroupModel.mnBaseField;
623 : 0 : }
624 : :
625 : 0 : void PivotCacheField::importPCDFRangePr( SequenceInputStream& rStrm )
626 : : {
627 : : sal_uInt8 nGroupBy, nFlags;
628 [ # # ][ # # ]: 0 : rStrm >> nGroupBy >> nFlags >> maFieldGroupModel.mfStartValue >> maFieldGroupModel.mfEndValue >> maFieldGroupModel.mfInterval;
[ # # ][ # # ]
[ # # ]
629 : :
630 : 0 : maFieldGroupModel.setBiffGroupBy( nGroupBy );
631 : 0 : maFieldGroupModel.mbRangeGroup = true;
632 : 0 : maFieldGroupModel.mbDateGroup = getFlag( nFlags, BIFF12_PCDFRANGEPR_DATEGROUP );
633 : 0 : maFieldGroupModel.mbAutoStart = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOSTART );
634 : 0 : maFieldGroupModel.mbAutoEnd = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOEND );
635 : :
636 : : OSL_ENSURE( maFieldGroupModel.mbDateGroup == (maFieldGroupModel.mnGroupBy != XML_range), "PivotCacheField::importPCDFRangePr - wrong date flag" );
637 [ # # ]: 0 : if( maFieldGroupModel.mbDateGroup )
638 : : {
639 [ # # ][ # # ]: 0 : maFieldGroupModel.maStartDate = getUnitConverter().calcDateTimeFromSerial( maFieldGroupModel.mfStartValue );
640 [ # # ][ # # ]: 0 : maFieldGroupModel.maEndDate = getUnitConverter().calcDateTimeFromSerial( maFieldGroupModel.mfEndValue );
641 : : }
642 : 0 : }
643 : :
644 : 0 : void PivotCacheField::importPCDFDiscretePrItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
645 : : {
646 : : OSL_ENSURE( nRecId == BIFF12_ID_PCITEM_INDEX, "PivotCacheField::importPCDFDiscretePrItem - unexpected record" );
647 [ # # ]: 0 : if( nRecId == BIFF12_ID_PCITEM_INDEX )
648 [ # # ]: 0 : maDiscreteItems.push_back( rStrm.readInt32() );
649 : 0 : }
650 : :
651 : 0 : void PivotCacheField::importPCDFGroupItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
652 : : {
653 : 0 : maGroupItems.importItem( nRecId, rStrm );
654 : 0 : }
655 : :
656 : 0 : void PivotCacheField::importPCDField( BiffInputStream& rStrm )
657 : : {
658 : : sal_uInt16 nFlags, nGroupItems, nBaseItems, nSharedItems;
659 [ # # ]: 0 : rStrm >> nFlags;
660 [ # # ]: 0 : maFieldGroupModel.mnParentField = rStrm.readuInt16();
661 [ # # ]: 0 : maFieldGroupModel.mnBaseField = rStrm.readuInt16();
662 [ # # ]: 0 : rStrm.skip( 2 ); // number of unique items (either shared or group)
663 [ # # ][ # # ]: 0 : rStrm >> nGroupItems >> nBaseItems >> nSharedItems;
[ # # ]
664 [ # # ][ # # ]: 0 : maFieldModel.maName = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( true, getTextEncoding() );
[ # # ][ # # ]
[ # # ]
665 : :
666 : 0 : maFieldModel.mbServerField = getFlag( nFlags, BIFF_PCDFIELD_SERVERFIELD );
667 : 0 : maFieldModel.mbUniqueList = !getFlag( nFlags, BIFF_PCDFIELD_NOUNIQUEITEMS );
668 : 0 : maSharedItemsModel.mbHasSemiMixed = getFlag( nFlags, BIFF_PCDFIELD_HASSEMIMIXED );
669 : 0 : maSharedItemsModel.mbHasNonDate = getFlag( nFlags, BIFF_PCDFIELD_HASNONDATE );
670 : 0 : maSharedItemsModel.mbHasDate = getFlag( nFlags, BIFF_PCDFIELD_HASDATE );
671 : 0 : maSharedItemsModel.mbIsNumeric = getFlag( nFlags, BIFF_PCDFIELD_ISNUMERIC );
672 : 0 : maSharedItemsModel.mbHasLongIndexes = getFlag( nFlags, BIFF_PCDFIELD_HASLONGINDEX );
673 : 0 : maFieldGroupModel.mbRangeGroup = getFlag( nFlags, BIFF_PCDFIELD_RANGEGROUP );
674 : :
675 : : // in BIFF, presence of parent group field is denoted by a flag
676 [ # # ]: 0 : if( !getFlag( nFlags, BIFF_PCDFIELD_HASPARENT ) )
677 : 0 : maFieldGroupModel.mnParentField = -1;
678 : :
679 : : // following PCDFSQLTYPE record contains SQL type
680 [ # # ][ # # ]: 0 : if( (rStrm.getNextRecId() == BIFF_ID_PCDFSQLTYPE) && rStrm.startNextRecord() )
[ # # ][ # # ]
[ # # ]
681 [ # # ]: 0 : maFieldModel.mnSqlType = rStrm.readInt16();
682 : :
683 : : // read group items, if any
684 [ # # ]: 0 : if( nGroupItems > 0 )
685 : : {
686 : : OSL_ENSURE( getFlag( nFlags, BIFF_PCDFIELD_HASITEMS ), "PivotCacheField::importPCDField - missing items flag" );
687 [ # # ]: 0 : maGroupItems.importItemList( rStrm, nGroupItems );
688 : :
689 [ # # ]: 0 : sal_uInt16 nNextRecId = rStrm.getNextRecId();
690 : 0 : bool bHasRangePr = nNextRecId == BIFF_ID_PCDFRANGEPR;
691 : 0 : bool bHasDiscretePr = nNextRecId == BIFF_ID_PCDFDISCRETEPR;
692 : :
693 : : OSL_ENSURE( bHasRangePr || bHasDiscretePr, "PivotCacheField::importPCDField - missing group properties record" );
694 : : OSL_ENSURE( bHasRangePr == maFieldGroupModel.mbRangeGroup, "PivotCacheField::importPCDField - invalid range grouping flag" );
695 [ # # ][ # # ]: 0 : if( bHasRangePr && rStrm.startNextRecord() )
[ # # ][ # # ]
696 [ # # ]: 0 : importPCDFRangePr( rStrm );
697 [ # # ][ # # ]: 0 : else if( bHasDiscretePr && rStrm.startNextRecord() )
[ # # ][ # # ]
698 [ # # ]: 0 : importPCDFDiscretePr( rStrm );
699 : : }
700 : :
701 : : // read the shared items, if any
702 [ # # ]: 0 : if( nSharedItems > 0 )
703 : : {
704 : : OSL_ENSURE( getFlag( nFlags, BIFF_PCDFIELD_HASITEMS ), "PivotCacheField::importPCDField - missing items flag" );
705 [ # # ]: 0 : maSharedItems.importItemList( rStrm, nSharedItems );
706 : : }
707 : 0 : }
708 : :
709 : 0 : void PivotCacheField::importPCDFRangePr( BiffInputStream& rStrm )
710 : : {
711 : : sal_uInt16 nFlags;
712 [ # # ]: 0 : rStrm >> nFlags;
713 : 0 : maFieldGroupModel.setBiffGroupBy( extractValue< sal_uInt8 >( nFlags, 2, 3 ) );
714 : 0 : maFieldGroupModel.mbRangeGroup = true;
715 : 0 : maFieldGroupModel.mbDateGroup = maFieldGroupModel.mnGroupBy != XML_range;
716 : 0 : maFieldGroupModel.mbAutoStart = getFlag( nFlags, BIFF_PCDFRANGEPR_AUTOSTART );
717 : 0 : maFieldGroupModel.mbAutoEnd = getFlag( nFlags, BIFF_PCDFRANGEPR_AUTOEND );
718 : :
719 : : /* Start, end, and interval are stored in 3 separate item records. Type of
720 : : the items is dependent on numeric/date mode. Numeric groups expect
721 : : three PCITEM_DOUBLE records, date groups expect two PCITEM_DATE records
722 : : and one PCITEM_INT record. */
723 [ # # ]: 0 : PivotCacheItemList aLimits( *this );
724 [ # # ]: 0 : aLimits.importItemList( rStrm, 3 );
725 : : OSL_ENSURE( aLimits.size() == 3, "PivotCacheField::importPCDFRangePr - missing grouping records" );
726 [ # # ]: 0 : const PivotCacheItem* pStartValue = aLimits.getCacheItem( 0 );
727 [ # # ]: 0 : const PivotCacheItem* pEndValue = aLimits.getCacheItem( 1 );
728 [ # # ]: 0 : const PivotCacheItem* pInterval = aLimits.getCacheItem( 2 );
729 [ # # ][ # # ]: 0 : if( pStartValue && pEndValue && pInterval )
[ # # ]
730 : : {
731 [ # # ]: 0 : if( maFieldGroupModel.mbDateGroup )
732 : : {
733 [ # # ][ # # ]: 0 : bool bHasTypes = (pStartValue->getType() == XML_d) && (pEndValue->getType() == XML_d) && (pInterval->getType() == XML_i);
[ # # ]
734 : : OSL_ENSURE( bHasTypes, "PivotCacheField::importPCDFRangePr - wrong data types in grouping items" );
735 [ # # ]: 0 : if( bHasTypes )
736 : : {
737 [ # # ]: 0 : maFieldGroupModel.maStartDate = pStartValue->getValue().get< DateTime >();
738 [ # # ]: 0 : maFieldGroupModel.maEndDate = pEndValue->getValue().get< DateTime >();
739 [ # # ]: 0 : maFieldGroupModel.mfInterval = pInterval->getValue().get< sal_Int16 >();
740 : : }
741 : : }
742 : : else
743 : : {
744 [ # # ][ # # ]: 0 : bool bHasTypes = (pStartValue->getType() == XML_n) && (pEndValue->getType() == XML_n) && (pInterval->getType() == XML_n);
[ # # ]
745 : : OSL_ENSURE( bHasTypes, "PivotCacheField::importPCDFRangePr - wrong data types in grouping items" );
746 [ # # ]: 0 : if( bHasTypes )
747 : : {
748 [ # # ]: 0 : maFieldGroupModel.mfStartValue = pStartValue->getValue().get< double >();
749 [ # # ]: 0 : maFieldGroupModel.mfEndValue = pEndValue->getValue().get< double >();
750 [ # # ]: 0 : maFieldGroupModel.mfInterval = pInterval->getValue().get< double >();
751 : : }
752 : : }
753 [ # # ]: 0 : }
754 : 0 : }
755 : :
756 : 0 : void PivotCacheField::importPCDFDiscretePr( BiffInputStream& rStrm )
757 : : {
758 : 0 : sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.size() / 2 );
759 [ # # ][ # # ]: 0 : for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
[ # # ]
760 [ # # ]: 0 : maDiscreteItems.push_back( rStrm.readuInt16() );
761 : 0 : }
762 : :
763 : 0 : const PivotCacheItem* PivotCacheField::getCacheItem( sal_Int32 nItemIdx ) const
764 : : {
765 [ # # ]: 0 : if( hasGroupItems() )
766 : 0 : return maGroupItems.getCacheItem( nItemIdx );
767 [ # # ]: 0 : if( hasSharedItems() )
768 : 0 : return maSharedItems.getCacheItem( nItemIdx );
769 : 0 : return 0;
770 : : }
771 : :
772 : 0 : void PivotCacheField::applyItemCaptions( const IdCaptionPairList& vCaptions )
773 : : {
774 [ # # ]: 0 : if( hasGroupItems() )
775 : 0 : maGroupItems.applyItemCaptions( vCaptions );
776 [ # # ]: 0 : if( hasSharedItems() )
777 : 0 : maSharedItems.applyItemCaptions( vCaptions );
778 : 0 : }
779 : :
780 : 0 : void PivotCacheField::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
781 : : {
782 [ # # ]: 0 : if( hasGroupItems() )
783 : 0 : maGroupItems.getCacheItemNames( orItemNames );
784 [ # # ]: 0 : else if( hasSharedItems() )
785 : 0 : maSharedItems.getCacheItemNames( orItemNames );
786 : 0 : }
787 : :
788 : 0 : PivotCacheItemList PivotCacheField::getCacheItems() const
789 : : {
790 [ # # ]: 0 : if( hasGroupItems() )
791 : 0 : return maGroupItems;
792 : 0 : return maSharedItems;
793 : : }
794 : :
795 : 0 : void PivotCacheField::convertNumericGrouping( const Reference< XDataPilotField >& rxDPField ) const
796 : : {
797 : : OSL_ENSURE( hasGroupItems() && hasNumericGrouping(), "PivotCacheField::convertNumericGrouping - not a numeric group field" );
798 [ # # ]: 0 : PropertySet aPropSet( rxDPField );
799 [ # # ][ # # ]: 0 : if( hasGroupItems() && hasNumericGrouping() && aPropSet.is() )
[ # # ][ # # ]
800 : : {
801 [ # # ]: 0 : DataPilotFieldGroupInfo aGroupInfo;
802 : 0 : aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
803 : 0 : aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
804 : 0 : aGroupInfo.HasDateValues = sal_False;
805 : 0 : aGroupInfo.Start = maFieldGroupModel.mfStartValue;
806 : 0 : aGroupInfo.End = maFieldGroupModel.mfEndValue;
807 : 0 : aGroupInfo.Step = maFieldGroupModel.mfInterval;
808 : 0 : aGroupInfo.GroupBy = 0;
809 [ # # ][ # # ]: 0 : aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
810 [ # # ]: 0 : }
811 : 0 : }
812 : :
813 : 0 : OUString PivotCacheField::createDateGroupField( const Reference< XDataPilotField >& rxBaseDPField ) const
814 : : {
815 : : OSL_ENSURE( hasGroupItems() && hasDateGrouping(), "PivotCacheField::createDateGroupField - not a numeric group field" );
816 : 0 : Reference< XDataPilotField > xDPGroupField;
817 [ # # ]: 0 : PropertySet aPropSet( rxBaseDPField );
818 [ # # ][ # # ]: 0 : if( hasGroupItems() && hasDateGrouping() && aPropSet.is() )
[ # # ][ # # ]
819 : : {
820 [ # # ][ # # ]: 0 : bool bDayRanges = (maFieldGroupModel.mnGroupBy == XML_days) && (maFieldGroupModel.mfInterval >= 2.0);
821 : :
822 [ # # ]: 0 : DataPilotFieldGroupInfo aGroupInfo;
823 : 0 : aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
824 : 0 : aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
825 : 0 : aGroupInfo.HasDateValues = sal_True;
826 [ # # ][ # # ]: 0 : aGroupInfo.Start = getUnitConverter().calcSerialFromDateTime( maFieldGroupModel.maStartDate );
827 [ # # ][ # # ]: 0 : aGroupInfo.End = getUnitConverter().calcSerialFromDateTime( maFieldGroupModel.maEndDate );
828 [ # # ]: 0 : aGroupInfo.Step = bDayRanges ? maFieldGroupModel.mfInterval : 0.0;
829 : :
830 : : using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
831 [ # # # # : 0 : switch( maFieldGroupModel.mnGroupBy )
# # # # ]
832 : : {
833 : 0 : case XML_years: aGroupInfo.GroupBy = YEARS; break;
834 : 0 : case XML_quarters: aGroupInfo.GroupBy = QUARTERS; break;
835 : 0 : case XML_months: aGroupInfo.GroupBy = MONTHS; break;
836 : 0 : case XML_days: aGroupInfo.GroupBy = DAYS; break;
837 : 0 : case XML_hours: aGroupInfo.GroupBy = HOURS; break;
838 : 0 : case XML_minutes: aGroupInfo.GroupBy = MINUTES; break;
839 : 0 : case XML_seconds: aGroupInfo.GroupBy = SECONDS; break;
840 : : default: OSL_FAIL( "PivotCacheField::convertRangeGrouping - unknown date/time interval" );
841 : : }
842 : :
843 : : try
844 : : {
845 [ # # ]: 0 : Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY_THROW );
846 [ # # ][ # # ]: 0 : xDPGroupField = xDPGrouping->createDateGroup( aGroupInfo );
[ # # ][ # # ]
847 : : }
848 [ # # ]: 0 : catch( Exception& )
849 : : {
850 [ # # ]: 0 : }
851 : : }
852 : :
853 [ # # ]: 0 : Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
854 [ # # ][ # # ]: 0 : return xFieldName.is() ? xFieldName->getName() : OUString();
[ # # ][ # # ]
855 : : }
856 : :
857 : 0 : OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotField >& rxBaseDPField, const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames ) const
858 : : {
859 : : OSL_ENSURE( hasGroupItems() && !maDiscreteItems.empty(), "PivotCacheField::createParentGroupField - not a group field" );
860 : : OSL_ENSURE( maDiscreteItems.size() == orItemNames.size(), "PivotCacheField::createParentGroupField - number of item names does not match grouping info" );
861 [ # # ]: 0 : Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY );
862 [ # # ]: 0 : if( !xDPGrouping.is() ) return OUString();
863 : :
864 : : // map the group item indexes from maGroupItems to all item indexes from maDiscreteItems
865 : : typedef ::std::vector< sal_Int32 > GroupItemList;
866 : : typedef ::std::vector< GroupItemList > GroupItemMap;
867 [ # # ]: 0 : GroupItemMap aItemMap( maGroupItems.size() );
868 [ # # ][ # # ]: 0 : for( IndexVector::const_iterator aBeg = maDiscreteItems.begin(), aIt = aBeg, aEnd = maDiscreteItems.end(); aIt != aEnd; ++aIt )
[ # # ]
869 : : {
870 [ # # ][ # # ]: 0 : if( GroupItemList* pItems = ContainerHelper::getVectorElementAccess( aItemMap, *aIt ) )
[ # # ]
871 : : {
872 [ # # ][ # # ]: 0 : if ( const PivotCacheItem* pItem = rBaseCacheField.getCacheItems().getCacheItem( aIt - aBeg ) )
[ # # ][ # # ]
[ # # ]
873 : : {
874 : : // Skip unspecified or ununsed entries or errors
875 [ # # ][ # # ]: 0 : if ( pItem->isUnused() || ( pItem->getType() == XML_m ) || ( pItem->getType() == XML_e ) )
[ # # ][ # # ]
876 : 0 : continue;
877 : : }
878 [ # # ][ # # ]: 0 : pItems->push_back( static_cast< sal_Int32 >( aIt - aBeg ) );
879 : : }
880 : : }
881 : :
882 : : // process all groups
883 : 0 : Reference< XDataPilotField > xDPGroupField;
884 [ # # ][ # # ]: 0 : for( GroupItemMap::iterator aBeg = aItemMap.begin(), aIt = aBeg, aEnd = aItemMap.end(); aIt != aEnd; ++aIt )
[ # # ]
885 : : {
886 : : OSL_ENSURE( !aIt->empty(), "PivotCacheField::createParentGroupField - item/group should not be empty" );
887 [ # # ][ # # ]: 0 : if( !aIt->empty() )
888 : : {
889 : : /* Insert the names of the items that are part of this group. Calc
890 : : expects the names of the members of the field whose members are
891 : : grouped (which may be the names of groups too). Excel provides
892 : : the names of the base field items instead (no group names
893 : : involved). Therefore, the passed collection of current item
894 : : names as they are already grouped is used here to resolve the
895 : : item names. */
896 [ # # ]: 0 : ::std::vector< OUString > aMembers;
897 [ # # ][ # # ]: 0 : for( GroupItemList::iterator aBeg2 = aIt->begin(), aIt2 = aBeg2, aEnd2 = aIt->end(); aIt2 != aEnd2; ++aIt2 )
[ # # ][ # # ]
[ # # ]
898 [ # # ][ # # ]: 0 : if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, *aIt2 ) )
[ # # ]
899 [ # # ][ # # ]: 0 : if( ::std::find( aMembers.begin(), aMembers.end(), pName->maGroupName ) == aMembers.end() )
[ # # ]
900 [ # # ]: 0 : aMembers.push_back( pName->maGroupName );
901 : :
902 : : /* Check again, that this is not just a group that is not grouped
903 : : further with other items. */
904 [ # # ]: 0 : if( !aMembers.empty() ) try
905 : : {
906 : : // only the first call of createNameGroup() returns the new field
907 [ # # ][ # # ]: 0 : Reference< XDataPilotField > xDPNewField = xDPGrouping->createNameGroup( ContainerHelper::vectorToSequence( aMembers ) );
[ # # ][ # # ]
908 : : OSL_ENSURE( xDPGroupField.is() != xDPNewField.is(), "PivotCacheField::createParentGroupField - missing group field" );
909 [ # # ]: 0 : if( !xDPGroupField.is() )
910 [ # # ]: 0 : xDPGroupField = xDPNewField;
911 : :
912 : : // get current grouping info
913 [ # # ]: 0 : DataPilotFieldGroupInfo aGroupInfo;
914 [ # # ]: 0 : PropertySet aPropSet( xDPGroupField );
915 [ # # ]: 0 : aPropSet.getProperty( aGroupInfo, PROP_GroupInfo );
916 : :
917 : : /* Find the group object and the auto-generated group name.
918 : : The returned field contains all groups derived from the
919 : : previous field if that is grouped too. To find the correct
920 : : group, the first item used to create the group is serached.
921 : : Calc provides the original item names of the base field
922 : : when the group is querried for its members. Its does not
923 : : provide the names of members that are already groups in the
924 : : field used to create the new groups. (Is this a bug?)
925 : : Therefore, a name from the passed list of original item
926 : : names is used to find the correct group. */
927 : 0 : OUString aFirstItem;
928 [ # # ][ # # ]: 0 : if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, aIt->front() ) )
[ # # ][ # # ]
929 : 0 : aFirstItem = pName->maOrigName;
930 : 0 : Reference< XNamed > xGroupName;
931 : 0 : OUString aAutoName;
932 [ # # ]: 0 : Reference< XIndexAccess > xGroupsIA( aGroupInfo.Groups, UNO_QUERY_THROW );
933 [ # # ][ # # ]: 0 : for( sal_Int32 nIdx = 0, nCount = xGroupsIA->getCount(); (nIdx < nCount) && (aAutoName.isEmpty()); ++nIdx ) try
[ # # ][ # # ]
[ # # ]
934 : : {
935 [ # # ][ # # ]: 0 : Reference< XNameAccess > xItemsNA( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
[ # # ]
936 [ # # ][ # # ]: 0 : if( xItemsNA->hasByName( aFirstItem ) )
[ # # ]
937 : : {
938 [ # # ][ # # ]: 0 : xGroupName.set( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
[ # # ]
939 [ # # ][ # # ]: 0 : aAutoName = xGroupName->getName();
940 [ # # ]: 0 : }
941 : : }
942 [ # # ]: 0 : catch( Exception& )
943 : : {
944 : : }
945 : : OSL_ENSURE( !aAutoName.isEmpty(), "PivotCacheField::createParentGroupField - cannot find auto-generated group name" );
946 : :
947 : : // get the real group name from the list of group items
948 : 0 : OUString aGroupName;
949 [ # # ][ # # ]: 0 : if( const PivotCacheItem* pGroupItem = maGroupItems.getCacheItem( static_cast< sal_Int32 >( aIt - aBeg ) ) )
[ # # ]
950 [ # # ]: 0 : aGroupName = pGroupItem->getName();
951 : : OSL_ENSURE( !aGroupName.isEmpty(), "PivotCacheField::createParentGroupField - cannot find group name" );
952 [ # # ]: 0 : if( aGroupName.isEmpty() )
953 : 0 : aGroupName = aAutoName;
954 : :
955 [ # # ][ # # ]: 0 : if( xGroupName.is() && !aGroupName.isEmpty() )
[ # # ]
956 : : {
957 : : // replace the auto-generated group name with the real name
958 [ # # ]: 0 : if( aAutoName != aGroupName )
959 : : {
960 [ # # ][ # # ]: 0 : xGroupName->setName( aGroupName );
961 [ # # ]: 0 : aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
962 : : }
963 : : // replace original item names in passed vector with group name
964 [ # # ][ # # ]: 0 : for( GroupItemList::iterator aIt2 = aIt->begin(), aEnd2 = aIt->end(); aIt2 != aEnd2; ++aIt2 )
[ # # ][ # # ]
[ # # ]
965 [ # # ][ # # ]: 0 : if( PivotCacheGroupItem* pName = ContainerHelper::getVectorElementAccess( orItemNames, *aIt2 ) )
[ # # ]
966 : 0 : pName->maGroupName = aGroupName;
967 [ # # ][ # # ]: 0 : }
[ # # ]
968 : : }
969 [ # # ]: 0 : catch( Exception& )
970 : : {
971 : 0 : }
972 : : }
973 : : }
974 : :
975 [ # # ]: 0 : Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
976 [ # # ][ # # ]: 0 : return xFieldName.is() ? xFieldName->getName() : OUString();
[ # # ]
977 : : }
978 : :
979 : 0 : void PivotCacheField::writeSourceHeaderCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
980 : : {
981 [ # # ]: 0 : CellModel aModel;
982 [ # # ]: 0 : aModel.maCellAddr = CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow );
983 [ # # ][ # # ]: 0 : rSheetHelper.getSheetData().setStringCell( aModel, maFieldModel.maName );
984 : 0 : }
985 : :
986 : 0 : void PivotCacheField::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
987 : : {
988 : 0 : bool bHasIndex = rItem.getType() == XML_x;
989 : : OSL_ENSURE( bHasIndex != maSharedItems.empty(), "PivotCacheField::writeSourceDataCell - shared items missing or not expected" );
990 [ # # ]: 0 : if( bHasIndex )
991 : 0 : writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem.getValue().get< sal_Int32 >() );
992 : : else
993 : 0 : writeItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem );
994 : 0 : }
995 : :
996 : 0 : void PivotCacheField::importPCRecordItem( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
997 : : {
998 [ # # ]: 0 : if( hasSharedItems() )
999 : : {
1000 : 0 : writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rStrm.readInt32() );
1001 : : }
1002 : : else
1003 : : {
1004 : 0 : PivotCacheItem aItem;
1005 [ # # ]: 0 : if( maSharedItemsModel.mbIsNumeric )
1006 [ # # ]: 0 : aItem.readDouble( rStrm );
1007 [ # # ][ # # ]: 0 : else if( maSharedItemsModel.mbHasDate && !maSharedItemsModel.mbHasString )
1008 [ # # ]: 0 : aItem.readDate( rStrm );
1009 : : else
1010 [ # # ]: 0 : aItem.readString( rStrm );
1011 [ # # ]: 0 : writeItemToSourceDataCell( rSheetHelper, nCol, nRow, aItem );
1012 : : }
1013 : 0 : }
1014 : :
1015 : 0 : void PivotCacheField::importPCItemIndex( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
1016 : : {
1017 : : OSL_ENSURE( hasSharedItems(), "PivotCacheField::importPCItemIndex - invalid call, no shared items found" );
1018 [ # # ]: 0 : sal_Int32 nIndex = maSharedItemsModel.mbHasLongIndexes ? rStrm.readuInt16() : rStrm.readuInt8();
1019 : 0 : writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, nIndex );
1020 : 0 : }
1021 : :
1022 : : // private --------------------------------------------------------------------
1023 : :
1024 : 0 : void PivotCacheField::writeItemToSourceDataCell( WorksheetHelper& rSheetHelper,
1025 : : sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
1026 : : {
1027 [ # # ]: 0 : if( rItem.getType() != XML_m )
1028 : : {
1029 [ # # ]: 0 : CellModel aModel;
1030 [ # # ]: 0 : aModel.maCellAddr = CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow );
1031 [ # # ]: 0 : SheetDataBuffer& rSheetData = rSheetHelper.getSheetData();
1032 [ # # # # : 0 : switch( rItem.getType() )
# # # ]
1033 : : {
1034 [ # # ][ # # ]: 0 : case XML_s: rSheetData.setStringCell( aModel, rItem.getValue().get< OUString >() ); break;
1035 [ # # ][ # # ]: 0 : case XML_n: rSheetData.setValueCell( aModel, rItem.getValue().get< double >() ); break;
1036 [ # # ][ # # ]: 0 : case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< sal_Int16 >() ); break;
1037 [ # # ][ # # ]: 0 : case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< DateTime >() ); break;
1038 [ # # ][ # # ]: 0 : case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< bool >() ); break;
1039 [ # # ][ # # ]: 0 : case XML_e: rSheetData.setErrorCell( aModel, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break;
1040 : : default: OSL_FAIL( "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" );
1041 : : }
1042 : : }
1043 : 0 : }
1044 : :
1045 : 0 : void PivotCacheField::writeSharedItemToSourceDataCell(
1046 : : WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nItemIdx ) const
1047 : : {
1048 [ # # ]: 0 : if( const PivotCacheItem* pCacheItem = maSharedItems.getCacheItem( nItemIdx ) )
1049 : 0 : writeItemToSourceDataCell( rSheetHelper, nCol, nRow, *pCacheItem );
1050 : 0 : }
1051 : :
1052 : : // ============================================================================
1053 : :
1054 : 0 : PCDefinitionModel::PCDefinitionModel() :
1055 : : mfRefreshedDate( 0.0 ),
1056 : : mnRecords( 0 ),
1057 : : mnMissItemsLimit( 0 ),
1058 : : mnDatabaseFields( 0 ),
1059 : : mbInvalid( false ),
1060 : : mbSaveData( true ),
1061 : : mbRefreshOnLoad( false ),
1062 : : mbOptimizeMemory( false ),
1063 : : mbEnableRefresh( true ),
1064 : : mbBackgroundQuery( false ),
1065 : : mbUpgradeOnRefresh( false ),
1066 : : mbTupleCache( false ),
1067 : : mbSupportSubquery( false ),
1068 : 0 : mbSupportDrill( false )
1069 : : {
1070 : 0 : }
1071 : :
1072 : : // ----------------------------------------------------------------------------
1073 : :
1074 : 0 : PCSourceModel::PCSourceModel() :
1075 : : mnSourceType( XML_TOKEN_INVALID ),
1076 : 0 : mnConnectionId( 0 )
1077 : : {
1078 : 0 : }
1079 : :
1080 : : // ----------------------------------------------------------------------------
1081 : :
1082 : 0 : PCWorksheetSourceModel::PCWorksheetSourceModel()
1083 : : {
1084 : 0 : maRange.StartColumn = maRange.StartRow = maRange.EndColumn = maRange.EndRow = -1;
1085 : 0 : }
1086 : :
1087 : : // ----------------------------------------------------------------------------
1088 : :
1089 : 0 : PivotCache::PivotCache( const WorkbookHelper& rHelper ) :
1090 : : WorkbookHelper( rHelper ),
1091 : : mnCurrRow( -1 ),
1092 : : mbValidSource( false ),
1093 [ # # ][ # # ]: 0 : mbDummySheet( false )
[ # # ][ # # ]
1094 : : {
1095 : 0 : }
1096 : :
1097 : 0 : void PivotCache::importPivotCacheDefinition( const AttributeList& rAttribs )
1098 : : {
1099 [ # # ]: 0 : maDefModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
1100 [ # # ]: 0 : maDefModel.maRefreshedBy = rAttribs.getXString( XML_refreshedBy, OUString() );
1101 : 0 : maDefModel.mfRefreshedDate = rAttribs.getDouble( XML_refreshedDate, 0.0 );
1102 : 0 : maDefModel.mnRecords = rAttribs.getInteger( XML_recordCount, 0 );
1103 : 0 : maDefModel.mnMissItemsLimit = rAttribs.getInteger( XML_missingItemsLimit, 0 );
1104 : 0 : maDefModel.mbInvalid = rAttribs.getBool( XML_invalid, false );
1105 : 0 : maDefModel.mbSaveData = rAttribs.getBool( XML_saveData, true );
1106 : 0 : maDefModel.mbRefreshOnLoad = rAttribs.getBool( XML_refreshOnLoad, false );
1107 : 0 : maDefModel.mbOptimizeMemory = rAttribs.getBool( XML_optimizeMemory, false );
1108 : 0 : maDefModel.mbEnableRefresh = rAttribs.getBool( XML_enableRefresh, true );
1109 : 0 : maDefModel.mbBackgroundQuery = rAttribs.getBool( XML_backgroundQuery, false );
1110 : 0 : maDefModel.mbUpgradeOnRefresh = rAttribs.getBool( XML_upgradeOnRefresh, false );
1111 : 0 : maDefModel.mbTupleCache = rAttribs.getBool( XML_tupleCache, false );
1112 : 0 : maDefModel.mbSupportSubquery = rAttribs.getBool( XML_supportSubquery, false );
1113 : 0 : maDefModel.mbSupportDrill = rAttribs.getBool( XML_supportAdvancedDrill, false );
1114 : 0 : }
1115 : :
1116 : 0 : void PivotCache::importCacheSource( const AttributeList& rAttribs )
1117 : : {
1118 : 0 : maSourceModel.mnSourceType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
1119 : 0 : maSourceModel.mnConnectionId = rAttribs.getInteger( XML_connectionId, 0 );
1120 : 0 : }
1121 : :
1122 : 0 : void PivotCache::importWorksheetSource( const AttributeList& rAttribs, const Relations& rRelations )
1123 : : {
1124 [ # # ]: 0 : maSheetSrcModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
1125 [ # # ]: 0 : maSheetSrcModel.maSheet = rAttribs.getXString( XML_sheet, OUString() );
1126 [ # # ]: 0 : maSheetSrcModel.maDefName = rAttribs.getXString( XML_name, OUString() );
1127 : :
1128 : : // resolve URL of external document
1129 : 0 : maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
1130 : : // store range address unchecked with sheet index 0, will be resolved/checked later
1131 [ # # ][ # # ]: 0 : getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, rAttribs.getString( XML_ref, OUString() ), 0 );
[ # # ]
1132 : 0 : }
1133 : :
1134 : 0 : void PivotCache::importPCDefinition( SequenceInputStream& rStrm )
1135 : : {
1136 : : sal_uInt8 nFlags1, nFlags2;
1137 [ # # ]: 0 : rStrm.skip( 3 ); // create/refresh version id's
1138 [ # # ][ # # ]: 0 : rStrm >> nFlags1 >> maDefModel.mnMissItemsLimit >> maDefModel.mfRefreshedDate >> nFlags2 >> maDefModel.mnRecords;
[ # # ][ # # ]
[ # # ]
1139 [ # # ]: 0 : if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASUSERNAME ) )
1140 [ # # ]: 0 : rStrm >> maDefModel.maRefreshedBy;
1141 [ # # ]: 0 : if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASRELID ) )
1142 [ # # ]: 0 : rStrm >> maDefModel.maRelId;
1143 : :
1144 : 0 : maDefModel.mbInvalid = getFlag( nFlags1, BIFF12_PCDEFINITION_INVALID );
1145 : 0 : maDefModel.mbSaveData = getFlag( nFlags1, BIFF12_PCDEFINITION_SAVEDATA );
1146 : 0 : maDefModel.mbRefreshOnLoad = getFlag( nFlags1, BIFF12_PCDEFINITION_REFRESHONLOAD );
1147 : 0 : maDefModel.mbOptimizeMemory = getFlag( nFlags1, BIFF12_PCDEFINITION_OPTIMIZEMEMORY );
1148 : 0 : maDefModel.mbEnableRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_ENABLEREFRESH );
1149 : 0 : maDefModel.mbBackgroundQuery = getFlag( nFlags1, BIFF12_PCDEFINITION_BACKGROUNDQUERY );
1150 : 0 : maDefModel.mbUpgradeOnRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_UPGRADEONREFR );
1151 : 0 : maDefModel.mbTupleCache = getFlag( nFlags1, BIFF12_PCDEFINITION_TUPELCACHE );
1152 : 0 : maDefModel.mbSupportSubquery = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTSUBQUERY );
1153 : 0 : maDefModel.mbSupportDrill = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTDRILL );
1154 : 0 : }
1155 : :
1156 : 0 : void PivotCache::importPCDSource( SequenceInputStream& rStrm )
1157 : : {
1158 : : sal_Int32 nSourceType;
1159 [ # # ][ # # ]: 0 : rStrm >> nSourceType >> maSourceModel.mnConnectionId;
1160 : : static const sal_Int32 spnSourceTypes[] = { XML_worksheet, XML_external, XML_consolidation, XML_scenario };
1161 [ # # ]: 0 : maSourceModel.mnSourceType = STATIC_ARRAY_SELECT( spnSourceTypes, nSourceType, XML_TOKEN_INVALID );
1162 : 0 : }
1163 : :
1164 : 0 : void PivotCache::importPCDSheetSource( SequenceInputStream& rStrm, const Relations& rRelations )
1165 : : {
1166 : : sal_uInt8 nIsDefName, nIsBuiltinName, nFlags;
1167 [ # # ][ # # ]: 0 : rStrm >> nIsDefName >> nIsBuiltinName >> nFlags;
[ # # ]
1168 [ # # ]: 0 : if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASSHEET ) )
1169 [ # # ]: 0 : rStrm >> maSheetSrcModel.maSheet;
1170 [ # # ]: 0 : if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASRELID ) )
1171 [ # # ]: 0 : rStrm >> maSheetSrcModel.maRelId;
1172 : :
1173 : : // read cell range or defined name
1174 [ # # ]: 0 : if( nIsDefName == 0 )
1175 : : {
1176 : 0 : BinRange aBinRange;
1177 [ # # ]: 0 : rStrm >> aBinRange;
1178 : : // store range address unchecked with sheet index 0, will be resolved/checked later
1179 [ # # ][ # # ]: 0 : getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, aBinRange, 0 );
1180 : : }
1181 : : else
1182 : : {
1183 [ # # ]: 0 : rStrm >> maSheetSrcModel.maDefName;
1184 [ # # ]: 0 : if( nIsBuiltinName != 0 )
1185 [ # # ]: 0 : maSheetSrcModel.maDefName = CREATE_OUSTRING( "_xlnm." ) + maSheetSrcModel.maDefName;
1186 : : }
1187 : :
1188 : : // resolve URL of external document
1189 [ # # ]: 0 : maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
1190 : 0 : }
1191 : :
1192 : 0 : void PivotCache::importPCDefinition( BiffInputStream& rStrm )
1193 : : {
1194 : : sal_uInt16 nFlags, nUserNameLen;
1195 [ # # ]: 0 : rStrm >> maDefModel.mnRecords;
1196 [ # # ]: 0 : rStrm.skip( 2 ); // repeated cache ID
1197 [ # # ]: 0 : rStrm >> nFlags;
1198 [ # # ]: 0 : rStrm.skip( 2 ); // unused
1199 [ # # ]: 0 : rStrm >> maDefModel.mnDatabaseFields;
1200 [ # # ]: 0 : rStrm.skip( 6 ); // total field count, report record count, (repeated) cache type
1201 [ # # ]: 0 : rStrm >> nUserNameLen;
1202 [ # # ]: 0 : if( nUserNameLen != BIFF_PC_NOSTRING )
1203 [ # # ]: 0 : maDefModel.maRefreshedBy = (getBiff() == BIFF8) ?
1204 : : rStrm.readUniString( nUserNameLen ) :
1205 [ # # ][ # # ]: 0 : rStrm.readCharArrayUC( nUserNameLen, getTextEncoding() );
[ # # ][ # # ]
1206 : :
1207 : 0 : maDefModel.mbInvalid = getFlag( nFlags, BIFF_PCDEFINITION_INVALID );
1208 : 0 : maDefModel.mbSaveData = getFlag( nFlags, BIFF_PCDEFINITION_SAVEDATA );
1209 : 0 : maDefModel.mbRefreshOnLoad = getFlag( nFlags, BIFF_PCDEFINITION_REFRESHONLOAD );
1210 : 0 : maDefModel.mbOptimizeMemory = getFlag( nFlags, BIFF_PCDEFINITION_OPTIMIZEMEMORY );
1211 : 0 : maDefModel.mbEnableRefresh = getFlag( nFlags, BIFF_PCDEFINITION_ENABLEREFRESH );
1212 : 0 : maDefModel.mbBackgroundQuery = getFlag( nFlags, BIFF_PCDEFINITION_BACKGROUNDQUERY );
1213 : :
1214 [ # # ][ # # ]: 0 : if( (rStrm.getNextRecId() == BIFF_ID_PCDEFINITION2) && rStrm.startNextRecord() )
[ # # ][ # # ]
[ # # ]
1215 [ # # ]: 0 : rStrm >> maDefModel.mfRefreshedDate;
1216 : 0 : }
1217 : :
1218 : 0 : PivotCacheField& PivotCache::createCacheField( bool bInitDatabaseField )
1219 : : {
1220 [ # # ][ # # ]: 0 : bool bIsDatabaseField = !bInitDatabaseField || (maFields.size() < maDefModel.mnDatabaseFields);
1221 [ # # ][ # # ]: 0 : PivotCacheFieldVector::value_type xCacheField( new PivotCacheField( *this, bIsDatabaseField ) );
[ # # ]
1222 [ # # ]: 0 : maFields.push_back( xCacheField );
1223 [ # # ]: 0 : return *xCacheField;
1224 : : }
1225 : :
1226 : 0 : void PivotCache::finalizeImport()
1227 : : {
1228 : : // collect all fields that are based on source data (needed to finalize source data below)
1229 : : OSL_ENSURE( !maFields.empty(), "PivotCache::finalizeImport - no pivot cache fields found" );
1230 [ # # ][ # # ]: 0 : for( PivotCacheFieldVector::const_iterator aIt = maFields.begin(), aEnd = maFields.end(); aIt != aEnd; ++aIt )
[ # # ][ # # ]
1231 : : {
1232 [ # # ]: 0 : if( (*aIt)->isDatabaseField() )
1233 : : {
1234 : : OSL_ENSURE( (aIt == maFields.begin()) || (*(aIt - 1))->isDatabaseField(),
1235 : : "PivotCache::finalizeImport - database field follows a calculated field" );
1236 [ # # ]: 0 : maDatabaseIndexes.push_back( static_cast< sal_Int32 >( maDatabaseFields.size() ) );
1237 [ # # ]: 0 : maDatabaseFields.push_back( *aIt );
1238 : : }
1239 : : else
1240 : : {
1241 [ # # ]: 0 : maDatabaseIndexes.push_back( -1 );
1242 : : }
1243 : : }
1244 : : OSL_ENSURE( !maDatabaseFields.empty(), "PivotCache::finalizeImport - no pivot cache source fields found" );
1245 : :
1246 : : // finalize source data depending on source type
1247 [ # # # # : 0 : switch( maSourceModel.mnSourceType )
# ]
1248 : : {
1249 : : case XML_worksheet:
1250 : : {
1251 : : // decide whether an external document is used
1252 [ # # ][ # # ]: 0 : bool bInternal = maTargetUrl.isEmpty() && maSheetSrcModel.maRelId.isEmpty();
1253 : 0 : bool bExternal = !maTargetUrl.isEmpty(); // relation ID may be empty, e.g. BIFF import
1254 : : OSL_ENSURE( bInternal || bExternal, "PivotCache::finalizeImport - invalid external document URL" );
1255 [ # # ]: 0 : if( bInternal )
1256 : 0 : finalizeInternalSheetSource();
1257 [ # # ]: 0 : else if( bExternal )
1258 : 0 : finalizeExternalSheetSource();
1259 : : }
1260 : 0 : break;
1261 : :
1262 : : // currently, we only support worksheet data sources
1263 : : case XML_external:
1264 : 0 : break;
1265 : : case XML_consolidation:
1266 : 0 : break;
1267 : : case XML_scenario:
1268 : 0 : break;
1269 : : }
1270 : 0 : }
1271 : :
1272 : 0 : sal_Int32 PivotCache::getCacheFieldCount() const
1273 : : {
1274 : 0 : return static_cast< sal_Int32 >( maFields.size() );
1275 : : }
1276 : :
1277 : 0 : const PivotCacheField* PivotCache::getCacheField( sal_Int32 nFieldIdx ) const
1278 : : {
1279 : 0 : return maFields.get( nFieldIdx ).get();
1280 : : }
1281 : :
1282 : 0 : sal_Int32 PivotCache::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
1283 : : {
1284 [ # # ]: 0 : return ContainerHelper::getVectorElement( maDatabaseIndexes, nFieldIdx, -1 );
1285 : : }
1286 : :
1287 : 0 : void PivotCache::writeSourceHeaderCells( WorksheetHelper& rSheetHelper ) const
1288 : : {
1289 : : OSL_ENSURE( static_cast< size_t >( maSheetSrcModel.maRange.EndColumn - maSheetSrcModel.maRange.StartColumn + 1 ) == maDatabaseFields.size(),
1290 : : "PivotCache::writeSourceHeaderCells - source cell range width does not match number of source fields" );
1291 : 0 : sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
1292 : 0 : sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
1293 : 0 : sal_Int32 nRow = maSheetSrcModel.maRange.StartRow;
1294 : 0 : mnCurrRow = -1;
1295 : 0 : updateSourceDataRow( rSheetHelper, nRow );
1296 [ # # ][ # # ]: 0 : for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
[ # # ][ # # ]
1297 [ # # ]: 0 : (*aIt)->writeSourceHeaderCell( rSheetHelper, nCol, nRow );
1298 : 0 : }
1299 : :
1300 : 0 : void PivotCache::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nColIdx, sal_Int32 nRowIdx, const PivotCacheItem& rItem ) const
1301 : : {
1302 : 0 : sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn + nColIdx;
1303 : : OSL_ENSURE( (maSheetSrcModel.maRange.StartColumn <= nCol) && (nCol <= maSheetSrcModel.maRange.EndColumn), "PivotCache::writeSourceDataCell - invalid column index" );
1304 : 0 : sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx;
1305 : : OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::writeSourceDataCell - invalid row index" );
1306 : 0 : updateSourceDataRow( rSheetHelper, nRow );
1307 [ # # ]: 0 : if( const PivotCacheField* pCacheField = maDatabaseFields.get( nColIdx ).get() )
1308 : 0 : pCacheField->writeSourceDataCell( rSheetHelper, nCol, nRow, rItem );
1309 : 0 : }
1310 : :
1311 : 0 : void PivotCache::importPCRecord( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const
1312 : : {
1313 : 0 : sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx;
1314 : : OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::importPCRecord - invalid row index" );
1315 : 0 : sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
1316 : 0 : sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
1317 [ # # ][ # # ]: 0 : for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
[ # # ][ # # ]
[ # # ]
1318 [ # # ]: 0 : (*aIt)->importPCRecordItem( rStrm, rSheetHelper, nCol, nRow );
1319 : 0 : }
1320 : :
1321 : 0 : void PivotCache::importPCItemIndexList( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const
1322 : : {
1323 : 0 : sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx;
1324 : : OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::importPCItemIndexList - invalid row index" );
1325 : 0 : sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
1326 : 0 : sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
1327 [ # # ][ # # ]: 0 : for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
[ # # ][ # # ]
[ # # ]
1328 [ # # ]: 0 : if( (*aIt)->hasSharedItems() )
1329 [ # # ]: 0 : (*aIt)->importPCItemIndex( rStrm, rSheetHelper, nCol, nRow );
1330 : 0 : }
1331 : :
1332 : : // private --------------------------------------------------------------------
1333 : :
1334 : 0 : void PivotCache::finalizeInternalSheetSource()
1335 : : {
1336 : : // resolve sheet name to sheet index
1337 : 0 : sal_Int16 nSheet = getWorksheets().getCalcSheetIndex( maSheetSrcModel.maSheet );
1338 : :
1339 : : // if cache is based on a defined name or table, try to resolve to cell range
1340 [ # # ]: 0 : if( !maSheetSrcModel.maDefName.isEmpty() )
1341 : : {
1342 : : // local or global defined name
1343 [ # # ]: 0 : if( const DefinedName* pDefName = getDefinedNames().getByModelName( maSheetSrcModel.maDefName, nSheet ).get() )
1344 : : {
1345 : 0 : mbValidSource = pDefName->getAbsoluteRange( maSheetSrcModel.maRange );
1346 : : }
1347 : : // table
1348 [ # # ]: 0 : else if( const Table* pTable = getTables().getTable( maSheetSrcModel.maDefName ).get() )
1349 : : {
1350 : : // get original range from table, but exclude the totals row(s)
1351 : 0 : maSheetSrcModel.maRange = pTable->getOriginalRange();
1352 : 0 : mbValidSource = (pTable->getHeight() - pTable->getTotalsRows()) > 1;
1353 [ # # ]: 0 : if( mbValidSource )
1354 : 0 : maSheetSrcModel.maRange.EndRow -= pTable->getTotalsRows();
1355 : : }
1356 : : }
1357 : : // else try the cell range (if the sheet exists)
1358 [ # # ]: 0 : else if( nSheet >= 0 )
1359 : : {
1360 : : // insert sheet index into the range, range address will be checked below
1361 : 0 : maSheetSrcModel.maRange.Sheet = nSheet;
1362 : 0 : mbValidSource = true;
1363 : : }
1364 : : // else sheet has been deleted, generate the source data from cache
1365 [ # # ]: 0 : else if( !maSheetSrcModel.maSheet.isEmpty() )
1366 : : {
1367 : 0 : prepareSourceDataSheet();
1368 : : // return here to skip the source range check below
1369 : 0 : return;
1370 : : }
1371 : :
1372 : : // check range location, do not allow ranges that overflow the sheet partly
1373 : : mbValidSource = mbValidSource &&
1374 : 0 : getAddressConverter().checkCellRange( maSheetSrcModel.maRange, false, true ) &&
1375 [ # # # # ]: 0 : (maSheetSrcModel.maRange.StartRow < maSheetSrcModel.maRange.EndRow);
[ # # ]
1376 : : }
1377 : :
1378 : 0 : void PivotCache::finalizeExternalSheetSource()
1379 : : {
1380 : : /* If pivot cache is based on external sheet data, try to restore sheet
1381 : : data from cache records. No support for external defined names or tables,
1382 : : sheet name and path to cache records fragment (OOXML only) are required. */
1383 [ # # ][ # # ]: 0 : bool bHasRelation = (getFilterType() == FILTER_BIFF) || !maDefModel.maRelId.isEmpty();
1384 [ # # ][ # # ]: 0 : if( bHasRelation && maSheetSrcModel.maDefName.isEmpty() && !maSheetSrcModel.maSheet.isEmpty() )
[ # # ][ # # ]
1385 : 0 : prepareSourceDataSheet();
1386 : 0 : }
1387 : :
1388 : 0 : void PivotCache::prepareSourceDataSheet()
1389 : : {
1390 : 0 : CellRangeAddress& rRange = maSheetSrcModel.maRange;
1391 : : // data will be inserted in top-left cell, sheet index is still set to 0 (will be set below)
1392 : 0 : rRange.EndColumn -= rRange.StartColumn;
1393 : 0 : rRange.StartColumn = 0;
1394 : 0 : rRange.EndRow -= rRange.StartRow;
1395 : 0 : rRange.StartRow = 0;
1396 : : // check range location, do not allow ranges that overflow the sheet partly
1397 [ # # ]: 0 : if( getAddressConverter().checkCellRange( rRange, false, true ) )
1398 : : {
1399 [ # # ]: 0 : maColSpans.insert( ValueRange( rRange.StartColumn, rRange.EndColumn ) );
1400 [ # # ]: 0 : OUString aSheetName = CREATE_OUSTRING( "DPCache_" ) + maSheetSrcModel.maSheet;
1401 [ # # ][ # # ]: 0 : rRange.Sheet = getWorksheets().insertEmptySheet( aSheetName, false );
1402 : 0 : mbValidSource = mbDummySheet = rRange.Sheet >= 0;
1403 : : }
1404 : 0 : }
1405 : :
1406 : 0 : void PivotCache::updateSourceDataRow( WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const
1407 : : {
1408 [ # # ]: 0 : if( mnCurrRow != nRow )
1409 : : {
1410 : 0 : rSheetHelper.getSheetData().setColSpans( nRow, maColSpans );
1411 : 0 : mnCurrRow = nRow;
1412 : : }
1413 : 0 : }
1414 : :
1415 : : // ============================================================================
1416 : :
1417 : 24 : PivotCacheBuffer::PivotCacheBuffer( const WorkbookHelper& rHelper ) :
1418 [ + - ][ + - ]: 24 : WorkbookHelper( rHelper )
[ + - ]
1419 : : {
1420 : 24 : }
1421 : :
1422 : 0 : void PivotCacheBuffer::registerPivotCacheFragment( sal_Int32 nCacheId, const OUString& rFragmentPath )
1423 : : {
1424 : : OSL_ENSURE( nCacheId >= 0, "PivotCacheBuffer::registerPivotCacheFragment - invalid pivot cache identifier" );
1425 : : OSL_ENSURE( maFragmentPaths.count( nCacheId ) == 0, "PivotCacheBuffer::registerPivotCacheFragment - fragment path exists already" );
1426 [ # # ][ # # ]: 0 : if( (nCacheId >= 0) && !rFragmentPath.isEmpty() )
[ # # ]
1427 : 0 : maFragmentPaths[ nCacheId ] = rFragmentPath;
1428 : 0 : }
1429 : :
1430 : 0 : PivotCache* PivotCacheBuffer::importPivotCacheFragment( sal_Int32 nCacheId )
1431 : : {
1432 [ # # # ]: 0 : switch( getFilterType() )
1433 : : {
1434 : : /* OOXML/BIFF12 filter: On first call for the cache ID, the pivot
1435 : : cache object is created and inserted into maCaches. Then, the cache
1436 : : definition fragment is read and the cache is returned. On
1437 : : subsequent calls, the created cache will be found in maCaches and
1438 : : returned immediately. */
1439 : : case FILTER_OOXML:
1440 : : {
1441 : : // try to find an imported pivot cache
1442 [ # # ][ # # ]: 0 : if( PivotCache* pCache = maCaches.get( nCacheId ).get() )
[ # # ]
1443 : 0 : return pCache;
1444 : :
1445 : : // check if a fragment path exists for the passed cache identifier
1446 [ # # ]: 0 : FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
1447 [ # # ]: 0 : if( aIt == maFragmentPaths.end() )
1448 : 0 : return 0;
1449 : :
1450 : : /* Import the cache fragment. This may create a dummy data sheet
1451 : : for external sheet sources. */
1452 [ # # ]: 0 : PivotCache& rCache = createPivotCache( nCacheId );
1453 [ # # ][ # # ]: 0 : importOoxFragment( new PivotCacheDefinitionFragment( *this, aIt->second, rCache ) );
1454 : 0 : return &rCache;
1455 : : }
1456 : :
1457 : : /* BIFF filter: Pivot table provides 0-based index into list of pivot
1458 : : cache source links (PIVOTCACHE/PCDSOURCE/... record blocks in
1459 : : workbook stream). First, this index has to be resolved to the cache
1460 : : identifier that is used to manage the cache stream names (the
1461 : : maFragmentPaths member). The cache object itself exists already
1462 : : before the first call for the cache source index, because source data
1463 : : link is part of workbook data, not of the cache stream. To detect
1464 : : subsequent calls with an already initialized cache, the entry in
1465 : : maFragmentPaths will be removed after reading the cache stream. */
1466 : : case FILTER_BIFF:
1467 : : {
1468 : : /* Resolve cache index to cache identifier and try to find pivot
1469 : : cache. Cache must exist already for a valid cache index. */
1470 [ # # ]: 0 : nCacheId = ContainerHelper::getVectorElement( maCacheIds, nCacheId, -1 );
1471 [ # # ][ # # ]: 0 : PivotCache* pCache = maCaches.get( nCacheId ).get();
1472 [ # # ]: 0 : if( !pCache )
1473 : 0 : return 0;
1474 : :
1475 : : /* Try to find fragment path entry (stream name). If missing, the
1476 : : stream has been read already, and the cache can be returned. */
1477 [ # # ]: 0 : FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
1478 [ # # ]: 0 : if( aIt != maFragmentPaths.end() )
1479 : : {
1480 : : /* Import the cache stream. This may create a dummy data sheet
1481 : : for external sheet sources. */
1482 [ # # ][ # # ]: 0 : BiffPivotCacheFragment( *this, aIt->second, *pCache ).importFragment();
[ # # ]
1483 : : // remove the fragment entry to mark that the cache is initialized
1484 [ # # ]: 0 : maFragmentPaths.erase( aIt );
1485 : : }
1486 : 0 : return pCache;
1487 : : }
1488 : :
1489 : : case FILTER_UNKNOWN:
1490 : : OSL_FAIL( "PivotCacheBuffer::importPivotCacheFragment - unknown filter type" );
1491 : : }
1492 : 0 : return 0;
1493 : : }
1494 : :
1495 : 0 : PivotCache& PivotCacheBuffer::createPivotCache( sal_Int32 nCacheId )
1496 : : {
1497 : 0 : maCacheIds.push_back( nCacheId );
1498 : 0 : PivotCacheMap::mapped_type& rxCache = maCaches[ nCacheId ];
1499 [ # # ]: 0 : rxCache.reset( new PivotCache( *this ) );
1500 : 0 : return *rxCache;
1501 : : }
1502 : :
1503 : : // ============================================================================
1504 : :
1505 : : } // namespace xls
1506 [ + - ][ + - ]: 24 : } // namespace oox
1507 : :
1508 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|