LCOV - code coverage report
Current view: top level - sc/source/filter/oox - pivottablebuffer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 332 681 48.8 %
Date: 2015-06-13 12:38:46 Functions: 36 67 53.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "pivottablebuffer.hxx"
      21             : 
      22             : #include <set>
      23             : #include <com/sun/star/container/XIndexAccess.hpp>
      24             : #include <com/sun/star/container/XNameAccess.hpp>
      25             : #include <com/sun/star/sheet/CellFlags.hpp>
      26             : #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
      27             : #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
      28             : #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
      29             : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
      30             : #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
      31             : #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
      32             : #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
      33             : #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
      34             : #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
      35             : #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
      36             : #include <com/sun/star/sheet/GeneralFunction.hpp>
      37             : #include <com/sun/star/sheet/XDataPilotDataLayoutFieldSupplier.hpp>
      38             : #include <com/sun/star/sheet/XDataPilotField.hpp>
      39             : #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
      40             : #include <com/sun/star/sheet/XSheetOperation.hpp>
      41             : #include <oox/helper/attributelist.hxx>
      42             : #include <oox/helper/containerhelper.hxx>
      43             : #include <oox/helper/propertyset.hxx>
      44             : #include <oox/token/properties.hxx>
      45             : #include "addressconverter.hxx"
      46             : #include "biffinputstream.hxx"
      47             : 
      48             : #include "dapiuno.hxx"
      49             : #include "dpobject.hxx"
      50             : #include "dpsave.hxx"
      51             : 
      52             : namespace oox {
      53             : namespace xls {
      54             : 
      55             : using namespace ::com::sun::star::container;
      56             : using namespace ::com::sun::star::sheet;
      57             : using namespace ::com::sun::star::table;
      58             : using namespace ::com::sun::star::uno;
      59             : using namespace com::sun::star;
      60             : 
      61             : namespace {
      62             : 
      63             : const sal_Int32 OOX_PT_DATALAYOUTFIELD              = -2;           /// Placeholder index of data layout field.
      64             : 
      65             : const sal_Int32 OOX_PT_PREVIOUS_ITEM                = 0x001000FC;   /// Calculation of data item result is based on previous item.
      66             : const sal_Int32 OOX_PT_NEXT_ITEM                    = 0x001000FD;   /// Calculation of data item result is based on next item.
      67             : 
      68             : const sal_uInt32 BIFF12_PTFIELD_DATAFIELD           = 0x00000008;
      69             : const sal_uInt32 BIFF12_PTFIELD_DEFAULT             = 0x00000100;
      70             : const sal_uInt32 BIFF12_PTFIELD_SUM                 = 0x00000200;
      71             : const sal_uInt32 BIFF12_PTFIELD_COUNTA              = 0x00000400;
      72             : const sal_uInt32 BIFF12_PTFIELD_AVERAGE             = 0x00000800;
      73             : const sal_uInt32 BIFF12_PTFIELD_MAX                 = 0x00001000;
      74             : const sal_uInt32 BIFF12_PTFIELD_MIN                 = 0x00002000;
      75             : const sal_uInt32 BIFF12_PTFIELD_PRODUCT             = 0x00004000;
      76             : const sal_uInt32 BIFF12_PTFIELD_COUNT               = 0x00008000;
      77             : const sal_uInt32 BIFF12_PTFIELD_STDDEV              = 0x00010000;
      78             : const sal_uInt32 BIFF12_PTFIELD_STDDEVP             = 0x00020000;
      79             : const sal_uInt32 BIFF12_PTFIELD_VAR                 = 0x00040000;
      80             : const sal_uInt32 BIFF12_PTFIELD_VARP                = 0x00080000;
      81             : 
      82             : const sal_uInt32 BIFF12_PTFIELD_SHOWALL             = 0x00000020;
      83             : const sal_uInt32 BIFF12_PTFIELD_OUTLINE             = 0x00000040;
      84             : const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW      = 0x00000080;
      85             : const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP         = 0x00000100;
      86             : const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK     = 0x00000800;
      87             : const sal_uInt32 BIFF12_PTFIELD_AUTOSORT            = 0x00001000;
      88             : const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING       = 0x00002000;
      89             : const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW            = 0x00004000;
      90             : const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP         = 0x00008000;
      91             : const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS      = 0x00080000;
      92             : 
      93             : const sal_uInt16 BIFF12_PTFITEM_HIDDEN              = 0x0001;
      94             : const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS         = 0x0002;
      95             : 
      96             : const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME          = 0x01;
      97             : const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS       = 0x001000FE;
      98             : 
      99             : const sal_uInt16 BIFF12_PTFILTER_HASNAME            = 0x0001;
     100             : const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION     = 0x0002;
     101             : const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1       = 0x0004;
     102             : const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2       = 0x0008;
     103             : 
     104             : const sal_uInt8 BIFF12_TOP10FILTER_TOP              = 0x01;
     105             : const sal_uInt8 BIFF12_TOP10FILTER_PERCENT          = 0x02;
     106             : 
     107             : const sal_uInt32 BIFF12_PTDEF_SHOWITEMS             = 0x00000100;
     108             : const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST      = 0x00000400;
     109             : const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS       = 0x00001000;
     110             : const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS      = 0x00002000;
     111             : const sal_uInt32 BIFF12_PTDEF_HIDEDRILL             = 0x00100000;
     112             : const sal_uInt32 BIFF12_PTDEF_PRINTDRILL            = 0x00200000;
     113             : const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS           = 0x80000000;
     114             : 
     115             : const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW          = 0x00000004;
     116             : const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL          = 0x00000008;
     117             : const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL           = 0x00000020;
     118             : const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING    = 0x00000080;
     119             : const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT         = 0x00000100;
     120             : const sal_uInt32 BIFF12_PTDEF_SHOWERROR             = 0x00000200;
     121             : const sal_uInt32 BIFF12_PTDEF_SHOWMISSING           = 0x00000400;
     122             : const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN      = 0x00000800;
     123             : const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS   = 0x00001000;
     124             : const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS        = 0x00002000;
     125             : const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS        = 0x00004000;
     126             : const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES      = 0x00008000;
     127             : const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES       = 0x00020000;
     128             : const sal_uInt32 BIFF12_PTDEF_MERGEITEM             = 0x00040000;
     129             : const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION        = 0x00080000;
     130             : const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION  = 0x00100000;
     131             : const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE          = 0x00200000;
     132             : const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE    = 0x00400000;
     133             : const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE       = 0x00800000;
     134             : const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT           = 0x01000000;
     135             : const sal_uInt32 BIFF12_PTDEF_APPLYFONT             = 0x02000000;
     136             : const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT        = 0x04000000;
     137             : const sal_uInt32 BIFF12_PTDEF_APPLYBORDER           = 0x08000000;
     138             : const sal_uInt32 BIFF12_PTDEF_APPLYFILL             = 0x10000000;
     139             : const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION       = 0x20000000;
     140             : const sal_uInt32 BIFF12_PTDEF_HASTAG                = 0x40000000;
     141             : 
     142             : const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION        = 0x00000040;
     143             : const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION      = 0x00000080;
     144             : const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION   = 0x00000400;
     145             : const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION   = 0x00000800;
     146             : const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC      = 0x00001000;
     147             : const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT      = 0x00004000;
     148             : 
     149             : const sal_uInt8 BIFF12_PTDEF_ROWAXIS                = 1;
     150             : const sal_uInt8 BIFF12_PTDEF_COLAXIS                = 2;
     151             : 
     152             : } // namespace
     153             : 
     154          20 : PTFieldItemModel::PTFieldItemModel() :
     155             :     mnCacheItem( -1 ),
     156             :     mnType( XML_data ),
     157             :     mbShowDetails( true ),
     158          20 :     mbHidden( false )
     159             : {
     160          20 : }
     161             : 
     162           0 : void PTFieldItemModel::setBiffType( sal_uInt16 nType )
     163             : {
     164             :     static const sal_Int32 spnTypes[] = { XML_data, XML_default,
     165             :         XML_sum, XML_countA, XML_avg, XML_max, XML_min, XML_product, XML_count,
     166             :         XML_stdDev, XML_stdDevP, XML_var, XML_varP, XML_grand, XML_blank };
     167           0 :     mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_data );
     168           0 : }
     169             : 
     170          28 : PTFieldModel::PTFieldModel() :
     171             :     mnAxis( XML_TOKEN_INVALID ),
     172             :     mnNumFmtId( 0 ),
     173             :     mnAutoShowItems( 10 ),
     174             :     mnAutoShowRankBy( -1 ),
     175             :     mnSortType( XML_manual ),
     176             :     mnSortRefField( -1 ),
     177             :     mnSortRefItem( -1 ),
     178             :     mbDataField( false ),
     179             :     mbDefaultSubtotal( true ),
     180             :     mbSumSubtotal( false ),
     181             :     mbCountASubtotal( false ),
     182             :     mbAverageSubtotal( false ),
     183             :     mbMaxSubtotal( false ),
     184             :     mbMinSubtotal( false ),
     185             :     mbProductSubtotal( false ),
     186             :     mbCountSubtotal( false ),
     187             :     mbStdDevSubtotal( false ),
     188             :     mbStdDevPSubtotal( false ),
     189             :     mbVarSubtotal( false ),
     190             :     mbVarPSubtotal( false ),
     191             :     mbShowAll( true ),
     192             :     mbOutline( true ),
     193             :     mbSubtotalTop( true ),
     194             :     mbInsertBlankRow( false ),
     195             :     mbInsertPageBreak( false ),
     196             :     mbAutoShow( false ),
     197             :     mbTopAutoShow( true ),
     198          28 :     mbMultiPageItems( false )
     199             : {
     200          28 : }
     201             : 
     202           0 : void PTFieldModel::setBiffAxis( sal_uInt8 nAxis )
     203             : {
     204             :     /*  Weird. The axis field is organized as bit field, but only one of the
     205             :         row/col/page flags are allowed at the same time and refer to the values
     206             :         'axisRow', 'axisCol', and 'axisPage' of the XML attribute
     207             :         'pivotField@axis'. Additionally, the fourth bit determines if the field
     208             :         is a data field, which may appear combined with the row/col/page flags.
     209             :         Therefore, this bit is unrelated to the 'axisValues' value of the
     210             :         'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
     211             :         boolean attribute. */
     212             :     static const sal_Int32 spnAxisIds[] = { XML_TOKEN_INVALID, XML_axisRow, XML_axisCol, XML_TOKEN_INVALID, XML_axisPage };
     213           0 :     mnAxis = STATIC_ARRAY_SELECT( spnAxisIds, nAxis, XML_TOKEN_INVALID );
     214           0 : }
     215             : 
     216           4 : PTPageFieldModel::PTPageFieldModel() :
     217             :     mnField( -1 ),
     218           4 :     mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS )
     219             : {
     220           4 : }
     221             : 
     222           6 : PTDataFieldModel::PTDataFieldModel() :
     223             :     mnField( -1 ),
     224             :     mnSubtotal( XML_sum ),
     225             :     mnShowDataAs( XML_normal ),
     226             :     mnBaseField( -1 ),
     227             :     mnBaseItem( -1 ),
     228           6 :     mnNumFmtId( 0 )
     229             : {
     230           6 : }
     231             : 
     232           0 : void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal )
     233             : {
     234             :     static const 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 };
     235           0 :     mnSubtotal = STATIC_ARRAY_SELECT( spnSubtotals, nSubtotal, XML_TOKEN_INVALID );
     236           0 : }
     237             : 
     238           0 : void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs )
     239             : {
     240             :     static const sal_Int32 spnShowDataAs[] = { XML_normal, XML_difference, XML_percent, XML_percentDiff, XML_runTotal, XML_percentOfRow, XML_percentOfCol, XML_percentOfTotal, XML_index };
     241           0 :     mnShowDataAs = STATIC_ARRAY_SELECT( spnShowDataAs, nShowDataAs, XML_TOKEN_INVALID );
     242           0 : }
     243             : 
     244          28 : PivotTableField::PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex ) :
     245             :     WorkbookHelper( rPivotTable ),
     246             :     mrPivotTable( rPivotTable ),
     247          28 :     mnFieldIndex( nFieldIndex )
     248             : {
     249          28 : }
     250             : 
     251          24 : void PivotTableField::importPivotField( const AttributeList& rAttribs )
     252             : {
     253             :     /*  The documentation mentions a value 'axisValues' for the attribute
     254             :         'pivotField@axis'. But this value is not used to mark a data field, as
     255             :         data fields may be inserted in one of the row/column/page dimensions at
     256             :         the same time. Therefore, the boolean attribute 'pivotField@dataField'
     257             :         is really used to mark data fields. */
     258          24 :     maModel.mnAxis            = rAttribs.getToken( XML_axis, XML_TOKEN_INVALID );
     259          24 :     maModel.mnNumFmtId        = rAttribs.getInteger( XML_numFmtId, 0 );
     260          24 :     maModel.mnAutoShowItems   = rAttribs.getInteger( XML_itemPageCount, 10 );
     261          24 :     maModel.mnAutoShowRankBy  = rAttribs.getInteger( XML_rankBy, -1 );
     262          24 :     maModel.mnSortType        = rAttribs.getToken( XML_sortType, XML_manual );
     263          24 :     maModel.mbDataField       = rAttribs.getBool( XML_dataField, false );
     264          24 :     maModel.mbDefaultSubtotal = rAttribs.getBool( XML_defaultSubtotal, true );
     265          24 :     maModel.mbSumSubtotal     = rAttribs.getBool( XML_sumSubtotal, false );
     266          24 :     maModel.mbCountASubtotal  = rAttribs.getBool( XML_countASubtotal, false );
     267          24 :     maModel.mbAverageSubtotal = rAttribs.getBool( XML_avgSubtotal, false );
     268          24 :     maModel.mbMaxSubtotal     = rAttribs.getBool( XML_maxSubtotal, false );
     269          24 :     maModel.mbMinSubtotal     = rAttribs.getBool( XML_minSubtotal, false );
     270          24 :     maModel.mbProductSubtotal = rAttribs.getBool( XML_productSubtotal, false );
     271          24 :     maModel.mbCountSubtotal   = rAttribs.getBool( XML_countSubtotal, false );
     272          24 :     maModel.mbStdDevSubtotal  = rAttribs.getBool( XML_stdDevSubtotal, false );
     273          24 :     maModel.mbStdDevPSubtotal = rAttribs.getBool( XML_stdDevPSubtotal, false );
     274          24 :     maModel.mbVarSubtotal     = rAttribs.getBool( XML_varSubtotal, false );
     275          24 :     maModel.mbVarPSubtotal    = rAttribs.getBool( XML_varPSubtotal, false );
     276          24 :     maModel.mbShowAll         = rAttribs.getBool( XML_showAll, true );
     277          24 :     maModel.mbOutline         = rAttribs.getBool( XML_outline, true );
     278          24 :     maModel.mbSubtotalTop     = rAttribs.getBool( XML_subtotalTop, true );
     279          24 :     maModel.mbInsertBlankRow  = rAttribs.getBool( XML_insertBlankRow, false );
     280          24 :     maModel.mbInsertPageBreak = rAttribs.getBool( XML_insertPageBreak, false );
     281          24 :     maModel.mbAutoShow        = rAttribs.getBool( XML_autoShow, false );
     282          24 :     maModel.mbTopAutoShow     = rAttribs.getBool( XML_topAutoShow, true );
     283          24 :     maModel.mbMultiPageItems  = rAttribs.getBool( XML_multipleItemSelectionAllowed, false );
     284          24 : }
     285             : 
     286          20 : void PivotTableField::importItem( const AttributeList& rAttribs )
     287             : {
     288          20 :     PTFieldItemModel aModel;
     289          20 :     aModel.mnCacheItem   = rAttribs.getInteger( XML_x, -1 );
     290          20 :     aModel.mnType        = rAttribs.getToken( XML_t, XML_data );
     291          20 :     aModel.mbShowDetails = rAttribs.getBool( XML_sd, true );
     292          20 :     aModel.mbHidden      = rAttribs.getBool( XML_h, false );
     293          20 :     aModel.msCaption     = rAttribs.getXString( XML_n, OUString() );
     294          20 :     maItems.push_back( aModel );
     295          20 : }
     296             : 
     297           0 : void PivotTableField::importReference( const AttributeList& rAttribs )
     298             : {
     299             :     // field index is stored as unsigned integer
     300           0 :     maModel.mnSortRefField = static_cast< sal_Int32 >( rAttribs.getUnsigned( XML_field, SAL_MAX_UINT32 ) );
     301           0 : }
     302             : 
     303           0 : void PivotTableField::importReferenceItem( const AttributeList& rAttribs )
     304             : {
     305           0 :     maModel.mnSortRefItem = rAttribs.getInteger( XML_v, -1 );
     306           0 : }
     307             : 
     308           0 : void PivotTableField::importPTField( SequenceInputStream& rStrm )
     309             : {
     310             :     sal_uInt32 nFlags1, nFlags2;
     311           0 :     nFlags1 = rStrm.readuInt32();
     312           0 :     maModel.mnNumFmtId = rStrm.readInt32();
     313           0 :     nFlags2 = rStrm.readuInt32();
     314           0 :     maModel.mnAutoShowItems = rStrm.readInt32();
     315           0 :     maModel.mnAutoShowRankBy = rStrm.readInt32();
     316             : 
     317           0 :     maModel.setBiffAxis( extractValue< sal_uInt8 >( nFlags1, 0, 3 ) );
     318           0 :     maModel.mbDataField       = getFlag( nFlags1, BIFF12_PTFIELD_DATAFIELD );
     319           0 :     maModel.mbDefaultSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_DEFAULT );
     320           0 :     maModel.mbSumSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_SUM );
     321           0 :     maModel.mbCountASubtotal  = getFlag( nFlags1, BIFF12_PTFIELD_COUNTA );
     322           0 :     maModel.mbAverageSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_AVERAGE );
     323           0 :     maModel.mbMaxSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_MAX );
     324           0 :     maModel.mbMinSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_MIN );
     325           0 :     maModel.mbProductSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_PRODUCT );
     326           0 :     maModel.mbCountSubtotal   = getFlag( nFlags1, BIFF12_PTFIELD_COUNT );
     327           0 :     maModel.mbStdDevSubtotal  = getFlag( nFlags1, BIFF12_PTFIELD_STDDEV );
     328           0 :     maModel.mbStdDevPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEVP );
     329           0 :     maModel.mbVarSubtotal     = getFlag( nFlags1, BIFF12_PTFIELD_VAR );
     330           0 :     maModel.mbVarPSubtotal    = getFlag( nFlags1, BIFF12_PTFIELD_VARP );
     331             : 
     332           0 :     maModel.mbShowAll         = getFlag( nFlags2, BIFF12_PTFIELD_SHOWALL );
     333           0 :     maModel.mbOutline         = getFlag( nFlags2, BIFF12_PTFIELD_OUTLINE );
     334           0 :     maModel.mbSubtotalTop     = getFlag( nFlags2, BIFF12_PTFIELD_SUBTOTALTOP );
     335           0 :     maModel.mbInsertBlankRow  = getFlag( nFlags2, BIFF12_PTFIELD_INSERTBLANKROW );
     336           0 :     maModel.mbInsertPageBreak = getFlag( nFlags2, BIFF12_PTFIELD_INSERTPAGEBREAK );
     337           0 :     maModel.mbAutoShow        = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOW );
     338           0 :     maModel.mbTopAutoShow     = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOWTOP );
     339           0 :     maModel.mbMultiPageItems  = getFlag( nFlags2, BIFF12_PTFIELD_MULTIPAGEITEMS );
     340             : 
     341           0 :     bool bAutoSort = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSORT );
     342           0 :     bool bAscending = getFlag( nFlags2, BIFF12_PTFIELD_SORTASCENDING );
     343           0 :     maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
     344           0 : }
     345             : 
     346           0 : void PivotTableField::importPTFItem( SequenceInputStream& rStrm )
     347             : {
     348           0 :     PTFieldItemModel aModel;
     349             :     sal_uInt8 nType;
     350             :     sal_uInt16 nFlags;
     351           0 :     nType = rStrm.readuChar();
     352           0 :     nFlags = rStrm.readuInt16();
     353           0 :     aModel.mnCacheItem = rStrm.readInt32();
     354             : 
     355           0 :     aModel.setBiffType( nType );
     356           0 :     aModel.mbShowDetails = !getFlag( nFlags, BIFF12_PTFITEM_HIDEDETAILS );
     357           0 :     aModel.mbHidden      = getFlag( nFlags, BIFF12_PTFITEM_HIDDEN );
     358             : 
     359           0 :     maItems.push_back( aModel );
     360           0 : }
     361             : 
     362           0 : void PivotTableField::importPTReference( SequenceInputStream& rStrm )
     363             : {
     364           0 :     maModel.mnSortRefField = rStrm.readInt32();
     365           0 : }
     366             : 
     367           0 : void PivotTableField::importPTReferenceItem( SequenceInputStream& rStrm )
     368             : {
     369           0 :     maModel.mnSortRefItem = rStrm.readInt32();
     370           0 : }
     371             : 
     372          24 : void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& rxDPDesc )
     373             : {
     374             :     /*  Process all fields based on source data, other fields (e.g. group
     375             :         fields) are processed from here. PivotCacahe::getDatabaseIndex()
     376             :         returns -1 for all fields not based on source data. */
     377          24 :     Reference< XDataPilotField > xDPField;
     378          24 :     sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
     379          24 :     if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
     380             :     {
     381             :         // try to get the source field and its name from passed DataPilot descriptor
     382          24 :         Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
     383          24 :         xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
     384          48 :         Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
     385          24 :         maDPFieldName = xDPFieldName->getName();
     386             :         OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeImport - no field name in source data found" );
     387             : 
     388             :         // try to convert grouping settings
     389          24 :         if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
     390             :         {
     391             :             // numeric grouping is done inplace, no nested group fields will appear
     392          24 :             if( pCacheField->hasNumericGrouping() )
     393             :             {
     394           0 :                 pCacheField->convertNumericGrouping( xDPField );
     395             :             }
     396          24 :             else if( pCacheField->hasDateGrouping() )
     397             :             {
     398             :                 // first date group settings are inplace
     399           0 :                 pCacheField->createDateGroupField( xDPField );
     400             :                 // create all nested group fields (if any)
     401           0 :                 mrPivotTable.finalizeDateGroupingImport( xDPField, mnFieldIndex );
     402             :             }
     403          24 :             else if( pCacheField->hasParentGrouping() )
     404             :             {
     405             : 
     406             :                 // create a list of all item names, needed to map between original and group items
     407           0 :                 ::std::vector< OUString > aItems;
     408           0 :                 pCacheField->getCacheItemNames( aItems );
     409           0 :                 PivotCacheGroupItemVector aItemNames;
     410           0 :                 for( ::std::vector< OUString >::iterator aIt = aItems.begin(), aEnd = aItems.end(); aIt != aEnd; ++aIt )
     411           0 :                     aItemNames.push_back( PivotCacheGroupItem( *aIt ) );
     412             :                 // create all nested group fields (if any)
     413           0 :                 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, aItemNames );
     414             :             }
     415          24 :         }
     416             :     }
     417           0 :     catch( Exception& )
     418             :     {
     419          24 :     }
     420          24 : }
     421             : 
     422           0 : void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
     423             : {
     424           0 :     if( maDPFieldName.isEmpty() )    // prevent endless loops if file format is broken
     425             :     {
     426           0 :         if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
     427             :         {
     428           0 :             if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) )
     429             :             {
     430           0 :                 maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField );
     431             :                 OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
     432             :             }
     433             :         }
     434             :     }
     435           0 : }
     436             : 
     437           0 : void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField,  const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
     438             : {
     439           0 :     if( maDPFieldName.isEmpty() )    // prevent endless loops if file format is broken
     440             :     {
     441           0 :         if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
     442             :         {
     443             :             // data field can have user defined groupname captions, apply them
     444             :             // if they do
     445           0 :             IdCaptionPairList captionList;
     446           0 :             for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
     447             :             {
     448           0 :                 if ( aIt->mnType == XML_data  && aIt->msCaption.getLength() )
     449           0 :                     captionList.push_back( IdCaptionPair( aIt->mnCacheItem, aIt->msCaption ) );
     450             :             }
     451             :             // #FIXME find another way out of this const nightmare prison
     452           0 :             if ( !captionList.empty() )
     453           0 :                 const_cast<PivotCacheField*>( pCacheField )->applyItemCaptions( captionList );
     454           0 :             maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, rBaseCacheField, orItemNames );
     455             :             // on success, try to create nested group fields
     456           0 :             Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
     457           0 :             if( xDPField.is() )
     458           0 :                 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames );
     459             :         }
     460             :     }
     461           0 : }
     462             : 
     463           4 : void PivotTableField::convertRowField()
     464             : {
     465           4 :     convertRowColPageField( XML_axisRow );
     466           4 : }
     467             : 
     468           4 : void PivotTableField::convertColField()
     469             : {
     470           4 :     convertRowColPageField( XML_axisCol );
     471           4 : }
     472             : 
     473          14 : void PivotTableField::convertHiddenField()
     474             : {
     475          14 :     convertRowColPageField( XML_TOKEN_INVALID );
     476          14 : }
     477             : 
     478           4 : void PivotTableField::convertPageField( const PTPageFieldModel& rPageField )
     479             : {
     480             :     OSL_ENSURE( rPageField.mnField == mnFieldIndex, "PivotTableField::convertPageField - wrong field index" );
     481             :     // convert all settings common for row/column/page fields
     482           4 :     Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage );
     483             : 
     484           4 :     if( xDPField.is() )
     485             :     {
     486           4 :         PropertySet aPropSet( xDPField );
     487             :         using namespace ::com::sun::star::sheet;
     488             : 
     489             :         // find cache item used as 'selected page'
     490           4 :         sal_Int32 nCacheItem = -1;
     491           4 :         if( maModel.mbMultiPageItems )
     492             :         {
     493             :             // multiple items may be selected
     494             :             OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" );
     495             :             // try to find a single visible item
     496           0 :             bool bHasMultiItems = false;
     497           0 :             for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); (aIt != aEnd) && !bHasMultiItems; ++aIt )
     498             :             {
     499           0 :                 if( (aIt->mnType == XML_data) && !aIt->mbHidden )
     500             :                 {
     501           0 :                     bHasMultiItems = nCacheItem >= 0;
     502           0 :                     nCacheItem = bHasMultiItems ? -1 : aIt->mnCacheItem;
     503             :                 }
     504             :             }
     505             :         }
     506             :         else
     507             :         {
     508             :             // single item may be selected
     509           4 :             if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) )
     510           0 :                 nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem;
     511             :         }
     512             : 
     513           4 :         if( nCacheItem >= 0 )
     514             :         {
     515           0 :             if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
     516             :             {
     517           0 :                 if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) )
     518             :                 {
     519           0 :                     OUString aSelectedPage = pSharedItem->getName();
     520           0 :                     aPropSet.setProperty( PROP_SelectedPage, aSelectedPage );
     521             :                 }
     522             :             }
     523           4 :         }
     524           4 :     }
     525           4 : }
     526             : 
     527           6 : void PivotTableField::convertDataField( const PTDataFieldModel& rDataField )
     528             : {
     529             :     OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" );
     530             :     OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" );
     531           6 :     Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
     532           6 :     if( xDPField.is() )
     533             :     {
     534           6 :         PropertySet aPropSet( xDPField );
     535             :         using namespace ::com::sun::star::sheet;
     536             : 
     537             :         // field orientation
     538           6 :         aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA );
     539             : 
     540             :         /*  Field aggregation function. Documentation is a little bit confused
     541             :             about which names to use for the count functions. The name 'count'
     542             :             means 'count all', and 'countNum' means 'count numbers'. On the
     543             :             other hand, for subtotals, 'countA' means 'count all', and 'count'
     544             :             means 'count numbers' (see above). */
     545           6 :         GeneralFunction eAggFunc = GeneralFunction_SUM;
     546           6 :         switch( rDataField.mnSubtotal )
     547             :         {
     548           4 :             case XML_sum:       eAggFunc = GeneralFunction_SUM;         break;
     549           2 :             case XML_count:     eAggFunc = GeneralFunction_COUNT;       break;
     550           0 :             case XML_average:   eAggFunc = GeneralFunction_AVERAGE;     break;
     551           0 :             case XML_max:       eAggFunc = GeneralFunction_MAX;         break;
     552           0 :             case XML_min:       eAggFunc = GeneralFunction_MIN;         break;
     553           0 :             case XML_product:   eAggFunc = GeneralFunction_PRODUCT;     break;
     554           0 :             case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS;   break;
     555           0 :             case XML_stdDev:    eAggFunc = GeneralFunction_STDEV;       break;
     556           0 :             case XML_stdDevp:   eAggFunc = GeneralFunction_STDEVP;      break;
     557           0 :             case XML_var:       eAggFunc = GeneralFunction_VAR;         break;
     558           0 :             case XML_varp:      eAggFunc = GeneralFunction_VARP;        break;
     559             :             default:            OSL_FAIL( "PivotTableField::convertDataField - unknown aggregation function" );
     560             :         }
     561           6 :         aPropSet.setProperty( PROP_Function, eAggFunc );
     562             : 
     563             :         // field reference ('show data as')
     564           6 :         DataPilotFieldReference aReference;
     565           6 :         aReference.ReferenceType = DataPilotFieldReferenceType::NONE;
     566           6 :         switch( rDataField.mnShowDataAs )
     567             :         {
     568           0 :             case XML_difference:        aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE;            break;
     569           0 :             case XML_percent:           aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE;            break;
     570           0 :             case XML_percentDiff:       aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break;
     571           0 :             case XML_runTotal:          aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL;              break;
     572           0 :             case XML_percentOfRow:      aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE;             break;
     573           0 :             case XML_percentOfCol:      aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE;          break;
     574           0 :             case XML_percentOfTotal:    aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE;           break;
     575           0 :             case XML_index:             aReference.ReferenceType = DataPilotFieldReferenceType::INDEX;                      break;
     576             :         }
     577           6 :         if( aReference.ReferenceType != DataPilotFieldReferenceType::NONE )
     578             :         {
     579           0 :             if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ) )
     580             :             {
     581           0 :                 aReference.ReferenceField = pCacheField->getName();
     582           0 :                 switch( rDataField.mnBaseItem )
     583             :                 {
     584             :                     case OOX_PT_PREVIOUS_ITEM:
     585           0 :                         aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
     586           0 :                     break;
     587             :                     case OOX_PT_NEXT_ITEM:
     588           0 :                         aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
     589           0 :                     break;
     590             :                     default:
     591           0 :                         aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
     592           0 :                         if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) )
     593           0 :                             aReference.ReferenceItemName = pCacheItem->getName();
     594             :                 }
     595           0 :                 aPropSet.setProperty( PROP_Reference, aReference );
     596             :             }
     597           6 :         }
     598           6 :     }
     599           6 : }
     600             : 
     601             : // private --------------------------------------------------------------------
     602             : 
     603          26 : Reference< XDataPilotField > PivotTableField::convertRowColPageField( sal_Int32 nAxis )
     604             : {
     605          26 :     bool bDataLayout = mnFieldIndex == OOX_PT_DATALAYOUTFIELD;
     606          26 :     Reference< XDataPilotField > xDPField = bDataLayout ? mrPivotTable.getDataLayoutField() : mrPivotTable.getDataPilotField( maDPFieldName );
     607             :     OSL_ENSURE( bDataLayout || (nAxis == maModel.mnAxis), "PivotTableField::convertRowColPageField - field axis mismatch" );
     608             : 
     609          26 :     if( xDPField.is() )
     610             :     {
     611             :         // TODO: Use this to set properties directly, bypassing the slow uno layer.
     612          26 :         ScDPObject* pDPObj = mrPivotTable.getDPObject();
     613             : 
     614          26 :         PropertySet aPropSet( xDPField );
     615             :         using namespace ::com::sun::star::sheet;
     616             : 
     617             :         // field orientation
     618          26 :         DataPilotFieldOrientation eFieldOrient = DataPilotFieldOrientation_HIDDEN;
     619          26 :         switch( nAxis )
     620             :         {
     621           4 :             case XML_axisRow:   eFieldOrient = DataPilotFieldOrientation_ROW;       break;
     622           4 :             case XML_axisCol:   eFieldOrient = DataPilotFieldOrientation_COLUMN;    break;
     623           4 :             case XML_axisPage:  eFieldOrient = DataPilotFieldOrientation_PAGE;      break;
     624             :         }
     625          26 :         if( eFieldOrient != DataPilotFieldOrientation_HIDDEN )
     626          12 :             aPropSet.setProperty( PROP_Orientation, eFieldOrient );
     627             : 
     628             :         // all other settings not for the data layout field
     629          26 :         if( !bDataLayout )
     630             :         {
     631             :             /*  Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
     632             :                 explicit functions are set. This is different behaviour between
     633             :                 XML (where 'defaultSubtotal' is set regardless of other
     634             :                 functions) and binary formats (where 'defaultSubtotal' is not
     635             :                 set if other functions are set). */
     636          24 :             ::std::vector< GeneralFunction > aSubtotals;
     637             :             /*  Order of subtotals is fixed in Excel. Documentation is a little
     638             :                 bit confused about which names to use for the count functions.
     639             :                 For subtotals, 'countA' means 'count all', and 'count' means
     640             :                 'count numbers'. On the other hand, for the data field
     641             :                 aggregation function, 'count' means 'count all', and 'countNum'
     642             :                 means 'count numbers' (see below). */
     643          24 :             if( maModel.mbSumSubtotal )     aSubtotals.push_back( GeneralFunction_SUM );
     644          24 :             if( maModel.mbCountASubtotal )  aSubtotals.push_back( GeneralFunction_COUNT );
     645          24 :             if( maModel.mbAverageSubtotal ) aSubtotals.push_back( GeneralFunction_AVERAGE );
     646          24 :             if( maModel.mbMaxSubtotal )     aSubtotals.push_back( GeneralFunction_MAX );
     647          24 :             if( maModel.mbMinSubtotal )     aSubtotals.push_back( GeneralFunction_MIN );
     648          24 :             if( maModel.mbProductSubtotal ) aSubtotals.push_back( GeneralFunction_PRODUCT );
     649          24 :             if( maModel.mbCountSubtotal )   aSubtotals.push_back( GeneralFunction_COUNTNUMS );
     650          24 :             if( maModel.mbStdDevSubtotal )  aSubtotals.push_back( GeneralFunction_STDEV );
     651          24 :             if( maModel.mbStdDevPSubtotal ) aSubtotals.push_back( GeneralFunction_STDEVP );
     652          24 :             if( maModel.mbVarSubtotal )     aSubtotals.push_back( GeneralFunction_VAR );
     653          24 :             if( maModel.mbVarPSubtotal )    aSubtotals.push_back( GeneralFunction_VARP );
     654             :             // if no function is set manually, check the 'defaultSubtotal' flag
     655          24 :             if( aSubtotals.empty() && maModel.mbDefaultSubtotal )
     656          24 :                 aSubtotals.push_back( GeneralFunction_AUTO );
     657          24 :             aPropSet.setProperty( PROP_Subtotals, ContainerHelper::vectorToSequence( aSubtotals ) );
     658             : 
     659             :             // layout settings
     660          24 :             DataPilotFieldLayoutInfo aLayoutInfo;
     661             :             aLayoutInfo.LayoutMode = maModel.mbOutline ?
     662             :                 (maModel.mbSubtotalTop ? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP : DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM) :
     663          24 :                 DataPilotFieldLayoutMode::TABULAR_LAYOUT;
     664          24 :             aLayoutInfo.AddEmptyLines = maModel.mbInsertBlankRow;
     665          24 :             aPropSet.setProperty( PROP_LayoutInfo, aLayoutInfo );
     666          24 :             aPropSet.setProperty( PROP_ShowEmpty, maModel.mbShowAll );
     667             : 
     668             :             // auto show (OOXML/BIFF12 only)
     669          24 :             if( maModel.mbAutoShow )
     670             :             {
     671           0 :                 DataPilotFieldAutoShowInfo aAutoShowInfo;
     672           0 :                 aAutoShowInfo.IsEnabled = sal_True;
     673           0 :                 aAutoShowInfo.ShowItemsMode = maModel.mbTopAutoShow ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
     674           0 :                 aAutoShowInfo.ItemCount = maModel.mnAutoShowItems;
     675           0 :                 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnAutoShowRankBy ) )
     676           0 :                     aAutoShowInfo.DataField = pCacheField->getName();
     677           0 :                 aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
     678             :             }
     679             : 
     680             :             // auto sort
     681          48 :             DataPilotFieldSortInfo aSortInfo;
     682          24 :             aSortInfo.IsAscending = maModel.mnSortType == XML_ascending;
     683          24 :             if( (maModel.mnSortType != XML_ascending) && (maModel.mnSortType != XML_descending) )
     684             :             {
     685          24 :                 aSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
     686             :             }
     687             :             else
     688             :             {
     689           0 :                 const PivotCacheField* pCacheField = (maModel.mnSortRefField == OOX_PT_DATALAYOUTFIELD) ?
     690           0 :                     mrPivotTable.getCacheFieldOfDataField( maModel.mnSortRefItem ) : 0;
     691           0 :                 if( pCacheField )
     692             :                 {
     693           0 :                     aSortInfo.Mode = DataPilotFieldSortMode::DATA;
     694           0 :                     aSortInfo.Field = pCacheField->getName();
     695             :                 }
     696             :                 else
     697             :                 {
     698           0 :                     aSortInfo.Mode = DataPilotFieldSortMode::NAME;
     699             :                 }
     700             :             }
     701          24 :             aPropSet.setProperty( PROP_SortInfo, aSortInfo );
     702             : 
     703             :             // item settings
     704          24 :             if (const PivotCacheField* pCacheField = mrPivotTable.getCacheField(mnFieldIndex))
     705             :             {
     706          24 :                 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
     707          24 :                 ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(pCacheField->getName());
     708             : 
     709             :                 try
     710             :                 {
     711          44 :                     for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
     712             :                     {
     713          20 :                         if (aIt->mnType != XML_data)
     714           5 :                             continue;
     715             : 
     716          15 :                         const PivotCacheItem* pSharedItem = pCacheField->getCacheItem(aIt->mnCacheItem);
     717          15 :                         if (!pSharedItem)
     718           0 :                             continue;
     719             : 
     720             :                         try
     721             :                         {
     722          15 :                             ScDPSaveMember* pMem = pDim->GetMemberByName(pSharedItem->getName());
     723          15 :                             pMem->SetShowDetails(aIt->mbShowDetails);
     724          15 :                             pMem->SetIsVisible(!aIt->mbHidden);
     725             :                         }
     726           0 :                         catch( Exception& )
     727             :                         {
     728             :                             // catch every failed container access to be able to process following items
     729             :                         }
     730             :                     }
     731             :                 }
     732           0 :                 catch (const Exception&) {}
     733          24 :             }
     734          26 :         }
     735             :     }
     736          26 :     return xDPField;
     737             : }
     738             : 
     739           0 : PTFilterModel::PTFilterModel() :
     740             :     mfValue( 0.0 ),
     741             :     mnField( -1 ),
     742             :     mnMemPropField( -1 ),
     743             :     mnType( XML_TOKEN_INVALID ),
     744             :     mnEvalOrder( 0 ),
     745             :     mnId( -1 ),
     746             :     mnMeasureField( -1 ),
     747             :     mnMeasureHier( -1 ),
     748           0 :     mbTopFilter( true )
     749             : {
     750           0 : }
     751             : 
     752           0 : PivotTableFilter::PivotTableFilter( const PivotTable& rPivotTable ) :
     753             :     WorkbookHelper( rPivotTable ),
     754           0 :     mrPivotTable( rPivotTable )
     755             : {
     756           0 : }
     757             : 
     758           0 : void PivotTableFilter::importFilter( const AttributeList& rAttribs )
     759             : {
     760           0 :     maModel.maName         = rAttribs.getXString( XML_name, OUString() );
     761           0 :     maModel.maDescription  = rAttribs.getXString( XML_description, OUString() );
     762           0 :     maModel.maStrValue1    = rAttribs.getXString( XML_stringValue1, OUString() );
     763           0 :     maModel.maStrValue2    = rAttribs.getXString( XML_stringValue2, OUString() );
     764           0 :     maModel.mnField        = rAttribs.getInteger( XML_fld, -1 );
     765           0 :     maModel.mnMemPropField = rAttribs.getInteger( XML_mpFld, -1 );
     766           0 :     maModel.mnType         = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
     767           0 :     maModel.mnEvalOrder    = rAttribs.getInteger( XML_evalOrder, 0 );
     768           0 :     maModel.mnId           = rAttribs.getInteger( XML_id, -1 );
     769           0 :     maModel.mnMeasureField = rAttribs.getInteger( XML_iMeasureFld, -1 );
     770           0 :     maModel.mnMeasureHier  = rAttribs.getInteger( XML_iMeasureHier, -1 );
     771           0 : }
     772             : 
     773           0 : void PivotTableFilter::importTop10( const AttributeList& rAttribs )
     774             : {
     775             :     OSL_ENSURE( rAttribs.getBool( XML_percent, false ) == (maModel.mnType == XML_percent),
     776             :         "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
     777           0 :     maModel.mfValue     = rAttribs.getDouble( XML_val, 0.0 );
     778           0 :     maModel.mbTopFilter = rAttribs.getBool( XML_top, true );
     779           0 : }
     780             : 
     781           0 : void PivotTableFilter::importPTFilter( SequenceInputStream& rStrm )
     782             : {
     783             :     sal_Int32 nType;
     784             :     sal_uInt16 nFlags;
     785           0 :     maModel.mnField = rStrm.readInt32();
     786           0 :     maModel.mnMemPropField = rStrm.readInt32();
     787           0 :     nType = rStrm.readInt32();
     788           0 :     rStrm.skip( 4 );    // unused
     789           0 :     maModel.mnId = rStrm.readInt32();
     790           0 :     maModel.mnMeasureField = rStrm.readInt32();
     791           0 :     maModel.mnMeasureHier = rStrm.readInt32();
     792           0 :     nFlags = rStrm.readuInt16();
     793           0 :     if( getFlag( nFlags, BIFF12_PTFILTER_HASNAME ) )
     794           0 :         rStrm >> maModel.maName;
     795           0 :     if( getFlag( nFlags, BIFF12_PTFILTER_HASDESCRIPTION ) )
     796           0 :         rStrm >> maModel.maDescription;
     797           0 :     if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE1 ) )
     798           0 :         rStrm >> maModel.maStrValue1;
     799           0 :     if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE2 ) )
     800           0 :         rStrm >> maModel.maStrValue2;
     801             : 
     802             :     static const sal_Int32 spnTypes[] =
     803             :     {
     804             :         XML_unknown,
     805             :         // data field top10 filter (1-3)
     806             :         XML_count, XML_percent, XML_sum,
     807             :         // caption filter (4-17)
     808             :         XML_captionEqual, XML_captionNotEqual,
     809             :         XML_captionBeginsWith, XML_captionNotBeginsWith, XML_captionEndsWith, XML_captionNotEndsWith,
     810             :         XML_captionContains, XML_captionNotContains, XML_captionGreaterThan, XML_captionGreaterThanOrEqual,
     811             :         XML_captionLessThan, XML_captionLessThanOrEqual, XML_captionBetween, XML_captionNotBetween,
     812             :         // value filter (18-25)
     813             :         XML_valueEqual, XML_valueNotEqual, XML_valueGreaterThan, XML_valueGreaterThanOrEqual,
     814             :         XML_valueLessThan, XML_valueLessThanOrEqual, XML_valueBetween, XML_valueNotBetween,
     815             :         // date filter (26-65)
     816             :         XML_dateEqual, XML_dateOlderThan, XML_dateNewerThan, XML_dateBetween,
     817             :         XML_tomorrow, XML_today, XML_yesterday, XML_nextWeek, XML_thisWeek, XML_lastWeek,
     818             :         XML_nextMonth, XML_thisMonth, XML_lastMonth, XML_nextQuarter, XML_thisQuarter, XML_lastQuarter,
     819             :         XML_nextYear, XML_thisYear, XML_lastYear, XML_yearToDate, XML_Q1, XML_Q2, XML_Q3, XML_Q4,
     820             :         XML_M1, XML_M2, XML_M3, XML_M4, XML_M5, XML_M6, XML_M7, XML_M8, XML_M9, XML_M10, XML_M11, XML_M12,
     821             :         XML_dateNotEqual, XML_dateOlderThanOrEqual, XML_dateNewerThanOrEqual, XML_dateNotBetween
     822             :     };
     823           0 :     maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
     824           0 : }
     825             : 
     826           0 : void PivotTableFilter::importTop10Filter( SequenceInputStream& rStrm )
     827             : {
     828             :     sal_uInt8 nFlags;
     829           0 :     nFlags = rStrm.readuChar();
     830           0 :     maModel.mfValue = rStrm.readDouble();
     831             : 
     832             :     SAL_WARN_IF(
     833             :         getFlag(nFlags, BIFF12_TOP10FILTER_PERCENT) != (maModel.mnType == XML_percent),
     834             :         "sc.filter",
     835             :         "PivotTableFilter::importTop10 - unexpected value of percent attribute");
     836           0 :     maModel.mbTopFilter = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
     837           0 : }
     838             : 
     839           0 : void PivotTableFilter::finalizeImport()
     840             : {
     841             :     // only simple top10 filter supported
     842           0 :     if( maModel.mnType == XML_count )
     843             :     {
     844           0 :         PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) );
     845           0 :         if( aPropSet.is() )
     846             :         {
     847             :             using namespace ::com::sun::star::sheet;
     848           0 :             DataPilotFieldAutoShowInfo aAutoShowInfo;
     849           0 :             aAutoShowInfo.IsEnabled = sal_True;
     850           0 :             aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
     851           0 :             aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 );
     852           0 :             if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) )
     853           0 :                 aAutoShowInfo.DataField = pCacheField->getName();
     854           0 :             aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
     855           0 :         }
     856             :     }
     857           0 : }
     858             : 
     859           4 : PTDefinitionModel::PTDefinitionModel() :
     860             :     mnCacheId( -1 ),
     861             :     mnDataPosition( 0 ),
     862             :     mnPageWrap( 0 ),
     863             :     mnIndent( 1 ),
     864             :     mnChartFormat( 0 ),
     865             :     mnRowFields( 0 ),
     866             :     mnColFields( 0 ),
     867             :     mbDataOnRows( false ),
     868             :     mbShowError( false ),
     869             :     mbShowMissing( true ),
     870             :     mbShowItems( true ),
     871             :     mbDisableFieldList( false ),
     872             :     mbShowCalcMembers( true ),
     873             :     mbVisualTotals( true ),
     874             :     mbShowDrill( true ),
     875             :     mbPrintDrill( false ),
     876             :     mbEnableDrill( true ),
     877             :     mbPreserveFormatting( true ),
     878             :     mbUseAutoFormat( false ),
     879             :     mbPageOverThenDown( false ),
     880             :     mbSubtotalHiddenItems( false ),
     881             :     mbRowGrandTotals( true ),
     882             :     mbColGrandTotals( true ),
     883             :     mbFieldPrintTitles( false ),
     884             :     mbItemPrintTitles( false ),
     885             :     mbMergeItem( false ),
     886             :     mbShowEmptyRow( false ),
     887             :     mbShowEmptyCol( false ),
     888             :     mbShowHeaders( true ),
     889             :     mbFieldListSortAsc( false ),
     890           4 :     mbCustomListSort( true )
     891             : {
     892           4 : }
     893             : 
     894           4 : PTLocationModel::PTLocationModel() :
     895             :     mnFirstHeaderRow( 0 ),
     896             :     mnFirstDataRow( 0 ),
     897             :     mnFirstDataCol( 0 ),
     898             :     mnRowPageCount( 0 ),
     899           4 :     mnColPageCount( 0 )
     900             : {
     901           4 : }
     902             : 
     903           4 : PivotTable::PivotTable( const WorkbookHelper& rHelper ) :
     904             :     WorkbookHelper( rHelper ),
     905             :     mpDPObject(NULL),
     906             :     maDataField( *this, OOX_PT_DATALAYOUTFIELD ),
     907           4 :     mpPivotCache( 0 )
     908             : {
     909           4 : }
     910             : 
     911           4 : void PivotTable::importPivotTableDefinition( const AttributeList& rAttribs )
     912             : {
     913           4 :     maDefModel.maName                = rAttribs.getXString( XML_name, OUString() );
     914           4 :     maDefModel.maDataCaption         = rAttribs.getXString( XML_dataCaption , OUString() );
     915           4 :     maDefModel.maGrandTotalCaption   = rAttribs.getXString( XML_grandTotalCaption, OUString() );
     916           4 :     maDefModel.maRowHeaderCaption    = rAttribs.getXString( XML_rowHeaderCaption, OUString() );
     917           4 :     maDefModel.maColHeaderCaption    = rAttribs.getXString( XML_colHeaderCaption, OUString() );
     918           4 :     maDefModel.maErrorCaption        = rAttribs.getXString( XML_errorCaption, OUString() );
     919           4 :     maDefModel.maMissingCaption      = rAttribs.getXString( XML_missingCaption, OUString() );
     920           4 :     maDefModel.maPageStyle           = rAttribs.getXString( XML_pageStyle, OUString() );
     921           4 :     maDefModel.maPivotTableStyle     = rAttribs.getXString( XML_pivotTableStyle, OUString() );
     922           4 :     maDefModel.maVacatedStyle        = rAttribs.getXString( XML_vacatedStyle, OUString() );
     923           4 :     maDefModel.maTag                 = rAttribs.getXString( XML_tag, OUString() );
     924           4 :     maDefModel.mnCacheId             = rAttribs.getInteger( XML_cacheId, -1 );
     925           4 :     maDefModel.mnDataPosition        = rAttribs.getInteger( XML_dataPosition, 0 );
     926           4 :     maDefModel.mnPageWrap            = rAttribs.getInteger( XML_pageWrap, 0 );
     927           4 :     maDefModel.mnIndent              = rAttribs.getInteger( XML_indent, 1 );
     928           4 :     maDefModel.mnChartFormat         = rAttribs.getInteger( XML_chartFormat, 0 );
     929           4 :     maDefModel.mnAutoFormatId        = rAttribs.getInteger( XML_autoFormatId, 0 );
     930           4 :     maDefModel.mbDataOnRows          = rAttribs.getBool( XML_dataOnRows, false );
     931           4 :     maDefModel.mbShowError           = rAttribs.getBool( XML_showError, false );
     932           4 :     maDefModel.mbShowMissing         = rAttribs.getBool( XML_showMissing, true );
     933           4 :     maDefModel.mbShowItems           = rAttribs.getBool( XML_showItems, true );
     934           4 :     maDefModel.mbDisableFieldList    = rAttribs.getBool( XML_disableFieldList, false );
     935           4 :     maDefModel.mbShowCalcMembers     = rAttribs.getBool( XML_showCalcMbrs, true );
     936           4 :     maDefModel.mbVisualTotals        = rAttribs.getBool( XML_visualTotals, true );
     937           4 :     maDefModel.mbShowDrill           = rAttribs.getBool( XML_showDrill, true );
     938           4 :     maDefModel.mbPrintDrill          = rAttribs.getBool( XML_printDrill, false );
     939           4 :     maDefModel.mbEnableDrill         = rAttribs.getBool( XML_enableDrill, true );
     940           4 :     maDefModel.mbPreserveFormatting  = rAttribs.getBool( XML_preserveFormatting, true );
     941           4 :     maDefModel.mbUseAutoFormat       = rAttribs.getBool( XML_useAutoFormatting, false );
     942           4 :     maDefModel.mbPageOverThenDown    = rAttribs.getBool( XML_pageOverThenDown, false );
     943           4 :     maDefModel.mbSubtotalHiddenItems = rAttribs.getBool( XML_subtotalHiddenItems, false );
     944           4 :     maDefModel.mbRowGrandTotals      = rAttribs.getBool( XML_rowGrandTotals, true );
     945           4 :     maDefModel.mbColGrandTotals      = rAttribs.getBool( XML_colGrandTotals, true );
     946           4 :     maDefModel.mbFieldPrintTitles    = rAttribs.getBool( XML_fieldPrintTitles, false );
     947           4 :     maDefModel.mbItemPrintTitles     = rAttribs.getBool( XML_itemPrintTitles, false );
     948           4 :     maDefModel.mbMergeItem           = rAttribs.getBool( XML_mergeItem, false );
     949           4 :     maDefModel.mbShowEmptyRow        = rAttribs.getBool( XML_showEmptyRow, false );
     950           4 :     maDefModel.mbShowEmptyCol        = rAttribs.getBool( XML_showEmptyCol, false );
     951           4 :     maDefModel.mbShowHeaders         = rAttribs.getBool( XML_showHeaders, true );
     952           4 :     maDefModel.mbFieldListSortAsc    = rAttribs.getBool( XML_fieldListSortAscending, false );
     953           4 :     maDefModel.mbCustomListSort      = rAttribs.getBool( XML_customListSort, true );
     954           4 :     maDefModel.mbApplyNumFmt         = rAttribs.getBool( XML_applyNumberFormats, false );
     955           4 :     maDefModel.mbApplyFont           = rAttribs.getBool( XML_applyFontFormats, false );
     956           4 :     maDefModel.mbApplyAlignment      = rAttribs.getBool( XML_applyAlignmentFormats, false );
     957           4 :     maDefModel.mbApplyBorder         = rAttribs.getBool( XML_applyBorderFormats, false );
     958           4 :     maDefModel.mbApplyFill           = rAttribs.getBool( XML_applyPatternFormats, false );
     959             :     // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
     960           4 :     maDefModel.mbApplyProtection     = rAttribs.getBool( XML_applyWidthHeightFormats, false );
     961           4 : }
     962             : 
     963           4 : void PivotTable::importLocation( const AttributeList& rAttribs, sal_Int16 nSheet )
     964             : {
     965           4 :     AddressConverter::convertToCellRangeUnchecked( maLocationModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet );
     966           4 :     maLocationModel.mnFirstHeaderRow = rAttribs.getInteger( XML_firstHeaderRow, 0 );
     967           4 :     maLocationModel.mnFirstDataRow   = rAttribs.getInteger( XML_firstDataRow, 0 );
     968           4 :     maLocationModel.mnFirstDataCol   = rAttribs.getInteger( XML_firstDataCol, 0 );
     969           4 :     maLocationModel.mnRowPageCount   = rAttribs.getInteger( XML_rowPageCount, 0 );
     970           4 :     maLocationModel.mnColPageCount   = rAttribs.getInteger( XML_colPageCount, 0 );
     971           4 : }
     972             : 
     973           4 : void PivotTable::importRowField( const AttributeList& rAttribs )
     974             : {
     975           4 :     importField( maRowFields, rAttribs );
     976           4 : }
     977             : 
     978           4 : void PivotTable::importColField( const AttributeList& rAttribs )
     979             : {
     980           4 :     importField( maColFields, rAttribs );
     981           4 : }
     982             : 
     983           4 : void PivotTable::importPageField( const AttributeList& rAttribs )
     984             : {
     985           4 :     PTPageFieldModel aModel;
     986           4 :     aModel.maName      = rAttribs.getXString( XML_name, OUString() );
     987           4 :     aModel.mnField     = rAttribs.getInteger( XML_fld, -1 );
     988             :     // specification is wrong, XML_item is not the cache item, but the field item
     989           4 :     aModel.mnItem      = rAttribs.getInteger( XML_item, BIFF12_PTPAGEFIELD_MULTIITEMS );
     990           4 :     maPageFields.push_back( aModel );
     991           4 : }
     992             : 
     993           6 : void PivotTable::importDataField( const AttributeList& rAttribs )
     994             : {
     995           6 :     PTDataFieldModel aModel;
     996           6 :     aModel.maName       = rAttribs.getXString( XML_name, OUString() );
     997           6 :     aModel.mnField      = rAttribs.getInteger( XML_fld, -1 );
     998           6 :     aModel.mnSubtotal   = rAttribs.getToken( XML_subtotal, XML_sum );
     999           6 :     aModel.mnShowDataAs = rAttribs.getToken( XML_showDataAs, XML_normal );
    1000           6 :     aModel.mnBaseField  = rAttribs.getInteger( XML_baseField, -1 );
    1001           6 :     aModel.mnBaseItem   = rAttribs.getInteger( XML_baseItem, -1 );
    1002           6 :     aModel.mnNumFmtId   = rAttribs.getInteger( XML_numFmtId, 0 );
    1003           6 :     maDataFields.push_back( aModel );
    1004           6 : }
    1005             : 
    1006           0 : void PivotTable::importPTDefinition( SequenceInputStream& rStrm )
    1007             : {
    1008             :     sal_uInt32 nFlags1, nFlags2, nFlags3;
    1009             :     sal_uInt8 nDataAxis;
    1010           0 :     nFlags1 = rStrm.readuInt32();
    1011           0 :     nFlags2 = rStrm.readuInt32();
    1012           0 :     nFlags3 = rStrm.readuInt32();
    1013           0 :     nDataAxis = rStrm.readuChar();
    1014           0 :     maDefModel.mnPageWrap = rStrm.readuInt8();
    1015           0 :     rStrm.skip( 2 );    // refresh versions
    1016           0 :     maDefModel.mnDataPosition = rStrm.readInt32();
    1017           0 :     maDefModel.mnAutoFormatId = rStrm.readuInt16();
    1018           0 :     rStrm.skip( 2 );    // unused
    1019           0 :     maDefModel.mnChartFormat = rStrm.readInt32();
    1020           0 :     maDefModel.mnCacheId = rStrm.readInt32();
    1021           0 :     rStrm >> maDefModel.maName;
    1022           0 :     if( getFlag( nFlags2, BIFF12_PTDEF_HASDATACAPTION ) )
    1023           0 :         rStrm >> maDefModel.maDataCaption;
    1024           0 :     if( getFlag( nFlags2, BIFF12_PTDEF_HASGRANDTOTALCAPTION ) )
    1025           0 :         rStrm >> maDefModel.maGrandTotalCaption;
    1026           0 :     if( !getFlag( nFlags3, BIFF12_PTDEF_NOERRORCAPTION ) )   // missing flag indicates existing string
    1027           0 :         rStrm >> maDefModel.maErrorCaption;
    1028           0 :     if( !getFlag( nFlags3, BIFF12_PTDEF_NOMISSINGCAPTION ) ) // missing flag indicates existing string
    1029           0 :         rStrm >> maDefModel.maMissingCaption;
    1030           0 :     if( getFlag( nFlags2, BIFF12_PTDEF_HASPAGESTYLE ) )
    1031           0 :         rStrm >> maDefModel.maPageStyle;
    1032           0 :     if( getFlag( nFlags2, BIFF12_PTDEF_HASPIVOTTABLESTYLE ) )
    1033           0 :         rStrm >> maDefModel.maPivotTableStyle;
    1034           0 :     if( getFlag( nFlags2, BIFF12_PTDEF_HASVACATEDSTYLE ) )
    1035           0 :         rStrm >> maDefModel.maVacatedStyle;
    1036           0 :     if( getFlag( nFlags2, BIFF12_PTDEF_HASTAG ) )
    1037           0 :         rStrm >> maDefModel.maTag;
    1038           0 :     if( getFlag( nFlags3, BIFF12_PTDEF_HASCOLHEADERCAPTION ) )   // TODO: right order (col/row)? spec is unclear
    1039           0 :         rStrm >> maDefModel.maColHeaderCaption;
    1040           0 :     if( getFlag( nFlags3, BIFF12_PTDEF_HASROWHEADERCAPTION ) )
    1041           0 :         rStrm >> maDefModel.maRowHeaderCaption;
    1042             : 
    1043             :     SAL_WARN_IF(
    1044             :         (nDataAxis != BIFF12_PTDEF_ROWAXIS) && (nDataAxis != BIFF12_PTDEF_COLAXIS),
    1045             :         "sc.filter",
    1046             :         "PivotTable::importPTDefinition - unexpected axis position for data field");
    1047             : 
    1048           0 :     maDefModel.mnIndent              = extractValue< sal_uInt8 >( nFlags1, 24, 7 );
    1049           0 :     maDefModel.mbDataOnRows          = nDataAxis == BIFF12_PTDEF_ROWAXIS;
    1050           0 :     maDefModel.mbShowError           = getFlag( nFlags2, BIFF12_PTDEF_SHOWERROR );
    1051           0 :     maDefModel.mbShowMissing         = getFlag( nFlags2, BIFF12_PTDEF_SHOWMISSING );
    1052           0 :     maDefModel.mbShowItems           = getFlag( nFlags1, BIFF12_PTDEF_SHOWITEMS );
    1053           0 :     maDefModel.mbDisableFieldList    = getFlag( nFlags1, BIFF12_PTDEF_DISABLEFIELDLIST );
    1054           0 :     maDefModel.mbShowCalcMembers     = !getFlag( nFlags1, BIFF12_PTDEF_HIDECALCMEMBERS );
    1055           0 :     maDefModel.mbVisualTotals        = !getFlag( nFlags1, BIFF12_PTDEF_WITHHIDDENTOTALS );
    1056           0 :     maDefModel.mbShowDrill           = !getFlag( nFlags1, BIFF12_PTDEF_HIDEDRILL );
    1057           0 :     maDefModel.mbPrintDrill          = getFlag( nFlags1, BIFF12_PTDEF_PRINTDRILL );
    1058           0 :     maDefModel.mbEnableDrill         = getFlag( nFlags2, BIFF12_PTDEF_ENABLEDRILL );
    1059           0 :     maDefModel.mbPreserveFormatting  = getFlag( nFlags2, BIFF12_PTDEF_PRESERVEFORMATTING );
    1060           0 :     maDefModel.mbUseAutoFormat       = getFlag( nFlags2, BIFF12_PTDEF_USEAUTOFORMAT );
    1061           0 :     maDefModel.mbPageOverThenDown    = getFlag( nFlags2, BIFF12_PTDEF_PAGEOVERTHENDOWN );
    1062           0 :     maDefModel.mbSubtotalHiddenItems = getFlag( nFlags2, BIFF12_PTDEF_SUBTOTALHIDDENITEMS );
    1063           0 :     maDefModel.mbRowGrandTotals      = getFlag( nFlags2, BIFF12_PTDEF_ROWGRANDTOTALS );
    1064           0 :     maDefModel.mbColGrandTotals      = getFlag( nFlags2, BIFF12_PTDEF_COLGRANDTOTALS );
    1065           0 :     maDefModel.mbFieldPrintTitles    = getFlag( nFlags2, BIFF12_PTDEF_FIELDPRINTTITLES );
    1066           0 :     maDefModel.mbItemPrintTitles     = getFlag( nFlags2, BIFF12_PTDEF_ITEMPRINTTITLES );
    1067           0 :     maDefModel.mbMergeItem           = getFlag( nFlags2, BIFF12_PTDEF_MERGEITEM );
    1068           0 :     maDefModel.mbApplyNumFmt         = getFlag( nFlags2, BIFF12_PTDEF_APPLYNUMFMT );
    1069           0 :     maDefModel.mbApplyFont           = getFlag( nFlags2, BIFF12_PTDEF_APPLYFONT );
    1070           0 :     maDefModel.mbApplyAlignment      = getFlag( nFlags2, BIFF12_PTDEF_APPLYALIGNMENT );
    1071           0 :     maDefModel.mbApplyBorder         = getFlag( nFlags2, BIFF12_PTDEF_APPLYBORDER );
    1072           0 :     maDefModel.mbApplyFill           = getFlag( nFlags2, BIFF12_PTDEF_APPLYFILL );
    1073           0 :     maDefModel.mbApplyProtection     = getFlag( nFlags2, BIFF12_PTDEF_APPLYPROTECTION );
    1074           0 :     maDefModel.mbShowEmptyRow        = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYROW );
    1075           0 :     maDefModel.mbShowEmptyCol        = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYCOL );
    1076           0 :     maDefModel.mbShowHeaders         = !getFlag( nFlags1, BIFF12_PTDEF_HIDEHEADERS );
    1077           0 :     maDefModel.mbFieldListSortAsc    = getFlag( nFlags3, BIFF12_PTDEF_FIELDLISTSORTASC );
    1078           0 :     maDefModel.mbCustomListSort      = !getFlag( nFlags3, BIFF12_PTDEF_NOCUSTOMLISTSORT );
    1079           0 : }
    1080             : 
    1081           0 : void PivotTable::importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet )
    1082             : {
    1083           0 :     BinRange aBinRange;
    1084           0 :     rStrm >> aBinRange;
    1085           0 :     maLocationModel.mnFirstHeaderRow = rStrm.readInt32();
    1086           0 :     maLocationModel.mnFirstDataRow = rStrm.readInt32();
    1087           0 :     maLocationModel.mnFirstDataCol = rStrm.readInt32();
    1088           0 :     maLocationModel.mnRowPageCount = rStrm.readInt32();
    1089           0 :     maLocationModel.mnColPageCount = rStrm.readInt32();
    1090           0 :     AddressConverter::convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
    1091           0 : }
    1092             : 
    1093           0 : void PivotTable::importPTRowFields( SequenceInputStream& rStrm )
    1094             : {
    1095           0 :     importFields( maRowFields, rStrm );
    1096           0 : }
    1097             : 
    1098           0 : void PivotTable::importPTColFields( SequenceInputStream& rStrm )
    1099             : {
    1100           0 :     importFields( maColFields, rStrm );
    1101           0 : }
    1102             : 
    1103           0 : void PivotTable::importPTPageField( SequenceInputStream& rStrm )
    1104             : {
    1105           0 :     PTPageFieldModel aModel;
    1106             :     sal_uInt8 nFlags;
    1107           0 :     aModel.mnField = rStrm.readInt32();
    1108           0 :     aModel.mnItem = rStrm.readInt32();
    1109           0 :     rStrm.skip( 4 );    // hierarchy
    1110           0 :     nFlags = rStrm.readuChar();
    1111           0 :     if( getFlag( nFlags, BIFF12_PTPAGEFIELD_HASNAME ) )
    1112           0 :         rStrm >> aModel.maName;
    1113           0 :     maPageFields.push_back( aModel );
    1114           0 : }
    1115             : 
    1116           0 : void PivotTable::importPTDataField( SequenceInputStream& rStrm )
    1117             : {
    1118           0 :     PTDataFieldModel aModel;
    1119             :     sal_Int32 nSubtotal, nShowDataAs;
    1120             :     sal_uInt8 nHasName;
    1121           0 :     aModel.mnField = rStrm.readInt32(  );
    1122           0 :     nSubtotal = rStrm.readInt32();
    1123           0 :     nShowDataAs = rStrm.readInt32();
    1124           0 :     aModel.mnBaseField = rStrm.readInt32();
    1125           0 :     aModel.mnBaseItem = rStrm.readInt32();
    1126           0 :     aModel.mnNumFmtId = rStrm.readInt32();
    1127           0 :     nHasName = rStrm.readuChar();
    1128           0 :     if( nHasName == 1 )
    1129           0 :         rStrm >> aModel.maName;
    1130           0 :     aModel.setBiffSubtotal( nSubtotal );
    1131           0 :     aModel.setBiffShowDataAs( nShowDataAs );
    1132           0 :     maDataFields.push_back( aModel );
    1133           0 : }
    1134             : 
    1135          24 : PivotTableField& PivotTable::createTableField()
    1136             : {
    1137          24 :     sal_Int32 nFieldIndex = static_cast< sal_Int32 >( maFields.size() );
    1138          24 :     PivotTableFieldVector::value_type xTableField( new PivotTableField( *this, nFieldIndex ) );
    1139          24 :     maFields.push_back( xTableField );
    1140          24 :     return *xTableField;
    1141             : }
    1142             : 
    1143           0 : PivotTableFilter& PivotTable::createTableFilter()
    1144             : {
    1145           0 :     PivotTableFilterVector::value_type xTableFilter( new PivotTableFilter( *this ) );
    1146           0 :     maFilters.push_back( xTableFilter );
    1147           0 :     return *xTableFilter;
    1148             : }
    1149             : 
    1150           4 : void PivotTable::finalizeImport()
    1151             : {
    1152           4 :     if( getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) )
    1153             :     {
    1154           4 :         mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId );
    1155           4 :         if( mpPivotCache && mpPivotCache->isValidDataSource() && !maDefModel.maName.isEmpty() )
    1156             :         {
    1157             :             // clear destination area of the original pivot table
    1158             :             try
    1159             :             {
    1160           4 :                 Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW );
    1161             :                 using namespace ::com::sun::star::sheet::CellFlags;
    1162           4 :                 xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED );
    1163             :             }
    1164           0 :             catch( Exception& )
    1165             :             {
    1166             :             }
    1167             : 
    1168             :             try
    1169             :             {
    1170             :                 // create a new data pilot descriptor based on the source data
    1171           4 :                 Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.Sheet ), UNO_QUERY_THROW );
    1172           8 :                 Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW );
    1173           4 :                 mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW );
    1174           4 :                 mxDPDescriptor->setSourceRange( mpPivotCache->getSourceRange() );
    1175           4 :                 mxDPDescriptor->setTag( maDefModel.maTag );
    1176             : 
    1177             :                 // TODO: This is a hack. Eventually we need to convert the whole thing to the internal API.
    1178           4 :                 ScDataPilotDescriptorBase* pImpl = ScDataPilotDescriptorBase::getImplementation(mxDPDescriptor);
    1179           4 :                 if (!pImpl)
    1180           0 :                     return;
    1181             : 
    1182           4 :                 mpDPObject = pImpl->GetDPObject();
    1183           4 :                 if (!mpDPObject)
    1184           0 :                     return;
    1185             : 
    1186             :                 // global data pilot properties
    1187           8 :                 PropertySet aDescProp( mxDPDescriptor );
    1188           4 :                 aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals );
    1189           4 :                 aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals );
    1190           4 :                 aDescProp.setProperty( PROP_ShowFilterButton, false );
    1191           4 :                 aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill );
    1192             : 
    1193             :                 // finalize all fields, this finds field names and creates grouping fields
    1194           4 :                 maFields.forEachMem( &PivotTableField::finalizeImport, ::boost::cref( mxDPDescriptor ) );
    1195             : 
    1196             :                 // all row fields
    1197           8 :                 for( IndexVector::iterator aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
    1198           4 :                     if( PivotTableField* pField = getTableField( *aIt ) )
    1199           4 :                         pField->convertRowField();
    1200             : 
    1201             :                 // all column fields
    1202           8 :                 for( IndexVector::iterator aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt )
    1203           4 :                     if( PivotTableField* pField = getTableField( *aIt ) )
    1204           4 :                         pField->convertColField();
    1205             : 
    1206             :                 // all page fields
    1207           8 :                 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
    1208           4 :                     if( PivotTableField* pField = getTableField( aIt->mnField ) )
    1209           4 :                         pField->convertPageField( *aIt );
    1210             : 
    1211             :                 // all hidden fields
    1212           8 :                 ::std::set< sal_Int32 > aVisFields;
    1213           4 :                 aVisFields.insert( maRowFields.begin(), maRowFields.end() );
    1214           4 :                 aVisFields.insert( maColFields.begin(), maColFields.end() );
    1215           8 :                 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
    1216           4 :                     aVisFields.insert( aIt->mnField );
    1217          28 :                 for( PivotTableFieldVector::iterator aBeg = maFields.begin(), aIt = aBeg, aEnd = maFields.end(); aIt != aEnd; ++aIt )
    1218          24 :                     if( aVisFields.count( static_cast< sal_Int32 >( aIt - aBeg ) ) == 0 )
    1219          14 :                         (*aIt)->convertHiddenField();
    1220             : 
    1221             :                 // all data fields
    1222          10 :                 for( DataFieldVector::iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
    1223             :                 {
    1224           6 :                     if( const PivotCacheField* pCacheField = getCacheField( aIt->mnField  ) )
    1225             :                     {
    1226           6 :                         if ( pCacheField-> getGroupBaseField() != -1 )
    1227           0 :                             aIt->mnField = pCacheField-> getGroupBaseField();
    1228             :                     }
    1229           6 :                     if( PivotTableField* pField = getTableField( aIt->mnField ) )
    1230           6 :                         pField->convertDataField( *aIt );
    1231             :                 }
    1232             : 
    1233             :                 // filters
    1234           4 :                 maFilters.forEachMem( &PivotTableFilter::finalizeImport );
    1235             : 
    1236             :                 // calculate base position of table
    1237           4 :                 CellAddress aPos( maLocationModel.maRange.Sheet, maLocationModel.maRange.StartColumn, maLocationModel.maRange.StartRow );
    1238             :                 /*  If page fields exist, include them into the destination
    1239             :                     area (they are excluded in Excel). Add an extra blank row. */
    1240           4 :                 if( !maPageFields.empty() )
    1241           2 :                     aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 );
    1242             : 
    1243             :                 // insert the DataPilot table into the sheet
    1244           8 :                 xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
    1245             :             }
    1246           0 :             catch( Exception& )
    1247             :             {
    1248             :                 OSL_FAIL( "PivotTable::finalizeImport - exception while creating the DataPilot table" );
    1249             :             }
    1250             :         }
    1251             :     }
    1252             : }
    1253             : 
    1254           0 : void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
    1255             : {
    1256             :     // process all fields, there is no chaining information in the cache fields
    1257           0 :     maFields.forEachMem( &PivotTableField::finalizeDateGroupingImport, ::boost::cref( rxBaseDPField ), nBaseFieldIdx );
    1258           0 : }
    1259             : 
    1260           0 : void PivotTable::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField,
    1261             :         const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
    1262             : {
    1263             :     // try to create parent group fields that group the items of the passed base field
    1264           0 :     if( PivotTableField* pParentTableField = maFields.get( rBaseCacheField.getParentGroupField() ).get() )
    1265           0 :         pParentTableField->finalizeParentGroupingImport( rxBaseDPField, rBaseCacheField, orItemNames );
    1266           0 : }
    1267             : 
    1268          30 : Reference< XDataPilotField > PivotTable::getDataPilotField( const OUString& rFieldName ) const
    1269             : {
    1270          30 :     Reference< XDataPilotField > xDPField;
    1271          30 :     if( !rFieldName.isEmpty() && mxDPDescriptor.is() ) try
    1272             :     {
    1273          30 :         Reference< XNameAccess > xDPFieldsNA( mxDPDescriptor->getDataPilotFields(), UNO_QUERY_THROW );
    1274          30 :         xDPField.set( xDPFieldsNA->getByName( rFieldName ), UNO_QUERY );
    1275             :     }
    1276           0 :     catch( Exception& )
    1277             :     {
    1278             :     }
    1279          30 :     return xDPField;
    1280             : }
    1281             : 
    1282           0 : Reference< XDataPilotField > PivotTable::getDataPilotField( sal_Int32 nFieldIdx ) const
    1283             : {
    1284           0 :     Reference< XDataPilotField > xDPField;
    1285           0 :     if( const PivotTableField* pTableField = maFields.get( nFieldIdx ).get() )
    1286           0 :         xDPField = getDataPilotField( pTableField->getDPFieldName() );
    1287           0 :     return xDPField;
    1288             : }
    1289             : 
    1290           2 : Reference< XDataPilotField > PivotTable::getDataLayoutField() const
    1291             : {
    1292           2 :     Reference< XDataPilotField > xDPField;
    1293             :     try
    1294             :     {
    1295           2 :         Reference< XDataPilotDataLayoutFieldSupplier > xDPDataFieldSupp( mxDPDescriptor, UNO_QUERY_THROW );
    1296           2 :         xDPField = xDPDataFieldSupp->getDataLayoutField();
    1297             :     }
    1298           0 :     catch( Exception& )
    1299             :     {
    1300             :     }
    1301           2 :     return xDPField;
    1302             : }
    1303             : 
    1304          54 : const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const
    1305             : {
    1306          54 :     return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : 0;
    1307             : }
    1308             : 
    1309           0 : const PivotCacheField* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const
    1310             : {
    1311           0 :     const PTDataFieldModel* pDataField = ContainerHelper::getVectorElement( maDataFields, nDataItemIdx );
    1312           0 :     return pDataField ? getCacheField( pDataField->mnField ) : 0;
    1313             : }
    1314             : 
    1315          24 : sal_Int32 PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
    1316             : {
    1317          24 :     return mpPivotCache ? mpPivotCache->getCacheDatabaseIndex( nFieldIdx ) : -1;
    1318             : }
    1319             : 
    1320             : // private --------------------------------------------------------------------
    1321             : 
    1322          18 : PivotTableField* PivotTable::getTableField( sal_Int32 nFieldIdx )
    1323             : {
    1324          18 :     return (nFieldIdx == OOX_PT_DATALAYOUTFIELD) ? &maDataField : maFields.get( nFieldIdx ).get();
    1325             : }
    1326             : 
    1327           8 : void PivotTable::importField( IndexVector& orFields, const AttributeList& rAttribs )
    1328             : {
    1329           8 :     orFields.push_back( rAttribs.getInteger( XML_x, -1 ) );
    1330           8 : }
    1331             : 
    1332           0 : void PivotTable::importFields( IndexVector& orFields, SequenceInputStream& rStrm )
    1333             : {
    1334             :     OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
    1335           0 :     orFields.clear();
    1336           0 :     sal_Int32 nCount = rStrm.readInt32();
    1337             :     OSL_ENSURE( 4 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
    1338           0 :     nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 4 );
    1339           0 :     for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
    1340           0 :         orFields.push_back( rStrm.readInt32() );
    1341           0 : }
    1342             : 
    1343         145 : PivotTableBuffer::PivotTableBuffer( const WorkbookHelper& rHelper ) :
    1344         145 :     WorkbookHelper( rHelper )
    1345             : {
    1346         145 : }
    1347             : 
    1348           4 : PivotTable& PivotTableBuffer::createPivotTable()
    1349             : {
    1350           4 :     PivotTableVector::value_type xTable( new PivotTable( *this ) );
    1351           4 :     maTables.push_back( xTable );
    1352           4 :     return *xTable;
    1353             : }
    1354             : 
    1355         145 : void PivotTableBuffer::finalizeImport()
    1356             : {
    1357         145 :     maTables.forEachMem( &PivotTable::finalizeImport );
    1358         145 : }
    1359             : 
    1360             : } // namespace xls
    1361          30 : } // namespace oox
    1362             : 
    1363             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11