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