/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#include "oox/xls/pivotcachebuffer.hxx"

#include <set>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
#include <com/sun/star/sheet/DataPilotFieldGroupInfo.hpp>
#include <com/sun/star/sheet/XDataPilotFieldGrouping.hpp>
#include <rtl/ustrbuf.hxx>
#include "oox/core/filterbase.hxx"
#include "oox/helper/attributelist.hxx"
#include "oox/helper/containerhelper.hxx"
#include "oox/helper/propertyset.hxx"
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/defnamesbuffer.hxx"
#include "oox/xls/excelhandlers.hxx"
#include "oox/xls/pivotcachefragment.hxx"
#include "oox/xls/sheetdatabuffer.hxx"
#include "oox/xls/tablebuffer.hxx"
#include "oox/xls/unitconverter.hxx"
#include "oox/xls/worksheetbuffer.hxx"

namespace oox {
namespace xls {

// ============================================================================

using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::table;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;

using ::oox::core::Relations;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;

// ============================================================================

namespace {

const sal_uInt16 BIFF12_PCDFIELD_SERVERFIELD        = 0x0001;
const sal_uInt16 BIFF12_PCDFIELD_NOUNIQUEITEMS      = 0x0002;
const sal_uInt16 BIFF12_PCDFIELD_DATABASEFIELD      = 0x0004;
const sal_uInt16 BIFF12_PCDFIELD_HASCAPTION         = 0x0008;
const sal_uInt16 BIFF12_PCDFIELD_MEMBERPROPFIELD    = 0x0010;
const sal_uInt16 BIFF12_PCDFIELD_HASFORMULA         = 0x0100;
const sal_uInt16 BIFF12_PCDFIELD_HASPROPERTYNAME    = 0x0200;

const sal_uInt16 BIFF12_PCDFSITEMS_HASSEMIMIXED     = 0x0001;
const sal_uInt16 BIFF12_PCDFSITEMS_HASNONDATE       = 0x0002;
const sal_uInt16 BIFF12_PCDFSITEMS_HASDATE          = 0x0004;
const sal_uInt16 BIFF12_PCDFSITEMS_HASSTRING        = 0x0008;
const sal_uInt16 BIFF12_PCDFSITEMS_HASBLANK         = 0x0010;
const sal_uInt16 BIFF12_PCDFSITEMS_HASMIXED         = 0x0020;
const sal_uInt16 BIFF12_PCDFSITEMS_ISNUMERIC        = 0x0040;
const sal_uInt16 BIFF12_PCDFSITEMS_ISINTEGER        = 0x0080;
const sal_uInt16 BIFF12_PCDFSITEMS_HASMINMAX        = 0x0100;
const sal_uInt16 BIFF12_PCDFSITEMS_HASLONGTEXT      = 0x0200;

const sal_uInt16 BIFF12_PCITEM_ARRAY_DOUBLE         = 0x0001;
const sal_uInt16 BIFF12_PCITEM_ARRAY_STRING         = 0x0002;
const sal_uInt16 BIFF12_PCITEM_ARRAY_ERROR          = 0x0010;
const sal_uInt16 BIFF12_PCITEM_ARRAY_DATE           = 0x0020;

const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOSTART        = 0x01;
const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOEND          = 0x02;
const sal_uInt8 BIFF12_PCDFRANGEPR_DATEGROUP        = 0x04;

const sal_uInt8 BIFF12_PCDEFINITION_SAVEDATA        = 0x01;
const sal_uInt8 BIFF12_PCDEFINITION_INVALID         = 0x02;
const sal_uInt8 BIFF12_PCDEFINITION_REFRESHONLOAD   = 0x04;
const sal_uInt8 BIFF12_PCDEFINITION_OPTIMIZEMEMORY  = 0x08;
const sal_uInt8 BIFF12_PCDEFINITION_ENABLEREFRESH   = 0x10;
const sal_uInt8 BIFF12_PCDEFINITION_BACKGROUNDQUERY = 0x20;
const sal_uInt8 BIFF12_PCDEFINITION_UPGRADEONREFR   = 0x40;
const sal_uInt8 BIFF12_PCDEFINITION_TUPELCACHE      = 0x80;

const sal_uInt8 BIFF12_PCDEFINITION_HASUSERNAME     = 0x01;
const sal_uInt8 BIFF12_PCDEFINITION_HASRELID        = 0x02;
const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTSUBQUERY = 0x04;
const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTDRILL    = 0x08;

const sal_uInt8 BIFF12_PCDWBSOURCE_HASRELID         = 0x01;
const sal_uInt8 BIFF12_PCDWBSOURCE_HASSHEET         = 0x02;

// ----------------------------------------------------------------------------

const sal_uInt16 BIFF_PCDSOURCE_WORKSHEET           = 0x0001;
const sal_uInt16 BIFF_PCDSOURCE_EXTERNAL            = 0x0002;
const sal_uInt16 BIFF_PCDSOURCE_CONSOLIDATION       = 0x0004;
const sal_uInt16 BIFF_PCDSOURCE_SCENARIO            = 0x0010;

const sal_uInt16 BIFF_PC_NOSTRING                   = 0xFFFF;

const sal_uInt16 BIFF_PCDFIELD_HASITEMS             = 0x0001;
const sal_uInt16 BIFF_PCDFIELD_HASUNSHAREDITEMS     = 0x0002;
const sal_uInt16 BIFF_PCDFIELD_CALCULATED           = 0x0004;
const sal_uInt16 BIFF_PCDFIELD_HASPARENT            = 0x0008;
const sal_uInt16 BIFF_PCDFIELD_RANGEGROUP           = 0x0010;
const sal_uInt16 BIFF_PCDFIELD_ISNUMERIC            = 0x0020;
const sal_uInt16 BIFF_PCDFIELD_HASSEMIMIXED         = 0x0080;
const sal_uInt16 BIFF_PCDFIELD_HASMINMAX            = 0x0100;
const sal_uInt16 BIFF_PCDFIELD_HASLONGINDEX         = 0x0200;
const sal_uInt16 BIFF_PCDFIELD_HASNONDATE           = 0x0400;
const sal_uInt16 BIFF_PCDFIELD_HASDATE              = 0x0800;
const sal_uInt16 BIFF_PCDFIELD_SERVERFIELD          = 0x2000;
const sal_uInt16 BIFF_PCDFIELD_NOUNIQUEITEMS        = 0x4000;

const sal_uInt16 BIFF_PCDFRANGEPR_AUTOSTART         = 0x0001;
const sal_uInt16 BIFF_PCDFRANGEPR_AUTOEND           = 0x0002;

const sal_uInt16 BIFF_PCDEFINITION_SAVEDATA         = 0x0001;
const sal_uInt16 BIFF_PCDEFINITION_INVALID          = 0x0002;
const sal_uInt16 BIFF_PCDEFINITION_REFRESHONLOAD    = 0x0004;
const sal_uInt16 BIFF_PCDEFINITION_OPTIMIZEMEMORY   = 0x0008;
const sal_uInt16 BIFF_PCDEFINITION_BACKGROUNDQUERY  = 0x0010;
const sal_uInt16 BIFF_PCDEFINITION_ENABLEREFRESH    = 0x0020;

// ----------------------------------------------------------------------------

/** Adjusts the weird date format read from binary streams.

    Dates before 1900-Mar-01 are stored including the non-existing leap day
    1900-02-29. Time values (without date) are stored as times of day
    1900-Jan-00. Nothing has to be done when the workbook is stored in 1904
    date mode (dates before 1904-Jan-01 will not occur in this case).
 */
void lclAdjustBinDateTime( DateTime& orDateTime )
{
    if( (orDateTime.Year == 1900) && (orDateTime.Month <= 2) )
    {
        OSL_ENSURE( (orDateTime.Month == 1) || ((orDateTime.Month == 2) && (orDateTime.Day > 0)), "lclAdjustBinDateTime - invalid date" );
        switch( orDateTime.Month )
        {
            case 2: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; --orDateTime.Month; }                       break;
            case 1: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; orDateTime.Month = 12; --orDateTime.Year; } break;
        }
    }
}

} // namespace

// ============================================================================

PivotCacheItem::PivotCacheItem() :
    mnType( XML_m )
{
}

void PivotCacheItem::readString( const AttributeList& rAttribs )
{
    maValue <<= rAttribs.getXString( XML_v, OUString() );
    mnType = XML_s;
}

void PivotCacheItem::readNumeric( const AttributeList& rAttribs )
{
    maValue <<= rAttribs.getDouble( XML_v, 0.0 );
    mnType = XML_n;
}

void PivotCacheItem::readDate( const AttributeList& rAttribs )
{
    maValue <<= rAttribs.getDateTime( XML_v, DateTime() );
    mnType = XML_d;
}

void PivotCacheItem::readBool( const AttributeList& rAttribs )
{
    maValue <<= rAttribs.getBool( XML_v, false );
    mnType = XML_b;
}

void PivotCacheItem::readError( const AttributeList& rAttribs, const UnitConverter& rUnitConverter )
{
    maValue <<= static_cast< sal_Int32 >( rUnitConverter.calcBiffErrorCode( rAttribs.getXString( XML_v, OUString() ) ) );
    mnType = XML_e;
}

void PivotCacheItem::readIndex( const AttributeList& rAttribs )
{
    maValue <<= rAttribs.getInteger( XML_v, -1 );
    mnType = XML_x;
}

void PivotCacheItem::readString( SequenceInputStream& rStrm )
{
    maValue <<= BiffHelper::readString( rStrm );
    mnType = XML_s;
}

void PivotCacheItem::readDouble( SequenceInputStream& rStrm )
{
    maValue <<= rStrm.readDouble();
    mnType = XML_n;
}

void PivotCacheItem::readDate( SequenceInputStream& rStrm )
{
    DateTime aDateTime;
    aDateTime.Year = rStrm.readuInt16();
    aDateTime.Month = rStrm.readuInt16();
    aDateTime.Day = rStrm.readuInt8();
    aDateTime.Hours = rStrm.readuInt8();
    aDateTime.Minutes = rStrm.readuInt8();
    aDateTime.Seconds = rStrm.readuInt8();
    lclAdjustBinDateTime( aDateTime );
    maValue <<= aDateTime;
    mnType = XML_d;
}

void PivotCacheItem::readBool( SequenceInputStream& rStrm )
{
    maValue <<= (rStrm.readuInt8() != 0);
    mnType = XML_b;
}

void PivotCacheItem::readError( SequenceInputStream& rStrm )
{
    maValue <<= static_cast< sal_Int32 >( rStrm.readuInt8() );
    mnType = XML_e;
}

void PivotCacheItem::readIndex( SequenceInputStream& rStrm )
{
    maValue <<= rStrm.readInt32();
    mnType = XML_x;
}

void PivotCacheItem::readString( BiffInputStream& rStrm, const WorkbookHelper& rHelper )
{
    maValue <<= (rHelper.getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( true, rHelper.getTextEncoding() );
    mnType = XML_s;
}

void PivotCacheItem::readDouble( BiffInputStream& rStrm )
{
    maValue <<= rStrm.readDouble();
    mnType = XML_n;
}

void PivotCacheItem::readInteger( BiffInputStream& rStrm )
{
    maValue <<= rStrm.readInt16();
    mnType = XML_i;                 // fake, used for BIFF only
}

void PivotCacheItem::readDate( BiffInputStream& rStrm )
{
    DateTime aDateTime;
    aDateTime.Year = rStrm.readuInt16();
    aDateTime.Month = rStrm.readuInt16();
    aDateTime.Day = rStrm.readuInt8();
    aDateTime.Hours = rStrm.readuInt8();
    aDateTime.Minutes = rStrm.readuInt8();
    aDateTime.Seconds = rStrm.readuInt8();
    lclAdjustBinDateTime( aDateTime );
    maValue <<= aDateTime;
    mnType = XML_d;
}

void PivotCacheItem::readBool( BiffInputStream& rStrm )
{
    maValue <<= (rStrm.readuInt8() != 0);
    mnType = XML_b;
}

void PivotCacheItem::readError( BiffInputStream& rStrm )
{
    maValue <<= static_cast< sal_Int32 >( rStrm.readuInt8() );
    mnType = XML_e;
}

OUString PivotCacheItem::getName() const
{
    switch( mnType )
    {
        case XML_m: return OUString();
        case XML_s: return maValue.get< OUString >();
        case XML_n: return OUString::valueOf( maValue.get< double >() );                            // !TODO
        case XML_i: return OUString::valueOf( maValue.get< sal_Int32 >() );
        case XML_d: return OUString();                                                              // !TODO
        case XML_b: return OUString::valueOf( static_cast< sal_Bool >( maValue.get< bool >() ) );   // !TODO
        case XML_e: return OUString();                                                              // !TODO
    }
    OSL_ENSURE( false, "PivotCacheItem::getName - invalid data type" );
    return OUString();
}

// ----------------------------------------------------------------------------

PivotCacheItemList::PivotCacheItemList( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper )
{
}

void PivotCacheItemList::importItem( sal_Int32 nElement, const AttributeList& rAttribs )
{
    PivotCacheItem& rItem = createItem();
    switch( nElement )
    {
        case XLS_TOKEN( m ):                                                        break;
        case XLS_TOKEN( s ):    rItem.readString( rAttribs );                       break;
        case XLS_TOKEN( n ):    rItem.readNumeric( rAttribs );                      break;
        case XLS_TOKEN( d ):    rItem.readDate( rAttribs );                         break;
        case XLS_TOKEN( b ):    rItem.readBool( rAttribs );                         break;
        case XLS_TOKEN( e ):    rItem.readError( rAttribs, getUnitConverter() );    break;
        default:    OSL_ENSURE( false, "PivotCacheItemList::importItem - unknown element type" );
    }
}

void PivotCacheItemList::importItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    if( nRecId == BIFF12_ID_PCITEM_ARRAY )
    {
        importArray( rStrm );
        return;
    }

    PivotCacheItem& rItem = createItem();
    switch( nRecId )
    {
        case BIFF12_ID_PCITEM_MISSING:
        case BIFF12_ID_PCITEMA_MISSING:                             break;
        case BIFF12_ID_PCITEM_STRING:
        case BIFF12_ID_PCITEMA_STRING:  rItem.readString( rStrm );  break;
        case BIFF12_ID_PCITEM_DOUBLE:
        case BIFF12_ID_PCITEMA_DOUBLE:  rItem.readDouble( rStrm );  break;
        case BIFF12_ID_PCITEM_DATE:
        case BIFF12_ID_PCITEMA_DATE:    rItem.readDate( rStrm );    break;
        case BIFF12_ID_PCITEM_BOOL:
        case BIFF12_ID_PCITEMA_BOOL:    rItem.readBool( rStrm );    break;
        case BIFF12_ID_PCITEM_ERROR:
        case BIFF12_ID_PCITEMA_ERROR:   rItem.readError( rStrm );   break;
        default:    OSL_ENSURE( false, "PivotCacheItemList::importItem - unknown record type" );
    }
}

void PivotCacheItemList::importItemList( BiffInputStream& rStrm, sal_uInt16 nCount )
{
    bool bLoop = true;
    for( sal_uInt16 nItemIdx = 0; bLoop && (nItemIdx < nCount); ++nItemIdx )
    {
        bLoop = rStrm.startNextRecord();
        if( bLoop ) switch( rStrm.getRecId() )
        {
            case BIFF_ID_PCITEM_MISSING:    createItem();                               break;
            case BIFF_ID_PCITEM_STRING:     createItem().readString( rStrm, *this );    break;
            case BIFF_ID_PCITEM_DOUBLE:     createItem().readDouble( rStrm );           break;
            case BIFF_ID_PCITEM_INTEGER:    createItem().readInteger( rStrm );          break;
            case BIFF_ID_PCITEM_DATE:       createItem().readDate( rStrm );             break;
            case BIFF_ID_PCITEM_BOOL:       createItem().readBool( rStrm );             break;
            case BIFF_ID_PCITEM_ERROR:      createItem().readError( rStrm );            break;
            default:                        rStrm.rewindRecord(); bLoop = false;
        }
    }
    OSL_ENSURE( bLoop, "PivotCacheItemList::importItemList - could not read all cache item records" );
}

const PivotCacheItem* PivotCacheItemList::getCacheItem( sal_Int32 nItemIdx ) const
{
    return ContainerHelper::getVectorElement( maItems, nItemIdx );
}

void PivotCacheItemList::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
{
    orItemNames.clear();
    orItemNames.reserve( maItems.size() );
    for( CacheItemVector::const_iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
        orItemNames.push_back( aIt->getName() );
}

// private --------------------------------------------------------------------

PivotCacheItem& PivotCacheItemList::createItem()
{
    maItems.resize( maItems.size() + 1 );
    return maItems.back();
}

void PivotCacheItemList::importArray( SequenceInputStream& rStrm )
{
    sal_uInt16 nType = rStrm.readuInt16();
    sal_Int32 nCount = rStrm.readInt32();
    for( sal_Int32 nIdx = 0; !rStrm.isEof() && (nIdx < nCount); ++nIdx )
    {
        switch( nType )
        {
            case BIFF12_PCITEM_ARRAY_DOUBLE: createItem().readDouble( rStrm );   break;
            case BIFF12_PCITEM_ARRAY_STRING: createItem().readString( rStrm );   break;
            case BIFF12_PCITEM_ARRAY_ERROR:  createItem().readError( rStrm );    break;
            case BIFF12_PCITEM_ARRAY_DATE:   createItem().readDate( rStrm );     break;
            default:
                OSL_ENSURE( false, "PivotCacheItemList::importArray - unknown data type" );
                nIdx = nCount;
        }
    }
}

// ============================================================================

PCFieldModel::PCFieldModel() :
    mnNumFmtId( 0 ),
    mnSqlType( 0 ),
    mnHierarchy( 0 ),
    mnLevel( 0 ),
    mnMappingCount( 0 ),
    mbDatabaseField( true ),
    mbServerField( false ),
    mbUniqueList( true ),
    mbMemberPropField( false )
{
}

// ----------------------------------------------------------------------------

PCSharedItemsModel::PCSharedItemsModel() :
    mbHasSemiMixed( true ),
    mbHasNonDate( true ),
    mbHasDate( false ),
    mbHasString( true ),
    mbHasBlank( false ),
    mbHasMixed( false ),
    mbIsNumeric( false ),
    mbIsInteger( false ),
    mbHasLongText( false ),
    mbHasLongIndexes( false )
{
}

// ----------------------------------------------------------------------------

PCFieldGroupModel::PCFieldGroupModel() :
    mfStartValue( 0.0 ),
    mfEndValue( 0.0 ),
    mfInterval( 1.0 ),
    mnParentField( -1 ),
    mnBaseField( -1 ),
    mnGroupBy( XML_range ),
    mbRangeGroup( false ),
    mbDateGroup( false ),
    mbAutoStart( true ),
    mbAutoEnd( true )
{
}

void PCFieldGroupModel::setBiffGroupBy( sal_uInt8 nGroupBy )
{
    static const sal_Int32 spnGroupBy[] = { XML_range,
        XML_seconds, XML_minutes, XML_hours, XML_days, XML_months, XML_quarters, XML_years };
    mnGroupBy = STATIC_ARRAY_SELECT( spnGroupBy, nGroupBy, XML_range );
}

// ----------------------------------------------------------------------------

PivotCacheField::PivotCacheField( const WorkbookHelper& rHelper, bool bIsDatabaseField ) :
    WorkbookHelper( rHelper ),
    maSharedItems( rHelper ),
    maGroupItems( rHelper )
{
    maFieldModel.mbDatabaseField = bIsDatabaseField;
}

void PivotCacheField::importCacheField( const AttributeList& rAttribs )
{
    maFieldModel.maName            = rAttribs.getXString( XML_name, OUString() );
    maFieldModel.maCaption         = rAttribs.getXString( XML_caption, OUString() );
    maFieldModel.maPropertyName    = rAttribs.getXString( XML_propertyName, OUString() );
    maFieldModel.maFormula         = rAttribs.getXString( XML_formula, OUString() );
    maFieldModel.mnNumFmtId        = rAttribs.getInteger( XML_numFmtId, 0 );
    maFieldModel.mnSqlType         = rAttribs.getInteger( XML_sqlType, 0 );
    maFieldModel.mnHierarchy       = rAttribs.getInteger( XML_hierarchy, 0 );
    maFieldModel.mnLevel           = rAttribs.getInteger( XML_level, 0 );
    maFieldModel.mnMappingCount    = rAttribs.getInteger( XML_mappingCount, 0 );
    maFieldModel.mbDatabaseField   = rAttribs.getBool( XML_databaseField, true );
    maFieldModel.mbServerField     = rAttribs.getBool( XML_serverField, false );
    maFieldModel.mbUniqueList      = rAttribs.getBool( XML_uniqueList, true );
    maFieldModel.mbMemberPropField = rAttribs.getBool( XML_memberPropertyField, false );
}

void PivotCacheField::importSharedItems( const AttributeList& rAttribs )
{
    OSL_ENSURE( maSharedItems.empty(), "PivotCacheField::importSharedItems - multiple shared items elements" );
    maSharedItemsModel.mbHasSemiMixed = rAttribs.getBool( XML_containsSemiMixedTypes, true );
    maSharedItemsModel.mbHasNonDate   = rAttribs.getBool( XML_containsNonDate, true );
    maSharedItemsModel.mbHasDate      = rAttribs.getBool( XML_containsDate, false );
    maSharedItemsModel.mbHasString    = rAttribs.getBool( XML_containsString, true );
    maSharedItemsModel.mbHasBlank     = rAttribs.getBool( XML_containsBlank, false );
    maSharedItemsModel.mbHasMixed     = rAttribs.getBool( XML_containsMixedTypes, false );
    maSharedItemsModel.mbIsNumeric    = rAttribs.getBool( XML_containsNumber, false );
    maSharedItemsModel.mbIsInteger    = rAttribs.getBool( XML_containsInteger, false );
    maSharedItemsModel.mbHasLongText  = rAttribs.getBool( XML_longText, false );
}

void PivotCacheField::importSharedItem( sal_Int32 nElement, const AttributeList& rAttribs )
{
    maSharedItems.importItem( nElement, rAttribs );
}

void PivotCacheField::importFieldGroup( const AttributeList& rAttribs )
{
    maFieldGroupModel.mnParentField = rAttribs.getInteger( XML_par, -1 );
    maFieldGroupModel.mnBaseField   = rAttribs.getInteger( XML_base, -1 );
}

void PivotCacheField::importRangePr( const AttributeList& rAttribs )
{
    maFieldGroupModel.maStartDate    = rAttribs.getDateTime( XML_startDate, DateTime() );
    maFieldGroupModel.maEndDate      = rAttribs.getDateTime( XML_endDate, DateTime() );
    maFieldGroupModel.mfStartValue   = rAttribs.getDouble( XML_startNum, 0.0 );
    maFieldGroupModel.mfEndValue     = rAttribs.getDouble( XML_endNum, 0.0 );
    maFieldGroupModel.mfInterval     = rAttribs.getDouble( XML_groupInterval, 1.0 );
    maFieldGroupModel.mnGroupBy      = rAttribs.getToken( XML_groupBy, XML_range );
    maFieldGroupModel.mbRangeGroup   = true;
    maFieldGroupModel.mbDateGroup    = maFieldGroupModel.mnGroupBy != XML_range;
    maFieldGroupModel.mbAutoStart    = rAttribs.getBool( XML_autoStart, true );
    maFieldGroupModel.mbAutoEnd      = rAttribs.getBool( XML_autoEnd, true );
}

void PivotCacheField::importDiscretePrItem( sal_Int32 nElement, const AttributeList& rAttribs )
{
    OSL_ENSURE( nElement == XLS_TOKEN( x ), "PivotCacheField::importDiscretePrItem - unexpected element" );
    if( nElement == XLS_TOKEN( x ) )
        maDiscreteItems.push_back( rAttribs.getInteger( XML_v, -1 ) );
}

void PivotCacheField::importGroupItem( sal_Int32 nElement, const AttributeList& rAttribs )
{
    maGroupItems.importItem( nElement, rAttribs );
}

void PivotCacheField::importPCDField( SequenceInputStream& rStrm )
{
    sal_uInt16 nFlags;
    rStrm >> nFlags >> maFieldModel.mnNumFmtId;
    maFieldModel.mnSqlType = rStrm.readInt16();
    rStrm >> maFieldModel.mnHierarchy >> maFieldModel.mnLevel >> maFieldModel.mnMappingCount >> maFieldModel.maName;
    if( getFlag( nFlags, BIFF12_PCDFIELD_HASCAPTION ) )
        rStrm >> maFieldModel.maCaption;
    if( getFlag( nFlags, BIFF12_PCDFIELD_HASFORMULA ) )
        rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
    if( maFieldModel.mnMappingCount > 0 )
        rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
    if( getFlag( nFlags, BIFF12_PCDFIELD_HASPROPERTYNAME ) )
        rStrm >> maFieldModel.maPropertyName;

    maFieldModel.mbDatabaseField   = getFlag( nFlags, BIFF12_PCDFIELD_DATABASEFIELD );
    maFieldModel.mbServerField     = getFlag( nFlags, BIFF12_PCDFIELD_SERVERFIELD );
    maFieldModel.mbUniqueList      = !getFlag( nFlags, BIFF12_PCDFIELD_NOUNIQUEITEMS );
    maFieldModel.mbMemberPropField = getFlag( nFlags, BIFF12_PCDFIELD_MEMBERPROPFIELD );
}

void PivotCacheField::importPCDFSharedItems( SequenceInputStream& rStrm )
{
    sal_uInt16 nFlags;
    rStrm >> nFlags;
    maSharedItemsModel.mbHasSemiMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSEMIMIXED );
    maSharedItemsModel.mbHasNonDate   = getFlag( nFlags, BIFF12_PCDFSITEMS_HASNONDATE );
    maSharedItemsModel.mbHasDate      = getFlag( nFlags, BIFF12_PCDFSITEMS_HASDATE );
    maSharedItemsModel.mbHasString    = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSTRING );
    maSharedItemsModel.mbHasBlank     = getFlag( nFlags, BIFF12_PCDFSITEMS_HASBLANK );
    maSharedItemsModel.mbHasMixed     = getFlag( nFlags, BIFF12_PCDFSITEMS_HASMIXED );
    maSharedItemsModel.mbIsNumeric    = getFlag( nFlags, BIFF12_PCDFSITEMS_ISNUMERIC );
    maSharedItemsModel.mbIsInteger    = getFlag( nFlags, BIFF12_PCDFSITEMS_ISINTEGER );
    maSharedItemsModel.mbHasLongText  = getFlag( nFlags, BIFF12_PCDFSITEMS_HASLONGTEXT );
}

void PivotCacheField::importPCDFSharedItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    maSharedItems.importItem( nRecId, rStrm );
}

void PivotCacheField::importPCDFieldGroup( SequenceInputStream& rStrm )
{
    rStrm >> maFieldGroupModel.mnParentField >> maFieldGroupModel.mnBaseField;
}

void PivotCacheField::importPCDFRangePr( SequenceInputStream& rStrm )
{
    sal_uInt8 nGroupBy, nFlags;
    rStrm >> nGroupBy >> nFlags >> maFieldGroupModel.mfStartValue >> maFieldGroupModel.mfEndValue >> maFieldGroupModel.mfInterval;

    maFieldGroupModel.setBiffGroupBy( nGroupBy );
    maFieldGroupModel.mbRangeGroup   = true;
    maFieldGroupModel.mbDateGroup    = getFlag( nFlags, BIFF12_PCDFRANGEPR_DATEGROUP );
    maFieldGroupModel.mbAutoStart    = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOSTART );
    maFieldGroupModel.mbAutoEnd      = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOEND );

    OSL_ENSURE( maFieldGroupModel.mbDateGroup == (maFieldGroupModel.mnGroupBy != XML_range), "PivotCacheField::importPCDFRangePr - wrong date flag" );
    if( maFieldGroupModel.mbDateGroup )
    {
        maFieldGroupModel.maStartDate = getUnitConverter().calcDateTimeFromSerial( maFieldGroupModel.mfStartValue );
        maFieldGroupModel.maEndDate   = getUnitConverter().calcDateTimeFromSerial( maFieldGroupModel.mfEndValue );
    }
}

void PivotCacheField::importPCDFDiscretePrItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    OSL_ENSURE( nRecId == BIFF12_ID_PCITEM_INDEX, "PivotCacheField::importPCDFDiscretePrItem - unexpected record" );
    if( nRecId == BIFF12_ID_PCITEM_INDEX )
        maDiscreteItems.push_back( rStrm.readInt32() );
}

void PivotCacheField::importPCDFGroupItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    maGroupItems.importItem( nRecId, rStrm );
}

void PivotCacheField::importPCDField( BiffInputStream& rStrm )
{
    sal_uInt16 nFlags, nGroupItems, nBaseItems, nSharedItems;
    rStrm >> nFlags;
    maFieldGroupModel.mnParentField  = rStrm.readuInt16();
    maFieldGroupModel.mnBaseField    = rStrm.readuInt16();
    rStrm.skip( 2 );    // number of unique items (either shared or group)
    rStrm >> nGroupItems >> nBaseItems >> nSharedItems;
    maFieldModel.maName = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( true, getTextEncoding() );

    maFieldModel.mbServerField          = getFlag( nFlags, BIFF_PCDFIELD_SERVERFIELD );
    maFieldModel.mbUniqueList           = !getFlag( nFlags, BIFF_PCDFIELD_NOUNIQUEITEMS );
    maSharedItemsModel.mbHasSemiMixed   = getFlag( nFlags, BIFF_PCDFIELD_HASSEMIMIXED );
    maSharedItemsModel.mbHasNonDate     = getFlag( nFlags, BIFF_PCDFIELD_HASNONDATE );
    maSharedItemsModel.mbHasDate        = getFlag( nFlags, BIFF_PCDFIELD_HASDATE );
    maSharedItemsModel.mbIsNumeric      = getFlag( nFlags, BIFF_PCDFIELD_ISNUMERIC );
    maSharedItemsModel.mbHasLongIndexes = getFlag( nFlags, BIFF_PCDFIELD_HASLONGINDEX );
    maFieldGroupModel.mbRangeGroup      = getFlag( nFlags, BIFF_PCDFIELD_RANGEGROUP );

    // in BIFF, presence of parent group field is denoted by a flag
    if( !getFlag( nFlags, BIFF_PCDFIELD_HASPARENT ) )
        maFieldGroupModel.mnParentField = -1;

    // following PCDFSQLTYPE record contains SQL type
    if( (rStrm.getNextRecId() == BIFF_ID_PCDFSQLTYPE) && rStrm.startNextRecord() )
        maFieldModel.mnSqlType = rStrm.readInt16();

    // read group items, if any
    if( nGroupItems > 0 )
    {
        OSL_ENSURE( getFlag( nFlags, BIFF_PCDFIELD_HASITEMS ), "PivotCacheField::importPCDField - missing items flag" );
        maGroupItems.importItemList( rStrm, nGroupItems );

        sal_uInt16 nNextRecId = rStrm.getNextRecId();
        bool bHasRangePr = nNextRecId == BIFF_ID_PCDFRANGEPR;
        bool bHasDiscretePr = nNextRecId == BIFF_ID_PCDFDISCRETEPR;

        OSL_ENSURE( bHasRangePr || bHasDiscretePr, "PivotCacheField::importPCDField - missing group properties record" );
        OSL_ENSURE( bHasRangePr == maFieldGroupModel.mbRangeGroup, "PivotCacheField::importPCDField - invalid range grouping flag" );
        if( bHasRangePr && rStrm.startNextRecord() )
            importPCDFRangePr( rStrm );
        else if( bHasDiscretePr && rStrm.startNextRecord() )
            importPCDFDiscretePr( rStrm );
    }

    // read the shared items, if any
    if( nSharedItems > 0 )
    {
        OSL_ENSURE( getFlag( nFlags, BIFF_PCDFIELD_HASITEMS ), "PivotCacheField::importPCDField - missing items flag" );
        maSharedItems.importItemList( rStrm, nSharedItems );
    }
}

void PivotCacheField::importPCDFRangePr( BiffInputStream& rStrm )
{
    sal_uInt16 nFlags;
    rStrm >> nFlags;
    maFieldGroupModel.setBiffGroupBy( extractValue< sal_uInt8 >( nFlags, 2, 3 ) );
    maFieldGroupModel.mbRangeGroup = true;
    maFieldGroupModel.mbDateGroup  = maFieldGroupModel.mnGroupBy != XML_range;
    maFieldGroupModel.mbAutoStart  = getFlag( nFlags, BIFF_PCDFRANGEPR_AUTOSTART );
    maFieldGroupModel.mbAutoEnd    = getFlag( nFlags, BIFF_PCDFRANGEPR_AUTOEND );

    /*  Start, end, and interval are stored in 3 separate item records. Type of
        the items is dependent on numeric/date mode. Numeric groups expect
        three PCITEM_DOUBLE records, date groups expect two PCITEM_DATE records
        and one PCITEM_INT record. */
    PivotCacheItemList aLimits( *this );
    aLimits.importItemList( rStrm, 3 );
    OSL_ENSURE( aLimits.size() == 3, "PivotCacheField::importPCDFRangePr - missing grouping records" );
    const PivotCacheItem* pStartValue = aLimits.getCacheItem( 0 );
    const PivotCacheItem* pEndValue = aLimits.getCacheItem( 1 );
    const PivotCacheItem* pInterval = aLimits.getCacheItem( 2 );
    if( pStartValue && pEndValue && pInterval )
    {
        if( maFieldGroupModel.mbDateGroup )
        {
            bool bHasTypes = (pStartValue->getType() == XML_d) && (pEndValue->getType() == XML_d) && (pInterval->getType() == XML_i);
            OSL_ENSURE( bHasTypes, "PivotCacheField::importPCDFRangePr - wrong data types in grouping items" );
            if( bHasTypes )
            {
                maFieldGroupModel.maStartDate = pStartValue->getValue().get< DateTime >();
                maFieldGroupModel.maEndDate   = pEndValue->getValue().get< DateTime >();
                maFieldGroupModel.mfInterval  = pInterval->getValue().get< sal_Int16 >();
            }
        }
        else
        {
            bool bHasTypes = (pStartValue->getType() == XML_n) && (pEndValue->getType() == XML_n) && (pInterval->getType() == XML_n);
            OSL_ENSURE( bHasTypes, "PivotCacheField::importPCDFRangePr - wrong data types in grouping items" );
            if( bHasTypes )
            {
                maFieldGroupModel.mfStartValue = pStartValue->getValue().get< double >();
                maFieldGroupModel.mfEndValue   = pEndValue->getValue().get< double >();
                maFieldGroupModel.mfInterval   = pInterval->getValue().get< double >();
            }
        }
    }
}

void PivotCacheField::importPCDFDiscretePr( BiffInputStream& rStrm )
{
    sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.size() / 2 );
    for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
        maDiscreteItems.push_back( rStrm.readuInt16() );
}

const PivotCacheItem* PivotCacheField::getCacheItem( sal_Int32 nItemIdx ) const
{
    if( hasGroupItems() )
        return maGroupItems.getCacheItem( nItemIdx );
    if( hasSharedItems() )
        return maSharedItems.getCacheItem( nItemIdx );
    return 0;
}

void PivotCacheField::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
{
    if( hasGroupItems() )
        maGroupItems.getCacheItemNames( orItemNames );
    else if( hasSharedItems() )
        maSharedItems.getCacheItemNames( orItemNames );
}

void PivotCacheField::convertNumericGrouping( const Reference< XDataPilotField >& rxDPField ) const
{
    OSL_ENSURE( hasGroupItems() && hasNumericGrouping(), "PivotCacheField::convertNumericGrouping - not a numeric group field" );
    PropertySet aPropSet( rxDPField );
    if( hasGroupItems() && hasNumericGrouping() && aPropSet.is() )
    {
        DataPilotFieldGroupInfo aGroupInfo;
        aGroupInfo.HasAutoStart  = maFieldGroupModel.mbAutoStart;
        aGroupInfo.HasAutoEnd    = maFieldGroupModel.mbAutoEnd;
        aGroupInfo.HasDateValues = sal_False;
        aGroupInfo.Start         = maFieldGroupModel.mfStartValue;
        aGroupInfo.End           = maFieldGroupModel.mfEndValue;
        aGroupInfo.Step          = maFieldGroupModel.mfInterval;
        aGroupInfo.GroupBy       = 0;
        aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
    }
}

OUString PivotCacheField::createDateGroupField( const Reference< XDataPilotField >& rxBaseDPField ) const
{
    OSL_ENSURE( hasGroupItems() && hasDateGrouping(), "PivotCacheField::createDateGroupField - not a numeric group field" );
    Reference< XDataPilotField > xDPGroupField;
    PropertySet aPropSet( rxBaseDPField );
    if( hasGroupItems() && hasDateGrouping() && aPropSet.is() )
    {
        bool bDayRanges = (maFieldGroupModel.mnGroupBy == XML_days) && (maFieldGroupModel.mfInterval >= 2.0);

        DataPilotFieldGroupInfo aGroupInfo;
        aGroupInfo.HasAutoStart  = maFieldGroupModel.mbAutoStart;
        aGroupInfo.HasAutoEnd    = maFieldGroupModel.mbAutoEnd;
        aGroupInfo.HasDateValues = sal_True;
        aGroupInfo.Start         = getUnitConverter().calcSerialFromDateTime( maFieldGroupModel.maStartDate );
        aGroupInfo.End           = getUnitConverter().calcSerialFromDateTime( maFieldGroupModel.maEndDate );
        aGroupInfo.Step          = bDayRanges ? maFieldGroupModel.mfInterval : 0.0;

        using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
        switch( maFieldGroupModel.mnGroupBy )
        {
            case XML_years:     aGroupInfo.GroupBy = YEARS;     break;
            case XML_quarters:  aGroupInfo.GroupBy = QUARTERS;  break;
            case XML_months:    aGroupInfo.GroupBy = MONTHS;    break;
            case XML_days:      aGroupInfo.GroupBy = DAYS;      break;
            case XML_hours:     aGroupInfo.GroupBy = HOURS;     break;
            case XML_minutes:   aGroupInfo.GroupBy = MINUTES;   break;
            case XML_seconds:   aGroupInfo.GroupBy = SECONDS;   break;
            default:    OSL_ENSURE( false, "PivotCacheField::convertRangeGrouping - unknown date/time interval" );
        }

        try
        {
            Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY_THROW );
            xDPGroupField = xDPGrouping->createDateGroup( aGroupInfo );
        }
        catch( Exception& )
        {
        }
    }

    Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
    return xFieldName.is() ? xFieldName->getName() : OUString();
}

OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotField >& rxBaseDPField, PivotCacheGroupItemVector& orItemNames ) const
{
    OSL_ENSURE( hasGroupItems() && !maDiscreteItems.empty(), "PivotCacheField::createParentGroupField - not a group field" );
    OSL_ENSURE( maDiscreteItems.size() == orItemNames.size(), "PivotCacheField::createParentGroupField - number of item names does not match grouping info" );
    Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY );
    if( !xDPGrouping.is() ) return OUString();

    // map the group item indexes from maGroupItems to all item indexes from maDiscreteItems
    typedef ::std::vector< sal_Int32 > GroupItemList;
    typedef ::std::vector< GroupItemList > GroupItemMap;
    GroupItemMap aItemMap( maGroupItems.size() );
    for( IndexVector::const_iterator aBeg = maDiscreteItems.begin(), aIt = aBeg, aEnd = maDiscreteItems.end(); aIt != aEnd; ++aIt )
        if( GroupItemList* pItems = ContainerHelper::getVectorElementAccess( aItemMap, *aIt ) )
            pItems->push_back( static_cast< sal_Int32 >( aIt - aBeg ) );

    // process all groups
    Reference< XDataPilotField > xDPGroupField;
    for( GroupItemMap::iterator aBeg = aItemMap.begin(), aIt = aBeg, aEnd = aItemMap.end(); aIt != aEnd; ++aIt )
    {
        OSL_ENSURE( !aIt->empty(), "PivotCacheField::createParentGroupField - item/group should not be empty" );
        // if the item count is greater than 1, the item is a group of items
        if( aIt->size() > 1 )
        {
            /*  Insert the names of the items that are part of this group. Calc
                expects the names of the members of the field whose members are
                grouped (which may be the names of groups too). Excel provides
                the names of the base field items instead (no group names
                involved). Therefore, the passed collection of current item
                names as they are already grouped is used here to resolve the
                item names. */
            ::std::vector< OUString > aMembers;
            for( GroupItemList::iterator aBeg2 = aIt->begin(), aIt2 = aBeg2, aEnd2 = aIt->end(); aIt2 != aEnd2; ++aIt2 )
                if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, *aIt2 ) )
                    if( ::std::find( aMembers.begin(), aMembers.end(), pName->maGroupName ) == aMembers.end() )
                        aMembers.push_back( pName->maGroupName );

            /*  Check again, that this is not just a group that is not grouped
                further with other items. */
            if( aMembers.size() > 1 ) try
            {
                // only the first call of createNameGroup() returns the new field
                Reference< XDataPilotField > xDPNewField = xDPGrouping->createNameGroup( ContainerHelper::vectorToSequence( aMembers ) );
                OSL_ENSURE( xDPGroupField.is() != xDPNewField.is(), "PivotCacheField::createParentGroupField - missing group field" );
                if( !xDPGroupField.is() )
                    xDPGroupField = xDPNewField;

                // get current grouping info
                DataPilotFieldGroupInfo aGroupInfo;
                PropertySet aPropSet( xDPGroupField );
                aPropSet.getProperty( aGroupInfo, PROP_GroupInfo );

                /*  Find the group object and the auto-generated group name.
                    The returned field contains all groups derived from the
                    previous field if that is grouped too. To find the correct
                    group, the first item used to create the group is serached.
                    Calc provides the original item names of the base field
                    when the group is querried for its members. Its does not
                    provide the names of members that are already groups in the
                    field used to create the new groups. (Is this a bug?)
                    Therefore, a name from the passed list of original item
                    names is used to find the correct group. */
                OUString aFirstItem;
                if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, aIt->front() ) )
                    aFirstItem = pName->maOrigName;
                Reference< XNamed > xGroupName;
                OUString aAutoName;
                Reference< XIndexAccess > xGroupsIA( aGroupInfo.Groups, UNO_QUERY_THROW );
                for( sal_Int32 nIdx = 0, nCount = xGroupsIA->getCount(); (nIdx < nCount) && (aAutoName.getLength() == 0); ++nIdx ) try
                {
                    Reference< XNameAccess > xItemsNA( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
                    if( xItemsNA->hasByName( aFirstItem ) )
                    {
                        xGroupName.set( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
                        aAutoName = xGroupName->getName();
                    }
                }
                catch( Exception& )
                {
                }
                OSL_ENSURE( aAutoName.getLength() > 0, "PivotCacheField::createParentGroupField - cannot find auto-generated group name" );

                // get the real group name from the list of group items
                OUString aGroupName;
                if( const PivotCacheItem* pGroupItem = maGroupItems.getCacheItem( static_cast< sal_Int32 >( aIt - aBeg ) ) )
                    aGroupName = pGroupItem->getName();
                OSL_ENSURE( aGroupName.getLength() > 0, "PivotCacheField::createParentGroupField - cannot find group name" );
                if( aGroupName.getLength() == 0 )
                    aGroupName = aAutoName;

                if( xGroupName.is() && (aGroupName.getLength() > 0) )
                {
                    // replace the auto-generated group name with the real name
                    if( aAutoName != aGroupName )
                    {
                        xGroupName->setName( aGroupName );
                        aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
                    }
                    // replace original item names in passed vector with group name
                    for( GroupItemList::iterator aIt2 = aIt->begin(), aEnd2 = aIt->end(); aIt2 != aEnd2; ++aIt2 )
                        if( PivotCacheGroupItem* pName = ContainerHelper::getVectorElementAccess( orItemNames, *aIt2 ) )
                            pName->maGroupName = aGroupName;
                }
            }
            catch( Exception& )
            {
            }
        }
    }

    Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
    return xFieldName.is() ? xFieldName->getName() : OUString();
}

void PivotCacheField::writeSourceHeaderCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
{
    CellModel aModel;
    aModel.maCellAddr = CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow );
    rSheetHelper.getSheetData().setStringCell( aModel, maFieldModel.maName );
}

void PivotCacheField::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
{
    bool bHasIndex = rItem.getType() == XML_x;
    OSL_ENSURE( bHasIndex != maSharedItems.empty(), "PivotCacheField::writeSourceDataCell - shared items missing or not expected" );
    if( bHasIndex )
        writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem.getValue().get< sal_Int32 >() );
    else
        writeItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem );
}

void PivotCacheField::importPCRecordItem( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
{
    if( hasSharedItems() )
    {
        writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rStrm.readInt32() );
    }
    else
    {
        PivotCacheItem aItem;
        if( maSharedItemsModel.mbIsNumeric )
           aItem.readDouble( rStrm );
        else if( maSharedItemsModel.mbHasDate && !maSharedItemsModel.mbHasString )
           aItem.readDate( rStrm );
        else
           aItem.readString( rStrm );
        writeItemToSourceDataCell( rSheetHelper, nCol, nRow, aItem );
    }
}

void PivotCacheField::importPCItemIndex( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
{
    OSL_ENSURE( hasSharedItems(), "PivotCacheField::importPCItemIndex - invalid call, no shared items found" );
    sal_Int32 nIndex = maSharedItemsModel.mbHasLongIndexes ? rStrm.readuInt16() : rStrm.readuInt8();
    writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, nIndex );
}

// private --------------------------------------------------------------------

void PivotCacheField::writeItemToSourceDataCell( WorksheetHelper& rSheetHelper,
        sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
{
    if( rItem.getType() != XML_m )
    {
        CellModel aModel;
        aModel.maCellAddr = CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow );
        SheetDataBuffer& rSheetData = rSheetHelper.getSheetData();
        switch( rItem.getType() )
        {
            case XML_s: rSheetData.setStringCell( aModel, rItem.getValue().get< OUString >() );                             break;
            case XML_n: rSheetData.setValueCell( aModel, rItem.getValue().get< double >() );                                break;
            case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< sal_Int16 >() );                             break;
            case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< DateTime >() );                           break;
            case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< bool >() );                                break;
            case XML_e: rSheetData.setErrorCell( aModel, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break;
            default:    OSL_ENSURE( false, "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" );
        }
    }
}

void PivotCacheField::writeSharedItemToSourceDataCell(
        WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nItemIdx ) const
{
    if( const PivotCacheItem* pCacheItem = maSharedItems.getCacheItem( nItemIdx ) )
        writeItemToSourceDataCell( rSheetHelper, nCol, nRow, *pCacheItem );
}

// ============================================================================

PCDefinitionModel::PCDefinitionModel() :
    mfRefreshedDate( 0.0 ),
    mnRecords( 0 ),
    mnMissItemsLimit( 0 ),
    mnDatabaseFields( 0 ),
    mbInvalid( false ),
    mbSaveData( true ),
    mbRefreshOnLoad( false ),
    mbOptimizeMemory( false ),
    mbEnableRefresh( true ),
    mbBackgroundQuery( false ),
    mbUpgradeOnRefresh( false ),
    mbTupleCache( false ),
    mbSupportSubquery( false ),
    mbSupportDrill( false )
{
}

// ----------------------------------------------------------------------------

PCSourceModel::PCSourceModel() :
    mnSourceType( XML_TOKEN_INVALID ),
    mnConnectionId( 0 )
{
}

// ----------------------------------------------------------------------------

PCWorksheetSourceModel::PCWorksheetSourceModel()
{
    maRange.StartColumn = maRange.StartRow = maRange.EndColumn = maRange.EndRow = -1;
}

// ----------------------------------------------------------------------------

PivotCache::PivotCache( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper ),
    mnCurrRow( -1 ),
    mbValidSource( false ),
    mbDummySheet( false )
{
}

void PivotCache::importPivotCacheDefinition( const AttributeList& rAttribs )
{
    maDefModel.maRelId            = rAttribs.getString( R_TOKEN( id ), OUString() );
    maDefModel.maRefreshedBy      = rAttribs.getXString( XML_refreshedBy, OUString() );
    maDefModel.mfRefreshedDate    = rAttribs.getDouble( XML_refreshedDate, 0.0 );
    maDefModel.mnRecords          = rAttribs.getInteger( XML_recordCount, 0 );
    maDefModel.mnMissItemsLimit   = rAttribs.getInteger( XML_missingItemsLimit, 0 );
    maDefModel.mbInvalid          = rAttribs.getBool( XML_invalid, false );
    maDefModel.mbSaveData         = rAttribs.getBool( XML_saveData, true );
    maDefModel.mbRefreshOnLoad    = rAttribs.getBool( XML_refreshOnLoad, false );
    maDefModel.mbOptimizeMemory   = rAttribs.getBool( XML_optimizeMemory, false );
    maDefModel.mbEnableRefresh    = rAttribs.getBool( XML_enableRefresh, true );
    maDefModel.mbBackgroundQuery  = rAttribs.getBool( XML_backgroundQuery, false );
    maDefModel.mbUpgradeOnRefresh = rAttribs.getBool( XML_upgradeOnRefresh, false );
    maDefModel.mbTupleCache       = rAttribs.getBool( XML_tupleCache, false );
    maDefModel.mbSupportSubquery  = rAttribs.getBool( XML_supportSubquery, false );
    maDefModel.mbSupportDrill     = rAttribs.getBool( XML_supportAdvancedDrill, false );
}

void PivotCache::importCacheSource( const AttributeList& rAttribs )
{
    maSourceModel.mnSourceType   = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
    maSourceModel.mnConnectionId = rAttribs.getInteger( XML_connectionId, 0 );
}

void PivotCache::importWorksheetSource( const AttributeList& rAttribs, const Relations& rRelations )
{
    maSheetSrcModel.maRelId   = rAttribs.getString( R_TOKEN( id ), OUString() );
    maSheetSrcModel.maSheet   = rAttribs.getXString( XML_sheet, OUString() );
    maSheetSrcModel.maDefName = rAttribs.getXString( XML_name, OUString() );

    // resolve URL of external document
    maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
    // store range address unchecked with sheet index 0, will be resolved/checked later
    getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, rAttribs.getString( XML_ref, OUString() ), 0 );
}

void PivotCache::importPCDefinition( SequenceInputStream& rStrm )
{
    sal_uInt8 nFlags1, nFlags2;
    rStrm.skip( 3 );    // create/refresh version id's
    rStrm >> nFlags1 >> maDefModel.mnMissItemsLimit >> maDefModel.mfRefreshedDate >> nFlags2 >> maDefModel.mnRecords;
    if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASUSERNAME ) )
        rStrm >> maDefModel.maRefreshedBy;
    if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASRELID ) )
        rStrm >> maDefModel.maRelId;

    maDefModel.mbInvalid          = getFlag( nFlags1, BIFF12_PCDEFINITION_INVALID );
    maDefModel.mbSaveData         = getFlag( nFlags1, BIFF12_PCDEFINITION_SAVEDATA );
    maDefModel.mbRefreshOnLoad    = getFlag( nFlags1, BIFF12_PCDEFINITION_REFRESHONLOAD );
    maDefModel.mbOptimizeMemory   = getFlag( nFlags1, BIFF12_PCDEFINITION_OPTIMIZEMEMORY );
    maDefModel.mbEnableRefresh    = getFlag( nFlags1, BIFF12_PCDEFINITION_ENABLEREFRESH );
    maDefModel.mbBackgroundQuery  = getFlag( nFlags1, BIFF12_PCDEFINITION_BACKGROUNDQUERY );
    maDefModel.mbUpgradeOnRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_UPGRADEONREFR );
    maDefModel.mbTupleCache       = getFlag( nFlags1, BIFF12_PCDEFINITION_TUPELCACHE );
    maDefModel.mbSupportSubquery  = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTSUBQUERY );
    maDefModel.mbSupportDrill     = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTDRILL );
}

void PivotCache::importPCDSource( SequenceInputStream& rStrm )
{
    sal_Int32 nSourceType;
    rStrm >> nSourceType >> maSourceModel.mnConnectionId;
    static const sal_Int32 spnSourceTypes[] = { XML_worksheet, XML_external, XML_consolidation, XML_scenario };
    maSourceModel.mnSourceType = STATIC_ARRAY_SELECT( spnSourceTypes, nSourceType, XML_TOKEN_INVALID );
}

void PivotCache::importPCDSheetSource( SequenceInputStream& rStrm, const Relations& rRelations )
{
    sal_uInt8 nIsDefName, nIsBuiltinName, nFlags;
    rStrm >> nIsDefName >> nIsBuiltinName >> nFlags;
    if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASSHEET ) )
        rStrm >> maSheetSrcModel.maSheet;
    if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASRELID ) )
        rStrm >> maSheetSrcModel.maRelId;

    // read cell range or defined name
    if( nIsDefName == 0 )
    {
        BinRange aBinRange;
        rStrm >> aBinRange;
        // store range address unchecked with sheet index 0, will be resolved/checked later
        getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, aBinRange, 0 );
    }
    else
    {
        rStrm >> maSheetSrcModel.maDefName;
        if( nIsBuiltinName != 0 )
            maSheetSrcModel.maDefName = CREATE_OUSTRING( "_xlnm." ) + maSheetSrcModel.maDefName;
    }

    // resolve URL of external document
    maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
}

void PivotCache::importPCDSource( BiffInputStream& rStrm )
{
    switch( rStrm.readuInt16() )
    {
        case BIFF_PCDSOURCE_WORKSHEET:
        {
            maSourceModel.mnSourceType = XML_worksheet;
            sal_uInt16 nNextRecId = rStrm.getNextRecId();
            switch( nNextRecId )
            {
                case BIFF_ID_DCONREF:       if( rStrm.startNextRecord() ) importDConRef( rStrm );       break;
                case BIFF_ID_DCONNAME:      if( rStrm.startNextRecord() ) importDConName( rStrm );      break;
                case BIFF_ID_DCONBINAME:    if( rStrm.startNextRecord() ) importDConBIName( rStrm );    break;
            }
        }
        break;
        case BIFF_PCDSOURCE_EXTERNAL:
            maSourceModel.mnSourceType = XML_external;
        break;
        case BIFF_PCDSOURCE_CONSOLIDATION:
            maSourceModel.mnSourceType = XML_consolidation;
        break;
        case BIFF_PCDSOURCE_SCENARIO:
            maSourceModel.mnSourceType = XML_scenario;
        break;
        default:
            maSourceModel.mnSourceType = XML_TOKEN_INVALID;
    }
}

void PivotCache::importPCDefinition( BiffInputStream& rStrm )
{
    sal_uInt16 nFlags, nUserNameLen;
    rStrm >> maDefModel.mnRecords;
    rStrm.skip( 2 );    // repeated cache ID
    rStrm >> nFlags;
    rStrm.skip( 2 );    // unused
    rStrm >> maDefModel.mnDatabaseFields;
    rStrm.skip( 6 );    // total field count, report record count, (repeated) cache type
    rStrm >> nUserNameLen;
    if( nUserNameLen != BIFF_PC_NOSTRING )
        maDefModel.maRefreshedBy = (getBiff() == BIFF8) ?
            rStrm.readUniString( nUserNameLen ) :
            rStrm.readCharArrayUC( nUserNameLen, getTextEncoding() );

    maDefModel.mbInvalid          = getFlag( nFlags, BIFF_PCDEFINITION_INVALID );
    maDefModel.mbSaveData         = getFlag( nFlags, BIFF_PCDEFINITION_SAVEDATA );
    maDefModel.mbRefreshOnLoad    = getFlag( nFlags, BIFF_PCDEFINITION_REFRESHONLOAD );
    maDefModel.mbOptimizeMemory   = getFlag( nFlags, BIFF_PCDEFINITION_OPTIMIZEMEMORY );
    maDefModel.mbEnableRefresh    = getFlag( nFlags, BIFF_PCDEFINITION_ENABLEREFRESH );
    maDefModel.mbBackgroundQuery  = getFlag( nFlags, BIFF_PCDEFINITION_BACKGROUNDQUERY );

    if( (rStrm.getNextRecId() == BIFF_ID_PCDEFINITION2) && rStrm.startNextRecord() )
        rStrm >> maDefModel.mfRefreshedDate;
}

PivotCacheField& PivotCache::createCacheField( bool bInitDatabaseField )
{
    bool bIsDatabaseField = !bInitDatabaseField || (maFields.size() < maDefModel.mnDatabaseFields);
    PivotCacheFieldVector::value_type xCacheField( new PivotCacheField( *this, bIsDatabaseField ) );
    maFields.push_back( xCacheField );
    return *xCacheField;
}

void PivotCache::finalizeImport()
{
    // collect all fields that are based on source data (needed to finalize source data below)
    OSL_ENSURE( !maFields.empty(), "PivotCache::finalizeImport - no pivot cache fields found" );
    for( PivotCacheFieldVector::const_iterator aIt = maFields.begin(), aEnd = maFields.end(); aIt != aEnd; ++aIt )
    {
        if( (*aIt)->isDatabaseField() )
        {
            OSL_ENSURE( (aIt == maFields.begin()) || (*(aIt - 1))->isDatabaseField(),
                "PivotCache::finalizeImport - database field follows a calculated field" );
            maDatabaseIndexes.push_back( static_cast< sal_Int32 >( maDatabaseFields.size() ) );
            maDatabaseFields.push_back( *aIt );
        }
        else
        {
            maDatabaseIndexes.push_back( -1 );
        }
    }
    OSL_ENSURE( !maDatabaseFields.empty(), "PivotCache::finalizeImport - no pivot cache source fields found" );

    // finalize source data depending on source type
    switch( maSourceModel.mnSourceType )
    {
        case XML_worksheet:
        {
            // decide whether an external document is used
            bool bInternal = (maTargetUrl.getLength() == 0) && (maSheetSrcModel.maRelId.getLength() == 0);
            bool bExternal = maTargetUrl.getLength() > 0;   // relation ID may be empty, e.g. BIFF import
            OSL_ENSURE( bInternal || bExternal, "PivotCache::finalizeImport - invalid external document URL" );
            if( bInternal )
                finalizeInternalSheetSource();
            else if( bExternal )
                finalizeExternalSheetSource();
        }
        break;

        // currently, we only support worksheet data sources
        case XML_external:
        break;
        case XML_consolidation:
        break;
        case XML_scenario:
        break;
    }
}

sal_Int32 PivotCache::getCacheFieldCount() const
{
    return static_cast< sal_Int32 >( maFields.size() );
}

const PivotCacheField* PivotCache::getCacheField( sal_Int32 nFieldIdx ) const
{
    return maFields.get( nFieldIdx ).get();
}

sal_Int32 PivotCache::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
{
    return ContainerHelper::getVectorElement( maDatabaseIndexes, nFieldIdx, -1 );
}

void PivotCache::writeSourceHeaderCells( WorksheetHelper& rSheetHelper ) const
{
    OSL_ENSURE( static_cast< size_t >( maSheetSrcModel.maRange.EndColumn - maSheetSrcModel.maRange.StartColumn + 1 ) == maDatabaseFields.size(),
        "PivotCache::writeSourceHeaderCells - source cell range width does not match number of source fields" );
    sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
    sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
    sal_Int32 nRow = maSheetSrcModel.maRange.StartRow;
    mnCurrRow = -1;
    updateSourceDataRow( rSheetHelper, nRow );
    for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
        (*aIt)->writeSourceHeaderCell( rSheetHelper, nCol, nRow );
}

void PivotCache::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nColIdx, sal_Int32 nRowIdx, const PivotCacheItem& rItem ) const
{
    sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn + nColIdx;
    OSL_ENSURE( (maSheetSrcModel.maRange.StartColumn <= nCol) && (nCol <= maSheetSrcModel.maRange.EndColumn), "PivotCache::writeSourceDataCell - invalid column index" );
    sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx;
    OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::writeSourceDataCell - invalid row index" );
    updateSourceDataRow( rSheetHelper, nRow );
    if( const PivotCacheField* pCacheField = maDatabaseFields.get( nColIdx ).get() )
        pCacheField->writeSourceDataCell( rSheetHelper, nCol, nRow, rItem );
}

void PivotCache::importPCRecord( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const
{
    sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx;
    OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::importPCRecord - invalid row index" );
    sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
    sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
    for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
        (*aIt)->importPCRecordItem( rStrm, rSheetHelper, nCol, nRow );
}

void PivotCache::importPCItemIndexList( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const
{
    sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx;
    OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::importPCItemIndexList - invalid row index" );
    sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
    sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
    for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
        if( (*aIt)->hasSharedItems() )
            (*aIt)->importPCItemIndex( rStrm, rSheetHelper, nCol, nRow );
}

// private --------------------------------------------------------------------

void PivotCache::importDConRef( BiffInputStream& rStrm )
{
    BinRange aBinRange;
    aBinRange.read( rStrm, false );     // always 8-bit column indexes
    // store range address unchecked with sheet index 0, will be resolved/checked later
    getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, aBinRange, 0 );

    // the URL with (required) sheet name and optional URL of an external document
    importDConUrl( rStrm );
    OSL_ENSURE( maSheetSrcModel.maSheet.getLength() > 0, "PivotCache::importDConRef - missing sheet name" );
}

void PivotCache::importDConName( BiffInputStream& rStrm )
{
    maSheetSrcModel.maDefName = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
    OSL_ENSURE( maSheetSrcModel.maDefName.getLength() > 0, "PivotCache::importDConName - missing defined name" );
    importDConUrl( rStrm );
}

void PivotCache::importDConBIName( BiffInputStream& rStrm )
{
    sal_uInt8 nNameId = rStrm.readuInt8();
    rStrm.skip( 3 );
    maSheetSrcModel.maDefName = OUString( sal_Unicode( nNameId ) );
    importDConUrl( rStrm );
}

void PivotCache::importDConUrl( BiffInputStream& rStrm )
{
    // the URL with sheet name and optional URL of an external document
    OUString aEncodedUrl;
    if( getBiff() == BIFF8 )
    {
        // empty string does not contain a flags byte, cannot use simple readUniString() here...
        sal_uInt16 nChars = rStrm.readuInt16();
        if( nChars > 0 )
            aEncodedUrl = rStrm.readUniString( nChars );
    }
    else
    {
        aEncodedUrl = rStrm.readByteStringUC( false, getTextEncoding() );
    }

    if( aEncodedUrl.getLength() > 0 )
    {
        OUString aClassName;
        getAddressConverter().parseBiffTargetUrl( aClassName, maTargetUrl, maSheetSrcModel.maSheet, aEncodedUrl, true );
    }
}

void PivotCache::finalizeInternalSheetSource()
{
    // resolve sheet name to sheet index
    sal_Int16 nSheet = getWorksheets().getCalcSheetIndex( maSheetSrcModel.maSheet );

    // if cache is based on a defined name or table, try to resolve to cell range
    if( maSheetSrcModel.maDefName.getLength() > 0 )
    {
        // local or global defined name
        if( const DefinedName* pDefName = getDefinedNames().getByModelName( maSheetSrcModel.maDefName, nSheet ).get() )
        {
            mbValidSource = pDefName->getAbsoluteRange( maSheetSrcModel.maRange );
        }
        // table
        else if( const Table* pTable = getTables().getTable( maSheetSrcModel.maDefName ).get() )
        {
            // get original range from table, but exclude the totals row(s)
            maSheetSrcModel.maRange = pTable->getOriginalRange();
            mbValidSource = (pTable->getHeight() - pTable->getTotalsRows()) > 1;
            if( mbValidSource )
                maSheetSrcModel.maRange.EndRow -= pTable->getTotalsRows();
        }
    }
    // else try the cell range (if the sheet exists)
    else if( nSheet >= 0 )
    {
        // insert sheet index into the range, range address will be checked below
        maSheetSrcModel.maRange.Sheet = nSheet;
        mbValidSource = true;
    }
    // else sheet has been deleted, generate the source data from cache
    else if( maSheetSrcModel.maSheet.getLength() > 0 )
    {
        prepareSourceDataSheet();
        // return here to skip the source range check below
        return;
    }

    // check range location, do not allow ranges that overflow the sheet partly
    mbValidSource = mbValidSource &&
        getAddressConverter().checkCellRange( maSheetSrcModel.maRange, false, true ) &&
        (maSheetSrcModel.maRange.StartRow < maSheetSrcModel.maRange.EndRow);
}

void PivotCache::finalizeExternalSheetSource()
{
    /*  If pivot cache is based on external sheet data, try to restore sheet
        data from cache records. No support for external defined names or tables,
        sheet name and path to cache records fragment (OOXML only) are required. */
    bool bHasRelation = (getFilterType() == FILTER_BIFF) || (maDefModel.maRelId.getLength() > 0);
    if( bHasRelation && (maSheetSrcModel.maDefName.getLength() == 0) && (maSheetSrcModel.maSheet.getLength() > 0) )
        prepareSourceDataSheet();
}

void PivotCache::prepareSourceDataSheet()
{
    CellRangeAddress& rRange = maSheetSrcModel.maRange;
    // data will be inserted in top-left cell, sheet index is still set to 0 (will be set below)
    rRange.EndColumn -= rRange.StartColumn;
    rRange.StartColumn = 0;
    rRange.EndRow -= rRange.StartRow;
    rRange.StartRow = 0;
    // check range location, do not allow ranges that overflow the sheet partly
    if( getAddressConverter().checkCellRange( rRange, false, true ) )
    {
        maColSpans.insert( ValueRange( rRange.StartColumn, rRange.EndColumn ) );
        OUString aSheetName = CREATE_OUSTRING( "DPCache_" ) + maSheetSrcModel.maSheet;
        rRange.Sheet = getWorksheets().insertEmptySheet( aSheetName, false );
        mbValidSource = mbDummySheet = rRange.Sheet >= 0;
    }
}

void PivotCache::updateSourceDataRow( WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const
{
    if( mnCurrRow != nRow )
    {
        rSheetHelper.getSheetData().setColSpans( nRow, maColSpans );
        mnCurrRow = nRow;
    }
}

// ============================================================================

PivotCacheBuffer::PivotCacheBuffer( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper )
{
}

void PivotCacheBuffer::registerPivotCacheFragment( sal_Int32 nCacheId, const OUString& rFragmentPath )
{
    OSL_ENSURE( nCacheId >= 0, "PivotCacheBuffer::registerPivotCacheFragment - invalid pivot cache identifier" );
    OSL_ENSURE( maFragmentPaths.count( nCacheId ) == 0, "PivotCacheBuffer::registerPivotCacheFragment - fragment path exists already" );
    if( (nCacheId >= 0) && (rFragmentPath.getLength() > 0) )
        maFragmentPaths[ nCacheId ] = rFragmentPath;
}

void PivotCacheBuffer::importPivotCacheRef( BiffInputStream& rStrm )
{
    // read the PIVOTCACHE record that contains the stream ID
    sal_Int32 nCacheId = rStrm.readuInt16();
    OSL_ENSURE( maFragmentPaths.count( nCacheId ) == 0, "PivotCacheBuffer::importPivotCacheRef - cache stream exists already" );
    OUStringBuffer aStrmName;
    static const sal_Unicode spcHexChars[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
    for( sal_uInt8 nBit = 0; nBit < 16; nBit += 4 )
        aStrmName.insert( 0, spcHexChars[ extractValue< size_t >( nCacheId, nBit, 4 ) ] );
    aStrmName.insert( 0, (getBiff() == BIFF8) ? CREATE_OUSTRING( "_SX_DB_CUR/" ) : CREATE_OUSTRING( "_SX_DB/" ) );
    maFragmentPaths[ nCacheId ] = aStrmName.makeStringAndClear();

    // try to read PCDSOURCE record (will read following data location records too)
    sal_uInt16 nNextRecId = rStrm.getNextRecId();
    OSL_ENSURE( nNextRecId == BIFF_ID_PCDSOURCE, "PivotCacheBuffer::importPivotCacheRef - PCDSOURCE record expected" );
    if( (nNextRecId == BIFF_ID_PCDSOURCE) && rStrm.startNextRecord() )
        createPivotCache( nCacheId ).importPCDSource( rStrm );
}

PivotCache* PivotCacheBuffer::importPivotCacheFragment( sal_Int32 nCacheId )
{
    switch( getFilterType() )
    {
        /*  OOXML/BIFF12 filter: On first call for the cache ID, the pivot
            cache object is created and inserted into maCaches. Then, the cache
            definition fragment is read and the cache is returned. On
            subsequent calls, the created cache will be found in maCaches and
            returned immediately. */
        case FILTER_OOXML:
        {
            // try to find an imported pivot cache
            if( PivotCache* pCache = maCaches.get( nCacheId ).get() )
                return pCache;

            // check if a fragment path exists for the passed cache identifier
            FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
            if( aIt == maFragmentPaths.end() )
                return 0;

            /*  Import the cache fragment. This may create a dummy data sheet
                for external sheet sources. */
            PivotCache& rCache = createPivotCache( nCacheId );
            importOoxFragment( new PivotCacheDefinitionFragment( *this, aIt->second, rCache ) );
            return &rCache;
        }

        /*  BIFF filter: Pivot table provides 0-based index into list of pivot
            cache source links (PIVOTCACHE/PCDSOURCE/... record blocks in
            workbook stream). First, this index has to be resolved to the cache
            identifier that is used to manage the cache stream names (the
            maFragmentPaths member). The cache object itself exists already
            before the first call for the cache source index (see
            PivotCacheBuffer::importPivotCacheRef() above), because source data
            link is part of workbook data, not of the cache stream. To detect
            subsequent calls with an already initialized cache, the entry in
            maFragmentPaths will be removed after reading the cache stream. */
        case FILTER_BIFF:
        {
            /*  Resolve cache index to cache identifier and try to find pivot
                cache. Cache must exist already for a valid cache index. */
            nCacheId = ContainerHelper::getVectorElement( maCacheIds, nCacheId, -1 );
            PivotCache* pCache = maCaches.get( nCacheId ).get();
            if( !pCache )
                return 0;

            /*  Try to find fragment path entry (stream name). If missing, the
                stream has been read already, and the cache can be returned. */
            FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
            if( aIt != maFragmentPaths.end() )
            {
                /*  Import the cache stream. This may create a dummy data sheet
                    for external sheet sources. */
                BiffPivotCacheFragment( *this, aIt->second, *pCache ).importFragment();
                // remove the fragment entry to mark that the cache is initialized
                maFragmentPaths.erase( aIt );
            }
            return pCache;
        }

        case FILTER_UNKNOWN:
            OSL_ENSURE( false, "PivotCacheBuffer::importPivotCacheFragment - unknown filter type" );
    }
    return 0;
}

PivotCache& PivotCacheBuffer::createPivotCache( sal_Int32 nCacheId )
{
    maCacheIds.push_back( nCacheId );
    PivotCacheMap::mapped_type& rxCache = maCaches[ nCacheId ];
    rxCache.reset( new PivotCache( *this ) );
    return *rxCache;
}

// ============================================================================

} // namespace xls
} // namespace oox
