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