/**************************************************************
 * 
 * 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/pivottablebuffer.hxx"

#include <set>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/sheet/CellFlags.hpp>
#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
#include <com/sun/star/sheet/GeneralFunction.hpp>
#include <com/sun/star/sheet/XDataPilotDataLayoutFieldSupplier.hpp>
#include <com/sun/star/sheet/XDataPilotField.hpp>
#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
#include <com/sun/star/sheet/XSheetOperation.hpp>
#include "oox/helper/attributelist.hxx"
#include "oox/helper/containerhelper.hxx"
#include "oox/helper/propertyset.hxx"
#include "oox/xls/addressconverter.hxx"
#include "oox/xls/biffinputstream.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 ::rtl::OUString;

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

namespace {

const sal_Int32 OOX_PT_DATALAYOUTFIELD              = -2;           /// Placeholder index of data layout field.

const sal_Int32 OOX_PT_PREVIOUS_ITEM                = 0x001000FC;   /// Calculation of data item result is based on previous item.
const sal_Int32 OOX_PT_NEXT_ITEM                    = 0x001000FD;   /// Calculation of data item result is based on next item.

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

const sal_uInt32 BIFF12_PTFIELD_DATAFIELD           = 0x00000008;
const sal_uInt32 BIFF12_PTFIELD_DEFAULT             = 0x00000100;
const sal_uInt32 BIFF12_PTFIELD_SUM                 = 0x00000200;
const sal_uInt32 BIFF12_PTFIELD_COUNTA              = 0x00000400;
const sal_uInt32 BIFF12_PTFIELD_AVERAGE             = 0x00000800;
const sal_uInt32 BIFF12_PTFIELD_MAX                 = 0x00001000;
const sal_uInt32 BIFF12_PTFIELD_MIN                 = 0x00002000;
const sal_uInt32 BIFF12_PTFIELD_PRODUCT             = 0x00004000;
const sal_uInt32 BIFF12_PTFIELD_COUNT               = 0x00008000;
const sal_uInt32 BIFF12_PTFIELD_STDDEV              = 0x00010000;
const sal_uInt32 BIFF12_PTFIELD_STDDEVP             = 0x00020000;
const sal_uInt32 BIFF12_PTFIELD_VAR                 = 0x00040000;
const sal_uInt32 BIFF12_PTFIELD_VARP                = 0x00080000;

const sal_uInt32 BIFF12_PTFIELD_SHOWALL             = 0x00000020;
const sal_uInt32 BIFF12_PTFIELD_OUTLINE             = 0x00000040;
const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW      = 0x00000080;
const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP         = 0x00000100;
const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK     = 0x00000800;
const sal_uInt32 BIFF12_PTFIELD_AUTOSORT            = 0x00001000;
const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING       = 0x00002000;
const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW            = 0x00004000;
const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP         = 0x00008000;
const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS      = 0x00080000;

const sal_uInt16 BIFF12_PTFITEM_HIDDEN              = 0x0001;
const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS         = 0x0002;

const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME          = 0x01;
const sal_uInt8 BIFF12_PTPAGEFIELD_HASOLAPCAPTION   = 0x02;
const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS       = 0x001000FE;

const sal_uInt16 BIFF12_PTFILTER_HASNAME            = 0x0001;
const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION     = 0x0002;
const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1       = 0x0004;
const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2       = 0x0008;

const sal_uInt8 BIFF12_TOP10FILTER_TOP              = 0x01;
const sal_uInt8 BIFF12_TOP10FILTER_PERCENT          = 0x02;

const sal_uInt32 BIFF12_PTDEF_SHOWITEMS             = 0x00000100;
const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST      = 0x00000400;
const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS       = 0x00001000;
const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS      = 0x00002000;
const sal_uInt32 BIFF12_PTDEF_HIDEDRILL             = 0x00100000;
const sal_uInt32 BIFF12_PTDEF_PRINTDRILL            = 0x00200000;
const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS           = 0x80000000;

const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW          = 0x00000004;
const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL          = 0x00000008;
const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL           = 0x00000020;
const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING    = 0x00000080;
const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT         = 0x00000100;
const sal_uInt32 BIFF12_PTDEF_SHOWERROR             = 0x00000200;
const sal_uInt32 BIFF12_PTDEF_SHOWMISSING           = 0x00000400;
const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN      = 0x00000800;
const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS   = 0x00001000;
const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS        = 0x00002000;
const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS        = 0x00004000;
const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES      = 0x00008000;
const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES       = 0x00020000;
const sal_uInt32 BIFF12_PTDEF_MERGEITEM             = 0x00040000;
const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION        = 0x00080000;
const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION  = 0x00100000;
const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE          = 0x00200000;
const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE    = 0x00400000;
const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE       = 0x00800000;
const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT           = 0x01000000;
const sal_uInt32 BIFF12_PTDEF_APPLYFONT             = 0x02000000;
const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT        = 0x04000000;
const sal_uInt32 BIFF12_PTDEF_APPLYBORDER           = 0x08000000;
const sal_uInt32 BIFF12_PTDEF_APPLYFILL             = 0x10000000;
const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION       = 0x20000000;
const sal_uInt32 BIFF12_PTDEF_HASTAG                = 0x40000000;

const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION        = 0x00000040;
const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION      = 0x00000080;
const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION   = 0x00000400;
const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION   = 0x00000800;
const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC      = 0x00001000;
const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT      = 0x00004000;

const sal_uInt8 BIFF12_PTDEF_ROWAXIS                = 1;
const sal_uInt8 BIFF12_PTDEF_COLAXIS                = 2;

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

const sal_uInt16 BIFF_PT_NOSTRING                   = 0xFFFF;

const sal_uInt16 BIFF_PTFIELD_DATAFIELD             = 0x0008;
const sal_uInt16 BIFF_PTFIELD_DEFAULT               = 0x0001;
const sal_uInt16 BIFF_PTFIELD_SUM                   = 0x0002;
const sal_uInt16 BIFF_PTFIELD_COUNTA                = 0x0004;
const sal_uInt16 BIFF_PTFIELD_AVERAGE               = 0x0008;
const sal_uInt16 BIFF_PTFIELD_MAX                   = 0x0010;
const sal_uInt16 BIFF_PTFIELD_MIN                   = 0x0020;
const sal_uInt16 BIFF_PTFIELD_PRODUCT               = 0x0040;
const sal_uInt16 BIFF_PTFIELD_COUNT                 = 0x0080;
const sal_uInt16 BIFF_PTFIELD_STDDEV                = 0x0100;
const sal_uInt16 BIFF_PTFIELD_STDDEVP               = 0x0200;
const sal_uInt16 BIFF_PTFIELD_VAR                   = 0x0400;
const sal_uInt16 BIFF_PTFIELD_VARP                  = 0x0800;

const sal_uInt32 BIFF_PTFIELD2_SHOWALL              = 0x00000001;
const sal_uInt32 BIFF_PTFIELD2_AUTOSORT             = 0x00000200;
const sal_uInt32 BIFF_PTFIELD2_SORTASCENDING        = 0x00000400;
const sal_uInt32 BIFF_PTFIELD2_AUTOSHOW             = 0x00000800;
const sal_uInt32 BIFF_PTFIELD2_AUTOSHOWTOP          = 0x00001000;
const sal_uInt32 BIFF_PTFIELD2_OUTLINE              = 0x00200000;
const sal_uInt32 BIFF_PTFIELD2_INSERTBLANKROW       = 0x00400000;
const sal_uInt32 BIFF_PTFIELD2_SUBTOTALTOP          = 0x00800000;

const sal_uInt16 BIFF_PTFITEM_HIDDEN                = 0x0001;
const sal_uInt16 BIFF_PTFITEM_HIDEDETAILS           = 0x0002;

const sal_uInt16 BIFF_PTDEF_ROWGRANDTOTALS          = 0x0001;
const sal_uInt16 BIFF_PTDEF_COLGRANDTOTALS          = 0x0002;

const sal_uInt8 BIFF_PTDEF_ROWAXIS                  = 1;
const sal_uInt8 BIFF_PTDEF_COLAXIS                  = 2;

const sal_uInt32 BIFF_PTDEF2_PAGEOVERTHENDOWN       = 0x00000001;
const sal_uInt32 BIFF_PTDE2F_ENABLEDRILL            = 0x00020000;
const sal_uInt32 BIFF_PTDEF2_PRESERVEFORMATTING     = 0x00080000;
const sal_uInt32 BIFF_PTDEF2_MERGEITEM              = 0x00100000;
const sal_uInt32 BIFF_PTDEF2_SHOWERROR              = 0x00200000;
const sal_uInt32 BIFF_PTDEF2_SHOWMISSING            = 0x00400000;
const sal_uInt32 BIFF_PTDEF2_SUBTOTALHIDDENITEMS    = 0x00800000;

const sal_Int16 BIFF_PTPAGEFIELDS_ALLITEMS          = 0x7FFD;

const sal_Int16 BIFF_PTDATAFIELD_PREVIOUS           = 0x7FFB;
const sal_Int16 BIFF_PTDATAFIELD_NEXT               = 0x7FFC;

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

OUString lclReadPivotString( const WorkbookHelper& rHelper, BiffInputStream& rStrm, sal_uInt16 nLen )
{
    if( nLen == BIFF_PT_NOSTRING )
        return OUString();
    return (rHelper.getBiff() == BIFF8) ? rStrm.readUniStringBody( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() );
}

} // namespace

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

PTFieldItemModel::PTFieldItemModel() :
    mnCacheItem( -1 ),
    mnType( XML_data ),
    mbShowDetails( true ),
    mbHidden( false )
{
}

void PTFieldItemModel::setBiffType( sal_uInt16 nType )
{
    static const sal_Int32 spnTypes[] = { XML_data, XML_default,
        XML_sum, XML_countA, XML_avg, XML_max, XML_min, XML_product, XML_count,
        XML_stdDev, XML_stdDevP, XML_var, XML_varP, XML_grand, XML_blank };
    mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_data );
}

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

PTFieldModel::PTFieldModel() :
    mnAxis( XML_TOKEN_INVALID ),
    mnNumFmtId( 0 ),
    mnAutoShowItems( 10 ),
    mnAutoShowRankBy( -1 ),
    mnSortType( XML_manual ),
    mnSortRefField( -1 ),
    mnSortRefItem( -1 ),
    mbDataField( false ),
    mbDefaultSubtotal( true ),
    mbSumSubtotal( false ),
    mbCountASubtotal( false ),
    mbAverageSubtotal( false ),
    mbMaxSubtotal( false ),
    mbMinSubtotal( false ),
    mbProductSubtotal( false ),
    mbCountSubtotal( false ),
    mbStdDevSubtotal( false ),
    mbStdDevPSubtotal( false ),
    mbVarSubtotal( false ),
    mbVarPSubtotal( false ),
    mbShowAll( true ),
    mbOutline( true ),
    mbSubtotalTop( true ),
    mbInsertBlankRow( false ),
    mbInsertPageBreak( false ),
    mbAutoShow( false ),
    mbTopAutoShow( true ),
    mbMultiPageItems( false )
{
}

void PTFieldModel::setBiffAxis( sal_uInt8 nAxis )
{
    /*  Weird. The axis field is organized as bit field, but only one of the
        row/col/page flags are allowed at the same time and refer to the values
        'axisRow', 'axisCol', and 'axisPage' of the XML attribute
        'pivotField@axis'. Additionally, the fourth bit determines if the field
        is a data field, which may appear combined with the row/col/page flags.
        Therefore, this bit is unrelated to the 'axisValues' value of the
        'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
        boolean attribute. */
    static const sal_Int32 spnAxisIds[] = { XML_TOKEN_INVALID, XML_axisRow, XML_axisCol, XML_TOKEN_INVALID, XML_axisPage };
    mnAxis = STATIC_ARRAY_SELECT( spnAxisIds, nAxis, XML_TOKEN_INVALID );
}

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

PTPageFieldModel::PTPageFieldModel() :
    mnField( -1 ),
    mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS )
{
}

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

PTDataFieldModel::PTDataFieldModel() :
    mnField( -1 ),
    mnSubtotal( XML_sum ),
    mnShowDataAs( XML_normal ),
    mnBaseField( -1 ),
    mnBaseItem( -1 ),
    mnNumFmtId( 0 )
{
}

void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal )
{
    static sal_Int32 spnSubtotals[] = { XML_sum, XML_count, XML_average, XML_max, XML_min, XML_product, XML_countNums, XML_stdDev, XML_stdDevp, XML_var, XML_varp };
    mnSubtotal = STATIC_ARRAY_SELECT( spnSubtotals, nSubtotal, XML_TOKEN_INVALID );
}

void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs )
{
    static sal_Int32 spnShowDataAs[] = { XML_normal, XML_difference, XML_percent, XML_percentDiff, XML_runTotal, XML_percentOfRow, XML_percentOfCol, XML_percentOfTotal, XML_index };
    mnShowDataAs = STATIC_ARRAY_SELECT( spnShowDataAs, nShowDataAs, XML_TOKEN_INVALID );
}

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

PivotTableField::PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex ) :
    WorkbookHelper( rPivotTable ),
    mrPivotTable( rPivotTable ),
    mnFieldIndex( nFieldIndex )
{
}

void PivotTableField::importPivotField( const AttributeList& rAttribs )
{
    /*  The documentation mentions a value 'axisValues' for the attribute
        'pivotField@axis'. But this value is not used to mark a data field, as
        data fields may be inserted in one of the row/column/page dimensions at
        the same time. Therefore, the boolean attribute 'pivotField@dataField'
        is really used to mark data fields. */
    maModel.mnAxis            = rAttribs.getToken( XML_axis, XML_TOKEN_INVALID );
    maModel.mnNumFmtId        = rAttribs.getInteger( XML_numFmtId, 0 );
    maModel.mnAutoShowItems   = rAttribs.getInteger( XML_itemPageCount, 10 );
    maModel.mnAutoShowRankBy  = rAttribs.getInteger( XML_rankBy, -1 );
    maModel.mnSortType        = rAttribs.getToken( XML_sortType, XML_manual );
    maModel.mbDataField       = rAttribs.getBool( XML_dataField, false );
    maModel.mbDefaultSubtotal = rAttribs.getBool( XML_defaultSubtotal, true );
    maModel.mbSumSubtotal     = rAttribs.getBool( XML_sumSubtotal, false );
    maModel.mbCountASubtotal  = rAttribs.getBool( XML_countASubtotal, false );
    maModel.mbAverageSubtotal = rAttribs.getBool( XML_avgSubtotal, false );
    maModel.mbMaxSubtotal     = rAttribs.getBool( XML_maxSubtotal, false );
    maModel.mbMinSubtotal     = rAttribs.getBool( XML_minSubtotal, false );
    maModel.mbProductSubtotal = rAttribs.getBool( XML_productSubtotal, false );
    maModel.mbCountSubtotal   = rAttribs.getBool( XML_countSubtotal, false );
    maModel.mbStdDevSubtotal  = rAttribs.getBool( XML_stdDevSubtotal, false );
    maModel.mbStdDevPSubtotal = rAttribs.getBool( XML_stdDevPSubtotal, false );
    maModel.mbVarSubtotal     = rAttribs.getBool( XML_varSubtotal, false );
    maModel.mbVarPSubtotal    = rAttribs.getBool( XML_varPSubtotal, false );
    maModel.mbShowAll         = rAttribs.getBool( XML_showAll, true );
    maModel.mbOutline         = rAttribs.getBool( XML_outline, true );
    maModel.mbSubtotalTop     = rAttribs.getBool( XML_subtotalTop, true );
    maModel.mbInsertBlankRow  = rAttribs.getBool( XML_insertBlankRow, false );
    maModel.mbInsertPageBreak = rAttribs.getBool( XML_insertPageBreak, false );
    maModel.mbAutoShow        = rAttribs.getBool( XML_autoShow, false );
    maModel.mbTopAutoShow     = rAttribs.getBool( XML_topAutoShow, true );
    maModel.mbMultiPageItems  = rAttribs.getBool( XML_multipleItemSelectionAllowed, false );
}

void PivotTableField::importItem( const AttributeList& rAttribs )
{
    PTFieldItemModel aModel;
    aModel.mnCacheItem   = rAttribs.getInteger( XML_x, -1 );
    aModel.mnType        = rAttribs.getToken( XML_t, XML_data );
    aModel.mbShowDetails = rAttribs.getBool( XML_sd, true );
    aModel.mbHidden      = rAttribs.getBool( XML_h, false );
    maItems.push_back( aModel );
}

void PivotTableField::importReference( const AttributeList& rAttribs )
{
    // field index is stored as unsigned integer
    maModel.mnSortRefField = static_cast< sal_Int32 >( rAttribs.getUnsigned( XML_field, SAL_MAX_UINT32 ) );
}

void PivotTableField::importReferenceItem( const AttributeList& rAttribs )
{
    maModel.mnSortRefItem = rAttribs.getInteger( XML_v, -1 );
}

void PivotTableField::importPTField( SequenceInputStream& rStrm )
{
    sal_uInt32 nFlags1, nFlags2;
    rStrm >> nFlags1 >> maModel.mnNumFmtId >> nFlags2 >> maModel.mnAutoShowItems >> maModel.mnAutoShowRankBy;

    maModel.setBiffAxis( extractValue< sal_uInt8 >( nFlags1, 0, 3 ) );
    maModel.mbDataField       = getFlag( nFlags1, BIFF12_PTFIELD_DATAFIELD );
    maModel.mbDefaultSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_DEFAULT );
    maModel.mbSumSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_SUM );
    maModel.mbCountASubtotal  = getFlag( nFlags1, BIFF12_PTFIELD_COUNTA );
    maModel.mbAverageSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_AVERAGE );
    maModel.mbMaxSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_MAX );
    maModel.mbMinSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_MIN );
    maModel.mbProductSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_PRODUCT );
    maModel.mbCountSubtotal   = getFlag( nFlags1, BIFF12_PTFIELD_COUNT );
    maModel.mbStdDevSubtotal  = getFlag( nFlags1, BIFF12_PTFIELD_STDDEV );
    maModel.mbStdDevPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEVP );
    maModel.mbVarSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_VAR );
    maModel.mbVarPSubtotal    = getFlag( nFlags1, BIFF12_PTFIELD_VARP );

    maModel.mbShowAll         = getFlag( nFlags2, BIFF12_PTFIELD_SHOWALL );
    maModel.mbOutline         = getFlag( nFlags2, BIFF12_PTFIELD_OUTLINE );
    maModel.mbSubtotalTop     = getFlag( nFlags2, BIFF12_PTFIELD_SUBTOTALTOP );
    maModel.mbInsertBlankRow  = getFlag( nFlags2, BIFF12_PTFIELD_INSERTBLANKROW );
    maModel.mbInsertPageBreak = getFlag( nFlags2, BIFF12_PTFIELD_INSERTPAGEBREAK );
    maModel.mbAutoShow        = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOW );
    maModel.mbTopAutoShow     = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOWTOP );
    maModel.mbMultiPageItems  = getFlag( nFlags2, BIFF12_PTFIELD_MULTIPAGEITEMS );

    bool bAutoSort = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSORT );
    bool bAscending = getFlag( nFlags2, BIFF12_PTFIELD_SORTASCENDING );
    maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
}

void PivotTableField::importPTFItem( SequenceInputStream& rStrm )
{
    PTFieldItemModel aModel;
    sal_uInt8 nType;
    sal_uInt16 nFlags;
    rStrm >> nType >> nFlags >> aModel.mnCacheItem;

    aModel.setBiffType( nType );
    aModel.mbShowDetails = !getFlag( nFlags, BIFF12_PTFITEM_HIDEDETAILS );
    aModel.mbHidden      = getFlag( nFlags, BIFF12_PTFITEM_HIDDEN );

    maItems.push_back( aModel );
}

void PivotTableField::importPTReference( SequenceInputStream& rStrm )
{
    rStrm >> maModel.mnSortRefField;
}

void PivotTableField::importPTReferenceItem( SequenceInputStream& rStrm )
{
    rStrm >> maModel.mnSortRefItem;
}

void PivotTableField::importPTField( BiffInputStream& rStrm )
{
    sal_uInt16 nAxis, nSubtCount, nSubtotals;
    rStrm >> nAxis >> nSubtCount >> nSubtotals;
    rStrm.skip( 2 );    // item count

    maModel.setBiffAxis( extractValue< sal_uInt8 >( nAxis, 0, 3 ) );
    maModel.mbDataField       = getFlag( nAxis, BIFF_PTFIELD_DATAFIELD );

    maModel.mbDefaultSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_DEFAULT );
    maModel.mbSumSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_SUM );
    maModel.mbCountASubtotal  = getFlag( nSubtotals, BIFF_PTFIELD_COUNTA );
    maModel.mbAverageSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_AVERAGE );
    maModel.mbMaxSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_MAX );
    maModel.mbMinSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_MIN );
    maModel.mbProductSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_PRODUCT );
    maModel.mbCountSubtotal   = getFlag( nSubtotals, BIFF_PTFIELD_COUNT );
    maModel.mbStdDevSubtotal  = getFlag( nSubtotals, BIFF_PTFIELD_STDDEV );
    maModel.mbStdDevPSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_STDDEVP );
    maModel.mbVarSubtotal     = getFlag( nSubtotals, BIFF_PTFIELD_VAR );
    maModel.mbVarPSubtotal    = getFlag( nSubtotals, BIFF_PTFIELD_VARP );

    // set different defaults for BIFF
    maModel.mbShowAll = maModel.mbOutline = maModel.mbSubtotalTop = false;

    // read following items
    while( (rStrm.getNextRecId() == BIFF_ID_PTFITEM) && rStrm.startNextRecord() )
        importPTFItem( rStrm );

    // read following PTFIELD2 record with additional field settings
    if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_PTFIELD2) && rStrm.startNextRecord() )
        importPTField2( rStrm );
}

void PivotTableField::importPTField2( BiffInputStream& rStrm )
{
    sal_uInt32 nFlags;
    rStrm >> nFlags;
    maModel.mnSortRefItem    = rStrm.readInt16();
    maModel.mnAutoShowRankBy = rStrm.readInt16();
    maModel.mnNumFmtId       = rStrm.readuInt16();

    maModel.mnAutoShowItems   = extractValue< sal_Int32 >( nFlags, 24, 8 );
    maModel.mbShowAll         = getFlag( nFlags, BIFF_PTFIELD2_SHOWALL );
    maModel.mbOutline         = getFlag( nFlags, BIFF_PTFIELD2_OUTLINE );
    maModel.mbSubtotalTop     = getFlag( nFlags, BIFF_PTFIELD2_SUBTOTALTOP );
    maModel.mbInsertBlankRow  = getFlag( nFlags, BIFF_PTFIELD2_INSERTBLANKROW );
    maModel.mbAutoShow        = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOW );
    maModel.mbTopAutoShow     = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOWTOP );

    bool bAutoSort = getFlag( nFlags, BIFF_PTFIELD2_AUTOSORT );
    bool bAscending = getFlag( nFlags, BIFF_PTFIELD2_SORTASCENDING );
    maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
    // mnSortRefField == OOX_PT_DATALAYOUTFIELD will indicate sorting by data field
    if( maModel.mnSortRefItem >= 0 )
        maModel.mnSortRefField = OOX_PT_DATALAYOUTFIELD;
}

void PivotTableField::importPTFItem( BiffInputStream& rStrm )
{
    PTFieldItemModel aModel;
    sal_uInt16 nType, nFlags;
    sal_Int16 nCacheItem;
    rStrm >> nType >> nFlags >> nCacheItem;

    aModel.setBiffType( nType );
    aModel.mnCacheItem = nCacheItem;
    aModel.mbShowDetails = !getFlag( nFlags, BIFF_PTFITEM_HIDEDETAILS );
    aModel.mbHidden      = getFlag( nFlags, BIFF_PTFITEM_HIDDEN );

    maItems.push_back( aModel );
}

void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& rxDPDesc )
{
    /*  Process all fields based on source data, other fields (e.g. group
        fields) are processed from here. PivotCacahe::getDatabaseIndex()
        returns -1 for all fields not based on source data. */
    Reference< XDataPilotField > xDPField;
    sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
    if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
    {
        // try to get the source field and its name from passed DataPilot descriptor
        Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
        xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
        Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
        maDPFieldName = xDPFieldName->getName();
        OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeImport - no field name in source data found" );

        // try to convert grouping settings
        if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
        {
            // numeric grouping is done inplace, no nested group fields will appear
            if( pCacheField->hasNumericGrouping() )
            {
                pCacheField->convertNumericGrouping( xDPField );
            }
            else if( pCacheField->hasDateGrouping() )
            {
                // first date group settings are inplace
                pCacheField->createDateGroupField( xDPField );
                // create all nested group fields (if any)
                mrPivotTable.finalizeDateGroupingImport( xDPField, mnFieldIndex );
            }
            else if( pCacheField->hasParentGrouping() )
            {
                // create a list of all item names, needed to map between original and group items
                ::std::vector< OUString > aItems;
                pCacheField->getCacheItemNames( aItems );
                PivotCacheGroupItemVector aItemNames;
                for( ::std::vector< OUString >::iterator aIt = aItems.begin(), aEnd = aItems.end(); aIt != aEnd; ++aIt )
                    aItemNames.push_back( PivotCacheGroupItem( *aIt ) );
                // create all nested group fields (if any)
                mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, aItemNames );
            }
        }
    }
    catch( Exception& )
    {
    }
}

void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
{
    if( maDPFieldName.getLength() == 0 )    // prevent endless loops if file format is broken
    {
        if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
        {
            if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) )
            {
                maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField );
                OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
            }
        }
    }
}

void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, PivotCacheGroupItemVector& orItemNames )
{
    if( maDPFieldName.getLength() == 0 )    // prevent endless loops if file format is broken
    {
        if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
        {
            maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, orItemNames );
            // on success, try to create nested group fields
            Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
            if( xDPField.is() )
                mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames );
        }
    }
}

void PivotTableField::convertRowField()
{
    convertRowColPageField( XML_axisRow );
}

void PivotTableField::convertColField()
{
    convertRowColPageField( XML_axisCol );
}

void PivotTableField::convertHiddenField()
{
    convertRowColPageField( XML_TOKEN_INVALID );
}

void PivotTableField::convertPageField( const PTPageFieldModel& rPageField )
{
    OSL_ENSURE( rPageField.mnField == mnFieldIndex, "PivotTableField::convertPageField - wrong field index" );
    // convert all settings common for row/column/page fields
    Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage );

    if( xDPField.is() )
    {
        PropertySet aPropSet( xDPField );
        using namespace ::com::sun::star::sheet;

        // find cache item used as 'selected page'
        sal_Int32 nCacheItem = -1;
        if( maModel.mbMultiPageItems )
        {
            // multiple items may be selected
            OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" );
            // try to find a single visible item
            bool bHasMultiItems = false;
            for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); (aIt != aEnd) && !bHasMultiItems; ++aIt )
            {
                if( (aIt->mnType == XML_data) && !aIt->mbHidden )
                {
                    bHasMultiItems = nCacheItem >= 0;
                    nCacheItem = bHasMultiItems ? -1 : aIt->mnCacheItem;
                }
            }
        }
        else
        {
            // single item may be selected
            if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) )
                nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem;
        }

        if( nCacheItem >= 0 )
        {
            if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
            {
                if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) )
                {
                    OUString aSelectedPage = pSharedItem->getName();
                    aPropSet.setProperty( PROP_SelectedPage, aSelectedPage );
                }
            }
        }
    }
}

void PivotTableField::convertDataField( const PTDataFieldModel& rDataField )
{
    OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" );
    OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" );
    Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
    if( xDPField.is() )
    {
        PropertySet aPropSet( xDPField );
        using namespace ::com::sun::star::sheet;

        // field orientation
        aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA );

        /*  Field aggregation function. Documentation is a little bit confused
            about which names to use for the count functions. The name 'count'
            means 'count all', and 'countNum' means 'count numbers'. On the
            other hand, for subtotals, 'countA' means 'count all', and 'count'
            means 'count numbers' (see above). */
        GeneralFunction eAggFunc = GeneralFunction_SUM;
        switch( rDataField.mnSubtotal )
        {
            case XML_sum:       eAggFunc = GeneralFunction_SUM;         break;
            case XML_count:     eAggFunc = GeneralFunction_COUNT;       break;
            case XML_average:   eAggFunc = GeneralFunction_AVERAGE;     break;
            case XML_max:       eAggFunc = GeneralFunction_MAX;         break;
            case XML_min:       eAggFunc = GeneralFunction_MIN;         break;
            case XML_product:   eAggFunc = GeneralFunction_PRODUCT;     break;
            case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS;   break;
            case XML_stdDev:    eAggFunc = GeneralFunction_STDEV;       break;
            case XML_stdDevp:   eAggFunc = GeneralFunction_STDEVP;      break;
            case XML_var:       eAggFunc = GeneralFunction_VAR;         break;
            case XML_varp:      eAggFunc = GeneralFunction_VARP;        break;
            default:            OSL_ENSURE( false, "PivotTableField::convertDataField - unknown aggregation function" );
        }
        aPropSet.setProperty( PROP_Function, eAggFunc );

        // field reference ('show data as')
        DataPilotFieldReference aReference;
        aReference.ReferenceType = DataPilotFieldReferenceType::NONE;
        switch( rDataField.mnShowDataAs )
        {
            case XML_difference:        aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE;            break;
            case XML_percent:           aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE;            break;
            case XML_percentDiff:       aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break;
            case XML_runTotal:          aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL;              break;
            case XML_percentOfRow:      aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE;             break;
            case XML_percentOfCol:      aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE;          break;
            case XML_percentOfTotal:    aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE;           break;
            case XML_index:             aReference.ReferenceType = DataPilotFieldReferenceType::INDEX;                      break;
        }
        if( aReference.ReferenceType != DataPilotFieldReferenceType::NONE )
        {
            if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ) )
            {
                aReference.ReferenceField = pCacheField->getName();
                switch( rDataField.mnBaseItem )
                {
                    case OOX_PT_PREVIOUS_ITEM:
                        aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
                    break;
                    case OOX_PT_NEXT_ITEM:
                        aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
                    break;
                    default:
                        aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
                        if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) )
                            aReference.ReferenceItemName = pCacheItem->getName();
                }
                aPropSet.setProperty( PROP_Reference, aReference );
            }
        }
    }
}

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

Reference< XDataPilotField > PivotTableField::convertRowColPageField( sal_Int32 nAxis )
{
    bool bDataLayout = mnFieldIndex == OOX_PT_DATALAYOUTFIELD;
    Reference< XDataPilotField > xDPField = bDataLayout ? mrPivotTable.getDataLayoutField() : mrPivotTable.getDataPilotField( maDPFieldName );
    OSL_ENSURE( bDataLayout || (nAxis == maModel.mnAxis), "PivotTableField::convertRowColPageField - field axis mismatch" );

    if( xDPField.is() )
    {
        PropertySet aPropSet( xDPField );
        using namespace ::com::sun::star::sheet;

        // field orientation
        DataPilotFieldOrientation eFieldOrient = DataPilotFieldOrientation_HIDDEN;
        switch( nAxis )
        {
            case XML_axisRow:   eFieldOrient = DataPilotFieldOrientation_ROW;       break;
            case XML_axisCol:   eFieldOrient = DataPilotFieldOrientation_COLUMN;    break;
            case XML_axisPage:  eFieldOrient = DataPilotFieldOrientation_PAGE;      break;
        }
        if( eFieldOrient != DataPilotFieldOrientation_HIDDEN )
            aPropSet.setProperty( PROP_Orientation, eFieldOrient );

        // all other settings not for the data layout field
        if( !bDataLayout )
        {
            /*  Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
                explicit functions are set. This is different behaviour between
                XML (where 'defaultSubtotal' is set regardless of other
                functions) and binary formats (where 'defaultSubtotal' is not
                set if other functions are set). */
            ::std::vector< GeneralFunction > aSubtotals;
            /*  Order of subtotals is fixed in Excel. Documentation is a little
                bit confused about which names to use for the count functions.
                For subtotals, 'countA' means 'count all', and 'count' means
                'count numbers'. On the other hand, for the data field
                aggregation function, 'count' means 'count all', and 'countNum'
                means 'count numbers' (see below). */
            if( maModel.mbSumSubtotal )     aSubtotals.push_back( GeneralFunction_SUM );
            if( maModel.mbCountASubtotal )  aSubtotals.push_back( GeneralFunction_COUNT );
            if( maModel.mbAverageSubtotal ) aSubtotals.push_back( GeneralFunction_AVERAGE );
            if( maModel.mbMaxSubtotal )     aSubtotals.push_back( GeneralFunction_MAX );
            if( maModel.mbMinSubtotal )     aSubtotals.push_back( GeneralFunction_MIN );
            if( maModel.mbProductSubtotal ) aSubtotals.push_back( GeneralFunction_PRODUCT );
            if( maModel.mbCountSubtotal )   aSubtotals.push_back( GeneralFunction_COUNTNUMS );
            if( maModel.mbStdDevSubtotal )  aSubtotals.push_back( GeneralFunction_STDEV );
            if( maModel.mbStdDevPSubtotal ) aSubtotals.push_back( GeneralFunction_STDEVP );
            if( maModel.mbVarSubtotal )     aSubtotals.push_back( GeneralFunction_VAR );
            if( maModel.mbVarPSubtotal )    aSubtotals.push_back( GeneralFunction_VARP );
            // if no function is set manually, check the 'defaultSubtotal' flag
            if( aSubtotals.empty() && maModel.mbDefaultSubtotal )
                aSubtotals.push_back( GeneralFunction_AUTO );
            aPropSet.setProperty( PROP_Subtotals, ContainerHelper::vectorToSequence( aSubtotals ) );

            // layout settings
            DataPilotFieldLayoutInfo aLayoutInfo;
            aLayoutInfo.LayoutMode = maModel.mbOutline ?
                (maModel.mbSubtotalTop ? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP : DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM) :
                DataPilotFieldLayoutMode::TABULAR_LAYOUT;
            aLayoutInfo.AddEmptyLines = maModel.mbInsertBlankRow;
            aPropSet.setProperty( PROP_LayoutInfo, aLayoutInfo );
            aPropSet.setProperty( PROP_ShowEmpty, maModel.mbShowAll );

            // auto show (OOXML/BIFF12 only)
            if( maModel.mbAutoShow )
            {
                DataPilotFieldAutoShowInfo aAutoShowInfo;
                aAutoShowInfo.IsEnabled = sal_True;
                aAutoShowInfo.ShowItemsMode = maModel.mbTopAutoShow ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
                aAutoShowInfo.ItemCount = maModel.mnAutoShowItems;
                if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnAutoShowRankBy ) )
                    aAutoShowInfo.DataField = pCacheField->getName();
                aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
            }

            // auto sort
            DataPilotFieldSortInfo aSortInfo;
            aSortInfo.IsAscending = maModel.mnSortType == XML_ascending;
            if( (maModel.mnSortType != XML_ascending) && (maModel.mnSortType != XML_descending) )
            {
                aSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
            }
            else
            {
                const PivotCacheField* pCacheField = (maModel.mnSortRefField == OOX_PT_DATALAYOUTFIELD) ?
                    mrPivotTable.getCacheFieldOfDataField( maModel.mnSortRefItem ) : 0;
                if( pCacheField )
                {
                    aSortInfo.Mode = DataPilotFieldSortMode::DATA;
                    aSortInfo.Field = pCacheField->getName();
                }
                else
                {
                    aSortInfo.Mode = DataPilotFieldSortMode::NAME;
                }
            }
            aPropSet.setProperty( PROP_SortInfo, aSortInfo );

            // item settings
            if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) try
            {
                Reference< XNameAccess > xDPItemsNA( xDPField->getItems(), UNO_QUERY_THROW );
                for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
                {
                    if( aIt->mnType == XML_data )
                    {
                        if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( aIt->mnCacheItem ) ) try
                        {
                            PropertySet aItemProp( xDPItemsNA->getByName( pSharedItem->getName() ) );
                            aItemProp.setProperty( PROP_ShowDetail, aIt->mbShowDetails );
                            aItemProp.setProperty( PROP_IsHidden, aIt->mbHidden );
                        }
                        catch( Exception& )
                        {
                            // catch every failed container access to be able to process following items
                        }
                    }
                }
            }
            catch( Exception& )
            {
            }
        }
    }
    return xDPField;
}

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

PTFilterModel::PTFilterModel() :
    mfValue( 0.0 ),
    mnField( -1 ),
    mnMemPropField( -1 ),
    mnType( XML_TOKEN_INVALID ),
    mnEvalOrder( 0 ),
    mnId( -1 ),
    mnMeasureField( -1 ),
    mnMeasureHier( -1 ),
    mbTopFilter( true )
{
}

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

PivotTableFilter::PivotTableFilter( const PivotTable& rPivotTable ) :
    WorkbookHelper( rPivotTable ),
    mrPivotTable( rPivotTable )
{
}

void PivotTableFilter::importFilter( const AttributeList& rAttribs )
{
    maModel.maName         = rAttribs.getXString( XML_name, OUString() );
    maModel.maDescription  = rAttribs.getXString( XML_description, OUString() );
    maModel.maStrValue1    = rAttribs.getXString( XML_stringValue1, OUString() );
    maModel.maStrValue2    = rAttribs.getXString( XML_stringValue2, OUString() );
    maModel.mnField        = rAttribs.getInteger( XML_fld, -1 );
    maModel.mnMemPropField = rAttribs.getInteger( XML_mpFld, -1 );
    maModel.mnType         = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
    maModel.mnEvalOrder    = rAttribs.getInteger( XML_evalOrder, 0 );
    maModel.mnId           = rAttribs.getInteger( XML_id, -1 );
    maModel.mnMeasureField = rAttribs.getInteger( XML_iMeasureFld, -1 );
    maModel.mnMeasureHier  = rAttribs.getInteger( XML_iMeasureHier, -1 );
}

void PivotTableFilter::importTop10( const AttributeList& rAttribs )
{
    OSL_ENSURE( rAttribs.getBool( XML_percent, false ) == (maModel.mnType == XML_percent),
        "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
    maModel.mfValue     = rAttribs.getDouble( XML_val, 0.0 );
    maModel.mbTopFilter = rAttribs.getBool( XML_top, true );
}

void PivotTableFilter::importPTFilter( SequenceInputStream& rStrm )
{
    sal_Int32 nType;
    sal_uInt16 nFlags;
    rStrm >> maModel.mnField >> maModel.mnMemPropField >> nType;
    rStrm.skip( 4 );    // unused
    rStrm >> maModel.mnId >> maModel.mnMeasureField >> maModel.mnMeasureHier >> nFlags;
    if( getFlag( nFlags, BIFF12_PTFILTER_HASNAME ) )
        rStrm >> maModel.maName;
    if( getFlag( nFlags, BIFF12_PTFILTER_HASDESCRIPTION ) )
        rStrm >> maModel.maDescription;
    if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE1 ) )
        rStrm >> maModel.maStrValue1;
    if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE2 ) )
        rStrm >> maModel.maStrValue2;

    static sal_Int32 spnTypes[] =
    {
        XML_unknown,
        // data field top10 filter (1-3)
        XML_count, XML_percent, XML_sum,
        // caption filter (4-17)
        XML_captionEqual, XML_captionNotEqual,
        XML_captionBeginsWith, XML_captionNotBeginsWith, XML_captionEndsWith, XML_captionNotEndsWith,
        XML_captionContains, XML_captionNotContains, XML_captionGreaterThan, XML_captionGreaterThanOrEqual,
        XML_captionLessThan, XML_captionLessThanOrEqual, XML_captionBetween, XML_captionNotBetween,
        // value filter (18-25)
        XML_valueEqual, XML_valueNotEqual, XML_valueGreaterThan, XML_valueGreaterThanOrEqual,
        XML_valueLessThan, XML_valueLessThanOrEqual, XML_valueBetween, XML_valueNotBetween,
        // date filter (26-65)
        XML_dateEqual, XML_dateOlderThan, XML_dateNewerThan, XML_dateBetween,
        XML_tomorrow, XML_today, XML_yesterday, XML_nextWeek, XML_thisWeek, XML_lastWeek,
        XML_nextMonth, XML_thisMonth, XML_lastMonth, XML_nextQuarter, XML_thisQuarter, XML_lastQuarter,
        XML_nextYear, XML_thisYear, XML_lastYear, XML_yearToDate, XML_Q1, XML_Q2, XML_Q3, XML_Q4,
        XML_M1, XML_M2, XML_M3, XML_M4, XML_M5, XML_M6, XML_M7, XML_M8, XML_M9, XML_M10, XML_M11, XML_M12,
        XML_dateNotEqual, XML_dateOlderThanOrEqual, XML_dateNewerThanOrEqual, XML_dateNotBetween
    };
    maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
}

void PivotTableFilter::importTop10Filter( SequenceInputStream& rStrm )
{
    sal_uInt8 nFlags;
    rStrm >> nFlags >> maModel.mfValue;

    OSL_ENSURE( getFlag( nFlags, BIFF12_TOP10FILTER_PERCENT ) == (maModel.mnType == XML_percent),
        "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
    maModel.mbTopFilter = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
}

void PivotTableFilter::finalizeImport()
{
    // only simple top10 filter supported
    if( maModel.mnType == XML_count )
    {
        PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) );
        if( aPropSet.is() )
        {
            using namespace ::com::sun::star::sheet;
            DataPilotFieldAutoShowInfo aAutoShowInfo;
            aAutoShowInfo.IsEnabled = sal_True;
            aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
            aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 );
            if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) )
                aAutoShowInfo.DataField = pCacheField->getName();
            aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
        }
    }
}

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

PTDefinitionModel::PTDefinitionModel() :
    mnCacheId( -1 ),
    mnDataPosition( 0 ),
    mnPageWrap( 0 ),
    mnIndent( 1 ),
    mnChartFormat( 0 ),
    mnRowFields( 0 ),
    mnColFields( 0 ),
    mbDataOnRows( false ),
    mbShowError( false ),
    mbShowMissing( true ),
    mbShowItems( true ),
    mbDisableFieldList( false ),
    mbShowCalcMembers( true ),
    mbVisualTotals( true ),
    mbShowDrill( true ),
    mbPrintDrill( false ),
    mbEnableDrill( true ),
    mbPreserveFormatting( true ),
    mbUseAutoFormat( false ),
    mbPageOverThenDown( false ),
    mbSubtotalHiddenItems( false ),
    mbRowGrandTotals( true ),
    mbColGrandTotals( true ),
    mbFieldPrintTitles( false ),
    mbItemPrintTitles( false ),
    mbMergeItem( false ),
    mbShowEmptyRow( false ),
    mbShowEmptyCol( false ),
    mbShowHeaders( true ),
    mbFieldListSortAsc( false ),
    mbCustomListSort( true )
{
}

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

PTLocationModel::PTLocationModel() :
    mnFirstHeaderRow( 0 ),
    mnFirstDataRow( 0 ),
    mnFirstDataCol( 0 ),
    mnRowPageCount( 0 ),
    mnColPageCount( 0 )
{
}

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

PivotTable::PivotTable( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper ),
    maDataField( *this, OOX_PT_DATALAYOUTFIELD ),
    mpPivotCache( 0 )
{
}

void PivotTable::importPivotTableDefinition( const AttributeList& rAttribs )
{
    maDefModel.maName                = rAttribs.getXString( XML_name, OUString() );
    maDefModel.maDataCaption         = rAttribs.getXString( XML_dataCaption , OUString() );
    maDefModel.maGrandTotalCaption   = rAttribs.getXString( XML_grandTotalCaption, OUString() );
    maDefModel.maRowHeaderCaption    = rAttribs.getXString( XML_rowHeaderCaption, OUString() );
    maDefModel.maColHeaderCaption    = rAttribs.getXString( XML_colHeaderCaption, OUString() );
    maDefModel.maErrorCaption        = rAttribs.getXString( XML_errorCaption, OUString() );
    maDefModel.maMissingCaption      = rAttribs.getXString( XML_missingCaption, OUString() );
    maDefModel.maPageStyle           = rAttribs.getXString( XML_pageStyle, OUString() );
    maDefModel.maPivotTableStyle     = rAttribs.getXString( XML_pivotTableStyle, OUString() );
    maDefModel.maVacatedStyle        = rAttribs.getXString( XML_vacatedStyle, OUString() );
    maDefModel.maTag                 = rAttribs.getXString( XML_tag, OUString() );
    maDefModel.mnCacheId             = rAttribs.getInteger( XML_cacheId, -1 );
    maDefModel.mnDataPosition        = rAttribs.getInteger( XML_dataPosition, 0 );
    maDefModel.mnPageWrap            = rAttribs.getInteger( XML_pageWrap, 0 );
    maDefModel.mnIndent              = rAttribs.getInteger( XML_indent, 1 );
    maDefModel.mnChartFormat         = rAttribs.getInteger( XML_chartFormat, 0 );
    maDefModel.mnAutoFormatId        = rAttribs.getInteger( XML_autoFormatId, 0 );
    maDefModel.mbDataOnRows          = rAttribs.getBool( XML_dataOnRows, false );
    maDefModel.mbShowError           = rAttribs.getBool( XML_showError, false );
    maDefModel.mbShowMissing         = rAttribs.getBool( XML_showMissing, true );
    maDefModel.mbShowItems           = rAttribs.getBool( XML_showItems, true );
    maDefModel.mbDisableFieldList    = rAttribs.getBool( XML_disableFieldList, false );
    maDefModel.mbShowCalcMembers     = rAttribs.getBool( XML_showCalcMbrs, true );
    maDefModel.mbVisualTotals        = rAttribs.getBool( XML_visualTotals, true );
    maDefModel.mbShowDrill           = rAttribs.getBool( XML_showDrill, true );
    maDefModel.mbPrintDrill          = rAttribs.getBool( XML_printDrill, false );
    maDefModel.mbEnableDrill         = rAttribs.getBool( XML_enableDrill, true );
    maDefModel.mbPreserveFormatting  = rAttribs.getBool( XML_preserveFormatting, true );
    maDefModel.mbUseAutoFormat       = rAttribs.getBool( XML_useAutoFormatting, false );
    maDefModel.mbPageOverThenDown    = rAttribs.getBool( XML_pageOverThenDown, false );
    maDefModel.mbSubtotalHiddenItems = rAttribs.getBool( XML_subtotalHiddenItems, false );
    maDefModel.mbRowGrandTotals      = rAttribs.getBool( XML_rowGrandTotals, true );
    maDefModel.mbColGrandTotals      = rAttribs.getBool( XML_colGrandTotals, true );
    maDefModel.mbFieldPrintTitles    = rAttribs.getBool( XML_fieldPrintTitles, false );
    maDefModel.mbItemPrintTitles     = rAttribs.getBool( XML_itemPrintTitles, false );
    maDefModel.mbMergeItem           = rAttribs.getBool( XML_mergeItem, false );
    maDefModel.mbShowEmptyRow        = rAttribs.getBool( XML_showEmptyRow, false );
    maDefModel.mbShowEmptyCol        = rAttribs.getBool( XML_showEmptyCol, false );
    maDefModel.mbShowHeaders         = rAttribs.getBool( XML_showHeaders, true );
    maDefModel.mbFieldListSortAsc    = rAttribs.getBool( XML_fieldListSortAscending, false );
    maDefModel.mbCustomListSort      = rAttribs.getBool( XML_customListSort, true );
    maDefModel.mbApplyNumFmt         = rAttribs.getBool( XML_applyNumberFormats, false );
    maDefModel.mbApplyFont           = rAttribs.getBool( XML_applyFontFormats, false );
    maDefModel.mbApplyAlignment      = rAttribs.getBool( XML_applyAlignmentFormats, false );
    maDefModel.mbApplyBorder         = rAttribs.getBool( XML_applyBorderFormats, false );
    maDefModel.mbApplyFill           = rAttribs.getBool( XML_applyPatternFormats, false );
    // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
    maDefModel.mbApplyProtection     = rAttribs.getBool( XML_applyWidthHeightFormats, false );
}

void PivotTable::importLocation( const AttributeList& rAttribs, sal_Int16 nSheet )
{
    getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet );
    maLocationModel.mnFirstHeaderRow = rAttribs.getInteger( XML_firstHeaderRow, 0 );
    maLocationModel.mnFirstDataRow   = rAttribs.getInteger( XML_firstDataRow, 0 );
    maLocationModel.mnFirstDataCol   = rAttribs.getInteger( XML_firstDataCol, 0 );
    maLocationModel.mnRowPageCount   = rAttribs.getInteger( XML_rowPageCount, 0 );
    maLocationModel.mnColPageCount   = rAttribs.getInteger( XML_colPageCount, 0 );
}

void PivotTable::importRowField( const AttributeList& rAttribs )
{
    importField( maRowFields, rAttribs );
}

void PivotTable::importColField( const AttributeList& rAttribs )
{
    importField( maColFields, rAttribs );
}

void PivotTable::importPageField( const AttributeList& rAttribs )
{
    PTPageFieldModel aModel;
    aModel.maName      = rAttribs.getXString( XML_name, OUString() );
    aModel.mnField     = rAttribs.getInteger( XML_fld, -1 );
    // specification is wrong, XML_item is not the cache item, but the field item
    aModel.mnItem      = rAttribs.getInteger( XML_item, BIFF12_PTPAGEFIELD_MULTIITEMS );
    maPageFields.push_back( aModel );
}

void PivotTable::importDataField( const AttributeList& rAttribs )
{
    PTDataFieldModel aModel;
    aModel.maName       = rAttribs.getXString( XML_name, OUString() );
    aModel.mnField      = rAttribs.getInteger( XML_fld, -1 );
    aModel.mnSubtotal   = rAttribs.getToken( XML_subtotal, XML_sum );
    aModel.mnShowDataAs = rAttribs.getToken( XML_showDataAs, XML_normal );
    aModel.mnBaseField  = rAttribs.getInteger( XML_baseField, -1 );
    aModel.mnBaseItem   = rAttribs.getInteger( XML_baseItem, -1 );
    aModel.mnNumFmtId   = rAttribs.getInteger( XML_numFmtId, 0 );
    maDataFields.push_back( aModel );
}

void PivotTable::importPTDefinition( SequenceInputStream& rStrm )
{
    sal_uInt32 nFlags1, nFlags2, nFlags3;
    sal_uInt8 nDataAxis;
    rStrm >> nFlags1 >> nFlags2 >> nFlags3 >> nDataAxis;
    maDefModel.mnPageWrap = rStrm.readuInt8();
    rStrm.skip( 2 );    // refresh versions
    rStrm >> maDefModel.mnDataPosition;
    maDefModel.mnAutoFormatId = rStrm.readuInt16();
    rStrm.skip( 2 );    // unused
    rStrm >> maDefModel.mnChartFormat >> maDefModel.mnCacheId >> maDefModel.maName;
    if( getFlag( nFlags2, BIFF12_PTDEF_HASDATACAPTION ) )
        rStrm >> maDefModel.maDataCaption;
    if( getFlag( nFlags2, BIFF12_PTDEF_HASGRANDTOTALCAPTION ) )
        rStrm >> maDefModel.maGrandTotalCaption;
    if( !getFlag( nFlags3, BIFF12_PTDEF_NOERRORCAPTION ) )   // missing flag indicates existing string
        rStrm >> maDefModel.maErrorCaption;
    if( !getFlag( nFlags3, BIFF12_PTDEF_NOMISSINGCAPTION ) ) // missing flag indicates existing string
        rStrm >> maDefModel.maMissingCaption;
    if( getFlag( nFlags2, BIFF12_PTDEF_HASPAGESTYLE ) )
        rStrm >> maDefModel.maPageStyle;
    if( getFlag( nFlags2, BIFF12_PTDEF_HASPIVOTTABLESTYLE ) )
        rStrm >> maDefModel.maPivotTableStyle;
    if( getFlag( nFlags2, BIFF12_PTDEF_HASVACATEDSTYLE ) )
        rStrm >> maDefModel.maVacatedStyle;
    if( getFlag( nFlags2, BIFF12_PTDEF_HASTAG ) )
        rStrm >> maDefModel.maTag;
    if( getFlag( nFlags3, BIFF12_PTDEF_HASCOLHEADERCAPTION ) )   // TODO: right order (col/row)? spec is unclear
        rStrm >> maDefModel.maColHeaderCaption;
    if( getFlag( nFlags3, BIFF12_PTDEF_HASROWHEADERCAPTION ) )
        rStrm >> maDefModel.maRowHeaderCaption;

    OSL_ENSURE( (nDataAxis == BIFF12_PTDEF_ROWAXIS) || (nDataAxis == BIFF12_PTDEF_COLAXIS),
        "PivotTable::importPTDefinition - unexpected axis position for data field" );

    maDefModel.mnIndent              = extractValue< sal_uInt8 >( nFlags1, 24, 7 );
    maDefModel.mbDataOnRows          = nDataAxis == BIFF12_PTDEF_ROWAXIS;
    maDefModel.mbShowError           = getFlag( nFlags2, BIFF12_PTDEF_SHOWERROR );
    maDefModel.mbShowMissing         = getFlag( nFlags2, BIFF12_PTDEF_SHOWMISSING );
    maDefModel.mbShowItems           = getFlag( nFlags1, BIFF12_PTDEF_SHOWITEMS );
    maDefModel.mbDisableFieldList    = getFlag( nFlags1, BIFF12_PTDEF_DISABLEFIELDLIST );
    maDefModel.mbShowCalcMembers     = !getFlag( nFlags1, BIFF12_PTDEF_HIDECALCMEMBERS );
    maDefModel.mbVisualTotals        = !getFlag( nFlags1, BIFF12_PTDEF_WITHHIDDENTOTALS );
    maDefModel.mbShowDrill           = !getFlag( nFlags1, BIFF12_PTDEF_HIDEDRILL );
    maDefModel.mbPrintDrill          = getFlag( nFlags1, BIFF12_PTDEF_PRINTDRILL );
    maDefModel.mbEnableDrill         = getFlag( nFlags2, BIFF12_PTDEF_ENABLEDRILL );
    maDefModel.mbPreserveFormatting  = getFlag( nFlags2, BIFF12_PTDEF_PRESERVEFORMATTING );
    maDefModel.mbUseAutoFormat       = getFlag( nFlags2, BIFF12_PTDEF_USEAUTOFORMAT );
    maDefModel.mbPageOverThenDown    = getFlag( nFlags2, BIFF12_PTDEF_PAGEOVERTHENDOWN );
    maDefModel.mbSubtotalHiddenItems = getFlag( nFlags2, BIFF12_PTDEF_SUBTOTALHIDDENITEMS );
    maDefModel.mbRowGrandTotals      = getFlag( nFlags2, BIFF12_PTDEF_ROWGRANDTOTALS );
    maDefModel.mbColGrandTotals      = getFlag( nFlags2, BIFF12_PTDEF_COLGRANDTOTALS );
    maDefModel.mbFieldPrintTitles    = getFlag( nFlags2, BIFF12_PTDEF_FIELDPRINTTITLES );
    maDefModel.mbItemPrintTitles     = getFlag( nFlags2, BIFF12_PTDEF_ITEMPRINTTITLES );
    maDefModel.mbMergeItem           = getFlag( nFlags2, BIFF12_PTDEF_MERGEITEM );
    maDefModel.mbApplyNumFmt         = getFlag( nFlags2, BIFF12_PTDEF_APPLYNUMFMT );
    maDefModel.mbApplyFont           = getFlag( nFlags2, BIFF12_PTDEF_APPLYFONT );
    maDefModel.mbApplyAlignment      = getFlag( nFlags2, BIFF12_PTDEF_APPLYALIGNMENT );
    maDefModel.mbApplyBorder         = getFlag( nFlags2, BIFF12_PTDEF_APPLYBORDER );
    maDefModel.mbApplyFill           = getFlag( nFlags2, BIFF12_PTDEF_APPLYFILL );
    maDefModel.mbApplyProtection     = getFlag( nFlags2, BIFF12_PTDEF_APPLYPROTECTION );
    maDefModel.mbShowEmptyRow        = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYROW );
    maDefModel.mbShowEmptyCol        = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYCOL );
    maDefModel.mbShowHeaders         = !getFlag( nFlags1, BIFF12_PTDEF_HIDEHEADERS );
    maDefModel.mbFieldListSortAsc    = getFlag( nFlags3, BIFF12_PTDEF_FIELDLISTSORTASC );
    maDefModel.mbCustomListSort      = !getFlag( nFlags3, BIFF12_PTDEF_NOCUSTOMLISTSORT );
}

void PivotTable::importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet )
{
    BinRange aBinRange;
    rStrm   >> aBinRange >> maLocationModel.mnFirstHeaderRow
            >> maLocationModel.mnFirstDataRow >> maLocationModel.mnFirstDataCol
            >> maLocationModel.mnRowPageCount >> maLocationModel.mnColPageCount;
    getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
}

void PivotTable::importPTRowFields( SequenceInputStream& rStrm )
{
    importFields( maRowFields, rStrm );
}

void PivotTable::importPTColFields( SequenceInputStream& rStrm )
{
    importFields( maColFields, rStrm );
}

void PivotTable::importPTPageField( SequenceInputStream& rStrm )
{
    PTPageFieldModel aModel;
    sal_uInt8 nFlags;
    rStrm >> aModel.mnField >> aModel.mnItem;
    rStrm.skip( 4 );    // hierarchy
    rStrm >> nFlags;
    if( getFlag( nFlags, BIFF12_PTPAGEFIELD_HASNAME ) )
        rStrm >> aModel.maName;
    maPageFields.push_back( aModel );
}

void PivotTable::importPTDataField( SequenceInputStream& rStrm )
{
    PTDataFieldModel aModel;
    sal_Int32 nSubtotal, nShowDataAs;
    sal_uInt8 nHasName;
    rStrm >> aModel.mnField >> nSubtotal >> nShowDataAs >> aModel.mnBaseField >> aModel.mnBaseItem >> aModel.mnNumFmtId >> nHasName;
    if( nHasName == 1 )
        rStrm >> aModel.maName;
    aModel.setBiffSubtotal( nSubtotal );
    aModel.setBiffShowDataAs( nShowDataAs );
    maDataFields.push_back( aModel );
}

void PivotTable::importPTDefinition( BiffInputStream& rStrm, sal_Int16 nSheet )
{
    BinRange aBinRange;
    sal_uInt16 nFlags, nTabNameLen, nDataNameLen;
    rStrm >> aBinRange;
    maLocationModel.mnFirstHeaderRow = rStrm.readuInt16();
    maLocationModel.mnFirstDataRow   = rStrm.readuInt16();
    maLocationModel.mnFirstDataCol   = rStrm.readuInt16();
    maDefModel.mnCacheId             = rStrm.readuInt16();
    rStrm.skip( 2 );                 // unused
    maDefModel.mbDataOnRows          = rStrm.readuInt16() == BIFF_PTDEF_ROWAXIS;
    maDefModel.mnDataPosition        = rStrm.readInt16();
    rStrm.skip( 2 );                 // number of fields
    rStrm >> maDefModel.mnRowFields >> maDefModel.mnColFields;
    rStrm.skip( 8 );                 // number of page fields, data fields, data rows, data columns
    rStrm >> nFlags;
    maDefModel.mnChartFormat         = rStrm.readuInt16();
    rStrm >> nTabNameLen >> nDataNameLen;
    maDefModel.maName                = lclReadPivotString( *this, rStrm, nTabNameLen );
    maDefModel.maDataCaption         = lclReadPivotString( *this, rStrm, nDataNameLen );

    maDefModel.mbRowGrandTotals  = getFlag( nFlags, BIFF_PTDEF_ROWGRANDTOTALS );
    maDefModel.mbColGrandTotals  = getFlag( nFlags, BIFF_PTDEF_COLGRANDTOTALS );

    getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
}

void PivotTable::importPTDefinition2( BiffInputStream& rStrm )
{
    if( getBiff() == BIFF8 )
    {
        sal_uInt16 nErrCaptLen, nMissCaptLen, nTagLen, nPageStyleLen, nTabStyleLen, nVacStyleLen;
        sal_uInt32 nFlags;
        rStrm.skip( 2 );    // number of formatting records
        rStrm >> nErrCaptLen >> nMissCaptLen >> nTagLen;
        rStrm.skip( 6 );    // number of selection records, page rows, page columns
        rStrm >> nFlags >> nPageStyleLen >> nTabStyleLen >> nVacStyleLen;
        maDefModel.maErrorCaption    = lclReadPivotString( *this, rStrm, nErrCaptLen );
        maDefModel.maMissingCaption  = lclReadPivotString( *this, rStrm, nMissCaptLen );
        maDefModel.maTag             = lclReadPivotString( *this, rStrm, nTagLen );
        maDefModel.maPageStyle       = lclReadPivotString( *this, rStrm, nPageStyleLen );
        maDefModel.maPivotTableStyle = lclReadPivotString( *this, rStrm, nTabStyleLen );
        maDefModel.maVacatedStyle    = lclReadPivotString( *this, rStrm, nVacStyleLen );

        maDefModel.mbShowError           = getFlag( nFlags, BIFF_PTDEF2_SHOWERROR );
        maDefModel.mbShowMissing         = getFlag( nFlags, BIFF_PTDEF2_SHOWMISSING );
        maDefModel.mbEnableDrill         = getFlag( nFlags, BIFF_PTDE2F_ENABLEDRILL );
        maDefModel.mbPreserveFormatting  = getFlag( nFlags, BIFF_PTDEF2_PRESERVEFORMATTING );
        maDefModel.mbPageOverThenDown    = getFlag( nFlags, BIFF_PTDEF2_PAGEOVERTHENDOWN );
        maDefModel.mbSubtotalHiddenItems = getFlag( nFlags, BIFF_PTDEF2_SUBTOTALHIDDENITEMS );
        maDefModel.mbMergeItem           = getFlag( nFlags, BIFF_PTDEF2_MERGEITEM );
    }
}

void PivotTable::importPTRowColFields( BiffInputStream& rStrm )
{
    // first PTROWCOLFIELDS record contains row fields unless there are no row fields
    if( (maDefModel.mnRowFields > 0) && maRowFields.empty() )
        importFields( maRowFields, rStrm, maDefModel.mnRowFields );
    else if( (maDefModel.mnColFields > 0) && maColFields.empty() )
        importFields( maColFields, rStrm, maDefModel.mnColFields );
}

void PivotTable::importPTPageFields( BiffInputStream& rStrm )
{
    while( rStrm.getRemaining() >= 6 )
    {
        PTPageFieldModel aModel;
        sal_Int16 nField, nItem;
        rStrm >> nField >> nItem;
        rStrm.skip( 2 );    // dropdown object ID
        aModel.mnField = nField;
        aModel.mnItem = (nItem == BIFF_PTPAGEFIELDS_ALLITEMS) ? BIFF12_PTPAGEFIELD_MULTIITEMS : nItem;
        maPageFields.push_back( aModel );
    }
}

void PivotTable::importPTDataField( BiffInputStream& rStrm )
{
    PTDataFieldModel aModel;
    sal_Int16 nField, nBaseField, nBaseItem;
    sal_uInt16 nSubtotal, nShowDataAs, nNumFmt, nNameLen;
    rStrm >> nField >> nSubtotal >> nShowDataAs >> nBaseField >> nBaseItem >> nNumFmt >> nNameLen;
    aModel.maName = lclReadPivotString( *this, rStrm, nNameLen );

    aModel.mnField = nField;
    aModel.setBiffSubtotal( nSubtotal );
    aModel.setBiffShowDataAs( nShowDataAs );
    aModel.mnBaseField = nBaseField;
    switch( nBaseItem )
    {
        case BIFF_PTDATAFIELD_PREVIOUS: aModel.mnBaseItem = OOX_PT_PREVIOUS_ITEM;   break;
        case BIFF_PTDATAFIELD_NEXT:     aModel.mnBaseItem = OOX_PT_NEXT_ITEM;       break;
        default:                        aModel.mnBaseItem = nBaseItem;
    }
    aModel.mnNumFmtId = nNumFmt;

    maDataFields.push_back( aModel );
}

PivotTableField& PivotTable::createTableField()
{
    sal_Int32 nFieldIndex = static_cast< sal_Int32 >( maFields.size() );
    PivotTableFieldVector::value_type xTableField( new PivotTableField( *this, nFieldIndex ) );
    maFields.push_back( xTableField );
    return *xTableField;
}

PivotTableFilter& PivotTable::createTableFilter()
{
    PivotTableFilterVector::value_type xTableFilter( new PivotTableFilter( *this ) );
    maFilters.push_back( xTableFilter );
    return *xTableFilter;
}

void PivotTable::finalizeImport()
{
    if( getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) )
    {
        mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId );
        if( mpPivotCache && mpPivotCache->isValidDataSource() && (maDefModel.maName.getLength() > 0) )
        {
            // clear destination area of the original pivot table
            try
            {
                Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW );
                using namespace ::com::sun::star::sheet::CellFlags;
                xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED );
            }
            catch( Exception& )
            {
            }

            try
            {
                // create a new data pilot descriptor based on the source data
                Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.Sheet ), UNO_QUERY_THROW );
                Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW );
                mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW );
                mxDPDescriptor->setSourceRange( mpPivotCache->getSourceRange() );
                mxDPDescriptor->setTag( maDefModel.maTag );

                // global data pilot properties
                PropertySet aDescProp( mxDPDescriptor );
                aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals );
                aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals );
                aDescProp.setProperty( PROP_ShowFilterButton, false );
                aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill );

                // finalize all fields, this finds field names and creates grouping fields
                maFields.forEachMem( &PivotTableField::finalizeImport, ::boost::cref( mxDPDescriptor ) );

                // all row fields
                for( IndexVector::iterator aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
                    if( PivotTableField* pField = getTableField( *aIt ) )
                        pField->convertRowField();

                // all column fields
                for( IndexVector::iterator aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt )
                    if( PivotTableField* pField = getTableField( *aIt ) )
                        pField->convertColField();

                // all page fields
                for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
                    if( PivotTableField* pField = getTableField( aIt->mnField ) )
                        pField->convertPageField( *aIt );

                // all hidden fields
                ::std::set< sal_Int32 > aVisFields;
                aVisFields.insert( maRowFields.begin(), maRowFields.end() );
                aVisFields.insert( maColFields.begin(), maColFields.end() );
                for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
                    aVisFields.insert( aIt->mnField );
                for( PivotTableFieldVector::iterator aBeg = maFields.begin(), aIt = aBeg, aEnd = maFields.end(); aIt != aEnd; ++aIt )
                    if( aVisFields.count( static_cast< sal_Int32 >( aIt - aBeg ) ) == 0 )
                        (*aIt)->convertHiddenField();

                // all data fields
                for( DataFieldVector::iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
                    if( PivotTableField* pField = getTableField( aIt->mnField ) )
                        pField->convertDataField( *aIt );

                // filters
                maFilters.forEachMem( &PivotTableFilter::finalizeImport );

                // calculate base position of table
                CellAddress aPos( maLocationModel.maRange.Sheet, maLocationModel.maRange.StartColumn, maLocationModel.maRange.StartRow );
                /*  If page fields exist, include them into the destination
                    area (they are excluded in Excel). Add an extra blank row. */
                if( !maPageFields.empty() )
                    aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 );

                // insert the DataPilot table into the sheet
                xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
            }
            catch( Exception& )
            {
                OSL_ENSURE( false, "PivotTable::finalizeImport - exception while creating the DataPilot table" );
            }
        }
    }
}

void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
{
    // process all fields, there is no chaining information in the cache fields
    maFields.forEachMem( &PivotTableField::finalizeDateGroupingImport, ::boost::cref( rxBaseDPField ), nBaseFieldIdx );
}

void PivotTable::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField,
        const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
{
    // try to create parent group fields that group the items of the passed base field
    if( PivotTableField* pParentTableField = maFields.get( rBaseCacheField.getParentGroupField() ).get() )
        pParentTableField->finalizeParentGroupingImport( rxBaseDPField, orItemNames );
}

Reference< XDataPilotField > PivotTable::getDataPilotField( const OUString& rFieldName ) const
{
    Reference< XDataPilotField > xDPField;
    if( (rFieldName.getLength() > 0) && mxDPDescriptor.is() ) try
    {
        Reference< XNameAccess > xDPFieldsNA( mxDPDescriptor->getDataPilotFields(), UNO_QUERY_THROW );
        xDPField.set( xDPFieldsNA->getByName( rFieldName ), UNO_QUERY );
    }
    catch( Exception& )
    {
    }
    return xDPField;
}

Reference< XDataPilotField > PivotTable::getDataPilotField( sal_Int32 nFieldIdx ) const
{
    Reference< XDataPilotField > xDPField;
    if( const PivotTableField* pTableField = maFields.get( nFieldIdx ).get() )
        xDPField = getDataPilotField( pTableField->getDPFieldName() );
    return xDPField;
}

Reference< XDataPilotField > PivotTable::getDataLayoutField() const
{
    Reference< XDataPilotField > xDPField;
    try
    {
        Reference< XDataPilotDataLayoutFieldSupplier > xDPDataFieldSupp( mxDPDescriptor, UNO_QUERY_THROW );
        xDPField = xDPDataFieldSupp->getDataLayoutField();
    }
    catch( Exception& )
    {
    }
    return xDPField;
}

const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const
{
    return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : 0;
}

const PivotCacheField* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const
{
    const PTDataFieldModel* pDataField = ContainerHelper::getVectorElement( maDataFields, nDataItemIdx );
    return pDataField ? getCacheField( pDataField->mnField ) : 0;
}

sal_Int32 PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
{
    return mpPivotCache ? mpPivotCache->getCacheDatabaseIndex( nFieldIdx ) : -1;
}

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

PivotTableField* PivotTable::getTableField( sal_Int32 nFieldIdx )
{
    return (nFieldIdx == OOX_PT_DATALAYOUTFIELD) ? &maDataField : maFields.get( nFieldIdx ).get();
}

void PivotTable::importField( IndexVector& orFields, const AttributeList& rAttribs )
{
    orFields.push_back( rAttribs.getInteger( XML_x, -1 ) );
}

void PivotTable::importFields( IndexVector& orFields, SequenceInputStream& rStrm )
{
    OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
    orFields.clear();
    sal_Int32 nCount = rStrm.readInt32();
    OSL_ENSURE( 4 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
    nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 4 );
    for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
        orFields.push_back( rStrm.readInt32() );
}

void PivotTable::importFields( IndexVector& orFields, BiffInputStream& rStrm, sal_Int32 nCount )
{
    OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
    orFields.clear();
    OSL_ENSURE( 2 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
    nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 2 );
    for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
        orFields.push_back( rStrm.readInt16() );
}

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

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

PivotTable& PivotTableBuffer::createPivotTable()
{
    PivotTableVector::value_type xTable( new PivotTable( *this ) );
    maTables.push_back( xTable );
    return *xTable;
}

void PivotTableBuffer::finalizeImport()
{
    maTables.forEachMem( &PivotTable::finalizeImport );
}

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

} // namespace xls
} // namespace oox
