LCOV - code coverage report
Current view: top level - sc/source/filter/oox - pivotcachebuffer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 4 751 0.5 %
Date: 2012-08-25 Functions: 3 96 3.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 5 1021 0.5 %

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

Generated by: LCOV version 1.10